|
1 | 1 | import { usePaneRole } from "../../components/ui/Pane"; |
| 2 | +import { ScreenContent } from "../../components/ui/ScreenContent"; |
2 | 3 | import { useActiveNewTask } from "../../state/active-new-task"; |
3 | 4 | import { AppActivityIndicator } from "../../components/ui/AppActivityIndicator"; |
4 | 5 | import { useAndroidControlSizing } from "../../components/ui/useAndroidControlSizing"; |
@@ -672,45 +673,51 @@ export function HomeScreen(props: HomeScreenProps) { |
672 | 673 | if (!hasAnyThreads) { |
673 | 674 | return ( |
674 | 675 | <View className={containerClassName}> |
675 | | - <View |
676 | | - className={cn( |
677 | | - "flex-1 items-center justify-center px-8", |
678 | | - contentBackground, |
679 | | - Platform.OS === "android" && "overflow-hidden rounded-t-[28px]", |
680 | | - )} |
681 | | - style={{ |
682 | | - paddingBottom: Platform.OS === "ios" ? iosBottomClearance : Math.max(insets.bottom, 24), |
683 | | - paddingTop: NATIVE_LIQUID_GLASS_SUPPORTED ? insets.top + 72 : 0, |
684 | | - paddingLeft: 32 + (contentSideInsets?.left ?? 0), |
685 | | - paddingRight: 32 + (contentSideInsets?.right ?? 0), |
686 | | - }} |
687 | | - > |
688 | | - <View className="w-full max-w-[430px]"> |
689 | | - <EmptyState |
690 | | - title={emptyState.title} |
691 | | - detail={emptyState.detail} |
692 | | - actionLabel={!props.catalogState.hasReadyEnvironment ? "Add environment" : undefined} |
693 | | - onAction={!props.catalogState.hasReadyEnvironment ? props.onAddConnection : undefined} |
694 | | - action={ |
695 | | - Platform.OS === "android" && !props.catalogState.hasReadyEnvironment ? ( |
696 | | - <FloatingActionButton |
697 | | - label="Add environment" |
698 | | - icon="plus" |
699 | | - variant="extended" |
700 | | - tone="primary" |
701 | | - onPress={props.onAddConnection} |
702 | | - /> |
703 | | - ) : undefined |
704 | | - } |
705 | | - variant="plain" |
706 | | - /> |
707 | | - {emptyState.loading ? ( |
708 | | - <View className="mt-4 items-center"> |
709 | | - <AppActivityIndicator colorClassName="accent-icon-muted" /> |
710 | | - </View> |
711 | | - ) : null} |
| 676 | + <ScreenContent surface={sidebarSurface ? "drawer" : "screen"}> |
| 677 | + <View |
| 678 | + className={cn( |
| 679 | + "flex-1 items-center justify-center px-8", |
| 680 | + Platform.OS !== "android" && contentBackground, |
| 681 | + )} |
| 682 | + style={{ |
| 683 | + paddingBottom: |
| 684 | + Platform.OS === "ios" ? iosBottomClearance : Math.max(insets.bottom, 24), |
| 685 | + paddingTop: NATIVE_LIQUID_GLASS_SUPPORTED ? insets.top + 72 : 0, |
| 686 | + paddingLeft: 32 + (contentSideInsets?.left ?? 0), |
| 687 | + paddingRight: 32 + (contentSideInsets?.right ?? 0), |
| 688 | + }} |
| 689 | + > |
| 690 | + <View className="w-full max-w-[430px]"> |
| 691 | + <EmptyState |
| 692 | + title={emptyState.title} |
| 693 | + detail={emptyState.detail} |
| 694 | + actionLabel={ |
| 695 | + !props.catalogState.hasReadyEnvironment ? "Add environment" : undefined |
| 696 | + } |
| 697 | + onAction={ |
| 698 | + !props.catalogState.hasReadyEnvironment ? props.onAddConnection : undefined |
| 699 | + } |
| 700 | + action={ |
| 701 | + Platform.OS === "android" && !props.catalogState.hasReadyEnvironment ? ( |
| 702 | + <FloatingActionButton |
| 703 | + label="Add environment" |
| 704 | + icon="plus" |
| 705 | + variant="extended" |
| 706 | + tone="primary" |
| 707 | + onPress={props.onAddConnection} |
| 708 | + /> |
| 709 | + ) : undefined |
| 710 | + } |
| 711 | + variant="plain" |
| 712 | + /> |
| 713 | + {emptyState.loading ? ( |
| 714 | + <View className="mt-4 items-center"> |
| 715 | + <AppActivityIndicator colorClassName="accent-icon-muted" /> |
| 716 | + </View> |
| 717 | + ) : null} |
| 718 | + </View> |
712 | 719 | </View> |
713 | | - </View> |
| 720 | + </ScreenContent> |
714 | 721 | </View> |
715 | 722 | ); |
716 | 723 | } |
@@ -766,97 +773,93 @@ export function HomeScreen(props: HomeScreenProps) { |
766 | 773 |
|
767 | 774 | if (Platform.OS === "android" && threadListV2Items.length === 0) { |
768 | 775 | return ( |
769 | | - <View className="flex-1 bg-header"> |
| 776 | + <ScreenContent surface="screen"> |
770 | 777 | <View |
771 | | - className="flex-1 items-center justify-center overflow-hidden rounded-t-[28px] bg-screen px-4" |
| 778 | + className="flex-1 items-center justify-center px-4" |
772 | 779 | style={{ paddingBottom: insets.bottom }} |
773 | 780 | > |
774 | 781 | {v2ListEmpty} |
775 | 782 | </View> |
776 | | - </View> |
| 783 | + </ScreenContent> |
777 | 784 | ); |
778 | 785 | } |
779 | 786 |
|
780 | 787 | return ( |
781 | 788 | <View className={containerClassName}> |
782 | | - <View |
783 | | - className={ |
784 | | - Platform.OS === "android" |
785 | | - ? "flex-1 overflow-hidden rounded-t-[28px] bg-screen" |
786 | | - : cn("flex-1", contentBackground) |
787 | | - } |
788 | | - > |
789 | | - <SwipeableScrollGateProvider enabled={swipeEnabled} activation={swipeRowActivation}> |
790 | | - <GestureDetector gesture={homeScrollGesture}> |
791 | | - <AnimatedLegendList |
792 | | - itemLayoutAnimation={sidebarSurface ? THREAD_SIDEBAR_ROW_LAYOUT : undefined} |
793 | | - ref={listRef} |
794 | | - onLoad={() => activateVisibleRows(threadListV2Items)} |
795 | | - onTouchStart={(event) => trackListTouches(event, true)} |
796 | | - onTouchEnd={(event) => trackListTouches(event, false)} |
797 | | - onTouchCancel={(event) => trackListTouches(event, false)} |
798 | | - renderScrollComponent={Platform.OS === "ios" ? renderHomeScrollView : undefined} |
799 | | - data={threadListV2Items} |
800 | | - renderItem={renderV2Item} |
801 | | - keyExtractor={v2KeyExtractor} |
802 | | - getItemType={(item) => item.type} |
803 | | - itemsAreEqual={threadListV2ListItemsAreEqual} |
804 | | - estimatedItemSize={ESTIMATED_THREAD_LIST_V2_ROW_HEIGHT} |
805 | | - drawDistance={THREAD_LIST_V2_DRAW_DISTANCE} |
806 | | - recycleItems |
807 | | - extraData={v2ExtraData} |
808 | | - ListHeaderComponent={v2ListHeader} |
809 | | - ListFooterComponent={ |
810 | | - settledShelfExpanded && threadListV2Layout.hiddenSettledCount > 0 ? ( |
811 | | - <ThreadListV2ShowMoreRow |
812 | | - hiddenCount={threadListV2Layout.hiddenSettledCount} |
813 | | - {...(olderSettledShelf.loading |
814 | | - ? { state: "loading" as const } |
815 | | - : olderSettledShelf.failed |
816 | | - ? { state: "failed" as const } |
817 | | - : {})} |
818 | | - onPress={() => { |
819 | | - olderSettledShelf.retry(); |
820 | | - showMoreSettled(); |
821 | | - }} |
822 | | - /> |
823 | | - ) : null |
824 | | - } |
825 | | - ListEmptyComponent={v2ListEmpty} |
826 | | - style={{ flex: 1 }} |
827 | | - automaticallyAdjustsScrollIndicatorInsets={Platform.OS === "ios"} |
828 | | - // UIKit owns the bar's inset, so a minimizing bar and a resized column move |
829 | | - // the list in the same frame as the bar. |
830 | | - contentInsetAdjustmentBehavior="automatic" |
831 | | - contentInsetStartAdjustment={Platform.OS === "ios" ? insets.top : 0} |
832 | | - // RN scrollTo clamps against raw insets and ignores the automatic bar inset. |
833 | | - scrollToOverflowEnabled |
834 | | - initialScrollOffset={ |
835 | | - initialScrollOffset > 0 |
836 | | - ? initialScrollOffset - (Platform.OS === "ios" ? insets.top : 0) |
837 | | - : undefined |
838 | | - } |
839 | | - showsVerticalScrollIndicator={false} |
840 | | - keyboardDismissMode="on-drag" |
841 | | - keyboardShouldPersistTaps="handled" |
842 | | - {...scrollGateHandlers} |
843 | | - scrollEventThrottle={16} |
844 | | - contentContainerStyle={{ |
845 | | - paddingLeft: |
846 | | - (contentSideInsets?.left ?? 0) + (sidebarSurface ? 8 : 0) + androidListGutter, |
847 | | - paddingRight: |
848 | | - (contentSideInsets?.right ?? 0) + (sidebarSurface ? 8 : 0) + androidListGutter, |
849 | | - paddingBottom: |
850 | | - Platform.OS === "ios" |
851 | | - ? iosBottomClearance - (columnMetrics?.safeArea.bottom ?? insets.bottom) |
852 | | - : (workspace?.bottomClearance ?? |
853 | | - Math.max(insets.bottom, 16) + |
854 | | - (Platform.OS === "android" ? fabClearance : 88)), |
855 | | - }} |
856 | | - /> |
857 | | - </GestureDetector> |
858 | | - </SwipeableScrollGateProvider> |
859 | | - </View> |
| 789 | + <ScreenContent surface="screen"> |
| 790 | + <View className={cn("flex-1", Platform.OS !== "android" && contentBackground)}> |
| 791 | + <SwipeableScrollGateProvider enabled={swipeEnabled} activation={swipeRowActivation}> |
| 792 | + <GestureDetector gesture={homeScrollGesture}> |
| 793 | + <AnimatedLegendList |
| 794 | + itemLayoutAnimation={sidebarSurface ? THREAD_SIDEBAR_ROW_LAYOUT : undefined} |
| 795 | + ref={listRef} |
| 796 | + onLoad={() => activateVisibleRows(threadListV2Items)} |
| 797 | + onTouchStart={(event) => trackListTouches(event, true)} |
| 798 | + onTouchEnd={(event) => trackListTouches(event, false)} |
| 799 | + onTouchCancel={(event) => trackListTouches(event, false)} |
| 800 | + renderScrollComponent={Platform.OS === "ios" ? renderHomeScrollView : undefined} |
| 801 | + data={threadListV2Items} |
| 802 | + renderItem={renderV2Item} |
| 803 | + keyExtractor={v2KeyExtractor} |
| 804 | + getItemType={(item) => item.type} |
| 805 | + itemsAreEqual={threadListV2ListItemsAreEqual} |
| 806 | + estimatedItemSize={ESTIMATED_THREAD_LIST_V2_ROW_HEIGHT} |
| 807 | + drawDistance={THREAD_LIST_V2_DRAW_DISTANCE} |
| 808 | + recycleItems |
| 809 | + extraData={v2ExtraData} |
| 810 | + ListHeaderComponent={v2ListHeader} |
| 811 | + ListFooterComponent={ |
| 812 | + settledShelfExpanded && threadListV2Layout.hiddenSettledCount > 0 ? ( |
| 813 | + <ThreadListV2ShowMoreRow |
| 814 | + hiddenCount={threadListV2Layout.hiddenSettledCount} |
| 815 | + {...(olderSettledShelf.loading |
| 816 | + ? { state: "loading" as const } |
| 817 | + : olderSettledShelf.failed |
| 818 | + ? { state: "failed" as const } |
| 819 | + : {})} |
| 820 | + onPress={() => { |
| 821 | + olderSettledShelf.retry(); |
| 822 | + showMoreSettled(); |
| 823 | + }} |
| 824 | + /> |
| 825 | + ) : null |
| 826 | + } |
| 827 | + ListEmptyComponent={v2ListEmpty} |
| 828 | + style={{ flex: 1 }} |
| 829 | + automaticallyAdjustsScrollIndicatorInsets={Platform.OS === "ios"} |
| 830 | + // UIKit owns the bar's inset, so a minimizing bar and a resized column move |
| 831 | + // the list in the same frame as the bar. |
| 832 | + contentInsetAdjustmentBehavior="automatic" |
| 833 | + contentInsetStartAdjustment={Platform.OS === "ios" ? insets.top : 0} |
| 834 | + // RN scrollTo clamps against raw insets and ignores the automatic bar inset. |
| 835 | + scrollToOverflowEnabled |
| 836 | + initialScrollOffset={ |
| 837 | + initialScrollOffset > 0 |
| 838 | + ? initialScrollOffset - (Platform.OS === "ios" ? insets.top : 0) |
| 839 | + : undefined |
| 840 | + } |
| 841 | + showsVerticalScrollIndicator={false} |
| 842 | + keyboardDismissMode="on-drag" |
| 843 | + keyboardShouldPersistTaps="handled" |
| 844 | + {...scrollGateHandlers} |
| 845 | + scrollEventThrottle={16} |
| 846 | + contentContainerStyle={{ |
| 847 | + paddingLeft: |
| 848 | + (contentSideInsets?.left ?? 0) + (sidebarSurface ? 8 : 0) + androidListGutter, |
| 849 | + paddingRight: |
| 850 | + (contentSideInsets?.right ?? 0) + (sidebarSurface ? 8 : 0) + androidListGutter, |
| 851 | + paddingBottom: |
| 852 | + Platform.OS === "ios" |
| 853 | + ? iosBottomClearance - (columnMetrics?.safeArea.bottom ?? insets.bottom) |
| 854 | + : (workspace?.bottomClearance ?? |
| 855 | + Math.max(insets.bottom, 16) + |
| 856 | + (Platform.OS === "android" ? fabClearance : 88)), |
| 857 | + }} |
| 858 | + /> |
| 859 | + </GestureDetector> |
| 860 | + </SwipeableScrollGateProvider> |
| 861 | + </View> |
| 862 | + </ScreenContent> |
860 | 863 | </View> |
861 | 864 | ); |
862 | 865 | } |
0 commit comments