mirror of https://github.com/Chocobozzz/PeerTube
				
				
				
			Resume videos for non-logged in users (#3885)
* client: resume videos for non-logged in users closes #3866 * fix build for embeded * Update client/src/app/app.component.ts * fix review commentspull/3909/head
							parent
							
								
									d794137057
								
							
						
					
					
						commit
						58b9ce3080
					
				|  | @ -29,7 +29,7 @@ import { MetaService } from '@ngx-meta/core' | |||
| import { peertubeLocalStorage } from '@root-helpers/peertube-web-storage' | ||||
| import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes' | ||||
| import { ServerConfig, ServerErrorCode, UserVideoRateType, VideoCaption, VideoPrivacy, VideoState } from '@shared/models' | ||||
| import { getStoredP2PEnabled, getStoredTheater } from '../../../assets/player/peertube-player-local-storage' | ||||
| import { cleanupVideoWatch, getStoredP2PEnabled, getStoredTheater, getStoredVideoWatchHistory } from '../../../assets/player/peertube-player-local-storage' | ||||
| import { | ||||
|   CustomizationOptions, | ||||
|   P2PMediaLoaderOptions, | ||||
|  | @ -195,6 +195,8 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
|     this.theaterEnabled = getStoredTheater() | ||||
| 
 | ||||
|     this.hooks.runAction('action:video-watch.init', 'video-watch') | ||||
| 
 | ||||
|     setTimeout(cleanupVideoWatch, 1500) // Run in timeout to ensure we're not blocking the UI
 | ||||
|   } | ||||
| 
 | ||||
|   ngOnDestroy () { | ||||
|  | @ -768,9 +770,11 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
|     const getStartTime = () => { | ||||
|       const byUrl = urlOptions.startTime !== undefined | ||||
|       const byHistory = video.userHistory && (!this.playlist || urlOptions.resume !== undefined) | ||||
|       const byLocalStorage = getStoredVideoWatchHistory(video.uuid) | ||||
| 
 | ||||
|       if (byUrl) return timeToInt(urlOptions.startTime) | ||||
|       if (byHistory) return video.userHistory.currentTime | ||||
|       if (byLocalStorage) return byLocalStorage.duration | ||||
| 
 | ||||
|       return 0 | ||||
|     } | ||||
|  | @ -828,7 +832,9 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
| 
 | ||||
|         serverUrl: environment.apiUrl, | ||||
| 
 | ||||
|         videoCaptions: playerCaptions | ||||
|         videoCaptions: playerCaptions, | ||||
| 
 | ||||
|         videoUUID: video.uuid | ||||
|       }, | ||||
| 
 | ||||
|       webtorrent: { | ||||
|  |  | |||
|  | @ -68,6 +68,51 @@ function getStoredLastSubtitle () { | |||
|   return getLocalStorage('last-subtitle') | ||||
| } | ||||
| 
 | ||||
| function saveVideoWatchHistory(videoUUID: string, duration: number) { | ||||
|   return setLocalStorage(`video-watch-history`, JSON.stringify({ | ||||
|     ...getStoredVideoWatchHistory(), | ||||
|     [videoUUID]: { | ||||
|       duration, | ||||
|       date: `${(new Date()).toISOString()}` | ||||
|     } | ||||
|   })) | ||||
| } | ||||
| 
 | ||||
| function getStoredVideoWatchHistory(videoUUID?: string) { | ||||
|   let data | ||||
| 
 | ||||
|   try { | ||||
|     data = JSON.parse(getLocalStorage('video-watch-history')) | ||||
|   } catch (error) { | ||||
|     console.error('Cannot parse video watch history from local storage: ', error) | ||||
|   } | ||||
| 
 | ||||
|   data = data || {} | ||||
| 
 | ||||
|   if (videoUUID) return data[videoUUID] | ||||
| 
 | ||||
|   return data | ||||
| } | ||||
| 
 | ||||
| function cleanupVideoWatch() { | ||||
|   const data = getStoredVideoWatchHistory() | ||||
| 
 | ||||
|   const newData = Object.keys(data).reduce((acc, videoUUID) => { | ||||
|     const date = Date.parse(data[videoUUID].date) | ||||
| 
 | ||||
|     const diff = Math.ceil(((new Date()).getTime() - date) / (1000 * 3600 * 24)) | ||||
| 
 | ||||
|     if (diff > 30) return acc | ||||
| 
 | ||||
|     return { | ||||
|       ...acc, | ||||
|       [videoUUID]: data[videoUUID] | ||||
|     } | ||||
|   }, {}) | ||||
| 
 | ||||
|   setLocalStorage('video-watch-history', JSON.stringify(newData)) | ||||
| } | ||||
| 
 | ||||
| // ---------------------------------------------------------------------------
 | ||||
| 
 | ||||
| export { | ||||
|  | @ -81,7 +126,10 @@ export { | |||
|   saveAverageBandwidth, | ||||
|   getAverageBandwidthInStore, | ||||
|   saveLastSubtitle, | ||||
|   getStoredLastSubtitle | ||||
|   getStoredLastSubtitle, | ||||
|   saveVideoWatchHistory, | ||||
|   getStoredVideoWatchHistory, | ||||
|   cleanupVideoWatch | ||||
| } | ||||
| 
 | ||||
| // ---------------------------------------------------------------------------
 | ||||
|  |  | |||
|  | @ -106,6 +106,8 @@ export interface CommonOptions extends CustomizationOptions { | |||
| 
 | ||||
|   videoCaptions: VideoJSCaption[] | ||||
| 
 | ||||
|   videoUUID: string | ||||
| 
 | ||||
|   userWatching?: UserWatching | ||||
| 
 | ||||
|   serverUrl: string | ||||
|  | @ -231,7 +233,8 @@ export class PeertubePlayerManager { | |||
|         subtitle: commonOptions.subtitle, | ||||
|         videoCaptions: commonOptions.videoCaptions, | ||||
|         stopTime: commonOptions.stopTime, | ||||
|         isLive: commonOptions.isLive | ||||
|         isLive: commonOptions.isLive, | ||||
|         videoUUID: commonOptions.videoUUID | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -13,6 +13,7 @@ import { | |||
|   getStoredVolume, | ||||
|   saveLastSubtitle, | ||||
|   saveMuteInStore, | ||||
|   saveVideoWatchHistory, | ||||
|   saveVolumeInStore | ||||
| } from './peertube-player-local-storage' | ||||
| 
 | ||||
|  | @ -120,7 +121,7 @@ class PeerTubePlugin extends Plugin { | |||
|       this.initializePlayer() | ||||
|       this.runViewAdd() | ||||
| 
 | ||||
|       if (options.userWatching) this.runUserWatchVideo(options.userWatching) | ||||
|       this.runUserWatchVideo(options.userWatching, options.videoUUID) | ||||
|     }) | ||||
|   } | ||||
| 
 | ||||
|  | @ -178,7 +179,7 @@ class PeerTubePlugin extends Plugin { | |||
|     }, 1000) | ||||
|   } | ||||
| 
 | ||||
|   private runUserWatchVideo (options: UserWatching) { | ||||
|   private runUserWatchVideo (options: UserWatching, videoUUID: string) { | ||||
|     let lastCurrentTime = 0 | ||||
| 
 | ||||
|     this.userWatchingVideoInterval = setInterval(() => { | ||||
|  | @ -187,8 +188,12 @@ class PeerTubePlugin extends Plugin { | |||
|       if (currentTime - lastCurrentTime >= 1) { | ||||
|         lastCurrentTime = currentTime | ||||
| 
 | ||||
|         this.notifyUserIsWatching(currentTime, options.url, options.authorizationHeader) | ||||
|           .catch(err => console.error('Cannot notify user is watching.', err)) | ||||
|         if (options) { | ||||
|           this.notifyUserIsWatching(currentTime, options.url, options.authorizationHeader) | ||||
|             .catch(err => console.error('Cannot notify user is watching.', err)) | ||||
|         } else { | ||||
|           saveVideoWatchHistory(videoUUID, currentTime) | ||||
|         } | ||||
|       } | ||||
|     }, this.CONSTANTS.USER_WATCHING_VIDEO_INTERVAL) | ||||
|   } | ||||
|  |  | |||
|  | @ -108,6 +108,8 @@ type PeerTubePluginOptions = { | |||
|   stopTime: number | string | ||||
| 
 | ||||
|   isLive: boolean | ||||
| 
 | ||||
|   videoUUID: string | ||||
| } | ||||
| 
 | ||||
| type PlaylistPluginOptions = { | ||||
|  |  | |||
|  | @ -531,6 +531,7 @@ export class PeerTubeEmbed { | |||
|         videoCaptions, | ||||
|         inactivityTimeout: 2500, | ||||
|         videoViewUrl: this.getVideoUrl(videoInfo.uuid) + '/views', | ||||
|         videoUUID: videoInfo.uuid, | ||||
| 
 | ||||
|         isLive: videoInfo.isLive, | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 kontrollanten
						kontrollanten