mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 07:52:24 +00:00
Clicking the creator avatar/name in the video player modal did nothing. VideoModal
dispatched "navigate:profile", but ModalManager only listens for "creator:navigate"
(→ app.openCreatorChannel), so the event went into the void — same class as the old
action:embed bug noted just above the handler.
Fix:
- VideoModal.handleCreatorNavigation dispatches "creator:navigate" (the listened name)
with { pubkey }.
- ModalManager's handler forwards event.detail.pubkey to app.openCreatorChannel.
- routerCoordinator.openCreatorChannel(pubkey) accepts an optional pubkey (prefers it,
falls back to the active video's creator), so it navigates to the modal's own
creator rather than whatever currentVideo happens to be.
Tests: tests/video-modal-controllers.test.mjs (+2 — dispatches creator:navigate with
the pubkey and never the dead navigate:profile; no-op without a pubkey). Lint + build green.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
95 lines
2.5 KiB
JavaScript
95 lines
2.5 KiB
JavaScript
// js/app/routerCoordinator.js
|
|
|
|
/**
|
|
* Routing logic for the application.
|
|
*
|
|
* All module-level dependencies are injected from the Application
|
|
* composition root rather than imported at module scope.
|
|
*
|
|
* Methods use `this` which is bound to the Application instance.
|
|
*/
|
|
export function createRouterCoordinator(deps) {
|
|
const {
|
|
devLogger,
|
|
} = deps;
|
|
|
|
return {
|
|
goToProfile(pubkey) {
|
|
if (typeof pubkey !== "string") {
|
|
this.showError("No creator info available.");
|
|
return;
|
|
}
|
|
|
|
let candidate = pubkey.trim();
|
|
if (!candidate) {
|
|
this.showError("No creator info available.");
|
|
return;
|
|
}
|
|
|
|
if (candidate.startsWith("nostr:")) {
|
|
candidate = candidate.slice("nostr:".length);
|
|
}
|
|
|
|
const normalizedHex = this.normalizeHexPubkey(candidate);
|
|
const npub = normalizedHex ? this.safeEncodeNpub(normalizedHex) : null;
|
|
|
|
if (!npub) {
|
|
devLogger.warn(
|
|
"[Application] Invalid pubkey for profile navigation:",
|
|
candidate,
|
|
);
|
|
this.showError("Invalid creator profile.");
|
|
return;
|
|
}
|
|
|
|
window.location.hash = `#view=channel-profile&npub=${npub}`;
|
|
},
|
|
|
|
openCreatorChannel(pubkey) {
|
|
// Prefer an explicit pubkey (e.g. the video modal's own creator) and fall
|
|
// back to the active video's creator.
|
|
const targetPubkey =
|
|
(typeof pubkey === "string" && pubkey.trim()) ||
|
|
this.currentVideo?.pubkey ||
|
|
"";
|
|
if (!targetPubkey) {
|
|
this.showError("No creator info available.");
|
|
return;
|
|
}
|
|
|
|
try {
|
|
// Encode the hex pubkey to npub
|
|
const npub = window.NostrTools.nip19.npubEncode(targetPubkey);
|
|
|
|
// Close the video modal
|
|
this.hideModal();
|
|
|
|
// Switch to channel profile view
|
|
window.location.hash = `#view=channel-profile&npub=${npub}`;
|
|
} catch (err) {
|
|
devLogger.error("Failed to open creator channel:", err);
|
|
this.showError("Could not open channel.");
|
|
}
|
|
},
|
|
|
|
handleProfileChannelLink(element) {
|
|
if (!(element instanceof HTMLElement)) {
|
|
return;
|
|
}
|
|
|
|
const targetNpub =
|
|
typeof element.dataset.targetNpub === "string"
|
|
? element.dataset.targetNpub
|
|
: "";
|
|
if (this.profileController) {
|
|
this.profileController.hide();
|
|
}
|
|
if (targetNpub) {
|
|
window.location.hash = `#view=channel-profile&npub=${encodeURIComponent(
|
|
targetNpub,
|
|
)}`;
|
|
}
|
|
}
|
|
};
|
|
}
|