• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

DaniSomoza / galactic-commander / 12444891208

21 Dec 2024 11:46AM UTC coverage: 52.036% (-13.6%) from 65.587%
12444891208

Pull #11

github

web-flow
Merge 9b5ea0e56 into 4f9f087f0
Pull Request #11: Build units

206 of 789 branches covered (26.11%)

Branch coverage included in aggregate %.

366 of 898 new or added lines in 85 files covered. (40.76%)

10 existing lines in 7 files now uncovered.

1417 of 2330 relevant lines covered (60.82%)

3.82 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

2.56
/packages/frontend/src/components/build-units-queue/BuildUnitsQueue.tsx
1
import { useState } from 'react'
2
import Paper from '@mui/material/Paper'
3
import Stack from '@mui/material/Stack'
4
import Typography from '@mui/material/Typography'
5
import Box from '@mui/material/Box'
6
import Tooltip from '@mui/material/Tooltip'
7
import Skeleton from '@mui/material/Skeleton'
8
import IconButton from '@mui/material/IconButton'
9
import ArrowRightAltRoundedIcon from '@mui/icons-material/ArrowRightAltRounded'
10
import CancelRoundedIcon from '@mui/icons-material/CancelRounded'
11
import AlarmIcon from '@mui/icons-material/Alarm'
12

13
import { UnitType, UnitTypes } from 'game-api-microservice/src/types/Unit'
14
import { PlanetType } from 'game-api-microservice/src/types/Planet'
15
import { PlayerType } from 'game-api-microservice/src/types/Player'
16
import computedBonus from 'game-engine/src/engine/bonus/computedBonus'
17

18
import { usePlayer } from '../../store/PlayerContext'
19
import Loader from '../loader/Loader'
20
import { useTranslations } from '../../store/TranslationContext'
21
import UnitCard from '../unit-card/UnitCard'
22
import formatTimestamp from '../../utils/formatTimestamp'
23
import formatTimer from '../../utils/formatTimer'
24
import millisToSeconds from '../../utils/millisToSeconds'
25
import { useBuildUnits } from '../../store/buildUnitsContext'
26

27
type BuildUnitsQueueProps = {
28
  unitType: UnitTypes
29
}
30

31
const path: Record<UnitTypes, keyof PlanetType['unitBuild']> = {
1✔
32
  TROOP: 'troops',
33
  SPACESHIP: 'spaceships',
34
  DEFENSE: 'defenses'
35
}
36

37
function BuildUnitsQueue({ unitType }: BuildUnitsQueueProps) {
NEW
38
  const { translate } = useTranslations()
×
NEW
39
  const { player, isPlayerLoading, selectedPlanet, units } = usePlayer()
×
40

NEW
41
  if (!player || isPlayerLoading || !selectedPlanet) {
×
NEW
42
    return <Loader isLoading />
×
43
  }
44

NEW
45
  const queue = selectedPlanet.unitBuild[path[unitType]].queue
×
NEW
46
  const showQueue = queue.length > 0
×
47

NEW
48
  return (
×
49
    <Paper variant="outlined">
50
      {showQueue ? (
×
51
        <Stack direction={'row'} gap={1} padding={1} sx={{ overflowX: 'auto' }}>
52
          {queue.map(({ unitName, amount }, index) => {
NEW
53
            const unit = units.find((unit) => unit.name === unitName)
×
54

NEW
55
            const showNextArrow = index < queue.length - 1
×
56

NEW
57
            return (
×
58
              <Stack key={index} alignItems={'center'} direction={'row'} gap={1}>
59
                <QueueItem index={index} unit={unit!} amount={amount} player={player} />
60

61
                {showNextArrow && <ArrowRightAltRoundedIcon sx={{ transform: 'rotate(180deg)' }} />}
×
62
              </Stack>
63
            )
64
          })}
65
        </Stack>
66
      ) : (
67
        <Stack direction={'row'} justifyContent={'center'} gap={1} padding={4}>
68
          <Tooltip title={translate('BUILD_UNITS_QUEUE_EMPTY_TOOLTIP')} arrow>
69
            <Typography fontSize={12}>{translate('BUILD_UNITS_QUEUE_EMPTY')}</Typography>
70
          </Tooltip>
71
        </Stack>
72
      )}
73
    </Paper>
74
  )
75
}
76

