From f2001b412653180fa75dbbb3b63288bfaca312e0 Mon Sep 17 00:00:00 2001 From: Trenton Zimmer <66042448+trmazi@users.noreply.github.com> Date: Sat, 4 Oct 2025 17:36:56 -0400 Subject: [PATCH] finish rival support. move to new vue router, fix buttons and a web crash bug --- .env.development | 2 +- .env.production | 2 +- public/assets/games/ddr/card/20.webp | Bin 0 -> 34252 bytes public/data-sources/changelog.json | 3 +- src/components/ArcadeCard.vue | 8 +- src/components/Cards/GameHeader.vue | 18 +- src/constants/index.js | 38 +++- src/router/index.js | 4 +- src/stores/api/profile.js | 45 ++++ src/views/Arcade/ClaimView.vue | 2 +- src/views/Auth/LoginView.vue | 12 +- src/views/Auth/RegisterView.vue | 2 +- src/views/Auth/ResetView.vue | 2 +- src/views/ErrorView.vue | 2 +- src/views/Game/NetworkRecords.vue | 2 +- src/views/Game/PersonalRecords.vue | 6 +- src/views/Game/PersonalScores.vue | 4 +- src/views/Game/PlayerView.vue | 4 +- src/views/Game/RivalsView.vue | 305 ++++++++++++++++++++++++--- src/views/Profile/ClaimView.vue | 2 +- src/views/Profile/CustomizeView.vue | 8 +- 21 files changed, 389 insertions(+), 82 deletions(-) create mode 100644 public/assets/games/ddr/card/20.webp diff --git a/.env.development b/.env.development index 10b1237..cd1c9c3 100644 --- a/.env.development +++ b/.env.development @@ -1,4 +1,4 @@ -VITE_APP_VERSION="3.0.27" +VITE_APP_VERSION="3.0.28" VITE_API_URL="http://10.5.7.5:8000/" VITE_API_KEY="your_api_key_should_be_here" VITE_ASSET_PATH="/assets" diff --git a/.env.production b/.env.production index 46c01ff..8682841 100644 --- a/.env.production +++ b/.env.production @@ -1,4 +1,4 @@ -VITE_APP_VERSION="3.0.27" +VITE_APP_VERSION="3.0.28" VITE_API_URL="https://restfulsleep.phaseii.network" VITE_API_KEY="your_api_key_should_be_here" VITE_ASSET_PATH="https://cdn.phaseii.network/file/PhaseII/web-assets" diff --git a/public/assets/games/ddr/card/20.webp b/public/assets/games/ddr/card/20.webp new file mode 100644 index 0000000000000000000000000000000000000000..de028f09c2529490a192b207f97a8f52cdb6ac51 GIT binary patch literal 34252 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 literal 0 HcmV?d00001 diff --git a/public/data-sources/changelog.json b/public/data-sources/changelog.json index 94b86b7..cc8849f 100644 --- a/public/data-sources/changelog.json +++ b/public/data-sources/changelog.json @@ -26,5 +26,6 @@ "3.0.24": ["- (Bugfix) Fix theme forcing for dark mode", "- (Bugfix) Fix animations across entire app", "- (Bugfix) Fix cursor on login screen easter egg", "- (Minor) Add new greeting"], "3.0.25-oMini": ["- (Major ++) Move from Material Design Icons to Phosphor Icons. Icons are currently set to their initial picks, but may change (suggest a change!)", "- (Major) Add initial icon animations, start work on icon color standards", "- (Optimization) Improve random greeting selection (SoftieTechCat) ", "- (Minor) Fix ESlint config"], "3.0.26": ["- (Minor) Game player table is more sortable", "- (Minor) Greetings now support custom styling", "- (Minor) Added the first styled greeting"], - "3.0.27": ["- (Major) Profile data exporting added.", "- (Minor) More work for rivals."] + "3.0.27": ["- (Major) Profile data exporting added.", "- (Minor) More work for rivals."], + "3.0.28": ["- (Major) Full support for rivals across applicable games", "- (Major) Move from Vue Hash routing to standard routing", "- (Bugfix) Fix issue when customizing on iOS"] } \ No newline at end of file diff --git a/src/components/ArcadeCard.vue b/src/components/ArcadeCard.vue index 7b02d76..809ef37 100644 --- a/src/components/ArcadeCard.vue +++ b/src/components/ArcadeCard.vue @@ -95,26 +95,26 @@ function getCardStyle(path) {
setTimeout(resolve, 200)); + } + const userId = mainStore.userId; + + try { + await mainStore.callApi(`/profile/${game}/link`, "PUT", { + version: version, + userId: userId, + otherUserId: otherUserId, + type: type, + }); + return true; + } catch (error) { + console.log("Error putting profile link:", error); + throw error; + } +} + +export async function APIDeleteLink(game, version, otherUserId, type) { + while (!mainStore.userId) { + await new Promise((resolve) => setTimeout(resolve, 200)); + } + const userId = mainStore.userId; + + const confirmed = window.confirm("Are you really?"); + if (confirmed) { + try { + await mainStore.callApi(`/profile/${game}/link`, "DELETE", { + version: version, + userId: userId, + otherUserId: otherUserId, + type: type, + }); + return true; + } catch (error) { + console.log("Error deleting profile link:", error); + throw error; + } + } else { + return false; + } +} diff --git a/src/views/Arcade/ClaimView.vue b/src/views/Arcade/ClaimView.vue index 67062a7..879d8c8 100644 --- a/src/views/Arcade/ClaimView.vue +++ b/src/views/Arcade/ClaimView.vue @@ -132,7 +132,7 @@ async function saveSettings() {
diff --git a/src/views/Auth/LoginView.vue b/src/views/Auth/LoginView.vue index 5d81ebc..5471a4f 100644 --- a/src/views/Auth/LoginView.vue +++ b/src/views/Auth/LoginView.vue @@ -100,18 +100,10 @@ const submit = async () => {

Not Registered?

- +

Forgot Password?

- +
diff --git a/src/views/Auth/RegisterView.vue b/src/views/Auth/RegisterView.vue index daa76fe..e9d5ed3 100644 --- a/src/views/Auth/RegisterView.vue +++ b/src/views/Auth/RegisterView.vue @@ -186,7 +186,7 @@ async function registerProfile() {

Have an Account?

- +
diff --git a/src/views/Auth/ResetView.vue b/src/views/Auth/ResetView.vue index 248791d..2647058 100644 --- a/src/views/Auth/ResetView.vue +++ b/src/views/Auth/ResetView.vue @@ -177,7 +177,7 @@ async function resetPassword() {

Remember it?

- +
diff --git a/src/views/ErrorView.vue b/src/views/ErrorView.vue index 298f2f1..85db1d8 100644 --- a/src/views/ErrorView.vue +++ b/src/views/ErrorView.vue @@ -26,7 +26,7 @@ import LayoutGuest from "@/layouts/LayoutGuest.vue";

The server was unable to locate the page you're trying to go to.

- + diff --git a/src/views/Game/NetworkRecords.vue b/src/views/Game/NetworkRecords.vue index 74e1a5e..edec9f2 100644 --- a/src/views/Game/NetworkRecords.vue +++ b/src/views/Game/NetworkRecords.vue @@ -87,7 +87,7 @@ const filteredSongs = computed(() => { diff --git a/src/views/Game/PersonalRecords.vue b/src/views/Game/PersonalRecords.vue index 5a1a7c3..d637039 100644 --- a/src/views/Game/PersonalRecords.vue +++ b/src/views/Game/PersonalRecords.vue @@ -92,14 +92,14 @@ const filteredSongs = computed(() => {
{
diff --git a/src/views/Game/PersonalScores.vue b/src/views/Game/PersonalScores.vue index 2023022..02b331e 100644 --- a/src/views/Game/PersonalScores.vue +++ b/src/views/Game/PersonalScores.vue @@ -185,14 +185,14 @@ const navigateToSong = (item) => {
versionForm.currentVersion, @@ -41,19 +48,25 @@ watch( loadProfile(); loadLinks(); loadAllProfiles(); + versionMaxRivals(); }, ); onMounted(async () => { - loadAllProfiles(); - await loadProfile(); - loadLinks(); + await loadAll(); }); if (!thisGame.versions) { versionForm.currentVersion = 1; } +async function loadAll() { + loadAllProfiles(); + await loadProfile(); + loadLinks(); + filterForm.filter = null; +} + async function loadProfile() { try { profile.value = null; @@ -63,6 +76,10 @@ async function loadProfile() { if (data && !versionForm.currentVersion) { versionForm.currentVersion = data.versions[data.versions.length - 1]; } + + if (thisGame.useActiveRival) { + getActiveRivals(); + } } catch (error) { console.error("Failed to fetch user profile data:", error); } @@ -71,7 +88,7 @@ async function loadProfile() { async function loadLinks() { try { links.value = null; - const linkData = await APIGetLinks(gameID, versionForm.currentVersion); + var linkData = await APIGetLinks(gameID, versionForm.currentVersion); links.value = linkData; } catch (error) { console.error("Failed to fetch user link data:", error); @@ -111,19 +128,196 @@ if (!thisGame) { } function filterProfiles() { - if (filterForm.filter) { + var inputForm = JSON.parse(JSON.stringify(filterForm.filter)); + if (inputForm) { + inputForm = inputForm.replace(/-/g, ""); return allProfiles.value.filter( (rival) => - rival.username - .toLowerCase() - .includes(filterForm.filter.toLowerCase()) || - rival.extid - .toString() - .toLowerCase() - .includes(filterForm.filter.toLowerCase()), + rival.username.toLowerCase().includes(inputForm.toLowerCase()) || + rival.extid.toString().toLowerCase().includes(inputForm.toLowerCase()), ); } } + +function checkDisabled(rivalId) { + if (rivalId == profile.value?.userId) { + return true; + } + + if (links.value == null) { + return false; + } + + if (links.value.length >= maxRivals.value) { + return true; + } + + return links.value.some((link) => link.otherUserId === rivalId); +} + +function versionMaxRivals() { + const versionInfo = thisGame.versions.find( + (version) => version.id == versionForm.currentVersion, + ); + + maxRivals.value = versionInfo?.maxRivals ?? 3; + maxActiveRivals.value = versionInfo?.maxActiveRivals ?? 3; +} + +function getActiveRivals() { + if (!profile.value?.last) { + activeRivals.value = []; + return; + } + + var rivalList = []; + const keys = ["fri", "rival1", "rival2", "rival3"]; + for (const key of keys) { + const rivalId = profile.value?.last[key]; + if (rivalId >= 1) { + rivalList.push(rivalId); + } + } + + activeRivals.value = rivalList; +} + +async function addRival(otherUserId) { + if (links.value && links.value.length >= maxRivals.value) { + return; + } + + var type = "rival"; + if (thisGame?.useActiveRival) { + const usedTypes = new Set( + (links.value ?? []) + .map((link) => { + if (link?.type?.startsWith("friend_")) { + return parseInt(link.type.replace("friend_", ""), 10); + } + return null; + }) + .filter((v) => v !== null && !isNaN(v)), + ); + + var availableId = null; + for (let i = 0; i <= 9; i++) { + if (!usedTypes.has(i)) { + availableId = i; + break; + } + } + type = `friend_${availableId}`; + } + + try { + await APIPutLink(gameID, versionForm.currentVersion, otherUserId, type); + await loadAll(); + } catch (error) { + console.error("Failed to add rival:", error); + } +} + +async function deleteRival(otherUserId, type) { + try { + const deleteState = await APIDeleteLink( + gameID, + versionForm.currentVersion, + otherUserId, + type, + ); + if (deleteState) { + if (thisGame.useActiveRival) { + await setInactive(type); + } + } + + await loadAll(); + } catch (error) { + console.error("Failed to delete rival:", error); + } +} + +async function setActive(type) { + var lastObject = profile.value?.last ?? {}; + var rivalPosition = null; + if (type.startsWith("friend_")) { + rivalPosition = parseInt(type.replace("friend_", ""), 10); + } else { + return; + } + + if ([GameConstants.DDR, GameConstants.DDROMNI].includes(gameID)) { + if ( + [VersionConstants.DDR_X, VersionConstants.DDR_X2].includes( + versionForm.currentVersion, + ) + ) { + lastObject.fri = rivalPosition + 1; + } else { + if (!lastObject.rival1 || lastObject.rival1 < 1) { + lastObject.rival1 = rivalPosition + 1; + } else if (!lastObject.rival2 || lastObject.rival2 < 1) { + lastObject.rival2 = rivalPosition + 1; + } else if (!lastObject.rival3 || lastObject.rival3 < 1) { + lastObject.rival3 = rivalPosition + 1; + } + } + } + + await APIUpdateProfile(gameID, versionForm.currentVersion, { + last: lastObject, + }); + await loadAll(); +} + +async function setInactive(type) { + var lastObject = profile.value?.last ?? {}; + var rivalPosition = null; + + if (type.startsWith("friend_")) { + rivalPosition = parseInt(type.replace("friend_", ""), 10); + } else { + return; + } + + if ([GameConstants.DDR, GameConstants.DDROMNI].includes(gameID)) { + if ( + [VersionConstants.DDR_X, VersionConstants.DDR_X2].includes( + versionForm.currentVersion, + ) + ) { + if (lastObject.fri === rivalPosition + 1) { + lastObject.fri = 0; + } + } else { + if (lastObject.rival1 === rivalPosition + 1) { + lastObject.rival1 = 0; + } else if (lastObject.rival2 === rivalPosition + 1) { + lastObject.rival2 = 0; + } else if (lastObject.rival3 === rivalPosition + 1) { + lastObject.rival3 = 0; + } + } + } + + await APIUpdateProfile(gameID, versionForm.currentVersion, { + last: lastObject, + }); + await loadAll(); +} + +const getLinkNum = (type) => { + if (type.startsWith("friend_")) { + return parseInt(type.replace("friend_", ""), 10) + 1; + } else { + return; + } +}; + +const navigateToProfile = (userID) => { + $router.push(`/games/${gameID}/profiles/${userID}`); +};