fix(widgets): stabilize user card layout
This commit is contained in:
@@ -22,61 +22,170 @@
|
||||
}
|
||||
|
||||
.aksrt-user-card {
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
min-width: 0;
|
||||
border-radius: 8px;
|
||||
overflow: visible;
|
||||
border: 1px solid var(--color-line, #e5e7eb);
|
||||
background: var(--surface-1, #fff);
|
||||
text-align: center;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.aksrt-user-card__cover {
|
||||
height: 90px;
|
||||
background: linear-gradient(135deg, #93c5fd, #c4b5fd) center/cover no-repeat;
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
height: 104px;
|
||||
min-height: 104px;
|
||||
max-height: 104px;
|
||||
margin: 0;
|
||||
padding: 0 !important;
|
||||
overflow: hidden;
|
||||
border-radius: 7px 7px 0 0;
|
||||
background-color: #93c5fd;
|
||||
background-image: linear-gradient(135deg, #93c5fd, #c4b5fd);
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
}
|
||||
.aksrt-user-card__cover.is-empty {
|
||||
background: linear-gradient(135deg, #e2e8f0, #f8fafc);
|
||||
}
|
||||
.aksrt-user-card__body { padding: 0 14px 16px; position: relative; }
|
||||
.aksrt-user-card__body {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
min-width: 0;
|
||||
padding: 0 16px 18px;
|
||||
}
|
||||
.aksrt-user-card__checkin {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 8px;
|
||||
z-index: 2;
|
||||
max-width: 48%;
|
||||
top: 66%;
|
||||
right: 0;
|
||||
z-index: 3;
|
||||
max-width: calc(100% - 56px);
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
.aksrt-user-card__checkin .but {
|
||||
padding: 4px 8px !important;
|
||||
font-size: 12px !important;
|
||||
line-height: 1.2;
|
||||
.aksrt-user-card__checkin--without-cover {
|
||||
position: relative;
|
||||
top: auto;
|
||||
right: auto;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
max-width: none;
|
||||
margin: 10px 0 0;
|
||||
transform: none;
|
||||
}
|
||||
.aksrt-user-card .aksrt-user-card__checkin .aksrt-header-checkin {
|
||||
width: auto !important;
|
||||
min-height: 40px;
|
||||
padding: 8px 12px !important;
|
||||
border-radius: 6px 0 0 6px !important;
|
||||
font-size: 13px !important;
|
||||
line-height: 1.25;
|
||||
}
|
||||
.aksrt-user-card__checkin .aksrt-header-checkin-details { display: none; }
|
||||
.aksrt-user-card__avatar {
|
||||
.aksrt-user-card__avatar-wrap {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
margin-top: -36px;
|
||||
width: 72px;
|
||||
height: 72px;
|
||||
flex: 0 0 auto;
|
||||
width: 76px;
|
||||
height: 76px;
|
||||
margin: -38px auto 0;
|
||||
}
|
||||
.aksrt-user-card.no-cover .aksrt-user-card__avatar-wrap {
|
||||
margin-top: 16px;
|
||||
}
|
||||
.aksrt-user-card__avatar {
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
width: 76px;
|
||||
height: 76px;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
border: 3px solid var(--surface-1, #fff);
|
||||
background: var(--surface-2, #eee);
|
||||
}
|
||||
.aksrt-user-card__avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
|
||||
.aksrt-user-card__avatar > a {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.aksrt-user-card__avatar > img,
|
||||
.aksrt-user-card__avatar > a > img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
.aksrt-user-card__vip {
|
||||
position: absolute;
|
||||
right: -5px;
|
||||
bottom: -3px;
|
||||
z-index: 2;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: 28px;
|
||||
height: 28px;
|
||||
padding: 3px;
|
||||
border: 2px solid var(--surface-1, #fff);
|
||||
border-radius: 50%;
|
||||
background: var(--surface-1, #fff);
|
||||
box-shadow: 0 2px 6px rgba(0, 0, 0, .18);
|
||||
line-height: 1;
|
||||
}
|
||||
.aksrt-user-card__vip .aksrt-vip-badge {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.aksrt-user-card__vip .aksrt-vip-badge__icon {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
max-width: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
.aksrt-user-card__name {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
margin: 10px 0 0;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
line-height: 1.35;
|
||||
}
|
||||
.aksrt-user-card__name-row {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: 0;
|
||||
max-width: 100%;
|
||||
gap: 4px;
|
||||
}
|
||||
.aksrt-user-card__name .display-name {
|
||||
min-width: 0;
|
||||
max-width: 100%;
|
||||
}
|
||||
.aksrt-user-card__name a { color: inherit; text-decoration: none; }
|
||||
.aksrt-user-card__bio,
|
||||
.aksrt-user-card__guest-title {
|
||||
width: 100%;
|
||||
margin: 8px 0 0;
|
||||
font-size: 12px;
|
||||
color: var(--muted-2-color, #888);
|
||||
line-height: 1.5;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
.aksrt-user-card__guest-title { font-size: 14px; font-weight: 600; color: inherit; }
|
||||
.aksrt-user-card__stats {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
gap: 18px;
|
||||
margin-top: 12px;
|
||||
@@ -92,6 +201,7 @@
|
||||
}
|
||||
.aksrt-user-card__actions {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
|
||||
@@ -119,9 +119,12 @@
|
||||
btn.disabled = true;
|
||||
btn.setAttribute('disabled', 'disabled');
|
||||
// Keep existing structure so CSS layout (.but.block flex) is not lost.
|
||||
var signedLabel = btn.classList.contains('aksrt-header-checkin--compact')
|
||||
? '已签到'
|
||||
: '今日已签到';
|
||||
btn.innerHTML =
|
||||
'<i class="fas fa-calendar-check" aria-hidden="true"></i>' +
|
||||
'<span>今日已签到</span>';
|
||||
'<span>' + signedLabel + '</span>';
|
||||
})
|
||||
.catch(function () {
|
||||
toast('网络错误', 'danger');
|
||||
|
||||
@@ -9,9 +9,12 @@ defined('ABSPATH') || exit;
|
||||
|
||||
if (!function_exists('aksrt_header_user_checkin_btn')) :
|
||||
/**
|
||||
* Check-in CTA for header dropdown (uses REST /aksrt/v1/signin).
|
||||
* Check-in CTA for header dropdown and compact card placements (uses REST /aksrt/v1/signin).
|
||||
*
|
||||
* @param int $user_id Current user ID.
|
||||
* @param bool $compact Render a short card-friendly label.
|
||||
*/
|
||||
function aksrt_header_user_checkin_btn(int $user_id = 0): string {
|
||||
function aksrt_header_user_checkin_btn(int $user_id = 0, bool $compact = false): string {
|
||||
$user_id = $user_id > 0 ? $user_id : get_current_user_id();
|
||||
if ($user_id <= 0 || !class_exists('\AKSRT\Credits\Signin')) {
|
||||
return '';
|
||||
@@ -39,16 +42,17 @@ if (!function_exists('aksrt_header_user_checkin_btn')) :
|
||||
$signed = false;
|
||||
}
|
||||
|
||||
$compact_class = $compact ? ' aksrt-header-checkin--compact' : '';
|
||||
if ($signed) {
|
||||
return '<button type="button" class="but block c-yellow aksrt-header-checkin is-done" disabled>'
|
||||
return '<button type="button" class="but block c-yellow aksrt-header-checkin' . $compact_class . ' is-done" disabled>'
|
||||
. '<i class="fas fa-calendar-check" aria-hidden="true"></i>'
|
||||
. '<span>' . esc_html__('今日已签到', 'aksrt') . '</span>'
|
||||
. '<span>' . esc_html($compact ? __('已签到', 'aksrt') : __('今日已签到', 'aksrt')) . '</span>'
|
||||
. '</button>';
|
||||
}
|
||||
|
||||
return '<button type="button" class="but block c-yellow aksrt-header-checkin" data-aksrt-checkin="1">'
|
||||
return '<button type="button" class="but block c-yellow aksrt-header-checkin' . $compact_class . '" data-aksrt-checkin="1">'
|
||||
. '<i class="fas fa-calendar-check" aria-hidden="true"></i>'
|
||||
. '<span>' . esc_html__('签到领取今日奖励', 'aksrt') . '</span>'
|
||||
. '<span>' . esc_html($compact ? __('签到', 'aksrt') : __('签到领取今日奖励', 'aksrt')) . '</span>'
|
||||
. '</button>';
|
||||
}
|
||||
endif;
|
||||
|
||||
@@ -7,13 +7,9 @@
|
||||
|
||||
namespace AKSRT\Widgets;
|
||||
|
||||
use AKSRT\Widgets\Traits\CommonWidgetFields;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
class WidgetUserCard extends \WP_Widget {
|
||||
use CommonWidgetFields;
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct(
|
||||
'aksrt_user_card',
|
||||
@@ -122,13 +118,28 @@ class WidgetUserCard extends \WP_Widget {
|
||||
}
|
||||
|
||||
$name_html = function_exists('aksrt_get_user_name')
|
||||
? aksrt_get_user_name(['id' => $user_id, 'follow' => !$is_self, 'class' => 'flex ac jc'])
|
||||
? aksrt_get_user_name([
|
||||
'id' => $user_id,
|
||||
'vip' => false,
|
||||
'follow' => !$is_self,
|
||||
'class' => 'aksrt-user-card__name-row',
|
||||
])
|
||||
: '<a href="' . esc_url($profile_url) . '">' . esc_html($user->display_name) . '</a>';
|
||||
$vip_badge = function_exists('aksrt_render_vip_badge')
|
||||
? (string) aksrt_render_vip_badge($user_id, 'sm')
|
||||
: '';
|
||||
$checkin_btn = '';
|
||||
if ($show_checkin && $is_self && function_exists('aksrt_header_user_checkin_btn')) {
|
||||
$checkin_btn = aksrt_header_user_checkin_btn($user_id, true);
|
||||
}
|
||||
$checkin_html = $checkin_btn !== ''
|
||||
? '<div class="aksrt-user-card__checkin">' . $checkin_btn . '</div>'
|
||||
: '';
|
||||
|
||||
echo '<div class="aksrt-user-card user-card">';
|
||||
echo '<div class="aksrt-user-card user-card' . ($show_cover ? ' has-cover' : ' no-cover') . '">';
|
||||
if ($show_cover) {
|
||||
if ($cover !== '') {
|
||||
echo '<div class="aksrt-user-card__cover user-cover graphic" style="background-image:url(' . esc_url($cover) . ')"></div>';
|
||||
echo '<div class="aksrt-user-card__cover" style="background-image:url(' . esc_url($cover) . ')">' . $checkin_html . '</div>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
} else {
|
||||
// Prefer site default cover image when available.
|
||||
$default_cover = '';
|
||||
@@ -139,22 +150,23 @@ class WidgetUserCard extends \WP_Widget {
|
||||
$default_cover = (string) get_theme_mod('aksrt_user_cover', '');
|
||||
}
|
||||
if ($default_cover !== '') {
|
||||
echo '<div class="aksrt-user-card__cover user-cover graphic" style="background-image:url(' . esc_url($default_cover) . ')"></div>';
|
||||
echo '<div class="aksrt-user-card__cover" style="background-image:url(' . esc_url($default_cover) . ')">' . $checkin_html . '</div>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
} else {
|
||||
echo '<div class="aksrt-user-card__cover user-cover graphic is-empty"></div>';
|
||||
echo '<div class="aksrt-user-card__cover is-empty">' . $checkin_html . '</div>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
}
|
||||
}
|
||||
} elseif ($checkin_btn !== '') {
|
||||
echo '<div class="aksrt-user-card__checkin aksrt-user-card__checkin--without-cover">' . $checkin_btn . '</div>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
}
|
||||
echo '<div class="aksrt-user-card__body card-content">';
|
||||
if ($show_checkin && $is_self && function_exists('aksrt_header_user_checkin_btn')) {
|
||||
$btn = aksrt_header_user_checkin_btn($user_id);
|
||||
if ($btn !== '') {
|
||||
echo '<div class="aksrt-user-card__checkin">' . $btn . '</div>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
}
|
||||
}
|
||||
echo '<div class="aksrt-user-card__avatar-wrap">';
|
||||
echo '<div class="aksrt-user-card__avatar user-avatar">';
|
||||
$ph = get_template_directory_uri() . '/assets/img/placeholder.svg';
|
||||
echo '<a href="' . esc_url($profile_url) . '"><img class="aksrt-lazy lazyload" data-src="' . esc_url($avatar_url) . '" src="' . esc_url($ph) . '" alt="' . esc_attr($user->display_name) . '" loading="lazy" width="72" height="72" /></a>';
|
||||
echo '<a href="' . esc_url($profile_url) . '"><img class="aksrt-lazy lazyload" data-src="' . esc_url($avatar_url) . '" src="' . esc_url($ph) . '" alt="' . esc_attr($user->display_name) . '" loading="lazy" width="76" height="76" /></a>';
|
||||
echo '</div>';
|
||||
if ($vip_badge !== '') {
|
||||
echo '<span class="aksrt-user-card__vip">' . $vip_badge . '</span>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
}
|
||||
echo '</div>';
|
||||
echo '<h4 class="aksrt-user-card__name user-name">' . $name_html . '</h4>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
if ($bio !== '') {
|
||||
@@ -212,20 +224,20 @@ class WidgetUserCard extends \WP_Widget {
|
||||
}
|
||||
}
|
||||
|
||||
echo '<div class="aksrt-user-card user-card is-guest">';
|
||||
echo '<div class="aksrt-user-card user-card is-guest' . ($show_cover ? ' has-cover' : ' no-cover') . '">';
|
||||
if ($show_cover) {
|
||||
$default_cover = '';
|
||||
if (class_exists('\AKSRT\Settings\Settings') && method_exists('\AKSRT\Settings\Settings', 'get_user_cover_default')) {
|
||||
$default_cover = (string) \AKSRT\Settings\Settings::get_user_cover_default();
|
||||
}
|
||||
if ($default_cover !== '') {
|
||||
echo '<div class="aksrt-user-card__cover user-cover graphic" style="background-image:url(' . esc_url($default_cover) . ')"></div>';
|
||||
echo '<div class="aksrt-user-card__cover" style="background-image:url(' . esc_url($default_cover) . ')"></div>';
|
||||
} else {
|
||||
echo '<div class="aksrt-user-card__cover user-cover graphic is-empty"></div>';
|
||||
echo '<div class="aksrt-user-card__cover is-empty"></div>';
|
||||
}
|
||||
}
|
||||
echo '<div class="aksrt-user-card__body card-content">';
|
||||
echo '<div class="aksrt-user-card__avatar user-avatar"><img src="' . esc_url($default_avatar) . '" alt="" width="72" height="72" loading="lazy" /></div>';
|
||||
echo '<div class="aksrt-user-card__avatar-wrap"><div class="aksrt-user-card__avatar user-avatar"><img src="' . esc_url($default_avatar) . '" alt="" width="76" height="76" loading="lazy" /></div></div>';
|
||||
echo '<div class="aksrt-user-card__guest-title">' . esc_html($loged_title) . '</div>';
|
||||
echo '<div class="aksrt-user-card__actions">';
|
||||
echo '<a class="aksrt-user-card__btn aksrt-user-card__btn--primary signin-loader" href="' . esc_url($login) . '">' . esc_html__('登录', 'aksrt') . '</a>';
|
||||
@@ -320,7 +332,6 @@ class WidgetUserCard extends \WP_Widget {
|
||||
</select>
|
||||
</label>
|
||||
</p>
|
||||
<?php $this->render_common_form_section($instance); ?>
|
||||
<?php
|
||||
}
|
||||
|
||||
@@ -333,7 +344,7 @@ class WidgetUserCard extends \WP_Widget {
|
||||
if (!in_array($orderby, ['date', 'views', 'comment_count', 'modified', 'rand'], true)) {
|
||||
$orderby = 'date';
|
||||
}
|
||||
return $this->update_common_fields($new_instance, $old_instance, [
|
||||
return [
|
||||
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
|
||||
'user_id' => max(0, (int) ($new_instance['user_id'] ?? 0)),
|
||||
'loged_title' => sanitize_text_field((string) ($new_instance['loged_title'] ?? '')),
|
||||
@@ -351,7 +362,7 @@ class WidgetUserCard extends \WP_Widget {
|
||||
'limit' => max(0, min(12, (int) ($new_instance['limit'] ?? 6))),
|
||||
'post_style' => $post_style,
|
||||
'orderby' => $orderby,
|
||||
]);
|
||||
];
|
||||
}
|
||||
|
||||
/** Zibll CFS_Module::zib_palette() gradient/solid keys (c/b/jb families). */
|
||||
|
||||
Reference in New Issue
Block a user