diff --git a/app/components/commander/index.js b/app/components/commander/index.js
index 924236d2eb1d2008781266517acabbb0f44958d1..789840e8d8a461ac70ca0d081b536e0e8e418f22 100644
--- a/app/components/commander/index.js
+++ b/app/components/commander/index.js
@@ -258,10 +258,6 @@ export default class CommanderComponent extends Component {
       succeeded. It is invoked on the SOURCE panel.
       `model` is instance of `model.document` or `model.folder`
     */
-    console.log(
-      `onDragendSuccess on ${this.args.hint}: id=${model.id} type=${model.nodeType}`
-    );
-    console.log(`onDragendSuccess selected_nodes=${sel_nodes}`);
     this.selected_nodes = []; // reset currect selected nodes list
   }
 
diff --git a/app/components/viewer/document/index.hbs b/app/components/viewer/document/index.hbs
new file mode 100644
index 0000000000000000000000000000000000000000..f3128a6c3cdfbe7bb1eb368a6255381e4eccf47e
--- /dev/null
+++ b/app/components/viewer/document/index.hbs
@@ -0,0 +1,8 @@
+<div class="d-flex">
+  <Viewer::Thumbnails
+    @pages={{@pages}}
+    @onDblClick={{this.onThumbnailDblClick}} />
+  <Viewer::Pages
+    @pages={{@pages}}
+    @scroll_to_page={{this.scroll_to_page}} />
+</div>
\ No newline at end of file
diff --git a/app/components/viewer/document/index.js b/app/components/viewer/document/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..e22025e058c5774ae4518a065882c9e4765c9e46
--- /dev/null
+++ b/app/components/viewer/document/index.js
@@ -0,0 +1,13 @@
+import Component from '@glimmer/component';
+import { tracked } from '@glimmer/tracking';
+import { action } from '@ember/object';
+
+
+export default class ViewerDocumentComponent extends Component {
+  @tracked scroll_to_page;
+
+  @action
+  onThumbnailDblClick(page) {
+    this.scroll_to_page = page;
+  }
+}
\ No newline at end of file
diff --git a/app/components/viewer/index.hbs b/app/components/viewer/index.hbs
index db0f1d15d23fb71ce6d89f7794f185a6576d655d..97a21d6bfe7729d8eec8a0812637851cbd647d4d 100644
--- a/app/components/viewer/index.hbs
+++ b/app/components/viewer/index.hbs
@@ -16,10 +16,11 @@
     @node={{@doc}}
     @extranode={{@extranode}}
     @extradoc={{@extradoc}}
+    @onNodeClicked={{this.onNodeClicked}}
     @hint={{@hint}} />
 
-  <div class="d-flex">
-    <Viewer::Thumbnails @pages={{this.pages}} />
-    <Viewer::Pages @pages={{this.pages}} />
-  </div>
+
+  <Viewer::Document
+    @pages={{this.pages}} />
+
 </div>
diff --git a/app/components/viewer/index.js b/app/components/viewer/index.js
index 431e7e75abc77e2e3d94cb3d395328cf4227dd51..bb30f001d278fa50dccb255c0fc5a15c09e76754 100644
--- a/app/components/viewer/index.js
+++ b/app/components/viewer/index.js
@@ -1,6 +1,6 @@
 import Component from '@glimmer/component';
 import { tracked } from '@glimmer/tracking';
-import { inject as service } from '@ember/service';
+import { service } from '@ember/service';
 import { action } from '@ember/object';
 import { A } from '@ember/array';
 
@@ -100,6 +100,11 @@ export default class ViewerComponent extends Component {
     });
   }
 
