main #19

Merged
artem merged 39 commits from main into dev 2023-09-22 14:13:12 +02:00
13 changed files with 191 additions and 13 deletions
Showing only changes of commit dd9ba6188c - Show all commits

View File

@ -808,6 +808,10 @@ li {
list-style: none; list-style: none;
} }
li:hover {
background-color: var(--nav);
}
li.selected, li.selected,
li.active { li.active {
background-color: var(--selected); background-color: var(--selected);

View File

@ -1,7 +1,11 @@
<template> <template>
<div id="app"> <div id="app">
<nav <nav
v-show="$route.path != '/login' && $route.path != '/setup' && $route.path != '/share' " v-show="
$route.path != '/login' &&
$route.path != '/setup' &&
$route.path != '/share'
"
:class="{ slideOverTop: $store.getters.isDialogOpen }" :class="{ slideOverTop: $store.getters.isDialogOpen }"
> >
<div> <div>
@ -72,6 +76,14 @@
> >
<awesome-icon icon="server" />Server settings <awesome-icon icon="server" />Server settings
</button> </button>
<button
@click="openDialog('sharedItems')"
v-if="$store.getters['user/isAdministrator']"
>
<awesome-icon icon="share" />Shared items
</button>
<button <button
v-if="$store.getters.isElectron" v-if="$store.getters.isElectron"
@click="openDialog('dialogSettings')" @click="openDialog('dialogSettings')"
@ -122,6 +134,7 @@
<VideoScreen /> <VideoScreen />
<AudioUploadDialog ref="audioUploader" /> <AudioUploadDialog ref="audioUploader" />
<VideoUploadDialog ref="videoUploader" /> <VideoUploadDialog ref="videoUploader" />
<SharedItems ref="sharedItems" />
</div> </div>
</template> </template>
@ -135,6 +148,7 @@ import Player from "./components/Player";
import ServerSettings from "./components/dialogs/ServerSettings"; import ServerSettings from "./components/dialogs/ServerSettings";
import AudioUploadDialog from "./components/dialogs/AudioUpload"; import AudioUploadDialog from "./components/dialogs/AudioUpload";
import VideoUploadDialog from "./components/dialogs/VideoUpload"; import VideoUploadDialog from "./components/dialogs/VideoUpload";
import SharedItems from "./components/dialogs/SharedItems";
import { mapGetters } from "vuex"; import { mapGetters } from "vuex";
@ -245,7 +259,11 @@ export default {
}, },
login() { login() {
let hash = window.location.hash.replace("#/", ""); let hash = window.location.hash.replace("#/", "");
if (!hash.startsWith("login") && !hash.startsWith("setup") && !hash.startsWith("share")) { if (
!hash.startsWith("login") &&
!hash.startsWith("setup") &&
!hash.startsWith("share")
) {
let redirect = encodeURIComponent(hash); let redirect = encodeURIComponent(hash);
if (redirect) { if (redirect) {
this.$router.replace({ this.$router.replace({
@ -284,6 +302,7 @@ export default {
UserProfile, UserProfile,
VideoScreen, VideoScreen,
VideoUploadDialog, VideoUploadDialog,
SharedItems,
}, },
}; };
</script> </script>

View File

@ -1,10 +1,10 @@
<template> <template>
<div id="content" class="flex-column"> <div id="content" class="flex-column">
<div class="flex-column ma-horizontal"> <div class="flex-column pa-horizontal border-bottom hideOnMobile">
<h1>{{ album.title }}</h1> <h1>{{ album.title }}</h1>
<h2>{{ album.artist_name }}</h2> <h2>{{ album.artist_name }}</h2>
</div> </div>
<div id="tracks" class="flex-row border-top"> <div id="tracks" class="flex-row">
<div class="flex-column"> <div class="flex-column">
<img id="cover" class="shadow ma24" :src="cover" /> <img id="cover" class="shadow ma24" :src="cover" />
<p class="center ma-off hideOnMobile"> <p class="center ma-off hideOnMobile">

View File

@ -1,9 +1,9 @@
<template> <template>
<div id="content" class="flex-column"> <div id="content" class="flex-column">
<div class="flex-column ma-horizontal"> <div class="flex-column pa-horizontal border-bottom hideOnMobile">
<h1>{{ box.title }}</h1> <h1>{{ box.title }}</h1>
</div> </div>
<div id="videos" class="flex-row border-top"> <div id="videos" class="flex-row">
<div class="flex-column"> <div class="flex-column">
<img id="cover" class="shadow ma24" :src="cover" /> <img id="cover" class="shadow ma24" :src="cover" />
<p class="center ma-off hideOnMobile"> <p class="center ma-off hideOnMobile">

View File

@ -0,0 +1,110 @@
<template>
<DialogBase ref="dialogWindow" title="Shared items" button-text="close">
<div class="flex-column">
<ul v-if="shares.length > 0">
<li
class="flex-row pa4-top pa4-bottom"
v-for="share in shares"
:key="share._id"
>
<div class="flex-row grow">
<a
:href="'/#/share?id=' + share._id"
target="webplay_share"
:title="'Open ' + share.type"
>
<img
class="cover ma-horizontal shadow pointer"
:src="cover(share)"
/>
</a>
<p class="grow ma-off">
{{ share.type }}
</p>
<button class="flat danger" @click="shareDisable(share)">
<awesome-icon icon="trash" />
</button>
</div>
</li>
</ul>
<h3 v-else class="ma">No shares on your instance</h3>
</div>
</DialogBase>
</template>
<script>
import { mapGetters } from "vuex";
export default {
methods: {
open() {
this.loadCollection();
this.$store.state.systemDialog = true;
this.$refs.dialogWindow.open();
},
closed() {
this.$store.state.systemDialog = false;
},
cover(item) {
switch (item.type) {
case "album":
return item.cover || "/static/icons/dummy/album.svg";
case "box":
return item.cover || "/static/icons/dummy/box.svg";
}
},
loadCollection() {
this.$store.dispatch("share/loadShares");
},
shareDisable(share) {
switch (share.type) {
case "album":
this.$store
.dispatch("albums/getAlbumById", share.object_id)
.then((item) => {
this.$store
.dispatch(
"albums/shareDisable",
item || { _id: share.object_id }
)
.then(() => {
this.loadCollection();
});
});
break;
case "box":
this.$store
.dispatch("boxes/getBoxById", share.object_id)
.then((item) => {
this.$store
.dispatch(
"boxes/shareDisable",
item || { _id: share.object_id }
)
.then(() => {
this.loadCollection();
});
});
break;
}
},
},
computed: {
...mapGetters({
shares: ["share/collection"],
}),
},
};
</script>
<style scoped>
li p {
align-self: center;
}
li .cover {
width: 32px;
}
</style>

View File

@ -111,6 +111,12 @@ export default {
context.dispatch("selectAlbum", album); context.dispatch("selectAlbum", album);
} }
}, },
getAlbumById(context, id) {
return new Promise(resolve => {
let album = context.getters.collection.find(item => item._id == id);
resolve(album);
});
},
gotoPrevAlbum(context) { gotoPrevAlbum(context) {
let prevAlbum = context.getters.prevAlbum; let prevAlbum = context.getters.prevAlbum;
if (prevAlbum._id) { if (prevAlbum._id) {
@ -163,8 +169,11 @@ export default {
}); });
}, },
shareDisable(context, album) { shareDisable(context, album) {
return new Promise(resolve => {
axios.delete(context.rootGetters.server + "/api/albums/" + album._id + "/share", context.rootGetters.headers).then(() => { axios.delete(context.rootGetters.server + "/api/albums/" + album._id + "/share", context.rootGetters.headers).then(() => {
album.share = {}; album.share = {};
resolve();
});
}); });
} }
} }

View File

@ -75,6 +75,12 @@ export default {
context.dispatch("selectBox", box); context.dispatch("selectBox", box);
} }
}, },
getBoxById(context, id) {
return new Promise(resolve => {
let box = context.getters.collection.find(item => item._id == id);
resolve(box);
});
},
gotoPrevBox(context) { gotoPrevBox(context) {
let prevBox = context.getters.prevBox; let prevBox = context.getters.prevBox;
if (prevBox._id) { if (prevBox._id) {
@ -139,8 +145,11 @@ export default {
}); });
}, },
shareDisable(context, box) { shareDisable(context, box) {
return new Promise(resolve => {
axios.delete(context.rootGetters.server + "/api/boxes/" + box._id + "/share", context.rootGetters.headers).then(() => { axios.delete(context.rootGetters.server + "/api/boxes/" + box._id + "/share", context.rootGetters.headers).then(() => {
box.share = {}; box.share = {};
resolve();
});
}); });
} }
} }

