diff --git a/src/components/editors/EditorPanel/index.tsx b/src/components/editors/EditorPanel/index.tsx index 6cc3faca..e34da5ff 100644 --- a/src/components/editors/EditorPanel/index.tsx +++ b/src/components/editors/EditorPanel/index.tsx @@ -1,6 +1,6 @@ import React, { FC } from 'react'; import * as styles from './styles.scss'; -import { INode, IFileWithUUID } from '~/redux/types'; +import { INode } from '~/redux/types'; interface IProps { data: INode; diff --git a/src/components/editors/ImageEditor/index.tsx b/src/components/editors/ImageEditor/index.tsx index 9265fcd7..63e9b340 100644 --- a/src/components/editors/ImageEditor/index.tsx +++ b/src/components/editors/ImageEditor/index.tsx @@ -7,6 +7,7 @@ import { connect } from 'react-redux'; import { selectUploads } from '~/redux/uploads/selectors'; import assocPath from 'ramda/es/assocPath'; import append from 'ramda/es/append'; +import { ImageUpload } from '~/components/upload/ImageUpload'; const mapStateToProps = selectUploads; const mapDispatchToProps = { @@ -100,7 +101,25 @@ const ImageEditorUnconnected: FC = ({ data, setData, uploadUploadFiles, return (
-
{data.type}
+ { + data.files.map(file => ( + + )) + } + { + temp.map(id => ( + statuses[id] && ( + + ) + )) + } + ); diff --git a/src/components/input/ArcProgress/index.tsx b/src/components/input/ArcProgress/index.tsx new file mode 100644 index 00000000..ea515e8a --- /dev/null +++ b/src/components/input/ArcProgress/index.tsx @@ -0,0 +1,22 @@ +import React, { FC } from 'react'; +import * as styles from './styles.scss'; +import { describeArc } from '~/utils/dom'; + +interface IProps { + size: number; + progress: number; +}; + +export const ArcProgress: FC = ({ size, progress }) => ( + + + +); diff --git a/src/components/input/ArcProgress/styles.scss b/src/components/input/ArcProgress/styles.scss new file mode 100644 index 00000000..7f216069 --- /dev/null +++ b/src/components/input/ArcProgress/styles.scss @@ -0,0 +1,8 @@ +.icon { + fill: $red; + stroke: none; + + //path { + // transition: d 0.5s; + //} +} diff --git a/src/components/upload/ImageUpload/index.tsx b/src/components/upload/ImageUpload/index.tsx new file mode 100644 index 00000000..c29bd2b4 --- /dev/null +++ b/src/components/upload/ImageUpload/index.tsx @@ -0,0 +1,30 @@ +import React, { FC } from 'react'; +import * as styles from './styles.scss'; +import classNames from 'classnames'; +import { ArcProgress } from '~/components/input/ArcProgress'; + +interface IProps { + id?: string; + thumb?: string; + progress?: number; + + is_uploading?: boolean; +}; + +const ImageUpload: FC = ({ + thumb, + id, + progress, + is_uploading, +}) => { + return ( +
+
+ {thumb &&
} + {is_uploading &&
} +
+
+ ); +} + +export { ImageUpload }; \ No newline at end of file diff --git a/src/components/upload/ImageUpload/styles.scss b/src/components/upload/ImageUpload/styles.scss new file mode 100644 index 00000000..b9888e0b --- /dev/null +++ b/src/components/upload/ImageUpload/styles.scss @@ -0,0 +1,52 @@ +.wrap { + background: lighten($content_bg, 4%); + padding-bottom: 100%; + border-radius: $radius; + position: relative; +} + +.thumb_wrap { + position: absolute; + width: 100%; + height: 100%; + z-index: 1; + border-radius: $radius; + overflow: hidden; + + &:global(.is_uploading) { + .thumb { + filter: blur(16px); + } + } +} + +.thumb { + position: absolute; + width: 100%; + height: 100%; + z-index: 1; + top: 0; + left: 0; + border-radius: $radius; + background: no-repeat 50% 50%; + background-size: cover; +} + +.progress { + position: absolute; + width: 100%; + height: 100%; + z-index: 2; + top: 0; + left: 0; + display: flex; + align-items: center; + justify-content: center; + background: transparentize(black, 0.5); + + svg { + fill: none; + // stroke: white + fill: white; + } +} \ No newline at end of file diff --git a/src/redux/node/reducer.ts b/src/redux/node/reducer.ts index 239e4e95..1e844b44 100644 --- a/src/redux/node/reducer.ts +++ b/src/redux/node/reducer.ts @@ -1,7 +1,9 @@ import { createReducer } from "~/utils/reducer"; import { INode } from "../types"; -import {EMPTY_BLOCK, EMPTY_NODE} from "./constants"; +import { EMPTY_BLOCK, EMPTY_NODE } from "./constants"; import { NODE_HANDLERS } from "./handlers"; +import { EMPTY_FILE } from "../uploads/constants"; +import uuid from 'uuid4'; export type INodeState = Readonly<{ is_loading: boolean; @@ -16,7 +18,8 @@ const INITIAL_STATE: INodeState = { type: 'image', blocks: [ { ...EMPTY_BLOCK, type: 'image' }, - ] + ], + files: [{ ...EMPTY_FILE, id: uuid() }, { ...EMPTY_FILE, id: uuid() }] }, is_loading: false, error: null, diff --git a/src/utils/dom.ts b/src/utils/dom.ts new file mode 100644 index 00000000..2845603a --- /dev/null +++ b/src/utils/dom.ts @@ -0,0 +1,41 @@ +export const getStyle = (oElm: any, strCssRule: string) => { + if (document.defaultView && document.defaultView.getComputedStyle) { + return document.defaultView.getComputedStyle(oElm, '').getPropertyValue(strCssRule); + } + + if (oElm.currentStyle) { + return oElm.currentStyle[strCssRule.replace(/-(\w)/g, (strMatch, p1) => p1.toUpperCase())]; + } + + return ''; +}; + +function polarToCartesian(centerX, centerY, radius, angleInDegrees) { + const angleInRadians = (angleInDegrees - 90) * Math.PI / 180.0; + + return { + x: centerX + (radius * Math.cos(angleInRadians)), + y: centerY + (radius * Math.sin(angleInRadians)), + }; +} + +export const describeArc = ( + x: number, + y: number, + radius: number, + startAngle: number = 0, + endAngle: number = 360, +): string => { + + const start = polarToCartesian(x, y, radius, endAngle); + const end = polarToCartesian(x, y, radius, startAngle); + + const largeArcFlag = endAngle - startAngle <= 180 ? 0 : 1; + + return [ + 'M', start.x, start.y, + 'A', radius, radius, 0, largeArcFlag, 0, end.x, end.y, + 'L', x, y, + 'L', start.x, start.y, + ].join(' '); +};