mirror of
https://github.com/PhaseII-eAmusement-Network/PhaseWeb3-Vue.git
synced 2026-09-11 02:35:15 -05:00
Add play video page
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
VITE_API_URL="http://10.5.7.5:8000/"
|
||||
VITE_API_KEY="your_api_key_should_be_here"
|
||||
VITE_ASSET_PATH="/assets"
|
||||
VITE_ASSET_PATH="/assets"
|
||||
VITE_DISCORD_OAUTH_URL="https://discord.com/api/oauth2/authorize?client_id=947985989421395988&redirect_uri=https%3A%2F%2Fphaseii.network%2Faccount%2Fdiscord_callback&response_type=code&scope=identify"
|
||||
VITE_TACHI_OAUTH_URL="https://kamai.tachi.ac/oauth/request-auth?clientID=CI820ca69046783e9fb4cc7d616f985ea2cab00f5f"
|
||||
@@ -1,3 +1,5 @@
|
||||
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"
|
||||
VITE_ASSET_PATH="https://cdn.phaseii.network/file/PhaseII/web-assets"
|
||||
VITE_DISCORD_OAUTH_URL=""
|
||||
VITE_TACHI_OAUTH_URL=""
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
mdiStoreCog,
|
||||
mdiGamepad,
|
||||
mdiSecurity,
|
||||
mdiMultimedia,
|
||||
} from "@mdi/js";
|
||||
import { ref, watch, onMounted, computed } from "vue";
|
||||
import { useRouter, useRoute } from "vue-router";
|
||||
@@ -128,12 +129,6 @@ const menuAside = computed(() => {
|
||||
const sortedArcades = mainStore.userArcades.map((arcade) => ({
|
||||
label: arcade.name,
|
||||
to: `/arcade/${arcade.id}`,
|
||||
// menu: [
|
||||
// { label: "Overview", to: `/arcade/${arcade.id}` },
|
||||
// { label: "Event Settings", to: `/arcade/${arcade.id}/events` },
|
||||
// { label: "Machine List", to: `/arcade/${arcade.id}/machines` },
|
||||
// { label: "PASELI", to: `/arcade/${arcade.id}/paseli` },
|
||||
// ],
|
||||
}));
|
||||
|
||||
const adminMenu = [
|
||||
@@ -205,6 +200,17 @@ const menuAside = computed(() => {
|
||||
});
|
||||
}
|
||||
|
||||
sideMenu.push({
|
||||
label: "My Content",
|
||||
icon: mdiMultimedia,
|
||||
menu: [
|
||||
{
|
||||
label: "Play Videos",
|
||||
to: `/profile/videos`,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
return sideMenu;
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -82,6 +82,14 @@ const routes = [
|
||||
// name: "profile_goals",
|
||||
// component: () => import("@/views/Profile/GoalsView.vue"),
|
||||
// },
|
||||
{
|
||||
meta: {
|
||||
title: "Play Videos",
|
||||
},
|
||||
path: "/profile/videos",
|
||||
name: "profile_videos",
|
||||
component: () => import("@/views/Profile/VideoView.vue"),
|
||||
},
|
||||
{
|
||||
meta: {
|
||||
title: "View Profile",
|
||||
|
||||
@@ -103,3 +103,13 @@ export async function APIDeleteCard(cardId) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export async function APIGetPlayVideos() {
|
||||
try {
|
||||
const data = await mainStore.callApi(`/user/playVideos`);
|
||||
return data.data;
|
||||
} catch (error) {
|
||||
console.log("Error fetching videos:", error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
37
src/stores/api/music.js
Normal file
37
src/stores/api/music.js
Normal file
@@ -0,0 +1,37 @@
|
||||
import { useMainStore } from "@/stores/main";
|
||||
const mainStore = useMainStore();
|
||||
|
||||
export async function APIGetMusicData(
|
||||
game,
|
||||
version,
|
||||
songIds = null,
|
||||
oneChart = false
|
||||
) {
|
||||
try {
|
||||
const data = await mainStore.callApi(
|
||||
`/music?game=${game}&version=${version}` +
|
||||
(oneChart ? "&oneChart=true" : ""),
|
||||
"GET",
|
||||
null,
|
||||
{ songIds: songIds.toString() }
|
||||
);
|
||||
return data.data;
|
||||
} catch (error) {
|
||||
console.log("Error fetching music data:", error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export async function getAttemptData(game, userId = null) {
|
||||
try {
|
||||
const data = await mainStore.callApi(
|
||||
`/attempts/${game}` + (userId ? `?userId=${userId}` : ""),
|
||||
"GET",
|
||||
null
|
||||
);
|
||||
return data.data;
|
||||
} catch (error) {
|
||||
console.log("Error fetching attempt data:", error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
175
src/views/Profile/VideoView.vue
Normal file
175
src/views/Profile/VideoView.vue
Normal file
@@ -0,0 +1,175 @@
|
||||
<script setup>
|
||||
import { ref, onMounted } from "vue";
|
||||
import { mdiVideoOutline, mdiVideoWirelessOutline } from "@mdi/js";
|
||||
import SectionMain from "@/components/SectionMain.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import UserCard from "@/components/UserCard.vue";
|
||||
import LayoutAuthenticated from "@/layouts/LayoutAuthenticated.vue";
|
||||
import SectionTitleLine from "@/components/SectionTitleLine.vue";
|
||||
import GeneralTable from "@/components/GeneralTable.vue";
|
||||
import { getGameInfo } from "@/constants";
|
||||
|
||||
import { APIGetPlayVideos } from "@/stores/api/account";
|
||||
|
||||
var videoData = ref([]);
|
||||
const loading = ref(false);
|
||||
|
||||
const headers = [
|
||||
{
|
||||
text: "Timestamp",
|
||||
value: "timestamp",
|
||||
sortable: true,
|
||||
width: 120,
|
||||
},
|
||||
{
|
||||
text: "Game",
|
||||
value: "game",
|
||||
sortable: true,
|
||||
width: 120,
|
||||
},
|
||||
{
|
||||
text: "Version",
|
||||
value: "version",
|
||||
sortable: true,
|
||||
width: 120,
|
||||
},
|
||||
{
|
||||
text: "Status",
|
||||
value: "data.status",
|
||||
sortable: true,
|
||||
width: 120,
|
||||
},
|
||||
];
|
||||
|
||||
async function loadVideos() {
|
||||
videoData.value = null;
|
||||
try {
|
||||
const data = await APIGetPlayVideos();
|
||||
videoData.value = filterVideos(data);
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch video data:", error);
|
||||
}
|
||||
|
||||
loading.value = false;
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await loadVideos();
|
||||
});
|
||||
|
||||
function filterVideos(playVideos) {
|
||||
playVideos.sort(function (x, y) {
|
||||
return y.timestamp - x.timestamp;
|
||||
});
|
||||
|
||||
for (const video of playVideos) {
|
||||
const game = getGameInfo(video.game);
|
||||
video.game = game.name;
|
||||
video.version = game.versions.find((x) => x.id == video.version).label ?? 0;
|
||||
|
||||
if (video.timestamp) {
|
||||
const date = new Date(video.timestamp * 1000);
|
||||
video.timestamp = date.toLocaleString();
|
||||
}
|
||||
}
|
||||
|
||||
return playVideos;
|
||||
}
|
||||
|
||||
const copyToClipboard = (text) => {
|
||||
if (text.data?.url) {
|
||||
text = text.data?.url;
|
||||
}
|
||||
|
||||
navigator.clipboard
|
||||
.writeText(text)
|
||||
.then(() => {
|
||||
alert("Copied URL to clipboard!");
|
||||
})
|
||||
.catch(() => {
|
||||
alert("Failed to copy to clipboard!");
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<LayoutAuthenticated>
|
||||
<SectionMain>
|
||||
<UserCard class="mb-6" use-small even-smaller />
|
||||
|
||||
<template v-if="videoData[0]">
|
||||
<SectionTitleLine
|
||||
:icon="mdiVideoWirelessOutline"
|
||||
title="Your Latest Upload"
|
||||
main
|
||||
/>
|
||||
<CardBox class="mb-6">
|
||||
<div
|
||||
v-if="videoData[0]?.data?.status == 'uploaded'"
|
||||
class="grid grid-cols-1 md:grid-cols-2 gap-4"
|
||||
>
|
||||
<video controls class="mt-3 rounded-xl w-[640px] xl:w-[1280px]">
|
||||
<source :src="videoData[0]?.data?.url" type="video/mp4" />
|
||||
Your browser does not support the video tag.
|
||||
</video>
|
||||
|
||||
<div
|
||||
class="text-center md:text-left grid grid-cols-1 place-content-start gap-6"
|
||||
>
|
||||
<div class="space-y-1">
|
||||
<!-- <h1 class="text-2xl xl:text-4xl font-bold">
|
||||
{{ videoData[0]?.musicid }}
|
||||
</h1> -->
|
||||
<h2 class="text-xl xl:text-2xl font-light">
|
||||
{{ videoData[0]?.game }} {{ videoData[0]?.version }}
|
||||
</h2>
|
||||
<!-- <h2 class="text-xl xl:text-xl">SP HYPER LV. 7</h2> -->
|
||||
</div>
|
||||
<div>
|
||||
<p>{{ videoData[0]?.timestamp }}</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<BaseButton
|
||||
color="info"
|
||||
label="Share"
|
||||
@click="copyToClipboard(videoData[0]?.data?.url)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div class="space-y-1 text-center">
|
||||
<h1 class="text-2xl xl:text-4xl font-bold">
|
||||
Your video is still uploading!
|
||||
</h1>
|
||||
<h2 class="text-xl xl:text-2xl font-light">
|
||||
Please wait for the upload to complete.
|
||||
</h2>
|
||||
<h2 class="text-xl xl:text-xl">
|
||||
Upload started at {{ videoData[0].timestamp }}
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
</CardBox>
|
||||
</template>
|
||||
|
||||
<SectionTitleLine :icon="mdiVideoOutline" title="All Play Videos" main />
|
||||
|
||||
<CardBox has-table>
|
||||
<div
|
||||
class="bg-white dark:bg-slate-900/95 rounded-2xl lg:flex lg:justify-between"
|
||||
>
|
||||
<div class="w-full">
|
||||
<GeneralTable
|
||||
:headers="headers"
|
||||
:items="videoData"
|
||||
@row-clicked="copyToClipboard"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</CardBox>
|
||||
</SectionMain>
|
||||
</LayoutAuthenticated>
|
||||
</template>
|
||||
Reference in New Issue
Block a user