From a34099e707d8d9a1aa849dcbf5fc9991142ac1d2 Mon Sep 17 00:00:00 2001 From: Konrad Jamrozik Date: Fri, 28 Jun 2024 20:10:48 -0700 Subject: [PATCH] WIP: InputSlider --- .../FactionsDataGrid/InputSlider.tsx | 16 ++++++---- .../FactionsDataGrid/ManageFactionDialog.tsx | 14 +++++---- web/src/components/Label.tsx | 2 +- web/src/lib/rendering/formatString.ts | 28 ++++++++++++++++++ web/src/lib/rendering/renderGameEvent.ts | 29 ++----------------- 5 files changed, 50 insertions(+), 39 deletions(-) create mode 100644 web/src/lib/rendering/formatString.ts diff --git a/web/src/components/FactionsDataGrid/InputSlider.tsx b/web/src/components/FactionsDataGrid/InputSlider.tsx index 6c34d86f..c098cb44 100644 --- a/web/src/components/FactionsDataGrid/InputSlider.tsx +++ b/web/src/components/FactionsDataGrid/InputSlider.tsx @@ -1,12 +1,12 @@ /** This file was originally adapted from * https://mui.com/material-ui/react-slider/#slider-with-input-field */ -import { Button, Stack, SvgIcon, TextField } from '@mui/material' +import { Button, Stack, TextField } from '@mui/material' import Box from '@mui/material/Box' import Slider from '@mui/material/Slider' import { useState } from 'react' -import { assetNameColors } from '../../lib/rendering/renderAssets' -import { Icon } from '../Icon/Icon' +import { formatString } from '../../lib/rendering/formatString' +import { Icon, type IconName } from '../Icon/Icon' const textFieldWidth = 110 @@ -15,6 +15,8 @@ export type InputSliderProps = { readonly onClick: (value: number) => Promise readonly minValue: number readonly maxValue: number + readonly iconName: IconName + readonly label: string } export default function InputSlider( @@ -48,7 +50,7 @@ export default function InputSlider( > - + props.maxValue || value < props.minValue} + disabled={ + value > props.maxValue || value < props.minValue || value === 0 + } onClick={async () => props.onClick(value)} > - Invest intel + {formatString('Invest $TargetID intel', undefined, value)} diff --git a/web/src/components/FactionsDataGrid/ManageFactionDialog.tsx b/web/src/components/FactionsDataGrid/ManageFactionDialog.tsx index 09d33c8a..52f921a4 100644 --- a/web/src/components/FactionsDataGrid/ManageFactionDialog.tsx +++ b/web/src/components/FactionsDataGrid/ManageFactionDialog.tsx @@ -19,7 +19,7 @@ import { getSx } from '../../lib/rendering/renderUtils' import { Label } from '../Label' import InputSlider from './InputSlider' -const factionDetailsGridMaxWidthPx = 400 +const factionDetailsGridMaxWidthPx = 300 export type ManageFactionDialogProps = { readonly faction: Faction @@ -103,22 +103,26 @@ export default function DeployMissionDialog( alignItems="center" > { await Promise.resolve() investIntel(intel) }} minValue={0} maxValue={gs.Assets.Intel} + iconName="Intel" + label="Invest $TargetID intel" /> { await Promise.resolve() investIntel(intel) }} minValue={0} maxValue={gs.Assets.Intel} + iconName="Intel" + label="Invest $TargetID intel" /> @@ -144,10 +148,10 @@ function factionDetailsGrid( > {_.map(entries, (entry, index) => ( - + - + diff --git a/web/src/components/Label.tsx b/web/src/components/Label.tsx index 34c44fa7..5bdccb1a 100644 --- a/web/src/components/Label.tsx +++ b/web/src/components/Label.tsx @@ -11,10 +11,10 @@ export function Label(props: LabelProps): React.JSX.Element { return ( diff --git a/web/src/lib/rendering/formatString.ts b/web/src/lib/rendering/formatString.ts new file mode 100644 index 00000000..d01218ab --- /dev/null +++ b/web/src/lib/rendering/formatString.ts @@ -0,0 +1,28 @@ +import _ from 'lodash' +import { logIds } from './renderGameEvent' + +export function formatString( + template: string, + ids?: number[] | undefined, + targetId?: number | undefined, +): string { + let formatted = template + if (!_.isNil(ids)) { + if (!_.isEmpty(ids)) { + for (const index of _.rangeRight(ids.length)) { + formatted = _.replace( + formatted, + `$IDs[${index}]`, + ids[index]!.toString(), + ) + } + } + formatted = _.replace(formatted, '$IDs[1..]', logIds(ids.slice(1))) + formatted = _.replace(formatted, '$IDs', logIds(ids)) + } + if (!_.isNil(targetId)) { + formatted = _.replace(formatted, '$TargetID+1', (targetId + 1).toString()) + formatted = _.replace(formatted, '$TargetID', targetId.toString()) + } + return formatted +} diff --git a/web/src/lib/rendering/renderGameEvent.ts b/web/src/lib/rendering/renderGameEvent.ts index e3b517d0..401306a7 100644 --- a/web/src/lib/rendering/renderGameEvent.ts +++ b/web/src/lib/rendering/renderGameEvent.ts @@ -5,6 +5,7 @@ import { PlayerActionNameVal, } from '../codesync/PlayerActionEvent' import { str } from '../utils' +import { formatString } from './formatString' const playerActionNameToDisplayMap: { [name in GameEventName]: { @@ -77,33 +78,7 @@ export function getDisplayedDetails(event: GameEventWithTurn): string { ) } -function formatString( - template: string, - ids: number[] | undefined, - targetId: number | undefined, -): string { - let formatted = template - if (!_.isNil(ids)) { - if (!_.isEmpty(ids)) { - for (const index of _.rangeRight(ids.length)) { - formatted = _.replace( - formatted, - `$IDs[${index}]`, - ids[index]!.toString(), - ) - } - } - formatted = _.replace(formatted, '$IDs[1..]', logIds(ids.slice(1))) - formatted = _.replace(formatted, '$IDs', logIds(ids)) - } - if (!_.isNil(targetId)) { - formatted = _.replace(formatted, '$TargetID+1', (targetId + 1).toString()) - formatted = _.replace(formatted, '$TargetID', targetId.toString()) - } - return formatted -} - -function logIds(ids: number[]): string { +export function logIds(ids: number[]): string { // The "[...id]" spread here is used to avoid mutating the "ids" array. return str([...ids].sort((left, right) => left - right)) }