MOBILE-3565 menu: Add network status message
parent
ec1f63c818
commit
f09c3f9210
|
@ -18,6 +18,8 @@ import { NavController } from '@ionic/angular';
|
|||
import { CoreLangProvider } from '@services/lang';
|
||||
import { CoreLoginHelperProvider } from '@core/login/services/helper';
|
||||
import { CoreEvents, CoreEventSessionExpiredData } from '@singletons/events';
|
||||
import { Network, NgZone, Platform } from '@singletons/core.singletons';
|
||||
import { CoreApp } from '@services/app';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
|
@ -45,14 +47,73 @@ export class AppComponent implements OnInit {
|
|||
this.langProvider.clearCustomStrings();
|
||||
|
||||
// Remove version classes from body.
|
||||
// @todo
|
||||
// this.removeVersionClass();
|
||||
this.removeVersionClass();
|
||||
});
|
||||
|
||||
// Listen for session expired events.
|
||||
CoreEvents.on(CoreEvents.SESSION_EXPIRED, (data: CoreEventSessionExpiredData) => {
|
||||
this.loginHelper.sessionExpired(data);
|
||||
});
|
||||
|
||||
this.onPlatformReady();
|
||||
}
|
||||
|
||||
protected async onPlatformReady(): Promise<void> {
|
||||
await Platform.instance.ready();
|
||||
|
||||
// Refresh online status when changes.
|
||||
Network.instance.onChange().subscribe(() => {
|
||||
// Execute the callback in the Angular zone, so change detection doesn't stop working.
|
||||
NgZone.instance.run(() => {
|
||||
const isOnline = CoreApp.instance.isOnline();
|
||||
const hadOfflineMessage = document.body.classList.contains('core-offline');
|
||||
|
||||
document.body.classList.toggle('core-offline', !isOnline);
|
||||
|
||||
if (isOnline && hadOfflineMessage) {
|
||||
document.body.classList.add('core-online');
|
||||
|
||||
setTimeout(() => {
|
||||
document.body.classList.remove('core-online');
|
||||
}, 3000);
|
||||
} else if (!isOnline) {
|
||||
document.body.classList.remove('core-online');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience function to add version to body classes.
|
||||
*
|
||||
* @param release Current release number of the site.
|
||||
*/
|
||||
protected addVersionClass(release: string): void {
|
||||
const parts = release.split('.', 3);
|
||||
|
||||
parts[1] = parts[1] || '0';
|
||||
parts[2] = parts[2] || '0';
|
||||
|
||||
document.body.classList.add('version-' + parts[0],
|
||||
'version-' + parts[0] + '-' + parts[1],
|
||||
'version-' + parts[0] + '-' + parts[1] + '-' + parts[2]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience function to remove all version classes form body.
|
||||
*/
|
||||
protected removeVersionClass(): void {
|
||||
const remove: string[] = [];
|
||||
|
||||
Array.from(document.body.classList).forEach((tempClass) => {
|
||||
if (tempClass.substring(0, 8) == 'version-') {
|
||||
remove.push(tempClass);
|
||||
}
|
||||
});
|
||||
|
||||
remove.forEach((tempClass) => {
|
||||
document.body.classList.remove(tempClass);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
<ion-tabs #mainTabs [hidden]="!showTabs">
|
||||
|
||||
<ion-tab-bar slot="bottom">
|
||||
<ion-tabs #mainTabs [hidden]="!showTabs" [class]="'placement-' + tabsPlacement" [class.tabshidden]="hidden">
|
||||
<ion-tab-bar slot="bottom" [hidden]="hidden">
|
||||
<ion-spinner *ngIf="!loaded"></ion-spinner>
|
||||
|
||||
<ion-tab-button tab="redirect" [disabled]="true" [hidden]="true"></ion-tab-button> <!-- [root]="redirectPage" [rootParams]="redirectParams" -->
|
||||
|
|
|
@ -42,6 +42,7 @@ export class CoreMainMenuPage implements OnInit, OnDestroy {
|
|||
redirectParams?: Params;
|
||||
showTabs = false;
|
||||
tabsPlacement = 'bottom';
|
||||
hidden = false;
|
||||
|
||||
protected subscription?: Subscription;
|
||||
protected redirectObs?: CoreEventObserver;
|
||||
|
@ -178,6 +179,22 @@ export class CoreMainMenuPage implements OnInit, OnDestroy {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Change tabs visibility to show/hide them from the view.
|
||||
*
|
||||
* @param visible If show or hide the tabs.
|
||||
*/
|
||||
changeVisibility(visible: boolean): void {
|
||||
if (this.hidden == visible) {
|
||||
// Change needed.
|
||||
this.hidden = !visible;
|
||||
|
||||
/* setTimeout(() => {
|
||||
this.viewCtrl.getContent().resize();
|
||||
});*/
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a redirect.
|
||||
*
|
||||
|
@ -246,7 +263,7 @@ export class CoreMainMenuPage implements OnInit, OnDestroy {
|
|||
|
||||
// User confirmed, go to root.
|
||||
this.mainTabs?.select(page);
|
||||
} catch (error) {
|
||||
} catch {
|
||||
// User canceled.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,93 +1,89 @@
|
|||
ion-icon.tab-button-icon {
|
||||
text-overflow: unset;
|
||||
overflow: visible;
|
||||
text-align: center;
|
||||
transition: margin 500ms ease-in-out, transform 300ms ease-in-out;
|
||||
}
|
||||
:host{
|
||||
--menutabbar-size: 60px;
|
||||
|
||||
.ion-md-fa-graduation-cap,
|
||||
.ion-ios-fa-graduation-cap,
|
||||
.ion-ios-fa-graduation-cap-outline,
|
||||
.ion-fa-graduation-cap {
|
||||
// @todo @extend .fa-graduation-cap;
|
||||
// @todo @extend .fa;
|
||||
font-size: 21px;
|
||||
height: 21px;
|
||||
ion-tabs {
|
||||
-webkit-filter: drop-shadow(0px 3px 3px rgba(var(--drop-shadow)));
|
||||
filter: drop-shadow(0px 3px 3px rgba(var(--drop-shadow)));
|
||||
}
|
||||
|
||||
}
|
||||
ion-tab-button ion-icon {
|
||||
text-overflow: unset;
|
||||
overflow: visible;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.ion-ios-fa-graduation-cap-outline {
|
||||
color: transparent;
|
||||
-webkit-text-stroke-width: 0.8px;
|
||||
// @todo -webkit-text-stroke-color: $tabs-tab-color-inactive;
|
||||
font-size: 23px;
|
||||
height: 23px;
|
||||
}
|
||||
ion-tabs.placement-bottom ion-tab-button {
|
||||
ion-icon {
|
||||
transition: margin 500ms ease-in-out, transform 300ms ease-in-out;
|
||||
}
|
||||
ion-badge {
|
||||
top: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.ion-md-fa-newspaper-o,
|
||||
.ion-ios-fa-newspaper-o,
|
||||
.ion-ios-fa-newspaper-o-outline,
|
||||
.ion-fa-newspaper-o {
|
||||
// @todo @extend .fa-newspaper-o;
|
||||
// @todo @extend .fa;
|
||||
font-size: 22px;
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
.ion-ios-fa-newspaper-o-outline {
|
||||
font-size: 23px;
|
||||
height: 23px;
|
||||
}
|
||||
|
||||
.core-network-message {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
text-align: center;
|
||||
color: white;
|
||||
visibility: hidden;
|
||||
height: 0;
|
||||
transition: all 500ms ease-in-out;
|
||||
opacity: .8;
|
||||
}
|
||||
|
||||
.core-online-message,
|
||||
.core-offline-message {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
.core-online ion-app.app-root page-core-mainmenu,
|
||||
.core-offline ion-app.app-root page-core-mainmenu {
|
||||
|
||||
core-ion-tabs[tabsplacement="bottom"] ion-icon.tab-button-icon {
|
||||
margin-bottom: $core-network-message-height / 2;
|
||||
|
||||
&.icon-ios {
|
||||
margin-bottom: 14px;
|
||||
ion-tabs.placement-side {
|
||||
flex-direction: row;
|
||||
ion-tab-bar {
|
||||
order: -1;
|
||||
width: var(--menutabbar-size);
|
||||
height: 100%;
|
||||
flex-direction: column;
|
||||
ion-tab-button {
|
||||
width: 100%;
|
||||
ion-badge {
|
||||
top: calc(50% - 20px);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.core-network-message {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
text-align: center;
|
||||
color: white;
|
||||
visibility: hidden;
|
||||
height: 0;
|
||||
transition: all 500ms ease-in-out;
|
||||
opacity: .8;
|
||||
}
|
||||
|
||||
.core-online-message,
|
||||
.core-offline-message {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
:host-context(.core-online),
|
||||
:host-context(.core-offline) {
|
||||
ion-tabs.placement-bottom ion-tab-button ion-icon {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
ion-tabs.placement-bottom ion-tab-button.ios ion-icon {
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.core-network-message {
|
||||
visibility: visible;
|
||||
height: $core-network-message-height;
|
||||
height: 16px;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
.core-offline ion-app.app-root page-core-mainmenu .core-offline-message,
|
||||
.core-online ion-app.app-root page-core-mainmenu .core-online-message {
|
||||
:host-context(.core-offline) .core-offline-message,
|
||||
:host-context(.core-online) .core-online-message {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.core-online ion-app.app-root page-core-mainmenu .core-network-message {
|
||||
background: $green;
|
||||
:host-context(.core-online) .core-network-message {
|
||||
background: var(--green);
|
||||
}
|
||||
|
||||
.core-offline ion-app.app-root page-core-mainmenu .core-network-message {
|
||||
background: $red;
|
||||
}*/
|
||||
:host-context(.core-offline) .core-network-message {
|
||||
background: var(--red);
|
||||
}
|
||||
|
|
|
@ -29,7 +29,6 @@ import { CoreEventObserver, CoreEvents } from '@singletons/events';
|
|||
@Component({
|
||||
selector: 'page-core-mainmenu-more',
|
||||
templateUrl: 'more.html',
|
||||
styleUrls: ['more.scss'],
|
||||
})
|
||||
export class CoreMainMenuMorePage implements OnInit, OnDestroy {
|
||||
|
||||
|
|
|
@ -1,97 +0,0 @@
|
|||
/*
|
||||
$core-more-icon: $gray-darker !default;
|
||||
$core-more-background-ios: $list-ios-background-color !default;
|
||||
$core-more-background-md: $list-md-background-color !default;
|
||||
$core-more-activated-background-ios: color-shade($core-more-background-ios) !default;
|
||||
$core-more-activated-background-md: color-shade($core-more-background-md) !default;
|
||||
$core-more-divider-ios: $item-ios-divider-background !default;
|
||||
$core-more-divider-md: $item-md-divider-background !default;
|
||||
$core-more-border-ios: $list-ios-border-color !default;
|
||||
$core-more-border-md: $list-md-border-color !default;
|
||||
$core-more-color-ios: $list-ios-text-color!default;
|
||||
$core-more-color-md: $list-md-text-color !default;
|
||||
|
||||
.item-block {
|
||||
&.item-ios {
|
||||
background-color: $core-more-background-ios;
|
||||
color: $core-more-color-ios;
|
||||
p {
|
||||
color: $core-more-color-ios;
|
||||
}
|
||||
|
||||
.item-inner {
|
||||
border-bottom: $hairlines-width solid $core-more-border-ios;
|
||||
}
|
||||
}
|
||||
&.item-md {
|
||||
background-color: $core-more-background-md;
|
||||
color: $core-more-color-md;
|
||||
p {
|
||||
color: $core-more-color-md;
|
||||
}
|
||||
|
||||
.item-inner {
|
||||
border-bottom: 1px solid $core-more-border-md;
|
||||
}
|
||||
}
|
||||
|
||||
&.activated {
|
||||
&.item-ios {
|
||||
background-color: $core-more-activated-background-ios;
|
||||
}
|
||||
&.item-md {
|
||||
background-color: $core-more-activated-background-md;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ion-icon {
|
||||
color: $core-more-icon;
|
||||
}
|
||||
|
||||
.item-divider {
|
||||
&.item-ios {
|
||||
background-color: $core-more-divider-ios;
|
||||
}
|
||||
|
||||
&.item-md {
|
||||
background-color: $core-more-divider-md;
|
||||
border-bottom: $core-more-border-md;
|
||||
}
|
||||
}
|
||||
|
||||
@include darkmode() {
|
||||
ion-icon {
|
||||
color: $core-dark-text-color;
|
||||
}
|
||||
|
||||
.item-divider {
|
||||
&.item-ios,
|
||||
&.item-md {
|
||||
color: $core-dark-text-color;
|
||||
background-color: $core-dark-item-divider-bg-color;
|
||||
}
|
||||
}
|
||||
|
||||
.item-block {
|
||||
&.item-ios,
|
||||
&.item-md {
|
||||
color: $core-dark-text-color;
|
||||
background-color: $core-dark-item-bg-color;
|
||||
p {
|
||||
color: $core-dark-text-color;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
&.activated {
|
||||
&.item-ios {
|
||||
background-color: $core-more-activated-background-ios;
|
||||
}
|
||||
&.item-md {
|
||||
background-color: $core-more-activated-background-md;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
Loading…
Reference in New Issue