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.desktop.window.custom.CustomWindow
import com.abdownloadmanager.shared.utils.mvi.HandleEffects import com.abdownloadmanager.shared.utils.mvi.HandleEffects
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.unit.DpSize import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.WindowPlacement
import androidx.compose.ui.window.WindowPosition import androidx.compose.ui.window.WindowPosition
import androidx.compose.ui.window.rememberWindowState import androidx.compose.ui.window.rememberWindowState
@ -14,17 +16,22 @@ fun SettingWindow(
settingsComponent: SettingsComponent, settingsComponent: SettingsComponent,
onRequestCloseWindow: () -> Unit, onRequestCloseWindow: () -> Unit,
) { ) {
val state = rememberWindowState( val windowState = rememberWindowState(
size = DpSize(width = 800.dp, height = 400.dp), size = settingsComponent.windowSize.value,
position = WindowPosition.Aligned(Alignment.Center), position = WindowPosition.Aligned(Alignment.Center),
) )
CustomWindow(state, { LaunchedEffect(windowState.size) {
if (!windowState.isMinimized && windowState.placement == WindowPlacement.Floating) {
settingsComponent.setWindowSize(windowState.size)
}
}
CustomWindow(windowState, {
onRequestCloseWindow() onRequestCloseWindow()
}) { }) {
HandleEffects(settingsComponent) { HandleEffects(settingsComponent) {
when (it) { when (it) {
SettingPageEffects.BringToFront -> { SettingPageEffects.BringToFront -> {
state.isMinimized = false windowState.isMinimized = false
window.toFront() window.toFront()
} }
} }
@ -32,4 +39,4 @@ fun SettingWindow(
// Spacer(Modifier.fillMaxWidth().height(1.dp).background(myColors.surface)) // Spacer(Modifier.fillMaxWidth().height(1.dp).background(myColors.surface))
SettingsPage(settingsComponent, onRequestCloseWindow) SettingsPage(settingsComponent, onRequestCloseWindow)
} }
} }

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.ContainsEffects
import com.abdownloadmanager.shared.utils.mvi.supportEffects import com.abdownloadmanager.shared.utils.mvi.supportEffects
import androidx.compose.runtime.* 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.resources.Res
import com.abdownloadmanager.shared.utils.proxy.ProxyManager import com.abdownloadmanager.shared.utils.proxy.ProxyManager
import com.abdownloadmanager.shared.utils.proxy.ProxyMode 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.osfileutil.FileUtils
import ir.amirab.util.flow.createMutableStateFlowFromStateFlow import ir.amirab.util.flow.createMutableStateFlowFromStateFlow
import ir.amirab.util.flow.mapStateFlow import ir.amirab.util.flow.mapStateFlow
import ir.amirab.util.flow.mapTwoWayStateFlow
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.*
import org.koin.core.component.KoinComponent import org.koin.core.component.KoinComponent
import org.koin.core.component.inject import org.koin.core.component.inject
@ -427,6 +432,7 @@ class SettingsComponent(
KoinComponent, KoinComponent,
ContainsEffects<SettingPageEffects> by supportEffects() { ContainsEffects<SettingPageEffects> by supportEffects() {
val appSettings by inject<AppSettingsStorage>() val appSettings by inject<AppSettingsStorage>()
private val pageStorage by inject<PageStatesStorage>()
val appRepository by inject<AppRepository>() val appRepository by inject<AppRepository>()
val proxyManager by inject<ProxyManager>() val proxyManager by inject<ProxyManager>()
val themeManager by inject<ThemeManager>() val themeManager by inject<ThemeManager>()
@ -471,6 +477,32 @@ class SettingsComponent(
sendEffect(SettingPageEffects.BringToFront) 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( var pages = listOf(
Appearance, Appearance,
// Network, // Network,

View File

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