diff options
author | Chocobozzz <me@florianbigard.com> | 2020-08-05 11:41:22 +0200 |
---|---|---|
committer | Chocobozzz <chocobozzz@cpy.re> | 2020-08-07 08:58:29 +0200 |
commit | 56674bb9f81775ff85115e7daa7d9be0db95c001 (patch) | |
tree | 06f74dd3a0d1a39b8e1272c54794604c3a5f6ef2 | |
parent | a950e4c82bd458e924b00698a77c06275a64a46c (diff) | |
download | PeerTube-56674bb9f81775ff85115e7daa7d9be0db95c001.tar.gz PeerTube-56674bb9f81775ff85115e7daa7d9be0db95c001.tar.zst PeerTube-56674bb9f81775ff85115e7daa7d9be0db95c001.zip |
Handle unavailable videos in embed playlists
-rw-r--r-- | client/src/assets/player/playlist/playlist-menu-item.ts | 45 | ||||
-rw-r--r-- | client/src/assets/player/playlist/playlist-menu.ts | 14 | ||||
-rw-r--r-- | client/src/sass/player/playlist.scss | 35 | ||||
-rwxr-xr-x | scripts/i18n/create-custom-files.ts | 3 |
4 files changed, 71 insertions, 26 deletions
diff --git a/client/src/assets/player/playlist/playlist-menu-item.ts b/client/src/assets/player/playlist/playlist-menu-item.ts index 916c6338f..21a7f8046 100644 --- a/client/src/assets/player/playlist/playlist-menu-item.ts +++ b/client/src/assets/player/playlist/playlist-menu-item.ts | |||
@@ -26,24 +26,47 @@ class PlaylistMenuItem extends Component { | |||
26 | innerHTML: '' | 26 | innerHTML: '' |
27 | }) as HTMLElement | 27 | }) as HTMLElement |
28 | 28 | ||
29 | if (!options.element.video) { | ||
30 | li.classList.add('vjs-disabled') | ||
31 | } | ||
32 | |||
29 | const positionBlock = super.createEl('div', { | 33 | const positionBlock = super.createEl('div', { |
30 | className: 'item-position-block' | 34 | className: 'item-position-block' |
31 | }) | 35 | }) as HTMLElement |
32 | 36 | ||
33 | const position = super.createEl('div', { | 37 | const position = super.createEl('div', { |
34 | className: 'item-position', | 38 | className: 'item-position', |
35 | innerHTML: options.element.position | 39 | innerHTML: options.element.position |
36 | }) | 40 | }) |
37 | 41 | ||
42 | positionBlock.appendChild(position) | ||
43 | li.appendChild(positionBlock) | ||
44 | |||
45 | if (options.element.video) { | ||
46 | this.buildAvailableVideo(li, positionBlock, options) | ||
47 | } else { | ||
48 | this.buildUnavailableVideo(li) | ||
49 | } | ||
50 | |||
51 | return li | ||
52 | } | ||
53 | |||
54 | setSelected (selected: boolean) { | ||
55 | if (selected) this.addClass('vjs-selected') | ||
56 | else this.removeClass('vjs-selected') | ||
57 | } | ||
58 | |||
59 | getElement () { | ||
60 | return this.element | ||
61 | } | ||
62 | |||
63 | private buildAvailableVideo (li: HTMLElement, positionBlock: HTMLElement, options: PlaylistItemOptions) { | ||
38 | const player = super.createEl('div', { | 64 | const player = super.createEl('div', { |
39 | className: 'item-player' | 65 | className: 'item-player' |
40 | }) | 66 | }) |
41 | 67 | ||
42 | positionBlock.appendChild(position) | ||
43 | positionBlock.appendChild(player) | 68 | positionBlock.appendChild(player) |
44 | 69 | ||
45 | li.appendChild(positionBlock) | ||
46 | |||
47 | const thumbnail = super.createEl('img', { | 70 | const thumbnail = super.createEl('img', { |
48 | src: window.location.origin + options.element.video.thumbnailPath | 71 | src: window.location.origin + options.element.video.thumbnailPath |
49 | }) | 72 | }) |
@@ -67,17 +90,15 @@ class PlaylistMenuItem extends Component { | |||
67 | 90 | ||
68 | li.append(thumbnail) | 91 | li.append(thumbnail) |
69 | li.append(infoBlock) | 92 | li.append(infoBlock) |
70 | |||
71 | return li | ||
72 | } | 93 | } |
73 | 94 | ||
74 | setSelected (selected: boolean) { | 95 | private buildUnavailableVideo (li: HTMLElement) { |
75 | if (selected) this.addClass('vjs-selected') | 96 | const block = super.createEl('div', { |
76 | else this.removeClass('vjs-selected') | 97 | className: 'item-unavailable', |
77 | } | 98 | innerHTML: this.player().localize('Unavailable video') |
99 | }) | ||
78 | 100 | ||
79 | getElement () { | 101 | li.appendChild(block) |
80 | return this.element | ||
81 | } | 102 | } |
82 | 103 | ||
83 | private handleKeyDown (event: KeyboardEvent) { | 104 | private handleKeyDown (event: KeyboardEvent) { |
diff --git a/client/src/assets/player/playlist/playlist-menu.ts b/client/src/assets/player/playlist/playlist-menu.ts index 7d7d9e12f..37284fb44 100644 --- a/client/src/assets/player/playlist/playlist-menu.ts +++ b/client/src/assets/player/playlist/playlist-menu.ts | |||
@@ -11,8 +11,18 @@ class PlaylistMenu extends Component { | |||
11 | constructor (player: videojs.Player, options?: PlaylistPluginOptions) { | 11 | constructor (player: videojs.Player, options?: PlaylistPluginOptions) { |
12 | super(player, options as any) | 12 | super(player, options as any) |
13 | 13 | ||
14 | this.player().on('userinactive', () => { | 14 | const self = this |
15 | this.close() | 15 | |
16 | function userInactiveHandler () { | ||
17 | self.close() | ||
18 | } | ||
19 | |||
20 | this.el().addEventListener('mouseenter', () => { | ||
21 | this.player().off('userinactive', userInactiveHandler) | ||
22 | }) | ||
23 | |||
24 | this.el().addEventListener('mouseleave', () => { | ||
25 | this.player().one('userinactive', userInactiveHandler) | ||
16 | }) | 26 | }) |
17 | 27 | ||
18 | this.player().on('click', event => { | 28 | this.player().on('click', event => { |
diff --git a/client/src/sass/player/playlist.scss b/client/src/sass/player/playlist.scss index c242acba8..544d45a48 100644 --- a/client/src/sass/player/playlist.scss +++ b/client/src/sass/player/playlist.scss | |||
@@ -24,17 +24,17 @@ $playlist-menu-width: 350px; | |||
24 | justify-content: space-between; | 24 | justify-content: space-between; |
25 | 25 | ||
26 | .title { | 26 | .title { |
27 | @include ellipsis; | ||
28 | |||
27 | font-size: 14px; | 29 | font-size: 14px; |
28 | margin-bottom: 5px; | 30 | margin-bottom: 5px; |
29 | white-space: nowrap; | ||
30 | text-overflow: ellipsis; | ||
31 | } | 31 | } |
32 | 32 | ||
33 | .channel { | 33 | .channel { |
34 | @include ellipsis; | ||
35 | |||
34 | font-size: 11px; | 36 | font-size: 11px; |
35 | color: #bfbfbf; | 37 | color: #bfbfbf; |
36 | white-space: nowrap; | ||
37 | text-overflow: ellipsis; | ||
38 | } | 38 | } |
39 | 39 | ||
40 | .cross { | 40 | .cross { |
@@ -106,9 +106,13 @@ $playlist-menu-width: 350px; | |||
106 | } | 106 | } |
107 | 107 | ||
108 | .vjs-playlist-menu-item { | 108 | .vjs-playlist-menu-item { |
109 | cursor: pointer; | ||
110 | display: flex; | 109 | display: flex; |
111 | padding: 10px 0; | 110 | padding: 10px 0; |
111 | height: 60px; | ||
112 | |||
113 | &:not(.vjs-disabled) { | ||
114 | cursor: pointer; | ||
115 | } | ||
112 | 116 | ||
113 | .item-position-block { | 117 | .item-position-block { |
114 | position: relative; | 118 | position: relative; |
@@ -116,6 +120,14 @@ $playlist-menu-width: 350px; | |||
116 | align-items: center; | 120 | align-items: center; |
117 | justify-content: center; | 121 | justify-content: center; |
118 | width: 30px; | 122 | width: 30px; |
123 | flex-shrink: 0; | ||
124 | } | ||
125 | |||
126 | .item-unavailable { | ||
127 | position: relative; | ||
128 | display: flex; | ||
129 | align-items: center; | ||
130 | justify-content: center; | ||
119 | } | 131 | } |
120 | 132 | ||
121 | .item-player { | 133 | .item-player { |
@@ -136,7 +148,7 @@ $playlist-menu-width: 350px; | |||
136 | } | 148 | } |
137 | } | 149 | } |
138 | 150 | ||
139 | &:hover { | 151 | &:hover:not(.vjs-disabled) { |
140 | background-color: rgba(150, 150, 150, 0.2); | 152 | background-color: rgba(150, 150, 150, 0.2); |
141 | } | 153 | } |
142 | 154 | ||
@@ -146,20 +158,21 @@ $playlist-menu-width: 350px; | |||
146 | } | 158 | } |
147 | 159 | ||
148 | .info-block { | 160 | .info-block { |
149 | margin-left: 10px; | 161 | margin: 0 10px; |
162 | min-width: 1px; | ||
150 | 163 | ||
151 | .title { | 164 | .title { |
165 | @include ellipsis; | ||
166 | |||
152 | font-size: 13px; | 167 | font-size: 13px; |
153 | margin-bottom: 5px; | 168 | margin-bottom: 5px; |
154 | white-space: nowrap; | ||
155 | text-overflow: ellipsis; | ||
156 | } | 169 | } |
157 | 170 | ||
158 | .channel { | 171 | .channel { |
172 | @include ellipsis; | ||
173 | |||
159 | font-size: 11px; | 174 | font-size: 11px; |
160 | color: #bfbfbf; | 175 | color: #bfbfbf; |
161 | white-space: nowrap; | ||
162 | text-overflow: ellipsis; | ||
163 | } | 176 | } |
164 | } | 177 | } |
165 | } | 178 | } |
diff --git a/scripts/i18n/create-custom-files.ts b/scripts/i18n/create-custom-files.ts index 89a967b14..78a51d1e6 100755 --- a/scripts/i18n/create-custom-files.ts +++ b/scripts/i18n/create-custom-files.ts | |||
@@ -52,7 +52,8 @@ values(VIDEO_CATEGORIES) | |||
52 | 'This playlist does not exist', | 52 | 'This playlist does not exist', |
53 | 'We cannot fetch the playlist. Please try again later.', | 53 | 'We cannot fetch the playlist. Please try again later.', |
54 | 'Playlist: {1}', | 54 | 'Playlist: {1}', |
55 | 'By {1}' | 55 | 'By {1}', |
56 | 'Unavailable video' | ||
56 | ]) | 57 | ]) |
57 | .forEach(v => { serverKeys[v] = v }) | 58 | .forEach(v => { serverKeys[v] = v }) |
58 | 59 | ||