界面优化
This commit is contained in:
23 files changed
+1234
-1072
No files matched your search
@@ -193,11 +193,6 @@
|
|||||||
android:name=".ui.qrcode.QrCodeActivity"
|
android:name=".ui.qrcode.QrCodeActivity"
|
||||||
android:enableOnBackInvokedCallback="true"
|
android:enableOnBackInvokedCallback="true"
|
||||||
android:launchMode="singleTask" />
|
android:launchMode="singleTask" />
|
||||||
<!-- 规则订阅 -->
|
|
||||||
<activity
|
|
||||||
android:name=".ui.rss.subscription.RuleSubActivity"
|
|
||||||
android:enableOnBackInvokedCallback="true"
|
|
||||||
android:launchMode="singleTask" />
|
|
||||||
<!-- 书源编辑 -->
|
<!-- 书源编辑 -->
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.book.source.edit.BookSourceEditActivity"
|
android:name=".ui.book.source.edit.BookSourceEditActivity"
|
||||||
@@ -268,11 +263,6 @@
|
|||||||
android:name=".ui.rss.source.debug.RssSourceDebugActivity"
|
android:name=".ui.rss.source.debug.RssSourceDebugActivity"
|
||||||
android:enableOnBackInvokedCallback="true"
|
android:enableOnBackInvokedCallback="true"
|
||||||
android:launchMode="singleTop" />
|
android:launchMode="singleTop" />
|
||||||
<!-- Rss收藏 -->
|
|
||||||
<activity
|
|
||||||
android:name=".ui.rss.favorites.RssFavoritesActivity"
|
|
||||||
android:enableOnBackInvokedCallback="true"
|
|
||||||
android:launchMode="singleTop" />
|
|
||||||
<!-- 书签 -->
|
<!-- 书签 -->
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.book.bookmark.AllBookmarkActivity"
|
android:name=".ui.book.bookmark.AllBookmarkActivity"
|
||||||
|
|||||||
@@ -271,6 +271,7 @@ object PreferKey {
|
|||||||
const val bookshelfCoverShadow = "bookshelfCoverShadow"
|
const val bookshelfCoverShadow = "bookshelfCoverShadow"
|
||||||
const val bookshelfSearchActionDirectToSearch = "bookshelfSearchActionDirectToSearch"
|
const val bookshelfSearchActionDirectToSearch = "bookshelfSearchActionDirectToSearch"
|
||||||
const val bookshelfCardColor = "bookshelfCardColor"
|
const val bookshelfCardColor = "bookshelfCardColor"
|
||||||
|
const val bookshelfCardColorDark = "bookshelfCardColorDark"
|
||||||
const val bookshelfGroupListStyle = "bookshelfGroupListStyle"
|
const val bookshelfGroupListStyle = "bookshelfGroupListStyle"
|
||||||
const val bookshelfGroupCoverCount = "bookshelfGroupCoverCount"
|
const val bookshelfGroupCoverCount = "bookshelfGroupCoverCount"
|
||||||
|
|
||||||
|
|||||||
@@ -723,8 +723,8 @@ interface BookDao {
|
|||||||
type, `group`, `order`, canUpdate,
|
type, `group`, `order`, canUpdate,
|
||||||
ifnull(customIntro, intro) as intro, kind
|
ifnull(customIntro, intro) as intro, kind
|
||||||
FROM books
|
FROM books
|
||||||
ORDER BY CASE WHEN (coverUrl IS NOT NULL OR customCoverUrl IS NOT NULL) THEN 0 ELSE 1 END, durChapterTime DESC
|
ORDER BY durChapterTime DESC
|
||||||
LIMIT 4
|
LIMIT 10
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
fun flowBookShelfPreview(): Flow<List<BookShelfItem>>
|
fun flowBookShelfPreview(): Flow<List<BookShelfItem>>
|
||||||
@@ -741,8 +741,8 @@ interface BookDao {
|
|||||||
WHERE type & ${BookType.text} > 0 AND type & ${BookType.local} = 0
|
WHERE type & ${BookType.text} > 0 AND type & ${BookType.local} = 0
|
||||||
AND ((SELECT COALESCE(SUM(groupId), 0) FROM book_groups WHERE groupId > 0) & `group`) = 0
|
AND ((SELECT COALESCE(SUM(groupId), 0) FROM book_groups WHERE groupId > 0) & `group`) = 0
|
||||||
AND (SELECT show FROM book_groups WHERE groupId = ${BookGroup.IdNetNone}) != 1
|
AND (SELECT show FROM book_groups WHERE groupId = ${BookGroup.IdNetNone}) != 1
|
||||||
ORDER BY CASE WHEN (coverUrl IS NOT NULL OR customCoverUrl IS NOT NULL) THEN 0 ELSE 1 END, durChapterTime DESC
|
ORDER BY durChapterTime DESC
|
||||||
LIMIT 4
|
LIMIT 10
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
fun flowBookShelfRootPreview(): Flow<List<BookShelfItem>>
|
fun flowBookShelfRootPreview(): Flow<List<BookShelfItem>>
|
||||||
@@ -757,8 +757,8 @@ interface BookDao {
|
|||||||
ifnull(customIntro, intro) as intro, kind
|
ifnull(customIntro, intro) as intro, kind
|
||||||
FROM books
|
FROM books
|
||||||
WHERE type & ${BookType.local} > 0
|
WHERE type & ${BookType.local} > 0
|
||||||
ORDER BY CASE WHEN (coverUrl IS NOT NULL OR customCoverUrl IS NOT NULL) THEN 0 ELSE 1 END, durChapterTime DESC
|
ORDER BY durChapterTime DESC
|
||||||
LIMIT 4
|
LIMIT 10
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
fun flowBookShelfLocalPreview(): Flow<List<BookShelfItem>>
|
fun flowBookShelfLocalPreview(): Flow<List<BookShelfItem>>
|
||||||
@@ -773,8 +773,8 @@ interface BookDao {
|
|||||||
ifnull(customIntro, intro) as intro, kind
|
ifnull(customIntro, intro) as intro, kind
|
||||||
FROM books
|
FROM books
|
||||||
WHERE type & ${BookType.audio} > 0
|
WHERE type & ${BookType.audio} > 0
|
||||||
ORDER BY CASE WHEN (coverUrl IS NOT NULL OR customCoverUrl IS NOT NULL) THEN 0 ELSE 1 END, durChapterTime DESC
|
ORDER BY durChapterTime DESC
|
||||||
LIMIT 4
|
LIMIT 10
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
fun flowBookShelfAudioPreview(): Flow<List<BookShelfItem>>
|
fun flowBookShelfAudioPreview(): Flow<List<BookShelfItem>>
|
||||||
@@ -790,8 +790,8 @@ interface BookDao {
|
|||||||
FROM books
|
FROM books
|
||||||
WHERE type & ${BookType.audio} = 0 AND type & ${BookType.local} = 0
|
WHERE type & ${BookType.audio} = 0 AND type & ${BookType.local} = 0
|
||||||
AND ((SELECT COALESCE(SUM(groupId), 0) FROM book_groups WHERE groupId > 0) & `group`) = 0
|
AND ((SELECT COALESCE(SUM(groupId), 0) FROM book_groups WHERE groupId > 0) & `group`) = 0
|
||||||
ORDER BY CASE WHEN (coverUrl IS NOT NULL OR customCoverUrl IS NOT NULL) THEN 0 ELSE 1 END, durChapterTime DESC
|
ORDER BY durChapterTime DESC
|
||||||
LIMIT 4
|
LIMIT 10
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
fun flowBookShelfNetNoGroupPreview(): Flow<List<BookShelfItem>>
|
fun flowBookShelfNetNoGroupPreview(): Flow<List<BookShelfItem>>
|
||||||
@@ -807,8 +807,8 @@ interface BookDao {
|
|||||||
FROM books
|
FROM books
|
||||||
WHERE type & ${BookType.local} > 0
|
WHERE type & ${BookType.local} > 0
|
||||||
AND ((SELECT COALESCE(SUM(groupId), 0) FROM book_groups WHERE groupId > 0) & `group`) = 0
|
AND ((SELECT COALESCE(SUM(groupId), 0) FROM book_groups WHERE groupId > 0) & `group`) = 0
|
||||||
ORDER BY CASE WHEN (coverUrl IS NOT NULL OR customCoverUrl IS NOT NULL) THEN 0 ELSE 1 END, durChapterTime DESC
|
ORDER BY durChapterTime DESC
|
||||||
LIMIT 4
|
LIMIT 10
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
fun flowBookShelfLocalNoGroupPreview(): Flow<List<BookShelfItem>>
|
fun flowBookShelfLocalNoGroupPreview(): Flow<List<BookShelfItem>>
|
||||||
@@ -823,8 +823,8 @@ interface BookDao {
|
|||||||
ifnull(customIntro, intro) as intro, kind
|
ifnull(customIntro, intro) as intro, kind
|
||||||
FROM books
|
FROM books
|
||||||
WHERE type & ${BookType.image} > 0
|
WHERE type & ${BookType.image} > 0
|
||||||
ORDER BY CASE WHEN (coverUrl IS NOT NULL OR customCoverUrl IS NOT NULL) THEN 0 ELSE 1 END, durChapterTime DESC
|
ORDER BY durChapterTime DESC
|
||||||
LIMIT 4
|
LIMIT 10
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
fun flowBookShelfMangaPreview(): Flow<List<BookShelfItem>>
|
fun flowBookShelfMangaPreview(): Flow<List<BookShelfItem>>
|
||||||
@@ -839,8 +839,8 @@ interface BookDao {
|
|||||||
ifnull(customIntro, intro) as intro, kind
|
ifnull(customIntro, intro) as intro, kind
|
||||||
FROM books
|
FROM books
|
||||||
WHERE type & ${BookType.text} > 0
|
WHERE type & ${BookType.text} > 0
|
||||||
ORDER BY CASE WHEN (coverUrl IS NOT NULL OR customCoverUrl IS NOT NULL) THEN 0 ELSE 1 END, durChapterTime DESC
|
ORDER BY durChapterTime DESC
|
||||||
LIMIT 4
|
LIMIT 10
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
fun flowBookShelfTextPreview(): Flow<List<BookShelfItem>>
|
fun flowBookShelfTextPreview(): Flow<List<BookShelfItem>>
|
||||||
@@ -855,8 +855,8 @@ interface BookDao {
|
|||||||
ifnull(customIntro, intro) as intro, kind
|
ifnull(customIntro, intro) as intro, kind
|
||||||
FROM books
|
FROM books
|
||||||
WHERE type & ${BookType.updateError} > 0
|
WHERE type & ${BookType.updateError} > 0
|
||||||
ORDER BY CASE WHEN (coverUrl IS NOT NULL OR customCoverUrl IS NOT NULL) THEN 0 ELSE 1 END, durChapterTime DESC
|
ORDER BY durChapterTime DESC
|
||||||
LIMIT 4
|
LIMIT 10
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
fun flowBookShelfUpdateErrorPreview(): Flow<List<BookShelfItem>>
|
fun flowBookShelfUpdateErrorPreview(): Flow<List<BookShelfItem>>
|
||||||
@@ -871,8 +871,8 @@ interface BookDao {
|
|||||||
ifnull(customIntro, intro) as intro, kind
|
ifnull(customIntro, intro) as intro, kind
|
||||||
FROM books
|
FROM books
|
||||||
WHERE durChapterIndex = 0 AND durChapterPos = 0
|
WHERE durChapterIndex = 0 AND durChapterPos = 0
|
||||||
ORDER BY CASE WHEN (coverUrl IS NOT NULL OR customCoverUrl IS NOT NULL) THEN 0 ELSE 1 END, durChapterTime DESC
|
ORDER BY durChapterTime DESC
|
||||||
LIMIT 4
|
LIMIT 10
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
fun flowBookShelfUnreadPreview(): Flow<List<BookShelfItem>>
|
fun flowBookShelfUnreadPreview(): Flow<List<BookShelfItem>>
|
||||||
@@ -887,8 +887,8 @@ interface BookDao {
|
|||||||
ifnull(customIntro, intro) as intro, kind
|
ifnull(customIntro, intro) as intro, kind
|
||||||
FROM books
|
FROM books
|
||||||
WHERE totalChapterNum > 0 AND durChapterIndex > 0 AND durChapterIndex < totalChapterNum - 1
|
WHERE totalChapterNum > 0 AND durChapterIndex > 0 AND durChapterIndex < totalChapterNum - 1
|
||||||
ORDER BY CASE WHEN (coverUrl IS NOT NULL OR customCoverUrl IS NOT NULL) THEN 0 ELSE 1 END, durChapterTime DESC
|
ORDER BY durChapterTime DESC
|
||||||
LIMIT 4
|
LIMIT 10
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
fun flowBookShelfReadingPreview(): Flow<List<BookShelfItem>>
|
fun flowBookShelfReadingPreview(): Flow<List<BookShelfItem>>
|
||||||
@@ -903,8 +903,8 @@ interface BookDao {
|
|||||||
ifnull(customIntro, intro) as intro, kind
|
ifnull(customIntro, intro) as intro, kind
|
||||||
FROM books
|
FROM books
|
||||||
WHERE totalChapterNum > 0 AND durChapterIndex >= totalChapterNum - 1
|
WHERE totalChapterNum > 0 AND durChapterIndex >= totalChapterNum - 1
|
||||||
ORDER BY CASE WHEN (coverUrl IS NOT NULL OR customCoverUrl IS NOT NULL) THEN 0 ELSE 1 END, durChapterTime DESC
|
ORDER BY durChapterTime DESC
|
||||||
LIMIT 4
|
LIMIT 10
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
fun flowBookShelfReadFinishedPreview(): Flow<List<BookShelfItem>>
|
fun flowBookShelfReadFinishedPreview(): Flow<List<BookShelfItem>>
|
||||||
@@ -919,8 +919,8 @@ interface BookDao {
|
|||||||
ifnull(customIntro, intro) as intro, kind
|
ifnull(customIntro, intro) as intro, kind
|
||||||
FROM books
|
FROM books
|
||||||
WHERE (`group` & :groupId) > 0
|
WHERE (`group` & :groupId) > 0
|
||||||
ORDER BY CASE WHEN (coverUrl IS NOT NULL OR customCoverUrl IS NOT NULL) THEN 0 ELSE 1 END, durChapterTime DESC
|
ORDER BY durChapterTime DESC
|
||||||
LIMIT 4
|
LIMIT 10
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
fun flowBookShelfPreviewByUserGroup(groupId: Long): Flow<List<BookShelfItem>>
|
fun flowBookShelfPreviewByUserGroup(groupId: Long): Flow<List<BookShelfItem>>
|
||||||
|
|||||||
@@ -14,23 +14,23 @@ import io.legado.app.data.repository.BookRepository
|
|||||||
import io.legado.app.data.repository.BookSourceCallbackRepository
|
import io.legado.app.data.repository.BookSourceCallbackRepository
|
||||||
import io.legado.app.data.repository.CacheBookDownloadRepository
|
import io.legado.app.data.repository.CacheBookDownloadRepository
|
||||||
import io.legado.app.data.repository.DatabaseMaintenanceRepository
|
import io.legado.app.data.repository.DatabaseMaintenanceRepository
|
||||||
import io.legado.app.data.repository.DirectLinkUploadRepository
|
|
||||||
import io.legado.app.data.repository.DictRuleRepository
|
import io.legado.app.data.repository.DictRuleRepository
|
||||||
|
import io.legado.app.data.repository.DirectLinkUploadRepository
|
||||||
import io.legado.app.data.repository.ExploreRepository
|
import io.legado.app.data.repository.ExploreRepository
|
||||||
import io.legado.app.data.repository.ExploreRepositoryImpl
|
import io.legado.app.data.repository.ExploreRepositoryImpl
|
||||||
import io.legado.app.data.repository.LocalBookRepository
|
import io.legado.app.data.repository.LocalBookRepository
|
||||||
import io.legado.app.data.repository.ReadRecordRepository
|
import io.legado.app.data.repository.ReadRecordRepository
|
||||||
import io.legado.app.data.repository.RemoteBookRepository
|
import io.legado.app.data.repository.RemoteBookRepository
|
||||||
import io.legado.app.data.repository.RssRepository
|
import io.legado.app.data.repository.RssRepository
|
||||||
|
import io.legado.app.data.repository.SearchContentRepository
|
||||||
import io.legado.app.data.repository.SearchRepository
|
import io.legado.app.data.repository.SearchRepository
|
||||||
import io.legado.app.data.repository.SearchRepositoryImpl
|
import io.legado.app.data.repository.SearchRepositoryImpl
|
||||||
import io.legado.app.data.repository.SearchContentRepository
|
|
||||||
import io.legado.app.data.repository.SettingsRepository
|
import io.legado.app.data.repository.SettingsRepository
|
||||||
import io.legado.app.data.repository.UploadRepository
|
import io.legado.app.data.repository.UploadRepository
|
||||||
import io.legado.app.data.repository.WebDavBackupRepository
|
import io.legado.app.data.repository.WebDavBackupRepository
|
||||||
import io.legado.app.data.repository.WebDavReadingProgressRepository
|
import io.legado.app.data.repository.WebDavReadingProgressRepository
|
||||||
import io.legado.app.domain.gateway.BookCacheCleanupGateway
|
|
||||||
import io.legado.app.domain.gateway.AppStartupGateway
|
import io.legado.app.domain.gateway.AppStartupGateway
|
||||||
|
import io.legado.app.domain.gateway.BookCacheCleanupGateway
|
||||||
import io.legado.app.domain.gateway.BookCacheDownloadGateway
|
import io.legado.app.domain.gateway.BookCacheDownloadGateway
|
||||||
import io.legado.app.domain.gateway.BookSearchGateway
|
import io.legado.app.domain.gateway.BookSearchGateway
|
||||||
import io.legado.app.domain.gateway.BookSourceCallbackGateway
|
import io.legado.app.domain.gateway.BookSourceCallbackGateway
|
||||||
@@ -47,14 +47,13 @@ import io.legado.app.domain.usecase.ClearBookCacheUseCase
|
|||||||
import io.legado.app.domain.usecase.DeleteBooksUseCase
|
import io.legado.app.domain.usecase.DeleteBooksUseCase
|
||||||
import io.legado.app.domain.usecase.GetReadingProgressUseCase
|
import io.legado.app.domain.usecase.GetReadingProgressUseCase
|
||||||
import io.legado.app.domain.usecase.RemoveBookGroupAssignmentUseCase
|
import io.legado.app.domain.usecase.RemoveBookGroupAssignmentUseCase
|
||||||
import io.legado.app.ui.widget.components.explore.ExploreKindUiUseCase
|
|
||||||
import io.legado.app.domain.usecase.ResolveBookShelfStateUseCase
|
import io.legado.app.domain.usecase.ResolveBookShelfStateUseCase
|
||||||
import io.legado.app.domain.usecase.readRecord.GetReadRecordOverviewUseCase
|
|
||||||
import io.legado.app.domain.usecase.SearchBooksUseCase
|
import io.legado.app.domain.usecase.SearchBooksUseCase
|
||||||
import io.legado.app.domain.usecase.ShrinkDatabaseUseCase
|
import io.legado.app.domain.usecase.ShrinkDatabaseUseCase
|
||||||
import io.legado.app.domain.usecase.UpdateBooksGroupUseCase
|
import io.legado.app.domain.usecase.UpdateBooksGroupUseCase
|
||||||
import io.legado.app.domain.usecase.UploadReadingProgressUseCase
|
import io.legado.app.domain.usecase.UploadReadingProgressUseCase
|
||||||
import io.legado.app.domain.usecase.WebDavBackupUseCase
|
import io.legado.app.domain.usecase.WebDavBackupUseCase
|
||||||
|
import io.legado.app.domain.usecase.readRecord.GetReadRecordOverviewUseCase
|
||||||
import io.legado.app.help.coil.CoverFetcher
|
import io.legado.app.help.coil.CoverFetcher
|
||||||
import io.legado.app.help.coil.CoverInterceptor
|
import io.legado.app.help.coil.CoverInterceptor
|
||||||
import io.legado.app.help.http.okHttpClient
|
import io.legado.app.help.http.okHttpClient
|
||||||
@@ -64,7 +63,6 @@ import io.legado.app.ui.book.cache.manage.BookCacheManageViewModel
|
|||||||
import io.legado.app.ui.book.changecover.ChangeCoverViewModel
|
import io.legado.app.ui.book.changecover.ChangeCoverViewModel
|
||||||
import io.legado.app.ui.book.changesource.ChangeBookSourceComposeViewModel
|
import io.legado.app.ui.book.changesource.ChangeBookSourceComposeViewModel
|
||||||
import io.legado.app.ui.book.changesource.ChangeBookSourceViewModel
|
import io.legado.app.ui.book.changesource.ChangeBookSourceViewModel
|
||||||
import io.legado.app.ui.book.manage.BookshelfManageScreenViewModel
|
|
||||||
import io.legado.app.ui.book.explore.ExploreShowViewModel
|
import io.legado.app.ui.book.explore.ExploreShowViewModel
|
||||||
import io.legado.app.ui.book.group.GroupViewModel
|
import io.legado.app.ui.book.group.GroupViewModel
|
||||||
import io.legado.app.ui.book.import.local.ImportBookViewModel
|
import io.legado.app.ui.book.import.local.ImportBookViewModel
|
||||||
@@ -72,10 +70,11 @@ import io.legado.app.ui.book.import.remote.RemoteBookViewModel
|
|||||||
import io.legado.app.ui.book.import.remote.ServerConfigViewModel
|
import io.legado.app.ui.book.import.remote.ServerConfigViewModel
|
||||||
import io.legado.app.ui.book.import.remote.ServersViewModel
|
import io.legado.app.ui.book.import.remote.ServersViewModel
|
||||||
import io.legado.app.ui.book.info.BookInfoViewModel
|
import io.legado.app.ui.book.info.BookInfoViewModel
|
||||||
|
import io.legado.app.ui.book.manage.BookshelfManageScreenViewModel
|
||||||
import io.legado.app.ui.book.manga.ReadMangaViewModel
|
import io.legado.app.ui.book.manga.ReadMangaViewModel
|
||||||
import io.legado.app.ui.book.read.ReadBookViewModel
|
import io.legado.app.ui.book.read.ReadBookViewModel
|
||||||
import io.legado.app.ui.book.readRecord.ReadRecordViewModel
|
|
||||||
import io.legado.app.ui.book.readRecord.ReadRecordOverviewViewModel
|
import io.legado.app.ui.book.readRecord.ReadRecordOverviewViewModel
|
||||||
|
import io.legado.app.ui.book.readRecord.ReadRecordViewModel
|
||||||
import io.legado.app.ui.book.search.SearchViewModel
|
import io.legado.app.ui.book.search.SearchViewModel
|
||||||
import io.legado.app.ui.book.searchContent.SearchContentViewModel
|
import io.legado.app.ui.book.searchContent.SearchContentViewModel
|
||||||
import io.legado.app.ui.book.toc.TocViewModel
|
import io.legado.app.ui.book.toc.TocViewModel
|
||||||
@@ -97,10 +96,13 @@ import io.legado.app.ui.main.rss.RssViewModel
|
|||||||
import io.legado.app.ui.replace.ReplaceEditRoute
|
import io.legado.app.ui.replace.ReplaceEditRoute
|
||||||
import io.legado.app.ui.replace.ReplaceRuleViewModel
|
import io.legado.app.ui.replace.ReplaceRuleViewModel
|
||||||
import io.legado.app.ui.replace.edit.ReplaceEditViewModel
|
import io.legado.app.ui.replace.edit.ReplaceEditViewModel
|
||||||
import io.legado.app.ui.rss.source.manage.RssSourceViewModel
|
|
||||||
import io.legado.app.ui.rss.article.RssArticlesViewModel
|
import io.legado.app.ui.rss.article.RssArticlesViewModel
|
||||||
import io.legado.app.ui.rss.article.RssSortViewModel
|
import io.legado.app.ui.rss.article.RssSortViewModel
|
||||||
|
import io.legado.app.ui.rss.favorites.RssFavoritesViewModel
|
||||||
import io.legado.app.ui.rss.read.ReadRssViewModel
|
import io.legado.app.ui.rss.read.ReadRssViewModel
|
||||||
|
import io.legado.app.ui.rss.source.manage.RssSourceViewModel
|
||||||
|
import io.legado.app.ui.rss.subscription.RuleSubViewModel
|
||||||
|
import io.legado.app.ui.widget.components.explore.ExploreKindUiUseCase
|
||||||
import org.koin.core.module.dsl.singleOf
|
import org.koin.core.module.dsl.singleOf
|
||||||
import org.koin.core.module.dsl.viewModel
|
import org.koin.core.module.dsl.viewModel
|
||||||
import org.koin.core.module.dsl.viewModelOf
|
import org.koin.core.module.dsl.viewModelOf
|
||||||
@@ -179,6 +181,8 @@ val appModule = module {
|
|||||||
viewModelOf(::RssSortViewModel)
|
viewModelOf(::RssSortViewModel)
|
||||||
viewModelOf(::RssArticlesViewModel)
|
viewModelOf(::RssArticlesViewModel)
|
||||||
viewModelOf(::ReadRssViewModel)
|
viewModelOf(::ReadRssViewModel)
|
||||||
|
viewModelOf(::RssFavoritesViewModel)
|
||||||
|
viewModelOf(::RuleSubViewModel)
|
||||||
viewModelOf(::ReadRecordViewModel)
|
viewModelOf(::ReadRecordViewModel)
|
||||||
viewModelOf(::ReadRecordOverviewViewModel)
|
viewModelOf(::ReadRecordOverviewViewModel)
|
||||||
viewModelOf(::ExploreShowViewModel)
|
viewModelOf(::ExploreShowViewModel)
|
||||||
|
|||||||
@@ -269,12 +269,17 @@ object BookshelfConfig {
|
|||||||
/**
|
/**
|
||||||
* 书架卡片背景颜色
|
* 书架卡片背景颜色
|
||||||
*/
|
*/
|
||||||
private val _bookshelfCardColor = prefStateDelegate(PreferKey.bookshelfCardColor, 0) {
|
private val _bookshelfCardColor = prefStateDelegate(PreferKey.bookshelfCardColor, 0)
|
||||||
postEvent(EventBus.NOTIFY_MAIN, false)
|
|
||||||
}
|
|
||||||
var bookshelfCardColor by _bookshelfCardColor
|
var bookshelfCardColor by _bookshelfCardColor
|
||||||
val bookshelfCardColorState: State<Int> get() = _bookshelfCardColor.state
|
val bookshelfCardColorState: State<Int> get() = _bookshelfCardColor.state
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 书架卡片背景颜色 (夜间)
|
||||||
|
*/
|
||||||
|
private val _bookshelfCardColorDark = prefStateDelegate(PreferKey.bookshelfCardColorDark, 0)
|
||||||
|
var bookshelfCardColorDark by _bookshelfCardColorDark
|
||||||
|
val bookshelfCardColorDarkState: State<Int> get() = _bookshelfCardColorDark.state
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件夹在列表模式下的样式: 0: 默认, 2: 横排封面
|
* 文件夹在列表模式下的样式: 0: 默认, 2: 横排封面
|
||||||
*/
|
*/
|
||||||
|
|||||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,152 @@
|
|||||||
|
package io.legado.app.ui.main
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import io.legado.app.ui.config.ConfigTag
|
||||||
|
|
||||||
|
object MainIntent {
|
||||||
|
const val EXTRA_START_ROUTE = "startRoute"
|
||||||
|
const val EXTRA_CACHE_GROUP_ID = "extra_cache_group_id"
|
||||||
|
const val EXTRA_SEARCH_KEY = "extra_search_key"
|
||||||
|
const val EXTRA_SEARCH_SCOPE = "extra_search_scope"
|
||||||
|
const val EXTRA_BOOK_NAME = "name"
|
||||||
|
const val EXTRA_BOOK_AUTHOR = "author"
|
||||||
|
const val EXTRA_BOOK_URL = "bookUrl"
|
||||||
|
const val EXTRA_EXPLORE_NAME = "exploreName"
|
||||||
|
const val EXTRA_SOURCE_URL = "sourceUrl"
|
||||||
|
const val EXTRA_EXPLORE_URL = "exploreUrl"
|
||||||
|
|
||||||
|
const val EXTRA_RSS_SOURCE_URL = "extra_rss_source_url"
|
||||||
|
const val EXTRA_RSS_SORT_URL = "extra_rss_sort_url"
|
||||||
|
const val EXTRA_RSS_KEY = "extra_rss_key"
|
||||||
|
|
||||||
|
const val EXTRA_RSS_READ_TITLE = "extra_rss_read_title"
|
||||||
|
const val EXTRA_RSS_READ_ORIGIN = "extra_rss_read_origin"
|
||||||
|
const val EXTRA_RSS_READ_LINK = "extra_rss_read_link"
|
||||||
|
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, MainRouteConst.ROUTE_MAIN)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createIntent(context: Context, configTag: String? = null): Intent {
|
||||||
|
return createLauncherIntent(context).apply {
|
||||||
|
putExtra(EXTRA_START_ROUTE, routeForConfigTag(configTag))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createRssSortIntent(
|
||||||
|
context: Context,
|
||||||
|
sourceUrl: String,
|
||||||
|
sortUrl: String? = null,
|
||||||
|
key: String? = null
|
||||||
|
): Intent {
|
||||||
|
return createLauncherIntent(context).apply {
|
||||||
|
putExtra(EXTRA_START_ROUTE, MainRouteConst.ROUTE_RSS_SORT)
|
||||||
|
putExtra(EXTRA_RSS_SOURCE_URL, sourceUrl)
|
||||||
|
putExtra(EXTRA_RSS_SORT_URL, sortUrl)
|
||||||
|
putExtra(EXTRA_RSS_KEY, key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createRssReadIntent(
|
||||||
|
context: Context,
|
||||||
|
title: String? = null,
|
||||||
|
origin: String,
|
||||||
|
link: String? = null,
|
||||||
|
openUrl: String? = null
|
||||||
|
): Intent {
|
||||||
|
return createLauncherIntent(context).apply {
|
||||||
|
putExtra(EXTRA_START_ROUTE, MainRouteConst.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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createBookshelfManageScreenIntent(
|
||||||
|
context: Context,
|
||||||
|
groupId: Long = -1L
|
||||||
|
): Intent {
|
||||||
|
return createLauncherIntent(context).apply {
|
||||||
|
putExtra(EXTRA_START_ROUTE, MainRouteConst.ROUTE_CACHE)
|
||||||
|
putExtra(EXTRA_CACHE_GROUP_ID, groupId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createCacheIntent(
|
||||||
|
context: Context,
|
||||||
|
groupId: Long = -1L
|
||||||
|
): Intent = createBookshelfManageScreenIntent(context, groupId)
|
||||||
|
|
||||||
|
fun createBookCacheManageIntent(context: Context): Intent {
|
||||||
|
return createLauncherIntent(context).apply {
|
||||||
|
putExtra(EXTRA_START_ROUTE, MainRouteConst.ROUTE_BOOK_CACHE_MANAGE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createSearchIntent(
|
||||||
|
context: Context,
|
||||||
|
key: String? = null,
|
||||||
|
scopeRaw: String? = null
|
||||||
|
): Intent {
|
||||||
|
return createLauncherIntent(context).apply {
|
||||||
|
putExtra(EXTRA_START_ROUTE, MainRouteConst.ROUTE_SEARCH)
|
||||||
|
putExtra(EXTRA_SEARCH_KEY, key)
|
||||||
|
putExtra(EXTRA_SEARCH_SCOPE, scopeRaw)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createBookInfoIntent(
|
||||||
|
context: Context,
|
||||||
|
name: String? = null,
|
||||||
|
author: String? = null,
|
||||||
|
bookUrl: String
|
||||||
|
): Intent {
|
||||||
|
return createLauncherIntent(context).apply {
|
||||||
|
putExtra(EXTRA_START_ROUTE, MainRouteConst.ROUTE_BOOK_INFO)
|
||||||
|
putExtra(EXTRA_BOOK_NAME, name)
|
||||||
|
putExtra(EXTRA_BOOK_AUTHOR, author)
|
||||||
|
putExtra(EXTRA_BOOK_URL, bookUrl)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createExploreShowIntent(
|
||||||
|
context: Context,
|
||||||
|
exploreName: String? = null,
|
||||||
|
sourceUrl: String,
|
||||||
|
exploreUrl: String? = null
|
||||||
|
): Intent {
|
||||||
|
return createLauncherIntent(context).apply {
|
||||||
|
putExtra(EXTRA_START_ROUTE, MainRouteConst.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 -> MainRouteConst.ROUTE_SETTINGS_OTHER
|
||||||
|
ConfigTag.READ_CONFIG -> MainRouteConst.ROUTE_SETTINGS_READ
|
||||||
|
ConfigTag.COVER_CONFIG -> MainRouteConst.ROUTE_SETTINGS_COVER
|
||||||
|
ConfigTag.THEME_CONFIG -> MainRouteConst.ROUTE_SETTINGS_THEME
|
||||||
|
ConfigTag.BACKUP_CONFIG -> MainRouteConst.ROUTE_SETTINGS_BACKUP
|
||||||
|
ConfigTag.DOWNLOAD_CACHE_CONFIG -> MainRouteConst.ROUTE_SETTINGS_DOWNLOAD_CACHE
|
||||||
|
else -> MainRouteConst.ROUTE_SETTINGS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,423 @@
|
|||||||
|
package io.legado.app.ui.main
|
||||||
|
|
||||||
|
import androidx.compose.animation.ExperimentalSharedTransitionApi
|
||||||
|
import androidx.compose.animation.SharedTransitionScope
|
||||||
|
import androidx.compose.animation.core.tween
|
||||||
|
import androidx.compose.animation.fadeIn
|
||||||
|
import androidx.compose.animation.fadeOut
|
||||||
|
import androidx.compose.animation.togetherWith
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.navigation3.runtime.NavKey
|
||||||
|
import androidx.navigation3.runtime.entryProvider
|
||||||
|
import androidx.navigation3.ui.LocalNavAnimatedContentScope
|
||||||
|
import androidx.navigation3.ui.NavDisplay
|
||||||
|
import io.legado.app.ui.book.cache.manage.BookCacheManageRouteScreen
|
||||||
|
import io.legado.app.ui.book.explore.ExploreShowScreen
|
||||||
|
import io.legado.app.ui.book.import.local.ImportBookScreen
|
||||||
|
import io.legado.app.ui.book.import.remote.RemoteBookScreen
|
||||||
|
import io.legado.app.ui.book.info.BookInfoRouteScreen
|
||||||
|
import io.legado.app.ui.book.info.BookInfoViewModel
|
||||||
|
import io.legado.app.ui.book.manage.BookshelfManageRouteScreen
|
||||||
|
import io.legado.app.ui.book.readRecord.ReadRecordOverviewScreen
|
||||||
|
import io.legado.app.ui.book.readRecord.ReadRecordScreen
|
||||||
|
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.source.manage.BookSourceActivity
|
||||||
|
import io.legado.app.ui.config.ConfigNavScreen
|
||||||
|
import io.legado.app.ui.config.backupConfig.BackupConfigScreen
|
||||||
|
import io.legado.app.ui.config.coverConfig.CoverConfigScreen
|
||||||
|
import io.legado.app.ui.config.customTheme.CustomThemeScreen
|
||||||
|
import io.legado.app.ui.config.downloadCacheConfig.DownloadCacheConfigScreen
|
||||||
|
import io.legado.app.ui.config.otherConfig.OtherConfigScreen
|
||||||
|
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.favorites.RssFavoritesScreen
|
||||||
|
import io.legado.app.ui.rss.read.MainRouteRssRead
|
||||||
|
import io.legado.app.ui.rss.read.RssReadRouteScreen
|
||||||
|
import io.legado.app.ui.rss.subscription.RuleSubScreen
|
||||||
|
import io.legado.app.utils.startActivity
|
||||||
|
import io.legado.app.utils.startActivityForBook
|
||||||
|
import kotlinx.coroutines.Dispatchers.IO
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import org.koin.androidx.compose.koinViewModel
|
||||||
|
|
||||||
|
@OptIn(ExperimentalSharedTransitionApi::class)
|
||||||
|
fun MainActivity.mainEntryProvider(
|
||||||
|
backStack: MutableList<NavKey>,
|
||||||
|
useRail: Boolean,
|
||||||
|
sharedTransitionScope: SharedTransitionScope,
|
||||||
|
onNavigateToRoute: (NavKey) -> Unit,
|
||||||
|
onNavigateBack: () -> Unit,
|
||||||
|
onRegisterVariableSetter: (((String, String?) -> Unit)?) -> Unit
|
||||||
|
) = entryProvider {
|
||||||
|
entry<MainRouteHome> {
|
||||||
|
MainScreen(
|
||||||
|
useRail = useRail,
|
||||||
|
onOpenSettings = {
|
||||||
|
onNavigateToRoute(MainRouteSettings)
|
||||||
|
},
|
||||||
|
onNavigateToSearch = { key ->
|
||||||
|
onNavigateToRoute(
|
||||||
|
MainRouteSearch(
|
||||||
|
key = key?.trim()?.takeIf { it.isNotEmpty() }
|
||||||
|
)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
onNavigateToRemoteImport = {
|
||||||
|
onNavigateToRoute(MainRouteImportRemote)
|
||||||
|
},
|
||||||
|
onNavigateToLocalImport = {
|
||||||
|
onNavigateToRoute(MainRouteImportLocal)
|
||||||
|
},
|
||||||
|
onNavigateToCache = { groupId ->
|
||||||
|
onNavigateToRoute(MainRouteCache(groupId))
|
||||||
|
},
|
||||||
|
onNavigateToBookCacheManage = {
|
||||||
|
onNavigateToRoute(MainRouteBookCacheManage)
|
||||||
|
},
|
||||||
|
onNavigateToBookInfo = { name, author, bookUrl ->
|
||||||
|
onNavigateToRoute(
|
||||||
|
MainRouteBookInfo(
|
||||||
|
name = name,
|
||||||
|
author = author,
|
||||||
|
bookUrl = bookUrl
|
||||||
|
)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
onNavigateToExploreShow = { title, sourceUrl, exploreUrl ->
|
||||||
|
onNavigateToRoute(
|
||||||
|
MainRouteExploreShow(
|
||||||
|
title = title,
|
||||||
|
sourceUrl = sourceUrl,
|
||||||
|
exploreUrl = exploreUrl
|
||||||
|
)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
onNavigateToRssSort = { sourceUrl, sortUrl, key ->
|
||||||
|
onNavigateToRoute(
|
||||||
|
MainRouteRssSort(
|
||||||
|
sourceUrl = sourceUrl,
|
||||||
|
sortUrl = sortUrl,
|
||||||
|
key = key
|
||||||
|
)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
onNavigateToRssRead = { title, origin, link, openUrl ->
|
||||||
|
onNavigateToRoute(
|
||||||
|
MainRouteRssRead(
|
||||||
|
title = title,
|
||||||
|
origin = origin,
|
||||||
|
link = link,
|
||||||
|
openUrl = openUrl
|
||||||
|
)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
onNavigateToRssFavorites = {
|
||||||
|
onNavigateToRoute(MainRouteRssFavorites)
|
||||||
|
},
|
||||||
|
onNavigateToRuleSub = {
|
||||||
|
onNavigateToRoute(MainRouteRuleSub)
|
||||||
|
},
|
||||||
|
onNavigateToReadRecord = {
|
||||||
|
onNavigateToRoute(MainRouteReadRecord)
|
||||||
|
},
|
||||||
|
sharedTransitionScope = sharedTransitionScope,
|
||||||
|
animatedVisibilityScope = LocalNavAnimatedContentScope.current,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
entry<MainRouteSettings> {
|
||||||
|
ConfigNavScreen(
|
||||||
|
onBackClick = { onNavigateBack() },
|
||||||
|
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 = { onNavigateBack() })
|
||||||
|
}
|
||||||
|
|
||||||
|
entry<MainRouteSettingsRead> {
|
||||||
|
ReadConfigScreen(onBackClick = { onNavigateBack() })
|
||||||
|
}
|
||||||
|
|
||||||
|
entry<MainRouteSettingsCover> {
|
||||||
|
CoverConfigScreen(onBackClick = { onNavigateBack() })
|
||||||
|
}
|
||||||
|
|
||||||
|
entry<MainRouteSettingsTheme> {
|
||||||
|
ThemeConfigScreen(
|
||||||
|
onBackClick = { onNavigateBack() },
|
||||||
|
onNavigateToCustomTheme = { backStack.add(MainRouteSettingsCustomTheme) },
|
||||||
|
onNavigateToThemeManage = { backStack.add(MainRouteSettingsThemeManage) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
entry<MainRouteSettingsBackup> {
|
||||||
|
BackupConfigScreen(onBackClick = { onNavigateBack() })
|
||||||
|
}
|
||||||
|
|
||||||
|
entry<MainRouteSettingsDownloadCache> {
|
||||||
|
DownloadCacheConfigScreen(onBackClick = { onNavigateBack() })
|
||||||
|
}
|
||||||
|
|
||||||
|
entry<MainRouteSettingsCustomTheme> {
|
||||||
|
CustomThemeScreen(
|
||||||
|
onBackClick = { onNavigateBack() }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
entry<MainRouteSettingsThemeManage> {
|
||||||
|
ThemeManageScreen(onBackClick = { onNavigateBack() })
|
||||||
|
}
|
||||||
|
|
||||||
|
entry<MainRouteImportLocal> {
|
||||||
|
ImportBookScreen(
|
||||||
|
onBackClick = { onNavigateBack() }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
entry<MainRouteImportRemote> {
|
||||||
|
RemoteBookScreen(
|
||||||
|
onBackClick = { onNavigateBack() }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
entry<MainRouteCache> { route ->
|
||||||
|
BookshelfManageRouteScreen(
|
||||||
|
groupId = route.groupId,
|
||||||
|
onBackClick = { onNavigateBack() },
|
||||||
|
onOpenBookInfo = { name, author, bookUrl ->
|
||||||
|
onNavigateToRoute(
|
||||||
|
MainRouteBookInfo(
|
||||||
|
name = name,
|
||||||
|
author = author,
|
||||||
|
bookUrl = bookUrl
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
entry<MainRouteBookCacheManage> {
|
||||||
|
BookCacheManageRouteScreen(
|
||||||
|
onBackClick = { onNavigateBack() }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
entry<MainRouteSearch> { route ->
|
||||||
|
val searchViewModel = koinViewModel<SearchViewModel>()
|
||||||
|
|
||||||
|
LaunchedEffect(route.key, route.scopeRaw, searchViewModel) {
|
||||||
|
searchViewModel.onIntent(
|
||||||
|
SearchIntent.Initialize(
|
||||||
|
key = route.key,
|
||||||
|
scopeRaw = route.scopeRaw
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
SearchScreen(
|
||||||
|
viewModel = searchViewModel,
|
||||||
|
onBack = {
|
||||||
|
searchViewModel.onIntent(SearchIntent.ClearSearchResults)
|
||||||
|
onNavigateBack()
|
||||||
|
},
|
||||||
|
onOpenBookInfo = { name, author, bookUrl ->
|
||||||
|
onNavigateToRoute(
|
||||||
|
MainRouteBookInfo(
|
||||||
|
name = name,
|
||||||
|
author = author,
|
||||||
|
bookUrl = bookUrl
|
||||||
|
)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
onOpenSourceManage = {
|
||||||
|
this@mainEntryProvider.startActivity<BookSourceActivity>()
|
||||||
|
},
|
||||||
|
sharedTransitionScope = sharedTransitionScope,
|
||||||
|
animatedVisibilityScope = LocalNavAnimatedContentScope.current,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
entry<MainRouteRssSort> { route ->
|
||||||
|
RssSortRouteScreen(
|
||||||
|
sourceUrl = route.sourceUrl,
|
||||||
|
initialSortUrl = route.sortUrl,
|
||||||
|
onBackClick = { onNavigateBack() },
|
||||||
|
onOpenRead = { title, origin, link, openUrl ->
|
||||||
|
if (link?.contains("@js:") == true) {
|
||||||
|
onNavigateToRoute(
|
||||||
|
MainRouteRssSort(
|
||||||
|
sourceUrl = origin,
|
||||||
|
sortUrl = link
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
onNavigateToRoute(
|
||||||
|
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 = { onNavigateBack() }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
entry<MainRouteRssFavorites> {
|
||||||
|
RssFavoritesScreen(
|
||||||
|
onBackClick = { onNavigateBack() },
|
||||||
|
onOpenRead = { title, origin, link, openUrl ->
|
||||||
|
onNavigateToRoute(
|
||||||
|
MainRouteRssRead(
|
||||||
|
title = title,
|
||||||
|
origin = origin,
|
||||||
|
link = link,
|
||||||
|
openUrl = openUrl
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
entry<MainRouteRuleSub> {
|
||||||
|
RuleSubScreen(
|
||||||
|
onBackClick = { onNavigateBack() }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
entry<MainRouteReadRecord> {
|
||||||
|
ReadRecordScreen(
|
||||||
|
onBackClick = { onNavigateBack() },
|
||||||
|
onBookClick = { name, author ->
|
||||||
|
lifecycleScope.launch {
|
||||||
|
val book = withContext(IO) {
|
||||||
|
io.legado.app.data.appDb.bookDao.getBook(name, author)
|
||||||
|
}
|
||||||
|
if (book != null) this@mainEntryProvider.startActivityForBook(book)
|
||||||
|
else {
|
||||||
|
onNavigateToRoute(MainRouteSearch(key = name))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onSummaryClick = {
|
||||||
|
onNavigateToRoute(MainRouteReadRecordOverview)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
entry<MainRouteReadRecordOverview> {
|
||||||
|
ReadRecordOverviewScreen(
|
||||||
|
onBackClick = { onNavigateBack() },
|
||||||
|
onBookClick = { name, author ->
|
||||||
|
lifecycleScope.launch {
|
||||||
|
val book = withContext(IO) {
|
||||||
|
io.legado.app.data.appDb.bookDao.getBook(name, author)
|
||||||
|
}
|
||||||
|
if (book != null) this@mainEntryProvider.startActivityForBook(book)
|
||||||
|
else {
|
||||||
|
onNavigateToRoute(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 = { onNavigateBack() },
|
||||||
|
onFinish = { _, _ -> onNavigateBack() },
|
||||||
|
onOpenSearch = { keyword ->
|
||||||
|
onNavigateToRoute(MainRouteSearch(key = keyword))
|
||||||
|
},
|
||||||
|
sharedTransitionScope = sharedTransitionScope,
|
||||||
|
animatedVisibilityScope = LocalNavAnimatedContentScope.current,
|
||||||
|
sharedCoverKey = bookCoverSharedElementKey(route.bookUrl),
|
||||||
|
onRegisterVariableSetter = { setter ->
|
||||||
|
onRegisterVariableSetter(setter)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
entry<MainRouteExploreShow> { route ->
|
||||||
|
ExploreShowScreen(
|
||||||
|
title = route.title ?: "探索",
|
||||||
|
sourceUrl = route.sourceUrl,
|
||||||
|
exploreUrl = route.exploreUrl,
|
||||||
|
onBack = { onNavigateBack() },
|
||||||
|
onBookClick = { book ->
|
||||||
|
onNavigateToRoute(
|
||||||
|
MainRouteBookInfo(
|
||||||
|
name = book.name,
|
||||||
|
author = book.author,
|
||||||
|
bookUrl = book.bookUrl
|
||||||
|
)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
sharedTransitionScope = sharedTransitionScope,
|
||||||
|
animatedVisibilityScope = LocalNavAnimatedContentScope.current,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
package io.legado.app.ui.main
|
||||||
|
|
||||||
|
import androidx.navigation3.runtime.NavKey
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
sealed interface MainRoute : NavKey
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data object MainRouteHome : MainRoute
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data object MainRouteSettings : MainRoute
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data object MainRouteSettingsOther : MainRoute
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data object MainRouteSettingsRead : MainRoute
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data object MainRouteSettingsCover : MainRoute
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data object MainRouteSettingsTheme : MainRoute
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data object MainRouteSettingsBackup : MainRoute
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data object MainRouteSettingsCustomTheme : MainRoute
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data object MainRouteSettingsThemeManage : MainRoute
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data object MainRouteSettingsDownloadCache : MainRoute
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data object MainRouteImportLocal : MainRoute
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data object MainRouteImportRemote : MainRoute
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data object MainRouteReadRecord : MainRoute
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data object MainRouteReadRecordOverview : MainRoute
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class MainRouteCache(val groupId: Long) : MainRoute
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data object MainRouteBookCacheManage : MainRoute
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class MainRouteSearch(
|
||||||
|
val key: String?,
|
||||||
|
val scopeRaw: String? = null
|
||||||
|
) : MainRoute
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class MainRouteBookInfo(
|
||||||
|
val name: String?,
|
||||||
|
val author: String?,
|
||||||
|
val bookUrl: String,
|
||||||
|
) : MainRoute
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data object MainRouteRssFavorites : MainRoute
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data object MainRouteRuleSub : MainRoute
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class MainRouteExploreShow(
|
||||||
|
val title: String?,
|
||||||
|
val sourceUrl: String,
|
||||||
|
val exploreUrl: String?,
|
||||||
|
) : MainRoute
|
||||||
|
|
||||||
|
object MainRouteConst {
|
||||||
|
const val ROUTE_MAIN = "main"
|
||||||
|
const val ROUTE_SETTINGS = "settings"
|
||||||
|
const val ROUTE_SETTINGS_OTHER = "settings/other"
|
||||||
|
const val ROUTE_SETTINGS_READ = "settings/read"
|
||||||
|
const val ROUTE_SETTINGS_COVER = "settings/cover"
|
||||||
|
const val ROUTE_SETTINGS_THEME = "settings/theme"
|
||||||
|
const val ROUTE_SETTINGS_BACKUP = "settings/backup"
|
||||||
|
const val ROUTE_SETTINGS_CUSTOM_THEME = "settings/custom_theme"
|
||||||
|
const val ROUTE_SETTINGS_DOWNLOAD_CACHE = "settings/download_cache"
|
||||||
|
const val ROUTE_IMPORT_LOCAL = "import/local"
|
||||||
|
const val ROUTE_IMPORT_REMOTE = "import/remote"
|
||||||
|
const val ROUTE_CACHE = "cache"
|
||||||
|
const val ROUTE_BOOK_CACHE_MANAGE = "book/cache/manage"
|
||||||
|
const val ROUTE_SEARCH = "search"
|
||||||
|
const val ROUTE_BOOK_INFO = "book/info"
|
||||||
|
const val ROUTE_EXPLORE_SHOW = "explore/show"
|
||||||
|
const val ROUTE_RSS_SORT = "rss/sort"
|
||||||
|
const val ROUTE_RSS_READ = "rss/read"
|
||||||
|
const val ROUTE_RSS_FAVORITES = "rss/favorites"
|
||||||
|
const val ROUTE_RULE_SUB = "rss/rule_sub"
|
||||||
|
const val ROUTE_READ_RECORD = "read_record"
|
||||||
|
const val ROUTE_READ_RECORD_OVERVIEW = "read_record_overview"
|
||||||
|
}
|
||||||
@@ -0,0 +1,253 @@
|
|||||||
|
package io.legado.app.ui.main
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.content.Intent
|
||||||
|
import androidx.navigation3.runtime.NavKey
|
||||||
|
import io.legado.app.ui.rss.article.MainRouteRssSort
|
||||||
|
import io.legado.app.ui.rss.read.MainRouteRssRead
|
||||||
|
|
||||||
|
object MainNavigator {
|
||||||
|
|
||||||
|
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 ||
|
||||||
|
currentRoute is MainRouteBookInfo ||
|
||||||
|
currentRoute is MainRouteExploreShow ||
|
||||||
|
currentRoute is MainRouteSearch
|
||||||
|
) {
|
||||||
|
backStack.add(route)
|
||||||
|
} else {
|
||||||
|
backStack.clear()
|
||||||
|
backStack.add(MainRouteHome)
|
||||||
|
backStack.add(route)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is MainRouteBookInfo -> {
|
||||||
|
if (
|
||||||
|
currentRoute == MainRouteHome ||
|
||||||
|
currentRoute is MainRouteSearch ||
|
||||||
|
currentRoute is MainRouteExploreShow ||
|
||||||
|
currentRoute is MainRouteBookInfo
|
||||||
|
) {
|
||||||
|
backStack.add(route)
|
||||||
|
} else {
|
||||||
|
backStack.clear()
|
||||||
|
backStack.add(MainRouteHome)
|
||||||
|
backStack.add(route)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is MainRouteExploreShow -> {
|
||||||
|
if (
|
||||||
|
currentRoute == MainRouteHome ||
|
||||||
|
currentRoute is MainRouteBookInfo ||
|
||||||
|
currentRoute is MainRouteSearch ||
|
||||||
|
currentRoute is MainRouteExploreShow
|
||||||
|
) {
|
||||||
|
backStack.add(route)
|
||||||
|
} else {
|
||||||
|
backStack.clear()
|
||||||
|
backStack.add(MainRouteHome)
|
||||||
|
backStack.add(route)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is MainRouteRssSort -> {
|
||||||
|
if (
|
||||||
|
currentRoute == MainRouteHome ||
|
||||||
|
currentRoute is MainRouteRssSort ||
|
||||||
|
currentRoute is MainRouteRssRead
|
||||||
|
) {
|
||||||
|
backStack.add(route)
|
||||||
|
} else {
|
||||||
|
backStack.clear()
|
||||||
|
backStack.add(MainRouteHome)
|
||||||
|
backStack.add(route)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is MainRouteRssRead -> {
|
||||||
|
if (
|
||||||
|
currentRoute == MainRouteHome ||
|
||||||
|
currentRoute is MainRouteRssSort ||
|
||||||
|
currentRoute is MainRouteRssRead
|
||||||
|
) {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun navigateBack(activity: Activity, backStack: MutableList<NavKey>) {
|
||||||
|
if (backStack.size > 1) {
|
||||||
|
backStack.removeLastOrNull()
|
||||||
|
} else {
|
||||||
|
activity.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun resolveStartRoute(intent: Intent?): NavKey {
|
||||||
|
val route = intent?.getStringExtra(MainIntent.EXTRA_START_ROUTE)
|
||||||
|
resolveRssStartRoute(route, intent)?.let { return it }
|
||||||
|
return resolveStartRoute(route, intent)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun resolveRssStartRoute(route: String?, intent: Intent?): NavKey? {
|
||||||
|
return when (route) {
|
||||||
|
MainRouteConst.ROUTE_RSS_SORT -> {
|
||||||
|
val sourceUrl = intent?.getStringExtra(MainIntent.EXTRA_RSS_SOURCE_URL)
|
||||||
|
if (sourceUrl.isNullOrBlank()) {
|
||||||
|
null
|
||||||
|
} else {
|
||||||
|
MainRouteRssSort(
|
||||||
|
sourceUrl = sourceUrl,
|
||||||
|
sortUrl = intent.getStringExtra(MainIntent.EXTRA_RSS_SORT_URL),
|
||||||
|
key = intent.getStringExtra(MainIntent.EXTRA_RSS_KEY)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MainRouteConst.ROUTE_RSS_READ -> {
|
||||||
|
val origin = intent?.getStringExtra(MainIntent.EXTRA_RSS_READ_ORIGIN)
|
||||||
|
if (origin.isNullOrBlank()) {
|
||||||
|
null
|
||||||
|
} else {
|
||||||
|
MainRouteRssRead(
|
||||||
|
title = intent.getStringExtra(MainIntent.EXTRA_RSS_READ_TITLE),
|
||||||
|
origin = origin,
|
||||||
|
link = intent.getStringExtra(MainIntent.EXTRA_RSS_READ_LINK),
|
||||||
|
openUrl = intent.getStringExtra(MainIntent.EXTRA_RSS_READ_OPEN_URL)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MainRouteConst.ROUTE_RSS_FAVORITES -> MainRouteRssFavorites
|
||||||
|
|
||||||
|
MainRouteConst.ROUTE_RULE_SUB -> MainRouteRuleSub
|
||||||
|
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun resolveStartRoute(route: String?, intent: Intent?): MainRoute {
|
||||||
|
return when (route) {
|
||||||
|
MainRouteConst.ROUTE_MAIN -> MainRouteHome
|
||||||
|
MainRouteConst.ROUTE_SETTINGS -> MainRouteSettings
|
||||||
|
MainRouteConst.ROUTE_SETTINGS_OTHER -> MainRouteSettingsOther
|
||||||
|
MainRouteConst.ROUTE_SETTINGS_READ -> MainRouteSettingsRead
|
||||||
|
MainRouteConst.ROUTE_SETTINGS_COVER -> MainRouteSettingsCover
|
||||||
|
MainRouteConst.ROUTE_SETTINGS_THEME -> MainRouteSettingsTheme
|
||||||
|
MainRouteConst.ROUTE_SETTINGS_BACKUP -> MainRouteSettingsBackup
|
||||||
|
MainRouteConst.ROUTE_SETTINGS_CUSTOM_THEME -> MainRouteSettingsCustomTheme
|
||||||
|
MainRouteConst.ROUTE_SETTINGS_DOWNLOAD_CACHE -> MainRouteSettingsDownloadCache
|
||||||
|
MainRouteConst.ROUTE_IMPORT_LOCAL -> MainRouteImportLocal
|
||||||
|
MainRouteConst.ROUTE_IMPORT_REMOTE -> MainRouteImportRemote
|
||||||
|
MainRouteConst.ROUTE_CACHE -> MainRouteCache(
|
||||||
|
intent?.getLongExtra(
|
||||||
|
MainIntent.EXTRA_CACHE_GROUP_ID,
|
||||||
|
-1L
|
||||||
|
) ?: -1L
|
||||||
|
)
|
||||||
|
|
||||||
|
MainRouteConst.ROUTE_BOOK_CACHE_MANAGE -> MainRouteBookCacheManage
|
||||||
|
MainRouteConst.ROUTE_SEARCH -> MainRouteSearch(
|
||||||
|
key = intent?.getStringExtra(MainIntent.EXTRA_SEARCH_KEY),
|
||||||
|
scopeRaw = intent?.getStringExtra(MainIntent.EXTRA_SEARCH_SCOPE)
|
||||||
|
)
|
||||||
|
|
||||||
|
MainRouteConst.ROUTE_BOOK_INFO -> intent?.getStringExtra(MainIntent.EXTRA_BOOK_URL)
|
||||||
|
?.takeIf { it.isNotBlank() }
|
||||||
|
?.let { bookUrl ->
|
||||||
|
MainRouteBookInfo(
|
||||||
|
name = intent.getStringExtra(MainIntent.EXTRA_BOOK_NAME),
|
||||||
|
author = intent.getStringExtra(MainIntent.EXTRA_BOOK_AUTHOR),
|
||||||
|
bookUrl = bookUrl
|
||||||
|
)
|
||||||
|
} ?: MainRouteHome
|
||||||
|
|
||||||
|
MainRouteConst.ROUTE_EXPLORE_SHOW -> intent?.getStringExtra(MainIntent.EXTRA_SOURCE_URL)
|
||||||
|
?.takeIf { it.isNotBlank() }
|
||||||
|
?.let { sourceUrl ->
|
||||||
|
MainRouteExploreShow(
|
||||||
|
title = intent.getStringExtra(MainIntent.EXTRA_EXPLORE_NAME),
|
||||||
|
sourceUrl = sourceUrl,
|
||||||
|
exploreUrl = intent.getStringExtra(MainIntent.EXTRA_EXPLORE_URL)
|
||||||
|
)
|
||||||
|
} ?: MainRouteHome
|
||||||
|
|
||||||
|
else -> MainRouteHome
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -113,6 +113,8 @@ fun MainScreen(
|
|||||||
onNavigateToExploreShow: (title: String?, sourceUrl: String, exploreUrl: String?) -> Unit,
|
onNavigateToExploreShow: (title: String?, sourceUrl: String, exploreUrl: String?) -> Unit,
|
||||||
onNavigateToRssSort: (sourceUrl: String, sortUrl: String?, key: String?) -> Unit,
|
onNavigateToRssSort: (sourceUrl: String, sortUrl: String?, key: String?) -> Unit,
|
||||||
onNavigateToRssRead: (title: String?, origin: String, link: String?, openUrl: String?) -> Unit,
|
onNavigateToRssRead: (title: String?, origin: String, link: String?, openUrl: String?) -> Unit,
|
||||||
|
onNavigateToRssFavorites: () -> Unit,
|
||||||
|
onNavigateToRuleSub: () -> Unit,
|
||||||
onNavigateToReadRecord: () -> Unit,
|
onNavigateToReadRecord: () -> Unit,
|
||||||
sharedTransitionScope: SharedTransitionScope? = null,
|
sharedTransitionScope: SharedTransitionScope? = null,
|
||||||
animatedVisibilityScope: AnimatedVisibilityScope? = null,
|
animatedVisibilityScope: AnimatedVisibilityScope? = null,
|
||||||
@@ -383,7 +385,9 @@ fun MainScreen(
|
|||||||
},
|
},
|
||||||
onOpenRead = { title, origin, link, openUrl ->
|
onOpenRead = { title, origin, link, openUrl ->
|
||||||
onNavigateToRssRead(title, origin, link, openUrl)
|
onNavigateToRssRead(title, origin, link, openUrl)
|
||||||
}
|
},
|
||||||
|
onOpenFavorites = onNavigateToRssFavorites,
|
||||||
|
onOpenRuleSub = onNavigateToRuleSub
|
||||||
)
|
)
|
||||||
MainDestination.My -> MyScreen(
|
MainDestination.My -> MyScreen(
|
||||||
onOpenSettings = onOpenSettings,
|
onOpenSettings = onOpenSettings,
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ import androidx.compose.foundation.shape.RoundedCornerShape
|
|||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight
|
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight
|
||||||
import androidx.compose.material3.HorizontalDivider
|
import androidx.compose.material3.HorizontalDivider
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
@@ -36,12 +35,12 @@ import androidx.compose.ui.graphics.Brush
|
|||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.Shadow
|
import androidx.compose.ui.graphics.Shadow
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
|
||||||
import androidx.compose.ui.text.AnnotatedString
|
import androidx.compose.ui.text.AnnotatedString
|
||||||
import androidx.compose.ui.text.SpanStyle
|
import androidx.compose.ui.text.SpanStyle
|
||||||
import androidx.compose.ui.text.buildAnnotatedString
|
import androidx.compose.ui.text.buildAnnotatedString
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.text.withStyle
|
import androidx.compose.ui.text.withStyle
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import io.legado.app.R
|
import io.legado.app.R
|
||||||
@@ -49,13 +48,11 @@ import io.legado.app.constant.BookType
|
|||||||
import io.legado.app.ui.config.bookshelfConfig.BookshelfConfig
|
import io.legado.app.ui.config.bookshelfConfig.BookshelfConfig
|
||||||
import io.legado.app.ui.config.themeConfig.ThemeConfig
|
import io.legado.app.ui.config.themeConfig.ThemeConfig
|
||||||
import io.legado.app.ui.theme.LegadoTheme
|
import io.legado.app.ui.theme.LegadoTheme
|
||||||
import io.legado.app.ui.widget.components.card.GlassCard
|
|
||||||
import io.legado.app.ui.widget.components.card.NormalCard
|
import io.legado.app.ui.widget.components.card.NormalCard
|
||||||
import io.legado.app.ui.widget.components.card.TextCard
|
import io.legado.app.ui.widget.components.card.TextCard
|
||||||
import io.legado.app.ui.widget.components.cover.CoilBookCover
|
|
||||||
import io.legado.app.ui.widget.components.cover.BookshelfCover
|
import io.legado.app.ui.widget.components.cover.BookshelfCover
|
||||||
|
import io.legado.app.ui.widget.components.cover.CoilBookCover
|
||||||
import io.legado.app.ui.widget.components.icon.AppIcon
|
import io.legado.app.ui.widget.components.icon.AppIcon
|
||||||
import io.legado.app.ui.widget.components.icon.AppIcons
|
|
||||||
import io.legado.app.ui.widget.components.text.AppText
|
import io.legado.app.ui.widget.components.text.AppText
|
||||||
import io.legado.app.utils.splitNotBlank
|
import io.legado.app.utils.splitNotBlank
|
||||||
import io.legado.app.utils.toTimeAgo
|
import io.legado.app.utils.toTimeAgo
|
||||||
@@ -90,10 +87,11 @@ fun BookshelfItem(
|
|||||||
onClick: () -> Unit,
|
onClick: () -> Unit,
|
||||||
onLongClick: (() -> Unit)?
|
onLongClick: (() -> Unit)?
|
||||||
) {
|
) {
|
||||||
val containerColor = if (!isGrid && BookshelfConfig.bookshelfCardColor != 0) {
|
val isDark = LegadoTheme.isDark
|
||||||
Color(BookshelfConfig.bookshelfCardColor)
|
val bookshelfCardColor =
|
||||||
} else if (ThemeConfig.enableDeepPersonalization && ThemeConfig.secondaryThemeColor != 0) {
|
if (isDark) BookshelfConfig.bookshelfCardColorDark else BookshelfConfig.bookshelfCardColor
|
||||||
Color(ThemeConfig.secondaryThemeColor)
|
val containerColor = if (!isGrid && bookshelfCardColor != 0) {
|
||||||
|
Color(bookshelfCardColor)
|
||||||
} else {
|
} else {
|
||||||
LegadoTheme.colorScheme.cardContainer
|
LegadoTheme.colorScheme.cardContainer
|
||||||
}
|
}
|
||||||
@@ -189,7 +187,7 @@ fun BookshelfItem(
|
|||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.align(Alignment.Top)
|
.align(Alignment.Top)
|
||||||
.width(if (!isCompact) 80.dp else 56.dp)
|
.width(if (!isCompact) 84.dp else 56.dp)
|
||||||
.padding(end = 8.dp)
|
.padding(end = 8.dp)
|
||||||
) {
|
) {
|
||||||
Box(
|
Box(
|
||||||
@@ -209,11 +207,13 @@ fun BookshelfItem(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier.weight(1f).padding(top = 8.dp, bottom = 8.dp, end = 8.dp),
|
modifier = Modifier
|
||||||
|
.weight(1f)
|
||||||
|
.padding(top = 8.dp, bottom = 8.dp, end = 8.dp),
|
||||||
verticalArrangement = Arrangement.Center
|
verticalArrangement = Arrangement.Center
|
||||||
) {
|
) {
|
||||||
Row(
|
Row(
|
||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.Top
|
||||||
) {
|
) {
|
||||||
AppText(
|
AppText(
|
||||||
text = title,
|
text = title,
|
||||||
@@ -222,11 +222,15 @@ fun BookshelfItem(
|
|||||||
} else {
|
} else {
|
||||||
LegadoTheme.typography.titleMediumEmphasized
|
LegadoTheme.typography.titleMediumEmphasized
|
||||||
},
|
},
|
||||||
maxLines = 1,
|
maxLines = BookshelfConfig.bookshelfTitleMaxLines,
|
||||||
overflow = TextOverflow.Ellipsis,
|
overflow = TextOverflow.Ellipsis,
|
||||||
modifier = Modifier.weight(1f)
|
modifier = Modifier.weight(1f)
|
||||||
)
|
)
|
||||||
titleEnd?.invoke()
|
titleEnd?.let {
|
||||||
|
Box(modifier = Modifier.padding(top = 4.dp)) {
|
||||||
|
it.invoke()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
subTitle?.let {
|
subTitle?.let {
|
||||||
AppText(
|
AppText(
|
||||||
@@ -296,7 +300,20 @@ fun BookGroupCover(
|
|||||||
modifier = Modifier.fillMaxSize()
|
modifier = Modifier.fillMaxSize()
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
Column(modifier = Modifier.fillMaxSize()) {
|
Box(
|
||||||
|
modifier = Modifier.run {
|
||||||
|
if (BookshelfConfig.bookshelfCoverShadow) {
|
||||||
|
background(LegadoTheme.colorScheme.surface)
|
||||||
|
} else {
|
||||||
|
this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(horizontal = 1.dp),
|
||||||
|
) {
|
||||||
Row(modifier = Modifier.weight(1f)) {
|
Row(modifier = Modifier.weight(1f)) {
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
@@ -363,6 +380,7 @@ fun BookGroupCover(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!leftBottomText.isNullOrEmpty()) {
|
if (!leftBottomText.isNullOrEmpty()) {
|
||||||
TextCard(
|
TextCard(
|
||||||
@@ -482,13 +500,16 @@ fun BookGroupItemHorizontalCovers(
|
|||||||
onBookClick: ((BookShelfItem) -> Unit)? = null
|
onBookClick: ((BookShelfItem) -> Unit)? = null
|
||||||
) {
|
) {
|
||||||
Column {
|
Column {
|
||||||
|
val isDark = LegadoTheme.isDark
|
||||||
|
val bookshelfCardColor =
|
||||||
|
if (isDark) BookshelfConfig.bookshelfCardColorDark else BookshelfConfig.bookshelfCardColor
|
||||||
NormalCard(
|
NormalCard(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(all = 4.dp),
|
.padding(all = 4.dp),
|
||||||
cornerRadius = 12.dp,
|
cornerRadius = 12.dp,
|
||||||
containerColor = if (BookshelfConfig.bookshelfCardColor != 0) {
|
containerColor = if (bookshelfCardColor != 0) {
|
||||||
Color(BookshelfConfig.bookshelfCardColor)
|
Color(bookshelfCardColor)
|
||||||
} else {
|
} else {
|
||||||
LegadoTheme.colorScheme.cardContainer
|
LegadoTheme.colorScheme.cardContainer
|
||||||
},
|
},
|
||||||
@@ -634,7 +655,9 @@ fun BookItem(
|
|||||||
path = book.getDisplayCover(),
|
path = book.getDisplayCover(),
|
||||||
isUpdating = isUpdating,
|
isUpdating = isUpdating,
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
coverModifier = Modifier.fillMaxWidth().aspectRatio(5f / 7f),
|
coverModifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.aspectRatio(5f / 7f),
|
||||||
sourceOrigin = book.origin,
|
sourceOrigin = book.origin,
|
||||||
badgeText = if (layoutMode != 0) unreadText else null,
|
badgeText = if (layoutMode != 0) unreadText else null,
|
||||||
showBadgeDot = BookshelfConfig.showUnread && BookshelfConfig.showUnreadNew && book.isNew,
|
showBadgeDot = BookshelfConfig.showUnread && BookshelfConfig.showUnreadNew && book.isNew,
|
||||||
|
|||||||
@@ -3,11 +3,16 @@ package io.legado.app.ui.main.bookshelf
|
|||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
import androidx.compose.animation.animateContentSize
|
import androidx.compose.animation.animateContentSize
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.border
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
@@ -17,6 +22,8 @@ import androidx.compose.runtime.mutableStateOf
|
|||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.toArgb
|
import androidx.compose.ui.graphics.toArgb
|
||||||
import androidx.compose.ui.platform.LocalConfiguration
|
import androidx.compose.ui.platform.LocalConfiguration
|
||||||
import androidx.compose.ui.res.stringArrayResource
|
import androidx.compose.ui.res.stringArrayResource
|
||||||
@@ -27,8 +34,8 @@ import io.legado.app.ui.config.bookshelfConfig.BookshelfConfig
|
|||||||
import io.legado.app.ui.config.themeConfig.LabelColorManageSheet
|
import io.legado.app.ui.config.themeConfig.LabelColorManageSheet
|
||||||
import io.legado.app.ui.config.themeConfig.ThemeConfig
|
import io.legado.app.ui.config.themeConfig.ThemeConfig
|
||||||
import io.legado.app.ui.theme.LegadoTheme
|
import io.legado.app.ui.theme.LegadoTheme
|
||||||
import io.legado.app.ui.widget.components.card.GlassCard
|
|
||||||
import io.legado.app.ui.widget.components.dialog.ColorPickerSheet
|
import io.legado.app.ui.widget.components.dialog.ColorPickerSheet
|
||||||
|
import io.legado.app.ui.widget.components.divider.PillDivider
|
||||||
import io.legado.app.ui.widget.components.modalBottomSheet.AppModalBottomSheet
|
import io.legado.app.ui.widget.components.modalBottomSheet.AppModalBottomSheet
|
||||||
import io.legado.app.ui.widget.components.settingItem.CompactClickableSettingItem
|
import io.legado.app.ui.widget.components.settingItem.CompactClickableSettingItem
|
||||||
import io.legado.app.ui.widget.components.settingItem.CompactDropdownSettingItem
|
import io.legado.app.ui.widget.components.settingItem.CompactDropdownSettingItem
|
||||||
@@ -45,15 +52,13 @@ fun BookshelfConfigSheet(
|
|||||||
val isLandscape = configuration.orientation == Configuration.ORIENTATION_LANDSCAPE
|
val isLandscape = configuration.orientation == Configuration.ORIENTATION_LANDSCAPE
|
||||||
var showLabelColorManage by remember { mutableStateOf(false) }
|
var showLabelColorManage by remember { mutableStateOf(false) }
|
||||||
var showColorPicker by remember { mutableStateOf(false) }
|
var showColorPicker by remember { mutableStateOf(false) }
|
||||||
|
var showColorPickerDark by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
AppModalBottomSheet(
|
AppModalBottomSheet(
|
||||||
title = stringResource(R.string.bookshelf_layout),
|
title = stringResource(R.string.bookshelf_layout),
|
||||||
show = show,
|
show = show,
|
||||||
onDismissRequest = onDismissRequest
|
onDismissRequest = onDismissRequest
|
||||||
) {
|
) {
|
||||||
GlassCard() {
|
|
||||||
|
|
||||||
}
|
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
@@ -99,21 +104,12 @@ fun BookshelfConfigSheet(
|
|||||||
if (isLandscape) BookshelfConfig.bookshelfFolderLayoutModeLandscape
|
if (isLandscape) BookshelfConfig.bookshelfFolderLayoutModeLandscape
|
||||||
else BookshelfConfig.bookshelfFolderLayoutModePortrait
|
else BookshelfConfig.bookshelfFolderLayoutModePortrait
|
||||||
|
|
||||||
CompactDropdownSettingItem(
|
|
||||||
title = stringResource(R.string.layout_mode),
|
|
||||||
description = stringResource(if (isLandscape) R.string.screen_landscape else R.string.screen_portrait),
|
|
||||||
selectedValue = layoutMode.toString(),
|
|
||||||
displayEntries = arrayOf(stringResource(R.string.layout_mode_list),stringResource(R.string.layout_mode_grid)),
|
|
||||||
entryValues = arrayOf("0", "1"),
|
|
||||||
onValueChange = {
|
|
||||||
if (isLandscape) BookshelfConfig.bookshelfLayoutModeLandscape = it.toInt()
|
|
||||||
else BookshelfConfig.bookshelfLayoutModePortrait = it.toInt()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// Folder Layout Mode
|
// Folder Layout Mode
|
||||||
AnimatedVisibility(visible = BookshelfConfig.bookGroupStyle == 2) {
|
AnimatedVisibility(visible = BookshelfConfig.bookGroupStyle == 2) {
|
||||||
Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
|
Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||||
|
|
||||||
|
PillDivider()
|
||||||
|
|
||||||
CompactDropdownSettingItem(
|
CompactDropdownSettingItem(
|
||||||
title = "文件夹布局模式",
|
title = "文件夹布局模式",
|
||||||
description = stringResource(if (isLandscape) R.string.screen_landscape else R.string.screen_portrait),
|
description = stringResource(if (isLandscape) R.string.screen_landscape else R.string.screen_portrait),
|
||||||
@@ -157,8 +153,6 @@ fun BookshelfConfigSheet(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AnimatedVisibility(
|
AnimatedVisibility(
|
||||||
visible = BookshelfConfig.bookGroupStyle == 2 && folderLayoutMode == 0
|
visible = BookshelfConfig.bookGroupStyle == 2 && folderLayoutMode == 0
|
||||||
@@ -171,7 +165,9 @@ fun BookshelfConfigSheet(
|
|||||||
selectedValue = BookshelfConfig.bookshelfGroupListStyle.toString(),
|
selectedValue = BookshelfConfig.bookshelfGroupListStyle.toString(),
|
||||||
displayEntries = arrayOf("默认", "紧凑", "横排封面"),
|
displayEntries = arrayOf("默认", "紧凑", "横排封面"),
|
||||||
entryValues = arrayOf("0", "1", "2"),
|
entryValues = arrayOf("0", "1", "2"),
|
||||||
onValueChange = { BookshelfConfig.bookshelfGroupListStyle = it.toInt() }
|
onValueChange = {
|
||||||
|
BookshelfConfig.bookshelfGroupListStyle = it.toInt()
|
||||||
|
}
|
||||||
)
|
)
|
||||||
AnimatedVisibility(visible = BookshelfConfig.bookshelfGroupListStyle == 2) {
|
AnimatedVisibility(visible = BookshelfConfig.bookshelfGroupListStyle == 2) {
|
||||||
CompactSliderSettingItem(
|
CompactSliderSettingItem(
|
||||||
@@ -179,12 +175,33 @@ fun BookshelfConfigSheet(
|
|||||||
value = BookshelfConfig.bookshelfGroupCoverCount.toFloat(),
|
value = BookshelfConfig.bookshelfGroupCoverCount.toFloat(),
|
||||||
valueRange = 1f..10f,
|
valueRange = 1f..10f,
|
||||||
steps = 9,
|
steps = 9,
|
||||||
onValueChange = { BookshelfConfig.bookshelfGroupCoverCount = it.toInt() }
|
onValueChange = {
|
||||||
|
BookshelfConfig.bookshelfGroupCoverCount = it.toInt()
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PillDivider()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CompactDropdownSettingItem(
|
||||||
|
title = stringResource(R.string.layout_mode),
|
||||||
|
description = stringResource(if (isLandscape) R.string.screen_landscape else R.string.screen_portrait),
|
||||||
|
selectedValue = layoutMode.toString(),
|
||||||
|
displayEntries = arrayOf(
|
||||||
|
stringResource(R.string.layout_mode_list),
|
||||||
|
stringResource(R.string.layout_mode_grid)
|
||||||
|
),
|
||||||
|
entryValues = arrayOf("0", "1"),
|
||||||
|
onValueChange = {
|
||||||
|
if (isLandscape) BookshelfConfig.bookshelfLayoutModeLandscape = it.toInt()
|
||||||
|
else BookshelfConfig.bookshelfLayoutModePortrait = it.toInt()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
AnimatedVisibility(
|
AnimatedVisibility(
|
||||||
visible = layoutMode == 1
|
visible = layoutMode == 1
|
||||||
) {
|
) {
|
||||||
@@ -243,17 +260,47 @@ fun BookshelfConfigSheet(
|
|||||||
)
|
)
|
||||||
|
|
||||||
CompactClickableSettingItem(
|
CompactClickableSettingItem(
|
||||||
title = "卡片背景颜色",
|
title = "日间卡片背景颜色",
|
||||||
color = LegadoTheme.colorScheme.surface,
|
color = LegadoTheme.colorScheme.surface,
|
||||||
onClick = { showColorPicker = true }
|
onClick = { showColorPicker = true },
|
||||||
|
trailingContent = {
|
||||||
|
if (BookshelfConfig.bookshelfCardColor != 0) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.size(20.dp)
|
||||||
|
.clip(CircleShape)
|
||||||
|
.background(Color(BookshelfConfig.bookshelfCardColor))
|
||||||
|
.border(
|
||||||
|
1.dp,
|
||||||
|
MaterialTheme.colorScheme.outlineVariant,
|
||||||
|
CircleShape
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
val isHorizontalCovers = BookshelfConfig.bookGroupStyle == 2 && BookshelfConfig.bookshelfGroupListStyle == 2
|
CompactClickableSettingItem(
|
||||||
|
title = "夜间卡片背景颜色",
|
||||||
|
color = LegadoTheme.colorScheme.surface,
|
||||||
|
onClick = { showColorPickerDark = true },
|
||||||
|
trailingContent = {
|
||||||
|
if (BookshelfConfig.bookshelfCardColorDark != 0) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.size(20.dp)
|
||||||
|
.clip(CircleShape)
|
||||||
|
.background(Color(BookshelfConfig.bookshelfCardColorDark))
|
||||||
|
.border(
|
||||||
|
1.dp,
|
||||||
|
MaterialTheme.colorScheme.outlineVariant,
|
||||||
|
CircleShape
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
AnimatedVisibility(visible = !isHorizontalCovers) {
|
|
||||||
Column(
|
|
||||||
verticalArrangement = Arrangement.spacedBy(8.dp)
|
|
||||||
) {
|
|
||||||
if (BookshelfConfig.bookGroupStyle != 2) {
|
if (BookshelfConfig.bookGroupStyle != 2) {
|
||||||
CompactSwitchSettingItem(
|
CompactSwitchSettingItem(
|
||||||
title = stringResource(R.string.compact_mode),
|
title = stringResource(R.string.compact_mode),
|
||||||
@@ -292,7 +339,9 @@ fun BookshelfConfigSheet(
|
|||||||
title = "显示最新章节",
|
title = "显示最新章节",
|
||||||
checked = BookshelfConfig.bookshelfShowLatestChapter,
|
checked = BookshelfConfig.bookshelfShowLatestChapter,
|
||||||
color = LegadoTheme.colorScheme.surface,
|
color = LegadoTheme.colorScheme.surface,
|
||||||
onCheckedChange = { BookshelfConfig.bookshelfShowLatestChapter = it }
|
onCheckedChange = {
|
||||||
|
BookshelfConfig.bookshelfShowLatestChapter = it
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
CompactSwitchSettingItem(
|
CompactSwitchSettingItem(
|
||||||
@@ -310,7 +359,9 @@ fun BookshelfConfigSheet(
|
|||||||
value = BookshelfConfig.bookshelfIntroMaxLines.toFloat(),
|
value = BookshelfConfig.bookshelfIntroMaxLines.toFloat(),
|
||||||
valueRange = 0f..10f,
|
valueRange = 0f..10f,
|
||||||
steps = 10,
|
steps = 10,
|
||||||
onValueChange = { BookshelfConfig.bookshelfIntroMaxLines = it.toInt() }
|
onValueChange = {
|
||||||
|
BookshelfConfig.bookshelfIntroMaxLines = it.toInt()
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
CompactSwitchSettingItem(
|
CompactSwitchSettingItem(
|
||||||
@@ -344,8 +395,8 @@ fun BookshelfConfigSheet(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CompactSliderSettingItem(
|
CompactSliderSettingItem(
|
||||||
title = stringResource(R.string.max_title_lines),
|
title = stringResource(R.string.max_title_lines),
|
||||||
@@ -448,5 +499,12 @@ fun BookshelfConfigSheet(
|
|||||||
onDismissRequest = { showColorPicker = false },
|
onDismissRequest = { showColorPicker = false },
|
||||||
onColorSelected = { BookshelfConfig.bookshelfCardColor = it }
|
onColorSelected = { BookshelfConfig.bookshelfCardColor = it }
|
||||||
)
|
)
|
||||||
|
|
||||||
|
ColorPickerSheet(
|
||||||
|
show = showColorPickerDark,
|
||||||
|
initialColor = if (BookshelfConfig.bookshelfCardColorDark != 0) BookshelfConfig.bookshelfCardColorDark else LegadoTheme.colorScheme.surfaceVariant.toArgb(),
|
||||||
|
onDismissRequest = { showColorPickerDark = false },
|
||||||
|
onColorSelected = { BookshelfConfig.bookshelfCardColorDark = it }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -778,7 +778,7 @@ fun BookshelfScreen(
|
|||||||
),
|
),
|
||||||
contentPadding = adaptiveContentPaddingBookshelf(
|
contentPadding = adaptiveContentPaddingBookshelf(
|
||||||
top = paddingValues.calculateTopPadding(),
|
top = paddingValues.calculateTopPadding(),
|
||||||
bottom = if (ThemeConfig.useFloatingBottomBar) 120.dp else 8.dp,
|
bottom = if (ThemeConfig.useFloatingBottomBar || ThemeConfig.enableBlur) 120.dp else 8.dp,
|
||||||
horizontal = if (isGridMode) 8.dp else 4.dp
|
horizontal = if (isGridMode) 8.dp else 4.dp
|
||||||
),
|
),
|
||||||
verticalArrangement = Arrangement.spacedBy(if (isGridMode) 8.dp else 0.dp),
|
verticalArrangement = Arrangement.spacedBy(if (isGridMode) 8.dp else 0.dp),
|
||||||
@@ -1342,7 +1342,7 @@ fun BookshelfPage(
|
|||||||
),
|
),
|
||||||
contentPadding = adaptiveContentPaddingBookshelf(
|
contentPadding = adaptiveContentPaddingBookshelf(
|
||||||
top = paddingValues.calculateTopPadding(),
|
top = paddingValues.calculateTopPadding(),
|
||||||
bottom = if (ThemeConfig.useFloatingBottomBar) 120.dp else 8.dp,
|
bottom = if (ThemeConfig.useFloatingBottomBar || ThemeConfig.enableBlur) 120.dp else 8.dp,
|
||||||
horizontal = if (isGridMode) 8.dp else 4.dp
|
horizontal = if (isGridMode) 8.dp else 4.dp
|
||||||
),
|
),
|
||||||
verticalArrangement = Arrangement.spacedBy(if (isGridMode) 8.dp else 0.dp),
|
verticalArrangement = Arrangement.spacedBy(if (isGridMode) 8.dp else 0.dp),
|
||||||
|
|||||||
@@ -45,10 +45,8 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
|||||||
import io.legado.app.R
|
import io.legado.app.R
|
||||||
import io.legado.app.data.entities.RssSource
|
import io.legado.app.data.entities.RssSource
|
||||||
import io.legado.app.ui.login.SourceLoginActivity
|
import io.legado.app.ui.login.SourceLoginActivity
|
||||||
import io.legado.app.ui.rss.favorites.RssFavoritesActivity
|
|
||||||
import io.legado.app.ui.rss.source.edit.RssSourceEditActivity
|
import io.legado.app.ui.rss.source.edit.RssSourceEditActivity
|
||||||
import io.legado.app.ui.rss.source.manage.RssSourceActivity
|
import io.legado.app.ui.rss.source.manage.RssSourceActivity
|
||||||
import io.legado.app.ui.rss.subscription.RuleSubActivity
|
|
||||||
import io.legado.app.ui.theme.LegadoTheme
|
import io.legado.app.ui.theme.LegadoTheme
|
||||||
import io.legado.app.ui.theme.adaptiveContentPadding
|
import io.legado.app.ui.theme.adaptiveContentPadding
|
||||||
import io.legado.app.ui.widget.components.SourceIcon
|
import io.legado.app.ui.widget.components.SourceIcon
|
||||||
@@ -71,7 +69,9 @@ import org.koin.androidx.compose.koinViewModel
|
|||||||
fun RssScreen(
|
fun RssScreen(
|
||||||
viewModel: RssViewModel = koinViewModel(),
|
viewModel: RssViewModel = koinViewModel(),
|
||||||
onOpenSort: (sourceUrl: String, sortUrl: String?, key: String?) -> Unit,
|
onOpenSort: (sourceUrl: String, sortUrl: String?, key: String?) -> Unit,
|
||||||
onOpenRead: (title: String?, origin: String, link: String?, openUrl: String?) -> Unit
|
onOpenRead: (title: String?, origin: String, link: String?, openUrl: String?) -> Unit,
|
||||||
|
onOpenRuleSub: () -> Unit,
|
||||||
|
onOpenFavorites: () -> Unit,
|
||||||
) {
|
) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
|
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
|
||||||
@@ -82,6 +82,8 @@ fun RssScreen(
|
|||||||
val currentContext by rememberUpdatedState(context)
|
val currentContext by rememberUpdatedState(context)
|
||||||
val currentOnOpenSort by rememberUpdatedState(onOpenSort)
|
val currentOnOpenSort by rememberUpdatedState(onOpenSort)
|
||||||
val currentOnOpenRead by rememberUpdatedState(onOpenRead)
|
val currentOnOpenRead by rememberUpdatedState(onOpenRead)
|
||||||
|
val currentOnOpenRuleSub by rememberUpdatedState(onOpenRuleSub)
|
||||||
|
val currentOnOpenFavorites by rememberUpdatedState(onOpenFavorites)
|
||||||
|
|
||||||
LaunchedEffect(viewModel) {
|
LaunchedEffect(viewModel) {
|
||||||
viewModel.effects.collectLatest { effect ->
|
viewModel.effects.collectLatest { effect ->
|
||||||
@@ -112,11 +114,11 @@ fun RssScreen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
RssEffect.OpenRuleSub -> {
|
RssEffect.OpenRuleSub -> {
|
||||||
currentContext.startActivity<RuleSubActivity>()
|
currentOnOpenRuleSub()
|
||||||
}
|
}
|
||||||
|
|
||||||
RssEffect.OpenFavorites -> {
|
RssEffect.OpenFavorites -> {
|
||||||
currentContext.startActivity<RssFavoritesActivity>()
|
currentOnOpenFavorites()
|
||||||
}
|
}
|
||||||
|
|
||||||
RssEffect.OpenSourceManage -> {
|
RssEffect.OpenSourceManage -> {
|
||||||
|
|||||||
@@ -1,52 +0,0 @@
|
|||||||
package io.legado.app.ui.rss.favorites
|
|
||||||
|
|
||||||
import android.os.Bundle
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import io.legado.app.base.BaseComposeActivity
|
|
||||||
import io.legado.app.ui.rss.read.RssReadRouteScreen
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 收藏夹
|
|
||||||
*/
|
|
||||||
class RssFavoritesActivity : BaseComposeActivity() {
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
|
||||||
super.onCreate(savedInstanceState)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
override fun Content() {
|
|
||||||
var readArgs by remember {
|
|
||||||
mutableStateOf<ReadArgs?>(null)
|
|
||||||
}
|
|
||||||
|
|
||||||
val currentReadArgs = readArgs
|
|
||||||
if (currentReadArgs == null) {
|
|
||||||
RssFavoritesScreen(
|
|
||||||
onBackClick = { finish() },
|
|
||||||
onOpenRead = { title, origin, link, openUrl ->
|
|
||||||
readArgs = ReadArgs(title, origin, link, openUrl)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
RssReadRouteScreen(
|
|
||||||
title = currentReadArgs.title,
|
|
||||||
origin = currentReadArgs.origin,
|
|
||||||
link = currentReadArgs.link,
|
|
||||||
openUrl = currentReadArgs.openUrl,
|
|
||||||
onBackClick = { readArgs = null }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private data class ReadArgs(
|
|
||||||
val title: String?,
|
|
||||||
val origin: String,
|
|
||||||
val link: String?,
|
|
||||||
val openUrl: String?
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -28,7 +28,6 @@ import androidx.compose.ui.Modifier
|
|||||||
import androidx.compose.ui.layout.ContentScale
|
import androidx.compose.ui.layout.ContentScale
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
|
||||||
import io.legado.app.R
|
import io.legado.app.R
|
||||||
import io.legado.app.data.entities.RssStar
|
import io.legado.app.data.entities.RssStar
|
||||||
import io.legado.app.ui.theme.adaptiveContentPadding
|
import io.legado.app.ui.theme.adaptiveContentPadding
|
||||||
@@ -41,13 +40,14 @@ import io.legado.app.ui.widget.components.dialog.TextListInputDialog
|
|||||||
import io.legado.app.ui.widget.components.divider.PillDivider
|
import io.legado.app.ui.widget.components.divider.PillDivider
|
||||||
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenuItem
|
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenuItem
|
||||||
import io.legado.app.ui.widget.components.rules.RuleListScaffold
|
import io.legado.app.ui.widget.components.rules.RuleListScaffold
|
||||||
|
import org.koin.androidx.compose.koinViewModel
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun RssFavoritesScreen(
|
fun RssFavoritesScreen(
|
||||||
onBackClick: () -> Unit,
|
onBackClick: () -> Unit,
|
||||||
onOpenRead: (title: String?, origin: String, link: String?, openUrl: String?) -> Unit,
|
onOpenRead: (title: String?, origin: String, link: String?, openUrl: String?) -> Unit,
|
||||||
viewModel: RssFavoritesViewModel = viewModel()
|
viewModel: RssFavoritesViewModel = koinViewModel()
|
||||||
) {
|
) {
|
||||||
val state by viewModel.state.collectAsState()
|
val state by viewModel.state.collectAsState()
|
||||||
val groups by viewModel.groups.collectAsState()
|
val groups by viewModel.groups.collectAsState()
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
package io.legado.app.ui.rss.subscription
|
|
||||||
|
|
||||||
import android.os.Bundle
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import io.legado.app.base.BaseComposeActivity
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 规则订阅界面
|
|
||||||
*/
|
|
||||||
class RuleSubActivity : BaseComposeActivity() {
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
|
||||||
super.onCreate(savedInstanceState)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
override fun Content() {
|
|
||||||
RuleSubScreen(
|
|
||||||
onBackClick = { finish() }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -18,7 +18,6 @@ import androidx.compose.material.icons.filled.Add
|
|||||||
import androidx.compose.material.icons.filled.Edit
|
import androidx.compose.material.icons.filled.Edit
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||||
import io.legado.app.ui.widget.components.AppFloatingActionButton
|
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
import androidx.compose.material3.SnackbarHostState
|
import androidx.compose.material3.SnackbarHostState
|
||||||
@@ -37,7 +36,6 @@ import androidx.compose.ui.res.stringArrayResource
|
|||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
|
||||||
import io.legado.app.R
|
import io.legado.app.R
|
||||||
import io.legado.app.data.entities.RuleSub
|
import io.legado.app.data.entities.RuleSub
|
||||||
import io.legado.app.data.entities.RuleSubType
|
import io.legado.app.data.entities.RuleSubType
|
||||||
@@ -46,6 +44,7 @@ import io.legado.app.ui.association.ImportReplaceRuleDialog
|
|||||||
import io.legado.app.ui.association.ImportRssSourceDialog
|
import io.legado.app.ui.association.ImportRssSourceDialog
|
||||||
import io.legado.app.ui.theme.LegadoTheme
|
import io.legado.app.ui.theme.LegadoTheme
|
||||||
import io.legado.app.ui.theme.adaptiveContentPadding
|
import io.legado.app.ui.theme.adaptiveContentPadding
|
||||||
|
import io.legado.app.ui.widget.components.AppFloatingActionButton
|
||||||
import io.legado.app.ui.widget.components.AppTextField
|
import io.legado.app.ui.widget.components.AppTextField
|
||||||
import io.legado.app.ui.widget.components.EmptyMessage
|
import io.legado.app.ui.widget.components.EmptyMessage
|
||||||
import io.legado.app.ui.widget.components.alert.AppAlertDialog
|
import io.legado.app.ui.widget.components.alert.AppAlertDialog
|
||||||
@@ -57,12 +56,13 @@ import io.legado.app.ui.widget.components.rules.RuleListScaffold
|
|||||||
import io.legado.app.ui.widget.components.text.AppText
|
import io.legado.app.ui.widget.components.text.AppText
|
||||||
import io.legado.app.utils.showDialogFragment
|
import io.legado.app.utils.showDialogFragment
|
||||||
import io.legado.app.utils.toastOnUi
|
import io.legado.app.utils.toastOnUi
|
||||||
|
import org.koin.androidx.compose.koinViewModel
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
|
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun RuleSubScreen(
|
fun RuleSubScreen(
|
||||||
onBackClick: () -> Unit,
|
onBackClick: () -> Unit,
|
||||||
viewModel: RuleSubViewModel = viewModel()
|
viewModel: RuleSubViewModel = koinViewModel()
|
||||||
) {
|
) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val state by viewModel.state.collectAsState()
|
val state by viewModel.state.collectAsState()
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ fun adaptiveContentPadding(
|
|||||||
bottom: Dp
|
bottom: Dp
|
||||||
): PaddingValues {
|
): PaddingValues {
|
||||||
val horizontal = if (ThemeResolver.isMiuixEngine(composeEngine)) 12.dp else 16.dp
|
val horizontal = if (ThemeResolver.isMiuixEngine(composeEngine)) 12.dp else 16.dp
|
||||||
val adjustedTop = if (ThemeResolver.isMiuixEngine(composeEngine)) top + 8.dp else top
|
val adjustedTop = if (ThemeResolver.isMiuixEngine(composeEngine)) top + 12.dp else top + 16.dp
|
||||||
return PaddingValues(
|
return PaddingValues(
|
||||||
top = adjustedTop,
|
top = adjustedTop,
|
||||||
bottom = bottom,
|
bottom = bottom,
|
||||||
@@ -70,7 +70,7 @@ fun adaptiveContentPadding(
|
|||||||
bottom: Dp,
|
bottom: Dp,
|
||||||
horizontal: Dp
|
horizontal: Dp
|
||||||
): PaddingValues {
|
): PaddingValues {
|
||||||
val adjustedTop = if (ThemeResolver.isMiuixEngine(composeEngine)) top + 6.dp else top + 4.dp
|
val adjustedTop = if (ThemeResolver.isMiuixEngine(composeEngine)) top + 12.dp else top + 16.dp
|
||||||
return PaddingValues(
|
return PaddingValues(
|
||||||
top = adjustedTop,
|
top = adjustedTop,
|
||||||
bottom = bottom,
|
bottom = bottom,
|
||||||
|
|||||||
@@ -5,16 +5,16 @@ import androidx.compose.animation.ExperimentalSharedTransitionApi
|
|||||||
import androidx.compose.animation.SharedTransitionScope
|
import androidx.compose.animation.SharedTransitionScope
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.horizontalScroll
|
import androidx.compose.foundation.horizontalScroll
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.IntrinsicSize
|
import androidx.compose.foundation.layout.IntrinsicSize
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.RowScope
|
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.aspectRatio
|
import androidx.compose.foundation.layout.aspectRatio
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
@@ -23,37 +23,18 @@ import androidx.compose.material.icons.filled.Check
|
|||||||
import androidx.compose.material.icons.filled.Shuffle
|
import androidx.compose.material.icons.filled.Shuffle
|
||||||
import androidx.compose.material3.Surface
|
import androidx.compose.material3.Surface
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
|
||||||
import io.legado.app.data.entities.SearchBook
|
import io.legado.app.data.entities.SearchBook
|
||||||
import io.legado.app.domain.model.BookShelfState
|
import io.legado.app.domain.model.BookShelfState
|
||||||
import io.legado.app.ui.theme.LegadoTheme
|
import io.legado.app.ui.theme.LegadoTheme
|
||||||
|
import io.legado.app.ui.widget.components.card.TextCard
|
||||||
import io.legado.app.ui.widget.components.cover.CoilBookCover
|
import io.legado.app.ui.widget.components.cover.CoilBookCover
|
||||||
import io.legado.app.ui.widget.components.text.AppText
|
import io.legado.app.ui.widget.components.text.AppText
|
||||||
import kotlinx.coroutines.flow.Flow
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun SearchBookListItem(
|
|
||||||
book: SearchBook,
|
|
||||||
shelfState: Flow<BookShelfState>,
|
|
||||||
onClick: () -> Unit,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
|
||||||
val currentShelfState by shelfState.collectAsState(initial = BookShelfState.NOT_IN_SHELF)
|
|
||||||
SearchBookListItem(
|
|
||||||
book = book,
|
|
||||||
shelfState = currentShelfState,
|
|
||||||
onClick = onClick,
|
|
||||||
modifier = modifier,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@OptIn(ExperimentalSharedTransitionApi::class)
|
@OptIn(ExperimentalSharedTransitionApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
@@ -72,11 +53,14 @@ fun SearchBookListItem(
|
|||||||
.clickable(onClick = onClick)
|
.clickable(onClick = onClick)
|
||||||
.padding(horizontal = 16.dp, vertical = 8.dp)
|
.padding(horizontal = 16.dp, vertical = 8.dp)
|
||||||
) {
|
) {
|
||||||
|
Box(modifier = Modifier
|
||||||
|
.width(72.dp)
|
||||||
|
.aspectRatio(5f / 7f)) {
|
||||||
CoilBookCover(
|
CoilBookCover(
|
||||||
name = book.name,
|
name = book.name,
|
||||||
author = book.author,
|
author = book.author,
|
||||||
path = book.coverUrl,
|
path = book.coverUrl,
|
||||||
modifier = Modifier.width(72.dp).aspectRatio(5f / 7f),
|
modifier = Modifier.fillMaxSize(),
|
||||||
sourceOrigin = book.origin,
|
sourceOrigin = book.origin,
|
||||||
sharedTransitionScope = sharedTransitionScope,
|
sharedTransitionScope = sharedTransitionScope,
|
||||||
animatedVisibilityScope = animatedVisibilityScope,
|
animatedVisibilityScope = animatedVisibilityScope,
|
||||||
@@ -84,6 +68,25 @@ fun SearchBookListItem(
|
|||||||
showLoadingPlaceholder = sharedCoverKey == null
|
showLoadingPlaceholder = sharedCoverKey == null
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val shelfIcon = when (shelfState) {
|
||||||
|
BookShelfState.IN_SHELF -> Icons.Default.Check
|
||||||
|
BookShelfState.SAME_NAME_AUTHOR -> Icons.Default.Shuffle
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shelfIcon != null) {
|
||||||
|
TextCard(
|
||||||
|
icon = shelfIcon,
|
||||||
|
modifier = Modifier
|
||||||
|
.align(Alignment.TopEnd)
|
||||||
|
.padding(2.dp),
|
||||||
|
cornerRadius = 4.dp,
|
||||||
|
horizontalPadding = 2.dp,
|
||||||
|
verticalPadding = 2.dp
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Spacer(modifier = Modifier.width(8.dp))
|
Spacer(modifier = Modifier.width(8.dp))
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
@@ -151,22 +154,6 @@ fun SearchBookListItem(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun SearchBookGridItem(
|
|
||||||
book: SearchBook,
|
|
||||||
shelfState: Flow<BookShelfState>,
|
|
||||||
onClick: () -> Unit,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
|
||||||
val currentShelfState by shelfState.collectAsState(initial = BookShelfState.NOT_IN_SHELF)
|
|
||||||
SearchBookGridItem(
|
|
||||||
book = book,
|
|
||||||
shelfState = currentShelfState,
|
|
||||||
onClick = onClick,
|
|
||||||
modifier = modifier,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@OptIn(ExperimentalSharedTransitionApi::class)
|
@OptIn(ExperimentalSharedTransitionApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun SearchBookGridItem(
|
fun SearchBookGridItem(
|
||||||
@@ -183,14 +170,17 @@ fun SearchBookGridItem(
|
|||||||
.width(IntrinsicSize.Min)
|
.width(IntrinsicSize.Min)
|
||||||
.clickable(onClick = onClick)
|
.clickable(onClick = onClick)
|
||||||
.padding(4.dp)
|
.padding(4.dp)
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.aspectRatio(5f / 7f)
|
||||||
) {
|
) {
|
||||||
CoilBookCover(
|
CoilBookCover(
|
||||||
name = book.name,
|
name = book.name,
|
||||||
author = book.author,
|
author = book.author,
|
||||||
path = book.coverUrl,
|
path = book.coverUrl,
|
||||||
modifier = Modifier
|
modifier = Modifier.fillMaxSize(),
|
||||||
.fillMaxWidth()
|
|
||||||
.aspectRatio(5f / 7f),
|
|
||||||
sourceOrigin = book.origin,
|
sourceOrigin = book.origin,
|
||||||
sharedTransitionScope = sharedTransitionScope,
|
sharedTransitionScope = sharedTransitionScope,
|
||||||
animatedVisibilityScope = animatedVisibilityScope,
|
animatedVisibilityScope = animatedVisibilityScope,
|
||||||
@@ -198,6 +188,25 @@ fun SearchBookGridItem(
|
|||||||
showLoadingPlaceholder = sharedCoverKey == null
|
showLoadingPlaceholder = sharedCoverKey == null
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val shelfIcon = when (shelfState) {
|
||||||
|
BookShelfState.IN_SHELF -> Icons.Default.Check
|
||||||
|
BookShelfState.SAME_NAME_AUTHOR -> Icons.Default.Shuffle
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shelfIcon != null) {
|
||||||
|
TextCard(
|
||||||
|
icon = shelfIcon,
|
||||||
|
modifier = Modifier
|
||||||
|
.align(Alignment.TopEnd)
|
||||||
|
.padding(2.dp),
|
||||||
|
cornerRadius = 4.dp,
|
||||||
|
horizontalPadding = 2.dp,
|
||||||
|
verticalPadding = 2.dp
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(4.dp))
|
Spacer(modifier = Modifier.height(4.dp))
|
||||||
|
|
||||||
AppText(
|
AppText(
|
||||||
|
|||||||
@@ -27,12 +27,18 @@ fun PillDivider(
|
|||||||
val isMiuix = ThemeResolver.isMiuixEngine(LegadoTheme.composeEngine)
|
val isMiuix = ThemeResolver.isMiuixEngine(LegadoTheme.composeEngine)
|
||||||
if (isMiuix) {
|
if (isMiuix) {
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(vertical = 2.dp)
|
.padding(vertical = 4.dp),
|
||||||
.height(4.dp)
|
contentAlignment = Alignment.Center
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth(0.8f)
|
||||||
|
.height(thickness)
|
||||||
.background(MiuixTheme.colorScheme.dividerLine)
|
.background(MiuixTheme.colorScheme.dividerLine)
|
||||||
)
|
)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Box(
|
Box(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
|
|||||||
+4
-4
@@ -48,7 +48,7 @@ fun CompactDropdownSettingItem(
|
|||||||
entryValues: Array<String>,
|
entryValues: Array<String>,
|
||||||
description: String? = null,
|
description: String? = null,
|
||||||
imageVector: ImageVector? = null,
|
imageVector: ImageVector? = null,
|
||||||
color: Color? = LegadoTheme.colorScheme.surface,
|
color: Color? = LegadoTheme.colorScheme.onSheetContent,
|
||||||
shape: Shape = MaterialTheme.shapes.small,
|
shape: Shape = MaterialTheme.shapes.small,
|
||||||
onValueChange: (String) -> Unit
|
onValueChange: (String) -> Unit
|
||||||
) {
|
) {
|
||||||
@@ -126,7 +126,7 @@ fun CompactSliderSettingItem(
|
|||||||
steps: Int = 0,
|
steps: Int = 0,
|
||||||
description: String? = null,
|
description: String? = null,
|
||||||
imageVector: ImageVector? = null,
|
imageVector: ImageVector? = null,
|
||||||
color: Color? = MaterialTheme.colorScheme.surface,
|
color: Color? = LegadoTheme.colorScheme.onSheetContent,
|
||||||
shape: Shape = MaterialTheme.shapes.small,
|
shape: Shape = MaterialTheme.shapes.small,
|
||||||
onValueChange: (Float) -> Unit
|
onValueChange: (Float) -> Unit
|
||||||
) {
|
) {
|
||||||
@@ -222,7 +222,7 @@ fun CompactSwitchSettingItem(
|
|||||||
checked: Boolean,
|
checked: Boolean,
|
||||||
description: String? = null,
|
description: String? = null,
|
||||||
imageVector: ImageVector? = null,
|
imageVector: ImageVector? = null,
|
||||||
color: Color? = MaterialTheme.colorScheme.surface,
|
color: Color? = LegadoTheme.colorScheme.onSheetContent,
|
||||||
shape: Shape = MaterialTheme.shapes.small,
|
shape: Shape = MaterialTheme.shapes.small,
|
||||||
enabled: Boolean = true,
|
enabled: Boolean = true,
|
||||||
onCheckedChange: (Boolean) -> Unit
|
onCheckedChange: (Boolean) -> Unit
|
||||||
@@ -260,7 +260,7 @@ fun CompactClickableSettingItem(
|
|||||||
title: String,
|
title: String,
|
||||||
description: String? = null,
|
description: String? = null,
|
||||||
imageVector: ImageVector? = null,
|
imageVector: ImageVector? = null,
|
||||||
color: Color? = MaterialTheme.colorScheme.surface,
|
color: Color? = LegadoTheme.colorScheme.onSheetContent,
|
||||||
shape: Shape = MaterialTheme.shapes.small,
|
shape: Shape = MaterialTheme.shapes.small,
|
||||||
trailingContent: (@Composable () -> Unit)? = null,
|
trailingContent: (@Composable () -> Unit)? = null,
|
||||||
onClick: () -> Unit
|
onClick: () -> Unit
|
||||||
|
|||||||
Reference in new issue
Block a user