Replaces the snackbar for offline-mode with a banner.
This commit is contained in:
parent
bbe294a1ad
commit
c5f90b0972
@ -1,56 +1,51 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { WebsocketService } from './websocket.service';
|
||||
import { BehaviorSubject, Observable } from 'rxjs';
|
||||
|
||||
/**
|
||||
* This service handles everything connected with being offline.
|
||||
*
|
||||
* TODO: This is just a stub. Needs to be done in the future; Maybe we cancel this whole concept
|
||||
* of this service. We'll see whats happens here..
|
||||
* of this service. We'll see what happens here..
|
||||
*/
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class OfflineService {
|
||||
private _offline = false;
|
||||
|
||||
public get offline(): boolean {
|
||||
return this._offline;
|
||||
}
|
||||
|
||||
/**
|
||||
* BehaviorSubject to receive further status values.
|
||||
*/
|
||||
public constructor(private socketService: WebsocketService) {}
|
||||
private offline = new BehaviorSubject<boolean>(false);
|
||||
|
||||
/**
|
||||
* Determines of you are either in Offline mode or not connected via websocket
|
||||
*
|
||||
* @returns whether the client is offline or not connected
|
||||
*/
|
||||
public isOffline(): boolean {
|
||||
return this.offline || !this.socketService.isConnected;
|
||||
public isOffline(): Observable<boolean> {
|
||||
return this.offline;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the offline flag. Restores the DataStoreService to the last known configuration.
|
||||
*/
|
||||
public goOfflineBecauseFailedWhoAmI(): void {
|
||||
this._offline = true;
|
||||
this.offline.next(true);
|
||||
console.log('offline because whoami failed.');
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Should be somehow connected to the websocket service.
|
||||
* Sets the offline flag, because there is no connection to the server.
|
||||
*/
|
||||
public goOfflineBecauseConnectionLost(): void {
|
||||
this._offline = true;
|
||||
this.offline.next(true);
|
||||
console.log('offline because connection lost.');
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Should be somehow connected to the websocket service.
|
||||
* Function to return to online-status.
|
||||
*/
|
||||
public goOnline(): void {
|
||||
this._offline = false;
|
||||
this.offline.next(false);
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,13 @@
|
||||
import { EventEmitter, Injectable, NgZone } from '@angular/core';
|
||||
import { MatSnackBar, MatSnackBarRef, SimpleSnackBar } from '@angular/material/snack-bar';
|
||||
import { MatSnackBarRef, SimpleSnackBar } from '@angular/material/snack-bar';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { compress, decompress } from 'lz4js';
|
||||
import { Observable, Subject } from 'rxjs';
|
||||
import { take } from 'rxjs/operators';
|
||||
import { TextDecoder, TextEncoder } from 'text-encoding';
|
||||
|
||||
import { OfflineService } from './offline.service';
|
||||
import { OpenSlidesStatusService } from './openslides-status.service';
|
||||
import { formatQueryParams, QueryParams } from '../definitions/query-params';
|
||||
|
||||
@ -189,17 +189,17 @@ export class WebsocketService {
|
||||
|
||||
/**
|
||||
* Constructor that handles the router
|
||||
* @param matSnackBar
|
||||
*
|
||||
* @param zone
|
||||
* @param translate
|
||||
* @param router
|
||||
* @param openSlidesStatusService
|
||||
* @param offlineService
|
||||
*/
|
||||
public constructor(
|
||||
private matSnackBar: MatSnackBar,
|
||||
private zone: NgZone,
|
||||
private translate: TranslateService,
|
||||
private router: Router,
|
||||
private openSlidesStatusService: OpenSlidesStatusService
|
||||
private openSlidesStatusService: OpenSlidesStatusService,
|
||||
private offlineService: OfflineService
|
||||
) {}
|
||||
|
||||
/**
|
||||
@ -380,12 +380,7 @@ export class WebsocketService {
|
||||
}
|
||||
|
||||
if (!this.connectionErrorNotice && !onProjector && this.retryCounter > 3) {
|
||||
// So here we have a connection failure that wasn't intendet.
|
||||
this.connectionErrorNotice = this.matSnackBar.open(
|
||||
this.translate.instant('Offline mode: You can use OpenSlides but changes are not saved.'),
|
||||
'',
|
||||
{ duration: 0 }
|
||||
);
|
||||
this.offlineService.goOfflineBecauseConnectionLost();
|
||||
}
|
||||
|
||||
// A random retry timeout between 2000 and 5000 ms.
|
||||
@ -405,10 +400,7 @@ export class WebsocketService {
|
||||
}
|
||||
|
||||
private dismissConnectionErrorNotice(): void {
|
||||
if (this.connectionErrorNotice) {
|
||||
this.connectionErrorNotice.dismiss();
|
||||
this.connectionErrorNotice = null;
|
||||
}
|
||||
this.offlineService.goOnline();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,6 +1,6 @@
|
||||
<div id="container" class="projector-container" [osResized]="resizeSubject" #container>
|
||||
<div id="projector" class="projector">
|
||||
<div id="offline-indicator" *ngIf="isOffline()">
|
||||
<div id="offline-indicator" *ngIf="isOffline">
|
||||
<mat-icon>
|
||||
fiber_manual_record
|
||||
</mat-icon>
|
||||
|
@ -148,11 +148,21 @@ export class ProjectorComponent extends BaseComponent implements OnDestroy {
|
||||
*/
|
||||
public scale = 0;
|
||||
|
||||
/**
|
||||
* Info about if the user is offline.
|
||||
*/
|
||||
public isOffline = false;
|
||||
|
||||
/**
|
||||
* The subscription to the projector.
|
||||
*/
|
||||
private projectorSubscription: Subscription;
|
||||
|
||||
/**
|
||||
* Holds the subscription to the offline-service.
|
||||
*/
|
||||
private offlineSubscription: Subscription;
|
||||
|
||||
/**
|
||||
* A subject that fires, if the container is resized.
|
||||
*/
|
||||
@ -226,15 +236,8 @@ export class ProjectorComponent extends BaseComponent implements OnDestroy {
|
||||
this.updateScaling();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* determine if the server is offline
|
||||
*
|
||||
* @returns whether the client is offlien
|
||||
*/
|
||||
public isOffline(): boolean {
|
||||
return this.offlineService.isOffline();
|
||||
this.offlineSubscription = this.offlineService.isOffline().subscribe(isOffline => (this.isOffline = isOffline));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -327,5 +330,9 @@ export class ProjectorComponent extends BaseComponent implements OnDestroy {
|
||||
}
|
||||
document.head.removeChild(this.styleElement);
|
||||
this.styleElement = null;
|
||||
if (this.offlineSubscription) {
|
||||
this.offlineSubscription.unsubscribe();
|
||||
this.offlineSubscription = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
<div class="offline-banner" *ngIf="isOffline"><mat-icon>cloud_off</mat-icon><span translate>Offline mode</span></div>
|
||||
<div class="history-mode-indicator" *ngIf="OSStatus.isInHistoryMode">
|
||||
<span translate>You are using the history mode of OpenSlides. Changes will not be saved.</span>
|
||||
<span>({{ getHistoryTimestamp() }})</span>
|
||||
@ -133,7 +134,6 @@
|
||||
<div class="os-footer-logo-container">
|
||||
<os-logo [footer]="true"></os-logo>
|
||||
</div>
|
||||
|
||||
</mat-nav-list>
|
||||
<!-- Toggle-button -->
|
||||
<div class="nav-toggle-button-container" *ngIf="!vp.isMobile">
|
||||
|
@ -48,5 +48,30 @@
|
||||
color: mat-color($primary);
|
||||
}
|
||||
}
|
||||
|
||||
/** style for the offline-banner */
|
||||
.offline-banner {
|
||||
display: flex;
|
||||
top: 0;
|
||||
z-index: 2;
|
||||
width: 100%;
|
||||
height: 20px;
|
||||
background: mat-color($primary, 900);
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: white;
|
||||
|
||||
mat-icon {
|
||||
$font-size: 16px;
|
||||
width: $font-size;
|
||||
height: $font-size;
|
||||
font-size: $font-size;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 90%;
|
||||
margin: 0 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import { TranslateService } from '@ngx-translate/core';
|
||||
import { filter } from 'rxjs/operators';
|
||||
|
||||
import { navItemAnim, pageTransition } from '../shared/animations';
|
||||
import { OfflineService } from 'app/core/core-services/offline.service';
|
||||
import { ConfigService } from 'app/core/ui-services/config.service';
|
||||
import { UpdateService } from 'app/core/ui-services/update.service';
|
||||
import { langToLocale } from 'app/shared/utils/lang-to-locale';
|
||||
@ -52,6 +53,11 @@ export class SiteComponent extends BaseComponent implements OnInit {
|
||||
*/
|
||||
public isLoggedIn: boolean;
|
||||
|
||||
/**
|
||||
* Indicates, whether the user is offline or not.
|
||||
*/
|
||||
public isOffline: boolean;
|
||||
|
||||
/**
|
||||
* Holds the typed search query.
|
||||
*/
|
||||
@ -84,6 +90,7 @@ export class SiteComponent extends BaseComponent implements OnInit {
|
||||
title: Title,
|
||||
protected translate: TranslateService,
|
||||
configService: ConfigService,
|
||||
offlineService: OfflineService,
|
||||
private updateService: UpdateService,
|
||||
private authService: AuthService,
|
||||
private router: Router,
|
||||
@ -106,6 +113,10 @@ export class SiteComponent extends BaseComponent implements OnInit {
|
||||
this.isLoggedIn = !!user;
|
||||
});
|
||||
|
||||
offlineService.isOffline().subscribe(offline => {
|
||||
this.isOffline = offline;
|
||||
});
|
||||
|
||||
this.searchform = new FormGroup({ query: new FormControl([]) });
|
||||
|
||||
// detect routing data such as base perm and noInterruption
|
||||
|
@ -6,9 +6,9 @@ $openslides-green: (
|
||||
400: #62a64b,
|
||||
500: #46962b,
|
||||
600: #3f8e26,
|
||||
700: #0a321e,
|
||||
800: #092d1a,
|
||||
900: #072616,
|
||||
700: #378320,
|
||||
800: #2f791a,
|
||||
900: #206810,
|
||||
A100: #acff9d,
|
||||
A200: #80ff6a,
|
||||
A400: #55ff37,
|
||||
|
@ -7,18 +7,18 @@ $openslides-blue: (
|
||||
400: #508ba6,
|
||||
500: #317796,
|
||||
600: #2c6f8e,
|
||||
700: #002a42,
|
||||
800: #00253c,
|
||||
900: #001f33,
|
||||
700: #256483,
|
||||
800: #1f5a79,
|
||||
900: #134768,
|
||||
A100: #9fd7ff,
|
||||
A200: #6cc2ff,
|
||||
A400: #39acff,
|
||||
A700: #1fa2ff,
|
||||
contrast: (
|
||||
50: #ffffff,
|
||||
100: #ffffff,
|
||||
200: #ffffff,
|
||||
300: #ffffff,
|
||||
50: #000000,
|
||||
100: #000000,
|
||||
200: #000000,
|
||||
300: #000000,
|
||||
400: #ffffff,
|
||||
500: #ffffff,
|
||||
600: #ffffff,
|
||||
@ -57,9 +57,19 @@ $os-background: mat-color($mat-grey, 100);
|
||||
* The components will get a value from this map.
|
||||
*/
|
||||
$background: map-get($openslides-theme, background);
|
||||
$background: map_merge($background, (background: $os-background));
|
||||
$background: map_merge(
|
||||
$background,
|
||||
(
|
||||
background: $os-background
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* Merge the theme with the custom-background.
|
||||
*/
|
||||
$openslides-theme: map_merge($openslides-theme, (background: $background));
|
||||
$openslides-theme: map_merge(
|
||||
$openslides-theme,
|
||||
(
|
||||
background: $background
|
||||
)
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user