feat(checkin): open reference-parity details modal from signed buttons
- Rebuild checkin details modal HTML 1:1 with reference theme: colorful header c-blue, user card (points/level), daily reward card and 7-day continuous mini cards - Signed entry buttons (header dropdown, user-card badge, user center) become clickable checkin-details-link modal triggers instead of disabled buttons - Swap data-signin-btn to details link in place after successful signin (reference .initiate-checkin replacement behavior) - Add aksrt-checkin-details-modal runtime shell (modal-mini 400px) - Remove dead code: legacy lite modal, admin-ajax details handler, /signin/history route, signin calendar; rebuild public bundles - Update contract tests to the new checkin modal contract
This commit is contained in:
+19
-39
@@ -3046,10 +3046,8 @@ main.container,
|
||||
}
|
||||
|
||||
/* 已签到态对齐参考主题:保留原配色(参考主题签到后仍为同一彩色按钮),
|
||||
* 仅禁用指针交互;此前的灰底灰字覆盖是与参考主题的偏差。 */
|
||||
.aksrt-header-checkin.is-done,
|
||||
* 且按钮可点击(打开签到详情弹窗);仅请求进行中的禁用态降不透明度。 */
|
||||
.aksrt-header-checkin:disabled,
|
||||
.aksrt-header-checkin.is-done:hover,
|
||||
.aksrt-header-checkin:disabled:hover {
|
||||
cursor: default;
|
||||
opacity: .85;
|
||||
@@ -6269,42 +6267,7 @@ body.aksrt-body-scroll .aksrt-show-on-scroll {
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
* 18. 签到日历可视化
|
||||
* ============================================================ */
|
||||
.aksrt-signin-calendar__grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(7, 1fr);
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.aksrt-signin-calendar__day {
|
||||
aspect-ratio: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 6px;
|
||||
background: var(--surface-2, #F4F5F7);
|
||||
font-size: 12px;
|
||||
color: var(--color-ink-3);
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.aksrt-signin-calendar__day.is-signed {
|
||||
background: var(--color-success, #10B981);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.aksrt-signin-calendar__day.is-today {
|
||||
border: 2px solid var(--color-primary, var(--color-primary));
|
||||
}
|
||||
|
||||
.aksrt-signin-calendar__day.is-signed.is-today {
|
||||
background: var(--color-primary, var(--color-primary));
|
||||
border-color: var(--color-primary, var(--color-primary));
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
* 19. VIP 等级标识
|
||||
* 18. VIP 等级标识
|
||||
* ============================================================ */
|
||||
.aksrt-vip-badge {
|
||||
display: inline-flex;
|
||||
@@ -7180,6 +7143,23 @@ body.aksrt-modal-runtime-open {
|
||||
color: var(--color-on-primary, #fff);
|
||||
}
|
||||
|
||||
/* ---- 签到详情弹窗(参考主题 refresh_modal modal-mini 同构壳) ----
|
||||
内容为服务端 HTML(modal-colorful-header + modal-body),与参考主题
|
||||
.modal-dialog.modal-mini 几何 1:1:宽 400px、圆角 var(--main-radius)。 */
|
||||
.aksrt-modal-runtime.aksrt-checkin-details-modal:not(.aksrt-modal-runtime--bottom) .aksrt-modal-runtime__dialog {
|
||||
width: min(400px, calc(100vw - 32px));
|
||||
border-radius: var(--main-radius, 8px);
|
||||
background: var(--main-bg-color, #fff);
|
||||
}
|
||||
|
||||
.aksrt-modal-runtime.aksrt-checkin-details-modal .aksrt-modal-runtime__content {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.aksrt-modal-runtime.aksrt-checkin-details-modal .aksrt-modal-runtime__skeleton {
|
||||
padding: 24px 18px;
|
||||
}
|
||||
|
||||
/* ---- ajax list ---- */
|
||||
.ajaxpager.is-ajax-loading {
|
||||
position: relative;
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -356,42 +356,7 @@
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
* 18. 签到日历可视化
|
||||
* ============================================================ */
|
||||
.aksrt-signin-calendar__grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(7, 1fr);
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.aksrt-signin-calendar__day {
|
||||
aspect-ratio: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 6px;
|
||||
background: var(--surface-2, #F4F5F7);
|
||||
font-size: 12px;
|
||||
color: var(--color-ink-3);
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.aksrt-signin-calendar__day.is-signed {
|
||||
background: var(--color-success, #10B981);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.aksrt-signin-calendar__day.is-today {
|
||||
border: 2px solid var(--color-primary, var(--color-primary));
|
||||
}
|
||||
|
||||
.aksrt-signin-calendar__day.is-signed.is-today {
|
||||
background: var(--color-primary, var(--color-primary));
|
||||
border-color: var(--color-primary, var(--color-primary));
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
* 19. VIP 等级标识
|
||||
* 18. VIP 等级标识
|
||||
* ============================================================ */
|
||||
.aksrt-vip-badge {
|
||||
display: inline-flex;
|
||||
|
||||
@@ -327,10 +327,8 @@
|
||||
}
|
||||
|
||||
/* 已签到态对齐参考主题:保留原配色(参考主题签到后仍为同一彩色按钮),
|
||||
* 仅禁用指针交互;此前的灰底灰字覆盖是与参考主题的偏差。 */
|
||||
.aksrt-header-checkin.is-done,
|
||||
* 且按钮可点击(打开签到详情弹窗);仅请求进行中的禁用态降不透明度。 */
|
||||
.aksrt-header-checkin:disabled,
|
||||
.aksrt-header-checkin.is-done:hover,
|
||||
.aksrt-header-checkin:disabled:hover {
|
||||
cursor: default;
|
||||
opacity: .85;
|
||||
|
||||
@@ -223,6 +223,23 @@ body.aksrt-modal-runtime-open {
|
||||
color: var(--color-on-primary, #fff);
|
||||
}
|
||||
|
||||
/* ---- 签到详情弹窗(参考主题 refresh_modal modal-mini 同构壳) ----
|
||||
内容为服务端 HTML(modal-colorful-header + modal-body),与参考主题
|
||||
.modal-dialog.modal-mini 几何 1:1:宽 400px、圆角 var(--main-radius)。 */
|
||||
.aksrt-modal-runtime.aksrt-checkin-details-modal:not(.aksrt-modal-runtime--bottom) .aksrt-modal-runtime__dialog {
|
||||
width: min(400px, calc(100vw - 32px));
|
||||
border-radius: var(--main-radius, 8px);
|
||||
background: var(--main-bg-color, #fff);
|
||||
}
|
||||
|
||||
.aksrt-modal-runtime.aksrt-checkin-details-modal .aksrt-modal-runtime__content {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.aksrt-modal-runtime.aksrt-checkin-details-modal .aksrt-modal-runtime__skeleton {
|
||||
padding: 24px 18px;
|
||||
}
|
||||
|
||||
/* ---- ajax list ---- */
|
||||
.ajaxpager.is-ajax-loading {
|
||||
position: relative;
|
||||
|
||||
@@ -241,41 +241,6 @@
|
||||
});
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
* 8. 签到日历可视化
|
||||
* ============================================================ */
|
||||
function initSigninCalendar() {
|
||||
var calendar = document.querySelector('[data-aksrt-signin-calendar]');
|
||||
if (!calendar) return;
|
||||
|
||||
var data = [];
|
||||
try {
|
||||
data = JSON.parse(calendar.dataset.aksrtSigninCalendar || '[]');
|
||||
} catch (e) {}
|
||||
|
||||
// 生成最近 30 天的格子
|
||||
var today = new Date();
|
||||
var html = '<div class="aksrt-signin-calendar__grid">';
|
||||
|
||||
for (var i = 29; i >= 0; i--) {
|
||||
var d = new Date(today);
|
||||
d.setDate(d.getDate() - i);
|
||||
var dateStr = d.toISOString().split('T')[0];
|
||||
var isSigned = data.indexOf(dateStr) !== -1;
|
||||
var isToday = i === 0;
|
||||
|
||||
html += '<div class="aksrt-signin-calendar__day' +
|
||||
(isSigned ? ' is-signed' : '') +
|
||||
(isToday ? ' is-today' : '') +
|
||||
'" title="' + dateStr + (isSigned ? ' ✓' : '') + '">' +
|
||||
'<span>' + d.getDate() + '</span>' +
|
||||
'</div>';
|
||||
}
|
||||
|
||||
html += '</div>';
|
||||
calendar.innerHTML = html;
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
* 初始化入口 — 先执行一次,随后监听 auto_fun 重扫(各 init 幂等)
|
||||
* ============================================================ */
|
||||
@@ -286,7 +251,6 @@
|
||||
initSticky();
|
||||
initParallax();
|
||||
initFloatLabels();
|
||||
initSigninCalendar();
|
||||
}
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -72,6 +72,26 @@
|
||||
});
|
||||
}
|
||||
|
||||
// 签到成功后,入口按钮就地替换为「已签到」详情弹窗触发链接
|
||||
// (参考主题:.initiate-checkin → details_link 的替换行为)。
|
||||
function swapButtonsToDetailsLink() {
|
||||
var url = window.aksrtData && window.aksrtData.signinDetailsUrl;
|
||||
if (!url) return;
|
||||
currentButtons().forEach(function (button) {
|
||||
var link = document.createElement('a');
|
||||
link.href = 'javascript:;';
|
||||
link.className = (button.className || '') + ' checkin-details-link';
|
||||
link.setAttribute('data-aksrt-modal', 'remote');
|
||||
link.setAttribute('data-aksrt-modal-url', url);
|
||||
link.setAttribute('data-aksrt-modal-class', 'aksrt-checkin-details-modal modal-mini');
|
||||
link.setAttribute('data-aksrt-modal-height', '240');
|
||||
link.setAttribute('data-aksrt-modal-mobile-bottom', 'true');
|
||||
link.setAttribute('data-aksrt-modal-cache', 'false');
|
||||
link.innerHTML = button.innerHTML;
|
||||
button.replaceWith(link);
|
||||
});
|
||||
}
|
||||
|
||||
function refresh() {
|
||||
api('/signin/today').then(function (result) {
|
||||
if (!result.ok) {
|
||||
@@ -90,6 +110,7 @@
|
||||
if (data.signed) {
|
||||
setStatusHtml('已签到 <strong>' + data.streak + '</strong> 天 +' + data.reward_today);
|
||||
setButtonState('done');
|
||||
swapButtonsToDetailsLink();
|
||||
return;
|
||||
}
|
||||
setStatusHtml('连续 <strong>' + data.streak + '</strong> 天,+' + data.reward_if_signin);
|
||||
@@ -120,6 +141,7 @@
|
||||
element.title = element.textContent;
|
||||
});
|
||||
setButtonState('done');
|
||||
swapButtonsToDetailsLink();
|
||||
refresh();
|
||||
}).finally(function () {
|
||||
if (window.AKSRTCaptcha) window.AKSRTCaptcha.reset('signin', captchaMount());
|
||||
|
||||
Reference in New Issue
Block a user