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

151 lines
6.5 KiB
TypeScript
Raw Normal View History

2021-10-21 02:50:23 +02:00
import { ChatlineData, ChatRecordData, UserProfileComposer } from '@nitrots/nitro-renderer';
2021-10-19 23:32:22 +02:00
import { FC, useCallback } from 'react';
import { AutoSizer, CellMeasurer, CellMeasurerCache, List, ListRowProps, ListRowRenderer } from 'react-virtualized';
2021-10-19 23:32:22 +02:00
import { TryVisitRoom } from '../../../../api';
import { ModToolsOpenRoomInfoEvent } from '../../../../events/mod-tools/ModToolsOpenRoomInfoEvent';
import { dispatchUiEvent, SendMessageHook } from '../../../../hooks';
2021-10-16 04:34:36 +02:00
import { ChatlogViewProps } from './ChatlogView.types';
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
2021-10-19 23:32:22 +02:00
const simpleRowRenderer: ListRowRenderer = (props: ListRowProps) =>
2021-10-16 04:34:36 +02:00
{
2021-10-19 23:32:22 +02:00
const item = records[0].chatlog[props.index];
2021-10-16 04:34:36 +02:00
return (
<CellMeasurer
cache={cache}
columnIndex={0}
key={props.key}
parent={props.parent}
rowIndex={props.index}
>
2021-10-24 02:00:48 +02:00
<div key={props.key} style={props.style} className={'row chatlog-entry justify-content-start ' + (item.hasHighlighting ? 'highlighted' : '')}>
2021-10-16 08:26:03 +02:00
<div className="col-auto text-center">{item.timestamp}</div>
<div className="col-sm-2 justify-content-start username"><span className="fw-bold cursor-pointer" onClick={() => SendMessageHook(new UserProfileComposer(item.userId))}>{item.userName}</span></div>
<div className="col justify-content-start h-100"><span className="text-break text-wrap h-100">{item.message}</span></div>
</div>
</CellMeasurer>
2021-10-16 04:34:36 +02:00
);
};
2021-10-19 23:32:22 +02:00
const advancedRowRenderer: ListRowRenderer = (props: ListRowProps) =>
{
2021-10-21 02:50:23 +02:00
let chatlogEntry: ChatlineData;
2021-10-19 23:32:22 +02:00
let currentRecord: ChatRecordData;
let isRoomInfo = false;
let totalIndex = 0;
for(let i = 0; i < records.length; i++)
{
currentRecord = records[i];
totalIndex++; // row for room info
totalIndex = totalIndex + currentRecord.chatlog.length;
if(props.index > (totalIndex - 1))
{
continue; // it is not in current one
}
if( (props.index + 1) === (totalIndex - currentRecord.chatlog.length))
{
isRoomInfo = true;
break;
}
const index = props.index - (totalIndex - currentRecord.chatlog.length);
chatlogEntry = currentRecord.chatlog[index];
break;
}
return (
<CellMeasurer
cache={cache}
columnIndex={0}
key={props.key}
parent={props.parent}
rowIndex={props.index}
>
{isRoomInfo && <RoomInfo roomId={currentRecord.roomId} roomName={currentRecord.roomName} uniqueKey={props.key} style={props.style}/>}
{!isRoomInfo &&
<div key={props.key} style={props.style} className="row chatlog-entry justify-content-start">
<div className="col-auto text-center">{chatlogEntry.timestamp}</div>
<div className="col-sm-2 justify-content-start username"><span className="fw-bold cursor-pointer" onClick={() => SendMessageHook(new UserProfileComposer(chatlogEntry.userId))}>{chatlogEntry.userName}</span></div>
<div className="col justify-content-start h-100"><span className="text-break text-wrap h-100">{chatlogEntry.message}</span></div>
</div>
}
</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]);
const cache = new CellMeasurerCache({
defaultHeight: 25,
fixedWidth: true
});
2021-10-16 04:34:36 +02:00
2021-10-19 23:32:22 +02:00
const RoomInfo = useCallback(({ roomId, roomName, uniqueKey, style }) =>
{
return (
<div key={uniqueKey} style={style} className="row justify-content-start gap-2 room-info">
<div className="col-7"><span className="fw-bold">Room: </span>{roomName}</div>
<button className="btn btn-sm btn-primary col-auto" onClick={() => TryVisitRoom(roomId)}>Visit Room</button>
<button className="btn btn-sm btn-primary col-auto" onClick={() => dispatchUiEvent(new ModToolsOpenRoomInfoEvent(roomId))}>Room Tools</button>
2021-10-19 23:32:22 +02:00
</div>
);
}, []);
2021-10-16 04:34:36 +02:00
return (
<>
2021-10-19 23:32:22 +02:00
{
(records && records.length) &&
<>
{(records.length === 1) && <RoomInfo roomId={records[0].roomId} roomName={records[0].roomName} uniqueKey={records[0].roomId} style={{}} />}
<div className="chatlog-messages w-100 h-100 overflow-hidden">
<div className="row align-items-start w-100">
<div className="col-auto text-center fw-bold">Time</div>
<div className="col-sm-2 username-label fw-bold">User</div>
<div className="col fw-bold">Message</div>
</div>
<div className="row w-100 h-100 chatlog">
<AutoSizer defaultWidth={400} defaultHeight={200}>
{({ height, width }) =>
{
cache.clearAll();
return (
<List
width={width}
height={height}
rowCount={records.length > 1 ? getNumRowsForAdvanced() : records[0].chatlog.length}
rowHeight={cache.rowHeight}
className={'chatlog-container'}
rowRenderer={records.length > 1 ? advancedRowRenderer : simpleRowRenderer}
deferredMeasurementCache={cache} />
)
}
}
</AutoSizer>
</div>
</div>
</>
}
2021-10-16 04:34:36 +02:00
</>
);
}