v26110233 广场普通卡去话题;图上文字 30% 放顶部/中间;回复里「作者」拉开间距;自己的评论带孕周;我的收藏(首页「我的」入口 + 广场收藏层)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
deploy
2026-11-02 13:29:18 +00:00
parent 0a74cfc83f
commit 1e9b88896b
7 changed files with 127 additions and 30 deletions

View File

@@ -187,5 +187,5 @@
} }
/* feed.js 首页默认不加载(index.html 只引了 topics.js),这里按需拉一次 */ /* feed.js 首页默认不加载(index.html 只引了 topics.js),这里按需拉一次 */
if (window.GC_FEED) init(); if (window.GC_FEED) init();
else { var fs = document.createElement('script'); fs.src = 'guangchang/feed.js?v=26110232'; fs.onload = fs.onerror = init; document.body.appendChild(fs); } else { var fs = document.createElement('script'); fs.src = 'guangchang/feed.js?v=26110233'; fs.onload = fs.onerror = init; document.body.appendChild(fs); }
})(); })();

View File

@@ -325,8 +325,8 @@ mark{background:linear-gradient(transparent 62%,var(--c20) 0);color:inherit;padd
</div> </div>
<div class="toast" id="toast"></div> <div class="toast" id="toast"></div>
<script src="meta.js?v=26110232"></script> <script src="meta.js?v=26110233"></script>
<script src="tests.js?v=26110232"></script> <script src="tests.js?v=26110233"></script>
<script> <script>
(function () { (function () {
'use strict'; 'use strict';

View File

@@ -247,6 +247,19 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
.nc{display:block;width:100%;text-align:left;border-radius:14px;overflow:hidden;background:#fff;box-shadow:0 3px 12px rgba(170,110,90,.08);animation:ncIn .35s ease both} .nc{display:block;width:100%;text-align:left;border-radius:14px;overflow:hidden;background:#fff;box-shadow:0 3px 12px rgba(170,110,90,.08);animation:ncIn .35s ease both}
.nc:active{transform:scale(.985)} .nc:active{transform:scale(.985)}
/* 我的投稿入口卡(11-02 从右上角挪到「全部」瀑布流第一位,点进 mine/ 独立页) */ /* 我的投稿入口卡(11-02 从右上角挪到「全部」瀑布流第一位,点进 mine/ 独立页) */
.nc.fvc{display:flex;align-items:center;gap:8px;padding:11px 12px;border-radius:14px;background:#fff;color:var(--ink);font-size:13.5px;font-weight:900;text-align:left;box-shadow:0 4px 14px rgba(170,110,90,.08)}
.fvc .fi{width:30px;height:30px;flex:none;border-radius:10px;display:grid;place-items:center;background:#FFF4D6;color:#F2A20C}
.fvc .fi .ic{width:17px;height:17px;fill:currentColor;stroke:none}
.fvc span{flex:1;min-width:0}.fvc small{display:block;font-size:11px;font-weight:600;color:var(--muted)}
.fvc>.ic{width:14px;height:14px;color:#C9B6B0}
/* 我的收藏(11-02 用户:收藏了要有地方找 → 首页「我的」页入口 → ?fav=1 打开这一层;广场「全部」里我的投稿卡下面也有入口) */
#fvp{position:fixed;inset:0;z-index:35;background:var(--bg);transform:translateX(100%);transition:transform .32s cubic-bezier(.2,.8,.2,1);display:flex;flex-direction:column}
#fvp.show{transform:none}
#fvp .nav{flex:none;padding-top:env(safe-area-inset-top);height:calc(46px + env(safe-area-inset-top))}
#fvs{flex:1;overflow-y:auto;-webkit-overflow-scrolling:touch;overscroll-behavior:none;padding-bottom:calc(30px + env(safe-area-inset-bottom))}
#fvs .fvh{margin:4px 14px 0;font-size:12.5px;color:var(--muted)}
#fvs .fve{margin:40px 24px;text-align:center;color:var(--muted);font-size:13px;line-height:1.7}
#fvs .fve b{display:block;margin-bottom:4px;font-size:16px;color:var(--ink)}
.nc.myc{position:relative;padding:14px 12px 12px;color:#fff;background:linear-gradient(150deg,#FF8A65,#F0607E 70%,#D8609E);box-shadow:0 10px 20px -14px #E8506E} .nc.myc{position:relative;padding:14px 12px 12px;color:#fff;background:linear-gradient(150deg,#FF8A65,#F0607E 70%,#D8609E);box-shadow:0 10px 20px -14px #E8506E}
.nc.myc::after{content:"";position:absolute;right:-26px;top:-30px;width:96px;height:96px;border-radius:50%;background:rgba(255,255,255,.15)} .nc.myc::after{content:"";position:absolute;right:-26px;top:-30px;width:96px;height:96px;border-radius:50%;background:rgba(255,255,255,.15)}
.myc .mi{position:relative;width:38px;height:38px;border-radius:12px;display:grid;place-items:center;background:rgba(255,255,255,.22)} .myc .mi{position:relative;width:38px;height:38px;border-radius:12px;display:grid;place-items:center;background:rgba(255,255,255,.22)}
@@ -302,6 +315,10 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
.nc .tgt span{background:#FFF2A6;padding:1px 5px;-webkit-box-decoration-break:clone;box-decoration-break:clone;border-radius:3px} .nc .tgt span{background:#FFF2A6;padding:1px 5px;-webkit-box-decoration-break:clone;box-decoration-break:clone;border-radius:3px}
.nc:nth-child(odd) .tgt span{background:#fff} .nc:nth-child(odd) .tgt span{background:#fff}
.nc .ovt~*,.nc .tgt~*{display:none} .nc .ovt~*,.nc .tgt~*{display:none}
.nc .ovt.at-top{bottom:auto;top:0;padding:11px 11px 56px;background:linear-gradient(rgba(30,18,14,.72),rgba(30,18,14,.35) 70%,transparent)}
.nc .ovt.at-mid{bottom:auto;top:50%;transform:translateY(-50%);padding:16px 11px;background:rgba(30,18,14,.42)}
.nc .tgt.at-top{bottom:auto;top:12px}
.nc .tgt.at-mid{bottom:auto;top:50%;transform:translateY(-50%)}
.cm-ld{padding:22px 0;text-align:center;font-size:12.5px;color:#B8A39D} .cm-ld{padding:22px 0;text-align:center;font-size:12.5px;color:#B8A39D}
.nc.s-ov .nb .tp,.nc.s-tg .nb .tp{display:none} /* 11-02 用户:图上带字的卡,下方放一行标题、不放话题 */ .nc.s-ov .nb .tp,.nc.s-tg .nb .tp{display:none} /* 11-02 用户:图上带字的卡,下方放一行标题、不放话题 */
.nc.s-ov .nb h3,.nc.s-tg .nb h3{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;-webkit-line-clamp:unset} .nc.s-ov .nb h3,.nc.s-tg .nb h3{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;-webkit-line-clamp:unset}
@@ -391,7 +408,7 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
.ci-b{flex:1;min-width:0} .ci-b{flex:1;min-width:0}
.ci-n{display:flex;align-items:center;gap:6px;font-size:12.5px;color:var(--muted)} .ci-n{display:flex;align-items:center;gap:6px;font-size:12.5px;color:var(--muted)}
.ci-n b{color:#7A6A64;font-weight:700} .ci-n b{color:#7A6A64;font-weight:700}
.ci-n .au{height:16px;padding:0 5px;border-radius:4px;background:#F4593C;color:#fff;font-size:10px;font-weight:800;line-height:16px} .ci-n .au{height:16px;margin-left:3px;padding:0 5px;border-radius:4px;background:#F4593C;color:#fff;font-size:10px;font-weight:800;line-height:16px}
.ci-n .mt{height:16px;padding:0 5px;border-radius:4px;background:#FFE7E0;color:#EC4D33;font-size:10px;font-weight:800;line-height:16px} .ci-n .mt{height:16px;padding:0 5px;border-radius:4px;background:#FFE7E0;color:#EC4D33;font-size:10px;font-weight:800;line-height:16px}
.ci-n .lk{margin-left:auto} .ci-n .lk{margin-left:auto}
.ci-t{margin:3px 0 0;font-size:14.5px;line-height:1.65;color:#2F2624;word-break:break-word} .ci-t{margin:3px 0 0;font-size:14.5px;line-height:1.65;color:#2F2624;word-break:break-word}
@@ -400,7 +417,7 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
.rp p{margin:0 0 4px} .rp p{margin:0 0 4px}
.rp p:last-child{margin-bottom:0} .rp p:last-child{margin-bottom:0}
.rp b{font-weight:700;color:#7A6A64} .rp b{font-weight:700;color:#7A6A64}
.rp .au{display:inline-block;height:15px;margin:0 3px 0 -1px;padding:0 4px;border-radius:4px;background:#F4593C;color:#fff;font-size:9.5px;font-weight:800;line-height:15px;vertical-align:1px} .rp .au{display:inline-block;height:15px;margin:0 4px 0 7px;padding:0 4px;border-radius:4px;background:#F4593C;color:#fff;font-size:9.5px;font-weight:800;line-height:15px;vertical-align:1px}
.cm-end{padding:18px 0 6px;text-align:center;font-size:12px;color:#C9B7B1} .cm-end{padding:18px 0 6px;text-align:center;font-size:12px;color:#C9B7B1}
.bar{flex:none;display:flex;align-items:center;gap:6px;padding:8px 10px calc(8px + var(--safe-b)) 14px;background:#fff;border-top:1px solid var(--line)} .bar{flex:none;display:flex;align-items:center;gap:6px;padding:8px 10px calc(8px + var(--safe-b)) 14px;background:#fff;border-top:1px solid var(--line)}
@@ -517,6 +534,10 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
</div> </div>
</div> </div>
<div id="fvp" aria-hidden="true">
<div class="nav"><button class="bk" id="fvBack" type="button" aria-label="返回"><svg class="ic"><use href="#i-back"/></svg></button><h1><span>我的收藏</span></h1><i class="nsp"></i></div>
<div id="fvs"><div class="fvh" id="fvh"></div><div class="wf" id="fvw"><div class="col"></div><div class="col"></div></div></div>
</div>
<div id="dt" aria-hidden="true"> <div id="dt" aria-hidden="true">
<div class="dnav" id="dnav"> <div class="dnav" id="dnav">
<button class="bk" id="dback" type="button" aria-label="返回"><svg class="ic"><use href="#i-back"/></svg></button> <button class="bk" id="dback" type="button" aria-label="返回"><svg class="ic"><use href="#i-back"/></svg></button>
@@ -549,10 +570,10 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
<div id="sheet" role="dialog" aria-modal="true"><i class="sg"></i><div class="sbd" id="sbd"></div></div> <div id="sheet" role="dialog" aria-modal="true"><i class="sg"></i><div class="sbd" id="sbd"></div></div>
<div class="toast" id="toast"></div> <div class="toast" id="toast"></div>
<script src="topics.js?v=26110232"></script> <script src="topics.js?v=26110233"></script>
<script src="data.js?v=26110232"></script> <script src="data.js?v=26110233"></script>
<script src="feed.js?v=26110232"></script> <script src="feed.js?v=26110233"></script>
<script src="ceshi/meta.js?v=26110232"></script> <script src="ceshi/meta.js?v=26110233"></script>
<script> <script>
(function () { (function () {
'use strict'; 'use strict';
@@ -617,7 +638,7 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
模拟内容,见 AGENTS.md 12c;文件较大,进页面后后台拉,详情页先显示「评论加载中」 */ 模拟内容,见 AGENTS.md 12c;文件较大,进页面后后台拉,详情页先显示「评论加载中」 */
var CMD = null, CMERR = false; var CMD = null, CMERR = false;
var avP = function (a) { return typeof a === 'number' ? 'av/' + ('000' + a).slice(-4) + '.webp' : '../assets/img/mom/' + a + '.jpg'; }; var avP = function (a) { return typeof a === 'number' ? 'av/' + ('000' + a).slice(-4) + '.webp' : '../assets/img/mom/' + a + '.jpg'; };
fetch('cm.json?v=26110232').then(function (r) { return r.json(); }).then(function (j) { fetch('cm.json?v=26110233').then(function (r) { return r.json(); }).then(function (j) {
CMD = j; if (openId && NBY[openId]) { renderComments(NBY[openId]); syncBar(NBY[openId]); } CMD = j; if (openId && NBY[openId]) { renderComments(NBY[openId]); syncBar(NBY[openId]); }
}).catch(function () { CMERR = true; if (openId && NBY[openId]) renderComments(NBY[openId]); }); }).catch(function () { CMERR = true; if (openId && NBY[openId]) renderComments(NBY[openId]); });
function commentsOf(n) { function commentsOf(n) {
@@ -675,12 +696,15 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
function cardHTML(n, showTopic, sty) { function cardHTML(n, showTopic, sty) {
var t = TBY[n.t], r = n.ratio, ov = ''; var t = TBY[n.t], r = n.ratio, ov = '';
if (!n.photo) sty = ''; if (!n.photo) sty = '';
/* 11-02 用户:图上放的短语「不知所云」→ 图上直接放完整标题;卡片下方再放一行标题(单行省略)、不放话题 */ /* 11-02 用户:图上放的短语「不知所云」→ 图上直接放完整标题;卡片下方再放一行标题(单行省略)、不放话题。
if (sty === 'ov') { r = Math.max(r, 1.33); ov = '<div class="ovt">' + (n.stage ? '<small>' + esc(n.stage) + '</small>' : '') + '<b>' + esc(n.title) + '</b></div>'; } 11-02 二改:普通卡(图上没字)也不放话题;图上文字 70% 在底部,30% 放顶部/中间(按帖子 id 哈希固定,刷新不跳) */
else if (sty === 'tg') { r = Math.max(r, 1.2); ov = '<div class="tgt"><b><span>' + esc(n.title) + '</span></b></div>'; } var ph = 0; for (var q = 0; q < n.id.length; q++) ph = (ph * 31 + n.id.charCodeAt(q)) >>> 0;
var pos = ph % 10 < 7 ? '' : ph % 10 < 9 ? ' at-mid' : ' at-top';
if (sty === 'ov') { r = Math.max(r, 1.33); ov = '<div class="ovt' + pos + '">' + (n.stage ? '<small>' + esc(n.stage) + '</small>' : '') + '<b>' + esc(n.title) + '</b></div>'; }
else if (sty === 'tg') { r = Math.max(r, 1.2); ov = '<div class="tgt' + pos + '"><b><span>' + esc(n.title) + '</span></b></div>'; }
return '<button type="button" class="nc' + (sty ? ' s-' + sty : '') + '" data-id="' + n.id + '"><div class="cvw">' + return '<button type="button" class="nc' + (sty ? ' s-' + sty : '') + '" data-id="' + n.id + '"><div class="cvw">' +
coverHTML(n, 'calc(var(--cw) * ' + r + ')') + ov + '</div>' + coverHTML(n, 'calc(var(--cw) * ' + r + ')') + ov + '</div>' +
'<div class="nb"><h3>' + esc(n.title) + '</h3>' + (showTopic ? '<span class="tp k-' + t.cat + '">#' + esc(t.name) + '#</span>' : '') + '<div class="nf"><img src="' + esc(avOf(n)) + '" alt="" loading="lazy"><span class="nm">' + esc(n.author) + '</span>' + likeHTML(n) + '</div></div></button>'; '<div class="nb"><h3>' + esc(n.title) + '</h3><div class="nf"><img src="' + esc(avOf(n)) + '" alt="" loading="lazy"><span class="nm">' + esc(n.author) + '</span>' + likeHTML(n) + '</div></div></button>';
} }
/* ---------- 列表 ---------- */ /* ---------- 列表 ---------- */
@@ -751,7 +775,7 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
var CS_MIX = ['t11', 't29', 't01', 't24', 't26', 't16', 't03', 't27', 't14', 't21', 't30', 't18']; var CS_MIX = ['t11', 't29', 't01', 't24', 't26', 't16', 't03', 't27', 't14', 't21', 't30', 't18'];
function csDone() { try { return (JSON.parse(localStorage.getItem('mmbox.gcts.v1') || '{}')[param('openid') || '_guest']) || {}; } catch (e) { return {}; } } function csDone() { try { return (JSON.parse(localStorage.getItem('mmbox.gcts.v1') || '{}')[param('openid') || '_guest']) || {}; } catch (e) { return {}; } }
function ceshiURL(id, fromTab) { function ceshiURL(id, fromTab) {
var q = new URLSearchParams(location.search); ['t', 'n', 'c', 'id', 'mine', 'write'].forEach(function (k) { q.delete(k); }); var q = new URLSearchParams(location.search); ['t', 'n', 'c', 'id', 'mine', 'write', 'fav'].forEach(function (k) { q.delete(k); });
if (fromTab) q.set('c', 'ceshi'); if (fromTab) q.set('c', 'ceshi');
q.set('id', id); q.set('id', id);
return 'ceshi/?' + q.toString() + location.hash; return 'ceshi/?' + q.toString() + location.hash;
@@ -878,6 +902,8 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
if (n.mine) { if (n.mine) {
tmp.innerHTML = myCardHTML(); var me = tmp.firstChild; tmp.innerHTML = myCardHTML(); var me = tmp.firstChild;
cols[0].appendChild(me); hs[0] += me.offsetHeight + 8; cols[0].appendChild(me); hs[0] += me.offsetHeight + 8;
tmp.innerHTML = favCardHTML(); var fe = tmp.firstChild;
cols[0].appendChild(fe); hs[0] += fe.offsetHeight + 8;
return; return;
} }
if (n.test) { if (n.test) {
@@ -906,7 +932,7 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
if (t) q.set('t', t); else q.delete('t'); if (t) q.set('t', t); else q.delete('t');
if (!t && catF) q.set('c', catF); else q.delete('c'); /* 只选了分类没选话题时记在 ?c=,刷新 / 详情返回还在原分类 */ if (!t && catF) q.set('c', catF); else q.delete('c'); /* 只选了分类没选话题时记在 ?c=,刷新 / 详情返回还在原分类 */
if (n) q.set('n', n); else q.delete('n'); if (n) q.set('n', n); else q.delete('n');
q.delete('mine'); q.delete('write'); q.delete('mine'); q.delete('write'); q.delete('fav');
var s = q.toString(); var s = q.toString();
return location.pathname + (s ? '?' + s : '') + location.hash; /* hash(身份)原样保留 */ return location.pathname + (s ? '?' + s : '') + location.hash; /* hash(身份)原样保留 */
} }
@@ -1069,6 +1095,7 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
}, true); }, true);
$('#wf').addEventListener('click', function (e) { $('#wf').addEventListener('click', function (e) {
if (e.target.closest('[data-mine]')) { haptic(); location.href = mineURL(); return; } if (e.target.closest('[data-mine]')) { haptic(); location.href = mineURL(); return; }
if (e.target.closest('[data-fav]')) { haptic(); openFav(false); return; }
var ts = e.target.closest('[data-test]'); var ts = e.target.closest('[data-test]');
if (ts) { haptic(); location.href = ceshiURL(ts.dataset.test, catF === 'ceshi'); return; } if (ts) { haptic(); location.href = ceshiURL(ts.dataset.test, catF === 'ceshi'); return; }
var lk = e.target.closest('[data-like]'); var lk = e.target.closest('[data-like]');
@@ -1085,10 +1112,15 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
return /^\d{1,2}[.、.]\s*/.test(p) ? '<p class="li">' + esc(p) + '</p>' : '<p>' + esc(p) + '</p>'; return /^\d{1,2}[.、.]\s*/.test(p) ? '<p class="li">' + esc(p) + '</p>' : '<p>' + esc(p) + '</p>';
}).join(''); }).join('');
} }
/* 11-02 用户:自己发的评论也带上孕周(首页写进 mmbox.gcwk.v1;产后显示「宝妈」) */
function myStage() {
try { var g = JSON.parse(localStorage.getItem('mmbox.gcwk.v1') || 'null'); return !g ? '' : g.pp ? '宝妈' : g.w ? '孕 ' + g.w + ' 周' : ''; } catch (e) { return ''; }
}
function commentHTML(c, mine) { function commentHTML(c, mine) {
if (mine) { if (mine) {
var st = c.s || myStage();
return '<div class="ci mine"><span class="me">我</span><div class="ci-b"><div class="ci-n"><b>' + esc(MYNAME) + '</b><span class="mt">我</span></div>' + return '<div class="ci mine"><span class="me">我</span><div class="ci-b"><div class="ci-n"><b>' + esc(MYNAME) + '</b><span class="mt">我</span></div>' +
'<p class="ci-t">' + esc(c.t) + '</p></div></div>'; /* 11-02 自己的评论也不显示时间 */ '<p class="ci-t">' + esc(c.t) + '</p>' + (st ? '<div class="ci-s">' + esc(st) + '</div>' : '') + '</div></div>'; /* 11-02 自己的评论也不显示时间 */
} }
var on = !!ME.cl[c.key], n = c.likes + (on ? 1 : 0); var on = !!ME.cl[c.key], n = c.likes + (on ? 1 : 0);
var rp = c.r.length ? '<div class="rp">' + c.r.map(function (x) { return '<p><b>' + esc(x.n) + '</b>' + (x.au ? '<span class="au">作者</span>' : '') + ':' + esc(x.t) + '</p>'; }).join('') + '</div>' : ''; var rp = c.r.length ? '<div class="rp">' + c.r.map(function (x) { return '<p><b>' + esc(x.n) + '</b>' + (x.au ? '<span class="au">作者</span>' : '') + ':' + esc(x.t) + '</p>'; }).join('') + '</div>' : '';
@@ -1148,6 +1180,7 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
$('#cin').blur(); $('#cin').blur();
var id = openId; openId = ''; var id = openId; openId = '';
if (id) syncCardLike(id); if (id) syncCardLike(id);
if (fvOn) renderFav(); /* 详情里取消了收藏,回到收藏页要立刻消失 */
} }
function closeNote() { function closeNote() {
if (!openId) return; if (!openId) return;
@@ -1189,7 +1222,7 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
}); });
$('#bfv').addEventListener('click', function () { $('#bfv').addEventListener('click', function () {
var n = NBY[openId]; if (!n) return; var n = NBY[openId]; if (!n) return;
if (ME.fav[n.id]) delete ME.fav[n.id]; else ME.fav[n.id] = 1; if (ME.fav[n.id]) delete ME.fav[n.id]; else ME.fav[n.id] = Date.now(); /* 存收藏时间,「我的收藏」按它倒序 */
save(); haptic(); syncBar(n, ME.fav[n.id] ? 'fv' : ''); save(); haptic(); syncBar(n, ME.fav[n.id] ? 'fv' : '');
toast(ME.fav[n.id] ? '已收藏,在这台手机上随时能找到' : '已取消收藏'); toast(ME.fav[n.id] ? '已收藏,在这台手机上随时能找到' : '已取消收藏');
}); });
@@ -1205,7 +1238,7 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
function send() { function send() {
var n = NBY[openId], v = cin.value.trim(); var n = NBY[openId], v = cin.value.trim();
if (!n || !v) return; if (!n || !v) return;
(ME.cm[n.id] = myCm(n.id)).push({ t: v.slice(0, 200), ts: Date.now() }); (ME.cm[n.id] = myCm(n.id)).push({ t: v.slice(0, 200), ts: Date.now(), s: myStage() });
save(); haptic(); save(); haptic();
cin.value = ''; $('#csend').disabled = true; cin.blur(); $('#bar').classList.remove('typing'); cin.value = ''; $('#csend').disabled = true; cin.blur(); $('#bar').classList.remove('typing');
renderComments(n); syncBar(n); renderComments(n); syncBar(n);
@@ -1258,6 +1291,43 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
: '<p>写下你的故事,被选中得 <em>¥30</em> + <em>500</em> 兜豆</p>') + : '<p>写下你的故事,被选中得 <em>¥30</em> + <em>500</em> 兜豆</p>') +
'<span class="go">' + (MINE.length ? '查看全部' : '去看看') + '<svg class="ic"><use href="#i-right"/></svg></span></button>'; '<span class="go">' + (MINE.length ? '查看全部' : '去看看') + '<svg class="ic"><use href="#i-right"/></svg></span></button>';
} }
function favIds() {
return Object.keys(ME.fav).filter(function (id) { return NBY[id]; }).sort(function (a, b) { return (+ME.fav[b] || 0) - (+ME.fav[a] || 0); });
}
function favCardHTML() {
var k = favIds().length;
return '<button type="button" class="nc fvc" id="fvc" data-fav="1"><i class="fi"><svg class="ic"><use href="#i-star-f"/></svg></i><span>我的收藏<small>' + (k ? '已收藏 ' + k + ' 篇' : '看到喜欢的点 ☆ 收藏') + '</small></span><svg class="ic"><use href="#i-right"/></svg></button>';
}
var fvOn = false, fvDeep = false;
function renderFav() {
var ids = favIds(), cols = $('#fvw').children, hs = [0, 0], tmp = document.createElement('div');
cols[0].innerHTML = ''; cols[1].innerHTML = '';
$('#fvh').textContent = ids.length ? '共 ' + ids.length + ' 篇 · 只保存在这台手机上' : '';
var em = $('#fvs .fve'); if (em) em.remove();
if (!ids.length) { $('#fvw').insertAdjacentHTML('beforebegin', '<div class="fve"><b>还没有收藏</b>看到有用的帖子,点底部的 ☆ 就能收藏到这里</div>'); return; }
$('#fvw').style.setProperty('--cw', (cols[0].clientWidth || 175) + 'px');
ids.forEach(function (id, k) {
tmp.innerHTML = cardHTML(NBY[id], false, ''); var el = tmp.firstChild; el.style.animationDelay = Math.min(k, 10) * 30 + 'ms';
var c = hs[0] <= hs[1] ? 0 : 1; cols[c].appendChild(el); hs[c] += el.offsetHeight + 8;
});
}
function openFav(deep) {
fvOn = true; fvDeep = !!deep;
var p = $('#fvp'); p.classList.add('show'); p.setAttribute('aria-hidden', 'false'); $('#fvs').scrollTop = 0;
renderFav();
}
function closeFav() {
/* 从首页「我的 → 我的收藏」直接进来的,返回就回首页 */
if (fvDeep && history.length > 1 && document.referrer && document.referrer.indexOf('/guangchang/') < 0) { history.back(); return; }
fvOn = false; var p = $('#fvp'); p.classList.remove('show'); p.setAttribute('aria-hidden', 'true');
var c = $('#fvc'); if (c) c.outerHTML = favCardHTML();
history.replaceState(history.state, '', setQuery(cur, ''));
}
$('#fvBack').addEventListener('click', closeFav);
$('#fvw').addEventListener('click', function (e) {
var lk = e.target.closest('[data-like]'); if (lk) { toggleLike(lk.dataset.like); syncCardLike(lk.dataset.like); return; }
var c = e.target.closest('[data-id]'); if (c) { haptic(); openNote(c.dataset.id, true); }
});
function syncMyCard() { var c = $('#myc'); if (c) { c.outerHTML = myCardHTML(); } } function syncMyCard() { var c = $('#myc'); if (c) { c.outerHTML = myCardHTML(); } }
function loadMine(cb) { function loadMine(cb) {
if (!OPENID) return; if (!OPENID) return;
@@ -1433,6 +1503,7 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
selectTopic(param('t') && TBY[param('t')] ? param('t') : '', false); selectTopic(param('t') && TBY[param('t')] ? param('t') : '', false);
if (deep && NBY[deep]) openNote(deep, false); if (deep && NBY[deep]) openNote(deep, false);
loadApproved(); loadApproved();
if (q0.get('fav') === '1') openFav(true); /* 首页「我的 → 我的收藏」 */
if (q0.get('mine') === '1') location.href = mineURL(); /* 首页审核提醒 ?mine=1 → 我的投稿页(selectTopic 已把 mine 从地址里去掉,返回不会再跳) */ if (q0.get('mine') === '1') location.href = mineURL(); /* 首页审核提醒 ?mine=1 → 我的投稿页(selectTopic 已把 mine 从地址里去掉,返回不会再跳) */
else if (q0.get('write') === '1') { loadMine(function () {}); openCompose(q0.get('t') || ''); } /* 我的投稿页「写新的故事 / 修改后重投」:结果在那页已看过,不再弹 */ else if (q0.get('write') === '1') { loadMine(function () {}); openCompose(q0.get('t') || ''); } /* 我的投稿页「写新的故事 / 修改后重投」:结果在那页已看过,不再弹 */
else loadMine(); /* 我的投稿页「写新的故事 / 修改后重投」 */ else loadMine(); /* 我的投稿页「写新的故事 / 修改后重投」 */

View File

@@ -105,7 +105,7 @@ main{padding:6px 16px 0}
</div> </div>
<div class="wb"><button type="button" id="write"><svg class="ic" viewBox="0 0 24 24"><path d="M12 20h9M16.5 3.5a2.1 2.1 0 013 3L7 19l-4 1 1-4z"/></svg>写新的故事</button></div> <div class="wb"><button type="button" id="write"><svg class="ic" viewBox="0 0 24 24"><path d="M12 20h9M16.5 3.5a2.1 2.1 0 013 3L7 19l-4 1 1-4z"/></svg>写新的故事</button></div>
<script src="../topics.js?v=26110232"></script> <script src="../topics.js?v=26110233"></script>
<script> <script>
(function () { (function () {
'use strict'; 'use strict';

View File

@@ -7,7 +7,7 @@
<meta name="mobile-web-app-capable" content="yes"> <meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-capable" content="yes">
<title>兜爸心选 · 孕育陪伴</title> <title>兜爸心选 · 孕育陪伴</title>
<!-- V:26110232 缓存版本标记:改 css/js 时同步 bump 该值(与 js/app.js 的 VER 同源),静态资源按 mtime 走 ETag 自动刷新 --> <!-- V:26110233 缓存版本标记:改 css/js 时同步 bump 该值(与 js/app.js 的 VER 同源),静态资源按 mtime 走 ETag 自动刷新 -->
<link rel="stylesheet" href="mama-box.css"> <link rel="stylesheet" href="mama-box.css">
<link rel="stylesheet" href="night.css"> <link rel="stylesheet" href="night.css">
<!-- 夜晚模式:首屏绘制前就按上次的选择加 class,避免先白后黑闪一下(开关在首页右上角 #nightBtn,逻辑见 app.js) --> <!-- 夜晚模式:首屏绘制前就按上次的选择加 class,避免先白后黑闪一下(开关在首页右上角 #nightBtn,逻辑见 app.js) -->
@@ -1378,6 +1378,16 @@
</button> </button>
</div> </div>
<!-- 11-02 用户:孕妈广场点了收藏,要在「我的」页给收藏入口 → 广场 ?fav=1 打开「我的收藏」层;数字读本机 mmbox.gc.v1(收藏只存本机) -->
<div class="list-card" style="margin-top:14px">
<button class="li ripple" id="meFavCard">
<span class="li-ico y"><svg viewBox="0 0 24 24" width="19" height="19" aria-hidden="true"><path d="M12 3.6l2.6 5.3 5.8.8-4.2 4.1 1 5.8L12 16.9l-5.2 2.7 1-5.8-4.2-4.1 5.8-.8z" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/></svg></span>
<span class="li-t">我的收藏</span>
<span class="li-v" id="meFavN">孕妈广场里收藏的帖子</span>
<i class="chev">›</i>
</button>
</div>
<!-- 兜豆兑换:2026-10-04 用户要求「收起来,不要这么大地展示」—— 原来的大卡(标题+热门 3 件好物)收成一条横条, <!-- 兜豆兑换:2026-10-04 用户要求「收起来,不要这么大地展示」—— 原来的大卡(标题+热门 3 件好物)收成一条横条,
和下面「兜爸心选商城」同款。#meExchCard / #meExchSub 不变(openExchange、loadDou 照旧); 和下面「兜爸心选商城」同款。#meExchCard / #meExchSub 不变(openExchange、loadDou 照旧);
#meExchDrop 已删,renderDrop() 里有 if (box) 判空,不用改 JS。 --> #meExchDrop 已删,renderDrop() 里有 if (box) 判空,不用改 JS。 -->
@@ -2514,7 +2524,7 @@
<script src="/_bridge/avatar-picker.js?v=26101105"></script> <script src="/_bridge/avatar-picker.js?v=26101105"></script>
<script src="/_bridge/hand-icons.js?v=26101202"></script> <script src="/_bridge/hand-icons.js?v=26101202"></script>
<script src="js/zodiac-art.js"></script> <script src="js/zodiac-art.js"></script>
<script src="guangchang/topics.js?v=26110232"></script> <script src="guangchang/topics.js?v=26110233"></script>
<script src="js/app.js"></script> <script src="js/app.js"></script>
<script> <script>
/* 11-02 首页「孕妈广场」效果稿:地址带 ?gcv=1~6 时,把 #gcHome 换成 demo/gch/vN.css + vN.js 的版式并滚到这一块。 /* 11-02 首页「孕妈广场」效果稿:地址带 ?gcv=1~6 时,把 #gcHome 换成 demo/gch/vN.css + vN.js 的版式并滚到这一块。
@@ -2522,7 +2532,7 @@
(function () { (function () {
var m = location.search.match(/[?&]gcv=([1-6])(?:&|$)/); var m = location.search.match(/[?&]gcv=([1-6])(?:&|$)/);
if (!m) window.__gcDefault = 1; if (!m) window.__gcDefault = 1;
var n = m ? m[1] : '6', l = document.createElement('link'), s = document.createElement('script'), q = m ? Date.now() : 'v=26110232'; var n = m ? m[1] : '6', l = document.createElement('link'), s = document.createElement('script'), q = m ? Date.now() : 'v=26110233';
l.rel = 'stylesheet'; l.href = 'demo/gch/v' + n + '.css?' + q; l.rel = 'stylesheet'; l.href = 'demo/gch/v' + n + '.css?' + q;
s.src = 'demo/gch/v' + n + '.js?' + q; s.src = 'demo/gch/v' + n + '.js?' + q;
if (m) s.onload = function () { setTimeout(function () { var el = document.getElementById('gcHome'); if (el) el.scrollIntoView({ block: 'center' }); }, 900); }; if (m) s.onload = function () { setTimeout(function () { var el = document.getElementById('gcHome'); if (el) el.scrollIntoView({ block: 'center' }); }, 900); };
@@ -2530,7 +2540,7 @@
/* 11-02 品牌露出(用户定 4 处都要):默认加载,?brand=0 可关掉对比;⚠️ 上正式前和 V6 一起并进正式代码,别依赖 demo/ */ /* 11-02 品牌露出(用户定 4 处都要):默认加载,?brand=0 可关掉对比;⚠️ 上正式前和 V6 一起并进正式代码,别依赖 demo/ */
if (!/[?&]brand=0/.test(location.search)) { if (!/[?&]brand=0/.test(location.search)) {
var bl = document.createElement('link'), bs = document.createElement('script'); var bl = document.createElement('link'), bs = document.createElement('script');
bl.rel = 'stylesheet'; bl.href = 'demo/brand/brand.css?v=26110232'; bs.src = 'demo/brand/brand.js?v=26110232'; bl.rel = 'stylesheet'; bl.href = 'demo/brand/brand.css?v=26110233'; bs.src = 'demo/brand/brand.js?v=26110233';
document.head.appendChild(bl); document.body.appendChild(bs); document.head.appendChild(bl); document.body.appendChild(bs);
} }
})(); })();

View File

@@ -3,7 +3,7 @@
(function () { (function () {
'use strict'; 'use strict';
/* 页面版本号(YYMMDD+序号):显示在「关于兜爸心选」页底部;bump 时同步 head 注释与 ?v= */ /* 页面版本号(YYMMDD+序号):显示在「关于兜爸心选」页底部;bump 时同步 head 注释与 ?v= */
var VER = '26110232'; var VER = '26110233';
const $ = (s, c) => (c || document).querySelector(s); const $ = (s, c) => (c || document).querySelector(s);
const $$ = (s, c) => Array.from((c || document).querySelectorAll(s)); const $$ = (s, c) => Array.from((c || document).querySelectorAll(s));
@@ -6471,6 +6471,20 @@
toast('请在小程序中完成授权登录'); toast('请在小程序中完成授权登录');
} }
} }
/* 11-02 「我的」→ 我的收藏:进孕妈广场的收藏层(guangchang/?fav=1),条数读本机 mmbox.gc.v1[openid].fav */
(function () {
const card = $('#meFavCard'); if (!card) return;
const cnt = () => {
try { const a = JSON.parse(localStorage.getItem('mmbox.gc.v1') || '{}'), me = a[hashParam('openid') || '_guest'] || {}; const k = Object.keys(me.fav || {}).length; $('#meFavN').textContent = k ? '已收藏 ' + k + ' 篇' : '孕妈广场里收藏的帖子'; } catch (e) {}
};
cnt(); window.addEventListener('pageshow', cnt);
card.addEventListener('click', () => {
haptic();
const url = 'guangchang/?fav=1' + location.hash;
reportHostLocation(new URL(url, location.href).href);
location.href = url;
});
})();
var meAuth = $('#meAuthCard'); var meAuth = $('#meAuthCard');
if (meAuth) meAuth.addEventListener('click', goAuth); if (meAuth) meAuth.addEventListener('click', goAuth);
/* 方案A:未授权时点「我的」页顶部资料卡 → 直接去授权,不打开资料弹窗(捕获阶段拦在 data-modal 之前) */ /* 方案A:未授权时点「我的」页顶部资料卡 → 直接去授权,不打开资料弹窗(捕获阶段拦在 data-modal 之前) */

View File

@@ -51,13 +51,15 @@
var SK = 'mmbox.tp.v1', UK = (function () { var m = ((location.hash || '') + '&' + (location.search || '')).match(/[#?&]openid=([^&]*)/); return m ? decodeURIComponent(m[1]) : '_guest'; })(); var SK = 'mmbox.tp.v1', UK = (function () { var m = ((location.hash || '') + '&' + (location.search || '')).match(/[#?&]openid=([^&]*)/); return m ? decodeURIComponent(m[1]) : '_guest'; })();
function loadMe() { try { var a = JSON.parse(localStorage.getItem(SK) || '{}') || {}; var m = a[UK] || {}; m.cm = m.cm || {}; m.lk = m.lk || {}; return { a: a, m: m }; } catch (e) { return { a: {}, m: { cm: {}, lk: {} } }; } } function loadMe() { try { var a = JSON.parse(localStorage.getItem(SK) || '{}') || {}; var m = a[UK] || {}; m.cm = m.cm || {}; m.lk = m.lk || {}; return { a: a, m: m }; } catch (e) { return { a: {}, m: { cm: {}, lk: {} } }; } }
function saveMe(st) { try { st.a[UK] = st.m; localStorage.setItem(SK, JSON.stringify(st.a)); } catch (e) {} } function saveMe(st) { try { st.a[UK] = st.m; localStorage.setItem(SK, JSON.stringify(st.a)); } catch (e) {} }
/* 11-02 用户:自己发的评论带上孕周(首页写进 mmbox.gcwk.v1) */
function myStage() { try { var g = JSON.parse(localStorage.getItem('mmbox.gcwk.v1') || 'null'); return !g ? '' : g.pp ? '宝妈' : g.w ? '孕 ' + g.w + ' 周' : ''; } catch (e) { return ''; } }
function avP(a) { return typeof a === 'number' ? '../../guangchang/av/' + ('000' + a).slice(-4) + '.webp' : '../../assets/img/mom/' + a + '.jpg'; } function avP(a) { return typeof a === 'number' ? '../../guangchang/av/' + ('000' + a).slice(-4) + '.webp' : '../../assets/img/mom/' + a + '.jpg'; }
function wan(n) { return n >= 1e4 ? (Math.round(n / 1e3) / 10) + '万' : String(n); } function wan(n) { return n >= 1e4 ? (Math.round(n / 1e3) / 10) + '万' : String(n); }
var HEART = '<svg viewBox="0 0 24 24"><path d="M12 20s-7-4.4-7-10a4 4 0 017-2.6A4 4 0 0119 10c0 5.6-7 10-7 10z"/></svg>'; var HEART = '<svg viewBox="0 0 24 24"><path d="M12 20s-7-4.4-7-10a4 4 0 017-2.6A4 4 0 0119 10c0 5.6-7 10-7 10z"/></svg>';
function getJSON(u) { return fetch(u, { cache: 'no-cache' }).then(function (r) { if (!r.ok) throw r.status; return r.json(); }); } function getJSON(u) { return fetch(u, { cache: 'no-cache' }).then(function (r) { if (!r.ok) throw r.status; return r.json(); }); }
function related(box) { function related(box) {
getJSON('../_shared/idx.json?v=26110232').then(function (idx) { getJSON('../_shared/idx.json?v=26110233').then(function (idx) {
var me = null; idx.forEach(function (x) { if (x[0] === SLUG) me = x; }); var me = null; idx.forEach(function (x) { if (x[0] === SLUG) me = x; });
var tag = me ? me[2] : '', h = 0; for (var i = 0; i < SLUG.length; i++) h = (h * 31 + SLUG.charCodeAt(i)) >>> 0; var tag = me ? me[2] : '', h = 0; for (var i = 0; i < SLUG.length; i++) h = (h * 31 + SLUG.charCodeAt(i)) >>> 0;
var rest = idx.filter(function (x) { return x[0] !== SLUG; }); var rest = idx.filter(function (x) { return x[0] !== SLUG; });
@@ -79,7 +81,7 @@
function item(c, key) { function item(c, key) {
var lk = !!st.m.lk[key]; var lk = !!st.m.lk[key];
return '<div class="tc-it">' + (c.me ? '<span class="tc-av tc-me">我</span>' : '<img class="tc-av" src="' + esc(avP(c[1])) + '" alt="" loading="lazy">') + return '<div class="tc-it">' + (c.me ? '<span class="tc-av tc-me">我</span>' : '<img class="tc-av" src="' + esc(avP(c[1])) + '" alt="" loading="lazy">') +
'<div class="tc-b"><div class="tc-n"><b>' + esc(c.me ? '我' : c[0]) + '</b>' + (c.me ? '<i>刚刚</i>' : (c[2] ? '<i>' + esc(c[2]) + '</i>' : '')) + '</div>' + '<div class="tc-b"><div class="tc-n"><b>' + esc(c.me ? '我' : c[0]) + '</b>' + (c.me ? '<i>' + esc(c.s || myStage() || '刚刚') + '</i>' : (c[2] ? '<i>' + esc(c[2]) + '</i>' : '')) + '</div>' +
'<div class="tc-t">' + esc(c.me ? c.t : c[3]) + '</div>' + '<div class="tc-t">' + esc(c.me ? c.t : c[3]) + '</div>' +
(!c.me && c[5] && c[5].length ? '<div class="tc-r">' + c[5].map(function (r) { return '<p><b>' + esc(r[0]) + ':</b>' + esc(r[3]) + '</p>'; }).join('') + '</div>' : '') + (!c.me && c[5] && c[5].length ? '<div class="tc-r">' + c[5].map(function (r) { return '<p><b>' + esc(r[0]) + ':</b>' + esc(r[3]) + '</p>'; }).join('') + '</div>' : '') +
'<div class="tc-f"><button type="button" class="tc-lk' + (lk ? ' on' : '') + '" data-k="' + esc(key) + '">' + HEART + '<span>' + ((c.me ? 0 : c[4]) + (lk ? 1 : 0) || '赞') + '</span></button></div></div></div>'; '<div class="tc-f"><button type="button" class="tc-lk' + (lk ? ' on' : '') + '" data-k="' + esc(key) + '">' + HEART + '<span>' + ((c.me ? 0 : c[4]) + (lk ? 1 : 0) || '赞') + '</span></button></div></div></div>';
@@ -88,21 +90,21 @@
var my = mine().slice().reverse(), n = L.length + my.length, show = open ? L : L.slice(0, 5); var my = mine().slice().reverse(), n = L.length + my.length, show = open ? L : L.slice(0, 5);
box.innerHTML = '<div class="tt-h"><b>大家怎么说</b><span>' + n + ' 条评论</span></div>' + box.innerHTML = '<div class="tt-h"><b>大家怎么说</b><span>' + n + ' 条评论</span></div>' +
'<div class="tc-in"><textarea rows="1" maxlength="200" placeholder="说说你的情况,和其他妈妈聊聊…"></textarea><button type="button" disabled>发布</button></div>' + '<div class="tc-in"><textarea rows="1" maxlength="200" placeholder="说说你的情况,和其他妈妈聊聊…"></textarea><button type="button" disabled>发布</button></div>' +
'<div class="tc-list">' + my.map(function (c, i) { return item({ me: 1, t: c.t }, 'me' + c.ts); }).join('') + '<div class="tc-list">' + my.map(function (c, i) { return item({ me: 1, t: c.t, s: c.s }, 'me' + c.ts); }).join('') +
show.map(function (c, i) { return item(c, SLUG + '#' + i); }).join('') + '</div>' + show.map(function (c, i) { return item(c, SLUG + '#' + i); }).join('') + '</div>' +
(!open && L.length > 5 ? '<button type="button" class="tc-more">展开全部 ' + n + ' 条评论</button>' : ''); (!open && L.length > 5 ? '<button type="button" class="tc-more">展开全部 ' + n + ' 条评论</button>' : '');
var ta = box.querySelector('textarea'), bt = box.querySelector('.tc-in button'); var ta = box.querySelector('textarea'), bt = box.querySelector('.tc-in button');
ta.addEventListener('input', function () { bt.disabled = !ta.value.trim(); ta.style.height = '24px'; ta.style.height = Math.min(96, ta.scrollHeight) + 'px'; }); ta.addEventListener('input', function () { bt.disabled = !ta.value.trim(); ta.style.height = '24px'; ta.style.height = Math.min(96, ta.scrollHeight) + 'px'; });
bt.addEventListener('click', function () { bt.addEventListener('click', function () {
var v = ta.value.trim(); if (!v) return; var v = ta.value.trim(); if (!v) return;
(st.m.cm[SLUG] = mine()).push({ t: v.slice(0, 200), ts: Date.now() }); saveMe(st); paint(); (st.m.cm[SLUG] = mine()).push({ t: v.slice(0, 200), ts: Date.now(), s: myStage() }); saveMe(st); paint();
}); });
var mo = box.querySelector('.tc-more'); if (mo) mo.addEventListener('click', function () { open = true; paint(); }); var mo = box.querySelector('.tc-more'); if (mo) mo.addEventListener('click', function () { open = true; paint(); });
[].forEach.call(box.querySelectorAll('.tc-lk'), function (b) { [].forEach.call(box.querySelectorAll('.tc-lk'), function (b) {
b.addEventListener('click', function () { var k = b.dataset.k; if (st.m.lk[k]) delete st.m.lk[k]; else st.m.lk[k] = 1; saveMe(st); paint(); }); b.addEventListener('click', function () { var k = b.dataset.k; if (st.m.lk[k]) delete st.m.lk[k]; else st.m.lk[k] = 1; saveMe(st); paint(); });
}); });
} }
getJSON('../_shared/cm/' + SLUG + '.json?v=26110232').then(function (d) { L = d.c || []; paint(); }).catch(function () { paint(); }); getJSON('../_shared/cm/' + SLUG + '.json?v=26110233').then(function (d) { L = d.c || []; paint(); }).catch(function () { paint(); });
} }
function extras(el) { function extras(el) {