Factor chat display into its own component

thrimbletrimmer-solid
ElementalAlchemist 1 week ago
parent bd866ba1bf
commit 213b4066ff

@ -1,4 +1,4 @@
import { Accessor, Component, For, JSX, Show } from "solid-js"; import { Accessor, Component, createResource, For, Index, JSX, Show, Suspense } from "solid-js";
import { StreamVideoInfo } from "./streamInfo"; import { StreamVideoInfo } from "./streamInfo";
import { DateTime } from "luxon"; import { DateTime } from "luxon";
import { Fragment } from "hls.js"; import { Fragment } from "hls.js";
@ -148,6 +148,56 @@ function formatDisplayTime(timeSeconds: number): string {
return `${hours}:${minutes}:${seconds}.${milliseconds}`; return `${hours}:${minutes}:${seconds}.${milliseconds}`;
} }
export interface ChatDisplayProps {
streamInfo: StreamVideoInfo;
fragments: Accessor<Fragment[]>;
videoTime: Accessor<number>;
}
export const ChatDisplay: Component<ChatDisplayProps> = (props) => {
const streamDataAndFragments = () => {
const fragments = props.fragments();
if (!fragments || fragments.length === 0) {
return null;
}
return {
streamInfo: props.streamInfo,
fragments: fragments,
};
};
const [possibleChatLog] = createResource(streamDataAndFragments, async () => {
const { streamInfo, fragments } = streamDataAndFragments()!;
return await chatData(streamInfo, fragments);
});
const chatLog = () => {
const chatLogData = possibleChatLog();
if (chatLogData) {
return chatLogData;
}
return ChatLog.default();
};
return (
<Suspense>
<Index each={chatLog().messages}>
{(item: Accessor<ChatMessageData>, index: number) => {
const chatCommand = item().message.command;
if (chatCommand === "PRIVMSG") {
return (
<ChatMessage chatMessage={item()} chatLog={chatLog()} videoTime={props.videoTime} />
);
} else if (chatCommand === "USERNOTICE") {
return <SystemMessage chatMessage={item()} videoTime={props.videoTime} />;
} else {
return <></>;
}
}}
</Index>
</Suspense>
);
};
export interface ChatMessageProps { export interface ChatMessageProps {
chatMessage: ChatMessageData; chatMessage: ChatMessageData;
chatLog: ChatLog; chatLog: ChatLog;

@ -4,7 +4,6 @@ import {
createResource, createResource,
createSignal, createSignal,
For, For,
Index,
onMount, onMount,
Setter, Setter,
Show, Show,
@ -21,7 +20,7 @@ import {
} from "../common/convertTime"; } from "../common/convertTime";
import { StreamVideoInfo } from "../common/streamInfo"; import { StreamVideoInfo } from "../common/streamInfo";
import { KeyboardShortcuts, StreamTimeSettings, VideoPlayer } from "../common/video"; import { KeyboardShortcuts, StreamTimeSettings, VideoPlayer } from "../common/video";
import { chatData, ChatLog, ChatMessage, ChatMessageData, SystemMessage } from "../common/chat"; import { ChatDisplay } from "../common/chat";
export interface DefaultsData { export interface DefaultsData {
video_channel: string; video_channel: string;
@ -153,30 +152,6 @@ const RestreamerWithDefaults: Component<RestreamerDefaultProps> = (props) => {
return `/frame/${streamInfo.streamName}/source.png?timestamp=${wubloaderTime}`; return `/frame/${streamInfo.streamName}/source.png?timestamp=${wubloaderTime}`;
}; };
const streamDataAndFragments = () => {
const streamInfo = streamVideoInfo();
const fragments = videoFragments();
if (!fragments || fragments.length === 0) {
return null;
}
return {
streamInfo: streamInfo,
fragments: fragments,
};
};
const [possibleChatLog] = createResource(streamDataAndFragments, async () => {
const { streamInfo, fragments } = streamDataAndFragments()!;
return await chatData(streamInfo, fragments);
});
const chatLog = () => {
const chatLogData = possibleChatLog();
if (chatLogData) {
return chatLogData;
}
return ChatLog.default();
};
return ( return (
<> <>
<StreamTimeSettings <StreamTimeSettings
@ -198,22 +173,11 @@ const RestreamerWithDefaults: Component<RestreamerDefaultProps> = (props) => {
<a href={downloadFrameURL()}>Download Current Frame as Image</a> <a href={downloadFrameURL()}>Download Current Frame as Image</a>
</div> </div>
<div class={styles.chatContainer}> <div class={styles.chatContainer}>
<Suspense> <ChatDisplay
<Index each={chatLog().messages}> streamInfo={streamVideoInfo()}
{(item: Accessor<ChatMessageData>, index: number) => { fragments={videoFragments}
const chatCommand = item().message.command; videoTime={playerTime}
if (chatCommand === "PRIVMSG") { />
return (
<ChatMessage chatMessage={item()} chatLog={chatLog()} videoTime={playerTime} />
);
} else if (chatCommand === "USERNOTICE") {
return <SystemMessage chatMessage={item()} videoTime={playerTime} />;
} else {
return <></>;
}
}}
</Index>
</Suspense>
</div> </div>
</> </>
); );

Loading…
Cancel
Save