import * as React from "react"; import {useContext, useEffect, useState} from "react"; import {AbstractModal} from "tc-shared/ui/react-elements/modal/Definitions"; import {Translatable} from "tc-shared/ui/react-elements/i18n"; import {IpcRegistryDescription, Registry} from "tc-events"; import {InviteUiEvents, InviteUiVariables} from "tc-shared/ui/modal/invite/Definitions"; import {UiVariableConsumer} from "tc-shared/ui/utils/Variable"; import {Button} from "tc-shared/ui/react-elements/Button"; import {createIpcUiVariableConsumer, IpcVariableDescriptor} from "tc-shared/ui/utils/IpcVariable"; import {ClientIconRenderer} from "tc-shared/ui/react-elements/Icons"; import {ClientIcon} from "svg-sprites/client-icons"; import {LoadingDots} from "tc-shared/ui/react-elements/LoadingDots"; import {copyToClipboard} from "tc-shared/utils/helpers"; import {ControlledBoxedInputField, ControlledSelect} from "tc-shared/ui/react-elements/InputField"; import {useTr} from "tc-shared/ui/react-elements/Helper"; import {Checkbox} from "tc-shared/ui/react-elements/Checkbox"; import * as moment from 'moment'; const cssStyle = require("./Renderer.scss"); const EventsContext = React.createContext>(undefined); const VariablesContext = React.createContext>(undefined); const OptionChannel = React.memo(() => { const variables = useContext(VariablesContext); const availableChannels = variables.useReadOnly("availableChannels", undefined, []); const selectedChannel = variables.useVariable("selectedChannel", undefined, 0); return (
Automatically join channel
{ const value = parseInt(event.target.value); if(isNaN(value)) { return; } selectedChannel.setValue(value); }} > {availableChannels.map(channel => ( )) as any}
); }); const OptionChannelPassword = React.memo(() => { const variables = useContext(VariablesContext); const selectedChannel = variables.useReadOnly("selectedChannel", undefined, 0); const channelPassword = variables.useVariable("channelPassword", undefined, { raw: undefined, hashed: undefined }); let body; if(selectedChannel === 0) { body = ( {}} /> ); } else if(channelPassword.localValue.hashed && !channelPassword.localValue.raw) { body = ( channelPassword.setValue({ hashed: channelPassword.localValue.hashed, raw: newValue }, true)} /> ); } else { body = ( channelPassword.setValue({ hashed: channelPassword.localValue.hashed, raw: newValue }, true)} onBlur={() => channelPassword.setValue(channelPassword.localValue, false)} finishOnEnter={true} /> ); } return (
Channel password
{body}
); }) const OptionGeneralShortLink = React.memo(() => { const variables = useContext(VariablesContext); const showShortUrl = variables.useVariable("shortLink", undefined, true); return (
showShortUrl.setValue(newValue)} value={showShortUrl.localValue} label={Use short URL} />
) }) const OptionGeneralShowAdvanced = React.memo(() => { const variables = useContext(VariablesContext); const showShortUrl = variables.useVariable("advancedSettings", undefined, false); return (
showShortUrl.setValue(newValue)} value={showShortUrl.localValue} label={Advanced settings} />
) }) const OptionAdvancedToken = React.memo(() => { const variables = useContext(VariablesContext); const currentToken = variables.useVariable("token", undefined, ""); return (
Token
currentToken.setValue(newValue, true)} onBlur={() => currentToken.setValue(currentToken.localValue, false)} finishOnEnter={true} />
); }); const OptionAdvancedWebUrlBase = React.memo(() => { const variables = useContext(VariablesContext); const currentUrl = variables.useVariable("webClientUrlBase", undefined, { override: undefined, fallback: undefined }); return (
WebClient URL
currentUrl.setValue({ fallback: currentUrl.localValue.fallback, override: newValue }, true)} onBlur={() => currentUrl.setValue(currentUrl.localValue, false)} finishOnEnter={true} />
); }); type ExpirePreset = { name: () => string, seconds: number }; const ExpirePresets: ExpirePreset[] = [ { name: () => tr("5 Minutes"), seconds: 5 * 60 }, { name: () => tr("1 hour"), seconds: 60 * 60 }, { name: () => tr("24 hours"), seconds: 24 * 60 * 60 }, { name: () => tr("1 Week"), seconds: 7 * 24 * 60 * 60 }, { name: () => tr("1 Month"), seconds: 31 * 24 * 60 * 60 }, ] const OptionAdvancedExpires = React.memo(() => { const variables = useContext(VariablesContext); const expiresAfter = variables.useVariable("expiresAfter", undefined, 0); let presetSelected = -2; if(expiresAfter.localValue === 0) { presetSelected = -1; } else { const difference = expiresAfter.localValue - Date.now() / 1000; if(difference > 0) { for(let index = 0; index < ExpirePresets.length; index++) { if(Math.abs(difference - ExpirePresets[index].seconds) <= 60 * 60) { presetSelected = index; break; } } } } return (
Link expire time
{ const value = parseInt(event.target.value); if(isNaN(value)) { return; } if(value === -1) { expiresAfter.setValue(0); } else if(value >= 0) { expiresAfter.setValue(Math.floor(Date.now() / 1000 + ExpirePresets[value].seconds)); } }} > { ExpirePresets.map((preset, index) => ( )) as any }
); }); const OptionsAdvanced = React.memo(() => { return (
Advanced options
) }); const Options = React.memo(() => { const variables = useContext(VariablesContext); const showAdvanced = variables.useReadOnly("advancedSettings", undefined, false); return (
General
Channel
{showAdvanced ? : undefined}
); }); const ButtonCopy = React.memo((props: { onCopy: () => void, disabled: boolean }) => { const [ showTimeout, setShowTimeout ] = useState(0); const now = Date.now(); useEffect(() => { if(now >= showTimeout) { return; } const timeout = setTimeout(() => setShowTimeout(0), showTimeout - now); return () => clearTimeout(timeout); }); return (
{ if(props.disabled) { return; } props.onCopy(); setShowTimeout(Date.now() + 1750); }}>
); }); const LinkExpire = (props: { date: number | 0 | -1 }) => { let value; if(props.date === -1) { value =  ; } else if(props.date === 0) { value = Link expires never; } else { value = Link expires at {moment(props.date * 1000).format('LLLL')}; } return (
{value}
); } const Link = React.memo(() => { const variables = useContext(VariablesContext); const shortLink = variables.useReadOnly("shortLink", undefined, true); const link = variables.useReadOnly("generatedLink", undefined, { status: "generating" }); let className, value, copyValue; switch (link.status) { case "generating": className = cssStyle.generating; value = Generating link ; break; case "error": className = cssStyle.errored; copyValue = link.message; value = link.message; break; case "success": className = cssStyle.success; copyValue = shortLink ? link.shortUrl : link.longUrl; value = copyValue; break; } return (
Link
{value} { if(copyValue) { copyToClipboard(copyValue); } }} />
); }); const Buttons = () => { const events = useContext(EventsContext); return (
) } class ModalInvite extends AbstractModal { private readonly events: Registry; private readonly variables: UiVariableConsumer; private readonly serverName: string; constructor(events: IpcRegistryDescription, variables: IpcVariableDescriptor, serverName: string) { super(); this.events = Registry.fromIpcDescription(events); this.variables = createIpcUiVariableConsumer(variables); this.serverName = serverName; } renderBody(): React.ReactElement { return (
); } renderTitle(): string | React.ReactElement { return <>Invite People to {this.serverName}; } } export = ModalInvite; /* const modal = spawnModal("global-settings-editor", [ events.generateIpcDescription() ], { popoutable: true, popedOut: false }); modal.show(); modal.getEvents().on("destroy", () => { events.fire("notify_destroy"); events.destroy(); }); */