DnD inline images frontend.

Review Request #8147 — Created May 6, 2016 and submitted

Information

Review Board
release-3.0.x
4db0143...

Reviewers

This change implements the frontend for letting users drag-and-drop images into
their markdown editors. This will upload the image as a user file attachment
and insert the relevant markdown syntax into the editor.

This is based on work by David Kus at https://reviews.reviewboard.org/r/6510/
Compared to that change, I've reworked the UI a bit to avoid the overlapping
drop targets (the review request file attachments drop target is now isolated
to the "Files" section, which appears momentarily if it wasn't already
visible). I've also done a bunch of refactoring of the code to modernize and
clean it up.

At the moment, this adds overlays over the entire text field, and will insert
the markdown text as a new line wherever the cursor is. I'd like to improve
this in the future to make it more obvious where the new entry will end up
(basically moving the cursor during the dragover with inline feedback) but
that's a larger change.

  • Dragged images into a variety of text fields.
  • Dragged files to create new file attachments.
  • Ran unit tests.
  • Ran js-tests.
Description From Last Updated

Since RB.BaseResource.prototype.defaults is a method that returns an object fo extra data, we'll want to make this a function.

brenniebrennie

Can we do: const url = `${SITE_ROOT}api/users/${this.get('username')}/file-attachments/`; or similar?

brenniebrennie

you can use { $target } here as shorthand for { $target: $target }

brenniebrennie

You can do: const target = new DnDDropTarget({ $target, dropText, callback });

brenniebrennie

Why do we need the !important? Can we rework things to not need it?

chipx86chipx86

What does the 64px relate to? Can we add a constant?

chipx86chipx86

Can we add constants for these colors and border size?

chipx86chipx86

Can we use a relative font size (percentage)?

chipx86chipx86

Same here.

chipx86chipx86

Should use the standard multi-line comment format.

chipx86chipx86

Are we limiting this exclusively to images? I can think of other file formats that would be useful in discussions.

chipx86chipx86

"append"

chipx86chipx86

This is too long.

chipx86chipx86

While the new shorthand in ES6 probably has some good uses, I think it's not very future-proof. If anyone ever …

chipx86chipx86

One too many "anys," probably.

chipx86chipx86

You can do this.el.value += `\n${text}`; here

brenniebrennie

Same here.

brenniebrennie

(Almost) the same here.

brenniebrennie

And here.

brenniebrennie

Should these be .jpeg etc? Because I couldn't I upload foojpeg and it would allow it? Or do something like: …

brenniebrennie

You can do callback() {} in the object literal.

brenniebrennie

Can we put the comparison in parens, to help visually distinguish it better from the => ?

chipx86chipx86
reviewbot
  1. Tool: Pyflakes
    Processed Files:
        reviewboard/staticbundles.py
    
    Ignored Files:
        reviewboard/static/rb/js/resources/models/tests/userFileAttachmentModelTests.js
        reviewboard/static/rb/css/ui/dnd-uploader.less
        reviewboard/static/rb/js/resources/models/userFileAttachmentModel.es6.js
        reviewboard/static/rb/js/ui/views/textEditorView.es6.js
        reviewboard/static/rb/js/views/dndUploaderView.es6.js
        reviewboard/static/rb/js/pages/views/tests/reviewablePageViewTests.js
        reviewboard/static/rb/js/views/reviewReplyEditorView.js
        reviewboard/templates/reviews/review_request_box.html
        reviewboard/static/rb/css/pages/reviews.less
        reviewboard/static/rb/js/ui/views/tests/textEditorViewTests.js
        reviewboard/static/rb/css/common.less
        reviewboard/static/rb/css/defs.less
        reviewboard/static/rb/js/views/reviewRequestEditorView.js
        reviewboard/static/rb/js/pages/views/reviewablePageView.js
    
    
    
    Tool: PEP8 Style Checker
    Processed Files:
        reviewboard/staticbundles.py
    
    Ignored Files:
        reviewboard/static/rb/js/resources/models/tests/userFileAttachmentModelTests.js
        reviewboard/static/rb/css/ui/dnd-uploader.less
        reviewboard/static/rb/js/resources/models/userFileAttachmentModel.es6.js
        reviewboard/static/rb/js/ui/views/textEditorView.es6.js
        reviewboard/static/rb/js/views/dndUploaderView.es6.js
        reviewboard/static/rb/js/pages/views/tests/reviewablePageViewTests.js
        reviewboard/static/rb/js/views/reviewReplyEditorView.js
        reviewboard/templates/reviews/review_request_box.html
        reviewboard/static/rb/css/pages/reviews.less
        reviewboard/static/rb/js/ui/views/tests/textEditorViewTests.js
        reviewboard/static/rb/css/common.less
        reviewboard/static/rb/css/defs.less
        reviewboard/static/rb/js/views/reviewRequestEditorView.js
        reviewboard/static/rb/js/pages/views/reviewablePageView.js
    
    
  2. 
      
