Commit 39d1318d authored by Rene Saarsoo's avatar Rene Saarsoo
Browse files

Drag-drop of comments to organize them into threads.

This is the implementation of just the visual side of dragging.
Everything that happens after the drop is still unimplemented.
parent 6bf8ce04
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -280,11 +280,12 @@ Ext.define('Docs.Comments', {
    /**
     * Generates an `<img>` tag for loading the avatar.
     * @param {String} emailHash MD5 hash of users e-mail address.
     * @param {String} [cls] Additional CSS class or classes to add to the image.
     * @return {String}
     */
    avatar: function(emailHash) {
        return '<img class="avatar" width="25" height="25" src="http://www.gravatar.com/avatar/' +
               emailHash + '?s=25&amp;r=PG&amp;d=identicon">';
    avatar: function(emailHash, cls) {
        return '<img class="avatar ' + (cls || "") + '" width="25" height="25" ' +
               'src="http://www.gravatar.com/avatar/' + emailHash + '?s=25&amp;r=PG&amp;d=identicon">';
    },

    /**
+39 −0
Original line number Diff line number Diff line
/**
 * DragZone for comments drag-drop reorganization.
 */
Ext.define("Docs.view.comments.DragZone", {
    extend: 'Ext.dd.DragZone',

    constructor: function(view, config) {
        this.view = view;
        this.callParent([view.getEl(), config]);
    },

    getDragData: function(e) {
        var avatarEl = e.getTarget("img.drag-handle", 10);
        if (avatarEl) {
            var sourceEl = Ext.fly(avatarEl).up(this.view.itemSelector).dom;
            return {
                sourceEl: sourceEl,
                repairXY: Ext.fly(sourceEl).getXY(),
                ddel: this.cloneCommentEl(sourceEl),
                comment: this.view.getRecord(sourceEl)
            };
        }
        return false;
    },

    cloneCommentEl: function(el) {
        var clone = el.cloneNode(true);
        // hide the list of replies, we don't want to drag such a huge object.
        var replies = Ext.fly(clone).down(".comments-list-with-form");
        replies && replies.remove();
        // generate new ID
        clone.id = Ext.id();
        return clone;
    },

    getRepairXY: function() {
        return this.dragData.repairXY;
    }
});
+48 −0
Original line number Diff line number Diff line
/**
 * DropZone for comments drag-drop reorganization.
 */
Ext.define("Docs.view.comments.DropZone", {
    extend: 'Ext.dd.DropZone',

    constructor: function(view, config) {
        this.view = view;
        this.callParent([view.getEl(), config]);
    },

    getTargetFromEvent: function(e) {
        return e.getTarget(this.view.itemSelector, 10);
    },

    onNodeEnter: function(target, dd, e, data) {
        if (this.isValidDropTarget(target, data)) {
            Ext.fly(target).addCls('drop-target-hover');
        }
    },

    onNodeOut: function(target, dd, e, data) {
        Ext.fly(target).removeCls('drop-target-hover');
    },

    onNodeOver: function(target, dd, e, data) {
        if (this.isValidDropTarget(target, data)) {
            // Return the built-in dropAllowed CSS class.
            return this.dropAllowed;
        }
        else {
            return false;
        }
    },

    isValidDropTarget: function(target, data) {
        var targetComment = this.view.getRecord(target);
        return targetComment && targetComment.get("id") !== data.comment.get("id");
    },

    onNodeDrop: function(target, dd, e, data) {
        if (this.isValidDropTarget(target, data)) {
            alert("drop!");
            return true;
        }
        return false;
    }
});
+6 −0
Original line number Diff line number Diff line
@@ -12,6 +12,8 @@ Ext.define('Docs.view.comments.List', {
        'Docs.view.comments.Form',
        'Docs.view.comments.TagEditor',
        'Docs.view.comments.RepliesExpander',
        'Docs.view.comments.DragZone',
        'Docs.view.comments.DropZone',
        'Docs.model.Comment',
        'Docs.Tip'
    ],
@@ -93,6 +95,10 @@ Ext.define('Docs.view.comments.List', {

        this.delegateClick("a.add-tag", this.addTag, this);
        this.delegateClick("a.remove-tag", this.removeTag, this);

        // initialize drag-drop
        new Docs.view.comments.DragZone(this);
        new Docs.view.comments.DropZone(this);
    },

    delegateClick: function(selector, callback, scope) {
+6 −1
Original line number Diff line number Diff line
@@ -42,7 +42,7 @@ Ext.define('Docs.view.comments.Template', {
                        '<div class="deleted-comment">Comment was deleted. <a href="#" class="undoDeleteComment">Undo</a>.</div>',
                    '<tpl else>',
                        '<div class="com-meta">',
                            '{[Docs.Comments.avatar(values.emailHash)]}',
                            '{[this.avatar(values.emailHash)]}',
                            '<div class="author<tpl if="moderator"> moderator" title="Sencha Engineer</tpl>">',
                                '{author}',
                                '<tpl if="this.isTargetVisible()">',
@@ -88,6 +88,11 @@ Ext.define('Docs.view.comments.Template', {
        ]);
    },

    avatar: function(emailHash) {
        // turns avatars into drag-handles for moderators.
        return Docs.Comments.avatar(emailHash, this.isMod() ? "drag-handle" : "");
    },

    isTargetVisible: function() {
        return this.showTarget;
    },
Loading