77
export default BuildUnitsQueue
78

79
type QueueItemProps = {
80
  index: number
81
  unit: UnitType
82
  amount: number
83
  player: PlayerType
84
}
85

86
function QueueItem({ unit, amount, player, index }: QueueItemProps) {
NEW
87
  const { translate } = useTranslations()
×
88

NEW
89
  const { removeBuildUnitsFromQueue } = useBuildUnits()
×
90

NEW
91
  const [showRemoveButton, setShowRemoveButton] = useState(false)
×
92

NEW
93
  if (!unit) {
×
NEW
94
    return <Skeleton variant="rounded" height={'200px'} width={'200px'} />
×
95
  }
96

NEW
97
  const buildUnitBonus = computedBonus(player.perks, 'TROOPS_TRAINING_BONUS')
×
NEW
98
  const buildUnitDuration = millisToSeconds(unit.buildBaseTime * (100 / buildUnitBonus))
×
NEW
99
  const countdown = buildUnitDuration * amount
×
100

101
  async function removeFromQueue(index: number) {
NEW
102
    await removeBuildUnitsFromQueue(index, unit.type)
×
103
  }
104

NEW
105
  return (
×
106
    <Tooltip title={translate(unit.name)} arrow>
107
      <div
NEW
108
        onMouseEnter={() => setShowRemoveButton(true)}
×
NEW
109
        onMouseLeave={() => setShowRemoveButton(false)}
×
110
      >
111
        <UnitCard showNameLabel={false} unit={unit} amount={amount} height={128} width={128}>
112
          <>
113
            {/* Countdown */}
114
            <Box position={'absolute'} top={20} sx={{ transform: 'translate(0, -50%)' }}>
115
              <Paper variant="outlined">
116
                <Tooltip
117
                  title={translate(
118
                    'BUILD_UNITS_QUEUE_END_DATE_TOOLTIP',
119
                    formatTimestamp(countdown || 0)
×
120
                  )}
121
                  arrow
122
                >
123
                  <Stack
124
                    direction={'row'}
125
                    gap={0.5}
126
                    padding={0.4}
127
                    paddingLeft={0.6}
128
                    paddingRight={0.8}
129
                    alignItems={'center'}
130
                  >
131
                    <AlarmIcon fontSize="small" />
132
                    <Typography fontSize={12}>{formatTimer(countdown)}</Typography>
133
                  </Stack>
134
                </Tooltip>
135
              </Paper>
136
            </Box>
137

138
            {/* remove item from the queue */}
139
            {showRemoveButton && (
×
140
              <Box position={'absolute'} top={0} right={0}>
141
                <Tooltip
142
                  title={translate('BUILD_UNITS_QUEUE_REMOVE_ITEM_TOOLTIP')}
143
                  arrow
144
                  placement="top"
145
                >
146
                  <IconButton
147
                    size="small"
NEW
148
                    onClick={() => removeFromQueue(index)}
×
149
                    aria-label={translate('BUILD_UNITS_QUEUE_REMOVE_ITEM_TOOLTIP')}
150
                    color="inherit"
151
                    sx={{ fontSize: '14px' }}
152
                  >
153
                    <CancelRoundedIcon color="error" fontSize="inherit" />
154
                  </IconButton>
155
                </Tooltip>
156
              </Box>
157
            )}
158

159
            {/* position in the queue */}
160
            <Box position={'absolute'} left={0} bottom={0} padding={1}>
161
              <Paper variant="outlined">
162
                <Typography
163
                  variant="body1"
164
                  fontSize={12}
165
                  fontWeight={500}
166
                  padding={0.3}
167
                  paddingLeft={0.6}
168
                  paddingRight={0.6}
169
                >
170
                  {index + 1}ยบ
171
                </Typography>
172
              </Paper>
173
            </Box>
174
          </>
175
        </UnitCard>
176
      </div>
177
    </Tooltip>
178
  )
179
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc