only show latest conversation message elemetn in the pearce screen list

This commit is contained in:
bedlam343 2024-05-25 16:57:32 -07:00
parent f4cc43fbf1
commit f0755936fc
12 changed files with 72 additions and 54 deletions

View File

@ -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 (
<div id={id} className="flex text-white items-center gap-4">

View File

@ -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 (
<div id={id} className="flex text-white items-center gap-4">
<IconElement element={icon} />
<span>{target.type}</span>
{/* @ts-ignore */}
<span>{message?.data?.target?.type}</span>
</div>
);
};

View File

@ -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

View File

@ -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);
});

View File

@ -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),

View File

@ -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),

View File

@ -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),

View File

@ -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<Message>) => {
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<number>) => {
@ -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,

View File

@ -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;
};

View File

@ -24,8 +24,10 @@ export type BaseMessage<TKind extends string, TData extends object> = {
priority: Priority;
kind: TKind;
data: TData;
latestInConvo?: boolean;
read?: boolean;
fulfilled?: boolean;
tags?: string[]
tags?: string[];
};
export type RequestApprovalToAttack = BaseMessage<

View File

@ -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;
};

View File

@ -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,