feat(comments): hide every comment mention when COMMENTS_ENABLED=false
The kill-switch previously left comment UI/text visible in several places. Sweep the whole surface so a comments-off instance shows no trace: Frontend (main app): - VirtualFeed grid tile: gate the comment button/count on $commentsEnabled (was ungated — the only feed surface still showing it). - admin stats: hide the "Kommentare" count card. - UploadSheet "Uploads geschlossen" notice, host ban-modal description, and host/admin unban confirmations: drop the "…und kommentieren" wording. - export page: drop "Kommentaren" from the keepsake description. Keepsake export (had no concept of the flag): - export.rs: thread comments_enabled into the exported data (ViewerEvent), wired through spawn_export_jobs/recover_exports and their call sites (host.rs, main.rs). - export-viewer: gate comment counts (list + grid) and the lightbox comments section; older exports without the field default to enabled (?? true). Backend still 403s comment writes when disabled (unchanged) — this is the UI half so stale clients and archives match. Verified on the running stack (COMMENTS_ENABLED=false): /event reports comments_enabled=false, a regenerated keepsake embeds "comments_enabled": false with no comment UI, and the uploads-closed notice renders "…ansehen und liken." Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,9 @@ export interface ViewerData {
|
||||
event: {
|
||||
name: string;
|
||||
exported_at: string;
|
||||
// Mirrors the live COMMENTS_ENABLED flag. Older exports predate this field, so
|
||||
// treat a missing value as enabled (`?? true`) to preserve their comment UI.
|
||||
comments_enabled?: boolean;
|
||||
};
|
||||
posts: ViewerPost[];
|
||||
}
|
||||
|
||||
@@ -31,6 +31,9 @@
|
||||
|
||||
let posts = $derived(data?.posts ?? []);
|
||||
|
||||
// Mirror the live COMMENTS_ENABLED flag. Missing on older exports → treat as enabled.
|
||||
let commentsEnabled = $derived(data?.event.comments_enabled ?? true);
|
||||
|
||||
let allTags = $derived.by(() => {
|
||||
// eslint-disable-next-line svelte/prefer-svelte-reactivity -- local throwaway counter inside a $derived.by; never stored in $state.
|
||||
const freq = new Map<string, number>();
|
||||
@@ -550,22 +553,24 @@
|
||||
</svg>
|
||||
{post.likes}
|
||||
</span>
|
||||
<span class="flex items-center gap-1.5 text-sm font-medium text-gray-500">
|
||||
<svg
|
||||
class="h-5 w-5"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"
|
||||
/>
|
||||
</svg>
|
||||
{post.comments.length}
|
||||
</span>
|
||||
{#if commentsEnabled}
|
||||
<span class="flex items-center gap-1.5 text-sm font-medium text-gray-500">
|
||||
<svg
|
||||
class="h-5 w-5"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"
|
||||
/>
|
||||
</svg>
|
||||
{post.comments.length}
|
||||
</span>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<!-- Caption -->
|
||||
@@ -641,17 +646,24 @@
|
||||
</svg>
|
||||
{post.likes}
|
||||
</span>
|
||||
<span class="flex items-center gap-0.5">
|
||||
<svg class="h-3.5 w-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"
|
||||
/>
|
||||
</svg>
|
||||
{post.comments.length}
|
||||
</span>
|
||||
{#if commentsEnabled}
|
||||
<span class="flex items-center gap-0.5">
|
||||
<svg
|
||||
class="h-3.5 w-3.5"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"
|
||||
/>
|
||||
</svg>
|
||||
{post.comments.length}
|
||||
</span>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -784,23 +796,25 @@
|
||||
</div>
|
||||
|
||||
<!-- Comments list -->
|
||||
<div class="flex-1 overflow-y-auto p-3">
|
||||
{#if selectedPost.comments.length === 0}
|
||||
<p class="text-center text-sm text-gray-400">Keine Kommentare.</p>
|
||||
{:else}
|
||||
<div class="space-y-3">
|
||||
{#each selectedPost.comments as comment, i (i)}
|
||||
<div>
|
||||
<span class="text-sm font-medium text-gray-900">{comment.author}</span>
|
||||
<span class="ml-1 text-sm text-gray-700">{comment.text}</span>
|
||||
<div class="mt-0.5 text-xs text-gray-400">
|
||||
{formatShortDate(comment.timestamp)}
|
||||
{#if commentsEnabled}
|
||||
<div class="flex-1 overflow-y-auto p-3">
|
||||
{#if selectedPost.comments.length === 0}
|
||||
<p class="text-center text-sm text-gray-400">Keine Kommentare.</p>
|
||||
{:else}
|
||||
<div class="space-y-3">
|
||||
{#each selectedPost.comments as comment, i (i)}
|
||||
<div>
|
||||
<span class="text-sm font-medium text-gray-900">{comment.author}</span>
|
||||
<span class="ml-1 text-sm text-gray-700">{comment.text}</span>
|
||||
<div class="mt-0.5 text-xs text-gray-400">
|
||||
{formatShortDate(comment.timestamp)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user