diff options
Diffstat (limited to 'client/src/app/videos/+video-watch')
11 files changed, 361 insertions, 446 deletions
diff --git a/client/src/app/videos/+video-watch/video-download.component.html b/client/src/app/videos/+video-watch/video-download.component.html index ddc57e999..7efc79e93 100644 --- a/client/src/app/videos/+video-watch/video-download.component.html +++ b/client/src/app/videos/+video-watch/video-download.component.html | |||
@@ -6,18 +6,19 @@ | |||
6 | <button type="button" class="close" aria-label="Close" (click)="hide()"> | 6 | <button type="button" class="close" aria-label="Close" (click)="hide()"> |
7 | <span aria-hidden="true">×</span> | 7 | <span aria-hidden="true">×</span> |
8 | </button> | 8 | </button> |
9 | <h4 class="modal-title">Download</h4> | 9 | <h4 class="title-page title-page-single">Download</h4> |
10 | </div> | 10 | </div> |
11 | 11 | ||
12 | <div class="modal-body"> | 12 | <div class="modal-body"> |
13 | <div *ngFor="let file of video.files" class="resolution-block"> | 13 | <div *ngFor="let file of video.files" class="resolution-block"> |
14 | <label>{{ file.resolutionLabel }}</label> | 14 | <label>{{ file.resolutionLabel }}</label> |
15 | <a class="btn btn-default " target="_blank" [href]="file.torrentUrl"> | 15 | |
16 | <span class="glyphicon glyphicon-download"></span> | 16 | <a class="orange-button-link " target="_blank" [href]="file.torrentUrl"> |
17 | <span class="icon icon-download"></span> | ||
17 | Torrent file | 18 | Torrent file |
18 | </a> | 19 | </a> |
19 | <a class="btn btn-default" target="_blank" [href]="file.fileUrl"> | 20 | <a class="orange-button-link" target="_blank" [href]="file.fileUrl"> |
20 | <span class="glyphicon glyphicon-download"></span> | 21 | <span class="icon icon-download"></span> |
21 | Download | 22 | Download |
22 | </a> | 23 | </a> |
23 | 24 | ||
diff --git a/client/src/app/videos/+video-watch/video-download.component.scss b/client/src/app/videos/+video-watch/video-download.component.scss new file mode 100644 index 000000000..c9d5af9c1 --- /dev/null +++ b/client/src/app/videos/+video-watch/video-download.component.scss | |||
@@ -0,0 +1,23 @@ | |||
1 | .resolution-block:not(:first-child) { | ||
2 | margin-top: 30px; | ||
3 | } | ||
4 | |||
5 | .orange-button-link { | ||
6 | margin-right: 10px; | ||
7 | } | ||
8 | |||
9 | label { | ||
10 | display: block; | ||
11 | } | ||
12 | |||
13 | .icon { | ||
14 | @include icon(21px); | ||
15 | |||
16 | margin-right: 5px; | ||
17 | position: relative; | ||
18 | top: -1px; | ||
19 | |||
20 | &.icon-download { | ||
21 | background-image: url('../../../assets/images/video/download-white.svg'); | ||
22 | } | ||
23 | } | ||
diff --git a/client/src/app/videos/+video-watch/video-download.component.ts b/client/src/app/videos/+video-watch/video-download.component.ts index c32f8d586..095df1698 100644 --- a/client/src/app/videos/+video-watch/video-download.component.ts +++ b/client/src/app/videos/+video-watch/video-download.component.ts | |||
@@ -1,13 +1,11 @@ | |||
1 | import { Component, Input, ViewChild } from '@angular/core' | 1 | import { Component, Input, ViewChild } from '@angular/core' |
2 | |||
3 | import { ModalDirective } from 'ngx-bootstrap/modal' | 2 | import { ModalDirective } from 'ngx-bootstrap/modal' |
4 | 3 | import { VideoDetails } from '../../shared/video/video-details.model' | |
5 | import { VideoDetails } from '../shared' | ||
6 | 4 | ||
7 | @Component({ | 5 | @Component({ |
8 | selector: 'my-video-download', | 6 | selector: 'my-video-download', |
9 | templateUrl: './video-download.component.html', | 7 | templateUrl: './video-download.component.html', |
10 | styles: [ '.resolution-block { margin-top: 20px; }' ] | 8 | styleUrls: [ './video-download.component.scss' ] |
11 | }) | 9 | }) |
12 | export class VideoDownloadComponent { | 10 | export class VideoDownloadComponent { |
13 | @Input() video: VideoDetails = null | 11 | @Input() video: VideoDetails = null |
diff --git a/client/src/app/videos/+video-watch/video-report.component.html b/client/src/app/videos/+video-watch/video-report.component.html index ceb7cf50a..20474bab4 100644 --- a/client/src/app/videos/+video-watch/video-report.component.html +++ b/client/src/app/videos/+video-watch/video-report.component.html | |||
@@ -6,28 +6,28 @@ | |||
6 | <button type="button" class="close" aria-label="Close" (click)="hide()"> | 6 | <button type="button" class="close" aria-label="Close" (click)="hide()"> |
7 | <span aria-hidden="true">×</span> | 7 | <span aria-hidden="true">×</span> |
8 | </button> | 8 | </button> |
9 | <h4 class="modal-title">Report video</h4> | 9 | <h4 class="title-page title-page-single">Report video</h4> |
10 | </div> | 10 | </div> |
11 | 11 | ||
12 | <div class="modal-body"> | 12 | <div class="modal-body"> |
13 | 13 | ||
14 | <form novalidate [formGroup]="form"> | 14 | <form novalidate [formGroup]="form" (ngSubmit)="report()"> |
15 | <div class="form-group"> | 15 | <div class="form-group"> |
16 | <label for="reason">Reason</label> | 16 | <label for="reason">Reason</label> |
17 | <textarea | 17 | <textarea |
18 | id="reason" class="form-control" placeholder="Reason..." | 18 | id="reason" class="form-control" placeholder="Reason..." |
19 | formControlName="reason" | 19 | formControlName="reason" [ngClass]="{ 'input-error': formErrors['reason'] }" |
20 | > | 20 | > |
21 | </textarea> | 21 | </textarea> |
22 | <div *ngIf="formErrors.reason" class="alert alert-danger"> | 22 | <div *ngIf="formErrors.reason" class="form-error"> |
23 | {{ formErrors.reason }} | 23 | {{ formErrors.reason }} |
24 | </div> | 24 | </div> |
25 | </div> | 25 | </div> |
26 | 26 | ||
27 | <div class="form-group"> | 27 | <div class="form-group"> |
28 | <input | 28 | <input |
29 | type="button" value="Report" class="btn btn-default form-control" | 29 | type="submit" value="Report" class="orange-button" |
30 | [disabled]="!form.valid" (click)="report()" | 30 | [disabled]="!form.valid" |
31 | > | 31 | > |
32 | </div> | 32 | </div> |
33 | </form> | 33 | </form> |
diff --git a/client/src/app/videos/+video-watch/video-report.component.ts b/client/src/app/videos/+video-watch/video-report.component.ts index fc9b5a9d4..b94e4144e 100644 --- a/client/src/app/videos/+video-watch/video-report.component.ts +++ b/client/src/app/videos/+video-watch/video-report.component.ts | |||
@@ -1,11 +1,9 @@ | |||
1 | import { Component, Input, OnInit, ViewChild } from '@angular/core' | 1 | import { Component, Input, OnInit, ViewChild } from '@angular/core' |
2 | import { FormBuilder, FormGroup } from '@angular/forms' | 2 | import { FormBuilder, FormGroup } from '@angular/forms' |
3 | |||
4 | import { ModalDirective } from 'ngx-bootstrap/modal' | ||
5 | import { NotificationsService } from 'angular2-notifications' | 3 | import { NotificationsService } from 'angular2-notifications' |
6 | 4 | import { ModalDirective } from 'ngx-bootstrap/modal' | |
7 | import { FormReactive, VideoAbuseService, VIDEO_ABUSE_REASON } from '../../shared' | 5 | import { FormReactive, VIDEO_ABUSE_REASON, VideoAbuseService } from '../../shared' |
8 | import { VideoDetails, VideoService } from '../shared' | 6 | import { VideoDetails } from '../../shared/video/video-details.model' |
9 | 7 | ||
10 | @Component({ | 8 | @Component({ |
11 | selector: 'my-video-report', | 9 | selector: 'my-video-report', |
diff --git a/client/src/app/videos/+video-watch/video-share.component.html b/client/src/app/videos/+video-watch/video-share.component.html index 88f59c063..36ec38d88 100644 --- a/client/src/app/videos/+video-watch/video-share.component.html +++ b/client/src/app/videos/+video-watch/video-share.component.html | |||
@@ -6,7 +6,7 @@ | |||
6 | <button type="button" class="close" aria-label="Close" (click)="hide()"> | 6 | <button type="button" class="close" aria-label="Close" (click)="hide()"> |
7 | <span aria-hidden="true">×</span> | 7 | <span aria-hidden="true">×</span> |
8 | </button> | 8 | </button> |
9 | <h4 class="modal-title">Share</h4> | 9 | <h4 class="title-page title-page-single">Share</h4> |
10 | </div> | 10 | </div> |
11 | 11 | ||
12 | <div class="modal-body"> | 12 | <div class="modal-body"> |
diff --git a/client/src/app/videos/+video-watch/video-share.component.ts b/client/src/app/videos/+video-watch/video-share.component.ts index aeef65ecf..4df9adf29 100644 --- a/client/src/app/videos/+video-watch/video-share.component.ts +++ b/client/src/app/videos/+video-watch/video-share.component.ts | |||
@@ -1,8 +1,6 @@ | |||
1 | import { Component, Input, ViewChild } from '@angular/core' | 1 | import { Component, Input, ViewChild } from '@angular/core' |
2 | |||
3 | import { ModalDirective } from 'ngx-bootstrap/modal' | 2 | import { ModalDirective } from 'ngx-bootstrap/modal' |
4 | 3 | import { VideoDetails } from '../../shared/video/video-details.model' | |
5 | import { VideoDetails } from '../shared' | ||
6 | 4 | ||
7 | @Component({ | 5 | @Component({ |
8 | selector: 'my-video-share', | 6 | selector: 'my-video-share', |
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 f528d73c3..f99e84caf 100644 --- a/client/src/app/videos/+video-watch/video-watch.component.html +++ b/client/src/app/videos/+video-watch/video-watch.component.html | |||
@@ -1,197 +1,153 @@ | |||
1 | <div *ngIf="error" class="row"> | ||
2 | <div class="alert alert-danger"> | ||
3 | The video load seems to be abnormally long. | ||
4 | <ul> | ||
5 | <li>Maybe the server {{ video.serverHost }} is down :(</li> | ||
6 | <li> | ||
7 | If not, you can report an issue on | ||
8 | <a href="https://github.com/Chocobozzz/PeerTube/issues" title="Report an issue"> | ||
9 | https://github.com/Chocobozzz/PeerTube/issues | ||
10 | </a> | ||
11 | </li> | ||
12 | </ul> | ||
13 | </div> | ||
14 | </div> | ||
15 | |||
16 | <div class="row"> | 1 | <div class="row"> |
17 | <!-- We need the video container for videojs so we just hide it --> | 2 | <!-- We need the video container for videojs so we just hide it --> |
18 | <div [hidden]="videoNotFound" class="embed-responsive embed-responsive-19by9"> | 3 | <div [hidden]="videoNotFound" id="video-container"> |
19 | <video id="video-container" class="video-js vjs-sublime-skin"></video> | 4 | <video id="video-element" class="video-js vjs-peertube-skin vjs-fluid"></video> |
20 | </div> | 5 | </div> |
21 | 6 | ||
22 | <div *ngIf="videoNotFound" id="video-not-found">Video not found :'(</div> | 7 | <div *ngIf="videoNotFound" id="video-not-found">Video not found :'(</div> |
23 | </div> | ||
24 | |||
25 | <!-- P2P information --> | ||
26 | <div id="torrent-info" class="row"> | ||
27 | <div id="torrent-info-download" class="col-md-4 col-sm-4 col-xs-4">Download: {{ downloadSpeed | bytes }}/s</div> | ||
28 | <div id="torrent-info-upload" class="col-md-4 col-sm-4 col-xs-4">Upload: {{ uploadSpeed | bytes }}/s</div> | ||
29 | <div id="torrent-info-peers" class="col-md-4 col-sm-4 col-xs-4">Number of peers: {{ numPeers }}</div> | ||
30 | </div> | ||
31 | |||
32 | <!-- Video information --> | ||
33 | <div *ngIf="video !== null" id="video-info"> | ||
34 | <div class="row video-name-views"> | ||
35 | <div class="col-xs-8 col-md-8 video-name"> | ||
36 | {{ video.name }} | ||
37 | </div> | ||
38 | |||
39 | <div class="col-xs-4 col-md-4 pull-right video-views"> | ||
40 | {{ video.views}} views | ||
41 | </div> | ||
42 | </div> | ||
43 | |||
44 | <div class="row video-small-blocks"> | ||
45 | <div class="col-xs-5 col-xs-3 col-md-3 video-small-block video-small-block-account"> | ||
46 | <a class="option" title="Access to all videos of this user" [routerLink]="['/videos/list', { field: 'account', search: video.account }]"> | ||
47 | <span class="glyphicon glyphicon-user"></span> | ||
48 | <span class="video-small-block-text">{{ video.by }}</span> | ||
49 | </a> | ||
50 | </div> | ||
51 | |||
52 | <div class="col-xs-2 col-md-3 video-small-block video-small-block-share"> | ||
53 | <a class="option" (click)="showShareModal()" title="Share the video"> | ||
54 | <span class="glyphicon glyphicon-share"></span> | ||
55 | <span class="hidden-xs video-small-block-text">Share</span> | ||
56 | </a> | ||
57 | </div> | ||
58 | 8 | ||
59 | <div class="col-xs-2 col-md-3 video-small-block video-small-block-more"> | 9 | <!-- Video information --> |
60 | <div class="video-small-block-dropdown" dropdown dropup="true" placement="right"> | 10 | <div *ngIf="video" class="margin-content video-bottom"> |
61 | <a class="option" title="Access to more options" dropdownToggle> | 11 | <div class="video-info"> |
62 | <span class="glyphicon glyphicon-option-horizontal"></span> | 12 | <div class="video-info-name-actions"> |
63 | <span class="hidden-xs video-small-block-text">More</span> | 13 | <div class="video-info-name">{{ video.name }}</div> |
64 | </a> | 14 | |
65 | 15 | <div class="video-info-actions"> | |
66 | <ul *dropdownMenu class="dropdown-menu" id="more-menu" role="menu" aria-labelledby="single-button"> | 16 | <div *ngIf="isUserLoggedIn()" [ngClass]="{ 'activated': userRating === 'like' }" class="action-button"> |
67 | <li *ngIf="canUserUpdateVideo()" role="menuitem"> | 17 | <span class="icon icon-like" title="Like this video" (click)="setLike()"></span> |
68 | <a class="dropdown-item" title="Update this video" href="#" [routerLink]="[ '/videos/edit', video.uuid ]"> | 18 | </div> |
69 | <span class="glyphicon glyphicon-pencil"></span> Update | 19 | |
70 | </a> | 20 | <div *ngIf="isUserLoggedIn()" [ngClass]="{ 'activated': userRating === 'dislike' }" class="action-button"> |
71 | </li> | 21 | <span class="icon icon-dislike" title="Dislike this video" (click)="setDislike()"></span> |
72 | 22 | </div> | |
73 | <li role="menuitem"> | 23 | |
74 | <a class="dropdown-item" title="Download the video" href="#" (click)="showDownloadModal($event)"> | 24 | <div (click)="showShareModal()" class="action-button"> |
75 | <span class="glyphicon glyphicon-download-alt"></span> Download | 25 | <span class="icon icon-share"></span> |
76 | </a> | 26 | Share |
77 | </li> | 27 | </div> |
78 | 28 | ||
79 | <li *ngIf="isUserLoggedIn()" role="menuitem"> | 29 | <div class="action-more" dropdown dropup="true" placement="right"> |
80 | <a class="dropdown-item" title="Report this video" href="#" (click)="showReportModal($event)"> | 30 | <div class="action-button" dropdownToggle> |
81 | <span class="glyphicon glyphicon-alert"></span> Report | 31 | <span class="icon icon-more"></span> |
82 | </a> | 32 | </div> |
83 | </li> | 33 | |
84 | 34 | <ul *dropdownMenu class="dropdown-menu" id="more-menu" role="menu" aria-labelledby="single-button"> | |
85 | <li *ngIf="isVideoRemovable()" role="menuitem"> | 35 | <li role="menuitem"> |
86 | <a class="dropdown-item" title="Delete this video" href="#" (click)="removeVideo($event)"> | 36 | <a class="dropdown-item" title="Download the video" href="#" (click)="showDownloadModal($event)"> |
87 | <span class="glyphicon glyphicon-remove"></span> Delete | 37 | <span class="icon icon-download"></span> Download |
88 | </a> | 38 | </a> |
89 | </li> | 39 | </li> |
90 | 40 | ||
91 | <li *ngIf="isVideoBlacklistable()" role="menuitem"> | 41 | <li *ngIf="isUserLoggedIn()" role="menuitem"> |
92 | <a class="dropdown-item" title="Blacklist this video" href="#" (click)="blacklistVideo($event)"> | 42 | <a class="dropdown-item" title="Report this video" href="#" (click)="showReportModal($event)"> |
93 | <span class="glyphicon glyphicon-eye-close"></span> Blacklist | 43 | <span class="icon icon-alert"></span> Report |
94 | </a> | 44 | </a> |
95 | </li> | 45 | </li> |
96 | </ul> | 46 | |
47 | <li *ngIf="isVideoBlacklistable()" role="menuitem"> | ||
48 | <a class="dropdown-item" title="Blacklist this video" href="#" (click)="blacklistVideo($event)"> | ||
49 | <span class="icon icon-blacklist"></span> Blacklist | ||
50 | </a> | ||
51 | </li> | ||
52 | </ul> | ||
53 | </div> | ||
54 | </div> | ||
97 | </div> | 55 | </div> |
98 | </div> | ||
99 | 56 | ||
100 | <div class="col-xs-3 col-md-3 video-small-block video-small-block-rating"> | 57 | <div class="video-info-date-views-bar"> |
101 | <div class="video-small-block-like"> | 58 | <div class="video-info-date-views"> |
102 | <span | 59 | {{ video.createdAt | myFromNow }} - {{ video.views | myNumberFormatter }} views |
103 | class="glyphicon glyphicon-thumbs-up" title="Like this video" | 60 | </div> |
104 | [ngClass]="{ 'interactive': isUserLoggedIn(), 'activated': userRating === 'like' }" (click)="setLike()" | ||
105 | ></span> | ||
106 | 61 | ||
107 | <span class="video-small-block-text"> | 62 | <div *ngIf="video.likes !== 0 || video.dislikes !== 0" class="video-info-likes-dislikes-bar"> |
108 | {{ video.likes }} | 63 | <div class="likes-bar" [ngStyle]="{ 'width.%': video.likesPercent }"></div> |
109 | </span> | 64 | </div> |
110 | </div> | 65 | </div> |
111 | 66 | ||
112 | <div class="video-small-block-dislike"> | 67 | <div class="video-info-channel"> |
113 | <span | 68 | {{ video.channel.name }} |
114 | class="glyphicon glyphicon-thumbs-down" title="Dislike this video" | 69 | <!-- Here will be the subscribe button --> |
115 | [ngClass]="{ 'interactive': isUserLoggedIn(), 'activated': userRating === 'dislike' }" (click)="setDislike()" | ||
116 | ></span> | ||
117 | |||
118 | <span class="video-small-block-text"> | ||
119 | {{ video.dislikes }} | ||
120 | </span> | ||
121 | </div> | 70 | </div> |
122 | </div> | ||
123 | </div> | ||
124 | 71 | ||
125 | <div class="row video-details"> | 72 | <div class="video-info-by"> |
126 | <div class="video-details-date-description col-xs-8 col-md-9"> | 73 | By {{ video.by }} |
127 | <div class="video-details-date"> | 74 | <img [src]="getAvatarPath()" alt="Account avatar" /> |
128 | Published on {{ video.createdAt | date:'short' }} | ||
129 | </div> | 75 | </div> |
130 | 76 | ||
131 | <div class="video-details-description" [innerHTML]="videoHTMLDescription"></div> | 77 | <div class="video-info-description"> |
78 | <div class="video-info-description-html" [innerHTML]="videoHTMLDescription"></div> | ||
132 | 79 | ||
133 | <div class="video-details-description-more" *ngIf="completeDescriptionShown === false && video.description.length === 250" (click)="showMoreDescription()"> | 80 | <div class="video-info-description-more" *ngIf="completeDescriptionShown === false && video.description?.length === 250" (click)="showMoreDescription()"> |
134 | Show more | 81 | Show more |
135 | <span *ngIf="descriptionLoading === false" class="glyphicon glyphicon-menu-down"></span> | 82 | <span *ngIf="descriptionLoading === false" class="glyphicon glyphicon-menu-down"></span> |
136 | <my-loader class="description-loading" [loading]="descriptionLoading"></my-loader> | 83 | <my-loader class="description-loading" [loading]="descriptionLoading"></my-loader> |
137 | </div> | 84 | </div> |
138 | 85 | ||
139 | <div *ngIf="completeDescriptionShown === true" (click)="showLessDescription()" class="video-details-description-more"> | 86 | <div *ngIf="completeDescriptionShown === true" (click)="showLessDescription()" class="video-info-description-more"> |
140 | Show less | 87 | Show less |
141 | <span *ngIf="descriptionLoading === false" class="glyphicon glyphicon-menu-up"></span> | 88 | <span *ngIf="descriptionLoading === false" class="glyphicon glyphicon-menu-up"></span> |
89 | </div> | ||
142 | </div> | 90 | </div> |
143 | </div> | ||
144 | 91 | ||
145 | <div class="video-details-attributes col-xs-4 col-md-3"> | 92 | <div class="video-attributes"> |
146 | <div class="video-details-attribute"> | 93 | <div class="video-attribute"> |
147 | <span class="video-details-attribute-label"> | 94 | <span class="video-attribute-label"> |
148 | Privacy: | 95 | Privacy |
149 | </span> | 96 | </span> |
150 | <span class="video-details-attribute-value"> | 97 | <span class="video-attribute-value"> |
151 | {{ video.privacyLabel }} | 98 | {{ video.privacyLabel }} |
152 | </span> | 99 | </span> |
153 | </div> | 100 | </div> |
154 | 101 | ||
155 | <div class="video-details-attribute"> | 102 | <div class="video-attribute"> |
156 | <span class="video-details-attribute-label"> | 103 | <span class="video-attribute-label"> |
157 | Category: | 104 | Category |
158 | </span> | 105 | </span> |
159 | <span class="video-details-attribute-value"> | 106 | <span class="video-attribute-value"> |
160 | {{ video.categoryLabel }} | 107 | {{ video.categoryLabel }} |
161 | </span> | 108 | </span> |
162 | </div> | 109 | </div> |
163 | 110 | ||
164 | <div class="video-details-attribute"> | 111 | <div class="video-attribute"> |
165 | <span class="video-details-attribute-label"> | 112 | <span class="video-attribute-label"> |
166 | Licence: | 113 | Licence |
167 | </span> | 114 | </span> |
168 | <span class="video-details-attribute-value"> | 115 | <span class="video-attribute-value"> |
169 | {{ video.licenceLabel }} | 116 | {{ video.licenceLabel }} |
170 | </span> | 117 | </span> |
171 | </div> | 118 | </div> |
172 | 119 | ||
173 | <div class="video-details-attribute"> | 120 | <div class="video-attribute"> |
174 | <span class="video-details-attribute-label"> | 121 | <span class="video-attribute-label"> |
175 | Language: | 122 | Language |
176 | </span> | 123 | </span> |
177 | <span class="video-details-attribute-value"> | 124 | <span class="video-attribute-value"> |
178 | {{ video.languageLabel }} | 125 | {{ video.languageLabel }} |
179 | </span> | 126 | </span> |
180 | </div> | 127 | </div> |
181 | 128 | ||
182 | <div class="video-details-attribute"> | 129 | <div class="video-attribute"> |
183 | <span class="video-details-attribute-label"> | 130 | <span class="video-attribute-label"> |
184 | Tags: | 131 | Tags |
185 | </span> | 132 | </span> |
186 | 133 | ||
187 | <div class="video-details-tags"> | 134 | <span class="video-attribute-value"> |
188 | <a *ngFor="let tag of video.tags" [routerLink]="['/videos/list', { field: 'tags', search: tag }]" class="label label-primary"> | 135 | {{ getVideoTags() }} |
189 | {{ tag }} | 136 | </span> |
190 | </a> | ||
191 | </div> | 137 | </div> |
192 | </div> | 138 | </div> |
193 | 139 | ||
194 | </div> | 140 | </div> |
141 | |||
142 | <div class="other-videos"> | ||
143 | <div class="title-page title-page-single"> | ||
144 | Other videos | ||
145 | </div> | ||
146 | |||
147 | <div *ngFor="let video of otherVideos"> | ||
148 | <my-video-miniature [video]="video" [user]="user"></my-video-miniature> | ||
149 | </div> | ||
150 | </div> | ||
195 | </div> | 151 | </div> |
196 | </div> | 152 | </div> |
197 | 153 | ||
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 cad21dd18..9daa757b4 100644 --- a/client/src/app/videos/+video-watch/video-watch.component.scss +++ b/client/src/app/videos/+video-watch/video-watch.component.scss | |||
@@ -1,6 +1,22 @@ | |||
1 | #video-container { | 1 | #video-container { |
2 | width: 100%; | 2 | background-color: #000; |
3 | height: 100%; | 3 | display: flex; |
4 | justify-content: center; | ||
5 | |||
6 | #video-element { | ||
7 | width: 888px; | ||
8 | height: 500px; | ||
9 | |||
10 | @media screen and (max-width: 800px) { | ||
11 | height: auto; | ||
12 | } | ||
13 | |||
14 | // VideoJS create an inner video player | ||
15 | video { | ||
16 | outline: 0; | ||
17 | position: relative !important; | ||
18 | } | ||
19 | } | ||
4 | } | 20 | } |
5 | 21 | ||
6 | #video-not-found { | 22 | #video-not-found { |
@@ -11,175 +27,153 @@ | |||
11 | font-weight: bold; | 27 | font-weight: bold; |
12 | } | 28 | } |
13 | 29 | ||
14 | .embed-responsive { | 30 | .video-bottom { |
15 | height: 500px; | 31 | margin-top: 40px; |
32 | display: flex; | ||
16 | 33 | ||
17 | @media screen and (max-width: 600px) { | 34 | .video-info { |
18 | height: 300px; | 35 | flex-grow: 1; |
19 | } | 36 | margin-right: 28px; |
20 | } | ||
21 | 37 | ||
22 | #torrent-info { | 38 | .video-info-name-actions { |
23 | font-size: 10px; | 39 | display: flex; |
24 | margin-top: 10px; | 40 | align-items: center; |
25 | text-align: center; | ||
26 | |||
27 | div { | ||
28 | min-width: 60px; | ||
29 | } | ||
30 | } | ||
31 | |||
32 | #video-info { | ||
33 | .video-name-views { | ||
34 | font-weight: bold; | ||
35 | font-size: 18px; | ||
36 | min-height: $video-watch-title-height; | ||
37 | display: flex; | ||
38 | align-items: center; | ||
39 | |||
40 | .video-name { | ||
41 | padding-left: $video-watch-info-padding-left; | ||
42 | } | ||
43 | 41 | ||
44 | .video-views { | 42 | .video-info-name { |
45 | text-align: right; | 43 | font-size: 27px; |
46 | // Keep a symmetry with the video name | 44 | font-weight: $font-semibold; |
47 | padding-right: $video-watch-info-padding-left | 45 | flex-grow: 1; |
48 | } | 46 | } |
49 | 47 | ||
50 | } | 48 | .video-info-actions { |
49 | .action-button { | ||
50 | @include peertube-button; | ||
51 | @include grey-button; | ||
51 | 52 | ||
52 | .video-small-blocks { | 53 | font-size: 15px; |
53 | height: $video-watch-info-height; | 54 | font-weight: $font-semibold; |
54 | color: $video-watch-info-color; | 55 | display: inline-block; |
55 | border-color: $video-watch-border-color; | 56 | padding: 0 10px 0 10px; |
56 | border-width: 1px 0px; | ||
57 | border-style: solid; | ||
58 | 57 | ||
59 | .video-small-block { | 58 | .icon { |
60 | height: $video-watch-info-height; | 59 | @include icon(21px); |
61 | display: flex; | ||
62 | flex-direction: column; | ||
63 | justify-content: center; | ||
64 | text-align: center; | ||
65 | 60 | ||
66 | a { | 61 | position: relative; |
67 | cursor: pointer; | 62 | top: -2px; |
68 | transition: color 0.3s; | ||
69 | white-space: nowrap; | ||
70 | overflow: hidden; | ||
71 | text-overflow: ellipsis; | ||
72 | |||
73 | &, &:hover { | ||
74 | color: inherit; | ||
75 | text-decoration:none; | ||
76 | } | ||
77 | 63 | ||
78 | &:hover { | 64 | &.icon-like { |
79 | color: #000 !important; | 65 | background-image: url('../../../assets/images/video/like-grey.svg'); |
80 | } | 66 | } |
81 | 67 | ||
82 | &:hover > .glyphicon { | 68 | &.icon-dislike { |
83 | opacity: 1 !important; | 69 | background-image: url('../../../assets/images/video/dislike-grey.svg'); |
84 | } | 70 | } |
85 | } | ||
86 | 71 | ||
87 | .option .glyphicon { | 72 | &.icon-share { |
88 | font-size: 22px; | 73 | background-image: url('../../../assets/images/video/share.svg'); |
89 | color: inherit; | 74 | } |
90 | opacity: 0.15; | ||
91 | margin-bottom: 10px; | ||
92 | transition: opacity 0.3s; | ||
93 | } | ||
94 | 75 | ||
95 | .video-small-block-text { | 76 | &.icon-more { |
96 | font-size: 15px; | 77 | background-image: url('../../../assets/images/video/more.svg'); |
97 | font-weight: bold; | 78 | top: -1px; |
98 | } | 79 | } |
99 | } | 80 | } |
100 | 81 | ||
101 | .video-small-block:not(:last-child) { | 82 | &.activated { |
102 | border-width: 0 1px 0 0; | 83 | @include orange-button; |
103 | border-color: $video-watch-border-color; | ||
104 | border-style: solid; | ||
105 | } | ||
106 | 84 | ||
107 | .video-small-block-account, .video-small-block-more { | 85 | .icon-like { |
108 | a.option { | 86 | background-image: url('../../../assets/images/video/like-white.svg'); |
109 | display: block; | 87 | } |
110 | 88 | ||
111 | .glyphicon { | 89 | .icon-dislike { |
112 | display: block; | 90 | background-image: url('../../../assets/images/video/dislike-white.svg'); |
91 | } | ||
92 | } | ||
113 | } | 93 | } |
114 | } | ||
115 | } | ||
116 | 94 | ||
117 | .video-small-block-share, .video-small-block-more { | 95 | .action-more { |
118 | a.option { | 96 | display: inline-block; |
119 | display: block; | 97 | |
120 | 98 | .dropdown-menu .icon { | |
121 | .glyphicon { | 99 | display: inline-block; |
122 | display: block; | 100 | background-repeat: no-repeat; |
101 | background-size: contain; | ||
102 | width: 21px; | ||
103 | height: 21px; | ||
104 | vertical-align: middle; | ||
105 | margin-right: 5px; | ||
106 | position: relative; | ||
107 | top: -1px; | ||
108 | |||
109 | &.icon-download { | ||
110 | background-image: url('../../../assets/images/video/download-grey.svg'); | ||
111 | } | ||
112 | |||
113 | &.icon-alert { | ||
114 | background-image: url('../../../assets/images/video/alert.svg'); | ||
115 | } | ||
116 | |||
117 | &.icon-blacklist { | ||
118 | background-image: url('../../../assets/images/video/eye-closed.svg'); | ||
119 | } | ||
120 | } | ||
123 | } | 121 | } |
124 | } | 122 | } |
125 | } | 123 | } |
126 | 124 | ||
127 | .video-small-block-more .video-small-block-dropdown { | 125 | .video-info-date-views-bar { |
128 | position: relative; | 126 | display: flex; |
129 | |||
130 | .dropdown-item .glyphicon { | ||
131 | margin-right: 5px; | ||
132 | } | ||
133 | } | ||
134 | |||
135 | .video-small-block-rating { | ||
136 | 127 | ||
137 | .video-small-block-like { | 128 | .video-info-date-views { |
129 | font-size: 16px; | ||
138 | margin-bottom: 10px; | 130 | margin-bottom: 10px; |
131 | flex-grow: 1; | ||
139 | } | 132 | } |
140 | 133 | ||
141 | .video-small-block-text { | 134 | .video-info-likes-dislikes-bar { |
142 | vertical-align: top; | 135 | height: 5px; |
143 | } | 136 | width: 186px; |
137 | background-color: #E5E5E5; | ||
138 | margin-top: 25px; | ||
144 | 139 | ||
145 | .glyphicon { | 140 | .likes-bar { |
146 | font-size: 18px; | 141 | height: 100%; |
147 | margin: 0 10px 0 0; | 142 | background-color: #39CC0B; |
148 | opacity: 0.3; | 143 | } |
149 | } | 144 | } |
145 | } | ||
150 | 146 | ||
151 | .interactive { | 147 | .video-info-channel { |
152 | cursor: pointer; | 148 | font-weight: $font-semibold; |
153 | transition: opacity, color 0.3s; | 149 | font-size: 15px; |
150 | } | ||
154 | 151 | ||
155 | &.activated, &:hover { | 152 | .video-info-by { |
156 | opacity: 1; | 153 | display: flex; |
157 | color: #000; | 154 | align-items: center; |
158 | } | 155 | font-size: 13px; |
156 | |||
157 | img { | ||
158 | width: 16px; | ||
159 | height: 16px; | ||
160 | margin-left: 3px; | ||
159 | } | 161 | } |
160 | } | 162 | } |
161 | } | ||
162 | 163 | ||
163 | .video-details { | 164 | .video-info-description { |
164 | margin-top: 30px; | 165 | margin: 20px 0; |
165 | 166 | font-size: 15px; | |
166 | .video-details-date-description { | ||
167 | padding-left: $video-watch-info-padding-left; | ||
168 | 167 | ||
169 | .description-loading { | 168 | .description-loading { |
170 | display: inline-block; | 169 | display: inline-block; |
171 | } | 170 | } |
172 | 171 | ||
173 | .video-details-date { | 172 | .video-info-description-more { |
174 | font-weight: bold; | ||
175 | margin-bottom: 30px; | ||
176 | } | ||
177 | |||
178 | .video-details-description-more { | ||
179 | cursor: pointer; | 173 | cursor: pointer; |
180 | margin-top: 15px; | 174 | font-weight: $font-semibold; |
181 | font-weight: bold; | 175 | color: #585858; |
182 | color: #acaeb7; | 176 | font-size: 14px; |
183 | 177 | ||
184 | .glyphicon { | 178 | .glyphicon { |
185 | position: relative; | 179 | position: relative; |
@@ -188,109 +182,68 @@ | |||
188 | } | 182 | } |
189 | } | 183 | } |
190 | 184 | ||
191 | .video-details-attributes { | 185 | .video-attributes { |
192 | font-weight: bold; | 186 | .video-attribute { |
193 | font-size: 12px; | 187 | font-size: 13px; |
194 | 188 | display: block; | |
195 | .video-details-attribute { | 189 | margin-bottom: 12px; |
196 | display: flex; | ||
197 | 190 | ||
198 | .video-details-attribute-label { | 191 | .video-attribute-label { |
199 | color: $video-watch-info-color; | 192 | width: 86px; |
200 | flex-basis: 60px; | 193 | display: inline-block; |
201 | flex-grow: 0; | 194 | color: #585858; |
202 | flex-shrink: 0; | 195 | font-weight: $font-bold; |
203 | margin-right: 5px; | ||
204 | } | 196 | } |
205 | } | 197 | } |
206 | } | 198 | } |
207 | |||
208 | .video-details-tags { | ||
209 | display: flex; | ||
210 | flex-wrap: wrap; | ||
211 | |||
212 | a { | ||
213 | margin: 0 3px 3px 0; | ||
214 | font-size: 11px; | ||
215 | } | ||
216 | } | ||
217 | } | 199 | } |
218 | 200 | ||
219 | @media screen and (max-width: 800px) { | 201 | .other-videos { |
220 | .video-name-views { | 202 | .title-page { |
221 | .video-name { | 203 | margin-top: 0; |
222 | padding-left: 5px; | ||
223 | padding-right: 0px; | ||
224 | } | ||
225 | |||
226 | .video-views { | ||
227 | padding-left: 0px; | ||
228 | padding-right: 5px; | ||
229 | } | ||
230 | } | 204 | } |
231 | 205 | ||
232 | .video-small-blocks { | 206 | /deep/ .video-miniature { |
233 | a, .video-small-block-text { | 207 | display: flex; |
234 | font-size: 13px !important; | 208 | height: 100%; |
235 | } | 209 | margin-bottom: 20px; |
236 | |||
237 | .glyphicon { | ||
238 | font-size: 18px !important; | ||
239 | } | ||
240 | 210 | ||
241 | .video-small-block-account { | 211 | .video-miniature-information { |
242 | padding-left: 10px; | 212 | margin-left: 10px; |
243 | padding-right: 10px; | ||
244 | } | 213 | } |
245 | } | 214 | } |
215 | } | ||
216 | } | ||
246 | 217 | ||
247 | .video-details { | ||
248 | .video-details-date-description { | ||
249 | padding-left: 10px; | ||
250 | font-size: 13px !important; | ||
251 | } | ||
252 | |||
253 | .video-details-attributes { | ||
254 | font-size: 11px !important; | ||
255 | 218 | ||
256 | .video-details-attribute-label { | 219 | @media screen and (max-width: 1000px) { |
257 | width: 50px; | 220 | .other-videos { |
258 | } | 221 | display: none; |
259 | } | ||
260 | } | ||
261 | } | 222 | } |
223 | } | ||
262 | 224 | ||
263 | @media screen and (max-width: 500px) { | 225 | @media screen and (max-width: 800px) { |
264 | .video-name-views { | 226 | .video-bottom { |
265 | font-size: 16px !important; | 227 | margin: 20px 0 0 0; |
266 | } | ||
267 | 228 | ||
268 | // Keep the same hierarchy than max-width: 800px | 229 | .video-info { |
269 | .video-small-blocks { | 230 | margin-right: 0; |
270 | a, .video-small-block-text { | ||
271 | font-size: 10px !important; | ||
272 | } | ||
273 | 231 | ||
274 | .video-small-block-account { | 232 | .video-info-name-actions { |
275 | padding-left: 5px; | 233 | align-items: left; |
276 | padding-right: 5px; | 234 | flex-direction: column; |
235 | margin-bottom: 30px; | ||
277 | } | 236 | } |
278 | } | ||
279 | 237 | ||
280 | .video-details { | 238 | .video-info-date-views-bar { |
281 | .video-details-date-description { | 239 | align-items: left; |
240 | flex-direction: column; | ||
282 | margin-bottom: 30px; | 241 | margin-bottom: 30px; |
283 | width: 100%; | ||
284 | 242 | ||
285 | .video-details-date { | 243 | .video-info-likes-dislikes-bar { |
286 | margin-bottom: 15px; | 244 | margin-top: 0; |
287 | } | 245 | } |
288 | } | 246 | } |
289 | |||
290 | .video-details-attributes { | ||
291 | padding-left: 10px; | ||
292 | padding-right: 10px; | ||
293 | } | ||
294 | } | 247 | } |
295 | } | 248 | } |
296 | } | 249 | } |
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 b26f3092f..d4e3ec014 100644 --- a/client/src/app/videos/+video-watch/video-watch.component.ts +++ b/client/src/app/videos/+video-watch/video-watch.component.ts | |||
@@ -2,6 +2,7 @@ import { Component, ElementRef, OnDestroy, OnInit, ViewChild } from '@angular/co | |||
2 | import { ActivatedRoute, Router } from '@angular/router' | 2 | import { ActivatedRoute, Router } from '@angular/router' |
3 | import { MetaService } from '@ngx-meta/core' | 3 | import { MetaService } from '@ngx-meta/core' |
4 | import { NotificationsService } from 'angular2-notifications' | 4 | import { NotificationsService } from 'angular2-notifications' |
5 | import { VideoService } from 'app/shared/video/video.service' | ||
5 | import { Observable } from 'rxjs/Observable' | 6 | import { Observable } from 'rxjs/Observable' |
6 | import { Subscription } from 'rxjs/Subscription' | 7 | import { Subscription } from 'rxjs/Subscription' |
7 | import videojs from 'video.js' | 8 | import videojs from 'video.js' |
@@ -9,7 +10,10 @@ import { UserVideoRateType, VideoRateType } from '../../../../../shared' | |||
9 | import '../../../assets/player/peertube-videojs-plugin' | 10 | import '../../../assets/player/peertube-videojs-plugin' |
10 | import { AuthService, ConfirmService } from '../../core' | 11 | import { AuthService, ConfirmService } from '../../core' |
11 | import { VideoBlacklistService } from '../../shared' | 12 | import { VideoBlacklistService } from '../../shared' |
12 | import { MarkdownService, VideoDetails, VideoService } from '../shared' | 13 | import { Account } from '../../shared/account/account.model' |
14 | import { VideoDetails } from '../../shared/video/video-details.model' | ||
15 | import { Video } from '../../shared/video/video.model' | ||
16 | import { MarkdownService } from '../shared' | ||
13 | import { VideoDownloadComponent } from './video-download.component' | 17 | import { VideoDownloadComponent } from './video-download.component' |
14 | import { VideoReportComponent } from './video-report.component' | 18 | import { VideoReportComponent } from './video-report.component' |
15 | import { VideoShareComponent } from './video-share.component' | 19 | import { VideoShareComponent } from './video-share.component' |
@@ -24,13 +28,12 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
24 | @ViewChild('videoShareModal') videoShareModal: VideoShareComponent | 28 | @ViewChild('videoShareModal') videoShareModal: VideoShareComponent |
25 | @ViewChild('videoReportModal') videoReportModal: VideoReportComponent | 29 | @ViewChild('videoReportModal') videoReportModal: VideoReportComponent |
26 | 30 | ||
27 | downloadSpeed: number | 31 | otherVideos: Video[] = [] |
32 | |||
28 | error = false | 33 | error = false |
29 | loading = false | 34 | loading = false |
30 | numPeers: number | ||
31 | player: videojs.Player | 35 | player: videojs.Player |
32 | playerElement: HTMLMediaElement | 36 | playerElement: HTMLMediaElement |
33 | uploadSpeed: number | ||
34 | userRating: UserVideoRateType = null | 37 | userRating: UserVideoRateType = null |
35 | video: VideoDetails = null | 38 | video: VideoDetails = null |
36 | videoPlayerLoaded = false | 39 | videoPlayerLoaded = false |
@@ -58,6 +61,13 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
58 | ) {} | 61 | ) {} |
59 | 62 | ||
60 | ngOnInit () { | 63 | ngOnInit () { |
64 | this.videoService.getVideos({ currentPage: 1, itemsPerPage: 5 }, '-createdAt') | ||
65 | .subscribe( | ||
66 | data => this.otherVideos = data.videos, | ||
67 | |||
68 | err => console.error(err) | ||
69 | ) | ||
70 | |||
61 | this.paramsSub = this.route.params.subscribe(routeParams => { | 71 | this.paramsSub = this.route.params.subscribe(routeParams => { |
62 | let uuid = routeParams['uuid'] | 72 | let uuid = routeParams['uuid'] |
63 | this.videoService.getVideo(uuid).subscribe( | 73 | this.videoService.getVideo(uuid).subscribe( |
@@ -115,27 +125,6 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
115 | ) | 125 | ) |
116 | } | 126 | } |
117 | 127 | ||
118 | removeVideo (event: Event) { | ||
119 | event.preventDefault() | ||
120 | |||
121 | this.confirmService.confirm('Do you really want to delete this video?', 'Delete').subscribe( | ||
122 | res => { | ||
123 | if (res === false) return | ||
124 | |||
125 | this.videoService.removeVideo(this.video.id) | ||
126 | .subscribe( | ||
127 | status => { | ||
128 | this.notificationsService.success('Success', `Video ${this.video.name} deleted.`) | ||
129 | // Go back to the video-list. | ||
130 | this.router.navigate(['/videos/list']) | ||
131 | }, | ||
132 | |||
133 | error => this.notificationsService.error('Error', error.text) | ||
134 | ) | ||
135 | } | ||
136 | ) | ||
137 | } | ||
138 | |||
139 | blacklistVideo (event: Event) { | 128 | blacklistVideo (event: Event) { |
140 | event.preventDefault() | 129 | event.preventDefault() |
141 | 130 | ||
@@ -166,7 +155,6 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
166 | } | 155 | } |
167 | 156 | ||
168 | showLessDescription () { | 157 | showLessDescription () { |
169 | |||
170 | this.updateVideoDescription(this.shortVideoDescription) | 158 | this.updateVideoDescription(this.shortVideoDescription) |
171 | this.completeDescriptionShown = false | 159 | this.completeDescriptionShown = false |
172 | } | 160 | } |
@@ -211,16 +199,18 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
211 | return this.authService.isLoggedIn() | 199 | return this.authService.isLoggedIn() |
212 | } | 200 | } |
213 | 201 | ||
214 | canUserUpdateVideo () { | 202 | isVideoBlacklistable () { |
215 | return this.video.isUpdatableBy(this.authService.getUser()) | 203 | return this.video.isBlackistableBy(this.authService.getUser()) |
216 | } | 204 | } |
217 | 205 | ||
218 | isVideoRemovable () { | 206 | getAvatarPath () { |
219 | return this.video.isRemovableBy(this.authService.getUser()) | 207 | return Account.GET_ACCOUNT_AVATAR_PATH(this.video.account) |
220 | } | 208 | } |
221 | 209 | ||
222 | isVideoBlacklistable () { | 210 | getVideoTags () { |
223 | return this.video.isBlackistableBy(this.authService.getUser()) | 211 | if (!this.video || Array.isArray(this.video.tags) === false) return [] |
212 | |||
213 | return this.video.tags.join(', ') | ||
224 | } | 214 | } |
225 | 215 | ||
226 | private updateVideoDescription (description: string) { | 216 | private updateVideoDescription (description: string) { |
@@ -229,6 +219,11 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
229 | } | 219 | } |
230 | 220 | ||
231 | private setVideoDescriptionHTML () { | 221 | private setVideoDescriptionHTML () { |
222 | if (!this.video.description) { | ||
223 | this.videoHTMLDescription = '' | ||
224 | return | ||
225 | } | ||
226 | |||
232 | this.videoHTMLDescription = this.markdownService.markdownToHTML(this.video.description) | 227 | this.videoHTMLDescription = this.markdownService.markdownToHTML(this.video.description) |
233 | } | 228 | } |
234 | 229 | ||
@@ -281,7 +276,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
281 | return this.router.navigate([ '/videos/list' ]) | 276 | return this.router.navigate([ '/videos/list' ]) |
282 | } | 277 | } |
283 | 278 | ||
284 | this.playerElement = this.elementRef.nativeElement.querySelector('#video-container') | 279 | this.playerElement = this.elementRef.nativeElement.querySelector('#video-element') |
285 | 280 | ||
286 | const videojsOptions = { | 281 | const videojsOptions = { |
287 | controls: true, | 282 | controls: true, |
@@ -304,12 +299,6 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
304 | this.on('customError', (event, data) => { | 299 | this.on('customError', (event, data) => { |
305 | self.handleError(data.err) | 300 | self.handleError(data.err) |
306 | }) | 301 | }) |
307 | |||
308 | this.on('torrentInfo', (event, data) => { | ||
309 | self.downloadSpeed = data.downloadSpeed | ||
310 | self.numPeers = data.numPeers | ||
311 | self.uploadSpeed = data.uploadSpeed | ||
312 | }) | ||
313 | }) | 302 | }) |
314 | 303 | ||
315 | this.setVideoDescriptionHTML() | 304 | this.setVideoDescriptionHTML() |
diff --git a/client/src/app/videos/+video-watch/video-watch.module.ts b/client/src/app/videos/+video-watch/video-watch.module.ts index 1b983200d..0b1dd5c15 100644 --- a/client/src/app/videos/+video-watch/video-watch.module.ts +++ b/client/src/app/videos/+video-watch/video-watch.module.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | import { NgModule } from '@angular/core' | 1 | import { NgModule } from '@angular/core' |
2 | 2 | ||
3 | import { VideoWatchRoutingModule } from './video-watch-routing.module' | 3 | import { VideoWatchRoutingModule } from './video-watch-routing.module' |
4 | import { VideoService, MarkdownService } from '../shared' | 4 | import { MarkdownService } from '../shared' |
5 | import { SharedModule } from '../../shared' | 5 | import { SharedModule } from '../../shared' |
6 | 6 | ||
7 | import { VideoWatchComponent } from './video-watch.component' | 7 | import { VideoWatchComponent } from './video-watch.component' |
@@ -28,8 +28,7 @@ import { VideoDownloadComponent } from './video-download.component' | |||
28 | ], | 28 | ], |
29 | 29 | ||
30 | providers: [ | 30 | providers: [ |
31 | MarkdownService, | 31 | MarkdownService |
32 | VideoService | ||
33 | ] | 32 | ] |
34 | }) | 33 | }) |
35 | export class VideoWatchModule { } | 34 | export class VideoWatchModule { } |