diff options
5 files changed, 55 insertions, 11 deletions
diff --git a/client/src/app/+video-channels/video-channels.component.html b/client/src/app/+video-channels/video-channels.component.html index e5a32dc92..8d6f81e1b 100644 --- a/client/src/app/+video-channels/video-channels.component.html +++ b/client/src/app/+video-channels/video-channels.component.html | |||
@@ -9,7 +9,7 @@ | |||
9 | <div class="actor-display-name">{{ videoChannel.displayName }}</div> | 9 | <div class="actor-display-name">{{ videoChannel.displayName }}</div> |
10 | <div class="actor-name">{{ videoChannel.nameWithHost }}</div> | 10 | <div class="actor-name">{{ videoChannel.nameWithHost }}</div> |
11 | 11 | ||
12 | <my-subscribe-button *ngIf="isUserLoggedIn()" [videoChannel]="videoChannel"></my-subscribe-button> | 12 | <my-subscribe-button #subscribeButton *ngIf="isUserLoggedIn()" [videoChannel]="videoChannel"></my-subscribe-button> |
13 | </div> | 13 | </div> |
14 | <div i18n class="actor-followers">{{ videoChannel.followersCount }} subscribers</div> | 14 | <div i18n class="actor-followers">{{ videoChannel.followersCount }} subscribers</div> |
15 | 15 | ||
diff --git a/client/src/app/+video-channels/video-channels.component.ts b/client/src/app/+video-channels/video-channels.component.ts index ee2c86915..82b4a345e 100644 --- a/client/src/app/+video-channels/video-channels.component.ts +++ b/client/src/app/+video-channels/video-channels.component.ts | |||
@@ -1,4 +1,4 @@ | |||
1 | import { Component, OnDestroy, OnInit } from '@angular/core' | 1 | import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core' |
2 | import { ActivatedRoute } from '@angular/router' | 2 | import { ActivatedRoute } from '@angular/router' |
3 | import { VideoChannel } from '@app/shared/video-channel/video-channel.model' | 3 | import { VideoChannel } from '@app/shared/video-channel/video-channel.model' |
4 | import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' | 4 | import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' |
@@ -6,13 +6,18 @@ import { RestExtractor } from '@app/shared' | |||
6 | import { catchError, distinctUntilChanged, map, switchMap } from 'rxjs/operators' | 6 | import { catchError, distinctUntilChanged, map, switchMap } from 'rxjs/operators' |
7 | import { Subscription } from 'rxjs' | 7 | import { Subscription } from 'rxjs' |
8 | import { AuthService } from '@app/core' | 8 | import { AuthService } from '@app/core' |
9 | import { Hotkey, HotkeysService } from 'angular2-hotkeys' | ||
10 | import { SubscribeButtonComponent } from '@app/shared/user-subscription/subscribe-button.component' | ||
9 | 11 | ||
10 | @Component({ | 12 | @Component({ |
11 | templateUrl: './video-channels.component.html', | 13 | templateUrl: './video-channels.component.html', |
12 | styleUrls: [ './video-channels.component.scss' ] | 14 | styleUrls: [ './video-channels.component.scss' ] |
13 | }) | 15 | }) |
14 | export class VideoChannelsComponent implements OnInit, OnDestroy { | 16 | export class VideoChannelsComponent implements OnInit, OnDestroy { |
17 | @ViewChild('subscribeButton') subscribeButton: SubscribeButtonComponent | ||
18 | |||
15 | videoChannel: VideoChannel | 19 | videoChannel: VideoChannel |
20 | hotkeys: Hotkey[] | ||
16 | 21 | ||
17 | private routeSub: Subscription | 22 | private routeSub: Subscription |
18 | 23 | ||
@@ -20,7 +25,8 @@ export class VideoChannelsComponent implements OnInit, OnDestroy { | |||
20 | private route: ActivatedRoute, | 25 | private route: ActivatedRoute, |
21 | private authService: AuthService, | 26 | private authService: AuthService, |
22 | private videoChannelService: VideoChannelService, | 27 | private videoChannelService: VideoChannelService, |
23 | private restExtractor: RestExtractor | 28 | private restExtractor: RestExtractor, |
29 | private hotkeysService: HotkeysService | ||
24 | ) { } | 30 | ) { } |
25 | 31 | ||
26 | ngOnInit () { | 32 | ngOnInit () { |
@@ -33,10 +39,22 @@ export class VideoChannelsComponent implements OnInit, OnDestroy { | |||
33 | ) | 39 | ) |
34 | .subscribe(videoChannel => this.videoChannel = videoChannel) | 40 | .subscribe(videoChannel => this.videoChannel = videoChannel) |
35 | 41 | ||
42 | this.hotkeys = [ | ||
43 | new Hotkey('S', (event: KeyboardEvent): boolean => { | ||
44 | this.subscribeButton.subscribed ? | ||
45 | this.subscribeButton.unsubscribe() : | ||
46 | this.subscribeButton.subscribe() | ||
47 | return false | ||
48 | }, undefined, 'Subscribe to the account') | ||
49 | ] | ||
50 | if (this.isUserLoggedIn()) this.hotkeysService.add(this.hotkeys) | ||
36 | } | 51 | } |
37 | 52 | ||
38 | ngOnDestroy () { | 53 | ngOnDestroy () { |
39 | if (this.routeSub) this.routeSub.unsubscribe() | 54 | if (this.routeSub) this.routeSub.unsubscribe() |
55 | |||
56 | // Unbind hotkeys | ||
57 | if (this.isUserLoggedIn()) this.hotkeysService.remove(this.hotkeys) | ||
40 | } | 58 | } |
41 | 59 | ||
42 | isUserLoggedIn () { | 60 | isUserLoggedIn () { |
diff --git a/client/src/app/app.component.ts b/client/src/app/app.component.ts index 7bab2e2fd..40eac7fb8 100644 --- a/client/src/app/app.component.ts +++ b/client/src/app/app.component.ts | |||
@@ -128,27 +128,27 @@ export class AppComponent implements OnInit { | |||
128 | document.getElementById('search-video').focus() | 128 | document.getElementById('search-video').focus() |
129 | return false // Prevent bubbling | 129 | return false // Prevent bubbling |
130 | }, undefined, 'Focus the search bar'), | 130 | }, undefined, 'Focus the search bar'), |
131 | new Hotkey('g+s', (event: KeyboardEvent): boolean => { | 131 | new Hotkey('g s', (event: KeyboardEvent): boolean => { |
132 | this.router.navigate([ '/videos/subscriptions' ]) | 132 | this.router.navigate([ '/videos/subscriptions' ]) |
133 | return false | 133 | return false |
134 | }, undefined, 'Go to the subscriptions videos page'), | 134 | }, undefined, 'Go to the subscriptions videos page'), |
135 | new Hotkey('g+o', (event: KeyboardEvent): boolean => { | 135 | new Hotkey('g o', (event: KeyboardEvent): boolean => { |
136 | this.router.navigate([ '/videos/overview' ]) | 136 | this.router.navigate([ '/videos/overview' ]) |
137 | return false | 137 | return false |
138 | }, undefined, 'Go to the videos overview page'), | 138 | }, undefined, 'Go to the videos overview page'), |
139 | new Hotkey('g+t', (event: KeyboardEvent): boolean => { | 139 | new Hotkey('g t', (event: KeyboardEvent): boolean => { |
140 | this.router.navigate([ '/videos/trending' ]) | 140 | this.router.navigate([ '/videos/trending' ]) |
141 | return false | 141 | return false |
142 | }, undefined, 'Go to the trending videos page'), | 142 | }, undefined, 'Go to the trending videos page'), |
143 | new Hotkey('g+r', (event: KeyboardEvent): boolean => { | 143 | new Hotkey('g r', (event: KeyboardEvent): boolean => { |
144 | this.router.navigate([ '/videos/recently-added' ]) | 144 | this.router.navigate([ '/videos/recently-added' ]) |
145 | return false | 145 | return false |
146 | }, undefined, 'Go to the recently added videos page'), | 146 | }, undefined, 'Go to the recently added videos page'), |
147 | new Hotkey('g+l', (event: KeyboardEvent): boolean => { | 147 | new Hotkey('g l', (event: KeyboardEvent): boolean => { |
148 | this.router.navigate([ '/videos/local' ]) | 148 | this.router.navigate([ '/videos/local' ]) |
149 | return false | 149 | return false |
150 | }, undefined, 'Go to the local videos page'), | 150 | }, undefined, 'Go to the local videos page'), |
151 | new Hotkey('g+u', (event: KeyboardEvent): boolean => { | 151 | new Hotkey('g u', (event: KeyboardEvent): boolean => { |
152 | this.router.navigate([ '/videos/upload' ]) | 152 | this.router.navigate([ '/videos/upload' ]) |
153 | return false | 153 | return false |
154 | }, undefined, 'Go to the videos upload page') | 154 | }, undefined, 'Go to the videos upload page') |
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 7dbc96bf4..0f2f3cf11 100644 --- a/client/src/app/videos/+video-watch/video-watch.component.html +++ b/client/src/app/videos/+video-watch/video-watch.component.html | |||
@@ -125,7 +125,7 @@ | |||
125 | <img [src]="video.videoChannelAvatarUrl" alt="Video channel avatar" /> | 125 | <img [src]="video.videoChannelAvatarUrl" alt="Video channel avatar" /> |
126 | </a> | 126 | </a> |
127 | 127 | ||
128 | <my-subscribe-button *ngIf="isUserLoggedIn()" [videoChannel]="video.channel" size="small"></my-subscribe-button> | 128 | <my-subscribe-button #subscribeButton *ngIf="isUserLoggedIn()" [videoChannel]="video.channel" size="small"></my-subscribe-button> |
129 | </div> | 129 | </div> |
130 | 130 | ||
131 | <div class="video-info-by"> | 131 | <div class="video-info-by"> |
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 25643cfde..768a08d42 100644 --- a/client/src/app/videos/+video-watch/video-watch.component.ts +++ b/client/src/app/videos/+video-watch/video-watch.component.ts | |||
@@ -1,4 +1,4 @@ | |||
1 | import { catchError } from 'rxjs/operators' | 1 | import { catchError, subscribeOn } from 'rxjs/operators' |
2 | import { ChangeDetectorRef, Component, ElementRef, Inject, LOCALE_ID, NgZone, OnDestroy, OnInit, ViewChild } from '@angular/core' | 2 | import { ChangeDetectorRef, Component, ElementRef, Inject, LOCALE_ID, NgZone, OnDestroy, OnInit, ViewChild } from '@angular/core' |
3 | import { ActivatedRoute, Router } from '@angular/router' | 3 | import { ActivatedRoute, Router } from '@angular/router' |
4 | import { RedirectService } from '@app/core/routing/redirect.service' | 4 | import { RedirectService } from '@app/core/routing/redirect.service' |
@@ -9,6 +9,7 @@ import { NotificationsService } from 'angular2-notifications' | |||
9 | import { forkJoin, Subscription } from 'rxjs' | 9 | import { forkJoin, Subscription } from 'rxjs' |
10 | import * as videojs from 'video.js' | 10 | import * as videojs from 'video.js' |
11 | import 'videojs-hotkeys' | 11 | import 'videojs-hotkeys' |
12 | import { Hotkey, HotkeysService } from 'angular2-hotkeys' | ||
12 | import * as WebTorrent from 'webtorrent' | 13 | import * as WebTorrent from 'webtorrent' |
13 | import { UserVideoRateType, VideoCaption, VideoPrivacy, VideoRateType, VideoState } from '../../../../../shared' | 14 | import { UserVideoRateType, VideoCaption, VideoPrivacy, VideoRateType, VideoState } from '../../../../../shared' |
14 | import '../../../assets/player/peertube-videojs-plugin' | 15 | import '../../../assets/player/peertube-videojs-plugin' |
@@ -21,6 +22,7 @@ import { VideoDownloadComponent } from './modal/video-download.component' | |||
21 | import { VideoReportComponent } from './modal/video-report.component' | 22 | import { VideoReportComponent } from './modal/video-report.component' |
22 | import { VideoShareComponent } from './modal/video-share.component' | 23 | import { VideoShareComponent } from './modal/video-share.component' |
23 | import { VideoBlacklistComponent } from './modal/video-blacklist.component' | 24 | import { VideoBlacklistComponent } from './modal/video-blacklist.component' |
25 | import { SubscribeButtonComponent } from '@app/shared/user-subscription/subscribe-button.component' | ||
24 | import { addContextMenu, getVideojsOptions, loadLocaleInVideoJS } from '../../../assets/player/peertube-player' | 26 | import { addContextMenu, getVideojsOptions, loadLocaleInVideoJS } from '../../../assets/player/peertube-player' |
25 | import { ServerService } from '@app/core' | 27 | import { ServerService } from '@app/core' |
26 | import { I18n } from '@ngx-translate/i18n-polyfill' | 28 | import { I18n } from '@ngx-translate/i18n-polyfill' |
@@ -41,6 +43,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
41 | @ViewChild('videoReportModal') videoReportModal: VideoReportComponent | 43 | @ViewChild('videoReportModal') videoReportModal: VideoReportComponent |
42 | @ViewChild('videoSupportModal') videoSupportModal: VideoSupportComponent | 44 | @ViewChild('videoSupportModal') videoSupportModal: VideoSupportComponent |
43 | @ViewChild('videoBlacklistModal') videoBlacklistModal: VideoBlacklistComponent | 45 | @ViewChild('videoBlacklistModal') videoBlacklistModal: VideoBlacklistComponent |
46 | @ViewChild('subscribeButton') subscribeButton: SubscribeButtonComponent | ||
44 | 47 | ||
45 | player: videojs.Player | 48 | player: videojs.Player |
46 | playerElement: HTMLVideoElement | 49 | playerElement: HTMLVideoElement |
@@ -55,6 +58,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
55 | likesBarTooltipText = '' | 58 | likesBarTooltipText = '' |
56 | hasAlreadyAcceptedPrivacyConcern = false | 59 | hasAlreadyAcceptedPrivacyConcern = false |
57 | remoteServerDown = false | 60 | remoteServerDown = false |
61 | hotkeys: Hotkey[] | ||
58 | 62 | ||
59 | private videojsLocaleLoaded = false | 63 | private videojsLocaleLoaded = false |
60 | private paramsSub: Subscription | 64 | private paramsSub: Subscription |
@@ -77,6 +81,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
77 | private redirectService: RedirectService, | 81 | private redirectService: RedirectService, |
78 | private videoCaptionService: VideoCaptionService, | 82 | private videoCaptionService: VideoCaptionService, |
79 | private i18n: I18n, | 83 | private i18n: I18n, |
84 | private hotkeysService: HotkeysService, | ||
80 | @Inject(LOCALE_ID) private localeId: string | 85 | @Inject(LOCALE_ID) private localeId: string |
81 | ) {} | 86 | ) {} |
82 | 87 | ||
@@ -115,6 +120,24 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
115 | .catch(err => this.handleError(err)) | 120 | .catch(err => this.handleError(err)) |
116 | }) | 121 | }) |
117 | }) | 122 | }) |
123 | |||
124 | this.hotkeys = [ | ||
125 | new Hotkey('L', (event: KeyboardEvent): boolean => { | ||
126 | this.setLike() | ||
127 | return false | ||
128 | }, undefined, 'Like the video'), | ||
129 | new Hotkey('D', (event: KeyboardEvent): boolean => { | ||
130 | this.setDislike() | ||
131 | return false | ||
132 | }, undefined, 'Dislike the video'), | ||
133 | new Hotkey('S', (event: KeyboardEvent): boolean => { | ||
134 | this.subscribeButton.subscribed ? | ||
135 | this.subscribeButton.unsubscribe() : | ||
136 | this.subscribeButton.subscribe() | ||
137 | return false | ||
138 | }, undefined, 'Subscribe to the account') | ||
139 | ] | ||
140 | if (this.isUserLoggedIn()) this.hotkeysService.add(this.hotkeys) | ||
118 | } | 141 | } |
119 | 142 | ||
120 | ngOnDestroy () { | 143 | ngOnDestroy () { |
@@ -122,6 +145,9 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
122 | 145 | ||
123 | // Unsubscribe subscriptions | 146 | // Unsubscribe subscriptions |
124 | this.paramsSub.unsubscribe() | 147 | this.paramsSub.unsubscribe() |
148 | |||
149 | // Unbind hotkeys | ||
150 | if (this.isUserLoggedIn()) this.hotkeysService.remove(this.hotkeys) | ||
125 | } | 151 | } |
126 | 152 | ||
127 | setLike () { | 153 | setLike () { |