Skip to content

Commit

Permalink
progress-banner (#163)
Browse files Browse the repository at this point in the history
* feat: banner showing updating status

* showing progress for updating

* showing progress for syncing & backup restoring too

* preferences for progress banner
  • Loading branch information
cuong-tran authored Jul 9, 2024
1 parent 0496c60 commit 050c661
Show file tree
Hide file tree
Showing 17 changed files with 170 additions and 40 deletions.
7 changes: 7 additions & 0 deletions app/src/main/java/eu/kanade/domain/sync/SyncPreferences.kt
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,11 @@ class SyncPreferences(
preferenceStore.getBoolean("sync_on_app_resume", false)
.set(syncTriggerOptions.syncOnAppResume)
}

// KMK -->
fun showSyncingProgressBanner() = preferenceStore.getBoolean(
Preference.appStateKey("pref_show_syncing_progress_banner_key"),
true,
)
// KMK <--
}
38 changes: 35 additions & 3 deletions app/src/main/java/eu/kanade/presentation/components/Banners.kt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ import androidx.compose.ui.util.fastMaxBy
import dev.icerock.moko.resources.StringResource
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.stringResource
import java.math.RoundingMode
import java.text.NumberFormat

val DownloadedOnlyBannerBackgroundColor
@Composable get() = MaterialTheme.colorScheme.tertiary
Expand All @@ -41,6 +43,15 @@ val IncognitoModeBannerBackgroundColor
val IndexingBannerBackgroundColor
@Composable get() = MaterialTheme.colorScheme.secondary

// KMK -->
val RestoringBannerBackgroundColor
@Composable get() = MaterialTheme.colorScheme.error
val SyncingBannerBackgroundColor
@Composable get() = MaterialTheme.colorScheme.secondary
val UpdatingBannerBackgroundColor
@Composable get() = MaterialTheme.colorScheme.tertiary
// KMK <--

@Composable
fun WarningBanner(
textRes: StringResource,
Expand All @@ -58,6 +69,13 @@ fun WarningBanner(
)
}

// KMK -->
private val percentFormatter = NumberFormat.getPercentInstance().apply {
roundingMode = RoundingMode.DOWN
maximumFractionDigits = 0
}
// KMK <--

