jadefin/mods/ExtrasMenu.js

206 lines
5.6 KiB
JavaScript

//@ts-check
import JadefinIntegrity from '../JadefinIntegrity.js';
import JadefinMod from "../JadefinMod.js";
import JadefinModules from "../JadefinModules.js";
import JadefinUtils from "../JadefinUtils.js";
import { rd, rdom, rd$, RDOMListHelper } from "../utils/rdom.js";
export default JadefinIntegrity("ExtrasMenu", import.meta.url, () => new (class ExtrasMenu extends JadefinMod {
IN_ALL = 0;
IN_CUSTOM = 1;
IN_DRAWER = 2;
IN_LIBRARY = 4;
IN_MOVIE = 8;
_popupId = 0;
_items = [];
/** @type {typeof this._items} */
items = new Proxy(this._items, {
deleteProperty: (target, property) => {
delete target[property];
this.update();
return true;
},
set: (target, property, value, receiver) => {
target[property] = value;
this.update();
return true;
}
});
headerExtrasEl = rd$()`
<button is="paper-icon-button-light" class="headerExtrasMenu headerButton headerButtonRight" title="Extras" style="display: inline-flex;">
<span class="material-icons tune"></span>
</button>
`;
drawerExtrasEl = rd$()`
<div class="extrasMenuOptions">
</div>
`;
constructor() {
super();
this.items.push({
name: "Reload",
secondaryText: "Fully reload and update Jellyfin",
icon: "update",
in: this.IN_LIBRARY,
cb: async () => {
try {
await window.caches.delete("embydata");
} catch (e) {
}
try {
await window.caches.delete(`workbox-precache-v2-${JadefinModules.Emby.Page.baseRoute}/`);
} catch (e) {
}
window.location.reload();
}
});
this.headerExtrasEl.addEventListener("click", e => this.openExtrasPopup());
}
async init(name, url) {
await super.init(name, url);
await JadefinUtils.waitUntil(() => document.querySelector(".headerRight"));
this.initStyle();
this.initHeaderExtras();
this.initDrawerExtras();
this.log.i("Ready");
}
initHeaderExtras() {
document.querySelector(".headerRight")?.appendChild(this.headerExtrasEl);
}
/**
* @param {boolean} [silentWarn]
*/
initDrawerExtras(silentWarn) {
const drawer = document.querySelector(".mainDrawer > .mainDrawer-scrollContainer");
const userMenuOptions = drawer?.querySelector("& > .userMenuOptions");
if (!userMenuOptions) {
if (!silentWarn) {
this.log.w("Couldn't find mainDrawer / home userMenuOptions, retrying");
}
setTimeout(() => this.initDrawerExtras(true), 1500);
return;
}
drawer?.insertBefore(this.drawerExtrasEl, userMenuOptions);
this.update();
}
openExtrasPopup() {
const currentVisibility = JadefinUtils.isInMovie ? this.IN_MOVIE : this.IN_LIBRARY;
const dialogClass = `extrasMenuPopup-${this._popupId++}`;
const items = this._items.map((item, i) => Object.assign({
id: i
}, item)).filter(item => this.checkVisibility(currentVisibility, item));
const p = JadefinModules.actionSheet.show({
dialogClass,
title: "Extras",
positionTo: this.headerExtrasEl,
items
});
p.then(id => {
if (!id) {
return;
}
this._items[id]?.cb?.();
});
const dialogEl = document.querySelector(`.${dialogClass}`);
if (!dialogEl) {
this.log.e(`Couldn't find .${dialogClass}`);
return;
}
this.log.i(`Opened .${dialogClass}`);
this.log.dir(dialogEl);
dialogEl.classList.add("extrasMenuPopup");
const dialogButtons = dialogEl.querySelectorAll("button");
for (let i in items) {
items[i].cbEl?.(dialogButtons[i], currentVisibility, true);
}
p.finally(() => {
for (let i in items) {
items[i].cbEl?.(dialogButtons[i], currentVisibility, false);
}
});
}
update() {
if (this.drawerExtrasEl) {
this.drawerExtrasEl.innerHTML = `<h3 class="sidebarHeader">Extras</h3>`;
for (let item of this._items) {
if (!this.checkVisibility(this.IN_DRAWER, item)) {
continue;
}
let itemEl = rd$()`
<a is="emby-linkbutton" class="navMenuOption emby-button" href="#">
<span class=${`material-icons navMenuOptionIcon ${item.icon}`} aria-hidden="true"></span>
<div class="navMenuOptionTextBlock">
<span class="navMenuOptionText">${item.name}</span><br>
<span class="navMenuOptionTextSubtext">${item.secondaryText}</span>
</div>
</a>
`;
itemEl.addEventListener("click", e => item.cb?.());
item.cbEl?.(itemEl, this.IN_DRAWER);
this.drawerExtrasEl.appendChild(itemEl);
}
}
}
/**
* @param {number} current
* @param {any} item
*/
checkVisibility(current, item) {
if ((item.in || this.IN_ALL) == this.IN_ALL) {
return true;
}
if ((item.in & this.IN_CUSTOM) == this.IN_CUSTOM) {
return item.inCustom(current, item);
}
return (item.in & current) == current;
}
})());