alantoa / react-native-awesome-slider

🚀 An anwesome <Slider/> that supports various features haptic, lottie, animation, ballon, etc.
MIT License
228 stars 28 forks source link

[2.1.1] Thumb not moving after updating from 2.0.8 to 2.1.1 #26

Closed efstathiosntonas closed 1 year ago

efstathiosntonas commented 1 year ago

Hi @alantoa, after upgrading from 2.0.8 to 2.1.1 the thumb stopped moving while playing audio files, downgrading to 2.0.8 works as expected. I've seen you've made some perfomance improvements using refs, I believe the ref value isn't updating the UI (at least in my case where progress is an event and not static thumb movement).

This is how I use it:

import React, { useCallback, useMemo } from "react";
import isEqual from "react-fast-compare";
import { Platform, StyleSheet, View } from "react-native";
import { Slider } from "react-native-awesome-slider";
import Animated, { useDerivedValue, useSharedValue } from "react-native-reanimated";
import { breadcrumb } from "utils/utils";

import { msToHMS, pausePlayer, seekPlayer } from "../AudioManager";

interface IProps {
  disabled: boolean;
  duration: number | undefined;
  messagePosition: string;
  onSeekComplete: (position: number, duration: number) => Promise<void>;
  progress: Animated.SharedValue<number>;
  themeContext: any;
}

const TrackPlayerProgress = ({
  disabled,
  duration,
  messagePosition,
  progress,
  themeContext
}: IProps) => {
  const isScrubbing = useSharedValue(false);
  const minValue = useSharedValue(0);

  const maxValue = useDerivedValue(() => {
    return duration;
  }, [duration]);

  const pauseAudio = useCallback(async () => {
    breadcrumb("User Paused Audio Message");
    await pausePlayer();
  }, []);

  const onSlidingStart = useCallback(async () => {
    await pauseAudio();
  }, [pauseAudio]);

  const onSlidingComplete = (slideValue: number) => {
    seekPlayer(slideValue).then(() => {
      isScrubbing.value = false;
    });
  };

  const theme = useMemo(
    () => ({
      minimumTrackTintColor:
        messagePosition === "right"
          ? themeContext.chatScreen.audioPlayer.right.minimumTrack
          : themeContext.chatScreen.audioPlayer.left.minimumTrack,
      maximumTrackTintColor:
        messagePosition === "right"
          ? themeContext.chatScreen.audioPlayer.right.track
          : themeContext.chatScreen.audioPlayer.left.track,
      bubbleBackgroundColor: themeContext.chatScreen.audioPlayer.timeBubble,
      bubbleTextColor: themeContext.chatScreen.audioPlayer.timeBubbleText
    }),
    [messagePosition, themeContext]
  );

  return (
    <View style={styles.container}>
      <View style={styles.sliderInnerContainer}>
        <Slider
          bubble={msToHMS}
          disableTrackFollow
          bubbleTranslateY={Platform.OS === "ios" ? -20 : -30}
          containerStyle={styles.sliderContainer}
          disable={disabled}
          isScrubbing={isScrubbing}
          // @ts-ignore
          maximumValue={maxValue}
          minimumValue={minValue}
          onSlidingComplete={onSlidingComplete}
          onSlidingStart={onSlidingStart}
          progress={progress}
          sliderHeight={5}
          style={styles.slider}
          thumbWidth={20}
          theme={theme}
        />
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    alignItems: "center",
    marginLeft: 5,
    marginRight: 15
  },
  sliderInnerContainer: {
    maxWidth: 500,
    position: "relative",
    width: "100%"
  },
  sliderContainer: {
    borderRadius: 50
  },
  slider: {
    borderRadius: 12,
    marginBottom: 14,
    marginTop: 16
  }
});
export default React.memo(TrackPlayerProgress, isEqual);

progress prop is const progress = useSharedValue(0); and it's been incremented by the audio player progress event.

Let me know if you need any additional info, I will go through the changes you've introduced and let you know if I figure out what is going on.

efstathiosntonas commented 1 year ago

disableTrackFollow prop is the culprit. Trying to figure what is causing it.

alantoa commented 1 year ago

hey, @efstathiosntonas, its a bit repetitive during the swipe, so I remove thumb logic. this is before video, maybe need to do adjust for this.

https://user-images.githubusercontent.com/37520667/191925501-3b051d5e-1245-473a-8692-09e7f36b5488.mp4

efstathiosntonas commented 1 year ago

After going through the entire diff between 2.0.8 and 2.1.1 I realised that you're using ref only on the bubble so discard the intro on the initial comment. Something is causing the thumb to not move if disableTrackFollow is enabled. Looking into it now.

alantoa commented 1 year ago

just check it, make sense! maybe we just make the disableTrackFollow change to Animated.SharedValue, and turn it when isScrubbing=true.

alantoa commented 1 year ago

we don't need it when isScrubbing = false.

alantoa commented 1 year ago

also, add you to manage of this lib, feel free to change it.

alantoa commented 1 year ago

just fixed thumbIndex.value === 0; to thumbIndex.value = 0;, and released to v2.1.2, thanks found it. also disableTrackFollow still needs to check.

efstathiosntonas commented 1 year ago

Thanks for adding me as a collaborator. This useAnimatedReaction is causing the issue, at 2.0.8 the calculations where different.

edit: link: https://github.com/alantoa/react-native-awesome-slider/blob/5a1fc1c084530d3c897d85428479de2e8d110adc/src/slide.tsx#L656

efstathiosntonas commented 1 year ago

This entire function is missing from 2.1.1

  // setting thumbValue
  useAnimatedReaction(
    () => {
      if (isScrubbing && isScrubbing.value) {
        return undefined;
      }
      if (step) {
        return undefined;
      }
      const currentValue =
        (progress.value / (minimumValue.value + maximumValue.value)) *
        (width.value - (disableTrackFollow ? thumbWidth : 0));
      return clamp(currentValue, 0, width.value - thumbWidth);
    },
    data => {
      if (data !== undefined) {
        thumbValue.value = data;
      }
    },
    [thumbWidth, maximumValue, minimumValue, step, progress, width],
  );

when i added it back it worked as it should 🤔

alantoa commented 1 year ago

yeah, I didn't know you needed this before. now I know you add isScrubbing prop to work this, but I'm not sure other people will add isScrubbing prop, I hope this component is simple to use. so I think need an isScrubbingInner value to use the inner component, that's prefect!

efstathiosntonas commented 1 year ago

It won't work if I remove the isScrubbing prop and enable the disableTrackFollow prop. Am I missing something on the "config"?

Just to be sure we're on the same page, this is how I'm using it:

https://user-images.githubusercontent.com/717975/191932005-3efe69a3-5ae5-452a-aed2-a75727d4a949.mov

alantoa commented 1 year ago

https://github.com/alantoa/react-native-awesome-slider/pull/27/files just created a PR, I think should fix both issues. and released v2.1.3.

efstathiosntonas commented 1 year ago

Just tested it, it works as it should. Thanks @alantoa, good work!