implement embed mode; add MePage
This commit is contained in:
parent
cf96264024
commit
27ab4c870d
19
src/Api.ts
19
src/Api.ts
@ -21,7 +21,11 @@ export class Api {
|
||||
this.baseURL = baseURL;
|
||||
this.authBaseURL = authBaseURL;
|
||||
this.publicBaseURL = publicBaseURL;
|
||||
this.accessToken = accessToken ?? localStorage.getItem("access-token");
|
||||
try{
|
||||
this.accessToken = accessToken ?? localStorage?.getItem("access-token");
|
||||
} catch (e) {
|
||||
this.accessToken = null;
|
||||
}
|
||||
this.axios = axios.create({ baseURL });
|
||||
this.axios.interceptors.request.use(({ headers = {}, ...config }) => ({
|
||||
...config,
|
||||
@ -63,11 +67,20 @@ export class Api {
|
||||
return (await this.axiosPublic.get(`/users/${userId}/info`))?.data;
|
||||
}
|
||||
|
||||
async getSession() {
|
||||
return (await this.axios.get(`/session`))?.data;
|
||||
}
|
||||
async createSession() {
|
||||
return (await this.axios.post(`/session`))?.data;
|
||||
}
|
||||
async deleteSession() {
|
||||
return (await this.axios.delete(`/session`))?.data;
|
||||
}
|
||||
async joinSession(hostId: string) {
|
||||
return (await this.axios.post(`/session/join`, { hostId }))?.data;
|
||||
}
|
||||
async leaveSession(hostId: string) {
|
||||
return (await this.axios.post(`/session/session`, { hostId }))?.data;
|
||||
async leaveSession() {
|
||||
return (await this.axios.post(`/session/leave`))?.data;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
<template>
|
||||
<div>
|
||||
<div v-if="$route.meta.allowEmbed && $route.query.embed === 'true'" class="p-2">
|
||||
<router-view />
|
||||
</div>
|
||||
<div v-else>
|
||||
<div class="bg-secondary shadow">
|
||||
<nav class="navbar px-2 container">
|
||||
<router-link class="d-flex btn" to="/">
|
||||
|
25
src/components/CurrentlyPlayingCompact.vue
Normal file
25
src/components/CurrentlyPlayingCompact.vue
Normal file
@ -0,0 +1,25 @@
|
||||
<script setup lang="ts">
|
||||
import { defineProps } from "vue";
|
||||
|
||||
defineProps({
|
||||
currentlyPlaying: Object,
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-3 col-md-2">
|
||||
<img :src="currentlyPlaying.item.album.images[0].url" alt="album cover" class="card-img">
|
||||
</div>
|
||||
<div class="col">
|
||||
<b>{{ currentlyPlaying?.item.name }}</b>
|
||||
<div>
|
||||
{{ currentlyPlaying?.item.artists.map(artist => artist.name).join(', ') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
@ -59,6 +59,7 @@ const update = async (promise: Promise | unknown) => {
|
||||
: promise);
|
||||
} catch (e) {
|
||||
error.value = e;
|
||||
console.error('PR', e);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
showThrobber.value = false;
|
||||
|
@ -17,9 +17,21 @@ const routes: Array<RouteRecordRaw> = [
|
||||
requireAuth: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "/me",
|
||||
name: "me",
|
||||
component: () =>
|
||||
import(/* webpackChunkName: "me" */ "../views/MePage.vue"),
|
||||
meta: {
|
||||
requireAuth: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "/user/:id",
|
||||
name: "user",
|
||||
meta: {
|
||||
allowEmbed: true,
|
||||
},
|
||||
component: () =>
|
||||
import(/* webpackChunkName: "user" */ "../views/UserPage.vue"),
|
||||
},
|
||||
@ -33,7 +45,7 @@ const routes: Array<RouteRecordRaw> = [
|
||||
path: "/auth/callback",
|
||||
name: "authCallback",
|
||||
component: () =>
|
||||
import(/* webpackChunkName: "auth" */ "../views/AuthCallbackPage.vue"),
|
||||
import(/* webpackChunkName: "authCallback" */ "../views/AuthCallbackPage.vue"),
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -14,7 +14,6 @@ const route = useRoute();
|
||||
code: route.query.code,
|
||||
state: route.query.state,
|
||||
})">
|
||||
{{ $route.query }}
|
||||
<div class="alert alert-success">
|
||||
Authorization completed
|
||||
</div>
|
||||
|
39
src/views/MePage.vue
Normal file
39
src/views/MePage.vue
Normal file
@ -0,0 +1,39 @@
|
||||
<script setup lang="ts"></script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<h1>Me</h1>
|
||||
<PromiseResolver
|
||||
:promise="$api.getSession()"
|
||||
v-slot="slot"
|
||||
>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
Your session
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p>
|
||||
{{ slot }}
|
||||
</p>
|
||||
<b>Clients</b>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<button
|
||||
class="btn btn-danger mx-1"
|
||||
@click="$api.leaveSession().then(() => update($api.getSession()))"
|
||||
>
|
||||
leave Session
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-danger mx-1"
|
||||
@click="$api.deleteSession().then(() => update($api.getSession()))"
|
||||
>
|
||||
delete Session
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</PromiseResolver>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss"></style>
|
@ -1,6 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import PromiseResolver from "@/components/PromiseResolver.vue";
|
||||
import CurrentlyPlaying from "@/components/CurrentlyPlaying.vue";
|
||||
import CurrentlyPlayingCompact from "@/components/CurrentlyPlayingCompact.vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import { onBeforeUnmount, ref } from "vue";
|
||||
import { useApi } from "@/Api";
|
||||
@ -20,46 +21,66 @@ onBeforeUnmount(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h1>User</h1>
|
||||
<PromiseResolver
|
||||
:promise="userInfo"
|
||||
v-slot="{ data: { user, currentlyPlaying } }"
|
||||
class="row"
|
||||
>
|
||||
<div class="col-md-4">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
{{ user.displayName }}
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-4">
|
||||
<img :src="user.images[0].url" alt="user image" class="card-img">
|
||||
</div>
|
||||
<div class="col">
|
||||
<p>{{ user.totalFollowers }} followers on Spotify</p>
|
||||
<div v-if="$route.query.embed === 'true'">
|
||||
<PromiseResolver
|
||||
:promise="userInfo"
|
||||
v-slot="{ data: { currentlyPlaying } }"
|
||||
>
|
||||
<CurrentlyPlayingCompact
|
||||
v-if="currentlyPlaying?.item"
|
||||
:currentlyPlaying="currentlyPlaying"
|
||||
:compact="true"
|
||||
/>
|
||||
<p v-else class="alert alert-info">
|
||||
User is not listening to music.
|
||||
</p>
|
||||
</PromiseResolver>
|
||||
</div>
|
||||
<div v-else>
|
||||
<h1>User</h1>
|
||||
<PromiseResolver
|
||||
:promise="userInfo"
|
||||
v-slot="{ data: { user, currentlyPlaying } }"
|
||||
class="row"
|
||||
>
|
||||
<div v-if="$route.query.embed === 'true'">
|
||||
|
||||
</div>
|
||||
<div v-else class="col-md-4">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
{{ user.displayName }}
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-4">
|
||||
<img :src="user.images[0].url" alt="user image" class="card-img">
|
||||
</div>
|
||||
<div class="col">
|
||||
<p>{{ user.totalFollowers }} followers on Spotify</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
v-if="$api.isAuthorized()"
|
||||
@click="$api.joinSession($route.params.id)"
|
||||
class="btn btn-primary my-2"
|
||||
>
|
||||
Join Session
|
||||
</button>
|
||||
<router-link
|
||||
v-else
|
||||
to="/auth"
|
||||
class="btn btn-primary my-2"
|
||||
>
|
||||
login with Spotify and join session
|
||||
</router-link>
|
||||
</div>
|
||||
<button
|
||||
v-if="$api.isAuthorized()"
|
||||
@click="$api.joinSession($route.params.id)"
|
||||
class="btn btn-primary my-2"
|
||||
>
|
||||
Join Session
|
||||
</button>
|
||||
<router-link
|
||||
v-else
|
||||
to="/auth"
|
||||
class="btn btn-primary my-2"
|
||||
>
|
||||
login with Spotify and join session
|
||||
</router-link>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h2>Currently listening to:</h2>
|
||||
<CurrentlyPlaying v-if="currentlyPlaying?.item" :currently-playing="currentlyPlaying" />
|
||||
</div>
|
||||
</PromiseResolver>
|
||||
<div class="col">
|
||||
<h2>Currently listening to:</h2>
|
||||
<CurrentlyPlaying v-if="currentlyPlaying?.item" :currently-playing="currentlyPlaying" />
|
||||
</div>
|
||||
</PromiseResolver>
|
||||
</div>
|
||||
</template>
|
||||
|
Loading…
Reference in New Issue
Block a user