2024-05-05 18:54:39 +00:00
|
|
|
import { ListItem, ListItemText, ListItemAvatar, Avatar, Typography } from '@mui/material';
|
2024-05-06 01:17:00 +00:00
|
|
|
import React, { MutableRefObject } from 'react';
|
2024-05-05 18:54:39 +00:00
|
|
|
|
|
|
|
import { formatters } from './format.js';
|
|
|
|
|
|
|
|
export interface EventItemProps {
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
|
|
event: any;
|
2024-05-06 01:17:00 +00:00
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
|
|
focusRef?: MutableRefObject<any>;
|
2024-05-05 18:54:39 +00:00
|
|
|
}
|
|
|
|
|
2024-05-10 04:45:10 +00:00
|
|
|
export function ActionEventItem(props: EventItemProps) {
|
2024-05-05 18:54:39 +00:00
|
|
|
const { event } = props;
|
|
|
|
const { actor, room, type } = event;
|
|
|
|
const content = formatters[type](event);
|
|
|
|
|
2024-05-06 01:17:00 +00:00
|
|
|
return <ListItem alignItems="flex-start" ref={props.focusRef}>
|
2024-05-05 18:54:39 +00:00
|
|
|
<ListItemAvatar>
|
2024-05-10 04:45:10 +00:00
|
|
|
<Avatar alt={actor.name} src="/static/images/avatar/1.jpg" />
|
2024-05-05 18:54:39 +00:00
|
|
|
</ListItemAvatar>
|
|
|
|
<ListItemText
|
2024-05-10 04:45:10 +00:00
|
|
|
primary={room.name}
|
2024-05-05 18:54:39 +00:00
|
|
|
secondary={
|
|
|
|
<React.Fragment>
|
|
|
|
<Typography
|
|
|
|
sx={{ display: 'block' }}
|
|
|
|
component="span"
|
|
|
|
variant="body2"
|
|
|
|
color="text.primary"
|
|
|
|
>
|
2024-05-10 04:45:10 +00:00
|
|
|
{actor.name}
|
2024-05-05 18:54:39 +00:00
|
|
|
</Typography>
|
|
|
|
{content}
|
|
|
|
</React.Fragment>
|
|
|
|
}
|
|
|
|
/>
|
|
|
|
</ListItem>;
|
|
|
|
}
|
|
|
|
|
2024-05-10 04:45:10 +00:00
|
|
|
export function SnapshotEventItem(props: EventItemProps) {
|
2024-05-05 18:54:39 +00:00
|
|
|
const { event } = props;
|
|
|
|
const { step, world } = event;
|
|
|
|
const { theme } = world;
|
|
|
|
|
2024-05-06 01:17:00 +00:00
|
|
|
return <ListItem alignItems="flex-start" ref={props.focusRef}>
|
2024-05-05 18:54:39 +00:00
|
|
|
<ListItemAvatar>
|
|
|
|
<Avatar alt={step.toString()} src="/static/images/avatar/1.jpg" />
|
|
|
|
</ListItemAvatar>
|
|
|
|
<ListItemText
|
|
|
|
primary={theme}
|
|
|
|
secondary={
|
|
|
|
<Typography
|
|
|
|
sx={{ display: 'block' }}
|
|
|
|
component="span"
|
|
|
|
variant="body2"
|
|
|
|
color="text.primary"
|
|
|
|
>
|
|
|
|
Step {step}
|
|
|
|
</Typography>
|
|
|
|
}
|
|
|
|
/>
|
|
|
|
</ListItem>;
|
|
|
|
}
|
|
|
|
|
2024-05-10 04:45:10 +00:00
|
|
|
export function ReplyEventItem(props: EventItemProps) {
|
2024-05-05 18:54:39 +00:00
|
|
|
const { event } = props;
|
2024-05-10 04:45:10 +00:00
|
|
|
const { text } = event;
|
2024-05-05 18:54:39 +00:00
|
|
|
|
2024-05-06 01:17:00 +00:00
|
|
|
return <ListItem alignItems="flex-start" ref={props.focusRef}>
|
2024-05-05 18:54:39 +00:00
|
|
|
<ListItemAvatar>
|
|
|
|
<Avatar alt="System" src="/static/images/avatar/1.jpg" />
|
|
|
|
</ListItemAvatar>
|
|
|
|
<ListItemText
|
|
|
|
primary="System"
|
|
|
|
secondary={
|
|
|
|
<Typography
|
|
|
|
sx={{ display: 'block' }}
|
|
|
|
component="span"
|
|
|
|
variant="body2"
|
|
|
|
color="text.primary"
|
|
|
|
>
|
2024-05-10 04:45:10 +00:00
|
|
|
{text}
|
2024-05-05 18:54:39 +00:00
|
|
|
</Typography>
|
|
|
|
}
|
|
|
|
/>
|
|
|
|
</ListItem>;
|
|
|
|
}
|
|
|
|
|
2024-05-10 04:45:10 +00:00
|
|
|
export function PlayerEventItem(props: EventItemProps) {
|
2024-05-05 18:54:39 +00:00
|
|
|
const { event } = props;
|
2024-05-10 04:45:10 +00:00
|
|
|
const { character, status, client } = event;
|
2024-05-06 01:17:00 +00:00
|
|
|
|
|
|
|
let primary = '';
|
|
|
|
let secondary = '';
|
2024-05-10 04:45:10 +00:00
|
|
|
if (status === 'join') {
|
2024-05-06 01:17:00 +00:00
|
|
|
primary = 'New Player';
|
2024-05-10 04:45:10 +00:00
|
|
|
secondary = `${client} is now playing as ${character}`;
|
2024-05-06 01:17:00 +00:00
|
|
|
}
|
2024-05-10 04:45:10 +00:00
|
|
|
if (status === 'leave') {
|
2024-05-06 01:17:00 +00:00
|
|
|
primary = 'Player Left';
|
2024-05-10 04:45:10 +00:00
|
|
|
secondary = `${client} has left the game. ${character} is now controlled by an LLM`;
|
2024-05-06 01:17:00 +00:00
|
|
|
}
|
2024-05-05 18:54:39 +00:00
|
|
|
|
2024-05-06 01:17:00 +00:00
|
|
|
return <ListItem alignItems="flex-start" ref={props.focusRef}>
|
2024-05-05 18:54:39 +00:00
|
|
|
<ListItemAvatar>
|
2024-05-06 01:17:00 +00:00
|
|
|
<Avatar alt={character} src="/static/images/avatar/1.jpg" />
|
2024-05-05 18:54:39 +00:00
|
|
|
</ListItemAvatar>
|
|
|
|
<ListItemText
|
2024-05-06 01:17:00 +00:00
|
|
|
primary={primary}
|
2024-05-05 18:54:39 +00:00
|
|
|
secondary={
|
|
|
|
<Typography
|
|
|
|
sx={{ display: 'block' }}
|
|
|
|
component="span"
|
|
|
|
variant="body2"
|
|
|
|
color="text.primary"
|
|
|
|
>
|
2024-05-06 01:17:00 +00:00
|
|
|
{secondary}
|
2024-05-05 18:54:39 +00:00
|
|
|
</Typography>
|
|
|
|
}
|
|
|
|
/>
|
|
|
|
</ListItem>;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function EventItem(props: EventItemProps) {
|
|
|
|
const { event } = props;
|
|
|
|
const { type } = event;
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
case 'action':
|
|
|
|
case 'result':
|
2024-05-10 04:45:10 +00:00
|
|
|
return <ActionEventItem event={event} focusRef={props.focusRef} />;
|
|
|
|
case 'reply':
|
|
|
|
return <ReplyEventItem event={event} focusRef={props.focusRef} />;
|
2024-05-05 18:54:39 +00:00
|
|
|
case 'player':
|
2024-05-10 04:45:10 +00:00
|
|
|
return <PlayerEventItem event={event} focusRef={props.focusRef} />;
|
|
|
|
case 'snapshot':
|
|
|
|
return <SnapshotEventItem event={event} focusRef={props.focusRef} />;
|
2024-05-05 18:54:39 +00:00
|
|
|
default:
|
2024-05-06 01:17:00 +00:00
|
|
|
return <ListItem ref={props.focusRef}>
|
2024-05-05 18:54:39 +00:00
|
|
|
<ListItemText primary={`Unknown event type: ${type}`} />
|
|
|
|
</ListItem>;
|
|
|
|
}
|
|
|
|
}
|