refactor(frontend): utility dedup, component splits, dead code removal (#193–#200) #241
@@ -2,6 +2,7 @@
|
|||||||
import { onMount, onDestroy } from 'svelte';
|
import { onMount, onDestroy } from 'svelte';
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import { m } from '$lib/paraglide/messages.js';
|
import { m } from '$lib/paraglide/messages.js';
|
||||||
|
import { clickOutside } from '$lib/actions/clickOutside';
|
||||||
import {
|
import {
|
||||||
type NotificationItem,
|
type NotificationItem,
|
||||||
relativeTime,
|
relativeTime,
|
||||||
@@ -110,21 +111,6 @@ function attachFirstFocusable(node: HTMLButtonElement) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attachment: closes dropdown when clicking outside the wrapper element
|
|
||||||
function attachClickOutside(node: HTMLElement) {
|
|
||||||
const handleClick = (event: MouseEvent) => {
|
|
||||||
if (!node.contains(event.target as Node) && !event.defaultPrevented) {
|
|
||||||
if (open) {
|
|
||||||
open = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
document.addEventListener('click', handleClick, true);
|
|
||||||
return () => {
|
|
||||||
document.removeEventListener('click', handleClick, true);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
fetchUnreadCount();
|
fetchUnreadCount();
|
||||||
eventSource = new EventSource('/api/notifications/stream');
|
eventSource = new EventSource('/api/notifications/stream');
|
||||||
@@ -143,7 +129,7 @@ onDestroy(() => {
|
|||||||
|
|
||||||
<svelte:window onkeydown={handleKeydown} />
|
<svelte:window onkeydown={handleKeydown} />
|
||||||
|
|
||||||
<div class="relative" {@attach attachClickOutside}>
|
<div class="relative" use:clickOutside onclickoutside={() => { if (open) closeDropdown(); }}>
|
||||||
<!-- Bell button -->
|
<!-- Bell button -->
|
||||||
<button
|
<button
|
||||||
{@attach attachBellButton}
|
{@attach attachBellButton}
|
||||||
|
|||||||
Reference in New Issue
Block a user