|
@@ -1,12 +1,12 @@
|
|
|
<script setup lang="ts">
|
|
|
-import { useForm } from "@/composables/useForm";
|
|
|
import Toast from "toasters";
|
|
|
import { defineAsyncComponent, ref, onMounted } from "vue";
|
|
|
import { GenericResponse } from "@musare_types/actions/GenericActions";
|
|
|
+import VueJsonPretty from "vue-json-pretty";
|
|
|
+import { useForm } from "@/composables/useForm";
|
|
|
import { useWebsocketsStore } from "@/stores/websockets";
|
|
|
import { useModalsStore } from "@/stores/modals";
|
|
|
import { useLongJobsStore } from "@/stores/longJobs";
|
|
|
-import VueJsonPretty from "vue-json-pretty";
|
|
|
import "vue-json-pretty/lib/styles.css";
|
|
|
|
|
|
const Modal = defineAsyncComponent(() => import("@/components/Modal.vue"));
|
|
@@ -30,66 +30,31 @@ const createdBy = ref();
|
|
|
const createdAt = ref(0);
|
|
|
const hideMusicbrainzData = ref(true);
|
|
|
|
|
|
-const relatedSongs = ref([]);
|
|
|
+// const relatedSongs = ref([]);
|
|
|
|
|
|
-const refreshRelatedSongs = () => {}
|
|
|
-const refreshRelatedAlbums = () => {}
|
|
|
-
|
|
|
-onMounted(() => {
|
|
|
- socket.onConnect(() => {
|
|
|
- if (props.artistId && !props.createArtist) {
|
|
|
- socket.dispatch(
|
|
|
- `artists.getArtistFromId`,
|
|
|
- props.artistId,
|
|
|
- (res) => { // res: GetArtistResponse
|
|
|
- if (res.status === "success") {
|
|
|
- setOriginalValue({
|
|
|
- name: res.data.artist.name,
|
|
|
- musicbrainzIdentifier: res.data.artist.musicbrainzIdentifier,
|
|
|
- musicbrainzData: res.data.artist.musicbrainzData ?? {},
|
|
|
- youtubeChannels: res.data.artist.youtubeChannels ?? [],
|
|
|
- spotifyArtists: res.data.artist.spotifyArtists ?? [],
|
|
|
- soundcloudArtists: res.data.artist.soundcloudArtists ?? [],
|
|
|
- });
|
|
|
- createdBy.value = res.data.artist.createdBy;
|
|
|
- createdAt.value = res.data.artist.createdAt;
|
|
|
-
|
|
|
- refreshRelatedSongs();
|
|
|
- refreshRelatedAlbums();
|
|
|
- } else {
|
|
|
- new Toast("Artist with that ID not found.");
|
|
|
- closeCurrentModal();
|
|
|
- }
|
|
|
- }
|
|
|
- );
|
|
|
- }
|
|
|
- });
|
|
|
-});
|
|
|
+const refreshRelatedSongs = () => {};
|
|
|
+const refreshRelatedAlbums = () => {};
|
|
|
|
|
|
-const {
|
|
|
- inputs,
|
|
|
- save,
|
|
|
- setOriginalValue,
|
|
|
- } = useForm(
|
|
|
+const { inputs, save, setOriginalValue } = useForm(
|
|
|
{
|
|
|
name: {
|
|
|
- value: "",
|
|
|
+ value: ""
|
|
|
},
|
|
|
musicbrainzIdentifier: {
|
|
|
- value: "",
|
|
|
+ value: ""
|
|
|
},
|
|
|
musicbrainzData: {
|
|
|
- value: {},
|
|
|
+ value: {}
|
|
|
},
|
|
|
youtubeChannels: {
|
|
|
- value: [],
|
|
|
+ value: []
|
|
|
},
|
|
|
spotifyArtists: {
|
|
|
- value: [],
|
|
|
+ value: []
|
|
|
},
|
|
|
soundcloudArtists: {
|
|
|
- value: [],
|
|
|
- },
|
|
|
+ value: []
|
|
|
+ }
|
|
|
},
|
|
|
({ status, messages, values }, resolve, reject) => {
|
|
|
if (status === "success") {
|
|
@@ -99,7 +64,7 @@ const {
|
|
|
musicbrainzData: values.musicbrainzData,
|
|
|
youtubeChannels: values.youtubeChannels,
|
|
|
spotifyArtists: values.spotifyArtists,
|
|
|
- soundcloudArtists: values.soundcloudArtists,
|
|
|
+ soundcloudArtists: values.soundcloudArtists
|
|
|
};
|
|
|
const cb = (res: GenericResponse) => {
|
|
|
new Toast(res.message);
|
|
@@ -118,10 +83,40 @@ const {
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
- modalUuid: props.modalUuid,
|
|
|
- },
|
|
|
+ modalUuid: props.modalUuid
|
|
|
+ }
|
|
|
);
|
|
|
|
|
|
+onMounted(() => {
|
|
|
+ socket.onConnect(() => {
|
|
|
+ if (props.artistId && !props.createArtist) {
|
|
|
+ socket.dispatch(`artists.getArtistFromId`, props.artistId, res => {
|
|
|
+ // res: GetArtistResponse
|
|
|
+ if (res.status === "success") {
|
|
|
+ setOriginalValue({
|
|
|
+ name: res.data.artist.name,
|
|
|
+ musicbrainzIdentifier:
|
|
|
+ res.data.artist.musicbrainzIdentifier,
|
|
|
+ musicbrainzData: res.data.artist.musicbrainzData ?? {},
|
|
|
+ youtubeChannels: res.data.artist.youtubeChannels ?? [],
|
|
|
+ spotifyArtists: res.data.artist.spotifyArtists ?? [],
|
|
|
+ soundcloudArtists:
|
|
|
+ res.data.artist.soundcloudArtists ?? []
|
|
|
+ });
|
|
|
+ createdBy.value = res.data.artist.createdBy;
|
|
|
+ createdAt.value = res.data.artist.createdAt;
|
|
|
+
|
|
|
+ refreshRelatedSongs();
|
|
|
+ refreshRelatedAlbums();
|
|
|
+ } else {
|
|
|
+ new Toast("Artist with that ID not found.");
|
|
|
+ closeCurrentModal();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+});
|
|
|
+
|
|
|
const saveArtist = (close?: boolean) => {
|
|
|
save(() => {
|
|
|
if (close) {
|
|
@@ -130,45 +125,49 @@ const saveArtist = (close?: boolean) => {
|
|
|
});
|
|
|
};
|
|
|
|
|
|
-const getMusicbrainzArtistData = (musicbrainzIdentifier) => {
|
|
|
- socket.dispatch("artists.getMusicbrainzArtist", musicbrainzIdentifier, (res) => {
|
|
|
- new Toast("Successfully got data");
|
|
|
- inputs.value["musicbrainzData"].value = res.data;
|
|
|
- });
|
|
|
-}
|
|
|
+const getMusicbrainzArtistData = musicbrainzIdentifier => {
|
|
|
+ socket.dispatch(
|
|
|
+ "artists.getMusicbrainzArtist",
|
|
|
+ musicbrainzIdentifier,
|
|
|
+ res => {
|
|
|
+ new Toast("Successfully got data");
|
|
|
+ inputs.value.musicbrainzData.value = res.data;
|
|
|
+ }
|
|
|
+ );
|
|
|
+};
|
|
|
|
|
|
const addYoutubeChannel = () => {
|
|
|
- inputs.value["youtubeChannels"].value.push({
|
|
|
+ inputs.value.youtubeChannels.value.push({
|
|
|
youtubeChannelId: "",
|
|
|
- comment: "",
|
|
|
+ comment: ""
|
|
|
});
|
|
|
-}
|
|
|
+};
|
|
|
|
|
|
const removeYoutubeChannel = index => {
|
|
|
- inputs.value["youtubeChannels"].value.splice(index, 1);
|
|
|
-}
|
|
|
+ inputs.value.youtubeChannels.value.splice(index, 1);
|
|
|
+};
|
|
|
|
|
|
const addSpotifyArtist = () => {
|
|
|
- inputs.value["spotifyArtists"].value.push({
|
|
|
+ inputs.value.spotifyArtists.value.push({
|
|
|
spotifyArtistId: "",
|
|
|
- comment: "",
|
|
|
+ comment: ""
|
|
|
});
|
|
|
-}
|
|
|
+};
|
|
|
|
|
|
const removeSpotifyArtist = index => {
|
|
|
- inputs.value["spotifyArtists"].value.splice(index, 1);
|
|
|
-}
|
|
|
+ inputs.value.spotifyArtists.value.splice(index, 1);
|
|
|
+};
|
|
|
|
|
|
const addSoundcloudArtist = () => {
|
|
|
- inputs.value["soundcloudArtists"].value.push({
|
|
|
+ inputs.value.soundcloudArtists.value.push({
|
|
|
soundcloudArtistId: "",
|
|
|
- comment: "",
|
|
|
+ comment: ""
|
|
|
});
|
|
|
-}
|
|
|
+};
|
|
|
|
|
|
const removeSoundcloudArtist = index => {
|
|
|
- inputs.value["soundcloudArtists"].value.splice(index, 1);
|
|
|
-}
|
|
|
+ inputs.value.soundcloudArtists.value.splice(index, 1);
|
|
|
+};
|
|
|
|
|
|
const importYoutubeChannel = youtubeChannelId => {
|
|
|
let id;
|
|
@@ -202,39 +201,62 @@ const importYoutubeChannel = youtubeChannelId => {
|
|
|
}
|
|
|
}
|
|
|
);
|
|
|
-}
|
|
|
+};
|
|
|
|
|
|
const fillMissingUrls = musicbrainzIdentifier => {
|
|
|
- socket.dispatch("artists.getMusicbrainzRelatedUrls", musicbrainzIdentifier, res => {
|
|
|
- const youtubeUrls = res.data.relations.filter(relation => relation.type === "youtube").map(relation => relation.url.resource);
|
|
|
-
|
|
|
- const promises = [];
|
|
|
-
|
|
|
- youtubeUrls.forEach(youtubeUrl => {
|
|
|
- promises.push(new Promise(resolve => {
|
|
|
- socket.dispatch("artists.getIdFromUrl", "youtube", youtubeUrl, res => {
|
|
|
- console.log(555, res);
|
|
|
-
|
|
|
- if (res.status === "success") {
|
|
|
- const youtubeChannelId = res.channelId;
|
|
|
-
|
|
|
- const existingYoutubeChannelIds = inputs.value["youtubeChannels"].value.map(youtubeChannel => youtubeChannel.youtubeChannelId);
|
|
|
- if (!existingYoutubeChannelIds.includes(youtubeChannelId)) {
|
|
|
- inputs.value["youtubeChannels"].value.push({
|
|
|
- youtubeChannelId,
|
|
|
- comment: `MusicBrainz URL artist relation ${'test'}`,
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- resolve(null);
|
|
|
- });
|
|
|
- }));
|
|
|
- });
|
|
|
-
|
|
|
- Promise.all(promises);
|
|
|
- });
|
|
|
-}
|
|
|
+ socket.dispatch(
|
|
|
+ "artists.getMusicbrainzRelatedUrls",
|
|
|
+ musicbrainzIdentifier,
|
|
|
+ res => {
|
|
|
+ const youtubeUrls = res.data.relations
|
|
|
+ .filter(relation => relation.type === "youtube")
|
|
|
+ .map(relation => relation.url.resource);
|
|
|
+
|
|
|
+ const promises = [];
|
|
|
+
|
|
|
+ youtubeUrls.forEach(youtubeUrl => {
|
|
|
+ promises.push(
|
|
|
+ new Promise(resolve => {
|
|
|
+ socket.dispatch(
|
|
|
+ "artists.getIdFromUrl",
|
|
|
+ "youtube",
|
|
|
+ youtubeUrl,
|
|
|
+ res => {
|
|
|
+ console.log(555, res);
|
|
|
+
|
|
|
+ if (res.status === "success") {
|
|
|
+ const youtubeChannelId = res.channelId;
|
|
|
+
|
|
|
+ const existingYoutubeChannelIds =
|
|
|
+ inputs.value.youtubeChannels.value.map(
|
|
|
+ youtubeChannel =>
|
|
|
+ youtubeChannel.youtubeChannelId
|
|
|
+ );
|
|
|
+ if (
|
|
|
+ !existingYoutubeChannelIds.includes(
|
|
|
+ youtubeChannelId
|
|
|
+ )
|
|
|
+ ) {
|
|
|
+ inputs.value.youtubeChannels.value.push(
|
|
|
+ {
|
|
|
+ youtubeChannelId,
|
|
|
+ comment: `MusicBrainz URL artist relation ${"test"}`
|
|
|
+ }
|
|
|
+ );
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ resolve(null);
|
|
|
+ }
|
|
|
+ );
|
|
|
+ })
|
|
|
+ );
|
|
|
+ });
|
|
|
+
|
|
|
+ Promise.all(promises);
|
|
|
+ }
|
|
|
+ );
|
|
|
+};
|
|
|
</script>
|
|
|
|
|
|
<template>
|
|
@@ -266,24 +288,41 @@ const fillMissingUrls = musicbrainzIdentifier => {
|
|
|
<div>
|
|
|
<div class="control is-grouped gap-4">
|
|
|
<div class="musicbrainz-identifier-container">
|
|
|
- <label class="label">MusicBrainz identifier</label>
|
|
|
+ <label class="label"
|
|
|
+ >MusicBrainz identifier</label
|
|
|
+ >
|
|
|
<input
|
|
|
class="input"
|
|
|
type="text"
|
|
|
- :ref="el => (inputs['musicbrainzIdentifier'].ref = el)"
|
|
|
- v-model="inputs['musicbrainzIdentifier'].value"
|
|
|
+ :ref="
|
|
|
+ el =>
|
|
|
+ (inputs[
|
|
|
+ 'musicbrainzIdentifier'
|
|
|
+ ].ref = el)
|
|
|
+ "
|
|
|
+ v-model="
|
|
|
+ inputs['musicbrainzIdentifier'].value
|
|
|
+ "
|
|
|
placeholder="Enter MusicBrainz identifier..."
|
|
|
/>
|
|
|
</div>
|
|
|
<button
|
|
|
class="button is-primary button-bottom"
|
|
|
- @click="getMusicbrainzArtistData(inputs['musicbrainzIdentifier'].value)"
|
|
|
+ @click="
|
|
|
+ getMusicbrainzArtistData(
|
|
|
+ inputs['musicbrainzIdentifier'].value
|
|
|
+ )
|
|
|
+ "
|
|
|
>
|
|
|
Get MusicBrainz artist data
|
|
|
</button>
|
|
|
<button
|
|
|
class="button is-primary button-bottom"
|
|
|
- @click="fillMissingUrls(inputs['musicbrainzIdentifier'].value)"
|
|
|
+ @click="
|
|
|
+ fillMissingUrls(
|
|
|
+ inputs['musicbrainzIdentifier'].value
|
|
|
+ )
|
|
|
+ "
|
|
|
>
|
|
|
Fill artists/channels from MusicBrainz
|
|
|
</button>
|
|
@@ -293,10 +332,17 @@ const fillMissingUrls = musicbrainzIdentifier => {
|
|
|
<p class="text-vcenter">MusicBrainz data</p>
|
|
|
<button
|
|
|
class="button is-primary"
|
|
|
- @click="hideMusicbrainzData = !hideMusicbrainzData"
|
|
|
+ @click="
|
|
|
+ hideMusicbrainzData =
|
|
|
+ !hideMusicbrainzData
|
|
|
+ "
|
|
|
>
|
|
|
- <span v-show="hideMusicbrainzData">Show MusicBrainz data</span>
|
|
|
- <span v-show="!hideMusicbrainzData">Hide MusicBrainz data</span>
|
|
|
+ <span v-show="hideMusicbrainzData"
|
|
|
+ >Show MusicBrainz data</span
|
|
|
+ >
|
|
|
+ <span v-show="!hideMusicbrainzData"
|
|
|
+ >Hide MusicBrainz data</span
|
|
|
+ >
|
|
|
</button>
|
|
|
</div>
|
|
|
<vue-json-pretty
|
|
@@ -310,16 +356,22 @@ const fillMissingUrls = musicbrainzIdentifier => {
|
|
|
<p>YouTube channels</p>
|
|
|
<div class="flex flex-column gap-4">
|
|
|
<template
|
|
|
- v-for="(youtubeChannel, index) in inputs['youtubeChannels'].value"
|
|
|
+ v-for="(youtubeChannel, index) in inputs[
|
|
|
+ 'youtubeChannels'
|
|
|
+ ].value"
|
|
|
:key="`${index}`"
|
|
|
>
|
|
|
<div class="control is-grouped gap-4">
|
|
|
<div class="name-container">
|
|
|
- <label class="label">YouTube channel ID</label>
|
|
|
+ <label class="label"
|
|
|
+ >YouTube channel ID</label
|
|
|
+ >
|
|
|
<input
|
|
|
class="input"
|
|
|
type="text"
|
|
|
- v-model="youtubeChannel.youtubeChannelId"
|
|
|
+ v-model="
|
|
|
+ youtubeChannel.youtubeChannelId
|
|
|
+ "
|
|
|
placeholder="Enter YouTube channel ID..."
|
|
|
/>
|
|
|
</div>
|
|
@@ -340,7 +392,11 @@ const fillMissingUrls = musicbrainzIdentifier => {
|
|
|
</button>
|
|
|
<button
|
|
|
class="button is-primary button-bottom"
|
|
|
- @click="importYoutubeChannel(youtubeChannel.youtubeChannelId)"
|
|
|
+ @click="
|
|
|
+ importYoutubeChannel(
|
|
|
+ youtubeChannel.youtubeChannelId
|
|
|
+ )
|
|
|
+ "
|
|
|
>
|
|
|
Import
|
|
|
</button>
|
|
@@ -358,16 +414,22 @@ const fillMissingUrls = musicbrainzIdentifier => {
|
|
|
<p>Spotify artists</p>
|
|
|
<div class="flex flex-column gap-4">
|
|
|
<template
|
|
|
- v-for="(spotifyArtist, index) in inputs['spotifyArtists'].value"
|
|
|
+ v-for="(spotifyArtist, index) in inputs[
|
|
|
+ 'spotifyArtists'
|
|
|
+ ].value"
|
|
|
:key="`${index}`"
|
|
|
>
|
|
|
<div class="control is-grouped gap-4">
|
|
|
<div class="name-container">
|
|
|
- <label class="label">Spotify artist ID</label>
|
|
|
+ <label class="label"
|
|
|
+ >Spotify artist ID</label
|
|
|
+ >
|
|
|
<input
|
|
|
class="input"
|
|
|
type="text"
|
|
|
- v-model="spotifyArtist.spotifyArtistId"
|
|
|
+ v-model="
|
|
|
+ spotifyArtist.spotifyArtistId
|
|
|
+ "
|
|
|
placeholder="Enter Spotify artist ID..."
|
|
|
/>
|
|
|
</div>
|
|
@@ -400,16 +462,22 @@ const fillMissingUrls = musicbrainzIdentifier => {
|
|
|
<p>SoundCloud artists</p>
|
|
|
<div class="flex flex-column gap-4">
|
|
|
<template
|
|
|
- v-for="(soundcloudArtist, index) in inputs['soundcloudArtists'].value"
|
|
|
+ v-for="(soundcloudArtist, index) in inputs[
|
|
|
+ 'soundcloudArtists'
|
|
|
+ ].value"
|
|
|
:key="`${index}`"
|
|
|
>
|
|
|
<div class="control is-grouped gap-4">
|
|
|
<div class="name-container">
|
|
|
- <label class="label">SoundCloud artist ID</label>
|
|
|
+ <label class="label"
|
|
|
+ >SoundCloud artist ID</label
|
|
|
+ >
|
|
|
<input
|
|
|
class="input"
|
|
|
type="text"
|
|
|
- v-model="soundcloudArtist.soundcloudArtistId"
|
|
|
+ v-model="
|
|
|
+ soundcloudArtist.soundcloudArtistId
|
|
|
+ "
|
|
|
placeholder="Enter Soundcloud artist ID..."
|
|
|
/>
|
|
|
</div>
|
|
@@ -439,9 +507,7 @@ const fillMissingUrls = musicbrainzIdentifier => {
|
|
|
</button>
|
|
|
</div>
|
|
|
</div>
|
|
|
- <div class="flex flex-column w-1/3">
|
|
|
-
|
|
|
- </div>
|
|
|
+ <div class="flex flex-column w-1/3"></div>
|
|
|
</div>
|
|
|
</template>
|
|
|
<template #footer>
|
|
@@ -462,7 +528,8 @@ const fillMissingUrls = musicbrainzIdentifier => {
|
|
|
<style lang="less">
|
|
|
.night-mode {
|
|
|
.edit-artist-modal {
|
|
|
- .vjs-tree-node.is-highlight, .vjs-tree-node:hover {
|
|
|
+ .vjs-tree-node.is-highlight,
|
|
|
+ .vjs-tree-node:hover {
|
|
|
background: black;
|
|
|
}
|
|
|
}
|