client/src/components/dialogs/BoxViewer.vue

301 lines
7.8 KiB
Vue
Raw Normal View History

2023-02-08 12:37:55 +01:00
<template>
<DialogBase
ref="dialogWindow"
:title="selectedBox.title"
@canceled="closed"
:showFooter="false"
:closeOnEscape="selectedVideo._id == null"
:disableXscroll="true"
:disableYscroll="true"
>
<div id="boxViewer">
<div id="header" class="flex-column">
<div id="background" :style="coverBackground" />
<awesome-icon
icon="star"
size="2x"
class="favourite ma4 z2"
:class="{ active: isFavourite }"
@click="toggleFavourite"
/>
<div id="navigation" class="flex-row grow center z1">
<img class="glow ma" :src="cover" @dblclick="dblclick" />
</div>
<div id="stats" class="z1 pa4">
<div class="flex-row">
<DropDown v-if="$store.getters['user/isAdministrator']">
<button
class="flat ma4 pa8-left pa8-right"
:title="visibility_text"
>
<awesome-icon :icon="visibility_icon" />
</button>
<template v-slot:dropdown-content>
<div>
<button
v-for="(item, i) in $store.state.system.lists.visibility"
:key="i"
@click="setVisibility(item)"
>
<awesome-icon :icon="getVisibilityIcon(item)" />{{
getVisibilityText(item)
}}
</button>
</div>
</template>
</DropDown>
<span class="grow center">
<b>{{ selectedBox.title }}</b>
<br />
<b>{{ box_videos.length }}</b> Videos
</span>
<DropDown v-if="$store.getters['user/isAdministrator']">
<button class="flat ma4 pa8-left pa8-right">
<awesome-icon icon="ellipsis-v" />
</button>
<template v-slot:dropdown-content>
<div>
<button @click="uploadNewCover">
<awesome-icon icon="image" />Set new Cover...
</button>
<button @click="resetCover">
<awesome-icon icon="eraser" />Reset Cover
</button>
<hr />
<button @click="mergeBox">
<awesome-icon icon="compress-alt" />Merge Boxes...
</button>
</div>
</template>
</DropDown>
</div>
</div>
</div>
<ul id="videoList" class="videos">
<li v-for="item in selectedBox.videos" :key="item._id">
<VideoItem :video="item" />
</li>
</ul>
</div>
<BoxMerge ref="mergeDialog" />
</DialogBase>
</template>
<script>
import BoxMerge from "./BoxMerge";
import VideoItem from "../Video";
import { mapGetters } from "vuex";
export default {
methods: {
dblclick() {
this.$store.commit("tracks/resetSelectedTrack");
this.$store.commit("radios/resetSelectedRadio");
this.$store.dispatch("videos/playContainer", this.selectedBox);
},
gotoVideo() {
if (this.$route.query.play) {
let video = this.selectedBox.videos.find(
(f) => f._id == this.$route.query.play
);
if (video) {
this.$store.dispatch("videos/play", video);
}
}
},
gotoNextBox() {
this.$store.dispatch("boxes/gotoNextBox");
},
gotoPrevBox() {
this.$store.dispatch("boxes/gotoPrevBox");
},
closed() {
if (
window.history.state.back.indexOf("?") == -1 ||
window.history.state.back.startsWith("/search")
) {
this.$router.back();
} else {
this.$store.dispatch("boxes/resetSelectedBox");
}
},
keydownListener(e) {
if (e.key == "ArrowLeft") {
e.preventDefault();
this.gotoPrevBox();
}
if (e.key == "ArrowRight") {
e.preventDefault();
this.gotoNextBox();
}
},
mergeBox() {
this.$refs.mergeDialog.open(this.selectedBox);
},
toggleFavourite() {
this.$store.dispatch("user/toggleFavourite", {
itemId: this.selectedBox._id,
type: "box",
});
},
setVisibility(visibility) {
this.selectedBox.visibility = visibility;
this.$store.dispatch("boxes/updateBox", this.selectedBox);
},
uploadNewCover() {
this.$store.dispatch("boxes/uploadNewCover", this.selectedBox);
},
getVisibilityIcon(visibility) {
return visibility == "global"
? "globe"
: visibility == "instance"
? "server"
: visibility == "hidden"
? "eye-slash"
: "user";
},
getVisibilityText(visibility) {
return visibility == "global"
? "Global"
: visibility == "instance"
? "On this server"
: visibility == "hidden"
? "Hide this Box"
: "Only for me";
},
resetCover() {
this.$store.dispatch("boxes/resetCover", this.selectedBox);
},
},
computed: {
...mapGetters({
prevBox: ["boxes/prevBox"],
nextBox: ["boxes/nextBox"],
selectedBox: ["boxes/selectedBox"],
selectedVideo: ["videos/selectedVideo"],
favourites: ["user/favourites"],
}),
box_videos() {
return this.selectedBox.videos || [];
},
box_year() {
return this.selectedBox.year;
},
coverBackground() {
return "background-image: url('" + this.cover + "')";
},
cover() {
let cover = "/static/icons/dummy/box.svg";
if (this.selectedBox.covers && this.selectedBox.covers.cover256) {
cover = this.selectedBox.covers.cover256;
}
return cover;
},
isFavourite() {
return (
this.favourites.find((f) => f.itemId == this.selectedBox._id) !=
undefined
);
},
visibility_icon() {
return this.selectedBox.visibility == "global"
? "globe"
: this.selectedBox.visibility == "instance"
? "server"
: this.selectedBox.visibility == "hidden"
? "eye-slash"
: "user";
},
visibility_text() {
return this.selectedBox.visibility == "global"
? "Visible for the whole world"
: this.selectedBox.visibility == "instance"
? "Visible on this instance"
: this.selectedBox.visibility == "hidden"
? "Hidden for all users"
: "Visible only for me";
},
},
watch: {
selectedBox(newVal) {
if (newVal._id) {
if (!this.$refs.dialogWindow.visible) {
this.$refs.dialogWindow.open();
window.addEventListener("keydown", this.keydownListener);
}
this.gotoVideo();
} else {
if (this.$refs.dialogWindow.visible) {
this.$refs.dialogWindow.close();
}
window.removeEventListener("keydown", this.keydownListener);
}
},
},
components: {
BoxMerge,
VideoItem,
},
};
</script>
<style scoped>
#boxViewer {
display: flex;
flex-direction: row;
height: 100%;
overflow: hidden;
}
#header {
position: relative;
min-width: 280px;
background-color: black;
}
#videoList {
height: 440px;
background-color: var(--white);
z-index: 1;
overflow: overlay;
}
#stats {
z-index: 2;
color: var(--white);
text-shadow: 0 1px 2px black;
line-height: 1.4;
background-color: #ffffff40;
border-top: 1px solid #ffffff20;
border-bottom: 1px solid #00000020;
}
.video {
width: 220px;
}
@media (max-width: 480px) {
#boxViewer {
flex-direction: column;
}
}
@media (max-width: 480px), (max-height: 480px) {
#videoList {
max-height: initial;
height: initial;
}
.video {
width: initial;
}
#navigation img{
height: 220px;
}
}
@media (max-height: 480px) {
#navigation {
align-items: center;
}
}
</style>