feat: Close to tray

This commit is contained in:
2026-03-30 04:48:34 +02:00
parent 42ac712571
commit e3b23247a9
9 changed files with 284 additions and 40 deletions

View File

@@ -8,39 +8,77 @@
<h4 class="text-sm font-semibold text-foreground">Application</h4>
</div>
<div
class="rounded-lg border border-border bg-secondary/20 p-4 transition-opacity"
[class.opacity-60]="!isElectron"
>
<div class="flex items-center justify-between gap-4">
<div>
<p class="text-sm font-medium text-foreground">Launch on system startup</p>
<div class="space-y-3">
<div
class="rounded-lg border border-border bg-secondary/20 p-4 transition-opacity"
[class.opacity-60]="!isElectron"
>
<div class="flex items-center justify-between gap-4">
<div>
<p class="text-sm font-medium text-foreground">Launch on system startup</p>
@if (isElectron) {
<p class="text-xs text-muted-foreground">Automatically start MetoYou when you sign in</p>
} @else {
<p class="text-xs text-muted-foreground">This setting is only available in the desktop app.</p>
}
@if (isElectron) {
<p class="text-xs text-muted-foreground">Automatically start MetoYou when you sign in</p>
} @else {
<p class="text-xs text-muted-foreground">This setting is only available in the desktop app.</p>
}
</div>
<label
class="relative inline-flex items-center"
[class.cursor-pointer]="isElectron && !savingAutoStart()"
[class.cursor-not-allowed]="!isElectron || savingAutoStart()"
>
<input
type="checkbox"
[checked]="autoStart()"
[disabled]="!isElectron || savingAutoStart()"
(change)="onAutoStartChange($event)"
id="general-auto-start-toggle"
aria-label="Toggle launch on startup"
class="sr-only peer"
/>
<div
class="w-10 h-5 bg-secondary rounded-full peer peer-checked:bg-primary peer-disabled:bg-muted/80 peer-disabled:after:bg-muted-foreground/40 peer-checked:after:translate-x-full after:content-[''] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:rounded-full after:h-4 after:w-4 after:transition-all"
></div>
</label>
</div>
</div>
<label
class="relative inline-flex items-center"
[class.cursor-pointer]="isElectron && !savingAutoStart()"
[class.cursor-not-allowed]="!isElectron || savingAutoStart()"
>
<input
type="checkbox"
[checked]="autoStart()"
[disabled]="!isElectron || savingAutoStart()"
(change)="onAutoStartChange($event)"
id="general-auto-start-toggle"
aria-label="Toggle launch on startup"
class="sr-only peer"
/>
<div
class="w-10 h-5 bg-secondary rounded-full peer peer-checked:bg-primary peer-disabled:bg-muted/80 peer-disabled:after:bg-muted-foreground/40 peer-checked:after:translate-x-full after:content-[''] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:rounded-full after:h-4 after:w-4 after:transition-all"
></div>
</label>
<div
class="rounded-lg border border-border bg-secondary/20 p-4 transition-opacity"
[class.opacity-60]="!isElectron"
>
<div class="flex items-center justify-between gap-4">
<div>
<p class="text-sm font-medium text-foreground">Minimize to tray on close</p>
@if (isElectron) {
<p class="text-xs text-muted-foreground">Keep MetoYou running in the tray when you click the X button</p>
} @else {
<p class="text-xs text-muted-foreground">This setting is only available in the desktop app.</p>
}
</div>
<label
class="relative inline-flex items-center"
[class.cursor-pointer]="isElectron && !savingCloseToTray()"
[class.cursor-not-allowed]="!isElectron || savingCloseToTray()"
>
<input
type="checkbox"
[checked]="closeToTray()"
[disabled]="!isElectron || savingCloseToTray()"
(change)="onCloseToTrayChange($event)"
id="general-close-to-tray-toggle"
aria-label="Toggle minimize to tray on close"
class="sr-only peer"
/>
<div
class="w-10 h-5 bg-secondary rounded-full peer peer-checked:bg-primary peer-disabled:bg-muted/80 peer-disabled:after:bg-muted-foreground/40 peer-checked:after:translate-x-full after:content-[''] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:rounded-full after:h-4 after:w-4 after:transition-all"
></div>
</label>
</div>
</div>
</div>
</section>

View File

@@ -8,6 +8,7 @@ import { CommonModule } from '@angular/common';
import { NgIcon, provideIcons } from '@ng-icons/core';
import { lucidePower } from '@ng-icons/lucide';
import type { DesktopSettingsSnapshot } from '../../../../core/platform/electron/electron-api.models';
import { ElectronBridgeService } from '../../../../core/platform/electron/electron-bridge.service';
import { PlatformService } from '../../../../core/platform';
@@ -28,7 +29,9 @@ export class GeneralSettingsComponent {
readonly isElectron = this.platform.isElectron;
autoStart = signal(false);
closeToTray = signal(true);
savingAutoStart = signal(false);
savingCloseToTray = signal(false);
constructor() {
if (this.isElectron) {
@@ -51,7 +54,7 @@ export class GeneralSettingsComponent {
try {
const snapshot = await api.setDesktopSettings({ autoStart: enabled });
this.autoStart.set(snapshot.autoStart);
this.applyDesktopSettings(snapshot);
} catch {
input.checked = this.autoStart();
} finally {
@@ -59,6 +62,29 @@ export class GeneralSettingsComponent {
}
}
async onCloseToTrayChange(event: Event): Promise<void> {
const input = event.target as HTMLInputElement;
const enabled = !!input.checked;
const api = this.electronBridge.getApi();
if (!this.isElectron || !api) {
input.checked = this.closeToTray();
return;
}
this.savingCloseToTray.set(true);
try {
const snapshot = await api.setDesktopSettings({ closeToTray: enabled });
this.applyDesktopSettings(snapshot);
} catch {
input.checked = this.closeToTray();
} finally {
this.savingCloseToTray.set(false);
}
}
private async loadDesktopSettings(): Promise<void> {
const api = this.electronBridge.getApi();
@@ -69,7 +95,12 @@ export class GeneralSettingsComponent {
try {
const snapshot = await api.getDesktopSettings();
this.autoStart.set(snapshot.autoStart);
this.applyDesktopSettings(snapshot);
} catch {}
}
private applyDesktopSettings(snapshot: DesktopSettingsSnapshot): void {
this.autoStart.set(snapshot.autoStart);
this.closeToTray.set(snapshot.closeToTray);
}
}