poi-plugin-quest-info-2 0.5.10 → 0.6.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/.eslintrc.js +1 -1
- package/build/assets.ts +2 -1
- package/build/kcQuestsData/DATA_VERSION +1 -1
- package/build/kcQuestsData/index.ts +1 -1
- package/build/kcQuestsData/quests-scn.json +1123 -1066
- package/build/kcanotifyGamedata/DATA_VERSION +1 -1
- package/build/kcanotifyGamedata/index.ts +1 -1
- package/build/kcanotifyGamedata/quests-en.json +60 -36
- package/build/kcanotifyGamedata/quests-jp.json +506 -482
- package/build/kcanotifyGamedata/quests-ko.json +101 -77
- package/build/kcanotifyGamedata/quests-scn.json +274 -251
- package/build/kcanotifyGamedata/quests-tcn.json +274 -251
- package/build/questCategory.json +600 -0
- package/i18n/en-US.json +4 -2
- package/i18n/ja-JP.json +3 -1
- package/i18n/ko-KR.json +1 -0
- package/i18n/zh-CN.json +3 -1
- package/i18n/zh-TW.json +2 -0
- package/package.json +4 -3
- package/scripts/convertAssets.ts +3 -2
- package/scripts/downloadKcQuestsData.ts +11 -3
- package/scripts/downloadKcanotifyGamedata.ts +10 -2
- package/scripts/genQuestCategory.ts +58 -0
- package/src/Toolbar.tsx +42 -37
- package/src/__tests__/__snapshots__/questCategory.spec.ts.snap +582 -0
- package/src/__tests__/kcanotifyData.spec.ts +1 -1
- package/src/__tests__/kcwikiData.spec.ts +1 -1
- package/src/__tests__/questCategory.spec.ts +37 -0
- package/src/components/PreTaskTag.tsx +40 -0
- package/src/components/QuestCard/MinimalQuestCard.tsx +48 -0
- package/src/components/QuestCard/index.tsx +71 -0
- package/src/components/QuestCard/styles.ts +42 -0
- package/src/components/QuestCard/utils.tsx +68 -0
- package/src/components/QuestList.tsx +2 -1
- package/src/questHelper.ts +24 -18
- package/src/store/filterTags.ts +44 -0
- package/src/store/quest.ts +3 -0
- package/src/store/search.ts +17 -0
- package/src/store/store.tsx +25 -2
- package/src/tags.ts +2 -1
- package/src/components/QuestCard.tsx +0 -213
package/scripts/convertAssets.ts
CHANGED
|
@@ -7,13 +7,14 @@ const OUTPUT_PATH = path.resolve('build')
|
|
|
7
7
|
const OUTPUT_FILE = path.resolve(OUTPUT_PATH, 'assets.ts')
|
|
8
8
|
const CONVERT_EXTS = ['jpg', 'png'] as const
|
|
9
9
|
|
|
10
|
-
const HEADER =
|
|
10
|
+
const HEADER = `/* eslint-disable prettier/prettier */
|
|
11
|
+
/**
|
|
11
12
|
* This file was automatically generated by \`${path.relative(
|
|
12
13
|
// project root
|
|
13
14
|
process.cwd(),
|
|
14
15
|
__filename
|
|
15
16
|
)}\`
|
|
16
|
-
* Do not edit
|
|
17
|
+
* Do not edit this file directly.
|
|
17
18
|
*/` as const
|
|
18
19
|
|
|
19
20
|
function base64Encode(file: string) {
|
|
@@ -14,7 +14,7 @@ const VERSION_URL =
|
|
|
14
14
|
'https://api.github.com/repos/kcwikizh/kcQuests/branches/main'
|
|
15
15
|
|
|
16
16
|
// expired quest: 2021 节分任务
|
|
17
|
-
const IGNORE_DATA = [840, 841, 842, 843] as const
|
|
17
|
+
const IGNORE_DATA = [329, 441, 840, 841, 842, 843] as const
|
|
18
18
|
|
|
19
19
|
const getRemoteVersion = async () => {
|
|
20
20
|
const resp = await fetch(VERSION_URL)
|
|
@@ -80,12 +80,20 @@ const main = async () => {
|
|
|
80
80
|
text = text.trim()
|
|
81
81
|
|
|
82
82
|
const json = JSON.parse(text) as {
|
|
83
|
-
[gameId: string]: {
|
|
83
|
+
[gameId: string]: {
|
|
84
|
+
code: string
|
|
85
|
+
name: string
|
|
86
|
+
desc: string
|
|
87
|
+
memo?: string
|
|
88
|
+
}
|
|
84
89
|
}
|
|
85
90
|
for (const gameId in json) {
|
|
86
|
-
const { name, desc } = json[gameId]
|
|
91
|
+
const { name, desc, memo } = json[gameId]
|
|
87
92
|
json[gameId].name = pangu.spacing(name)
|
|
88
93
|
json[gameId].desc = pangu.spacing(desc)
|
|
94
|
+
if (memo) {
|
|
95
|
+
json[gameId].memo = pangu.spacing(memo)
|
|
96
|
+
}
|
|
89
97
|
}
|
|
90
98
|
|
|
91
99
|
IGNORE_DATA.forEach((gameId) => delete json[gameId])
|
|
@@ -97,12 +97,20 @@ const main = async () => {
|
|
|
97
97
|
text = text.trim()
|
|
98
98
|
|
|
99
99
|
const json = JSON.parse(text) as {
|
|
100
|
-
[gameId: string]: {
|
|
100
|
+
[gameId: string]: {
|
|
101
|
+
code: string
|
|
102
|
+
name: string
|
|
103
|
+
desc: string
|
|
104
|
+
memo?: string
|
|
105
|
+
}
|
|
101
106
|
}
|
|
102
107
|
for (const gameId in json) {
|
|
103
|
-
const { name, desc } = json[gameId]
|
|
108
|
+
const { name, desc, memo } = json[gameId]
|
|
104
109
|
json[gameId].name = pangu.spacing(name)
|
|
105
110
|
json[gameId].desc = pangu.spacing(desc)
|
|
111
|
+
if (memo) {
|
|
112
|
+
json[gameId].memo = pangu.spacing(memo)
|
|
113
|
+
}
|
|
106
114
|
}
|
|
107
115
|
|
|
108
116
|
const data = JSON.stringify(json, undefined, 2)
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { writeFileSync } from 'fs'
|
|
2
|
+
import path from 'path'
|
|
3
|
+
import { QuestData } from '../build/kcanotifyGamedata'
|
|
4
|
+
import { KcwikiQuestData } from '../build/kcQuestsData'
|
|
5
|
+
|
|
6
|
+
const OUTPUT_PATH = path.resolve('build', 'questCategory.json')
|
|
7
|
+
|
|
8
|
+
const questStartsFilter = (str: string) =>
|
|
9
|
+
Object.entries(QuestData['zh-CN'])
|
|
10
|
+
.filter(([, quest]) => quest.name.startsWith(str))
|
|
11
|
+
.map(([gameId]) => gameId)
|
|
12
|
+
|
|
13
|
+
const kcwikiDataSelector = () => Object.entries(KcwikiQuestData['zh-CN'])
|
|
14
|
+
const mergeDataSelector = () =>
|
|
15
|
+
Object.entries({ ...QuestData['zh-CN'], ...KcwikiQuestData['zh-CN'] })
|
|
16
|
+
|
|
17
|
+
const main = () => {
|
|
18
|
+
const dailyQuest = questStartsFilter('(日任)')
|
|
19
|
+
const weeklyQuest = questStartsFilter('(周任)')
|
|
20
|
+
const monthlyQuest = questStartsFilter('(月任)')
|
|
21
|
+
const quarterlyQuest = [
|
|
22
|
+
...new Set([
|
|
23
|
+
...questStartsFilter('(季任)'),
|
|
24
|
+
...kcwikiDataSelector()
|
|
25
|
+
.filter(([, quest]) => quest.desc.includes('季常任务'))
|
|
26
|
+
.map(([gameId]) => gameId),
|
|
27
|
+
]),
|
|
28
|
+
].sort((a, b) => +a - +b)
|
|
29
|
+
// (年任) (年任 / x 月)
|
|
30
|
+
const yearlyQuest = kcwikiDataSelector()
|
|
31
|
+
.filter(([, quest]) => quest.desc.includes('❀备注:年常任务'))
|
|
32
|
+
.map(([gameId]) => gameId)
|
|
33
|
+
const singleQuest = mergeDataSelector()
|
|
34
|
+
.filter(
|
|
35
|
+
([gameId]) =>
|
|
36
|
+
![
|
|
37
|
+
...dailyQuest,
|
|
38
|
+
...weeklyQuest,
|
|
39
|
+
...monthlyQuest,
|
|
40
|
+
...quarterlyQuest,
|
|
41
|
+
...yearlyQuest,
|
|
42
|
+
].includes(gameId)
|
|
43
|
+
)
|
|
44
|
+
.map(([gameId]) => gameId)
|
|
45
|
+
|
|
46
|
+
const data = {
|
|
47
|
+
dailyQuest,
|
|
48
|
+
weeklyQuest,
|
|
49
|
+
monthlyQuest,
|
|
50
|
+
quarterlyQuest,
|
|
51
|
+
yearlyQuest,
|
|
52
|
+
singleQuest,
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
writeFileSync(OUTPUT_PATH, JSON.stringify(data, null, 2))
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
main()
|
package/src/Toolbar.tsx
CHANGED
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
import { Button, InputGroup, Intent, Tag, Tooltip } from '@blueprintjs/core'
|
|
2
2
|
import { IconNames } from '@blueprintjs/icons'
|
|
3
|
-
import styled from 'styled-components'
|
|
4
|
-
import React, { useCallback } from 'react'
|
|
5
3
|
import type { ChangeEvent } from 'react'
|
|
4
|
+
import React, { useCallback } from 'react'
|
|
6
5
|
import { useThrottle } from 'react-use'
|
|
7
|
-
import
|
|
6
|
+
import styled from 'styled-components'
|
|
7
|
+
import { IN_POI } from './poi/env'
|
|
8
|
+
import { usePluginTranslation } from './poi/hooks'
|
|
9
|
+
import type { UnionQuest } from './questHelper'
|
|
10
|
+
import { useQuest, useSyncWithGame } from './store'
|
|
11
|
+
import { useFilterTags } from './store/filterTags'
|
|
12
|
+
import { useSearchInput } from './store/search'
|
|
8
13
|
import {
|
|
9
|
-
ALL_TYPE_TAG,
|
|
10
14
|
ALL_CATEGORY_TAG,
|
|
11
|
-
TYPE_TAGS,
|
|
12
|
-
CATEGORY_TAGS,
|
|
13
15
|
ALL_TAGS,
|
|
16
|
+
ALL_TYPE_TAG,
|
|
17
|
+
CATEGORY_TAGS,
|
|
18
|
+
TYPE_TAGS,
|
|
14
19
|
} from './tags'
|
|
15
|
-
import type { UnionQuest } from './questHelper'
|
|
16
|
-
import { usePluginTranslation } from './poi/hooks'
|
|
17
|
-
import { IN_POI } from './poi/env'
|
|
18
20
|
|
|
19
21
|
const ToolbarWrapper = styled.div`
|
|
20
22
|
display: flex;
|
|
@@ -37,18 +39,21 @@ const TagsWrapper = styled.div`
|
|
|
37
39
|
|
|
38
40
|
const SyncButton = () => {
|
|
39
41
|
const { t } = usePluginTranslation()
|
|
40
|
-
const {
|
|
41
|
-
|
|
42
|
-
updateStore,
|
|
43
|
-
} = useStore()
|
|
42
|
+
const { searchInput } = useSearchInput()
|
|
43
|
+
const { syncWithGame, toggleSyncWithGame } = useSyncWithGame()
|
|
44
44
|
const handleClick = useCallback(() => {
|
|
45
|
-
|
|
46
|
-
}, [
|
|
45
|
+
toggleSyncWithGame()
|
|
46
|
+
}, [toggleSyncWithGame])
|
|
47
|
+
const intent = syncWithGame
|
|
48
|
+
? searchInput
|
|
49
|
+
? Intent.WARNING
|
|
50
|
+
: Intent.SUCCESS
|
|
51
|
+
: Intent.NONE
|
|
47
52
|
return (
|
|
48
53
|
<Tooltip content={t('Sync with game')}>
|
|
49
54
|
<Button
|
|
50
55
|
icon={IconNames.EXCHANGE}
|
|
51
|
-
intent={
|
|
56
|
+
intent={intent}
|
|
52
57
|
disabled={!IN_POI}
|
|
53
58
|
onClick={handleClick}
|
|
54
59
|
/>
|
|
@@ -58,24 +63,30 @@ const SyncButton = () => {
|
|
|
58
63
|
|
|
59
64
|
export const SearchInput: React.FC = () => {
|
|
60
65
|
const { t } = usePluginTranslation()
|
|
61
|
-
const {
|
|
62
|
-
store: { searchInput },
|
|
63
|
-
updateStore,
|
|
64
|
-
} = useStore()
|
|
66
|
+
const { searchInput, setSearchInput } = useSearchInput()
|
|
65
67
|
|
|
66
68
|
const handleChange = useCallback(
|
|
67
69
|
(event: ChangeEvent<HTMLInputElement>) =>
|
|
68
|
-
|
|
69
|
-
[
|
|
70
|
+
setSearchInput(event.target.value),
|
|
71
|
+
[setSearchInput]
|
|
70
72
|
)
|
|
71
73
|
|
|
74
|
+
const handleClear = useCallback(() => setSearchInput(''), [setSearchInput])
|
|
75
|
+
|
|
72
76
|
return (
|
|
73
77
|
<InputGroup
|
|
74
78
|
value={searchInput}
|
|
75
79
|
onChange={handleChange}
|
|
76
80
|
placeholder={t('Search')}
|
|
77
81
|
leftIcon={IconNames.SEARCH}
|
|
78
|
-
rightElement={
|
|
82
|
+
rightElement={
|
|
83
|
+
<>
|
|
84
|
+
{!!searchInput && (
|
|
85
|
+
<Button icon={IconNames.CROSS} onClick={handleClear} />
|
|
86
|
+
)}
|
|
87
|
+
<SyncButton></SyncButton>
|
|
88
|
+
</>
|
|
89
|
+
}
|
|
79
90
|
type="text"
|
|
80
91
|
/>
|
|
81
92
|
)
|
|
@@ -83,22 +94,16 @@ export const SearchInput: React.FC = () => {
|
|
|
83
94
|
|
|
84
95
|
const Tags = () => {
|
|
85
96
|
const { t } = usePluginTranslation()
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
} = useStore()
|
|
90
|
-
const withHandleClickTag = useCallback(
|
|
91
|
-
(tagName: string, key: 'typeTags' | 'categoryTags') => () =>
|
|
92
|
-
updateStore({ [key]: { [tagName]: true } }),
|
|
93
|
-
[updateStore]
|
|
94
|
-
)
|
|
97
|
+
|
|
98
|
+
const { typeTags, categoryTags, setCategoryTags, setTypeTags } =
|
|
99
|
+
useFilterTags()
|
|
95
100
|
|
|
96
101
|
return (
|
|
97
102
|
<>
|
|
98
103
|
<TagsWrapper>
|
|
99
104
|
{CATEGORY_TAGS.map(({ name }) => (
|
|
100
105
|
<Tag
|
|
101
|
-
onClick={
|
|
106
|
+
onClick={() => setCategoryTags(name)}
|
|
102
107
|
intent={
|
|
103
108
|
categoryTags[name]
|
|
104
109
|
? name === ALL_CATEGORY_TAG.name
|
|
@@ -116,7 +121,7 @@ const Tags = () => {
|
|
|
116
121
|
<TagsWrapper>
|
|
117
122
|
{TYPE_TAGS.map(({ name }) => (
|
|
118
123
|
<Tag
|
|
119
|
-
onClick={
|
|
124
|
+
onClick={() => setTypeTags(name)}
|
|
120
125
|
intent={
|
|
121
126
|
typeTags[name]
|
|
122
127
|
? name === ALL_TYPE_TAG.name
|
|
@@ -145,9 +150,9 @@ export const Toolbar = () => {
|
|
|
145
150
|
}
|
|
146
151
|
|
|
147
152
|
const useToolbarFilter = () => {
|
|
148
|
-
const {
|
|
149
|
-
|
|
150
|
-
|
|
153
|
+
const { searchInput } = useSearchInput()
|
|
154
|
+
const { typeTags, categoryTags } = useFilterTags()
|
|
155
|
+
|
|
151
156
|
const activatedTags = { ...typeTags, ...categoryTags }
|
|
152
157
|
const activatedTagsName = ALL_TAGS.filter((tag) => activatedTags[tag.name])
|
|
153
158
|
const tagsFilter = activatedTagsName.map((tag) => tag.filter)
|