Sharing #1

Merged
artem merged 3 commits from dev into main 2023-02-17 00:06:14 +01:00
13 changed files with 567 additions and 110 deletions
Showing only changes of commit 4d4fb4b4e9 - Show all commits

File diff suppressed because it is too large Load Diff

View File

@ -245,7 +245,7 @@ export default {
},
login() {
let hash = window.location.hash.replace("#/", "");
if (!hash.startsWith("login") && !hash.startsWith("setup")) {
if (!hash.startsWith("login") && !hash.startsWith("setup") && !hash.startsWith("share")) {
let redirect = encodeURIComponent(hash);
if (redirect) {
this.$router.replace({

View File

@ -0,0 +1,72 @@
<template>
<div id="content" class="flex-column">
<div class="flex-column ma-horizontal">
<h1>{{ album.title }}</h1>
<h2>{{ album.artist_name }}</h2>
</div>
<div id="tracks" class="flex-row border-top">
<div class="flex-column">
<img id="cover" class="shadow ma24" :src="cover" />
<p class="center ma-off hideOnMobile">
<b>{{ album.tracks.length }}</b> Tracks
</p>
</div>
<ul id="trackList" class="tracks">
<li v-for="track in album.tracks" :key="track._id">
<TrackItem :track="track" :showCover="false" />
</li>
</ul>
</div>
</div>
</template>
<script>
import TrackItem from "../components/Track";
export default {
data() {
return {
album: {
covers: {},
tracks: [],
},
};
},
methods: {
show(album) {
this.album = album;
},
},
computed: {
cover() {
if (!this.album.covers) {
return "/static/icons/dummy/album.svg";
}
return this.album.covers.cover256;
},
},
components: {
TrackItem,
},
};
</script>
<style scoped>
#cover {
align-self: center;
width: 256px;
}
#content,
#tracks {
overflow: auto;
}
@media (max-width: 480px) {
#tracks {
flex-direction: column;
}
#trackList {
border-top: 1px solid var(--light-border);
}
}
</style>

View File

@ -0,0 +1,78 @@
<template>
<div id="content" class="flex-column">
<div class="flex-column ma-horizontal">
<h1>{{ box.title }}</h1>
</div>
<div id="videos" class="flex-row border-top">
<div class="flex-column">
<img id="cover" class="shadow ma24" :src="cover" />
<p class="center ma-off hideOnMobile">
<b>{{ box.videos.length }}</b> Videos
</p>
</div>
<ul id="videoList" class="videos">
<li v-for="video in box.videos" :key="video._id">
<VideoItem :video="video" />
</li>
</ul>
</div>
</div>
</template>
<script>
import VideoItem from "../components/Video.vue";
export default {
data() {
return {
box: {
covers: {},
videos: [],
},
};
},
methods: {
show(box) {
this.box = box;
},
},
computed: {
cover() {
if (!this.box.covers) {
return "/static/icons/dummy/box.svg";
}
return this.box.covers.cover256;
},
},
components: {
VideoItem,
},
};
</script>
<style scoped>
#cover {
align-self: center;
width: 256px;
}
#content,
#videos {
overflow: auto;
}
.video {
max-width: 256px;
}
@media (max-width: 480px) {
#videos {
flex-direction: column;
}
#videoList {
border-top: 1px solid var(--light-border);
}
.video {
max-width: inherit;
}
}
</style>

View File

