diff options
Diffstat (limited to 'frontend/src/components')
| -rw-r--r-- | frontend/src/components/ConfirmDialog.tsx | 4 | ||||
| -rw-r--r-- | frontend/src/components/Discussions.tsx | 2 | ||||
| -rw-r--r-- | frontend/src/components/GameCategory.tsx | 6 | ||||
| -rw-r--r-- | frontend/src/components/GameEntry.tsx | 4 | ||||
| -rw-r--r-- | frontend/src/components/Leaderboards.tsx | 8 | ||||
| -rw-r--r-- | frontend/src/components/MapEntry.tsx | 4 | ||||
| -rw-r--r-- | frontend/src/components/MessageDialog.tsx | 6 | ||||
| -rw-r--r-- | frontend/src/components/MessageDialogLoad.tsx | 6 | ||||
| -rw-r--r-- | frontend/src/components/ModMenu.tsx | 20 | ||||
| -rw-r--r-- | frontend/src/components/RankingEntry.tsx | 6 | ||||
| -rw-r--r-- | frontend/src/components/Sidebar.tsx | 90 | ||||
| -rw-r--r-- | frontend/src/components/Summary.tsx | 10 | ||||
| -rw-r--r-- | frontend/src/components/UploadRunDialog.tsx | 46 |
13 files changed, 106 insertions, 106 deletions
diff --git a/frontend/src/components/ConfirmDialog.tsx b/frontend/src/components/ConfirmDialog.tsx index d8784d2..dbfbc62 100644 --- a/frontend/src/components/ConfirmDialog.tsx +++ b/frontend/src/components/ConfirmDialog.tsx | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | import React from "react"; | 1 | import React from "react"; |
| 2 | 2 | ||
| 3 | import "@css/Dialog.css" | 3 | import "@css/Dialog.css"; |
| 4 | 4 | ||
| 5 | interface ConfirmDialogProps { | 5 | interface ConfirmDialogProps { |
| 6 | title: string; | 6 | title: string; |
| @@ -25,7 +25,7 @@ const ConfirmDialog: React.FC<ConfirmDialogProps> = ({ title, subtitle, onConfir | |||
| 25 | </div> | 25 | </div> |
| 26 | </div> | 26 | </div> |
| 27 | </div> | 27 | </div> |
| 28 | ) | 28 | ); |
| 29 | }; | 29 | }; |
| 30 | 30 | ||
| 31 | export default ConfirmDialog; | 31 | export default ConfirmDialog; |
diff --git a/frontend/src/components/Discussions.tsx b/frontend/src/components/Discussions.tsx index 0c37355..51cf06a 100644 --- a/frontend/src/components/Discussions.tsx +++ b/frontend/src/components/Discussions.tsx | |||
| @@ -4,7 +4,7 @@ import { MapDiscussion, MapDiscussions, MapDiscussionsDetail } from "@customType | |||
| 4 | import { MapDiscussionContent } from "@customTypes/Content"; | 4 | import { MapDiscussionContent } from "@customTypes/Content"; |
| 5 | import { time_ago } from "@utils/Time"; | 5 | import { time_ago } from "@utils/Time"; |
| 6 | import { API } from "@api/Api"; | 6 | import { API } from "@api/Api"; |
| 7 | import "@css/Maps.css" | 7 | import "@css/Maps.css"; |
| 8 | import { Link } from "react-router-dom"; | 8 | import { Link } from "react-router-dom"; |
| 9 | import useConfirm from "@hooks/UseConfirm"; | 9 | import useConfirm from "@hooks/UseConfirm"; |
| 10 | 10 | ||
diff --git a/frontend/src/components/GameCategory.tsx b/frontend/src/components/GameCategory.tsx index 0d76d3e..79bb3fa 100644 --- a/frontend/src/components/GameCategory.tsx +++ b/frontend/src/components/GameCategory.tsx | |||
| @@ -2,7 +2,7 @@ import React from "react"; | |||
| 2 | import { Link } from "react-router-dom"; | 2 | import { Link } from "react-router-dom"; |
| 3 | 3 | ||
| 4 | import { Game, GameCategoryPortals } from "@customTypes/Game"; | 4 | import { Game, GameCategoryPortals } from "@customTypes/Game"; |
| 5 | import "@css/Games.css" | 5 | import "@css/Games.css"; |
| 6 | 6 | ||
| 7 | interface GameCategoryProps { | 7 | interface GameCategoryProps { |
| 8 | game: Game; | 8 | game: Game; |
| @@ -18,7 +18,7 @@ const GameCategory: React.FC<GameCategoryProps> = ({cat, game}) => { | |||
| 18 | <span className='games-page-item-body-item-num'>{cat.portal_count}</span> | 18 | <span className='games-page-item-body-item-num'>{cat.portal_count}</span> |
| 19 | </div> | 19 | </div> |
| 20 | </Link> | 20 | </Link> |
| 21 | ) | 21 | ); |
| 22 | } | 22 | }; |
| 23 | 23 | ||
| 24 | export default GameCategory; | 24 | export default GameCategory; |
diff --git a/frontend/src/components/GameEntry.tsx b/frontend/src/components/GameEntry.tsx index 454efb1..deeb0ed 100644 --- a/frontend/src/components/GameEntry.tsx +++ b/frontend/src/components/GameEntry.tsx | |||
| @@ -2,7 +2,7 @@ import React from "react"; | |||
| 2 | import { Link } from "react-router-dom"; | 2 | import { Link } from "react-router-dom"; |
| 3 | 3 | ||
| 4 | import { Game, GameCategoryPortals } from "@customTypes/Game"; | 4 | import { Game, GameCategoryPortals } from "@customTypes/Game"; |
| 5 | import "@css/Games.css" | 5 | import "@css/Games.css"; |
| 6 | 6 | ||
| 7 | import GameCategory from "@components/GameCategory"; | 7 | import GameCategory from "@components/GameCategory"; |
| 8 | 8 | ||
| @@ -25,7 +25,7 @@ const GameEntry: React.FC<GameEntryProps> = ({ game }) => { | |||
| 25 | </div> | 25 | </div> |
| 26 | <div id={game.id as any as string} className='games-page-item-body'> | 26 | <div id={game.id as any as string} className='games-page-item-body'> |
| 27 | {catInfo.map((cat, index) => { | 27 | {catInfo.map((cat, index) => { |
| 28 | return <GameCategory cat={cat} game={game} key={index}></GameCategory> | 28 | return <GameCategory cat={cat} game={game} key={index}></GameCategory>; |
| 29 | })} | 29 | })} |
| 30 | </div> | 30 | </div> |
| 31 | </div></Link> | 31 | </div></Link> |
diff --git a/frontend/src/components/Leaderboards.tsx b/frontend/src/components/Leaderboards.tsx index 1a4aa48..073c21b 100644 --- a/frontend/src/components/Leaderboards.tsx +++ b/frontend/src/components/Leaderboards.tsx | |||
| @@ -6,7 +6,7 @@ import { MapLeaderboard } from "@customTypes/Map"; | |||
| 6 | import { ticks_to_time, time_ago } from "@utils/Time"; | 6 | import { ticks_to_time, time_ago } from "@utils/Time"; |
| 7 | import { API } from "@api/Api"; | 7 | import { API } from "@api/Api"; |
| 8 | import useMessage from "@hooks/UseMessage"; | 8 | import useMessage from "@hooks/UseMessage"; |
| 9 | import "@css/Maps.css" | 9 | import "@css/Maps.css"; |
| 10 | 10 | ||
| 11 | interface LeaderboardsProps { | 11 | interface LeaderboardsProps { |
| 12 | mapID: string; | 12 | mapID: string; |
| @@ -26,7 +26,7 @@ const Leaderboards: React.FC<LeaderboardsProps> = ({ mapID }) => { | |||
| 26 | 26 | ||
| 27 | React.useEffect(() => { | 27 | React.useEffect(() => { |
| 28 | _fetch_map_leaderboards(); | 28 | _fetch_map_leaderboards(); |
| 29 | }, [pageNumber, navigate]) | 29 | }, [pageNumber, navigate]); |
| 30 | 30 | ||
| 31 | if (!data) { | 31 | if (!data) { |
| 32 | return ( | 32 | return ( |
| @@ -103,14 +103,14 @@ const Leaderboards: React.FC<LeaderboardsProps> = ({ mapID }) => { | |||
| 103 | 103 | ||
| 104 | {r.kind === "multiplayer" ? ( | 104 | {r.kind === "multiplayer" ? ( |
| 105 | <span> | 105 | <span> |
| 106 | <button onClick={() => { message("Demo Information", `Host Demo ID: ${r.host_demo_id} \nParnter Demo ID: ${r.partner_demo_id}`) }}><img src={ThreedotIcon} alt="demo_id" /></button> | 106 | <button onClick={() => { message("Demo Information", `Host Demo ID: ${r.host_demo_id} \nParnter Demo ID: ${r.partner_demo_id}`); }}><img src={ThreedotIcon} alt="demo_id" /></button> |
| 107 | <button onClick={() => window.location.href = `/api/v1/demos?uuid=${r.partner_demo_id}`}><img src={DownloadIcon} alt="download" style={{ filter: "hue-rotate(160deg) contrast(60%) saturate(1000%)" }} /></button> | 107 | <button onClick={() => window.location.href = `/api/v1/demos?uuid=${r.partner_demo_id}`}><img src={DownloadIcon} alt="download" style={{ filter: "hue-rotate(160deg) contrast(60%) saturate(1000%)" }} /></button> |
| 108 | <button onClick={() => window.location.href = `/api/v1/demos?uuid=${r.host_demo_id}`}><img src={DownloadIcon} alt="download" style={{ filter: "hue-rotate(300deg) contrast(60%) saturate(1000%)" }} /></button> | 108 | <button onClick={() => window.location.href = `/api/v1/demos?uuid=${r.host_demo_id}`}><img src={DownloadIcon} alt="download" style={{ filter: "hue-rotate(300deg) contrast(60%) saturate(1000%)" }} /></button> |
| 109 | </span> | 109 | </span> |
| 110 | ) : r.kind === "singleplayer" && ( | 110 | ) : r.kind === "singleplayer" && ( |
| 111 | 111 | ||
| 112 | <span> | 112 | <span> |
| 113 | <button onClick={() => { message("Demo Information", `Demo ID: ${r.demo_id}`) }}><img src={ThreedotIcon} alt="demo_id" /></button> | 113 | <button onClick={() => { message("Demo Information", `Demo ID: ${r.demo_id}`); }}><img src={ThreedotIcon} alt="demo_id" /></button> |
| 114 | <button onClick={() => window.location.href = `/api/v1/demos?uuid=${r.demo_id}`}><img src={DownloadIcon} alt="download" /></button> | 114 | <button onClick={() => window.location.href = `/api/v1/demos?uuid=${r.demo_id}`}><img src={DownloadIcon} alt="download" /></button> |
| 115 | </span> | 115 | </span> |
| 116 | )} | 116 | )} |
diff --git a/frontend/src/components/MapEntry.tsx b/frontend/src/components/MapEntry.tsx index 88137d8..5c58401 100644 --- a/frontend/src/components/MapEntry.tsx +++ b/frontend/src/components/MapEntry.tsx | |||
| @@ -6,7 +6,7 @@ const MapEntry: React.FC = () => { | |||
| 6 | <div> | 6 | <div> |
| 7 | 7 | ||
| 8 | </div> | 8 | </div> |
| 9 | ) | 9 | ); |
| 10 | } | 10 | }; |
| 11 | 11 | ||
| 12 | export default MapEntry; | 12 | export default MapEntry; |
diff --git a/frontend/src/components/MessageDialog.tsx b/frontend/src/components/MessageDialog.tsx index ae95f8d..e731c73 100644 --- a/frontend/src/components/MessageDialog.tsx +++ b/frontend/src/components/MessageDialog.tsx | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | import React from "react"; | 1 | import React from "react"; |
| 2 | 2 | ||
| 3 | import "@css/Dialog.css" | 3 | import "@css/Dialog.css"; |
| 4 | 4 | ||
| 5 | interface MessageDialogProps { | 5 | interface MessageDialogProps { |
| 6 | title: string; | 6 | title: string; |
| @@ -23,7 +23,7 @@ const MessageDialog: React.FC<MessageDialogProps> = ({ title, subtitle, onClose | |||
| 23 | </div> | 23 | </div> |
| 24 | </div> | 24 | </div> |
| 25 | </div> | 25 | </div> |
| 26 | ) | 26 | ); |
| 27 | } | 27 | }; |
| 28 | 28 | ||
| 29 | export default MessageDialog; | 29 | export default MessageDialog; |
diff --git a/frontend/src/components/MessageDialogLoad.tsx b/frontend/src/components/MessageDialogLoad.tsx index 000a2ab..b3726fb 100644 --- a/frontend/src/components/MessageDialogLoad.tsx +++ b/frontend/src/components/MessageDialogLoad.tsx | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | import React from "react"; | 1 | import React from "react"; |
| 2 | 2 | ||
| 3 | import "@css/Dialog.css" | 3 | import "@css/Dialog.css"; |
| 4 | 4 | ||
| 5 | interface MessageDialogLoadProps { | 5 | interface MessageDialogLoadProps { |
| 6 | title: string; | 6 | title: string; |
| @@ -23,7 +23,7 @@ const MessageDialogLoad: React.FC<MessageDialogLoadProps> = ({ title, onClose }) | |||
| 23 | </div> | 23 | </div> |
| 24 | </div> | 24 | </div> |
| 25 | </div> | 25 | </div> |
| 26 | ) | 26 | ); |
| 27 | } | 27 | }; |
| 28 | 28 | ||
| 29 | export default MessageDialogLoad; | 29 | export default MessageDialogLoad; |
diff --git a/frontend/src/components/ModMenu.tsx b/frontend/src/components/ModMenu.tsx index 19ce0ce..e7ef25c 100644 --- a/frontend/src/components/ModMenu.tsx +++ b/frontend/src/components/ModMenu.tsx | |||
| @@ -5,7 +5,7 @@ import { useNavigate } from "react-router-dom"; | |||
| 5 | import { MapSummary } from "@customTypes/Map"; | 5 | import { MapSummary } from "@customTypes/Map"; |
| 6 | import { ModMenuContent } from "@customTypes/Content"; | 6 | import { ModMenuContent } from "@customTypes/Content"; |
| 7 | import { API } from "@api/Api"; | 7 | import { API } from "@api/Api"; |
| 8 | import "@css/ModMenu.css" | 8 | import "@css/ModMenu.css"; |
| 9 | import useConfirm from "@hooks/UseConfirm"; | 9 | import useConfirm from "@hooks/UseConfirm"; |
| 10 | 10 | ||
| 11 | interface ModMenuProps { | 11 | interface ModMenuProps { |
| @@ -73,7 +73,7 @@ const ModMenu: React.FC<ModMenuProps> = ({ token, data, selectedRun, mapID }) => | |||
| 73 | if (success) { | 73 | if (success) { |
| 74 | navigate(0); | 74 | navigate(0); |
| 75 | } else { | 75 | } else { |
| 76 | alert("Error. Check logs.") | 76 | alert("Error. Check logs."); |
| 77 | } | 77 | } |
| 78 | } | 78 | } |
| 79 | } | 79 | } |
| @@ -87,7 +87,7 @@ const ModMenu: React.FC<ModMenuProps> = ({ token, data, selectedRun, mapID }) => | |||
| 87 | if (success) { | 87 | if (success) { |
| 88 | navigate(0); | 88 | navigate(0); |
| 89 | } else { | 89 | } else { |
| 90 | alert("Error. Check logs.") | 90 | alert("Error. Check logs."); |
| 91 | } | 91 | } |
| 92 | } | 92 | } |
| 93 | } | 93 | } |
| @@ -101,7 +101,7 @@ const ModMenu: React.FC<ModMenuProps> = ({ token, data, selectedRun, mapID }) => | |||
| 101 | if (success) { | 101 | if (success) { |
| 102 | navigate(0); | 102 | navigate(0); |
| 103 | } else { | 103 | } else { |
| 104 | alert("Error. Check logs.") | 104 | alert("Error. Check logs."); |
| 105 | } | 105 | } |
| 106 | } | 106 | } |
| 107 | } | 107 | } |
| @@ -115,7 +115,7 @@ const ModMenu: React.FC<ModMenuProps> = ({ token, data, selectedRun, mapID }) => | |||
| 115 | if (success) { | 115 | if (success) { |
| 116 | navigate(0); | 116 | navigate(0); |
| 117 | } else { | 117 | } else { |
| 118 | alert("Error. Check logs.") | 118 | alert("Error. Check logs."); |
| 119 | } | 119 | } |
| 120 | } | 120 | } |
| 121 | } | 121 | } |
| @@ -149,17 +149,17 @@ const ModMenu: React.FC<ModMenuProps> = ({ token, data, selectedRun, mapID }) => | |||
| 149 | }, [menu]); | 149 | }, [menu]); |
| 150 | 150 | ||
| 151 | React.useEffect(() => { | 151 | React.useEffect(() => { |
| 152 | const modview = document.querySelector("div#modview") as HTMLElement | 152 | const modview = document.querySelector("div#modview") as HTMLElement; |
| 153 | if (modview) { | 153 | if (modview) { |
| 154 | showButton ? modview.style.transform = "translateY(-68%)" | 154 | showButton ? modview.style.transform = "translateY(-68%)" |
| 155 | : modview.style.transform = "translateY(0%)" | 155 | : modview.style.transform = "translateY(0%)"; |
| 156 | } | 156 | } |
| 157 | 157 | ||
| 158 | const modview_block = document.querySelector("#modview_block") as HTMLElement | 158 | const modview_block = document.querySelector("#modview_block") as HTMLElement; |
| 159 | if (modview_block) { | 159 | if (modview_block) { |
| 160 | showButton ? modview_block.style.display = "none" : modview_block.style.display = "block" | 160 | showButton ? modview_block.style.display = "none" : modview_block.style.display = "block"; |
| 161 | } | 161 | } |
| 162 | }, [showButton]) | 162 | }, [showButton]); |
| 163 | 163 | ||
| 164 | return ( | 164 | return ( |
| 165 | <> | 165 | <> |
diff --git a/frontend/src/components/RankingEntry.tsx b/frontend/src/components/RankingEntry.tsx index 9ad9e1c..8db753a 100644 --- a/frontend/src/components/RankingEntry.tsx +++ b/frontend/src/components/RankingEntry.tsx | |||
| @@ -26,7 +26,7 @@ const RankingEntry: React.FC<RankingEntryProps> = (prop) => { | |||
| 26 | </div> | 26 | </div> |
| 27 | <span>{prop.curRankingData.total_score}</span> | 27 | <span>{prop.curRankingData.total_score}</span> |
| 28 | </div> | 28 | </div> |
| 29 | ) | 29 | ); |
| 30 | } else { | 30 | } else { |
| 31 | return ( | 31 | return ( |
| 32 | <div className='leaderboard-entry'> | 32 | <div className='leaderboard-entry'> |
| @@ -39,8 +39,8 @@ const RankingEntry: React.FC<RankingEntryProps> = (prop) => { | |||
| 39 | </div> | 39 | </div> |
| 40 | <span>{prop.currentLeaderboardType == RankingCategories.rankings_singleplayer ? prop.curRankingData.sp_score : prop.currentLeaderboardType == RankingCategories.rankings_multiplayer ? prop.curRankingData.mp_score : prop.curRankingData.overall_score}</span> | 40 | <span>{prop.currentLeaderboardType == RankingCategories.rankings_singleplayer ? prop.curRankingData.sp_score : prop.currentLeaderboardType == RankingCategories.rankings_multiplayer ? prop.curRankingData.mp_score : prop.curRankingData.overall_score}</span> |
| 41 | </div> | 41 | </div> |
| 42 | ) | 42 | ); |
| 43 | } | 43 | } |
| 44 | } | 44 | }; |
| 45 | 45 | ||
| 46 | export default RankingEntry; | 46 | export default RankingEntry; |
diff --git a/frontend/src/components/Sidebar.tsx b/frontend/src/components/Sidebar.tsx index 0a7efa8..8e2573c 100644 --- a/frontend/src/components/Sidebar.tsx +++ b/frontend/src/components/Sidebar.tsx | |||
| @@ -28,19 +28,19 @@ const Sidebar: React.FC<SidebarProps> = ({ setToken, profile, setProfile, onUplo | |||
| 28 | 28 | ||
| 29 | const handle_sidebar_click = (clicked_sidebar_idx: number) => { | 29 | const handle_sidebar_click = (clicked_sidebar_idx: number) => { |
| 30 | const btn = document.querySelectorAll("button.sidebar-button"); | 30 | const btn = document.querySelectorAll("button.sidebar-button"); |
| 31 | if (isSidebarOpen) { setSidebarOpen(false); _handle_sidebar_hide() } | 31 | if (isSidebarOpen) { setSidebarOpen(false); _handle_sidebar_hide(); } |
| 32 | // clusterfuck | 32 | // clusterfuck |
| 33 | btn.forEach((e, i) => { | 33 | btn.forEach((e, i) => { |
| 34 | btn[i].classList.remove("sidebar-button-selected") | 34 | btn[i].classList.remove("sidebar-button-selected"); |
| 35 | btn[i].classList.add("sidebar-button-deselected") | 35 | btn[i].classList.add("sidebar-button-deselected"); |
| 36 | }) | 36 | }); |
| 37 | btn[clicked_sidebar_idx].classList.add("sidebar-button-selected") | 37 | btn[clicked_sidebar_idx].classList.add("sidebar-button-selected"); |
| 38 | btn[clicked_sidebar_idx].classList.remove("sidebar-button-deselected") | 38 | btn[clicked_sidebar_idx].classList.remove("sidebar-button-deselected"); |
| 39 | }; | 39 | }; |
| 40 | 40 | ||
| 41 | const _handle_sidebar_hide = () => { | 41 | const _handle_sidebar_hide = () => { |
| 42 | const btn = document.querySelectorAll("button.sidebar-button") as NodeListOf<HTMLElement> | 42 | const btn = document.querySelectorAll("button.sidebar-button") as NodeListOf<HTMLElement>; |
| 43 | const span = document.querySelectorAll("button.sidebar-button>span") as NodeListOf<HTMLElement> | 43 | const span = document.querySelectorAll("button.sidebar-button>span") as NodeListOf<HTMLElement>; |
| 44 | const side = document.querySelector("#sidebar-list") as HTMLElement; | 44 | const side = document.querySelector("#sidebar-list") as HTMLElement; |
| 45 | const searchbar = document.querySelector("#searchbar") as HTMLInputElement; | 45 | const searchbar = document.querySelector("#searchbar") as HTMLInputElement; |
| 46 | const uploadRunBtn = document.querySelector("#upload-run") as HTMLInputElement; | 46 | const uploadRunBtn = document.querySelector("#upload-run") as HTMLInputElement; |
| @@ -49,42 +49,42 @@ const Sidebar: React.FC<SidebarProps> = ({ setToken, profile, setProfile, onUplo | |||
| 49 | if (isSidebarOpen) { | 49 | if (isSidebarOpen) { |
| 50 | if (profile) { | 50 | if (profile) { |
| 51 | const login = document.querySelectorAll(".login>button")[1] as HTMLElement; | 51 | const login = document.querySelectorAll(".login>button")[1] as HTMLElement; |
| 52 | login.style.opacity = "1" | 52 | login.style.opacity = "1"; |
| 53 | uploadRunBtn.style.width = "310px" | 53 | uploadRunBtn.style.width = "310px"; |
| 54 | uploadRunBtn.style.padding = "0.4em 0 0 11px" | 54 | uploadRunBtn.style.padding = "0.4em 0 0 11px"; |
| 55 | uploadRunSpan.style.opacity = "0" | 55 | uploadRunSpan.style.opacity = "0"; |
| 56 | setTimeout(() => { | 56 | setTimeout(() => { |
| 57 | uploadRunSpan.style.opacity = "1" | 57 | uploadRunSpan.style.opacity = "1"; |
| 58 | }, 100) | 58 | }, 100); |
| 59 | } | 59 | } |
| 60 | setSidebarOpen(false); | 60 | setSidebarOpen(false); |
| 61 | side.style.width = "320px" | 61 | side.style.width = "320px"; |
| 62 | btn.forEach((e, i) => { | 62 | btn.forEach((e, i) => { |
| 63 | e.style.width = (window.innerWidth > 1024) ? "310px" : "265px" | 63 | e.style.width = (window.innerWidth > 1024) ? "310px" : "265px"; |
| 64 | e.style.padding = "0.4em 0 0 11px" | 64 | e.style.padding = "0.4em 0 0 11px"; |
| 65 | setTimeout(() => { | 65 | setTimeout(() => { |
| 66 | span[i].style.opacity = "1" | 66 | span[i].style.opacity = "1"; |
| 67 | }, 100) | 67 | }, 100); |
| 68 | }); | 68 | }); |
| 69 | side.style.zIndex = "2" | 69 | side.style.zIndex = "2"; |
| 70 | } else { | 70 | } else { |
| 71 | if (profile) { | 71 | if (profile) { |
| 72 | const login = document.querySelectorAll(".login>button")[1] as HTMLElement; | 72 | const login = document.querySelectorAll(".login>button")[1] as HTMLElement; |
| 73 | login.style.opacity = "0" | 73 | login.style.opacity = "0"; |
| 74 | uploadRunBtn.style.width = "40px" | 74 | uploadRunBtn.style.width = "40px"; |
| 75 | uploadRunBtn.style.padding = "0.4em 0 0 5px" | 75 | uploadRunBtn.style.padding = "0.4em 0 0 5px"; |
| 76 | uploadRunSpan.style.opacity = "0" | 76 | uploadRunSpan.style.opacity = "0"; |
| 77 | } | 77 | } |
| 78 | setSidebarOpen(true); | 78 | setSidebarOpen(true); |
| 79 | side.style.width = "40px"; | 79 | side.style.width = "40px"; |
| 80 | searchbar.focus(); | 80 | searchbar.focus(); |
| 81 | btn.forEach((e, i) => { | 81 | btn.forEach((e, i) => { |
| 82 | e.style.width = "40px" | 82 | e.style.width = "40px"; |
| 83 | e.style.padding = "0.4em 0 0 5px" | 83 | e.style.padding = "0.4em 0 0 5px"; |
| 84 | span[i].style.opacity = "0" | 84 | span[i].style.opacity = "0"; |
| 85 | }) | 85 | }); |
| 86 | setTimeout(() => { | 86 | setTimeout(() => { |
| 87 | side.style.zIndex = "0" | 87 | side.style.zIndex = "0"; |
| 88 | }, 300); | 88 | }, 300); |
| 89 | } | 89 | } |
| 90 | }; | 90 | }; |
| @@ -94,7 +94,7 @@ const Sidebar: React.FC<SidebarProps> = ({ setToken, profile, setProfile, onUplo | |||
| 94 | setIsMobileSearchOpen(!isMobileSearchOpen); | 94 | setIsMobileSearchOpen(!isMobileSearchOpen); |
| 95 | } else { | 95 | } else { |
| 96 | if (!isSidebarLocked) { | 96 | if (!isSidebarLocked) { |
| 97 | _handle_sidebar_hide() | 97 | _handle_sidebar_hide(); |
| 98 | setIsSidebarLocked(true); | 98 | setIsSidebarLocked(true); |
| 99 | setTimeout(() => setIsSidebarLocked(false), 300); | 99 | setTimeout(() => setIsSidebarLocked(false), 300); |
| 100 | } | 100 | } |
| @@ -124,14 +124,14 @@ const Sidebar: React.FC<SidebarProps> = ({ setToken, profile, setProfile, onUplo | |||
| 124 | }; | 124 | }; |
| 125 | 125 | ||
| 126 | React.useEffect(() => { | 126 | React.useEffect(() => { |
| 127 | if (path === "/") { handle_sidebar_click(1) } | 127 | if (path === "/") { handle_sidebar_click(1); } |
| 128 | else if (path.includes("games")) { handle_sidebar_click(2) } | 128 | else if (path.includes("games")) { handle_sidebar_click(2); } |
| 129 | else if (path.includes("rankings")) { handle_sidebar_click(3) } | 129 | else if (path.includes("rankings")) { handle_sidebar_click(3); } |
| 130 | // else if (path.includes("news")) { handle_sidebar_click(4) } | 130 | // else if (path.includes("news")) { handle_sidebar_click(4) } |
| 131 | // else if (path.includes("scorelog")) { handle_sidebar_click(5) } | 131 | // else if (path.includes("scorelog")) { handle_sidebar_click(5) } |
| 132 | else if (path.includes("profile")) { handle_sidebar_click(4) } | 132 | else if (path.includes("profile")) { handle_sidebar_click(4); } |
| 133 | else if (path.includes("rules")) { handle_sidebar_click(5) } | 133 | else if (path.includes("rules")) { handle_sidebar_click(5); } |
| 134 | else if (path.includes("about")) { handle_sidebar_click(6) } | 134 | else if (path.includes("about")) { handle_sidebar_click(6); } |
| 135 | }, [path]); | 135 | }, [path]); |
| 136 | 136 | ||
| 137 | return ( | 137 | return ( |
| @@ -225,15 +225,15 @@ const Sidebar: React.FC<SidebarProps> = ({ setToken, profile, setProfile, onUplo | |||
| 225 | </Link> | 225 | </Link> |
| 226 | ))} | 226 | ))} |
| 227 | {searchData?.players.map((q, index) => | 227 | {searchData?.players.map((q, index) => |
| 228 | ( | 228 | ( |
| 229 | <Link to={ | 229 | <Link to={ |
| 230 | profile && q.steam_id === profile.steam_id ? "/profile" : | 230 | profile && q.steam_id === profile.steam_id ? "/profile" : |
| 231 | `/users/${q.steam_id}` | 231 | `/users/${q.steam_id}` |
| 232 | } className='search-player' key={index} onClick={_close_mobile_search_and_menu}> | 232 | } className='search-player' key={index} onClick={_close_mobile_search_and_menu}> |
| 233 | <img src={q.avatar_link} alt='pfp'></img> | 233 | <img src={q.avatar_link} alt='pfp'></img> |
| 234 | <span style={{ fontSize: `${36 - q.user_name.length * 0.8}px` }}>{q.user_name}</span> | 234 | <span style={{ fontSize: `${36 - q.user_name.length * 0.8}px` }}>{q.user_name}</span> |
| 235 | </Link> | 235 | </Link> |
| 236 | ))} | 236 | ))} |
| 237 | 237 | ||
| 238 | </div> | 238 | </div> |
| 239 | </div> | 239 | </div> |
diff --git a/frontend/src/components/Summary.tsx b/frontend/src/components/Summary.tsx index 922960b..ee50ce8 100644 --- a/frontend/src/components/Summary.tsx +++ b/frontend/src/components/Summary.tsx | |||
| @@ -2,7 +2,7 @@ import React from "react"; | |||
| 2 | import ReactMarkdown from "react-markdown"; | 2 | import ReactMarkdown from "react-markdown"; |
| 3 | 3 | ||
| 4 | import { MapSummary } from "@customTypes/Map"; | 4 | import { MapSummary } from "@customTypes/Map"; |
| 5 | import "@css/Maps.css" | 5 | import "@css/Maps.css"; |
| 6 | 6 | ||
| 7 | interface SummaryProps { | 7 | interface SummaryProps { |
| 8 | selectedRun: number | 8 | selectedRun: number |
| @@ -18,11 +18,11 @@ const Summary: React.FC<SummaryProps> = ({ selectedRun, setSelectedRun, data }) | |||
| 18 | function _select_run(idx: number, category_id: number) { | 18 | function _select_run(idx: number, category_id: number) { |
| 19 | const r = document.querySelectorAll("button.record"); | 19 | const r = document.querySelectorAll("button.record"); |
| 20 | r.forEach(e => (e as HTMLElement).style.backgroundColor = "#2b2e46"); | 20 | r.forEach(e => (e as HTMLElement).style.backgroundColor = "#2b2e46"); |
| 21 | (r[idx] as HTMLElement).style.backgroundColor = "#161723" | 21 | (r[idx] as HTMLElement).style.backgroundColor = "#161723"; |
| 22 | 22 | ||
| 23 | 23 | ||
| 24 | if (data && data.summary.routes.length !== 0) { | 24 | if (data && data.summary.routes.length !== 0) { |
| 25 | idx += data.summary.routes.filter(e => e.category.id < category_id).length // lethimcook | 25 | idx += data.summary.routes.filter(e => e.category.id < category_id).length; // lethimcook |
| 26 | setSelectedRun(idx); | 26 | setSelectedRun(idx); |
| 27 | } | 27 | } |
| 28 | }; | 28 | }; |
| @@ -34,7 +34,7 @@ const Summary: React.FC<SummaryProps> = ({ selectedRun, setSelectedRun, data }) | |||
| 34 | 34 | ||
| 35 | function _category_change() { | 35 | function _category_change() { |
| 36 | const btn = document.querySelectorAll("#section3 #category span button"); | 36 | const btn = document.querySelectorAll("#section3 #category span button"); |
| 37 | btn.forEach((e) => { (e as HTMLElement).style.backgroundColor = "#2b2e46" }); | 37 | btn.forEach((e) => { (e as HTMLElement).style.backgroundColor = "#2b2e46"; }); |
| 38 | // heavenly father forgive me for i have sinned. TODO: fix this bullshit with dynamic categories | 38 | // heavenly father forgive me for i have sinned. TODO: fix this bullshit with dynamic categories |
| 39 | const idx = selectedCategory === 1 ? 0 : data.map.is_coop ? selectedCategory - 3 : selectedCategory - 1; | 39 | const idx = selectedCategory === 1 ? 0 : data.map.is_coop ? selectedCategory - 3 : selectedCategory - 1; |
| 40 | (btn[idx] as HTMLElement).style.backgroundColor = "#202232"; | 40 | (btn[idx] as HTMLElement).style.backgroundColor = "#202232"; |
| @@ -42,7 +42,7 @@ const Summary: React.FC<SummaryProps> = ({ selectedRun, setSelectedRun, data }) | |||
| 42 | 42 | ||
| 43 | function _history_change() { | 43 | function _history_change() { |
| 44 | const btn = document.querySelectorAll("#section3 #history span button"); | 44 | const btn = document.querySelectorAll("#section3 #history span button"); |
| 45 | btn.forEach((e) => { (e as HTMLElement).style.backgroundColor = "#2b2e46" }); | 45 | btn.forEach((e) => { (e as HTMLElement).style.backgroundColor = "#2b2e46"; }); |
| 46 | (historySelected ? btn[1] as HTMLElement : btn[0] as HTMLElement).style.backgroundColor = "#202232"; | 46 | (historySelected ? btn[1] as HTMLElement : btn[0] as HTMLElement).style.backgroundColor = "#202232"; |
| 47 | }; | 47 | }; |
| 48 | 48 | ||
diff --git a/frontend/src/components/UploadRunDialog.tsx b/frontend/src/components/UploadRunDialog.tsx index dd609a1..445fe7c 100644 --- a/frontend/src/components/UploadRunDialog.tsx +++ b/frontend/src/components/UploadRunDialog.tsx | |||
| @@ -52,7 +52,7 @@ const UploadRunDialog: React.FC<UploadRunDialogProps> = ({ token, open, onClose, | |||
| 52 | } else { | 52 | } else { |
| 53 | fileInputRefPartner.current?.click(); | 53 | fileInputRefPartner.current?.click(); |
| 54 | } | 54 | } |
| 55 | } | 55 | }; |
| 56 | 56 | ||
| 57 | const _handle_drag_over = (e: React.DragEvent<HTMLDivElement>, host: boolean) => { | 57 | const _handle_drag_over = (e: React.DragEvent<HTMLDivElement>, host: boolean) => { |
| 58 | e.preventDefault(); | 58 | e.preventDefault(); |
| @@ -62,7 +62,7 @@ const UploadRunDialog: React.FC<UploadRunDialogProps> = ({ token, open, onClose, | |||
| 62 | } else { | 62 | } else { |
| 63 | setDragHighlightPartner(true); | 63 | setDragHighlightPartner(true); |
| 64 | } | 64 | } |
| 65 | } | 65 | }; |
| 66 | 66 | ||
| 67 | const _handle_drag_leave = (e: React.DragEvent<HTMLDivElement>, host: boolean) => { | 67 | const _handle_drag_leave = (e: React.DragEvent<HTMLDivElement>, host: boolean) => { |
| 68 | e.preventDefault(); | 68 | e.preventDefault(); |
| @@ -72,7 +72,7 @@ const UploadRunDialog: React.FC<UploadRunDialogProps> = ({ token, open, onClose, | |||
| 72 | } else { | 72 | } else { |
| 73 | setDragHighlightPartner(false); | 73 | setDragHighlightPartner(false); |
| 74 | } | 74 | } |
| 75 | } | 75 | }; |
| 76 | 76 | ||
| 77 | const _handle_drop = (e: React.DragEvent<HTMLDivElement>, host: boolean) => { | 77 | const _handle_drop = (e: React.DragEvent<HTMLDivElement>, host: boolean) => { |
| 78 | e.preventDefault(); | 78 | e.preventDefault(); |
| @@ -80,7 +80,7 @@ const UploadRunDialog: React.FC<UploadRunDialogProps> = ({ token, open, onClose, | |||
| 80 | setDragHighlight(true); | 80 | setDragHighlight(true); |
| 81 | 81 | ||
| 82 | _handle_file_change(e.dataTransfer.files, host); | 82 | _handle_file_change(e.dataTransfer.files, host); |
| 83 | } | 83 | }; |
| 84 | 84 | ||
| 85 | const _handle_dropdowns = (dropdown: number) => { | 85 | const _handle_dropdowns = (dropdown: number) => { |
| 86 | setDropdown1Vis(false); | 86 | setDropdown1Vis(false); |
| @@ -91,7 +91,7 @@ const UploadRunDialog: React.FC<UploadRunDialogProps> = ({ token, open, onClose, | |||
| 91 | setDropdown2Vis(!dropdown2Vis); | 91 | setDropdown2Vis(!dropdown2Vis); |
| 92 | document.querySelector("#dropdown2")?.scrollTo(0, 0); | 92 | document.querySelector("#dropdown2")?.scrollTo(0, 0); |
| 93 | } | 93 | } |
| 94 | } | 94 | }; |
| 95 | 95 | ||
| 96 | const _handle_game_select = async (game_id: string, game_name: string) => { | 96 | const _handle_game_select = async (game_id: string, game_name: string) => { |
| 97 | setLoading(true); | 97 | setLoading(true); |
| @@ -120,16 +120,16 @@ const UploadRunDialog: React.FC<UploadRunDialogProps> = ({ token, open, onClose, | |||
| 120 | if (token) { | 120 | if (token) { |
| 121 | if (games[selectedGameID].is_coop) { | 121 | if (games[selectedGameID].is_coop) { |
| 122 | if (uploadRunContent.host_demo === null) { | 122 | if (uploadRunContent.host_demo === null) { |
| 123 | await message("Error", "You must select a host demo to upload.") | 123 | await message("Error", "You must select a host demo to upload."); |
| 124 | return | 124 | return; |
| 125 | } else if (uploadRunContent.partner_demo === null) { | 125 | } else if (uploadRunContent.partner_demo === null) { |
| 126 | await message("Error", "You must select a partner demo to upload.") | 126 | await message("Error", "You must select a partner demo to upload."); |
| 127 | return | 127 | return; |
| 128 | } | 128 | } |
| 129 | } else { | 129 | } else { |
| 130 | if (uploadRunContent.host_demo === null) { | 130 | if (uploadRunContent.host_demo === null) { |
| 131 | await message("Error", "You must select a demo to upload.") | 131 | await message("Error", "You must select a demo to upload."); |
| 132 | return | 132 | return; |
| 133 | } | 133 | } |
| 134 | } | 134 | } |
| 135 | const demo = SourceDemoParser.default() | 135 | const demo = SourceDemoParser.default() |
| @@ -137,24 +137,24 @@ const UploadRunDialog: React.FC<UploadRunDialogProps> = ({ token, open, onClose, | |||
| 137 | .parse(await uploadRunContent.host_demo.arrayBuffer()); | 137 | .parse(await uploadRunContent.host_demo.arrayBuffer()); |
| 138 | const scoreboard = demo.findPacket<NetMessages.SvcUserMessage>((msg) => { | 138 | const scoreboard = demo.findPacket<NetMessages.SvcUserMessage>((msg) => { |
| 139 | return msg instanceof NetMessages.SvcUserMessage && msg.userMessage instanceof ScoreboardTempUpdate; | 139 | return msg instanceof NetMessages.SvcUserMessage && msg.userMessage instanceof ScoreboardTempUpdate; |
| 140 | }) | 140 | }); |
| 141 | 141 | ||
| 142 | if (!scoreboard) { | 142 | if (!scoreboard) { |
| 143 | await message("Error", "Error while processing demo: Unable to get scoreboard result. Either there is a demo that is corrupt or haven't been recorded in challenge mode.") | 143 | await message("Error", "Error while processing demo: Unable to get scoreboard result. Either there is a demo that is corrupt or haven't been recorded in challenge mode."); |
| 144 | return | 144 | return; |
| 145 | } | 145 | } |
| 146 | 146 | ||
| 147 | if (!demo.mapName || !MapNames[demo.mapName]) { | 147 | if (!demo.mapName || !MapNames[demo.mapName]) { |
| 148 | await message("Error", "Error while processing demo: Invalid map name.") | 148 | await message("Error", "Error while processing demo: Invalid map name."); |
| 149 | return | 149 | return; |
| 150 | } | 150 | } |
| 151 | 151 | ||
| 152 | if (selectedGameID === 0 && MapNames[demo.mapName] > 60) { | 152 | if (selectedGameID === 0 && MapNames[demo.mapName] > 60) { |
| 153 | await message("Error", "Error while processing demo: Invalid cooperative demo in singleplayer submission.") | 153 | await message("Error", "Error while processing demo: Invalid cooperative demo in singleplayer submission."); |
| 154 | return | 154 | return; |
| 155 | } else if (selectedGameID === 1 && MapNames[demo.mapName] <= 60) { | 155 | } else if (selectedGameID === 1 && MapNames[demo.mapName] <= 60) { |
| 156 | await message("Error", "Error while processing demo: Invalid singleplayer demo in cooperative submission.") | 156 | await message("Error", "Error while processing demo: Invalid singleplayer demo in cooperative submission."); |
| 157 | return | 157 | return; |
| 158 | } | 158 | } |
| 159 | 159 | ||
| 160 | const { portalScore, timeScore } = scoreboard.userMessage?.as<ScoreboardTempUpdate>() ?? {}; | 160 | const { portalScore, timeScore } = scoreboard.userMessage?.as<ScoreboardTempUpdate>() ?? {}; |
| @@ -207,7 +207,7 @@ const UploadRunDialog: React.FC<UploadRunDialogProps> = ({ token, open, onClose, | |||
| 207 | </div> | 207 | </div> |
| 208 | <div style={{ top: "110px" }} className={dropdown1Vis ? "upload-run-dropdown" : "upload-run-dropdown hidden"}> | 208 | <div style={{ top: "110px" }} className={dropdown1Vis ? "upload-run-dropdown" : "upload-run-dropdown hidden"}> |
| 209 | {games.map((game) => ( | 209 | {games.map((game) => ( |
| 210 | <div onClick={() => { _handle_game_select(game.id.toString(), game.name); _handle_dropdowns(1) }} key={game.id}>{game.name}</div> | 210 | <div onClick={() => { _handle_game_select(game.id.toString(), game.name); _handle_dropdowns(1); }} key={game.id}>{game.name}</div> |
| 211 | ))} | 211 | ))} |
| 212 | </div> | 212 | </div> |
| 213 | </div> | 213 | </div> |
| @@ -219,7 +219,7 @@ const UploadRunDialog: React.FC<UploadRunDialogProps> = ({ token, open, onClose, | |||
| 219 | 219 | ||
| 220 | <div> | 220 | <div> |
| 221 | <h3 style={{ margin: "10px 0px" }}>Host Demo</h3> | 221 | <h3 style={{ margin: "10px 0px" }}>Host Demo</h3> |
| 222 | <div onClick={() => { _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" : ""}`}> | 222 | <div onClick={() => { _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" : ""}`}> |
| 223 | <input ref={fileInputRef} type="file" name="host_demo" id="host_demo" accept=".dem" onChange={(e) => _handle_file_change(e.target.files, true)} /> | 223 | <input ref={fileInputRef} type="file" name="host_demo" id="host_demo" accept=".dem" onChange={(e) => _handle_file_change(e.target.files, true)} /> |
| 224 | {!uploadRunContent.host_demo ? | 224 | {!uploadRunContent.host_demo ? |
| 225 | <div> | 225 | <div> |
| @@ -239,7 +239,7 @@ const UploadRunDialog: React.FC<UploadRunDialogProps> = ({ token, open, onClose, | |||
| 239 | <> | 239 | <> |
| 240 | <div> | 240 | <div> |
| 241 | <h3 style={{ margin: "10px 0px" }}>Partner Demo</h3> | 241 | <h3 style={{ margin: "10px 0px" }}>Partner Demo</h3> |
| 242 | <div onClick={() => { _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" : ""}`}> | 242 | <div onClick={() => { _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" : ""}`}> |
| 243 | <input ref={fileInputRefPartner} type="file" name="partner_demo" id="partner_demo" accept=".dem" onChange={(e) => _handle_file_change(e.target.files, false)} /> {!uploadRunContent.partner_demo ? | 243 | <input ref={fileInputRefPartner} type="file" name="partner_demo" id="partner_demo" accept=".dem" onChange={(e) => _handle_file_change(e.target.files, false)} /> {!uploadRunContent.partner_demo ? |
| 244 | <div> | 244 | <div> |
| 245 | <span>Drag and drop</span> | 245 | <span>Drag and drop</span> |