Skip to content

Commit

Permalink
Merge pull request #21 from projectstorm/feature_loading
Browse files Browse the repository at this point in the history
Add loading spinners in more places + click on the canvas where u want to paste images
  • Loading branch information
dylanvorster authored Jul 4, 2023
2 parents 95b8c93 + 594d462 commit e80d6aa
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 26 deletions.
23 changes: 21 additions & 2 deletions tornado-frontend/src/routes/content/ImageCropPage.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import * as React from 'react';
import { createRef, useEffect, useState } from 'react';
import styled from '@emotion/styled';
import { useAuthenticated } from '../../hooks/useAuthenticated';
import { useSystem } from '../../hooks/useSystem';
import { generatePath, useNavigate, useParams } from 'react-router-dom';
Expand All @@ -11,6 +10,8 @@ import 'cropperjs/dist/cropper.css';
import { ButtonType, ButtonWidget } from '../../widgets/forms/ButtonWidget';
import { Routing } from '../routes';
import * as _ from 'lodash';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { styled } from '../../theme/theme';

export const ImageCropPage: React.FC = observer((props) => {
const system = useSystem();
Expand All @@ -29,7 +30,11 @@ export const ImageCropPage: React.FC = observer((props) => {
const cropperRef = createRef<ReactCropperElement>();

if (!mediaUrl) {
return null;
return (
<S.Loader>
<S.Icon icon="spinner" spin={true} />
</S.Loader>
);
}

return (
Expand Down Expand Up @@ -58,6 +63,7 @@ export const ImageCropPage: React.FC = observer((props) => {
<S.Button
type={ButtonType.PRIMARY}
label="Crop"
icon="crop"
action={async () => {
const data = cropperRef.current.cropper.getData();
await system.client.mediaCrop({
Expand Down Expand Up @@ -101,6 +107,19 @@ export const ImageCropPage: React.FC = observer((props) => {
);
});
namespace S {
export const Icon = styled(FontAwesomeIcon)`
color: ${(p) => p.theme.text.description};
font-size: 50px;
`;

export const Loader = styled.div`
display: flex;
align-items: center;
justify-content: center;
height: 100%;
width: 100%;
`;

export const Container = styled.div`
box-sizing: border-box;
padding: 10px;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { ConceptBoardModel } from '../../../../stores/ConceptsStore';
import * as _ from 'lodash';
import { ImageElement } from './image-element/ImageElementFactory';
import { action } from 'mobx';
import { FileData } from '@projectstorm/tornado-common';
import { ControlsLayerModel } from './controls-layer/ControlsLayerFactory';

export class ConceptCanvasModel extends CanvasModel {
Expand Down Expand Up @@ -32,13 +31,9 @@ export class ConceptCanvasModel extends CanvasModel {
this.model.setCanvasData(this.serialize());
}, 500);

addImage(data: FileData) {
const element = new ImageElement(data.id);

const size = 500;
element.width = size;
element.height = (size / data.width) * data.height;

addImage() {
const element = new ImageElement();
this.getLayers()[0].addModel(element);
return element;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from 'react';
import { useEffect, useState } from 'react';
import styled from '@emotion/styled';
import { CanvasWidget } from '@projectstorm/react-canvas-core';
import { Action, CanvasWidget, InputType } from '@projectstorm/react-canvas-core';
import { ConceptBoardModel } from '../../../../stores/ConceptsStore';
import { ConceptCanvasEngine } from './ConceptCanvasEngine';
import { ConceptCanvasModel } from './ConceptCanvasModel';
Expand All @@ -17,21 +17,38 @@ export const ConceptCanvasWidget: React.FC<ConceptCanvasWidgetProps> = (props) =
const [engine] = useState(() => {
return new ConceptCanvasEngine();
});
const [position, setPosition] = useState<React.MouseEvent>(null);

usePasteMedia({
gotMedia: (files) => {
files.forEach(async (file) => {
const media = await system.clientMedia.uploadMedia(file);
const element = engine.getModel().addImage();
if (position) {
element.setPosition(engine.getRelativeMousePoint(position));
}
engine.repaintCanvas();
media.registerListener({
finished: (data) => {
engine.getModel().addImage(data);
element.update(data);
engine.repaintCanvas();
}
});
});
}
});

useEffect(() => {
return engine.getActionEventBus().registerAction(
new Action({
type: InputType.MOUSE_DOWN,
fire: ({ event }) => {
setPosition(event as React.MouseEvent);
}
})
);
});

useEffect(() => {
const model = new ConceptCanvasModel(props.board);
model.load(engine);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,33 @@ import {
} from '@projectstorm/react-canvas-core';
import { ImageElementWidget } from './ImageElementWidget';
import { ImageLayerModel } from '../image-layer/ImageLayerFactory';
import { FileData } from '@projectstorm/tornado-common';

export class ImageElement extends BasePositionModel {
public width: number;
public height: number;

constructor(public imageID: number) {
constructor(public imageID: number = null) {
super({
type: ImageElementFactory.TYPE
});
this.width = 200;
this.height = 200;
this.setPosition(100, 100);
this.setLocked(false);
this.width = null;
this.height = null;
}

getCanvasModel() {
return (this.getParent() as ImageLayerModel).getParent();
}

update(data: FileData) {
const size = 500;
this.imageID = data.id;
this.width = size;
this.height = (size / data.width) * data.height;
}

serialize() {
return {
...super.serialize(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { MediaSize } from '@projectstorm/tornado-common';
import { ImageElement } from './ImageElementFactory';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { styled } from '../../../../../theme/theme';
import { MediaObject } from '../../../../../client/MediaClient';

export interface ResponseImageWidgetProps {
className?: any;
Expand All @@ -13,12 +14,17 @@ export interface ResponseImageWidgetProps {

export const ResponseImageWidget: React.FC<ResponseImageWidgetProps> = (props) => {
const system = useSystem();
const [object] = useState(() => {
return system.clientMedia.getMediaObject(props.model.imageID);
});
const [object, setObject] = useState<MediaObject>(null);
const [url, setUrl] = useState<string>(null);
const [size, setSize] = useState<MediaSize>();

useEffect(() => {
if (!props.model.imageID) {
return;
}
setObject(system.clientMedia.getMediaObject(props.model.imageID));
}, [props.model.imageID]);

useEffect(() => {
const compute = (zoom: number) => {
if (zoom < 15) {
Expand All @@ -41,10 +47,10 @@ export const ResponseImageWidget: React.FC<ResponseImageWidgetProps> = (props) =
}, []);

useEffect(() => {
if (size) {
if (object && size) {
object.getURL(size).then(setUrl);
}
}, [size]);
}, [object, size]);

if (!url) {
return (
Expand All @@ -63,17 +69,19 @@ namespace S {
font-size: 50px;
`;

export const Container = styled.div<{ url: string }>`
background-image: url('${(p) => p.url}');
background-repeat: no-repeat;
background-size: contain;
`;

export const Loader = styled.div`
display: flex;
align-items: center;
justify-content: center;
background: ${(p) => p.theme.editor.stripes};
border-radius: 5px;
width: 100%;
height: 100%;
`;

export const Container = styled.div<{ url: string }>`
background-image: url('${(p) => p.url}');
background-repeat: no-repeat;
background-size: contain;
`;
}

0 comments on commit e80d6aa

Please sign in to comment.