Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 29 additions & 13 deletions src/addon/mod/data/components/index/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,18 +124,8 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp
this.selectedGroup = this.group || 0;

this.loadContent(false, true).then(() => {
if (!this.data || !this.data.id) {
return;
}

this.dataProvider.logView(this.data.id, this.data.name).then(() => {
this.courseProvider.checkModuleCompletion(this.courseId, this.module.completiondata);
}).catch(() => {
// Ignore errors.
});
return this.logView(true);
});

// Setup search modal.
}

/**
Expand Down Expand Up @@ -362,7 +352,10 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp
this.loaded = false;
this.search.page = page;

return this.fetchEntriesData().catch((message) => {
return this.fetchEntriesData().then(() => {
// Log activity view for coherence with Moodle web.
return this.logView();
}).catch((message) => {
this.domUtils.showErrorModalDefault(message, 'core.course.errorgetmodule', true);
}).finally(() => {
this.loaded = true;
Expand Down Expand Up @@ -392,7 +385,10 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp
this.selectedGroup = groupId;
this.search.page = 0;

return this.fetchEntriesData().catch((message) => {
return this.fetchEntriesData().then(() => {
// Log activity view for coherence with Moodle web.
return this.logView();
}).catch((message) => {
this.domUtils.showErrorModalDefault(message, 'core.course.errorgetmodule', true);

return Promise.reject(null);
Expand Down Expand Up @@ -454,6 +450,26 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp
return result.updated;
}

/**
* Log viewing the activity.
*
* @param checkCompletion Whether to check completion.
* @return Promise resolved when done.
*/
protected logView(checkCompletion?: boolean): Promise<any> {
if (!this.data || !this.data.id) {
return Promise.resolve();
}

return this.dataProvider.logView(this.data.id, this.data.name).then(() => {
if (checkCompletion) {
this.courseProvider.checkModuleCompletion(this.courseId, this.module.completiondata);
}
}).catch(() => {
// Ignore errors, the user could be offline.
});
}

