187 lines
8.4 KiB
HTML
187 lines
8.4 KiB
HTML
<div class="space-y-6">
|
|
<section class="rounded-lg border border-border bg-secondary/20 p-5">
|
|
<div class="flex items-start gap-3">
|
|
<div class="grid h-9 w-9 shrink-0 place-items-center rounded-lg bg-primary/10 text-primary">
|
|
<ng-icon
|
|
name="lucideBell"
|
|
class="h-5 w-5"
|
|
/>
|
|
</div>
|
|
|
|
<div class="min-w-0 flex-1">
|
|
<h4 class="text-base font-semibold text-foreground">Delivery</h4>
|
|
<p class="mt-1 text-sm text-muted-foreground">
|
|
Desktop alerts use the system notification center on Linux and request taskbar attention when the app is not focused. Maximized app window
|
|
suppress system popups, and only play the configured notification sound while the app is in the background.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mt-5 space-y-4">
|
|
<div class="flex items-center justify-between gap-4">
|
|
<div>
|
|
<p class="font-medium text-foreground">Enable notifications</p>
|
|
<p class="text-sm text-muted-foreground">Mute every server and channel notification without affecting unread indicators.</p>
|
|
</div>
|
|
|
|
<label class="relative inline-flex cursor-pointer items-center">
|
|
<input
|
|
type="checkbox"
|
|
class="peer sr-only"
|
|
[checked]="enabled()"
|
|
(change)="onNotificationsEnabledChange($event)"
|
|
/>
|
|
<div
|
|
class="h-6 w-11 rounded-full bg-secondary transition-colors peer-checked:bg-primary after:absolute after:left-[2px] after:top-0.5 after:h-5 after:w-5 after:rounded-full after:bg-white after:transition-all after:content-[''] peer-checked:after:translate-x-full"
|
|
></div>
|
|
</label>
|
|
</div>
|
|
|
|
<div class="flex items-center justify-between gap-4">
|
|
<div class="flex items-start gap-3">
|
|
<ng-icon
|
|
name="lucideMessageSquareText"
|
|
class="mt-0.5 h-4 w-4 text-muted-foreground"
|
|
/>
|
|
|
|
<div>
|
|
<p class="font-medium text-foreground">Show message preview</p>
|
|
<p class="text-sm text-muted-foreground">Include a short message preview in desktop notifications when content privacy allows it.</p>
|
|
</div>
|
|
</div>
|
|
|
|
<label class="relative inline-flex cursor-pointer items-center">
|
|
<input
|
|
type="checkbox"
|
|
class="peer sr-only"
|
|
[checked]="showPreview()"
|
|
(change)="onShowPreviewChange($event)"
|
|
/>
|
|
<div
|
|
class="h-6 w-11 rounded-full bg-secondary transition-colors peer-checked:bg-primary after:absolute after:left-[2px] after:top-0.5 after:h-5 after:w-5 after:rounded-full after:bg-white after:transition-all after:content-[''] peer-checked:after:translate-x-full"
|
|
></div>
|
|
</label>
|
|
</div>
|
|
|
|
<div class="flex items-center justify-between gap-4">
|
|
<div class="flex items-start gap-3">
|
|
<ng-icon
|
|
name="lucideMoonStar"
|
|
class="mt-0.5 h-4 w-4 text-muted-foreground"
|
|
/>
|
|
|
|
<div>
|
|
<p class="font-medium text-foreground">Respect busy status</p>
|
|
<p class="text-sm text-muted-foreground">Suppress desktop alerts while your user presence is set to busy.</p>
|
|
</div>
|
|
</div>
|
|
|
|
<label class="relative inline-flex cursor-pointer items-center">
|
|
<input
|
|
type="checkbox"
|
|
class="peer sr-only"
|
|
[checked]="respectBusyStatus()"
|
|
(change)="onRespectBusyChange($event)"
|
|
/>
|
|
<div
|
|
class="h-6 w-11 rounded-full bg-secondary transition-colors peer-checked:bg-primary after:absolute after:left-[2px] after:top-0.5 after:h-5 after:w-5 after:rounded-full after:bg-white after:transition-all after:content-[''] peer-checked:after:translate-x-full"
|
|
></div>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="rounded-lg border border-border bg-card p-5">
|
|
<div class="flex items-start gap-3">
|
|
<div class="grid h-9 w-9 shrink-0 place-items-center rounded-lg bg-secondary text-muted-foreground">
|
|
<ng-icon
|
|
[name]="enabled() ? 'lucideBell' : 'lucideBellOff'"
|
|
class="h-5 w-5"
|
|
/>
|
|
</div>
|
|
|
|
<div class="min-w-0 flex-1">
|
|
<h4 class="text-base font-semibold text-foreground">Server Overrides</h4>
|
|
<p class="mt-1 text-sm text-muted-foreground">
|
|
Right-click actions mirror these switches. Muted servers and channels still collect unread badges so you can catch up later.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
@if (rooms().length === 0) {
|
|
<div class="mt-5 rounded-lg border border-dashed border-border bg-secondary/20 p-4 text-sm text-muted-foreground">
|
|
Join a server to configure notification overrides.
|
|
</div>
|
|
} @else {
|
|
<div class="mt-5 space-y-4">
|
|
@for (room of rooms(); track trackRoom($index, room)) {
|
|
<article class="rounded-lg border border-border bg-secondary/15 p-4">
|
|
<div class="flex items-start justify-between gap-4">
|
|
<div class="min-w-0 flex-1">
|
|
<div class="flex items-center gap-2">
|
|
<p class="truncate font-medium text-foreground">{{ room.name }}</p>
|
|
@if (roomUnreadCount(room.id) > 0) {
|
|
<span class="rounded-full bg-amber-400/20 px-2 py-0.5 text-[11px] font-semibold text-amber-300">
|
|
{{ formatUnreadCount(roomUnreadCount(room.id)) }} unread
|
|
</span>
|
|
}
|
|
</div>
|
|
<p class="mt-1 text-sm text-muted-foreground">{{ room.description || 'Notifications for every text channel in this server.' }}</p>
|
|
</div>
|
|
|
|
<label class="relative inline-flex cursor-pointer items-center">
|
|
<input
|
|
type="checkbox"
|
|
class="peer sr-only"
|
|
[checked]="isRoomEnabled(room.id)"
|
|
(change)="onRoomMutedChange(room.id, $event)"
|
|
/>
|
|
<div
|
|
class="h-6 w-11 rounded-full bg-secondary transition-colors peer-checked:bg-primary after:absolute after:left-[2px] after:top-0.5 after:h-5 after:w-5 after:rounded-full after:bg-white after:transition-all after:content-[''] peer-checked:after:translate-x-full"
|
|
></div>
|
|
</label>
|
|
</div>
|
|
|
|
<div class="mt-4 rounded-lg border border-border/70 bg-background/50 p-3">
|
|
<div class="mb-2 flex items-center justify-between">
|
|
<p class="text-xs font-semibold uppercase tracking-wide text-muted-foreground">Channels</p>
|
|
<p class="text-xs text-muted-foreground">Unread badges remain visible even if muted.</p>
|
|
</div>
|
|
|
|
<div class="space-y-2">
|
|
@for (channel of textChannels(room); track channel.id) {
|
|
<div class="flex items-center justify-between gap-3 rounded-lg px-2 py-2 hover:bg-secondary/40">
|
|
<div class="min-w-0 flex-1">
|
|
<div class="flex items-center gap-2">
|
|
<span class="text-muted-foreground">#</span>
|
|
<span class="truncate text-sm text-foreground">{{ channel.name }}</span>
|
|
@if (channelUnreadCount(room.id, channel.id) > 0) {
|
|
<span class="rounded-full bg-primary/15 px-1.5 py-0.5 text-[10px] font-semibold text-primary">
|
|
{{ formatUnreadCount(channelUnreadCount(room.id, channel.id)) }}
|
|
</span>
|
|
}
|
|
</div>
|
|
</div>
|
|
|
|
<label class="relative inline-flex cursor-pointer items-center">
|
|
<input
|
|
type="checkbox"
|
|
class="peer sr-only"
|
|
[checked]="isChannelEnabled(room.id, channel.id)"
|
|
(change)="onChannelMutedChange(room.id, channel.id, $event)"
|
|
/>
|
|
<div
|
|
class="h-5 w-9 rounded-full bg-secondary transition-colors peer-checked:bg-primary after:absolute after:left-[2px] after:top-0.5 after:h-4 after:w-4 after:rounded-full after:bg-white after:transition-all after:content-[''] peer-checked:after:translate-x-full"
|
|
></div>
|
|
</label>
|
|
</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
</article>
|
|
}
|
|
</div>
|
|
}
|
|
</section>
|
|
</div>
|