From 91e59fce047c0c8ef33037be84ed6912a0ac6877 Mon Sep 17 00:00:00 2001 From: dank074 Date: Fri, 22 Oct 2021 17:37:54 -0500 Subject: [PATCH] refactored state --- .../ChatHistoryMessageHandler.tsx | 55 ++++++++------- src/views/chat-history/ChatHistoryView.scss | 22 +++++- src/views/chat-history/ChatHistoryView.tsx | 69 +++++++++++++------ .../context/ChatHistoryContext.tsx | 2 +- .../context/ChatHistoryContext.types.ts | 41 ++++++++++- .../reducers/ChatHistoryReducer.tsx | 66 ------------------ .../chat-history/utils/ChatHistoryState.ts | 32 +++++++++ .../chat-history/utils/RoomHistoryState.ts | 32 +++++++++ 8 files changed, 204 insertions(+), 115 deletions(-) delete mode 100644 src/views/chat-history/reducers/ChatHistoryReducer.tsx create mode 100644 src/views/chat-history/utils/ChatHistoryState.ts create mode 100644 src/views/chat-history/utils/RoomHistoryState.ts diff --git a/src/views/chat-history/ChatHistoryMessageHandler.tsx b/src/views/chat-history/ChatHistoryMessageHandler.tsx index 9a0da789..f56702a4 100644 --- a/src/views/chat-history/ChatHistoryMessageHandler.tsx +++ b/src/views/chat-history/ChatHistoryMessageHandler.tsx @@ -1,41 +1,46 @@ import { RoomInfoEvent, RoomSessionChatEvent, RoomSessionEvent } from '@nitrots/nitro-renderer'; import { FC, useCallback, useState } from 'react'; import { GetRoomSession } from '../../api'; -import { ChatHistoryEvent } from '../../events/chat-history/ChatHistoryEvent'; -import { CreateMessageHook, dispatchUiEvent, useRoomSessionManagerEvent } from '../../hooks'; +import { CreateMessageHook, useRoomSessionManagerEvent } from '../../hooks'; import { useChatHistoryContext } from './context/ChatHistoryContext'; -import { ChatEntryType, ChatHistoryAction, CHAT_HISTORY_MAX, IChatEntry } from './reducers/ChatHistoryReducer'; +import { ChatEntryType, CHAT_HISTORY_MAX, IChatEntry, IRoomHistoryEntry, ROOM_HISTORY_MAX } from './context/ChatHistoryContext.types'; import { currentDate } from './utils/Utilities'; export const ChatHistoryMessageHandler: FC<{}> = props => { - const { chatHistoryState = null, dispatchChatHistoryState = null } = useChatHistoryContext(); - const { chats = null, roomHistory = null } = chatHistoryState; + const { chatHistoryState = null, roomHistoryState = null } = useChatHistoryContext(); const [needsRoomInsert, setNeedsRoomInsert ] = useState(false); const addChatEntry = useCallback((entry: IChatEntry) => { - const newChats = [...chats]; - - newChats.push(entry); + entry.id = chatHistoryState.chats.length; + + chatHistoryState.chats.push(entry); //check for overflow - if(newChats.length > CHAT_HISTORY_MAX) + if(chatHistoryState.chats.length > CHAT_HISTORY_MAX) { - newChats.shift(); + chatHistoryState.chats.shift(); + } + chatHistoryState.notify(); + + //dispatchUiEvent(new ChatHistoryEvent(ChatHistoryEvent.CHAT_HISTORY_CHANGED)); + + }, [chatHistoryState]); + + const addRoomHistoryEntry = useCallback((entry: IRoomHistoryEntry) => + { + roomHistoryState.roomHistory.push(entry); + + // check for overflow + if(roomHistoryState.roomHistory.length > ROOM_HISTORY_MAX) + { + roomHistoryState.roomHistory.shift(); } - dispatchChatHistoryState({ - type: ChatHistoryAction.SET_CHATS, - payload: { - chats: newChats - } - }); - - dispatchUiEvent(new ChatHistoryEvent(ChatHistoryEvent.CHAT_HISTORY_CHANGED)); - - }, [chats, dispatchChatHistoryState]); + roomHistoryState.notify(); + }, [roomHistoryState]); const onChatEvent = useCallback((event: RoomSessionChatEvent) => { @@ -49,7 +54,7 @@ export const ChatHistoryMessageHandler: FC<{}> = props => const timeString = currentDate(); - const entry: IChatEntry = { id: userData.webID, name: userData.name, look: userData.figure, message: event.message, timestamp: timeString, type: ChatEntryType.TYPE_CHAT }; + const entry: IChatEntry = { id: -1, entityId: userData.webID, name: userData.name, look: userData.figure, message: event.message, timestamp: timeString, type: ChatEntryType.TYPE_CHAT }; addChatEntry(entry); }, [addChatEntry]); @@ -84,13 +89,17 @@ export const ChatHistoryMessageHandler: FC<{}> = props => if(needsRoomInsert) { - const chatEntry: IChatEntry = { id: parser.data.roomId, name: parser.data.roomName, timestamp: currentDate(), type: ChatEntryType.TYPE_ROOM_INFO }; + const chatEntry: IChatEntry = { id: -1, entityId: parser.data.roomId, name: parser.data.roomName, timestamp: currentDate(), type: ChatEntryType.TYPE_ROOM_INFO }; addChatEntry(chatEntry); + const roomEntry: IRoomHistoryEntry = { id: parser.data.roomId, name: parser.data.roomName }; + + addRoomHistoryEntry(roomEntry); + setNeedsRoomInsert(false); } - }, [addChatEntry, needsRoomInsert]); + }, [addChatEntry, addRoomHistoryEntry, needsRoomInsert]); CreateMessageHook(RoomInfoEvent, onRoomInfoEvent); diff --git a/src/views/chat-history/ChatHistoryView.scss b/src/views/chat-history/ChatHistoryView.scss index ba3a4451..3d83a554 100644 --- a/src/views/chat-history/ChatHistoryView.scss +++ b/src/views/chat-history/ChatHistoryView.scss @@ -1,6 +1,6 @@ .nitro-chat-history { - width: 250px; + width: 300px; padding: 2px; background-color: #1C323F; @@ -27,6 +27,26 @@ { background-color: #1C323F; min-height: 200px; + + .chat-history-list + { + .chathistory-entry + { + .head-container + { + height: 44px; + width: 42px; + } + + .friend-bar-item-head { + top: -30px; + left: 15px; + pointer-events: none; + height: 44px; + width: 42px; + } + } + } } } } diff --git a/src/views/chat-history/ChatHistoryView.tsx b/src/views/chat-history/ChatHistoryView.tsx index a6f3ff3a..442a6065 100644 --- a/src/views/chat-history/ChatHistoryView.tsx +++ b/src/views/chat-history/ChatHistoryView.tsx @@ -1,19 +1,37 @@ -import { FC, useCallback, useEffect, useReducer, useRef, useState } from 'react'; -import { AutoSizer, CellMeasurer, CellMeasurerCache, List, ListRowProps, ListRowRenderer } from 'react-virtualized'; +import { FC, useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import { AutoSizer, CellMeasurer, CellMeasurerCache, List, ListRowProps, ListRowRenderer, Size } from 'react-virtualized'; import { ChatHistoryEvent } from '../../events/chat-history/ChatHistoryEvent'; import { useUiEvent } from '../../hooks'; import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../layout'; import { ChatHistoryMessageHandler } from './ChatHistoryMessageHandler'; import { ChatHistoryContextProvider } from './context/ChatHistoryContext'; -import { ChatEntryType, ChatHistoryReducer, initialChatHistory } from './reducers/ChatHistoryReducer'; +import { ChatEntryType } from './context/ChatHistoryContext.types'; +import { ChatHistoryState } from './utils/ChatHistoryState'; +import { RoomHistoryState } from './utils/RoomHistoryState'; export const ChatHistoryView: FC<{}> = props => { const [ isVisible, setIsVisible ] = useState(false); - const [ chatHistoryState, dispatchChatHistoryState ] = useReducer(ChatHistoryReducer, initialChatHistory); - const { chats = null } = chatHistoryState; + const [ chatHistoryUpdateId, setChatHistoryUpdateId ] = useState(-1); + const [ roomHistoryUpdateId, setRoomHistoryUpdateId ] = useState(-1); + const [ chatHistoryState, setChatHistoryState ] = useState(new ChatHistoryState()); + const [ roomHistoryState, setRoomHistoryState ] = useState(new RoomHistoryState()); const elementRef = useRef(null); + useEffect(() => + { + const chatState = new ChatHistoryState(); + const roomState = new RoomHistoryState(); + + chatState.notifier = () => setChatHistoryUpdateId(prevValue => (prevValue + 1)); + roomState.notifier = () => setRoomHistoryUpdateId(prevValue => (prevValue + 1)); + + setChatHistoryState(chatState); + setRoomHistoryState(roomState); + + return () => {chatState.notifier = null; roomState.notifier = null;}; + }, []); + const onChatHistoryEvent = useCallback((event: ChatHistoryEvent) => { switch(event.type) @@ -37,15 +55,19 @@ export const ChatHistoryView: FC<{}> = props => useUiEvent(ChatHistoryEvent.TOGGLE_CHAT_HISTORY, onChatHistoryEvent); useUiEvent(ChatHistoryEvent.CHAT_HISTORY_CHANGED, onChatHistoryEvent); - const cache = new CellMeasurerCache({ - defaultHeight: 25, - fixedWidth: true - }); + const cache = useMemo(() => +{ + return new CellMeasurerCache({ + defaultHeight: 25, + fixedWidth: true, + //keyMapper: (index) => chatHistoryState.chats[index].id + }); + }, []); const RowRenderer: ListRowRenderer = (props: ListRowProps) => { - const item = chats[props.index]; - + const item = chatHistoryState.chats[props.index]; + console.log(props.index); return ( = props => parent={props.parent} rowIndex={props.index} > -
+
{(item.type === ChatEntryType.TYPE_CHAT) && <>
{item.timestamp}
@@ -83,38 +105,43 @@ export const ChatHistoryView: FC<{}> = props => ); }; + const onResize = useCallback((info: Size) => + { + cache.clearAll(); + }, [cache]); + useEffect(() => { if(elementRef && elementRef.current && isVisible) { - elementRef.current.scrollToRow(chats.length - 1); + //elementRef.current.measureAllRows(); + elementRef.current.scrollToRow(chatHistoryState.chats.length - 1); } - console.log(chats.length); - }, [chats, isVisible]) + //console.log(chatHistoryState.chats.length); + }, [chatHistoryState.chats, isVisible, chatHistoryUpdateId]) return ( - + {isVisible && setIsVisible(false) } />
- + {({ height, width }) => { - cache.clearAll(); - return ( + deferredMeasurementCache={cache} + /> ) } } diff --git a/src/views/chat-history/context/ChatHistoryContext.tsx b/src/views/chat-history/context/ChatHistoryContext.tsx index 10c8ee3f..981d6007 100644 --- a/src/views/chat-history/context/ChatHistoryContext.tsx +++ b/src/views/chat-history/context/ChatHistoryContext.tsx @@ -3,7 +3,7 @@ import { ChatHistoryContextProps, IChatHistoryContext } from './ChatHistoryConte const ChatHistoryContext = createContext({ chatHistoryState: null, - dispatchChatHistoryState: null + roomHistoryState: null }); export const ChatHistoryContextProvider: FC = props => diff --git a/src/views/chat-history/context/ChatHistoryContext.types.ts b/src/views/chat-history/context/ChatHistoryContext.types.ts index 57cbbd91..e691d471 100644 --- a/src/views/chat-history/context/ChatHistoryContext.types.ts +++ b/src/views/chat-history/context/ChatHistoryContext.types.ts @@ -1,12 +1,47 @@ -import { Dispatch, ProviderProps } from 'react'; -import { IChatHistoryAction, IChatHistoryState } from '../reducers/ChatHistoryReducer'; +import { ProviderProps } from 'react'; export interface IChatHistoryContext { chatHistoryState: IChatHistoryState; - dispatchChatHistoryState: Dispatch; + roomHistoryState: IRoomHistoryState; } +export interface IChatHistoryState { + chats: IChatEntry[]; + notifier: () => void + notify(): void; +} + +export interface IRoomHistoryState { + roomHistory: IRoomHistoryEntry[]; + notifier: () => void + notify(): void; +} + +export interface IChatEntry { + id: number; + entityId: number; + name: string; + look?: string; + message?: string; + timestamp: string; + type: number; +} + +export interface IRoomHistoryEntry { + id: number; + name: string; +} + +export class ChatEntryType +{ + public static TYPE_CHAT = 1; + public static TYPE_ROOM_INFO = 2; +} + +export const CHAT_HISTORY_MAX = 1000; +export const ROOM_HISTORY_MAX = 10; + export interface ChatHistoryContextProps extends ProviderProps { diff --git a/src/views/chat-history/reducers/ChatHistoryReducer.tsx b/src/views/chat-history/reducers/ChatHistoryReducer.tsx deleted file mode 100644 index 4a51ff8c..00000000 --- a/src/views/chat-history/reducers/ChatHistoryReducer.tsx +++ /dev/null @@ -1,66 +0,0 @@ -import { Reducer } from 'react'; - -export interface IChatHistoryState { - chats: IChatEntry[]; - roomHistory: IRoomHistoryEntry[]; -} - -export interface IChatEntry { - id: number; - name: string; - look?: string; - message?: string; - timestamp: string; - type: number; -} - -export interface IRoomHistoryEntry { - id: number; - name: string; -} - -export class ChatEntryType -{ - public static TYPE_CHAT = 1; - public static TYPE_ROOM_INFO = 2; -} - -export interface IChatHistoryAction -{ - type: string; - payload: { - chats?: IChatEntry[]; - roomHistory?: IRoomHistoryEntry[]; - } -} - -export class ChatHistoryAction -{ - public static SET_CHATS: string = 'CHA_SET_CHATS'; - public static SET_ROOM_HISTORY: string = 'CHA_SET_ROOM_HISTORY'; -} - -export const initialChatHistory: IChatHistoryState = { - chats: [], - roomHistory: [] -}; - -export const CHAT_HISTORY_MAX = 1000; -export const ROOM_HISTORY_MAX = 10; - -export const ChatHistoryReducer: Reducer = (state, action) => -{ - switch(action.type) - { - case ChatHistoryAction.SET_CHATS: { - const chats = (action.payload.chats || state.chats || null); - - return { ...state, chats }; - } - case ChatHistoryAction.SET_ROOM_HISTORY: { - const roomHistory = (action.payload.roomHistory || state.roomHistory || null); - - return { ...state, roomHistory }; - } - } -} diff --git a/src/views/chat-history/utils/ChatHistoryState.ts b/src/views/chat-history/utils/ChatHistoryState.ts new file mode 100644 index 00000000..895c00a1 --- /dev/null +++ b/src/views/chat-history/utils/ChatHistoryState.ts @@ -0,0 +1,32 @@ +import { IChatEntry, IChatHistoryState } from '../context/ChatHistoryContext.types'; + +export class ChatHistoryState implements IChatHistoryState +{ + private _chats: IChatEntry[]; + private _notifier: () => void; + + constructor() + { + this._chats = []; + } + + public get chats(): IChatEntry[] + { + return this._chats; + } + + public get notifier(): () => void + { + return this._notifier; + } + + public set notifier(notifier: () => void) + { + this._notifier = notifier; + } + + notify(): void + { + if(this._notifier) this._notifier(); + } +} diff --git a/src/views/chat-history/utils/RoomHistoryState.ts b/src/views/chat-history/utils/RoomHistoryState.ts new file mode 100644 index 00000000..d3002b81 --- /dev/null +++ b/src/views/chat-history/utils/RoomHistoryState.ts @@ -0,0 +1,32 @@ +import { IRoomHistoryEntry, IRoomHistoryState } from '../context/ChatHistoryContext.types'; + +export class RoomHistoryState implements IRoomHistoryState +{ + private _roomHistory: IRoomHistoryEntry[]; + private _notifier: () => void; + + constructor() + { + this._roomHistory = []; + } + + public get roomHistory(): IRoomHistoryEntry[] + { + return this._roomHistory; + } + + public get notifier(): () => void + { + return this._notifier; + } + + public set notifier(notifier: () => void) + { + this._notifier = notifier; + } + + notify(): void + { + if(this._notifier) this._notifier(); + } +}