diff --git a/app/components-react/highlighter/HighlightGenerator.tsx b/app/components-react/highlighter/HighlightGenerator.tsx index 6e1d93188527..c9465292c256 100644 --- a/app/components-react/highlighter/HighlightGenerator.tsx +++ b/app/components-react/highlighter/HighlightGenerator.tsx @@ -3,7 +3,7 @@ import { Button, Select, Checkbox, Typography } from 'antd'; import { DownOutlined, RobotOutlined } from '@ant-design/icons'; import { IFilterOptions } from './utils'; import { IInput } from 'services/highlighter'; -import { getPlacementFromInputs, InputEmojiSection } from './InputEmojiSection'; +import { getPlacementFromInputs } from './InputEmojiSection'; import { EHighlighterInputTypes } from 'services/highlighter/ai-highlighter/ai-highlighter'; import styles from './HighlightGenerator.m.less'; import { formatSecondsToHMS } from './ClipPreview'; diff --git a/app/components-react/highlighter/InputEmojiSection.m.less b/app/components-react/highlighter/InputEmojiSection.m.less index c1d7d0f50749..69cab023a0b8 100644 --- a/app/components-react/highlighter/InputEmojiSection.m.less +++ b/app/components-react/highlighter/InputEmojiSection.m.less @@ -1,3 +1,10 @@ .description { text-wrap: nowrap; } + +.aimoment-wrapper { + display: flex; + gap: 8px; + flex-wrap: wrap; + overflow: hidden; +} diff --git a/app/components-react/highlighter/InputEmojiSection.tsx b/app/components-react/highlighter/InputEmojiSection.tsx index 6ce9326fd2c2..4f9baf9aade3 100644 --- a/app/components-react/highlighter/InputEmojiSection.tsx +++ b/app/components-react/highlighter/InputEmojiSection.tsx @@ -7,39 +7,48 @@ import styles from './InputEmojiSection.m.less'; interface TypeWording { emoji: string; description: string; + orderPriority: number; } -const TYPE_WORDING_MAP: Record TypeWording> = { +const DISPLAY_TYPE_MAP: Record TypeWording> = { [EHighlighterInputTypes.KILL]: count => ({ emoji: 'ðŸ”Ŧ', description: count > 1 ? 'eliminations' : 'elimination', + orderPriority: 4, }), [EHighlighterInputTypes.KNOCKED]: count => ({ emoji: 'ðŸĨŠ', description: count > 1 ? 'knocks' : 'knocked', + orderPriority: 5, }), [EHighlighterInputTypes.DEATH]: count => ({ emoji: 'ðŸŠĶ', description: count > 1 ? 'deaths' : 'death', + orderPriority: 3, }), [EHighlighterInputTypes.VICTORY]: count => ({ emoji: '🏆', description: count > 1 ? 'wins' : 'win', + orderPriority: 2, }), [EHighlighterInputTypes.DEPLOY]: count => ({ emoji: '🊂', description: count > 1 ? 'deploys' : 'deploy', + orderPriority: 8, }), [EHighlighterInputTypes.PLAYER_KNOCKED]: () => ({ emoji: 'ðŸ˜ĩ', description: 'got knocked', + orderPriority: 6, }), BOT_KILL: count => ({ emoji: 'ðŸĪ–', description: count > 1 ? 'bot eliminations' : 'bot elimination', + orderPriority: 7, }), rounds: count => ({ emoji: '🏁', description: count === 0 || count > 1 ? `rounds ${count === 0 ? 'detected' : ''}` : 'round', + orderPriority: 1, }), }; @@ -47,7 +56,7 @@ function getTypeWordingFromType( type: string, count: number, ): { emoji: string; description: string } { - return TYPE_WORDING_MAP[type]?.(count) ?? { emoji: '', description: '?' }; + return DISPLAY_TYPE_MAP[type]?.(count) ?? { emoji: '', description: '?' }; } function getInputTypeCount(clips: TClip[]): { [type: string]: number } { @@ -108,12 +117,14 @@ export function InputEmojiSection({ includeDeploy, showCount, showDescription, + showDeathPlacement, }: { clips: TClip[]; includeRounds: boolean; includeDeploy: boolean; showCount?: boolean; showDescription?: boolean; + showDeathPlacement?: boolean; }): JSX.Element { const excludeTypes = [ EHighlighterInputTypes.GAME_SEQUENCE, @@ -123,29 +134,46 @@ export function InputEmojiSection({ EHighlighterInputTypes.META_DURATION, EHighlighterInputTypes.LOW_HEALTH, ]; - const inputTypeMap = Object.entries(getInputTypeCount(clips)); - const filteredInputTypeMap = inputTypeMap.filter( - ([type]) => - !excludeTypes.includes(type as EHighlighterInputTypes) && - (inputTypeMap.length <= 2 || includeDeploy || type !== 'deploy'), - ); + const filteredInputTypeMap = inputTypeMap + .filter(([type]) => { + if (excludeTypes.includes(type as EHighlighterInputTypes)) { + return false; + } + + if (!includeDeploy && type === EHighlighterInputTypes.DEPLOY) { + return false; + } + + return true; + }) + .sort(([typeA], [typeB]) => { + const orderItemA = DISPLAY_TYPE_MAP[typeA](0).orderPriority; + const orderItemB = DISPLAY_TYPE_MAP[typeB](0).orderPriority; + return orderItemA - orderItemB; + }); return ( -
+
{includeRounds && } - {filteredInputTypeMap.map(([type, count]) => ( - - ))} +
3 ? 'space-evenly' : 'left', + }} + > + {filteredInputTypeMap.map(([type, count]) => ( + + ))} +
{inputTypeMap.length > 3 ? '...' : ''}
@@ -171,24 +199,24 @@ export function AiMomentTag({ clips, showCount, showDescription, - includeRounds, + showDeathPlacement, }: { type: string; count: number; clips: TClip[]; showCount?: boolean; showDescription?: boolean; - includeRounds?: boolean; + showDeathPlacement?: boolean; }): JSX.Element { const { emoji, description } = getTypeWordingFromType(type, count); return (
{emoji} - {(showCount !== false || showDescription !== false) && ( + {(showCount || showDescription || showDeathPlacement) && ( - {showCount !== false && `${count} `} - {showDescription !== false && description} - {!includeRounds && isDeath(type) && getGamePlacement(clips) + {showCount && `${count} `} + {showDescription && description} + {showDeathPlacement && isDeath(type) && getGamePlacement(clips) ? '#' + getGamePlacement(clips) : ''} diff --git a/app/components-react/highlighter/StreamCard.tsx b/app/components-react/highlighter/StreamCard.tsx index ff287fe06945..994c8019cb9c 100644 --- a/app/components-react/highlighter/StreamCard.tsx +++ b/app/components-react/highlighter/StreamCard.tsx @@ -81,7 +81,14 @@ export default function StreamCard({

{stream.state.type === EAiDetectionState.FINISHED ? ( - + ) : (
)}