From 35946dbb2feb7f9d1cbab16fb0602ce0303562e9 Mon Sep 17 00:00:00 2001 From: Wolfboy248 Date: Tue, 29 Oct 2024 10:09:17 +0100 Subject: refactor: upload run dialog, useMessage update, added loader spinner --- frontend/src/App.css | 22 +++++++++++- frontend/src/components/Leaderboards.tsx | 9 ++++- frontend/src/components/UploadRunDialog.tsx | 56 +++++++++++++++++++++-------- frontend/src/css/UploadRunDialog.css | 10 +++--- frontend/src/hooks/UseMessage.tsx | 4 +++ frontend/src/pages/Profile.tsx | 15 ++++---- frontend/src/pages/Rankings.tsx | 25 +++++++++---- 7 files changed, 108 insertions(+), 33 deletions(-) (limited to 'frontend/src') diff --git a/frontend/src/App.css b/frontend/src/App.css index b0445d8..14a9972 100644 --- a/frontend/src/App.css +++ b/frontend/src/App.css @@ -56,6 +56,26 @@ body { } } +.loader { + width: 48px; + height: 48px; + border: 5px solid #FFF; + border-bottom-color: transparent; + border-radius: 50%; + display: inline-block; + box-sizing: border-box; + animation: rotation 1s linear infinite; + } + +@keyframes rotation { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } +} + @font-face { font-family: 'BarlowCondensed-Bold'; src: local('BarlowCondensed-Bold'), url(./fonts/BarlowCondensed-Bold.ttf) format('truetype'); @@ -74,4 +94,4 @@ body { @font-face { font-family: 'BarlowSemiCondensed-SemiBold'; src: local('BarlowSemiCondensed-Regular'), url(./fonts/BarlowSemiCondensed-SemiBold.ttf) format('truetype'); -} \ No newline at end of file +} diff --git a/frontend/src/components/Leaderboards.tsx b/frontend/src/components/Leaderboards.tsx index f86aa7b..b9e071c 100644 --- a/frontend/src/components/Leaderboards.tsx +++ b/frontend/src/components/Leaderboards.tsx @@ -4,6 +4,7 @@ import { Link } from 'react-router-dom'; import { DownloadIcon, ThreedotIcon } from '../images/Images'; import { MapLeaderboard } from '../types/Map'; import { ticks_to_time, time_ago } from '../utils/Time'; +import useMessage from "../hooks/UseMessage"; import "../css/Maps.css" interface LeaderboardsProps { @@ -12,6 +13,7 @@ interface LeaderboardsProps { const Leaderboards: React.FC = ({ data }) => { + const { message, MessageDialogComponent } = useMessage(); const [pageNumber, setPageNumber] = React.useState(1); if (!data) { @@ -31,6 +33,10 @@ const Leaderboards: React.FC = ({ data }) => { }; return ( +
+
+ {MessageDialogComponent} +
= ({ data }) => { ) : r.kind === "singleplayer" && ( - + )} @@ -102,6 +108,7 @@ const Leaderboards: React.FC = ({ data }) => { ))}
+
); }; diff --git a/frontend/src/components/UploadRunDialog.tsx b/frontend/src/components/UploadRunDialog.tsx index a0d23e7..212a792 100644 --- a/frontend/src/components/UploadRunDialog.tsx +++ b/frontend/src/components/UploadRunDialog.tsx @@ -47,22 +47,36 @@ const UploadRunDialog: React.FC = ({ token, open, onClose, const [loading, setLoading] = React.useState(false); const [dragHightlight, setDragHighlight] = React.useState(false); + const [dragHightlightPartner, setDragHighlightPartner] = React.useState(false); const fileInputRef = React.useRef(null); - - const _handle_file_click = () => { - fileInputRef.current?.click(); + const fileInputRefPartner = React.useRef(null); + + const _handle_file_click = (host: boolean) => { + if (host) { + fileInputRef.current?.click(); + } else { + fileInputRefPartner.current?.click(); + } } - const _handle_drag_over = (e: React.DragEvent) => { + const _handle_drag_over = (e: React.DragEvent, host: boolean) => { e.preventDefault(); e.stopPropagation(); - setDragHighlight(true); + if (host) { + setDragHighlight(true); + } else { + setDragHighlightPartner(true); + } } - const _handle_drag_leave = (e: React.DragEvent) => { + const _handle_drag_leave = (e: React.DragEvent, host: boolean) => { e.preventDefault(); e.stopPropagation(); - setDragHighlight(false); + if (host) { + setDragHighlight(false); + } else { + setDragHighlightPartner(false); + } } const _handle_drop = (e: React.DragEvent, host: boolean) => { @@ -70,8 +84,6 @@ const UploadRunDialog: React.FC = ({ token, open, onClose, e.stopPropagation(); setDragHighlight(true); - console.log(e.dataTransfer.files); - _handle_file_change(e.dataTransfer.files, host); } @@ -102,7 +114,6 @@ const UploadRunDialog: React.FC = ({ token, open, onClose, }; const _handle_file_change = async (files: FileList | null, host: boolean) => { - console.log(files); if (files) { if (host) { setUploadRunContent({ @@ -155,13 +166,16 @@ const UploadRunDialog: React.FC = ({ token, open, onClose, const [ success, response ] = await API.post_record(token, uploadRunContent); await message("Upload Record", response); - console.log("weweew") onClose(success); + navigate("/profile"); } }; React.useEffect(() => { if (open) { + + setDragHighlightPartner(false); + setDragHighlight(false); _handle_game_select("1", "Portal 2 - Singleplayer"); // a different approach?. } }, [open]); @@ -208,14 +222,14 @@ const UploadRunDialog: React.FC = ({ token, open, onClose, Host Demo -
{_handle_drag_over(e)}} onDrop={(e) => {_handle_drop(e, true)}} onDragLeave={(e) => {_handle_drag_leave(e)}} className={`upload-run-drag-area ${dragHightlight ? "upload-run-drag-area-highlight" : ""} ${uploadRunContent.host_demo ? "upload-run-drag-area-hidden" : ""}`}> +
{_handle_file_click(true)}} onDragOver={(e) => {_handle_drag_over(e, true)}} onDrop={(e) => {_handle_drop(e, true)}} onDragLeave={(e) => {_handle_drag_leave(e, true)}} className={`upload-run-drag-area ${dragHightlight ? "upload-run-drag-area-highlight" : ""} ${uploadRunContent.host_demo ? "upload-run-drag-area-hidden" : ""}`}> _handle_file_change(e.target.files, true)} /> {!uploadRunContent.host_demo ?
Drag and drop
- Or click here - + Or click here
+
: null} @@ -227,7 +241,19 @@ const UploadRunDialog: React.FC = ({ token, open, onClose, ( <> Partner Demo - _handle_file_change(e.target.files, false)} /> +
{_handle_file_click(false)}} onDragOver={(e) => {_handle_drag_over(e, false)}} onDrop={(e) => {_handle_drop(e, false)}} onDragLeave={(e) => {_handle_drag_leave(e, false)}} className={`upload-run-drag-area ${dragHightlightPartner ? "upload-run-drag-area-highlight-partner" : ""} ${uploadRunContent.partner_demo ? "upload-run-drag-area-hidden" : ""}`}> + _handle_file_change(e.target.files, false)} /> {!uploadRunContent.partner_demo ? +
+ Drag and drop +
+ Or click here
+ +
+
+ : null} + + {uploadRunContent.partner_demo?.name} +
) } diff --git a/frontend/src/css/UploadRunDialog.css b/frontend/src/css/UploadRunDialog.css index c783d2a..737409e 100644 --- a/frontend/src/css/UploadRunDialog.css +++ b/frontend/src/css/UploadRunDialog.css @@ -23,6 +23,7 @@ div#upload-run{ outline: 8px solid #2b2e46; border-radius: 20px; font-size: 40px; + width: 400px; } #upload-run-menu-add>div, @@ -115,7 +116,7 @@ button:hover { width: 100%; } -#host_demo { +#host_demo, #partner_demo { background-color: rgba(0, 0, 0, 0); display: none; } @@ -123,18 +124,19 @@ button:hover { .upload-run-drag-area { border: 2px dashed grey; border-radius: 10px; - height: 200px; + height: 150px; cursor: pointer; - width: 300px; + width: 360px; transition: all 0.2s ease; text-align: center; display: flex; flex-direction: column; align-items: center; justify-content: center; + margin: 20px 0px; } -.upload-run-drag-area-highlight { +.upload-run-drag-area-highlight, .upload-run-drag-area-highlight-partner { border: 2px dashed white; } diff --git a/frontend/src/hooks/UseMessage.tsx b/frontend/src/hooks/UseMessage.tsx index 602cf65..9bfb713 100644 --- a/frontend/src/hooks/UseMessage.tsx +++ b/frontend/src/hooks/UseMessage.tsx @@ -29,6 +29,10 @@ const useMessage = () => { ); + const getDialogComponent = () => { + return MessageDialogComponent; + }; + return { message, MessageDialogComponent }; } diff --git a/frontend/src/pages/Profile.tsx b/frontend/src/pages/Profile.tsx index 5d1c75d..3dba3ae 100644 --- a/frontend/src/pages/Profile.tsx +++ b/frontend/src/pages/Profile.tsx @@ -103,10 +103,12 @@ const Profile: React.FC = ({ profile, token, gameData, onDeleteRec }; return ( -
- {ConfirmDialogComponent} - {MessageDialogComponent} -
+
+ {MessageDialogComponent} + {ConfirmDialogComponent} + +
+
{profile.profile ? ( @@ -266,7 +268,7 @@ const Profile: React.FC = ({ profile, token, gameData, onDeleteRec {e.date.split("T")[0]} - + {i === 0 && r.scores.length > 1 ? + {i === 0 && record!.scores.length > 1 ?
+
); }; diff --git a/frontend/src/pages/Rankings.tsx b/frontend/src/pages/Rankings.tsx index 9280b02..1830815 100644 --- a/frontend/src/pages/Rankings.tsx +++ b/frontend/src/pages/Rankings.tsx @@ -13,6 +13,9 @@ const Rankings: React.FC = () => { official, unofficial } + const [currentRankingType, setCurrentRankingType] = React.useState(LeaderboardTypes.official); + + const [leaderboardLoad, setLeaderboardLoad] = React.useState(false); enum RankingCategories { rankings_overall, @@ -23,6 +26,7 @@ const Rankings: React.FC = () => { const [load, setLoad] = React.useState(false); const _fetch_rankings = async () => { + setLeaderboardLoad(false); const rankings = await API.get_official_rankings(); setLeaderboardData(rankings); if (currentLeaderboardType == RankingCategories.rankings_singleplayer) { @@ -33,10 +37,12 @@ const Rankings: React.FC = () => { setCurrentLeaderboard(rankings.rankings_overall) } setLoad(true); + setLeaderboardLoad(true); } const __dev_fetch_unofficial_rankings = async () => { try { + setLeaderboardLoad(false); const rankings = await API.get_unofficial_rankings(); setLeaderboardData(rankings); if (currentLeaderboardType == RankingCategories.rankings_singleplayer) { @@ -47,6 +53,7 @@ const Rankings: React.FC = () => { } else { setCurrentLeaderboard(rankings.rankings_overall) } + setLeaderboardLoad(true); } catch (e) { console.log(e) } @@ -83,23 +90,23 @@ const Rankings: React.FC = () => {
- -
- - -
@@ -116,10 +123,16 @@ const Rankings: React.FC = () => {
- {currentLeaderboard?.map((curRankingData, i) => { + {leaderboardLoad && currentLeaderboard?.map((curRankingData, i) => { return }) } + + {leaderboardLoad ? null : +
+ +
+ }
: null} -- cgit v1.2.3