Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add drag and drop support #519

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 63 additions & 19 deletions css/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,16 @@ body:after {
float: left;
}

.breadcrumbs-droppable {

}

.breadcrumbs-droppable-hover {
transform: scale(1.1);
-webkit-transition: transform .1s ease-in;
transition: transform .1s ease-in;
}

div.crumb.last a {
cursor: default;
}
Expand Down Expand Up @@ -91,22 +101,56 @@ div.crumb.last a {
margin-left: 4px;
}

#gallery .row > a {
a.row-element {
position: relative;
display: inline-block;
height: auto;
padding: 0;
margin: 2px;
vertical-align: top;
-webkit-transition: transform .2s ease-in-out;
transition: transform .2s ease-in-out;
-webkit-user-select:none;
-moz-user-select:none;
-ms-user-select:none;
user-select:none;
-webkit-touch-callout:none;
}

.album-droppable {
transform: scale(0.9);
-webkit-transform: scale(0.9);
}

.album-droppable .album {
background: repeating-linear-gradient(
45deg,
transparent,
transparent 20px,
rgba(0, 0, 0, .3) 20px,
rgba(0, 0, 0, .3) 40px
);
}

.album-droppable .album .cropped {
transform: scale(0.9);
-webkit-transform: scale(0.9);
}

.album-droppable-hover {
transform: scale(1.0);
-webkit-transform: scale(1.0);
-webkit-transition: transform .1s ease-in;
transition: transform .1s ease-in;
}

#gallery .row > a .container {
a.row-element .container {
-webkit-transition: all .2s ease-in-out;
transition: all .2s ease-in-out;
}

