galerie/web/www/gallery.html.tsx

252 lines
6.7 KiB
TypeScript

/*
Copyright 2023 0xf8.dev@proton.me
This file is part of Galerie
Galerie is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
Galerie is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with Galerie. If not, see <https://www.gnu.org/licenses/>.
*/
import App from "./app";
import React from "react";
import jQuery from "jquery";
const $ = jQuery;
import Settings, { apiUrl } from "./settings";
const settings = new Settings();
let global_ActivePopout: Popout = null;
class Popout {
private element: JQuery<HTMLImageElement>;
private overlay: JQuery<HTMLElement>;
constructor(element: JQuery<HTMLImageElement>, src: string) {
this.element = element.clone();
this.element.removeClass("resourceh resource");
this.element.addClass("popout");
this.element.css("opacity", 0.0001);
this.element.on("load", () => {
console.log(this.element.height() > this.element.width(), this.element.height(), this.element.width());
if (this.element.height() > this.element.width())
if (screen.orientation.type == "portrait-primary" || screen.orientation.type == "portrait-secondary")
this.element.css("width", "94vw");
else
this.element.css("height", "94vh");
if (this.element.width() >= this.element.height())
this.element.css("width", "96vw");
this.element.css("opacity", 1);
});
this.overlay = $("<div class='overlay' scroll='no'>");
this.overlay.append(this.element);
}
create() {
if (global_ActivePopout != null) return;
global_ActivePopout = this;
$("root").append(this.overlay);
this.overlay.one("click", (event) => {
event.preventDefault();
this.destroy();
});
}
destroy() {
if (global_ActivePopout != this) return;
global_ActivePopout = null;
this.overlay.remove();
this.element.remove();
}
}
// ===============
// === Gallery ===
// ===============
class gallery {
constructor() {}
public async load(): Promise<void> {
console.log("Loading gallery");
await settings.cache.load();
}
public async loadDisplay(data: string[]): Promise<void> {
await this.clearDisplay();
if (settings.config.get("onlyFavorites")) {
let d = [];
for (let i in data) {
let j = data[i];
if (await settings.favorites.contains(j)) d.push(j);
}
data = d;
}
if (!settings.config.get("ignoreBlacklist")) {
let d = [];
for (let i in data) {
let j = data[i];
if (!await settings.blacklist.contains(j)) d.push(j);
}
data = d;
}
if (data.length != 0) {
for (let i = 0; i < data.length; i++) {
let f = await data.at(i);
if (!settings.config.get("ignoreBlacklist"))
if (await settings.blacklist.contains(f)) continue;
this.createElement(f).then((e) => e.appendTo($("div#display")));
}
} else {
let t = $(
`<span style='margin-top: 3em'>There's nothing here${settings.config.get("onlyFavorites") ? "" : ". <a style='color: white; text-decoration: none' href='#' id='a'>Reload?</a>"}${
settings.config.get("onlyFavorites")
? "<br>Hint: 'onlyFavorites' is enabled. <a style='color: white; text-decoration: none' href='#' id='dar'>Disable and reload?</a>"
: ""
}${await settings.blacklist.at(0) ? '<br>Hint: Every image is blacklisted' : ""}</span>`
);
t.children("a#a").on("click", async (e) => {
e.preventDefault();
this.loadDisplay(await settings.cache.order());
});
t.children("a#dar").on("click", async (e) => {
e.preventDefault();
settings.config.set("onlyFavorites", false);
this.loadDisplay(await settings.cache.order());
})
$(t).appendTo($("div#display"));
}
}
private async clearDisplay(): Promise<void> {
$("#display").children().remove();
}
private async createElement(src: string): Promise<JQuery<HTMLElement>> {
let container = $("<span>");
let element: JQuery<HTMLImageElement> = $(`<img class='resource resourceh'>`);
element.prop("loop", true);
element.prop("nocontrols", true);
element.attr("src", `${apiUrl}img/${src}`);
let popoutHandler = async (event) => {
event.preventDefault();
const popout = new Popout(element, src);
popout.create();
};
element.on("click", popoutHandler);
let ialist: JQuery<HTMLElement>;
let reloadlist = async () => {
ialist = await this.createIconActionList(container, src, reloadlist);
container.children("span").remove();
container.append(ialist);
};
container.append(element);
ialist = await this.createIconActionList(container, src, reloadlist);
ialist.css("opacity", 0);
container.append(ialist);
element.on("load", (e) => {
ialist.removeAttr("style");
});
// await reloadlist();
return container;
}
private async createIconActionList(e:JQuery<HTMLElement>, src: string, triggerReload) {
let container = $("<span>");
let ia = (icon: string, title: string, func: () => void) => {
let i = $(`<i title="${title}" class="${icon}">`);
i.on("click", func);
container.append(i);
};
if (await settings.favorites.contains(src)) {
ia("fa-solid fa-heart", "Unfavorite", () => {
settings.favorites.delete(src);
triggerReload();
});
} else {
ia("fa-regular fa-heart", "Favorite", () => {
settings.favorites.push(src);
triggerReload();
});
}
if (settings.config.get("ignoreBlacklist")) {
if (await settings.blacklist.contains(src)) {
ia("fa-solid fa-eye-slash", "De-blacklist", () => {
settings.blacklist.delete(src);
triggerReload();
});
} else {
ia("fa-solid fa-eye", "Blacklist", () => {
settings.blacklist.push(src);
triggerReload();
});
}
} else {
ia("fa-solid fa-ban", "Blacklist", () => {
settings.blacklist.push(src);
e.remove();
triggerReload();
})
}
return container;
}
}
let Gallery = new gallery();
window.onload = async () => {
await Gallery.load();
await Gallery.loadDisplay(await settings.cache.order());
};
const root = App(() => {
return (
<>
<div id="container">
<div id="display"></div>
</div>
</>
);
});