/* ==================================================================== ОБЕРТКА ДЛЯ ОЖИДАНИЯ JQUERY ==================================================================== */ (function waitForJQuery() { if (typeof jQuery === 'undefined') { setTimeout(waitForJQuery, 10); } else { (function($) { if (typeof aveabspath === 'undefined') { window.aveabspath = '/'; } /* --- ТАЙМЕРЫ --- */ function initCommentTimers() { $('.timer-count:not(.timer-running)').each(function() { var $timer = $(this); $timer.addClass('timer-running'); var timeLeft = parseInt($timer.attr('data-left')); var cid = $timer.attr('id').replace('timer_', ''); var countdown = setInterval(function() { timeLeft--; if (timeLeft <= 0) { clearInterval(countdown); // Пытаемся найти блок управления по ID var $controls = $('#controls_' + cid); if ($controls.length) { // Скрываем кнопки $controls.fadeOut(300, function() { $(this).remove(); // Полностью удаляем из DOM для надежности }); } // Обновляем статус таймера $('#timer_container_' + cid).html(' Время на правку истекло'); return; } var minutes = Math.floor(timeLeft / 60); var seconds = timeLeft % 60; $timer.text(minutes + ':' + (seconds < 10 ? '0' : '') + seconds); $timer.attr('data-left', timeLeft); }, 1000); $timer.data('interval-id', countdown); }); } /* Limit Plugin */ $.fn.extend({ limit: function(limit, element) { return this.each(function() { var self = $(this); function substring() { var val = self.val(); if (val.length > limit) self.val(val.substring(0, limit)); if (typeof element !== 'undefined') { var remaining = limit - self.val().length; $(element).html(remaining < 0 ? '0' : remaining); } } self.on('focus keyup paste', substring); substring(); }); } }); function getCaptha() { var now = new Date(); $('#captcha img').attr('src', aveabspath + 'inc/captcha.php?cd=' + now.getTime()); } // ВАЛИДАЦИЯ ПОЛЕЙ function validate(form) { var isValid = true; // Вспомогательная функция для подсветки function setInvalid($el, show, msg) { if (show) { $el.addClass('is-invalid'); if ($el.next('.invalid-feedback').length === 0) { $el.after('
' + msg + '
'); } isValid = false; } else { $el.removeClass('is-invalid'); $el.next('.invalid-feedback').remove(); } } // Проверка Имени setInvalid($(form.comment_author_name), !form.comment_author_name.value.trim(), "Введите ваше имя"); // Проверка Email setInvalid($(form.comment_author_email), !form.comment_author_email.value.trim(), "Введите корректный Email"); // Проверка Доп. поля №1 (если оно обязательное) if (typeof REQ_F1 !== 'undefined' && REQ_F1 == '1') { var f1 = $('#in_author_website'); setInvalid(f1, !f1.val().trim(), "Заполните: " + NAME_F1); } // Проверка Доп. поля №2 (если оно обязательное) if (typeof REQ_F2 !== 'undefined' && REQ_F2 == '1') { var f2 = $('#in_author_city'); setInvalid(f2, !f2.val().trim(), "Заполните: " + NAME_F2); } // Проверка Текста setInvalid($(form.comment_text), !form.comment_text.value.trim(), "Введите текст комментария"); if (!isValid) { // Скроллим к первой ошибке $('html, body').animate({ scrollTop: $('.is-invalid:first').offset().top - 130 }, 300); } return isValid; } /* --- ДЕЙСТВИЯ (DELETE, LOCK, OPEN/CLOSE, VOTE) --- */ function cAction(obj, action) { var $btn = $(obj); var cid = $btn.data('id'); if (!cid && action !== 'open' && action !== 'close') return; $.get(aveabspath + 'index.php', { module: 'comment', action: action, docid: typeof DOC_ID !== 'undefined' ? DOC_ID : '', Id: cid ? cid : '' }, function() { if (action === 'close') { $btn.attr('id', 'mod_comment_open') .removeClass('btn-outline-danger').addClass('btn-outline-success') .html(' ' + COMMENT_SITE_OPEN); $('#mod_comment_new').fadeOut(300); } else if (action === 'open') { $btn.attr('id', 'mod_comment_close') .removeClass('btn-outline-success').addClass('btn-outline-danger') .html(' ' + COMMENT_SITE_CLOSE); $('#mod_comment_new').fadeIn(300); } if (action === 'delete') { var $commentBlock = $btn.closest('.mod_comment_comment'); $commentBlock.fadeOut(300, function() { $(this).remove(); }); } if (action === 'unlock' || action === 'lock') { var isLock = (action === 'lock'); $btn.toggleClass('mod_comment_lock mod_comment_unlock text-dark text-success') .attr('title', isLock ? 'Разблокировать' : 'Заблокировать') .find('i').toggleClass('bi-lock-fill bi-unlock-fill'); } }); } /* --- ИНИЦИАЛИЗАЦИЯ --- */ $(document).ready(function() { initCommentTimers(); var $doc = $(document); // Убираем красную рамку, когда пользователь начинает исправлять поле $doc.on('input change', '.form-control', function() { $(this).removeClass('is-invalid'); $(this).next('.invalid-feedback').fadeOut(200, function() { $(this).remove(); }); }); // Счетчик: Количество оставшихся символов 1000 для формы создания комментария $('#in_message').limit(1000, '#charsLeft_new'); // --- ЛОГИКА ПРЕДПРОСМОТРА ИЗОБРАЖЕНИЯ (НОВАЯ ФОРМА) --- $doc.on('change', '#comment_image', function() { var input = this; if (input.files && input.files[0]) { var reader = new FileReader(); reader.onload = function(e) { $('#image_preview_img').attr('src', e.target.result); $('#image_preview_wrapper').removeClass('d-none'); } reader.readAsDataURL(input.files[0]); } }); $doc.on('click', '#remove_image_btn', function() { $('#comment_image').val(''); $('#image_preview_wrapper').addClass('d-none'); $('#image_preview_img').attr('src', '#'); }); // --- ЛОГИКА ВЫБОРА РЕЙТИНГА В ФОРМЕ --- $doc.on('mouseenter', '.star-choice', function() { var val = $(this).data('value'); $(this).parent().find('.star-choice').each(function() { if ($(this).data('value') <= val) { $(this).removeClass('bi-star').addClass('bi-star-fill'); } else { $(this).removeClass('bi-star-fill').addClass('bi-star'); } }); }); $doc.on('mouseleave', '.rating-edit-block', function() { var cid = $(this).find('input[type="hidden"]').attr('id').replace('rating_input_', ''); var currentRating = parseInt($('#rating_input_' + cid).val()) || 0; $(this).find('.star-choice').each(function() { if ($(this).data('value') <= currentRating) { $(this).removeClass('bi-star').addClass('bi-star-fill'); } else { $(this).removeClass('bi-star-fill').addClass('bi-star'); } }); }); $doc.on('click', '.star-choice', function() { var val = $(this).data('value'); var ratingInput = $(this).closest('.rating-edit-block').find('input[type="hidden"]'); if (ratingInput.length) { ratingInput.val(val); } else { $('#comment_user_rating').val(val); } $(this).prevAll().addBack().removeClass('bi-star').addClass('bi-star-fill'); $(this).nextAll().removeClass('bi-star-fill').addClass('bi-star'); }); $doc.on('click', '#buttonReset', function() { $('#comment_user_rating').val(0); $('#user_rating_stars .star-choice').removeClass('bi-star-fill').addClass('bi-star'); $('#image_preview_wrapper').addClass('d-none'); $('#charsLeft_new').text(MAX_CHARS); $('.form-control').removeClass('is-invalid'); $('.invalid-feedback').remove(); }); $doc.on('click', '#reset_stars', function(e) { e.preventDefault(); $('#comment_user_rating').val(0); $('#user_rating_stars .star-choice').removeClass('bi-star-fill').addClass('bi-star'); }); $doc.on('click', '.reset-edit-stars', function(e) { e.preventDefault(); var cid = $(this).data('id'); $('#rating_input_' + cid).val(0); $('#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('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'); $.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('Спасибо!'); setTimeout(function(){ location.reload(); }, 1000); } else if (res.indexOf('already_voted') !== -1) { alert('Вы уже голосовали за этот комментарий.'); } else if (res.indexOf('own_comment') !== -1) { alert('Нельзя голосовать за свой собственный комментарий.'); } else if (res.indexOf('forbidden_anon') !== -1) { alert('Голосование доступно только зарегистрированным пользователям.'); } else { alert('Ошибка при обработке голоса сервером.'); } }, error: function(xhr) { alert('Ошибка связи с сервером. Статус: ' + xhr.status); } }); }); $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'); }); // КНОПКА ОТВЕТА $doc.off('click', '.mod_comment_answer').on('click', '.mod_comment_answer', function(e) { e.preventDefault(); var cid = $(this).data('id'); var $form = $('#mod_comment_new'); $form.insertAfter('#comment_' + cid).show(); $('#parent_id').val(cid); $('html, body').animate({ scrollTop: $form.offset().top - 150 }, 500); $('#in_message').focus(); }); // Удаление $doc.off('click', '.mod_comment_delete').on('click', '.mod_comment_delete', function(e) { e.preventDefault(); if (confirm('Удалить этот комментарий?')) cAction(this, 'delete'); }); // Блокировка $doc.off('click', '.mod_comment_lock, .mod_comment_unlock').on('click', '.mod_comment_lock, .mod_comment_unlock', function(e) { e.preventDefault(); cAction(this, $(this).hasClass('mod_comment_lock') ? 'lock' : 'unlock'); }); // --- РЕДАКТИРОВАНИЕ (С ПРЕДПРОСМОТРОМ ТЕКУЩЕГО ФОТО) --- $doc.off('click', '.mod_comment_edit').on('click', '.mod_comment_edit', function(e) { e.preventDefault(); var cid = $(this).data('id'); var $wrapper = $('#comment_wrapper_' + cid); var $textBlock = $wrapper.find('.mod_comment_text').first(); if ($wrapper.find('.edit-form-container').length > 0) return; var isMyOwn = $wrapper.attr('data-is-own') == '1'; var currentRating = parseInt($wrapper.attr('data-user-rating')) || 0; $('.edit-form-container').remove(); $('.mod_comment_text').show(); var cleanText = $textBlock.html().replace(//mg, "\n").trim(); var currentImg = $wrapper.find('.mod_comment_attached_image img').first().attr('src'); var starsEditBlock = ''; if (typeof SHOW_USER_RATING !== 'undefined' && SHOW_USER_RATING == '1' && isMyOwn) { if (typeof UGROUP !== 'undefined' && (UGROUP != '2' || RATING_ANON_SET == '1')) { var starsHtml = ''; for(var i=1; i<=5; i++) { var starClass = (i <= currentRating) ? 'bi-star-fill' : 'bi-star'; starsHtml += ``; } starsEditBlock = `
${starsHtml}
Сбросить
`; } } // Обертка для ТЕКУЩЕГО изображения с крестиком (как при загрузке) var currentImgPreview = ''; if (currentImg) { currentImgPreview = `
`; } var fileInputHtml = ''; if (typeof UGROUP !== 'undefined' && (UGROUP != '2' || (typeof ALLOW_FILES_ANON !== 'undefined' && ALLOW_FILES_ANON == '1'))) { fileInputHtml = `
Превью
`; } var editHtml = `
${starsEditBlock} ${currentImgPreview} ${fileInputHtml}
Осталось:
`; $textBlock.hide().after(editHtml); $('#ta_' + cid).limit(1000, '#charsLeft_' + cid).focus(); }); // Удаление ТЕКУЩЕГО изображения при редактировании $doc.on('click', '.remove-existing-img', function() { var cid = $(this).data('id'); $('#existing_preview_wrapper_' + cid).addClass('d-none'); $('#del_img_' + cid).prop('checked', true); // Помечаем скрытый чекбокс на удаление }); // Обработка выбора НОВОГО файла при редактировании $doc.on('change', 'input[id^="new_file_"]', function() { var cid = $(this).attr('id').replace('new_file_', ''); var input = this; if (input.files && input.files[0]) { var reader = new FileReader(); reader.onload = function(e) { $('#edit_preview_img_' + cid).attr('src', e.target.result); $('#edit_preview_wrapper_' + cid).removeClass('d-none'); // Если выбрали новый файл, старое превью логично скрыть $('#existing_preview_wrapper_' + cid).addClass('d-none'); $('#del_img_' + cid).prop('checked', true); } reader.readAsDataURL(input.files[0]); } }); // Удаление НОВОГО выбранного файла в режиме редактирования $doc.on('click', '.remove-edit-new-img', function() { var cid = $(this).data('id'); $('#new_file_' + cid).val(''); $('#edit_preview_wrapper_' + cid).addClass('d-none'); }); $doc.on('click', '.cancelButton', function() { var $container = $(this).closest('.edit-form-container'); $container.prev('.mod_comment_text').show(); $container.remove(); }); $doc.on('click', '.saveButton', function() { var $btn = $(this); var cid = $btn.data('id'); var fd = new FormData(); fd.append('module', 'comment'); fd.append('action', 'edit'); fd.append('Id', cid); fd.append('text', $('#ta_' + cid).val()); var rInput = $('#rating_input_' + cid); if (rInput.length) fd.append('user_rating', rInput.val()); fd.append('delete_image', $('#del_img_' + cid).is(':checked') ? 1 : 0); var fileInput = $('#new_file_' + cid); if (fileInput.length) { var file = fileInput[0].files[0]; if (file) fd.append('comment_image', file); } $.ajax({ url: aveabspath + 'index.php?ajax=1', type: 'POST', data: fd, processData: false, contentType: false, xhr: function() { var xhr = new window.XMLHttpRequest(); xhr.upload.addEventListener("progress", function(evt) { if (evt.lengthComputable) { var pct = Math.round((evt.loaded / evt.total) * 100); $('#edit_progress_container_' + cid).removeClass('d-none'); $('#edit_progress_bar_' + cid).css('width', pct + '%'); } }, false); return xhr; }, beforeSend: function() { $btn.prop('disabled', true).text('...'); }, success: function() { location.reload(); } }); }); // Отправка новой формы (или ответа) $doc.on('submit', '#mod_comment_new form', function(e) { e.preventDefault(); if (!validate(this)) return false; var $form = $(this); var $btn = $form.find('[type="submit"]'); var originalBtnText = $btn.text(); $.ajax({ url: aveabspath + 'index.php?ajax=1', type: 'POST', data: new FormData(this), processData: false, contentType: false, xhr: function() { var xhr = new window.XMLHttpRequest(); xhr.upload.addEventListener("progress", function(evt) { if (evt.lengthComputable) { var pct = Math.round((evt.loaded / evt.total) * 100); $('#upload_progress_container').removeClass('d-none'); $('#upload_progress_bar').css('width', pct + '%'); $('#upload_status_text').text('Загрузка: ' + pct + '%'); } }, false); return xhr; }, beforeSend: function() { $btn.prop('disabled', true).text('Отправка...'); }, success: function(data) { if (data.includes('wrong_securecode')) { alert("Код капчи введен неверно!"); getCaptha(); $btn.prop('disabled', false).text(originalBtnText); $('#upload_progress_container').addClass('d-none'); } else { location.reload(); } }, error: function() { alert("Ошибка связи с сервером"); $btn.prop('disabled', false).text(originalBtnText); $('#upload_progress_container').addClass('d-none'); } }); }); $doc.on('click', '#captcha img, #reload_captcha', function(e) { e.preventDefault(); getCaptha(); }); }); })(jQuery); } })();