commit
df4dfa6eb5
|
@ -25,6 +25,10 @@ const routes: Routes = [
|
|||
path: 'login',
|
||||
loadChildren: () => import('./core/login/login.module').then( m => m.CoreLoginModule),
|
||||
},
|
||||
{
|
||||
path: 'settings',
|
||||
loadChildren: () => import('./core/settings/settings.module').then( m => m.CoreAppSettingsPageModule),
|
||||
},
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
:host {
|
||||
&.fa {
|
||||
font-size: 24px;
|
||||
contain: none;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
// Center font awesome icons
|
||||
|
|
|
@ -71,6 +71,8 @@ export class CoreIconComponent implements OnChanges, OnDestroy {
|
|||
if (this.fixedWidth) {
|
||||
this.newElement.classList.add('fa-fw');
|
||||
}
|
||||
} else {
|
||||
this.newElement.setAttribute('name', this.name);
|
||||
}
|
||||
|
||||
!this.label && this.newElement.setAttribute('aria-hidden', 'true');
|
||||
|
|
|
@ -19,8 +19,8 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|||
import { IonicModule } from '@ionic/angular';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
|
||||
import { CoreComponentsModule } from '@/app/components/components.module';
|
||||
import { CoreDirectivesModule } from '@/app/directives/directives.module';
|
||||
import { CoreComponentsModule } from '@components/components.module';
|
||||
import { CoreDirectivesModule } from '@directives/directives.module';
|
||||
|
||||
import { CoreLoginRoutingModule } from './login-routing.module';
|
||||
import { CoreLoginCredentialsPage } from './pages/credentials/credentials.page';
|
||||
|
@ -34,6 +34,7 @@ import { CoreLoginHelperProvider } from './services/helper';
|
|||
CommonModule,
|
||||
IonicModule,
|
||||
CoreLoginRoutingModule,
|
||||
CoreComponentsModule,
|
||||
TranslateModule.forChild(),
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
|
|
|
@ -22,9 +22,9 @@ import { CoreSites } from '@services/sites';
|
|||
import { CoreDomUtils } from '@services/utils/dom';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreLoginHelper, CoreLoginHelperProvider } from '@core/login/services/helper';
|
||||
import { CoreConstants } from '@/app/core/constants';
|
||||
import { CoreConstants } from '@core/constants';
|
||||
import { Translate } from '@singletons/core.singletons';
|
||||
import { CoreSiteIdentityProvider, CoreSitePublicConfigResponse } from '@/app/classes/site';
|
||||
import { CoreSiteIdentityProvider, CoreSitePublicConfigResponse } from '@classes/site';
|
||||
import { CoreEvents } from '@singletons/events';
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<ion-back-button></ion-back-button>
|
||||
<ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
|
||||
</ion-buttons>
|
||||
|
||||
<ion-title>{{ 'core.login.connecttomoodle' | translate }}</ion-title>
|
||||
|
||||
<ion-buttons slot="end">
|
||||
<!-- @todo: Settings button. -->
|
||||
<ion-button router-direction="forward" routerLink="/settings/app"
|
||||
[attr.aria-label]="'core.settings.appsettings' | translate">
|
||||
<core-icon slot="icon-only" name="fa-cog"></core-icon>
|
||||
</ion-button>
|
||||
</ion-buttons>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
|
|
@ -24,10 +24,10 @@ import { CoreDomUtils } from '@services/utils/dom';
|
|||
import { CoreLoginHelper, CoreLoginHelperProvider } from '@core/login/services/helper';
|
||||
import { CoreSite } from '@classes/site';
|
||||
import { CoreError } from '@classes/errors/error';
|
||||
import { CoreConstants } from '@/app/core/constants';
|
||||
import { CoreConstants } from '@core/constants';
|
||||
import { Translate } from '@singletons/core.singletons';
|
||||
import { CoreUrl } from '@singletons/url';
|
||||
import { CoreUrlUtils } from '@/app/services/utils/url';
|
||||
import { CoreUrlUtils } from '@services/utils/url';
|
||||
import { NavController } from '@ionic/angular';
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,37 +1,43 @@
|
|||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<ion-back-button></ion-back-button>
|
||||
<ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
|
||||
</ion-buttons>
|
||||
|
||||
<ion-title>{{ 'core.settings.sites' | translate }}</ion-title>
|
||||
|
||||
<ion-buttons slot="end">
|
||||
<!-- @todo: Settings button. -->
|
||||
<ion-button *ngIf="sites && sites.length > 0" icon-only (click)="toggleDelete()" [attr.aria-label]="'core.delete' | translate">
|
||||
<ion-icon name="create" ios="md-create"></ion-icon>
|
||||
<ion-button *ngIf="sites && sites.length > 0" (click)="toggleDelete()" [attr.aria-label]="'core.delete' | translate">
|
||||
<core-icon slot="icon-only" name="fa-pencil"></core-icon>
|
||||
</ion-button>
|
||||
<ion-button router-direction="forward" routerLink="/settings/app"
|
||||
[attr.aria-label]="'core.settings.appsettings' | translate">
|
||||
<core-icon slot="icon-only" name="fa-cog"></core-icon>
|
||||
</ion-button>
|
||||
</ion-buttons>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
<ion-list>
|
||||
<ion-item (click)="login(site.id)" *ngFor="let site of sites; let idx = index" detail-none>
|
||||
<ion-avatar item-start>
|
||||
<ion-item (click)="login(site.id)" *ngFor="let site of sites">
|
||||
<ion-avatar slot="start">
|
||||
<img [src]="site.avatar" core-external-content [siteId]="site.id" alt="{{ 'core.pictureof' | translate:{$a: site.fullName} }}" role="presentation" onError="this.src='assets/img/user-avatar.png'">
|
||||
</ion-avatar>
|
||||
<ion-label>
|
||||
<h2>{{site.fullName}}</h2>
|
||||
<p><core-format-text [text]="site.siteName" clean="true" [siteId]="site.id"></core-format-text></p>
|
||||
<p>{{site.siteUrl}}</p>
|
||||
<ion-badge item-end *ngIf="!showDelete && site.badge">{{site.badge}}</ion-badge>
|
||||
<ion-button *ngIf="showDelete" item-end icon-only clear color="danger" (click)="deleteSite($event, idx)" [attr.aria-label]="'core.delete' | translate">
|
||||
<ion-icon name="trash"></ion-icon>
|
||||
</ion-label>
|
||||
<ion-badge slot="end" *ngIf="!showDelete && site.badge">{{site.badge}}</ion-badge>
|
||||
<ion-button *ngIf="showDelete" slot="end" fill="clear" color="danger" (click)="deleteSite($event, site)"
|
||||
[attr.aria-label]="'core.delete' | translate">
|
||||
<core-icon name="fa-trash" slot="icon-only"></core-icon>
|
||||
</ion-button>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
<ion-fab slot="fixed" core-fab vertical="bottom" horizontal="end">
|
||||
<ion-fab-button (click)="add()" [attr.aria-label]="'core.add' | translate">
|
||||
<ion-icon name="add"></ion-icon>
|
||||
<core-icon name="fa-plus"></core-icon>
|
||||
</ion-fab-button>
|
||||
</ion-fab>
|
||||
</ion-content>
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { CoreDomUtils } from '@/app/services/utils/dom';
|
||||
import { CoreUtils } from '@/app/services/utils/utils';
|
||||
import { CoreDomUtils } from '@services/utils/dom';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
import { CoreSiteBasicInfo, CoreSites } from '@services/sites';
|
||||
|
@ -26,7 +26,6 @@ import { CoreLoginHelper } from '../../services/helper';
|
|||
@Component({
|
||||
selector: 'page-core-login-sites',
|
||||
templateUrl: 'sites.html',
|
||||
styleUrls: ['sites.scss'],
|
||||
})
|
||||
export class CoreLoginSitesPage implements OnInit {
|
||||
|
||||
|
@ -76,13 +75,12 @@ export class CoreLoginSitesPage implements OnInit {
|
|||
* Delete a site.
|
||||
*
|
||||
* @param e Click event.
|
||||
* @param index Position of the site.
|
||||
* @param site Site to delete.
|
||||
* @return Promise resolved when done.
|
||||
*/
|
||||
async deleteSite(e: Event, index: number): Promise<void> {
|
||||
async deleteSite(e: Event, site: CoreSiteBasicInfo): Promise<void> {
|
||||
e.stopPropagation();
|
||||
|
||||
const site = this.sites[index];
|
||||
const siteName = site.siteName || '';
|
||||
|
||||
// @todo: Format text: siteName.
|
||||
|
@ -97,7 +95,8 @@ export class CoreLoginSitesPage implements OnInit {
|
|||
try {
|
||||
await CoreSites.instance.deleteSite(site.id);
|
||||
|
||||
this.sites.splice(index, 1);
|
||||
const index = this.sites.findIndex((listedSite) => listedSite.id == site.id);
|
||||
index >= 0 && this.sites.splice(index, 1);
|
||||
this.showDelete = false;
|
||||
|
||||
// If there are no sites left, go to add site.
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
.item-ios .item-button[icon-only] ion-icon {
|
||||
font-size: 2.1em;
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
{
|
||||
"about": "About",
|
||||
"appsettings": "App settings",
|
||||
"appversion": "App version",
|
||||
"cannotsyncloggedout": "This site cannot be synchronised because you've logged out. Please try again when you're logged in the site again.",
|
||||
"cannotsyncoffline": "Cannot synchronise offline.",
|
||||
"cannotsyncwithoutwifi": "Cannot synchronise because the current settings only allow to synchronise when connected to Wi-Fi. Please connect to a Wi-Fi network.",
|
||||
"colorscheme": "Color Scheme",
|
||||
"colorscheme-auto": "Auto (based on system settings)",
|
||||
"colorscheme-dark": "Dark",
|
||||
"colorscheme-light": "Light",
|
||||
"compilationinfo": "Compilation info",
|
||||
"copyinfo": "Copy device info on the clipboard",
|
||||
"cordovadevicemodel": "Cordova device model",
|
||||
"cordovadeviceosversion": "Cordova device OS version",
|
||||
"cordovadeviceplatform": "Cordova device platform",
|
||||
"cordovadeviceuuid": "Cordova device UUID",
|
||||
"cordovaversion": "Cordova version",
|
||||
"currentlanguage": "Current language",
|
||||
"debugdisplay": "Display debug messages",
|
||||
"debugdisplaydescription": "If enabled, error modals will display more data about the error if possible.",
|
||||
"deletesitefiles": "Are you sure that you want to delete the downloaded files and cached data from the site '{{sitename}}'? You won't be able to use the app in offline mode.",
|
||||
"deletesitefilestitle": "Delete site files",
|
||||
"deviceinfo": "Device info",
|
||||
"deviceos": "Device OS",
|
||||
"disableall": "Disable notifications",
|
||||
"disabled": "Disabled",
|
||||
"displayformat": "Display format",
|
||||
"enabledownloadsection": "Enable download sections",
|
||||
"enablefirebaseanalytics": "Enable Firebase analytics",
|
||||
"enablefirebaseanalyticsdescription": "If enabled, the app will collect anonymous data usage.",
|
||||
"enablerichtexteditor": "Enable text editor",
|
||||
"enablerichtexteditordescription": "If enabled, a text editor will be available when entering content.",
|
||||
"enablesyncwifi": "Allow sync only when on Wi-Fi",
|
||||
"entriesincache": "{{$a}} entries in cache",
|
||||
"errordeletesitefiles": "Error deleting site files.",
|
||||
"errorsyncsite": "Error synchronising site data. Please check your Internet connection and try again.",
|
||||
"estimatedfreespace": "Estimated free space",
|
||||
"filesystemroot": "File system root",
|
||||
"fontsize": "Text size",
|
||||
"fontsizecharacter": "A",
|
||||
"forcedsetting": "This setting has been forced by your site configuration.",
|
||||
"general": "General",
|
||||
"language": "Language",
|
||||
"license": "Licence",
|
||||
"localnotifavailable": "Local notifications available",
|
||||
"locationhref": "Web view URL",
|
||||
"locked": "Locked",
|
||||
"loggedin": "Online",
|
||||
"loggedoff": "Offline",
|
||||
"navigatorlanguage": "Navigator language",
|
||||
"navigatoruseragent": "Navigator userAgent",
|
||||
"networkstatus": "Internet connection status",
|
||||
"opensourcelicenses": "Open Source Licences",
|
||||
"preferences": "Preferences",
|
||||
"privacypolicy": "Privacy policy",
|
||||
"publisher": "Publisher",
|
||||
"pushid": "Push notifications ID",
|
||||
"reportinbackground": "Report errors automatically",
|
||||
"screen": "Screen information",
|
||||
"settings": "Settings",
|
||||
"showdownloadoptions": "Show download options",
|
||||
"siteinfo": "Site info",
|
||||
"sites": "Sites",
|
||||
"spaceusage": "Space usage",
|
||||
"spaceusagehelp": "Deleting the stored information of the site will remove all the site offline data. This information allows you to use the app when offline. ",
|
||||
"synchronization": "Synchronisation",
|
||||
"synchronizenow": "Synchronise now",
|
||||
"synchronizenowhelp": "Synchronising a site will send pending changes and all offline activity stored in the device and will synchronise some data like messages and notifications.",
|
||||
"syncsettings": "Synchronisation settings",
|
||||
"total": "Total",
|
||||
"wificonnection": "Wi-Fi connection"
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
|
||||
</ion-buttons>
|
||||
<ion-title>
|
||||
{{ 'core.settings.about' | translate}}
|
||||
</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content>
|
||||
<ion-item text-wrap>
|
||||
<ion-label><h2>{{ appName }} {{ versionName }}</h2></ion-label>
|
||||
</ion-item>
|
||||
<ion-item text-wrap (click)="openPage('licenses')" detail>
|
||||
<core-icon name="fa-copyright" slot="start"></core-icon>
|
||||
<ion-label>{{ 'core.settings.opensourcelicenses' | translate }}</ion-label>
|
||||
</ion-item>
|
||||
<ion-item text-wrap *ngIf="privacyPolicy" [href]="privacyPolicy" core-link auto-login="no" detail>
|
||||
<core-icon name="fa-user-secret" slot="start"></core-icon>
|
||||
<ion-label>{{ 'core.settings.privacypolicy' | translate }}</ion-label>
|
||||
</ion-item>
|
||||
<ion-item text-wrap (click)="openPage('deviceinfo')" detail>
|
||||
<core-icon name="fa-mobile" slot="start"></core-icon>
|
||||
<ion-label>{{ 'core.settings.deviceinfo' | translate }}</ion-label>
|
||||
</ion-item>
|
||||
</ion-content>
|
|
@ -0,0 +1,55 @@
|
|||
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { CoreSites } from '@services/sites';
|
||||
import { Component } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { CoreConstants } from '@core/constants';
|
||||
import { CoreApp } from '@services/app';
|
||||
|
||||
@Component({
|
||||
selector: 'settings-about',
|
||||
templateUrl: 'about.html',
|
||||
})
|
||||
export class CoreSettingsAboutPage {
|
||||
|
||||
appName: string;
|
||||
versionName: string;
|
||||
privacyPolicy: string;
|
||||
|
||||
constructor(
|
||||
protected router: Router,
|
||||
) {
|
||||
const currentSite = CoreSites.instance.getCurrentSite();
|
||||
|
||||
this.appName = CoreApp.instance.isDesktop() ? CoreConstants.CONFIG.desktopappname : CoreConstants.CONFIG.appname;
|
||||
this.versionName = CoreConstants.CONFIG.versionname;
|
||||
|
||||
// Calculate the privacy policy to use.
|
||||
this.privacyPolicy = (currentSite && (currentSite.getStoredConfig('tool_mobile_apppolicy') ||
|
||||
currentSite.getStoredConfig('sitepolicy'))) || CoreConstants.CONFIG.privacypolicy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a page.
|
||||
*
|
||||
* @param page The component deeplink name you want to push onto the navigation stack.
|
||||
*/
|
||||
openPage(page: string): void {
|
||||
// const navCtrl = this.svComponent ? this.svComponent.getMasterNav() : this.navCtrl;
|
||||
// navCtrl.push(page);
|
||||
this.router.navigate(['/settings/' + page]);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
|
||||
</ion-buttons>
|
||||
<ion-title>
|
||||
{{ 'core.settings.appsettings' | translate}}
|
||||
</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
<ion-item (click)="openSettings('general')" [class.core-split-item-selected]="'general' == selectedPage" detail>
|
||||
<core-icon name="fa-wrench" slot="start"></core-icon>
|
||||
<ion-label>{{ 'core.settings.general' | translate }}</ion-label>
|
||||
</ion-item>
|
||||
<ion-item (click)="openSettings('spaceusage')" [class.core-split-item-selected]="'spaceusage' == selectedPage" detail>
|
||||
<core-icon name="fa-tasks" slot="start"></core-icon>
|
||||
<ion-label>{{ 'core.settings.spaceusage' | translate }}</ion-label>
|
||||
</ion-item>
|
||||
<ion-item (click)="openSettings('sync')" [class.core-split-item-selected]="'sync' == selectedPage" detail>
|
||||
<core-icon name="fa-refresh" slot="start"></core-icon>
|
||||
<ion-label>{{ 'core.settings.synchronization' | translate }}</ion-label>
|
||||
</ion-item>
|
||||
<ion-item *ngIf="isIOS" (click)="openSettings('sharedfiles', {manage: true})"
|
||||
[class.core-split-item-selected]="'sharedfiles' == selectedPage" detail>
|
||||
<core-icon name="fa-folder" slot="start"></core-icon>
|
||||
<ion-label>{{ 'core.sharedfiles.sharedfiles' | translate }}</ion-label>
|
||||
</ion-item>
|
||||
<ion-item (click)="openSettings('about')" [class.core-split-item-selected]="'about' == selectedPage" detail>
|
||||
<core-icon name="fa-id-card" slot="start"></core-icon>
|
||||
<ion-label>{{ 'core.settings.about' | translate }}</ion-label>
|
||||
</ion-item>
|
||||
</ion-content>
|
|
@ -0,0 +1,65 @@
|
|||
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { CoreApp } from '@services/app';
|
||||
import { Component } from '@angular/core';
|
||||
import { ActivatedRoute, Params, Router } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
selector: 'app-settings',
|
||||
templateUrl: 'app.html',
|
||||
})
|
||||
export class CoreAppSettingsPage {
|
||||
|
||||
// @ViewChild(CoreSplitViewComponent) splitviewCtrl?: CoreSplitViewComponent;
|
||||
|
||||
isIOS: boolean;
|
||||
selectedPage?: string;
|
||||
|
||||
constructor(
|
||||
protected route: ActivatedRoute,
|
||||
protected router: Router, // Will be removed when splitview is implemented
|
||||
) {
|
||||
this.isIOS = CoreApp.instance.isIOS();
|
||||
this.selectedPage = route.snapshot.paramMap.get('page') || undefined;
|
||||
|
||||
if (this.selectedPage) {
|
||||
this.openSettings(this.selectedPage);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* View loaded.
|
||||
*/
|
||||
ionViewDidLoad(): void {
|
||||
if (this.selectedPage) {
|
||||
this.openSettings(this.selectedPage);
|
||||
} /* else if (this.splitviewCtrl!.isOn()) {
|
||||
this.openSettings('general');
|
||||
}*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a settings page.
|
||||
*
|
||||
* @param page Page to open.
|
||||
* @param params Params of the page to open.
|
||||
*/
|
||||
openSettings(page: string, params?: Params): void {
|
||||
this.selectedPage = page;
|
||||
// this.splitviewCtrl!.push(page, params);
|
||||
this.router.navigate(['../'+page], { relativeTo: this.route, queryParams: params });
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,142 @@
|
|||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
|
||||
</ion-buttons>
|
||||
<ion-title>
|
||||
{{ 'core.settings.deviceinfo' | translate }}
|
||||
</ion-title>
|
||||
<ion-buttons slot="end">
|
||||
<ion-button (click)="copyInfo()" [attr.aria-label]="'core.settings.copyinfo' | translate">
|
||||
<core-icon slot="icon-only" name="fa-clipboard" color="light"></core-icon>
|
||||
</ion-button>
|
||||
</ion-buttons>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content>
|
||||
<ion-item (longPress)="copyItemInfo($event)">
|
||||
<ion-label class="ion-text-wrap">
|
||||
<h2>{{ 'core.settings.appversion' | translate}}</h2>
|
||||
<p>{{ deviceInfo.versionName }} ({{ deviceInfo.versionCode }})</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item (longPress)="copyItemInfo($event)">
|
||||
<ion-label class="ion-text-wrap">
|
||||
<h2>{{ 'core.settings.compilationinfo' | translate }}</h2>
|
||||
<p *ngIf="deviceInfo.compilationTime">{{ deviceInfo.compilationTime | coreFormatDate: "LLL Z": false }}</p>
|
||||
<p *ngIf="deviceInfo.lastCommit">{{ deviceInfo.lastCommit }}</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item *ngIf="deviceInfo.siteUrl" (longPress)="copyItemInfo($event)">
|
||||
<ion-label class="ion-text-wrap">
|
||||
<h2>{{ 'core.settings.siteinfo' | translate }}<ng-container *ngIf="deviceInfo.isPrefixedUrl"> *</ng-container></h2>
|
||||
<p><a [href]="deviceInfo.siteUrl" core-link auto-login="yes">{{ deviceInfo.siteUrl }}</a></p>
|
||||
<p *ngIf="deviceInfo.siteVersion">{{ deviceInfo.siteVersion }}</p>
|
||||
<p *ngIf="deviceInfo.siteId">{{ deviceInfo.siteId }}</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item *ngIf="deviceInfo.fileSystemRoot" (longPress)="copyItemInfo($event)">
|
||||
<ion-label class="ion-text-wrap">
|
||||
<h2>{{ 'core.settings.filesystemroot' | translate }}</h2>
|
||||
<p><a *ngIf="fsClickable" [href]="deviceInfo.fileSystemRoot" core-link auto-login="no">{{ deviceInfo.fileSystemRoot }}</a></p>
|
||||
<p *ngIf="!fsClickable">{{ deviceInfo.fileSystemRoot }}</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item *ngIf="deviceInfo.userAgent" (longPress)="copyItemInfo($event)">
|
||||
<ion-label class="ion-text-wrap">
|
||||
<h2>{{ 'core.settings.navigatoruseragent' | translate }}</h2>
|
||||
<p>{{ deviceInfo.userAgent }}</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item *ngIf="deviceInfo.browserLanguage" (longPress)="copyItemInfo($event)">
|
||||
<ion-label class="ion-text-wrap">
|
||||
<h2>{{ 'core.settings.navigatorlanguage' | translate }}</h2>
|
||||
<p>{{ deviceInfo.browserLanguage }}</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item *ngIf="deviceInfo.currentLanguage" (longPress)="copyItemInfo($event)">
|
||||
<ion-label class="ion-text-wrap">
|
||||
<h2>{{ 'core.settings.currentlanguage' | translate }}</h2>
|
||||
<p>{{ currentLangName }} ({{ deviceInfo.currentLanguage }})</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item *ngIf="deviceInfo.locationHref" (longPress)="copyItemInfo($event)">
|
||||
<ion-label class="ion-text-wrap">
|
||||
<h2>{{ 'core.settings.locationhref' | translate }}</h2>
|
||||
<p>{{ deviceInfo.locationHref }}</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item *ngIf="deviceInfo.deviceType" (longPress)="copyItemInfo($event)">
|
||||
<ion-label class="ion-text-wrap">
|
||||
<h2>{{ 'core.settings.displayformat' | translate }}</h2>
|
||||
<p>{{ 'core.' + deviceInfo.deviceType | translate }}</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item *ngIf="deviceInfo.deviceOs && deviceOsTranslated" (longPress)="copyItemInfo($event)">
|
||||
<ion-label class="ion-text-wrap">
|
||||
<h2>{{ 'core.settings.deviceos' | translate}}</h2>
|
||||
<p>{{ deviceOsTranslated }}</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item *ngIf="deviceInfo.screen" (longPress)="copyItemInfo($event)">
|
||||
<ion-label class="ion-text-wrap">
|
||||
<h2>{{ 'core.settings.screen' | translate }}</h2>
|
||||
<p>{{ deviceInfo.screen }}</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item (longPress)="copyItemInfo($event)">
|
||||
<ion-label class="ion-text-wrap">
|
||||
<h2>{{ 'core.settings.networkstatus' | translate}}</h2>
|
||||
<p>{{ 'core.' + deviceInfo.networkStatus | translate }}</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item (longPress)="copyItemInfo($event)">
|
||||
<ion-label class="ion-text-wrap">
|
||||
<h2>{{ 'core.settings.wificonnection' | translate}}</h2>
|
||||
<p>{{ 'core.' + deviceInfo.wifiConnection | translate }}</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item *ngIf="deviceInfo.cordovaVersion" (longPress)="copyItemInfo($event)">
|
||||
<ion-label class="ion-text-wrap">
|
||||
<h2>{{ 'core.settings.cordovaversion' | translate }}</h2>
|
||||
<p>{{ deviceInfo.cordovaVersion }}</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item *ngIf="deviceInfo.platform" (longPress)="copyItemInfo($event)">
|
||||
<ion-label class="ion-text-wrap">
|
||||
<h2>{{ 'core.settings.cordovadeviceplatform' | translate }}</h2>
|
||||
<p>{{ deviceInfo.platform }}</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item *ngIf="deviceInfo.osVersion" (longPress)="copyItemInfo($event)">
|
||||
<ion-label class="ion-text-wrap">
|
||||
<h2>{{ 'core.settings.cordovadeviceosversion' | translate }}</h2>
|
||||
<p>{{ deviceInfo.osVersion }}</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item *ngIf="deviceInfo.model" (longPress)="copyItemInfo($event)">
|
||||
<ion-label class="ion-text-wrap">
|
||||
<h2>{{ 'core.settings.cordovadevicemodel' | translate}}</h2>
|
||||
<p>{{ deviceInfo.model }}</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item *ngIf="deviceInfo.uuid" (longPress)="copyItemInfo($event)">
|
||||
<ion-label class="ion-text-wrap">
|
||||
<h2>{{ 'core.settings.cordovadeviceuuid'}}</h2>
|
||||
<p>{{ deviceInfo.uuid }}</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item *ngIf="deviceInfo.pushId" (longPress)="copyItemInfo($event)">
|
||||
<ion-label class="ion-text-wrap">
|
||||
<h2>{{ 'core.settings.pushid' | translate }}</h2>
|
||||
<p>{{ deviceInfo.pushId }}</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item (longPress)="copyItemInfo($event)">
|
||||
<ion-label class="ion-text-wrap">
|
||||
<h2>{{ 'core.settings.localnotifavailable' | translate }}</h2>
|
||||
<p>{{ 'core.' + deviceInfo.localNotifAvailable | translate }}</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
</ion-content>
|
|
@ -0,0 +1,232 @@
|
|||
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { CoreApp } from '@services/app';
|
||||
import { Component, OnDestroy } from '@angular/core';
|
||||
import { CoreConstants } from '@core/constants';
|
||||
import { CoreLocalNotifications } from '@services/local-notifications';
|
||||
import { Device, Platform, Translate, Network, NgZone } from '@singletons/core.singletons';
|
||||
import { CoreLang } from '@services/lang';
|
||||
import { CoreFile } from '@services/file';
|
||||
import { CoreSites } from '@services/sites';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { Subscription } from 'rxjs';
|
||||
|
||||
/**
|
||||
* Device Info to be shown and copied to clipboard.
|
||||
*/
|
||||
interface CoreSettingsDeviceInfo {
|
||||
versionName: string;
|
||||
versionCode: number;
|
||||
compilationTime: number;
|
||||
lastCommit: string;
|
||||
siteUrl?: string;
|
||||
isPrefixedUrl?: boolean;
|
||||
siteId?: string;
|
||||
siteVersion?: string;
|
||||
fileSystemRoot?: string;
|
||||
userAgent?: string;
|
||||
deviceOs?: string;
|
||||
browserLanguage?: string;
|
||||
currentLanguage?: string;
|
||||
locationHref?: string;
|
||||
deviceType: string;
|
||||
screen?: string;
|
||||
networkStatus: string;
|
||||
wifiConnection: string;
|
||||
cordovaVersion?: string;
|
||||
platform?: string;
|
||||
osVersion?: string;
|
||||
model?: string;
|
||||
uuid?: string;
|
||||
pushId: string;
|
||||
localNotifAvailable: string;
|
||||
}
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'settings-deviceinfo',
|
||||
templateUrl: 'deviceinfo.html',
|
||||
styleUrls: ['deviceinfo.scss'],
|
||||
})
|
||||
export class CoreSettingsDeviceInfoPage implements OnDestroy {
|
||||
|
||||
deviceInfo: CoreSettingsDeviceInfo;
|
||||
deviceOsTranslated?: string;
|
||||
currentLangName?: string;
|
||||
fsClickable = false;
|
||||
|
||||
protected onlineObserver?: Subscription;
|
||||
|
||||
constructor() {
|
||||
const appProvider = CoreApp.instance;
|
||||
const sitesProvider = CoreSites.instance;
|
||||
const device = Device.instance;
|
||||
const translate = Translate.instance;
|
||||
const navigator = window.navigator;
|
||||
|
||||
this.deviceInfo = {
|
||||
versionName: CoreConstants.CONFIG.versionname,
|
||||
versionCode: CoreConstants.CONFIG.versioncode,
|
||||
compilationTime: CoreConstants.BUILD.compilationTime || 0,
|
||||
lastCommit: CoreConstants.BUILD.lastCommitHash || '',
|
||||
networkStatus: appProvider.isOnline() ? 'online' : 'offline',
|
||||
wifiConnection: appProvider.isWifi() ? 'yes' : 'no',
|
||||
localNotifAvailable: CoreLocalNotifications.instance.isAvailable() ? 'yes' : 'no',
|
||||
pushId: '',// TODO pushNotificationsProvider.getPushId(),
|
||||
deviceType: '',
|
||||
};
|
||||
|
||||
if (window.location && window.location.href) {
|
||||
const url = window.location.href;
|
||||
this.deviceInfo.locationHref = url.indexOf('#') > 0 ? url.substr(0, url.indexOf('#')) : url;
|
||||
}
|
||||
|
||||
if (window.screen) {
|
||||
this.deviceInfo.screen = window.innerWidth + 'x' + window.innerHeight +
|
||||
' (' + window.screen.width + 'x' + window.screen.height + ')';
|
||||
}
|
||||
|
||||
if (appProvider.isMobile()) {
|
||||
this.deviceInfo.deviceType = Platform.instance.is('tablet') ? 'tablet' : 'phone';
|
||||
if (appProvider.isAndroid()) {
|
||||
this.deviceInfo.deviceOs = 'android';
|
||||
this.deviceOsTranslated = 'Android';
|
||||
} else if (appProvider.isIOS()) {
|
||||
this.deviceInfo.deviceOs = 'ios';
|
||||
this.deviceOsTranslated = 'iOS';
|
||||
} else {
|
||||
const matches = navigator.userAgent.match(/\(([^)]*)\)/);
|
||||
if (matches && matches.length > 1) {
|
||||
this.deviceInfo.deviceOs = matches[1];
|
||||
this.deviceOsTranslated = matches[1];
|
||||
} else {
|
||||
this.deviceInfo.deviceOs = 'unknown';
|
||||
this.deviceOsTranslated = translate.instant('core.unknown');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.deviceInfo.deviceType = appProvider.isDesktop() ? 'desktop' : 'browser';
|
||||
if (appProvider.isLinux()) {
|
||||
this.deviceInfo.deviceOs = 'linux';
|
||||
this.deviceOsTranslated = 'Linux';
|
||||
} else if (appProvider.isMac()) {
|
||||
this.deviceInfo.deviceOs = 'mac';
|
||||
this.deviceOsTranslated = 'MacOS';
|
||||
} else if (appProvider.isWindows()) {
|
||||
this.deviceInfo.deviceOs = 'windows';
|
||||
this.deviceOsTranslated = 'Windows';
|
||||
} else {
|
||||
const matches = navigator.userAgent.match(/\(([^)]*)\)/);
|
||||
if (matches && matches.length > 1) {
|
||||
this.deviceInfo.deviceOs = matches[1];
|
||||
this.deviceOsTranslated = matches[1];
|
||||
} else {
|
||||
this.deviceInfo.deviceOs = 'unknown';
|
||||
this.deviceOsTranslated = translate.instant('core.unknown');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (navigator) {
|
||||
if (navigator.userAgent) {
|
||||
this.deviceInfo.userAgent = navigator.userAgent;
|
||||
}
|
||||
|
||||
if (navigator.language) {
|
||||
this.deviceInfo.browserLanguage = navigator.language;
|
||||
}
|
||||
}
|
||||
|
||||
if (device) {
|
||||
if (device.cordova) {
|
||||
this.deviceInfo.cordovaVersion = device.cordova;
|
||||
}
|
||||
if (device.platform) {
|
||||
this.deviceInfo.platform = device.platform;
|
||||
}
|
||||
if (device.version) {
|
||||
this.deviceInfo.osVersion = device.version;
|
||||
}
|
||||
if (device.model) {
|
||||
this.deviceInfo.model = device.model;
|
||||
}
|
||||
if (device.uuid) {
|
||||
this.deviceInfo.uuid = device.uuid;
|
||||
}
|
||||
}
|
||||
|
||||
const currentSite = sitesProvider.getCurrentSite();
|
||||
|
||||
this.deviceInfo.siteUrl = (currentSite?.getURL()) ||
|
||||
(typeof CoreConstants.CONFIG.siteurl == 'string' && CoreConstants.CONFIG.siteurl) || undefined;
|
||||
this.deviceInfo.isPrefixedUrl = !!CoreConstants.CONFIG.siteurl;
|
||||
this.deviceInfo.siteId = currentSite?.getId();
|
||||
this.deviceInfo.siteVersion = currentSite?.getInfo()?.release;
|
||||
|
||||
// Refresh online status when changes.
|
||||
this.onlineObserver = Network.instance.onChange().subscribe(() => {
|
||||
// Execute the callback in the Angular zone, so change detection doesn't stop working.
|
||||
NgZone.instance.run(() => {
|
||||
this.deviceInfo!.networkStatus = appProvider.isOnline() ? 'online' : 'offline';
|
||||
});
|
||||
});
|
||||
|
||||
this.asyncInit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Async part of the constructor.
|
||||
*/
|
||||
protected async asyncInit(): Promise<void> {
|
||||
const fileProvider = CoreFile.instance;
|
||||
|
||||
const lang = await CoreLang.instance.getCurrentLanguage();
|
||||
this.deviceInfo.currentLanguage = lang;
|
||||
this.currentLangName = CoreConstants.CONFIG.languages[lang];
|
||||
|
||||
if (fileProvider.isAvailable()) {
|
||||
const basepath = await fileProvider.getBasePath();
|
||||
this.deviceInfo.fileSystemRoot = basepath;
|
||||
this.fsClickable = fileProvider.usesHTMLAPI();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies device info into the clipboard.
|
||||
*/
|
||||
copyInfo(): void {
|
||||
CoreUtils.instance.copyToClipboard(JSON.stringify(this.deviceInfo));
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies device info item into the clipboard.
|
||||
*
|
||||
* @param e Event.
|
||||
*/
|
||||
copyItemInfo(e: Event): void {
|
||||
const el = <Element>e.target;
|
||||
const text = el?.closest('ion-item')?.textContent?.trim();
|
||||
|
||||
text && CoreUtils.instance.copyToClipboard(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Page destroyed.
|
||||
*/
|
||||
ngOnDestroy(): void {
|
||||
this.onlineObserver && this.onlineObserver.unsubscribe();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
.item {
|
||||
user-select: text;
|
||||
cursor: text;
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { CoreAppSettingsPage } from './pages/app/app.page';
|
||||
import { CoreSettingsAboutPage } from './pages/about/about.page';
|
||||
import { CoreSettingsDeviceInfoPage } from './pages/deviceinfo/deviceinfo.page';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: 'about',
|
||||
component: CoreSettingsAboutPage,
|
||||
},
|
||||
{
|
||||
path: 'deviceinfo',
|
||||
component: CoreSettingsDeviceInfoPage,
|
||||
},
|
||||
{
|
||||
path: 'app',
|
||||
component: CoreAppSettingsPage,
|
||||
},
|
||||
{
|
||||
path: '',
|
||||
redirectTo: 'app',
|
||||
pathMatch: 'full',
|
||||
},
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule],
|
||||
})
|
||||
export class CoreAppSettingsRoutingModule {}
|
|
@ -0,0 +1,46 @@
|
|||
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
import { IonicModule } from '@ionic/angular';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
|
||||
import { CoreAppSettingsRoutingModule } from './settings-routing.module';
|
||||
import { CorePipesModule } from '@pipes/pipes.module';
|
||||
import { CoreComponentsModule } from '@components/components.module';
|
||||
import { CoreDirectivesModule } from '@directives/directives.module';
|
||||
|
||||
import { CoreAppSettingsPage } from './pages/app/app.page';
|
||||
import { CoreSettingsAboutPage } from './pages/about/about.page';
|
||||
import { CoreSettingsDeviceInfoPage } from './pages/deviceinfo/deviceinfo.page';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
CoreAppSettingsRoutingModule,
|
||||
CorePipesModule,
|
||||
CoreComponentsModule,
|
||||
CoreDirectivesModule,
|
||||
TranslateModule.forChild(),
|
||||
],
|
||||
declarations: [
|
||||
CoreAppSettingsPage,
|
||||
CoreSettingsAboutPage,
|
||||
CoreSettingsDeviceInfoPage,
|
||||
],
|
||||
})
|
||||
export class CoreAppSettingsPageModule {}
|
|
@ -17,8 +17,9 @@ import { NgModule } from '@angular/core';
|
|||
import { CoreAutoFocusDirective } from './auto-focus';
|
||||
import { CoreExternalContentDirective } from './external-content';
|
||||
import { CoreFormatTextDirective } from './format-text';
|
||||
import { CoreLongPressDirective } from './long-press.directive';
|
||||
import { CoreLongPressDirective } from './long-press';
|
||||
import { CoreSupressEventsDirective } from './supress-events';
|
||||
import { CoreFabDirective } from './fab';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
|
@ -27,6 +28,7 @@ import { CoreSupressEventsDirective } from './supress-events';
|
|||
CoreFormatTextDirective,
|
||||
CoreLongPressDirective,
|
||||
CoreSupressEventsDirective,
|
||||
CoreFabDirective,
|
||||
],
|
||||
imports: [],
|
||||
exports: [
|
||||
|
@ -35,6 +37,7 @@ import { CoreSupressEventsDirective } from './supress-events';
|
|||
CoreFormatTextDirective,
|
||||
CoreLongPressDirective,
|
||||
CoreSupressEventsDirective,
|
||||
CoreFabDirective,
|
||||
],
|
||||
})
|
||||
export class CoreDirectivesModule {}
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Directive, OnDestroy } from '@angular/core';
|
||||
import { IonContent } from '@ionic/angular';
|
||||
|
||||
/**
|
||||
* Directive to move ion-fab components as direct children of the nearest ion-content.
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
* <ion-fab core-fab>
|
||||
*/
|
||||
@Directive({
|
||||
selector: 'ion-fab[core-fab]',
|
||||
})
|
||||
export class CoreFabDirective implements OnDestroy {
|
||||
|
||||
protected static readonly PADDINGBOTTOM = 56;
|
||||
|
||||
protected element?: HTMLElement;
|
||||
protected done = false;
|
||||
|
||||
constructor(protected content: IonContent) {
|
||||
this.asyncInit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize Component.
|
||||
*/
|
||||
async asyncInit(): Promise<void> {
|
||||
if (this.content) {
|
||||
this.element = await this.content.getScrollElement();
|
||||
if (!this.done) {
|
||||
const bottom = parseInt(this.element.style.paddingBottom, 10) || 0;
|
||||
this.element.style.paddingBottom = (bottom + CoreFabDirective.PADDINGBOTTOM) + 'px';
|
||||
this.done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy component.
|
||||
*/
|
||||
ngOnDestroy(): void {
|
||||
if (this.done && this.element) {
|
||||
const bottom = parseInt(this.element.style.paddingBottom, 10) || 0;
|
||||
this.element.style.paddingBottom = (bottom + CoreFabDirective.PADDINGBOTTOM) + 'px';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"back": "Back",
|
||||
"browser": "Browser",
|
||||
"copiedtoclipboard": "Text copied to clipboard",
|
||||
"no": "No",
|
||||
"offline": "Offline",
|
||||
"ok": "OK",
|
||||
"online": "Online",
|
||||
"unknown": "Unknown",
|
||||
"yes": "Yes"
|
||||
}
|
|
@ -16,7 +16,7 @@ import { Injectable } from '@angular/core';
|
|||
|
||||
import { CoreLang } from '@services/lang';
|
||||
import { CoreTextUtils } from '@services/utils/text';
|
||||
import { CoreConstants } from '@/app/core/constants';
|
||||
import { CoreConstants } from '@core/constants';
|
||||
import { makeSingleton } from '@singletons/core.singletons';
|
||||
import { CoreUrl } from '@singletons/url';
|
||||
|
||||
|
|
|
@ -300,5 +300,85 @@
|
|||
"assets.mimetypes.text/rtf": "RTF document",
|
||||
"assets.mimetypes.text/vtt": "Web Video Text Track",
|
||||
"assets.mimetypes.video": "Video file ({{$a.EXT}})",
|
||||
"core.login.yourenteredsite": "Connect to your site"
|
||||
"core.back": "Back",
|
||||
"core.browser": "Browser",
|
||||
"core.copiedtoclipboard": "Text copied to clipboard",
|
||||
"core.login.yourenteredsite": "Connect to your site",
|
||||
"core.no": "No",
|
||||
"core.offline": "Offline",
|
||||
"core.ok": "OK",
|
||||
"core.online": "Online",
|
||||
"core.settings.about": "About",
|
||||
"core.settings.appsettings": "App settings",
|
||||
"core.settings.appversion": "App version",
|
||||
"core.settings.cannotsyncloggedout": "This site cannot be synchronised because you've logged out. Please try again when you're logged in the site again.",
|
||||
"core.settings.cannotsyncoffline": "Cannot synchronise offline.",
|
||||
"core.settings.cannotsyncwithoutwifi": "Cannot synchronise because the current settings only allow to synchronise when connected to Wi-Fi. Please connect to a Wi-Fi network.",
|
||||
"core.settings.colorscheme": "Color Scheme",
|
||||
"core.settings.colorscheme-auto": "Auto (based on system settings)",
|
||||
"core.settings.colorscheme-dark": "Dark",
|
||||
"core.settings.colorscheme-light": "Light",
|
||||
"core.settings.compilationinfo": "Compilation info",
|
||||
"core.settings.copyinfo": "Copy device info on the clipboard",
|
||||
"core.settings.cordovadevicemodel": "Cordova device model",
|
||||
"core.settings.cordovadeviceosversion": "Cordova device OS version",
|
||||
"core.settings.cordovadeviceplatform": "Cordova device platform",
|
||||
"core.settings.cordovadeviceuuid": "Cordova device UUID",
|
||||
"core.settings.cordovaversion": "Cordova version",
|
||||
"core.settings.currentlanguage": "Current language",
|
||||
"core.settings.debugdisplay": "Display debug messages",
|
||||
"core.settings.debugdisplaydescription": "If enabled, error modals will display more data about the error if possible.",
|
||||
"core.settings.deletesitefiles": "Are you sure that you want to delete the downloaded files and cached data from the site '{{sitename}}'? You won't be able to use the app in offline mode.",
|
||||
"core.settings.deletesitefilestitle": "Delete site files",
|
||||
"core.settings.deviceinfo": "Device info",
|
||||
"core.settings.deviceos": "Device OS",
|
||||
"core.settings.disableall": "Disable notifications",
|
||||
"core.settings.disabled": "Disabled",
|
||||
"core.settings.displayformat": "Display format",
|
||||
"core.settings.enabledownloadsection": "Enable download sections",
|
||||
"core.settings.enablefirebaseanalytics": "Enable Firebase analytics",
|
||||
"core.settings.enablefirebaseanalyticsdescription": "If enabled, the app will collect anonymous data usage.",
|
||||
"core.settings.enablerichtexteditor": "Enable text editor",
|
||||
"core.settings.enablerichtexteditordescription": "If enabled, a text editor will be available when entering content.",
|
||||
"core.settings.enablesyncwifi": "Allow sync only when on Wi-Fi",
|
||||
"core.settings.entriesincache": "{{$a}} entries in cache",
|
||||
"core.settings.errordeletesitefiles": "Error deleting site files.",
|
||||
"core.settings.errorsyncsite": "Error synchronising site data. Please check your Internet connection and try again.",
|
||||
"core.settings.estimatedfreespace": "Estimated free space",
|
||||
"core.settings.filesystemroot": "File system root",
|
||||
"core.settings.fontsize": "Text size",
|
||||
"core.settings.fontsizecharacter": "A",
|
||||
"core.settings.forcedsetting": "This setting has been forced by your site configuration.",
|
||||
"core.settings.general": "General",
|
||||
"core.settings.language": "Language",
|
||||
"core.settings.license": "Licence",
|
||||
"core.settings.localnotifavailable": "Local notifications available",
|
||||
"core.settings.locationhref": "Web view URL",
|
||||
"core.settings.locked": "Locked",
|
||||
"core.settings.loggedin": "Online",
|
||||
"core.settings.loggedoff": "Offline",
|
||||
"core.settings.navigatorlanguage": "Navigator language",
|
||||
"core.settings.navigatoruseragent": "Navigator userAgent",
|
||||
"core.settings.networkstatus": "Internet connection status",
|
||||
"core.settings.opensourcelicenses": "Open Source Licences",
|
||||
"core.settings.preferences": "Preferences",
|
||||
"core.settings.privacypolicy": "Privacy policy",
|
||||
"core.settings.publisher": "Publisher",
|
||||
"core.settings.pushid": "Push notifications ID",
|
||||
"core.settings.reportinbackground": "Report errors automatically",
|
||||
"core.settings.screen": "Screen information",
|
||||
"core.settings.settings": "Settings",
|
||||
"core.settings.showdownloadoptions": "Show download options",
|
||||
"core.settings.siteinfo": "Site info",
|
||||
"core.settings.sites": "Sites",
|
||||
"core.settings.spaceusage": "Space usage",
|
||||
"core.settings.spaceusagehelp": "Deleting the stored information of the site will remove all the site offline data. This information allows you to use the app when offline. ",
|
||||
"core.settings.synchronization": "Synchronisation",
|
||||
"core.settings.synchronizenow": "Synchronise now",
|
||||
"core.settings.synchronizenowhelp": "Synchronising a site will send pending changes and all offline activity stored in the device and will synchronise some data like messages and notifications.",
|
||||
"core.settings.syncsettings": "Synchronisation settings",
|
||||
"core.settings.total": "Total",
|
||||
"core.settings.wificonnection": "Wi-Fi connection",
|
||||
"core.unknown": "Unknown",
|
||||
"core.yes": "Yes"
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
// Add here base app styles.
|
||||
|
||||
ion-toolbar ion-back-button,
|
||||
ion-toolbar .in-toolbar.button-clear {
|
||||
--color: var(--ion-color-primary-contrast);
|
||||
}
|
|
@ -134,3 +134,5 @@
|
|||
--background: var(--ion-background-color);
|
||||
}
|
||||
}
|
||||
|
||||
@import "app.scss";
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
|
||||
import { CoreSitesDemoSiteData } from '@/app/services/sites';
|
||||
import { CoreSitesDemoSiteData } from '@services/sites';
|
||||
|
||||
declare global {
|
||||
|
||||
|
|
Loading…
Reference in New Issue