Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
// This file is part of Moodle - http://moodle.org/
2
//
3
// Moodle is free software: you can redistribute it and/or modify
4
// it under the terms of the GNU General Public License as published by
5
// the Free Software Foundation, either version 3 of the License, or
6
// (at your option) any later version.
7
//
8
// Moodle is distributed in the hope that it will be useful,
9
// but WITHOUT ANY WARRANTY; without even the implied warranty of
10
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
// GNU General Public License for more details.
12
//
13
// You should have received a copy of the GNU General Public License
14
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
15
 
16
/**
17
 * This module handles the in page replying to forum posts.
18
 *
19
 * @module     mod_forum/inpage_reply
20
 * @copyright  2019 Peter Dias
21
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
22
 */
23
define([
24
    'jquery',
25
    'core/templates',
26
    'core/notification',
27
    'mod_forum/repository',
28
    'mod_forum/selectors',
29
    'core_form/changechecker',
30
], function(
31
    $,
32
    Templates,
33
    Notification,
34
    Repository,
35
    Selectors,
36
    FormChangeChecker
37
) {
38
 
39
    var DISPLAYCONSTANTS = {
40
        NESTED_V2: 4,
41
        THREADED: 2,
42
        NESTED: 3,
43
        FLAT_OLDEST_FIRST: 1,
44
        FLAT_NEWEST_FIRST: -1
45
    };
46
 
47
    var EVENTS = {
48
        POST_CREATED: 'mod_forum-post-created'
49
    };
50
 
51
     /**
52
      * Moodle formats taken from the FORMAT_* constants declared in lib/weblib.php.
53
      * @type {Object}
54
      */
55
    var CONTENT_FORMATS = {
56
        MOODLE: 0
57
    };
58
    /**
59
     * Show the loading icon for the submit button.
60
     *
61
     * @param {Object} button The submit button element
62
     */
63
    var showSubmitButtonLoadingIcon = function(button) {
64
        var textContainer = button.find(Selectors.post.inpageSubmitBtnText);
65
        var loadingIconContainer = button.find(Selectors.post.loadingIconContainer);
66
        var width = button.outerWidth();
67
        // Fix the width so that the button size doesn't change when we show the loading icon.
68
        button.css('width', width);
69
        textContainer.addClass('hidden');
70
        loadingIconContainer.removeClass('hidden');
71
    };
72
 
73
    /**
74
     * Hide the loading icon for the submit button.
75
     *
76
     * @param {Object} button The submit button element
77
     */
78
    var hideSubmitButtonLoadingIcon = function(button) {
79
        var textContainer = button.find(Selectors.post.inpageSubmitBtnText);
80
        var loadingIconContainer = button.find(Selectors.post.loadingIconContainer);
81
        // Reset the width back to it's default.
82
        button.css('width', '');
83
        textContainer.removeClass('hidden');
84
        loadingIconContainer.addClass('hidden');
85
    };
86
 
87
    /**
88
     * Register the event listeners for the submit/cancel buttons of the in page reply.
89
     *
90
     * @param {Object} root The discussion container element.
91
     */
92
    var registerEventListeners = function(root) {
93
        root.on('click', Selectors.post.inpageSubmitBtn, function(e) {
94
            e.preventDefault();
95
            var submitButton = $(e.currentTarget);
96
            var allButtons = submitButton.parent().find(Selectors.post.inpageReplyButton);
97
            var form = submitButton.parents(Selectors.post.inpageReplyForm).get(0);
98
            var message = form.elements.post.value.trim();
99
            // For now, we consider the inline reply post written using the FORMAT_MOODLE (because a textarea is displayed).
100
            // In the future, other formats should be supported, letting users to use their preferred editor and format.
101
            var messageformat = CONTENT_FORMATS.MOODLE;
102
            // The message post will be converted from messageformat to FORMAT_HTML.
103
            var topreferredformat = true;
104
            var postid = form.elements.reply.value;
105
            var subject = form.elements.subject.value;
106
            var currentRoot = submitButton.closest(Selectors.post.post);
107
            var isprivatereply = form.elements.privatereply != undefined ? form.elements.privatereply.checked : false;
108
            var modeSelector = root.find(Selectors.post.modeSelect);
109
            var mode = modeSelector.length ? parseInt(modeSelector.get(0).value) : null;
110
            var newid;
111
 
112
            if (message.length) {
113
                showSubmitButtonLoadingIcon(submitButton);
114
                allButtons.prop('disabled', true);
115
 
116
                Repository.addDiscussionPost(postid, subject, message, messageformat, isprivatereply, topreferredformat)
117
                    .then(function(context) {
118
                        var message = context.messages.reduce(function(carry, message) {
119
                            if (message.type == 'success') {
120
                                carry += '<p>' + message.message + '</p>';
121
                            }
122
                            return carry;
123
                        }, '');
124
                        Notification.addNotification({
125
                            message: message,
126
                            type: "success"
127
                        });
128
 
129
                        return context;
130
                    })
131
                    .then(function(context) {
132
                        form.reset();
133
                        var post = context.post;
134
                        newid = post.id;
135
 
136
                        switch (mode) {
137
                            case DISPLAYCONSTANTS.NESTED_V2:
138
                                var capabilities = post.capabilities;
139
                                var currentAuthorName = currentRoot.children()
140
                                                                   .not(Selectors.post.repliesContainer)
141
                                                                   .find(Selectors.post.authorName)
142
                                                                   .text();
143
                                post.parentauthorname = currentAuthorName;
144
                                post.showactionmenu = capabilities.view ||
145
                                                      capabilities.controlreadstatus ||
146
                                                      capabilities.edit ||
147
                                                      capabilities.split ||
148
                                                      capabilities.delete ||
149
                                                      capabilities.export ||
150
                                                      post.urls.viewparent;
151
                                return Templates.render('mod_forum/forum_discussion_nested_v2_post_reply', post);
152
                            case DISPLAYCONSTANTS.THREADED:
153
                                return Templates.render('mod_forum/forum_discussion_threaded_post', post);
154
                            case DISPLAYCONSTANTS.NESTED:
155
                                return Templates.render('mod_forum/forum_discussion_nested_post', post);
156
                            default:
157
                                return Templates.render('mod_forum/forum_discussion_post', post);
158
                        }
159
                    })
160
                    .then(function(html, js) {
161
                        var repliesnode = currentRoot.find(Selectors.post.repliesContainer).first();
162
 
163
                        if (mode == DISPLAYCONSTANTS.FLAT_NEWEST_FIRST) {
164
                            return Templates.prependNodeContents(repliesnode, html, js);
165
                        } else {
166
                            return Templates.appendNodeContents(repliesnode, html, js);
167
                        }
168
                    })
169
                    .then(function() {
170
                        submitButton.trigger(EVENTS.POST_CREATED, newid);
171
                        hideSubmitButtonLoadingIcon(submitButton);
172
                        allButtons.prop('disabled', false);
173
 
174
                        // Tell formchangechecker we submitted the form.
175
                        FormChangeChecker.resetFormDirtyState(submitButton[0]);
176
 
177
                        return currentRoot.find(Selectors.post.inpageReplyContent).hide();
178
                    })
179
                    .then(function() {
180
                        location.href = "#p" + newid;
181
 
182
                        // Reload the page, say if threshold is being set by user those would get reflected through the templates.
183
                        location.reload();
184
                    })
185
                    .catch(function(error) {
186
                        hideSubmitButtonLoadingIcon(submitButton);
187
                        allButtons.prop('disabled', false);
188
                        return Notification.exception(error);
189
                    });
190
            }
191
        });
192
 
193
        root.on('click', Selectors.post.inpageCancelButton, function(e) {
194
            // Tell formchangechecker to reset the form state.
195
            FormChangeChecker.resetFormDirtyState(e.currentTarget);
196
        });
197
    };
198
 
199
    return {
200
        init: function(root) {
201
            registerEventListeners(root);
202
        },
203
        CONTENT_FORMATS: CONTENT_FORMATS,
204
        EVENTS: EVENTS
205
    };
206
});