Merge pull request #1924 from crazyserver/MOBILE-3035

Mobile 3035
main
Juan Leyva 2019-05-20 12:16:59 +02:00 committed by GitHub
commit 7a466aac22
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 115 additions and 27 deletions

View File

@ -1710,6 +1710,7 @@
"core.settings.privacypolicy": "local_moodlemobileapp", "core.settings.privacypolicy": "local_moodlemobileapp",
"core.settings.pushid": "local_moodlemobileapp", "core.settings.pushid": "local_moodlemobileapp",
"core.settings.reportinbackground": "local_moodlemobileapp", "core.settings.reportinbackground": "local_moodlemobileapp",
"core.settings.entriesincache": "local_moodlemobileapp",
"core.settings.settings": "moodle", "core.settings.settings": "moodle",
"core.settings.showdownloadoptions": "local_moodlemobileapp", "core.settings.showdownloadoptions": "local_moodlemobileapp",
"core.settings.sites": "moodle", "core.settings.sites": "moodle",

View File

@ -1680,7 +1680,7 @@
"core.settings.currentlanguage": "Current language", "core.settings.currentlanguage": "Current language",
"core.settings.debugdisplay": "Display debug messages", "core.settings.debugdisplay": "Display debug messages",
"core.settings.debugdisplaydescription": "If enabled, error modals will display more data about the error if possible.", "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 from the site '{{sitename}}'?", "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.deletesitefilestitle": "Delete site files",
"core.settings.deviceinfo": "Device info", "core.settings.deviceinfo": "Device info",
"core.settings.deviceos": "Device OS", "core.settings.deviceos": "Device OS",
@ -1692,6 +1692,7 @@
"core.settings.enablerichtexteditor": "Enable text editor", "core.settings.enablerichtexteditor": "Enable text editor",
"core.settings.enablerichtexteditordescription": "If enabled, a text editor will be available when entering content.", "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.enablesyncwifi": "Allow sync only when on Wi-Fi",
"core.settings.entriesincache": "{{$a}} entries in cache",
"core.settings.errordeletesitefiles": "Error deleting site files.", "core.settings.errordeletesitefiles": "Error deleting site files.",
"core.settings.errorsyncsite": "Error synchronising site data. Please check your Internet connection and try again.", "core.settings.errorsyncsite": "Error synchronising site data. Please check your Internet connection and try again.",
"core.settings.estimatedfreespace": "Estimated free space", "core.settings.estimatedfreespace": "Estimated free space",

View File

