Merge pull request #236 from NicolasConstant/topic_simplify-add-account
Topic simplify add account
This commit is contained in:
commit
c27ed4dc2d
|
@ -21,9 +21,9 @@
|
|||
"test-nowatch": "ng test --watch=false",
|
||||
"lint": "ng lint",
|
||||
"e2e": "ng e2e",
|
||||
"electron": "ng build --prod && electron .",
|
||||
"electron": "electron .",
|
||||
"electron-prod": "ng build --prod && electron .",
|
||||
"electron-debug": "ng build && electron .",
|
||||
"electron-test": "electron .",
|
||||
"dist": "npm run build && electron-builder --publish onTagOrDraft",
|
||||
"travis": "electron-builder --publish onTagOrDraft"
|
||||
},
|
||||
|
|
|
@ -1,16 +1,25 @@
|
|||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { Subscription, Observable, Subject } from 'rxjs';
|
||||
import { debounceTime, map } from 'rxjs/operators';
|
||||
import { Select } from '@ngxs/store';
|
||||
import { Select, Store } from '@ngxs/store';
|
||||
|
||||
import { faTimes } from "@fortawesome/free-solid-svg-icons";
|
||||
// import { ElectronService } from 'ngx-electron';
|
||||
|
||||
import { NavigationService, LeftPanelType, OpenLeftPanelEvent } from './services/navigation.service';
|
||||
import { StreamElement } from './states/streams.state';
|
||||
import { AccountInfo, AddAccount } from "./states/accounts.state";
|
||||
import { OpenMediaEvent } from './models/common.model';
|
||||
import { ToolsService } from './services/tools.service';
|
||||
import { MediaService } from './services/media.service';
|
||||
import { ServiceWorkerService } from './services/service-worker.service';
|
||||
import { AuthService, CurrentAuthProcess } from './services/auth.service';
|
||||
|
||||
import { MastodonWrapperService } from './services/mastodon-wrapper.service';
|
||||
import { TokenData, Account } from './services/models/mastodon.interfaces';
|
||||
import { NotificationService } from './services/notification.service';
|
||||
import { AppInfo, RegisteredAppsStateModel } from './states/registered-apps.state';
|
||||
import { HttpErrorResponse } from '@angular/common/http';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
|
@ -25,15 +34,24 @@ export class AppComponent implements OnInit, OnDestroy {
|
|||
openedMediaEvent: OpenMediaEvent
|
||||
updateAvailable: boolean;
|
||||
|
||||
private authStorageKey: string = 'tempAuth';
|
||||
|
||||
private columnEditorSub: Subscription;
|
||||
private openMediaSub: Subscription;
|
||||
private streamSub: Subscription;
|
||||
private dragoverSub: Subscription;
|
||||
private updateAvailableSub: Subscription;
|
||||
private paramsSub: Subscription;
|
||||
|
||||
@Select(state => state.streamsstatemodel.streams) streamElements$: Observable<StreamElement[]>;
|
||||
|
||||
constructor(
|
||||
private readonly router: Router,
|
||||
private readonly notificationService: NotificationService,
|
||||
private readonly store: Store,
|
||||
private readonly mastodonService: MastodonWrapperService,
|
||||
private readonly authService: AuthService,
|
||||
private readonly activatedRoute: ActivatedRoute,
|
||||
private readonly serviceWorkerService: ServiceWorkerService,
|
||||
private readonly toolsService: ToolsService,
|
||||
private readonly mediaService: MediaService,
|
||||
|
@ -41,6 +59,60 @@ export class AppComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.paramsSub = this.activatedRoute.queryParams.subscribe(params => {
|
||||
const code = params['code'];
|
||||
if (!code) {
|
||||
return;
|
||||
}
|
||||
|
||||
const appDataWrapper = <CurrentAuthProcess>JSON.parse(localStorage.getItem(this.authStorageKey));
|
||||
if (!appDataWrapper) {
|
||||
this.notificationService.notify('', 400, 'Something when wrong in the authentication process. Please retry.', true);
|
||||
this.router.navigate(['/']);
|
||||
return;
|
||||
}
|
||||
|
||||
const appInfo = this.getAllSavedApps().filter(x => x.instance === appDataWrapper.instance)[0];
|
||||
let usedTokenData: TokenData;
|
||||
this.authService.getToken(appDataWrapper.instance, appInfo.app.client_id, appInfo.app.client_secret, code, appInfo.app.redirect_uri)
|
||||
.then((tokenData: TokenData) => {
|
||||
|
||||
if(tokenData.refresh_token && !tokenData.created_at){
|
||||
const nowEpoch = Date.now() / 1000 | 0;
|
||||
tokenData.created_at = nowEpoch;
|
||||
}
|
||||
|
||||
usedTokenData = tokenData;
|
||||
|
||||
return this.mastodonService.retrieveAccountDetails({ 'instance': appDataWrapper.instance, 'id': '', 'username': '', 'order': 0, 'isSelected': true, 'token': tokenData });
|
||||
})
|
||||
.then((account: Account) => {
|
||||
var username = account.username.toLowerCase();
|
||||
var instance = appDataWrapper.instance.toLowerCase();
|
||||
|
||||
if(this.isAccountAlreadyPresent(username, instance)){
|
||||
this.notificationService.notify(null, null, `Account @${username}@${instance} is already registered`, true);
|
||||
this.router.navigate(['/']);
|
||||
return;
|
||||
}
|
||||
|
||||
const accountInfo = new AccountInfo();
|
||||
accountInfo.username = username;
|
||||
accountInfo.instance = instance;
|
||||
accountInfo.token = usedTokenData;
|
||||
|
||||
this.store.dispatch([new AddAccount(accountInfo)])
|
||||
.subscribe(() => {
|
||||
localStorage.removeItem(this.authStorageKey);
|
||||
this.router.navigate(['/']);
|
||||
});
|
||||
})
|
||||
.catch((err: HttpErrorResponse) => {
|
||||
this.notificationService.notifyHttpError(err, null);
|
||||
this.router.navigate(['/']);
|
||||
});
|
||||
});
|
||||
|
||||
this.updateAvailableSub = this.serviceWorkerService.newAppVersionIsAvailable.subscribe((updateAvailable) => {
|
||||
this.updateAvailable = updateAvailable;
|
||||
});
|
||||
|
@ -69,7 +141,6 @@ export class AppComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
});
|
||||
|
||||
|
||||
this.dragoverSub = this.dragoverSubject
|
||||
.pipe(
|
||||
debounceTime(1500)
|
||||
|
@ -85,6 +156,7 @@ export class AppComponent implements OnInit, OnDestroy {
|
|||
this.openMediaSub.unsubscribe();
|
||||
this.dragoverSub.unsubscribe();
|
||||
this.updateAvailableSub.unsubscribe();
|
||||
this.paramsSub.unsubscribe();
|
||||
}
|
||||
|
||||
closeMedia() {
|
||||
|
@ -131,4 +203,19 @@ export class AppComponent implements OnInit, OnDestroy {
|
|||
this.updateAvailable = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
private isAccountAlreadyPresent(username: string, instance: string): boolean{
|
||||
const accounts = <AccountInfo[]>this.store.snapshot().registeredaccounts.accounts;
|
||||
for (let acc of accounts) {
|
||||
if(acc.instance === instance && acc.username == username){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private getAllSavedApps(): AppInfo[] {
|
||||
const snapshot = <RegisteredAppsStateModel>this.store.snapshot().registeredapps;
|
||||
return snapshot.apps;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ import { LeftSideBarComponent } from "./components/left-side-bar/left-side-bar.c
|
|||
import { StreamsMainDisplayComponent } from "./pages/streams-main-display/streams-main-display.component";
|
||||
import { StreamComponent } from "./components/stream/stream.component";
|
||||
import { StreamsSelectionFooterComponent } from "./components/streams-selection-footer/streams-selection-footer.component";
|
||||
import { RegisterNewAccountComponent } from "./pages/register-new-account/register-new-account.component";
|
||||
// import { RegisterNewAccountComponent } from "./pages/register-new-account/register-new-account.component";
|
||||
import { AuthService } from "./services/auth.service";
|
||||
import { StreamingService } from "./services/streaming.service";
|
||||
import { RegisteredAppsState } from "./states/registered-apps.state";
|
||||
|
@ -84,10 +84,10 @@ import { environment } from '../environments/environment';
|
|||
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: "", redirectTo: "home", pathMatch: "full" },
|
||||
{ path: "home", component: StreamsMainDisplayComponent },
|
||||
{ path: "register", component: RegisterNewAccountComponent },
|
||||
{ path: "**", redirectTo: "home" }
|
||||
{ path: "", component: StreamsMainDisplayComponent },
|
||||
// { path: "home", component: StreamsMainDisplayComponent },
|
||||
// { path: "register", component: RegisterNewAccountComponent },
|
||||
{ path: "**", redirectTo: "" }
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
|
@ -98,7 +98,7 @@ const routes: Routes = [
|
|||
StreamComponent,
|
||||
StreamsSelectionFooterComponent,
|
||||
StatusComponent,
|
||||
RegisterNewAccountComponent,
|
||||
// RegisterNewAccountComponent,
|
||||
AccountIconComponent,
|
||||
FloatingColumnComponent,
|
||||
ManageAccountComponent,
|
||||
|
|
|
@ -1,124 +1,124 @@
|
|||
import { Component, OnInit, Input } from "@angular/core";
|
||||
import { Store, Select } from '@ngxs/store';
|
||||
import { ActivatedRoute, Router } from "@angular/router";
|
||||
import { HttpErrorResponse } from "@angular/common/http";
|
||||
// import { Component, OnInit, Input } from "@angular/core";
|
||||
// import { Store, Select } from '@ngxs/store';
|
||||
// import { ActivatedRoute, Router } from "@angular/router";
|
||||
// import { HttpErrorResponse } from "@angular/common/http";
|
||||
|
||||
import { AuthService, CurrentAuthProcess } from "../../services/auth.service";
|
||||
import { TokenData, Account } from "../../services/models/mastodon.interfaces";
|
||||
import { RegisteredAppsStateModel, AppInfo } from "../../states/registered-apps.state";
|
||||
import { AccountInfo, AddAccount, AccountsStateModel } from "../../states/accounts.state";
|
||||
import { NotificationService } from "../../services/notification.service";
|
||||
import { MastodonWrapperService } from '../../services/mastodon-wrapper.service';
|
||||
// import { AuthService, CurrentAuthProcess } from "../../services/auth.service";
|
||||
// import { TokenData, Account } from "../../services/models/mastodon.interfaces";
|
||||
// import { RegisteredAppsStateModel, AppInfo } from "../../states/registered-apps.state";
|
||||
// import { AccountInfo, AddAccount, AccountsStateModel } from "../../states/accounts.state";
|
||||
// import { NotificationService } from "../../services/notification.service";
|
||||
// import { MastodonWrapperService } from '../../services/mastodon-wrapper.service';
|
||||
|
||||
@Component({
|
||||
selector: "app-register-new-account",
|
||||
templateUrl: "./register-new-account.component.html",
|
||||
styleUrls: ["./register-new-account.component.scss"]
|
||||
})
|
||||
export class RegisterNewAccountComponent implements OnInit {
|
||||
@Input() mastodonFullHandle: string;
|
||||
// @Component({
|
||||
// selector: "app-register-new-account",
|
||||
// templateUrl: "./register-new-account.component.html",
|
||||
// styleUrls: ["./register-new-account.component.scss"]
|
||||
// })
|
||||
// export class RegisterNewAccountComponent implements OnInit {
|
||||
// // @Input() mastodonFullHandle: string;
|
||||
|
||||
hasError: boolean;
|
||||
errorMessage: string;
|
||||
// hasError: boolean;
|
||||
// errorMessage: string;
|
||||
|
||||
private authStorageKey: string = 'tempAuth';
|
||||
// private authStorageKey: string = 'tempAuth';
|
||||
|
||||
constructor(
|
||||
private readonly mastodonService: MastodonWrapperService,
|
||||
private readonly notificationService: NotificationService,
|
||||
private readonly authService: AuthService,
|
||||
private readonly store: Store,
|
||||
private readonly activatedRoute: ActivatedRoute,
|
||||
private readonly router: Router) {
|
||||
// constructor(
|
||||
// private readonly mastodonService: MastodonWrapperService,
|
||||
// private readonly notificationService: NotificationService,
|
||||
// private readonly authService: AuthService,
|
||||
// private readonly store: Store,
|
||||
// private readonly activatedRoute: ActivatedRoute,
|
||||
// private readonly router: Router) {
|
||||
|
||||
this.activatedRoute.queryParams.subscribe(params => {
|
||||
this.hasError = false;
|
||||
// this.activatedRoute.queryParams.subscribe(params => {
|
||||
// this.hasError = false;
|
||||
|
||||
const code = params['code'];
|
||||
if (!code) {
|
||||
this.displayError(RegistrationErrorTypes.CodeNotFound);
|
||||
return;
|
||||
}
|
||||
// const code = params['code'];
|
||||
// if (!code) {
|
||||
// this.displayError(RegistrationErrorTypes.CodeNotFound);
|
||||
// return;
|
||||
// }
|
||||
|
||||
const appDataWrapper = <CurrentAuthProcess>JSON.parse(localStorage.getItem(this.authStorageKey));
|
||||
if (!appDataWrapper) {
|
||||
this.displayError(RegistrationErrorTypes.AuthProcessNotFound);
|
||||
return;
|
||||
}
|
||||
// const appDataWrapper = <CurrentAuthProcess>JSON.parse(localStorage.getItem(this.authStorageKey));
|
||||
// if (!appDataWrapper) {
|
||||
// this.displayError(RegistrationErrorTypes.AuthProcessNotFound);
|
||||
// return;
|
||||
// }
|
||||
|
||||
const appInfo = this.getAllSavedApps().filter(x => x.instance === appDataWrapper.instance)[0];
|
||||
let usedTokenData: TokenData;
|
||||
this.authService.getToken(appDataWrapper.instance, appInfo.app.client_id, appInfo.app.client_secret, code, appInfo.app.redirect_uri)
|
||||
.then((tokenData: TokenData) => {
|
||||
// const appInfo = this.getAllSavedApps().filter(x => x.instance === appDataWrapper.instance)[0];
|
||||
// let usedTokenData: TokenData;
|
||||
// this.authService.getToken(appDataWrapper.instance, appInfo.app.client_id, appInfo.app.client_secret, code, appInfo.app.redirect_uri)
|
||||
// .then((tokenData: TokenData) => {
|
||||
|
||||
if(tokenData.refresh_token && !tokenData.created_at){
|
||||
const nowEpoch = Date.now() / 1000 | 0;
|
||||
tokenData.created_at = nowEpoch;
|
||||
}
|
||||
// if(tokenData.refresh_token && !tokenData.created_at){
|
||||
// const nowEpoch = Date.now() / 1000 | 0;
|
||||
// tokenData.created_at = nowEpoch;
|
||||
// }
|
||||
|
||||
usedTokenData = tokenData;
|
||||
// usedTokenData = tokenData;
|
||||
|
||||
return this.mastodonService.retrieveAccountDetails({ 'instance': appDataWrapper.instance, 'id': '', 'username': '', 'order': 0, 'isSelected': true, 'token': tokenData });
|
||||
})
|
||||
.then((account: Account) => {
|
||||
var username = account.username.toLowerCase();
|
||||
var instance = appDataWrapper.instance.toLowerCase();
|
||||
// return this.mastodonService.retrieveAccountDetails({ 'instance': appDataWrapper.instance, 'id': '', 'username': '', 'order': 0, 'isSelected': true, 'token': tokenData });
|
||||
// })
|
||||
// .then((account: Account) => {
|
||||
// var username = account.username.toLowerCase();
|
||||
// var instance = appDataWrapper.instance.toLowerCase();
|
||||
|
||||
if(this.isAccountAlreadyPresent(username, instance)){
|
||||
this.notificationService.notify(null, null, `Account @${username}@${instance} is already registered`, true);
|
||||
this.router.navigate(['/home']);
|
||||
return;
|
||||
}
|
||||
// if(this.isAccountAlreadyPresent(username, instance)){
|
||||
// this.notificationService.notify(null, null, `Account @${username}@${instance} is already registered`, true);
|
||||
// this.router.navigate(['/home']);
|
||||
// return;
|
||||
// }
|
||||
|
||||
const accountInfo = new AccountInfo();
|
||||
accountInfo.username = username;
|
||||
accountInfo.instance = instance;
|
||||
accountInfo.token = usedTokenData;
|
||||
// const accountInfo = new AccountInfo();
|
||||
// accountInfo.username = username;
|
||||
// accountInfo.instance = instance;
|
||||
// accountInfo.token = usedTokenData;
|
||||
|
||||
this.store.dispatch([new AddAccount(accountInfo)])
|
||||
.subscribe(() => {
|
||||
localStorage.removeItem(this.authStorageKey);
|
||||
this.router.navigate(['/home']);
|
||||
});
|
||||
})
|
||||
.catch((err: HttpErrorResponse) => {
|
||||
this.notificationService.notifyHttpError(err, null);
|
||||
});
|
||||
});
|
||||
}
|
||||
// this.store.dispatch([new AddAccount(accountInfo)])
|
||||
// .subscribe(() => {
|
||||
// localStorage.removeItem(this.authStorageKey);
|
||||
// this.router.navigate(['/home']);
|
||||
// });
|
||||
// })
|
||||
// .catch((err: HttpErrorResponse) => {
|
||||
// this.notificationService.notifyHttpError(err, null);
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
// ngOnInit() {
|
||||
// }
|
||||
|
||||
private isAccountAlreadyPresent(username: string, instance: string): boolean{
|
||||
const accounts = <AccountInfo[]>this.store.snapshot().registeredaccounts.accounts;
|
||||
for (let acc of accounts) {
|
||||
if(acc.instance === instance && acc.username == username){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// private isAccountAlreadyPresent(username: string, instance: string): boolean{
|
||||
// const accounts = <AccountInfo[]>this.store.snapshot().registeredaccounts.accounts;
|
||||
// for (let acc of accounts) {
|
||||
// if(acc.instance === instance && acc.username == username){
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
|
||||
private displayError(type: RegistrationErrorTypes) {
|
||||
this.hasError = true;
|
||||
switch (type) {
|
||||
case RegistrationErrorTypes.AuthProcessNotFound:
|
||||
this.errorMessage = 'Something when wrong in the authentication process. Please retry.'
|
||||
break;
|
||||
case RegistrationErrorTypes.CodeNotFound:
|
||||
this.errorMessage = 'No authentication code returned. Please retry.'
|
||||
break;
|
||||
}
|
||||
}
|
||||
// private displayError(type: RegistrationErrorTypes) {
|
||||
// this.hasError = true;
|
||||
// switch (type) {
|
||||
// case RegistrationErrorTypes.AuthProcessNotFound:
|
||||
// this.errorMessage = 'Something when wrong in the authentication process. Please retry.'
|
||||
// break;
|
||||
// case RegistrationErrorTypes.CodeNotFound:
|
||||
// this.errorMessage = 'No authentication code returned. Please retry.'
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
private getAllSavedApps(): AppInfo[] {
|
||||
const snapshot = <RegisteredAppsStateModel>this.store.snapshot().registeredapps;
|
||||
return snapshot.apps;
|
||||
}
|
||||
}
|
||||
// private getAllSavedApps(): AppInfo[] {
|
||||
// const snapshot = <RegisteredAppsStateModel>this.store.snapshot().registeredapps;
|
||||
// return snapshot.apps;
|
||||
// }
|
||||
// }
|
||||
|
||||
enum RegistrationErrorTypes {
|
||||
CodeNotFound,
|
||||
AuthProcessNotFound
|
||||
}
|
||||
// enum RegistrationErrorTypes {
|
||||
// CodeNotFound,
|
||||
// AuthProcessNotFound
|
||||
// }
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { Component, OnInit, OnDestroy, QueryList, ViewChildren, ElementRef } from "@angular/core";
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { Observable, Subscription } from "rxjs";
|
||||
import { Select } from "@ngxs/store";
|
||||
import scrollIntoView from "smooth-scroll-into-view-if-needed";
|
||||
|
@ -20,20 +19,10 @@ export class StreamsMainDisplayComponent implements OnInit, OnDestroy {
|
|||
private columnSelectedSub: Subscription;
|
||||
|
||||
constructor(
|
||||
private readonly router: Router,
|
||||
private readonly activatedRoute: ActivatedRoute,
|
||||
private readonly navigationService: NavigationService) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.activatedRoute.queryParams.subscribe(params => {
|
||||
const code = params['code'];
|
||||
if (code) {
|
||||
this.router.navigate(['/register'], { queryParams: { code: code} });
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
this.columnSelectedSub = this.navigationService.columnSelectedSubject.subscribe((columnIndex: number) => {
|
||||
this.focusOnColumn(columnIndex);
|
||||
});
|
||||
|
@ -55,10 +44,6 @@ export class StreamsMainDisplayComponent implements OnInit, OnDestroy {
|
|||
.then(() => {
|
||||
this.streamComponents.toArray()[columnIndex].focus();
|
||||
});
|
||||
|
||||
// setTimeout(() => {
|
||||
// this.streamComponents.toArray()[columnIndex].focus();
|
||||
// }, 500);
|
||||
}, 0);
|
||||
|
||||
|
||||
|
|
|
@ -22,6 +22,9 @@ export class MastodonWrapperService {
|
|||
let isExpired = false;
|
||||
let storedAccountInfo = this.getStoreAccountInfo(accountInfo.id);
|
||||
|
||||
if(!storedAccountInfo || !(storedAccountInfo.token))
|
||||
return Promise.resolve(accountInfo);
|
||||
|
||||
try {
|
||||
if (storedAccountInfo.token.refresh_token) {
|
||||
if (!storedAccountInfo.token.created_at || !storedAccountInfo.token.expires_in) {
|
||||
|
|
Loading…
Reference in New Issue