OSC / ood-fileexplorer

[MOVED] The Open OnDemand File Explorer
https://osc.github.io/Open-OnDemand/
MIT License
4 stars 1 forks source link

Context menus #47

Closed ericfranz closed 8 years ago

ericfranz commented 8 years ago

Detecting whether the selected item is a directory or file during a right click can be done with this:

$('.current-file').find("[data-name=js-type]").hasClass("directory")

Right click on a directory should display only these options:

Right click on a file should display only these options:

Right click on the current directory should display only these options:

brianmcmichael commented 8 years ago

I can see wanting to remove "pack" and "extract" because it isn't immediately clear that they tar.gz and untar files, but "Cut" is a pretty standard file management feature. Why remove it?

brianmcmichael commented 8 years ago

Update. So far as I can tell, there is pretty much always a $('.current-file') selected. The menu listener uses the actual screen position of the mouse, so I'm working on trying to figure out exactly what it's using to determine what's been clicked on.

It's happening here https://github.com/OSC/cloudcmd/blob/osc-5.3.1/lib/client/menu.js#L80-L104

and here

https://github.com/OSC/cloudcmd/blob/osc-5.3.1/lib%2Fclient%2Fdom.js#L848

Where the DOM.getCurrentByPosition seems to be actually returning the element the mouse is hovering over.

brianmcmichael commented 8 years ago

I'm able to get the 'li' element for the hovered over object, and it returns null when there's no object, but it doesn't distinguish between files and directories here, so I'll have to perform some jQuery magic to get the type from a child span.

I'm also concerned that I don't know how this works under the hood, some testing will need to be performed to ensure that it is using the actual position and that our styling hasn't interfered with the mechanism.

note: data-name is js-file-<name> for files and folders.

file = DOM.getCurrentByPosition({x: 200, y: 200});
<li class="bootstrap " data-name="js-file-ebtables" draggable="true">
file = DOM.getCurrentByPosition({x: 10, y: 10});
null
ericfranz commented 8 years ago

This approach seems challenging. The client code already has logic to determine whether you are going to display a "File/Directory" menu or a "Current Directory" menu.

Why can't we just stick with those two functions and inside the 'display a "File/Folder" menu' function determine whether what is currently selected is a file or a directory by A. inspecting the "current-file" and B. verifying no other file or folder is selected i.e. multiple selection?

brianmcmichael commented 8 years ago

getMenuData() is a default menu. Every item in this menu shows every time the menu is displayed. https://github.com/OSC/cloudcmd/blob/osc-5.3.1/lib/client/menu.js#L140-L159

loadFileMenuData() is displayed whenever a user clicks on a file/folder. https://github.com/OSC/cloudcmd/blob/osc-5.3.1/lib/client/menu.js#L175-L215

When the latter loads it pulls in the former.

I need a separate way (specifically DOM.getCurrentByPosition()) to determine whether we are clicking on an element or a null space.

Curretly the plan is this:

Click on File Click on Dir Click on null
View
Edit
Rename Rename
Delete Delete
Download Download
Copy Copy
(Un)Select All (Un)Select All (Un)Select All
Paste
New -> File/Dir
Upload
Open In Terminal

I need to be able to use the DOM.getCurrentByPosition() method determine if we are clicking over a null space to prevent the unique items in the "Click on null" column from appearing when a user clicks on a file or a dir.

ericfranz commented 8 years ago

I'm sure you're already deep into this change, but... You shouldn't need to do anything with DOM.getCurrentByPosition() here.

Why couldn't you do something like this:

function getMenuData(isAuth, includeall) {
    var includeall = typeof includeall !== 'undefined' ?  includeall : true;

    var menu = {
      '(Un)Select All': DOM.toggleAllSelectedFiles
    };

    if(includeall){
      menu = {
          // OSC_CUSTOM_CODE add the function to open the path in the terminal to the menu
          'Open Path In Terminal'
              : function () {
              var terminal_path = '/pun/sys/shell/ssh/oakley';
              window.open(terminal_path + DOM.getCurrentDirPath());
          },
          'Paste'         : Buffer.paste,
          'New'           : {
               'File'             : DOM.promptNewFile,
               'Directory'        : DOM.promptNewDir
          },
          'Upload'        : function() {
              CloudCmd.Upload.show();
          },
          // OSC_CUSTOM_CODE disable "'Upload From Cloud': uploadFromCloud," because it's not working
          //'Upload From Cloud': uploadFromCloud,
          '(Un)Select All': DOM.toggleAllSelectedFiles
      };
    }

    if (isAuth)
        menu['Log Out'] = CloudCmd.logOut;

    return menu;
}

