mirror of
https://github.com/PhaseII-eAmusement-Network/PhaseWeb3-Vue.git
synced 2026-08-23 09:34:33 -05:00
finish rival support. move to new vue router, fix buttons and a web crash bug
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
BIN
public/assets/games/ddr/card/20.webp
Normal file
BIN
public/assets/games/ddr/card/20.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 33 KiB |
@@ -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"]
|
||||
}
|
||||
@@ -95,26 +95,26 @@ function getCardStyle(path) {
|
||||
|
||||
<div class="md:w-full grid grid-cols-1 md:grid-cols-4 gap-3">
|
||||
<BaseButton
|
||||
:href="`/#/arcade/${arcade.id}`"
|
||||
:to="`/arcade/${arcade.id}`"
|
||||
:icon="PhHouse"
|
||||
color="info"
|
||||
label="Arcade Home"
|
||||
class="w-full md:w-[150px]"
|
||||
/>
|
||||
<BaseButton
|
||||
:href="`/#/arcade/${arcade.id}/events`"
|
||||
:to="`/arcade/${arcade.id}/events`"
|
||||
:icon="PhNewspaper"
|
||||
color="info"
|
||||
label="Event Settings"
|
||||
/>
|
||||
<BaseButton
|
||||
:href="`/#/arcade/${arcade.id}/machines`"
|
||||
:to="`/arcade/${arcade.id}/machines`"
|
||||
:icon="PhJoystick"
|
||||
color="info"
|
||||
label="Machine List"
|
||||
/>
|
||||
<BaseButton
|
||||
:href="`/#/arcade/${arcade.id}/paseli`"
|
||||
:to="`/arcade/${arcade.id}/paseli`"
|
||||
:icon="PhCashRegister"
|
||||
color="info"
|
||||
label="PASELI"
|
||||
|
||||
@@ -42,7 +42,7 @@ function loadRoutes() {
|
||||
props.game.shortName ? props.game.shortName : props.game.name
|
||||
} Home`,
|
||||
icon: PhHouse,
|
||||
path: `/#/games/${props.game.id}/`,
|
||||
path: `/games/${props.game.id}/`,
|
||||
route: "game_page",
|
||||
color: "success",
|
||||
},
|
||||
@@ -52,7 +52,7 @@ function loadRoutes() {
|
||||
navigationData.push({
|
||||
label: "My Profile",
|
||||
icon: PhUserList,
|
||||
path: `/#/games/${props.game.id}/profiles/${mainStore.userId}`,
|
||||
path: `/games/${props.game.id}/profiles/${mainStore.userId}`,
|
||||
route: "game_profile",
|
||||
color: "info",
|
||||
});
|
||||
@@ -60,7 +60,7 @@ function loadRoutes() {
|
||||
navigationData.push({
|
||||
label: "Edit Profile",
|
||||
icon: PhGear,
|
||||
path: `/#/games/${props.game.id}/edit`,
|
||||
path: `/games/${props.game.id}/edit`,
|
||||
route: "edit_profile",
|
||||
color: "warning",
|
||||
});
|
||||
@@ -69,7 +69,7 @@ function loadRoutes() {
|
||||
navigationData.push({
|
||||
label: "Rivals",
|
||||
icon: PhSword,
|
||||
path: `/#/games/${props.game.id}/rivals`,
|
||||
path: `/games/${props.game.id}/rivals`,
|
||||
route: "game_rivals",
|
||||
color: "danger",
|
||||
});
|
||||
@@ -79,7 +79,7 @@ function loadRoutes() {
|
||||
navigationData.push({
|
||||
label: "My Scores",
|
||||
icon: PhPlaylist,
|
||||
path: `/#/games/${props.game.id}/scores/${mainStore.userId}`,
|
||||
path: `/games/${props.game.id}/scores/${mainStore.userId}`,
|
||||
color: "info",
|
||||
});
|
||||
}
|
||||
@@ -87,7 +87,7 @@ function loadRoutes() {
|
||||
navigationData.push({
|
||||
label: "My Records",
|
||||
icon: PhListStar,
|
||||
path: `/#/games/${props.game.id}/records/${mainStore.userId}`,
|
||||
path: `/games/${props.game.id}/records/${mainStore.userId}`,
|
||||
route: "personal_records",
|
||||
color: "success",
|
||||
});
|
||||
@@ -98,14 +98,14 @@ function loadRoutes() {
|
||||
{
|
||||
label: "Network Scores",
|
||||
icon: PhPlaylist,
|
||||
path: `/#/games/${props.game.id}/scores`,
|
||||
path: `/games/${props.game.id}/scores`,
|
||||
route: "all_scores",
|
||||
color: "info",
|
||||
},
|
||||
{
|
||||
label: "Network Records",
|
||||
icon: PhListStar,
|
||||
path: `/#/games/${props.game.id}/records`,
|
||||
path: `/games/${props.game.id}/records`,
|
||||
route: "all_records",
|
||||
color: "success",
|
||||
},
|
||||
@@ -142,7 +142,7 @@ function loadRoutes() {
|
||||
<template v-for="item of loadRoutes()" :key="item.path">
|
||||
<BaseButton
|
||||
v-if="item.route != $route.name"
|
||||
:href="item.path"
|
||||
:to="item.path"
|
||||
:icon="item.icon"
|
||||
:label="item.label"
|
||||
:color="item.color"
|
||||
|
||||
@@ -84,6 +84,7 @@ export class VersionConstants {
|
||||
static DDR_A20 = 17;
|
||||
static DDR_A20_PLUS = 18;
|
||||
static DDR_A3 = 19;
|
||||
static DDR_WORLD = 20;
|
||||
|
||||
static DRUMMANIA_1ST = 1;
|
||||
static DRUMMANIA_2ND = 2;
|
||||
@@ -476,6 +477,7 @@ export const gameData = [
|
||||
icon: null,
|
||||
cardBG: null,
|
||||
gameOptions: DDROptions,
|
||||
useActiveRival: true,
|
||||
videoTable: [
|
||||
VersionConstants.DDR_ACE,
|
||||
VersionConstants.DDR_A20,
|
||||
@@ -571,46 +573,62 @@ export const gameData = [
|
||||
{
|
||||
id: VersionConstants.DDR_X,
|
||||
label: "X",
|
||||
maxRivals: 10,
|
||||
maxActiveRivals: 1,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.DDR_X2,
|
||||
label: "X2",
|
||||
maxRivals: 1,
|
||||
maxRivals: 10,
|
||||
maxActiveRivals: 1,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.DDR_X3_VS_2ND_MIX,
|
||||
label: "X3 vs. 2ND MIX",
|
||||
maxRivals: 3,
|
||||
maxRivals: 10,
|
||||
maxActiveRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.DDR_2013,
|
||||
label: "(2013)",
|
||||
maxRivals: 3,
|
||||
maxRivals: 10,
|
||||
maxActiveRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.DDR_2014,
|
||||
label: "(2014)",
|
||||
maxRivals: 3,
|
||||
maxRivals: 10,
|
||||
maxActiveRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.DDR_ACE,
|
||||
label: "Ace",
|
||||
maxRivals: 3,
|
||||
maxRivals: 10,
|
||||
maxActiveRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.DDR_A20,
|
||||
label: "A20",
|
||||
maxRivals: 3,
|
||||
maxRivals: 10,
|
||||
maxActiveRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.DDR_A20_PLUS,
|
||||
label: "A20 PLUS",
|
||||
maxRivals: 3,
|
||||
maxRivals: 10,
|
||||
maxActiveRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.DDR_A3,
|
||||
label: "A3",
|
||||
maxRivals: 3,
|
||||
maxRivals: 10,
|
||||
maxActiveRivals: 3,
|
||||
},
|
||||
{
|
||||
id: VersionConstants.DDR_WORLD,
|
||||
label: "WORLD",
|
||||
maxRivals: 10,
|
||||
maxActiveRivals: 3,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -674,6 +692,7 @@ export const gameData = [
|
||||
cardBG: `${ASSET_PATH}/card/ddr.webp`,
|
||||
assetId: "ddr",
|
||||
gameOptions: DDROptions,
|
||||
useActiveRival: true,
|
||||
videoTable: [VersionConstants.DDR_A20_PLUS],
|
||||
scoreHeaders: [
|
||||
{ text: "Combos", value: "data.combo", width: 80 },
|
||||
@@ -792,7 +811,8 @@ export const gameData = [
|
||||
{
|
||||
id: VersionConstants.DDR_A20_PLUS,
|
||||
label: "OmniMIX (A20 PLUS)",
|
||||
maxRivals: 3,
|
||||
maxRivals: 10,
|
||||
maxActiveRivals: 3,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { createRouter, createWebHashHistory } from "vue-router";
|
||||
import { createRouter, createWebHistory } from "vue-router";
|
||||
import Home from "@/views/HomeView.vue";
|
||||
|
||||
const routes = [
|
||||
@@ -388,7 +388,7 @@ const routes = [
|
||||
];
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHashHistory(),
|
||||
history: createWebHistory(),
|
||||
routes,
|
||||
scrollBehavior(to, from, savedPosition) {
|
||||
return savedPosition || { top: 0 };
|
||||
|
||||
@@ -106,3 +106,48 @@ export async function APIGetLinks(game, version) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export async function APIPutLink(game, version, otherUserId, type) {
|
||||
while (!mainStore.userId) {
|
||||
await new Promise((resolve) => 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ async function saveSettings() {
|
||||
<BaseButton
|
||||
color="success"
|
||||
label="Go to Arcade"
|
||||
:href="`#/arcade/${takeoverData?.arcade?.id}`"
|
||||
:to="`/arcade/${takeoverData?.arcade?.id}`"
|
||||
/>
|
||||
</div>
|
||||
</CardBox>
|
||||
|
||||
@@ -100,18 +100,10 @@ const submit = async () => {
|
||||
|
||||
<div class="flex flex-col gap-2 my-4">
|
||||
<h2>Not Registered?</h2>
|
||||
<BaseButton
|
||||
label="Register"
|
||||
color="info"
|
||||
href="/#/auth/register"
|
||||
/>
|
||||
<BaseButton label="Register" color="info" to="/auth/register" />
|
||||
|
||||
<h2>Forgot Password?</h2>
|
||||
<BaseButton
|
||||
label="i forgor"
|
||||
color="warning"
|
||||
href="/#/auth/reset"
|
||||
/>
|
||||
<BaseButton label="i forgor" color="warning" to="/auth/reset" />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -186,7 +186,7 @@ async function registerProfile() {
|
||||
|
||||
<div class="flex flex-col gap-2 my-4">
|
||||
<h2>Have an Account?</h2>
|
||||
<BaseButton label="Log In" color="info" href="/#/auth/login" />
|
||||
<BaseButton label="Log In" color="info" to="/auth/login" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -177,7 +177,7 @@ async function resetPassword() {
|
||||
<hr v-if="!form.authValid" class="border-t border mt-3 w-full" />
|
||||
<div v-if="!form.authValid" class="flex flex-col gap-2 my-1">
|
||||
<h2>Remember it?</h2>
|
||||
<BaseButton label="Log In" color="success" href="/#/auth/login" />
|
||||
<BaseButton label="Log In" color="success" to="/auth/login" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -26,7 +26,7 @@ import LayoutGuest from "@/layouts/LayoutGuest.vue";
|
||||
<h2 class="mb-2">
|
||||
The server was unable to locate the page you're trying to go to.
|
||||
</h2>
|
||||
<BaseButton label="Home" color="info" href="/" />
|
||||
<BaseButton label="Home" color="info" to="/" />
|
||||
</div>
|
||||
</div>
|
||||
</CardBox>
|
||||
|
||||
@@ -87,7 +87,7 @@ const filteredSongs = computed(() => {
|
||||
<BaseButton
|
||||
label="View Song"
|
||||
color="info"
|
||||
:href="`/#/games/${gameId}/song/${song.id}`"
|
||||
:to="`/games/${gameId}/song/${song.id}`"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -92,14 +92,14 @@ const filteredSongs = computed(() => {
|
||||
<div class="flex gap-2 mb-6 md:mb-0">
|
||||
<BaseButton
|
||||
:icon="PhUser"
|
||||
:href="`/#/games/${thisGame.id}/profiles/${myProfile.userId}`"
|
||||
:to="`/games/${thisGame.id}/profiles/${myProfile.userId}`"
|
||||
:outline="false"
|
||||
color="info"
|
||||
:label="`${myProfile.username}'s Profile`"
|
||||
/>
|
||||
<BaseButton
|
||||
:icon="PhMedal"
|
||||
:href="`/#/games/${thisGame.id}/scores/${myProfile.userId}`"
|
||||
:to="`/games/${thisGame.id}/scores/${myProfile.userId}`"
|
||||
:outline="false"
|
||||
color="info"
|
||||
:label="`${myProfile.username}'s Scores`"
|
||||
@@ -134,7 +134,7 @@ const filteredSongs = computed(() => {
|
||||
<BaseButton
|
||||
label="View Song"
|
||||
color="info"
|
||||
:href="`/#/games/${gameId}/song/${song.id}`"
|
||||
:to="`/games/${gameId}/song/${song.id}`"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -185,14 +185,14 @@ const navigateToSong = (item) => {
|
||||
<div class="flex gap-2 mb-6">
|
||||
<BaseButton
|
||||
:icon="PhUser"
|
||||
:href="`/#/games/${thisGame.id}/profiles/${myProfile.userId}`"
|
||||
:to="`/games/${thisGame.id}/profiles/${myProfile.userId}`"
|
||||
:outline="false"
|
||||
color="info"
|
||||
:label="`${myProfile.username}'s Profile`"
|
||||
/>
|
||||
<BaseButton
|
||||
:icon="PhRanking"
|
||||
:href="`/#/games/${thisGame.id}/records/${myProfile.userId}`"
|
||||
:to="`/games/${thisGame.id}/records/${myProfile.userId}`"
|
||||
:outline="false"
|
||||
color="info"
|
||||
:label="`${myProfile.username}'s Records`"
|
||||
|
||||
@@ -400,7 +400,7 @@ async function generateTimeline(myProfile) {
|
||||
class="md:w-1/3 grid grid-cols-1 md:grid-cols-2 gap-3 mt-4"
|
||||
>
|
||||
<BaseButton
|
||||
:href="`/#/games/${gameID}/scores/${myProfile.userId}`"
|
||||
:to="`/games/${gameID}/scores/${myProfile.userId}`"
|
||||
:icon="PhMedal"
|
||||
class="w-full md:w-auto"
|
||||
color="info"
|
||||
@@ -408,7 +408,7 @@ async function generateTimeline(myProfile) {
|
||||
/>
|
||||
|
||||
<BaseButton
|
||||
:href="`/#/games/${gameID}/records/${myProfile.userId}`"
|
||||
:to="`/games/${gameID}/records/${myProfile.userId}`"
|
||||
:icon="PhRanking"
|
||||
class="w-full md:w-auto"
|
||||
color="info"
|
||||
|
||||
@@ -5,6 +5,7 @@ import { PhSword, PhPlusCircle } from "@phosphor-icons/vue";
|
||||
import SectionMain from "@/components/SectionMain.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import BaseButtons from "@/components/BaseButtons.vue";
|
||||
import GameHeader from "@/components/Cards/GameHeader.vue";
|
||||
import ProfileCard from "@/components/Cards/ProfileCard.vue";
|
||||
import LayoutAuthenticated from "@/layouts/LayoutAuthenticated.vue";
|
||||
@@ -16,8 +17,11 @@ import {
|
||||
APIGetProfile,
|
||||
APIGetAllProfiles,
|
||||
APIGetLinks,
|
||||
APIUpdateProfile,
|
||||
APIPutLink,
|
||||
APIDeleteLink,
|
||||
} from "@/stores/api/profile";
|
||||
import { getGameInfo } from "@/constants";
|
||||
import { getGameInfo, GameConstants, VersionConstants } from "@/constants";
|
||||
import { dashCode } from "@/constants/userData";
|
||||
|
||||
const $route = useRoute();
|
||||
@@ -34,6 +38,9 @@ const allProfiles = ref([]);
|
||||
const versionForm = reactive({
|
||||
currentVersion: null,
|
||||
});
|
||||
const maxRivals = ref(null);
|
||||
const maxActiveRivals = ref(null);
|
||||
const activeRivals = ref(null);
|
||||
|
||||
watch(
|
||||
() => 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}`);
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -175,7 +369,7 @@ function filterProfiles() {
|
||||
:key="player.id"
|
||||
class="bg-slate-800 p-4 rounded-xl"
|
||||
>
|
||||
<div class="flex w-full place-content-between">
|
||||
<div class="grid md:flex gap-2 w-full place-content-between">
|
||||
<div>
|
||||
<h1 class="text-lg md:text-xl">{{ player.username }}</h1>
|
||||
<h2 class="text-md md:text-lg font-mono">
|
||||
@@ -183,36 +377,91 @@ function filterProfiles() {
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div class="flex align-middle">
|
||||
<BaseButtons>
|
||||
<BaseButton
|
||||
label="Open Profile"
|
||||
color="info"
|
||||
@click="navigateToProfile(player.userId)"
|
||||
/>
|
||||
<BaseButton
|
||||
label="Add Rival"
|
||||
color="success"
|
||||
:disabled="player.userId == profile?.userId"
|
||||
tooltip="penis"
|
||||
:disabled="checkDisabled(player.userId)"
|
||||
@click="addRival(player.userId)"
|
||||
/>
|
||||
</div>
|
||||
</BaseButtons>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardBox>
|
||||
|
||||
<SectionTitleLine :icon="PhSword" title="Rivals" main />
|
||||
<h2 class="text-xl rounded-2xl p-4 my-2 bg-slate-900">
|
||||
{{ links?.length ?? 0 }} / {{ maxRivals }} added
|
||||
<template v-if="thisGame?.useActiveRival">
|
||||
-
|
||||
<span
|
||||
>{{ activeRivals?.length ?? 0 }} /
|
||||
{{ maxActiveRivals }} active</span
|
||||
>
|
||||
</template>
|
||||
</h2>
|
||||
<CardBox v-if="versionForm.currentVersion" class="mb-6">
|
||||
<div class="grid gap-3">
|
||||
<CardBox v-for="rival of profile?.rivals" :key="rival.id">
|
||||
<div class="flex justify-between items-center">
|
||||
<CardBox
|
||||
v-for="link of links"
|
||||
:key="getLinkNum(link?.type)"
|
||||
color-prop="bg-slate-800 dark:bg-slate-800"
|
||||
>
|
||||
<div class="grid gap-2 md:flex justify-between items-center">
|
||||
<div class="flex">
|
||||
<div class="grid">
|
||||
<h1 class="text-lg">{{ rival.name }}</h1>
|
||||
<h2 class="text-md font-mono">{{ rival.rivalID }}</h2>
|
||||
</div>
|
||||
<h1 class="text-lg">
|
||||
{{ link?.otherProfileData?.username }}
|
||||
<template v-if="thisGame?.useActiveRival">
|
||||
-
|
||||
<span
|
||||
v-if="activeRivals.includes(getLinkNum(link?.type))"
|
||||
class="text-emerald-500"
|
||||
>Active</span
|
||||
>
|
||||
<span v-else class="text-red-500">Inactive</span>
|
||||
</template>
|
||||
</h1>
|
||||
</div>
|
||||
<BaseButton label="Remove Rival" color="danger" />
|
||||
|
||||
<BaseButtons>
|
||||
<BaseButton
|
||||
label="Open Profile"
|
||||
color="info"
|
||||
@click="navigateToProfile(link?.otherUserId)"
|
||||
/>
|
||||
<template v-if="thisGame?.useActiveRival">
|
||||
<BaseButton
|
||||
v-if="activeRivals.includes(getLinkNum(link?.type))"
|
||||
label="Set Inactive"
|
||||
color="warning"
|
||||
@click="setInactive(link?.type)"
|
||||
/>
|
||||
<BaseButton
|
||||
v-else
|
||||
label="Set Active"
|
||||
color="success"
|
||||
:disabled="activeRivals.length >= maxActiveRivals"
|
||||
@click="setActive(link?.type)"
|
||||
/>
|
||||
</template>
|
||||
<BaseButton
|
||||
label="Remove Rival"
|
||||
color="danger"
|
||||
@click="deleteRival(link?.otherUserId, link?.type)"
|
||||
/>
|
||||
</BaseButtons>
|
||||
</div>
|
||||
</CardBox>
|
||||
<CardBox v-if="!profile?.rivals">
|
||||
<h1 class="text-2xl">{{ links }}</h1>
|
||||
</CardBox>
|
||||
|
||||
<template v-if="!links || !links.length">
|
||||
<span class="text-xl">No rivals!</span>
|
||||
</template>
|
||||
</div>
|
||||
</CardBox>
|
||||
</SectionMain>
|
||||
|
||||
@@ -248,7 +248,7 @@ async function saveSettings() {
|
||||
</h2>
|
||||
|
||||
<div class="mt-4">
|
||||
<BaseButton color="success" label="Return to Dashboard" href="#/" />
|
||||
<BaseButton color="success" label="Return to Dashboard" to="/" />
|
||||
</div>
|
||||
</CardBox>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<script setup>
|
||||
import { useMainStore } from "@/stores/main";
|
||||
import { useRouter } from "vue-router";
|
||||
import { ref, watch } from "vue";
|
||||
import { PhPaintBrushBroad } from "@phosphor-icons/vue";
|
||||
|
||||
@@ -16,7 +15,6 @@ import FormCheckRadio from "@/components/FormCheckRadio.vue";
|
||||
import { ProfileCustomizations } from "@/constants/customizations";
|
||||
import { APIUserCustomize } from "@/stores/api/account";
|
||||
|
||||
const $router = useRouter();
|
||||
const mainStore = useMainStore();
|
||||
const userCustomize = ref(mainStore.userCustomize);
|
||||
var originalData = JSON.parse(JSON.stringify(mainStore.userCustomize));
|
||||
@@ -40,7 +38,8 @@ async function updateCustomize() {
|
||||
|
||||
if (data?.status === "success") {
|
||||
mainStore.userLoaded = false;
|
||||
$router.go();
|
||||
await mainStore.loadUser();
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +53,8 @@ function userChanged() {
|
||||
|
||||
async function revert() {
|
||||
mainStore.userLoaded = false;
|
||||
$router.go();
|
||||
await mainStore.loadUser();
|
||||
location.reload();
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user