]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/commitdiff
Handle unavailable videos in embed playlists
authorChocobozzz <me@florianbigard.com>
Wed, 5 Aug 2020 09:41:22 +0000 (11:41 +0200)
committerChocobozzz <chocobozzz@cpy.re>
Fri, 7 Aug 2020 06:58:29 +0000 (08:58 +0200)
client/src/assets/player/playlist/playlist-menu-item.ts
client/src/assets/player/playlist/playlist-menu.ts
client/src/sass/player/playlist.scss
scripts/i18n/create-custom-files.ts

index 916c6338f4efd7b323bd1ba741542bda9ae4eb3b..21a7f80465f5b7d54c2e95163bb56f3ec301bcf5 100644 (file)
@@ -26,24 +26,47 @@ class PlaylistMenuItem extends Component {
       innerHTML: ''
     }) as HTMLElement
 
+    if (!options.element.video) {
+      li.classList.add('vjs-disabled')
+    }
+
     const positionBlock = super.createEl('div', {
       className: 'item-position-block'
-    })
+    }) as HTMLElement
 
     const position = super.createEl('div', {
       className: 'item-position',
       innerHTML: options.element.position
     })
 
+    positionBlock.appendChild(position)
+    li.appendChild(positionBlock)
+
+    if (options.element.video) {
+      this.buildAvailableVideo(li, positionBlock, options)
+    } else {
+      this.buildUnavailableVideo(li)
+    }
+
+    return li
+  }
+
+  setSelected (selected: boolean) {
+    if (selected) this.addClass('vjs-selected')
+    else this.removeClass('vjs-selected')
+  }
+
+  getElement () {
+    return this.element
+  }
+
+  private buildAvailableVideo (li: HTMLElement, positionBlock: HTMLElement, options: PlaylistItemOptions) {
     const player = super.createEl('div', {
       className: 'item-player'
     })
 
-    positionBlock.appendChild(position)
     positionBlock.appendChild(player)
 
-    li.appendChild(positionBlock)
-
     const thumbnail = super.createEl('img', {
       src: window.location.origin + options.element.video.thumbnailPath
     })
@@ -67,17 +90,15 @@ class PlaylistMenuItem extends Component {
 
     li.append(thumbnail)
     li.append(infoBlock)
-
-    return li
   }
 
-  setSelected (selected: boolean) {
-    if (selected) this.addClass('vjs-selected')
-    else this.removeClass('vjs-selected')
-  }
+  private buildUnavailableVideo (li: HTMLElement) {
+    const block = super.createEl('div', {
+      className: 'item-unavailable',
+      innerHTML: this.player().localize('Unavailable video')
+    })
 
-  getElement () {
-    return this.element
+    li.appendChild(block)
   }
 
   private handleKeyDown (event: KeyboardEvent) {
index 7d7d9e12f11cb996b1cddaed4be2f0f1b236e2e2..37284fb44ae558d670d8ac15157c2bdd8194a1d2 100644 (file)
@@ -11,8 +11,18 @@ class PlaylistMenu extends Component {
   constructor (player: videojs.Player, options?: PlaylistPluginOptions) {
     super(player, options as any)
 
-    this.player().on('userinactive', () => {
-      this.close()
+    const self = this
+
+    function userInactiveHandler () {
+      self.close()
+    }
+
+    this.el().addEventListener('mouseenter', () => {
+      this.player().off('userinactive', userInactiveHandler)
+    })
+
+    this.el().addEventListener('mouseleave', () => {
+      this.player().one('userinactive', userInactiveHandler)
     })
 
     this.player().on('click', event => {
index c242acba88078ce47da5497dcdf12a3578f10470..544d45a481e00b9e082cabdd9363c769babf2558 100644 (file)
@@ -24,17 +24,17 @@ $playlist-menu-width: 350px;
     justify-content: space-between;
 
     .title {
+      @include ellipsis;
+
       font-size: 14px;
       margin-bottom: 5px;
-      white-space: nowrap;
-      text-overflow: ellipsis;
     }
 
     .channel {
+      @include ellipsis;
+
       font-size: 11px;
       color: #bfbfbf;
-      white-space: nowrap;
-      text-overflow: ellipsis;
     }
 
     .cross {
@@ -106,9 +106,13 @@ $playlist-menu-width: 350px;
 }
 
 .vjs-playlist-menu-item {
-  cursor: pointer;
   display: flex;
   padding: 10px 0;
+  height: 60px;
+
+  &:not(.vjs-disabled) {
+    cursor: pointer;
+  }
 
   .item-position-block {
     position: relative;
@@ -116,6 +120,14 @@ $playlist-menu-width: 350px;
     align-items: center;
     justify-content: center;
     width: 30px;
+    flex-shrink: 0;
+  }
+
+  .item-unavailable {
+    position: relative;
+    display: flex;
+    align-items: center;
+    justify-content: center;
   }
 
   .item-player {
@@ -136,7 +148,7 @@ $playlist-menu-width: 350px;
     }
   }
 
-  &:hover {
+  &:hover:not(.vjs-disabled) {
     background-color: rgba(150, 150, 150, 0.2);
   }
 
@@ -146,20 +158,21 @@ $playlist-menu-width: 350px;
   }
 
   .info-block {
-    margin-left: 10px;
+    margin: 0 10px;
+    min-width: 1px;
 
     .title {
+      @include ellipsis;
+
       font-size: 13px;
       margin-bottom: 5px;
-      white-space: nowrap;
-      text-overflow: ellipsis;
     }
 
     .channel {
+      @include ellipsis;
+
       font-size: 11px;
       color: #bfbfbf;
-      white-space: nowrap;
-      text-overflow: ellipsis;
     }
   }
 }
index 89a967b148b194f96037af449f45b91c7aaceffb..78a51d1e657ac17bd4a9e55c2168e7cc97b0d170 100755 (executable)
@@ -52,7 +52,8 @@ values(VIDEO_CATEGORIES)
     'This playlist does not exist',
     'We cannot fetch the playlist. Please try again later.',
     'Playlist: {1}',
-    'By {1}'
+    'By {1}',
+    'Unavailable video'
   ])
   .forEach(v => { serverKeys[v] = v })