diff --git a/.idea/misc.xml b/.idea/misc.xml index 743dfecc1..881ae3168 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -44,6 +44,7 @@ + diff --git a/core/src/main/res/drawable/ic_update.xml b/core/src/main/res/drawable/ic_update.xml new file mode 100644 index 000000000..bbbc68778 --- /dev/null +++ b/core/src/main/res/drawable/ic_update.xml @@ -0,0 +1,9 @@ + + + diff --git a/data/src/main/java/org/ireader/data/local/dao/HistoryDao.kt b/data/src/main/java/org/ireader/data/local/dao/HistoryDao.kt index 7831c4909..3902a377b 100644 --- a/data/src/main/java/org/ireader/data/local/dao/HistoryDao.kt +++ b/data/src/main/java/org/ireader/data/local/dao/HistoryDao.kt @@ -18,7 +18,7 @@ interface HistoryDao { @Query("""SELECT history.*, library.title as bookTitle, library.sourceId, library.cover, library.favorite, chapter.title as chapterTitle, - date(ROUND(history.readAt / 1000), 'unixepoch', 'localtime') AS date + date(ROUND(history.readAt / 1000), 'unixepoch', 'localtime') AS date,chapter.number as chapterNumber FROM history JOIN library ON history.bookId = library.id JOIN chapter ON history.chapterId = chapter.id diff --git a/data/src/main/java/org/ireader/data/local/dao/LibraryBookDao.kt b/data/src/main/java/org/ireader/data/local/dao/LibraryBookDao.kt index 1aa578b96..b79d0af9f 100644 --- a/data/src/main/java/org/ireader/data/local/dao/LibraryBookDao.kt +++ b/data/src/main/java/org/ireader/data/local/dao/LibraryBookDao.kt @@ -14,31 +14,30 @@ interface LibraryBookDao { fun subscribeAllLocalBooks(): Flow> @RewriteQueriesToDropUnusedColumns - @Query("""SELECT library.*, MAX(chapter.readAt) as lastRead,COUNT(DISTINCT chapter.id) AS total_chapter, COUNT(chapter.read) as isRead, COUNT(length(chapter.content) > 10) AS total_download + @Query("""SELECT library.*, + MAX(chapter.readAt) as lastRead, + COUNT(DISTINCT chapter.id) AS totalChapters, + SUM(chapter.read) as isRead, + SUM(length(chapter.content) > 10) AS totalDownload FROM library LEFT JOIN chapter ON library.id = chapter.bookId GROUP BY library.id - HAVING library.favorite = 1 - AND (CASE WHEN :unread= 1 THEN lastRead is NULL ELSE 1 END) - AND (CASE WHEN :complete= 1 THEN total_chapter == isRead ELSE 1 END) - AND (CASE WHEN :downloaded= 1 THEN total_chapter == total_download ELSE 1 END) + HAVING library.favorite = 1 ORDER BY - CASE WHEN :isAsc = 1 AND :sortByAbs = 1 THEN library.title END ASC, - CASE WHEN :isAsc = 0 AND :sortByAbs = 1 THEN library.title END DESC, - CASE WHEN :isAsc = 1 AND :sortByDateAdded = 1 THEN library.dataAdded END ASC, - CASE WHEN :isAsc = 0 AND :sortByDateAdded = 1 THEN library.dataAdded END DESC, - CASE WHEN :isAsc = 1 AND :sortByLastRead = 1 THEN lastRead END ASC, - CASE WHEN :isAsc = 0 AND :sortByLastRead = 1 THEN lastRead END DESC, - CASE WHEN :isAsc = 1 AND :dateFetched = 1 THEN dateFetch END ASC, - CASE WHEN :isAsc = 0 AND :dateFetched = 1 THEN dateFetch END DESC, - CASE WHEN :isAsc = 1 AND :dateAdded = 1 THEN dataAdded END ASC, - CASE WHEN :isAsc = 0 AND :dateAdded = 1 THEN dataAdded END DESC, - CASE WHEN :isAsc = 1 AND :latestChapter = 1 THEN dateUpload END ASC, - CASE WHEN :isAsc = 0 AND :latestChapter = 1 THEN dateUpload END DESC, - CASE WHEN :isAsc = 1 AND :unread = 1 THEN lastRead END ASC, - CASE WHEN :isAsc = 0 AND :unread = 1 THEN lastRead END DESC, - CASE WHEN :isAsc = 1 AND :sortByTotalChapter = 1 THEN total_chapter END ASC, - CASE WHEN :isAsc = 0 AND :sortByTotalChapter = 1 THEN total_chapter END DESC + CASE WHEN :desc = 1 AND :sortByAbs = 1 THEN library.title END DESC, + CASE WHEN :desc = 0 AND :sortByAbs = 1 THEN library.title END ASC, + CASE WHEN :desc = 1 AND :sortByDateAdded = 1 THEN library.dataAdded END DESC, + CASE WHEN :desc = 0 AND :sortByDateAdded = 1 THEN library.dataAdded END ASC, + CASE WHEN :desc = 1 AND :sortByLastRead = 1 THEN lastRead END DESC, + CASE WHEN :desc = 0 AND :sortByLastRead = 1 THEN lastRead END ASC, + CASE WHEN :desc = 1 AND :dateFetched = 1 THEN dateFetch END DESC, + CASE WHEN :desc = 0 AND :dateFetched = 1 THEN dateFetch END ASC, + CASE WHEN :desc = 1 AND :dateAdded = 1 THEN dataAdded END DESC, + CASE WHEN :desc = 0 AND :dateAdded = 1 THEN dataAdded END ASC, + CASE WHEN :desc = 1 AND :sortByTotalChapter = 1 THEN totalChapters END DESC, + CASE WHEN :desc = 0 AND :sortByTotalChapter = 1 THEN totalChapters END ASC, + CASE WHEN :desc = 1 AND :lastChecked = 1 THEN lastUpdated END DESC, + CASE WHEN :desc = 0 AND :lastChecked = 1 THEN lastUpdated END ASC """) fun subscribeAllInLibraryBooks( sortByAbs: Boolean = false, @@ -47,14 +46,88 @@ interface LibraryBookDao { sortByTotalChapter: Boolean = false, dateFetched: Boolean = false, dateAdded: Boolean = false, - latestChapter: Boolean = false, - unread: Boolean = false, - downloaded: Boolean = false, - complete: Boolean = false, - isAsc: Boolean = false, + lastChecked: Boolean = false, + desc: Boolean = false, ): Flow> + @Query(""" + SELECT library.*, MAX(history.readAt) AS max + FROM library + LEFT JOIN chapter + ON library.id = chapter.bookId + LEFT JOIN history + ON chapter.id = history.chapterId + WHERE library.favorite = 1 + GROUP BY library.id + ORDER BY + CASE WHEN :desc = 1 THEN max END DESC, + CASE WHEN :desc = 0 THEN max END ASC +""") + fun subscribeLatestRead(desc: Boolean): Flow> + + @Query(""" + SELECT library.*, MAX(chapter.dateUpload) AS max + FROM library + LEFT JOIN chapter + ON library.id = chapter.bookId + GROUP BY library.id + ORDER by + CASE WHEN :desc = 1 THEN max END DESC, + CASE WHEN :desc = 0 THEN max END ASC +""") + fun subscribeLatestChapter(desc: Boolean): Flow> + + @Query(""" + SELECT library.*, SUM(CASE WHEN chapter.read == 0 THEN 1 ELSE 0 END) AS unread + FROM library + JOIN chapter + ON library.id = chapter.bookId + GROUP BY library.id + HAVING library.favorite = 1 + ORDER by + CASE WHEN :desc = 1 THEN COUNT(*) END DESC, + CASE WHEN :desc = 0 THEN COUNT(*) END ASC +""") + fun subscribeTotalChapter(desc: Boolean): Flow> + + @Query(""" + SELECT library.*, + SUM(CASE WHEN chapter.read == 0 THEN 1 ELSE 0 END) AS unread, + COUNT(*) AS total + FROM library + LEFT JOIN chapter + ON library.id = chapter.bookId + GROUP BY library.id + HAVING library.favorite = 1 AND unread == total +""") + suspend fun findUnreadBooks(): List + + @Query(""" + SELECT library.*, + SUM(length(chapter.content) > 10) as total_download, + COUNT(*) AS total + FROM library + LEFT JOIN chapter + ON library.id = chapter.bookId + GROUP BY library.id + HAVING library.favorite = 1 AND total_download == total +""") + suspend fun findCompletedBooks(): List + + @Query(""" + SELECT library.*, + SUM(CASE WHEN chapter.read == 0 THEN 1 ELSE 0 END) AS unread, + COUNT(*) AS total + FROM library + LEFT JOIN chapter + ON library.id = chapter.bookId + GROUP BY library.id + HAVING library.favorite = 1 AND unread == 0 +""") + suspend fun findDownloadedBooks(): List + + @Query("SELECT * FROM library WHERE favorite = 1") suspend fun findAllInLibraryBooks(): List diff --git a/data/src/main/java/org/ireader/data/repository/LocalBookRepositoryImpl.kt b/data/src/main/java/org/ireader/data/repository/LocalBookRepositoryImpl.kt index 5bd66ca28..6e27a7ae2 100644 --- a/data/src/main/java/org/ireader/data/repository/LocalBookRepositoryImpl.kt +++ b/data/src/main/java/org/ireader/data/repository/LocalBookRepositoryImpl.kt @@ -41,6 +41,17 @@ class LocalBookRepositoryImpl( } + override suspend fun findUnreadBooks(): List { + return bookDao.findUnreadBooks() + } + + override suspend fun findCompletedBooks(): List { + return bookDao.findCompletedBooks() + } + + override suspend fun findDownloadedBooks(): List { + return bookDao.findDownloadedBooks() + } override fun subscribeAllInLibrary( sortByAbs: Boolean, @@ -50,25 +61,27 @@ class LocalBookRepositoryImpl( sortByTotalChapters: Boolean, dateAdded: Boolean, latestChapter: Boolean, - unread: Boolean, - downloaded: Boolean, - complete: Boolean, - isAsc: Boolean, + lastChecked: Boolean, + desc: Boolean, ): Flow> { - return bookDao.subscribeAllInLibraryBooks( - sortByAbs = sortByAbs, - sortByDateAdded = sortByDateAdded, - sortByLastRead = sortByLastRead, - unread = unread, - isAsc = isAsc, - latestChapter = latestChapter, - downloaded = downloaded, - dateFetched = dateFetched, - dateAdded = dateAdded, - complete = complete, - sortByTotalChapter = sortByTotalChapters - ) + return when { + sortByLastRead -> bookDao.subscribeLatestRead(desc) + sortByTotalChapters -> bookDao.subscribeTotalChapter(desc) + latestChapter -> bookDao.subscribeLatestChapter(desc) + else -> { + bookDao.subscribeAllInLibraryBooks( + sortByAbs = sortByAbs, + sortByDateAdded = sortByDateAdded, + sortByLastRead = sortByLastRead, + desc = desc, + dateFetched = dateFetched, + dateAdded = dateAdded, + sortByTotalChapter = sortByTotalChapters, + lastChecked = lastChecked + ) + } + } } diff --git a/domain/src/main/java/org/ireader/domain/feature_services/LibraryUpdatesService.kt b/domain/src/main/java/org/ireader/domain/feature_services/LibraryUpdatesService.kt index 76a158c1c..c0ccf54d6 100644 --- a/domain/src/main/java/org/ireader/domain/feature_services/LibraryUpdatesService.kt +++ b/domain/src/main/java/org/ireader/domain/feature_services/LibraryUpdatesService.kt @@ -49,13 +49,14 @@ class LibraryUpdatesService @AssistedInject constructor( override suspend fun doWork(): Result { val libraryBooks = getBookUseCases.findAllInLibraryBooks() + var updatedBookSize = 0 val cancelIntent = WorkManager.getInstance(applicationContext) .createCancelPendingIntent(id) val builder = NotificationCompat.Builder(applicationContext, Notifications.CHANNEL_LIBRARY_PROGRESS).apply { setContentTitle("Checking Updates") - setSmallIcon(R.drawable.ic_downloading) + setSmallIcon(R.drawable.ic_update) setOnlyAlertOnce(true) priority = NotificationCompat.PRIORITY_LOW setAutoCancel(true) @@ -88,6 +89,9 @@ class LibraryUpdatesService @AssistedInject constructor( }, onError = {}) val newChapters = remoteChapters.filterNot { chapter -> chapter.title in chapters.map { it.title } } + if (newChapters.isNotEmpty()) { + updatedBookSize += 1 + } withContext(Dispatchers.IO) { insertUseCases.insertChapters(newChapters.map { it.copy( @@ -115,7 +119,7 @@ class LibraryUpdatesService @AssistedInject constructor( setContentTitle("Failed to Check Library Updates.") setSubText(e.localizedMessage) } - setSmallIcon(R.drawable.ic_downloading) + setSmallIcon(R.drawable.ic_update) priority = NotificationCompat.PRIORITY_DEFAULT setAutoCancel(true) }.build() @@ -137,8 +141,8 @@ class LibraryUpdatesService @AssistedInject constructor( Notifications.ID_LIBRARY_PROGRESS, NotificationCompat.Builder(applicationContext, Notifications.CHANNEL_DOWNLOADER_COMPLETE).apply { - setContentTitle("${libraryBooks.size} book was update successfully.") - setSmallIcon(R.drawable.ic_downloading) + setContentTitle("$updatedBookSize book was updated.") + setSmallIcon(R.drawable.ic_update) priority = NotificationCompat.PRIORITY_DEFAULT setSubText("It was Updated Successfully") setAutoCancel(true) diff --git a/domain/src/main/java/org/ireader/domain/feature_services/io/BookCover.kt b/domain/src/main/java/org/ireader/domain/feature_services/io/BookCover.kt index 6725ce7a3..1ee3538c5 100644 --- a/domain/src/main/java/org/ireader/domain/feature_services/io/BookCover.kt +++ b/domain/src/main/java/org/ireader/domain/feature_services/io/BookCover.kt @@ -36,5 +36,6 @@ data class HistoryWithRelations( val cover: String, val favorite: Boolean, val chapterTitle: String, + val chapterNumber: Int, val date: String, ) diff --git a/domain/src/main/java/org/ireader/domain/models/SortType.kt b/domain/src/main/java/org/ireader/domain/models/SortType.kt index dffca55a8..717f3a19d 100644 --- a/domain/src/main/java/org/ireader/domain/models/SortType.kt +++ b/domain/src/main/java/org/ireader/domain/models/SortType.kt @@ -4,11 +4,10 @@ sealed class SortType(val name: String, val index: Int) { object Alphabetically : SortType("Alphabetically", 0) object LastRead : SortType("Last Read", 1) object LastChecked : SortType("Last Checked", 2) - object Unread : SortType("Unread", 3) - object TotalChapters : SortType("Total Chapters", 4) - object LatestChapter : SortType("Latest Chapter", 5) - object DateFetched : SortType("Date Fetched", 6) - object DateAdded : SortType("Date Added", 7) + object TotalChapters : SortType("Total Chapters", 3) + object LatestChapter : SortType("Latest Chapter", 4) + object DateFetched : SortType("Date Fetched", 5) + object DateAdded : SortType("Date Added", 6) } sealed class FilterType(val name: String, val index: Int) { diff --git a/domain/src/main/java/org/ireader/domain/models/entities/Book.kt b/domain/src/main/java/org/ireader/domain/models/entities/Book.kt index 8372ea41b..4e4977986 100644 --- a/domain/src/main/java/org/ireader/domain/models/entities/Book.kt +++ b/domain/src/main/java/org/ireader/domain/models/entities/Book.kt @@ -118,4 +118,49 @@ fun MangaInfo.fromBookInfo(sourceId: Long): Book { description = this.description, author = this.author, ) +} + +data class BookWithInfo( + val id: Long = 0, + val title: String, + val lastRead: Long = 0, + val lastUpdated: Long = 0, + val unread: Boolean = false, + val totalChapters: Int = 0, + val dateUpload: Long = 0, + val dateFetch: Long = 0, + val dataAdded: Long = 0, + val sourceId: Long, + val totalDownload: Int, + val isRead: Int, + val link: String, + val status: Int = 0, + val cover: String = "", + val customCover: String = "", + val favorite: Boolean = false, + val tableId: Long = 0, + val author: String = "", + val description: String = "", + val genres: List = emptyList(), + val viewer: Int = 0, + val flags: Int = 0, +) + +fun BookWithInfo.toBook(): Book { + return Book( + id = this.id, + sourceId = sourceId, + customCover = this.cover, + cover = this.cover, + flags = 0, + link = this.link, + dataAdded = 0L, + lastUpdated = 0L, + favorite = false, + title = this.title, + status = this.status, + genres = this.genres, + description = this.description, + author = this.author, + ) } \ No newline at end of file diff --git a/domain/src/main/java/org/ireader/domain/repository/LocalBookRepository.kt b/domain/src/main/java/org/ireader/domain/repository/LocalBookRepository.kt index 683833d2c..7b2eeffcd 100644 --- a/domain/src/main/java/org/ireader/domain/repository/LocalBookRepository.kt +++ b/domain/src/main/java/org/ireader/domain/repository/LocalBookRepository.kt @@ -34,12 +34,15 @@ interface LocalBookRepository { sortByTotalChapters: Boolean, dateAdded: Boolean, latestChapter: Boolean, - unread: Boolean, - downloaded: Boolean, - complete: Boolean, - isAsc: Boolean, + lastChecked: Boolean, + desc: Boolean, ): Flow> + suspend fun findUnreadBooks(): List + + suspend fun findCompletedBooks(): List + + suspend fun findDownloadedBooks(): List fun getAllExploreBookPagingSource(): PagingSource diff --git a/domain/src/main/java/org/ireader/domain/use_cases/local/book_usecases/SubscribeInLibraryBooksPagingData.kt b/domain/src/main/java/org/ireader/domain/use_cases/local/book_usecases/SubscribeInLibraryBooksPagingData.kt index 059721f47..901281976 100644 --- a/domain/src/main/java/org/ireader/domain/use_cases/local/book_usecases/SubscribeInLibraryBooksPagingData.kt +++ b/domain/src/main/java/org/ireader/domain/use_cases/local/book_usecases/SubscribeInLibraryBooksPagingData.kt @@ -1,7 +1,9 @@ package org.ireader.domain.use_cases.local.book_usecases +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.withContext import org.ireader.domain.models.FilterType import org.ireader.domain.models.SortType import org.ireader.domain.models.entities.Book @@ -10,9 +12,8 @@ import javax.inject.Inject class SubscribeInLibraryBooks @Inject constructor(private val localBookRepository: LocalBookRepository) { operator fun invoke( - query: String, sortType: SortType, - isAsc: Boolean, + desc: Boolean, filter: List, ): Flow> = flow { localBookRepository.subscribeAllInLibrary( @@ -20,15 +21,54 @@ class SubscribeInLibraryBooks @Inject constructor(private val localBookRepositor sortByAbs = sortType == SortType.Alphabetically, sortByDateAdded = sortType == SortType.DateAdded, sortByTotalChapters = sortType == SortType.TotalChapters, - unread = FilterType.Unread in filter, - isAsc = isAsc, - complete = FilterType.Completed in filter, + desc = desc, dateAdded = sortType == SortType.DateAdded, dateFetched = sortType == SortType.DateFetched, - downloaded = FilterType.Downloaded in filter, latestChapter = sortType == SortType.LatestChapter, + lastChecked = sortType == SortType.LastChecked ).collect { books -> - emit(books.filter { it.title.contains(query, true) }) + val filteredBooks = mutableListOf() + + withContext(Dispatchers.IO) { + when { + filter.contains(FilterType.Unread) -> { + filteredBooks.addAll(localBookRepository.findUnreadBooks()) + } + filter.contains(FilterType.Downloaded) -> { + filteredBooks.addAll(localBookRepository.findCompletedBooks()) + } + filter.contains(FilterType.Completed) -> { + filteredBooks.addAll(localBookRepository.findDownloadedBooks()) + } + else -> {} + } + } + emit(books.filter { book -> + if (filter.isNotEmpty()) { + book in filteredBooks + } else { + true + } + }) + + +// if (filter.isNotEmpty()) { +// emit(books.filter { it.title.contains(query, true) }.filter { it in filteredBooks }) +// +// } else { +// emit(books.filter { it.title.contains(query, true) }) +// } + +// when(isAsc) { +// true -> { +// when (sortType) { +// SortType.Alphabetically -> this.sortedBy { it.title } +// SortType.DateAdded -> this.sortedBy { it.dataAdded } +// else -> {} +// } +// } +// else -> {} +// } } } } diff --git a/domain/src/main/java/org/ireader/domain/use_cases/preferences/reader_preferences/OrientationUseCase.kt b/domain/src/main/java/org/ireader/domain/use_cases/preferences/reader_preferences/OrientationUseCase.kt index 9c0906d33..a6599c1fb 100644 --- a/domain/src/main/java/org/ireader/domain/use_cases/preferences/reader_preferences/OrientationUseCase.kt +++ b/domain/src/main/java/org/ireader/domain/use_cases/preferences/reader_preferences/OrientationUseCase.kt @@ -45,18 +45,15 @@ fun mapSortType(input: Int): SortType { SortType.LastChecked } 3 -> { - SortType.Unread - } - 4 -> { SortType.TotalChapters } - 5 -> { + 4 -> { SortType.LatestChapter } - 6 -> { + 5 -> { SortType.DateFetched } - 7 -> { + 6 -> { SortType.DateAdded } else -> { diff --git a/presentation/src/main/java/org/ireader/presentation/feature_history/HistoryItem.kt b/presentation/src/main/java/org/ireader/presentation/feature_history/HistoryItem.kt index e82bf6080..76d12641a 100644 --- a/presentation/src/main/java/org/ireader/presentation/feature_history/HistoryItem.kt +++ b/presentation/src/main/java/org/ireader/presentation/feature_history/HistoryItem.kt @@ -13,7 +13,6 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp -import org.ireader.core.utils.convertLongToTime import org.ireader.domain.feature_services.io.HistoryWithRelations import org.ireader.domain.feature_services.io.coil.rememberBookCover @@ -52,9 +51,11 @@ fun HistoryItem( ) BookListItemSubtitle( - text = "Ch. ${history.chapterTitle} - ${ - convertLongToTime(history.readAt, "HH:mm") - }" + text = if (history.chapterNumber != -1) { + "Ch. ${history.chapterNumber}" + } else { + history.chapterTitle + } ) } IconButton(onClick = { onClickDelete(history) }) { diff --git a/presentation/src/main/java/org/ireader/presentation/feature_library/presentation/LibraryScreen.kt b/presentation/src/main/java/org/ireader/presentation/feature_library/presentation/LibraryScreen.kt index 87e82ef5c..c8c2516dc 100644 --- a/presentation/src/main/java/org/ireader/presentation/feature_library/presentation/LibraryScreen.kt +++ b/presentation/src/main/java/org/ireader/presentation/feature_library/presentation/LibraryScreen.kt @@ -72,7 +72,8 @@ fun LibraryScreen( Column(modifier = Modifier .fillMaxSize() ) { - LibraryScreenTopBar(navController = navController, + LibraryScreenTopBar( + navController = navController, vm = vm, coroutineScope = coroutineScope, bottomSheetState = bottomSheetState) diff --git a/presentation/src/main/java/org/ireader/presentation/feature_library/presentation/LibraryScreenTopBar.kt b/presentation/src/main/java/org/ireader/presentation/feature_library/presentation/LibraryScreenTopBar.kt index c5f0b864a..e57108676 100644 --- a/presentation/src/main/java/org/ireader/presentation/feature_library/presentation/LibraryScreenTopBar.kt +++ b/presentation/src/main/java/org/ireader/presentation/feature_library/presentation/LibraryScreenTopBar.kt @@ -3,11 +3,9 @@ package org.ireader.presentation.feature_library.presentation import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.ModalBottomSheetState import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.ArrowBack -import androidx.compose.material.icons.filled.Close -import androidx.compose.material.icons.filled.Search -import androidx.compose.material.icons.filled.Sort +import androidx.compose.material.icons.filled.* import androidx.compose.runtime.Composable +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalFocusManager import androidx.navigation.NavController import kotlinx.coroutines.CoroutineScope @@ -31,6 +29,7 @@ fun LibraryScreenTopBar( bottomSheetState: ModalBottomSheetState, ) { val focusManager = LocalFocusManager.current + val context = LocalContext.current Toolbar( title = { @@ -63,6 +62,13 @@ fun LibraryScreenTopBar( }, ) } + AppIconButton( + imageVector = Icons.Default.Refresh, + title = "Refresh", + onClick = { + vm.refreshUpdate(context = context) + }, + ) AppIconButton( imageVector = Icons.Default.Sort, title = "Filter", diff --git a/presentation/src/main/java/org/ireader/presentation/feature_library/presentation/components/FilterScreen.kt b/presentation/src/main/java/org/ireader/presentation/feature_library/presentation/components/FilterScreen.kt index 29a2bc070..1edea68e8 100644 --- a/presentation/src/main/java/org/ireader/presentation/feature_library/presentation/components/FilterScreen.kt +++ b/presentation/src/main/java/org/ireader/presentation/feature_library/presentation/components/FilterScreen.kt @@ -24,8 +24,8 @@ fun FilterScreen(viewModel: LibraryViewModel) { verticalArrangement = Arrangement.Top) { val items = listOf( FilterItem("Unread", FilterType.Unread), - FilterItem("Complete", FilterType.Completed), - FilterItem("Download", FilterType.Downloaded), + FilterItem("Completed", FilterType.Completed), + FilterItem("Downloaded", FilterType.Downloaded), ) items.forEach { filter -> CheckBoxWithText(filter.name, diff --git a/presentation/src/main/java/org/ireader/presentation/feature_library/presentation/components/SortScreen.kt b/presentation/src/main/java/org/ireader/presentation/feature_library/presentation/components/SortScreen.kt index bc89a4841..99dbfaa2b 100644 --- a/presentation/src/main/java/org/ireader/presentation/feature_library/presentation/components/SortScreen.kt +++ b/presentation/src/main/java/org/ireader/presentation/feature_library/presentation/components/SortScreen.kt @@ -20,7 +20,6 @@ fun SortScreen(viewModel: LibraryViewModel) { SortType.Alphabetically, SortType.LastRead, SortType.LastChecked, - SortType.Unread, SortType.TotalChapters, SortType.LatestChapter, SortType.DateFetched, @@ -41,7 +40,7 @@ fun SortScreen(viewModel: LibraryViewModel) { items.forEach { item -> IconWithText(item.name, - if (viewModel.isSortAcs) Icons.Default.ArrowUpward else Icons.Default.ArrowDownward, + if (viewModel.desc) Icons.Default.ArrowDownward else Icons.Default.ArrowUpward, viewModel.sortType == item, onClick = { viewModel.changeSortIndex(item) diff --git a/presentation/src/main/java/org/ireader/presentation/feature_library/presentation/viewmodel/LibraryScreenState.kt b/presentation/src/main/java/org/ireader/presentation/feature_library/presentation/viewmodel/LibraryScreenState.kt index b33693614..5cea52496 100644 --- a/presentation/src/main/java/org/ireader/presentation/feature_library/presentation/viewmodel/LibraryScreenState.kt +++ b/presentation/src/main/java/org/ireader/presentation/feature_library/presentation/viewmodel/LibraryScreenState.kt @@ -23,7 +23,7 @@ interface LibraryState { var inSearchMode: Boolean var searchQuery: String var sortType: SortType - var isSortAcs: Boolean + var desc: Boolean var filters: SnapshotStateList var currentScrollState: Int var histories: List @@ -39,7 +39,7 @@ open class LibraryStateImpl @Inject constructor() : LibraryState { override var inSearchMode by mutableStateOf(false) override var searchQuery by mutableStateOf("") override var sortType by mutableStateOf(SortType.LastRead) - override var isSortAcs by mutableStateOf(false) + override var desc by mutableStateOf(false) override var filters: SnapshotStateList = mutableStateListOf() override var currentScrollState by mutableStateOf(0) override var histories by mutableStateOf>(emptyList()) diff --git a/presentation/src/main/java/org/ireader/presentation/feature_library/presentation/viewmodel/LibraryViewModel.kt b/presentation/src/main/java/org/ireader/presentation/feature_library/presentation/viewmodel/LibraryViewModel.kt index c47f1554b..b7f31288c 100644 --- a/presentation/src/main/java/org/ireader/presentation/feature_library/presentation/viewmodel/LibraryViewModel.kt +++ b/presentation/src/main/java/org/ireader/presentation/feature_library/presentation/viewmodel/LibraryViewModel.kt @@ -1,11 +1,18 @@ package org.ireader.presentation.feature_library.presentation.viewmodel +import android.content.Context import androidx.lifecycle.viewModelScope +import androidx.work.ExistingWorkPolicy +import androidx.work.OneTimeWorkRequest +import androidx.work.OneTimeWorkRequestBuilder +import androidx.work.WorkManager import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.launch import org.ireader.core_ui.viewmodel.BaseViewModel +import org.ireader.domain.feature_services.LibraryUpdatesService import org.ireader.domain.models.DisplayMode import org.ireader.domain.models.FilterType import org.ireader.domain.models.SortType @@ -70,12 +77,11 @@ class LibraryViewModel @Inject constructor( getBooksJob?.cancel() getBooksJob = viewModelScope.launch { localGetBookUseCases.SubscribeInLibraryBooks( - query = searchQuery, sortType, - isAsc = isSortAcs, + desc = desc, filters - ).collect { - books = it + ).collectLatest { + books = it.filter { it.title.contains(searchQuery, true) } } } } @@ -107,7 +113,7 @@ class LibraryViewModel @Inject constructor( fun changeSortIndex(sortType: SortType) { this.sortType = sortType if (sortType == sortType) { - this.isSortAcs = !isSortAcs + this.desc = !desc } saveSortType(sortType) getLibraryBooks() @@ -119,13 +125,11 @@ class LibraryViewModel @Inject constructor( fun addFilters(filterType: FilterType) { this.filters.add(filterType) - getLibraryBooks() } fun removeFilters(filterType: FilterType) { this.filters.remove(filterType) - getLibraryBooks() } @@ -135,4 +139,17 @@ class LibraryViewModel @Inject constructor( this.searchQuery = "" getLibraryBooks() } + + lateinit var work: OneTimeWorkRequest + fun refreshUpdate(context: Context) { + work = + OneTimeWorkRequestBuilder().apply { + addTag(LibraryUpdatesService.LibraryUpdateTag) + }.build() + WorkManager.getInstance(context).enqueueUniqueWork( + LibraryUpdatesService.LibraryUpdateTag, + ExistingWorkPolicy.REPLACE, + work + ) + } } \ No newline at end of file