-
Notifications
You must be signed in to change notification settings - Fork 3
feat: splits #160
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat: splits #160
Conversation
8b9255d to
a5bcb77
Compare
early draft, forgot to delete
a2d3db1 to
0fc4c86
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR implements a comprehensive split view feature that allows users to view multiple Twitch chats simultaneously. The implementation uses a binary tree structure to manage split layouts with configurable behavior through new settings. Key features include drag-and-drop split management, keyboard shortcuts for split operations (Ctrl/Cmd+T to add, Ctrl/Cmd+W to close), and persistent layout restoration.
Key Changes:
- Binary tree-based split layout system with horizontal/vertical panes
- Five new settings controlling split behavior (orientation, restore, close, and auto-leave options)
- Keyboard navigation between splits and keyboard shortcuts for split management
- Drag-and-drop support for reordering and rearranging splits
- Layout persistence across application restarts
Reviewed changes
Copilot reviewed 29 out of 30 changed files in this pull request and generated 15 comments.
Show a summary per file
| File | Description |
|---|---|
src/lib/split-layout.ts |
Core split layout management class implementing binary tree operations, navigation, and drag-drop handling |
src/routes/(main)/channels/split/SplitView.svelte |
Individual split view component with drag-drop zones and empty state |
src/routes/(main)/channels/split/SplitNode.svelte |
Recursive component rendering split tree with resizable panes |
src/routes/(main)/channels/split/SplitHeader.svelte |
Split header with controls for adding splits and closing |
src/routes/(main)/channels/split/+page.svelte |
Main split page with keyboard navigation between splits |
src/routes/settings/categories/splits.ts |
Settings definitions for split behavior configuration |
src/lib/settings.ts |
Added split-related settings types and default values |
src/lib/stores.ts |
New layout store for persisting split state |
src/routes/(main)/channels/+layout.svelte |
Keyboard shortcuts for split operations (Ctrl/Cmd+T and Ctrl/Cmd+W) |
src/routes/(main)/+layout.svelte |
DragDropProvider setup and drag overlay component |
src/routes/(main)/+page.svelte |
Layout restoration logic on app startup |
src/lib/components/Channel.svelte |
Extracted channel view component for reuse in splits |
src/lib/menus/channel-menu.ts |
Added split-related menu items for opening and arranging channels |
src/lib/components/DraggableChannel.svelte |
New draggable wrapper for channel list items |
src/lib/models/channel.svelte.ts |
Added split parameter to join method |
package.json & pnpm-lock.yaml |
Added paneforge dependency for resizable panes |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| <Pane defaultSize={node.size ?? 50} onResize={(size) => (node.size = size)}> | ||
| <Self bind:node={node.before} /> | ||
| </Pane> | ||
|
|
||
| <PaneResizer | ||
| class={[ | ||
| "bg-muted relative flex items-center justify-center transition-colors hover:bg-blue-400", | ||
| node.axis === "horizontal" ? "w-1 cursor-col-resize" : "h-1 cursor-row-resize", | ||
| ]} | ||
| /> | ||
|
|
||
| <Pane defaultSize={100 - (node.size ?? 50)} onResize={(size) => (node.size = 100 - size)}> | ||
| <Self bind:node={node.after} /> |
Copilot
AI
Dec 11, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The onResize callbacks directly mutate the node.size property. Since node is passed as a bindable prop, this could cause reactivity issues or infinite update loops in Svelte 5. Additionally, the calculation 100 - size for the second pane assumes the first pane's new size, but if the sizes don't sum to 100 due to rounding or precision issues, this could cause layout inconsistencies. Consider validating that the sizes remain synchronized or handle the resize state more carefully.
Splits allow multiple chats to be viewed at once. A multitude of new settings have been added to control the behavior of splits to make sure UX can be tailored. I set defaults to what I believe is most intuitive.
A couple of keyboard shortcuts have also been added:
Ctrl/Cmd+Twill add a new splitCtrl/Cmd+Wwill close the focused splitAs well as new channel menu items.
Internally, splits are represented as a binary tree (never thought I'd see the day). Because splits can be arranged horizontally and vertically, I named the branches
beforeandafterto avoid confusion with the spatial representations ofleftandright.Closes #15