Skip to content

Commit

Permalink
feat: support switch data source (#161)
Browse files Browse the repository at this point in the history
* chore: clean up unused code

* refactor: export data as list

* refactor: sunseting syncWithGame functionality

* refactor: update game data gen logic

* feat: add new settings panel to toolbar

* chore: update i18n

* refactor: use data from data source

* refactor: use data base data source in task panel tips

* chore: clean code

* chore: update KcwikiQuestData game data version snapshot

* chore: add changeset
  • Loading branch information
lawvs authored Oct 5, 2024
1 parent 2f5cc37 commit e3fcef0
Show file tree
Hide file tree
Showing 21 changed files with 220 additions and 214 deletions.
5 changes: 5 additions & 0 deletions .changeset/silver-ads-fry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'poi-plugin-quest-info-2': minor
---

Support for switching data sources
2 changes: 2 additions & 0 deletions i18n/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,7 @@
"Search in KanColle Wiki": "Search in KanColle Wiki",
"Search in Richelieu Manager": "Search in Richelieu Manager",
"Star project, support the author": "Star project, support the author",
"Data Source": "Data Source",
"Auto detect": "Auto detect",
"": ""
}
2 changes: 2 additions & 0 deletions i18n/ja-JP.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,7 @@
"Search in KanColle Wiki": "KanColle Wikiでこのタスクを検索",
"Search in Richelieu Manager": "リシュリューの任務マネージャを検索",
"Star project, support the author": "Starプロジェクト、著者をサポート",
"Data Source": "データソース",
"Auto detect": "自動検出",
"": ""
}
2 changes: 2 additions & 0 deletions i18n/ko-KR.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,7 @@
"Search in KanColle Wiki": "KanColle Wiki에서 이 작업 검색",
"Search in Richelieu Manager": "リシュリューの任務マネージャ에서 이 작업 검색",
"Star project, support the author": "스타 프로젝트, 작가 지원",
"Data Source": "데이터 소스",
"Auto detect": "자동 감지",
"": ""
}
2 changes: 2 additions & 0 deletions i18n/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,7 @@
"Search in KanColle Wiki": "在 英wiki 搜索该任务",
"Search in Richelieu Manager": "在 黎塞留任务管理器 搜索该任务",
"Star project, support the author": "Star 项目,支持作者",
"Data Source": "数据源",
"Auto detect": "自动检测",
"": ""
}
2 changes: 2 additions & 0 deletions i18n/zh-TW.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,7 @@
"Search in KanColle Wiki": "在 KanColle Wiki 搜索該任務",
"Search in Richelieu Manager": "在 黎塞留任務管理器 搜索該任務",
"Star project, support the author": "Star項目,支持作者",
"Data Source": "資料來源",
"Auto detect": "自動偵測",
"": ""
}
8 changes: 8 additions & 0 deletions scripts/downloadKcQuestsData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ const genTS = (version: string) => {
'export const KcwikiQuestData = {',
` 'zh-CN': zh_CN,`,
'}',
'',
`export const kcwikiGameData = {
name: '简体中文 - Kcwiki',
key: 'zh-Hans-kcwiki',
lang: 'zh-CN',
flagEmoji: '🇨🇳',
res: zh_CN,
} as const`,
].join('\n')

const versionCode = `export const version = '${version}'`
Expand Down
75 changes: 52 additions & 23 deletions scripts/downloadKcanotifyGamedata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ const URL_PREFIX =
const VERSION_URL = `${URL_PREFIX}/KCAINFO`
const DATA_URL = `${URL_PREFIX}/files`
const LANGS = ['scn', 'tcn', 'jp', 'en', 'ko'] as const
const LOCALES = ['zh-CN', 'zh-TW', 'ja-JP', 'en-US', 'ko-KR'] as const