View File

@ -1,6 +1,11 @@
import axios from 'axios' import axios from 'axios'
export default { export default {
loadShares(context) {
axios.get(context.rootGetters.server + "/api/shares", context.rootGetters.headers).then((res) => {
context.commit('setShares', res.data);
});
},
get(context, id) { get(context, id) {
return new Promise((resolve) => { return new Promise((resolve) => {
axios.get(context.rootGetters.server + "/api/shares/" + id, context.rootGetters.headers).then((res) => { axios.get(context.rootGetters.server + "/api/shares/" + id, context.rootGetters.headers).then((res) => {

View File

@ -0,0 +1,5 @@
export default {
collection(state) {
return state.collection;
},
}

View File

@ -1,9 +1,12 @@
//import state from './state.js'; import state from './state.js';
//import getters from './getters.js'; import getters from './getters.js';
//import mutations from './mutations.js'; import mutations from './mutations.js';
import actions from './actions.js'; import actions from './actions.js';
export default { export default {
namespaced: true, namespaced: true,
state,
getters,
mutations,
actions actions
} }

View File

@ -0,0 +1,6 @@
export default {
setShares(state, shares) {
state.collection = shares;
},
}

View File

@ -0,0 +1,3 @@
export default {
collection: [],
}

View File

@ -16,6 +16,11 @@ export default {
type: "", type: "",
}; };
}, },
mounted() {
if (this.server != "none") {
this.loadShare();
}
},
methods: { methods: {
loadShare() { loadShare() {
if (this.$route.query.id) { if (this.$route.query.id) {