Skip to content
Snippets Groups Projects
Commit 10079186 authored by Eugen Ciur's avatar Eugen Ciur
Browse files

feature: thumbnails viewer drag and drop feedback

parent 80d473ba
Branches
No related tags found
No related merge requests found
......@@ -7,6 +7,8 @@
@onDblClick={{this.onThumbnailDblClick}}
@onCheckboxChange={{@onCheckboxChange}}
@onThumbnailsPositionChanged={{@onThumbnailsPositionChanged}}
@onAddThumbnailPlaceholderAt={{@onAddThumbnailPlaceholderAt}}
@onRemoveThumbnailPlaceholder={{@onRemoveThumbnailPlaceholder}}
@onIncomingPages={{@onIncomingPages}} />
{{/if}}
<Viewer::ThumbnailsSwitch
......
......@@ -53,5 +53,7 @@
@thumbnails_visible={{this.thumbnails_visible}}
@onCheckboxChange={{this.onThumbnailCheckboxChange}}
@onThumbnailsPositionChanged={{this.onThumbnailsPositionChanged}}
@onAddThumbnailPlaceholderAt={{this.onAddThumbnailPlaceholderAt}}
@onRemoveThumbnailPlaceholder={{this.onRemoveThumbnailPlaceholder}}
@onIncomingPages={{this.onIncomingPages}} />
</div>
......@@ -5,7 +5,6 @@ import { action } from '@ember/object';
import { A } from '@ember/array';
import {
reposition_items,
get_id,
detect_order_changes
} from 'papermerge/utils/array';
......@@ -163,6 +162,34 @@ export default class ViewerComponent extends Component {
});
}
@action
onAddThumbnailPlaceholderAt(pos) {
let new_pages,
placeholder;
new_pages = Array.from(this.pages);
placeholder = {'is_placeholder': true};
if (!new_pages.find(item => item.is_placeholder)) {
// Only one placeholder is allowed
new_pages.splice(pos, 0, placeholder);
this.pages = new_pages;
}
}
@action
onRemoveThumbnailPlaceholder() {
let new_pages,
placeholder_pos;
new_pages = Array.from(this.pages);
placeholder_pos = new_pages.findIndex(item => item.is_placeholder);
if (placeholder_pos >= 0) {
console.log(`placeholder found at pos ${placeholder_pos}`)
new_pages.splice(placeholder_pos, 1);
this.pages = new_pages;
}
}
@action
async onIncomingPages({page_ids, drop_pos}) {
await this.requests.moveToDocument({
......
......@@ -8,13 +8,17 @@
{{adjust_element_height}}>
{{#each @pages as |page|}}
<Viewer::Thumbnail
@doc={{@doc}}
@page={{page}}
@selectedPages={{@selectedPages}}
@onDblClick={{@onDblClick}}
@onDragendSuccess={{this.onDragendSuccess}}
@onDragendCancel={{this.onDragendCancel}}
@onCheckboxChange={{@onCheckboxChange}} />
{{#if page.is_placeholder}}
Placeholder
{{else}}
<Viewer::Thumbnail
@doc={{@doc}}
@page={{page}}
@selectedPages={{@selectedPages}}
@onDblClick={{@onDblClick}}
@onDragendSuccess={{this.onDragendSuccess}}
@onDragendCancel={{this.onDragendCancel}}
@onCheckboxChange={{@onCheckboxChange}} />
{{/if}}
{{/each}}
</div>
......@@ -54,7 +54,57 @@ export default class ViewerThumbnailsComponent extends Component {
}
@action
onDragOver() {
onDragOver({event, element}) {
/*
Creates DOM placeholder suggesting to user that here he/she can drop the page.
Only one placeholder DOM element is allowed.
*/
let thumbnail_dom_items,
cursor_coord,
pos,
rect,
cursor_before_child = 0,
outside_all_thumbnails = true,
svg_element;
if (!element) {
return;
}
cursor_coord = new Point(event.clientX, event.clientY);
thumbnail_dom_items = Array.from(element.children);
thumbnail_dom_items.forEach(thumbnail_dom_item => {
// page_item is DOM element which may be real thumbnail of the page or
// it may be a paceholder used as suggestion that it is OK to drop page here.
// Real page thumbnail DOM element contains DOM element for image/svg
// and DOM element denoting page number
svg_element = thumbnail_dom_item.querySelector('svg');
if (svg_element) { // in case of thumbnail placeholder, there won't be SVG element
rect = svg_element.getBoundingClientRect();
if (cursor_coord.y <= rect.y) {
cursor_before_child += 1;
}
// Check if cursor position is outside of any thumbnail i.e.
// position to drop will be suggested only in case cursor coordinate
// is BETWEEN thumbnails images/svg
if ((cursor_coord.y < rect.bottom) && (cursor_coord.y > rect.top)) {
outside_all_thumbnails = false;
}
}
});
// position where to suggest page drop
pos = thumbnail_dom_items.length - cursor_before_child;
if (outside_all_thumbnails) {
// suggest position to drop ONLY of cursor is outside of all thumbnails
this.args.onAddThumbnailPlaceholderAt(pos);
} else {
this.args.onRemoveThumbnailPlaceholder();
}
}
@action
......
......@@ -38,11 +38,17 @@ export default class DrappableModifier extends Modifier {
@action
onDragOver(event) {
const isNode = event.dataTransfer.types.includes("application/x.node");
//const isNode = event.dataTransfer.types.includes("application/x.node");
event.preventDefault();
if (isNode) {
//event.preventDefault();
//if (isNode) {
//console.log(`dragging over a node`);
//}
let _onDragOver = this.args.named['onDragOver'], element;
element = this.element;
if (_onDragOver) {
_onDragOver({event, element});
}
}
......
......@@ -124,7 +124,7 @@ function detect_order_changes(arr1, arr2) {
}
if (arr1.length != arr2.length) {
throw 'Invalid input. Both arrays need to be of same length';
return false;
}
arr1.forEach((item, index) => {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment