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
|
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.R
|
||||||
|
import org.koitharu.kotatsu.core.model.MangaSource
|
||||||
import org.koitharu.kotatsu.ui.common.BaseFragment
|
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() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
activity?.setTitle(R.string.remote_sources)
|
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"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_height="match_parent">
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
</androidx.recyclerview.widget.RecyclerView>
|
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