diff options
author | Chocobozzz <me@florianbigard.com> | 2020-08-07 13:43:48 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2020-08-07 13:43:48 +0200 |
commit | 951b582f52d0694865f020f0e53ccfad2d2d6033 (patch) | |
tree | e82f6eaf08a2add25a7807135a5b2351819ab3a0 /client/src/app/+videos | |
parent | 4891e4c77b72ac5a2f9d3d761a71eebe26d81357 (diff) | |
download | PeerTube-951b582f52d0694865f020f0e53ccfad2d2d6033.tar.gz PeerTube-951b582f52d0694865f020f0e53ccfad2d2d6033.tar.zst PeerTube-951b582f52d0694865f020f0e53ccfad2d2d6033.zip |
Add ability to share playlists in modal
Diffstat (limited to 'client/src/app/+videos')
4 files changed, 79 insertions, 18 deletions
diff --git a/client/src/app/+videos/+video-watch/comment/video-comment.component.ts b/client/src/app/+videos/+video-watch/comment/video-comment.component.ts index 6744a0954..36ec6e9f9 100644 --- a/client/src/app/+videos/+video-watch/comment/video-comment.component.ts +++ b/client/src/app/+videos/+video-watch/comment/video-comment.component.ts | |||
@@ -135,7 +135,7 @@ export class VideoCommentComponent implements OnInit, OnChanges { | |||
135 | this.comment.account = null | 135 | this.comment.account = null |
136 | } | 136 | } |
137 | 137 | ||
138 | if (this.isUserLoggedIn() && this.authService.getUser().account.id !== this.comment.account.id) { | 138 | if (this.isUserLoggedIn() && this.comment.isDeleted === false && this.authService.getUser().account.id !== this.comment.account.id) { |
139 | this.prependModerationActions = [ | 139 | this.prependModerationActions = [ |
140 | { | 140 | { |
141 | label: this.i18n('Report comment'), | 141 | label: this.i18n('Report comment'), |
diff --git a/client/src/app/+videos/+video-watch/modal/video-share.component.html b/client/src/app/+videos/+video-watch/modal/video-share.component.html index 71ae6544f..946e8d8ca 100644 --- a/client/src/app/+videos/+video-watch/modal/video-share.component.html +++ b/client/src/app/+videos/+video-watch/modal/video-share.component.html | |||
@@ -6,18 +6,56 @@ | |||
6 | 6 | ||
7 | 7 | ||
8 | <div class="modal-body"> | 8 | <div class="modal-body"> |
9 | |||
9 | <div class="playlist" *ngIf="hasPlaylist()"> | 10 | <div class="playlist" *ngIf="hasPlaylist()"> |
10 | <div class="title-page title-page-single" i18n>Share the playlist</div> | 11 | <div class="title-page title-page-single" i18n>Share the playlist</div> |
11 | 12 | ||
12 | <my-input-readonly-copy [value]="getPlaylistUrl()"></my-input-readonly-copy> | 13 | <div ngbNav #nav="ngbNav" class="nav-tabs" [(activeId)]="activePlaylistId"> |
14 | |||
15 | <ng-container ngbNavItem="url"> | ||
16 | <a ngbNavLink i18n>URL</a> | ||
17 | |||
18 | <ng-template ngbNavContent> | ||
19 | <div class="nav-content"> | ||
20 | |||
21 | <my-input-readonly-copy [value]="getPlaylistUrl()"></my-input-readonly-copy> | ||
22 | </div> | ||
23 | </ng-template> | ||
24 | </ng-container> | ||
25 | |||
26 | <ng-container ngbNavItem="qrcode"> | ||
27 | <a ngbNavLink i18n>QR-Code</a> | ||
28 | |||
29 | <ng-template ngbNavContent> | ||
30 | <div class="nav-content"> | ||
31 | <qrcode [qrdata]="getPlaylistUrl()" [size]="256" level="Q"></qrcode> | ||
32 | </div> | ||
33 | </ng-template> | ||
34 | </ng-container> | ||
35 | |||
36 | <ng-container ngbNavItem="embed"> | ||
37 | <a ngbNavLink i18n>Embed</a> | ||
38 | |||
39 | <ng-template ngbNavContent> | ||
40 | <div class="nav-content"> | ||
41 | <my-input-readonly-copy [value]="getPlaylistIframeCode()"></my-input-readonly-copy> | ||
42 | |||
43 | <div i18n *ngIf="notSecure()" class="alert alert-warning"> | ||
44 | The url is not secured (no HTTPS), so the embed video won't work on HTTPS websites (web browsers block non secured HTTP requests on HTTPS websites). | ||
45 | </div> | ||
46 | </div> | ||
47 | </ng-template> | ||
48 | </ng-container> | ||
49 | |||
50 | </div> | ||
51 | |||
52 | <div [ngbNavOutlet]="nav"></div> | ||
13 | 53 | ||
14 | <div class="filters"> | 54 | <div class="filters"> |
15 | 55 | ||
16 | <div class="form-group"> | 56 | <div class="form-group"> |
17 | <my-peertube-checkbox | 57 | <my-peertube-checkbox inputName="includeVideoInPlaylist" [(ngModel)]="includeVideoInPlaylist" i18n-labelText |
18 | inputName="includeVideoInPlaylist" [(ngModel)]="includeVideoInPlaylist" | 58 | labelText="Share the playlist at this video position"></my-peertube-checkbox> |
19 | i18n-labelText labelText="Share the playlist at this video position" | ||
20 | ></my-peertube-checkbox> | ||
21 | </div> | 59 | </div> |
22 | 60 | ||
23 | </div> | 61 | </div> |
@@ -27,7 +65,7 @@ | |||
27 | <div class="video"> | 65 | <div class="video"> |
28 | <div class="title-page title-page-single" *ngIf="hasPlaylist()" i18n>Share the video</div> | 66 | <div class="title-page title-page-single" *ngIf="hasPlaylist()" i18n>Share the video</div> |
29 | 67 | ||
30 | <div ngbNav #nav="ngbNav" class="nav-tabs" [(activeId)]="activeId"> | 68 | <div ngbNav #nav="ngbNav" class="nav-tabs" [(activeId)]="activeVideoId"> |
31 | 69 | ||
32 | <ng-container ngbNavItem="url"> | 70 | <ng-container ngbNavItem="url"> |
33 | <a ngbNavLink i18n>URL</a> | 71 | <a ngbNavLink i18n>URL</a> |
@@ -137,7 +175,7 @@ | |||
137 | </div> | 175 | </div> |
138 | </div> | 176 | </div> |
139 | 177 | ||
140 | <ng-container *ngIf="isInEmbedTab()"> | 178 | <ng-container *ngIf="isVideoInEmbedTab()"> |
141 | <div class="form-group"> | 179 | <div class="form-group"> |
142 | <my-peertube-checkbox | 180 | <my-peertube-checkbox |
143 | inputName="title" [(ngModel)]="customizations.title" | 181 | inputName="title" [(ngModel)]="customizations.title" |
diff --git a/client/src/app/+videos/+video-watch/modal/video-share.component.ts b/client/src/app/+videos/+video-watch/modal/video-share.component.ts index 23c562273..d9171fe0e 100644 --- a/client/src/app/+videos/+video-watch/modal/video-share.component.ts +++ b/client/src/app/+videos/+video-watch/modal/video-share.component.ts | |||
@@ -1,5 +1,5 @@ | |||
1 | import { Component, ElementRef, Input, ViewChild } from '@angular/core' | 1 | import { Component, ElementRef, Input, ViewChild } from '@angular/core' |
2 | import { buildVideoEmbed, buildVideoLink } from '../../../../assets/player/utils' | 2 | import { buildVideoOrPlaylistEmbed, buildVideoLink, buildPlaylistLink } from '../../../../assets/player/utils' |
3 | import { NgbModal } from '@ng-bootstrap/ng-bootstrap' | 3 | import { NgbModal } from '@ng-bootstrap/ng-bootstrap' |
4 | import { VideoCaption } from '@shared/models' | 4 | import { VideoCaption } from '@shared/models' |
5 | import { VideoDetails } from '@app/shared/shared-main' | 5 | import { VideoDetails } from '@app/shared/shared-main' |
@@ -24,6 +24,8 @@ type Customizations = { | |||
24 | peertubeLink: boolean | 24 | peertubeLink: boolean |
25 | } | 25 | } |
26 | 26 | ||
27 | type TabId = 'url' | 'qrcode' | 'embed' | ||
28 | |||
27 | @Component({ | 29 | @Component({ |
28 | selector: 'my-video-share', | 30 | selector: 'my-video-share', |
29 | templateUrl: './video-share.component.html', | 31 | templateUrl: './video-share.component.html', |
@@ -36,14 +38,18 @@ export class VideoShareComponent { | |||
36 | @Input() videoCaptions: VideoCaption[] = [] | 38 | @Input() videoCaptions: VideoCaption[] = [] |
37 | @Input() playlist: VideoPlaylist = null | 39 | @Input() playlist: VideoPlaylist = null |
38 | 40 | ||
39 | activeId: 'url' | 'qrcode' | 'embed' = 'url' | 41 | activeVideoId: TabId = 'url' |
42 | activePlaylistId: TabId = 'url' | ||
43 | |||
40 | customizations: Customizations | 44 | customizations: Customizations |
41 | isAdvancedCustomizationCollapsed = true | 45 | isAdvancedCustomizationCollapsed = true |
42 | includeVideoInPlaylist = false | 46 | includeVideoInPlaylist = false |
43 | 47 | ||
48 | private playlistPosition: number = null | ||
49 | |||
44 | constructor (private modalService: NgbModal) { } | 50 | constructor (private modalService: NgbModal) { } |
45 | 51 | ||
46 | show (currentVideoTimestamp?: number) { | 52 | show (currentVideoTimestamp?: number, currentPlaylistPosition?: number) { |
47 | let subtitle: string | 53 | let subtitle: string |
48 | if (this.videoCaptions.length !== 0) { | 54 | if (this.videoCaptions.length !== 0) { |
49 | subtitle = this.videoCaptions[0].language.id | 55 | subtitle = this.videoCaptions[0].language.id |
@@ -70,19 +76,28 @@ export class VideoShareComponent { | |||
70 | peertubeLink: true | 76 | peertubeLink: true |
71 | } | 77 | } |
72 | 78 | ||
79 | this.playlistPosition = currentPlaylistPosition | ||
80 | |||
73 | this.modalService.open(this.modal, { centered: true }) | 81 | this.modalService.open(this.modal, { centered: true }) |
74 | } | 82 | } |
75 | 83 | ||
76 | getVideoIframeCode () { | 84 | getVideoIframeCode () { |
77 | const options = this.getOptions(this.video.embedUrl) | 85 | const options = this.getVideoOptions(this.video.embedUrl) |
78 | 86 | ||
79 | const embedUrl = buildVideoLink(options) | 87 | const embedUrl = buildVideoLink(options) |
80 | return buildVideoEmbed(embedUrl) | 88 | return buildVideoOrPlaylistEmbed(embedUrl) |
89 | } | ||
90 | |||
91 | getPlaylistIframeCode () { | ||
92 | const options = this.getPlaylistOptions(this.playlist.embedUrl) | ||
93 | |||
94 | const embedUrl = buildPlaylistLink(options) | ||
95 | return buildVideoOrPlaylistEmbed(embedUrl) | ||
81 | } | 96 | } |
82 | 97 | ||
83 | getVideoUrl () { | 98 | getVideoUrl () { |
84 | const baseUrl = window.location.origin + '/videos/watch/' + this.video.uuid | 99 | const baseUrl = window.location.origin + '/videos/watch/' + this.video.uuid |
85 | const options = this.getOptions(baseUrl) | 100 | const options = this.getVideoOptions(baseUrl) |
86 | 101 | ||
87 | return buildVideoLink(options) | 102 | return buildVideoLink(options) |
88 | } | 103 | } |
@@ -99,15 +114,23 @@ export class VideoShareComponent { | |||
99 | return window.location.protocol === 'http:' | 114 | return window.location.protocol === 'http:' |
100 | } | 115 | } |
101 | 116 | ||
102 | isInEmbedTab () { | 117 | isVideoInEmbedTab () { |
103 | return this.activeId === 'embed' | 118 | return this.activeVideoId === 'embed' |
104 | } | 119 | } |
105 | 120 | ||
106 | hasPlaylist () { | 121 | hasPlaylist () { |
107 | return !!this.playlist | 122 | return !!this.playlist |
108 | } | 123 | } |
109 | 124 | ||
110 | private getOptions (baseUrl?: string) { | 125 | private getPlaylistOptions (baseUrl?: string) { |
126 | return { | ||
127 | baseUrl, | ||
128 | |||
129 | playlistPosition: this.playlistPosition || undefined | ||
130 | } | ||
131 | } | ||
132 | |||
133 | private getVideoOptions (baseUrl?: string) { | ||
111 | return { | 134 | return { |
112 | baseUrl, | 135 | baseUrl, |
113 | 136 | ||
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 dfe73d14d..d8136ab4f 100644 --- a/client/src/app/+videos/+video-watch/video-watch.component.ts +++ b/client/src/app/+videos/+video-watch/video-watch.component.ts | |||
@@ -244,7 +244,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
244 | showShareModal () { | 244 | showShareModal () { |
245 | this.pausePlayer() | 245 | this.pausePlayer() |
246 | 246 | ||
247 | this.videoShareModal.show(this.currentTime) | 247 | this.videoShareModal.show(this.currentTime, this.videoWatchPlaylist.currentPlaylistPosition) |
248 | } | 248 | } |
249 | 249 | ||
250 | isUserLoggedIn () { | 250 | isUserLoggedIn () { |