feat(ui): add desktop git sidebar + terminal dock and improve in-app PR workflow (#362)
* feat: add unified dropdown with services content in header * feat: add right Git sidebar with resizable panel * feat: implement responsive panel auto-toggle and terminal rehydration - Auto-close the right sidebar when width is below a threshold and auto-open it when space permits - Auto-close the bottom terminal when height is below a threshold and auto-open it when enough space - Apply a dedicated rehydrated streaming configuration for terminal sessions to optimize reconnect behavior * feat: enhance PR view with status caching and annotations * feat(ui): enable chat dispatch in PullRequestSection * feat(TerminalView): adjust layout * feat: refine chat input layout and text selection menu * fix(ui): show empty state in GitView when no changes * feat(git): update PR actions styling and create PR button
This commit is contained in:
committed by
GitHub
parent
3f29b2c6a2
commit
5b0a97d170
@@ -24,6 +24,12 @@ interface UIStore {
|
||||
isSidebarOpen: boolean;
|
||||
sidebarWidth: number;
|
||||
hasManuallyResizedLeftSidebar: boolean;
|
||||
isRightSidebarOpen: boolean;
|
||||
rightSidebarWidth: number;
|
||||
hasManuallyResizedRightSidebar: boolean;
|
||||
isBottomTerminalOpen: boolean;
|
||||
bottomTerminalHeight: number;
|
||||
hasManuallyResizedBottomTerminal: boolean;
|
||||
isSessionSwitcherOpen: boolean;
|
||||
activeMainTab: MainTab;
|
||||
mainTabGuard: MainTabGuard | null;
|
||||
@@ -81,6 +87,12 @@ interface UIStore {
|
||||
toggleSidebar: () => void;
|
||||
setSidebarOpen: (open: boolean) => void;
|
||||
setSidebarWidth: (width: number) => void;
|
||||
toggleRightSidebar: () => void;
|
||||
setRightSidebarOpen: (open: boolean) => void;
|
||||
setRightSidebarWidth: (width: number) => void;
|
||||
toggleBottomTerminal: () => void;
|
||||
setBottomTerminalOpen: (open: boolean) => void;
|
||||
setBottomTerminalHeight: (height: number) => void;
|
||||
setSessionSwitcherOpen: (open: boolean) => void;
|
||||
setActiveMainTab: (tab: MainTab) => void;
|
||||
setMainTabGuard: (guard: MainTabGuard | null) => void;
|
||||
@@ -153,6 +165,12 @@ export const useUIStore = create<UIStore>()(
|
||||
isSidebarOpen: true,
|
||||
sidebarWidth: 264,
|
||||
hasManuallyResizedLeftSidebar: false,
|
||||
isRightSidebarOpen: false,
|
||||
rightSidebarWidth: 420,
|
||||
hasManuallyResizedRightSidebar: false,
|
||||
isBottomTerminalOpen: false,
|
||||
bottomTerminalHeight: 300,
|
||||
hasManuallyResizedBottomTerminal: false,
|
||||
isSessionSwitcherOpen: false,
|
||||
activeMainTab: 'chat',
|
||||
mainTabGuard: null,
|
||||
@@ -243,6 +261,76 @@ export const useUIStore = create<UIStore>()(
|
||||
set({ sidebarWidth: width, hasManuallyResizedLeftSidebar: true });
|
||||
},
|
||||
|
||||
toggleRightSidebar: () => {
|
||||
set((state) => {
|
||||
const newOpen = !state.isRightSidebarOpen;
|
||||
|
||||
if (newOpen && typeof window !== 'undefined') {
|
||||
const proportionalWidth = Math.floor(window.innerWidth * 0.28);
|
||||
return {
|
||||
isRightSidebarOpen: newOpen,
|
||||
rightSidebarWidth: proportionalWidth,
|
||||
hasManuallyResizedRightSidebar: false,
|
||||
};
|
||||
}
|
||||
return { isRightSidebarOpen: newOpen };
|
||||
});
|
||||
},
|
||||
|
||||
setRightSidebarOpen: (open) => {
|
||||
set(() => {
|
||||
if (open && typeof window !== 'undefined') {
|
||||
const proportionalWidth = Math.floor(window.innerWidth * 0.28);
|
||||
return {
|
||||
isRightSidebarOpen: open,
|
||||
rightSidebarWidth: proportionalWidth,
|
||||
hasManuallyResizedRightSidebar: false,
|
||||
};
|
||||
}
|
||||
return { isRightSidebarOpen: open };
|
||||
});
|
||||
},
|
||||
|
||||
setRightSidebarWidth: (width) => {
|
||||
set({ rightSidebarWidth: width, hasManuallyResizedRightSidebar: true });
|
||||
},
|
||||
|
||||
toggleBottomTerminal: () => {
|
||||
set((state) => {
|
||||
const newOpen = !state.isBottomTerminalOpen;
|
||||
|
||||
if (newOpen && typeof window !== 'undefined') {
|
||||
const proportionalHeight = Math.floor(window.innerHeight * 0.32);
|
||||
return {
|
||||
isBottomTerminalOpen: newOpen,
|
||||
bottomTerminalHeight: proportionalHeight,
|
||||
hasManuallyResizedBottomTerminal: false,
|
||||
};
|
||||
}
|
||||
|
||||
return { isBottomTerminalOpen: newOpen };
|
||||
});
|
||||
},
|
||||
|
||||
setBottomTerminalOpen: (open) => {
|
||||
set(() => {
|
||||
if (open && typeof window !== 'undefined') {
|
||||
const proportionalHeight = Math.floor(window.innerHeight * 0.32);
|
||||
return {
|
||||
isBottomTerminalOpen: open,
|
||||
bottomTerminalHeight: proportionalHeight,
|
||||
hasManuallyResizedBottomTerminal: false,
|
||||
};
|
||||
}
|
||||
|
||||
return { isBottomTerminalOpen: open };
|
||||
});
|
||||
},
|
||||
|
||||
setBottomTerminalHeight: (height) => {
|
||||
set({ bottomTerminalHeight: height, hasManuallyResizedBottomTerminal: true });
|
||||
},
|
||||
|
||||
setSessionSwitcherOpen: (open) => {
|
||||
set({ isSessionSwitcherOpen: open });
|
||||
},
|
||||
@@ -623,6 +711,14 @@ export const useUIStore = create<UIStore>()(
|
||||
updates.sidebarWidth = Math.floor(window.innerWidth * 0.2);
|
||||
}
|
||||
|
||||
if (state.isRightSidebarOpen && !state.hasManuallyResizedRightSidebar) {
|
||||
updates.rightSidebarWidth = Math.floor(window.innerWidth * 0.28);
|
||||
}
|
||||
|
||||
if (state.isBottomTerminalOpen && !state.hasManuallyResizedBottomTerminal) {
|
||||
updates.bottomTerminalHeight = Math.floor(window.innerHeight * 0.32);
|
||||
}
|
||||
|
||||
return updates;
|
||||
});
|
||||
},
|
||||
@@ -702,6 +798,10 @@ export const useUIStore = create<UIStore>()(
|
||||
theme: state.theme,
|
||||
isSidebarOpen: state.isSidebarOpen,
|
||||
sidebarWidth: state.sidebarWidth,
|
||||
isRightSidebarOpen: state.isRightSidebarOpen,
|
||||
rightSidebarWidth: state.rightSidebarWidth,
|
||||
isBottomTerminalOpen: state.isBottomTerminalOpen,
|
||||
bottomTerminalHeight: state.bottomTerminalHeight,
|
||||
isSessionSwitcherOpen: state.isSessionSwitcherOpen,
|
||||
activeMainTab: state.activeMainTab,
|
||||
sidebarSection: state.sidebarSection,
|
||||
|
||||
Reference in New Issue
Block a user