2 import { filter, throttleTime } from 'rxjs'
3 import { Injectable } from '@angular/core'
4 import { AuthService, AuthStatus } from '@app/core/auth'
5 import { getBoolOrDefault } from '@root-helpers/local-storage-utils'
6 import { logger } from '@root-helpers/logger'
7 import { UserLocalStorageKeys, UserTokens } from '@root-helpers/users'
8 import { UserRole, UserUpdateMe } from '@shared/models'
9 import { NSFWPolicyType } from '@shared/models/videos'
10 import { ServerService } from '../server'
11 import { LocalStorageService } from '../wrappers/storage.service'
14 export class UserLocalStorageService {
17 private authService: AuthService,
18 private server: ServerService,
19 private localStorageService: LocalStorageService
21 this.authService.userInformationLoaded.subscribe({
23 const user = this.authService.getUser()
25 this.setLoggedInUser(user)
26 this.setUserInfo(user)
27 this.setTokens(user.tokens)
31 this.authService.loginChangedSource
32 .pipe(filter(status => status === AuthStatus.LoggedOut))
35 this.flushLoggedInUser()
41 this.authService.tokensRefreshed
44 const user = this.authService.getUser()
46 this.setTokens(user.tokens)
51 // ---------------------------------------------------------------------------
54 const usernameLocalStorage = this.localStorageService.getItem(UserLocalStorageKeys.USERNAME)
56 if (!usernameLocalStorage) return undefined
59 id: parseInt(this.localStorageService.getItem(UserLocalStorageKeys.ID), 10),
60 username: this.localStorageService.getItem(UserLocalStorageKeys.USERNAME),
61 email: this.localStorageService.getItem(UserLocalStorageKeys.EMAIL),
62 role: parseInt(this.localStorageService.getItem(UserLocalStorageKeys.ROLE), 10) as UserRole,
68 setLoggedInUser (user: {
74 this.localStorageService.setItem(UserLocalStorageKeys.ID, user.id.toString())
75 this.localStorageService.setItem(UserLocalStorageKeys.USERNAME, user.username)
76 this.localStorageService.setItem(UserLocalStorageKeys.EMAIL, user.email)
77 this.localStorageService.setItem(UserLocalStorageKeys.ROLE, user.role.toString())
80 flushLoggedInUser () {
81 this.localStorageService.removeItem(UserLocalStorageKeys.ID)
82 this.localStorageService.removeItem(UserLocalStorageKeys.USERNAME)
83 this.localStorageService.removeItem(UserLocalStorageKeys.EMAIL)
84 this.localStorageService.removeItem(UserLocalStorageKeys.ROLE)
87 // ---------------------------------------------------------------------------
90 let videoLanguages: string[]
93 const languagesString = this.localStorageService.getItem(UserLocalStorageKeys.VIDEO_LANGUAGES)
94 videoLanguages = languagesString && languagesString !== 'undefined'
95 ? JSON.parse(languagesString)
99 logger.error('Cannot parse desired video languages from localStorage.', err)
102 const htmlConfig = this.server.getHTMLConfig()
104 const defaultNSFWPolicy = htmlConfig.instance.defaultNSFWPolicy
105 const defaultP2PEnabled = htmlConfig.defaults.p2p.webapp.enabled
108 nsfwPolicy: this.localStorageService.getItem<NSFWPolicyType>(UserLocalStorageKeys.NSFW_POLICY) || defaultNSFWPolicy,
109 p2pEnabled: getBoolOrDefault(this.localStorageService.getItem(UserLocalStorageKeys.P2P_ENABLED), defaultP2PEnabled),
110 theme: this.localStorageService.getItem(UserLocalStorageKeys.THEME) || 'instance-default',
113 autoPlayVideo: getBoolOrDefault(this.localStorageService.getItem(UserLocalStorageKeys.AUTO_PLAY_VIDEO), true),
114 autoPlayNextVideo: getBoolOrDefault(this.localStorageService.getItem(UserLocalStorageKeys.AUTO_PLAY_NEXT_VIDEO), false),
115 autoPlayNextVideoPlaylist: getBoolOrDefault(this.localStorageService.getItem(UserLocalStorageKeys.AUTO_PLAY_VIDEO_PLAYLIST), true)
119 setUserInfo (profile: UserUpdateMe) {
120 const localStorageKeys: { [ id in keyof UserUpdateMe ]: string } = {
121 nsfwPolicy: UserLocalStorageKeys.NSFW_POLICY,
122 p2pEnabled: UserLocalStorageKeys.P2P_ENABLED,
123 autoPlayNextVideo: UserLocalStorageKeys.AUTO_PLAY_VIDEO,
124 autoPlayNextVideoPlaylist: UserLocalStorageKeys.AUTO_PLAY_VIDEO_PLAYLIST,
125 theme: UserLocalStorageKeys.THEME,
126 videoLanguages: UserLocalStorageKeys.VIDEO_LANGUAGES
129 const obj = Object.keys(localStorageKeys)
130 .filter(key => key in profile)
131 .map(key => ([ localStorageKeys[key], profile[key] ]))
133 for (const [ key, value ] of obj) {
135 if (value === undefined) {
136 this.localStorageService.removeItem(key)
140 const localStorageValue = typeof value === 'string'
142 : JSON.stringify(value)
144 this.localStorageService.setItem(key, localStorageValue)
146 logger.error(`Cannot set ${key}->${value} in localStorage. Likely due to a value impossible to stringify.`, err)
152 this.localStorageService.removeItem(UserLocalStorageKeys.NSFW_POLICY)
153 this.localStorageService.removeItem(UserLocalStorageKeys.P2P_ENABLED)
154 this.localStorageService.removeItem(UserLocalStorageKeys.AUTO_PLAY_VIDEO)
155 this.localStorageService.removeItem(UserLocalStorageKeys.AUTO_PLAY_VIDEO_PLAYLIST)
156 this.localStorageService.removeItem(UserLocalStorageKeys.THEME)
157 this.localStorageService.removeItem(UserLocalStorageKeys.VIDEO_LANGUAGES)
160 listenUserInfoChange () {
161 return this.localStorageService.watch([
162 UserLocalStorageKeys.NSFW_POLICY,
163 UserLocalStorageKeys.P2P_ENABLED,
164 UserLocalStorageKeys.AUTO_PLAY_VIDEO,
165 UserLocalStorageKeys.AUTO_PLAY_VIDEO_PLAYLIST,
166 UserLocalStorageKeys.THEME,
167 UserLocalStorageKeys.VIDEO_LANGUAGES
170 filter(() => this.authService.isLoggedIn() !== true)
174 // ---------------------------------------------------------------------------
177 return UserTokens.getUserTokens(this.localStorageService)
180 setTokens (tokens: UserTokens) {
181 UserTokens.saveToLocalStorage(this.localStorageService, tokens)
185 UserTokens.flushLocalStorage(this.localStorageService)