nitro-react/src/components/mod-tools/views/chatlog/ChatlogView.tsx

159 lines
6.5 KiB
TypeScript
Raw Normal View History

2022-02-21 05:28:21 +01:00
import { ChatRecordData, UserProfileComposer } from '@nitrots/nitro-renderer';
import { CSSProperties, FC, Key, useCallback } from 'react';
import { AutoSizer, CellMeasurer, CellMeasurerCache, List, ListRowProps } from 'react-virtualized';
2022-03-03 10:11:31 +01:00
import { SendMessageComposer, TryVisitRoom } from '../../../../api';
2022-02-21 05:28:21 +01:00
import { Base, Button, Column, Flex, Grid, Text } from '../../../../common';
2021-10-19 23:32:22 +02:00
import { ModToolsOpenRoomInfoEvent } from '../../../../events/mod-tools/ModToolsOpenRoomInfoEvent';
2022-03-03 10:11:31 +01:00
import { DispatchUiEvent } from '../../../../hooks';
2022-02-21 05:28:21 +01:00
interface ChatlogViewProps
{
records: ChatRecordData[];
}
2021-10-16 04:34:36 +02:00
export const ChatlogView: FC<ChatlogViewProps> = props =>
{
2021-10-19 23:32:22 +02:00
const { records = null } = props;
2021-10-16 04:34:36 +02:00
2022-02-21 05:28:21 +01:00
const rowRenderer = (props: ListRowProps) =>
2021-10-16 04:34:36 +02:00
{
2022-02-21 05:28:21 +01:00
let chatlogEntry = records[0].chatlog[props.index];
2021-10-16 04:34:36 +02:00
return (
<CellMeasurer
2022-02-21 05:28:21 +01:00
cache={ cache }
columnIndex={ 0 }
key={ props.key }
parent={ props.parent }
rowIndex={ props.index }
>
2022-02-21 05:28:21 +01:00
<Grid key={ props.key } fullHeight={ false } style={ props.style } gap={ 1 } alignItems="center" className="log-entry py-1 border-bottom">
<Text className="g-col-2">{ chatlogEntry.timestamp }</Text>
2022-03-03 10:11:31 +01:00
<Text className="g-col-3" bold underline pointer onClick={ event => SendMessageComposer(new UserProfileComposer(chatlogEntry.userId)) }>{ chatlogEntry.userName }</Text>
2022-02-21 05:28:21 +01:00
<Text textBreak wrap className="g-col-7">{ chatlogEntry.message }</Text>
</Grid>
</CellMeasurer>
2021-10-16 04:34:36 +02:00
);
};
2022-02-21 05:28:21 +01:00
const advancedRowRenderer = (props: ListRowProps) =>
2021-10-19 23:32:22 +02:00
{
2022-02-21 05:28:21 +01:00
let chatlogEntry = null;
let currentRecord: ChatRecordData = null;
2021-10-19 23:32:22 +02:00
let isRoomInfo = false;
let totalIndex = 0;
2022-02-21 05:28:21 +01:00
2021-10-19 23:32:22 +02:00
for(let i = 0; i < records.length; i++)
{
currentRecord = records[i];
totalIndex++; // row for room info
2022-02-21 05:28:21 +01:00
totalIndex = (totalIndex + currentRecord.chatlog.length);
2021-10-19 23:32:22 +02:00
2022-02-21 05:28:21 +01:00
if(props.index > (totalIndex - 1)) continue;
2021-10-19 23:32:22 +02:00
2022-02-21 05:28:21 +01:00
if((props.index + 1) === (totalIndex - currentRecord.chatlog.length))
2021-10-19 23:32:22 +02:00
{
isRoomInfo = true;
2022-02-21 05:28:21 +01:00
2021-10-19 23:32:22 +02:00
break;
}
2022-02-21 05:28:21 +01:00
const index = (props.index - (totalIndex - currentRecord.chatlog.length));
2021-10-19 23:32:22 +02:00
chatlogEntry = currentRecord.chatlog[index];
2022-02-21 05:28:21 +01:00
2021-10-19 23:32:22 +02:00
break;
}
return (
<CellMeasurer
2022-02-21 05:28:21 +01:00
cache={ cache }
columnIndex={ 0 }
key={ props.key }
parent={ props.parent }
rowIndex={ props.index }
2021-10-19 23:32:22 +02:00
>
2022-02-21 05:28:21 +01:00
{ (isRoomInfo && currentRecord) &&
<RoomInfo roomId={ currentRecord.roomId } roomName={ currentRecord.roomName } uniqueKey={ props.key } style={ props.style } /> }
{ !isRoomInfo &&
2022-03-15 11:22:22 +01:00
<Grid key={ props.key } fullHeight={ false } style={ props.style } gap={ 1 } alignItems="center" className="log-entry py-1 border-bottom">
2022-02-21 05:28:21 +01:00
<Text className="g-col-2">{ chatlogEntry.timestamp }</Text>
2022-03-03 10:11:31 +01:00
<Text className="g-col-3" bold underline pointer onClick={ event => SendMessageComposer(new UserProfileComposer(chatlogEntry.userId)) }>{ chatlogEntry.userName }</Text>
2022-02-21 05:28:21 +01:00
<Text textBreak wrap className="g-col-7">{ chatlogEntry.message }</Text>
</Grid> }
2021-10-19 23:32:22 +02:00
</CellMeasurer>
);
}
const getNumRowsForAdvanced = useCallback(() =>
{
let count = 0;
for(let i = 0; i < records.length; i++)
{
count++; // add room info row
count = count + records[i].chatlog.length;
}
return count;
}, [records]);
2022-02-21 05:28:21 +01:00
const RoomInfo = (props: { roomId: number, roomName: string, uniqueKey: Key, style: CSSProperties }) =>
{
return (
<Flex key={ props.uniqueKey } gap={ 2 } alignItems="center" justifyContent="between" className="room-info bg-muted rounded p-1" style={ props.style }>
<Flex gap={ 1 }>
<Text bold>Room name:</Text>
<Text>{ props.roomName }</Text>
</Flex>
<Flex gap={ 1 }>
<Button onClick={ event => TryVisitRoom(props.roomId) }>Visit Room</Button>
2022-03-03 10:11:31 +01:00
<Button onClick={ event => DispatchUiEvent(new ModToolsOpenRoomInfoEvent(props.roomId)) }>Room Tools</Button>
2022-02-21 05:28:21 +01:00
</Flex>
</Flex>
);
}
const cache = new CellMeasurerCache({
defaultHeight: 25,
fixedWidth: true
});
2021-10-16 04:34:36 +02:00
return (
<>
2022-02-21 05:28:21 +01:00
{ (records && (records.length === 1)) &&
<RoomInfo roomId={records[0].roomId} roomName={records[0].roomName} uniqueKey={ null } style={ {} } /> }
<Column fit gap={ 0 } overflow="hidden">
<Column gap={ 2 }>
<Grid gap={ 1 } className="text-black fw-bold border-bottom pb-1">
<Base className="g-col-2">Time</Base>
<Base className="g-col-3">User</Base>
<Base className="g-col-7">Message</Base>
</Grid>
</Column>
{ (records && (records.length > 0)) &&
<Column className="log-container striped-children" overflow="auto" gap={ 0 }>
<AutoSizer defaultWidth={ 400 } defaultHeight={ 200 }>
{ ({ height, width }) =>
2021-10-19 23:32:22 +02:00
{
cache.clearAll();
return (
<List
2022-02-21 05:28:21 +01:00
width={ width }
height={ height }
rowCount={ (records.length > 1) ? getNumRowsForAdvanced() : records[0].chatlog.length }
rowHeight={ cache.rowHeight }
className={ 'log-entry-container' }
rowRenderer={ (records.length > 1) ? advancedRowRenderer : rowRenderer }
deferredMeasurementCache={ cache } />
);
} }
</AutoSizer>
</Column> }
</Column>
2021-10-16 04:34:36 +02:00
</>
);
}