From d0b2fdd3e8e5caaeaf4fd3b16783b7975b34e1d2 Mon Sep 17 00:00:00 2001 From: Repellent Date: Mon, 12 Jan 2026 11:17:49 +0500 Subject: [PATCH] =?UTF-8?q?=D0=B7=D0=B0=D0=BC=D0=B5=D0=BD=D0=B0=20js=20?= =?UTF-8?q?=D0=B0=D0=BB=D0=B5=D1=80=D1=82=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- js/comment.js | 167 +++++++++++++++++++++++++----------- templates/comments_tree.tpl | 69 ++++++++------- 2 files changed, 154 insertions(+), 82 deletions(-) diff --git a/js/comment.js b/js/comment.js index 3c188f3..64ae6f8 100644 --- a/js/comment.js +++ b/js/comment.js @@ -206,8 +206,6 @@ if ($fileInput.length && $fileInput[0].files.length > 0) { var $commentBlock = $btn.closest('.mod_comment_comment'); $commentBlock.fadeOut(300, function() { $(this).remove(); }); } -// показать / скрыть комментарий - // показать / скрыть комментарий if (action === 'unlock' || action === 'lock') { @@ -239,7 +237,7 @@ if (action === 'unlock' || action === 'lock') { $card.removeClass('opacity-75 border-warning'); - // Надежное скрытие: используем callback, чтобы после анимации точно убрать элемент + // используем callback, чтобы после анимации убрать элемент $card.find('.alert-warning').stop(true, true).fadeOut(300, function() { $(this).remove(); // Удаляем плашку из кода совсем, чтобы при следующем "скрыть" она создалась чисто }); @@ -391,50 +389,85 @@ $doc.on('mouseleave', '.rating-edit-block, #rating_wrapper', function() { $('#user_rating_stars_' + cid + ' .star-choice').removeClass('bi-star-fill').addClass('bi-star'); }); - // --- ГОЛОСОВАНИЕ (РЕЙТИНГ УЖЕ ОПУБЛИКОВАННЫХ) --- - $doc.on('mouseenter', '.star-item', function() { - var $parent = $(this).parent(); - if ($parent.hasClass('comment-like')) { - $(this).css('transform', 'scale(1.2)'); - } - else { - $(this).prevAll().addBack().removeClass('bi-star').addClass('bi-star-fill'); - $(this).nextAll().removeClass('bi-star-fill').addClass('bi-star'); - } - }); +// --- ГОЛОСОВАНИЕ (РЕЙТИНГ УЖЕ ОПУБЛИКОВАННЫХ) --- +$doc.on('mouseenter', '.star-item', function() { + var $parent = $(this).parent(); + if ($parent.hasClass('comment-like')) { + $(this).css('transform', 'scale(1.2)'); + } else { + $(this).prevAll().addBack().removeClass('bi-star').addClass('bi-star-fill'); + $(this).nextAll().removeClass('bi-star-fill').addClass('bi-star'); + } +}); - $doc.on('mouseleave', '.star-item', function() { - var $parent = $(this).parent(); - if ($parent.hasClass('comment-like')) { $(this).css('transform', 'scale(1)'); } - }); +$doc.on('mouseleave', '.star-item', function() { + var $parent = $(this).parent(); + if ($parent.hasClass('comment-like')) { $(this).css('transform', 'scale(1)'); } +}); - $doc.on('click', '.star-item', function() { - var $container = $(this).closest('.comment-rating-container'); - var commentId = $container.data('id'); - var voteValue = $(this).data('value'); +// Голосование +$(document).on('click', '.star-item', function() { + var $this = $(this); + // Находим основной контейнер звезд с рамкой + var $container = $this.closest('.comment-rating-container'); + var commentId = $container.data('id'); + var voteValue = $this.data('value'); - $.ajax({ - url: 'index.php?module=comment&action=vote&ajax=1', - type: 'POST', - data: { comment_id: commentId, vote: voteValue, ajax: 1 }, - success: function(response) { - var res = response.toString().trim(); - if (res.indexOf('success') !== -1) { - $container.html('' + COMMENT_JS_THX + ''); - setTimeout(function(){ location.reload(); }, 1000); - } else if (res.indexOf('already_voted') !== -1) { - alert(COMMENT_JS_VOTE_A); - } else if (res.indexOf('own_comment') !== -1) { - alert(COMMENT_JS_VOTE_B); - } else if (res.indexOf('forbidden_anon') !== -1) { - alert(COMMENT_JS_VOTE_C); - } else { - alert(COMMENT_JS_VOTE_ERR); - } - }, - error: function(xhr) {alert(COMMENT_JS_VOTE_ERR_A + ' ' + xhr.status);} + $.ajax({ + url: 'index.php?module=comment&action=vote&ajax=1', + type: 'POST', + data: { comment_id: commentId, vote: voteValue, ajax: 1 }, + success: function(response) { + var res = response.toString().trim(); + + // Функция для подмены блока на время + var showStatus = function(type, message, icon) { + var statusHtml = + '
' + + '' + + '' + message + '' + + '
'; + + // 1. Создаем объект алерта + var $newAlert = $(statusHtml); + + // 2. заменяем контейнер звезд на алерт + $container.replaceWith($newAlert); + + // 3. Через 4 секунды возвращаем звезды обратно + setTimeout(function() { + $newAlert.fadeOut(400, function() { + // Заменяем алерт обратно на сохраненный контейнер звезд + $(this).replaceWith($container); + $container.hide().fadeIn(300); }); - }); + }, 4000); + }; + + if (res.indexOf('success') !== -1) { + // При успехе заменяем содержимое на "Спасибо" и обновляем + $container.html('' + COMMENT_JS_THX + ''); + setTimeout(function(){ location.reload(); }, 1200); + } + else if (res.indexOf('already_voted') !== -1) { + showStatus('info', COMMENT_JS_VOTE_A, 'bi-info-circle-fill'); + } + else if (res.indexOf('own_comment') !== -1) { + showStatus('warning', COMMENT_JS_VOTE_B, 'bi-exclamation-triangle-fill'); + } + else if (res.indexOf('forbidden_anon') !== -1) { + showStatus('danger', COMMENT_JS_VOTE_C, 'bi-person-x-fill'); + } + else { + showStatus('danger', COMMENT_JS_VOTE_ERR, 'bi-x-circle-fill'); + } + }, + error: function(xhr) { + showStatus('danger', COMMENT_JS_VOTE_ERR_A + ' (Код: ' + xhr.status + ')', 'bi-wifi-off', 5000); + } + }); +}); $doc.on('click', '#mod_comment_close', function(e) { e.preventDefault(); cAction(this, 'close'); }); $doc.on('click', '#mod_comment_open', function(e) { e.preventDefault(); cAction(this, 'open'); }); @@ -459,11 +492,26 @@ $doc.on('mouseleave', '.rating-edit-block, #rating_wrapper', function() { $('#in_message').focus(); }); - // Удаление - $doc.off('click', '.mod_comment_delete').on('click', '.mod_comment_delete', function(e) { - e.preventDefault(); - if (confirm(COMMENT_JS_DELDEL_CONFIRM)) cAction(this, 'delete'); - }); +// Удаление через модальное окно Bootstrap +$doc.off('click', '.mod_comment_delete').on('click', '.mod_comment_delete', function(e) { + e.preventDefault(); + + var deleteBtn = this; // Запоминаем кнопку, на которую нажали + + // Инициализируем модальное окно Bootstrap + var modalElement = document.getElementById('deleteCommentModal'); + var confirmModal = new bootstrap.Modal(modalElement); + + // Показываем окно + confirmModal.show(); + + // Находим кнопку подтверждения внутри модалки + // Используем .one('click'), чтобы событие сработало только один раз + $('#confirmDeleteButton').off('click').one('click', function() { + cAction(deleteBtn, 'delete'); // Выполняем удаление + confirmModal.hide(); // Закрываем окно + }); +}); // Универсальный обработчик для переключателя видимости @@ -1037,7 +1085,28 @@ $doc.on('submit', '#mod_comment_new form', function(e) { beforeSend: function() { $btn.prop('disabled', true).text(COMMENT_JS_LOADS_R); }, success: function(data) { if (data.includes('wrong_securecode')) { - alert(COMMENT_JS_SEC_CODE_WRONG); + // Очищаем старую ошибку +$('#captcha_error_msg').empty(); +$('#securecode').removeClass('is-invalid'); + +// Создаем простой алерт Bootstrap под инпутом +var $err = $(''); + +// Вставляем и подсвечиваем +$('#captcha_error_msg').append($err); +$('#securecode').addClass('is-invalid').val('').focus(); + +// Автоудаление +setTimeout(function() { + $err.fadeOut(400, function() { + $(this).remove(); + $('#securecode').removeClass('is-invalid'); + }); +}, 6000); getCaptha(); $btn.prop('disabled', false).text(originalBtnText); $('#upload_progress_container').addClass('d-none'); diff --git a/templates/comments_tree.tpl b/templates/comments_tree.tpl index b1cde6c..fa63b0f 100644 --- a/templates/comments_tree.tpl +++ b/templates/comments_tree.tpl @@ -183,23 +183,24 @@ {/if} {/if} - {if $im} -
-
- - -
-
- - -
-
- {/if} +{if $im} +
+
+ + +
+
+ + +
+
+
+{/if}
{/if} - {* Модальное окно удаления *} - +{* Модальное окно удаления *} +