Skip to content

Commit b663b97

Browse files
committed
Reactify inline drop-zone border setting logic
Also fix overlap of drop-zones, and correct a couple of types
1 parent 8a769b0 commit b663b97

File tree

3 files changed

+20
-23
lines changed

3 files changed

+20
-23
lines changed

src/IsaacApiTypes.tsx

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ export interface IsaacParsonsQuestionDTO extends IsaacItemQuestionDTO {
134134
disableIndentation?: boolean;
135135
}
136136

137-
export interface IsaacClozeQuestionDTO extends IsaacParsonsQuestionDTO {
137+
export interface IsaacClozeQuestionDTO extends IsaacItemQuestionDTO {
138138
withReplacement?: boolean;
139139
}
140140

@@ -408,10 +408,6 @@ export interface ItemChoiceDTO extends ChoiceDTO {
408408
export interface ItemDTO extends ContentDTO {
409409
}
410410

411-
export interface ClozeItemDTO extends ItemDTO {
412-
replacementId?: string;
413-
}
414-
415411
export interface LogicFormulaDTO extends ChoiceDTO {
416412
pythonExpression?: string;
417413
}

src/IsaacAppTypes.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
Difficulty,
1111
GameboardDTO,
1212
GameboardItem,
13+
ItemDTO,
1314
QuizFeedbackMode,
1415
RegisteredUserDTO,
1516
ResultsWrapper,
@@ -962,3 +963,7 @@ export interface AppQuizAssignment extends ApiTypes.QuizAssignmentDTO {
962963
}
963964

964965
export const QuizFeedbackModes: QuizFeedbackMode[] = ["NONE", "OVERALL_MARK", "SECTION_MARKS", "DETAILED_FEEDBACK"];
966+
967+
export interface ClozeItemDTO extends ItemDTO {
968+
replacementId?: string;
969+
}

src/app/components/content/IsaacClozeQuestion.tsx

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import React, {RefObject, useContext, useEffect, useRef, useState} from "react";
22
import * as RS from "reactstrap";
33
import {Label} from "reactstrap";
44
import {
5-
ClozeItemDTO,
65
IsaacClozeQuestionDTO,
76
ItemChoiceDTO,
87
ItemDTO
@@ -21,7 +20,7 @@ import {
2120
ResponderProvided
2221
} from "react-beautiful-dnd";
2322
import ReactDOM from 'react-dom';
24-
import {ClozeDropRegionContext} from "../../../IsaacAppTypes";
23+
import {ClozeDropRegionContext, ClozeItemDTO} from "../../../IsaacAppTypes";
2524
import {setCurrentAttempt} from "../../state/actions";
2625
import uuid from "uuid";
2726
import {Item} from "../../services/select";
@@ -35,9 +34,9 @@ function Item({item}: {item: ItemDTO}) {
3534
}
3635

3736
interface InlineDropRegionProps {
38-
id: string; item?: ClozeItemDTO; contentHolder: RefObject<HTMLDivElement>; readonly?: boolean; updateAttempt: (dropResult : DropResult) => void;
37+
id: string; item?: ClozeItemDTO; contentHolder: RefObject<HTMLDivElement>; readonly?: boolean; updateAttempt: (dropResult : DropResult) => void; showBorder: boolean;
3938
}
40-
function InlineDropRegion({id, item, contentHolder, readonly, updateAttempt}: InlineDropRegionProps) {
39+
function InlineDropRegion({id, item, contentHolder, readonly, updateAttempt, showBorder}: InlineDropRegionProps) {
4140

4241
function clearInlineDropZone() {
4342
updateAttempt({source: {droppableId: id, index: 0}, draggableId: (item?.replacementId as string)} as DropResult);
@@ -46,11 +45,11 @@ function InlineDropRegion({id, item, contentHolder, readonly, updateAttempt}: In
4645
const droppableTarget = contentHolder.current?.querySelector(`#${id}`);
4746
if (droppableTarget) {
4847
return ReactDOM.createPortal(
49-
<div style={{minHeight: "inherit", position: "relative"}}>
48+
<div style={{minHeight: "inherit", position: "relative", margin: "2px"}}>
5049
<Droppable droppableId={id} isDropDisabled={readonly} direction="vertical" >
5150
{(provided, snapshot) => <div
5251
ref={provided.innerRef} {...provided.droppableProps}
53-
className="d-flex justify-content-center align-items-center bg-grey rounded w-100 overflow-hidden"
52+
className={`d-flex justify-content-center align-items-center bg-grey rounded w-100 overflow-hidden ${showBorder && "border border-dark"}`}
5453
style={{minHeight: "inherit"}}
5554
>
5655
{item && <Draggable key={item.replacementId} draggableId={item?.replacementId as string} index={0} isDragDisabled={true}>
@@ -111,6 +110,8 @@ export function IsaacClozeQuestion({doc, questionId, readonly}: {doc: IsaacCloze
111110
const registeredDropRegionIDs = useRef<string[]>([]).current;
112111
const [inlineDropValues, setInlineDropValues] = useState<(ClozeItemDTO | undefined)[]>(() => currentAttempt?.items || []);
113112

113+
const [borderMap, setBorderMap] = useState<{[dropId: string]: boolean}>({});
114+
114115
useEffect(() => {
115116
if (currentAttempt?.items) {
116117
const idvs = currentAttempt.items as (ClozeItemDTO | undefined)[];
@@ -128,6 +129,7 @@ export function IsaacClozeQuestion({doc, questionId, readonly}: {doc: IsaacCloze
128129
if (!registeredDropRegionIDs.includes(dropRegionId)) {
129130
registeredDropRegionIDs.push(dropRegionId);
130131
setInlineDropValues(registeredDropRegionIDs.map(() => undefined));
132+
setBorderMap(registeredDropRegionIDs.reduce((dict: {[dropId: string]: boolean}, id) => Object.assign(dict, {[id]: false}), {}));
131133
}
132134
}
133135

@@ -138,21 +140,14 @@ export function IsaacClozeQuestion({doc, questionId, readonly}: {doc: IsaacCloze
138140
// This is run on drag update to highlight the droppable that the user is dragging over
139141
// this gives more control over when a droppable is highlighted
140142
function fixInlineZones({destination}: DragUpdate, provided: ResponderProvided) {
141-
registeredDropRegionIDs.map((dropid, i) => {
142-
const inlineDrop = document.querySelector(`[data-rbd-droppable-id="${dropid}"]`) as HTMLElement;
143-
const destinationDropIndex = destination ? registeredDropRegionIDs.indexOf(dropid) : -1;
143+
registeredDropRegionIDs.map((dropId, i) => {
144+
const destinationDropIndex = destination ? registeredDropRegionIDs.indexOf(dropId) : -1;
144145
const destinationDragIndex = destination?.index ?? -1;
145146

146-
if (inlineDrop) {
147-
if (dropid === destination?.droppableId && destinationDropIndex !== -1 && destinationDragIndex === 0) {
148-
// Reselect zone (or make sure it's got a border)
149-
inlineDrop.className = inlineDrop.className.replace("border border-dark", "") + " border border-dark";
150-
} else {
151-
// Deselect zone
152-
inlineDrop.className = inlineDrop.className.replace("border border-dark", "");
153-
}
154-
}
147+
borderMap[dropId] = (dropId === destination?.droppableId && destinationDropIndex !== -1 && destinationDragIndex === 0);
155148
});
149+
// Tell React about the changes to borderMap
150+
setBorderMap({...borderMap});
156151
}
157152

158153
// Run after a drag action ends
@@ -279,6 +274,7 @@ export function IsaacClozeQuestion({doc, questionId, readonly}: {doc: IsaacCloze
279274
id={dropRegionId} item={inlineDropValues[index]} updateAttempt={(dropResult) => {
280275
updateAttempt({...dropResult, destination: {droppableId: itemsSection, index: nonSelectedItems.length}},{announce: (_) => {return;}});
281276
}}
277+
showBorder={borderMap[dropRegionId]}
282278
/>
283279
)}
284280
</DragDropContext>

0 commit comments

Comments
 (0)