add option to automatically show completion dialog

This commit is contained in:
AmirHossein Abdolmotallebi 2024-11-21 14:30:50 +03:30
parent d95511accb
commit a9d49b09f4
4 changed files with 61 additions and 13 deletions

View File

@ -106,6 +106,17 @@ fun useSparseFileAllocation(appRepository: AppRepository): BooleanConfigurable {
)
}
fun showDownloadFinishWindow(settingsStorage: AppSettingsStorage): BooleanConfigurable {
return BooleanConfigurable(
title = Res.string.settings_show_completion_dialog.asStringSource(),
description = Res.string.settings_show_completion_dialog_description.asStringSource(),
backedBy = settingsStorage.showCompletionDialog,
describe = {
(if (it) Res.string.enabled else Res.string.disabled).asStringSource()
},
)
}
fun speedLimitConfig(appRepository: AppRepository): SpeedLimitConfigurable {
return SpeedLimitConfigurable(
title = Res.string.settings_global_speed_limiter.asStringSource(),
@ -374,8 +385,9 @@ class SettingsComponent(
speedLimitConfig(appRepository),
threadCountConfig(appRepository),
dynamicPartDownloadConfig(appRepository),
showDownloadFinishWindow(appSettings),
useServerLastModified(appRepository),
useSparseFileAllocation(appRepository)
useSparseFileAllocation(appRepository),
)
}
}

View File

