From 824752967a2325df1114c1debee5773f4a2919cc Mon Sep 17 00:00:00 2001 From: Bob Carmichael Date: Fri, 7 Jun 2024 16:43:39 -0400 Subject: [PATCH] max. file size; some cleanup --- TODO.md | 30 ---------- src/features/import/ImageUploader.js | 62 +++++++++++--------- src/features/layers/layersSlice.spec.js | 13 ++-- src/features/shapes/image_import/subtypes.js | 2 +- 4 files changed, 41 insertions(+), 66 deletions(-) diff --git a/TODO.md b/TODO.md index d0c69bc..8dbf745 100644 --- a/TODO.md +++ b/TODO.md @@ -1,6 +1,5 @@ ### TODO FOR RELEASE -- get rectangular preview image from Jeff - bug: wiper, 90 degrees with noise effect; change wiper size from 4 to 40, hangs browser - bug: edge-case optimization of pattern with inverted mask is adding a center point within the mask; workaround is to enable "minimize perimeter moves", but this isn't user-friendly obviously @@ -15,32 +14,3 @@ - store pattern name and other desired attribution (?) in exported file and display it somewhere (either stats tab or in the preview window) - show pattern start/end type (e.g., 1-0) if start/end if specified - new fine tuning setting: when backtracking at end, optionally ignore border if enabled - -## NEW IN 1.0.0 - -- User interface - - Layout improvements - - Can zoom in/out in the preview window. - - Can now click on a layer in the preview window to select the layer. - - Improved coloring and display layers and effects when they are selected and dragged to make editing more intuitive. -- Save and load patterns (new .sdf file format) - - Patterns can be saved and loaded from a file. - - Unsaved work is automatically preserved in the browser (can reload the page without losing work) -- Effects - - Effects are now displayed within their parent layer, and are no longer shown in the "layers" list. - - Track - - Improved settings make it easier to either "unwind" a single shape along a prescribed track, or position multiple shapes along a track. - - Fine tuning - - Percentages are based on overall length of the pattern, not number of vertices. Fractional values are supported. - - Fisheye - - Improved rendering when applied to shapes that have straight lines - - Transformer (new) - - New effect to allow resizing and rotation of a given layer -- Shapes - - Loop, scale, spin, and track transformers, as well as fine tuning settings, are now individual effects that can be added to a shape in any order, and are not added by default. - - New "maintain aspect ratio" setting, when enabled, forced a fixed aspect ratio. -- Machines - - Configure (add/remove/edit) multiple machines and switch between them. - - Machine settings from imported patterns are automatically saved as an "[Imported]" machine. -- Export - - Machine and shape settings are no longer added as comments to exported files in various formats. diff --git a/src/features/import/ImageUploader.js b/src/features/import/ImageUploader.js index 7f8b217..5f9701d 100644 --- a/src/features/import/ImageUploader.js +++ b/src/features/import/ImageUploader.js @@ -1,3 +1,4 @@ +import { toast } from "react-toastify" import React, { useEffect, useRef } from "react" import Form from "react-bootstrap/Form" import { useSelector, useDispatch } from "react-redux" @@ -18,42 +19,47 @@ const ImageUploader = ({ toggleModal, showModal }) => { const handleFileSelected = (event) => { const file = event.target.files[0] + const maxSize = 1024 * 1024 // 1 MB if (file) { - const reader = new FileReader() - reader.onload = (event) => { - const image = new Image() + if (file.size > maxSize) { + toast.error("This file is too large to import (maximum size 1 MB).") + } else { + const reader = new FileReader() + reader.onload = (event) => { + const image = new Image() - image.onload = () => { - const layerInstance = new Layer("imageImport") - const layerProps = { - machine: machineState, - width: image.width, - height: image.height, - } - const layer = { - ...layerInstance.getInitialState(layerProps), - imageFileName: file.name, - name: file.name, + image.onload = () => { + const layerInstance = new Layer("imageImport") + const layerProps = { + machine: machineState, + width: image.width, + height: image.height, + } + const layer = { + ...layerInstance.getInitialState(layerProps), + imageFileName: file.name, + name: file.name, + } + + dispatch( + addLayerWithImage({ + layer, + image: { + src: reader.result, + height: image.height, + width: image.width, + }, + }), + ) + inputRef.current.value = "" // reset to allow more uploads } - dispatch( - addLayerWithImage({ - layer, - image: { - src: reader.result, - height: image.height, - width: image.width, - }, - }), - ) - inputRef.current.value = "" // reset to allow more uploads + image.src = reader.result } - image.src = reader.result + reader.readAsDataURL(file) } - - reader.readAsDataURL(file) } } diff --git a/src/features/layers/layersSlice.spec.js b/src/features/layers/layersSlice.spec.js index 107ac03..bce2c7c 100644 --- a/src/features/layers/layersSlice.spec.js +++ b/src/features/layers/layersSlice.spec.js @@ -564,21 +564,20 @@ describe("layers reducer", () => { }) store.dispatch( - addLayerWithImage({ layer: { name: "layer" }, imageSrc: "SRC" }), + addLayerWithImage({ + layer: { name: "layer" }, + image: { src: "SRC" }, + }), ) const actions = store.getActions() + expect(actions[0].type).toEqual("images/addImage") expect(actions[0].payload).toEqual({ id: "1", src: "SRC", }) expect(actions[0].meta.id).toEqual("1") - expect(actions[1].type).toEqual("layers/addLayer") - expect(actions[1].payload).toEqual({ - id: "2", - name: "layer", - imageId: "1", - }) + expect(actions[1].type).toEqual("images/getImage/pending") }) }) }) diff --git a/src/features/shapes/image_import/subtypes.js b/src/features/shapes/image_import/subtypes.js index 7f1d31f..065e114 100644 --- a/src/features/shapes/image_import/subtypes.js +++ b/src/features/shapes/image_import/subtypes.js @@ -57,5 +57,5 @@ export const subtypes = { // some protection against bad data export const getSubtype = (subtype) => { - return subtypes[subtype] || subtypes['Squiggle'] + return subtypes[subtype] || subtypes["Squiggle"] }