• 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

0.0
/packages/frontend/src/components/research-queue/ResearchQueue.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 IconButton from '@mui/material/IconButton'
8
import ArrowRightAltRoundedIcon from '@mui/icons-material/ArrowRightAltRounded'
9
import CancelRoundedIcon from '@mui/icons-material/CancelRounded'
10
import AlarmIcon from '@mui/icons-material/Alarm'
11

12
import calculateResearchDuration from 'game-engine/src/engine/research/calculateResearchDuration'
13
import { PlayerType } from 'game-api-microservice/src/types/Player'
14
import computedBonus from 'game-engine/src/engine/bonus/computedBonus'
15
import getSecond from 'game-engine/src/helpers/getSecond'
16

17
import { useResearch } from '../../store/ResearchContext'
18
import { useTranslations } from '../../store/TranslationContext'
19
import { usePlayer } from '../../store/PlayerContext'
20
import Loader from '../../components/loader/Loader'
21
import { ResearchType } from 'game-api-microservice/src/types/Research'
22
import ResearchCard from '../research-card/ResearchCard'
23
import formatTimestamp from '../../utils/formatTimestamp'
24
import formatTimer from '../../utils/formatTimer'
25
import calculateResearchLevelInTheQueue from '../../utils/calculateResearchLevelInTheQueue'
26

27
function ResearchQueue() {
NEW
28
  const { translate } = useTranslations()
×
29

NEW
30
  const { player, isPlayerLoading } = usePlayer()
×
31

NEW
32
  const { activeResearch, researchQueue, researched } = useResearch()
×
33

NEW
34
  const showQueue = researchQueue.length > 0
×
35

NEW
36
  if (!player || isPlayerLoading) {
×
37
    // TODO: create a research queue loader component
NEW
38
    return <Loader isLoading />
×
39
  }
40

41
  // TODO: research 500 Internal server error bug when remove an item from the queue
42

NEW
43
  const { researches: raceResearches } = player.race
×
44

NEW
45
  return (
×
46
    <Paper variant="outlined">
47
      {showQueue ? (
×
48
        <Stack direction={'row'} gap={1} padding={1} sx={{ overflowX: 'auto' }}>
49
          {researchQueue.map((researchName, index) => {
NEW
50
            const playerResearch = researched.find(
×
NEW
51
              (playerResearch) => playerResearch.research.name === researchName
×
52
            )
53

NEW
54
            const raceResearch = raceResearches.find(
×
NEW
55
              (raceResearch) => raceResearch.name === researchName
×
56
            )
57

NEW
58
            const currentLevel = calculateResearchLevelInTheQueue(
×
59
              researchName,
60
              playerResearch?.level || 0, // player level
×
61
              researchQueue,
62
              index,
63
              activeResearch
64
            )
65

NEW
66
            const startResearchTime = calculateStartResearchTimestamp(player, researchQueue, index)
×
67

NEW
68
            const showNextArrow = index < researchQueue.length - 1
×
69

NEW
70
            return (
×
71
              <Stack key={index} alignItems={'center'} direction={'row'} gap={1}>
72
                <QueueItem
73
                  index={index}
74
                  research={raceResearch!}
75
                  player={player}
76
                  level={currentLevel}
77
                  startResearchTime={startResearchTime}
78
                />
79

80
                {showNextArrow && <ArrowRightAltRoundedIcon sx={{ transform: 'rotate(180deg)' }} />}
×
81
              </Stack>
82
            )
83
          })}
84
        </Stack>
85
      ) : (
86
        <Stack direction={'row'} justifyContent={'center'} gap={1} padding={4}>
87
          <Tooltip title={translate('RESEARCH_QUEUE_EMPTY_TOOLTIP')} arrow>
88
            <Typography fontSize={12}>{translate('RESEARCH_QUEUE_EMPTY')}</Typography>
89
          </Tooltip>
90
        </Stack>
91
      )}
92
    </Paper>
93
  )
94
}
95

96
export default ResearchQueue
97

98
type QueueItemProps = {
99
  index: number
100
  research: ResearchType
101
  player: PlayerType
102
  level: number
103
  startResearchTime: number
104
}
105