function loadFileMenuData(callback) {
    isAuth(function(is) {
        var dir_selected = $('.current-file').find("[data-name=js-type]").hasClass("directory");

        var show        = function(name) {
                CloudCmd[name].show();
            },
            Dialog      = DOM.Dialog,
            menuData    = getMenuData(is, false),
            menu        = {
                'View'          : curry(show, 'View'),
            ...

Its an option, and it avoids a headache if it works.

brianmcmichael commented 8 years ago

Experimented with this a little yesterday. This app doesn't use jQuery so it will need to be added for $('.current-file').find("[data-name=js-type]").hasClass("directory") to work. That's going to add to the load time if we want to use a "cachebusted" local version. That's probably going to boost the priority of https://github.com/AweSim-OSC/osc-fileexplorer/issues/66

Additionally, the menu itself is cached in an object somewhere after the first load. I can create different menus and have them appropriately display on the first click, but after that they stick in that state. I need to discover where that is getting cached and disable it so that the menu stays dynamic.

ericfranz commented 8 years ago

66 is easy if we only want to manage the caching of jquery and bootstrap

ericfranz commented 8 years ago

As far as the menu being cached. I'd like to know what the cost would be of adding buttons to initiate these actions.

Assuming the HTML and CSS was taken care of, and we could supply our own javascript that updated the enabling/disabling/showing/hiding of the buttons based on selected files... what else is there? Where is the complexity? How would we implement this? Could we just add a separate block with our own click handlers? Are the methods that the context menus call available for us to call?

ericfranz commented 8 years ago

For adding buttons on top, don't worry that they will be added to both panels. For now thats okay, as Basil and I were discussing reverting back to a single panel since drag and drop is not yet supported.

ericfranz commented 8 years ago

screen shot 2016-05-11 at 3 15 14 pm

<div class="menu-buttons bootstrap" style="
    padding: 15px;
">
    <button type="button" class="icon icon-view btn btn-default btn-sm" onclick="CloudCmd['View'].show()">View</button>
    <button type="button" class="icon icon-edit btn btn-default btn-sm" onclick="CloudCmd['Edit'].show()">Edit</button>
    <button type="button" class="icon icon-rename btn btn-default btn-sm" onclick="DOM.renameCurrent()">Rename</button>

    <button type="button" class="icon icon-download btn btn-primary btn-sm" onclick="download()">Download</button>

    <button type="button" class="icon icon-copy btn btn-default btn-sm" onclick="DOM.Buffer.copy()">Copy</button>
    <button type="button" class="icon icon-unselect-all btn btn-default btn-sm" onclick="DOM.toggleAllSelectedFiles()">(Un)Select All</button>
<button type="button" class="icon icon-delete btn btn-danger btn-sm pull-right" onclick="CloudCmd.Operation.show('delete');">Delete</button><div class="panel-btns" style="
    position: absolute;
    top: -40px;
    right: 0px;
">    
    <button type="button" class="icon icon-console btn btn-default btn-sm " onclick="terminal()">Open in Terminal</button><button type="button" class="icon icon-paste btn btn-default btn-sm" onclick="DOM.Buffer.paste()">Paste</button>
    <button type="button" class="icon icon-file btn btn-default btn-sm" onclick="DOM.promptNewFile()">New File</button>
    <button type="button" class="icon icon-directory btn btn-default btn-sm" onclick="DOM.promptNewDir()">New Dir</button>
    <button type="button" class="icon icon-upload btn btn-default btn-sm" onclick="CloudCmd.Upload.show();">Upload</button>
</div>
</div>

Notice the embedded css styles would be moved to ood_styles.css. Also added this:

.panel {
    margin-top: 40px;
}