Merge pull request #5005 from GabrielInTheWorld/freshSpinner
Hotfix: Fresh login does not get the real user.
This commit is contained in:
commit
02c745ed75
@ -2,7 +2,7 @@ import { ApplicationRef, Component } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { auditTime, filter, take } from 'rxjs/operators';
|
||||
import { filter, take } from 'rxjs/operators';
|
||||
|
||||
import { ConfigService } from './core/ui-services/config.service';
|
||||
import { ConstantsService } from './core/core-services/constants.service';
|
||||
@ -17,7 +17,6 @@ import { PrioritizeService } from './core/core-services/prioritize.service';
|
||||
import { RoutingStateService } from './core/ui-services/routing-state.service';
|
||||
import { ServertimeService } from './core/core-services/servertime.service';
|
||||
import { ThemeService } from './core/ui-services/theme.service';
|
||||
import { ViewUser } from './site/users/models/view-user';
|
||||
|
||||
declare global {
|
||||
/**
|
||||
@ -46,16 +45,6 @@ declare global {
|
||||
styleUrls: ['./app.component.scss']
|
||||
})
|
||||
export class AppComponent {
|
||||
/**
|
||||
* Member to hold the state of `stable`.
|
||||
*/
|
||||
private isStable: boolean;
|
||||
|
||||
/**
|
||||
* Member to hold the user.
|
||||
*/
|
||||
private user: ViewUser;
|
||||
|
||||
/**
|
||||
* Master-component of all apps.
|
||||
*
|
||||
@ -79,11 +68,11 @@ export class AppComponent {
|
||||
appRef: ApplicationRef,
|
||||
servertimeService: ServertimeService,
|
||||
router: Router,
|
||||
private operator: OperatorService,
|
||||
operator: OperatorService,
|
||||
loginDataService: LoginDataService,
|
||||
constantsService: ConstantsService, // Needs to be started, so it can register itself to the WebsocketService
|
||||
themeService: ThemeService,
|
||||
private overlayService: OverlayService,
|
||||
overlayService: OverlayService,
|
||||
countUsersService: CountUsersService, // Needed to register itself.
|
||||
configService: ConfigService,
|
||||
loadFontService: LoadFontService,
|
||||
@ -115,31 +104,6 @@ export class AppComponent {
|
||||
take(1)
|
||||
)
|
||||
.subscribe(() => servertimeService.startScheduler());
|
||||
|
||||
// Subscribe to hide the spinner if the application has changed.
|
||||
appRef.isStable
|
||||
.pipe(
|
||||
filter(s => s),
|
||||
auditTime(1000)
|
||||
)
|
||||
.subscribe(stable => {
|
||||
// check the stable state only once.
|
||||
if (!this.isStable && stable) {
|
||||
this.isStable = true;
|
||||
this.checkConnectionProgress();
|
||||
}
|
||||
});
|
||||
// subscribe, to get the user.
|
||||
operator.getViewUserObservable().subscribe(user => {
|
||||
// check the user only once
|
||||
if ((!this.user && user) || operator.isAnonymous) {
|
||||
this.user = user;
|
||||
this.checkConnectionProgress();
|
||||
// if the user is logging out, remove this user.
|
||||
} else if (user === null) {
|
||||
this.user = user;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -192,14 +156,4 @@ export class AppComponent {
|
||||
return ((this % n) + n) % n;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to check if the user is existing and the app is already stable.
|
||||
* If both conditions true, hide the spinner.
|
||||
*/
|
||||
private checkConnectionProgress(): void {
|
||||
if ((this.user || this.operator.isAnonymous) && this.isStable) {
|
||||
this.overlayService.setSpinner(false, null, false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -48,7 +48,9 @@ export class AuthService {
|
||||
};
|
||||
const response = await this.http.post<WhoAmI>(environment.urlPrefix + '/users/login/', user);
|
||||
earlySuccessCallback();
|
||||
await this.OpenSlides.shutdown();
|
||||
await this.operator.setWhoAmI(response);
|
||||
await this.OpenSlides.afterLoginBootup(response.user_id);
|
||||
await this.redirectUser(response.user_id);
|
||||
return response;
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
|
||||
import { AutoupdateService } from './autoupdate.service';
|
||||
import { ConstantsService } from './constants.service';
|
||||
import { StorageService } from './storage.service';
|
||||
@ -26,6 +28,11 @@ const SCHEMA_VERSION = 'SchemaVersion';
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class DataStoreUpgradeService {
|
||||
/**
|
||||
* Notify, when upgrade has checked.
|
||||
*/
|
||||
public readonly upgradeChecked = new BehaviorSubject(false);
|
||||
|
||||
/**
|
||||
* @param autoupdateService
|
||||
* @param constantsService
|
||||
@ -48,6 +55,7 @@ export class DataStoreUpgradeService {
|
||||
}
|
||||
|
||||
public async checkForUpgrade(serverVersion: SchemaVersion): Promise<boolean> {
|
||||
this.upgradeChecked.next(false);
|
||||
console.log('Server schema version:', serverVersion);
|
||||
const clientVersion = await this.storageService.get<SchemaVersion>(SCHEMA_VERSION);
|
||||
await this.storageService.set(SCHEMA_VERSION, serverVersion);
|
||||
@ -77,6 +85,7 @@ export class DataStoreUpgradeService {
|
||||
} else {
|
||||
console.log('\t-> No upgrade needed.');
|
||||
}
|
||||
this.upgradeChecked.next(true);
|
||||
return doUpgrade;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
|
||||
import { AutoupdateService } from './autoupdate.service';
|
||||
import { ConstantsService } from './constants.service';
|
||||
import { DataStoreService } from './data-store.service';
|
||||
@ -20,14 +22,17 @@ export class OpenSlidesService {
|
||||
*/
|
||||
public redirectUrl: string;
|
||||
|
||||
/**
|
||||
* Subject to hold the flag `booted`.
|
||||
*/
|
||||
public readonly booted = new BehaviorSubject(false);
|
||||
|
||||
/**
|
||||
* Saves, if OpenSlides is fully booted. This means, that a user must be logged in
|
||||
* (Anonymous is also a user in this case). This is the case after `afterLoginBootup`.
|
||||
*/
|
||||
private _booted = false;
|
||||
|
||||
public get booted(): boolean {
|
||||
return this._booted;
|
||||
public get isBooted(): boolean {
|
||||
return this.booted.value;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -113,7 +118,7 @@ export class OpenSlidesService {
|
||||
}
|
||||
await this.setupDataStoreAndWebSocket();
|
||||
// Now finally booted.
|
||||
this._booted = true;
|
||||
this.booted.next(true);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -139,7 +144,7 @@ export class OpenSlidesService {
|
||||
*/
|
||||
public async shutdown(): Promise<void> {
|
||||
await this.websocketService.close();
|
||||
this._booted = false;
|
||||
this.booted.next(false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -5,6 +5,9 @@ import { Observable, Subject } from 'rxjs';
|
||||
|
||||
import { largeDialogSettings } from 'app/shared/utils/dialog-settings';
|
||||
import { SuperSearchComponent } from 'app/site/common/components/super-search/super-search.component';
|
||||
import { DataStoreUpgradeService } from '../core-services/data-store-upgrade.service';
|
||||
import { OpenSlidesService } from '../core-services/openslides.service';
|
||||
import { OperatorService } from '../core-services/operator.service';
|
||||
|
||||
/**
|
||||
* Component to control the visibility of components, that overlay the whole window.
|
||||
@ -26,28 +29,66 @@ export class OverlayService {
|
||||
private spinner: Subject<{ isVisible: boolean; text?: string }> = new Subject();
|
||||
|
||||
/**
|
||||
* Boolean, whether appearing of the spinner should be prevented next time.
|
||||
* Flag, that indicates, if the upgrade has checked.
|
||||
*/
|
||||
private preventAppearingSpinner = false;
|
||||
private upgradeChecked = false;
|
||||
|
||||
/**
|
||||
* The current user.
|
||||
*/
|
||||
private user = null;
|
||||
|
||||
/**
|
||||
* Flag, whether the app has booted.
|
||||
*/
|
||||
private hasBooted = false;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param dialogService Injects the `MatDialog` to show the `super-search.component`
|
||||
*/
|
||||
public constructor(private dialogService: MatDialog) {}
|
||||
public constructor(
|
||||
private dialogService: MatDialog,
|
||||
private operator: OperatorService,
|
||||
OpenSlides: OpenSlidesService,
|
||||
upgradeService: DataStoreUpgradeService
|
||||
) {
|
||||
// Subscribe to the current user.
|
||||
operator.getViewUserObservable().subscribe(user => {
|
||||
if (user) {
|
||||
this.user = user;
|
||||
this.checkConnection();
|
||||
}
|
||||
});
|
||||
// Subscribe to the booting-step.
|
||||
OpenSlides.booted.subscribe(isBooted => {
|
||||
this.hasBooted = isBooted;
|
||||
this.checkConnection();
|
||||
});
|
||||
// Subscribe to the upgrade-mechanism.
|
||||
upgradeService.upgradeChecked.subscribe(upgradeDone => {
|
||||
this.upgradeChecked = upgradeDone;
|
||||
this.checkConnection();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to change the visibility of the `global-spinner.component`.
|
||||
* Function to show the `global-spinner.component`.
|
||||
*
|
||||
* @param isVisible flag, if the spinner should be shown.
|
||||
* @param text optional. If the spinner should show a message.
|
||||
* @param preventAppearing optional. Wether to prevent showing the spinner the next time.
|
||||
* @param forceAppearing optional. If the spinner must be shown.
|
||||
*/
|
||||
public setSpinner(isVisible: boolean, text?: string, forceAppearing?: boolean, preventAppearing?: boolean): void {
|
||||
if (!this.preventAppearingSpinner || forceAppearing) {
|
||||
setTimeout(() => this.spinner.next({ isVisible, text }));
|
||||
public showSpinner(text?: string, forceAppearing?: boolean): void {
|
||||
if (!this.isConnectionStable() || forceAppearing) {
|
||||
setTimeout(() => this.spinner.next({ isVisible: true, text }));
|
||||
}
|
||||
this.preventAppearingSpinner = preventAppearing;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to hide the `global-spinner.component`.
|
||||
*/
|
||||
public hideSpinner(): void {
|
||||
setTimeout(() => this.spinner.next({ isVisible: false }));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -78,6 +119,25 @@ export class OverlayService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks, if the connection is stable.
|
||||
* This relates to `appStable`, `booted` and `user || anonymous`.
|
||||
*
|
||||
* @returns True, if the three booleans are all true.
|
||||
*/
|
||||
public isConnectionStable(): boolean {
|
||||
return this.upgradeChecked && this.hasBooted && (!!this.user || this.operator.isAnonymous);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to check, if the app is stable and, if true, hide the spinner.
|
||||
*/
|
||||
private checkConnection(): void {
|
||||
if (this.isConnectionStable()) {
|
||||
this.hideSpinner();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to reset the properties for the spinner.
|
||||
*
|
||||
@ -85,6 +145,8 @@ export class OverlayService {
|
||||
* and still stays at the website.
|
||||
*/
|
||||
public logout(): void {
|
||||
this.preventAppearingSpinner = false;
|
||||
this.hasBooted = false;
|
||||
this.user = null;
|
||||
this.upgradeChecked = false;
|
||||
}
|
||||
}
|
||||
|
@ -52,6 +52,11 @@ export class LoginMaskComponent extends BaseViewComponent implements OnInit, OnD
|
||||
|
||||
public operatorSubscription: Subscription | null;
|
||||
|
||||
/**
|
||||
* The message, that should appear, when the user logs in.
|
||||
*/
|
||||
private loginMessage = 'Loading data. Please wait...';
|
||||
|
||||
/**
|
||||
* Constructor for the login component
|
||||
*
|
||||
@ -136,11 +141,12 @@ export class LoginMaskComponent extends BaseViewComponent implements OnInit, OnD
|
||||
public async formLogin(): Promise<void> {
|
||||
this.loginErrorMsg = '';
|
||||
try {
|
||||
this.overlayService.showSpinner(this.translate.instant(this.loginMessage), true);
|
||||
await this.authService.login(this.loginForm.value.username, this.loginForm.value.password, () => {
|
||||
this.overlayService.setSpinner(true, this.translate.instant('Loading data. Please wait...'));
|
||||
this.clearOperatorSubscription(); // We take control, not the subscription.
|
||||
});
|
||||
} catch (e) {
|
||||
this.overlayService.hideSpinner();
|
||||
this.loginForm.setErrors({
|
||||
notFound: true
|
||||
});
|
||||
@ -166,6 +172,7 @@ export class LoginMaskComponent extends BaseViewComponent implements OnInit, OnD
|
||||
* Guests (if enabled) can navigate directly to the main page.
|
||||
*/
|
||||
public guestLogin(): void {
|
||||
this.overlayService.showSpinner(this.translate.instant(this.loginMessage));
|
||||
this.authService.guestLogin();
|
||||
}
|
||||
}
|
||||
|
@ -380,7 +380,7 @@ export class MotionListComponent extends BaseListViewComponent<ViewMotion> imple
|
||||
} catch (e) {
|
||||
this.raiseError(e);
|
||||
} finally {
|
||||
this.overlayService.setSpinner(false);
|
||||
this.overlayService.hideSpinner();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -81,10 +81,10 @@ export class MotionMultiselectService {
|
||||
`\n${i} ` +
|
||||
this.translate.instant('of') +
|
||||
` ${motions.length}`;
|
||||
this.overlayService.setSpinner(true, message, true);
|
||||
this.overlayService.showSpinner(message, true);
|
||||
await this.repo.delete(motion);
|
||||
}
|
||||
this.overlayService.setSpinner(false);
|
||||
this.overlayService.hideSpinner();
|
||||
}
|
||||
}
|
||||
|
||||
@ -119,7 +119,7 @@ export class MotionMultiselectService {
|
||||
const selectedChoice = await this.choiceService.open(title, choices);
|
||||
if (selectedChoice) {
|
||||
const message = `${motions.length} ` + this.translate.instant(this.messageForSpinner);
|
||||
this.overlayService.setSpinner(true, message, true);
|
||||
this.overlayService.showSpinner(message, true);
|
||||
await this.repo.setMultiState(motions, selectedChoice.items as number);
|
||||
}
|
||||
} else {
|
||||
@ -152,7 +152,7 @@ export class MotionMultiselectService {
|
||||
recommendation: selectedChoice.action ? 0 : (selectedChoice.items as number)
|
||||
}));
|
||||
const message = `${motions.length} ` + this.translate.instant(this.messageForSpinner);
|
||||
this.overlayService.setSpinner(true, message, true);
|
||||
this.overlayService.showSpinner(message, true);
|
||||
await this.httpService.post('/rest/motions/motion/manage_multiple_recommendation/', {
|
||||
motions: requestData
|
||||
});
|
||||
@ -181,7 +181,7 @@ export class MotionMultiselectService {
|
||||
);
|
||||
if (selectedChoice) {
|
||||
const message = this.translate.instant(this.messageForSpinner);
|
||||
this.overlayService.setSpinner(true, message, true);
|
||||
this.overlayService.showSpinner(message, true);
|
||||
await this.repo.setMultiCategory(motions, selectedChoice.items as number);
|
||||
}
|
||||
}
|
||||
@ -220,7 +220,7 @@ export class MotionMultiselectService {
|
||||
}
|
||||
|
||||
const message = `${motions.length} ` + this.translate.instant(this.messageForSpinner);
|
||||
this.overlayService.setSpinner(true, message, true);
|
||||
this.overlayService.showSpinner(message, true);
|
||||
await this.httpService.post('/rest/motions/motion/manage_multiple_submitters/', { motions: requestData });
|
||||
}
|
||||
}
|
||||
@ -268,7 +268,7 @@ export class MotionMultiselectService {
|
||||
}
|
||||
|
||||
const message = `${motions.length} ` + this.translate.instant(this.messageForSpinner);
|
||||
this.overlayService.setSpinner(true, message, true);
|
||||
this.overlayService.showSpinner(message, true);
|
||||
await this.httpService.post('/rest/motions/motion/manage_multiple_tags/', { motions: requestData });
|
||||
}
|
||||
}
|
||||
@ -290,7 +290,7 @@ export class MotionMultiselectService {
|
||||
);
|
||||
if (selectedChoice) {
|
||||
const message = this.translate.instant(this.messageForSpinner);
|
||||
this.overlayService.setSpinner(true, message, true);
|
||||
this.overlayService.showSpinner(message, true);
|
||||
const blockId = selectedChoice.action ? null : (selectedChoice.items as number);
|
||||
await this.repo.setMultiMotionBlock(motions, blockId);
|
||||
}
|
||||
@ -355,7 +355,7 @@ export class MotionMultiselectService {
|
||||
if (selectedChoice && motions.length) {
|
||||
const message = this.translate.instant(`I have ${motions.length} favorite motions. Please wait ...`);
|
||||
const star = (selectedChoice.items as number) === choices[0].id;
|
||||
this.overlayService.setSpinner(true, message, true);
|
||||
this.overlayService.showSpinner(message, true);
|
||||
await this.personalNoteService.bulkSetStar(motions, star);
|
||||
}
|
||||
}
|
||||
|
@ -103,7 +103,10 @@ export class SiteComponent extends BaseComponent implements OnInit {
|
||||
private overlayService: OverlayService
|
||||
) {
|
||||
super(title, translate);
|
||||
overlayService.setSpinner(true, translate.instant('Loading data. Please wait...'));
|
||||
overlayService.showSpinner(
|
||||
translate.instant('Loading data. Please wait...'),
|
||||
!(operator.guestsEnabled && operator.isAnonymous)
|
||||
);
|
||||
|
||||
this.operator.getViewUserObservable().subscribe(user => {
|
||||
if (!operator.isAnonymous) {
|
||||
@ -253,6 +256,9 @@ export class SiteComponent extends BaseComponent implements OnInit {
|
||||
* Function to log out the current user
|
||||
*/
|
||||
public logout(): void {
|
||||
if (this.operator.guestsEnabled) {
|
||||
this.overlayService.showSpinner(null, true);
|
||||
}
|
||||
this.authService.logout();
|
||||
this.overlayService.logout();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user