From c7ee1bb0bf9e707bef9669a37a8969f6abbfd489 Mon Sep 17 00:00:00 2001 From: creations Date: Thu, 29 May 2025 16:45:42 -0400 Subject: [PATCH] move to a list on load instead of each reqest, move refresh and set database to toolbox --- .../timezones/TimezoneModal.tsx | 11 +-- src/equicordplugins/timezones/database.tsx | 65 ++++++-------- src/equicordplugins/timezones/index.tsx | 86 ++++++++----------- 3 files changed, 66 insertions(+), 96 deletions(-) diff --git a/src/equicordplugins/timezones/TimezoneModal.tsx b/src/equicordplugins/timezones/TimezoneModal.tsx index 4b9f859c..8966c94f 100644 --- a/src/equicordplugins/timezones/TimezoneModal.tsx +++ b/src/equicordplugins/timezones/TimezoneModal.tsx @@ -24,19 +24,14 @@ export function SetTimezoneModal({ userId, modalProps, database }: { userId: str const [currentValue, setCurrentValue] = useState(timezones[userId] ?? null); useEffect(() => { - if (!database) return; - const localTimezone = timezones[userId]; const shouldUseDatabase = settings.store.useDatabase && (settings.store.preferDatabaseOverLocal || !localTimezone); - if (shouldUseDatabase) { - getTimezone(userId).then(e => setCurrentValue(e ?? localTimezone)); - } else { - setCurrentValue(localTimezone); - } - }, [userId, settings.store.useDatabase, settings.store.preferDatabaseOverLocal, database]); + setCurrentValue(shouldUseDatabase ? getTimezone(userId) ?? localTimezone : localTimezone); + }, [userId, settings.store.useDatabase, settings.store.preferDatabaseOverLocal]); + const options = useMemo(() => { return Intl.supportedValuesOf("timeZone").map(timezone => { diff --git a/src/equicordplugins/timezones/database.tsx b/src/equicordplugins/timezones/database.tsx index 643f760b..7bbd6ff8 100644 --- a/src/equicordplugins/timezones/database.tsx +++ b/src/equicordplugins/timezones/database.tsx @@ -4,55 +4,45 @@ * SPDX-License-Identifier: GPL-3.0-or-later */ -import { DataStore } from "@api/index"; -import { openModal } from "@utils/modal"; +import { openModal } from "@utils/index"; import { OAuth2AuthorizeModal, showToast, Toasts } from "@webpack/common"; -import { databaseTimezones } from "."; +const databaseTimezones: Record = {}; -export const DOMAIN = "https://timezone.creations.works"; -export const REDIRECT_URI = `${DOMAIN}/auth/discord/callback`; -export const CLIENT_ID = "1377021506810417173"; - -export const DATASTORE_KEY = "vencord-database-timezones"; - -const pendingRequests: Record> = {}; +const DOMAIN = "https://timezone.creations.works"; +const REDIRECT_URI = `${DOMAIN}/auth/discord/callback`; +const CLIENT_ID = "1377021506810417173"; export async function setUserDatabaseTimezone(userId: string, timezone: string | null) { - databaseTimezones[userId] = { - value: timezone, - expires: Date.now() + 60 * 60 * 1000 // 1 hour - }; - await DataStore.set(DATASTORE_KEY, databaseTimezones); + databaseTimezones[userId] = { value: timezone }; } -export async function getTimezone(userId: string, force?: boolean): Promise { - const now = Date.now(); +export function getTimezone(userId: string): string | null { + return databaseTimezones[userId]?.value ?? null; +} - const cached = databaseTimezones[userId]; - if (cached && now < cached.expires && !force) return cached.value; +export async function loadDatabaseTimezones(): Promise { + try { + const res = await fetch(`${DOMAIN}/list`, { + headers: { Accept: "application/json" } + }); - if (!pendingRequests[userId]) { - pendingRequests[userId] = (async () => { - const res = await fetch(`${DOMAIN}/get?id=${userId}`, { - headers: { Accept: "application/json" } - }); - - let value: string | null = null; - if (res.ok) { - const json = await res.json(); - if (json?.timezone && typeof json.timezone === "string") { - value = json.timezone; - } + if (res.ok) { + const json = await res.json(); + for (const id in json) { + databaseTimezones[id] = { + value: json[id]?.timezone ?? null + }; } - setUserDatabaseTimezone(userId, value); - delete pendingRequests[userId]; - return value; - })(); - } + return true; + } - return pendingRequests[userId]; + return false; + } catch (e) { + console.error("Failed to fetch timezones list:", e); + return false; + } } export async function setTimezone(timezone: string): Promise { @@ -115,4 +105,3 @@ export function authModal(callback?: () => void) { /> )); } - diff --git a/src/equicordplugins/timezones/index.tsx b/src/equicordplugins/timezones/index.tsx index 12d58f72..733e694d 100644 --- a/src/equicordplugins/timezones/index.tsx +++ b/src/equicordplugins/timezones/index.tsx @@ -1,6 +1,6 @@ /* * Vencord, a Discord client mod - * Copyright (c) 2024 Vendicated and contributors + * Copyright (c) 2025 Vendicated and contributors * SPDX-License-Identifier: GPL-3.0-or-later */ @@ -17,15 +17,9 @@ import { findByPropsLazy } from "@webpack"; import { Button, Menu, showToast, Toasts, Tooltip, useEffect, UserStore, useState } from "@webpack/common"; import { Message, User } from "discord-types/general"; -import { authModal, deleteTimezone, getTimezone, setUserDatabaseTimezone } from "./database"; +import { authModal, deleteTimezone, getTimezone, loadDatabaseTimezones, setUserDatabaseTimezone } from "./database"; import { SetTimezoneModal } from "./TimezoneModal"; -type CacheEntry = { - value: string | null; - expires: number; -}; - -export let databaseTimezones: Record = {}; export let timezones: Record = {}; export const DATASTORE_KEY = "vencord-timezones"; @@ -70,8 +64,7 @@ export const settings = definePluginSettings({ @@ -112,6 +105,7 @@ interface Props { timestamp?: string; type: "message" | "profile"; } + const TimestampComponent = ErrorBoundary.wrap(({ userId, timestamp, type }: Props) => { const [currentTime, setCurrentTime] = useState(timestamp || Date.now()); const [timezone, setTimezone] = useState(null); @@ -123,7 +117,7 @@ const TimestampComponent = ErrorBoundary.wrap(({ userId, timestamp, type }: Prop (settings.store.preferDatabaseOverLocal || !localTimezone); if (shouldUseDatabase) { - getTimezone(userId).then(e => setTimezone(e ?? localTimezone)); + setTimezone(getTimezone(userId) ?? localTimezone); } else { setTimezone(localTimezone); } @@ -178,45 +172,19 @@ const TimestampComponent = ErrorBoundary.wrap(({ userId, timestamp, type }: Prop ); }, { noop: true }); - const userContextMenuPatch: NavContextMenuPatchCallback = (children, { user }: { user: User; }) => { if (user?.id == null) return; + const label = settings.store.useDatabase ? "Set Local Timezone" : "Set Timezone"; const setTimezoneItem = ( openModal(modalProps => )} /> ); children.push(, setTimezoneItem); - - if (settings.store.useDatabase) { - const refreshTimezoneItem = ( - { - showToast("Refreshing timezone...", Toasts.Type.CLOCK); - - try { - const timezone = await getTimezone(user.id, true); - - if (timezone) { - showToast("Timezone refreshed successfully!", Toasts.Type.SUCCESS); - } else { - showToast("Timezone reset successfully!", Toasts.Type.SUCCESS); - } - } catch (error) { - console.error("Failed to refresh timezone:", error); - showToast("Failed to refresh timezone.", Toasts.Type.FAILURE); - } - }} - /> - ); - children.push(refreshTimezoneItem); - } }; export default definePlugin({ @@ -246,31 +214,49 @@ export default definePlugin({ } ], + toolboxActions: { + "Set Database Timezone": () => { + authModal(async () => { + openModal(modalProps => ); + }); + }, + "Refresh Database Timezones": async () => { + try { + const good = await loadDatabaseTimezones(); + + if (good) { + showToast("Timezones refreshed successfully!", Toasts.Type.SUCCESS); + } else { + showToast("Timezones Failed to refresh!", Toasts.Type.FAILURE); + } + } + catch (error) { + console.error("Failed to refresh timezone:", error); + showToast("Failed to refresh timezones.", Toasts.Type.FAILURE); + } + } + }, + async start() { - databaseTimezones = await DataStore.get>(DATASTORE_KEY) || {}; timezones = await DataStore.get>(DATASTORE_KEY) || {}; + + if (settings.store.useDatabase) { + await loadDatabaseTimezones(); + } }, settings, getTime, - renderProfileTimezone: (props?: { user?: User; }) => { if (!settings.store.showProfileTime || !props?.user?.id) return null; - return ; + return ; }, renderMessageTimezone: (props?: { message?: Message; }) => { if (!settings.store.showMessageHeaderTime || !props?.message) return null; - return ; + return ; } });