From 84e778d5cdd1bb5cded8a7c0238797c17d48666c Mon Sep 17 00:00:00 2001 From: Christophe Besson Date: Sun, 16 Aug 2026 15:29:11 +0200 Subject: feat(hub): chat, presence, a Profile page, and downloads that do not freeze MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Chat opens on the newest hundred messages, loads fifty older on demand with the reading position anchored — the distance from the *bottom*, since everything above the viewport just grew — and follows new messages only when the reader was already at the end. Day separators, sender grouping, an unread marker, and a jump-to-latest pill. Messages are keyed by id: index keys plus prepending makes Preact reuse the wrong bubbles. A presence dot per group in the sidebar, three states, each backed by something: the hub's registry, or a connection this browser made or failed to make. Never colour alone — red and green are the pair colour-blind readers cannot separate — so each dot carries a title and an aria-label. Profile is split out of Settings: identity, node link, pinned node identities and account deletion. Mixing them put an irreversible button two scrolls under a theme picker. The create-group page loses its centred 520 px card, which left 190 px of margin either side, and its two button panels become a radio group — a button conveys no chosen state to a screen reader, and side by side they read as two independent actions rather than one either/or. The Files toolbar shows its actions as icon buttons the moment Select is on, disabled when they do not apply rather than appearing and vanishing. On a phone the right-hand group could not wrap and ran 130 px off the screen. Streamed downloads no longer freeze after one chunk. `registration.active` says a worker exists, not that this page is controlled by it — and an uncontrolled page's requests never reach its fetch handler, so the worker took the stream and was never asked for it, leaving `writer.write()` waiting on backpressure that would never lift. The page now requires control and the worker confirms it actually served the request before the sink is trusted. Fixed on the way: `setActionsOpen` outlived the state it belonged to and threw on every Files action; the chat scrollbar stopped short of the bottom; the owner's row sat lower than the rest; About showed a version hardcoded two releases ago. Co-Authored-By: Claude Opus 5 --- .../meshbay-hub/src/meshbay_hub/static/locales/zh-CN.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'packages/meshbay-hub/src/meshbay_hub/static/locales/zh-CN.js') diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/zh-CN.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/zh-CN.js index bfa6d05..40a40a4 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/locales/zh-CN.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/zh-CN.js @@ -373,4 +373,21 @@ export default { other: '找到 {n} 个文件', }, 'search.hint': '在所有已缓存的群组索引中搜索文件名。', + + // Presence, chat paging, leaving a group, the profile page + 'presence.online': '有一个服务本群组的 node 在线', + 'presence.offline': '本群组没有可达的 node', + 'presence.unknown': '尚未检测', + 'chat.load_older': '加载更早的 {n} 条消息', + 'chat.start_of_history': '对话开头', + 'chat.today': '今天', + 'chat.yesterday': '昨天', + 'chat.unread': '新消息', + 'chat.jump_latest': '跳到最新', + 'chat.jump_new': '新消息', + 'group.leave': '退出群组', + 'group.leave_confirm': '退出“{name}”?您将失去其文件和聊天的访问权。您上传的文件仍留在 node 上,node 也会保留它为您固定的身份,直到其运营者将其移除。', + 'profile.title': '个人资料', + 'usermenu.profile': '个人资料', + 'create_group.public_is_open': '任何人都可以找到并加入公开群组。若要挑选谁能进来,请创建为私密群组。', }; -- cgit v1.2.3