diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8e7d4b16..846a55cf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -296,8 +296,10 @@ importers: web/plugins/com.msgbyte.genshin: specifiers: genshin-gacha-kit: ^1.1.0 + html-react-parser: ^1.4.5 dependencies: genshin-gacha-kit: registry.npmmirror.com/genshin-gacha-kit/1.1.0 + html-react-parser: registry.npmmirror.com/html-react-parser/1.4.5_react@17.0.2 web/plugins/com.msgbyte.intro: specifiers: @@ -1840,7 +1842,6 @@ packages: domelementtype: registry.nlark.com/domelementtype/2.2.0 domhandler: registry.npmmirror.com/domhandler/4.3.0 entities: registry.nlark.com/entities/2.2.0 - dev: true registry.nlark.com/domelementtype/1.3.1: resolution: {integrity: sha1-0EjESzew0Qp/Kj1f7j9DM9eQSB8=, registry: https://registry.npm.taobao.org/, tarball: https://registry.nlark.com/domelementtype/download/domelementtype-1.3.1.tgz} @@ -1870,7 +1871,6 @@ packages: dom-serializer: registry.nlark.com/dom-serializer/1.3.2 domelementtype: registry.nlark.com/domelementtype/2.2.0 domhandler: registry.npmmirror.com/domhandler/4.3.0 - dev: true registry.nlark.com/dot-case/3.0.4: resolution: {integrity: sha1-mytnDQCkMWZ6inW6Kc0bmICc51E=, registry: https://registry.npm.taobao.org/, tarball: https://registry.nlark.com/dot-case/download/dot-case-3.0.4.tgz} @@ -1972,6 +1972,13 @@ packages: name: entities version: 2.2.0 + registry.nlark.com/entities/3.0.1: + resolution: {integrity: sha1-K4h8piWF6W2zkDSC0zbBAGwwAdQ=, registry: https://registry.npm.taobao.org/, tarball: https://registry.nlark.com/entities/download/entities-3.0.1.tgz} + name: entities + version: 3.0.1 + engines: {node: '>=0.12'} + dev: false + registry.nlark.com/envinfo/7.8.1: resolution: {integrity: sha1-Bjd+Pl9NN5/qesWS1a2JJ+DE1HU=, registry: https://registry.npm.taobao.org/, tarball: https://registry.nlark.com/envinfo/download/envinfo-7.8.1.tgz} name: envinfo @@ -10216,7 +10223,6 @@ packages: engines: {node: '>= 4'} dependencies: domelementtype: registry.nlark.com/domelementtype/2.2.0 - dev: true registry.npmmirror.com/dts-generator/3.0.0: resolution: {integrity: sha1-cO0A3BBnvGb2itVQu+uJSHPUX3c=, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/dts-generator/download/dts-generator-3.0.0.tgz} @@ -11060,6 +11066,15 @@ packages: lru-cache: registry.nlark.com/lru-cache/6.0.0 dev: true + registry.npmmirror.com/html-dom-parser/1.0.4: + resolution: {integrity: sha512-ThM/vK/18R5/cVB9UsqhNqbJU7LE2BmSA7C/FjYV88wIDW75GSUpvSE/JxE4mJ8bOuU6Kp15/I1giM2JbD+ieA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/html-dom-parser/download/html-dom-parser-1.0.4.tgz} + name: html-dom-parser + version: 1.0.4 + dependencies: + domhandler: registry.npmmirror.com/domhandler/4.3.0 + htmlparser2: registry.npmmirror.com/htmlparser2/7.2.0 + dev: false + registry.npmmirror.com/html-minifier-terser/6.1.0: resolution: {integrity: sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/html-minifier-terser/download/html-minifier-terser-6.1.0.tgz} name: html-minifier-terser @@ -11086,6 +11101,21 @@ packages: void-elements: registry.nlark.com/void-elements/3.1.0 dev: false + registry.npmmirror.com/html-react-parser/1.4.5_react@17.0.2: + resolution: {integrity: sha512-dxo0z1G9b3mS1VGmcVw4cUGwVsEwkJZZ7r29pOSdE69JukJyFTCL1I6TXSEp2p1LAHvuO6ZBiEVp2M5lXqKLAg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/html-react-parser/download/html-react-parser-1.4.5.tgz} + id: registry.npmmirror.com/html-react-parser/1.4.5 + name: html-react-parser + version: 1.4.5 + peerDependencies: + react: 0.14 || 15 || 16 || 17 + dependencies: + domhandler: registry.npmmirror.com/domhandler/4.3.0 + html-dom-parser: registry.npmmirror.com/html-dom-parser/1.0.4 + react: registry.npmmirror.com/react/17.0.2 + react-property: registry.npmmirror.com/react-property/2.0.0 + style-to-js: registry.npmmirror.com/style-to-js/1.1.0 + dev: false + registry.npmmirror.com/html-webpack-plugin/5.5.0_webpack@5.65.0: resolution: {integrity: sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/html-webpack-plugin/download/html-webpack-plugin-5.5.0.tgz} id: registry.npmmirror.com/html-webpack-plugin/5.5.0 @@ -11116,6 +11146,17 @@ packages: entities: registry.nlark.com/entities/2.2.0 dev: true + registry.npmmirror.com/htmlparser2/7.2.0: + resolution: {integrity: sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/htmlparser2/download/htmlparser2-7.2.0.tgz} + name: htmlparser2 + version: 7.2.0 + dependencies: + domelementtype: registry.nlark.com/domelementtype/2.2.0 + domhandler: registry.npmmirror.com/domhandler/4.3.0 + domutils: registry.nlark.com/domutils/2.8.0 + entities: registry.nlark.com/entities/3.0.1 + dev: false + registry.npmmirror.com/http-errors/1.6.3: resolution: {integrity: sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/http-errors/download/http-errors-1.6.3.tgz} name: http-errors @@ -11277,6 +11318,12 @@ packages: resolve-cwd: registry.nlark.com/resolve-cwd/3.0.0 dev: true + registry.npmmirror.com/inline-style-parser/0.1.1: + resolution: {integrity: sha1-7Io7QpJ06cCh8cT/qUU6f+9yzqE=, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/inline-style-parser/download/inline-style-parser-0.1.1.tgz} + name: inline-style-parser + version: 0.1.1 + dev: false + registry.npmmirror.com/inquirer/3.0.6: resolution: {integrity: sha512-thluxTGBXUGb8DuQcvH9/CM/CrcGyB5xUpWc9x6Slqcq1z/hRr2a6KxUpX4ddRfmbe0hg3E4jTvo5833aWz3BA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/inquirer/download/inquirer-3.0.6.tgz} name: inquirer @@ -13619,6 +13666,12 @@ packages: name: react-is version: 17.0.2 + registry.npmmirror.com/react-property/2.0.0: + resolution: {integrity: sha1-IVa6nYX6R0H68ZGLOO/B6uPGoTY=, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/react-property/download/react-property-2.0.0.tgz} + name: react-property + version: 2.0.0 + dev: false + registry.npmmirror.com/react-query/3.34.6_react@17.0.2: resolution: {integrity: sha512-2UKldH8T2PjmLxaOzANok7yITQn9FF1pBbrZFF1hvukBjYefHtCjUur+GOVAWMhrsskcCoKRviei4hcpvj9wLQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/react-query/download/react-query-3.34.6.tgz} id: registry.npmmirror.com/react-query/3.34.6 @@ -14314,6 +14367,22 @@ packages: webpack: registry.npmmirror.com/webpack/5.65.0_webpack-cli@4.9.1 dev: true + registry.npmmirror.com/style-to-js/1.1.0: + resolution: {integrity: sha1-Yxy7IPziBAGbOqH8tbadlRzqxKw=, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/style-to-js/download/style-to-js-1.1.0.tgz} + name: style-to-js + version: 1.1.0 + dependencies: + style-to-object: registry.npmmirror.com/style-to-object/0.3.0 + dev: false + + registry.npmmirror.com/style-to-object/0.3.0: + resolution: {integrity: sha1-sbeQ0gWZHMeDgBlnIUl57hmnbkY=, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/style-to-object/download/style-to-object-0.3.0.tgz} + name: style-to-object + version: 0.3.0 + dependencies: + inline-style-parser: registry.npmmirror.com/inline-style-parser/0.1.1 + dev: false + registry.npmmirror.com/supports-color/2.0.0: resolution: {integrity: sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/supports-color/download/supports-color-2.0.0.tgz} name: supports-color diff --git a/web/plugins/com.msgbyte.genshin/package.json b/web/plugins/com.msgbyte.genshin/package.json index ef82b57e..92ce3a84 100644 --- a/web/plugins/com.msgbyte.genshin/package.json +++ b/web/plugins/com.msgbyte.genshin/package.json @@ -4,6 +4,7 @@ "version": "0.0.0", "private": true, "dependencies": { - "genshin-gacha-kit": "^1.1.0" + "genshin-gacha-kit": "^1.1.0", + "html-react-parser": "^1.4.5" } } diff --git a/web/plugins/com.msgbyte.genshin/src/GenshinPanel/GachaPool.tsx b/web/plugins/com.msgbyte.genshin/src/GenshinPanel/GachaPool.tsx index 8a6de7ec..43c09e07 100644 --- a/web/plugins/com.msgbyte.genshin/src/GenshinPanel/GachaPool.tsx +++ b/web/plugins/com.msgbyte.genshin/src/GenshinPanel/GachaPool.tsx @@ -2,6 +2,7 @@ import { useAsync } from '@capital/common'; import { Divider } from '@capital/component'; import React from 'react'; import { OfficialGachaPoolItem, util } from 'genshin-gacha-kit'; +import { GenshinRichtext } from '../components/GenshinRichtext'; const GachaPoolItem: React.FC<{ items: OfficialGachaPoolItem[]; @@ -43,7 +44,7 @@ export const GachaPool: React.FC<{ -
{poolData.content}
+ ); }); diff --git a/web/plugins/com.msgbyte.genshin/src/components/GenshinRichtext.tsx b/web/plugins/com.msgbyte.genshin/src/components/GenshinRichtext.tsx new file mode 100644 index 00000000..1be4c7e5 --- /dev/null +++ b/web/plugins/com.msgbyte.genshin/src/components/GenshinRichtext.tsx @@ -0,0 +1,20 @@ +import React, { useMemo } from 'react'; +import parser from 'html-react-parser'; + +/** + * 原神富文本渲染 + */ +export const GenshinRichtext: React.FC<{ + raw: string; +}> = React.memo(({ raw }) => { + const el = useMemo(() => { + const processedHtml = raw.replace( + /\(.*?)\<\/color\>/g, + '$2' + ); + + return parser(processedHtml); + }, [raw]); + return <>{el}; +}); +GenshinRichtext.displayName = 'GenshinRichtext'; diff --git a/web/plugins/com.msgbyte.genshin/src/components/__tests__/GenshinRichtext.spec.tsx b/web/plugins/com.msgbyte.genshin/src/components/__tests__/GenshinRichtext.spec.tsx new file mode 100644 index 00000000..8ea7f627 --- /dev/null +++ b/web/plugins/com.msgbyte.genshin/src/components/__tests__/GenshinRichtext.spec.tsx @@ -0,0 +1,31 @@ +import { GenshinRichtext } from '../GenshinRichtext'; +import { render } from '@testing-library/react'; +import React from 'react'; + +describe('GenshinRichtext', () => { + const testRawRichtext = `「陵薮市朝」活动祈愿已开启。活动期间内,限定5星角色「尘世闲游·钟离(岩)」以及4星角色「少年春衫薄·行秋(水)」、「无冕的龙王·北斗(雷)」、「智明无邪·烟绯(火)」的祈愿获取概率将大幅提升!

+ ※以上角色中,限定角色不会进入「奔行世间」常驻祈愿。

+
+ ※一般情况下所有角色或武器均适用基础概率,如触发概率UP、保底等以具体规则为准。

+
+ 〓祈愿规则〓

+ 【5星物品】

+ 在本期「陵薮市朝」活动祈愿中,5星角色祈愿的基础概率为0.600%,综合概率(含保底)为1.600%,最多90次祈愿必定能通过保底获取5星角色。

+ 当祈愿获取到5星角色时,有50.000%的概率为本期5星UP角色「尘世闲游·钟离(岩)」。如果本次祈愿获取的5星角色非本期5星UP角色,下次祈愿获取的5星角色必定为本期5星UP角色。

+ 【4星物品】

+ 在本期「陵薮市朝」活动祈愿中,4星物品祈愿的基础概率为5.100%,4星角色祈愿的基础概率为2.550%,4星武器祈愿的基础概率为2.550%,4星物品祈愿的综合概率(含保底)为13.000%。最多10次祈愿必定能通过保底获取4星或以上物品,通过保底获取4星物品的概率为99.400%,获取5星物品的概率为0.600%。

+ 当祈愿获取到4星物品时,有50.000%的概率为本期4星UP角色「少年春衫薄·行秋(水)」、「无冕的龙王·北斗(雷)」、「智明无邪·烟绯(火)」中的一个。如果本次祈愿获取的4星物品非本期4星UP角色,下次祈愿获取的4星物品必定为本期4星UP角色。当祈愿获取到4星UP物品时,每个本期4星UP角色的获取概率均等。

+
+ 获得4星武器时,会同时获得2个无主的星辉作为副产物;获得3星武器时,会同时获得15个无主的星尘作为副产物。

+
+ 〓若获得重复角色〓

+ 无论通过何种方式(包含但不限于祈愿、商城兑换、系统赠送等)第2~7次获得相同5星角色时,每次将转化为1个对应角色的命星和10个无主的星辉;第8次及之后获得,将仅转化为25个无主的星辉。

+ 无论通过何种方式(包含但不限于祈愿、商城兑换、系统赠送等)第2~7次获得相同4星角色时,每次将转化为1个对应角色的命星和2个无主的星辉;第8次及之后获得,将仅转化为5个无主的星辉。

+
+ ※本祈愿属于「角色活动祈愿」,「角色活动祈愿」和「角色活动祈愿-2」的祈愿次数保底完全共享,会一直共同累计在「角色活动祈愿」和「角色活动祈愿-2」中,与其他祈愿的祈愿次数保底相互独立计算,互不影响。

`; + + test('test', () => { + const wrapper = render(); + expect(wrapper.container).toMatchSnapshot(); + }); +}); diff --git a/web/plugins/com.msgbyte.genshin/src/components/__tests__/__snapshots__/GenshinRichtext.spec.tsx.snap b/web/plugins/com.msgbyte.genshin/src/components/__tests__/__snapshots__/GenshinRichtext.spec.tsx.snap new file mode 100644 index 00000000..9e4db50f --- /dev/null +++ b/web/plugins/com.msgbyte.genshin/src/components/__tests__/__snapshots__/GenshinRichtext.spec.tsx.snap @@ -0,0 +1,280 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`GenshinRichtext test 1`] = ` +
+ 「 + + 陵薮 + + 市朝」活动祈愿已开启。活动期间内, + + 限定 + + 5星角色 + + 「尘世闲游·钟离(岩)」 + + 以及4星角色 + + 「少年春衫薄·行秋(水)」 + + 、 + + 「无冕的龙王·北斗(雷)」 + + 、 + + 「智明无邪·烟绯(火)」 + + 的祈愿获取概率将 + + 大幅提升 + + ! +

+ + + + ※以上角色中,限定角色不会进入「奔行世间」常驻祈愿。 + +

+ + +
+ + ※一般情况下所有角色或武器均适用基础概率,如触发概率UP、保底等以具体规则为准。 +

+ + +
+ + 〓祈愿规则〓 +

+ + 【5星物品】 +

+ + 在本期「 + + 陵薮 + + 市朝」活动祈愿中,5星角色祈愿的基础概率为 + + 0.600% + + ,综合概率(含保底)为 + + 1.600% + + ,最多 + + 90 + + 次祈愿必定能通过保底获取5星角色。 +

+ + 当祈愿获取到5星角色时,有 + + 50.000% + + 的概率为本期5星UP角色 + + 「尘世闲游·钟离(岩)」 + + 。如果本次祈愿获取的5星角色非本期5星UP角色,下次祈愿获取的5星角色 + + 必定 + + 为本期5星UP角色。 +

+ + 【4星物品】 +

+ + 在本期「 + + 陵薮 + + 市朝」活动祈愿中,4星物品祈愿的基础概率为 + + 5.100% + + ,4星角色祈愿的基础概率为 + + 2.550% + + ,4星武器祈愿的基础概率为 + + 2.550% + + ,4星物品祈愿的综合概率(含保底)为 + + 13.000% + + 。最多 + + 10 + + 次祈愿必定能通过保底获取4星或以上物品,通过保底获取4星物品的概率为 + + 99.400% + + ,获取5星物品的概率为 + + 0.600% + + 。 +

+ + 当祈愿获取到4星物品时,有 + + 50.000% + + 的概率为本期4星UP角色 + + 「少年春衫薄·行秋(水)」 + + 、 + + 「无冕的龙王·北斗(雷)」 + + 、 + + 「智明无邪·烟绯(火)」 + + 中的一个。如果本次祈愿获取的4星物品非本期4星UP角色,下次祈愿获取的4星物品 + + 必定 + + 为本期4星UP角色。当祈愿获取到4星UP物品时,每个本期4星UP角色的获取概率均等。 +

+ + +
+ + 获得4星武器时,会同时获得2个 + + 无主的星辉 + + 作为副产物;获得3星武器时,会同时获得15个 + + 无主的星尘 + + 作为副产物。 +

+ + +
+ + 〓若获得重复角色〓 +

+ + 无论通过何种方式(包含但不限于祈愿、商城兑换、系统赠送等)第2~7次获得相同5星角色时,每次将转化为1个 + + 对应角色的命星 + + 和10个 + + 无主的星辉 + + ;第8次及之后获得,将仅转化为25个 + + 无主的星辉 + + 。 +

+ + 无论通过何种方式(包含但不限于祈愿、商城兑换、系统赠送等)第2~7次获得相同4星角色时,每次将转化为1个 + + 对应角色的命星 + + 和2个 + + 无主的星辉 + + ;第8次及之后获得,将仅转化为5个 + + 无主的星辉 + + 。 +

+ + +
+ + ※本祈愿属于「角色活动祈愿」,「角色活动祈愿」和「角色活动祈愿-2」的祈愿次数保底完全共享,会一直共同累计在「角色活动祈愿」和「角色活动祈愿-2」中,与其他祈愿的祈愿次数保底相互独立计算,互不影响。 +

+

+`;