评论/回复只显示审核通过的(星空留言、广场、专题页,自己也不显示审核中);星空亮星均匀铺满整片夜空

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
deploy
2026-11-07 03:23:48 +00:00
parent 35717e8793
commit 580f5144a7
5 changed files with 32 additions and 25 deletions

View File

@@ -3,7 +3,7 @@
(function () {
'use strict';
/* 页面版本号(YYMMDD+序号):显示在「关于兜爸心选」页底部;bump 时同步 head 注释与 ?v= */
var VER = '26110622';
var VER = '26110623';
const $ = (s, c) => (c || document).querySelector(s);
const $$ = (s, c) => Array.from((c || document).querySelectorAll(s));
@@ -4520,23 +4520,26 @@
}
/* 亮星落在夜空中上部偏右(流星往左下走,右边起步才划得够长);抖动网格,不会叠在一起 */
function paintSky(l) {
/* 11-07 用户:可以点的星星再多一些 → 超过 26 颗时铺开到 6 列、更宽更高的一片,点得到不挤 */
const n = l.length, big = n > 26, cols = big ? 6 : n > 16 ? 5 : 4, rows = Math.max(2, Math.ceil(n / cols));
const X0 = big ? 16 : 36, XW = big ? 78 : 58, Y0 = big ? 30 : 21, YH = big ? 38 : 38; // 铺开时从话题牌下面开始,不压标题
/* 11-07 用户:「星星要均匀地挂在星空中,不要密集地放在一个地方」→ 话题牌下面到「说一句」上面整片夜空
(横 8–92%、竖 31–79%)切成差不多正方的格子,n 颗星按等间隔挑格子,每格里小幅抖动 */
const n = l.length, X0 = 8, XW = 84, Y0 = 31, YH = 48;
const pw = page.clientWidth || 390, phh = page.clientHeight || 844;
const cols = Math.max(3, Math.round(Math.sqrt(n * (XW * pw) / (YH * phh)))), rows = Math.max(2, Math.ceil(n / cols));
const cell = l.map((it, i) => Math.floor(i * cols * rows / n));
const fresh = l.findIndex(x => !x.mine && !seen.has(x.id));
const xs = l.map((it, i) => X0 + ((i % cols + .5 + ((hsh(it.id) % 100) / 100 - .5) * .7) / cols) * XW);
const xs = l.map((it, i) => X0 + ((cell[i] % cols + .5 + ((hsh(it.id) % 100) / 100 - .5) * .6) / cols) * XW);
/* 十三改(用户:「每点一下都是一个音符,每一个星星代表不同的音符」):
按横向位置从左到右排成一架竖琴——越靠左越低、越靠右越高,五声音阶(C4 起),连着点就是一段旋律 */
const rank = xs.map((x, i) => i).sort((p, q) => xs[p] - xs[q]);
const note = [];
rank.forEach((i, k) => { note[i] = PENTA[k % PENTA.length]; });
$('#wskBright').innerHTML = l.map((it, i) => {
const h = hsh(it.id), r = Math.floor(i / cols);
const h = hsh(it.id), r = Math.floor(cell[i] / cols);
const x = xs[i];
const y = Y0 + ((r + .5 + (((h >> 8) % 100) / 100 - .5) * .6) / rows) * YH;
const y = Y0 + ((r + .5 + (((h >> 8) % 100) / 100 - .5) * .5) / rows) * YH;
const sz = it.mine ? 26 : Math.round(15 + Math.min(it.hugs || 0, 30) / 30 * 11);
return '<button type="button" class="wsk-st' + (it.mine ? ' mine' : '') + (seen.has(it.id) ? ' used' : '') + (i === fresh && !seen.size ? ' hint' : '') +
'" data-go="' + (i + 1) + '" data-note="' + note[i].toFixed(1) + '" style="left:' + x.toFixed(1) + '%;top:' + y.toFixed(1) + '%;--s:' + sz + 'px;--tw:' + (2 + (h % 30) / 10).toFixed(1) + 's" aria-label="' + esc(it.text) + '"><i></i></button>';
'" data-go="' + (i + 1) + '" data-hx="' + x.toFixed(1) + '" data-hy="' + y.toFixed(1) + '" data-note="' + note[i].toFixed(1) + '" style="left:' + x.toFixed(1) + '%;top:' + y.toFixed(1) + '%;--s:' + sz + 'px;--tw:' + (2 + (h % 30) / 10).toFixed(1) + 's" aria-label="' + esc(it.text) + '"><i></i></button>';
}).join('');
}
function paintList(l) {
@@ -4589,8 +4592,9 @@
function reborn(btn) {
setTimeout(() => {
if (!btn.isConnected || !btn.classList.contains('used')) return;
btn.style.left = (36 + Math.random() * 58).toFixed(1) + '%';
btn.style.top = (21 + Math.random() * 38).toFixed(1) + '%';
/* 回到自己那一格(小幅挪一点),整片星空保持均匀 */
btn.style.left = (+btn.dataset.hx + (Math.random() - .5) * 4).toFixed(1) + '%';
btn.style.top = (+btn.dataset.hy + (Math.random() - .5) * 3).toFixed(1) + '%';
btn.classList.remove('used', 'cur', 'flare', 'gone');
btn.classList.add('born');
setTimeout(() => btn.classList.remove('born'), 1500);
@@ -4991,7 +4995,7 @@
/* 11-07 悄悄话第 2 步(用户定):星空页「说一句」并入留言区 —— 发成置顶笔记下的留言(先审后发),赞够门槛自动挂星 */
if (window.MBWhCm) {
MBWhCm.post(t, data.week)
.then(m => { if (m) { toast(m); return; } closeModal(); toast('发出去了,审核通过后大家就能看到'); })
.then(m => { if (m) { toast(m); return; } closeModal(); toast('已提交,审核通过后才会显示'); })
.then(() => { busy = false; btn.disabled = false; btn.textContent = '悄悄发出'; });
return;
}

View File

@@ -4,7 +4,7 @@
「说一句」按钮下面一条入口 → 半屏面板(先开到半屏,拖把手 / 往上划能拉到 2/3,再往上就不动了;往下拖关掉)。
面板里自己滚动看全部留言。右上角「全部」也打开这个面板(原来那个只列悄悄话的抽屉不用了)。
· 数据:广场置顶笔记 wh-<话题 from> 的评论 = cm.json 模拟(AGENTS.md 12c,不得挂星)+ /plaza/comments 已审核通过的真实评论
+ 我自己发的(含审核中)。打开星空页才拉 cm.json(版本号跟广场 index.html 引的一致,共用缓存)。
+ 我自己发的(11-07 起只显示已通过的)。打开星空页才拉 cm.json(版本号跟广场 index.html 引的一致,共用缓存)。
· 真实留言的赞走服务端(POST /plaza/comment/like,每人每条一次、不能赞自己),赞够 starLikes(后台可改,先 3)自动挂星;
模拟留言的赞只记本机 mmbox.whcm.v1。最热 / 最新 / 同孕周 三种看法。
· 三改(用户:「我不能给别人的留言回复」):点留言上的「回复」→ 底部输入框回复那一楼(先审后发);
@@ -77,7 +77,8 @@
.then(function (r) { return r.json(); }).then(function (j) {
var R = j && j.code === 200 && j.result || {};
if (R.starLikes) STAR_N = R.starLikes;
var mine = (R.mine || []).filter(function (c) { return c.status !== 'rejected'; });
/* 11-07 用户:留言、回复一定要审核通过才显示,自己也不显示「审核中」 */
var mine = (R.mine || []).filter(function (c) { return c.status === 'approved'; });
REAL = (R.list || []).filter(top).map(realOf).concat(mine.filter(top).map(function (c) { var o = realOf(c); o.n = '我'; o.me = 1; o.st = c.status; return o; }));
RREP = (R.list || []).filter(function (c) { return !top(c); }).map(function (c) { return repOf(c, 0); })
.concat(mine.filter(function (c) { return !top(c); }).map(function (c) { return repOf(c, 1); }));
@@ -187,11 +188,10 @@
var on = likedOf(c), rp = repsOf(c);
return '<div class="wcm-it" data-k="' + esc(c.key) + '"><img class="wcm-av" src="' + esc(c.av) + '" alt="" loading="lazy" onerror="this.style.visibility=\'hidden\'">' +
'<div class="wcm-bd"><p class="wcm-nm"><b>' + esc(c.n) + '</b>' + (c.s ? '<span>' + esc(c.s) + '</span>' : '') + (c.ts ? '<span>' + ago(c.ts) + '</span>' : '') + '</p>' +
'<p class="wcm-tx">' + esc(c.t) + '</p>' + (c.st === 'pending' ? '<p class="wcm-st">审核中,通过了大家才看得到</p>' : '') +
'<p class="wcm-tx">' + esc(c.t) + '</p>' +
(c.star ? '<p class="wcm-star"><svg viewBox="0 0 20 20"><path d="M10 .5C10.9 7.4 12.6 9.1 19.5 10 12.6 10.9 10.9 12.6 10 19.5 9.1 12.6 7.4 10.9.5 10 7.4 9.1 9.1 7.4 10 .5Z"/></svg>已经变成星星了</p>' : '') +
(rp.length ? '<div class="wcm-rp">' + rp.map(function (x) {
return '<p' + (x.me ? ' class="me"' : '') + '><b>' + esc(x.n) + '</b>' + (x.to && x.to !== c.n ? ' 回复 <b>' + esc(x.to) + '</b>' : '') + ':' + esc(x.t) +
(x.st === 'pending' ? '<span class="wcm-st">(审核中)</span>' : '') + '</p>';
return '<p' + (x.me ? ' class="me"' : '') + '><b>' + esc(x.n) + '</b>' + (x.to && x.to !== c.n ? ' 回复 <b>' + esc(x.to) + '</b>' : '') + ':' + esc(x.t) + '</p>';
}).join('') + '</div>' : '') +
(c.me ? mineFoot(c) : '<button type="button" class="wcm-re" data-wrp="' + esc(c.key) + '">回复</button>') + '</div>' +
(c.me ? '<span class="wcm-lk me">' + HEART + '<span>' + fmt(likesOf(c)) + '</span></span></div>' :
@@ -263,6 +263,7 @@
method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body)
}).then(function (r) { return r.json(); }).then(function (j) {
if (!j || j.code !== 200 || !j.result) return (j && j.message) || '没发出去,再试一次';
if (j.result.status !== 'approved') return null; /* 审核中的不放进列表,通过后才显示 */
if (reply) { RREP.push(repOf(j.result, 1)); rerender(reply); }
else {
var o = realOf(j.result); o.n = '我'; o.me = 1; o.st = j.result.status;
@@ -278,11 +279,12 @@
var t = inp.value.trim();
if (t.length < 2) { toast('多写一两个字吧'); return; }
if (busy) return; busy = true; sendB.disabled = true;
var REPLY0 = REPLY;
post(t, +window.MB_WH_WEEK || 0, REPLY).then(function (msg) {
busy = false; sendB.disabled = false;
if (msg) { toast(msg); return; }
inp.value = ''; inp.blur(); setReply(null);
toast('发出去了,审核通过后大家就能看到');
toast(REPLY0 ? '回复已提交,审核通过后才会显示' : '已提交,审核通过后才会显示');
});
}
sendB.addEventListener('click', send);