atagen

malice

public
Star0
Watch0
0f306a02ef992c8a7d2252fafe6f2548d710e0dd
2
ssh://brewery@pls.lobotomise.me:33/atagen/malice.git
web/src/lib/NotificationSettings.svelteSvelte38 lines1.3 KB
1
<script lang="ts">
2
  import { disableNotifications, enableNotifications, notificationPermission, notificationsEnabled } from './notifications';
3
4
  let busy = false;
5
6
  $: denied = $notificationPermission === 'denied';
7
  $: unsupported = $notificationPermission === 'unsupported';
8
  $: on = $notificationsEnabled && $notificationPermission === 'granted';
9
10
  async function toggle(): Promise<void> {
11
    if (busy) return;
12
    busy = true;
13
    try {
14
      if (on) disableNotifications();
15
      else await enableNotifications();
16
    } finally {
17
      busy = false;
18
    }
19
  }
20
</script>
21
22
<section aria-label="Notifications">
23
  <div class="sec-head">
24
    <h3 class="sec-h">Notifications</h3>
25
    <span class="state" class:ok={on}>{unsupported ? 'Unavailable' : denied ? 'Blocked' : on ? 'On' : 'Off'}</span>
26
  </div>
27
  <button type="button" class="ghost-btn" disabled={busy || denied || unsupported} aria-pressed={on} on:click={() => void toggle()}>
28
    {on ? 'Turn off' : 'Turn on'}
29
  </button>
30
</section>
31
32
<style>
33
  section { margin-top: 18px; }
34
  .sec-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; }
35
  .sec-h { font-size: 12px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--muted); margin: 0; }
36
  .state { font-size: 12px; color: var(--muted); }
37
  .state.ok { color: var(--accent); }
38
</style>