poi-plugin-quest-info-2 0.8.0 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/i18n/en-US.json CHANGED
@@ -21,6 +21,8 @@
21
21
  "Locked": "Locked",
22
22
  "In Progress": "In Progress {{number}}",
23
23
  "Completed": "Completed",
24
+ "Already Completed": "Already Completed",
25
+ "Unknown": "Unknown",
24
26
  "TotalQuests": "Total {{number}} quests",
25
27
  "Sync with game": "Sync with game (Show in-game quests only)",
26
28
  "Version": "Version: {{version}}",
package/i18n/ja-JP.json CHANGED
@@ -20,7 +20,9 @@
20
20
  "One-time": "単発",
21
21
  "Locked": "ロック中",
22
22
  "In Progress": "進行中 {{number}}",
23
- "Completed": "完了",
23
+ "Completed": "達成",
24
+ "Already Completed": "完了",
25
+ "Unknown": "状態不明",
24
26
  "TotalQuests": "全て {{number}} 個の任務",
25
27
  "Sync with game": "ゲームと連動(インゲームクエストのみ表示する)",
26
28
  "Version": "バージョン: {{version}}",
package/i18n/ko-KR.json CHANGED
@@ -5,7 +5,9 @@
5
5
  "All": "전체",
6
6
  "Locked": "잠김",
7
7
  "In Progress": "진행 중 {{number}}",
8
- "Completed": "완료",
8
+ "Completed": "달성",
9
+ "Already Completed": "완료",
10
+ "Unknown": "알 수 없는 상태",
9
11
  "Version": "버전: {{version}}",
10
12
  "Data Version": "데이터 버전: {{version}}",
11
13
  "View source code on GitHub": "GitHub에서 소스코드를 알아보세요",
package/i18n/zh-CN.json CHANGED
@@ -20,7 +20,9 @@
20
20
  "One-time": "单次",
21
21
  "Locked": "未解锁",
22
22
  "In Progress": "进行中 {{number}}",
23
- "Completed": "已完成",
23
+ "Completed": "达成",
24
+ "Already Completed": "已完成",
25
+ "Unknown": "状态未知",
24
26
  "TotalQuests": "一共 {{number}} 个任务",
25
27
  "Sync with game": "与游戏同步(仅展示游戏内任务)",
26
28
  "Version": "版本: {{version}}",
package/i18n/zh-TW.json CHANGED
@@ -20,7 +20,9 @@
20
20
  "One-time": "單次",
21
21
  "Locked": "未解鎖",
22
22
  "In Progress": "進行中 {{number}}",
23
- "Completed": "已完成",
23
+ "Completed": "達成",
24
+ "Already Completed": "已完成",
25
+ "Unknown": "未知狀態",
24
26
  "TotalQuests": "一共 {{number}} 個任務",
25
27
  "Sync with game": "與遊戲同步",
26
28
  "Version": "版本: {{version}}",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "poi-plugin-quest-info-2",
3
- "version": "0.8.0",
3
+ "version": "0.8.1",
4
4
  "private": false,
5
5
  "description": "show quest info",
6
6
  "homepage": "https://github.com/lawvs/poi-plugin-quest-2/",
@@ -34,6 +34,7 @@
34
34
  "update": "npm run downloadKcanotifyData && npm run downloadKcQuestsData && npm run genQuestData"
35
35
  },
36
36
  "dependencies": {
37
+ "moize": "^6.1.1",
37
38
  "react-use": "^17.3.1",
38
39
  "react-virtualized": "^9.22.3"
39
40
  },
