Sources settings
parent
bb1ddc31df
commit
9373bae091
@ -0,0 +1,35 @@
|
||||
package org.koitharu.kotatsu.ui.settings
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import org.koin.core.KoinComponent
|
||||
import org.koitharu.kotatsu.core.model.MangaSource
|
||||
import org.koitharu.kotatsu.utils.ext.withArgs
|
||||
|
||||
class SourceSettingsFragment : PreferenceFragmentCompat(), KoinComponent {
|
||||
|
||||
private lateinit var source: MangaSource
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
source = requireArguments().getParcelable(EXTRA_SOURCE)!!
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
activity?.title = source.title
|
||||
}
|
||||
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private const val EXTRA_SOURCE = "source"
|
||||
|
||||
fun newInstance(source: MangaSource) = SourceSettingsFragment().withArgs(1) {
|
||||
putParcelable(EXTRA_SOURCE, source)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
package org.koitharu.kotatsu.ui.settings.sources
|
||||
|
||||
import android.view.ViewGroup
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.ui.common.list.BaseViewHolder
|
||||
|
||||
class SourceDividerHolder(parent: ViewGroup) :
|
||||
BaseViewHolder<Unit, Unit>(parent, R.layout.item_sources_pref_divider) {
|
||||
|
||||
override fun onBind(data: Unit, extra: Unit) = Unit
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
package org.koitharu.kotatsu.ui.settings.sources
|
||||
|
||||
import android.view.ViewGroup
|
||||
import kotlinx.android.synthetic.main.item_source_config.*
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.model.MangaSource
|
||||
import org.koitharu.kotatsu.ui.common.list.BaseViewHolder
|
||||
|
||||
class SourceViewHolder(parent: ViewGroup) :
|
||||
BaseViewHolder<MangaSource, Unit>(parent, R.layout.item_source_config) {
|
||||
|
||||
override fun onBind(data: MangaSource, extra: Unit) {
|
||||
textView_title.text = data.title
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,59 @@
|
||||
package org.koitharu.kotatsu.ui.settings.sources
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.view.MotionEvent
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import kotlinx.android.synthetic.main.item_source_config.*
|
||||
import org.koin.core.KoinComponent
|
||||
import org.koin.core.get
|
||||
import org.koitharu.kotatsu.core.model.MangaSource
|
||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||
import org.koitharu.kotatsu.domain.MangaProviderFactory
|
||||
import org.koitharu.kotatsu.ui.common.list.BaseViewHolder
|
||||
import org.koitharu.kotatsu.ui.common.list.OnRecyclerItemClickListener
|
||||
|
||||
class SourcesAdapter(private val onItemClickListener: OnRecyclerItemClickListener<MangaSource>) :
|
||||
RecyclerView.Adapter<BaseViewHolder<*, Unit>>(), KoinComponent {
|
||||
|
||||
private val dataSet = MangaProviderFactory.sources.toMutableList()
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = when (viewType) {
|
||||
ITEM_SOURCE -> SourceViewHolder(parent).also(::onViewHolderCreated)
|
||||
ITEM_DIVIDER -> SourceDividerHolder(parent)
|
||||
else -> throw IllegalArgumentException("Unsupported viewType $viewType")
|
||||
}
|
||||
|
||||
override fun getItemCount() = dataSet.size
|
||||
|
||||
override fun onBindViewHolder(holder: BaseViewHolder<*, Unit>, position: Int) {
|
||||
(holder as? SourceViewHolder)?.bind(dataSet[position], Unit)
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
private fun onViewHolderCreated(holder: SourceViewHolder) {
|
||||
holder.imageView_config.setOnClickListener { v ->
|
||||
onItemClickListener.onItemClick(holder.requireData(), holder.adapterPosition, v)
|
||||
}
|
||||
holder.imageView_handle.setOnTouchListener { v, event ->
|
||||
if (event.actionMasked == MotionEvent.ACTION_DOWN) {
|
||||
onItemClickListener.onItemLongClick(holder.requireData(), holder.adapterPosition, v)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun moveItem(oldPos: Int, newPos: Int) {
|
||||
val item = dataSet.removeAt(oldPos)
|
||||
dataSet.add(newPos, item)
|
||||
notifyItemMoved(oldPos, newPos)
|
||||
get<AppSettings>().sourcesOrder = dataSet.map { it.ordinal }
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
const val ITEM_SOURCE = 0
|
||||
const val ITEM_DIVIDER = 1
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
package org.koitharu.kotatsu.ui.settings.sources
|
||||
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
|
||||
class SourcesReorderCallback : ItemTouchHelper.SimpleCallback(ItemTouchHelper.DOWN or ItemTouchHelper.UP, 0) {
|
||||
|
||||
override fun onMove(
|
||||
recyclerView: RecyclerView,
|
||||
viewHolder: RecyclerView.ViewHolder,
|
||||
target: RecyclerView.ViewHolder
|
||||
): Boolean {
|
||||
val adapter = recyclerView.adapter as? SourcesAdapter ?: return false
|
||||
val oldPos = viewHolder.adapterPosition
|
||||
val newPos = target.adapterPosition
|
||||
adapter.moveItem(oldPos, newPos)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) = Unit
|
||||
|
||||
override fun isLongPressDragEnabled() = false
|
||||
}
|
||||
@ -1,12 +1,47 @@
|
||||
package org.koitharu.kotatsu.ui.settings.sources
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import kotlinx.android.synthetic.main.fragment_settings_sources.*
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.model.MangaSource
|
||||
import org.koitharu.kotatsu.ui.common.BaseFragment
|
||||
import org.koitharu.kotatsu.ui.common.list.OnRecyclerItemClickListener
|
||||
import org.koitharu.kotatsu.ui.settings.SettingsActivity
|
||||
|
||||
class SourcesSettingsFragment : BaseFragment(R.layout.fragment_settings_sources) {
|
||||
class SourcesSettingsFragment : BaseFragment(R.layout.fragment_settings_sources),
|
||||
OnRecyclerItemClickListener<MangaSource> {
|
||||
|
||||
private lateinit var reorderHelper: ItemTouchHelper
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
reorderHelper = ItemTouchHelper(SourcesReorderCallback())
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
activity?.setTitle(R.string.remote_sources)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
recyclerView.adapter = SourcesAdapter(this)
|
||||
reorderHelper.attachToRecyclerView(recyclerView)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
reorderHelper.attachToRecyclerView(null)
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
override fun onItemClick(item: MangaSource, position: Int, view: View) {
|
||||
(activity as? SettingsActivity)?.openMangaSourceSettings(item)
|
||||
}
|
||||
|
||||
override fun onItemLongClick(item: MangaSource, position: Int, view: View): Boolean {
|
||||
reorderHelper.startDrag(recyclerView.findViewHolderForAdapterPosition(position) ?: return false)
|
||||
return super.onItemLongClick(item, position, view)
|
||||
}
|
||||
}
|
||||
@ -1,33 +0,0 @@
|
||||
package org.koitharu.kotatsu.utils.ext
|
||||
|
||||
import androidx.preference.EditTextPreference
|
||||
import androidx.preference.ListPreference
|
||||
|
||||
fun ListPreference.bindSummary(listener: (String) -> Boolean = { true }) {
|
||||
summary = entries.getOrNull(findIndexOfValue(value))
|
||||
this.setOnPreferenceChangeListener { preference, newValue ->
|
||||
newValue as String
|
||||
preference as ListPreference
|
||||
val res = listener(newValue)
|
||||
if (res) {
|
||||
preference.summary = preference.entries.getOrNull(preference.findIndexOfValue(newValue))
|
||||
}
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
fun EditTextPreference.bindSummary(
|
||||
formatter: (String) -> String = { it },
|
||||
listener: (String) -> Boolean = { true }
|
||||
) {
|
||||
summary = formatter(text)
|
||||
this.setOnPreferenceChangeListener { preference, newValue ->
|
||||
newValue as String
|
||||
preference as EditTextPreference
|
||||
val res = listener(newValue)
|
||||
if (res) {
|
||||
preference.summary = formatter(newValue)
|
||||
}
|
||||
res
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="?colorControlNormal"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#000"
|
||||
android:pathData="M7,19V17H9V19H7M11,19V17H13V19H11M15,19V17H17V19H15M7,15V13H9V15H7M11,15V13H13V15H11M15,15V13H17V15H15M7,11V9H9V11H7M11,11V9H13V11H11M15,11V9H17V11H15M7,7V5H9V7H7M11,7V5H13V7H11M15,7V5H17V7H15Z" />
|
||||
</vector>
|
||||
@ -1,6 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
</androidx.recyclerview.widget.RecyclerView>
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/recyclerView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:scrollbars="vertical"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
tools:listitem="@layout/item_source_config" />
|
||||
@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?android:listPreferredItemHeightSmall"
|
||||
android:background="?android:windowBackground"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imageView_handle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="?listPreferredItemPaddingStart"
|
||||
android:scaleType="center"
|
||||
android:src="@drawable/ic_reorder_handle" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="marquee"
|
||||
android:fadingEdge="horizontal"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
tools:text="@tools:sample/lorem[1]" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imageView_config"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?selectableItemBackgroundBorderless"
|
||||
android:padding="?listPreferredItemPaddingEnd"
|
||||
android:scaleType="center"
|
||||
android:src="@drawable/ic_settings" />
|
||||
|
||||
</LinearLayout>
|
||||
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TextView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/header_height"
|
||||
android:background="?attr/colorButtonNormal"
|
||||
android:gravity="start|center_vertical"
|
||||
android:paddingStart="?listPreferredItemPaddingStart"
|
||||
android:paddingEnd="?listPreferredItemPaddingEnd"
|
||||
android:text="@string/put_items_below_to_disable_it"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
|
||||
android:textColor="?android:textColorPrimary" />
|
||||
Loading…
Reference in New Issue