书架性能优化
This commit is contained in:
6 files changed
+2223
-29
No files matched your search
File diff suppressed because it is too large.
Load diff
@@ -69,7 +69,7 @@ val appDb by lazy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Database(
|
@Database(
|
||||||
version = 86,
|
version = 87,
|
||||||
exportSchema = true,
|
exportSchema = true,
|
||||||
entities = [Book::class, BookGroup::class, BookSource::class, BookChapter::class,
|
entities = [Book::class, BookGroup::class, BookSource::class, BookChapter::class,
|
||||||
ReplaceRule::class, SearchBook::class, SearchKeyword::class, Cookie::class,
|
ReplaceRule::class, SearchBook::class, SearchKeyword::class, Cookie::class,
|
||||||
@@ -122,7 +122,8 @@ val appDb by lazy {
|
|||||||
AutoMigration(from = 82, to = 83),
|
AutoMigration(from = 82, to = 83),
|
||||||
AutoMigration(from = 83, to = 84),
|
AutoMigration(from = 83, to = 84),
|
||||||
AutoMigration(from = 84, to = 85),
|
AutoMigration(from = 84, to = 85),
|
||||||
AutoMigration(from = 85, to = 86)
|
AutoMigration(from = 85, to = 86),
|
||||||
|
AutoMigration(from = 86, to = 87)
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
abstract class AppDatabase : RoomDatabase() {
|
abstract class AppDatabase : RoomDatabase() {
|
||||||
|
|||||||
@@ -33,7 +33,10 @@ import kotlin.math.max
|
|||||||
@TypeConverters(Book.Converters::class)
|
@TypeConverters(Book.Converters::class)
|
||||||
@Entity(
|
@Entity(
|
||||||
tableName = "books",
|
tableName = "books",
|
||||||
indices = [Index(value = ["name", "author"], unique = false)]
|
indices = [
|
||||||
|
Index(value = ["name", "author"], unique = false),
|
||||||
|
Index(value = ["durChapterTime"], unique = false)
|
||||||
|
]
|
||||||
)
|
)
|
||||||
data class Book(
|
data class Book(
|
||||||
// 详情页Url(本地书源存储完整文件路径)
|
// 详情页Url(本地书源存储完整文件路径)
|
||||||
|
|||||||
@@ -262,15 +262,17 @@ fun BookshelfScreen(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
EmptyMessage(
|
if (!uiState.isInitialLoading) {
|
||||||
modifier = Modifier
|
EmptyMessage(
|
||||||
.fillMaxSize()
|
modifier = Modifier
|
||||||
.padding(
|
.fillMaxSize()
|
||||||
top = paddingValues.calculateTopPadding(),
|
.padding(
|
||||||
bottom = 120.dp
|
top = paddingValues.calculateTopPadding(),
|
||||||
),
|
bottom = 120.dp
|
||||||
messageResId = R.string.bookshelf_empty
|
),
|
||||||
)
|
messageResId = R.string.bookshelf_empty
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -1250,7 +1252,7 @@ fun BookshelfPage(
|
|||||||
buttonText = stringResource(R.string.global_search),
|
buttonText = stringResource(R.string.global_search),
|
||||||
onButtonClick = onGlobalSearch
|
onButtonClick = onGlobalSearch
|
||||||
)
|
)
|
||||||
} else {
|
} else if (!uiState.isInitialLoading) {
|
||||||
EmptyMessage(
|
EmptyMessage(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import kotlinx.collections.immutable.persistentSetOf
|
|||||||
|
|
||||||
@Stable
|
@Stable
|
||||||
data class BookshelfGroupSelectorState(
|
data class BookshelfGroupSelectorState(
|
||||||
|
val isInitialLoading: Boolean = true,
|
||||||
val groups: ImmutableList<BookGroupUi> = persistentListOf(),
|
val groups: ImmutableList<BookGroupUi> = persistentListOf(),
|
||||||
val selectedGroupIndex: Int = 0,
|
val selectedGroupIndex: Int = 0,
|
||||||
val selectedGroupId: Long = BookGroup.IdAll
|
val selectedGroupId: Long = BookGroup.IdAll
|
||||||
@@ -37,6 +38,7 @@ data class BookshelfUiState(
|
|||||||
override val searchKey: String = "",
|
override val searchKey: String = "",
|
||||||
override val isSearch: Boolean = false,
|
override val isSearch: Boolean = false,
|
||||||
override val isLoading: Boolean = false,
|
override val isLoading: Boolean = false,
|
||||||
|
val isInitialLoading: Boolean = true,
|
||||||
val groups: ImmutableList<BookGroupUi> = persistentListOf(),
|
val groups: ImmutableList<BookGroupUi> = persistentListOf(),
|
||||||
val allGroups: ImmutableList<BookGroupUi> = persistentListOf(),
|
val allGroups: ImmutableList<BookGroupUi> = persistentListOf(),
|
||||||
val groupPreviews: ImmutableMap<Long, ImmutableList<BookShelfItem>> = persistentMapOf(),
|
val groupPreviews: ImmutableMap<Long, ImmutableList<BookShelfItem>> = persistentMapOf(),
|
||||||
|
|||||||
@@ -77,10 +77,13 @@ import kotlinx.coroutines.flow.Flow
|
|||||||
import kotlinx.coroutines.flow.combine
|
import kotlinx.coroutines.flow.combine
|
||||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
import kotlinx.coroutines.flow.flowOf
|
import kotlinx.coroutines.flow.flowOf
|
||||||
|
import kotlinx.coroutines.flow.filter
|
||||||
import kotlinx.coroutines.flow.flatMapLatest
|
import kotlinx.coroutines.flow.flatMapLatest
|
||||||
import kotlinx.coroutines.flow.flow
|
import kotlinx.coroutines.flow.flow
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.flowOf
|
||||||
import kotlinx.coroutines.flow.flowOn
|
import kotlinx.coroutines.flow.flowOn
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
|
import kotlinx.coroutines.flow.onEach
|
||||||
import kotlinx.coroutines.flow.receiveAsFlow
|
import kotlinx.coroutines.flow.receiveAsFlow
|
||||||
import kotlinx.coroutines.flow.stateIn
|
import kotlinx.coroutines.flow.stateIn
|
||||||
import kotlinx.coroutines.isActive
|
import kotlinx.coroutines.isActive
|
||||||
@@ -117,6 +120,7 @@ class BookshelfViewModel(
|
|||||||
private val bookGroupStyleFlow = MutableStateFlow(BookshelfConfig.bookGroupStyle)
|
private val bookGroupStyleFlow = MutableStateFlow(BookshelfConfig.bookGroupStyle)
|
||||||
private val draggingBooksFlow = MutableStateFlow<List<BookShelfItem>?>(null)
|
private val draggingBooksFlow = MutableStateFlow<List<BookShelfItem>?>(null)
|
||||||
private val pendingSavedBooksFlow = MutableStateFlow<List<BookShelfItem>?>(null)
|
private val pendingSavedBooksFlow = MutableStateFlow<List<BookShelfItem>?>(null)
|
||||||
|
private val isInitialLoadingFlow = MutableStateFlow(true)
|
||||||
|
|
||||||
private data class BookshelfSortConfig(
|
private data class BookshelfSortConfig(
|
||||||
val sort: Int,
|
val sort: Int,
|
||||||
@@ -156,6 +160,7 @@ class BookshelfViewModel(
|
|||||||
val events = _eventChannel.receiveAsFlow()
|
val events = _eventChannel.receiveAsFlow()
|
||||||
|
|
||||||
val groupsFlow: StateFlow<List<BookGroup>> = bookGroupRepository.flowShow()
|
val groupsFlow: StateFlow<List<BookGroup>> = bookGroupRepository.flowShow()
|
||||||
|
.onEach { isInitialLoadingFlow.value = false }
|
||||||
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), emptyList())
|
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), emptyList())
|
||||||
|
|
||||||
val allGroupsFlow: StateFlow<List<BookGroup>> = bookGroupRepository.flowAll()
|
val allGroupsFlow: StateFlow<List<BookGroup>> = bookGroupRepository.flowAll()
|
||||||
@@ -363,18 +368,23 @@ class BookshelfViewModel(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val groupPreviewsStateFlow = MutableStateFlow(
|
||||||
|
GroupPreviewState(persistentMapOf(), persistentMapOf(), 0)
|
||||||
|
)
|
||||||
|
|
||||||
|
private val allGroupBooksStateFlow = MutableStateFlow<ImmutableMap<Long, ImmutableList<BookShelfItem>>>(
|
||||||
|
persistentMapOf()
|
||||||
|
)
|
||||||
|
|
||||||
private val dataStateFlow = combine(
|
private val dataStateFlow = combine(
|
||||||
combine(
|
booksFlow,
|
||||||
booksFlow,
|
groupsFlow,
|
||||||
groupsFlow,
|
allGroupsFlow,
|
||||||
allGroupsFlow,
|
groupPreviewsStateFlow,
|
||||||
groupPreviewsFlow,
|
internalStateFlow
|
||||||
internalStateFlow
|
) { books, groups, allGroups, previews, internal ->
|
||||||
) { books, groups, allGroups, previews, internal ->
|
BookshelfDataCore(books, groups, allGroups, previews, internal)
|
||||||
BookshelfDataCore(books, groups, allGroups, previews, internal)
|
}.combine(allGroupBooksStateFlow) { core, allGroupBooks ->
|
||||||
},
|
|
||||||
allGroupBooksImmutableFlow
|
|
||||||
) { core, allGroupBooks ->
|
|
||||||
BookshelfDataState(
|
BookshelfDataState(
|
||||||
books = core.books,
|
books = core.books,
|
||||||
groups = core.groups.map { it.toBookGroupUi() },
|
groups = core.groups.map { it.toBookGroupUi() },
|
||||||
@@ -405,8 +415,9 @@ class BookshelfViewModel(
|
|||||||
val uiState: StateFlow<BookshelfUiState> = combine(
|
val uiState: StateFlow<BookshelfUiState> = combine(
|
||||||
dataStateFlow,
|
dataStateFlow,
|
||||||
interactionStateFlow,
|
interactionStateFlow,
|
||||||
visibleBooksFlow
|
visibleBooksFlow,
|
||||||
) { data, interaction, filteredBooks ->
|
isInitialLoadingFlow
|
||||||
|
) { data, interaction, filteredBooks, isInitialLoading ->
|
||||||
val books = data.books
|
val books = data.books
|
||||||
val groups = data.groups
|
val groups = data.groups
|
||||||
val allGroups = data.allGroups
|
val allGroups = data.allGroups
|
||||||
@@ -429,6 +440,7 @@ class BookshelfViewModel(
|
|||||||
BookshelfUiState(
|
BookshelfUiState(
|
||||||
items = filteredBooks.toImmutableList(),
|
items = filteredBooks.toImmutableList(),
|
||||||
selectedIds = selectedIds.toImmutableSet(),
|
selectedIds = selectedIds.toImmutableSet(),
|
||||||
|
isInitialLoading = isInitialLoading,
|
||||||
groups = groups.toImmutableList(),
|
groups = groups.toImmutableList(),
|
||||||
allGroups = allGroups.toImmutableList(),
|
allGroups = allGroups.toImmutableList(),
|
||||||
groupPreviews = previews.previews,
|
groupPreviews = previews.previews,
|
||||||
@@ -485,8 +497,19 @@ class BookshelfViewModel(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BookshelfConfig.autoRefreshBook) {
|
viewModelScope.launch {
|
||||||
upAllBookToc()
|
groupPreviewsFlow.collect { groupPreviewsStateFlow.value = it }
|
||||||
|
}
|
||||||
|
viewModelScope.launch {
|
||||||
|
allGroupBooksImmutableFlow.collect { allGroupBooksStateFlow.value = it }
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModelScope.launch {
|
||||||
|
isInitialLoadingFlow.filter { !it }.collect {
|
||||||
|
if (BookshelfConfig.autoRefreshBook) {
|
||||||
|
upAllBookToc()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user