mirror of
https://github.com/aniyomiorg/aniyomi.git
synced 2024-11-21 12:17:12 +03:00
parent
717479961c
commit
370212c677
140 changed files with 364 additions and 545 deletions
|
@ -31,7 +31,7 @@ class PreferenceMutableState<T>(
|
|||
}
|
||||
|
||||
override fun component2(): (T) -> Unit {
|
||||
return { preference.set(it) }
|
||||
return preference::set
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 = '.' },
|
||||
)
|
||||
|
|
|
@ -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 = '.' },
|
||||
)
|
||||
|
|
|
@ -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(),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -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(),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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(),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -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(),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -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(),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 = '.' },
|
||||
)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 = '.' },
|
||||
)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
Loading…
Reference in a new issue