Skip to content

Commit

Permalink
Merge pull request #8 from tonyito/mvp
Browse files Browse the repository at this point in the history
Add/Remove Template Image Functionality Updated
  • Loading branch information
jzuniga206 authored Mar 10, 2020
2 parents 5b06f95 + 88e60d4 commit e51db57
Show file tree
Hide file tree
Showing 11 changed files with 214 additions and 52 deletions.
4 changes: 3 additions & 1 deletion src/actionTypes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,6 @@ export const ADD_PROP = 'ADD_PROP';
export const DELETE_ALL_DATA = 'DELETE_ALL_DATA';
export const CHANGE_IMAGE_PATH = 'CHANGE_IMAGE_PATH';
export const UPDATE_HTML_ATTR = 'UPDATE_HTML_ATTR';
export const UPDATE_CHILDREN_SORT = 'UPDATE_CHILDREN_SORT'
export const UPDATE_CHILDREN_SORT = 'UPDATE_CHILDREN_SORT';
export const CHANGE_IMAGE_SOURCE = 'CHANGE_IMAGE_SOURCE';
export const DELETE_IMAGE = 'DELETE_IMAGE';
13 changes: 13 additions & 0 deletions src/actions/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,19 @@ import {
DELETE_ALL_DATA,
UPDATE_HTML_ATTR,
UPDATE_CHILDREN_SORT,
CHANGE_IMAGE_SOURCE,
DELETE_IMAGE
} from '../actionTypes/index.js';

import { loadState } from '../localStorage';
import createFiles from '../utils/createFiles.util.ts';
import createApplicationUtil from '../utils/createApplication.util.ts';

export const changeImagePath = (imageSource: string) => ({
type: CHANGE_IMAGE_SOURCE,
payload: imageSource,
})

