Skip to content

Commit

Permalink
Video consent trial
Browse files Browse the repository at this point in the history
  • Loading branch information
okaycj committed Oct 3, 2024
1 parent bee67e0 commit 93b3868
Showing 1 changed file with 155 additions and 25 deletions.
180 changes: 155 additions & 25 deletions packages/record/src/consentVideo.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,135 @@
import { JsPsych, JsPsychPlugin } from "jspsych";
import Mustache from "mustache";
import { LookitWindow } from "@lookit/data/dist/types";
import Handlebars from "handlebars";
import { JsPsych, JsPsychPlugin, ParameterType, TrialType } from "jspsych";
import { version } from "../package.json";
import consentVideo from "../templates/consent-video-trial.mustache";
import consentCopyTemplate from "../templates/consent-copy.hbs";
import consentVideoTrialTemplate from "../templates/consent-video-trial.hbs";
import {
ButtonNotFoundError,
ImageNotFoundError,
VideoContainerNotFoundError,
} from "./errors";
import Recorder from "./recorder";
import { CSSWidthHeight } from "./types";
import { init } from "./utils";

declare const window: LookitWindow;

const info = <const>{
name: "consent-video",
version,
parameters: {},
data: {},
parameters: {
summary_statement: {
type: ParameterType.STRING,
default: "",
},
locale: {
type: ParameterType.STRING,
default: "en",
},
purpose_header: {
type: ParameterType.STRING,
default: "",
},
procedures: {
type: ParameterType.STRING,
default: "",
},
purpose: {
type: ParameterType.STRING,
default: "",
},
voluntary_participation: {
type: ParameterType.STRING,
default: "",
},
institution: {
type: ParameterType.STRING,
default: "",
},
risk_statement: {
type: ParameterType.STRING,
default: "",
},
risk_header: {
type: ParameterType.STRING,
default: "",
},
benefits_header: {
type: ParameterType.STRING,
default: "",
},
payment: {
type: ParameterType.STRING,
default: "",
},
prompt_only_adults: {
type: ParameterType.BOOL,
default: false,
},
private_level_only: {
type: ParameterType.BOOL,
default: false,
},
include_databrary: {
type: ParameterType.BOOL,
default: true,
},
additional_video_privacy_statement: {
type: ParameterType.STRING,
default: "",
},
datause: {
type: ParameterType.STRING,
default: "",
},
additional_segments: {
type: ParameterType.OBJECT,
default: {},
},
research_rights_statement: {
type: ParameterType.STRING,
default: "",
},
gdpr: {
type: ParameterType.BOOL,
default: false,
},
gdpr_personal_data: {
type: ParameterType.STRING,
default: "",
},
gdpr_sensitive_data: {
type: ParameterType.STRING,
default: "",
},
PIName: {
type: ParameterType.STRING,
default: "",
},
PIContact: {
type: ParameterType.STRING,
default: "",
},
omit_injury_phrase: {
type: ParameterType.BOOL,
default: false,
},
},
};
type Info = typeof info;

/** The video consent plugin. */
export class VideoConsentPlugin implements JsPsychPlugin<Info> {
public static readonly info = info;
private recorder: Recorder;

// Template variables
private video_container_id = "lookit-jspsych-video-container";

// Style variables
private videoWidth: CSSWidthHeight = "300px";
private readonly recorder: Recorder;
private readonly video_container_id = "lookit-jspsych-video-container";

/**
* Instantiate video consent plugin.
*
* @param jsPsych - JsPsych object
*/
public constructor(private jsPsych: JsPsych) {
public constructor(private readonly jsPsych: JsPsych) {
this.jsPsych = jsPsych;
this.recorder = new Recorder(this.jsPsych);
}
Expand All @@ -43,16 +138,37 @@ export class VideoConsentPlugin implements JsPsychPlugin<Info> {
* Create/Show trial view.
*
* @param display - HTML element for experiment.
* @param trial - Trial data including user supplied parameters.
*/
public trial(display: HTMLElement) {
public trial(display: HTMLElement, trial: TrialType<Info>) {
const { video_container_id } = this;
const experiment = window.chs.study.attributes;

// Initialize both i18next and Handlebars
init(trial);

display.insertAdjacentHTML(
"afterbegin",
Mustache.render(consentVideo, { video_container_id }),
// Render left side (consent text)
const renderConsent = Handlebars.compile(consentCopyTemplate);
const consent = renderConsent({
name: trial.PIName,
contact: trial.PIContact,
institution: trial.institution,
experiment,
});

// Render whole document with above consent text
const renderConsentVideoTrial = Handlebars.compile(
consentVideoTrialTemplate,
);
const consentVideoTrial = renderConsentVideoTrial({
consent,
video_container_id,
});

// Set up trial HTML
// Add rendered document to display HTML
display.insertAdjacentHTML("afterbegin", consentVideoTrial);

// Video recording HTML
this.webcamFeed(display);
this.recordButton(display);
this.stopButton(display);
Expand Down Expand Up @@ -84,7 +200,7 @@ export class VideoConsentPlugin implements JsPsychPlugin<Info> {
*/
private webcamFeed(display: HTMLElement) {
const videoContainer = this.getVideoContainer(display);
this.recorder.insertWebcamFeed(videoContainer, this.videoWidth);
this.recorder.insertWebcamFeed(videoContainer);
this.getImg(display, "record-icon").style.visibility = "hidden";
}

Expand All @@ -95,11 +211,7 @@ export class VideoConsentPlugin implements JsPsychPlugin<Info> {
*/
private playbackFeed(display: HTMLElement) {
const videoContainer = this.getVideoContainer(display);
this.recorder.insertPlaybackFeed(
videoContainer,
this.onEnded(display),
this.videoWidth,
);
this.recorder.insertPlaybackFeed(videoContainer, this.onEnded(display));
}

/**
Expand Down Expand Up @@ -217,3 +329,21 @@ export class VideoConsentPlugin implements JsPsychPlugin<Info> {
next.addEventListener("click", () => this.jsPsych.finishTrial());
}
}

// type Objectx ={
// type:string
// }

// interface ObjectA extends Objectx {
// type: "A";
// value1: string;
// value2: number;
// };

// interface ObjectB extends Objectx {
// type: "B";
// valueA: string;
// valueB: number;
// };

// type TypeA<I extends Objectx>

0 comments on commit 93b3868

Please sign in to comment.