Fix the mobile swipe-back behavior so users can swipe right from the chat list
in a workspace to navigate back to the workspace list (matching the behavior on
the old task detail page).
Changes
In ui/src/components/spaces/SpaceDetail.tsx:
Pass onSelectSpace to SpaceChat: So that SpaceChat can trigger
workspace list return via onSelectSpace(undefined).
Add useEdgeSwipe to SpaceChat: The existing useEdgeSwipe hook (already
used at the app level for opening the navigation drawer) is reused for the
chat list pane.
Enable only on the chat list: The edge swipe is enabled when:
onSelectSpace is provided
No task is selected (spaceTaskId == null) — i.e., the chat list view
No create dialog is open (!showCreate)
Design Notes
The useEdgeSwipe hook detects a right-edge swipe (starts within 20px from the
left edge, moves right by at least 60px or 22% of container width, with minimal
vertical movement).
The existing SwipeableTabs component on the conversation detail pane already
handles swipe-back from the detail to the chat list (onSwipeBackFromFirst).
This change fills the gap: the chat list -> workspace list swipe.
## Summary
Fix the mobile swipe-back behavior so users can swipe right from the chat list
in a workspace to navigate back to the workspace list (matching the behavior on
the old task detail page).
## Changes
In `ui/src/components/spaces/SpaceDetail.tsx`:
1. **Pass `onSelectSpace` to `SpaceChat`**: So that `SpaceChat` can trigger
workspace list return via `onSelectSpace(undefined)`.
2. **Add `useEdgeSwipe` to `SpaceChat`**: The existing `useEdgeSwipe` hook (already
used at the app level for opening the navigation drawer) is reused for the
chat list pane.
3. **Enable only on the chat list**: The edge swipe is enabled when:
- `onSelectSpace` is provided
- No task is selected (`spaceTaskId == null`) — i.e., the chat list view
- No create dialog is open (`!showCreate`)
## Design Notes
- The `useEdgeSwipe` hook detects a right-edge swipe (starts within 20px from the
left edge, moves right by at least 60px or 22% of container width, with minimal
vertical movement).
- The existing `SwipeableTabs` component on the conversation detail pane already
handles swipe-back from the detail to the chat list (`onSwipeBackFromFirst`).
- This change fills the gap: the chat list -> workspace list swipe.
## Patch
```diff
diff --git a/ui/src/components/spaces/SpaceDetail.tsx b/ui/src/components/spaces/SpaceDetail.tsx
index 62d9fef..921c526 100644
--- a/ui/src/components/spaces/SpaceDetail.tsx
+++ b/ui/src/components/spaces/SpaceDetail.tsx
@@ -1,4 +1,4 @@
-import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
+import { useCallback, useEffect, useMemo, useRef, useState, type TouchEvent } from 'react';
import { useTranslation } from 'react-i18next';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import { useSpaces, useArchiveSpace } from '../../hooks/useSpaces';
@@ -30,6 +30,7 @@ import { SpaceSettings } from './SpaceSettings';
import { SpaceCalendar } from './SpaceCalendar';
import { SchedulesPage } from '../../pages/SpacesPage';
import { SpaceApps } from './SpaceApps';
+import { useEdgeSwipe } from '../../hooks/useEdgeSwipe';
import { useAuthState } from '../../App';
import { SkeletonChatPane } from '../shared/Skeleton';
import { EmptyState } from '../shared/EmptyState';
@@ -189,6 +190,7 @@ export function SpaceDetail({ spaceId, spaceTaskId, initialTab, onInitialTabAppl
spaceId={spaceId}
isPersonalSpace={space.kind === 'personal'}
spaceTaskId={spaceTaskId}
+ onSelectSpace={onSelectSpace}
onSelectSpaceTask={onSelectSpaceTask}
onCreateTask={onCreateTask}
filter={chatFilter}
@@ -426,6 +428,7 @@ function SpaceChat({
spaceId,
isPersonalSpace,
spaceTaskId,
+ onSelectSpace,
onSelectSpaceTask,
filter,
onFilterChange,
@@ -433,6 +436,7 @@ function SpaceChat({
spaceId: string;
isPersonalSpace: boolean;
spaceTaskId?: number;
+ onSelectSpace?: (id: string | undefined) => void;
onSelectSpaceTask: (id: number) => void;
onCreateTask: SpaceDetailProps['onCreateTask'];
filter: SpaceChatFilter;
@@ -501,10 +505,19 @@ function SpaceChat({
onSelectSpaceTask(created.task.id);
}, [qc, onSelectSpaceTask]);
+ // 右スワイプでチャット一覧(ワークスペース一覧)に戻る(モバイル操作感)。
+ // チャット一覧画面のみで有効(会話はSwipeableTabsが処理)。
+ const edgeSwipe = useEdgeSwipe({
+ enabled: !!onSelectSpace && spaceTaskId == null && !showCreate,
+ onOpen: () => { onSelectSpace?.(undefined); },
+ });
+
return (
<div className="flex h-full min-h-0">
- {/* 左: チャット一覧。会話を開いている狭幅では隠す(会話が一覧を置き換える)。 */}
+ {/* 左: チャット一覧。右スワイプでワークスペース一覧へ戻る。
+ 会話を開いている狭幅では隠す(会話が一覧を置き換える)。 */}
<div
+ {...edgeSwipe}
className={`w-full md:w-[280px] md:shrink-0 flex flex-col min-h-0 overflow-hidden border-r border-hairline ${
spaceTaskId != null || showCreate ? 'hidden md:flex' : 'flex'
}`}
```
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
Fix the mobile swipe-back behavior so users can swipe right from the chat list
in a workspace to navigate back to the workspace list (matching the behavior on
the old task detail page).
Changes
In
ui/src/components/spaces/SpaceDetail.tsx:Pass
onSelectSpacetoSpaceChat: So thatSpaceChatcan triggerworkspace list return via
onSelectSpace(undefined).Add
useEdgeSwipetoSpaceChat: The existinguseEdgeSwipehook (alreadyused at the app level for opening the navigation drawer) is reused for the
chat list pane.
Enable only on the chat list: The edge swipe is enabled when:
onSelectSpaceis providedspaceTaskId == null) — i.e., the chat list view!showCreate)Design Notes
useEdgeSwipehook detects a right-edge swipe (starts within 20px from theleft edge, moves right by at least 60px or 22% of container width, with minimal
vertical movement).
SwipeableTabscomponent on the conversation detail pane alreadyhandles swipe-back from the detail to the chat list (
onSwipeBackFromFirst).Patch
View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.