Merge pull request 'use new cover structure for radios' (#20) from dev into main #21
@ -1,26 +1,14 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <DialogBase
 | 
			
		||||
    ref="dialogWindow"
 | 
			
		||||
    :title="selectedBox.title"
 | 
			
		||||
    @canceled="closed"
 | 
			
		||||
    :showFooter="false"
 | 
			
		||||
    :closeOnEscape="selectedVideo._id == null"
 | 
			
		||||
    :disableXscroll="true"
 | 
			
		||||
    :disableYscroll="true"
 | 
			
		||||
  >
 | 
			
		||||
  <DialogBase ref="dialogWindow" :title="selectedBox.title" @canceled="closed" :showFooter="false" :closeOnEscape="selectedVideo._id == null" :disableXscroll="true" :disableYscroll="true">
 | 
			
		||||
    <div id="boxViewer" class="flex-row">
 | 
			
		||||
      <div id="header" class="flex-column">
 | 
			
		||||
        <div id="background" :style="coverBackground" />
 | 
			
		||||
        <div class="grow z1 center flex-column">
 | 
			
		||||
          <img class="glow ma24" :src="cover" @dblclick="dblclick" />
 | 
			
		||||
        </div>
 | 
			
		||||
        <awesome-icon
 | 
			
		||||
          icon="star"
 | 
			
		||||
          size="2x"
 | 
			
		||||
          class="favourite ma4 z2"
 | 
			
		||||
          :class="{ active: isFavourite }"
 | 
			
		||||
          @click="toggleFavourite"
 | 
			
		||||
        />
 | 
			
		||||
        <awesome-icon icon="star" size="2x" class="favourite ma4 z2" :class="{ active: isFavourite }" @click="toggleFavourite" />
 | 
			
		||||
        <awesome-icon icon="play" size="2x" class="keepPlaying ma4 primary-text" @click="playProgress" v-if="selectedBox.progress" title="Keep playing" />
 | 
			
		||||
 | 
			
		||||
        <div id="stats" class="flex-row z1">
 | 
			
		||||
          <DropDown v-if="$store.getters['user/isAdministrator']">
 | 
			
		||||
            <button class="flat center" :title="visibility_text">
 | 
			
		||||
@ -28,11 +16,7 @@
 | 
			
		||||
            </button>
 | 
			
		||||
            <template v-slot:dropdown-content>
 | 
			
		||||
              <div>
 | 
			
		||||
                <button
 | 
			
		||||
                  v-for="(item, i) in $store.state.system.lists.visibility"
 | 
			
		||||
                  :key="i"
 | 
			
		||||
                  @click="setVisibility(item)"
 | 
			
		||||
                >
 | 
			
		||||
                <button v-for="(item, i) in $store.state.system.lists.visibility" :key="i" @click="setVisibility(item)">
 | 
			
		||||
                  <awesome-icon :icon="getVisibilityIcon(item)" />{{
 | 
			
		||||
                    getVisibilityText(item)
 | 
			
		||||
                  }}
 | 
			
		||||
@ -41,10 +25,7 @@
 | 
			
		||||
                <button v-if="!selectedBox.share._id" @click="shareEnable">
 | 
			
		||||
                  <awesome-icon icon="share" />Share this box
 | 
			
		||||
                </button>
 | 
			
		||||
                <button
 | 
			
		||||
                  v-if="selectedBox.share._id"
 | 
			
		||||
                  @click="addShareUrlToClipboard"
 | 
			
		||||
                >
 | 
			
		||||
                <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">
 | 
			
		||||
@ -121,6 +102,14 @@ export default {
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    playProgress() {
 | 
			
		||||
      let video = this.selectedBox.videos.find(
 | 
			
		||||
        (f) => f._id == this.selectedBox.progress.id
 | 
			
		||||
      );
 | 
			
		||||
      if (video) {
 | 
			
		||||
        this.$store.dispatch("videos/play", video);
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    gotoNextBox() {
 | 
			
		||||
      this.$store.dispatch("boxes/gotoNextBox");
 | 
			
		||||
    },
 | 
			
		||||
@ -167,19 +156,19 @@ export default {
 | 
			
		||||
      return visibility == "global"
 | 
			
		||||
        ? "globe"
 | 
			
		||||
        : visibility == "instance"
 | 
			
		||||
        ? "server"
 | 
			
		||||
        : visibility == "hidden"
 | 
			
		||||
        ? "eye-slash"
 | 
			
		||||
        : "user";
 | 
			
		||||
          ? "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";
 | 
			
		||||
          ? "On this server"
 | 
			
		||||
          : visibility == "hidden"
 | 
			
		||||
            ? "Hide this Box"
 | 
			
		||||
            : "Only for me";
 | 
			
		||||
    },
 | 
			
		||||
    resetCover() {
 | 
			
		||||
      this.$store.dispatch("boxes/resetCover", this.selectedBox);
 | 
			
		||||
@ -192,6 +181,15 @@ export default {
 | 
			
		||||
    shareDisable() {
 | 
			
		||||
      this.$store.dispatch("boxes/shareDisable", this.selectedBox);
 | 
			
		||||
    },
 | 
			
		||||
    loadUserProgress() {
 | 
			
		||||
      if (this.selectedVideo.parent._id != this.selectedBox._id) {
 | 
			
		||||
        this.$store
 | 
			
		||||
          .dispatch("user/getProgress", this.selectedBox)
 | 
			
		||||
          .then(() => {
 | 
			
		||||
            this.gotoVideo();
 | 
			
		||||
          });
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  computed: {
 | 
			
		||||
    ...mapGetters({
 | 
			
		||||
@ -227,19 +225,19 @@ export default {
 | 
			
		||||
      return this.selectedBox.visibility == "global"
 | 
			
		||||
        ? "globe"
 | 
			
		||||
        : this.selectedBox.visibility == "instance"
 | 
			
		||||
        ? "server"
 | 
			
		||||
        : this.selectedBox.visibility == "hidden"
 | 
			
		||||
        ? "eye-slash"
 | 
			
		||||
        : "user";
 | 
			
		||||
          ? "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";
 | 
			
		||||
          ? "Visible on this instance"
 | 
			
		||||
          : this.selectedBox.visibility == "hidden"
 | 
			
		||||
            ? "Hidden for all users"
 | 
			
		||||
            : "Visible only for me";
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
  watch: {
 | 
			
		||||
@ -249,7 +247,7 @@ export default {
 | 
			
		||||
          this.$refs.dialogWindow.open();
 | 
			
		||||
          window.addEventListener("keydown", this.keydownListener);
 | 
			
		||||
        }
 | 
			
		||||
        this.gotoVideo();
 | 
			
		||||
        this.loadUserProgress();
 | 
			
		||||
      } else {
 | 
			
		||||
        if (this.$refs.dialogWindow.visible) {
 | 
			
		||||
          this.$refs.dialogWindow.close();
 | 
			
		||||
@ -269,14 +267,17 @@ export default {
 | 
			
		||||
#boxViewer {
 | 
			
		||||
  height: 462px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#header {
 | 
			
		||||
  position: relative;
 | 
			
		||||
  background-color: black;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#header img {
 | 
			
		||||
  align-self: center;
 | 
			
		||||
  width: 256px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#stats {
 | 
			
		||||
  z-index: 2;
 | 
			
		||||
  align-items: center;
 | 
			
		||||
@ -287,19 +288,23 @@ export default {
 | 
			
		||||
  border-top: 1px solid #ffffff20;
 | 
			
		||||
  border-bottom: 1px solid #00000020;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.dropdown-activator button {
 | 
			
		||||
  width: 32px;
 | 
			
		||||
  height: 32px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#stats p {
 | 
			
		||||
  max-width: 192px;
 | 
			
		||||
  align-self: center;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#videoList {
 | 
			
		||||
  background-color: var(--white);
 | 
			
		||||
  z-index: 1;
 | 
			
		||||
  overflow: overlay;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.video {
 | 
			
		||||
  width: 220px;
 | 
			
		||||
}
 | 
			
		||||
@ -308,26 +313,32 @@ export default {
 | 
			
		||||
  #boxViewer {
 | 
			
		||||
    flex-direction: column;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  #stats p {
 | 
			
		||||
    max-width: initial;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@media (max-width: 480px), (max-height: 480px) {
 | 
			
		||||
 | 
			
		||||
@media (max-width: 480px),
 | 
			
		||||
(max-height: 480px) {
 | 
			
		||||
  #boxViewer {
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    height: 100%;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  #header img {
 | 
			
		||||
    width: 192px;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  #videoList {
 | 
			
		||||
    height: initial;
 | 
			
		||||
    flex-grow: 1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .video {
 | 
			
		||||
    width: initial;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@media (max-height: 480px) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@media (max-height: 480px) {}
 | 
			
		||||
</style>
 | 
			
		||||
@ -1,37 +1,14 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <DialogBase
 | 
			
		||||
    ref="dialogWindow"
 | 
			
		||||
    @closing="closing"
 | 
			
		||||
    :showFooter="false"
 | 
			
		||||
    :showFullscreenButton="true"
 | 
			
		||||
  >
 | 
			
		||||
  <DialogBase ref="dialogWindow" @closing="closing" :showFooter="false" :showFullscreenButton="true">
 | 
			
		||||
    <template v-slot:header-right>
 | 
			
		||||
      <span v-if="selectedVideo.tracks && selectedVideo.tracks.length > 1"
 | 
			
		||||
        >Language:</span
 | 
			
		||||
      >
 | 
			
		||||
      <select
 | 
			
		||||
        v-if="selectedVideo.tracks && selectedVideo.tracks.length > 1"
 | 
			
		||||
        @change="langChanged"
 | 
			
		||||
        v-model="selectedLang"
 | 
			
		||||
      >
 | 
			
		||||
        <option
 | 
			
		||||
          v-for="(lang, i) in selectedVideo.tracks"
 | 
			
		||||
          :key="i"
 | 
			
		||||
          :value="lang"
 | 
			
		||||
          :title="lang.title"
 | 
			
		||||
        >
 | 
			
		||||
      <span v-if="selectedVideo.tracks && selectedVideo.tracks.length > 1">Language:</span>
 | 
			
		||||
      <select v-if="selectedVideo.tracks && selectedVideo.tracks.length > 1" @change="langChanged" v-model="selectedLang">
 | 
			
		||||
        <option v-for="(lang, i) in selectedVideo.tracks" :key="i" :value="lang" :title="lang.title">
 | 
			
		||||
          {{ lang.lang.toUpperCase() }}
 | 
			
		||||
        </option>
 | 
			
		||||
      </select>
 | 
			
		||||
    </template>
 | 
			
		||||
    <video
 | 
			
		||||
      @ended="nextVideo"
 | 
			
		||||
      @timeupdate="timeUpdate"
 | 
			
		||||
      controls
 | 
			
		||||
      style="height: 100%; width: 100%; background: black"
 | 
			
		||||
      ref="videoControl"
 | 
			
		||||
      src
 | 
			
		||||
    ></video>
 | 
			
		||||
    <video @ended="nextVideo" @timeupdate="timeUpdate" @playing="playing" @pause="pause" controls style="height: 100%; width: 100%; background: black" ref="videoControl" src></video>
 | 
			
		||||
  </DialogBase>
 | 
			
		||||
</template>
 | 
			
		||||
<script>
 | 
			
		||||
@ -42,6 +19,7 @@ export default {
 | 
			
		||||
      languages: [],
 | 
			
		||||
      selectedLang: {},
 | 
			
		||||
      preConvert: false,
 | 
			
		||||
      intervalState: 0,
 | 
			
		||||
    };
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
@ -50,6 +28,30 @@ export default {
 | 
			
		||||
        this.$store.getters["videos/getStreamUrl"] + this.langIndex;
 | 
			
		||||
      this.video.play();
 | 
			
		||||
    },
 | 
			
		||||
    pause() {
 | 
			
		||||
      window.clearInterval(this.intervalState);
 | 
			
		||||
    },
 | 
			
		||||
    playing() {
 | 
			
		||||
      window.clearInterval(this.intervalState);
 | 
			
		||||
      this.pushState();
 | 
			
		||||
 | 
			
		||||
      this.intervalState = setInterval(() => {
 | 
			
		||||
        this.pushState();
 | 
			
		||||
      }, 10000);
 | 
			
		||||
    },
 | 
			
		||||
    pushState() {
 | 
			
		||||
      if (!this.currentUser._id || !this.video || !this.selectedVideo._id) {
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      let item = {
 | 
			
		||||
        id: this.selectedVideo._id,
 | 
			
		||||
        parentId: this.selectedVideo.parent._id,
 | 
			
		||||
        type: "video",
 | 
			
		||||
        progress: Math.round(this.video.currentTime)
 | 
			
		||||
      }
 | 
			
		||||
      this.$store.dispatch("user/saveProgress", item);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    playVideo(video) {
 | 
			
		||||
      this.$store.commit("radios/resetSelectedRadio");
 | 
			
		||||
      this.$store.commit("tracks/resetSelectedTrack");
 | 
			
		||||
@ -81,6 +83,13 @@ export default {
 | 
			
		||||
 | 
			
		||||
      this.video.src =
 | 
			
		||||
        this.$store.getters["videos/getStreamUrl"] + this.langIndex;
 | 
			
		||||
      if (this.selectedVideo.parent.progress) {
 | 
			
		||||
        if (this.selectedVideo.parent.progress.id == this.selectedVideo._id) {
 | 
			
		||||
          this.skipToSecond(this.selectedVideo.parent.progress.progress);
 | 
			
		||||
        }
 | 
			
		||||
        this.selectedVideo.parent.progress = undefined;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      this.video.play();
 | 
			
		||||
 | 
			
		||||
      this.pushHistoryItem();
 | 
			
		||||
@ -120,7 +129,22 @@ export default {
 | 
			
		||||
        });
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    reset() {
 | 
			
		||||
      if (this.$refs.dialogWindow.visible) {
 | 
			
		||||
        this.$refs.dialogWindow.close();
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    skipToSecond(second) {
 | 
			
		||||
      let was_paused = this.video.paused;
 | 
			
		||||
      this.video.pause();
 | 
			
		||||
      this.video.currentTime = second;
 | 
			
		||||
      if (!was_paused) {
 | 
			
		||||
        this.video.play();
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    closing() {
 | 
			
		||||
      window.clearInterval(this.intervalState);
 | 
			
		||||
      this.pushState();
 | 
			
		||||
      this.video = undefined;
 | 
			
		||||
      this.$store.dispatch("videos/resetSelectedVideo");
 | 
			
		||||
    },
 | 
			
		||||
@ -172,9 +196,7 @@ export default {
 | 
			
		||||
      if (newVal._id) {
 | 
			
		||||
        this.playVideo(newVal);
 | 
			
		||||
      } else {
 | 
			
		||||
        if (this.$refs.dialogWindow.visible) {
 | 
			
		||||
          this.$refs.dialogWindow.close();
 | 
			
		||||
        }
 | 
			
		||||
        this.reset();
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
@ -16,6 +16,8 @@ export default {
 | 
			
		||||
    let currentIndex = video.parent.videos.indexOf(video);
 | 
			
		||||
    if (currentIndex < video.parent.videos.length - 1) {
 | 
			
		||||
      context.dispatch("play", video.parent.videos[currentIndex + 1]);
 | 
			
		||||
    } else {
 | 
			
		||||
      this.dispatch("user/resetProgress", video.parent._id);
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  convertNextTo(context, payload) {
 | 
			
		||||
 | 
			
		||||
@ -6,7 +6,7 @@ export default {
 | 
			
		||||
        if (!state.selectedVideo._id) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        state.selectedVideo = { tracks: [] };
 | 
			
		||||
        state.selectedVideo = { tracks: [], parent: { title: "", covers: {} } };
 | 
			
		||||
    },
 | 
			
		||||
    setMostViewed(state, tracks) {
 | 
			
		||||
        state.mostViewed = tracks;
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
export default {
 | 
			
		||||
    selectedVideo: { tracks: [] },
 | 
			
		||||
    selectedVideo: { tracks: [], parent: { title: "", covers: {} } },
 | 
			
		||||
    mostViewed: []
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user