1/** 2 * Main Feed - Post Modal Flag (Report Post) 3 * 4 * Catches clicks on the flag trigger in the post modal header, slides 5 * in a report form panel, and submits to the 6 * `tradezing_flag_post_submission` AJAX endpoint (defined in 7 * cwicly/main-feed/ajax/post-flag-handler.php). 8 * 9 * Mirrors the profile-modal flag-form UX: 10 * - reason radio enables submit 11 * - "other" toggles a free-text textarea 12 * - submit -> AJAX -> success message -> auto-close after a beat 13 * 14 * Button visibility is driven by the AJAX response from post-modal-handler: 15 * when it injects `<div class="mfeed-post-flag-form">` (i.e. the post is 16 * flaggable â community post, not your own), we surface the trigger. 17 * MutationObserver picks this up automatically so we don't have to thread 18 * a `show_flag` flag through main-feed.js's openPostModal callback. 19 */ 20(function ($) { 21 'use strict'; 22 23 if (typeof mfeed_ajax === 'undefined') return; 24 25 var OVERLAY_SEL = '.mfeed-post-modal-overlay'; 26 var INNER_SEL = '.mfeed-post-modal-inner'; 27 var TRIGGER_SEL = '.mfeed-post-flag-trigger'; 28 var FORM_SEL = '.mfeed-post-flag-form'; 29 var FORM_EL_SEL = '.mfeed-post-flag-form-el'; 30 31 // Watch the modal's inner content. When the AJAX response injects (or 32 // omits) the flag-form panel, toggle the header trigger to match. 33 function watchPostModalContent() { 34 if (typeof MutationObserver === 'undefined') return; 35 var $inner = $(OVERLAY_SEL + ' ' + INNER_SEL).first(); 36 if (!$inner.length) return; 37 38 var inner = $inner[0]; 39 var trigger = document.querySelector(OVERLAY_SEL + ' ' + TRIGGER_SEL); 40 if (!trigger) return; 41 42 function sync() { 43 var hasForm = inner.querySelector(FORM_SEL) !== null; 44 trigger.style.display = hasForm ? 'flex' : 'none'; 45 } 46 47 // Run once on bind in case content is already there (rare, since 48 // the modal opens empty), then on every subsequent mutation. 49 sync(); 50 new MutationObserver(sync).observe(inner, { 51 childList: true, 52 subtree: true, 53 }); 54 } 55 56 function bindHandlers() { 57 // Open form panel. 58 $(document).on('click.tzPostFlag', OVERLAY_SEL + ' ' + TRIGGER_SEL, function (e) { 59 e.preventDefault(); 60 e.stopPropagation(); 61 var $form = $(OVERLAY_SEL + ' ' + FORM_SEL).first(); 62 if (!$form.length) return; 63 64 // Reset on every open â radios cleared, textarea empty, 65 // submit disabled, status banner cleared. 66 var $formEl = $form.find(FORM_EL_SEL); 67 $formEl.find('input[type="radio"]').prop('checked', false); 68 $formEl.find('textarea').val(''); 69 $formEl.find('.mfeed-post-flag-submit').prop('disabled', true).text('Report'); 70 $formEl.find('.mfeed-post-flag-status').empty().removeClass('is-error is-success'); 71 $formEl.find('.mfeed-post-flag-other').hide(); 72 $form.show(); 73 }); 74 75 // Cancel. 76 $(document).on('click.tzPostFlag', OVERLAY_SEL + ' .mfeed-post-flag-cancel', function (e) { 77 e.preventDefault(); 78 $(this).closest(FORM_SEL).hide(); 79 }); 80 81 // Reason radio change â enable submit, toggle "other" textarea. 82 $(document).on('change.tzPostFlag', 83 OVERLAY_SEL + ' input[name="reason_for_flagging"]', 84 function () { 85 var $formEl = $(this).closest(FORM_EL_SEL); 86 if (!$formEl.length) return; // belongs to a different modal 87 $formEl.find('.mfeed-post-flag-submit').prop('disabled', false); 88 $formEl.find('.mfeed-post-flag-other').toggle(this.value === 'other'); 89 } 90 ); 91 92 // Submit â AJAX to tradezing_flag_post_submission. 93 $(document).on('submit.tzPostFlag', OVERLAY_SEL + ' ' + FORM_EL_SEL, function (e) { 94 e.preventDefault(); 95 var $formEl = $(this); 96 var $status = $formEl.find('.mfeed-post-flag-status'); 97 var $submit = $formEl.find('.mfeed-post-flag-submit'); 98 99 $submit.prop('disabled', true).text('Reportingâ¦'); 100 $status.empty().removeClass('is-error is-success'); 101 102 $.ajax({ 103 type: 'POST', 104 url: mfeed_ajax.ajax_url, 105 data: $formEl.serialize() + '&action=tradezing_flag_post_submission', 106 success: function (res) { 107 if (res && res.success) { 108 $status 109 .addClass('is-success') 110 .text((res.data && res.data.message) 111 || 'Thanks for reporting. Our moderators have been notified.'); 112 $formEl.find('input[type="radio"]').prop('checked', false); 113 $formEl.find('textarea').val(''); 114 $formEl.find('.mfeed-post-flag-other').hide(); 115 $submit.text('Reported').prop('disabled', true); 116 setTimeout(function () { 117 $formEl.closest(FORM_SEL).hide(); 118 $submit.text('Report'); 119 }, 1800); 120 } else { 121 $status 122 .addClass('is-error') 123 .text((res && res.data && res.data.message) 124 || 'Something went wrong, please try again.'); 125 $submit.prop('disabled', false).text('Report'); 126 } 127 }, 128 error: function () { 129 $status.addClass('is-error').text('Network error, please try again.'); 130 $submit.prop('disabled', false).text('Report'); 131 } 132 }); 133 }); 134 } 135 136 $(function () { 137 bindHandlers(); 138 watchPostModalContent(); 139 }); 140 141})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.