Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🚀 Optimierungen am Code #51

Merged
merged 57 commits into from
Aug 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
01bbb54
Updated the return value of the generateRelativeTime method to "N/A"
gnmyt Aug 29, 2022
aa02acd
MySpeed now displays N/A at the latest test if no test has been made yet
gnmyt Aug 29, 2022
5629e5f
Added the styling for the TestAreaComponent.jsx (error text)
gnmyt Aug 29, 2022
0cbe761
Added a message in thr TestAreaComponent.jsx if no tests exists
gnmyt Aug 29, 2022
ac62cdc
Added the unit to the placeholder in the update methods
gnmyt Aug 30, 2022
53afd85
Fixed a bug in the speedtest util
gnmyt Aug 30, 2022
521bfc1
Created an easier utility to send requests. This cleans some code up
gnmyt Aug 30, 2022
7b282df
Removed the deprecation warning in the client
gnmyt Aug 30, 2022
1ee901e
Moved the options of the DropdownComponent.jsx into a separate file
gnmyt Aug 30, 2022
b95a693
Moved the dialog infos of the DropdownComponent.jsx into a separate file
gnmyt Aug 30, 2022
1c21adb
Cleaned up the code of the DropdownComponent.jsx
gnmyt Aug 30, 2022
ceff778
Moved unsetButtonText -> unsetButton in DialogContext.jsx
gnmyt Aug 30, 2022
63ebf17
Changed the order of the functions in the DropdownComponent.jsx
gnmyt Aug 30, 2022
39a2366
Moved SpeedtestComponent.jsx tooltips -> tooltips.js
gnmyt Aug 30, 2022
5c7334c
Moved SpeedtestComponent.jsx errors -> errors.js
gnmyt Aug 30, 2022
cd64a0b
Moved SpeedtestComponent.jsx infos -> infos.js
gnmyt Aug 30, 2022
2384d8c
Cleaned up the code in the SpeedtestComponent.jsx
gnmyt Aug 30, 2022
c29e3b0
Moved HeaderComponent.jsx infos -> infos.js
gnmyt Aug 30, 2022
83a8110
Cleaned up the code in the HeaderComponent.jsx
gnmyt Aug 30, 2022
4f87104
Moved ConfigContext.jsx dialog -> dialog.jsx
gnmyt Aug 30, 2022
3369f6c
Cleaned up the code in the ConfigContext.jsx
gnmyt Aug 30, 2022
b5b7698
Cleaned up the code in the DialogContext.jsx & fixed the tooltip bug
gnmyt Aug 30, 2022
c10d4de
Fixed a bug in the DialogContext.jsx
gnmyt Aug 30, 2022
858feff
Added an id to the open dropdown entry in the HeaderComponent.jsx
gnmyt Aug 30, 2022
4564e12
The DropdownComponent.jsx now closes if clicked outside the component
gnmyt Aug 30, 2022
c03c079
Removed a debug statement in the DialogContext.jsx
gnmyt Aug 30, 2022
ae88a2c
Cleaned up the code in the SpeedtestContext.jsx
gnmyt Aug 30, 2022
86feaea
Created a test running animation
gnmyt Aug 30, 2022
2964fde
A running test now shows a pulse in the header
gnmyt Aug 30, 2022
9215960
Created the 192x192 logo for mobile devices
gnmyt Aug 30, 2022
b4625be
Added the 192x192 logo to the manifest.json
gnmyt Aug 30, 2022
6211b64
Added the apple touch icon to the index.html
gnmyt Aug 30, 2022
42a4770
Added a mobile break div to the LatestTestComponent.jsx
gnmyt Aug 30, 2022
3037af1
Made the scrollbar smaller on mobile devices
gnmyt Aug 30, 2022
b484237
Optimized the mobile version of the Header
gnmyt Aug 30, 2022
66afbc8
Optimized the mobile version of the LatestTest
gnmyt Aug 30, 2022
0cf5a66
Optimized the mobile version of the Speedtest
gnmyt Aug 30, 2022
f7eaa36
Added the vite pwa plugin to the dependencies
gnmyt Aug 30, 2022
2f8bb4e
Added vite pwa to the vite plugins array
gnmyt Aug 30, 2022
f696e77
Moved LatestTestComponent.jsx dialogs -> dialogs.jsx
gnmyt Aug 30, 2022
0fbb803
Cleaned up the code in the LatestTestComponent.jsx
gnmyt Aug 30, 2022
9561b02
Cleaned up the code in the StatusContext.jsx
gnmyt Aug 30, 2022
48d28e1
Cleaned up the code in the StatusContext.jsx
gnmyt Aug 30, 2022
00d40ca
Cleaned up the code in the styles.sass of the LatestTest
gnmyt Aug 30, 2022
ad38c32
Upgraded the client dependencies
gnmyt Aug 30, 2022
213bbc9
Fixed a bug with hoverable tooltips
gnmyt Aug 30, 2022
bcdbde2
Added the cron-parser dependency to the client
gnmyt Aug 30, 2022
6d4ca41
Added the updateDescription function to the DialogContext.jsx
gnmyt Aug 30, 2022
69f5bea
Created the DropdownComponent.jsx utils
gnmyt Aug 30, 2022
ea7eb92
The DropdownComponent.jsx cron now displays the current cron expressi…
gnmyt Aug 30, 2022
3813639
Fixed a bug in the DropdownComponent.jsx
gnmyt Aug 30, 2022
666c498
Fixed a bug in the LatestTestComponent.jsx
gnmyt Aug 30, 2022
f6cbb7a
Fixed the formatting in the info.jsx
gnmyt Aug 30, 2022
29d8ff7
Added the orange hover color
gnmyt Aug 30, 2022
a489a24
Added a custom keyframe for the update icon
gnmyt Aug 30, 2022
d434189
Updated the icon & the classes of the update available icon
gnmyt Aug 30, 2022
5c22fed
The speedtest icon is now hidden if the status is paused
gnmyt Aug 30, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions client/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;700;900&display=swap" rel="stylesheet">
<link rel="apple-touch-icon" href="/logo192.png" />
<link rel="manifest" href="/manifest.json" />
<title>MySpeed</title>
</head>
Expand Down
7,469 changes: 6,197 additions & 1,272 deletions client/package-lock.json