brennie
  1. 
      
  2. Show all issues

    Since RB.BaseResource.prototype.defaults is a method that returns an object fo extra data, we'll want to make this a function.

    1. We can just call it as a function, actually.

      Looks like there are several other places with the same issue. I'll fix those up in a separate change.

  3. Show all issues

    Can we do:

    const url = `${SITE_ROOT}api/users/${this.get('username')}/file-attachments/`;
    

    or similar?

  4. Show all issues

    you can use { $target } here as shorthand for { $target: $target }

  5. reviewboard/static/rb/js/views/dndUploaderView.es6.js (Diff revision 1)
     
     
     
     
     
     
    Show all issues

    You can do:

    const target = new DnDDropTarget({
        $target,
        dropText,
        callback
    });
    
  6. 
      
david
reviewbot
  1. Tool: Pyflakes
    Processed Files:
        reviewboard/staticbundles.py
    
    Ignored Files:
        reviewboard/static/rb/js/resources/models/tests/userFileAttachmentModelTests.js
        reviewboard/static/rb/css/ui/dnd-uploader.less
        reviewboard/static/rb/js/resources/models/userFileAttachmentModel.es6.js
        reviewboard/static/rb/js/ui/views/textEditorView.es6.js
        reviewboard/static/rb/js/views/dndUploaderView.es6.js
        reviewboard/static/rb/js/pages/views/tests/reviewablePageViewTests.js
        reviewboard/static/rb/js/views/reviewReplyEditorView.js
        reviewboard/templates/reviews/review_request_box.html
        reviewboard/static/rb/css/pages/reviews.less
        reviewboard/static/rb/js/ui/views/tests/textEditorViewTests.js
        reviewboard/static/rb/css/common.less
        reviewboard/static/rb/css/defs.less
        reviewboard/static/rb/js/views/reviewRequestEditorView.js
        reviewboard/static/rb/js/pages/views/reviewablePageView.js
    
    
    
    Tool: PEP8 Style Checker
    Processed Files:
        reviewboard/staticbundles.py
    
    Ignored Files:
        reviewboard/static/rb/js/resources/models/tests/userFileAttachmentModelTests.js
        reviewboard/static/rb/css/ui/dnd-uploader.less
        reviewboard/static/rb/js/resources/models/userFileAttachmentModel.es6.js
        reviewboard/static/rb/js/ui/views/textEditorView.es6.js
        reviewboard/static/rb/js/views/dndUploaderView.es6.js
        reviewboard/static/rb/js/pages/views/tests/reviewablePageViewTests.js
        reviewboard/static/rb/js/views/reviewReplyEditorView.js
        reviewboard/templates/reviews/review_request_box.html
        reviewboard/static/rb/css/pages/reviews.less
        reviewboard/static/rb/js/ui/views/tests/textEditorViewTests.js
        reviewboard/static/rb/css/common.less
        reviewboard/static/rb/css/defs.less
        reviewboard/static/rb/js/views/reviewRequestEditorView.js
        reviewboard/static/rb/js/pages/views/reviewablePageView.js
    
    
  2. 
      
david
reviewbot
  1. Tool: PEP8 Style Checker
    Processed Files:
        reviewboard/staticbundles.py
    
    Ignored Files:
        reviewboard/static/rb/js/resources/models/tests/userFileAttachmentModelTests.js
        reviewboard/static/rb/css/ui/dnd-uploader.less
        reviewboard/static/rb/js/resources/models/userFileAttachmentModel.es6.js
        reviewboard/static/rb/js/ui/views/textEditorView.es6.js
        reviewboard/static/rb/js/views/dndUploaderView.es6.js
        reviewboard/static/rb/js/pages/views/tests/reviewablePageViewTests.js
        reviewboard/static/rb/js/views/reviewReplyEditorView.js
        reviewboard/templates/reviews/review_request_box.html
        reviewboard/static/rb/css/pages/reviews.less
        reviewboard/static/rb/js/ui/views/tests/textEditorViewTests.js
        reviewboard/static/rb/css/common.less
        reviewboard/static/rb/css/defs.less
        reviewboard/static/rb/js/views/reviewRequestEditorView.js
        reviewboard/static/rb/js/pages/views/reviewablePageView.js
    
    
    
    Tool: Pyflakes
    Processed Files:
        reviewboard/staticbundles.py
    
    Ignored Files:
        reviewboard/static/rb/js/resources/models/tests/userFileAttachmentModelTests.js
        reviewboard/static/rb/css/ui/dnd-uploader.less
        reviewboard/static/rb/js/resources/models/userFileAttachmentModel.es6.js
        reviewboard/static/rb/js/ui/views/textEditorView.es6.js
        reviewboard/static/rb/js/views/dndUploaderView.es6.js
        reviewboard/static/rb/js/pages/views/tests/reviewablePageViewTests.js
        reviewboard/static/rb/js/views/reviewReplyEditorView.js
        reviewboard/templates/reviews/review_request_box.html
        reviewboard/static/rb/css/pages/reviews.less
        reviewboard/static/rb/js/ui/views/tests/textEditorViewTests.js
        reviewboard/static/rb/css/common.less
        reviewboard/static/rb/css/defs.less
        reviewboard/static/rb/js/views/reviewRequestEditorView.js
        reviewboard/static/rb/js/pages/views/reviewablePageView.js
    
    
  2. 
      
