diff --git a/apps/mobile/src/features/home/HomeScreen.tsx b/apps/mobile/src/features/home/HomeScreen.tsx
index 80642147052f85c2ec557dac46c11f4be1367e04..c0afbfed208902dd98efa03d19448621ed5056a9 100644
--- a/apps/mobile/src/features/home/HomeScreen.tsx
+++ b/apps/mobile/src/features/home/HomeScreen.tsx
@@ -23,12 +23,11 @@ import { useAtomSet, useAtomValue } from "@effect/atom-react";
import { AsyncResult } from "effect/unstable/reactivity";
import { useFocusEffect } from "@react-navigation/native";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
-import { ActivityIndicator, FlatList, Platform, Pressable, View } from "react-native";
+import { ActivityIndicator, FlatList, Platform, View } from "react-native";
import type { SwipeableMethods } from "react-native-gesture-handler/ReanimatedSwipeable";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { cn } from "../../lib/cn";
-import { AppText as Text } from "../../components/AppText";
import { EmptyState } from "../../components/EmptyState";
import { MaterialFloatingActionButton } from "../../components/MaterialFloatingActionButton";
import type { WorkspaceEnvironment, WorkspaceState } from "../../state/workspaceModel";
@@ -53,6 +52,7 @@ import {
ThreadListV2PendingRow,
ThreadListV2Row,
ThreadListV2SettledShelfHeader,
+ ThreadListV2ShowMoreRow,
ThreadListV2SnoozedShelfHeader,
} from "../threads/thread-list-v2-items";
import { resolveThreadProviderInstance } from "../threads/thread-provider-instance";
@@ -1234,17 +1234,10 @@ export function HomeScreen(props: HomeScreenProps) {
ListHeaderComponent={v2ListHeader}
ListFooterComponent={
settledShelfExpanded && threadListV2Layout.hiddenSettledCount > 0 ? (
- ({ opacity: pressed ? 0.6 : 1 })}
- >
-
- Show more ({threadListV2Layout.hiddenSettledCount} settled hidden)
-
-
+ />
) : null
}
ListEmptyComponent={v2ListEmpty}
diff --git a/apps/mobile/src/features/threads/ThreadNavigationSidebar.tsx b/apps/mobile/src/features/threads/ThreadNavigationSidebar.tsx
index df04439a94b7e42e2a0d7c4cbfb0ac84ccfb0f00..f6ea5dcf48ea06624133b57015fcf770474785d3 100644
--- a/apps/mobile/src/features/threads/ThreadNavigationSidebar.tsx
+++ b/apps/mobile/src/features/threads/ThreadNavigationSidebar.tsx
@@ -14,7 +14,7 @@ import { useAtomValue } from "@effect/atom-react";
import { type EnvironmentId, resolveEnvironmentMachineKind } from "@t3tools/contracts";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import type { LayoutChangeEvent } from "react-native";
-import { Platform, Pressable, StyleSheet, TextInput, View } from "react-native";
+import { Platform, StyleSheet, TextInput, View } from "react-native";
import { Gesture, GestureDetector } from "react-native-gesture-handler";
import type { SwipeableMethods } from "react-native-gesture-handler/ReanimatedSwipeable";
import { useSafeAreaInsets } from "react-native-safe-area-context";
@@ -81,6 +81,7 @@ import {
ThreadListV2PendingRow,
ThreadListV2Row,
ThreadListV2SettledShelfHeader,
+ ThreadListV2ShowMoreRow,
ThreadListV2SnoozedShelfHeader,
} from "./thread-list-v2-items";
import { resolveThreadProviderInstance } from "./thread-provider-instance";
@@ -990,17 +991,7 @@ function ThreadNavigationSidebarPane(
);
case "v2-show-more":
return (
- ({ opacity: pressed ? 0.6 : 1 })}
- >
-
- Show more ({item.hiddenCount} settled hidden)
-
-
+
);
case "header":
return (
diff --git a/apps/mobile/src/features/threads/thread-list-v2-items.tsx b/apps/mobile/src/features/threads/thread-list-v2-items.tsx
index 64c865cae809e1084b747e986f1c43e1579d3dbf..fa406271198f12ab4a330b31a679d7a8241e32ff 100644
--- a/apps/mobile/src/features/threads/thread-list-v2-items.tsx
+++ b/apps/mobile/src/features/threads/thread-list-v2-items.tsx
@@ -31,6 +31,7 @@ import { useThreadPr } from "../../state/use-thread-pr";
import { ThreadSwipeable } from "../home/thread-swipe-actions";
import { buildThreadTitleRegenerationMenuItems } from "./thread-title-regeneration-menu";
import {
+ THREAD_LIST_V2_SETTLED_PAGE_COUNT,
resolveThreadListV2SnoozeMenuSelection,
resolveThreadListV2SnoozeGateExpiryMs,
resolveThreadListV2Status,
@@ -95,96 +96,130 @@ const LEGACY_MENU_ACTIONS: MenuAction[] = [
/** Rounded-row radius shared with the v1 sidebar rows. */
const SIDEBAR_V2_ROW_RADIUS = 12;
+function ThreadListV2Section(props: {
+ readonly label: string;
+ readonly pane?: "screen" | "sidebar";
+ readonly tone?: "default" | "snoozed";
+ readonly disclosure?: {
+ readonly expanded: boolean;
+ readonly disabled?: boolean;
+ readonly onToggle: () => void;
+ readonly accessibilityLabel: string;
+ readonly accessibilityHint: string;
+ };
+}) {
+ const snoozed = props.tone === "snoozed";
+ const className = cn(
+ "mb-1.5 mt-4 flex-row items-center gap-2.5",
+ props.pane === "sidebar" ? "px-3" : "px-5",
+ );
+ const content = (
+ <>
+
+ {props.label}
+
+
+ {props.disclosure ? (
+
+ ) : null}
+ >
+ );
+
+ return props.disclosure ? (
+ ({ opacity: pressed ? 0.6 : 1 })}
+ >
+ {content}
+
+ ) : (
+ {content}
+ );
+}
+
/** Section label + rule: the only structure in an otherwise flat list. */
export const ThreadListV2SectionDivider = memo(function ThreadListV2SectionDivider(props: {
readonly label: string;
readonly pane?: "screen" | "sidebar";
}) {
- return (
-
- {props.label}
-
-
- );
+ return ;
});
-export const ThreadListV2SnoozedShelfHeader = memo(function ThreadListV2SnoozedShelfHeader(props: {
+type ThreadListV2ShelfHeaderProps = {
readonly count: number;
readonly disabled?: boolean;
readonly expanded: boolean;
readonly onToggle: () => void;
readonly pane?: "screen" | "sidebar";
-}) {
+};
+
+function ThreadListV2ShelfHeader(
+ props: ThreadListV2ShelfHeaderProps & { readonly kind: "snoozed" | "settled" },
+) {
+ const label = props.kind === "snoozed" ? "Snoozed" : "Settled";
return (
- ({ opacity: pressed ? 0.6 : 1 })}
- >
-
- {props.expanded ? "Snoozed" : `Snoozed (${props.count})`}
-
-
-
-
+
);
+}
+
+export const ThreadListV2SnoozedShelfHeader = memo(function ThreadListV2SnoozedShelfHeader(
+ props: ThreadListV2ShelfHeaderProps,
+) {
+ return ;
});
-export const ThreadListV2SettledShelfHeader = memo(function ThreadListV2SettledShelfHeader(props: {
- readonly count: number;
- readonly disabled?: boolean;
- readonly expanded: boolean;
- readonly onToggle: () => void;
- readonly pane?: "screen" | "sidebar";
+export const ThreadListV2SettledShelfHeader = memo(function ThreadListV2SettledShelfHeader(
+ props: ThreadListV2ShelfHeaderProps,
+) {
+ return ;
+});
+
+export const ThreadListV2ShowMoreRow = memo(function ThreadListV2ShowMoreRow(props: {
+ readonly hiddenCount: number;
+ readonly onPress: () => void;
}) {
return (
({ opacity: pressed ? 0.6 : 1 })}
>
-
- {props.expanded ? "Settled" : `Settled (${props.count})`}
+
+ Show more ({props.hiddenCount} settled hidden)
-
-
);
});