@Composable
fun AppStateBanners(
downloadedOnlyMode: Boolean,
Expand All @@ -66,8 +84,12 @@ fun AppStateBanners(
// KMK -->
restoring: Boolean,
syncing: Boolean,
updating: Boolean,
// KMK <--
modifier: Modifier = Modifier,
// KMK -->
progress: Float? = null,
// KMK <--
) {
val density = LocalDensity.current
val mainInsets = WindowInsets.statusBars
Expand All @@ -76,7 +98,7 @@ fun AppStateBanners(
val indexingPlaceable = subcompose(0) {
AnimatedVisibility(
// KMK -->
visible = indexing || restoring || syncing,
visible = indexing || restoring || syncing || updating,
// KMK <--
enter = expandVertically(),
exit = shrinkVertically(),
Expand All @@ -85,8 +107,18 @@ fun AppStateBanners(
modifier = Modifier.windowInsetsPadding(mainInsets),
// KMK -->
text = when {
syncing -> stringResource(MR.strings.syncing_library)
restoring -> stringResource(MR.strings.restoring_backup)
updating -> progress?.let {
stringResource(
MR.strings.notification_updating_progress,
percentFormatter.format(it),
)
} ?: stringResource(MR.strings.updating_library)
syncing -> progress?.let {
stringResource(MR.strings.syncing_library) + " (${percentFormatter.format(it)})"
} ?: stringResource(MR.strings.syncing_library)
restoring -> progress?.let {
stringResource(MR.strings.restoring_backup) + " (${percentFormatter.format(it)})"
} ?: stringResource(MR.strings.restoring_backup)
else -> stringResource(MR.strings.download_notifier_cache_renewal)
},
// KMK <--
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ import tachiyomi.domain.backup.service.BackupPreferences
import tachiyomi.domain.library.service.LibraryPreferences
import tachiyomi.domain.storage.service.StoragePreferences
import tachiyomi.i18n.MR
import tachiyomi.i18n.kmk.KMR
import tachiyomi.i18n.sy.SYMR
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.collectAsState
Expand Down Expand Up @@ -274,6 +275,12 @@ object SettingsDataScreen : SearchableSettings {
stringResource(MR.strings.backup_info) + "\n\n" +
stringResource(MR.strings.last_auto_backup_info, relativeTimeSpanString(lastAutoBackup)),
),
// KMK -->
Preference.PreferenceItem.SwitchPreference(
pref = backupPreferences.showRestoringProgressBanner(),
title = stringResource(KMR.strings.pref_show_restoring_progress_banner),
),
// KMK <--
),
)
}
Expand Down Expand Up @@ -403,7 +410,16 @@ object SettingsDataScreen : SearchableSettings {

@Composable
private fun getAdditionalPreferences(syncPreferences: SyncPreferences): List<Preference> {
return listOf(getSyncNowPref(), getAutomaticSyncGroup(syncPreferences))
return listOf(
getSyncNowPref(),
getAutomaticSyncGroup(syncPreferences),
// KMK -->
Preference.PreferenceItem.SwitchPreference(
pref = syncPreferences.showSyncingProgressBanner(),
title = stringResource(KMR.strings.pref_show_syncing_progress_banner),
),
// KMK <--
)
}

@Composable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import tachiyomi.domain.library.service.LibraryPreferences.Companion.MANGA_NON_C
import tachiyomi.domain.library.service.LibraryPreferences.Companion.MANGA_NON_READ
import tachiyomi.domain.library.service.LibraryPreferences.Companion.MANGA_OUTSIDE_RELEASE_PERIOD
import tachiyomi.i18n.MR
import tachiyomi.i18n.kmk.KMR
import tachiyomi.i18n.sy.SYMR
import tachiyomi.presentation.core.i18n.pluralStringResource
import tachiyomi.presentation.core.i18n.stringResource
Expand Down Expand Up @@ -242,6 +243,12 @@ object SettingsLibraryScreen : SearchableSettings {
subtitle = stringResource(SYMR.strings.pref_library_mark_duplicate_chapters_summary),
),
// SY <--
// KMK -->
Preference.PreferenceItem.SwitchPreference(
pref = libraryPreferences.showUpdatingProgressBanner(),
title = stringResource(KMR.strings.pref_show_updating_progress_banner),
),
// KMK <--
),
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package eu.kanade.tachiyomi.data.backup.restore
package eu.kanade.tachiyomi.data

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
Expand All @@ -7,7 +7,7 @@ import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.stateIn

class BackupRestoreStatus {
open class BannerProgressStatus {
private val scope = CoroutineScope(Dispatchers.IO)

private val _isRunning = MutableStateFlow(false)
Expand All @@ -23,4 +23,14 @@ class BackupRestoreStatus {
suspend fun stop() {
_isRunning.emit(false)
}

val progress = MutableStateFlow(0f)

suspend fun updateProgress(progress: Float) {
this.progress.emit(progress)
}
}

class LibraryUpdateStatus : BannerProgressStatus()
class SyncStatus : BannerProgressStatus()
class BackupRestoreStatus : BannerProgressStatus()
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import androidx.core.app.NotificationCompat
import com.hippo.unifile.UniFile
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.core.security.SecurityPreferences
import eu.kanade.tachiyomi.data.BackupRestoreStatus
import eu.kanade.tachiyomi.data.notification.NotificationReceiver
import eu.kanade.tachiyomi.data.notification.Notifications
import eu.kanade.tachiyomi.util.storage.getUriCompat
Expand All @@ -16,6 +17,8 @@ import tachiyomi.core.common.i18n.pluralStringResource
import tachiyomi.core.common.i18n.stringResource
import tachiyomi.core.common.storage.displayablePath
import tachiyomi.i18n.MR
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy
import java.io.File
import java.util.concurrent.TimeUnit
Expand All @@ -24,6 +27,10 @@ class BackupNotifier(private val context: Context) {

private val preferences: SecurityPreferences by injectLazy()

// KMK -->
private val backupRestoreStatus: BackupRestoreStatus = Injekt.get()
// KMK <--

private val progressNotificationBuilder = context.notificationBuilder(
Notifications.CHANNEL_BACKUP_RESTORE_PROGRESS,
) {
Expand Down Expand Up @@ -87,7 +94,7 @@ class BackupNotifier(private val context: Context) {
}
}

fun showRestoreProgress(
suspend fun showRestoreProgress(
content: String = "",
progress: Int = 0,
maxAmount: Int = 100,
Expand All @@ -107,6 +114,9 @@ class BackupNotifier(private val context: Context) {

setProgress(maxAmount, progress, false)
setOnlyAlertOnce(true)
// KMK -->
backupRestoreStatus.updateProgress(progress.toFloat() / maxAmount)
// KMK <--

clearActions()
addAction(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import androidx.work.ForegroundInfo
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkerParameters
import androidx.work.workDataOf
import eu.kanade.tachiyomi.data.BackupRestoreStatus
import eu.kanade.tachiyomi.data.backup.BackupNotifier
import eu.kanade.tachiyomi.data.notification.Notifications
import eu.kanade.tachiyomi.util.system.cancelNotification
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import eu.kanade.domain.manga.model.toSManga
import eu.kanade.domain.sync.SyncPreferences
import eu.kanade.domain.track.model.toDbTrack
import eu.kanade.domain.track.model.toDomainTrack
import eu.kanade.tachiyomi.data.LibraryUpdateStatus
import eu.kanade.tachiyomi.data.cache.CoverCache
import eu.kanade.tachiyomi.data.download.DownloadManager
import eu.kanade.tachiyomi.data.notification.Notifications
Expand Down Expand Up @@ -134,6 +135,10 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet

private val notifier = LibraryUpdateNotifier(context)

// KMK -->
private val libraryUpdateStatus: LibraryUpdateStatus = Injekt.get()
// KMK <--

private var mangaToUpdate: List<LibraryManga> = mutableListOf()

override suspend fun doWork(): Result {
Expand All @@ -150,6 +155,10 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
}
}

// KMK -->
libraryUpdateStatus.start()
// KMK <--

setForegroundSafely()

val target = inputData.getString(KEY_TARGET)?.let { Target.valueOf(it) } ?: Target.CHAPTERS
Expand Down Expand Up @@ -187,6 +196,9 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
}
} finally {
notifier.cancelProgressNotification()
// KMK -->
libraryUpdateStatus.stop()
// KMK <--
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import coil3.transform.CircleCropTransformation
import eu.kanade.presentation.util.formatChapterNumber
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.core.security.SecurityPreferences
import eu.kanade.tachiyomi.data.LibraryUpdateStatus
import eu.kanade.tachiyomi.data.download.Downloader
import eu.kanade.tachiyomi.data.notification.NotificationHandler
import eu.kanade.tachiyomi.data.notification.NotificationReceiver
Expand Down Expand Up @@ -49,6 +50,9 @@ class LibraryUpdateNotifier(
private val securityPreferences: SecurityPreferences = Injekt.get(),
private val sourceManager: SourceManager = Injekt.get(),
) {
// KMK -->
private val libraryUpdateStatus: LibraryUpdateStatus = Injekt.get()
// KMK <--

private val percentFormatter = NumberFormat.getPercentInstance().apply {
roundingMode = RoundingMode.DOWN
Expand Down Expand Up @@ -90,7 +94,7 @@ class LibraryUpdateNotifier(
* @param current the current progress.
* @param total the total progress.
*/
fun showProgressNotification(manga: List<Manga>, current: Int, total: Int) {
suspend fun showProgressNotification(manga: List<Manga>, current: Int, total: Int) {
progressNotificationBuilder
.setContentTitle(
context.stringResource(
Expand All @@ -99,6 +103,10 @@ class LibraryUpdateNotifier(
),
)

// KMK -->
libraryUpdateStatus.updateProgress(current.toFloat() / total)
// KMK <--

if (!securityPreferences.hideNotificationContent().get()) {
val updatingText = manga.joinToString("\n") { it.title.chop(40) }
progressNotificationBuilder.setStyle(NotificationCompat.BigTextStyle().bigText(updatingText))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import androidx.work.WorkInfo
import androidx.work.WorkQuery
import androidx.work.WorkerParameters
import eu.kanade.domain.sync.SyncPreferences
import eu.kanade.tachiyomi.data.SyncStatus
import eu.kanade.tachiyomi.data.notification.Notifications
import eu.kanade.tachiyomi.util.system.cancelNotification
import eu.kanade.tachiyomi.util.system.isRunning
Expand Down
16 changes: 15 additions & 1 deletion app/src/main/java/eu/kanade/tachiyomi/data/sync/SyncNotifier.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,24 @@ import android.graphics.BitmapFactory
import androidx.core.app.NotificationCompat
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.core.security.SecurityPreferences
import eu.kanade.tachiyomi.data.SyncStatus
import eu.kanade.tachiyomi.data.notification.NotificationReceiver
import eu.kanade.tachiyomi.data.notification.Notifications
import eu.kanade.tachiyomi.util.system.cancelNotification
import eu.kanade.tachiyomi.util.system.notificationBuilder
import eu.kanade.tachiyomi.util.system.notify
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy

class SyncNotifier(private val context: Context) {

private val preferences: SecurityPreferences by injectLazy()

// KMK -->
private val syncStatus: SyncStatus = Injekt.get()
// KMK <--

private val progressNotificationBuilder = context.notificationBuilder(
Notifications.CHANNEL_BACKUP_RESTORE_PROGRESS,
) {
Expand All @@ -38,7 +45,11 @@ class SyncNotifier(private val context: Context) {
context.notify(id, build())
}

fun showSyncProgress(content: String = "", progress: Int = 0, maxAmount: Int = 100): NotificationCompat.Builder {
suspend fun showSyncProgress(
content: String = "",
progress: Int = 0,
maxAmount: Int = 100,
): NotificationCompat.Builder {
val builder = with(progressNotificationBuilder) {
setContentTitle(context.getString(R.string.syncing_library))

Expand All @@ -48,6 +59,9 @@ class SyncNotifier(private val context: Context) {

setProgress(maxAmount, progress, true)
setOnlyAlertOnce(true)
// KMK -->
syncStatus.updateProgress(progress.toFloat() / maxAmount)
// KMK <--

clearActions()
addAction(
Expand Down
26 changes: 0 additions & 26 deletions app/src/main/java/eu/kanade/tachiyomi/data/sync/SyncStatus.kt

This file was deleted.

Loading

0 comments on commit 050c661

Please sign in to comment.