only show latest conversation message elemetn in the pearce screen list
This commit is contained in:
parent
f4cc43fbf1
commit
f0755936fc
@ -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">
|
||||
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
});
|
||||
|
@ -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),
|
||||
|
@ -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),
|
||||
|
@ -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),
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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<
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user