|
|
- class TheRipperPremiumHUB {
- constructor() {
- this.outdatedModules = {};
- this.announcementsHtml = "";
- this._debug = false;
- this.converter = new showdown.Converter();
- this.init();
- }
-
- get repositoryIndex() {
- return {
- megapack: "megapack",
- "vtt-desktop-client": "fvtt-player-client",
- levels: "Levels",
- enhancedcombathud: "enhancedcombathud",
- "automated-evocations": "automated-evocations",
- betterroofs: "Better-Roofs",
- "combat-tracker-dock": "combat-tracker-dock",
- bossbar: "Boss-Bar",
- combatbooster: "Combat-Booster",
- "fuzzy-foundry": "fuzzy-foundry",
- "hover-distance": "hover-distance",
- "hurry-up": "hurry-up",
- levelsautocover: "levelsautocover",
- levelsvolumetrictemplates: "levelsvolumetrictemplates",
- patrol: "Patrol",
- "damage-numbers": "damage-numbers",
- smarttarget: "Smart-Target",
- splatter: "splatter",
- "dnd-randomizer": "dnd-randomizer",
- "tile-sort": "tile-sort",
- "tile-scroll": "tile-scroll",
- "token-z": "token-z",
- "foundry-taskbar": "foundry-taskbar",
- quickdraw: "quickdraw",
- "config-presets": "config-presets",
- "light-switch": "light-switch",
- "filepicker-plus": "filepicker-plus",
- "progress-tracker": "progress-tracker",
- "situational-shortcuts": "situational-shortcuts",
- "quick-doors": "quick-doors",
- "image-context": "image-context",
- "inactive-tokens-lmao": "inactive-tokens-lmao",
- "levels-3d-preview": "levels-3d-preview",
- choices: "choices",
- mmm: "Maxwell-s-Manual-of-Malicious-Maladies",
- socketmacros: "socketmacros",
- tokenflip: "tokenflip",
- "token-notes": "token-notes",
- "wall-height": "wall-height",
- canvas3dcompendium: "canvas3dcompendium",
- canvas3dtokencompendium: "canvas3dtokencompendium",
- "theripper-premium-hub": "theripper-premium-hub",
- "levels-layer-effects": "levels-layer-effects",
- "three-actor-portrait": "three-actor-portrait",
- mastercrafted: "mastercrafted",
- gatherer: "gatherer",
- "camera-dock": "camera-dock",
- "macro-wheel": "macro-wheel",
- };
- }
-
- async init() {
- this.moduleData = await this.fetchData();
- this.announcements = this.moduleData.announcements;
- delete this.moduleData.announcements;
- this.getOutdatedModules();
- if (game.settings.get("theripper-premium-hub", "autoCheck")) {
- this.displayOutdated(false);
- }
- this.displayAnnouncements();
- }
-
- async getForgeData(moduleId) {
- return await fetch(`https://forge-vtt.com/api/bazaar/package/${moduleId}`)
- .then((response) => response.json())
- .then((data) => data)
- }
-
- getOutdatedModules() {
- const checkDisabled = game.settings.get("theripper-premium-hub", "checkDisabled");
- for (let [k, v] of Object.entries(this.moduleData)) {
- const installedModule = game.modules.get(k);
- if (!installedModule) continue;
- if (!checkDisabled && !installedModule?.active) continue;
- if (isNewerVersion(v.version, installedModule.version) || this._debug) {
- this.outdatedModules[k] = v;
- this.outdatedModules[k].title = installedModule.title;
- this.outdatedModules[k].currentVersion = installedModule.version;
- }
- }
- }
-
- async displayOutdated(notify = false) {
- if (Object.keys(this.outdatedModules).length === 0) return notify ? ui.notifications.info(`No outdated modules found.`) : null;
- let displayUpdated = {};
- if (!notify) {
- const viewedUpdates = game.settings.get("theripper-premium-hub", "viewedUpdates");
- for (let [k, v] of Object.entries(this.outdatedModules)) {
- if (viewedUpdates[k] && v.version === viewedUpdates[k]) continue;
- displayUpdated[k] = v;
- }
- } else {
- displayUpdated = this.outdatedModules;
- }
- if (Object.keys(displayUpdated).length === 0) return null;
- const html = await renderTemplate("modules/theripper-premium-hub/templates/modlist.hbs", displayUpdated);
- Dialog.prompt({
- title: "TheRipper93 Premium HUB - Updates Available!",
- content: html,
- rejectClose: false,
- callback: () => {
- const viewedUpdates = game.settings.get("theripper-premium-hub", "viewedUpdates");
- for (let [k, v] of Object.entries(this.outdatedModules)) {
- viewedUpdates[k] = v.version;
- }
- game.settings.set("theripper-premium-hub", "viewedUpdates", viewedUpdates);
- },
- close: () => {},
- });
- }
-
- async displayAnnouncements() {
- const announcements = this.announcements;
- if (!announcements) return;
- const ids = Object.keys(announcements);
- const viewedAnnouncements = game.settings.get("theripper-premium-hub", "viewedAnnouncements") ?? "";
- const allViewed = ids.every((id) => viewedAnnouncements.includes(id));
- const html = await renderTemplate("modules/theripper-premium-hub/templates/announcements.hbs", announcements);
- this.announcementsHtml = html;
- if (allViewed && !this._debug) return;
- game.settings.set("theripper-premium-hub", "viewedAnnouncements", ids.join(","));
- Dialog.prompt({
- title: "TheRipper93 Premium HUB - Announcement!",
- content:
- html +
- ` <p style="text-align: center;">Want to support me and get access to premium modules?</p><hr>
- <p style="text-align: center;"><a href="https://theripper93.com/" target="_blank" rel="nofollow" title="https://theripper93.com/">Check out my Website</a></p>`,
- rejectClose: false,
- callback: () => {},
- close: () => {},
- });
- }
-
- async fetchData() {
- const modules = game.modules.filter((v) => v.authors && v.authors.some((a) => a.name === "theripper93"));
- const announcements = await this.fetchAnnouncements();
- const promises = modules.map((m) => this.fetchModuleData(m));
-
- const obj = {};
-
- await Promise.all(promises).then((data) => {
- data.forEach((d) => {
- if (d) {
- obj[d.id] = d;
- }
- });
- });
- obj.announcements = announcements.announcements;
- return obj;
- }
-
- async fetchModuleData(module) {
- const checkDisabled = game.settings.get("theripper-premium-hub", "checkDisabled");
- if (!checkDisabled && !module.active) return null;
- const isPremium = module?.manifest?.includes("foundryvtt");
- const id = module.id;
- const owner = "theripper93";
- const repo = this.repositoryIndex[id] ?? id;
- const releases = await this.getAllReleasesFromGitHub(owner, repo, isPremium, module);
- if (!releases) return null;
- const latestRelease = Object.keys(releases).sort((a, b) => isNewerVersion(b, a))[0];
- if(!latestRelease) return null;
- return {
- version: latestRelease,
- title: module.title,
- changelog: releases,
- latestChangeLog: this.converter.makeHtml(releases[latestRelease]),
- id: id,
- };
- /*return await fetch(`https://forge-vtt.com/api/bazaar/package/${moduleId}`)
- .then((response) => response.json())
- .then((data) => data);*/
- }
-
- async getAllReleasesFromGitHub(owner, repo, isPremium, module) {
- if (isPremium) {
- const changelogURL = `https://raw.githubusercontent.com/theripper93/theripper-premium-hub/master/premium-changelogs/${repo}.md`;
- try {
- const response = await fetch(changelogURL);
- if (!response.ok) return null;
- const changelog = await response.text();
- if (!changelog) return null;
- const releases = {};
- //parse changelog
- const changelogLines = changelog.split(/\r?\n/);
- let currentVersion = "";
- for (const line of changelogLines) {
- if (line.startsWith("##")) {
- const version = line.replace("## Version ", "");
- releases[version] = "";
- currentVersion = version;
- } else {
- const trimmed = line.trim();
- if (trimmed != "") releases[currentVersion] += line + "\n";
- }
- }
- return releases;
- } catch (error) {
- return null;
- }
- } else {
- const releasesPerPage = 10; // Maximum allowed by GitHub API
- const apiUrl = `https://api.github.com/repos/${owner}/${repo}/releases?per_page=${releasesPerPage}`;
-
- try {
- let compiledReleases = {};
-
- const response = await fetch(`${apiUrl}&page=1`);
-
- if (response.status === 404 && !module.download) {
- ui.notifications.error(`The module <strong>${module.title}</strong> is still installed using the old manual installation, please switch to the new Foundry/Patreon integration. <a href="https://theripper93.com/info/installation" target="_blank" rel="nofollow">More Information</a>`, { permanent: true });
- }
-
-
-
- const releases = await response.json();
- releases.forEach((release) => {
- compiledReleases[release.tag_name] = release.body;
- });
-
- return compiledReleases;
- } catch (error) {
- return null;
- }
- }
- }
-
- async fetchAnnouncements() {
- return await fetch(`https://api.theripper93.com/moduleListing/latest`, { cache: "no-cache" })
- .then((response) => response.json())
- .then((data) => data);
- }
-
- _getdataforfile() {
- const mods = {};
- game.modules.forEach((v, k) => {
- if (v.authors && v.authors.some((a) => a.name === "theripper93") && v.manifest.includes("foundryvtt")) {
- mods[k] = {
- title: v.title,
- version: v.version,
- downloadURL: this.moduleData[k]?.downloadURL ?? "",
- };
- }
- });
- return mods;
- }
-
- getDependencies(moduleId) {
- const rootModule = game.modules.get(moduleId);
- const dependencies = new Set();
- const addDependecies = (module) => {
- const moduleDependencies = Array.from(module.relationships.requires).map((m) => game.modules.get(m.id));
- moduleDependencies.forEach((m) => {
- dependencies.add(m);
- addDependecies(m);
- });
- };
- addDependecies(rootModule);
- return dependencies;
- }
-
- async troubleshoot(moduleId) {
- const confirm = await Dialog.confirm({
- title: "TheRipper93 Premium HUB - Troubleshoot",
- content: `<p>Do you want to start the troubleshoot for ${game.modules.get(moduleId).title}?</p><br><p>This will disable all modules except the one you selected and its dependencies. You will be prompted to restore your modules after the troubleshoot.</p>`,
- yes: () => {
- return true;
- },
- no: () => {
- return false;
- },
- });
- if (!confirm) return;
- const dependencies = this.getDependencies(moduleId);
- const dependenciesIds = [...Array.from(dependencies).map((m) => m.id), moduleId, "theripper-premium-hub"];
- const modulesSetting = game.settings.get("core", ModuleManagement.CONFIG_SETTING);
- const currentlyEnabled = [];
- for (let [k, v] of Object.entries(modulesSetting)) {
- if (v) currentlyEnabled.push(k);
- if (dependenciesIds.includes(k)) continue;
- modulesSetting[k] = false;
- }
- await game.settings.set("theripper-premium-hub", "prevEnabledModules", currentlyEnabled);
- await game.settings.set("core", ModuleManagement.CONFIG_SETTING, modulesSetting);
- debouncedReload();
- }
- }
|