MOBILE-3946 h5p: Refresh completion when H5P is finished
parent
007fbe0ab2
commit
c7a32b3e09
|
@ -37,6 +37,7 @@ import {
|
||||||
AddonModH5PActivityAccessInfo,
|
AddonModH5PActivityAccessInfo,
|
||||||
AddonModH5PActivityData,
|
AddonModH5PActivityData,
|
||||||
AddonModH5PActivityProvider,
|
AddonModH5PActivityProvider,
|
||||||
|
AddonModH5PActivityXAPIData,
|
||||||
} from '../../services/h5pactivity';
|
} from '../../services/h5pactivity';
|
||||||
import {
|
import {
|
||||||
AddonModH5PActivitySync,
|
AddonModH5PActivitySync,
|
||||||
|
@ -409,7 +410,8 @@ export class AddonModH5PActivityIndexComponent extends CoreCourseModuleMainActiv
|
||||||
* @return Promise resolved when done.
|
* @return Promise resolved when done.
|
||||||
*/
|
*/
|
||||||
protected async onIframeMessage(event: MessageEvent): Promise<void> {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -423,8 +425,8 @@ export class AddonModH5PActivityIndexComponent extends CoreCourseModuleMainActiv
|
||||||
|
|
||||||
const sent = await CoreXAPI.postStatements(
|
const sent = await CoreXAPI.postStatements(
|
||||||
this.h5pActivity!.context,
|
this.h5pActivity!.context,
|
||||||
event.data.component,
|
data.component,
|
||||||
JSON.stringify(event.data.statements),
|
JSON.stringify(data.statements),
|
||||||
options,
|
options,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -437,6 +439,12 @@ export class AddonModH5PActivityIndexComponent extends CoreCourseModuleMainActiv
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Ignore errors.
|
// 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) {
|
} catch (error) {
|
||||||
CoreDomUtils.showErrorModalDefault(error, 'Error sending tracking data.');
|
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.
|
* @return Whether it's an XAPI post statement of the current activity.
|
||||||
*/
|
*/
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// 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) {
|
if (data.environment != 'moodleapp' || data.context != 'h5p' || data.action != 'xapi_post_statement' || !data.statements) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in New Issue