+  @action
+  onNodeClicked() {
+    console.log('node clicked');
+  }
+
   get versions() {
     /* Just a shortcut */
     return this.args.doc.versions;
diff --git a/app/components/viewer/page.hbs b/app/components/viewer/page.hbs
index 6c432f6e412dc877a07421cf36617667578ce4e7..f32dab0e2d3cdb1e2adb6f1ded1d87a221c557c8 100644
--- a/app/components/viewer/page.hbs
+++ b/app/components/viewer/page.hbs
@@ -1,4 +1,7 @@
-<div class="page d-flex flex-column align-items-center">
+<div
+  class="page d-flex flex-column align-items-center"
+  {{scrollIntoView page=@page scroll_to_page=@scroll_to_page}}>
+
   {{#if @page.svg_image}}
     {{{@page.svg_image}}}
   {{else}}
@@ -7,4 +10,5 @@
   <div class="number fs-3 m-3">
     {{@page.number}}
   </div>
-</div>
\ No newline at end of file
+
+</div> <!-- .page -->
diff --git a/app/components/viewer/pages.hbs b/app/components/viewer/pages.hbs
index 1e23bbccb16c0cf5b435d658800492fa3fbf6628..dca9a5187d9804da32af31c96ca38b6a038001c1 100644
--- a/app/components/viewer/pages.hbs
+++ b/app/components/viewer/pages.hbs
@@ -1,5 +1,7 @@
 <div class="d-flex flex-column pages">
   {{#each @pages as |page|}}
-    <Viewer::Page @page={{page}} />
+    <Viewer::Page
+      @page={{page}}
+      @scroll_to_page={{@scroll_to_page}} />
   {{/each}}
 </div>
\ No newline at end of file
diff --git a/app/components/viewer/thumbnail.hbs b/app/components/viewer/thumbnail/index.hbs
similarity index 63%
rename from app/components/viewer/thumbnail.hbs
rename to app/components/viewer/thumbnail/index.hbs
index 293513a05d4a69d68ca29bb472c6c396aff81b34..87f494ba6cb570f47803213f1798323004c8b86e 100644
--- a/app/components/viewer/thumbnail.hbs
+++ b/app/components/viewer/thumbnail/index.hbs
@@ -1,4 +1,6 @@
-<div class="thumbnail d-flex flex-column align-items-center">
+<div
+  class="thumbnail d-flex flex-column align-items-center"
+  {{on "dblclick" this.onDblClick}} >
   {{#if @page.svg_image}}
     {{{@page.svg_image}}}
   {{else}}
diff --git a/app/components/viewer/thumbnail/index.js b/app/components/viewer/thumbnail/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..4a7220bb99d6269efedb2f3ffa195f32af8108e7
--- /dev/null
+++ b/app/components/viewer/thumbnail/index.js
@@ -0,0 +1,11 @@
+import Component from '@glimmer/component';
+import { action } from '@ember/object';
+
+
+export default class ViewerThumbnailComponent extends Component {
+
+  @action
+  onDblClick() {
+    this.args.onDblClick(this.args.page);
+  }
+}
\ No newline at end of file
diff --git a/app/components/viewer/thumbnails.hbs b/app/components/viewer/thumbnails.hbs
index 0752d9ab674cbcf45d88e79f2e29f7d9a4852776..7c0a4b83e1c28f6d6470e1cd2c397f893436104a 100644
--- a/app/components/viewer/thumbnails.hbs
+++ b/app/components/viewer/thumbnails.hbs
@@ -1,5 +1,7 @@
 <div class="d-flex flex-column thumbnails">
   {{#each @pages as |page|}}
-    <Viewer::Thumbnail @page={{page}} />
+    <Viewer::Thumbnail
+      @page={{page}}
+      @onDblClick={{@onDblClick}} />
   {{/each}}
 </div>
\ No newline at end of file
diff --git a/app/modifiers/draggable.js b/app/modifiers/draggable.js
index b9087295a708a21e706e6249d28dfa1694a44580..733367b4851cf07d7d5ecf69aad3ecf15e5f0bd8 100644
--- a/app/modifiers/draggable.js
+++ b/app/modifiers/draggable.js
@@ -59,7 +59,7 @@ export default class DraggableModifier extends Modifier {
 
   @action
   onDragStart(event) {
-    let data, nodes;
+    let data, nodes, canvas;
 
     this.model = this.args.positional[0];
     this.selected_nodes = this.args.named['selectedNodes'];
@@ -77,10 +77,31 @@ export default class DraggableModifier extends Modifier {
       }
     }
 
+    canvas = this.get_drag_canvas(nodes.length);
+
     event.dataTransfer.setData(
       "application/x.node",
       JSON.stringify(data)
     );
+
+    event.dataTransfer.setDragImage(canvas, 0, -15);
+  }
+
+  get_drag_canvas(count) {
+    /*
+      Returns a canvas with `Move ${count} item(s)` text on it.
+    */
+    let canvas = document.createElement("canvas"),
+      ctx;
+
+    canvas.width = 280;
+    canvas.height = 120;
+    ctx = canvas.getContext("2d");
+    ctx.font = "18px Arial";
+
+    ctx.fillText(`Move ${count} item(s)`, 10, 20);
+
+    return canvas;
   }
 
   @action
diff --git a/app/modifiers/scroll_into_view.js b/app/modifiers/scroll_into_view.js
new file mode 100644
index 0000000000000000000000000000000000000000..b7b887e3859b1551b0b544caf52ac174c1eed9c5
--- /dev/null
+++ b/app/modifiers/scroll_into_view.js
@@ -0,0 +1,24 @@
+import Modifier from 'ember-modifier';
+
+
+export default class ScrollIntoViewModifier extends Modifier {
+
+  didReceiveArguments() {
+    let page, scroll_to_page;
+
+    page = this.args.named['page'];
+    scroll_to_page = this.args.named['scroll_to_page'];
+
+    if (!page) {
+      return;
+    }
+
+    if(!scroll_to_page) {
+      return;
+    }
+
+    if (page.id == scroll_to_page.id) {
+      this.element.scrollIntoView();
+    }
+  }
+}
diff --git a/app/modifiers/ui_select.js b/app/modifiers/ui_select.js
index 5b70a0184b8363e548cea58cd9552a4d19f332b5..7a8c06a8578c7a6e79fa6dca749e1c243118c8ba 100644
--- a/app/modifiers/ui_select.js
+++ b/app/modifiers/ui_select.js
@@ -53,6 +53,10 @@ class UISelect {
   update(x, y) {
     let height, width, top, left;
 
+    if (this.is_dragging) {
+      console.log('This is draggin operation. Abort selection.');
+      return;
+    }
 
     this.show(x, y);
     this.current_x = x;
diff --git a/app/utils/rectangle.js b/app/utils/rectangle.js
index 5c89745dffdba788791a9f400fda878b6d94ad68..028a23f7a770cd8c9cb8f469671d76256b252ddf 100644
--- a/app/utils/rectangle.js
+++ b/app/utils/rectangle.js
@@ -38,7 +38,13 @@ export default class Rectangle {
   }
 
   contains_point(x, y) {
-    
+    /*
+      returns true if coord (x, y) is within boundries of the rectangle
+    */
+    let is_within_x = this.x <= x && x <= this.x + this.width,
+        is_within_y = this.y <= y && y <= this.y + this.height;
+
+      return is_within_x && is_within_y;
   }
 
   toString() {
diff --git a/tests/unit/rectangle-test.js b/tests/unit/rectangle-test.js
index 1e117fa0a215ecf06b63834939c3b9aeaa831f81..9eecdf89e8ee6441224a9412e52be87f5824186b 100644
--- a/tests/unit/rectangle-test.js
+++ b/tests/unit/rectangle-test.js
@@ -76,5 +76,19 @@ module('Unit | Rectangle', function () {
       rect2.intersect(rect1)
     );
   });
+
+  test('contains_point', function(assert) {
+    let rect;
+
+    rect = new Rectangle(100, 100, 20, 20);
+
+    assert.true(
+      rect.contains_point(115, 110)
+    );
+
+    assert.false(
+      rect.contains_point(5, 5)
+    );
+  });
 });