diff options
author | Rigel Kent <sendmemail@rigelk.eu> | 2019-12-20 17:49:57 +0100 |
---|---|---|
committer | Rigel Kent <sendmemail@rigelk.eu> | 2019-12-20 17:49:57 +0100 |
commit | 223b24e618146f85b20b5bf365bc18d14a5964cd (patch) | |
tree | 236fde34d190fa5d0d9a44c6760c0161594dd872 /client/src/app | |
parent | 1dc240a9488c66ad38205d08fcfdb32d35efceaa (diff) | |
download | PeerTube-223b24e618146f85b20b5bf365bc18d14a5964cd.tar.gz PeerTube-223b24e618146f85b20b5bf365bc18d14a5964cd.tar.zst PeerTube-223b24e618146f85b20b5bf365bc18d14a5964cd.zip |
Fix upnext, refactor avatar menu, add to playlist overflow
Diffstat (limited to 'client/src/app')
11 files changed, 73 insertions, 26 deletions
diff --git a/client/src/app/+accounts/accounts.component.html b/client/src/app/+accounts/accounts.component.html index 6269091df..70257162d 100644 --- a/client/src/app/+accounts/accounts.component.html +++ b/client/src/app/+accounts/accounts.component.html | |||
@@ -23,7 +23,7 @@ | |||
23 | <span *ngIf="account.mutedServerByInstance" class="badge badge-danger" i18n>Instance muted by your instance</span> | 23 | <span *ngIf="account.mutedServerByInstance" class="badge badge-danger" i18n>Instance muted by your instance</span> |
24 | 24 | ||
25 | <my-user-moderation-dropdown | 25 | <my-user-moderation-dropdown |
26 | buttonSize="small" [account]="account" [user]="user" | 26 | buttonSize="small" [account]="account" [user]="user" placement="bottom-right auto" |
27 | (userChanged)="onUserChanged()" (userDeleted)="onUserDeleted()" | 27 | (userChanged)="onUserChanged()" (userDeleted)="onUserDeleted()" |
28 | > | 28 | > |
29 | </my-user-moderation-dropdown> | 29 | </my-user-moderation-dropdown> |
diff --git a/client/src/app/menu/avatar-notification.component.html b/client/src/app/menu/avatar-notification.component.html index 1b6e6dcf8..8ffec46da 100644 --- a/client/src/app/menu/avatar-notification.component.html +++ b/client/src/app/menu/avatar-notification.component.html | |||
@@ -25,7 +25,7 @@ | |||
25 | </div> | 25 | </div> |
26 | </div> | 26 | </div> |
27 | 27 | ||
28 | <div *ngIf="!loaded" class="loader"> | 28 | <div *ngIf="!loaded" class="loader mt-4"> |
29 | <my-loader [loading]="!loaded"></my-loader> | 29 | <my-loader [loading]="!loaded"></my-loader> |
30 | </div> | 30 | </div> |
31 | 31 | ||
diff --git a/client/src/app/menu/avatar-notification.component.scss b/client/src/app/menu/avatar-notification.component.scss index 713ac7cb9..2ca7f24dc 100644 --- a/client/src/app/menu/avatar-notification.component.scss +++ b/client/src/app/menu/avatar-notification.component.scss | |||
@@ -45,7 +45,7 @@ | |||
45 | align-items: center; | 45 | align-items: center; |
46 | padding: 0 10px; | 46 | padding: 0 10px; |
47 | font-size: 16px; | 47 | font-size: 16px; |
48 | height: 50px; | 48 | min-height: 50px; |
49 | 49 | ||
50 | a { | 50 | a { |
51 | @include disable-default-a-behaviour; | 51 | @include disable-default-a-behaviour; |
diff --git a/client/src/app/menu/menu.component.html b/client/src/app/menu/menu.component.html index 3f406586e..848f9949f 100644 --- a/client/src/app/menu/menu.component.html +++ b/client/src/app/menu/menu.component.html | |||
@@ -5,8 +5,10 @@ | |||
5 | <my-avatar-notification [user]="user"></my-avatar-notification> | 5 | <my-avatar-notification [user]="user"></my-avatar-notification> |
6 | 6 | ||
7 | <div class="logged-in-info"> | 7 | <div class="logged-in-info"> |
8 | <a routerLink="/my-account/settings" class="logged-in-display-name">{{ user.account?.displayName }}</a> | 8 | <a *ngIf="user.account" [routerLink]="[ '/accounts', user.account.nameWithHost ]" class="logged-in-display-name">{{ user.account?.displayName }}</a> |
9 | <div class="logged-in-username">{{ user.username }}</div> | 9 | <a *ngIf="!user.account" routerLink="/my-account/settings" class="logged-in-display-name">{{ user.account?.displayName }}</a> |
10 | |||
11 | <div ngxClipboard [cbContent]="user.account?.nameWithHost" class="logged-in-username">{{ user.username }}</div> | ||
10 | </div> | 12 | </div> |
11 | 13 | ||
12 | <div class="logged-in-more" ngbDropdown placement="bottom-right auto"> | 14 | <div class="logged-in-more" ngbDropdown placement="bottom-right auto"> |
@@ -14,13 +16,21 @@ | |||
14 | 16 | ||
15 | <div ngbDropdownMenu> | 17 | <div ngbDropdownMenu> |
16 | <a *ngIf="user.account" [routerLink]="[ '/accounts', user.account.nameWithHost ]" class="dropdown-item"> | 18 | <a *ngIf="user.account" [routerLink]="[ '/accounts', user.account.nameWithHost ]" class="dropdown-item"> |
17 | <my-global-icon iconName="go"></my-global-icon> <ng-container i18n>My public profile</ng-container> | 19 | <my-global-icon iconName="go"></my-global-icon> <ng-container i18n>Public profile</ng-container> |
18 | </a> | 20 | </a> |
19 | 21 | ||
22 | <div class="dropdown-divider"></div> | ||
23 | |||
20 | <a routerLink="/my-account" class="dropdown-item"> | 24 | <a routerLink="/my-account" class="dropdown-item"> |
21 | <my-global-icon iconName="user"></my-global-icon> <ng-container i18n>My account</ng-container> | 25 | <my-global-icon iconName="user"></my-global-icon> <ng-container i18n>Account settings</ng-container> |
22 | </a> | 26 | </a> |
23 | 27 | ||
28 | <a routerLink="/my-account/video-channels" class="dropdown-item"> | ||
29 | <my-global-icon iconName="folder"></my-global-icon> <ng-container i18n>Channels settings</ng-container> | ||
30 | </a> | ||
31 | |||
32 | <div class="dropdown-divider"></div> | ||
33 | |||
24 | <a (click)="logout($event)" class="dropdown-item" href="#"> | 34 | <a (click)="logout($event)" class="dropdown-item" href="#"> |
25 | <my-global-icon iconName="sign-out"></my-global-icon> <ng-container i18n>Log out</ng-container> | 35 | <my-global-icon iconName="sign-out"></my-global-icon> <ng-container i18n>Log out</ng-container> |
26 | </a> | 36 | </a> |
diff --git a/client/src/app/menu/menu.component.scss b/client/src/app/menu/menu.component.scss index 79a28d258..2963d4d19 100644 --- a/client/src/app/menu/menu.component.scss +++ b/client/src/app/menu/menu.component.scss | |||
@@ -69,6 +69,7 @@ menu { | |||
69 | font-size: 13px; | 69 | font-size: 13px; |
70 | color: #C6C6C6; | 70 | color: #C6C6C6; |
71 | max-width: 140px; | 71 | max-width: 140px; |
72 | cursor: pointer; | ||
72 | } | 73 | } |
73 | } | 74 | } |
74 | 75 | ||
diff --git a/client/src/app/shared/misc/utils.ts b/client/src/app/shared/misc/utils.ts index f26240d21..b1d1fc0b5 100644 --- a/client/src/app/shared/misc/utils.ts +++ b/client/src/app/shared/misc/utils.ts | |||
@@ -169,6 +169,26 @@ function importModule (path: string) { | |||
169 | }) | 169 | }) |
170 | } | 170 | } |
171 | 171 | ||
172 | function isInViewport (el: HTMLElement) { | ||
173 | const bounding = el.getBoundingClientRect() | ||
174 | return ( | ||
175 | bounding.top >= 0 && | ||
176 | bounding.left >= 0 && | ||
177 | bounding.bottom <= (window.innerHeight || document.documentElement.clientHeight) && | ||
178 | bounding.right <= (window.innerWidth || document.documentElement.clientWidth) | ||
179 | ) | ||
180 | } | ||
181 | |||
182 | function isXPercentInViewport (el: HTMLElement, percentVisible: number) { | ||
183 | const rect = el.getBoundingClientRect() | ||
184 | const windowHeight = (window.innerHeight || document.documentElement.clientHeight) | ||
185 | |||
186 | return !( | ||
187 | Math.floor(100 - (((rect.top >= 0 ? 0 : rect.top) / +-(rect.height / 1)) * 100)) < percentVisible || | ||
188 | Math.floor(100 - ((rect.bottom - windowHeight) / rect.height) * 100) < percentVisible | ||
189 | ) | ||
190 | } | ||
191 | |||
172 | export { | 192 | export { |
173 | sortBy, | 193 | sortBy, |
174 | durationToString, | 194 | durationToString, |
@@ -183,5 +203,7 @@ export { | |||
183 | objectLineFeedToHtml, | 203 | objectLineFeedToHtml, |
184 | removeElementFromArray, | 204 | removeElementFromArray, |
185 | importModule, | 205 | importModule, |
186 | scrollToTop | 206 | scrollToTop, |
207 | isInViewport, | ||
208 | isXPercentInViewport | ||
187 | } | 209 | } |
diff --git a/client/src/app/shared/video-playlist/video-add-to-playlist.component.html b/client/src/app/shared/video-playlist/video-add-to-playlist.component.html index 648d580fa..0cc8af345 100644 --- a/client/src/app/shared/video-playlist/video-add-to-playlist.component.html +++ b/client/src/app/shared/video-playlist/video-add-to-playlist.component.html | |||
@@ -41,14 +41,16 @@ | |||
41 | </div> | 41 | </div> |
42 | </div> | 42 | </div> |
43 | 43 | ||
44 | <div class="playlist dropdown-item" *ngFor="let playlist of videoPlaylists" (click)="togglePlaylist($event, playlist)"> | 44 | <div class="playlists"> |
45 | <my-peertube-checkbox [inputName]="'in-playlist-' + playlist.id" [(ngModel)]="playlist.inPlaylist" [onPushWorkaround]="true"></my-peertube-checkbox> | 45 | <div class="playlist dropdown-item" *ngFor="let playlist of videoPlaylists" (click)="togglePlaylist($event, playlist)"> |
46 | <my-peertube-checkbox [inputName]="'in-playlist-' + playlist.id" [(ngModel)]="playlist.inPlaylist" [onPushWorkaround]="true"></my-peertube-checkbox> | ||
46 | 47 | ||
47 | <div class="display-name"> | 48 | <div class="display-name"> |
48 | {{ playlist.displayName }} | 49 | {{ playlist.displayName }} |
49 | 50 | ||
50 | <div *ngIf="playlist.inPlaylist && (playlist.startTimestamp || playlist.stopTimestamp)" class="timestamp-info"> | 51 | <div *ngIf="playlist.inPlaylist && (playlist.startTimestamp || playlist.stopTimestamp)" class="timestamp-info"> |
51 | {{ formatTimestamp(playlist) }} | 52 | {{ formatTimestamp(playlist) }} |
53 | </div> | ||
52 | </div> | 54 | </div> |
53 | </div> | 55 | </div> |
54 | </div> | 56 | </div> |
diff --git a/client/src/app/shared/video-playlist/video-add-to-playlist.component.scss b/client/src/app/shared/video-playlist/video-add-to-playlist.component.scss index c677fea6c..090b530cf 100644 --- a/client/src/app/shared/video-playlist/video-add-to-playlist.component.scss +++ b/client/src/app/shared/video-playlist/video-add-to-playlist.component.scss | |||
@@ -1,11 +1,6 @@ | |||
1 | @import '_variables'; | 1 | @import '_variables'; |
2 | @import '_mixins'; | 2 | @import '_mixins'; |
3 | 3 | ||
4 | .root { | ||
5 | max-height: 300px; | ||
6 | overflow-y: auto; | ||
7 | } | ||
8 | |||
9 | .header { | 4 | .header { |
10 | min-width: 240px; | 5 | min-width: 240px; |
11 | padding: 6px 24px 10px 24px; | 6 | padding: 6px 24px 10px 24px; |
@@ -53,6 +48,11 @@ | |||
53 | padding: 6px 24px; | 48 | padding: 6px 24px; |
54 | } | 49 | } |
55 | 50 | ||
51 | .playlists { | ||
52 | max-height: 180px; | ||
53 | overflow-y: auto; | ||
54 | } | ||
55 | |||
56 | .playlist { | 56 | .playlist { |
57 | display: flex; | 57 | display: flex; |
58 | cursor: pointer; | 58 | cursor: pointer; |
diff --git a/client/src/app/videos/+video-watch/video-watch.component.html b/client/src/app/videos/+video-watch/video-watch.component.html index 7a9f00a50..9e69033e1 100644 --- a/client/src/app/videos/+video-watch/video-watch.component.html +++ b/client/src/app/videos/+video-watch/video-watch.component.html | |||
@@ -114,9 +114,9 @@ | |||
114 | ></my-video-actions-dropdown> | 114 | ></my-video-actions-dropdown> |
115 | </div> | 115 | </div> |
116 | 116 | ||
117 | <div class="video-info-likes-dislikes-bar-outerContainer"> | 117 | <div class="video-info-likes-dislikes-bar-outer-container"> |
118 | <div | 118 | <div |
119 | class="video-info-likes-dislikes-bar-innerContainer" | 119 | class="video-info-likes-dislikes-bar-inner-container" |
120 | *ngIf="video.likes !== 0 || video.dislikes !== 0" | 120 | *ngIf="video.likes !== 0 || video.dislikes !== 0" |
121 | [ngbTooltip]="likesBarTooltipText" | 121 | [ngbTooltip]="likesBarTooltipText" |
122 | placement="bottom" | 122 | placement="bottom" |
diff --git a/client/src/app/videos/+video-watch/video-watch.component.scss b/client/src/app/videos/+video-watch/video-watch.component.scss index 180b7c6ad..f9ff83c34 100644 --- a/client/src/app/videos/+video-watch/video-watch.component.scss +++ b/client/src/app/videos/+video-watch/video-watch.component.scss | |||
@@ -297,13 +297,13 @@ $video-info-margin-left: 44px; | |||
297 | } | 297 | } |
298 | } | 298 | } |
299 | 299 | ||
300 | .video-info-likes-dislikes-bar-outerContainer { | 300 | .video-info-likes-dislikes-bar-outer-container { |
301 | position: relative; | 301 | position: relative; |
302 | } | 302 | } |
303 | 303 | ||
304 | .video-info-likes-dislikes-bar-innerContainer { | 304 | .video-info-likes-dislikes-bar-inner-container { |
305 | position: absolute; | 305 | position: absolute; |
306 | height: 30px; | 306 | height: 20px; |
307 | } | 307 | } |
308 | 308 | ||
309 | .video-info-likes-dislikes-bar { | 309 | .video-info-likes-dislikes-bar { |
diff --git a/client/src/app/videos/+video-watch/video-watch.component.ts b/client/src/app/videos/+video-watch/video-watch.component.ts index bad0144bf..dcceb1400 100644 --- a/client/src/app/videos/+video-watch/video-watch.component.ts +++ b/client/src/app/videos/+video-watch/video-watch.component.ts | |||
@@ -37,7 +37,7 @@ import { PluginService } from '@app/core/plugins/plugin.service' | |||
37 | import { HooksService } from '@app/core/plugins/hooks.service' | 37 | import { HooksService } from '@app/core/plugins/hooks.service' |
38 | import { PlatformLocation } from '@angular/common' | 38 | import { PlatformLocation } from '@angular/common' |
39 | import { RecommendedVideosComponent } from '../recommendations/recommended-videos.component' | 39 | import { RecommendedVideosComponent } from '../recommendations/recommended-videos.component' |
40 | import { scrollToTop } from '@app/shared/misc/utils' | 40 | import { scrollToTop, isInViewport, isXPercentInViewport } from '@app/shared/misc/utils' |
41 | 41 | ||
42 | @Component({ | 42 | @Component({ |
43 | selector: 'my-video-watch', | 43 | selector: 'my-video-watch', |
@@ -478,12 +478,18 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
478 | 478 | ||
479 | /** | 479 | /** |
480 | * replaces this.player.one('ended') | 480 | * replaces this.player.one('ended') |
481 | * define 'condition(next)' to return true to wait, false to stop | 481 | * 'condition()': true to make the upnext functionality trigger, |
482 | * false to disable the upnext functionality | ||
483 | * go to the next video in 'condition()' if you don't want of the timer. | ||
484 | * 'next': function triggered at the end of the timer. | ||
485 | * 'suspended': function used at each clic of the timer checking if we need | ||
486 | * to reset progress and wait until 'suspended' becomes truthy again. | ||
482 | */ | 487 | */ |
483 | this.player.upnext({ | 488 | this.player.upnext({ |
484 | timeout: 10000, // 10s | 489 | timeout: 10000, // 10s |
485 | headText: this.i18n('Up Next'), | 490 | headText: this.i18n('Up Next'), |
486 | cancelText: this.i18n('Cancel'), | 491 | cancelText: this.i18n('Cancel'), |
492 | suspendedText: this.i18n('Autoplay is suspended'), | ||
487 | getTitle: () => this.nextVideoTitle, | 493 | getTitle: () => this.nextVideoTitle, |
488 | next: () => this.zone.run(() => this.autoplayNext()), | 494 | next: () => this.zone.run(() => this.autoplayNext()), |
489 | condition: () => { | 495 | condition: () => { |
@@ -496,6 +502,12 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
496 | return true // upnext will trigger | 502 | return true // upnext will trigger |
497 | } | 503 | } |
498 | return false // upnext will not trigger, and instead leave the video stopping | 504 | return false // upnext will not trigger, and instead leave the video stopping |
505 | }, | ||
506 | suspended: () => { | ||
507 | return ( | ||
508 | !isXPercentInViewport(this.player.el(), 80) || | ||
509 | !document.getElementById('content').contains(document.activeElement) | ||
510 | ) | ||
499 | } | 511 | } |
500 | }) | 512 | }) |
501 | 513 | ||