Skip to content

Commit 77b3ed6

Browse files
authored
add gcsim risk banner on web (#2456)
* add gcsim risk banner on db page * moved latest version component to a separate file and added latest characters * reworked db home page * added pyro mc translations * fixed LatestVersion for ui module * added risk banner to viewer * add discord link to risk banner * add localization
1 parent 8278491 commit 77b3ed6

18 files changed

Lines changed: 287 additions & 151 deletions

File tree

ui/packages/components/src/Cards/AvatarPortait/AvatarPortrait.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ type AvatarPortraitProps = {
5656
i: number;
5757
invalid: boolean;
5858
onImageLoaded: () => void;
59+
hideDetails?: boolean;
5960

6061
//optional classes
6162
className?: string;
@@ -66,6 +67,7 @@ export const AvatarPortrait = ({
6667
i,
6768
invalid,
6869
onImageLoaded,
70+
hideDetails = false,
6971
className = '',
7072
}: AvatarPortraitProps) => {
7173
//display an empty card here
@@ -89,7 +91,7 @@ export const AvatarPortrait = ({
8991
const sets: string[] = [];
9092
let half = false;
9193

92-
if (char.sets && char.sets !== null) {
94+
if (!hideDetails && char.sets && char.sets !== null) {
9395
for (const [key] of Object.entries(char.sets)) {
9496
sets.push(key);
9597
}
@@ -122,7 +124,7 @@ export const AvatarPortrait = ({
122124
onLoad={onImageLoaded}
123125
/>
124126
</div>
125-
{char.weapon ? <WeaponImage weapon={char.weapon} /> : null}
127+
{!hideDetails && char.weapon ? <WeaponImage weapon={char.weapon} /> : null}
126128
<div className="absolute bottom-0 left-0 opacity-85">
127129
<svg
128130
width={35}
@@ -135,6 +137,7 @@ export const AvatarPortrait = ({
135137
</svg>
136138
</div>
137139

140+
{!hideDetails ? <>
138141
<div
139142
className={
140143
'absolute left-[-1px] top-[-1px] flex flex-col gap-0 px-1 py-0 rounded-none ' +
@@ -143,7 +146,7 @@ export const AvatarPortrait = ({
143146
}>
144147
<div className="flex flex-row gap-1 min-h-fit">
145148
<span className="text-geo">{`C${char.cons ?? 0}`}</span>
146-
{char.weapon ? (
149+
{!hideDetails && char.weapon ? (
147150
<span className="text-electro">{`R${
148151
char.weapon.refine ?? 0
149152
}`}</span>
@@ -165,7 +168,7 @@ export const AvatarPortrait = ({
165168
{char.level}
166169
</span>
167170
</div>
168-
</div>
171+
</div> </> : null}
169172

170173
{invalid && (
171174
<div className="absolute left-0 top-1/3 w-full">
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import {AnchorButton, Card} from '@blueprintjs/core';
2+
import {useTranslation} from 'react-i18next';
3+
import {useEffect, useState} from 'react';
4+
import axios from 'axios';
5+
import ReactMarkdown from 'react-markdown';
6+
import remarkGfm from 'remark-gfm';
7+
import { AvatarPortrait } from "@gcsim/components";
8+
import LatestCharactersData from '@gcsim/data/src/latest_chars.json'
9+
10+
const majorVersionRegex = /v\d+\.\d+/gm;
11+
12+
export function LatestVersion() {
13+
const {t} = useTranslation();
14+
15+
const [{isLoaded, text, tag, portraits}, setState] = useState({
16+
isLoaded: false,
17+
text: '',
18+
tag: '',
19+
portraits: []
20+
});
21+
22+
useEffect(() => {
23+
axios('https://api.github.com/repos/genshinsim/gcsim/releases/latest')
24+
.then((resp: {data}) => {
25+
const majorVersion = majorVersionRegex.exec(resp.data.name);
26+
let portraits = [];
27+
if (majorVersion && majorVersion[0]) {
28+
portraits = LatestCharactersData[majorVersion[0]] || [];
29+
}
30+
setState({isLoaded: true, text: resp.data.body, tag: resp.data.name, portraits});
31+
})
32+
.catch((err) =>
33+
console.log(t('viewer.error_encountered') + err.message),
34+
);
35+
}, [t]);
36+
37+
return (
38+
<Card className="flex flex-col items-center gap-4 overflow-x-auto">
39+
{isLoaded ? (
40+
<>
41+
<div className="flex flex-col gap-4">
42+
<h1 className="text-center text-xl md:text-2xl lg:text-4xl">
43+
<b>{t('dash.latest_release')}</b>
44+
<a
45+
href={`https://github.com/genshinsim/gcsim/releases/tag/${tag}`}>
46+
{tag}
47+
</a>
48+
</h1>
49+
</div>
50+
<div className="flex flex-col">
51+
<h2 className="text-center text-2xl">{t('dash.new_characters')}</h2>
52+
<div className="flex gap-4">
53+
{portraits.map((char) => (
54+
<div key={char} className="flex flex-col items-center">
55+
<AvatarPortrait char={{ name: char }} hideDetails />
56+
{t(`game:character_names.${char}`)}
57+
</div>
58+
))}
59+
</div>
60+
</div>
61+
<div className="self-start">
62+
<ReactMarkdown remarkPlugins={[remarkGfm]}>
63+
{text}
64+
</ReactMarkdown>
65+
</div>
66+
<AnchorButton
67+
href="https://github.com/genshinsim/gcsim/releases"
68+
intent="primary"
69+
target="_blank"
70+
className="!p-3 !rounded-md">
71+
<span className="text-xl md:text-2xl font-semibold">
72+
{t('dash.view_releases')}
73+
</span>
74+
</AnchorButton>
75+
</>
76+
) : (
77+
<>{t('sim.loading')}</>
78+
)}
79+
</Card>
80+
);
81+
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import {Button} from '@blueprintjs/core';
2+
import tanuki from '../../images/tanuki.png'
3+
import React from 'react';
4+
import {Trans, useTranslation} from 'react-i18next';
5+
6+
interface WarningProps {
7+
hideKey: string;
8+
headerKey: string;
9+
bodyKey: string;
10+
bodyComponents?: Record<string, React.ReactElement>;
11+
showButton?: boolean;
12+
className?: string;
13+
}
14+
15+
export function Warning({
16+
hideKey,
17+
headerKey,
18+
bodyKey,
19+
bodyComponents,
20+
showButton = true,
21+
className = "bg-slate-900 border-blue-800",
22+
}: WarningProps) {
23+
const { t } = useTranslation();
24+
const [hide, setHide] = React.useState<boolean>(() => {
25+
return localStorage.getItem(hideKey) === 'true';
26+
});
27+
React.useEffect(() => {
28+
localStorage.setItem(hideKey, hide.toString());
29+
}, [hide, hideKey]);
30+
31+
if (hide) {
32+
if (!showButton) {
33+
return <></>;
34+
}
35+
return (
36+
<div className="flex flex-col py-0 min-[1300px]:w-[1100px]">
37+
<div className="ml-auto">
38+
<Button
39+
small
40+
intent="success"
41+
onClick={() => {
42+
setHide(false);
43+
}}>
44+
{t('db.readme_show')}
45+
</Button>
46+
</div>
47+
</div>
48+
);
49+
}
50+
51+
return (
52+
<div className={`relative flex flex-col gap-2 items-center px-5 py-0 border min-[1300px]:w-[1100px] ${className}`}>
53+
<div className="absolute top-1 right-1">
54+
<Button
55+
icon="cross"
56+
small
57+
intent="danger"
58+
onClick={() => {
59+
setHide(true);
60+
}}
61+
/>
62+
</div>
63+
<div className="inline-flex pt-4">
64+
<img src={tanuki} className="w-15 h-10 mx-0" />
65+
<div className="font-semibold px-3 pt-2 text-xl w-50 text-gray-200">
66+
{t(headerKey)}
67+
</div>
68+
<img src={tanuki} className="w-15 h-10 mx-0" />
69+
</div>
70+
<div className="space-y-3 pb-3 text-s leading-5 text-gray-400">
71+
<Trans i18nKey={bodyKey} components={bodyComponents}>
72+
<p />
73+
<p>{{ rerun: t('viewer.rerun') }}</p>
74+
<p className="font-semibold leading-6 text-gray-200" />
75+
</Trans>
76+
</div>
77+
</div>
78+
);
79+
}
80+
81+
export const RiskWarning = () => (
82+
<Warning
83+
hideKey="hide-warning-risk"
84+
headerKey="warnings.gcsim_risk_title"
85+
bodyKey="warnings.gcsim_risk_body"
86+
bodyComponents={{
87+
b: <b />,
88+
p: <p className="text-gray-200" />,
89+
discordlink: <a href="https://discord.gg/m7jvjdxx7q" target="_blank" rel="noreferrer" />,
90+
}}
91+
className="bg-red-950 border-red-800"
92+
showButton={false}
93+
/>
94+
);

ui/packages/components/src/common/gcsim/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,6 @@ export * from "./GraphComponents/OuterLabelPie/OuterLabels";
99
export * from "./GraphComponents/OuterLabelPie/Tooltip";
1010
export * from "./NoData";
1111
export * from "./Refresh";
12-
export { OuterLabelPie, CardTitle, FloatStatTooltipContent };
12+
export * from "./LatestVersion";
13+
export * from "./Warning";
14+
export { OuterLabelPie, CardTitle, FloatStatTooltipContent };
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"v2.38": [
3+
"varesa",
4+
"luminepyro"
5+
]
6+
}

ui/packages/db/src/Pages/Database/DBVIew.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import eula from 'images/eula.png';
33
import {useTranslation} from 'react-i18next';
44
import InfiniteScroll from 'react-infinite-scroll-component';
55
import {ActionBar} from 'SharedComponents/ActionBar';
6-
import {Warning} from 'SharedComponents/Warning';
6+
import {Warning, RiskWarning} from '@gcsim/components';
77
import {ListView} from '../../SharedComponents/ListView';
88

99
type Props = {
@@ -17,7 +17,12 @@ export const DBView = (props: Props) => {
1717
return (
1818
<div className="flex flex-col gap-4 m-8 my-4 items-center">
1919
<ActionBar simCount={props.data.length} />
20-
<Warning />
20+
<RiskWarning />
21+
<Warning
22+
hideKey="hide-warning-db"
23+
headerKey="db.readme_header"
24+
bodyKey="db.readme_body"
25+
/>
2126
{props.data.length === 0 ? (
2227
<div className="6 flex flex-col justify-center items-center h-screen">
2328
<img src={eula} className=" object-contain opacity-50 w-32 h-32" />
Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import {Button, ButtonGroup} from '@blueprintjs/core';
1+
import {Button, Card} from '@blueprintjs/core';
22
import tagData from '@gcsim/data/src/tags.json';
33
import {useTranslation} from 'react-i18next';
4+
import {LatestVersion} from '@gcsim/components';
45
import {useLocation} from 'wouter';
56

67
export const Home = () => {
@@ -18,27 +19,36 @@ export const Home = () => {
1819
}
1920
return (
2021
<li key={key}>
21-
<span className="font-semibold text-rose-700">{name}</span>
22+
<span className="font-semibold text-rose-600">{name}</span>
2223
{`: ${t<string>('db.home.tag_desc_' + key)}`}
2324
</li>
2425
);
2526
});
2627
return (
27-
<div className="ml-2 mr-2 mt-2">
28-
<div className="text-center text-lg font-semibold text-indigo-600">
29-
{t<string>('db.home.welcome')}{' '}
30-
</div>
31-
<div className="mb-4">
32-
<p className="m-2">{t<string>('db.home.simpact_desc')}</p>
33-
<p className="m-2">{t<string>('db.home.simpact_tag_desc')} </p>
34-
<p className="m-2">{t<string>('db.home.simpact_tag_list_header')} </p>
35-
<ul className="list-disc m-4 ml-8">{sortedTagnames}</ul>
36-
</div>
37-
<ButtonGroup fill className="mb-4">
38-
<Button intent="primary" onClick={() => to('/database')}>
28+
<main className="w-full flex flex-col items-center flex-grow gap-4 py-4 px-4">
29+
<Button
30+
className="bp4-button !p-3 !rounded-md"
31+
intent="primary"
32+
onClick={() => to('/database')}
33+
>
34+
<span className="bp4-button-text text-3xl md:text-4xl lg:text-5xl font-semibold">
3935
{t<string>('db.home.get_started')}
40-
</Button>
41-
</ButtonGroup>
42-
</div>
36+
</span>
37+
</Button>
38+
<div className="flex flex-col gap-4 w-full md:w-fit">
39+
<Card className="flex flex-col gap-4 items-center">
40+
<h1 className="text-center text-xl md:text-2xl lg:text-4xl font-bold">
41+
{t<string>('db.home.welcome')}
42+
</h1>
43+
<div className="min-[1300px]:w-[1225px]">
44+
<p className="m-2">{t<string>('db.home.simpact_desc')}</p>
45+
<p className="m-2">{t<string>('db.home.simpact_tag_desc')} </p>
46+
<p className="m-2">{t<string>('db.home.simpact_tag_list_header')} </p>
47+
<ul className="list-disc m-4 ml-8">{sortedTagnames}</ul>
48+
</div>
49+
</Card>
50+
<LatestVersion />
51+
</div>
52+
</main>
4353
);
4454
};

0 commit comments

Comments
 (0)