chipx86
  1. Can you upload some screenshots? Would love to see this.

    1. A video/animation would also be very cool for this.

    2. Will make one tomorrow. I do want to tweak the visuals a bit but this change was getting pretty big already.

  2. 
      
chipx86
  1. 
      
  2. Show all issues

    Why do we need the !important? Can we rework things to not need it?

    1. We do need it. The files box is shown in jquery using show() and hide(), which updates the inline style in the DOM. This needs to take precedence over that.

  3. Show all issues

    What does the 64px relate to? Can we add a constant?

    1. It's just pulled out of a hat. I'll add a comment.

  4. reviewboard/static/rb/css/ui/dnd-uploader.less (Diff revision 3)
     
     
     
     
     
    Show all issues

    Can we add constants for these colors and border size?

    1. Constants are useful when things are used more than once. In this case they're not.

    2. I've been trying to move all "theme"-y values to constants so it's easier to update as we change styles. When I was doing the 2.5 restyling, it was much easier to work with the constants than to hunt for the values. I ended up adding constants for a lot of things because of it. I'd like to make this easier on my future self.

  5. Show all issues

    Can we use a relative font size (percentage)?

  6. Show all issues

    Same here.

  7. Show all issues

    Should use the standard multi-line comment format.

  8. Show all issues

    Are we limiting this exclusively to images? I can think of other file formats that would be useful in discussions.

    1. Well yes, because the markdown syntax will turn it into an <img> tag...

      Perhaps in the future we'll add the capability to insert some kind of download link instead for non-image types, but I think that's definitely a separate change.

  9. Show all issues

    "append"

  10. Show all issues

    This is too long.

  11. Show all issues

    While the new shorthand in ES6 probably has some good uses, I think it's not very future-proof. If anyone ever changes one of these variable names down the road for any reason (or in some other case where we use this syntax), we will break.

    I don't mind using it for the case where you're defining an object inline and want to give it those properties with those values, but when we're calling into another function (here or in findWhere above, for example), we should be explicit.

    1. I'm not sure I agree. It's new syntax to learn, and sure, it does require being aware of how it works, but it's no less fragile to search/replace than it would be if it were { $target: $target }, and it's a lot more DRY.

    2. Okay. I think this will bite us eventually in a confusing way, when someone mistakes the {} for a [] or something and starts changing variables, but go for it.

    3. And to clarify my position, I think these are useful for the case of creating local objects that you know are going to be based on particular variables and have those variables' names. Something like:

      function createFoo(a, b, c) {
          return {a, b, c};
      }
      

      I just don't like it when calling into external functions/objects. I like being explicit about saying "I'm fulfilling these specific keyword arguments/fields of this function/class, and providing these values," not "these keyword arguments/fields happen to match these variable names, yay magic."

  12. Show all issues

    One too many "anys," probably.

  13. 
      
