diff --git a/web/boneyard.config.json b/web/boneyard.config.json index a151052b1..de7419e33 100644 --- a/web/boneyard.config.json +++ b/web/boneyard.config.json @@ -126,6 +126,12 @@ }, "ui-toggle--checked": { "route": "/iframe.html?id=ui-toggle--checked&viewMode=story" + }, + "notifications-notificationlist--skeleton-fixture": { + "route": "/iframe.html?id=notifications-notificationlist--skeleton-fixture&viewMode=story" + }, + "notifications-notificationlist--social-skeleton-fixture": { + "route": "/iframe.html?id=notifications-notificationlist--social-skeleton-fixture&viewMode=story" } } } diff --git a/web/src/lib/bones/notifications-notificationlist--skeleton-fixture.bones.json b/web/src/lib/bones/notifications-notificationlist--skeleton-fixture.bones.json new file mode 100644 index 000000000..749495378 --- /dev/null +++ b/web/src/lib/bones/notifications-notificationlist--skeleton-fixture.bones.json @@ -0,0 +1,153 @@ +{ + "breakpoints": { + "375": { + "name": "notifications-notificationlist--skeleton-fixture", + "viewportWidth": 343, + "width": 343, + "height": 420, + "bones": [ + [0, 0, 100, 420, 4, true, 15, false], + [0.2915, 1, 99.4169, 37, 0, true, 4, true], + [2.6239, 11, 8.8101, 15, 4], + [2.6239, 48, 10.1084, 15, 4], + [0.2915, 75, 99.4169, 77, 0, true, 4, true], + [2.6239, 94, 4.0816, 14, 0], + [16.3129, 91, 61.6481, 20, 4], + [84.8943, 93, 12.4818, 15, 4], + [2.6239, 117, 9.0242, 15, 4], + [16.3129, 117, 73.7655, 15, 4], + [0.2915, 152, 99.4169, 77, 0, true, 4, true], + [2.6239, 171, 4.0816, 14, 0], + [16.3129, 168, 61.6481, 20, 4], + [82.6257, 170, 14.7504, 15, 4], + [2.6239, 194, 9.0242, 15, 4], + [16.3129, 194, 67.2148, 15, 4], + [0.2915, 229, 99.4169, 77, 0, true, 4, true], + [2.6239, 248, 4.0816, 14, 0], + [16.3129, 245, 61.6481, 20, 4], + [85.8874, 247, 11.4887, 15, 4], + [2.6239, 271, 6.7556, 15, 4], + [16.3129, 271, 70.0255, 15, 4], + [2.6239, 316, 16.7638, 15, 4], + [0.2915, 343, 99.4169, 76, 0, true, 0, true], + [2.6239, 362, 4.0816, 14, 0], + [16.3129, 359, 61.6481, 20, 4], + [85.8145, 361, 11.5616, 15, 4], + [2.6239, 385, 9.0242, 15, 4], + [16.3129, 385, 69.9982, 15, 4] + ] + }, + "768": { + "name": "notifications-notificationlist--skeleton-fixture", + "viewportWidth": 480, + "width": 480, + "height": 420, + "bones": [ + [0, 0, 100, 420, 4, true, 15, false], + [0.2083, 1, 99.5833, 37, 0, true, 4, true], + [3.5417, 11, 6.2956, 15, 4], + [3.5417, 48, 7.2233, 15, 4], + [0.2083, 75, 99.5833, 77, 0, true, 4, true], + [3.5417, 94, 2.9167, 14, 0], + [13.3236, 91, 69.2611, 20, 4], + [87.5391, 93, 8.9193, 15, 4], + [3.5417, 117, 6.4486, 15, 4], + [13.3236, 117, 52.7116, 15, 4], + [0.2083, 152, 99.5833, 77, 0, true, 4, true], + [3.5417, 171, 2.9167, 14, 0], + [13.3236, 168, 61.1198, 20, 4], + [85.918, 170, 10.5404, 15, 4], + [3.5417, 194, 6.4486, 15, 4], + [13.3236, 194, 48.0306, 15, 4], + [0.2083, 229, 99.5833, 77, 0, true, 4, true], + [3.5417, 248, 2.9167, 14, 0], + [13.3236, 245, 69.2611, 20, 4], + [88.2487, 247, 8.2096, 15, 4], + [3.5417, 271, 4.8275, 15, 4], + [13.3236, 271, 50.0391, 15, 4], + [3.5417, 316, 11.9792, 15, 4], + [0.2083, 343, 99.5833, 76, 0, true, 0, true], + [3.5417, 362, 2.9167, 14, 0], + [13.3236, 359, 69.2611, 20, 4], + [88.1966, 361, 8.2617, 15, 4], + [3.5417, 385, 6.4486, 15, 4], + [13.3236, 385, 50.0195, 15, 4] + ] + }, + "1024": { + "name": "notifications-notificationlist--skeleton-fixture", + "viewportWidth": 480, + "width": 480, + "height": 420, + "bones": [ + [0, 0, 100, 420, 4, true, 15, false], + [0.2083, 1, 99.5833, 37, 0, true, 4, true], + [3.5417, 11, 6.2956, 15, 4], + [3.5417, 48, 7.2233, 15, 4], + [0.2083, 75, 99.5833, 77, 0, true, 4, true], + [3.5417, 94, 2.9167, 14, 0], + [13.3236, 91, 69.2611, 20, 4], + [87.5391, 93, 8.9193, 15, 4], + [3.5417, 117, 6.4486, 15, 4], + [13.3236, 117, 52.7116, 15, 4], + [0.2083, 152, 99.5833, 77, 0, true, 4, true], + [3.5417, 171, 2.9167, 14, 0], + [13.3236, 168, 61.1198, 20, 4], + [85.918, 170, 10.5404, 15, 4], + [3.5417, 194, 6.4486, 15, 4], + [13.3236, 194, 48.0306, 15, 4], + [0.2083, 229, 99.5833, 77, 0, true, 4, true], + [3.5417, 248, 2.9167, 14, 0], + [13.3236, 245, 69.2611, 20, 4], + [88.2487, 247, 8.2096, 15, 4], + [3.5417, 271, 4.8275, 15, 4], + [13.3236, 271, 50.0391, 15, 4], + [3.5417, 316, 11.9792, 15, 4], + [0.2083, 343, 99.5833, 76, 0, true, 0, true], + [3.5417, 362, 2.9167, 14, 0], + [13.3236, 359, 69.2611, 20, 4], + [88.1966, 361, 8.2617, 15, 4], + [3.5417, 385, 6.4486, 15, 4], + [13.3236, 385, 50.0195, 15, 4] + ] + }, + "1440": { + "name": "notifications-notificationlist--skeleton-fixture", + "viewportWidth": 480, + "width": 480, + "height": 420, + "bones": [ + [0, 0, 100, 420, 4, true, 15, false], + [0.2083, 1, 99.5833, 37, 0, true, 4, true], + [3.5417, 11, 6.2956, 15, 4], + [3.5417, 48, 7.2233, 15, 4], + [0.2083, 75, 99.5833, 77, 0, true, 4, true], + [3.5417, 94, 2.9167, 14, 0], + [13.3236, 91, 69.2611, 20, 4], + [87.5391, 93, 8.9193, 15, 4], + [3.5417, 117, 6.4486, 15, 4], + [13.3236, 117, 52.7116, 15, 4], + [0.2083, 152, 99.5833, 77, 0, true, 4, true], + [3.5417, 171, 2.9167, 14, 0], + [13.3236, 168, 61.1198, 20, 4], + [85.918, 170, 10.5404, 15, 4], + [3.5417, 194, 6.4486, 15, 4], + [13.3236, 194, 48.0306, 15, 4], + [0.2083, 229, 99.5833, 77, 0, true, 4, true], + [3.5417, 248, 2.9167, 14, 0], + [13.3236, 245, 69.2611, 20, 4], + [88.2487, 247, 8.2096, 15, 4], + [3.5417, 271, 4.8275, 15, 4], + [13.3236, 271, 50.0391, 15, 4], + [3.5417, 316, 11.9792, 15, 4], + [0.2083, 343, 99.5833, 76, 0, true, 0, true], + [3.5417, 362, 2.9167, 14, 0], + [13.3236, 359, 69.2611, 20, 4], + [88.1966, 361, 8.2617, 15, 4], + [3.5417, 385, 6.4486, 15, 4], + [13.3236, 385, 50.0195, 15, 4] + ] + } + }, + "_hash": "687e3edab88b2b8f70d0566af9c0ae4e" +} diff --git a/web/src/lib/bones/notifications-notificationlist--social-skeleton-fixture.bones.json b/web/src/lib/bones/notifications-notificationlist--social-skeleton-fixture.bones.json new file mode 100644 index 000000000..595df4b67 --- /dev/null +++ b/web/src/lib/bones/notifications-notificationlist--social-skeleton-fixture.bones.json @@ -0,0 +1,157 @@ +{ + "breakpoints": { + "375": { + "name": "notifications-notificationlist--social-skeleton-fixture", + "viewportWidth": 343, + "width": 343, + "height": 467, + "bones": [ + [0, 0, 100, 467, 4, true, 15, false], + [0.2915, 1, 99.4169, 37, 0, true, 4, true], + [2.6239, 11, 10.2633, 15, 4], + [2.6239, 48, 10.1084, 15, 4], + [0.2915, 75, 99.4169, 53, 0, true, 4, true], + [2.6239, 94, 4.0816, 14, 0], + [11.3703, 91, 66.5907, 20, 4], + [82.6257, 93, 14.7504, 15, 4], + [0.2915, 128, 99.4169, 53, 0, true, 4, true], + [2.6239, 147, 4.0816, 14, 0], + [11.3703, 144, 53.8356, 20, 4], + [85.8874, 146, 11.4887, 15, 4], + [2.6239, 191, 16.7638, 15, 4], + [0.2915, 218, 99.4169, 53, 0, true, 4, true], + [2.6239, 237, 4.0816, 14, 0], + [11.3703, 234, 50.0774, 20, 4], + [85.8145, 236, 11.5616, 15, 4], + [0.2915, 271, 99.4169, 53, 0, true, 4, true], + [2.6239, 290, 4.0816, 14, 0], + [11.3703, 287, 66.5907, 20, 4], + [85.8145, 289, 11.5616, 15, 4], + [2.6239, 334, 9.088, 15, 4], + [0.2915, 361, 99.4169, 53, 0, true, 4, true], + [2.6239, 380, 4.0816, 14, 0], + [11.3703, 377, 52.5966, 20, 4], + [85.0948, 379, 12.2813, 15, 4], + [0.2915, 414, 99.4169, 52, 0, true, 0, true], + [2.6239, 433, 4.0816, 14, 0], + [11.3703, 430, 50.9885, 20, 4], + [85.0948, 432, 12.2813, 15, 4] + ] + }, + "768": { + "name": "notifications-notificationlist--social-skeleton-fixture", + "viewportWidth": 480, + "width": 480, + "height": 467, + "bones": [ + [0, 0, 100, 467, 4, true, 15, false], + [0.2083, 1, 99.5833, 37, 0, true, 4, true], + [3.5417, 11, 7.334, 15, 4], + [3.5417, 48, 7.2233, 15, 4], + [0.2083, 75, 99.5833, 53, 0, true, 4, true], + [3.5417, 94, 2.9167, 14, 0], + [9.7917, 91, 52.3307, 20, 4], + [85.918, 93, 10.5404, 15, 4], + [0.2083, 128, 99.5833, 53, 0, true, 4, true], + [3.5417, 147, 2.9167, 14, 0], + [9.7917, 144, 38.4701, 20, 4], + [88.2487, 146, 8.2096, 15, 4], + [3.5417, 191, 11.9792, 15, 4], + [0.2083, 218, 99.5833, 53, 0, true, 4, true], + [3.5417, 237, 2.9167, 14, 0], + [9.7917, 234, 35.7845, 20, 4], + [88.1966, 236, 8.2617, 15, 4], + [0.2083, 271, 99.5833, 53, 0, true, 4, true], + [3.5417, 290, 2.9167, 14, 0], + [9.7917, 287, 48.9355, 20, 4], + [88.1966, 289, 8.2617, 15, 4], + [3.5417, 334, 6.4941, 15, 4], + [0.2083, 361, 99.5833, 53, 0, true, 4, true], + [3.5417, 380, 2.9167, 14, 0], + [9.7917, 377, 37.5846, 20, 4], + [87.6823, 379, 8.776, 15, 4], + [0.2083, 414, 99.5833, 52, 0, true, 0, true], + [3.5417, 433, 2.9167, 14, 0], + [9.7917, 430, 36.4355, 20, 4], + [87.6823, 432, 8.776, 15, 4] + ] + }, + "1024": { + "name": "notifications-notificationlist--social-skeleton-fixture", + "viewportWidth": 480, + "width": 480, + "height": 467, + "bones": [ + [0, 0, 100, 467, 4, true, 15, false], + [0.2083, 1, 99.5833, 37, 0, true, 4, true], + [3.5417, 11, 7.334, 15, 4], + [3.5417, 48, 7.2233, 15, 4], + [0.2083, 75, 99.5833, 53, 0, true, 4, true], + [3.5417, 94, 2.9167, 14, 0], + [9.7917, 91, 52.3307, 20, 4], + [85.918, 93, 10.5404, 15, 4], + [0.2083, 128, 99.5833, 53, 0, true, 4, true], + [3.5417, 147, 2.9167, 14, 0], + [9.7917, 144, 38.4701, 20, 4], + [88.2487, 146, 8.2096, 15, 4], + [3.5417, 191, 11.9792, 15, 4], + [0.2083, 218, 99.5833, 53, 0, true, 4, true], + [3.5417, 237, 2.9167, 14, 0], + [9.7917, 234, 35.7845, 20, 4], + [88.1966, 236, 8.2617, 15, 4], + [0.2083, 271, 99.5833, 53, 0, true, 4, true], + [3.5417, 290, 2.9167, 14, 0], + [9.7917, 287, 48.9355, 20, 4], + [88.1966, 289, 8.2617, 15, 4], + [3.5417, 334, 6.4941, 15, 4], + [0.2083, 361, 99.5833, 53, 0, true, 4, true], + [3.5417, 380, 2.9167, 14, 0], + [9.7917, 377, 37.5846, 20, 4], + [87.6823, 379, 8.776, 15, 4], + [0.2083, 414, 99.5833, 52, 0, true, 0, true], + [3.5417, 433, 2.9167, 14, 0], + [9.7917, 430, 36.4355, 20, 4], + [87.6823, 432, 8.776, 15, 4] + ] + }, + "1440": { + "name": "notifications-notificationlist--social-skeleton-fixture", + "viewportWidth": 480, + "width": 480, + "height": 467, + "bones": [ + [0, 0, 100, 467, 4, true, 15, false], + [0.2083, 1, 99.5833, 37, 0, true, 4, true], + [3.5417, 11, 7.334, 15, 4], + [3.5417, 48, 7.2233, 15, 4], + [0.2083, 75, 99.5833, 53, 0, true, 4, true], + [3.5417, 94, 2.9167, 14, 0], + [9.7917, 91, 52.3307, 20, 4], + [85.918, 93, 10.5404, 15, 4], + [0.2083, 128, 99.5833, 53, 0, true, 4, true], + [3.5417, 147, 2.9167, 14, 0], + [9.7917, 144, 38.4701, 20, 4], + [88.2487, 146, 8.2096, 15, 4], + [3.5417, 191, 11.9792, 15, 4], + [0.2083, 218, 99.5833, 53, 0, true, 4, true], + [3.5417, 237, 2.9167, 14, 0], + [9.7917, 234, 35.7845, 20, 4], + [88.1966, 236, 8.2617, 15, 4], + [0.2083, 271, 99.5833, 53, 0, true, 4, true], + [3.5417, 290, 2.9167, 14, 0], + [9.7917, 287, 48.9355, 20, 4], + [88.1966, 289, 8.2617, 15, 4], + [3.5417, 334, 6.4941, 15, 4], + [0.2083, 361, 99.5833, 53, 0, true, 4, true], + [3.5417, 380, 2.9167, 14, 0], + [9.7917, 377, 37.5846, 20, 4], + [87.6823, 379, 8.776, 15, 4], + [0.2083, 414, 99.5833, 52, 0, true, 0, true], + [3.5417, 433, 2.9167, 14, 0], + [9.7917, 430, 36.4355, 20, 4], + [87.6823, 432, 8.776, 15, 4] + ] + } + }, + "_hash": "ceb4af4a2bcd8c341e83d69ee19ade7c" +} diff --git a/web/src/lib/components/notifications/NotificationBell.svelte b/web/src/lib/components/notifications/NotificationBell.svelte index 49209adf3..da70b37c5 100644 --- a/web/src/lib/components/notifications/NotificationBell.svelte +++ b/web/src/lib/components/notifications/NotificationBell.svelte @@ -170,6 +170,7 @@ + + + {#snippet template(args)} + + {/snippet} + + + + {#snippet template(args)} + + {/snippet} + + + + {#snippet template()} + + {/snippet} + + + diff --git a/web/src/lib/components/notifications/NotificationList.svelte b/web/src/lib/components/notifications/NotificationList.svelte index e42dc15b7..a0870b0e7 100644 --- a/web/src/lib/components/notifications/NotificationList.svelte +++ b/web/src/lib/components/notifications/NotificationList.svelte @@ -3,27 +3,32 @@ import Inbox from "$icon/inbox"; import EmptyState from "$lib/components/ui/EmptyState.svelte"; import NotificationItem from "$lib/components/notifications/NotificationItem.svelte"; + import notificationsNotificationlistSkeletonFixture from "$lib/bones/notifications-notificationlist--skeleton-fixture.bones.json"; + import notificationsSociallistSkeletonFixture from "$lib/bones/notifications-notificationlist--social-skeleton-fixture.bones.json"; + import Bones from "$lib/components/ui/Bones.svelte"; import { groupNotificationsByDate } from "$lib/components/notifications/notification"; import { formatCount } from "$lib/format"; import type { NotificationSummary, ReadFilter } from "$lib/components/notifications/types"; interface Props { - notifications: NotificationSummary[]; + notifications?: NotificationSummary[]; title?: string; unreadCount?: number; readFilter?: ReadFilter; border?: boolean; grouped?: boolean; + loading?: boolean; onToggleRead?: (uri: string, read: boolean) => void; } let { - notifications, + notifications = [], title, unreadCount = 0, readFilter = "inbox", border = true, grouped = true, + loading = false, onToggleRead }: Props = $props(); @@ -41,60 +46,70 @@ ); - -
- {#if title || unreadCount > 0} -
-

- {title} -

- {#if unreadCount > 0} - +
+ {#if title || unreadCount > 0} +
+

- {formatCount(unreadCount)} - - {/if} -

- {/if} - - {#if empty} -
- -
- {:else} - {#each sections as section (section.label)} - {#if section.items.length > 0} - {#if section.label} -
+ {#if unreadCount > 0} + - {section.label} -
+ {formatCount(unreadCount)} + + {/if} +
+ {/if} + + {#if empty} +
+ +
+ {:else} + {#each sections as section (section.label)} + {#if section.items.length > 0} + {#if section.label} +
+ {section.label} +
+ {/if} + {#each section.items as notification (notification.uri)} + + {/each} {/if} - {#each section.items as notification (notification.uri)} - - {/each} - {/if} - {/each} - {/if} -
+ {/each} + {/if} +
+{/if} diff --git a/web/src/lib/components/notifications/mock.ts b/web/src/lib/components/notifications/mock.ts index f35657d8b..ea3525902 100644 --- a/web/src/lib/components/notifications/mock.ts +++ b/web/src/lib/components/notifications/mock.ts @@ -246,5 +246,30 @@ export const notifications: NotificationSummary[] = [ number: "180", title: "camo: cache remote images for a week" } + }, + { + uri: `at://mock/notif/20`, + id: 20, + type: "followed", + read: true, + createdAt: ago(60 * 24 * 7), + actor: { did: "did:plc:mock_sophie", handle: "sophies.rocks" } + }, + { + uri: `at://mock/notif/21`, + id: 21, + type: "followed", + read: true, + createdAt: ago(60 * 24 * 7), + actor: { did: "did:plc:mock_karitham", handle: "karitham.dev" } + }, + { + uri: `at://mock/notif/22`, + id: 22, + type: "repo_starred", + read: true, + createdAt: ago(60 * 24 * 14), + actor: { did: "did:plc:mock_jola", handle: "jola.dev" }, + repo: { ownerHandle: "ptr.pet", name: "hydrant" } } ]; diff --git a/web/src/routes/notifications/+page.svelte b/web/src/routes/notifications/+page.svelte index 5896be18c..07cc3b087 100644 --- a/web/src/routes/notifications/+page.svelte +++ b/web/src/routes/notifications/+page.svelte @@ -11,6 +11,7 @@ import NotificationToolbar from "$lib/components/notifications/NotificationToolbar.svelte"; import { notificationCategory } from "$lib/components/notifications/notification"; import type { NotificationSummary } from "$lib/components/notifications/types"; + import ErrorAlert from "$lib/components/ui/Error.svelte"; import { getAuth } from "$lib/auth.svelte"; import { createLoad } from "$lib/action.svelte"; import type { PageData } from "./$types"; @@ -25,10 +26,13 @@ let overrides = $state>({}); const loaded = createLoad(async () => { - const agent = auth.agent; + const did = auth.currentDid; + if (!did) return []; + + const agent = auth.agent ?? (await auth.agentFor(did)); const deliberiUrl = data.deliberiUrl; const bobbinUrl = data.bobbinUrl; - if (!agent || !deliberiUrl || !bobbinUrl) throw new Error("Not ready"); + if (!agent || !deliberiUrl || !bobbinUrl) return []; const deliberi = createDeliberiClient({ deliberiUrl, agent }); const bobbin = createBobbinClient({ serviceUrl: bobbinUrl }); @@ -39,6 +43,9 @@ }); return hydrateNotifications(bobbin, result.notifications); }); + + const loading = $derived(loaded.loading || !loaded.data); + const all = $derived( (loaded.data ?? []).map((n) => (n.uri in overrides ? { ...n, read: overrides[n.uri] } : n)) ); @@ -96,12 +103,15 @@ 0} + hasNotifications={loading ? false : visible.length > 0} onMarkAllRead={markAllRead} /> + +