Manga languages onboarding
This commit is contained in:
7
.idea/misc.xml
generated
7
.idea/misc.xml
generated
@@ -14,6 +14,8 @@
|
||||
<entry key="app/src/main/res/drawable/ic_clear_all.xml" value="0.275" />
|
||||
<entry key="app/src/main/res/drawable/ic_complete.xml" value="0.275" />
|
||||
<entry key="app/src/main/res/drawable/ic_history.xml" value="0.275" />
|
||||
<entry key="app/src/main/res/drawable/ic_locale.xml" value="0.197" />
|
||||
<entry key="app/src/main/res/drawable/ic_open_external.xml" value="0.197" />
|
||||
<entry key="app/src/main/res/drawable/tab_indicator.xml" value="0.28512820512820514" />
|
||||
<entry key="app/src/main/res/drawable/tabs_background.xml" value="0.28512820512820514" />
|
||||
<entry key="app/src/main/res/layout-w600dp/activity_details.xml" value="0.18072916666666666" />
|
||||
@@ -23,6 +25,7 @@
|
||||
<entry key="app/src/main/res/layout/activity_setup_protect.xml" value="0.26927083333333335" />
|
||||
<entry key="app/src/main/res/layout/dialog_favorite_categories.xml" value="0.2601851851851852" />
|
||||
<entry key="app/src/main/res/layout/dialog_list_mode.xml" value="0.2601851851851852" />
|
||||
<entry key="app/src/main/res/layout/dialog_onboard.xml" value="0.25885416666666666" />
|
||||
<entry key="app/src/main/res/layout/fragment_chapters.xml" value="0.24739583333333334" />
|
||||
<entry key="app/src/main/res/layout/fragment_details.xml" value="0.26145833333333335" />
|
||||
<entry key="app/src/main/res/layout/fragment_favourites.xml" value="0.26296296296296295" />
|
||||
@@ -31,6 +34,7 @@
|
||||
<entry key="app/src/main/res/layout/fragment_search_suggestion.xml" value="0.25885416666666666" />
|
||||
<entry key="app/src/main/res/layout/item_branch.xml" value="0.24739583333333334" />
|
||||
<entry key="app/src/main/res/layout/item_branch_dropdown.xml" value="0.25743589743589745" />
|
||||
<entry key="app/src/main/res/layout/item_category.xml" value="0.25885416666666666" />
|
||||
<entry key="app/src/main/res/layout/item_category_checkable.xml" value="0.2601851851851852" />
|
||||
<entry key="app/src/main/res/layout/item_manga_grid.xml" value="0.26042632066728455" />
|
||||
<entry key="app/src/main/res/layout/item_manga_list_details.xml" value="0.2601851851851852" />
|
||||
@@ -41,9 +45,12 @@
|
||||
<entry key="app/src/main/res/layout/item_search_suggestion_manga.xml" value="0.24479166666666666" />
|
||||
<entry key="app/src/main/res/layout/item_search_suggestion_query.xml" value="0.587248322147651" />
|
||||
<entry key="app/src/main/res/layout/item_source_config.xml" value="0.25885416666666666" />
|
||||
<entry key="app/src/main/res/layout/item_source_locale.xml" value="0.25885416666666666" />
|
||||
<entry key="app/src/main/res/layout/item_tracklog.xml" value="0.24479166666666666" />
|
||||
<entry key="app/src/main/res/layout/sheet_pages.xml" value="0.2601851851851852" />
|
||||
<entry key="app/src/main/res/menu/opt_browser.xml" value="0.24479166666666666" />
|
||||
<entry key="app/src/main/res/menu/opt_protect.xml" value="0.26927083333333335" />
|
||||
<entry key="app/src/main/res/menu/opt_sources.xml" value="0.24479166666666666" />
|
||||
<entry key="app/src/main/res/menu/popup_category.xml" value="0.2601851851851852" />
|
||||
<entry key="app/src/main/res/xml/pref_main.xml" value="0.26927083333333335" />
|
||||
</map>
|
||||
|
||||
@@ -74,7 +74,7 @@ dependencies {
|
||||
implementation 'androidx.lifecycle:lifecycle-process:2.3.1'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
|
||||
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
|
||||
implementation 'androidx.recyclerview:recyclerview:1.2.0'
|
||||
implementation 'androidx.recyclerview:recyclerview:1.2.1'
|
||||
implementation 'androidx.viewpager2:viewpager2:1.1.0-alpha01'
|
||||
implementation 'androidx.preference:preference-ktx:1.1.1'
|
||||
implementation 'androidx.work:work-runtime-ktx:2.5.0'
|
||||
|
||||
@@ -37,7 +37,7 @@ enum class MangaSource(
|
||||
NINEMANGA_RU("NineManga Русский", "ru", NineMangaRepository.Russian::class.java),
|
||||
NINEMANGA_DE("NineManga Deutsch", "de", NineMangaRepository.Deutsch::class.java),
|
||||
NINEMANGA_IT("NineManga Italiano", "it", NineMangaRepository.Italiano::class.java),
|
||||
NINEMANGA_BR("NineManga Brasil", "br", NineMangaRepository.Brazil::class.java),
|
||||
NINEMANGA_BR("NineManga Brasil", "pt", NineMangaRepository.Brazil::class.java),
|
||||
NINEMANGA_FR("NineManga Français", "fr", NineMangaRepository.Francais::class.java),
|
||||
;
|
||||
|
||||
|
||||
@@ -101,6 +101,9 @@ class AppSettings private constructor(private val prefs: SharedPreferences) :
|
||||
|
||||
var hiddenSources by StringSetPreferenceDelegate(KEY_SOURCES_HIDDEN)
|
||||
|
||||
val isSourcesSelected: Boolean
|
||||
get() = KEY_SOURCES_HIDDEN in prefs
|
||||
|
||||
fun getStorageDir(context: Context): File? {
|
||||
val value = prefs.getString(KEY_LOCAL_STORAGE, null)?.let {
|
||||
File(it)
|
||||
|
||||
@@ -20,6 +20,7 @@ import androidx.fragment.app.commit
|
||||
import androidx.swiperefreshlayout.widget.CircularProgressDrawable
|
||||
import com.google.android.material.navigation.NavigationView
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
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.BaseActivity
|
||||
@@ -41,6 +42,7 @@ import org.koitharu.kotatsu.search.ui.suggestion.SearchSuggestionViewModel
|
||||
import org.koitharu.kotatsu.search.ui.suggestion.SearchUI
|
||||
import org.koitharu.kotatsu.settings.AppUpdateChecker
|
||||
import org.koitharu.kotatsu.settings.SettingsActivity
|
||||
import org.koitharu.kotatsu.settings.onboard.OnboardDialogFragment
|
||||
import org.koitharu.kotatsu.tracker.ui.FeedFragment
|
||||
import org.koitharu.kotatsu.tracker.work.TrackWorker
|
||||
import org.koitharu.kotatsu.utils.ext.getDisplayMessage
|
||||
@@ -86,6 +88,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>(),
|
||||
if (savedInstanceState == null) {
|
||||
TrackWorker.setup(applicationContext)
|
||||
AppUpdateChecker(this).launchIfNeeded()
|
||||
OnboardDialogFragment.showWelcome(get(), supportFragmentManager)
|
||||
}
|
||||
|
||||
viewModel.onOpenReader.observe(this, this::onOpenReader)
|
||||
|
||||
@@ -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.onboard.OnboardViewModel
|
||||
import org.koitharu.kotatsu.settings.protect.ProtectSetupViewModel
|
||||
|
||||
val settingsModule
|
||||
@@ -21,4 +22,5 @@ val settingsModule
|
||||
viewModel { BackupViewModel(get(), androidContext()) }
|
||||
viewModel { (uri: Uri?) -> RestoreViewModel(uri, get(), androidContext()) }
|
||||
viewModel { ProtectSetupViewModel(get()) }
|
||||
viewModel { OnboardViewModel(get()) }
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package org.koitharu.kotatsu.settings.onboard
|
||||
|
||||
import android.content.DialogInterface
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.base.ui.AlertDialogFragment
|
||||
import org.koitharu.kotatsu.base.ui.list.OnListItemClickListener
|
||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||
import org.koitharu.kotatsu.databinding.DialogOnboardBinding
|
||||
import org.koitharu.kotatsu.settings.onboard.adapter.SourceLocalesAdapter
|
||||
import org.koitharu.kotatsu.settings.onboard.model.SourceLocale
|
||||
import org.koitharu.kotatsu.utils.ext.observeNotNull
|
||||
import org.koitharu.kotatsu.utils.ext.withArgs
|
||||
|
||||
class OnboardDialogFragment : AlertDialogFragment<DialogOnboardBinding>(),
|
||||
OnListItemClickListener<SourceLocale>, DialogInterface.OnClickListener {
|
||||
|
||||
private val viewModel by viewModel<OnboardViewModel>(mode = LazyThreadSafetyMode.NONE)
|
||||
private var isWelcome: Boolean = false
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
arguments?.run {
|
||||
isWelcome = getBoolean(ARG_WELCOME, false)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onInflateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
) = DialogOnboardBinding.inflate(inflater, container, false)
|
||||
|
||||
override fun onBuildDialog(builder: AlertDialog.Builder) {
|
||||
builder
|
||||
.setPositiveButton(R.string.done, this)
|
||||
.setCancelable(true)
|
||||
if (isWelcome) {
|
||||
builder.setTitle(R.string.welcome)
|
||||
} else {
|
||||
builder
|
||||
.setTitle(R.string.remote_sources)
|
||||
.setNegativeButton(android.R.string.cancel, this)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
val adapter = SourceLocalesAdapter(this)
|
||||
binding.recyclerView.adapter = adapter
|
||||
viewModel.list.observeNotNull(viewLifecycleOwner) {
|
||||
adapter.items = it
|
||||
}
|
||||
}
|
||||
|
||||
override fun onItemClick(item: SourceLocale, view: View) {
|
||||
viewModel.setItemChecked(item.key, !item.isChecked)
|
||||
}
|
||||
|
||||
override fun onClick(dialog: DialogInterface?, which: Int) {
|
||||
when (which) {
|
||||
DialogInterface.BUTTON_POSITIVE -> viewModel.apply()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private const val TAG = "OnboardDialog"
|
||||
private const val ARG_WELCOME = "welcome"
|
||||
|
||||
fun show(fm: FragmentManager) = OnboardDialogFragment().show(fm, TAG)
|
||||
|
||||
fun showWelcome(settings: AppSettings, fm: FragmentManager) {
|
||||
if (!settings.isSourcesSelected) {
|
||||
OnboardDialogFragment().withArgs(1) {
|
||||
putBoolean(ARG_WELCOME, true)
|
||||
}.show(fm, TAG)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package org.koitharu.kotatsu.settings.onboard
|
||||
|
||||
import androidx.collection.ArraySet
|
||||
import androidx.core.os.LocaleListCompat
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import org.koitharu.kotatsu.base.ui.BaseViewModel
|
||||
import org.koitharu.kotatsu.core.model.MangaSource
|
||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||
import org.koitharu.kotatsu.settings.onboard.model.SourceLocale
|
||||
import org.koitharu.kotatsu.utils.ext.map
|
||||
import org.koitharu.kotatsu.utils.ext.mapTo
|
||||
import org.koitharu.kotatsu.utils.ext.mapToSet
|
||||
import java.util.*
|
||||
|
||||
class OnboardViewModel(
|
||||
private val settings: AppSettings,
|
||||
) : BaseViewModel() {
|
||||
|
||||
private val allSources = MangaSource.values().filterNot { x -> x == MangaSource.LOCAL }
|
||||
|
||||
private val locales = allSources.mapTo(ArraySet()) {
|
||||
it.locale
|
||||
}
|
||||
|
||||
private val selectedLocales = locales.toMutableSet()
|
||||
|
||||
val list = MutableLiveData<List<SourceLocale>?>()
|
||||
|
||||
init {
|
||||
if (settings.isSourcesSelected) {
|
||||
selectedLocales.removeAll(settings.hiddenSources.map { x -> MangaSource.valueOf(x).locale })
|
||||
} else {
|
||||
LocaleListCompat.getDefault().mapTo(selectedLocales) { x ->
|
||||
x.language
|
||||
}
|
||||
selectedLocales.retainAll(allSources.map { x -> x.locale })
|
||||
if (selectedLocales.isEmpty()) {
|
||||
selectedLocales += "en"
|
||||
}
|
||||
}
|
||||
rebuildList()
|
||||
}
|
||||
|
||||
fun setItemChecked(key: String?, isChecked: Boolean) {
|
||||
val isModified = if (isChecked) {
|
||||
selectedLocales.add(key)
|
||||
} else {
|
||||
selectedLocales.remove(key)
|
||||
}
|
||||
if (isModified) {
|
||||
rebuildList()
|
||||
}
|
||||
}
|
||||
|
||||
fun apply() {
|
||||
settings.hiddenSources = allSources.filterNot { x ->
|
||||
x.locale in selectedLocales
|
||||
}.mapToSet { x -> x.name }
|
||||
}
|
||||
|
||||
private fun rebuildList() {
|
||||
list.value = locales.map { key ->
|
||||
val locale = if (key != null) {
|
||||
Locale(key)
|
||||
} else null
|
||||
SourceLocale(
|
||||
key = key,
|
||||
title = locale?.getDisplayLanguage(locale)?.capitalize(locale),
|
||||
isChecked = key in selectedLocales
|
||||
)
|
||||
}.sortedWith(SourceLocaleComparator())
|
||||
}
|
||||
|
||||
private class SourceLocaleComparator : Comparator<SourceLocale> {
|
||||
|
||||
private val deviceLocales = LocaleListCompat.getAdjustedDefault()
|
||||
.map { it.language }
|
||||
|
||||
override fun compare(a: SourceLocale?, b: SourceLocale?): Int {
|
||||
return when {
|
||||
a === b -> 0
|
||||
a?.key == null -> 1
|
||||
b?.key == null -> -1
|
||||
else -> {
|
||||
val index = deviceLocales.indexOf(a.key)
|
||||
if (index == -1) {
|
||||
compareValues(a.title, b.title)
|
||||
} else {
|
||||
-2 - index
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.koitharu.kotatsu.settings.onboard.adapter
|
||||
|
||||
import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.base.ui.list.OnListItemClickListener
|
||||
import org.koitharu.kotatsu.databinding.ItemSourceLocaleBinding
|
||||
import org.koitharu.kotatsu.settings.onboard.model.SourceLocale
|
||||
|
||||
fun sourceLocaleAD(
|
||||
clickListener: OnListItemClickListener<SourceLocale>
|
||||
) = adapterDelegateViewBinding<SourceLocale, SourceLocale, ItemSourceLocaleBinding>(
|
||||
{ inflater, parent -> ItemSourceLocaleBinding.inflate(inflater, parent, false) }
|
||||
) {
|
||||
|
||||
binding.root.setOnClickListener {
|
||||
clickListener.onItemClick(item, it)
|
||||
}
|
||||
|
||||
bind {
|
||||
binding.root.text = item.title ?: getString(R.string.other)
|
||||
binding.root.isChecked = item.isChecked
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package org.koitharu.kotatsu.settings.onboard.adapter
|
||||
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import com.hannesdorfmann.adapterdelegates4.AsyncListDifferDelegationAdapter
|
||||
import org.koitharu.kotatsu.base.ui.list.OnListItemClickListener
|
||||
import org.koitharu.kotatsu.settings.onboard.model.SourceLocale
|
||||
|
||||
class SourceLocalesAdapter(
|
||||
clickListener: OnListItemClickListener<SourceLocale>,
|
||||
) : AsyncListDifferDelegationAdapter<SourceLocale>(DiffCallback()) {
|
||||
|
||||
init {
|
||||
delegatesManager.addDelegate(sourceLocaleAD(clickListener))
|
||||
}
|
||||
|
||||
private class DiffCallback : DiffUtil.ItemCallback<SourceLocale>() {
|
||||
|
||||
override fun areItemsTheSame(
|
||||
oldItem: SourceLocale,
|
||||
newItem: SourceLocale,
|
||||
): Boolean = oldItem.key == newItem.key
|
||||
|
||||
override fun areContentsTheSame(
|
||||
oldItem: SourceLocale,
|
||||
newItem: SourceLocale,
|
||||
): Boolean = oldItem == newItem
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package org.koitharu.kotatsu.settings.onboard.model
|
||||
|
||||
import java.util.*
|
||||
|
||||
data class SourceLocale(
|
||||
val key: String?,
|
||||
val title: String?,
|
||||
val isChecked: Boolean,
|
||||
) : Comparable<SourceLocale> {
|
||||
|
||||
override fun compareTo(other: SourceLocale): Int {
|
||||
return when {
|
||||
this === other -> 0
|
||||
key == Locale.getDefault().language -> -2
|
||||
key == null -> 1
|
||||
other.key == null -> -1
|
||||
else -> compareValues(title, other.title)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,7 @@
|
||||
package org.koitharu.kotatsu.settings.sources
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.*
|
||||
import androidx.core.graphics.Insets
|
||||
import androidx.core.view.updatePadding
|
||||
import androidx.recyclerview.widget.DividerItemDecoration
|
||||
@@ -16,6 +14,7 @@ import org.koitharu.kotatsu.base.ui.list.OnListItemClickListener
|
||||
import org.koitharu.kotatsu.core.model.MangaSource
|
||||
import org.koitharu.kotatsu.databinding.FragmentSettingsSourcesBinding
|
||||
import org.koitharu.kotatsu.settings.SettingsActivity
|
||||
import org.koitharu.kotatsu.settings.onboard.OnboardDialogFragment
|
||||
|
||||
class SourcesSettingsFragment : BaseFragment<FragmentSettingsSourcesBinding>(),
|
||||
OnListItemClickListener<MangaSource> {
|
||||
@@ -25,6 +24,7 @@ class SourcesSettingsFragment : BaseFragment<FragmentSettingsSourcesBinding>(),
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
reorderHelper = ItemTouchHelper(SourcesReorderCallback())
|
||||
setHasOptionsMenu(true)
|
||||
}
|
||||
|
||||
override fun onInflateView(
|
||||
@@ -51,6 +51,22 @@ class SourcesSettingsFragment : BaseFragment<FragmentSettingsSourcesBinding>(),
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater)
|
||||
// TODO handle changes in dialog
|
||||
// inflater.inflate(R.menu.opt_sources, menu)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
return when(item.itemId) {
|
||||
R.id.action_languages -> {
|
||||
OnboardDialogFragment.show(parentFragmentManager)
|
||||
true
|
||||
}
|
||||
else -> super.onOptionsItemSelected(item)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onWindowInsetsChanged(insets: Insets) {
|
||||
binding.recyclerView.updatePadding(
|
||||
bottom = insets.bottom,
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package org.koitharu.kotatsu.utils.ext
|
||||
|
||||
import androidx.core.os.LocaleListCompat
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
fun LocaleListCompat.toList(): List<Locale> {
|
||||
val list = ArrayList<Locale>(size())
|
||||
for (i in 0 until size()) {
|
||||
list += get(i)
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
inline fun <R, C : MutableCollection<in R>> LocaleListCompat.mapTo(
|
||||
destination: C,
|
||||
block: (Locale) -> R,
|
||||
): C {
|
||||
val len = size()
|
||||
for (i in 0 until len) {
|
||||
val item = get(i)
|
||||
destination.add(block(item))
|
||||
}
|
||||
return destination
|
||||
}
|
||||
|
||||
inline fun <T> LocaleListCompat.map(block: (Locale) -> T): List<T> {
|
||||
return mapTo(ArrayList(size()), block)
|
||||
}
|
||||
11
app/src/main/res/drawable/ic_locale.xml
Normal file
11
app/src/main/res/drawable/ic_locale.xml
Normal file
@@ -0,0 +1,11 @@
|
||||
<vector
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M12.87,15.07l-2.54,-2.51 0.03,-0.03c1.74,-1.94 2.98,-4.17 3.71,-6.53L17,6L17,4h-7L10,2L8,2v2L1,4v1.99h11.17C11.5,7.92 10.44,9.75 9,11.35 8.07,10.32 7.3,9.19 6.69,8h-2c0.73,1.63 1.73,3.17 2.98,4.56l-5.09,5.02L4,19l5,-5 3.11,3.11 0.76,-2.04zM18.5,10h-2L12,22h2l1.12,-3h4.75L21,22h2l-4.5,-12zM15.88,17l1.62,-4.33L19.12,17h-3.24z" />
|
||||
</vector>
|
||||
29
app/src/main/res/layout/dialog_onboard.xml
Normal file
29
app/src/main/res/layout/dialog_onboard.xml
Normal file
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
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:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="?listPreferredItemPaddingStart"
|
||||
android:paddingTop="6dp"
|
||||
android:paddingEnd="?listPreferredItemPaddingEnd"
|
||||
android:paddingBottom="6dp"
|
||||
android:text="Select languages which you want to read manga. You can change it later in settings."
|
||||
android:textAppearance="?android:textAppearanceSmall" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:scrollbars="vertical"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
tools:listitem="@layout/item_source_locale" />
|
||||
|
||||
</LinearLayout>
|
||||
16
app/src/main/res/layout/item_source_locale.xml
Normal file
16
app/src/main/res/layout/item_source_locale.xml
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<CheckedTextView
|
||||
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="?selectableItemBackground"
|
||||
android:drawableStart="?android:listChoiceIndicatorMultiple"
|
||||
android:drawablePadding="10dp"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingStart="?listPreferredItemPaddingStart"
|
||||
android:paddingEnd="?listPreferredItemPaddingEnd"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
tools:text="@tools:sample/lorem[2]" />
|
||||
12
app/src/main/res/menu/opt_sources.xml
Normal file
12
app/src/main/res/menu/opt_sources.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/action_languages"
|
||||
android:icon="@drawable/ic_locale"
|
||||
android:title="@string/languages"
|
||||
app:showAsAction="ifRoom" />
|
||||
|
||||
</menu>
|
||||
@@ -207,4 +207,7 @@
|
||||
<string name="password_length_hint">Пароль должен содержать не менее 4 символов</string>
|
||||
<string name="hide_toolbar">Прятать заголовок при прокрутке</string>
|
||||
<string name="search_only_on_s">Поиск только по %s</string>
|
||||
<string name="other">Другие</string>
|
||||
<string name="languages">Languages</string>
|
||||
<string name="welcome">Welcome</string>
|
||||
</resources>
|
||||
@@ -210,4 +210,7 @@
|
||||
<string name="hide_toolbar">Hide toolbar when scrolling</string>
|
||||
<string name="search_only_on_s">Search only on %s</string>
|
||||
<string name="text_clear_search_history_prompt">Do you really want to remove all recent search queries? This action cannot be undone.</string>
|
||||
<string name="other">Other</string>
|
||||
<string name="languages">Languages</string>
|
||||
<string name="welcome">Welcome</string>
|
||||
</resources>
|
||||
Reference in New Issue
Block a user