| ... | @@ -6,8 +6,9 @@ import type { | ... | @@ -6,8 +6,9 @@ import type { |
| 6 | import type { MenuAction } from "@react-native-menu/menu"; | 6 | import type { MenuAction } from "@react-native-menu/menu"; |
| 7 | import { SymbolView } from "expo-symbols"; | 7 | import { SymbolView } from "expo-symbols"; |
| 8 | import { memo, useCallback, useMemo, type ComponentProps } from "react"; | 8 | import { memo, useCallback, useMemo, type ComponentProps } from "react"; |
| 9 | import { Pressable, useWindowDimensions, View } from "react-native"; | 9 | import { Pressable, useColorScheme, useWindowDimensions, View } from "react-native"; |
| 10 | import type { SwipeableMethods } from "react-native-gesture-handler/ReanimatedSwipeable"; | 10 | import type { SwipeableMethods } from "react-native-gesture-handler/ReanimatedSwipeable"; |
| | 11 | import Svg, { Circle, Path } from "react-native-svg"; |
| 11 | | 12 | |
| 12 | import { AppText as Text } from "../../components/AppText"; | 13 | import { AppText as Text } from "../../components/AppText"; |
| 13 | import { ControlPillMenu } from "../../components/ControlPill"; | 14 | import { ControlPillMenu } from "../../components/ControlPill"; |
| ... | @@ -16,7 +17,7 @@ import { cn } from "../../lib/cn"; | ... | @@ -16,7 +17,7 @@ import { cn } from "../../lib/cn"; |
| 16 | import { relativeTime } from "../../lib/time"; | 17 | import { relativeTime } from "../../lib/time"; |
| 17 | import { useThemeColor } from "../../lib/useThemeColor"; | 18 | import { useThemeColor } from "../../lib/useThemeColor"; |
| 18 | import type { PendingNewTask } from "../../state/use-pending-new-tasks"; | 19 | import type { PendingNewTask } from "../../state/use-pending-new-tasks"; |
| 19 | import { useThreadPr } from "../../state/use-thread-pr"; | 20 | import { useThreadPr, type ThreadPr } from "../../state/use-thread-pr"; |
| 20 | import type { HomeGroupDisplayAction } from "../home/homeListItems"; | 21 | import type { HomeGroupDisplayAction } from "../home/homeListItems"; |
| 21 | import { ThreadSwipeable } from "../home/thread-swipe-actions"; | 22 | import { ThreadSwipeable } from "../home/thread-swipe-actions"; |
| 22 | import { resolveThreadStatus } from "./threadPresentation"; | 23 | import { resolveThreadStatus } from "./threadPresentation"; |
| ... | @@ -33,6 +34,41 @@ export type ThreadListVariant = "compact" | "sidebar"; | ... | @@ -33,6 +34,41 @@ export type ThreadListVariant = "compact" | "sidebar"; |
| 33 | export const THREAD_LIST_COMPACT_INSET = 20; | 34 | export const THREAD_LIST_COMPACT_INSET = 20; |
| 34 | const SIDEBAR_ROW_RADIUS = 12; | 35 | const SIDEBAR_ROW_RADIUS = 12; |
| 35 | | 36 | |
| | 37 | function pullRequestTintColor( |
| | 38 | state: ThreadPr["state"], |
| | 39 | colorScheme: ReturnType<typeof useColorScheme>, |
| | 40 | ) { |
| | 41 | const dark = colorScheme === "dark"; |
| | 42 | switch (state) { |
| | 43 | case "open": |
| | 44 | return dark ? "#34d399" : "#059669"; |
| | 45 | case "merged": |
| | 46 | return dark ? "#a78bfa" : "#7c3aed"; |
| | 47 | case "closed": |
| | 48 | return dark ? "#a1a1aa" : "#71717a"; |
| | 49 | } |
| | 50 | } |
| | 51 | |
| | 52 | function PullRequestIcon(props: { readonly size: number; readonly color: string }) { |
| | 53 | return ( |
| | 54 | <Svg |
| | 55 | width={props.size} |
| | 56 | height={props.size} |
| | 57 | viewBox="0 0 24 24" |
| | 58 | fill="none" |
| | 59 | stroke={props.color} |
| | 60 | strokeWidth={2} |
| | 61 | strokeLinecap="round" |
| | 62 | strokeLinejoin="round" |
| | 63 | > |
| | 64 | <Circle cx={18} cy={18} r={3} /> |
| | 65 | <Circle cx={6} cy={6} r={3} /> |
| | 66 | <Path d="M13 6h3a2 2 0 0 1 2 2v7" /> |
| | 67 | <Path d="M6 9v12" /> |
| | 68 | </Svg> |
| | 69 | ); |
| | 70 | } |
| | 71 | |
| 36 | /* ─── Project group header ───────────────────────────────────────────── */ | 72 | /* ─── Project group header ───────────────────────────────────────────── */ |
| 37 | | 73 | |
| 38 | export const ThreadListGroupHeader = memo(function ThreadListGroupHeader(props: { | 74 | export const ThreadListGroupHeader = memo(function ThreadListGroupHeader(props: { |
| ... | @@ -394,6 +430,7 @@ export const ThreadListRow = memo(function ThreadListRow(props: { | ... | @@ -394,6 +430,7 @@ export const ThreadListRow = memo(function ThreadListRow(props: { |
| 394 | >["simultaneousWithExternalGesture"]; | 430 | >["simultaneousWithExternalGesture"]; |
| 395 | }) { | 431 | }) { |
| 396 | const { width: windowWidth } = useWindowDimensions(); | 432 | const { width: windowWidth } = useWindowDimensions(); |
| | 433 | const colorScheme = useColorScheme(); |
| 397 | const compact = props.variant === "compact"; | 434 | const compact = props.variant === "compact"; |
| 398 | const selected = props.selected === true; | 435 | const selected = props.selected === true; |
| 399 | // Recycling-safe: resets when the list container is reused for another | 436 | // Recycling-safe: resets when the list container is reused for another |
| ... | @@ -479,13 +516,22 @@ export const ThreadListRow = memo(function ThreadListRow(props: { | ... | @@ -479,13 +516,22 @@ export const ThreadListRow = memo(function ThreadListRow(props: { |
| 479 | </> | 516 | </> |
| 480 | ) : null} | 517 | ) : null} |
| 481 | {pr !== null ? ( | 518 | {pr !== null ? ( |
| 482 | <Text | 519 | <View |
| 483 | className={`${compact ? "text-sm" : "text-xs"} font-t3-medium ${ | 520 | accessibilityLabel={pr.accessibilityLabel} |
| 484 | selected ? "text-white" : pr.textClassName | 521 | className="flex-row items-center gap-0.5" |
| 485 | }`} | | |
| 486 | > | 522 | > |
| 487 | {pr.label} | 523 | <PullRequestIcon |
| 488 | </Text> | 524 | size={compact ? 13 : 11} |
| | 525 | color={selected ? "#ffffff" : pullRequestTintColor(pr.state, colorScheme)} |
| | 526 | /> |
| | 527 | <Text |
| | 528 | className={`${compact ? "text-sm" : "text-xs"} font-t3-medium ${ |
| | 529 | selected ? "text-white" : pr.textClassName |
| | 530 | }`} |
| | 531 | > |
| | 532 | {pr.label} |
| | 533 | </Text> |
| | 534 | </View> |
| 489 | ) : null} | 535 | ) : null} |
| 490 | </View> | 536 | </View> |
| 491 | ) : null; | 537 | ) : null; |