feat(single): identity chips, comment 神评, reward open from author bar
Share VIP/verify/level/badge chrome via aksrt-identity helpers on author bar, author card, and comments; mark hot comments; open reward modal from author actions; admin threshold for 神评; task list go-to actions.
This commit is contained in:
@@ -20,6 +20,7 @@ export const commentSchema = {
|
|||||||
comment_img: true,
|
comment_img: true,
|
||||||
comment_upload_img: false,
|
comment_upload_img: false,
|
||||||
comment_like_s: true,
|
comment_like_s: true,
|
||||||
|
comment_hot_threshold: 10,
|
||||||
comment_quick_s: true,
|
comment_quick_s: true,
|
||||||
comment_city_s: true,
|
comment_city_s: true,
|
||||||
comment_author_tag: true,
|
comment_author_tag: true,
|
||||||
@@ -78,6 +79,7 @@ export const commentSchema = {
|
|||||||
title: '互动功能',
|
title: '互动功能',
|
||||||
icon: 'fas fa-heart',
|
icon: 'fas fa-heart',
|
||||||
fields: [
|
fields: [
|
||||||
|
{ key: 'comment_hot_threshold', label: '神评点赞阈值', type: 'number', default: 10, min: 1, max: 999, help: '点赞数达到该值后显示「神评」徽章', dependsOn: { key: 'comment_like_s', value: true } },
|
||||||
{ key: 'comment_like_s', label: '评论点赞', type: 'switch', default: true },
|
{ key: 'comment_like_s', label: '评论点赞', type: 'switch', default: true },
|
||||||
{ key: 'comment_quick_s', label: '快捷回复', type: 'switch', default: true },
|
{ key: 'comment_quick_s', label: '快捷回复', type: 'switch', default: true },
|
||||||
{ key: 'comment_city_s', label: '评论城市', type: 'switch', default: true },
|
{ key: 'comment_city_s', label: '评论城市', type: 'switch', default: true },
|
||||||
|
|||||||
@@ -671,3 +671,34 @@ body.dark-theme .comment-login-prompt__inner {
|
|||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
opacity: 0.9;
|
opacity: 0.9;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Identity chips + 神评 */
|
||||||
|
.aksrt-identity-chip {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 3px;
|
||||||
|
vertical-align: middle;
|
||||||
|
max-width: 9em;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.aksrt-identity-chip--comment {
|
||||||
|
font-size: 11px;
|
||||||
|
padding: 0 6px;
|
||||||
|
}
|
||||||
|
.aksrt-comment__badge--hot {
|
||||||
|
color: #ea580c;
|
||||||
|
background: rgba(234, 88, 12, 0.1);
|
||||||
|
border-radius: 999px;
|
||||||
|
padding: 0 6px;
|
||||||
|
margin-left: 4px;
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
.aksrt-comment__header .author-box {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
|
|||||||
@@ -40,6 +40,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
btn.addEventListener('click', openReward);
|
btn.addEventListener('click', openReward);
|
||||||
|
document.querySelectorAll('[data-aksrt-reward-open]').forEach(function (el) {
|
||||||
|
if (el === btn) return;
|
||||||
|
el.addEventListener('click', function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
openReward();
|
||||||
|
});
|
||||||
|
});
|
||||||
if (closeBtn) closeBtn.addEventListener('click', closeReward);
|
if (closeBtn) closeBtn.addEventListener('click', closeReward);
|
||||||
if (overlay) overlay.addEventListener('click', closeReward);
|
if (overlay) overlay.addEventListener('click', closeReward);
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ require_once AKSRT_DIR . '/inc/helpers/aksrt-pay.php';
|
|||||||
require_once AKSRT_DIR . '/inc/helpers/aksrt-coupon-order.php';
|
require_once AKSRT_DIR . '/inc/helpers/aksrt-coupon-order.php';
|
||||||
require_once AKSRT_DIR . '/inc/helpers/aksrt-credits.php';
|
require_once AKSRT_DIR . '/inc/helpers/aksrt-credits.php';
|
||||||
require_once AKSRT_DIR . '/inc/helpers/aksrt-null.php';
|
require_once AKSRT_DIR . '/inc/helpers/aksrt-null.php';
|
||||||
|
require_once AKSRT_DIR . '/inc/helpers/aksrt-identity.php';
|
||||||
require_once AKSRT_DIR . '/inc/helpers/menu-decoration.php';
|
require_once AKSRT_DIR . '/inc/helpers/menu-decoration.php';
|
||||||
require_once AKSRT_DIR . '/inc/helpers/class-aksrt-nav-walker.php';
|
require_once AKSRT_DIR . '/inc/helpers/class-aksrt-nav-walker.php';
|
||||||
require_once AKSRT_DIR . '/inc/helpers/aksrt-transactions.php';
|
require_once AKSRT_DIR . '/inc/helpers/aksrt-transactions.php';
|
||||||
|
|||||||
@@ -250,6 +250,7 @@ class AKSRT_Admin_Schema_Post_List {
|
|||||||
['key' => 'comment_upload_img', 'label' => '评论图片上传', 'type' => 'switch', 'default' => false],
|
['key' => 'comment_upload_img', 'label' => '评论图片上传', 'type' => 'switch', 'default' => false],
|
||||||
]],
|
]],
|
||||||
['key' => 'interaction', 'title' => '互动功能', 'fields' => [
|
['key' => 'interaction', 'title' => '互动功能', 'fields' => [
|
||||||
|
['key' => 'comment_hot_threshold', 'label' => '神评点赞阈值', 'type' => 'number', 'default' => 10, 'min' => 1, 'max' => 999],
|
||||||
['key' => 'comment_like_s', 'label' => '评论点赞', 'type' => 'switch', 'default' => true],
|
['key' => 'comment_like_s', 'label' => '评论点赞', 'type' => 'switch', 'default' => true],
|
||||||
['key' => 'comment_quick_s', 'label' => '快捷回复', 'type' => 'switch', 'default' => true],
|
['key' => 'comment_quick_s', 'label' => '快捷回复', 'type' => 'switch', 'default' => true],
|
||||||
['key' => 'comment_city_s', 'label' => '评论城市', 'type' => 'switch', 'default' => true],
|
['key' => 'comment_city_s', 'label' => '评论城市', 'type' => 'switch', 'default' => true],
|
||||||
|
|||||||
@@ -1055,9 +1055,18 @@ if (!function_exists('aksrt_comment_callback')) :
|
|||||||
<div class="author-box">
|
<div class="author-box">
|
||||||
<?php echo get_avatar($comment, $avatar_size, '', '', ['class' => 'avatar-img comt-avatar']); ?>
|
<?php echo get_avatar($comment, $avatar_size, '', '', ['class' => 'avatar-img comt-avatar']); ?>
|
||||||
<span class="aksrt-comment__author"><?php comment_author_link(); ?></span>
|
<span class="aksrt-comment__author"><?php comment_author_link(); ?></span>
|
||||||
|
<?php
|
||||||
|
$comment_user_id = (int) $comment->user_id;
|
||||||
|
if ($comment_user_id > 0 && function_exists('aksrt_render_user_identity_chips')) {
|
||||||
|
echo aksrt_render_user_identity_chips($comment_user_id, 'comment'); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||||
|
}
|
||||||
|
?>
|
||||||
<?php if ($show_author_tag && $is_post_author) : ?>
|
<?php if ($show_author_tag && $is_post_author) : ?>
|
||||||
<span class="aksrt-comment__badge"><?php esc_html_e('作者', 'aksrt'); ?></span>
|
<span class="aksrt-comment__badge"><?php esc_html_e('作者', 'aksrt'); ?></span>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
<?php if (function_exists('aksrt_is_blog_comment_hot') && aksrt_is_blog_comment_hot($comment)) : ?>
|
||||||
|
<span class="aksrt-comment__badge aksrt-comment__badge--hot"><i class="fas fa-fire" aria-hidden="true"></i> <?php esc_html_e('神评', 'aksrt'); ?></span>
|
||||||
|
<?php endif; ?>
|
||||||
<?php if ($is_pinned) : ?>
|
<?php if ($is_pinned) : ?>
|
||||||
<span class="aksrt-comment__badge aksrt-comment__badge--pinned"><i class="fas fa-thumbtack" aria-hidden="true"></i> <?php esc_html_e('置顶', 'aksrt'); ?></span>
|
<span class="aksrt-comment__badge aksrt-comment__badge--pinned"><i class="fas fa-thumbtack" aria-hidden="true"></i> <?php esc_html_e('置顶', 'aksrt'); ?></span>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|||||||
@@ -0,0 +1,103 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Shared identity chrome: VIP / verify / level / badges for author bar & comments.
|
||||||
|
*
|
||||||
|
* @package AKSRT
|
||||||
|
*/
|
||||||
|
|
||||||
|
defined('ABSPATH') || exit;
|
||||||
|
|
||||||
|
if (!function_exists('aksrt_get_user_identity_signals')) {
|
||||||
|
/**
|
||||||
|
* @return list<array{type:string,label:string,icon:string,tone:string,title?:string}>
|
||||||
|
*/
|
||||||
|
function aksrt_get_user_identity_signals(int $user_id): array {
|
||||||
|
if ($user_id <= 0) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
if (class_exists('AKSRT_User_Home')) {
|
||||||
|
$signals = AKSRT_User_Home::get_instance()->get_profile_signals($user_id);
|
||||||
|
return is_array($signals) ? array_values($signals) : [];
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!function_exists('aksrt_render_user_identity_chips')) {
|
||||||
|
/**
|
||||||
|
* Render compact identity chips (verify / level / badges).
|
||||||
|
*
|
||||||
|
* @param int $user_id
|
||||||
|
* @param string $context author|comment|card
|
||||||
|
*/
|
||||||
|
function aksrt_render_user_identity_chips(int $user_id, string $context = 'author'): string {
|
||||||
|
if ($user_id <= 0) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
$html = '';
|
||||||
|
if (function_exists('aksrt_render_vip_badge')) {
|
||||||
|
$vip = aksrt_render_vip_badge($user_id, 'sm');
|
||||||
|
if (is_string($vip) && $vip !== '') {
|
||||||
|
$html .= $vip;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$signals = aksrt_get_user_identity_signals($user_id);
|
||||||
|
$limit = $context === 'comment' ? 3 : 6;
|
||||||
|
$n = 0;
|
||||||
|
foreach ($signals as $signal) {
|
||||||
|
if ($n >= $limit) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$label = trim((string) ($signal['label'] ?? ''));
|
||||||
|
if ($label === '') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$tone = sanitize_html_class((string) ($signal['tone'] ?? 'info'));
|
||||||
|
$icon = sanitize_html_class((string) ($signal['icon'] ?? 'check'));
|
||||||
|
// Font Awesome: map short names to fa-* if needed.
|
||||||
|
if ($icon !== '' && !str_contains($icon, 'fa-')) {
|
||||||
|
$icon = 'fa-' . $icon;
|
||||||
|
}
|
||||||
|
$title = (string) ($signal['title'] ?? $label);
|
||||||
|
$html .= '<span class="badg badg-sm ml3 aksrt-identity-chip aksrt-identity-chip--' . esc_attr($tone) . ' aksrt-identity-chip--' . esc_attr($context) . '" title="' . esc_attr($title) . '">';
|
||||||
|
if ($icon !== '') {
|
||||||
|
$html .= '<i class="fa ' . esc_attr($icon) . '" aria-hidden="true"></i> ';
|
||||||
|
}
|
||||||
|
$html .= esc_html($label) . '</span>';
|
||||||
|
$n++;
|
||||||
|
}
|
||||||
|
return $html;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!function_exists('aksrt_is_blog_comment_hot')) {
|
||||||
|
/**
|
||||||
|
* "神评" for ordinary post comments when likes cross threshold.
|
||||||
|
*/
|
||||||
|
function aksrt_is_blog_comment_hot($comment): bool {
|
||||||
|
$comment_id = $comment instanceof WP_Comment ? (int) $comment->comment_ID : (int) $comment;
|
||||||
|
if ($comment_id <= 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ('1' === (string) get_comment_meta($comment_id, '_aksrt_comment_hot', true)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
$threshold = 10;
|
||||||
|
if (class_exists('AKSRT_Settings') && method_exists('AKSRT_Settings', 'get_comment_display_settings')) {
|
||||||
|
$display = AKSRT_Settings::get_comment_display_settings();
|
||||||
|
if (isset($display['hot_threshold'])) {
|
||||||
|
$threshold = max(1, (int) $display['hot_threshold']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$all = class_exists('AKSRT_Settings') ? AKSRT_Settings::get_all() : [];
|
||||||
|
if (isset($all['comment_hot_threshold'])) {
|
||||||
|
$threshold = max(1, (int) $all['comment_hot_threshold']);
|
||||||
|
}
|
||||||
|
$likes = function_exists('aksrt_get_comment_likes') ? aksrt_get_comment_likes($comment_id) : (int) get_comment_meta($comment_id, 'aksrt_comment_likes', true);
|
||||||
|
if ($likes < $threshold) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
update_comment_meta($comment_id, '_aksrt_comment_hot', '1');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -306,11 +306,9 @@ if (!function_exists('aksrt_single_render_author_card')) :
|
|||||||
$author_url = get_author_posts_url($author_id);
|
$author_url = get_author_posts_url($author_id);
|
||||||
$author_name = get_the_author();
|
$author_name = get_the_author();
|
||||||
$bio = trim((string) get_the_author_meta('description'));
|
$bio = trim((string) get_the_author_meta('description'));
|
||||||
$vip_badge = function_exists('aksrt_render_vip_badge') ? aksrt_render_vip_badge($author_id, 'sm') : '';
|
$identity_chips = function_exists('aksrt_render_user_identity_chips')
|
||||||
$signals = [];
|
? aksrt_render_user_identity_chips($author_id, 'card')
|
||||||
if (class_exists('AKSRT_User_Home')) {
|
: '';
|
||||||
$signals = AKSRT_User_Home::get_instance()->get_profile_signals($author_id);
|
|
||||||
}
|
|
||||||
$avatar = function_exists('aksrt_get_avatar_html')
|
$avatar = function_exists('aksrt_get_avatar_html')
|
||||||
? aksrt_get_avatar_html($author_id, 80, ['class' => 'avatar avatar-lg'])
|
? aksrt_get_avatar_html($author_id, 80, ['class' => 'avatar avatar-lg'])
|
||||||
: get_avatar($author_id, 80, '', esc_attr($author_name), ['class' => 'avatar avatar-lg']);
|
: get_avatar($author_id, 80, '', esc_attr($author_name), ['class' => 'avatar avatar-lg']);
|
||||||
@@ -331,13 +329,9 @@ if (!function_exists('aksrt_single_render_author_card')) :
|
|||||||
<div class="user-info mt20 mb10">
|
<div class="user-info mt20 mb10">
|
||||||
<div class="user-name flex jc">
|
<div class="user-name flex jc">
|
||||||
<a class="display-name" href="<?php echo esc_url($author_url); ?>"><?php echo esc_html($author_name); ?></a>
|
<a class="display-name" href="<?php echo esc_url($author_url); ?>"><?php echo esc_html($author_name); ?></a>
|
||||||
<?php echo $vip_badge; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
<?php if ($identity_chips !== '') : ?>
|
||||||
<?php foreach ($signals as $signal) : ?>
|
<?php echo $identity_chips; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||||
<span class="badg badg-sm ml3 aksrt-identity-chip aksrt-identity-chip--<?php echo esc_attr((string) ($signal['tone'] ?? 'info')); ?>">
|
<?php endif; ?>
|
||||||
<i class="fa fa-<?php echo esc_attr((string) ($signal['icon'] ?? 'check')); ?>" aria-hidden="true"></i>
|
|
||||||
<?php echo esc_html((string) ($signal['label'] ?? '')); ?>
|
|
||||||
</span>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</div>
|
</div>
|
||||||
<?php if ($bio !== '') : ?>
|
<?php if ($bio !== '') : ?>
|
||||||
<div class="user-desc mt10 muted-2-color em09"><?php echo esc_html($bio); ?></div>
|
<div class="user-desc mt10 muted-2-color em09"><?php echo esc_html($bio); ?></div>
|
||||||
|
|||||||
@@ -48,12 +48,10 @@ $aksrt_msg_url = function_exists('aksrt_get_messages_page_url') ? aksrt_get_mess
|
|||||||
$login_url = function_exists('aksrt_get_login_url') ? aksrt_get_login_url() : wp_login_url(get_permalink());
|
$login_url = function_exists('aksrt_get_login_url') ? aksrt_get_login_url() : wp_login_url(get_permalink());
|
||||||
$is_self = is_user_logged_in() && get_current_user_id() === $author_id;
|
$is_self = is_user_logged_in() && get_current_user_id() === $author_id;
|
||||||
|
|
||||||
// Identity chips: VIP + verify/level/badges.
|
// Identity chips: VIP + verify/level/badges (shared helper).
|
||||||
$vip_badge = function_exists('aksrt_render_vip_badge') ? aksrt_render_vip_badge($author_id, 'sm') : '';
|
$identity_chips = function_exists('aksrt_render_user_identity_chips')
|
||||||
$signals = [];
|
? aksrt_render_user_identity_chips($author_id, 'author')
|
||||||
if (class_exists('AKSRT_User_Home')) {
|
: '';
|
||||||
$signals = AKSRT_User_Home::get_instance()->get_profile_signals($author_id);
|
|
||||||
}
|
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<div class="<?php echo esc_attr($classes); ?>">
|
<div class="<?php echo esc_attr($classes); ?>">
|
||||||
@@ -71,15 +69,9 @@ if (class_exists('AKSRT_User_Home')) {
|
|||||||
<div class="flex1">
|
<div class="flex1">
|
||||||
<span class="name flex ac flex1">
|
<span class="name flex ac flex1">
|
||||||
<a class="display-name text-ellipsis" href="<?php echo esc_url($author_url); ?>"><?php echo esc_html($author_name); ?></a>
|
<a class="display-name text-ellipsis" href="<?php echo esc_url($author_url); ?>"><?php echo esc_html($author_name); ?></a>
|
||||||
<?php if ($vip_badge !== '') : ?>
|
<?php if ($identity_chips !== '') : ?>
|
||||||
<?php echo $vip_badge; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
<?php echo $identity_chips; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<?php foreach ($signals as $signal) : ?>
|
|
||||||
<span class="badg badg-sm ml3 aksrt-identity-chip aksrt-identity-chip--<?php echo esc_attr((string) ($signal['tone'] ?? 'info')); ?>">
|
|
||||||
<i class="fa fa-<?php echo esc_attr((string) ($signal['icon'] ?? 'check')); ?>" aria-hidden="true"></i>
|
|
||||||
<?php echo esc_html((string) ($signal['label'] ?? '')); ?>
|
|
||||||
</span>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</span>
|
</span>
|
||||||
<div class="px12-sm muted-2-color text-ellipsis">
|
<div class="px12-sm muted-2-color text-ellipsis">
|
||||||
<?php if ($show_time) : ?>
|
<?php if ($show_time) : ?>
|
||||||
|
|||||||
Reference in New Issue
Block a user