@ -5,14 +5,13 @@ ion-app.app-root core-ion-tabs {
z-index: 101; // For some reason, the regular z-index isn't enough with our tabs, use a higher one. z-index: 101; // For some reason, the regular z-index isn't enough with our tabs, use a higher one.
.core-ion-tabs-loading { .core-ion-tabs-loading {
height: 100%;
width: 100%; width: 100%;
display: table; display: flex;
align-items: center;
justify-content: center;
.core-ion-tabs-loading-spinner { .core-ion-tabs-loading-spinner {
display: table-cell;
text-align: center;
vertical-align: middle;
.spinner circle, .spinner line { .spinner circle, .spinner line {
stroke: $white; stroke: $white;
} }

View File

@ -1,4 +1,10 @@
ion-app.app-root page-core-mainmenu { ion-app.app-root page-core-mainmenu {
ion-icon {
text-overflow: unset;
overflow: visible;
text-align: center;
}
.ion-md-fa-graduation-cap, .ion-md-fa-graduation-cap,
.ion-ios-fa-graduation-cap, .ion-ios-fa-graduation-cap,
.ion-ios-fa-graduation-cap-outline, .ion-ios-fa-graduation-cap-outline,
@ -8,6 +14,7 @@ ion-app.app-root page-core-mainmenu {
@extend .fa; @extend .fa;
font-size: 21px; font-size: 21px;
height: 21px; height: 21px;
} }
.ion-ios-fa-graduation-cap-outline { .ion-ios-fa-graduation-cap-outline {

View File

@ -12,7 +12,7 @@
"currentlanguage": "Current language", "currentlanguage": "Current language",
"debugdisplay": "Display debug messages", "debugdisplay": "Display debug messages",
"debugdisplaydescription": "If enabled, error modals will display more data about the error if possible.", "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 from the site '{{sitename}}'?", "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", "deletesitefilestitle": "Delete site files",
"deviceinfo": "Device info", "deviceinfo": "Device info",
"deviceos": "Device OS", "deviceos": "Device OS",
@ -42,6 +42,7 @@
"privacypolicy": "Privacy policy", "privacypolicy": "Privacy policy",
"pushid": "Push notifications ID", "pushid": "Push notifications ID",
"reportinbackground": "Report errors automatically", "reportinbackground": "Report errors automatically",
"entriesincache": "{{$a}} entries in cache",
"settings": "Settings", "settings": "Settings",
"showdownloadoptions": "Show download options", "showdownloadoptions": "Show download options",
"sites": "Sites", "sites": "Sites",

View File

@ -9,16 +9,22 @@
</ion-refresher> </ion-refresher>
<core-loading [hideUntil]="usageLoaded"> <core-loading [hideUntil]="usageLoaded">
<ion-item *ngFor="let site of sites" [class.core-primary-selected-item]="site.id == currentSiteId"> <ion-item *ngFor="let site of sites" [class.core-primary-selected-item]="site.id == currentSiteId">
<h2><core-format-text [text]="site.siteName"></core-format-text></h2> <h2 text-wrap><core-format-text [text]="site.siteName"></core-format-text></h2>
<p>{{ site.fullName }}</p> <p text-wrap>{{ site.fullName }}</p>
<p item-end>{{ site.spaceUsage | coreBytesToSize }}</p> <div item-end>
<button ion-button icon-only clear color="danger" item-end (click)="deleteSiteFiles(site)" [hidden]="!site.spaceUsage > '0'" [attr.aria-label]="'core.settings.deletesitefilestitle' | translate"> <p>{{ site.spaceUsage | coreBytesToSize }}</p>
<p>{{ 'core.settings.entriesincache' | translate: { $a: site.cacheEntries } }}</p>
</div>
<button ion-button icon-only clear color="danger" item-end (click)="deleteSiteStorage(site)" [hidden]="!site.spaceUsage > '0' && !site.cacheEntries > '0'" [attr.aria-label]="'core.settings.deletesitefilestitle' | translate">
<ion-icon name="trash"></ion-icon> <ion-icon name="trash"></ion-icon>
</button> </button>
</ion-item> </ion-item>
<ion-item-divider> <ion-item-divider>
<p>{{ 'core.settings.total' | translate }}</p> <p>{{ 'core.settings.total' | translate }}</p>
<p item-end>{{ totalUsage | coreBytesToSize }}</p> <div item-end>
<p>{{ totalUsage | coreBytesToSize }}</p>
<p>{{ 'core.settings.entriesincache' | translate: { $a: totalEntries } }}</p>
</div>
</ion-item-divider> </ion-item-divider>
</core-loading> </core-loading>
</ion-content> </ion-content>

View File

@ -35,6 +35,7 @@ export class CoreSettingsSpaceUsagePage {
sites = []; sites = [];
currentSiteId = ''; currentSiteId = '';
totalUsage = 0; totalUsage = 0;
totalEntries = 0;
constructor(private filePoolProvider: CoreFilepoolProvider, constructor(private filePoolProvider: CoreFilepoolProvider,
private sitesProvider: CoreSitesProvider, private textUtils: CoreTextUtilsProvider, private sitesProvider: CoreSitesProvider, private textUtils: CoreTextUtilsProvider,
@ -63,9 +64,17 @@ export class CoreSettingsSpaceUsagePage {
// Get space usage. // Get space usage.
const promises = this.sites.map((siteEntry) => { const promises = this.sites.map((siteEntry) => {
return this.sitesProvider.getSite(siteEntry.id).then((site) => { return this.sitesProvider.getSite(siteEntry.id).then((site) => {
return site.getSpaceUsage().then((size) => { const proms2 = [];
proms2.push(this.calcSiteClearRows(site).then((rows) => {
siteEntry.cacheEntries = rows;
}));
proms2.push(site.getSpaceUsage().then((size) => {
siteEntry.spaceUsage = size; siteEntry.spaceUsage = size;
}); }));
return Promise.all(proms2);
}); });
}); });
@ -77,13 +86,14 @@ export class CoreSettingsSpaceUsagePage {
* Convenience function to calculate total usage. * Convenience function to calculate total usage.
*/ */
protected calculateTotalUsage(): void { protected calculateTotalUsage(): void {
let total = 0; let totalSize = 0,
totalEntries = 0;
this.sites.forEach((site) => { this.sites.forEach((site) => {
if (site.spaceUsage) { totalSize += (site.spaceUsage ? parseInt(site.spaceUsage, 10) : 0);
total += parseInt(site.spaceUsage, 10); totalEntries += (site.cacheEntries ? parseInt(site.cacheEntries, 10) : 0);
}
}); });
this.totalUsage = total; this.totalUsage = totalSize;
this.totalEntries = totalEntries;
} }
/** /**
@ -123,11 +133,33 @@ export class CoreSettingsSpaceUsagePage {
} }
/** /**
* Deletes files of a site. * Calculate the number of rows to be deleted on a site.
*
* @param {any} site Site object.
* @return {Promise<number>} If there are rows to delete or not.
*/
protected calcSiteClearRows(site: any): Promise<number> {
const clearTables = this.sitesProvider.getSiteTableSchemasToClear();
let totalEntries = 0;
const promises = clearTables.map((name) => {
return site.getDb().countRecords(name).then((rows) => {
totalEntries += rows;
});
});
return Promise.all(promises).then(() => {
return totalEntries;
});
}
/**
* Deletes files of a site and the tables that can be cleared.
* *
* @param {any} siteData Site object with space usage. * @param {any} siteData Site object with space usage.
*/ */
deleteSiteFiles(siteData: any): void { deleteSiteStorage(siteData: any): void {
this.textUtils.formatText(siteData.siteName).then((siteName) => { this.textUtils.formatText(siteData.siteName).then((siteName) => {
const title = this.translate.instant('core.settings.deletesitefilestitle'); const title = this.translate.instant('core.settings.deletesitefilestitle');
const message = this.translate.instant('core.settings.deletesitefiles', {sitename: siteName}); const message = this.translate.instant('core.settings.deletesitefiles', {sitename: siteName});
@ -135,7 +167,14 @@ export class CoreSettingsSpaceUsagePage {
this.domUtils.showConfirm(message, title).then(() => { this.domUtils.showConfirm(message, title).then(() => {
return this.sitesProvider.getSite(siteData.id); return this.sitesProvider.getSite(siteData.id);
}).then((site) => { }).then((site) => {
site.deleteFolder().then(() => {
// Clear cache tables.
const cleanSchemas = this.sitesProvider.getSiteTableSchemasToClear();
const promises = cleanSchemas.map((name) => {
return site.getDb().deleteRecords(name);
});
promises.push(site.deleteFolder().then(() => {
this.filePoolProvider.clearAllPackagesStatus(site.id); this.filePoolProvider.clearAllPackagesStatus(site.id);
this.filePoolProvider.clearFilepool(site.id); this.filePoolProvider.clearFilepool(site.id);
this.updateSiteUsage(siteData, 0); this.updateSiteUsage(siteData, 0);
@ -151,7 +190,13 @@ export class CoreSettingsSpaceUsagePage {
this.updateSiteUsage(siteData, size); this.updateSiteUsage(siteData, size);
}); });
} }
}).finally(() => {
this.calcSiteClearRows(site).then((rows) => {
siteData.cacheEntries = rows;
}); });
}));
return Promise.all(promises);
}).catch(() => { }).catch(() => {
// Ignore cancelled confirmation modal. // Ignore cancelled confirmation modal.
}); });

View File

@ -36,6 +36,7 @@ export class CoreUserProvider {
protected siteSchema: CoreSiteSchema = { protected siteSchema: CoreSiteSchema = {
name: 'CoreUserProvider', name: 'CoreUserProvider',
version: 1, version: 1,
canBeCleared: [ this.USERS_TABLE ],
tables: [ tables: [
{ {
name: this.USERS_TABLE, name: this.USERS_TABLE,
@ -53,7 +54,7 @@ export class CoreUserProvider {
name: 'profileimageurl', name: 'profileimageurl',
type: 'TEXT' type: 'TEXT'
} }
] ],
} }
] ]
}; };

View File

@ -306,7 +306,7 @@ export class CoreFilepoolProvider {
primaryKeys: ['siteId', 'fileId'] primaryKeys: ['siteId', 'fileId']
} }
]; ];
protected siteSchma: CoreSiteSchema = { protected siteSchema: CoreSiteSchema = {
name: 'CoreFilepoolProvider', name: 'CoreFilepoolProvider',
version: 1, version: 1,
tables: [ tables: [
@ -447,7 +447,7 @@ export class CoreFilepoolProvider {
this.appDB = this.appProvider.getDB(); this.appDB = this.appProvider.getDB();
this.appDB.createTablesFromSchema(this.appTablesSchema); this.appDB.createTablesFromSchema(this.appTablesSchema);
this.sitesProvider.registerSiteSchema(this.siteSchma); this.sitesProvider.registerSiteSchema(this.siteSchema);
initDelegate.ready().then(() => { initDelegate.ready().then(() => {
// Waiting for the app to be ready to start processing the queue. // Waiting for the app to be ready to start processing the queue.
@ -857,7 +857,10 @@ export class CoreFilepoolProvider {
*/ */
clearFilepool(siteId: string): Promise<any> { clearFilepool(siteId: string): Promise<any> {
return this.sitesProvider.getSiteDb(siteId).then((db) => { return this.sitesProvider.getSiteDb(siteId).then((db) => {
return db.deleteRecords(this.FILES_TABLE); return Promise.all([
db.deleteRecords(this.FILES_TABLE),
db.deleteRecords(this.LINKS_TABLE)
]);
}); });
} }

View File

@ -145,6 +145,13 @@ export interface CoreSiteSchema {
*/ */
version: number; version: number;
/**
* Names of the tables of the site schema that can be cleared.
*
* @type {string[]}
*/
canBeCleared?: string[];
/** /**
* Tables to create when installing or upgrading the schema. * Tables to create when installing or upgrading the schema.
*/ */
@ -270,6 +277,7 @@ export class CoreSitesProvider {
protected siteSchema: CoreSiteSchema = { protected siteSchema: CoreSiteSchema = {
name: 'CoreSitesProvider', name: 'CoreSitesProvider',
version: 1, version: 1,
canBeCleared: [ CoreSite.WS_CACHE_TABLE ],
tables: [ tables: [
{ {
name: CoreSite.WS_CACHE_TABLE, name: CoreSite.WS_CACHE_TABLE,
@ -1521,4 +1529,20 @@ export class CoreSitesProvider {
return result; return result;
}); });
} }
/**
* Returns the Site Schema names that can be cleared on space storage.
*
* @return {string[]} Name of the site schemas.
*/
getSiteTableSchemasToClear(): string[] {
let reset = [];
for (const name in this.siteSchemas) {
if (this.siteSchemas[name].canBeCleared) {
reset = reset.concat(this.siteSchemas[name].canBeCleared);
}
}
return reset;
}
} }