MOBILE-3565 settings: Add site preferences

main
Pau Ferrer Ocaña 2020-11-12 09:43:34 +01:00
parent d6a42f992b
commit adf5de823f
6 changed files with 354 additions and 4 deletions

View File

@ -70,7 +70,8 @@
<h2>{{ 'core.mainmenu.help' | translate }}</h2> <h2>{{ 'core.mainmenu.help' | translate }}</h2>
</ion-label> </ion-label>
</ion-item> </ion-item>
<ion-item button (click)="openSitePreferences()" title="{{ 'core.settings.preferences' | translate }}" detail> <ion-item button router-direction="forward" routerLink="preferences"
title="{{ 'core.settings.preferences' | translate }}" detail>
<ion-icon name="fa-wrench" slot="start"></ion-icon> <ion-icon name="fa-wrench" slot="start"></ion-icon>
<ion-label> <ion-label>
<h2>{{ 'core.settings.preferences' | translate }}</h2> <h2>{{ 'core.settings.preferences' | translate }}</h2>

View File

@ -0,0 +1,80 @@
<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.preferences' | translate}}</ion-title>
<ion-buttons slot="end">
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-refresher slot="fixed" [disabled]="!loaded" (ionRefresh)="refreshData($event)">
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
</ion-refresher>
<core-loading [hideUntil]="loaded">
<ion-list>
<ion-item *ngIf="siteInfo" class="ion-text-wrap">
<ion-label>
<h2>{{siteInfo!.fullname}}</h2>
<p>
<core-format-text [text]="siteName" contextLevel="system" [contextInstanceId]="0"
[wsNotFiltered]="true"></core-format-text>
</p>
<p>{{ siteUrl }}</p>
</ion-label>
</ion-item>
<ion-item-divider></ion-item-divider>
<ion-item *ngIf="isIOS"
(click)="openHandler('CoreSharedFilesListPage', {manage: true, siteId: siteId, hideSitePicker: true})"
[title]="'core.sharedfiles.sharedfiles' | translate"
[class.core-split-item-selected]="'CoreSharedFilesListPage' == selectedPage" details>
<ion-icon name="fas-folder" slot="start"></ion-icon>
<ion-label>
<h2>{{ 'core.sharedfiles.sharedfiles' | translate }}</h2>
</ion-label>
<ion-badge slot="end">{{ iosSharedFiles }}</ion-badge>
</ion-item>
<ion-item *ngFor="let handler of handlers" [ngClass]="['core-settings-handler', handler.class]"
(click)="openHandler(handler.page, handler.params)" [title]="handler.title | translate" details
[class.core-split-item-selected]="handler.page == selectedPage">
<ion-icon [name]="handler.icon" slot="start" *ngIf="handler.icon">
</ion-icon>
<ion-label>
<h2>{{ handler.title | translate}}</h2>
</ion-label>
</ion-item>
<ion-card>
<ion-item class="ion-text-wrap" *ngIf="spaceUsage">
<ion-label>
<h2 class="ion-text-wrap">{{ 'core.settings.spaceusage' | translate }} <ion-icon
name="fas-info-circle" color="secondary" [attr.aria-label]="'core.info' | translate"
(click)="showSpaceInfo()"></ion-icon>
</h2>
<p *ngIf="spaceUsage.spaceUsage">{{ spaceUsage.spaceUsage | coreBytesToSize }}</p>
</ion-label>
<ion-button fill="clear" color="danger" slot="end" (click)="deleteSiteStorage()"
[hidden]="spaceUsage.spaceUsage! + spaceUsage.cacheEntries! <= 0"
[attr.aria-label]="'core.settings.deletesitefilestitle' | translate">
<ion-icon name="fas-trash" slot="icon-only"></ion-icon>
</ion-button>
</ion-item>
<ion-item class="ion-text-wrap">
<ion-label>
<h2>{{ 'core.settings.synchronizenow' | translate }} <ion-icon name="fas-info-circle"
color="secondary" [attr.aria-label]="'core.info' | translate" (click)="showSyncInfo()">
</ion-icon>
</h2>
</ion-label>
<ion-button fill="clear" slot="end" *ngIf="!isSynchronizing()" (click)="synchronize()"
[title]="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()"></ion-spinner>
</ion-item>
</ion-card>
</ion-list>
</core-loading>
</ion-content>

View File

@ -0,0 +1,48 @@
// (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 { CorePipesModule } from '@pipes/pipes.module';
import { CoreSitePreferencesPage } from './site.page';
const routes: Routes = [
{
path: '',
component: CoreSitePreferencesPage,
},
];
@NgModule({
declarations: [
CoreSitePreferencesPage,
],
imports: [
RouterModule.forChild(routes),
CommonModule,
IonicModule,
TranslateModule.forChild(),
CoreComponentsModule,
CoreDirectivesModule,
CorePipesModule,
],
})
export class CoreSitePreferencesPageModule {}

View File

