Convert entry deletion for split view
This commit is contained in:
@@ -1,24 +1,4 @@
|
||||
|
||||
<!-- Modal remove entry -->
|
||||
<div class="modal fade" id="{{ 'entryRemoveModal-' + $id }}" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-body">
|
||||
<p class="text-bold text-danger" ng-show="entryRemove.error">{{ entryRemove.error }}</p>
|
||||
<!-- TODO remove fileName later once all translations have been updated -->
|
||||
<h4 ng-hide="entryRemove.error">{{ 'filemanager.removeDialog.reallyDelete' | tr:{ fileName: selected[0].fileName } }}</h4>
|
||||
<ul>
|
||||
<li ng-repeat="entry in selected">{{ entry.fileName }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">{{ 'main.dialog.no' | tr }}</button>
|
||||
<button type="button" class="btn btn-danger" ng-click="entryRemove.submit()" ng-hide="entryRemove.error" ng-disabled="entryRemove.busy"><i class="fa fa-circle-notch fa-spin" ng-show="entryRemove.busy"></i> {{ 'main.dialog.yes' | tr }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modal new directory -->
|
||||
<div class="modal fade" id="{{ 'newDirectoryModal-' + $id }}" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
@@ -157,11 +137,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!-- main content -->
|
||||
|
||||
|
||||
<div class="toolbar">
|
||||
<div class="btn-group" role="group" style="display: block;">
|
||||
<!-- TODO figure out why a line break in code between the two buttons results in a gap visually without any margin/padding set -->
|
||||
|
||||
+42
-148
@@ -1,19 +1,24 @@
|
||||
'use strict';
|
||||
|
||||
/* global angular */
|
||||
/* global sanitize */
|
||||
/* global sanitize, isModalVisible */
|
||||
|
||||
angular.module('Application').component('filetree', {
|
||||
bindings: {
|
||||
backendId: '<',
|
||||
backendType: '<',
|
||||
view: '<'
|
||||
view: '<',
|
||||
onUploadFile: '&',
|
||||
onUploadFolder: '&',
|
||||
onDeleteEntries: '&'
|
||||
},
|
||||
templateUrl: 'components/filetree.html?<%= revision %>',
|
||||
controller: [ '$scope', '$translate', '$timeout', 'Client', FileTreeController ]
|
||||
});
|
||||
|
||||
function FileTreeController($scope, $translate, $timeout, Client) {
|
||||
var ctrl = this;
|
||||
|
||||
$scope.backendId = this.backendId;
|
||||
$scope.backendType = this.backendType;
|
||||
$scope.view = this.view;
|
||||
@@ -30,6 +35,9 @@ function FileTreeController($scope, $translate, $timeout, Client) {
|
||||
$scope.dropToBody = false;
|
||||
$scope.applicationLink = '';
|
||||
|
||||
// register so parent can call child
|
||||
$scope.$parent.registerChild($scope);
|
||||
|
||||
$scope.owners = [
|
||||
{ name: 'cloudron', value: 1000 },
|
||||
{ name: 'www-data', value: 33 },
|
||||
@@ -305,6 +313,10 @@ function FileTreeController($scope, $translate, $timeout, Client) {
|
||||
};
|
||||
|
||||
$scope.refresh = function () {
|
||||
$scope.$parent.refresh();
|
||||
};
|
||||
|
||||
$scope.onRefresh = function () {
|
||||
$scope.selected = [];
|
||||
|
||||
Client.filesGet($scope.backendId, $scope.backendType, $scope.cwd, 'data', function (error, result) {
|
||||
@@ -495,101 +507,9 @@ function FileTreeController($scope, $translate, $timeout, Client) {
|
||||
$scope.selected = $scope.entries.slice();
|
||||
};
|
||||
|
||||
$scope.uploadStatus = {
|
||||
error: null,
|
||||
busy: false,
|
||||
fileName: '',
|
||||
count: 0,
|
||||
countDone: 0,
|
||||
size: 0,
|
||||
done: 0,
|
||||
percentDone: 0,
|
||||
files: [],
|
||||
targetFolder: ''
|
||||
};
|
||||
|
||||
function uploadFiles(files, targetFolder, overwrite) {
|
||||
if (!files || !files.length) return;
|
||||
|
||||
targetFolder = targetFolder || $scope.cwd;
|
||||
overwrite = !!overwrite;
|
||||
|
||||
// prevent it from getting closed
|
||||
$('#uploadModal').modal({
|
||||
backdrop: 'static',
|
||||
keyboard: false
|
||||
});
|
||||
|
||||
$scope.uploadStatus.files = files;
|
||||
$scope.uploadStatus.targetFolder = targetFolder;
|
||||
$scope.uploadStatus.error = null;
|
||||
$scope.uploadStatus.busy = true;
|
||||
$scope.uploadStatus.count = files.length;
|
||||
$scope.uploadStatus.countDone = 0;
|
||||
$scope.uploadStatus.size = 0;
|
||||
$scope.uploadStatus.sizeDone = 0;
|
||||
$scope.uploadStatus.done = 0;
|
||||
$scope.uploadStatus.percentDone = 0;
|
||||
|
||||
for (var i = 0; i < files.length; ++i) {
|
||||
$scope.uploadStatus.size += files[i].size;
|
||||
}
|
||||
|
||||
async.eachSeries(files, function (file, callback) {
|
||||
var filePath = sanitize(targetFolder + '/' + (file.webkitRelativePath || file.name));
|
||||
|
||||
$scope.uploadStatus.fileName = file.name;
|
||||
|
||||
Client.filesUpload($scope.backendId, $scope.backendType, filePath, file, overwrite, function (loaded) {
|
||||
$scope.uploadStatus.percentDone = ($scope.uploadStatus.done+loaded) * 100 / $scope.uploadStatus.size;
|
||||
$scope.uploadStatus.sizeDone = loaded;
|
||||
}, function (error) {
|
||||
if (error) return callback(error);
|
||||
|
||||
$scope.uploadStatus.done += file.size;
|
||||
$scope.uploadStatus.percentDone = $scope.uploadStatus.done * 100 / $scope.uploadStatus.size;
|
||||
$scope.uploadStatus.countDone++;
|
||||
|
||||
callback();
|
||||
});
|
||||
}, function (error) {
|
||||
$scope.uploadStatus.busy = false;
|
||||
|
||||
if (error && error.statusCode === 409) {
|
||||
$scope.uploadStatus.error = 'exists';
|
||||
return;
|
||||
} else if (error) {
|
||||
console.error(error);
|
||||
$scope.uploadStatus.error = 'generic';
|
||||
return;
|
||||
}
|
||||
|
||||
$('#uploadModal').modal('hide');
|
||||
|
||||
$scope.uploadStatus.fileName = '';
|
||||
$scope.uploadStatus.count = 0;
|
||||
$scope.uploadStatus.size = 0;
|
||||
$scope.uploadStatus.sizeDone = 0;
|
||||
$scope.uploadStatus.done = 0;
|
||||
$scope.uploadStatus.percentDone = 100;
|
||||
$scope.uploadStatus.files = [];
|
||||
$scope.uploadStatus.targetFolder = '';
|
||||
|
||||
$scope.refresh();
|
||||
});
|
||||
}
|
||||
|
||||
$scope.retryUpload = function (overwrite) {
|
||||
uploadFiles($scope.uploadStatus.files, $scope.uploadStatus.targetFolder, !!overwrite);
|
||||
};
|
||||
|
||||
// file upload
|
||||
$('#uploadFileInput').on('change', function (e) { uploadFiles(e.target.files || [], $scope.cwd, false); });
|
||||
$scope.onUploadFile = function () { $('#uploadFileInput').click(); };
|
||||
|
||||
// folder upload
|
||||
$('#uploadFolderInput').on('change', function (e ) { uploadFiles(e.target.files || [], $scope.cwd, false); });
|
||||
$scope.onUploadFolder = function () { $('#uploadFolderInput').click(); };
|
||||
// just events to the parent controller
|
||||
$scope.onUploadFile = function () { ctrl.onUploadFile({ cwd: $scope.cwd }); };
|
||||
$scope.onUploadFolder = function () { ctrl.onUploadFolder({ cwd: $scope.cwd }); };
|
||||
|
||||
$scope.restartBusy = false;
|
||||
$scope.onRestartApp = function () {
|
||||
@@ -799,35 +719,6 @@ function FileTreeController($scope, $translate, $timeout, Client) {
|
||||
}
|
||||
};
|
||||
|
||||
$scope.entryRemove = {
|
||||
busy: false,
|
||||
error: null,
|
||||
|
||||
show: function () {
|
||||
$scope.entryRemove.error = null;
|
||||
|
||||
$('#entryRemoveModal-' + $scope.$id).modal('show');
|
||||
},
|
||||
|
||||
submit: function () {
|
||||
$scope.entryRemove.busy = true;
|
||||
|
||||
async.eachLimit($scope.selected, 5, function (entry, callback) {
|
||||
var filePath = sanitize($scope.cwd + '/' + entry.fileName);
|
||||
|
||||
Client.filesRemove($scope.backendId, $scope.backendType, filePath, callback);
|
||||
}, function (error) {
|
||||
$scope.entryRemove.busy = false;
|
||||
if (error) return Client.error(error);
|
||||
|
||||
$scope.refresh();
|
||||
|
||||
$('#entryRemoveModal-' + $scope.$id).modal('hide');
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
$translate(['filemanager.list.menu.edit', 'filemanager.list.menu.cut', 'filemanager.list.menu.copy', 'filemanager.list.menu.paste', 'filemanager.list.menu.rename', 'filemanager.list.menu.chown', 'filemanager.list.menu.extract', 'filemanager.list.menu.download', 'filemanager.list.menu.delete' ]).then(function (tr) {
|
||||
$scope.menuOptions = [
|
||||
{
|
||||
@@ -865,7 +756,7 @@ function FileTreeController($scope, $translate, $timeout, Client) {
|
||||
}, {
|
||||
text: tr['filemanager.list.menu.delete'],
|
||||
hasTopDivider: true,
|
||||
click: function ($itemScope, $event, entry) { $scope.entryRemove.show(); }
|
||||
click: function ($itemScope, $event, entry) { ctrl.onDeleteEntries({ cwd: $scope.cwd, entries: $scope.selected }); }
|
||||
}
|
||||
];
|
||||
});
|
||||
@@ -891,27 +782,6 @@ function FileTreeController($scope, $translate, $timeout, Client) {
|
||||
];
|
||||
});
|
||||
|
||||
$('.file-list').on('scroll', function (event) {
|
||||
if (event.target.scrollTop > 10) event.target.classList.add('top-scroll-indicator');
|
||||
else event.target.classList.remove('top-scroll-indicator');
|
||||
});
|
||||
|
||||
// setup all the dialog focus handling
|
||||
['newFileModal', 'newDirectoryModal', 'renameEntryModal'].forEach(function (id) {
|
||||
$('#' + id).on('shown.bs.modal', function () {
|
||||
$(this).find('[autofocus]:first').focus();
|
||||
});
|
||||
});
|
||||
|
||||
// selects filename (without extension)
|
||||
['renameEntryModal'].forEach(function (id) {
|
||||
$('#' + id).on('shown.bs.modal', function () {
|
||||
var elem = $(this).find('[autofocus]:first');
|
||||
var text = elem.val();
|
||||
elem[0].setSelectionRange(0, text.indexOf('.'));
|
||||
});
|
||||
});
|
||||
|
||||
function scrollInView(element) {
|
||||
if (!element) return;
|
||||
|
||||
@@ -970,6 +840,30 @@ function FileTreeController($scope, $translate, $timeout, Client) {
|
||||
|
||||
openPath('.');
|
||||
|
||||
// DOM handlers, wait for elements to exist
|
||||
setTimeout(function () {
|
||||
$('.file-list').on('scroll', function (event) {
|
||||
if (event.target.scrollTop > 10) event.target.classList.add('top-scroll-indicator');
|
||||
else event.target.classList.remove('top-scroll-indicator');
|
||||
});
|
||||
|
||||
// setup all the dialog focus handling
|
||||
['newFileModal', 'newDirectoryModal', 'renameEntryModal'].forEach(function (id) {
|
||||
$('#' + id + '-' + $scope.$id).on('shown.bs.modal', function () {
|
||||
$(this).find('[autofocus]:first').focus();
|
||||
});
|
||||
});
|
||||
|
||||
// selects filename (without extension)
|
||||
['renameEntryModal'].forEach(function (id) {
|
||||
$('#' + id + '-' + $scope.$id).on('shown.bs.modal', function () {
|
||||
var elem = $(this).find('[autofocus]:first');
|
||||
var text = elem.val();
|
||||
elem[0].setSelectionRange(0, text.indexOf('.'));
|
||||
});
|
||||
});
|
||||
}, 0);
|
||||
|
||||
// handle save shortcuts
|
||||
window.addEventListener('keydown', function (event) {
|
||||
if ($scope.$parent.activeView !== $scope.view || $scope.$parent.viewerOpen || isModalVisible()) return;
|
||||
|
||||
+50
-21
@@ -75,6 +75,44 @@
|
||||
|
||||
<div class="restart-banner animateMe" ng-show="restartBusy" ng-cloak><i class="fa fa-circle-notch fa-spin"></i> {{ 'filemanager.status.restartingApp' | tr}}</div>
|
||||
|
||||
<!-- Modal delete entries -->
|
||||
<div class="modal fade" id="entriesDeleteModal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-body">
|
||||
<p class="text-bold text-danger" ng-show="deleteEntries.error">{{ deleteEntries.error }}</p>
|
||||
<!-- TODO remove fileName later once all translations have been updated -->
|
||||
<h4 ng-hide="deleteEntries.error">{{ 'filemanager.removeDialog.reallyDelete' | tr:{ fileName: deleteEntries.entries[0].fileName } }}</h4>
|
||||
<ul>
|
||||
<li ng-repeat="entry in deleteEntries.entries">{{ entry.fileName }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">{{ 'main.dialog.no' | tr }}</button>
|
||||
<button type="button" class="btn btn-danger" ng-click="deleteEntries.submit()" ng-hide="deleteEntries.error" ng-disabled="deleteEntries.busy"><i class="fa fa-circle-notch fa-spin" ng-show="deleteEntries.busy"></i> {{ 'main.dialog.yes' | tr }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modal editor close -->
|
||||
<div class="modal fade" id="textEditorCloseModal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title">{{ 'filemanager.textEditorCloseDialog.title' | tr }}</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p class="text-bold text-danger">{{ 'filemanager.textEditorCloseDialog.details' | tr }}</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" ng-click="textEditor.onClose()">{{ 'filemanager.textEditorCloseDialog.dontSave' | tr }}</button>
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">{{ 'main.dialog.cancel' | tr }}</button>
|
||||
<button type="button" class="btn btn-success" ng-click="textEditor.saveAndClose()"><i class="fa fa-circle-notch fa-spin" ng-show="textEditor.busy"></i> {{ 'main.dialog.save' | tr }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modal upload -->
|
||||
<div class="modal fade" id="uploadModal" tabindex="-1" role="dialog">
|
||||
@@ -104,25 +142,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modal editor close -->
|
||||
<div class="modal fade" id="textEditorCloseModal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title">{{ 'filemanager.textEditorCloseDialog.title' | tr }}</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p class="text-bold text-danger">{{ 'filemanager.textEditorCloseDialog.details' | tr }}</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" ng-click="textEditor.onClose()">{{ 'filemanager.textEditorCloseDialog.dontSave' | tr }}</button>
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">{{ 'main.dialog.cancel' | tr }}</button>
|
||||
<button type="button" class="btn btn-success" ng-click="textEditor.saveAndClose()"><i class="fa fa-circle-notch fa-spin" ng-show="textEditor.busy"></i> {{ 'main.dialog.save' | tr }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="animateMe ng-hide layout-root" ng-show="initialized">
|
||||
<div class="row" ng-hide="title">
|
||||
<div class="col-md-12 text-center">
|
||||
@@ -155,9 +174,19 @@
|
||||
</h4>
|
||||
|
||||
<div class="file-trees">
|
||||
<filetree ng-class="{ 'two-pane': splitView }" backend-type="backendType" backend-id="backendId" view="VIEW.LEFT" ng-click="setActiveView(VIEW.LEFT)"></filetree>
|
||||
<filetree ng-class="{ 'two-pane': splitView }"
|
||||
on-upload-folder="onUploadFolder(cwd)"
|
||||
on-upload-file="onUploadFile(cwd)"
|
||||
on-delete-entries="deleteEntries.show(cwd, entries)"
|
||||
backend-type="backendType" backend-id="backendId" view="VIEW.LEFT"
|
||||
ng-click="setActiveView(VIEW.LEFT)"></filetree>
|
||||
<!-- <div class="spacer" ng-show="splitView"></div> -->
|
||||
<filetree class="two-pane" backend-type="backendType" backend-id="backendId" view="VIEW.RIGHT" ng-click="setActiveView(VIEW.RIGHT)" ng-show="splitView"></filetree>
|
||||
<filetree class="two-pane"
|
||||
on-upload-folder="onUploadFolder(cwd)"
|
||||
on-upload-file="onUploadFile(cwd)"
|
||||
on-delete-entries="deleteEntries.show(cwd, entries)"
|
||||
backend-type="backendType" backend-id="backendId" view="VIEW.RIGHT"
|
||||
ng-click="setActiveView(VIEW.RIGHT)" ng-show="splitView"></filetree>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
+178
-7
@@ -82,6 +82,7 @@ var VIEW = {
|
||||
app.controller('FileManagerController', ['$scope', '$translate', '$timeout', 'Client', function ($scope, $translate, $timeout, Client) {
|
||||
var search = decodeURIComponent(window.location.search).slice(1).split('&').map(function (item) { return item.split('='); }).reduce(function (o, k) { o[k[0]] = k[1]; return o; }, {});
|
||||
|
||||
// expose enums
|
||||
$scope.VIEW = VIEW;
|
||||
|
||||
$scope.initialized = false;
|
||||
@@ -91,24 +92,189 @@ app.controller('FileManagerController', ['$scope', '$translate', '$timeout', 'Cl
|
||||
$scope.backendId = search.id;
|
||||
$scope.backendType = search.type;
|
||||
$scope.volumes = [];
|
||||
$scope.splitView = false;
|
||||
$scope.splitView = !!window.localStorage.splitView;
|
||||
$scope.activeView = VIEW.LEFT;
|
||||
$scope.viewerOpen = false;
|
||||
|
||||
|
||||
// add a hook for children to refresh both tree views
|
||||
|
||||
$scope.children = [];
|
||||
$scope.registerChild = function (child) { $scope.children.push(child); };
|
||||
$scope.refresh = function () {
|
||||
$scope.children.forEach(function (child) {
|
||||
child.onRefresh();
|
||||
});
|
||||
};
|
||||
|
||||
// handle uploads
|
||||
|
||||
$scope.uploadStatus = {
|
||||
error: null,
|
||||
busy: false,
|
||||
fileName: '',
|
||||
count: 0,
|
||||
countDone: 0,
|
||||
size: 0,
|
||||
done: 0,
|
||||
percentDone: 0,
|
||||
files: [],
|
||||
targetFolder: ''
|
||||
};
|
||||
|
||||
function uploadFiles(files, targetFolder, overwrite) {
|
||||
if (!files || !files.length) return;
|
||||
|
||||
targetFolder = targetFolder || $scope.cwd;
|
||||
overwrite = !!overwrite;
|
||||
|
||||
// prevent it from getting closed
|
||||
$('#uploadModal').modal({
|
||||
backdrop: 'static',
|
||||
keyboard: false
|
||||
});
|
||||
|
||||
$scope.uploadStatus.files = files;
|
||||
$scope.uploadStatus.targetFolder = targetFolder;
|
||||
$scope.uploadStatus.error = null;
|
||||
$scope.uploadStatus.busy = true;
|
||||
$scope.uploadStatus.count = files.length;
|
||||
$scope.uploadStatus.countDone = 0;
|
||||
$scope.uploadStatus.size = 0;
|
||||
$scope.uploadStatus.sizeDone = 0;
|
||||
$scope.uploadStatus.done = 0;
|
||||
$scope.uploadStatus.percentDone = 0;
|
||||
|
||||
for (var i = 0; i < files.length; ++i) {
|
||||
$scope.uploadStatus.size += files[i].size;
|
||||
}
|
||||
|
||||
async.eachSeries(files, function (file, callback) {
|
||||
var filePath = sanitize(targetFolder + '/' + (file.webkitRelativePath || file.name));
|
||||
|
||||
$scope.uploadStatus.fileName = file.name;
|
||||
|
||||
Client.filesUpload($scope.backendId, $scope.backendType, filePath, file, overwrite, function (loaded) {
|
||||
$scope.uploadStatus.percentDone = ($scope.uploadStatus.done+loaded) * 100 / $scope.uploadStatus.size;
|
||||
$scope.uploadStatus.sizeDone = loaded;
|
||||
}, function (error) {
|
||||
if (error) return callback(error);
|
||||
|
||||
$scope.uploadStatus.done += file.size;
|
||||
$scope.uploadStatus.percentDone = $scope.uploadStatus.done * 100 / $scope.uploadStatus.size;
|
||||
$scope.uploadStatus.countDone++;
|
||||
|
||||
callback();
|
||||
});
|
||||
}, function (error) {
|
||||
$scope.uploadStatus.busy = false;
|
||||
|
||||
if (error && error.statusCode === 409) {
|
||||
$scope.uploadStatus.error = 'exists';
|
||||
return;
|
||||
} else if (error) {
|
||||
console.error(error);
|
||||
$scope.uploadStatus.error = 'generic';
|
||||
return;
|
||||
}
|
||||
|
||||
$('#uploadModal').modal('hide');
|
||||
|
||||
$scope.uploadStatus.fileName = '';
|
||||
$scope.uploadStatus.count = 0;
|
||||
$scope.uploadStatus.size = 0;
|
||||
$scope.uploadStatus.sizeDone = 0;
|
||||
$scope.uploadStatus.done = 0;
|
||||
$scope.uploadStatus.percentDone = 100;
|
||||
$scope.uploadStatus.files = [];
|
||||
$scope.uploadStatus.targetFolder = '';
|
||||
|
||||
$scope.refresh();
|
||||
});
|
||||
}
|
||||
|
||||
$scope.retryUpload = function (overwrite) {
|
||||
uploadFiles($scope.uploadStatus.files, $scope.uploadStatus.targetFolder, !!overwrite);
|
||||
};
|
||||
|
||||
|
||||
// file and folder upload hooks, stashing $scope.uploadCwd for now
|
||||
|
||||
$scope.uploadCwd = '';
|
||||
$('#uploadFileInput').on('change', function (e ) {
|
||||
uploadFiles(e.target.files || [], $scope.uploadCwd, false);
|
||||
});
|
||||
$scope.onUploadFile = function (cwd) {
|
||||
$scope.uploadCwd = cwd;
|
||||
$('#uploadFileInput').click();
|
||||
};
|
||||
|
||||
$('#uploadFolderInput').on('change', function (e ) {
|
||||
uploadFiles(e.target.files || [], $scope.uploadCwd, false);
|
||||
});
|
||||
$scope.onUploadFolder = function (cwd) {
|
||||
$scope.uploadCwd = cwd;
|
||||
$('#uploadFolderInput').click();
|
||||
};
|
||||
|
||||
|
||||
// handle delete
|
||||
|
||||
$scope.deleteEntries = {
|
||||
busy: false,
|
||||
error: null,
|
||||
cwd: '',
|
||||
entries: [],
|
||||
|
||||
show: function (cwd, entries) {
|
||||
$scope.deleteEntries.error = null;
|
||||
$scope.deleteEntries.cwd = cwd;
|
||||
$scope.deleteEntries.entries = entries;
|
||||
|
||||
$('#entriesDeleteModal').modal('show');
|
||||
},
|
||||
|
||||
submit: function () {
|
||||
$scope.deleteEntries.busy = true;
|
||||
|
||||
async.eachLimit($scope.deleteEntries.entries, 5, function (entry, callback) {
|
||||
var filePath = sanitize($scope.deleteEntries.cwd + '/' + entry.fileName);
|
||||
|
||||
Client.filesRemove($scope.backendId, $scope.backendType, filePath, callback);
|
||||
}, function (error) {
|
||||
$scope.deleteEntries.busy = false;
|
||||
if (error) return Client.error(error);
|
||||
|
||||
$scope.refresh();
|
||||
|
||||
$('#entriesDeleteModal').modal('hide');
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// split view handling
|
||||
|
||||
$scope.toggleSplitView = function () {
|
||||
$scope.splitView = !$scope.splitView;
|
||||
if (!$scope.splitView) $scope.activeView = VIEW.LEFT;
|
||||
if (!$scope.splitView) {
|
||||
$scope.activeView = VIEW.LEFT;
|
||||
delete window.localStorage.splitView;
|
||||
} else {
|
||||
window.localStorage.splitView = true;
|
||||
}
|
||||
};
|
||||
|
||||
$scope.setActiveView = function (view) {
|
||||
$scope.activeView = view;
|
||||
};
|
||||
|
||||
// for monaco editor
|
||||
|
||||
// monaco text editor
|
||||
|
||||
var LANGUAGES = [];
|
||||
require(['vs/editor/editor.main'], function() {
|
||||
LANGUAGES = monaco.languages.getLanguages();
|
||||
});
|
||||
require(['vs/editor/editor.main'], function() { LANGUAGES = monaco.languages.getLanguages(); });
|
||||
|
||||
function getLanguage(filename) {
|
||||
var ext = '.' + filename.split('.').pop();
|
||||
@@ -207,6 +373,9 @@ app.controller('FileManagerController', ['$scope', '$translate', '$timeout', 'Cl
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
// init code
|
||||
|
||||
function fetchVolumesInfo(mounts) {
|
||||
$scope.volumes = [];
|
||||
|
||||
@@ -299,7 +468,9 @@ app.controller('FileManagerController', ['$scope', '$translate', '$timeout', 'Cl
|
||||
|
||||
init();
|
||||
|
||||
// handle save shortcuts
|
||||
|
||||
// toplevel key input handling
|
||||
|
||||
window.addEventListener('keydown', function (event) {
|
||||
if((navigator.platform.match('Mac') ? event.metaKey : event.ctrlKey) && event.key === 's') {
|
||||
if ($scope.view !== 'textEditor') return;
|
||||
|
||||
Reference in New Issue
Block a user