From ef937f277e747dceba7683f37e07e0615e738766 Mon Sep 17 00:00:00 2001 From: inorichi Date: Tue, 22 Jun 2021 12:58:35 +0200 Subject: [PATCH 1/8] Update image decoder with better AVIF support --- app/build.gradle.kts | 2 +- app/src/main/java/eu/kanade/tachiyomi/util/system/ImageUtil.kt | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 698e7b88cc..76e7152ba0 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -219,7 +219,7 @@ dependencies { implementation("com.github.tachiyomiorg:subsampling-scale-image-view:846abe0") { exclude(module = "image-decoder") } - implementation("com.github.tachiyomiorg:image-decoder:ac5f65c") + implementation("com.github.tachiyomiorg:image-decoder:0e91111") // Logging implementation("com.jakewharton.timber:timber:4.7.1") diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/system/ImageUtil.kt b/app/src/main/java/eu/kanade/tachiyomi/util/system/ImageUtil.kt index f65c1e68eb..8c4ed31f0d 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/system/ImageUtil.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/util/system/ImageUtil.kt @@ -43,7 +43,6 @@ object ImageUtil { fun findImageType(stream: InputStream): ImageType? { try { return when (getImageType(stream)?.format) { - // TODO: image-decoder library currently doesn't actually detect AVIF yet Format.Avif -> ImageType.AVIF Format.Gif -> ImageType.GIF Format.Heif -> ImageType.HEIF From 88fd799a3069ac28dd667e84383662a103c0c12a Mon Sep 17 00:00:00 2001 From: Soitora Date: Wed, 23 Jun 2021 00:22:59 +0200 Subject: [PATCH 2/8] Add favorited badge to browse and search (#5440) --- .../browse/SourceComfortableGridHolder.kt | 7 +++++ .../browse/source/browse/SourceGridHolder.kt | 7 +++++ .../browse/source/browse/SourceListHolder.kt | 7 +++++ .../globalsearch/GlobalSearchCardHolder.kt | 9 +++++++ .../global_search_controller_card_item.xml | 26 +++++++++++++++++++ .../layout/source_comfortable_grid_item.xml | 16 ++++++++++++ .../res/layout/source_compact_grid_item.xml | 16 ++++++++++++ app/src/main/res/layout/source_list_item.xml | 16 ++++++++++++ 8 files changed, 104 insertions(+) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceComfortableGridHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceComfortableGridHolder.kt index cd4f42f218..6bbe76b8cc 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceComfortableGridHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceComfortableGridHolder.kt @@ -1,6 +1,7 @@ package eu.kanade.tachiyomi.ui.browse.source.browse import android.view.View +import androidx.core.view.isVisible import coil.clear import coil.imageLoader import coil.request.ImageRequest @@ -37,6 +38,12 @@ class SourceComfortableGridHolder(private val view: View, private val adapter: F // Set alpha of thumbnail. binding.thumbnail.alpha = if (manga.favorite) 0.3f else 1.0f + // For rounded corners + binding.badges.clipToOutline = true + + // Set favorite badge + binding.favoriteText.isVisible = manga.favorite + setImage(manga) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceGridHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceGridHolder.kt index a238003b5f..38b5363711 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceGridHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceGridHolder.kt @@ -1,6 +1,7 @@ package eu.kanade.tachiyomi.ui.browse.source.browse import android.view.View +import androidx.core.view.isVisible import coil.clear import coil.imageLoader import coil.request.ImageRequest @@ -37,6 +38,12 @@ open class SourceGridHolder(private val view: View, private val adapter: Flexibl // Set alpha of thumbnail. binding.thumbnail.alpha = if (manga.favorite) 0.3f else 1.0f + // For rounded corners + binding.badges.clipToOutline = true + + // Set favorite badge + binding.favoriteText.isVisible = manga.favorite + setImage(manga) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceListHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceListHolder.kt index a509c71e8e..c6d020fe83 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceListHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceListHolder.kt @@ -1,6 +1,7 @@ package eu.kanade.tachiyomi.ui.browse.source.browse import android.view.View +import androidx.core.view.isVisible import coil.clear import coil.loadAny import coil.transform.RoundedCornersTransformation @@ -40,6 +41,12 @@ class SourceListHolder(private val view: View, adapter: FlexibleAdapter<*>) : // Set alpha of thumbnail. binding.thumbnail.alpha = if (manga.favorite) 0.3f else 1.0f + // For rounded corners + binding.badges.clipToOutline = true + + // Set favorite badge + binding.favoriteText.isVisible = manga.favorite + setImage(manga) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/globalsearch/GlobalSearchCardHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/globalsearch/GlobalSearchCardHolder.kt index 4c5c23d280..a67e9785bc 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/globalsearch/GlobalSearchCardHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/globalsearch/GlobalSearchCardHolder.kt @@ -1,6 +1,7 @@ package eu.kanade.tachiyomi.ui.browse.source.globalsearch import android.view.View +import androidx.core.view.isVisible import coil.clear import coil.imageLoader import coil.request.ImageRequest @@ -36,10 +37,18 @@ class GlobalSearchCardHolder(view: View, adapter: GlobalSearchCardAdapter) : fun bind(manga: Manga) { binding.card.clipToOutline = true + // Set manga title binding.title.text = manga.title + // Set alpha of thumbnail. binding.cover.alpha = if (manga.favorite) 0.3f else 1.0f + // For rounded corners + binding.badges.clipToOutline = true + + // Set favorite badge + binding.favoriteText.isVisible = manga.favorite + setImage(manga) } diff --git a/app/src/main/res/layout/global_search_controller_card_item.xml b/app/src/main/res/layout/global_search_controller_card_item.xml index 5ab5c88cdc..50515dcdd0 100644 --- a/app/src/main/res/layout/global_search_controller_card_item.xml +++ b/app/src/main/res/layout/global_search_controller_card_item.xml @@ -38,6 +38,32 @@ tools:ignore="ContentDescription" tools:src="@mipmap/ic_launcher" /> + + + + + + + + + + + + From 98fc028d39a4d4830402b7f5565016cba8a3cf38 Mon Sep 17 00:00:00 2001 From: arkon Date: Thu, 24 Jun 2021 12:36:56 -0400 Subject: [PATCH 3/8] [skip ci] Remove explicit SKIP CI workflow logic GitHub has it built-in now: https://github.blog/changelog/2021-02-08-github-actions-skip-pull-request-and-push-workflows-with-skip-ci/ --- .github/workflows/build.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 881ff3f0cf..8868196f40 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -22,7 +22,6 @@ jobs: build: name: Build app needs: check_wrapper - if: "!startsWith(github.event.head_commit.message, '[SKIP CI]')" runs-on: ubuntu-latest steps: From e31a39b9d515a693aa09aed95f54c6153f24ba57 Mon Sep 17 00:00:00 2001 From: Soitora Date: Fri, 25 Jun 2021 18:56:26 +0200 Subject: [PATCH 4/8] [skip ci] Convert issue templates to the new issue forms (#5454) * [SKIP-CI] Update issue config * [SKIP-CI] Delete redundant Source Issue * [SKIP-CI] Convert bug report to an issue form * [SKIP-CI] Convert feature request to an issue form --- .github/ISSUE_TEMPLATE/bug_report.md | 44 --------- .github/ISSUE_TEMPLATE/bug_report.yml | 106 +++++++++++++++++++++ .github/ISSUE_TEMPLATE/config.yml | 13 ++- .github/ISSUE_TEMPLATE/feature_request.md | 29 ------ .github/ISSUE_TEMPLATE/feature_request.yml | 39 ++++++++ .github/ISSUE_TEMPLATE/source_issue.md | 8 -- 6 files changed, 153 insertions(+), 86 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml delete mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yml delete mode 100644 .github/ISSUE_TEMPLATE/source_issue.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index bac8225441..0000000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -name: "🐞 Bug report" -about: Report a bug -title: "[Bug] " -labels: "bug" ---- - -**PLEASE READ THIS** - -I acknowledge that: - -- I have updated: - - To the latest version of the app (stable is v0.11.1) - - All extensions -- I have tried the troubleshooting guide: https://tachiyomi.org/help/guides/troubleshooting-problems/ -- If this is an issue with an extension, that I should be opening an issue in https://github.com/tachiyomiorg/tachiyomi-extensions -- I have searched the existing issues and this is new ticket **NOT** a duplicate or related to another open issue -- I will fill out the title and the information in this template - -Note that the issue will be automatically closed if you do not fill out the title or requested information. - -**DELETE THIS SECTION IF YOU HAVE READ AND ACKNOWLEDGED IT** - ---- - -## Device information -* Tachiyomi version: ? -* Android version: ? -* Device: ? - -## Steps to reproduce -1. First step -2. Second step - -### Expected behavior -This should happen. - -### Actual behavior -This happened instead. - -## Other details -Additional details and attachments. - -If you're experiencing crashes, share the crash logs from More → Settings → Advanced → Dump crash logs. diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000000..5fe005b146 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,106 @@ +name: 🐞 Bug report +description: Report a bug in Tachiyomi +labels: [Bug] +body: + + - type: checkboxes + id: acknowledgements + attributes: + label: Acknowledgements + description: Read this carefully, we will close and ignore your issue if you skimmed through this. + options: + - label: I have searched the existing issues and this is a new ticket, **NOT** a duplicate or related to another open issue. + required: true + - label: I have written a short but informative title. + required: true + - label: If this is an issue with an extension, I should be opening an issue in the [extensions repository](https://github.com/tachiyomiorg/tachiyomi-extensions/issues/new/choose). + required: true + - label: I have tried the [troubleshooting guide](https://tachiyomi.org/help/guides/troubleshooting/). + required: true + - label: I have updated the app to version **[0.11.1](https://github.com/tachiyomiorg/tachiyomi/releases/tag/v0.11.1)**. + required: true + - label: I have updated all installed extensions. + required: true + - label: I will fill out all of the requested information in this form. + required: true + + - type: input + id: tachiyomi-version + attributes: + label: Tachiyomi version + description: You can find your Tachiyomi version in **More → About**. + placeholder: | + Example: "0.11.1" + validations: + required: true + + - type: input + id: android-version + attributes: + label: Android version + description: You can find this somewhere in your Android settings. + placeholder: | + Example: "Android 11" + validations: + required: true + + - type: input + id: device + attributes: + label: Device + description: List your device and model. + placeholder: | + Example: "Google Pixel 5" + validations: + required: true + + - type: textarea + id: reproduce-steps + attributes: + label: Steps to reproduce + description: Provide an example of how to trigger the bug. + placeholder: | + Example: + 1. First step + 2. Second step + 3. Bug occurs + validations: + required: true + + - type: textarea + id: expected-behavior + attributes: + label: Expected behavior + description: Explain what you should expect to happen. + placeholder: | + Example: + "This should happen..." + validations: + required: true + + - type: textarea + id: actual-behavior + attributes: + label: Actual behavior + description: Explain what actually happens. + placeholder: | + Example: + "This happened instead..." + validations: + required: true + + - type: textarea + id: crash-logs + attributes: + label: Crash logs + description: | + If you're experiencing crashes, share the crash logs from **More → Settings → Advanced** then press **Dump crash logs**. + placeholder: | + You can paste the crash logs in pure text or upload it as an attachment. + + - type: textarea + id: other-details + attributes: + label: Other details + placeholder: | + Additional details and attachments. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index c7765d348f..a54157595c 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,8 +1,11 @@ blank_issues_enabled: false contact_links: - - name: Tachiyomi help website - url: https://tachiyomi.org/help/ - about: Common questions are answered here. - - name: Tachiyomi extensions GitHub repository + - name: ⚠️ Extension/source issue + url: https://github.com/tachiyomiorg/tachiyomi-extensions/issues/new/choose + about: Issues and requests for extensions and sources should be opened here. + - name: 📦 Tachiyomi extensions url: https://github.com/tachiyomiorg/tachiyomi-extensions - about: Issues about an extension/source/catalogue should be opened here instead. + about: Extensions and sources. + - name: 🌐 Tachiyomi website + url: https://tachiyomi.org/help/ + about: Guides, troubleshooting, and answers to common questions. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index ce8dafed8b..0000000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -name: "🌟 Feature request" -about: Suggest a feature to improve Tachiyomi -title: "[Feature Request] " -labels: "feature" ---- - -**PLEASE READ THIS** - -I acknowledge that: - -- I have updated: - - To the latest version of the app (stable is v0.11.1) - - All extensions -- If this is an issue with an extension, that I should be opening an issue in https://github.com/tachiyomiorg/tachiyomi-extensions -- I have searched the existing issues and this is new ticket **NOT** a duplicate or related to another open issue -- I will fill out the title and the information in this template - -Note that the issue will be automatically closed if you do not fill out the title or requested information. - -**DELETE THIS SECTION IF YOU HAVE READ AND ACKNOWLEDGED IT** - ---- - -## Why/User Benefit/User Problem -(explain why this feature should be added) - -## What/Requirements -(explain how this feature would behave) diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000000..3c9ed5e139 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,39 @@ +name: ⭐ Feature request +description: Suggest a feature for Tachiyomi +labels: [Feature request] +body: + + - type: checkboxes + id: acknowledgements + attributes: + label: Acknowledgements + description: Read this carefully, we will close and ignore your issue if you skimmed through this. + options: + - label: I have searched the existing issues and this is a new ticket, **NOT** a duplicate or related to another open issue. + required: true + - label: I have written a short but informative title. + required: true + - label: If this is an issue with an extension, I should be opening an issue in the [extensions repository](https://github.com/tachiyomiorg/tachiyomi-extensions/issues/new/choose). + required: true + - label: I have updated the app to version **[0.11.1](https://github.com/tachiyomiorg/tachiyomi/releases/tag/v0.11.1)**. + required: true + - label: I will fill out all of the requested information in this form. + required: true + + - type: textarea + id: feature-description + attributes: + label: Describe your suggested feature + description: How can an existing extension be improved? + placeholder: | + Example: + "It should work like this..." + validations: + required: true + + - type: textarea + id: other-details + attributes: + label: Other details + placeholder: | + Additional details and attachments. diff --git a/.github/ISSUE_TEMPLATE/source_issue.md b/.github/ISSUE_TEMPLATE/source_issue.md deleted file mode 100644 index 212b77c4fa..0000000000 --- a/.github/ISSUE_TEMPLATE/source_issue.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -name: "Extension/source/catalogue issue" -about: "Do not open an issue here. See https://github.com/tachiyomiorg/tachiyomi-extensions" -title: "THIS ISSUE IS IN THE WRONG REPO; SEE https://github.com/tachiyomiorg/tachiyomi-extensions" -labels: "catalog, invalid" ---- - -DO NOT OPEN AN ISSUE IN THIS REPO. SEE https://github.com/tachiyomiorg/tachiyomi-extensions From d1b393965fb20660463cad6a13a82c3ea2d4fd29 Mon Sep 17 00:00:00 2001 From: Alessandro Jean Date: Fri, 25 Jun 2021 23:30:26 -0300 Subject: [PATCH 5/8] [skip ci] Update issue-moderator-action to v1.1 (#5459) --- .github/workflows/issue_moderator.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/issue_moderator.yml b/.github/workflows/issue_moderator.yml index 09eaa17537..dce3d51f69 100644 --- a/.github/workflows/issue_moderator.yml +++ b/.github/workflows/issue_moderator.yml @@ -9,6 +9,6 @@ jobs: runs-on: ubuntu-latest steps: - name: Moderate issues - uses: tachiyomiorg/issue-moderator-action@v1.0 + uses: tachiyomiorg/issue-moderator-action@v1.1 with: repo-token: ${{ secrets.GITHUB_TOKEN }} From feddd9285d1215a70c4319f271fe24b2027daed4 Mon Sep 17 00:00:00 2001 From: arkon Date: Fri, 25 Jun 2021 22:45:02 -0400 Subject: [PATCH 6/8] [skip ci] Update issue closer rules --- .github/ISSUE_TEMPLATE/config.yml | 2 +- .github/workflows/issue_closer.yml | 10 ---------- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index a54157595c..b88cba16a0 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -2,7 +2,7 @@ blank_issues_enabled: false contact_links: - name: ⚠️ Extension/source issue url: https://github.com/tachiyomiorg/tachiyomi-extensions/issues/new/choose - about: Issues and requests for extensions and sources should be opened here. + about: Issues and requests for extensions and sources should be opened in the tachiyomi-extensions repository instead. - name: 📦 Tachiyomi extensions url: https://github.com/tachiyomiorg/tachiyomi-extensions about: Extensions and sources. diff --git a/.github/workflows/issue_closer.yml b/.github/workflows/issue_closer.yml index a777e65e93..1f6275b6b6 100644 --- a/.github/workflows/issue_closer.yml +++ b/.github/workflows/issue_closer.yml @@ -13,16 +13,6 @@ jobs: repo-token: ${{ secrets.GITHUB_TOKEN }} rules: | [ - { - "type": "title", - "regex": ".*THIS ISSUE IS IN THE WRONG REPO.*", - "message": "It was not opened in the correct repo, as the template mentioned." - }, - { - "type": "title", - "regex": ".**", - "message": "The description in the title was not filled out." - }, { "type": "body", "regex": ".*DELETE THIS SECTION IF YOU HAVE READ AND ACKNOWLEDGED IT.*", From 64c95305b9831762cc0be72f7ab47b006da07fa8 Mon Sep 17 00:00:00 2001 From: Ivan Iskandar <12537387+ivaniskandar@users.noreply.github.com> Date: Sat, 26 Jun 2021 10:28:19 +0700 Subject: [PATCH 7/8] Match ReaderActivity theme with the rest of the app (#5450) * Match ReaderActivity theme with the rest of the app * Fix viewer inset when fullscreen reader is off * Fix incorrect toolbar color after recreate * Remove animated inset * Move isDarkMode to PreferencesHelper --- .../data/preference/PreferencesHelper.kt | 15 ++- .../ui/base/activity/BaseThemedActivity.kt | 49 ++++---- .../tachiyomi/ui/reader/ReaderActivity.kt | 115 +++++++++++------- .../tachiyomi/util/view/WindowExtensions.kt | 21 ---- .../widget/sheet/BaseBottomSheetDialog.kt | 11 +- app/src/main/res/layout/reader_activity.xml | 2 +- app/src/main/res/values/colors.xml | 3 - app/src/main/res/values/styles.xml | 5 - app/src/main/res/values/themes.xml | 61 +--------- 9 files changed, 113 insertions(+), 169 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt index 0ce869d628..704752c404 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt @@ -1,6 +1,7 @@ package eu.kanade.tachiyomi.data.preference import android.content.Context +import android.content.res.Configuration import android.os.Environment import androidx.core.content.edit import androidx.core.net.toUri @@ -10,6 +11,7 @@ import com.tfcporciuncula.flow.Preference import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.preference.PreferenceValues.DisplayMode +import eu.kanade.tachiyomi.data.preference.PreferenceValues.ThemeMode.* import eu.kanade.tachiyomi.data.track.TrackService import eu.kanade.tachiyomi.data.track.anilist.Anilist import eu.kanade.tachiyomi.ui.reader.setting.OrientationType @@ -84,7 +86,7 @@ class PreferencesHelper(val context: Context) { fun showLibraryUpdateErrors() = prefs.getBoolean(Keys.showLibraryUpdateErrors, true) - fun themeMode() = flowPrefs.getEnum(Keys.themeMode, Values.ThemeMode.system) + fun themeMode() = flowPrefs.getEnum(Keys.themeMode, system) fun themeLight() = flowPrefs.getEnum(Keys.themeLight, Values.LightThemeVariant.default) @@ -322,4 +324,15 @@ class PreferencesHelper(val context: Context) { putInt(Keys.defaultChapterSortByAscendingOrDescending, if (manga.sortDescending()) Manga.CHAPTER_SORT_DESC else Manga.CHAPTER_SORT_ASC) } } + + fun isDarkMode(): Boolean { + return when (themeMode().get()) { + light -> false + dark -> true + system -> { + context.applicationContext.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == + Configuration.UI_MODE_NIGHT_YES + } + } + } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/base/activity/BaseThemedActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/base/activity/BaseThemedActivity.kt index f5e22cf68e..28c9bffabb 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/base/activity/BaseThemedActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/base/activity/BaseThemedActivity.kt @@ -1,14 +1,11 @@ package eu.kanade.tachiyomi.ui.base.activity -import android.content.res.Configuration.UI_MODE_NIGHT_MASK -import android.content.res.Configuration.UI_MODE_NIGHT_YES import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.lifecycleScope import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.preference.PreferenceValues.DarkThemeVariant import eu.kanade.tachiyomi.data.preference.PreferenceValues.LightThemeVariant -import eu.kanade.tachiyomi.data.preference.PreferenceValues.ThemeMode import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.asImmediateFlow import eu.kanade.tachiyomi.util.view.setSecureScreen @@ -22,29 +19,7 @@ abstract class BaseThemedActivity : AppCompatActivity() { val preferences: PreferencesHelper by injectLazy() override fun onCreate(savedInstanceState: Bundle?) { - val isDarkMode = when (preferences.themeMode().get()) { - ThemeMode.light -> false - ThemeMode.dark -> true - ThemeMode.system -> resources.configuration.uiMode and UI_MODE_NIGHT_MASK == UI_MODE_NIGHT_YES - } - val themeId = if (isDarkMode) { - when (preferences.themeDark().get()) { - DarkThemeVariant.default -> R.style.Theme_Tachiyomi_Dark - DarkThemeVariant.blue -> R.style.Theme_Tachiyomi_Dark_Blue - DarkThemeVariant.greenapple -> R.style.Theme_Tachiyomi_Dark_GreenApple - DarkThemeVariant.midnightdusk -> R.style.Theme_Tachiyomi_Dark_MidnightDusk - DarkThemeVariant.amoled -> R.style.Theme_Tachiyomi_Amoled - DarkThemeVariant.hotpink -> R.style.Theme_Tachiyomi_Amoled_HotPink - } - } else { - when (preferences.themeLight().get()) { - LightThemeVariant.default -> R.style.Theme_Tachiyomi_Light - LightThemeVariant.blue -> R.style.Theme_Tachiyomi_Light_Blue - LightThemeVariant.strawberrydaiquiri -> R.style.Theme_Tachiyomi_Light_StrawberryDaiquiri - LightThemeVariant.yotsuba -> R.style.Theme_Tachiyomi_Light_Yotsuba - } - } - setTheme(themeId) + setTheme(getThemeResourceId(preferences)) Injekt.get().incognitoMode() .asImmediateFlow { @@ -54,4 +29,26 @@ abstract class BaseThemedActivity : AppCompatActivity() { super.onCreate(savedInstanceState) } + + companion object { + fun getThemeResourceId(preferences: PreferencesHelper): Int { + return if (preferences.isDarkMode()) { + when (preferences.themeDark().get()) { + DarkThemeVariant.default -> R.style.Theme_Tachiyomi_Dark + DarkThemeVariant.blue -> R.style.Theme_Tachiyomi_Dark_Blue + DarkThemeVariant.greenapple -> R.style.Theme_Tachiyomi_Dark_GreenApple + DarkThemeVariant.midnightdusk -> R.style.Theme_Tachiyomi_Dark_MidnightDusk + DarkThemeVariant.amoled -> R.style.Theme_Tachiyomi_Amoled + DarkThemeVariant.hotpink -> R.style.Theme_Tachiyomi_Amoled_HotPink + } + } else { + when (preferences.themeLight().get()) { + LightThemeVariant.default -> R.style.Theme_Tachiyomi_Light + LightThemeVariant.blue -> R.style.Theme_Tachiyomi_Light_Blue + LightThemeVariant.strawberrydaiquiri -> R.style.Theme_Tachiyomi_Light_StrawberryDaiquiri + LightThemeVariant.yotsuba -> R.style.Theme_Tachiyomi_Light_Yotsuba + } + } + } + } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt index dd5ccca666..754d1295fe 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt @@ -6,11 +6,13 @@ import android.app.ProgressDialog import android.content.ClipData import android.content.Context import android.content.Intent +import android.content.res.ColorStateList import android.graphics.Bitmap import android.graphics.Color import android.graphics.ColorMatrix import android.graphics.ColorMatrixColorFilter import android.graphics.Paint +import android.graphics.drawable.ColorDrawable import android.os.Build import android.os.Bundle import android.view.KeyEvent @@ -23,12 +25,14 @@ import android.view.animation.Animation import android.view.animation.AnimationUtils import android.widget.SeekBar import android.widget.Toast -import androidx.core.view.ViewCompat +import androidx.core.view.WindowCompat import androidx.core.view.WindowInsetsCompat +import androidx.core.view.WindowInsetsControllerCompat import androidx.core.view.isVisible -import androidx.core.view.setPadding import androidx.lifecycle.lifecycleScope import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView +import com.google.android.material.shape.MaterialShapeDrawable +import dev.chrisbanes.insetter.applyInsetter import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.models.Chapter import eu.kanade.tachiyomi.data.database.models.Manga @@ -38,6 +42,7 @@ import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.toggle import eu.kanade.tachiyomi.databinding.ReaderActivityBinding import eu.kanade.tachiyomi.ui.base.activity.BaseRxActivity +import eu.kanade.tachiyomi.ui.base.activity.BaseThemedActivity import eu.kanade.tachiyomi.ui.main.MainActivity import eu.kanade.tachiyomi.ui.manga.MangaController import eu.kanade.tachiyomi.ui.reader.ReaderPresenter.SetAsCoverResult.AddToLibraryFirst @@ -55,12 +60,8 @@ import eu.kanade.tachiyomi.util.storage.getUriCompat import eu.kanade.tachiyomi.util.system.GLUtil import eu.kanade.tachiyomi.util.system.hasDisplayCutout import eu.kanade.tachiyomi.util.system.toast -import eu.kanade.tachiyomi.util.view.defaultBar -import eu.kanade.tachiyomi.util.view.hideBar -import eu.kanade.tachiyomi.util.view.isDefaultBar import eu.kanade.tachiyomi.util.view.popupMenu import eu.kanade.tachiyomi.util.view.setTooltip -import eu.kanade.tachiyomi.util.view.showBar import eu.kanade.tachiyomi.widget.listener.SimpleAnimationListener import eu.kanade.tachiyomi.widget.listener.SimpleSeekBarListener import kotlinx.coroutines.flow.drop @@ -129,22 +130,20 @@ class ReaderActivity : BaseRxActivity() private var readingModeToast: Toast? = null + private val windowInsetsController by lazy { WindowInsetsControllerCompat(window, binding.root) } + /** * Called when the activity is created. Initializes the presenter and configuration. */ override fun onCreate(savedInstanceState: Bundle?) { - setTheme( - when (preferences.readerTheme().get()) { - 0 -> R.style.Theme_Reader_Light - 2 -> R.style.Theme_Reader_Dark_Grey - else -> R.style.Theme_Reader_Dark - } - ) + setTheme(BaseThemedActivity.getThemeResourceId(preferences)) super.onCreate(savedInstanceState) binding = ReaderActivityBinding.inflate(layoutInflater) setContentView(binding.root) + windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE + if (presenter.needsInit()) { val manga = intent.extras!!.getLong("manga", -1) val chapter = intent.extras!!.getLong("chapter", -1) @@ -163,9 +162,10 @@ class ReaderActivity : BaseRxActivity() config = ReaderConfig() initializeMenu() - // Avoid status bar showing up on rotation - window.decorView.setOnSystemUiVisibilityChangeListener { - setMenuVisibility(menuVisible, animate = false) + binding.pageNumber.applyInsetter { + type(navigationBars = true) { + margin() + } } // Finish when incognito mode is disabled @@ -299,17 +299,15 @@ class ReaderActivity : BaseRxActivity() onBackPressed() } - ViewCompat.setOnApplyWindowInsetsListener(binding.readerMenu) { _, insets -> - if (!window.isDefaultBar()) { - val systemInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars()) - binding.readerMenu.setPadding( - systemInsets.left, - systemInsets.top, - systemInsets.right, - systemInsets.bottom - ) + binding.toolbar.applyInsetter { + type(navigationBars = true, statusBars = true) { + margin(top = true, horizontal = true) + } + } + binding.readerMenuBottom.applyInsetter { + type(navigationBars = true) { + margin(bottom = true, horizontal = true) } - insets } binding.toolbar.setOnClickListener { @@ -355,6 +353,21 @@ class ReaderActivity : BaseRxActivity() initBottomShortcuts() + val alpha = if (preferences.isDarkMode()) 230 else 242 // 90% dark 95% light + listOf( + binding.toolbarBottom, + binding.leftChapter, + binding.readerSeekbar, + binding.rightChapter + ).forEach { + it.background.alpha = alpha + } + + val systemBarsColor = (binding.toolbarBottom.background as ColorDrawable).color + window.statusBarColor = systemBarsColor + window.navigationBarColor = systemBarsColor + (binding.toolbar.background as MaterialShapeDrawable).fillColor = ColorStateList.valueOf(systemBarsColor) + // Set initial visibility setMenuVisibility(menuVisible) } @@ -475,11 +488,7 @@ class ReaderActivity : BaseRxActivity() fun setMenuVisibility(visible: Boolean, animate: Boolean = true) { menuVisible = visible if (visible) { - if (preferences.fullscreen().get()) { - window.showBar() - } else { - resetDefaultMenuAndBar() - } + windowInsetsController.show(WindowInsetsCompat.Type.systemBars()) binding.readerMenu.isVisible = true if (animate) { @@ -503,9 +512,7 @@ class ReaderActivity : BaseRxActivity() } } else { if (preferences.fullscreen().get()) { - window.hideBar() - } else { - resetDefaultMenuAndBar() + windowInsetsController.hide(WindowInsetsCompat.Type.systemBars()) } if (animate) { @@ -529,14 +536,6 @@ class ReaderActivity : BaseRxActivity() } } - /** - * Reset menu padding and system bar - */ - private fun resetDefaultMenuAndBar() { - binding.readerMenu.setPadding(0) - window.defaultBar() - } - /** * Called from the presenter when a manga is ready. Used to instantiate the appropriate viewer * and the toolbar title. @@ -557,6 +556,7 @@ class ReaderActivity : BaseRxActivity() binding.viewerContainer.removeAllViews() } viewer = newViewer + updateViewerInset(preferences.fullscreen().get()) binding.viewerContainer.addView(newViewer.getView()) if (preferences.showReadingMode()) { @@ -811,6 +811,19 @@ class ReaderActivity : BaseRxActivity() updateOrientationShortcut(presenter.getMangaOrientationType(resolveDefault = false)) } + /** + * Updates viewer inset depending on fullscreen reader preferences. + */ + fun updateViewerInset(fullscreen: Boolean) { + viewer?.getView()?.applyInsetter { + if (!fullscreen) { + type(navigationBars = true, statusBars = true) { + padding() + } + } + } + } + /** * Class that handles the user preferences of the reader. */ @@ -831,8 +844,15 @@ class ReaderActivity : BaseRxActivity() */ init { preferences.readerTheme().asFlow() - .drop(1) // We only care about updates - .onEach { recreate() } + .onEach { + binding.readerContainer.setBackgroundResource( + when (preferences.readerTheme().get()) { + 0 -> android.R.color.white + 2 -> R.color.background_dark + else -> android.R.color.black + } + ) + } .launchIn(lifecycleScope) preferences.showPageNumber().asFlow() @@ -868,6 +888,13 @@ class ReaderActivity : BaseRxActivity() preferences.grayscale().asFlow() .onEach { setGrayscale(it) } .launchIn(lifecycleScope) + + preferences.fullscreen().asFlow() + .onEach { + WindowCompat.setDecorFitsSystemWindows(window, !it) + updateViewerInset(it) + } + .launchIn(lifecycleScope) } /** diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/view/WindowExtensions.kt b/app/src/main/java/eu/kanade/tachiyomi/util/view/WindowExtensions.kt index cefe188d33..e3f8724a23 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/view/WindowExtensions.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/util/view/WindowExtensions.kt @@ -3,32 +3,11 @@ package eu.kanade.tachiyomi.util.view import android.content.Context import android.graphics.Color import android.os.Build -import android.view.View import android.view.Window import android.view.WindowManager import eu.kanade.tachiyomi.util.system.InternalResourceHelper import eu.kanade.tachiyomi.util.system.getResourceColor -fun Window.showBar() { - decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or - View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or - View.SYSTEM_UI_FLAG_LAYOUT_STABLE -} - -fun Window.hideBar() { - decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or - View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or - View.SYSTEM_UI_FLAG_FULLSCREEN or - View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or - View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY -} - -fun Window.defaultBar() { - decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE -} - -fun Window.isDefaultBar() = decorView.systemUiVisibility == View.SYSTEM_UI_FLAG_VISIBLE - /** * Sets navigation bar color to transparent if system's config_navBarNeedsScrim is false, * otherwise it will use the theme navigationBarColor with 70% opacity. diff --git a/app/src/main/java/eu/kanade/tachiyomi/widget/sheet/BaseBottomSheetDialog.kt b/app/src/main/java/eu/kanade/tachiyomi/widget/sheet/BaseBottomSheetDialog.kt index c4b2132082..8f592af247 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/widget/sheet/BaseBottomSheetDialog.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/widget/sheet/BaseBottomSheetDialog.kt @@ -1,7 +1,6 @@ package eu.kanade.tachiyomi.widget.sheet import android.content.Context -import android.content.res.Configuration import android.os.Build import android.os.Bundle import android.util.DisplayMetrics @@ -10,7 +9,6 @@ import android.view.View import android.view.ViewGroup import com.google.android.material.bottomsheet.BottomSheetDialog import eu.kanade.tachiyomi.R -import eu.kanade.tachiyomi.data.preference.PreferenceValues import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.util.system.displayCompat import eu.kanade.tachiyomi.util.view.setNavigationBarTransparentCompat @@ -45,16 +43,9 @@ abstract class BaseBottomSheetDialog(context: Context) : BottomSheetDialog(conte @Suppress("DEPRECATION") if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { window?.setNavigationBarTransparentCompat(context) - val isDarkMode = when (Injekt.get().themeMode().get()) { - PreferenceValues.ThemeMode.light -> false - PreferenceValues.ThemeMode.dark -> true - PreferenceValues.ThemeMode.system -> - context.resources.configuration.uiMode and - Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES - } val bottomSheet = rootView.parent as ViewGroup var flags = bottomSheet.systemUiVisibility - flags = if (isDarkMode) { + flags = if (Injekt.get().isDarkMode()) { flags and View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR.inv() } else { flags or View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR diff --git a/app/src/main/res/layout/reader_activity.xml b/app/src/main/res/layout/reader_activity.xml index 9217591b4a..09a7373cb6 100644 --- a/app/src/main/res/layout/reader_activity.xml +++ b/app/src/main/res/layout/reader_activity.xml @@ -61,7 +61,6 @@ android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="?attr/colorToolbar" android:minHeight="?attr/actionBarSize" /> #FF3399 #1FFF3399 - - #242529 - #FFC107 #FFEB3B #FFEB3B diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 4e38b20f2f..94e44ce70f 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -219,11 +219,6 @@ - - - - - - - - - - - - - - - - From 60890147c3c24ac30a75bfb8c4fab7b8cccd60be Mon Sep 17 00:00:00 2001 From: Andreas Date: Sat, 26 Jun 2021 19:30:16 +0200 Subject: [PATCH 8/8] Sort per category (#5408) * Add flags for sorting per category * Add logic to LibrarySettingsSheet * Add logic to LibraryPresenter * Minor tweaks * Use enum instead of variables Also deprecates LibrarySort in favour of the new enum classes * Remove debug log and suppress deprecation * Convert DisplayMode setting to enum Also fix bug were adapter would get de-synced with the current per category setting * Fix migration crashing app due to values being access before migration --- app/build.gradle.kts | 2 +- .../java/eu/kanade/tachiyomi/Migrations.kt | 46 ++++++- .../data/database/models/Category.kt | 20 ++- .../data/preference/PreferenceKeys.kt | 1 + .../data/preference/PreferenceValues.kt | 6 - .../data/preference/PreferencesHelper.kt | 13 +- .../source/browse/BrowseSourceController.kt | 18 +-- .../ui/browse/source/browse/SourceItem.kt | 16 +-- .../ui/library/LibraryCategoryView.kt | 4 +- .../tachiyomi/ui/library/LibraryController.kt | 5 + .../tachiyomi/ui/library/LibraryItem.kt | 24 ++-- .../tachiyomi/ui/library/LibraryPresenter.kt | 52 ++++--- .../ui/library/LibrarySettingsSheet.kt | 128 +++++++++++------- .../tachiyomi/ui/library/LibrarySort.kt | 1 + .../ui/library/setting/DisplayModeSetting.kt | 16 +++ .../library/setting/SortDirectionSetting.kt | 25 ++++ .../ui/library/setting/SortModeSetting.kt | 32 +++++ .../kanade/tachiyomi/ui/main/MainActivity.kt | 4 +- 18 files changed, 289 insertions(+), 124 deletions(-) create mode 100644 app/src/main/java/eu/kanade/tachiyomi/ui/library/setting/DisplayModeSetting.kt create mode 100644 app/src/main/java/eu/kanade/tachiyomi/ui/library/setting/SortDirectionSetting.kt create mode 100644 app/src/main/java/eu/kanade/tachiyomi/ui/library/setting/SortModeSetting.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 76e7152ba0..951d371c96 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -30,7 +30,7 @@ android { minSdkVersion(AndroidConfig.minSdk) targetSdkVersion(AndroidConfig.targetSdk) testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - versionCode = 63 + versionCode = 64 versionName = "0.11.1" buildConfigField("String", "COMMIT_COUNT", "\"${getCommitCount()}\"") diff --git a/app/src/main/java/eu/kanade/tachiyomi/Migrations.kt b/app/src/main/java/eu/kanade/tachiyomi/Migrations.kt index 09512b1861..afdcd30c8e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/Migrations.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/Migrations.kt @@ -12,6 +12,8 @@ import eu.kanade.tachiyomi.data.updater.UpdaterJob import eu.kanade.tachiyomi.extension.ExtensionUpdateJob import eu.kanade.tachiyomi.network.PREF_DOH_CLOUDFLARE import eu.kanade.tachiyomi.ui.library.LibrarySort +import eu.kanade.tachiyomi.ui.library.setting.SortDirectionSetting +import eu.kanade.tachiyomi.ui.library.setting.SortModeSetting import eu.kanade.tachiyomi.ui.reader.setting.OrientationType import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.widget.ExtendedNavigationView @@ -96,9 +98,15 @@ object Migrations { } if (oldVersion < 44) { // Reset sorting preference if using removed sort by source + val prefs = PreferenceManager.getDefaultSharedPreferences(context) + + val oldSortingMode = prefs.getInt(PreferenceKeys.librarySortingMode, 0) + @Suppress("DEPRECATION") - if (preferences.librarySortingMode().get() == LibrarySort.SOURCE) { - preferences.librarySortingMode().set(LibrarySort.ALPHA) + if (oldSortingMode == LibrarySort.SOURCE) { + prefs.edit { + putInt(PreferenceKeys.librarySortingMode, LibrarySort.ALPHA) + } } } if (oldVersion < 52) { @@ -190,6 +198,40 @@ object Migrations { LibraryUpdateJob.setupTask(context, 3) } } + if (oldVersion < 64) { + val prefs = PreferenceManager.getDefaultSharedPreferences(context) + + val oldSortingMode = prefs.getInt(PreferenceKeys.librarySortingMode, 0) + val oldSortingDirection = prefs.getBoolean(PreferenceKeys.librarySortingDirection, true) + + @Suppress("DEPRECATION") + val newSortingMode = when (oldSortingMode) { + LibrarySort.ALPHA -> SortModeSetting.ALPHABETICAL + LibrarySort.LAST_READ -> SortModeSetting.LAST_READ + LibrarySort.LAST_CHECKED -> SortModeSetting.LAST_CHECKED + LibrarySort.UNREAD -> SortModeSetting.UNREAD + LibrarySort.TOTAL -> SortModeSetting.TOTAL_CHAPTERS + LibrarySort.LATEST_CHAPTER -> SortModeSetting.LATEST_CHAPTER + LibrarySort.CHAPTER_FETCH_DATE -> SortModeSetting.DATE_FETCHED + LibrarySort.DATE_ADDED -> SortModeSetting.DATE_ADDED + else -> SortModeSetting.ALPHABETICAL + } + + val newSortingDirection = when (oldSortingDirection) { + true -> SortDirectionSetting.ASCENDING + else -> SortDirectionSetting.DESCENDING + } + + prefs.edit(commit = true) { + remove(PreferenceKeys.librarySortingMode) + remove(PreferenceKeys.librarySortingDirection) + } + + prefs.edit { + putString(PreferenceKeys.librarySortingMode, newSortingMode.name) + putString(PreferenceKeys.librarySortingDirection, newSortingDirection.name) + } + } return true } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/database/models/Category.kt b/app/src/main/java/eu/kanade/tachiyomi/data/database/models/Category.kt index 14a842476b..366a1b8550 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/database/models/Category.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/database/models/Category.kt @@ -1,5 +1,8 @@ package eu.kanade.tachiyomi.data.database.models +import eu.kanade.tachiyomi.ui.library.setting.DisplayModeSetting +import eu.kanade.tachiyomi.ui.library.setting.SortDirectionSetting +import eu.kanade.tachiyomi.ui.library.setting.SortModeSetting import java.io.Serializable interface Category : Serializable { @@ -17,15 +20,18 @@ interface Category : Serializable { } var displayMode: Int - get() = flags and MASK - set(mode) = setFlags(mode, MASK) + get() = flags and DisplayModeSetting.MASK + set(mode) = setFlags(mode, DisplayModeSetting.MASK) - companion object { + var sortMode: Int + get() = flags and SortModeSetting.MASK + set(mode) = setFlags(mode, SortModeSetting.MASK) + + var sortDirection: Int + get() = flags and SortDirectionSetting.MASK + set(mode) = setFlags(mode, SortDirectionSetting.MASK) - const val COMPACT_GRID = 0b00000000 - const val COMFORTABLE_GRID = 0b00000001 - const val LIST = 0b00000010 - const val MASK = 0b00000011 + companion object { fun create(name: String): Category = CategoryImpl().apply { this.name = name diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt index fd756ad2fc..05046a3085 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt @@ -147,6 +147,7 @@ object PreferenceKeys { const val filterTracked = "pref_filter_library_tracked" const val librarySortingMode = "library_sorting_mode" + const val librarySortingDirection = "library_sorting_ascending" const val automaticExtUpdates = "automatic_ext_updates" diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceValues.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceValues.kt index 32a25818fe..981c279973 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceValues.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceValues.kt @@ -37,12 +37,6 @@ object PreferenceValues { /* ktlint-enable experimental:enum-entry-name-case */ - enum class DisplayMode { - COMPACT_GRID, - COMFORTABLE_GRID, - LIST, - } - enum class TappingInvertMode(val shouldInvertHorizontal: Boolean = false, val shouldInvertVertical: Boolean = false) { NONE, HORIZONTAL(shouldInvertHorizontal = true), diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt index 704752c404..3c6f8997a2 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt @@ -10,10 +10,12 @@ import com.tfcporciuncula.flow.FlowSharedPreferences import com.tfcporciuncula.flow.Preference import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.models.Manga -import eu.kanade.tachiyomi.data.preference.PreferenceValues.DisplayMode import eu.kanade.tachiyomi.data.preference.PreferenceValues.ThemeMode.* import eu.kanade.tachiyomi.data.track.TrackService import eu.kanade.tachiyomi.data.track.anilist.Anilist +import eu.kanade.tachiyomi.ui.library.setting.DisplayModeSetting +import eu.kanade.tachiyomi.ui.library.setting.SortDirectionSetting +import eu.kanade.tachiyomi.ui.library.setting.SortModeSetting import eu.kanade.tachiyomi.ui.reader.setting.OrientationType import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType import eu.kanade.tachiyomi.widget.ExtendedNavigationView @@ -184,7 +186,7 @@ class PreferencesHelper(val context: Context) { fun lastVersionCode() = flowPrefs.getInt("last_version_code", 0) - fun sourceDisplayMode() = flowPrefs.getEnum(Keys.sourceDisplayMode, DisplayMode.COMPACT_GRID) + fun sourceDisplayMode() = flowPrefs.getEnum(Keys.sourceDisplayMode, DisplayModeSetting.COMPACT_GRID) fun enabledLanguages() = flowPrefs.getStringSet(Keys.enabledLanguages, setOf("en", Locale.getDefault().language)) @@ -235,7 +237,7 @@ class PreferencesHelper(val context: Context) { fun libraryUpdatePrioritization() = flowPrefs.getInt(Keys.libraryUpdatePrioritization, 0) - fun libraryDisplayMode() = flowPrefs.getEnum(Keys.libraryDisplayMode, DisplayMode.COMPACT_GRID) + fun libraryDisplayMode() = flowPrefs.getEnum(Keys.libraryDisplayMode, DisplayModeSetting.COMPACT_GRID) fun downloadBadge() = flowPrefs.getBoolean(Keys.downloadBadge, false) @@ -257,9 +259,8 @@ class PreferencesHelper(val context: Context) { fun filterTracking(name: Int) = flowPrefs.getInt("${Keys.filterTracked}_$name", ExtendedNavigationView.Item.TriStateGroup.State.IGNORE.value) - fun librarySortingMode() = flowPrefs.getInt(Keys.librarySortingMode, 0) - - fun librarySortingAscending() = flowPrefs.getBoolean("library_sorting_ascending", true) + fun librarySortingMode() = flowPrefs.getEnum(Keys.librarySortingMode, SortModeSetting.ALPHABETICAL) + fun librarySortingAscending() = flowPrefs.getEnum(Keys.librarySortingDirection, SortDirectionSetting.ASCENDING) fun automaticExtUpdates() = flowPrefs.getBoolean(Keys.automaticExtUpdates, true) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceController.kt index a821874693..6dccc80614 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceController.kt @@ -24,7 +24,6 @@ import eu.davidea.flexibleadapter.items.IFlexible import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.models.Category import eu.kanade.tachiyomi.data.database.models.Manga -import eu.kanade.tachiyomi.data.preference.PreferenceValues.DisplayMode import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.asImmediateFlow import eu.kanade.tachiyomi.databinding.SourceControllerBinding @@ -37,6 +36,7 @@ import eu.kanade.tachiyomi.ui.base.controller.SearchableNucleusController import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchController import eu.kanade.tachiyomi.ui.library.ChangeMangaCategoriesDialog +import eu.kanade.tachiyomi.ui.library.setting.DisplayModeSetting import eu.kanade.tachiyomi.ui.main.MainActivity import eu.kanade.tachiyomi.ui.manga.MangaController import eu.kanade.tachiyomi.ui.more.MoreController @@ -205,7 +205,7 @@ open class BrowseSourceController(bundle: Bundle) : binding.catalogueView.removeView(oldRecycler) } - val recycler = if (preferences.sourceDisplayMode().get() == DisplayMode.LIST) { + val recycler = if (preferences.sourceDisplayMode().get() == DisplayModeSetting.LIST) { RecyclerView(view.context).apply { id = R.id.recycler layoutManager = LinearLayoutManager(context) @@ -273,9 +273,9 @@ open class BrowseSourceController(bundle: Bundle) : ) val displayItem = when (preferences.sourceDisplayMode().get()) { - DisplayMode.COMPACT_GRID -> R.id.action_compact_grid - DisplayMode.COMFORTABLE_GRID -> R.id.action_comfortable_grid - DisplayMode.LIST -> R.id.action_list + DisplayModeSetting.COMPACT_GRID -> R.id.action_compact_grid + DisplayModeSetting.COMFORTABLE_GRID -> R.id.action_comfortable_grid + DisplayModeSetting.LIST -> R.id.action_list } menu.findItem(displayItem).isChecked = true } @@ -297,9 +297,9 @@ open class BrowseSourceController(bundle: Bundle) : override fun onOptionsItemSelected(item: MenuItem): Boolean { when (item.itemId) { R.id.action_search -> expandActionViewFromInteraction = true - R.id.action_compact_grid -> setDisplayMode(DisplayMode.COMPACT_GRID) - R.id.action_comfortable_grid -> setDisplayMode(DisplayMode.COMFORTABLE_GRID) - R.id.action_list -> setDisplayMode(DisplayMode.LIST) + R.id.action_compact_grid -> setDisplayMode(DisplayModeSetting.COMPACT_GRID) + R.id.action_comfortable_grid -> setDisplayMode(DisplayModeSetting.COMFORTABLE_GRID) + R.id.action_list -> setDisplayMode(DisplayModeSetting.LIST) R.id.action_open_in_web_view -> openInWebView() R.id.action_local_source_help -> openLocalSourceHelpGuide() } @@ -446,7 +446,7 @@ open class BrowseSourceController(bundle: Bundle) : * * @param mode the mode to change to */ - private fun setDisplayMode(mode: DisplayMode) { + private fun setDisplayMode(mode: DisplayModeSetting) { val view = view ?: return val adapter = adapter ?: return diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceItem.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceItem.kt index a1382cd92b..b905246c2c 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceItem.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceItem.kt @@ -12,19 +12,19 @@ import eu.davidea.flexibleadapter.items.AbstractFlexibleItem import eu.davidea.flexibleadapter.items.IFlexible import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.models.Manga -import eu.kanade.tachiyomi.data.preference.PreferenceValues.DisplayMode import eu.kanade.tachiyomi.databinding.SourceComfortableGridItemBinding import eu.kanade.tachiyomi.databinding.SourceCompactGridItemBinding +import eu.kanade.tachiyomi.ui.library.setting.DisplayModeSetting import eu.kanade.tachiyomi.widget.AutofitRecyclerView -class SourceItem(val manga: Manga, private val displayMode: Preference) : +class SourceItem(val manga: Manga, private val displayMode: Preference) : AbstractFlexibleItem>() { override fun getLayoutRes(): Int { return when (displayMode.get()) { - DisplayMode.COMPACT_GRID -> R.layout.source_compact_grid_item - DisplayMode.COMFORTABLE_GRID -> R.layout.source_comfortable_grid_item - DisplayMode.LIST -> R.layout.source_list_item + DisplayModeSetting.COMPACT_GRID -> R.layout.source_compact_grid_item + DisplayModeSetting.COMFORTABLE_GRID -> R.layout.source_comfortable_grid_item + DisplayModeSetting.LIST -> R.layout.source_list_item } } @@ -33,7 +33,7 @@ class SourceItem(val manga: Manga, private val displayMode: Preference> ): SourceHolder<*> { return when (displayMode.get()) { - DisplayMode.COMPACT_GRID -> { + DisplayModeSetting.COMPACT_GRID -> { val binding = SourceCompactGridItemBinding.bind(view) val parent = adapter.recyclerView as AutofitRecyclerView val coverHeight = parent.itemWidth / 3 * 4 @@ -50,7 +50,7 @@ class SourceItem(val manga: Manga, private val displayMode: Preference { + DisplayModeSetting.COMFORTABLE_GRID -> { val binding = SourceComfortableGridItemBinding.bind(view) val parent = adapter.recyclerView as AutofitRecyclerView val coverHeight = parent.itemWidth / 3 * 4 @@ -62,7 +62,7 @@ class SourceItem(val manga: Manga, private val displayMode: Preference { + DisplayModeSetting.LIST -> { SourceListHolder(view, adapter) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt index 9851de2cd7..2c419c462a 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt @@ -12,7 +12,6 @@ import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.models.Category import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.library.LibraryUpdateService -import eu.kanade.tachiyomi.data.preference.PreferenceValues.DisplayMode import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.databinding.LibraryCategoryBinding import eu.kanade.tachiyomi.util.lang.plusAssign @@ -28,6 +27,7 @@ import reactivecircus.flowbinding.swiperefreshlayout.refreshes import rx.subscriptions.CompositeSubscription import uy.kohesive.injekt.injectLazy import java.util.ArrayDeque +import eu.kanade.tachiyomi.ui.library.setting.DisplayModeSetting as DisplayMode /** * Fragment containing the library manga for a certain category. @@ -125,7 +125,7 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att // If displayMode should be set from category adjust manga count per row if (preferences.categorisedDisplaySettings().get()) { - recycler.spanCount = if (category.displayMode == Category.LIST || (preferences.libraryDisplayMode().get() == DisplayMode.LIST && category.id == 0)) { + recycler.spanCount = if (DisplayMode.fromFlag(category.displayMode) == DisplayMode.LIST || (preferences.libraryDisplayMode().get() == DisplayMode.LIST && category.id == 0)) { 1 } else { controller.mangaPerRow diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt index 7ba8bb7b99..d377250900 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt @@ -295,6 +295,11 @@ class LibraryController( .map { (it.id ?: -1) to (mangaMap[it.id]?.size ?: 0) } .toMap() + if (preferences.categorisedDisplaySettings().get()) { + // Reattach adapter so it doesn't get de-synced + reattachAdapter() + } + // Restore active category. binding.libraryPager.setCurrentItem(activeCat, false) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryItem.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryItem.kt index 941a2c6469..d15605f535 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryItem.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryItem.kt @@ -13,10 +13,10 @@ import eu.davidea.flexibleadapter.items.IFilterable import eu.davidea.flexibleadapter.items.IFlexible import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.models.LibraryManga -import eu.kanade.tachiyomi.data.preference.PreferenceValues.DisplayMode import eu.kanade.tachiyomi.databinding.SourceComfortableGridItemBinding import eu.kanade.tachiyomi.databinding.SourceCompactGridItemBinding import eu.kanade.tachiyomi.source.SourceManager +import eu.kanade.tachiyomi.ui.library.setting.DisplayModeSetting import eu.kanade.tachiyomi.widget.AutofitRecyclerView import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get @@ -24,7 +24,7 @@ import uy.kohesive.injekt.api.get class LibraryItem( val manga: LibraryManga, private val shouldSetFromCategory: Preference, - private val defaultLibraryDisplayMode: Preference + private val defaultLibraryDisplayMode: Preference ) : AbstractFlexibleItem>(), IFilterable { @@ -35,13 +35,9 @@ class LibraryItem( var unreadCount = -1 var isLocal = false - private fun getDisplayMode(): DisplayMode { + private fun getDisplayMode(): DisplayModeSetting { return if (shouldSetFromCategory.get() && manga.category != 0) { - if (displayMode != -1) { - DisplayMode.values()[displayMode] - } else { - DisplayMode.COMPACT_GRID - } + DisplayModeSetting.fromFlag(displayMode) } else { defaultLibraryDisplayMode.get() } @@ -49,15 +45,15 @@ class LibraryItem( override fun getLayoutRes(): Int { return when (getDisplayMode()) { - DisplayMode.COMPACT_GRID -> R.layout.source_compact_grid_item - DisplayMode.COMFORTABLE_GRID -> R.layout.source_comfortable_grid_item - DisplayMode.LIST -> R.layout.source_list_item + DisplayModeSetting.COMPACT_GRID -> R.layout.source_compact_grid_item + DisplayModeSetting.COMFORTABLE_GRID -> R.layout.source_comfortable_grid_item + DisplayModeSetting.LIST -> R.layout.source_list_item } } override fun createViewHolder(view: View, adapter: FlexibleAdapter>): LibraryHolder<*> { return when (getDisplayMode()) { - DisplayMode.COMPACT_GRID -> { + DisplayModeSetting.COMPACT_GRID -> { val binding = SourceCompactGridItemBinding.bind(view) val parent = adapter.recyclerView as AutofitRecyclerView val coverHeight = parent.itemWidth / 3 * 4 @@ -71,7 +67,7 @@ class LibraryItem( } LibraryCompactGridHolder(view, adapter) } - DisplayMode.COMFORTABLE_GRID -> { + DisplayModeSetting.COMFORTABLE_GRID -> { val binding = SourceComfortableGridItemBinding.bind(view) val parent = adapter.recyclerView as AutofitRecyclerView val coverHeight = parent.itemWidth / 3 * 4 @@ -83,7 +79,7 @@ class LibraryItem( } LibraryComfortableGridHolder(view, adapter) } - DisplayMode.LIST -> { + DisplayModeSetting.LIST -> { LibraryListHolder(view, adapter) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt index ed8dc3d6c3..88ff44dd99 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt @@ -15,6 +15,8 @@ import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter +import eu.kanade.tachiyomi.ui.library.setting.SortDirectionSetting +import eu.kanade.tachiyomi.ui.library.setting.SortModeSetting import eu.kanade.tachiyomi.util.isLocal import eu.kanade.tachiyomi.util.lang.combineLatest import eu.kanade.tachiyomi.util.lang.isNullOrUnsubscribed @@ -98,7 +100,7 @@ class LibraryPresenter( lib.copy(mangaMap = applyFilters(lib.mangaMap, tracks)) } .combineLatest(sortTriggerRelay.observeOn(Schedulers.io())) { lib, _ -> - lib.copy(mangaMap = applySort(lib.mangaMap)) + lib.copy(mangaMap = applySort(lib.categories, lib.mangaMap)) } .observeOn(AndroidSchedulers.mainThread()) .subscribeLatestCache({ view, (categories, mangaMap) -> @@ -228,9 +230,7 @@ class LibraryPresenter( * * @param map the map to sort. */ - private fun applySort(map: LibraryMap): LibraryMap { - val sortingMode = preferences.librarySortingMode().get() - + private fun applySort(categories: List, map: LibraryMap): LibraryMap { val lastReadManga by lazy { var counter = 0 db.getLastReadManga().executeAsBlocking().associate { it.id!! to counter++ } @@ -248,55 +248,67 @@ class LibraryPresenter( db.getChapterFetchDateManga().executeAsBlocking().associate { it.id!! to counter++ } } - val sortAscending = preferences.librarySortingAscending().get() + val sortingModes = categories.associate { category -> + (category.id ?: 0) to SortModeSetting.get(preferences, category) + } + + val sortAscending = categories.associate { category -> + (category.id ?: 0) to SortDirectionSetting.get(preferences, category) + } + val sortFn: (LibraryItem, LibraryItem) -> Int = { i1, i2 -> + val sortingMode = sortingModes[i1.manga.category]!! + val sortAscending = sortAscending[i1.manga.category]!! == SortDirectionSetting.ASCENDING when (sortingMode) { - LibrarySort.ALPHA -> i1.manga.title.compareTo(i2.manga.title, true) - LibrarySort.LAST_READ -> { + SortModeSetting.ALPHABETICAL -> i1.manga.title.compareTo(i2.manga.title, true) + SortModeSetting.LAST_READ -> { // Get index of manga, set equal to list if size unknown. val manga1LastRead = lastReadManga[i1.manga.id!!] ?: lastReadManga.size val manga2LastRead = lastReadManga[i2.manga.id!!] ?: lastReadManga.size manga1LastRead.compareTo(manga2LastRead) } - LibrarySort.LAST_CHECKED -> i2.manga.last_update.compareTo(i1.manga.last_update) - LibrarySort.UNREAD -> when { + SortModeSetting.LAST_CHECKED -> i2.manga.last_update.compareTo(i1.manga.last_update) + SortModeSetting.UNREAD -> when { // Ensure unread content comes first i1.manga.unread == i2.manga.unread -> 0 i1.manga.unread == 0 -> if (sortAscending) 1 else -1 i2.manga.unread == 0 -> if (sortAscending) -1 else 1 else -> i1.manga.unread.compareTo(i2.manga.unread) } - LibrarySort.TOTAL -> { + SortModeSetting.TOTAL_CHAPTERS -> { val manga1TotalChapter = totalChapterManga[i1.manga.id!!] ?: 0 val mange2TotalChapter = totalChapterManga[i2.manga.id!!] ?: 0 manga1TotalChapter.compareTo(mange2TotalChapter) } - LibrarySort.LATEST_CHAPTER -> { + SortModeSetting.LATEST_CHAPTER -> { val manga1latestChapter = latestChapterManga[i1.manga.id!!] ?: latestChapterManga.size val manga2latestChapter = latestChapterManga[i2.manga.id!!] ?: latestChapterManga.size manga1latestChapter.compareTo(manga2latestChapter) } - LibrarySort.CHAPTER_FETCH_DATE -> { + SortModeSetting.DATE_FETCHED -> { val manga1chapterFetchDate = chapterFetchDateManga[i1.manga.id!!] ?: chapterFetchDateManga.size val manga2chapterFetchDate = chapterFetchDateManga[i2.manga.id!!] ?: chapterFetchDateManga.size manga1chapterFetchDate.compareTo(manga2chapterFetchDate) } - LibrarySort.DATE_ADDED -> i2.manga.date_added.compareTo(i1.manga.date_added) - else -> throw Exception("Unknown sorting mode") + SortModeSetting.DATE_ADDED -> i2.manga.date_added.compareTo(i1.manga.date_added) } } - val comparator = if (sortAscending) { - Comparator(sortFn) - } else { - Collections.reverseOrder(sortFn) - } + return map.mapValues { entry -> + val sortAscending = sortAscending[entry.key]!! == SortDirectionSetting.ASCENDING - return map.mapValues { entry -> entry.value.sortedWith(comparator) } + val comparator = if (sortAscending) { + Comparator(sortFn) + } else { + Collections.reverseOrder(sortFn) + } + + entry.value.sortedWith(comparator) + } } /** diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibrarySettingsSheet.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibrarySettingsSheet.kt index 9cc1c4eb04..267701af47 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibrarySettingsSheet.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibrarySettingsSheet.kt @@ -7,10 +7,12 @@ import com.bluelinelabs.conductor.Router import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.DatabaseHelper import eu.kanade.tachiyomi.data.database.models.Category -import eu.kanade.tachiyomi.data.preference.PreferenceValues.DisplayMode import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.track.TrackManager import eu.kanade.tachiyomi.data.track.TrackService +import eu.kanade.tachiyomi.ui.library.setting.DisplayModeSetting +import eu.kanade.tachiyomi.ui.library.setting.SortDirectionSetting +import eu.kanade.tachiyomi.ui.library.setting.SortModeSetting import eu.kanade.tachiyomi.widget.ExtendedNavigationView import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.TriStateGroup.State import eu.kanade.tachiyomi.widget.sheet.TabbedBottomSheetDialog @@ -45,6 +47,8 @@ class LibrarySettingsSheet( * @param currentCategory ID of currently shown category */ fun show(currentCategory: Category) { + sort.currentCategory = currentCategory + sort.adjustDisplaySelection() display.currentCategory = currentCategory display.adjustDisplaySelection() super.show() @@ -158,8 +162,16 @@ class LibrarySettingsSheet( inner class Sort @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : Settings(context, attrs) { + private val sort = SortGroup() + init { - setGroups(listOf(SortGroup())) + setGroups(listOf(sort)) + } + + // Refreshes Display Setting selections + fun adjustDisplaySelection() { + sort.initModels() + sort.items.forEach { adapter.notifyItemChanged(it) } } inner class SortGroup : Group { @@ -179,29 +191,29 @@ class LibrarySettingsSheet( override val footer = null override fun initModels() { - val sorting = preferences.librarySortingMode().get() - val order = if (preferences.librarySortingAscending().get()) { + val sorting = SortModeSetting.get(preferences, currentCategory) + val order = if (SortDirectionSetting.get(preferences, currentCategory) == SortDirectionSetting.ASCENDING) { Item.MultiSort.SORT_ASC } else { Item.MultiSort.SORT_DESC } alphabetically.state = - if (sorting == LibrarySort.ALPHA) order else Item.MultiSort.SORT_NONE + if (sorting == SortModeSetting.ALPHABETICAL) order else Item.MultiSort.SORT_NONE lastRead.state = - if (sorting == LibrarySort.LAST_READ) order else Item.MultiSort.SORT_NONE + if (sorting == SortModeSetting.LAST_READ) order else Item.MultiSort.SORT_NONE lastChecked.state = - if (sorting == LibrarySort.LAST_CHECKED) order else Item.MultiSort.SORT_NONE + if (sorting == SortModeSetting.LAST_CHECKED) order else Item.MultiSort.SORT_NONE unread.state = - if (sorting == LibrarySort.UNREAD) order else Item.MultiSort.SORT_NONE + if (sorting == SortModeSetting.UNREAD) order else Item.MultiSort.SORT_NONE total.state = - if (sorting == LibrarySort.TOTAL) order else Item.MultiSort.SORT_NONE + if (sorting == SortModeSetting.TOTAL_CHAPTERS) order else Item.MultiSort.SORT_NONE latestChapter.state = - if (sorting == LibrarySort.LATEST_CHAPTER) order else Item.MultiSort.SORT_NONE + if (sorting == SortModeSetting.LATEST_CHAPTER) order else Item.MultiSort.SORT_NONE chapterFetchDate.state = - if (sorting == LibrarySort.CHAPTER_FETCH_DATE) order else Item.MultiSort.SORT_NONE + if (sorting == SortModeSetting.DATE_FETCHED) order else Item.MultiSort.SORT_NONE dateAdded.state = - if (sorting == LibrarySort.DATE_ADDED) order else Item.MultiSort.SORT_NONE + if (sorting == SortModeSetting.DATE_ADDED) order else Item.MultiSort.SORT_NONE } override fun onItemClicked(item: Item) { @@ -219,23 +231,50 @@ class LibrarySettingsSheet( else -> throw Exception("Unknown state") } - preferences.librarySortingMode().set( - when (item) { - alphabetically -> LibrarySort.ALPHA - lastRead -> LibrarySort.LAST_READ - lastChecked -> LibrarySort.LAST_CHECKED - unread -> LibrarySort.UNREAD - total -> LibrarySort.TOTAL - latestChapter -> LibrarySort.LATEST_CHAPTER - chapterFetchDate -> LibrarySort.CHAPTER_FETCH_DATE - dateAdded -> LibrarySort.DATE_ADDED - else -> throw Exception("Unknown sorting") - } - ) - preferences.librarySortingAscending().set(item.state == Item.MultiSort.SORT_ASC) + setSortModePreference(item) + + setSortDirectionPrefernece(item) item.group.items.forEach { adapter.notifyItemChanged(it) } } + + private fun setSortDirectionPrefernece(item: Item.MultiStateGroup) { + val flag = if (item.state == Item.MultiSort.SORT_ASC) { + SortDirectionSetting.ASCENDING + } else { + SortDirectionSetting.DESCENDING + } + + if (preferences.categorisedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0) { + currentCategory?.sortDirection = flag.flag + + db.insertCategory(currentCategory!!).executeAsBlocking() + } else { + preferences.librarySortingAscending().set(flag) + } + } + + private fun setSortModePreference(item: Item) { + val flag = when (item) { + alphabetically -> SortModeSetting.ALPHABETICAL + lastRead -> SortModeSetting.LAST_READ + lastChecked -> SortModeSetting.LAST_CHECKED + unread -> SortModeSetting.UNREAD + total -> SortModeSetting.TOTAL_CHAPTERS + latestChapter -> SortModeSetting.LATEST_CHAPTER + chapterFetchDate -> SortModeSetting.DATE_FETCHED + dateAdded -> SortModeSetting.DATE_ADDED + else -> throw NotImplementedError("Unknown display mode") + } + + if (preferences.categorisedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0) { + currentCategory?.sortMode = flag.flag + + db.insertCategory(currentCategory!!).executeAsBlocking() + } else { + preferences.librarySortingMode().set(flag) + } + } } } @@ -264,9 +303,9 @@ class LibrarySettingsSheet( } // Gets user preference of currently selected display mode at current category - private fun getDisplayModePreference(): DisplayMode { + private fun getDisplayModePreference(): DisplayModeSetting { return if (preferences.categorisedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0) { - DisplayMode.values()[currentCategory?.displayMode ?: 0] + DisplayModeSetting.fromFlag(currentCategory?.displayMode) } else { preferences.libraryDisplayMode().get() } @@ -300,33 +339,26 @@ class LibrarySettingsSheet( } // Sets display group selections based on given mode - fun setGroupSelections(mode: DisplayMode) { - compactGrid.checked = mode == DisplayMode.COMPACT_GRID - comfortableGrid.checked = mode == DisplayMode.COMFORTABLE_GRID - list.checked = mode == DisplayMode.LIST + fun setGroupSelections(mode: DisplayModeSetting) { + compactGrid.checked = mode == DisplayModeSetting.COMPACT_GRID + comfortableGrid.checked = mode == DisplayModeSetting.COMFORTABLE_GRID + list.checked = mode == DisplayModeSetting.LIST } private fun setDisplayModePreference(item: Item) { - if (preferences.categorisedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0) { - val flag = when (item) { - compactGrid -> Category.COMPACT_GRID - comfortableGrid -> Category.COMFORTABLE_GRID - list -> Category.LIST - else -> throw NotImplementedError("Unknown display mode") - } + val flag = when (item) { + compactGrid -> DisplayModeSetting.COMPACT_GRID + comfortableGrid -> DisplayModeSetting.COMFORTABLE_GRID + list -> DisplayModeSetting.LIST + else -> throw NotImplementedError("Unknown display mode") + } - currentCategory?.displayMode = flag + if (preferences.categorisedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0) { + currentCategory?.displayMode = flag.flag db.insertCategory(currentCategory!!).executeAsBlocking() } else { - preferences.libraryDisplayMode().set( - when (item) { - compactGrid -> DisplayMode.COMPACT_GRID - comfortableGrid -> DisplayMode.COMFORTABLE_GRID - list -> DisplayMode.LIST - else -> throw NotImplementedError("Unknown display mode") - } - ) + preferences.libraryDisplayMode().set(flag) } } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibrarySort.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibrarySort.kt index 28e583c84a..1190d61c1d 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibrarySort.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibrarySort.kt @@ -1,5 +1,6 @@ package eu.kanade.tachiyomi.ui.library +@Deprecated("Deprecated in favor for SortModeSetting") object LibrarySort { const val ALPHA = 0 diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/setting/DisplayModeSetting.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/setting/DisplayModeSetting.kt new file mode 100644 index 0000000000..dca6a744ae --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/setting/DisplayModeSetting.kt @@ -0,0 +1,16 @@ +package eu.kanade.tachiyomi.ui.library.setting + +enum class DisplayModeSetting(val flag: Int) { + COMPACT_GRID(0b00000000), + COMFORTABLE_GRID(0b00000001), + LIST(0b00000010); + + companion object { + const val MASK = 0b00000011 + + fun fromFlag(flag: Int?): DisplayModeSetting { + return values() + .find { mode -> mode.flag == flag } ?: COMPACT_GRID + } + } +} diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/setting/SortDirectionSetting.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/setting/SortDirectionSetting.kt new file mode 100644 index 0000000000..dc79f2d400 --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/setting/SortDirectionSetting.kt @@ -0,0 +1,25 @@ +package eu.kanade.tachiyomi.ui.library.setting + +import eu.kanade.tachiyomi.data.database.models.Category +import eu.kanade.tachiyomi.data.preference.PreferencesHelper + +enum class SortDirectionSetting(val flag: Int) { + ASCENDING(0b01000000), + DESCENDING(0b00000000); + + companion object { + const val MASK = 0b01000000 + + fun fromFlag(flag: Int?): SortDirectionSetting { + return values().find { mode -> mode.flag == flag } ?: ASCENDING + } + + fun get(preferences: PreferencesHelper, category: Category?): SortDirectionSetting { + return if (preferences.categorisedDisplaySettings().get() && category != null && category.id != 0) { + fromFlag(category.sortDirection) + } else { + preferences.librarySortingAscending().get() + } + } + } +} diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/setting/SortModeSetting.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/setting/SortModeSetting.kt new file mode 100644 index 0000000000..33df901ff0 --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/setting/SortModeSetting.kt @@ -0,0 +1,32 @@ +package eu.kanade.tachiyomi.ui.library.setting + +import eu.kanade.tachiyomi.data.database.models.Category +import eu.kanade.tachiyomi.data.preference.PreferencesHelper + +enum class SortModeSetting(val flag: Int) { + ALPHABETICAL(0b00000000), + LAST_READ(0b00000100), + LAST_CHECKED(0b00001000), + UNREAD(0b00001100), + TOTAL_CHAPTERS(0b00010000), + LATEST_CHAPTER(0b00010100), + DATE_FETCHED(0b00011000), + DATE_ADDED(0b00011100); + + companion object { + // Mask supports for more sorting flags if necessary + const val MASK = 0b00111100 + + fun fromFlag(flag: Int?): SortModeSetting { + return values().find { mode -> mode.flag == flag } ?: ALPHABETICAL + } + + fun get(preferences: PreferencesHelper, category: Category?): SortModeSetting { + return if (preferences.categorisedDisplaySettings().get() && category != null && category.id != 0) { + fromFlag(category.sortMode) + } else { + preferences.librarySortingMode().get() + } + } + } +} diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt index 1e1bd8e8aa..8bc9354209 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt @@ -84,6 +84,8 @@ class MainActivity : BaseViewBindingActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + val didMigration = if (savedInstanceState == null) Migrations.upgrade(preferences) else false + binding = MainActivityBinding.inflate(layoutInflater) // Do not let the launcher create a new activity http://stackoverflow.com/questions/16283079 @@ -224,7 +226,7 @@ class MainActivity : BaseViewBindingActivity() { preferences.incognitoMode().set(false) // Show changelog prompt on update - if (Migrations.upgrade(preferences) && !BuildConfig.DEBUG) { + if (didMigration && !BuildConfig.DEBUG) { WhatsNewDialogController().showDialog(router) } }