Large diffs are not rendered by default.

15 changes: 8 additions & 7 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,19 @@
"preview": "vite preview"
},
"dependencies": {
"@fortawesome/fontawesome-free-solid": "^5.0.13",
"@fortawesome/fontawesome-svg-core": "^6.1.2",
"@fortawesome/free-solid-svg-icons": "^6.1.2",
"@fortawesome/fontawesome-svg-core": "^6.2.0",
"@fortawesome/free-solid-svg-icons": "^6.2.0",
"@fortawesome/react-fontawesome": "^0.2.0",
"@vitejs/plugin-react": "^2.0.1",
"cron-parser": "^4.6.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"sass": "^1.54.5",
"@vitejs/plugin-react": "^2.0.1",
"vite": "^3.0.9"
"sass": "^1.54.6",
"vite": "^3.0.9",
"vite-plugin-pwa": "^0.12.3"
},
"devDependencies": {
"@types/react": "^18.0.17",
"@types/react": "^18.0.18",
"@types/react-dom": "^18.0.6"
}
}
Binary file added client/public/logo192.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 8 additions & 1 deletion client/public/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192",
"purpose": "maskable"
},
{
"src": "logo.png",
"type": "image/png",
Expand All @@ -16,5 +22,6 @@
],
"start_url": ".",
"display": "standalone",
"theme_color": "#232835"
"theme_color": "#232835",
"background_color": "#232835"
}
6 changes: 5 additions & 1 deletion client/src/App.sass
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,8 @@ hr
transform: scale(1.6)
filter: blur(5px)
100%
opacity: 1
opacity: 1

@media (max-width: 730px)
::-webkit-scrollbar
width: 5px
380 changes: 142 additions & 238 deletions client/src/common/components/Dropdown/DropdownComponent.jsx

Large diffs are not rendered by default.

16 changes: 16 additions & 0 deletions client/src/common/components/Dropdown/utils/infos.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export const healthChecksInfo = <>MySpeed verwendet <a href="https://healthchecks.io/" target="_blank">Healthchecks</a>,
um dich zu benachrichtigen, wenn dein Internet ausfällt. Um dies zu aktivieren, setze deine Ping URL in das Textfeld
ein. Mehr dazu <a href="https://myspeed.gnmyt.dev/instructions/settings/" target="_blank">hier</a></>;

export const creditsInfo = <><a href="https://github.com/gnmyt/myspeed" target="_blank"
rel="noreferrer">MySpeed</a> wird von GNMYT bereitgestellt und verwendet die <a
href="https://www.speedtest.net/apps/cli" target="_blank" rel="noreferrer">Speedtest-CLI</a> von Ookla.</>;

export const recommendationsError = <>Du musst mindestens 10 Tests machen, damit ein Durchschnitt ermittelt werden kann.
Ob die Tests manuell oder automatisch durchgeführt wurden ist egal.</>;

