| author | |
| committer | |
| log | 8863990fcaecfb59dbd6c338e49aba603ecccdfd |
| tree | 6400a1e739e64fb536ea83ca29ed105bc524abcc |
| parent | 2e19207b179dca57d57ecd24a4b0b0776a41e0bf |
| signature | Signed by PGP key B5690EEEBB952194 |
32 files changed, 159 insertions(+), 113 deletions(-)
apps/mobile/src/components/AppActivityIndicator.android.tsx created+49| ... | @@ -0,0 +1,49 @@ | ||
| 1 | import { LoadingIndicator, Host } from "@expo/ui/jetpack-compose"; | ||
| 2 | import { size as composeSize } from "@expo/ui/jetpack-compose/modifiers"; | ||
| 3 | import { StyleSheet, View, type ActivityIndicatorProps } from "react-native"; | ||
| 4 | import { useResolveClassNames, withUniwind } from "uniwind"; | ||
| 5 | |||
| 6 | function AndroidActivityIndicator({ | ||
| 7 | animating = true, | ||
| 8 | color, | ||
| 9 | colorClassName: _colorClassName, | ||
| 10 | className: _className, | ||
| 11 | hidesWhenStopped: _hidesWhenStopped, | ||
| 12 | size = "small", | ||
| 13 | style, | ||
| 14 | ...viewProps | ||
| 15 | }: ActivityIndicatorProps) { | ||
| 16 | const { color: primaryColor } = useResolveClassNames("text-primary"); | ||
| 17 | const diameter = typeof size === "number" ? size : size === "large" ? 48 : 20; | ||
| 18 | |||
| 19 | return ( | ||
| 20 | <View | ||
| 21 | accessible={animating} | ||
| 22 | accessibilityRole="progressbar" | ||
| 23 | accessibilityState={{ busy: animating }} | ||
| 24 | {...viewProps} | ||
| 25 | style={[styles.container, style]} | ||
| 26 | > | ||
| 27 | <View | ||
| 28 | pointerEvents="none" | ||
| 29 | importantForAccessibility="no-hide-descendants" | ||
| 30 | style={{ width: diameter, height: diameter }} | ||
| 31 | > | ||
| 32 | {animating ? ( | ||
| 33 | <Host ignoreSafeAreaKeyboardInsets style={{ flex: 1 }}> | ||
| 34 | <LoadingIndicator | ||
| 35 | color={color ?? primaryColor} | ||
| 36 | modifiers={[composeSize(diameter, diameter)]} | ||
| 37 | /> | ||
| 38 | </Host> | ||
| 39 | ) : null} | ||
| 40 | </View> | ||
| 41 | </View> | ||
| 42 | ); | ||
| 43 | } | ||
| 44 | |||
| 45 | export const AppActivityIndicator = withUniwind(AndroidActivityIndicator); | ||
| 46 | |||
| 47 | const styles = StyleSheet.create({ | ||
| 48 | container: { alignItems: "center", justifyContent: "center" }, | ||
| 49 | }); | ||
apps/mobile/src/components/AppActivityIndicator.tsx created+3| ... | @@ -0,0 +1,3 @@ | ||
| 1 | import { ActivityIndicator } from "react-native"; | ||
| 2 | |||
| 3 | export const AppActivityIndicator = ActivityIndicator; | ||
apps/mobile/src/components/LoadingScreen.tsx+3-2| ... | @@ -1,5 +1,6 @@ | ... | @@ -1,5 +1,6 @@ |
| 1 | import { ActivityIndicator, StatusBar, View } from "react-native"; | 1 | import { StatusBar, View } from "react-native"; |
| 2 | import { useSafeAreaInsets } from "react-native-safe-area-context"; | 2 | import { useSafeAreaInsets } from "react-native-safe-area-context"; |
| 3 | import { AppActivityIndicator } from "./AppActivityIndicator"; | ||
| 3 | import { useAppearancePreferences } from "../features/settings/appearance/AppearancePreferencesProvider"; | 4 | import { useAppearancePreferences } from "../features/settings/appearance/AppearancePreferencesProvider"; |
| 4 | 5 | ||
| 5 | import { AppText as Text } from "./AppText"; | 6 | import { AppText as Text } from "./AppText"; |
| ... | @@ -26,7 +27,7 @@ export function LoadingScreen(props: { | ... | @@ -26,7 +27,7 @@ export function LoadingScreen(props: { |
| 26 | {messagePlacement === "above-spinner" ? ( | 27 | {messagePlacement === "above-spinner" ? ( |
| 27 | <Text className="font-t3-bold text-lg text-foreground">{props.message}</Text> | 28 | <Text className="font-t3-bold text-lg text-foreground">{props.message}</Text> |
| 28 | ) : null} | 29 | ) : null} |
| 29 | <ActivityIndicator size="large" /> | 30 | <AppActivityIndicator size="large" /> |
| 30 | {messagePlacement === "below-spinner" ? ( | 31 | {messagePlacement === "below-spinner" ? ( |
| 31 | <Text className="font-t3-bold text-lg text-foreground">{props.message}</Text> | 32 | <Text className="font-t3-bold text-lg text-foreground">{props.message}</Text> |
| 32 | ) : null} | 33 | ) : null} |
apps/mobile/src/components/MaterialButton.android.tsx+2-3| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | import { | 1 | import { |
| 2 | Box, | 2 | Box, |
| 3 | Button, | 3 | Button, |
| 4 | CircularProgressIndicator, | 4 | LoadingIndicator, |
| 5 | FilledTonalButton, | 5 | FilledTonalButton, |
| 6 | Host, | 6 | Host, |
| 7 | Row, | 7 | Row, |
| ... | @@ -78,9 +78,8 @@ export function MaterialButton(props: MaterialButtonProps) { | ... | @@ -78,9 +78,8 @@ export function MaterialButton(props: MaterialButtonProps) { |
| 78 | <Row verticalAlignment="center"> | 78 | <Row verticalAlignment="center"> |
| 79 | {props.loading ? ( | 79 | {props.loading ? ( |
| 80 | <> | 80 | <> |
| 81 | <CircularProgressIndicator | 81 | <LoadingIndicator |
| 82 | modifiers={[size(mediumIconSize, mediumIconSize)]} | 82 | modifiers={[size(mediumIconSize, mediumIconSize)]} |
| 83 | strokeWidth={2} | ||
| 84 | color={colors["--color-foreground-muted"]} | 83 | color={colors["--color-foreground-muted"]} |
| 85 | /> | 84 | /> |
| 86 | <Box modifiers={[size(8 * scale, 1)]} /> | 85 | <Box modifiers={[size(8 * scale, 1)]} /> |
apps/mobile/src/components/MediaVideoPlayer.tsx+4-3| ... | @@ -2,8 +2,9 @@ import { useIsFocused } from "@react-navigation/native"; | ... | @@ -2,8 +2,9 @@ import { useIsFocused } from "@react-navigation/native"; |
| 2 | import { useEvent } from "expo"; | 2 | import { useEvent } from "expo"; |
| 3 | import { useVideoPlayer, VideoView } from "expo-video"; | 3 | import { useVideoPlayer, VideoView } from "expo-video"; |
| 4 | import { useEffect, useEffectEvent, useRef, useState } from "react"; | 4 | import { useEffect, useEffectEvent, useRef, useState } from "react"; |
| 5 | import { ActivityIndicator, AppState, Pressable, View } from "react-native"; | 5 | import { AppState, Pressable, View } from "react-native"; |
| 6 | 6 | ||
| 7 | import { AppActivityIndicator } from "./AppActivityIndicator"; | ||
| 7 | import { AppText } from "./AppText"; | 8 | import { AppText } from "./AppText"; |
| 8 | import { SymbolView } from "./AppSymbol"; | 9 | import { SymbolView } from "./AppSymbol"; |
| 9 | import { VideoThumbnailImage } from "./VideoThumbnailImage"; | 10 | import { VideoThumbnailImage } from "./VideoThumbnailImage"; |
| ... | @@ -96,7 +97,7 @@ function LoadedMediaVideo(props: { | ... | @@ -96,7 +97,7 @@ function LoadedMediaVideo(props: { |
| 96 | </View> | 97 | </View> |
| 97 | ) : loadState === "pending" || status === "loading" ? ( | 98 | ) : loadState === "pending" || status === "loading" ? ( |
| 98 | <View pointerEvents="none" className="absolute inset-0 items-center justify-center"> | 99 | <View pointerEvents="none" className="absolute inset-0 items-center justify-center"> |
| 99 | <ActivityIndicator color="#ffffff" accessibilityLabel="Loading video" /> | 100 | <AppActivityIndicator color="#ffffff" accessibilityLabel="Loading video" /> |
| 100 | </View> | 101 | </View> |
| 101 | ) : null} | 102 | ) : null} |
| 102 | </View> | 103 | </View> |
| ... | @@ -160,7 +161,7 @@ function MediaVideoPlayerContent(props: MediaVideoPlayerProps) { | ... | @@ -160,7 +161,7 @@ function MediaVideoPlayerContent(props: MediaVideoPlayerProps) { |
| 160 | {props.unavailable ? ( | 161 | {props.unavailable ? ( |
| 161 | <AppText className="text-sm text-white/80">Video unavailable</AppText> | 162 | <AppText className="text-sm text-white/80">Video unavailable</AppText> |
| 162 | ) : props.uri === null ? ( | 163 | ) : props.uri === null ? ( |
| 163 | <ActivityIndicator color="#ffffff" accessibilityLabel="Loading video" /> | 164 | <AppActivityIndicator color="#ffffff" accessibilityLabel="Loading video" /> |
| 164 | ) : ( | 165 | ) : ( |
| 165 | <View className="size-12 items-center justify-center rounded-full bg-black/60"> | 166 | <View className="size-12 items-center justify-center rounded-full bg-black/60"> |
| 166 | <SymbolView name="play" size={28} tintColor="#ffffff" type="monochrome" /> | 167 | <SymbolView name="play" size={28} tintColor="#ffffff" type="monochrome" /> |
apps/mobile/src/components/ProjectCloneBanner.tsx+3-2| ... | @@ -3,8 +3,9 @@ import { | ... | @@ -3,8 +3,9 @@ import { |
| 3 | projectCloneProgressSummary, | 3 | projectCloneProgressSummary, |
| 4 | type ProjectCloneSnapshot, | 4 | type ProjectCloneSnapshot, |
| 5 | } from "@t3tools/contracts"; | 5 | } from "@t3tools/contracts"; |
| 6 | import { ActivityIndicator, Pressable, View } from "react-native"; | 6 | import { Pressable, View } from "react-native"; |
| 7 | 7 | ||
| 8 | import { AppActivityIndicator } from "./AppActivityIndicator"; | ||
| 8 | import { cn } from "../lib/cn"; | 9 | import { cn } from "../lib/cn"; |
| 9 | import { AppText as Text } from "./AppText"; | 10 | import { AppText as Text } from "./AppText"; |
| 10 | 11 | ||
| ... | @@ -24,7 +25,7 @@ export function ProjectCloneBanner(props: { | ... | @@ -24,7 +25,7 @@ export function ProjectCloneBanner(props: { |
| 24 | if (clone.phase === "running") { | 25 | if (clone.phase === "running") { |
| 25 | return ( | 26 | return ( |
| 26 | <View className="flex-row items-center gap-3 rounded-2xl border border-border bg-card px-3.5 py-3"> | 27 | <View className="flex-row items-center gap-3 rounded-2xl border border-border bg-card px-3.5 py-3"> |
| 27 | <ActivityIndicator size="small" /> | 28 | <AppActivityIndicator size="small" /> |
| 28 | <View className="min-w-0 flex-1"> | 29 | <View className="min-w-0 flex-1"> |
| 29 | <Text className="font-t3-medium text-sm" numberOfLines={1}> | 30 | <Text className="font-t3-medium text-sm" numberOfLines={1}> |
| 30 | Cloning {name} | 31 | Cloning {name} |
apps/mobile/src/components/VideoPreviewModal.tsx+3-2| ... | @@ -1,9 +1,10 @@ | ... | @@ -1,9 +1,10 @@ |
| 1 | import { useIsFocused } from "@react-navigation/native"; | 1 | import { useIsFocused } from "@react-navigation/native"; |
| 2 | import { videoMimeType } from "@t3tools/shared/video"; | 2 | import { videoMimeType } from "@t3tools/shared/video"; |
| 3 | import { useEffect, useRef, useState } from "react"; | 3 | import { useEffect, useRef, useState } from "react"; |
| 4 | import { ActivityIndicator, Keyboard, Modal, Pressable, View } from "react-native"; | 4 | import { Keyboard, Modal, Pressable, View } from "react-native"; |
| 5 | import { useSafeAreaInsets } from "react-native-safe-area-context"; | 5 | import { useSafeAreaInsets } from "react-native-safe-area-context"; |
| 6 | 6 | ||
| 7 | import { AppActivityIndicator } from "./AppActivityIndicator"; | ||
| 7 | import { loadLocalAttachmentPreview } from "../lib/localAttachmentPreview"; | 8 | import { loadLocalAttachmentPreview } from "../lib/localAttachmentPreview"; |
| 8 | import { useMediaActions } from "../state/mediaActions"; | 9 | import { useMediaActions } from "../state/mediaActions"; |
| 9 | import { type MediaActionsSource } from "../lib/mediaActionsSource"; | 10 | import { type MediaActionsSource } from "../lib/mediaActionsSource"; |
| ... | @@ -165,7 +166,7 @@ function OpenVideoPreviewModal(props: { | ... | @@ -165,7 +166,7 @@ function OpenVideoPreviewModal(props: { |
| 165 | <MediaSourceCaption source={mediaActions.title} /> | 166 | <MediaSourceCaption source={mediaActions.title} /> |
| 166 | {playback.uri === null && !playback.unavailable ? ( | 167 | {playback.uri === null && !playback.unavailable ? ( |
| 167 | <View className="flex-1 items-center justify-center gap-3 px-6"> | 168 | <View className="flex-1 items-center justify-center gap-3 px-6"> |
| 168 | <ActivityIndicator color="#ffffff" /> | 169 | <AppActivityIndicator color="#ffffff" /> |
| 169 | <AppText className="text-sm text-white/80">Loading video...</AppText> | 170 | <AppText className="text-sm text-white/80">Loading video...</AppText> |
| 170 | </View> | 171 | </View> |
| 171 | ) : ( | 172 | ) : ( |
apps/mobile/src/features/archive/ArchivedThreadsScreen.tsx+3-9| ... | @@ -10,17 +10,11 @@ import { | ... | @@ -10,17 +10,11 @@ import { |
| 10 | resolveEnvironmentMachineKind, | 10 | resolveEnvironmentMachineKind, |
| 11 | } from "@t3tools/contracts"; | 11 | } from "@t3tools/contracts"; |
| 12 | import { useNavigation } from "@react-navigation/native"; | 12 | import { useNavigation } from "@react-navigation/native"; |
| 13 | import { AppActivityIndicator } from "../../components/AppActivityIndicator"; | ||
| 13 | import { ScreenHeader } from "../../components/ScreenHeader"; | 14 | import { ScreenHeader } from "../../components/ScreenHeader"; |
| 14 | import { SymbolView } from "../../components/AppSymbol"; | 15 | import { SymbolView } from "../../components/AppSymbol"; |
| 15 | import { useCallback, useMemo, useRef, type ComponentProps } from "react"; | 16 | import { useCallback, useMemo, useRef, type ComponentProps } from "react"; |
| 16 | import { | 17 | import { Platform, Pressable, RefreshControl, useWindowDimensions, View } from "react-native"; |
| 17 | ActivityIndicator, | ||
| 18 | Platform, | ||
| 19 | Pressable, | ||
| 20 | RefreshControl, | ||
| 21 | useWindowDimensions, | ||
| 22 | View, | ||
| 23 | } from "react-native"; | ||
| 24 | import { GestureDetector, useNativeGesture } from "react-native-gesture-handler"; | 18 | import { GestureDetector, useNativeGesture } from "react-native-gesture-handler"; |
| 25 | import type { SwipeableMethods } from "react-native-gesture-handler/ReanimatedSwipeable"; | 19 | import type { SwipeableMethods } from "react-native-gesture-handler/ReanimatedSwipeable"; |
| 26 | 20 | ||
| ... | @@ -399,7 +393,7 @@ export function ArchivedThreadsScreen(props: { | ... | @@ -399,7 +393,7 @@ export function ArchivedThreadsScreen(props: { |
| 399 | if (isInitialLoad) { | 393 | if (isInitialLoad) { |
| 400 | return ( | 394 | return ( |
| 401 | <View className="items-center py-16"> | 395 | <View className="items-center py-16"> |
| 402 | <ActivityIndicator colorClassName="accent-icon" /> | 396 | <AppActivityIndicator colorClassName="accent-icon" /> |
| 403 | <Text className="mt-3 text-sm text-foreground-muted">Loading archive...</Text> | 397 | <Text className="mt-3 text-sm text-foreground-muted">Loading archive...</Text> |
| 404 | </View> | 398 | </View> |
| 405 | ); | 399 | ); |
apps/mobile/src/features/cloud/T3ConnectProfilePage.tsx+7-11| ... | @@ -7,16 +7,9 @@ import type { MenuAction } from "@react-native-menu/menu"; | ... | @@ -7,16 +7,9 @@ import type { MenuAction } from "@react-native-menu/menu"; |
| 7 | import type { EnvironmentId } from "@t3tools/contracts"; | 7 | import type { EnvironmentId } from "@t3tools/contracts"; |
| 8 | import type { RelayClientEnvironmentRecord } from "@t3tools/contracts/relay"; | 8 | import type { RelayClientEnvironmentRecord } from "@t3tools/contracts/relay"; |
| 9 | import { type ReactNode, useRef, useState } from "react"; | 9 | import { type ReactNode, useRef, useState } from "react"; |
| 10 | import { | 10 | import { Alert, Pressable, RefreshControl, ScrollView, Text, View } from "react-native"; |
| 11 | ActivityIndicator, | ||
| 12 | Alert, | ||
| 13 | Pressable, | ||
| 14 | RefreshControl, | ||
| 15 | ScrollView, | ||
| 16 | Text, | ||
| 17 | View, | ||
| 18 | } from "react-native"; | ||
| 19 | 11 | ||
| 12 | import { AppActivityIndicator } from "../../components/AppActivityIndicator"; | ||
| 20 | import { SymbolView } from "../../components/AppSymbol"; | 13 | import { SymbolView } from "../../components/AppSymbol"; |
| 21 | import { showConfirmDialog } from "../../components/ConfirmDialogHost"; | 14 | import { showConfirmDialog } from "../../components/ConfirmDialogHost"; |
| 22 | import { ControlPillMenu } from "../../components/ControlPill"; | 15 | import { ControlPillMenu } from "../../components/ControlPill"; |
| ... | @@ -167,7 +160,7 @@ export function T3ConnectProfilePage() { | ... | @@ -167,7 +160,7 @@ export function T3ConnectProfilePage() { |
| 167 | </> | 160 | </> |
| 168 | ) : isInitialLoad ? ( | 161 | ) : isInitialLoad ? ( |
| 169 | <View className="flex-row items-center gap-3 px-6 py-4"> | 162 | <View className="flex-row items-center gap-3 px-6 py-4"> |
| 170 | <ActivityIndicator colorClassName={"accent-clerk-foreground-muted"} size="small" /> | 163 | <AppActivityIndicator colorClassName={"accent-clerk-foreground-muted"} size="small" /> |
| 171 | <Text className="text-base text-clerk-foreground-muted">Loading environments</Text> | 164 | <Text className="text-base text-clerk-foreground-muted">Loading environments</Text> |
| 172 | </View> | 165 | </View> |
| 173 | ) : environments.length > 0 ? ( | 166 | ) : environments.length > 0 ? ( |
| ... | @@ -178,7 +171,10 @@ export function T3ConnectProfilePage() { | ... | @@ -178,7 +171,10 @@ export function T3ConnectProfilePage() { |
| 178 | subtitle={`${linkedAtLabel(environment.linkedAt)} · ${endpointLabel(environment)}`} | 171 | subtitle={`${linkedAtLabel(environment.linkedAt)} · ${endpointLabel(environment)}`} |
| 179 | accessory={ | 172 | accessory={ |
| 180 | deregisteringEnvironmentId === environment.environmentId ? ( | 173 | deregisteringEnvironmentId === environment.environmentId ? ( |
| 181 | <ActivityIndicator colorClassName={"accent-clerk-foreground-muted"} size="small" /> | 174 | <AppActivityIndicator |
| 175 | colorClassName={"accent-clerk-foreground-muted"} | ||
| 176 | size="small" | ||
| 177 | /> | ||
| 182 | ) : ( | 178 | ) : ( |
| 183 | <ControlPillMenu | 179 | <ControlPillMenu |
| 184 | actions={ENVIRONMENT_MENU_ACTIONS} | 180 | actions={ENVIRONMENT_MENU_ACTIONS} |
apps/mobile/src/features/connection/CloudEnvironmentRows.tsx+3-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | import { AppActivityIndicator } from "../../components/AppActivityIndicator"; | ||
| 1 | import { ConnectionTraceId } from "./ConnectionTraceId"; | 2 | import { ConnectionTraceId } from "./ConnectionTraceId"; |
| 2 | import { useAuth } from "@clerk/expo"; | 3 | import { useAuth } from "@clerk/expo"; |
| 3 | import { SymbolView } from "../../components/AppSymbol"; | 4 | import { SymbolView } from "../../components/AppSymbol"; |
| ... | @@ -13,7 +14,7 @@ import { | ... | @@ -13,7 +14,7 @@ import { |
| 13 | } from "@t3tools/contracts"; | 14 | } from "@t3tools/contracts"; |
| 14 | import { useAtomValue } from "@effect/atom-react"; | 15 | import { useAtomValue } from "@effect/atom-react"; |
| 15 | import { useCallback, useState } from "react"; | 16 | import { useCallback, useState } from "react"; |
| 16 | import { ActivityIndicator, Pressable, type TextLayoutEvent, View } from "react-native"; | 17 | import { Pressable, type TextLayoutEvent, View } from "react-native"; |
| 17 | 18 | ||
| 18 | import { AppText as Text } from "../../components/AppText"; | 19 | import { AppText as Text } from "../../components/AppText"; |
| 19 | import { EnvironmentMachineSymbol } from "../../components/EnvironmentMachineSymbol"; | 20 | import { EnvironmentMachineSymbol } from "../../components/EnvironmentMachineSymbol"; |
| ... | @@ -151,7 +152,7 @@ function CloudEnvironmentRowsContent( | ... | @@ -151,7 +152,7 @@ function CloudEnvironmentRowsContent( |
| 151 | </View> | 152 | </View> |
| 152 | ) : controller.relayDiscovery.isRefreshing ? ( | 153 | ) : controller.relayDiscovery.isRefreshing ? ( |
| 153 | <View collapsable={false} className="items-center gap-3 rounded-[24px] bg-grouped-card p-6"> | 154 | <View collapsable={false} className="items-center gap-3 rounded-[24px] bg-grouped-card p-6"> |
| 154 | <ActivityIndicator colorClassName={"accent-icon"} /> | 155 | <AppActivityIndicator colorClassName={"accent-icon"} /> |
| 155 | <Text className="text-center text-sm leading-normal text-foreground-muted"> | 156 | <Text className="text-center text-sm leading-normal text-foreground-muted"> |
| 156 | Loading linked cloud environments. | 157 | Loading linked cloud environments. |
| 157 | </Text> | 158 | </Text> |
apps/mobile/src/features/connection/EnvironmentConnectionNotice.tsx+3-2| ... | @@ -1,10 +1,11 @@ | ... | @@ -1,10 +1,11 @@ |
| 1 | import { AppActivityIndicator } from "../../components/AppActivityIndicator"; | ||
| 1 | import { ConnectionTraceId } from "./ConnectionTraceId"; | 2 | import { ConnectionTraceId } from "./ConnectionTraceId"; |
| 2 | import { | 3 | import { |
| 3 | type EnvironmentConnectionPhase, | 4 | type EnvironmentConnectionPhase, |
| 4 | type EnvironmentConnectionPresentation, | 5 | type EnvironmentConnectionPresentation, |
| 5 | } from "@t3tools/client-runtime/connection"; | 6 | } from "@t3tools/client-runtime/connection"; |
| 6 | import { SymbolView } from "../../components/AppSymbol"; | 7 | import { SymbolView } from "../../components/AppSymbol"; |
| 7 | import { ActivityIndicator, Pressable, View } from "react-native"; | 8 | import { Pressable, View } from "react-native"; |
| 8 | 9 | ||
| 9 | import { AppText as Text } from "../../components/AppText"; | 10 | import { AppText as Text } from "../../components/AppText"; |
| 10 | 11 | ||
| ... | @@ -65,7 +66,7 @@ export function EnvironmentConnectionNotice(props: { | ... | @@ -65,7 +66,7 @@ export function EnvironmentConnectionNotice(props: { |
| 65 | <View className="flex-1 items-center justify-center px-8"> | 66 | <View className="flex-1 items-center justify-center px-8"> |
| 66 | <View className="max-w-[320px] items-center gap-3"> | 67 | <View className="max-w-[320px] items-center gap-3"> |
| 67 | {isRetrying ? ( | 68 | {isRetrying ? ( |
| 68 | <ActivityIndicator size="small" colorClassName={"accent-icon-muted"} /> | 69 | <AppActivityIndicator size="small" colorClassName={"accent-icon-muted"} /> |
| 69 | ) : ( | 70 | ) : ( |
| 70 | <SymbolView | 71 | <SymbolView |
| 71 | name={props.connection.phase === "offline" ? "wifi.slash" : "bolt.horizontal.circle"} | 72 | name={props.connection.phase === "offline" ? "wifi.slash" : "bolt.horizontal.circle"} |
apps/mobile/src/features/devices/DevicePreviewRouteScreen.tsx+4-11| ... | @@ -9,19 +9,12 @@ import * as Cause from "effect/Cause"; | ... | @@ -9,19 +9,12 @@ import * as Cause from "effect/Cause"; |
| 9 | import { useCallback, useEffect, useMemo, useRef, useState, type RefObject } from "react"; | 9 | import { useCallback, useEffect, useMemo, useRef, useState, type RefObject } from "react"; |
| 10 | import * as Haptics from "expo-haptics"; | 10 | import * as Haptics from "expo-haptics"; |
| 11 | import { Accelerometer } from "expo-sensors"; | 11 | import { Accelerometer } from "expo-sensors"; |
| 12 | import { | 12 | import { Alert, AppState, BackHandler, Pressable, StatusBar, View } from "react-native"; |
| 13 | ActivityIndicator, | ||
| 14 | Alert, | ||
| 15 | AppState, | ||
| 16 | BackHandler, | ||
| 17 | Pressable, | ||
| 18 | StatusBar, | ||
| 19 | View, | ||
| 20 | } from "react-native"; | ||
| 21 | import Animated, { FadeIn, FadeOut, ReduceMotion } from "react-native-reanimated"; | 13 | import Animated, { FadeIn, FadeOut, ReduceMotion } from "react-native-reanimated"; |
| 22 | import { useSafeAreaInsets } from "react-native-safe-area-context"; | 14 | import { useSafeAreaInsets } from "react-native-safe-area-context"; |
| 23 | 15 | ||
| 24 | import { SymbolView } from "../../components/AppSymbol"; | 16 | import { SymbolView } from "../../components/AppSymbol"; |
| 17 | import { AppActivityIndicator } from "../../components/AppActivityIndicator"; | ||
| 25 | import { AppText } from "../../components/AppText"; | 18 | import { AppText } from "../../components/AppText"; |
| 26 | import { ControlPill, ControlPillMenu } from "../../components/ControlPill"; | 19 | import { ControlPill, ControlPillMenu } from "../../components/ControlPill"; |
| 27 | import { GlassSurface } from "../../components/GlassSurface"; | 20 | import { GlassSurface } from "../../components/GlassSurface"; |
| ... | @@ -295,7 +288,7 @@ function DevicePreviewScreen({ | ... | @@ -295,7 +288,7 @@ function DevicePreviewScreen({ |
| 295 | </Pressable> | 288 | </Pressable> |
| 296 | </> | 289 | </> |
| 297 | ) : focused && foreground ? ( | 290 | ) : focused && foreground ? ( |
| 298 | <ActivityIndicator color={themeVariables["--color-icon"]} /> | 291 | <AppActivityIndicator color={themeVariables["--color-icon"]} /> |
| 299 | ) : null} | 292 | ) : null} |
| 300 | </View> | 293 | </View> |
| 301 | )} | 294 | )} |
| ... | @@ -428,7 +421,7 @@ function OpenDevicePreview({ | ... | @@ -428,7 +421,7 @@ function OpenDevicePreview({ |
| 428 | </> | 421 | </> |
| 429 | ) : ( | 422 | ) : ( |
| 430 | <> | 423 | <> |
| 431 | <ActivityIndicator color={themeVariables["--color-icon"]} /> | 424 | <AppActivityIndicator color={themeVariables["--color-icon"]} /> |
| 432 | <AppText className="text-sm text-foreground-muted">Connecting to device...</AppText> | 425 | <AppText className="text-sm text-foreground-muted">Connecting to device...</AppText> |
| 433 | </> | 426 | </> |
| 434 | )} | 427 | )} |
apps/mobile/src/features/devices/DeviceStreamWebView.tsx+3-2| ... | @@ -9,10 +9,11 @@ import { | ... | @@ -9,10 +9,11 @@ import { |
| 9 | useState, | 9 | useState, |
| 10 | type Ref, | 10 | type Ref, |
| 11 | } from "react"; | 11 | } from "react"; |
| 12 | import { ActivityIndicator, Platform, Pressable, View } from "react-native"; | 12 | import { Platform, Pressable, View } from "react-native"; |
| 13 | import { WebView } from "react-native-webview"; | 13 | import { WebView } from "react-native-webview"; |
| 14 | import type { DeviceStreamStatus } from "@t3tools/client-runtime/device/stream"; | 14 | import type { DeviceStreamStatus } from "@t3tools/client-runtime/device/stream"; |
| 15 | 15 | ||
| 16 | import { AppActivityIndicator } from "../../components/AppActivityIndicator"; | ||
| 16 | import { AppText } from "../../components/AppText"; | 17 | import { AppText } from "../../components/AppText"; |
| 17 | 18 | ||
| 18 | import { | 19 | import { |
| ... | @@ -187,7 +188,7 @@ function DeviceStreamDocumentView({ | ... | @@ -187,7 +188,7 @@ function DeviceStreamDocumentView({ |
| 187 | className="absolute inset-0 items-center justify-center gap-4 px-6" | 188 | className="absolute inset-0 items-center justify-center gap-4 px-6" |
| 188 | style={{ backgroundColor: background }} | 189 | style={{ backgroundColor: background }} |
| 189 | > | 190 | > |
| 190 | {status === "connecting" ? <ActivityIndicator colorClassName="accent-icon" /> : null} | 191 | {status === "connecting" ? <AppActivityIndicator colorClassName="accent-icon" /> : null} |
| 191 | <AppText | 192 | <AppText |
| 192 | accessibilityLiveRegion="polite" | 193 | accessibilityLiveRegion="polite" |
| 193 | className="text-center text-sm text-foreground-muted" | 194 | className="text-center text-sm text-foreground-muted" |
apps/mobile/src/features/diagnostics/SettingsDiagnosticsRouteScreen.tsx+3-2| ... | @@ -1,8 +1,9 @@ | ... | @@ -1,8 +1,9 @@ |
| 1 | import { AppActivityIndicator } from "../../components/AppActivityIndicator"; | ||
| 1 | import { ScreenScrollView as ScrollView } from "../../components/ScreenScrollView"; | 2 | import { ScreenScrollView as ScrollView } from "../../components/ScreenScrollView"; |
| 2 | import Constants from "expo-constants"; | 3 | import Constants from "expo-constants"; |
| 3 | import * as Updates from "expo-updates"; | 4 | import * as Updates from "expo-updates"; |
| 4 | import { useEffect, useState } from "react"; | 5 | import { useEffect, useState } from "react"; |
| 5 | import { ActivityIndicator, Platform, View } from "react-native"; | 6 | import { Platform, View } from "react-native"; |
| 6 | import { useSafeAreaInsets } from "react-native-safe-area-context"; | 7 | import { useSafeAreaInsets } from "react-native-safe-area-context"; |
| 7 | 8 | ||
| 8 | import { SymbolView } from "../../components/AppSymbol"; | 9 | import { SymbolView } from "../../components/AppSymbol"; |
| ... | @@ -85,7 +86,7 @@ export function SettingsDiagnosticsRouteScreen() { | ... | @@ -85,7 +86,7 @@ export function SettingsDiagnosticsRouteScreen() { |
| 85 | <SettingsSection title="Startup crashes"> | 86 | <SettingsSection title="Startup crashes"> |
| 86 | {state.status === "loading" ? ( | 87 | {state.status === "loading" ? ( |
| 87 | <View className="items-center gap-3 px-6 py-8"> | 88 | <View className="items-center gap-3 px-6 py-8"> |
| 88 | <ActivityIndicator /> | 89 | <AppActivityIndicator /> |
| 89 | <Text className="text-center text-sm text-foreground-muted">Reading crash log…</Text> | 90 | <Text className="text-center text-sm text-foreground-muted">Reading crash log…</Text> |
| 90 | </View> | 91 | </View> |
| 91 | ) : state.status === "unavailable" ? ( | 92 | ) : state.status === "unavailable" ? ( |
apps/mobile/src/features/files/FilePreviewFeedback.tsx+3-2| ... | @@ -1,5 +1,6 @@ | ... | @@ -1,5 +1,6 @@ |
| 1 | import { ActivityIndicator, View } from "react-native"; | 1 | import { View } from "react-native"; |
| 2 | 2 | ||
| 3 | import { AppActivityIndicator } from "../../components/AppActivityIndicator"; | ||
| 3 | import { AppText as Text } from "../../components/AppText"; | 4 | import { AppText as Text } from "../../components/AppText"; |
| 4 | import { cn } from "../../lib/cn"; | 5 | import { cn } from "../../lib/cn"; |
| 5 | 6 | ||
| ... | @@ -14,7 +15,7 @@ export function FilePreviewLoading(props: { | ... | @@ -14,7 +15,7 @@ export function FilePreviewLoading(props: { |
| 14 | props.background === "card" ? "bg-card" : "bg-sheet", | 15 | props.background === "card" ? "bg-card" : "bg-sheet", |
| 15 | )} | 16 | )} |
| 16 | > | 17 | > |
| 17 | <ActivityIndicator /> | 18 | <AppActivityIndicator /> |
| 18 | <Text className="text-center text-sm text-foreground-muted">{props.message}</Text> | 19 | <Text className="text-center text-sm text-foreground-muted">{props.message}</Text> |
| 19 | </View> | 20 | </View> |
| 20 | ); | 21 | ); |
apps/mobile/src/features/files/FileTreeBrowser.tsx+4-3| ... | @@ -1,8 +1,9 @@ | ... | @@ -1,8 +1,9 @@ |
| 1 | import { LegendList } from "@legendapp/list/react-native"; | 1 | import { LegendList } from "@legendapp/list/react-native"; |
| 2 | import type { ProjectEntry } from "@t3tools/contracts"; | 2 | import type { ProjectEntry } from "@t3tools/contracts"; |
| 3 | import { AppActivityIndicator } from "../../components/AppActivityIndicator"; | ||
| 3 | import { SymbolView } from "../../components/AppSymbol"; | 4 | import { SymbolView } from "../../components/AppSymbol"; |
| 4 | import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react"; | 5 | import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react"; |
| 5 | import { ActivityIndicator, Platform, Pressable, RefreshControl, View } from "react-native"; | 6 | import { Platform, Pressable, RefreshControl, View } from "react-native"; |
| 6 | import { useSafeAreaInsets } from "react-native-safe-area-context"; | 7 | import { useSafeAreaInsets } from "react-native-safe-area-context"; |
| 7 | 8 | ||
| 8 | import { AppText as Text } from "../../components/AppText"; | 9 | import { AppText as Text } from "../../components/AppText"; |
| ... | @@ -96,7 +97,7 @@ const FileTreeRow = memo(function FileTreeRow(props: { | ... | @@ -96,7 +97,7 @@ const FileTreeRow = memo(function FileTreeRow(props: { |
| 96 | {node.name} | 97 | {node.name} |
| 97 | </Text> | 98 | </Text> |
| 98 | {node.kind === "directory" && props.expanded && props.loading ? ( | 99 | {node.kind === "directory" && props.expanded && props.loading ? ( |
| 99 | <ActivityIndicator size="small" accessibilityLabel={`Loading ${node.name}`} /> | 100 | <AppActivityIndicator size="small" accessibilityLabel={`Loading ${node.name}`} /> |
| 100 | ) : null} | 101 | ) : null} |
| 101 | </Pressable> | 102 | </Pressable> |
| 102 | ); | 103 | ); |
| ... | @@ -296,7 +297,7 @@ export function FileTreeBrowser(props: { | ... | @@ -296,7 +297,7 @@ export function FileTreeBrowser(props: { |
| 296 | </Pressable> | 297 | </Pressable> |
| 297 | </> | 298 | </> |
| 298 | ) : props.isPending ? ( | 299 | ) : props.isPending ? ( |
| 299 | <ActivityIndicator size="small" /> | 300 | <AppActivityIndicator size="small" /> |
| 300 | ) : ( | 301 | ) : ( |
| 301 | <> | 302 | <> |
| 302 | <Text className="text-sm font-t3-bold text-foreground">No files found</Text> | 303 | <Text className="text-sm font-t3-bold text-foreground">No files found</Text> |
apps/mobile/src/features/files/WorkspaceFileWebPreview.tsx+3-2| ... | @@ -1,7 +1,8 @@ | ... | @@ -1,7 +1,8 @@ |
| 1 | import { useState } from "react"; | 1 | import { useState } from "react"; |
| 2 | import { ActivityIndicator, View } from "react-native"; | 2 | import { View } from "react-native"; |
| 3 | import { WebView } from "react-native-webview"; | 3 | import { WebView } from "react-native-webview"; |
| 4 | 4 | ||
| 5 | import { AppActivityIndicator } from "../../components/AppActivityIndicator"; | ||
| 5 | import { AppText as Text } from "../../components/AppText"; | 6 | import { AppText as Text } from "../../components/AppText"; |
| 6 | import { FilePreviewLoading } from "./FilePreviewFeedback"; | 7 | import { FilePreviewLoading } from "./FilePreviewFeedback"; |
| 7 | import { LoadingStrip } from "../../components/LoadingStrip"; | 8 | import { LoadingStrip } from "../../components/LoadingStrip"; |
| ... | @@ -46,7 +47,7 @@ export function WorkspaceFileWebPreview(props: { readonly uri: string | null }) | ... | @@ -46,7 +47,7 @@ export function WorkspaceFileWebPreview(props: { readonly uri: string | null }) |
| 46 | }} | 47 | }} |
| 47 | renderLoading={() => ( | 48 | renderLoading={() => ( |
| 48 | <View className="absolute inset-0 items-center justify-center bg-card"> | 49 | <View className="absolute inset-0 items-center justify-center bg-card"> |
| 49 | <ActivityIndicator /> | 50 | <AppActivityIndicator /> |
| 50 | </View> | 51 | </View> |
| 51 | )} | 52 | )} |
| 52 | style={{ flex: 1, backgroundColor: "transparent" }} | 53 | style={{ flex: 1, backgroundColor: "transparent" }} |
apps/mobile/src/features/home/HomeScreen.tsx+2-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | import { AppActivityIndicator } from "../../components/AppActivityIndicator"; | ||
| 1 | import { useAndroidControlSizing } from "../../components/useAndroidControlSizing"; | 2 | import { useAndroidControlSizing } from "../../components/useAndroidControlSizing"; |
| 2 | import type { ThreadMoveDestination } from "../threads/threadOrder"; | 3 | import type { ThreadMoveDestination } from "../threads/threadOrder"; |
| 3 | import { computeThreadMoveAvailability } from "../threads/threadOrder"; | 4 | import { computeThreadMoveAvailability } from "../threads/threadOrder"; |
| ... | @@ -15,7 +16,6 @@ import { useAtomValue } from "@effect/atom-react"; | ... | @@ -15,7 +16,6 @@ import { useAtomValue } from "@effect/atom-react"; |
| 15 | import { useFocusEffect } from "@react-navigation/native"; | 16 | import { useFocusEffect } from "@react-navigation/native"; |
| 16 | import { use, useCallback, useEffect, useMemo, useRef, useState, type ComponentProps } from "react"; | 17 | import { use, useCallback, useEffect, useMemo, useRef, useState, type ComponentProps } from "react"; |
| 17 | import { | 18 | import { |
| 18 | ActivityIndicator, | ||
| 19 | Platform, | 19 | Platform, |
| 20 | ScrollView, | 20 | ScrollView, |
| 21 | View, | 21 | View, |
| ... | @@ -947,7 +947,7 @@ export function HomeScreen(props: HomeScreenProps) { | ... | @@ -947,7 +947,7 @@ export function HomeScreen(props: HomeScreenProps) { |
| 947 | /> | 947 | /> |
| 948 | {emptyState.loading ? ( | 948 | {emptyState.loading ? ( |
| 949 | <View className="mt-4 items-center"> | 949 | <View className="mt-4 items-center"> |
| 950 | <ActivityIndicator colorClassName="accent-icon-muted" /> | 950 | <AppActivityIndicator colorClassName="accent-icon-muted" /> |
| 951 | </View> | 951 | </View> |
| 952 | ) : null} | 952 | ) : null} |
| 953 | </View> | 953 | </View> |
apps/mobile/src/features/home/WorkspaceConnectionTitle.tsx+3-2| ... | @@ -1,7 +1,8 @@ | ... | @@ -1,7 +1,8 @@ |
| 1 | import type { NativeStackNavigationOptions } from "@react-navigation/native-stack"; | 1 | import type { NativeStackNavigationOptions } from "@react-navigation/native-stack"; |
| 2 | import { useEffect, useRef, useState, type ReactNode } from "react"; | 2 | import { useEffect, useRef, useState, type ReactNode } from "react"; |
| 3 | import { ActivityIndicator, Animated, Platform, Pressable, View } from "react-native"; | 3 | import { Animated, Platform, Pressable, View } from "react-native"; |
| 4 | 4 | ||
| 5 | import { AppActivityIndicator } from "../../components/AppActivityIndicator"; | ||
| 5 | import { SymbolView } from "../../components/AppSymbol"; | 6 | import { SymbolView } from "../../components/AppSymbol"; |
| 6 | import { AppText as Text } from "../../components/AppText"; | 7 | import { AppText as Text } from "../../components/AppText"; |
| 7 | import { useAndroidControlSizing } from "../../components/useAndroidControlSizing"; | 8 | import { useAndroidControlSizing } from "../../components/useAndroidControlSizing"; |
| ... | @@ -134,7 +135,7 @@ export function WorkspaceConnectionTitle(props: { | ... | @@ -134,7 +135,7 @@ export function WorkspaceConnectionTitle(props: { |
| 134 | ]} | 135 | ]} |
| 135 | > | 136 | > |
| 136 | {status.showsProgress ? ( | 137 | {status.showsProgress ? ( |
| 137 | <ActivityIndicator | 138 | <AppActivityIndicator |
| 138 | colorClassName={"accent-icon-muted"} | 139 | colorClassName={"accent-icon-muted"} |
| 139 | size={Platform.OS === "android" ? Math.round(20 * scale) : "small"} | 140 | size={Platform.OS === "android" ? Math.round(20 * scale) : "small"} |
| 140 | /> | 141 | /> |
apps/mobile/src/features/projects/AddProjectScreen.tsx+5-4| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | import { AppActivityIndicator } from "../../components/AppActivityIndicator"; | ||
| 1 | import { MaterialListRow } from "../../components/MaterialListRow"; | 2 | import { MaterialListRow } from "../../components/MaterialListRow"; |
| 2 | import { SettingsScreen } from "../settings/components/SettingsScreen"; | 3 | import { SettingsScreen } from "../settings/components/SettingsScreen"; |
| 3 | import { ScreenScrollView as ScrollView } from "../../components/ScreenScrollView"; | 4 | import { ScreenScrollView as ScrollView } from "../../components/ScreenScrollView"; |
| ... | @@ -55,7 +56,7 @@ import { | ... | @@ -55,7 +56,7 @@ import { |
| 55 | import { CommonActions, StackActions, useNavigation } from "@react-navigation/native"; | 56 | import { CommonActions, StackActions, useNavigation } from "@react-navigation/native"; |
| 56 | import { SymbolView } from "../../components/AppSymbol"; | 57 | import { SymbolView } from "../../components/AppSymbol"; |
| 57 | import { useCallback, useEffect, useMemo, useRef, useState, type ReactNode } from "react"; | 58 | import { useCallback, useEffect, useMemo, useRef, useState, type ReactNode } from "react"; |
| 58 | import { Platform, ActivityIndicator, Alert, Pressable, View } from "react-native"; | 59 | import { Platform, Alert, Pressable, View } from "react-native"; |
| 59 | import { useSafeAreaInsets } from "react-native-safe-area-context"; | 60 | import { useSafeAreaInsets } from "react-native-safe-area-context"; |
| 60 | import * as Arr from "effect/Array"; | 61 | import * as Arr from "effect/Array"; |
| 61 | import * as Cause from "effect/Cause"; | 62 | import * as Cause from "effect/Cause"; |
| ... | @@ -265,7 +266,7 @@ function PrimaryActionButton(props: { | ... | @@ -265,7 +266,7 @@ function PrimaryActionButton(props: { |
| 265 | className="h-12 items-center justify-center rounded-full bg-primary active:opacity-70 disabled:opacity-45" | 266 | className="h-12 items-center justify-center rounded-full bg-primary active:opacity-70 disabled:opacity-45" |
| 266 | > | 267 | > |
| 267 | {props.loading ? ( | 268 | {props.loading ? ( |
| 268 | <ActivityIndicator colorClassName={String("accent-primary-foreground")} /> | 269 | <AppActivityIndicator colorClassName={String("accent-primary-foreground")} /> |
| 269 | ) : ( | 270 | ) : ( |
| 270 | <Text className="text-base font-t3-bold text-primary-foreground">{props.label}</Text> | 271 | <Text className="text-base font-t3-bold text-primary-foreground">{props.label}</Text> |
| 271 | )} | 272 | )} |
| ... | @@ -665,7 +666,7 @@ export function AddProjectSourceScreen() { | ... | @@ -665,7 +666,7 @@ export function AddProjectSourceScreen() { |
| 665 | )} | 666 | )} |
| 666 | </ListSection> | 667 | </ListSection> |
| 667 | {discoveryState.isPending ? ( | 668 | {discoveryState.isPending ? ( |
| 668 | <ActivityIndicator colorClassName="accent-icon-muted" /> | 669 | <AppActivityIndicator colorClassName="accent-icon-muted" /> |
| 669 | ) : null} | 670 | ) : null} |
| 670 | </> | 671 | </> |
| 671 | ) : null} | 672 | ) : null} |
| ... | @@ -918,7 +919,7 @@ function FolderBrowser(props: { | ... | @@ -918,7 +919,7 @@ function FolderBrowser(props: { |
| 918 | <ListSection> | 919 | <ListSection> |
| 919 | {fileAccess.isPending || (browseState.isPending && browseState.data === null) ? ( | 920 | {fileAccess.isPending || (browseState.isPending && browseState.data === null) ? ( |
| 920 | <View className="items-center py-5"> | 921 | <View className="items-center py-5"> |
| 921 | <ActivityIndicator colorClassName="accent-icon-muted" /> | 922 | <AppActivityIndicator colorClassName="accent-icon-muted" /> |
| 922 | </View> | 923 | </View> |
| 923 | ) : null} | 924 | ) : null} |
| 924 | {browsePath.canBrowseUp ? ( | 925 | {browsePath.canBrowseUp ? ( |
apps/mobile/src/features/review/ReviewSheet.tsx+2-2| ... | @@ -1,6 +1,7 @@ | ... | @@ -1,6 +1,7 @@ |
| 1 | import type { EnvironmentId, ThreadId } from "@t3tools/contracts"; | 1 | import type { EnvironmentId, ThreadId } from "@t3tools/contracts"; |
| 2 | import { formatDiffCount } from "@t3tools/client-runtime/diff-count"; | 2 | import { formatDiffCount } from "@t3tools/client-runtime/diff-count"; |
| 3 | import { useNavigation, type StaticScreenProps } from "@react-navigation/native"; | 3 | import { useNavigation, type StaticScreenProps } from "@react-navigation/native"; |
| 4 | import { AppActivityIndicator } from "../../components/AppActivityIndicator"; | ||
| 4 | import { nativeHeaderScrollEdgeEffects } from "../../native/StackHeader"; | 5 | import { nativeHeaderScrollEdgeEffects } from "../../native/StackHeader"; |
| 5 | import { ScreenHeader } from "../../components/ScreenHeader"; | 6 | import { ScreenHeader } from "../../components/ScreenHeader"; |
| 6 | import type { ScreenHeaderMenuItem } from "../../components/ScreenHeader.types"; | 7 | import type { ScreenHeaderMenuItem } from "../../components/ScreenHeader.types"; |
| ... | @@ -19,7 +20,6 @@ import { | ... | @@ -19,7 +20,6 @@ import { |
| 19 | useState, | 20 | useState, |
| 20 | } from "react"; | 21 | } from "react"; |
| 21 | import { | 22 | import { |
| 22 | ActivityIndicator, | ||
| 23 | FlatList, | 23 | FlatList, |
| 24 | Platform, | 24 | Platform, |
| 25 | Pressable, | 25 | Pressable, |
| ... | @@ -855,7 +855,7 @@ export function ReviewSheet(props: ReviewSheetProps) { | ... | @@ -855,7 +855,7 @@ export function ReviewSheet(props: ReviewSheetProps) { |
| 855 | Platform.OS !== "android" && "border-b border-border bg-card", | 855 | Platform.OS !== "android" && "border-b border-border bg-card", |
| 856 | )} | 856 | )} |
| 857 | > | 857 | > |
| 858 | <ActivityIndicator size="small" /> | 858 | <AppActivityIndicator size="small" /> |
| 859 | <Text className="text-xs text-foreground-muted">Loading diff…</Text> | 859 | <Text className="text-xs text-foreground-muted">Loading diff…</Text> |
| 860 | </View> | 860 | </View> |
| 861 | ) : parsedDiff.kind === "empty" ? ( | 861 | ) : parsedDiff.kind === "empty" ? ( |
apps/mobile/src/features/settings/SettingsClientStorageRouteScreen.tsx+3-2| ... | @@ -1,9 +1,10 @@ | ... | @@ -1,9 +1,10 @@ |
| 1 | import { AppActivityIndicator } from "../../components/AppActivityIndicator"; | ||
| 1 | import { ScreenScrollView as ScrollView } from "../../components/ScreenScrollView"; | 2 | import { ScreenScrollView as ScrollView } from "../../components/ScreenScrollView"; |
| 2 | import { useAtomSet, useAtomValue } from "@effect/atom-react"; | 3 | import { useAtomSet, useAtomValue } from "@effect/atom-react"; |
| 3 | import { type EnvironmentMachineKind, resolveEnvironmentMachineKind } from "@t3tools/contracts"; | 4 | import { type EnvironmentMachineKind, resolveEnvironmentMachineKind } from "@t3tools/contracts"; |
| 4 | import { AsyncResult } from "effect/reactivity"; | 5 | import { AsyncResult } from "effect/reactivity"; |
| 5 | import { useMemo } from "react"; | 6 | import { useMemo } from "react"; |
| 6 | import { ActivityIndicator, Alert, Pressable, View } from "react-native"; | 7 | import { Alert, Pressable, View } from "react-native"; |
| 7 | import { useSafeAreaInsets } from "react-native-safe-area-context"; | 8 | import { useSafeAreaInsets } from "react-native-safe-area-context"; |
| 8 | 9 | ||
| 9 | import { AppText as Text } from "../../components/AppText"; | 10 | import { AppText as Text } from "../../components/AppText"; |
| ... | @@ -99,7 +100,7 @@ export function SettingsClientStorageRouteScreen() { | ... | @@ -99,7 +100,7 @@ export function SettingsClientStorageRouteScreen() { |
| 99 | </View> | 100 | </View> |
| 100 | ) : !summary ? ( | 101 | ) : !summary ? ( |
| 101 | <View className="items-center gap-3 px-6 py-8"> | 102 | <View className="items-center gap-3 px-6 py-8"> |
| 102 | <ActivityIndicator /> | 103 | <AppActivityIndicator /> |
| 103 | <Text className="text-center text-sm text-foreground-muted"> | 104 | <Text className="text-center text-sm text-foreground-muted"> |
| 104 | Inspecting cached data… | 105 | Inspecting cached data… |
| 105 | </Text> | 106 | </Text> |
apps/mobile/src/features/settings/components/SettingsActionRow.tsx+5-2| ... | @@ -1,6 +1,7 @@ | ... | @@ -1,6 +1,7 @@ |
| 1 | import type { ComponentProps } from "react"; | 1 | import type { ComponentProps } from "react"; |
| 2 | import { ActivityIndicator, Platform, Pressable } from "react-native"; | 2 | import { Platform, Pressable } from "react-native"; |
| 3 | 3 | ||
| 4 | import { AppActivityIndicator } from "../../../components/AppActivityIndicator"; | ||
| 4 | import { SymbolView } from "../../../components/AppSymbol"; | 5 | import { SymbolView } from "../../../components/AppSymbol"; |
| 5 | import { AppText as Text } from "../../../components/AppText"; | 6 | import { AppText as Text } from "../../../components/AppText"; |
| 6 | import { MaterialListRow } from "../../../components/MaterialListRow"; | 7 | import { MaterialListRow } from "../../../components/MaterialListRow"; |
| ... | @@ -26,7 +27,9 @@ export function SettingsActionRow(props: { | ... | @@ -26,7 +27,9 @@ export function SettingsActionRow(props: { |
| 26 | weight="regular" | 27 | weight="regular" |
| 27 | /> | 28 | /> |
| 28 | ); | 29 | ); |
| 29 | const spinner = props.loading ? <ActivityIndicator colorClassName={iconColorClassName} /> : null; | 30 | const spinner = props.loading ? ( |
| 31 | <AppActivityIndicator colorClassName={iconColorClassName} /> | ||
| 32 | ) : null; | ||
| 30 | 33 | ||
| 31 | if (Platform.OS === "android") { | 34 | if (Platform.OS === "android") { |
| 32 | return ( | 35 | return ( |
apps/mobile/src/features/settings/components/SettingsLegalDocumentRouteScreen.tsx+3-2| ... | @@ -1,8 +1,9 @@ | ... | @@ -1,8 +1,9 @@ |
| 1 | import { type NavigationProp, type ParamListBase, useNavigation } from "@react-navigation/native"; | 1 | import { type NavigationProp, type ParamListBase, useNavigation } from "@react-navigation/native"; |
| 2 | import { useCallback, useLayoutEffect, useState } from "react"; | 2 | import { useCallback, useLayoutEffect, useState } from "react"; |
| 3 | import { ActivityIndicator, Linking, Pressable, View } from "react-native"; | 3 | import { Linking, Pressable, View } from "react-native"; |
| 4 | import { WebView } from "react-native-webview"; | 4 | import { WebView } from "react-native-webview"; |
| 5 | 5 | ||
| 6 | import { AppActivityIndicator } from "../../../components/AppActivityIndicator"; | ||
| 6 | import { AppText as Text } from "../../../components/AppText"; | 7 | import { AppText as Text } from "../../../components/AppText"; |
| 7 | import { LoadingStrip } from "../../../components/LoadingStrip"; | 8 | import { LoadingStrip } from "../../../components/LoadingStrip"; |
| 8 | import { SymbolView } from "../../../components/AppSymbol"; | 9 | import { SymbolView } from "../../../components/AppSymbol"; |
| ... | @@ -172,7 +173,7 @@ export function SettingsLegalDocumentRouteScreen({ | ... | @@ -172,7 +173,7 @@ export function SettingsLegalDocumentRouteScreen({ |
| 172 | }} | 173 | }} |
| 173 | renderLoading={() => ( | 174 | renderLoading={() => ( |
| 174 | <View className="absolute inset-0 items-center justify-center bg-sheet"> | 175 | <View className="absolute inset-0 items-center justify-center bg-sheet"> |
| 175 | <ActivityIndicator /> | 176 | <AppActivityIndicator /> |
| 176 | </View> | 177 | </View> |
| 177 | )} | 178 | )} |
| 178 | style={{ flex: 1, backgroundColor: "transparent" }} | 179 | style={{ flex: 1, backgroundColor: "transparent" }} |
apps/mobile/src/features/threads/GitActionProgressOverlay.tsx+3-2| ... | @@ -1,8 +1,9 @@ | ... | @@ -1,8 +1,9 @@ |
| 1 | import * as Haptics from "expo-haptics"; | 1 | import * as Haptics from "expo-haptics"; |
| 2 | import { GlassView } from "expo-glass-effect"; | 2 | import { GlassView } from "expo-glass-effect"; |
| 3 | import { AppActivityIndicator } from "../../components/AppActivityIndicator"; | ||
| 3 | import { SymbolView } from "../../components/AppSymbol"; | 4 | import { SymbolView } from "../../components/AppSymbol"; |
| 4 | import { useCallback, useEffect, useRef } from "react"; | 5 | import { useCallback, useEffect, useRef } from "react"; |
| 5 | import { ActivityIndicator, Pressable, StyleSheet, useColorScheme, View } from "react-native"; | 6 | import { Pressable, StyleSheet, useColorScheme, View } from "react-native"; |
| 6 | import Animated, { FadeIn, FadeOut, LinearTransition } from "react-native-reanimated"; | 7 | import Animated, { FadeIn, FadeOut, LinearTransition } from "react-native-reanimated"; |
| 7 | import { useSafeAreaInsets } from "react-native-safe-area-context"; | 8 | import { useSafeAreaInsets } from "react-native-safe-area-context"; |
| 8 | 9 | ||
| ... | @@ -158,7 +159,7 @@ function OverlayContent(props: { readonly progress: GitActionProgress }) { | ... | @@ -158,7 +159,7 @@ function OverlayContent(props: { readonly progress: GitActionProgress }) { |
| 158 | function OverlayIcon(props: { readonly phase: GitActionProgress["phase"] }) { | 159 | function OverlayIcon(props: { readonly phase: GitActionProgress["phase"] }) { |
| 159 | switch (props.phase) { | 160 | switch (props.phase) { |
| 160 | case "running": | 161 | case "running": |
| 161 | return <ActivityIndicator size="small" colorClassName={"accent-icon"} />; | 162 | return <AppActivityIndicator size="small" colorClassName={"accent-icon"} />; |
| 162 | case "success": | 163 | case "success": |
| 163 | return ( | 164 | return ( |
| 164 | <View className="h-6 w-6 items-center justify-center rounded-full bg-green-500"> | 165 | <View className="h-6 w-6 items-center justify-center rounded-full bg-green-500"> |
apps/mobile/src/features/threads/NewTaskContextPickerScreens.tsx+4-11| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | import { AppActivityIndicator } from "../../components/AppActivityIndicator"; | ||
| 1 | import { MaterialListRow } from "../../components/MaterialListRow"; | 2 | import { MaterialListRow } from "../../components/MaterialListRow"; |
| 2 | import type { EnvironmentProject } from "@t3tools/client-runtime/state/shell"; | 3 | import type { EnvironmentProject } from "@t3tools/client-runtime/state/shell"; |
| 3 | import { shouldCheckoutNewTaskBranch } from "./new-task-context-presentation"; | 4 | import { shouldCheckoutNewTaskBranch } from "./new-task-context-presentation"; |
| ... | @@ -11,15 +12,7 @@ import { | ... | @@ -11,15 +12,7 @@ import { |
| 11 | import * as Haptics from "expo-haptics"; | 12 | import * as Haptics from "expo-haptics"; |
| 12 | import { useNavigation } from "@react-navigation/native"; | 13 | import { useNavigation } from "@react-navigation/native"; |
| 13 | import { useCallback, useEffect, useMemo, useRef, useState, type ReactNode } from "react"; | 14 | import { useCallback, useEffect, useMemo, useRef, useState, type ReactNode } from "react"; |
| 14 | import { | 15 | import { Alert, Platform, Pressable, ScrollView, TextInput, View } from "react-native"; |
| 15 | ActivityIndicator, | ||
| 16 | Alert, | ||
| 17 | Platform, | ||
| 18 | Pressable, | ||
| 19 | ScrollView, | ||
| 20 | TextInput, | ||
| 21 | View, | ||
| 22 | } from "react-native"; | ||
| 23 | import { useSafeAreaInsets } from "react-native-safe-area-context"; | 16 | import { useSafeAreaInsets } from "react-native-safe-area-context"; |
| 24 | 17 | ||
| 25 | import { AndroidScreenHeader } from "../../components/AndroidScreenHeader"; | 18 | import { AndroidScreenHeader } from "../../components/AndroidScreenHeader"; |
| ... | @@ -486,7 +479,7 @@ export function BranchPickerScreen(props: { | ... | @@ -486,7 +479,7 @@ export function BranchPickerScreen(props: { |
| 486 | : 0, | 479 | : 0, |
| 487 | }} | 480 | }} |
| 488 | > | 481 | > |
| 489 | {props.loading ? <ActivityIndicator /> : null} | 482 | {props.loading ? <AppActivityIndicator /> : null} |
| 490 | <Text className="text-center text-sm text-foreground-muted"> | 483 | <Text className="text-center text-sm text-foreground-muted"> |
| 491 | {props.loading | 484 | {props.loading |
| 492 | ? "Loading branches…" | 485 | ? "Loading branches…" |
| ... | @@ -525,7 +518,7 @@ export function BranchPickerScreen(props: { | ... | @@ -525,7 +518,7 @@ export function BranchPickerScreen(props: { |
| 525 | ListFooterComponent={ | 518 | ListFooterComponent={ |
| 526 | props.refreshing ? ( | 519 | props.refreshing ? ( |
| 527 | <View className="items-center py-4"> | 520 | <View className="items-center py-4"> |
| 528 | <ActivityIndicator /> | 521 | <AppActivityIndicator /> |
| 529 | </View> | 522 | </View> |
| 530 | ) : null | 523 | ) : null |
| 531 | } | 524 | } |
apps/mobile/src/features/threads/NewTaskRouteScreen.tsx+3-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | import { AppActivityIndicator } from "../../components/AppActivityIndicator"; | ||
| 1 | import { MaterialListRow } from "../../components/MaterialListRow"; | 2 | import { MaterialListRow } from "../../components/MaterialListRow"; |
| 2 | import { ScreenHeader } from "../../components/ScreenHeader"; | 3 | import { ScreenHeader } from "../../components/ScreenHeader"; |
| 3 | import { | 4 | import { |
| ... | @@ -15,7 +16,7 @@ import { | ... | @@ -15,7 +16,7 @@ import { |
| 15 | } from "@t3tools/client-runtime/state/runtime"; | 16 | } from "@t3tools/client-runtime/state/runtime"; |
| 16 | import type { EnvironmentProject } from "@t3tools/client-runtime/state/shell"; | 17 | import type { EnvironmentProject } from "@t3tools/client-runtime/state/shell"; |
| 17 | import { useEffect, useRef, useState } from "react"; | 18 | import { useEffect, useRef, useState } from "react"; |
| 18 | import { ActivityIndicator, Alert, Platform, Pressable, View } from "react-native"; | 19 | import { Alert, Platform, Pressable, View } from "react-native"; |
| 19 | import { useSafeAreaInsets } from "react-native-safe-area-context"; | 20 | import { useSafeAreaInsets } from "react-native-safe-area-context"; |
| 20 | import { cn } from "../../lib/cn"; | 21 | import { cn } from "../../lib/cn"; |
| 21 | import { MaterialScreenContent } from "../../components/MaterialScreenContent"; | 22 | import { MaterialScreenContent } from "../../components/MaterialScreenContent"; |
| ... | @@ -369,7 +370,7 @@ export function NewTaskRouteScreen({ route }: StaticScreenProps<NewTaskRoutePara | ... | @@ -369,7 +370,7 @@ export function NewTaskRouteScreen({ route }: StaticScreenProps<NewTaskRoutePara |
| 369 | )} | 370 | )} |
| 370 | > | 371 | > |
| 371 | {projectEmptyState.loading ? ( | 372 | {projectEmptyState.loading ? ( |
| 372 | <ActivityIndicator colorClassName="accent-icon-muted" /> | 373 | <AppActivityIndicator colorClassName="accent-icon-muted" /> |
| 373 | ) : null} | 374 | ) : null} |
| 374 | <Text className="text-center text-lg font-t3-bold text-foreground"> | 375 | <Text className="text-center text-lg font-t3-bold text-foreground"> |
| 375 | {projectEmptyState.title} | 376 | {projectEmptyState.title} |
apps/mobile/src/features/threads/ThreadFeed.tsx+5-5| ... | @@ -1,6 +1,7 @@ | ... | @@ -1,6 +1,7 @@ |
| 1 | import { ThreadContextDivider } from "./thread-context-divider"; | 1 | import { ThreadContextDivider } from "./thread-context-divider"; |
| 2 | import { ThreadHandoffRow } from "./thread-handoff-row"; | 2 | import { ThreadHandoffRow } from "./thread-handoff-row"; |
| 3 | import { SecretRequestCard } from "./SecretRequestCard"; | 3 | import { SecretRequestCard } from "./SecretRequestCard"; |
| 4 | import { AppActivityIndicator } from "../../components/AppActivityIndicator"; | ||
| 4 | import { | 5 | import { |
| 5 | WorktreeWorkingHeader, | 6 | WorktreeWorkingHeader, |
| 6 | WorktreeSetupCard, | 7 | WorktreeSetupCard, |
| ... | @@ -79,7 +80,6 @@ import { | ... | @@ -79,7 +80,6 @@ import { |
| 79 | type PartialMarkdownTheme, | 80 | type PartialMarkdownTheme, |
| 80 | } from "react-native-nitro-markdown"; | 81 | } from "react-native-nitro-markdown"; |
| 81 | import { | 82 | import { |
| 82 | ActivityIndicator, | ||
| 83 | Alert, | 83 | Alert, |
| 84 | Image, | 84 | Image, |
| 85 | Platform, | 85 | Platform, |
| ... | @@ -378,7 +378,7 @@ function AssistantForkButton(props: { | ... | @@ -378,7 +378,7 @@ function AssistantForkButton(props: { |
| 378 | className="h-7 w-7 items-center justify-center disabled:opacity-40" | 378 | className="h-7 w-7 items-center justify-center disabled:opacity-40" |
| 379 | > | 379 | > |
| 380 | {busy ? ( | 380 | {busy ? ( |
| 381 | <ActivityIndicator size="small" /> | 381 | <AppActivityIndicator size="small" /> |
| 382 | ) : ( | 382 | ) : ( |
| 383 | <SymbolView | 383 | <SymbolView |
| 384 | name="arrow.triangle.branch" | 384 | name="arrow.triangle.branch" |
| ... | @@ -416,7 +416,7 @@ function MessageAttachmentImage(props: { | ... | @@ -416,7 +416,7 @@ function MessageAttachmentImage(props: { |
| 416 | if (uri === null) { | 416 | if (uri === null) { |
| 417 | return ( | 417 | return ( |
| 418 | <View className={`${props.className} items-center justify-center`}> | 418 | <View className={`${props.className} items-center justify-center`}> |
| 419 | <ActivityIndicator /> | 419 | <AppActivityIndicator /> |
| 420 | </View> | 420 | </View> |
| 421 | ); | 421 | ); |
| 422 | } | 422 | } |
| ... | @@ -630,7 +630,7 @@ function MessageAttachmentFile(props: { | ... | @@ -630,7 +630,7 @@ function MessageAttachmentFile(props: { |
| 630 | > | 630 | > |
| 631 | <View className="h-12 w-10 shrink-0 items-center justify-center rounded-lg bg-subtle"> | 631 | <View className="h-12 w-10 shrink-0 items-center justify-center rounded-lg bg-subtle"> |
| 632 | {opening ? ( | 632 | {opening ? ( |
| 633 | <ActivityIndicator size="small" /> | 633 | <AppActivityIndicator size="small" /> |
| 634 | ) : ( | 634 | ) : ( |
| 635 | <PierreEntryIcon path={attachment.name} kind="file" size={26} /> | 635 | <PierreEntryIcon path={attachment.name} kind="file" size={26} /> |
| 636 | )} | 636 | )} |
| ... | @@ -3310,7 +3310,7 @@ function ThreadFeedLoadEarlierControl(props: ThreadFeedHistoryControls) { | ... | @@ -3310,7 +3310,7 @@ function ThreadFeedLoadEarlierControl(props: ThreadFeedHistoryControls) { |
| 3310 | className="min-h-9 flex-row items-center justify-center gap-2 rounded-full border border-border/60 bg-surface/80 px-4 py-2 disabled:opacity-50" | 3310 | className="min-h-9 flex-row items-center justify-center gap-2 rounded-full border border-border/60 bg-surface/80 px-4 py-2 disabled:opacity-50" |
| 3311 | > | 3311 | > |
| 3312 | {props.loading ? ( | 3312 | {props.loading ? ( |
| 3313 | <ActivityIndicator size="small" color={accentColor} /> | 3313 | <AppActivityIndicator size="small" color={accentColor} /> |
| 3314 | ) : ( | 3314 | ) : ( |
| 3315 | <SymbolView name="chevron.up" size={12} tintColor={accentColor} type="monochrome" /> | 3315 | <SymbolView name="chevron.up" size={12} tintColor={accentColor} type="monochrome" /> |
| 3316 | )} | 3316 | )} |
apps/mobile/src/features/threads/ThreadMarkdownImage.tsx+3-9| ... | @@ -1,14 +1,8 @@ | ... | @@ -1,14 +1,8 @@ |
| 1 | import type { AssetResource, EnvironmentId } from "@t3tools/contracts"; | 1 | import type { AssetResource, EnvironmentId } from "@t3tools/contracts"; |
| 2 | import { createContext, useContext, useEffect, useId, useState } from "react"; | 2 | import { createContext, useContext, useEffect, useId, useState } from "react"; |
| 3 | import { | 3 | import { Image, Pressable, StyleSheet, View, type ViewStyle } from "react-native"; |
| 4 | ActivityIndicator, | ||
| 5 | Image, | ||
| 6 | Pressable, | ||
| 7 | StyleSheet, | ||
| 8 | View, | ||
| 9 | type ViewStyle, | ||
| 10 | } from "react-native"; | ||
| 11 | 4 | ||
| 5 | import { AppActivityIndicator } from "../../components/AppActivityIndicator"; | ||
| 12 | import { AppText as Text } from "../../components/AppText"; | 6 | import { AppText as Text } from "../../components/AppText"; |
| 13 | import type { FilePreviewSource } from "../../components/FilePreviewModal"; | 7 | import type { FilePreviewSource } from "../../components/FilePreviewModal"; |
| 14 | import { MediaActionsMenu } from "../../components/MediaActionsMenu"; | 8 | import { MediaActionsMenu } from "../../components/MediaActionsMenu"; |
| ... | @@ -96,7 +90,7 @@ export function ThreadMarkdownImageView(props: { | ... | @@ -96,7 +90,7 @@ export function ThreadMarkdownImageView(props: { |
| 96 | {failed ? ( | 90 | {failed ? ( |
| 97 | <Text className="text-xs text-foreground-muted">Image unavailable</Text> | 91 | <Text className="text-xs text-foreground-muted">Image unavailable</Text> |
| 98 | ) : ( | 92 | ) : ( |
| 99 | <ActivityIndicator /> | 93 | <AppActivityIndicator /> |
| 100 | )} | 94 | )} |
| 101 | </Pressable> | 95 | </Pressable> |
| 102 | </MediaActionsMenu> | 96 | </MediaActionsMenu> |
apps/mobile/src/features/threads/floating-working-control.tsx+3-3| ... | @@ -3,7 +3,6 @@ import { formatDuration } from "@t3tools/shared/orchestrationTiming"; | ... | @@ -3,7 +3,6 @@ import { formatDuration } from "@t3tools/shared/orchestrationTiming"; |
| 3 | import { GlassContainer, GlassView } from "expo-glass-effect"; | 3 | import { GlassContainer, GlassView } from "expo-glass-effect"; |
| 4 | import { type ReactNode, useEffect, useRef, useState } from "react"; | 4 | import { type ReactNode, useEffect, useRef, useState } from "react"; |
| 5 | import { | 5 | import { |
| 6 | ActivityIndicator, | ||
| 7 | type LayoutChangeEvent, | 6 | type LayoutChangeEvent, |
| 8 | Pressable, | 7 | Pressable, |
| 9 | Text as SystemText, | 8 | Text as SystemText, |
| ... | @@ -22,6 +21,7 @@ import Animated, { | ... | @@ -22,6 +21,7 @@ import Animated, { |
| 22 | } from "react-native-reanimated"; | 21 | } from "react-native-reanimated"; |
| 23 | import { withUniwind } from "uniwind"; | 22 | import { withUniwind } from "uniwind"; |
| 24 | 23 | ||
| 24 | import { AppActivityIndicator } from "../../components/AppActivityIndicator"; | ||
| 25 | import { AppText as Text } from "../../components/AppText"; | 25 | import { AppText as Text } from "../../components/AppText"; |
| 26 | import { SymbolView } from "../../components/AppSymbol"; | 26 | import { SymbolView } from "../../components/AppSymbol"; |
| 27 | import { ControlPill } from "../../components/ControlPill"; | 27 | import { ControlPill } from "../../components/ControlPill"; |
| ... | @@ -364,7 +364,7 @@ function FloatingStatusLabel(props: { | ... | @@ -364,7 +364,7 @@ function FloatingStatusLabel(props: { |
| 364 | className="gap-2" | 364 | className="gap-2" |
| 365 | onLayout={props.onLayout} | 365 | onLayout={props.onLayout} |
| 366 | > | 366 | > |
| 367 | <ActivityIndicator size="small" colorClassName="accent-icon-muted" /> | 367 | <AppActivityIndicator size="small" colorClassName="accent-icon-muted" /> |
| 368 | <Text className="shrink font-t3-medium text-xs text-foreground" numberOfLines={1}> | 368 | <Text className="shrink font-t3-medium text-xs text-foreground" numberOfLines={1}> |
| 369 | {props.status.label} | 369 | {props.status.label} |
| 370 | </Text> | 370 | </Text> |
| ... | @@ -402,7 +402,7 @@ function FloatingStatusLabel(props: { | ... | @@ -402,7 +402,7 @@ function FloatingStatusLabel(props: { |
| 402 | onPress={props.status.onPress} | 402 | onPress={props.status.onPress} |
| 403 | > | 403 | > |
| 404 | {props.status.tone === "reconnecting" ? ( | 404 | {props.status.tone === "reconnecting" ? ( |
| 405 | <ActivityIndicator size="small" colorClassName="accent-icon-muted" /> | 405 | <AppActivityIndicator size="small" colorClassName="accent-icon-muted" /> |
| 406 | ) : ( | 406 | ) : ( |
| 407 | <View className="h-2 w-2 rounded-full bg-red-500" /> | 407 | <View className="h-2 w-2 rounded-full bg-red-500" /> |
| 408 | )} | 408 | )} |
apps/mobile/src/features/threads/worktree-setup-card.tsx+10-5| ... | @@ -6,8 +6,9 @@ import { | ... | @@ -6,8 +6,9 @@ import { |
| 6 | import { worktreeSetupAgentStarted } from "@t3tools/client-runtime/worktree-setup"; | 6 | import { worktreeSetupAgentStarted } from "@t3tools/client-runtime/worktree-setup"; |
| 7 | import { formatDuration } from "@t3tools/shared/orchestrationTiming"; | 7 | import { formatDuration } from "@t3tools/shared/orchestrationTiming"; |
| 8 | import { useEffect, useState } from "react"; | 8 | import { useEffect, useState } from "react"; |
| 9 | import { ActivityIndicator, AppState, Pressable, ScrollView, View } from "react-native"; | 9 | import { AppState, Platform, Pressable, ScrollView, View } from "react-native"; |
| 10 | import { useSafeAreaInsets } from "react-native-safe-area-context"; | 10 | import { useSafeAreaInsets } from "react-native-safe-area-context"; |
| 11 | import { AppActivityIndicator } from "../../components/AppActivityIndicator"; | ||
| 11 | import { AppText as Text } from "../../components/AppText"; | 12 | import { AppText as Text } from "../../components/AppText"; |
| 12 | import { SymbolView, type AppSymbolName } from "../../components/AppSymbol"; | 13 | import { SymbolView, type AppSymbolName } from "../../components/AppSymbol"; |
| 13 | import { WorktreeSetupSheet } from "./worktree-setup-sheet"; | 14 | import { WorktreeSetupSheet } from "./worktree-setup-sheet"; |
| ... | @@ -97,10 +98,14 @@ export function WorktreeSetupCard(props: WorktreeSetupCardProps) { | ... | @@ -97,10 +98,14 @@ export function WorktreeSetupCard(props: WorktreeSetupCardProps) { |
| 97 | } | 98 | } |
| 98 | > | 99 | > |
| 99 | {backgroundSetup ? ( | 100 | {backgroundSetup ? ( |
| 100 | <ActivityIndicator | 101 | <AppActivityIndicator |
| 101 | size="small" | 102 | size={Platform.OS === "android" ? 12 : "small"} |
| 102 | colorClassName="accent-icon-muted" | 103 | colorClassName="accent-icon-muted" |
| 103 | style={{ width: 12, height: 12, transform: [{ scale: 0.65 }] }} | 104 | style={{ |
| 105 | width: 12, | ||
| 106 | height: 12, | ||
| 107 | transform: Platform.OS === "android" ? undefined : [{ scale: 0.65 }], | ||
| 108 | }} | ||
| 104 | /> | 109 | /> |
| 105 | ) : failed ? ( | 110 | ) : failed ? ( |
| 106 | <SymbolView | 111 | <SymbolView |
| ... | @@ -302,7 +307,7 @@ function StageRow({ | ... | @@ -302,7 +307,7 @@ function StageRow({ |
| 302 | > | 307 | > |
| 303 | <View className="w-6 items-center"> | 308 | <View className="w-6 items-center"> |
| 304 | {stage.status === "running" && animate ? ( | 309 | {stage.status === "running" && animate ? ( |
| 305 | <ActivityIndicator | 310 | <AppActivityIndicator |
| 306 | size="small" | 311 | size="small" |
| 307 | colorClassName="accent-icon-muted" | 312 | colorClassName="accent-icon-muted" |
| 308 | style={{ transform: [{ scale: 0.75 }] }} | 313 | style={{ transform: [{ scale: 0.75 }] }} |
apps/mobile/src/features/voice-input/ComposerDictationControl.tsx+2-2| ... | @@ -1,7 +1,6 @@ | ... | @@ -1,7 +1,6 @@ |
| 1 | import type { VoiceInputPhase, VoiceInputState } from "@t3tools/client-runtime/voice-input"; | 1 | import type { VoiceInputPhase, VoiceInputState } from "@t3tools/client-runtime/voice-input"; |
| 2 | import { memo, useCallback, useLayoutEffect, useState, type ReactNode } from "react"; | 2 | import { memo, useCallback, useLayoutEffect, useState, type ReactNode } from "react"; |
| 3 | import { | 3 | import { |
| 4 | ActivityIndicator, | ||
| 5 | Linking, | 4 | Linking, |
| 6 | Platform, | 5 | Platform, |
| 7 | Pressable, | 6 | Pressable, |
| ... | @@ -20,6 +19,7 @@ import Animated, { | ... | @@ -20,6 +19,7 @@ import Animated, { |
| 20 | type SharedValue, | 19 | type SharedValue, |
| 21 | } from "react-native-reanimated"; | 20 | } from "react-native-reanimated"; |
| 22 | 21 | ||
| 22 | import { AppActivityIndicator } from "../../components/AppActivityIndicator"; | ||
| 23 | import { AppText as Text } from "../../components/AppText"; | 23 | import { AppText as Text } from "../../components/AppText"; |
| 24 | import { SymbolView, type AppSymbolName } from "../../components/AppSymbol"; | 24 | import { SymbolView, type AppSymbolName } from "../../components/AppSymbol"; |
| 25 | import { cn } from "../../lib/cn"; | 25 | import { cn } from "../../lib/cn"; |
| ... | @@ -304,7 +304,7 @@ function VoiceActionButton(props: { | ... | @@ -304,7 +304,7 @@ function VoiceActionButton(props: { |
| 304 | ) : null} | 304 | ) : null} |
| 305 | <View className="absolute inset-0 items-center justify-center"> | 305 | <View className="absolute inset-0 items-center justify-center"> |
| 306 | {props.loading ? ( | 306 | {props.loading ? ( |
| 307 | <ActivityIndicator size="small" colorClassName="accent-icon-muted" /> | 307 | <AppActivityIndicator size="small" colorClassName="accent-icon-muted" /> |
| 308 | ) : ( | 308 | ) : ( |
| 309 | <SymbolView | 309 | <SymbolView |
| 310 | name={props.icon} | 310 | name={props.icon} |