/**
* Component being destroyed.
*/
Expand Down
27 changes: 24 additions & 3 deletions src/addon/mod/data/pages/entry/entry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,9 @@ export class AddonModDataEntryPage implements OnDestroy {
*/
ionViewDidLoad(): void {
this.commentsEnabled = !this.commentsProvider.areCommentsDisabledInSite();
this.fetchEntryData();
this.fetchEntryData().then(() => {
this.logView();
});

// Refresh data if this discussion is synchronized automatically.
this.syncObserver = this.eventsProvider.on(AddonModDataSyncProvider.AUTO_SYNCED, (data) => {
Expand Down Expand Up @@ -199,7 +201,9 @@ export class AddonModDataEntryPage implements OnDestroy {
this.entry = null;
this.entryLoaded = false;

return this.fetchEntryData();
return this.fetchEntryData().then(() => {
this.logView();
});
}

/**
Expand Down Expand Up @@ -258,7 +262,9 @@ export class AddonModDataEntryPage implements OnDestroy {
this.entryId = null;
this.entryLoaded = false;

return this.fetchEntryData();
return this.fetchEntryData().then(() => {
this.logView();
});
}

/**
Expand Down Expand Up @@ -363,6 +369,21 @@ export class AddonModDataEntryPage implements OnDestroy {
this.dataProvider.invalidateEntryData(this.data.id, this.entryId);
}

/**
* Log viewing the activity.
*
* @return Promise resolved when done.
*/
protected logView(): Promise<any> {
if (!this.data || !this.data.id) {
return Promise.resolve();
}

return this.dataProvider.logView(this.data.id, this.data.name).catch(() => {
// Ignore errors, the user could be offline.
});
}

/**
* Component being destroyed.
*/
Expand Down
17 changes: 11 additions & 6 deletions src/core/fileuploader/providers/fileuploader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,20 +150,25 @@ export class CoreFileUploaderProvider {
* @return Options.
*/
getCameraUploadOptions(uri: string, isFromAlbum?: boolean): CoreFileUploaderOptions {
const extension = this.mimeUtils.getExtension(uri),
mimetype = this.mimeUtils.getMimeType(extension),
isIOS = this.platform.is('ios'),
options: CoreFileUploaderOptions = {
const extension = this.mimeUtils.guessExtensionFromUrl(uri);
const mimetype = this.mimeUtils.getMimeType(extension);
const isIOS = this.platform.is('ios');
const options: CoreFileUploaderOptions = {
deleteAfterUpload: !isFromAlbum,
mimeType: mimetype
};
const fileName = this.fileProvider.getFileAndDirectoryFromPath(uri).name;

if (isIOS && (mimetype == 'image/jpeg' || mimetype == 'image/png')) {
// In iOS, the pictures can have repeated names, even if they come from the album.
options.fileName = 'image_' + this.timeUtils.readableTimestamp() + '.' + extension;
// Add a timestamp to the filename to make it unique.
const split = fileName.split('.');
split[0] += '_' + this.timeUtils.readableTimestamp();

options.fileName = split.join('.');
} else {
// Use the same name that the file already has.
options.fileName = this.fileProvider.getFileAndDirectoryFromPath(uri).name;
options.fileName = fileName;
}

if (isFromAlbum) {
Expand Down
25 changes: 14 additions & 11 deletions src/core/fileuploader/providers/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,12 @@ export class CoreFileUploaderHelperProvider {
* @param defaultExt Defaut extension to use if the file doesn't have any.
* @return Promise resolved with the copied file.
*/
protected copyToTmpFolder(path: string, shouldDelete: boolean, maxSize?: number, defaultExt?: string): Promise<any> {
let fileName = this.fileProvider.getFileAndDirectoryFromPath(path).name,
promise,
fileTooLarge;
protected copyToTmpFolder(path: string, shouldDelete: boolean, maxSize?: number, defaultExt?: string,
options?: CoreFileUploaderOptions): Promise<any> {

const fileName = (options && options.fileName) || this.fileProvider.getFileAndDirectoryFromPath(path).name;
let promise;
let fileTooLarge;

// Check that size isn't too large.
if (typeof maxSize != 'undefined' && maxSize != -1) {
Expand All @@ -154,9 +156,6 @@ export class CoreFileUploaderHelperProvider {
}

// File isn't too large.
// Picking an image from album in Android adds a timestamp at the end of the file. Delete it.
fileName = fileName.replace(/(\.[^\.]*)\?[^\.]*$/, '$1');

// Get a unique name in the folder to prevent overriding another file.
return this.fileProvider.getUniqueNameInFolder(CoreFileProvider.TMPFOLDER, fileName, defaultExt);
}).then((newName) => {
Expand Down Expand Up @@ -468,11 +467,13 @@ export class CoreFileUploaderHelperProvider {
path = 'file://' + path;
}

const options = this.fileUploaderProvider.getMediaUploadOptions(media);

if (upload) {
return this.uploadFile(path, maxSize, true, this.fileUploaderProvider.getMediaUploadOptions(media));
return this.uploadFile(path, maxSize, true, options);
} else {
// Copy or move the file to our temporary folder.
return this.copyToTmpFolder(path, true, maxSize);
return this.copyToTmpFolder(path, true, maxSize, undefined, options);
}
}, (error) => {
const defaultError = isAudio ? 'core.fileuploader.errorcapturingaudio' : 'core.fileuploader.errorcapturingvideo';
Expand Down Expand Up @@ -552,11 +553,13 @@ export class CoreFileUploaderHelperProvider {
return Promise.reject(error);
}

const options = this.fileUploaderProvider.getCameraUploadOptions(path, fromAlbum);

if (upload) {
return this.uploadFile(path, maxSize, true, this.fileUploaderProvider.getCameraUploadOptions(path, fromAlbum));
return this.uploadFile(path, maxSize, true, options);
} else {
// Copy or move the file to our temporary folder.
return this.copyToTmpFolder(path, !fromAlbum, maxSize, 'jpg');
return this.copyToTmpFolder(path, !fromAlbum, maxSize, 'jpg', options);
}
}, (error) => {
const defaultError = fromAlbum ? 'core.fileuploader.errorgettingimagealbum' : 'core.fileuploader.errorcapturingimage';
Expand Down
8 changes: 4 additions & 4 deletions src/core/h5p/classes/content-validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,7 @@ export class CoreH5PContentValidator {
continue;
}

// Find semantics for name=$key
// Find semantics for name=key.
let found = false,
fn = null,
field = null;
Expand Down Expand Up @@ -729,7 +729,7 @@ export class CoreH5PContentValidator {
}

if (slash != '') {
return '</$elem>';
return '</' + elem + '>';
}

// Is there a closing XHTML slash at the end of the attributes?
Expand Down Expand Up @@ -871,8 +871,8 @@ export class CoreH5PContentValidator {
* Processes an HTML attribute value and strips dangerous protocols from URLs.
*
* @param str The string with the attribute value.
* @param decode Whether to decode entities in the $string.
* @return Cleaned up and HTML-escaped version of $string.
* @param decode Whether to decode entities in the str.
* @return Cleaned up and HTML-escaped version of str.
*/
filterXssBadProtocol(str: string, decode: boolean = true): string {
// Get the plain text representation of the attribute value (i.e. its meaning).
Expand Down