Skip to content

Commit

Permalink
Merge pull request #301 from tropy/feature/selection-thumbnails
Browse files Browse the repository at this point in the history
Selection thumbnails
  • Loading branch information
inukshuk committed Nov 22, 2018
2 parents 286a0bc + bd5810b commit c9c34ae
Show file tree
Hide file tree
Showing 13 changed files with 126 additions and 79 deletions.
26 changes: 13 additions & 13 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
"chai-as-promised": "^7.1.1",
"chokidar": "^2.0.4",
"devtron": "^1.0.0",
"electron": "^3.0.9",
"electron": "^3.0.10",
"electron-devtools-installer": "^2.2.4",
"electron-mocha": "^6.0.4",
"electron-packager": "^12.2.0",
Expand Down Expand Up @@ -129,7 +129,7 @@
"winreg": "^1.2.4",
"winston": "^2.4.4",
"write-file-atomic": "^2.3.0",
"yargs": "^12.0.4"
"yargs": "^12.0.5"
},
"yargs": {
"short-option-groups": false
Expand Down
33 changes: 9 additions & 24 deletions src/commands/import.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,23 @@ const mod = require('../models')
const act = require('../actions')
const { warn, verbose } = require('../common/log')
const { prompt } = require('../dialog')
const MIME = require('../constants/mime')


class ImportCommand extends Command {
*createThumbnails(id, image, { overwrite = true, quality = 100 } = {}) {
*createThumbnails(id, image, {
overwrite = true,
quality = 100,
selection
} = {}) {
try {
let { cache } = this.options
let ext = imageExt(image.mimetype)

for (let size of SIZE.get(image.mimetype)) {
let path = imagePath(id, size, ext)
for (let v of image.variants(selection != null)) {
let path = imagePath(id, v.name, ext)

if (overwrite || !(yield call(cache.exists, path))) {
let dup = image.resize(SIZE[size])
let dup = image.resize(v.size, selection)

switch (ext) {
case '.png':
Expand All @@ -40,7 +43,7 @@ class ImportCommand extends Command {
yield call([dup, dup.toFile], cache.expand(path))

} else {
verbose(`Skipping ${size} thumbnail for #${id}: already exists`)
verbose(`Skipping ${v.name} thumbnail for #${id}: already exists`)
}
}
} catch (error) {
Expand Down Expand Up @@ -93,24 +96,6 @@ class ImportCommand extends Command {
}
}

const SIZE = {
48: {
width: 48, height: 48, fit: 'cover', position: 'center'
},

512: {
width: 512, height: 512, fit: 'cover', position: 'center'
},

get(mimetype) {
switch (mimetype) {
case MIME.TIFF:
return [48, 512, 'full']
default:
return [48, 512]
}
}
}



Expand Down
16 changes: 13 additions & 3 deletions src/commands/photo.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@ class Consolidate extends ImportCommand {
let { payload, meta } = this.action
let consolidated = []

let [project, photos] = yield select(state => [
let [project, photos, selections] = yield select(state => [
state.project,
blank(payload) ? values(state.photos) : pluck(state.photos, payload)
blank(payload) ? values(state.photos) : pluck(state.photos, payload),
state.selections
])

for (let i = 0, total = photos.length; i < total; ++i) {
Expand Down Expand Up @@ -61,7 +62,16 @@ class Consolidate extends ImportCommand {
overwrite: hasChanged
})

const data = { id: photo.id, ...image.toJSON() }
for (let id of photo.selections) {
if (id in selections) {
yield* this.createThumbnails(id, image, {
overwrite: hasChanged,
selection: selections[id]
})
}
}

let data = { id: photo.id, ...image.toJSON() }

yield call(mod.photo.save, db, data, project)
yield put(act.photo.update({
Expand Down
33 changes: 18 additions & 15 deletions src/commands/selection.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,37 @@

const { call, put, select } = require('redux-saga/effects')
const { Command } = require('./command')
const { ImportCommand } = require('./import')
const { Image } = require('../image')
const mod = require('../models')
const act = require('../actions')
const { SELECTION } = require('../constants')
const { pick, splice } = require('../common/util')
const { keys } = Object


class Create extends Command {
class Create extends ImportCommand {
static get ACTION() { return SELECTION.CREATE }

*exec() {
const { db } = this.options
const { payload, meta } = this.action
let { db } = this.options
let { payload, meta } = this.action

const idx = (meta.idx != null) ? meta.idx : [
yield select(state => state.photos[payload.photo].selections.length)
]
let photo = yield select(state => state.photos[payload.photo])
let image = yield call(Image.open, photo.path, photo.page)
let idx = (meta.idx != null) ? meta.idx : [photo.selections.length]

const selection = yield call(db.transaction, tx =>
let selection = yield call(db.transaction, tx =>
mod.selection.create(tx, null, payload))

const photo = selection.photo
const selections = [selection.id]
let data = { selections: [selection.id] }

yield put(act.photo.selections.add({ id: photo, selections }, { idx }))
yield* this.createThumbnails(selection.id, image, { selection })

yield put(act.photo.selections.add({ id: photo.id, ...data }, { idx }))

this.undo = act.selection.delete({ photo, selections }, { idx })
this.redo = act.selection.restore({ photo, selections }, { idx })
this.undo = act.selection.delete({ photo: photo.id, ...data }, { idx })
this.redo = act.selection.restore({ photo: photo.id, ...data }, { idx })

return selection
}
Expand All @@ -39,9 +42,9 @@ class Delete extends Command {
static get ACTION() { return SELECTION.DELETE }

*exec() {
const { db } = this.options
const { payload } = this.action
const { photo, selections } = payload
let { db } = this.options
let { payload } = this.action
let { photo, selections } = payload

let ord = yield select(({ photos }) => photos[photo].selections)
let idx = selections.map(id => ord.indexOf(id))
Expand Down
3 changes: 1 addition & 2 deletions src/components/item/panel.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
'use strict'

const React = require('react')
const { PureComponent } = React
const { ItemToolbar } = require('./toolbar')
const { ItemTabHeader, ItemTabBody } = require('./tab')
const { NotePanel } = require('../note')
Expand All @@ -16,7 +15,7 @@ const {
} = require('prop-types')


class ItemPanel extends PureComponent {
class ItemPanel extends React.PureComponent {
constructor(props) {
super(props)
this.state = {
Expand Down
1 change: 1 addition & 0 deletions src/components/photo/grid.js
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ class PhotoGrid extends PhotoIterator {
onTabFocus={this.handleNestedTabFocus}
onContextMenu={this.props.onContextMenu}
onDelete={this.handleDelete}
onError={this.props.onError}
onItemOpen={this.handleItemOpen}
onSelect={this.select}
onSort={this.props.onSelectionSort}
Expand Down
3 changes: 1 addition & 2 deletions src/components/photo/iterable.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
'use strict'

const React = require('react')
const { PureComponent } = React
const { Thumbnail } = require('./thumbnail')
const { DragSource, DropTarget } = require('react-dnd')
const { getEmptyImage } = require('react-dnd-electron-backend')
Expand All @@ -14,7 +13,7 @@ const {
} = require('prop-types')


class PhotoIterable extends PureComponent {
class PhotoIterable extends React.PureComponent {
constructor(props) {
super(props)

Expand Down
1 change: 1 addition & 0 deletions src/components/photo/list-item.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ class PhotoListItem extends PhotoIterable {
onContextMenu={this.props.onContextMenu}
onEdit={this.props.onEdit}
onEditCancel={this.props.onEditCancel}
onError={this.props.onError}
onItemOpen={this.props.onItemOpen}
onSelect={this.props.onSelect}
onSort={this.props.onSelectionSort}
Expand Down
18 changes: 8 additions & 10 deletions src/components/selection/iterable.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
'use strict'

const React = require('react')
const { PureComponent } = React
const { Thumbnail } = require('../photo/thumbnail')
const { DragSource, DropTarget } = require('react-dnd')
const { getEmptyImage } = require('react-dnd-electron-backend')
Expand All @@ -11,13 +10,9 @@ const { bounds } = require('../../dom')
const { DND } = require('../../constants')


class SelectionIterable extends PureComponent {
constructor(props) {
super(props)

this.state = {
offset: null
}
class SelectionIterable extends React.PureComponent {
state = {
offset: null
}

componentDidMount() {
Expand Down Expand Up @@ -87,13 +82,15 @@ class SelectionIterable extends PureComponent {
renderThumbnail(props) {
return (
<Thumbnail {...props}
id={this.props.photo.id}
id={this.props.selection.id}
angle={this.props.selection.angle}
broken={this.props.photo.broken}
mimetype={this.props.photo.mimetype}
mirror={this.props.selection.mirror}
orientation={this.props.photo.orientation}
cache={this.props.cache}
size={this.props.size}/>
size={this.props.size}
onError={this.props.onError}/>
)
}

Expand Down Expand Up @@ -123,6 +120,7 @@ class SelectionIterable extends PureComponent {
size: number.isRequired,
onContextMenu: func.isRequired,
onDropSelection: func.isRequired,
onError: func.isRequired,
onItemOpen: func.isRequired,
onSelect: func.isRequired
}
Expand Down
6 changes: 6 additions & 0 deletions src/components/selection/iterator.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ class SelectionIterator extends Iterator {
onSort({ photo: photo.id, selections: order })
}

handleLoadError = () => {
this.props.onError(this.props.photo.id)
}

select = (selection) => {
if (selection != null && !this.props.isActive) {
this.props.onSelect({
Expand Down Expand Up @@ -81,6 +85,7 @@ class SelectionIterator extends Iterator {
photo: this.props.photo,
onContextMenu: this.props.onContextMenu,
onDropSelection: this.handleDropSelection,
onError: this.handleLoadError,
onItemOpen: this.open,
onSelect: this.select
})
Expand All @@ -102,6 +107,7 @@ class SelectionIterator extends Iterator {
cache: string.isRequired,
size: number.isRequired,
onContextMenu: func.isRequired,
onError: func.isRequired,
onItemOpen: func.isRequired,
onSelect: func.isRequired,
onSort: func.isRequired
Expand Down

0 comments on commit c9c34ae

Please sign in to comment.