clearlove2.1
1{
2 "name": "rules-gate",
3 "version": "1.0.0",
4 "author": "ClearLove",
5 "description": "发帖前弹出社区守则,需滚动阅读全文并勾选同意后才能发布(自动同步后台「社区守则」设置)",
6 "hooks": [
7 {
8 "hook": "footer_html",
9 "type": "html",
10 "html": "<script>\n(function () {\n var CFG = {\n TITLE: '社区守则',\n DESC: '发布前请仔细阅读以下守则,确认同意后方可发布。',\n TIP: '请向下滚动阅读完守则全文',\n CHECK: '我已阅读并同意《社区守则》',\n OK: '同意并发布',\n NO: '取消',\n REMEMBER_DAYS: 0,\n REQUIRE_SCROLL: true,\n AUTO_SYNC: true,\n FALLBACK: [\n '1. 禁止发布违法违规、暴力、色情、辱骂及广告刷屏内容。',\n '2. 请勿泄露他人隐私信息(真实姓名、联系方式、住址、证件号等)。',\n '3. 尊重他人,理性表达,不使用攻击性或歧视性语言。',\n '4. 请勿重复刷屏,或发布与本站主题无关的广告内容。',\n '5. 违规内容将被隐藏或删除,多次违规可能被封禁发布权限。'\n ].join('\\n')\n };\n var KEY = 'clv_rules_gate_v1';\n var CSS = \"#clv-rg-mask{position:fixed;left:0;top:0;right:0;bottom:0;background:rgba(15,17,24,.55);z-index:99998;display:none;align-items:center;justify-content:center;padding:16px;box-sizing:border-box}#clv-rg-box{width:100%;max-width:460px;max-height:82vh;background:var(--clv-card,#fff);color:var(--clv-text,#23262f);border-radius:var(--clv-radius,16px);box-shadow:0 18px 50px rgba(0,0,0,.28);display:flex;flex-direction:column;overflow:hidden;font-family:var(--clv-font,sans-serif)}#clv-rg-head{padding:18px 20px 10px}#clv-rg-head h3{margin:0 0 6px;font-size:17px;line-height:1.4}#clv-rg-head p{margin:0;font-size:13px;line-height:1.6;color:var(--clv-muted,#8a8f9c)}#clv-rg-body{margin:0 20px;padding:12px 14px;border:1px solid var(--clv-border,#eceef4);border-radius:10px;background:rgba(127,127,127,.06);font-size:14px;line-height:1.9;white-space:pre-wrap;word-break:break-word;overflow-y:auto;flex:1 1 auto;min-height:130px;max-height:44vh;-webkit-overflow-scrolling:touch}#clv-rg-foot{padding:14px 20px 18px}#clv-rg-tip{font-size:12px;color:var(--clv-muted,#8a8f9c);margin:0 0 10px;min-height:16px}#clv-rg-check{display:flex;align-items:flex-start;gap:8px;font-size:13.5px;line-height:1.5;margin-bottom:12px;cursor:pointer;user-select:none}#clv-rg-check input{margin:2px 0 0;width:16px;height:16px;flex:0 0 auto;accent-color:var(--clv-accent,#ff7ba9)}#clv-rg-acts{display:flex;gap:10px}#clv-rg-acts button{flex:1;padding:11px 14px;border-radius:10px;font-size:15px;font-family:inherit;border:1px solid var(--clv-border,#eceef4);background:transparent;color:inherit;cursor:pointer}#clv-rg-acts #clv-rg-ok{flex:1.4;border:0;background:var(--clv-accent,#ff7ba9);color:#fff;font-weight:600}#clv-rg-acts #clv-rg-ok:disabled{opacity:.45;cursor:not-allowed}@media(max-width:420px){#clv-rg-mask{padding:10px}#clv-rg-box{max-height:88vh}}\";\n var HTML = \"<div id='clv-rg-mask' role='dialog' aria-modal='true'><div id='clv-rg-box'><div id='clv-rg-head'><h3 id='clv-rg-ttl'></h3><p id='clv-rg-sub'></p></div><div id='clv-rg-body' tabindex='0'></div><div id='clv-rg-foot'><p id='clv-rg-tip'></p><label id='clv-rg-check'><input type='checkbox' id='clv-rg-chk'><span id='clv-rg-ck'></span></label><div id='clv-rg-acts'><button type='button' id='clv-rg-no'></button><button type='button' id='clv-rg-ok' disabled></button></div></div></div></div>\";\n var cur = '', form2 = null, readDone = false, built = false;\n function txt(h) {\n var d = document.createElement('div');\n d.innerHTML = String(h).split('<br>').join('\\n').split('<br/>').join('\\n');\n return String(d.textContent || '').trim();\n }\n function h(s) {\n var x = 0, i;\n for (i = 0; i < s.length; i++) { x = ((x << 5) - x + s.charCodeAt(i)) | 0; }\n return String(x);\n }\n function q(id) { return document.getElementById(id); }\n function okBefore() {\n if (CFG.REMEMBER_DAYS <= 0) { return false; }\n try {\n var o = JSON.parse(localStorage.getItem(KEY) || '0');\n if (!o || o.h !== h(cur)) { return false; }\n return (Date.now() - o.t) < CFG.REMEMBER_DAYS * 86400000;\n } catch (e) { return false; }\n }\n function save() {\n if (CFG.REMEMBER_DAYS <= 0) { return; }\n try { localStorage.setItem(KEY, JSON.stringify({ t: Date.now(), h: h(cur) })); } catch (e) { }\n }\n function sync() {\n var can = (!CFG.REQUIRE_SCROLL) || readDone;\n q('clv-rg-tip').textContent = can ? '' : CFG.TIP;\n q('clv-rg-ok').disabled = !(can && q('clv-rg-chk').checked);\n }\n function onScroll() {\n var b = q('clv-rg-body');\n if (b.scrollTop + b.clientHeight >= b.scrollHeight - 8) { readDone = true; sync(); }\n }\n function close() {\n q('clv-rg-mask').style.display = 'none';\n document.body.style.overflow = '';\n form2 = null;\n }\n function agree() {\n var f = form2;\n if (!f) { close(); return; }\n save();\n close();\n f.clvRulesGate = 1;\n if (typeof f.requestSubmit === 'function') { f.requestSubmit(); }\n else { f.dispatchEvent(new Event('submit', { bubbles: true, cancelable: true })); }\n }\n function build() {\n var st = document.createElement('style');\n st.textContent = CSS;\n document.head.appendChild(st);\n var box = document.createElement('div');\n box.innerHTML = HTML;\n document.body.appendChild(box.firstChild);\n q('clv-rg-ttl').textContent = CFG.TITLE;\n q('clv-rg-sub').textContent = CFG.DESC;\n q('clv-rg-ck').textContent = CFG.CHECK;\n q('clv-rg-no').textContent = CFG.NO;\n q('clv-rg-ok').textContent = CFG.OK;\n q('clv-rg-chk').addEventListener('change', sync);\n q('clv-rg-body').addEventListener('scroll', onScroll);\n q('clv-rg-no').addEventListener('click', close);\n q('clv-rg-ok').addEventListener('click', agree);\n q('clv-rg-mask').addEventListener('click', function (e) { if (e.target.id === 'clv-rg-mask') { close(); } });\n document.addEventListener('keydown', function (e) {\n var m = q('clv-rg-mask');\n if (e.key === 'Escape' && m && m.style.display !== 'none') { close(); }\n });\n built = true;\n }\n function show(f) {\n if (!built) { build(); }\n form2 = f;\n readDone = false;\n q('clv-rg-chk').checked = false;\n q('clv-rg-body').textContent = cur;\n q('clv-rg-body').scrollTop = 0;\n q('clv-rg-mask').style.display = 'flex';\n document.body.style.overflow = 'hidden';\n sync();\n setTimeout(function () {\n var b = q('clv-rg-body');\n if (b.scrollHeight <= b.clientHeight + 4) { readDone = true; }\n sync();\n }, 80);\n }\n function fromServer() {\n if (!CFG.AUTO_SYNC) { return; }\n var x = new XMLHttpRequest();\n x.open('GET', '/api/v1/posts?limit=1', true);\n x.onload = function () {\n var id = 0;\n try { var d = JSON.parse(x.responseText); if (d && d.posts && d.posts.length) { id = d.posts[0].id; } } catch (e) { }\n if (!id) { return; }\n var y = new XMLHttpRequest();\n y.open('GET', '/post/' + id, true);\n y.onload = function () {\n var s = String(y.responseText), i = s.indexOf('rules card'), t = '';\n if (i >= 0) {\n var p1 = s.indexOf('<p>', i), p2 = p1 >= 0 ? s.indexOf('</p>', p1) : -1;\n if (p1 >= 0 && p2 > p1) { t = txt(s.slice(p1 + 3, p2)); }\n }\n if (t) { cur = t; }\n };\n y.send();\n };\n x.send();\n }\n if (!document.getElementById('compose-form')) { return; }\n cur = CFG.FALLBACK;\n document.addEventListener('submit', function (ev) {\n var f = ev.target;\n if (!f || f.id !== 'compose-form') { return; }\n if (f.clvRulesGate) { f.clvRulesGate = 0; return; }\n if (okBefore()) { return; }\n ev.preventDefault();\n ev.stopImmediatePropagation();\n show(f);\n }, true);\n fromServer();\n})();\n</script>"
11 }
12 ]
13}