MOBILE-3565 settings: Add sync page
parent
d5e95ccd89
commit
a19a25dc51
|
@ -19,7 +19,7 @@
|
|||
<ion-label>{{ 'core.settings.spaceusage' | translate }}</ion-label>
|
||||
</ion-item>
|
||||
<ion-item button (click)="openSettings('sync')" [class.core-split-item-selected]="'sync' == selectedPage" detail>
|
||||
<ion-icon name="fa-sync" slot="start"></ion-icon>
|
||||
<ion-icon name="fa-sync-alt" slot="start"></ion-icon>
|
||||
<ion-label>{{ 'core.settings.synchronization' | translate }}</ion-label>
|
||||
</ion-item>
|
||||
<ion-item button *ngIf="isIOS" (click)="openSettings('sharedfiles', {manage: true})"
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
<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.synchronization' | translate }}</ion-title>
|
||||
<ion-buttons slot="end">
|
||||
<!-- @todo <core-navbar-buttons></core-navbar-buttons>-->
|
||||
<ion-button (click)="showInfo()" [attr.aria-label]="'core.info' | translate">
|
||||
<ion-icon name="fas-info-circle" slot="icon-only"></ion-icon>
|
||||
</ion-button>
|
||||
</ion-buttons>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
<core-loading [hideUntil]="sitesLoaded">
|
||||
<ion-item-divider>
|
||||
<ion-label>
|
||||
<h2>{{ 'core.settings.syncsettings' | translate }}</h2>
|
||||
</ion-label>
|
||||
</ion-item-divider>
|
||||
<ion-item class="ion-text-wrap">
|
||||
<ion-label>{{ 'core.settings.enablesyncwifi' | translate }}</ion-label>
|
||||
<ion-toggle slot="end" [(ngModel)]="syncOnlyOnWifi" (ngModelChange)="syncOnlyOnWifiChanged()">
|
||||
</ion-toggle>
|
||||
</ion-item>
|
||||
<ion-item-divider>
|
||||
<ion-label>
|
||||
<h2>{{ 'core.settings.sites' | translate }}</h2>
|
||||
</ion-label>
|
||||
</ion-item-divider>
|
||||
<ion-item *ngFor="let site of sites" [class.core-selected-item]="site.id == currentSiteId" class="ion-text-wrap">
|
||||
<ion-label>
|
||||
<h2>
|
||||
<core-format-text [text]="site.siteName" clean="true" [siteId]="site.id"></core-format-text>
|
||||
</h2>
|
||||
<p>{{ site.fullName }}</p>
|
||||
<p>{{ site.siteUrl }}</p>
|
||||
</ion-label>
|
||||
<ion-button fill="clear" slot="end" *ngIf="!isSynchronizing(site.id)" (click)="synchronize(site.id)"
|
||||
[title]="site.siteName" [attr.aria-label]="'core.settings.synchronizenow' | translate">
|
||||
<ion-icon name="fas-sync-alt" slot="icon-only"></ion-icon>
|
||||
</ion-button>
|
||||
<ion-spinner slot="end" *ngIf="isSynchronizing(site.id)"></ion-spinner>
|
||||
</ion-item>
|
||||
</core-loading>
|
||||
</ion-content>
|
|
@ -0,0 +1,50 @@
|
|||
// (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 { TranslateModule } from '@ngx-translate/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { IonicModule } from '@ionic/angular';
|
||||
|
||||
import { CoreComponentsModule } from '@components/components.module';
|
||||
import { CoreDirectivesModule } from '@directives/directives.module';
|
||||
|
||||
import { CoreSettingsSynchronizationPage } from './synchronization.page';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: CoreSettingsSynchronizationPage,
|
||||
},
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
RouterModule.forChild(routes),
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
FormsModule,
|
||||
TranslateModule.forChild(),
|
||||
CoreComponentsModule,
|
||||
CoreDirectivesModule,
|
||||
],
|
||||
declarations: [
|
||||
CoreSettingsSynchronizationPage,
|
||||
],
|
||||
exports: [RouterModule],
|
||||
})
|
||||
export class CoreSettingsSynchronizationPageModule {}
|
|
@ -0,0 +1,130 @@
|
|||
// (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 { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
|
||||
import { CoreConstants } from '@core/constants';
|
||||
import { CoreEventObserver, CoreEvents, CoreEventSiteUpdatedData } from '@singletons/events';
|
||||
import { CoreSites, CoreSiteBasicInfo } from '@services/sites';
|
||||
import { CoreDomUtils } from '@services/utils/dom';
|
||||
import { CoreConfig } from '@services/config';
|
||||
import { CoreSettingsHelper } from '@core/settings/services/settings.helper';
|
||||
import { Translate } from '@singletons/core.singletons';
|
||||
|
||||
/**
|
||||
* Page that displays the synchronization settings.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'page-core-app-settings-synchronization',
|
||||
templateUrl: 'synchronization.html',
|
||||
})
|
||||
export class CoreSettingsSynchronizationPage implements OnInit, OnDestroy {
|
||||
|
||||
sites: CoreSiteBasicInfo[] = [];
|
||||
sitesLoaded = false;
|
||||
currentSiteId = '';
|
||||
syncOnlyOnWifi = false;
|
||||
protected isDestroyed = false;
|
||||
protected sitesObserver: CoreEventObserver;
|
||||
|
||||
constructor() {
|
||||
|
||||
this.currentSiteId = CoreSites.instance.getCurrentSiteId();
|
||||
|
||||
this.sitesObserver = CoreEvents.on(CoreEvents.SITE_UPDATED, async (data: CoreEventSiteUpdatedData) => {
|
||||
const site = await CoreSites.instance.getSite(data.siteId);
|
||||
|
||||
const siteEntry = this.sites.find((siteEntry) => siteEntry.id == site.id);
|
||||
if (siteEntry) {
|
||||
const siteInfo = site.getInfo();
|
||||
|
||||
siteEntry.siteName = site.getSiteName();
|
||||
|
||||
if (siteInfo) {
|
||||
siteEntry.siteUrl = siteInfo.siteurl;
|
||||
siteEntry.fullName = siteInfo.fullname;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* View loaded.
|
||||
*/
|
||||
async ngOnInit(): Promise<void> {
|
||||
try {
|
||||
this.sites = await CoreSites.instance.getSortedSites();
|
||||
} catch {
|
||||
// Ignore errors.
|
||||
}
|
||||
|
||||
this.sitesLoaded = true;
|
||||
|
||||
this.syncOnlyOnWifi = await CoreConfig.instance.get(CoreConstants.SETTINGS_SYNC_ONLY_ON_WIFI, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when sync only on wifi setting is enabled or disabled.
|
||||
*/
|
||||
syncOnlyOnWifiChanged(): void {
|
||||
CoreConfig.instance.set(CoreConstants.SETTINGS_SYNC_ONLY_ON_WIFI, this.syncOnlyOnWifi ? 1 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Syncrhonizes a site.
|
||||
*
|
||||
* @param siteId Site ID.
|
||||
*/
|
||||
async synchronize(siteId: string): Promise<void> {
|
||||
// Using syncOnlyOnWifi false to force manual sync.
|
||||
try {
|
||||
await CoreSettingsHelper.instance.synchronizeSite(false, siteId);
|
||||
} catch (error) {
|
||||
if (this.isDestroyed) {
|
||||
return;
|
||||
}
|
||||
|
||||
CoreDomUtils.instance.showErrorModalDefault(error, 'core.settings.errorsyncsite', true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if site is beeing synchronized.
|
||||
*
|
||||
* @param siteId Site ID.
|
||||
* @return True if site is beeing synchronized, false otherwise.
|
||||
*/
|
||||
isSynchronizing(siteId: string): boolean {
|
||||
return !!CoreSettingsHelper.instance.getSiteSyncPromise(siteId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show information about sync actions.
|
||||
*/
|
||||
showInfo(): void {
|
||||
CoreDomUtils.instance.showAlert(
|
||||
Translate.instance.instant('core.help'),
|
||||
Translate.instance.instant('core.settings.synchronizenowhelp'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Page destroyed.
|
||||
*/
|
||||
ngOnDestroy(): void {
|
||||
this.isDestroyed = true;
|
||||
this.sitesObserver?.off();
|
||||
}
|
||||
|
||||
}
|
|
@ -257,7 +257,7 @@ export class CoreSettingsHelperProvider {
|
|||
* @param siteId ID of the site.
|
||||
* @return Sync promise or null if site is not being syncrhonized.
|
||||
*/
|
||||
async getSiteSyncPromise(siteId: string): Promise<void> {
|
||||
getSiteSyncPromise(siteId: string): Promise<void> | void {
|
||||
if (this.syncPromises[siteId]) {
|
||||
return this.syncPromises[siteId];
|
||||
}
|
||||
|
|
|
@ -30,6 +30,12 @@ const routes: Routes = [
|
|||
import('@core/settings/pages/space-usage/space-usage.page.module')
|
||||
.then(m => m.CoreSettingsSpaceUsagePageModule),
|
||||
},
|
||||
{
|
||||
path: 'sync',
|
||||
loadChildren: () =>
|
||||
import('@core/settings/pages/synchronization/synchronization.page.module')
|
||||
.then(m => m.CoreSettingsSynchronizationPageModule),
|
||||
},
|
||||
{
|
||||
path: '',
|
||||
loadChildren: () => import('./pages/app/app.page.module').then( m => m.CoreSettingsAppPageModule),
|
||||
|
|
|
@ -131,6 +131,10 @@
|
|||
}
|
||||
}
|
||||
|
||||
ion-spinner {
|
||||
--color: var(--core-color);
|
||||
}
|
||||
|
||||
--selected-item-color: var(--custom-selected-item-color, var(--core-color));
|
||||
--selected-item-border-width: var(--custom-selected-item-border-width, 5px);
|
||||
|
||||
|
|
Loading…
Reference in New Issue