🔨 Add disconnect

This commit is contained in:
SebClem 2022-06-23 12:50:04 +02:00
parent 271228c1b9
commit 28001879a9
Signed by: sebclem
GPG Key ID: 5A4308F6A359EA50
5 changed files with 122 additions and 74 deletions

View File

@ -28,7 +28,7 @@
"uuid": "^8.3.2", "uuid": "^8.3.2",
"vue": "^3.2.33", "vue": "^3.2.33",
"vue-router": "^4.0.14", "vue-router": "^4.0.14",
"vuetify": "^3.0.0-beta.3", "vuetify": "^3.0.0-beta.4",
"webfontloader": "^1.0.0" "webfontloader": "^1.0.0"
}, },
"devDependencies": { "devDependencies": {

View File

@ -11,6 +11,7 @@
:disabled="connectBtnDisable" :disabled="connectBtnDisable"
size="small" size="small"
v-bind="props" v-bind="props"
:loading="voiceChannelConnecting"
> >
{{ status.channel?.name }} {{ status.channel?.name }}
</v-btn> </v-btn>
@ -172,16 +173,19 @@
:disabled="connectBtnDisable" :disabled="connectBtnDisable"
:color="connectBtnDisable ? '' : 'primary'" :color="connectBtnDisable ? '' : 'primary'"
class="elevation-10" class="elevation-10"
@click="onDisconnect"
></v-btn> ></v-btn>
<v-btn <v-btn
v-else v-else
icon="mdi-connection" icon="mdi-connection"
:loading="voiceChannelConnecting"
variant="outlined" variant="outlined"
:disabled="connectBtnDisable" :disabled="connectBtnDisable"
:color="connectBtnDisable ? '' : 'primary'" :color="connectBtnDisable ? '' : 'primary'"
class="elevation-10" class="elevation-10"
id="connectBtn" id="connectBtn"
></v-btn> >
</v-btn>
</v-col> </v-col>
</v-row> </v-row>
<v-overlay <v-overlay
@ -236,11 +240,11 @@
import type { Chanel } from "@/data/guild/Channel"; import type { Chanel } from "@/data/guild/Channel";
import type { Guild } from "@/data/guild/Guild"; import type { Guild } from "@/data/guild/Guild";
import type { Status } from "@/data/music/Status"; import type { Status } from "@/data/music/Status";
import { connect, getAudioStatus } from "@/services/audioService"; import { connect, getAudioStatus, disconnect } from "@/services/audioService";
import { getVoiceChannels } from "@/services/guildService"; import { getVoiceChannels } from "@/services/guildService";
import { computed } from "@vue/reactivity"; import { computed } from "@vue/reactivity";
import { ref, watch } from "vue"; import { ref, watch } from "vue";
import { onBeforeRouteUpdate } from "vue-router"; import { onBeforeRouteLeave, onBeforeRouteUpdate } from "vue-router";
const properties = defineProps<{ const properties = defineProps<{
guild: Guild; guild: Guild;
@ -253,11 +257,7 @@ const status = ref<Status>({ connected: false });
const chanListMenuOpen = ref(false); const chanListMenuOpen = ref(false);
const chanListLoading = ref(true); const chanListLoading = ref(true);
const voiceChannelList = ref<Chanel[]>([]); const voiceChannelList = ref<Chanel[]>([]);
const voiceChannelConnecting = ref(false);
getAudioStatus(properties.guild.id).then((value) => {
status.value = value;
loading.value = false;
});
const progress = computed(() => { const progress = computed(() => {
if ( if (
@ -324,12 +324,9 @@ const privateChan = computed(() => {
return status.value.connected && !status.value.canView; return status.value.connected && !status.value.canView;
}); });
function timeToMMSS(time: number) { const selectedListVoice = computed(() => {
let seconds = Math.floor(time / 1000); return [status.value.channel?.id as string];
const minutes = Math.floor(seconds / 60); });
seconds = seconds % 60;
return `${minutes}:${("0" + seconds).slice(-2)}`;
}
watch(chanListMenuOpen, (value) => { watch(chanListMenuOpen, (value) => {
if (value) { if (value) {
@ -343,24 +340,56 @@ watch(chanListMenuOpen, (value) => {
}); });
function voiceChannelSelected(value: string[]) { function voiceChannelSelected(value: string[]) {
voiceChannelConnecting.value = true;
if (value[0] != status.value.channel?.id) { if (value[0] != status.value.channel?.id) {
connect(properties.guild.id, value[0]); connect(properties.guild.id, value[0]).then((value) => {
if (value) {
status.value = value.data;
voiceChannelConnecting.value = false;
}
});
} }
} }
const selectedListVoice = computed(() => { function onDisconnect() {
return [status.value.channel?.id as string]; disconnect(properties.guild.id)
.then((value) => {
if (value) {
status.value = value.data;
}
})
.catch();
}
function timeToMMSS(time: number) {
let seconds = Math.floor(time / 1000);
const minutes = Math.floor(seconds / 60);
seconds = seconds % 60;
return `${minutes}:${("0" + seconds).slice(-2)}`;
}
getAudioStatus(properties.guild.id).then((value) => {
if (value) {
status.value = value.data;
loading.value = false;
}
}); });
let interval = setInterval(() => { let interval = setInterval(() => {
getAudioStatus(properties.guild.id).then((value) => { getAudioStatus(properties.guild.id).then((value) => {
status.value = value; if (value) {
status.value = value.data;
}
}); });
}, 1000); }, 1000);
onBeforeRouteUpdate(() => { onBeforeRouteUpdate(() => {
clearInterval(interval); clearInterval(interval);
}); });
onBeforeRouteLeave(() => {
clearInterval(interval);
});
</script> </script>
<style scoped></style> <style scoped></style>

View File

@ -4,6 +4,7 @@ import type { TrackInfo } from "./TrackInfo";
type Status = { type Status = {
connected: boolean; connected: boolean;
canView?: boolean; canView?: boolean;
connectionStatus?: string;
canInteract?: boolean; canInteract?: boolean;
channel?: Chanel; channel?: Chanel;
playBackInfo?: { playBackInfo?: {

View File

@ -3,62 +3,74 @@ import { useEventQueuStore } from "@/stores/eventQueu";
import { useUserStore } from "@/stores/user"; import { useUserStore } from "@/stores/user";
import axios from "axios"; import axios from "axios";
function getAudioStatus(guildId: string): Promise<Status> { function getAudioStatus(guildId: string) {
return new Promise((resolve, reject) => { const userStore = useUserStore();
const userStore = useUserStore(); return axios
axios .get<Status>(`/audio/${guildId}/status`, {
.get<Status>(`/audio/${guildId}/status`, { headers: {
authorization: `Bearer ${userStore.token}`,
},
})
.catch((reason) => {
console.error(`Fail to retrive audio status !`);
console.log(reason);
const eventQueuStore = useEventQueuStore();
eventQueuStore.push({
uuid: undefined,
type: "error",
text: "Fail to retrive audio status !",
});
});
}
function connect(guildId: string, voiceChannelId: string) {
const userStore = useUserStore();
return axios
.post<Status>(
`/audio/${guildId}/connect`,
{
channelId: voiceChannelId,
},
{
headers: { headers: {
authorization: `Bearer ${userStore.token}`, authorization: `Bearer ${userStore.token}`,
}, },
}) }
.then((value) => { )
resolve(value.data); .catch((reason) => {
}) console.error(`Fail to connect to voice channel !`);
.catch((reason) => { console.log(reason);
console.error(`Fail to retrive audio status !`); const eventQueuStore = useEventQueuStore();
console.log(reason); eventQueuStore.push({
const eventQueuStore = useEventQueuStore(); uuid: undefined,
eventQueuStore.push({ type: "error",
uuid: undefined, text: "Fail to connect to voice channel !",
type: "error",
text: "Fail to retrive audio status !",
});
reject(reason);
}); });
}); });
} }
function connect(guildId: string, voiceChannelId: string): Promise<void> { function disconnect(guildId: string) {
return new Promise((resolve, reject) => { const userStore = useUserStore();
const userStore = useUserStore(); return axios
axios .post<Status>(
.post<Status>( `/audio/${guildId}/disconnect`,
`/audio/${guildId}/connect`, {},
{ {
channelId: voiceChannelId, headers: {
authorization: `Bearer ${userStore.token}`,
}, },
{ }
headers: { )
authorization: `Bearer ${userStore.token}`, .catch((reason) => {
}, console.error(`Fail to disconnect from voice channel !`);
} console.log(reason);
) const eventQueuStore = useEventQueuStore();
.then(() => { eventQueuStore.push({
resolve(); uuid: undefined,
}) type: "error",
.catch((reason) => { text: "Fail to disconnect from voice channel !",
console.error(`Fail to connect to voice channel !`);
console.log(reason);
const eventQueuStore = useEventQueuStore();
eventQueuStore.push({
uuid: undefined,
type: "error",
text: "Fail to connect to voice channel !",
});
reject(reason);
}); });
}); });
} }
export { getAudioStatus, connect }; export { getAudioStatus, connect, disconnect };

View File

@ -3648,7 +3648,7 @@ __metadata:
vue-cli-plugin-vuetify: ~2.4.8 vue-cli-plugin-vuetify: ~2.4.8
vue-router: ^4.0.14 vue-router: ^4.0.14
vue-tsc: ^0.34.7 vue-tsc: ^0.34.7
vuetify: ^3.0.0-beta.3 vuetify: ^3.0.0-beta.4
vuetify-loader: ^2.0.0-alpha.0 vuetify-loader: ^2.0.0-alpha.0
webfontloader: ^1.0.0 webfontloader: ^1.0.0
languageName: unknown languageName: unknown
@ -10626,19 +10626,25 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"vuetify@npm:^3.0.0-beta.3": "vuetify@npm:^3.0.0-beta.4":
version: 3.0.0-beta.3 version: 3.0.0-beta.4
resolution: "vuetify@npm:3.0.0-beta.3" resolution: "vuetify@npm:3.0.0-beta.4"
peerDependencies: peerDependencies:
"@formatjs/intl": ^1.0.0 || ^2.0.0 "@formatjs/intl": ^1.0.0 || ^2.0.0
vue: ^3.2.36 vite-plugin-vuetify: 1.0.0-alpha.12
vue: ^3.2.0
vue-i18n: ^9.0.0 vue-i18n: ^9.0.0
webpack-plugin-vuetify: 2.0.0-alpha.11
peerDependenciesMeta: peerDependenciesMeta:
"@formatjs/intl": "@formatjs/intl":
optional: true optional: true
vite-plugin-vuetify:
optional: true
vue-i18n: vue-i18n:
optional: true optional: true
checksum: 2e1ef8f8ac1ba3bb0f60f275d0c07e747acff59cbae920f7c963bb786c0c726729e3a06a441f8817c540840a5c0f6175477334aa3f7393f62ee4b7dd583ad287 webpack-plugin-vuetify:
optional: true
checksum: 7c6d67c2f25a1bc62b52a6c551e747f890e1f9362696781a5e6f16ad96e2c2d8be56eb0eeef338d6da511e18672f86dd2d9e97ca1bc7453bc9dd75abd93209d5
languageName: node languageName: node
linkType: hard linkType: hard