feat: move moderation and link preview settings to new Safety tab in Profile modal

- Added 'Safety' tab to `components/profile-modal.html`, positioned before 'Blocked'
- Moved `profileModerationSettings` and `profileLinkPreviewSettings` panels to the new tab
- Updated `ProfileModalController.js` to manage the new tab and initialize settings when selected
- Renamed 'Safety & Moderation' panel header to 'Safety'
This commit is contained in:
google-labs-jules[bot] committed 2026-01-20 01:58:02 +00:00
1 parent 32ae80019a
commit 383a77d6da
2 files changed
+199 -176

No files matched your search

+192 -176
View File
@@ -136,6 +136,15 @@
>
Friends
</button>
<button
id="profileNavSafety"
type="button"
class="btn-ghost focus-ring w-full justify-start gap-2 px-3 py-2 text-xs font-medium"
aria-controls="profilePaneSafety"
aria-selected="false"
>
Safety
</button>
<button
id="profileNavBlocked"
type="button"
@@ -292,182 +301,6 @@
Profiles you add here will stay on this device so you can quickly switch before posting or moderating.
</p>
</div>
<div id="profileModerationSettings" class="card space-y-5 p-5">
<div class="space-y-2">
<h3 class="text-base font-semibold text-text">Safety & Moderation</h3>
<p class="text-sm text-muted">
Choose how many trusted reports or mutes it takes to blur thumbnails, block autoplay previews, or hide videos entirely.
Lower numbers are stricter.
</p>
<div class="rounded-lg border border-border bg-bg-muted p-3 text-xs text-muted">
<p>
Trusted counts include your first-degree follows (F1) plus seeded moderators.
</p>
<dl class="mt-2 grid gap-1">
<div class="flex items-center justify-between gap-3">
<dt>Trusted contacts</dt>
<dd id="profileModerationTrustedContactsCount" class="font-semibold text-text">0</dd>
</div>
<div class="flex items-center justify-between gap-3">
<dt>Active trusted mute contributors</dt>
<dd id="profileModerationTrustedMuteCount" class="font-semibold text-text">0</dd>
</div>
<div class="flex items-center justify-between gap-3">
<dt>Active trusted report contributors</dt>
<dd id="profileModerationTrustedReportCount" class="font-semibold text-text">0</dd>
</div>
</dl>
<p
id="profileModerationSeedOnlyIndicator"
class="mt-2 flex items-center gap-1 text-xs text-warning-strong"
hidden
>
<span aria-hidden="true">●</span>
<span>Seeded moderators only</span>
</p>
</div>
</div>
<div class="grid gap-4 sm:grid-cols-2">
<label
class="block text-sm text-muted-strong"
for="profileModerationBlurThreshold"
>
<span class="mb-2 block font-medium">Blur after trusted reports</span>
<input
id="profileModerationBlurThreshold"
type="number"
inputmode="numeric"
min="0"
step="1"
class="input"
/>
<span class="mt-1 block text-xs text-muted">
Thumbnails blur when trusted contacts report nudity at or above this count.
</span>
</label>
<label
class="block text-sm text-muted-strong"
for="profileModerationAutoplayThreshold"
>
<span class="mb-2 block font-medium">Block autoplay after reports</span>
<input
id="profileModerationAutoplayThreshold"
type="number"
inputmode="numeric"
min="0"
step="1"
class="input"
/>
<span class="mt-1 block text-xs text-muted">
Autoplay previews pause once trusted reports meet this threshold.
</span>
</label>
</div>
<div
class="grid gap-4 sm:grid-cols-2"
data-role="trusted-hide-controls"
>
<label
class="block text-sm text-muted-strong"
for="profileModerationMuteHideThreshold"
data-role="trusted-hide-control"
>
<span class="mb-2 block font-medium">Hide after trusted mutes</span>
<input
id="profileModerationMuteHideThreshold"
type="number"
inputmode="numeric"
min="0"
step="1"
class="input"
/>
<span class="mt-1 block text-xs text-muted">
Hide videos when this many trusted contacts add the author to their mute list.
</span>
</label>
<label
class="block text-sm text-muted-strong"
for="profileModerationSpamHideThreshold"
data-role="trusted-hide-control"
>
<span class="mb-2 block font-medium">Hide after trusted spam reports</span>
<input
id="profileModerationSpamHideThreshold"
type="number"
inputmode="numeric"
min="0"
step="1"
class="input"
/>
<span class="mt-1 block text-xs text-muted">
Hide videos entirely once trusted contacts report spam at or above this count.
</span>
</label>
</div>
<div class="flex flex-wrap items-center gap-3">
<button
id="profileModerationSave"
type="button"
class="btn focus-ring"
disabled
>
Save moderation settings
</button>
<button
id="profileModerationReset"
type="button"
class="btn-ghost focus-ring"
>
Restore defaults
</button>
</div>
<p
id="profileModerationStatus"
class="text-sm text-muted"
role="status"
aria-live="polite"
></p>
<div class="space-y-3 border-t border-border/60 pt-4">
<div class="space-y-1">
<h4 class="text-sm font-semibold text-text">Active overrides</h4>
<p class="text-xs text-muted">
Videos you unblocked with “Show anyway” stay listed here until reset.
</p>
</div>
<div
id="profileModerationOverridesEmpty"
class="card border border-dashed border-border/60 p-4 text-center text-xs text-muted"
>
No moderation overrides yet.
</div>
<ul
id="profileModerationOverridesList"
class="grid-stack hidden"
data-orientation="vertical"
></ul>
</div>
</div>
<div id="profileLinkPreviewSettings" class="card space-y-4 p-5">
<div class="space-y-2">
<h3 class="text-base font-semibold text-text">Link previews</h3>
<p class="text-sm text-muted">
Control when bitvid fetches link preview metadata. Disable auto-fetch to review new domains before previews load.
</p>
</div>
<label
for="profileLinkPreviewAutoToggle"
class="inline-flex items-center gap-2 text-xs font-medium text-muted-strong"
>
<input
id="profileLinkPreviewAutoToggle"
type="checkbox"
class="checkbox"
/>
Auto-fetch previews from new domains
</label>
</div>
</section>
<section
@@ -1028,6 +861,189 @@
<ul id="friendsList" class="grid-stack" data-orientation="vertical"></ul>
</section>
<section
id="profilePaneSafety"
class="profile-pane hidden space-y-6"
role="tabpanel"
aria-labelledby="profileNavSafety"
>
<div id="profileModerationSettings" class="card space-y-5 p-5">
<div class="space-y-2">
<h3 class="text-base font-semibold text-text">Safety</h3>
<p class="text-sm text-muted">
Choose how many trusted reports or mutes it takes to blur thumbnails, block autoplay previews, or hide videos entirely.
Lower numbers are stricter.
</p>
<div class="rounded-lg border border-border bg-bg-muted p-3 text-xs text-muted">
<p>
Trusted counts include your first-degree follows (F1) plus seeded moderators.
</p>
<dl class="mt-2 grid gap-1">
<div class="flex items-center justify-between gap-3">
<dt>Trusted contacts</dt>
<dd id="profileModerationTrustedContactsCount" class="font-semibold text-text">0</dd>
</div>
<div class="flex items-center justify-between gap-3">
<dt>Active trusted mute contributors</dt>
<dd id="profileModerationTrustedMuteCount" class="font-semibold text-text">0</dd>
</div>
<div class="flex items-center justify-between gap-3">
<dt>Active trusted report contributors</dt>
<dd id="profileModerationTrustedReportCount" class="font-semibold text-text">0</dd>
</div>
</dl>
<p
id="profileModerationSeedOnlyIndicator"
class="mt-2 flex items-center gap-1 text-xs text-warning-strong"
hidden
>
<span aria-hidden="true">●</span>
<span>Seeded moderators only</span>
</p>
</div>
</div>
<div class="grid gap-4 sm:grid-cols-2">
<label
class="block text-sm text-muted-strong"
for="profileModerationBlurThreshold"
>
<span class="mb-2 block font-medium">Blur after trusted reports</span>
<input
id="profileModerationBlurThreshold"
type="number"
inputmode="numeric"
min="0"
step="1"
class="input"
/>
<span class="mt-1 block text-xs text-muted">
Thumbnails blur when trusted contacts report nudity at or above this count.
</span>
</label>
<label
class="block text-sm text-muted-strong"
for="profileModerationAutoplayThreshold"
>
<span class="mb-2 block font-medium">Block autoplay after reports</span>
<input
id="profileModerationAutoplayThreshold"
type="number"
inputmode="numeric"
min="0"
step="1"
class="input"
/>
<span class="mt-1 block text-xs text-muted">
Autoplay previews pause once trusted reports meet this threshold.
</span>
</label>
</div>
<div
class="grid gap-4 sm:grid-cols-2"
data-role="trusted-hide-controls"
>
<label
class="block text-sm text-muted-strong"
for="profileModerationMuteHideThreshold"
data-role="trusted-hide-control"
>
<span class="mb-2 block font-medium">Hide after trusted mutes</span>
<input
id="profileModerationMuteHideThreshold"
type="number"
inputmode="numeric"
min="0"
step="1"
class="input"
/>
<span class="mt-1 block text-xs text-muted">
Hide videos when this many trusted contacts add the author to their mute list.
</span>
</label>
<label
class="block text-sm text-muted-strong"
for="profileModerationSpamHideThreshold"
data-role="trusted-hide-control"
>
<span class="mb-2 block font-medium">Hide after trusted spam reports</span>
<input
id="profileModerationSpamHideThreshold"
type="number"
inputmode="numeric"
min="0"
step="1"
class="input"
/>
<span class="mt-1 block text-xs text-muted">
Hide videos entirely once trusted contacts report spam at or above this count.
</span>
</label>
</div>
<div class="flex flex-wrap items-center gap-3">
<button
id="profileModerationSave"
type="button"
class="btn focus-ring"
disabled
>
Save moderation settings
</button>
<button
id="profileModerationReset"
type="button"
class="btn-ghost focus-ring"
>
Restore defaults
</button>
</div>
<p
id="profileModerationStatus"
class="text-sm text-muted"
role="status"
aria-live="polite"
></p>
<div class="space-y-3 border-t border-border/60 pt-4">
<div class="space-y-1">
<h4 class="text-sm font-semibold text-text">Active overrides</h4>
<p class="text-xs text-muted">
Videos you unblocked with “Show anyway” stay listed here until reset.
</p>
</div>
<div
id="profileModerationOverridesEmpty"
class="card border border-dashed border-border/60 p-4 text-center text-xs text-muted"
>
No moderation overrides yet.
</div>
<ul
id="profileModerationOverridesList"
class="grid-stack hidden"
data-orientation="vertical"
></ul>
</div>
</div>
<div id="profileLinkPreviewSettings" class="card space-y-4 p-5">
<div class="space-y-2">
<h3 class="text-base font-semibold text-text">Link previews</h3>
<p class="text-sm text-muted">
Control when bitvid fetches link preview metadata. Disable auto-fetch to review new domains before previews load.
</p>
</div>
<label
for="profileLinkPreviewAutoToggle"
class="inline-flex items-center gap-2 text-xs font-medium text-muted-strong"
>
<input
id="profileLinkPreviewAutoToggle"
type="checkbox"
class="checkbox"
/>
Auto-fetch previews from new domains
</label>
</div>
</section>
<section
id="profilePaneBlocked"
class="profile-pane hidden space-y-4"
+7
View File
@@ -1225,6 +1225,7 @@ export class ProfileModalController {
messages: null,
history: null,
admin: null,
safety: null,
};
this.panes = {
account: null,
@@ -1238,6 +1239,7 @@ export class ProfileModalController {
messages: null,
history: null,
admin: null,
safety: null,
};
this.relayList = null;
this.relayInput = null;
@@ -1512,6 +1514,7 @@ export class ProfileModalController {
this.navButtons.history =
document.getElementById("profileNavHistory") || null;
this.navButtons.admin = document.getElementById("profileNavAdmin") || null;
this.navButtons.safety = document.getElementById("profileNavSafety") || null;
this.profileEditBtn = document.getElementById("profileEditBtn") || null;
this.profileEditBackBtn = document.getElementById("profileEditBackBtn") || null;
@@ -1529,6 +1532,7 @@ export class ProfileModalController {
this.panes.messages = document.getElementById("profilePaneMessages") || null;
this.panes.history = document.getElementById("profilePaneHistory") || null;
this.panes.admin = document.getElementById("profilePaneAdmin") || null;
this.panes.safety = document.getElementById("profilePaneSafety") || null;
this.relayList = document.getElementById("relayList") || null;
this.relayInput = document.getElementById("relayInput") || null;
@@ -6745,6 +6749,9 @@ export class ProfileModalController {
void this.populateSubscriptionsList();
} else if (target === "blocked") {
this.populateBlockedList();
} else if (target === "safety") {
this.refreshModerationSettingsUi();
this.syncLinkPreviewSettingsUi();
}
this.callbacks.onSelectPane(target, { controller: this });