#gallery .row > a > .album-loader,
#gallery .row > a > .image-loader {
a.row-element > .album-loader,
a.row-element > .image-loader {
position: absolute;
z-index: 11;
top: 0;
Expand All @@ -115,7 +159,7 @@ div.crumb.last a {
right: 0;
}

#gallery .row > a > .album-label {
a.row-element > .album-label {
color: #fff;
position: absolute;
left: 0;
Expand All @@ -131,7 +175,7 @@ div.crumb.last a {
z-index: 11;
}

#gallery .row > a > .image-label {
a.row-element > .image-label {
display: none;
position: absolute;
left: 0;
Expand All @@ -144,8 +188,8 @@ div.crumb.last a {
word-break: break-all;
}

#gallery .row > a > .album-label,
#gallery .row > a > .image-label {
a.row-element > .album-label,
a.row-element > .image-label {
position: absolute;
width: 100%;
height: 100%;
Expand All @@ -154,8 +198,8 @@ div.crumb.last a {
background-image: linear-gradient(rgba(0,0,0,0) 65%,rgba(0,0,0,0.35));
}

#gallery .row > a > .image-label .title,
#gallery .row > a > .album-label .title {
a.row-element > .image-label .title,
a.row-element > .album-label .title {
display: inline-block;
color: #fff;
text-align: center;
Expand All @@ -170,13 +214,13 @@ div.crumb.last a {
position: absolute;
}

#gallery .row > a > .image-label .title:hover,
#gallery .row > a > .album-label .title:hover {
a.row-element > .image-label .title:hover,
a.row-element > .album-label .title:hover {
overflow: visible;
white-space: normal;
}

#gallery .row > a > .album > img {
a.row-element > .album > img {
max-width: 200px;
max-height: 200px;
position: relative;
Expand All @@ -185,12 +229,12 @@ div.crumb.last a {
}

/* make focus visible for keyboard users */
#gallery .row > a:focus,
#gallery .row > a > .album:focus {
a.row-element:focus,
a.row-element > .album:focus {
opacity: .5;
}

#gallery .row > a .image > img {
a.row-element .image > img {
max-height: 200px;
}

Expand All @@ -201,16 +245,16 @@ div.crumb.last a {
transition: opacity 500ms;
}

#gallery .row > a .album .cropped {
a.row-element .album .cropped {
position: relative;
float: left;
margin: 1px;
background-position: center;
background-size: cover;
}

#gallery .row > a .album .icon-loading,
#gallery .row > a .icon-loading {
a.row-element .album .icon-loading,
a.row-element .icon-loading {
margin: auto;
position: absolute;
top: 0;
Expand Down
45 changes: 45 additions & 0 deletions js/breadcrumb.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@
ellipsis: null,
albumPath: null,
availableWidth: 0,
onClick: null,
droppableOptions: {
accept: "#gallery > .row > a",
activeClass: 'breadcrumbs-droppable',
hoverClass: 'breadcrumbs-droppable-hover',
tolerance: 'pointer'
},

/**
* Initialises the breadcrumbs for the current album
Expand Down Expand Up @@ -66,6 +73,41 @@
}
},

/**
* Processes UI elements dropped on the breadcrumbs
*
* @param event
* @param ui
*/
onDrop: function (event, ui) {
var $item = ui.draggable;
var $clone = ui.helper;
var $target = $(event.target);
if (!$target.is('.crumb')) {
$target = $target.closest('.crumb');
}
var targetPath = $(event.target).data('dir');
var dir = Gallery.currentAlbum;

while (dir.substr(0, 1) === '/') {//remove extra leading /'s
dir = dir.substr(1);
}
dir = '/' + dir;
if (dir.substr(-1, 1) !== '/') {
dir = dir + '/';
}
// Do nothing if dragged on current dir
if (targetPath === dir || targetPath + '/' === dir) {
return;
}
var filePath = $item.data('path');
var fileName = OC.basename(filePath);

$clone.fadeOut("normal", function () {
Gallery.move($item, fileName, filePath, $target, targetPath);
});
},

/**
* Builds the breadcrumbs array
*
Expand Down Expand Up @@ -170,6 +212,9 @@
});

this.breadcrumbsElement.append(breadcrumbs);

this.droppableOptions.drop = this.onDrop.bind(this);
this.breadcrumbsElement.find('.crumb:not(.last)').droppable(this.droppableOptions);
},

/**
Expand Down
81 changes: 81 additions & 0 deletions js/gallery.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
activeSlideShow: null,
buttonsWidth: 350,
browserToolbarHeight: 150,
filesClient: OC.Files.getClient(),

/**
* Refreshes the view and starts the slideshow if required
Expand Down Expand Up @@ -377,6 +378,47 @@
document.activeElement.blur();
},

/**
* Moves files and albums to a new location
*
* @param {jQuery} $item
* @param {string} fileName
* @param {string} filePath
* @param {jQuery} $target
* @param {string} targetPath
*/
move: function ($item, fileName, filePath, $target, targetPath) {
var self = this;
var dir = Gallery.currentAlbum;

if (targetPath.charAt(targetPath.length - 1) !== '/') {
// make sure we move the files into the target dir,
// not overwrite it
targetPath = targetPath + '/';
}
self.filesClient.move(dir + '/' + fileName, targetPath + fileName)
.done(function () {
self._removeElement(dir, filePath, $item);
})
.fail(function (status) {
if (status === 412) {
// TODO: some day here we should invoke the conflict dialog
OC.Notification.showTemporary(
t('gallery', 'Could not move "{file}", target exists', {file: fileName})
);
} else {
OC.Notification.showTemporary(
t('gallery', 'Could not move "{file}"', {file: fileName})
);
}
$item.fadeTo("normal", 1);
$target.children('.album-loader').hide();
})
.always(function () {
// Nothing?
});
},

/**
* Builds the album's model
*
Expand Down Expand Up @@ -527,6 +569,45 @@
}
});
}
},

/**
* Removes the moved element from the UI and refreshes the view
*
* @param {string} dir
* @param {string}filePath
* @param {jQuery} $item
* @private
*/
_removeElement: function (dir, filePath, $item) {
var images = Gallery.albumMap[Gallery.currentAlbum].images;
var albums = Gallery.albumMap[Gallery.currentAlbum].subAlbums;
// if still viewing the same directory
if (Gallery.currentAlbum === dir) {
var removed = false;
// We try to see if an image was removed
var movedImage = _(images).findIndex({path: filePath});
if (movedImage >= 0) {
images.splice(movedImage, 1);
removed = true;
} else {
// It wasn't an image, so try to remove an album
var movedAlbum = _(albums).findIndex({path: filePath});
if (movedAlbum >= 0) {
albums.splice(movedAlbum, 1);
removed = true;
}
}

if (removed) {
$item.remove();
// Refresh the photowall without checking if new files have arrived in the
// current album
// TODO On the next visit this album is going to be reloaded, unless we can get
// an etag back from the move endpoint
Gallery.view.init(Gallery.currentAlbum);
}
}
}
};
window.Gallery = Gallery;
Expand Down
Loading