diff --git a/src/ZenThemeMarketplace.mjs b/src/ZenThemeMarketplace.mjs deleted file mode 100644 index dda3cc9..0000000 --- a/src/ZenThemeMarketplace.mjs +++ /dev/null @@ -1,5 +0,0 @@ - -const gZenThemeMarketplace = { - init() { - }, -}; diff --git a/src/actors/ZenThemeMarketplaceChild.sys.mjs b/src/actors/ZenThemeMarketplaceChild.sys.mjs index c3e7229..d120df1 100644 --- a/src/actors/ZenThemeMarketplaceChild.sys.mjs +++ b/src/actors/ZenThemeMarketplaceChild.sys.mjs @@ -1,4 +1,5 @@ +const kZenThemesPreference = "zen.themes.data"; export class ZenThemeMarketplaceChild extends JSWindowActorChild { constructor() { super(); @@ -19,7 +20,7 @@ export class ZenThemeMarketplaceChild extends JSWindowActorChild { }, 1000); } - addIntallButtons() { + async addIntallButtons() { const actionButtons = this.contentWindow.document.querySelectorAll(".install-theme"); const errorMessages = this.contentWindow.document.querySelectorAll(".install-theme-error"); if (actionButtons.length !== 0) { @@ -36,9 +37,51 @@ export class ZenThemeMarketplaceChild extends JSWindowActorChild { } } - installTheme(event) { + get themes() { + if (!this._themes) { + this._themes = JSON.parse(Services.prefs.getStringPref(kZenThemesPreference, "{}")); + } + return this._themes; + } + + set themes(themes) { + this._themes = themes; + this.sendAsyncMessage("ZenThemeMarketplace:UpdateThemes", { themes }); + } + + addTheme(theme) { + this.themes[theme.id] = theme; + this.themes = this.themes; + } + + async getThemeInfo(themeId) { + const url = `https://zen-browser.app/api/get-theme?id=${themeId}`; + console.info("ZTM: Fetching theme info from: ", url); + const data = await fetch(url, { + mode: "no-cors", + }); + + if (data.ok) { + try { + const obj = await data.json(); + return obj; + } catch (e) { + console.error("ZTM: Error parsing theme info: ", e); + } + } + return null; + } + + async installTheme(event) { const button = event.target; const themeId = button.getAttribute("zen-theme-id"); - console.info("Installing theme with id: ", themeId); + console.info("ZTM: Installing theme with id: ", themeId); + + const theme = await this.getThemeInfo(themeId); + if (!theme) { + console.error("ZTM: Error fetching theme info"); + return; + } + this.addTheme(theme); } }; diff --git a/src/actors/ZenThemeMarketplaceParent.sys.mjs b/src/actors/ZenThemeMarketplaceParent.sys.mjs new file mode 100644 index 0000000..e5255d9 --- /dev/null +++ b/src/actors/ZenThemeMarketplaceParent.sys.mjs @@ -0,0 +1,67 @@ + +const kZenThemesPreference = "zen.themes.data"; +export class ZenThemeMarketplaceParent extends JSWindowActorParent { + constructor() { + super(); + + Services.prefs.addObserver(kZenThemesPreference, this.onThemePreferenceChange.bind(this)); + } + + receiveMessage(message) { + switch (message.name) { + case "ZenThemeMarketplace:UpdateThemes": { + console.info("ZenThemeMarketplaceParent: Updating themes"); + this.updateThemes(message.data.themes); + break; + } + } + } + + get themes() { + if (!this._themes) { + this._themes = JSON.parse(Services.prefs.getStringPref(kZenThemesPreference, "{}")); + } + return this._themes; + } + + updateThemes(themes) { + Services.prefs.setStringPref(kZenThemesPreference, JSON.stringify(themes)); + } + + onThemePreferenceChange() { + this._themes = null; + this.checkForThemeChanges(); + } + + async getDownloadFileContents(themeId) { + try { + const theme = this.themes[themeId]; + if (!theme) { + throw new Error("Theme not found"); + } + const downloadUrl = theme.downloadUrl; + console.info("ZenThemeMarketplaceParent: Downloading file from ", downloadUrl); + const response = await fetch(downloadUrl); + const data = await response.text(); + return data; + } catch (e) { + console.error("ZenThemeMarketplaceParent: Error getting downloadable file", e); + return ""; + } + } + + get themesRootPath() { + return PathUtils.join( + PathUtils.profileDir, + "chrome", + "zen-themes" + ); + } + + // Compare the downloaded themes to the "installed" themes + // and update the installed themes with the new ones. We may also + // delete any themes that are no longer available. + async checkForThemeChanges() { + + } +};