]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
Better QnA ajax insert - work in progress
authorZach Copley <zach@status.net>
Fri, 15 Apr 2011 22:07:17 +0000 (15:07 -0700)
committerZach Copley <zach@status.net>
Mon, 18 Apr 2011 23:47:01 +0000 (16:47 -0700)
plugins/QnA/actions/qnanewanswer.php
plugins/QnA/js/qna.js
plugins/QnA/lib/qnanewanswerform.php

index f5eedbfac997b1b3507e496a674e5fc9676f5f37..e94b86fb3874cdedd5264d515cd5e4404734307a 100644 (file)
@@ -49,7 +49,7 @@ class QnanewanswerAction extends Action
     protected $error    = null;
     protected $complete = null;
 
-    protected $question = null;
+    public    $question = null;
     protected $content  = null;
 
     /**
@@ -162,30 +162,10 @@ class QnanewanswerAction extends Action
 
             $this->elementStart('body');
 
-            $nli = new NoticeListItem($notice, $this);
+            
+            $nli = new NoticeAnswerListItem($notice, $this);
             $nli->show();
-            //$this->raw($answer->asHTML());
-
-            /*
-            $question = $this->question;
-
-            $nli = new NoticeListItem($notice, $this);
-            $nli->showNotice();
-
-            $this->elementStart('div', array('class' => 'entry-content answer-content'));
-
-            if (!empty($answer)) {
-                $form = new QnashowanswerForm($this, $answer);
-                $form->show();
-            } else {
-                $this->text(_m('Answer data is missing.'));
-            }
-
-            $this->elementEnd('div');
-
-            // @fixme
-            //$this->elementStart('div', array('class' => 'entry-content'));
-            */
+  
             $this->elementEnd('body');
             $this->elementEnd('html');
         } else {
@@ -299,3 +279,41 @@ class QnanewanswerAction extends Action
     }
 
 }
