mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-11-05 20:32:27 +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
@@ -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();
|
||||
|
||||
Reference in new issue
Block a user