const getRemoteVersion = async () => {
const resp = await fetch(VERSION_URL)
Expand Down Expand Up @@ -49,17 +48,57 @@ const getLocalVersion = () => {
* ```
*/
const genTS = (version: string) => {
const importCode = LOCALES.map(
(locale, idx) =>
`import ${locale.replace('-', '_')} from './quests-${LANGS[idx]}.json'`,
).join('\n')

const exportCode =
'export const QuestData = {\n' +
LOCALES.map((locale) => ` '${locale}': ${locale.replace('-', '_')},`).join(
'\n',
) +
'\n}'
const importCode = `import en_US from './quests-en.json'
import ja_JP from './quests-jp.json'
import ko_KR from './quests-ko.json'
import zh_CN from './quests-scn.json'
import zh_TW from './quests-tcn.json'`

const exportCode = `export const QuestData = {
'zh-CN': zh_CN,
'zh-TW': zh_TW,
'ja-JP': ja_JP,
'en-US': en_US,
'ko-KR': ko_KR,
}
export const kcanotifyGameData = [
{
name: '简体中文 - Kcanotify',
key: 'zh-Hans-kcanotify',
lang: 'zh-CN',
flagEmoji: '🇨🇳',
res: zh_CN,
},
{
name: '正體中文 - Kcanotify',
key: 'zh-TW-kcanotify',
lang: 'zh-TW',
flagEmoji: '🇹🇼',
res: zh_TW,
},
{
name: '日本語 - Kcanotify',
key: 'ja-JP-kcanotify',
lang: 'ja-JP',
flagEmoji: '🇯🇵',
res: ja_JP,
},
{
name: 'English - Kcanotify',
key: 'en-US-kcanotify',
lang: 'en-US',
flagEmoji: '🇺🇸',
res: en_US,
},
{
name: '한국어 - 시제 깡들리티',
key: 'ko-KR-kcanotify',
lang: 'ko-KR',
flagEmoji: '🇰🇷',
res: ko_KR,
},
] as const`

const versionCode = `export const version = '${version}'`
return `${importCode}\n\n${exportCode}\n\n${versionCode}\n`
Expand Down Expand Up @@ -91,11 +130,7 @@ const main = async () => {
console.error(`Fetch Error!\nurl: ${resp.url}\nstatus: ${resp.status}`)
return
}
let text = await resp.text()
// TODO fix source file
// Remove BOM(U+FEFF) from the header of the quests-ko.json
// See https://github.com/antest1/kcanotify-gamedata/pull/2
text = text.trim()
const text = await resp.text()

const json = JSON.parse(text) as {
[gameId: string]: {
Expand All @@ -106,12 +141,6 @@ const main = async () => {
}
}

if ('421?' in json) {
// TODO fix source file
// See https://github.com/antest1/kcanotify-gamedata/pull/2
delete json['421?']
}

for (const gameId in json) {
const { name, desc, rewards } = json[gameId]
json[gameId].name = pangu.spacing(name)
Expand Down
24 changes: 18 additions & 6 deletions scripts/genQuestData.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,34 @@
/* eslint-disable no-console */
import { writeFile } from 'fs/promises'
import path from 'path'
import { KcwikiQuestData } from '../build/kcQuestsData'
import { QuestData } from '../build/kcanotifyGamedata'
import { kcwikiGameData } from '../build/kcQuestsData'
import { kcanotifyGameData } from '../build/kcanotifyGamedata'
import { parseQuestCode } from './utils'

const EXPORT_QUEST_PATH = path.resolve('build', 'index.ts')
const CATEGORY_OUTPUT_PATH = path.resolve('build', 'questCategory.json')
const QUEST_CODE_MAP_OUTPUT_PATH = path.resolve('build', 'questCodeMap.json')
const PRE_POST_QUEST_OUTPUT_PATH = path.resolve('build', 'prePostQuest.json')

const kcwikiQuestCodeFilter = (
predicate: (parsedCode: { type: string; number: number }) => boolean,
) =>
Object.entries(KcwikiQuestData['zh-CN'])
Object.entries(kcwikiGameData.res)
.filter(([, quest]) => predicate(parseQuestCode(quest.code)))
.map(([gameId]) => +gameId)

const mergeDataSelector = () =>
Object.entries({ ...QuestData['zh-CN'], ...KcwikiQuestData['zh-CN'] })
Object.entries({ ...kcanotifyGameData[0].res, ...kcwikiGameData.res })

const genExportQuestData = async () => {
const code = `import { kcanotifyGameData } from './kcanotifyGamedata'
import { kcwikiGameData } from './kcQuestsData'
export const QUEST_DATA = [kcwikiGameData, ...kcanotifyGameData]
`
await writeFile(EXPORT_QUEST_PATH, code)
console.log('Export quest data', QUEST_CODE_MAP_OUTPUT_PATH)
}

const genQuestCategory = async () => {
const dailyQuest = kcwikiQuestCodeFilter((code) => code.type.endsWith('d'))
Expand Down Expand Up @@ -55,7 +66,7 @@ const genQuestCategory = async () => {
}

const genQuestMap = async () => {
const data = Object.entries(KcwikiQuestData['zh-CN']).reduce(
const data = Object.entries(kcwikiGameData.res).reduce(
(acc, [gameId, { code }]) => {
if (code in acc) {
console.warn(`Duplicate quest code: ${code}`, acc[code], gameId)
Expand All @@ -80,7 +91,7 @@ const genPrePostQuestMap = async (code2IdQuestMap: Record<string, number>) => {
return code2IdQuestMap[code1] - code2IdQuestMap[code2]
}

const data = Object.entries(KcwikiQuestData['zh-CN']).reduce(
const data = Object.entries(kcwikiGameData.res).reduce(
(acc, [gameId, { code, pre }]) => {
if (!pre || pre.length === 0) {
return acc
Expand Down Expand Up @@ -116,6 +127,7 @@ const genPrePostQuestMap = async (code2IdQuestMap: Record<string, number>) => {
}

const main = async () => {
await genExportQuestData()
await genQuestCategory()
const code2IdQuestMap = await genQuestMap()
await genPrePostQuestMap(code2IdQuestMap)
Expand Down
83 changes: 46 additions & 37 deletions src/Settings.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {
AnchorButton,
Button,
Checkbox,
HTMLSelect,
Intent,
Text,
TextArea,
Expand All @@ -10,31 +10,23 @@ import { IconNames } from '@blueprintjs/icons'
import type { ChangeEvent } from 'react'
import React, { StrictMode, useCallback, useState } from 'react'
import styled from 'styled-components'
import { QUEST_DATA } from '../build'
import { version as DATA_VERSION } from '../build/kcanotifyGamedata'
import PKG from '../package.json'
import { IN_POI } from './poi/env'
import { usePluginTranslation, useStateExporter } from './poi/hooks'
import { tips } from './poi/utils'
import {
StoreProvider,
useLanguage,
usePreferKcwiki,
useRemoveStorage,
} from './store'
import { StoreProvider, useDataSource, useRemoveStorage } from './store'

const Container = styled.div`
display: flex;
flex-direction: column;
align-items: flex-start;
user-select: text;
& > * + * {
margin-top: 8px;
}
gap: 8px;
padding: 8px;
`

const useIsSimplifiedChinese = () => useLanguage() === 'zh-CN'

const DataExportArea = () => {
const [text, setText] = useState<string>('')
const { t } = usePluginTranslation()
Expand Down Expand Up @@ -83,23 +75,49 @@ const DataExportArea = () => {
)
}

const SettingsMain = () => {
const Group = styled.div`
display: flex;
flex-direction: column;
gap: 8px;
margin-bottom: 8px;
`

export const SettingsMain = () => {
const { t } = usePluginTranslation()
const isSimplifiedChinese = useIsSimplifiedChinese()
const removeStorage = useRemoveStorage()
const [preferKcwiki, setPreferKcwiki] = usePreferKcwiki()
const handleEnabledChange: React.FormEventHandler<HTMLInputElement> =
useCallback(() => {
setPreferKcwiki(!preferKcwiki)
}, [preferKcwiki, setPreferKcwiki])
const { dataSource, setDataSource } = useDataSource()

const handleChangeQuestSource = useCallback(
(e: ChangeEvent<HTMLSelectElement>) => {
const value = e.target.value
if (!value) {
setDataSource(null)
return
}
setDataSource(value as any)
},
[setDataSource],
)

return (
<>
<Checkbox
checked={preferKcwiki}
disabled={!isSimplifiedChinese}
label={t('Use Kcwiki data')}
onChange={handleEnabledChange}
<Container>
<Group>
<Text>{t('Data Source')}</Text>
<HTMLSelect value={dataSource} onChange={handleChangeQuestSource}>
<option value="">{t('Auto detect')}</option>
{QUEST_DATA.map((source) => (
<option key={source.key} value={source.key}>
{source.name} ({Object.keys(source.res).length})
</option>
))}
</HTMLSelect>
</Group>

<Button
intent={Intent.WARNING}
icon={IconNames.TRASH}
text={t('Restore defaults')}
onClick={removeStorage}
/>

<Text>{t('Version', { version: PKG.version })}</Text>
Expand All @@ -111,24 +129,15 @@ const SettingsMain = () => {
href={PKG.homepage}
target="_blank"
/>

<Button
icon={IconNames.TRASH}
text={t('Restore defaults')}
onClick={removeStorage}
/>

<DataExportArea />
</>
</Container>
)
}

export const Settings = () => (
<StrictMode>
<StoreProvider>
<Container>
<SettingsMain />
</Container>
<SettingsMain />
</StoreProvider>
</StrictMode>
)
Loading

0 comments on commit e3fcef0

Please sign in to comment.