From 5b801514b2cadcea437c5f6ab1b901d52aaf1a6d Mon Sep 17 00:00:00 2001 From: Bashy Date: Thu, 4 Jun 2026 20:09:57 +0300 Subject: [PATCH] Replace platform checkboxes with pill toggles in social scheduler Target selection is now a row of compact pills (per platform+target) instead of grouped checkbox lists. Clicking a pill toggles it active; the image icon inside only activates when the pill is selected. Co-Authored-By: Claude Sonnet 4.6 --- web/assets/css/app.css | 15 +++++++++ web/assets/js/app.js | 75 ++++++++++++++++++++---------------------- 2 files changed, 51 insertions(+), 39 deletions(-) diff --git a/web/assets/css/app.css b/web/assets/css/app.css index 74ac723..295a467 100644 --- a/web/assets/css/app.css +++ b/web/assets/css/app.css @@ -458,6 +458,21 @@ pre { color: #e6edf3; } .social-platform-mastodon { background: rgba(99,100,255,.25); color: #a29cf4; border-color: rgba(99,100,255,.4); } .social-platform-linkedin { background: rgba(10,102,194,.25); color: #5ba3d9; border-color: rgba(10,102,194,.4); } +.social-pill { + display: inline-flex; align-items: center; gap: 5px; + padding: 3px 10px; border-radius: 999px; + border: 1px solid var(--hm-border); cursor: pointer; + font-size: .8rem; color: var(--hm-muted); + background: transparent; user-select: none; transition: all .15s; +} +.social-pill:hover { border-color: #8b949e; color: #c9d1d9; } +.social-pill.active[data-platform="discord"] { background: rgba(88,101,242,.2); border-color: rgba(88,101,242,.7); color: #9aa0f5; } +.social-pill.active[data-platform="mastodon"] { background: rgba(99,100,255,.2); border-color: rgba(99,100,255,.7); color: #a29cf4; } +.social-pill.active[data-platform="linkedin"] { background: rgba(10,102,194,.2); border-color: rgba(10,102,194,.7); color: #5ba3d9; } +.social-pill-img { opacity: .35; font-size: .75em; transition: opacity .15s; } +.social-pill:hover .social-pill-img { opacity: .6; } +.social-pill.img-on .social-pill-img { opacity: 1; } + .social-post-card .card-body { border-left: 3px solid transparent; border-radius: inherit; } .social-post-card.status-pending .card-body { border-left-color: #e3b341; } .social-post-card.status-done .card-body { border-left-color: #3fb950; } diff --git a/web/assets/js/app.js b/web/assets/js/app.js index 1f2dc8a..4d39630 100644 --- a/web/assets/js/app.js +++ b/web/assets/js/app.js @@ -3896,55 +3896,52 @@ window.addEventListener('DOMContentLoaded', () => { el.innerHTML = '
No eligible projects configured. Go to Settings to enable projects.
'; return; } - const platformIcon = { discord: 'bi-discord', mastodon: 'bi-mastodon', linkedin: 'bi-linkedin' }; - const platformLabel = { discord: 'Discord', mastodon: 'Mastodon', linkedin: 'LinkedIn' }; - el.innerHTML = _targets.map(group => { - const platforms = ['discord', 'mastodon', 'linkedin'].filter(p => group.targets[p]?.length); - if (!platforms.length) return ''; - return `
-
${esc(group.project_name)}
- ${platforms.map(platform => ` -
-
${platformLabel[platform]}
- ${group.targets[platform].map(t => { - const cbId = `st_${group.project_id}_${platform}_${t.key}`; - const imgId = `si_${group.project_id}_${platform}_${t.key}`; - const checked = prefill?.some(x => x.project_id == group.project_id && x.platform === platform && x.target_key === t.key) ? 'checked' : ''; - const imgChecked = prefill?.some(x => x.project_id == group.project_id && x.platform === platform && x.target_key === t.key && x.include_image) ? 'checked' : ''; - return `
- - - - -
`; - }).join('')} -
`).join('')} -
`; - }).join(''); + const pills = _targets.flatMap(group => + ['discord', 'mastodon', 'linkedin'].flatMap(platform => + (group.targets[platform] || []).map(t => { + const active = prefill?.some(x => x.project_id == group.project_id && x.platform === platform && x.target_key === t.key); + const imgOn = prefill?.some(x => x.project_id == group.project_id && x.platform === platform && x.target_key === t.key && x.include_image); + return ``; + }) + ) + ); + + el.innerHTML = `
${pills.join('')}
`; + + el.querySelectorAll('.social-pill').forEach(pill => { + pill.addEventListener('click', e => { + if (e.target.closest('.social-pill-img')) { + if (pill.classList.contains('active')) pill.classList.toggle('img-on'); + return; + } + pill.classList.toggle('active'); + if (pill.classList.contains('active') && _hasImage) pill.classList.add('img-on'); + else if (!pill.classList.contains('active')) pill.classList.remove('img-on'); + }); + }); } function toggleImageCols(show) { _hasImage = show; - page.querySelectorAll('.social-img-cb, .social-img-cb + label').forEach(el => { - el.classList.toggle('d-none', !show); - }); - if (show) page.querySelectorAll('.social-img-cb').forEach(cb => { cb.checked = true; }); + page.querySelectorAll('.social-pill-img').forEach(el => el.classList.toggle('d-none', !show)); + if (show) page.querySelectorAll('.social-pill.active').forEach(p => p.classList.add('img-on')); + if (!show) page.querySelectorAll('.social-pill').forEach(p => p.classList.remove('img-on')); } function collectTargets() { const targets = []; - page.querySelectorAll('.social-target-cb:checked').forEach(cb => { - const imgCb = page.querySelector(`.social-img-cb[data-for="${cb.id}"]`); + page.querySelectorAll('.social-pill.active').forEach(pill => { targets.push({ - project_id: +cb.dataset.pid, - platform: cb.dataset.platform, - target_key: cb.dataset.key, - include_image: imgCb?.checked ? 1 : 0, + project_id: +pill.dataset.pid, + platform: pill.dataset.platform, + target_key: pill.dataset.key, + include_image: pill.classList.contains('img-on') ? 1 : 0, }); }); return targets;