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

Andrei/dnd #172

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/nbproject/private/
nbproject/
node_modules/
.idea/
8 changes: 4 additions & 4 deletions dist/angular-filemanager.min.js

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
<!-- Uncomment if you need to use raw source code
<script src="src/js/app.js"></script>
<script src="src/js/directives/directives.js"></script>
<script src="src/js/directives/and-uuid.js"></script>
<script src="src/js/directives/and-drag-drop.js"></script>
<script src="src/js/filters/filters.js"></script>
<script src="src/js/providers/config.js"></script>
<script src="src/js/entities/chmod.js"></script>
Expand Down
29 changes: 29 additions & 0 deletions src/css/dragdrop.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
.lvl-over {
/* applied to a drop target when a draggable object is over it */
background-color: #3d3d3d;
opacity: .5;
}
.drag-target {
max-width: 200px;
background: #2196F3;
color:#fff;
padding: 10px;
}
.lvl-zone-over {
/* applied to a drop target when a draggable object is over it */
background-color: #66ccff;
opacity: .5;
z-index:9999;
}

.lvl-zone-over:before {
content: "\e198";
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
z-index: 100;
color: #2196F3;
font-size: 8em;
font-family: 'Glyphicons Halflings';
}
72 changes: 72 additions & 0 deletions src/js/controllers/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,78 @@
});
};

$scope.droppedFromDesktop = function(dragEl, dropEl, dragFiles) { // function referenced by the drop target
//this is application logic, for the demo we just want to color the grid squares
//the directive provides a native dom object, wrap with jqlite
var drop = angular.element(dropEl);
var drag = angular.element(dragEl);

//clear the previously applied color, if it exists
var bgClass = drop.attr('data-color');
if (bgClass) {
drop.removeClass(bgClass);
}

//add the dragged color
bgClass = drag.attr("data-color");
drop.addClass(bgClass);
drop.attr('data-color', bgClass);

//if element has been dragged from the grid, clear dragged color
if (drag.attr("x-lvl-drop-zone")) {
drag.removeClass(bgClass);
}

$scope.addForUpload([].slice.call(dragFiles));
}
$scope.dropped = function(dragEl, dropEl, item) { // function referenced by the drop target
//this is application logic, for the demo we just want to color the grid squares
//the directive provides a native dom object, wrap with jqlite
var drop = angular.element(dropEl);
var drag = angular.element(dragEl);

//clear the previously applied color, if it exists
var bgClass = drop.attr('data-color');
if (bgClass) {
drop.removeClass(bgClass);
}

//add the dragged color
bgClass = drag.attr("data-color");
drop.addClass(bgClass);
drop.attr('data-color', bgClass);

//if element has been dragged from the grid, clear dragged color
if (drag.attr("x-lvl-drop-target")) {
drag.removeClass(bgClass);
}

//moving files and directories
if($scope.temps.indexOf(item) !== -1){
//can't drop here
return;
} else {
//set destination path
for(var i =0; i< $scope.temps.length; i ++){
$scope.temps[i].tempModel.path = item.model.fullPath().split('/');
}
//move all files
Promise.all($scope.temps.map(function(drag, i){
drag.rename().then(function () {
var deferred = $q.defer();
FileNavigator.clearTree(drag);
return deferred.promise;
}, function(error) {
$scope.temp.error = error;
});
})).then(function(data){
FileNavigator.refresh();
},function(err){
FileNavigator.refresh();
});
}
}

