df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 1 | <script lang="ts"> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 2 | import { createEventDispatcher } from 'svelte'; |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 3 | import { |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 4 | LINE_HEIGHT_DEFAULT, |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 5 | LINE_HEIGHT_MAX, |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 6 | LINE_HEIGHT_MIN, |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 7 | MESSAGE_SPACING_DEFAULT, |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 8 | MESSAGE_SPACING_MAX, |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 9 | MESSAGE_SPACING_MIN, |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 10 | THEMES, |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 11 | accent, |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 12 | lineHeight, |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 13 | messageSpacing, |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 14 | theme |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 15 | } from './appearance'; |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 16 | import { DEFAULT_QUICK_REACTIONS } from './quick-reactions'; |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 17 | import ReactionPicker from './ReactionPicker.svelte'; |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 18 | import type { ImagePack, QuickReaction } from './types'; |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 19 | |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 20 | export let quick: QuickReaction[]; |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 21 | export let packs: ImagePack[] = []; |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 22 | export let onQuickChange: (list: QuickReaction[]) => void; |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 23 | |
d095131eec0e | atagen | 2026-10-24 08:39 UTC | 24 | const dispatch = createEventDispatcher<{ close: void; packs: void }>(); |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 25 | |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 26 | $: quickIsDefault = |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 27 | quick.length === DEFAULT_QUICK_REACTIONS.length && quick.every((r, i) => r.key === DEFAULT_QUICK_REACTIONS[i].key); |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 28 | |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 29 | function themeAccent(): string { |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 30 | return getComputedStyle(document.documentElement).getPropertyValue('--accent').trim() || '#5865f2'; |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 31 | } |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 32 | </script> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 33 | |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 34 | <div class="modal settings" role="dialog" aria-modal="true" aria-label="Settings"> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 35 | <div class="modal-tabs" role="tablist" aria-label="Settings"> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 36 | <button type="button" role="tab" aria-selected="true" class="active">Settings</button> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 37 | <button type="button" class="icon-btn modal-x" aria-label="Close settings" on:click={() => dispatch('close')}> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 38 | <span aria-hidden="true">✕</span> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 39 | </button> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 40 | </div> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 41 | |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 42 | <section aria-label="Theme"> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 43 | <h3 class="sec-h">Theme</h3> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 44 | <div class="themes" role="radiogroup" aria-label="Theme"> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 45 | {#each THEMES as t (t.id)} |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 46 | <button |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 47 | type="button" |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 48 | role="radio" |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 49 | aria-checked={$theme === t.id} |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 50 | class="theme-opt" |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 51 | class:active={$theme === t.id} |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 52 | data-swatch={t.id} |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 53 | on:click={() => theme.set(t.id)} |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 54 | > |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 55 | <span class="swatch" aria-hidden="true"></span> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 56 | {t.label} |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 57 | </button> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 58 | {/each} |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 59 | </div> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 60 | <div class="range accent-row"> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 61 | <label for="accent-colour">Accent colour</label> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 62 | <input id="accent-colour" type="color" value={$accent ?? themeAccent()} on:input={(e) => accent.set(e.currentTarget.value)} /> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 63 | <button type="button" class="ghost-btn" disabled={$accent === null} on:click={() => accent.set(null)}>Use theme colour</button> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 64 | </div> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 65 | </section> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 66 | |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 67 | <section aria-label="Message spacing"> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 68 | <h3 class="sec-h">Space between messages</h3> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 69 | <div class="range"> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 70 | <input |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 71 | type="range" |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 72 | min={MESSAGE_SPACING_MIN} |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 73 | max={MESSAGE_SPACING_MAX} |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 74 | step="1" |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 75 | bind:value={$messageSpacing} |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 76 | aria-label="Space between messages in pixels" |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 77 | /> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 78 | <span class="value">{$messageSpacing}px</span> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 79 | <button |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 80 | type="button" |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 81 | class="ghost-btn" |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 82 | disabled={$messageSpacing === MESSAGE_SPACING_DEFAULT} |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 83 | on:click={() => messageSpacing.set(MESSAGE_SPACING_DEFAULT)} |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 84 | > |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 85 | Reset |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 86 | </button> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 87 | </div> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 88 | <h3 class="sec-h">Line height</h3> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 89 | <div class="range"> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 90 | <input |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 91 | type="range" |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 92 | min={LINE_HEIGHT_MIN} |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 93 | max={LINE_HEIGHT_MAX} |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 94 | step="0.05" |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 95 | bind:value={$lineHeight} |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 96 | aria-label="Line height within messages" |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 97 | /> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 98 | <span class="value">{$lineHeight.toFixed(2)}</span> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 99 | <button |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 100 | type="button" |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 101 | class="ghost-btn" |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 102 | disabled={$lineHeight === LINE_HEIGHT_DEFAULT} |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 103 | on:click={() => lineHeight.set(LINE_HEIGHT_DEFAULT)} |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 104 | > |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 105 | Reset |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 106 | </button> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 107 | </div> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 108 | </section> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 109 | |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 110 | <section aria-label="Quick reactions"> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 111 | <div class="sec-head"> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 112 | <h3 class="sec-h">Quick reactions</h3> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 113 | <button type="button" class="ghost-btn" disabled={quickIsDefault} on:click={() => onQuickChange(DEFAULT_QUICK_REACTIONS)}> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 114 | Reset |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 115 | </button> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 116 | </div> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 117 | <ReactionPicker embedded {quick} {packs} {onQuickChange} onPick={() => {}} onClose={() => dispatch('close')} /> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 118 | </section> |
d095131eec0e | atagen | 2026-10-24 08:39 UTC | 119 | |
d095131eec0e | atagen | 2026-10-24 08:39 UTC | 120 | <section aria-label="Packs"> |
d095131eec0e | atagen | 2026-10-24 08:39 UTC | 121 | <div class="sec-head"> |
d095131eec0e | atagen | 2026-10-24 08:39 UTC | 122 | <h3 class="sec-h">Sticker and emoji packs</h3> |
d095131eec0e | atagen | 2026-10-24 08:39 UTC | 123 | <button type="button" class="ghost-btn" on:click={() => dispatch('packs')}>Manage</button> |
d095131eec0e | atagen | 2026-10-24 08:39 UTC | 124 | </div> |
d095131eec0e | atagen | 2026-10-24 08:39 UTC | 125 | </section> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 126 | </div> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 127 | |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 128 | <style> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 129 | .settings { max-height: calc(100dvh - 32px); overflow-y: auto; } |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 130 | section + section { margin-top: 18px; } |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 131 | .sec-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; } |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 132 | .sec-head .sec-h { margin: 0; } |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 133 | .sec-h { font-size: 12px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--muted); margin: 0 0 6px; } |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 134 | .range + .sec-h { margin-top: 12px; } |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 135 | .range { display: flex; align-items: center; gap: 10px; } |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 136 | .range input[type='range'] { flex: 1; accent-color: var(--accent); } |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 137 | .value { font-size: 13px; min-width: 4ch; text-align: right; font-variant-numeric: tabular-nums; } |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 138 | .themes { display: grid; grid-template-columns: repeat(auto-fill, minmax(118px, 1fr)); gap: 6px; } |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 139 | .theme-opt { |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 140 | display: flex; align-items: center; gap: 8px; |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 141 | padding: 6px 8px; |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 142 | background: var(--bg-soft); |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 143 | border: 1px solid var(--border); |
05a48e9e7942 | atagen | 2026-10-24 09:32 UTC | 144 | border-radius: var(--r-md); |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 145 | color: var(--text); |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 146 | font-size: 13px; |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 147 | cursor: pointer; |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 148 | text-align: left; |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 149 | } |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 150 | .theme-opt.active { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); } |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 151 | .swatch { flex: none; width: 18px; height: 18px; border-radius: 50%; border: 1px solid var(--border); } |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 152 | [data-swatch='system'] .swatch { background: linear-gradient(135deg, #14151c 50%, #f7f7fa 50%); } |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 153 | [data-swatch='dark'] .swatch { background: #14151c; } |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 154 | [data-swatch='light'] .swatch { background: #f7f7fa; } |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 155 | [data-swatch='black'] .swatch { background: #000; } |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 156 | [data-swatch='nord'] .swatch { background: #2e3440; } |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 157 | .accent-row { margin-top: 10px; font-size: 13px; } |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 158 | .accent-row label { flex: 1; } |
05a48e9e7942 | atagen | 2026-10-24 09:32 UTC | 159 | .accent-row input[type='color'] { width: 36px; height: 26px; padding: 0; border: 1px solid var(--border); border-radius: var(--r-sm); background: none; cursor: pointer; } |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 160 | </style> |