Merge branch 'pr21'

This commit is contained in:
jmir1 2021-05-25 17:30:58 +02:00
commit b76a8c5fa7
22 changed files with 162 additions and 128 deletions

View file

@ -8,7 +8,6 @@ plugins {
id("com.android.application")
id("com.mikepenz.aboutlibraries.plugin")
kotlin("android")
kotlin("kapt")
kotlin("plugin.serialization")
id("com.github.zellius.shortcut-helper")
}
@ -121,7 +120,7 @@ android {
dependencies {
// Source models and interfaces from Tachiyomi 1.x
implementation("tachiyomi.sourceapi:source-api:1.1")
implementation("org.tachiyomi:source-api:1.1")
// AndroidX libraries
implementation("androidx.annotation:annotation:1.3.0-alpha01")

View file

@ -21,6 +21,7 @@ import eu.kanade.tachiyomi.data.download.DownloadService
import eu.kanade.tachiyomi.data.notification.Notifications
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.data.track.TrackService
import eu.kanade.tachiyomi.data.track.UnattendedTrackService
import eu.kanade.tachiyomi.source.AnimeSourceManager
import eu.kanade.tachiyomi.source.model.SAnime
@ -273,6 +274,7 @@ class AnimelibUpdateService(
val newUpdates = mutableListOf<Pair<AnimelibAnime, Array<Episode>>>()
val failedUpdates = mutableListOf<Pair<Anime, String?>>()
var hasDownloads = false
val loggedServices by lazy { trackManager.services.filter { it.isLogged } }
animeToUpdate.forEach { anime ->
if (updateJob?.isActive != true) {
@ -301,6 +303,10 @@ class AnimelibUpdateService(
}
failedUpdates.add(anime to errorMessage)
}
if (preferences.autoUpdateTrackers()) {
updateTrackings(anime, loggedServices)
}
}
notifier.cancelProgressNotification()
@ -408,31 +414,35 @@ class AnimelibUpdateService(
notifier.showProgressNotification(anime, progressCount++, animeToUpdate.size)
// Update the tracking details.
db.getTracks(anime).executeAsBlocking()
.map { track ->
supervisorScope {
async {
val service = trackManager.getService(track.sync_id)
if (service != null && service in loggedServices) {
try {
val updatedTrack = service.refresh(track)
db.insertTrack(updatedTrack).executeAsBlocking()
updateTrackings(anime, loggedServices)
}
if (service is UnattendedTrackService) {
syncEpisodesWithTrackServiceTwoWay(db, db.getEpisodes(anime).executeAsBlocking(), track, service)
}
} catch (e: Throwable) {
// Ignore errors and continue
Timber.e(e)
notifier.cancelProgressNotification()
}
private suspend fun updateTrackings(anime: AnimelibAnime, loggedServices: List<TrackService>) {
db.getTracks(anime).executeAsBlocking()
.map { track ->
supervisorScope {
async {
val service = trackManager.getService(track.sync_id)
if (service != null && service in loggedServices) {
try {
val updatedTrack = service.refresh(track)
db.insertTrack(updatedTrack).executeAsBlocking()
if (service is UnattendedTrackService) {
syncEpisodesWithTrackServiceTwoWay(db, db.getEpisodes(anime).executeAsBlocking(), track, service)
}
} catch (e: Throwable) {
// Ignore errors and continue
Timber.e(e)
}
}
}
}
.awaitAll()
}
notifier.cancelProgressNotification()
}
.awaitAll()
}
/**

View file

@ -21,6 +21,7 @@ import eu.kanade.tachiyomi.data.library.LibraryUpdateService.Companion.start
import eu.kanade.tachiyomi.data.notification.Notifications
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.data.track.TrackService
import eu.kanade.tachiyomi.data.track.UnattendedTrackService
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.model.SManga
@ -273,6 +274,7 @@ class LibraryUpdateService(
val newUpdates = mutableListOf<Pair<LibraryManga, Array<Chapter>>>()
val failedUpdates = mutableListOf<Pair<Manga, String?>>()
var hasDownloads = false
val loggedServices by lazy { trackManager.services.filter { it.isLogged } }
mangaToUpdate.forEach { manga ->
if (updateJob?.isActive != true) {
@ -301,6 +303,10 @@ class LibraryUpdateService(
}
failedUpdates.add(manga to errorMessage)
}
if (preferences.autoUpdateTrackers()) {
updateTrackings(manga, loggedServices)
}
}
notifier.cancelProgressNotification()
@ -409,31 +415,35 @@ class LibraryUpdateService(
notifier.showProgressNotification(manga, progressCount++, mangaToUpdate.size)
// Update the tracking details.
db.getTracks(manga).executeAsBlocking()
.map { track ->
supervisorScope {
async {
val service = trackManager.getService(track.sync_id)
if (service != null && service in loggedServices) {
try {
val updatedTrack = service.refresh(track)
db.insertTrack(updatedTrack).executeAsBlocking()
updateTrackings(manga, loggedServices)
}
if (service is UnattendedTrackService) {
syncChaptersWithTrackServiceTwoWay(db, db.getChapters(manga).executeAsBlocking(), track, service)
}
} catch (e: Throwable) {
// Ignore errors and continue
Timber.e(e)
notifier.cancelProgressNotification()
}
private suspend fun updateTrackings(manga: LibraryManga, loggedServices: List<TrackService>) {
db.getTracks(manga).executeAsBlocking()
.map { track ->
supervisorScope {
async {
val service = trackManager.getService(track.sync_id)
if (service != null && service in loggedServices) {
try {
val updatedTrack = service.refresh(track)
db.insertTrack(updatedTrack).executeAsBlocking()
if (service is UnattendedTrackService) {
syncChaptersWithTrackServiceTwoWay(db, db.getChapters(manga).executeAsBlocking(), track, service)
}
} catch (e: Throwable) {
// Ignore errors and continue
Timber.e(e)
}
}
}
}
.awaitAll()
}
notifier.cancelProgressNotification()
}
.awaitAll()
}
/**

View file

@ -187,6 +187,8 @@ object PreferenceKeys {
const val autoUpdateMetadata = "auto_update_metadata"
const val autoUpdateTrackers = "auto_update_trackers"
const val showLibraryUpdateErrors = "show_library_update_errors"
const val showAnimelibUpdateErrors = "show_animelib_update_errors"

View file

@ -25,6 +25,7 @@ object PreferenceValues {
enum class DarkThemeVariant {
default,
blue,
greenapple,
midnightdusk,
amoled,
hotpink,

View file

@ -80,6 +80,8 @@ class PreferencesHelper(val context: Context) {
fun autoUpdateMetadata() = prefs.getBoolean(Keys.autoUpdateMetadata, false)
fun autoUpdateTrackers() = prefs.getBoolean(Keys.autoUpdateTrackers, false)
fun showLibraryUpdateErrors() = prefs.getBoolean(Keys.showLibraryUpdateErrors, false)
fun clear() = prefs.edit { clear() }

View file

@ -50,10 +50,6 @@ abstract class TrackService(val id: Int) {
abstract fun displayScore(track: AnimeTrack): String
abstract suspend fun add(track: Track): Track
abstract suspend fun add(track: AnimeTrack): AnimeTrack
abstract suspend fun update(track: Track): Track
abstract suspend fun update(track: AnimeTrack): AnimeTrack

View file

@ -151,11 +151,11 @@ class Anilist(private val context: Context, id: Int) : TrackService(id) {
}
}
override suspend fun add(track: Track): Track {
private suspend fun add(track: Track): Track {
return api.addLibManga(track)
}
override suspend fun add(track: AnimeTrack): AnimeTrack {
private suspend fun add(track: AnimeTrack): AnimeTrack {
return api.addLibAnime(track)
}

View file

@ -37,11 +37,11 @@ class Bangumi(private val context: Context, id: Int) : TrackService(id) {
return track.score.toInt().toString()
}
override suspend fun add(track: Track): Track {
private suspend fun add(track: Track): Track {
return api.addLibManga(track)
}
override suspend fun add(track: AnimeTrack): AnimeTrack {
private suspend fun add(track: AnimeTrack): AnimeTrack {
return api.addLibAnime(track)
}

View file

@ -74,11 +74,11 @@ class Kitsu(private val context: Context, id: Int) : TrackService(id) {
return df.format(track.score)
}
override suspend fun add(track: Track): Track {
private suspend fun add(track: Track): Track {
return api.addLibManga(track, getUserId())
}
override suspend fun add(track: AnimeTrack): AnimeTrack {
private suspend fun add(track: AnimeTrack): AnimeTrack {
return api.addLibAnime(track, getUserId())
}

View file

@ -60,10 +60,6 @@ class Komga(private val context: Context, id: Int) : TrackService(id), Unattende
override fun displayScore(track: Track): String = ""
override fun displayScore(track: AnimeTrack): String = throw Exception("Not used")
override suspend fun add(track: Track): Track = throw Exception("Not used")
override suspend fun add(track: AnimeTrack): AnimeTrack = throw Exception("Not used")
override suspend fun update(track: Track): Track {
return api.updateProgress(track)
}

View file

@ -72,13 +72,13 @@ class MyAnimeList(private val context: Context, id: Int) : TrackService(id) {
return track.score.toInt().toString()
}
override suspend fun add(track: Track): Track {
private suspend fun add(track: Track): Track {
track.status = READING
track.score = 0F
return api.updateItem(track)
}
override suspend fun add(track: AnimeTrack): AnimeTrack {
private suspend fun add(track: AnimeTrack): AnimeTrack {
track.status = READING
track.score = 0F
return api.updateItem(track)

View file

@ -46,11 +46,11 @@ class Shikimori(private val context: Context, id: Int) : TrackService(id) {
return track.score.toInt().toString()
}
override suspend fun add(track: Track): Track {
private suspend fun add(track: Track): Track {
return api.addLibManga(track, getUsername())
}
override suspend fun add(track: AnimeTrack): AnimeTrack {
private suspend fun add(track: AnimeTrack): AnimeTrack {
return api.addLibAnime(track, getUsername())
}

View file

@ -3,7 +3,6 @@ package eu.kanade.tachiyomi.ui.anime.track
import android.annotation.SuppressLint
import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView
import eu.kanade.tachiyomi.R.string
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.databinding.TrackItemBinding
import uy.kohesive.injekt.injectLazy
@ -43,18 +42,22 @@ class TrackHolder(private val binding: TrackItemBinding, adapter: TrackAdapter)
binding.trackSet.isVisible = track == null
binding.trackTitle.isVisible = track != null
binding.trackDetails.isVisible = track != null
binding.topDivider.isVisible = track != null
binding.middleRow.isVisible = track != null
binding.bottomDivider.isVisible = track != null
binding.bottomRow.isVisible = track != null
if (track != null) {
binding.trackTitle.text = track.title
binding.trackChapters.text = "${track.last_episode_seen}/" +
if (track.total_episodes > 0) track.total_episodes else "-"
binding.trackStatus.text = item.service.getStatus(track.status)
binding.trackScore.text = if (track.score == 0f) "-" else item.service.displayScore(track)
if (item.service.getScoreList().isEmpty()) {
with(binding.trackScore) {
text = context.getString(string.score_unsupported)
isEnabled = false
}
binding.trackScore.isVisible = false
binding.vertDivider2.isVisible = false
} else {
binding.trackScore.text = if (track.score == 0f) "-" else item.service.displayScore(track)
}
if (item.service.supportsReadingDates) {
@ -64,9 +67,7 @@ class TrackHolder(private val binding: TrackItemBinding, adapter: TrackAdapter)
if (track.finished_watching_date != 0L) dateFormat.format(track.finished_watching_date) else "-"
} else {
binding.bottomDivider.isVisible = false
binding.vertDivider3.isVisible = false
binding.trackStartDate.isVisible = false
binding.trackFinishDate.isVisible = false
binding.bottomRow.isVisible = false
}
}
}

View file

@ -25,6 +25,7 @@ abstract class BaseThemedActivity : AppCompatActivity() {
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

View file

@ -3,7 +3,6 @@ package eu.kanade.tachiyomi.ui.manga.track
import android.annotation.SuppressLint
import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView
import eu.kanade.tachiyomi.R.string
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.databinding.TrackItemBinding
import uy.kohesive.injekt.injectLazy
@ -43,18 +42,22 @@ class TrackHolder(private val binding: TrackItemBinding, adapter: TrackAdapter)
binding.trackSet.isVisible = track == null
binding.trackTitle.isVisible = track != null
binding.trackDetails.isVisible = track != null
binding.topDivider.isVisible = track != null
binding.middleRow.isVisible = track != null
binding.bottomDivider.isVisible = track != null
binding.bottomRow.isVisible = track != null
if (track != null) {
binding.trackTitle.text = track.title
binding.trackChapters.text = "${track.last_chapter_read}/" +
if (track.total_chapters > 0) track.total_chapters else "-"
binding.trackStatus.text = item.service.getStatus(track.status)
binding.trackScore.text = if (track.score == 0f) "-" else item.service.displayScore(track)
if (item.service.getScoreList().isEmpty()) {
with(binding.trackScore) {
text = context.getString(string.score_unsupported)
isEnabled = false
}
binding.trackScore.isVisible = false
binding.vertDivider2.isVisible = false
} else {
binding.trackScore.text = if (track.score == 0f) "-" else item.service.displayScore(track)
}
if (item.service.supportsReadingDates) {
@ -64,9 +67,7 @@ class TrackHolder(private val binding: TrackItemBinding, adapter: TrackAdapter)
if (track.finished_reading_date != 0L) dateFormat.format(track.finished_reading_date) else "-"
} else {
binding.bottomDivider.isVisible = false
binding.vertDivider3.isVisible = false
binding.trackStartDate.isVisible = false
binding.trackFinishDate.isVisible = false
binding.bottomRow.isVisible = false
}
}
}

View file

@ -143,6 +143,7 @@ class SettingsGeneralController : SettingsController() {
entriesRes = arrayOf(
R.string.theme_dark_default,
R.string.theme_dark_blue,
R.string.theme_dark_greenapple,
R.string.theme_dark_midnightdusk,
R.string.theme_dark_amoled,
R.string.theme_dark_amoled_hotpink
@ -150,6 +151,7 @@ class SettingsGeneralController : SettingsController() {
entryValues = arrayOf(
Values.DarkThemeVariant.default.name,
Values.DarkThemeVariant.blue.name,
Values.DarkThemeVariant.greenapple.name,
Values.DarkThemeVariant.midnightdusk.name,
Values.DarkThemeVariant.amoled.name,
Values.DarkThemeVariant.hotpink.name

View file

@ -241,6 +241,12 @@ class SettingsLibraryController : SettingsController() {
summaryRes = R.string.pref_library_update_refresh_metadata_summary
defaultValue = false
}
switchPreference {
key = Keys.autoUpdateTrackers
titleRes = R.string.pref_library_update_refresh_trackers
summaryRes = R.string.pref_library_update_refresh_trackers_summary
defaultValue = false
}
switchPreference {
key = Keys.showLibraryUpdateErrors
titleRes = R.string.pref_library_update_error_notification

View file

@ -67,24 +67,22 @@
</LinearLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/track_details"
<View
android:id="@+id/top_divider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:alpha="0.25"
android:background="?android:attr/textColorHint" />
<LinearLayout
android:id="@+id/middle_row"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<View
android:id="@+id/top_divider"
android:layout_width="0dp"
android:layout_height="1dp"
android:alpha="0.25"
android:background="?android:attr/textColorHint"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/track_status"
style="@style/TextAppearance.Regular.Body1.Secondary"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@drawable/list_item_selector"
@ -92,27 +90,22 @@
android:gravity="center"
android:maxLines="1"
android:padding="16dp"
app:layout_constraintEnd_toStartOf="@+id/vert_divider_1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/top_divider"
tools:text="Reading" />
<View
android:id="@+id/vert_divider_1"
android:layout_width="1dp"
android:layout_height="0dp"
android:layout_height="match_parent"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:alpha="0.25"
android:background="?android:attr/textColorHint"
app:layout_constraintBottom_toTopOf="@+id/bottom_divider"
app:layout_constraintEnd_toStartOf="@+id/track_chapters"
app:layout_constraintStart_toEndOf="@+id/track_status"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/track_chapters"
style="@style/TextAppearance.Regular.Body1.Secondary"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@drawable/list_item_selector"
@ -120,27 +113,21 @@
android:gravity="center"
android:maxLines="1"
android:padding="16dp"
app:layout_constraintEnd_toStartOf="@+id/vert_divider_2"
app:layout_constraintStart_toEndOf="@+id/vert_divider_1"
app:layout_constraintTop_toBottomOf="@+id/top_divider"
tools:text="12/24" />
<View
android:id="@+id/vert_divider_2"
android:layout_width="1dp"
android:layout_height="0dp"
android:layout_height="match_parent"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:alpha="0.25"
android:background="?android:attr/textColorHint"
app:layout_constraintBottom_toTopOf="@+id/bottom_divider"
app:layout_constraintEnd_toStartOf="@+id/track_score"
app:layout_constraintStart_toEndOf="@+id/track_chapters"
app:layout_constraintTop_toTopOf="parent" />
android:background="?android:attr/textColorHint"/>
<TextView
android:id="@+id/track_score"
style="@style/TextAppearance.Regular.Body1.Secondary"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@drawable/list_item_selector"
@ -148,24 +135,26 @@
android:gravity="center"
android:maxLines="1"
android:padding="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/vert_divider_2"
app:layout_constraintTop_toBottomOf="@+id/top_divider"
tools:text="10" />
<View
android:id="@+id/bottom_divider"
android:layout_width="0dp"
android:layout_height="1dp"
android:alpha="0.25"
android:background="?android:attr/textColorHint"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/track_score" />
</LinearLayout>
<View
android:id="@+id/bottom_divider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:alpha="0.25"
android:background="?android:attr/textColorHint" />
<LinearLayout
android:id="@+id/bottom_row"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/track_start_date"
style="@style/TextAppearance.Regular.Body1.Secondary"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@drawable/list_item_selector"
@ -173,27 +162,22 @@
android:gravity="center"
android:maxLines="1"
android:padding="16dp"
app:layout_constraintEnd_toStartOf="@+id/vert_divider_3"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/bottom_divider"
tools:text="4/16/2020" />
<View
android:id="@+id/vert_divider_3"
android:layout_width="1dp"
android:layout_height="0dp"
android:layout_height="match_parent"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:alpha="0.25"
android:background="?android:attr/textColorHint"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/track_finish_date"
app:layout_constraintStart_toEndOf="@+id/track_start_date"
app:layout_constraintTop_toTopOf="@+id/bottom_divider" />
app:layout_constraintBottom_toBottomOf="parent" />
<TextView
android:id="@+id/track_finish_date"
style="@style/TextAppearance.Regular.Body1.Secondary"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@drawable/list_item_selector"
@ -206,7 +190,7 @@
app:layout_constraintTop_toBottomOf="@+id/bottom_divider"
tools:text="4/16/2020" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
</LinearLayout>

View file

@ -46,6 +46,12 @@
<color name="dialogDark">@color/colorDarkPrimary</color>
<color name="selectorColorDark">@color/md_blue_A200_50</color>
<!-- Green Apple Theme -->
<color name="colorAccentApple">#48E484</color>
<color name="colorOnSecondaryApple">@color/md_black_1000</color>
<color name="rippleSecondaryColorApple">#0A48E484</color>
<color name="selectorColorApple">#8048E484</color>
<!-- Midnight Dusk Theme -->
<color name="colorAccentDusk">#F02475</color>
<color name="textColorPrimaryDusk">@color/md_white_1000</color>

View file

@ -169,6 +169,7 @@
<string name="pref_theme_dark">Dark theme</string>
<string name="theme_dark_default">Default</string>
<string name="theme_dark_blue">Dark Blue</string>
<string name="theme_dark_greenapple">Green Apple</string>
<string name="theme_dark_midnightdusk">Midnight Dusk</string>
<string name="theme_dark_amoled">AMOLED Black</string>
<string name="theme_dark_amoled_hotpink">Hot Pink</string>
@ -227,6 +228,8 @@
<string name="pref_update_only_non_completed">Only update ongoing manga</string>
<string name="pref_library_update_refresh_metadata">Automatically refresh metadata</string>
<string name="pref_library_update_refresh_metadata_summary">Check for new cover and details when updating library</string>
<string name="pref_library_update_refresh_trackers">Automatically update trackers</string>
<string name="pref_library_update_refresh_trackers_summary">Update trackers when updating library</string>
<string name="pref_library_update_error_notification">Show update errors notifications</string>
<string name="default_category">Default category</string>
@ -639,7 +642,6 @@
<string name="error_invalid_date_supplied">Invalid date supplied</string>
<string name="myanimelist_creds_missing">MAL login credentials not found</string>
<string name="myanimelist_relogin">Please login to MAL again</string>
<string name="score_unsupported">Not supported</string>
<string name="source_unsupported">Source is not supported</string>
<string name="error_no_match">No match found</string>

View file

@ -248,6 +248,21 @@
<item name="rippleToolbarColor">@color/md_black_1000_12</item>
</style>
<!--== Green Apple theme ==-->
<style name="Theme.Tachiyomi.Dark.GreenApple">
<!-- Theme colors -->
<item name="colorAccentOnPrimary">@color/colorAccentApple</item>
<item name="colorSecondary">@color/colorAccentApple</item>
<item name="colorOnSecondary">@color/colorOnSecondaryApple</item>
<item name="colorAccent">@color/colorAccentApple</item>
<!-- Ripples -->
<item name="rippleSecondaryColor">@color/rippleSecondaryColorApple</item>
<!-- Custom Attributes-->
<item name="colorLibrarySelectionActive">@color/selectorColorApple</item>
</style>
<!--== Midnight Dusk theme ==-->
<style name="Theme.Tachiyomi.Dark.MidnightDusk" parent="Theme.Base.Dark">
<!-- Theme colors -->