297 lines
17 KiB
Smarty
297 lines
17 KiB
Smarty
{foreach from=$subcomments item=c name=sub_loop}
|
||
{* ОПРЕДЕЛЯЕМ СТАТУС УДАЛЕНИЯ *}
|
||
{assign var="is_deleted" value=false}
|
||
{if $c.comment_author_name == '__DELETED__' || $c.comment_author_name == 'Удалено'}
|
||
{assign var="is_deleted" value=true}
|
||
{/if}
|
||
|
||
{assign var="parent_hidden" value=false}
|
||
{if isset($parent_status) && $parent_status == 0}
|
||
{assign var="parent_hidden" value=true}
|
||
{/if}
|
||
|
||
<div class="card mb-3 mod_comment_comment {if $c.parent_id} ms-2 ms-md-4{/if} {if $is_deleted}opacity-75 bg-light{/if}"
|
||
id="comment_wrapper_{$c.Id}"
|
||
data-parent="{$c.parent_id|default:0}"
|
||
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">
|
||
{/if}
|
||
|
||
<div id="comment_{$c.Id}" class="mod_comment_box {if $c.comment_status == 0 && !$is_deleted}opacity-75 border border-warning rounded{/if}">
|
||
<div class="card-body p-3 d-flex align-items-start">
|
||
|
||
{* БЛОК АВАТАРА *}
|
||
<div class="mod_comment_avatar">
|
||
{if !$is_deleted}
|
||
{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}
|
||
{else}
|
||
<div class="mod_comment_avatar_letter bg-secondary text-white" style="opacity: 0.5;">
|
||
{if $c.comment_text == '__DEL_BY_ADM__'}
|
||
<i class="bi bi-shield-lock"></i>
|
||
{else}
|
||
<i class="bi bi-person-x"></i>
|
||
{/if}
|
||
</div>
|
||
{/if}
|
||
</div>
|
||
|
||
<div class="flex-grow-1 min-w-0">
|
||
{* ПРОВЕРКА НА МОДЕРАЦИЮ ДЛЯ АВТОРА *}
|
||
{if $c.comment_status == 0 && !$is_deleted}
|
||
<div class="alert alert-warning py-1 px-2 mb-2 small d-flex align-items-center border-0 shadow-sm" style="border-left: 4px solid #ffc107 !important;">
|
||
<i class="bi bi-clock-history me-2 text-dark"></i>
|
||
<span class="text-dark">
|
||
{#COMMENT_WAITING_MODERATION#}
|
||
</span>
|
||
</div>
|
||
{/if}
|
||
|
||
{* Информация об авторе и дате *}
|
||
<div class="mod_comment_meta text-muted small d-flex flex-wrap align-items-center">
|
||
{if !$is_deleted}
|
||
<span class="d-flex align-items-center">
|
||
<i class="bi bi-person me-1"></i>
|
||
<span title="{#COMMENT_PUB_AUTOR_A#}">
|
||
<a href="javascript:void(0);"
|
||
class="author-popover fw-bold link-dark text-decoration-none"
|
||
data-id="{$c.Id}"
|
||
role="button"
|
||
tabindex="0">
|
||
{$c.comment_author_name|stripslashes|escape}
|
||
</a>
|
||
</span>
|
||
{* ПРОВЕРКА ИСТОРИИ ИМЕН АНОНИМА *}
|
||
{if !empty($c.past_names)}
|
||
<span class="badge rounded-pill bg-light text-danger border border-danger ms-1"
|
||
style="font-size: 0.65rem; cursor: help;"
|
||
data-bs-toggle="tooltip"
|
||
data-bs-html="true"
|
||
title="{#COMMENT_CHECK_NAME#}<br/>{foreach $c.past_names as $pname}• {$pname|escape}<br/>{/foreach}">
|
||
<i class="bi bi-exclamation-triangle-fill"></i> {#COMMENT_CHECK_NAME_TRUE#}
|
||
</span>
|
||
{/if}
|
||
</span>
|
||
<span class="d-flex align-items-center ms-2"><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 ms-2">• IP:{$c.comment_author_ip}</span>
|
||
{/if}
|
||
|
||
{if isset($c.comment_changed) && $c.comment_changed && $c.comment_changed != '0'}
|
||
<span class="badge bg-light text-secondary border fw-normal ms-2" id="changed_{$c.Id}">{#COMMENT_CHECK_NAME_EDIT#} {$c.comment_changed}</span>
|
||
{/if}
|
||
{else}
|
||
<span class="fw-bold text-secondary text-uppercase" style="font-size: 0.75rem;">
|
||
<i class="bi bi-info-circle me-1"></i> {#COMMENT_STATUS_DELETED#}
|
||
</span>
|
||
<span class="ms-2 d-flex align-items-center"><i class="bi bi-clock me-1"></i> {$c.comment_published}</span>
|
||
{/if}
|
||
</div>
|
||
|
||
{* Текст комментария *}
|
||
<div class="mod_comment_text comment-text-content mb-2 {if $is_deleted}text-secondary fst-italic{/if}">
|
||
{if $c.comment_text == '__DEL_BY_ADM__'}
|
||
<i class="bi bi-shield-exclamation me-1"></i> {#COMMENT_TEXT_DEL_BY_ADMIN#}
|
||
{elseif $c.comment_text == '__DEL_BY_AUT__'}
|
||
<i class="bi bi-trash3 me-1"></i> {#COMMENT_TEXT_DEL_BY_AUTHOR#}
|
||
{elseif $is_deleted}
|
||
<i class="bi bi-trash3 me-1"></i> {#COMMENT_STATUS_DELETED#}
|
||
{else}
|
||
{$c.comment_text|stripslashes|nl2br}
|
||
{/if}
|
||
</div>
|
||
|
||
{* Доп. поля и Файлы (Выводим только если НЕ удален) *}
|
||
{if !$is_deleted}
|
||
{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_images mt-2 d-flex flex-wrap gap-2" id="image_container_{$c.Id}">
|
||
{assign var="all_files" value=","|explode:$c.comment_file}
|
||
{assign var="img_exts" value=['jpg', 'jpeg', 'png', 'gif', 'webp']}
|
||
|
||
{* 1. ИЗОБРАЖЕНИЯ *}
|
||
{foreach from=$all_files item=file}
|
||
{assign var="f_name" value=$file|trim}
|
||
{if $f_name}
|
||
{assign var="ext_parts" value="."|explode:$f_name}
|
||
{assign var="f_ext" value=$ext_parts[$ext_parts|@count-1]|lower}
|
||
{if in_array($f_ext, $img_exts)}
|
||
<div class="comment-image-item d-flex flex-column align-items-center justify-content-between h-100">
|
||
<a href="{$ABS_PATH}uploads/comments/{$f_name}" target="_blank" class="card-link-wrapper d-flex align-items-center justify-content-center mb-1" style="height: 100px;">
|
||
<img src="{$ABS_PATH}uploads/comments/{$f_name}" class="img-fluid rounded border shadow-sm" style="width: 100px; height: 100px; object-fit: cover;" alt="{#COMMENT_FILE_IMAGE#}" />
|
||
</a>
|
||
<div class="d-flex align-items-center">
|
||
<span class="badge bg-light text-secondary border fw-normal text-truncate d-inline-block" style="max-width: 100px; font-size: 0.7rem; padding: 1px 4px; line-height: 1.2;" title="{$f_name|regex_replace:'/_[0-9]+(?=\.[a-z0-9]+$)/i':''}">
|
||
{$f_name|regex_replace:"/_[0-9]+(?=\.[a-z0-9]+$)/i":""}
|
||
</span>
|
||
</div>
|
||
</div>
|
||
{/if}
|
||
{/if}
|
||
{/foreach}
|
||
|
||
{* 2. ОСТАЛЬНЫЕ файлы *}
|
||
{foreach from=$all_files item=file}
|
||
{assign var="f_name" value=$file|trim}
|
||
{if $f_name}
|
||
{assign var="ext_parts" value="."|explode:$f_name}
|
||
{assign var="f_ext" value=$ext_parts[$ext_parts|@count-1]|lower}
|
||
{if !in_array($f_ext, $img_exts)}
|
||
<div class="comment-image-item d-flex flex-column align-items-center justify-content-between h-100">
|
||
<a href="{$ABS_PATH}uploads/comments/{$f_name}" target="_blank" class="card-link-wrapper text-decoration-none d-block text-center mb-1">
|
||
<div class="file-box d-flex align-items-center justify-content-center bg-light text-dark rounded border shadow-sm" style="width: 100px; height: 100px; font-weight: bold; text-transform: uppercase; font-size: 14px; transition: all 0.2s;">
|
||
<i class="bi bi-file-earmark-arrow-down me-1"></i>{$f_ext}
|
||
</div>
|
||
</a>
|
||
<div class="d-flex align-items-center">
|
||
<span class="badge bg-light text-secondary border fw-normal text-truncate d-inline-block" style="max-width: 100px; font-size: 0.7rem; padding: 1px 4px; line-height: 1.2;" title="{$f_name|regex_replace:'/_[0-9]+(?=\.[a-z0-9]+$)/i':''}">
|
||
{$f_name|regex_replace:"/_[0-9]+(?=\.[a-z0-9]+$)/i":""}
|
||
</span>
|
||
</div>
|
||
</div>
|
||
{/if}
|
||
{/if}
|
||
{/foreach}
|
||
</div>
|
||
{/if}
|
||
{/if}
|
||
</div>
|
||
</div>
|
||
|
||
{* ФУТЕР *}
|
||
<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 gap-2">
|
||
{if !$is_deleted}
|
||
{* 1. Оценка автора *}
|
||
{if isset($c.user_rating) && $c.user_rating > 0}
|
||
<div class="rating-author-badge" title="{#COMMENT_AUTOR_RATING_A#} {$c.user_rating} {#COMMENT_AUTOR_RATING_IZ#} 5">
|
||
<span class="d-none d-sm-inline">{#COMMENT_AUTOR_RATING_B#}</span>
|
||
<div class="rating-author-stars">
|
||
{section name=r_star start=1 loop=6}
|
||
<i class="bi {if $smarty.section.r_star.index <= $c.user_rating}bi-star-fill{else}bi-star{/if}"></i>
|
||
{/section}
|
||
</div>
|
||
<span class="rating-value">{$c.user_rating}</span>
|
||
</div>
|
||
{/if}
|
||
|
||
{* 2. Рейтинг комментария *}
|
||
{if $comment_rating_type != 2}
|
||
<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 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>
|
||
{else}
|
||
<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}
|
||
<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}
|
||
</div>
|
||
{/if}
|
||
|
||
{* 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> {#COMMENT_PUB_TIMER_TXT_A#}
|
||
<span id="timer_{$c.Id}" data-left="{$c.edit_time_left}" class="timer-count fw-bold">
|
||
{math equation="floor(x/3600)" x=$c.edit_time_left assign="h"}
|
||
{math equation="floor((x%3600)/60)" x=$c.edit_time_left assign="m"}
|
||
{math equation="x%60" x=$c.edit_time_left assign="s"}
|
||
|
||
{if $h > 0}{$h} {#COMMENT_PUB_TIMER_HOUR#} {/if}
|
||
|
||
{* Теперь минуты тоже с ведущим нулем *}
|
||
{if $m < 10}0{/if}{$m} {#COMMENT_PUB_TIMER_MIN#}
|
||
|
||
{if $s < 10}0{/if}{$s} {#COMMENT_PUB_TIMER_SEC#}
|
||
</span>{#COMMENT_PUB_TIMER_TXT_B#}
|
||
</div>
|
||
{/if}
|
||
{/if}
|
||
</div>
|
||
|
||
{* КНОПКИ ДЕЙСТВИЙ *}
|
||
<div class="actions-buttons d-flex align-items-center gap-1">
|
||
{if !$is_deleted}
|
||
{if ($cancomment==1 && $closed!=1) || $smarty.const.UGROUP==1}
|
||
{if $comment_allow_self_answer == 1 || !(isset($c.is_my_own) && $c.is_my_own)}
|
||
<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}
|
||
|
||
<span id="controls_{$c.Id}" class="d-flex align-items-center gap-1">
|
||
{if $c.can_edit}
|
||
<a class="btn btn-sm btn-link text-warning mod_comment_edit px-2" title="{#COMMENT_EDIT_LINK#}" 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="{#COMMENT_DELETE_LINK#}" href="javascript:void(0);" data-id="{$c.Id}"><i class="bi bi-trash"></i></a>
|
||
{/if}
|
||
</span>
|
||
|
||
{if $smarty.const.UGROUP==1}
|
||
{* Если родитель НЕ скрыт — показываем кнопку управления потомком *}
|
||
<a class="btn btn-sm btn-link {if $c.comment_status==1}text-success{else}text-danger{/if} mod_comment_toggle px-2"
|
||
href="javascript:void(0);"
|
||
data-id="{$c.Id}"
|
||
{if $parent_hidden}style="display: none;"{/if}
|
||
title="{if $c.comment_status==1}{#COMMENT_ICON_HIDE#}{else}{#COMMENT_ICON_SHOW#}{/if}">
|
||
<i class="bi bi-{if $c.comment_status==1}eye{else}eye-slash{/if}"></i>
|
||
</a>
|
||
{/if}
|
||
{/if}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{if isset($smarty.request.subaction) && $smarty.request.subaction=='showonly' && isset($smarty.request.comment_id) && $smarty.request.comment_id==$c.Id}
|
||
</div>
|
||
{/if}
|
||
|
||
<span id="end{$c.Id}"></span>
|
||
|
||
{if isset($comments) && isset($comments[$c.Id])}
|
||
<div class="mt-2">
|
||
{include file="$subtpl" subcomments=$comments[$c.Id] sub=1 parentId=$c.Id parent_status=$c.comment_status}
|
||
</div>
|
||
{/if}
|
||
|
||
</div>
|
||
|
||
{* --- ВСТАВЛЯЕМ КНОПКУ AJAX ОТВЕТОВ --- *}
|
||
{if $smarty.foreach.sub_loop.last && isset($more_counts[$parentId])}
|
||
<div id="ajax_loader_{$parentId}" class="ms-4 mb-3">
|
||
<button class="btn btn-sm btn-outline-primary" onclick="loadMoreReplies('{$parentId}')">
|
||
<i class="bi bi-chevron-double-down"></i> {#COMMENT_ANSWER_AJAX_BUTTON#} {$more_counts[$parentId]} {#COMMENT_ANSWER_AJAX_TEXT#}
|
||
</button>
|
||
</div>
|
||
{/if}
|
||
|
||
{/foreach}
|
||
|