Skip to content
This repository has been archived by the owner on Apr 26, 2020. It is now read-only.

Commit

Permalink
feat: title bar avatar
Browse files Browse the repository at this point in the history
Change-Id: I373b412c2e710c104a5fad8b284d7a55759d3083
  • Loading branch information
myml committed Nov 15, 2018
1 parent d342de8 commit 65e7c59
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 79 deletions.
4 changes: 2 additions & 2 deletions src/web/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { DstoreModule } from './dstore/dstore.module';
import { ClientModule } from 'app/modules/client/client.module';
import { ShareModule } from 'app/modules/share/share.module';

import { MyHttpInterceptor } from './services/http-interceptor';
import { AuthInterceptor } from './services/auth-interceptor';

import { AppService } from './services/app.service';
import { CategoryService } from './services/category.service';
Expand Down Expand Up @@ -77,7 +77,7 @@ import { StoreJobErrorComponent } from './components/store-job-error/store-job-e
SearchService,
LoginService,
RecommendService,
{ provide: HTTP_INTERCEPTORS, useClass: MyHttpInterceptor, multi: true },
{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },
],
bootstrap: [AppComponent],
})
Expand Down
31 changes: 31 additions & 0 deletions src/web/src/app/services/auth-interceptor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import {
HttpHandler,
HttpRequest,
HttpInterceptor,
HttpErrorResponse,
HttpEvent,
} from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable, of, throwError } from 'rxjs';
import { catchError, take, first, switchMap, map } from 'rxjs/operators';

import { LoginService } from './login.service';
import { AuthService } from './auth.service';

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor(private authService: AuthService) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return this.authService.token$.pipe(
first(),
map(token => (!token ? req : req.clone({ setHeaders: { 'Access-Token': token } }))),
switchMap(authReq => next.handle(authReq)),
catchError((err: HttpErrorResponse) => {
if (err.status === 401) {
this.authService.authorized();
}
throw err;
}),
);
}
}
56 changes: 24 additions & 32 deletions src/web/src/app/services/auth.service.ts
Original file line number Diff line number Diff line change
@@ -1,54 +1,46 @@
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { Subject, BehaviorSubject } from 'rxjs';
import * as JwtDecode from 'jwt-decode';
import { map, skip } from 'rxjs/operators';
import { map, first, distinctUntilChanged } from 'rxjs/operators';

import { DstoreObject } from 'app/modules/client/utils/dstore-objects';
import { LoginService } from './login.service';
import { BaseService } from '../dstore/services/base.service';
import { environment } from 'environments/environment';

export interface UserInfo {
username: string;
userID: number;
}
console.log(environment);
@Injectable()
export class AuthService {
constructor(private loginService: LoginService) {
this.token$.subscribe(token => {
if (token) {
this.loginService.SetLoginStatue(true);
localStorage.setItem(this.tokenStorageKey, token);
} else {
this.loginService.SetLoginStatue(false);
localStorage.removeItem(this.tokenStorageKey);
}
});
}
constructor() {}

private tokenStorageKey = 'auth-token:' + BaseService.domainName;
private tokenSubject = new BehaviorSubject<string>(localStorage.getItem(this.tokenStorageKey));
private loginSubject = new Subject<boolean>();

token$ = this.tokenSubject.asObservable();
logged$ = this.token$.pipe(map(token => token !== null));
info$ = this.token$.pipe(
map(token => {
if (token) {
return JwtDecode(token) as UserInfo;
} else {
return null;
}
}),
);

token$ = this.tokenSubject.pipe(distinctUntilChanged());
logged$ = this.token$.pipe(map(Boolean));
info$ = this.token$.pipe(map(token => (token ? JwtDecode<UserInfo>(token) : null)));
auth$ = this.loginSubject.asObservable();
// 登录方法
login(token: string) {
localStorage.setItem(this.tokenStorageKey, token);
this.tokenSubject.next(token);
}

// 登出方法
logout() {
localStorage.removeItem(this.tokenStorageKey);
this.tokenSubject.next(null);
}

// 需要验证事件
authorized() {
this.logged$.pipe(first()).subscribe(logged => this.loginSubject.next(logged));
}
// 打开注册页面
register() {
DstoreObject.openURL(`https://account.deepin.org/register`);
}
}

export interface UserInfo {
username: string;
userID: number;
}
30 changes: 30 additions & 0 deletions src/web/src/app/services/deepin-user-info.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { environment } from 'environments/environment';
import { DeepinInfo } from 'app/dstore/services/deepin-info.model';
import { UserInfo } from './auth.service';

@Injectable({
providedIn: 'root',
})
export class DeepinUserInfoService {
private apiURL = environment.metadataServer + '/api/deepin_user';
constructor(private http: HttpClient) {}

getDeepinUserInfo(uid: number): Promise<DeepinInfo>;
getDeepinUserInfo(uidList: Array<number>): Promise<Array<DeepinInfo>>;

getDeepinUserInfo(param: number | Array<number>) {
if (typeof param === 'number') {
return this.http
.get<DeepinInfo[]>(this.apiURL, { params: { uid: String(param) } })
.toPromise()
.then(users => users.find(user => user.uid === param));
} else if (param instanceof Array) {
return this.http
.get<DeepinInfo[]>(this.apiURL, { params: { uid: param.map(String) } })
.toPromise()
.then(users => users);
}
}
}
42 changes: 0 additions & 42 deletions src/web/src/app/services/http-interceptor.ts

This file was deleted.

48 changes: 45 additions & 3 deletions src/web/src/app/services/login.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,37 @@ import { Observable, merge } from 'rxjs';

import { Channel } from 'app/modules/client/utils/channel';
import { Subject } from 'rxjs';
import { UserInfo, AuthService } from './auth.service';
import { DeepinUserInfoService } from './deepin-user-info.service';

@Injectable()
@Injectable({
providedIn: 'root',
})
export class LoginService {
constructor(private zone: NgZone) {
constructor(
private zone: NgZone,
private authService: AuthService,
private deepinService: DeepinUserInfoService,
) {
Channel.connect<boolean>('menu.loginRequested').subscribe(status => {
zone.run(() => {
this.zone.run(() => {
this.obs.next(status);
});
});

this.authService.auth$.subscribe(logged => {
if (logged) {
this.OpenLogout();
} else {
this.OpenLogin();
}
});
this.authService.logged$.subscribe(logged => {
this.SetLoginStatue(logged);
});
this.authService.info$.subscribe(info => {
this.SetLoginInfo(info);
});
}

private obs = new Subject<boolean>();
Expand All @@ -30,4 +52,24 @@ export class LoginService {
SetLoginStatue(logged: boolean) {
Channel.exec('menu.setLoginState', logged);
}

SetLoginInfo(userInfo: UserInfo) {
if (userInfo) {
// 设置头像
this.deepinService.getDeepinUserInfo(userInfo.userID).then(info => {
fetch(info.profile_image)
.then(resp => resp.blob())
.then(blob => {
return new Promise<string>(resolve => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result as string);
reader.readAsDataURL(blob);
});
})
.then(data => {
Channel.exec('menu.setUserInfo', { profile_image: data.slice(data.indexOf(',') + 1) });
});
});
}
}
}

0 comments on commit 65e7c59

Please sign in to comment.