MOBILE-3565 settings: Add sync page

main
Pau Ferrer Ocaña 2020-11-12 09:44:44 +01:00
parent d5e95ccd89
commit a19a25dc51
7 changed files with 239 additions and 2 deletions

View File

@ -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})"

View File

@ -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>

View File

@ -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 {}

View File

@ -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();
}
}

View File

@ -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];
}

View File

@ -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),

View File

@ -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);