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 + `
Want to support me and get access to premium modules?
Do you want to start the troubleshoot for ${game.modules.get(moduleId).title}?
This will disable all modules except the one you selected and its dependencies. You will be prompted to restore your modules after the troubleshoot.
`, 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(); } }