diff --git a/components/profile-modal.html b/components/profile-modal.html index 50b317e0..64216637 100644 --- a/components/profile-modal.html +++ b/components/profile-modal.html @@ -304,6 +304,14 @@
0
+
diff --git a/js/services/moderationService.js b/js/services/moderationService.js index 0cc17b01..31c0c563 100644 --- a/js/services/moderationService.js +++ b/js/services/moderationService.js @@ -497,6 +497,7 @@ export class ModerationService { this.trustedMuteLists = new Map(); this.trustedMutedAuthors = new Map(); this.trustedMuteSubscriptions = new Map(); + this.trustedSeedOnly = false; this.emitter = new SimpleEventEmitter((message, error) => { try { @@ -549,6 +550,35 @@ export class ModerationService { return merged; } + computeTrustedSeedOnly() { + const trustedContacts = + this.trustedContacts instanceof Set ? this.trustedContacts : new Set(); + const trustedSeedContacts = + this.trustedSeedContacts instanceof Set ? this.trustedSeedContacts : new Set(); + + if (!trustedSeedContacts.size || trustedContacts.size !== trustedSeedContacts.size) { + return false; + } + + for (const value of trustedContacts) { + if (!trustedSeedContacts.has(value)) { + return false; + } + } + + return true; + } + + updateTrustedSeedOnlyStatus() { + const nextValue = this.computeTrustedSeedOnly(); + if (nextValue === this.trustedSeedOnly) { + return; + } + + this.trustedSeedOnly = nextValue; + this.emit("trusted-seed-only", { seedOnly: nextValue }); + } + rebuildTrustedContacts(nextContacts = new Set(), { previous = null } = {}) { const sanitized = new Set(); @@ -580,6 +610,7 @@ export class ModerationService { const seededNext = this.mergeSeedsIntoSet(sanitized); this.trustedContacts = seededNext; + this.updateTrustedSeedOnlyStatus(); this.emit("contacts", { size: seededNext.size }); this.recomputeAllSummaries(); this.reconcileTrustedMuteSubscriptions(previousContacts, seededNext); @@ -681,6 +712,10 @@ export class ModerationService { this.rebuildTrustedContacts(this.viewerContacts, { previous: previousContacts }); } + isTrustedSeedOnly() { + return this.trustedSeedOnly === true; + } + logThresholdTransitions({ eventId = "", reportType = "", diff --git a/js/services/trustBootstrap.js b/js/services/trustBootstrap.js index 24ba4f67..4f029bb5 100644 --- a/js/services/trustBootstrap.js +++ b/js/services/trustBootstrap.js @@ -117,6 +117,9 @@ export async function bootstrapTrustedSeeds() { }); devLogger.info(`[trustBootstrap] Applying ${seeds.size} trusted seeds`, Array.from(seeds)); moderationService.setTrustedSeeds(seeds); + if (typeof moderationService.updateTrustedSeedOnlyStatus === "function") { + moderationService.updateTrustedSeedOnlyStatus(); + } if ( moderationService && typeof moderationService.recomputeAllSummaries === "function" diff --git a/js/ui/profileModalController.js b/js/ui/profileModalController.js index 25d5770e..d8b8d8b6 100644 --- a/js/ui/profileModalController.js +++ b/js/ui/profileModalController.js @@ -1421,6 +1421,8 @@ export class ProfileModalController { document.getElementById("profileModerationTrustedMuteCount") || null; this.moderationTrustedReportCount = document.getElementById("profileModerationTrustedReportCount") || null; + this.moderationSeedOnlyIndicator = + document.getElementById("profileModerationSeedOnlyIndicator") || null; this.moderationHideControlsGroup = this.moderationSettingsCard?.querySelector( "[data-role=\"trusted-hide-controls\"]", @@ -7140,6 +7142,7 @@ export class ProfileModalController { trustedContactsCount: 0, trustedMuteContributors: 0, trustedReportContributors: 0, + trustedSeedOnly: false, }; const service = this.moderationService; @@ -7147,6 +7150,12 @@ export class ProfileModalController { return summary; } + if (typeof service.isTrustedSeedOnly === "function") { + summary.trustedSeedOnly = service.isTrustedSeedOnly(); + } else if (typeof service.trustedSeedOnly === "boolean") { + summary.trustedSeedOnly = service.trustedSeedOnly; + } + const trustedContacts = service.trustedContacts instanceof Set ? service.trustedContacts @@ -7225,7 +7234,8 @@ export class ProfileModalController { if ( !(this.moderationTrustedContactsCount instanceof HTMLElement) && !(this.moderationTrustedMuteCount instanceof HTMLElement) && - !(this.moderationTrustedReportCount instanceof HTMLElement) + !(this.moderationTrustedReportCount instanceof HTMLElement) && + !(this.moderationSeedOnlyIndicator instanceof HTMLElement) ) { return; } @@ -7249,6 +7259,10 @@ export class ProfileModalController { summary.trustedReportContributors, ); } + + if (this.moderationSeedOnlyIndicator instanceof HTMLElement) { + this.moderationSeedOnlyIndicator.hidden = !summary.trustedSeedOnly; + } } async handleModerationSettingsSave() {