@ -0,0 +1,217 @@
// (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 { ActivatedRoute, Params, Router } from '@angular/router';
import { IonRefresher } from '@ionic/angular';
import { CoreSettingsDelegate, CoreSettingsHandlerData } from '../../services/settings.delegate';
import { CoreEventObserver, CoreEvents, CoreEventSiteUpdatedData } from '@singletons/events';
import { CoreSites } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom';
// import { CoreSplitViewComponent } from '@components/split-view/split-view';
// import { CoreSharedFiles } from '@core/sharedfiles/providers/sharedfiles';
import { CoreSettingsHelper, CoreSiteSpaceUsage } from '../../services/settings.helper';
import { CoreApp } from '@services/app';
import { CoreSiteInfo } from '@classes/site';
import { Translate } from '@singletons/core.singletons';
/**
* Page that displays the list of site settings pages.
*/
@Component({
selector: 'page-core-site-preferences',
templateUrl: 'site.html',
})
export class CoreSitePreferencesPage implements OnInit, OnDestroy {
// @ViewChild(CoreSplitViewComponent) splitviewCtrl?: CoreSplitViewComponent;
isIOS: boolean;
selectedPage?: string;
handlers: CoreSettingsHandlerData[] = [];
siteId: string;
siteInfo?: CoreSiteInfo;
siteName?: string;
siteUrl?: string;
spaceUsage: CoreSiteSpaceUsage = {
cacheEntries: 0,
spaceUsage: 0,
};
loaded = false;
iosSharedFiles = 0;
protected sitesObserver: CoreEventObserver;
protected isDestroyed = false;
constructor(
protected settingsDelegate: CoreSettingsDelegate,
protected route: ActivatedRoute,
protected router: Router, // Will be removed when splitview is implemented
) {
this.isIOS = CoreApp.instance.isIOS();
this.siteId = CoreSites.instance.getCurrentSiteId();
this.selectedPage = route.snapshot.paramMap.get('page') || undefined;
this.sitesObserver = CoreEvents.on(CoreEvents.SITE_UPDATED, (data: CoreEventSiteUpdatedData) => {
if (data.siteId == this.siteId) {
this.refreshData();
}
});
}
/**
* View loaded.
*/
ngOnInit(): void {
this.fetchData().finally(() => {
this.loaded = true;
if (this.selectedPage) {
this.openHandler(this.selectedPage);
} /* else if (this.splitviewCtrl.isOn()) {
if (this.isIOS) {
this.openHandler('CoreSharedFilesListPage', { manage: true, siteId: this.siteId, hideSitePicker: true });
} else if (this.handlers.length > 0) {
this.openHandler(this.handlers[0].page, this.handlers[0].params);
}
}*/
});
}
/**
* Fetch Data.
*/
protected async fetchData(): Promise<void> {
this.handlers = this.settingsDelegate.getHandlers();
const currentSite = CoreSites.instance.getCurrentSite();
this.siteInfo = currentSite!.getInfo();
this.siteName = currentSite!.getSiteName();
this.siteUrl = currentSite!.getURL();
const promises: Promise<void>[] = [];
promises.push(CoreSettingsHelper.instance.getSiteSpaceUsage(this.siteId)
.then((spaceUsage) => {
this.spaceUsage = spaceUsage;
return;
}));
/* if (this.isIOS) {
promises.push(CoreSharedFiles.instance.getSiteSharedFiles(this.siteId)
.then((files) => {
this.iosSharedFiles = files.length;
return;
}));
}*/
await Promise.all(promises);
}
/**
* Syncrhonizes the site.
*/
async synchronize(): Promise<void> {
try {
// Using syncOnlyOnWifi false to force manual sync.
await CoreSettingsHelper.instance.synchronizeSite(false, this.siteId);
} catch (error) {
if (this.isDestroyed) {
return;
}
CoreDomUtils.instance.showErrorModalDefault(error, 'core.settings.errorsyncsite', true);
}
}
/**
* Returns true if site is beeing synchronized.
*
* @return True if site is beeing synchronized, false otherwise.
*/
isSynchronizing(): boolean {
return !!CoreSettingsHelper.instance.getSiteSyncPromise(this.siteId);
}
/**
* Refresh the data.
*
* @param refresher Refresher.
*/
refreshData(refresher?: CustomEvent<IonRefresher>): void {
this.fetchData().finally(() => {
refresher?.detail.complete();
});
}
/**
* Deletes files of a site and the tables that can be cleared.
*
* @param siteData Site object with space usage.
*/
async deleteSiteStorage(): Promise<void> {
try {
this.spaceUsage = await CoreSettingsHelper.instance.deleteSiteStorage(this.siteName || '', this.siteId);
} catch {
// Ignore cancelled confirmation modal.
}
}
/**
* Open a handler.
*
* @param page Page to open.
* @param params Params of the page to open.
*/
openHandler(page: string, params?: Params): void {
this.selectedPage = page;
// this.splitviewCtrl.push(page, params);
this.router.navigate([page], { relativeTo: this.route, queryParams: params });
}
/**
* Show information about space usage actions.
*/
showSpaceInfo(): void {
CoreDomUtils.instance.showAlert(
Translate.instance.instant('core.help'),
Translate.instance.instant('core.settings.spaceusagehelp'),
);
}
/**
* Show information about sync actions.
*/
showSyncInfo(): 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

@ -23,6 +23,10 @@ const routes: Routes = [
path: 'settings', path: 'settings',
loadChildren: () => import('@core/settings/settings.module').then(m => m.CoreSettingsModule), loadChildren: () => import('@core/settings/settings.module').then(m => m.CoreSettingsModule),
}, },
{
path: 'preferences',
loadChildren: () => import('@core/settings/pages/site/site.page.module').then(m => m.CoreSitePreferencesPageModule),
},
]; ];
@NgModule({ @NgModule({