[feature] add ability to set global filter/sort/display for Manga chapters (#3622)
* - [feature] add ability to set global filter/sort/display for Manga chapters * - move default chapter settings functionality to overflow menu - code clean up * - show confirmation dialog when user selects "Set as Default" option in Chapter Settings * - hide overflow menu in LibrarySettingsSheet * - apply default chapter settings if manga is added to Library from a Source's browsing screen Co-authored-by: arkon <arkon@users.noreply.github.com>
This commit is contained in:
parent
791a7d5a01
commit
64050e8266
14 changed files with 252 additions and 19 deletions
|
@ -83,6 +83,11 @@ interface MangaQueries : DbProvider {
|
||||||
.withPutResolver(MangaFlagsPutResolver())
|
.withPutResolver(MangaFlagsPutResolver())
|
||||||
.prepare()
|
.prepare()
|
||||||
|
|
||||||
|
fun updateFlags(mangas: List<Manga>) = db.put()
|
||||||
|
.objects(mangas)
|
||||||
|
.withPutResolver(MangaFlagsPutResolver(true))
|
||||||
|
.prepare()
|
||||||
|
|
||||||
fun updateLastUpdated(manga: Manga) = db.put()
|
fun updateLastUpdated(manga: Manga) = db.put()
|
||||||
.`object`(manga)
|
.`object`(manga)
|
||||||
.withPutResolver(MangaLastUpdatedPutResolver())
|
.withPutResolver(MangaLastUpdatedPutResolver())
|
||||||
|
|
|
@ -9,7 +9,7 @@ import eu.kanade.tachiyomi.data.database.inTransactionReturn
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable
|
import eu.kanade.tachiyomi.data.database.tables.MangaTable
|
||||||
|
|
||||||
class MangaFlagsPutResolver : PutResolver<Manga>() {
|
class MangaFlagsPutResolver(private val updateAll: Boolean = false) : PutResolver<Manga>() {
|
||||||
|
|
||||||
override fun performPut(db: StorIOSQLite, manga: Manga) = db.inTransactionReturn {
|
override fun performPut(db: StorIOSQLite, manga: Manga) = db.inTransactionReturn {
|
||||||
val updateQuery = mapToUpdateQuery(manga)
|
val updateQuery = mapToUpdateQuery(manga)
|
||||||
|
@ -19,11 +19,21 @@ class MangaFlagsPutResolver : PutResolver<Manga>() {
|
||||||
PutResult.newUpdateResult(numberOfRowsUpdated, updateQuery.table())
|
PutResult.newUpdateResult(numberOfRowsUpdated, updateQuery.table())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun mapToUpdateQuery(manga: Manga) = UpdateQuery.builder()
|
fun mapToUpdateQuery(manga: Manga): UpdateQuery {
|
||||||
.table(MangaTable.TABLE)
|
val builder = UpdateQuery.builder()
|
||||||
.where("${MangaTable.COL_ID} = ?")
|
|
||||||
.whereArgs(manga.id)
|
return if (updateAll) {
|
||||||
.build()
|
builder
|
||||||
|
.table(MangaTable.TABLE)
|
||||||
|
.build()
|
||||||
|
} else {
|
||||||
|
builder
|
||||||
|
.table(MangaTable.TABLE)
|
||||||
|
.where("${MangaTable.COL_ID} = ?")
|
||||||
|
.whereArgs(manga.id)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun mapToContentValues(manga: Manga) = ContentValues(1).apply {
|
fun mapToContentValues(manga: Manga) = ContentValues(1).apply {
|
||||||
put(MangaTable.COL_CHAPTER_FLAGS, manga.chapter_flags)
|
put(MangaTable.COL_CHAPTER_FLAGS, manga.chapter_flags)
|
||||||
|
|
|
@ -165,6 +165,18 @@ object PreferenceKeys {
|
||||||
|
|
||||||
const val enableDoh = "enable_doh"
|
const val enableDoh = "enable_doh"
|
||||||
|
|
||||||
|
const val defaultChapterFilterByRead = "default_chapter_filter_by_read"
|
||||||
|
|
||||||
|
const val defaultChapterFilterByDownloaded = "default_chapter_filter_by_downloaded"
|
||||||
|
|
||||||
|
const val defaultChapterFilterByBookmarked = "default_chapter_filter_by_bookmarked"
|
||||||
|
|
||||||
|
const val defaultChapterSortBySourceOrNumber = "default_chapter_sort_by_source_or_number" // and upload date
|
||||||
|
|
||||||
|
const val defaultChapterSortByAscendingOrDescending = "default_chapter_sort_by_ascending_or_descending"
|
||||||
|
|
||||||
|
const val defaultChapterDisplayByNameOrNumber = "default_chapter_display_by_name_or_number"
|
||||||
|
|
||||||
fun trackUsername(syncId: Int) = "pref_mangasync_username_$syncId"
|
fun trackUsername(syncId: Int) = "pref_mangasync_username_$syncId"
|
||||||
|
|
||||||
fun trackPassword(syncId: Int) = "pref_mangasync_password_$syncId"
|
fun trackPassword(syncId: Int) = "pref_mangasync_password_$syncId"
|
||||||
|
|
|
@ -2,11 +2,15 @@ package eu.kanade.tachiyomi.data.preference
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Environment
|
import android.os.Environment
|
||||||
|
import androidx.core.content.edit
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
import com.tfcporciuncula.flow.FlowSharedPreferences
|
import com.tfcporciuncula.flow.FlowSharedPreferences
|
||||||
import com.tfcporciuncula.flow.Preference
|
import com.tfcporciuncula.flow.Preference
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
|
import eu.kanade.tachiyomi.data.preference.PreferenceKeys as Keys
|
||||||
|
import eu.kanade.tachiyomi.data.preference.PreferenceValues as Values
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferenceValues.DisplayMode
|
import eu.kanade.tachiyomi.data.preference.PreferenceValues.DisplayMode
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferenceValues.NsfwAllowance
|
import eu.kanade.tachiyomi.data.preference.PreferenceValues.NsfwAllowance
|
||||||
import eu.kanade.tachiyomi.data.track.TrackService
|
import eu.kanade.tachiyomi.data.track.TrackService
|
||||||
|
@ -18,8 +22,6 @@ import java.io.File
|
||||||
import java.text.DateFormat
|
import java.text.DateFormat
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferenceKeys as Keys
|
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferenceValues as Values
|
|
||||||
|
|
||||||
@OptIn(ExperimentalCoroutinesApi::class)
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
fun <T> Preference<T>.asImmediateFlow(block: (value: T) -> Unit): Flow<T> {
|
fun <T> Preference<T>.asImmediateFlow(block: (value: T) -> Unit): Flow<T> {
|
||||||
|
@ -249,4 +251,29 @@ class PreferencesHelper(val context: Context) {
|
||||||
fun trustedSignatures() = flowPrefs.getStringSet("trusted_signatures", emptySet())
|
fun trustedSignatures() = flowPrefs.getStringSet("trusted_signatures", emptySet())
|
||||||
|
|
||||||
fun enableDoh() = prefs.getBoolean(Keys.enableDoh, false)
|
fun enableDoh() = prefs.getBoolean(Keys.enableDoh, false)
|
||||||
|
|
||||||
|
fun filterChapterByRead() = prefs.getInt(Keys.defaultChapterFilterByRead, Manga.SHOW_ALL)
|
||||||
|
|
||||||
|
fun filterChapterByDownloaded() = prefs.getInt(Keys.defaultChapterFilterByDownloaded, Manga.SHOW_ALL)
|
||||||
|
|
||||||
|
fun filterChapterByBookmarked() = prefs.getInt(Keys.defaultChapterFilterByBookmarked, Manga.SHOW_ALL)
|
||||||
|
|
||||||
|
fun sortChapterBySourceOrNumber() = prefs.getInt(Keys.defaultChapterSortBySourceOrNumber, Manga.SORTING_SOURCE)
|
||||||
|
|
||||||
|
fun displayChapterByNameOrNumber() = prefs.getInt(Keys.defaultChapterDisplayByNameOrNumber, Manga.DISPLAY_NAME)
|
||||||
|
|
||||||
|
fun sortChapterByAscendingOrDescending() = prefs.getInt(Keys.defaultChapterSortByAscendingOrDescending, Manga.SORT_DESC)
|
||||||
|
|
||||||
|
fun setChapterSettingsDefault(m: Manga) {
|
||||||
|
prefs.edit {
|
||||||
|
putInt(Keys.defaultChapterFilterByRead, m.readFilter)
|
||||||
|
putInt(Keys.defaultChapterFilterByDownloaded, m.downloadedFilter)
|
||||||
|
putInt(Keys.defaultChapterFilterByBookmarked, m.bookmarkedFilter)
|
||||||
|
putInt(Keys.defaultChapterSortBySourceOrNumber, m.sorting)
|
||||||
|
putInt(Keys.defaultChapterDisplayByNameOrNumber, m.displayMode)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m.sortDescending()) prefs.edit { putInt(Keys.defaultChapterSortByAscendingOrDescending, Manga.SORT_DESC) }
|
||||||
|
else prefs.edit { putInt(Keys.defaultChapterSortByAscendingOrDescending, Manga.SORT_ASC) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ import eu.kanade.tachiyomi.ui.browse.source.filter.TextItem
|
||||||
import eu.kanade.tachiyomi.ui.browse.source.filter.TextSectionItem
|
import eu.kanade.tachiyomi.ui.browse.source.filter.TextSectionItem
|
||||||
import eu.kanade.tachiyomi.ui.browse.source.filter.TriStateItem
|
import eu.kanade.tachiyomi.ui.browse.source.filter.TriStateItem
|
||||||
import eu.kanade.tachiyomi.ui.browse.source.filter.TriStateSectionItem
|
import eu.kanade.tachiyomi.ui.browse.source.filter.TriStateSectionItem
|
||||||
|
import eu.kanade.tachiyomi.util.chapter.ChapterSettingsHelper
|
||||||
import eu.kanade.tachiyomi.util.removeCovers
|
import eu.kanade.tachiyomi.util.removeCovers
|
||||||
import kotlinx.coroutines.flow.subscribe
|
import kotlinx.coroutines.flow.subscribe
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
|
@ -268,6 +269,8 @@ open class BrowseSourcePresenter(
|
||||||
|
|
||||||
if (!manga.favorite) {
|
if (!manga.favorite) {
|
||||||
manga.removeCovers(coverCache)
|
manga.removeCovers(coverCache)
|
||||||
|
} else {
|
||||||
|
ChapterSettingsHelper.applySettingDefaultsFromPreferences(manga)
|
||||||
}
|
}
|
||||||
|
|
||||||
db.insertManga(manga).executeAsBlocking()
|
db.insertManga(manga).executeAsBlocking()
|
||||||
|
|
|
@ -18,6 +18,7 @@ import eu.kanade.tachiyomi.source.LocalSource
|
||||||
import eu.kanade.tachiyomi.source.Source
|
import eu.kanade.tachiyomi.source.Source
|
||||||
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
||||||
import eu.kanade.tachiyomi.ui.manga.chapter.ChapterItem
|
import eu.kanade.tachiyomi.ui.manga.chapter.ChapterItem
|
||||||
|
import eu.kanade.tachiyomi.util.chapter.ChapterSettingsHelper
|
||||||
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
|
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
|
||||||
import eu.kanade.tachiyomi.util.isLocal
|
import eu.kanade.tachiyomi.util.isLocal
|
||||||
import eu.kanade.tachiyomi.util.lang.isNullOrUnsubscribed
|
import eu.kanade.tachiyomi.util.lang.isNullOrUnsubscribed
|
||||||
|
@ -82,6 +83,10 @@ class MangaPresenter(
|
||||||
override fun onCreate(savedState: Bundle?) {
|
override fun onCreate(savedState: Bundle?) {
|
||||||
super.onCreate(savedState)
|
super.onCreate(savedState)
|
||||||
|
|
||||||
|
if (!manga.favorite) {
|
||||||
|
ChapterSettingsHelper.applySettingDefaultsFromPreferences(manga)
|
||||||
|
}
|
||||||
|
|
||||||
// Manga info - start
|
// Manga info - start
|
||||||
|
|
||||||
getMangaObservable()
|
getMangaObservable()
|
||||||
|
|
|
@ -14,7 +14,7 @@ class ChaptersSettingsSheet(
|
||||||
activity: Activity,
|
activity: Activity,
|
||||||
private val presenter: MangaPresenter,
|
private val presenter: MangaPresenter,
|
||||||
onGroupClickListener: (ExtendedNavigationView.Group) -> Unit
|
onGroupClickListener: (ExtendedNavigationView.Group) -> Unit
|
||||||
) : TabbedBottomSheetDialog(activity) {
|
) : TabbedBottomSheetDialog(activity, presenter.manga) {
|
||||||
|
|
||||||
val filters: Filter
|
val filters: Filter
|
||||||
private val sort: Sort
|
private val sort: Sort
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
package eu.kanade.tachiyomi.ui.manga.chapter
|
||||||
|
|
||||||
|
import android.app.Dialog
|
||||||
|
import android.content.Context
|
||||||
|
import com.afollestad.materialdialogs.MaterialDialog
|
||||||
|
import com.afollestad.materialdialogs.customview.customView
|
||||||
|
import eu.kanade.tachiyomi.R
|
||||||
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
|
import eu.kanade.tachiyomi.util.chapter.ChapterSettingsHelper
|
||||||
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
|
import eu.kanade.tachiyomi.widget.DialogCheckboxView
|
||||||
|
|
||||||
|
class SetChapterSettingsDialog(val context: Context, val manga: Manga) {
|
||||||
|
private var dialog: Dialog
|
||||||
|
|
||||||
|
init {
|
||||||
|
this.dialog = buildDialog()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun buildDialog(): Dialog {
|
||||||
|
val view = DialogCheckboxView(context).apply {
|
||||||
|
setDescription(R.string.confirm_set_chapter_settings)
|
||||||
|
setOptionDescription(R.string.also_set_chapter_settings_for_library)
|
||||||
|
}
|
||||||
|
|
||||||
|
return MaterialDialog(context)
|
||||||
|
.title(R.string.action_chapter_settings)
|
||||||
|
.customView(
|
||||||
|
view = view,
|
||||||
|
horizontalPadding = true
|
||||||
|
)
|
||||||
|
.positiveButton(android.R.string.ok) {
|
||||||
|
ChapterSettingsHelper.setNewSettingDefaults(manga)
|
||||||
|
if (view.isChecked()) {
|
||||||
|
ChapterSettingsHelper.updateAllMangasWithDefaultsFromPreferences()
|
||||||
|
}
|
||||||
|
|
||||||
|
context.toast(context.getString(R.string.chapter_settings_updated))
|
||||||
|
}
|
||||||
|
.negativeButton(android.R.string.cancel)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun showDialog() = dialog.show()
|
||||||
|
|
||||||
|
fun dismissDialog() = dialog.dismiss()
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
package eu.kanade.tachiyomi.util.chapter
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||||
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
|
import eu.kanade.tachiyomi.util.lang.launchIO
|
||||||
|
import uy.kohesive.injekt.Injekt
|
||||||
|
import uy.kohesive.injekt.api.get
|
||||||
|
|
||||||
|
object ChapterSettingsHelper {
|
||||||
|
private val prefs = Injekt.get<PreferencesHelper>()
|
||||||
|
private val db: DatabaseHelper = Injekt.get()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* updates the Chapter Settings in Preferences
|
||||||
|
*/
|
||||||
|
fun setNewSettingDefaults(m: Manga?) {
|
||||||
|
m?.let {
|
||||||
|
prefs.setChapterSettingsDefault(it)
|
||||||
|
db.updateFlags(it).executeAsBlocking()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* updates a single manga's Chapter Settings to match what's set in Preferences
|
||||||
|
*/
|
||||||
|
fun applySettingDefaultsFromPreferences(m: Manga) {
|
||||||
|
m.readFilter = prefs.filterChapterByRead()
|
||||||
|
m.downloadedFilter = prefs.filterChapterByDownloaded()
|
||||||
|
m.bookmarkedFilter = prefs.filterChapterByBookmarked()
|
||||||
|
m.sorting = prefs.sortChapterBySourceOrNumber()
|
||||||
|
m.displayMode = prefs.displayChapterByNameOrNumber()
|
||||||
|
m.setChapterOrder(prefs.sortChapterByAscendingOrDescending())
|
||||||
|
db.updateFlags(m).executeAsBlocking()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* updates all mangas in database Chapter Settings to match what's set in Preferences
|
||||||
|
*/
|
||||||
|
fun updateAllMangasWithDefaultsFromPreferences() {
|
||||||
|
launchIO {
|
||||||
|
val dbMangas = db.getMangas().executeAsBlocking().toMutableList()
|
||||||
|
|
||||||
|
val updatedMangas = dbMangas.map { m ->
|
||||||
|
m.readFilter = prefs.filterChapterByRead()
|
||||||
|
m.downloadedFilter = prefs.filterChapterByDownloaded()
|
||||||
|
m.bookmarkedFilter = prefs.filterChapterByBookmarked()
|
||||||
|
m.sorting = prefs.sortChapterBySourceOrNumber()
|
||||||
|
m.displayMode = prefs.displayChapterByNameOrNumber()
|
||||||
|
m.setChapterOrder(prefs.sortChapterByAscendingOrDescending())
|
||||||
|
m
|
||||||
|
}.toList()
|
||||||
|
|
||||||
|
db.updateFlags(updatedMangas).executeAsBlocking()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -64,7 +64,7 @@ inline fun View.popupMenu(
|
||||||
@MenuRes menuRes: Int,
|
@MenuRes menuRes: Int,
|
||||||
noinline initMenu: (Menu.() -> Unit)? = null,
|
noinline initMenu: (Menu.() -> Unit)? = null,
|
||||||
noinline onMenuItemClick: MenuItem.() -> Boolean
|
noinline onMenuItemClick: MenuItem.() -> Boolean
|
||||||
) {
|
): PopupMenu {
|
||||||
val popup = PopupMenu(context, this, Gravity.NO_GRAVITY, R.attr.actionOverflowMenuStyle, 0)
|
val popup = PopupMenu(context, this, Gravity.NO_GRAVITY, R.attr.actionOverflowMenuStyle, 0)
|
||||||
popup.menuInflater.inflate(menuRes, popup.menu)
|
popup.menuInflater.inflate(menuRes, popup.menu)
|
||||||
|
|
||||||
|
@ -74,6 +74,7 @@ inline fun View.popupMenu(
|
||||||
popup.setOnMenuItemClickListener { it.onMenuItemClick() }
|
popup.setOnMenuItemClickListener { it.onMenuItemClick() }
|
||||||
|
|
||||||
popup.show()
|
popup.show()
|
||||||
|
return popup
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -4,21 +4,49 @@ import android.app.Activity
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||||
|
import eu.kanade.tachiyomi.R
|
||||||
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
import eu.kanade.tachiyomi.databinding.CommonTabbedSheetBinding
|
import eu.kanade.tachiyomi.databinding.CommonTabbedSheetBinding
|
||||||
|
import eu.kanade.tachiyomi.ui.manga.chapter.SetChapterSettingsDialog
|
||||||
|
import eu.kanade.tachiyomi.util.view.popupMenu
|
||||||
|
|
||||||
abstract class TabbedBottomSheetDialog(private val activity: Activity) : BottomSheetDialog(activity) {
|
abstract class TabbedBottomSheetDialog(private val activity: Activity, private val manga: Manga? = null) : BottomSheetDialog(activity) {
|
||||||
|
val binding: CommonTabbedSheetBinding = CommonTabbedSheetBinding.inflate(activity.layoutInflater)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val binding: CommonTabbedSheetBinding = CommonTabbedSheetBinding.inflate(activity.layoutInflater)
|
|
||||||
|
|
||||||
val adapter = LibrarySettingsSheetAdapter()
|
val adapter = LibrarySettingsSheetAdapter()
|
||||||
binding.pager.offscreenPageLimit = 2
|
binding.pager.offscreenPageLimit = 2
|
||||||
binding.pager.adapter = adapter
|
binding.pager.adapter = adapter
|
||||||
binding.tabs.setupWithViewPager(binding.pager)
|
binding.tabs.setupWithViewPager(binding.pager)
|
||||||
|
|
||||||
|
// currently, we only need to show the overflow menu if this is a ChaptersSettingsSheet
|
||||||
|
if (manga != null) {
|
||||||
|
binding.menu.visibility = View.VISIBLE
|
||||||
|
binding.menu.setOnClickListener { it.post { showPopupMenu(it) } }
|
||||||
|
} else {
|
||||||
|
binding.menu.visibility = View.GONE
|
||||||
|
}
|
||||||
|
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun showPopupMenu(view: View) {
|
||||||
|
view.popupMenu(
|
||||||
|
R.menu.default_chapter_filter,
|
||||||
|
{
|
||||||
|
},
|
||||||
|
{
|
||||||
|
when (this.itemId) {
|
||||||
|
R.id.save_as_default -> {
|
||||||
|
manga?.let { SetChapterSettingsDialog(context, it).showDialog() }
|
||||||
|
true
|
||||||
|
}
|
||||||
|
else -> true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
abstract fun getTabViews(): List<View>
|
abstract fun getTabViews(): List<View>
|
||||||
|
|
||||||
abstract fun getTabTitles(): List<Int>
|
abstract fun getTabTitles(): List<Int>
|
||||||
|
|
|
@ -1,17 +1,42 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<com.google.android.material.tabs.TabLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:id="@+id/tabs"
|
|
||||||
style="@style/Theme.Widget.Tabs"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content">
|
||||||
app:tabGravity="fill"
|
|
||||||
app:tabMode="fixed" />
|
<com.google.android.material.tabs.TabLayout
|
||||||
|
android:id="@+id/tabs"
|
||||||
|
style="@style/Theme.Widget.Tabs"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/menu"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:tabGravity="fill"
|
||||||
|
app:tabMode="fixed" />
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/menu"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?selectableItemBackgroundBorderless"
|
||||||
|
android:contentDescription="@string/action_menu"
|
||||||
|
android:paddingStart="10dp"
|
||||||
|
android:paddingEnd="10dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:srcCompat="@drawable/ic_more_vert_24dp"
|
||||||
|
app:tint="?attr/colorOnBackground" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
<eu.kanade.tachiyomi.widget.MaxHeightViewPager
|
<eu.kanade.tachiyomi.widget.MaxHeightViewPager
|
||||||
android:id="@+id/pager"
|
android:id="@+id/pager"
|
||||||
|
|
8
app/src/main/res/menu/default_chapter_filter.xml
Normal file
8
app/src/main/res/menu/default_chapter_filter.xml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<?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/save_as_default"
|
||||||
|
android:title="@string/set_chapter_settings_as_default" />
|
||||||
|
|
||||||
|
</menu>
|
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
<!-- Actions -->
|
<!-- Actions -->
|
||||||
<string name="action_settings">Settings</string>
|
<string name="action_settings">Settings</string>
|
||||||
|
<string name="action_chapter_settings">Chapter Settings</string>
|
||||||
<string name="action_menu">Menu</string>
|
<string name="action_menu">Menu</string>
|
||||||
<string name="action_filter">Filter</string>
|
<string name="action_filter">Filter</string>
|
||||||
<string name="action_filter_downloaded">Downloaded</string>
|
<string name="action_filter_downloaded">Downloaded</string>
|
||||||
|
@ -524,6 +525,9 @@
|
||||||
<string name="download_unread">Unread</string>
|
<string name="download_unread">Unread</string>
|
||||||
<string name="confirm_delete_chapters">Are you sure you want to delete the selected chapters?</string>
|
<string name="confirm_delete_chapters">Are you sure you want to delete the selected chapters?</string>
|
||||||
<string name="invalid_download_dir">Invalid download location</string>
|
<string name="invalid_download_dir">Invalid download location</string>
|
||||||
|
<string name="confirm_set_chapter_settings">Are you sure you want to save these settings as default?</string>
|
||||||
|
<string name="also_set_chapter_settings_for_library">Also apply to all manga in my Library</string>
|
||||||
|
<string name="set_chapter_settings_as_default">Set as Default</string>
|
||||||
<string name="no_chapters_error">No chapters found</string>
|
<string name="no_chapters_error">No chapters found</string>
|
||||||
|
|
||||||
<!-- Tracking Screen -->
|
<!-- Tracking Screen -->
|
||||||
|
@ -678,6 +682,7 @@
|
||||||
<string name="information_cloudflare_bypass_failure">Failed to bypass Cloudflare</string>
|
<string name="information_cloudflare_bypass_failure">Failed to bypass Cloudflare</string>
|
||||||
<string name="information_webview_required">WebView is required for Tachiyomi</string>
|
<string name="information_webview_required">WebView is required for Tachiyomi</string>
|
||||||
<string name="information_webview_outdated">Please update the WebView app for better compatibility</string>
|
<string name="information_webview_outdated">Please update the WebView app for better compatibility</string>
|
||||||
|
<string name="chapter_settings_updated">Updated default chapter settings</string>
|
||||||
|
|
||||||
<!-- Download Notification -->
|
<!-- Download Notification -->
|
||||||
<string name="download_notifier_downloader_title">Downloader</string>
|
<string name="download_notifier_downloader_title">Downloader</string>
|
||||||
|
@ -705,4 +710,5 @@
|
||||||
<string name="tapping_inverted_horizontal">Horizontal</string>
|
<string name="tapping_inverted_horizontal">Horizontal</string>
|
||||||
<string name="tapping_inverted_vertical">Vertical</string>
|
<string name="tapping_inverted_vertical">Vertical</string>
|
||||||
<string name="tapping_inverted_both">Both</string>
|
<string name="tapping_inverted_both">Both</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Reference in a new issue