Badge posts: manual Post to Telegram is admin-only; members' badges still post automatically on unlock

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
martbost
2026-09-13 17:09:59 -05:00
parent 964a02a342
commit e63bc57a99
4 changed files with 13 additions and 8 deletions
+8 -5
View File
@@ -87,13 +87,16 @@
return '<div class="badge-a' + (got ? '' : ' locked') + '">'
+ '<img class="badge-img" src="' + b.img + '" alt="' + b.label + ' badge" loading="lazy">'
+ '<div class="bl">' + b.label + '</div><div class="bs">' + b.sub + '</div>'
+ (got ? '<button class="share" data-badge="' + b.key + '">Share</button> <button class="share" data-badgepost="' + b.key + '">Post to Telegram</button>' : '<div class="bs">🔒 locked</div>') + '</div>';
+ (got ? '<button class="share" data-badge="' + b.key + '">Share</button> <button class="share" data-badgepost="' + b.key + '" hidden>Post to Telegram</button>' : '<div class="bs">🔒 locked</div>') + '</div>';
}).join('');
strip.querySelectorAll('[data-badge]').forEach(btn =>
btn.addEventListener('click', () => shareBadge(btn.dataset.badge, d)));
strip.querySelectorAll('[data-badgepost]').forEach(btn =>
btn.addEventListener('click', () => postBadge(btn.dataset.badgepost, d, btn)));
fetch('/api/my/badge-posted').then(r => r.json()).then(r => (r.posted || []).forEach(k => { const b = strip.querySelector('[data-badgepost="' + k + '"]'); if (b) { b.textContent = 'Posted ✓'; b.disabled = true; } })).catch(() => {});
btn.addEventListener('click', () => postBadge(btn.dataset.badgepost, d, btn, true)));
fetch('/api/my/badge-posted').then(r => r.json()).then(r => { // the manual button is the admin's only (Marty, 2026-09-13)
if (r.canPost) strip.querySelectorAll('[data-badgepost]').forEach(b => { b.hidden = false; });
(r.posted || []).forEach(k => { const b = strip.querySelector('[data-badgepost="' + k + '"]'); if (b) { b.textContent = 'Posted ✓'; b.disabled = true; } });
}).catch(() => {});
// celebrate anything newly granted this load, and post the branded badge to the team channels (Marty, 2026-09-13)
if (d.milestonesGranted && d.milestonesGranted.length) {
const total = d.milestonesGranted.reduce((s, g) => s + g.credited, 0);
@@ -124,14 +127,14 @@
img.onerror = () => cb(null);
img.src = b.img;
}
async function postBadge(key, d, btn) {
async function postBadge(key, d, btn, manual) {
if (btn && btn.disabled) return;
if (btn) { btn.disabled = true; btn.textContent = 'Posting…'; }
composeBadge(key, d, c => {
if (!c) { if (btn) { btn.disabled = false; btn.textContent = 'Post to Telegram'; } return; }
c.toBlob(async bl => {
try {
const r = await (await fetch('/api/my/badge-post?key=' + encodeURIComponent(key), { method: 'POST', headers: { 'Content-Type': 'image/jpeg' }, body: bl })).json();
const r = await (await fetch('/api/my/badge-post?key=' + encodeURIComponent(key) + (manual ? '&manual=1' : ''), { method: 'POST', headers: { 'Content-Type': 'image/jpeg' }, body: bl })).json();
if (r.error) throw new Error(r.error);
if (btn) { btn.textContent = 'Posted ✓'; btn.disabled = true; }
if (!r.already) IAP.status('Your badge is posted in the team channels.', 'ok');
+1 -1
View File
@@ -915,7 +915,7 @@
<script src="/assets/common.js?v=20260913a"></script>
<script src="/assets/wallet.js?v=20260911a"></script>
<script src="/assets/promo.js?v=20260911a"></script>
<script src="/assets/my.js?v=20260913g"></script>
<script src="/assets/my.js?v=20260913h"></script>
<script src="/assets/chat.js?v=20260907l"></script>
</body>
</html>