diff --git a/src/app/components/CloseBehaviorPrompt.tsx b/src/app/components/CloseBehaviorPrompt.tsx
new file mode 100644
index 000000000..b1bc7bbf7
--- /dev/null
+++ b/src/app/components/CloseBehaviorPrompt.tsx
@@ -0,0 +1,114 @@
+import React, { useCallback, useEffect, useState } from 'react';
+import FocusTrap from 'focus-trap-react';
+import {
+ Box,
+ Button,
+ Checkbox,
+ Dialog,
+ Header,
+ Overlay,
+ OverlayBackdrop,
+ OverlayCenter,
+ Text,
+ config,
+} from 'folds';
+import { invokeTauri, isTauri, tauriInvoke, useTauriEvent } from '../hooks/useTauri';
+import { useModalStyle } from '../hooks/useModalStyle';
+
+/**
+ * cinny-desktop #5: the first time the window is closed, ask whether Lotus Chat
+ * should keep running in the tray (calls, messages, notifications) or quit —
+ * and, in the same moment, whether it should start when you sign in. Asked
+ * once; changeable in Settings → General. The native side sends
+ * `lotus-close-requested` only while the choice is still "ask", and never
+ * during a call (a call always goes to the tray).
+ */
+export function CloseBehaviorPrompt() {
+ const [open, setOpen] = useState(false);
+ const [launchOnLogin, setLaunchOnLogin] = useState(false);
+ const modalStyle = useModalStyle(420);
+
+ // Tells the native side we're listening (see get_close_behavior).
+ useEffect(() => {
+ if (!isTauri()) return;
+ tauriInvoke()?.('get_close_behavior').catch(() => undefined);
+ }, []);
+
+ useTauriEvent('lotus-close-requested', () => setOpen(true));
+
+ const choose = useCallback(
+ (value: 'tray' | 'quit') => {
+ if (launchOnLogin) invokeTauri('plugin:autostart|enable');
+ setOpen(false);
+ invokeTauri('resolve_close_request', { value });
+ },
+ [launchOnLogin],
+ );
+
+ if (!open) return null;
+ return (
+ }>
+
+ setOpen(false),
+ clickOutsideDeactivates: true,
+ }}
+ >
+
+
+
+
+ );
+}
diff --git a/src/app/features/settings/general/General.tsx b/src/app/features/settings/general/General.tsx
index cfdedc137..edcb37f03 100644
--- a/src/app/features/settings/general/General.tsx
+++ b/src/app/features/settings/general/General.tsx
@@ -164,11 +164,18 @@ function AutostartSetting() {
// [cinny-desktop #3] null until the native side answers (older builds don't
// have the command, so the switch just stays hidden there).
const [startMinimized, setStartMinimized] = useState(null);
+ // [cinny-desktop #5] "ask" | "tray" | "quit"; null on builds without it.
+ const [closeBehavior, setCloseBehavior] = useState(null);
useEffect(() => {
tauriInvoke()?.('plugin:autostart|is_enabled')
.then((value) => setEnabled(value === true))
.catch(() => undefined);
+ tauriInvoke()?.('get_close_behavior')
+ .then((value) => {
+ if (typeof value === 'string') setCloseBehavior(value);
+ })
+ .catch(() => undefined);
tauriInvoke()?.('get_start_minimized')
.then((value) => {
if (typeof value === 'boolean') setStartMinimized(value);
@@ -181,6 +188,11 @@ function AutostartSetting() {
setEnabled(value);
};
+ const handleCloseBehavior = (value: string) => {
+ invokeTauri('set_close_behavior', { value });
+ setCloseBehavior(value);
+ };
+
const handleStartMinimized = (value: boolean) => {
invokeTauri('set_start_minimized', { value });
setStartMinimized(value);
@@ -194,6 +206,24 @@ function AutostartSetting() {
description="Start Lotus Chat automatically when you sign in to your computer."
after={}
/>
+ {closeBehavior !== null && (
+
+ }
+ />
+ )}
{enabled && startMinimized !== null && (
+