Skip to content

Commit 879a79a

Browse files
authored
Merge pull request #17 from tonyito/mvp
Comments Batch #1
2 parents 931dc28 + 1e22880 commit 879a79a

File tree

12 files changed

+243
-119
lines changed

12 files changed

+243
-119
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Created by https://www.gitignore.io/api/node,linux,macos,windows,visualstudio,yarn
22
yarn.lock
3+
package-lock.json
34
### Linux ###
45
*~
56

src/actions/components.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {
2-
ComponentInt, ComponentsInt, PropInt, ChildInt, Action, ApplicationStateInt, LoadInitData, AddComponent
3-
} from '../utils/Interfaces.ts';
2+
ComponentInt, ComponentsInt, PropInt, ChildInt, Action
3+
} from '../utils/Interfaces';
44

55
import {
66
LOAD_INIT_DATA,
@@ -26,14 +26,14 @@ import {
2626
ADD_PROP,
2727
DELETE_ALL_DATA,
2828
UPDATE_HTML_ATTR,
29-
UPDATE_CHILDREN_SORT,
29+
// UPDATE_CHILDREN_SORT, --The reason why this is commented out is because of the unused reducer of the same name, for the component that is unfinished with the same name. Check out the Sort Children component to see what it does.
3030
CHANGE_IMAGE_SOURCE,
3131
DELETE_IMAGE
32-
} from '../actionTypes/index.ts';
32+
} from '../actionTypes/index';
3333

34-
import { loadState } from '../localStorage';
35-
import createFiles from '../utils/createFiles.util.ts';
36-
import createApplicationUtil from '../utils/createApplication.util.ts';
34+
import { loadState } from '../localStorage'; //this is a warning from 'localStorage' being a .js file instead of .ts. Convert to .ts to remove this warning.
35+
import createFiles from '../utils/createFiles.util';
36+
import createApplicationUtil from '../utils/createApplication.util';
3737

3838
export const changeImagePath = (imageSource: string) => ({
3939
type: CHANGE_IMAGE_SOURCE,
@@ -51,7 +51,7 @@ export const loadInitData = () => (dispatch: (arg: Action) => void) => {
5151
});
5252
};
5353