export const recommendationsInfo = (ping, download, upload) => <>Anhand der letzten 10 Testergebnisse wurde
festgestellt, dass der optimale Ping bei <span className="dialog-value">{ping} ms</span>, der Download bei <span
className="dialog-value">{download} Mbit/s </span>und der Upload bei <span
className="dialog-value">{upload} Mbit/s</span> liegt. <br/>Orientiere dich am besten an deinem Internetvertrag
und übernehme es nur, wenn es mit dem übereinstimmt.</>;
19 changes: 19 additions & 0 deletions client/src/common/components/Dropdown/utils/options.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
export const timeOptions = {
1: "24 Stunden (Standard)",
2: "2 Tage (Insgesamt)",
3: "7 Tage (Durchschnitt)",
4: "30 Tage (Durchschnitt)"
};

export const selectOptions = {
"* * * * *": "Durchgehend (jede Minute)",
"0,30 * * * *": "Sehr häufig (alle 30 Minuten)",
"0 * * * *": "Standard (jede Stunde)",
"0 0,3,6,9,12,15,18,21 * * *": "Selten (alle 3 Stunden)",
"0 0,6,12,18 * * *": "Sehr selten (alle 6 Stunden)"
}

export const exportOptions = {
json: "JSON-Datei",
csv: "CSV-Datei"
}
19 changes: 19 additions & 0 deletions client/src/common/components/Dropdown/utils/utils.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import {parseExpression} from "cron-parser";

// Parses cron as a locale string
export const parseCron = (cron) => {
try {
return parseExpression(cron).next().toDate().toLocaleString()
} catch (e) {
return <span className="icon-orange">Eingabe ungültig</span>;
}
}

// Fixes the cron provided by the user
export const stringifyCron = (cron) => {
try {
return parseExpression(cron).stringify();
} catch (e) {
return null;
}
}
58 changes: 21 additions & 37 deletions client/src/common/components/Header/HeaderComponent.jsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,21 @@
import "./styles.sass";
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
import {faCircleExclamation, faGaugeHigh, faGear} from "@fortawesome/free-solid-svg-icons";
import {faCircleArrowUp, faGaugeHigh, faGear} from "@fortawesome/free-solid-svg-icons";
import {useContext, useEffect, useState} from "react";
import DropdownComponent, {toggleDropdown} from "../Dropdown/DropdownComponent";
import {DialogContext} from "@/common/contexts/Dialog";
import {StatusContext} from "@/common/contexts/Status";
import {SpeedtestContext} from "@/common/contexts/Speedtests";

import {jsonRequest, postRequest} from "@/common/utils/RequestUtil";
import {updateInfo} from "@/common/components/Header/utils/infos";

function HeaderComponent() {

const [setDialog] = useContext(DialogContext);
const [icon, setIcon] = useState(faGear);
const [status, updateStatus] = useContext(StatusContext);
const updateTests = useContext(SpeedtestContext)[1];
const [updateAvailable, setUpdateAvailable] = useState("");

const headers = localStorage.getItem("password") ? {password: localStorage.getItem("password")} : {}
headers['content-type'] = 'application/json'

function switchDropdown() {
toggleDropdown(setIcon);
}
Expand All @@ -39,23 +36,18 @@ function HeaderComponent() {

setDialog({speedtest: true});

fetch("/api/speedtests/run", {headers, method: "POST"}).then(() => {
updateTests();
updateStatus();
setDialog();
});
postRequest("/speedtests/run").then(updateTests).then(updateStatus).then(setDialog);
}

useEffect(() => {
fetch("/api/info/version", {headers})
.then(res => res.json())
.then(version => {
if (version.remote.localeCompare(version.local, undefined,
{numeric: true, sensitivity: 'base'}) === 1)
setUpdateAvailable(version.remote);
});
async function updateVersion() {
const version = await jsonRequest("/info/version");

if (version.remote.localeCompare(version.local, undefined, {numeric: true, sensitivity: 'base'}) === 1)
setUpdateAvailable(version.remote);
}

// eslint-disable-next-line react-hooks/exhaustive-deps
updateVersion();
}, []);

return (
Expand All @@ -64,38 +56,30 @@ function HeaderComponent() {
<h2>Netzwerkanalyse</h2>
<div className="header-right">
{updateAvailable ?
<div><FontAwesomeIcon icon={faCircleExclamation} className="header-icon icon-orange"
<div><FontAwesomeIcon icon={faCircleArrowUp} className="header-icon icon-orange update-icon"
onClick={() => setDialog({
title: "Update verfügbar",
buttonText: "Okay",
description: <>Ein Update auf die Version {updateAvailable} ist
verfügbar. Sieh dir <a target="_blank"
href="https://github.com/gnmyt/myspeed/releases/latest"
rel="noreferrer">die Änderungen
an</a> und <a target="_blank"
href="https://myspeed.gnmyt.dev/setup/linux/"
rel="noreferrer">lade dir das Update
herunter</a>.</>
})}/></div>
: <></>}
<div className="tooltip-element tooltip-bottom">
description: updateInfo(updateAvailable)
})}/></div> : <></>}

