Skip to content

Commit 043ff68

Browse files
committed
Revert "small customPrompt rework & fix multiple prompts"
This reverts commit f10c44f.
1 parent f10c44f commit 043ff68

File tree

7 files changed

+63
-184
lines changed

7 files changed

+63
-184
lines changed

src/components/box/box.jsx

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,8 @@ Box.propTypes = {
9999
/**
100100
* A callback function whose first parameter is the underlying dom elements.
101101
* This call back will be executed immediately after the component is mounted or unmounted
102-
* Can also be a ref of Element
103102
*/
104-
componentRef: PropTypes.oneOfType([
105-
PropTypes.func,
106-
PropTypes.shape({ current: PropTypes.instanceOf(Element) })
107-
]),
103+
componentRef: PropTypes.func,
108104
/** https://developer.mozilla.org/en-US/docs/Web/CSS/flex-direction */
109105
direction: PropTypes.oneOf([
110106
'row', 'row-reverse', 'column', 'column-reverse'

src/components/modal/modal.jsx

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import styles from './modal.css';
1616
const ModalComponent = props => (
1717
<ReactModal
1818
isOpen
19-
ref={props.componentRef}
2019
className={classNames(styles.modalContent, props.className, {
2120
[styles.fullScreen]: props.fullScreen
2221
})}
@@ -25,12 +24,10 @@ const ModalComponent = props => (
2524
[styles.scrollable]: props.scrollable
2625
})}
2726
onRequestClose={props.onRequestClose}
28-
style={{ content: props.styleContent, overlay: props.styleOverlay }}
2927
>
3028
<Box
3129
dir={props.isRtl ? 'rtl' : 'ltr'}
3230
direction="column"
33-
componentRef={props.boxRef}
3431
grow={1}
3532
>
3633
<div className={classNames(styles.header, props.headerClassName)}>
@@ -101,16 +98,6 @@ const ModalComponent = props => (
10198

10299
ModalComponent.propTypes = {
103100
children: PropTypes.node,
104-
componentRef: PropTypes.oneOfType([
105-
PropTypes.func,
106-
PropTypes.shape({ current: PropTypes.instanceOf(Element) })
107-
]),
108-
boxRef: PropTypes.oneOfType([
109-
PropTypes.func,
110-
PropTypes.shape({ current: PropTypes.instanceOf(Element) })
111-
]),
112-
styleContent: PropTypes.object,
113-
styleOverlay: PropTypes.object,
114101
className: PropTypes.string,
115102
contentLabel: PropTypes.oneOfType([
116103
PropTypes.string,

src/components/prompt/prompt.jsx

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import Modal from '../../containers/modal.jsx';
99
import styles from './prompt.css';
1010
import { SCRATCH_MAX_CLOUD_VARIABLES } from '../../lib/tw-cloud-limits.js';
1111

12+
1213
const messages = defineMessages({
1314
forAllSpritesMessage: {
1415
defaultMessage: 'For all sprites',
@@ -45,13 +46,9 @@ const PromptComponent = props => props.isCustom ? (
4546
contentLabel={props.title}
4647
id="customModal"
4748
onRequestClose={props.onCancel}
48-
componentRef={props.ref}
49-
boxRef={props.boxRef}
50-
styleContent={props.styleContent}
51-
styleOverlay={props.styleOverlay}
5249
>
5350
<Box className={styles.body}>
54-
<Box componentRef={props.customRef}>
51+
<Box>
5552
</Box>
5653
<Box className={styles.buttonRow}>
5754
<button
@@ -75,10 +72,6 @@ const PromptComponent = props => props.isCustom ? (
7572
contentLabel={props.title}
7673
id="variableModal"
7774
onRequestClose={props.onCancel}
78-
componentRef={props.componentRef}
79-
boxRef={props.boxRef}
80-
styleContent={props.styleContent}
81-
styleOverlay={props.styleOverlay}
8275
>
8376
<Box className={styles.body}>
8477
<Box className={styles.label}>
@@ -239,25 +232,11 @@ PromptComponent.propTypes = {
239232
onScopeOptionSelection: PropTypes.func,
240233
showCloudOption: PropTypes.bool,
241234
showVariableOptions: PropTypes.bool,
242-
componentRef: PropTypes.oneOfType([
243-
PropTypes.func,
244-
PropTypes.shape({ current: PropTypes.instanceOf(Element) })
245-
]),
246-
boxRef: PropTypes.oneOfType([
247-
PropTypes.func,
248-
PropTypes.shape({ current: PropTypes.instanceOf(Element) })
249-
]),
250-
styleContent: PropTypes.object,
251-
styleOverlay: PropTypes.object,
252235

253236
/* custom modals */
254237
isCustom: PropTypes.bool,
255238
enterTitle: PropTypes.string,
256-
closeTitle: PropTypes.string,
257-
customRef: PropTypes.oneOfType([
258-
PropTypes.func,
259-
PropTypes.shape({ current: PropTypes.instanceOf(Element) })
260-
]),
239+
closeTitle: PropTypes.string
261240
};
262241

263242
export default PromptComponent;

src/containers/blocks.jsx

Lines changed: 58 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import DragConstants from '../lib/drag-constants';
2121
import defineDynamicBlock from '../lib/define-dynamic-block';
2222
import AddonHooks from '../addons/hooks';
2323
import LoadScratchBlocksHOC from '../lib/tw-load-scratch-blocks-hoc.jsx';
24-
import uid from "../lib/uid.js";
2524

2625
import {connect} from 'react-redux';
2726
import {updateToolbox} from '../reducers/toolbox';
@@ -77,7 +76,6 @@ const addFunctionListener = (object, property, callback) => {
7776
return result;
7877
};
7978
};
80-
const isObject = (value) => value && typeof value === 'object' && !Array.isArray(value);
8179

8280
const DroppableBlocks = DropAreaHOC([
8381
DragConstants.BACKPACK_CODE
@@ -145,12 +143,10 @@ class Blocks extends React.Component {
145143
this.ScratchBlocks.recordSoundCallback = this.handleOpenSoundRecorder;
146144

147145
this.state = {
148-
prompt: null,
149-
customPrompts: [],
146+
prompt: null
150147
};
151148
this.onTargetsUpdate = debounce(this.onTargetsUpdate, 100);
152149
this.toolboxUpdateQueue = [];
153-
this.customModalRefs = new Map();
154150
}
155151
componentDidMount () {
156152
this.props.vm.setCompilerOptions({
@@ -240,8 +236,6 @@ class Blocks extends React.Component {
240236
shouldComponentUpdate (nextProps, nextState) {
241237
return (
242238
this.state.prompt !== nextState.prompt ||
243-
this.state.customPrompts !== nextState.customPrompts ||
244-
(nextState.customPrompts && this.state.customPrompts.length !== nextState.customPrompts.length) ||
245239
this.props.isVisible !== nextProps.isVisible ||
246240
this._renderedToolboxXML !== nextProps.toolboxXML ||
247241
this.props.extensionLibraryVisible !== nextProps.extensionLibraryVisible ||
@@ -617,49 +611,46 @@ class Blocks extends React.Component {
617611
p.prompt.showCloudOption = (optVarType === this.ScratchBlocks.SCALAR_VARIABLE_TYPE) && this.props.canUseCloud;
618612
this.setState(p);
619613
}
620-
handleCustomPrompt (config, styles, enterInfo, closeInfo) {
621-
return new Promise((resolve, reject) => {
622-
/* validate arguments */
623-
if (config && isObject(config)) {
624-
if (!config.title) return reject("Custom Modal -- Missing 'title' (string) property in Param 1");
625-
} else {
626-
return reject("Custom Modal -- Param 1 must be an object with at least properties: 'title' (string)");
627-
}
628-
if (styles && !isObject(styles)) {
629-
return reject("Custom Modal -- Param 2 must be an object");
630-
}
631-
if (styles && (!styles.content && !styles.overlay)) {
632-
return reject("Custom Modal -- If Param 2 is specified, specify CSS styles within either: 'content' or 'overlay'");
633-
}
634-
if (isObject(enterInfo)) {
635-
if (!enterInfo.name || !enterInfo.callback) return reject("Custom Modal -- Missing name/callback property in Param 3");
636-
if (enterInfo.callback && typeof enterInfo.callback !== 'function') return reject("Custom Modal -- callback property in Param 3 must be a function");
637-
} else {
638-
return reject("Custom Modal -- Param 3 must be a object with properties: 'name' (string) and 'callback' (function)");
639-
}
640-
if (isObject(closeInfo)) {
641-
if (!closeInfo.name || !closeInfo.callback) return reject("Custom Modal -- Missing name/callback property in Param 4");
642-
if (closeInfo.callback && typeof closeInfo.callback !== 'function') return reject("Custom Modal -- callback property in Param 4 must be a function");
643-
} else {
644-
return reject("Custom Modal -- Param 4 must be a object with properties: 'name' (string) and 'callback' (function)");
645-
}
614+
handleCustomPrompt (title, scale, enterInfo, closeInfo) {
615+
const isObject = (value) => typeof value === 'object' && !Array.isArray(value);
616+
let needsExit = false;
617+
const exitFunc = (message) => {
618+
needsExit = true;
619+
console.error(message);
620+
};
646621

647-
// create the callback for when the node is created. an HTML element (or modal) with ref={functionHere} will run the function with the HTMLElement as 1st arg
648-
const thisPromptId = uid();
649-
this.customModalRefs.set(thisPromptId, (node) => {
650-
resolve(node);
651-
})
652-
653-
// Setting state with this info will cause blocks.jsx to re-render, rendering the modal before any code after setState can run.
654-
// However, the callback & ref are not be usable until slightly later. this is why ref is set to a callback above.
655-
// This is one of many reasons why React is pretty stupid.
656-
this.setState({
657-
customPrompts: this.state.customPrompts.concat({
658-
id: thisPromptId,
659-
config, styles, enterInfo, closeInfo
660-
})
661-
});
662-
});
622+
/* validate arguments */
623+
if (isObject(scale)) {
624+
if (!scale.width || !scale.height) exitFunc("Custom Modal -- Missing width/height number property in Param 2");
625+
} else {
626+
exitFunc("Custom Modal -- Param 2 must be a object with 'width' and 'height' number properties");
627+
}
628+
if (isObject(enterInfo)) {
629+
if (!enterInfo.name || !enterInfo.callback) exitFunc("Custom Modal -- Missing name/callback property in Param 3");
630+
if (enterInfo.callback && typeof enterInfo.callback !== 'function') exitFunc("Custom Modal -- callback property in Param 3 must be a function");
631+
} else {
632+
exitFunc("Custom Modal -- Param 3 must be a object with properties: 'name' (string) and 'callback' (function)");
633+
}
634+
if (isObject(closeInfo)) {
635+
if (!closeInfo.name || !closeInfo.callback) exitFunc("Custom Modal -- Missing name/callback property in Param 4");
636+
if (closeInfo.callback && typeof closeInfo.callback !== 'function') exitFunc("Custom Modal -- callback property in Param 4 must be a function");
637+
} else {
638+
exitFunc("Custom Modal -- Param 4 must be a object with properties: 'name' (string) and 'callback' (function)");
639+
}
640+
if (needsExit) return;
641+
642+
this.setState({prompt: {
643+
isCustom: true,
644+
title, enterInfo, closeInfo
645+
}});
646+
647+
const modal = document.querySelector(`div[class="ReactModalPortal"]`);
648+
if (modal) {
649+
const inner = modal.firstChild.firstChild;
650+
inner.style.width = typeof scale.width === 'number' ? `${scale.width}px` : scale.width;
651+
inner.style.height = typeof scale.height === 'number' ? `${scale.height}px` : scale.height;
652+
return inner.querySelector(`div[class*="prompt_body_"] div`);
653+
}
663654
}
664655
handleConnectionModalStart (extensionId) {
665656
this.props.onOpenConnectionModal(extensionId);
@@ -676,28 +667,20 @@ class Blocks extends React.Component {
676667
* and additional potentially conflicting variable names from the VM
677668
* to the variable validation prompt callback used in scratch-blocks.
678669
*/
679-
handlePromptCallback (input, variableOptions, customPrompt) {
680-
if (customPrompt) {
681-
customPrompt.enterInfo.callback();
682-
return this.setState({
683-
customPrompts: this.state.customPrompts.filter(prompt => prompt !== customPrompt)
684-
});
670+
handlePromptCallback (input, variableOptions) {
671+
if (this.state.prompt.isCustom) {
672+
this.state.prompt.enterInfo.callback();
673+
this.setState({prompt: null});
674+
return;
685675
}
686-
687676
this.state.prompt.callback(
688677
input,
689678
this.props.vm.runtime.getAllVarNamesOfType(this.state.prompt.varType),
690679
variableOptions);
691680
this.handlePromptClose();
692681
}
693-
handlePromptClose (customPrompt) {
694-
if (customPrompt) {
695-
customPrompt.closeInfo.callback();
696-
return this.setState({
697-
customPrompts: this.state.customPrompts.filter(prompt => prompt !== customPrompt)
698-
});
699-
}
700-
682+
handlePromptClose () {
683+
if (this.state.prompt.isCustom) this.state.prompt.closeInfo.callback();
701684
this.setState({prompt: null});
702685
}
703686
handleCustomProceduresClose (data) {
@@ -753,7 +736,17 @@ class Blocks extends React.Component {
753736
onDrop={this.handleDrop}
754737
{...props}
755738
/>
756-
{this.state.prompt ? (
739+
{this.state.prompt ? this.state.prompt.isCustom ? (
740+
<Prompt
741+
isCustom={this.state.prompt.isCustom}
742+
title={this.state.prompt.title}
743+
enterTitle={this.state.prompt.enterInfo.name}
744+
closeTitle={this.state.prompt.closeInfo.name}
745+
vm={vm}
746+
onCancel={this.handlePromptClose}
747+
onOk={this.handlePromptCallback}
748+
/>
749+
) : (
757750
<Prompt
758751
defaultValue={this.state.prompt.defaultValue}
759752
isStage={vm.runtime.getEditingTarget().isStage}
@@ -767,20 +760,6 @@ class Blocks extends React.Component {
767760
onOk={this.handlePromptCallback}
768761
/>
769762
) : null}
770-
{this.state.customPrompts.map(prompt => (
771-
<Prompt
772-
isCustom={true}
773-
vm={vm}
774-
customRef={this.customModalRefs.get(prompt.id)}
775-
title={prompt.config.title}
776-
styleContent={prompt.styles ? prompt.styles.content : null}
777-
styleOverlay={prompt.styles ? prompt.styles.overlay : null}
778-
enterTitle={prompt.enterInfo.name}
779-
closeTitle={prompt.closeInfo.name}
780-
onCancel={() => this.handlePromptClose(prompt)}
781-
onOk={() => this.handlePromptCallback(null, null, prompt)}
782-
/>
783-
))}
784763
{extensionLibraryVisible ? (
785764
<ExtensionLibrary
786765
vm={vm}

src/containers/modal.jsx

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,19 +48,9 @@ class Modal extends React.Component {
4848

4949
Modal.propTypes = {
5050
id: PropTypes.string.isRequired,
51-
componentRef: PropTypes.oneOfType([
52-
PropTypes.func,
53-
PropTypes.shape({ current: PropTypes.instanceOf(Element) })
54-
]),
55-
boxRef: PropTypes.oneOfType([
56-
PropTypes.func,
57-
PropTypes.shape({ current: PropTypes.instanceOf(Element) })
58-
]),
5951
isRtl: PropTypes.bool,
6052
onRequestClose: PropTypes.func,
6153
onRequestOpen: PropTypes.func,
62-
styleContent: PropTypes.object,
63-
styleOverlay: PropTypes.object,
6454
scrollable: PropTypes.bool
6555
};
6656

src/containers/prompt.jsx

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -62,17 +62,12 @@ class Prompt extends React.Component {
6262
if (this.props.isCustom) return (
6363
<PromptComponent
6464
isCustom={this.props.isCustom}
65-
componentRef={this.props.componentRef}
66-
boxRef={this.props.boxRef}
67-
styleContent={this.props.styleContent}
68-
styleOverlay={this.props.styleOverlay}
6965
title={this.props.title}
7066
enterTitle={this.props.enterTitle}
7167
closeTitle={this.props.closeTitle}
7268
onOk={this.handleOk}
7369
onCancel={this.handleCancel}
7470
onKeyPress={this.handleKeyPress}
75-
customRef={this.props.customRef}
7671
/>
7772
)
7873
else return (
@@ -95,10 +90,6 @@ class Prompt extends React.Component {
9590
onKeyPress={this.handleKeyPress}
9691
onOk={this.handleOk}
9792
onScopeOptionSelection={this.handleScopeOptionSelection}
98-
componentRef={this.props.componentRef}
99-
styleContent={this.props.styleContent}
100-
styleOverlay={this.props.styleOverlay}
101-
boxRef={this.props.boxRef}
10293
/>
10394
);
10495
}
@@ -115,25 +106,11 @@ Prompt.propTypes = {
115106
showCloudOption: PropTypes.bool,
116107
showVariableOptions: PropTypes.bool,
117108
vm: PropTypes.instanceOf(VM),
118-
componentRef: PropTypes.oneOfType([
119-
PropTypes.func,
120-
PropTypes.shape({ current: PropTypes.instanceOf(Element) })
121-
]),
122-
boxRef: PropTypes.oneOfType([
123-
PropTypes.func,
124-
PropTypes.shape({ current: PropTypes.instanceOf(Element) })
125-
]),
126-
styleContent: PropTypes.object,
127-
styleOverlay: PropTypes.object,
128109

129110
/* custom modals */
130111
isCustom: PropTypes.bool,
131112
enterTitle: PropTypes.string,
132-
closeTitle: PropTypes.string,
133-
customRef: PropTypes.oneOfType([
134-
PropTypes.func,
135-
PropTypes.shape({ current: PropTypes.instanceOf(Element) })
136-
]),
113+
closeTitle: PropTypes.string
137114
};
138115

139116
export default Prompt;

0 commit comments

Comments
 (0)