diff --git a/packages/web/package.json b/packages/web/package.json index d054c5f0d..275269de0 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -151,6 +151,7 @@ "eslint-plugin-prettier": "^4.0.0", "eslint-plugin-react": "^7.26.1", "eslint-plugin-react-hooks": "^4.6.0", + "ignore-loader": "^0.1.2", "isomorphic-unfetch": "^3.1.0", "node-sass": "^9.0.0", "prettier": "^2.6.2", @@ -158,7 +159,9 @@ "storybook-dark-mode": "3.0.0", "style-loader": "^3.3.3", "terser-webpack-plugin": "^5.3.10", + "thread-loader": "^4.0.2", "ts-node": "^10.8.1", - "typescript": "~4.3.5" + "typescript": "~4.3.5", + "webpack-bundle-analyzer": "^4.10.2" } } diff --git a/src/assets/json/index.ts b/src/assets/json/index.ts index cd12ea5eb..269bfdf0c 100644 --- a/src/assets/json/index.ts +++ b/src/assets/json/index.ts @@ -2,28 +2,140 @@ * @Author: czy0729 * @Date: 2024-08-17 11:48:04 * @Last Modified by: czy0729 - * @Last Modified time: 2024-08-19 13:03:20 + * @Last Modified time: 2024-08-28 21:05:01 */ -const memo = new Map() -const lock = new Map() +import { JSONData, JSONPath } from './types' + +const memo = new Map() +const lock = new Map() /** 加载 json 数据, 客户端与本地获取方式是一致的, 目的是网页端能把 json 文件从打包中剔除 */ -export async function loadJSON(name: string, defaultValue: any = {}): Promise { +export async function loadJSON( + name: T, + defaultValue: any = {} +): Promise { try { - if (memo.has(name)) return memo.get(name) + if (memo.has(name)) return memo.get(name) as JSONData[T] - const module = await import(`./json/${name}.json`) - const data = module.default - memo.set(name, data) + let data: JSONData[T] + switch (name as JSONPath) { + /** ==================== substrings ==================== */ + case 'substrings/anime': + data = require('./substrings/anime.json') + break - return data - } catch (error) { - return defaultValue - } + case 'substrings/book': + data = require('./substrings/book.json') + break + + case 'substrings/game': + data = require('./substrings/game.json') + break + + case 'substrings/alias': + data = require('./substrings/alias.json') + break + + case 'substrings/addon': + data = require('./substrings/addon.json') + break + + /** ==================== typerank ==================== */ + case 'typerank/anime': + data = require('./typerank/anime.json') + break + + case 'typerank/book': + data = require('./typerank/book.json') + break + + case 'typerank/game': + data = require('./typerank/game.json') + break + + case 'typerank/music': + data = require('./typerank/music.json') + break + + case 'typerank/real': + data = require('./typerank/real.json') + break + + /** ==================== typerank-ids ==================== */ + case 'typerank/anime-ids': + data = require('./typerank/anime-ids.json') + break + + case 'typerank/book-ids': + data = require('./typerank/book-ids.json') + break + + case 'typerank/game-ids': + data = require('./typerank/game-ids.json') + break + + case 'typerank/music-ids': + data = require('./typerank/music-ids.json') + break + + case 'typerank/real-ids': + data = require('./typerank/real-ids.json') + break + + /** ==================== data ==================== */ + case 'katakana': + data = require('./katakana.json') + break + + case 'group': + data = require('./group.json') + break + + /** ==================== japanese romanization ==================== */ + case 'thirdParty/ja.min': + data = require('./thirdParty/ja.min.json') + break + + case 'thirdParty/ja.addon': + data = require('./thirdParty/ja.addon.json') + break + + /** ==================== thirdParty ==================== */ + case 'thirdParty/d.min': + data = require('./thirdParty/d.min.json') + break + + case 'thirdParty/h.min': + data = require('./thirdParty/h.min.json') + break + + case 'thirdParty/nsfw.min': + data = require('./thirdParty/nsfw.min.json') + break + + case 'thirdParty/wenku.min': + data = require('./thirdParty/wenku.min.json') + break + + default: + break + } + + if (data) { + memo.set(name, data) + return data + } + } catch (error) {} + + return defaultValue } /** 返回同步的 json 数据, 需要先提前使用 loadJSON 加载数据 */ -export function getJSON(name: string, defaultValue: any = {}, autoLoad: boolean = false) { +export function getJSON( + name: T, + defaultValue: any = {}, + autoLoad: boolean = false +): JSONData[T] { if (autoLoad && !memo.has(name) && !lock.has(name)) { lock.set(name, true) diff --git a/src/assets/json/index.web.ts b/src/assets/json/index.web.ts index 795ffdfa8..558cd93d9 100644 --- a/src/assets/json/index.web.ts +++ b/src/assets/json/index.web.ts @@ -2,17 +2,22 @@ * @Author: czy0729 * @Date: 2024-08-17 11:48:13 * @Last Modified by: czy0729 - * @Last Modified time: 2024-08-19 13:01:37 + * @Last Modified time: 2024-08-28 21:01:26 */ +import { JSONData, JSONPath } from './types' + const GITHUB_STORYBOOK_REPO = 'Bangumi-Storybook/storybook-static' -const memo = new Map() -const lock = new Map() +const memo = new Map() +const lock = new Map() /** 加载 json 数据, 客户端与本地获取方式是一致的, 目的是网页端能把 json 文件从打包中剔除 */ -export async function loadJSON(name: string, defaultValue: any = {}): Promise { +export async function loadJSON( + name: T, + defaultValue: any = {} +): Promise { try { - if (memo.has(name)) return memo.get(name) + if (memo.has(name)) return memo.get(name) as JSONData[T] let path = `/assets/json/${name}.json` if (window.location.host.includes('github')) path = `/${GITHUB_STORYBOOK_REPO}${path}` @@ -20,17 +25,21 @@ export async function loadJSON(name: string, defaultValue: any = {}): Promise( + name: T, + defaultValue: any = {}, + autoLoad: boolean = false +) { if (autoLoad && !memo.has(name) && !lock.has(name)) { lock.set(name, true) diff --git a/src/assets/json/types.ts b/src/assets/json/types.ts new file mode 100644 index 000000000..cc7262d16 --- /dev/null +++ b/src/assets/json/types.ts @@ -0,0 +1,102 @@ +/* + * @Author: czy0729 + * @Date: 2024-08-28 19:23:45 + * @Last Modified by: czy0729 + * @Last Modified time: 2024-08-28 20:46:06 + */ +import { Expand, Id, SubjectId, SubjectType } from '@types' + +type Substring = `substrings/${'anime' | 'book' | 'game' | 'alias' | 'addon'}` + +type TypeRank = `typerank/${SubjectType}` + +type TypeRankIds = `typerank/${SubjectType}-ids` + +export type JSONPath = + | Substring + | TypeRank + | TypeRankIds + | 'katakana' + | 'group' + | 'thirdParty/ja.min' + | 'thirdParty/ja.addon' + | 'thirdParty/d.min' + | 'thirdParty/h.min' + | 'thirdParty/nsfw.min' + | 'thirdParty/wenku.min' + +export type JSONSubString = Record + +export type JSONTypeRank = Record + +export type JSONTypeRankIds = Record + +export type JSONKatakana = Record + +export type JSONGroup = { + t: string + n: number + i: number +}[] + +export type JSONJA = Record + +export type JSONDouban = Record + +export type JSONHentai = { + id: number + f?: string + s?: number + r?: number + n?: number + a: string + t: number[] +}[] + +export type JSONNSFW = { + i: number + t?: number + d?: string + s?: number + r?: number + l?: number + c?: number + e?: number +}[] + +export type JSONWenku = { + i: number + f?: string + v?: number + m?: number + a?: number + b: string + u: string + c: number + h: number + p?: number + l: number + s?: number + r?: number + k?: number + j?: number[] +}[] + +export type JSONData = Expand< + { + [K in Substring]: JSONSubString + } & { + [K in TypeRank]: JSONTypeRank + } & { + [K in TypeRankIds]: JSONTypeRankIds + } & { + katakana: JSONKatakana + group: JSONGroup + 'thirdParty/ja.min': JSONJA + 'thirdParty/ja.addon': JSONJA + 'thirdParty/d.min': JSONDouban + 'thirdParty/h.min': JSONHentai + 'thirdParty/nsfw.min': JSONNSFW + 'thirdParty/wenku.min': JSONWenku + } +> diff --git a/src/components/header/index.tsx b/src/components/header/index.tsx index b47f3566d..e03bbba65 100644 --- a/src/components/header/index.tsx +++ b/src/components/header/index.tsx @@ -2,12 +2,12 @@ * @Author: czy0729 * @Date: 2022-03-10 17:27:04 * @Last Modified by: czy0729 - * @Last Modified time: 2024-01-14 16:07:38 + * @Last Modified time: 2024-08-28 21:15:21 */ import React, { useEffect } from 'react' import { r } from '@utils/dev' import { useNavigation, useObserver } from '@utils/hooks' -import { STORYBOOK } from '@constants' +import { WEB } from '@constants' import { Track } from '../track' import HeaderComponent from './header-component' import Placeholder from './placeholder' @@ -80,7 +80,7 @@ const Header: IHeader = ({ <> {mode ? ( - ) : STORYBOOK ? ( + ) : WEB ? ( <> diff --git a/src/components/header/transition/styles.ts b/src/components/header/transition/styles.ts index ea79d0458..685b64725 100644 --- a/src/components/header/transition/styles.ts +++ b/src/components/header/transition/styles.ts @@ -2,7 +2,7 @@ * @Author: czy0729 * @Date: 2023-04-11 16:15:24 * @Last Modified by: czy0729 - * @Last Modified time: 2024-08-23 16:51:27 + * @Last Modified time: 2024-08-28 21:23:15 */ import { _ } from '@stores' import { WEB, WSA } from '@constants' @@ -19,7 +19,7 @@ if (WSA) { export const memoStyles = _.memoStyles(() => ({ view: { position: 'absolute', - zIndex: 1, + zIndex: _.web(1, undefined), top: 0, right: 0, bottom: 0, diff --git a/src/components/katakana/utils.ts b/src/components/katakana/utils.ts index 0c1a0cb9d..f7f946496 100644 --- a/src/components/katakana/utils.ts +++ b/src/components/katakana/utils.ts @@ -2,15 +2,16 @@ * @Author: czy0729 * @Date: 2022-05-06 20:48:56 * @Last Modified by: czy0729 - * @Last Modified time: 2024-08-19 07:00:18 + * @Last Modified time: 2024-08-28 19:40:46 */ import { getStorage, setStorage } from '@utils' import { baiduTranslate } from '@utils/fetch' import { loadJSON } from '@assets/json' +import { JSONKatakana } from '@assets/json/types' import { Fn } from '@types' import { CACHE_KEY } from './ds' -let memo = { +let memo: JSONKatakana = { スクールアイドル: 'Idol school', マギカ: 'Magica' } diff --git a/src/components/toast/container/index.tsx b/src/components/toast/container/index.tsx index 705dc03f7..2bf1b4b97 100755 --- a/src/components/toast/container/index.tsx +++ b/src/components/toast/container/index.tsx @@ -2,14 +2,14 @@ * @Author: czy0729 * @Date: 2020-09-28 18:30:52 * @Last Modified by: czy0729 - * @Last Modified time: 2024-08-13 16:14:36 + * @Last Modified time: 2024-08-28 21:10:13 */ import React from 'react' import { ActivityIndicator, Animated, TouchableOpacity, View } from 'react-native' import { WithTheme } from '@ant-design/react-native/lib/style' import ToastStyles from '@ant-design/react-native/lib/toast/style/index' import { syncThemeStore } from '@utils/async' -import { USE_NATIVE_DRIVER } from '@constants' +import { USE_NATIVE_DRIVER } from '@constants/constants' import BlurView from '../blur-view' import Desc from '../desc' import { ToastProps } from './type'