From af9bebfcfb61da4c25710ab520abb1b1e4140d93 Mon Sep 17 00:00:00 2001 From: Henry Burgess Date: Wed, 10 Sep 2025 11:51:04 -0500 Subject: [PATCH 1/6] INT-74 Add `showStatusPreview` prop to `loaded` --- src/classes/factories/ScreenPropFactory.ts | 2 ++ src/index.tsx | 3 +++ types/index.d.ts | 1 + types/jsPsych.d.ts | 1 + types/props.d.ts | 1 + 5 files changed, 8 insertions(+) diff --git a/src/classes/factories/ScreenPropFactory.ts b/src/classes/factories/ScreenPropFactory.ts index 2de5543..29e1616 100644 --- a/src/classes/factories/ScreenPropFactory.ts +++ b/src/classes/factories/ScreenPropFactory.ts @@ -115,6 +115,7 @@ class ScreenPropFactory implements Factory { trial: this.trial.trial, display: this.trial.display, loadingType: this.trial.loadingType, + showStatusPreview: this.trial.showStatusPreview, handler: this.handler.callback.bind(this.handler), }; } else { @@ -128,6 +129,7 @@ class ScreenPropFactory implements Factory { trial: this.trial.trial, display: this.trial.display, loadingType: this.trial.loadingType, + showStatusPreview: this.trial.showStatusPreview, }; } break; diff --git a/src/index.tsx b/src/index.tsx index 5aa017d..3b7916f 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -912,6 +912,7 @@ timeline.push({ type: Configuration.studyName, display: "loaded", loadingType: "matchingIntentions", + showStatusPreview: Configuration.manipulations.enableStatusPhaseOne, }); // Set and store the data collection @@ -1311,6 +1312,7 @@ for (let i = 0; i < dataCollection.length; i++) { type: Configuration.studyName, display: "loaded", loadingType: "matchingIntentions", + showStatusPreview: Configuration.manipulations.enableStatusPhaseTwo, }); break; @@ -1527,6 +1529,7 @@ for (let i = 0; i < dataCollection.length; i++) { type: Configuration.studyName, display: "loaded", loadingType: "matchingIntentions", + showStatusPreview: Configuration.manipulations.enableStatusPhaseThree, }); break; diff --git a/types/index.d.ts b/types/index.d.ts index b69b89d..cfaeef2 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -103,6 +103,7 @@ declare type Trial = { // Loading screen configuration (used by Loading screen) loadingType?: "matchingIntentions" | "matchingCyberball" | "social" | "default"; // Type of loading: "matchingIntentions" (partner matching), "matchingCyberball" (cyberball partners), "social" (status generation), or "default" (generic loading) + showStatusPreview?: boolean; // Whether to show the status preview fetchData: boolean; // Whether to fetch data from server (only used when loadingType is "matchingIntentions") mode: "facilitator" | "mri"; diff --git a/types/jsPsych.d.ts b/types/jsPsych.d.ts index 2709063..9bff8db 100644 --- a/types/jsPsych.d.ts +++ b/types/jsPsych.d.ts @@ -46,6 +46,7 @@ declare type TimelineNode = { // Matching screen fetchData?: boolean; loadingType?: "matchingIntentions" | "matchingCyberball" | "social" | "default"; + showStatusPreview?: boolean; // Waiting screen mode?: "facilitator" | "mri"; diff --git a/types/props.d.ts b/types/props.d.ts index 23eca4d..b5a0976 100644 --- a/types/props.d.ts +++ b/types/props.d.ts @@ -86,6 +86,7 @@ declare namespace Props { // Loaded screen type Loaded = GenericScreenProps & { loadingType: "matchingIntentions" | "matchingCyberball" | "social"; + showStatusPreview: boolean; handler: () => void; }; From 8ce8e8b59a3c3fc2ce104d406a32491d962645bb Mon Sep 17 00:00:00 2001 From: Henry Burgess Date: Wed, 10 Sep 2025 11:53:35 -0500 Subject: [PATCH 2/6] Revert "INT-74 Add `showStatusPreview` prop to `loaded`" This reverts commit af9bebfcfb61da4c25710ab520abb1b1e4140d93. --- src/classes/factories/ScreenPropFactory.ts | 2 -- src/index.tsx | 3 --- types/index.d.ts | 1 - types/jsPsych.d.ts | 1 - types/props.d.ts | 1 - 5 files changed, 8 deletions(-) diff --git a/src/classes/factories/ScreenPropFactory.ts b/src/classes/factories/ScreenPropFactory.ts index 29e1616..2de5543 100644 --- a/src/classes/factories/ScreenPropFactory.ts +++ b/src/classes/factories/ScreenPropFactory.ts @@ -115,7 +115,6 @@ class ScreenPropFactory implements Factory { trial: this.trial.trial, display: this.trial.display, loadingType: this.trial.loadingType, - showStatusPreview: this.trial.showStatusPreview, handler: this.handler.callback.bind(this.handler), }; } else { @@ -129,7 +128,6 @@ class ScreenPropFactory implements Factory { trial: this.trial.trial, display: this.trial.display, loadingType: this.trial.loadingType, - showStatusPreview: this.trial.showStatusPreview, }; } break; diff --git a/src/index.tsx b/src/index.tsx index 3b7916f..5aa017d 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -912,7 +912,6 @@ timeline.push({ type: Configuration.studyName, display: "loaded", loadingType: "matchingIntentions", - showStatusPreview: Configuration.manipulations.enableStatusPhaseOne, }); // Set and store the data collection @@ -1312,7 +1311,6 @@ for (let i = 0; i < dataCollection.length; i++) { type: Configuration.studyName, display: "loaded", loadingType: "matchingIntentions", - showStatusPreview: Configuration.manipulations.enableStatusPhaseTwo, }); break; @@ -1529,7 +1527,6 @@ for (let i = 0; i < dataCollection.length; i++) { type: Configuration.studyName, display: "loaded", loadingType: "matchingIntentions", - showStatusPreview: Configuration.manipulations.enableStatusPhaseThree, }); break; diff --git a/types/index.d.ts b/types/index.d.ts index cfaeef2..b69b89d 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -103,7 +103,6 @@ declare type Trial = { // Loading screen configuration (used by Loading screen) loadingType?: "matchingIntentions" | "matchingCyberball" | "social" | "default"; // Type of loading: "matchingIntentions" (partner matching), "matchingCyberball" (cyberball partners), "social" (status generation), or "default" (generic loading) - showStatusPreview?: boolean; // Whether to show the status preview fetchData: boolean; // Whether to fetch data from server (only used when loadingType is "matchingIntentions") mode: "facilitator" | "mri"; diff --git a/types/jsPsych.d.ts b/types/jsPsych.d.ts index 9bff8db..2709063 100644 --- a/types/jsPsych.d.ts +++ b/types/jsPsych.d.ts @@ -46,7 +46,6 @@ declare type TimelineNode = { // Matching screen fetchData?: boolean; loadingType?: "matchingIntentions" | "matchingCyberball" | "social" | "default"; - showStatusPreview?: boolean; // Waiting screen mode?: "facilitator" | "mri"; diff --git a/types/props.d.ts b/types/props.d.ts index b5a0976..23eca4d 100644 --- a/types/props.d.ts +++ b/types/props.d.ts @@ -86,7 +86,6 @@ declare namespace Props { // Loaded screen type Loaded = GenericScreenProps & { loadingType: "matchingIntentions" | "matchingCyberball" | "social"; - showStatusPreview: boolean; handler: () => void; }; From 95e1fa3169773bc37ad2365b7e93bdecdc4476a0 Mon Sep 17 00:00:00 2001 From: Henry Burgess Date: Wed, 10 Sep 2025 12:07:33 -0500 Subject: [PATCH 3/6] INT-74 Re-implement `statusPreview` screen --- src/classes/factories/ScreenPropFactory.ts | 10 +++ src/view/components/Wrapper/index.tsx | 7 +- src/view/screens/StatusPreview/index.tsx | 79 ++++++++++++++++++++++ types/index.d.ts | 8 ++- types/jsPsych.d.ts | 3 +- types/props.d.ts | 6 ++ 6 files changed, 110 insertions(+), 3 deletions(-) create mode 100644 src/view/screens/StatusPreview/index.tsx diff --git a/src/classes/factories/ScreenPropFactory.ts b/src/classes/factories/ScreenPropFactory.ts index 2de5543..db78a28 100644 --- a/src/classes/factories/ScreenPropFactory.ts +++ b/src/classes/factories/ScreenPropFactory.ts @@ -132,6 +132,16 @@ class ScreenPropFactory implements Factory { } break; + case "statusPreview": + // Setup the props + returned.props = { + trial: this.trial.trial, + display: this.trial.display, + isPartnerHighStatus: this.trial.isPartnerHighStatus, + handler: this.handler.callback.bind(this.handler), + }; + break; + // Loading screen case "loading": if (this.trial.loadingType === "social") { diff --git a/src/view/components/Wrapper/index.tsx b/src/view/components/Wrapper/index.tsx index 9cbf063..3547724 100644 --- a/src/view/components/Wrapper/index.tsx +++ b/src/view/components/Wrapper/index.tsx @@ -33,8 +33,9 @@ import Status from "../../screens/Questionnaires/Status"; import DASS from "../../screens/Questionnaires/DASS"; import Screentime from "../../screens/Questionnaires/Screentime"; import Demographics from "../../screens/Questionnaires/Demographics"; -import Loaded from "../../screens/Loaded"; import Loading from "../../screens/Loading"; +import Loaded from "../../screens/Loaded"; +import StatusPreview from "src/view/screens/StatusPreview"; import Waiting from "../../screens/Waiting"; import End from "../../screens/End"; import Resources from "../../screens/Resources"; @@ -134,6 +135,10 @@ const Wrapper: FC = ( {activeDisplay === "loaded" && } + {activeDisplay === "statusPreview" && ( + + )} + {activeDisplay === "loading" && ( )} diff --git a/src/view/screens/StatusPreview/index.tsx b/src/view/screens/StatusPreview/index.tsx new file mode 100644 index 0000000..568d647 --- /dev/null +++ b/src/view/screens/StatusPreview/index.tsx @@ -0,0 +1,79 @@ +/** + * @file `Loaded` screen to confirm completion of loading process. + * + * This screen displays the newly assigned partner avatar to participants + * at the start of each game phase. Key features include: + * - Partner avatar presentation + * - Unique partner assignment per phase + * - State management for partner tracking + * - Consistent partner identity across sessions + * + * @author Henry Burgess + */ + +// React import +import React, { FC, ReactElement } from "react"; + +// Grommet UI components +import { Box, Button, Layer, Paragraph, WorldMap } from "grommet"; +import { LinkNext } from "grommet-icons"; +import Status from "src/view/components/Status"; +import Avatar from "boring-neutral-avatars"; + +// Configuration +import { Configuration } from "src/configuration"; + +/** + * @summary Generate a 'Loaded' screen containing a card with the partner avatar for the subsequent phase of the game + * @param {FC} props Empty props object as this component takes no props + * @return {ReactElement} 'Loaded' screen with partner avatar and success message + */ +const Loaded: FC = (props: Props.Screens.StatusPreview): ReactElement => { + // Get the current partner avatar + const experiment = window.Experiment; + const partnerStatus = props.isPartnerHighStatus ? experiment.getState().get("partnerHighStatus") : experiment.getState().get("partnerLowStatus"); + + // Get the updated partner avatar + const partnerAvatar = Configuration.avatars.names.partner[ + experiment.getState().get("partnerAvatar") + ] + + return ( + <> + + + + + In this phase you will be able to see your partner's social standing. + + + + + Their ID has been hidden to preserve anonymity. + +