Client: add ability for user to change nsfw settings
This commit is contained in:
parent
92fb909c9b
commit
af5e743b01
|
@ -0,0 +1,24 @@
|
||||||
|
<div *ngIf="error" class="alert alert-danger">{{ error }}</div>
|
||||||
|
|
||||||
|
<form role="form" (ngSubmit)="changePassword()" [formGroup]="form">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="new-password">New password</label>
|
||||||
|
<input
|
||||||
|
type="password" class="form-control" id="new-password"
|
||||||
|
formControlName="new-password"
|
||||||
|
>
|
||||||
|
<div *ngIf="formErrors['new-password']" class="alert alert-danger">
|
||||||
|
{{ formErrors['new-password'] }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="name">Confirm new password</label>
|
||||||
|
<input
|
||||||
|
type="password" class="form-control" id="new-confirmed-password"
|
||||||
|
formControlName="new-confirmed-password"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input type="submit" value="Change password" class="btn btn-default" [disabled]="!form.valid">
|
||||||
|
</form>
|
|
@ -0,0 +1,66 @@
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
|
||||||
|
import { NotificationsService } from 'angular2-notifications';
|
||||||
|
|
||||||
|
import { FormReactive, UserService, USER_PASSWORD } from '../../shared';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'my-account-change-password',
|
||||||
|
templateUrl: './account-change-password.component.html'
|
||||||
|
})
|
||||||
|
|
||||||
|
export class AccountChangePasswordComponent extends FormReactive implements OnInit {
|
||||||
|
error: string = null;
|
||||||
|
|
||||||
|
form: FormGroup;
|
||||||
|
formErrors = {
|
||||||
|
'new-password': '',
|
||||||
|
'new-confirmed-password': ''
|
||||||
|
};
|
||||||
|
validationMessages = {
|
||||||
|
'new-password': USER_PASSWORD.MESSAGES,
|
||||||
|
'new-confirmed-password': USER_PASSWORD.MESSAGES
|
||||||
|
};
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private formBuilder: FormBuilder,
|
||||||
|
private router: Router,
|
||||||
|
private notificationsService: NotificationsService,
|
||||||
|
private userService: UserService
|
||||||
|
) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
buildForm() {
|
||||||
|
this.form = this.formBuilder.group({
|
||||||
|
'new-password': [ '', USER_PASSWORD.VALIDATORS ],
|
||||||
|
'new-confirmed-password': [ '', USER_PASSWORD.VALIDATORS ],
|
||||||
|
});
|
||||||
|
|
||||||
|
this.form.valueChanges.subscribe(data => this.onValueChanged(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.buildForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
changePassword() {
|
||||||
|
const newPassword = this.form.value['new-password'];
|
||||||
|
const newConfirmedPassword = this.form.value['new-confirmed-password'];
|
||||||
|
|
||||||
|
this.error = null;
|
||||||
|
|
||||||
|
if (newPassword !== newConfirmedPassword) {
|
||||||
|
this.error = 'The new password and the confirmed password do not correspond.';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.userService.changePassword(newPassword).subscribe(
|
||||||
|
() => this.notificationsService.success('Success', 'Password updated.'),
|
||||||
|
|
||||||
|
err => this.error = err
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
export * from './account-change-password.component';
|
|
@ -0,0 +1,16 @@
|
||||||
|
<div *ngIf="error" class="alert alert-danger">{{ error }}</div>
|
||||||
|
|
||||||
|
<form role="form" (ngSubmit)="updateDetails()" [formGroup]="form">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="displayNSFW">Display NSFW videos</label>
|
||||||
|
<input
|
||||||
|
type="checkbox" id="displayNSFW"
|
||||||
|
formControlName="displayNSFW"
|
||||||
|
>
|
||||||
|
<div *ngIf="formErrors['displayNSFW']" class="alert alert-danger">
|
||||||
|
{{ formErrors['displayNSFW'] }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input type="submit" value="Update" class="btn btn-default" [disabled]="!form.valid">
|
||||||
|
</form>
|
|
@ -0,0 +1,68 @@
|
||||||
|
import { Component, OnInit, Input } from '@angular/core';
|
||||||
|
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
|
||||||
|
import { NotificationsService } from 'angular2-notifications';
|
||||||
|
|
||||||
|
import { AuthService } from '../../core';
|
||||||
|
import {
|
||||||
|
FormReactive,
|
||||||
|
User,
|
||||||
|
UserService,
|
||||||
|
USER_PASSWORD
|
||||||
|
} from '../../shared';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'my-account-details',
|
||||||
|
templateUrl: './account-details.component.html'
|
||||||
|
})
|
||||||
|
|
||||||
|
export class AccountDetailsComponent extends FormReactive implements OnInit {
|
||||||
|
@Input() user: User = null;
|
||||||
|
|
||||||
|
error: string = null;
|
||||||
|
|
||||||
|
form: FormGroup;
|
||||||
|
formErrors = {};
|
||||||
|
validationMessages = {};
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private authService: AuthService,
|
||||||
|
private formBuilder: FormBuilder,
|
||||||
|
private router: Router,
|
||||||
|
private notificationsService: NotificationsService,
|
||||||
|
private userService: UserService
|
||||||
|
) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
buildForm() {
|
||||||
|
this.form = this.formBuilder.group({
|
||||||
|
displayNSFW: [ this.user.displayNSFW ],
|
||||||
|
});
|
||||||
|
|
||||||
|
this.form.valueChanges.subscribe(data => this.onValueChanged(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.buildForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
updateDetails() {
|
||||||
|
const displayNSFW = this.form.value['displayNSFW'];
|
||||||
|
const details = {
|
||||||
|
displayNSFW
|
||||||
|
};
|
||||||
|
|
||||||
|
this.error = null;
|
||||||
|
this.userService.updateDetails(details).subscribe(
|
||||||
|
() => {
|
||||||
|
this.notificationsService.success('Success', 'Informations updated.');
|
||||||
|
|
||||||
|
this.authService.refreshUserInformations();
|
||||||
|
},
|
||||||
|
|
||||||
|
err => this.error = err
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
export * from './account-details.component';
|
|
@ -1,26 +1,11 @@
|
||||||
<h3>Account</h3>
|
<h3>Account</h3>
|
||||||
|
|
||||||
<div *ngIf="error" class="alert alert-danger">{{ error }}</div>
|
<div class="block">
|
||||||
|
<h4>Change password</h4>
|
||||||
|
<my-account-change-password></my-account-change-password>
|
||||||
|
</div>
|
||||||
|
|
||||||
<form role="form" (ngSubmit)="changePassword()" [formGroup]="form">
|
<div class="block">
|
||||||
<div class="form-group">
|
<h4>Update my informations</h4>
|
||||||
<label for="new-password">New password</label>
|
<my-account-details [user]="user"></my-account-details>
|
||||||
<input
|
</div>
|
||||||
type="password" class="form-control" id="new-password"
|
|
||||||
formControlName="new-password"
|
|
||||||
>
|
|
||||||
<div *ngIf="formErrors['new-password']" class="alert alert-danger">
|
|
||||||
{{ formErrors['new-password'] }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="name">Confirm new password</label>
|
|
||||||
<input
|
|
||||||
type="password" class="form-control" id="new-confirmed-password"
|
|
||||||
formControlName="new-confirmed-password"
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<input type="submit" value="Change password" class="btn btn-default" [disabled]="!form.valid">
|
|
||||||
</form>
|
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
.block {
|
||||||
|
margin-top: 40px;
|
||||||
|
}
|
|
@ -4,63 +4,25 @@ import { Router } from '@angular/router';
|
||||||
|
|
||||||
import { NotificationsService } from 'angular2-notifications';
|
import { NotificationsService } from 'angular2-notifications';
|
||||||
|
|
||||||
import { FormReactive, UserService, USER_PASSWORD } from '../shared';
|
import { AuthService } from '../core';
|
||||||
|
import {
|
||||||
|
FormReactive,
|
||||||
|
User,
|
||||||
|
UserService,
|
||||||
|
USER_PASSWORD
|
||||||
|
} from '../shared';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'my-account',
|
selector: 'my-account',
|
||||||
templateUrl: './account.component.html'
|
templateUrl: './account.component.html',
|
||||||
|
styleUrls: [ './account.component.scss' ]
|
||||||
})
|
})
|
||||||
|
export class AccountComponent implements OnInit {
|
||||||
|
user: User = null;
|
||||||
|
|
||||||
export class AccountComponent extends FormReactive implements OnInit {
|
constructor(private authService: AuthService) {}
|
||||||
error: string = null;
|
|
||||||
|
|
||||||
form: FormGroup;
|
|
||||||
formErrors = {
|
|
||||||
'new-password': '',
|
|
||||||
'new-confirmed-password': ''
|
|
||||||
};
|
|
||||||
validationMessages = {
|
|
||||||
'new-password': USER_PASSWORD.MESSAGES,
|
|
||||||
'new-confirmed-password': USER_PASSWORD.MESSAGES
|
|
||||||
};
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private formBuilder: FormBuilder,
|
|
||||||
private router: Router,
|
|
||||||
private notificationsService: NotificationsService,
|
|
||||||
private userService: UserService
|
|
||||||
) {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
buildForm() {
|
|
||||||
this.form = this.formBuilder.group({
|
|
||||||
'new-password': [ '', USER_PASSWORD.VALIDATORS ],
|
|
||||||
'new-confirmed-password': [ '', USER_PASSWORD.VALIDATORS ],
|
|
||||||
});
|
|
||||||
|
|
||||||
this.form.valueChanges.subscribe(data => this.onValueChanged(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.buildForm();
|
this.user = this.authService.getUser();
|
||||||
}
|
|
||||||
|
|
||||||
changePassword() {
|
|
||||||
const newPassword = this.form.value['new-password'];
|
|
||||||
const newConfirmedPassword = this.form.value['new-confirmed-password'];
|
|
||||||
|
|
||||||
this.error = null;
|
|
||||||
|
|
||||||
if (newPassword !== newConfirmedPassword) {
|
|
||||||
this.error = 'The new password and the confirmed password do not correspond.';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.userService.changePassword(newPassword).subscribe(
|
|
||||||
() => this.notificationsService.success('Success', 'Password updated.'),
|
|
||||||
|
|
||||||
err => this.error = err
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,8 @@ import { NgModule } from '@angular/core';
|
||||||
|
|
||||||
import { AccountRoutingModule } from './account-routing.module';
|
import { AccountRoutingModule } from './account-routing.module';
|
||||||
import { AccountComponent } from './account.component';
|
import { AccountComponent } from './account.component';
|
||||||
|
import { AccountChangePasswordComponent } from './account-change-password';
|
||||||
|
import { AccountDetailsComponent } from './account-details';
|
||||||
import { AccountService } from './account.service';
|
import { AccountService } from './account.service';
|
||||||
import { SharedModule } from '../shared';
|
import { SharedModule } from '../shared';
|
||||||
|
|
||||||
|
@ -12,7 +14,9 @@ import { SharedModule } from '../shared';
|
||||||
],
|
],
|
||||||
|
|
||||||
declarations: [
|
declarations: [
|
||||||
AccountComponent
|
AccountComponent,
|
||||||
|
AccountChangePasswordComponent,
|
||||||
|
AccountDetailsComponent
|
||||||
],
|
],
|
||||||
|
|
||||||
exports: [
|
exports: [
|
||||||
|
|
|
@ -67,7 +67,7 @@ export class AuthUser extends User {
|
||||||
localStorage.setItem(AuthUser.KEYS.ID, this.id.toString());
|
localStorage.setItem(AuthUser.KEYS.ID, this.id.toString());
|
||||||
localStorage.setItem(AuthUser.KEYS.USERNAME, this.username);
|
localStorage.setItem(AuthUser.KEYS.USERNAME, this.username);
|
||||||
localStorage.setItem(AuthUser.KEYS.ROLE, this.role);
|
localStorage.setItem(AuthUser.KEYS.ROLE, this.role);
|
||||||
localStorage.setItem(AuthUser.KEYS.DISPLAY_NSFW, JSON.stringify(this.displayNSFW);
|
localStorage.setItem(AuthUser.KEYS.DISPLAY_NSFW, JSON.stringify(this.displayNSFW));
|
||||||
this.tokens.save();
|
this.tokens.save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,7 +125,7 @@ export class AuthService {
|
||||||
res.username = username;
|
res.username = username;
|
||||||
return res;
|
return res;
|
||||||
})
|
})
|
||||||
.flatMap(res => this.fetchUserInformations(res))
|
.flatMap(res => this.mergeUserInformations(res))
|
||||||
.map(res => this.handleLogin(res))
|
.map(res => this.handleLogin(res))
|
||||||
.catch((res) => this.restExtractor.handleError(res));
|
.catch((res) => this.restExtractor.handleError(res));
|
||||||
}
|
}
|
||||||
|
@ -178,7 +178,23 @@ export class AuthService {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private fetchUserInformations (obj: any) {
|
refreshUserInformations() {
|
||||||
|
const obj = {
|
||||||
|
access_token: this.user.getAccessToken()
|
||||||
|
};
|
||||||
|
|
||||||
|
this.mergeUserInformations(obj)
|
||||||
|
.subscribe(
|
||||||
|
res => {
|
||||||
|
this.user.displayNSFW = res.displayNSFW;
|
||||||
|
this.user.role = res.role;
|
||||||
|
|
||||||
|
this.user.save();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private mergeUserInformations(obj: { access_token: string }) {
|
||||||
// Do not call authHttp here to avoid circular dependencies headaches
|
// Do not call authHttp here to avoid circular dependencies headaches
|
||||||
|
|
||||||
const headers = new Headers();
|
const headers = new Headers();
|
||||||
|
@ -187,9 +203,13 @@ export class AuthService {
|
||||||
return this.http.get(AuthService.BASE_USER_INFORMATIONS_URL, { headers })
|
return this.http.get(AuthService.BASE_USER_INFORMATIONS_URL, { headers })
|
||||||
.map(res => res.json())
|
.map(res => res.json())
|
||||||
.map(res => {
|
.map(res => {
|
||||||
obj.id = res.id;
|
const newProperties = {
|
||||||
obj.role = res.role;
|
id: res.id,
|
||||||
return obj;
|
role: res.role,
|
||||||
|
displayNSFW: res.displayNSFW
|
||||||
|
};
|
||||||
|
|
||||||
|
return Object.assign(obj, newProperties);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -198,13 +218,14 @@ export class AuthService {
|
||||||
const id = obj.id;
|
const id = obj.id;
|
||||||
const username = obj.username;
|
const username = obj.username;
|
||||||
const role = obj.role;
|
const role = obj.role;
|
||||||
|
const displayNSFW = obj.displayNSFW;
|
||||||
const hashTokens = {
|
const hashTokens = {
|
||||||
access_token: obj.access_token,
|
access_token: obj.access_token,
|
||||||
token_type: obj.token_type,
|
token_type: obj.token_type,
|
||||||
refresh_token: obj.refresh_token
|
refresh_token: obj.refresh_token
|
||||||
};
|
};
|
||||||
|
|
||||||
this.user = new AuthUser({ id, username, role }, hashTokens);
|
this.user = new AuthUser({ id, username, role, displayNSFW }, hashTokens);
|
||||||
this.user.save();
|
this.user.save();
|
||||||
|
|
||||||
this.setStatus(AuthStatus.LoggedIn);
|
this.setStatus(AuthStatus.LoggedIn);
|
||||||
|
|
|
@ -33,4 +33,12 @@ export class UserService {
|
||||||
.map(this.restExtractor.extractDataBool)
|
.map(this.restExtractor.extractDataBool)
|
||||||
.catch((res) => this.restExtractor.handleError(res));
|
.catch((res) => this.restExtractor.handleError(res));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateDetails(details: { displayNSFW: boolean }) {
|
||||||
|
const url = UserService.BASE_USERS_URL + this.authService.getUser().id;
|
||||||
|
|
||||||
|
return this.authHttp.put(url, details)
|
||||||
|
.map(this.restExtractor.extractDataBool)
|
||||||
|
.catch((res) => this.restExtractor.handleError(res));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue