poi-plugin-quest-info-2 0.6.7 → 0.7.2
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/README.md +2 -0
- package/build/kcQuestsData/DATA_VERSION +1 -1
- package/build/kcQuestsData/index.ts +1 -1
- package/build/kcQuestsData/quests-scn.json +10 -0
- package/i18n/en-US.json +3 -3
- package/i18n/ja-JP.json +3 -3
- package/i18n/ko-KR.json +1 -1
- package/i18n/zh-CN.json +3 -3
- package/i18n/zh-TW.json +3 -3
- package/package.json +1 -1
- package/src/App.tsx +1 -1
- package/src/Toolbar.tsx +32 -81
- package/src/__tests__/kcwikiData.spec.ts +1 -1
- package/src/poi/hooks.ts +10 -1
- package/src/poi/types.ts +11 -8
- package/src/questHelper.ts +3 -3
- package/src/reducer.ts +4 -2
- package/src/store/filterTags.ts +49 -1
- package/src/store/quest.ts +2 -4
- package/src/tags.tsx +172 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -14
- package/.github/ISSUE_TEMPLATE/feature_request.md +0 -12
- package/.github/workflows/build.yml +0 -51
- package/.github/workflows/publish.yml +0 -45
- package/.vscode/extensions.json +0 -6
- package/.vscode/settings.json +0 -11
- package/src/tags.ts +0 -66
package/README.md
CHANGED
|
@@ -9,6 +9,8 @@ A [poi](https://github.com/poooi/poi) plugin that helps you view quest info. Dat
|
|
|
9
9
|
|
|
10
10
|
## Installation
|
|
11
11
|
|
|
12
|
+
Paste `poi-plugin-quest-info-2` in the plugins tab and click the install button.
|
|
13
|
+
|
|
12
14
|

|
|
13
15
|
|
|
14
16
|
## Features
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
2b2c2222f933ff9863dec8c72fc6037fbfe375ac
|
|
@@ -1352,6 +1352,16 @@
|
|
|
1352
1352
|
]
|
|
1353
1353
|
},
|
|
1354
1354
|
"239": {
|
|
1355
|
+
"code": "B20",
|
|
1356
|
+
"desc": "派出包含「第八驱逐队」的舰队出击,消灭 2-3 的敌人!",
|
|
1357
|
+
"memo": "奖励:开发资材 *1 家具箱 (中) *1",
|
|
1358
|
+
"memo2": "使用朝潮 / 满潮 / 荒潮 / 大潮出击,击破 BOSS,B 胜及以上可以携带其他舰娘",
|
|
1359
|
+
"name": "「第八驱逐队」出击!",
|
|
1360
|
+
"pre": [
|
|
1361
|
+
"A31"
|
|
1362
|
+
]
|
|
1363
|
+
},
|
|
1364
|
+
"240": {
|
|
1355
1365
|
"code": "B21",
|
|
1356
1366
|
"desc": "派出包含「第十八驱逐队」的舰队出击,消灭 3-1 的敌人!",
|
|
1357
1367
|
"memo": "奖励:开发资材 *2 家具箱 (大) *1",
|
package/i18n/en-US.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"Arsenal": "Arsenal",
|
|
12
12
|
"Modernization": "Modernization",
|
|
13
13
|
"Others": "Others",
|
|
14
|
-
"New": "New",
|
|
14
|
+
"New": "New {{number}}",
|
|
15
15
|
"Daily": "Daily",
|
|
16
16
|
"Weekly": "Weekly",
|
|
17
17
|
"Monthly": "Monthly",
|
|
@@ -19,9 +19,9 @@
|
|
|
19
19
|
"Yearly": "Yearly",
|
|
20
20
|
"One-time": "One-time",
|
|
21
21
|
"Locked": "Locked",
|
|
22
|
-
"In Progress": "In Progress",
|
|
22
|
+
"In Progress": "In Progress {{number}}",
|
|
23
23
|
"Completed": "Completed",
|
|
24
|
-
"TotalQuests": "Total {{
|
|
24
|
+
"TotalQuests": "Total {{number}} quests",
|
|
25
25
|
"Sync with game": "Sync with game (Show in-game quests only)",
|
|
26
26
|
"Version": "Version: {{version}}",
|
|
27
27
|
"Data Version": "Data Version: {{version}}",
|
package/i18n/ja-JP.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"Arsenal": "工廠",
|
|
12
12
|
"Modernization": "改装",
|
|
13
13
|
"Others": "その他",
|
|
14
|
-
"New": "最新任務",
|
|
14
|
+
"New": "最新任務 {{number}}",
|
|
15
15
|
"Daily": "デイリー",
|
|
16
16
|
"Weekly": "ウィークリー",
|
|
17
17
|
"Monthly": "マンスリー",
|
|
@@ -19,9 +19,9 @@
|
|
|
19
19
|
"Yearly": "イヤーリー",
|
|
20
20
|
"One-time": "単発",
|
|
21
21
|
"Locked": "ロック中",
|
|
22
|
-
"In Progress": "進行中",
|
|
22
|
+
"In Progress": "進行中 {{number}}",
|
|
23
23
|
"Completed": "完了",
|
|
24
|
-
"TotalQuests": "全て {{
|
|
24
|
+
"TotalQuests": "全て {{number}} 個の任務",
|
|
25
25
|
"Sync with game": "ゲームと連動(インゲームクエストのみ表示する)",
|
|
26
26
|
"Version": "バージョン: {{version}}",
|
|
27
27
|
"Data Version": "データ バージョン: {{version}}",
|
package/i18n/ko-KR.json
CHANGED
package/i18n/zh-CN.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"Arsenal": "工厂",
|
|
12
12
|
"Modernization": "改装",
|
|
13
13
|
"Others": "其他",
|
|
14
|
-
"New": "新任务",
|
|
14
|
+
"New": "新任务 {{number}}",
|
|
15
15
|
"Daily": "日常",
|
|
16
16
|
"Weekly": "周常",
|
|
17
17
|
"Monthly": "月常",
|
|
@@ -19,9 +19,9 @@
|
|
|
19
19
|
"Yearly": "年常",
|
|
20
20
|
"One-time": "单次",
|
|
21
21
|
"Locked": "未解锁",
|
|
22
|
-
"In Progress": "进行中",
|
|
22
|
+
"In Progress": "进行中 {{number}}",
|
|
23
23
|
"Completed": "已完成",
|
|
24
|
-
"TotalQuests": "一共 {{
|
|
24
|
+
"TotalQuests": "一共 {{number}} 个任务",
|
|
25
25
|
"Sync with game": "与游戏同步(仅展示游戏内任务)",
|
|
26
26
|
"Version": "版本: {{version}}",
|
|
27
27
|
"Data Version": "数据版本: {{version}}",
|
package/i18n/zh-TW.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"Arsenal": "工廠",
|
|
12
12
|
"Modernization": "改装",
|
|
13
13
|
"Others": "其他",
|
|
14
|
-
"New": "新任務",
|
|
14
|
+
"New": "新任務 {{number}}",
|
|
15
15
|
"Daily": "每日",
|
|
16
16
|
"Weekly": "每週",
|
|
17
17
|
"Monthly": "每月",
|
|
@@ -19,9 +19,9 @@
|
|
|
19
19
|
"Yearly": "每年",
|
|
20
20
|
"One-time": "單次",
|
|
21
21
|
"Locked": "未解鎖",
|
|
22
|
-
"In Progress": "進行中",
|
|
22
|
+
"In Progress": "進行中 {{number}}",
|
|
23
23
|
"Completed": "已完成",
|
|
24
|
-
"TotalQuests": "一共 {{
|
|
24
|
+
"TotalQuests": "一共 {{number}} 個任務",
|
|
25
25
|
"Sync with game": "與遊戲同步",
|
|
26
26
|
"Version": "版本: {{version}}",
|
|
27
27
|
"Data Version": "資料版本: {{version}}",
|
package/package.json
CHANGED
package/src/App.tsx
CHANGED
|
@@ -31,7 +31,7 @@ const Main: React.FC = () => {
|
|
|
31
31
|
return (
|
|
32
32
|
<>
|
|
33
33
|
<Toolbar></Toolbar>
|
|
34
|
-
<CountText>{t('TotalQuests', {
|
|
34
|
+
<CountText>{t('TotalQuests', { number: quests.length })}</CountText>
|
|
35
35
|
<QuestList quests={quests}></QuestList>
|
|
36
36
|
</>
|
|
37
37
|
)
|
package/src/Toolbar.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Button, InputGroup, Intent,
|
|
1
|
+
import { Button, InputGroup, Intent, Tooltip } from '@blueprintjs/core'
|
|
2
2
|
import { IconNames } from '@blueprintjs/icons'
|
|
3
3
|
import type { ChangeEvent } from 'react'
|
|
4
4
|
import React, { useCallback } from 'react'
|
|
@@ -8,15 +8,9 @@ import { IN_POI } from './poi/env'
|
|
|
8
8
|
import { usePluginTranslation } from './poi/hooks'
|
|
9
9
|
import type { UnionQuest } from './questHelper'
|
|
10
10
|
import { useQuest, useSyncWithGame } from './store'
|
|
11
|
-
import { useFilterTags } from './store/filterTags'
|
|
11
|
+
import { useFilterTags, useSyncGameTagEffect } from './store/filterTags'
|
|
12
12
|
import { useSearchInput } from './store/search'
|
|
13
|
-
import {
|
|
14
|
-
ALL_CATEGORY_TAG,
|
|
15
|
-
ALL_TAGS,
|
|
16
|
-
ALL_TYPE_TAG,
|
|
17
|
-
CATEGORY_TAGS,
|
|
18
|
-
TYPE_TAGS,
|
|
19
|
-
} from './tags'
|
|
13
|
+
import { CategoryTags, CATEGORY_TAGS, TypeTags, TYPE_TAGS } from './tags'
|
|
20
14
|
|
|
21
15
|
const ToolbarWrapper = styled.div`
|
|
22
16
|
display: flex;
|
|
@@ -28,15 +22,6 @@ const ToolbarWrapper = styled.div`
|
|
|
28
22
|
}
|
|
29
23
|
`
|
|
30
24
|
|
|
31
|
-
const TagsWrapper = styled.div`
|
|
32
|
-
margin-left: -4px;
|
|
33
|
-
margin-right: -4px;
|
|
34
|
-
|
|
35
|
-
& > * {
|
|
36
|
-
margin: 4px;
|
|
37
|
-
}
|
|
38
|
-
`
|
|
39
|
-
|
|
40
25
|
const SyncButton = () => {
|
|
41
26
|
const { t } = usePluginTranslation()
|
|
42
27
|
const { searchInput } = useSearchInput()
|
|
@@ -92,72 +77,20 @@ export const SearchInput: React.FC = () => {
|
|
|
92
77
|
)
|
|
93
78
|
}
|
|
94
79
|
|
|
95
|
-
const Tags = () => {
|
|
96
|
-
const { t } = usePluginTranslation()
|
|
97
|
-
|
|
98
|
-
const { typeTags, categoryTags, setCategoryTags, setTypeTags } =
|
|
99
|
-
useFilterTags()
|
|
100
|
-
|
|
101
|
-
return (
|
|
102
|
-
<>
|
|
103
|
-
<TagsWrapper>
|
|
104
|
-
{CATEGORY_TAGS.map(({ name }) => (
|
|
105
|
-
<Tag
|
|
106
|
-
onClick={() => setCategoryTags(name)}
|
|
107
|
-
intent={
|
|
108
|
-
categoryTags[name]
|
|
109
|
-
? name === ALL_CATEGORY_TAG.name
|
|
110
|
-
? 'success'
|
|
111
|
-
: 'primary'
|
|
112
|
-
: 'none'
|
|
113
|
-
}
|
|
114
|
-
interactive={true}
|
|
115
|
-
key={name}
|
|
116
|
-
>
|
|
117
|
-
{t(name)}
|
|
118
|
-
</Tag>
|
|
119
|
-
))}
|
|
120
|
-
</TagsWrapper>
|
|
121
|
-
<TagsWrapper>
|
|
122
|
-
{TYPE_TAGS.map((tag) => (
|
|
123
|
-
<Tag
|
|
124
|
-
onClick={() => setTypeTags(tag.name)}
|
|
125
|
-
intent={
|
|
126
|
-
typeTags[tag.name]
|
|
127
|
-
? tag.name === ALL_TYPE_TAG.name
|
|
128
|
-
? 'success'
|
|
129
|
-
: 'primary'
|
|
130
|
-
: 'none'
|
|
131
|
-
}
|
|
132
|
-
interactive={true}
|
|
133
|
-
key={tag.name}
|
|
134
|
-
>
|
|
135
|
-
{t(tag.name)}
|
|
136
|
-
{'suffix' in tag && ' ' + tag.suffix}
|
|
137
|
-
</Tag>
|
|
138
|
-
))}
|
|
139
|
-
</TagsWrapper>
|
|
140
|
-
</>
|
|
141
|
-
)
|
|
142
|
-
}
|
|
143
|
-
|
|
144
80
|
export const Toolbar = () => {
|
|
81
|
+
useSyncGameTagEffect()
|
|
82
|
+
|
|
145
83
|
return (
|
|
146
84
|
<ToolbarWrapper>
|
|
147
85
|
<SearchInput></SearchInput>
|
|
148
|
-
<
|
|
86
|
+
<CategoryTags />
|
|
87
|
+
<TypeTags />
|
|
149
88
|
</ToolbarWrapper>
|
|
150
89
|
)
|
|
151
90
|
}
|
|
152
91
|
|
|
153
|
-
const
|
|
92
|
+
const useInputStringFilter = () => {
|
|
154
93
|
const { searchInput } = useSearchInput()
|
|
155
|
-
const { typeTags, categoryTags } = useFilterTags()
|
|
156
|
-
|
|
157
|
-
const activatedTags = { ...typeTags, ...categoryTags }
|
|
158
|
-
const activatedTagsName = ALL_TAGS.filter((tag) => activatedTags[tag.name])
|
|
159
|
-
const tagsFilter = activatedTagsName.map((tag) => tag.filter)
|
|
160
|
-
|
|
161
94
|
const throttledSearchInput = useThrottle(searchInput)
|
|
162
95
|
const searchKeywords = throttledSearchInput
|
|
163
96
|
.split(' ')
|
|
@@ -179,14 +112,32 @@ const useToolbarFilter = () => {
|
|
|
179
112
|
},
|
|
180
113
|
[searchKeywords]
|
|
181
114
|
)
|
|
115
|
+
return stringFilter
|
|
116
|
+
}
|
|
182
117
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
[stringFilter, tagsFilter]
|
|
188
|
-
)
|
|
118
|
+
const And =
|
|
119
|
+
<T extends (...args: any[]) => boolean>(...fnArray: T[]) =>
|
|
120
|
+
(...args: Parameters<T>) =>
|
|
121
|
+
fnArray.every((fn) => fn(...args))
|
|
189
122
|
|
|
123
|
+
const Or =
|
|
124
|
+
<T extends (...args: any[]) => boolean>(...fnArray: T[]) =>
|
|
125
|
+
(...args: Parameters<T>) =>
|
|
126
|
+
fnArray.some((fn) => fn(...args))
|
|
127
|
+
|
|
128
|
+
const useToolbarFilter = () => {
|
|
129
|
+
const stringFilter = useInputStringFilter()
|
|
130
|
+
const { typeTags, categoryTags } = useFilterTags()
|
|
131
|
+
|
|
132
|
+
const typeTagsFilter = Or(
|
|
133
|
+
...TYPE_TAGS.filter((tag) => typeTags[tag.name]).map((tag) => tag.filter)
|
|
134
|
+
)
|
|
135
|
+
const categoryTagsFilter = Or(
|
|
136
|
+
...CATEGORY_TAGS.filter((tag) => categoryTags[tag.name]).map(
|
|
137
|
+
(tag) => tag.filter
|
|
138
|
+
)
|
|
139
|
+
)
|
|
140
|
+
const toolbarFilter = And(stringFilter, typeTagsFilter, categoryTagsFilter)
|
|
190
141
|
return toolbarFilter
|
|
191
142
|
}
|
|
192
143
|
|
|
@@ -3,7 +3,7 @@ import { version, KcwikiQuestData } from '../../build/kcQuestsData'
|
|
|
3
3
|
describe('should version correct', () => {
|
|
4
4
|
test('should KcwikiQuestData Game data version correct', () => {
|
|
5
5
|
expect(version).toMatchInlineSnapshot(
|
|
6
|
-
`"
|
|
6
|
+
`"2b2c2222f933ff9863dec8c72fc6037fbfe375ac"`
|
|
7
7
|
)
|
|
8
8
|
})
|
|
9
9
|
|
package/src/poi/hooks.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { useState, useEffect } from 'react'
|
|
|
2
2
|
import { useTranslation } from 'react-i18next'
|
|
3
3
|
import { observePluginStore, observePoiStore } from './store'
|
|
4
4
|
import { name as PACKAGE_NAME } from '../../package.json'
|
|
5
|
-
import
|
|
5
|
+
import { GameQuest, PoiQuestState, PoiState, QuestTab } from './types'
|
|
6
6
|
|
|
7
7
|
export const useActiveQuest = () => {
|
|
8
8
|
const [activeQuests, setActiveQuests] = useState<PoiQuestState>({})
|
|
@@ -34,6 +34,15 @@ export const useGameQuest = () => {
|
|
|
34
34
|
return quests
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
export const useGameTab = () => {
|
|
38
|
+
const [tab, setTab] = useState<QuestTab>(QuestTab.ALL)
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
const listener = (tabId: QuestTab | null) => setTab(tabId ?? QuestTab.ALL)
|
|
41
|
+
return observePluginStore(listener, (i) => i?._?.tabId)
|
|
42
|
+
}, [])
|
|
43
|
+
return tab
|
|
44
|
+
}
|
|
45
|
+
|
|
37
46
|
const UNKNOWN_TAB = 'unknown'
|
|
38
47
|
const useActiveTab = () => {
|
|
39
48
|
const [activeMainTab, setActiveMainTab] = useState<string>(UNKNOWN_TAB)
|
package/src/poi/types.ts
CHANGED
|
@@ -60,19 +60,22 @@ export type GameQuest = {
|
|
|
60
60
|
api_bonus_flag: 1
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
+
export enum QuestTab {
|
|
64
|
+
ALL = '0',
|
|
65
|
+
IN_PROGRESS = '9',
|
|
66
|
+
DAILY = '1',
|
|
67
|
+
WEEKLY = '2',
|
|
68
|
+
MONTHLY = '3',
|
|
69
|
+
ONCE = '4',
|
|
70
|
+
OTHERS = '5',
|
|
71
|
+
}
|
|
72
|
+
|
|
63
73
|
type QuestListAction = {
|
|
64
74
|
type: '@@Response/kcsapi/api_get_member/questlist'
|
|
65
75
|
path: '/kcsapi/api_get_member/questlist'
|
|
66
76
|
postBody: {
|
|
67
77
|
api_verno: '1'
|
|
68
|
-
api_tab_id:
|
|
69
|
-
| '0' // All
|
|
70
|
-
| '9' // In progress
|
|
71
|
-
| '1' // Daily
|
|
72
|
-
| '2' // Weekly
|
|
73
|
-
| '3' // Monthly
|
|
74
|
-
| '4' // Once
|
|
75
|
-
| '5' // Others
|
|
78
|
+
api_tab_id: QuestTab
|
|
76
79
|
}
|
|
77
80
|
body: {
|
|
78
81
|
api_completed_kind: number
|
package/src/questHelper.ts
CHANGED
|
@@ -42,9 +42,9 @@ const yearlyQuest = new Set(questCategory.yearlyQuest)
|
|
|
42
42
|
const singleQuest = new Set(questCategory.singleQuest)
|
|
43
43
|
const newQuest = new Set(newQuestData)
|
|
44
44
|
|
|
45
|
-
export const isInProgressQuest = (quest:
|
|
46
|
-
quest.
|
|
47
|
-
quest.
|
|
45
|
+
export const isInProgressQuest = (quest: GameQuest) =>
|
|
46
|
+
quest.api_state === QUEST_API_STATE.IN_PROGRESS ||
|
|
47
|
+
quest.api_state === QUEST_API_STATE.COMPLETED
|
|
48
48
|
|
|
49
49
|
export const isDailyQuest = (quest: UnionQuest) => dailyQuest.has(quest.gameId)
|
|
50
50
|
export const isWeeklyQuest = (quest: UnionQuest) =>
|
package/src/reducer.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { GameQuest, PoiAction, QuestTab } from './poi/types'
|
|
2
2
|
|
|
3
3
|
const initState = {
|
|
4
4
|
questList: null as null | GameQuest[],
|
|
5
|
+
tabId: QuestTab.ALL,
|
|
5
6
|
}
|
|
6
7
|
|
|
7
8
|
export type PluginState = { _: typeof initState }
|
|
@@ -12,11 +13,12 @@ export const reducer = (
|
|
|
12
13
|
): typeof initState => {
|
|
13
14
|
switch (action.type) {
|
|
14
15
|
case '@@Response/kcsapi/api_get_member/questlist': {
|
|
15
|
-
const { body } = action
|
|
16
|
+
const { body, postBody } = action
|
|
16
17
|
|
|
17
18
|
return {
|
|
18
19
|
...state,
|
|
19
20
|
questList: body.api_list,
|
|
21
|
+
tabId: postBody.api_tab_id,
|
|
20
22
|
}
|
|
21
23
|
}
|
|
22
24
|
default:
|
package/src/store/filterTags.ts
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { useCallback } from 'react'
|
|
2
|
+
import { useUpdateEffect } from 'react-use'
|
|
3
|
+
import { useGameTab } from '../poi/hooks'
|
|
4
|
+
import { QuestTab } from '../poi/types'
|
|
2
5
|
import {
|
|
3
6
|
ALL_CATEGORY_TAG,
|
|
4
7
|
ALL_TYPE_TAG,
|
|
5
8
|
CATEGORY_TAGS,
|
|
6
9
|
TYPE_TAGS,
|
|
7
10
|
} from '../tags'
|
|
8
|
-
import { useStore } from './store'
|
|
11
|
+
import { useStore, useSyncWithGame } from './store'
|
|
9
12
|
|
|
10
13
|
export const useFilterTags = () => {
|
|
11
14
|
const {
|
|
@@ -29,6 +32,13 @@ export const useFilterTags = () => {
|
|
|
29
32
|
},
|
|
30
33
|
[updateStore]
|
|
31
34
|
)
|
|
35
|
+
const manualSetTypeTags = useCallback(
|
|
36
|
+
(data: Record<string, boolean>) => {
|
|
37
|
+
updateStore({ typeTags: data })
|
|
38
|
+
},
|
|
39
|
+
[updateStore]
|
|
40
|
+
)
|
|
41
|
+
|
|
32
42
|
const setTypeTagsAll = useCallback(() => {
|
|
33
43
|
setTypeTags(ALL_TYPE_TAG.name)
|
|
34
44
|
}, [setTypeTags])
|
|
@@ -39,6 +49,44 @@ export const useFilterTags = () => {
|
|
|
39
49
|
setCategoryTags,
|
|
40
50
|
setCategoryTagsAll,
|
|
41
51
|
setTypeTags,
|
|
52
|
+
manualSetTypeTags,
|
|
42
53
|
setTypeTagsAll,
|
|
43
54
|
}
|
|
44
55
|
}
|
|
56
|
+
|
|
57
|
+
export const useSyncGameTagEffect = () => {
|
|
58
|
+
const { syncWithGame } = useSyncWithGame()
|
|
59
|
+
const filterTags = useFilterTags()
|
|
60
|
+
const tab = useGameTab()
|
|
61
|
+
|
|
62
|
+
useUpdateEffect(() => {
|
|
63
|
+
if (!syncWithGame) {
|
|
64
|
+
return
|
|
65
|
+
}
|
|
66
|
+
switch (tab) {
|
|
67
|
+
case QuestTab.ALL:
|
|
68
|
+
filterTags.setTypeTagsAll()
|
|
69
|
+
break
|
|
70
|
+
case QuestTab.DAILY:
|
|
71
|
+
filterTags.setTypeTags('Daily')
|
|
72
|
+
break
|
|
73
|
+
case QuestTab.WEEKLY:
|
|
74
|
+
filterTags.setTypeTags('Weekly')
|
|
75
|
+
break
|
|
76
|
+
case QuestTab.MONTHLY:
|
|
77
|
+
filterTags.setTypeTags('Monthly')
|
|
78
|
+
break
|
|
79
|
+
case QuestTab.IN_PROGRESS:
|
|
80
|
+
filterTags.setTypeTags('In Progress')
|
|
81
|
+
break
|
|
82
|
+
case QuestTab.OTHERS:
|
|
83
|
+
filterTags.manualSetTypeTags({ Quarterly: true, Yearly: true })
|
|
84
|
+
break
|
|
85
|
+
case QuestTab.ONCE:
|
|
86
|
+
filterTags.setTypeTags('One-time')
|
|
87
|
+
break
|
|
88
|
+
default:
|
|
89
|
+
break
|
|
90
|
+
}
|
|
91
|
+
}, [syncWithGame, tab])
|
|
92
|
+
}
|
package/src/store/quest.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { useGameQuest, usePluginTranslation } from '../poi/hooks'
|
|
|
4
4
|
import { getCategory } from '../questHelper'
|
|
5
5
|
import type { UnionQuest } from '../questHelper'
|
|
6
6
|
import { useKcwikiData, checkIsKcwikiSupportedLanguages } from './kcwiki'
|
|
7
|
-
import { useStore } from './store'
|
|
7
|
+
import { useStore, useSyncWithGame } from './store'
|
|
8
8
|
|
|
9
9
|
const DEFAULT_LANG = 'ja-JP'
|
|
10
10
|
|
|
@@ -40,9 +40,7 @@ const useQuestMap = () => {
|
|
|
40
40
|
export const useQuest = (): UnionQuest[] => {
|
|
41
41
|
const docQuestMap = useQuestMap()
|
|
42
42
|
const gameQuest = useGameQuest()
|
|
43
|
-
const {
|
|
44
|
-
store: { syncWithGame },
|
|
45
|
-
} = useStore()
|
|
43
|
+
const { syncWithGame } = useSyncWithGame()
|
|
46
44
|
|
|
47
45
|
if (syncWithGame && gameQuest.length) {
|
|
48
46
|
return gameQuest.map((quest) => {
|
package/src/tags.tsx
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { Tag } from '@blueprintjs/core'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
import styled from 'styled-components'
|
|
4
|
+
import { IN_POI } from './poi/env'
|
|
5
|
+
import { useGameQuest, useGameTab, usePluginTranslation } from './poi/hooks'
|
|
6
|
+
import { GameQuest, QuestTab } from './poi/types'
|
|
7
|
+
import type { UnionQuest } from './questHelper'
|
|
8
|
+
import {
|
|
9
|
+
hasNewQuest,
|
|
10
|
+
isArsenalQuest,
|
|
11
|
+
isCompositionQuest,
|
|
12
|
+
isDailyQuest,
|
|
13
|
+
isExerciseQuest,
|
|
14
|
+
isExpeditionQuest,
|
|
15
|
+
isInProgressQuest,
|
|
16
|
+
isModernizationQuest,
|
|
17
|
+
isMonthlyQuest,
|
|
18
|
+
isNewQuest,
|
|
19
|
+
isQuarterlyQuest,
|
|
20
|
+
isSingleQuest,
|
|
21
|
+
isSortieQuest,
|
|
22
|
+
isSupplyOrDockingQuest,
|
|
23
|
+
isUnknownCategoryQuest,
|
|
24
|
+
isWeeklyQuest,
|
|
25
|
+
isYearlyQuest,
|
|
26
|
+
newQuestNumber,
|
|
27
|
+
} from './questHelper'
|
|
28
|
+
import { useSyncWithGame } from './store'
|
|
29
|
+
import { useFilterTags } from './store/filterTags'
|
|
30
|
+
|
|
31
|
+
const yes = () => true as const
|
|
32
|
+
|
|
33
|
+
export const ALL_CATEGORY_TAG = {
|
|
34
|
+
name: 'All',
|
|
35
|
+
filter: yes,
|
|
36
|
+
} as const
|
|
37
|
+
|
|
38
|
+
export const ALL_TYPE_TAG = ALL_CATEGORY_TAG
|
|
39
|
+
|
|
40
|
+
const withDocQuest =
|
|
41
|
+
<T extends any>(filterFn: (q: UnionQuest['docQuest']) => T) =>
|
|
42
|
+
(unionQuest: UnionQuest) =>
|
|
43
|
+
filterFn(unionQuest.docQuest)
|
|
44
|
+
|
|
45
|
+
const withGameQuestOr =
|
|
46
|
+
<T extends any>(filterFn: (q: GameQuest) => T, fallback: T) =>
|
|
47
|
+
({ gameQuest }: UnionQuest) => {
|
|
48
|
+
if (!gameQuest) {
|
|
49
|
+
return fallback
|
|
50
|
+
}
|
|
51
|
+
return filterFn(gameQuest)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export const CATEGORY_TAGS = [
|
|
55
|
+
ALL_CATEGORY_TAG,
|
|
56
|
+
{ name: 'Composition', filter: withDocQuest(isCompositionQuest) },
|
|
57
|
+
{ name: 'Sortie', filter: withDocQuest(isSortieQuest) },
|
|
58
|
+
{ name: 'Exercise', filter: withDocQuest(isExerciseQuest) },
|
|
59
|
+
{ name: 'Expedition', filter: withDocQuest(isExpeditionQuest) },
|
|
60
|
+
{ name: 'Supply / Docking', filter: withDocQuest(isSupplyOrDockingQuest) },
|
|
61
|
+
{ name: 'Arsenal', filter: withDocQuest(isArsenalQuest) },
|
|
62
|
+
{ name: 'Modernization', filter: withDocQuest(isModernizationQuest) },
|
|
63
|
+
{ name: 'Others', filter: withDocQuest(isUnknownCategoryQuest) },
|
|
64
|
+
] as const
|
|
65
|
+
|
|
66
|
+
export const TYPE_TAGS = [
|
|
67
|
+
ALL_TYPE_TAG,
|
|
68
|
+
{
|
|
69
|
+
name: 'In Progress',
|
|
70
|
+
filter: withGameQuestOr(isInProgressQuest, false),
|
|
71
|
+
},
|
|
72
|
+
{ name: 'New', filter: isNewQuest },
|
|
73
|
+
{ name: 'Daily', filter: isDailyQuest },
|
|
74
|
+
{ name: 'Weekly', filter: isWeeklyQuest },
|
|
75
|
+
{ name: 'Monthly', filter: isMonthlyQuest },
|
|
76
|
+
{ name: 'One-time', filter: isSingleQuest },
|
|
77
|
+
{ name: 'Quarterly', filter: isQuarterlyQuest },
|
|
78
|
+
{ name: 'Yearly', filter: isYearlyQuest },
|
|
79
|
+
] as const
|
|
80
|
+
|
|
81
|
+
// TODO tag Lock / Completed
|
|
82
|
+
|
|
83
|
+
const TagsWrapper = styled.div`
|
|
84
|
+
margin-left: -4px;
|
|
85
|
+
margin-right: -4px;
|
|
86
|
+
|
|
87
|
+
& > * {
|
|
88
|
+
margin: 4px;
|
|
89
|
+
}
|
|
90
|
+
`
|
|
91
|
+
|
|
92
|
+
export const CategoryTags = () => {
|
|
93
|
+
const { t } = usePluginTranslation()
|
|
94
|
+
|
|
95
|
+
const { categoryTags, setCategoryTags } = useFilterTags()
|
|
96
|
+
return (
|
|
97
|
+
<TagsWrapper>
|
|
98
|
+
{CATEGORY_TAGS.map(({ name }) => (
|
|
99
|
+
<Tag
|
|
100
|
+
onClick={() => setCategoryTags(name)}
|
|
101
|
+
intent={
|
|
102
|
+
categoryTags[name]
|
|
103
|
+
? name === ALL_CATEGORY_TAG.name
|
|
104
|
+
? 'success'
|
|
105
|
+
: 'primary'
|
|
106
|
+
: 'none'
|
|
107
|
+
}
|
|
108
|
+
interactive={true}
|
|
109
|
+
key={name}
|
|
110
|
+
>
|
|
111
|
+
{t(name)}
|
|
112
|
+
</Tag>
|
|
113
|
+
))}
|
|
114
|
+
</TagsWrapper>
|
|
115
|
+
)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export const TypeTags = () => {
|
|
119
|
+
const { t } = usePluginTranslation()
|
|
120
|
+
const gameTab = useGameTab()
|
|
121
|
+
const { syncWithGame } = useSyncWithGame()
|
|
122
|
+
const gameQuests = useGameQuest()
|
|
123
|
+
const inProgressQuest = gameQuests.filter((gameQuest) =>
|
|
124
|
+
isInProgressQuest(gameQuest)
|
|
125
|
+
)
|
|
126
|
+
const { typeTags, setTypeTags } = useFilterTags()
|
|
127
|
+
|
|
128
|
+
const limitSwitch = syncWithGame && gameTab !== QuestTab.ALL
|
|
129
|
+
|
|
130
|
+
return (
|
|
131
|
+
<TagsWrapper>
|
|
132
|
+
<Tag
|
|
133
|
+
intent={typeTags['All'] ? 'success' : 'none'}
|
|
134
|
+
interactive={true}
|
|
135
|
+
onClick={() => setTypeTags('All')}
|
|
136
|
+
>
|
|
137
|
+
{t('All')}
|
|
138
|
+
</Tag>
|
|
139
|
+
{IN_POI && (
|
|
140
|
+
<Tag
|
|
141
|
+
intent={typeTags['In Progress'] ? 'primary' : 'none'}
|
|
142
|
+
interactive={true}
|
|
143
|
+
onClick={() => setTypeTags('In Progress')}
|
|
144
|
+
>
|
|
145
|
+
{t('In Progress', { number: inProgressQuest.length })}
|
|
146
|
+
</Tag>
|
|
147
|
+
)}
|
|
148
|
+
{hasNewQuest && (
|
|
149
|
+
<Tag
|
|
150
|
+
intent={typeTags['New'] ? 'primary' : 'none'}
|
|
151
|
+
interactive={true}
|
|
152
|
+
onClick={() => setTypeTags('New')}
|
|
153
|
+
>
|
|
154
|
+
{t('New', { number: newQuestNumber })}
|
|
155
|
+
</Tag>
|
|
156
|
+
)}
|
|
157
|
+
|
|
158
|
+
{TYPE_TAGS.slice(3).map((tag) => (
|
|
159
|
+
<Tag
|
|
160
|
+
onClick={() => setTypeTags(tag.name)}
|
|
161
|
+
intent={
|
|
162
|
+
typeTags[tag.name] ? (limitSwitch ? 'warning' : 'primary') : 'none'
|
|
163
|
+
}
|
|
164
|
+
interactive={true}
|
|
165
|
+
key={tag.name}
|
|
166
|
+
>
|
|
167
|
+
{t(tag.name)}
|
|
168
|
+
</Tag>
|
|
169
|
+
))}
|
|
170
|
+
</TagsWrapper>
|
|
171
|
+
)
|
|
172
|
+
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: Bug report 代码缺陷汇报
|
|
3
|
-
about: Create a report to help us improve 汇报程序代码错误
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
**poi 版本 / poi version:**
|
|
7
|
-
|
|
8
|
-
**操作系统 / OS:**
|
|
9
|
-
|
|
10
|
-
**插件版本 / Plugin version:**
|
|
11
|
-
|
|
12
|
-
**你遇到了什么样的问题 / The problem you've met:**
|
|
13
|
-
|
|
14
|
-
**有没有重现的方法,或者与问题相关的任何信息 / How to reproduce, or any information that might be related:**
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
name: Build
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches: [main]
|
|
6
|
-
pull_request:
|
|
7
|
-
branches: [main]
|
|
8
|
-
|
|
9
|
-
jobs:
|
|
10
|
-
build:
|
|
11
|
-
strategy:
|
|
12
|
-
matrix:
|
|
13
|
-
node-version: [16.x]
|
|
14
|
-
os: [ubuntu-latest]
|
|
15
|
-
|
|
16
|
-
if: "!contains(github.event.head_commit.message, '[skip ci]')"
|
|
17
|
-
runs-on: ${{ matrix.os }}
|
|
18
|
-
|
|
19
|
-
steps:
|
|
20
|
-
- uses: actions/checkout@v2
|
|
21
|
-
|
|
22
|
-
- name: Use Node.js ${{ matrix.node-version }}
|
|
23
|
-
uses: actions/setup-node@v1
|
|
24
|
-
with:
|
|
25
|
-
node-version: ${{ matrix.node-version }}
|
|
26
|
-
|
|
27
|
-
- name: Install node modules
|
|
28
|
-
uses: bahmutov/npm-install@v1
|
|
29
|
-
|
|
30
|
-
- name: Build
|
|
31
|
-
run: npm run build
|
|
32
|
-
|
|
33
|
-
- name: Lint
|
|
34
|
-
run: npm run lint -- --max-warnings=0
|
|
35
|
-
|
|
36
|
-
- name: Type check
|
|
37
|
-
run: npm run typeCheck
|
|
38
|
-
|
|
39
|
-
- name: Test
|
|
40
|
-
run: npm run test -- --coverage
|
|
41
|
-
|
|
42
|
-
- name: Build storybook
|
|
43
|
-
run: npm run build-storybook
|
|
44
|
-
|
|
45
|
-
- name: Deploy GitHub Pages
|
|
46
|
-
if: github.ref == 'refs/heads/main'
|
|
47
|
-
uses: peaceiris/actions-gh-pages@v3
|
|
48
|
-
with:
|
|
49
|
-
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
50
|
-
publish_dir: storybook-static
|
|
51
|
-
force_orphan: true
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
name: Publish
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
# Sequence of patterns matched against refs/tags
|
|
6
|
-
tags:
|
|
7
|
-
- 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
|
|
8
|
-
|
|
9
|
-
jobs:
|
|
10
|
-
build:
|
|
11
|
-
strategy:
|
|
12
|
-
matrix:
|
|
13
|
-
node-version: [16.x]
|
|
14
|
-
os: [ubuntu-latest]
|
|
15
|
-
|
|
16
|
-
runs-on: ${{ matrix.os }}
|
|
17
|
-
|
|
18
|
-
steps:
|
|
19
|
-
- uses: actions/checkout@v2
|
|
20
|
-
|
|
21
|
-
- name: Use Node.js ${{ matrix.node-version }}
|
|
22
|
-
uses: actions/setup-node@v1
|
|
23
|
-
with:
|
|
24
|
-
node-version: ${{ matrix.node-version }}
|
|
25
|
-
registry-url: 'https://registry.npmjs.org'
|
|
26
|
-
|
|
27
|
-
- name: Install node modules
|
|
28
|
-
uses: bahmutov/npm-install@v1
|
|
29
|
-
|
|
30
|
-
- name: Build
|
|
31
|
-
run: npm run build
|
|
32
|
-
|
|
33
|
-
- name: Lint
|
|
34
|
-
run: npm run lint -- --max-warnings=0
|
|
35
|
-
|
|
36
|
-
- name: Type check
|
|
37
|
-
run: npm run typeCheck
|
|
38
|
-
|
|
39
|
-
- name: Test
|
|
40
|
-
run: npm test
|
|
41
|
-
|
|
42
|
-
- name: Publish
|
|
43
|
-
run: npm publish
|
|
44
|
-
env:
|
|
45
|
-
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
package/.vscode/extensions.json
DELETED
package/.vscode/settings.json
DELETED
package/src/tags.ts
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { IN_POI } from './poi/env'
|
|
2
|
-
import {
|
|
3
|
-
isDailyQuest,
|
|
4
|
-
isMonthlyQuest,
|
|
5
|
-
isQuarterlyQuest,
|
|
6
|
-
isWeeklyQuest,
|
|
7
|
-
isYearlyQuest,
|
|
8
|
-
isCompositionQuest,
|
|
9
|
-
isSortieQuest,
|
|
10
|
-
isExerciseQuest,
|
|
11
|
-
isExpeditionQuest,
|
|
12
|
-
isSupplyOrDockingQuest,
|
|
13
|
-
isArsenalQuest,
|
|
14
|
-
isModernizationQuest,
|
|
15
|
-
isUnknownCategoryQuest,
|
|
16
|
-
isInProgressQuest,
|
|
17
|
-
isSingleQuest,
|
|
18
|
-
hasNewQuest,
|
|
19
|
-
isNewQuest,
|
|
20
|
-
newQuestNumber,
|
|
21
|
-
} from './questHelper'
|
|
22
|
-
import type { UnionQuest } from './questHelper'
|
|
23
|
-
|
|
24
|
-
const yes = () => true as const
|
|
25
|
-
|
|
26
|
-
export const ALL_CATEGORY_TAG = {
|
|
27
|
-
name: 'All',
|
|
28
|
-
filter: yes,
|
|
29
|
-
} as const
|
|
30
|
-
|
|
31
|
-
export const ALL_TYPE_TAG = ALL_CATEGORY_TAG
|
|
32
|
-
|
|
33
|
-
const withDocQuest =
|
|
34
|
-
(filterFn: (q: UnionQuest['docQuest']) => boolean) =>
|
|
35
|
-
(unionQuest: UnionQuest) =>
|
|
36
|
-
filterFn(unionQuest.docQuest)
|
|
37
|
-
|
|
38
|
-
export const CATEGORY_TAGS = [
|
|
39
|
-
ALL_CATEGORY_TAG,
|
|
40
|
-
{ name: 'Composition', filter: withDocQuest(isCompositionQuest) },
|
|
41
|
-
{ name: 'Sortie', filter: withDocQuest(isSortieQuest) },
|
|
42
|
-
{ name: 'Exercise', filter: withDocQuest(isExerciseQuest) },
|
|
43
|
-
{ name: 'Expedition', filter: withDocQuest(isExpeditionQuest) },
|
|
44
|
-
{ name: 'Supply / Docking', filter: withDocQuest(isSupplyOrDockingQuest) },
|
|
45
|
-
{ name: 'Arsenal', filter: withDocQuest(isArsenalQuest) },
|
|
46
|
-
{ name: 'Modernization', filter: withDocQuest(isModernizationQuest) },
|
|
47
|
-
{ name: 'Others', filter: withDocQuest(isUnknownCategoryQuest) },
|
|
48
|
-
] as const
|
|
49
|
-
|
|
50
|
-
export const TYPE_TAGS = [
|
|
51
|
-
ALL_TYPE_TAG,
|
|
52
|
-
...(IN_POI ? [{ name: 'In Progress', filter: isInProgressQuest }] : []),
|
|
53
|
-
...(hasNewQuest
|
|
54
|
-
? [{ name: 'New', filter: isNewQuest, suffix: newQuestNumber }]
|
|
55
|
-
: []),
|
|
56
|
-
{ name: 'Daily', filter: isDailyQuest },
|
|
57
|
-
{ name: 'Weekly', filter: isWeeklyQuest },
|
|
58
|
-
{ name: 'Monthly', filter: isMonthlyQuest },
|
|
59
|
-
{ name: 'Quarterly', filter: isQuarterlyQuest },
|
|
60
|
-
{ name: 'Yearly', filter: isYearlyQuest },
|
|
61
|
-
{ name: 'One-time', filter: isSingleQuest },
|
|
62
|
-
] as const
|
|
63
|
-
|
|
64
|
-
// TODO tag In Progress / Lock / Completed
|
|
65
|
-
|
|
66
|
-
export const ALL_TAGS = [...CATEGORY_TAGS, ...TYPE_TAGS]
|