mirror of
https://github.com/aniyomiorg/aniyomi.git
synced 2024-11-28 09:15:12 +03:00
Merge remote-tracking branch 'upstream/master'
TODO: fix sorting in anime library
This commit is contained in:
commit
267b68b7d9
57 changed files with 873 additions and 504 deletions
43
.github/ISSUE_TEMPLATE/bug_report.md
vendored
43
.github/ISSUE_TEMPLATE/bug_report.md
vendored
|
@ -1,43 +0,0 @@
|
||||||
---
|
|
||||||
name: "🐞 Bug report"
|
|
||||||
about: Report a bug
|
|
||||||
title: "[Bug] <Write short description here>"
|
|
||||||
labels: "bug"
|
|
||||||
---
|
|
||||||
|
|
||||||
**PLEASE READ THIS**
|
|
||||||
|
|
||||||
I acknowledge that:
|
|
||||||
|
|
||||||
- I have updated:
|
|
||||||
- To the latest version of the app
|
|
||||||
- All extensions
|
|
||||||
- If this is an issue with an extension, that I should be opening an issue in https://github.com/jmir1/aniyomi-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
|
|
||||||
* Aniyomi 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.
|
|
106
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
106
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
name: 🐞 Bug report
|
||||||
|
description: Report a bug in Aniyomi
|
||||||
|
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/jmir1/aniyomi-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 the **[latest version](https://github.com/jmir1/aniyomi/releases)**.
|
||||||
|
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: aniyomi-version
|
||||||
|
attributes:
|
||||||
|
label: Aniyomi version
|
||||||
|
description: You can find your Aniyomi version in **More → About**.
|
||||||
|
placeholder: |
|
||||||
|
Example: "0.11.1.7"
|
||||||
|
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.
|
11
.github/ISSUE_TEMPLATE/config.yml
vendored
11
.github/ISSUE_TEMPLATE/config.yml
vendored
|
@ -1,8 +1,11 @@
|
||||||
blank_issues_enabled: false
|
blank_issues_enabled: false
|
||||||
contact_links:
|
contact_links:
|
||||||
- name: Aniyomi help discord
|
- name: ⚠️ Anime extension/source issue
|
||||||
|
url: https://github.com/jmir1/aniyomi-extensions/issues/new/choose
|
||||||
|
about: Issues and requests for extensions and sources should be opened in the aniyomi-extensions repository instead.
|
||||||
|
- name: 📦 Aniyomi extensions
|
||||||
|
url: https://github.com/jmir1/aniyomi-extensions
|
||||||
|
about: Anime extensions and sources.
|
||||||
|
- name: Aniyomi help discord
|
||||||
url: https://discord.gg/F32UjdJZrR
|
url: https://discord.gg/F32UjdJZrR
|
||||||
about: Common questions are answered here.
|
about: Common questions are answered here.
|
||||||
- name: Aniyomi extensions GitHub repository
|
|
||||||
url: https://github.com/jmir1/aniyomi-extensions
|
|
||||||
about: Issues about an anime extension/source/catalogue should be opened here instead.
|
|
||||||
|
|
29
.github/ISSUE_TEMPLATE/feature_request.md
vendored
29
.github/ISSUE_TEMPLATE/feature_request.md
vendored
|
@ -1,29 +0,0 @@
|
||||||
---
|
|
||||||
name: "🌟 Feature request"
|
|
||||||
about: Suggest a feature to improve Aniyomi
|
|
||||||
title: "[Feature Request] <Write short description here>"
|
|
||||||
labels: "feature"
|
|
||||||
---
|
|
||||||
|
|
||||||
**PLEASE READ THIS**
|
|
||||||
|
|
||||||
I acknowledge that:
|
|
||||||
|
|
||||||
- I have updated:
|
|
||||||
- To the latest version of the app
|
|
||||||
- All extensions
|
|
||||||
- If this is an issue with an anime extension, that I should be opening an issue in https://github.com/jmir1/aniyomi-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)
|
|
39
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
39
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
name: ⭐ Feature request
|
||||||
|
description: Suggest a feature for Aniyomi
|
||||||
|
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/jmir1/aniyomi-extensions/issues/new/choose).
|
||||||
|
required: true
|
||||||
|
- label: I have updated the app to the **[latest version](https://github.com/jmir1/aniyomi/releases)**.
|
||||||
|
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.
|
8
.github/ISSUE_TEMPLATE/source_issue.md
vendored
8
.github/ISSUE_TEMPLATE/source_issue.md
vendored
|
@ -1,8 +0,0 @@
|
||||||
---
|
|
||||||
name: "Extension/source/catalogue issue"
|
|
||||||
about: "Do not open an issue here. See https://github.com/jmir1/aniyomi-extensions"
|
|
||||||
title: "THIS ISSUE IS IN THE WRONG REPO; SEE https://github.com/jmir1/aniyomi-extensions"
|
|
||||||
labels: "catalog, invalid"
|
|
||||||
---
|
|
||||||
|
|
||||||
DO NOT OPEN AN ISSUE IN THIS REPO. SEE https://github.com/jmir1/aniyomi-extensions
|
|
1
.github/workflows/build.yml
vendored
1
.github/workflows/build.yml
vendored
|
@ -22,7 +22,6 @@ jobs:
|
||||||
build:
|
build:
|
||||||
name: Build app
|
name: Build app
|
||||||
needs: check_wrapper
|
needs: check_wrapper
|
||||||
if: "!startsWith(github.event.head_commit.message, '[SKIP CI]')"
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
|
10
.github/workflows/issue_closer.yml
vendored
10
.github/workflows/issue_closer.yml
vendored
|
@ -13,16 +13,6 @@ jobs:
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
rules: |
|
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": ".*<Write short description here>*",
|
|
||||||
"message": "The description in the title was not filled out."
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"type": "body",
|
"type": "body",
|
||||||
"regex": ".*DELETE THIS SECTION IF YOU HAVE READ AND ACKNOWLEDGED IT.*",
|
"regex": ".*DELETE THIS SECTION IF YOU HAVE READ AND ACKNOWLEDGED IT.*",
|
||||||
|
|
2
.github/workflows/issue_moderator.yml
vendored
2
.github/workflows/issue_moderator.yml
vendored
|
@ -9,6 +9,6 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Moderate issues
|
- name: Moderate issues
|
||||||
uses: tachiyomiorg/issue-moderator-action@v1.0
|
uses: tachiyomiorg/issue-moderator-action@v1.1
|
||||||
with:
|
with:
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
|
@ -221,7 +221,7 @@ dependencies {
|
||||||
implementation("com.github.tachiyomiorg:subsampling-scale-image-view:846abe0") {
|
implementation("com.github.tachiyomiorg:subsampling-scale-image-view:846abe0") {
|
||||||
exclude(module = "image-decoder")
|
exclude(module = "image-decoder")
|
||||||
}
|
}
|
||||||
implementation("com.github.tachiyomiorg:image-decoder:ac5f65c")
|
implementation("com.github.tachiyomiorg:image-decoder:0e91111")
|
||||||
|
|
||||||
// Logging
|
// Logging
|
||||||
implementation("com.jakewharton.timber:timber:4.7.1")
|
implementation("com.jakewharton.timber:timber:4.7.1")
|
||||||
|
|
|
@ -13,7 +13,10 @@ import eu.kanade.tachiyomi.data.updater.UpdaterJob
|
||||||
import eu.kanade.tachiyomi.extension.AnimeExtensionUpdateJob
|
import eu.kanade.tachiyomi.extension.AnimeExtensionUpdateJob
|
||||||
import eu.kanade.tachiyomi.extension.ExtensionUpdateJob
|
import eu.kanade.tachiyomi.extension.ExtensionUpdateJob
|
||||||
import eu.kanade.tachiyomi.network.PREF_DOH_CLOUDFLARE
|
import eu.kanade.tachiyomi.network.PREF_DOH_CLOUDFLARE
|
||||||
|
import eu.kanade.tachiyomi.ui.animelib.AnimelibSort
|
||||||
import eu.kanade.tachiyomi.ui.library.LibrarySort
|
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.ui.reader.setting.OrientationType
|
||||||
import eu.kanade.tachiyomi.util.system.toast
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
import eu.kanade.tachiyomi.widget.ExtendedNavigationView
|
import eu.kanade.tachiyomi.widget.ExtendedNavigationView
|
||||||
|
@ -100,9 +103,15 @@ object Migrations {
|
||||||
}
|
}
|
||||||
if (oldVersion < 44) {
|
if (oldVersion < 44) {
|
||||||
// Reset sorting preference if using removed sort by source
|
// Reset sorting preference if using removed sort by source
|
||||||
|
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
|
||||||
|
|
||||||
|
val oldSortingMode = prefs.getInt(PreferenceKeys.librarySortingMode, 0)
|
||||||
|
|
||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
if (preferences.librarySortingMode().get() == LibrarySort.SOURCE) {
|
if (oldSortingMode == LibrarySort.SOURCE) {
|
||||||
preferences.librarySortingMode().set(LibrarySort.ALPHA)
|
prefs.edit {
|
||||||
|
putInt(PreferenceKeys.librarySortingMode, LibrarySort.ALPHA)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (oldVersion < 52) {
|
if (oldVersion < 52) {
|
||||||
|
@ -209,6 +218,65 @@ object Migrations {
|
||||||
LibraryUpdateJob.setupTask(context)
|
LibraryUpdateJob.setupTask(context)
|
||||||
AnimelibUpdateJob.setupTask(context)
|
AnimelibUpdateJob.setupTask(context)
|
||||||
}
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
val oldSortingModeAnime = prefs.getInt(PreferenceKeys.animelibSortingMode, 0)
|
||||||
|
val oldSortingDirectionAnime = prefs.getBoolean(PreferenceKeys.animelibSortingDirection, true)
|
||||||
|
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
val newSortingModeAnime = when (oldSortingModeAnime) {
|
||||||
|
AnimelibSort.ALPHA -> SortModeSetting.ALPHABETICAL
|
||||||
|
AnimelibSort.LAST_READ -> SortModeSetting.LAST_READ
|
||||||
|
AnimelibSort.LAST_CHECKED -> SortModeSetting.LAST_CHECKED
|
||||||
|
AnimelibSort.UNREAD -> SortModeSetting.UNREAD
|
||||||
|
AnimelibSort.TOTAL -> SortModeSetting.TOTAL_CHAPTERS
|
||||||
|
AnimelibSort.LATEST_CHAPTER -> SortModeSetting.LATEST_CHAPTER
|
||||||
|
AnimelibSort.CHAPTER_FETCH_DATE -> SortModeSetting.DATE_FETCHED
|
||||||
|
AnimelibSort.DATE_ADDED -> SortModeSetting.DATE_ADDED
|
||||||
|
else -> SortModeSetting.ALPHABETICAL
|
||||||
|
}
|
||||||
|
|
||||||
|
val newSortingDirectionAnime = when (oldSortingDirectionAnime) {
|
||||||
|
true -> SortDirectionSetting.ASCENDING
|
||||||
|
else -> SortDirectionSetting.DESCENDING
|
||||||
|
}
|
||||||
|
|
||||||
|
prefs.edit(commit = true) {
|
||||||
|
remove(PreferenceKeys.librarySortingMode)
|
||||||
|
remove(PreferenceKeys.librarySortingDirection)
|
||||||
|
remove(PreferenceKeys.animelibSortingMode)
|
||||||
|
remove(PreferenceKeys.animelibSortingDirection)
|
||||||
|
}
|
||||||
|
|
||||||
|
prefs.edit {
|
||||||
|
putString(PreferenceKeys.librarySortingMode, newSortingMode.name)
|
||||||
|
putString(PreferenceKeys.librarySortingDirection, newSortingDirection.name)
|
||||||
|
putString(PreferenceKeys.animelibSortingMode, newSortingModeAnime.name)
|
||||||
|
putString(PreferenceKeys.animelibSortingDirection, newSortingDirectionAnime.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
package eu.kanade.tachiyomi.data.database.models
|
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
|
import java.io.Serializable
|
||||||
|
|
||||||
interface Category : Serializable {
|
interface Category : Serializable {
|
||||||
|
@ -17,16 +20,19 @@ interface Category : Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
var displayMode: Int
|
var displayMode: Int
|
||||||
get() = flags and MASK
|
get() = flags and DisplayModeSetting.MASK
|
||||||
set(mode) = setFlags(mode, MASK)
|
set(mode) = setFlags(mode, DisplayModeSetting.MASK)
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
const val COMPACT_GRID = 0b00000000
|
|
||||||
const val COMFORTABLE_GRID = 0b00000001
|
|
||||||
const val LIST = 0b00000010
|
|
||||||
const val MASK = 0b00000011
|
|
||||||
|
|
||||||
fun create(name: String): Category = CategoryImpl().apply {
|
fun create(name: String): Category = CategoryImpl().apply {
|
||||||
this.name = name
|
this.name = name
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,6 +118,7 @@ object PreferenceKeys {
|
||||||
const val lastUsedAnimeCategory = "last_used_anime_category"
|
const val lastUsedAnimeCategory = "last_used_anime_category"
|
||||||
|
|
||||||
const val sourceDisplayMode = "pref_display_mode_catalogue"
|
const val sourceDisplayMode = "pref_display_mode_catalogue"
|
||||||
|
const val animesourceDisplayMode = "pref_display_mode_anime_catalogue"
|
||||||
|
|
||||||
const val enabledLanguages = "source_languages"
|
const val enabledLanguages = "source_languages"
|
||||||
|
|
||||||
|
@ -163,8 +164,10 @@ object PreferenceKeys {
|
||||||
const val filterTracked = "pref_filter_library_tracked"
|
const val filterTracked = "pref_filter_library_tracked"
|
||||||
|
|
||||||
const val librarySortingMode = "library_sorting_mode"
|
const val librarySortingMode = "library_sorting_mode"
|
||||||
|
const val librarySortingDirection = "library_sorting_ascending"
|
||||||
|
|
||||||
const val animelibSortingMode = "animelib_sorting_mode"
|
const val animelibSortingMode = "animelib_sorting_mode"
|
||||||
|
const val animelibSortingDirection = "animelib_sorting_ascending"
|
||||||
|
|
||||||
const val automaticExtUpdates = "automatic_ext_updates"
|
const val automaticExtUpdates = "automatic_ext_updates"
|
||||||
|
|
||||||
|
|
|
@ -37,12 +37,6 @@ object PreferenceValues {
|
||||||
|
|
||||||
/* ktlint-enable experimental:enum-entry-name-case */
|
/* 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) {
|
enum class TappingInvertMode(val shouldInvertHorizontal: Boolean = false, val shouldInvertVertical: Boolean = false) {
|
||||||
NONE,
|
NONE,
|
||||||
HORIZONTAL(shouldInvertHorizontal = true),
|
HORIZONTAL(shouldInvertHorizontal = true),
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package eu.kanade.tachiyomi.data.preference
|
package eu.kanade.tachiyomi.data.preference
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.res.Configuration
|
||||||
import android.os.Environment
|
import android.os.Environment
|
||||||
import androidx.core.content.edit
|
import androidx.core.content.edit
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
|
@ -10,9 +11,12 @@ import com.tfcporciuncula.flow.Preference
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.models.Anime
|
import eu.kanade.tachiyomi.data.database.models.Anime
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
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.TrackService
|
||||||
import eu.kanade.tachiyomi.data.track.anilist.Anilist
|
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.OrientationType
|
||||||
import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType
|
import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType
|
||||||
import eu.kanade.tachiyomi.widget.ExtendedNavigationView
|
import eu.kanade.tachiyomi.widget.ExtendedNavigationView
|
||||||
|
@ -85,7 +89,7 @@ class PreferencesHelper(val context: Context) {
|
||||||
|
|
||||||
fun showLibraryUpdateErrors() = prefs.getBoolean(Keys.showLibraryUpdateErrors, true)
|
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)
|
fun themeLight() = flowPrefs.getEnum(Keys.themeLight, Values.LightThemeVariant.default)
|
||||||
|
|
||||||
|
@ -199,7 +203,8 @@ class PreferencesHelper(val context: Context) {
|
||||||
|
|
||||||
fun lastVersionCode() = flowPrefs.getInt("last_version_code", 0)
|
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 animesourceDisplayMode() = flowPrefs.getEnum(Keys.animesourceDisplayMode, DisplayModeSetting.COMPACT_GRID)
|
||||||
|
|
||||||
fun enabledLanguages() = flowPrefs.getStringSet(Keys.enabledLanguages, setOf("en", Locale.getDefault().language))
|
fun enabledLanguages() = flowPrefs.getStringSet(Keys.enabledLanguages, setOf("en", Locale.getDefault().language))
|
||||||
|
|
||||||
|
@ -255,9 +260,9 @@ class PreferencesHelper(val context: Context) {
|
||||||
|
|
||||||
fun libraryUpdatePrioritization() = flowPrefs.getInt(Keys.libraryUpdatePrioritization, 0)
|
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 animelibDisplayMode() = flowPrefs.getEnum(Keys.animelibDisplayMode, DisplayMode.COMPACT_GRID)
|
fun animelibDisplayMode() = flowPrefs.getEnum(Keys.animelibDisplayMode, DisplayModeSetting.COMPACT_GRID)
|
||||||
|
|
||||||
fun downloadBadge() = flowPrefs.getBoolean(Keys.downloadBadge, false)
|
fun downloadBadge() = flowPrefs.getBoolean(Keys.downloadBadge, false)
|
||||||
|
|
||||||
|
@ -283,13 +288,11 @@ class PreferencesHelper(val context: Context) {
|
||||||
|
|
||||||
fun filterTracking(name: Int) = flowPrefs.getInt("${Keys.filterTracked}_$name", ExtendedNavigationView.Item.TriStateGroup.State.IGNORE.value)
|
fun filterTracking(name: Int) = flowPrefs.getInt("${Keys.filterTracked}_$name", ExtendedNavigationView.Item.TriStateGroup.State.IGNORE.value)
|
||||||
|
|
||||||
fun librarySortingMode() = flowPrefs.getInt(Keys.librarySortingMode, 0)
|
fun librarySortingMode() = flowPrefs.getEnum(Keys.librarySortingMode, SortModeSetting.ALPHABETICAL)
|
||||||
|
fun librarySortingAscending() = flowPrefs.getEnum(Keys.librarySortingDirection, SortDirectionSetting.ASCENDING)
|
||||||
|
|
||||||
fun librarySortingAscending() = flowPrefs.getBoolean("library_sorting_ascending", true)
|
fun animelibSortingMode() = flowPrefs.getEnum(Keys.animelibSortingMode, SortModeSetting.ALPHABETICAL)
|
||||||
|
fun animelibSortingAscending() = flowPrefs.getEnum(Keys.animelibSortingDirection, SortDirectionSetting.ASCENDING)
|
||||||
fun animelibSortingMode() = flowPrefs.getInt(Keys.animelibSortingMode, 0)
|
|
||||||
|
|
||||||
fun animelibSortingAscending() = flowPrefs.getBoolean("animelib_sorting_ascending", true)
|
|
||||||
|
|
||||||
fun automaticExtUpdates() = flowPrefs.getBoolean(Keys.automaticExtUpdates, true)
|
fun automaticExtUpdates() = flowPrefs.getBoolean(Keys.automaticExtUpdates, true)
|
||||||
|
|
||||||
|
@ -382,7 +385,21 @@ class PreferencesHelper(val context: Context) {
|
||||||
putInt(Keys.defaultEpisodeFilterByBookmarked, anime.bookmarkedFilter)
|
putInt(Keys.defaultEpisodeFilterByBookmarked, anime.bookmarkedFilter)
|
||||||
putInt(Keys.defaultEpisodeSortBySourceOrNumber, anime.sorting)
|
putInt(Keys.defaultEpisodeSortBySourceOrNumber, anime.sorting)
|
||||||
putInt(Keys.defaultEpisodeDisplayByNameOrNumber, anime.displayMode)
|
putInt(Keys.defaultEpisodeDisplayByNameOrNumber, anime.displayMode)
|
||||||
putInt(Keys.defaultEpisodeSortByAscendingOrDescending, if (anime.sortDescending()) Anime.EPISODE_SORT_DESC else Anime.EPISODE_SORT_ASC)
|
putInt(
|
||||||
|
Keys.defaultEpisodeSortByAscendingOrDescending,
|
||||||
|
if (anime.sortDescending()) Anime.EPISODE_SORT_DESC else Anime.EPISODE_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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,6 @@ import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.animelib.AnimelibUpdateService
|
import eu.kanade.tachiyomi.data.animelib.AnimelibUpdateService
|
||||||
import eu.kanade.tachiyomi.data.database.models.Anime
|
import eu.kanade.tachiyomi.data.database.models.Anime
|
||||||
import eu.kanade.tachiyomi.data.database.models.Category
|
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.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.databinding.AnimelibCategoryBinding
|
import eu.kanade.tachiyomi.databinding.AnimelibCategoryBinding
|
||||||
import eu.kanade.tachiyomi.util.lang.plusAssign
|
import eu.kanade.tachiyomi.util.lang.plusAssign
|
||||||
|
@ -28,6 +27,7 @@ import reactivecircus.flowbinding.swiperefreshlayout.refreshes
|
||||||
import rx.subscriptions.CompositeSubscription
|
import rx.subscriptions.CompositeSubscription
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.util.ArrayDeque
|
import java.util.ArrayDeque
|
||||||
|
import eu.kanade.tachiyomi.ui.library.setting.DisplayModeSetting as DisplayMode
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fragment containing the animelib anime for a certain category.
|
* Fragment containing the animelib anime for a certain category.
|
||||||
|
@ -125,7 +125,7 @@ class AnimelibCategoryView @JvmOverloads constructor(context: Context, attrs: At
|
||||||
|
|
||||||
// If displayMode should be set from category adjust manga count per row
|
// If displayMode should be set from category adjust manga count per row
|
||||||
if (preferences.categorisedDisplaySettings().get()) {
|
if (preferences.categorisedDisplaySettings().get()) {
|
||||||
recycler.spanCount = if (category.displayMode == Category.LIST || (preferences.animelibDisplayMode().get() == DisplayMode.LIST && category.id == 0)) {
|
recycler.spanCount = if (DisplayMode.fromFlag(category.displayMode) == DisplayMode.LIST || (preferences.libraryDisplayMode().get() == DisplayMode.LIST && category.id == 0)) {
|
||||||
1
|
1
|
||||||
} else {
|
} else {
|
||||||
controller.animePerRow
|
controller.animePerRow
|
||||||
|
|
|
@ -295,6 +295,11 @@ class AnimelibController(
|
||||||
.map { (it.id ?: -1) to (animeMap[it.id]?.size ?: 0) }
|
.map { (it.id ?: -1) to (animeMap[it.id]?.size ?: 0) }
|
||||||
.toMap()
|
.toMap()
|
||||||
|
|
||||||
|
if (preferences.categorisedDisplaySettings().get()) {
|
||||||
|
// Reattach adapter so it doesn't get de-synced
|
||||||
|
reattachAdapter()
|
||||||
|
}
|
||||||
|
|
||||||
// Restore active category.
|
// Restore active category.
|
||||||
binding.libraryPager.setCurrentItem(activeCat, false)
|
binding.libraryPager.setCurrentItem(activeCat, false)
|
||||||
|
|
||||||
|
|
|
@ -14,9 +14,9 @@ import eu.davidea.flexibleadapter.items.IFlexible
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.animesource.AnimeSourceManager
|
import eu.kanade.tachiyomi.animesource.AnimeSourceManager
|
||||||
import eu.kanade.tachiyomi.data.database.models.AnimelibAnime
|
import eu.kanade.tachiyomi.data.database.models.AnimelibAnime
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferenceValues.DisplayMode
|
|
||||||
import eu.kanade.tachiyomi.databinding.SourceComfortableGridItemBinding
|
import eu.kanade.tachiyomi.databinding.SourceComfortableGridItemBinding
|
||||||
import eu.kanade.tachiyomi.databinding.SourceCompactGridItemBinding
|
import eu.kanade.tachiyomi.databinding.SourceCompactGridItemBinding
|
||||||
|
import eu.kanade.tachiyomi.ui.library.setting.DisplayModeSetting
|
||||||
import eu.kanade.tachiyomi.widget.AutofitRecyclerView
|
import eu.kanade.tachiyomi.widget.AutofitRecyclerView
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
|
@ -24,7 +24,7 @@ import uy.kohesive.injekt.api.get
|
||||||
class AnimelibItem(
|
class AnimelibItem(
|
||||||
val anime: AnimelibAnime,
|
val anime: AnimelibAnime,
|
||||||
private val shouldSetFromCategory: Preference<Boolean>,
|
private val shouldSetFromCategory: Preference<Boolean>,
|
||||||
private val defaultLibraryDisplayMode: Preference<DisplayMode>
|
private val defaultLibraryDisplayMode: Preference<DisplayModeSetting>
|
||||||
) :
|
) :
|
||||||
AbstractFlexibleItem<AnimelibHolder<*>>(), IFilterable<String> {
|
AbstractFlexibleItem<AnimelibHolder<*>>(), IFilterable<String> {
|
||||||
|
|
||||||
|
@ -35,13 +35,9 @@ class AnimelibItem(
|
||||||
var unreadCount = -1
|
var unreadCount = -1
|
||||||
var isLocal = false
|
var isLocal = false
|
||||||
|
|
||||||
private fun getDisplayMode(): DisplayMode {
|
private fun getDisplayMode(): DisplayModeSetting {
|
||||||
return if (shouldSetFromCategory.get() && anime.category != 0) {
|
return if (shouldSetFromCategory.get() && anime.category != 0) {
|
||||||
if (displayMode != -1) {
|
DisplayModeSetting.fromFlag(displayMode)
|
||||||
DisplayMode.values()[displayMode]
|
|
||||||
} else {
|
|
||||||
DisplayMode.COMPACT_GRID
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
defaultLibraryDisplayMode.get()
|
defaultLibraryDisplayMode.get()
|
||||||
}
|
}
|
||||||
|
@ -49,15 +45,15 @@ class AnimelibItem(
|
||||||
|
|
||||||
override fun getLayoutRes(): Int {
|
override fun getLayoutRes(): Int {
|
||||||
return when (getDisplayMode()) {
|
return when (getDisplayMode()) {
|
||||||
DisplayMode.COMPACT_GRID -> R.layout.source_compact_grid_item
|
DisplayModeSetting.COMPACT_GRID -> R.layout.source_compact_grid_item
|
||||||
DisplayMode.COMFORTABLE_GRID -> R.layout.source_comfortable_grid_item
|
DisplayModeSetting.COMFORTABLE_GRID -> R.layout.source_comfortable_grid_item
|
||||||
DisplayMode.LIST -> R.layout.source_list_item
|
DisplayModeSetting.LIST -> R.layout.source_list_item
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): AnimelibHolder<*> {
|
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): AnimelibHolder<*> {
|
||||||
return when (getDisplayMode()) {
|
return when (getDisplayMode()) {
|
||||||
DisplayMode.COMPACT_GRID -> {
|
DisplayModeSetting.COMPACT_GRID -> {
|
||||||
val binding = SourceCompactGridItemBinding.bind(view)
|
val binding = SourceCompactGridItemBinding.bind(view)
|
||||||
val parent = adapter.recyclerView as AutofitRecyclerView
|
val parent = adapter.recyclerView as AutofitRecyclerView
|
||||||
val coverHeight = parent.itemWidth / 3 * 4
|
val coverHeight = parent.itemWidth / 3 * 4
|
||||||
|
@ -71,7 +67,7 @@ class AnimelibItem(
|
||||||
}
|
}
|
||||||
AnimelibCompactGridHolder(view, adapter)
|
AnimelibCompactGridHolder(view, adapter)
|
||||||
}
|
}
|
||||||
DisplayMode.COMFORTABLE_GRID -> {
|
DisplayModeSetting.COMFORTABLE_GRID -> {
|
||||||
val binding = SourceComfortableGridItemBinding.bind(view)
|
val binding = SourceComfortableGridItemBinding.bind(view)
|
||||||
val parent = adapter.recyclerView as AutofitRecyclerView
|
val parent = adapter.recyclerView as AutofitRecyclerView
|
||||||
val coverHeight = parent.itemWidth / 3 * 4
|
val coverHeight = parent.itemWidth / 3 * 4
|
||||||
|
@ -83,7 +79,7 @@ class AnimelibItem(
|
||||||
}
|
}
|
||||||
AnimelibComfortableGridHolder(view, adapter)
|
AnimelibComfortableGridHolder(view, adapter)
|
||||||
}
|
}
|
||||||
DisplayMode.LIST -> {
|
DisplayModeSetting.LIST -> {
|
||||||
AnimelibListHolder(view, adapter)
|
AnimelibListHolder(view, adapter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,8 @@ import eu.kanade.tachiyomi.data.download.AnimeDownloadManager
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.data.track.TrackManager
|
import eu.kanade.tachiyomi.data.track.TrackManager
|
||||||
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
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.isLocal
|
||||||
import eu.kanade.tachiyomi.util.lang.combineLatest
|
import eu.kanade.tachiyomi.util.lang.combineLatest
|
||||||
import eu.kanade.tachiyomi.util.lang.isNullOrUnsubscribed
|
import eu.kanade.tachiyomi.util.lang.isNullOrUnsubscribed
|
||||||
|
@ -98,7 +100,7 @@ class AnimelibPresenter(
|
||||||
lib.copy(animeMap = applyFilters(lib.animeMap, tracks))
|
lib.copy(animeMap = applyFilters(lib.animeMap, tracks))
|
||||||
}
|
}
|
||||||
.combineLatest(sortTriggerRelay.observeOn(Schedulers.io())) { lib, _ ->
|
.combineLatest(sortTriggerRelay.observeOn(Schedulers.io())) { lib, _ ->
|
||||||
lib.copy(animeMap = applySort(lib.animeMap))
|
lib.copy(animeMap = applySort(lib.categories, lib.animeMap))
|
||||||
}
|
}
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribeLatestCache({ view, (categories, animeMap) ->
|
.subscribeLatestCache({ view, (categories, animeMap) ->
|
||||||
|
@ -228,9 +230,7 @@ class AnimelibPresenter(
|
||||||
*
|
*
|
||||||
* @param map the map to sort.
|
* @param map the map to sort.
|
||||||
*/
|
*/
|
||||||
private fun applySort(map: AnimelibMap): AnimelibMap {
|
private fun applySort(categories: List<Category>, map: AnimelibMap): AnimelibMap {
|
||||||
val sortingMode = preferences.animelibSortingMode().get()
|
|
||||||
|
|
||||||
val lastReadAnime by lazy {
|
val lastReadAnime by lazy {
|
||||||
var counter = 0
|
var counter = 0
|
||||||
db.getLastSeenAnime().executeAsBlocking().associate { it.id!! to counter++ }
|
db.getLastSeenAnime().executeAsBlocking().associate { it.id!! to counter++ }
|
||||||
|
@ -248,55 +248,66 @@ class AnimelibPresenter(
|
||||||
db.getEpisodeFetchDateAnime().executeAsBlocking().associate { it.id!! to counter++ }
|
db.getEpisodeFetchDateAnime().executeAsBlocking().associate { it.id!! to counter++ }
|
||||||
}
|
}
|
||||||
|
|
||||||
val sortAscending = preferences.animelibSortingAscending().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: (AnimelibItem, AnimelibItem) -> Int = { i1, i2 ->
|
val sortFn: (AnimelibItem, AnimelibItem) -> Int = { i1, i2 ->
|
||||||
|
val sortingMode = sortingModes[i1.anime.category]!!
|
||||||
|
val sortAscending = sortAscending[i1.anime.category]!! == SortDirectionSetting.ASCENDING
|
||||||
when (sortingMode) {
|
when (sortingMode) {
|
||||||
AnimelibSort.ALPHA -> i1.anime.title.compareTo(i2.anime.title, true)
|
SortModeSetting.ALPHABETICAL -> i1.anime.title.compareTo(i2.anime.title, true)
|
||||||
AnimelibSort.LAST_READ -> {
|
SortModeSetting.LAST_READ -> {
|
||||||
// Get index of anime, set equal to list if size unknown.
|
// Get index of anime, set equal to list if size unknown.
|
||||||
val anime1LastRead = lastReadAnime[i1.anime.id!!] ?: lastReadAnime.size
|
val anime1LastRead = lastReadAnime[i1.anime.id!!] ?: lastReadAnime.size
|
||||||
val anime2LastRead = lastReadAnime[i2.anime.id!!] ?: lastReadAnime.size
|
val anime2LastRead = lastReadAnime[i2.anime.id!!] ?: lastReadAnime.size
|
||||||
anime1LastRead.compareTo(anime2LastRead)
|
anime1LastRead.compareTo(anime2LastRead)
|
||||||
}
|
}
|
||||||
AnimelibSort.LAST_CHECKED -> i2.anime.last_update.compareTo(i1.anime.last_update)
|
SortModeSetting.LAST_CHECKED -> i2.anime.last_update.compareTo(i1.anime.last_update)
|
||||||
AnimelibSort.UNREAD -> when {
|
SortModeSetting.UNREAD -> when {
|
||||||
// Ensure unread content comes first
|
// Ensure unread content comes first
|
||||||
i1.anime.unread == i2.anime.unread -> 0
|
i1.anime.unread == i2.anime.unread -> 0
|
||||||
i1.anime.unread == 0 -> if (sortAscending) 1 else -1
|
i1.anime.unread == 0 -> if (sortAscending) 1 else -1
|
||||||
i2.anime.unread == 0 -> if (sortAscending) -1 else 1
|
i2.anime.unread == 0 -> if (sortAscending) -1 else 1
|
||||||
else -> i1.anime.unread.compareTo(i2.anime.unread)
|
else -> i1.anime.unread.compareTo(i2.anime.unread)
|
||||||
}
|
}
|
||||||
AnimelibSort.TOTAL -> {
|
SortModeSetting.TOTAL_CHAPTERS -> {
|
||||||
val anime1TotalEpisode = totalChapterAnime[i1.anime.id!!] ?: 0
|
val anime1TotalEpisode = totalChapterAnime[i1.anime.id!!] ?: 0
|
||||||
val mange2TotalEpisode = totalChapterAnime[i2.anime.id!!] ?: 0
|
val mange2TotalEpisode = totalChapterAnime[i2.anime.id!!] ?: 0
|
||||||
anime1TotalEpisode.compareTo(mange2TotalEpisode)
|
anime1TotalEpisode.compareTo(mange2TotalEpisode)
|
||||||
}
|
}
|
||||||
AnimelibSort.LATEST_CHAPTER -> {
|
SortModeSetting.LATEST_CHAPTER -> {
|
||||||
val anime1latestEpisode = latestChapterAnime[i1.anime.id!!]
|
val anime1latestEpisode = latestChapterAnime[i1.anime.id!!]
|
||||||
?: latestChapterAnime.size
|
?: latestChapterAnime.size
|
||||||
val anime2latestEpisode = latestChapterAnime[i2.anime.id!!]
|
val anime2latestEpisode = latestChapterAnime[i2.anime.id!!]
|
||||||
?: latestChapterAnime.size
|
?: latestChapterAnime.size
|
||||||
anime1latestEpisode.compareTo(anime2latestEpisode)
|
anime1latestEpisode.compareTo(anime2latestEpisode)
|
||||||
}
|
}
|
||||||
AnimelibSort.CHAPTER_FETCH_DATE -> {
|
SortModeSetting.DATE_FETCHED -> {
|
||||||
val anime1chapterFetchDate = chapterFetchDateAnime[i1.anime.id!!]
|
val anime1chapterFetchDate = chapterFetchDateAnime[i1.anime.id!!]
|
||||||
?: chapterFetchDateAnime.size
|
?: chapterFetchDateAnime.size
|
||||||
val anime2chapterFetchDate = chapterFetchDateAnime[i2.anime.id!!]
|
val anime2chapterFetchDate = chapterFetchDateAnime[i2.anime.id!!]
|
||||||
?: chapterFetchDateAnime.size
|
?: chapterFetchDateAnime.size
|
||||||
anime1chapterFetchDate.compareTo(anime2chapterFetchDate)
|
anime1chapterFetchDate.compareTo(anime2chapterFetchDate)
|
||||||
}
|
}
|
||||||
AnimelibSort.DATE_ADDED -> i2.anime.date_added.compareTo(i1.anime.date_added)
|
SortModeSetting.DATE_ADDED -> i2.anime.date_added.compareTo(i1.anime.date_added)
|
||||||
else -> throw Exception("Unknown sorting mode")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val comparator = if (sortAscending) {
|
return map.mapValues { entry ->
|
||||||
Comparator(sortFn)
|
val sortAscending = sortAscending[entry.key]!! == SortDirectionSetting.ASCENDING
|
||||||
} else {
|
|
||||||
Collections.reverseOrder(sortFn)
|
|
||||||
}
|
|
||||||
|
|
||||||
return map.mapValues { entry -> entry.value.sortedWith(comparator) }
|
val comparator = if (sortAscending) {
|
||||||
|
Comparator(sortFn)
|
||||||
|
} else {
|
||||||
|
Collections.reverseOrder(sortFn)
|
||||||
|
}
|
||||||
|
|
||||||
|
entry.value.sortedWith(comparator)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -7,10 +7,12 @@ import com.bluelinelabs.conductor.Router
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.AnimeDatabaseHelper
|
import eu.kanade.tachiyomi.data.database.AnimeDatabaseHelper
|
||||||
import eu.kanade.tachiyomi.data.database.models.Category
|
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.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.data.track.TrackManager
|
import eu.kanade.tachiyomi.data.track.TrackManager
|
||||||
import eu.kanade.tachiyomi.data.track.TrackService
|
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
|
||||||
import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.TriStateGroup.State
|
import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.TriStateGroup.State
|
||||||
import eu.kanade.tachiyomi.widget.sheet.TabbedBottomSheetDialog
|
import eu.kanade.tachiyomi.widget.sheet.TabbedBottomSheetDialog
|
||||||
|
@ -45,6 +47,8 @@ class AnimelibSettingsSheet(
|
||||||
* @param currentCategory ID of currently shown category
|
* @param currentCategory ID of currently shown category
|
||||||
*/
|
*/
|
||||||
fun show(currentCategory: Category) {
|
fun show(currentCategory: Category) {
|
||||||
|
sort.currentCategory = currentCategory
|
||||||
|
sort.adjustDisplaySelection()
|
||||||
display.currentCategory = currentCategory
|
display.currentCategory = currentCategory
|
||||||
display.adjustDisplaySelection()
|
display.adjustDisplaySelection()
|
||||||
super.show()
|
super.show()
|
||||||
|
@ -158,8 +162,16 @@ class AnimelibSettingsSheet(
|
||||||
inner class Sort @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
|
inner class Sort @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
|
||||||
Settings(context, attrs) {
|
Settings(context, attrs) {
|
||||||
|
|
||||||
|
private val sort = SortGroup()
|
||||||
|
|
||||||
init {
|
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 {
|
inner class SortGroup : Group {
|
||||||
|
@ -179,29 +191,29 @@ class AnimelibSettingsSheet(
|
||||||
override val footer = null
|
override val footer = null
|
||||||
|
|
||||||
override fun initModels() {
|
override fun initModels() {
|
||||||
val sorting = preferences.animelibSortingMode().get()
|
val sorting = SortModeSetting.get(preferences, currentCategory)
|
||||||
val order = if (preferences.animelibSortingAscending().get()) {
|
val order = if (SortDirectionSetting.get(preferences, currentCategory) == SortDirectionSetting.ASCENDING) {
|
||||||
Item.MultiSort.SORT_ASC
|
Item.MultiSort.SORT_ASC
|
||||||
} else {
|
} else {
|
||||||
Item.MultiSort.SORT_DESC
|
Item.MultiSort.SORT_DESC
|
||||||
}
|
}
|
||||||
|
|
||||||
alphabetically.state =
|
alphabetically.state =
|
||||||
if (sorting == AnimelibSort.ALPHA) order else Item.MultiSort.SORT_NONE
|
if (sorting == SortModeSetting.ALPHABETICAL) order else Item.MultiSort.SORT_NONE
|
||||||
lastRead.state =
|
lastRead.state =
|
||||||
if (sorting == AnimelibSort.LAST_READ) order else Item.MultiSort.SORT_NONE
|
if (sorting == SortModeSetting.LAST_READ) order else Item.MultiSort.SORT_NONE
|
||||||
lastChecked.state =
|
lastChecked.state =
|
||||||
if (sorting == AnimelibSort.LAST_CHECKED) order else Item.MultiSort.SORT_NONE
|
if (sorting == SortModeSetting.LAST_CHECKED) order else Item.MultiSort.SORT_NONE
|
||||||
unread.state =
|
unread.state =
|
||||||
if (sorting == AnimelibSort.UNREAD) order else Item.MultiSort.SORT_NONE
|
if (sorting == SortModeSetting.UNREAD) order else Item.MultiSort.SORT_NONE
|
||||||
total.state =
|
total.state =
|
||||||
if (sorting == AnimelibSort.TOTAL) order else Item.MultiSort.SORT_NONE
|
if (sorting == SortModeSetting.TOTAL_CHAPTERS) order else Item.MultiSort.SORT_NONE
|
||||||
latestChapter.state =
|
latestChapter.state =
|
||||||
if (sorting == AnimelibSort.LATEST_CHAPTER) order else Item.MultiSort.SORT_NONE
|
if (sorting == SortModeSetting.LATEST_CHAPTER) order else Item.MultiSort.SORT_NONE
|
||||||
chapterFetchDate.state =
|
chapterFetchDate.state =
|
||||||
if (sorting == AnimelibSort.CHAPTER_FETCH_DATE) order else Item.MultiSort.SORT_NONE
|
if (sorting == SortModeSetting.DATE_FETCHED) order else Item.MultiSort.SORT_NONE
|
||||||
dateAdded.state =
|
dateAdded.state =
|
||||||
if (sorting == AnimelibSort.DATE_ADDED) order else Item.MultiSort.SORT_NONE
|
if (sorting == SortModeSetting.DATE_ADDED) order else Item.MultiSort.SORT_NONE
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onItemClicked(item: Item) {
|
override fun onItemClicked(item: Item) {
|
||||||
|
@ -219,23 +231,50 @@ class AnimelibSettingsSheet(
|
||||||
else -> throw Exception("Unknown state")
|
else -> throw Exception("Unknown state")
|
||||||
}
|
}
|
||||||
|
|
||||||
preferences.animelibSortingMode().set(
|
setSortModePreference(item)
|
||||||
when (item) {
|
|
||||||
alphabetically -> AnimelibSort.ALPHA
|
setSortDirectionPreference(item)
|
||||||
lastRead -> AnimelibSort.LAST_READ
|
|
||||||
lastChecked -> AnimelibSort.LAST_CHECKED
|
|
||||||
unread -> AnimelibSort.UNREAD
|
|
||||||
total -> AnimelibSort.TOTAL
|
|
||||||
latestChapter -> AnimelibSort.LATEST_CHAPTER
|
|
||||||
chapterFetchDate -> AnimelibSort.CHAPTER_FETCH_DATE
|
|
||||||
dateAdded -> AnimelibSort.DATE_ADDED
|
|
||||||
else -> throw Exception("Unknown sorting")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
preferences.animelibSortingAscending().set(item.state == Item.MultiSort.SORT_ASC)
|
|
||||||
|
|
||||||
item.group.items.forEach { adapter.notifyItemChanged(it) }
|
item.group.items.forEach { adapter.notifyItemChanged(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun setSortDirectionPreference(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.animelibSortingAscending().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.animelibSortingMode().set(flag)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,11 +303,11 @@ class AnimelibSettingsSheet(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets user preference of currently selected display mode at current category
|
// 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) {
|
return if (preferences.categorisedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0) {
|
||||||
DisplayMode.values()[currentCategory?.displayMode ?: 0]
|
DisplayModeSetting.fromFlag(currentCategory?.displayMode)
|
||||||
} else {
|
} else {
|
||||||
preferences.libraryDisplayMode().get()
|
preferences.animelibDisplayMode().get()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,35 +339,26 @@ class AnimelibSettingsSheet(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets display group selections based on given mode
|
// Sets display group selections based on given mode
|
||||||
fun setGroupSelections(mode: DisplayMode) {
|
fun setGroupSelections(mode: DisplayModeSetting) {
|
||||||
compactGrid.checked = mode == DisplayMode.COMPACT_GRID
|
compactGrid.checked = mode == DisplayModeSetting.COMPACT_GRID
|
||||||
comfortableGrid.checked = mode == DisplayMode.COMFORTABLE_GRID
|
comfortableGrid.checked = mode == DisplayModeSetting.COMFORTABLE_GRID
|
||||||
list.checked = mode == DisplayMode.LIST
|
list.checked = mode == DisplayModeSetting.LIST
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setDisplayModePreference(item: ExtendedNavigationView.Item) {
|
private fun setDisplayModePreference(item: ExtendedNavigationView.Item) {
|
||||||
if (preferences.categorisedDisplaySettings()
|
val flag = when (item) {
|
||||||
.get() && currentCategory != null && currentCategory?.id != 0
|
compactGrid -> DisplayModeSetting.COMPACT_GRID
|
||||||
) {
|
comfortableGrid -> DisplayModeSetting.COMFORTABLE_GRID
|
||||||
val flag = when (item) {
|
list -> DisplayModeSetting.LIST
|
||||||
compactGrid -> Category.COMPACT_GRID
|
else -> throw NotImplementedError("Unknown display mode")
|
||||||
comfortableGrid -> Category.COMFORTABLE_GRID
|
}
|
||||||
list -> Category.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()
|
db.insertCategory(currentCategory!!).executeAsBlocking()
|
||||||
} else {
|
} else {
|
||||||
preferences.libraryDisplayMode().set(
|
preferences.animelibDisplayMode().set(flag)
|
||||||
when (item) {
|
|
||||||
compactGrid -> DisplayMode.COMPACT_GRID
|
|
||||||
comfortableGrid -> DisplayMode.COMFORTABLE_GRID
|
|
||||||
list -> DisplayMode.LIST
|
|
||||||
else -> throw NotImplementedError("Unknown display mode")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package eu.kanade.tachiyomi.ui.animelib
|
package eu.kanade.tachiyomi.ui.animelib
|
||||||
|
|
||||||
|
@Deprecated("Deprecated in favor for SortModeSetting")
|
||||||
object AnimelibSort {
|
object AnimelibSort {
|
||||||
|
|
||||||
const val ALPHA = 0
|
const val ALPHA = 0
|
||||||
|
|
|
@ -1,14 +1,11 @@
|
||||||
package eu.kanade.tachiyomi.ui.base.activity
|
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 android.os.Bundle
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferenceValues.DarkThemeVariant
|
import eu.kanade.tachiyomi.data.preference.PreferenceValues.DarkThemeVariant
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferenceValues.LightThemeVariant
|
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.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.data.preference.asImmediateFlow
|
import eu.kanade.tachiyomi.data.preference.asImmediateFlow
|
||||||
import eu.kanade.tachiyomi.util.view.setSecureScreen
|
import eu.kanade.tachiyomi.util.view.setSecureScreen
|
||||||
|
@ -22,29 +19,7 @@ abstract class BaseThemedActivity : AppCompatActivity() {
|
||||||
val preferences: PreferencesHelper by injectLazy()
|
val preferences: PreferencesHelper by injectLazy()
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
val isDarkMode = when (preferences.themeMode().get()) {
|
setTheme(getThemeResourceId(preferences))
|
||||||
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)
|
|
||||||
|
|
||||||
Injekt.get<PreferencesHelper>().incognitoMode()
|
Injekt.get<PreferencesHelper>().incognitoMode()
|
||||||
.asImmediateFlow {
|
.asImmediateFlow {
|
||||||
|
@ -54,4 +29,26 @@ abstract class BaseThemedActivity : AppCompatActivity() {
|
||||||
|
|
||||||
super.onCreate(savedInstanceState)
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package eu.kanade.tachiyomi.ui.browse.animesource.browse
|
package eu.kanade.tachiyomi.ui.browse.animesource.browse
|
||||||
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import androidx.core.view.isVisible
|
||||||
import coil.clear
|
import coil.clear
|
||||||
import coil.imageLoader
|
import coil.imageLoader
|
||||||
import coil.request.ImageRequest
|
import coil.request.ImageRequest
|
||||||
|
@ -37,6 +38,12 @@ class AnimeSourceComfortableGridHolder(private val view: View, private val adapt
|
||||||
// Set alpha of thumbnail.
|
// Set alpha of thumbnail.
|
||||||
binding.thumbnail.alpha = if (anime.favorite) 0.3f else 1.0f
|
binding.thumbnail.alpha = if (anime.favorite) 0.3f else 1.0f
|
||||||
|
|
||||||
|
// For rounded corners
|
||||||
|
binding.badges.clipToOutline = true
|
||||||
|
|
||||||
|
// Set favorite badge
|
||||||
|
binding.favoriteText.isVisible = anime.favorite
|
||||||
|
|
||||||
setImage(anime)
|
setImage(anime)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package eu.kanade.tachiyomi.ui.browse.animesource.browse
|
package eu.kanade.tachiyomi.ui.browse.animesource.browse
|
||||||
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import androidx.core.view.isVisible
|
||||||
import coil.clear
|
import coil.clear
|
||||||
import coil.imageLoader
|
import coil.imageLoader
|
||||||
import coil.request.ImageRequest
|
import coil.request.ImageRequest
|
||||||
|
@ -37,6 +38,12 @@ open class AnimeSourceGridHolder(private val view: View, private val adapter: Fl
|
||||||
// Set alpha of thumbnail.
|
// Set alpha of thumbnail.
|
||||||
binding.thumbnail.alpha = if (anime.favorite) 0.3f else 1.0f
|
binding.thumbnail.alpha = if (anime.favorite) 0.3f else 1.0f
|
||||||
|
|
||||||
|
// For rounded corners
|
||||||
|
binding.badges.clipToOutline = true
|
||||||
|
|
||||||
|
// Set favorite badge
|
||||||
|
binding.favoriteText.isVisible = anime.favorite
|
||||||
|
|
||||||
setImage(anime)
|
setImage(anime)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,19 +12,19 @@ import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
import eu.davidea.flexibleadapter.items.IFlexible
|
import eu.davidea.flexibleadapter.items.IFlexible
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.models.Anime
|
import eu.kanade.tachiyomi.data.database.models.Anime
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferenceValues.DisplayMode
|
|
||||||
import eu.kanade.tachiyomi.databinding.SourceComfortableGridItemBinding
|
import eu.kanade.tachiyomi.databinding.SourceComfortableGridItemBinding
|
||||||
import eu.kanade.tachiyomi.databinding.SourceCompactGridItemBinding
|
import eu.kanade.tachiyomi.databinding.SourceCompactGridItemBinding
|
||||||
|
import eu.kanade.tachiyomi.ui.library.setting.DisplayModeSetting
|
||||||
import eu.kanade.tachiyomi.widget.AutofitRecyclerView
|
import eu.kanade.tachiyomi.widget.AutofitRecyclerView
|
||||||
|
|
||||||
class AnimeSourceItem(val anime: Anime, private val displayMode: Preference<DisplayMode>) :
|
class AnimeSourceItem(val anime: Anime, private val displayMode: Preference<DisplayModeSetting>) :
|
||||||
AbstractFlexibleItem<AnimeSourceHolder<*>>() {
|
AbstractFlexibleItem<AnimeSourceHolder<*>>() {
|
||||||
|
|
||||||
override fun getLayoutRes(): Int {
|
override fun getLayoutRes(): Int {
|
||||||
return when (displayMode.get()) {
|
return when (displayMode.get()) {
|
||||||
DisplayMode.COMPACT_GRID -> R.layout.source_compact_grid_item
|
DisplayModeSetting.COMPACT_GRID -> R.layout.source_compact_grid_item
|
||||||
DisplayMode.COMFORTABLE_GRID -> R.layout.source_comfortable_grid_item
|
DisplayModeSetting.COMFORTABLE_GRID -> R.layout.source_comfortable_grid_item
|
||||||
DisplayMode.LIST -> R.layout.source_list_item
|
DisplayModeSetting.LIST -> R.layout.source_list_item
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ class AnimeSourceItem(val anime: Anime, private val displayMode: Preference<Disp
|
||||||
adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>
|
adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>
|
||||||
): AnimeSourceHolder<*> {
|
): AnimeSourceHolder<*> {
|
||||||
return when (displayMode.get()) {
|
return when (displayMode.get()) {
|
||||||
DisplayMode.COMPACT_GRID -> {
|
DisplayModeSetting.COMPACT_GRID -> {
|
||||||
val binding = SourceCompactGridItemBinding.bind(view)
|
val binding = SourceCompactGridItemBinding.bind(view)
|
||||||
val parent = adapter.recyclerView as AutofitRecyclerView
|
val parent = adapter.recyclerView as AutofitRecyclerView
|
||||||
val coverHeight = parent.itemWidth / 3 * 4
|
val coverHeight = parent.itemWidth / 3 * 4
|
||||||
|
@ -50,7 +50,7 @@ class AnimeSourceItem(val anime: Anime, private val displayMode: Preference<Disp
|
||||||
}
|
}
|
||||||
AnimeSourceGridHolder(view, adapter)
|
AnimeSourceGridHolder(view, adapter)
|
||||||
}
|
}
|
||||||
DisplayMode.COMFORTABLE_GRID -> {
|
DisplayModeSetting.COMFORTABLE_GRID -> {
|
||||||
val binding = SourceComfortableGridItemBinding.bind(view)
|
val binding = SourceComfortableGridItemBinding.bind(view)
|
||||||
val parent = adapter.recyclerView as AutofitRecyclerView
|
val parent = adapter.recyclerView as AutofitRecyclerView
|
||||||
val coverHeight = parent.itemWidth / 3 * 4
|
val coverHeight = parent.itemWidth / 3 * 4
|
||||||
|
@ -62,7 +62,7 @@ class AnimeSourceItem(val anime: Anime, private val displayMode: Preference<Disp
|
||||||
}
|
}
|
||||||
AnimeSourceComfortableGridHolder(view, adapter)
|
AnimeSourceComfortableGridHolder(view, adapter)
|
||||||
}
|
}
|
||||||
DisplayMode.LIST -> {
|
DisplayModeSetting.LIST -> {
|
||||||
AnimeSourceListHolder(view, adapter)
|
AnimeSourceListHolder(view, adapter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package eu.kanade.tachiyomi.ui.browse.animesource.browse
|
package eu.kanade.tachiyomi.ui.browse.animesource.browse
|
||||||
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import androidx.core.view.isVisible
|
||||||
import coil.clear
|
import coil.clear
|
||||||
import coil.loadAny
|
import coil.loadAny
|
||||||
import coil.transform.RoundedCornersTransformation
|
import coil.transform.RoundedCornersTransformation
|
||||||
|
@ -40,6 +41,12 @@ class AnimeSourceListHolder(private val view: View, adapter: FlexibleAdapter<*>)
|
||||||
// Set alpha of thumbnail.
|
// Set alpha of thumbnail.
|
||||||
binding.thumbnail.alpha = if (anime.favorite) 0.3f else 1.0f
|
binding.thumbnail.alpha = if (anime.favorite) 0.3f else 1.0f
|
||||||
|
|
||||||
|
// For rounded corners
|
||||||
|
binding.badges.clipToOutline = true
|
||||||
|
|
||||||
|
// Set favorite badge
|
||||||
|
binding.favoriteText.isVisible = anime.favorite
|
||||||
|
|
||||||
setImage(anime)
|
setImage(anime)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,6 @@ import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
|
||||||
import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource
|
import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource
|
||||||
import eu.kanade.tachiyomi.data.database.models.Anime
|
import eu.kanade.tachiyomi.data.database.models.Anime
|
||||||
import eu.kanade.tachiyomi.data.database.models.Category
|
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.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.data.preference.asImmediateFlow
|
import eu.kanade.tachiyomi.data.preference.asImmediateFlow
|
||||||
import eu.kanade.tachiyomi.databinding.SourceControllerBinding
|
import eu.kanade.tachiyomi.databinding.SourceControllerBinding
|
||||||
|
@ -38,6 +37,7 @@ import eu.kanade.tachiyomi.ui.base.controller.FabController
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.SearchableNucleusController
|
import eu.kanade.tachiyomi.ui.base.controller.SearchableNucleusController
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||||
import eu.kanade.tachiyomi.ui.browse.animesource.globalsearch.GlobalAnimeSearchController
|
import eu.kanade.tachiyomi.ui.browse.animesource.globalsearch.GlobalAnimeSearchController
|
||||||
|
import eu.kanade.tachiyomi.ui.library.setting.DisplayModeSetting
|
||||||
import eu.kanade.tachiyomi.ui.main.MainActivity
|
import eu.kanade.tachiyomi.ui.main.MainActivity
|
||||||
import eu.kanade.tachiyomi.ui.more.MoreController
|
import eu.kanade.tachiyomi.ui.more.MoreController
|
||||||
import eu.kanade.tachiyomi.ui.webview.WebViewActivityAnime
|
import eu.kanade.tachiyomi.ui.webview.WebViewActivityAnime
|
||||||
|
@ -205,7 +205,7 @@ open class BrowseAnimeSourceController(bundle: Bundle) :
|
||||||
binding.catalogueView.removeView(oldRecycler)
|
binding.catalogueView.removeView(oldRecycler)
|
||||||
}
|
}
|
||||||
|
|
||||||
val recycler = if (preferences.sourceDisplayMode().get() == DisplayMode.LIST) {
|
val recycler = if (preferences.sourceDisplayMode().get() == DisplayModeSetting.LIST) {
|
||||||
RecyclerView(view.context).apply {
|
RecyclerView(view.context).apply {
|
||||||
id = R.id.recycler
|
id = R.id.recycler
|
||||||
layoutManager = LinearLayoutManager(context)
|
layoutManager = LinearLayoutManager(context)
|
||||||
|
@ -273,9 +273,9 @@ open class BrowseAnimeSourceController(bundle: Bundle) :
|
||||||
)
|
)
|
||||||
|
|
||||||
val displayItem = when (preferences.sourceDisplayMode().get()) {
|
val displayItem = when (preferences.sourceDisplayMode().get()) {
|
||||||
DisplayMode.COMPACT_GRID -> R.id.action_compact_grid
|
DisplayModeSetting.COMPACT_GRID -> R.id.action_compact_grid
|
||||||
DisplayMode.COMFORTABLE_GRID -> R.id.action_comfortable_grid
|
DisplayModeSetting.COMFORTABLE_GRID -> R.id.action_comfortable_grid
|
||||||
DisplayMode.LIST -> R.id.action_list
|
DisplayModeSetting.LIST -> R.id.action_list
|
||||||
}
|
}
|
||||||
menu.findItem(displayItem).isChecked = true
|
menu.findItem(displayItem).isChecked = true
|
||||||
}
|
}
|
||||||
|
@ -297,9 +297,9 @@ open class BrowseAnimeSourceController(bundle: Bundle) :
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
when (item.itemId) {
|
when (item.itemId) {
|
||||||
R.id.action_search -> expandActionViewFromInteraction = true
|
R.id.action_search -> expandActionViewFromInteraction = true
|
||||||
R.id.action_compact_grid -> setDisplayMode(DisplayMode.COMPACT_GRID)
|
R.id.action_compact_grid -> setDisplayMode(DisplayModeSetting.COMPACT_GRID)
|
||||||
R.id.action_comfortable_grid -> setDisplayMode(DisplayMode.COMFORTABLE_GRID)
|
R.id.action_comfortable_grid -> setDisplayMode(DisplayModeSetting.COMFORTABLE_GRID)
|
||||||
R.id.action_list -> setDisplayMode(DisplayMode.LIST)
|
R.id.action_list -> setDisplayMode(DisplayModeSetting.LIST)
|
||||||
R.id.action_open_in_web_view -> openInWebView()
|
R.id.action_open_in_web_view -> openInWebView()
|
||||||
R.id.action_local_source_help -> openLocalSourceHelpGuide()
|
R.id.action_local_source_help -> openLocalSourceHelpGuide()
|
||||||
}
|
}
|
||||||
|
@ -446,7 +446,7 @@ open class BrowseAnimeSourceController(bundle: Bundle) :
|
||||||
*
|
*
|
||||||
* @param mode the mode to change to
|
* @param mode the mode to change to
|
||||||
*/
|
*/
|
||||||
private fun setDisplayMode(mode: DisplayMode) {
|
private fun setDisplayMode(mode: DisplayModeSetting) {
|
||||||
val view = view ?: return
|
val view = view ?: return
|
||||||
val adapter = adapter ?: return
|
val adapter = adapter ?: return
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package eu.kanade.tachiyomi.ui.browse.animesource.globalsearch
|
package eu.kanade.tachiyomi.ui.browse.animesource.globalsearch
|
||||||
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import androidx.core.view.isVisible
|
||||||
import coil.clear
|
import coil.clear
|
||||||
import coil.imageLoader
|
import coil.imageLoader
|
||||||
import coil.request.ImageRequest
|
import coil.request.ImageRequest
|
||||||
|
@ -36,10 +37,18 @@ class GlobalAnimeSearchCardHolder(view: View, adapter: GlobalAnimeSearchCardAdap
|
||||||
fun bind(anime: Anime) {
|
fun bind(anime: Anime) {
|
||||||
binding.card.clipToOutline = true
|
binding.card.clipToOutline = true
|
||||||
|
|
||||||
|
// Set anime title
|
||||||
binding.title.text = anime.title
|
binding.title.text = anime.title
|
||||||
|
|
||||||
// Set alpha of anime_thumbnail.
|
// Set alpha of anime_thumbnail.
|
||||||
binding.cover.alpha = if (anime.favorite) 0.3f else 1.0f
|
binding.cover.alpha = if (anime.favorite) 0.3f else 1.0f
|
||||||
|
|
||||||
|
// For rounded corners
|
||||||
|
binding.badges.clipToOutline = true
|
||||||
|
|
||||||
|
// Set favorite badge
|
||||||
|
binding.favoriteText.isVisible = anime.favorite
|
||||||
|
|
||||||
setImage(anime)
|
setImage(anime)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,6 @@ import eu.davidea.flexibleadapter.items.IFlexible
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.models.Category
|
import eu.kanade.tachiyomi.data.database.models.Category
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
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.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.data.preference.asImmediateFlow
|
import eu.kanade.tachiyomi.data.preference.asImmediateFlow
|
||||||
import eu.kanade.tachiyomi.databinding.SourceControllerBinding
|
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.base.controller.withFadeTransaction
|
||||||
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchController
|
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchController
|
||||||
import eu.kanade.tachiyomi.ui.library.ChangeMangaCategoriesDialog
|
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.main.MainActivity
|
||||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||||
import eu.kanade.tachiyomi.ui.more.MoreController
|
import eu.kanade.tachiyomi.ui.more.MoreController
|
||||||
|
@ -205,7 +205,7 @@ open class BrowseSourceController(bundle: Bundle) :
|
||||||
binding.catalogueView.removeView(oldRecycler)
|
binding.catalogueView.removeView(oldRecycler)
|
||||||
}
|
}
|
||||||
|
|
||||||
val recycler = if (preferences.sourceDisplayMode().get() == DisplayMode.LIST) {
|
val recycler = if (preferences.sourceDisplayMode().get() == DisplayModeSetting.LIST) {
|
||||||
RecyclerView(view.context).apply {
|
RecyclerView(view.context).apply {
|
||||||
id = R.id.recycler
|
id = R.id.recycler
|
||||||
layoutManager = LinearLayoutManager(context)
|
layoutManager = LinearLayoutManager(context)
|
||||||
|
@ -273,9 +273,9 @@ open class BrowseSourceController(bundle: Bundle) :
|
||||||
)
|
)
|
||||||
|
|
||||||
val displayItem = when (preferences.sourceDisplayMode().get()) {
|
val displayItem = when (preferences.sourceDisplayMode().get()) {
|
||||||
DisplayMode.COMPACT_GRID -> R.id.action_compact_grid
|
DisplayModeSetting.COMPACT_GRID -> R.id.action_compact_grid
|
||||||
DisplayMode.COMFORTABLE_GRID -> R.id.action_comfortable_grid
|
DisplayModeSetting.COMFORTABLE_GRID -> R.id.action_comfortable_grid
|
||||||
DisplayMode.LIST -> R.id.action_list
|
DisplayModeSetting.LIST -> R.id.action_list
|
||||||
}
|
}
|
||||||
menu.findItem(displayItem).isChecked = true
|
menu.findItem(displayItem).isChecked = true
|
||||||
}
|
}
|
||||||
|
@ -297,9 +297,9 @@ open class BrowseSourceController(bundle: Bundle) :
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
when (item.itemId) {
|
when (item.itemId) {
|
||||||
R.id.action_search -> expandActionViewFromInteraction = true
|
R.id.action_search -> expandActionViewFromInteraction = true
|
||||||
R.id.action_compact_grid -> setDisplayMode(DisplayMode.COMPACT_GRID)
|
R.id.action_compact_grid -> setDisplayMode(DisplayModeSetting.COMPACT_GRID)
|
||||||
R.id.action_comfortable_grid -> setDisplayMode(DisplayMode.COMFORTABLE_GRID)
|
R.id.action_comfortable_grid -> setDisplayMode(DisplayModeSetting.COMFORTABLE_GRID)
|
||||||
R.id.action_list -> setDisplayMode(DisplayMode.LIST)
|
R.id.action_list -> setDisplayMode(DisplayModeSetting.LIST)
|
||||||
R.id.action_open_in_web_view -> openInWebView()
|
R.id.action_open_in_web_view -> openInWebView()
|
||||||
R.id.action_local_source_help -> openLocalSourceHelpGuide()
|
R.id.action_local_source_help -> openLocalSourceHelpGuide()
|
||||||
}
|
}
|
||||||
|
@ -446,7 +446,7 @@ open class BrowseSourceController(bundle: Bundle) :
|
||||||
*
|
*
|
||||||
* @param mode the mode to change to
|
* @param mode the mode to change to
|
||||||
*/
|
*/
|
||||||
private fun setDisplayMode(mode: DisplayMode) {
|
private fun setDisplayMode(mode: DisplayModeSetting) {
|
||||||
val view = view ?: return
|
val view = view ?: return
|
||||||
val adapter = adapter ?: return
|
val adapter = adapter ?: return
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package eu.kanade.tachiyomi.ui.browse.source.browse
|
package eu.kanade.tachiyomi.ui.browse.source.browse
|
||||||
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import androidx.core.view.isVisible
|
||||||
import coil.clear
|
import coil.clear
|
||||||
import coil.imageLoader
|
import coil.imageLoader
|
||||||
import coil.request.ImageRequest
|
import coil.request.ImageRequest
|
||||||
|
@ -37,6 +38,12 @@ class SourceComfortableGridHolder(private val view: View, private val adapter: F
|
||||||
// Set alpha of anime_thumbnail.
|
// Set alpha of anime_thumbnail.
|
||||||
binding.thumbnail.alpha = if (manga.favorite) 0.3f else 1.0f
|
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)
|
setImage(manga)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package eu.kanade.tachiyomi.ui.browse.source.browse
|
package eu.kanade.tachiyomi.ui.browse.source.browse
|
||||||
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import androidx.core.view.isVisible
|
||||||
import coil.clear
|
import coil.clear
|
||||||
import coil.imageLoader
|
import coil.imageLoader
|
||||||
import coil.request.ImageRequest
|
import coil.request.ImageRequest
|
||||||
|
@ -37,6 +38,12 @@ open class SourceGridHolder(private val view: View, private val adapter: Flexibl
|
||||||
// Set alpha of anime_thumbnail.
|
// Set alpha of anime_thumbnail.
|
||||||
binding.thumbnail.alpha = if (manga.favorite) 0.3f else 1.0f
|
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)
|
setImage(manga)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,19 +12,19 @@ import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
import eu.davidea.flexibleadapter.items.IFlexible
|
import eu.davidea.flexibleadapter.items.IFlexible
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
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.SourceComfortableGridItemBinding
|
||||||
import eu.kanade.tachiyomi.databinding.SourceCompactGridItemBinding
|
import eu.kanade.tachiyomi.databinding.SourceCompactGridItemBinding
|
||||||
|
import eu.kanade.tachiyomi.ui.library.setting.DisplayModeSetting
|
||||||
import eu.kanade.tachiyomi.widget.AutofitRecyclerView
|
import eu.kanade.tachiyomi.widget.AutofitRecyclerView
|
||||||
|
|
||||||
class SourceItem(val manga: Manga, private val displayMode: Preference<DisplayMode>) :
|
class SourceItem(val manga: Manga, private val displayMode: Preference<DisplayModeSetting>) :
|
||||||
AbstractFlexibleItem<SourceHolder<*>>() {
|
AbstractFlexibleItem<SourceHolder<*>>() {
|
||||||
|
|
||||||
override fun getLayoutRes(): Int {
|
override fun getLayoutRes(): Int {
|
||||||
return when (displayMode.get()) {
|
return when (displayMode.get()) {
|
||||||
DisplayMode.COMPACT_GRID -> R.layout.source_compact_grid_item
|
DisplayModeSetting.COMPACT_GRID -> R.layout.source_compact_grid_item
|
||||||
DisplayMode.COMFORTABLE_GRID -> R.layout.source_comfortable_grid_item
|
DisplayModeSetting.COMFORTABLE_GRID -> R.layout.source_comfortable_grid_item
|
||||||
DisplayMode.LIST -> R.layout.source_list_item
|
DisplayModeSetting.LIST -> R.layout.source_list_item
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ class SourceItem(val manga: Manga, private val displayMode: Preference<DisplayMo
|
||||||
adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>
|
adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>
|
||||||
): SourceHolder<*> {
|
): SourceHolder<*> {
|
||||||
return when (displayMode.get()) {
|
return when (displayMode.get()) {
|
||||||
DisplayMode.COMPACT_GRID -> {
|
DisplayModeSetting.COMPACT_GRID -> {
|
||||||
val binding = SourceCompactGridItemBinding.bind(view)
|
val binding = SourceCompactGridItemBinding.bind(view)
|
||||||
val parent = adapter.recyclerView as AutofitRecyclerView
|
val parent = adapter.recyclerView as AutofitRecyclerView
|
||||||
val coverHeight = parent.itemWidth / 3 * 4
|
val coverHeight = parent.itemWidth / 3 * 4
|
||||||
|
@ -50,7 +50,7 @@ class SourceItem(val manga: Manga, private val displayMode: Preference<DisplayMo
|
||||||
}
|
}
|
||||||
SourceGridHolder(view, adapter)
|
SourceGridHolder(view, adapter)
|
||||||
}
|
}
|
||||||
DisplayMode.COMFORTABLE_GRID -> {
|
DisplayModeSetting.COMFORTABLE_GRID -> {
|
||||||
val binding = SourceComfortableGridItemBinding.bind(view)
|
val binding = SourceComfortableGridItemBinding.bind(view)
|
||||||
val parent = adapter.recyclerView as AutofitRecyclerView
|
val parent = adapter.recyclerView as AutofitRecyclerView
|
||||||
val coverHeight = parent.itemWidth / 3 * 4
|
val coverHeight = parent.itemWidth / 3 * 4
|
||||||
|
@ -62,7 +62,7 @@ class SourceItem(val manga: Manga, private val displayMode: Preference<DisplayMo
|
||||||
}
|
}
|
||||||
SourceComfortableGridHolder(view, adapter)
|
SourceComfortableGridHolder(view, adapter)
|
||||||
}
|
}
|
||||||
DisplayMode.LIST -> {
|
DisplayModeSetting.LIST -> {
|
||||||
SourceListHolder(view, adapter)
|
SourceListHolder(view, adapter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package eu.kanade.tachiyomi.ui.browse.source.browse
|
package eu.kanade.tachiyomi.ui.browse.source.browse
|
||||||
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import androidx.core.view.isVisible
|
||||||
import coil.clear
|
import coil.clear
|
||||||
import coil.loadAny
|
import coil.loadAny
|
||||||
import coil.transform.RoundedCornersTransformation
|
import coil.transform.RoundedCornersTransformation
|
||||||
|
@ -40,6 +41,12 @@ class SourceListHolder(private val view: View, adapter: FlexibleAdapter<*>) :
|
||||||
// Set alpha of anime_thumbnail.
|
// Set alpha of anime_thumbnail.
|
||||||
binding.thumbnail.alpha = if (manga.favorite) 0.3f else 1.0f
|
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)
|
setImage(manga)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package eu.kanade.tachiyomi.ui.browse.source.globalsearch
|
package eu.kanade.tachiyomi.ui.browse.source.globalsearch
|
||||||
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import androidx.core.view.isVisible
|
||||||
import coil.clear
|
import coil.clear
|
||||||
import coil.imageLoader
|
import coil.imageLoader
|
||||||
import coil.request.ImageRequest
|
import coil.request.ImageRequest
|
||||||
|
@ -36,10 +37,18 @@ class GlobalSearchCardHolder(view: View, adapter: GlobalSearchCardAdapter) :
|
||||||
fun bind(manga: Manga) {
|
fun bind(manga: Manga) {
|
||||||
binding.card.clipToOutline = true
|
binding.card.clipToOutline = true
|
||||||
|
|
||||||
|
// Set manga title
|
||||||
binding.title.text = manga.title
|
binding.title.text = manga.title
|
||||||
// Set alpha of anime_thumbnail.
|
|
||||||
|
// Set alpha of thumbnail.
|
||||||
binding.cover.alpha = if (manga.favorite) 0.3f else 1.0f
|
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)
|
setImage(manga)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,6 @@ import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.models.Category
|
import eu.kanade.tachiyomi.data.database.models.Category
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
import eu.kanade.tachiyomi.data.library.LibraryUpdateService
|
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.data.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.databinding.LibraryCategoryBinding
|
import eu.kanade.tachiyomi.databinding.LibraryCategoryBinding
|
||||||
import eu.kanade.tachiyomi.util.lang.plusAssign
|
import eu.kanade.tachiyomi.util.lang.plusAssign
|
||||||
|
@ -28,6 +27,7 @@ import reactivecircus.flowbinding.swiperefreshlayout.refreshes
|
||||||
import rx.subscriptions.CompositeSubscription
|
import rx.subscriptions.CompositeSubscription
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.util.ArrayDeque
|
import java.util.ArrayDeque
|
||||||
|
import eu.kanade.tachiyomi.ui.library.setting.DisplayModeSetting as DisplayMode
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fragment containing the library manga for a certain category.
|
* 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 displayMode should be set from category adjust manga count per row
|
||||||
if (preferences.categorisedDisplaySettings().get()) {
|
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
|
1
|
||||||
} else {
|
} else {
|
||||||
controller.mangaPerRow
|
controller.mangaPerRow
|
||||||
|
|
|
@ -295,6 +295,11 @@ class LibraryController(
|
||||||
.map { (it.id ?: -1) to (mangaMap[it.id]?.size ?: 0) }
|
.map { (it.id ?: -1) to (mangaMap[it.id]?.size ?: 0) }
|
||||||
.toMap()
|
.toMap()
|
||||||
|
|
||||||
|
if (preferences.categorisedDisplaySettings().get()) {
|
||||||
|
// Reattach adapter so it doesn't get de-synced
|
||||||
|
reattachAdapter()
|
||||||
|
}
|
||||||
|
|
||||||
// Restore active category.
|
// Restore active category.
|
||||||
binding.libraryPager.setCurrentItem(activeCat, false)
|
binding.libraryPager.setCurrentItem(activeCat, false)
|
||||||
|
|
||||||
|
|
|
@ -13,10 +13,10 @@ import eu.davidea.flexibleadapter.items.IFilterable
|
||||||
import eu.davidea.flexibleadapter.items.IFlexible
|
import eu.davidea.flexibleadapter.items.IFlexible
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.models.LibraryManga
|
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.SourceComfortableGridItemBinding
|
||||||
import eu.kanade.tachiyomi.databinding.SourceCompactGridItemBinding
|
import eu.kanade.tachiyomi.databinding.SourceCompactGridItemBinding
|
||||||
import eu.kanade.tachiyomi.source.SourceManager
|
import eu.kanade.tachiyomi.source.SourceManager
|
||||||
|
import eu.kanade.tachiyomi.ui.library.setting.DisplayModeSetting
|
||||||
import eu.kanade.tachiyomi.widget.AutofitRecyclerView
|
import eu.kanade.tachiyomi.widget.AutofitRecyclerView
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
|
@ -24,7 +24,7 @@ import uy.kohesive.injekt.api.get
|
||||||
class LibraryItem(
|
class LibraryItem(
|
||||||
val manga: LibraryManga,
|
val manga: LibraryManga,
|
||||||
private val shouldSetFromCategory: Preference<Boolean>,
|
private val shouldSetFromCategory: Preference<Boolean>,
|
||||||
private val defaultLibraryDisplayMode: Preference<DisplayMode>
|
private val defaultLibraryDisplayMode: Preference<DisplayModeSetting>
|
||||||
) :
|
) :
|
||||||
AbstractFlexibleItem<LibraryHolder<*>>(), IFilterable<String> {
|
AbstractFlexibleItem<LibraryHolder<*>>(), IFilterable<String> {
|
||||||
|
|
||||||
|
@ -35,13 +35,9 @@ class LibraryItem(
|
||||||
var unreadCount = -1
|
var unreadCount = -1
|
||||||
var isLocal = false
|
var isLocal = false
|
||||||
|
|
||||||
private fun getDisplayMode(): DisplayMode {
|
private fun getDisplayMode(): DisplayModeSetting {
|
||||||
return if (shouldSetFromCategory.get() && manga.category != 0) {
|
return if (shouldSetFromCategory.get() && manga.category != 0) {
|
||||||
if (displayMode != -1) {
|
DisplayModeSetting.fromFlag(displayMode)
|
||||||
DisplayMode.values()[displayMode]
|
|
||||||
} else {
|
|
||||||
DisplayMode.COMPACT_GRID
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
defaultLibraryDisplayMode.get()
|
defaultLibraryDisplayMode.get()
|
||||||
}
|
}
|
||||||
|
@ -49,15 +45,15 @@ class LibraryItem(
|
||||||
|
|
||||||
override fun getLayoutRes(): Int {
|
override fun getLayoutRes(): Int {
|
||||||
return when (getDisplayMode()) {
|
return when (getDisplayMode()) {
|
||||||
DisplayMode.COMPACT_GRID -> R.layout.source_compact_grid_item
|
DisplayModeSetting.COMPACT_GRID -> R.layout.source_compact_grid_item
|
||||||
DisplayMode.COMFORTABLE_GRID -> R.layout.source_comfortable_grid_item
|
DisplayModeSetting.COMFORTABLE_GRID -> R.layout.source_comfortable_grid_item
|
||||||
DisplayMode.LIST -> R.layout.source_list_item
|
DisplayModeSetting.LIST -> R.layout.source_list_item
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): LibraryHolder<*> {
|
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): LibraryHolder<*> {
|
||||||
return when (getDisplayMode()) {
|
return when (getDisplayMode()) {
|
||||||
DisplayMode.COMPACT_GRID -> {
|
DisplayModeSetting.COMPACT_GRID -> {
|
||||||
val binding = SourceCompactGridItemBinding.bind(view)
|
val binding = SourceCompactGridItemBinding.bind(view)
|
||||||
val parent = adapter.recyclerView as AutofitRecyclerView
|
val parent = adapter.recyclerView as AutofitRecyclerView
|
||||||
val coverHeight = parent.itemWidth / 3 * 4
|
val coverHeight = parent.itemWidth / 3 * 4
|
||||||
|
@ -71,7 +67,7 @@ class LibraryItem(
|
||||||
}
|
}
|
||||||
LibraryCompactGridHolder(view, adapter)
|
LibraryCompactGridHolder(view, adapter)
|
||||||
}
|
}
|
||||||
DisplayMode.COMFORTABLE_GRID -> {
|
DisplayModeSetting.COMFORTABLE_GRID -> {
|
||||||
val binding = SourceComfortableGridItemBinding.bind(view)
|
val binding = SourceComfortableGridItemBinding.bind(view)
|
||||||
val parent = adapter.recyclerView as AutofitRecyclerView
|
val parent = adapter.recyclerView as AutofitRecyclerView
|
||||||
val coverHeight = parent.itemWidth / 3 * 4
|
val coverHeight = parent.itemWidth / 3 * 4
|
||||||
|
@ -83,7 +79,7 @@ class LibraryItem(
|
||||||
}
|
}
|
||||||
LibraryComfortableGridHolder(view, adapter)
|
LibraryComfortableGridHolder(view, adapter)
|
||||||
}
|
}
|
||||||
DisplayMode.LIST -> {
|
DisplayModeSetting.LIST -> {
|
||||||
LibraryListHolder(view, adapter)
|
LibraryListHolder(view, adapter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,8 @@ import eu.kanade.tachiyomi.source.SourceManager
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||||
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
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.isLocal
|
||||||
import eu.kanade.tachiyomi.util.lang.combineLatest
|
import eu.kanade.tachiyomi.util.lang.combineLatest
|
||||||
import eu.kanade.tachiyomi.util.lang.isNullOrUnsubscribed
|
import eu.kanade.tachiyomi.util.lang.isNullOrUnsubscribed
|
||||||
|
@ -98,7 +100,7 @@ class LibraryPresenter(
|
||||||
lib.copy(mangaMap = applyFilters(lib.mangaMap, tracks))
|
lib.copy(mangaMap = applyFilters(lib.mangaMap, tracks))
|
||||||
}
|
}
|
||||||
.combineLatest(sortTriggerRelay.observeOn(Schedulers.io())) { lib, _ ->
|
.combineLatest(sortTriggerRelay.observeOn(Schedulers.io())) { lib, _ ->
|
||||||
lib.copy(mangaMap = applySort(lib.mangaMap))
|
lib.copy(mangaMap = applySort(lib.categories, lib.mangaMap))
|
||||||
}
|
}
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribeLatestCache({ view, (categories, mangaMap) ->
|
.subscribeLatestCache({ view, (categories, mangaMap) ->
|
||||||
|
@ -228,9 +230,7 @@ class LibraryPresenter(
|
||||||
*
|
*
|
||||||
* @param map the map to sort.
|
* @param map the map to sort.
|
||||||
*/
|
*/
|
||||||
private fun applySort(map: LibraryMap): LibraryMap {
|
private fun applySort(categories: List<Category>, map: LibraryMap): LibraryMap {
|
||||||
val sortingMode = preferences.librarySortingMode().get()
|
|
||||||
|
|
||||||
val lastReadManga by lazy {
|
val lastReadManga by lazy {
|
||||||
var counter = 0
|
var counter = 0
|
||||||
db.getLastReadManga().executeAsBlocking().associate { it.id!! to counter++ }
|
db.getLastReadManga().executeAsBlocking().associate { it.id!! to counter++ }
|
||||||
|
@ -248,55 +248,67 @@ class LibraryPresenter(
|
||||||
db.getChapterFetchDateManga().executeAsBlocking().associate { it.id!! to counter++ }
|
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 sortFn: (LibraryItem, LibraryItem) -> Int = { i1, i2 ->
|
||||||
|
val sortingMode = sortingModes[i1.manga.category]!!
|
||||||
|
val sortAscending = sortAscending[i1.manga.category]!! == SortDirectionSetting.ASCENDING
|
||||||
when (sortingMode) {
|
when (sortingMode) {
|
||||||
LibrarySort.ALPHA -> i1.manga.title.compareTo(i2.manga.title, true)
|
SortModeSetting.ALPHABETICAL -> i1.manga.title.compareTo(i2.manga.title, true)
|
||||||
LibrarySort.LAST_READ -> {
|
SortModeSetting.LAST_READ -> {
|
||||||
// Get index of manga, set equal to list if size unknown.
|
// Get index of manga, set equal to list if size unknown.
|
||||||
val manga1LastRead = lastReadManga[i1.manga.id!!] ?: lastReadManga.size
|
val manga1LastRead = lastReadManga[i1.manga.id!!] ?: lastReadManga.size
|
||||||
val manga2LastRead = lastReadManga[i2.manga.id!!] ?: lastReadManga.size
|
val manga2LastRead = lastReadManga[i2.manga.id!!] ?: lastReadManga.size
|
||||||
manga1LastRead.compareTo(manga2LastRead)
|
manga1LastRead.compareTo(manga2LastRead)
|
||||||
}
|
}
|
||||||
LibrarySort.LAST_CHECKED -> i2.manga.last_update.compareTo(i1.manga.last_update)
|
SortModeSetting.LAST_CHECKED -> i2.manga.last_update.compareTo(i1.manga.last_update)
|
||||||
LibrarySort.UNREAD -> when {
|
SortModeSetting.UNREAD -> when {
|
||||||
// Ensure unread content comes first
|
// Ensure unread content comes first
|
||||||
i1.manga.unread == i2.manga.unread -> 0
|
i1.manga.unread == i2.manga.unread -> 0
|
||||||
i1.manga.unread == 0 -> if (sortAscending) 1 else -1
|
i1.manga.unread == 0 -> if (sortAscending) 1 else -1
|
||||||
i2.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)
|
else -> i1.manga.unread.compareTo(i2.manga.unread)
|
||||||
}
|
}
|
||||||
LibrarySort.TOTAL -> {
|
SortModeSetting.TOTAL_CHAPTERS -> {
|
||||||
val manga1TotalChapter = totalChapterManga[i1.manga.id!!] ?: 0
|
val manga1TotalChapter = totalChapterManga[i1.manga.id!!] ?: 0
|
||||||
val mange2TotalChapter = totalChapterManga[i2.manga.id!!] ?: 0
|
val mange2TotalChapter = totalChapterManga[i2.manga.id!!] ?: 0
|
||||||
manga1TotalChapter.compareTo(mange2TotalChapter)
|
manga1TotalChapter.compareTo(mange2TotalChapter)
|
||||||
}
|
}
|
||||||
LibrarySort.LATEST_CHAPTER -> {
|
SortModeSetting.LATEST_CHAPTER -> {
|
||||||
val manga1latestChapter = latestChapterManga[i1.manga.id!!]
|
val manga1latestChapter = latestChapterManga[i1.manga.id!!]
|
||||||
?: latestChapterManga.size
|
?: latestChapterManga.size
|
||||||
val manga2latestChapter = latestChapterManga[i2.manga.id!!]
|
val manga2latestChapter = latestChapterManga[i2.manga.id!!]
|
||||||
?: latestChapterManga.size
|
?: latestChapterManga.size
|
||||||
manga1latestChapter.compareTo(manga2latestChapter)
|
manga1latestChapter.compareTo(manga2latestChapter)
|
||||||
}
|
}
|
||||||
LibrarySort.CHAPTER_FETCH_DATE -> {
|
SortModeSetting.DATE_FETCHED -> {
|
||||||
val manga1chapterFetchDate = chapterFetchDateManga[i1.manga.id!!]
|
val manga1chapterFetchDate = chapterFetchDateManga[i1.manga.id!!]
|
||||||
?: chapterFetchDateManga.size
|
?: chapterFetchDateManga.size
|
||||||
val manga2chapterFetchDate = chapterFetchDateManga[i2.manga.id!!]
|
val manga2chapterFetchDate = chapterFetchDateManga[i2.manga.id!!]
|
||||||
?: chapterFetchDateManga.size
|
?: chapterFetchDateManga.size
|
||||||
manga1chapterFetchDate.compareTo(manga2chapterFetchDate)
|
manga1chapterFetchDate.compareTo(manga2chapterFetchDate)
|
||||||
}
|
}
|
||||||
LibrarySort.DATE_ADDED -> i2.manga.date_added.compareTo(i1.manga.date_added)
|
SortModeSetting.DATE_ADDED -> i2.manga.date_added.compareTo(i1.manga.date_added)
|
||||||
else -> throw Exception("Unknown sorting mode")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val comparator = if (sortAscending) {
|
return map.mapValues { entry ->
|
||||||
Comparator(sortFn)
|
val sortAscending = sortAscending[entry.key]!! == SortDirectionSetting.ASCENDING
|
||||||
} else {
|
|
||||||
Collections.reverseOrder(sortFn)
|
|
||||||
}
|
|
||||||
|
|
||||||
return map.mapValues { entry -> entry.value.sortedWith(comparator) }
|
val comparator = if (sortAscending) {
|
||||||
|
Comparator(sortFn)
|
||||||
|
} else {
|
||||||
|
Collections.reverseOrder(sortFn)
|
||||||
|
}
|
||||||
|
|
||||||
|
entry.value.sortedWith(comparator)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -7,10 +7,12 @@ import com.bluelinelabs.conductor.Router
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||||
import eu.kanade.tachiyomi.data.database.models.Category
|
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.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.data.track.TrackManager
|
import eu.kanade.tachiyomi.data.track.TrackManager
|
||||||
import eu.kanade.tachiyomi.data.track.TrackService
|
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
|
||||||
import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.TriStateGroup.State
|
import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.TriStateGroup.State
|
||||||
import eu.kanade.tachiyomi.widget.sheet.TabbedBottomSheetDialog
|
import eu.kanade.tachiyomi.widget.sheet.TabbedBottomSheetDialog
|
||||||
|
@ -45,6 +47,8 @@ class LibrarySettingsSheet(
|
||||||
* @param currentCategory ID of currently shown category
|
* @param currentCategory ID of currently shown category
|
||||||
*/
|
*/
|
||||||
fun show(currentCategory: Category) {
|
fun show(currentCategory: Category) {
|
||||||
|
sort.currentCategory = currentCategory
|
||||||
|
sort.adjustDisplaySelection()
|
||||||
display.currentCategory = currentCategory
|
display.currentCategory = currentCategory
|
||||||
display.adjustDisplaySelection()
|
display.adjustDisplaySelection()
|
||||||
super.show()
|
super.show()
|
||||||
|
@ -158,8 +162,16 @@ class LibrarySettingsSheet(
|
||||||
inner class Sort @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
|
inner class Sort @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
|
||||||
Settings(context, attrs) {
|
Settings(context, attrs) {
|
||||||
|
|
||||||
|
private val sort = SortGroup()
|
||||||
|
|
||||||
init {
|
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 {
|
inner class SortGroup : Group {
|
||||||
|
@ -179,29 +191,29 @@ class LibrarySettingsSheet(
|
||||||
override val footer = null
|
override val footer = null
|
||||||
|
|
||||||
override fun initModels() {
|
override fun initModels() {
|
||||||
val sorting = preferences.librarySortingMode().get()
|
val sorting = SortModeSetting.get(preferences, currentCategory)
|
||||||
val order = if (preferences.librarySortingAscending().get()) {
|
val order = if (SortDirectionSetting.get(preferences, currentCategory) == SortDirectionSetting.ASCENDING) {
|
||||||
Item.MultiSort.SORT_ASC
|
Item.MultiSort.SORT_ASC
|
||||||
} else {
|
} else {
|
||||||
Item.MultiSort.SORT_DESC
|
Item.MultiSort.SORT_DESC
|
||||||
}
|
}
|
||||||
|
|
||||||
alphabetically.state =
|
alphabetically.state =
|
||||||
if (sorting == LibrarySort.ALPHA) order else Item.MultiSort.SORT_NONE
|
if (sorting == SortModeSetting.ALPHABETICAL) order else Item.MultiSort.SORT_NONE
|
||||||
lastRead.state =
|
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 =
|
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 =
|
unread.state =
|
||||||
if (sorting == LibrarySort.UNREAD) order else Item.MultiSort.SORT_NONE
|
if (sorting == SortModeSetting.UNREAD) order else Item.MultiSort.SORT_NONE
|
||||||
total.state =
|
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 =
|
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 =
|
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 =
|
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) {
|
override fun onItemClicked(item: Item) {
|
||||||
|
@ -219,23 +231,50 @@ class LibrarySettingsSheet(
|
||||||
else -> throw Exception("Unknown state")
|
else -> throw Exception("Unknown state")
|
||||||
}
|
}
|
||||||
|
|
||||||
preferences.librarySortingMode().set(
|
setSortModePreference(item)
|
||||||
when (item) {
|
|
||||||
alphabetically -> LibrarySort.ALPHA
|
setSortDirectionPrefernece(item)
|
||||||
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)
|
|
||||||
|
|
||||||
item.group.items.forEach { adapter.notifyItemChanged(it) }
|
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
|
// 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) {
|
return if (preferences.categorisedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0) {
|
||||||
DisplayMode.values()[currentCategory?.displayMode ?: 0]
|
DisplayModeSetting.fromFlag(currentCategory?.displayMode)
|
||||||
} else {
|
} else {
|
||||||
preferences.libraryDisplayMode().get()
|
preferences.libraryDisplayMode().get()
|
||||||
}
|
}
|
||||||
|
@ -300,33 +339,26 @@ class LibrarySettingsSheet(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets display group selections based on given mode
|
// Sets display group selections based on given mode
|
||||||
fun setGroupSelections(mode: DisplayMode) {
|
fun setGroupSelections(mode: DisplayModeSetting) {
|
||||||
compactGrid.checked = mode == DisplayMode.COMPACT_GRID
|
compactGrid.checked = mode == DisplayModeSetting.COMPACT_GRID
|
||||||
comfortableGrid.checked = mode == DisplayMode.COMFORTABLE_GRID
|
comfortableGrid.checked = mode == DisplayModeSetting.COMFORTABLE_GRID
|
||||||
list.checked = mode == DisplayMode.LIST
|
list.checked = mode == DisplayModeSetting.LIST
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setDisplayModePreference(item: Item) {
|
private fun setDisplayModePreference(item: Item) {
|
||||||
if (preferences.categorisedDisplaySettings().get() && currentCategory != null && currentCategory?.id != 0) {
|
val flag = when (item) {
|
||||||
val flag = when (item) {
|
compactGrid -> DisplayModeSetting.COMPACT_GRID
|
||||||
compactGrid -> Category.COMPACT_GRID
|
comfortableGrid -> DisplayModeSetting.COMFORTABLE_GRID
|
||||||
comfortableGrid -> Category.COMFORTABLE_GRID
|
list -> DisplayModeSetting.LIST
|
||||||
list -> Category.LIST
|
else -> throw NotImplementedError("Unknown display mode")
|
||||||
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()
|
db.insertCategory(currentCategory!!).executeAsBlocking()
|
||||||
} else {
|
} else {
|
||||||
preferences.libraryDisplayMode().set(
|
preferences.libraryDisplayMode().set(flag)
|
||||||
when (item) {
|
|
||||||
compactGrid -> DisplayMode.COMPACT_GRID
|
|
||||||
comfortableGrid -> DisplayMode.COMFORTABLE_GRID
|
|
||||||
list -> DisplayMode.LIST
|
|
||||||
else -> throw NotImplementedError("Unknown display mode")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package eu.kanade.tachiyomi.ui.library
|
package eu.kanade.tachiyomi.ui.library
|
||||||
|
|
||||||
|
@Deprecated("Deprecated in favor for SortModeSetting")
|
||||||
object LibrarySort {
|
object LibrarySort {
|
||||||
|
|
||||||
const val ALPHA = 0
|
const val ALPHA = 0
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -90,6 +90,8 @@ class MainActivity : BaseViewBindingActivity<MainActivityBinding>() {
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
val didMigration = if (savedInstanceState == null) Migrations.upgrade(preferences) else false
|
||||||
|
|
||||||
binding = MainActivityBinding.inflate(layoutInflater)
|
binding = MainActivityBinding.inflate(layoutInflater)
|
||||||
|
|
||||||
// Do not let the launcher create a new activity http://stackoverflow.com/questions/16283079
|
// Do not let the launcher create a new activity http://stackoverflow.com/questions/16283079
|
||||||
|
@ -234,7 +236,7 @@ class MainActivity : BaseViewBindingActivity<MainActivityBinding>() {
|
||||||
preferences.incognitoMode().set(false)
|
preferences.incognitoMode().set(false)
|
||||||
|
|
||||||
// Show changelog prompt on update
|
// Show changelog prompt on update
|
||||||
if (Migrations.upgrade(preferences) && !BuildConfig.DEBUG) {
|
if (didMigration && !BuildConfig.DEBUG) {
|
||||||
WhatsNewDialogController().showDialog(router)
|
WhatsNewDialogController().showDialog(router)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,11 +6,13 @@ import android.app.ProgressDialog
|
||||||
import android.content.ClipData
|
import android.content.ClipData
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.content.res.ColorStateList
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.graphics.ColorMatrix
|
import android.graphics.ColorMatrix
|
||||||
import android.graphics.ColorMatrixColorFilter
|
import android.graphics.ColorMatrixColorFilter
|
||||||
import android.graphics.Paint
|
import android.graphics.Paint
|
||||||
|
import android.graphics.drawable.ColorDrawable
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.KeyEvent
|
import android.view.KeyEvent
|
||||||
|
@ -23,12 +25,14 @@ import android.view.animation.Animation
|
||||||
import android.view.animation.AnimationUtils
|
import android.view.animation.AnimationUtils
|
||||||
import android.widget.SeekBar
|
import android.widget.SeekBar
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.WindowCompat
|
||||||
import androidx.core.view.WindowInsetsCompat
|
import androidx.core.view.WindowInsetsCompat
|
||||||
|
import androidx.core.view.WindowInsetsControllerCompat
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.core.view.setPadding
|
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
|
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.R
|
||||||
import eu.kanade.tachiyomi.data.database.models.Chapter
|
import eu.kanade.tachiyomi.data.database.models.Chapter
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
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.data.preference.toggle
|
||||||
import eu.kanade.tachiyomi.databinding.ReaderActivityBinding
|
import eu.kanade.tachiyomi.databinding.ReaderActivityBinding
|
||||||
import eu.kanade.tachiyomi.ui.base.activity.BaseRxActivity
|
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.main.MainActivity
|
||||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||||
import eu.kanade.tachiyomi.ui.reader.ReaderPresenter.SetAsCoverResult.AddToLibraryFirst
|
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.GLUtil
|
||||||
import eu.kanade.tachiyomi.util.system.hasDisplayCutout
|
import eu.kanade.tachiyomi.util.system.hasDisplayCutout
|
||||||
import eu.kanade.tachiyomi.util.system.toast
|
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.popupMenu
|
||||||
import eu.kanade.tachiyomi.util.view.setTooltip
|
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.SimpleAnimationListener
|
||||||
import eu.kanade.tachiyomi.widget.listener.SimpleSeekBarListener
|
import eu.kanade.tachiyomi.widget.listener.SimpleSeekBarListener
|
||||||
import kotlinx.coroutines.flow.drop
|
import kotlinx.coroutines.flow.drop
|
||||||
|
@ -129,22 +130,20 @@ class ReaderActivity : BaseRxActivity<ReaderActivityBinding, ReaderPresenter>()
|
||||||
|
|
||||||
private var readingModeToast: Toast? = null
|
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.
|
* Called when the activity is created. Initializes the presenter and configuration.
|
||||||
*/
|
*/
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
setTheme(
|
setTheme(BaseThemedActivity.getThemeResourceId(preferences))
|
||||||
when (preferences.readerTheme().get()) {
|
|
||||||
0 -> R.style.Theme_Reader_Light
|
|
||||||
2 -> R.style.Theme_Reader_Dark_Grey
|
|
||||||
else -> R.style.Theme_Reader_Dark
|
|
||||||
}
|
|
||||||
)
|
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
binding = ReaderActivityBinding.inflate(layoutInflater)
|
binding = ReaderActivityBinding.inflate(layoutInflater)
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
|
|
||||||
|
windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
|
||||||
|
|
||||||
if (presenter.needsInit()) {
|
if (presenter.needsInit()) {
|
||||||
val manga = intent.extras!!.getLong("manga", -1)
|
val manga = intent.extras!!.getLong("manga", -1)
|
||||||
val chapter = intent.extras!!.getLong("chapter", -1)
|
val chapter = intent.extras!!.getLong("chapter", -1)
|
||||||
|
@ -163,9 +162,10 @@ class ReaderActivity : BaseRxActivity<ReaderActivityBinding, ReaderPresenter>()
|
||||||
config = ReaderConfig()
|
config = ReaderConfig()
|
||||||
initializeMenu()
|
initializeMenu()
|
||||||
|
|
||||||
// Avoid status bar showing up on rotation
|
binding.pageNumber.applyInsetter {
|
||||||
window.decorView.setOnSystemUiVisibilityChangeListener {
|
type(navigationBars = true) {
|
||||||
setMenuVisibility(menuVisible, animate = false)
|
margin()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finish when incognito mode is disabled
|
// Finish when incognito mode is disabled
|
||||||
|
@ -299,17 +299,15 @@ class ReaderActivity : BaseRxActivity<ReaderActivityBinding, ReaderPresenter>()
|
||||||
onBackPressed()
|
onBackPressed()
|
||||||
}
|
}
|
||||||
|
|
||||||
ViewCompat.setOnApplyWindowInsetsListener(binding.readerMenu) { _, insets ->
|
binding.toolbar.applyInsetter {
|
||||||
if (!window.isDefaultBar()) {
|
type(navigationBars = true, statusBars = true) {
|
||||||
val systemInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars())
|
margin(top = true, horizontal = true)
|
||||||
binding.readerMenu.setPadding(
|
}
|
||||||
systemInsets.left,
|
}
|
||||||
systemInsets.top,
|
binding.readerMenuBottom.applyInsetter {
|
||||||
systemInsets.right,
|
type(navigationBars = true) {
|
||||||
systemInsets.bottom
|
margin(bottom = true, horizontal = true)
|
||||||
)
|
|
||||||
}
|
}
|
||||||
insets
|
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.toolbar.setOnClickListener {
|
binding.toolbar.setOnClickListener {
|
||||||
|
@ -355,6 +353,21 @@ class ReaderActivity : BaseRxActivity<ReaderActivityBinding, ReaderPresenter>()
|
||||||
|
|
||||||
initBottomShortcuts()
|
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
|
// Set initial visibility
|
||||||
setMenuVisibility(menuVisible)
|
setMenuVisibility(menuVisible)
|
||||||
}
|
}
|
||||||
|
@ -475,11 +488,7 @@ class ReaderActivity : BaseRxActivity<ReaderActivityBinding, ReaderPresenter>()
|
||||||
fun setMenuVisibility(visible: Boolean, animate: Boolean = true) {
|
fun setMenuVisibility(visible: Boolean, animate: Boolean = true) {
|
||||||
menuVisible = visible
|
menuVisible = visible
|
||||||
if (visible) {
|
if (visible) {
|
||||||
if (preferences.fullscreen().get()) {
|
windowInsetsController.show(WindowInsetsCompat.Type.systemBars())
|
||||||
window.showBar()
|
|
||||||
} else {
|
|
||||||
resetDefaultMenuAndBar()
|
|
||||||
}
|
|
||||||
binding.readerMenu.isVisible = true
|
binding.readerMenu.isVisible = true
|
||||||
|
|
||||||
if (animate) {
|
if (animate) {
|
||||||
|
@ -503,9 +512,7 @@ class ReaderActivity : BaseRxActivity<ReaderActivityBinding, ReaderPresenter>()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (preferences.fullscreen().get()) {
|
if (preferences.fullscreen().get()) {
|
||||||
window.hideBar()
|
windowInsetsController.hide(WindowInsetsCompat.Type.systemBars())
|
||||||
} else {
|
|
||||||
resetDefaultMenuAndBar()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (animate) {
|
if (animate) {
|
||||||
|
@ -529,14 +536,6 @@ class ReaderActivity : BaseRxActivity<ReaderActivityBinding, ReaderPresenter>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
* Called from the presenter when a manga is ready. Used to instantiate the appropriate viewer
|
||||||
* and the toolbar title.
|
* and the toolbar title.
|
||||||
|
@ -557,6 +556,7 @@ class ReaderActivity : BaseRxActivity<ReaderActivityBinding, ReaderPresenter>()
|
||||||
binding.viewerContainer.removeAllViews()
|
binding.viewerContainer.removeAllViews()
|
||||||
}
|
}
|
||||||
viewer = newViewer
|
viewer = newViewer
|
||||||
|
updateViewerInset(preferences.fullscreen().get())
|
||||||
binding.viewerContainer.addView(newViewer.getView())
|
binding.viewerContainer.addView(newViewer.getView())
|
||||||
|
|
||||||
if (preferences.showReadingMode()) {
|
if (preferences.showReadingMode()) {
|
||||||
|
@ -811,6 +811,19 @@ class ReaderActivity : BaseRxActivity<ReaderActivityBinding, ReaderPresenter>()
|
||||||
updateOrientationShortcut(presenter.getMangaOrientationType(resolveDefault = false))
|
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.
|
* Class that handles the user preferences of the reader.
|
||||||
*/
|
*/
|
||||||
|
@ -831,8 +844,15 @@ class ReaderActivity : BaseRxActivity<ReaderActivityBinding, ReaderPresenter>()
|
||||||
*/
|
*/
|
||||||
init {
|
init {
|
||||||
preferences.readerTheme().asFlow()
|
preferences.readerTheme().asFlow()
|
||||||
.drop(1) // We only care about updates
|
.onEach {
|
||||||
.onEach { recreate() }
|
binding.readerContainer.setBackgroundResource(
|
||||||
|
when (preferences.readerTheme().get()) {
|
||||||
|
0 -> android.R.color.white
|
||||||
|
2 -> R.color.background_dark
|
||||||
|
else -> android.R.color.black
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
.launchIn(lifecycleScope)
|
.launchIn(lifecycleScope)
|
||||||
|
|
||||||
preferences.showPageNumber().asFlow()
|
preferences.showPageNumber().asFlow()
|
||||||
|
@ -868,6 +888,13 @@ class ReaderActivity : BaseRxActivity<ReaderActivityBinding, ReaderPresenter>()
|
||||||
preferences.grayscale().asFlow()
|
preferences.grayscale().asFlow()
|
||||||
.onEach { setGrayscale(it) }
|
.onEach { setGrayscale(it) }
|
||||||
.launchIn(lifecycleScope)
|
.launchIn(lifecycleScope)
|
||||||
|
|
||||||
|
preferences.fullscreen().asFlow()
|
||||||
|
.onEach {
|
||||||
|
WindowCompat.setDecorFitsSystemWindows(window, !it)
|
||||||
|
updateViewerInset(it)
|
||||||
|
}
|
||||||
|
.launchIn(lifecycleScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -54,7 +54,6 @@ import eu.kanade.tachiyomi.util.lang.awaitSingle
|
||||||
import eu.kanade.tachiyomi.util.lang.launchIO
|
import eu.kanade.tachiyomi.util.lang.launchIO
|
||||||
import eu.kanade.tachiyomi.util.lang.withIOContext
|
import eu.kanade.tachiyomi.util.lang.withIOContext
|
||||||
import eu.kanade.tachiyomi.util.system.toast
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
import eu.kanade.tachiyomi.util.view.hideBar
|
|
||||||
import kotlinx.coroutines.async
|
import kotlinx.coroutines.async
|
||||||
import kotlinx.coroutines.awaitAll
|
import kotlinx.coroutines.awaitAll
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
|
@ -109,9 +108,6 @@ class WatcherActivity : AppCompatActivity() {
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.watcher_activity)
|
setContentView(R.layout.watcher_activity)
|
||||||
window.decorView.setOnSystemUiVisibilityChangeListener {
|
|
||||||
window.hideBar()
|
|
||||||
}
|
|
||||||
playerView = findViewById(R.id.player_view)
|
playerView = findViewById(R.id.player_view)
|
||||||
youTubeDoubleTap = findViewById(R.id.youtube_overlay)
|
youTubeDoubleTap = findViewById(R.id.youtube_overlay)
|
||||||
youTubeDoubleTap
|
youTubeDoubleTap
|
||||||
|
|
|
@ -43,7 +43,6 @@ object ImageUtil {
|
||||||
fun findImageType(stream: InputStream): ImageType? {
|
fun findImageType(stream: InputStream): ImageType? {
|
||||||
try {
|
try {
|
||||||
return when (getImageType(stream)?.format) {
|
return when (getImageType(stream)?.format) {
|
||||||
// TODO: image-decoder library currently doesn't actually detect AVIF yet
|
|
||||||
Format.Avif -> ImageType.AVIF
|
Format.Avif -> ImageType.AVIF
|
||||||
Format.Gif -> ImageType.GIF
|
Format.Gif -> ImageType.GIF
|
||||||
Format.Heif -> ImageType.HEIF
|
Format.Heif -> ImageType.HEIF
|
||||||
|
|
|
@ -3,32 +3,11 @@ package eu.kanade.tachiyomi.util.view
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.view.View
|
|
||||||
import android.view.Window
|
import android.view.Window
|
||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
import eu.kanade.tachiyomi.util.system.InternalResourceHelper
|
import eu.kanade.tachiyomi.util.system.InternalResourceHelper
|
||||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
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,
|
* Sets navigation bar color to transparent if system's config_navBarNeedsScrim is false,
|
||||||
* otherwise it will use the theme navigationBarColor with 70% opacity.
|
* otherwise it will use the theme navigationBarColor with 70% opacity.
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package eu.kanade.tachiyomi.widget.sheet
|
package eu.kanade.tachiyomi.widget.sheet
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.res.Configuration
|
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.DisplayMetrics
|
import android.util.DisplayMetrics
|
||||||
|
@ -10,7 +9,6 @@ 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.R
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferenceValues
|
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.util.system.displayCompat
|
import eu.kanade.tachiyomi.util.system.displayCompat
|
||||||
import eu.kanade.tachiyomi.util.view.setNavigationBarTransparentCompat
|
import eu.kanade.tachiyomi.util.view.setNavigationBarTransparentCompat
|
||||||
|
@ -45,16 +43,9 @@ abstract class BaseBottomSheetDialog(context: Context) : BottomSheetDialog(conte
|
||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
window?.setNavigationBarTransparentCompat(context)
|
window?.setNavigationBarTransparentCompat(context)
|
||||||
val isDarkMode = when (Injekt.get<PreferencesHelper>().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
|
val bottomSheet = rootView.parent as ViewGroup
|
||||||
var flags = bottomSheet.systemUiVisibility
|
var flags = bottomSheet.systemUiVisibility
|
||||||
flags = if (isDarkMode) {
|
flags = if (Injekt.get<PreferencesHelper>().isDarkMode()) {
|
||||||
flags and View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR.inv()
|
flags and View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR.inv()
|
||||||
} else {
|
} else {
|
||||||
flags or View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
|
flags or View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
|
||||||
|
|
|
@ -38,6 +38,32 @@
|
||||||
tools:ignore="ContentDescription"
|
tools:ignore="ContentDescription"
|
||||||
tools:src="@mipmap/ic_launcher" />
|
tools:src="@mipmap/ic_launcher" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/badges"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="4dp"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:background="@drawable/rounded_rectangle">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/favorite_text"
|
||||||
|
style="@style/TextAppearance.Regular.Caption"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/colorSecondary"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:paddingStart="3dp"
|
||||||
|
android:paddingTop="1dp"
|
||||||
|
android:paddingEnd="3dp"
|
||||||
|
android:paddingBottom="1dp"
|
||||||
|
android:text="@string/in_library"
|
||||||
|
android:textColor="?attr/colorOnSecondary"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
|
|
@ -61,7 +61,6 @@
|
||||||
android:id="@+id/toolbar"
|
android:id="@+id/toolbar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="?attr/colorToolbar"
|
|
||||||
android:minHeight="?attr/actionBarSize" />
|
android:minHeight="?attr/actionBarSize" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
@ -147,6 +146,7 @@
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/toolbar_bottom"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="?attr/actionBarSize"
|
android:layout_height="?attr/actionBarSize"
|
||||||
android:layout_gravity="bottom"
|
android:layout_gravity="bottom"
|
||||||
|
|
|
@ -84,6 +84,22 @@
|
||||||
tools:text="120"
|
tools:text="120"
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/favorite_text"
|
||||||
|
style="@style/TextAppearance.Regular.Caption"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/colorSecondary"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:paddingStart="3dp"
|
||||||
|
android:paddingTop="1dp"
|
||||||
|
android:paddingEnd="3dp"
|
||||||
|
android:paddingBottom="1dp"
|
||||||
|
android:text="@string/in_library"
|
||||||
|
android:textColor="?attr/colorOnSecondary"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<com.google.android.material.progressindicator.CircularProgressIndicator
|
<com.google.android.material.progressindicator.CircularProgressIndicator
|
||||||
|
|
|
@ -83,6 +83,22 @@
|
||||||
tools:text="120"
|
tools:text="120"
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/favorite_text"
|
||||||
|
style="@style/TextAppearance.Regular.Caption"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/colorSecondary"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:paddingStart="3dp"
|
||||||
|
android:paddingTop="1dp"
|
||||||
|
android:paddingEnd="3dp"
|
||||||
|
android:paddingBottom="1dp"
|
||||||
|
android:text="@string/in_library"
|
||||||
|
android:textColor="?attr/colorOnSecondary"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
|
|
@ -97,6 +97,22 @@
|
||||||
tools:text="130"
|
tools:text="130"
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/favorite_text"
|
||||||
|
style="@style/TextAppearance.Regular.Caption"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/colorSecondary"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:paddingStart="3dp"
|
||||||
|
android:paddingTop="1dp"
|
||||||
|
android:paddingEnd="3dp"
|
||||||
|
android:paddingBottom="1dp"
|
||||||
|
android:text="@string/in_library"
|
||||||
|
android:textColor="?attr/colorOnSecondary"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
|
@ -53,9 +53,6 @@
|
||||||
<color name="accent_hotpink">#FF3399</color>
|
<color name="accent_hotpink">#FF3399</color>
|
||||||
<color name="ripple_colored_hotpink">#1FFF3399</color>
|
<color name="ripple_colored_hotpink">#1FFF3399</color>
|
||||||
|
|
||||||
<!-- Reader Theme -->
|
|
||||||
<color name="reader_toolbar">#242529</color>
|
|
||||||
|
|
||||||
<color name="filterColorLight">#FFC107</color>
|
<color name="filterColorLight">#FFC107</color>
|
||||||
<color name="filterColorDark">#FFEB3B</color>
|
<color name="filterColorDark">#FFEB3B</color>
|
||||||
<color name="filterColorAmoled">#FFEB3B</color>
|
<color name="filterColorAmoled">#FFEB3B</color>
|
||||||
|
|
|
@ -219,11 +219,6 @@
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
||||||
<style name="Widget.Tachiyomi.BasicSwitch" parent="Widget.MaterialComponents.CompoundButton.Switch">
|
|
||||||
<item name="useMaterialThemeColors">false</item>
|
|
||||||
</style>
|
|
||||||
|
|
||||||
|
|
||||||
<style name="Widget.Tachiyomi.CircularProgressIndicator.Small" parent="Widget.MaterialComponents.CircularProgressIndicator">
|
<style name="Widget.Tachiyomi.CircularProgressIndicator.Small" parent="Widget.MaterialComponents.CircularProgressIndicator">
|
||||||
<item name="indicatorSize">16dp</item>
|
<item name="indicatorSize">16dp</item>
|
||||||
<item name="trackThickness">2dp</item>
|
<item name="trackThickness">2dp</item>
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
<item name="android:navigationBarColor">@color/md_black_1000</item>
|
<item name="android:navigationBarColor">@color/md_black_1000</item>
|
||||||
<item name="android:navigationBarDividerColor" tools:targetApi="o_mr1">@null</item>
|
<item name="android:navigationBarDividerColor" tools:targetApi="o_mr1">@null</item>
|
||||||
<item name="android:enforceNavigationBarContrast" tools:targetApi="Q">false</item>
|
<item name="android:enforceNavigationBarContrast" tools:targetApi="Q">false</item>
|
||||||
|
<item name="android:enforceStatusBarContrast" tools:targetApi="Q">false</item>
|
||||||
<item name="android:itemTextAppearance">@style/TextAppearance.Widget.Menu</item>
|
<item name="android:itemTextAppearance">@style/TextAppearance.Widget.Menu</item>
|
||||||
<item name="android:backgroundDimAmount">0.32</item>
|
<item name="android:backgroundDimAmount">0.32</item>
|
||||||
<item name="windowActionModeOverlay">true</item>
|
<item name="windowActionModeOverlay">true</item>
|
||||||
|
@ -174,6 +175,7 @@
|
||||||
<item name="android:navigationBarColor">@color/md_black_1000</item>
|
<item name="android:navigationBarColor">@color/md_black_1000</item>
|
||||||
<item name="android:navigationBarDividerColor" tools:targetApi="o_mr1">@null</item>
|
<item name="android:navigationBarDividerColor" tools:targetApi="o_mr1">@null</item>
|
||||||
<item name="android:enforceNavigationBarContrast" tools:targetApi="Q">false</item>
|
<item name="android:enforceNavigationBarContrast" tools:targetApi="Q">false</item>
|
||||||
|
<item name="android:enforceStatusBarContrast" tools:targetApi="Q">false</item>
|
||||||
<item name="android:itemTextAppearance">@style/TextAppearance.Widget.Menu</item>
|
<item name="android:itemTextAppearance">@style/TextAppearance.Widget.Menu</item>
|
||||||
<item name="android:backgroundDimAmount">0.32</item>
|
<item name="android:backgroundDimAmount">0.32</item>
|
||||||
<item name="windowActionModeOverlay">true</item>
|
<item name="windowActionModeOverlay">true</item>
|
||||||
|
@ -298,6 +300,7 @@
|
||||||
<item name="android:statusBarColor">?attr/colorSurface</item>
|
<item name="android:statusBarColor">?attr/colorSurface</item>
|
||||||
<item name="android:navigationBarDividerColor" tools:targetApi="o_mr1">@null</item>
|
<item name="android:navigationBarDividerColor" tools:targetApi="o_mr1">@null</item>
|
||||||
<item name="android:enforceNavigationBarContrast" tools:targetApi="Q">false</item>
|
<item name="android:enforceNavigationBarContrast" tools:targetApi="Q">false</item>
|
||||||
|
<item name="android:enforceStatusBarContrast" tools:targetApi="Q">false</item>
|
||||||
<item name="android:itemTextAppearance">@style/TextAppearance.Widget.Menu</item>
|
<item name="android:itemTextAppearance">@style/TextAppearance.Widget.Menu</item>
|
||||||
<item name="android:backgroundDimAmount">0.32</item>
|
<item name="android:backgroundDimAmount">0.32</item>
|
||||||
<item name="windowActionModeOverlay">true</item>
|
<item name="windowActionModeOverlay">true</item>
|
||||||
|
@ -349,64 +352,6 @@
|
||||||
<item name="colorControlHighlight">@color/ripple_colored_hotpink</item>
|
<item name="colorControlHighlight">@color/ripple_colored_hotpink</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<!--===============-->
|
|
||||||
<!-- Reader Themes -->
|
|
||||||
<!--===============-->
|
|
||||||
|
|
||||||
<!--== Light Reader base ==-->
|
|
||||||
<style name="Theme.Base.Reader.Light" parent="Theme.Base.Light">
|
|
||||||
<!-- Theme colors -->
|
|
||||||
<item name="colorSurface">@color/md_white_1000</item>
|
|
||||||
<item name="colorToolbar">@color/reader_toolbar</item>
|
|
||||||
<item name="colorOnToolbar">@color/md_white_1000</item>
|
|
||||||
|
|
||||||
<!-- Base background/text colors -->
|
|
||||||
<item name="android:colorBackground">@color/md_white_1000</item>
|
|
||||||
<item name="android:statusBarColor">?attr/colorToolbar</item>
|
|
||||||
<item name="android:navigationBarColor">?attr/colorToolbar</item>
|
|
||||||
|
|
||||||
<!-- Themes -->
|
|
||||||
<item name="toolbarStyle">@style/Widget.Tachiyomi.Toolbar.Primary</item>
|
|
||||||
<item name="switchStyle">@style/Widget.Tachiyomi.BasicSwitch</item>
|
|
||||||
<item name="bottomSheetDialogTheme">@style/ThemeOverlay.Tachiyomi.BottomSheetDialog</item>
|
|
||||||
<item name="android:alertDialogTheme">@style/ThemeOverlay.Tachiyomi.MaterialAlertDialog</item>
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<!--== Light Reader ==-->
|
|
||||||
<style name="Theme.Reader.Light" parent="Theme.Base.Reader.Light" />
|
|
||||||
|
|
||||||
<!--== Dark Reader base ==-->
|
|
||||||
<style name="Theme.Base.Reader.Dark" parent="Theme.Base.Dark">
|
|
||||||
<!-- Theme colors -->
|
|
||||||
<item name="colorSurface">@color/md_black_1000</item>
|
|
||||||
<item name="colorToolbar">@color/reader_toolbar</item>
|
|
||||||
|
|
||||||
<!-- Base background/text colors -->
|
|
||||||
<item name="android:colorBackground">@color/md_black_1000</item>
|
|
||||||
<item name="android:statusBarColor">?attr/colorToolbar</item>
|
|
||||||
<item name="android:navigationBarColor">?attr/colorToolbar</item>
|
|
||||||
|
|
||||||
<!-- Themes -->
|
|
||||||
<item name="switchStyle">@style/Widget.Tachiyomi.BasicSwitch</item>
|
|
||||||
<item name="bottomSheetDialogTheme">@style/ThemeOverlay.Tachiyomi.BottomSheetDialog</item>
|
|
||||||
<item name="android:alertDialogTheme">@style/ThemeOverlay.Tachiyomi.MaterialAlertDialog</item>
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<!--== Dark Reader ==-->
|
|
||||||
<style name="Theme.Reader.Dark" parent="Theme.Base.Reader.Dark" />
|
|
||||||
|
|
||||||
<!--== Dark Grey Reader ==-->
|
|
||||||
<style name="Theme.Reader.Dark.Grey" parent="Theme.Base.Reader.Dark">
|
|
||||||
<!-- Theme colors -->
|
|
||||||
<item name="colorSurface">@color/background_dark</item>
|
|
||||||
|
|
||||||
<!-- Base background/text colors -->
|
|
||||||
<item name="android:colorBackground">@color/background_dark</item>
|
|
||||||
|
|
||||||
<!-- Alert Dialog -->
|
|
||||||
<item name="android:alertDialogTheme">@style/ThemeOverlay.Tachiyomi.MaterialAlertDialog</item>
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<!--===============-->
|
<!--===============-->
|
||||||
<!-- Launch Screen -->
|
<!-- Launch Screen -->
|
||||||
<!--===============-->
|
<!--===============-->
|
||||||
|
|
Loading…
Reference in a new issue