From e65ccce19c78e791624d866fa8e5381b30d1a71f Mon Sep 17 00:00:00 2001 From: dev Date: Sat, 31 Oct 2026 09:22:27 +0000 Subject: [PATCH] Update static/js/00-config.js --- static/js/00-config.js | 159 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 157 insertions(+), 2 deletions(-) diff --git a/static/js/00-config.js b/static/js/00-config.js index f3c7219..079e959 100644 --- a/static/js/00-config.js +++ b/static/js/00-config.js @@ -41,6 +41,7 @@ Glow.els = { themeButton: document.getElementById("themeButton"), adminUsers: document.getElementById("adminUsers"), adminRooms: document.getElementById("adminRooms"), + adminTeamsChannels: document.getElementById("adminTeamsChannels"), statusToast: document.getElementById("statusToast"), blockedOverlay: document.getElementById("blockedOverlay"), blockedMessage: document.getElementById("blockedMessage"), @@ -97,7 +98,36 @@ Glow.els = { muteCallButton: document.getElementById("muteCallButton"), hangupCallButton: document.getElementById("hangupCallButton"), endCallButton: document.getElementById("endCallButton"), - closeCallPanelButton: document.getElementById("closeCallPanelButton") + closeCallPanelButton: document.getElementById("closeCallPanelButton"), + + dmLayoutToggle: document.getElementById("dmLayoutToggle"), + emojiAutocomplete: document.getElementById("emojiAutocomplete"), + threadEmojiAutocomplete: document.getElementById("threadEmojiAutocomplete"), + settingsSavePanel: document.getElementById("settingsSavePanel"), + settingsSaveButton: document.getElementById("settingsSaveButton"), + settingsCloseButton: document.getElementById("settingsCloseButton"), + settingsUnsavedIndicator: document.getElementById("settingsUnsavedIndicator"), + avatarUploadInput: document.getElementById("avatarUploadInput"), + bannerUploadInput: document.getElementById("bannerUploadInput"), + imageCropOverlay: document.getElementById("imageCropOverlay"), + imageCropPreview: document.getElementById("imageCropPreview"), + imageCropZoom: document.getElementById("imageCropZoom"), + imageCropAuto: document.getElementById("imageCropAuto"), + imageCropApply: document.getElementById("imageCropApply"), + imageCropCancel: document.getElementById("imageCropCancel"), + adminTabRooms: document.getElementById("adminTabRooms"), + adminTabUsers: document.getElementById("adminTabUsers"), + adminTabTeams: document.getElementById("adminTabTeams"), + adminRoomsPanel: document.getElementById("adminRoomsPanel"), + adminUsersPanel: document.getElementById("adminUsersPanel"), + adminTeamsPanel: document.getElementById("adminTeamsPanel"), + callDragHandle: document.getElementById("callDragHandle"), + callSummaryStats: document.getElementById("callSummaryStats"), + callLatencyStat: document.getElementById("callLatencyStat"), + callPacketLossStat: document.getElementById("callPacketLossStat"), + callUptimeStat: document.getElementById("callUptimeStat"), + callUserCountStat: document.getElementById("callUserCountStat"), + callElapsedStat: document.getElementById("callElapsedStat") }; Glow.state = { @@ -135,6 +165,9 @@ Glow.state = { pageTypeFilter: "", activeProfile: null, settings: null, + settingsSaved: null, + settingsDraft: null, + settingsDirty: false, pollTimer: null, initialized: false, toastTimer: null, @@ -154,6 +187,33 @@ Glow.state = { originalTitle: document.title, dialogResolver: null, lastFocusedElement: null, + dmLayoutMode: + localStorage.getItem("glow_dm_layout_mode") === "compact" + ? "compact" + : "cards", + profilePresenceBadgeVisible: + localStorage.getItem("glow_profile_presence_badge_visible") !== "false", + profileMediaDraft: { + avatarFile: null, + bannerFile: null + }, + imageCrop: { + open: false, + kind: "", + file: null, + previewUrl: "", + zoom: 1, + autoCrop: false + }, + emojiAutocomplete: { + open: false, + owner: "main", + query: "", + suggestions: [], + selectedIndex: 0, + triggerIndex: -1 + }, + adminTab: "rooms", presence: { roomOnlineCount: 0, channelOnlineCount: 0, @@ -185,7 +245,21 @@ Glow.state = { }, backendParticipants: [], scope: null, - statusText: "Idle" + statusText: "Idle", + metrics: { + packetLoss: null, + uptime: null, + latency: null, + elapsedSeconds: 0, + userCount: 0 + }, + drag: { + active: false, + x: null, + y: null, + offsetX: 0, + offsetY: 0 + } } }; @@ -263,6 +337,38 @@ Glow.resetAccentColor = () => { Glow.applyAccentColor(Glow.DEFAULT_ACCENT_COLOR); }; +Glow.loadDmLayoutPreference = () => { + const stored = localStorage.getItem("glow_dm_layout_mode"); + return stored === "compact" ? "compact" : "cards"; +}; + +Glow.saveDmLayoutPreference = mode => { + const normalized = mode === "compact" ? "compact" : "cards"; + Glow.state.dmLayoutMode = normalized; + localStorage.setItem("glow_dm_layout_mode", normalized); +}; + +Glow.isSettingsDirty = () => Boolean(Glow.state.settingsDirty); + +Glow.markSettingsDirty = () => { + Glow.state.settingsDirty = true; + Glow.syncSettingsSavePanel?.(); +}; + +Glow.clearSettingsDirty = () => { + Glow.state.settingsDirty = false; + Glow.syncSettingsSavePanel?.(); +}; + +Glow.getTimestampVisibilityMode = () => { + return Glow.state.activeDm ? "hover" : "always"; +}; + +Glow.shouldShowMessageTimestamp = (_message = null, context = null) => { + const view = context || Glow.getTimestampVisibilityMode(); + return view !== "hover"; +}; + Glow.roleDefaultNameColor = role => { switch (String(role || "").toLowerCase()) { case "admin": @@ -414,6 +520,55 @@ Glow.normalizeSelectedFiles = fileList => { return [...fileList].filter(Boolean); }; +Glow.websiteBrandMeta = value => { + if (typeof value !== "string" || !value.trim()) { + return { + host: "", + brand: "web", + label: "website", + iconText: "â—‹" + }; + } + + try { + const url = new URL(value); + const host = url.hostname.toLowerCase().replace(/^www\./, ""); + + const mappings = [ + { match: /github\.com$/, brand: "github", label: "GitHub", iconText: "gh" }, + { match: /youtube\.com$|youtu\.be$/, brand: "youtube", label: "YouTube", iconText: "yt" }, + { match: /spotify\.com$/, brand: "spotify", label: "Spotify", iconText: "sp" }, + { match: /soundcloud\.com$/, brand: "soundcloud", label: "SoundCloud", iconText: "sc" }, + { match: /twitter\.com$|x\.com$/, brand: "x", label: "X", iconText: "x" } + ]; + + for (const item of mappings) { + if (item.match.test(host)) { + return { + host, + brand: item.brand, + label: item.label, + iconText: item.iconText + }; + } + } + + return { + host, + brand: "web", + label: "website", + iconText: "â—‹" + }; + } catch (_) { + return { + host: "", + brand: "web", + label: "website", + iconText: "â—‹" + }; + } +}; + Glow.openDialog = ({ title, body,