Skip to content

Releases: kernoeb/secousse

Secousse v0.3.5

17 May 17:34

Choose a tag to compare

Fix

  • Chat reconnection cascade. A duplicate chat-disconnected event from the Rust side was triggering parallel reconnect attempts, each one aborting the previous (single-slot chat) and re-emitting another disconnect — snowballing into seconds-long chat freezes whenever Twitch reset the WebSocket. Fixed by emitting once and coalescing duplicates on the frontend.

Full changelog: v0.3.4...v0.3.5

Secousse v0.3.4

17 May 16:14

Choose a tag to compare

Player

  • Fix 1-2s black screen at stream start — the loading spinner now stays visible until the first frame is actually decoded, not just when the HLS manifest is parsed.
  • Player overlay, cursor and the open-chat button now auto-hide when the pointer is idle for cleaner viewing.

Chat

  • Open-chat button repositions correctly when the navbar is hidden in fullscreen.

Secousse v0.3.3

17 May 15:37

Choose a tag to compare

HLS streaming

  • Low-latency parity with Twitch web via progressive prefetch loader — playlist #EXT-X-TWITCH-PREFETCH tags are rewritten into standard #EXTINF pairs and segments stream chunk-by-chunk into MSE while the encoder is still producing them.
  • Bandwidth/ABR fix: TTFB is now recorded at headers received instead of after the body is fully read, preventing inflated bandwidth estimates that pinned ABR to the top quality level.

Performance

  • Repaints isolated per chat/tile and the video element promoted to its own GPU layer on WebKit — smoother scrolling and fewer dropped frames in multi-stream grid.
  • Heavy consumers (chat, emotes, stream info) are deferred when focus shifts between grid tiles so the focus switch itself stays responsive.

Windows

  • Updater no longer auto-relaunches Secousse after installing on close — the NSIS installer's /R flag is now suppressed via a custom installerHooks.

Misc

  • Dependencies bumped to latest compatible versions; Cargo.lock realigned with manifest constraints.

Secousse v0.3.2

16 May 17:44

Choose a tag to compare

UI improvements

  • macOS title bar: forced to dark and matched to the navbar color (no more inconsistency with a light system theme).
  • Collapsed sidebar: content re-centered and scrollbar cleanly hidden.
  • Navbar / chat: removed the misleading "clickable" affordance on the navbar avatar and the user icon in chat.

Full changelog: v0.3.1...v0.3.2

Secousse v0.3.1

16 May 16:39

Choose a tag to compare

Fixes

  • Title bar followed the Windows theme/accent color, not the app's dark UI. On Windows 11, the native title bar inherits the OS theme and, if the user has enabled "Show accent color on title bars and window borders" in Personalization, that accent paints over even the dark theme. Tauri's .theme(Theme::Dark) only affects the WebView's prefers-color-scheme, not the native chrome. We now call DwmSetWindowAttribute directly with DWMWA_USE_IMMERSIVE_DARK_MODE, DWMWA_CAPTION_COLOR, and DWMWA_TEXT_COLOR on every window creation (main + pop-outs) so the title bar stays dark regardless of OS theme or accent color.

  • Sidebar scrollbar overlapped channel avatars on Windows. The default Windows scrollbar rendered as an inset overlay and stole pixels from the rightmost column when the followed-channels list grew long. The scrollbar now auto-hides until hover so avatars stay fully visible.

Full changelog: v0.3.0...v0.3.1

Secousse v0.3.0

16 May 15:10

Choose a tag to compare

Features

  • Silent auto-update. Secousse now checks for new versions on launch and downloads them in the background, then applies the update only when you quit the app. No mid-session restart, no popup. macOS/Linux users will see the new version the next time they launch; on Windows the NSIS installer runs during the quit you already initiated.

  • Real native fullscreen with a global toggle for the multi-stream grid. Fullscreen used to be a CSS fixed inset-0 overlay that left the OS window normal — broken with multi-monitor, broken on Windows. Now it calls Tauri's setFullscreen API so the OS window itself goes fullscreen on macOS/Windows/Linux. The navbar, sidebar, stream info panel and pop-out header all hide in that state; chat stays available. A dedicated toolbar above the multi-stream grid hosts the global Fullscreen button so it isn't mistaken for a per-tile control.

  • Chat scrollbar hides while auto-following live messages. The thin scrollbar in chat only appears once you've actually scrolled away from the bottom. The gutter is still reserved so content doesn't shift when the scrollbar toggles in/out.

Fixes

  • Trackpad rubber-band on the page root felt out of place (macOS). The app has its own internal scrollable panels and the page itself never needed to scroll, but the trackpad bounce was hitting the root scroller anyway. The html element is now locked with overflow: hidden + overscroll-behavior: none, with body pinned to a fixed viewport height so flex children size correctly.

  • Native Windows scrollbar in the sidebar was visually jarring. A new .scrollbar-thin utility is applied to every scrollable container, and a parasitic horizontal scroll axis in the followed-channels column is clipped (overflow-x-hidden + min-w-0).

  • Collapsed-sidebar channel tooltip was invisible. It was clipped by the scroll container's overflow-y-auto and never rendered. Now uses position: fixed with hover-time getBoundingClientRect() so it escapes the clip.

This is the seed release for the updater — users on v0.2.1 must install v0.3.0 manually, but from v0.3.0 onward updates land automatically.

Full changelog: v0.2.1...v0.3.0

Secousse v0.2.1

15 May 21:08

Choose a tag to compare

