Files
mama-box/topic/_shared/tools.js

255 lines
27 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* 孕期专题页共用:推荐工具卡(2026-10-31)
* 工具清单与 /api/mp/apps?isPublished=1 的「孕期工具」一致;跳转一律同源相对路径,带上 search + hash(openid)。
* 用法:TopicTools.render(el, [{id:'taidong', why:'一句推荐理由'}...], {title:'用得上的工具', color:'#18A058', wk:当前孕周})
*/
(function () {
var T = {
taidong: { n: '数胎动', u: '/taidong/', l: '/taidong/logo/logo-foot.svg', gate: 16 },
gongsuopinlv: { n: '数宫缩', u: '/gongsuo-pinlv/', l: '/upload/picture/1c02d720e4d23b09c996e859703b8b5e.svg', gate: 20 },
taierguzhong: { n: '胎儿估重', u: '/taier-guzhong/', l: '/upload/picture/715333a69fb67d8812ab093f342fa00f.png', gate: 15 },
chanjianrili: { n: '孕检日历', u: '/chanjian-rili/', l: '/chanjian-rili/logo/logo-7-dots.svg' },
yunqitizhong: { n: '孕期体重管理', u: '/yunqi-tizhong/', l: '/upload/picture/a6d7e61edee2ff0395cf00587a7c4036.svg' },
yunqixuetang: { n: '孕期血糖记录', u: '/yunqi-xuetang/', l: '/upload/picture/fde3c920fae453f2642731e4135b88f5.png' },
yunqinengbuchi: { n: '孕期能不能吃', u: '/yunqi-nengbuchi/', l: '/upload/picture/cf8750e19250caacd703b9d074211488.png' },
daichanqingdan: { n: '待产清单', u: '/daichan-qingdan/', l: '/upload/picture/f2da62ce728d3a7e85b4440ece6f26e5.svg' },
bushui: { n: '孕期补水补剂', u: '/yunqi-bushui/yindao/', l: '/upload/picture/ca30770e30bc2270c4aea0d382b872b0.svg' },
yun: { n: '孕期血压记录', u: '/yunqi-xueya/intro/', l: '/upload/picture/816227e3933211145bb8fc774ee32e82.svg' },
yundujinian: { n: '宝宝相册', u: '/yundu-jinian/', l: '/yundu-jinian/logo.svg' }
};
var css = '.tt-wrap{margin:28px 0 8px}.tt-h{display:flex;align-items:baseline;justify-content:space-between;margin:0 2px 12px}' +
'.tt-h b{font-size:18px;font-weight:800;color:#1F2329}.tt-h span{font-size:12.5px;color:#86909C}' +
'.tt-list{display:flex;flex-direction:column;gap:10px}' +
'.tt-it{display:flex;align-items:center;gap:12px;padding:12px 14px;background:#fff;border:1px solid #EEF0F3;border-radius:18px;text-decoration:none;-webkit-tap-highlight-color:transparent;transition:transform .15s}' +
'.tt-it:active{transform:scale(.98)}.tt-ic{flex:0 0 44px;width:44px;height:44px;border-radius:13px;background:var(--tt-bg,#F7F8FA);display:flex;align-items:center;justify-content:center}' +
'.tt-ic img{width:34px;height:34px;object-fit:contain}.tt-tx{flex:1;min-width:0}.tt-n{font-size:15px;font-weight:700;color:#1F2329;display:flex;align-items:center;gap:6px}' +
'.tt-tag{font-size:11px;font-weight:600;padding:1px 7px;border-radius:99px;background:#F2F3F5;color:#86909C}' +
'.tt-w{font-size:12.5px;color:#4E5969;margin-top:2px;line-height:1.5}.tt-go{flex:0 0 auto;font-size:13px;font-weight:700;color:var(--tt-c,#18A058);padding:6px 12px;border-radius:99px;background:var(--tt-bg,#F7F8FA)}';
function href(u) { return u + (location.search || '') + (location.hash || ''); }
function esc(s) { return String(s == null ? '' : s).replace(/[&<>"]/g, function (c) { return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;' }[c]; }); }
/* 11-02 用户:推荐工具做成固定模块,下面再推荐 3 个相关专题,再下面是评论区(预置评论 + 用户可评)。
* 104 个专题页都走 render(),所以统一在这里追加,页面不用改。
* 预置评论是 AI 写的模拟评论(AGENTS.md 12c),数据 cm/<slug>.json;用户自己发的只存本机 mmbox.tp.v1。 */
var css2 = '.tt-wrap{padding:16px 14px 14px;border-radius:22px;background:var(--tt-bg,#F7F8FA);border:0}.tt-wrap .tt-it{border-color:transparent;box-shadow:0 4px 14px -10px rgba(31,35,41,.25)}' +
'.tt-h b{display:flex;align-items:center;gap:6px}.tt-h b::before{content:"";width:4px;height:16px;border-radius:4px;background:var(--tt-c,#18A058)}' +
'.tx-sec{margin:26px 0 8px}.tx-sec>.tt-h{margin-bottom:12px}' +
/* 11-03 用户:相关推荐不要图、别占太大 → 紧凑文字行:标题 + 分类 · N 人看过 */
'.tr-list{border-radius:16px;background:#fff;border:1px solid #EEF0F3;padding:0 12px}.tr-it{display:flex;align-items:center;gap:10px;padding:11px 0;border-bottom:1px solid #F2F3F5;text-decoration:none;-webkit-tap-highlight-color:transparent}.tr-it:last-child{border-bottom:0}' +
'.tr-it:active{opacity:.6}' +
'.tr-tx{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}.tr-tx b{font-size:14.5px;font-weight:600;line-height:1.45;color:#1F2329;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}' +
'.tr-tx span{font-size:12px;color:#86909C;display:flex;gap:6px;align-items:center}.tr-tx em{font-style:normal;font-size:11px;font-weight:600;color:var(--tt-c,#18A058)}.tr-tx em::after{content:"·";margin-left:6px;color:#C9CDD4;font-weight:400}.tr-go{color:#C9CDD4;font-size:18px}' +
/* 11-03 用户:评论输入框别放在评论区最上面,浮在页面底部 */
'.tc-in{position:fixed;left:0;right:0;bottom:0;z-index:30;display:flex;gap:8px;align-items:flex-end;padding:8px 12px calc(8px + env(safe-area-inset-bottom));background:rgba(255,255,255,.97);border-top:1px solid #F0F1F3;box-shadow:0 -6px 18px -14px rgba(31,35,41,.3)}' +
/* 11-03 用户:点回复时底部要明显显示在回复谁(同孕妈广场) */
'.tc-rto{position:absolute;left:0;right:0;bottom:100%;display:flex;align-items:center;gap:8px;padding:8px 14px;background:#F7F8FA;border-top:1px solid #EEF0F3;font-size:12.5px;color:#86909C}.tc-rto[hidden]{display:none}.tc-rto span{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.tc-rto b{color:#1F2329;font-weight:600}.tc-in .tc-rto button{flex:none;width:22px;height:22px;padding:0;border:0;border-radius:50%;background:#E5E6EB;color:#86909C;font-size:14px;line-height:22px}' +
'.tc-in label{flex:1;min-width:0;display:flex;padding:6px 14px;border-radius:20px;background:#F2F3F5}' +
'.tc-in textarea{flex:1;min-width:0;border:0;background:transparent;resize:none;font-size:14px;line-height:1.6;font-family:inherit;color:#1F2329;height:24px;max-height:96px;outline:0;padding:0}' +
'.tc-in button{flex:0 0 auto;height:36px;padding:0 16px;border:0;border-radius:99px;background:var(--tt-c,#18A058);color:#fff;font-size:13.5px;font-weight:700}.tc-in button:disabled{opacity:.35}' +
/* 11-05 评论带图:图片按钮 / 缩略图条(js/cm-pics.js)别吃到上面通用的绿色按钮样式;缩略图条浮在输入条上方,「回复 XX」条出来时再往上让一格 */
'.tc-in .cmp-btn{height:36px;width:32px;padding:0;background:none;color:#86909C;border-radius:50%}.tc-in .cmp-btn.on{color:var(--tt-c,#18A058)}.tc-in .cmp-btn[hidden]{display:none}' +
'.tc-in .cmp-t button{width:18px;height:18px;padding:0;border-radius:50%;background:rgba(0,0,0,.55);font-size:13px;font-weight:400;line-height:18px}' +
'.tc-in .cmp-up{position:absolute;left:0;right:0;bottom:100%;background:#fff}.tc-in .cmp-strip{padding:8px 14px 6px;border-top:1px solid #EEF0F3}.tc-rto:not([hidden]) ~ .cmp-up{bottom:calc(100% + 38px)}' +
'.tc-in .cmp-emo button{height:auto;padding:2px;border-radius:10px;background:#FBF6F3;color:inherit;font-weight:400}.tc-in .cmp-emo button.on{box-shadow:inset 0 0 0 2px var(--tt-c,#18A058)}' +
'.tc-it{display:flex;gap:10px;padding:14px 0;border-bottom:1px solid #F2F3F5}.tc-it:last-child{border-bottom:0}.tc-av{flex:0 0 34px;width:34px;height:34px;border-radius:50%;object-fit:cover;background:#F2F3F5}' +
/* 11-03 用户评论先审核:自己的评论挂状态 */
'.tc-st{display:inline-block;margin-top:6px;padding:0 7px;border-radius:4px;font-size:11px;line-height:18px;font-weight:600;background:#F2F3F5;color:#86909C}.tc-st.pending{background:#FFF4E5;color:#E08A00}.tc-it.rej .tc-t{color:#A0A6AE}' +
'.tc-me{display:flex;align-items:center;justify-content:center;font-size:13px;font-weight:800;color:#fff;background:var(--tt-c,#18A058)}' +
'.tc-b{flex:1;min-width:0}.tc-n{display:flex;align-items:center;gap:6px;font-size:13px;color:#86909C;line-height:1.4}.tc-n b{font-weight:600;color:#4E5969}.tc-n i{font-style:normal;font-size:11px;padding:0 6px;border-radius:99px;background:#F2F3F5}' +
'.tc-t{margin-top:4px;font-size:14.5px;line-height:1.7;color:#1F2329;word-break:break-word}' +
'.tc-f{display:flex;justify-content:flex-end;margin-top:2px}.tc-lk{display:inline-flex;align-items:center;gap:3px;border:0;background:none;padding:2px 0;font-size:12px;color:#86909C}.tc-lk svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:1.8}' +
'.tc-lk.on{color:#F2533A}.tc-lk.on svg{fill:currentColor}' +
'.tc-rpy{border:0;background:none;padding:2px 0;margin-right:auto;font-size:12px;font-weight:600;color:#86909C}.tc-r p[data-rk],.tc-b[data-rk] .tc-t{cursor:pointer}.tc-r p.rej{color:#A0A6AE}.tc-r .tc-st{margin-top:3px}' +
'.tc-r{margin-top:6px;padding:8px 10px;border-radius:12px;background:#F7F8FA;font-size:13.5px;line-height:1.65;color:#4E5969}.tc-r p+p{margin-top:4px}.tc-r b{font-weight:600;color:#1F2329}' +
'.tc-more{display:block;width:100%;margin-top:6px;height:40px;border:0;border-radius:99px;background:#F7F8FA;color:#4E5969;font-size:13px;font-weight:600}';
var SLUG = (location.pathname.match(/\/topic\/([^\/]+)\//) || [])[1] || '';
/* 11-04 微信转发图:每个专题一张 assets/share/t/<slug>.jpg(核心词大字 + logo),见 js/share-card.js */
if (SLUG) (function () { var s = document.createElement('script'); s.src = '../../js/share-card.js?v=26110464'; s.onload = function () { window.mbShare('../../assets/share/t/' + SLUG + '.jpg'); }; document.head.appendChild(s); })();
/* 11-07 退出登录后只看不写(js/login-gate.js):点赞、评论、发图都弹「登录后才能使用」 */
if (!window.mbGate) (function () { var s = document.createElement('script'); s.src = '../../js/login-gate.js?v=26110610'; document.head.appendChild(s); })();
var SK = 'mmbox.tp.v1', UK = (function () { var m = ((location.hash || '') + '&' + (location.search || '')).match(/[#?&]openid=([^&]*)/); return m ? decodeURIComponent(m[1]).split('?')[0] : ((function(){try{var c=JSON.parse(sessionStorage.getItem('mmbox.identity')||'null');return c&&c.openid&&(!c.at||Date.now()-c.at<432e5)?c.openid:'';}catch(e){return '';}})() || '_guest'); })(); /* 11-07 URL 没带身份时用首页存的同源缓存 */
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) {} }
/* 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) { if (/^https?:\/\//.test(a)) return a; if (a === '') a = 'av:q' + ('00' + (SLUG.length * 37 % 150)).slice(-3); /* 真实评论:用户自己的头像;没头像给个可爱卡通 */
return typeof a === 'number' ? '../../guangchang/av/' + ('000' + a).slice(-4) + '.webp' : a.indexOf('av:') === 0 ? '../../guangchang/av/' + a.slice(3) + '.webp' : a.charAt(0) === '/' ? a : '../../assets/img/mom/' + a + '.jpg'; }
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>';
function getJSON(u) { return fetch(u, { cache: 'no-cache' }).then(function (r) { if (!r.ok) throw r.status; return r.json(); }); }
function related(box) {
getJSON('../_shared/idx.json?v=26110464').then(function (idx) {
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 rest = idx.filter(function (x) { return x[0] !== SLUG && (window.__mbUgc || ['ceshi', 'duiyou'].indexOf(x[0]) < 0); }); /* UGC 关着不推两个测试 */
var same = rest.filter(function (x) { return x[2] === tag; }).sort(function (a, b) { return b[3] - a[3]; });
/* 同类按热度取前几里轮换,凑不够 3 个用全站热门补 */
var pick = [], top = same.slice(0, 6);
for (var k = 0; k < top.length && pick.length < 3; k++) pick.push(top[(h + k) % top.length]);
rest.sort(function (a, b) { return b[3] - a[3]; }).forEach(function (x) { if (pick.length < 3 && pick.indexOf(x) < 0) pick.push(x); });
box.innerHTML = '<div class="tt-h"><b>相关推荐</b><span>其他妈妈也在看</span></div><div class="tr-list">' + pick.map(function (x) {
return '<a class="tr-it" href="' + esc(href('../' + x[0] + '/')) + '"><span class="tr-tx"><b>' + esc(x[1]) + '</b><span>' + (x[2] ? '<em>' + esc(x[2]) + '</em>' : '') + wan(Math.round(1510000 * x[3])) + ' 人看过</span></span><span class="tr-go">›</span></a>';
}).join('') + '</div>';
}).catch(function () { box.remove(); });
}
function comments(box) {
/* 11-03 用户:评论要后台审核通过才对外公开。服务器 /plaza/comments?kind=topic:list = 别人已通过的,mine = 我发的(含审核中/未通过);
st.m.cm 里是 11-03 以前只存本机的旧评论,从没公开过,照旧只给自己看(标「仅自己可见」) */
var st = loadMe(), L = [], open = false, RC = { list: [], mine: [] }, OID = UK === '_guest' ? '' : UK;
var API = '/api/mp/public/mama-box/plaza';
function mine() {
/* 11-07 用户改(同星空留言区):别人只看到已通过的;自己发的审核中也显示、标「审核中 · 只有你自己看得到」;没通过的不出;本机旧评论(从没审过)不再显示 */
return RC.mine.filter(function (c) { return c.status !== 'rejected'; }).reverse().map(function (c) { return { t: c.text, ts: c.at, s: c.stage, st: c.status, why: c.reason, id: c.id, parent: c.parent, to: c.parentName, img: c.images }; });
}
function real() { return RC.list.filter(function (c) { return !c.parent; }).map(function (c) { return [c.nickname || '孕妈', c.avatar || '', c.stage || '', c.text, 0, [], 'r:' + c.id, c.images]; }); }
var cpH = function (a) { return window.MBCmPics ? MBCmPics.html(a) : ''; }; /* 11-05 评论里的图 */
var cpT = function (t) { return window.MBCmPics ? MBCmPics.txt(t) : esc(t); }; /* 11-05 [兜表情:xx] 换成表情图 */
/* 11-03 用户:可以回复别人的评论。回复也先审核;楼里只有一层,回复回复也挂在同一楼,写「回复 XX」 */
var REPLY = null, MYN = '我';
function stTag(c) { return c.st === 'pending' ? '<span class="tc-st pending">审核中 · 只有你自己看得到</span>' : c.st === 'rejected' ? '<span class="tc-st">未通过' + (c.why ? ':' + esc(c.why) : '') + '</span>' : c.st === 'local' ? '<span class="tc-st">仅自己可见</span>' : ''; }
function replies(base, k, owner) {
var L2 = (base || []).map(function (r) { return { n: r[0], t: r[3] }; })
.concat(RC.list.filter(function (c) { return c.parent === k; }).map(function (c) { return { n: c.nickname || '孕妈', t: c.text, to: c.parentName, ts: c.at, img: c.images }; })
.concat(mine().filter(function (c) { return c.parent === k; }).map(function (c) { return { n: MYN, me: 1, t: c.t, to: c.to, st: c.st, why: c.why, ts: c.ts, img: c.img }; }))
.sort(function (x, y) { return x.ts - y.ts; })); /* 预置回复在前,真实回复按时间先后 */
return L2.length ? '<div class="tc-r">' + L2.map(function (r) {
return '<p' + (r.me ? (r.st === 'rejected' ? ' class="rej"' : '') : ' data-rk="' + esc(k) + '" data-rn="' + esc(r.n) + '"') + '><b>' + esc(r.n) + '</b>' + (r.to && r.to !== owner ? ' 回复 <b>' + esc(r.to) + '</b>' : '') + '<b>:</b>' + cpT(r.t) + cpH(r.img) +
(r.me && r.st !== 'approved' ? '<br>' + stTag(r) : '') + '</p>';
}).join('') + '</div>' : '';
}
function item(c, key) {
var lk = !!st.m.lk[key];
var rk = c.me ? (c.id && c.st === 'approved' ? 'r:' + c.id : '') : key, rn = c.me ? MYN : c[0];
var tag = c.me ? stTag(c) : '';
return '<div class="tc-it' + (c.me && c.st === 'rejected' ? ' rej' : '') + '">' + (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"' + (rk ? ' data-rk="' + esc(rk) + '" data-rn="' + esc(rn) + '"' : '') + '><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>' +
((c.me ? c.t : c[3]) ? '<div class="tc-t">' + cpT(c.me ? c.t : c[3]) + '</div>' : '') + cpH(c.me ? c.img : c[7]) + tag +
(rk ? replies(c.me ? [] : c[5], rk, rn) : '') +
'<div class="tc-f">' + (rk ? '<button type="button" class="tc-rpy">回复</button>' : '') + '<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>';
}
function paint() {
var my = mine().filter(function (c) { return !c.parent; }).reverse(), A = real().concat(L), n = A.length + my.filter(function (c) { return c.st !== 'rejected'; }).length, show = open ? A : A.slice(0, 5);
box.innerHTML = '<div class="tt-h"><b>大家怎么说</b><span>' + n + ' 条评论</span></div>' +
'<div class="tc-list">' + my.map(function (c, i) { return item({ me: 1, t: c.t, s: c.s, st: c.st, why: c.why, img: c.img }, 'me' + c.ts); }).join('') +
show.map(function (c, i) { return item(c, c[6] || SLUG + '#' + (i - (A.length - L.length))); }).join('') + '</div>' +
(!open && A.length > 5 ? '<button type="button" class="tc-more">展开全部 ' + n + ' 条评论</button>' : '');
[].forEach.call(box.querySelectorAll('[data-rk]'), function (el) {
el.addEventListener('click', function (e) {
if (e.target.closest('.tc-lk') || (el.classList.contains('tc-b') && e.target.closest('.tc-r'))) return;
var tx = el.classList.contains('tc-b') ? (el.querySelector('.tc-t') || {}).textContent : el.textContent.replace(/^[^:]*:/, '');
setReply({ k: el.dataset.rk, n: el.dataset.rn }, tx); ta.focus();
});
});
var mo = box.querySelector('.tc-more'); if (mo) mo.addEventListener('click', function () { open = true; paint(); });
[].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(); });
});
}
/* 底部浮条:整页常驻,发完滚到评论区看到自己那条 */
var bar = document.createElement('div'); bar.className = 'tc-in';
bar.innerHTML = '<div class="tc-rto" hidden><span></span><button type="button" aria-label="取消回复">×</button></div><div class="cmp-up"><div class="cmp-strip"></div><div class="cmp-emo" hidden></div></div><label><textarea rows="1" maxlength="200" placeholder="说说你的情况,和其他妈妈聊聊…"></textarea></label><button type="button" class="cmp-btn emo-b" aria-label="表情"></button><button type="button" class="cmp-btn pic-b" aria-label="加图片"></button><button type="button" class="tc-go" disabled>发布</button>';
bar.style.setProperty('--tt-c', box.style.getPropertyValue('--tt-c'));
document.body.appendChild(bar);
var sc = box.parentNode; while (sc && sc !== document.body && !/(auto|scroll)/.test(getComputedStyle(sc).overflowY)) sc = sc.parentNode;
sc = sc || document.body; sc.style.paddingBottom = (parseFloat(getComputedStyle(sc).paddingBottom) || 0) + 64 + 'px';
var ta = bar.querySelector('textarea'), bt = bar.querySelector('.tc-go'), PH = ta.placeholder, rto = bar.querySelector('.tc-rto');
function setReply(r, tx) {
REPLY = r; ta.placeholder = r ? '回复 ' + r.n + ':' : PH; rto.hidden = !r;
if (r) rto.querySelector('span').innerHTML = '回复 <b>' + esc(r.n) + '</b>' + (tx ? ':' + esc(String(tx).trim().slice(0, 40)) : '');
}
rto.querySelector('button').addEventListener('mousedown', function (e) { e.preventDefault(); });
rto.querySelector('button').addEventListener('click', function () { setReply(null); });
/* 11-05 评论 / 回复可带图(最多 3 张,js/cm-pics.js 加载好之后才出按钮);只有图没有字也能发 */
var CP = null, pb = bar.querySelector('.pic-b'), eb = bar.querySelector('.emo-b');
var canSend = function () { return !!ta.value.trim() || !!(CP && CP.count()); };
pb.hidden = true; eb.hidden = true;
eb.addEventListener('mousedown', function (e) { e.preventDefault(); });
eb.addEventListener('click', function () { if (CP) CP.toggleEmo(); });
pb.addEventListener('mousedown', function (e) { e.preventDefault(); });
pb.addEventListener('click', function () { if (CP) CP.pick(); });
cmPicsReady(function () {
CP = MBCmPics.picker({ strip: bar.querySelector('.cmp-strip'), emoPanel: bar.querySelector('.cmp-emo'), toast: toast, onChange: function () { bt.disabled = !canSend(); eb.classList.toggle('on', CP.hasEmo() || CP.emoOpen()); } });
pb.innerHTML = MBCmPics.ICON; pb.hidden = false; paint(); /* 11-05 用户:评论框去掉表情(同广场),eb 一直 hidden */
});
ta.addEventListener('blur', function () { setTimeout(function () { if (!canSend() && !(CP && CP.emoOpen())) setReply(null); }, 150); });
ta.addEventListener('input', function () { bt.disabled = !canSend(); ta.style.height = '24px'; ta.style.height = Math.min(96, ta.scrollHeight) + 'px'; });
bt.addEventListener('click', function () {
var v = ta.value.trim(); if (!canSend() || bt.busy) return;
if (CP && CP.busy()) { toast('图片还在上传,稍等一下'); return; }
var imgs = CP ? CP.urls() : [], emo = CP ? CP.emoji() : '';
if (!v && !imgs.length && !emo) { toast('图片没传上去,删掉重新选一下'); return; }
if (!OID) { toast('请在小程序里打开后再评论'); return; }
/* 11-03:先交后台审核,通过后才公开;审核中只有自己看得到 */
bt.busy = true; bt.disabled = true;
var h1 = document.querySelector('h1');
fetch(API + '/comment?openid=' + encodeURIComponent(OID), { method: 'POST', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ kind: 'topic', target: SLUG, title: (h1 && h1.textContent.trim()) || document.title, text: (v.slice(0, 200 - emo.length) + emo).trim(), images: imgs, stage: myStage(), parent: REPLY ? REPLY.k : '', parentName: REPLY ? REPLY.n : '' }) })
.then(function (r) { return r.json(); }).then(function (j) {
bt.busy = false;
if (!j || j.code !== 200) { bt.disabled = !canSend(); toast((j && j.message) || '没发出去,稍后再试'); return; }
RC.mine.unshift(j.result);
var wasReply = !!REPLY; setReply(null);
ta.value = ''; if (CP) CP.clear(); ta.style.height = '24px'; bt.disabled = true; ta.blur(); paint();
if (!wasReply) box.scrollIntoView({ block: 'start', behavior: 'smooth' });
toast(wasReply ? '回复已发出,审核通过后大家就能看到' : '已发出,审核通过后大家就能看到');
}).catch(function () { bt.busy = false; bt.disabled = !canSend(); toast('网络不太好,稍后再试'); });
});
function toast(m) {
var t = document.createElement('div'); t.textContent = m;
t.style.cssText = 'position:fixed;left:50%;bottom:96px;transform:translateX(-50%);z-index:40;max-width:80%;padding:9px 16px;border-radius:99px;background:rgba(31,35,41,.86);color:#fff;font-size:13.5px;line-height:1.4;text-align:center';
document.body.appendChild(t); setTimeout(function () { t.remove(); }, 2000);
}
fetch(API + '/comments?kind=topic&target=' + encodeURIComponent(SLUG) + (OID ? '&openid=' + encodeURIComponent(OID) : ''))
.then(function (r) { return r.json(); }).then(function (j) { if (j && j.code === 200) { RC = j.result; paint(); } }).catch(function () {});
getJSON('../_shared/cm/' + SLUG + '.json?v=26110464').then(function (d) { L = d.c || []; paint(); }).catch(function () { paint(); });
}
function cmPicsReady(cb) {
if (window.MBCmPics) return cb();
var s = document.createElement('script'); s.src = '../../js/cm-pics.js?v=26110464'; s.onload = function () { if (window.MBCmPics) cb(); };
document.head.appendChild(s);
}
function ugcReady() {
if (window.__mbUgcReady) return window.__mbUgcReady;
return new Promise(function (res) {
var u = document.createElement('script'); u.src = '../../js/ugc.js?v=26110464';
u.onload = function () { (window.__mbUgcReady || Promise.resolve(false)).then(res); };
u.onerror = function () { res(false); };
document.head.appendChild(u);
});
}
function extras(el) {
if (!SLUG || document.getElementById('tx-rel')) return;
if (!document.getElementById('tx-css')) { var s = document.createElement('style'); s.id = 'tx-css'; s.textContent = css2; document.head.appendChild(s); }
var a = document.createElement('section'); a.id = 'tx-rel'; a.className = 'tx-sec';
var b = document.createElement('section'); b.id = 'tx-cm'; b.className = 'tx-sec';
el.parentNode.insertBefore(b, el.nextSibling); el.parentNode.insertBefore(a, b);
var c = getComputedStyle(el);
[a, b].forEach(function (x) { x.style.marginLeft = c.marginLeft; x.style.marginRight = c.marginRight; });
a.style.setProperty('--tt-c', c.getPropertyValue('--tt-c')); a.style.setProperty('--tt-bg', c.getPropertyValue('--tt-bg'));
b.style.setProperty('--tt-c', c.getPropertyValue('--tt-c')); b.style.setProperty('--tt-bg', c.getPropertyValue('--tt-bg'));
/* 11-04 UGC 总开关(js/ugc.js):评论区是用户内容,关着就不出;相关推荐等开关结果再排(关着不推测试) */
ugcReady().then(function (on) { related(a); if (on) comments(b); else b.remove(); });
}
function render(el, list, opt) {
if (!el) return;
opt = opt || {};
if (!document.getElementById('tt-css')) { var s = document.createElement('style'); s.id = 'tt-css'; s.textContent = css; document.head.appendChild(s); }
var wk = +opt.wk || 0, html = '';
list.forEach(function (x) {
var t = T[x.id]; if (!t) return;
var lock = t.gate && wk && wk < t.gate;
html += '<a class="tt-it" href="' + esc(href(t.u)) + '"><span class="tt-ic"><img src="' + esc(t.l) + '" alt=""></span>' +
'<span class="tt-tx"><span class="tt-n">' + esc(t.n) + (lock ? '<span class="tt-tag">孕' + t.gate + '周开放</span>' : (x.tag ? '<span class="tt-tag">' + esc(x.tag) + '</span>' : '')) + '</span>' +
'<span class="tt-w">' + esc(x.why) + '</span></span><span class="tt-go">' + esc(x.btn || '去用') + '</span></a>';
});
el.classList.add('tt-wrap');
if (opt.color) el.style.setProperty('--tt-c', opt.color);
if (opt.bg) el.style.setProperty('--tt-bg', opt.bg);
el.innerHTML = '<div class="tt-h"><b>' + esc(opt.title || '用得上的工具') + '</b><span>' + esc(opt.sub || '都在兜爸心选,免费用') + '</span></div><div class="tt-list">' + html + '</div>';
extras(el);
}
window.TopicTools = { render: render, list: T, href: href };
})();