diff options
author | kontrollanten <6680299+kontrollanten@users.noreply.github.com> | 2021-03-31 11:26:32 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-31 11:26:32 +0200 |
commit | 58b9ce3080c12678e8c1c28c08da09d6ea60011d (patch) | |
tree | 10e501ba791e67febd47b397729ba5debb81a85c /client | |
parent | d794137057fc5fcea10ddd29f82e79ee2412fea4 (diff) | |
download | PeerTube-58b9ce3080c12678e8c1c28c08da09d6ea60011d.tar.gz PeerTube-58b9ce3080c12678e8c1c28c08da09d6ea60011d.tar.zst PeerTube-58b9ce3080c12678e8c1c28c08da09d6ea60011d.zip |
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 comments
Diffstat (limited to 'client')
6 files changed, 73 insertions, 8 deletions
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 571d1e99a..075f70f56 100644 --- a/client/src/app/+videos/+video-watch/video-watch.component.ts +++ b/client/src/app/+videos/+video-watch/video-watch.component.ts | |||
@@ -29,7 +29,7 @@ import { MetaService } from '@ngx-meta/core' | |||
29 | import { peertubeLocalStorage } from '@root-helpers/peertube-web-storage' | 29 | import { peertubeLocalStorage } from '@root-helpers/peertube-web-storage' |
30 | import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes' | 30 | import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes' |
31 | import { ServerConfig, ServerErrorCode, UserVideoRateType, VideoCaption, VideoPrivacy, VideoState } from '@shared/models' | 31 | import { ServerConfig, ServerErrorCode, UserVideoRateType, VideoCaption, VideoPrivacy, VideoState } from '@shared/models' |
32 | import { getStoredP2PEnabled, getStoredTheater } from '../../../assets/player/peertube-player-local-storage' | 32 | import { cleanupVideoWatch, getStoredP2PEnabled, getStoredTheater, getStoredVideoWatchHistory } from '../../../assets/player/peertube-player-local-storage' |
33 | import { | 33 | import { |
34 | CustomizationOptions, | 34 | CustomizationOptions, |
35 | P2PMediaLoaderOptions, | 35 | P2PMediaLoaderOptions, |
@@ -195,6 +195,8 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
195 | this.theaterEnabled = getStoredTheater() | 195 | this.theaterEnabled = getStoredTheater() |
196 | 196 | ||
197 | this.hooks.runAction('action:video-watch.init', 'video-watch') | 197 | this.hooks.runAction('action:video-watch.init', 'video-watch') |
198 | |||
199 | setTimeout(cleanupVideoWatch, 1500) // Run in timeout to ensure we're not blocking the UI | ||
198 | } | 200 | } |
199 | 201 | ||
200 | ngOnDestroy () { | 202 | ngOnDestroy () { |
@@ -768,9 +770,11 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
768 | const getStartTime = () => { | 770 | const getStartTime = () => { |
769 | const byUrl = urlOptions.startTime !== undefined | 771 | const byUrl = urlOptions.startTime !== undefined |
770 | const byHistory = video.userHistory && (!this.playlist || urlOptions.resume !== undefined) | 772 | const byHistory = video.userHistory && (!this.playlist || urlOptions.resume !== undefined) |
773 | const byLocalStorage = getStoredVideoWatchHistory(video.uuid) | ||
771 | 774 | ||
772 | if (byUrl) return timeToInt(urlOptions.startTime) | 775 | if (byUrl) return timeToInt(urlOptions.startTime) |
773 | if (byHistory) return video.userHistory.currentTime | 776 | if (byHistory) return video.userHistory.currentTime |
777 | if (byLocalStorage) return byLocalStorage.duration | ||
774 | 778 | ||
775 | return 0 | 779 | return 0 |
776 | } | 780 | } |
@@ -828,7 +832,9 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
828 | 832 | ||
829 | serverUrl: environment.apiUrl, | 833 | serverUrl: environment.apiUrl, |
830 | 834 | ||
831 | videoCaptions: playerCaptions | 835 | videoCaptions: playerCaptions, |
836 | |||
837 | videoUUID: video.uuid | ||
832 | }, | 838 | }, |
833 | 839 | ||
834 | webtorrent: { | 840 | webtorrent: { |
diff --git a/client/src/assets/player/peertube-player-local-storage.ts b/client/src/assets/player/peertube-player-local-storage.ts index 75ccfe618..cf2cfb472 100644 --- a/client/src/assets/player/peertube-player-local-storage.ts +++ b/client/src/assets/player/peertube-player-local-storage.ts | |||
@@ -68,6 +68,51 @@ function getStoredLastSubtitle () { | |||
68 | return getLocalStorage('last-subtitle') | 68 | return getLocalStorage('last-subtitle') |
69 | } | 69 | } |
70 | 70 | ||
71 | function saveVideoWatchHistory(videoUUID: string, duration: number) { | ||
72 | return setLocalStorage(`video-watch-history`, JSON.stringify({ | ||
73 | ...getStoredVideoWatchHistory(), | ||
74 | [videoUUID]: { | ||
75 | duration, | ||
76 | date: `${(new Date()).toISOString()}` | ||
77 | } | ||
78 | })) | ||
79 | } | ||
80 | |||
81 | function getStoredVideoWatchHistory(videoUUID?: string) { | ||
82 | let data | ||
83 | |||
84 | try { | ||
85 | data = JSON.parse(getLocalStorage('video-watch-history')) | ||
86 | } catch (error) { | ||
87 | console.error('Cannot parse video watch history from local storage: ', error) | ||
88 | } | ||
89 | |||
90 | data = data || {} | ||
91 | |||
92 | if (videoUUID) return data[videoUUID] | ||
93 | |||
94 | return data | ||
95 | } | ||
96 | |||
97 | function cleanupVideoWatch() { | ||
98 | const data = getStoredVideoWatchHistory() | ||
99 | |||
100 | const newData = Object.keys(data).reduce((acc, videoUUID) => { | ||
101 | const date = Date.parse(data[videoUUID].date) | ||
102 | |||
103 | const diff = Math.ceil(((new Date()).getTime() - date) / (1000 * 3600 * 24)) | ||
104 | |||
105 | if (diff > 30) return acc | ||
106 | |||
107 | return { | ||
108 | ...acc, | ||
109 | [videoUUID]: data[videoUUID] | ||
110 | } | ||
111 | }, {}) | ||
112 | |||
113 | setLocalStorage('video-watch-history', JSON.stringify(newData)) | ||
114 | } | ||
115 | |||
71 | // --------------------------------------------------------------------------- | 116 | // --------------------------------------------------------------------------- |
72 | 117 | ||
73 | export { | 118 | export { |
@@ -81,7 +126,10 @@ export { | |||
81 | saveAverageBandwidth, | 126 | saveAverageBandwidth, |
82 | getAverageBandwidthInStore, | 127 | getAverageBandwidthInStore, |
83 | saveLastSubtitle, | 128 | saveLastSubtitle, |
84 | getStoredLastSubtitle | 129 | getStoredLastSubtitle, |
130 | saveVideoWatchHistory, | ||
131 | getStoredVideoWatchHistory, | ||
132 | cleanupVideoWatch | ||
85 | } | 133 | } |
86 | 134 | ||
87 | // --------------------------------------------------------------------------- | 135 | // --------------------------------------------------------------------------- |
diff --git a/client/src/assets/player/peertube-player-manager.ts b/client/src/assets/player/peertube-player-manager.ts index 1d335805b..119dec379 100644 --- a/client/src/assets/player/peertube-player-manager.ts +++ b/client/src/assets/player/peertube-player-manager.ts | |||
@@ -106,6 +106,8 @@ export interface CommonOptions extends CustomizationOptions { | |||
106 | 106 | ||
107 | videoCaptions: VideoJSCaption[] | 107 | videoCaptions: VideoJSCaption[] |
108 | 108 | ||
109 | videoUUID: string | ||
110 | |||
109 | userWatching?: UserWatching | 111 | userWatching?: UserWatching |
110 | 112 | ||
111 | serverUrl: string | 113 | serverUrl: string |
@@ -231,7 +233,8 @@ export class PeertubePlayerManager { | |||
231 | subtitle: commonOptions.subtitle, | 233 | subtitle: commonOptions.subtitle, |
232 | videoCaptions: commonOptions.videoCaptions, | 234 | videoCaptions: commonOptions.videoCaptions, |
233 | stopTime: commonOptions.stopTime, | 235 | stopTime: commonOptions.stopTime, |
234 | isLive: commonOptions.isLive | 236 | isLive: commonOptions.isLive, |
237 | videoUUID: commonOptions.videoUUID | ||
235 | } | 238 | } |
236 | } | 239 | } |
237 | 240 | ||
diff --git a/client/src/assets/player/peertube-plugin.ts b/client/src/assets/player/peertube-plugin.ts index 75a6e662e..07c7e33f6 100644 --- a/client/src/assets/player/peertube-plugin.ts +++ b/client/src/assets/player/peertube-plugin.ts | |||
@@ -13,6 +13,7 @@ import { | |||
13 | getStoredVolume, | 13 | getStoredVolume, |
14 | saveLastSubtitle, | 14 | saveLastSubtitle, |
15 | saveMuteInStore, | 15 | saveMuteInStore, |
16 | saveVideoWatchHistory, | ||
16 | saveVolumeInStore | 17 | saveVolumeInStore |
17 | } from './peertube-player-local-storage' | 18 | } from './peertube-player-local-storage' |
18 | 19 | ||
@@ -120,7 +121,7 @@ class PeerTubePlugin extends Plugin { | |||
120 | this.initializePlayer() | 121 | this.initializePlayer() |
121 | this.runViewAdd() | 122 | this.runViewAdd() |
122 | 123 | ||
123 | if (options.userWatching) this.runUserWatchVideo(options.userWatching) | 124 | this.runUserWatchVideo(options.userWatching, options.videoUUID) |
124 | }) | 125 | }) |
125 | } | 126 | } |
126 | 127 | ||
@@ -178,7 +179,7 @@ class PeerTubePlugin extends Plugin { | |||
178 | }, 1000) | 179 | }, 1000) |
179 | } | 180 | } |
180 | 181 | ||
181 | private runUserWatchVideo (options: UserWatching) { | 182 | private runUserWatchVideo (options: UserWatching, videoUUID: string) { |
182 | let lastCurrentTime = 0 | 183 | let lastCurrentTime = 0 |
183 | 184 | ||
184 | this.userWatchingVideoInterval = setInterval(() => { | 185 | this.userWatchingVideoInterval = setInterval(() => { |
@@ -187,8 +188,12 @@ class PeerTubePlugin extends Plugin { | |||
187 | if (currentTime - lastCurrentTime >= 1) { | 188 | if (currentTime - lastCurrentTime >= 1) { |
188 | lastCurrentTime = currentTime | 189 | lastCurrentTime = currentTime |
189 | 190 | ||
190 | this.notifyUserIsWatching(currentTime, options.url, options.authorizationHeader) | 191 | if (options) { |
191 | .catch(err => console.error('Cannot notify user is watching.', err)) | 192 | this.notifyUserIsWatching(currentTime, options.url, options.authorizationHeader) |
193 | .catch(err => console.error('Cannot notify user is watching.', err)) | ||
194 | } else { | ||
195 | saveVideoWatchHistory(videoUUID, currentTime) | ||
196 | } | ||
192 | } | 197 | } |
193 | }, this.CONSTANTS.USER_WATCHING_VIDEO_INTERVAL) | 198 | }, this.CONSTANTS.USER_WATCHING_VIDEO_INTERVAL) |
194 | } | 199 | } |
diff --git a/client/src/assets/player/peertube-videojs-typings.ts b/client/src/assets/player/peertube-videojs-typings.ts index e5259092c..4a6c80247 100644 --- a/client/src/assets/player/peertube-videojs-typings.ts +++ b/client/src/assets/player/peertube-videojs-typings.ts | |||
@@ -108,6 +108,8 @@ type PeerTubePluginOptions = { | |||
108 | stopTime: number | string | 108 | stopTime: number | string |
109 | 109 | ||
110 | isLive: boolean | 110 | isLive: boolean |
111 | |||
112 | videoUUID: string | ||
111 | } | 113 | } |
112 | 114 | ||
113 | type PlaylistPluginOptions = { | 115 | type PlaylistPluginOptions = { |
diff --git a/client/src/standalone/videos/embed.ts b/client/src/standalone/videos/embed.ts index 614a1cc0b..ae8f176b7 100644 --- a/client/src/standalone/videos/embed.ts +++ b/client/src/standalone/videos/embed.ts | |||
@@ -531,6 +531,7 @@ export class PeerTubeEmbed { | |||
531 | videoCaptions, | 531 | videoCaptions, |
532 | inactivityTimeout: 2500, | 532 | inactivityTimeout: 2500, |
533 | videoViewUrl: this.getVideoUrl(videoInfo.uuid) + '/views', | 533 | videoViewUrl: this.getVideoUrl(videoInfo.uuid) + '/views', |
534 | videoUUID: videoInfo.uuid, | ||
534 | 535 | ||
535 | isLive: videoInfo.isLive, | 536 | isLive: videoInfo.isLive, |
536 | 537 | ||