TeaWeb/shared/js/ui/AppRenderer.tsx

133 lines
5.8 KiB
TypeScript
Raw Normal View History

2021-01-05 18:13:57 +01:00
import * as React from "react";
2021-04-29 22:18:11 +02:00
import {useEffect, useMemo} from "react";
2021-01-05 18:13:57 +01:00
import {ControlBar2} from "tc-shared/ui/frames/control-bar/Renderer";
2021-04-29 22:18:11 +02:00
import {IpcRegistryDescription, Registry} from "tc-shared/events";
2021-01-05 18:13:57 +01:00
import {ConnectionHandlerList} from "tc-shared/ui/frames/connection-handler-list/Renderer";
import {ErrorBoundary} from "tc-shared/ui/react-elements/ErrorBoundary";
import {ContextDivider} from "tc-shared/ui/react-elements/ContextDivider";
import {SideBarRenderer} from "tc-shared/ui/frames/SideBarRenderer";
import {ServerLogFrame} from "tc-shared/ui/frames/log/Renderer";
import {FooterRenderer} from "tc-shared/ui/frames/footer/Renderer";
import {HostBanner} from "tc-shared/ui/frames/HostBannerRenderer";
2021-04-29 22:18:11 +02:00
import {AppUiVariables} from "tc-shared/ui/AppDefinitions";
2021-01-05 18:13:57 +01:00
import {ChannelTreeRenderer} from "tc-shared/ui/tree/Renderer";
import {ImagePreviewHook} from "tc-shared/ui/frames/ImagePreview";
import {InternalModalHook} from "tc-shared/ui/react-elements/modal/internal";
2021-04-05 23:05:44 +02:00
import {TooltipHook} from "tc-shared/ui/react-elements/Tooltip";
import {ChannelVideoRenderer} from "tc-shared/ui/frames/video/Renderer";
2021-04-29 22:18:11 +02:00
import {
createIpcUiVariableConsumer,
IpcVariableDescriptor
} from "tc-shared/ui/utils/IpcVariable";
import {UiVariableConsumer} from "tc-shared/ui/utils/Variable";
import {useRegistry} from "tc-shared/ui/react-elements/Helper";
2021-01-05 18:13:57 +01:00
const cssStyle = require("./AppRenderer.scss");
2021-04-29 22:18:11 +02:00
const VideoFrame = React.memo((props: { variables: UiVariableConsumer<AppUiVariables> }) => {
const data = props.variables.useReadOnly("channelVideo", undefined, { handlerId: undefined, events: undefined });
const events = useRegistry(data.events);
if(!data.events) {
return null;
}
2021-04-29 22:18:11 +02:00
return <ChannelVideoRenderer handlerId={data.handlerId} events={events} key={"video-" + data.handlerId} />;
});
2021-04-29 22:18:11 +02:00
const ChannelTree = React.memo((props: { variables: UiVariableConsumer<AppUiVariables> }) => {
const data = props.variables.useReadOnly("channelTree", undefined, { handlerId: undefined, events: undefined });
const events = useRegistry(data.events);
2021-01-05 18:13:57 +01:00
2021-04-29 22:18:11 +02:00
if(!events) {
2021-01-05 18:13:57 +01:00
return null;
}
2021-04-29 22:18:11 +02:00
return <ChannelTreeRenderer handlerId={data.handlerId} events={events} key={"tree-" + data.handlerId} />;
2021-01-05 18:13:57 +01:00
});
2021-04-29 22:18:11 +02:00
const SideBar = React.memo((props: { variables: UiVariableConsumer<AppUiVariables> }) => (
<EventProvider registry={props.variables.useReadOnly("sidebar", undefined, undefined)}>
{sidebarRegistry => (
<EventProvider registry={props.variables.useReadOnly("sidebarHeader", undefined, undefined)}>
{sidebarHeaderRegistry => sidebarRegistry && sidebarHeaderRegistry ? (
<SideBarRenderer events={sidebarRegistry} eventsHeader={sidebarHeaderRegistry} className={cssStyle.sideBar} />
) : null}
</EventProvider>
)}
</EventProvider>
));
function EventProvider<T>(props: {
registry: IpcRegistryDescription<T> | undefined,
children: (registry: Registry<T> | undefined) => React.ReactElement
}) : React.ReactElement {
return props.children(useRegistry(props.registry));
}
2021-01-05 18:13:57 +01:00
export const TeaAppMainView = (props: {
2021-04-29 22:18:11 +02:00
variables: IpcVariableDescriptor<AppUiVariables>,
2021-01-05 18:13:57 +01:00
}) => {
2021-04-29 22:18:11 +02:00
const variables = useMemo(() => createIpcUiVariableConsumer(props.variables), [ props.variables ]);
useEffect(() => () => variables.destroy(), [ props.variables ]);
2021-01-05 18:13:57 +01:00
return (
<div className={cssStyle.app}>
<ErrorBoundary>
2021-04-29 22:18:11 +02:00
<EventProvider registry={variables.useReadOnly("controlBar", undefined, undefined)}>
{registry => registry ? (
<ControlBar2 events={registry} className={cssStyle.controlBar} />
) : null}
</EventProvider>
2021-01-05 18:13:57 +01:00
</ErrorBoundary>
<ErrorBoundary>
2021-04-29 22:18:11 +02:00
<EventProvider registry={variables.useReadOnly("connectionList", undefined, undefined)}>
{registry => registry ? (
<ConnectionHandlerList events={registry} />
) : null}
</EventProvider>
2021-01-05 18:13:57 +01:00
</ErrorBoundary>
<div className={cssStyle.mainContainer}>
2021-04-29 22:18:11 +02:00
<VideoFrame variables={variables} />
<div className={cssStyle.channelTreeAndSidebar}>
<div className={cssStyle.channelTree}>
<ErrorBoundary>
2021-04-29 22:18:11 +02:00
<EventProvider registry={variables.useReadOnly("hostBanner", undefined, undefined)}>
{registry => registry ? (
<HostBanner events={registry} />
) : null}
</EventProvider>
<ChannelTree variables={variables} />
</ErrorBoundary>
</div>
<ContextDivider id={"channel-chat"} direction={"horizontal"} defaultValue={25} />
2021-04-29 22:18:11 +02:00
<SideBar variables={variables} />
2021-01-05 18:13:57 +01:00
</div>
<ContextDivider id={"main-log"} direction={"vertical"} defaultValue={75} />
<ErrorBoundary>
<div className={cssStyle.containerLog}>
2021-04-29 22:18:11 +02:00
<EventProvider registry={variables.useReadOnly("log", undefined, undefined)}>
{registry => registry ? (
<ServerLogFrame events={registry} />
) : null}
</EventProvider>
</div>
</ErrorBoundary>
2021-01-05 18:13:57 +01:00
</div>
<FooterRenderer />
<ErrorBoundary>
<ImagePreviewHook />
</ErrorBoundary>
<ErrorBoundary>
<InternalModalHook />
</ErrorBoundary>
2021-04-05 23:05:44 +02:00
<ErrorBoundary>
<TooltipHook />
</ErrorBoundary>
2021-01-05 18:13:57 +01:00
</div>
);
}