MOBILE-3946 h5p: Refresh completion when H5P is finished

main
Dani Palou 2021-12-15 09:10:39 +01:00
parent 007fbe0ab2
commit c7a32b3e09
2 changed files with 52 additions and 4 deletions

View File

@ -37,6 +37,7 @@ import {
AddonModH5PActivityAccessInfo,
AddonModH5PActivityData,
AddonModH5PActivityProvider,
AddonModH5PActivityXAPIData,
} from '../../services/h5pactivity';
import {
AddonModH5PActivitySync,
@ -409,7 +410,8 @@ export class AddonModH5PActivityIndexComponent extends CoreCourseModuleMainActiv
* @return Promise resolved when done.
*/
protected async onIframeMessage(event: MessageEvent): Promise<void> {
if (!event.data || !CoreXAPI.canPostStatementsInSite(this.site) || !this.isCurrentXAPIPost(event.data)) {
const data = event.data;
if (!data || !CoreXAPI.canPostStatementsInSite(this.site) || !this.isCurrentXAPIPost(data)) {
return;
}
@ -423,8 +425,8 @@ export class AddonModH5PActivityIndexComponent extends CoreCourseModuleMainActiv
const sent = await CoreXAPI.postStatements(
this.h5pActivity!.context,
event.data.component,
JSON.stringify(event.data.statements),
data.component,
JSON.stringify(data.statements),
options,
);
@ -437,6 +439,12 @@ export class AddonModH5PActivityIndexComponent extends CoreCourseModuleMainActiv
} catch (error) {
// Ignore errors.
}
// Check if the H5P has ended. Final statements don't include a subContentId.
const hasEnded = data.statements.some(statement => !statement.object.id.includes('subContentId='));
if (hasEnded) {
CoreCourse.checkModuleCompletion(this.courseId, this.module.completiondata);
}
}
} catch (error) {
CoreDomUtils.showErrorModalDefault(error, 'Error sending tracking data.');
@ -450,7 +458,7 @@ export class AddonModH5PActivityIndexComponent extends CoreCourseModuleMainActiv
* @return Whether it's an XAPI post statement of the current activity.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
protected isCurrentXAPIPost(data: any): boolean {
protected isCurrentXAPIPost(data: any): data is AddonModH5PActivityXAPIData {
if (data.environment != 'moodleapp' || data.context != 'h5p' || data.action != 'xapi_post_statement' || !data.statements) {
return false;
}

View File

@ -1128,3 +1128,43 @@ declare module '@singletons/events' {
}
}
/**
* Data to be sent using xAPI.
*/
export type AddonModH5PActivityXAPIData = {
action: string;
component: string;
context: string;
environment: string;
statements: AddonModH5PActivityStatement[];
};
/**
* xAPI statement.
*/
export type AddonModH5PActivityStatement = {
actor: Record<string, string>;
context: Record<string, unknown>;
object: {
id: string;
definition: Record<string, unknown>;
objectType: string;
};
result: {
completion: boolean;
duration: string;
score: {
min: number;
max: number;
raw: number;
scaled: number;
};
success?: boolean;
response?: string;
};
verb: {
id: string;
display: Record<string, string>;
};
};