+
+class NoticeAnswerListItem extends NoticeListItem
+{
+
+    protected $question;
+
+    /**
+     * constructor
+     *
+     * Also initializes the profile attribute.
+     *
+     * @param Notice $notice The notice we'll display
+     */
+    function __construct($notice, $out=null)
+    {
+        parent::__construct($notice, $out);
+        $this->question = $out->question;
+    }
+
+    function show()
+    {
+        if (empty($this->notice)) {
+            common_log(LOG_WARNING, "Trying to show missing notice; skipping.");
+            return;
+        } else if (empty($this->profile)) {
+            common_log(LOG_WARNING, "Trying to show missing profile (" . $this->notice->profile_id . "); skipping.");
+            return;
+        }
+
+        $this->showStart();
+        $this->showNotice();
+        $this->showNoticeInfo();
+        $notice = $this->question->getNotice();
+        $this->out->hidden('inreplyto', $notice->id);
+        $this->showEnd();
+    }
+
+}
\ No newline at end of file
index 5fa329f8933efd23a12402756f344295a37724e8..c83440452f0bfebd1050d3ec68850d72574d9690 100644 (file)
@@ -24,9 +24,6 @@ var QnA = {
         $('input[name=best]').live('click', function() {
             that.close(this);
         });
-
-
-
     },
 
     /**
@@ -88,8 +85,10 @@ var QnA = {
 
                 var openAnswers = $('li.notice-answer');
                     if (openAnswers.length > 0) {
+                        console.log("Found and open answer to close");
                         var target = $(e.target);
                         openAnswers.each(function() {
+                            console.log("found an open answer");
                             // Did we click outside this one?
                             var answerItem = $(this);
                             if (answerItem.has(e.target).length == 0) {
@@ -107,6 +106,7 @@ var QnA = {
                 });
 
             text.focus();
+            console.log('finished dealing with body click');
         };
 
         placeholder.hide();
@@ -159,15 +159,6 @@ var QnA = {
 
      },
 
-
-    AnswerFormSetup: function(form) {
-        console.log("AnswerFormSetup - begin");
-        if (!form.data('AnswerFormSetup')) {
-            form.data('AnswerFormSetup', true);
-        }
-        console.log("AnswerFormSetup - exit");
-    },
-
     /**
      * Setup function -- DOES NOT apply immediately.
      *
@@ -183,6 +174,208 @@ var QnA = {
                 return false;
             });
         console.log("NoticeInlineAnswerSetup - exit");
+    },
+
+    AnswerFormSetup: function(form) {
+        console.log("AnswerFormSetup");
+        $('input[type=submit]').live('click', function() {
+            console.log("AnswerFormSetup click");
+            QnA.FormAnswerXHR(form);
+        });
+    },
+
+
+   /**
+     * Setup function -- DOES NOT trigger actions immediately.
+     *
+     * Sets up event handlers for special-cased async submission of the
+     * notice-posting form, including some pre-post validation.
+     *
+     * Unlike FormXHR() this does NOT submit the form immediately!
+     * It sets up event handlers so that any method of submitting the
+     * form (click on submit button, enter, submit() etc) will trigger
+     * it properly.
+     *
+     * Also unlike FormXHR(), this system will use a hidden iframe
+     * automatically to handle file uploads via <input type="file">
+     * controls.
+     *
+     * @fixme tl;dr
+     * @fixme vast swaths of duplicate code and really long variable names clutter this function up real bad
+     * @fixme error handling is unreliable
+     * @fixme cookieValue is a global variable, but probably shouldn't be
+     * @fixme saving the location cache cookies should be split out
+     * @fixme some error messages are hardcoded english: needs i18n
+     * @fixme special-case for bookmarklet is confusing and uses a global var "self". Is this ok?
+     *
+     * @param {jQuery} form: jQuery object whose first element is a form
+     *
+     * @access public
+     */
+    FormAnswerXHR: function(form) {
+        console.log("FormAanwerXHR - begin");
+        //SN.C.I.NoticeDataGeo = {};
+        form.append('<input type="hidden" name="ajax" value="1"/>');
+        console.log("appended ajax flag");
+
+        // Make sure we don't have a mixed HTTP/HTTPS submission...
+        form.attr('action', SN.U.RewriteAjaxAction(form.attr('action')));
+        console.log("rewrote action");
+
+        /**
+         * Show a response feedback bit under the new-notice dialog.
+         *
+         * @param {String} cls: CSS class name to use ('error' or 'success')
+         * @param {String} text
+         * @access private
+         */
+        var showFeedback = function(cls, text) {
+            form.append(
+                $('<p class="form_response"></p>')
+                    .addClass(cls)
+                    .text(text)
+            );
+        };
+
+        /**
+         * Hide the previous response feedback, if any.
+         */
+        var removeFeedback = function() {
+            form.find('.form_response').remove();
+        };
+
+        console.log("doing ajax");
+
+        form.ajaxForm({
+            dataType: 'xml',
+            timeout: '60000',
+            beforeSend: function(formData) {
+                console.log("beforeSend");
+                if (form.find('.notice_data-text:first').val() == '') {
+                    form.addClass(SN.C.S.Warning);
+                    return false;
+                }
+                form
+                    .addClass(SN.C.S.Processing)
+                    .find('.submit')
+                        .addClass(SN.C.S.Disabled)
+                        .attr(SN.C.S.Disabled, SN.C.S.Disabled);
+
+                SN.U.normalizeGeoData(form);
+
+                return true;
+            },
+            error: function (xhr, textStatus, errorThrown) {
+                form
+                    .removeClass(SN.C.S.Processing)
+                    .find('.submit')
+                        .removeClass(SN.C.S.Disabled)
+                        .removeAttr(SN.C.S.Disabled, SN.C.S.Disabled);
+                removeFeedback();
+                if (textStatus == 'timeout') {
+                    // @fixme i18n
+                    showFeedback('error', 'Sorry! We had trouble sending your notice. The servers are overloaded. Please try again, and contact the site administrator if this problem persists.');
+                }
+                else {
+                    var response = SN.U.GetResponseXML(xhr);
+                    if ($('.'+SN.C.S.Error, response).length > 0) {
+                        form.append(document._importNode($('.'+SN.C.S.Error, response)[0], true));
+                    }
+                    else {
+                        if (parseInt(xhr.status) === 0 || jQuery.inArray(parseInt(xhr.status), SN.C.I.HTTP20x30x) >= 0) {
+                            form
+                                .resetForm()
+                                .find('.attach-status').remove();
+                            SN.U.FormNoticeEnhancements(form);
+                        }
+                        else {
+                            // @fixme i18n
+                            showFeedback('error', '(Sorry! We had trouble sending your notice ('+xhr.status+' '+xhr.statusText+'). Please report the problem to the site administrator if this happens again.');
+                        }
+                    }
+                }
+            },
+            success: function(data, textStatus) {
+                console.log("FormAnswerHXR success");
+                removeFeedback();
+                var errorResult = $('#'+SN.C.S.Error, data);
+                if (errorResult.length > 0) {
+                    showFeedback('error', errorResult.text());
+                }
+                else {
+
+                    // New notice post was successful. If on our timeline, show it!
+                    var notice = document._importNode($('li', data)[0], true);
+
+                    var notices = $('#notices_primary .notices:first');
+                    var replyItem = form.closest('li.notice-reply');
+
+                    if (replyItem.length > 0) {
+                        console.log("I found a reply li to append to");
+                        // If this is an inline reply, remove the form...
+                        var list = form.closest('.threaded-replies');
+                        var placeholder = list.find('.notice-answer-placeholder');
+                        replyItem.remove();
+
+                        var id = $(notice).attr('id');
+                        console.log("got notice id " + id);
+                        if ($("#"+id).length == 0) {
+                            console.log("inserting before placeholder");
+                            $(notice).insertBefore(placeholder);
+                        } else {
+                            // Realtime came through before us...
+                        }
+
+                        // ...and show the placeholder form.
+                        placeholder.show();
+                        console.log('qqqq made it this far')
+                    } else if (notices.length > 0 && SN.U.belongsOnTimeline(notice)) {
+                        // Not a reply. If on our timeline, show it at the top!
+                        if ($('#'+notice.id).length === 0) {
+                            console.log("couldn't find a notice id for " + notice.id);
+                            var notice_irt_value = form.find('#inreplyto').val();
+                            var notice_irt = '#notices_primary #notice-'+notice_irt_value;
+                            console.log("notice_irt value = " + notice_irt_value);
+                            if($('body')[0].id == 'conversation') {
+                                console.log("found conversation");
+                                if(notice_irt_value.length > 0 && $(notice_irt+' .notices').length < 1) {
+                                    $(notice_irt).append('<ul class="notices"></ul>');
+                                }
+                                $($(notice_irt+' .notices')[0]).append(notice);
+                            }
+                            else {
+                                console.log("prepending notice")
+                                notices.prepend(notice);
+                            }
+                            $('#'+notice.id)
+                                .css({display:'none'})
+                                .fadeIn(2500);
+                        }
+                    } else {
+                        // Not on a timeline that this belongs on?
+                        // Just show a success message.
+                        // @fixme inline
+                        showFeedback('success', $('title', data).text());
+                    }
+
+                    //form.resetForm();
+                    //SN.U.FormNoticeEnhancements(form);
+                }
+            },
+            complete: function(xhr, textStatus) {
+                form
+                    .removeClass(SN.C.S.Processing)
+                    .find('.submit')
+                        .removeAttr(SN.C.S.Disabled)
+                        .removeClass(SN.C.S.Disabled);
+
+                form.find('[name=lat]').val(SN.C.I.NoticeDataGeo.NLat);
+                form.find('[name=lon]').val(SN.C.I.NoticeDataGeo.NLon);
+                form.find('[name=location_ns]').val(SN.C.I.NoticeDataGeo.NLNS);
+                form.find('[name=location_id]').val(SN.C.I.NoticeDataGeo.NLID);
+                form.find('[name=notice_data-geo]').attr('checked', SN.C.I.NoticeDataGeo.NDG);
+            }
+        });
     }
 
 };
index ac8d2793bf04ee48dafd05327563a8e74688fc3e..73765b3639a4af9e1b299c86e1e07f04b39854d4 100644 (file)
@@ -81,7 +81,7 @@ class QnanewanswerForm extends Form
      */
     function formClass()
     {
-        return 'form_settings ajax';
+        return 'form_settings qna_answer_form';
     }
 
     /**