Skip to content

Commit 851d4bf

Browse files
authored
Merge pull request #680 from gnmyt/updates/welcome-dialog
👋 Willkommensdialog hinzugefügt
2 parents 5d8a83a + 62c387b commit 851d4bf

File tree

20 files changed

+409
-3
lines changed

20 files changed

+409
-3
lines changed

client/public/assets/locales/en.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,22 @@
11
{
22
"failed": "Failed",
3+
"welcome": {
4+
"step": "Step",
5+
"title": "Welcome to MySpeed!",
6+
"subtext": "Let's set up MySpeed for the first time. Don't worry, it won't take long.",
7+
"provider_title": "Choose a provider",
8+
"provider_subtext": "Select the provider you want to use here. This provider will then perform your tests.",
9+
"data_title": "Set optimal data",
10+
"data_subtext": "Select your contractually agreed speeds in this step",
11+
"ms": "(in ms)",
12+
"mbps": "(in Mbps)",
13+
"accept_title": "Accept the terms",
14+
"accept_subtext": "In this step, we would like to inform you about the Ookla license. Read it and confirm that you have read and accept it by clicking on “Done”."
15+
},
316
"dialog": {
417
"okay": "Okay",
518
"done": "Done",
19+
"continue": "Continue",
620
"apply": "Yes, apply",
721
"update": "Update",
822
"close": "Close",

client/src/common/components/ProviderDialog/ProviderDialog.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {jsonRequest, patchRequest} from "@/common/utils/RequestUtil";
1111
import {Trans} from "react-i18next";
1212
import {ConfigContext} from "@/common/contexts/Config";
1313

14-
const providers = [
14+
export const providers = [
1515
{id: "ookla", name: "Ookla", image: OoklaImage},
1616
{id: "libre", name: "LibreSpeed", image: LibreImage},
1717
{id: "cloudflare", name: "Cloudflare", image: CloudflareImage}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import { DialogContext, DialogProvider } from "@/common/contexts/Dialog";
2+
import "./styles.sass";
3+
import { useContext, useState } from "react";
4+
import Greetings from "./steps/Greetings";
5+
import ProviderChooser from "./steps/ProviderChooser";
6+
import DataHelper from "./steps/DataHelper";
7+
import OoklaLicense from "./steps/OoklaLicense";
8+
import {patchRequest} from "@/common/utils/RequestUtil";
9+
import {ConfigContext} from "@/common/contexts/Config";
10+
import {t} from "i18next";
11+
12+
export const Dialog = () => {
13+
const close = useContext(DialogContext);
14+
15+
const [config, reloadConfig] = useContext(ConfigContext);
16+
17+
const [step, setStep] = useState(1);
18+
const [provider, setProvider] = useState("ookla");
19+
20+
const [ping, setPing] = useState(25);
21+
const [download, setDownload] = useState(100);
22+
const [upload, setUpload] = useState(50);
23+
const [animating, setAnimating] = useState(false);
24+
25+
const finish = async () => {
26+
await patchRequest("/config/provider", {value: provider});
27+
28+
if (config.previewMode) {
29+
localStorage.setItem("welcomeShown", "true");
30+
} else {
31+
await patchRequest("/config/ping", {value: ping});
32+
await patchRequest("/config/download", {value: download});
33+
await patchRequest("/config/upload", {value: upload});
34+
}
35+
36+
reloadConfig();
37+
38+
close(true);
39+
}
40+
41+
const continueStep = () => {
42+
if (step === (provider === "ookla" ? 4 : 3)) {
43+
finish();
44+
} else {
45+
setAnimating(true);
46+
setStep(step + 1);
47+
setTimeout(() => {
48+
setAnimating(false);
49+
}, 500);
50+
}
51+
}
52+
53+
return (
54+
<>
55+
<div className="welcome-banner">
56+
<div className={`welcome-inner ${animating ? 'slide-in' : ''}`}>
57+
{step === 1 && <Greetings />}
58+
{step === 2 && <ProviderChooser provider={provider} setProvider={setProvider} />}
59+
{step === 3 && <DataHelper ping={ping} setPing={setPing} download={download}
60+
setDownload={setDownload} upload={upload} setUpload={setUpload} />}
61+
{step === 4 && provider === "ookla" && <OoklaLicense />}
62+
</div>
63+
<div className="welcome-actions">
64+
<h3>{t("welcome.step")} {step}/{provider === "ookla" ? 4 : 3}</h3>
65+
<button className="dialog-btn" onClick={continueStep}>
66+
{step === (provider === "ookla" ? 4 : 3) ? t("dialog.done") : t("dialog.continue")}
67+
</button>
68+
</div>
69+
</div>
70+
</>
71+
)
72+
}
73+
74+
export const WelcomeDialog = (props) => {
75+
return (
76+
<>
77+
<DialogProvider close={props.onClose} disableClosing={true}>
78+
<Dialog />
79+
</DialogProvider>
80+
</>
81+
)
82+
}
Binary file not shown.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export {WelcomeDialog as default} from "./WelcomeDialog";
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import "./styles.sass";
2+
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
3+
import {faArrowDown, faArrowUp, faTableTennis} from "@fortawesome/free-solid-svg-icons";
4+
import {t} from "i18next";
5+
6+
export const DataHelper = ({setDownload, download, ping, setPing, upload, setUpload}) => {
7+
return (
8+
<div className="data-helper">
9+
<h2>{t("welcome.data_title")}</h2>
10+
<p>{t("welcome.data_subtext")}</p>
11+
12+
<div className="speeds">
13+
<div className="speed">
14+
<div className="speed-header">
15+
<FontAwesomeIcon icon={faTableTennis}/>
16+
<div className="speed-text">
17+
<h2>{t("latest.ping")}</h2>
18+
<p>{t("welcome.ms")}</p>
19+
</div>
20+
</div>
21+
<input type="number" placeholder={t("latest.ping")} className="dialog-input"
22+
value={ping} onChange={(e) => setPing(e.target.value)}/>
23+
</div>
24+
<div className="speed">
25+
<div className="speed-header">
26+
<FontAwesomeIcon icon={faArrowDown}/>
27+
<div className="speed-text">
28+
<h2>{t("latest.down")}</h2>
29+
<p>{t("welcome.mbps")}</p>
30+
</div>
31+
</div>
32+
<input type="number" placeholder={t("latest.down")} className="dialog-input"
33+
value={download} onChange={(e) => setDownload(e.target.value)}/>
34+
</div>
35+
<div className="speed">
36+
<div className="speed-header">
37+
<FontAwesomeIcon icon={faArrowUp}/>
38+
<div className="speed-text">
39+
<h2>{t("latest.up")}</h2>
40+
<p>{t("welcome.mbps")}</p>
41+
</div>
42+
</div>
43+
<input type="number" placeholder={t("latest.up")} className="dialog-input"
44+
value={upload} onChange={(e) => setUpload(e.target.value)}/>
45+
</div>
46+
</div>
47+
</div>
48+
)
49+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export {DataHelper as default} from "./DataHelper";
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
@import "@/common/styles/colors"
2+
3+
.data-helper
4+
5+
h2
6+
margin: 0 0 0.5rem
7+
color: $darker-white
8+
9+
p
10+
margin: 0
11+
color: $darker-white
12+
13+
14+
.speeds
15+
display: flex
16+
justify-content: center
17+
gap: 2rem
18+
margin-top: 1rem
19+
20+
.speed
21+
display: flex
22+
flex-direction: column
23+
align-items: center
24+
25+
input
26+
box-sizing: border-box
27+
width: 100%
28+
29+
.speed-header
30+
display: flex
31+
align-items: center
32+
margin-bottom: 0.5rem
33+
34+
svg
35+
font-size: 28pt
36+
margin-right: 0.5rem
37+
color: $green
38+
39+
.speed-text h2
40+
margin: 0
41+
color: $darker-white
42+
43+
.speed-text p
44+
margin: 0
45+
color: $subtext
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import Banner from "@/common/components/WelcomeDialog/banner.webp";
2+
import "./styles.sass";
3+
import {t} from "i18next";
4+
5+
export const Greetings = () => {
6+
return (
7+
<div className="welcome-greetings">
8+
<img src={Banner} alt="Welcome banner"/>
9+
<h2>{t("welcome.title")}</h2>
10+
<p>{t("welcome.subtext")}</p>
11+
</div>
12+
);
13+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export {Greetings as default} from "./Greetings";

0 commit comments

Comments
 (0)