Files
newbeggar/templates/site.html
T

190 lines
19 KiB
HTML
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.
{{define "title"}}{{.Site.Name}} {{T "在要饭 ·"}} {{T .SiteTitle}}{{end}}
{{define "content"}}
{{$lv := level .Exp}}
<div class="layout">
<aside class="col-l">
{{if not .Site.Listed}}<div class="notice">{{T "🕵️ 这个站还没被丐帮收录,暂不进榜。"}}{{if and .Me (eq .Me.ID .Site.ID)}}{{T "主站站长审核后会收录。"}}{{end}}</div>{{end}}
<section class="card px" id="topcard">
<div class="char-top">
<div class="sprite-wrap">{{template "sprite"}}</div>
<div class="char-info">
<div class="lvrow"><span class="lv">Lv.{{$lv.Lv}}<b>{{$lv.Title}}</b></span>{{if .SectTitle}}<span class="lv gold">{{T .SectTitle}}{{if .Position}} {{T "· 榜 #"}}{{.Position}}{{end}}</span>{{end}}</div>
<h1 class="pname">{{if .Site.AvatarURL}}<img class="xavatar" src="{{.Site.AvatarURL}}" alt="">{{else}}{{.Site.Avatar}} {{end}}{{.Site.Name}}</h1>
<div class="barlabel">EXP <b>{{.Exp}}</b>{{if $lv.Next}}<span>{{T "升%s要 %s" (T $lv.NextT) $lv.Next}}</span>{{else}}<span>{{T "满级"}}</span>{{end}}</div>
<div class="bar xp"><span style="width:{{$lv.Pct}}%"></span></div>
<div class="barlabel">{{T "饱食度"}} <b>{{satiety .Stats.TodayE8}}%</b><span>{{if eq (satiety .Stats.TodayE8) 0}}{{T "今天还没吃饭"}}{{else}}{{T "今天有人投币了"}}{{end}}</span></div>
<div class="bar hp"><span style="width:{{satiety .Stats.TodayE8}}%"></span></div>
{{if .Site.XLabel}}<a class="xpill" href="https://x.com/{{.Site.XLabel}}" target="_blank" rel="noopener">𝕏 @{{.Site.XLabel}}</a>{{end}}
</div>
</div>
{{if .Site.Slogan}}<div class="dialog"><span class="typer" data-text="{{.Site.Slogan}}">{{.Site.Slogan}}</span><span class="cursor">▼</span></div>{{end}}
<div class="coinrow">
<button type="button" class="btn sec sm coinbtn" id="coinbtn" data-site="{{.Site.Slug}}" {{if ge .MyCoins .CoinsPerDay}}disabled{{end}}>{{template "coin"}}<span id="coinTxt">{{if ge .MyCoins .CoinsPerDay}}{{T "今天丢过了"}}{{else}}{{T "丢个钢镚(免费)"}}{{end}}</span></button>
{{if .Ready}}<a class="btn sm" id="donateBtn" href="#donate">{{T "💸 投币施舍"}}</a>{{else}}<span class="hint" style="margin:0">{{T "还没摆碗,暂不能投币"}}{{if and .Me (eq .Me.ID .Site.ID)}},<a href="/manage#payment">{{T "去配置"}}</a>{{end}}</span>{{end}}
</div>
<div class="coins hint" style="margin-top:8px">{{T "钢镚"}} <b class="pf coinN">{{.Coins}}</b> {{T "· 今日"}} <b id="coinT" class="pf">{{.CoinsToday}}</b> {{T "· 每 0.1 U ="}} {{.MoneyExp | div10}} {{T "EXP · 每个钢镚 ="}} {{.CoinExp}} EXP</div>
</section>
<section class="stats">
<div class="stat main px">{{template "bowlicon"}}<div style="min-width:0;flex:1"><div class="k">{{T "碗里已有"}}</div><div class="v num bowlv"><span>{{fmtAmt .Stats.TotalE8}}<small>{{.Site.Currency}}</small></span><span class="bowlcoins">{{template "coin"}}<b class="coinN">{{.Coins}}</b><small>{{T "钢镚"}}</small></span></div></div>
<div class="sub2"><span><i>{{T "施主"}}</i><b class="num">{{.Stats.Donors}}</b><small>{{T "人"}}</small></span><span><i>{{T "今日"}}</i><b class="num">+{{fmtAmt .Stats.TodayE8}}</b></span></div></div>
</section>
<section class="card px donate-card" id="donate">
<h2>{{T "🕹️ 投币施舍"}}</h2>
{{if .Ready}}
<div class="insert blink">▶ INSERT COIN ◀</div>
<form method="post" action="/donate" id="f">
<input type="hidden" name="site" value="{{.Site.Slug}}">
<div class="grid2">
<div><label for="nick">{{T "玩家名(上榜用,可留空)"}}</label><input id="nick" name="nickname" maxlength="20" placeholder="{{T "匿名施主"}}" value="{{.Nick}}" autocomplete="nickname"></div>
<div><label for="xh">{{T "你的 X(可选,显示头像)"}}</label><input id="xh" name="x_handle" maxlength="16" placeholder="@name" value="{{.XHandle}}" autocapitalize="off"></div>
</div>
<label>{{T "投多少"}} {{.Site.Currency}}</label>
<div class="amounts" id="amounts">
{{range .Presets}}<button type="button" class="amt-btn" data-v="{{.}}">{{template "coin"}}{{.}}</button>{{end}}
<button type="button" class="amt-btn" data-v="">{{T "✏️ 自定义"}}</button>
</div>
<input name="amount" id="amount" inputmode="decimal" autocomplete="off" placeholder="{{T "输入金额,最多两位小数"}}" value="{{.Amount}}" required style="margin-top:10px">
<label for="msg">{{T "对乞丐喊话"}} <span class="count" id="cnt">0/80</span></label>
<textarea id="msg" name="message" maxlength="80" rows="2" placeholder="{{T "例如:别买烟了,去吃饭"}}">{{.Message}}</textarea>
{{if .Err}}<div class="err">{{T .Err}}</div>{{end}}
<button class="btn" type="submit" id="cta" style="margin-top:16px">{{T "投币 💸"}}</button>
<div class="hint" style="margin-top:10px">{{if eq .Site.PayMode "gateway"}}{{T "币安 App 扫码 / 一键唤起支付,到账后自动刻上功德簿。"}}{{else}}{{T "通过币安 Pay 直接转给站长,提交后由站长确认上榜。"}}{{end}}{{T "最少 %s,最多 %s。留言里不能放链接和联系方式。" .MinAmount .MaxAmount}}</div>
</form>
{{else}}
<div class="notice">{{T "这位乞丐还没摆碗(未配置收款方式),暂时收不了钱。"}}{{if and .Me (eq .Me.ID .Site.ID)}}<a href="/manage#payment">{{T "去后台配置 →"}}</a>{{end}}</div>
{{end}}
</section>
{{if and .SubsitesEnabled (not .Me)}}<div class="only-desktop">
<section class="card px cta">
<h2 style="justify-content:center">{{T "🏚 想自己要饭?"}}</h2>
<p>{{T "用 X 账号发一条推就能开自己的要饭站:独立地址、自己的碗、功德簿和施主榜,钱直接进你的币安账户。"}}</p>
<a class="btn sec" href="/new">{{T "用 X 开通我的要饭站 →"}}</a>
</section>
</div>{{end}}
</aside>
<main class="col-r">
<section class="card px">
<div class="tabs four" role="tablist">
<button class="tab on" type="button" role="tab" id="t-popular" aria-controls="p-popular" aria-selected="true" data-t="popular">{{T "人气榜"}}</button>
<button class="tab" type="button" role="tab" id="t-feed" aria-controls="p-feed" aria-selected="false" data-t="feed">{{T "功德簿"}}</button>
<button class="tab" type="button" role="tab" id="t-donors" aria-controls="p-donors" aria-selected="false" data-t="donors">{{T "施主榜"}}</button>
<button class="tab" type="button" role="tab" id="t-beggars" aria-controls="p-beggars" aria-selected="false" data-t="beggars">{{T "乞丐榜"}}</button>
</div>
<div class="panel" id="p-feed" role="tabpanel" aria-labelledby="t-feed">
{{if .Feed}}<ul class="list feed">
{{range .Feed}}<li class="item">
{{template "avatar" .}}
<div class="body"><div class="name"><span>{{if .Blocked}}{{T "已屏蔽的施主"}}{{else}}{{.Nickname}}{{end}}</span>{{if and .XHandle (not .Blocked)}}<span class="xh" title="{{T "施主自己填的 X,未经验证"}}">@{{.XHandle}}</span>{{end}}</div><div class="sub">{{ago .PaidAt}} {{T "投币"}}</div></div>
<div class="amtv num accent">+{{fmtAmt .ActualE8}}</div>
{{if .Blocked}}{{else if .MsgBlocked}}<div class="bubble blocked">***</div>{{else if .Message}}<div class="bubble">{{.Message}}</div>{{end}}
{{if and .Reply (not .Blocked)}}<div class="bubble reply">{{T "🥣 站长:"}}{{.Reply}}</div>{{end}}
</li>{{end}}
</ul>{{template "pager" .PgFeed}}{{else}}<div class="empty"><div class="ico">📜</div>{{T "功德簿空空如也,第一枚硬币会刻在这里"}}</div>{{end}}
</div>
<div class="panel" id="p-donors" role="tabpanel" aria-labelledby="t-donors">
<div class="toggle" data-for="donors"><button type="button" class="on" data-w="all">{{T "总榜"}}</button><button type="button" data-w="week">{{T "本周"}}</button></div>
<div class="hint" style="margin:-4px 0 8px">{{T "HIGH SCORE · 给"}} {{.Site.Name}} {{T "投币最多的人 · 🏁 首位施主 💎 单笔最大 🔥 常客"}}</div>
<div class="wk donors-all">{{template "donorlist" (dict "Rows" .Rank "Badges" .Badges "Start" .PgDonors.Offset)}}{{template "pager" .PgDonors}}</div>
<div class="wk donors-week" hidden>{{template "donorlist" (dict "Rows" .RankWeek "Badges" .Badges "Start" .PgDonorsWeek.Offset)}}{{template "pager" .PgDonorsWeek}}</div>
</div>
<div class="panel" id="p-beggars" role="tabpanel" aria-labelledby="t-beggars">
<div class="toggle" data-for="beggars"><button type="button" class="on" data-w="all">{{T "总榜"}}</button><button type="button" data-w="week">{{T "本周"}}</button></div>
<div class="hint" style="margin:-4px 0 8px">{{T "丐帮排名 · 要到最多的要饭站"}}</div>
<div class="wk beggars-all">{{template "sitelist" (dict "Rows" .Subsites "Me" .MeID "Here" .Site.ID "By" "amount" "Start" .PgBeggars.Offset)}}{{template "pager" .PgBeggars}}</div>
<div class="wk beggars-week" hidden>{{template "sitelist" (dict "Rows" .SubsitesWeek "Me" .MeID "Here" .Site.ID "By" "amount" "Start" .PgBeggarsWeek.Offset)}}{{template "pager" .PgBeggarsWeek}}</div>
</div>
<div class="panel on" id="p-popular" role="tabpanel" aria-labelledby="t-popular">
<div class="hint" style="margin:-4px 0 8px">{{T "人气榜 · 收到钢镚最多的要饭站(钢镚免费,不用花钱)"}}</div>
{{template "sitelist" (dict "Rows" .Popular "Me" .MeID "Here" .Site.ID "By" "coins" "Start" .PgPopular.Offset)}}{{template "pager" .PgPopular}}
</div>
</section>
{{if and .SubsitesEnabled (not .Me)}}<div class="only-mobile">
<section class="card px cta">
<h2 style="justify-content:center">{{T "🏚 想自己要饭?"}}</h2>
<p>{{T "用 X 账号发一条推就能开自己的要饭站:独立地址、自己的碗、功德簿和施主榜,钱直接进你的币安账户。"}}</p>
<a class="btn sec" href="/new">{{T "用 X 开通我的要饭站 →"}}</a>
</section>
</div>{{end}}
</main>
</div>
{{if .Ready}}<div class="fab" id="fab"><a class="btn" href="#donate" id="fabBtn">{{T "💸 投币施舍"}}</a></div>{{end}}
<div id="toast" class="toast" hidden></div>
<div class="modal" id="modal" hidden role="dialog" aria-modal="true"><div class="modal-box"><button class="modal-x" type="button" id="modalX" aria-label="{{T "关闭"}}">✕</button><div id="modalForm" hidden></div><div id="modalBody" hidden></div></div></div>
{{end}}
{{define "avatar"}}{{$f := xav .XHandle}}{{if and $f (not .Blocked)}}<img class="av img" src="/a/{{$f}}" alt="">{{else}}<div class="av" style="--h:{{hue .NickKey}}">{{if .Blocked}}✕{{else}}{{initial .Nickname}}{{end}}</div>{{end}}{{end}}
{{define "donorlist"}}{{if .Rows}}<ul class="list">
{{range $i, $r := .Rows}}{{$n := add $i $.Start}}<li class="item">
<div class="rank{{if lt $n 3}} m{{end}}">{{rankBadge $n}}</div>
{{$h := handleOf $r.NickKey}}{{$f := xav $h}}{{if $f}}<img class="av img" src="/a/{{$f}}" alt="">{{else}}<div class="av" style="--h:{{hue $r.NickKey}}">{{initial $r.Nickname}}</div>{{end}}
<div class="body"><div class="name"><span>{{$r.Nickname}}</span>{{if $h}}<span class="xh" title="{{T "施主自己填的 X,未经验证"}}">@{{$h}}</span>{{end}}{{with index $.Badges $r.NickKey}}<span class="badge">{{.}}</span>{{end}}</div><div class="sub">{{donorTier $r.TotalE8}} · {{$r.Count}} {{T "次"}}</div></div>
<div class="amtv num accent">{{fmtAmt $r.TotalE8}}</div>
</li>{{end}}
</ul>{{else}}<div class="empty"><div class="ico">👑</div>{{T "榜上无人,第一个投币的就是首席施主"}}</div>{{end}}{{end}}
{{define "sitelist"}}{{if .Rows}}<ul class="list">
{{range $i, $s := .Rows}}{{$n := add $i $.Start}}<li class="item">
<div class="rank{{if lt $n 3}} m{{end}}">{{rankBadge $n}}</div>
{{if $s.AvatarURL}}<img class="av img" src="{{$s.AvatarURL}}" alt="">{{else}}<div class="av sq">{{$s.Avatar}}</div>{{end}}
<div class="body"><div class="name"><span><a href="{{$s.Path}}">{{$s.Name}}</a></span>{{if eq $s.ID $.Me}}<span class="me">{{T "就是我"}}</span>{{else if eq $s.ID $.Here}}<span class="me here">{{T "本站"}}</span>{{end}}</div><div class="sub">{{if $s.Title}}{{T $s.Title}} · {{end}}{{(level $s.Exp).Title}} · {{$s.Donors}} {{T "位施主 · 钢镚"}} {{$s.Coins}}</div></div>
<div class="amtv num{{if ne $.By "coins"}} accent{{end}}">{{if eq $.By "coins"}}{{template "coin"}} {{$s.Coins}}{{else}}{{fmtAmt $s.TotalE8}}{{end}}</div>
</li>{{end}}
</ul>{{else}}<div class="empty"><div class="ico">🏚</div>{{T "还没有人上榜"}}</div>{{end}}{{end}}
{{define "scripts"}}<script>
(function(){
var tabs=document.querySelectorAll('.tab'),panels=document.querySelectorAll('.panel');
function show(t){tabs.forEach(function(x){var on=x.dataset.t===t;x.classList.toggle('on',on);x.setAttribute('aria-selected',on?'true':'false')});panels.forEach(function(p){p.classList.toggle('on',p.id==='p-'+t)})}
tabs.forEach(function(t){t.addEventListener('click',function(){show(t.dataset.t);try{history.replaceState(null,'','#'+t.dataset.t)}catch(e){}})});
var m=/^#(donors|beggars|feed|popular)(-week)?$/.exec(location.hash);
if(m){show(m[1]);if(m[2])setTimeout(function(){var wb=document.querySelector('.toggle[data-for="'+m[1]+'"] button[data-w="week"]');if(wb)wb.click()},0)}
document.querySelectorAll('.toggle').forEach(function(tg){var k=tg.dataset.for;tg.querySelectorAll('button').forEach(function(b){b.addEventListener('click',function(){tg.querySelectorAll('button').forEach(function(x){x.classList.toggle('on',x===b)});document.querySelector('.'+k+'-all').hidden=b.dataset.w!=='all';document.querySelector('.'+k+'-week').hidden=b.dataset.w!=='week'})})});
var ty=document.querySelector('.typer');
if(ty&&!matchMedia('(prefers-reduced-motion: reduce)').matches){var full=ty.dataset.text,i=0;ty.textContent='';(function step(){ty.textContent=full.slice(0,++i);if(i<full.length)setTimeout(step,55)})()}
var toast=document.getElementById('toast'),tt;
function say(m){toast.textContent=m;toast.hidden=false;clearTimeout(tt);tt=setTimeout(function(){toast.hidden=true},2200)}
var cb=document.getElementById('coinbtn');
if(cb){cb.addEventListener('click',function(){cb.disabled=true;var fd=new FormData();fd.append('site',cb.dataset.site);
fetch('/coin',{method:'POST',body:fd}).then(function(r){return r.json()}).then(function(j){
if(j.ok&&j.added){document.querySelectorAll('.coinN').forEach(function(el){el.textContent=j.total});document.getElementById('coinT').textContent=j.today;
var c=document.createElement('div');c.className='flycoin';c.textContent='🪙';var r=cb.getBoundingClientRect();c.style.left=(r.left+r.width/2)+'px';c.style.top=r.top+'px';document.body.appendChild(c);setTimeout(function(){c.remove()},900);
var sw=document.querySelector('.char-top .sprite-wrap');if(sw){sw.classList.add('jump');setTimeout(function(){sw.classList.remove('jump')},900)}
if(window.sfx)sfx.coin();say({{T "叮!钢镚 +1"}});if(j.mine>=j.per_day){document.getElementById('coinTxt').textContent={{T "今天丢过了"}}}else{cb.disabled=false}}
else{if(window.sfx)sfx.fail();say(j.msg||{{T "没丢进去"}});if(j.mine>=j.per_day){document.getElementById('coinTxt').textContent={{T "今天丢过了"}}}else{cb.disabled=false}}
}).catch(function(){if(window.sfx)sfx.fail();say({{T "网络开小差了"}});cb.disabled=false})})}
var f=document.getElementById('f');if(!f)return;
var btns=f.querySelectorAll('.amt-btn'),amt=document.getElementById('amount'),cta=document.getElementById('cta'),msg=document.getElementById('msg'),cnt=document.getElementById('cnt');
var cur={{.Site.Currency}};
function sel(b){btns.forEach(function(x){x.classList.remove('on')});if(b)b.classList.add('on')}
function custom(){return f.querySelector('.amt-btn[data-v=""]')}
function label(){cta.textContent=amt.value?{{T "投币"}}+' '+amt.value+' '+cur+' 💸':{{T "投币 💸"}}}
function sync(){var hit=null;btns.forEach(function(b){if(b.dataset.v&&b.dataset.v===amt.value)hit=b});sel(hit||(amt.value?custom():null));amt.style.display=(hit&&hit.dataset.v)?'none':'';label()}
btns.forEach(function(b){b.addEventListener('click',function(){if(b.dataset.v){amt.value=b.dataset.v;sync()}else{amt.value='';sel(b);amt.style.display='';amt.focus();label()}})});
amt.addEventListener('input',function(){var hit=null;btns.forEach(function(b){if(b.dataset.v&&b.dataset.v===amt.value)hit=b});sel(hit||custom());label()});
function count(){cnt.textContent=msg.value.length+'/80'}msg.addEventListener('input',count);count();
if(amt.value){sync()}else if(btns.length>1){btns[Math.min(1,btns.length-2)].click()}
// 投币:按钮打开弹窗(表单从页面移进弹窗),异步下单后同一弹窗切到付款面板,不离开本站
document.documentElement.classList.add('js');
var modal=document.getElementById('modal'),mform=document.getElementById('modalForm'),mbody=document.getElementById('modalBody'),donateSec=document.getElementById('donate'),stopPanel=null,paidDone=false;
function openDonate(ev){if(ev)ev.preventDefault();if(donateSec.parentNode!==mform)mform.appendChild(donateSec);mform.hidden=false;mbody.hidden=true;modal.hidden=false;var n=document.getElementById('nick');if(n&&!n.value&&!matchMedia('(max-width:899px)').matches)n.focus()}
function closeModal(){modal.hidden=true;if(stopPanel){stopPanel();stopPanel=null}if(paidDone){location.href=location.pathname+'#feed';location.reload()}}
var db=document.getElementById('donateBtn'),fb=document.getElementById('fabBtn');if(db)db.addEventListener('click',openDonate);if(fb)fb.addEventListener('click',openDonate);
if(location.hash==='#donate')openDonate();
document.getElementById('modalX').addEventListener('click',closeModal);
modal.addEventListener('click',function(ev){if(ev.target===modal)closeModal()});
f.addEventListener('submit',function(ev){if(!window.fetch)return;ev.preventDefault();var fd=new FormData(f);fd.append('ajax','1');cta.disabled=true;var old=cta.textContent;cta.textContent='下单中…';
var errEl=f.querySelector('.err');if(!errEl){errEl=document.createElement('div');errEl.className='err';cta.parentNode.insertBefore(errEl,cta)}errEl.textContent='';
fetch('/donate',{method:'POST',body:fd}).then(function(r){return r.text().then(function(t){return {ok:r.ok,text:t}})}).then(function(res){cta.disabled=false;cta.textContent=old;
if(!res.ok){errEl.textContent=res.text;return}
mbody.innerHTML=res.text;mform.hidden=true;mbody.hidden=false;modal.hidden=false;modal.querySelector('.modal-box').scrollTop=0;var pp=mbody.querySelector('.paypanel');if(pp){stopPanel=window.initPayPanel(pp,function(){paidDone=true})}
}).catch(function(){cta.disabled=false;cta.textContent=old;errEl.textContent={{T "网络开小差了,再试一次"}}})});
var fab=document.getElementById('fab'),top=document.getElementById('topcard');
if(fab&&top&&'IntersectionObserver' in window){new IntersectionObserver(function(es){fab.classList.toggle('show',!es[0].isIntersecting&&es[0].boundingClientRect.top<0)},{threshold:0}).observe(top)}
})();
</script>{{end}}