From 88a7f93f8e5666f44121a2e3cf9d33d74c472aa7 Mon Sep 17 00:00:00 2001 From: Rigel Kent Date: Wed, 11 Dec 2019 22:13:20 +0100 Subject: [PATCH] add loop setting for playlists, and use sessionStorage --- .../app/+admin/system/jobs/jobs.component.ts | 2 +- client/src/app/core/auth/auth-user.model.ts | 2 +- client/src/app/core/auth/auth.service.ts | 2 +- client/src/app/core/server/server.service.ts | 2 +- client/src/app/core/theme/theme.service.ts | 2 +- .../shared/images/global-icon.component.ts | 1 + ...cal-storage.ts => peertube-web-storage.ts} | 9 ++++- client/src/app/shared/rest/rest-table.ts | 2 +- .../video-watch-playlist.component.html | 9 +++++ .../video-watch-playlist.component.scss | 4 ++ .../video-watch-playlist.component.ts | 39 +++++++++++++++---- .../+video-watch/video-watch.component.ts | 9 ++--- .../recommended-videos.component.ts | 8 ++-- client/src/assets/images/global/repeat.svg | 1 + 14 files changed, 68 insertions(+), 24 deletions(-) rename client/src/app/shared/misc/{peertube-local-storage.ts => peertube-web-storage.ts} (87%) create mode 100644 client/src/assets/images/global/repeat.svg diff --git a/client/src/app/+admin/system/jobs/jobs.component.ts b/client/src/app/+admin/system/jobs/jobs.component.ts index 95ee17023..c3211d71f 100644 --- a/client/src/app/+admin/system/jobs/jobs.component.ts +++ b/client/src/app/+admin/system/jobs/jobs.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit } from '@angular/core' -import { peertubeLocalStorage } from '@app/shared/misc/peertube-local-storage' +import { peertubeLocalStorage } from '@app/shared/misc/peertube-web-storage' import { Notifier } from '@app/core' import { SortMeta } from 'primeng/api' import { Job, JobType } from '../../../../../../shared/index' diff --git a/client/src/app/core/auth/auth-user.model.ts b/client/src/app/core/auth/auth-user.model.ts index 334ede0cd..d371a923f 100644 --- a/client/src/app/core/auth/auth-user.model.ts +++ b/client/src/app/core/auth/auth-user.model.ts @@ -1,4 +1,4 @@ -import { peertubeLocalStorage } from '@app/shared/misc/peertube-local-storage' +import { peertubeLocalStorage } from '@app/shared/misc/peertube-web-storage' import { UserRight } from '../../../../../shared/models/users/user-right.enum' import { User as ServerUserModel } from '../../../../../shared/models/users/user.model' // Do not use the barrel (dependency loop) diff --git a/client/src/app/core/auth/auth.service.ts b/client/src/app/core/auth/auth.service.ts index eaa822e0f..d601cadf5 100644 --- a/client/src/app/core/auth/auth.service.ts +++ b/client/src/app/core/auth/auth.service.ts @@ -12,7 +12,7 @@ import { RestExtractor } from '../../shared/rest/rest-extractor.service' import { AuthStatus } from './auth-status.model' import { AuthUser } from './auth-user.model' import { objectToUrlEncoded } from '@app/shared/misc/utils' -import { peertubeLocalStorage } from '@app/shared/misc/peertube-local-storage' +import { peertubeLocalStorage } from '@app/shared/misc/peertube-web-storage' import { I18n } from '@ngx-translate/i18n-polyfill' import { Hotkey, HotkeysService } from 'angular2-hotkeys' diff --git a/client/src/app/core/server/server.service.ts b/client/src/app/core/server/server.service.ts index 8e76bebb1..cf9c411a4 100644 --- a/client/src/app/core/server/server.service.ts +++ b/client/src/app/core/server/server.service.ts @@ -1,7 +1,7 @@ import { map, shareReplay, switchMap, tap } from 'rxjs/operators' import { HttpClient } from '@angular/common/http' import { Inject, Injectable, LOCALE_ID } from '@angular/core' -import { peertubeLocalStorage } from '@app/shared/misc/peertube-local-storage' +import { peertubeLocalStorage } from '@app/shared/misc/peertube-web-storage' import { Observable, of, ReplaySubject } from 'rxjs' import { getCompleteLocale, ServerConfig } from '../../../../../shared' import { environment } from '../../../environments/environment' diff --git a/client/src/app/core/theme/theme.service.ts b/client/src/app/core/theme/theme.service.ts index b312e8f7a..9be8e7a2d 100644 --- a/client/src/app/core/theme/theme.service.ts +++ b/client/src/app/core/theme/theme.service.ts @@ -4,7 +4,7 @@ import { ServerService } from '@app/core/server' import { environment } from '../../../environments/environment' import { PluginService } from '@app/core/plugins/plugin.service' import { ServerConfigTheme } from '@shared/models' -import { peertubeLocalStorage } from '@app/shared/misc/peertube-local-storage' +import { peertubeLocalStorage } from '@app/shared/misc/peertube-web-storage' @Injectable() export class ThemeService { diff --git a/client/src/app/shared/images/global-icon.component.ts b/client/src/app/shared/images/global-icon.component.ts index eb723db94..31cfe2666 100644 --- a/client/src/app/shared/images/global-icon.component.ts +++ b/client/src/app/shared/images/global-icon.component.ts @@ -26,6 +26,7 @@ const icons = { 'cross': require('!!raw-loader?!../../../assets/images/global/cross.svg'), 'validate': require('!!raw-loader?!../../../assets/images/global/validate.svg'), 'tick': require('!!raw-loader?!../../../assets/images/global/tick.svg'), + 'repeat': require('!!raw-loader?!../../../assets/images/global/repeat.svg'), 'dislike': require('!!raw-loader?!../../../assets/images/video/dislike.svg'), 'support': require('!!raw-loader?!../../../assets/images/video/support.svg'), 'like': require('!!raw-loader?!../../../assets/images/video/like.svg'), diff --git a/client/src/app/shared/misc/peertube-local-storage.ts b/client/src/app/shared/misc/peertube-web-storage.ts similarity index 87% rename from client/src/app/shared/misc/peertube-local-storage.ts rename to client/src/app/shared/misc/peertube-web-storage.ts index fb5c45acf..fff209678 100644 --- a/client/src/app/shared/misc/peertube-local-storage.ts +++ b/client/src/app/shared/misc/peertube-web-storage.ts @@ -42,12 +42,14 @@ class MemoryStorage { } let peertubeLocalStorage: Storage +let peertubeSessionStorage: Storage try { peertubeLocalStorage = localStorage + peertubeSessionStorage = sessionStorage } catch (err) { const instance = new MemoryStorage() - peertubeLocalStorage = new Proxy(instance, { + peertubeLocalStorage = sessionStorage = new Proxy(instance, { set: function (obj, prop: string | number, value) { if (MemoryStorage.prototype.hasOwnProperty(prop)) { instance[prop] = value @@ -67,4 +69,7 @@ try { }) } -export { peertubeLocalStorage } +export { + peertubeLocalStorage, + peertubeSessionStorage +} diff --git a/client/src/app/shared/rest/rest-table.ts b/client/src/app/shared/rest/rest-table.ts index 884588207..c180346af 100644 --- a/client/src/app/shared/rest/rest-table.ts +++ b/client/src/app/shared/rest/rest-table.ts @@ -1,4 +1,4 @@ -import { peertubeLocalStorage } from '@app/shared/misc/peertube-local-storage' +import { peertubeLocalStorage } from '@app/shared/misc/peertube-web-storage' import { LazyLoadEvent } from 'primeng/components/common/lazyloadevent' import { SortMeta } from 'primeng/components/common/sortmeta' import { RestPagination } from './rest-pagination' diff --git a/client/src/app/videos/+video-watch/video-watch-playlist.component.html b/client/src/app/videos/+video-watch/video-watch-playlist.component.html index c07ba1ed6..a04081d35 100644 --- a/client/src/app/videos/+video-watch/video-watch-playlist.component.html +++ b/client/src/app/videos/+video-watch/video-watch-playlist.component.html @@ -24,6 +24,15 @@ placement="bottom auto" container="body" > + + diff --git a/client/src/app/videos/+video-watch/video-watch-playlist.component.scss b/client/src/app/videos/+video-watch/video-watch-playlist.component.scss index ba8d1c3e1..0dd318cb0 100644 --- a/client/src/app/videos/+video-watch/video-watch-playlist.component.scss +++ b/client/src/app/videos/+video-watch/video-watch-playlist.component.scss @@ -39,6 +39,10 @@ display: flex; margin: 10px 0; + my-global-icon:not(:last-child) { + margin-right: .5rem; + } + my-global-icon { &:not(.active) { opacity: .5 diff --git a/client/src/app/videos/+video-watch/video-watch-playlist.component.ts b/client/src/app/videos/+video-watch/video-watch-playlist.component.ts index ed2aeda6e..c6b04fd4b 100644 --- a/client/src/app/videos/+video-watch/video-watch-playlist.component.ts +++ b/client/src/app/videos/+video-watch/video-watch-playlist.component.ts @@ -3,11 +3,11 @@ import { VideoPlaylist } from '@app/shared/video-playlist/video-playlist.model' import { ComponentPagination } from '@app/shared/rest/component-pagination.model' import { VideoDetails, VideoPlaylistPrivacy } from '@shared/models' import { Router } from '@angular/router' -import { User, UserService } from '@app/shared' +import { UserService } from '@app/shared' import { AuthService, Notifier } from '@app/core' import { VideoPlaylistService } from '@app/shared/video-playlist/video-playlist.service' import { VideoPlaylistElement } from '@app/shared/video-playlist/video-playlist-element.model' -import { peertubeLocalStorage } from '@app/shared/misc/peertube-local-storage' +import { peertubeLocalStorage, peertubeSessionStorage } from '@app/shared/misc/peertube-web-storage' import { I18n } from '@ngx-translate/i18n-polyfill' @Component({ @@ -17,6 +17,7 @@ import { I18n } from '@ngx-translate/i18n-polyfill' }) export class VideoWatchPlaylistComponent { static LOCAL_STORAGE_AUTO_PLAY_NEXT_VIDEO_PLAYLIST = 'auto_play_video_playlist' + static SESSION_STORAGE_AUTO_PLAY_NEXT_VIDEO_PLAYLIST = 'loop_playlist' @Input() video: VideoDetails @Input() playlist: VideoPlaylist @@ -30,6 +31,8 @@ export class VideoWatchPlaylistComponent { autoPlayNextVideoPlaylist: boolean autoPlayNextVideoPlaylistSwitchText = '' + loopPlaylist: boolean + loopPlaylistSwitchText = '' noPlaylistVideos = false currentPlaylistPosition = 1 @@ -45,6 +48,9 @@ export class VideoWatchPlaylistComponent { ? this.auth.getUser().autoPlayNextVideoPlaylist : peertubeLocalStorage.getItem(VideoWatchPlaylistComponent.LOCAL_STORAGE_AUTO_PLAY_NEXT_VIDEO_PLAYLIST) !== 'false' this.setAutoPlayNextVideoPlaylistSwitchText() + + this.loopPlaylist = peertubeSessionStorage.getItem(VideoWatchPlaylistComponent.SESSION_STORAGE_AUTO_PLAY_NEXT_VIDEO_PLAYLIST) === 'true' + this.setLoopPlaylistSwitchText() } onPlaylistVideosNearOfBottom () { @@ -121,9 +127,9 @@ export class VideoWatchPlaylistComponent { this.onPlaylistVideosNearOfBottom() } - navigateToNextPlaylistVideo () { + navigateToNextPlaylistVideo (_next: VideoPlaylistElement = null) { if (this.currentPlaylistPosition < this.playlistPagination.totalItems) { - const next = this.playlistElements.find(e => e.position === this.currentPlaylistPosition + 1) + const next = _next || this.playlistElements.find(e => e.position === this.currentPlaylistPosition + 1) if (!next || !next.video) { this.currentPlaylistPosition++ @@ -134,6 +140,9 @@ export class VideoWatchPlaylistComponent { const start = next.startTimestamp const stop = next.stopTimestamp this.router.navigate([],{ queryParams: { videoId: next.video.uuid, start, stop } }) + } else if (this.loopPlaylist) { + this.currentPlaylistPosition = 0 + this.navigateToNextPlaylistVideo(this.playlistElements.find(e => e.position === this.currentPlaylistPosition)) } } @@ -160,9 +169,25 @@ export class VideoWatchPlaylistComponent { } } + switchLoopPlaylist () { + this.loopPlaylist = !this.loopPlaylist + this.setLoopPlaylistSwitchText() + + peertubeSessionStorage.setItem( + VideoWatchPlaylistComponent.SESSION_STORAGE_AUTO_PLAY_NEXT_VIDEO_PLAYLIST, + this.loopPlaylist.toString() + ) + } + private setAutoPlayNextVideoPlaylistSwitchText () { - this.autoPlayNextVideoPlaylistSwitchText = this.i18n('{{verb}} autoplay for playlists', { - verb: this.autoPlayNextVideoPlaylist ? this.i18n('Disable') : this.i18n('Enable') - }) + this.autoPlayNextVideoPlaylistSwitchText = this.autoPlayNextVideoPlaylist + ? this.i18n('Stop autoplaying next video') + : this.i18n('Autoplay next video') + } + + private setLoopPlaylistSwitchText () { + this.loopPlaylistSwitchText = this.loopPlaylist + ? this.i18n('Stop looping playlist videos') + : this.i18n('Loop playlist videos') } } 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 92c1c50c0..aaaa63d4d 100644 --- a/client/src/app/videos/+video-watch/video-watch.component.ts +++ b/client/src/app/videos/+video-watch/video-watch.component.ts @@ -2,7 +2,7 @@ import { catchError } from 'rxjs/operators' import { ChangeDetectorRef, Component, ElementRef, Inject, LOCALE_ID, NgZone, OnDestroy, OnInit, ViewChild } from '@angular/core' import { ActivatedRoute, Router } from '@angular/router' import { RedirectService } from '@app/core/routing/redirect.service' -import { peertubeLocalStorage } from '@app/shared/misc/peertube-local-storage' +import { peertubeLocalStorage, peertubeSessionStorage } from '@app/shared/misc/peertube-web-storage' import { VideoSupportComponent } from '@app/videos/+video-watch/modal/video-support.component' import { MetaService } from '@ngx-meta/core' import { AuthUser, Notifier, ServerService } from '@app/core' @@ -46,7 +46,6 @@ import { RecommendedVideosComponent } from '../recommendations/recommended-video }) export class VideoWatchComponent implements OnInit, OnDestroy { private static LOCAL_STORAGE_PRIVACY_CONCERN_KEY = 'video-watch-privacy-concern' - private static LOCAL_STORAGE_AUTO_PLAY_NEXT_VIDEO = 'auto_play_next_video' @ViewChild('videoWatchPlaylist', { static: true }) videoWatchPlaylist: VideoWatchPlaylistComponent @ViewChild('videoShareModal', { static: false }) videoShareModal: VideoShareComponent @@ -439,11 +438,11 @@ export class VideoWatchComponent implements OnInit, OnDestroy { if (this.playlist) { if ( this.user && this.user.autoPlayNextVideoPlaylist || - peertubeLocalStorage.getItem(VideoWatchPlaylistComponent.LOCAL_STORAGE_AUTO_PLAY_NEXT_VIDEO_PLAYLIST) === 'true' + peertubeSessionStorage.getItem(VideoWatchPlaylistComponent.SESSION_STORAGE_AUTO_PLAY_NEXT_VIDEO_PLAYLIST) === 'true' ) this.zone.run(() => this.videoWatchPlaylist.navigateToNextPlaylistVideo()) } else if ( this.user && this.user.autoPlayNextVideo || - peertubeLocalStorage.getItem(RecommendedVideosComponent.LOCAL_STORAGE_AUTO_PLAY_NEXT_VIDEO) === 'true' + peertubeSessionStorage.getItem(RecommendedVideosComponent.SESSION_STORAGE_AUTO_PLAY_NEXT_VIDEO) === 'true' ) { this.zone.run(() => this.autoplayNext()) } @@ -453,7 +452,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy { if (this.playlist) { if ( this.user && this.user.autoPlayNextVideoPlaylist || - peertubeLocalStorage.getItem(VideoWatchPlaylistComponent.LOCAL_STORAGE_AUTO_PLAY_NEXT_VIDEO_PLAYLIST) === 'true' + peertubeSessionStorage.getItem(VideoWatchPlaylistComponent.SESSION_STORAGE_AUTO_PLAY_NEXT_VIDEO_PLAYLIST) === 'true' ) this.zone.run(() => this.videoWatchPlaylist.navigateToNextPlaylistVideo()) } }) diff --git a/client/src/app/videos/recommendations/recommended-videos.component.ts b/client/src/app/videos/recommendations/recommended-videos.component.ts index 771ae54a2..fdcfb28e3 100644 --- a/client/src/app/videos/recommendations/recommended-videos.component.ts +++ b/client/src/app/videos/recommendations/recommended-videos.component.ts @@ -7,7 +7,7 @@ import { RecommendedVideosStore } from '@app/videos/recommendations/recommended- import { User } from '@app/shared' import { AuthService, Notifier } from '@app/core' import { UserService } from '@app/shared/users/user.service' -import { peertubeLocalStorage } from '@app/shared/misc/peertube-local-storage' +import { peertubeSessionStorage } from '@app/shared/misc/peertube-web-storage' @Component({ selector: 'my-recommended-videos', @@ -15,7 +15,7 @@ import { peertubeLocalStorage } from '@app/shared/misc/peertube-local-storage' styleUrls: [ './recommended-videos.component.scss' ] }) export class RecommendedVideosComponent implements OnChanges { - static LOCAL_STORAGE_AUTO_PLAY_NEXT_VIDEO = 'auto_play_next_video' + static SESSION_STORAGE_AUTO_PLAY_NEXT_VIDEO = 'auto_play_next_video' @Input() inputRecommendation: RecommendationInfo @Input() user: User @@ -39,7 +39,7 @@ export class RecommendedVideosComponent implements OnChanges { this.autoPlayNextVideo = this.authService.isLoggedIn() ? this.authService.getUser().autoPlayNextVideo - : peertubeLocalStorage.getItem(RecommendedVideosComponent.LOCAL_STORAGE_AUTO_PLAY_NEXT_VIDEO) === 'true' || false + : peertubeSessionStorage.getItem(RecommendedVideosComponent.SESSION_STORAGE_AUTO_PLAY_NEXT_VIDEO) === 'true' || false } public ngOnChanges (): void { @@ -53,7 +53,7 @@ export class RecommendedVideosComponent implements OnChanges { } switchAutoPlayNextVideo () { - peertubeLocalStorage.setItem(RecommendedVideosComponent.LOCAL_STORAGE_AUTO_PLAY_NEXT_VIDEO, this.autoPlayNextVideo.toString()) + peertubeSessionStorage.setItem(RecommendedVideosComponent.SESSION_STORAGE_AUTO_PLAY_NEXT_VIDEO, this.autoPlayNextVideo.toString()) if (this.authService.isLoggedIn()) { const details = { diff --git a/client/src/assets/images/global/repeat.svg b/client/src/assets/images/global/repeat.svg new file mode 100644 index 000000000..c7657b08e --- /dev/null +++ b/client/src/assets/images/global/repeat.svg @@ -0,0 +1 @@ + \ No newline at end of file