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:
MechaCat02
2026-07-19 18:26:59 +02:00
parent e1ca9d192f
commit 3fb1b5d80d
11 changed files with 133 additions and 78 deletions

View File

@@ -302,6 +302,7 @@ pub async fn rebuild_export(
r.event_id,
r.event_name,
r.epoch,
state.config.comments_enabled,
std::time::Duration::ZERO,
state.pool.clone(),
state.config.media_path.clone(),
@@ -549,6 +550,7 @@ pub fn start_regen(state: &AppState, regen: crate::services::export::PendingRege
regen.event_id,
regen.event_name,
regen.epoch,
state.config.comments_enabled,
// Debounced: a takedown pass is a burst, and each request retires the last generation. The
// delay lets superseded workers fail their claim and do zero work instead of each building
// a full archive. See export::REGEN_DEBOUNCE.
@@ -753,6 +755,7 @@ pub async fn release_gallery(
event_id,
event_name,
epoch,
state.config.comments_enabled,
std::time::Duration::ZERO,
state.pool.clone(),
state.config.media_path.clone(),

View File

@@ -58,6 +58,7 @@ async fn main() -> Result<()> {
pool.clone(),
config.media_path.clone(),
config.export_path.clone(),
config.comments_enabled,
state.sse_tx.clone(),
)
.await;

View File

@@ -53,6 +53,9 @@ struct ViewerData {
struct ViewerEvent {
name: String,
exported_at: String,
// Mirrors the live COMMENTS_ENABLED flag so the offline keepsake hides all comment
// UI (buttons, counts, sections) when the feature was off for the event.
comments_enabled: bool,
}
#[derive(Serialize)]
@@ -238,6 +241,7 @@ pub async fn recover_exports(
pool: PgPool,
media_path: PathBuf,
export_path: PathBuf,
comments_enabled: bool,
sse_tx: broadcast::Sender<SseEvent>,
) {
let rows = match sqlx::query_as::<_, (Uuid, String, i64)>(
@@ -297,6 +301,7 @@ pub async fn recover_exports(
event_id,
event_name,
epoch,
comments_enabled,
Duration::ZERO,
pool.clone(),
media_path.clone(),
@@ -403,6 +408,7 @@ pub fn spawn_export_jobs(
event_id: Uuid,
event_name: String,
epoch: i64,
comments_enabled: bool,
delay: Duration,
pool: PgPool,
media_path: PathBuf,
@@ -439,6 +445,7 @@ pub fn spawn_export_jobs(
event_id,
epoch,
&event_name2,
comments_enabled,
&pool2,
&media_path2,
&export_path2,
@@ -635,10 +642,12 @@ impl MediaSource {
}
}
#[allow(clippy::too_many_arguments)]
async fn run_html_export(
event_id: Uuid,
epoch: i64,
event_name: &str,
comments_enabled: bool,
pool: &PgPool,
media_path: &Path,
export_path: &Path,
@@ -653,6 +662,7 @@ async fn run_html_export(
epoch,
event_id,
event_name,
comments_enabled,
pool,
media_path,
export_path,
@@ -672,10 +682,12 @@ async fn run_html_export(
abandon_if_superseded("HTML", event_id, epoch, res)
}
#[allow(clippy::too_many_arguments)]
async fn run_html_export_inner(
epoch: i64,
event_id: Uuid,
event_name: &str,
comments_enabled: bool,
pool: &PgPool,
media_path: &Path,
export_path: &Path,
@@ -882,6 +894,7 @@ async fn run_html_export_inner(
event: ViewerEvent {
name: event_name.to_string(),
exported_at: Utc::now().to_rfc3339(),
comments_enabled,
},
posts: viewer_posts,
};

File diff suppressed because one or more lines are too long