From 6debfb7c28b59bad57797eccce39ec07b46459b4 Mon Sep 17 00:00:00 2001 From: Faey Umbrea <1144986+FaeyUmbrea@users.noreply.github.com> Date: Mon, 30 Sep 2024 14:40:22 +0200 Subject: [PATCH] Lots of rewrite --- package.json | 1 + src/applications/chatApplication.js | 54 --- src/applications/configApplication.js | 4 - src/applications/loginApplication.js | 18 + src/index.js | 22 +- src/server/chat_api.js | 3 +- src/server/connectionManager.js | 4 +- src/server/patreon.js | 28 +- src/server/poll_api.js | 3 +- src/svelte/ChatCommandConfigUI.svelte | 7 +- src/svelte/ConfigUI.svelte | 20 +- src/svelte/LoginUI.svelte | 80 +++++ src/svelte/NotificationCenterUI.svelte | 6 +- src/svelte/PollApplicationUI.svelte | 4 +- src/svelte/components/PatreonConfig.svelte | 16 +- src/svelte/components/PollDisplay.svelte | 4 +- src/svelte/components/PollEditor.svelte | 4 +- src/utils/const.js | 2 +- src/utils/settings.js | 367 ++++++++++----------- yarn.lock | 10 + 20 files changed, 351 insertions(+), 306 deletions(-) delete mode 100644 src/applications/chatApplication.js create mode 100644 src/applications/loginApplication.js create mode 100644 src/svelte/LoginUI.svelte diff --git a/package.json b/package.json index 73cba2a..3dd92f5 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "vite": "^5.4.8" }, "dependencies": { + "@castlenine/svelte-qrcode": "^2.2.0", "@directus/sdk": "^17.0.1", "@microsoft/signalr": "^8.0.7", "@typhonjs-fvtt/runtime": "^0.1.3", diff --git a/src/applications/chatApplication.js b/src/applications/chatApplication.js deleted file mode 100644 index cd0225b..0000000 --- a/src/applications/chatApplication.js +++ /dev/null @@ -1,54 +0,0 @@ -import { SvelteApplication } from "@typhonjs-fvtt/runtime/svelte/application"; -import ChatApplicationUi from "../svelte/ChatApplicationUi.svelte"; - -export class ChatApplication extends SvelteApplication { - /** - * The Scene Control Tool sidebar button. - * @type {SceneControlTool} - */ - sidebarButton; - - /** - * Creates a new instance of ChatApplication. - * @param {SceneControlTool} sidebarButton The Scene Control Tool sidebar button. - */ - constructor(sidebarButton) { - super(); - this.sidebarButton = sidebarButton; - } - - /** - * Gets the default options for the ChatApplication. - * @returns {object} The default options. - */ - static get defaultOptions() { - // @ts-ignore - return foundry.utils.mergeObject(super.defaultOptions, { - classes: ["epchat", "flexcol"], - minimizable: true, - width: 300, - height: 700, - id: "streamchat-application", - title: "Stream Chat", - resizable: true, - positionOrtho: false, - transformOrigin: null, - svelte: { - class: ChatApplicationUi, - target: document.body, - intro: true, - }, - }); - } - - /** - * Closes the application. - * @returns {Promise} - */ - async close() { - //@ts-ignore - await super.close(); - $("[data-tool=openStreamDirector]").removeClass("active"); - this.sidebarButton.active = false; - } -} diff --git a/src/applications/configApplication.js b/src/applications/configApplication.js index f4b7ddf..c380f1e 100644 --- a/src/applications/configApplication.js +++ b/src/applications/configApplication.js @@ -1,6 +1,5 @@ import { SvelteApplication } from "@typhonjs-fvtt/runtime/svelte/application"; import ConfigUI from "../svelte/ConfigUI.svelte"; -import { settings } from "../utils/settings.js"; /** @extends SvelteApplication */ export class ConfigApplication extends SvelteApplication { @@ -20,9 +19,6 @@ export class ConfigApplication extends SvelteApplication { class: ConfigUI, target: document.body, intro: true, - props: { - settings: settings, - }, }, }); } diff --git a/src/applications/loginApplication.js b/src/applications/loginApplication.js new file mode 100644 index 0000000..ce54d4e --- /dev/null +++ b/src/applications/loginApplication.js @@ -0,0 +1,18 @@ +import { SvelteApplication } from "@typhonjs-fvtt/runtime/svelte/application"; +import LoginUI from "../svelte/LoginUI.svelte"; + +export default class LoginApplication extends SvelteApplication { + static get defaultOptions() { + return foundry.utils.mergeObject(super.defaultOptions, { + classes: ["login-dialog"], + id: "login-application", + title: "Ethereal Plane Login", + width: 400, + height: 435, + svelte: { + class: LoginUI, + target: document.body, + }, + }); + } +} diff --git a/src/index.js b/src/index.js index d5a104c..0ac0ef7 100644 --- a/src/index.js +++ b/src/index.js @@ -1,9 +1,9 @@ -import PollApplication from "./applications/pollApplication.js"; import { registerHanlders } from "./handlers"; import { getSetting, + registerMenus, setSetting, - settings, + registerSettings, showNotifications, } from "./utils/settings.js"; import { registerOverlay } from "./utils/overlay.js"; @@ -33,7 +33,7 @@ function buildButtons(buttons) { name: "openPolls", title: "Open Polls", toggle: true, - onClick: () => openPolls(pollsButton), + onClick: async () => await openPolls(pollsButton), }; buttonGroup?.tools.push(pollsButton); } @@ -41,11 +41,14 @@ function buildButtons(buttons) { /** @param {SceneControlTool} button * @returns {void} */ -function openPolls(button) { - if (!polls) polls = new PollApplication(button); - //@ts-ignore - if (!polls.rendered) polls.render(true); - else polls.close(); +async function openPolls(button) { + if (!polls) { + const PollApplication = (await import("./applications/pollApplication.js")) + .default; + polls = new PollApplication(button); + } + if (!polls?.rendered) polls?.render(true); + else polls?.close(); } Hooks.once("ready", async () => { @@ -62,7 +65,8 @@ Hooks.once("ready", async () => { Hooks.on("getSceneControlButtons", buildButtons); -Hooks.on("init", () => settings.init()); +Hooks.on("init", () => registerSettings()); +Hooks.once("ready", () => registerMenus()); Hooks.on("obsUtilsInit", registerOverlay); diff --git a/src/server/chat_api.js b/src/server/chat_api.js index 5e12101..75b3be5 100644 --- a/src/server/chat_api.js +++ b/src/server/chat_api.js @@ -1,5 +1,3 @@ -import * as signalR from "@microsoft/signalr"; - /** @type {signalR.HubConnection} */ let connection; @@ -26,6 +24,7 @@ export async function initChatAPI( handleChatMessageReceived, baseURL, ) { + const signalR = await import("@microsoft/signalr"); connection = new signalR.HubConnectionBuilder() .withUrl(baseURL + "api/v2/hubs/chat", { accessTokenFactory: () => accessToken, diff --git a/src/server/connectionManager.js b/src/server/connectionManager.js index 488ff4f..23745d4 100644 --- a/src/server/connectionManager.js +++ b/src/server/connectionManager.js @@ -1,4 +1,4 @@ -import { getSetting, settings } from "../utils/settings.js"; +import { getSetting, getStore } from "../utils/settings.js"; import { Modes } from "../utils/const.js"; import { PatreonConnector } from "./patreon.js"; import { LocalServer } from "./localserver.js"; @@ -18,7 +18,7 @@ class ConnectionManager { messageListeners = undefined; constructor() { - settings.getStore("mode")?.subscribe((mode) => { + getStore("mode")?.subscribe((mode) => { this.onChangeMode(mode); }); this.messageListeners = []; diff --git a/src/server/patreon.js b/src/server/patreon.js index 966bf29..5fc0087 100644 --- a/src/server/patreon.js +++ b/src/server/patreon.js @@ -39,8 +39,9 @@ export class PatreonConnector { }); } - connect() { - connectClient().then(); + async connect() { + await this.logout(); + await connectClient(); } /** @returns {Promise} */ @@ -163,28 +164,23 @@ export class PatreonConnector { verification_uri_complete: uri, user_code, } = await patreonLogin(); - let d = new Dialog({ - title: "Device Code", - content: `The login Device Code is ${user_code}.
Either manually enter it or press open to open the login dialog. Pressing any button will close this window, please note down the code beforehand.`, - buttons: { - open: { - label: "Open", - callback: () => - window.open( - uri, - "_blank", - "location=yes,height=570,width=520,scrollbars=yes,status=yes", - ), + const LoginApplication = ( + await import("../applications/loginApplication.js") + ).default; + let d = new LoginApplication({ + svelte: { + props: { + user_code: user_code, + uri: uri, }, - close: { label: "Close" }, }, - default: "two", }); d.render(true); const { access_token, refresh_token } = await waitForPatreonVerification(device_code); await setSetting("authentication-token", access_token); await setSetting("refresh-token", refresh_token); + Hooks.callAll("ethereal-plane.patreon-logged-in"); await this.init(); } diff --git a/src/server/poll_api.js b/src/server/poll_api.js index e7cfa4e..ce97f35 100644 --- a/src/server/poll_api.js +++ b/src/server/poll_api.js @@ -1,5 +1,3 @@ -import * as signalR from "@microsoft/signalr"; - /** * @type {import('@microsoft/signalr').HubConnection} */ @@ -25,6 +23,7 @@ let connection = null; * @return {Promise} - A Promise representing the connection start operation. */ export async function initPollAPI(bearerToken, pollUpdateCallback, baseUrl) { + const signalR = await import("@microsoft/signalr"); connection = new signalR.HubConnectionBuilder() .withUrl(`${baseUrl}api/v2/hubs/polls`, { accessTokenFactory: () => bearerToken, diff --git a/src/svelte/ChatCommandConfigUI.svelte b/src/svelte/ChatCommandConfigUI.svelte index ccf2c7f..0d8db1c 100644 --- a/src/svelte/ChatCommandConfigUI.svelte +++ b/src/svelte/ChatCommandConfigUI.svelte @@ -1,16 +1,13 @@ @@ -80,7 +80,7 @@ {#if $mode === Modes.patreon || $mode === Modes.localchat} - + {/if} diff --git a/src/svelte/LoginUI.svelte b/src/svelte/LoginUI.svelte new file mode 100644 index 0000000..adb86e2 --- /dev/null +++ b/src/svelte/LoginUI.svelte @@ -0,0 +1,80 @@ + + + + + +
+
+ + The login Device Code is {user_code}. + + + Either press "Open" to open a log-in dialog directly, copy it and send + it to another device, or scan the QR code. + + + This window will automatically close when the login is complete. + +
+
+ +
+
+ + + +
+
+
+ + diff --git a/src/svelte/NotificationCenterUI.svelte b/src/svelte/NotificationCenterUI.svelte index 323fa70..ee2de26 100644 --- a/src/svelte/NotificationCenterUI.svelte +++ b/src/svelte/NotificationCenterUI.svelte @@ -21,8 +21,8 @@ function setNews(id) { news = notifications.find((notification) => notification.id === id); } - onDestroy(() => { - setSetting("lastReadNotification", cutoffDate); + onDestroy(async () => { + await setSetting("last-read-notification", cutoffDate); }); @@ -71,7 +71,7 @@ -