import {AbstractModal} from "tc-shared/ui/react-elements/modal/Definitions"; import React, {useContext} from "react"; import {IpcRegistryDescription, Registry} from "tc-events"; import {ModalChannelInfoEvents, ModalChannelInfoVariables} from "tc-shared/ui/modal/channel-info/Definitions"; import {UiVariableConsumer} from "tc-shared/ui/utils/Variable"; import {createIpcUiVariableConsumer, IpcVariableDescriptor} from "tc-shared/ui/utils/IpcVariable"; import {Translatable, VariadicTranslatable} from "tc-shared/ui/react-elements/i18n"; import {tr} from "tc-shared/i18n/localize"; import {joinClassList, useTr} from "tc-shared/ui/react-elements/Helper"; import {LoadingDots} from "tc-shared/ui/react-elements/LoadingDots"; import {Button} from "tc-shared/ui/react-elements/Button"; import {BBCodeRenderer} from "tc-shared/text/bbcode"; const cssStyle = require("./Renderer.scss"); const VariablesContext = React.createContext>(undefined); const EventContext = React.createContext>(undefined); const kCodecNames = [ () => useTr("Speex Narrowband"), () => useTr("Speex Wideband"), () => useTr("Speex Ultra-Wideband"), () => useTr("CELT Mono"), () => useTr("Opus Voice"), () => useTr("Opus Music") ]; const TitleRenderer = React.memo(() => { const title = useContext(VariablesContext).useReadOnly("name"); if(title.status === "loaded") { return ( {title.value} ); } else { return ( Channel information ); } }); const TopicRenderer = React.memo(() => { const topic = useContext(VariablesContext).useReadOnly("topic"); if(topic.status !== "loaded" || !topic.value) { return null; } return (
Topic
{topic.value}
) }); const DescriptionRenderer = React.memo(() => { const description = useContext(VariablesContext).useReadOnly("description"); let overlay; let descriptionBody; if(description.status === "loaded") { switch(description.value.status) { case "success": descriptionBody = ( ); break; case "empty": overlay = Channel has no description; break; case "no-permissions": overlay = ( {description.value.failedPermission} ); break; case "error": default: overlay = ( {description.value.status === "error" ? description.value.message : tr("Unknown error")} ); break; } } else { overlay = Loading ; } return (
Description
{descriptionBody}
{overlay}
); }); const kVariablePropertyName: {[T in keyof ModalChannelInfoVariables]?: () => React.ReactElement } = { name: () => Channel Name, type: () => Channel Type, chatMode: () => Chat Mode, currentClients: () => Current Clients, audioCodec: () => Audio Codec, audioEncrypted: () => Audio Encrypted, password: () => Password protected, topic: () => Topic, description: () => Description }; const PropertyRenderer = (props: { property: T, children: (value: ModalChannelInfoVariables[T]) => React.ReactNode | React.ReactNode[], className?: string, }) => { const value = useContext(VariablesContext).useReadOnly(props.property); return (
{kVariablePropertyName[props.property]()}
{value.status === "loaded" ? props.children(value.value) : undefined}
); }; class Modal extends AbstractModal { private readonly events: Registry; private readonly variables: UiVariableConsumer; constructor(events: IpcRegistryDescription, variables: IpcVariableDescriptor) { super(); this.events = Registry.fromIpcDescription(events); this.variables = createIpcUiVariableConsumer(variables); } protected onDestroy() { super.onDestroy(); this.events.destroy(); this.variables.destroy(); } renderBody(): React.ReactElement { return (
{value => { switch (value) { case "default": return Default Channel; case "permanent": return Permanent; case "semi-permanent": return Semi-Permanent; case "temporary": return Temporary; case "unknown": default: return Unknown; } }} {value => { switch (value.mode) { case "private": return Private; case "none": return disabled; case "public": if(value.history === -1) { return Semi-Permanent; } else if(value.history === 0) { return Permanent; } else { return ( {value.history} ); } default: return Unknown; } }} {value => { if(value.status === "subscribed") { let limit; if(value.limit === "unlimited") { limit = Unlimited; } else if(value.limit === "inherited") { limit = Inherited; } else { limit = value.limit.toString(); } return ( {value.online} / {limit} ); } else if(value.status === "unsubscribed") { return Not subscribed; } else { return Unknown; } }}
{value => ( {kCodecNames[value.codec]() || tr("Unknown")} ({value.quality}) )} {value => { let textValue = value.channel ? "Encrypted" : "Unencrypted"; switch(value.server) { case "globally-on": return ( {textValue} ); case "globally-off": return ( {textValue} ); default: return textValue; } }} {value => value ? ( Yes ) : ( No )}
); } renderTitle(): string | React.ReactElement { return ( ); } } export default Modal;