@ -181,6 +181,13 @@ export default {
this.audio.pause();
this.audio.src = url;
this.pushHistoryItem();
},
pushHistoryItem() {
if (!this.currentUser._id) {
return;
}
let item = {
id: this.currentTrackParent._id,
type: this.currentTrackParentType,
@ -258,15 +265,17 @@ export default {
}
},
gotoContainer() {
switch (this.selectedTrack.parentType) {
case "album":
this.$router.push("/albums?id=" + this.selectedTrack.parent._id);
break;
case "artist":
this.$router.push(
"/artists?id=" + this.selectedTrack.parent.parent._id
);
break;
if (this.currentUser._id) {
switch (this.selectedTrack.parentType) {
case "album":
this.$router.push("/albums?id=" + this.selectedTrack.parent._id);
break;
case "artist":
this.$router.push(
"/artists?id=" + this.selectedTrack.parent.parent._id
);
break;
}
}
},
switchShuffle() {
@ -275,9 +284,15 @@ export default {
},
switchRepeatType() {
this.$store.dispatch("player/switchPlayerRepeatMode");
if (!this.currentUser._id) {
return;
}
this.saveUserSettings();
},
saveUserSettings() {
if (!this.currentUser._id) {
return;
}
this.$store.dispatch("user/savePlayerSettings");
},
timeUpdate(event) {
@ -314,6 +329,9 @@ export default {
}
return type;
},
currentUser() {
return this.$store.getters["user/user"];
},
formatedD() {
let m = Math.floor(this.duration / 60);
let s = Math.floor(this.duration - m * 60);

View File

@ -40,7 +40,13 @@
<button v-if="!selectedAlbum.share._id" @click="shareEnable">
<awesome-icon icon="share" />Share this album
</button>
<button v-else @click="shareDisable">
<button
v-if="selectedAlbum.share._id"
@click="addShareUrlToClipboard"
>
<awesome-icon icon="clipboard" />Copy url into clipboard
</button>
<button v-if="selectedAlbum.share._id" @click="shareDisable">
<awesome-icon icon="share" />Remove share
</button>
</div>
@ -110,6 +116,11 @@ export default {
};
},
methods: {
addShareUrlToClipboard() {
let url =
window.location.origin + "/#/share?id=" + this.selectedAlbum.share._id;
navigator.clipboard.writeText(url);
},
dblclick() {
this.$store.commit("tracks/resetSelectedTrack");
this.$store.commit("radios/resetSelectedRadio");
@ -208,7 +219,11 @@ export default {
this.$store.dispatch("albums/selectAlbum", album);
},
shareEnable() {
this.$store.dispatch("albums/shareEnable", this.selectedAlbum);
this.$store
.dispatch("albums/shareEnable", this.selectedAlbum)
.then(() => {
this.addShareUrlToClipboard();
});
},
shareDisable() {
this.$store.dispatch("albums/shareDisable", this.selectedAlbum);
@ -342,7 +357,7 @@ export default {
border-top: 1px solid #ffffff20;
border-bottom: 1px solid #00000020;
}
#stats button {
.dropdown-activator button {
width: 32px;
height: 32px;
}

View File

@ -41,7 +41,13 @@
<button v-if="!selectedBox.share._id" @click="shareEnable">
<awesome-icon icon="share" />Share this box
</button>
<button v-else @click="shareDisable">
<button
v-if="selectedBox.share._id"
@click="addShareUrlToClipboard"
>
<awesome-icon icon="clipboard" />Copy url into clipboard
</button>
<button v-if="selectedBox.share._id" @click="shareDisable">
<awesome-icon icon="share" />Remove share
</button>
</div>
@ -95,6 +101,11 @@ import { mapGetters } from "vuex";
export default {
methods: {
addShareUrlToClipboard() {
let url =
window.location.origin + "/#/share?id=" + this.selectedBox.share._id;
navigator.clipboard.writeText(url);
},
dblclick() {
this.$store.commit("tracks/resetSelectedTrack");
this.$store.commit("radios/resetSelectedRadio");
@ -174,7 +185,9 @@ export default {
this.$store.dispatch("boxes/resetCover", this.selectedBox);
},
shareEnable() {
this.$store.dispatch("boxes/shareEnable", this.selectedBox);
this.$store.dispatch("boxes/shareEnable", this.selectedBox).then(() => {
this.addShareUrlToClipboard();
});
},
shareDisable() {
this.$store.dispatch("boxes/shareDisable", this.selectedBox);
@ -274,7 +287,7 @@ export default {
border-top: 1px solid #ffffff20;
border-bottom: 1px solid #00000020;
}
#stats button {
.dropdown-activator button {
width: 32px;
height: 32px;
}

View File

@ -89,6 +89,9 @@ export default {
this.$store.dispatch("videos/playNextTo", this.selectedVideo);
},
pushHistoryItem() {
if (!this.currentUser._id) {
return;
}
let item = {
id: this.selectedVideo.parent._id,
type: "box",
@ -154,6 +157,9 @@ export default {
},
},
computed: {
currentUser() {
return this.$store.getters["user/user"];
},
selectedVideo() {
return this.$store.getters["videos/selectedVideo"];
},

View File

@ -155,8 +155,11 @@ export default {
axios.put(context.rootGetters.server + "/api/albums/" + album._id, body, context.rootGetters.headers);
},
shareEnable(context, album) {
axios.post(context.rootGetters.server + "/api/albums/" + album._id + "/share", {}, context.rootGetters.headers).then(res => {
album.share = res.data;
return new Promise(resolve => {
axios.post(context.rootGetters.server + "/api/albums/" + album._id + "/share", {}, context.rootGetters.headers).then(res => {
album.share = res.data;
resolve();
});
});
},
shareDisable(context, album) {

View File

@ -131,8 +131,11 @@ export default {
});
},
shareEnable(context, box) {
axios.post(context.rootGetters.server + "/api/boxes/" + box._id + "/share", {}, context.rootGetters.headers).then(res => {
box.share = res.data;
return new Promise(resolve => {
axios.post(context.rootGetters.server + "/api/boxes/" + box._id + "/share", {}, context.rootGetters.headers).then(res => {
box.share = res.data;
resolve();
});
});
},
shareDisable(context, box) {

View File

@ -4,12 +4,23 @@ export default {
get(context, id) {
return new Promise((resolve) => {
axios.get(context.rootGetters.server + "/api/shares/" + id, context.rootGetters.headers).then((res) => {
if (res.data.object.type == "album") {
console.log(res.data)
res.data.object.tracks.forEach(track => {
track.parent = res.data.object;
track.parentType = "album"
});
if (!res.data._id) {
resolve(res.data);
return;
}
switch (res.data.object.type) {
case "album":
res.data.object.tracks.forEach(track => {
track.parent = res.data.object;
track.parentType = "album"
});
break;
case "box":
res.data.object.videos.forEach(video => {
video.parent = res.data.object;
video.parentType = "box"
});
break;
}
resolve(res.data);
});

View File

@ -4,7 +4,7 @@ import router from '../../../router'
export default {
play(context, video) {
context.commit("selectVideo", video);
if (context.rootGetters.routerQuery.play != video._id) {
if (context.rootGetters.routerQuery.play != video._id && context.rootGetters.routerPath != "/share") {
router.push("/boxes?id=" + video.parent._id + "&play=" + video._id);
}
},

View File

@ -1,52 +1,62 @@
<template>
<div ref="share" id="share" class="flex-column">
<div class="flex-column ma-horizontal">
<h1>{{ object.title }}</h1>
<h2>{{ object.artist_name }}</h2>
</div>
<div id="content" class="flex-row border-top">
<div>
<img id="cover" class="shadow ma24" :src="cover" />
</div>
<ul id="trackList" class="tracks">
<li v-for="track in object.tracks" :key="track._id">
<TrackItem :track="track" :showCover="false" />
</li>
</ul>
</div>
<AlbumContent ref="album" v-if="type == 'album'" />
<BoxContent ref="box" v-if="type == 'box'" />
</div>
</template>
<script>
import TrackItem from "../components/Track";
import AlbumContent from "../components/AlbumContent.vue";
import BoxContent from "../components/BoxContent.vue";
export default {
name: "ShareView",
data() {
return {
object: {
covers: { cover256: "" },
},
type: "",
};
},
mounted() {
if (this.$route.query.id) {
this.$store.dispatch("share/get", this.$route.query.id).then((res) => {
this.$nextTick(() => {
this.object = res.object;
methods: {
loadShare() {
if (this.$route.query.id) {
this.$store.dispatch("share/get", this.$route.query.id).then((res) => {
if (!res._id) {
this.$router.replace("/login");
return;
}
this.type = res.object.type;
this.$nextTick(() => {
switch (this.type) {
case "album":
this.$refs.album.show(res.object);
break;
case "box":
this.$refs.box.show(res.object);
break;
}
});
});
});
} else {
this.$router.replace("/");
}
} else {
this.$router.replace("/login");
}
},
},
computed: {
cover() {
return this.object.covers.cover256;
server() {
return this.$store.getters.server;
},
},
components: {
TrackItem,
AlbumContent,
BoxContent,
},
watch: {
server() {
this.loadShare();
},
"$route.query.id": function () {
this.loadShare();
},
},
};
</script>
@ -55,12 +65,4 @@ export default {
#share {
overflow: auto;
}
#cover {
align-self: flex-start;
width: 256px;
align-self: center;
}
#content {
overflow: auto;
}
</style>