|
@@ -15,18 +15,12 @@ import androidx.compose.animation.fadeIn
|
|
|
import androidx.compose.animation.fadeOut
|
|
import androidx.compose.animation.fadeOut
|
|
|
import androidx.compose.animation.scaleOut
|
|
import androidx.compose.animation.scaleOut
|
|
|
import androidx.compose.animation.togetherWith
|
|
import androidx.compose.animation.togetherWith
|
|
|
-import androidx.compose.runtime.DisposableEffect
|
|
|
|
|
import androidx.compose.runtime.Composable
|
|
import androidx.compose.runtime.Composable
|
|
|
import androidx.compose.runtime.LaunchedEffect
|
|
import androidx.compose.runtime.LaunchedEffect
|
|
|
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
|
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
|
|
-import androidx.lifecycle.Lifecycle
|
|
|
|
|
-import androidx.lifecycle.LifecycleEventObserver
|
|
|
|
|
-import androidx.lifecycle.compose.LocalLifecycleOwner
|
|
|
|
|
import androidx.lifecycle.lifecycleScope
|
|
import androidx.lifecycle.lifecycleScope
|
|
|
import androidx.navigation3.runtime.NavKey
|
|
import androidx.navigation3.runtime.NavKey
|
|
|
-import androidx.navigation3.runtime.entryProvider
|
|
|
|
|
import androidx.navigation3.runtime.rememberNavBackStack
|
|
import androidx.navigation3.runtime.rememberNavBackStack
|
|
|
-import androidx.navigation3.ui.LocalNavAnimatedContentScope
|
|
|
|
|
import androidx.navigation3.ui.NavDisplay
|
|
import androidx.navigation3.ui.NavDisplay
|
|
|
import io.legado.app.BuildConfig
|
|
import io.legado.app.BuildConfig
|
|
|
import io.legado.app.R
|
|
import io.legado.app.R
|
|
@@ -43,49 +37,18 @@ import io.legado.app.lib.dialogs.alert
|
|
|
import io.legado.app.service.WebService
|
|
import io.legado.app.service.WebService
|
|
|
import io.legado.app.ui.about.CrashLogsDialog
|
|
import io.legado.app.ui.about.CrashLogsDialog
|
|
|
import io.legado.app.ui.about.UpdateDialog
|
|
import io.legado.app.ui.about.UpdateDialog
|
|
|
-import io.legado.app.ui.book.cache.manage.BookCacheManageRouteScreen
|
|
|
|
|
-import io.legado.app.ui.book.explore.ExploreShowScreen
|
|
|
|
|
-import io.legado.app.ui.book.info.BookInfoRouteScreen
|
|
|
|
|
-import io.legado.app.ui.book.info.BookInfoViewModel
|
|
|
|
|
-import io.legado.app.ui.book.import.local.ImportBookScreen
|
|
|
|
|
-import io.legado.app.ui.book.import.remote.RemoteBookScreen
|
|
|
|
|
-import io.legado.app.ui.book.search.SearchIntent
|
|
|
|
|
-import io.legado.app.ui.book.search.SearchScreen
|
|
|
|
|
-import io.legado.app.ui.book.search.SearchViewModel
|
|
|
|
|
-import io.legado.app.ui.book.readRecord.ReadRecordOverviewScreen
|
|
|
|
|
-import io.legado.app.ui.book.readRecord.ReadRecordScreen
|
|
|
|
|
-import io.legado.app.ui.book.readRecord.ReadRecordViewModel
|
|
|
|
|
-import io.legado.app.ui.book.source.manage.BookSourceActivity
|
|
|
|
|
-import io.legado.app.ui.book.manage.BookshelfManageRouteScreen
|
|
|
|
|
import io.legado.app.ui.book.read.ReadBookActivity
|
|
import io.legado.app.ui.book.read.ReadBookActivity
|
|
|
-import io.legado.app.ui.config.ConfigNavScreen
|
|
|
|
|
-import io.legado.app.ui.config.ConfigTag
|
|
|
|
|
-import io.legado.app.ui.config.backupConfig.BackupConfigScreen
|
|
|
|
|
-import io.legado.app.ui.config.coverConfig.CoverConfigScreen
|
|
|
|
|
-import io.legado.app.ui.config.downloadCacheConfig.DownloadCacheConfigScreen
|
|
|
|
|
import io.legado.app.ui.config.themeConfig.ThemeConfig
|
|
import io.legado.app.ui.config.themeConfig.ThemeConfig
|
|
|
-import io.legado.app.ui.config.otherConfig.OtherConfigScreen
|
|
|
|
|
-import io.legado.app.ui.config.customTheme.CustomThemeScreen
|
|
|
|
|
-import io.legado.app.ui.config.readConfig.ReadConfigScreen
|
|
|
|
|
-import io.legado.app.ui.config.themeConfig.ThemeConfigScreen
|
|
|
|
|
-import io.legado.app.ui.config.themeManage.ThemeManageScreen
|
|
|
|
|
-import io.legado.app.ui.rss.article.MainRouteRssSort
|
|
|
|
|
-import io.legado.app.ui.rss.article.RssSortRouteScreen
|
|
|
|
|
-import io.legado.app.ui.rss.read.MainRouteRssRead
|
|
|
|
|
-import io.legado.app.ui.rss.read.RssReadRouteScreen
|
|
|
|
|
import io.legado.app.ui.welcome.WelcomeActivity
|
|
import io.legado.app.ui.welcome.WelcomeActivity
|
|
|
import io.legado.app.ui.widget.dialog.TextDialog
|
|
import io.legado.app.ui.widget.dialog.TextDialog
|
|
|
import io.legado.app.ui.widget.dialog.VariableDialog
|
|
import io.legado.app.ui.widget.dialog.VariableDialog
|
|
|
import io.legado.app.utils.getPrefBoolean
|
|
import io.legado.app.utils.getPrefBoolean
|
|
|
import io.legado.app.utils.showDialogFragment
|
|
import io.legado.app.utils.showDialogFragment
|
|
|
import io.legado.app.utils.startActivity
|
|
import io.legado.app.utils.startActivity
|
|
|
-import io.legado.app.utils.startActivityForBook
|
|
|
|
|
import kotlinx.coroutines.Dispatchers.IO
|
|
import kotlinx.coroutines.Dispatchers.IO
|
|
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
|
|
import kotlinx.coroutines.launch
|
|
import kotlinx.coroutines.launch
|
|
|
import kotlinx.coroutines.withContext
|
|
import kotlinx.coroutines.withContext
|
|
|
-import kotlinx.serialization.Serializable
|
|
|
|
|
-import org.koin.androidx.compose.koinViewModel
|
|
|
|
|
import org.koin.androidx.viewmodel.ext.android.viewModel
|
|
import org.koin.androidx.viewmodel.ext.android.viewModel
|
|
|
import kotlin.coroutines.resume
|
|
import kotlin.coroutines.resume
|
|
|
import kotlin.coroutines.suspendCoroutine
|
|
import kotlin.coroutines.suspendCoroutine
|
|
@@ -96,81 +59,19 @@ import kotlin.coroutines.suspendCoroutine
|
|
|
open class MainActivity : BaseComposeActivity(), VariableDialog.Callback {
|
|
open class MainActivity : BaseComposeActivity(), VariableDialog.Callback {
|
|
|
|
|
|
|
|
companion object {
|
|
companion object {
|
|
|
- const val EXTRA_START_ROUTE = "startRoute"
|
|
|
|
|
- private const val ROUTE_MAIN = "main"
|
|
|
|
|
- private const val ROUTE_SETTINGS = "settings"
|
|
|
|
|
- private const val ROUTE_SETTINGS_OTHER = "settings/other"
|
|
|
|
|
- private const val ROUTE_SETTINGS_READ = "settings/read"
|
|
|
|
|
- private const val ROUTE_SETTINGS_COVER = "settings/cover"
|
|
|
|
|
- private const val ROUTE_SETTINGS_THEME = "settings/theme"
|
|
|
|
|
- private const val ROUTE_SETTINGS_BACKUP = "settings/backup"
|
|
|
|
|
- private const val ROUTE_SETTINGS_CUSTOM_THEME = "settings/custom_theme"
|
|
|
|
|
- private const val ROUTE_SETTINGS_DOWNLOAD_CACHE = "settings/download_cache"
|
|
|
|
|
- private const val ROUTE_IMPORT_LOCAL = "import/local"
|
|
|
|
|
- private const val ROUTE_IMPORT_REMOTE = "import/remote"
|
|
|
|
|
- private const val ROUTE_CACHE = "cache"
|
|
|
|
|
- private const val ROUTE_BOOK_CACHE_MANAGE = "book/cache/manage"
|
|
|
|
|
- private const val ROUTE_SEARCH = "search"
|
|
|
|
|
- private const val ROUTE_BOOK_INFO = "book/info"
|
|
|
|
|
- private const val ROUTE_EXPLORE_SHOW = "explore/show"
|
|
|
|
|
- private const val ROUTE_RSS_SORT = "rss/sort"
|
|
|
|
|
- private const val ROUTE_RSS_READ = "rss/read"
|
|
|
|
|
- private const val ROUTE_READ_RECORD = "read_record"
|
|
|
|
|
- private const val ROUTE_READ_RECORD_OVERVIEW = "read_record_overview"
|
|
|
|
|
- private const val EXTRA_CACHE_GROUP_ID = "extra_cache_group_id"
|
|
|
|
|
- private const val EXTRA_SEARCH_KEY = "extra_search_key"
|
|
|
|
|
- private const val EXTRA_SEARCH_SCOPE = "extra_search_scope"
|
|
|
|
|
- private const val EXTRA_BOOK_NAME = "name"
|
|
|
|
|
- private const val EXTRA_BOOK_AUTHOR = "author"
|
|
|
|
|
- private const val EXTRA_BOOK_URL = "bookUrl"
|
|
|
|
|
- private const val EXTRA_EXPLORE_NAME = "exploreName"
|
|
|
|
|
- private const val EXTRA_SOURCE_URL = "sourceUrl"
|
|
|
|
|
- private const val EXTRA_EXPLORE_URL = "exploreUrl"
|
|
|
|
|
|
|
+ fun createLauncherIntent(context: Context): Intent =
|
|
|
|
|
+ MainIntent.createLauncherIntent(context)
|
|
|
|
|
|
|
|
- private const val EXTRA_RSS_SOURCE_URL = "extra_rss_source_url"
|
|
|
|
|
- private const val EXTRA_RSS_SORT_URL = "extra_rss_sort_url"
|
|
|
|
|
- private const val EXTRA_RSS_KEY = "extra_rss_key"
|
|
|
|
|
-
|
|
|
|
|
- private const val EXTRA_RSS_READ_TITLE = "extra_rss_read_title"
|
|
|
|
|
- private const val EXTRA_RSS_READ_ORIGIN = "extra_rss_read_origin"
|
|
|
|
|
- private const val EXTRA_RSS_READ_LINK = "extra_rss_read_link"
|
|
|
|
|
- private const val EXTRA_RSS_READ_OPEN_URL = "extra_rss_read_open_url"
|
|
|
|
|
-
|
|
|
|
|
- fun createLauncherIntent(context: Context): Intent {
|
|
|
|
|
- val launcherComponent =
|
|
|
|
|
- context.packageManager.getLaunchIntentForPackage(context.packageName)?.component
|
|
|
|
|
- return if (launcherComponent != null) {
|
|
|
|
|
- Intent().setComponent(launcherComponent)
|
|
|
|
|
- } else {
|
|
|
|
|
- Intent(context, MainActivity::class.java)
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- fun createHomeIntent(context: Context): Intent {
|
|
|
|
|
- return createLauncherIntent(context).apply {
|
|
|
|
|
- putExtra(EXTRA_START_ROUTE, ROUTE_MAIN)
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- fun createIntent(context: Context, configTag: String? = null): Intent {
|
|
|
|
|
- return createLauncherIntent(context).apply {
|
|
|
|
|
- putExtra(EXTRA_START_ROUTE, routeForConfigTag(configTag))
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ fun createHomeIntent(context: Context): Intent = MainIntent.createHomeIntent(context)
|
|
|
|
|
+ fun createIntent(context: Context, configTag: String? = null): Intent =
|
|
|
|
|
+ MainIntent.createIntent(context, configTag)
|
|
|
|
|
|
|
|
fun createRssSortIntent(
|
|
fun createRssSortIntent(
|
|
|
context: Context,
|
|
context: Context,
|
|
|
sourceUrl: String,
|
|
sourceUrl: String,
|
|
|
sortUrl: String? = null,
|
|
sortUrl: String? = null,
|
|
|
key: String? = null
|
|
key: String? = null
|
|
|
- ): Intent {
|
|
|
|
|
- return createLauncherIntent(context).apply {
|
|
|
|
|
- putExtra(EXTRA_START_ROUTE, ROUTE_RSS_SORT)
|
|
|
|
|
- putExtra(EXTRA_RSS_SOURCE_URL, sourceUrl)
|
|
|
|
|
- putExtra(EXTRA_RSS_SORT_URL, sortUrl)
|
|
|
|
|
- putExtra(EXTRA_RSS_KEY, key)
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ ): Intent = MainIntent.createRssSortIntent(context, sourceUrl, sortUrl, key)
|
|
|
|
|
|
|
|
fun createRssReadIntent(
|
|
fun createRssReadIntent(
|
|
|
context: Context,
|
|
context: Context,
|
|
@@ -178,165 +79,42 @@ open class MainActivity : BaseComposeActivity(), VariableDialog.Callback {
|
|
|
origin: String,
|
|
origin: String,
|
|
|
link: String? = null,
|
|
link: String? = null,
|
|
|
openUrl: String? = null
|
|
openUrl: String? = null
|
|
|
- ): Intent {
|
|
|
|
|
- return createLauncherIntent(context).apply {
|
|
|
|
|
- putExtra(EXTRA_START_ROUTE, ROUTE_RSS_READ)
|
|
|
|
|
- putExtra(EXTRA_RSS_READ_TITLE, title)
|
|
|
|
|
- putExtra(EXTRA_RSS_READ_ORIGIN, origin)
|
|
|
|
|
- putExtra(EXTRA_RSS_READ_LINK, link)
|
|
|
|
|
- putExtra(EXTRA_RSS_READ_OPEN_URL, openUrl)
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ ): Intent = MainIntent.createRssReadIntent(context, title, origin, link, openUrl)
|
|
|
|
|
|
|
|
- fun createBookshelfManageScreenIntent(
|
|
|
|
|
- context: Context,
|
|
|
|
|
- groupId: Long = -1L
|
|
|
|
|
- ): Intent {
|
|
|
|
|
- return createLauncherIntent(context).apply {
|
|
|
|
|
- putExtra(EXTRA_START_ROUTE, ROUTE_CACHE)
|
|
|
|
|
- putExtra(EXTRA_CACHE_GROUP_ID, groupId)
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ fun createBookshelfManageScreenIntent(context: Context, groupId: Long = -1L): Intent =
|
|
|
|
|
+ MainIntent.createBookshelfManageScreenIntent(context, groupId)
|
|
|
|
|
|
|
|
- fun createCacheIntent(
|
|
|
|
|
- context: Context,
|
|
|
|
|
- groupId: Long = -1L
|
|
|
|
|
- ): Intent = createBookshelfManageScreenIntent(context, groupId)
|
|
|
|
|
|
|
+ fun createCacheIntent(context: Context, groupId: Long = -1L): Intent =
|
|
|
|
|
+ MainIntent.createCacheIntent(context, groupId)
|
|
|
|
|
|
|
|
- fun createBookCacheManageIntent(context: Context): Intent {
|
|
|
|
|
- return createLauncherIntent(context).apply {
|
|
|
|
|
- putExtra(EXTRA_START_ROUTE, ROUTE_BOOK_CACHE_MANAGE)
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ fun createBookCacheManageIntent(context: Context): Intent =
|
|
|
|
|
+ MainIntent.createBookCacheManageIntent(context)
|
|
|
|
|
|
|
|
fun createSearchIntent(
|
|
fun createSearchIntent(
|
|
|
context: Context,
|
|
context: Context,
|
|
|
key: String? = null,
|
|
key: String? = null,
|
|
|
scopeRaw: String? = null
|
|
scopeRaw: String? = null
|
|
|
- ): Intent {
|
|
|
|
|
- return createLauncherIntent(context).apply {
|
|
|
|
|
- putExtra(EXTRA_START_ROUTE, ROUTE_SEARCH)
|
|
|
|
|
- putExtra(EXTRA_SEARCH_KEY, key)
|
|
|
|
|
- putExtra(EXTRA_SEARCH_SCOPE, scopeRaw)
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ ): Intent = MainIntent.createSearchIntent(context, key, scopeRaw)
|
|
|
|
|
|
|
|
fun createBookInfoIntent(
|
|
fun createBookInfoIntent(
|
|
|
context: Context,
|
|
context: Context,
|
|
|
name: String? = null,
|
|
name: String? = null,
|
|
|
author: String? = null,
|
|
author: String? = null,
|
|
|
bookUrl: String
|
|
bookUrl: String
|
|
|
- ): Intent {
|
|
|
|
|
- return createLauncherIntent(context).apply {
|
|
|
|
|
- putExtra(EXTRA_START_ROUTE, ROUTE_BOOK_INFO)
|
|
|
|
|
- putExtra(EXTRA_BOOK_NAME, name)
|
|
|
|
|
- putExtra(EXTRA_BOOK_AUTHOR, author)
|
|
|
|
|
- putExtra(EXTRA_BOOK_URL, bookUrl)
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ ): Intent = MainIntent.createBookInfoIntent(context, name, author, bookUrl)
|
|
|
|
|
|
|
|
fun createExploreShowIntent(
|
|
fun createExploreShowIntent(
|
|
|
context: Context,
|
|
context: Context,
|
|
|
exploreName: String? = null,
|
|
exploreName: String? = null,
|
|
|
sourceUrl: String,
|
|
sourceUrl: String,
|
|
|
exploreUrl: String? = null
|
|
exploreUrl: String? = null
|
|
|
- ): Intent {
|
|
|
|
|
- return createLauncherIntent(context).apply {
|
|
|
|
|
- putExtra(EXTRA_START_ROUTE, ROUTE_EXPLORE_SHOW)
|
|
|
|
|
- putExtra(EXTRA_EXPLORE_NAME, exploreName)
|
|
|
|
|
- putExtra(EXTRA_SOURCE_URL, sourceUrl)
|
|
|
|
|
- putExtra(EXTRA_EXPLORE_URL, exploreUrl)
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- private fun routeForConfigTag(configTag: String?): String {
|
|
|
|
|
- return when (configTag) {
|
|
|
|
|
- ConfigTag.OTHER_CONFIG -> ROUTE_SETTINGS_OTHER
|
|
|
|
|
- ConfigTag.READ_CONFIG -> ROUTE_SETTINGS_READ
|
|
|
|
|
- ConfigTag.COVER_CONFIG -> ROUTE_SETTINGS_COVER
|
|
|
|
|
- ConfigTag.THEME_CONFIG -> ROUTE_SETTINGS_THEME
|
|
|
|
|
- ConfigTag.BACKUP_CONFIG -> ROUTE_SETTINGS_BACKUP
|
|
|
|
|
- ConfigTag.DOWNLOAD_CACHE_CONFIG -> ROUTE_SETTINGS_DOWNLOAD_CACHE
|
|
|
|
|
- else -> ROUTE_SETTINGS
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ ): Intent = MainIntent.createExploreShowIntent(context, exploreName, sourceUrl, exploreUrl)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private val viewModel by viewModel<MainViewModel>()
|
|
private val viewModel by viewModel<MainViewModel>()
|
|
|
private val routeEvents = MutableSharedFlow<NavKey>(extraBufferCapacity = 1)
|
|
private val routeEvents = MutableSharedFlow<NavKey>(extraBufferCapacity = 1)
|
|
|
private var bookInfoVariableSetter: ((String, String?) -> Unit)? = null
|
|
private var bookInfoVariableSetter: ((String, String?) -> Unit)? = null
|
|
|
|
|
|
|
|
- @Serializable
|
|
|
|
|
- private sealed interface MainRoute : NavKey
|
|
|
|
|
-
|
|
|
|
|
- @Serializable
|
|
|
|
|
- private data object MainRouteHome : MainRoute
|
|
|
|
|
-
|
|
|
|
|
- @Serializable
|
|
|
|
|
- private data object MainRouteSettings : MainRoute
|
|
|
|
|
-
|
|
|
|
|
- @Serializable
|
|
|
|
|
- private data object MainRouteSettingsOther : MainRoute
|
|
|
|
|
-
|
|
|
|
|
- @Serializable
|
|
|
|
|
- private data object MainRouteSettingsRead : MainRoute
|
|
|
|
|
-
|
|
|
|
|
- @Serializable
|
|
|
|
|
- private data object MainRouteSettingsCover : MainRoute
|
|
|
|
|
-
|
|
|
|
|
- @Serializable
|
|
|
|
|
- private data object MainRouteSettingsTheme : MainRoute
|
|
|
|
|
-
|
|
|
|
|
- @Serializable
|
|
|
|
|
- private data object MainRouteSettingsBackup : MainRoute
|
|
|
|
|
-
|
|
|
|
|
- @Serializable
|
|
|
|
|
- private data object MainRouteSettingsCustomTheme : MainRoute
|
|
|
|
|
-
|
|
|
|
|
- @Serializable
|
|
|
|
|
- private data object MainRouteSettingsThemeManage : MainRoute
|
|
|
|
|
-
|
|
|
|
|
- @Serializable
|
|
|
|
|
- private data object MainRouteSettingsDownloadCache : MainRoute
|
|
|
|
|
-
|
|
|
|
|
- @Serializable
|
|
|
|
|
- private data object MainRouteImportLocal : MainRoute
|
|
|
|
|
-
|
|
|
|
|
- @Serializable
|
|
|
|
|
- private data object MainRouteImportRemote : MainRoute
|
|
|
|
|
-
|
|
|
|
|
- @Serializable
|
|
|
|
|
- private data object MainRouteReadRecord : MainRoute
|
|
|
|
|
-
|
|
|
|
|
- @Serializable
|
|
|
|
|
- private data object MainRouteReadRecordOverview : MainRoute
|
|
|
|
|
-
|
|
|
|
|
- @Serializable
|
|
|
|
|
- private data class MainRouteCache(val groupId: Long) : MainRoute
|
|
|
|
|
-
|
|
|
|
|
- @Serializable
|
|
|
|
|
- private data object MainRouteBookCacheManage : MainRoute
|
|
|
|
|
-
|
|
|
|
|
- @Serializable
|
|
|
|
|
- private data class MainRouteSearch(
|
|
|
|
|
- val key: String?,
|
|
|
|
|
- val scopeRaw: String? = null
|
|
|
|
|
- ) : MainRoute
|
|
|
|
|
-
|
|
|
|
|
- @Serializable
|
|
|
|
|
- private data class MainRouteBookInfo(
|
|
|
|
|
- val name: String?,
|
|
|
|
|
- val author: String?,
|
|
|
|
|
- val bookUrl: String,
|
|
|
|
|
- ) : MainRoute
|
|
|
|
|
-
|
|
|
|
|
- @Serializable
|
|
|
|
|
- private data class MainRouteExploreShow(
|
|
|
|
|
- val title: String?,
|
|
|
|
|
- val sourceUrl: String,
|
|
|
|
|
- val exploreUrl: String?,
|
|
|
|
|
- ) : MainRoute
|
|
|
|
|
-
|
|
|
|
|
override fun onCreate(savedInstanceState: Bundle?) {
|
|
override fun onCreate(savedInstanceState: Bundle?) {
|
|
|
installSplashScreen()
|
|
installSplashScreen()
|
|
|
super.onCreate(savedInstanceState)
|
|
super.onCreate(savedInstanceState)
|
|
@@ -367,7 +145,7 @@ open class MainActivity : BaseComposeActivity(), VariableDialog.Callback {
|
|
|
override fun onNewIntent(intent: Intent) {
|
|
override fun onNewIntent(intent: Intent) {
|
|
|
super.onNewIntent(intent)
|
|
super.onNewIntent(intent)
|
|
|
setIntent(intent)
|
|
setIntent(intent)
|
|
|
- routeEvents.tryEmit(resolveStartRoute(intent))
|
|
|
|
|
|
|
+ routeEvents.tryEmit(MainNavigator.resolveStartRoute(intent))
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@OptIn(ExperimentalSharedTransitionApi::class)
|
|
@OptIn(ExperimentalSharedTransitionApi::class)
|
|
@@ -385,11 +163,11 @@ open class MainActivity : BaseComposeActivity(), VariableDialog.Callback {
|
|
|
else -> false
|
|
else -> false
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- val backStack = rememberNavBackStack(resolveStartRoute(intent))
|
|
|
|
|
|
|
+ val backStack = rememberNavBackStack(MainNavigator.resolveStartRoute(intent))
|
|
|
|
|
|
|
|
LaunchedEffect(backStack) {
|
|
LaunchedEffect(backStack) {
|
|
|
routeEvents.collect { route ->
|
|
routeEvents.collect { route ->
|
|
|
- navigateToRoute(backStack, route)
|
|
|
|
|
|
|
+ MainNavigator.navigateToRoute(backStack, route)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -397,556 +175,69 @@ open class MainActivity : BaseComposeActivity(), VariableDialog.Callback {
|
|
|
NavDisplay(
|
|
NavDisplay(
|
|
|
backStack = backStack,
|
|
backStack = backStack,
|
|
|
transitionSpec = {
|
|
transitionSpec = {
|
|
|
- (slideIntoContainer(
|
|
|
|
|
- towards = AnimatedContentTransitionScope.SlideDirection.Start,
|
|
|
|
|
- animationSpec = tween(
|
|
|
|
|
- durationMillis = 480,
|
|
|
|
|
- easing = FastOutSlowInEasing
|
|
|
|
|
- ),
|
|
|
|
|
- initialOffset = { fullWidth -> fullWidth }
|
|
|
|
|
- ) + fadeIn(
|
|
|
|
|
- animationSpec = tween(
|
|
|
|
|
- durationMillis = 360,
|
|
|
|
|
- easing = LinearOutSlowInEasing
|
|
|
|
|
- )
|
|
|
|
|
- )) togetherWith (slideOutOfContainer(
|
|
|
|
|
- towards = AnimatedContentTransitionScope.SlideDirection.Start,
|
|
|
|
|
- animationSpec = tween(
|
|
|
|
|
- durationMillis = 480,
|
|
|
|
|
- easing = FastOutSlowInEasing
|
|
|
|
|
- ),
|
|
|
|
|
- targetOffset = { fullWidth -> fullWidth / 4 }
|
|
|
|
|
- ) + fadeOut(
|
|
|
|
|
- animationSpec = tween(
|
|
|
|
|
- durationMillis = 360,
|
|
|
|
|
- easing = LinearOutSlowInEasing
|
|
|
|
|
- )
|
|
|
|
|
- ))
|
|
|
|
|
- },
|
|
|
|
|
- popTransitionSpec = {
|
|
|
|
|
- (slideIntoContainer(
|
|
|
|
|
- towards = AnimatedContentTransitionScope.SlideDirection.Start,
|
|
|
|
|
- animationSpec = tween(
|
|
|
|
|
- durationMillis = 480,
|
|
|
|
|
- easing = FastOutSlowInEasing
|
|
|
|
|
- ),
|
|
|
|
|
- initialOffset = { fullWidth -> -fullWidth / 4 }
|
|
|
|
|
- ) + fadeIn(
|
|
|
|
|
- animationSpec = tween(
|
|
|
|
|
- durationMillis = 360,
|
|
|
|
|
- easing = LinearOutSlowInEasing
|
|
|
|
|
- )
|
|
|
|
|
- )) togetherWith (scaleOut(
|
|
|
|
|
- targetScale = 0.8f,
|
|
|
|
|
- animationSpec = tween(
|
|
|
|
|
- durationMillis = 480,
|
|
|
|
|
- easing = FastOutSlowInEasing
|
|
|
|
|
- )
|
|
|
|
|
- ) + fadeOut(
|
|
|
|
|
- animationSpec = tween(durationMillis = 360)
|
|
|
|
|
- ))
|
|
|
|
|
- },
|
|
|
|
|
- predictivePopTransitionSpec = { _ ->
|
|
|
|
|
- (slideIntoContainer(
|
|
|
|
|
- towards = AnimatedContentTransitionScope.SlideDirection.Start,
|
|
|
|
|
- animationSpec = tween(
|
|
|
|
|
- easing = FastOutSlowInEasing
|
|
|
|
|
- ),
|
|
|
|
|
- initialOffset = { fullWidth -> -fullWidth / 4 }
|
|
|
|
|
- ) + fadeIn(
|
|
|
|
|
- animationSpec = tween(
|
|
|
|
|
- easing = LinearOutSlowInEasing
|
|
|
|
|
- )
|
|
|
|
|
- )) togetherWith (scaleOut(
|
|
|
|
|
- targetScale = 0.8f,
|
|
|
|
|
- animationSpec = tween(
|
|
|
|
|
- easing = FastOutSlowInEasing
|
|
|
|
|
- )
|
|
|
|
|
- ) + fadeOut(
|
|
|
|
|
- animationSpec = tween()
|
|
|
|
|
- ))
|
|
|
|
|
- },
|
|
|
|
|
- onBack = {
|
|
|
|
|
- if (backStack.size > 1) {
|
|
|
|
|
- backStack.removeLastOrNull()
|
|
|
|
|
- } else {
|
|
|
|
|
- finish()
|
|
|
|
|
- }
|
|
|
|
|
- },
|
|
|
|
|
- entryProvider = entryProvider {
|
|
|
|
|
- entry<MainRouteHome> {
|
|
|
|
|
- MainScreen(
|
|
|
|
|
- useRail = useRail,
|
|
|
|
|
- onOpenSettings = {
|
|
|
|
|
- navigateToRoute(backStack, MainRouteSettings)
|
|
|
|
|
- },
|
|
|
|
|
- onNavigateToSearch = { key ->
|
|
|
|
|
- navigateToRoute(
|
|
|
|
|
- backStack,
|
|
|
|
|
- MainRouteSearch(
|
|
|
|
|
- key = key?.trim()?.takeIf { it.isNotEmpty() }
|
|
|
|
|
- )
|
|
|
|
|
- )
|
|
|
|
|
- },
|
|
|
|
|
- onNavigateToRemoteImport = {
|
|
|
|
|
- navigateToRoute(backStack, MainRouteImportRemote)
|
|
|
|
|
- },
|
|
|
|
|
- onNavigateToLocalImport = {
|
|
|
|
|
- navigateToRoute(backStack, MainRouteImportLocal)
|
|
|
|
|
- },
|
|
|
|
|
- onNavigateToCache = { groupId ->
|
|
|
|
|
- navigateToRoute(backStack, MainRouteCache(groupId))
|
|
|
|
|
- },
|
|
|
|
|
- onNavigateToBookCacheManage = {
|
|
|
|
|
- navigateToRoute(backStack, MainRouteBookCacheManage)
|
|
|
|
|
- },
|
|
|
|
|
- onNavigateToBookInfo = { name, author, bookUrl ->
|
|
|
|
|
- navigateToRoute(
|
|
|
|
|
- backStack,
|
|
|
|
|
- MainRouteBookInfo(
|
|
|
|
|
- name = name,
|
|
|
|
|
- author = author,
|
|
|
|
|
- bookUrl = bookUrl
|
|
|
|
|
- )
|
|
|
|
|
- )
|
|
|
|
|
- },
|
|
|
|
|
- onNavigateToExploreShow = { title, sourceUrl, exploreUrl ->
|
|
|
|
|
- navigateToRoute(
|
|
|
|
|
- backStack,
|
|
|
|
|
- MainRouteExploreShow(
|
|
|
|
|
- title = title,
|
|
|
|
|
- sourceUrl = sourceUrl,
|
|
|
|
|
- exploreUrl = exploreUrl
|
|
|
|
|
- )
|
|
|
|
|
- )
|
|
|
|
|
- },
|
|
|
|
|
- onNavigateToRssSort = { sourceUrl, sortUrl, key ->
|
|
|
|
|
- navigateToRoute(
|
|
|
|
|
- backStack,
|
|
|
|
|
- MainRouteRssSort(
|
|
|
|
|
- sourceUrl = sourceUrl,
|
|
|
|
|
- sortUrl = sortUrl,
|
|
|
|
|
- key = key
|
|
|
|
|
- )
|
|
|
|
|
- )
|
|
|
|
|
- },
|
|
|
|
|
- onNavigateToRssRead = { title, origin, link, openUrl ->
|
|
|
|
|
- navigateToRoute(
|
|
|
|
|
- backStack,
|
|
|
|
|
- MainRouteRssRead(
|
|
|
|
|
- title = title,
|
|
|
|
|
- origin = origin,
|
|
|
|
|
- link = link,
|
|
|
|
|
- openUrl = openUrl
|
|
|
|
|
- )
|
|
|
|
|
- )
|
|
|
|
|
- },
|
|
|
|
|
- onNavigateToReadRecord = {
|
|
|
|
|
- navigateToRoute(backStack, MainRouteReadRecord)
|
|
|
|
|
- },
|
|
|
|
|
- sharedTransitionScope = this@SharedTransitionLayout,
|
|
|
|
|
- animatedVisibilityScope = LocalNavAnimatedContentScope.current,
|
|
|
|
|
- )
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- entry<MainRouteSettings> {
|
|
|
|
|
- ConfigNavScreen(
|
|
|
|
|
- onBackClick = { navigateBack(backStack) },
|
|
|
|
|
- onNavigateToOther = { backStack.add(MainRouteSettingsOther) },
|
|
|
|
|
- onNavigateToRead = { backStack.add(MainRouteSettingsRead) },
|
|
|
|
|
- onNavigateToCover = { backStack.add(MainRouteSettingsCover) },
|
|
|
|
|
- onNavigateToTheme = { backStack.add(MainRouteSettingsTheme) },
|
|
|
|
|
- onNavigateToBackup = { backStack.add(MainRouteSettingsBackup) },
|
|
|
|
|
- onNavigateToDownloadCache = { backStack.add(MainRouteSettingsDownloadCache) }
|
|
|
|
|
- )
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- entry<MainRouteSettingsOther> {
|
|
|
|
|
- OtherConfigScreen(onBackClick = { navigateBack(backStack) })
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- entry<MainRouteSettingsRead> {
|
|
|
|
|
- ReadConfigScreen(onBackClick = { navigateBack(backStack) })
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- entry<MainRouteSettingsCover> {
|
|
|
|
|
- CoverConfigScreen(onBackClick = { navigateBack(backStack) })
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- entry<MainRouteSettingsTheme> {
|
|
|
|
|
- ThemeConfigScreen(
|
|
|
|
|
- onBackClick = { navigateBack(backStack) },
|
|
|
|
|
- onNavigateToCustomTheme = { backStack.add(MainRouteSettingsCustomTheme) },
|
|
|
|
|
- onNavigateToThemeManage = { backStack.add(MainRouteSettingsThemeManage) }
|
|
|
|
|
- )
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- entry<MainRouteSettingsBackup> {
|
|
|
|
|
- BackupConfigScreen(onBackClick = { navigateBack(backStack) })
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- entry<MainRouteSettingsDownloadCache> {
|
|
|
|
|
- DownloadCacheConfigScreen(onBackClick = { navigateBack(backStack) })
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- entry<MainRouteSettingsCustomTheme> {
|
|
|
|
|
- CustomThemeScreen(
|
|
|
|
|
- onBackClick = { navigateBack(backStack) }
|
|
|
|
|
- )
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- entry<MainRouteSettingsThemeManage> {
|
|
|
|
|
- ThemeManageScreen(onBackClick = { navigateBack(backStack) })
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- entry<MainRouteImportLocal> {
|
|
|
|
|
- ImportBookScreen(
|
|
|
|
|
- onBackClick = { navigateBack(backStack) }
|
|
|
|
|
- )
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- entry<MainRouteImportRemote> {
|
|
|
|
|
- RemoteBookScreen(
|
|
|
|
|
- onBackClick = { navigateBack(backStack) }
|
|
|
|
|
- )
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- entry<MainRouteCache> { route ->
|
|
|
|
|
- BookshelfManageRouteScreen(
|
|
|
|
|
- groupId = route.groupId,
|
|
|
|
|
- onBackClick = { navigateBack(backStack) },
|
|
|
|
|
- onOpenBookInfo = { name, author, bookUrl ->
|
|
|
|
|
- navigateToRoute(
|
|
|
|
|
- backStack,
|
|
|
|
|
- MainRouteBookInfo(
|
|
|
|
|
- name = name,
|
|
|
|
|
- author = author,
|
|
|
|
|
- bookUrl = bookUrl
|
|
|
|
|
- )
|
|
|
|
|
- )
|
|
|
|
|
- }
|
|
|
|
|
- )
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- entry<MainRouteBookCacheManage> {
|
|
|
|
|
- BookCacheManageRouteScreen(
|
|
|
|
|
- onBackClick = { navigateBack(backStack) }
|
|
|
|
|
- )
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- entry<MainRouteSearch> { route ->
|
|
|
|
|
- val searchViewModel = koinViewModel<SearchViewModel>()
|
|
|
|
|
-
|
|
|
|
|
- LaunchedEffect(route.key, route.scopeRaw, searchViewModel) {
|
|
|
|
|
- searchViewModel.onIntent(
|
|
|
|
|
- SearchIntent.Initialize(
|
|
|
|
|
- key = route.key,
|
|
|
|
|
- scopeRaw = route.scopeRaw
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ (slideIntoContainer(
|
|
|
|
|
+ towards = AnimatedContentTransitionScope.SlideDirection.Start,
|
|
|
|
|
+ animationSpec = tween(durationMillis = 480, easing = FastOutSlowInEasing),
|
|
|
|
|
+ initialOffset = { fullWidth -> fullWidth }
|
|
|
|
|
+ ) + fadeIn(
|
|
|
|
|
+ animationSpec = tween(
|
|
|
|
|
+ durationMillis = 360,
|
|
|
|
|
+ easing = LinearOutSlowInEasing
|
|
|
)
|
|
)
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- SearchScreen(
|
|
|
|
|
- viewModel = searchViewModel,
|
|
|
|
|
- onBack = {
|
|
|
|
|
- searchViewModel.onIntent(SearchIntent.ClearSearchResults)
|
|
|
|
|
- navigateBack(backStack)
|
|
|
|
|
- },
|
|
|
|
|
- onOpenBookInfo = { name, author, bookUrl ->
|
|
|
|
|
- navigateToRoute(
|
|
|
|
|
- backStack,
|
|
|
|
|
- MainRouteBookInfo(
|
|
|
|
|
- name = name,
|
|
|
|
|
- author = author,
|
|
|
|
|
- bookUrl = bookUrl
|
|
|
|
|
- )
|
|
|
|
|
- )
|
|
|
|
|
- },
|
|
|
|
|
- onOpenSourceManage = {
|
|
|
|
|
- this@MainActivity.startActivity<BookSourceActivity>()
|
|
|
|
|
- },
|
|
|
|
|
- sharedTransitionScope = this@SharedTransitionLayout,
|
|
|
|
|
- animatedVisibilityScope = LocalNavAnimatedContentScope.current,
|
|
|
|
|
- )
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- entry<MainRouteRssSort> { route ->
|
|
|
|
|
- RssSortRouteScreen(
|
|
|
|
|
- sourceUrl = route.sourceUrl,
|
|
|
|
|
- initialSortUrl = route.sortUrl,
|
|
|
|
|
- onBackClick = { navigateBack(backStack) },
|
|
|
|
|
- onOpenRead = { title, origin, link, openUrl ->
|
|
|
|
|
- if (link?.contains("@js:") == true) {
|
|
|
|
|
- navigateToRoute(
|
|
|
|
|
- backStack,
|
|
|
|
|
- MainRouteRssSort(
|
|
|
|
|
- sourceUrl = origin,
|
|
|
|
|
- sortUrl = link
|
|
|
|
|
- )
|
|
|
|
|
- )
|
|
|
|
|
- } else {
|
|
|
|
|
- navigateToRoute(
|
|
|
|
|
- backStack,
|
|
|
|
|
- MainRouteRssRead(
|
|
|
|
|
- title = title,
|
|
|
|
|
- origin = origin,
|
|
|
|
|
- link = link,
|
|
|
|
|
- openUrl = openUrl
|
|
|
|
|
- )
|
|
|
|
|
- )
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- )
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- entry<MainRouteRssRead> { route ->
|
|
|
|
|
- RssReadRouteScreen(
|
|
|
|
|
- title = route.title,
|
|
|
|
|
- origin = route.origin,
|
|
|
|
|
- link = route.link,
|
|
|
|
|
- openUrl = route.openUrl,
|
|
|
|
|
- onBackClick = { navigateBack(backStack) }
|
|
|
|
|
- )
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- entry<MainRouteReadRecord> {
|
|
|
|
|
- ReadRecordScreen(
|
|
|
|
|
- onBackClick = { navigateBack(backStack) },
|
|
|
|
|
- onBookClick = { name, author ->
|
|
|
|
|
- lifecycleScope.launch {
|
|
|
|
|
- val book = withContext(IO) {
|
|
|
|
|
- io.legado.app.data.appDb.bookDao.getBook(name, author)
|
|
|
|
|
- }
|
|
|
|
|
- if (book != null) this@MainActivity.startActivityForBook(book)
|
|
|
|
|
- else {
|
|
|
|
|
- navigateToRoute(backStack, MainRouteSearch(key = name))
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- },
|
|
|
|
|
- onSummaryClick = {
|
|
|
|
|
- navigateToRoute(backStack, MainRouteReadRecordOverview)
|
|
|
|
|
- }
|
|
|
|
|
- )
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- entry<MainRouteReadRecordOverview> {
|
|
|
|
|
- ReadRecordOverviewScreen(
|
|
|
|
|
- onBackClick = { navigateBack(backStack) },
|
|
|
|
|
- onBookClick = { name, author ->
|
|
|
|
|
- lifecycleScope.launch {
|
|
|
|
|
- val book = withContext(IO) {
|
|
|
|
|
- io.legado.app.data.appDb.bookDao.getBook(name, author)
|
|
|
|
|
- }
|
|
|
|
|
- if (book != null) this@MainActivity.startActivityForBook(book)
|
|
|
|
|
- else {
|
|
|
|
|
- navigateToRoute(backStack, MainRouteSearch(key = name))
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- )
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- entry<MainRouteBookInfo>(
|
|
|
|
|
- metadata = NavDisplay.transitionSpec {
|
|
|
|
|
- val from = initialState.key
|
|
|
|
|
- val fromStr = from.toString()
|
|
|
|
|
- if (from is MainRouteHome || from is MainRouteExploreShow || from is MainRouteSearch ||
|
|
|
|
|
- fromStr.startsWith("MainRouteHome") || fromStr.startsWith("MainRouteExploreShow") || fromStr.startsWith("MainRouteSearch")) {
|
|
|
|
|
- fadeIn(animationSpec = tween(300)) togetherWith
|
|
|
|
|
- fadeOut(animationSpec = tween(300))
|
|
|
|
|
- } else null
|
|
|
|
|
- } + NavDisplay.popTransitionSpec {
|
|
|
|
|
- val to = targetState.key
|
|
|
|
|
- val toStr = to.toString()
|
|
|
|
|
- if (to is MainRouteHome || to is MainRouteExploreShow || to is MainRouteSearch ||
|
|
|
|
|
- toStr.startsWith("MainRouteHome") || toStr.startsWith("MainRouteExploreShow") || toStr.startsWith("MainRouteSearch")) {
|
|
|
|
|
- fadeIn(animationSpec = tween(300)) togetherWith
|
|
|
|
|
- fadeOut(animationSpec = tween(300))
|
|
|
|
|
- } else null
|
|
|
|
|
- } + NavDisplay.predictivePopTransitionSpec { _ ->
|
|
|
|
|
- val to = targetState.key
|
|
|
|
|
- val toStr = to.toString()
|
|
|
|
|
- if (to is MainRouteHome || to is MainRouteExploreShow || to is MainRouteSearch ||
|
|
|
|
|
- toStr.startsWith("MainRouteHome") || toStr.startsWith("MainRouteExploreShow") || toStr.startsWith("MainRouteSearch")) {
|
|
|
|
|
- fadeIn(animationSpec = tween(300)) togetherWith
|
|
|
|
|
- fadeOut(animationSpec = tween(300))
|
|
|
|
|
- } else null
|
|
|
|
|
- }
|
|
|
|
|
- ) { route ->
|
|
|
|
|
- val bookInfoViewModel = koinViewModel<BookInfoViewModel>()
|
|
|
|
|
- BookInfoRouteScreen(
|
|
|
|
|
- bookUrl = route.bookUrl,
|
|
|
|
|
- viewModel = bookInfoViewModel,
|
|
|
|
|
- onBack = { navigateBack(backStack) },
|
|
|
|
|
- onFinish = { _, _ -> navigateBack(backStack) },
|
|
|
|
|
- onOpenSearch = { keyword ->
|
|
|
|
|
- navigateToRoute(backStack, MainRouteSearch(key = keyword))
|
|
|
|
|
- },
|
|
|
|
|
- sharedTransitionScope = this@SharedTransitionLayout,
|
|
|
|
|
- animatedVisibilityScope = LocalNavAnimatedContentScope.current,
|
|
|
|
|
- sharedCoverKey = bookCoverSharedElementKey(route.bookUrl),
|
|
|
|
|
- onRegisterVariableSetter = { setter ->
|
|
|
|
|
- bookInfoVariableSetter = setter
|
|
|
|
|
- }
|
|
|
|
|
- )
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- entry<MainRouteExploreShow> { route ->
|
|
|
|
|
- ExploreShowScreen(
|
|
|
|
|
- title = route.title ?: "探索",
|
|
|
|
|
- sourceUrl = route.sourceUrl,
|
|
|
|
|
- exploreUrl = route.exploreUrl,
|
|
|
|
|
- onBack = { navigateBack(backStack) },
|
|
|
|
|
- onBookClick = { book ->
|
|
|
|
|
- navigateToRoute(
|
|
|
|
|
- backStack,
|
|
|
|
|
- MainRouteBookInfo(
|
|
|
|
|
- name = book.name,
|
|
|
|
|
- author = book.author,
|
|
|
|
|
- bookUrl = book.bookUrl
|
|
|
|
|
- )
|
|
|
|
|
- )
|
|
|
|
|
- },
|
|
|
|
|
- sharedTransitionScope = this@SharedTransitionLayout,
|
|
|
|
|
- animatedVisibilityScope = LocalNavAnimatedContentScope.current,
|
|
|
|
|
- )
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ )) togetherWith (slideOutOfContainer(
|
|
|
|
|
+ towards = AnimatedContentTransitionScope.SlideDirection.Start,
|
|
|
|
|
+ animationSpec = tween(durationMillis = 480, easing = FastOutSlowInEasing),
|
|
|
|
|
+ targetOffset = { fullWidth -> fullWidth / 4 }
|
|
|
|
|
+ ) + fadeOut(
|
|
|
|
|
+ animationSpec = tween(
|
|
|
|
|
+ durationMillis = 360,
|
|
|
|
|
+ easing = LinearOutSlowInEasing
|
|
|
|
|
+ )
|
|
|
|
|
+ ))
|
|
|
|
|
+ },
|
|
|
|
|
+ popTransitionSpec = {
|
|
|
|
|
+ (slideIntoContainer(
|
|
|
|
|
+ towards = AnimatedContentTransitionScope.SlideDirection.Start,
|
|
|
|
|
+ animationSpec = tween(durationMillis = 480, easing = FastOutSlowInEasing),
|
|
|
|
|
+ initialOffset = { fullWidth -> -fullWidth / 4 }
|
|
|
|
|
+ ) + fadeIn(
|
|
|
|
|
+ animationSpec = tween(
|
|
|
|
|
+ durationMillis = 360,
|
|
|
|
|
+ easing = LinearOutSlowInEasing
|
|
|
|
|
+ )
|
|
|
|
|
+ )) togetherWith (scaleOut(
|
|
|
|
|
+ targetScale = 0.8f,
|
|
|
|
|
+ animationSpec = tween(durationMillis = 480, easing = FastOutSlowInEasing)
|
|
|
|
|
+ ) + fadeOut(animationSpec = tween(durationMillis = 360)))
|
|
|
|
|
+ },
|
|
|
|
|
+ predictivePopTransitionSpec = { _ ->
|
|
|
|
|
+ (slideIntoContainer(
|
|
|
|
|
+ towards = AnimatedContentTransitionScope.SlideDirection.Start,
|
|
|
|
|
+ animationSpec = tween(easing = FastOutSlowInEasing),
|
|
|
|
|
+ initialOffset = { fullWidth -> -fullWidth / 4 }
|
|
|
|
|
+ ) + fadeIn(animationSpec = tween(easing = LinearOutSlowInEasing))) togetherWith (scaleOut(
|
|
|
|
|
+ targetScale = 0.8f,
|
|
|
|
|
+ animationSpec = tween(easing = FastOutSlowInEasing)
|
|
|
|
|
+ ) + fadeOut(animationSpec = tween()))
|
|
|
|
|
+ },
|
|
|
|
|
+ onBack = { MainNavigator.navigateBack(this@MainActivity, backStack) },
|
|
|
|
|
+ entryProvider = mainEntryProvider(
|
|
|
|
|
+ backStack = backStack,
|
|
|
|
|
+ useRail = useRail,
|
|
|
|
|
+ sharedTransitionScope = this@SharedTransitionLayout,
|
|
|
|
|
+ onNavigateToRoute = { route ->
|
|
|
|
|
+ MainNavigator.navigateToRoute(
|
|
|
|
|
+ backStack,
|
|
|
|
|
+ route
|
|
|
|
|
+ )
|
|
|
|
|
+ },
|
|
|
|
|
+ onNavigateBack = { MainNavigator.navigateBack(this@MainActivity, backStack) },
|
|
|
|
|
+ onRegisterVariableSetter = { setter -> bookInfoVariableSetter = setter }
|
|
|
|
|
+ )
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private fun navigateToRoute(backStack: MutableList<NavKey>, route: NavKey) {
|
|
|
|
|
- val currentRoute = backStack.lastOrNull()
|
|
|
|
|
- if (currentRoute == route) return
|
|
|
|
|
-
|
|
|
|
|
- when (route) {
|
|
|
|
|
- MainRouteHome -> {
|
|
|
|
|
- backStack.clear()
|
|
|
|
|
- backStack.add(MainRouteHome)
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- MainRouteSettings -> {
|
|
|
|
|
- if (currentRoute == MainRouteHome) {
|
|
|
|
|
- backStack.add(MainRouteSettings)
|
|
|
|
|
- } else {
|
|
|
|
|
- backStack.clear()
|
|
|
|
|
- backStack.add(MainRouteHome)
|
|
|
|
|
- backStack.add(MainRouteSettings)
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- MainRouteSettingsOther,
|
|
|
|
|
- MainRouteSettingsRead,
|
|
|
|
|
- MainRouteSettingsCover,
|
|
|
|
|
- MainRouteSettingsTheme,
|
|
|
|
|
- MainRouteSettingsBackup,
|
|
|
|
|
- MainRouteSettingsCustomTheme,
|
|
|
|
|
- MainRouteSettingsThemeManage,
|
|
|
|
|
- MainRouteSettingsDownloadCache -> {
|
|
|
|
|
- backStack.clear()
|
|
|
|
|
- backStack.add(MainRouteHome)
|
|
|
|
|
- backStack.add(MainRouteSettings)
|
|
|
|
|
- backStack.add(route)
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- MainRouteImportLocal,
|
|
|
|
|
- MainRouteImportRemote,
|
|
|
|
|
- is MainRouteCache,
|
|
|
|
|
- MainRouteBookCacheManage -> {
|
|
|
|
|
- if (currentRoute == MainRouteHome) {
|
|
|
|
|
- backStack.add(route)
|
|
|
|
|
- } else {
|
|
|
|
|
- backStack.clear()
|
|
|
|
|
- backStack.add(MainRouteHome)
|
|
|
|
|
- backStack.add(route)
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- is MainRouteSearch -> {
|
|
|
|
|
- if (currentRoute == MainRouteHome) {
|
|
|
|
|
- backStack.add(route)
|
|
|
|
|
- } else {
|
|
|
|
|
- backStack.clear()
|
|
|
|
|
- backStack.add(MainRouteHome)
|
|
|
|
|
- backStack.add(route)
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- is MainRouteBookInfo -> {
|
|
|
|
|
- if (
|
|
|
|
|
- currentRoute == MainRouteHome ||
|
|
|
|
|
- currentRoute is MainRouteSearch ||
|
|
|
|
|
- currentRoute is MainRouteExploreShow
|
|
|
|
|
- ) {
|
|
|
|
|
- backStack.add(route)
|
|
|
|
|
- } else {
|
|
|
|
|
- backStack.clear()
|
|
|
|
|
- backStack.add(MainRouteHome)
|
|
|
|
|
- backStack.add(route)
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- is MainRouteExploreShow -> {
|
|
|
|
|
- if (currentRoute == MainRouteHome) {
|
|
|
|
|
- backStack.add(route)
|
|
|
|
|
- } else {
|
|
|
|
|
- backStack.clear()
|
|
|
|
|
- backStack.add(MainRouteHome)
|
|
|
|
|
- backStack.add(route)
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- is MainRouteRssSort -> {
|
|
|
|
|
- if (currentRoute == MainRouteHome) {
|
|
|
|
|
- backStack.add(route)
|
|
|
|
|
- } else {
|
|
|
|
|
- backStack.clear()
|
|
|
|
|
- backStack.add(MainRouteHome)
|
|
|
|
|
- backStack.add(route)
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- is MainRouteRssRead -> {
|
|
|
|
|
- if (currentRoute == MainRouteHome || currentRoute is MainRouteRssSort) {
|
|
|
|
|
- backStack.add(route)
|
|
|
|
|
- } else {
|
|
|
|
|
- backStack.clear()
|
|
|
|
|
- backStack.add(MainRouteHome)
|
|
|
|
|
- backStack.add(route)
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- MainRouteReadRecord -> {
|
|
|
|
|
- if (currentRoute == MainRouteHome) {
|
|
|
|
|
- backStack.add(route)
|
|
|
|
|
- } else {
|
|
|
|
|
- backStack.clear()
|
|
|
|
|
- backStack.add(MainRouteHome)
|
|
|
|
|
- backStack.add(route)
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- MainRouteReadRecordOverview -> {
|
|
|
|
|
- if (currentRoute == MainRouteHome || currentRoute == MainRouteReadRecord) {
|
|
|
|
|
- backStack.add(route)
|
|
|
|
|
- } else {
|
|
|
|
|
- backStack.clear()
|
|
|
|
|
- backStack.add(MainRouteHome)
|
|
|
|
|
- backStack.add(route)
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- private fun navigateBack(backStack: MutableList<NavKey>) {
|
|
|
|
|
- if (backStack.size > 1) {
|
|
|
|
|
- backStack.removeLastOrNull()
|
|
|
|
|
- } else {
|
|
|
|
|
- finish()
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
private fun checkStartupRoute(): Boolean {
|
|
private fun checkStartupRoute(): Boolean {
|
|
|
return when {
|
|
return when {
|
|
|
LocalConfig.isFirstOpenApp -> {
|
|
LocalConfig.isFirstOpenApp -> {
|
|
@@ -1057,96 +348,6 @@ open class MainActivity : BaseComposeActivity(), VariableDialog.Callback {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private fun resolveStartRoute(intent: Intent?): NavKey {
|
|
|
|
|
- val route = intent?.getStringExtra(EXTRA_START_ROUTE)
|
|
|
|
|
- resolveRssStartRoute(route, intent)?.let { return it }
|
|
|
|
|
- return resolveStartRoute(route)
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- private fun resolveRssStartRoute(route: String?, intent: Intent?): NavKey? {
|
|
|
|
|
- return when (route) {
|
|
|
|
|
- ROUTE_RSS_SORT -> {
|
|
|
|
|
- val sourceUrl = intent?.getStringExtra(EXTRA_RSS_SOURCE_URL)
|
|
|
|
|
- if (sourceUrl.isNullOrBlank()) {
|
|
|
|
|
- null
|
|
|
|
|
- } else {
|
|
|
|
|
- MainRouteRssSort(
|
|
|
|
|
- sourceUrl = sourceUrl,
|
|
|
|
|
- sortUrl = intent.getStringExtra(EXTRA_RSS_SORT_URL),
|
|
|
|
|
- key = intent.getStringExtra(EXTRA_RSS_KEY)
|
|
|
|
|
- )
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- ROUTE_RSS_READ -> {
|
|
|
|
|
- val origin = intent?.getStringExtra(EXTRA_RSS_READ_ORIGIN)
|
|
|
|
|
- if (origin.isNullOrBlank()) {
|
|
|
|
|
- null
|
|
|
|
|
- } else {
|
|
|
|
|
- MainRouteRssRead(
|
|
|
|
|
- title = intent.getStringExtra(EXTRA_RSS_READ_TITLE),
|
|
|
|
|
- origin = origin,
|
|
|
|
|
- link = intent.getStringExtra(EXTRA_RSS_READ_LINK),
|
|
|
|
|
- openUrl = intent.getStringExtra(EXTRA_RSS_READ_OPEN_URL)
|
|
|
|
|
- )
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- else -> null
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- private fun resolveStartRoute(route: String?): MainRoute {
|
|
|
|
|
- return when (route) {
|
|
|
|
|
- "main" -> MainRouteHome
|
|
|
|
|
- "settings" -> MainRouteSettings
|
|
|
|
|
- "settings/other" -> MainRouteSettingsOther
|
|
|
|
|
- "settings/read" -> MainRouteSettingsRead
|
|
|
|
|
- "settings/cover" -> MainRouteSettingsCover
|
|
|
|
|
- "settings/theme" -> MainRouteSettingsTheme
|
|
|
|
|
- "settings/backup" -> MainRouteSettingsBackup
|
|
|
|
|
- "settings/custom_theme" -> MainRouteSettingsCustomTheme
|
|
|
|
|
- "settings/download_cache" -> MainRouteSettingsDownloadCache
|
|
|
|
|
- "import/local" -> MainRouteImportLocal
|
|
|
|
|
- "import/remote" -> MainRouteImportRemote
|
|
|
|
|
- ROUTE_MAIN -> MainRouteHome
|
|
|
|
|
- ROUTE_SETTINGS -> MainRouteSettings
|
|
|
|
|
- ROUTE_SETTINGS_OTHER -> MainRouteSettingsOther
|
|
|
|
|
- ROUTE_SETTINGS_READ -> MainRouteSettingsRead
|
|
|
|
|
- ROUTE_SETTINGS_COVER -> MainRouteSettingsCover
|
|
|
|
|
- ROUTE_SETTINGS_THEME -> MainRouteSettingsTheme
|
|
|
|
|
- ROUTE_SETTINGS_BACKUP -> MainRouteSettingsBackup
|
|
|
|
|
- ROUTE_SETTINGS_DOWNLOAD_CACHE -> MainRouteSettingsDownloadCache
|
|
|
|
|
- ROUTE_IMPORT_LOCAL -> MainRouteImportLocal
|
|
|
|
|
- ROUTE_IMPORT_REMOTE -> MainRouteImportRemote
|
|
|
|
|
- ROUTE_CACHE -> MainRouteCache(intent?.getLongExtra(EXTRA_CACHE_GROUP_ID, -1L) ?: -1L)
|
|
|
|
|
- ROUTE_BOOK_CACHE_MANAGE -> MainRouteBookCacheManage
|
|
|
|
|
- ROUTE_SEARCH -> MainRouteSearch(
|
|
|
|
|
- key = intent?.getStringExtra(EXTRA_SEARCH_KEY),
|
|
|
|
|
- scopeRaw = intent?.getStringExtra(EXTRA_SEARCH_SCOPE)
|
|
|
|
|
- )
|
|
|
|
|
- ROUTE_BOOK_INFO -> intent?.getStringExtra(EXTRA_BOOK_URL)
|
|
|
|
|
- ?.takeIf { it.isNotBlank() }
|
|
|
|
|
- ?.let { bookUrl ->
|
|
|
|
|
- MainRouteBookInfo(
|
|
|
|
|
- name = intent.getStringExtra(EXTRA_BOOK_NAME),
|
|
|
|
|
- author = intent.getStringExtra(EXTRA_BOOK_AUTHOR),
|
|
|
|
|
- bookUrl = bookUrl
|
|
|
|
|
- )
|
|
|
|
|
- } ?: MainRouteHome
|
|
|
|
|
- ROUTE_EXPLORE_SHOW -> intent?.getStringExtra(EXTRA_SOURCE_URL)
|
|
|
|
|
- ?.takeIf { it.isNotBlank() }
|
|
|
|
|
- ?.let { sourceUrl ->
|
|
|
|
|
- MainRouteExploreShow(
|
|
|
|
|
- title = intent.getStringExtra(EXTRA_EXPLORE_NAME),
|
|
|
|
|
- sourceUrl = sourceUrl,
|
|
|
|
|
- exploreUrl = intent.getStringExtra(EXTRA_EXPLORE_URL)
|
|
|
|
|
- )
|
|
|
|
|
- } ?: MainRouteHome
|
|
|
|
|
- else -> MainRouteHome
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
override fun setVariable(key: String, variable: String?) {
|
|
override fun setVariable(key: String, variable: String?) {
|
|
|
bookInfoVariableSetter?.invoke(key, variable)
|
|
bookInfoVariableSetter?.invoke(key, variable)
|
|
|
}
|
|
}
|