diff options
author | Chocobozzz <me@florianbigard.com> | 2021-06-29 17:57:59 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2021-06-29 18:01:02 +0200 |
commit | 06a555797929d4867264b096c8420cdedd50f496 (patch) | |
tree | e68b0038d3f3f8ccae43b3bd22509200888a699a /client/src/app/+videos/+video-watch/shared | |
parent | 6ebdd12f8806edd7076e89c8ea3bcfaf5658b2b6 (diff) | |
download | PeerTube-06a555797929d4867264b096c8420cdedd50f496.tar.gz PeerTube-06a555797929d4867264b096c8420cdedd50f496.tar.zst PeerTube-06a555797929d4867264b096c8420cdedd50f496.zip |
Move watch action buttons in a dedicated component
Diffstat (limited to 'client/src/app/+videos/+video-watch/shared')
10 files changed, 283 insertions, 5 deletions
diff --git a/client/src/app/+videos/+video-watch/shared/action-buttons/action-buttons.component.html b/client/src/app/+videos/+video-watch/shared/action-buttons/action-buttons.component.html new file mode 100644 index 000000000..8fb244cc4 --- /dev/null +++ b/client/src/app/+videos/+video-watch/shared/action-buttons/action-buttons.component.html | |||
@@ -0,0 +1,85 @@ | |||
1 | <div class="video-actions-rates"> | ||
2 | <div class="video-actions full-width justify-content-end"> | ||
3 | <my-video-rate | ||
4 | [video]="video" [isUserLoggedIn]="isUserLoggedIn" | ||
5 | (rateUpdated)="onRateUpdated($event)" (userRatingLoaded)="onRateUpdated($event)" | ||
6 | ></my-video-rate> | ||
7 | |||
8 | <button *ngIf="video.support" (click)="showSupportModal()" (keyup.enter)="showSupportModal()" class="action-button action-button-support" [attr.aria-label]="tooltipSupport" | ||
9 | [ngbTooltip]="tooltipSupport" | ||
10 | placement="bottom auto" | ||
11 | > | ||
12 | <my-global-icon iconName="support" aria-hidden="true"></my-global-icon> | ||
13 | <span class="icon-text" i18n>SUPPORT</span> | ||
14 | </button> | ||
15 | |||
16 | <button (click)="showShareModal()" (keyup.enter)="showShareModal()" class="action-button"> | ||
17 | <my-global-icon iconName="share" aria-hidden="true"></my-global-icon> | ||
18 | <span class="icon-text" i18n>SHARE</span> | ||
19 | </button> | ||
20 | |||
21 | <div | ||
22 | class="action-dropdown" ngbDropdown placement="top" role="button" autoClose="outside" | ||
23 | *ngIf="isUserLoggedIn" (openChange)="addContent.openChange($event)" | ||
24 | [ngbTooltip]="tooltipSaveToPlaylist" | ||
25 | placement="bottom auto" | ||
26 | > | ||
27 | <button class="action-button action-button-save" ngbDropdownToggle> | ||
28 | <my-global-icon iconName="playlist-add" aria-hidden="true"></my-global-icon> | ||
29 | <span class="icon-text" i18n>SAVE</span> | ||
30 | </button> | ||
31 | |||
32 | <div ngbDropdownMenu> | ||
33 | <my-video-add-to-playlist #addContent [video]="video"></my-video-add-to-playlist> | ||
34 | </div> | ||
35 | </div> | ||
36 | |||
37 | <ng-container *ngIf="!isUserLoggedIn && !video.isLive"> | ||
38 | <button | ||
39 | *ngIf="isVideoDownloadable()" class="action-button action-button-save" | ||
40 | (click)="showDownloadModal()" (keydown.enter)="showDownloadModal()" | ||
41 | > | ||
42 | <my-global-icon iconName="download" aria-hidden="true"></my-global-icon> | ||
43 | <span class="icon-text d-none d-sm-inline" i18n>DOWNLOAD</span> | ||
44 | </button> | ||
45 | |||
46 | <my-video-download #videoDownloadModal></my-video-download> | ||
47 | </ng-container> | ||
48 | |||
49 | <ng-container *ngIf="isUserLoggedIn"> | ||
50 | <my-video-actions-dropdown | ||
51 | placement="bottom auto" buttonDirection="horizontal" [buttonStyled]="true" [video]="video" [videoCaptions]="videoCaptions" | ||
52 | [displayOptions]="videoActionsOptions" (videoRemoved)="onVideoRemoved()" | ||
53 | ></my-video-actions-dropdown> | ||
54 | </ng-container> | ||
55 | </div> | ||
56 | |||
57 | <div class="likes-dislikes-bar-outer-container"> | ||
58 | <div | ||
59 | class="likes-dislikes-bar-inner-container" | ||
60 | *ngIf="video.likes !== 0 || video.dislikes !== 0" | ||
61 | [ngbTooltip]="likesBarTooltipText" | ||
62 | placement="bottom" | ||
63 | > | ||
64 | <div | ||
65 | class="likes-dislikes-bar" | ||
66 | > | ||
67 | <div class="likes-bar" [ngClass]="{ 'liked': userRating !== 'none' }" [ngStyle]="{ 'width.%': video.likesPercent }"></div> | ||
68 | </div> | ||
69 | </div> | ||
70 | </div> | ||
71 | </div> | ||
72 | |||
73 | <div | ||
74 | class="likes-dislikes-bar" | ||
75 | *ngIf="video.likes !== 0 || video.dislikes !== 0" | ||
76 | [ngbTooltip]="likesBarTooltipText" | ||
77 | placement="bottom" | ||
78 | > | ||
79 | <div class="likes-bar" [ngStyle]="{ 'width.%': video.likesPercent }"></div> | ||
80 | </div> | ||
81 | |||
82 | <ng-container *ngIf="video"> | ||
83 | <my-support-modal #supportModal [video]="video"></my-support-modal> | ||
84 | <my-video-share #videoShareModal [video]="video" [videoCaptions]="videoCaptions" [playlist]="playlist"></my-video-share> | ||
85 | </ng-container> | ||
diff --git a/client/src/app/+videos/+video-watch/shared/action-buttons/action-buttons.component.scss b/client/src/app/+videos/+video-watch/shared/action-buttons/action-buttons.component.scss new file mode 100644 index 000000000..967d515e6 --- /dev/null +++ b/client/src/app/+videos/+video-watch/shared/action-buttons/action-buttons.component.scss | |||
@@ -0,0 +1,99 @@ | |||
1 | @use '_variables' as *; | ||
2 | @use '_mixins' as *; | ||
3 | |||
4 | .video-actions { | ||
5 | height: 40px; // Align with the title | ||
6 | display: flex; | ||
7 | align-items: center; | ||
8 | |||
9 | .action-button:not(:first-child), | ||
10 | .action-dropdown, | ||
11 | my-video-actions-dropdown { | ||
12 | @include margin-left(5px); | ||
13 | } | ||
14 | |||
15 | ::ng-deep.action-button { | ||
16 | @include peertube-button; | ||
17 | @include button-with-icon(21px, 0, -1px); | ||
18 | |||
19 | font-size: 100%; | ||
20 | font-weight: $font-semibold; | ||
21 | display: inline-block; | ||
22 | padding: 0 10px; | ||
23 | white-space: nowrap; | ||
24 | background-color: transparent !important; | ||
25 | color: pvar(--actionButtonColor); | ||
26 | text-transform: uppercase; | ||
27 | |||
28 | &::after { | ||
29 | display: none; | ||
30 | } | ||
31 | |||
32 | &:hover { | ||
33 | opacity: 0.9; | ||
34 | } | ||
35 | |||
36 | &.action-button-support { | ||
37 | color: pvar(--supportButtonColor); | ||
38 | |||
39 | my-global-icon { | ||
40 | @include apply-svg-color(pvar(--supportButtonColor)); | ||
41 | } | ||
42 | } | ||
43 | |||
44 | &.action-button-support { | ||
45 | my-global-icon { | ||
46 | ::ng-deep path:first-child { | ||
47 | fill: pvar(--supportButtonHeartColor) !important; | ||
48 | } | ||
49 | } | ||
50 | } | ||
51 | |||
52 | &.action-button-save { | ||
53 | my-global-icon { | ||
54 | top: 0 !important; | ||
55 | right: -1px; | ||
56 | } | ||
57 | } | ||
58 | |||
59 | .icon-text { | ||
60 | @include margin-left(3px); | ||
61 | } | ||
62 | } | ||
63 | } | ||
64 | |||
65 | .likes-dislikes-bar-outer-container { | ||
66 | position: relative; | ||
67 | } | ||
68 | |||
69 | .likes-dislikes-bar-inner-container { | ||
70 | position: absolute; | ||
71 | height: 20px; | ||
72 | } | ||
73 | |||
74 | .likes-dislikes-bar { | ||
75 | $likes-bar-height: 2px; | ||
76 | |||
77 | height: $likes-bar-height; | ||
78 | margin-top: -$likes-bar-height; | ||
79 | |||
80 | width: 120px; | ||
81 | background-color: #ccc; | ||
82 | position: relative; | ||
83 | top: 10px; | ||
84 | |||
85 | .likes-bar { | ||
86 | height: 100%; | ||
87 | background-color: #909090; | ||
88 | |||
89 | &.liked { | ||
90 | background-color: pvar(--activatedActionButtonColor); | ||
91 | } | ||
92 | } | ||
93 | } | ||
94 | |||
95 | @media screen and (max-width: 450px) { | ||
96 | .action-button .icon-text { | ||
97 | display: none !important; | ||
98 | } | ||
99 | } | ||
diff --git a/client/src/app/+videos/+video-watch/shared/action-buttons/action-buttons.component.ts b/client/src/app/+videos/+video-watch/shared/action-buttons/action-buttons.component.ts new file mode 100644 index 000000000..e59238ffe --- /dev/null +++ b/client/src/app/+videos/+video-watch/shared/action-buttons/action-buttons.component.ts | |||
@@ -0,0 +1,93 @@ | |||
1 | import { Component, Input, OnChanges, OnInit, ViewChild } from '@angular/core' | ||
2 | import { RedirectService, ScreenService } from '@app/core' | ||
3 | import { VideoDetails } from '@app/shared/shared-main' | ||
4 | import { VideoShareComponent } from '@app/shared/shared-share-modal' | ||
5 | import { SupportModalComponent } from '@app/shared/shared-support-modal' | ||
6 | import { VideoActionsDisplayType, VideoDownloadComponent } from '@app/shared/shared-video-miniature' | ||
7 | import { VideoPlaylist } from '@app/shared/shared-video-playlist' | ||
8 | import { UserVideoRateType, VideoCaption } from '@shared/models/videos' | ||
9 | |||
10 | @Component({ | ||
11 | selector: 'my-action-buttons', | ||
12 | templateUrl: './action-buttons.component.html', | ||
13 | styleUrls: [ './action-buttons.component.scss' ] | ||
14 | }) | ||
15 | export class ActionButtonsComponent implements OnInit, OnChanges { | ||
16 | @ViewChild('videoShareModal') videoShareModal: VideoShareComponent | ||
17 | @ViewChild('supportModal') supportModal: SupportModalComponent | ||
18 | @ViewChild('videoDownloadModal') videoDownloadModal: VideoDownloadComponent | ||
19 | |||
20 | @Input() video: VideoDetails | ||
21 | @Input() videoCaptions: VideoCaption[] | ||
22 | @Input() playlist: VideoPlaylist | ||
23 | |||
24 | @Input() isUserLoggedIn: boolean | ||
25 | |||
26 | @Input() currentTime: number | ||
27 | @Input() currentPlaylistPosition: number | ||
28 | |||
29 | likesBarTooltipText = '' | ||
30 | |||
31 | tooltipSupport = '' | ||
32 | tooltipSaveToPlaylist = '' | ||
33 | |||
34 | videoActionsOptions: VideoActionsDisplayType = { | ||
35 | playlist: false, | ||
36 | download: true, | ||
37 | update: true, | ||
38 | blacklist: true, | ||
39 | delete: true, | ||
40 | report: true, | ||
41 | duplicate: true, | ||
42 | mute: true, | ||
43 | liveInfo: true | ||
44 | } | ||
45 | |||
46 | userRating: UserVideoRateType | ||
47 | |||
48 | constructor ( | ||
49 | private screenService: ScreenService, | ||
50 | private redirectService: RedirectService | ||
51 | ) { } | ||
52 | |||
53 | ngOnInit () { | ||
54 | // Hide the tooltips for unlogged users in mobile view, this adds confusion with the popover | ||
55 | if (this.isUserLoggedIn || !this.screenService.isInMobileView()) { | ||
56 | this.tooltipSupport = $localize`Support options for this video` | ||
57 | this.tooltipSaveToPlaylist = $localize`Save to playlist` | ||
58 | } | ||
59 | } | ||
60 | |||
61 | ngOnChanges () { | ||
62 | this.setVideoLikesBarTooltipText() | ||
63 | } | ||
64 | |||
65 | showDownloadModal () { | ||
66 | this.videoDownloadModal.show(this.video, this.videoCaptions) | ||
67 | } | ||
68 | |||
69 | isVideoDownloadable () { | ||
70 | return this.video && this.video instanceof VideoDetails && this.video.downloadEnabled && !this.video.isLive | ||
71 | } | ||
72 | |||
73 | showSupportModal () { | ||
74 | this.supportModal.show() | ||
75 | } | ||
76 | |||
77 | showShareModal () { | ||
78 | this.videoShareModal.show(this.currentTime, this.currentPlaylistPosition) | ||
79 | } | ||
80 | |||
81 | onRateUpdated (userRating: UserVideoRateType) { | ||
82 | this.userRating = userRating | ||
83 | this.setVideoLikesBarTooltipText() | ||
84 | } | ||
85 | |||
86 | onVideoRemoved () { | ||
87 | this.redirectService.redirectToHomepage() | ||
88 | } | ||
89 | |||
90 | private setVideoLikesBarTooltipText () { | ||
91 | this.likesBarTooltipText = `${this.video.likes} likes / ${this.video.dislikes} dislikes` | ||
92 | } | ||
93 | } | ||
diff --git a/client/src/app/+videos/+video-watch/shared/action-buttons/index.ts b/client/src/app/+videos/+video-watch/shared/action-buttons/index.ts new file mode 100644 index 000000000..3844dd12e --- /dev/null +++ b/client/src/app/+videos/+video-watch/shared/action-buttons/index.ts | |||
@@ -0,0 +1,2 @@ | |||
1 | export * from './action-buttons.component' | ||
2 | export * from './video-rate.component' | ||
diff --git a/client/src/app/+videos/+video-watch/shared/metadata/video-rate.component.html b/client/src/app/+videos/+video-watch/shared/action-buttons/video-rate.component.html index 7dd9b3678..7dd9b3678 100644 --- a/client/src/app/+videos/+video-watch/shared/metadata/video-rate.component.html +++ b/client/src/app/+videos/+video-watch/shared/action-buttons/video-rate.component.html | |||
diff --git a/client/src/app/+videos/+video-watch/shared/metadata/video-rate.component.scss b/client/src/app/+videos/+video-watch/shared/action-buttons/video-rate.component.scss index f4f696f33..f4f696f33 100644 --- a/client/src/app/+videos/+video-watch/shared/metadata/video-rate.component.scss +++ b/client/src/app/+videos/+video-watch/shared/action-buttons/video-rate.component.scss | |||
diff --git a/client/src/app/+videos/+video-watch/shared/metadata/video-rate.component.ts b/client/src/app/+videos/+video-watch/shared/action-buttons/video-rate.component.ts index 89a666a62..ecb5a9281 100644 --- a/client/src/app/+videos/+video-watch/shared/metadata/video-rate.component.ts +++ b/client/src/app/+videos/+video-watch/shared/action-buttons/video-rate.component.ts | |||
@@ -31,7 +31,7 @@ export class VideoRateComponent implements OnInit, OnChanges, OnDestroy { | |||
31 | private screenService: ScreenService | 31 | private screenService: ScreenService |
32 | ) { } | 32 | ) { } |
33 | 33 | ||
34 | async ngOnInit () { | 34 | ngOnInit () { |
35 | // Hide the tooltips for unlogged users in mobile view, this adds confusion with the popover | 35 | // Hide the tooltips for unlogged users in mobile view, this adds confusion with the popover |
36 | if (this.isUserLoggedIn || !this.screenService.isInMobileView()) { | 36 | if (this.isUserLoggedIn || !this.screenService.isInMobileView()) { |
37 | this.tooltipLike = $localize`Like this video` | 37 | this.tooltipLike = $localize`Like this video` |
diff --git a/client/src/app/+videos/+video-watch/shared/index.ts b/client/src/app/+videos/+video-watch/shared/index.ts index 6c5ff7e9b..069f862e2 100644 --- a/client/src/app/+videos/+video-watch/shared/index.ts +++ b/client/src/app/+videos/+video-watch/shared/index.ts | |||
@@ -1,3 +1,4 @@ | |||
1 | export * from './action-buttons' | ||
1 | export * from './comment' | 2 | export * from './comment' |
2 | export * from './information' | 3 | export * from './information' |
3 | export * from './metadata' | 4 | export * from './metadata' |
diff --git a/client/src/app/+videos/+video-watch/shared/metadata/index.ts b/client/src/app/+videos/+video-watch/shared/metadata/index.ts index ba97f7011..7f7ee797b 100644 --- a/client/src/app/+videos/+video-watch/shared/metadata/index.ts +++ b/client/src/app/+videos/+video-watch/shared/metadata/index.ts | |||
@@ -1,3 +1,2 @@ | |||
1 | export * from './video-avatar-channel.component' | 1 | export * from './video-avatar-channel.component' |
2 | export * from './video-description.component' | 2 | export * from './video-description.component' |
3 | export * from './video-rate.component' | ||
diff --git a/client/src/app/+videos/+video-watch/shared/metadata/video-description.component.ts b/client/src/app/+videos/+video-watch/shared/metadata/video-description.component.ts index b554567d9..23d00d31a 100644 --- a/client/src/app/+videos/+video-watch/shared/metadata/video-description.component.ts +++ b/client/src/app/+videos/+video-watch/shared/metadata/video-description.component.ts | |||
@@ -1,4 +1,4 @@ | |||
1 | import { Component, EventEmitter, Inject, Input, LOCALE_ID, OnChanges, Output } from '@angular/core' | 1 | import { Component, EventEmitter, Input, OnChanges, Output } from '@angular/core' |
2 | import { MarkdownService, Notifier } from '@app/core' | 2 | import { MarkdownService, Notifier } from '@app/core' |
3 | import { VideoDetails, VideoService } from '@app/shared/shared-main' | 3 | import { VideoDetails, VideoService } from '@app/shared/shared-main' |
4 | 4 | ||
@@ -21,8 +21,7 @@ export class VideoDescriptionComponent implements OnChanges { | |||
21 | constructor ( | 21 | constructor ( |
22 | private videoService: VideoService, | 22 | private videoService: VideoService, |
23 | private notifier: Notifier, | 23 | private notifier: Notifier, |
24 | private markdownService: MarkdownService, | 24 | private markdownService: MarkdownService |
25 | @Inject(LOCALE_ID) private localeId: string | ||
26 | ) { } | 25 | ) { } |
27 | 26 | ||
28 | ngOnChanges () { | 27 | ngOnChanges () { |