2 import { filter, throttleTime } from 'rxjs'
3 import { Injectable } from '@angular/core'
4 import { AuthService, AuthStatus } from '@app/core/auth'
5 import { UserLocalStorageKeys, UserTokens } from '@root-helpers/users'
6 import { getBoolOrDefault } from '@root-helpers/local-storage-utils'
7 import { UserRole, UserUpdateMe } from '@shared/models'
8 import { NSFWPolicyType } from '@shared/models/videos'
9 import { ServerService } from '../server'
10 import { LocalStorageService } from '../wrappers/storage.service'
13 export class UserLocalStorageService {
16 private authService: AuthService,
17 private server: ServerService,
18 private localStorageService: LocalStorageService
20 this.authService.userInformationLoaded.subscribe({
22 const user = this.authService.getUser()
24 this.setLoggedInUser(user)
25 this.setUserInfo(user)
26 this.setTokens(user.tokens)
30 this.authService.loginChangedSource
31 .pipe(filter(status => status === AuthStatus.LoggedOut))
34 this.flushLoggedInUser()
40 this.authService.tokensRefreshed
43 const user = this.authService.getUser()
45 this.setTokens(user.tokens)
50 // ---------------------------------------------------------------------------
53 const usernameLocalStorage = this.localStorageService.getItem(UserLocalStorageKeys.USERNAME)
55 if (!usernameLocalStorage) return undefined
58 id: parseInt(this.localStorageService.getItem(UserLocalStorageKeys.ID), 10),
59 username: this.localStorageService.getItem(UserLocalStorageKeys.USERNAME),
60 email: this.localStorageService.getItem(UserLocalStorageKeys.EMAIL),
61 role: parseInt(this.localStorageService.getItem(UserLocalStorageKeys.ROLE), 10) as UserRole,
67 setLoggedInUser (user: {
73 this.localStorageService.setItem(UserLocalStorageKeys.ID, user.id.toString())
74 this.localStorageService.setItem(UserLocalStorageKeys.USERNAME, user.username)
75 this.localStorageService.setItem(UserLocalStorageKeys.EMAIL, user.email)
76 this.localStorageService.setItem(UserLocalStorageKeys.ROLE, user.role.toString())
79 flushLoggedInUser () {
80 this.localStorageService.removeItem(UserLocalStorageKeys.ID)
81 this.localStorageService.removeItem(UserLocalStorageKeys.USERNAME)
82 this.localStorageService.removeItem(UserLocalStorageKeys.EMAIL)
83 this.localStorageService.removeItem(UserLocalStorageKeys.ROLE)
86 // ---------------------------------------------------------------------------
89 let videoLanguages: string[]
92 const languagesString = this.localStorageService.getItem(UserLocalStorageKeys.VIDEO_LANGUAGES)
93 videoLanguages = languagesString && languagesString !== 'undefined'
94 ? JSON.parse(languagesString)
98 console.error('Cannot parse desired video languages from localStorage.', err)
101 const htmlConfig = this.server.getHTMLConfig()
103 const defaultNSFWPolicy = htmlConfig.instance.defaultNSFWPolicy
104 const defaultP2PEnabled = htmlConfig.defaults.p2p.webapp.enabled
107 nsfwPolicy: this.localStorageService.getItem<NSFWPolicyType>(UserLocalStorageKeys.NSFW_POLICY) || defaultNSFWPolicy,
108 p2pEnabled: getBoolOrDefault(this.localStorageService.getItem(UserLocalStorageKeys.P2P_ENABLED), defaultP2PEnabled),
109 theme: this.localStorageService.getItem(UserLocalStorageKeys.THEME) || 'instance-default',
112 autoPlayVideo: getBoolOrDefault(this.localStorageService.getItem(UserLocalStorageKeys.AUTO_PLAY_VIDEO), true),
113 autoPlayNextVideo: getBoolOrDefault(this.localStorageService.getItem(UserLocalStorageKeys.AUTO_PLAY_NEXT_VIDEO), false),
114 autoPlayNextVideoPlaylist: getBoolOrDefault(this.localStorageService.getItem(UserLocalStorageKeys.AUTO_PLAY_VIDEO_PLAYLIST), true)
118 setUserInfo (profile: UserUpdateMe) {
119 const localStorageKeys: { [ id in keyof UserUpdateMe ]: string } = {
120 nsfwPolicy: UserLocalStorageKeys.NSFW_POLICY,
121 p2pEnabled: UserLocalStorageKeys.P2P_ENABLED,
122 autoPlayNextVideo: UserLocalStorageKeys.AUTO_PLAY_VIDEO,
123 autoPlayNextVideoPlaylist: UserLocalStorageKeys.AUTO_PLAY_VIDEO_PLAYLIST,
124 theme: UserLocalStorageKeys.THEME,
125 videoLanguages: UserLocalStorageKeys.VIDEO_LANGUAGES
128 const obj = Object.keys(localStorageKeys)
129 .filter(key => key in profile)
130 .map(key => ([ localStorageKeys[key], profile[key] ]))
132 for (const [ key, value ] of obj) {
134 if (value === undefined) {
135 this.localStorageService.removeItem(key)
139 const localStorageValue = typeof value === 'string'
141 : JSON.stringify(value)
143 this.localStorageService.setItem(key, localStorageValue)
145 console.error(`Cannot set ${key}->${value} in localStorage. Likely due to a value impossible to stringify.`, err)
151 this.localStorageService.removeItem(UserLocalStorageKeys.NSFW_POLICY)
152 this.localStorageService.removeItem(UserLocalStorageKeys.P2P_ENABLED)
153 this.localStorageService.removeItem(UserLocalStorageKeys.AUTO_PLAY_VIDEO)
154 this.localStorageService.removeItem(UserLocalStorageKeys.AUTO_PLAY_VIDEO_PLAYLIST)
155 this.localStorageService.removeItem(UserLocalStorageKeys.THEME)
156 this.localStorageService.removeItem(UserLocalStorageKeys.VIDEO_LANGUAGES)
159 listenUserInfoChange () {
160 return this.localStorageService.watch([
161 UserLocalStorageKeys.NSFW_POLICY,
162 UserLocalStorageKeys.P2P_ENABLED,
163 UserLocalStorageKeys.AUTO_PLAY_VIDEO,
164 UserLocalStorageKeys.AUTO_PLAY_VIDEO_PLAYLIST,
165 UserLocalStorageKeys.THEME,
166 UserLocalStorageKeys.VIDEO_LANGUAGES
169 filter(() => this.authService.isLoggedIn() !== true)
173 // ---------------------------------------------------------------------------
176 return UserTokens.getUserTokens(this.localStorageService)
179 setTokens (tokens: UserTokens) {
180 UserTokens.saveToLocalStorage(this.localStorageService, tokens)
184 UserTokens.flushLocalStorage(this.localStorageService)