190 lines
19 KiB
HTML
190 lines
19 KiB
HTML
{{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}}
|