Skip to content

Commit

Permalink
@uppy/image-editor: refactor to ESM (#3685)
Browse files Browse the repository at this point in the history
  • Loading branch information
aduh95 authored May 3, 2022
1 parent 447cd92 commit 4c81c21
Show file tree
Hide file tree
Showing 7 changed files with 172 additions and 149 deletions.
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ module.exports = {
'packages/@uppy/file-input/src/**/*.js',
'packages/@uppy/form/src/**/*.js',
'packages/@uppy/google-drive/src/**/*.js',
'packages/@uppy/image-editor/src/**/*.js',
'packages/@uppy/svelte/src/**/*.js',
'packages/@uppy/svelte/rollup.config.js',
'packages/@uppy/vue/src/**/*.js',
Expand Down
1 change: 1 addition & 0 deletions packages/@uppy/image-editor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"main": "lib/index.js",
"style": "dist/style.min.css",
"types": "types/index.d.ts",
"type": "module",
"keywords": [
"file uploader",
"upload",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
const CropperImport = require('cropperjs')
const { h, Component } = require('preact')
import CropperImport from 'cropperjs'
import { h, Component } from 'preact'

// @TODO A silly hack that we can get rid of when moving to ESM.
// @TODO A silly hack that we can get rid of when we start publishing ESM to the npm package.
// eslint-disable-next-line no-underscore-dangle
const Cropper = CropperImport.__esModule ? CropperImport.default : CropperImport

module.exports = class Editor extends Component {
export default class Editor extends Component {
constructor (props) {
super(props)
this.state = { rotationAngle: 0, rotationDelta: 0 }
Expand Down
144 changes: 144 additions & 0 deletions packages/@uppy/image-editor/src/ImageEditor.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import { UIPlugin } from '@uppy/core'
import { h } from 'preact'

import Editor from './Editor.jsx'
import packageJson from '../package.json'
import locale from './locale.js'

export default class ImageEditor extends UIPlugin {
static VERSION = packageJson.version

constructor (uppy, opts) {
super(uppy, opts)
this.id = this.opts.id || 'ImageEditor'
this.title = 'Image Editor'
this.type = 'editor'

this.defaultLocale = locale

const defaultCropperOptions = {
viewMode: 1,
background: false,
autoCropArea: 1,
responsive: true,
croppedCanvasOptions: {},
}

const defaultActions = {
revert: true,
rotate: true,
granularRotate: true,
flip: true,
zoomIn: true,
zoomOut: true,
cropSquare: true,
cropWidescreen: true,
cropWidescreenVertical: true,
}

const defaultOptions = {
quality: 0.8,
}

this.opts = {
...defaultOptions,
...opts,
actions: {
...defaultActions,
...opts.actions,
},
cropperOptions: {
...defaultCropperOptions,
...opts.cropperOptions,
},
}

this.i18nInit()
}

// eslint-disable-next-line class-methods-use-this
canEditFile (file) {
if (!file.type || file.isRemote) {
return false
}

const fileTypeSpecific = file.type.split('/')[1]

if (/^(jpe?g|gif|png|bmp|webp)$/.test(fileTypeSpecific)) {
return true
}

return false
}

save = () => {
const saveBlobCallback = (blob) => {
const { currentImage } = this.getPluginState()

this.uppy.setFileState(currentImage.id, {
data: blob,
size: blob.size,
preview: null,
})

const updatedFile = this.uppy.getFile(currentImage.id)
this.uppy.emit('thumbnail:request', updatedFile)
this.setPluginState({
currentImage: updatedFile,
})
this.uppy.emit('file-editor:complete', updatedFile)
}

const { currentImage } = this.getPluginState()

this.cropper.getCroppedCanvas(this.opts.cropperOptions.croppedCanvasOptions).toBlob(
saveBlobCallback,
currentImage.type,
this.opts.quality,
)
}

storeCropperInstance = (cropper) => {
this.cropper = cropper
}

selectFile = (file) => {
this.uppy.emit('file-editor:start', file)
this.setPluginState({
currentImage: file,
})
}

install () {
this.setPluginState({
currentImage: null,
})

const { target } = this.opts
if (target) {
this.mount(target, this)
}
}

uninstall () {
this.unmount()
}

render () {
const { currentImage } = this.getPluginState()

if (currentImage === null || currentImage.isRemote) {
return null
}

return (
<Editor
currentImage={currentImage}
storeCropperInstance={this.storeCropperInstance}
save={this.save}
opts={this.opts}
i18n={this.i18n}
/>
)
}
}
145 changes: 1 addition & 144 deletions packages/@uppy/image-editor/src/index.js
Original file line number Diff line number Diff line change
@@ -1,144 +1 @@
const { UIPlugin } = require('@uppy/core')
const { h } = require('preact')
const Editor = require('./Editor')

const locale = require('./locale.js')

module.exports = class ImageEditor extends UIPlugin {
// eslint-disable-next-line global-require
static VERSION = require('../package.json').version

constructor (uppy, opts) {
super(uppy, opts)
this.id = this.opts.id || 'ImageEditor'
this.title = 'Image Editor'
this.type = 'editor'

this.defaultLocale = locale

const defaultCropperOptions = {
viewMode: 1,
background: false,
autoCropArea: 1,
responsive: true,
croppedCanvasOptions: {},
}

const defaultActions = {
revert: true,
rotate: true,
granularRotate: true,
flip: true,
zoomIn: true,
zoomOut: true,
cropSquare: true,
cropWidescreen: true,
cropWidescreenVertical: true,
}

const defaultOptions = {
quality: 0.8,
}

this.opts = {
...defaultOptions,
...opts,
actions: {
...defaultActions,
...opts.actions,
},
cropperOptions: {
...defaultCropperOptions,
...opts.cropperOptions,
},
}

this.i18nInit()
}

// eslint-disable-next-line class-methods-use-this
canEditFile (file) {
if (!file.type || file.isRemote) {
return false
}

const fileTypeSpecific = file.type.split('/')[1]

if (/^(jpe?g|gif|png|bmp|webp)$/.test(fileTypeSpecific)) {
return true
}

return false
}

save = () => {
const saveBlobCallback = (blob) => {
const { currentImage } = this.getPluginState()

this.uppy.setFileState(currentImage.id, {
data: blob,
size: blob.size,
preview: null,
})

const updatedFile = this.uppy.getFile(currentImage.id)
this.uppy.emit('thumbnail:request', updatedFile)
this.setPluginState({
currentImage: updatedFile,
})
this.uppy.emit('file-editor:complete', updatedFile)
}

const { currentImage } = this.getPluginState()

this.cropper.getCroppedCanvas(this.opts.cropperOptions.croppedCanvasOptions).toBlob(
saveBlobCallback,
currentImage.type,
this.opts.quality,
)
}

storeCropperInstance = (cropper) => {
this.cropper = cropper
}

selectFile = (file) => {
this.uppy.emit('file-editor:start', file)
this.setPluginState({
currentImage: file,
})
}

install () {
this.setPluginState({
currentImage: null,
})

const { target } = this.opts
if (target) {
this.mount(target, this)
}
}

uninstall () {
this.unmount()
}

render () {
const { currentImage } = this.getPluginState()

if (currentImage === null || currentImage.isRemote) {
return null
}

return (
<Editor
currentImage={currentImage}
storeCropperInstance={this.storeCropperInstance}
save={this.save}
opts={this.opts}
i18n={this.i18n}
/>
)
}
}
export { default } from './ImageEditor.jsx'
2 changes: 1 addition & 1 deletion packages/@uppy/image-editor/src/locale.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module.exports = {
export default {
strings: {
revert: 'Revert',
rotate: 'Rotate',
Expand Down
20 changes: 20 additions & 0 deletions website/src/docs/image-editor.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,23 @@ uppy.on('file-editor:complete', (updatedFile) => {
console.log(updatedFile)
})
```

### `locale: {}`

<!-- eslint-disable no-restricted-globals, no-multiple-empty-lines -->

```js
export default {
strings: {
revert: 'Revert',
rotate: 'Rotate',
zoomIn: 'Zoom in',
zoomOut: 'Zoom out',
flipHorizontal: 'Flip horizontal',
aspectRatioSquare: 'Crop square',
aspectRatioLandscape: 'Crop landscape (16:9)',
aspectRatioPortrait: 'Crop portrait (9:16)',
},
}

```

0 comments on commit 4c81c21

Please sign in to comment.