@@ -0,0 +1,399 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`questHelper should 101 locked quests match snapshot 1`] = `
4
+ Object {
5
+ "102": true,
6
+ "103": true,
7
+ "104": true,
8
+ "105": true,
9
+ "106": true,
10
+ "107": true,
11
+ "108": true,
12
+ "109": true,
13
+ "110": true,
14
+ "1103": true,
15
+ "1104": true,
16
+ "1106": true,
17
+ "111": true,
18
+ "112": true,
19
+ "113": true,
20
+ "114": true,
21
+ "115": true,
22
+ "116": true,
23
+ "117": true,
24
+ "118": true,
25
+ "119": true,
26
+ "120": true,
27
+ "121": true,
28
+ "122": true,
29
+ "123": true,
30
+ "124": true,
31
+ "125": true,
32
+ "126": true,
33
+ "127": true,
34
+ "128": true,
35
+ "129": true,
36
+ "130": true,
37
+ "131": true,
38
+ "132": true,
39
+ "133": true,
40
+ "134": true,
41
+ "135": true,
42
+ "136": true,
43
+ "137": true,
44
+ "138": true,
45
+ "139": true,
46
+ "140": true,
47
+ "141": true,
48
+ "142": true,
49
+ "143": true,
50
+ "144": true,
51
+ "145": true,
52
+ "146": true,
53
+ "147": true,
54
+ "148": true,
55
+ "149": true,
56
+ "150": true,
57
+ "151": true,
58
+ "152": true,
59
+ "153": true,
60
+ "154": true,
61
+ "155": true,
62
+ "156": true,
63
+ "157": true,
64
+ "158": true,
65
+ "161": true,
66
+ "162": true,
67
+ "163": true,
68
+ "164": true,
69
+ "165": true,
70
+ "166": true,
71
+ "167": true,
72
+ "168": true,
73
+ "169": true,
74
+ "170": true,
75
+ "171": true,
76
+ "172": true,
77
+ "173": true,
78
+ "174": true,
79
+ "175": true,
80
+ "177": true,
81
+ "178": true,
82
+ "179": true,
83
+ "180": true,
84
+ "181": true,
85
+ "182": true,
86
+ "183": true,
87
+ "184": true,
88
+ "185": true,
89
+ "186": true,
90
+ "187": true,
91
+ "188": true,
92
+ "189": true,
93
+ "190": true,
94
+ "191": true,
95
+ "192": true,
96
+ "193": true,
97
+ "194": true,
98
+ "195": true,
99
+ "196": true,
100
+ "197": true,
101
+ "215": true,
102
+ "217": true,
103
+ "219": true,
104
+ "222": true,
105
+ "223": true,
106
+ "224": true,
107
+ "225": true,
108
+ "227": true,
109
+ "231": true,
110
+ "232": true,
111
+ "233": true,
112
+ "236": true,
113
+ "239": true,
114
+ "240": true,
115
+ "244": true,
116
+ "245": true,
117
+ "246": true,
118
+ "247": true,
119
+ "248": true,
120
+ "249": true,
121
+ "250": true,
122
+ "251": true,
123
+ "252": true,
124
+ "253": true,
125
+ "254": true,
126
+ "258": true,
127
+ "259": true,
128
+ "260": true,
129
+ "261": true,
130
+ "262": true,
131
+ "263": true,
132
+ "264": true,
133
+ "265": true,
134
+ "266": true,
135
+ "267": true,
136
+ "268": true,
137
+ "269": true,
138
+ "270": true,
139
+ "271": true,
140
+ "273": true,
141
+ "274": true,
142
+ "275": true,
143
+ "276": true,
144
+ "277": true,
145
+ "278": true,
146
+ "279": true,
147
+ "281": true,
148
+ "282": true,
149
+ "285": true,
150
+ "287": true,
151
+ "288": true,
152
+ "289": true,
153
+ "290": true,
154
+ "291": true,
155
+ "292": true,
156
+ "293": true,
157
+ "294": true,
158
+ "295": true,
159
+ "296": true,
160
+ "297": true,
161
+ "298": true,
162
+ "306": true,
163
+ "307": true,
164
+ "308": true,
165
+ "309": true,
166
+ "312": true,
167
+ "316": true,
168
+ "318": true,
169
+ "319": true,
170
+ "323": true,
171
+ "324": true,
172
+ "325": true,
173
+ "328": true,
174
+ "330": true,
175
+ "331": true,
176
+ "339": true,
177
+ "346": true,
178
+ "347": true,
179
+ "355": true,
180
+ "401": true,
181
+ "402": true,
182
+ "403": true,
183
+ "404": true,
184
+ "405": true,
185
+ "406": true,
186
+ "408": true,
187
+ "409": true,
188
+ "410": true,
189
+ "411": true,
190
+ "412": true,
191
+ "413": true,
192
+ "414": true,
193
+ "415": true,
194
+ "418": true,
195
+ "419": true,
196
+ "420": true,
197
+ "422": true,
198
+ "423": true,
199
+ "424": true,
200
+ "425": true,
201
+ "429": true,
202
+ "431": true,
203
+ "433": true,
204
+ "434": true,
205
+ "437": true,
206
+ "440": true,
207
+ "442": true,
208
+ "443": true,
209
+ "444": true,
210
+ "445": true,
211
+ "610": true,
212
+ "611": true,
213
+ "612": true,
214
+ "614": true,
215
+ "615": true,
216
+ "616": true,
217
+ "618": true,
218
+ "619": true,
219
+ "620": true,
220
+ "622": true,
221
+ "623": true,
222
+ "624": true,
223
+ "625": true,
224
+ "626": true,
225
+ "627": true,
226
+ "628": true,
227
+ "629": true,
228
+ "630": true,
229
+ "631": true,
230
+ "632": true,
231
+ "633": true,
232
+ "635": true,
233
+ "636": true,
234
+ "638": true,
235
+ "639": true,
236
+ "641": true,
237
+ "642": true,
238
+ "643": true,
239
+ "644": true,
240
+ "645": true,
241
+ "646": true,
242
+ "647": true,
243
+ "648": true,
244
+ "649": true,
245
+ "650": true,
246
+ "651": true,
247
+ "652": true,
248
+ "654": true,
249
+ "655": true,
250
+ "656": true,
251
+ "658": true,
252
+ "659": true,
253
+ "660": true,
254
+ "661": true,
255
+ "662": true,
256
+ "663": true,
257
+ "664": true,
258
+ "665": true,
259
+ "666": true,
260
+ "667": true,
261
+ "669": true,
262
+ "670": true,
263
+ "671": true,
264
+ "676": true,
265
+ "681": true,
266
+ "683": true,
267
+ "684": true,
268
+ "685": true,
269
+ "686": true,
270
+ "687": true,
271
+ "689": true,
272
+ "690": true,
273
+ "695": true,
274
+ "696": true,
275
+ "698": true,
276
+ "704": true,
277
+ "705": true,
278
+ "718": true,
279
+ "719": true,
280
+ "805": true,
281
+ "806": true,
282
+ "807": true,
283
+ "808": true,
284
+ "809": true,
285
+ "812": true,
286
+ "813": true,
287
+ "814": true,
288
+ "815": true,
289
+ "816": true,
290
+ "817": true,
291
+ "822": true,
292
+ "829": true,
293
+ "833": true,
294
+ "835": true,
295
+ "836": true,
296
+ "837": true,
297
+ "838": true,
298
+ "839": true,
299
+ "842": true,
300
+ "844": true,
301
+ "845": true,
302
+ "846": true,
303
+ "847": true,
304
+ "848": true,
305
+ "850": true,
306
+ "851": true,
307
+ "852": true,
308
+ "854": true,
309
+ "856": true,
310
+ "858": true,
311
+ "859": true,
312
+ "860": true,
313
+ "861": true,
314
+ "862": true,
315
+ "863": true,
316
+ "864": true,
317
+ "865": true,
318
+ "870": true,
319
+ "871": true,
320
+ "872": true,
321
+ "875": true,
322
+ "877": true,
323
+ "879": true,
324
+ "881": true,
325
+ "884": true,
326
+ "885": true,
327
+ "886": true,
328
+ "887": true,
329
+ "888": true,
330
+ "890": true,
331
+ "891": true,
332
+ "892": true,
333
+ "896": true,
334
+ "897": true,
335
+ "901": true,
336
+ "902": true,
337
+ "903": true,
338
+ "904": true,
339
+ "911": true,
340
+ "913": true,
341
+ "916": true,
342
+ "917": true,
343
+ "918": true,
344
+ "924": true,
345
+ "925": true,
346
+ "926": true,
347
+ "927": true,
348
+ "929": true,
349
+ "930": true,
350
+ "933": true,
351
+ "934": true,
352
+ "935": true,
353
+ "936": true,
354
+ "937": true,
355
+ "940": true,
356
+ "943": true,
357
+ "947": true,
358
+ "948": true,
359
+ "949": true,
360
+ "961": true,
361
+ "966": true,
362
+ "967": true,
363
+ "968": true,
364
+ "969": true,
365
+ }
366
+ `;
367
+
368
+ exports[`questHelper should 196 getLockedQuest correct 1`] = `
369
+ Object {
370
+ "197": true,
371
+ "346": true,
372
+ "892": true,
373
+ "930": true,
374
+ }
375
+ `;
376
+
377
+ exports[`questHelper should 236 getCompletedQuest correct 1`] = `
378
+ Object {
379
+ "101": true,
380
+ "102": true,
381
+ "103": true,
382
+ "105": true,
383
+ "106": true,
384
+ "107": true,
385
+ "113": true,
386
+ "119": true,
387
+ "121": true,
388
+ "124": true,
389
+ "125": true,
390
+ "131": true,
391
+ "133": true,
392
+ "136": true,
393
+ "152": true,
394
+ "227": true,
395
+ "235": true,
396
+ "273": true,
397
+ "307": true,
398
+ }
399
+ `;
@@ -0,0 +1,36 @@
1
+ import {
2
+ getCompletedQuest,
3
+ getLockedQuest,
4
+ getPostQuestIds,
5
+ getPreQuestIds,
6
+ } from '../questHelper'
7
+
8
+ describe('questHelper', () => {
9
+ test('should getPreQuestIds correct', () => {
10
+ expect(getPreQuestIds(101)).toEqual([])
11
+ expect(getPreQuestIds(102)).toEqual([101])
12
+ expect(getPreQuestIds(236)).toEqual([235, 273])
13
+ })
14
+
15
+ test('should getPostQuestIds correct', () => {
16
+ expect(getPostQuestIds(101)).toEqual([102])
17
+ expect(getPostQuestIds(105)).toEqual([106, 108, 254, 401, 612, 816])
18
+ expect(getPostQuestIds(140)).toEqual([])
19
+ })
20
+
21
+ test('should 101 no completed quest', () => {
22
+ expect(getCompletedQuest([101])).toEqual({})
23
+ })
24
+
25
+ test('should 236 getCompletedQuest correct', () => {
26
+ expect(getCompletedQuest([236])).toMatchSnapshot()
27
+ })
28
+
29
+ test('should 101 locked quests match snapshot', () => {
30
+ expect(getLockedQuest([101])).toMatchSnapshot()
31
+ })
32
+
33
+ test('should 196 getLockedQuest correct', () => {
34
+ expect(getLockedQuest([196])).toMatchSnapshot()
35
+ })
36
+ })
@@ -1,4 +1,4 @@
1
- import { Card, Elevation, H5, Text } from '@blueprintjs/core'
1
+ import { Card, Elevation, H5 } from '@blueprintjs/core'
2
2
  import React, { forwardRef } from 'react'
