mirror of
https://github.com/Vendicated/Vencord.git
synced 2025-02-23 23:15:10 +00:00
separate components/remove api backend setting/wip oauth
This commit is contained in:
parent
964801da3a
commit
1fd506da73
7 changed files with 210 additions and 150 deletions
|
@ -7,15 +7,12 @@
|
||||||
import { DataStore } from "@api/index";
|
import { DataStore } from "@api/index";
|
||||||
import { Logger } from "@utils/Logger";
|
import { Logger } from "@utils/Logger";
|
||||||
import { openModal } from "@utils/modal";
|
import { openModal } from "@utils/modal";
|
||||||
import { findByPropsLazy } from "@webpack";
|
import { OAuth2AuthorizeModal, showToast, Toasts, UserStore } from "@webpack/common";
|
||||||
import { showToast, Toasts, UserStore } from "@webpack/common";
|
|
||||||
|
|
||||||
import { ReviewDBAuth } from "./entities";
|
import { ReviewDBAuth } from "./entities";
|
||||||
|
|
||||||
const DATA_STORE_KEY = "rdb-auth";
|
const DATA_STORE_KEY = "rdb-auth";
|
||||||
|
|
||||||
const { OAuth2AuthorizeModal } = findByPropsLazy("OAuth2AuthorizeModal");
|
|
||||||
|
|
||||||
export let Auth: ReviewDBAuth = {};
|
export let Auth: ReviewDBAuth = {};
|
||||||
|
|
||||||
export async function initAuth() {
|
export async function initAuth() {
|
||||||
|
|
|
@ -6,33 +6,33 @@
|
||||||
|
|
||||||
import { VENCORD_USER_AGENT } from "@shared/vencordUserAgent";
|
import { VENCORD_USER_AGENT } from "@shared/vencordUserAgent";
|
||||||
import { Logger } from "@utils/Logger";
|
import { Logger } from "@utils/Logger";
|
||||||
|
import { UserStore } from "@webpack/common";
|
||||||
|
|
||||||
import settings from "./settings";
|
import settings from "./settings";
|
||||||
|
|
||||||
export const DEFAULT_API = "https://timezonedb.catvibers.me/api";
|
export const API_URL: string = "https://timezonedb.catvibers.me/api";
|
||||||
|
|
||||||
export type Snowflake = string;
|
export type Snowflake = string;
|
||||||
type ApiError = { error: string; };
|
type ApiError = { error: string; };
|
||||||
type UserFetchResponse = ApiError | { timezoneId: string }
|
type UserFetchResponse = ApiError | { timezoneId: string }
|
||||||
type BulkFetchResponse = ApiError | Record<Snowflake, { timezoneId: string | null }>;
|
type BulkFetchResponse = ApiError | Record<Snowflake, { timezoneId: string | null }>;
|
||||||
|
|
||||||
export async function verifyApi(url: string): Promise<boolean> {
|
export async function verifyLogin(token: string): Promise<boolean> {
|
||||||
if (url === DEFAULT_API) return true;
|
const res = await fetch(API_URL, {
|
||||||
|
|
||||||
const res = await fetch(url, {
|
|
||||||
method: "GET",
|
method: "GET",
|
||||||
headers: {
|
headers: {
|
||||||
"User-Agent": VENCORD_USER_AGENT,
|
"User-Agent": VENCORD_USER_AGENT,
|
||||||
|
"Authorization": token,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return "logged_in" in await res.json();
|
const json: { logged_in?: boolean } = await res.json();
|
||||||
|
return !!json.logged_in;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchTimezonesBulk(ids: Snowflake[]): Promise<Record<Snowflake, string | null> | undefined> {
|
export async function fetchTimezonesBulk(ids: Snowflake[]): Promise<Record<Snowflake, string | null> | undefined> {
|
||||||
try {
|
try {
|
||||||
const { apiUrl } = settings.store;
|
const req = await fetch(`${API_URL}/user/bulk`, {
|
||||||
const req = await fetch(`${apiUrl}/user/bulk`, {
|
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
|
@ -58,8 +58,7 @@ export async function fetchTimezonesBulk(ids: Snowflake[]): Promise<Record<Snowf
|
||||||
|
|
||||||
export async function fetchTimezone(userId: Snowflake): Promise<string | null | undefined> {
|
export async function fetchTimezone(userId: Snowflake): Promise<string | null | undefined> {
|
||||||
try {
|
try {
|
||||||
const { apiUrl } = settings.store;
|
const req = await fetch(`${API_URL}/user/${userId}`, {
|
||||||
const req = await fetch(`${apiUrl}/user/${userId}`, {
|
|
||||||
method: "GET",
|
method: "GET",
|
||||||
headers: {
|
headers: {
|
||||||
"User-Agent": VENCORD_USER_AGENT,
|
"User-Agent": VENCORD_USER_AGENT,
|
||||||
|
@ -80,3 +79,10 @@ export async function fetchTimezone(userId: Snowflake): Promise<string | null |
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getCurrentToken(): string | undefined {
|
||||||
|
const userId = UserStore.getCurrentUser().id;
|
||||||
|
const { tokens } = settings.store;
|
||||||
|
|
||||||
|
return tokens[userId];
|
||||||
|
}
|
||||||
|
|
95
src/plugins/timezones/components/LocalTimestamp.tsx
Normal file
95
src/plugins/timezones/components/LocalTimestamp.tsx
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
/*
|
||||||
|
* Vencord, a Discord client mod
|
||||||
|
* Copyright (c) 2024 Vendicated and contributors
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
import "../styles.css";
|
||||||
|
|
||||||
|
import { ErrorBoundary } from "@components/index";
|
||||||
|
import { findByPropsLazy } from "@webpack";
|
||||||
|
import { React, Tooltip, useEffect, useState } from "@webpack/common";
|
||||||
|
|
||||||
|
import { Snowflake } from "../api";
|
||||||
|
import { getUserTimezone } from "../cache";
|
||||||
|
import { formatTimestamp } from "../utils";
|
||||||
|
import { openTimezoneOverrideModal } from "./SetTimezoneOverrideModal";
|
||||||
|
|
||||||
|
// Based on Syncxv's vc-timezones user plugin //
|
||||||
|
|
||||||
|
const messageClasses = findByPropsLazy("timestamp", "compact", "contentOnly");
|
||||||
|
|
||||||
|
interface LocalTimestampProps {
|
||||||
|
userId: Snowflake;
|
||||||
|
timestamp?: Date;
|
||||||
|
type: "message" | "profile";
|
||||||
|
}
|
||||||
|
|
||||||
|
export function LocalTimestamp(props: LocalTimestampProps): JSX.Element {
|
||||||
|
return <ErrorBoundary noop={true} wrappedProps={props}>
|
||||||
|
<LocalTimestampInner {...props} />
|
||||||
|
</ErrorBoundary>;
|
||||||
|
}
|
||||||
|
|
||||||
|
function LocalTimestampInner(props: LocalTimestampProps): JSX.Element | null {
|
||||||
|
const [timezone, setTimezone] = useState<string | null>();
|
||||||
|
const [timestamp, setTimestamp] = useState(props.timestamp ?? Date.now());
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!timezone) {
|
||||||
|
getUserTimezone(props.userId, props.type === "profile").then(setTimezone);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let timer: NodeJS.Timeout;
|
||||||
|
|
||||||
|
if (props.type === "profile") {
|
||||||
|
setTimestamp(Date.now());
|
||||||
|
|
||||||
|
const now = new Date();
|
||||||
|
const delay = (60 - now.getSeconds()) * 1000 + 1000 - now.getMilliseconds();
|
||||||
|
|
||||||
|
timer = setTimeout(() => setTimestamp(Date.now()), delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => timer && clearTimeout(timer);
|
||||||
|
}, [timezone, timestamp]);
|
||||||
|
|
||||||
|
if (!timezone) return null;
|
||||||
|
|
||||||
|
const longTime = formatTimestamp(timezone, timestamp, true);
|
||||||
|
const shortTime = formatTimestamp(timezone, timestamp, false);
|
||||||
|
|
||||||
|
if (props.type === "message" && !shortTime)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
const shortTimeFormatted = props.type === "message"
|
||||||
|
? `• ${shortTime}`
|
||||||
|
: shortTime ?? "Error";
|
||||||
|
const classes = props.type === "message"
|
||||||
|
? `vc-timezones-message-display ${messageClasses.timestamp}`
|
||||||
|
: "vc-timezones-profile-display";
|
||||||
|
|
||||||
|
return <Tooltip
|
||||||
|
position="top"
|
||||||
|
// @ts-ignore
|
||||||
|
delay={750}
|
||||||
|
allowOverflow={false}
|
||||||
|
spacing={8}
|
||||||
|
hideOnClick={true}
|
||||||
|
tooltipClassName="vc-timezones-tooltip"
|
||||||
|
hide={!longTime}
|
||||||
|
text={longTime}
|
||||||
|
>
|
||||||
|
{toolTipProps => <>
|
||||||
|
<span {...toolTipProps}
|
||||||
|
className={classes}
|
||||||
|
onClick={() => {
|
||||||
|
toolTipProps.onClick();
|
||||||
|
openTimezoneOverrideModal(props.userId);
|
||||||
|
}}>
|
||||||
|
{shortTimeFormatted}
|
||||||
|
</span>
|
||||||
|
</>}
|
||||||
|
</Tooltip>;
|
||||||
|
}
|
|
@ -4,7 +4,7 @@
|
||||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import "./styles.css";
|
import "../styles.css";
|
||||||
|
|
||||||
import { ErrorBoundary, Link } from "@components/index";
|
import { ErrorBoundary, Link } from "@components/index";
|
||||||
import { Margins } from "@utils/margins";
|
import { Margins } from "@utils/margins";
|
||||||
|
@ -18,102 +18,27 @@ import {
|
||||||
ModalRoot,
|
ModalRoot,
|
||||||
openModal,
|
openModal,
|
||||||
} from "@utils/modal";
|
} from "@utils/modal";
|
||||||
import { findByPropsLazy } from "@webpack";
|
import { Button, Forms, React, SearchableSelect, Text, useEffect, useState } from "@webpack/common";
|
||||||
import { Button, Forms, React, SearchableSelect, Text, Tooltip, useEffect, useState } from "@webpack/common";
|
|
||||||
import { SelectOption } from "@webpack/types";
|
import { SelectOption } from "@webpack/types";
|
||||||
|
|
||||||
import { Snowflake } from "./api";
|
import settings, { TimezoneOverrides } from "../settings";
|
||||||
import { getUserTimezone } from "./cache";
|
import { getTimezonesLazy } from "../utils";
|
||||||
import settings, { TimezoneOverrides } from "./settings";
|
import { openTimezoneDBAuthModal } from "./TimezoneDBAuthModal";
|
||||||
import { formatTimestamp, getTimezonesLazy } from "./utils";
|
|
||||||
|
|
||||||
// Based on Syncxv's vc-timezones user plugin //
|
export function openTimezoneOverrideModal(userId: string) {
|
||||||
|
openModal(modalProps => <>
|
||||||
const messageClasses = findByPropsLazy("timestamp", "compact", "contentOnly");
|
<ErrorBoundary>
|
||||||
|
<SetTimezoneOverrideModal userId={userId} modalProps={modalProps} />
|
||||||
interface LocalTimestampProps {
|
</ErrorBoundary>
|
||||||
userId: Snowflake;
|
</>);
|
||||||
timestamp?: Date;
|
|
||||||
type: "message" | "profile";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function LocalTimestamp(props: LocalTimestampProps): JSX.Element {
|
interface SetTimezoneOverrideModalProps {
|
||||||
return <ErrorBoundary noop={true} wrappedProps={props}>
|
|
||||||
<LocalTimestampInner {...props} />
|
|
||||||
</ErrorBoundary>;
|
|
||||||
}
|
|
||||||
|
|
||||||
function LocalTimestampInner(props: LocalTimestampProps): JSX.Element | null {
|
|
||||||
const [timezone, setTimezone] = useState<string | null>();
|
|
||||||
const [timestamp, setTimestamp] = useState(props.timestamp ?? Date.now());
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!timezone) {
|
|
||||||
getUserTimezone(props.userId, props.type === "profile").then(setTimezone);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let timer: NodeJS.Timeout;
|
|
||||||
|
|
||||||
if (props.type === "profile") {
|
|
||||||
setTimestamp(Date.now());
|
|
||||||
|
|
||||||
const now = new Date();
|
|
||||||
const delay = (60 - now.getSeconds()) * 1000 + 1000 - now.getMilliseconds();
|
|
||||||
|
|
||||||
timer = setTimeout(() => setTimestamp(Date.now()), delay);
|
|
||||||
}
|
|
||||||
|
|
||||||
return () => timer && clearTimeout(timer);
|
|
||||||
}, [timezone, timestamp]);
|
|
||||||
|
|
||||||
if (!timezone) return null;
|
|
||||||
|
|
||||||
const longTime = formatTimestamp(timezone, timestamp, true);
|
|
||||||
const shortTime = formatTimestamp(timezone, timestamp, false);
|
|
||||||
|
|
||||||
if (props.type === "message" && !shortTime)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
const shortTimeFormatted = props.type === "message"
|
|
||||||
? `• ${shortTime}`
|
|
||||||
: shortTime ?? "Error";
|
|
||||||
const classes = props.type === "message"
|
|
||||||
? `vc-timezones-message-display ${messageClasses.timestamp}`
|
|
||||||
: "vc-timezones-profile-display";
|
|
||||||
|
|
||||||
return <>
|
|
||||||
<Tooltip
|
|
||||||
position="top"
|
|
||||||
// @ts-ignore
|
|
||||||
delay={750}
|
|
||||||
allowOverflow={false}
|
|
||||||
spacing={8}
|
|
||||||
hideOnClick={true}
|
|
||||||
tooltipClassName="vc-timezones-tooltip"
|
|
||||||
hide={!longTime}
|
|
||||||
text={longTime}
|
|
||||||
>
|
|
||||||
{toolTipProps => <>
|
|
||||||
<span {...toolTipProps}
|
|
||||||
className={classes}
|
|
||||||
onClick={() => {
|
|
||||||
toolTipProps.onClick();
|
|
||||||
openTimezoneOverrideModal(props.userId);
|
|
||||||
}}>
|
|
||||||
{shortTimeFormatted}
|
|
||||||
</span>
|
|
||||||
</>}
|
|
||||||
</Tooltip>
|
|
||||||
</>;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface TimezoneOverrideModalProps {
|
|
||||||
userId: string,
|
userId: string,
|
||||||
modalProps: ModalProps,
|
modalProps: ModalProps,
|
||||||
}
|
}
|
||||||
|
|
||||||
function SetTimezoneOverrideModal(props: TimezoneOverrideModalProps) {
|
function SetTimezoneOverrideModal(props: SetTimezoneOverrideModalProps) {
|
||||||
const [availableTimezones, setAvailableTimezones] = useState<SelectOption[]>();
|
const [availableTimezones, setAvailableTimezones] = useState<SelectOption[]>();
|
||||||
const [timezone, setTimezone] = useState<string | "NONE" | undefined>();
|
const [timezone, setTimezone] = useState<string | "NONE" | undefined>();
|
||||||
|
|
||||||
|
@ -174,7 +99,7 @@ function SetTimezoneOverrideModal(props: TimezoneOverrideModalProps) {
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
To set your own Timezone for other users to see,
|
To set your own Timezone for other users to see,
|
||||||
click <Link onClick={/* TODO */ _ => _}>here</Link> to
|
click <Link onClick={openTimezoneDBAuthModal}>here</Link> to
|
||||||
authorize the public TimezoneDB API.
|
authorize the public TimezoneDB API.
|
||||||
</Text>
|
</Text>
|
||||||
|
|
||||||
|
@ -207,11 +132,3 @@ function SetTimezoneOverrideModal(props: TimezoneOverrideModalProps) {
|
||||||
</ModalFooter>
|
</ModalFooter>
|
||||||
</ModalRoot>;
|
</ModalRoot>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function openTimezoneOverrideModal(userId: string) {
|
|
||||||
openModal(modalProps => <>
|
|
||||||
<ErrorBoundary>
|
|
||||||
<SetTimezoneOverrideModal userId={userId} modalProps={modalProps} />
|
|
||||||
</ErrorBoundary>
|
|
||||||
</>);
|
|
||||||
}
|
|
67
src/plugins/timezones/components/TimezoneDBAuthModal.tsx
Normal file
67
src/plugins/timezones/components/TimezoneDBAuthModal.tsx
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
/*
|
||||||
|
* Vencord, a Discord client mod
|
||||||
|
* Copyright (c) 2024 Vendicated and contributors
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
|
import { VENCORD_USER_AGENT } from "@shared/vencordUserAgent";
|
||||||
|
import { Logger } from "@utils/Logger";
|
||||||
|
import { ModalProps, openModal } from "@utils/modal";
|
||||||
|
import { OAuth2AuthorizeModal, showToast, Toasts, UserStore } from "@webpack/common";
|
||||||
|
|
||||||
|
import { API_URL, getCurrentToken, verifyLogin } from "../api";
|
||||||
|
import settings from "../settings";
|
||||||
|
|
||||||
|
const REDIRECT_URI: string = `${API_URL}/auth`;
|
||||||
|
const CLIENT_ID: string = "922650528821940224";
|
||||||
|
const SCOPES: string[] = ["identify"];
|
||||||
|
|
||||||
|
export async function openTimezoneDBAuthModal() {
|
||||||
|
const token = getCurrentToken();
|
||||||
|
if (token && await verifyLogin(token)) return; // TODO: open set current user modal
|
||||||
|
|
||||||
|
openModal(modalProps => <>
|
||||||
|
<ErrorBoundary>
|
||||||
|
<TimezoneDBAuthModal {...modalProps} />
|
||||||
|
</ErrorBoundary>
|
||||||
|
</>);
|
||||||
|
}
|
||||||
|
|
||||||
|
function TimezoneDBAuthModal(modalProps: ModalProps): JSX.Element {
|
||||||
|
return <OAuth2AuthorizeModal
|
||||||
|
{...modalProps}
|
||||||
|
scopes={SCOPES}
|
||||||
|
responseType="code"
|
||||||
|
redirectUri={REDIRECT_URI}
|
||||||
|
permissions={0n}
|
||||||
|
clientId={CLIENT_ID}
|
||||||
|
cancelCompletesFlow={false}
|
||||||
|
callback={async (response: { location: string }) => {
|
||||||
|
try {
|
||||||
|
const res = await fetch(response.location, {
|
||||||
|
redirect: "manual",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": VENCORD_USER_AGENT,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const { token } = await res.json() as { token: string };
|
||||||
|
|
||||||
|
if (!await verifyLogin(token)) {
|
||||||
|
throw "Returned token was invalid!";
|
||||||
|
}
|
||||||
|
|
||||||
|
settings.store.tokens = {
|
||||||
|
[UserStore.getCurrentUser().id]: token,
|
||||||
|
...settings.store.tokens,
|
||||||
|
};
|
||||||
|
|
||||||
|
showToast("Successfully connected to TimezoneDB!", Toasts.Type.SUCCESS);
|
||||||
|
} catch (e) {
|
||||||
|
showToast("Failed to authorize TimezoneDB!", Toasts.Type.FAILURE);
|
||||||
|
new Logger("Timezones").error("Failed to authorize TimezoneDB", e);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>;
|
||||||
|
}
|
|
@ -7,14 +7,12 @@
|
||||||
import { NavContextMenuPatchCallback } from "@api/ContextMenu";
|
import { NavContextMenuPatchCallback } from "@api/ContextMenu";
|
||||||
import { CogWheel } from "@components/Icons";
|
import { CogWheel } from "@components/Icons";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import { Logger } from "@utils/Logger";
|
|
||||||
import definePlugin from "@utils/types";
|
import definePlugin from "@utils/types";
|
||||||
import { Menu, UserStore } from "@webpack/common";
|
import { Menu, UserStore } from "@webpack/common";
|
||||||
import { Message, User } from "discord-types/general";
|
import { Message, User } from "discord-types/general";
|
||||||
import { Promisable } from "type-fest";
|
|
||||||
|
|
||||||
import { verifyApi } from "./api";
|
import { LocalTimestamp } from "./components/LocalTimestamp";
|
||||||
import { LocalTimestamp, openTimezoneOverrideModal } from "./components";
|
import { openTimezoneOverrideModal } from "./components/SetTimezoneOverrideModal";
|
||||||
import settings, { SettingsComponent } from "./settings";
|
import settings, { SettingsComponent } from "./settings";
|
||||||
|
|
||||||
const contextMenuPatch: NavContextMenuPatchCallback = (children, { user }: { user: User }) => {
|
const contextMenuPatch: NavContextMenuPatchCallback = (children, { user }: { user: User }) => {
|
||||||
|
@ -57,7 +55,7 @@ export default definePlugin({
|
||||||
},
|
},
|
||||||
})),
|
})),
|
||||||
{
|
{
|
||||||
find: '"Message Username"',
|
find: "\"Message Username\"",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /(?<=isVisibleOnlyOnHover.+?)id:.{1,11},timestamp.{1,50}}\),/,
|
match: /(?<=isVisibleOnlyOnHover.+?)id:.{1,11},timestamp.{1,50}}\),/,
|
||||||
replace: "$&,$self.renderMessageTimezone(arguments[0]),",
|
replace: "$&,$self.renderMessageTimezone(arguments[0]),",
|
||||||
|
@ -70,20 +68,6 @@ export default definePlugin({
|
||||||
"user-profile-overflow-menu": contextMenuPatch,
|
"user-profile-overflow-menu": contextMenuPatch,
|
||||||
},
|
},
|
||||||
|
|
||||||
beforeSave(options: Record<string, any>): Promisable<true | string> {
|
|
||||||
// Check that API url is valid
|
|
||||||
const { apiUrl } = options;
|
|
||||||
if (!apiUrl) return "Invalid API url!";
|
|
||||||
|
|
||||||
return verifyApi(apiUrl).then(success => {
|
|
||||||
if (success) return true;
|
|
||||||
return "Failed to verify API!";
|
|
||||||
}).catch(err => {
|
|
||||||
new Logger("Timezones").info("Failed to verify API url", err);
|
|
||||||
return "Failed to verify API!";
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
renderProfileTimezone: (props?: { user?: User; }) => {
|
renderProfileTimezone: (props?: { user?: User; }) => {
|
||||||
if (!settings.store.displayInProfile || !props?.user?.id) return null;
|
if (!settings.store.displayInProfile || !props?.user?.id) return null;
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { DataStore } from "@api/index";
|
|
||||||
import { definePluginSettings } from "@api/Settings";
|
import { definePluginSettings } from "@api/Settings";
|
||||||
import { Link } from "@components/Link";
|
import { Link } from "@components/Link";
|
||||||
import { Margins } from "@utils/margins";
|
import { Margins } from "@utils/margins";
|
||||||
|
@ -24,25 +23,24 @@ import { classes } from "@utils/misc";
|
||||||
import { IPluginOptionComponentProps, OptionType } from "@utils/types";
|
import { IPluginOptionComponentProps, OptionType } from "@utils/types";
|
||||||
import { Text } from "@webpack/common";
|
import { Text } from "@webpack/common";
|
||||||
|
|
||||||
import { DEFAULT_API, Snowflake } from "./api";
|
import { Snowflake } from "./api";
|
||||||
import { TimezoneCache } from "./cache";
|
|
||||||
|
|
||||||
|
/** A mapping of each user id to the override, being either a timezone or "disabled" */
|
||||||
export type TimezoneOverrides = Record<Snowflake, string | null>;
|
export type TimezoneOverrides = Record<Snowflake, string | null>;
|
||||||
|
|
||||||
|
/* A mapping of each authorized user id to the JWT token returned by the API. */
|
||||||
|
export type TimezoneDBTokens = Record<Snowflake, string>;
|
||||||
|
|
||||||
const settings = definePluginSettings({
|
const settings = definePluginSettings({
|
||||||
enableApi: {
|
enableApi: {
|
||||||
type: OptionType.BOOLEAN,
|
type: OptionType.BOOLEAN,
|
||||||
description: "Fetch user timezones from TimezoneDB when a local override does not exist",
|
description: "Fetch user timezones from TimezoneDB when a local override does not exist",
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
apiUrl: {
|
tokens: {
|
||||||
type: OptionType.STRING,
|
type: OptionType.COMPONENT,
|
||||||
description: "The TimezoneDB API instance",
|
description: "Authorization with TimezoneDB",
|
||||||
default: DEFAULT_API,
|
component: props => <AuthorizeTimezoneDBSetting {...props} />,
|
||||||
placeholder: DEFAULT_API,
|
|
||||||
onChange(_: string) {
|
|
||||||
DataStore.clear(TimezoneCache).catch(_ => _);
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
displayInChat: {
|
displayInChat: {
|
||||||
type: OptionType.BOOLEAN,
|
type: OptionType.BOOLEAN,
|
||||||
|
@ -57,21 +55,13 @@ const settings = definePluginSettings({
|
||||||
timezoneOverrides: {
|
timezoneOverrides: {
|
||||||
type: OptionType.COMPONENT,
|
type: OptionType.COMPONENT,
|
||||||
description: "Local overrides for users' timezones",
|
description: "Local overrides for users' timezones",
|
||||||
component: props => <>
|
component: props => <TimezoneOverridesSetting {...props} />,
|
||||||
<TimezoneOverridesSetting
|
|
||||||
setValue={props.setValue}
|
|
||||||
setError={props.setError}
|
|
||||||
option={props.option} />
|
|
||||||
</>,
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default settings;
|
export default settings;
|
||||||
|
|
||||||
export function SettingsComponent(): JSX.Element {
|
export function SettingsComponent(): JSX.Element {
|
||||||
// const { apiUrl } = settings.use(["apiUrl"]);
|
|
||||||
// const url = `${apiUrl}/../?client_mod=${encodeURIComponent(VENCORD_USER_AGENT)}`;
|
|
||||||
|
|
||||||
return <>
|
return <>
|
||||||
<Text variant="text-md/normal" className={classes(Margins.top16, Margins.bottom20)}>
|
<Text variant="text-md/normal" className={classes(Margins.top16, Margins.bottom20)}>
|
||||||
This plugin supports setting your own timezone publicly for others to
|
This plugin supports setting your own timezone publicly for others to
|
||||||
|
@ -84,3 +74,7 @@ export function SettingsComponent(): JSX.Element {
|
||||||
function TimezoneOverridesSetting(props: IPluginOptionComponentProps): JSX.Element {
|
function TimezoneOverridesSetting(props: IPluginOptionComponentProps): JSX.Element {
|
||||||
return <></>;
|
return <></>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function AuthorizeTimezoneDBSetting(props: IPluginOptionComponentProps): JSX.Element {
|
||||||
|
return <></>;
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue