mirror of
https://github.com/amir1376/ab-download-manager.git
synced 2025-02-20 11:43:24 +08:00
save last part info state
This commit is contained in:
parent
36f446a14c
commit
9e6ffcab09
@ -60,7 +60,7 @@ fun ShowDownloadDialogs(component: DownloadDialogManager) {
|
||||
val defaultHeight = 290f
|
||||
val defaultWidth = 450f
|
||||
|
||||
val showPartInfo by singleDownloadComponent.showPartInfo
|
||||
val showPartInfo by singleDownloadComponent.showPartInfo.collectAsState()
|
||||
val itemState by singleDownloadComponent.itemStateFlow.collectAsState()
|
||||
val state = rememberWindowState(
|
||||
height = defaultHeight.dp,
|
||||
@ -92,10 +92,12 @@ fun ShowDownloadDialogs(component: DownloadDialogManager) {
|
||||
if (showPartInfo && itemState is ProcessingDownloadItemState) {
|
||||
h += singleDownloadPageSizing.partInfoHeight.value
|
||||
}
|
||||
state.size = DpSize(
|
||||
width = w.dp,
|
||||
height = h.dp
|
||||
)
|
||||
LaunchedEffect(w, h) {
|
||||
state.size = DpSize(
|
||||
width = w.dp,
|
||||
height = h.dp
|
||||
)
|
||||
}
|
||||
itemState?.let { itemState ->
|
||||
UpdateTaskBar(window, itemState)
|
||||
}
|
||||
|
@ -56,7 +56,8 @@ private val tabs = SingleDownloadPageSections.entries.toList()
|
||||
fun SingleDownloadPage(singleDownloadComponent: SingleDownloadComponent) {
|
||||
val itemState = singleDownloadComponent.itemStateFlow.collectAsState().value
|
||||
var selectedTab by remember { mutableStateOf(Info) }
|
||||
val (showPartInfo, setShowPartInfo) = singleDownloadComponent.showPartInfo
|
||||
val showPartInfo by singleDownloadComponent.showPartInfo.collectAsState()
|
||||
val setShowPartInfo = singleDownloadComponent::setShowPartInfo
|
||||
if (itemState != null) {
|
||||
Column(
|
||||
Modifier.padding(horizontal = 16.dp)
|
||||
|
@ -6,7 +6,8 @@ import com.abdownloadmanager.desktop.pages.settings.configurable.SpeedLimitConfi
|
||||
import com.abdownloadmanager.desktop.utils.*
|
||||
import com.abdownloadmanager.desktop.utils.mvi.ContainsEffects
|
||||
import com.abdownloadmanager.desktop.utils.mvi.supportEffects
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import arrow.optics.copy
|
||||
import com.abdownloadmanager.desktop.storage.PageStatesStorage
|
||||
import com.arkivanov.decompose.ComponentContext
|
||||
import ir.amirab.downloader.DownloadManagerEvents
|
||||
import ir.amirab.downloader.downloaditem.DownloadJobStatus
|
||||
@ -17,6 +18,7 @@ import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.get
|
||||
import org.koin.core.component.inject
|
||||
|
||||
sealed interface SingleDownloadEffects {
|
||||
@ -31,6 +33,7 @@ data class SingleDownloadPagePropertyItem(
|
||||
) {
|
||||
enum class ValueType { Normal, Error, Success }
|
||||
}
|
||||
|
||||
class SingleDownloadComponent(
|
||||
ctx: ComponentContext,
|
||||
val downloadItemOpener: DownloadItemOpener,
|
||||
@ -40,14 +43,25 @@ class SingleDownloadComponent(
|
||||
ContainsEffects<SingleDownloadEffects> by supportEffects(),
|
||||
KoinComponent {
|
||||
private val downloadSystem: DownloadSystem by inject()
|
||||
private val singleDownloadPageStateToPersist by lazy {
|
||||
get<PageStatesStorage>().downloadPage
|
||||
}
|
||||
private val downloadMonitor: IDownloadMonitor = downloadSystem.downloadMonitor
|
||||
private val downloadManager: DownloadManager = downloadSystem.downloadManager
|
||||
val itemStateFlow = downloadMonitor.downloadListFlow.map {
|
||||
it.firstOrNull { it.id == downloadId }
|
||||
}.stateIn(scope, SharingStarted.Eagerly, null)
|
||||
|
||||
val showPartInfo = mutableStateOf(false)
|
||||
|
||||
private val _showPartInfo = MutableStateFlow(singleDownloadPageStateToPersist.value.showPartInfo)
|
||||
val showPartInfo = _showPartInfo.asStateFlow()
|
||||
fun setShowPartInfo(value: Boolean) {
|
||||
_showPartInfo.value = value
|
||||
singleDownloadPageStateToPersist.update {
|
||||
it.copy {
|
||||
SingleDownloadPageStateToPersist.showPartInfo.set(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val extraDownloadInfo: StateFlow<List<SingleDownloadPagePropertyItem>> = itemStateFlow
|
||||
.filterNotNull()
|
||||
@ -61,24 +75,31 @@ class SingleDownloadComponent(
|
||||
}
|
||||
|
||||
is ProcessingDownloadItemState -> {
|
||||
add(SingleDownloadPagePropertyItem("Downloaded" , convertBytesToHumanReadable(it.progress).orEmpty()))
|
||||
add(SingleDownloadPagePropertyItem("Speed" , convertSpeedToHumanReadable(it.speed)))
|
||||
add(SingleDownloadPagePropertyItem("Remaining Time" , (it.remainingTime?.let { remainingTime ->
|
||||
add(
|
||||
SingleDownloadPagePropertyItem(
|
||||
"Downloaded",
|
||||
convertBytesToHumanReadable(it.progress).orEmpty()
|
||||
)
|
||||
)
|
||||
add(SingleDownloadPagePropertyItem("Speed", convertSpeedToHumanReadable(it.speed)))
|
||||
add(SingleDownloadPagePropertyItem("Remaining Time", (it.remainingTime?.let { remainingTime ->
|
||||
convertTimeRemainingToHumanReadable(remainingTime, TimeNames.ShortNames)
|
||||
}.orEmpty())))
|
||||
add(SingleDownloadPagePropertyItem(
|
||||
"Resume Support",
|
||||
when (it.supportResume) {
|
||||
true -> "Yes"
|
||||
false -> "No"
|
||||
null -> "Unknown"
|
||||
},
|
||||
when (it.supportResume) {
|
||||
true -> SingleDownloadPagePropertyItem.ValueType.Success
|
||||
false -> SingleDownloadPagePropertyItem.ValueType.Error
|
||||
null -> SingleDownloadPagePropertyItem.ValueType.Normal
|
||||
}
|
||||
))
|
||||
add(
|
||||
SingleDownloadPagePropertyItem(
|
||||
"Resume Support",
|
||||
when (it.supportResume) {
|
||||
true -> "Yes"
|
||||
false -> "No"
|
||||
null -> "Unknown"
|
||||
},
|
||||
when (it.supportResume) {
|
||||
true -> SingleDownloadPagePropertyItem.ValueType.Success
|
||||
false -> SingleDownloadPagePropertyItem.ValueType.Error
|
||||
null -> SingleDownloadPagePropertyItem.ValueType.Normal
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -135,6 +156,7 @@ class SingleDownloadComponent(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun resume() {
|
||||
val state = itemStateFlow.value as ProcessingDownloadItemState ?: return
|
||||
scope.launch {
|
||||
@ -143,6 +165,7 @@ class SingleDownloadComponent(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun pause() {
|
||||
val state = itemStateFlow.value as ProcessingDownloadItemState ?: return
|
||||
scope.launch {
|
||||
@ -170,14 +193,14 @@ class SingleDownloadComponent(
|
||||
downloadManager.dlListDb.getById(downloadId)
|
||||
}
|
||||
threadCount = MutableStateFlow(
|
||||
dItem?.preferredConnectionCount ?:0
|
||||
dItem?.preferredConnectionCount ?: 0
|
||||
)
|
||||
speedLimit = MutableStateFlow(dItem?.speedLimit ?: 0)
|
||||
downloadManager.listOfJobsEvents
|
||||
.filterIsInstance<DownloadManagerEvents.OnJobChanged>()
|
||||
.onEach { event ->
|
||||
threadCount.update {
|
||||
event.downloadItem.preferredConnectionCount?:0
|
||||
event.downloadItem.preferredConnectionCount ?: 0
|
||||
}
|
||||
speedLimit.update {
|
||||
event.downloadItem.speedLimit
|
||||
@ -190,7 +213,7 @@ class SingleDownloadComponent(
|
||||
.debounce(500)
|
||||
.onEach { count ->
|
||||
downloadManager.updateDownloadItem(downloadId) {
|
||||
it.preferredConnectionCount = count.takeIf { it>0 }
|
||||
it.preferredConnectionCount = count.takeIf { it > 0 }
|
||||
}
|
||||
}.launchIn(scope)
|
||||
speedLimit
|
||||
@ -211,9 +234,9 @@ class SingleDownloadComponent(
|
||||
description = "How much thread used to download this item 0 for default",
|
||||
backedBy = threadCount,
|
||||
describe = {
|
||||
if (it==0){
|
||||
if (it == 0) {
|
||||
"uses global setting"
|
||||
}else{
|
||||
} else {
|
||||
"$it threads"
|
||||
}
|
||||
},
|
||||
|
@ -0,0 +1,36 @@
|
||||
package com.abdownloadmanager.desktop.pages.singleDownloadPage
|
||||
|
||||
import arrow.optics.Lens
|
||||
import arrow.optics.optics
|
||||
import ir.amirab.util.config.MapConfig
|
||||
import ir.amirab.util.config.booleanKeyOf
|
||||
import kotlinx.serialization.Serializable
|
||||
import org.koin.core.component.KoinComponent
|
||||
|
||||
@optics
|
||||
@Serializable
|
||||
data class SingleDownloadPageStateToPersist(
|
||||
val showPartInfo: Boolean = false,
|
||||
) {
|
||||
class ConfigLens(prefix: String) : Lens<MapConfig, SingleDownloadPageStateToPersist>,
|
||||
KoinComponent {
|
||||
class Keys(prefix: String) {
|
||||
val showPartInfo = booleanKeyOf("${prefix}showPartInfo")
|
||||
}
|
||||
|
||||
private val keys = Keys(prefix)
|
||||
override fun get(source: MapConfig): SingleDownloadPageStateToPersist {
|
||||
val default by lazy { SingleDownloadPageStateToPersist() }
|
||||
return SingleDownloadPageStateToPersist(
|
||||
showPartInfo = source.get(keys.showPartInfo) ?: default.showPartInfo,
|
||||
)
|
||||
}
|
||||
|
||||
override fun set(source: MapConfig, focus: SingleDownloadPageStateToPersist): MapConfig {
|
||||
source.put(keys.showPartInfo, focus.showPartInfo)
|
||||
return source
|
||||
}
|
||||
}
|
||||
|
||||
companion object
|
||||
}
|
@ -5,6 +5,7 @@ import com.abdownloadmanager.desktop.utils.*
|
||||
import androidx.datastore.core.DataStore
|
||||
import arrow.optics.Lens
|
||||
import arrow.optics.optics
|
||||
import com.abdownloadmanager.desktop.pages.singleDownloadPage.SingleDownloadPageStateToPersist
|
||||
import ir.amirab.util.config.getDecoded
|
||||
import ir.amirab.util.config.keyOfEncoded
|
||||
import ir.amirab.util.config.putEncoded
|
||||
@ -48,6 +49,7 @@ data class CommonData(
|
||||
@Serializable
|
||||
data class PageStatesModel(
|
||||
val home: HomePageStateToPersist = HomePageStateToPersist(),
|
||||
val downloadPage: SingleDownloadPageStateToPersist = SingleDownloadPageStateToPersist(),
|
||||
val global: CommonData = CommonData(),
|
||||
) {
|
||||
companion object {
|
||||
@ -59,23 +61,22 @@ data class PageStatesModel(
|
||||
|
||||
object Child {
|
||||
val common = CommonData.ConfigLens("global.")
|
||||
val downloadPage = SingleDownloadPageStateToPersist.ConfigLens("downloadPage.")
|
||||
val home = HomePageStateToPersist.ConfigLens("home.")
|
||||
}
|
||||
|
||||
override fun get(source: MapConfig): PageStatesModel {
|
||||
return with(json) {
|
||||
PageStatesModel(
|
||||
home = Child.home.get(source),
|
||||
global = Child.common.get(source)
|
||||
)
|
||||
}
|
||||
return PageStatesModel(
|
||||
home = Child.home.get(source),
|
||||
downloadPage = Child.downloadPage.get(source),
|
||||
global = Child.common.get(source)
|
||||
)
|
||||
}
|
||||
|
||||
override fun set(source: MapConfig, focus: PageStatesModel): MapConfig {
|
||||
with(json) {
|
||||
Child.home.set(source, focus.home)
|
||||
Child.common.set(source, focus.global)
|
||||
}
|
||||
Child.home.set(source, focus.home)
|
||||
Child.downloadPage.set(source, focus.downloadPage)
|
||||
Child.common.set(source, focus.global)
|
||||
return source
|
||||
}
|
||||
}
|
||||
@ -85,6 +86,6 @@ class PageStatesStorage(
|
||||
settings: DataStore<MapConfig>,
|
||||
) : ConfigBaseSettings<PageStatesModel>(settings, PageStatesModel.ConfigLens) {
|
||||
val lastUsedSaveLocations = from(PageStatesModel.global.lastSavedLocations)
|
||||
|
||||
val downloadPage = from(PageStatesModel.downloadPage)
|
||||
val homePageStorage = from(PageStatesModel.home)
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user