mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 07:52:24 +00:00
Profile dot: show for DMs OR pending admin submissions
The profile-button red dot now lights when the logged-in user has either unseen DMs or (if they can edit admin lists) pending submissions to review. The Messages-nav dot stays DM-only. - applicationBootstrap.js: split indicator state into _dmUnread and _submissionsPending; applyProfileNotificationDot() ORs them for the profile dot. Added refreshSubmissionsIndicator (gated on FEATURE_SUBMISSIONS + canEditAdminLists), a bitvid:submissions-changed listener, a 180s poll, and a startup refresh. - authSessionCoordinator.js: refresh the submissions indicator on auth-login and auth-logout alongside the DM refresh. - submissionsSection.js: emit bitvid:submissions-changed after approve/deny so the dot recomputes for all admins. - check-file-size.mjs: bump authSessionCoordinator grandfather baseline. Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
36cb71b676
commit
ef4191538c
4 files changed
+107
-14
No files matched your search
@@ -237,6 +237,9 @@ export function createAuthSessionCoordinator(deps) {
|
||||
if (typeof this.refreshUnreadDmIndicator === "function") {
|
||||
void this.refreshUnreadDmIndicator({ reason: "auth-login" });
|
||||
}
|
||||
if (typeof this.refreshSubmissionsIndicator === "function") {
|
||||
void this.refreshSubmissionsIndicator({ reason: "auth-login" });
|
||||
}
|
||||
|
||||
const currentView = getHashViewName();
|
||||
const normalizedView =
|
||||
@@ -1043,6 +1046,9 @@ export function createAuthSessionCoordinator(deps) {
|
||||
} else if (this.appChromeController?.setUnreadDmIndicator) {
|
||||
this.appChromeController.setUnreadDmIndicator(false);
|
||||
}
|
||||
if (typeof this.refreshSubmissionsIndicator === "function") {
|
||||
void this.refreshSubmissionsIndicator({ reason: "auth-logout" });
|
||||
}
|
||||
|
||||
const logoutView = getHashViewName();
|
||||
if (
|
||||
|
||||
@@ -83,6 +83,8 @@ import {
|
||||
isDevMode,
|
||||
} from "../config.js";
|
||||
import { ADMIN_INITIAL_EVENT_BLACKLIST } from "../lists.js";
|
||||
import { FEATURE_SUBMISSIONS } from "../constants.js";
|
||||
import { fetchPendingSubmissions } from "../submissions/submissionFacade.js";
|
||||
import {
|
||||
prepareStaticModal,
|
||||
openStaticModal,
|
||||
@@ -858,21 +860,30 @@ export default class ApplicationBootstrap {
|
||||
};
|
||||
|
||||
app.videosMap = app.nostrService.getVideosMap();
|
||||
// The profile-button red dot shows when EITHER there are unread DMs OR (for
|
||||
// admins) there are pending submissions. The Messages nav dot stays DM-only.
|
||||
app._dmUnread = false;
|
||||
app._submissionsPending = false;
|
||||
app.applyProfileNotificationDot = () => {
|
||||
const profileDot = app._dmUnread || app._submissionsPending;
|
||||
if (
|
||||
app.appChromeController &&
|
||||
typeof app.appChromeController.setUnreadDmIndicator === "function"
|
||||
) {
|
||||
app.appChromeController.setUnreadDmIndicator(profileDot);
|
||||
}
|
||||
if (
|
||||
app.profileController &&
|
||||
typeof app.profileController.setMessagesUnreadIndicator === "function"
|
||||
) {
|
||||
app.profileController.setMessagesUnreadIndicator(app._dmUnread);
|
||||
}
|
||||
};
|
||||
|
||||
app.refreshUnreadDmIndicator = async ({ reason = "" } = {}) => {
|
||||
const applyIndicatorState = (visible) => {
|
||||
if (
|
||||
app.appChromeController &&
|
||||
typeof app.appChromeController.setUnreadDmIndicator === "function"
|
||||
) {
|
||||
app.appChromeController.setUnreadDmIndicator(visible);
|
||||
}
|
||||
|
||||
if (
|
||||
app.profileController &&
|
||||
typeof app.profileController.setMessagesUnreadIndicator === "function"
|
||||
) {
|
||||
app.profileController.setMessagesUnreadIndicator(visible);
|
||||
}
|
||||
app._dmUnread = Boolean(visible);
|
||||
app.applyProfileNotificationDot();
|
||||
};
|
||||
|
||||
if (typeof app.isUserLoggedIn === "function" && !app.isUserLoggedIn()) {
|
||||
@@ -929,6 +940,43 @@ export default class ApplicationBootstrap {
|
||||
}
|
||||
};
|
||||
|
||||
// #23: admin-only signal — pending submissions light up the profile dot too.
|
||||
app.refreshSubmissionsIndicator = async ({ reason = "" } = {}) => {
|
||||
let pending = false;
|
||||
try {
|
||||
if (
|
||||
FEATURE_SUBMISSIONS &&
|
||||
typeof app.isUserLoggedIn === "function" &&
|
||||
app.isUserLoggedIn()
|
||||
) {
|
||||
const actorNpub =
|
||||
typeof app.getCurrentUserNpub === "function"
|
||||
? app.getCurrentUserNpub()
|
||||
: "";
|
||||
if (
|
||||
actorNpub &&
|
||||
typeof accessControl.canEditAdminLists === "function" &&
|
||||
accessControl.canEditAdminLists(actorNpub)
|
||||
) {
|
||||
const adminHex = app.safeDecodeNpub(ADMIN_SUPER_NPUB);
|
||||
const editorHexes = Array.from(accessControl.getEditors?.() || [])
|
||||
.map((npub) => app.safeDecodeNpub(npub))
|
||||
.filter(Boolean);
|
||||
const list = await fetchPendingSubmissions({ adminHex, editorHexes });
|
||||
pending = Array.isArray(list) && list.length > 0;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
devLogger.warn(
|
||||
"[Application] Failed to refresh submissions indicator",
|
||||
reason,
|
||||
error,
|
||||
);
|
||||
}
|
||||
app._submissionsPending = pending;
|
||||
app.applyProfileNotificationDot();
|
||||
};
|
||||
|
||||
const nostrUnsubscribes = [];
|
||||
nostrUnsubscribes.push(
|
||||
app.nostrService.on("subscription:changed", ({ subscription }) => {
|
||||
@@ -975,6 +1023,33 @@ export default class ApplicationBootstrap {
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
// #23: keep the admin submissions dot fresh — recompute when one is resolved
|
||||
// (event) and on a light poll (submissions arrive from external users, so
|
||||
// there's no push signal). refreshSubmissionsIndicator no-ops for non-admins.
|
||||
if (typeof document !== "undefined") {
|
||||
const onSubmissionsChanged = () => {
|
||||
void app.refreshSubmissionsIndicator({ reason: "submissions-changed" });
|
||||
};
|
||||
document.addEventListener(
|
||||
"bitvid:submissions-changed",
|
||||
onSubmissionsChanged,
|
||||
);
|
||||
nostrUnsubscribes.push(() =>
|
||||
document.removeEventListener(
|
||||
"bitvid:submissions-changed",
|
||||
onSubmissionsChanged,
|
||||
),
|
||||
);
|
||||
}
|
||||
const submissionsPollId = setInterval(() => {
|
||||
void app.refreshSubmissionsIndicator({ reason: "poll" });
|
||||
}, 180000);
|
||||
if (submissionsPollId && typeof submissionsPollId.unref === "function") {
|
||||
submissionsPollId.unref();
|
||||
}
|
||||
nostrUnsubscribes.push(() => clearInterval(submissionsPollId));
|
||||
void app.refreshSubmissionsIndicator({ reason: "startup" });
|
||||
app.unsubscribeFromNostrService = () => {
|
||||
while (nostrUnsubscribes.length) {
|
||||
const unsubscribe = nostrUnsubscribes.pop();
|
||||
|
||||
@@ -22,6 +22,16 @@ function setLoading(controller, value) {
|
||||
}
|
||||
}
|
||||
|
||||
// Let the app recompute the profile-button "pending submissions" dot after a
|
||||
// moderator approves/denies one.
|
||||
function emitSubmissionsChanged() {
|
||||
try {
|
||||
document.dispatchEvent(new CustomEvent("bitvid:submissions-changed"));
|
||||
} catch (error) {
|
||||
// best effort
|
||||
}
|
||||
}
|
||||
|
||||
export async function populateSubmissions(controller) {
|
||||
if (!FEATURE_SUBMISSIONS || !controller.submissionsList) {
|
||||
return;
|
||||
@@ -214,6 +224,7 @@ async function approveSubmission(controller, submission) {
|
||||
`Approved — ${applicant} added to the whitelist.`,
|
||||
);
|
||||
controller.populateAdminLists();
|
||||
emitSubmissionsChanged();
|
||||
} catch (error) {
|
||||
devLogger.warn("[profileModal] Approve submission failed:", error);
|
||||
controller.mainController.showError?.("Couldn't approve — please try again.");
|
||||
@@ -238,6 +249,7 @@ async function denySubmission(controller, submission) {
|
||||
actingHex: safeDecodeNpub(actorNpub),
|
||||
});
|
||||
controller.mainController.showSuccess?.("Submission dismissed.");
|
||||
emitSubmissionsChanged();
|
||||
} catch (error) {
|
||||
devLogger.warn("[profileModal] Deny submission failed:", error);
|
||||
controller.mainController.showError?.("Couldn't dismiss — please try again.");
|
||||
|
||||
@@ -44,7 +44,7 @@ const GRANDFATHERED = {
|
||||
"js/state/cache.js": 1827,
|
||||
"js/app/feedCoordinator.js": 1857,
|
||||
"js/viewCounter.js": 1023,
|
||||
"js/app/authSessionCoordinator.js": 1803,
|
||||
"js/app/authSessionCoordinator.js": 2008,
|
||||
"js/ui/components/RevertModal.js": 1663,
|
||||
"js/payments/nwcClient.js": 1642,
|
||||
"js/ui/moreMenuController.js": 1601,
|
||||
|
||||
Reference in new issue
Block a user