export const loadInitData = () => (dispatch: any) => {
loadState().then((data: any) => dispatch({
type: LOAD_INIT_DATA,
Expand Down Expand Up @@ -112,6 +119,12 @@ childId: number;
});
};

export const deleteImage = () => ({
type: DELETE_IMAGE,
payload: ''
})


export const exportFiles = ({
components,
path,
Expand Down
15 changes: 12 additions & 3 deletions src/components/KonvaStage.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
//This component includes a component for the background image to be uploaded as reference for drawing components
//and also the parent rectangle components.

import React, { Component } from "react";
import { Stage, Layer, Line } from "react-konva";
import { Stage, Layer, Line, Image } from "react-konva";
import Rectangle from "./Rectangle.tsx";
import cloneDeep from "../utils/cloneDeep.ts";
import { ComponentInt, ComponentsInt, ChildInt } from "../utils/Interfaces.ts";
import isEmpty from '../utils/isEmpty';

interface PropsInt {
image: HTMLImageElement;
components: ComponentsInt;
focusComponent: ComponentInt;
selectableChildren: Array<number>;
Expand Down Expand Up @@ -102,6 +107,7 @@ class KonvaStage extends Component<PropsInt, StateInt> {
}
};

//event handler to handle mouse click
handleStageMouseDown = (e: any) => {
// clicked on stage - clear selection
if (e.target === e.target.getStage()) {
Expand All @@ -116,7 +122,6 @@ class KonvaStage extends Component<PropsInt, StateInt> {

// find clicked rect by its name
const rectChildId = e.target.attrs.childId;
// console.log("user clicked on child rectangle with childId: ", rectChildId);
this.props.changeFocusChild({ childId: rectChildId });
this.props.changeComponentFocusChild({
componentId: this.props.focusComponent.id,
Expand Down Expand Up @@ -167,6 +172,7 @@ class KonvaStage extends Component<PropsInt, StateInt> {

render() {
const {
image,
components,
handleTransform,
focusComponent,
Expand Down Expand Up @@ -202,7 +208,10 @@ class KonvaStage extends Component<PropsInt, StateInt> {
}}
>
{this.state.grid}
{this.getDirectChildrenCopy(focusComponent)
<Image image={this.props.focusComponent.id === 1 ? image : null //only display background image if the focused component is <App>
} draggable width={this.state.stageWidth*0.8} height={this.state.stageHeight*0.9 } //for background image uploaded, fix to fit screen
/>
{!isEmpty(focusComponent) && this.getDirectChildrenCopy(focusComponent)
.map((child: ChildInt, i: number) => (
<Rectangle
childType={child.childType}
Expand Down
17 changes: 6 additions & 11 deletions src/components/Rectangle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ class Rectangle extends Component<PropsInt, StateInt> {
x: target.x() + focChild.position.x,
y: target.y() + focChild.position.y
};

this.props.handleTransform(componentId, childId, transformation);
}

Expand Down Expand Up @@ -166,17 +165,13 @@ class Rectangle extends Component<PropsInt, StateInt> {
strokeWidth={childType === 'COMP' ? 4 : 2}
strokeScaleEnabled={false}
draggable={false}
fill={childId === -1 ? 'white' : null}
fill={null}
shadowBlur={childId === -1 ? 6 : null}
fillPatternImage={
this.state.image ? this.state.image : this.setImage(imageSource)
}
fillPatternScaleX={
this.state.image ? width / this.state.image.width : 1
}
fillPatternScaleY={
this.state.image ? height / this.state.image.height : 1
}

fillPatternImage={this.state.image ? this.state.image : null}
fillPatternScaleX={this.state.image ? width / this.state.image.width : 1}
fillPatternScaleY={this.state.image ? height / this.state.image.height : 1}

_useStrictMode
/>
<Label>
Expand Down
100 changes: 78 additions & 22 deletions src/containers/AppContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,36 +1,94 @@
import React, { Component } from "react";
import { connect } from "react-redux";
import { MuiThemeProvider } from "@material-ui/core/styles";
import LinearProgress from "@material-ui/core/LinearProgress";
import LeftContainer from "./LeftContainer.tsx";
import MainContainer from "./MainContainer.tsx";
import theme from "../components/theme.ts";
import { loadInitData } from "../actions/components.ts";
import { ComponentInt, ComponentsInt } from "../utils/Interfaces.ts";
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { MuiThemeProvider } from '@material-ui/core/styles';
import LinearProgress from '@material-ui/core/LinearProgress';
import LeftContainer from './LeftContainer.tsx';
import MainContainer from './MainContainer.tsx';
import theme from '../components/theme.ts';
import { loadInitData } from '../actions/components.ts';
import { ComponentInt, ComponentsInt } from '../utils/Interfaces.ts';
import * as actions from '../actions/components';

// ** Used with electron to render
const IPC = require('electron').ipcRenderer;

type Props = {
imageSource: string;
components: ComponentsInt;
focusComponent: ComponentInt;
totalComponents: number;
loading: boolean;
selectableChildren: Array<number>;
loadInitData: any;
changeImagePath: any;
changed: boolean;
};

type State = {
image: HTMLImageElement | null;
width: number;
changed: boolean;
}

const mapStateToProps = (store: any) => ({
imageSource: store.workspace.imageSource,
components: store.workspace.components,
totalComponents: store.workspace.totalComponents,
focusComponent: store.workspace.focusComponent,
loading: store.workspace.loading,
selectableChildren: store.workspace.selectableChildren
});

const mapDispatchToProps = { loadInitData };
const mapDispatchToProps = (dispatch: any) => ({
loadInitData,
changeImagePath: (imageSource: string) => dispatch(actions.changeImagePath(imageSource)),
});

class AppContainer extends Component<Props, State> {

constructor(props: Props) {
super(props);
// ** state here to create a collapsable right column where bottom panel currently lives
this.state = {
image: null,
width: 25,
changed: false
};

class AppContainer extends Component<Props> {
state = {
width: 25,
rightColumnOpen: true
IPC.on('new-file', (event, file: string) => {
const image = new window.Image();
image.src = file;
image.onload = () => {
// update state when the image has been uploaded
this.props.changeImagePath(file);
this.setState({ image });
};
});
}

componentDidUpdate(prevProps: Props) {
const { imageSource } = this.props;
const {changed} = this.state;
if (imageSource == '' && changed) {
this.setState({...this.state, image:null, changed:false});

}
else if (imageSource !== prevProps.imageSource) {
this.setImage(imageSource);
}
}

setImage = (imageSource: string) => {
if (imageSource) {
let image: HTMLImageElement;
image = new window.Image();
image.src = imageSource;
image.onload = () => {
// setState will redraw layer
// because "image" property is changed
this.setState({ image, changed: true });
};
}
};

componentDidMount() {
Expand All @@ -57,13 +115,14 @@ class AppContainer extends Component<Props> {
focusComponent={focusComponent}
selectableChildren={selectableChildren}
/>
<MainContainer components={components} />
<MainContainer components={components} image={this.state.image}
imageSource={this.props.imageSource}/>
{loading ? (
<div
style={{
alignSelf: "flex-end",
position: "fixed",
width: "100%"
alignSelf: 'flex-end',
position: 'fixed',
width: '100%'
}}
>
<LinearProgress color="secondary" />
Expand All @@ -75,7 +134,4 @@ class AppContainer extends Component<Props> {
}
}

export default connect(
mapStateToProps,
mapDispatchToProps
)(AppContainer);
export default connect(mapStateToProps, mapDispatchToProps)(AppContainer);
53 changes: 49 additions & 4 deletions src/containers/LeftContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import cloneDeep from '../utils/cloneDeep.ts';
const IPC = require('electron').ipcRenderer;

interface PropsInt {
imageSource: string;
components: ComponentsInt;
focusComponent: ComponentInt;
selectableChildren: Array<number>;
Expand All @@ -32,6 +33,7 @@ interface PropsInt {
deleteComponent: any;
createApp: any;
deleteAllData: any;
deleteImage: any;
}

interface StateInt {
Expand All @@ -41,6 +43,10 @@ interface StateInt {
genOption: number;
}

const mapStateToProps = (store: any) => ({
imageSource: store.workspace.imageSource
});

const mapDispatchToProps = (dispatch: any) => ({
addComponent: ({ title }: { title: string }) =>
dispatch(actions.addComponent({ title })),
Expand All @@ -65,6 +71,7 @@ const mapDispatchToProps = (dispatch: any) => ({
stateComponents: ComponentsInt;
}) => dispatch(actions.deleteComponent({ componentId, stateComponents })),
deleteAllData: () => dispatch(actions.deleteAllData()),
deleteImage: () => dispatch(actions.deleteImage()),
createApp: ({
path,
components,
Expand Down Expand Up @@ -98,7 +105,8 @@ class LeftContainer extends Component<PropsInt, StateInt> {
'Export components',
'Export components with application files'
],
genOption: 0
genOption: 0.,
imageSource: this.props.imageSource
};

IPC.on('app_dir_selected', (event: any, path: string) => {
Expand Down Expand Up @@ -155,7 +163,10 @@ class LeftContainer extends Component<PropsInt, StateInt> {
this.chooseAppDir();
};

chooseAppDir = () => IPC.send('choose_app_dir');

chooseAppDir = () => IPC.send("choose_app_dir");
addImage = () => IPC.send('update-file');


showGenerateAppModal = () => {
const { closeModal, chooseGenOptions } = this;
Expand Down Expand Up @@ -194,14 +205,16 @@ class LeftContainer extends Component<PropsInt, StateInt> {

render(): JSX.Element {
const {
imageSource,
components,
deleteComponent,
focusComponent,
classes,
addChild,
changeFocusComponent,
changeFocusChild,
selectableChildren
selectableChildren,
deleteImage
} = this.props;
const { componentName, modal } = this.state;

Expand All @@ -222,6 +235,7 @@ class LeftContainer extends Component<PropsInt, StateInt> {
components={components}
/>
));
const { addImage, clearImage } = this;

return (
<div className='column left'>
Expand Down Expand Up @@ -292,6 +306,32 @@ class LeftContainer extends Component<PropsInt, StateInt> {
flexDirection: 'column'
}}
>
{
imageSource ? (
<Button
aria-label="Remove Image"
variant="contained"
fullWidth
onClick={deleteImage
}
className={classes.clearButton}
style={{ borderRadius: 0, top: 0, backgroundColor: '#dc004e', color: '#fff' }}
>
Remove Image
</Button>
) : (
<Button
aria-label="Upload Image"
variant="contained"
fullWidth
onClick={addImage}
className={classes.clearButton}
style={{ borderRadius: 0, top: 0, backgroundColor: '#dc004e', color: '#fff' }}
>
Upload Image
</Button>
)
}
<Button
color='secondary'
aria-label='Delete All'
Expand Down Expand Up @@ -376,5 +416,10 @@ function styles(): any {

export default compose(
withStyles(styles),
connect(null, mapDispatchToProps)

connect(
mapStateToProps,
mapDispatchToProps
)

)(LeftContainer);
Loading

0 comments on commit e51db57

Please sign in to comment.