diff --git a/.gitattributes b/.gitattributes index 97c33e3..7ba41b6 100644 --- a/.gitattributes +++ b/.gitattributes @@ -10,3 +10,4 @@ res/icon/linux/32x32.png filter=lfs diff=lfs merge=lfs -text res/icon/linux/48x48.png filter=lfs diff=lfs merge=lfs -text res/icon/linux/512x512.png filter=lfs diff=lfs merge=lfs -text res/icon/linux/64x64.png filter=lfs diff=lfs merge=lfs -text +res/icon/brand.png filter=lfs diff=lfs merge=lfs -text diff --git a/.prettierrc b/.prettierrc index 59ba0ac..c057862 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,5 +1,5 @@ { - "plugins": ["prettier-plugin-java"], + "plugins": [], "printWidth":120, "tabWidth":4, "useTabs":false, diff --git a/Makefile b/Makefile index 40fc48a..3520c2c 100644 --- a/Makefile +++ b/Makefile @@ -15,17 +15,16 @@ node_modules: package-lock.json .PHONY: run run: - $(ELECTRON) src/main.js + LOCAL_DOMAIN=1 $(ELECTRON) src/main.js .PHONY: run-x run-x: - ./util/run-xorg $(ELECTRON) + LOCAL_DOMAIN=1 ./util/run-xorg $(ELECTRON) .PHONY: run-wl run-wl: - ./util/run-wl $(ELECTRON) + LOCAL_DOMAIN=1 ./util/run-wl $(ELECTRON) .PHONY: fix fix: node_modules ./node_modules/.bin/prettier --write src - diff --git a/package-lock.json b/package-lock.json index 14b56c0..264689e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "imgfloat-client", - "version": "1.0.0", + "version": "1.0.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "imgfloat-client", - "version": "1.0.0", + "version": "1.0.2", "dependencies": { "electron-updater": "^6.7.3" }, diff --git a/package.json b/package.json index 4a2d2d5..f2c5bb8 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "appId": "dev.kruhlmann.imgfloat", "productName": "Imgfloat", "files": [ - "src/main.js", + "src/**", "res/**" ], "publish": { diff --git a/res/icon/brand.png b/res/icon/brand.png new file mode 100644 index 0000000..bebb644 --- /dev/null +++ b/res/icon/brand.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0ec08d7610f373892433ed67f85c3afb377aa08a097cec2b0b94656f00540f68 +size 1301 diff --git a/src/index.html b/src/index.html index ec0b7a1..8cdfd84 100644 --- a/src/index.html +++ b/src/index.html @@ -9,7 +9,7 @@
- brand + brand
Imgfloat
Twitch overlay manager
@@ -35,6 +35,15 @@ autofocus spellcheck="false" /> + + @@ -44,6 +53,7 @@ diff --git a/src/js/broadcast.js b/src/js/broadcast.js index 9368955..b96761b 100644 --- a/src/js/broadcast.js +++ b/src/js/broadcast.js @@ -2,7 +2,11 @@ import { BroadcastRenderer } from "./broadcast/renderer.js"; import { saveSelectedBroadcaster } from "./ipc.js"; import { showToast } from "./toast.js"; -const domain = "https://imgfloat.kruhlmann.dev"; +const normalizeDomain = (value) => value?.trim()?.replace(/\/+$/, ""); +const domainParam = new URL(window.location.href).searchParams.get("domain"); +const defaultDomain = await window.store.loadDefaultDomain(); +const savedDomain = await window.store.loadDomain(); +const domain = normalizeDomain(domainParam || savedDomain || defaultDomain); globalThis.onerror = (error, url, line) => { console.error(error); @@ -17,6 +21,9 @@ const broadcaster = new URL(window.location.href).searchParams.get("broadcaster" if (!broadcaster) { throw new Error("No broadcaster"); } +if (!domain) { + throw new Error("No domain configured"); +} saveSelectedBroadcaster(broadcaster); const renderer = new BroadcastRenderer({ diff --git a/src/js/broadcast/renderer.js b/src/js/broadcast/renderer.js index 82d0f85..15200d5 100644 --- a/src/js/broadcast/renderer.js +++ b/src/js/broadcast/renderer.js @@ -62,7 +62,7 @@ export class BroadcastRenderer { const body = JSON.parse(payload.body); this.handleEvent(body); }); - fetch(`https://imgfloat.kruhlmann.dev/api/channels/${this.broadcaster}/assets`) + fetch(`${this.domain}/api/channels/${this.broadcaster}/assets`) .then((r) => { if (!r.ok) { throw new Error("Failed to load assets"); @@ -121,7 +121,7 @@ export class BroadcastRenderer { } async fetchCanvasSettings() { - return fetch(`https://imgfloat.kruhlmann.dev/api/channels/${encodeURIComponent(this.broadcaster)}/canvas`) + return fetch(`${this.domain}/api/channels/${encodeURIComponent(this.broadcaster)}/canvas`) .then((r) => { if (!r.ok) { throw new Error("Failed to load canvas"); diff --git a/src/main.js b/src/main.js index 37fbe13..5c1a685 100644 --- a/src/main.js +++ b/src/main.js @@ -7,6 +7,22 @@ const { readStore, writeStore } = require("./store.js"); const STORE_PATH = path.join(app.getPath("userData"), "settings.json"); const INITIAL_WINDOW_WIDTH_PX = 960; const INITIAL_WINDOW_HEIGHT_PX = 640; +const LOCAL_DOMAIN = "http://localhost:8080"; +const DEFAULT_DOMAIN = "https://imgfloat.kruhlmann.dev"; + +function normalizeDomain(domain) { + return domain?.trim()?.replace(/\/+$/, ""); +} + +function resolveDefaultDomain() { + if (process.env.DEVTOOLS || process.env.LOCAL_DOMAIN) { + return normalizeDomain(LOCAL_DOMAIN); + } + const buildTimeDomain = process.env.IMGFLOAT_DOMAIN || DEFAULT_DOMAIN; + return normalizeDomain(buildTimeDomain); +} + +const runtimeDefaultDomain = resolveDefaultDomain(); let ELECTRON_WINDOW; @@ -74,6 +90,19 @@ ipcMain.handle("load-broadcaster", () => { return store.lastBroadcaster ?? ""; }); +ipcMain.handle("save-domain", (_, domain) => { + const store = readStore(STORE_PATH); + store.lastDomain = normalizeDomain(domain); + writeStore(STORE_PATH, store); +}); + +ipcMain.handle("load-domain", () => { + const store = readStore(STORE_PATH); + return normalizeDomain(store.lastDomain) || runtimeDefaultDomain; +}); + +ipcMain.handle("load-default-domain", () => runtimeDefaultDomain); + app.whenReady().then(() => { if (process.env.CI) { process.on("uncaughtException", (err) => { diff --git a/src/preload.js b/src/preload.js index 4a9bb27..f127af1 100644 --- a/src/preload.js +++ b/src/preload.js @@ -3,5 +3,8 @@ const { contextBridge, ipcRenderer } = require("electron"); contextBridge.exposeInMainWorld("store", { saveBroadcaster: (value) => ipcRenderer.invoke("save-broadcaster", value), loadBroadcaster: () => ipcRenderer.invoke("load-broadcaster"), + saveDomain: (value) => ipcRenderer.invoke("save-domain", value), + loadDomain: () => ipcRenderer.invoke("load-domain"), + loadDefaultDomain: () => ipcRenderer.invoke("load-default-domain"), setWindowSize: (width, height) => ipcRenderer.invoke("set-window-size", width, height), });