MOBILE-2340 folder: Add link, prefetch and plugin handlers

main
Pau Ferrer Ocaña 2018-03-05 18:01:25 +01:00
parent 14ccd74b3a
commit 6cdb32d30d
15 changed files with 204 additions and 25 deletions

View File

@ -15,6 +15,7 @@
import { Injectable } from '@angular/core';
import { CoreContentLinksModuleIndexHandler } from '@core/contentlinks/classes/module-index-handler';
import { CoreCourseHelperProvider } from '@core/course/providers/helper';
import { AddonModBookProvider } from './book';
/**
* Handler to treat links to book.
@ -24,6 +25,6 @@ export class AddonModBookLinkHandler extends CoreContentLinksModuleIndexHandler
name = 'AddonModBookLinkHandler';
constructor(courseHelper: CoreCourseHelperProvider) {
super(courseHelper, 'mmaModBook', 'book');
super(courseHelper, AddonModBookProvider.COMPONENT, 'book');
}
}

View File

@ -17,7 +17,6 @@ import { CommonModule } from '@angular/common';
import { IonicModule } from 'ionic-angular';
import { TranslateModule } from '@ngx-translate/core';
import { CoreComponentsModule } from '@components/components.module';
import { CoreDirectivesModule } from '@directives';
import { CoreCourseComponentsModule } from '@core/course/components/components.module';
import { AddonModFolderIndexComponent } from './index/index';
@ -30,7 +29,6 @@ import { AddonModFolderIndexComponent } from './index/index';
IonicModule,
TranslateModule.forChild(),
CoreComponentsModule,
CoreDirectivesModule,
CoreCourseComponentsModule
],
providers: [

View File

@ -0,0 +1,6 @@
addon-mod-folder-index {
.item-media > img:first-child {
width: 24px;
height: 24px;
}
}

View File

@ -12,8 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { Component, OnInit, OnDestroy, Input, Output, EventEmitter, Optional } from '@angular/core';
import { NavParams, NavController, Content } from 'ionic-angular';
import { Component, OnInit, OnDestroy, Input, Output, EventEmitter } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { CoreAppProvider } from '@providers/app';
import { CoreDomUtilsProvider } from '@providers/utils/dom';
@ -27,7 +26,7 @@ import { AddonModFolderHelperProvider } from '../../providers/helper';
/**
* Component that displays a folder.
* @todo Adding a new file in a folder updates the revision of all the files, so they're all shown as outdated.
* To ignore revision in folders we'll have to modify $mmCoursePrefetchDelegate, core-file and $mmFilepool.
* To ignore revision in folders we'll have to modify CoreCourseModulePrefetchDelegate, core-file and CoreFilepoolProvider.
*/
@Component({
selector: 'addon-mod-folder-index',
@ -60,7 +59,7 @@ export class AddonModFolderIndexComponent implements OnInit, OnDestroy, CoreCour
constructor(private folderProvider: AddonModFolderProvider, private courseProvider: CoreCourseProvider,
private domUtils: CoreDomUtilsProvider, private appProvider: CoreAppProvider, private textUtils: CoreTextUtilsProvider,
private courseHelper: CoreCourseHelperProvider, private translate: TranslateService,
@Optional() private content: Content, private folderHelper: AddonModFolderHelperProvider) {
private folderHelper: AddonModFolderHelperProvider) {
this.folderRetrieved = new EventEmitter();
}
@ -107,7 +106,7 @@ export class AddonModFolderIndexComponent implements OnInit, OnDestroy, CoreCour
if (this.canReload) {
this.refreshIcon = 'spinner';
return this.folderProvider.invalidateContent(this.module.id, this.courseId).catch(() => {
this.folderProvider.invalidateContent(this.module.id, this.courseId).catch(() => {
// Ignore errors.
}).then(() => {
return this.fetchContent(true);
@ -117,6 +116,8 @@ export class AddonModFolderIndexComponent implements OnInit, OnDestroy, CoreCour
done && done();
});
}
return Promise.resolve();
}
/**

View File

@ -18,6 +18,12 @@ import { AddonModFolderHelperProvider } from './providers/helper';
import { AddonModFolderModuleHandler } from './providers/module-handler';
import { CoreCourseModuleDelegate } from '@core/course/providers/module-delegate';
import { AddonModFolderComponentsModule } from './components/components.module';
import { AddonModFolderPrefetchHandler } from './providers/prefetch-handler';
import { AddonModFolderLinkHandler } from './providers/link-handler';
import { AddonModFolderPluginFileHandler } from './providers/pluginfile-handler';
import { CoreContentLinksDelegate } from '@core/contentlinks/providers/delegate';
import { CoreCourseModulePrefetchDelegate } from '@core/course/providers/module-prefetch-delegate';
import { CorePluginFileDelegate } from '@providers/plugin-file-delegate';
@NgModule({
declarations: [
@ -28,11 +34,20 @@ import { AddonModFolderComponentsModule } from './components/components.module';
providers: [
AddonModFolderProvider,
AddonModFolderHelperProvider,
AddonModFolderModuleHandler
AddonModFolderModuleHandler,
AddonModFolderPrefetchHandler,
AddonModFolderLinkHandler,
AddonModFolderPluginFileHandler
]
})
export class AddonModFolderModule {
constructor(moduleDelegate: CoreCourseModuleDelegate, moduleHandler: AddonModFolderModuleHandler) {
constructor(moduleDelegate: CoreCourseModuleDelegate, moduleHandler: AddonModFolderModuleHandler,
prefetchDelegate: CoreCourseModulePrefetchDelegate, prefetchHandler: AddonModFolderPrefetchHandler,
contentLinksDelegate: CoreContentLinksDelegate, linkHandler: AddonModFolderLinkHandler,
pluginfileDelegate: CorePluginFileDelegate, pluginfileHandler: AddonModFolderPluginFileHandler) {
moduleDelegate.registerHandler(moduleHandler);
prefetchDelegate.registerHandler(prefetchHandler);
contentLinksDelegate.registerHandler(linkHandler);
pluginfileDelegate.registerHandler(pluginfileHandler);
}
}

View File

@ -1,4 +1,3 @@
{
"emptyfilelist": "There are no files to show.",
"errorwhilegettingfolder": "Error while getting folder data."
"emptyfilelist": "There are no files to show."
}

View File

@ -15,7 +15,7 @@
import { NgModule } from '@angular/core';
import { IonicPageModule } from 'ionic-angular';
import { TranslateModule } from '@ngx-translate/core';
import { CoreDirectivesModule } from '@directives';
import { CoreDirectivesModule } from '@directives/directives.module';
import { AddonModFolderComponentsModule } from '../../components/components.module';
import { AddonModFolderIndexPage } from './index';

View File

@ -122,6 +122,7 @@ export class AddonModFolderProvider {
* Returns whether or not getFolder WS available or not.
*
* @return {boolean} If WS is avalaible.
* @since 3.3
*/
isGetFolderWSAvailable(): boolean {
return this.sitesProvider.wsAvailableInCurrentSite('mod_folder_get_folders_by_courses');
@ -134,14 +135,10 @@ export class AddonModFolderProvider {
* @return {Promise<any>} Promise resolved when the WS call is successful.
*/
logView(id: number): Promise<any> {
if (id) {
const params = {
folderid: id
};
const params = {
folderid: id
};
return this.sitesProvider.getCurrentSite().write('mod_folder_view_folder', params);
}
return Promise.reject(null);
return this.sitesProvider.getCurrentSite().write('mod_folder_view_folder', params);
}
}

View File

@ -13,7 +13,6 @@
// limitations under the License.
import { Injectable } from '@angular/core';
import { CoreLoggerProvider } from '@providers/logger';
import { CoreCourseProvider } from '@core/course/providers/course';
/**
@ -22,7 +21,7 @@ import { CoreCourseProvider } from '@core/course/providers/course';
@Injectable()
export class AddonModFolderHelperProvider {
constructor(logger: CoreLoggerProvider, private courseProvider: CoreCourseProvider) {
constructor(private courseProvider: CoreCourseProvider) {
}
/**

View File

@ -0,0 +1,30 @@
// (C) Copyright 2015 Martin Dougiamas
//
// 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 { Injectable } from '@angular/core';
import { CoreContentLinksModuleIndexHandler } from '@core/contentlinks/classes/module-index-handler';
import { CoreCourseHelperProvider } from '@core/course/providers/helper';
import { AddonModFolderProvider } from './folder';
/**
* Handler to treat links to resource.
*/
@Injectable()
export class AddonModFolderLinkHandler extends CoreContentLinksModuleIndexHandler {
name = 'AddonModFolderLinkHandler';
constructor(courseHelper: CoreCourseHelperProvider) {
super(courseHelper, AddonModFolderProvider.COMPONENT, 'folder');
}
}

View File

@ -0,0 +1,49 @@
// (C) Copyright 2015 Martin Dougiamas
//
// 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 { Injectable } from '@angular/core';
import { CorePluginFileHandler } from '@providers/plugin-file-delegate';
/**
* Handler to treat links to folder.
*/
@Injectable()
export class AddonModFolderPluginFileHandler implements CorePluginFileHandler {
name = 'AddonModFolderPluginFileHandler';
/**
* Return the RegExp to match the revision on pluginfile URLs.
*
* @param {string[]} args Arguments of the pluginfile URL defining component and filearea at least.
* @return {RegExp} RegExp to match the revision on pluginfile URLs.
*/
getComponentRevisionRegExp(args: string[]): RegExp {
// Check filearea.
if (args[2] == 'content') {
// Component + Filearea + Revision
return new RegExp('/mod_folder/content/([0-9]+)/');
}
}
/**
* Should return the string to remove the revision on pluginfile url.
*
* @param {string[]} args Arguments of the pluginfile URL defining component and filearea at least.
* @return {string} String to remove the revision on pluginfile url.
*/
getComponentRevisionReplace(args: string[]): string {
// Component + Filearea + Revision
return '/mod_folder/content/0/';
}
}

View File

@ -0,0 +1,81 @@
// (C) Copyright 2015 Martin Dougiamas
//
// 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 { Injectable, Injector } from '@angular/core';
import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler';
import { AddonModFolderProvider } from './folder';
/**
* Handler to prefetch folders.
*/
@Injectable()
export class AddonModFolderPrefetchHandler extends CoreCourseModulePrefetchHandlerBase {
name = 'folder';
component = AddonModFolderProvider.COMPONENT;
isResource = true;
constructor(injector: Injector, protected folderProvider: AddonModFolderProvider) {
super(injector);
}
/**
* Download or prefetch the content.
*
* @param {any} module The module object returned by WS.
* @param {number} courseId Course ID.
* @param {boolean} [prefetch] True to prefetch, false to download right away.
* @param {string} [dirPath] Path of the directory where to store all the content files. This is to keep the files
* relative paths and make the package work in an iframe. Undefined to download the files
* in the filepool root folder.
* @return {Promise<any>} Promise resolved when all content is downloaded. Data returned is not reliable.
*/
downloadOrPrefetch(module: any, courseId: number, prefetch?: boolean, dirPath?: string): Promise<any> {
const promises = [];
promises.push(super.downloadOrPrefetch(module, courseId, prefetch));
if (this.folderProvider.isGetFolderWSAvailable()) {
promises.push(this.folderProvider.getFolder(courseId, module.id));
}
return Promise.all(promises);
}
/**
* Invalidate the prefetched content.
*
* @param {number} moduleId The module ID.
* @param {number} courseId Course ID the module belongs to.
* @return {Promise<any>} Promise resolved when the data is invalidated.
*/
invalidateContent(moduleId: number, courseId: number): Promise<any> {
return this.folderProvider.invalidateContent(moduleId, courseId);
}
/**
* Invalidate WS calls needed to determine module status.
*
* @param {any} module Module.
* @param {number} courseId Course ID the module belongs to.
* @return {Promise<any>} Promise resolved when invalidated.
*/
invalidateModule(module: any, courseId: number): Promise<any> {
const promises = [];
promises.push(this.folderProvider.invalidateFolderData(courseId));
promises.push(this.courseProvider.invalidateModule(module.id));
return Promise.all(promises);
}
}

View File

@ -104,6 +104,8 @@ export class AddonModResourceIndexComponent implements OnInit, OnDestroy, CoreCo
done && done();
});
}
return Promise.resolve();
}
/**

View File

@ -15,6 +15,7 @@
import { Injectable } from '@angular/core';
import { CoreContentLinksModuleIndexHandler } from '@core/contentlinks/classes/module-index-handler';
import { CoreCourseHelperProvider } from '@core/course/providers/helper';
import { AddonModResourceProvider } from './resource';
/**
* Handler to treat links to resource.
@ -24,6 +25,6 @@ export class AddonModResourceLinkHandler extends CoreContentLinksModuleIndexHand
name = 'AddonModResourceLinkHandler';
constructor(courseHelper: CoreCourseHelperProvider) {
super(courseHelper, AddonModResourceLinkHandler.name, 'resource');
super(courseHelper, AddonModResourceProvider.COMPONENT, 'resource');
}
}

View File

@ -49,7 +49,7 @@ export class CoreContextMenuItemComponent implements OnInit, OnDestroy, OnChange
@Input() badge?: string; // A badge to show in the item.
@Input() badgeClass?: number; // A class to set in the badge.
@Input() hidden?: boolean; // Whether the item should be hidden.
@Output() action?: EventEmitter<string>; // Will emit an event when the item clicked.
@Output() action?: EventEmitter<() => void>; // Will emit an event when the item clicked.
protected hasAction = false;
protected destroyed = false;