Show new sources on app startup
This commit is contained in:
@@ -134,6 +134,20 @@ class AppSettings(context: Context) {
|
||||
val isSourcesSelected: Boolean
|
||||
get() = KEY_SOURCES_HIDDEN in prefs
|
||||
|
||||
val newSources: Set<MangaSource>
|
||||
get() {
|
||||
val known = sourcesOrder.toSet()
|
||||
val hidden = hiddenSources
|
||||
return remoteMangaSources
|
||||
.filterNotTo(EnumSet.noneOf(MangaSource::class.java)) { x ->
|
||||
x.name in known || x.name in hidden
|
||||
}
|
||||
}
|
||||
|
||||
fun markKnownSources(sources: Collection<MangaSource>) {
|
||||
sourcesOrder = sourcesOrder + sources.map { it.name }
|
||||
}
|
||||
|
||||
val isPagesNumbersEnabled: Boolean
|
||||
get() = prefs.getBoolean(KEY_PAGES_NUMBERS, false)
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@ import org.koitharu.kotatsu.search.ui.suggestion.SearchSuggestionListener
|
||||
import org.koitharu.kotatsu.search.ui.suggestion.SearchSuggestionViewModel
|
||||
import org.koitharu.kotatsu.settings.AppUpdateChecker
|
||||
import org.koitharu.kotatsu.settings.SettingsActivity
|
||||
import org.koitharu.kotatsu.settings.newsources.NewSourcesDialogFragment
|
||||
import org.koitharu.kotatsu.settings.onboard.OnboardDialogFragment
|
||||
import org.koitharu.kotatsu.suggestions.ui.SuggestionsFragment
|
||||
import org.koitharu.kotatsu.suggestions.ui.SuggestionsWorker
|
||||
@@ -390,10 +391,14 @@ class MainActivity :
|
||||
if (AppUpdateChecker.isUpdateSupported(this@MainActivity)) {
|
||||
AppUpdateChecker(this@MainActivity).checkIfNeeded()
|
||||
}
|
||||
if (!get<AppSettings>().isSourcesSelected) {
|
||||
withContext(Dispatchers.Main) {
|
||||
val settings = get<AppSettings>()
|
||||
when {
|
||||
!settings.isSourcesSelected -> withContext(Dispatchers.Main) {
|
||||
OnboardDialogFragment.showWelcome(supportFragmentManager)
|
||||
}
|
||||
settings.newSources.isNotEmpty() -> withContext(Dispatchers.Main) {
|
||||
NewSourcesDialogFragment.show(supportFragmentManager)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import org.koitharu.kotatsu.core.backup.RestoreRepository
|
||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||
import org.koitharu.kotatsu.settings.backup.BackupViewModel
|
||||
import org.koitharu.kotatsu.settings.backup.RestoreViewModel
|
||||
import org.koitharu.kotatsu.settings.newsources.NewSourcesViewModel
|
||||
import org.koitharu.kotatsu.settings.onboard.OnboardViewModel
|
||||
import org.koitharu.kotatsu.settings.protect.ProtectSetupViewModel
|
||||
import org.koitharu.kotatsu.settings.sources.SourcesSettingsViewModel
|
||||
@@ -27,4 +28,5 @@ val settingsModule
|
||||
viewModel { ProtectSetupViewModel(get()) }
|
||||
viewModel { OnboardViewModel(get()) }
|
||||
viewModel { SourcesSettingsViewModel(get()) }
|
||||
viewModel { NewSourcesViewModel(get()) }
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package org.koitharu.kotatsu.settings.newsources
|
||||
|
||||
import android.content.DialogInterface
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import org.koin.android.ext.android.get
|
||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.base.ui.AlertDialogFragment
|
||||
import org.koitharu.kotatsu.databinding.DialogOnboardBinding
|
||||
import org.koitharu.kotatsu.settings.sources.adapter.SourceConfigAdapter
|
||||
import org.koitharu.kotatsu.settings.sources.adapter.SourceConfigListener
|
||||
import org.koitharu.kotatsu.settings.sources.model.SourceConfigItem
|
||||
|
||||
class NewSourcesDialogFragment :
|
||||
AlertDialogFragment<DialogOnboardBinding>(),
|
||||
SourceConfigListener,
|
||||
DialogInterface.OnClickListener {
|
||||
|
||||
private val viewModel by viewModel<NewSourcesViewModel>()
|
||||
|
||||
override fun onInflateView(inflater: LayoutInflater, container: ViewGroup?): DialogOnboardBinding {
|
||||
return DialogOnboardBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
val adapter = SourceConfigAdapter(this, get(), viewLifecycleOwner)
|
||||
binding.recyclerView.adapter = adapter
|
||||
binding.textViewTitle.setText(R.string.new_sources_text)
|
||||
|
||||
viewModel.sources.observe(viewLifecycleOwner) { adapter.items = it }
|
||||
}
|
||||
|
||||
override fun onBuildDialog(builder: MaterialAlertDialogBuilder) {
|
||||
builder
|
||||
.setPositiveButton(R.string.done, this)
|
||||
.setCancelable(true)
|
||||
.setTitle(R.string.remote_sources)
|
||||
}
|
||||
|
||||
override fun onClick(dialog: DialogInterface, which: Int) {
|
||||
viewModel.apply()
|
||||
dialog.dismiss()
|
||||
}
|
||||
|
||||
override fun onItemSettingsClick(item: SourceConfigItem.SourceItem) = Unit
|
||||
|
||||
override fun onItemEnabledChanged(item: SourceConfigItem.SourceItem, isEnabled: Boolean) {
|
||||
viewModel.onItemEnabledChanged(item, isEnabled)
|
||||
}
|
||||
|
||||
override fun onDragHandleTouch(holder: RecyclerView.ViewHolder) = Unit
|
||||
|
||||
override fun onHeaderClick(header: SourceConfigItem.LocaleGroup) = Unit
|
||||
|
||||
companion object {
|
||||
|
||||
private const val TAG = "NewSources"
|
||||
|
||||
fun show(fm: FragmentManager) = NewSourcesDialogFragment().show(fm, TAG)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package org.koitharu.kotatsu.settings.newsources
|
||||
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import org.koitharu.kotatsu.base.ui.BaseViewModel
|
||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||
import org.koitharu.kotatsu.settings.sources.model.SourceConfigItem
|
||||
|
||||
class NewSourcesViewModel(
|
||||
private val settings: AppSettings,
|
||||
) : BaseViewModel() {
|
||||
|
||||
val sources = MutableLiveData<List<SourceConfigItem>>()
|
||||
private val initialList = settings.newSources
|
||||
|
||||
init {
|
||||
buildList()
|
||||
}
|
||||
|
||||
fun onItemEnabledChanged(item: SourceConfigItem.SourceItem, isEnabled: Boolean) {
|
||||
if (isEnabled) {
|
||||
settings.hiddenSources -= item.source.name
|
||||
} else {
|
||||
settings.hiddenSources += item.source.name
|
||||
}
|
||||
}
|
||||
|
||||
fun apply() {
|
||||
settings.markKnownSources(initialList)
|
||||
}
|
||||
|
||||
private fun buildList() {
|
||||
val hidden = settings.hiddenSources
|
||||
sources.value = initialList.map {
|
||||
SourceConfigItem.SourceItem(
|
||||
source = it,
|
||||
summary = null,
|
||||
isEnabled = it.name !in hidden,
|
||||
isDraggable = false,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -53,6 +53,7 @@ class OnboardDialogFragment : AlertDialogFragment<DialogOnboardBinding>(),
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
val adapter = SourceLocalesAdapter(this)
|
||||
binding.recyclerView.adapter = adapter
|
||||
binding.textViewTitle.setText(R.string.onboard_text)
|
||||
viewModel.list.observeNotNull(viewLifecycleOwner) {
|
||||
adapter.items = it
|
||||
}
|
||||
|
||||
@@ -141,7 +141,10 @@ class SourcesSettingsFragment : BaseFragment<FragmentSettingsSourcesBinding>(),
|
||||
recyclerView: RecyclerView,
|
||||
current: RecyclerView.ViewHolder,
|
||||
target: RecyclerView.ViewHolder,
|
||||
): Boolean = current.itemViewType == target.itemViewType
|
||||
): Boolean = current.itemViewType == target.itemViewType && viewModel.canReorder(
|
||||
current.bindingAdapterPosition,
|
||||
target.bindingAdapterPosition,
|
||||
)
|
||||
|
||||
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) = Unit
|
||||
|
||||
|
||||
@@ -83,7 +83,9 @@ fun sourceConfigDraggableItemDelegate(
|
||||
on = { item, _, _ -> item is SourceConfigItem.SourceItem && item.isDraggable }
|
||||
) {
|
||||
|
||||
val eventListener = object : View.OnClickListener, View.OnTouchListener,
|
||||
val eventListener = object :
|
||||
View.OnClickListener,
|
||||
View.OnTouchListener,
|
||||
CompoundButton.OnCheckedChangeListener {
|
||||
override fun onClick(v: View?) = listener.onItemSettingsClick(item)
|
||||
|
||||
|
||||
@@ -8,14 +8,15 @@
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="?listPreferredItemPaddingStart"
|
||||
android:paddingTop="6dp"
|
||||
android:paddingEnd="?listPreferredItemPaddingEnd"
|
||||
android:paddingBottom="6dp"
|
||||
android:text="@string/onboard_text"
|
||||
android:textAppearance="?attr/textAppearanceBodyMedium" />
|
||||
android:textAppearance="?attr/textAppearanceBodyMedium"
|
||||
tools:text="@string/onboard_text" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler_view"
|
||||
|
||||
@@ -276,4 +276,6 @@
|
||||
<string name="download_slowdown_summary">Помогает избежать блокировки IP-адреса</string>
|
||||
<string name="local_manga_processing">Обработка сохранённой манги</string>
|
||||
<string name="chapters_will_removed_background">Главы будут удалены в фоновом режиме. Это может занять какое-то время</string>
|
||||
<string name="hide">Скрыть</string>
|
||||
<string name="new_sources_text">Доступны новые источники манги</string>
|
||||
</resources>
|
||||
@@ -280,4 +280,5 @@
|
||||
<string name="local_manga_processing">Saved manga processing</string>
|
||||
<string name="chapters_will_removed_background">Chapters will be removed in the background. It can take some time</string>
|
||||
<string name="hide">Hide</string>
|
||||
<string name="new_sources_text">New manga sources are available</string>
|
||||
</resources>
|
||||
Reference in New Issue
Block a user