From f0755936fc6ed30f01d4609845faedb9c9bd4a51 Mon Sep 17 00:00:00 2001 From: bedlam343 Date: Sat, 25 May 2024 16:57:32 -0700 Subject: [PATCH] only show latest conversation message elemetn in the pearce screen list --- .../Complex/MissileIncomingElement.tsx | 15 +++------ .../Complex/RequestApprovalElement.tsx | 26 ++++----------- src/components/Widget/ListWidget.tsx | 17 ++++++++-- src/hooks/useWorldSim.ts | 2 +- src/prototype/lpd/stress/highLPD.ts | 4 +-- src/prototype/lpd/stress/lowLPD.ts | 4 +-- src/prototype/lpd/stress/mediumLPD.ts | 4 +-- src/redux/slices/minimapSlice.ts | 33 +++++++++++++++---- src/types/element.ts | 4 +-- src/types/schema-types.ts | 4 ++- src/types/support-types.ts | 5 +++ src/utils/lpdHelper.ts | 8 ++--- 12 files changed, 72 insertions(+), 54 deletions(-) diff --git a/src/components/Element/Complex/MissileIncomingElement.tsx b/src/components/Element/Complex/MissileIncomingElement.tsx index 79e95e6..8d0472a 100644 --- a/src/components/Element/Complex/MissileIncomingElement.tsx +++ b/src/components/Element/Complex/MissileIncomingElement.tsx @@ -1,22 +1,15 @@ import type { MissileIncomingElement as MissileIncomingElementType } from 'src/types/element'; import IconElement from 'src/components/Element/Simple/IconElement'; +import { useAppSelector } from 'src/redux/hooks'; +import { getMessage } from 'src/redux/slices/minimapSlice'; type MissileIncomingProps = { element: MissileIncomingElementType; }; const MissileIncomingElement = ({ element }: MissileIncomingProps) => { - const { id, h, w, message, icon: iconElement } = element; - const { - data: { - detectedByAca, - missileLocation, - choiceWeight, - survivability, - acaAttackWeapon, - }, - priority, - } = message; + const { id, h, w, messageId, icon: iconElement } = element; + const message = useAppSelector((state) => getMessage(state, messageId)); return (
diff --git a/src/components/Element/Complex/RequestApprovalElement.tsx b/src/components/Element/Complex/RequestApprovalElement.tsx index 7e0ba1e..c0b6cb2 100644 --- a/src/components/Element/Complex/RequestApprovalElement.tsx +++ b/src/components/Element/Complex/RequestApprovalElement.tsx @@ -1,7 +1,9 @@ -import type { ReactNode } from 'react'; +import { useEffect, type ReactNode } from 'react'; import { type RequestApprovalElement as RequestApprovalElementType } from 'src/types/element'; import ButtonElement from '../Simple/ButtonElement'; import IconElement from '../Simple/IconElement'; +import { useAppSelector } from 'src/redux/hooks'; +import { getMessage } from 'src/redux/slices/minimapSlice'; type RequestApprovalProps = { element: RequestApprovalElementType; @@ -12,28 +14,14 @@ const RequestApprovalElement = ({ element, children, }: RequestApprovalProps) => { - const { - id, - collapsed, - icon, - rightButton, - leftButton, - message: { - priority, - data: { - target, - detectedByAca, - choiceWeight, - attackWeapon, - collateralDamage, - }, - }, - } = element; + const { id, collapsed, icon, rightButton, leftButton, messageId } = element; + const message = useAppSelector((state) => getMessage(state, messageId)); return (
- {target.type} + {/* @ts-ignore */} + {message?.data?.target?.type}
); }; diff --git a/src/components/Widget/ListWidget.tsx b/src/components/Widget/ListWidget.tsx index a0f4fd7..a8932bd 100644 --- a/src/components/Widget/ListWidget.tsx +++ b/src/components/Widget/ListWidget.tsx @@ -7,6 +7,7 @@ import { import { getElementsInGaze, getGazesAndKeys } from 'src/redux/slices/gazeSlice'; import type { Widget } from 'src/types/widget'; import ListElement from 'src/components/Element/Complex/ListElement'; +import { getMessages } from 'src/redux/slices/minimapSlice'; type ListWidgetProps = { widget: Widget; @@ -16,6 +17,7 @@ const LIST_ELEMENT_HEIGHT = 80; const GAP_BETWEEN_ELEMENTS = 6; const ListWidget = ({ widget }: ListWidgetProps) => { + const messages = useAppSelector(getMessages); const elementsInGaze = useAppSelector(getElementsInGaze); const gazesAndKeys = useAppSelector(getGazesAndKeys); const { activeElementId } = useAppSelector(getCommunication); @@ -75,7 +77,7 @@ const ListWidget = ({ widget }: ListWidgetProps) => { // just pick the first element in the gaze for now if (element.id === mouseLeftClick.elemsInGaze[0].id) { // @ts-ignore - if (!element.message) { + if (!element.messageId) { // FIX: all elements should have a message (at least the ones in the list) // at the minimu, they should have a conversationId attached to them? console.warn('Element does not have a message', element); @@ -85,13 +87,13 @@ const ListWidget = ({ widget }: ListWidgetProps) => { dispatch( updateCommunication({ // @ts-ignore - activeConversationId: element.message.conversationId, + activeConversationId: messages[element.messageId].conversationId, activeElementId: element.id, }), ); } }); - }, [gazesAndKeys, dispatch, elementInGazeId, widget.elements]); + }, [gazesAndKeys, dispatch, elementInGazeId, messages, widget.elements]); // check if the list is overflowed // useEffect(() => { @@ -143,6 +145,15 @@ const ListWidget = ({ widget }: ListWidgetProps) => { }} > {sortedElementsByPriority.map((element) => { + // don't render element if it's message is not the latest in the conversation + // @ts-ignore + const elemMessageId = element.messageId; + if (elemMessageId) { + if (!messages[elemMessageId].latestInConvo) { + return null; + } + } + // style for the element which is current being hoverd over const hoverStyle = element.id === elementInGazeId diff --git a/src/hooks/useWorldSim.ts b/src/hooks/useWorldSim.ts index 73ca764..01e9be1 100644 --- a/src/hooks/useWorldSim.ts +++ b/src/hooks/useWorldSim.ts @@ -19,7 +19,7 @@ const useWorldSim = () => { if (message) setMessages((prevMessages) => [ ...prevMessages, - { ...message, fulfilled: false }, + { ...message, fulfilled: false, read: false, latestInConvo: true }, // newest message is latest in convo ]); if (stressLevel) setStressLevel(stressLevel); }); diff --git a/src/prototype/lpd/stress/highLPD.ts b/src/prototype/lpd/stress/highLPD.ts index eb45dbd..49b8f17 100644 --- a/src/prototype/lpd/stress/highLPD.ts +++ b/src/prototype/lpd/stress/highLPD.ts @@ -34,7 +34,7 @@ const requestApprovalToAttackMessageHigh = ( message.priority, 'list', ), - message, + message.id, listWidgetId, lpdHelper.generateIconElement( lpdHelper.generateBaseElement(uuid(), 'visual', 56, 56), @@ -181,7 +181,7 @@ const missileToOwnshipDetectedMessageHigh = ( message.priority, 'list', ), - message, + message.id, listWidgetId, lpdHelper.generateIconElement( lpdHelper.generateBaseElement(uuid(), 'visual', 56, 56), diff --git a/src/prototype/lpd/stress/lowLPD.ts b/src/prototype/lpd/stress/lowLPD.ts index c283c9d..59bbba3 100644 --- a/src/prototype/lpd/stress/lowLPD.ts +++ b/src/prototype/lpd/stress/lowLPD.ts @@ -27,7 +27,7 @@ const requestApprovalToAttackMessageLow = ( const pearceScreenElements = [ lpdHelper.generateRequestApprovalElement( lpdHelper.generateBaseElement(uuid(), 'visual', 30, 30, message.priority), - message, + message.id, listWidgetId, lpdHelper.generateIconElement( lpdHelper.generateBaseElement(uuid(), 'visual', 56, 56), @@ -223,7 +223,7 @@ const missileToOwnshipDetectedMessageLow = ( 200, message.priority, ), - message, + message.id, listWidgetId, lpdHelper.generateIconElement( lpdHelper.generateBaseElement(uuid(), 'visual', 56, 56), diff --git a/src/prototype/lpd/stress/mediumLPD.ts b/src/prototype/lpd/stress/mediumLPD.ts index d7d962f..dc872b4 100644 --- a/src/prototype/lpd/stress/mediumLPD.ts +++ b/src/prototype/lpd/stress/mediumLPD.ts @@ -27,7 +27,7 @@ const requestApprovalToAttackMessageMedium = ( const pearceScreenElements: Element[] = [ lpdHelper.generateRequestApprovalElement( lpdHelper.generateBaseElement(uuid(), 'visual', 30, 30, message.priority), - message, + message.id, listWidgetId, lpdHelper.generateIconElement( lpdHelper.generateBaseElement(uuid(), 'visual', 56, 56), @@ -173,7 +173,7 @@ const missileToOwnshipDetectedMessageMedium = ( 200, message.priority, ), - message, + message.id, listWidgetId, lpdHelper.generateIconElement( lpdHelper.generateBaseElement(uuid(), 'visual', 56, 56), diff --git a/src/redux/slices/minimapSlice.ts b/src/redux/slices/minimapSlice.ts index 90fa4b4..0c493d0 100644 --- a/src/redux/slices/minimapSlice.ts +++ b/src/redux/slices/minimapSlice.ts @@ -1,7 +1,7 @@ import { createSlice, createSelector } from '@reduxjs/toolkit'; import type { PayloadAction } from '@reduxjs/toolkit'; import type { Widget, VehicleWidget, WidgetMap } from 'src/types/widget'; -import type { Screen } from 'src/types/support-types'; +import type { MessageMap, Screen } from 'src/types/support-types'; import type { Message } from 'src/types/schema-types'; import type { Element, ElementMap } from 'src/types/element'; import type { LinkedSectionWidget, Section } from 'src/types/support-types'; @@ -15,7 +15,7 @@ export type InitialMinimapState = { drones: VehicleWidget[]; widgets: WidgetMap; - messages: Message[]; + messages: MessageMap; sections: Section[]; stressLevel: number; @@ -26,7 +26,7 @@ const initialState: InitialMinimapState = { audioComplexity: 0, ownship: null, drones: [], - messages: [], + messages: {}, widgets: {}, sections: [], stressLevel: 0, @@ -397,7 +397,19 @@ export const minimapSlice = createSlice({ }, addMessage: (state, action: PayloadAction) => { - state.messages.push(action.payload); + const updatedMessages = { ...state.messages }; + + // set latestInConvo to false for all messages in the same conversation + Object.keys(updatedMessages).forEach((id) => { + if ( + updatedMessages[id].conversationId === action.payload.conversationId + ) { + updatedMessages[id].latestInConvo = false; + } + }); + + updatedMessages[action.payload.id] = action.payload; + state.messages = updatedMessages; }, setStressLevel: (state, action: PayloadAction) => { @@ -449,10 +461,16 @@ export const minimapSlice = createSlice({ getVisualComplexity: (state) => state.visualComplexity, getAudioComplexity: (state) => state.audioComplexity, getMessages: (state) => state.messages, + getMessage: (state, messageId: string) => state.messages[messageId], getConversationMessages: (state, conversationId: string) => { - return state.messages.filter( - (message) => message.conversationId === conversationId, - ); + const messages: Message[] = []; + Object.keys(state.messages).forEach((messageId) => { + if (state.messages[messageId].conversationId === conversationId) { + messages.push(state.messages[messageId]); + } + }); + + return messages; }, getStressLevel: (state) => state.stressLevel, @@ -511,6 +529,7 @@ export const { getElementsOnScreen, getMessages, + getMessage, getConversationMessages, getOwnship, diff --git a/src/types/element.ts b/src/types/element.ts index be4fd84..fe9a57b 100644 --- a/src/types/element.ts +++ b/src/types/element.ts @@ -85,7 +85,7 @@ export type CustomElement = BaseElement & { export type RequestApprovalElement = BaseElement & { type: 'request-approval'; - message: RequestApprovalToAttack; + messageId: string; icon: IconElement; leftButton: ButtonElement; rightButton: ButtonElement; @@ -95,7 +95,7 @@ export type RequestApprovalElement = BaseElement & { export type MissileIncomingElement = BaseElement & { type: 'missile-incoming'; - message: MissileToOwnshipDetected; + messageId: string; icon: IconElement; widgetId: string; }; diff --git a/src/types/schema-types.ts b/src/types/schema-types.ts index 95059a5..d529202 100644 --- a/src/types/schema-types.ts +++ b/src/types/schema-types.ts @@ -24,8 +24,10 @@ export type BaseMessage = { priority: Priority; kind: TKind; data: TData; + latestInConvo?: boolean; + read?: boolean; fulfilled?: boolean; - tags?: string[] + tags?: string[]; }; export type RequestApprovalToAttack = BaseMessage< diff --git a/src/types/support-types.ts b/src/types/support-types.ts index 4d1dba6..bfbb482 100644 --- a/src/types/support-types.ts +++ b/src/types/support-types.ts @@ -1,4 +1,5 @@ import { type Widget } from 'src/types/widget'; +import { type Message } from 'src/types/schema-types'; export type Cell = { widgetIDs: string[]; @@ -45,3 +46,7 @@ export type WidgetCluster = { sectionIds?: LinkedSectionWidget[]; actions?: string[]; }; + +export type MessageMap = { + [key: string]: Message; +}; diff --git a/src/utils/lpdHelper.ts b/src/utils/lpdHelper.ts index 238c088..6cedf8d 100644 --- a/src/utils/lpdHelper.ts +++ b/src/utils/lpdHelper.ts @@ -210,20 +210,20 @@ const generateAudioElement = ( // Generate complex elements const generateMissileIncomingElement = ( baseElement: Element.BaseElement, - message: MissileToOwnshipDetected, + messageId: string, widgetId: string, icon: Element.IconElement, ): Element.MissileIncomingElement => ({ ...baseElement, type: 'missile-incoming', - message, + messageId, widgetId, icon, }); const generateRequestApprovalElement = ( baseElement: Element.BaseElement, - message: RequestApprovalToAttack, + messageId: string, widgetId: string, icon: Element.IconElement, leftButton: Element.ButtonElement, @@ -231,7 +231,7 @@ const generateRequestApprovalElement = ( ): Element.RequestApprovalElement => ({ ...baseElement, type: 'request-approval', - message, + messageId, widgetId, icon, leftButton,