aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-10-08 23:05:34 -0700
committerAdam Soltys <[email protected]>2026-10-08 23:05:34 -0700
commitf3545a79caf0f76eeaa0b99a65bbcab1b52506d0 (patch)
tree06c0a8368436f901044f8aa6a0e9c25bc00952cb /src
parentf555cba5723453fc48dfbcba234da351b37db2f0 (diff)
downloadcoinosv3-f3545a79caf0f76eeaa0b99a65bbcab1b52506d0.tar.gz
coinosv3-f3545a79caf0f76eeaa0b99a65bbcab1b52506d0.zip
Chip strips drag sideways with a mouse (a drag doesn't click the chip it started on) and show a thin scrollbar on mouse devices, so the feed chips that run past the card are reachable on desktop
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/app.js32
-rw-r--r--src/style.css8
2 files changed, 40 insertions, 0 deletions
diff --git a/src/app.js b/src/app.js
index bf49dd1..9d5c86e 100644
--- a/src/app.js
+++ b/src/app.js
@@ -6328,6 +6328,38 @@ if (INTENT_URI) {
}, 500);
}
+// Chip strips (the feed chips, a profile's lists) scroll sideways: a finger
+// swipes them, a mouse drags them. A drag that moved isn't a click on the
+// chip it started on.
+(() => {
+ let drag = null;
+ document.addEventListener('pointerdown', (e) => {
+ if (e.pointerType !== 'mouse' || e.button !== 0) return;
+ const el = e.target.closest && e.target.closest('.feed-chips');
+ if (!el || el.scrollWidth <= el.clientWidth) return;
+ drag = { el, x: e.clientX, left: el.scrollLeft, moved: false };
+ });
+ document.addEventListener('pointermove', (e) => {
+ if (!drag) return;
+ const dx = e.clientX - drag.x;
+ if (!drag.moved && Math.abs(dx) < 5) return;
+ drag.moved = true;
+ drag.el.classList.add('dragging');
+ drag.el.scrollLeft = drag.left - dx;
+ });
+ const end = () => {
+ if (!drag) return;
+ const d = drag; drag = null;
+ d.el.classList.remove('dragging');
+ if (!d.moved) return;
+ const eat = (ev) => { ev.stopPropagation(); ev.preventDefault(); };
+ document.addEventListener('click', eat, { capture: true, once: true });
+ setTimeout(() => document.removeEventListener('click', eat, { capture: true }), 0); // a release off the strip has no click to eat
+ };
+ document.addEventListener('pointerup', end);
+ document.addEventListener('pointercancel', () => { if (drag) drag.el.classList.remove('dragging'); drag = null; });
+})();
+
window.addEventListener('load', () => {
if (!pendingMigratedName()) return;
const started = Date.now();
diff --git a/src/style.css b/src/style.css
index dabd7be..9b5f5d9 100644
--- a/src/style.css
+++ b/src/style.css
@@ -703,6 +703,14 @@ html:has(#app .chat-card), body:has(#app .chat-card) { overflow: hidden; }
/* the feeds row: pills that scroll sideways, the one on screen filled */
.feed-chips { gap: 6px; flex-wrap: nowrap; overflow-x: auto; margin: 0 -14px; padding: 2px 14px; scrollbar-width: none; -webkit-overflow-scrolling: touch; }
.feed-chips::-webkit-scrollbar { display: none; }
+/* with a mouse: a thin bar says the strip scrolls, and it drags (app.js) */
+@media (hover: hover) and (pointer: fine) {
+ .feed-chips { scrollbar-width: thin; scrollbar-color: var(--line-strong) transparent; padding-bottom: 6px; cursor: grab; }
+ .feed-chips::-webkit-scrollbar { display: block; height: 6px; }
+ .feed-chips::-webkit-scrollbar-thumb { background: var(--line-strong); border-radius: 3px; }
+ .feed-chips.dragging { cursor: grabbing; user-select: none; }
+ .feed-chips.dragging .feed-chip { pointer-events: none; }
+}
.feed-chip { flex: 0 0 auto; border: 1px solid var(--line); background: var(--surface2); color: var(--muted); border-radius: 999px; padding: 5px 12px; font-size: 14px; line-height: 1.2; cursor: pointer; white-space: nowrap; max-width: 180px; overflow: hidden; text-overflow: ellipsis; }
.feed-chip.on { background: var(--accent); color: var(--accent-fg); border-color: var(--accent); }
.feed-chip.add { font-weight: 600; padding: 5px 11px; }