diff options
Diffstat (limited to 'frontend/src/components')
| -rw-r--r-- | frontend/src/components/UploadRunDialog.tsx | 113 |
1 files changed, 52 insertions, 61 deletions
diff --git a/frontend/src/components/UploadRunDialog.tsx b/frontend/src/components/UploadRunDialog.tsx index 118b589..c02fdb8 100644 --- a/frontend/src/components/UploadRunDialog.tsx +++ b/frontend/src/components/UploadRunDialog.tsx | |||
| @@ -4,12 +4,12 @@ import { ScoreboardTempUpdate, SourceDemoParser, NetMessages } from '@nekz/sdp'; | |||
| 4 | 4 | ||
| 5 | import '@css/UploadRunDialog.css'; | 5 | import '@css/UploadRunDialog.css'; |
| 6 | import { Game } from '@customTypes/Game'; | 6 | import { Game } from '@customTypes/Game'; |
| 7 | import { Map } from '@customTypes/Map'; | ||
| 8 | import { API } from '@api/Api'; | 7 | import { API } from '@api/Api'; |
| 9 | import { useNavigate } from 'react-router-dom'; | 8 | import { useNavigate } from 'react-router-dom'; |
| 10 | import useMessage from '@hooks/UseMessage'; | 9 | import useMessage from '@hooks/UseMessage'; |
| 11 | import useConfirm from '@hooks/UseConfirm'; | 10 | import useConfirm from '@hooks/UseConfirm'; |
| 12 | import useMessageLoad from "@hooks/UseMessageLoad"; | 11 | import useMessageLoad from "@hooks/UseMessageLoad"; |
| 12 | import { MapNames } from '@customTypes/MapNames'; | ||
| 13 | 13 | ||
| 14 | interface UploadRunDialogProps { | 14 | interface UploadRunDialogProps { |
| 15 | token?: string; | 15 | token?: string; |
| @@ -27,19 +27,11 @@ const UploadRunDialog: React.FC<UploadRunDialogProps> = ({ token, open, onClose, | |||
| 27 | const navigate = useNavigate(); | 27 | const navigate = useNavigate(); |
| 28 | 28 | ||
| 29 | const [uploadRunContent, setUploadRunContent] = React.useState<UploadRunContent>({ | 29 | const [uploadRunContent, setUploadRunContent] = React.useState<UploadRunContent>({ |
| 30 | map_id: 0, | ||
| 31 | host_demo: null, | 30 | host_demo: null, |
| 32 | partner_demo: null, | 31 | partner_demo: null, |
| 33 | }); | 32 | }); |
| 34 | 33 | ||
| 35 | const [currentMap, setCurrentMap] = React.useState<string>(""); | ||
| 36 | |||
| 37 | const _set_current_map = (game_name: string) => { | ||
| 38 | setCurrentMap(game_name); | ||
| 39 | } | ||
| 40 | |||
| 41 | const [selectedGameID, setSelectedGameID] = React.useState<number>(0); | 34 | const [selectedGameID, setSelectedGameID] = React.useState<number>(0); |
| 42 | const [selectedGameMaps, setSelectedGameMaps] = React.useState<Map[]>([]); | ||
| 43 | const [selectedGameName, setSelectedGameName] = React.useState<string>(""); | 35 | const [selectedGameName, setSelectedGameName] = React.useState<string>(""); |
| 44 | 36 | ||
| 45 | // dropdowns | 37 | // dropdowns |
| @@ -50,6 +42,7 @@ const UploadRunDialog: React.FC<UploadRunDialogProps> = ({ token, open, onClose, | |||
| 50 | 42 | ||
| 51 | const [dragHightlight, setDragHighlight] = React.useState<boolean>(false); | 43 | const [dragHightlight, setDragHighlight] = React.useState<boolean>(false); |
| 52 | const [dragHightlightPartner, setDragHighlightPartner] = React.useState<boolean>(false); | 44 | const [dragHightlightPartner, setDragHighlightPartner] = React.useState<boolean>(false); |
| 45 | |||
| 53 | const fileInputRef = React.useRef<HTMLInputElement>(null); | 46 | const fileInputRef = React.useRef<HTMLInputElement>(null); |
| 54 | const fileInputRefPartner = React.useRef<HTMLInputElement>(null); | 47 | const fileInputRefPartner = React.useRef<HTMLInputElement>(null); |
| 55 | 48 | ||
| @@ -102,14 +95,6 @@ const UploadRunDialog: React.FC<UploadRunDialogProps> = ({ token, open, onClose, | |||
| 102 | 95 | ||
| 103 | const _handle_game_select = async (game_id: string, game_name: string) => { | 96 | const _handle_game_select = async (game_id: string, game_name: string) => { |
| 104 | setLoading(true); | 97 | setLoading(true); |
| 105 | const gameMaps = await API.get_game_maps(game_id); | ||
| 106 | setSelectedGameMaps(gameMaps); | ||
| 107 | setUploadRunContent({ | ||
| 108 | map_id: gameMaps.find((map) => !map.is_disabled)!.id, //gameMaps[0].id, | ||
| 109 | host_demo: null, | ||
| 110 | partner_demo: null, | ||
| 111 | }); | ||
| 112 | _set_current_map(gameMaps.find((map) => !map.is_disabled)!.name); | ||
| 113 | setSelectedGameID(parseInt(game_id) - 1); | 98 | setSelectedGameID(parseInt(game_id) - 1); |
| 114 | setSelectedGameName(game_name); | 99 | setSelectedGameName(game_name); |
| 115 | setLoading(false); | 100 | setLoading(false); |
| @@ -158,6 +143,20 @@ const UploadRunDialog: React.FC<UploadRunDialogProps> = ({ token, open, onClose, | |||
| 158 | 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.") |
| 159 | return | 144 | return |
| 160 | } | 145 | } |
| 146 | |||
| 147 | if (!demo.mapName || !MapNames[demo.mapName]) { | ||
| 148 | await message("Error", "Error while processing demo: Invalid map name.") | ||
| 149 | return | ||
| 150 | } | ||
| 151 | |||
| 152 | if (selectedGameID === 0 && MapNames[demo.mapName] > 60) { | ||
| 153 | await message("Error", "Error while processing demo: Invalid cooperative demo in singleplayer submission.") | ||
| 154 | return | ||
| 155 | } else if (selectedGameID === 1 && MapNames[demo.mapName] <= 60) { | ||
| 156 | await message("Error", "Error while processing demo: Invalid singleplayer demo in cooperative submission.") | ||
| 157 | return | ||
| 158 | } | ||
| 159 | |||
| 161 | const { portalScore, timeScore } = scoreboard.userMessage?.as<ScoreboardTempUpdate>() ?? {}; | 160 | const { portalScore, timeScore } = scoreboard.userMessage?.as<ScoreboardTempUpdate>() ?? {}; |
| 162 | 161 | ||
| 163 | const userConfirmed = await confirm("Upload Record", `Map Name: ${demo.mapName}\nPortal Count: ${portalScore}\nTicks: ${timeScore}\n\nAre you sure you want to upload this demo?`); | 162 | const userConfirmed = await confirm("Upload Record", `Map Name: ${demo.mapName}\nPortal Count: ${portalScore}\nTicks: ${timeScore}\n\nAre you sure you want to upload this demo?`); |
| @@ -167,10 +166,14 @@ const UploadRunDialog: React.FC<UploadRunDialogProps> = ({ token, open, onClose, | |||
| 167 | } | 166 | } |
| 168 | 167 | ||
| 169 | messageLoad("Uploading..."); | 168 | messageLoad("Uploading..."); |
| 170 | const [success, response] = await API.post_record(token, uploadRunContent); | 169 | const [success, response] = await API.post_record(token, uploadRunContent, MapNames[demo.mapName]); |
| 171 | messageLoadClose(); | 170 | messageLoadClose(); |
| 172 | await message("Upload Record", response); | 171 | await message("Upload Record", response); |
| 173 | if (success) { | 172 | if (success) { |
| 173 | setUploadRunContent({ | ||
| 174 | host_demo: null, | ||
| 175 | partner_demo: null, | ||
| 176 | }); | ||
| 174 | onClose(success); | 177 | onClose(success); |
| 175 | navigate("/profile"); | 178 | navigate("/profile"); |
| 176 | } | 179 | } |
| @@ -179,7 +182,6 @@ const UploadRunDialog: React.FC<UploadRunDialogProps> = ({ token, open, onClose, | |||
| 179 | 182 | ||
| 180 | React.useEffect(() => { | 183 | React.useEffect(() => { |
| 181 | if (open) { | 184 | if (open) { |
| 182 | |||
| 183 | setDragHighlightPartner(false); | 185 | setDragHighlightPartner(false); |
| 184 | setDragHighlight(false); | 186 | setDragHighlight(false); |
| 185 | _handle_game_select("1", "Portal 2 - Singleplayer"); // a different approach?. | 187 | _handle_game_select("1", "Portal 2 - Singleplayer"); // a different approach?. |
| @@ -203,37 +205,20 @@ const UploadRunDialog: React.FC<UploadRunDialogProps> = ({ token, open, onClose, | |||
| 203 | <div className='dropdown-cur'>{selectedGameName}</div> | 205 | <div className='dropdown-cur'>{selectedGameName}</div> |
| 204 | <i style={{ rotate: "-90deg", transform: "translate(-5px, 10px)" }} className="triangle"></i> | 206 | <i style={{ rotate: "-90deg", transform: "translate(-5px, 10px)" }} className="triangle"></i> |
| 205 | </div> | 207 | </div> |
| 206 | <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"}> |
| 207 | {games.map((game) => ( | 209 | {games.map((game) => ( |
| 208 | <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> |
| 209 | ))} | 211 | ))} |
| 210 | </div> | 212 | </div> |
| 211 | {!loading && ( | 213 | </div> |
| 212 | <> | ||
| 213 | <div style={{ padding: "25px 0px" }}> | ||
| 214 | <h3 style={{ margin: "0px 0px" }}>Select Map</h3> | ||
| 215 | <div onClick={() => _handle_dropdowns(2)} style={{ display: "flex", alignItems: "center", cursor: "pointer", justifyContent: "space-between", margin: "10px 0px" }}> | ||
| 216 | <span style={{ userSelect: "none" }}>{currentMap}</span> | ||
| 217 | <i style={{ rotate: "-90deg", transform: "translate(-5px, 10px)" }} className="triangle"></i> | ||
| 218 | </div> | ||
| 219 | </div> | ||
| 220 | <div style={{top: "220px"}} id='dropdown2' className={dropdown2Vis ? "upload-run-dropdown" : "upload-run-dropdown hidden"}> | ||
| 221 | {selectedGameMaps && selectedGameMaps.filter(gameMap => !gameMap.is_disabled).map((gameMap) => ( | ||
| 222 | <div onClick={() => { setUploadRunContent({ ...uploadRunContent, map_id: gameMap.id }); _set_current_map(gameMap.name); _handle_dropdowns(2); }} key={gameMap.id}>{gameMap.name}</div> | ||
| 223 | ))} | ||
| 224 | </div> | ||
| 225 | </> | ||
| 226 | |||
| 227 | )} | ||
| 228 | </div> | ||
| 229 | 214 | ||
| 230 | { | 215 | { |
| 231 | !loading && | 216 | !loading && |
| 232 | ( | 217 | ( |
| 233 | <> | 218 | <> |
| 234 | 219 | ||
| 235 | <div> | 220 | <div> |
| 236 | <h3 style={{margin: "10px 0px"}}>Host Demo</h3> | 221 | <h3 style={{ margin: "10px 0px" }}>Host Demo</h3> |
| 237 | <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" : ""}`}> |
| 238 | <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)} /> |
| 239 | {!uploadRunContent.host_demo ? | 224 | {!uploadRunContent.host_demo ? |
| @@ -252,38 +237,44 @@ const UploadRunDialog: React.FC<UploadRunDialogProps> = ({ token, open, onClose, | |||
| 252 | games[selectedGameID].is_coop && | 237 | games[selectedGameID].is_coop && |
| 253 | ( | 238 | ( |
| 254 | <> | 239 | <> |
| 255 | <div> | 240 | <div> |
| 256 | <h3 style={{margin: "10px 0px"}}>Partner Demo</h3> | 241 | <h3 style={{ margin: "10px 0px" }}>Partner Demo</h3> |
| 257 | <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" : ""}`}> |
| 258 | <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 ? |
| 259 | <div> | ||
| 260 | <span>Drag and drop</span> | ||
| 261 | <div> | 244 | <div> |
| 262 | <span style={{ fontFamily: "BarlowSemiCondensed-Regular" }}>Or click here</span><br /> | 245 | <span>Drag and drop</span> |
| 263 | <button style={{ borderRadius: "24px", padding: "5px 8px", margin: "5px 0px" }}>Upload</button> | 246 | <div> |
| 247 | <span style={{ fontFamily: "BarlowSemiCondensed-Regular" }}>Or click here</span><br /> | ||
| 248 | <button style={{ borderRadius: "24px", padding: "5px 8px", margin: "5px 0px" }}>Upload</button> | ||
| 249 | </div> | ||
| 264 | </div> | 250 | </div> |
| 265 | </div> | 251 | : null} |
| 266 | : null} | ||
| 267 | 252 | ||
| 268 | <span className="upload-run-demo-name">{uploadRunContent.partner_demo?.name}</span> | 253 | <span className="upload-run-demo-name">{uploadRunContent.partner_demo?.name}</span> |
| 254 | </div> | ||
| 269 | </div> | 255 | </div> |
| 270 | </div> | ||
| 271 | </> | 256 | </> |
| 272 | ) | 257 | ) |
| 273 | } | 258 | } |
| 274 | </div> | 259 | </div> |
| 275 | <div className='search-container'> | 260 | <div className='search-container'> |
| 261 | |||
| 262 | </div> | ||
| 276 | 263 | ||
| 277 | </div> | ||
| 278 | |||
| 279 | </> | 264 | </> |
| 280 | ) | 265 | ) |
| 281 | } | 266 | } |
| 282 | </div> | 267 | </div> |
| 283 | <div className='upload-run-buttons-container'> | 268 | <div className='upload-run-buttons-container'> |
| 284 | <button onClick={_upload_run}>Submit</button> | 269 | <button onClick={_upload_run}>Submit</button> |
| 285 | <button onClick={() => onClose(false)}>Cancel</button> | 270 | <button onClick={() => { |
| 286 | </div> | 271 | onClose(false); |
| 272 | setUploadRunContent({ | ||
| 273 | host_demo: null, | ||
| 274 | partner_demo: null, | ||
| 275 | }); | ||
| 276 | }}>Cancel</button> | ||
| 277 | </div> | ||
| 287 | </div> | 278 | </div> |
| 288 | </div> | 279 | </div> |
| 289 | </> | 280 | </> |