diff --git a/src/addon/storagemanager/pages/course-storage/course-storage.ts b/src/addon/storagemanager/pages/course-storage/course-storage.ts index 6bdeecc52..9e38df36c 100644 --- a/src/addon/storagemanager/pages/course-storage/course-storage.ts +++ b/src/addon/storagemanager/pages/course-storage/course-storage.ts @@ -20,6 +20,7 @@ import { CoreCourseHelperProvider } from '@core/course/providers/helper'; import { CoreDomUtilsProvider } from '@providers/utils/dom'; import { TranslateService } from '@ngx-translate/core'; import { CoreConstants } from '@core/constants'; +import { CoreSitesProvider } from '@providers/sites'; /** * Page that displays the amount of file storage used by each activity on the course, and allows @@ -39,6 +40,7 @@ export class AddonStorageManagerCourseStoragePage { totalSize: number; constructor(navParams: NavParams, + private sitesProvider: CoreSitesProvider, private courseProvider: CoreCourseProvider, private prefetchDelegate: CoreCourseModulePrefetchDelegate, private courseHelperProvider: CoreCourseHelperProvider, @@ -70,7 +72,7 @@ export class AddonStorageManagerCourseStoragePage { // But these aren't necessarily consistent, for example mod_frog vs mmaModFrog. // There is nothing enforcing correct values. // Most modules which have large files are downloadable, so I think this is sufficient. - const promise = this.prefetchDelegate.getModuleDownloadedSize(module, this.course.id). + const promise = this.prefetchDelegate.getModuleTotalSize(module, this.course.id). then((size) => { // There are some cases where the return from this is not a valid number. if (!isNaN(size)) { @@ -185,7 +187,13 @@ export class AddonStorageManagerCourseStoragePage { modules.forEach((module) => { // Remove the files. const promise = this.prefetchDelegate.removeModuleFiles(module, this.course.id).then(() => { - // When the files are removed, update the size. + const handler = this.prefetchDelegate.getPrefetchHandlerFor(module); + if (handler) { + + return this.sitesProvider.getCurrentSite().deleteComponentFromCache(handler.component, module.id); + } + }).then(() => { + // When the files and cache are removed, update the size. module.parentSection.totalSize -= module.totalSize; this.totalSize -= module.totalSize; module.totalSize = 0; diff --git a/src/classes/site.ts b/src/classes/site.ts index c24685ef3..77f7e994f 100644 --- a/src/classes/site.ts +++ b/src/classes/site.ts @@ -1100,6 +1100,25 @@ export class CoreSite { }); } + /** + * Gets the size of cached data for a specific component or component instance. + * + * @param component Component name + * @param componentId Optional component id (if not included, returns sum for whole component) + * @return Promise resolved when we have calculated the size + */ + getComponentCacheSize(component: string, componentId?: string): Promise { + const params = [component]; + let extraClause = ''; + if (componentId) { + params.push(componentId); + extraClause = ' AND componentId = ?'; + } + + return this.db.getFieldSql('SELECT SUM(length(data)) FROM ' + CoreSite.WS_CACHE_TABLE + + ' WHERE component = ?' + extraClause, params); + } + /** * Save a WS response to cache. * @@ -1173,6 +1192,29 @@ export class CoreSite { return this.db.deleteRecords(CoreSite.WS_CACHE_TABLE, { id: id }); } + /** + * Deletes WS cache entries for all methods relating to a specific component (and + * optionally component id). + * + * @param component Component name. + * @param componentId Component id. + * @return Promise resolved when the entries are deleted. + */ + deleteComponentFromCache(component: string, componentId?: string): Promise { + if (!this.db) { + return Promise.reject(null); + } + + const params = { + component: component + } as any; + if (componentId) { + params.componentId = componentId; + } + + return this.db.deleteRecords(CoreSite.WS_CACHE_TABLE, params); + } + /* * Uploads a file using Cordova File API. * diff --git a/src/core/course/providers/helper.ts b/src/core/course/providers/helper.ts index 1ba933eac..870bced3c 100644 --- a/src/core/course/providers/helper.ts +++ b/src/core/course/providers/helper.ts @@ -425,6 +425,11 @@ export class CoreCourseHelperProvider { await this.prefetchDelegate.removeModuleFiles(module, courseId); + const handler = this.prefetchDelegate.getPrefetchHandlerFor(module); + if (handler) { + await this.sitesProvider.getCurrentSite().deleteComponentFromCache(handler.component, String(module.id)); + } + done && done(); } catch (error) { @@ -1131,7 +1136,7 @@ export class CoreCourseHelperProvider { this.prefetchDelegate.invalidateModuleStatusCache(module); } - promises.push(this.prefetchDelegate.getModuleDownloadedSize(module, courseId).then((moduleSize) => { + promises.push(this.prefetchDelegate.getModuleTotalSize(module, courseId).then((moduleSize) => { moduleInfo.size = moduleSize; moduleInfo.sizeReadable = this.textUtils.bytesToSize(moduleSize, 2); })); diff --git a/src/core/course/providers/module-prefetch-delegate.ts b/src/core/course/providers/module-prefetch-delegate.ts index 917a7bc4f..a42d080c5 100644 --- a/src/core/course/providers/module-prefetch-delegate.ts +++ b/src/core/course/providers/module-prefetch-delegate.ts @@ -690,6 +690,36 @@ export class CoreCourseModulePrefetchDelegate extends CoreDelegate { return Promise.resolve(0); } + /** + * Gets the estimated total size of data stored for a module. This includes + * the files downloaded for it (getModuleDownloadedSize) and also the total + * size of web service requests stored for it. + * + * @param module Module to get the size. + * @param courseId Course ID the module belongs to. + * @return Promise resolved with the total size (0 if unknown) + */ + getModuleTotalSize(module: any, courseId: number): Promise { + return this.getModuleDownloadedSize(module, courseId).then((downloadedSize) => { + if (isNaN(downloadedSize)) { + downloadedSize = 0; + } + const handler = this.getPrefetchHandlerFor(module); + if (handler) { + const site = this.sitesProvider.getCurrentSite(); + + return site.getComponentCacheSize(handler.component, module.id).then((cachedSize) => { + return cachedSize + downloadedSize; + }); + } else { + // If there is no handler then we can't find out the component name. + // So we can't work out the cached size, so just return downloaded size. + + return downloadedSize; + } + }); + } + /** * Get module files. *