{!status.paused ? <div className="tooltip-element tooltip-bottom">
<FontAwesomeIcon icon={faGaugeHigh}
className={"header-icon " + (status.running || status.paused ? "icon-red" : "")}
className={"header-icon " + (status.running ? "test-running" : "")}
onClick={startSpeedtest}/>
<span className="tooltip">Speedtest starten</span>
</div>
<span className="tooltip">{status.running ? "Speedtest läuft" : "Speedtest starten"}</span>
</div> : <></>}


<div className="tooltip-element tooltip-bottom">
<div className="tooltip-element tooltip-bottom" id="open-header">
<FontAwesomeIcon icon={icon} className="header-icon" onClick={switchDropdown}/>
<span className="tooltip">Einstellungen</span>
</div>

</div>
</div>
<DropdownComponent/>
</header>
)

}

export default HeaderComponent;
36 changes: 25 additions & 11 deletions client/src/common/components/Header/styles.sass
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,30 @@
transform: scale(1.1)
color: $green

.icon-red:hover
color: $red-hover
.test-running
animation: pulse 2s infinite
border-radius: 150px
color: $green

.test-running:hover
color: $green-hover

.update-icon
animation: pulse-update 2s infinite
border-radius: 150px

.update-icon:hover
color: $orange-hover

@keyframes pulse-update
0%
box-shadow: 0 0 0 0 $orange
70%
box-shadow: 0 0 0 10px #CCA92C00
100%
box-shadow: 0 0 0 0 #CCA92C00

@media (max-width: 425px)
@media (max-width: 460px)
.header-main
justify-content: center
.header-main div
Expand All @@ -48,14 +68,8 @@
height: 20px


@media (max-width: 280px)
.header-main
justify-content: center
@media (max-width: 360px)
.header-main h2
margin-left: 0
font-size: 16pt
text-overflow: ellipsis
overflow: hidden
.header-icon
width: 16px
height: 16px
overflow: hidden
5 changes: 5 additions & 0 deletions client/src/common/components/Header/utils/infos.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const updateInfo = (update) => <>Ein Update auf die Version {update} ist verfügbar. Sieh dir <a target="_blank"
href="https://github.com/gnmyt/myspeed/releases/latest"
rel="noreferrer">die
Änderungen an</a> und <a target="_blank" href="https://myspeed.gnmyt.dev/setup/linux/" rel="noreferrer">lade dir das
Update herunter</a>.</>;
31 changes: 8 additions & 23 deletions client/src/common/contexts/Config/ConfigContext.jsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,25 @@
import React, {useState, createContext, useEffect, useContext} from "react";
import {DialogContext} from "../Dialog";
import {request} from "@/common/utils/RequestUtil";
import {passwordRequiredDialog} from "@/common/contexts/Config/dialog";

export const ConfigContext = createContext();
export const ConfigContext = createContext({});

export const ConfigProvider = (props) => {

const [config, setConfig] = useState({});
const [setDialog] = useContext(DialogContext);

const reloadConfig = () => {
let passwordHeaders = localStorage.getItem("password") ? {password: localStorage.getItem("password")} : {}
fetch("/api/config", {headers: passwordHeaders})
.then(res => {
if (!res.ok) throw new Error();
return res;
request("/config").then(res => {
if (!res.ok) throw "No connection to server";
return res.json();
})
.then(res => res.json())
.then(result => setConfig(result))
.catch(() => setDialog({
title: "Passwort erforderlich",
placeholder: "Dein Passwort",
description: localStorage.getItem("password") ? <span className="icon-red">Das von dir eingegebene Passwort ist falsch</span> : "",
type: "password",
buttonText: "Fertig",
onClose: () => window.location.reload(),
onSuccess: (value) => {
localStorage.setItem("password", value);
window.location.reload();
}
}));
.catch(() => setDialog(passwordRequiredDialog));
}

useEffect(() => {
reloadConfig();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
useEffect(reloadConfig, []);

return (
<ConfigContext.Provider value={[config, reloadConfig]}>
Expand Down
12 changes: 12 additions & 0 deletions client/src/common/contexts/Config/dialog.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export const passwordRequiredDialog = {
title: "Passwort erforderlich",
placeholder: "Dein Passwort",
description: localStorage.getItem("password") ? <span className="icon-red">Das von dir eingegebene Passwort ist falsch</span> : "",
type: "password",
buttonText: "Fertig",
onClose: () => window.location.reload(),
onSuccess: (value) => {
localStorage.setItem("password", value);
window.location.reload();
}
}
Loading