diff options
Diffstat (limited to 'frontend/src/components/pages/maplist.js')
| -rw-r--r-- | frontend/src/components/pages/maplist.js | 890 |
1 files changed, 0 insertions, 890 deletions
diff --git a/frontend/src/components/pages/maplist.js b/frontend/src/components/pages/maplist.js deleted file mode 100644 index a5c6c19..0000000 --- a/frontend/src/components/pages/maplist.js +++ /dev/null | |||
| @@ -1,890 +0,0 @@ | |||
| 1 | import React, { useEffect, useRef, useState } from 'react'; | ||
| 2 | import { useLocation, Link } from "react-router-dom"; | ||
| 3 | import { BrowserRouter as Router, Route, Routes, useNavigate } from 'react-router-dom'; | ||
| 4 | |||
| 5 | import "./maplist.css" | ||
| 6 | import img5 from "../../imgs/5.png" | ||
| 7 | import img6 from "../../imgs/6.png" | ||
| 8 | |||
| 9 | export default function Maplist(prop) { | ||
| 10 | const { token, setToken } = prop | ||
| 11 | const scrollRef = useRef(null) | ||
| 12 | const [games, setGames] = React.useState(null); | ||
| 13 | const [hasOpenedStatistics, setHasOpenedStatistics] = React.useState(false); | ||
| 14 | const [totalPortals, setTotalPortals] = React.useState(0); | ||
| 15 | const [loading, setLoading] = React.useState(true) | ||
| 16 | const location = useLocation(); | ||
| 17 | |||
| 18 | const [gameTitle, setGameTitle] = React.useState(""); | ||
| 19 | const [catPortalCount, setCatPortalCount] = React.useState(0); | ||
| 20 | let minPage; | ||
| 21 | let maxPage; | ||
| 22 | let currentPage; | ||
| 23 | let add = 0; | ||
| 24 | let gameState; | ||
| 25 | let catState = 0; | ||
| 26 | async function detectGame() { | ||
| 27 | const response = await fetch("https://lp.ardapektezol.com/api/v1/games", { | ||
| 28 | headers: { | ||
| 29 | 'Authorization': token | ||
| 30 | } | ||
| 31 | }); | ||
| 32 | |||
| 33 | const data = await response.json(); | ||
| 34 | |||
| 35 | const url = new URL(window.location.href) | ||
| 36 | |||
| 37 | const params = new URLSearchParams(url.search) | ||
| 38 | gameState = parseFloat(location.pathname.split("/")[2]) | ||
| 39 | |||
| 40 | if (gameState == 1) { | ||
| 41 | setGameTitle(data.data[0].name); | ||
| 42 | |||
| 43 | maxPage = 9; | ||
| 44 | minPage = 1; | ||
| 45 | createCategories(1); | ||
| 46 | } else if (gameState == 2) { | ||
| 47 | setGameTitle(data.data[1].name); | ||
| 48 | |||
| 49 | maxPage = 16; | ||
| 50 | minPage = 10; | ||
| 51 | add = 10 | ||
| 52 | createCategories(2); | ||
| 53 | } | ||
| 54 | |||
| 55 | let chapterParam = params.get("chapter") | ||
| 56 | |||
| 57 | currentPage = minPage; | ||
| 58 | |||
| 59 | if (chapterParam) { | ||
| 60 | currentPage = +chapterParam + add | ||
| 61 | } | ||
| 62 | |||
| 63 | changePage(currentPage); | ||
| 64 | |||
| 65 | // if (!loading) { | ||
| 66 | |||
| 67 | // document.querySelector("#catPortalCount").innerText = data.data[gameState - 1].category_portals[0].portal_count; | ||
| 68 | |||
| 69 | // } | ||
| 70 | |||
| 71 | setCatPortalCount(data.data[gameState - 1].category_portals[0].portal_count); | ||
| 72 | |||
| 73 | // if (chapterParam) { | ||
| 74 | // document.querySelector("#pageNumbers").innerText = `${chapterParam - minPage + 1}/${maxPage - minPage + 1}` | ||
| 75 | // } | ||
| 76 | } | ||
| 77 | |||
| 78 | function changeMaplistOrStatistics(index, name) { | ||
| 79 | const maplistBtns = document.querySelectorAll("#maplistBtn"); | ||
| 80 | maplistBtns.forEach((btn, i) => { | ||
| 81 | if (i == index) { | ||
| 82 | btn.className = "game-nav-btn selected" | ||
| 83 | |||
| 84 | if (name == "maplist") { | ||
| 85 | document.querySelector(".stats").style.display = "none"; | ||
| 86 | document.querySelector(".maplist").style.display = "block"; | ||
| 87 | document.querySelector(".maplist").setAttribute("currentTab", "maplist"); | ||
| 88 | } else { | ||
| 89 | document.querySelector(".stats").style.display = "block"; | ||
| 90 | document.querySelector(".maplist").style.display = "none"; | ||
| 91 | |||
| 92 | document.querySelector(".maplist-page").scrollTo({ top: 372, behavior: "smooth" }) | ||
| 93 | document.querySelector(".maplist").setAttribute("currentTab", "stats"); | ||
| 94 | setHasOpenedStatistics(true); | ||
| 95 | } | ||
| 96 | } else { | ||
| 97 | btn.className = "game-nav-btn"; | ||
| 98 | } | ||
| 99 | }); | ||
| 100 | } | ||
| 101 | |||
| 102 | async function createCategories(gameID) { | ||
| 103 | const response = await fetch("https://lp.ardapektezol.com/api/v1/games", { | ||
| 104 | headers: { | ||
| 105 | 'Authorization': token | ||
| 106 | } | ||
| 107 | }); | ||
| 108 | |||
| 109 | const data = await response.json(); | ||
| 110 | let categoriesArr = data.data[gameID - 1].category_portals; | ||
| 111 | |||
| 112 | if (document.querySelector(".maplist-maps") == null) { | ||
| 113 | return; | ||
| 114 | } | ||
| 115 | const gameNav = document.querySelector(".game-nav"); | ||
| 116 | gameNav.innerHTML = ""; | ||
| 117 | categoriesArr.forEach((category) => { | ||
| 118 | createCategory(category); | ||
| 119 | }); | ||
| 120 | |||
| 121 | setLoading(false); | ||
| 122 | } | ||
| 123 | |||
| 124 | let categoryNum = 0; | ||
| 125 | function createCategory(category) { | ||
| 126 | const gameNav = document.querySelector(".game-nav"); | ||
| 127 | |||
| 128 | categoryNum++; | ||
| 129 | const gameNavBtn = document.createElement("button"); | ||
| 130 | if (categoryNum == 1) { | ||
| 131 | gameNavBtn.className = "game-nav-btn selected"; | ||
| 132 | } else { | ||
| 133 | gameNavBtn.className = "game-nav-btn"; | ||
| 134 | } | ||
| 135 | gameNavBtn.id = "catBtn" | ||
| 136 | gameNavBtn.innerText = category.category.name; | ||
| 137 | |||
| 138 | gameNavBtn.addEventListener("click", (e) => { | ||
| 139 | changeCategory(category, e); | ||
| 140 | changePage(currentPage); | ||
| 141 | }) | ||
| 142 | |||
| 143 | gameNav.appendChild(gameNavBtn); | ||
| 144 | } | ||
| 145 | |||
| 146 | async function changeCategory(category, btn) { | ||
| 147 | const navBtns = document.querySelectorAll("#catBtn"); | ||
| 148 | navBtns.forEach((btns) => { | ||
| 149 | btns.classList.remove("selected"); | ||
| 150 | }); | ||
| 151 | |||
| 152 | btn.srcElement.classList.add("selected"); | ||
| 153 | const response = await fetch("https://lp.ardapektezol.com/api/v1/games", { | ||
| 154 | headers: { | ||
| 155 | 'Authorization': token | ||
| 156 | } | ||
| 157 | }); | ||
| 158 | |||
| 159 | const data = await response.json(); | ||
| 160 | catState = category.category.id - 1; | ||
| 161 | // console.log(catState) | ||
| 162 | document.querySelector("#catPortalCount").innerText = category.portal_count; | ||
| 163 | } | ||
| 164 | |||
| 165 | async function changePage(page) { | ||
| 166 | const pageNumbers = document.querySelector("#pageNumbers"); | ||
| 167 | |||
| 168 | pageNumbers.innerText = `${currentPage - minPage + 1}/${maxPage - minPage + 1}`; | ||
| 169 | |||
| 170 | const maplistMaps = document.querySelector(".maplist-maps"); | ||
| 171 | maplistMaps.innerHTML = ""; | ||
| 172 | for (let index = 0; index < 8; index++) { | ||
| 173 | const loadingAnimation = document.createElement("div"); | ||
| 174 | loadingAnimation.classList.add("loader"); | ||
| 175 | loadingAnimation.classList.add("loader-map") | ||
| 176 | maplistMaps.appendChild(loadingAnimation); | ||
| 177 | } | ||
| 178 | const data = await fetchMaps(page); | ||
| 179 | const maps = data.data.maps; | ||
| 180 | const name = data.data.chapter.name; | ||
| 181 | |||
| 182 | let chapterName = "Chapter"; | ||
| 183 | const chapterNumberOld = name.split(" - ")[0]; | ||
| 184 | let chapterNumber1 = chapterNumberOld.split("Chapter ")[1]; | ||
| 185 | if (chapterNumber1 == undefined) { | ||
| 186 | chapterName = "Course" | ||
| 187 | chapterNumber1 = chapterNumberOld.split("Course ")[1]; | ||
| 188 | } | ||
| 189 | const chapterNumber = chapterNumber1.toString().padStart(2, "0"); | ||
| 190 | const chapterTitle = name.split(" - ")[1]; | ||
| 191 | |||
| 192 | if (document.querySelector(".maplist-maps") == null) { | ||
| 193 | return; | ||
| 194 | } | ||
| 195 | const chapterNumberElement = document.querySelector(".chapter-num") | ||
| 196 | const chapterTitleElement = document.querySelector(".chapter-name") | ||
| 197 | chapterNumberElement.innerText = chapterName + " " + chapterNumber; | ||
| 198 | chapterTitleElement.innerText = chapterTitle; | ||
| 199 | |||
| 200 | maplistMaps.innerHTML = ""; | ||
| 201 | maps.forEach(map => { | ||
| 202 | let portalCount; | ||
| 203 | if (map.category_portals[catState] != undefined) { | ||
| 204 | portalCount = map.category_portals[catState].portal_count; | ||
| 205 | } else { | ||
| 206 | portalCount = map.category_portals[0].portal_count; | ||
| 207 | } | ||
| 208 | addMap(map.name, portalCount, map.image, map.difficulty + 1, map.id); | ||
| 209 | }); | ||
| 210 | |||
| 211 | const url = new URL(window.location.href) | ||
| 212 | |||
| 213 | const params = new URLSearchParams(url.search) | ||
| 214 | |||
| 215 | let chapterParam = params.get("chapter") | ||
| 216 | |||
| 217 | try { | ||
| 218 | const response = await fetch("https://lp.ardapektezol.com/api/v1/games", { | ||
| 219 | headers: { | ||
| 220 | 'Authorization': token | ||
| 221 | } | ||
| 222 | }); | ||
| 223 | |||
| 224 | const data = await response.json(); | ||
| 225 | |||
| 226 | const gameImg = document.querySelector(".game-img"); | ||
| 227 | |||
| 228 | gameImg.style.backgroundImage = `url(${data.data[0].image})`; | ||
| 229 | |||
| 230 | // const mapImg = document.querySelectorAll(".maplist-img"); | ||
| 231 | // mapImg.forEach((map) => { | ||
| 232 | // map.style.backgroundImage = `url(${data.data[0].image})`; | ||
| 233 | // }); | ||
| 234 | |||
| 235 | } catch (error) { | ||
| 236 | console.log("error fetching games:", error); | ||
| 237 | } | ||
| 238 | |||
| 239 | asignDifficulties(); | ||
| 240 | } | ||
| 241 | |||
| 242 | async function addMap(mapName, mapPortalCount, mapImage, difficulty, mapID) { | ||
| 243 | // jesus christ | ||
| 244 | const maplistItem = document.createElement("div"); | ||
| 245 | const maplistTitle = document.createElement("span"); | ||
| 246 | const maplistImgDiv = document.createElement("div"); | ||
| 247 | const maplistImg = document.createElement("div"); | ||
| 248 | const maplistPortalcountDiv = document.createElement("div"); | ||
| 249 | const maplistPortalcount = document.createElement("span"); | ||
| 250 | const b = document.createElement("b"); | ||
| 251 | const maplistPortalcountPortals = document.createElement("span"); | ||
| 252 | const difficultyDiv = document.createElement("div"); | ||
| 253 | const difficultyLabel = document.createElement("span"); | ||
| 254 | const difficultyBar = document.createElement("div"); | ||
| 255 | const difficultyPoint1 = document.createElement("div"); | ||
| 256 | const difficultyPoint2 = document.createElement("div"); | ||
| 257 | const difficultyPoint3 = document.createElement("div"); | ||
| 258 | const difficultyPoint4 = document.createElement("div"); | ||
| 259 | const difficultyPoint5 = document.createElement("div"); | ||
| 260 | |||
| 261 | maplistItem.className = "maplist-item"; | ||
| 262 | maplistTitle.className = "maplist-title"; | ||
| 263 | maplistImgDiv.className = "maplist-img-div"; | ||
| 264 | maplistImg.className = "maplist-img"; | ||
| 265 | maplistPortalcountDiv.className = "maplist-portalcount-div"; | ||
| 266 | maplistPortalcount.className = "maplist-portalcount"; | ||
| 267 | maplistPortalcountPortals.className = "maplist-portals"; | ||
| 268 | difficultyDiv.className = "difficulty-div"; | ||
| 269 | difficultyLabel.className = "difficulty-label"; | ||
| 270 | difficultyBar.className = "difficulty-bar"; | ||
| 271 | difficultyPoint1.className = "difficulty-point"; | ||
| 272 | difficultyPoint2.className = "difficulty-point"; | ||
| 273 | difficultyPoint3.className = "difficulty-point"; | ||
| 274 | difficultyPoint4.className = "difficulty-point"; | ||
| 275 | difficultyPoint5.className = "difficulty-point"; | ||
| 276 | |||
| 277 | |||
| 278 | maplistTitle.innerText = mapName; | ||
| 279 | difficultyLabel.innerText = "Difficulty: " | ||
| 280 | maplistPortalcountPortals.innerText = "portals" | ||
| 281 | b.innerText = mapPortalCount; | ||
| 282 | maplistImg.style.backgroundImage = `url(${mapImage})`; | ||
| 283 | difficultyBar.setAttribute("difficulty", difficulty) | ||
| 284 | maplistItem.setAttribute("id", mapID) | ||
| 285 | maplistItem.addEventListener("click", () => { | ||
| 286 | console.log(mapID) | ||
| 287 | window.location.href = "/maps/" + mapID | ||
| 288 | }) | ||
| 289 | |||
| 290 | // appends | ||
| 291 | // maplist item | ||
| 292 | maplistItem.appendChild(maplistTitle); | ||
| 293 | maplistImgDiv.appendChild(maplistImg); | ||
| 294 | maplistImgDiv.appendChild(maplistPortalcountDiv); | ||
| 295 | maplistPortalcountDiv.appendChild(maplistPortalcount); | ||
| 296 | maplistPortalcount.appendChild(b); | ||
| 297 | maplistPortalcountDiv.appendChild(maplistPortalcountPortals); | ||
| 298 | maplistItem.appendChild(maplistImgDiv); | ||
| 299 | maplistItem.appendChild(difficultyDiv); | ||
| 300 | difficultyDiv.appendChild(difficultyLabel); | ||
| 301 | difficultyDiv.appendChild(difficultyBar); | ||
| 302 | difficultyBar.appendChild(difficultyPoint1); | ||
| 303 | difficultyBar.appendChild(difficultyPoint2); | ||
| 304 | difficultyBar.appendChild(difficultyPoint3); | ||
| 305 | difficultyBar.appendChild(difficultyPoint4); | ||
| 306 | difficultyBar.appendChild(difficultyPoint5); | ||
| 307 | |||
| 308 | // display in place | ||
| 309 | const maplistMaps = document.querySelector(".maplist-maps"); | ||
| 310 | maplistMaps.appendChild(maplistItem); | ||
| 311 | } | ||
| 312 | |||
| 313 | async function fetchMaps(chapterID) { | ||
| 314 | try { | ||
| 315 | const response = await fetch(`https://lp.ardapektezol.com/api/v1/chapters/${chapterID}`, { | ||
| 316 | headers: { | ||
| 317 | 'Authorization': token | ||
| 318 | } | ||
| 319 | }); | ||
| 320 | |||
| 321 | const data = await response.json(); | ||
| 322 | return data; | ||
| 323 | } catch (err) { | ||
| 324 | console.log(err) | ||
| 325 | } | ||
| 326 | } | ||
| 327 | |||
| 328 | // difficulty stuff | ||
| 329 | function asignDifficulties() { | ||
| 330 | const difficulties = document.querySelectorAll(".difficulty-bar"); | ||
| 331 | difficulties.forEach((difficultyElement) => { | ||
| 332 | let difficulty = difficultyElement.getAttribute("difficulty"); | ||
| 333 | if (difficulty == "1") { | ||
| 334 | difficultyElement.childNodes[0].style.backgroundColor = "#51C355"; | ||
| 335 | } else if (difficulty == "2") { | ||
| 336 | difficultyElement.childNodes[0].style.backgroundColor = "#8AC93A"; | ||
| 337 | difficultyElement.childNodes[1].style.backgroundColor = "#8AC93A"; | ||
| 338 | } else if (difficulty == "3") { | ||
| 339 | difficultyElement.childNodes[0].style.backgroundColor = "#8AC93A"; | ||
| 340 | difficultyElement.childNodes[1].style.backgroundColor = "#8AC93A"; | ||
| 341 | difficultyElement.childNodes[2].style.backgroundColor = "#8AC93A"; | ||
| 342 | } else if (difficulty == "4") { | ||
| 343 | difficultyElement.childNodes[0].style.backgroundColor = "#C35F51"; | ||
| 344 | difficultyElement.childNodes[1].style.backgroundColor = "#C35F51"; | ||
| 345 | difficultyElement.childNodes[2].style.backgroundColor = "#C35F51"; | ||
| 346 | difficultyElement.childNodes[3].style.backgroundColor = "#C35F51"; | ||
| 347 | } else if (difficulty == "5") { | ||
| 348 | difficultyElement.childNodes[0].style.backgroundColor = "#C35F51"; | ||
| 349 | difficultyElement.childNodes[1].style.backgroundColor = "#C35F51"; | ||
| 350 | difficultyElement.childNodes[2].style.backgroundColor = "#C35F51"; | ||
| 351 | difficultyElement.childNodes[3].style.backgroundColor = "#C35F51"; | ||
| 352 | difficultyElement.childNodes[4].style.backgroundColor = "#C35F51"; | ||
| 353 | } | ||
| 354 | }); | ||
| 355 | } | ||
| 356 | |||
| 357 | const divRef = useRef(null); | ||
| 358 | |||
| 359 | React.useEffect(() => { | ||
| 360 | |||
| 361 | const lineChart = document.querySelector(".line-chart") | ||
| 362 | let tempTotalPortals = 0 | ||
| 363 | fetch("https://lp.ardapektezol.com/api/v1/games/1/maps", { | ||
| 364 | headers: { | ||
| 365 | 'Authorization': token | ||
| 366 | } | ||
| 367 | }) | ||
| 368 | .then(r => r.json()) | ||
| 369 | .then(d => { | ||
| 370 | d.data.maps.forEach((map, i) => { | ||
| 371 | tempTotalPortals += map.portal_count | ||
| 372 | }) | ||
| 373 | }) | ||
| 374 | .then(() => { | ||
| 375 | setTotalPortals(tempTotalPortals) | ||
| 376 | }) | ||
| 377 | async function createGraph() { | ||
| 378 | console.log(totalPortals) | ||
| 379 | // max | ||
| 380 | let items = [ | ||
| 381 | { | ||
| 382 | record: "100", | ||
| 383 | date: new Date(2011, 4, 4), | ||
| 384 | map: "Container Ride", | ||
| 385 | first: "tiny zach" | ||
| 386 | }, | ||
| 387 | { | ||
| 388 | record: "98", | ||
| 389 | date: new Date(2012, 6, 4), | ||
| 390 | map: "Container Ride", | ||
| 391 | first: "tiny zach" | ||
| 392 | }, | ||
| 393 | { | ||
| 394 | record: "94", | ||
| 395 | date: new Date(2013, 0, 1), | ||
| 396 | map: "Container Ride", | ||
| 397 | first: "tiny zach" | ||
| 398 | }, | ||
| 399 | { | ||
| 400 | record: "90", | ||
| 401 | date: new Date(2014, 0, 1), | ||
| 402 | map: "Container Ride", | ||
| 403 | first: "tiny zach" | ||
| 404 | }, | ||
| 405 | { | ||
| 406 | record: "88", | ||
| 407 | date: new Date(2015, 6, 14), | ||
| 408 | map: "Container Ride", | ||
| 409 | first: "tiny zach" | ||
| 410 | }, | ||
| 411 | { | ||
| 412 | record: "84", | ||
| 413 | date: new Date(2016, 8, 19), | ||
| 414 | map: "Container Ride", | ||
| 415 | first: "tiny zach" | ||
| 416 | }, | ||
| 417 | { | ||
| 418 | record: "82", | ||
| 419 | date: new Date(2017, 3, 20), | ||
| 420 | map: "Container Ride", | ||
| 421 | first: "tiny zach" | ||
| 422 | }, | ||
| 423 | { | ||
| 424 | record: "81", | ||
| 425 | date: new Date(2018, 2, 25), | ||
| 426 | map: "Container Ride", | ||
| 427 | first: "tiny zach" | ||
| 428 | }, | ||
| 429 | { | ||
| 430 | record: "80", | ||
| 431 | date: new Date(2019, 3, 4), | ||
| 432 | map: "Container Ride", | ||
| 433 | first: "tiny zach" | ||
| 434 | }, | ||
| 435 | { | ||
| 436 | record: "78", | ||
| 437 | date: new Date(2020, 11, 21), | ||
| 438 | map: "Container Ride", | ||
| 439 | first: "tiny zach" | ||
| 440 | }, | ||
| 441 | { | ||
| 442 | record: "77", | ||
| 443 | date: new Date(2021, 10, 25), | ||
| 444 | map: "Container Ride", | ||
| 445 | first: "tiny zach" | ||
| 446 | }, | ||
| 447 | { | ||
| 448 | record: "76", | ||
| 449 | date: new Date(2022, 4, 17), | ||
| 450 | map: "Container Ride", | ||
| 451 | first: "tiny zach" | ||
| 452 | }, | ||
| 453 | { | ||
| 454 | record: "75", | ||
| 455 | date: new Date(2023, 9, 31), | ||
| 456 | map: "Container Ride", | ||
| 457 | first: "tiny zach" | ||
| 458 | }, | ||
| 459 | { | ||
| 460 | record: "74", | ||
| 461 | date: new Date(2024, 4, 4), | ||
| 462 | map: "Container Ride", | ||
| 463 | first: "tiny zach" | ||
| 464 | }, | ||
| 465 | ] | ||
| 466 | |||
| 467 | function calculatePosition(date, startDate, endDate, maxWidth) { | ||
| 468 | const totalMilliseconds = endDate - startDate + 10000000000; | ||
| 469 | const millisecondsFromStart = date - startDate + 5000000000; | ||
| 470 | return (millisecondsFromStart / totalMilliseconds) * maxWidth | ||
| 471 | } | ||
| 472 | |||
| 473 | const minDate = items.reduce((min, dp) => dp.date < min ? dp.date : min, items[0].date) | ||
| 474 | const maxDate = items.reduce((max, dp) => dp.date > max ? dp.date : max, items[0].date) | ||
| 475 | |||
| 476 | const graph_width = document.querySelector(".portalcount-over-time-div").clientWidth | ||
| 477 | // console.log(graph_width) | ||
| 478 | |||
| 479 | const uniqueYears = new Set() | ||
| 480 | items.forEach(dp => uniqueYears.add(dp.date.getFullYear())) | ||
| 481 | let minYear = Infinity; | ||
| 482 | let maxYear = -Infinity; | ||
| 483 | |||
| 484 | items.forEach(dp => { | ||
| 485 | const year = dp.date.getFullYear(); | ||
| 486 | minYear = Math.min(minYear, year); | ||
| 487 | maxYear = Math.max(maxYear, year); | ||
| 488 | }); | ||
| 489 | |||
| 490 | // Add missing years to the set | ||
| 491 | for (let year = minYear; year <= maxYear; year++) { | ||
| 492 | uniqueYears.add(year); | ||
| 493 | } | ||
| 494 | const uniqueYearsArr = Array.from(uniqueYears) | ||
| 495 | |||
| 496 | items = items.map(dp => ({ | ||
| 497 | record: dp.record, | ||
| 498 | date: dp.date, | ||
| 499 | x: calculatePosition(dp.date, minDate, maxDate, lineChart.clientWidth), | ||
| 500 | map: dp.map, | ||
| 501 | first: dp.first | ||
| 502 | })) | ||
| 503 | |||
| 504 | const yearInterval = lineChart.clientWidth / uniqueYears.size | ||
| 505 | for (let index = 1; index < (uniqueYears.size); index++) { | ||
| 506 | const placeholderlmao = document.createElement("div") | ||
| 507 | const yearSpan = document.createElement("span") | ||
| 508 | yearSpan.style.position = "absolute" | ||
| 509 | placeholderlmao.style.height = "100%" | ||
| 510 | placeholderlmao.style.width = "2px" | ||
| 511 | placeholderlmao.style.backgroundColor = "#00000080" | ||
| 512 | placeholderlmao.style.position = `absolute` | ||
| 513 | const thing = calculatePosition(new Date(uniqueYearsArr[index], 0, 0), minDate, maxDate, lineChart.clientWidth) | ||
| 514 | placeholderlmao.style.left = `${thing}px` | ||
| 515 | yearSpan.style.left = `${thing}px` | ||
| 516 | yearSpan.style.bottom = "-34px" | ||
| 517 | yearSpan.innerText = uniqueYearsArr[index] | ||
| 518 | yearSpan.style.fontFamily = "BarlowSemiCondensed-Regular" | ||
| 519 | yearSpan.style.fontSize = "22px" | ||
| 520 | yearSpan.style.opacity = "0.8" | ||
| 521 | lineChart.appendChild(yearSpan) | ||
| 522 | |||
| 523 | } | ||
| 524 | |||
| 525 | let maxPortals; | ||
| 526 | let minPortals; | ||
| 527 | let precision; | ||
| 528 | let multiplier = 1; | ||
| 529 | for (let index = 0; index < items.length; index++) { | ||
| 530 | precision = Math.floor((items[0].record - items[items.length - 1].record)) | ||
| 531 | if (precision > 20) { | ||
| 532 | precision = 20 | ||
| 533 | } | ||
| 534 | minPortals = Math.floor((items[items.length - 1].record) / 10) * 10 | ||
| 535 | if (index == 0) { | ||
| 536 | maxPortals = items[index].record - minPortals | ||
| 537 | } | ||
| 538 | } | ||
| 539 | function calculateMultiplier(value) { | ||
| 540 | while (value > precision) { | ||
| 541 | multiplier += 1; | ||
| 542 | value -= precision; | ||
| 543 | } | ||
| 544 | } | ||
| 545 | calculateMultiplier(items[0].record); | ||
| 546 | // if (items[0].record > 10) { | ||
| 547 | // multiplier = 2; | ||
| 548 | // } | ||
| 549 | |||
| 550 | // Original cubic bezier control points | ||
| 551 | const P0 = { x: 0, y: 0 }; | ||
| 552 | const P1 = { x: 0.26, y: 1 }; | ||
| 553 | const P2 = { x: 0.74, y: 1 }; | ||
| 554 | const P3 = { x: 1, y: 0 }; | ||
| 555 | |||
| 556 | function calculateIntermediateControlPoints(t, P0, P1, P2, P3) { | ||
| 557 | const x = (1 - t) ** 3 * P0.x + | ||
| 558 | 3 * (1 - t) ** 2 * t * P1.x + | ||
| 559 | 3 * (1 - t) * t ** 2 * P2.x + | ||
| 560 | t ** 3 * P3.x; | ||
| 561 | |||
| 562 | const y = (1 - t) ** 3 * P0.y + | ||
| 563 | 3 * (1 - t) ** 2 * t * P1.y + | ||
| 564 | 3 * (1 - t) * t ** 2 * P2.y + | ||
| 565 | t ** 3 * P3.y; | ||
| 566 | |||
| 567 | return { x, y }; | ||
| 568 | } | ||
| 569 | |||
| 570 | |||
| 571 | let delay = 0; | ||
| 572 | for (let index = 0; index < items.length; index++) { | ||
| 573 | let chart_height = 340; | ||
| 574 | const item = items[index]; | ||
| 575 | delay += 0.05; | ||
| 576 | // console.log(lineChart.clientWidth) | ||
| 577 | |||
| 578 | // maxPortals++; | ||
| 579 | // maxPortals++; | ||
| 580 | |||
| 581 | let point_height = (chart_height / maxPortals) | ||
| 582 | |||
| 583 | for (let index = 0; index < (maxPortals / multiplier); index++) { | ||
| 584 | // console.log((index + 1) * multiplier) | ||
| 585 | let current_portal_count = (index + 1); | ||
| 586 | |||
| 587 | const placeholderDiv = document.createElement("div") | ||
| 588 | const numPortalsText = document.createElement("span") | ||
| 589 | const numPortalsTextBottom = document.createElement("span") | ||
| 590 | numPortalsText.innerText = (current_portal_count * multiplier) + minPortals | ||
| 591 | numPortalsTextBottom.innerText = minPortals | ||
| 592 | placeholderDiv.style.position = "absolute" | ||
| 593 | numPortalsText.style.position = "absolute" | ||
| 594 | numPortalsTextBottom.style.position = "absolute" | ||
| 595 | numPortalsText.style.left = "-37px" | ||
| 596 | numPortalsText.style.opacity = "0.2" | ||
| 597 | numPortalsTextBottom.style.opacity = "0.2" | ||
| 598 | numPortalsText.style.fontFamily = "BarlowSemiCondensed-Regular" | ||
| 599 | numPortalsTextBottom.style.fontFamily = "BarlowSemiCondensed-Regular" | ||
| 600 | numPortalsText.style.fontSize = "22px" | ||
| 601 | numPortalsTextBottom.style.left = "-37px" | ||
| 602 | numPortalsTextBottom.style.fontSize = "22px" | ||
| 603 | numPortalsTextBottom.style.fontWeight = "400" | ||
| 604 | numPortalsText.style.color = "#CDCFDF" | ||
| 605 | numPortalsTextBottom.style.color = "#CDCFDF" | ||
| 606 | numPortalsText.style.fontFamily = "inherit" | ||
| 607 | numPortalsTextBottom.style.fontFamily = "inherit" | ||
| 608 | numPortalsText.style.textAlign = "right" | ||
| 609 | numPortalsTextBottom.style.textAlign = "right" | ||
| 610 | numPortalsText.style.width = "30px" | ||
| 611 | numPortalsTextBottom.style.width = "30px" | ||
| 612 | placeholderDiv.style.bottom = `${(point_height * current_portal_count * multiplier) - 2}px` | ||
| 613 | numPortalsText.style.bottom = `${(point_height * current_portal_count * multiplier) - 2 - 9}px` | ||
| 614 | numPortalsTextBottom.style.bottom = `${0 - 2 - 8}px` | ||
| 615 | placeholderDiv.id = placeholderDiv.style.bottom | ||
| 616 | placeholderDiv.style.width = "100%" | ||
| 617 | placeholderDiv.style.height = "2px" | ||
| 618 | placeholderDiv.style.backgroundColor = "#2B2E46" | ||
| 619 | placeholderDiv.style.zIndex = "0" | ||
| 620 | |||
| 621 | if (index == 0) { | ||
| 622 | lineChart.appendChild(numPortalsTextBottom) | ||
| 623 | } | ||
| 624 | lineChart.appendChild(numPortalsText) | ||
| 625 | lineChart.appendChild(placeholderDiv) | ||
| 626 | } | ||
| 627 | |||
| 628 | const li = document.createElement("li"); | ||
| 629 | const lineSeg = document.createElement("div"); | ||
| 630 | const dataPoint = document.createElement("div"); | ||
| 631 | |||
| 632 | li.style = `--y: ${point_height * (item.record - minPortals) - 3}px; --x: ${item.x}px`; | ||
| 633 | lineSeg.className = "line-segment"; | ||
| 634 | dataPoint.className = "data-point"; | ||
| 635 | |||
| 636 | if (items[index + 1] !== undefined) { | ||
| 637 | const hypotenuse = Math.sqrt( | ||
| 638 | Math.pow(items[index + 1].x - items[index].x, 2) + | ||
| 639 | Math.pow((point_height * items[index + 1].record) - point_height * item.record, 2) | ||
| 640 | ); | ||
| 641 | const angle = Math.asin( | ||
| 642 | ((point_height * item.record) - (point_height * items[index + 1].record)) / hypotenuse | ||
| 643 | ); | ||
| 644 | |||
| 645 | lineSeg.style = `--hypotenuse: ${hypotenuse}; --angle: ${angle * (-180 / Math.PI)}`; | ||
| 646 | const t0 = index / items.length; | ||
| 647 | const t1 = (index + 1) / items.length | ||
| 648 | |||
| 649 | const P0t0 = calculateIntermediateControlPoints(t0, P0, P1, P2, P3); | ||
| 650 | const P1t1 = calculateIntermediateControlPoints(t1, P0, P1, P2, P3); | ||
| 651 | const bezierStyle = `cubic-bezier(${P0t0.x.toFixed(3)}, ${P0t0.y.toFixed(3)}, ${P1t1.x.toFixed(3)}, ${P1t1.y.toFixed(3)})` | ||
| 652 | lineSeg.style.animationTimingFunction = bezierStyle | ||
| 653 | lineSeg.style.animationDelay = delay + "s" | ||
| 654 | } | ||
| 655 | dataPoint.style.animationDelay = delay + "s" | ||
| 656 | |||
| 657 | let isHoveringOverData = true; | ||
| 658 | let isDataActive = false; | ||
| 659 | document.querySelector("#dataPointInfo").style.left = item.x + "px"; | ||
| 660 | document.querySelector("#dataPointInfo").style.bottom = (point_height * item.record - 3) + "px"; | ||
| 661 | dataPoint.addEventListener("mouseenter", (e) => { | ||
| 662 | isDataActive = true; | ||
| 663 | isHoveringOverData = true; | ||
| 664 | const dataPoints = document.querySelectorAll(".data-point") | ||
| 665 | dataPoints.forEach(point => { | ||
| 666 | point.classList.remove("data-point-active") | ||
| 667 | }); | ||
| 668 | dataPoint.classList.add("data-point-active") | ||
| 669 | document.querySelector("#dataPointRecord").innerText = item.record; | ||
| 670 | document.querySelector("#dataPointMap").innerText = item.map; | ||
| 671 | document.querySelector("#dataPointDate").innerText = item.date.toLocaleDateString("en-GB"); | ||
| 672 | document.querySelector("#dataPointFirst").innerText = item.first; | ||
| 673 | if ((lineChart.clientWidth - 400) < item.x) { | ||
| 674 | document.querySelector("#dataPointInfo").style.left = item.x - 400 + "px"; | ||
| 675 | } else { | ||
| 676 | document.querySelector("#dataPointInfo").style.left = item.x + "px"; | ||
| 677 | } | ||
| 678 | if ((lineChart.clientHeight - 115) < (point_height * (item.record - minPortals) - 3)) { | ||
| 679 | document.querySelector("#dataPointInfo").style.bottom = (point_height * (item.record - minPortals) - 3) - 115 + "px"; | ||
| 680 | } else { | ||
| 681 | document.querySelector("#dataPointInfo").style.bottom = (point_height * (item.record - minPortals) - 3) + "px"; | ||
| 682 | } | ||
| 683 | document.querySelector("#dataPointInfo").style.opacity = "1"; | ||
| 684 | document.querySelector("#dataPointInfo").style.zIndex = "10"; | ||
| 685 | }); | ||
| 686 | document.querySelector("#dataPointInfo").addEventListener("mouseenter", (e) => { | ||
| 687 | isHoveringOverData = true; | ||
| 688 | }) | ||
| 689 | document.querySelector("#dataPointInfo").addEventListener("mouseleave", (e) => { | ||
| 690 | isHoveringOverData = false; | ||
| 691 | }) | ||
| 692 | document.addEventListener("mousedown", () => { | ||
| 693 | if (!isHoveringOverData) { | ||
| 694 | isDataActive = false | ||
| 695 | dataPoint.classList.remove("data-point-active") | ||
| 696 | document.querySelector("#dataPointInfo").style.opacity = "0"; | ||
| 697 | document.querySelector("#dataPointInfo").style.zIndex = "0"; | ||
| 698 | } | ||
| 699 | }) | ||
| 700 | dataPoint.addEventListener("mouseenter", (e) => { | ||
| 701 | isHoveringOverData = false; | ||
| 702 | }) | ||
| 703 | document.querySelector(".chart").addEventListener("mouseleave", () => { | ||
| 704 | isDataActive = false | ||
| 705 | // fuck you | ||
| 706 | isHoveringOverData = true; | ||
| 707 | dataPoint.classList.remove("data-point-active") | ||
| 708 | document.querySelector("#dataPointInfo").style.opacity = "0"; | ||
| 709 | document.querySelector("#dataPointInfo").style.zIndex = "0"; | ||
| 710 | }) | ||
| 711 | |||
| 712 | li.appendChild(lineSeg); | ||
| 713 | li.appendChild(dataPoint); | ||
| 714 | lineChart.appendChild(li); | ||
| 715 | } | ||
| 716 | } | ||
| 717 | |||
| 718 | async function fetchGames() { | ||
| 719 | try { | ||
| 720 | const response = await fetch("https://lp.ardapektezol.com/api/v1/games", { | ||
| 721 | headers: { | ||
| 722 | 'Authorization': token | ||
| 723 | } | ||
| 724 | }); | ||
| 725 | |||
| 726 | const data = await response.json(); | ||
| 727 | |||
| 728 | const gameImg = document.querySelector(".game-img"); | ||
| 729 | |||
| 730 | gameImg.style.backgroundImage = `url(${data.data[0].image})`; | ||
| 731 | |||
| 732 | // const mapImg = document.querySelectorAll(".maplist-img"); | ||
| 733 | // mapImg.forEach((map) => { | ||
| 734 | // map.style.backgroundImage = `url(${data.data[0].image})`; | ||
| 735 | // }); | ||
| 736 | |||
| 737 | } catch (error) { | ||
| 738 | console.log("error fetching games:", error); | ||
| 739 | } | ||
| 740 | } | ||
| 741 | |||
| 742 | detectGame(); | ||
| 743 | |||
| 744 | const maplistImg = document.querySelector("#maplistImg"); | ||
| 745 | maplistImg.src = img5; | ||
| 746 | const statisticsImg = document.querySelector("#statisticsImg"); | ||
| 747 | statisticsImg.src = img6; | ||
| 748 | |||
| 749 | fetchGames(); | ||
| 750 | |||
| 751 | const handleResize = (entries) => { | ||
| 752 | for (let entry of entries) { | ||
| 753 | if (hasOpenedStatistics) { | ||
| 754 | lineChart.innerHTML = "" | ||
| 755 | createGraph() | ||
| 756 | } | ||
| 757 | if (document.querySelector(".maplist").getAttribute("currentTab") == "stats") { | ||
| 758 | document.querySelector(".stats").style.display = "block" | ||
| 759 | } else { | ||
| 760 | document.querySelector(".stats").style.display = "none" | ||
| 761 | } | ||
| 762 | } | ||
| 763 | }; | ||
| 764 | |||
| 765 | const resizeObserver = new ResizeObserver(handleResize); | ||
| 766 | |||
| 767 | // if (scrollRef.current) { | ||
| 768 | // //hi | ||
| 769 | // if (new URLSearchParams(new URL(window.location.href).search).get("chapter")) { | ||
| 770 | // setTimeout(() => { | ||
| 771 | // scrollRef.current.scrollIntoView({ behavior: "smooth", block: "start" }) | ||
| 772 | // }, 200); | ||
| 773 | // } | ||
| 774 | |||
| 775 | // } | ||
| 776 | |||
| 777 | if (divRef.current) { | ||
| 778 | resizeObserver.observe(divRef.current); | ||
| 779 | } | ||
| 780 | |||
| 781 | return () => { | ||
| 782 | if (divRef.current) { | ||
| 783 | resizeObserver.unobserve(divRef.current); | ||
| 784 | } | ||
| 785 | resizeObserver.disconnect(); | ||
| 786 | }; | ||
| 787 | |||
| 788 | |||
| 789 | }) | ||
| 790 | return ( | ||
| 791 | <div ref={divRef} className='maplist-page'> | ||
| 792 | <div className='maplist-page-content'> | ||
| 793 | <section className='maplist-page-header'> | ||
| 794 | <Link to='/games'><button className='nav-btn'> | ||
| 795 | <i className='triangle'></i> | ||
| 796 | <span>Games list</span> | ||
| 797 | </button></Link> | ||
| 798 | {!loading ? | ||
| 799 | <span><b id='gameTitle'>{gameTitle}</b></span> | ||
| 800 | : | ||
| 801 | <span><b id='gameTitle' className='loader-text'>LOADINGLOADING</b></span>} | ||
| 802 | </section> | ||
| 803 | |||
| 804 | <div className='game'> | ||
| 805 | {!loading ? | ||
| 806 | <div className='game-header'> | ||
| 807 | <div className='game-img'></div> | ||
| 808 | <div className='game-header-text'> | ||
| 809 | <span><b id='catPortalCount'>{catPortalCount}</b></span> | ||
| 810 | <span>portals</span> | ||
| 811 | </div> | ||
| 812 | </div> | ||
| 813 | : <div className='game-header loader'> | ||
| 814 | <div className='game-img'></div> | ||
| 815 | <div className='game-header-text'> | ||
| 816 | <span className='loader-text'><b id='catPortalCount'>00</b></span> | ||
| 817 | <span className='loader-text'>portals</span> | ||
| 818 | </div> | ||
| 819 | </div>} | ||
| 820 | {!loading ? | ||
| 821 | <div className='game-nav'> | ||
| 822 | </div> | ||
| 823 | : <div className='game-nav loader'> | ||
| 824 | </div>} | ||
| 825 | </div> | ||
| 826 | |||
| 827 | <div className='gameview-nav'> | ||
| 828 | <button id='maplistBtn' onClick={() => { changeMaplistOrStatistics(0, "maplist") }} className='game-nav-btn selected'> | ||
| 829 | <img id='maplistImg' /> | ||
| 830 | <span>Map List</span> | ||
| 831 | </button> | ||
| 832 | <button id='maplistBtn' onClick={() => changeMaplistOrStatistics(1, "stats")} className='game-nav-btn'> | ||
| 833 | <img id='statisticsImg' /> | ||
| 834 | <span>Statistics</span> | ||
| 835 | </button> | ||
| 836 | </div> | ||
| 837 | |||
| 838 | <div ref={scrollRef} className='maplist'> | ||
| 839 | <div className='chapter'> | ||
| 840 | <span className='chapter-num'>undefined</span><br /> | ||
| 841 | <span className='chapter-name'>undefined</span> | ||
| 842 | |||
| 843 | <div className='chapter-page-div'> | ||
| 844 | <button id='pageChanger' onClick={() => { currentPage--; currentPage < minPage ? currentPage = minPage : changePage(currentPage); }}> | ||
| 845 | <i className='triangle'></i> | ||
| 846 | </button> | ||
| 847 | <span id='pageNumbers'>0/0</span> | ||
| 848 | <button id='pageChanger' onClick={() => { currentPage++; currentPage > maxPage ? currentPage = maxPage : changePage(currentPage); }}> | ||
| 849 | <i style={{ transform: "rotate(180deg)" }} className='triangle'></i> | ||
| 850 | </button> | ||
| 851 | </div> | ||
| 852 | |||
| 853 | <div className='maplist-maps'> | ||
| 854 | </div> | ||
| 855 | </div> | ||
| 856 | </div> | ||
| 857 | |||
| 858 | <div style={{ display: "block" }} className='stats'> | ||
| 859 | <div className='portalcount-over-time-div'> | ||
| 860 | <span className='graph-title'>Portal count over time</span><br /> | ||
| 861 | |||
| 862 | <div className='portalcount-graph'> | ||
| 863 | <figure className='chart'> | ||
| 864 | <div style={{ display: "block" }}></div> | ||
| 865 | <div id="dataPointInfo"> | ||
| 866 | <div className='section-header'> | ||
| 867 | <span className='header-title'>Date</span> | ||
| 868 | <span className='header-title'>Map</span> | ||
| 869 | <span className='header-title'>Record</span> | ||
| 870 | <span className='header-title'>First completion</span> | ||
| 871 | </div> | ||
| 872 | <div className='divider'></div> | ||
| 873 | <div className='section-data'> | ||
| 874 | <span id='dataPointDate'></span> | ||
| 875 | <span id='dataPointMap'></span> | ||
| 876 | <span id='dataPointRecord'></span> | ||
| 877 | <span id='dataPointFirst'>Hello</span> | ||
| 878 | </div> | ||
| 879 | </div> | ||
| 880 | <ul className='line-chart'> | ||
| 881 | |||
| 882 | </ul> | ||
| 883 | </figure> | ||
| 884 | </div> | ||
| 885 | </div> | ||
| 886 | </div> | ||
| 887 | </div> | ||
| 888 | </div> | ||
| 889 | ) | ||
| 890 | } \ No newline at end of file | ||