[优化] 优化书架性能

This commit is contained in:
HapeLee committed 2026-03-25 01:35:40 +08:00
1 parent 32806e2e26
commit 25abbdaf1e
7 files changed
+188 -42

No files matched your search

@@ -12,6 +12,7 @@ import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookGroup import io.legado.app.data.entities.BookGroup
import io.legado.app.data.entities.BookSource import io.legado.app.data.entities.BookSource
import io.legado.app.help.book.isNotShelf import io.legado.app.help.book.isNotShelf
import io.legado.app.ui.main.bookshelf.BookShelfItem
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
@@ -51,6 +52,31 @@ interface BookDao {
@Query("SELECT * FROM books order by durChapterTime desc") @Query("SELECT * FROM books order by durChapterTime desc")
fun flowAll(): Flow<List<Book>> fun flowAll(): Flow<List<Book>>
@Query(
"""
SELECT
bookUrl,
name,
author,
coverUrl,
customCoverUrl,
durChapterTitle,
durChapterTime,
durChapterPos,
latestChapterTitle,
latestChapterTime,
totalChapterNum,
durChapterIndex,
type,
`group`,
`order`,
canUpdate
FROM books
ORDER BY durChapterTime DESC
"""
)
fun flowBookShelf(): Flow<List<BookShelfItem>>
@Query("SELECT * FROM books WHERE type & ${BookType.audio} > 0") @Query("SELECT * FROM books WHERE type & ${BookType.audio} > 0")
fun flowAudio(): Flow<List<Book>> fun flowAudio(): Flow<List<Book>>
@@ -32,9 +32,7 @@ import androidx.compose.ui.text.style.TextAlign
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 io.legado.app.R import io.legado.app.R
import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookGroup import io.legado.app.data.entities.BookGroup
import io.legado.app.help.book.isLocal
import io.legado.app.ui.config.bookshelfConfig.BookshelfConfig import io.legado.app.ui.config.bookshelfConfig.BookshelfConfig
import io.legado.app.ui.widget.components.cover.BookCover import io.legado.app.ui.widget.components.cover.BookCover
import io.legado.app.ui.widget.components.cover.BookCoverWithProgress import io.legado.app.ui.widget.components.cover.BookCoverWithProgress
@@ -197,7 +195,7 @@ fun BookshelfItem(
@Composable @Composable
fun BookGroupCover( fun BookGroupCover(
books: List<Book>, books: List<BookShelfItem>,
coverPath: String? = null, coverPath: String? = null,
modifier: Modifier = Modifier modifier: Modifier = Modifier
) { ) {
@@ -289,7 +287,7 @@ fun BookGroupCover(
@Composable @Composable
fun BookGroupItemGrid( fun BookGroupItemGrid(
group: BookGroup, group: BookGroup,
previewBooks: List<Book>, previewBooks: List<BookShelfItem>,
gridStyle: Int = 0, gridStyle: Int = 0,
titleSmallFont: Boolean = false, titleSmallFont: Boolean = false,
titleCenter: Boolean = true, titleCenter: Boolean = true,
@@ -318,7 +316,7 @@ fun BookGroupItemGrid(
@Composable @Composable
fun BookGroupItemList( fun BookGroupItemList(
group: BookGroup, group: BookGroup,
previewBooks: List<Book>, previewBooks: List<BookShelfItem>,
isCompact: Boolean = false, isCompact: Boolean = false,
titleSmallFont: Boolean = false, titleSmallFont: Boolean = false,
titleCenter: Boolean = true, titleCenter: Boolean = true,
@@ -348,7 +346,7 @@ fun BookGroupItemList(
@Composable @Composable
fun BookItem( fun BookItem(
book: Book, book: BookShelfItem,
layoutMode: Int, layoutMode: Int,
gridStyle: Int = 0, gridStyle: Int = 0,
isCompact: Boolean = false, isCompact: Boolean = false,
@@ -374,7 +372,7 @@ fun BookItem(
isUpdating = isUpdating, isUpdating = isUpdating,
modifier = modifier, modifier = modifier,
badgeText = if (BookshelfConfig.showUnread && unreadCount > 0) unreadCount.toString() else null, badgeText = if (BookshelfConfig.showUnread && unreadCount > 0) unreadCount.toString() else null,
showBadgeDot = !BookshelfConfig.showUnread && BookshelfConfig.showUnreadNew && unreadCount > 0 && book.lastCheckCount > 0 showBadgeDot = !BookshelfConfig.showUnread && BookshelfConfig.showUnreadNew && unreadCount > 0
) )
}, },
title = book.name, title = book.name,
@@ -0,0 +1,55 @@
package io.legado.app.ui.main.bookshelf
import io.legado.app.constant.BookType
import io.legado.app.data.entities.Book
import kotlin.math.max
data class BookShelfItem(
val bookUrl: String,
val name: String,
val author: String,
val coverUrl: String?,
val customCoverUrl: String?,
val durChapterTitle: String?,
val durChapterTime: Long,
val durChapterPos: Int,
val latestChapterTitle: String?,
val latestChapterTime: Long,
val totalChapterNum: Int,
val durChapterIndex: Int,
val type: Int,
val group: Long,
val order: Int,
val canUpdate: Boolean = true
) {
fun getDisplayCover() = if (customCoverUrl.isNullOrEmpty()) coverUrl else customCoverUrl
val isLocal: Boolean get() = (type and BookType.local) > 0
val isAudio: Boolean get() = (type and BookType.audio) > 0
val isImage: Boolean get() = (type and BookType.image) > 0
fun getUnreadChapterNum() = max(totalChapterNum - durChapterIndex - 1, 0)
}
fun Book.toBookShelfItem(): BookShelfItem {
return BookShelfItem(
bookUrl = bookUrl,
name = name,
author = author,
coverUrl = coverUrl,
customCoverUrl = customCoverUrl,
durChapterTitle = durChapterTitle,
durChapterTime = durChapterTime,
durChapterPos = durChapterPos,
latestChapterTitle = latestChapterTitle,
latestChapterTime = latestChapterTime,
totalChapterNum = totalChapterNum,
durChapterIndex = durChapterIndex,
type = type,
group = group,
order = order,
canUpdate = canUpdate
)
}
@@ -11,14 +11,19 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
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.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.items import androidx.compose.foundation.lazy.grid.items
import androidx.compose.foundation.lazy.grid.itemsIndexed import androidx.compose.foundation.lazy.grid.itemsIndexed
import androidx.compose.foundation.pager.HorizontalPager import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.FormatListBulleted
import androidx.compose.material.icons.filled.Check
import androidx.compose.material.icons.filled.Download import androidx.compose.material.icons.filled.Download
import androidx.compose.material.icons.filled.Edit import androidx.compose.material.icons.filled.Edit
import androidx.compose.material.icons.filled.FileOpen import androidx.compose.material.icons.filled.FileOpen
@@ -65,7 +70,6 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.Dialog
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.BaseRuleEvent import io.legado.app.base.BaseRuleEvent
import io.legado.app.data.entities.Book
import io.legado.app.ui.about.AppLogSheet import io.legado.app.ui.about.AppLogSheet
import io.legado.app.ui.book.cache.CacheActivity import io.legado.app.ui.book.cache.CacheActivity
import io.legado.app.ui.book.import.local.ImportBookActivity import io.legado.app.ui.book.import.local.ImportBookActivity
@@ -74,10 +78,12 @@ import io.legado.app.ui.book.manage.BookshelfManageActivity
import io.legado.app.ui.book.search.SearchActivity import io.legado.app.ui.book.search.SearchActivity
import io.legado.app.ui.config.bookshelfConfig.BookshelfConfig import io.legado.app.ui.config.bookshelfConfig.BookshelfConfig
import io.legado.app.ui.widget.components.GlassTopAppBarDefaults import io.legado.app.ui.widget.components.GlassTopAppBarDefaults
import io.legado.app.ui.widget.components.button.SmallOutlinedIconToggleButton
import io.legado.app.ui.widget.components.filePicker.FilePickerSheet import io.legado.app.ui.widget.components.filePicker.FilePickerSheet
import io.legado.app.ui.widget.components.importComponents.SourceInputDialog import io.legado.app.ui.widget.components.importComponents.SourceInputDialog
import io.legado.app.ui.widget.components.lazylist.FastScrollLazyVerticalGrid import io.legado.app.ui.widget.components.lazylist.FastScrollLazyVerticalGrid
import io.legado.app.ui.widget.components.list.ListScaffold import io.legado.app.ui.widget.components.list.ListScaffold
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenu
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenuItem import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenuItem
import io.legado.app.utils.readText import io.legado.app.utils.readText
import io.legado.app.utils.startActivity import io.legado.app.utils.startActivity
@@ -94,8 +100,8 @@ import org.koin.androidx.compose.koinViewModel
@Composable @Composable
fun BookshelfScreen( fun BookshelfScreen(
viewModel: BookshelfViewModel = koinViewModel(), viewModel: BookshelfViewModel = koinViewModel(),
onBookClick: (Book) -> Unit, onBookClick: (BookShelfItem) -> Unit,
onBookLongClick: (Book) -> Unit onBookLongClick: (BookShelfItem) -> Unit
) { ) {
val context = LocalContext.current val context = LocalContext.current
val uiState by viewModel.uiState.collectAsState() val uiState by viewModel.uiState.collectAsState()
@@ -107,6 +113,7 @@ fun BookshelfScreen(
var showConfigSheet by remember { mutableStateOf(false) } var showConfigSheet by remember { mutableStateOf(false) }
var showGroupManageSheet by remember { mutableStateOf(false) } var showGroupManageSheet by remember { mutableStateOf(false) }
var showLogSheet by remember { mutableStateOf(false) } var showLogSheet by remember { mutableStateOf(false) }
var showGroupMenu by remember { mutableStateOf(false) }
val clipboardManager = LocalClipboard.current val clipboardManager = LocalClipboard.current
val snackbarHostState = remember { SnackbarHostState() } val snackbarHostState = remember { SnackbarHostState() }
@@ -309,12 +316,17 @@ fun BookshelfScreen(
if (uiState.groups.isNotEmpty()) { if (uiState.groups.isNotEmpty()) {
val selectedTabIndex = val selectedTabIndex =
pagerState.currentPage.coerceIn(0, uiState.groups.size - 1) pagerState.currentPage.coerceIn(0, uiState.groups.size - 1)
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically
) {
PrimaryScrollableTabRow( PrimaryScrollableTabRow(
selectedTabIndex = selectedTabIndex, selectedTabIndex = selectedTabIndex,
edgePadding = 0.dp, edgePadding = 0.dp,
divider = { }, divider = { },
containerColor = GlassTopAppBarDefaults.containerColor(), containerColor = GlassTopAppBarDefaults.containerColor(),
minTabWidth = 0.dp minTabWidth = 0.dp,
modifier = Modifier.weight(1f)
) { ) {
uiState.groups.forEachIndexed { index, group -> uiState.groups.forEachIndexed { index, group ->
Tab( Tab(
@@ -334,6 +346,41 @@ fun BookshelfScreen(
) )
} }
} }
if (BookshelfConfig.shouldShowExpandButton) {
Box(modifier = Modifier.padding(end = 16.dp)) {
SmallOutlinedIconToggleButton(
checked = showGroupMenu,
onCheckedChange = { showGroupMenu = it },
icon = Icons.AutoMirrored.Filled.FormatListBulleted,
contentDescription = stringResource(R.string.group_manage)
)
RoundDropdownMenu(
expanded = showGroupMenu,
onDismissRequest = { showGroupMenu = false }
) { dismiss ->
uiState.groups.forEachIndexed { index, group ->
RoundDropdownMenuItem(
text = { Text(group.groupName) },
onClick = {
scope.launch { pagerState.animateScrollToPage(index) }
dismiss()
},
trailingIcon = {
if (selectedTabIndex == index) {
Icon(
Icons.Default.Check,
null,
modifier = Modifier.size(18.dp)
)
}
}
)
}
}
}
}
}
} }
} }
} else null } else null
@@ -533,12 +580,12 @@ fun BookshelfScreen(
@Composable @Composable
fun BookshelfPage( fun BookshelfPage(
paddingValues: PaddingValues, paddingValues: PaddingValues,
books: List<Book>, books: List<BookShelfItem>,
uiState: BookshelfUiState, uiState: BookshelfUiState,
bookshelfLayoutMode: Int, bookshelfLayoutMode: Int,
bookshelfLayoutGrid: Int, bookshelfLayoutGrid: Int,
onBookClick: (Book) -> Unit, onBookClick: (BookShelfItem) -> Unit,
onBookLongClick: (Book) -> Unit onBookLongClick: (BookShelfItem) -> Unit
) { ) {
FastScrollLazyVerticalGrid( FastScrollLazyVerticalGrid(
columns = GridCells.Fixed(bookshelfLayoutGrid.coerceAtLeast(1)), columns = GridCells.Fixed(bookshelfLayoutGrid.coerceAtLeast(1)),
@@ -1,18 +1,17 @@
package io.legado.app.ui.main.bookshelf package io.legado.app.ui.main.bookshelf
import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookGroup import io.legado.app.data.entities.BookGroup
import io.legado.app.ui.widget.components.list.ListUiState import io.legado.app.ui.widget.components.list.ListUiState
data class BookshelfUiState( data class BookshelfUiState(
override val items: List<Book> = emptyList(), override val items: List<BookShelfItem> = emptyList(),
override val selectedIds: Set<Any> = emptySet(), override val selectedIds: Set<Any> = emptySet(),
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 groups: List<BookGroup> = emptyList(), val groups: List<BookGroup> = emptyList(),
val groupPreviews: Map<Long, List<Book>> = emptyMap(), val groupPreviews: Map<Long, List<BookShelfItem>> = emptyMap(),
val selectedGroupIndex: Int = 0, val selectedGroupIndex: Int = 0,
val loadingText: String? = null, val loadingText: String? = null,
val updatingBooks: Set<String> = emptySet() val updatingBooks: Set<String> = emptySet()
) : ListUiState<Book> ) : ListUiState<BookShelfItem>
@@ -22,7 +22,6 @@ import io.legado.app.data.repository.UploadRepository
import io.legado.app.exception.NoStackTraceException import io.legado.app.exception.NoStackTraceException
import io.legado.app.help.book.BookHelp import io.legado.app.help.book.BookHelp
import io.legado.app.help.book.addType import io.legado.app.help.book.addType
import io.legado.app.help.book.isLocal
import io.legado.app.help.book.isUpError import io.legado.app.help.book.isUpError
import io.legado.app.help.book.removeType import io.legado.app.help.book.removeType
import io.legado.app.help.book.sync import io.legado.app.help.book.sync
@@ -123,13 +122,15 @@ class BookshelfViewModel(
val allGroupsFlow: StateFlow<List<BookGroup>> = bookGroupRepository.flowAll() val allGroupsFlow: StateFlow<List<BookGroup>> = bookGroupRepository.flowAll()
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), emptyList()) .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), emptyList())
private val allBooksFlow = appDb.bookDao.flowAll().flowOn(Dispatchers.Default) private val allBooksFlow = appDb.bookDao.flowBookShelf().flowOn(Dispatchers.Default)
@OptIn(ExperimentalCoroutinesApi::class) @OptIn(ExperimentalCoroutinesApi::class)
val booksFlow = combine(groupIdFlow, refreshTrigger) { groupId, _ -> groupId } val booksFlow = combine(groupIdFlow, refreshTrigger) { groupId, _ -> groupId }
.flatMapLatest { groupId -> .flatMapLatest { groupId ->
appDb.bookDao.flowByGroup(groupId).map { list -> appDb.bookDao.flowByGroup(groupId).map { list ->
sortBooks(list, groupsFlow.value.find { it.groupId == groupId }) sortBooks(
list.map { it.toBookShelfItem() },
groupsFlow.value.find { it.groupId == groupId })
} }
}.flowOn(Dispatchers.Default) }.flowOn(Dispatchers.Default)
@@ -269,7 +270,7 @@ class BookshelfViewModel(
upTocPool.close() upTocPool.close()
} }
private fun sortBooks(list: List<Book>, group: BookGroup?): List<Book> { private fun sortBooks(list: List<BookShelfItem>, group: BookGroup?): List<BookShelfItem> {
val bookSort = group?.getRealBookSort() ?: BookshelfConfig.bookshelfSort val bookSort = group?.getRealBookSort() ?: BookshelfConfig.bookshelfSort
val isDescending = BookshelfConfig.bookshelfSortOrder == 1 val isDescending = BookshelfConfig.bookshelfSortOrder == 1
@@ -304,7 +305,7 @@ class BookshelfViewModel(
} }
@OptIn(ExperimentalCoroutinesApi::class) @OptIn(ExperimentalCoroutinesApi::class)
fun getBooksFlow(groupId: Long): Flow<List<Book>> { fun getBooksFlow(groupId: Long): Flow<List<BookShelfItem>> {
return combine( return combine(
appDb.bookDao.flowByGroup(groupId), appDb.bookDao.flowByGroup(groupId),
searchKeyFlow, searchKeyFlow,
@@ -312,10 +313,11 @@ class BookshelfViewModel(
refreshTrigger refreshTrigger
) { books, searchKey, groups, _ -> ) { books, searchKey, groups, _ ->
val group = groups.find { it.groupId == groupId } val group = groups.find { it.groupId == groupId }
val bookshelfItems = books.map { it.toBookShelfItem() }
val filtered = if (searchKey.isEmpty()) { val filtered = if (searchKey.isEmpty()) {
books bookshelfItems
} else { } else {
books.filter { bookshelfItems.filter {
it.name.contains(searchKey, true) || it.author.contains(searchKey, true) it.name.contains(searchKey, true) || it.author.contains(searchKey, true)
} }
} }
@@ -349,13 +351,11 @@ class BookshelfViewModel(
} }
} }
fun upToc(books: List<Book>) { fun upToc(books: List<BookShelfItem>) {
execute(context = upTocPool) { execute(context = upTocPool) {
books.filter { val bookUrls = books.filter { !it.isLocal && it.canUpdate }.map { it.bookUrl }
!it.isLocal && it.canUpdate val fullBooks = bookUrls.mapNotNull { appDb.bookDao.getBook(it) }
}.let { addToWaitUp(fullBooks)
addToWaitUp(it)
}
} }
} }
@@ -562,17 +562,20 @@ class BookshelfViewModel(
} }
} }
fun exportToUri(uri: Uri, books: List<Book>) { fun exportToUri(uri: Uri, items: List<BookShelfItem>) {
execute { execute {
context.contentResolver.openOutputStream(uri)?.use { out -> context.contentResolver.openOutputStream(uri)?.use { out ->
val writer = JsonWriter(OutputStreamWriter(out, "UTF-8")) val writer = JsonWriter(OutputStreamWriter(out, "UTF-8"))
writer.setIndent(" ") writer.setIndent(" ")
writer.beginArray() writer.beginArray()
books.forEach { items.forEach {
val bookMap = hashMapOf<String, String?>() val bookMap = hashMapOf<String, String?>()
bookMap["name"] = it.name bookMap["name"] = it.name
bookMap["author"] = it.author bookMap["author"] = it.author
bookMap["intro"] = it.getDisplayIntro() // intro is not in BookShelfItem, fetch from DB if needed or skip
// For now, let's keep it simple and skip intro or fetch it
val fullBook = appDb.bookDao.getBook(it.bookUrl)
bookMap["intro"] = fullBook?.getDisplayIntro()
GSON.toJson(bookMap, bookMap::class.java, writer) GSON.toJson(bookMap, bookMap::class.java, writer)
} }
writer.endArray() writer.endArray()
@@ -585,14 +588,15 @@ class BookshelfViewModel(
} }
} }
fun uploadBookshelf(books: List<Book>) { fun uploadBookshelf(items: List<BookShelfItem>) {
execute { execute {
val json = withContext(Dispatchers.Default) { val json = withContext(Dispatchers.Default) {
val list = books.map { val list = items.map {
val bookMap = hashMapOf<String, String?>() val bookMap = hashMapOf<String, String?>()
bookMap["name"] = it.name bookMap["name"] = it.name
bookMap["author"] = it.author bookMap["author"] = it.author
bookMap["intro"] = it.getDisplayIntro() val fullBook = appDb.bookDao.getBook(it.bookUrl)
bookMap["intro"] = fullBook?.getDisplayIntro()
bookMap bookMap
} }
GSON.toJson(list) GSON.toJson(list)
@@ -619,9 +623,9 @@ class BookshelfViewModel(
} }
} }
fun exportBookshelf(books: List<Book>?, success: (file: File) -> Unit) { fun exportBookshelf(items: List<BookShelfItem>?, success: (file: File) -> Unit) {
execute { execute {
books?.let { items?.let {
val path = "${context.filesDir}/books.json" val path = "${context.filesDir}/books.json"
FileUtils.delete(path) FileUtils.delete(path)
val file = FileUtils.createFileWithReplace(path) val file = FileUtils.createFileWithReplace(path)
@@ -629,11 +633,12 @@ class BookshelfViewModel(
val writer = JsonWriter(OutputStreamWriter(out, "UTF-8")) val writer = JsonWriter(OutputStreamWriter(out, "UTF-8"))
writer.setIndent(" ") writer.setIndent(" ")
writer.beginArray() writer.beginArray()
books.forEach { items.forEach {
val bookMap = hashMapOf<String, String?>() val bookMap = hashMapOf<String, String?>()
bookMap["name"] = it.name bookMap["name"] = it.name
bookMap["author"] = it.author bookMap["author"] = it.author
bookMap["intro"] = it.getDisplayIntro() val fullBook = appDb.bookDao.getBook(it.bookUrl)
bookMap["intro"] = fullBook?.getDisplayIntro()
GSON.toJson(bookMap, bookMap::class.java, writer) GSON.toJson(bookMap, bookMap::class.java, writer)
} }
writer.endArray() writer.endArray()
@@ -50,6 +50,7 @@ import io.legado.app.help.config.AppConfig
import io.legado.app.ui.book.audio.AudioPlayActivity import io.legado.app.ui.book.audio.AudioPlayActivity
import io.legado.app.ui.book.manga.ReadMangaActivity import io.legado.app.ui.book.manga.ReadMangaActivity
import io.legado.app.ui.book.read.ReadBookActivity import io.legado.app.ui.book.read.ReadBookActivity
import io.legado.app.ui.main.bookshelf.BookShelfItem
import splitties.systemservices.clipboardManager import splitties.systemservices.clipboardManager
import splitties.systemservices.connectivityManager import splitties.systemservices.connectivityManager
import splitties.systemservices.uiModeManager import splitties.systemservices.uiModeManager
@@ -80,6 +81,22 @@ fun Context.startActivityForBook(
startActivity(intent) startActivity(intent)
} }
fun Context.startActivityForBook(
book: BookShelfItem,
configIntent: Intent.() -> Unit = {},
) {
val cls = when {
book.isAudio -> AudioPlayActivity::class.java
!book.isLocal && book.isImage && AppConfig.showMangaUi -> ReadMangaActivity::class.java
else -> ReadBookActivity::class.java
}
val intent = Intent(this, cls)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
intent.putExtra("bookUrl", book.bookUrl)
intent.apply(configIntent)
startActivity(intent)
}
inline fun <reified T : Service> Context.startService(configIntent: Intent.() -> Unit = {}) { inline fun <reified T : Service> Context.startService(configIntent: Intent.() -> Unit = {}) {
startService(Intent(this, T::class.java).apply(configIntent)) startService(Intent(this, T::class.java).apply(configIntent))
} }
@@ -464,4 +481,3 @@ fun Context.themeColor(attr: Int): Int {
typedValue.data typedValue.data
} }
} }