106
function QueueItem({ research, player, level, index, startResearchTime }: QueueItemProps) {
NEW
107
  const { translate } = useTranslations()
×
108

NEW
109
  const nextLevel = level + 1
×
110

NEW
111
  const [showRemoveButton, setShowRemoveButton] = useState(false)
×
112

NEW
113
  const { removeResearchFromQueue } = useResearch()
×
114

115
  async function removeFromQueue(index: number) {
NEW
116
    await removeResearchFromQueue(index)
×
117
  }
118

NEW
119
  const researchBonus = computedBonus(player.perks, 'RESEARCH_BONUS')
×
120

NEW
121
  const researchDuration = calculateResearchDuration(research.initialTime, level, researchBonus)
×
122

NEW
123
  const endResearchTime = startResearchTime + researchDuration
×
124

NEW
125
  const countdown = Math.floor((endResearchTime - getSecond(Date.now())) / 1_000)
×
126

NEW
127
  return (
×
128
    <Tooltip title={translate(research.name)} arrow>
129
      <div
NEW
130
        onMouseEnter={() => setShowRemoveButton(true)}
×
NEW
131
        onMouseLeave={() => setShowRemoveButton(false)}
×
132
      >
133
        <ResearchCard
134
          showNameLabel={false}
135
          research={research}
136
          currentLevel={level}
137
          nextLevel={nextLevel}
138
          height={128}
139
          width={128}
140
        >
141
          <>
142
            {/* Countdown */}
143
            <Box position={'absolute'} top={20} sx={{ transform: 'translate(0, -50%)' }}>
144
              <Tooltip
145
                title={
146
                  <div>
147
                    <div>
148
                      {translate(
149
                        'GAME_RESEARCH_PAGE_RESEARCH_QUEUE_START_DATE',
150
                        formatTimestamp(startResearchTime)
151
                      )}
152
                    </div>
153
                    <div>
154
                      {translate(
155
                        'GAME_RESEARCH_PAGE_RESEARCH_QUEUE_END_DATE',
156
                        formatTimestamp(endResearchTime)
157
                      )}
158
                    </div>
159
                  </div>
160
                }
161
                arrow
162
                placement="top"
163
              >
164
                <Paper variant="outlined">
165
                  <Stack
166
                    direction={'row'}
167
                    gap={0.5}
168
                    padding={0.4}
169
                    paddingLeft={0.6}
170
                    paddingRight={0.8}
171
                    alignItems={'center'}
172
                  >
173
                    <AlarmIcon fontSize="small" />
174
                    <Typography fontSize={12}>{formatTimer(countdown)}</Typography>
175
                  </Stack>
176
                </Paper>
177
              </Tooltip>
178
            </Box>
179

180
            {/* remove item from the queue */}
181
            {showRemoveButton && (
×
182
              <Box position={'absolute'} top={0} right={0}>
183
                <Tooltip
184
                  title={translate('RESEARCH_QUEUE_REMOVE_ITEM_TOOLTIP')}
185
                  arrow
186
                  placement="top"
187
                >
188
                  <IconButton
189
                    size="small"
NEW
190
                    onClick={() => removeFromQueue(index)}
×
191
                    aria-label={translate('RESEARCH_QUEUE_REMOVE_ITEM_TOOLTIP')}
192
                    color="inherit"
193
                    sx={{ fontSize: '14px' }}
194
                  >
195
                    <CancelRoundedIcon color="error" fontSize="inherit" />
196
                  </IconButton>
197
                </Tooltip>
198
              </Box>
199
            )}
200

201
            {/* position in the queue */}
202
            <Box position={'absolute'} left={0} bottom={0} padding={1}>
203
              <Paper variant="outlined">
204
                <Typography
205
                  variant="body1"
206
                  fontSize={12}
207
                  fontWeight={500}
208
                  padding={0.3}
209
                  paddingLeft={0.6}
210
                  paddingRight={0.6}
211
                >
212
                  {index + 1}ยบ
213
                </Typography>
214
              </Paper>
215
            </Box>
216
          </>
217
        </ResearchCard>
218
      </div>
219
    </Tooltip>
220
  )
221
}
222

223
function calculateStartResearchTimestamp(
224
  player: PlayerType,
225
  researchQueue: string[],
226
  positionInTheQueue: number
227
): number {
NEW
228
  let startResearchTime = player.researches.activeResearch?.executeTaskAt || 0
×
229

230
  // TODO: include this in each iteration!
NEW
231
  const researchBonus = computedBonus(player.perks, 'RESEARCH_BONUS')
×
232

NEW
233
  for (let i = 0; i < positionInTheQueue; i++) {
×
NEW
234
    const playerResearch = player.researches.researched.find(
×
NEW
235
      (playerResearch) => playerResearch.research.name === researchQueue[i]
×
236
    )
NEW
237
    const raceResearch = player.race.researches.find(
×
NEW
238
      (raceResearch) => raceResearch.name === researchQueue[i]
×
239
    )
240

NEW
241
    const researchLevelInTheQueue = calculateResearchLevelInTheQueue(
×
242
      researchQueue[i],
243
      playerResearch?.level || 0,
×
244
      researchQueue,
245
      i,
246
      player.researches.activeResearch
247
    )
248

NEW
249
    const researchDuration = calculateResearchDuration(
×
250
      raceResearch!.initialTime,
251
      researchLevelInTheQueue,
252
      researchBonus
253
    )
254

NEW
255
    startResearchTime = startResearchTime + researchDuration
×
256
  }
257

NEW
258
  return startResearchTime
×
259
}
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