54-
export const addComponent = ({ title }: { title: string }) => (dispatch: (arg: AddComponent) => void) => {
54+
export const addComponent = ({ title }: { title: string }) => (dispatch: (arg: Action) => void) => {
5555
dispatch({ type: ADD_COMPONENT, payload: { title } });
5656
};
5757

@@ -81,7 +81,7 @@ export const deleteComponent = ({
8181
}) => (dispatch: (arg: Action) => void) => {
8282
// find all places where the "to be deleted" is a child and do what u gotta do
8383
stateComponents.forEach((parent: ComponentInt) => {
84-
parent.childrenArray
84+
parent.childrenArrayChildInt
8585
.filter((child: ChildInt) => child.childComponentId === componentId)
8686
.forEach((child: ChildInt) => {
8787
dispatch({
@@ -147,7 +147,7 @@ export const exportFiles = ({
147147
type: EXPORT_FILES
148148
});
149149
createFiles(components, path, appName, exportAppBool)
150-
.then((dir: string) =>
150+
.then((dir: any) =>
151151
dispatch({
152152
type: EXPORT_FILES_SUCCESS,
153153
payload: { status: true, dir: dir[0] }
@@ -194,7 +194,7 @@ export const createApplication = ({
194194
genOption: number;
195195
appName: string;
196196
exportAppBool: boolean;
197-
}) => (dispatch: (arg: Action) => void) => {
197+
}) => (dispatch: (arg: any) => void) => {
198198
if (genOption === 0) {
199199
exportAppBool = false;
200200
dispatch(

src/components/GrandchildRectangle.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@ import React, { Component } from "react";
22
import { Rect, Group } from "react-konva";
33
import { ComponentsInt, ComponentInt, ChildInt } from "../utils/Interfaces.ts";
44

5+
//////////////////////////////////////////////////////////////////////////////
6+
/////Logic in this component is mainly the same as Rectangle.tsx./////////////
7+
/////Not going to bother commenting too much in here for this reason./////////
8+
//////////////////////////////////////////////////////////////////////////////
9+
510
interface PropsInt {
611
x: number;
712
y: number;
@@ -45,6 +50,7 @@ class GrandchildRectangle extends Component<PropsInt, StateInt> {
4550
);
4651
}
4752

53+
//pretty sure this does nothing here because an image source is never passed down this deep...
4854
setImage = (imageSource: string): void => {
4955
if (!imageSource) return;
5056
const image = new window.Image();
@@ -75,7 +81,7 @@ class GrandchildRectangle extends Component<PropsInt, StateInt> {
7581
// the Rect emits changes to child width and height with help from Transformer
7682
return (
7783
<Group
78-
draggable={false}
84+
draggable={false} //this logic is necessary to make sure the user can't click on any grandchildren
7985
x={x}
8086
y={y}
8187
scaleX={scaleX}

src/components/KonvaStage.tsx

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,22 @@ interface PropsInt {
1212
image: HTMLImageElement;
1313
components: ComponentsInt;
1414
focusComponent: ComponentInt;
15-
selectableChildren: Array<number>;
15+
// selectableChildren: Array<number>; **It's expecting this prop in the interface, but is never used.**
1616
classes: any;
17-
addComponent: any;
18-
addChild: any;
19-
changeFocusComponent: any;
17+
// addComponent: any; **It's expecting this prop in the interface, but is never used.**
18+
// addChild: any; **It's expecting this prop in the interface, but is never used.**
19+
// changeFocusComponent: any; **It's expecting this prop in the interface, but is never used.**
2020
changeFocusChild: any;
21-
deleteComponent: any;
22-
createApp: any;
23-
deleteAllData: any;
21+
// deleteComponent: any; **It's expecting this prop in the interface, but is never used.**
22+
// createApp: any; **It's expecting this prop in the interface, but is never used.**
23+
// deleteAllData: any; **It's expecting this prop in the interface, but is never used.**
2424
handleTransform: any;
2525
focusChild: any;
2626
changeComponentFocusChild: any;
2727
deleteChild: any;
2828
scaleX: number;
2929
scaleY: number;
30-
draggable: boolean;
30+
// draggable: boolean; **THIS ONE is actually never passed down from the parent but reassigned in a seperate object below in this file.**
3131
}
3232

3333
interface StateInt {
@@ -41,6 +41,10 @@ interface StateInt {
4141
class KonvaStage extends Component<PropsInt, StateInt> {
4242
constructor(props: PropsInt) {
4343
super(props);
44+
//the main purpose of this state, although not supposed to be here per redux rules I believe,
45+
//is to initialize the values of the canvas height and width in pixels, and 'blockSnapSize' refers to
46+
//the height and width of the squares on the grid so it looks like graphing paper. The grid property doesn't do
47+
//anything, and the gridStroke is the stroke width of the squares.
4448
this.state = {
4549
stageWidth: 1800,
4650
stageHeight: 1300,
@@ -50,17 +54,21 @@ class KonvaStage extends Component<PropsInt, StateInt> {
5054
};
5155
}
5256

57+
//makes a copy of the array of children plus the parent component pushed onto it
5358
getDirectChildrenCopy(focusComponent: ComponentInt) {
59+
//assign component to the docused component
5460
const component = this.props.components.find(
5561
(comp: ComponentInt) => comp.id === focusComponent.id
5662
);
57-
63+
//assign childrenArr to an array of all the children of focused component
5864
const childrenArr = component.childrenArray.filter(
5965
(child: ChildInt) => child.childId !== -1
6066
);
6167

68+
//deep clone of childrenArr so addition of parent doesn't mutate the children saved in the state
6269
let childrenArrCopy = cloneDeep(childrenArr);
6370

71+
//adds a pseudochild witrh the parent component's property to the copied children array
6472
const pseudoChild = {
6573
childId: -1,
6674
childComponentId: component.id,
@@ -75,9 +83,11 @@ class KonvaStage extends Component<PropsInt, StateInt> {
7583
color: component.color
7684
};
7785
childrenArrCopy = childrenArrCopy.concat(pseudoChild); // could just use push here, concat needlessly generate new array
86+
//returns that new childrenArr + parent component
7887
return childrenArrCopy;
7988
}
8089

90+
//currently, only the handlekeydown event listener does anything.
8191
componentDidMount() {
8292
this.checkSize();
8393
// here we should add listener for "container" resize
@@ -88,11 +98,14 @@ class KonvaStage extends Component<PropsInt, StateInt> {
8898
this.createGrid();
8999
}
90100

101+
// I wonder if this lifecycle method is necessary. When I remove it,
102+
//I can't find any noticable changes. Possibly to prevent memory leaks?
91103
componentWillUnmount() {
92104
window.removeEventListener("resize", this.checkSize);
93105
this.container.removeEventListener("keydown", this.handleKeyDown);
94106
}
95107

108+
//something about the logic here isn't working. Will need to check some other time.
96109
checkSize = () => {
97110
const width = this.container.offsetWidth;
98111
const height = this.container.offsetHeight;
@@ -131,7 +144,9 @@ class KonvaStage extends Component<PropsInt, StateInt> {
131144
childId: rectChildId
132145
});
133146
};
134-
147+
//this function creates a grid with those 10x10 squares.
148+
//it first draws a grid or horizaontal lines, and then
149+
//draws the vertical ones.
135150
createGrid = () => {
136151
const output = [];
137152
for (let i = 0; i < this.state.stageWidth / this.state.blockSnapSize; i++) {
@@ -180,8 +195,8 @@ class KonvaStage extends Component<PropsInt, StateInt> {
180195
handleTransform,
181196
focusComponent,
182197
focusChild,
183-
deleteChild,
184-
classes
198+
// deleteChild, **neither of these are read**
199+
// classes
185200
} = this.props;
186201

187202
return (
@@ -211,6 +226,8 @@ class KonvaStage extends Component<PropsInt, StateInt> {
211226
}}
212227
>
213228
{this.state.grid}
229+
{/* {The logic hereis that it creates a new rectangle or each component that belongs to this parent component, plus the parent component.
230+
The parent component is rendered last. It renders based on the values in the return value of getDirectChildrenCopy. } */}
214231
{!isEmpty(focusComponent) && this.getDirectChildrenCopy(focusComponent)
215232
.map((child: ChildInt, i: number) => (
216233
<Rectangle

src/components/Rectangle.tsx

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -29,30 +29,51 @@ interface PropsInt {
2929

3030

3131
class Rectangle extends Component<PropsInt> {
32-
32+
//This assigns the color to the Rect based on componentId's color in the state
3333
getComponentColor(componentId: number) {
3434
const color = this.props.components.find(
3535
(comp: ComponentInt) => comp.id === componentId
3636
).color;
3737
return color;
3838
}
3939

40+
//this grabs the component ID of the child component when in the parent component's display mode
41+
//named pseudochild because it isn't saved as a child in the childrenArray.
4042
getPseudoChild() {
4143
return this.props.components.find(
4244
(comp: ComponentInt) => comp.id === this.props.childComponentId
4345
);
4446
}
4547

48+
//resize function
4649
handleResize(componentId: number, childId: number, target: Konva.Group, blockSnapSize: number) {
50+
//find the id of the component where the componentID in the state equals the currently focused component
51+
//and then find the numberID for that component
52+
//So, this would be assigning "Container 1", with component ID being whatever the ID for "Container" is
53+
//and 1 being the child ID
4754
let focChild: ChildInt | ComponentInt = this.props.components
4855
.find((comp: ComponentInt) => comp.id === this.props.componentId)
4956
.childrenArray.find((child: ChildInt) => child.childId === childId);
5057

58+
//If this is the parent component, it would not have a childID (hence -1), so it just would assign the forChild
59+
//variable to the parent.
5160
if (childId === -1) {
5261
focChild = this.props.components.find(
5362
(comp: ComponentInt) => comp.id === this.props.componentId
5463
);
5564
}
65+
66+
//The math here is easier than it looks
67+
//Basically, the height and width is first rounded up to a whole number (behind the whole snapping phenomenon)
68+
//after scaling it by multiplying it by scaleX/Y (height and width are the original height and width, the scale is the CHANGE in w/h),
69+
//dividing it by the 'snapsize' or grid unit area (which is 10x10 for this entire application) and re-multiplied by
70+
//that same snapsize. I'm not entirely sure why this had to be divided before the rounding, and re-multiplied,
71+
//since having positions that aren't a whole number doesn't seem to be that big of a deal.
72+
73+
//So there's a bit of redundancy in the x and y info. target.x() or y() only log the CHANGE of position of the Rect component.
74+
//Since when you change the width or height of the component you do not change the actual position, the
75+
//value for x an y dispatched to the action creator will always be the same as the current x,y position, unless you can somehow
76+
//resize AND reposition at the same time.
5677
const transformation = {
5778
width:
5879
Math.round((target.width() * target.scaleX()) / blockSnapSize) *
@@ -66,6 +87,8 @@ class Rectangle extends Component<PropsInt> {
6687
this.props.handleTransform(componentId, childId, transformation);
6788
}
6889

90+
//mostly the same logic as above, just grabbing the change in position for the focused child and sending it
91+
//to the action creator.
6992
handleDrag(componentId: number, childId: number, target: Konva.Group, blockSnapSize: number) {
7093
const transformation = {
7194
x: Math.round(target.x() / blockSnapSize) * blockSnapSize,
@@ -108,15 +131,15 @@ class Rectangle extends Component<PropsInt> {
108131
onDragEnd={event =>
109132
this.handleDrag(componentId, childId, event.target, blockSnapSize)
110133
}
111-
ref={node => {
134+
ref={node => { //this refference actually isn't doing anything since it isn't within the transformer component
112135
this.group = node;
113136
}}
114137
tabIndex='0' // required for keypress event to be heard by this.group
115138
>
116-
<Rect
139+
<Rect //basically the entire canvas
117140
// a Konva Rect is generated for each child of the focusComponent (including the pseudochild, representing the focusComponent itself)
118141
ref={node => {
119-
this.rect = node;
142+
this.rect = node; //same as above, the reference isn't assigned or pointing to anything
120143
}}
121144
tabIndex='0' // required for keypress event to be heard by this.group
122145
name={`${childId}`}
@@ -133,45 +156,45 @@ class Rectangle extends Component<PropsInt> {
133156
stroke={
134157
childType === 'COMP'
135158
? this.getComponentColor(childComponentId)
136-
: '#000000'
159+
: '#000000' //sets the parent component color to black
137160
}
138161
onTransformEnd={event =>
139162
this.handleResize(componentId, childId, event.target, blockSnapSize)
140163
}
141-
strokeWidth={childType === 'COMP' ? 4 : 2}
164+
strokeWidth={childType === 'COMP' ? 4 : 2}
142165
strokeScaleEnabled={false}
143166
draggable={false}
144167
fill={null}
145168
shadowBlur={childId === -1 ? 6 : null}
146169
fillPatternImage={childId === -1 ? this.props.image : null} //spooky addition, image if uploaded will only be background of App component
147-
fillPatternScaleX={this.props.image ? width / this.props.image.width : 1}
148-
fillPatternScaleY={this.props.image? height / this.props.image.height : 1}
170+
fillPatternScaleX={this.props.image ? width / this.props.image.width : 1} //here we are making sure the width of the image will stretch of shrink
171+
fillPatternScaleY={this.props.image? height / this.props.image.height : 1} //based on the width or height of the App component
149172
_useStrictMode
150173
/>
151174
<Label>
152-
<Text
175+
<Text //this is just the text that goes above each Rect,
153176
fontStyle={'bold'}
154177
fontVariant={'small-caps'}
155178
// pseudochild's label should look different than normal children:
156-
text={childId === -1 ? title.slice(0, title.length - 2) : title}
179+
text={childId === -1 ? title.slice(0, title.length - 2) : title} //slices the number off of the title of the top component
157180
fill={
158181
childId === -1
159182
? this.getComponentColor(childComponentId)
160-
: '#000000'
183+
: '#000000' //opposite logic of the stroke
161184
}
162185
fontSize={childId === -1 ? 15 : 10}
163186
x={4}
164187
y={childId === -1 ? -20 : -12}
165188
/>
166189
</Label>
167190
{// for all children other than the pseudoChild, find their component's children array and recursively render the children found there
168-
childId !== -1 &&
169-
childType === 'COMP' &&
170-
components
191+
childId !== -1 && //inline conditional to check if a child exists
192+
childType === 'COMP' && //inline conditional to see if the child is a component, not an HTML element
193+
components //map all 'grandchildren' in the child on display to this new component
171194
.find((comp: ComponentInt) => comp.title === childComponentName)
172195
.childrenArray.filter((child: ChildInt) => child.childId !== -1)
173196
.map((grandchild: ChildInt, i: number) => (
174-
<GrandchildRectangle
197+
<GrandchildRectangle
175198
key={i}
176199
components={components}
177200
componentId={componentId}
@@ -181,15 +204,15 @@ class Rectangle extends Component<PropsInt> {
181204
childComponentId={grandchild.childComponentId}
182205
focusChild={focusChild}
183206
childId={childId} // scary addition, grandchildren rects default to childId of "direct" children
184-
width={
207+
width={ //this is the logic used to display the grandchildren with proper scaling based on the parent (technically child) h/w
185208
grandchild.position.width *
186209
(width / this.getPseudoChild().position.width)
187210
}
188211
height={
189212
grandchild.position.height *
190213
(height / this.getPseudoChild().position.height)
191214
}
192-
x={
215+
x={ //similar logic to above
193216
(grandchild.position.x - this.getPseudoChild().position.x) *
194217
(width / this.getPseudoChild().position.width)
195218
}
@@ -199,7 +222,7 @@ class Rectangle extends Component<PropsInt> {
199222
}
200223
/>
201224
))}
202-
{focusChild && focusChild.childId === childId && draggable && (
225+
{focusChild && focusChild.childId === childId && draggable && ( //this conditional logic binds the transformer to the focused child, and Draggable is checked to make sure grandchildren can't be selected
203226
<TransformerComponent //This is the component that binds the Rect nodes to the Transformer node so they can be resized.
204227
focusChild={focusChild}
205228
rectClass={'childRect'}

0 commit comments

Comments
 (0)