poi-plugin-quest-info-2 0.5.2 → 0.5.6
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 +17 -2
- package/build/kcQuestsData/DATA_VERSION +1 -1
- package/build/kcQuestsData/index.ts +1 -1
- package/build/kcQuestsData/quests-scn.json +2305 -557
- package/build/kcanotifyGamedata/DATA_VERSION +1 -1
- package/build/kcanotifyGamedata/index.ts +1 -1
- package/package.json +6 -5
- package/src/App.tsx +1 -1
- package/src/Settings.tsx +1 -1
- package/src/Toolbar.tsx +8 -7
- package/src/__tests__/kcanotifyData.spec.ts +1 -1
- package/src/__tests__/kcwikiData.spec.ts +11 -5
- package/src/components/QuestCard.tsx +8 -8
- package/src/components/QuestList.tsx +54 -20
- package/src/patch.ts +2 -1
- package/src/poi/env.ts +16 -0
- package/src/poi/hooks.ts +56 -0
- package/src/poi/store.ts +80 -0
- package/src/poi/types.ts +117 -0
- package/src/questHelper.ts +26 -22
- package/src/reducer.ts +1 -1
- package/src/store/quest.ts +21 -54
- package/src/tags.ts +15 -9
- package/src/poi.ts +0 -211
package/src/store/quest.ts
CHANGED
|
@@ -1,16 +1,9 @@
|
|
|
1
|
-
import { useCallback
|
|
2
|
-
import { checkIsKcwikiSupportedLanguages } from '.'
|
|
1
|
+
import { useCallback } from 'react'
|
|
3
2
|
import { QuestData } from '../../build/kcanotifyGamedata'
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
observePoiStore,
|
|
9
|
-
PoiQuestState,
|
|
10
|
-
usePluginTranslation,
|
|
11
|
-
} from '../poi'
|
|
12
|
-
import { getCategory, KcanotifyQuestExt } from '../questHelper'
|
|
13
|
-
import { useKcwikiData } from './kcwiki'
|
|
3
|
+
import { useGameQuest, usePluginTranslation } from '../poi/hooks'
|
|
4
|
+
import { getCategory } from '../questHelper'
|
|
5
|
+
import type { UnionQuest } from '../questHelper'
|
|
6
|
+
import { useKcwikiData, checkIsKcwikiSupportedLanguages } from './kcwiki'
|
|
14
7
|
import { useStore } from './store'
|
|
15
8
|
|
|
16
9
|
const DEFAULT_LANG = 'ja-JP'
|
|
@@ -35,19 +28,6 @@ export const useLanguage = () => {
|
|
|
35
28
|
return lang
|
|
36
29
|
}
|
|
37
30
|
|
|
38
|
-
const useActiveQuest = () => {
|
|
39
|
-
const [activeQuests, setActiveQuests] = useState<PoiQuestState>({})
|
|
40
|
-
|
|
41
|
-
useEffect(() => {
|
|
42
|
-
const listener = (activeQuests: PoiQuestState) =>
|
|
43
|
-
setActiveQuests(activeQuests)
|
|
44
|
-
|
|
45
|
-
return observePoiStore(listener, activeQuestsSelector)
|
|
46
|
-
}, [])
|
|
47
|
-
|
|
48
|
-
return activeQuests
|
|
49
|
-
}
|
|
50
|
-
|
|
51
31
|
const useQuestMap = () => {
|
|
52
32
|
const lang = useLanguage()
|
|
53
33
|
const kcwikiData = useKcwikiData(lang)
|
|
@@ -57,37 +37,21 @@ const useQuestMap = () => {
|
|
|
57
37
|
return QuestData[lang]
|
|
58
38
|
}
|
|
59
39
|
|
|
60
|
-
const
|
|
61
|
-
const
|
|
62
|
-
useEffect(() => {
|
|
63
|
-
const listener = (quests: GameQuest[] | null) => setQuests(quests)
|
|
64
|
-
// See reducer.ts
|
|
65
|
-
return observePluginStore(listener, (i) => i?._?.questList)
|
|
66
|
-
}, [])
|
|
67
|
-
return quests
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export const useQuest = (): KcanotifyQuestExt[] => {
|
|
71
|
-
const activeQuest = useActiveQuest()
|
|
72
|
-
const questMap = useQuestMap()
|
|
40
|
+
export const useQuest = (): UnionQuest[] => {
|
|
41
|
+
const docQuestMap = useQuestMap()
|
|
73
42
|
const gameQuest = useGameQuest()
|
|
74
43
|
const {
|
|
75
44
|
store: { syncWithGame },
|
|
76
45
|
} = useStore()
|
|
77
46
|
|
|
78
|
-
if (syncWithGame) {
|
|
79
|
-
if (gameQuest == null) {
|
|
80
|
-
// TODO tip use to sync quest data
|
|
81
|
-
return []
|
|
82
|
-
}
|
|
47
|
+
if (syncWithGame && gameQuest.length) {
|
|
83
48
|
return gameQuest.map((quest) => {
|
|
84
49
|
const gameId = String(quest.api_no)
|
|
85
|
-
|
|
86
|
-
if (gameId in questMap) {
|
|
50
|
+
if (gameId in docQuestMap) {
|
|
87
51
|
return {
|
|
88
52
|
gameId,
|
|
89
|
-
|
|
90
|
-
|
|
53
|
+
gameQuest: quest,
|
|
54
|
+
docQuest: docQuestMap[gameId as keyof typeof docQuestMap],
|
|
91
55
|
}
|
|
92
56
|
}
|
|
93
57
|
|
|
@@ -95,18 +59,21 @@ export const useQuest = (): KcanotifyQuestExt[] => {
|
|
|
95
59
|
// May be a new quest
|
|
96
60
|
return {
|
|
97
61
|
gameId,
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
62
|
+
gameQuest: quest,
|
|
63
|
+
docQuest: {
|
|
64
|
+
code: `${getCategory(quest.api_category).wikiSymbol}?`,
|
|
65
|
+
name: quest.api_title,
|
|
66
|
+
desc: quest.api_detail,
|
|
67
|
+
},
|
|
102
68
|
}
|
|
103
69
|
})
|
|
104
70
|
} else {
|
|
105
71
|
// Return all recorded quests
|
|
106
|
-
return Object.entries(
|
|
72
|
+
return Object.entries(docQuestMap).map(([gameId, val]) => ({
|
|
107
73
|
gameId,
|
|
108
|
-
|
|
109
|
-
|
|
74
|
+
// Maybe empty
|
|
75
|
+
gameQuest: gameQuest.find((quest) => quest.api_no === Number(gameId))!,
|
|
76
|
+
docQuest: val,
|
|
110
77
|
}))
|
|
111
78
|
}
|
|
112
79
|
}
|
package/src/tags.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IN_POI } from './poi'
|
|
1
|
+
import { IN_POI } from './poi/env'
|
|
2
2
|
import {
|
|
3
3
|
isDailyQuest,
|
|
4
4
|
isMonthlyQuest,
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
isUnknownCategoryQuest,
|
|
16
16
|
isInProgressQuest,
|
|
17
17
|
} from './questHelper'
|
|
18
|
+
import type { UnionQuest } from './questHelper'
|
|
18
19
|
|
|
19
20
|
const yes = () => true as const
|
|
20
21
|
|
|
@@ -25,16 +26,21 @@ export const ALL_CATEGORY_TAG = {
|
|
|
25
26
|
|
|
26
27
|
export const ALL_TYPE_TAG = ALL_CATEGORY_TAG
|
|
27
28
|
|
|
29
|
+
const withDocQuest =
|
|
30
|
+
(filterFn: (q: UnionQuest['docQuest']) => boolean) =>
|
|
31
|
+
(unionQuest: UnionQuest) =>
|
|
32
|
+
filterFn(unionQuest.docQuest)
|
|
33
|
+
|
|
28
34
|
export const CATEGORY_TAGS = [
|
|
29
35
|
ALL_CATEGORY_TAG,
|
|
30
|
-
{ name: 'Composition', filter: isCompositionQuest },
|
|
31
|
-
{ name: 'Sortie', filter: isSortieQuest },
|
|
32
|
-
{ name: 'Exercise', filter: isExerciseQuest },
|
|
33
|
-
{ name: 'Expedition', filter: isExpeditionQuest },
|
|
34
|
-
{ name: 'Supply / Docking', filter: isSupplyOrDockingQuest },
|
|
35
|
-
{ name: 'Arsenal', filter: isArsenalQuest },
|
|
36
|
-
{ name: 'Modernization', filter: isModernizationQuest },
|
|
37
|
-
{ name: 'Others', filter: isUnknownCategoryQuest },
|
|
36
|
+
{ name: 'Composition', filter: withDocQuest(isCompositionQuest) },
|
|
37
|
+
{ name: 'Sortie', filter: withDocQuest(isSortieQuest) },
|
|
38
|
+
{ name: 'Exercise', filter: withDocQuest(isExerciseQuest) },
|
|
39
|
+
{ name: 'Expedition', filter: withDocQuest(isExpeditionQuest) },
|
|
40
|
+
{ name: 'Supply / Docking', filter: withDocQuest(isSupplyOrDockingQuest) },
|
|
41
|
+
{ name: 'Arsenal', filter: withDocQuest(isArsenalQuest) },
|
|
42
|
+
{ name: 'Modernization', filter: withDocQuest(isModernizationQuest) },
|
|
43
|
+
{ name: 'Others', filter: withDocQuest(isUnknownCategoryQuest) },
|
|
38
44
|
] as const
|
|
39
45
|
|
|
40
46
|
export const TYPE_TAGS = [
|
package/src/poi.ts
DELETED
|
@@ -1,211 +0,0 @@
|
|
|
1
|
-
import { useTranslation } from 'react-i18next'
|
|
2
|
-
import { name as PACKAGE_NAME } from '../package.json'
|
|
3
|
-
import type { PluginState } from './reducer'
|
|
4
|
-
|
|
5
|
-
// See https://github.com/poooi/poi/blob/master/views/redux/info/quests.es
|
|
6
|
-
export type GameQuest = {
|
|
7
|
-
// 1 Default
|
|
8
|
-
// 2 In progress
|
|
9
|
-
// 3 Completed
|
|
10
|
-
api_state: 1 | 2 | 3
|
|
11
|
-
api_no: number
|
|
12
|
-
api_title: string
|
|
13
|
-
api_detail: string
|
|
14
|
-
/**
|
|
15
|
-
* 任务类别
|
|
16
|
-
*
|
|
17
|
-
* 1. Composition
|
|
18
|
-
* 1. Sortie
|
|
19
|
-
* 1. Exercise
|
|
20
|
-
* 1. Expedition
|
|
21
|
-
* 1. Supply/Docking
|
|
22
|
-
* 1. Arsenal
|
|
23
|
-
* 1. Modernization
|
|
24
|
-
*
|
|
25
|
-
* @see https://github.com/poooi/plugin-quest/blob/master/index.es#L49-L57
|
|
26
|
-
*/
|
|
27
|
-
api_category: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
|
|
28
|
-
/**
|
|
29
|
-
* 任务类型
|
|
30
|
-
*
|
|
31
|
-
* 1. One-time
|
|
32
|
-
* 1. Daily
|
|
33
|
-
* 1. Weekly
|
|
34
|
-
* 1. -3rd/-7th/-0th
|
|
35
|
-
* 1. -2nd/-8th
|
|
36
|
-
* 1. Monthly
|
|
37
|
-
* 1. Quarterly
|
|
38
|
-
*
|
|
39
|
-
* @see https://github.com/poooi/plugin-quest/blob/master/index.es#L69-L77
|
|
40
|
-
*/
|
|
41
|
-
api_type: 1 | 2 | 3 | 4 | 5 | 6 | 7
|
|
42
|
-
// Rewards 油弹钢铝
|
|
43
|
-
api_get_material: [number, number, number, number]
|
|
44
|
-
api_invalid_flag: 0
|
|
45
|
-
api_label_type: 1
|
|
46
|
-
// 0: Empty: [0.0, 0.5)
|
|
47
|
-
// 1: 50%: [0.5, 0.8)
|
|
48
|
-
// 2: 80%: [0.8, 1.0)
|
|
49
|
-
api_progress_flag: 0 | 1 | 2
|
|
50
|
-
api_select_rewards?: [
|
|
51
|
-
{
|
|
52
|
-
api_count: number
|
|
53
|
-
api_kind: number
|
|
54
|
-
api_mst_id: number
|
|
55
|
-
api_no: number
|
|
56
|
-
}[]
|
|
57
|
-
]
|
|
58
|
-
api_voice_id: 0
|
|
59
|
-
api_bonus_flag: 1
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
type QuestListAction = {
|
|
63
|
-
type: '@@Response/kcsapi/api_get_member/questlist'
|
|
64
|
-
path: '/kcsapi/api_get_member/questlist'
|
|
65
|
-
postBody: {
|
|
66
|
-
api_verno: '1'
|
|
67
|
-
api_tab_id:
|
|
68
|
-
| '0' // All
|
|
69
|
-
| '9' // In progress
|
|
70
|
-
| '1' // Daily
|
|
71
|
-
| '2' // Weekly
|
|
72
|
-
| '3' // Monthly
|
|
73
|
-
| '4' // Once
|
|
74
|
-
| '5' // Others
|
|
75
|
-
}
|
|
76
|
-
body: {
|
|
77
|
-
api_completed_kind: number
|
|
78
|
-
// api_list.length
|
|
79
|
-
api_count: number
|
|
80
|
-
// In progress count
|
|
81
|
-
api_exec_count: number
|
|
82
|
-
api_exec_type: number
|
|
83
|
-
api_list: GameQuest[]
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
type OtherAction = {
|
|
88
|
-
type: 'otherString' // TODO fix me
|
|
89
|
-
path?: string
|
|
90
|
-
postBody?: unknown
|
|
91
|
-
body?: unknown
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
export type PoiAction = QuestListAction | OtherAction
|
|
95
|
-
|
|
96
|
-
export type PoiState = {
|
|
97
|
-
ext: {
|
|
98
|
-
// TODO fix use constant PACKAGE_NAME
|
|
99
|
-
[packageName: string]: PluginState
|
|
100
|
-
}
|
|
101
|
-
plugins: { id: string; enabled: boolean; [x: string]: unknown }[]
|
|
102
|
-
[x: string]: any
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
type Store<S> = {
|
|
106
|
-
getState: () => S
|
|
107
|
-
subscribe: (listener: () => void) => () => void
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// state.info.quests.activeQuests
|
|
111
|
-
export type PoiQuestState = Record<number, { time: number; detail: GameQuest }>
|
|
112
|
-
|
|
113
|
-
export const IN_POI = 'POI_VERSION' in globalThis
|
|
114
|
-
|
|
115
|
-
const noop = () => {}
|
|
116
|
-
const id = <T>(x: T) => x
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Prevent webpack early error
|
|
120
|
-
* Module not found: Error: Can't resolve 'views/create-store'
|
|
121
|
-
* TODO fix webpack warn
|
|
122
|
-
* Critical dependency: the request of a dependency is an expression
|
|
123
|
-
*/
|
|
124
|
-
export const importFromPoi = <T = any>(path: string): Promise<T> => {
|
|
125
|
-
if (!IN_POI) {
|
|
126
|
-
return new Promise(() => {
|
|
127
|
-
// Never resolve
|
|
128
|
-
})
|
|
129
|
-
}
|
|
130
|
-
return import(path)
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* See https://redux.js.org/api/store#subscribelistener
|
|
135
|
-
*/
|
|
136
|
-
const observeStore = <State, SelectedState = State>(
|
|
137
|
-
store: Store<State>,
|
|
138
|
-
onChange: (state: SelectedState) => void,
|
|
139
|
-
selector: (s: State) => SelectedState = id as any
|
|
140
|
-
) => {
|
|
141
|
-
let currentState: SelectedState
|
|
142
|
-
|
|
143
|
-
const handleChange = () => {
|
|
144
|
-
const nextState = selector(store.getState())
|
|
145
|
-
if (nextState !== currentState) {
|
|
146
|
-
currentState = nextState
|
|
147
|
-
onChange(currentState)
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
const unsubscribe = store.subscribe(handleChange)
|
|
152
|
-
handleChange()
|
|
153
|
-
return unsubscribe
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
export const observePoiStore = <SelectedState = PoiState>(
|
|
157
|
-
onChange: (state: SelectedState) => void,
|
|
158
|
-
selector: (state: PoiState) => SelectedState = id as any
|
|
159
|
-
) => {
|
|
160
|
-
let valid = true
|
|
161
|
-
let unsubscribe = noop
|
|
162
|
-
getPoiStore().then((store) => {
|
|
163
|
-
if (!valid) {
|
|
164
|
-
return
|
|
165
|
-
}
|
|
166
|
-
unsubscribe = observeStore(store, onChange, selector)
|
|
167
|
-
})
|
|
168
|
-
|
|
169
|
-
return () => {
|
|
170
|
-
valid = false
|
|
171
|
-
unsubscribe()
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
export const observePluginStore = <SelectedState = PluginState>(
|
|
176
|
-
onChange: (state: SelectedState) => void,
|
|
177
|
-
selector: (state: PluginState) => SelectedState = id as any
|
|
178
|
-
) => observePoiStore(onChange, (s) => selector(s?.ext[PACKAGE_NAME]))
|
|
179
|
-
|
|
180
|
-
const fallbackStore: Store<PoiState> = {
|
|
181
|
-
getState: noop as () => PoiState,
|
|
182
|
-
subscribe: () => (() => {}) as () => () => void,
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
let globalStore: Store<PoiState> | null = null
|
|
186
|
-
/**
|
|
187
|
-
* Get poi global Store if in poi env
|
|
188
|
-
*/
|
|
189
|
-
export const getPoiStore: () => Promise<Store<PoiState>> = async () => {
|
|
190
|
-
if (globalStore !== null) {
|
|
191
|
-
return globalStore
|
|
192
|
-
}
|
|
193
|
-
if (IN_POI) {
|
|
194
|
-
try {
|
|
195
|
-
const { store } = await importFromPoi('views/create-store')
|
|
196
|
-
globalStore = store
|
|
197
|
-
return store
|
|
198
|
-
} catch (error) {
|
|
199
|
-
console.warn('Load global store error', error)
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
globalStore = fallbackStore
|
|
203
|
-
return fallbackStore
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
export const activeQuestsSelector = (state: PoiState): PoiQuestState =>
|
|
207
|
-
state?.info?.quests?.activeQuests ?? {}
|
|
208
|
-
|
|
209
|
-
export const usePluginTranslation = () => {
|
|
210
|
-
return useTranslation(PACKAGE_NAME)
|
|
211
|
-
}
|