@ -7,6 +7,8 @@ import com.abdownloadmanager.desktop.utils.*
import com.abdownloadmanager.desktop.utils.mvi.ContainsEffects
import com.abdownloadmanager.desktop.utils.mvi.supportEffects
import arrow.optics.copy
import com.abdownloadmanager.desktop.pages.settings.configurable.BooleanConfigurable
import com.abdownloadmanager.desktop.storage.AppSettingsStorage
import com.abdownloadmanager.desktop.storage.PageStatesStorage
import com.abdownloadmanager.resources.Res
import com.abdownloadmanager.utils.FileIconProvider
@ -19,7 +21,9 @@ import ir.amirab.downloader.monitor.*
import ir.amirab.util.compose.StringSource
import ir.amirab.util.compose.asStringSource
import ir.amirab.util.compose.asStringSourceWithARgs
import kotlinx.coroutines.delay
import ir.amirab.util.flow.combineStateFlows
import ir.amirab.util.flow.mapStateFlow
import ir.amirab.util.flow.mapTwoWayStateFlow
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
@ -49,6 +53,7 @@ class SingleDownloadComponent(
ContainsEffects<SingleDownloadEffects> by supportEffects(),
KoinComponent {
private val downloadSystem: DownloadSystem by inject()
private val appSettings: AppSettingsStorage by inject()
val fileIconProvider: FileIconProvider by inject()
private val singleDownloadPageStateToPersist by lazy {
get<PageStatesStorage>().downloadPage
@ -57,9 +62,17 @@ class SingleDownloadComponent(
private val downloadManager: DownloadManager = downloadSystem.downloadManager
val itemStateFlow = MutableStateFlow<IDownloadItemState?>(null)
private val globalShowCompletionDialog: StateFlow<Boolean> = appSettings.showCompletionDialog
private val itemShouldShowCompletionDialog: MutableStateFlow<Boolean?> = MutableStateFlow(null as Boolean?)
private val shouldShowCompletionDialog = combineStateFlows(
globalShowCompletionDialog,
itemShouldShowCompletionDialog,
) { global, item ->
item ?: global
}
private fun shouldShowCompletionDialog(): Boolean {
// TODO implement an option to allow user disable this
return true
return shouldShowCompletionDialog.value
}
init {
@ -74,6 +87,7 @@ class SingleDownloadComponent(
if (shouldShowCompletionDialog()) {
itemStateFlow.value = item
} else {
itemStateFlow.value = null
close()
}
} else {
@ -270,6 +284,21 @@ class SingleDownloadComponent(
val settings by lazy {
listOf(
BooleanConfigurable(
title = Res.string.download_item_settings_show_completion_dialog.asStringSource(),
description = Res.string.download_item_settings_show_completion_dialog_description.asStringSource(),
backedBy = itemShouldShowCompletionDialog.mapTwoWayStateFlow(
map = {
it ?: globalShowCompletionDialog.value
},
unMap = { it }
),
describe = {
(if (it) Res.string.enabled
else Res.string.enabled)
.asStringSource()
},
),
IntConfigurable(
title = Res.string.download_item_settings_thread_count.asStringSource(),
description = Res.string.download_item_settings_thread_count_description.asStringSource(),

View File

@ -5,13 +5,9 @@ import androidx.datastore.core.DataStore
import arrow.optics.Lens
import arrow.optics.optics
import ir.amirab.util.compose.localizationmanager.LanguageStorage
import ir.amirab.util.config.booleanKeyOf
import ir.amirab.util.config.intKeyOf
import ir.amirab.util.config.longKeyOf
import ir.amirab.util.config.stringKeyOf
import ir.amirab.util.config.MapConfig
import kotlinx.coroutines.flow.MutableStateFlow
import ir.amirab.util.config.*
import kotlinx.serialization.Serializable
import org.koin.core.component.KoinComponent
import java.io.File
@optics
@ -25,6 +21,7 @@ data class AppSettingsModel(
val useServerLastModifiedTime: Boolean = false,
val useSparseFileAllocation: Boolean = true,
val useAverageSpeed: Boolean = true,
val showCompletionDialog: Boolean = true,
val speedLimit: Long = 0,
val autoStartOnBoot: Boolean = true,
val notificationSound: Boolean = true,
@ -38,7 +35,7 @@ data class AppSettingsModel(
val default: AppSettingsModel get() = AppSettingsModel()
}
object ConfigLens : Lens<MapConfig, AppSettingsModel> {
object ConfigLens : Lens<MapConfig, AppSettingsModel>, KoinComponent {
object Keys {
val theme = stringKeyOf("theme")
val language = stringKeyOf("language")
@ -48,6 +45,7 @@ data class AppSettingsModel(
val useServerLastModifiedTime = booleanKeyOf("useServerLastModifiedTime")
val useSparseFileAllocation = booleanKeyOf("useSparseFileAllocation")
val useAverageSpeed = booleanKeyOf("useAverageSpeed")
val showCompletionDialog = booleanKeyOf("showCompletionDialog")
val speedLimit = longKeyOf("speedLimit")
val autoStartOnBoot = booleanKeyOf("autoStartOnBoot")
val notificationSound = booleanKeyOf("notificationSound")
@ -66,15 +64,18 @@ data class AppSettingsModel(
mergeTopBarWithTitleBar = source.get(Keys.mergeTopBarWithTitleBar) ?: default.mergeTopBarWithTitleBar,
threadCount = source.get(Keys.threadCount) ?: default.threadCount,
dynamicPartCreation = source.get(Keys.dynamicPartCreation) ?: default.dynamicPartCreation,
useServerLastModifiedTime = source.get(Keys.useServerLastModifiedTime) ?: default.useServerLastModifiedTime,
useServerLastModifiedTime = source.get(Keys.useServerLastModifiedTime)
?: default.useServerLastModifiedTime,
useSparseFileAllocation = source.get(Keys.useSparseFileAllocation) ?: default.useSparseFileAllocation,
useAverageSpeed = source.get(Keys.useAverageSpeed) ?: default.useAverageSpeed,
showCompletionDialog = source.get(Keys.showCompletionDialog)
?: default.showCompletionDialog,
speedLimit = source.get(Keys.speedLimit) ?: default.speedLimit,
autoStartOnBoot = source.get(Keys.autoStartOnBoot) ?: default.autoStartOnBoot,
notificationSound = source.get(Keys.notificationSound) ?: default.notificationSound,
defaultDownloadFolder = source.get(Keys.defaultDownloadFolder) ?: default.defaultDownloadFolder,
browserIntegrationEnabled = source.get(Keys.browserIntegrationEnabled)
?: default.browserIntegrationEnabled,
?: default.browserIntegrationEnabled,
browserIntegrationPort = source.get(Keys.browserIntegrationPort) ?: default.browserIntegrationPort,
)
}
@ -89,6 +90,7 @@ data class AppSettingsModel(
put(Keys.useServerLastModifiedTime, focus.useServerLastModifiedTime)
put(Keys.useSparseFileAllocation, focus.useSparseFileAllocation)
put(Keys.useAverageSpeed, focus.useAverageSpeed)
put(Keys.showCompletionDialog, focus.showCompletionDialog)
put(Keys.speedLimit, focus.speedLimit)
put(Keys.autoStartOnBoot, focus.autoStartOnBoot)
put(Keys.notificationSound, focus.notificationSound)
@ -113,6 +115,7 @@ class AppSettingsStorage(
val useServerLastModifiedTime = from(AppSettingsModel.useServerLastModifiedTime)
val useSparseFileAllocation = from(AppSettingsModel.useSparseFileAllocation)
val useAverageSpeed = from(AppSettingsModel.useAverageSpeed)
val showCompletionDialog = from(AppSettingsModel.showCompletionDialog)
val speedLimit = from(AppSettingsModel.speedLimit)
val autoStartOnBoot = from(AppSettingsModel.autoStartOnBoot)
val notificationSound = from(AppSettingsModel.notificationSound)

View File

@ -206,8 +206,12 @@ settings_browser_integration_server_port_description=Port for browser integratio
settings_browser_integration_server_port_describe=App will listen to port {{port}}
settings_dynamic_part_creation=Dynamic part creation
settings_dynamic_part_creation_description=When a part is finished create another part by splitting other parts to improve download speed
settings_show_completion_dialog=Show Download Completion dialog
settings_show_completion_dialog_description=Automatically show "Download Completion" dialog when a download finished
download_item_settings_speed_limit=Speed Limit
download_item_settings_speed_limit_description=Limit download speed for this item
download_item_settings_show_completion_dialog=Show Completion dialog
download_item_settings_show_completion_dialog_description=Automatically Show the "Download Completion" dialog when this download is finished.
download_item_settings_thread_count=Thread count
download_item_settings_thread_count_description=How much thread used to download this download item (0 for default)
download_item_settings_thread_count_describe={{count}} threads for this download