262 lines
6.0 KiB
TypeScript
262 lines
6.0 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 { gzipSync, gunzipSync } from "zlib";
|
|
|
|
let apiUrl: string = `${location.protocol}//${location.hostname}:8856/`;
|
|
|
|
class Favorites {
|
|
private data: string[] = [];
|
|
|
|
constructor() {
|
|
console.log("Loading favorites");
|
|
this.data = JSON.parse(localStorage.getItem("settings.favorites")) || [];
|
|
this.sync();
|
|
}
|
|
|
|
public async sync(): Promise<void> {
|
|
localStorage.setItem("settings.favorites", JSON.stringify(this.data));
|
|
}
|
|
|
|
public async clear(): Promise<void> {
|
|
this.data = [];
|
|
this.sync();
|
|
}
|
|
|
|
public async pop(): Promise<string> {
|
|
let item: any = this.data.pop();
|
|
this.sync();
|
|
return item;
|
|
}
|
|
|
|
public async push(toadd): Promise<void> {
|
|
this.data.push(toadd);
|
|
this.sync();
|
|
}
|
|
|
|
public async delete(d): Promise<void> {
|
|
this.data = this.data.filter((v) => { return v != d });
|
|
this.sync();
|
|
}
|
|
|
|
public async at(d): Promise<string> {
|
|
return this.data.at(d);
|
|
}
|
|
|
|
public async contains(d): Promise<boolean> {
|
|
return this.data.includes(d);
|
|
}
|
|
|
|
public async shuffle(): Promise<string[]> {
|
|
let data: string[] = this.data;
|
|
|
|
for (let i = 0; i < await this.data.length; i++) {
|
|
data.sort(() => { return Math.random() - 0.5 });
|
|
}
|
|
|
|
return data;
|
|
}
|
|
}
|
|
|
|
class Blacklist {
|
|
private data: string[] = [];
|
|
|
|
constructor() {
|
|
console.log("Loading blacklist");
|
|
this.data = JSON.parse(localStorage.getItem("settings.blacklist")) || [];
|
|
this.sync();
|
|
}
|
|
|
|
public async sync(): Promise<void> {
|
|
localStorage.setItem("settings.blacklist", JSON.stringify(this.data));
|
|
}
|
|
|
|
public async clear(): Promise<void> {
|
|
this.data = [];
|
|
this.sync();
|
|
}
|
|
|
|
public async pop(): Promise<string> {
|
|
let item: any = this.data.pop();
|
|
this.sync();
|
|
return item;
|
|
}
|
|
|
|
public async push(toadd): Promise<void> {
|
|
this.data.push(toadd);
|
|
this.sync();
|
|
}
|
|
|
|
public async delete(d): Promise<void> {
|
|
this.data = this.data.filter((v) => { return v != d });
|
|
this.sync();
|
|
}
|
|
|
|
public async at(d): Promise<string> {
|
|
return this.data.at(d);
|
|
}
|
|
public async contains(d): Promise<boolean> {
|
|
return this.data.includes(d);
|
|
}
|
|
}
|
|
|
|
class Cache {
|
|
private cache: string[];
|
|
private checksum: string;
|
|
last: string[];
|
|
|
|
constructor() {}
|
|
|
|
async load(): Promise<void> {
|
|
console.log("Loading cache");
|
|
|
|
if (localStorage.getItem("cache"))
|
|
this.cache = JSON.parse(gunzipSync(Buffer.from(localStorage.getItem("cache"), "base64")).toString());
|
|
else
|
|
this.cache = [];
|
|
this.checksum = localStorage.getItem("cache.checksum");
|
|
|
|
if (!this.cache || !this.checksum) {
|
|
await this.sync();
|
|
} else if (!await this.validate()) {
|
|
await this.sync();
|
|
}
|
|
}
|
|
|
|
async sync(): Promise<void> {
|
|
console.log("Syncing cache");
|
|
|
|
try {
|
|
let sync = await fetch(apiUrl + "sync", {
|
|
body: JSON.stringify({ action: "fullUpdate", checksum: this.checksum }),
|
|
method: "POST",
|
|
});
|
|
let data = await sync.json();
|
|
|
|
if (!sync.ok)
|
|
throw Error(sync.statusText);
|
|
|
|
console.log(data);
|
|
|
|
if (!data.valid) {
|
|
this.checksum = data.checksum,
|
|
this.cache = data.files;
|
|
}
|
|
|
|
await this.update();
|
|
} catch (e) {
|
|
throw e;
|
|
}
|
|
}
|
|
|
|
private async update(): Promise<void> {
|
|
localStorage.setItem("cache", gzipSync(JSON.stringify(this.cache)).toString("base64"));
|
|
localStorage.setItem("cache.checksum", this.checksum);
|
|
}
|
|
|
|
private async validate(): Promise<boolean> {
|
|
try {
|
|
let sync = await fetch(apiUrl + "sync", {
|
|
body: JSON.stringify({ action: "validateChecksum", checksum: localStorage.getItem("cache.checksum") }),
|
|
method: "POST",
|
|
});
|
|
|
|
if (!sync.ok)
|
|
throw Error(sync.statusText);
|
|
|
|
return (await sync.json()).valid;
|
|
} catch(e) {
|
|
throw e;
|
|
}
|
|
}
|
|
|
|
public async at(d): Promise<string> {
|
|
return this.cache.at(d);
|
|
}
|
|
|
|
public async order(): Promise<string[]> {
|
|
let data: string[] = this.cache;
|
|
|
|
if (JSON.parse(localStorage.getItem("config")).deterministic) {
|
|
data = this.cache.sort((a, b) => a.localeCompare(b));
|
|
} else {
|
|
for (let i = 0; i < await this.length(); i++) {
|
|
data.sort(() => { return Math.random() - 0.5 });
|
|
}
|
|
}
|
|
|
|
this.last = data;
|
|
|
|
return data;
|
|
}
|
|
|
|
public async length(): Promise<Number> {
|
|
return this.cache.length;
|
|
}
|
|
}
|
|
|
|
class Config {
|
|
private data = {};
|
|
private defaultConfig = {
|
|
"ignoreBlacklist": false,
|
|
"onlyFavorites": false,
|
|
"deterministic": false
|
|
}
|
|
|
|
constructor() {
|
|
console.log("Loading config");
|
|
|
|
if (!localStorage.getItem("config"))
|
|
localStorage.setItem("config", JSON.stringify(this.defaultConfig));
|
|
|
|
this.data = JSON.parse(localStorage.getItem("config"));
|
|
|
|
this.verify();
|
|
this.sync();
|
|
}
|
|
|
|
private verify() {
|
|
for (let k in this.defaultConfig)
|
|
if (!this.get(k))
|
|
this.data[k] = this.defaultConfig[k];
|
|
}
|
|
|
|
public sync() {
|
|
localStorage.setItem("config", JSON.stringify(this.data));
|
|
}
|
|
|
|
public set(vr, vl) {
|
|
this.data[vr] = vl;
|
|
}
|
|
|
|
public get(vr) {
|
|
return this.data[vr];
|
|
}
|
|
|
|
public keys() {
|
|
return Object.keys(this.data);
|
|
}
|
|
}
|
|
|
|
export default class Settings {
|
|
favorites: Favorites;
|
|
blacklist: Blacklist;
|
|
cache: Cache;
|
|
config: Config;
|
|
|
|
constructor() {
|
|
this.favorites = new Favorites();
|
|
this.blacklist = new Blacklist();
|
|
this.cache = new Cache();
|
|
this.config = new Config();
|
|
}
|
|
}
|
|
|
|
export { apiUrl }; |