mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-11-06 04:42:57 +00:00
refactor(ai): extract VideoModalController from js/app.js (agent)
Co-authored-by: PR0M3TH3AN <[email protected]>
This commit is contained in:
1 parent
73c705831b
commit
3dfba92e04
3 files changed
+332
-148
No files matched your search
@@ -0,0 +1,202 @@
|
||||
import { devLogger } from "../utils/logger.js";
|
||||
|
||||
export default class VideoModalController {
|
||||
constructor({
|
||||
getVideoModal,
|
||||
callbacks: {
|
||||
showError,
|
||||
getLastModalTrigger,
|
||||
setLastModalTrigger,
|
||||
getCurrentVideo,
|
||||
} = {},
|
||||
}) {
|
||||
this.getVideoModal = getVideoModal;
|
||||
this.showError = showError;
|
||||
this.getLastModalTrigger = getLastModalTrigger;
|
||||
this.setLastModalTrigger = setLastModalTrigger;
|
||||
this.getCurrentVideo = getCurrentVideo;
|
||||
|
||||
this.videoModalReadyPromise = null;
|
||||
}
|
||||
|
||||
get videoModal() {
|
||||
return this.getVideoModal ? this.getVideoModal() : null;
|
||||
}
|
||||
|
||||
log(message, ...args) {
|
||||
devLogger.log("[VideoModalController]", message, ...args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the modal and set the "Please stand by" poster on the video.
|
||||
*/
|
||||
async showModalWithPoster(video = null, options = {}) {
|
||||
if (!this.videoModal) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (Object.prototype.hasOwnProperty.call(options || {}, "trigger")) {
|
||||
if (this.setLastModalTrigger) {
|
||||
this.setLastModalTrigger(options.trigger);
|
||||
}
|
||||
}
|
||||
|
||||
const targetVideo =
|
||||
video || (this.getCurrentVideo ? this.getCurrentVideo() : null);
|
||||
if (!targetVideo) {
|
||||
this.log("Skipping video modal open; no target video is available.");
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
const { root } = await this.ensureVideoModalReady({
|
||||
ensureVideoElement: true,
|
||||
});
|
||||
|
||||
if (!this.videoModal) {
|
||||
return root || null;
|
||||
}
|
||||
|
||||
const trigger = this.getLastModalTrigger
|
||||
? this.getLastModalTrigger()
|
||||
: null;
|
||||
this.videoModal.open(targetVideo, {
|
||||
triggerElement: trigger,
|
||||
});
|
||||
this.applyModalLoadingPoster();
|
||||
|
||||
return (
|
||||
root ||
|
||||
(typeof this.videoModal.getRoot === "function"
|
||||
? this.videoModal.getRoot()
|
||||
: null)
|
||||
);
|
||||
} catch (error) {
|
||||
devLogger.error(
|
||||
"[VideoModalController] Failed to open the video modal before playback:",
|
||||
error,
|
||||
);
|
||||
if (this.showError) {
|
||||
this.showError("Could not open the video player. Please try again.");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
applyModalLoadingPoster() {
|
||||
if (!this.videoModal) {
|
||||
return;
|
||||
}
|
||||
this.videoModal.applyLoadingPoster();
|
||||
}
|
||||
|
||||
forceRemoveModalPoster(reason = "manual-clear") {
|
||||
if (!this.videoModal) {
|
||||
return false;
|
||||
}
|
||||
return this.videoModal.forceRemovePoster(reason);
|
||||
}
|
||||
|
||||
async ensureVideoModalReady({ ensureVideoElement = false } = {}) {
|
||||
if (!this.videoModal) {
|
||||
throw new Error("Video modal instance is not available.");
|
||||
}
|
||||
|
||||
const getRoot = () =>
|
||||
typeof this.videoModal.getRoot === "function"
|
||||
? this.videoModal.getRoot()
|
||||
: null;
|
||||
const getVideoElement = () =>
|
||||
typeof this.videoModal.getVideoElement === "function"
|
||||
? this.videoModal.getVideoElement()
|
||||
: null;
|
||||
|
||||
const existingRoot = getRoot();
|
||||
const existingVideoElement = getVideoElement();
|
||||
const rootConnected = Boolean(existingRoot && existingRoot.isConnected);
|
||||
const hasVideoElement = Boolean(existingVideoElement);
|
||||
const videoConnected = Boolean(
|
||||
existingVideoElement && existingVideoElement.isConnected,
|
||||
);
|
||||
|
||||
const needsRehydrate =
|
||||
!rootConnected || !hasVideoElement || !videoConnected;
|
||||
|
||||
if (!needsRehydrate) {
|
||||
if (
|
||||
existingVideoElement &&
|
||||
this.videoModal &&
|
||||
typeof this.videoModal.setVideoElement === "function"
|
||||
) {
|
||||
const currentModalVideo =
|
||||
typeof this.videoModal.getVideoElement === "function"
|
||||
? this.videoModal.getVideoElement()
|
||||
: null;
|
||||
if (currentModalVideo !== existingVideoElement) {
|
||||
this.videoModal.setVideoElement(existingVideoElement);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
root: existingRoot,
|
||||
videoElement: existingVideoElement,
|
||||
};
|
||||
}
|
||||
|
||||
if (!videoConnected) {
|
||||
if (
|
||||
this.videoModal &&
|
||||
typeof this.videoModal.setVideoElement === "function"
|
||||
) {
|
||||
this.videoModal.setVideoElement(null);
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.videoModalReadyPromise) {
|
||||
if (typeof this.videoModal.load !== "function") {
|
||||
throw new Error("Video modal does not expose a load() method.");
|
||||
}
|
||||
this.videoModalReadyPromise = Promise.resolve(this.videoModal.load());
|
||||
}
|
||||
|
||||
try {
|
||||
await this.videoModalReadyPromise;
|
||||
} catch (error) {
|
||||
this.videoModalReadyPromise = null;
|
||||
throw error;
|
||||
}
|
||||
|
||||
this.videoModalReadyPromise = null;
|
||||
|
||||
const readyRoot = getRoot();
|
||||
const readyVideoElement = getVideoElement();
|
||||
const readyVideoConnected = Boolean(
|
||||
readyVideoElement && readyVideoElement.isConnected,
|
||||
);
|
||||
|
||||
if (readyVideoConnected) {
|
||||
if (
|
||||
this.videoModal &&
|
||||
typeof this.videoModal.setVideoElement === "function"
|
||||
) {
|
||||
this.videoModal.setVideoElement(readyVideoElement);
|
||||
}
|
||||
} else {
|
||||
if (
|
||||
this.videoModal &&
|
||||
typeof this.videoModal.setVideoElement === "function"
|
||||
) {
|
||||
this.videoModal.setVideoElement(null);
|
||||
}
|
||||
}
|
||||
|
||||
if (ensureVideoElement && !readyVideoConnected) {
|
||||
throw new Error("Video modal video element is missing after load().");
|
||||
}
|
||||
|
||||
return {
|
||||
root: readyRoot,
|
||||
videoElement: readyVideoConnected ? readyVideoElement : null,
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user