aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app/videos/+video-watch
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2019-06-12 12:40:24 +0200
committerChocobozzz <me@florianbigard.com>2019-06-12 16:44:15 +0200
commit2f4c784a92ac50cacef07f4925e284b4041422f4 (patch)
tree159e744c68c5f5cd8054b5f63eb389553e13bf56 /client/src/app/videos/+video-watch
parent011e1e6b37e15a44624b2d0e50263e16382060d2 (diff)
downloadPeerTube-2f4c784a92ac50cacef07f4925e284b4041422f4.tar.gz
PeerTube-2f4c784a92ac50cacef07f4925e284b4041422f4.tar.zst
PeerTube-2f4c784a92ac50cacef07f4925e284b4041422f4.zip
Add params to share modal
Diffstat (limited to 'client/src/app/videos/+video-watch')
-rw-r--r--client/src/app/videos/+video-watch/modal/video-share.component.html192
-rw-r--r--client/src/app/videos/+video-watch/modal/video-share.component.scss68
-rw-r--r--client/src/app/videos/+video-watch/modal/video-share.component.ts91
-rw-r--r--client/src/app/videos/+video-watch/video-watch.component.html2
-rw-r--r--client/src/app/videos/+video-watch/video-watch.component.ts5
5 files changed, 301 insertions, 57 deletions
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 955b2b80c..82e59d04d 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
@@ -5,53 +5,167 @@
5 </div> 5 </div>
6 6
7 <div class="modal-body"> 7 <div class="modal-body">
8 <ngb-tabset class="root-tabset bootstrap" (tabChange)="onTabChange($event)">
8 9
9 <div class="start-at"> 10 <ngb-tab i18n-title title="URL" id="url">
10 <my-peertube-checkbox 11 <ng-template ngbTabContent>
11 inputName="startAt" [(ngModel)]="startAtCheckbox" 12
12 i18n-labelText labelText="Start at" 13 <div class="tab-content">
13 ></my-peertube-checkbox> 14 <div class="input-group">
14 15 <input #urlInput (click)="urlInput.select()" type="text" class="form-control readonly" readonly [value]="getVideoUrl()" />
15 <my-timestamp-input 16 <div class="input-group-append">
16 [timestamp]="currentVideoTimestamp" 17 <button [ngxClipboard]="urlInput" (click)="activateCopiedMessage()" type="button" class="btn btn-outline-secondary">
17 [maxTimestamp]="video.duration" 18 <span class="glyphicon glyphicon-copy"></span>
18 [disabled]="!startAtCheckbox" 19 </button>
19 [(ngModel)]="currentVideoTimestamp" 20 </div>
20 > 21 </div>
21 </my-timestamp-input> 22 </div>
22 </div> 23
24 </ng-template>
25 </ngb-tab>
26
27 <ngb-tab i18n-title title="QR-Code" id="qrcode">
28 <ng-template ngbTabContent>
29 <div class="tab-content">
30 <ngx-qrcode qrc-element-type="url" [qrc-value]="getVideoUrl()" qrc-errorCorrectionLevel="Q"></ngx-qrcode>
31 </div>
32 </ng-template>
33 </ngb-tab>
34
35 <ngb-tab i18n-title title="Embed" id="embed">
36 <ng-template ngbTabContent>
37 <div class="tab-content">
38 <div class="input-group">
39 <input #shareInput (click)="shareInput.select()" type="text" class="form-control readonly" readonly [value]="getVideoIframeCode()" />
40 <div class="input-group-append">
41 <button [ngxClipboard]="shareInput" (click)="activateCopiedMessage()" type="button" class="btn btn-outline-secondary">
42 <span class="glyphicon glyphicon-copy"></span>
43 </button>
44 </div>
45 </div>
46
47 <div i18n *ngIf="notSecure()" class="alert alert-warning">
48 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).
49 </div>
50 </div>
51 </ng-template>
52 </ngb-tab>
53
54 </ngb-tabset>
23 55
24 <div class="form-group"> 56 <div class="filters">
25 <label i18n>URL</label> 57 <div>
26 <div class="input-group input-group-sm"> 58 <div class="form-group start-at">
27 <input #urlInput (click)="urlInput.select()" type="text" class="form-control input-sm readonly" readonly [value]="getVideoUrl()" /> 59 <my-peertube-checkbox
28 <div class="input-group-append"> 60 inputName="startAt" [(ngModel)]="customizations.startAtCheckbox"
29 <button [ngxClipboard]="urlInput" (click)="activateCopiedMessage()" type="button" class="btn btn-outline-secondary"> 61 i18n-labelText labelText="Start at"
30 <span class="glyphicon glyphicon-copy"></span> 62 ></my-peertube-checkbox>
31 </button> 63
64 <my-timestamp-input
65 [timestamp]="customizations.startAt"
66 [maxTimestamp]="video.duration"
67 [disabled]="!customizations.startAtCheckbox"
68 [(ngModel)]="customizations.startAt"
69 >
70 </my-timestamp-input>
32 </div> 71 </div>
33 </div>
34 </div>
35 72
36 <div class="form-group qr-code-group"> 73 <div *ngIf="videoCaptions.length !== 0" class="form-group video-caption-block">
37 <label i18n>QR-Code</label> 74 <my-peertube-checkbox
38 <ngx-qrcode qrc-element-type="url" [qrc-value]="getVideoUrl()" qrc-errorCorrectionLevel="Q"></ngx-qrcode> 75 inputName="subtitleCheckbox" [(ngModel)]="customizations.subtitleCheckbox"
39 </div> 76 i18n-labelText labelText="Auto select subtitle"
77 ></my-peertube-checkbox>
40 78
41 <div class="form-group"> 79 <div class="peertube-select-container" [ngClass]="{ disabled: !customizations.subtitleCheckbox }">
42 <label i18n>Embed</label> 80 <select [(ngModel)]="customizations.subtitle" [disabled]="!customizations.subtitleCheckbox">
43 <div class="input-group input-group-sm"> 81 <option *ngFor="let caption of videoCaptions" [value]="caption.language.id">{{ caption.language.label }}</option>
44 <input #shareInput (click)="shareInput.select()" type="text" class="form-control input-sm readonly" readonly [value]="getVideoIframeCode()" /> 82 </select>
45 <div class="input-group-append"> 83 </div>
46 <button [ngxClipboard]="shareInput" (click)="activateCopiedMessage()" type="button" class="btn btn-outline-secondary">
47 <span class="glyphicon glyphicon-copy"></span>
48 </button>
49 </div> 84 </div>
50 </div> 85 </div>
51 </div>
52 86
53 <div i18n *ngIf="notSecure()" class="alert alert-warning"> 87 <div (click)="isAdvancedCustomizationCollapsed = !isAdvancedCustomizationCollapsed" role="button" class="advanced-filters-button"
54 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). 88 [attr.aria-expanded]="!isAdvancedCustomizationCollapsed" aria-controls="collapseBasic">
89
90 <ng-container *ngIf="isAdvancedCustomizationCollapsed">
91 <span class="glyphicon glyphicon-menu-down"></span>
92
93 <ng-container i18n>
94 More customization
95 </ng-container>
96 </ng-container>
97
98 <ng-container *ngIf="!isAdvancedCustomizationCollapsed">
99 <span class="glyphicon glyphicon-menu-up"></span>
100
101 <ng-container i18n>
102 Less customization
103 </ng-container>
104 </ng-container>
105 </div>
106
107 <div class="advanced-filters collapse-transition" [ngbCollapse]="isAdvancedCustomizationCollapsed">
108 <div>
109 <div class="form-group stop-at">
110 <my-peertube-checkbox
111 inputName="stopAt" [(ngModel)]="customizations.stopAtCheckbox"
112 i18n-labelText labelText="Stop at"
113 ></my-peertube-checkbox>
114
115 <my-timestamp-input
116 [timestamp]="customizations.stopAt"
117 [maxTimestamp]="video.duration"
118 [disabled]="!customizations.stopAtCheckbox"
119 [(ngModel)]="customizations.stopAt"
120 >
121 </my-timestamp-input>
122 </div>
123
124 <div class="form-group">
125 <my-peertube-checkbox
126 inputName="autoplay" [(ngModel)]="customizations.autoplay"
127 i18n-labelText labelText="Autoplay"
128 ></my-peertube-checkbox>
129 </div>
130
131 <div class="form-group">
132 <my-peertube-checkbox
133 inputName="muted" [(ngModel)]="customizations.muted"
134 i18n-labelText labelText="Muted"
135 ></my-peertube-checkbox>
136 </div>
137
138 <div class="form-group">
139 <my-peertube-checkbox
140 inputName="loop" [(ngModel)]="customizations.loop"
141 i18n-labelText labelText="Loop"
142 ></my-peertube-checkbox>
143 </div>
144 </div>
145
146 <ng-container *ngIf="isInEmbedTab()">
147 <div class="form-group">
148 <my-peertube-checkbox
149 inputName="title" [(ngModel)]="customizations.title"
150 i18n-labelText labelText="Display video title"
151 ></my-peertube-checkbox>
152 </div>
153
154 <div class="form-group">
155 <my-peertube-checkbox
156 inputName="warningTitle" [(ngModel)]="customizations.warningTitle"
157 i18n-labelText labelText="Display privacy warning"
158 ></my-peertube-checkbox>
159 </div>
160
161 <div class="form-group">
162 <my-peertube-checkbox
163 inputName="controls" [(ngModel)]="customizations.controls"
164 i18n-labelText labelText="Display player controls"
165 ></my-peertube-checkbox>
166 </div>
167 </ng-container>
168 </div>
55 </div> 169 </div>
56 </div> 170 </div>
57 171
diff --git a/client/src/app/videos/+video-watch/modal/video-share.component.scss b/client/src/app/videos/+video-watch/modal/video-share.component.scss
index 472a45920..c48abf9e0 100644
--- a/client/src/app/videos/+video-watch/modal/video-share.component.scss
+++ b/client/src/app/videos/+video-watch/modal/video-share.component.scss
@@ -1,5 +1,9 @@
1@import '~bootstrap/scss/functions'; 1@import '_mixins';
2@import '~bootstrap/scss/variables'; 2@import '_variables';
3
4.peertube-select-container {
5 @include peertube-select-container(200px);
6}
3 7
4.action-button-cancel { 8.action-button-cancel {
5 margin-right: 0 !important; 9 margin-right: 0 !important;
@@ -9,13 +13,65 @@
9 text-align: center; 13 text-align: center;
10} 14}
11 15
12.start-at { 16.tab-content {
17 margin-top: 30px;
13 display: flex; 18 display: flex;
14 justify-content: center; 19 justify-content: center;
15 margin-top: 10px;
16 align-items: center; 20 align-items: center;
21 flex-direction: column;
22}
23
24.alert {
25 margin-top: 20px;
26}
27
28input.readonly {
29 font-size: 15px;
30}
31
32.filters {
33 margin-top: 30px;
34 padding-top: 30px;
35 border-top: 1px solid $separator-border-color;
36
37 .advanced-filters-button {
38 display: flex;
39 justify-content: center;
40 align-items: center;
41 margin-top: 30px;
42 font-size: 16px;
43 font-weight: $font-semibold;
44 cursor: pointer;
45
46 .glyphicon {
47 margin-right: 5px;
48 }
49 }
50
51 .form-group {
52 margin-bottom: 0;
53 height: 34px;
54 display: flex;
55 align-items: center;
56 }
57
58 .video-caption-block {
59 display: flex;
60 align-items: center;
61
62 .peertube-select-container {
63 margin-left: 10px;
64 }
65 }
66
67 .start-at,
68 .stop-at {
69 width: 300px;
70 display: flex;
71 align-items: center;
17 72
18 my-timestamp-input { 73 my-timestamp-input {
19 margin-left: 10px; 74 margin-left: 10px;
75 }
20 } 76 }
21} 77}
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 6565d7f88..eaaf6b902 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
@@ -3,8 +3,26 @@ import { Notifier } from '@app/core'
3import { VideoDetails } from '../../../shared/video/video-details.model' 3import { VideoDetails } from '../../../shared/video/video-details.model'
4import { buildVideoEmbed, buildVideoLink } from '../../../../assets/player/utils' 4import { buildVideoEmbed, buildVideoLink } from '../../../../assets/player/utils'
5import { I18n } from '@ngx-translate/i18n-polyfill' 5import { I18n } from '@ngx-translate/i18n-polyfill'
6import { NgbModal } from '@ng-bootstrap/ng-bootstrap' 6import { NgbModal, NgbTabChangeEvent } from '@ng-bootstrap/ng-bootstrap'
7import { durationToString } from '@app/shared/misc/utils' 7import { VideoCaption } from '@shared/models'
8
9type Customizations = {
10 startAtCheckbox: boolean
11 startAt: number
12
13 stopAtCheckbox: boolean
14 stopAt: number
15
16 subtitleCheckbox: boolean
17 subtitle: string
18
19 loop: boolean
20 autoplay: boolean
21 muted: boolean
22 title: boolean
23 warningTitle: boolean
24 controls: boolean
25}
8 26
9@Component({ 27@Component({
10 selector: 'my-video-share', 28 selector: 'my-video-share',
@@ -15,9 +33,13 @@ export class VideoShareComponent {
15 @ViewChild('modal') modal: ElementRef 33 @ViewChild('modal') modal: ElementRef
16 34
17 @Input() video: VideoDetails = null 35 @Input() video: VideoDetails = null
36 @Input() videoCaptions: VideoCaption[] = []
18 37
19 currentVideoTimestamp: number 38 activeId: 'url' | 'qrcode' | 'embed'
20 startAtCheckbox = false 39 customizations: Customizations
40 isAdvancedCustomizationCollapsed = true
41
42 private currentVideoTimestamp: number
21 43
22 constructor ( 44 constructor (
23 private modalService: NgbModal, 45 private modalService: NgbModal,
@@ -26,19 +48,47 @@ export class VideoShareComponent {
26 ) { } 48 ) { }
27 49
28 show (currentVideoTimestamp?: number) { 50 show (currentVideoTimestamp?: number) {
29 this.currentVideoTimestamp = currentVideoTimestamp ? Math.floor(currentVideoTimestamp) : 0 51 this.currentVideoTimestamp = currentVideoTimestamp
52
53 let subtitle: string
54 if (this.videoCaptions.length !== 0) {
55 subtitle = this.videoCaptions[0].language.id
56 }
57
58 this.customizations = {
59 startAtCheckbox: false,
60 startAt: currentVideoTimestamp ? Math.floor(currentVideoTimestamp) : 0,
61
62 stopAtCheckbox: false,
63 stopAt: this.video.duration,
64
65 subtitleCheckbox: false,
66 subtitle,
67
68 loop: false,
69 autoplay: false,
70 muted: false,
71
72 // Embed options
73 title: true,
74 warningTitle: true,
75 controls: true
76 }
30 77
31 this.modalService.open(this.modal) 78 this.modalService.open(this.modal)
32 } 79 }
33 80
34 getVideoIframeCode () { 81 getVideoIframeCode () {
35 const embedUrl = buildVideoLink(this.getVideoTimestampIfEnabled(), this.video.embedUrl) 82 const options = this.getOptions(this.video.embedUrl)
36 83
84 const embedUrl = buildVideoLink(options)
37 return buildVideoEmbed(embedUrl) 85 return buildVideoEmbed(embedUrl)
38 } 86 }
39 87
40 getVideoUrl () { 88 getVideoUrl () {
41 return buildVideoLink(this.getVideoTimestampIfEnabled()) 89 const options = this.getOptions()
90
91 return buildVideoLink(options)
42 } 92 }
43 93
44 notSecure () { 94 notSecure () {
@@ -49,9 +99,30 @@ export class VideoShareComponent {
49 this.notifier.success(this.i18n('Copied')) 99 this.notifier.success(this.i18n('Copied'))
50 } 100 }
51 101
52 private getVideoTimestampIfEnabled () { 102 onTabChange (event: NgbTabChangeEvent) {
53 if (this.startAtCheckbox === true) return this.currentVideoTimestamp 103 this.activeId = event.nextId as any
104 }
105
106 isInEmbedTab () {
107 return this.activeId === 'embed'
108 }
109
110 private getOptions (baseUrl?: string) {
111 return {
112 baseUrl,
113
114 startTime: this.customizations.startAtCheckbox ? this.customizations.startAt : undefined,
115 stopTime: this.customizations.stopAtCheckbox ? this.customizations.stopAt : undefined,
116
117 subtitle: this.customizations.subtitleCheckbox ? this.customizations.subtitle : undefined,
118
119 loop: this.customizations.loop,
120 autoplay: this.customizations.autoplay,
121 muted: this.customizations.muted,
54 122
55 return undefined 123 title: this.customizations.title,
124 warningTitle: this.customizations.warningTitle,
125 controls: this.customizations.controls
126 }
56 } 127 }
57} 128}
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 2e39b9c6b..6a02f630a 100644
--- a/client/src/app/videos/+video-watch/video-watch.component.html
+++ b/client/src/app/videos/+video-watch/video-watch.component.html
@@ -219,5 +219,5 @@
219 219
220<ng-template [ngIf]="video !== null"> 220<ng-template [ngIf]="video !== null">
221 <my-video-support #videoSupportModal [video]="video"></my-video-support> 221 <my-video-support #videoSupportModal [video]="video"></my-video-support>
222 <my-video-share #videoShareModal [video]="video"></my-video-share> 222 <my-video-share #videoShareModal [video]="video" [videoCaptions]="videoCaptions"></my-video-share>
223</ng-template> 223</ng-template>
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 29c472a42..3f1a98f89 100644
--- a/client/src/app/videos/+video-watch/video-watch.component.ts
+++ b/client/src/app/videos/+video-watch/video-watch.component.ts
@@ -50,9 +50,11 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
50 playerElement: HTMLVideoElement 50 playerElement: HTMLVideoElement
51 theaterEnabled = false 51 theaterEnabled = false
52 userRating: UserVideoRateType = null 52 userRating: UserVideoRateType = null
53 video: VideoDetails = null
54 descriptionLoading = false 53 descriptionLoading = false
55 54
55 video: VideoDetails = null
56 videoCaptions: VideoCaption[] = []
57
56 playlist: VideoPlaylist = null 58 playlist: VideoPlaylist = null
57 59
58 completeDescriptionShown = false 60 completeDescriptionShown = false
@@ -339,6 +341,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
339 urlOptions: CustomizationOptions & { playerMode: PlayerMode } 341 urlOptions: CustomizationOptions & { playerMode: PlayerMode }
340 ) { 342 ) {
341 this.video = video 343 this.video = video
344 this.videoCaptions = videoCaptions
342 345
343 // Re init attributes 346 // Re init attributes
344 this.descriptionLoading = false 347 this.descriptionLoading = false