mirror of
https://github.com/amir1376/ab-download-manager.git
synced 2025-02-20 11:43:24 +08:00
Merge pull request #211 from amir1376/feature/add-confirm-exit-dialog
add confirm exit dialog when there is active download
This commit is contained in:
commit
1e65eb2847
@ -48,7 +48,6 @@ import ir.amirab.util.compose.asStringSource
|
||||
import ir.amirab.util.compose.combineStringSources
|
||||
import ir.amirab.util.flow.mapStateFlow
|
||||
import ir.amirab.util.osfileutil.FileUtils
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.serialization.Serializable
|
||||
@ -732,10 +731,31 @@ class AppComponent(
|
||||
}
|
||||
}
|
||||
|
||||
fun requestClose() {
|
||||
private val _showConfirmExitDialog = MutableStateFlow(false)
|
||||
val showConfirmExitDialog = _showConfirmExitDialog.asStateFlow()
|
||||
|
||||
fun exitAppAsync() {
|
||||
scope.launch { exitApp() }
|
||||
}
|
||||
|
||||
suspend fun exitApp() {
|
||||
downloadSystem.stopAnything()
|
||||
exitProcess(0)
|
||||
}
|
||||
|
||||
fun closeConfirmExit() {
|
||||
_showConfirmExitDialog.value = false
|
||||
}
|
||||
|
||||
suspend fun requestExitApp() {
|
||||
val hasActiveDownloads = downloadSystem.downloadMonitor.activeDownloadCount.value > 0
|
||||
if (hasActiveDownloads) {
|
||||
_showConfirmExitDialog.value = true
|
||||
return
|
||||
}
|
||||
exitApp()
|
||||
}
|
||||
|
||||
fun openAbout() {
|
||||
showAboutPage.update { true }
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
package com.abdownloadmanager.desktop
|
||||
|
||||
import com.abdownloadmanager.desktop.actions.exitAction
|
||||
import com.abdownloadmanager.desktop.utils.IntegrationPortBroadcaster
|
||||
import com.abdownloadmanager.desktop.utils.singleInstance.Command
|
||||
import com.abdownloadmanager.desktop.utils.singleInstance.MutableSingleInstanceServerHandler
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.inject
|
||||
object Commands {
|
||||
@ -26,7 +26,9 @@ object SingleInstanceServerInitializer:KoinComponent {
|
||||
appComponent.isReady()
|
||||
}
|
||||
mutableHandler.add(Commands.exit) {
|
||||
exitAction()
|
||||
runBlocking {
|
||||
appComponent.exitApp()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -13,7 +13,6 @@ import ir.amirab.util.compose.action.simpleAction
|
||||
import com.abdownloadmanager.desktop.utils.getIcon
|
||||
import com.abdownloadmanager.desktop.utils.getName
|
||||
import com.abdownloadmanager.resources.Res
|
||||
import com.abdownloadmanager.resources.*
|
||||
import com.abdownloadmanager.utils.category.Category
|
||||
import ir.amirab.downloader.downloaditem.DownloadCredentials
|
||||
import ir.amirab.downloader.queue.DownloadQueue
|
||||
@ -115,11 +114,12 @@ val stopAllAction = simpleAction(
|
||||
}.apply {
|
||||
}
|
||||
|
||||
val exitAction = simpleAction(
|
||||
// ui exit
|
||||
val requestExitAction = simpleAction(
|
||||
Res.string.exit.asStringSource(),
|
||||
MyIcons.exit,
|
||||
) {
|
||||
appComponent.requestClose()
|
||||
scope.launch { appComponent.requestExitApp() }
|
||||
}
|
||||
|
||||
val browserIntegrations = MenuItem.SubMenu(
|
||||
|
@ -0,0 +1,24 @@
|
||||
package com.abdownloadmanager.desktop.pages.confirmexit
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import com.abdownloadmanager.desktop.AppComponent
|
||||
import com.abdownloadmanager.desktop.ui.widget.ConfirmDialog
|
||||
import com.abdownloadmanager.desktop.ui.widget.ConfirmDialogType
|
||||
import com.abdownloadmanager.resources.Res
|
||||
import ir.amirab.util.compose.asStringSource
|
||||
|
||||
@Composable
|
||||
fun ConfirmExit(appComponent: AppComponent) {
|
||||
val showExitDialog by appComponent.showConfirmExitDialog.collectAsState()
|
||||
if (showExitDialog) {
|
||||
ConfirmDialog(
|
||||
Res.string.confirm_exit.asStringSource(),
|
||||
Res.string.confirm_exit_description.asStringSource(),
|
||||
onCancel = appComponent::closeConfirmExit,
|
||||
onConfirm = appComponent::exitAppAsync,
|
||||
type = ConfirmDialogType.Warning,
|
||||
)
|
||||
}
|
||||
}
|
@ -522,7 +522,7 @@ class HomeComponent(
|
||||
+newDownloadFromClipboardAction
|
||||
+batchDownloadAction
|
||||
separator()
|
||||
+exitAction
|
||||
+requestExitAction
|
||||
|
||||
}
|
||||
subMenu(Res.string.tasks.asStringSource()) {
|
||||
@ -897,7 +897,7 @@ class HomeComponent(
|
||||
"ctrl V" to newDownloadFromClipboardAction
|
||||
"ctrl C" to downloadActions.copyDownloadLinkAction
|
||||
"ctrl alt S" to gotoSettingsAction
|
||||
"ctrl W" to exitAction
|
||||
"ctrl W" to requestExitAction
|
||||
"DELETE" to downloadActions.deleteAction
|
||||
"ctrl O" to downloadActions.openFileAction
|
||||
"ctrl F" to downloadActions.openFolderAction
|
||||
|
@ -14,9 +14,6 @@ import com.abdownloadmanager.desktop.pages.singleDownloadPage.ShowDownloadDialog
|
||||
import com.abdownloadmanager.desktop.ui.icon.MyIcons
|
||||
import com.abdownloadmanager.desktop.ui.theme.ABDownloaderTheme
|
||||
import com.abdownloadmanager.desktop.ui.widget.tray.ComposeTray
|
||||
import com.abdownloadmanager.desktop.ui.widget.ProvideNotificationManager
|
||||
import com.abdownloadmanager.desktop.ui.widget.ShowMessageDialogs
|
||||
import com.abdownloadmanager.desktop.ui.widget.useNotification
|
||||
import com.abdownloadmanager.desktop.utils.AppInfo
|
||||
import com.abdownloadmanager.desktop.utils.GlobalAppExceptionHandler
|
||||
import com.abdownloadmanager.desktop.utils.ProvideGlobalExceptionHandler
|
||||
@ -24,16 +21,15 @@ import ir.amirab.util.compose.action.buildMenu
|
||||
import com.abdownloadmanager.desktop.utils.isInDebugMode
|
||||
import com.abdownloadmanager.desktop.utils.mvi.HandleEffects
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.platform.LocalLayoutDirection
|
||||
import androidx.compose.ui.unit.LayoutDirection
|
||||
import androidx.compose.ui.window.*
|
||||
import com.abdownloadmanager.desktop.pages.batchdownload.BatchDownloadWindow
|
||||
import com.abdownloadmanager.desktop.pages.category.ShowCategoryDialogs
|
||||
import com.abdownloadmanager.desktop.pages.confirmexit.ConfirmExit
|
||||
import com.abdownloadmanager.desktop.pages.credits.translators.ShowTranslators
|
||||
import com.abdownloadmanager.desktop.pages.editdownload.EditDownloadWindow
|
||||
import com.abdownloadmanager.desktop.pages.home.HomeWindow
|
||||
import com.abdownloadmanager.desktop.pages.settings.ThemeManager
|
||||
import com.abdownloadmanager.desktop.ui.widget.ProvideLanguageManager
|
||||
import com.abdownloadmanager.desktop.ui.widget.*
|
||||
import com.abdownloadmanager.utils.compose.ProvideDebugInfo
|
||||
import ir.amirab.util.compose.localizationmanager.LanguageManager
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
@ -100,6 +96,7 @@ object Ui : KoinComponent {
|
||||
ShowMessageDialogs(appComponent)
|
||||
ShowOpenSourceLibraries(appComponent)
|
||||
ShowTranslators(appComponent)
|
||||
ConfirmExit(appComponent)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -140,7 +137,7 @@ private fun ApplicationScope.SystemTray(
|
||||
buildMenu {
|
||||
+showDownloadList
|
||||
+gotoSettingsAction
|
||||
+exitAction
|
||||
+requestExitAction
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -0,0 +1,36 @@
|
||||
package com.abdownloadmanager.desktop.ui.widget
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.abdownloadmanager.desktop.ui.theme.myColors
|
||||
import com.abdownloadmanager.desktop.utils.div
|
||||
|
||||
@Composable
|
||||
fun ActionContainer(
|
||||
modifier: Modifier,
|
||||
contentPadding: PaddingValues = PaddingValues(
|
||||
horizontal = 16.dp,
|
||||
vertical = 8.dp,
|
||||
),
|
||||
content: @Composable () -> Unit,
|
||||
) {
|
||||
Column(modifier) {
|
||||
Spacer(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.height(1.dp)
|
||||
.background(myColors.onBackground / 0.15f)
|
||||
)
|
||||
Box(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.background(myColors.surface / 0.5f)
|
||||
.padding(contentPadding),
|
||||
) {
|
||||
content()
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,119 @@
|
||||
package com.abdownloadmanager.desktop.ui.widget
|
||||
|
||||
import com.abdownloadmanager.desktop.ui.customwindow.CustomWindow
|
||||
import com.abdownloadmanager.desktop.ui.customwindow.WindowTitle
|
||||
import com.abdownloadmanager.utils.compose.widget.MyIcon
|
||||
import com.abdownloadmanager.desktop.ui.icon.MyIcons
|
||||
import com.abdownloadmanager.desktop.ui.theme.myColors
|
||||
import com.abdownloadmanager.desktop.ui.theme.myTextSizes
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.DpSize
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.WindowPosition
|
||||
import androidx.compose.ui.window.rememberWindowState
|
||||
import com.abdownloadmanager.resources.Res
|
||||
import ir.amirab.util.compose.StringSource
|
||||
import ir.amirab.util.compose.resources.myStringResource
|
||||
import java.awt.Dimension
|
||||
|
||||
@Suppress("unused")
|
||||
sealed class ConfirmDialogType {
|
||||
data object Success : ConfirmDialogType()
|
||||
data object Info : ConfirmDialogType()
|
||||
data object Error : ConfirmDialogType()
|
||||
data object Warning : ConfirmDialogType()
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ConfirmDialog(
|
||||
title: StringSource,
|
||||
message: StringSource,
|
||||
type: ConfirmDialogType,
|
||||
onConfirm: () -> Unit,
|
||||
onCancel: () -> Unit,
|
||||
) {
|
||||
val h = 180
|
||||
val w = 400
|
||||
val state = rememberWindowState(
|
||||
size = DpSize(w.dp, h.dp),
|
||||
position = WindowPosition.Aligned(Alignment.Center)
|
||||
)
|
||||
CustomWindow(
|
||||
state,
|
||||
onRequestMinimize = null,
|
||||
onRequestToggleMaximize = null,
|
||||
onCloseRequest = onCancel,
|
||||
alwaysOnTop = true,
|
||||
) {
|
||||
LaunchedEffect(Unit) {
|
||||
window.minimumSize = Dimension(w, h)
|
||||
}
|
||||
val typeName = type.toString()
|
||||
WindowTitle(typeName)
|
||||
Column {
|
||||
Row(
|
||||
Modifier
|
||||
.weight(1f)
|
||||
.padding(8.dp),
|
||||
) {
|
||||
val color = when (type) {
|
||||
ConfirmDialogType.Error -> myColors.info
|
||||
ConfirmDialogType.Info -> myColors.warning
|
||||
ConfirmDialogType.Success -> myColors.success
|
||||
ConfirmDialogType.Warning -> myColors.warning
|
||||
}
|
||||
MyIcon(
|
||||
icon = MyIcons.info,
|
||||
tint = color,
|
||||
modifier = Modifier
|
||||
.padding(16.dp)
|
||||
.requiredSize(36.dp),
|
||||
contentDescription = null,
|
||||
)
|
||||
Column {
|
||||
Text(
|
||||
title.rememberString(),
|
||||
fontSize = myTextSizes.xl,
|
||||
fontWeight = FontWeight.Bold,
|
||||
)
|
||||
Spacer(Modifier.height(8.dp))
|
||||
Text(
|
||||
message.rememberString(),
|
||||
fontSize = myTextSizes.base,
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.fillMaxWidth()
|
||||
.verticalScroll(rememberScrollState())
|
||||
)
|
||||
Spacer(Modifier.height(8.dp))
|
||||
}
|
||||
}
|
||||
ActionContainer(
|
||||
Modifier.fillMaxWidth()
|
||||
) {
|
||||
Row(
|
||||
Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.End,
|
||||
) {
|
||||
ActionButton(
|
||||
myStringResource(Res.string.ok),
|
||||
onClick = onConfirm
|
||||
)
|
||||
Spacer(Modifier.width(8.dp))
|
||||
ActionButton(
|
||||
myStringResource(Res.string.cancel),
|
||||
onClick = onCancel
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -305,4 +305,6 @@ translators_contribute_title=Improve Translations
|
||||
translators_contribute_description=Want to help improve this project? If your language isn't listed or needs some tweaks, you can contribute your translations and make it better\!
|
||||
contribute=Contribute
|
||||
meet_the_translators=Meet the Translators
|
||||
localized_by_translators=Localized by Translators
|
||||
localized_by_translators=Localized by Translators
|
||||
confirm_exit=Confirm Exit
|
||||
confirm_exit_description=Are you sure you want to exit AB Download Manager?\nActive downloads/queues will be stopped!
|
Loading…
x
Reference in New Issue
Block a user