3
3
  import type { StyledComponentProps } from 'styled-components'
4
4
  import { usePluginTranslation } from '../../poi/hooks'
@@ -7,6 +7,7 @@ import {
7
7
  guessQuestCategory,
8
8
  QUEST_STATUS,
9
9
  } from '../../questHelper'
10
+ import { useQuestStatus } from '../../store/quest'
10
11
  import { QuestTag } from '../QuestTag'
11
12
  import {
12
13
  CardActionWrapper,
@@ -18,6 +19,7 @@ import {
18
19
  TagsWrapper,
19
20
  } from './styles'
20
21
  import { questIconMap, questStatusMap } from './utils'
22
+ import { IN_POI } from '../../poi/env'
21
23
 
22
24
  export type QuestCardProps = {
23
25
  gameId: number
@@ -66,44 +68,30 @@ export const QuestCard = forwardRef<
66
68
  Card,
67
69
  // eslint-disable-next-line @typescript-eslint/ban-types
68
70
  QuestCardProps & StyledComponentProps<typeof Card, any, {}, never>
69
- >(
70
- (
71
- {
72
- gameId,
73
- code,
74
- name,
75
- desc,
76
- tip,
77
- tip2,
78
- status = QUEST_STATUS.DEFAULT,
79
- ...props
80
- },
81
- ref
82
- ) => {
83
- const headIcon = questIconMap[guessQuestCategory(code).type]
84
- const TailIcon = questStatusMap[status]
71
+ >(({ gameId, code, name, desc, tip, tip2, ...props }, ref) => {
72
+ const status = useQuestStatus(gameId)
73
+ const headIcon = questIconMap[guessQuestCategory(code).type]
74
+ const TailIcon = questStatusMap[status]
75
+ const inPoi = IN_POI
85
76
 
86
- return (
87
- <FlexCard
88
- ref={ref}
89
- elevation={Elevation.ZERO}
90
- interactive={false}
91
- {...props}
92
- >
93
- <CardMedia src={headIcon}></CardMedia>
94
- <CardBody>
95
- <H5>{[code, name].filter((i) => i != undefined).join(' - ')}</H5>
96
- <Text>{desc}</Text>
97
- {tip2 && <b>{tip2}</b>}
98
- {tip && <i>{tip}</i>}
77
+ return (
78
+ <FlexCard
79
+ ref={ref}
80
+ elevation={Elevation.ZERO}
81
+ interactive={false}
82
+ {...props}
83
+ >
84
+ <CardMedia src={headIcon}></CardMedia>
85
+ <CardBody>
86
+ <H5>{[code, name].filter((i) => i != undefined).join(' - ')}</H5>
87
+ <div>{desc}</div>
88
+ {tip2 && <b>{tip2}</b>}
89
+ {tip && <i>{tip}</i>}
99
90
 
100
- <CardAction gameId={gameId}></CardAction>
101
- </CardBody>
91
+ <CardAction gameId={gameId}></CardAction>
92
+ </CardBody>
102
93
 
103
- <CardTail>
104
- <TailIcon />
105
- </CardTail>
106
- </FlexCard>
107
- )
108
- }
109
- )
94
+ <CardTail>{inPoi && <TailIcon />}</CardTail>
95
+ </FlexCard>
96
+ )
97
+ })
@@ -50,6 +50,14 @@ export const questStatusMap: Record<QUEST_STATUS, React.FC> = {
50
50
  </Tooltip>
51
51
  )
52
52
  },
53
+ [QUEST_STATUS.UNKNOWN]: function AlreadyCompleted() {
54
+ const { t } = usePluginTranslation()
55
+ return (
56
+ <Tooltip content={t('Unknown')}>
57
+ <Icon icon={IconNames.HELP} iconSize={Icon.SIZE_LARGE}></Icon>
58
+ </Tooltip>
59
+ )
60
+ },
53
61
  }
