From acf2ff2579334bd6b8a5fce1d86878d9f6b2b092 Mon Sep 17 00:00:00 2001 From: "whey.party" Date: Mon, 1 Dec 2025 11:55:25 +0100 Subject: [PATCH] attempt 2 of slider android crash fix --- src/components/forms/Slider.tsx | 220 +++++--------------- src/screens/Settings/AppearanceSettings.tsx | 6 +- 2 files changed, 52 insertions(+), 174 deletions(-) diff --git a/src/components/forms/Slider.tsx b/src/components/forms/Slider.tsx index 401e4e842..237ef83b3 100644 --- a/src/components/forms/Slider.tsx +++ b/src/components/forms/Slider.tsx @@ -1,187 +1,67 @@ -import {useCallback, useEffect, useRef, useState} from 'react' -import {type StyleProp, View, type ViewStyle} from 'react-native' -import {Gesture, GestureDetector} from 'react-native-gesture-handler' -import Animated, { - runOnJS, - useAnimatedStyle, - useSharedValue, - withSpring, -} from 'react-native-reanimated' +import {type ViewStyle} from 'react-native' +import {Slider as RNSlider} from '@miblanchard/react-native-slider' -import {useHaptics} from '#/lib/haptics' -import {atoms as a, platform, useTheme} from '#/alf' +import {useTheme} from '#/alf' -export interface SliderProps { +interface SliderProps { value: number onValueChange: (value: number) => void - min?: number - max?: number + minimumValue?: number + maximumValue?: number step?: number - label?: string - accessibilityHint?: string - style?: StyleProp - debounce?: number + trackStyle?: ViewStyle + minimumTrackStyle?: ViewStyle + thumbStyle?: ViewStyle + thumbTouchSize?: {width: number; height: number} } export function Slider({ value, onValueChange, - min = 0, - max = 100, + minimumValue = 0, + maximumValue = 1, step = 1, - label, - accessibilityHint, - style, - debounce, + trackStyle, + minimumTrackStyle, + thumbStyle, + thumbTouchSize = {width: 40, height: 40}, }: SliderProps) { const t = useTheme() - const playHaptic = useHaptics() - const timerRef = useRef(undefined) - - const [width, setWidth] = useState(0) - - const progress = useSharedValue(0) - const isPressed = useSharedValue(false) - - useEffect(() => { - if (!isPressed.value) { - const clamped = Math.min(Math.max(value, min), max) - const normalized = (clamped - min) / (max - min) - progress.value = withSpring(normalized, {overshootClamping: true}) - } - }, [value, min, max, progress, isPressed]) - - useEffect(() => { - return () => { - if (timerRef.current) clearTimeout(timerRef.current) - } - }, []) - - const updateValueJS = useCallback( - (val: number) => { - if (debounce && debounce > 0) { - if (timerRef.current) { - clearTimeout(timerRef.current) - } - timerRef.current = setTimeout(() => { - onValueChange(val) - }, debounce) - } else { - onValueChange(val) - } - }, - [onValueChange, debounce], - ) - - const handleValueChange = useCallback( - (newProgress: number) => { - 'worklet' - const rawValue = min + newProgress * (max - min) - - const steppedValue = Math.round(rawValue / step) * step - const clamped = Math.min(Math.max(steppedValue, min), max) - - runOnJS(updateValueJS)(clamped) - }, - [min, max, step, updateValueJS], - ) - - const pan = Gesture.Pan() - .onBegin(e => { - isPressed.value = true - - if (width > 0) { - const newProgress = Math.min(Math.max(e.x / width, 0), 1) - progress.value = newProgress - handleValueChange(newProgress) - } - }) - .onUpdate(e => { - if (width === 0) return - const newProgress = Math.min(Math.max(e.x / width, 0), 1) - progress.value = newProgress - handleValueChange(newProgress) - }) - .onFinalize(() => { - isPressed.value = false - runOnJS(playHaptic)('Light') - }) - - const thumbAnimatedStyle = useAnimatedStyle(() => { - const translateX = progress.value * width - return { - transform: [ - {translateX: translateX - 12}, - {scale: isPressed.value ? 1.1 : 1}, - ], - } - }) - - const trackAnimatedStyle = useAnimatedStyle(() => { - return { - width: `${progress.value * 100}%`, - } - }) return ( - - - setWidth(e.nativeEvent.layout.width)}> - - - - - - - - + onValueChange(values[0])} + minimumValue={minimumValue} + maximumValue={maximumValue} + step={step} + trackStyle={{ + height: 4, + borderRadius: 2, + backgroundColor: t.atoms.bg_contrast_50.backgroundColor, + ...trackStyle, + }} + minimumTrackStyle={{ + height: 4, + borderRadius: 2, + backgroundColor: t.palette.primary_500, + ...minimumTrackStyle, + }} + thumbStyle={{ + width: 24, + height: 24, + borderRadius: 12, + borderWidth: 1, + borderColor: t.atoms.border_contrast_low.borderColor, + backgroundColor: t.atoms.bg.backgroundColor, + shadowColor: '#000', + shadowOffset: {width: 0, height: 2}, + shadowOpacity: 0.15, + shadowRadius: 4, + elevation: 3, + ...thumbStyle, + }} + thumbTouchSize={thumbTouchSize} + /> ) } diff --git a/src/screens/Settings/AppearanceSettings.tsx b/src/screens/Settings/AppearanceSettings.tsx index de049fcee..39f1fa299 100644 --- a/src/screens/Settings/AppearanceSettings.tsx +++ b/src/screens/Settings/AppearanceSettings.tsx @@ -184,13 +184,11 @@ export function AppearanceSettingsScreen({}: Props) { Hue shift the colors: -- 2.47.3