Commit 15552810 authored by Nick Poulden's avatar Nick Poulden
Browse files

Comment re-factor

parent ecc11404
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ Ext.define('Docs.Application', {
        'Welcome',
        'Classes',
        'Comments',
        'CommentsMeta',
        'Search',
        'InlineExamples',
        'Examples',
+1 −0
Original line number Diff line number Diff line
@@ -212,4 +212,5 @@ Ext.define('Docs.controller.Auth', {

        return false;
    }

});
+16 −0
Original line number Diff line number Diff line
Ext.define('Docs.controller.AuthHelpers', {

    addSid: function(url) {
        var sid = this.getController('Auth').sid;
        return url + (url.match(/\?/) ? '&' : '?') + 'sid=' + sid;
    },

    loggedIn: function() {
        if (!this.getController('Auth').isLoggedIn()) {
            return false;
        } else {
            return true;
        }
    }

});
 No newline at end of file
+51 −121
Original line number Diff line number Diff line
/**
 * Retrieving and posting Comments
 */
Ext.define('Docs.controller.Comments', {
    extend: 'Ext.app.Controller',

    // baseUrl: 'http://projects.sencha.com/auth',
    baseUrl: 'http://127.0.0.1/sencha/jsduck_out/auth',

    mixins: {
        authMixin: 'Docs.controller.AuthHelpers'
    },

    refs: [
        {
            ref: 'toolbar',
@@ -21,55 +28,50 @@ Ext.define('Docs.controller.Comments', {

    init: function() {

        this.addEvents('afterMetaLoad');
        this.addEvents(
            /**
             * @event add  Fired after a comment is added
             * @param {String} key  Key of the comment
             */
            'add',

            /**
             * @event remove  Fired after a comment is removed
             * @param {String} key  Key of the comment
             */
            'remove'
        );

        this.getController('Auth').on({
            loggedIn:  function() {
                Docs.view.Comments.renderNewCommentForms();
            },
            loggedOut: function() {
                Docs.view.Comments.renderNewCommentForms()
            }
        });

        this.getController('Classes').on({
            showClass: function(cls, opts) {
                if (opts.reRendered) {
                    if (this.commentMeta) {
                        Docs.view.Comments.renderCommentMeta();
                    } else {
                        this.addListener('afterMetaLoad', function() {
                            Docs.view.Comments.renderCommentMeta();
                        }, this, {
                            single: true
                        });
                    Docs.view.Comments.renderClassCommentContainers(this.currentCls);
                }
            }
            },
            showIndex: function() {
                if (!this.commentMetaTotals) {
                    this.renderMetaToClassIndex = true;
                } else if (!this.renderedMetaToClassIndex) {
                    this.updateClassIndex();
                }
            },
            scope: this
        });

        this.getController('Auth').addListener('loggedIn', function() {
            this.loggedIn = true;
            Docs.view.Comments.renderNewCommentForms();
        }, this);

        this.getController('Auth').addListener('loggedOut', function() {
            this.loggedIn = false;
            Docs.view.Comments.renderNewCommentForms();
        }, this);

        this.control({
            'classoverview': {
                afterrender: function(cmp) {
                    // Map user interactions to methods
                    Ext.Array.each([
                        [ '.expandComments',   'click', this.toggleComments],
                        [ '.newCommentSubmit', 'click', this.postComment],
                        [ '.up',               'click', this.voteUp],
                        [ '.down',             'click', this.voteDown],
                        [ '.member-comments',  'click', this.showMemberComments],
                        [ '.del',              'click', this.promptDeleteComment],
                        [ '.new-comment-a',    'click', this.toggleNewComment],
                        [ '.commentGuide',     'click', this.toggleCommentGuide]
                        [ '.toggleComments',       'click', this.toggleComments],
                        [ '.toggleMemberComments', 'click', this.showMemberComments],
                        [ '.toggleNewComment',     'click', this.toggleNewComment],
                        [ '.toggleCommentGuide',   'click', this.toggleCommentGuide],
                        [ '.postComment',          'click', this.postComment],
                        [ '.deleteComment',        'click', this.promptDeleteComment],
                        [ '.voteCommentUp',        'click', this.voteUp],
                        [ '.voteCommentDown',      'click', this.voteDown]
                    ], function(delegate) {
                        cmp.el.addListener(delegate[1], delegate[2], this, {
                            preventDefault: true,
@@ -89,52 +91,7 @@ Ext.define('Docs.controller.Comments', {
                        delegate: '.comment-btn'
                    });
                }
            },

            'hovermenu': {
                viewready : function(cmp) {
                    if (this.commentMeta) {
                        Docs.view.Comments.renderHoverMenuMeta(cmp.el);
                    } else {
                        this.addListener('afterMetaLoad', function() {
                            Docs.view.Comments.renderHoverMenuMeta(cmp.el);
                        }, this, {
                            single: true
                        });
                    }
                }
            }
        });

        this.fetchCommentMeta();
    },

    fetchCommentMeta: function() {

        Ext.data.JsonP.request({
            url: this.baseUrl + '/comments/_design/Comments/_view/by_target',
            method: 'GET',
            params: {
                reduce: true,
                group_level: 3
            },
            success: function(response) {

                this.commentMeta = {};
                this.commentMetaTotals = {};
                this.commentIdMap = {};

                Ext.Array.each(response.rows, function(r) {
                    this.updateMeta(r.key, r.value.num);
                }, this);

                this.fireEvent('afterMetaLoad');

                if (this.renderMetaToClassIndex) {
                    this.updateClassIndex();
            }
            },
            scope: this
        });
    },

@@ -162,7 +119,7 @@ Ext.define('Docs.controller.Comments', {

    postComment: function(cmp, el) {

        if (!this.getController('Auth').isLoggedIn()) {
        if (!this.loggedIn()) {
            return false;
        }

@@ -181,7 +138,7 @@ Ext.define('Docs.controller.Comments', {
            },
            callback: function(options, success, response) {
                if (success) {
                    this.updateMeta(this.commentId(id), 1);
                    this.fireEvent('add', id);
                    comments.down('textarea').dom.value = '';
                    this.toggleNewComment(null, el);
                }
@@ -193,7 +150,7 @@ Ext.define('Docs.controller.Comments', {

    promptDeleteComment: function(cmp, el) {

        if (!this.getController('Auth').isLoggedIn()) {
        if (!this.loggedIn()) {
            return false;
        }

@@ -224,7 +181,7 @@ Ext.define('Docs.controller.Comments', {
                var data = Ext.JSON.decode(response.responseText);

                if (data.success) {
                    this.updateMeta(this.commentId(cls), -1);
                    this.fireEvent('remove', cls);
                    Ext.get(id).remove();
                }
            },
@@ -240,9 +197,12 @@ Ext.define('Docs.controller.Comments', {
        this.vote('down', el);
    },

    /**
     * @private
     */
    vote: function(direction, el) {

        if (!this.getController('Auth').isLoggedIn()) {
        if (!this.loggedIn()) {
            this.showError('Please login to vote on this comment', el);
            return false;
        }
@@ -334,12 +294,12 @@ Ext.define('Docs.controller.Comments', {
        });
        Docs.view.Comments.commentsTpl.append(comments, data);

        var commentTpl = (this.loggedIn ? Docs.view.Comments.loggedInCommentTpl : Docs.view.Comments.loggedOutCommentTpl);
        commentTpl.overwrite(comments.down('.new-comment-wrap'), this.loggedIn ? this.getController('Auth').currentUser : {});
        var commentTpl = (this.loggedIn() ? Docs.view.Comments.loggedInCommentTpl : Docs.view.Comments.loggedOutCommentTpl);
        commentTpl.overwrite(comments.down('.new-comment-wrap'), this.loggedIn() ? this.getController('Auth').currentUser : {});
    },

    toggleNewComment: function(cmp, el) {
        if (!this.loggedIn) {
        if (!this.loggedIn()) {
            return;
        }

@@ -359,38 +319,8 @@ Ext.define('Docs.controller.Comments', {
        Docs.view.Comments.commentTpl.insertBefore(newCommentWrap, data);
    },

    addSid: function(url) {
        var sid = this.getController('Auth').sid;
        return url + (url.match(/\?/) ? '&' : '?') + 'sid=' + sid;
    },

    updateClassIndex: function(meta) {

        for(var c in this.commentMetaTotals) {
            var cls = Ext.query('#classindex a[rel="' + c + '"]');
            if (cls && cls[0]) {
                Docs.view.Comments.memberCommentsTpl.append(cls[0], [String(this.commentMetaTotals[c])]);
            }
        }

        this.renderedMetaToClassIndex = true;
    },

    updateMeta: function(key, value) {
        var k = (key[2] === '') ? key[1] : key.slice(1,3).join('-'),
            c = key[1],
            divId = 'comments-class-' + k.replace(/\./g, '-');

        this.commentMeta[k] = this.commentMeta[k] || 0;
        this.commentMeta[k] += value;
        this.commentMetaTotals[c] = this.commentMetaTotals[c] || 0;
        this.commentMetaTotals[c] += value;

        this.commentIdMap[divId] = key;
    },

    commentId: function(id) {
        return this.commentIdMap[id] || ['unknown'];
        return Docs.commentMeta.idMap[id] || ['unknown'];
    },

    toggleCommentGuide: function(e, el) {
+165 −0
Original line number Diff line number Diff line
/**
 * Handles Comment meta data - the number of comments on a class and its members.
 * Also deals with keeping meta content up to date when comments are added or removed.
 */
Ext.define('Docs.controller.CommentsMeta', {
    extend: 'Ext.app.Controller',

    // baseUrl: 'http://projects.sencha.com/auth',
    baseUrl: 'http://127.0.0.1/sencha/jsduck_out/auth',

    refs: [
        {
            ref: 'toolbar',
            selector: 'classoverview toolbar'
        },
        {
            ref: 'authentication',
            selector: 'authentication'
        },
        {
            ref: 'overview',
            selector: 'classoverview'
        }
    ],

    init: function() {

        Docs.commentMeta = {
            idMap: {}
        };

        this.addEvents(
            /**
             * @event afterLoad  Fired after a meta data is loaded
             */
            'afterLoad'
        );

        this.getController('Comments').on({
            add: function(id) {
                this.updateMeta(Docs.commentMeta.idMap[id], 1);
                var clsId = Docs.commentMeta.idMap[id];
                Docs.view.Comments.updateClassCommentMeta(clsId[1]);
            },
            remove: function(id) {
                this.updateMeta(Docs.commentMeta.idMap[id], -1);
                var clsId = Docs.commentMeta.idMap[id];
                Docs.view.Comments.updateClassCommentMeta(clsId[1]);
            },
            scope: this
        });

        this.getController('Classes').on({
            showIndex: function() {
                if (!this.commentMetaTotals) {
                    this.renderMetaToClassIndex = true;
                } else if (!this.renderedMetaToClassIndex) {
                    this.updateClassIndex();
                }
            },
            showClass: function(cls, opts) {
                if (opts.reRendered) {
                    this.createCommentIdMap(this.getController('Classes').currentCls);
                    Docs.view.Comments.updateClassCommentMeta(cls);
                }
            },
            scope: this
        });

        this.control({
            'hovermenu': {
                viewready : function(cmp) {
                    if (this.commentMeta) {
                        Docs.view.Comments.renderHoverMenuMeta(cmp.el);
                    } else {
                        this.addListener('afterMetaLoad', function() {
                            Docs.view.Comments.renderHoverMenuMeta(cmp.el);
                        }, this, {
                            single: true
                        });
                    }
                }
            }
        });

        this.fetchCommentMeta();
    },

    fetchCommentMeta: function() {

        Ext.data.JsonP.request({
            url: this.baseUrl + '/comments/_design/Comments/_view/by_target',
            method: 'GET',
            params: {
                reduce: true,
                group_level: 3
            },
            success: function(response) {

                Ext.Array.each(response.rows, function(r) {
                    this.updateMeta(r.key, r.value.num);
                }, this);

                this.fireEvent('afterLoad');
                Docs.view.Comments.updateClassIndex();
            },
            scope: this
        });
    },

    updateVoteMeta: function() {

        var id = Docs.App.getController('Classes').currentCls.name,
            startkey = Ext.JSON.encode(['class',id]),
            endkey = Ext.JSON.encode(['class',id,{}]),
            currentUser = this.getController('Auth').currentUser;

        if (!id) return;

        Ext.data.JsonP.request({
            url: this.baseUrl + '/comments/_design/Comments/_list/with_vote/by_target',
            method: 'GET',
            params: {
                reduce: false,
                startkey: startkey,
                endkey: endkey,
                user: currentUser && currentUser.userName,
                votes: true
            },
            success: function(response) {
                console.log(response.rows)
            },
            scope: this
        });
    },

    updateMeta: function(key, value) {
        Docs.commentMeta[key[0]] = Docs.commentMeta[key[0]] || {};
        Docs.commentMeta[key[0]][key[1]] = Docs.commentMeta[key[0]][key[1]] || { total: 0 };
        Docs.commentMeta[key[0]][key[1]][key[2]] = Docs.commentMeta[key[0]][key[1]][key[2]] || 0;

        Docs.commentMeta[key[0]][key[1]][key[2]] += value;
        Docs.commentMeta[key[0]][key[1]]['total'] += value;
    },

    /**
     * Creates a mapping between comment element IDs and CouchDB view keys
     */
    createCommentIdMap: function(cls) {

        var key, commentId, member
        Docs.commentMeta.idMap[('comments-class-' + cls.name).replace(/\./g, '-')] = ['class', cls.name, ''];

        if (cls.members) {
            for(member in cls.members) {
                Ext.Array.each(cls.members[member], function(memberItem) {
                    key = ['class', cls.name, memberItem.id];
                    commentId = 'comments-' + key.join('-').replace(/\./g, '-');
                    Docs.commentMeta.idMap[commentId] = key;
                }, this);
            }
        }
    }

});
 No newline at end of file
Loading