54
62
 
55
63
  // transparent GIF pixel
@@ -1,4 +1,5 @@
1
- import React, { useRef, useEffect, useCallback } from 'react'
1
+ import React, { useCallback, useEffect, useRef } from 'react'
2
+ import type { ListRowProps } from 'react-virtualized'
2
3
  // See https://github.com/bvaughn/react-virtualized
3
4
  import {
4
5
  AutoSizer,
@@ -7,13 +8,10 @@ import {
7
8
  List,
8
9
  ListRowRenderer,
9
10
  } from 'react-virtualized'
10
- import type { ListRowProps } from 'react-virtualized'
11
11
  import styled from 'styled-components'
12
- import { QUEST_STATUS } from '../questHelper'
12
+ import { useIsQuestPluginTab } from '../poi/hooks'
13
13
  import type { UnionQuest } from '../questHelper'
14
14
  import { QuestCard } from './QuestCard'
15
- import { useIsQuestPluginTab } from '../poi/hooks'
16
- import { QUEST_API_STATE } from '../poi/types'
17
15
 
18
16
  const QuestListWrapper = styled.div`
19
17
  flex: 1;
@@ -26,28 +24,12 @@ const cache = new CellMeasurerCache({
26
24
  fixedWidth: true,
27
25
  })
28
26
 
29
- const questApiStateToQuestStatus = (
30
- state: QUEST_API_STATE | undefined
31
- ): QUEST_STATUS => {
32
- switch (state) {
33
- case QUEST_API_STATE.DEFAULT:
34
- return QUEST_STATUS.DEFAULT
35
- case QUEST_API_STATE.COMPLETED:
36
- return QUEST_STATUS.COMPLETED
37
- case QUEST_API_STATE.IN_PROGRESS:
38
- return QUEST_STATUS.IN_PROGRESS
39
- default:
40
- return QUEST_STATUS.DEFAULT
41
- }
42
- }
43
-
44
27
  const useQuestsRowRenderer = (quests: UnionQuest[]) => {
45
28
  const rowRenderer = useCallback(
46
29
  ({ key, index, style, parent }: ListRowProps) => {
47
30
  const quest = quests[index]
48
31
  const { gameId } = quest
49
32
  const { code, name, desc, memo, memo2, pre } = quest.docQuest
50
- const questStatus = questApiStateToQuestStatus(quest.gameQuest?.api_state)
51
33
 
52
34
  return (
53
35
  <CellMeasurer
@@ -67,7 +49,6 @@ const useQuestsRowRenderer = (quests: UnionQuest[]) => {
67
49
  tip={memo}
68
50
  tip2={memo2}
69
51
  preQuest={pre}
70
- status={questStatus}
71
52
  ></QuestCard>
72
53
  </div>
73
54
  </CellMeasurer>
@@ -78,7 +59,7 @@ const useQuestsRowRenderer = (quests: UnionQuest[]) => {
78
59
  return rowRenderer
79
60
  }
80
61
 
81
- export const QuestList: React.FC<{ quests: UnionQuest[] }> = ({ quests }) => {
62
+ export const QuestList = ({ quests }: { quests: UnionQuest[] }) => {
82
63
  const activeTab = useIsQuestPluginTab()
83
64
  const listRef = useRef<List>(null)
84
65
  const rowRenderer: ListRowRenderer = useQuestsRowRenderer(quests)
package/src/poi/hooks.ts CHANGED
@@ -1,9 +1,8 @@
1
- import { useState, useEffect } from 'react'
1
+ import { useEffect, useState } from 'react'
2
2
  import { useTranslation } from 'react-i18next'
3
- import { observePluginStore, observePoiStore } from './store'
4
3
  import { name as PACKAGE_NAME } from '../../package.json'
4
+ import { observePluginStore, observePoiStore } from './store'
5
5
  import { GameQuest, PoiQuestState, PoiState, QuestTab } from './types'
6
- import { createGlobalState } from 'react-use'
7
6
 
8
7
  export const activeQuestsSelector = (state: PoiState): PoiQuestState =>
9
8
  state?.info?.quests?.activeQuests ?? {}
@@ -25,10 +24,8 @@ export const usePluginTranslation = () => {
25
24
  return useTranslation(PACKAGE_NAME)
26
25
  }
27
26
 
28
- const useGlobalGameQuest = createGlobalState<GameQuest[]>([])
29
-
30
27
  export const useGameQuest = () => {
31
- const [quests, setQuests] = useGlobalGameQuest()
28
+ const [quests, setQuests] = useState<GameQuest[]>([])
32
29
  useEffect(() => {
33
30
  const listener = (quests: GameQuest[] | null) => setQuests(quests ?? [])
34
31
  // See reducer.ts
@@ -1,3 +1,4 @@
1
+ import moize from 'moize'
1
2
  import { QuestData } from '../build/kcanotifyGamedata'
2
3
  import { KcwikiQuestData } from '../build/kcQuestsData'
3
4
  import newQuestData from '../build/kcQuestsData/quests-scn-new.json'
@@ -217,10 +218,66 @@ export const getQuestIdByCode = (code: string) => {
217
218
  return null
218
219
  }
219
220
 
221
+ export const getPreQuestIds = (gameId: number): number[] =>
222
+ getQuestPrePost(gameId)
223
+ .pre.map((code) => getQuestIdByCode(code))
224
+ .filter(Boolean) as number[]
225
+
226
+ export const getPostQuestIds = (gameId: number): number[] =>
227
+ getQuestPrePost(gameId)
228
+ .post.map((code) => getQuestIdByCode(code))
229
+ .filter(Boolean) as number[]
230
+
231
+ const calcQuestMap = (
232
+ inProgressQuests: number[],
233
+ next: (gameId: number) => number[]
234
+ ) => {
235
+ const map: Record<number, true> = {}
236
+ const queue: number[] = inProgressQuests.flatMap(next)
237
+ while (queue.length) {
238
+ const gameId = queue.shift()!
239
+ if (gameId in map) {
240
+ continue
241
+ }
242
+ map[gameId] = true
243
+
244
+ next(gameId).forEach((nextGameId) => {
245
+ queue.push(nextGameId)
246
+ })
247
+ }
248
+ return map
249
+ }
250
+
251
+ export const getCompletedQuest = moize((inProgressQuest: number[]) => {
252
+ const completedQuest = calcQuestMap(inProgressQuest, getPreQuestIds)
253
+ return completedQuest
254
+ })
255
+
256
+ export const getLockedQuest = moize((inProgressQuest: number[]) => {
257
+ const lockedQuest = calcQuestMap(inProgressQuest, getPostQuestIds)
258
+ return lockedQuest
259
+ })
260
+
261
+ export const questApiStateToQuestStatus = (
262
+ state: QUEST_API_STATE | undefined
263
+ ): QUEST_STATUS => {
264
+ switch (state) {
265
+ case QUEST_API_STATE.DEFAULT:
266
+ return QUEST_STATUS.DEFAULT
267
+ case QUEST_API_STATE.COMPLETED:
268
+ return QUEST_STATUS.COMPLETED
269
+ case QUEST_API_STATE.IN_PROGRESS:
270
+ return QUEST_STATUS.IN_PROGRESS
271
+ default:
272
+ return QUEST_STATUS.DEFAULT
273
+ }
274
+ }
275
+
220
276
  export enum QUEST_STATUS {
221
277
  LOCKED,
222
278
  DEFAULT,
223
279
  IN_PROGRESS,
224
280
  COMPLETED,
225
281
  ALREADY_COMPLETED,
282
+ UNKNOWN,
226
283
  }
@@ -3,13 +3,15 @@ import { useGameQuest, usePluginTranslation } from '../poi/hooks'
3
3
  import {
4
4
  DocQuest,
5
5
  getCategory,
6
+ getCompletedQuest,
6
7
  getKcanotifyQuestData,
8
+ getLockedQuest,
7
9
  getQuestIdByCode,
8
- getQuestPrePost,
10
+ questApiStateToQuestStatus,
9
11
  QUEST_STATUS,
12
+ UnionQuest,
10
13
  } from '../questHelper'
11
- import type { UnionQuest } from '../questHelper'
12
- import { useKcwikiData, checkIsKcwikiSupportedLanguages } from './kcwiki'
14
+ import { checkIsKcwikiSupportedLanguages, useKcwikiData } from './kcwiki'
13
15
  import { useStore, useSyncWithGame } from './store'
14
16
 
15
17
  const DEFAULT_LANG = 'ja-JP'
@@ -98,63 +100,26 @@ export const useQuestByCode = (code: string): UnionQuest | null => {
98
100
  return null
99
101
  }
100
102
 
101
- const useCompletedQuest = () => {
102
- const completedQuest: Record<number, true> = {}
103
- const gameQuest = useGameQuest()
104
- const queue: number[] = gameQuest.map((quest) => quest.api_no)
105
- while (queue.length) {
106
- const gameId = queue.shift()!
107
- if (gameId in completedQuest) {
108
- continue
109
- }
110
- completedQuest[gameId] = true
111
-
112
- const prePostQuests = getQuestPrePost(gameId)
113
- prePostQuests.pre.forEach((nextCode) => {
114
- const nextGameId = getQuestIdByCode(nextCode)
115
- if (nextGameId) {
116
- queue.push(nextGameId)
117
- }
118
- })
119
- }
120
- return completedQuest
121
- }
122
-
123
- const useLockedQuest = () => {
124
- const lockedQuest: Record<number, true> = {}
125
- const gameQuest = useGameQuest()
126
- const queue: number[] = gameQuest.map((quest) => quest.api_no)
127
- while (queue.length) {
128
- const gameId = queue.shift()!
129
- if (gameId in lockedQuest) {
130
- continue
131
- }
132
- lockedQuest[gameId] = true
133
- const prePostQuests = getQuestPrePost(gameId)
134
- prePostQuests.post.forEach((nextCode) => {
135
- const nextGameId = getQuestIdByCode(nextCode)
136
- if (nextGameId) {
137
- queue.push(nextGameId)
138
- }
139
- })
140
- }
141
- return lockedQuest
142
- }
143
-
144
103
  export const useQuestStatus = (gameId: number | null) => {
145
- const completedQuest = useCompletedQuest()
146
- const lockedQuest = useLockedQuest()
104
+ const gameQuest = useGameQuest()
105
+ const gameQuestId = gameQuest.map((quest) => quest.api_no)
106
+ const completedQuest = getCompletedQuest(gameQuestId)
107
+ const lockedQuest = getLockedQuest(gameQuestId)
147
108
 
148
109
  if (!gameId) {
149
- return QUEST_STATUS.DEFAULT
110
+ return QUEST_STATUS.UNKNOWN
150
111
  }
151
- if (gameId in completedQuest) {
152
- return QUEST_STATUS.ALREADY_COMPLETED
112
+ const theGameQuest = gameQuest.find((quest) => quest.api_no === gameId)
113
+ if (theGameQuest) {
114
+ return questApiStateToQuestStatus(theGameQuest.api_state)
153
115
  }
154
116
  if (gameId in lockedQuest) {
155
117
  return QUEST_STATUS.LOCKED
156
118
  }
157
- return QUEST_STATUS.DEFAULT
119
+ if (gameId in completedQuest) {
120
+ return QUEST_STATUS.ALREADY_COMPLETED
121
+ }
122
+ return QUEST_STATUS.UNKNOWN
158
123
  }
159
124
 
160
125
  /**
package/tsconfig.json CHANGED
@@ -44,7 +44,7 @@
44
44
  // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
45
45
  // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
46
46
  // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
47
- "importsNotUsedAsValues": "error",
47
+ // "importsNotUsedAsValues": "error",
48
48
 
49
49
  /* Module Resolution Options */
50
50
  // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
@@ -72,5 +72,6 @@
72
72
  /* Advanced Options */
73
73
  "skipLibCheck": true /* Skip type checking of declaration files. */,
74
74
  "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
75
- }
75
+ },
76
+ "exclude": ["./node_modules/**/*"]
76
77
  }