david
reviewbot
  1. Tool: PEP8 Style Checker
    Processed Files:
        reviewboard/staticbundles.py
    
    Ignored Files:
        reviewboard/static/rb/js/resources/models/tests/userFileAttachmentModelTests.js
        reviewboard/static/rb/css/ui/dnd-uploader.less
        reviewboard/static/rb/js/resources/models/userFileAttachmentModel.es6.js
        reviewboard/static/rb/js/ui/views/textEditorView.es6.js
        reviewboard/static/rb/js/views/dndUploaderView.es6.js
        reviewboard/static/rb/js/pages/views/tests/reviewablePageViewTests.js
        reviewboard/static/rb/js/views/reviewReplyEditorView.js
        reviewboard/templates/reviews/review_request_box.html
        reviewboard/static/rb/css/pages/reviews.less
        reviewboard/static/rb/js/ui/views/tests/textEditorViewTests.js
        reviewboard/static/rb/css/common.less
        reviewboard/static/rb/css/defs.less
        reviewboard/static/rb/js/views/reviewRequestEditorView.js
        reviewboard/static/rb/js/pages/views/reviewablePageView.js
    
    
    
    Tool: Pyflakes
    Processed Files:
        reviewboard/staticbundles.py
    
    Ignored Files:
        reviewboard/static/rb/js/resources/models/tests/userFileAttachmentModelTests.js
        reviewboard/static/rb/css/ui/dnd-uploader.less
        reviewboard/static/rb/js/resources/models/userFileAttachmentModel.es6.js
        reviewboard/static/rb/js/ui/views/textEditorView.es6.js
        reviewboard/static/rb/js/views/dndUploaderView.es6.js
        reviewboard/static/rb/js/pages/views/tests/reviewablePageViewTests.js
        reviewboard/static/rb/js/views/reviewReplyEditorView.js
        reviewboard/templates/reviews/review_request_box.html
        reviewboard/static/rb/css/pages/reviews.less
        reviewboard/static/rb/js/ui/views/tests/textEditorViewTests.js
        reviewboard/static/rb/css/common.less
        reviewboard/static/rb/css/defs.less
        reviewboard/static/rb/js/views/reviewRequestEditorView.js
        reviewboard/static/rb/js/pages/views/reviewablePageView.js
    
    
  2. 
      
brennie
  1. 
      
  2. Show all issues

    You can do

    this.el.value += `\n${text}`;
    

    here

    1. I don't think that's really an improvement. Template strings are cool for medium-complexity things but for something simple like this I think it's more readable this way.

  3. Show all issues

    Same here.

  4. Show all issues

    (Almost) the same here.

  5. Show all issues

    And here.

  6. Show all issues

    Should these be .jpeg etc? Because I couldn't I upload foojpeg and it would allow it?

    Or do something like:

    return [/*...*/].some(extension => filename.endsWith(`.${extension}`));
    
  7. Show all issues

    You can do callback() {} in the object literal.

    1. As I think I've mentioned before, I like the callback() {} syntax when something looks like a class, but in this case it doesn't.

  8. 
      
chipx86
  1. Looks good. Only one comment, beyond Barret's that were fixed.

  2. Show all issues

    Can we put the comparison in parens, to help visually distinguish it better from the => ?

  3. 
      
david
reviewbot
  1. Tool: PEP8 Style Checker
    Processed Files:
        reviewboard/staticbundles.py
    
    Ignored Files:
        reviewboard/static/rb/js/resources/models/tests/userFileAttachmentModelTests.js
        reviewboard/static/rb/css/ui/dnd-uploader.less
        reviewboard/static/rb/js/resources/models/userFileAttachmentModel.es6.js
        reviewboard/static/rb/js/ui/views/textEditorView.es6.js
        reviewboard/static/rb/js/views/dndUploaderView.es6.js
        reviewboard/static/rb/js/pages/views/tests/reviewablePageViewTests.js
        reviewboard/static/rb/js/views/reviewReplyEditorView.js
        reviewboard/templates/reviews/review_request_box.html
        reviewboard/static/rb/css/pages/reviews.less
        reviewboard/static/rb/js/ui/views/tests/textEditorViewTests.js
        reviewboard/static/rb/css/common.less
        reviewboard/static/rb/css/defs.less
        reviewboard/static/rb/js/views/reviewRequestEditorView.js
        reviewboard/static/rb/js/pages/views/reviewablePageView.js
    
    
    
    Tool: Pyflakes
    Processed Files:
        reviewboard/staticbundles.py
    
    Ignored Files:
        reviewboard/static/rb/js/resources/models/tests/userFileAttachmentModelTests.js
        reviewboard/static/rb/css/ui/dnd-uploader.less
        reviewboard/static/rb/js/resources/models/userFileAttachmentModel.es6.js
        reviewboard/static/rb/js/ui/views/textEditorView.es6.js
        reviewboard/static/rb/js/views/dndUploaderView.es6.js
        reviewboard/static/rb/js/pages/views/tests/reviewablePageViewTests.js
        reviewboard/static/rb/js/views/reviewReplyEditorView.js
        reviewboard/templates/reviews/review_request_box.html
        reviewboard/static/rb/css/pages/reviews.less
        reviewboard/static/rb/js/ui/views/tests/textEditorViewTests.js
        reviewboard/static/rb/css/common.less
        reviewboard/static/rb/css/defs.less
        reviewboard/static/rb/js/views/reviewRequestEditorView.js
        reviewboard/static/rb/js/pages/views/reviewablePageView.js
    
    
  2. 
      
brennie
  1. Ship It!
  2. 
      
david
Review request changed
Status:
Completed
Change Summary:
Pushed to ucosp/dkus/dnd-inline-images (c85bea4)