Skip to content

Commit

Permalink
adding selection to library screen and chapter screen
Browse files Browse the repository at this point in the history
  • Loading branch information
kazemcodes committed Apr 2, 2022
1 parent 51c0425 commit 7c9528b
Show file tree
Hide file tree
Showing 21 changed files with 370 additions and 70 deletions.
4 changes: 2 additions & 2 deletions .idea/deploymentTargetDropDown.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions buildSrc/src/main/kotlin/ProjectConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ object ProjectConfig {
const val minSdk = 23
const val targetSdk = 31
const val compileSdk = 31
const val versionName = "0.1.15"
const val versionCode = 16
const val versionName = "0.1.16"
const val versionCode = 17
const val applicationId = "ir.kazemcodes.infinityreader"
}
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,10 @@ interface LibraryBookDao {
@Query("SELECT sourceId FROM library GROUP BY sourceId ORDER BY COUNT(sourceId) DESC")
suspend fun findFavoriteSourceIds(): List<Long>

@Query("DELETE FROM library WHERE favorite = 0")
@Query("""
DELETE FROM library
WHERE favorite = 0
""")
suspend fun deleteExploredBooks()

@Query("UPDATE library SET tableId = 0 WHERE tableId != 0 AND favorite = 1")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import org.ireader.domain.feature_services.notification.Notifications.CHANNEL_DO
import org.ireader.domain.feature_services.notification.Notifications.ID_DOWNLOAD_CHAPTER_COMPLETE
import org.ireader.domain.feature_services.notification.Notifications.ID_DOWNLOAD_CHAPTER_ERROR
import org.ireader.domain.feature_services.notification.Notifications.ID_DOWNLOAD_CHAPTER_PROGRESS
import org.ireader.domain.models.entities.Chapter
import org.ireader.domain.models.entities.SavedDownload
import org.ireader.domain.repository.LocalBookRepository
import org.ireader.domain.repository.LocalChapterRepository
Expand All @@ -46,6 +47,8 @@ class DownloadService @AssistedInject constructor(
const val DOWNLOADER_SERVICE_NAME = "DOWNLOAD_SERVICE"
const val DOWNLOADER_BOOK_ID = "book_id"
const val DOWNLOADER_SOURCE_ID = "sourceId"
const val DOWNLOADER_Chapters_IDS = "chapterIds"
const val DOWNLOADER_BOOKS_IDS = "booksIds"
}


Expand All @@ -55,6 +58,8 @@ class DownloadService @AssistedInject constructor(

val bookId = inputData.getLong("book_id", 0)
val sourceId = inputData.getLong("sourceId", 0)
val downloadIds = inputData.getLongArray(DOWNLOADER_Chapters_IDS)?.distinct()
val booksIds = inputData.getLongArray(DOWNLOADER_BOOKS_IDS)?.distinct()
val bookResource = bookRepo.subscribeBookById(bookId).first()
?: throw IllegalArgumentException(
"Invalid bookId as argument: $bookId"
Expand All @@ -75,7 +80,22 @@ class DownloadService @AssistedInject constructor(

val source = extensions.get(sourceId)?.source

val chapters = chapterRepo.subscribeChaptersByBookId(bookId).first()
val chapters = mutableListOf<Chapter>()

if (booksIds?.isNotEmpty() == true) {
booksIds.forEach {
chapters.addAll(chapterRepo.findChaptersByBookId(it))
}
} else {
chapters.addAll(chapterRepo.findChaptersByBookId(bookId).filter {
if (downloadIds != null) {
it.id in downloadIds
} else {
true
}
})
}


val cancelDownloadIntent = WorkManager.getInstance(applicationContext)
.createCancelPendingIntent(id)
Expand Down Expand Up @@ -140,6 +160,7 @@ class DownloadService @AssistedInject constructor(
delay(1000)
}
}

} catch (e: Exception) {
Timber.e("getNotifications: Failed to download ${bookResource.title}")
notify(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,15 @@ import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.BookmarkBorder
import androidx.compose.material.icons.filled.Close
import androidx.compose.material.icons.filled.Done
import androidx.compose.material.icons.filled.GetApp
import androidx.compose.material.icons.filled.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
Expand All @@ -25,6 +23,7 @@ import androidx.compose.ui.draw.drawWithContent
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
Expand Down Expand Up @@ -53,6 +52,7 @@ fun ChapterDetailScreen(
navController: NavController = rememberNavController(),
) {
val book = vm.book
val context = LocalContext.current
val scrollState = rememberLazyListState()
val focusManager = LocalFocusManager.current
// LaunchedEffect(key1 = true) {
Expand Down Expand Up @@ -179,26 +179,55 @@ fun ChapterDetailScreen(
}
when {
vm.hasSelection -> {
Row(modifier = Modifier
.fillMaxWidth()
.height(60.dp)
.align(Alignment.BottomCenter)
.padding(8.dp)
.background(MaterialTheme.colors.background)
.border(width = 1.dp, color = MaterialTheme.colors.onBackground.copy(.4f)),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
Box(
modifier = Modifier
.fillMaxWidth()
.height(80.dp)
.align(Alignment.BottomCenter)
.padding(8.dp)
.background(MaterialTheme.colors.background)
.border(width = 1.dp,
color = MaterialTheme.colors.onBackground.copy(.1f))
.clickable(enabled = false) {},
) {
AppIconButton(imageVector = Icons.Default.GetApp,
title = "Download",
onClick = { /*TODO*/ })
AppIconButton(imageVector = Icons.Default.BookmarkBorder,
title = "Bookmark",
onClick = { /*TODO*/ })
AppIconButton(imageVector = Icons.Default.Done,
title = "Mark as read",
onClick = { /*TODO*/ })
Row(modifier = Modifier
.fillMaxSize(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
AppIconButton(imageVector = Icons.Default.GetApp,
title = "Download",
onClick = {
vm.downloadChapters(context = context)
vm.selection.clear()
})
AppIconButton(imageVector = Icons.Default.BookmarkBorder,
title = "Bookmark",
onClick = {
vm.insertChapters(vm.chapters.filter { it.id in vm.selection }
.map { it.copy(bookmark = !it.bookmark) })
vm.selection.clear()
})

AppIconButton(imageVector = if (vm.chapters.filter { it.read }
.map { it.id }
.containsAll(vm.selection)) Icons.Default.DoneOutline else Icons.Default.Done,
title = "Mark as read",
onClick = {
vm.insertChapters(vm.chapters.filter { it.id in vm.selection }
.map { it.copy(read = !it.read) })
vm.selection.clear()
})
AppIconButton(imageVector = Icons.Default.PlaylistAddCheck,
title = "Mark Previous as read",
onClick = {
vm.insertChapters(vm.chapters.filter { it.id <= vm.selection.maxOrNull() ?: 0 }
.map { it.copy(read = true) })
vm.selection.clear()
})
}
}

}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package org.ireader.presentation.feature_detail.presentation.chapter_detail.viewmodel

import android.content.Context
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.work.*
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
Expand All @@ -13,7 +15,10 @@ import kotlinx.coroutines.launch
import org.ireader.core.R
import org.ireader.core.utils.UiEvent
import org.ireader.core.utils.UiText
import org.ireader.domain.feature_services.downloaderService.DownloadService
import org.ireader.domain.feature_services.downloaderService.DownloadService.Companion.DOWNLOADER_Chapters_IDS
import org.ireader.domain.models.entities.Book
import org.ireader.domain.models.entities.Chapter
import org.ireader.domain.ui.NavigationArgs
import org.ireader.domain.use_cases.local.DeleteUseCase
import org.ireader.domain.use_cases.local.LocalGetChapterUseCase
Expand Down Expand Up @@ -127,6 +132,40 @@ class ChapterDetailViewModel @Inject constructor(
}
}

fun insertChapters(chapters: List<Chapter>) {
viewModelScope.launch(Dispatchers.IO) {
insertUseCases.insertChapters(chapters)
}
}

lateinit var work: OneTimeWorkRequest
fun downloadChapters(context: Context) {

book?.let { book ->
work =
OneTimeWorkRequestBuilder<DownloadService>().apply {
setInputData(
Data.Builder().apply {
putLong(DownloadService.DOWNLOADER_BOOK_ID,
book.id)
putLong(DownloadService.DOWNLOADER_SOURCE_ID,
book.sourceId)
putLongArray(DOWNLOADER_Chapters_IDS,
this@ChapterDetailViewModel.selection.toLongArray())
}.build()
)
addTag(DownloadService.DOWNLOADER_SERVICE_NAME)
}.build()
WorkManager.getInstance(context).enqueueUniqueWork(
DownloadService.DOWNLOADER_SERVICE_NAME.plus(
book.id + book.sourceId),
ExistingWorkPolicy.REPLACE,
work
)
}

}

suspend fun showSnackBar(message: UiText?) {
_eventFlow.emit(
UiEvent.ShowSnackbar(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ fun ExploreScreen(
navController = navController,
isLocal = false,
gridState = gridState,
onBookTap = { book ->
onClick = { book ->
navController.navigate(
route = BookDetailScreenSpec.buildRoute(sourceId = book.sourceId,
bookId = book.id)
Expand Down
Loading

0 comments on commit 7c9528b

Please sign in to comment.