From 6168ae492f13333f4277bbefd9a5d8f080a82511 Mon Sep 17 00:00:00 2001 From: Utkarsh Vishnoi Date: Tue, 28 Mar 2023 10:22:19 +0530 Subject: [PATCH 1/4] Android Implementation for Secondary Progress --- .gitignore | 3 +++ .../slider/ReactSlider.java | 11 +++++++++++ .../slider/ReactSliderManagerImpl.java | 19 +++++++++++++++++++ .../slider/ReactSliderManager.java | 12 ++++++++++++ .../slider/ReactSliderManager.java | 10 ++++++++++ package/src/RNCSliderNativeComponent.ts | 2 ++ package/src/Slider.tsx | 12 ++++++++++++ package/typings/index.d.ts | 15 +++++++++++++++ 8 files changed, 84 insertions(+) diff --git a/.gitignore b/.gitignore index 0aa21a68..cf3c3b37 100644 --- a/.gitignore +++ b/.gitignore @@ -69,3 +69,6 @@ src/dist # Expo .expo web-build + +# VS Code +.vscode diff --git a/package/android/src/main/java/com/reactnativecommunity/slider/ReactSlider.java b/package/android/src/main/java/com/reactnativecommunity/slider/ReactSlider.java index a68c49e4..37fefd85 100644 --- a/package/android/src/main/java/com/reactnativecommunity/slider/ReactSlider.java +++ b/package/android/src/main/java/com/reactnativecommunity/slider/ReactSlider.java @@ -57,6 +57,8 @@ public class ReactSlider extends AppCompatSeekBar { */ private double mValue = 0; + private double mBufferedValue = 0; + private boolean isSliding = false; /** If zero it's determined automatically. */ @@ -120,6 +122,11 @@ private void disableStateListAnimatorIfNeeded() { updateValue(); } + /* package */ void setBufferedValue(double value) { + mBufferedValue = value; + updateBufferedValue(); + } + /* package */ void setStep(double step) { mStep = step; updateAll(); @@ -263,6 +270,10 @@ private void updateValue() { setProgress((int) Math.round((mValue - mMinValue) / (mMaxValue - mMinValue) * getTotalSteps())); } + private void updateBufferedValue() { + setSecondaryProgress((int) Math.round((mBufferedValue - mMinValue) / (mMaxValue - mMinValue) * getTotalSteps())); + } + private int getTotalSteps() { return (int) Math.ceil((mMaxValue - mMinValue) / getStepValue()); } diff --git a/package/android/src/main/java/com/reactnativecommunity/slider/ReactSliderManagerImpl.java b/package/android/src/main/java/com/reactnativecommunity/slider/ReactSliderManagerImpl.java index dff1f9dd..0aa0de07 100644 --- a/package/android/src/main/java/com/reactnativecommunity/slider/ReactSliderManagerImpl.java +++ b/package/android/src/main/java/com/reactnativecommunity/slider/ReactSliderManagerImpl.java @@ -44,6 +44,10 @@ public static void setValue(ReactSlider view, double value) { } } + public static void setBufferedValue(ReactSlider view, double value) { + view.setBufferedValue(value); + } + public static void setMinimumValue(ReactSlider view, double value) { view.setMinValue(value); } @@ -116,6 +120,21 @@ public static void setMaximumTrackTintColor(ReactSlider view, Integer color) { } } + public static void setBufferedTrackTintColor(ReactSlider view, Integer color) { + LayerDrawable drawable = (LayerDrawable) view.getProgressDrawable().getCurrent(); + Drawable secondaryProgress = drawable.findDrawableByLayerId(android.R.id.secondaryProgress); + if (color == null) { + secondaryProgress.clearColorFilter(); + } else { + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) { + secondaryProgress.setColorFilter(new PorterDuffColorFilter((int)color, PorterDuff.Mode.SRC_IN)); + } + else { + secondaryProgress.setColorFilter(color, PorterDuff.Mode.SRC_IN); + } + } + } + public static void setInverted(ReactSlider view, boolean inverted) { if (inverted) view.setScaleX(-1f); else view.setScaleX(1f); diff --git a/package/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java b/package/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java index 0d8e1972..cb7c2476 100644 --- a/package/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java +++ b/package/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java @@ -106,6 +106,12 @@ public void setValue(ReactSlider view, float value) { ReactSliderManagerImpl.setValue(view, value); } + @Override + @ReactProp(name = "bufferedValue", defaultFloat = 0f) + public void setBufferedValue(ReactSlider view, float value) { + ReactSliderManagerImpl.setBufferedValue(view, value); + } + @Override @ReactProp(name = "minimumValue", defaultFloat = 0f) public void setMinimumValue(ReactSlider view, double value) { @@ -136,6 +142,12 @@ public void setMinimumTrackTintColor(ReactSlider view, Integer color) { ReactSliderManagerImpl.setMinimumTrackTintColor(view, color); } + @Override + @ReactProp(name = "bufferedTrackTintColor", customType = "Color") + public void setBufferedTrackTintColor(ReactSlider view, Integer color) { + ReactSliderManagerImpl.setBufferedTrackTintColor(view, color); + } + @Override @ReactProp(name = "maximumTrackTintColor", customType = "Color") public void setMaximumTrackTintColor(ReactSlider view, Integer color) { diff --git a/package/android/src/oldarch/java/com/reactnativecommunity/slider/ReactSliderManager.java b/package/android/src/oldarch/java/com/reactnativecommunity/slider/ReactSliderManager.java index 9be02a44..4af1026e 100644 --- a/package/android/src/oldarch/java/com/reactnativecommunity/slider/ReactSliderManager.java +++ b/package/android/src/oldarch/java/com/reactnativecommunity/slider/ReactSliderManager.java @@ -125,6 +125,11 @@ public void setValue(ReactSlider view, float value) { ReactSliderManagerImpl.setValue(view, value); } + @ReactProp(name = "bufferedValue", defaultFloat = 0f) + public void setBufferedValue(ReactSlider view, float value) { + ReactSliderManagerImpl.setBufferedValue(view, value); + } + @ReactProp(name = "minimumValue", defaultFloat = 0f) public void setMinimumValue(ReactSlider view, double value) { ReactSliderManagerImpl.setMinimumValue(view, value); @@ -160,6 +165,11 @@ public void setMinimumTrackTintColor(ReactSlider view, Integer color) { ReactSliderManagerImpl.setMinimumTrackTintColor(view, color); } + @ReactProp(name = "bufferedTrackTintColor", customType = "Color") + public void setBufferedTrackTintColor(ReactSlider view, Integer color) { + ReactSliderManagerImpl.setBufferedTrackTintColor(view, color); + } + @ReactProp(name = "thumbImage") public void setThumbImage(ReactSlider view, @Nullable ReadableMap source) { ReactSliderManagerImpl.setThumbImage(view, source); diff --git a/package/src/RNCSliderNativeComponent.ts b/package/src/RNCSliderNativeComponent.ts index cab4abfb..5445f238 100644 --- a/package/src/RNCSliderNativeComponent.ts +++ b/package/src/RNCSliderNativeComponent.ts @@ -26,6 +26,7 @@ export interface NativeProps extends ViewProps { maximumValue?: Float; minimumTrackImage?: ImageSource; minimumTrackTintColor?: ColorValue; + bufferedTrackTintColor?: ColorValue; minimumValue?: Float; onChange?: BubblingEventHandler; onRNCSliderSlidingStart?: DirectEventHandler; @@ -37,6 +38,7 @@ export interface NativeProps extends ViewProps { thumbTintColor?: ColorValue; trackImage?: ImageSource; value?: Float; + bufferedValue?: Float; lowerLimit?: Float; upperLimit?: Float; } diff --git a/package/src/Slider.tsx b/package/src/Slider.tsx index 45983ec4..78191678 100644 --- a/package/src/Slider.tsx +++ b/package/src/Slider.tsx @@ -87,6 +87,15 @@ type Props = ViewProps & */ value?: number; + /** + * Write-only property representing the secondaryProgress of the slider. + * Entered once at the beginning still acts as an initial value. + * The value should be between minimumValue and maximumValue, + * which default to 0 and 1 respectively. + * Default value is 0. + */ + bufferedValue?: number; + /** * Step value of the slider. The value should be * between 0 and (maximumValue - minimumValue). @@ -120,6 +129,8 @@ type Props = ViewProps & */ minimumTrackTintColor?: ColorValue; + bufferedTrackTintColor?: ColorValue; + /** * The color used for the track to the right of the button. * Overrides the default blue gradient image on iOS. @@ -351,6 +362,7 @@ const SliderWithRef = React.forwardRef(SliderComponent); SliderWithRef.defaultProps = { value: 0, + bufferedValue: 0, minimumValue: 0, maximumValue: 1, step: 0, diff --git a/package/typings/index.d.ts b/package/typings/index.d.ts index abae2dcb..96f93a2d 100644 --- a/package/typings/index.d.ts +++ b/package/typings/index.d.ts @@ -108,6 +108,12 @@ export interface SliderProps */ minimumTrackTintColor?: string; + /** + * The color used for the buffered track (secondaryProgress) + * Overrides the default grey gradient image. + */ + bufferedTrackTintColor?: string; + /** * Initial minimum value of the slider. Default value is 0. */ @@ -157,6 +163,15 @@ export interface SliderProps */ value?: number; + /** + * Write-only property representing the bufferedValue of the slider. + * Entered once at the beginning still acts as an initial value. + * The value should be between minimumValue and maximumValue, + * which default to 0 and 1 respectively. + * Default value is 0. + */ + bufferedValue?: number; + /** * Reverses the direction of the slider. */ From f8753f1e84783c06af512b2106a3e00b0a2f030f Mon Sep 17 00:00:00 2001 From: Utkarsh Vishnoi Date: Thu, 30 Mar 2023 22:13:56 +0530 Subject: [PATCH 2/4] Updated Readme --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 1035d099..85eb261a 100644 --- a/README.md +++ b/README.md @@ -97,8 +97,10 @@ To use this library you need to ensure you are using the correct version of Reac | `onValueChange` | Callback continuously called while the user is dragging the slider. | function | No | | | `step` | Step value of the slider. The value should be between 0 and (maximumValue - minimumValue). Default value is 0.
On Windows OS the default value is 1% of slider's range (from `minimumValue` to `maximumValue`). | number | No | | | `maximumTrackTintColor` | The color used for the track to the right of the button.
Overrides the default gray gradient image on iOS. | [color](https://reactnative.dev/docs/colors) | No | | +| `bufferedTrackTintColor` | The color used for the track for the secondaryProgress of the slider component. | [color](https://reactnative.dev/docs/colors) | No | Android | | `testID` | Used to locate this view in UI automation tests. | string | No | | | `value` | Write-only property representing the value of the slider. Can be used to programmatically control the position of the thumb. Entered once at the beginning still acts as an initial value. Changing the value programmatically does not trigger any event.
The value should be between minimumValue and maximumValue, which default to 0 and 1 respectively. Default value is 0.
_This is not a controlled component_, you don't need to update the value during dragging. | number | No | | +| `bufferedValue` | Write-only property representing the secondaryProgress of the slider. Entered once at the beginning still acts as an initial value.
The value should be between minimumValue and maximumValue, which default to 0 and 1 respectively. Default value is 0.
_This is not a controlled component_ | number | No | Android | | `tapToSeek` | Permits tapping on the slider track to set the thumb position.
Defaults to false on iOS. No effect on Android or Windows. | bool | No | iOS | | `inverted` | Reverses the direction of the slider.
Default value is false. | bool | No | | | `vertical` | Changes the orientation of the slider to vertical, if set to `true`.
Default value is false. | bool | No | Windows | From b6336a6362f80d017ea632a4d55281b3cb44ee83 Mon Sep 17 00:00:00 2001 From: "maciej.lodygowski" Date: Fri, 27 Sep 2024 17:44:43 +0200 Subject: [PATCH 3/4] fix: improve pr --- example/src/Examples.tsx | 14 ++++++++ .../slider/ReactSlider.java | 3 +- package/typings/index.d.ts | 36 +++++++++---------- 3 files changed, 34 insertions(+), 19 deletions(-) diff --git a/example/src/Examples.tsx b/example/src/Examples.tsx index 05c96c71..4ef20c7d 100644 --- a/example/src/Examples.tsx +++ b/example/src/Examples.tsx @@ -513,6 +513,20 @@ export const examples: Props[] = [ ); }, }, + { + title: 'Buffer value on Android', + render() { + return ( + + ); + }, + }, { title: 'onSlidingStart', render(): React.ReactElement { diff --git a/package/android/src/main/java/com/reactnativecommunity/slider/ReactSlider.java b/package/android/src/main/java/com/reactnativecommunity/slider/ReactSlider.java index 37fefd85..60ea686c 100644 --- a/package/android/src/main/java/com/reactnativecommunity/slider/ReactSlider.java +++ b/package/android/src/main/java/com/reactnativecommunity/slider/ReactSlider.java @@ -124,7 +124,7 @@ private void disableStateListAnimatorIfNeeded() { /* package */ void setBufferedValue(double value) { mBufferedValue = value; - updateBufferedValue(); + updateAll(); } /* package */ void setStep(double step) { @@ -238,6 +238,7 @@ private void updateAll() { updateLowerLimit(); updateUpperLimit(); updateValue(); + updateBufferedValue(); } /** Update limit based on props limit, max and min diff --git a/package/typings/index.d.ts b/package/typings/index.d.ts index 96f93a2d..5968926f 100644 --- a/package/typings/index.d.ts +++ b/package/typings/index.d.ts @@ -1,7 +1,7 @@ import * as React from 'react'; -import { FC } from 'react'; +import {FC} from 'react'; import * as ReactNative from 'react-native'; -import { ImageURISource } from 'react-native'; +import {ImageURISource} from 'react-native'; type Constructor = new (...args: any[]) => T; @@ -14,6 +14,21 @@ export interface SliderPropsAndroid extends ReactNative.ViewProps { * Color of the foreground switch grip. */ thumbTintColor?: string; + + /** + * Write-only property representing the bufferedValue of the slider. + * Entered once at the beginning still acts as an initial value. + * The value should be between minimumValue and maximumValue, + * which default to 0 and 1 respectively. + * Default value is 0. + */ + bufferedValue?: number; + + /** + * The color used for the buffered track (secondaryProgress) + * Overrides the default grey gradient image. + */ + bufferedTrackTintColor?: string; } export interface SliderRef { @@ -108,12 +123,6 @@ export interface SliderProps */ minimumTrackTintColor?: string; - /** - * The color used for the buffered track (secondaryProgress) - * Overrides the default grey gradient image. - */ - bufferedTrackTintColor?: string; - /** * Initial minimum value of the slider. Default value is 0. */ @@ -163,15 +172,6 @@ export interface SliderProps */ value?: number; - /** - * Write-only property representing the bufferedValue of the slider. - * Entered once at the beginning still acts as an initial value. - * The value should be between minimumValue and maximumValue, - * which default to 0 and 1 respectively. - * Default value is 0. - */ - bufferedValue?: number; - /** * Reverses the direction of the slider. */ @@ -183,7 +183,7 @@ export interface SliderProps StepMarker?: FC; /** - * + * */ renderStepNumber?: boolean; From 66939d15860c004d0a9cb8621619604a32e229c6 Mon Sep 17 00:00:00 2001 From: "maciej.lodygowski" Date: Fri, 27 Sep 2024 17:46:04 +0200 Subject: [PATCH 4/4] test: update snapshot --- package/src/__tests__/__snapshots__/Slider.test.tsx.snap | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/package/src/__tests__/__snapshots__/Slider.test.tsx.snap b/package/src/__tests__/__snapshots__/Slider.test.tsx.snap index c16d44b0..9862273a 100644 --- a/package/src/__tests__/__snapshots__/Slider.test.tsx.snap +++ b/package/src/__tests__/__snapshots__/Slider.test.tsx.snap @@ -23,6 +23,7 @@ exports[` accessibilityState disabled sets disabled={true} 1`] = ` "disabled": true, } } + bufferedValue={0} disabled={true} inverted={false} lowerLimit={-9007199254740991} @@ -81,6 +82,7 @@ exports[` disabled prop overrides accessibilityState.disabled 1`] = ` "disabled": true, } } + bufferedValue={0} disabled={true} inverted={false} lowerLimit={-9007199254740991} @@ -139,6 +141,7 @@ exports[` disabled prop overrides accessibilityState.enabled 1`] = ` "disabled": false, } } + bufferedValue={0} disabled={false} inverted={false} lowerLimit={-9007199254740991} @@ -192,6 +195,7 @@ exports[` renders a slider with custom props 1`] = ` } > renders a slider with custom stepMaker 1`] = ` renders disabled slider 1`] = ` "disabled": true, } } + bufferedValue={0} disabled={true} inverted={false} lowerLimit={-9007199254740991} @@ -32411,6 +32417,7 @@ exports[` renders enabled slider 1`] = ` } >