добавлены аватары по буквам имени комментатора , сделан отзывчивый шаблон, стили вынесены в отдельный css файл

This commit is contained in:
2025-12-28 20:49:11 +05:00
parent 713c28e45a
commit 29a9ed0eec
5 changed files with 258 additions and 221 deletions

View File

@@ -1,13 +1,3 @@
Шаг 1: Назначение перемнных в шаблоне
<script type="text/javascript">
var aveabspath = '[tag:path]';
var UGROUP = <?=UGROUP;?>;
</script>
Шаг 2: Нужен плагин для jQuery - jquery.form
http://malsup.com/jquery/form/
Добавить в шаблон <link rel="stylesheet" href="[tag:path]modules/comment/css/mod_comment_styles.css">

View File

@@ -303,14 +303,34 @@ function commentListShow($tpl_dir)
while ($row = $sql->FetchAssocArray())
{
if (isset($row['comment_author_id']) && $row['comment_author_id'] > 0)
{
$row['avatar'] = getAvatar($row['comment_author_id'], 48);
}
else
{
$row['avatar'] = '';
}
// 1. Получаем аватар через стандартную функцию системы
if (isset($row['comment_author_id']) && $row['comment_author_id'] > 0)
{
$row['avatar'] = getAvatar($row['comment_author_id'], 48);
}
else
{
$row['avatar'] = '';
}
// 2. ПРОВЕРКА: Если функция вернула системную заглушку, считаем, что аватара нет
if (!empty($row['avatar']) && strpos($row['avatar'], 'user.png') !== false)
{
$row['avatar'] = '';
}
// 3. ЛОГИКА БУКВ: Если аватара нет (пусто или мы его обнулили выше)
if (empty($row['avatar']))
{
// Берем имя автора (если пусто — 'Guest')
$name = !empty($row['comment_author_name']) ? stripslashes($row['comment_author_name']) : 'Guest';
// Получаем первую букву имени (в верхнем регистре)
$row['first_letter'] = mb_substr(trim($name), 0, 1, 'UTF-8');
// Вычисляем индекс цвета (от 1 до 8) на основе имени
$row['avatar_color_index'] = (abs(crc32($name)) % 12) + 1;
}
// --- ИСПРАВЛЕННАЯ ЛОГИКА ТАЙМЕРА И ПРАВ (УЧЕТ АДМИНА) ---
$row['can_edit'] = 0;
@@ -560,7 +580,22 @@ exit;
if ($ajax)
{
$new_comment['avatar'] = (isset($new_comment['comment_author_id']) && $new_comment['comment_author_id'] > 0) ? getAvatar($new_comment['comment_author_id'], 48) : '';
// 1. Получаем аватар как обычно
$new_comment['avatar'] = (isset($new_comment['comment_author_id']) && $new_comment['comment_author_id'] > 0) ? getAvatar($new_comment['comment_author_id'], 48) : '';
// 2. Очищаем, если это системный user.png
if (!empty($new_comment['avatar']) && strpos($new_comment['avatar'], 'user.png') !== false)
{
$new_comment['avatar'] = '';
}
// 3. Если аватара нет — генерируем данные для буквы
if (empty($new_comment['avatar']))
{
$name = !empty($new_comment['comment_author_name']) ? stripslashes($new_comment['comment_author_name']) : 'Guest';
$new_comment['first_letter'] = mb_substr(trim($name), 0, 1, 'UTF-8');
$new_comment['avatar_color_index'] = (abs(crc32($name)) % 12) + 1;
}
$new_comment['comment_changed'] = 0;
// Передаем флаги для мгновенной активации управления в шаблоне

View File

@@ -1,108 +1,109 @@
/* ====================================================================
ОБЩИЕ СТИЛИ КОММЕНТАРИЕВ И АВАТАРОВ (НОВЫЕ И ОБНОВЛЕННЫЕ)
ОБЩИЕ СТИЛИ КОММЕНТАРИЕВ И АВАТАРОВ
==================================================================== */
/* 1. Общие настройки для блока комментария */
.mod_comment_comment {
/* Можно добавить небольшой отступ снизу, если стандартный mb-3 недостаточен */
/* margin-bottom: 1.5rem !important; */
/* Резерв для кастомных отступов */
}
/* 2. Контейнер аватара */
.mod_comment_avatar {
/* Фиксируем размер и убедимся, что аватар не "съедет" */
width: 48px;
height: 48px;
margin-right: 20px !important;
/* Убедимся, что аватар имеет правильный отступ от метаданных/текста */
/* margin-right: 15px; */ /* Если вы используете me-3 в HTML, этот CSS не нужен */
margin-right: 1rem !important;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
/* 3. Стиль изображения аватара */
.mod_comment_avatar img {
/* Если rounded-circle не работает или его нет в Bootstrap */
border-radius: 50%;
width: 100%;
height: 100%;
object-fit: cover; /* Гарантирует, что изображение не исказится */
border-radius: 50% !important;
width: 48px !important;
height: 48px !important;
object-fit: cover !important;
}
/* 4. Стиль метаданных (Автор, Дата, IP) */
.mod_comment_meta {
/* Делаем блок метаданных компактнее и выравниваем по верхнему краю */
line-height: 1.2;
margin-bottom: 5px !important; /* Чуть меньше отступ от текста */
margin-bottom: 0.5rem !important;
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 5px 15px; /* Удобный отступ между элементами */
}
/* 5. Стили текста комментария */
.mod_comment_text {
/* Увеличиваем межстрочный интервал для лучшей читабельности */
line-height: 1.5;
word-wrap: break-word;
overflow-wrap: break-word;
}
/* 6. Стили панели действий (Редактировать, Удалить, Ответить) */
.mod_comment_actions a {
text-decoration: none;
font-size: 0.9em;
padding-left: 10px;
padding-right: 10px;
/* 6. Прикрепленные изображения */
.mod_comment_attached_image img {
max-width: 100%;
height: auto;
max-height: 300px;
}
/* 7. СТИЛИ ДЛЯ БУКВЕННЫХ АВАТАРОВ */
.mod_comment_avatar_letter {
width: 100%;
height: 100%;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
color: #ffffff;
font-size: 1.2rem;
text-transform: uppercase;
user-select: none;
box-shadow: inset 0 0 5px rgba(0,0,0,0.1);
}
/* Цветовая палитра для аватаров */
.av-c1 { background-color: #6c5ce7; }
.av-c2 { background-color: #2ecc71; }
.av-c3 { background-color: #e67e22; }
.av-c4 { background-color: #e91e63; }
.av-c5 { background-color: #00cec9; }
.av-c6 { background-color: #0984e3; }
.av-c7 { background-color: #d63031; }
.av-c8 { background-color: #636e72; }
.av-c9 { background-color: #fdcb6e; }
.av-c10 { background-color: #fd79a8; }
.av-c11 { background-color: #a29bfe; }
.av-c12 { background-color: #273c75; }
/* ====================================================================
СТИЛИ ДЛЯ ДРЕВОВИДНОГО ОТОБРАЖЕНИЯ КОММЕНТАРИЕВ (Replies) - ВАШ КОД
СТИЛИ ДЛЯ ДРЕВОВИДНОГО ОТОБРАЖЕНИЯ (Replies)
==================================================================== */
/* 1. Общий контейнер ответа, который находится внутри .mod_comment_comment
и имеет отступ ms-4 */
.mod_comment_comment .mod_comment_comment.ms-4 {
/* Добавляем вертикальную линию слева */
border-left: 3px solid #dee2e6; /* Легкая граница */
/* Уменьшаем margin-left, который дает ms-4, чтобы освободить место
для линии и при этом не уходить слишком далеко вправо на каждом уровне. */
margin-left: 20px !important; /* Принудительно уменьшаем отступ */
padding-left: 15px; /* Отступ между линией и контентом ответа */
/* Опционально: немного отличающийся фон */
border-left: 3px solid #dee2e6;
margin-left: 20px !important;
padding-left: 15px;
background-color: #f8f9fa;
}
/* 2. Отдельно стилизуем рамку для вложенных карточек, чтобы они не выглядели
громоздко внутри родителя */
.mod_comment_comment .mod_comment_comment.ms-4 > .mod_comment_box {
border: none !important; /* Убираем стандартную рамку карточки, чтобы осталась только наша вертикальная линия */
border: none !important;
}
/* 3. Убираем рамки у вложенных заголовков, чтобы линия была чистой */
.mod_comment_comment .mod_comment_comment.ms-4 > .mod_comment_box > .card-header {
border-bottom: none !important;
}
/* 4. Более глубокий уровень вложенности (если ответов много) */
/* Если ответ на ответ имеет дополнительный ms-4, стилизуем его дальше */
.mod_comment_comment .mod_comment_comment.ms-4 .mod_comment_comment.ms-4 {
border-color: #adb5bd; /* Чуть темнее линия для следующего уровня */
background-color: #fff; /* Возвращаем белый фон для контраста */
}
/* ====================================================================
!!! ФИНАЛЬНЫЕ СТИЛИ ДЛЯ ПАГИНАЦИИ !!!
СТИЛИ ДЛЯ ПАГИНАЦИИ
==================================================================== */
/* 1. Общий контейнер, который окружает <nav> */
.page_navigation_box {
padding: 15px 0;
text-align: center;
}
/* 2. Навигационный элемент <nav> */
.page_navigation_box nav {
display: inline-block;
}
/* 3. Стиль для списка <ul>. НОВОЕ: используем класс .page_nav, который есть в HTML */
.page_navigation_box ul.page_nav {
list-style: none;
padding: 0;
@@ -110,86 +111,109 @@
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center; /* НОВОЕ: для выравнивания текста "Страница 1 из 2" */
align-items: center;
}
/* 4. Стиль для текста "Страница 1 из 2" */
.page_navigation_box span.pages { /* НОВОЕ ПРАВИЛО */
margin-right: 15px; /* Отступ от цифр */
color: #6c757d;
}
/* 5. Элемент списка (<li>) */
.page_navigation_box li {
margin: 0 4px;
}
/* 6. Ссылки на страницы (<a>) */
/* ВАЖНО: Мы удаляем старый .page_nav_active и добавляем СТИЛИ для ССЫЛОК и АКТИВНОГО SPAN */
.page_navigation_box a.page_nav,
.page_navigation_box span.active { /* ИЗМЕНЕНИЕ: стилизуем span.active */
.page_navigation_box span.active {
display: block;
min-width: 36px;
padding: 6px 10px;
line-height: 1.5;
text-decoration: none;
color: #0d6efd; /* Цвет Bootstrap Primary */
background-color: #fff;
border: 1px solid #dee2e6; /* Легкая граница */
border: 1px solid #dee2e6;
border-radius: 4px;
text-decoration: none;
transition: all 0.2s;
text-align: center;
}
/* 7. Стили для текущей (активной) страницы */
.page_navigation_box span.active { /* ТОЧНОЕ ПРАВИЛО ДЛЯ АКТИВНОГО ЭЛЕМЕНТА */
.page_navigation_box span.active {
background-color: #0d6efd;
border-color: #0d6efd;
color: #fff; /* Белый текст на синем фоне */
font-weight: bold;
cursor: default;
}
/* 8. Ховер-эффект для ссылок */
.page_navigation_box a.page_nav:hover {
color: #fff;
background-color: #0b5ed7;
border-color: #0b5ed7;
font-weight: bold;
}
/* ====================================================================
ФУТЕР КОММЕНТАРИЯ (РЕЙТИНГИ, КНОПКИ, ТАЙМЕР)
==================================================================== */
/* Фиксируем подвал комментария: высота и выравнивание вправо */
.mod_comment_footer,
[id^="timer_container_"],
/* Основной контейнер футера */
.card-footer {
display: flex !important;
flex-wrap: wrap !important;
justify-content: space-between !important;
align-items: center !important;
/* ПРИЖИМАЕМ КНОПКИ ВПРАВО */
/* justify-content: flex-end !important; */
/* ФИКСИРОВАННАЯ ВЫСОТА (чтобы не прыгало как на Screenshot 5) */
min-height: 48px !important;
height: 48px !important;
padding: 0 1.25rem !important;
background-color: #f8f9fa !important;
border-top: 1px solid rgba(0,0,0,.125) !important;
gap: 10px !important;
padding: 0.5rem 1rem !important;
background-color: #ffffff !important; /* Белый фон для чистоты */
border-top: 1px solid #dee2e6 !important;
min-height: 48px;
}
/* Отступы между кнопками, чтобы они не слипались справа */
.mod_comment_footer > a,
.mod_comment_footer > button,
.mod_comment_footer .btn {
margin-left: 15px !important; /* Отступ слева, так как кнопки прижаты вправо */
margin-right: 0 !important;
/* Настраиваемая плашка "Оценка автора" */
.rating-author-badge {
display: inline-flex !important;
align-items: center !important;
gap: 8px;
padding: 4px 12px !important;
border-radius: 6px !important;
height: 32px;
background-color: #ffc107 !important;
color: #212529 !important;
border: 1px solid rgba(0,0,0,0.05) !important;
font-size: 0.8rem !important;
font-weight: 600;
}
.rating-author-stars {
display: flex !important;
align-items: center !important;
line-height: 1 !important;
}
.rating-author-stars i {
font-size: 0.75rem !important; /* Чуть уменьшил для баланса */
margin: 0 1px;
}
/* Контейнер лайков/звезд рейтинга комментария */
.comment-rating-container {
display: inline-flex !important;
align-items: center !important;
gap: 4px;
height: 32px;
padding: 0 10px !important;
}
.comment-stars,
.comment-like {
display: flex !important;
align-items: center !important;
line-height: 1 !important;
}
/* Иконки звезд и сердец в рейтинге */
.comment-rating-container .bi-star-fill,
.comment-rating-container .bi-star,
.comment-rating-container .bi-heart-fill {
font-size: 1rem !important;
line-height: 1;
}
/* Текст количества голосов */
.comment-rating-container span {
line-height: 1;
margin-left: 2px;
}
/* Кнопки действий в правой части */
.actions-buttons .btn-link {
text-decoration: none !important;
font-weight: 500;
}
/* Гарантируем, что текст таймера тоже будет справа */
/*[id^="timer_container_"] {
text-align: right !important;
}*/
/* Если нужно, чтобы кнопки "Ответить" и "Удалить" были разнесены (одну влево, другие вправо) */
/* .mod_comment_footer { justify-content: space-between !important; } */
/* Таймер */
[id^="timer_container_"] {
display: flex !important;
align-items: center !important;
height: 32px;
}

View File

@@ -1,5 +1,5 @@
{foreach from=$subcomments item=c}
<div class="card mb-3 mod_comment_comment{if $c.parent_id} ms-4{/if}" id="comment_wrapper_{$c.Id}" data-user-rating="{$c.user_rating|default:0}" data-is-own="{if isset($c.is_my_own) && $c.is_my_own}1{else}0{/if}">
<div class="card mb-3 mod_comment_comment{if $c.parent_id} ms-2 ms-md-4{/if}" id="comment_wrapper_{$c.Id}" data-user-rating="{$c.user_rating|default:0}" data-is-own="{if isset($c.is_my_own) && $c.is_my_own}1{else}0{/if}">
{if isset($smarty.request.subaction) && $smarty.request.subaction=='showonly' && isset($smarty.request.comment_id) && $smarty.request.comment_id==$c.Id}
<div class="border border-warning border-3 rounded p-0">
@@ -8,142 +8,130 @@
<div id="comment_{$c.Id}" class="mod_comment_box">
<div class="card-body p-3 d-flex align-items-start">
{* ----- БЛОК АВАТАРА ----- *}
{$avatar_url = "{$ABS_PATH}modules/comment/img/no_avatar.webp"}
{if isset($c.avatar) && $c.avatar != ''}
{$avatar_url = $c.avatar}
{/if}
<div class="mod_comment_avatar flex-shrink-0 me-3">
<img src="{$avatar_url}" alt="Аватар пользователя {$c.comment_author_name|stripslashes|escape}" class="rounded-circle" style="width: 48px; height: 48px;" loading="lazy" />
{* БЛОК АВАТАРА *}
<div class="mod_comment_avatar">
{if isset($c.avatar) && $c.avatar != ''}
<img src="{$c.avatar}" alt="{$c.comment_author_name|escape}" class="rounded-circle">
{else}
<div class="mod_comment_avatar_letter av-c{$c.avatar_color_index|default:1}">
{$c.first_letter|default:'?'|upper}
</div>
{/if}
</div>
<div class="flex-grow-1">
<div class="flex-grow-1 min-w-0">
{* Информация об авторе и дате *}
<div class="mod_comment_meta mb-2 text-muted small d-flex align-items-center flex-wrap">
<span class="me-2"><i class="bi bi-person me-1"></i> {#COMMENT_USER_ADD#} <a title="{#COMMENT_INFO#}" href="javascript:void(0);" onclick="popup('{$ABS_PATH}index.php?module=comment&action=postinfo&pop=1&Id={$c.Id}&theme={$theme}','comment','500','300','1');" class="fw-bold link-dark">{$c.comment_author_name|stripslashes|escape}</a></span>
<span class="me-2"><i class="bi bi-clock me-1"></i> {$c.comment_published}</span>
{if $comment_show_f1 == 1 && $c.comment_author_website}
<span class="ms-2 d-inline-block">
<i class="bi bi-link-45deg"></i> <strong>{$comment_name_f1|default:#COMMENT_YOUR_SITE#}:</strong> {$c.comment_author_website|stripslashes|escape}
</span>
{/if}
{if $comment_show_f2 == 1 && $c.comment_author_city}
<span class="ms-2 d-inline-block">
<i class="bi bi-geo-alt"></i> <strong>{$comment_name_f2|default:#COMMENT_YOUR_FROM#}:</strong> {$c.comment_author_city|stripslashes|escape}
</span>
{/if}
{if $smarty.const.UGROUP==1}
<span class="ms-2 text-secondary">• IP:{$c.comment_author_ip}</span>
{/if}
<span class="mod_comment_changed ms-2" id="changed_{$c.Id}">
{if isset($c.comment_changed) && $c.comment_changed > 1}
(<span class="text-secondary">{#COMMENT_TEXT_CHANGED#} {$c.comment_changed}</span>)
{/if}
<div class="mod_comment_meta text-muted small d-flex flex-wrap align-items-center">
<span class="d-flex align-items-center">
<i class="bi bi-person me-1"></i>
<a title="{#COMMENT_INFO#}" href="javascript:void(0);" onclick="popup('{$ABS_PATH}index.php?module=comment&action=postinfo&pop=1&Id={$c.Id}&theme={$theme}','comment','500','300','1');" class="fw-bold link-dark text-decoration-none">{$c.comment_author_name|stripslashes|escape}</a>
</span>
<span class="d-flex align-items-center"><i class="bi bi-clock me-1"></i> {$c.comment_published}</span>
{if $smarty.const.UGROUP==1}
<span class="text-secondary d-none d-sm-inline">• IP:{$c.comment_author_ip}</span>
{/if}
{if isset($c.comment_changed) && $c.comment_changed > 1}
<span class="badge bg-light text-secondary border fw-normal" id="changed_{$c.Id}">ред. {$c.comment_changed}</span>
{/if}
</div>
{* Текст комментария *}
<div class="mod_comment_text comment-text-content">{$c.comment_text|stripslashes|nl2br}</div>
<div class="mod_comment_text comment-text-content mb-2">
{$c.comment_text|stripslashes|nl2br}
</div>
{* Доп. поля (Сайт, Город) *}
{if $c.comment_author_website || $c.comment_author_city}
<div class="small text-muted mb-2 border-start ps-2">
{if $c.comment_author_website}<div><i class="bi bi-link-45deg"></i> {$c.comment_author_website}</div>{/if}
{if $c.comment_author_city}<div><i class="bi bi-geo-alt"></i> {$c.comment_author_city}</div>{/if}
</div>
{/if}
{* Вывод изображения *}
{if !empty($c.comment_file)}
<div class="mod_comment_attached_image mt-3" id="image_container_{$c.Id}">
<a href="{$ABS_PATH}uploads/comments/{$c.comment_file}" target="_blank" class="comment-img-link">
<img src="{$ABS_PATH}uploads/comments/{$c.comment_file}" class="img-fluid rounded border shadow-sm" style="max-width: 300px; max-height: 400px; cursor: zoom-in;" alt="Изображение" />
<div class="mod_comment_attached_image mt-2" id="image_container_{$c.Id}">
<a href="{$ABS_PATH}uploads/comments/{$c.comment_file}" target="_blank">
<img src="{$ABS_PATH}uploads/comments/{$c.comment_file}" class="img-fluid rounded border shadow-sm" alt="Изображение" />
</a>
</div>
{/if}
</div>
</div>
<div class="card-footer mod_comment_actions d-flex justify-content-between align-items-center bg-white border-top p-2">
{* ФУТЕР *}
<div class="card-footer bg-white border-top p-2 d-flex flex-wrap justify-content-between align-items-center gap-2">
{* ЛЕВАЯ ЧАСТЬ: РЕЙТИНГИ И ТАЙМЕР *}
<div class="d-flex align-items-center flex-wrap">
{* 1. Оценка автора (звезды) *}
<div class="d-flex align-items-center flex-wrap gap-2">
{* 1. Оценка автора *}
{if isset($c.user_rating) && $c.user_rating > 0}
<div class="badge bg-warning text-dark me-3 d-inline-flex align-items-center" title="Оценка автора: {$c.user_rating} из 5" style="font-size: 0.75rem; padding: 0.4rem 0.6rem; gap: 4px;">
<span style="line-height: 1;">Оценка автора:</span>
<div class="d-flex align-items-center" style="line-height: 1;">
<div class="rating-author-badge" title="Оценка автора: {$c.user_rating} из 5">
<span class="d-none d-sm-inline">Оценка:</span>
<div class="rating-author-stars">
{section name=r_star start=1 loop=6}
{if $smarty.section.r_star.index <= $c.user_rating}
<i class="bi bi-star-fill" style="font-size: 0.7rem;"></i>
{else}
<i class="bi bi-star text-white" style="font-size: 0.7rem;"></i>
{/if}
<i class="bi {if $smarty.section.r_star.index <= $c.user_rating}bi-star-fill{else}bi-star{/if}"></i>
{/section}
</div>
<span class="fw-bold" style="line-height: 1;">{$c.user_rating}</span>
<span class="rating-value">{$c.user_rating}</span>
</div>
{/if}
{* 2. Общий рейтинг комментария *}
{* 2. Рейтинг комментария *}
{if $comment_rating_type != 2}
<div class="comment-rating-container d-inline-flex align-items-center me-3 py-1 px-2 bg-light rounded border" data-id="{$c.Id}" style="line-height: 1;">
<div class="comment-rating-container d-flex align-items-center py-1 px-2 bg-light rounded border" data-id="{$c.Id}">
{if $comment_rating_type == 1}
<div class="comment-like d-inline-flex align-items-center" style="cursor: pointer; color: #dc3545; font-size: 0.95rem;">
<i class="star-item bi bi-heart-fill me-1" data-value="5" title="Мне нравится"></i>
<div class="comment-like text-danger" style="cursor: pointer;">
<i class="star-item bi bi-heart-fill me-1" data-value="5"></i>
<span class="fw-bold small">{$c.rating_count|default:0}</span>
</div>
{if isset($c.rating_count)}
<span class="ms-1 text-muted fw-bold" style="font-size: 0.8rem;">{$c.rating_count}</span>
{/if}
{else}
<div class="comment-stars d-inline-flex" style="cursor: pointer; color: #ffc107; font-size: 0.9rem;">
<div class="comment-stars text-warning" style="cursor: pointer;">
{assign var="avg_rating" value=0}
{if isset($c.rating_count) && $c.rating_count > 0}
{math equation="round(x / y)" x=$c.rating_sum y=$c.rating_count assign="avg_rating"}
{/if}
{section name=star start=1 loop=6}
<i class="star-item bi {if $smarty.section.star.index <= $avg_rating}bi-star-fill{else}bi-star{/if} {if !$smarty.section.star.last}me-1{/if}" data-value="{$smarty.section.star.index}" title="Оценить"></i>
{/section}
<div class="d-flex align-items-center me-1">
{section name=star start=1 loop=6}
<i class="star-item bi {if $smarty.section.star.index <= $avg_rating}bi-star-fill{else}bi-star{/if} me-1" data-value="{$smarty.section.star.index}"></i>
{/section}
</div>
{if isset($c.rating_count)}<span class="text-muted small">({$c.rating_count})</span>{/if}
</div>
{if isset($c.rating_count)}
<span class="ms-2 text-muted fw-bold" style="font-size: 0.8rem;">({$c.rating_count})</span>
{/if}
{/if}
</div>
{/if}
{* 3. ТАЙМЕР РЕДАКТИРОВАНИЯ (Добавлена проверка на UGROUP != 1) *}
{if $smarty.const.UGROUP != 1 && $c.can_edit && isset($c.edit_time_left) && $c.edit_time_left > 0}
<div class="edit-timer-wrapper text-muted small" id="timer_container_{$c.Id}" title="Осталось времени">
<i class="bi bi-hourglass-split text-primary"></i>
<span class="timer-count fw-bold" data-left="{$c.edit_time_left}" id="timer_{$c.Id}">
{math equation="floor(x/60)" x=$c.edit_time_left}:{if ($c.edit_time_left%60) < 10}0{/if}{math equation="x%60" x=$c.edit_time_left}
{* 3. Таймер редактирования *}
{if $c.can_edit && isset($c.edit_time_left) && $c.edit_time_left > 0}
<div class="text-muted small d-flex align-items-center" id="timer_container_{$c.Id}">
<i class="bi bi-hourglass-split text-primary me-1"></i>
<span id="timer_{$c.Id}" data-left="{$c.edit_time_left}" class="fw-bold">
{math equation="floor(x/60)" x=$c.edit_time_left}:{if ($c.edit_time_left%60) < 10}0{/if}{math equation="x%60" x=$c.edit_time_left}
</span>
</div>
{/if}
</div>
{* ПРАВАЯ ЧАСТЬ: КНОПКИ ДЕЙСТВИЙ *}
<div class="actions-buttons d-flex align-items-center">
{* КНОПКИ ДЕЙСТВИЙ *}
<div class="actions-buttons d-flex align-items-center gap-1">
{if ($cancomment==1 && $closed!=1) || $smarty.const.UGROUP==1}
{if !(isset($c.is_my_own) && $c.is_my_own)}
<a class="mod_comment_answer p-2 text-primary text-decoration-none" href="javascript:void(0);" data-id="{$c.Id}">
<i class="bi bi-reply-fill me-1"></i> {#COMMENT_ANSWER_LINK#}
<a class="btn btn-sm btn-link text-primary text-decoration-none mod_comment_answer px-2" href="javascript:void(0);" data-id="{$c.Id}">
<i class="bi bi-reply-fill me-1"></i> <span class="d-none d-sm-inline">{#COMMENT_ANSWER_LINK#}</span>
</a>
{/if}
{/if}
{if $c.can_edit}
<span id="controls_{$c.Id}" class="d-flex">
<a class="p-2 text-warning text-decoration-none mod_comment_edit" href="javascript:void(0);" data-id="{$c.Id}">
<i class="bi bi-pencil-square me-1"></i> Редактировать
</a>
<a class="p-2 text-danger text-decoration-none mod_comment_delete" href="javascript:void(0);" data-id="{$c.Id}">
<i class="bi bi-trash me-1"></i> Удалить
</a>
</span>
<a class="btn btn-sm btn-link text-warning mod_comment_edit px-2" title="Редактировать" href="javascript:void(0);" data-id="{$c.Id}"><i class="bi bi-pencil-square"></i></a>
<a class="btn btn-sm btn-link text-danger mod_comment_delete px-2" title="Удалить" href="javascript:void(0);" data-id="{$c.Id}"><i class="bi bi-trash"></i></a>
{/if}
{if $smarty.const.UGROUP==1}
<a class="mod_comment_{if $c.comment_status!=1}unlock{else}lock{/if} p-2 text-dark" href="javascript:void(0);" data-id="{$c.Id}">
<i class="bi bi-{if $c.comment_status!=1}unlock-fill{else}lock-fill{/if}"></i>
<a class="btn btn-sm btn-link text-dark mod_comment_lock px-2" href="javascript:void(0);" data-id="{$c.Id}">
<i class="bi bi-{if $c.comment_status!=1}unlock{else}lock{/if}-fill"></i>
</a>
{/if}
</div>
@@ -157,7 +145,7 @@
<span id="end{$c.Id}"></span>
{if isset($comments) && isset($comments[$c.Id])}
<div class="mt-3">
<div class="mt-2">
{include file="$subtpl" subcomments=$comments[$c.Id] sub=1}
</div>
{/if}

Binary file not shown.