Skip to content

Commit

Permalink
fix: workaround for broken await/async support in Jellyfin Web
Browse files Browse the repository at this point in the history
To-be removed if the issue is fixed in the core, but for now we'll have this ugly workaround.
  • Loading branch information
revam committed Sep 29, 2024
1 parent 2e842b5 commit 2ba25c1
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 13 deletions.
50 changes: 47 additions & 3 deletions Shokofin/Pages/Scripts/Common.js
Original file line number Diff line number Diff line change
Expand Up @@ -737,9 +737,11 @@ const Messages = {
* @param {HTMLDivElement} view - The view element.
* @param {ViewLifecycleEvents} events - The events.
* @param {TabType} [initialTab] - The initial tab.
* @param {boolean} [hide] - Whether to hide the view immediately.
* @param {boolean} [show] - Whether to show the view immediately.
* @returns {void} Void.
*/
export function setupEvents(view, events, initialTab = "connection") {
export function setupEvents(view, events, initialTab = "connection", hide = false, show = false) {
if (events.onBeforeShow) {
view.addEventListener("viewbeforeshow", events.onBeforeShow.bind(view));
}
Expand Down Expand Up @@ -835,6 +837,46 @@ export function setupEvents(view, events, initialTab = "connection") {
const initEvent = new CustomEvent("viewinit", { detail: {}, bubbles: true, cancelable: false });

events.onInit.call(view, initEvent);

// Do nothing if both show and hide are requested.
if (hide && show) return;

// Show the view if requested.
if (show) {
const eventDetails = {
/** @type {FullDetails} */
detail: {
type: view.getAttribute("data-type") || null,
params: Object.fromEntries(new URLSearchParams(window.location.hash.split("#").slice(1).join("#").split("?").slice(1).join("?"))),
properties: (view.getAttribute("data-properties") || "").split(","),
isRestored: undefined,
state: null,
options: {
supportsThemeMedia: false,
enableMediaControls: true,
},
},
bubbles: true,
cancelable: false,
}
view.dispatchEvent(new CustomEvent("viewbeforeshow", eventDetails));
view.dispatchEvent(new CustomEvent("viewshow", eventDetails));
}

// Hide the view if requested.
if (hide) {
const eventDetails = {
/** @type {MinimalDetails} */
detail: {
type: event.detail.type,
properties: event.detail.properties,
},
bubbles: true,
cancelable: false,
};
view.dispatchEvent(new CustomEvent("viewbeforehide", { ...eventDetails, cancelable: true }));
view.dispatchEvent(new CustomEvent("viewhide", eventDetails));
}
}
}

Expand All @@ -857,6 +899,8 @@ export function setupEvents(view, events, initialTab = "connection") {
* @typedef {Object} controllerFactoryOptions
* @property {ViewLifecycleEvents} events The lifecycle events for the view.
* @property {TabType} [initialTab] - The initial tab.
* @property {boolean} [show] - Whether to show the view immediately.
* @property {boolean} [hide] - Whether to hide the view immediately.
*/

/**
Expand All @@ -866,9 +910,9 @@ export function setupEvents(view, events, initialTab = "connection") {
* @returns {controllerFactoryFn} The controller factory.
*/
export function createControllerFactory(options) {
const { events, initialTab } = options;
const { events, initialTab, hide, show } = options;
return function(view) {
setupEvents(view, events, initialTab);
setupEvents(view, events, initialTab, hide, show);
}
}

Expand Down
19 changes: 15 additions & 4 deletions Shokofin/Pages/Scripts/Dummy.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
export default function (view) {
let show = false;
let hide = false;
view.addEventListener("viewshow", () => show = true);
view.addEventListener("viewhide", () => hide = true);

/**
* @type {import("./Common.js").ApiClientPrototype}
*/
Expand All @@ -9,11 +15,14 @@ const ApiClient = globalThis.ApiClient;
const Dashboard = globalThis.Dashboard;

/**
* @type {import("./Common.js")}
* @type {Promise<import("./Common.js")>}
*/
const { State, createControllerFactory } = await import(ApiClient.getUrl("/web/" + Dashboard.getPluginUrl("Shoko.Common.js")));
const promise = import(ApiClient.getUrl("/web/" + Dashboard.getPluginUrl("Shoko.Common.js")));
promise.then(({ State, createControllerFactory }) => {

export default createControllerFactory({
createControllerFactory({
show,
hide,
initialTab: "utilities",
events: {
onShow(event) {
Expand All @@ -35,4 +44,6 @@ export default createControllerFactory({
content.innerHTML = "Dummy.";
},
},
});
})(view);

}); }
23 changes: 17 additions & 6 deletions Shokofin/Pages/Scripts/Settings.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
export default function (view) {
let show = false;
let hide = false;
view.addEventListener("viewshow", () => show = true);
view.addEventListener("viewhide", () => hide = true);

/**
* @type {import("./Common.js").ApiClientPrototype}
*/
Expand All @@ -9,9 +15,10 @@ const ApiClient = globalThis.ApiClient;
const Dashboard = globalThis.Dashboard;

/**
* @type {import("./Common.js")}
* @type {Promise<import("./Common.js")>}
*/
const {
const promise = import(ApiClient.getUrl("/web/" + Dashboard.getPluginUrl("Shoko.Common.js")));
promise.then(({
ShokoApiClient,
State,
createControllerFactory,
Expand All @@ -22,7 +29,7 @@ const {
retrieveCheckboxList,
retrieveSortableCheckboxList,
updateTabs,
} = await import(ApiClient.getUrl("/web/" + Dashboard.getPluginUrl("Shoko.Common.js")));
}) => {

//#region Constants

Expand Down Expand Up @@ -72,7 +79,9 @@ const Messages = {

//#region Controller Logic

export default createControllerFactory({
createControllerFactory({
show,
hide,
events: {
onInit() {
const view = this;
Expand Down Expand Up @@ -263,7 +272,7 @@ export default createControllerFactory({
applyFormToConfig(form, State.config);
},
}
});
})(view);

/**
* Update the view to reflect the current state.
Expand Down Expand Up @@ -1221,4 +1230,6 @@ function filterReconnectIntervals(value) {
return Array.from(filteredSet).sort((a, b) => a - b);
}

//#endregion
//#endregion

}); }

0 comments on commit 2ba25c1

Please sign in to comment.