@@ -325,10 +325,34 @@ export const ThreadListV2PendingRow = memo(function ThreadListV2PendingRow(props
325325 readonly showTrailingDivider ?: boolean ;
326326 readonly onSelectPendingTask : ( pendingTask : PendingNewTask ) => void ;
327327 readonly onDeletePendingTask : ( pendingTask : PendingNewTask ) => void ;
328+ readonly fullSwipeWidth ?: number ;
329+ readonly onSwipeableWillOpen : ( methods : SwipeableMethods ) => void ;
330+ readonly onSwipeableClose : ( methods : SwipeableMethods ) => void ;
331+ readonly activationKey ?: string ;
332+ readonly simultaneousSwipeGesture ?: ComponentProps < typeof ThreadSwipeable > [ "simultaneousWith" ] ;
328333} ) {
329334 const { pendingTask, onSelectPendingTask, onDeletePendingTask } = props ;
335+ const { width : windowWidth } = useWindowDimensions ( ) ;
336+ const dormant = useSwipeRowDormant ( props . activationKey ) ;
337+ const theme = useUniwindTheme ( ) ;
330338 const sidebarPane = props . pane === "sidebar" ;
339+ const rowAppearance = getThreadListV2RowAppearance ( theme , sidebarPane , false ) ;
331340 const isDraft = pendingTask . kind === "draft" ;
341+ const deleteLabel = isDraft ? "Discard" : "Delete" ;
342+ const handleDelete = useCallback (
343+ ( ) => onDeletePendingTask ( pendingTask ) ,
344+ [ onDeletePendingTask , pendingTask ] ,
345+ ) ;
346+ const deleteAction = useMemo (
347+ ( ) => ( {
348+ accessibilityLabel : `${ deleteLabel } ${ pendingTask . title } ` ,
349+ destructive : true ,
350+ icon : "trash" as const ,
351+ label : deleteLabel ,
352+ onPress : handleDelete ,
353+ } ) ,
354+ [ deleteLabel , handleDelete , pendingTask . title ] ,
355+ ) ;
332356 const projectTitle = props . projectTitle ?? props . project ?. title ?? pendingTask . projectTitle ?? "" ;
333357 const branch = pendingTask . branch ;
334358
@@ -442,45 +466,65 @@ export const ThreadListV2PendingRow = memo(function ThreadListV2PendingRow(props
442466 { props . showPendingDivider ? (
443467 < ThreadListV2SectionDivider label = "Unsent" pane = { props . pane } />
444468 ) : null }
445- < Menu
446- actions = { isDraft ? DRAFT_TASK_MENU_ACTIONS : PENDING_TASK_MENU_ACTIONS }
447- onPressAction = { handleMenuAction }
448- shouldOpenOnLongPress
469+ < ThreadSwipeable
470+ dormant = { dormant }
471+ threadKey = { pendingTask . key }
472+ backgroundColor = { rowAppearance . swipeBackgroundColor }
473+ containerStyle = { rowAppearance . swipeContainerStyle }
474+ enableTrackpadSwipe
475+ fullSwipeAction = "primary"
476+ fullSwipeWidth = { props . fullSwipeWidth ?? windowWidth - 32 }
477+ onDelete = { handleDelete }
478+ onSwipeableClose = { props . onSwipeableClose }
479+ onSwipeableWillOpen = { props . onSwipeableWillOpen }
480+ primaryAction = { deleteAction }
481+ secondaryAction = { null }
482+ resetKey = { pendingTask . key }
483+ simultaneousWith = { props . simultaneousSwipeGesture }
484+ threadTitle = { pendingTask . title }
449485 >
450- < RowPressable
451- accessibilityHint = {
452- isDraft
453- ? "Opens the draft in the new task composer"
454- : "Sends when the environment reconnects. Opens the task for editing"
455- }
456- accessibilityLabel = { pendingTask . title }
457- accessibilityRole = "button"
458- key = { pendingTask . key }
459- className = { sidebarPane ? "bg-drawer" : "bg-screen" }
460- interactionClassName = { sidebarPane ? "bg-thread-hover" : "bg-row-hover" }
461- onPress = { ( ) => onSelectPendingTask ( pendingTask ) }
462- style = {
463- sidebarPane
464- ? {
465- borderRadius : SIDEBAR_V2_ROW_RADIUS ,
466- paddingHorizontal : 12 ,
467- paddingVertical : 10 ,
468- }
469- : undefined
470- }
471- >
472- { sidebarPane ? (
473- rowContent
474- ) : (
475- < View >
476- < View className = "px-5 py-2.5" > { rowContent } </ View >
477- { props . showTrailingDivider !== false ? (
478- < View className = "ml-5 h-px bg-border-subtle" />
479- ) : null }
480- </ View >
481- ) }
482- </ RowPressable >
483- </ Menu >
486+ { ( ) => (
487+ < Menu
488+ actions = { isDraft ? DRAFT_TASK_MENU_ACTIONS : PENDING_TASK_MENU_ACTIONS }
489+ onPressAction = { handleMenuAction }
490+ shouldOpenOnLongPress
491+ >
492+ < RowPressable
493+ accessibilityHint = {
494+ isDraft
495+ ? `Opens the draft in the new task composer. Swipe left to ${ deleteLabel . toLowerCase ( ) } .`
496+ : `Sends when the environment reconnects. Opens the task for editing. Swipe left to ${ deleteLabel . toLowerCase ( ) } .`
497+ }
498+ accessibilityLabel = { pendingTask . title }
499+ accessibilityRole = "button"
500+ key = { pendingTask . key }
501+ className = { sidebarPane ? "bg-drawer" : "bg-screen" }
502+ interactionClassName = { sidebarPane ? "bg-thread-hover" : "bg-row-hover" }
503+ onPress = { ( ) => onSelectPendingTask ( pendingTask ) }
504+ style = {
505+ sidebarPane
506+ ? {
507+ borderRadius : SIDEBAR_V2_ROW_RADIUS ,
508+ paddingHorizontal : 12 ,
509+ paddingVertical : 10 ,
510+ }
511+ : undefined
512+ }
513+ >
514+ { sidebarPane ? (
515+ rowContent
516+ ) : (
517+ < View >
518+ < View className = "px-5 py-2.5" > { rowContent } </ View >
519+ { props . showTrailingDivider !== false ? (
520+ < View className = "ml-5 h-px bg-border-subtle" />
521+ ) : null }
522+ </ View >
523+ ) }
524+ </ RowPressable >
525+ </ Menu >
526+ ) }
527+ </ ThreadSwipeable >
484528 </ >
485529 ) ;
486530} ) ;
@@ -1334,7 +1378,7 @@ export const ThreadListV2Row = memo(function ThreadListV2Row(props: {
13341378 onSwipeableWillOpen = { props . onSwipeableWillOpen }
13351379 primaryAction = { primaryAction }
13361380 secondaryAction = { secondaryAction }
1337- resetKey = { `${ thread . environmentId } :${ thread . id } :${ variant } :${ snoozedRow } :${ thread . settledAt } :${ thread . unsettledAt } :${ thread . snoozedUntil } ` }
1381+ resetKey = { `${ thread . environmentId } :${ thread . id } :${ variant } :${ snoozedRow } :${ thread . settledAt } :${ thread . unsettledAt } :${ thread . snoozedUntil } : ${ thread . pinnedAt } ` }
13381382 simultaneousWith = { props . simultaneousSwipeGesture }
13391383 threadTitle = { thread . title }
13401384 >
0 commit comments