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.
Files changed (41) hide show
  1. package/.eslintrc.js +1 -1
  2. package/build/assets.ts +2 -1
  3. package/build/kcQuestsData/DATA_VERSION +1 -1
  4. package/build/kcQuestsData/index.ts +1 -1
  5. package/build/kcQuestsData/quests-scn.json +1123 -1066
  6. package/build/kcanotifyGamedata/DATA_VERSION +1 -1
  7. package/build/kcanotifyGamedata/index.ts +1 -1
  8. package/build/kcanotifyGamedata/quests-en.json +60 -36
  9. package/build/kcanotifyGamedata/quests-jp.json +506 -482
  10. package/build/kcanotifyGamedata/quests-ko.json +101 -77
  11. package/build/kcanotifyGamedata/quests-scn.json +274 -251
  12. package/build/kcanotifyGamedata/quests-tcn.json +274 -251
  13. package/build/questCategory.json +600 -0
  14. package/i18n/en-US.json +4 -2
  15. package/i18n/ja-JP.json +3 -1
  16. package/i18n/ko-KR.json +1 -0
  17. package/i18n/zh-CN.json +3 -1
  18. package/i18n/zh-TW.json +2 -0
  19. package/package.json +4 -3
  20. package/scripts/convertAssets.ts +3 -2
  21. package/scripts/downloadKcQuestsData.ts +11 -3
  22. package/scripts/downloadKcanotifyGamedata.ts +10 -2
  23. package/scripts/genQuestCategory.ts +58 -0
  24. package/src/Toolbar.tsx +42 -37
  25. package/src/__tests__/__snapshots__/questCategory.spec.ts.snap +582 -0
  26. package/src/__tests__/kcanotifyData.spec.ts +1 -1
  27. package/src/__tests__/kcwikiData.spec.ts +1 -1
  28. package/src/__tests__/questCategory.spec.ts +37 -0
  29. package/src/components/PreTaskTag.tsx +40 -0
  30. package/src/components/QuestCard/MinimalQuestCard.tsx +48 -0
  31. package/src/components/QuestCard/index.tsx +71 -0
  32. package/src/components/QuestCard/styles.ts +42 -0
  33. package/src/components/QuestCard/utils.tsx +68 -0
  34. package/src/components/QuestList.tsx +2 -1
  35. package/src/questHelper.ts +24 -18
  36. package/src/store/filterTags.ts +44 -0
  37. package/src/store/quest.ts +3 -0
  38. package/src/store/search.ts +17 -0
  39. package/src/store/store.tsx +25 -2
  40. package/src/tags.ts +2 -1
  41. package/src/components/QuestCard.tsx +0 -213
@@ -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]: { code: string; name: string; desc: 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]: { code: string; name: string; desc: 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 { useQuest, useStore } from './store'
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
- store: { syncWithGame },
42
- updateStore,
43
- } = useStore()
42
+ const { searchInput } = useSearchInput()
43
+ const { syncWithGame, toggleSyncWithGame } = useSyncWithGame()
44
44
  const handleClick = useCallback(() => {
45
- updateStore({ syncWithGame: !syncWithGame })
46
- }, [syncWithGame, updateStore])
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={syncWithGame ? Intent.SUCCESS : Intent.NONE}
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
- updateStore({ searchInput: event.target.value }),
69
- [updateStore]
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={<SyncButton></SyncButton>}
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
- const {
87
- store: { typeTags, categoryTags },
88
- updateStore,
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={withHandleClickTag(name, 'categoryTags')}
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={withHandleClickTag(name, 'typeTags')}
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
- store: { searchInput, typeTags, categoryTags },
150
- } = useStore()
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)