var validateSamePath = function(item) {
var selectedPath = $rootScope.selectedModalPath.join('');
var selectedItemsPath = item && item.model.path.join('');
Expand Down
211 changes: 211 additions & 0 deletions src/js/directives/and-drag-drop.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
var module = angular.module("lvl.directives.dragdrop", ['lvl.services']);

module.directive('lvlDraggable', ['$rootScope', 'uuid','$compile', function ($rootScope, uuid) {
return {
restrict: 'A',
link: function (scope, el, attrs, controller) {
var isEnabled = scope.$eval(attrs.lvlDraggable);
if(isEnabled) {
angular.element(el).attr("draggable", "true");
var id = angular.element(el).attr("id");

if (!id) {
id = uuid.new()
angular.element(el).attr("id", id);
}
el.bind("dragstart", function (e) {
e.originalEvent.dataTransfer.setData('text', id);
e.originalEvent.dataTransfer.setDragImage(document.getElementById('file-drag-target'),40,30);
console.log('drag');
$rootScope.$emit("LVL-DRAG-START");
});

el.bind("dragend", function (e) {
$rootScope.$emit("LVL-DRAG-END");
});
}
}
};
}]);

module.directive('lvlDropTarget', ['$rootScope', 'uuid', function ($rootScope, uuid) {
return {
restrict: 'A',
scope: {
onDrop: '&'
},
link: function (scope, el, attrs, controller) {
var id = angular.element(el).attr("id");
if (!id) {
id = uuid.new();
angular.element(el).attr("id", id);
}

var isEnabled = scope.$eval(attrs.lvlDropTarget);
if(isEnabled){
el.bind("dragover", function (e) {
if (e.preventDefault) {
e.preventDefault(); // Necessary. Allows us to drop.
}

e.originalEvent.dataTransfer.dropEffect = 'move'; // See the section on the originalEvent.dataTransfer object.
return false;
});

el.bind("dragenter", function (e) {
// this / e.target is the current hover target.
//check if el exists
if(e.target == null)
return;

if(e.target.localName !== 'td'){
angular.element(e.target).addClass('lvl-over');
}else{
angular.element(e.target.parentElement).addClass('lvl-over');
}

});

el.bind("dragleave", function (e) {
//check if el exists
if(e.target == null)
return;

if(e.target.localName !== 'td'){
angular.element(e.target).removeClass('lvl-over'); // this / e.target is previous target element.
}else{
angular.element(e.target.parentElement).removeClass('lvl-over'); // this / e.target is previous target element.
}

});

el.bind("drop", function (e) {
if (e.preventDefault) {
e.preventDefault(); // Necessary. Allows us to drop.
}

if (e.stopPropagation) {
e.stopPropagation(); // Necessary. Allows us to drop.
}
var data = e.originalEvent.dataTransfer.getData("text");
var dest = document.getElementById(id);
var src = document.getElementById(data);

scope.onDrop({dragEl: data, dropEl: id});
});

$rootScope.$on("LVL-DRAG-START", function () {
var el = document.getElementById(id);
angular.element(el).addClass("lvl-target");
});

$rootScope.$on("LVL-DRAG-END", function () {
var el = document.getElementById(id);
angular.element(el).removeClass("lvl-target");

//check if el exists
if(el == null)
return;

if(el.localName !== 'td'){
angular.element(el).removeClass('lvl-over'); // this / e.target is previous target element.
}else{
angular.element(el.parentElement).removeClass('lvl-over'); // this / e.target is previous target element.
}
//angular.element(el).removeClass("lvl-over");
});
}

}
};
}]);

module.directive('lvlDropZone', ['$rootScope', 'uuid', function ($rootScope, uuid) {
return {
restrict: 'A',
scope: {
onDrop: '&'
},
link: function (scope, el, attrs, controller) {
var id = angular.element(el).attr("id");
if (!id) {
id = uuid.new();
angular.element(el).attr("id", id);
}

var isEnabled = scope.$eval(attrs.lvlDropZone);
if(isEnabled){
el.bind("dragover", function (e) {
if (e.preventDefault) {
e.preventDefault(); // Necessary. Allows us to drop.
}

e.originalEvent.dataTransfer.dropEffect = 'move'; // See the section on the originalEvent.dataTransfer object.
return false;
});

el.bind("dragenter", function (e) {
// this / e.target is the current hover target.
//check if el exists
if(e.target == null)
return;

//check if we really drag files from desktop
if(e.originalEvent.dataTransfer.types[0] != 'Files')
return;
//remove style
angular.element(e.target).addClass('lvl-zone-over');

});

el.bind("dragleave", function (e) {
//check if el exists
if(e.target == null)
return;

angular.element(e.target).removeClass('lvl-zone-over'); // this / e.target is previous target element.
});

el.bind("drop", function (e) {
console.log('files dropped');

angular.element(e.target).removeClass('lvl-zone-over');

if (e.preventDefault) {
e.preventDefault(); // Necessary. Allows us to drop.
}

if (e.stopPropagation) {
e.stopPropagation(); // Necessary. Allows us to drop.
}

//check if we really drag files from desktop
if(e.originalEvent.dataTransfer.types[0] != 'Files')
return;

var files = e.originalEvent.dataTransfer.files;

var data = e.originalEvent.dataTransfer.getData("text");

scope.onDrop({dragEl: data, dropEl: id, dragFiles: files});
});

$rootScope.$on("LVL-DRAG-START", function () {
var el = document.getElementById(id);
angular.element(el).addClass("lvl-target");
});

$rootScope.$on("LVL-DRAG-END", function () {
var el = document.getElementById(id);
angular.element(el).removeClass("lvl-target");

//check if el exists
if(el == null)
return;
angular.element(el).removeClass("lvl-zone-over");
});
}

}
};
}]);
25 changes: 25 additions & 0 deletions src/js/directives/and-uuid.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
var module;

try {
module = angular.module('lvl.services');
} catch (e) {
module = angular.module('lvl.services', []);
}

module.factory('uuid', function() {
var svc = {
new: function() {
function _p8(s) {
var p = (Math.random().toString(16)+"000000000").substr(2,8);
return s ? "-" + p.substr(0,4) + "-" + p.substr(4,4) : p ;
}
return _p8() + _p8(true) + _p8(true) + _p8();
},

empty: function() {
return '00000000-0000-0000-0000-000000000000';
}
};

return svc;
});
5 changes: 3 additions & 2 deletions src/templates/main-table.html
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,9 @@
{{ fileNavigator.error }}
</td>
</tr>
<tr class="item-list" ng-repeat="item in $parent.fileList = (fileNavigator.fileList | filter: {model:{name: query}} | orderBy:predicate:reverse)" ng-show="!fileNavigator.requesting" ng-click="selectOrUnselect(item, $event)" ng-dblclick="smartClick(item)" ng-right-click="selectOrUnselect(item, $event)" ng-class="{selected: isSelected(item)}">
<td>
<tr class="item-list" ng-repeat="item in $parent.fileList = (fileNavigator.fileList | filter: {model:{name: query}} | orderBy:predicate:reverse)" ng-show="!fileNavigator.requesting" ng-click="selectOrUnselect(item, $event)" ng-dblclick="smartClick(item)" ng-right-click="selectOrUnselect(item, $event)" ng-class="{selected: isSelected(item)}" x-lvl-drop-target="{{item.model.type === 'dir'}}"
x-on-drop="dropped(dragEl, dropEl, item)" >
<td x-lvl-draggable="{{item.model.type !== 'syncgroup'}}">
<a href="" title="{{item.model.name}} ({{item.model.size | humanReadableFileSize}})">
<i class="glyphicon glyphicon-folder-close" ng-show="item.model.type === 'dir'"></i>
<i class="glyphicon glyphicon-file" ng-show="item.model.type === 'file'"></i>
Expand Down
2 changes: 1 addition & 1 deletion src/templates/main.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<div ng-controller="FileManagerCtrl" ngf-drop="addForUpload($files)" ngf-drag-over-class="'upload-dragover'" ngf-multiple="true">
<div ng-include="config.tplPath + '/navbar.html'"></div>

<div class="container-fluid">
<div class="container-fluid" x-lvl-drop-zone="true" x-on-drop="droppedFromDesktop(dragEl, dropEl, dragFiles)">
<div class="row">

<div class="col-sm-4 col-md-3 sidebar file-tree animated slow fadeIn" ng-include="config.tplPath + '/sidebar.html'" ng-show="config.sidebar &amp;&amp; fileNavigator.history[0]">
Expand Down
3 changes: 2 additions & 1 deletion src/templates/sidebar.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
</ul>

<script type="text/ng-template" id="folder-branch-item">
<a href="" ng-click="fileNavigator.folderClick(item.item)" class="animated fast fadeInDown">
<a href="" ng-click="fileNavigator.folderClick(item.item)" x-lvl-drop-target="true"
x-on-drop="dropped(dragEl, dropEl, item.item)" class="animated fast fadeInDown">

<span class="point">
<i class="glyphicon glyphicon-chevron-down" ng-show="isInThisPath(item.name)"></i>
Expand Down