poi-plugin-quest-info-2 0.5.12 → 0.6.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/.eslintrc.js +1 -1
- package/build/kcQuestsData/DATA_VERSION +1 -1
- package/build/kcQuestsData/index.ts +1 -1
- package/build/kcQuestsData/quests-scn.json +1121 -1047
- package/build/kcanotifyGamedata/DATA_VERSION +1 -1
- package/build/kcanotifyGamedata/index.ts +1 -1
- package/build/kcanotifyGamedata/quests-jp.json +457 -457
- package/build/kcanotifyGamedata/quests-ko.json +40 -40
- package/build/kcanotifyGamedata/quests-scn.json +225 -225
- package/build/kcanotifyGamedata/quests-tcn.json +225 -225
- package/i18n/en-US.json +2 -1
- package/i18n/ja-JP.json +2 -1
- package/i18n/ko-KR.json +1 -0
- package/i18n/zh-CN.json +2 -1
- package/i18n/zh-TW.json +1 -0
- package/package.json +2 -2
- package/scripts/downloadKcQuestsData.ts +10 -2
- package/scripts/downloadKcanotifyGamedata.ts +10 -2
- package/src/Toolbar.tsx +42 -37
- package/src/__tests__/kcanotifyData.spec.ts +1 -1
- package/src/__tests__/kcwikiData.spec.ts +1 -1
- 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 +1 -0
- package/src/store/filterTags.ts +44 -0
- package/src/store/search.ts +17 -0
- package/src/store/store.tsx +25 -2
- package/src/components/QuestCard.tsx +0 -213
package/i18n/en-US.json
CHANGED
|
@@ -20,11 +20,12 @@
|
|
|
20
20
|
"In Progress": "In Progress",
|
|
21
21
|
"Completed": "Completed",
|
|
22
22
|
"TotalQuests": "Total {{count}} quests",
|
|
23
|
-
"Sync with game": "Sync with game",
|
|
23
|
+
"Sync with game": "Sync with game (Show in-game quests only)",
|
|
24
24
|
"Version": "Version: {{version}}",
|
|
25
25
|
"Data Version": "Data Version: {{version}}",
|
|
26
26
|
"View source code on GitHub": "View source code on GitHub",
|
|
27
27
|
"Restore defaults": "Restore defaults",
|
|
28
28
|
"Use Kcwiki data": "Use Kcwiki's data (Simplified Chinese only)",
|
|
29
|
+
"Requires": "Requires",
|
|
29
30
|
"": ""
|
|
30
31
|
}
|
package/i18n/ja-JP.json
CHANGED
|
@@ -20,11 +20,12 @@
|
|
|
20
20
|
"In Progress": "進行中",
|
|
21
21
|
"Completed": "完了",
|
|
22
22
|
"TotalQuests": "全て {{count}} 個の任務",
|
|
23
|
-
"Sync with game": "
|
|
23
|
+
"Sync with game": "ゲームと連動(インゲームクエストのみ表示する)",
|
|
24
24
|
"Version": "バージョン: {{version}}",
|
|
25
25
|
"Data Version": "データ バージョン: {{version}}",
|
|
26
26
|
"View source code on GitHub": "GitHubでソースコードを表示",
|
|
27
27
|
"Restore defaults": "デフォルトに戻す",
|
|
28
28
|
"Use Kcwiki data": "Kcwikiのデータを利用する(簡体字中国語のみ)",
|
|
29
|
+
"Requires": "開放条件",
|
|
29
30
|
"": ""
|
|
30
31
|
}
|
package/i18n/ko-KR.json
CHANGED
package/i18n/zh-CN.json
CHANGED
|
@@ -20,11 +20,12 @@
|
|
|
20
20
|
"In Progress": "进行中",
|
|
21
21
|
"Completed": "已完成",
|
|
22
22
|
"TotalQuests": "一共 {{count}} 个任务",
|
|
23
|
-
"Sync with game": "
|
|
23
|
+
"Sync with game": "与游戏同步(仅展示游戏内任务)",
|
|
24
24
|
"Version": "版本: {{version}}",
|
|
25
25
|
"Data Version": "数据版本: {{version}}",
|
|
26
26
|
"View source code on GitHub": "去 GitHub 查看源码",
|
|
27
27
|
"Restore defaults": "恢复默认设置",
|
|
28
28
|
"Use Kcwiki data": "使用 Kcwiki 的数据",
|
|
29
|
+
"Requires": "前置",
|
|
29
30
|
"": ""
|
|
30
31
|
}
|
package/i18n/zh-TW.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "poi-plugin-quest-info-2",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "show quest info",
|
|
6
6
|
"homepage": "https://github.com/lawvs/poi-plugin-quest-2/",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@babel/core": "^7.12.10",
|
|
41
|
-
"@blueprintjs/core": "^3.
|
|
41
|
+
"@blueprintjs/core": "^3.52.0",
|
|
42
42
|
"@storybook/addon-actions": "^6.3.4",
|
|
43
43
|
"@storybook/addon-essentials": "^6.3.4",
|
|
44
44
|
"@storybook/addon-links": "^6.3.4",
|
|
@@ -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)
|
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)
|
|
@@ -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(`"
|
|
4
|
+
expect(version).toMatchInlineSnapshot(`"2022020101"`)
|
|
5
5
|
})
|
|
6
6
|
|
|
7
7
|
test('should Kcanotify Game data keys correct', () => {
|
|
@@ -2,7 +2,7 @@ import { version, KcwikiQuestData } from '../../build/kcQuestsData'
|
|
|
2
2
|
|
|
3
3
|
test('should KcwikiQuestData Game data version correct', () => {
|
|
4
4
|
expect(version).toMatchInlineSnapshot(
|
|
5
|
-
`"
|
|
5
|
+
`"56b37a6d0a5ee58e8b88be58f7d7efff31ac6e28"`
|
|
6
6
|
)
|
|
7
7
|
})
|
|
8
8
|
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Tag } from '@blueprintjs/core'
|
|
2
|
+
import React, { useCallback } from 'react'
|
|
3
|
+
import styled from 'styled-components'
|
|
4
|
+
import { guessQuestCategory } from '../questHelper'
|
|
5
|
+
import { useFilterTags } from '../store/filterTags'
|
|
6
|
+
import { useSearchInput } from '../store/search'
|
|
7
|
+
|
|
8
|
+
const TagWrapper = styled(Tag)`
|
|
9
|
+
margin: 0 4px;
|
|
10
|
+
user-select: none;
|
|
11
|
+
|
|
12
|
+
& > span {
|
|
13
|
+
cursor: pointer;
|
|
14
|
+
}
|
|
15
|
+
`
|
|
16
|
+
|
|
17
|
+
export const PreTaskTag = ({ code }: { code: string }) => {
|
|
18
|
+
const { setSearchInput } = useSearchInput()
|
|
19
|
+
const { setCategoryTagsAll, setTypeTagsAll } = useFilterTags()
|
|
20
|
+
|
|
21
|
+
const handleClick = useCallback(() => {
|
|
22
|
+
setSearchInput(code)
|
|
23
|
+
setCategoryTagsAll()
|
|
24
|
+
setTypeTagsAll()
|
|
25
|
+
}, [code, setCategoryTagsAll, setSearchInput, setTypeTagsAll])
|
|
26
|
+
const indicatorColor = guessQuestCategory(code).color
|
|
27
|
+
const fontColor =
|
|
28
|
+
indicatorColor === '#fff' || indicatorColor === '#87da61'
|
|
29
|
+
? 'black'
|
|
30
|
+
: 'white'
|
|
31
|
+
return (
|
|
32
|
+
<TagWrapper
|
|
33
|
+
onClick={handleClick}
|
|
34
|
+
interactive
|
|
35
|
+
style={{ color: fontColor, background: indicatorColor }}
|
|
36
|
+
>
|
|
37
|
+
{code}
|
|
38
|
+
</TagWrapper>
|
|
39
|
+
)
|
|
40
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Elevation, Text, Tooltip } from '@blueprintjs/core'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
import { guessQuestCategory, QUEST_STATUS } from '../../questHelper'
|
|
4
|
+
import type { QuestCardProps } from './index'
|
|
5
|
+
import { CardBody, CardTail, CatIndicator, FlexCard } from './styles'
|
|
6
|
+
import { questStatusMap } from './utils'
|
|
7
|
+
|
|
8
|
+
export const MinimalQuestCard: React.FC<QuestCardProps> = ({
|
|
9
|
+
code,
|
|
10
|
+
name,
|
|
11
|
+
desc,
|
|
12
|
+
tips,
|
|
13
|
+
status = QUEST_STATUS.DEFAULT,
|
|
14
|
+
onClick,
|
|
15
|
+
style,
|
|
16
|
+
}) => {
|
|
17
|
+
const indicatorColor = guessQuestCategory(code).color
|
|
18
|
+
const TailIcon = questStatusMap[status]
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<Tooltip
|
|
22
|
+
targetTagName="div"
|
|
23
|
+
content={
|
|
24
|
+
<>
|
|
25
|
+
{desc}
|
|
26
|
+
<br />
|
|
27
|
+
{tips}
|
|
28
|
+
</>
|
|
29
|
+
}
|
|
30
|
+
>
|
|
31
|
+
<FlexCard
|
|
32
|
+
elevation={Elevation.ZERO}
|
|
33
|
+
interactive={true}
|
|
34
|
+
onClick={onClick}
|
|
35
|
+
style={style}
|
|
36
|
+
>
|
|
37
|
+
<CatIndicator color={indicatorColor}></CatIndicator>
|
|
38
|
+
<CardBody>
|
|
39
|
+
<Text>{[code, name].filter((i) => i != undefined).join(' - ')}</Text>
|
|
40
|
+
</CardBody>
|
|
41
|
+
|
|
42
|
+
<CardTail>
|
|
43
|
+
<TailIcon></TailIcon>
|
|
44
|
+
</CardTail>
|
|
45
|
+
</FlexCard>
|
|
46
|
+
</Tooltip>
|
|
47
|
+
)
|
|
48
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Elevation, H5, Text } from '@blueprintjs/core'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
import styled from 'styled-components'
|
|
4
|
+
import { usePluginTranslation } from '../../poi/hooks'
|
|
5
|
+
import { guessQuestCategory, QUEST_STATUS } from '../../questHelper'
|
|
6
|
+
import { PreTaskTag } from '../PreTaskTag'
|
|
7
|
+
import { CardBody, CardMedia, CardTail, FlexCard } from './styles'
|
|
8
|
+
import { questIconMap, questStatusMap } from './utils'
|
|
9
|
+
|
|
10
|
+
export type QuestCardProps = {
|
|
11
|
+
code: string
|
|
12
|
+
name: string
|
|
13
|
+
desc: string | JSX.Element
|
|
14
|
+
tips?: string
|
|
15
|
+
status?: QUEST_STATUS
|
|
16
|
+
preTask?: string[]
|
|
17
|
+
onClick?: (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => void
|
|
18
|
+
style?: React.CSSProperties
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const PreTaskTagWrapper = styled.div`
|
|
22
|
+
display: flex;
|
|
23
|
+
align-items: baseline;
|
|
24
|
+
`
|
|
25
|
+
|
|
26
|
+
export const LargeQuestCard = ({
|
|
27
|
+
code,
|
|
28
|
+
name,
|
|
29
|
+
desc,
|
|
30
|
+
tips,
|
|
31
|
+
preTask,
|
|
32
|
+
status = QUEST_STATUS.DEFAULT,
|
|
33
|
+
onClick,
|
|
34
|
+
style,
|
|
35
|
+
}: QuestCardProps) => {
|
|
36
|
+
const headIcon = questIconMap[guessQuestCategory(code).type]
|
|
37
|
+
const TailIcon = questStatusMap[status]
|
|
38
|
+
const { t } = usePluginTranslation()
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<FlexCard
|
|
42
|
+
elevation={Elevation.ZERO}
|
|
43
|
+
interactive={false}
|
|
44
|
+
onClick={onClick}
|
|
45
|
+
style={style}
|
|
46
|
+
>
|
|
47
|
+
<CardMedia src={headIcon}></CardMedia>
|
|
48
|
+
<CardBody>
|
|
49
|
+
<H5>{[code, name].filter((i) => i != undefined).join(' - ')}</H5>
|
|
50
|
+
<Text>{desc}</Text>
|
|
51
|
+
{tips && <Text tagName="i">{tips}</Text>}
|
|
52
|
+
<PreTaskTagWrapper>
|
|
53
|
+
{!!preTask?.length && <Text tagName="span">{t('Requires')}</Text>}
|
|
54
|
+
{preTask?.map((i) => (
|
|
55
|
+
<PreTaskTag key={i} code={i}></PreTaskTag>
|
|
56
|
+
))}
|
|
57
|
+
</PreTaskTagWrapper>
|
|
58
|
+
</CardBody>
|
|
59
|
+
|
|
60
|
+
<CardTail>
|
|
61
|
+
<TailIcon />
|
|
62
|
+
</CardTail>
|
|
63
|
+
</FlexCard>
|
|
64
|
+
)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export const QuestCard: React.FC<QuestCardProps & { gameId: string }> = ({
|
|
68
|
+
...props
|
|
69
|
+
}) => {
|
|
70
|
+
return <LargeQuestCard {...props}></LargeQuestCard>
|
|
71
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Card } from '@blueprintjs/core'
|
|
2
|
+
import styled from 'styled-components'
|
|
3
|
+
|
|
4
|
+
export const FlexCard = styled(Card)`
|
|
5
|
+
display: flex;
|
|
6
|
+
align-items: center;
|
|
7
|
+
|
|
8
|
+
& > * + * {
|
|
9
|
+
margin-left: 8px;
|
|
10
|
+
}
|
|
11
|
+
`
|
|
12
|
+
|
|
13
|
+
export const CardMedia = styled.img`
|
|
14
|
+
width: 64px;
|
|
15
|
+
height: 64px;
|
|
16
|
+
`
|
|
17
|
+
|
|
18
|
+
export const CatIndicator = styled.span<{ color: string }>`
|
|
19
|
+
height: 1em;
|
|
20
|
+
width: 4px;
|
|
21
|
+
background-color: ${({ color }) => color};
|
|
22
|
+
`
|
|
23
|
+
|
|
24
|
+
export const CardBody = styled.div`
|
|
25
|
+
display: flex;
|
|
26
|
+
flex: 1;
|
|
27
|
+
flex-direction: column;
|
|
28
|
+
|
|
29
|
+
& > * + * {
|
|
30
|
+
margin-top: 8px;
|
|
31
|
+
}
|
|
32
|
+
`
|
|
33
|
+
|
|
34
|
+
export const CardTail = styled.div`
|
|
35
|
+
display: flex;
|
|
36
|
+
justify-content: center;
|
|
37
|
+
align-items: center;
|
|
38
|
+
|
|
39
|
+
img {
|
|
40
|
+
height: 20px;
|
|
41
|
+
}
|
|
42
|
+
`
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { Icon, Tooltip } from '@blueprintjs/core'
|
|
2
|
+
import { IconNames } from '@blueprintjs/icons'
|
|
3
|
+
import React from 'react'
|
|
4
|
+
import {
|
|
5
|
+
IconArsenal,
|
|
6
|
+
IconCompleted,
|
|
7
|
+
IconComposition,
|
|
8
|
+
IconExercise,
|
|
9
|
+
IconExpedition,
|
|
10
|
+
IconInProgress,
|
|
11
|
+
IconModernization,
|
|
12
|
+
IconSortie,
|
|
13
|
+
IconSupplyDocking,
|
|
14
|
+
} from '../../../build/assets'
|
|
15
|
+
import { usePluginTranslation } from '../../poi/hooks'
|
|
16
|
+
import { QUEST_CATEGORY, QUEST_STATUS } from '../../questHelper'
|
|
17
|
+
|
|
18
|
+
export const questStatusMap: Record<QUEST_STATUS, React.FC> = {
|
|
19
|
+
[QUEST_STATUS.LOCKED]: function Locked() {
|
|
20
|
+
const { t } = usePluginTranslation()
|
|
21
|
+
return (
|
|
22
|
+
<Tooltip content={t('Locked')}>
|
|
23
|
+
<Icon icon={IconNames.LOCK} iconSize={Icon.SIZE_LARGE}></Icon>
|
|
24
|
+
</Tooltip>
|
|
25
|
+
)
|
|
26
|
+
},
|
|
27
|
+
// Display nothing
|
|
28
|
+
[QUEST_STATUS.DEFAULT]: () => null,
|
|
29
|
+
[QUEST_STATUS.IN_PROGRESS]: function InProgress() {
|
|
30
|
+
const { t } = usePluginTranslation()
|
|
31
|
+
return (
|
|
32
|
+
<Tooltip content={t('In Progress')}>
|
|
33
|
+
<img src={IconInProgress}></img>
|
|
34
|
+
</Tooltip>
|
|
35
|
+
)
|
|
36
|
+
},
|
|
37
|
+
[QUEST_STATUS.COMPLETED]: function Completed() {
|
|
38
|
+
const { t } = usePluginTranslation()
|
|
39
|
+
return (
|
|
40
|
+
<Tooltip content={t('Completed')}>
|
|
41
|
+
<img src={IconCompleted}></img>
|
|
42
|
+
</Tooltip>
|
|
43
|
+
)
|
|
44
|
+
},
|
|
45
|
+
[QUEST_STATUS.ALREADY_COMPLETED]: function AlreadyCompleted() {
|
|
46
|
+
const { t } = usePluginTranslation()
|
|
47
|
+
return (
|
|
48
|
+
<Tooltip content={t('Already Completed')}>
|
|
49
|
+
<Icon icon={IconNames.TICK} iconSize={Icon.SIZE_LARGE}></Icon>
|
|
50
|
+
</Tooltip>
|
|
51
|
+
)
|
|
52
|
+
},
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// transparent GIF pixel
|
|
56
|
+
const PLACEHOLDER =
|
|
57
|
+
'data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='
|
|
58
|
+
|
|
59
|
+
export const questIconMap = {
|
|
60
|
+
[QUEST_CATEGORY.Composition]: IconComposition,
|
|
61
|
+
[QUEST_CATEGORY.Sortie]: IconSortie,
|
|
62
|
+
[QUEST_CATEGORY.Exercise]: IconExercise,
|
|
63
|
+
[QUEST_CATEGORY.Expedition]: IconExpedition,
|
|
64
|
+
[QUEST_CATEGORY.SupplyOrDocking]: IconSupplyDocking,
|
|
65
|
+
[QUEST_CATEGORY.Arsenal]: IconArsenal,
|
|
66
|
+
[QUEST_CATEGORY.Modernization]: IconModernization,
|
|
67
|
+
[QUEST_CATEGORY.Unknown]: PLACEHOLDER,
|
|
68
|
+
} as const
|
|
@@ -47,7 +47,7 @@ const useQuestsRowRenderer = (quests: UnionQuest[]) => {
|
|
|
47
47
|
({ key, index, style, parent }: ListRowProps) => {
|
|
48
48
|
const quest = quests[index]
|
|
49
49
|
const { gameId } = quest
|
|
50
|
-
const { code, name, desc, memo } = quest.docQuest
|
|
50
|
+
const { code, name, desc, memo, pre } = quest.docQuest
|
|
51
51
|
const questStatus = questStateToQuestStatus(quest.gameQuest?.api_state)
|
|
52
52
|
|
|
53
53
|
return (
|
|
@@ -66,6 +66,7 @@ const useQuestsRowRenderer = (quests: UnionQuest[]) => {
|
|
|
66
66
|
name={name}
|
|
67
67
|
desc={desc}
|
|
68
68
|
tips={memo}
|
|
69
|
+
preTask={pre}
|
|
69
70
|
status={questStatus}
|
|
70
71
|
></QuestCard>
|
|
71
72
|
</div>
|
package/src/questHelper.ts
CHANGED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { useCallback } from 'react'
|
|
2
|
+
import {
|
|
3
|
+
ALL_CATEGORY_TAG,
|
|
4
|
+
ALL_TYPE_TAG,
|
|
5
|
+
CATEGORY_TAGS,
|
|
6
|
+
TYPE_TAGS,
|
|
7
|
+
} from '../tags'
|
|
8
|
+
import { useStore } from './store'
|
|
9
|
+
|
|
10
|
+
export const useFilterTags = () => {
|
|
11
|
+
const {
|
|
12
|
+
store: { categoryTags, typeTags },
|
|
13
|
+
updateStore,
|
|
14
|
+
} = useStore()
|
|
15
|
+
const setCategoryTags = useCallback(
|
|
16
|
+
(tagName: typeof CATEGORY_TAGS[number]['name']) => {
|
|
17
|
+
updateStore({ categoryTags: { [tagName]: true } })
|
|
18
|
+
},
|
|
19
|
+
[updateStore]
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
const setCategoryTagsAll = useCallback(() => {
|
|
23
|
+
setCategoryTags(ALL_CATEGORY_TAG.name)
|
|
24
|
+
}, [setCategoryTags])
|
|
25
|
+
|
|
26
|
+
const setTypeTags = useCallback(
|
|
27
|
+
(tagName: typeof TYPE_TAGS[number]['name']) => {
|
|
28
|
+
updateStore({ typeTags: { [tagName]: true } })
|
|
29
|
+
},
|
|
30
|
+
[updateStore]
|
|
31
|
+
)
|
|
32
|
+
const setTypeTagsAll = useCallback(() => {
|
|
33
|
+
setTypeTags(ALL_TYPE_TAG.name)
|
|
34
|
+
}, [setTypeTags])
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
categoryTags,
|
|
38
|
+
typeTags,
|
|
39
|
+
setCategoryTags,
|
|
40
|
+
setCategoryTagsAll,
|
|
41
|
+
setTypeTags,
|
|
42
|
+
setTypeTagsAll,
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { useCallback } from 'react'
|
|
2
|
+
import { useStore } from './store'
|
|
3
|
+
|
|
4
|
+
export const useSearchInput = () => {
|
|
5
|
+
const {
|
|
6
|
+
store: { searchInput },
|
|
7
|
+
updateStore,
|
|
8
|
+
} = useStore()
|
|
9
|
+
const setSearchInput = useCallback(
|
|
10
|
+
(value: string) => updateStore({ searchInput: value }),
|
|
11
|
+
[updateStore]
|
|
12
|
+
)
|
|
13
|
+
return {
|
|
14
|
+
searchInput,
|
|
15
|
+
setSearchInput,
|
|
16
|
+
}
|
|
17
|
+
}
|