Fixes

  • Chat listener leak that cascaded into a WebSocket storm. The disconnect listener in useChat registered its Tauri handler via an async await listen(...) whose unlisten function was stored in a ref. If the effect's cleanup ran before that promise resolved (typical when switching focus rapidly inside the multi-stream grid), the cleanup saw a null ref and did nothing — the listener slot was then overwritten by the next effect run and the original handler leaked. Each leaked listener also received chat-disconnected events and scheduled its own 2-second-delayed connect_to_chat, so a single Twitch-side disconnect produced N concurrent reconnect invocations on the same channel. Symptoms in the logs were repeated Chat disconnected from: <channel> entries from distinct user-script:NN slots and floods of duplicate USERNOTICE messages; on screen this could degrade into the WebView going black during chat scroll under load. Track the unlisten in a local variable with a cancelled flag so an in-flight listen() is torn down as soon as it resolves.

Full changelog: v0.2.0...v0.2.1

Secousse v0.2.0

15 May 19:05

Choose a tag to compare

Highlights

Watch up to four streams at once in a split-screen grid, or detach any stream into its own always-on-top window. Audio routes automatically to whichever tile you click — no more juggling tabs during raids, tournaments, or multi-POV events.

Features

  • Multi-stream grid (1–4 tiles). Shift+click a channel in the sidebar or the browse grid to add it to a CSS-grid layout. Click any tile to focus it: the focused tile owns the audio, the chat, and the stream info panel. Per-tile remove (×) and pop-out buttons in the hover overlay. Layout adapts automatically: 1 col for solo, 2×1 for duos, 3×1 / 2×2 beyond.
  • Pop-out windows. Detach a stream into an independent Tauri window via the ↗ icon (sidebar, browse card, or grid tile). Pop-out has a minimal header with toggleable chat and an always-on-top pin. Re-opening a pop-out for the same channel focuses the existing window instead of duplicating it. Each pop-out tracks the current channel in its URL, so reloads stay on the same stream.
  • Persistent grid. Your tile layout and focused tile are restored on launch. Single-stream usage stays identical — the grid is [channel] under the hood.

Under the hood

  • Per-channel emote cache (LRU, cap 5). Switching focus inside a grid no longer re-fetches 7TV/BTTV/FFZ/Twitch emote lists. Inflight requests are deduped so two tiles loading the same channel only hit the API once.
  • VideoPlayer gains compact and forceMuted modes. Non-focused tiles render without the fullscreen button and ignore the persisted volume/mute preferences (so flipping focus between tiles doesn't silently clobber your saved volume). Mute button and slider are disabled with a clear visual treatment on muted tiles.
  • useUserInfo hook extracted from App.tsx. Each tile owns its own polling loop, decoupling the focused tile's lifecycle from the rest of the grid.
  • Rust backend: new open_popout command, popout-* capability glob, set_always_on_top and close permissions.

Full changelog: v0.1.5...v0.2.0

Secousse v0.1.5

11 May 20:33

Choose a tag to compare

Highlights

Chat scroll stability fix for users who read older messages while a busy chat keeps flowing in, plus dependency refresh across the stack.

Fixes

  • Stable chat scroll while reading history. When you scroll up to read older messages, the chat now snapshots the message array and renders that fixed copy until you return to the bottom. Previously, virtua's lazy item measurements made the scroll-offset compensation drift every time the cap-300 buffer dropped a message from the front, jerking the viewport upward. Re-follow is triggered from onScrollEnd, which correctly handles macOS trackpad momentum.

Under the hood

  • Bumped Tauri to 2.11, wry 0.54 → 0.55, tokio 1.50 → 1.52, plus full minor/patch refresh of all Rust transitives (tray-icon, rustls, reqwest, …).
  • Bumped Vite to 8.0.12, @vitejs/plugin-react 5 → 6, React 19.2.6, Tailwind 4.3, TypeScript 6.0.3.
  • Added a dev-only chat scroll/freeze test harness for reproducing the read-while-streaming regression locally.

Full changelog: v0.1.4...v0.1.5

Secousse v0.1.4

10 May 19:04

Choose a tag to compare

Highlights

This release fixes a critical WKWebView freeze that affected anyone watching busy chats with animated emotes for more than a few minutes. Memory under stress drops from 2.7 GB peak to ~600 MB.

Fixes

  • Eliminate emote-induced freeze on macOS. Animated emotes now decode in Rust and render via <canvas>, side-stepping the WKWebView per-<img> ImageFrameWorkQueue allocation that saturates the macOS dispatch pool (~512 workers/process) and freezes the app within minutes on busy chats. Stress-tested at 80 msg/s × 6 emotes/msg with 581 unique emotes (242 animated): peak RSS 600 MB vs 2.7 GB before, steady ~200 MB, no leak.
  • Fix Sidebar crash on banned channels in top streams. Twitch's GraphQL response occasionally includes top-streams entries with a null broadcaster (banned/suspended channels still in the cache); these now get filtered out before reaching the UI.

Under the hood

  • New Rust command decode_emote (WebP / GIF / PNG / JPEG, animated or static), downscaled to 48 px (pixel-perfect on Retina), serialized as a single binary blob over IPC.
  • New <EmoteImg> React component with global cache (32 MB byte-budgeted LRU), LIFO decode queue (concurrency 6, prioritizes recently-mounted emotes), and a shared requestAnimationFrame orchestrator that dedupes per-URL frame indexing across all live canvases.

Full changelog: v0.1.3...v0.1.4