persist setting window size (#373)

This commit is contained in:
AmirHossein Abdolmotallebi 2025-01-17 01:54:38 +03:30 committed by GitHub
parent 0de23e1fb4
commit 7c3f540c49
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 94 additions and 6 deletions

View File

@ -0,0 +1,43 @@
package com.abdownloadmanager.desktop.pages.settings
import arrow.optics.Lens
import com.abdownloadmanager.desktop.pages.home.HomePageStateToPersist
import ir.amirab.util.config.*
import kotlinx.serialization.Serializable
import org.koin.core.component.KoinComponent
@Serializable
data class SettingPageStateToPersist(
val windowSize: Pair<Float, Float> = 800f to 400f
) {
class ConfigLens(prefix: String) : Lens<MapConfig, SettingPageStateToPersist>,
KoinComponent {
class Keys(prefix: String) {
val windowWidth = floatKeyOf("${prefix}window.width")
val windowHeight = floatKeyOf("${prefix}window.height")
}
private val keys = Keys(prefix)
override fun get(source: MapConfig): SettingPageStateToPersist {
val default by lazy { HomePageStateToPersist() }
return SettingPageStateToPersist(
windowSize = run {
val width = source.get(keys.windowWidth)
val height = source.get(keys.windowHeight)
if (height != null && width != null) {
width to height
} else {
default.windowSize
}
}
)
}
override fun set(source: MapConfig, focus: SettingPageStateToPersist): MapConfig {
source.put(keys.windowWidth, focus.windowSize.first)
source.put(keys.windowHeight, focus.windowSize.second)
return source
}
}
}

View File

@ -3,9 +3,11 @@ package com.abdownloadmanager.desktop.pages.settings
import com.abdownloadmanager.desktop.window.custom.CustomWindow
import com.abdownloadmanager.shared.utils.mvi.HandleEffects
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Alignment
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.WindowPlacement
import androidx.compose.ui.window.WindowPosition
import androidx.compose.ui.window.rememberWindowState
@ -14,17 +16,22 @@ fun SettingWindow(
settingsComponent: SettingsComponent,
onRequestCloseWindow: () -> Unit,
) {
val state = rememberWindowState(
size = DpSize(width = 800.dp, height = 400.dp),
val windowState = rememberWindowState(
size = settingsComponent.windowSize.value,
position = WindowPosition.Aligned(Alignment.Center),
)
CustomWindow(state, {
LaunchedEffect(windowState.size) {
if (!windowState.isMinimized && windowState.placement == WindowPlacement.Floating) {
settingsComponent.setWindowSize(windowState.size)
}
}
CustomWindow(windowState, {
onRequestCloseWindow()
}) {
HandleEffects(settingsComponent) {
when (it) {
SettingPageEffects.BringToFront -> {
state.isMinimized = false
windowState.isMinimized = false
window.toFront()
}
}

View File

@ -10,6 +10,9 @@ import com.abdownloadmanager.shared.utils.convertPositiveSpeedToHumanReadable
import com.abdownloadmanager.shared.utils.mvi.ContainsEffects
import com.abdownloadmanager.shared.utils.mvi.supportEffects
import androidx.compose.runtime.*
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
import com.abdownloadmanager.desktop.storage.PageStatesStorage
import com.abdownloadmanager.resources.Res
import com.abdownloadmanager.shared.utils.proxy.ProxyManager
import com.abdownloadmanager.shared.utils.proxy.ProxyMode
@ -22,7 +25,9 @@ import ir.amirab.util.datasize.ConvertSizeConfig
import ir.amirab.util.osfileutil.FileUtils
import ir.amirab.util.flow.createMutableStateFlowFromStateFlow
import ir.amirab.util.flow.mapStateFlow
import ir.amirab.util.flow.mapTwoWayStateFlow
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.*
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
@ -427,6 +432,7 @@ class SettingsComponent(
KoinComponent,
ContainsEffects<SettingPageEffects> by supportEffects() {
val appSettings by inject<AppSettingsStorage>()
private val pageStorage by inject<PageStatesStorage>()
val appRepository by inject<AppRepository>()
val proxyManager by inject<ProxyManager>()
val themeManager by inject<ThemeManager>()
@ -471,6 +477,32 @@ class SettingsComponent(
sendEffect(SettingPageEffects.BringToFront)
}
val settingsPageStateToPersist = MutableStateFlow(pageStorage.settingsPageStorage.value)
private val _windowSize = settingsPageStateToPersist.mapTwoWayStateFlow(
map = {
it.windowSize.let { (x, y) ->
DpSize(x.dp, y.dp)
}
},
unMap = {
copy(
windowSize = it.width.value to it.height.value
)
}
)
val windowSize = _windowSize.asStateFlow()
fun setWindowSize(dpSize: DpSize) {
_windowSize.value = dpSize
}
init {
settingsPageStateToPersist
.debounce(500)
.onEach { newValue ->
pageStorage.settingsPageStorage.update { newValue }
}.launchIn(scope)
}
var pages = listOf(
Appearance,
// Network,

View File

@ -4,6 +4,7 @@ import com.abdownloadmanager.desktop.pages.home.HomePageStateToPersist
import androidx.datastore.core.DataStore
import arrow.optics.Lens
import arrow.optics.optics
import com.abdownloadmanager.desktop.pages.settings.SettingPageStateToPersist
import com.abdownloadmanager.desktop.pages.singleDownloadPage.SingleDownloadPageStateToPersist
import com.abdownloadmanager.shared.utils.ConfigBaseSettingsByMapConfig
import ir.amirab.util.config.getDecoded
@ -49,6 +50,7 @@ data class CommonData(
@Serializable
data class PageStatesModel(
val home: HomePageStateToPersist = HomePageStateToPersist(),
val settings: SettingPageStateToPersist = SettingPageStateToPersist(),
val downloadPage: SingleDownloadPageStateToPersist = SingleDownloadPageStateToPersist(),
val global: CommonData = CommonData(),
) {
@ -63,11 +65,13 @@ data class PageStatesModel(
val common = CommonData.ConfigLens("global.")
val downloadPage = SingleDownloadPageStateToPersist.ConfigLens("downloadPage.")
val home = HomePageStateToPersist.ConfigLens("home.")
val settings = SettingPageStateToPersist.ConfigLens("settings.")
}
override fun get(source: MapConfig): PageStatesModel {
return PageStatesModel(
home = Child.home.get(source),
settings = Child.settings.get(source),
downloadPage = Child.downloadPage.get(source),
global = Child.common.get(source)
)
@ -75,6 +79,7 @@ data class PageStatesModel(
override fun set(source: MapConfig, focus: PageStatesModel): MapConfig {
Child.home.set(source, focus.home)
Child.settings.set(source, focus.settings)
Child.downloadPage.set(source, focus.downloadPage)
Child.common.set(source, focus.global)
return source
@ -88,4 +93,5 @@ class PageStatesStorage(
val lastUsedSaveLocations = from(PageStatesModel.global.lastSavedLocations)
val downloadPage = from(PageStatesModel.downloadPage)
val homePageStorage = from(PageStatesModel.home)
val settingsPageStorage = from(PageStatesModel.settings)
}