diff --git a/HANDOFF.md b/HANDOFF.md index 22da774..e943b0c 100644 --- a/HANDOFF.md +++ b/HANDOFF.md @@ -64,8 +64,8 @@ kick kills sync+video, no relay memory growth. - `packages/core/lib/src/`: constants.dart (tuning: seek 300 ms, drift 5 s, slow 1.5 s @0.95, min_buffer 4 s, heartbeat 1 s, ping 5 s, - avatar 128 KiB (base64 chars; any 128x128 PNG fits — raised 09-12 - from 64 KiB, which rejected normal PNGs), name 32, chat 500; dropAfter lives as RoomEngine ctor + avatar 256 KiB (base64 chars; wide headroom over any 128x128 PNG + — raised 09-12 from 64 KiB, which rejected normal PNGs), name 32, chat 500; dropAfter lives as RoomEngine ctor default, now 30 s), errors.dart, logging.dart, config.dart, protocol.dart (v4 schemas), media_source.dart, sync_engine.dart (RoomEngine + quorum in evaluate's HELD branch; PLAYING branch diff --git a/apps/desktop/lib/src/session/session_coordinator.dart b/apps/desktop/lib/src/session/session_coordinator.dart index 0383ee8..da73cd0 100644 --- a/apps/desktop/lib/src/session/session_coordinator.dart +++ b/apps/desktop/lib/src/session/session_coordinator.dart @@ -390,7 +390,11 @@ class SessionCoordinator { // While the room is PLAYING the ready flag gates nothing, so an // idle viewer must never lose it mid-watch. if (room.peek()?.transport != 'playing') { - if (idleSecs >= 8 * 60 && !_warnedIdle) { + // No warning when there is nothing to lose: the 10-min unready + // only fires while self is ready, so the 8-min warning must not + // fire while unready either. + final selfReady = selfMember.peek()?.ready ?? false; + if (selfReady && idleSecs >= 8 * 60 && !_warnedIdle) { _warnedIdle = true; _toastId++; toasts.value = [ diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index 2c972be..20c588b 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -73,7 +73,7 @@ silence-timeout + reconnect loop. Never run: shaper chaos suite ## Phase 6 — Identity & social (PARTIAL) -Shipped: names (32 cap), avatars (128 KiB cap, 128 px PNG picker, transparency kept), kick nudge +Shipped: names (32 cap), avatars (256 KiB cap, 128 px PNG picker, transparency kept), kick nudge + reason, feed attribution. Open: real chat pane/history (schema only), sounds swap-in (wiring + NoopSfxService ready; pick flutter_soloud or equivalent, Kenney/ObsydianX/akx sources in diff --git a/packages/core/lib/src/constants.dart b/packages/core/lib/src/constants.dart index c67ac62..104e970 100644 --- a/packages/core/lib/src/constants.dart +++ b/packages/core/lib/src/constants.dart @@ -15,13 +15,14 @@ abstract class RelayConstants { static const int stateHeartbeatSecs = 1; static const int pingIntervalSecs = 5; - // Base64-char count of the avatar string, enforced at hello. Sized so - // ANY 128x128 pipeline PNG always fits (raw bitmap <= 64 KiB, worst-case - // PNG ~70 KiB raw ~= 95 KiB base64). PNG keeps transparency; JPEG did not. + // Base64-char count of the avatar string, enforced at hello. 256 KiB + // leaves wide headroom over any 128x128 pipeline PNG (raw bitmap + // <= 64 KiB, worst-case base64 ~95 KiB chars) — deliberate over-size + // for private-server use. PNG keeps transparency; JPEG did not. // Trade: avatars ride in the 1 Hz room broadcast, so worst-case host // uplink scales with this cap. Follow-up (not now): send avatar bytes // once, reference by hash afterwards. - static const int maxAvatarBytes = 128 * 1024; + static const int maxAvatarBytes = 256 * 1024; static const int maxNameLength = 32; static const int maxChatLength = 500; }