diff options
author | Rigel Kent <sendmemail@rigelk.eu> | 2020-02-28 13:52:21 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-02-28 13:52:21 +0100 |
commit | d3217560a611b94f888ecf3de93b428a7521d4de (patch) | |
tree | 26fc984f351afb994dc13c94e138476ded50c76a /client/src/app/shared/users | |
parent | 64645512b08875c18ebdc009a550cdfa69def955 (diff) | |
download | PeerTube-d3217560a611b94f888ecf3de93b428a7521d4de.tar.gz PeerTube-d3217560a611b94f888ecf3de93b428a7521d4de.tar.zst PeerTube-d3217560a611b94f888ecf3de93b428a7521d4de.zip |
Add visitor settings, rework logged-in dropdown (#2514)
* Add visitor settings, rework logged-in dropdown
* Make user dropdown P2P switch functional
* Fix lint
* Fix unnecessary notification when user logs out
* Simplify visitor settings code and remove unnecessary icons
* Catch parsing errors and reindent menu styles
Diffstat (limited to 'client/src/app/shared/users')
-rw-r--r-- | client/src/app/shared/users/user.model.ts | 29 | ||||
-rw-r--r-- | client/src/app/shared/users/user.service.ts | 77 |
2 files changed, 92 insertions, 14 deletions
diff --git a/client/src/app/shared/users/user.model.ts b/client/src/app/shared/users/user.model.ts index 7707d7dda..a37cae749 100644 --- a/client/src/app/shared/users/user.model.ts +++ b/client/src/app/shared/users/user.model.ts | |||
@@ -1,10 +1,32 @@ | |||
1 | import { hasUserRight, User as UserServerModel, UserNotificationSetting, UserRight, UserRole, VideoChannel } from '../../../../../shared' | 1 | import { |
2 | hasUserRight, | ||
3 | User as UserServerModel, | ||
4 | UserNotificationSetting, | ||
5 | UserRight, | ||
6 | UserRole | ||
7 | } from '../../../../../shared/models/users' | ||
8 | import { VideoChannel } from '../../../../../shared/models/videos' | ||
2 | import { NSFWPolicyType } from '../../../../../shared/models/videos/nsfw-policy.type' | 9 | import { NSFWPolicyType } from '../../../../../shared/models/videos/nsfw-policy.type' |
3 | import { Account } from '@app/shared/account/account.model' | 10 | import { Account } from '@app/shared/account/account.model' |
4 | import { Avatar } from '../../../../../shared/models/avatars/avatar.model' | 11 | import { Avatar } from '../../../../../shared/models/avatars/avatar.model' |
5 | import { UserAdminFlag } from '@shared/models/users/user-flag.model' | 12 | import { UserAdminFlag } from '@shared/models/users/user-flag.model' |
6 | 13 | ||
7 | export class User implements UserServerModel { | 14 | export class User implements UserServerModel { |
15 | static KEYS = { | ||
16 | ID: 'id', | ||
17 | ROLE: 'role', | ||
18 | EMAIL: 'email', | ||
19 | VIDEOS_HISTORY_ENABLED: 'videos-history-enabled', | ||
20 | USERNAME: 'username', | ||
21 | NSFW_POLICY: 'nsfw_policy', | ||
22 | WEBTORRENT_ENABLED: 'peertube-videojs-' + 'webtorrent_enabled', | ||
23 | AUTO_PLAY_VIDEO: 'auto_play_video', | ||
24 | SESSION_STORAGE_AUTO_PLAY_NEXT_VIDEO: 'auto_play_next_video', | ||
25 | AUTO_PLAY_VIDEO_PLAYLIST: 'auto_play_video_playlist', | ||
26 | THEME: 'last_active_theme', | ||
27 | VIDEO_LANGUAGES: 'video_languages' | ||
28 | } | ||
29 | |||
8 | id: number | 30 | id: number |
9 | username: string | 31 | username: string |
10 | email: string | 32 | email: string |
@@ -60,8 +82,11 @@ export class User implements UserServerModel { | |||
60 | 82 | ||
61 | this.nsfwPolicy = hash.nsfwPolicy | 83 | this.nsfwPolicy = hash.nsfwPolicy |
62 | this.webTorrentEnabled = hash.webTorrentEnabled | 84 | this.webTorrentEnabled = hash.webTorrentEnabled |
63 | this.videosHistoryEnabled = hash.videosHistoryEnabled | ||
64 | this.autoPlayVideo = hash.autoPlayVideo | 85 | this.autoPlayVideo = hash.autoPlayVideo |
86 | this.autoPlayNextVideo = hash.autoPlayNextVideo | ||
87 | this.autoPlayNextVideoPlaylist = hash.autoPlayNextVideoPlaylist | ||
88 | this.videosHistoryEnabled = hash.videosHistoryEnabled | ||
89 | this.videoLanguages = hash.videoLanguages | ||
65 | 90 | ||
66 | this.theme = hash.theme | 91 | this.theme = hash.theme |
67 | 92 | ||
diff --git a/client/src/app/shared/users/user.service.ts b/client/src/app/shared/users/user.service.ts index e24d91df3..a79343646 100644 --- a/client/src/app/shared/users/user.service.ts +++ b/client/src/app/shared/users/user.service.ts | |||
@@ -1,8 +1,8 @@ | |||
1 | import { from, Observable, of } from 'rxjs' | 1 | import { from, Observable } from 'rxjs' |
2 | import { catchError, concatMap, map, share, shareReplay, tap, toArray } from 'rxjs/operators' | 2 | import { catchError, concatMap, map, shareReplay, toArray } from 'rxjs/operators' |
3 | import { HttpClient, HttpParams } from '@angular/common/http' | 3 | import { HttpClient, HttpParams } from '@angular/common/http' |
4 | import { Injectable } from '@angular/core' | 4 | import { Injectable } from '@angular/core' |
5 | import { ResultList, User, UserCreate, UserRole, UserUpdate, UserUpdateMe, UserVideoQuota } from '../../../../../shared' | 5 | import { ResultList, User as UserServerModel, UserCreate, UserRole, UserUpdate, UserUpdateMe, UserVideoQuota } from '../../../../../shared' |
6 | import { environment } from '../../../environments/environment' | 6 | import { environment } from '../../../environments/environment' |
7 | import { RestExtractor, RestPagination, RestService } from '../rest' | 7 | import { RestExtractor, RestPagination, RestService } from '../rest' |
8 | import { Avatar } from '../../../../../shared/models/avatars/avatar.model' | 8 | import { Avatar } from '../../../../../shared/models/avatars/avatar.model' |
@@ -10,6 +10,10 @@ import { SortMeta } from 'primeng/api' | |||
10 | import { BytesPipe } from 'ngx-pipes' | 10 | import { BytesPipe } from 'ngx-pipes' |
11 | import { I18n } from '@ngx-translate/i18n-polyfill' | 11 | import { I18n } from '@ngx-translate/i18n-polyfill' |
12 | import { UserRegister } from '@shared/models/users/user-register.model' | 12 | import { UserRegister } from '@shared/models/users/user-register.model' |
13 | import { User } from './user.model' | ||
14 | import { NSFWPolicyType } from '@shared/models/videos/nsfw-policy.type' | ||
15 | import { has } from 'lodash-es' | ||
16 | import { LocalStorageService, SessionStorageService } from '../misc/storage.service' | ||
13 | 17 | ||
14 | @Injectable() | 18 | @Injectable() |
15 | export class UserService { | 19 | export class UserService { |
@@ -17,12 +21,14 @@ export class UserService { | |||
17 | 21 | ||
18 | private bytesPipe = new BytesPipe() | 22 | private bytesPipe = new BytesPipe() |
19 | 23 | ||
20 | private userCache: { [ id: number ]: Observable<User> } = {} | 24 | private userCache: { [ id: number ]: Observable<UserServerModel> } = {} |
21 | 25 | ||
22 | constructor ( | 26 | constructor ( |
23 | private authHttp: HttpClient, | 27 | private authHttp: HttpClient, |
24 | private restExtractor: RestExtractor, | 28 | private restExtractor: RestExtractor, |
25 | private restService: RestService, | 29 | private restService: RestService, |
30 | private localStorageService: LocalStorageService, | ||
31 | private sessionStorageService: SessionStorageService, | ||
26 | private i18n: I18n | 32 | private i18n: I18n |
27 | ) { } | 33 | ) { } |
28 | 34 | ||
@@ -64,6 +70,30 @@ export class UserService { | |||
64 | ) | 70 | ) |
65 | } | 71 | } |
66 | 72 | ||
73 | updateMyAnonymousProfile (profile: UserUpdateMe) { | ||
74 | const supportedKeys = { | ||
75 | // local storage keys | ||
76 | nsfwPolicy: (val: NSFWPolicyType) => this.localStorageService.setItem(User.KEYS.NSFW_POLICY, val), | ||
77 | webTorrentEnabled: (val: boolean) => this.localStorageService.setItem(User.KEYS.WEBTORRENT_ENABLED, String(val)), | ||
78 | autoPlayVideo: (val: boolean) => this.localStorageService.setItem(User.KEYS.AUTO_PLAY_VIDEO, String(val)), | ||
79 | autoPlayNextVideoPlaylist: (val: boolean) => this.localStorageService.setItem(User.KEYS.AUTO_PLAY_VIDEO_PLAYLIST, String(val)), | ||
80 | theme: (val: string) => this.localStorageService.setItem(User.KEYS.THEME, val), | ||
81 | videoLanguages: (val: string[]) => this.localStorageService.setItem(User.KEYS.VIDEO_LANGUAGES, JSON.stringify(val)), | ||
82 | |||
83 | // session storage keys | ||
84 | autoPlayNextVideo: (val: boolean) => | ||
85 | this.sessionStorageService.setItem(User.KEYS.SESSION_STORAGE_AUTO_PLAY_NEXT_VIDEO, String(val)) | ||
86 | } | ||
87 | |||
88 | for (const key of Object.keys(profile)) { | ||
89 | try { | ||
90 | if (has(supportedKeys, key)) supportedKeys[key](profile[key]) | ||
91 | } catch (err) { | ||
92 | console.error(`Cannot set item ${key} in localStorage. Likely due to a value impossible to stringify.`, err) | ||
93 | } | ||
94 | } | ||
95 | } | ||
96 | |||
67 | deleteMe () { | 97 | deleteMe () { |
68 | const url = UserService.BASE_USERS_URL + 'me' | 98 | const url = UserService.BASE_USERS_URL + 'me' |
69 | 99 | ||
@@ -187,7 +217,7 @@ export class UserService { | |||
187 | ) | 217 | ) |
188 | } | 218 | } |
189 | 219 | ||
190 | updateUsers (users: User[], userUpdate: UserUpdate) { | 220 | updateUsers (users: UserServerModel[], userUpdate: UserUpdate) { |
191 | return from(users) | 221 | return from(users) |
192 | .pipe( | 222 | .pipe( |
193 | concatMap(u => this.authHttp.put(UserService.BASE_USERS_URL + u.id, userUpdate)), | 223 | concatMap(u => this.authHttp.put(UserService.BASE_USERS_URL + u.id, userUpdate)), |
@@ -205,17 +235,40 @@ export class UserService { | |||
205 | } | 235 | } |
206 | 236 | ||
207 | getUser (userId: number) { | 237 | getUser (userId: number) { |
208 | return this.authHttp.get<User>(UserService.BASE_USERS_URL + userId) | 238 | return this.authHttp.get<UserServerModel>(UserService.BASE_USERS_URL + userId) |
209 | .pipe(catchError(err => this.restExtractor.handleError(err))) | 239 | .pipe(catchError(err => this.restExtractor.handleError(err))) |
210 | } | 240 | } |
211 | 241 | ||
212 | getUsers (pagination: RestPagination, sort: SortMeta, search?: string): Observable<ResultList<User>> { | 242 | getAnonymousUser () { |
243 | let videoLanguages | ||
244 | try { | ||
245 | videoLanguages = JSON.parse(this.localStorageService.getItem(User.KEYS.VIDEO_LANGUAGES)) | ||
246 | } catch (err) { | ||
247 | videoLanguages = null | ||
248 | console.error('Cannot parse desired video languages from localStorage.', err) | ||
249 | } | ||
250 | |||
251 | return new User({ | ||
252 | // local storage keys | ||
253 | nsfwPolicy: this.localStorageService.getItem(User.KEYS.NSFW_POLICY) as NSFWPolicyType, | ||
254 | webTorrentEnabled: this.localStorageService.getItem(User.KEYS.WEBTORRENT_ENABLED) !== 'false', | ||
255 | autoPlayVideo: this.localStorageService.getItem(User.KEYS.AUTO_PLAY_VIDEO) === 'true', | ||
256 | autoPlayNextVideoPlaylist: this.localStorageService.getItem(User.KEYS.AUTO_PLAY_VIDEO_PLAYLIST) === 'true', | ||
257 | theme: this.localStorageService.getItem(User.KEYS.THEME) || 'default', | ||
258 | videoLanguages, | ||
259 | |||
260 | // session storage keys | ||
261 | autoPlayNextVideo: this.sessionStorageService.getItem(User.KEYS.SESSION_STORAGE_AUTO_PLAY_NEXT_VIDEO) === 'true' | ||
262 | }) | ||
263 | } | ||
264 | |||
265 | getUsers (pagination: RestPagination, sort: SortMeta, search?: string): Observable<ResultList<UserServerModel>> { | ||
213 | let params = new HttpParams() | 266 | let params = new HttpParams() |
214 | params = this.restService.addRestGetParams(params, pagination, sort) | 267 | params = this.restService.addRestGetParams(params, pagination, sort) |
215 | 268 | ||
216 | if (search) params = params.append('search', search) | 269 | if (search) params = params.append('search', search) |
217 | 270 | ||
218 | return this.authHttp.get<ResultList<User>>(UserService.BASE_USERS_URL, { params }) | 271 | return this.authHttp.get<ResultList<UserServerModel>>(UserService.BASE_USERS_URL, { params }) |
219 | .pipe( | 272 | .pipe( |
220 | map(res => this.restExtractor.convertResultListDateToHuman(res)), | 273 | map(res => this.restExtractor.convertResultListDateToHuman(res)), |
221 | map(res => this.restExtractor.applyToResultListData(res, this.formatUser.bind(this))), | 274 | map(res => this.restExtractor.applyToResultListData(res, this.formatUser.bind(this))), |
@@ -223,7 +276,7 @@ export class UserService { | |||
223 | ) | 276 | ) |
224 | } | 277 | } |
225 | 278 | ||
226 | removeUser (usersArg: User | User[]) { | 279 | removeUser (usersArg: UserServerModel | UserServerModel[]) { |
227 | const users = Array.isArray(usersArg) ? usersArg : [ usersArg ] | 280 | const users = Array.isArray(usersArg) ? usersArg : [ usersArg ] |
228 | 281 | ||
229 | return from(users) | 282 | return from(users) |
@@ -234,7 +287,7 @@ export class UserService { | |||
234 | ) | 287 | ) |
235 | } | 288 | } |
236 | 289 | ||
237 | banUsers (usersArg: User | User[], reason?: string) { | 290 | banUsers (usersArg: UserServerModel | UserServerModel[], reason?: string) { |
238 | const body = reason ? { reason } : {} | 291 | const body = reason ? { reason } : {} |
239 | const users = Array.isArray(usersArg) ? usersArg : [ usersArg ] | 292 | const users = Array.isArray(usersArg) ? usersArg : [ usersArg ] |
240 | 293 | ||
@@ -246,7 +299,7 @@ export class UserService { | |||
246 | ) | 299 | ) |
247 | } | 300 | } |
248 | 301 | ||
249 | unbanUsers (usersArg: User | User[]) { | 302 | unbanUsers (usersArg: UserServerModel | UserServerModel[]) { |
250 | const users = Array.isArray(usersArg) ? usersArg : [ usersArg ] | 303 | const users = Array.isArray(usersArg) ? usersArg : [ usersArg ] |
251 | 304 | ||
252 | return from(users) | 305 | return from(users) |
@@ -257,7 +310,7 @@ export class UserService { | |||
257 | ) | 310 | ) |
258 | } | 311 | } |
259 | 312 | ||
260 | private formatUser (user: User) { | 313 | private formatUser (user: UserServerModel) { |
261 | let videoQuota | 314 | let videoQuota |
262 | if (user.videoQuota === -1) { | 315 | if (user.videoQuota === -1) { |
263 | videoQuota = this.i18n('Unlimited') | 316 | videoQuota = this.i18n('Unlimited') |