aboutsummaryrefslogtreecommitdiffstats
path: root/src/features
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-09-12 07:17:58 -0700
committerAdam Soltys <[email protected]>2026-09-12 07:17:58 -0700
commitd4576229565d9b4411d0d9fc44780da03ef0b47b (patch)
tree3773d0bc0c8e42c0fc71b8ec07c66ab5152f7ca1 /src/features
parentc3befb79b6393e2cf6c3744484699707817fea28 (diff)
downloadcoinosv3-d4576229565d9b4411d0d9fc44780da03ef0b47b.tar.gz
coinosv3-d4576229565d9b4411d0d9fc44780da03ef0b47b.zip
A picture in a post opens full screen, and the paperclip is a button again.
The attach control was a .btn-sm holding a 16px icon, wedged between two full-height buttons — a sliver to aim at on a phone. It's a 48px square the height of the row now, with a 20px clip in it. And tapping an image opens it full screen: the image centred on a dark ground, tap anywhere (or Escape) to close. Posts crop images to 320px so a feed stays a feed, which makes a photograph a thumbnail — this is where you actually look at one. Two details in the viewer. The page underneath stops scrolling while it's open, and the scrollbar gutter the page keeps reserved stands down with it: fixed positioning is sized to the viewport WITHOUT that gutter, so an "inset: 0" backdrop leaves a pale stripe down the side of an otherwise full-screen picture. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_019mrt228Upn9nNCwGixzSLx
Diffstat (limited to 'src/features')
-rw-r--r--src/features/messages.js13
1 files changed, 9 insertions, 4 deletions
diff --git a/src/features/messages.js b/src/features/messages.js
index 24c9006..e95bfeb 100644
--- a/src/features/messages.js
+++ b/src/features/messages.js
@@ -2563,8 +2563,13 @@ export function messagesFeature(ctx) {
if (!part) continue;
if (/^https?:\/\//i.test(part)) {
if (/\.(png|jpe?g|gif|webp|avif)(\?[^\s]*)?$/i.test(part)) {
- out.push(h('img', { src: part, class: 'note-img', loading: 'lazy',
- onError: (e) => { e.target.style.display = 'none'; } }));
+ // tap it to see it properly — a 320px-tall crop of someone's
+ // photograph is a thumbnail, not the picture they posted
+ out.push(h('img', {
+ src: part, class: 'note-img clickable', loading: 'lazy',
+ onClick: (e) => { e.stopPropagation(); ctx.openImage && ctx.openImage(part); },
+ onError: (e) => { e.target.style.display = 'none'; },
+ }));
} else if (/\.(mp4|webm|mov|m4v)(\?[^\s]*)?$/i.test(part)) {
// metadata-only preload: the poster frame paints, nothing streams
// until the viewer presses play
@@ -3324,7 +3329,7 @@ export function messagesFeature(ctx) {
} catch (e) { toast(e.message || String(e)); }
ui.postUploading = false; render();
}
- const CLIP = '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="display:block"><path d="M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48"/></svg>';
+ const CLIP = '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="display:block"><path d="M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48"/></svg>';
function postComposer() {
if (ui.profCompose == null && !draftFor(POST_DRAFT)) return null;
const text = composeText();
@@ -3355,7 +3360,7 @@ export function messagesFeature(ctx) {
}
} }, t('profPostBtn')),
ctx.uploadImage ? h('button', {
- class: 'btn-sm', title: t('feedAttach'), disabled: !!ui.postUploading,
+ class: 'attach-btn', title: t('feedAttach'), 'aria-label': t('feedAttach'), disabled: !!ui.postUploading,
onClick: () => document.getElementById('post-file')?.click(),
}, ui.postUploading ? h('span', { class: 'spinner sm' }) : h('span', { style: 'display:flex', html: CLIP })) : null,
h('input', {