| author | |
| committer | |
| log | a1390ac655927cda10cfab3e4678d456db7b54b8 |
| tree | 992ae8dbd0ab666c9ba91c6072667d62c194580c |
| parent | 05a8c6016a4070b92f5d51e7a79b9c76814947df |
| signature | Signed by PGP key B5690EEEBB952194 |
3 files changed, 61 insertions(+), 49 deletions(-)
apps/mobile/src/features/settings/SettingsServerControlsRouteScreen.tsx+9-8| ... | ... | @@ -22,6 +22,7 @@ import { |
| 22 | 22 | SettingsEnvironmentFilterHeader, |
| 23 | 23 | } from "./components/SettingsEnvironmentFilterHeader"; |
| 24 | 24 | import { SettingsSection } from "./components/SettingsSection"; |
| 25 | import { SettingsControlRow } from "./components/SettingsControlRow"; | |
| 25 | 26 | import { SettingsSwitchRow } from "./components/SettingsSwitchRow"; |
| 26 | 27 | import { SettingsProjectOverridesSection } from "./components/SettingsProjectOverridesSection"; |
| 27 | 28 | import { useSettingsEnvironmentFilter } from "./settings-environment-filter"; |
| ... | ... | @@ -454,21 +455,21 @@ function FanoutSwitchRow(props: { |
| 454 | 455 | } |
| 455 | 456 | |
| 456 | 457 | return ( |
| 457 | <View className="flex-row items-center gap-4 p-4"> | |
| 458 | <SymbolView name={props.icon} size={22} tintColorClassName="accent-icon" /> | |
| 459 | <View className="min-w-0 flex-1 gap-1"> | |
| 460 | <Text className="text-lg text-foreground">{props.label}</Text> | |
| 461 | <Text className="text-sm text-foreground-muted">{props.subtitle}</Text> | |
| 462 | </View> | |
| 458 | <SettingsControlRow | |
| 459 | disabled={props.disabled} | |
| 460 | icon={props.icon} | |
| 461 | label={props.label} | |
| 462 | subtitle={props.subtitle} | |
| 463 | > | |
| 463 | 464 | <Pressable |
| 464 | 465 | accessibilityLabel={`Set ${props.label} on for selected environments`} |
| 465 | 466 | accessibilityRole="button" |
| 466 | 467 | disabled={props.disabled} |
| 467 | className="rounded-full bg-subtle px-3 py-2 active:opacity-70 disabled:opacity-40" | |
| 468 | className="rounded-full bg-subtle px-3 py-2 active:opacity-70" | |
| 468 | 469 | onPress={() => props.onValueChange(true)} |
| 469 | 470 | > |
| 470 | 471 | <Text className="text-sm font-t3-medium text-foreground">Mixed · Set on</Text> |
| 471 | 472 | </Pressable> |
| 472 | </View> | |
| 473 | </SettingsControlRow> | |
| 473 | 474 | ); |
| 474 | 475 | } |
apps/mobile/src/features/settings/components/SettingsControlRow.tsx created+39| ... | ... | @@ -0,0 +1,39 @@ |
| 1 | import type { ComponentProps, ReactNode } from "react"; | |
| 2 | import { Platform, View } from "react-native"; | |
| 3 | ||
| 4 | import { SymbolView } from "../../../components/AppSymbol"; | |
| 5 | import { AppText as Text } from "../../../components/AppText"; | |
| 6 | import { cn } from "../../../lib/cn"; | |
| 7 | ||
| 8 | export function SettingsControlRow(props: { | |
| 9 | readonly disabled?: boolean; | |
| 10 | readonly icon: ComponentProps<typeof SymbolView>["name"]; | |
| 11 | readonly label: string; | |
| 12 | readonly subtitle?: string; | |
| 13 | readonly children: ReactNode; | |
| 14 | }) { | |
| 15 | return ( | |
| 16 | <View | |
| 17 | className={cn( | |
| 18 | "flex-row items-center gap-4 p-4 android:min-h-14 android:py-3", | |
| 19 | props.subtitle && "android:min-h-18", | |
| 20 | props.disabled && "opacity-[0.45]", | |
| 21 | )} | |
| 22 | > | |
| 23 | <SymbolView | |
| 24 | name={props.icon} | |
| 25 | size={Platform.OS === "android" ? 24 : 22} | |
| 26 | tintColorClassName="accent-icon" | |
| 27 | type="monochrome" | |
| 28 | weight="regular" | |
| 29 | /> | |
| 30 | <View className="min-w-0 flex-1 android:gap-1"> | |
| 31 | <Text className="text-lg text-foreground android:text-base">{props.label}</Text> | |
| 32 | {props.subtitle ? ( | |
| 33 | <Text className="text-sm text-foreground-muted">{props.subtitle}</Text> | |
| 34 | ) : null} | |
| 35 | </View> | |
| 36 | {props.children} | |
| 37 | </View> | |
| 38 | ); | |
| 39 | } |
apps/mobile/src/features/settings/components/SettingsSwitchRow.tsx+13-41| ... | ... | @@ -1,55 +1,27 @@ |
| 1 | import { cn } from "../../../lib/cn"; | |
| 2 | 1 | import type { ComponentProps } from "react"; |
| 3 | import { Platform, View } from "react-native"; | |
| 4 | 2 | |
| 5 | import { SymbolView } from "../../../components/AppSymbol"; | |
| 6 | import { AppText as Text } from "../../../components/AppText"; | |
| 7 | 3 | import { ThemedSwitch } from "../../../components/ThemedSwitch"; |
| 4 | import { SettingsControlRow } from "./SettingsControlRow"; | |
| 8 | 5 | |
| 9 | type SymbolName = ComponentProps<typeof SymbolView>["name"]; | |
| 10 | ||
| 11 | export function SettingsSwitchRow(props: { | |
| 12 | readonly disabled?: boolean; | |
| 13 | readonly icon: SymbolName; | |
| 14 | readonly label: string; | |
| 15 | readonly subtitle?: string; | |
| 16 | readonly value: boolean; | |
| 17 | readonly onValueChange: (value: boolean) => void; | |
| 18 | }) { | |
| 6 | export function SettingsSwitchRow( | |
| 7 | props: Omit<ComponentProps<typeof SettingsControlRow>, "children"> & { | |
| 8 | readonly value: boolean; | |
| 9 | readonly onValueChange: (value: boolean) => void; | |
| 10 | }, | |
| 11 | ) { | |
| 19 | 12 | return ( |
| 20 | <View | |
| 21 | className={cn( | |
| 22 | "flex-row items-center gap-4", | |
| 23 | Platform.OS === "android" ? "min-h-14 px-4 py-3" : "p-4", | |
| 24 | Platform.OS === "android" && props.subtitle && "min-h-18", | |
| 25 | props.disabled && "opacity-[0.45]", | |
| 26 | )} | |
| 13 | <SettingsControlRow | |
| 14 | disabled={props.disabled} | |
| 15 | icon={props.icon} | |
| 16 | label={props.label} | |
| 17 | subtitle={props.subtitle} | |
| 27 | 18 | > |
| 28 | <SymbolView | |
| 29 | name={props.icon} | |
| 30 | size={Platform.OS === "android" ? 24 : 22} | |
| 31 | tintColorClassName="accent-icon" | |
| 32 | type="monochrome" | |
| 33 | weight="regular" | |
| 34 | /> | |
| 35 | <View className={cn("min-w-0 flex-1", Platform.OS === "android" && "gap-1")}> | |
| 36 | <Text | |
| 37 | className={ | |
| 38 | Platform.OS === "android" ? "text-base text-foreground" : "text-lg text-foreground" | |
| 39 | } | |
| 40 | > | |
| 41 | {props.label} | |
| 42 | </Text> | |
| 43 | {props.subtitle ? ( | |
| 44 | <Text className="text-sm text-foreground-muted">{props.subtitle}</Text> | |
| 45 | ) : null} | |
| 46 | </View> | |
| 47 | 19 | <ThemedSwitch |
| 48 | 20 | accessibilityLabel={props.label} |
| 49 | 21 | disabled={props.disabled} |
| 50 | 22 | onValueChange={props.onValueChange} |
| 51 | 23 | value={props.value} |
| 52 | 24 | /> |
| 53 | </View> | |
| 25 | </SettingsControlRow> | |
| 54 | 26 | ); |
| 55 | 27 | } |