import * as React from "react"; import { IpcInviteInfo, IpcInviteInfoLoaded } from "tc-shared/text/bbcode/InviteDefinitions"; import { ChannelMessage, getIpcInstance, IPCChannel } from "tc-shared/ipc/BrowserIPC"; import * as loader from "tc-loader"; import { useEffect, useState } from "react"; import _ = require("lodash"); import { Translatable } from "tc-shared/ui/react-elements/i18n"; import { Button } from "tc-shared/ui/react-elements/Button"; import { SimpleUrlRenderer } from "tc-shared/text/bbcode/url"; import { LoadingDots } from "tc-shared/ui/react-elements/LoadingDots"; import { ClientIconRenderer } from "tc-shared/ui/react-elements/Icons"; import { ClientIcon } from "svg-sprites/client-icons"; const cssStyle = require("./InviteRenderer.scss"); const kInviteUrlRegex = /^(https:\/\/)?(teaspeak.de\/|join.teaspeak.de\/(invite\/)?)([a-zA-Z0-9]{4})$/gm; export function isInviteLink(url: string): boolean { kInviteUrlRegex.lastIndex = 0; return !!url.match(kInviteUrlRegex); } type LocalInviteInfo = IpcInviteInfo | { status: "loading" }; type InviteCacheEntry = { status: LocalInviteInfo, timeout: number }; const localInviteCache: { [key: string]: InviteCacheEntry } = {}; const localInviteCallbacks: { [key: string]: (() => void)[] } = {}; const useInviteLink = (linkId: string): LocalInviteInfo => { if (!localInviteCache[linkId]) { localInviteCache[linkId] = { status: { status: "loading" }, timeout: setTimeout(() => delete localInviteCache[linkId], 60 * 1000) }; ipcChannel?.sendMessage("query", { linkId }); } const [value, setValue] = useState(localInviteCache[linkId].status); useEffect(() => { if (typeof localInviteCache[linkId]?.status === "undefined") { return; } if (!_.isEqual(value, localInviteCache[linkId].status)) { setValue(localInviteCache[linkId].status); } const callback = () => setValue(localInviteCache[linkId].status); (localInviteCallbacks[linkId] || (localInviteCallbacks[linkId] = [])).push(callback); return () => { localInviteCallbacks[linkId]?.remove(callback); } }, [linkId]); return value; } const LoadedInviteRenderer = React.memo((props: { info: IpcInviteInfoLoaded }) => { let joinButton = (