feat(desktop): tray Do-Not-Disturb + Launch-on-login toggle (P6-1 web)

- useTauriDnd + manualDndAtom: the native tray "Do Not Disturb" toggle
  (lotus-dnd-changed event) OR's into the notification quiet-gate in
  ClientNonUIFeatures (both invite + message notifiers), alongside Focus Assist.
- AutostartSetting in Settings → General (desktop-only): reads/sets
  plugin:autostart via invoke. Mirrors the window-chrome setting.
- Docs: LOTUS_FEATURES desktop section (Linux parity + DND + autostart),
  LOTUS_TODO P6-1 → [~], LOTUS_BUGS verification row.

Gates: tsc/eslint/prettier clean, build OK, 661 tests. Native side committed on
cinny-desktop:main (CI-compile-pending).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-02 13:31:09 -04:00
parent 625f0c2386
commit 804caa5130
8 changed files with 120 additions and 31 deletions
+34 -1
View File
@@ -102,7 +102,7 @@ import { useMessageLayoutItems } from '../../../hooks/useMessageLayout';
import { useMessageSpacingItems } from '../../../hooks/useMessageSpacing';
import { SequenceCardStyle } from '../styles.css';
import { useTauriUpdater } from '../../../hooks/useTauriUpdater';
import { isTauri as isTauriEnv } from '../../../hooks/useTauri';
import { isTauri as isTauriEnv, invokeTauri, tauriInvoke } from '../../../hooks/useTauri';
import { customWindowChromeAtom } from '../../../state/customWindowChrome';
import { useDateFormatItems } from '../../../hooks/useDateFormat';
import { playCallJoinSound } from '../../../utils/callSounds';
@@ -129,6 +129,38 @@ function DesktopChromeSetting() {
);
}
/**
* P6-1 — "Launch on login" toggle (desktop only). Renders nothing in the
* browser. Reads the current state from the `autostart` plugin on mount and
* enables/disables it via the plugin commands when flipped. Not backed by an
* atom — the OS registration is the source of truth, mirrored into local state.
*/
function AutostartSetting() {
const [enabled, setEnabled] = useState(false);
useEffect(() => {
tauriInvoke()?.('plugin:autostart|is_enabled')
.then((value) => setEnabled(value === true))
.catch(() => undefined);
}, []);
const handleChange = (value: boolean) => {
invokeTauri(value ? 'plugin:autostart|enable' : 'plugin:autostart|disable');
setEnabled(value);
};
if (!isTauriEnv()) return null;
return (
<SequenceCard className={SequenceCardStyle} variant="SurfaceVariant" direction="Column">
<SettingTile
title="Launch on login"
description="Start Lotus Chat automatically when you sign in to your computer."
after={<Switch variant="Primary" value={enabled} onChange={handleChange} />}
/>
</SequenceCard>
);
}
type ThemeSelectorProps = {
themeNames: Record<string, string>;
themes: Theme[];
@@ -443,6 +475,7 @@ function Appearance() {
</SequenceCard>
<DesktopChromeSetting />
<AutostartSetting />
<SequenceCard className={SequenceCardStyle} variant="SurfaceVariant" direction="Column">
<SettingTile