Last commit merged: 2556e9f08c
This commit is contained in:
LuftVerbot 2023-11-17 17:00:32 +01:00
parent 717479961c
commit 370212c677
140 changed files with 364 additions and 545 deletions

View file

@ -31,7 +31,7 @@ class PreferenceMutableState<T>(
}
override fun component2(): (T) -> Unit {
return { preference.set(it) }
return preference::set
}
}

View file

@ -65,6 +65,7 @@ import eu.kanade.presentation.entries.anime.components.AnimeInfoBox
import eu.kanade.presentation.entries.anime.components.EpisodeDownloadAction
import eu.kanade.presentation.entries.anime.components.ExpandableAnimeDescription
import eu.kanade.presentation.entries.anime.components.NextEpisodeAiringListItem
import eu.kanade.presentation.util.formatEpisodeNumber
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
import eu.kanade.tachiyomi.animesource.model.SAnime
@ -73,7 +74,6 @@ import eu.kanade.tachiyomi.source.anime.getNameForAnimeInfo
import eu.kanade.tachiyomi.ui.browse.anime.extension.details.SourcePreferencesScreen
import eu.kanade.tachiyomi.ui.entries.anime.AnimeScreenState
import eu.kanade.tachiyomi.ui.entries.anime.EpisodeItem
import eu.kanade.tachiyomi.ui.entries.anime.episodeDecimalFormat
import eu.kanade.tachiyomi.util.lang.toRelativeString
import eu.kanade.tachiyomi.util.system.copyToClipboard
import kotlinx.coroutines.delay
@ -477,7 +477,7 @@ private fun AnimeScreenSmallImpl(
NextEpisodeAiringListItem(
title = stringResource(
R.string.display_mode_episode,
episodeDecimalFormat.format(state.airingEpisodeNumber),
formatEpisodeNumber(state.airingEpisodeNumber.toFloat()),
),
date = formatTime(state.airingTime, useDayFormat = true),
)
@ -734,7 +734,7 @@ fun AnimeScreenLargeImpl(
NextEpisodeAiringListItem(
title = stringResource(
R.string.display_mode_episode,
episodeDecimalFormat.format(state.airingEpisodeNumber),
formatEpisodeNumber(state.airingEpisodeNumber.toFloat()),
),
date = formatTime(state.airingTime, useDayFormat = true),
)
@ -837,7 +837,7 @@ private fun LazyListScope.sharedEpisodeItems(
title = if (anime.displayMode == Anime.EPISODE_DISPLAY_NUMBER) {
stringResource(
R.string.display_mode_episode,
episodeDecimalFormat.format(episodeItem.episode.episodeNumber.toDouble()),
formatEpisodeNumber(episodeItem.episode.episodeNumber),
)
} else {
episodeItem.episode.name

View file

@ -61,6 +61,7 @@ import eu.kanade.presentation.entries.manga.components.ExpandableMangaDescriptio
import eu.kanade.presentation.entries.manga.components.MangaActionRow
import eu.kanade.presentation.entries.manga.components.MangaChapterListItem
import eu.kanade.presentation.entries.manga.components.MangaInfoBox
import eu.kanade.presentation.util.formatChapterNumber
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.download.manga.model.MangaDownload
import eu.kanade.tachiyomi.source.ConfigurableSource
@ -68,7 +69,6 @@ import eu.kanade.tachiyomi.source.manga.getNameForMangaInfo
import eu.kanade.tachiyomi.ui.browse.manga.extension.details.MangaSourcePreferencesScreen
import eu.kanade.tachiyomi.ui.entries.manga.ChapterItem
import eu.kanade.tachiyomi.ui.entries.manga.MangaScreenState
import eu.kanade.tachiyomi.ui.entries.manga.chapterDecimalFormat
import eu.kanade.tachiyomi.util.lang.toRelativeString
import eu.kanade.tachiyomi.util.system.copyToClipboard
import tachiyomi.domain.entries.manga.model.Manga
@ -746,7 +746,7 @@ private fun LazyListScope.sharedChapterItems(
title = if (manga.displayMode == Manga.CHAPTER_DISPLAY_NUMBER) {
stringResource(
R.string.display_mode_chapter,
chapterDecimalFormat.format(chapterItem.chapter.chapterNumber.toDouble()),
formatChapterNumber(chapterItem.chapter.chapterNumber),
)
} else {
chapterItem.chapter.name

View file

@ -21,12 +21,11 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import eu.kanade.presentation.entries.ItemCover
import eu.kanade.presentation.util.formatEpisodeNumber
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.util.lang.toTimestampString
import tachiyomi.domain.history.anime.model.AnimeHistoryWithRelations
import tachiyomi.presentation.core.components.material.padding
import java.text.DecimalFormat
import java.text.DecimalFormatSymbols
private val HISTORY_ITEM_HEIGHT = 96.dp
@ -68,7 +67,7 @@ fun AnimeHistoryItem(
text = if (history.episodeNumber > -1) {
stringResource(
R.string.recent_anime_time,
episodeFormatter.format(history.episodeNumber),
formatEpisodeNumber(history.episodeNumber),
seenAt,
)
} else {
@ -88,8 +87,3 @@ fun AnimeHistoryItem(
}
}
}
private val episodeFormatter = DecimalFormat(
"#.###",
DecimalFormatSymbols().apply { decimalSeparator = '.' },
)

View file

@ -21,12 +21,11 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import eu.kanade.presentation.entries.ItemCover
import eu.kanade.presentation.util.formatChapterNumber
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.util.lang.toTimestampString
import tachiyomi.domain.history.manga.model.MangaHistoryWithRelations
import tachiyomi.presentation.core.components.material.padding
import java.text.DecimalFormat
import java.text.DecimalFormatSymbols
private val HISTORY_ITEM_HEIGHT = 96.dp
@ -68,7 +67,7 @@ fun MangaHistoryItem(
text = if (history.chapterNumber > -1) {
stringResource(
R.string.recent_manga_time,
chapterFormatter.format(history.chapterNumber),
formatChapterNumber(history.chapterNumber),
readAt,
)
} else {
@ -88,8 +87,3 @@ fun MangaHistoryItem(
}
}
}
private val chapterFormatter = DecimalFormat(
"#.###",
DecimalFormatSymbols().apply { decimalSeparator = '.' },
)

View file

@ -16,7 +16,6 @@ import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.res.stringResource
import eu.kanade.presentation.components.TabbedDialog
import eu.kanade.presentation.components.TabbedDialogPaddings
import eu.kanade.presentation.util.collectAsState
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.library.anime.AnimeLibrarySettingsScreenModel
import tachiyomi.core.preference.TriState
@ -31,6 +30,7 @@ import tachiyomi.presentation.core.components.SettingsChipRow
import tachiyomi.presentation.core.components.SliderItem
import tachiyomi.presentation.core.components.SortItem
import tachiyomi.presentation.core.components.TriStateItem
import tachiyomi.presentation.core.util.collectAsState
@Composable
fun AnimeLibrarySettingsDialog(
@ -212,59 +212,35 @@ private fun ColumnScope.DisplayPage(
} else {
stringResource(R.string.label_default)
},
onChange = { columnPreference.set(it) },
onChange = columnPreference::set,
)
}
HeadingItem(R.string.overlay_header)
val downloadBadge by screenModel.libraryPreferences.downloadBadge().collectAsState()
CheckboxItem(
label = stringResource(R.string.action_display_download_badge_anime),
checked = downloadBadge,
onClick = {
screenModel.togglePreference(LibraryPreferences::downloadBadge)
},
pref = screenModel.libraryPreferences.downloadBadge(),
)
val localBadge by screenModel.libraryPreferences.localBadge().collectAsState()
CheckboxItem(
label = stringResource(R.string.action_display_local_badge),
checked = localBadge,
onClick = {
screenModel.togglePreference(LibraryPreferences::localBadge)
},
pref = screenModel.libraryPreferences.localBadge(),
)
val languageBadge by screenModel.libraryPreferences.languageBadge().collectAsState()
CheckboxItem(
label = stringResource(R.string.action_display_language_badge),
checked = languageBadge,
onClick = {
screenModel.togglePreference(LibraryPreferences::languageBadge)
},
pref = screenModel.libraryPreferences.languageBadge(),
)
val showContinueViewingButton by screenModel.libraryPreferences.showContinueViewingButton().collectAsState()
CheckboxItem(
label = stringResource(R.string.action_display_show_continue_reading_button),
checked = showContinueViewingButton,
onClick = {
screenModel.togglePreference(LibraryPreferences::showContinueViewingButton)
},
pref = screenModel.libraryPreferences.showContinueViewingButton(),
)
HeadingItem(R.string.tabs_header)
val categoryTabs by screenModel.libraryPreferences.categoryTabs().collectAsState()
CheckboxItem(
label = stringResource(R.string.action_display_show_tabs),
checked = categoryTabs,
onClick = {
screenModel.togglePreference(LibraryPreferences::categoryTabs)
},
pref = screenModel.libraryPreferences.categoryTabs(),
)
val categoryNumberOfItems by screenModel.libraryPreferences.categoryNumberOfItems().collectAsState()
CheckboxItem(
label = stringResource(R.string.action_display_show_number_of_items),
checked = categoryNumberOfItems,
onClick = {
screenModel.togglePreference(LibraryPreferences::categoryNumberOfItems)
},
pref = screenModel.libraryPreferences.categoryNumberOfItems(),
)
}

View file

@ -16,7 +16,6 @@ import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.res.stringResource
import eu.kanade.presentation.components.TabbedDialog
import eu.kanade.presentation.components.TabbedDialogPaddings
import eu.kanade.presentation.util.collectAsState
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.library.manga.MangaLibrarySettingsScreenModel
import tachiyomi.core.preference.TriState
@ -31,6 +30,7 @@ import tachiyomi.presentation.core.components.SettingsChipRow
import tachiyomi.presentation.core.components.SliderItem
import tachiyomi.presentation.core.components.SortItem
import tachiyomi.presentation.core.components.TriStateItem
import tachiyomi.presentation.core.util.collectAsState
@Composable
fun MangaLibrarySettingsDialog(
@ -211,59 +211,35 @@ private fun ColumnScope.DisplayPage(
} else {
stringResource(R.string.label_default)
},
onChange = { columnPreference.set(it) },
onChange = columnPreference::set,
)
}
HeadingItem(R.string.overlay_header)
val downloadBadge by screenModel.libraryPreferences.downloadBadge().collectAsState()
CheckboxItem(
label = stringResource(R.string.action_display_download_badge),
checked = downloadBadge,
onClick = {
screenModel.togglePreference(LibraryPreferences::downloadBadge)
},
pref = screenModel.libraryPreferences.downloadBadge(),
)
val localBadge by screenModel.libraryPreferences.localBadge().collectAsState()
CheckboxItem(
label = stringResource(R.string.action_display_local_badge),
checked = localBadge,
onClick = {
screenModel.togglePreference(LibraryPreferences::localBadge)
},
pref = screenModel.libraryPreferences.localBadge(),
)
val languageBadge by screenModel.libraryPreferences.languageBadge().collectAsState()
CheckboxItem(
label = stringResource(R.string.action_display_language_badge),
checked = languageBadge,
onClick = {
screenModel.togglePreference(LibraryPreferences::languageBadge)
},
pref = screenModel.libraryPreferences.languageBadge(),
)
val showContinueViewingButton by screenModel.libraryPreferences.showContinueViewingButton().collectAsState()
CheckboxItem(
label = stringResource(R.string.action_display_show_continue_reading_button),
checked = showContinueViewingButton,
onClick = {
screenModel.togglePreference(LibraryPreferences::showContinueViewingButton)
},
pref = screenModel.libraryPreferences.showContinueViewingButton(),
)
HeadingItem(R.string.tabs_header)
val categoryTabs by screenModel.libraryPreferences.categoryTabs().collectAsState()
CheckboxItem(
label = stringResource(R.string.action_display_show_tabs),
checked = categoryTabs,
onClick = {
screenModel.togglePreference(LibraryPreferences::categoryTabs)
},
pref = screenModel.libraryPreferences.categoryTabs(),
)
val categoryNumberOfItems by screenModel.libraryPreferences.categoryNumberOfItems().collectAsState()
CheckboxItem(
label = stringResource(R.string.action_display_show_number_of_items),
checked = categoryNumberOfItems,
onClick = {
screenModel.togglePreference(LibraryPreferences::categoryNumberOfItems)
},
pref = screenModel.libraryPreferences.categoryNumberOfItems(),
)
}

View file

@ -22,10 +22,10 @@ import eu.kanade.presentation.more.settings.widget.MultiSelectListPreferenceWidg
import eu.kanade.presentation.more.settings.widget.SwitchPreferenceWidget
import eu.kanade.presentation.more.settings.widget.TextPreferenceWidget
import eu.kanade.presentation.more.settings.widget.TrackingPreferenceWidget
import eu.kanade.presentation.util.collectAsState
import kotlinx.coroutines.launch
import tachiyomi.core.preference.PreferenceStore
import tachiyomi.presentation.core.components.SliderItem
import tachiyomi.presentation.core.util.collectAsState
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get

View file

@ -4,10 +4,10 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.platform.LocalContext
import eu.kanade.core.preference.asState
import eu.kanade.presentation.more.settings.Preference
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.player.settings.PlayerPreferences
import eu.kanade.tachiyomi.util.preference.asState
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get

View file

@ -33,7 +33,6 @@ import eu.kanade.presentation.more.settings.Preference
import eu.kanade.presentation.more.settings.screen.advanced.ClearAnimeDatabaseScreen
import eu.kanade.presentation.more.settings.screen.advanced.ClearDatabaseScreen
import eu.kanade.presentation.more.settings.screen.debug.DebugInfoScreen
import eu.kanade.presentation.util.collectAsState
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.cache.ChapterCache
import eu.kanade.tachiyomi.data.cache.EpisodeCache
@ -71,6 +70,7 @@ import tachiyomi.core.util.lang.withUIContext
import tachiyomi.core.util.system.logcat
import tachiyomi.domain.entries.manga.repository.MangaRepository
import tachiyomi.domain.library.service.LibraryPreferences
import tachiyomi.presentation.core.util.collectAsState
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.io.File

View file

@ -21,7 +21,6 @@ import eu.kanade.domain.ui.model.TabletUiMode
import eu.kanade.domain.ui.model.ThemeMode
import eu.kanade.domain.ui.model.setAppCompatDelegateThemeMode
import eu.kanade.presentation.more.settings.Preference
import eu.kanade.presentation.util.collectAsState
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.home.HomeScreen
import eu.kanade.tachiyomi.util.system.LocaleHelper
@ -31,6 +30,7 @@ import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.flow.merge
import org.xmlpull.v1.XmlPullParser
import tachiyomi.domain.library.service.LibraryPreferences
import tachiyomi.presentation.core.util.collectAsState
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.util.Date

View file

@ -42,7 +42,6 @@ import androidx.core.net.toUri
import com.hippo.unifile.UniFile
import eu.kanade.presentation.extensions.RequestStoragePermission
import eu.kanade.presentation.more.settings.Preference
import eu.kanade.presentation.util.collectAsState
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.backup.BackupConst
import eu.kanade.tachiyomi.data.backup.BackupCreateJob
@ -64,6 +63,7 @@ import tachiyomi.domain.backup.service.FLAG_SETTINGS
import tachiyomi.domain.backup.service.FLAG_TRACK
import tachiyomi.presentation.core.components.ScrollbarLazyColumn
import tachiyomi.presentation.core.components.material.Divider
import tachiyomi.presentation.core.util.collectAsState
import tachiyomi.presentation.core.util.isScrolledToEnd
import tachiyomi.presentation.core.util.isScrolledToStart
import uy.kohesive.injekt.Injekt

View file

@ -23,13 +23,13 @@ import eu.kanade.domain.base.BasePreferences
import eu.kanade.presentation.category.visualName
import eu.kanade.presentation.more.settings.Preference
import eu.kanade.presentation.more.settings.widget.TriStateListDialog
import eu.kanade.presentation.util.collectAsState
import eu.kanade.tachiyomi.R
import kotlinx.coroutines.runBlocking
import tachiyomi.domain.category.anime.interactor.GetAnimeCategories
import tachiyomi.domain.category.manga.interactor.GetMangaCategories
import tachiyomi.domain.category.model.Category
import tachiyomi.domain.download.service.DownloadPreferences
import tachiyomi.presentation.core.util.collectAsState
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.io.File

View file

@ -36,7 +36,6 @@ import cafe.adriel.voyager.navigator.currentOrThrow
import eu.kanade.presentation.category.visualName
import eu.kanade.presentation.more.settings.Preference
import eu.kanade.presentation.more.settings.widget.TriStateListDialog
import eu.kanade.presentation.util.collectAsState
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.library.anime.AnimeLibraryUpdateJob
import eu.kanade.tachiyomi.data.library.manga.MangaLibraryUpdateJob
@ -55,6 +54,7 @@ import tachiyomi.domain.library.service.LibraryPreferences.Companion.ENTRY_NON_C
import tachiyomi.domain.library.service.LibraryPreferences.Companion.ENTRY_NON_VIEWED
import tachiyomi.domain.library.service.LibraryPreferences.Companion.ENTRY_OUTSIDE_RELEASE_PERIOD
import tachiyomi.presentation.core.components.WheelTextPicker
import tachiyomi.presentation.core.util.collectAsState
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get

View file

@ -24,7 +24,6 @@ import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow
import eu.kanade.domain.base.BasePreferences
import eu.kanade.presentation.more.settings.Preference
import eu.kanade.presentation.util.collectAsState
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.player.JUST_PLAYER
import eu.kanade.tachiyomi.ui.player.MPV_PLAYER
@ -38,6 +37,7 @@ import eu.kanade.tachiyomi.ui.player.WEB_VIDEO_CASTER
import eu.kanade.tachiyomi.ui.player.X_PLAYER
import eu.kanade.tachiyomi.ui.player.settings.PlayerPreferences
import tachiyomi.presentation.core.components.WheelTextPicker
import tachiyomi.presentation.core.util.collectAsState
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get

View file

@ -9,12 +9,12 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.stringResource
import eu.kanade.presentation.more.settings.Preference
import eu.kanade.presentation.util.collectAsState
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.reader.setting.OrientationType
import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences
import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType
import eu.kanade.tachiyomi.util.system.isReleaseBuildType
import tachiyomi.presentation.core.util.collectAsState
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.text.NumberFormat

View file

@ -10,11 +10,11 @@ import androidx.compose.ui.res.pluralStringResource
import androidx.compose.ui.res.stringResource
import androidx.fragment.app.FragmentActivity
import eu.kanade.presentation.more.settings.Preference
import eu.kanade.presentation.util.collectAsState
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.core.security.SecurityPreferences
import eu.kanade.tachiyomi.util.system.AuthenticatorUtil.authenticate
import eu.kanade.tachiyomi.util.system.AuthenticatorUtil.isAuthenticationSupported
import tachiyomi.presentation.core.util.collectAsState
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get

View file

@ -11,14 +11,13 @@ import androidx.core.graphics.alpha
import androidx.core.graphics.blue
import androidx.core.graphics.green
import androidx.core.graphics.red
import eu.kanade.presentation.util.collectAsState
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences
import eu.kanade.tachiyomi.ui.reader.setting.ReaderSettingsScreenModel
import tachiyomi.core.preference.getAndSet
import tachiyomi.presentation.core.components.CheckboxItem
import tachiyomi.presentation.core.components.SettingsChipRow
import tachiyomi.presentation.core.components.SliderItem
import tachiyomi.presentation.core.util.collectAsState
@Composable
internal fun ColumnScope.ColorFilterPage(screenModel: ReaderSettingsScreenModel) {
@ -44,10 +43,7 @@ internal fun ColumnScope.ColorFilterPage(screenModel: ReaderSettingsScreenModel)
val customBrightness by screenModel.preferences.customBrightness().collectAsState()
CheckboxItem(
label = stringResource(R.string.pref_custom_brightness),
checked = customBrightness,
onClick = {
screenModel.togglePreference(ReaderPreferences::customBrightness)
},
pref = screenModel.preferences.customBrightness(),
)
/**
@ -71,10 +67,7 @@ internal fun ColumnScope.ColorFilterPage(screenModel: ReaderSettingsScreenModel)
val colorFilter by screenModel.preferences.colorFilter().collectAsState()
CheckboxItem(
label = stringResource(R.string.pref_custom_color_filter),
checked = colorFilter,
onClick = {
screenModel.togglePreference(ReaderPreferences::colorFilter)
},
pref = screenModel.preferences.colorFilter(),
)
if (colorFilter) {
val colorFilterValue by screenModel.preferences.colorFilterValue().collectAsState()
@ -135,21 +128,13 @@ internal fun ColumnScope.ColorFilterPage(screenModel: ReaderSettingsScreenModel)
}
}
val grayscale by screenModel.preferences.grayscale().collectAsState()
CheckboxItem(
label = stringResource(R.string.pref_grayscale),
checked = grayscale,
onClick = {
screenModel.togglePreference(ReaderPreferences::grayscale)
},
pref = screenModel.preferences.grayscale(),
)
val invertedColors by screenModel.preferences.invertedColors().collectAsState()
CheckboxItem(
label = stringResource(R.string.pref_inverted_colors),
checked = invertedColors,
onClick = {
screenModel.togglePreference(ReaderPreferences::invertedColors)
},
pref = screenModel.preferences.invertedColors(),
)
}

View file

@ -6,12 +6,11 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.res.stringResource
import eu.kanade.presentation.util.collectAsState
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences
import eu.kanade.tachiyomi.ui.reader.setting.ReaderSettingsScreenModel
import tachiyomi.presentation.core.components.CheckboxItem
import tachiyomi.presentation.core.components.SettingsChipRow
import tachiyomi.presentation.core.util.collectAsState
private val themes = listOf(
R.string.black_background to 1,
@ -33,67 +32,39 @@ internal fun ColumnScope.GeneralPage(screenModel: ReaderSettingsScreenModel) {
}
}
val showPageNumber by screenModel.preferences.showPageNumber().collectAsState()
CheckboxItem(
label = stringResource(R.string.pref_show_page_number),
checked = showPageNumber,
onClick = {
screenModel.togglePreference(ReaderPreferences::showPageNumber)
},
pref = screenModel.preferences.showPageNumber(),
)
val fullscreen by screenModel.preferences.fullscreen().collectAsState()
CheckboxItem(
label = stringResource(R.string.pref_fullscreen),
checked = fullscreen,
onClick = {
screenModel.togglePreference(ReaderPreferences::fullscreen)
},
pref = screenModel.preferences.fullscreen(),
)
// TODO: hide if there's no cutout
val cutoutShort by screenModel.preferences.cutoutShort().collectAsState()
CheckboxItem(
label = stringResource(R.string.pref_cutout_short),
checked = cutoutShort,
onClick = {
screenModel.togglePreference(ReaderPreferences::cutoutShort)
},
pref = screenModel.preferences.cutoutShort(),
)
val keepScreenOn by screenModel.preferences.keepScreenOn().collectAsState()
CheckboxItem(
label = stringResource(R.string.pref_keep_screen_on),
checked = keepScreenOn,
onClick = {
screenModel.togglePreference(ReaderPreferences::keepScreenOn)
},
pref = screenModel.preferences.keepScreenOn(),
)
val readWithLongTap by screenModel.preferences.readWithLongTap().collectAsState()
CheckboxItem(
label = stringResource(R.string.pref_read_with_long_tap),
checked = readWithLongTap,
onClick = {
screenModel.togglePreference(ReaderPreferences::readWithLongTap)
},
pref = screenModel.preferences.readWithLongTap(),
)
val alwaysShowChapterTransition by screenModel.preferences.alwaysShowChapterTransition().collectAsState()
CheckboxItem(
label = stringResource(R.string.pref_always_show_chapter_transition),
checked = alwaysShowChapterTransition,
onClick = {
screenModel.togglePreference(ReaderPreferences::alwaysShowChapterTransition)
},
pref = screenModel.preferences.alwaysShowChapterTransition(),
)
val pageTransitions by screenModel.preferences.pageTransitions().collectAsState()
CheckboxItem(
label = stringResource(R.string.pref_page_transitions),
checked = pageTransitions,
onClick = {
screenModel.togglePreference(ReaderPreferences::pageTransitions)
},
pref = screenModel.preferences.pageTransitions(),
)
}

View file

@ -10,7 +10,6 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.res.stringResource
import eu.kanade.domain.entries.manga.model.orientationType
import eu.kanade.domain.entries.manga.model.readingModeType
import eu.kanade.presentation.util.collectAsState
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.reader.setting.OrientationType
import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences
@ -22,6 +21,7 @@ import tachiyomi.presentation.core.components.CheckboxItem
import tachiyomi.presentation.core.components.HeadingItem
import tachiyomi.presentation.core.components.SettingsChipRow
import tachiyomi.presentation.core.components.SliderItem
import tachiyomi.presentation.core.util.collectAsState
import java.text.NumberFormat
private val readingModeOptions = ReadingModeType.entries.map { it.stringRes to it }
@ -98,70 +98,44 @@ private fun ColumnScope.PagerViewerSettings(screenModel: ReaderSettingsScreenMod
}
}
val cropBorders by screenModel.preferences.cropBorders().collectAsState()
CheckboxItem(
label = stringResource(R.string.pref_crop_borders),
checked = cropBorders,
onClick = {
screenModel.togglePreference(ReaderPreferences::cropBorders)
},
pref = screenModel.preferences.cropBorders(),
)
val landscapeZoom by screenModel.preferences.landscapeZoom().collectAsState()
CheckboxItem(
label = stringResource(R.string.pref_landscape_zoom),
checked = landscapeZoom,
onClick = {
screenModel.togglePreference(ReaderPreferences::landscapeZoom)
},
pref = screenModel.preferences.landscapeZoom(),
)
val navigateToPan by screenModel.preferences.navigateToPan().collectAsState()
CheckboxItem(
label = stringResource(R.string.pref_navigate_pan),
checked = navigateToPan,
onClick = {
screenModel.togglePreference(ReaderPreferences::navigateToPan)
},
pref = screenModel.preferences.navigateToPan(),
)
val dualPageSplitPaged by screenModel.preferences.dualPageSplitPaged().collectAsState()
CheckboxItem(
label = stringResource(R.string.pref_dual_page_split),
checked = dualPageSplitPaged,
onClick = {
screenModel.togglePreference(ReaderPreferences::dualPageSplitPaged)
},
pref = screenModel.preferences.dualPageInvertPaged(),
)
if (dualPageSplitPaged) {
val dualPageInvertPaged by screenModel.preferences.dualPageInvertPaged().collectAsState()
CheckboxItem(
label = stringResource(R.string.pref_dual_page_invert),
checked = dualPageInvertPaged,
onClick = {
screenModel.togglePreference(ReaderPreferences::dualPageInvertPaged)
},
pref = screenModel.preferences.dualPageRotateToFitInvert(),
)
}
val dualPageRotateToFit by screenModel.preferences.dualPageRotateToFit().collectAsState()
CheckboxItem(
label = stringResource(R.string.pref_page_rotate),
checked = dualPageRotateToFit,
onClick = {
screenModel.togglePreference(ReaderPreferences::dualPageRotateToFit)
},
pref = screenModel.preferences.dualPageRotateToFit(),
)
if (dualPageRotateToFit) {
val dualPageRotateToFitInvert by screenModel.preferences.dualPageRotateToFitInvert().collectAsState()
CheckboxItem(
label = stringResource(R.string.pref_page_rotate_invert),
checked = dualPageRotateToFitInvert,
onClick = {
screenModel.togglePreference(ReaderPreferences::dualPageRotateToFitInvert)
},
pref = screenModel.preferences.dualPageRotateToFitInvert(),
)
}
}
@ -193,55 +167,34 @@ private fun ColumnScope.WebtoonViewerSettings(screenModel: ReaderSettingsScreenM
},
)
val cropBordersWebtoon by screenModel.preferences.cropBordersWebtoon().collectAsState()
CheckboxItem(
label = stringResource(R.string.pref_crop_borders),
checked = cropBordersWebtoon,
onClick = {
screenModel.togglePreference(ReaderPreferences::cropBordersWebtoon)
},
pref = screenModel.preferences.cropBordersWebtoon(),
)
val dualPageSplitWebtoon by screenModel.preferences.dualPageSplitWebtoon().collectAsState()
CheckboxItem(
label = stringResource(R.string.pref_dual_page_split),
checked = dualPageSplitWebtoon,
onClick = {
screenModel.togglePreference(ReaderPreferences::dualPageSplitWebtoon)
},
pref = screenModel.preferences.dualPageSplitWebtoon(),
)
if (dualPageSplitWebtoon) {
val dualPageInvertWebtoon by screenModel.preferences.dualPageInvertWebtoon()
.collectAsState()
CheckboxItem(
label = stringResource(R.string.pref_dual_page_invert),
checked = dualPageInvertWebtoon,
onClick = {
screenModel.togglePreference(ReaderPreferences::dualPageInvertWebtoon)
},
pref = screenModel.preferences.dualPageInvertWebtoon(),
)
}
if (!isReleaseBuildType) {
val longStripSplitWebtoon by screenModel.preferences.longStripSplitWebtoon()
.collectAsState()
CheckboxItem(
label = stringResource(R.string.pref_long_strip_split),
checked = longStripSplitWebtoon,
onClick = {
screenModel.togglePreference(ReaderPreferences::longStripSplitWebtoon)
},
pref = screenModel.preferences.longStripSplitWebtoon(),
)
}
val webtoonDoubleTapZoomEnabled by screenModel.preferences.webtoonDoubleTapZoomEnabled().collectAsState()
CheckboxItem(
label = stringResource(R.string.pref_double_tap_zoom),
checked = webtoonDoubleTapZoomEnabled,
onClick = {
screenModel.togglePreference(ReaderPreferences::webtoonDoubleTapZoomEnabled)
},
pref = screenModel.preferences.webtoonDoubleTapZoomEnabled(),
)
}

View file

@ -0,0 +1,17 @@
package eu.kanade.presentation.util
import java.text.DecimalFormat
import java.text.DecimalFormatSymbols
private val formatter = DecimalFormat(
"#.###",
DecimalFormatSymbols().apply { decimalSeparator = '.' },
)
fun formatChapterNumber(chapterNumber: Float): String {
return formatter.format(chapterNumber)
}
fun formatEpisodeNumber(episodeNumber: Float): String {
return formatter.format(episodeNumber)
}

View file

@ -16,8 +16,6 @@ import eu.kanade.tachiyomi.network.PREF_DOH_CLOUDFLARE
import eu.kanade.tachiyomi.ui.player.settings.PlayerPreferences
import eu.kanade.tachiyomi.ui.reader.setting.OrientationType
import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences
import eu.kanade.tachiyomi.util.preference.minusAssign
import eu.kanade.tachiyomi.util.preference.plusAssign
import eu.kanade.tachiyomi.util.system.DeviceUtil
import eu.kanade.tachiyomi.util.system.isReleaseBuildType
import eu.kanade.tachiyomi.util.system.toast
@ -25,6 +23,8 @@ import eu.kanade.tachiyomi.util.system.workManager
import tachiyomi.core.preference.PreferenceStore
import tachiyomi.core.preference.TriState
import tachiyomi.core.preference.getEnum
import tachiyomi.core.preference.minusAssign
import tachiyomi.core.preference.plusAssign
import tachiyomi.domain.backup.service.BackupPreferences
import tachiyomi.domain.library.service.LibraryPreferences
import tachiyomi.domain.library.service.LibraryPreferences.Companion.ENTRY_NON_COMPLETED

View file

@ -131,9 +131,9 @@ class BackupManager(
backupAnimes(databaseAnime, flags),
backupAnimeCategories(flags),
emptyList(),
backupExtensionInfo(databaseManga),
prepExtensionInfoForSync(databaseManga),
emptyList(),
backupAnimeExtensionInfo(databaseAnime),
prepAnimeExtensionInfoForSync(databaseAnime),
backupPreferences(prefs, flags),
backupExtensionPreferences(flags),
backupExtensions(flags),
@ -190,7 +190,7 @@ class BackupManager(
}
}
private fun backupExtensionInfo(mangas: List<Manga>): List<BackupSource> {
fun prepExtensionInfoForSync(mangas: List<Manga>): List<BackupSource> {
return mangas
.asSequence()
.map(Manga::source)
@ -200,7 +200,7 @@ class BackupManager(
.toList()
}
private fun backupAnimeExtensionInfo(animes: List<Anime>): List<BackupAnimeSource> {
fun prepAnimeExtensionInfoForSync(animes: List<Anime>): List<BackupAnimeSource> {
return animes
.asSequence()
.map(Anime::source)
@ -215,7 +215,7 @@ class BackupManager(
*
* @return list of [BackupCategory] to be backed up
*/
private suspend fun backupCategories(options: Int): List<BackupCategory> {
suspend fun backupCategories(options: Int): List<BackupCategory> {
// Check if user wants category information in backup
return if (options and BACKUP_CATEGORY_MASK == BACKUP_CATEGORY) {
getMangaCategories.await()
@ -231,7 +231,7 @@ class BackupManager(
*
* @return list of [BackupCategory] to be backed up
*/
private suspend fun backupAnimeCategories(options: Int): List<BackupCategory> {
suspend fun backupAnimeCategories(options: Int): List<BackupCategory> {
// Check if user wants category information in backup
return if (options and BACKUP_CATEGORY_MASK == BACKUP_CATEGORY) {
getAnimeCategories.await()
@ -242,13 +242,13 @@ class BackupManager(
}
}
private suspend fun backupMangas(mangas: List<Manga>, flags: Int): List<BackupManga> {
suspend fun backupMangas(mangas: List<Manga>, flags: Int): List<BackupManga> {
return mangas.map {
backupManga(it, flags)
}
}
private suspend fun backupAnimes(animes: List<Anime>, flags: Int): List<BackupAnime> {
suspend fun backupAnimes(animes: List<Anime>, flags: Int): List<BackupAnime> {
return animes.map {
backupAnime(it, flags)
}

View file

@ -79,9 +79,9 @@ class BackupNotifier(private val context: Context) {
}
}
fun showRestoreProgress(content: String = "", progress: Int = 0, maxAmount: Int = 100): NotificationCompat.Builder {
fun showRestoreProgress(content: String = "", contentTitle: String = context.getString(R.string.restoring_backup), progress: Int = 0, maxAmount: Int = 100): NotificationCompat.Builder {
val builder = with(progressNotificationBuilder) {
setContentTitle(context.getString(R.string.restoring_backup))
setContentTitle(contentTitle)
if (!preferences.hideNotificationContent().get()) {
setContentText(content)
@ -114,7 +114,7 @@ class BackupNotifier(private val context: Context) {
}
}
fun showRestoreComplete(time: Long, errorCount: Int, path: String?, file: String?) {
fun showRestoreComplete(time: Long, errorCount: Int, path: String?, file: String?, contentTitle: String = context.getString(R.string.restore_completed)) {
context.cancelNotification(Notifications.ID_RESTORE_PROGRESS)
val timeString = context.getString(
@ -126,7 +126,7 @@ class BackupNotifier(private val context: Context) {
)
with(completeNotificationBuilder) {
setContentTitle(context.getString(R.string.restore_completed))
setContentTitle(contentTitle)
setContentText(context.resources.getQuantityString(R.plurals.restore_completed_message, errorCount, timeString, errorCount))
clearActions()

View file

@ -26,6 +26,7 @@ class BackupRestoreJob(private val context: Context, workerParams: WorkerParamet
override suspend fun doWork(): Result {
val uri = inputData.getString(LOCATION_URI_KEY)?.toUri()
?: return Result.failure()
val sync = inputData.getBoolean(SYNC, false)
try {
setForeground(getForegroundInfo())
@ -35,7 +36,7 @@ class BackupRestoreJob(private val context: Context, workerParams: WorkerParamet
return try {
val restorer = BackupRestorer(context, notifier)
restorer.restoreBackup(uri)
restorer.syncFromBackup(uri, sync)
Result.success()
} catch (e: Exception) {
if (e is CancellationException) {
@ -63,9 +64,10 @@ class BackupRestoreJob(private val context: Context, workerParams: WorkerParamet
return context.workManager.isRunning(TAG)
}
fun start(context: Context, uri: Uri) {
fun start(context: Context, uri: Uri, sync: Boolean = false) {
val inputData = workDataOf(
LOCATION_URI_KEY to uri.toString(),
SYNC to sync,
)
val request = OneTimeWorkRequestBuilder<BackupRestoreJob>()
.addTag(TAG)
@ -83,3 +85,5 @@ class BackupRestoreJob(private val context: Context, workerParams: WorkerParamet
private const val TAG = "BackupRestore"
private const val LOCATION_URI_KEY = "location_uri" // String
private const val SYNC = "sync" // Boolean

View file

@ -57,12 +57,12 @@ class BackupRestorer(
private val errors = mutableListOf<Pair<Date, String>>()
suspend fun restoreBackup(uri: Uri): Boolean {
suspend fun syncFromBackup(uri: Uri, sync: Boolean): Boolean {
val startTime = System.currentTimeMillis()
restoreProgress = 0
errors.clear()
if (!performRestore(uri)) {
if (!performRestore(uri, sync)) {
return false
}
@ -71,7 +71,11 @@ class BackupRestorer(
val logFile = writeErrorLog()
notifier.showRestoreComplete(time, errors.size, logFile.parent, logFile.name)
if (sync) {
notifier.showRestoreComplete(time, errors.size, logFile.parent, logFile.name, contentTitle = context.getString(R.string.library_sync_complete))
} else {
notifier.showRestoreComplete(time, errors.size, logFile.parent, logFile.name)
}
return true
}
@ -95,7 +99,7 @@ class BackupRestorer(
}
@Suppress("BlockingMethodInNonBlockingContext")
private suspend fun performRestore(uri: Uri): Boolean {
private suspend fun performRestore(uri: Uri, sync: Boolean): Boolean {
val backup = BackupUtil.decodeBackup(context, uri)
restoreAmount = backup.backupManga.size + backup.backupAnime.size + 2 // +2 for categories
@ -123,7 +127,7 @@ class BackupRestorer(
return@coroutineScope false
}
restoreManga(it, backup.backupCategories)
restoreManga(it, backup.backupCategories, sync)
}
backup.backupAnime.forEach {
@ -131,7 +135,7 @@ class BackupRestorer(
return@coroutineScope false
}
restoreAnime(it, backup.backupAnimeCategories)
restoreAnime(it, backup.backupAnimeCategories, sync)
}
if (backup.backupPreferences.isNotEmpty()) {
@ -158,17 +162,17 @@ class BackupRestorer(
backupManager.restoreCategories(backupCategories)
restoreProgress += 1
showRestoreProgress(restoreProgress, restoreAmount, context.getString(R.string.manga_categories))
showRestoreProgress(restoreProgress, restoreAmount, context.getString(R.string.manga_categories), context.getString(R.string.restoring_backup))
}
private suspend fun restoreAnimeCategories(backupCategories: List<BackupCategory>) {
backupManager.restoreAnimeCategories(backupCategories)
restoreProgress += 1
showRestoreProgress(restoreProgress, restoreAmount, context.getString(R.string.anime_categories))
showRestoreProgress(restoreProgress, restoreAmount, context.getString(R.string.anime_categories), context.getString(R.string.restoring_backup))
}
private suspend fun restoreManga(backupManga: BackupManga, backupCategories: List<BackupCategory>) {
private suspend fun restoreManga(backupManga: BackupManga, backupCategories: List<BackupCategory>, sync: Boolean) {
val manga = backupManga.getMangaImpl()
val chapters = backupManga.getChaptersImpl()
val categories = backupManga.categories.map { it.toInt() }
@ -194,7 +198,11 @@ class BackupRestorer(
}
restoreProgress += 1
showRestoreProgress(restoreProgress, restoreAmount, manga.title)
if (sync) {
showRestoreProgress(restoreProgress, restoreAmount, manga.title, context.getString(R.string.syncing_library))
} else {
showRestoreProgress(restoreProgress, restoreAmount, manga.title, context.getString(R.string.restoring_backup))
}
}
/**
@ -235,7 +243,7 @@ class BackupRestorer(
backupManager.restoreTracking(manga, tracks)
}
private suspend fun restoreAnime(backupAnime: BackupAnime, backupCategories: List<BackupCategory>) {
private suspend fun restoreAnime(backupAnime: BackupAnime, backupCategories: List<BackupCategory>, sync: Boolean) {
val anime = backupAnime.getAnimeImpl()
val episodes = backupAnime.getEpisodesImpl()
val categories = backupAnime.categories.map { it.toInt() }
@ -261,7 +269,11 @@ class BackupRestorer(
}
restoreProgress += 1
showRestoreProgress(restoreProgress, restoreAmount, anime.title)
if (sync) {
showRestoreProgress(restoreProgress, restoreAmount, anime.title, context.getString(R.string.syncing_library))
} else {
showRestoreProgress(restoreProgress, restoreAmount, anime.title, context.getString(R.string.restoring_backup))
}
}
/**
@ -368,7 +380,7 @@ class BackupRestorer(
* @param amount total restoreAmount of anime and manga
* @param title title of restored anime and manga
*/
private fun showRestoreProgress(progress: Int, amount: Int, title: String) {
notifier.showRestoreProgress(title, progress, amount)
private fun showRestoreProgress(progress: Int, amount: Int, title: String, contentTitle: String) {
notifier.showRestoreProgress(title, contentTitle, progress, amount)
}
}

View file

@ -13,6 +13,7 @@ import androidx.core.app.NotificationManagerCompat
import coil.imageLoader
import coil.request.ImageRequest
import coil.transform.CircleCropTransformation
import eu.kanade.presentation.util.formatEpisodeNumber
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.core.Constants
import eu.kanade.tachiyomi.core.security.SecurityPreferences
@ -29,8 +30,6 @@ import tachiyomi.core.util.lang.launchUI
import tachiyomi.domain.entries.anime.model.Anime
import tachiyomi.domain.items.episode.model.Episode
import uy.kohesive.injekt.injectLazy
import java.text.DecimalFormat
import java.text.DecimalFormatSymbols
class AnimeLibraryUpdateNotifier(private val context: Context) {
@ -279,16 +278,10 @@ class AnimeLibraryUpdateNotifier(private val context: Context) {
}
private fun getNewEpisodesDescription(episodes: Array<Episode>): String {
val formatter = DecimalFormat(
"#.###",
DecimalFormatSymbols()
.apply { decimalSeparator = '.' },
)
val displayableEpisodeNumbers = episodes
.filter { it.isRecognizedNumber }
.sortedBy { it.episodeNumber }
.map { formatter.format(it.episodeNumber) }
.map { formatEpisodeNumber(it.episodeNumber) }
.toSet()
return when (displayableEpisodeNumbers.size) {

View file

@ -13,6 +13,7 @@ import androidx.core.app.NotificationManagerCompat
import coil.imageLoader
import coil.request.ImageRequest
import coil.transform.CircleCropTransformation
import eu.kanade.presentation.util.formatChapterNumber
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.core.Constants
import eu.kanade.tachiyomi.core.security.SecurityPreferences
@ -29,8 +30,6 @@ import tachiyomi.core.util.lang.launchUI
import tachiyomi.domain.entries.manga.model.Manga
import tachiyomi.domain.items.chapter.model.Chapter
import uy.kohesive.injekt.injectLazy
import java.text.DecimalFormat
import java.text.DecimalFormatSymbols
class MangaLibraryUpdateNotifier(private val context: Context) {
@ -288,16 +287,10 @@ class MangaLibraryUpdateNotifier(private val context: Context) {
}
private fun getNewChaptersDescription(chapters: Array<Chapter>): String {
val formatter = DecimalFormat(
"#.###",
DecimalFormatSymbols()
.apply { decimalSeparator = '.' },
)
val displayableChapterNumbers = chapters
.filter { it.isRecognizedNumber }
.sortedBy { it.chapterNumber }
.map { formatter.format(it.chapterNumber) }
.map { formatChapterNumber(it.chapterNumber) }
.toSet()
return when (displayableChapterNumbers.size) {

View file

@ -61,7 +61,7 @@ interface AnimeTrackService {
val hasSeenEpisodes = allEpisodes.any { it.seen }
bind(item, hasSeenEpisodes)
val track = item.toDomainTrack(idRequired = false) ?: return@withIOContext
var track = item.toDomainTrack(idRequired = false) ?: return@withIOContext
Injekt.get<InsertAnimeTrack>().await(track)
@ -74,10 +74,10 @@ interface AnimeTrackService {
?.episodeNumber?.toDouble() ?: -1.0
if (latestLocalSeenEpisodeNumber > track.lastEpisodeSeen) {
val updatedTrack = track.copy(
track = track.copy(
lastEpisodeSeen = latestLocalSeenEpisodeNumber,
)
setRemoteLastEpisodeSeen(updatedTrack.toDbTrack(), latestLocalSeenEpisodeNumber.toInt())
setRemoteLastEpisodeSeen(track.toDbTrack(), latestLocalSeenEpisodeNumber.toInt())
}
if (track.startDate <= 0) {
@ -91,6 +91,9 @@ interface AnimeTrackService {
ZoneOffset.systemDefault(),
ZoneOffset.UTC,
)
track = track.copy(
startDate = startDate,
)
setRemoteStartDate(track.toDbTrack(), startDate)
}
}

View file

@ -61,7 +61,7 @@ interface MangaTrackService {
val hasReadChapters = allChapters.any { it.read }
bind(item, hasReadChapters)
val track = item.toDomainTrack(idRequired = false) ?: return@withIOContext
var track = item.toDomainTrack(idRequired = false) ?: return@withIOContext
Injekt.get<InsertMangaTrack>().await(track)
@ -74,10 +74,10 @@ interface MangaTrackService {
?.chapterNumber?.toDouble() ?: -1.0
if (latestLocalReadChapterNumber > track.lastChapterRead) {
val updatedTrack = track.copy(
track = track.copy(
lastChapterRead = latestLocalReadChapterNumber,
)
setRemoteLastChapterRead(updatedTrack.toDbTrack(), latestLocalReadChapterNumber.toInt())
setRemoteLastChapterRead(track.toDbTrack(), latestLocalReadChapterNumber.toInt())
}
if (track.startDate <= 0) {
@ -91,6 +91,9 @@ interface MangaTrackService {
ZoneOffset.systemDefault(),
ZoneOffset.UTC,
)
track = track.copy(
startDate = startDate,
)
setRemoteStartDate(track.toDbTrack(), startDate)
}
}

View file

@ -11,8 +11,6 @@ import eu.kanade.tachiyomi.extension.anime.model.AnimeLoadResult
import eu.kanade.tachiyomi.extension.anime.util.AnimeExtensionInstallReceiver
import eu.kanade.tachiyomi.extension.anime.util.AnimeExtensionInstaller
import eu.kanade.tachiyomi.extension.anime.util.AnimeExtensionLoader
import eu.kanade.tachiyomi.source.anime.toStubSource
import eu.kanade.tachiyomi.util.preference.plusAssign
import eu.kanade.tachiyomi.util.system.toast
import kotlinx.coroutines.async
import kotlinx.coroutines.flow.Flow
@ -20,6 +18,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.emptyFlow
import logcat.LogPriority
import tachiyomi.core.preference.plusAssign
import tachiyomi.core.util.lang.launchNow
import tachiyomi.core.util.lang.withUIContext
import tachiyomi.core.util.system.logcat

View file

@ -11,8 +11,6 @@ import eu.kanade.tachiyomi.extension.manga.model.MangaLoadResult
import eu.kanade.tachiyomi.extension.manga.util.MangaExtensionInstallReceiver
import eu.kanade.tachiyomi.extension.manga.util.MangaExtensionInstaller
import eu.kanade.tachiyomi.extension.manga.util.MangaExtensionLoader
import eu.kanade.tachiyomi.source.manga.toStubSource
import eu.kanade.tachiyomi.util.preference.plusAssign
import eu.kanade.tachiyomi.util.system.toast
import kotlinx.coroutines.async
import kotlinx.coroutines.flow.Flow
@ -20,6 +18,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.emptyFlow
import logcat.LogPriority
import tachiyomi.core.preference.plusAssign
import tachiyomi.core.util.lang.launchNow
import tachiyomi.core.util.lang.withUIContext
import tachiyomi.core.util.system.logcat

View file

@ -34,6 +34,7 @@ import eu.kanade.presentation.entries.anime.EpisodeSettingsDialog
import eu.kanade.presentation.entries.anime.components.AnimeCoverDialog
import eu.kanade.presentation.util.AssistContentScreen
import eu.kanade.presentation.util.Screen
import eu.kanade.presentation.util.formatEpisodeNumber
import eu.kanade.presentation.util.isTabletUi
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.animesource.AnimeSource
@ -76,7 +77,7 @@ class AnimeScreen(
val context = LocalContext.current
val haptic = LocalHapticFeedback.current
val scope = rememberCoroutineScope()
val screenModel = rememberScreenModel { AnimeInfoScreenModel(context, animeId, fromSource) }
val screenModel = rememberScreenModel { AnimeScreenModel(context, animeId, fromSource) }
val state by screenModel.state.collectAsState()
@ -160,7 +161,7 @@ class AnimeScreen(
}
when (val dialog = successState.dialog) {
null -> {}
is AnimeInfoScreenModel.Dialog.ChangeCategory -> {
is AnimeScreenModel.Dialog.ChangeCategory -> {
ChangeCategoryDialog(
initialSelection = dialog.initialSelection,
onDismissRequest = onDismissRequest,
@ -170,7 +171,7 @@ class AnimeScreen(
},
)
}
is AnimeInfoScreenModel.Dialog.DeleteEpisodes -> {
is AnimeScreenModel.Dialog.DeleteEpisodes -> {
DeleteItemsDialog(
onDismissRequest = onDismissRequest,
onConfirm = {
@ -180,12 +181,12 @@ class AnimeScreen(
isManga = false,
)
}
is AnimeInfoScreenModel.Dialog.DuplicateAnime -> DuplicateAnimeDialog(
is AnimeScreenModel.Dialog.DuplicateAnime -> DuplicateAnimeDialog(
onDismissRequest = onDismissRequest,
onConfirm = { screenModel.toggleFavorite(onRemoved = {}, checkDuplicate = false) },
onOpenAnime = { navigator.push(AnimeScreen(dialog.duplicate.id)) },
)
AnimeInfoScreenModel.Dialog.SettingsSheet -> EpisodeSettingsDialog(
AnimeScreenModel.Dialog.SettingsSheet -> EpisodeSettingsDialog(
onDismissRequest = onDismissRequest,
anime = successState.anime,
onDownloadFilterChanged = screenModel::setDownloadedFilter,
@ -195,7 +196,7 @@ class AnimeScreen(
onDisplayModeChanged = screenModel::setDisplayMode,
onSetAsDefault = screenModel::setCurrentSettingsAsDefault,
)
AnimeInfoScreenModel.Dialog.TrackSheet -> {
AnimeScreenModel.Dialog.TrackSheet -> {
NavigatorAdaptiveSheet(
screen = AnimeTrackInfoDialogHomeScreen(
animeId = successState.anime.id,
@ -206,7 +207,7 @@ class AnimeScreen(
onDismissRequest = onDismissRequest,
)
}
AnimeInfoScreenModel.Dialog.FullCover -> {
AnimeScreenModel.Dialog.FullCover -> {
val sm = rememberScreenModel { AnimeCoverScreenModel(successState.anime.id) }
val anime by sm.state.collectAsState()
if (anime != null) {
@ -232,7 +233,7 @@ class AnimeScreen(
LoadingScreen(Modifier.systemBarsPadding())
}
}
AnimeInfoScreenModel.Dialog.ChangeAnimeSkipIntro -> {
AnimeScreenModel.Dialog.ChangeAnimeSkipIntro -> {
fun updateSkipIntroLength(newLength: Long) {
scope.launchIO {
screenModel.setAnimeViewerFlags.awaitSetSkipIntroLength(animeId, newLength)
@ -246,12 +247,12 @@ class AnimeScreen(
onDismissRequest = onDismissRequest,
)
}
is AnimeInfoScreenModel.Dialog.ShowQualities -> {
is AnimeScreenModel.Dialog.ShowQualities -> {
EpisodeOptionsDialogScreen.onDismissDialog = onDismissRequest
val episodeTitle = if (dialog.anime.displayMode == Anime.EPISODE_DISPLAY_NUMBER) {
stringResource(
R.string.display_mode_episode,
episodeDecimalFormat.format(dialog.episode.episodeNumber.toDouble()),
formatEpisodeNumber(dialog.episode.episodeNumber),
)
} else {
dialog.episode.name

View file

@ -78,11 +78,9 @@ import tachiyomi.domain.track.anime.interactor.GetAnimeTracks
import tachiyomi.source.local.entries.anime.isLocal
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.text.DecimalFormat
import java.text.DecimalFormatSymbols
import java.util.Calendar
class AnimeInfoScreenModel(
class AnimeScreenModel(
val context: Context,
val animeId: Long,
private val isFromSource: Boolean,
@ -1023,7 +1021,7 @@ sealed class AnimeScreenState {
val episodes: List<EpisodeItem>,
val trackItems: List<AnimeTrackItem> = emptyList(),
val isRefreshingData: Boolean = false,
val dialog: AnimeInfoScreenModel.Dialog? = null,
val dialog: AnimeScreenModel.Dialog? = null,
val hasPromptedToAddBefore: Boolean = false,
val nextAiringEpisode: Pair<Int, Long> = Pair(anime.nextEpisodeToAir, anime.nextEpisodeAiringAt),
) : AnimeScreenState() {
@ -1071,9 +1069,3 @@ data class EpisodeItem(
) {
val isDownloaded = downloadState == AnimeDownload.State.DOWNLOADED
}
val episodeDecimalFormat = DecimalFormat(
"#.###",
DecimalFormatSymbols()
.apply { decimalSeparator = '.' },
)

View file

@ -72,7 +72,7 @@ class MangaScreen(
val context = LocalContext.current
val haptic = LocalHapticFeedback.current
val scope = rememberCoroutineScope()
val screenModel = rememberScreenModel { MangaInfoScreenModel(context, mangaId, fromSource) }
val screenModel = rememberScreenModel { MangaScreenModel(context, mangaId, fromSource) }
val state by screenModel.state.collectAsState()
@ -143,7 +143,7 @@ class MangaScreen(
}
when (val dialog = successState.dialog) {
null -> {}
is MangaInfoScreenModel.Dialog.ChangeCategory -> {
is MangaScreenModel.Dialog.ChangeCategory -> {
ChangeCategoryDialog(
initialSelection = dialog.initialSelection,
onDismissRequest = onDismissRequest,
@ -153,7 +153,7 @@ class MangaScreen(
},
)
}
is MangaInfoScreenModel.Dialog.DeleteChapters -> {
is MangaScreenModel.Dialog.DeleteChapters -> {
DeleteItemsDialog(
onDismissRequest = onDismissRequest,
onConfirm = {
@ -163,12 +163,12 @@ class MangaScreen(
isManga = true,
)
}
is MangaInfoScreenModel.Dialog.DuplicateManga -> DuplicateMangaDialog(
is MangaScreenModel.Dialog.DuplicateManga -> DuplicateMangaDialog(
onDismissRequest = onDismissRequest,
onConfirm = { screenModel.toggleFavorite(onRemoved = {}, checkDuplicate = false) },
onOpenManga = { navigator.push(MangaScreen(dialog.duplicate.id)) },
)
MangaInfoScreenModel.Dialog.SettingsSheet -> ChapterSettingsDialog(
MangaScreenModel.Dialog.SettingsSheet -> ChapterSettingsDialog(
onDismissRequest = onDismissRequest,
manga = successState.manga,
onDownloadFilterChanged = screenModel::setDownloadedFilter,
@ -178,7 +178,7 @@ class MangaScreen(
onDisplayModeChanged = screenModel::setDisplayMode,
onSetAsDefault = screenModel::setCurrentSettingsAsDefault,
)
MangaInfoScreenModel.Dialog.TrackSheet -> {
MangaScreenModel.Dialog.TrackSheet -> {
NavigatorAdaptiveSheet(
screen = MangaTrackInfoDialogHomeScreen(
mangaId = successState.manga.id,
@ -189,7 +189,7 @@ class MangaScreen(
onDismissRequest = onDismissRequest,
)
}
MangaInfoScreenModel.Dialog.FullCover -> {
MangaScreenModel.Dialog.FullCover -> {
val sm = rememberScreenModel { MangaCoverScreenModel(successState.manga.id) }
val manga by sm.state.collectAsState()
if (manga != null) {

View file

@ -75,10 +75,8 @@ import tachiyomi.domain.track.manga.interactor.GetMangaTracks
import tachiyomi.source.local.entries.manga.isLocal
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.text.DecimalFormat
import java.text.DecimalFormatSymbols
class MangaInfoScreenModel(
class MangaScreenModel(
val context: Context,
val mangaId: Long,
private val isFromSource: Boolean,
@ -997,7 +995,7 @@ sealed class MangaScreenState {
val chapters: List<ChapterItem>,
val trackItems: List<MangaTrackItem> = emptyList(),
val isRefreshingData: Boolean = false,
val dialog: MangaInfoScreenModel.Dialog? = null,
val dialog: MangaScreenModel.Dialog? = null,
val hasPromptedToAddBefore: Boolean = false,
) : MangaScreenState() {
@ -1038,9 +1036,3 @@ data class ChapterItem(
) {
val isDownloaded = downloadState == MangaDownload.State.DOWNLOADED
}
val chapterDecimalFormat = DecimalFormat(
"#.###",
DecimalFormatSymbols()
.apply { decimalSeparator = '.' },
)

View file

@ -4,7 +4,6 @@ import cafe.adriel.voyager.core.model.ScreenModel
import cafe.adriel.voyager.core.model.coroutineScope
import eu.kanade.domain.base.BasePreferences
import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.util.preference.toggle
import tachiyomi.core.preference.Preference
import tachiyomi.core.preference.TriState
import tachiyomi.core.preference.getAndSet
@ -29,10 +28,6 @@ class AnimeLibrarySettingsScreenModel(
val trackServices
get() = trackManager.services.filter { it.isLogged }
fun togglePreference(preference: (LibraryPreferences) -> Preference<Boolean>) {
preference(libraryPreferences).toggle()
}
fun toggleFilter(preference: (LibraryPreferences) -> Preference<TriState>) {
preference(libraryPreferences).getAndSet {
it.next()

View file

@ -4,7 +4,6 @@ import cafe.adriel.voyager.core.model.ScreenModel
import cafe.adriel.voyager.core.model.coroutineScope
import eu.kanade.domain.base.BasePreferences
import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.util.preference.toggle
import tachiyomi.core.preference.Preference
import tachiyomi.core.preference.TriState
import tachiyomi.core.preference.getAndSet
@ -29,10 +28,6 @@ class MangaLibrarySettingsScreenModel(
val trackServices
get() = trackManager.services.filter { it.isLogged }
fun togglePreference(preference: (LibraryPreferences) -> Preference<Boolean>) {
preference(libraryPreferences).toggle()
}
fun toggleFilter(preference: (LibraryPreferences) -> Preference<TriState>) {
preference(libraryPreferences).getAndSet {
it.next()

View file

@ -64,7 +64,6 @@ import eu.kanade.presentation.components.IncognitoModeBannerBackgroundColor
import eu.kanade.presentation.components.IndexingBannerBackgroundColor
import eu.kanade.presentation.util.AssistContentScreen
import eu.kanade.presentation.util.DefaultNavigatorScreenTransition
import eu.kanade.presentation.util.collectAsState
import eu.kanade.tachiyomi.BuildConfig
import eu.kanade.tachiyomi.Migrations
import eu.kanade.tachiyomi.R
@ -109,6 +108,7 @@ import tachiyomi.core.util.system.logcat
import tachiyomi.domain.library.service.LibraryPreferences
import tachiyomi.domain.release.interactor.GetApplicationRelease
import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.util.collectAsState
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy

View file

@ -26,14 +26,14 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import cafe.adriel.voyager.core.model.ScreenModel
import eu.kanade.presentation.util.collectAsState
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.player.settings.dialogs.PlayerDialog
import eu.kanade.tachiyomi.util.preference.toggle
import `is`.xyz.mpv.MPVLib
import tachiyomi.core.preference.Preference
import tachiyomi.core.preference.toggle
import tachiyomi.presentation.core.components.material.TextButton
import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.util.collectAsState
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.io.File

View file

@ -34,9 +34,9 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import eu.kanade.presentation.entries.DotSeparatorText
import eu.kanade.presentation.util.formatEpisodeNumber
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.anime.Episode
import eu.kanade.tachiyomi.ui.entries.anime.episodeDecimalFormat
import eu.kanade.tachiyomi.util.lang.toRelativeString
import tachiyomi.domain.entries.anime.model.Anime
import tachiyomi.presentation.core.components.VerticalFastScroller
@ -83,7 +83,7 @@ fun EpisodeListDialog(
val title = if (displayMode == Anime.EPISODE_DISPLAY_NUMBER) {
stringResource(
R.string.display_mode_episode,
episodeDecimalFormat.format(episode.episode_number.toDouble()),
formatEpisodeNumber(episode.episode_number),
)
} else {
episode.name

View file

@ -17,13 +17,13 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.sp
import eu.kanade.presentation.components.AdaptiveSheet
import eu.kanade.presentation.util.collectAsState
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.player.settings.PlayerSettingsScreenModel
import eu.kanade.tachiyomi.ui.player.viewer.HwDecState
import eu.kanade.tachiyomi.ui.player.viewer.PlayerStatsPage
import `is`.xyz.mpv.MPVLib
import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.util.collectAsState
@Composable
fun PlayerSettingsSheet(
@ -95,7 +95,7 @@ fun PlayerSettingsSheet(
modifier = Modifier.padding(vertical = MaterialTheme.padding.tiny),
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.padding.small),
) {
HwDecState.values().forEach {
HwDecState.entries.forEach {
if (!HwDecState.isHwSupported && it.title == "HW+") return@forEach
FilterChip(
selected = decoder == it.mpvValue,

View file

@ -26,11 +26,11 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import eu.kanade.presentation.components.AdaptiveSheet
import eu.kanade.presentation.util.collectAsState
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.player.settings.PlayerSettingsScreenModel
import eu.kanade.tachiyomi.ui.player.settings.dialogs.PlayerDialog
import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.util.collectAsState
import java.io.InputStream
@Composable

View file

@ -34,7 +34,6 @@ import androidx.compose.ui.graphics.drawscope.Fill
import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import eu.kanade.presentation.util.collectAsState
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.player.settings.PlayerPreferences
import eu.kanade.tachiyomi.ui.player.settings.PlayerSettingsScreenModel
@ -42,6 +41,7 @@ import `is`.xyz.mpv.MPVLib
import tachiyomi.core.preference.Preference
import tachiyomi.core.preference.getAndSet
import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.util.collectAsState
import kotlin.math.floor
import kotlin.math.max

View file

@ -15,12 +15,12 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import eu.kanade.presentation.util.collectAsState
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.player.settings.PlayerSettingsScreenModel
import `is`.xyz.mpv.MPVLib
import tachiyomi.presentation.core.components.OutlinedNumericChooser
import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.util.collectAsState
@Composable
fun StreamsDelayPage(

View file

@ -32,7 +32,6 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.yubyf.truetypeparser.TTFFile
import eu.kanade.presentation.components.DropdownMenu
import eu.kanade.presentation.util.collectAsState
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.player.settings.PlayerPreferences
import eu.kanade.tachiyomi.ui.player.settings.PlayerSettingsScreenModel
@ -40,6 +39,7 @@ import `is`.xyz.mpv.MPVLib
import tachiyomi.presentation.core.components.OutlinedNumericChooser
import tachiyomi.presentation.core.components.material.ReadItemAlpha
import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.util.collectAsState
import java.io.File
@Composable

View file

@ -73,7 +73,6 @@ import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType
import eu.kanade.tachiyomi.ui.reader.viewer.ReaderProgressIndicator
import eu.kanade.tachiyomi.ui.reader.viewer.pager.R2LPagerViewer
import eu.kanade.tachiyomi.ui.webview.WebViewActivity
import eu.kanade.tachiyomi.util.preference.toggle
import eu.kanade.tachiyomi.util.system.applySystemAnimatorScale
import eu.kanade.tachiyomi.util.system.hasDisplayCutout
import eu.kanade.tachiyomi.util.system.isNightMode
@ -94,6 +93,7 @@ import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.sample
import kotlinx.coroutines.launch
import logcat.LogPriority
import tachiyomi.core.preference.toggle
import tachiyomi.core.util.lang.launchIO
import tachiyomi.core.util.lang.launchNonCancellable
import tachiyomi.core.util.lang.withUIContext
@ -939,18 +939,20 @@ class ReaderActivity : BaseActivity() {
}
}
private val grayBackgroundColor = Color.rgb(0x20, 0x21, 0x25)
/**
* Initializes the reader subscriptions.
*/
init {
readerPreferences.readerTheme().changes()
.onEach { theme ->
binding.readerContainer.setBackgroundResource(
binding.readerContainer.setBackgroundColor(
when (theme) {
0 -> R.color.md_white_1000
2 -> R.color.reader_background_dark
0 -> Color.WHITE
2 -> grayBackgroundColor
3 -> automaticBackgroundColor()
else -> R.color.md_black_1000
else -> Color.BLACK
},
)
}
@ -1003,9 +1005,9 @@ class ReaderActivity : BaseActivity() {
*/
private fun automaticBackgroundColor(): Int {
return if (baseContext.isNightMode()) {
R.color.reader_background_dark
grayBackgroundColor
} else {
R.color.md_white_1000
Color.WHITE
}
}

View file

@ -66,7 +66,7 @@ class ReaderNavigationOverlayView(context: Context, attributeSet: AttributeSet)
// Scale rect from 1f,1f to screen width and height
canvas.withScale(width.toFloat(), height.toFloat()) {
regionPaint.color = context.getColor(region.type.colorRes)
regionPaint.color = region.type.color
drawRect(rect, regionPaint)
}

View file

@ -60,9 +60,7 @@ internal class HttpPageLoader(
}
}
.filter { it.status == Page.State.QUEUE }
.collect {
_loadPage(it)
}
.collect(::internalLoadPage)
}
}
@ -90,32 +88,30 @@ internal class HttpPageLoader(
/**
* Loads a page through the queue. Handles re-enqueueing pages if they were evicted from the cache.
*/
override suspend fun loadPage(page: ReaderPage) {
withIOContext {
val imageUrl = page.imageUrl
override suspend fun loadPage(page: ReaderPage) = withIOContext {
val imageUrl = page.imageUrl
// Check if the image has been deleted
if (page.status == Page.State.READY && imageUrl != null && !chapterCache.isImageInCache(imageUrl)) {
page.status = Page.State.QUEUE
}
// Check if the image has been deleted
if (page.status == Page.State.READY && imageUrl != null && !chapterCache.isImageInCache(imageUrl)) {
page.status = Page.State.QUEUE
}
// Automatically retry failed pages when subscribed to this page
if (page.status == Page.State.ERROR) {
page.status = Page.State.QUEUE
}
// Automatically retry failed pages when subscribed to this page
if (page.status == Page.State.ERROR) {
page.status = Page.State.QUEUE
}
val queuedPages = mutableListOf<PriorityPage>()
if (page.status == Page.State.QUEUE) {
queuedPages += PriorityPage(page, 1).also { queue.offer(it) }
}
queuedPages += preloadNextPages(page, preloadSize)
val queuedPages = mutableListOf<PriorityPage>()
if (page.status == Page.State.QUEUE) {
queuedPages += PriorityPage(page, 1).also { queue.offer(it) }
}
queuedPages += preloadNextPages(page, preloadSize)
suspendCancellableCoroutine<Nothing> { continuation ->
continuation.invokeOnCancellation {
queuedPages.forEach {
if (it.page.status == Page.State.QUEUE) {
queue.remove(it)
}
suspendCancellableCoroutine<Nothing> { continuation ->
continuation.invokeOnCancellation {
queuedPages.forEach {
if (it.page.status == Page.State.QUEUE) {
queue.remove(it)
}
}
}
@ -138,8 +134,7 @@ internal class HttpPageLoader(
queue.clear()
// Cache current page list progress for online chapters to allow a faster reopen
val pages = chapter.pages
if (pages != null) {
chapter.pages?.let { pages ->
launchIO {
try {
// Convert to pages without reader information
@ -181,7 +176,7 @@ internal class HttpPageLoader(
*
* @param page the page whose source image has to be downloaded.
*/
private suspend fun _loadPage(page: ReaderPage) {
private suspend fun internalLoadPage(page: ReaderPage) {
try {
if (page.imageUrl.isNullOrEmpty()) {
page.status = Page.State.LOAD_PAGE

View file

@ -3,13 +3,11 @@ package eu.kanade.tachiyomi.ui.reader.setting
import cafe.adriel.voyager.core.model.ScreenModel
import eu.kanade.presentation.util.ioCoroutineScope
import eu.kanade.tachiyomi.ui.reader.ReaderViewModel
import eu.kanade.tachiyomi.util.preference.toggle
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import tachiyomi.core.preference.Preference
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
@ -29,8 +27,4 @@ class ReaderSettingsScreenModel(
.map { it.manga }
.distinctUntilChanged()
.stateIn(ioCoroutineScope, SharingStarted.Lazily, null)
fun togglePreference(preference: (ReaderPreferences) -> Preference<Boolean>) {
preference(preferences).toggle()
}
}

View file

@ -1,5 +1,6 @@
package eu.kanade.tachiyomi.ui.reader.viewer
import android.graphics.Color
import android.graphics.PointF
import android.graphics.RectF
import androidx.annotation.StringRes
@ -9,12 +10,12 @@ import eu.kanade.tachiyomi.util.lang.invert
abstract class ViewerNavigation {
sealed class NavigationRegion(@StringRes val nameRes: Int, val colorRes: Int) {
data object MENU : NavigationRegion(R.string.action_menu, R.color.navigation_menu)
data object PREV : NavigationRegion(R.string.nav_zone_prev, R.color.navigation_prev)
data object NEXT : NavigationRegion(R.string.nav_zone_next, R.color.navigation_next)
data object LEFT : NavigationRegion(R.string.nav_zone_left, R.color.navigation_left)
data object RIGHT : NavigationRegion(R.string.nav_zone_right, R.color.navigation_right)
sealed class NavigationRegion(@StringRes val nameRes: Int, val color: Int) {
data object MENU : NavigationRegion(R.string.action_menu, Color.argb(0xCC, 0x95, 0x81, 0x8D))
data object PREV : NavigationRegion(R.string.nav_zone_prev, Color.argb(0xCC, 0xFF, 0x77, 0x33))
data object NEXT : NavigationRegion(R.string.nav_zone_next, Color.argb(0xCC, 0x84, 0xE2, 0x96))
data object LEFT : NavigationRegion(R.string.nav_zone_left, Color.argb(0xCC, 0x7D, 0x11, 0x28))
data object RIGHT : NavigationRegion(R.string.nav_zone_right, Color.argb(0xCC, 0xA6, 0xCF, 0xD5))
}
data class Region(

View file

@ -2,8 +2,8 @@
package androidx.recyclerview.widget
import android.content.Context
import androidx.recyclerview.widget.RecyclerView.NO_POSITION
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
/**
* Layout manager used by the webtoon viewer. Item prefetch is disabled because the extra layout
@ -13,12 +13,12 @@ import eu.kanade.tachiyomi.ui.reader.ReaderActivity
* This layout manager uses the same package name as the support library in order to use a package
* protected method.
*/
class WebtoonLayoutManager(activity: ReaderActivity) : LinearLayoutManager(activity) {
class WebtoonLayoutManager(context: Context) : LinearLayoutManager(context) {
/**
* Extra layout space is set to half the screen height.
*/
private val extraLayoutSpace = activity.resources.displayMetrics.heightPixels / 2
private val extraLayoutSpace = context.resources.displayMetrics.heightPixels / 2
init {
isItemPrefetchEnabled = false

View file

@ -1,22 +0,0 @@
package eu.kanade.tachiyomi.util.preference
import eu.kanade.core.preference.PreferenceMutableState
import kotlinx.coroutines.CoroutineScope
import tachiyomi.core.preference.Preference
operator fun <T> Preference<Set<T>>.plusAssign(item: T) {
set(get() + item)
}
operator fun <T> Preference<Set<T>>.minusAssign(item: T) {
set(get() - item)
}
fun Preference<Boolean>.toggle(): Boolean {
set(!get())
return get()
}
fun <T> Preference<T>.asState(presenterScope: CoroutineScope): PreferenceMutableState<T> {
return PreferenceMutableState(this, presenterScope)
}

View file

@ -11,10 +11,10 @@
android:translateX="16"
android:translateY="16">
<path
android:fillColor="@color/md_white_1000"
android:fillColor="#FFF"
android:pathData="M4,6H2v14c0,1.1 0.9,2 2,2h14v-2H4V6z"/>
<path
android:fillColor="@color/md_white_1000"
android:fillColor="#FFF"
android:pathData="M4,6L2,6v14c0,1.1 0.9,2 2,2h14v-2L4,20L4,6zM20,2L8,2c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM12,14.5v-9l6,4.5 -6,4.5z"/>
</group>
</vector>

View file

@ -13,10 +13,10 @@
android:translateX="16"
android:translateY="16">
<path
android:fillColor="@color/md_white_1000"
android:fillColor="#FFF"
android:pathData="M4,6H2v14c0,1.1 0.9,2 2,2h14v-2H4V6z"/>
<path
android:fillColor="@color/md_white_1000"
android:fillColor="#FFF"
android:pathData="M20,2L8,2c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM20,12l-2.5,-1.5L15,12L15,4h5v8z"/>
</group>
</vector>

View file

@ -13,7 +13,7 @@
android:translateX="16"
android:translateY="16">
<path
android:fillColor="@color/md_white_1000"
android:fillColor="#FFF"
android:pathData="M12,10.9c-0.61,0 -1.1,0.49 -1.1,1.1s0.49,1.1 1.1,1.1c0.61,0 1.1,-0.49 1.1,-1.1s-0.49,-1.1 -1.1,-1.1zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM14.19,14.19L6,18l3.81,-8.19L18,6l-3.81,8.19z" />
</group>
</vector>

View file

@ -13,7 +13,7 @@
android:translateX="16"
android:translateY="16">
<path
android:fillColor="@color/md_white_1000"
android:fillColor="#FFF"
android:pathData="M13,3c-4.97,0 -9,4.03 -9,9L1,12l3.89,3.89 0.07,0.14L9,12L6,12c0,-3.87 3.13,-7 7,-7s7,3.13 7,7 -3.13,7 -7,7c-1.93,0 -3.68,-0.79 -4.94,-2.06l-1.42,1.42C8.27,19.99 10.51,21 13,21c4.97,0 9,-4.03 9,-9s-4.03,-9 -9,-9zM12,8v5l4.28,2.54 0.72,-1.21 -3.5,-2.08L13.5,8L12,8z" />
</group>
</vector>

View file

@ -13,7 +13,7 @@
android:translateX="16"
android:translateY="16">
<path
android:fillColor="@color/md_white_1000"
android:fillColor="#FFF"
android:pathData="M23,12l-2.44,-2.78 0.34,-3.68 -3.61,-0.82 -1.89,-3.18L12,3 8.6,1.54 6.71,4.72l-3.61,0.81 0.34,3.68L1,12l2.44,2.78 -0.34,3.69 3.61,0.82 1.89,3.18L12,21l3.4,1.46 1.89,-3.18 3.61,-0.82 -0.34,-3.68L23,12zM13,17h-2v-2h2v2zM13,13h-2L11,7h2v6z" />
</group>
</vector>

View file

@ -24,7 +24,7 @@
android:translateY="-1.0">
<path
android:name="caret_l_rect"
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M -1.0,-4.0 l 2.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,8.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l -2.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,-8.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
</group>
</group>
@ -40,7 +40,7 @@
android:translateY="1.0">
<path
android:name="caret_r_rect"
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M -1.0,-4.0 l 2.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,8.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l -2.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,-8.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
</group>
</group>

View file

@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M4,6L2,6v14c0,1.1 0.9,2 2,2h14v-2L4,20L4,6zM20,2L8,2c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM12,14.5v-9l6,4.5 -6,4.5z"/>
</vector>

View file

@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M4,6L2,6v14c0,1.1 0.9,2 2,2h14v-2L4,20L4,6zM20,2L8,2c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM20,16L8,16L8,4h12v12zM12,5.5v9l6,-4.5z"/>
</vector>

View file

@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/>
</vector>

View file

@ -5,6 +5,6 @@
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:fillColor="#FFF"
android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/>
</vector>

View file

@ -5,5 +5,5 @@
android:width="24dp">
<path android:pathData="M4,6L2,6v14c0,1.1 0.9,2 2,2h14v-2L4,20L4,6zM20,2L8,2c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM20,16L8,16L8,4h12v12zM12,5.5v9l6,-4.5z"
android:fillColor="@android:color/black"/>
android:fillColor="#000"/>
</vector>

View file

@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M21,3.01H3c-1.1,0 -2,0.9 -2,2V9h2V4.99h18v14.03H3V15H1v4.01c0,1.1 0.9,1.98 2,1.98h18c1.1,0 2,-0.88 2,-1.98v-14c0,-1.11 -0.9,-2 -2,-2zM11,16l4,-4 -4,-4v3H1v2h10v3z"/>
</vector>

View file

@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M19,19H5V5h7V3H5c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2v-7h-2v7zM14,3v2h3.59l-9.83,9.83 1.41,1.41L19,6.41V10h2V3h-7z"/>
</vector>

View file

@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:fillColor="#FFF"
android:pathData="M18,2L6,2c-1.1,0 -2,0.9 -2,2v16c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L20,4c0,-1.1 -0.9,-2 -2,-2zM9,4h2v5l-1,-0.75L9,9L9,4zM18,20L6,20L6,4h1v9l3,-2.25L13,13L13,4h5v16z" />
</vector>

View file

@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M17,3H7c-1.1,0 -1.99,0.9 -1.99,2L5,21l7,-3 7,3V5c0,-1.1 -0.9,-2 -2,-2z" />
</vector>

View file

@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M17,3L7,3c-1.1,0 -1.99,0.9 -1.99,2L5,21l7,-3 7,3L19,5c0,-1.1 -0.9,-2 -2,-2zM17,18l-5,-2.18L7,18L7,5h10v13z" />
</vector>

View file

@ -4,6 +4,6 @@
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z" />
</vector>

View file

@ -4,6 +4,6 @@ android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M10,16.5l6,-4.5 -6,-4.5v9zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8z" />
</vector>

View file

@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:fillColor="#FFF"
android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z" />
</vector>

View file

@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M17,15h2V7c0,-1.1 -0.9,-2 -2,-2H9v2h8v8zM7,17V1H5v4H1v2h4v10c0,1.1 0.9,2 2,2h10v4h2v-4h4v-2H7z" />
</vector>

View file

@ -4,15 +4,15 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M7,1l-2,0l0,1.18l2,2l0,-3.18z" />
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M17,7v7.18l0.82,0.82H19V7a2.0059,2.0059 0,0 0,-2 -2H9V6.18L9.82,7Z" />
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M19.0001,19l-2,-2h0L2.1,2.1 0.68,3.51 2.1707,5H1V7H4.1718L5,7.8278V17a2.0059,2.0059 0,0 0,2 2h9.1778L17,19.8218V23h2V21.8207L20.49,23.31 21.9,21.9l-2.9,-2.9ZM7,17V9.8268L14.1768,17Z" />
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M19.82,17l2,2l1.18,0l0,-2l-3.18,0z" />
</vector>

View file

@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:fillColor="#FFF"
android:pathData="M16,9v10H8V9h8m-1.5,-6h-5l-1,1H5v2h14V4h-3.5l-1,-1zM18,7H6v12c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2V7z" />
</vector>

View file

@ -4,9 +4,9 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M9,16.2L4.8,12l-1.4,1.4L9,19 21,7l-1.4,-1.4L9,16.2z" />
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M22,18l-3,0l0,-4l-2,0l0,4l-3,0l4,4z" />
</vector>

View file

@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M20,9H4v2h16V9zM4,15h16v-2H4V15z" />
</vector>

View file

@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M20.5,11H19V7c0,-1.1 -0.9,-2 -2,-2h-4V3.5C13,2.12 11.88,1 10.5,1S8,2.12 8,3.5V5H4c-1.1,0 -1.99,0.9 -1.99,2v3.8H3.5c1.49,0 2.7,1.21 2.7,2.7s-1.21,2.7 -2.7,2.7H2V20c0,1.1 0.9,2 2,2h3.8v-1.5c0,-1.49 1.21,-2.7 2.7,-2.7 1.49,0 2.7,1.21 2.7,2.7V22H17c1.1,0 2,-0.9 2,-2v-4h1.5c1.38,0 2.5,-1.12 2.5,-2.5S21.88,11 20.5,11z" />
</vector>

View file

@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:fillColor="#FFF"
android:pathData="M10,4H4c-1.1,0 -1.99,0.9 -1.99,2L2,18c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2V8c0,-1.1 -0.9,-2 -2,-2h-8l-2,-2z" />
</vector>

View file

@ -5,6 +5,6 @@
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M7,14L5,14v5h5v-2L7,17v-3zM5,10h2L7,7h3L10,5L5,5v5zM17,17h-3v2h5v-5h-2v3zM14,5v2h3v3h2L19,5h-5z"/>
</vector>

View file

@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:fillColor="#FFF"
android:pathData="M3,10C2.76,10 2.55,10.09 2.41,10.25C2.27,10.4 2.21,10.62 2.24,10.86L2.74,13.85C2.82,14.5 3.4,15 4,15H7C7.64,15 8.36,14.44 8.5,13.82L9.56,10.63C9.6,10.5 9.57,10.31 9.5,10.19C9.39,10.07 9.22,10 9,10H3M7,17H4C2.38,17 0.96,15.74 0.76,14.14L0.26,11.15C0.15,10.3 0.39,9.5 0.91,8.92C1.43,8.34 2.19,8 3,8H9C9.83,8 10.58,8.35 11.06,8.96C11.17,9.11 11.27,9.27 11.35,9.45C11.78,9.36 12.22,9.36 12.64,9.45C12.72,9.27 12.82,9.11 12.94,8.96C13.41,8.35 14.16,8 15,8H21C21.81,8 22.57,8.34 23.09,8.92C23.6,9.5 23.84,10.3 23.74,11.11L23.23,14.18C23.04,15.74 21.61,17 20,17H17C15.44,17 13.92,15.81 13.54,14.3L12.64,11.59C12.26,11.31 11.73,11.31 11.35,11.59L10.43,14.37C10.07,15.82 8.56,17 7,17M15,10C14.78,10 14.61,10.07 14.5,10.19C14.42,10.31 14.4,10.5 14.45,10.7L15.46,13.75C15.64,14.44 16.36,15 17,15H20C20.59,15 21.18,14.5 21.25,13.89L21.76,10.82C21.79,10.62 21.73,10.4 21.59,10.25C21.45,10.09 21.24,10 21,10H15Z" />
</vector>

View file

@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M11,7h2v2h-2zM11,11h2v6h-2zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8z" />
</vector>

View file

@ -5,6 +5,6 @@
android:viewportHeight="24">
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M18,8h-1L17,6c0,-2.76 -2.24,-5 -5,-5S7,3.24 7,6v2L6,8c-1.1,0 -2,0.9 -2,2v10c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L20,10c0,-1.1 -0.9,-2 -2,-2zM12,17c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2 2,0.9 2,2 -0.9,2 -2,2zM15.1,8L8.9,8L8.9,6c0,-1.71 1.39,-3.1 3.1,-3.1 1.71,0 3.1,1.39 3.1,3.1v2z"/>
</vector>

View file

@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M10,6L8.59,7.41 13.17,12l-4.58,4.59L10,18l6,-6z" />
</vector>

View file

@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M12,2C6.5,2 2,6.5 2,12s4.5,10 10,10s10,-4.5 10,-10S17.5,2 12,2zM17,18H7v-2h10V18zM10.3,14L7,10.7l1.4,-1.4l1.9,1.9l5.3,-5.3L17,7.3L10.3,14z" />
</vector>

View file

@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M12,8c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM12,16c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2z" />
</vector>

View file

@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M12,8c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM12,16c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2z" />
</vector>

View file

@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:fillColor="#FFF"
android:pathData="M6,19h4L10,5L6,5v14zM14,5v14h4L18,5h-4z" />
</vector>

View file

@ -5,6 +5,6 @@
android:viewportHeight="24"
android:viewportWidth="24" >
<path
android:fillColor="@android:color/white"
android:fillColor="#FFF"
android:pathData="M6,19h4L10,5L6,5v14zM14,5v14h4L18,5h-4z"/>
</vector>

View file

@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:fillColor="#FFF"
android:pathData="M21,19V5c0,-1.1 -0.9,-2 -2,-2H5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2zM8.5,13.5l2.5,3.01L14.5,12l4.5,6H5l3.5,-4.5z" />
</vector>

View file

@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M19,11h-8v6h8v-6zM23,19L23,4.98C23,3.88 22.1,3 21,3L3,3c-1.1,0 -2,0.88 -2,1.98L1,19c0,1.1 0.9,2 2,2h18c1.1,0 2,-0.9 2,-2zM21,19.02L3,19.02L3,4.97h18v14.05z"/>
</vector>

View file

@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:fillColor="#FFF"
android:pathData="M8,5v14l11,-7z" />
</vector>

View file

@ -5,6 +5,6 @@
android:viewportHeight="24"
android:viewportWidth="24" >
<path
android:fillColor="@android:color/white"
android:fillColor="#FFF"
android:pathData="M8,5v14l11,-7z"/>
</vector>

View file

@ -4,12 +4,12 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M17.3159,1h-10a2.0059,2.0059 0,0 0,-2 2L5.3159,21a2.0059,2.0059 0,0 0,2 2h10a2.0059,2.0059 0,0 0,2 -2L19.3159,3A2.0059,2.0059 0,0 0,17.3159 1ZM17.3159,21h-10L7.3159,3h10Z" />
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M11.3083,5h2v5.5h-2z" />
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M15.308,16l-2,0l0,-4.5l-2,0l0,4.5l-2,0l3,3l3,-3z" />
</vector>

View file

@ -4,9 +4,9 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M6.9906,18L6.9906,6h12L18.9906,3a2.0059,2.0059 0,0 0,-2 -2h-10a2.0059,2.0059 0,0 0,-2 2L4.9906,21a2.0059,2.0059 0,0 0,2 2h10a2.0059,2.0059 0,0 0,2 -2L18.9906,18h-12ZM6.9906,3h10L16.9906,4h-10ZM16.9906,21h-10L6.9906,20h10Z" />
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M21.7706,12.44l-0.02,0.03a3.5546,3.5546 0,0 0,0.05 -0.47,3.9031 3.9031,0 0,0 -0.05,-0.48l0.02,0.03 0.85,-0.68a0.5068,0.5068 0,0 0,0.12 -0.64l-0.84,-1.46a0.4986,0.4986 0,0 0,-0.61 -0.22l-1.01,0.39 0.0099,0.04a3.6135,3.6135 0,0 0,-0.8 -0.48l-0.17,-1.07a0.4879,0.4879 0,0 0,-0.49 -0.43h-1.68a0.4876,0.4876 0,0 0,-0.49 0.42l-0.17,1.08a3.6149,3.6149 0,0 0,-0.8 0.48l0.02,-0.03 -1.01,-0.39a0.4878,0.4878 0,0 0,-0.61 0.22l-0.84,1.46a0.5068,0.5068 0,0 0,0.12 0.64l0.85,0.68 0.02,-0.03a3.9148,3.9148 0,0 0,-0.05 0.48,3.915 3.915,0 0,0 0.05,0.48l-0.02,-0.03 -0.85,0.68a0.5068,0.5068 0,0 0,-0.12 0.64l0.84,1.46a0.4985,0.4985 0,0 0,0.61 0.22l1.01,-0.39 -0.02,-0.03a4.4991,4.4991 0,0 0,0.8 0.46l0.17,1.08a0.4876,0.4876 0,0 0,0.49 0.42h1.68a0.4876,0.4876 0,0 0,0.49 -0.42l0.17,-1.08a3.6138,3.6138 0,0 0,0.8 -0.48l-0.02,0.03 1.02,0.39a0.4879,0.4879 0,0 0,0.61 -0.22l0.84,-1.46a0.5068,0.5068 0,0 0,-0.12 -0.64ZM17.9906,14a2,2 0,1 1,2 -2A2.0059,2.0059 0,0 1,17.9906 14Z" />
</vector>

View file

@ -4,18 +4,18 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M17.3159,18h-10L7.3159,16h-2v5a2.0059,2.0059 0,0 0,2 2h10a2.0059,2.0059 0,0 0,2 -2L19.3159,16h-2ZM17.3159,21h-10L7.3159,20h10Z" />
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M7.3159,6h10L17.3159,8h2L19.3159,3a2.0059,2.0059 0,0 0,-2 -2h-10a2.0059,2.0059 0,0 0,-2 2L5.3159,8h2ZM7.3159,3h10L17.3159,4h-10Z" />
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M22.311,12l-3,-3l0,2l-11.99,0l0,2l11.99,0l0,2l3,-3z" />
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M2.3206,11h1.5v2h-1.5z" />
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M4.8206,11h1.5v2h-1.5z" />
</vector>

View file

@ -4,18 +4,18 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M7,6H17V8h2V3a2.0059,2.0059 0,0 0,-2 -2H7A2.0059,2.0059 0,0 0,5 3V8H7ZM7,3H17V4H7Z" />
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M17,18L7,18L7,16L5,16v5a2.0059,2.0059 0,0 0,2 2L17,23a2.0059,2.0059 0,0 0,2 -2L19,16L17,16ZM17,21L7,21L7,20L17,20Z" />
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M5.005,13l11.99,0l0,-2l-11.99,0l0,-2l-3,3l3,3l0,-2z" />
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M20.4953,11h1.5v2h-1.5z" />
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M17.9953,11h1.5v2h-1.5z" />
</vector>

View file

@ -4,9 +4,9 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M17,1L7,1A2.0059,2.0059 0,0 0,5 3L5,21a2.0059,2.0059 0,0 0,2 2L17,23a2.0059,2.0059 0,0 0,2 -2L19,3A2.0059,2.0059 0,0 0,17 1ZM17,3v1.0462L7,4.0462L7,3ZM17,6.0462v12L7,18.0462v-12ZM7,21v-0.9538L17,20.0462L17,21Z" />
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M9,13l3,3l3,-3l-2,0l0,-5l-2,0l0,5l-2,0z" />
</vector>

View file

@ -4,9 +4,9 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M11.992,19l3,-3l-2,0l0,-11l-2,0l0,11l-2,0l3,3z" />
<path
android:fillColor="@android:color/black"
android:fillColor="#000"
android:pathData="M17,1L7,1A2.0059,2.0059 0,0 0,5 3L5,21a2.0059,2.0059 0,0 0,2 2L17,23a2.0059,2.0059 0,0 0,2 -2L19,3A2.0059,2.0059 0,0 0,17 1ZM17,21L7,21L7,3L17,3Z" />
</vector>

View file

@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:fillColor="#FFF"
android:pathData="M17.65,6.35C16.2,4.9 14.21,4 12,4c-4.42,0 -7.99,3.58 -7.99,8s3.57,8 7.99,8c3.73,0 6.84,-2.55 7.73,-6h-2.08c-0.82,2.33 -3.04,4 -5.65,4 -3.31,0 -6,-2.69 -6,-6s2.69,-6 6,-6c1.66,0 3.14,0.69 4.22,1.78L13,11h7V4l-2.35,2.35z" />
</vector>

Some files were not shown because too many files have changed in this diff Show more