Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 43 additions & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,29 @@ const globalStyles = css`
-moz-osx-font-smoothing: grayscale;
}

/* Mobile: Improve touch interactions */
@media (max-width: 768px) {
html {
/* Prevent text size adjustment on orientation change */
-webkit-text-size-adjust: 100%;
/* Improve tap responsiveness */
touch-action: manipulation;
}

body {
/* Slightly larger font for better readability on mobile */
font-size: 15px;
}

/* Make buttons and interactive elements easier to tap */
button,
a,
[role="button"] {
min-height: 44px;
min-width: 44px;
}
}

code {
font-family: var(--font-monospace);
}
Expand Down Expand Up @@ -135,19 +158,35 @@ const AppContainer = styled.div`
height: 100vh;
overflow: hidden;
background: #1e1e1e;

/* Mobile: Ensure content takes full width */
@media (max-width: 768px) {
flex-direction: column;
}
`;

const MainContent = styled.div`
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
min-width: 0; /* Allow content to shrink below its minimum content size */

/* Mobile: Take full width */
@media (max-width: 768px) {
width: 100%;
}
`;

const ContentArea = styled.div`
flex: 1;
display: flex;
overflow: hidden;

/* Mobile: Stack content vertically if needed */
@media (max-width: 768px) {
flex-direction: column;
}
`;

const WelcomeView = styled.div`
Expand Down Expand Up @@ -186,7 +225,10 @@ function AppInner() {
);
const [workspaceModalLoadError, setWorkspaceModalLoadError] = useState<string | null>(null);
const workspaceModalProjectRef = useRef<string | null>(null);
const [sidebarCollapsed, setSidebarCollapsed] = usePersistedState("sidebarCollapsed", false);

// Auto-collapse sidebar on mobile by default
const isMobile = typeof window !== "undefined" && window.innerWidth <= 768;
const [sidebarCollapsed, setSidebarCollapsed] = usePersistedState("sidebarCollapsed", isMobile);

const handleToggleSidebar = useCallback(() => {
setSidebarCollapsed((prev) => !prev);
Expand Down
18 changes: 18 additions & 0 deletions src/components/AIView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,24 @@ const ViewContainer = styled.div`
overflow-x: auto;
overflow-y: hidden;
container-type: inline-size;

/* Mobile: Stack vertically */
@media (max-width: 768px) {
flex-direction: column;
}
`;

const ChatArea = styled.div`
flex: 1;
min-width: 400px; /* Reduced from 750px to allow narrower layout when Review panel is wide */
display: flex;
flex-direction: column;

/* Mobile: Remove min-width and take full width */
@media (max-width: 768px) {
min-width: 0;
width: 100%;
}
`;

const ViewHeader = styled.div`
Expand All @@ -57,6 +68,13 @@ const ViewHeader = styled.div`
display: flex;
justify-content: space-between;
align-items: center;

/* Mobile: Add padding for hamburger button and adjust spacing */
@media (max-width: 768px) {
padding: 8px 15px 8px 60px; /* Extra left padding for hamburger button */
flex-wrap: wrap;
gap: 8px;
}
`;

const WorkspaceTitle = styled.div`
Expand Down
96 changes: 91 additions & 5 deletions src/components/LeftSidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,71 @@ const LeftSidebarContainer = styled.div<{ collapsed?: boolean }>`
flex-shrink: 0;
transition: width 0.2s ease;
overflow: hidden;
position: relative;
z-index: 100;

/* Mobile: Sidebar becomes overlay */
@media (max-width: 768px) {
position: fixed;
left: 0;
top: 0;
width: 280px;
z-index: 1000;
transform: ${(props) => (props.collapsed ? "translateX(-100%)" : "translateX(0)")};
transition: transform 0.3s ease;
box-shadow: ${(props) => (props.collapsed ? "none" : "2px 0 8px rgba(0, 0, 0, 0.5)")};
}
`;

const Overlay = styled.div<{ visible: boolean }>`
display: none;

/* Mobile: Show overlay backdrop when sidebar is open */
@media (max-width: 768px) {
display: ${(props) => (props.visible ? "block" : "none")};
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 999;
backdrop-filter: blur(2px);
}
`;

const HamburgerButton = styled.button`
display: none;

/* Mobile: Show hamburger menu */
@media (max-width: 768px) {
display: flex;
position: fixed;
top: 12px;
left: 12px;
z-index: 998;
width: 40px;
height: 40px;
background: #252526;
border: 1px solid #3c3c3c;
border-radius: 6px;
cursor: pointer;
align-items: center;
justify-content: center;
color: #cccccc;
font-size: 20px;
transition: all 0.2s;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);

&:hover {
background: #2a2a2b;
border-color: #4c4c4c;
}

&:active {
transform: scale(0.95);
}
}
`;

interface LeftSidebarProps {
Expand Down Expand Up @@ -46,12 +111,33 @@ interface LeftSidebarProps {
}

export function LeftSidebar(props: LeftSidebarProps) {
const { collapsed, ...projectSidebarProps } = props;
const { collapsed, onToggleCollapsed, ...projectSidebarProps } = props;

return (
<LeftSidebarContainer collapsed={collapsed}>
{!collapsed && <TitleBar />}
<ProjectSidebar {...projectSidebarProps} collapsed={collapsed} />
</LeftSidebarContainer>
<>
{/* Hamburger menu button - only visible on mobile */}
{collapsed && (
<HamburgerButton
onClick={onToggleCollapsed}
title="Open sidebar"
aria-label="Open sidebar menu"
>
☰
</HamburgerButton>
)}

{/* Overlay backdrop - only visible on mobile when sidebar is open */}
<Overlay visible={!collapsed} onClick={onToggleCollapsed} />

{/* Sidebar */}
<LeftSidebarContainer collapsed={collapsed}>
{!collapsed && <TitleBar />}
<ProjectSidebar
{...projectSidebarProps}
collapsed={collapsed}
onToggleCollapsed={onToggleCollapsed}
/>
</LeftSidebarContainer>
</>
);
}
10 changes: 10 additions & 0 deletions src/components/RightSidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,16 @@ const SidebarContainer = styled.div<SidebarContainerStyleProps>`
z-index: 10;
box-shadow: -2px 0 4px rgba(0, 0, 0, 0.2);
`}

/* Mobile: Full width when expanded, hide when collapsed */
@media (max-width: 768px) {
width: ${(props) => (props.collapsed ? "0" : "100%")};
border-left: none;
border-top: 1px solid #3e3e42;
max-height: ${(props) => (props.collapsed ? "0" : "50vh")};
position: ${(props) => (props.collapsed ? "absolute" : "relative")};
bottom: ${(props) => (props.collapsed ? "0" : "auto")};
}
`;

const FullView = styled.div<{ visible: boolean }>`
Expand Down