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
|
@@ -1 +1 @@
|
|
|
1
|
-
5.3.3.
|
|
1
|
+
5.3.3.1
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "poi-plugin-quest-info-2",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.6",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "show quest info",
|
|
6
6
|
"homepage": "https://github.com/lawvs/poi-plugin-quest-2/",
|
|
@@ -18,18 +18,19 @@
|
|
|
18
18
|
},
|
|
19
19
|
"main": "src/index.ts",
|
|
20
20
|
"scripts": {
|
|
21
|
-
"build": "npm run convertAssets && npm run
|
|
21
|
+
"build": "npm run convertAssets && npm run update",
|
|
22
22
|
"build-storybook": "build-storybook",
|
|
23
23
|
"clean": "rm -rf build",
|
|
24
|
-
"
|
|
24
|
+
"convertAssets": "ts-node scripts/convertAssets.ts",
|
|
25
25
|
"downloadKcQuestsData": "ts-node scripts/downloadKcQuestsData.ts",
|
|
26
|
+
"downloadKcanotifyData": "ts-node scripts/downloadKcanotifyGamedata.ts",
|
|
26
27
|
"downloadSprites": "ts-node scripts/downloadSprites.ts",
|
|
27
|
-
"convertAssets": "ts-node scripts/convertAssets.ts",
|
|
28
28
|
"lint": "eslint . --ignore-path .gitignore",
|
|
29
29
|
"lint:fix": "npm run lint -- --fix",
|
|
30
30
|
"storybook": "start-storybook -p 6006",
|
|
31
31
|
"test": "jest",
|
|
32
|
-
"typeCheck": "tsc --noEmit"
|
|
32
|
+
"typeCheck": "tsc --noEmit",
|
|
33
|
+
"update": "npm run downloadKcanotifyData & npm run downloadKcQuestsData"
|
|
33
34
|
},
|
|
34
35
|
"dependencies": {
|
|
35
36
|
"react-use": "^17.3.1",
|
package/src/App.tsx
CHANGED
|
@@ -4,7 +4,7 @@ import { Text } from '@blueprintjs/core'
|
|
|
4
4
|
|
|
5
5
|
import { Toolbar, useFilterQuest } from './Toolbar'
|
|
6
6
|
import { StoreProvider } from './store'
|
|
7
|
-
import { usePluginTranslation } from './poi'
|
|
7
|
+
import { usePluginTranslation } from './poi/hooks'
|
|
8
8
|
import { QuestList } from './components/QuestList'
|
|
9
9
|
|
|
10
10
|
const Container = styled.div`
|
package/src/Settings.tsx
CHANGED
|
@@ -4,7 +4,7 @@ import { IconNames } from '@blueprintjs/icons'
|
|
|
4
4
|
import styled from 'styled-components'
|
|
5
5
|
import { version as PACKAGE_VERSION, homepage } from '../package.json'
|
|
6
6
|
import { version as DATA_VERSION } from '../build/kcanotifyGamedata'
|
|
7
|
-
import { usePluginTranslation } from './poi'
|
|
7
|
+
import { usePluginTranslation } from './poi/hooks'
|
|
8
8
|
import {
|
|
9
9
|
useRemoveStorage,
|
|
10
10
|
StoreProvider,
|
package/src/Toolbar.tsx
CHANGED
|
@@ -12,8 +12,9 @@ import {
|
|
|
12
12
|
CATEGORY_TAGS,
|
|
13
13
|
ALL_TAGS,
|
|
14
14
|
} from './tags'
|
|
15
|
-
import type {
|
|
16
|
-
import {
|
|
15
|
+
import type { UnionQuest } from './questHelper'
|
|
16
|
+
import { usePluginTranslation } from './poi/hooks'
|
|
17
|
+
import { IN_POI } from './poi/env'
|
|
17
18
|
|
|
18
19
|
const ToolbarWrapper = styled.div`
|
|
19
20
|
display: flex;
|
|
@@ -157,10 +158,10 @@ const useToolbarFilter = () => {
|
|
|
157
158
|
.map((i) => i.toUpperCase())
|
|
158
159
|
|
|
159
160
|
const stringFilter = useCallback(
|
|
160
|
-
(quest:
|
|
161
|
-
const text = `${quest.code} ${quest.name} ${
|
|
162
|
-
quest.
|
|
163
|
-
}`
|
|
161
|
+
(quest: UnionQuest) => {
|
|
162
|
+
const text = `${quest.docQuest.code} ${quest.docQuest.name} ${
|
|
163
|
+
quest.docQuest.desc
|
|
164
|
+
} ${quest.docQuest.memo ?? ''}`
|
|
164
165
|
if (!searchKeywords) {
|
|
165
166
|
return true
|
|
166
167
|
}
|
|
@@ -172,7 +173,7 @@ const useToolbarFilter = () => {
|
|
|
172
173
|
)
|
|
173
174
|
|
|
174
175
|
const toolbarFilter = useCallback(
|
|
175
|
-
(quest:
|
|
176
|
+
(quest: UnionQuest) => {
|
|
176
177
|
return [...tagsFilter, stringFilter].every((filter) => filter(quest))
|
|
177
178
|
},
|
|
178
179
|
[stringFilter, tagsFilter]
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { version, QuestData } from '../../build/kcanotifyGamedata'
|
|
2
2
|
|
|
3
3
|
test('should Kcanotify Game data version correct', () => {
|
|
4
|
-
expect(version).toMatchInlineSnapshot(`"5.3.3.
|
|
4
|
+
expect(version).toMatchInlineSnapshot(`"5.3.3.1"`)
|
|
5
5
|
})
|
|
6
6
|
|
|
7
7
|
test('should Kcanotify Game data keys correct', () => {
|
|
@@ -1,9 +1,15 @@
|
|
|
1
|
-
import { KcwikiQuestData } from '../../build/kcQuestsData'
|
|
1
|
+
import { version, KcwikiQuestData } from '../../build/kcQuestsData'
|
|
2
|
+
|
|
3
|
+
test('should KcwikiQuestData Game data version correct', () => {
|
|
4
|
+
expect(version).toMatchInlineSnapshot(
|
|
5
|
+
`"5fc5ff0a78daaefe383d702873a688704f546de4"`
|
|
6
|
+
)
|
|
7
|
+
})
|
|
2
8
|
|
|
3
9
|
test('should KcwikiQuestData Game data keys correct', () => {
|
|
4
10
|
expect(Object.keys(KcwikiQuestData)).toMatchInlineSnapshot(`
|
|
5
|
-
Array [
|
|
6
|
-
|
|
7
|
-
]
|
|
8
|
-
`)
|
|
11
|
+
Array [
|
|
12
|
+
"zh-CN",
|
|
13
|
+
]
|
|
14
|
+
`)
|
|
9
15
|
})
|
|
@@ -2,7 +2,7 @@ import { Card, Elevation, H5, Text, Tooltip, Icon } from '@blueprintjs/core'
|
|
|
2
2
|
import { IconNames } from '@blueprintjs/icons'
|
|
3
3
|
import React, { useCallback } from 'react'
|
|
4
4
|
import styled from 'styled-components'
|
|
5
|
-
import { usePluginTranslation } from '../poi'
|
|
5
|
+
import { usePluginTranslation } from '../poi/hooks'
|
|
6
6
|
import {
|
|
7
7
|
guessQuestCategory,
|
|
8
8
|
QUEST_CATEGORY,
|
|
@@ -75,7 +75,7 @@ const questIconMap = {
|
|
|
75
75
|
} as const
|
|
76
76
|
|
|
77
77
|
const questStatusMap: Record<QUEST_STATUS, React.FC> = {
|
|
78
|
-
[QUEST_STATUS.
|
|
78
|
+
[QUEST_STATUS.LOCKED]: function Locked() {
|
|
79
79
|
const { t } = usePluginTranslation()
|
|
80
80
|
return (
|
|
81
81
|
<Tooltip content={t('Locked')}>
|
|
@@ -84,8 +84,8 @@ const questStatusMap: Record<QUEST_STATUS, React.FC> = {
|
|
|
84
84
|
)
|
|
85
85
|
},
|
|
86
86
|
// Display nothing
|
|
87
|
-
[QUEST_STATUS.
|
|
88
|
-
[QUEST_STATUS.
|
|
87
|
+
[QUEST_STATUS.DEFAULT]: () => null,
|
|
88
|
+
[QUEST_STATUS.IN_PROGRESS]: function InProgress() {
|
|
89
89
|
const { t } = usePluginTranslation()
|
|
90
90
|
return (
|
|
91
91
|
<Tooltip content={t('In Progress')}>
|
|
@@ -93,7 +93,7 @@ const questStatusMap: Record<QUEST_STATUS, React.FC> = {
|
|
|
93
93
|
</Tooltip>
|
|
94
94
|
)
|
|
95
95
|
},
|
|
96
|
-
[QUEST_STATUS.
|
|
96
|
+
[QUEST_STATUS.COMPLETED]: function Completed() {
|
|
97
97
|
const { t } = usePluginTranslation()
|
|
98
98
|
return (
|
|
99
99
|
<Tooltip content={t('Completed')}>
|
|
@@ -101,7 +101,7 @@ const questStatusMap: Record<QUEST_STATUS, React.FC> = {
|
|
|
101
101
|
</Tooltip>
|
|
102
102
|
)
|
|
103
103
|
},
|
|
104
|
-
[QUEST_STATUS.
|
|
104
|
+
[QUEST_STATUS.ALREADY_COMPLETED]: function AlreadyCompleted() {
|
|
105
105
|
const { t } = usePluginTranslation()
|
|
106
106
|
return (
|
|
107
107
|
<Tooltip content={t('Already Completed')}>
|
|
@@ -126,7 +126,7 @@ export const LargeQuestCard: React.FC<QuestCardProps> = ({
|
|
|
126
126
|
name,
|
|
127
127
|
desc,
|
|
128
128
|
tips,
|
|
129
|
-
status = QUEST_STATUS.
|
|
129
|
+
status = QUEST_STATUS.DEFAULT,
|
|
130
130
|
onClick,
|
|
131
131
|
style,
|
|
132
132
|
}) => {
|
|
@@ -159,7 +159,7 @@ export const MinimalQuestCard: React.FC<QuestCardProps> = ({
|
|
|
159
159
|
name,
|
|
160
160
|
desc,
|
|
161
161
|
tips,
|
|
162
|
-
status = QUEST_STATUS.
|
|
162
|
+
status = QUEST_STATUS.DEFAULT,
|
|
163
163
|
onClick,
|
|
164
164
|
style,
|
|
165
165
|
}) => {
|
|
@@ -7,10 +7,14 @@ import {
|
|
|
7
7
|
List,
|
|
8
8
|
ListRowRenderer,
|
|
9
9
|
} from 'react-virtualized'
|
|
10
|
+
import type { ListRowProps } from 'react-virtualized'
|
|
10
11
|
import styled from 'styled-components'
|
|
11
|
-
import {
|
|
12
|
+
import { QUEST_STATUS } from '../questHelper'
|
|
13
|
+
import type { UnionQuest } from '../questHelper'
|
|
12
14
|
import { useLargeCard } from '../store'
|
|
13
15
|
import { QuestCard } from './QuestCard'
|
|
16
|
+
import { useIsQuestPluginTab } from '../poi/hooks'
|
|
17
|
+
import { QUEST_API_STATE } from '../poi/types'
|
|
14
18
|
|
|
15
19
|
const QuestListWrapper = styled.div`
|
|
16
20
|
flex: 1;
|
|
@@ -23,26 +27,29 @@ const cache = new CellMeasurerCache({
|
|
|
23
27
|
fixedWidth: true,
|
|
24
28
|
})
|
|
25
29
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
30
|
+
const questStateToQuestStatus = (
|
|
31
|
+
state: QUEST_API_STATE | undefined
|
|
32
|
+
): QUEST_STATUS => {
|
|
33
|
+
switch (state) {
|
|
34
|
+
case QUEST_API_STATE.DEFAULT:
|
|
35
|
+
return QUEST_STATUS.DEFAULT
|
|
36
|
+
case QUEST_API_STATE.COMPLETED:
|
|
37
|
+
return QUEST_STATUS.COMPLETED
|
|
38
|
+
case QUEST_API_STATE.IN_PROGRESS:
|
|
39
|
+
return QUEST_STATUS.IN_PROGRESS
|
|
40
|
+
default:
|
|
41
|
+
return QUEST_STATUS.DEFAULT
|
|
42
|
+
}
|
|
43
|
+
}
|
|
37
44
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
45
|
+
const useQuestsRowRenderer = (quests: UnionQuest[]) => {
|
|
46
|
+
const rowRenderer = useCallback(
|
|
47
|
+
({ key, index, style, parent }: ListRowProps) => {
|
|
48
|
+
const quest = quests[index]
|
|
49
|
+
const { gameId } = quest
|
|
50
|
+
const { code, name, desc, memo } = quest.docQuest
|
|
51
|
+
const questStatus = questStateToQuestStatus(quest.gameQuest?.api_state)
|
|
42
52
|
|
|
43
|
-
const rowRenderer: ListRowRenderer = useCallback(
|
|
44
|
-
({ key, index, style, parent }) => {
|
|
45
|
-
const { gameId, code, name, desc, memo, active } = quests[index]
|
|
46
53
|
return (
|
|
47
54
|
<CellMeasurer
|
|
48
55
|
cache={cache}
|
|
@@ -59,7 +66,7 @@ export const QuestList: React.FC<{ quests: KcanotifyQuestExt[] }> = ({
|
|
|
59
66
|
name={name}
|
|
60
67
|
desc={desc}
|
|
61
68
|
tips={memo}
|
|
62
|
-
status={
|
|
69
|
+
status={questStatus}
|
|
63
70
|
></QuestCard>
|
|
64
71
|
</div>
|
|
65
72
|
</CellMeasurer>
|
|
@@ -67,6 +74,33 @@ export const QuestList: React.FC<{ quests: KcanotifyQuestExt[] }> = ({
|
|
|
67
74
|
},
|
|
68
75
|
[quests]
|
|
69
76
|
)
|
|
77
|
+
return rowRenderer
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export const QuestList: React.FC<{ quests: UnionQuest[] }> = ({ quests }) => {
|
|
81
|
+
const { largeCard } = useLargeCard()
|
|
82
|
+
const activeTab = useIsQuestPluginTab()
|
|
83
|
+
const listRef = useRef<List>(null)
|
|
84
|
+
const rowRenderer: ListRowRenderer = useQuestsRowRenderer(quests)
|
|
85
|
+
|
|
86
|
+
useEffect(() => {
|
|
87
|
+
const largeCardIdx = quests.findIndex((i) => i.gameId === largeCard)
|
|
88
|
+
cache.clearAll()
|
|
89
|
+
listRef.current?.recomputeRowHeights(largeCardIdx)
|
|
90
|
+
}, [quests, largeCard])
|
|
91
|
+
|
|
92
|
+
useEffect(() => {
|
|
93
|
+
if (activeTab) {
|
|
94
|
+
cache.clearAll()
|
|
95
|
+
listRef.current?.recomputeRowHeights()
|
|
96
|
+
}
|
|
97
|
+
}, [activeTab])
|
|
98
|
+
|
|
99
|
+
const onResize = useCallback(() => {
|
|
100
|
+
cache.clearAll()
|
|
101
|
+
listRef.current?.recomputeRowHeights()
|
|
102
|
+
}, [])
|
|
103
|
+
|
|
70
104
|
if (!quests.length) {
|
|
71
105
|
// Prevent Uncaught Error: Requested index 0 is outside of range 0..0
|
|
72
106
|
// See https://github.com/bvaughn/react-virtualized/issues/1016
|
package/src/patch.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { name as PACKAGE_NAME } from '../package.json'
|
|
2
|
-
import { getPoiStore
|
|
2
|
+
import { getPoiStore } from './poi/store'
|
|
3
|
+
import { importFromPoi } from './poi/env'
|
|
3
4
|
import { QuestData } from '../build/kcanotifyGamedata'
|
|
4
5
|
import { KcwikiQuestData } from '../build/kcQuestsData'
|
|
5
6
|
import {
|
package/src/poi/env.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const IN_POI = 'POI_VERSION' in globalThis
|
|
2
|
+
/**
|
|
3
|
+
* Prevent webpack early error
|
|
4
|
+
* Module not found: Error: Can't resolve 'views/create-store'
|
|
5
|
+
* TODO fix webpack warn
|
|
6
|
+
* Critical dependency: the request of a dependency is an expression
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export const importFromPoi = <T = any>(path: string): Promise<T> => {
|
|
10
|
+
if (!IN_POI) {
|
|
11
|
+
return new Promise(() => {
|
|
12
|
+
// Never resolve
|
|
13
|
+
})
|
|
14
|
+
}
|
|
15
|
+
return import(path)
|
|
16
|
+
}
|
package/src/poi/hooks.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { useState, useEffect } from 'react'
|
|
2
|
+
import { useTranslation } from 'react-i18next'
|
|
3
|
+
import { observePluginStore, observePoiStore } from './store'
|
|
4
|
+
import { name as PACKAGE_NAME } from '../../package.json'
|
|
5
|
+
import type { GameQuest, PoiQuestState, PoiState } from './types'
|
|
6
|
+
|
|
7
|
+
export const useActiveQuest = () => {
|
|
8
|
+
const [activeQuests, setActiveQuests] = useState<PoiQuestState>({})
|
|
9
|
+
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
const listener = (activeQuests: PoiQuestState) =>
|
|
12
|
+
setActiveQuests(activeQuests)
|
|
13
|
+
|
|
14
|
+
return observePoiStore(listener, activeQuestsSelector)
|
|
15
|
+
}, [])
|
|
16
|
+
|
|
17
|
+
return activeQuests
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const activeQuestsSelector = (state: PoiState): PoiQuestState =>
|
|
21
|
+
state?.info?.quests?.activeQuests ?? {}
|
|
22
|
+
|
|
23
|
+
export const usePluginTranslation = () => {
|
|
24
|
+
return useTranslation(PACKAGE_NAME)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export const useGameQuest = () => {
|
|
28
|
+
const [quests, setQuests] = useState<GameQuest[]>([])
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
const listener = (quests: GameQuest[] | null) => setQuests(quests ?? [])
|
|
31
|
+
// See reducer.ts
|
|
32
|
+
return observePluginStore(listener, (i) => i?._?.questList)
|
|
33
|
+
}, [])
|
|
34
|
+
return quests
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const UNKNOWN_TAB = 'unknown'
|
|
38
|
+
const useActiveTab = () => {
|
|
39
|
+
const [activeMainTab, setActiveMainTab] = useState<string>(UNKNOWN_TAB)
|
|
40
|
+
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
const listener = (activeMainTab: string) => setActiveMainTab(activeMainTab)
|
|
43
|
+
// poooi/poi/views/redux/ui.es
|
|
44
|
+
return observePoiStore(
|
|
45
|
+
listener,
|
|
46
|
+
(state) => state?.ui?.activeMainTab ?? UNKNOWN_TAB
|
|
47
|
+
)
|
|
48
|
+
}, [])
|
|
49
|
+
|
|
50
|
+
return activeMainTab
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export const useIsQuestPluginTab = () => {
|
|
54
|
+
const activeMainTab = useActiveTab()
|
|
55
|
+
return activeMainTab === PACKAGE_NAME
|
|
56
|
+
}
|
package/src/poi/store.ts
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { name as PACKAGE_NAME } from '../../package.json'
|
|
2
|
+
import type { PluginState } from '../reducer'
|
|
3
|
+
import { IN_POI, importFromPoi } from './env'
|
|
4
|
+
import type { PoiState, Store } from './types'
|
|
5
|
+
|
|
6
|
+
const noop = () => {}
|
|
7
|
+
const id = <T>(x: T) => x
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* See https://redux.js.org/api/store#subscribelistener
|
|
11
|
+
*/
|
|
12
|
+
const observeStore = <State, SelectedState = State>(
|
|
13
|
+
store: Store<State>,
|
|
14
|
+
onChange: (state: SelectedState) => void,
|
|
15
|
+
selector: (s: State) => SelectedState = id as any
|
|
16
|
+
) => {
|
|
17
|
+
let currentState: SelectedState
|
|
18
|
+
|
|
19
|
+
const handleChange = () => {
|
|
20
|
+
const nextState = selector(store.getState())
|
|
21
|
+
if (nextState !== currentState) {
|
|
22
|
+
currentState = nextState
|
|
23
|
+
onChange(currentState)
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const unsubscribe = store.subscribe(handleChange)
|
|
28
|
+
handleChange()
|
|
29
|
+
return unsubscribe
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export const observePoiStore = <SelectedState = PoiState>(
|
|
33
|
+
onChange: (state: SelectedState) => void,
|
|
34
|
+
selector: (state: PoiState) => SelectedState = id as any
|
|
35
|
+
) => {
|
|
36
|
+
let valid = true
|
|
37
|
+
let unsubscribe = noop
|
|
38
|
+
getPoiStore().then((store) => {
|
|
39
|
+
if (!valid) {
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
unsubscribe = observeStore(store, onChange, selector)
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
return () => {
|
|
46
|
+
valid = false
|
|
47
|
+
unsubscribe()
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export const observePluginStore = <SelectedState = PluginState>(
|
|
52
|
+
onChange: (state: SelectedState) => void,
|
|
53
|
+
selector: (state: PluginState) => SelectedState = id as any
|
|
54
|
+
) => observePoiStore(onChange, (s) => selector(s?.ext[PACKAGE_NAME]))
|
|
55
|
+
|
|
56
|
+
const fallbackStore: Store<PoiState> = {
|
|
57
|
+
getState: noop as () => PoiState,
|
|
58
|
+
subscribe: () => (() => {}) as () => () => void,
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
let globalStore: Store<PoiState> | null = null
|
|
62
|
+
/**
|
|
63
|
+
* Get poi global Store if in poi env
|
|
64
|
+
*/
|
|
65
|
+
export const getPoiStore: () => Promise<Store<PoiState>> = async () => {
|
|
66
|
+
if (globalStore !== null) {
|
|
67
|
+
return globalStore
|
|
68
|
+
}
|
|
69
|
+
if (IN_POI) {
|
|
70
|
+
try {
|
|
71
|
+
const { store } = await importFromPoi('views/create-store')
|
|
72
|
+
globalStore = store
|
|
73
|
+
return store
|
|
74
|
+
} catch (error) {
|
|
75
|
+
console.warn('Load global store error', error)
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
globalStore = fallbackStore
|
|
79
|
+
return fallbackStore
|
|
80
|
+
}
|
package/src/poi/types.ts
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import type { PluginState } from '../reducer'
|
|
2
|
+
|
|
3
|
+
export enum QUEST_API_STATE {
|
|
4
|
+
DEFAULT = 1,
|
|
5
|
+
IN_PROGRESS = 2,
|
|
6
|
+
COMPLETED = 3,
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// See https://github.com/poooi/poi/blob/master/views/redux/info/quests.es
|
|
10
|
+
export type GameQuest = {
|
|
11
|
+
api_state: QUEST_API_STATE
|
|
12
|
+
api_no: number
|
|
13
|
+
api_title: string
|
|
14
|
+
api_detail: string
|
|
15
|
+
/**
|
|
16
|
+
* 任务类别
|
|
17
|
+
*
|
|
18
|
+
* 1. Composition
|
|
19
|
+
* 1. Sortie
|
|
20
|
+
* 1. Exercise
|
|
21
|
+
* 1. Expedition
|
|
22
|
+
* 1. Supply/Docking
|
|
23
|
+
* 1. Arsenal
|
|
24
|
+
* 1. Modernization
|
|
25
|
+
*
|
|
26
|
+
* @see https://github.com/poooi/plugin-quest/blob/master/index.es#L49-L57
|
|
27
|
+
*/
|
|
28
|
+
api_category: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
|
|
29
|
+
/**
|
|
30
|
+
* 任务类型
|
|
31
|
+
*
|
|
32
|
+
* 1. One-time
|
|
33
|
+
* 1. Daily
|
|
34
|
+
* 1. Weekly
|
|
35
|
+
* 1. -3rd/-7th/-0th
|
|
36
|
+
* 1. -2nd/-8th
|
|
37
|
+
* 1. Monthly
|
|
38
|
+
* 1. Quarterly
|
|
39
|
+
*
|
|
40
|
+
* @see https://github.com/poooi/plugin-quest/blob/master/index.es#L69-L77
|
|
41
|
+
*/
|
|
42
|
+
api_type: 1 | 2 | 3 | 4 | 5 | 6 | 7
|
|
43
|
+
// Rewards 油弹钢铝
|
|
44
|
+
api_get_material: [number, number, number, number]
|
|
45
|
+
api_invalid_flag: 0
|
|
46
|
+
api_label_type: 1
|
|
47
|
+
// 0: Empty: [0.0, 0.5)
|
|
48
|
+
// 1: 50%: [0.5, 0.8)
|
|
49
|
+
// 2: 80%: [0.8, 1.0)
|
|
50
|
+
api_progress_flag: 0 | 1 | 2
|
|
51
|
+
api_select_rewards?: [
|
|
52
|
+
{
|
|
53
|
+
api_count: number
|
|
54
|
+
api_kind: number
|
|
55
|
+
api_mst_id: number
|
|
56
|
+
api_no: number
|
|
57
|
+
}[]
|
|
58
|
+
]
|
|
59
|
+
api_voice_id: 0
|
|
60
|
+
api_bonus_flag: 1
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
type QuestListAction = {
|
|
64
|
+
type: '@@Response/kcsapi/api_get_member/questlist'
|
|
65
|
+
path: '/kcsapi/api_get_member/questlist'
|
|
66
|
+
postBody: {
|
|
67
|
+
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
|
|
76
|
+
}
|
|
77
|
+
body: {
|
|
78
|
+
api_completed_kind: number
|
|
79
|
+
// api_list.length
|
|
80
|
+
api_count: number
|
|
81
|
+
// In progress count
|
|
82
|
+
api_exec_count: number
|
|
83
|
+
api_exec_type: number
|
|
84
|
+
api_list: GameQuest[]
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
type OtherAction = {
|
|
89
|
+
type: 'otherString' // TODO fix me
|
|
90
|
+
path?: string
|
|
91
|
+
postBody?: unknown
|
|
92
|
+
body?: unknown
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export type PoiAction = QuestListAction | OtherAction
|
|
96
|
+
|
|
97
|
+
export type PoiState = {
|
|
98
|
+
ui: {
|
|
99
|
+
activeMainTab: string
|
|
100
|
+
activeFleetId?: number
|
|
101
|
+
activePluginName?: string
|
|
102
|
+
}
|
|
103
|
+
ext: {
|
|
104
|
+
// TODO fix use constant PACKAGE_NAME
|
|
105
|
+
[packageName: string]: PluginState
|
|
106
|
+
}
|
|
107
|
+
plugins: { id: string; enabled: boolean; [x: string]: unknown }[]
|
|
108
|
+
[x: string]: any
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export type Store<S> = {
|
|
112
|
+
getState: () => S
|
|
113
|
+
subscribe: (listener: () => void) => () => void
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// state.info.quests.activeQuests
|
|
117
|
+
export type PoiQuestState = Record<number, { time: number; detail: GameQuest }>
|
package/src/questHelper.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { QuestData } from '../build/kcanotifyGamedata'
|
|
2
|
+
import { GameQuest, QUEST_API_STATE } from './poi/types'
|
|
2
3
|
|
|
3
|
-
type
|
|
4
|
+
type DocQuest = {
|
|
4
5
|
code: string
|
|
5
6
|
name: string
|
|
6
7
|
desc: string
|
|
@@ -9,9 +10,10 @@ type KcanotifyQuest = {
|
|
|
9
10
|
tracking?: number[][]
|
|
10
11
|
}
|
|
11
12
|
|
|
12
|
-
export type
|
|
13
|
+
export type UnionQuest = {
|
|
13
14
|
gameId: string
|
|
14
|
-
|
|
15
|
+
gameQuest?: GameQuest
|
|
16
|
+
docQuest: DocQuest
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
const questStartsFilter = (str: string) =>
|
|
@@ -26,16 +28,18 @@ export const quarterlyQuest = questStartsFilter('(季任)')
|
|
|
26
28
|
// (年任) (年任 / x 月)
|
|
27
29
|
export const yearlyQuest = questStartsFilter('(年任')
|
|
28
30
|
|
|
29
|
-
export const isInProgressQuest = (quest:
|
|
30
|
-
|
|
31
|
+
export const isInProgressQuest = (quest: UnionQuest) =>
|
|
32
|
+
quest.gameQuest?.api_state === QUEST_API_STATE.IN_PROGRESS ||
|
|
33
|
+
quest.gameQuest?.api_state === QUEST_API_STATE.COMPLETED
|
|
34
|
+
export const isDailyQuest = (quest: UnionQuest) =>
|
|
31
35
|
dailyQuest.includes(quest.gameId)
|
|
32
|
-
export const isWeeklyQuest = (quest:
|
|
36
|
+
export const isWeeklyQuest = (quest: UnionQuest) =>
|
|
33
37
|
weeklyQuest.includes(quest.gameId)
|
|
34
|
-
export const isMonthlyQuest = (quest:
|
|
38
|
+
export const isMonthlyQuest = (quest: UnionQuest) =>
|
|
35
39
|
monthlyQuest.includes(quest.gameId)
|
|
36
|
-
export const isQuarterlyQuest = (quest:
|
|
40
|
+
export const isQuarterlyQuest = (quest: UnionQuest) =>
|
|
37
41
|
quarterlyQuest.includes(quest.gameId)
|
|
38
|
-
export const isYearlyQuest = (quest:
|
|
42
|
+
export const isYearlyQuest = (quest: UnionQuest) =>
|
|
39
43
|
yearlyQuest.includes(quest.gameId)
|
|
40
44
|
|
|
41
45
|
export enum QUEST_CATEGORY {
|
|
@@ -154,28 +158,28 @@ export const guessQuestCategory = (
|
|
|
154
158
|
}
|
|
155
159
|
}
|
|
156
160
|
|
|
157
|
-
export const isCompositionQuest = ({ code }:
|
|
161
|
+
export const isCompositionQuest = ({ code }: DocQuest) =>
|
|
158
162
|
guessQuestCategory(code).type === QUEST_CATEGORY.Composition
|
|
159
|
-
export const isSortieQuest = ({ code }:
|
|
163
|
+
export const isSortieQuest = ({ code }: DocQuest) =>
|
|
160
164
|
guessQuestCategory(code).type === QUEST_CATEGORY.Sortie
|
|
161
|
-
export const isExerciseQuest = ({ code }:
|
|
165
|
+
export const isExerciseQuest = ({ code }: DocQuest) =>
|
|
162
166
|
guessQuestCategory(code).type === QUEST_CATEGORY.Exercise
|
|
163
|
-
export const isExpeditionQuest = ({ code }:
|
|
167
|
+
export const isExpeditionQuest = ({ code }: DocQuest) =>
|
|
164
168
|
guessQuestCategory(code).type === QUEST_CATEGORY.Expedition
|
|
165
|
-
export const isSupplyOrDockingQuest = ({ code }:
|
|
169
|
+
export const isSupplyOrDockingQuest = ({ code }: DocQuest) =>
|
|
166
170
|
guessQuestCategory(code).type === QUEST_CATEGORY.SupplyOrDocking
|
|
167
|
-
export const isArsenalQuest = ({ code }:
|
|
171
|
+
export const isArsenalQuest = ({ code }: DocQuest) =>
|
|
168
172
|
guessQuestCategory(code).type === QUEST_CATEGORY.Arsenal
|
|
169
|
-
export const isModernizationQuest = ({ code }:
|
|
173
|
+
export const isModernizationQuest = ({ code }: DocQuest) =>
|
|
170
174
|
guessQuestCategory(code).type === QUEST_CATEGORY.Modernization
|
|
171
|
-
export const isUnknownCategoryQuest = ({ code }:
|
|
175
|
+
export const isUnknownCategoryQuest = ({ code }: DocQuest) =>
|
|
172
176
|
// Starts with unknown character
|
|
173
177
|
/^[^ABCDEFG]/.test(code)
|
|
174
178
|
|
|
175
179
|
export enum QUEST_STATUS {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
180
|
+
LOCKED,
|
|
181
|
+
DEFAULT,
|
|
182
|
+
IN_PROGRESS,
|
|
183
|
+
COMPLETED,
|
|
184
|
+
ALREADY_COMPLETED,
|
|
181
185
|
}
|
package/src/reducer.ts
CHANGED