Merge pull request #143 from Deedone/timestamps
Make timestamps clickable
This commit is contained in:
		
						commit
						2d66b97328
					
				| 
						 | 
					@ -0,0 +1,26 @@
 | 
				
			||||||
 | 
					import Vue from 'vue'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default Vue.extend({
 | 
				
			||||||
 | 
					  name: 'FtTimestampCatcher',
 | 
				
			||||||
 | 
					  props: {
 | 
				
			||||||
 | 
					    inputHTML: {
 | 
				
			||||||
 | 
					      type: String,
 | 
				
			||||||
 | 
					      default: ''
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  methods: {
 | 
				
			||||||
 | 
					    catchTimestampClick: function(event) {
 | 
				
			||||||
 | 
					      const match = event.detail.match(/(\d+):(\d+):?(\d+)?/)
 | 
				
			||||||
 | 
					      if (match[3] !== undefined) { // HH:MM:SS
 | 
				
			||||||
 | 
					        const seconds = 3600 * Number(match[1]) + 60 * Number(match[2]) + Number(match[3])
 | 
				
			||||||
 | 
					        this.$emit('timestampEvent', seconds)
 | 
				
			||||||
 | 
					      } else { // MM:SS
 | 
				
			||||||
 | 
					        const seconds = 60 * Number(match[1]) + Number(match[2])
 | 
				
			||||||
 | 
					        this.$emit('timestampEvent', seconds)
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    detectTimestamps: function (input) {
 | 
				
			||||||
 | 
					      return input.replaceAll(/(\d+(:\d+)+)/g, '<a href="#" onclick="this.dispatchEvent(new CustomEvent(\'timestampClicked\',{bubbles:true, detail:\'$1\'}))">$1</a>')
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,9 @@
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <p
 | 
				
			||||||
 | 
					    @timestampClicked="catchTimestampClick"
 | 
				
			||||||
 | 
					    v-html="detectTimestamps(inputHTML)"
 | 
				
			||||||
 | 
					  />
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script src="./ft-timestamp-catcher.js" />
 | 
				
			||||||
 | 
					<style scoped src="./ft-timestamp-catcher.css" />
 | 
				
			||||||
| 
						 | 
					@ -3,12 +3,14 @@ import { mapActions } from 'vuex'
 | 
				
			||||||
import FtCard from '../ft-card/ft-card.vue'
 | 
					import FtCard from '../ft-card/ft-card.vue'
 | 
				
			||||||
import FtLoader from '../../components/ft-loader/ft-loader.vue'
 | 
					import FtLoader from '../../components/ft-loader/ft-loader.vue'
 | 
				
			||||||
import CommentScraper from 'yt-comment-scraper'
 | 
					import CommentScraper from 'yt-comment-scraper'
 | 
				
			||||||
 | 
					import FtTimestampCatcher from '../../components/ft-timestamp-catcher/ft-timestamp-catcher.vue'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default Vue.extend({
 | 
					export default Vue.extend({
 | 
				
			||||||
  name: 'WatchVideoComments',
 | 
					  name: 'WatchVideoComments',
 | 
				
			||||||
  components: {
 | 
					  components: {
 | 
				
			||||||
    'ft-card': FtCard,
 | 
					    'ft-card': FtCard,
 | 
				
			||||||
    'ft-loader': FtLoader
 | 
					    'ft-loader': FtLoader,
 | 
				
			||||||
 | 
					    'ft-timestamp-catcher': FtTimestampCatcher
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  props: {
 | 
					  props: {
 | 
				
			||||||
    id: {
 | 
					    id: {
 | 
				
			||||||
| 
						 | 
					@ -39,6 +41,10 @@ export default Vue.extend({
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  methods: {
 | 
					  methods: {
 | 
				
			||||||
 | 
					    onTimestamp: function(timestamp) {
 | 
				
			||||||
 | 
					      this.$emit('timestampEvent', timestamp)
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    getCommentData: function () {
 | 
					    getCommentData: function () {
 | 
				
			||||||
      this.isLoading = true
 | 
					      this.isLoading = true
 | 
				
			||||||
      switch (this.backendPreference) {
 | 
					      switch (this.backendPreference) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -46,9 +46,11 @@
 | 
				
			||||||
            {{ comment.time }}
 | 
					            {{ comment.time }}
 | 
				
			||||||
          </span>
 | 
					          </span>
 | 
				
			||||||
        </p>
 | 
					        </p>
 | 
				
			||||||
        <p class="commentText">
 | 
					        <ft-timestamp-catcher
 | 
				
			||||||
          {{ comment.text }}
 | 
					          class="commentText"
 | 
				
			||||||
        </p>
 | 
					          :inputHTML="comment.text"
 | 
				
			||||||
 | 
					          @timestampEvent="onTimestamp"
 | 
				
			||||||
 | 
					        />
 | 
				
			||||||
        <p class="commentLikeCount">
 | 
					        <p class="commentLikeCount">
 | 
				
			||||||
          <font-awesome-icon
 | 
					          <font-awesome-icon
 | 
				
			||||||
            icon="thumbs-up"
 | 
					            icon="thumbs-up"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,11 +1,13 @@
 | 
				
			||||||
import Vue from 'vue'
 | 
					import Vue from 'vue'
 | 
				
			||||||
import FtCard from '../ft-card/ft-card.vue'
 | 
					import FtCard from '../ft-card/ft-card.vue'
 | 
				
			||||||
 | 
					import FtTimestampCatcher from '../ft-timestamp-catcher/ft-timestamp-catcher.vue'
 | 
				
			||||||
import autolinker from 'autolinker'
 | 
					import autolinker from 'autolinker'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default Vue.extend({
 | 
					export default Vue.extend({
 | 
				
			||||||
  name: 'WatchVideoDescription',
 | 
					  name: 'WatchVideoDescription',
 | 
				
			||||||
  components: {
 | 
					  components: {
 | 
				
			||||||
    'ft-card': FtCard
 | 
					    'ft-card': FtCard,
 | 
				
			||||||
 | 
					    'ft-timestamp-catcher': FtTimestampCatcher
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  props: {
 | 
					  props: {
 | 
				
			||||||
    published: {
 | 
					    published: {
 | 
				
			||||||
| 
						 | 
					@ -34,6 +36,9 @@ export default Vue.extend({
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  methods: {
 | 
					  methods: {
 | 
				
			||||||
 | 
					    onTimestamp: function(timestamp) {
 | 
				
			||||||
 | 
					      this.$emit('timestampEvent', timestamp)
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    parseDescriptionHtml: function (descriptionText) {
 | 
					    parseDescriptionHtml: function (descriptionText) {
 | 
				
			||||||
      descriptionText = descriptionText.replace(/target="_blank"/g, '')
 | 
					      descriptionText = descriptionText.replace(/target="_blank"/g, '')
 | 
				
			||||||
      descriptionText = descriptionText.replace(/\/redirect.+?(?=q=)/g, '')
 | 
					      descriptionText = descriptionText.replace(/\/redirect.+?(?=q=)/g, '')
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,8 +1,9 @@
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <ft-card class="videoDescription">
 | 
					  <ft-card class="videoDescription">
 | 
				
			||||||
    <p
 | 
					    <ft-timestamp-catcher
 | 
				
			||||||
      class="description"
 | 
					      class="description"
 | 
				
			||||||
      v-html="shownDescription"
 | 
					      :inputHTML="shownDescription"
 | 
				
			||||||
 | 
					      @timestampEvent="onTimestamp"
 | 
				
			||||||
    />
 | 
					    />
 | 
				
			||||||
  </ft-card>
 | 
					  </ft-card>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -166,6 +166,9 @@ export default Vue.extend({
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  methods: {
 | 
					  methods: {
 | 
				
			||||||
 | 
					    changeTimestamp: function(timestamp) {
 | 
				
			||||||
 | 
					      this.$refs.videoPlayer.player.currentTime(timestamp)
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    toggleTheatreMode: function() {
 | 
					    toggleTheatreMode: function() {
 | 
				
			||||||
      this.useTheatreMode = !this.useTheatreMode
 | 
					      this.useTheatreMode = !this.useTheatreMode
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -86,12 +86,14 @@
 | 
				
			||||||
        :description-html="videoDescriptionHtml"
 | 
					        :description-html="videoDescriptionHtml"
 | 
				
			||||||
        class="watchVideo"
 | 
					        class="watchVideo"
 | 
				
			||||||
        :class="{ theatreWatchVideo: useTheatreMode }"
 | 
					        :class="{ theatreWatchVideo: useTheatreMode }"
 | 
				
			||||||
 | 
					        @timestampEvent="changeTimestamp"
 | 
				
			||||||
      />
 | 
					      />
 | 
				
			||||||
      <watch-video-comments
 | 
					      <watch-video-comments
 | 
				
			||||||
        v-if="!isLoading && !isLive"
 | 
					        v-if="!isLoading && !isLive"
 | 
				
			||||||
        :id="videoId"
 | 
					        :id="videoId"
 | 
				
			||||||
        class="watchVideo"
 | 
					        class="watchVideo"
 | 
				
			||||||
        :class="{ theatreWatchVideo: useTheatreMode }"
 | 
					        :class="{ theatreWatchVideo: useTheatreMode }"
 | 
				
			||||||
 | 
					        @timestampEvent="changeTimestamp"
 | 
				
			||||||
      />
 | 
					      />
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <div class="sidebarArea">
 | 
					    <div class="sidebarArea">
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue