Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v4.5.5: Unblock the build for v0.76 of React Native , jumping slider issue #667

Open
jimshidbachu opened this issue Nov 7, 2024 · 1 comment
Labels
bug report Something isn't working new architecture Issue relates to react-native new architecture

Comments

@jimshidbachu
Copy link

jimshidbachu commented Nov 7, 2024

Environment

  • are you using the new architecture?

yes

  • which version of react & react-native are you using?

"react": "^18.3.1",
"react-native": "^0.76.0",

Description

The latest version of @react-native-community/slider (v4.5.5) is causing issues with the slider functionality in my audio player. Specifically:

Slider jumps unexpectedly when interacted with.
Slider does not move smoothly during audio playback.
This issue was not present in the previous version (@react-native-community/slider v4.5.4), where the slider worked as expected. The setup for my project with v4.5.4 included:

React: 18.3.1
React Native: 0.75.4
Upgrading to v4.5.5 of the slider introduced the issue, despite other dependencies remaining the same.

Screenrecording_20241107_122323.mp4

Reproducible Demo

Integrate @react-native-community/slider v4.5.5 in an audio player project.
Attempt to move the slider to different positions during audio playback.
Observe that the slider does not respond smoothly and jumps to unexpected positions.

Repro implementation:

import React, {memo, useState} from 'react';
import {Alert, View} from 'react-native';
import Ionicons from 'react-native-vector-icons/Ionicons';
import Sound from 'react-native-sound';
import {APIURL} from '../Context/Endpoints';
import {PrimaryColor} from '../config';

import Slider from '@react-native-community/slider';

class AudioPlay extends React.Component {
constructor(props) {
super(props);
this.state = {
playing: false,
playState: 'paused', //playing, paused
playSeconds: 0,
duration: 0,
};
this.sliderEditing = false;
}

componentDidMount() {
// this.play();

this.timeout = setInterval(() => {
  if (
    this.sound &&
    this.sound.isLoaded() &&
    this.state.playState == 'playing' &&
    !this.sliderEditing
  ) {
    this.sound.getCurrentTime((seconds, isPlaying) => {
      this.setState({playSeconds: seconds});
    });
  }
}, 100);

}
componentWillUnmount() {
if (this.sound) {
this.sound.release();
this.sound = null;
}
if (this.timeout) {
clearInterval(this.timeout);
}
}

onSliderEditStart = () => {
this.sliderEditing = true;
};
onSliderEditEnd = () => {
this.sliderEditing = false;
};
onSliderEditing = value => {
if (this.sound) {
this.sound.setCurrentTime(value);
this.setState({playSeconds: value});
}
};

play = async () => {
if (this.sound) {
this.sound.play(this.playComplete);
this.setState({playState: 'playing'});
} else {
const filepath = APIURL + this.props.audio;

  this.sound = new Sound(filepath, '', error => {
    if (error) {
      // console.log('failed to load the sound', error);
      Alert.alert('Notice', 'audio file error. (Error code : 1)');
      this.setState({playState: 'paused'});
    } else {
      this.setState({
        playState: 'playing',
        duration: this.sound.getDuration(),
      });
      this.sound.play(this.playComplete);
    }
  });
}

};
playComplete = success => {
if (this.sound) {
if (success) {
// console.log('successfully finished playing');
} else {
// console.log('playback failed due to audio decoding errors');
Alert.alert('Notice', 'audio file error. (Error code : 2)');
}
this.setState({playState: 'paused', playSeconds: 0});
this.sound.setCurrentTime(0);
}
};

pause = () => {
if (this.sound) {
this.sound.pause();
}

this.setState({playState: 'paused'});

};

jumpPrev15Seconds = () => {
this.jumpSeconds(-15);
};
jumpNext15Seconds = () => {
this.jumpSeconds(15);
};
jumpSeconds = secsDelta => {
if (this.sound) {
this.sound.getCurrentTime((secs, isPlaying) => {
let nextSecs = secs + secsDelta;
if (nextSecs < 0) nextSecs = 0;
else if (nextSecs > this.state.duration) nextSecs = this.state.duration;
this.sound.setCurrentTime(nextSecs);
this.setState({playSeconds: nextSecs});
});
}
};

getAudioTimeString(seconds) {
const h = parseInt(seconds / (60 * 60));
const m = parseInt((seconds % (60 * 60)) / 60);
const s = parseInt(seconds % 60);

return (
  (h < 10 ? '0' + h : h) +
  ':' +
  (m < 10 ? '0' + m : m) +
  ':' +
  (s < 10 ? '0' + s : s)
);

}

render() {
if (this.state.playState == 'playing') {
return (
<View
style={{width: '80%', flexDirection: 'row', alignItems: 'center'}}>
<Ionicons
name={'pause'}
size={35}
color={PrimaryColor}
onPress={this.pause}
/>

      <Slider
        onTouchStart={this.onSliderEditStart}
        onTouchEnd={this.onSliderEditEnd}
        onValueChange={this.onSliderEditing}
        value={this.state.playSeconds}
        maximumValue={this.state.duration}
        maximumTrackTintColor="gray"
        minimumTrackTintColor={PrimaryColor}
        thumbTintColor={PrimaryColor}
        style={{
          height: 50,
          width: 200,
          alignSelf: 'center',
          marginHorizontal: Platform.select({ios: 5}),
        }}
      />
    </View>
  );
} else {
  return (
    <View
      style={{width: '80%', flexDirection: 'row', alignItems: 'center'}}>
      <Ionicons
        name={'play'}
        size={35}
        color={PrimaryColor}
        onPress={this.play}
      />

      <Slider
        onTouchStart={this.onSliderEditStart}
        onTouchEnd={this.onSliderEditEnd}
        onValueChange={this.onSliderEditing}
        value={this.state.playSeconds}
        maximumValue={this.state.duration}
        maximumTrackTintColor="gray"
        minimumTrackTintColor={PrimaryColor}
        thumbTintColor={PrimaryColor}
        style={{
          height: 50,
          width: 200,
          alignSelf: 'center',
          marginHorizontal: Platform.select({ios: 5}),
        }}
      />
    </View>
  );
}

}
}

export default memo(AudioPlay);
@jimshidbachu jimshidbachu added the bug report Something isn't working label Nov 7, 2024
@callstack callstack deleted a comment from jimshidbachu Nov 12, 2024
@BartoszKlonowski
Copy link
Member

Hello @jimshidbachu, thanks for the detailed report! 🙏
At first glance this looks like an issue with the controlledValue feature on the new arch, but before I dive deeper, I have two questions:

  1. What platforms do you see are affected?
  2. When running this on previous version (v4.5.4), did you use the new architecture as well?

Thanks in advance!

@BartoszKlonowski BartoszKlonowski added the new architecture Issue relates to react-native new architecture label Nov 12, 2024
@github-project-automation github-project-automation bot moved this to To be analyzed in Slider-Board Nov 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug report Something isn't working new architecture Issue relates to react-native new architecture
Projects
Status: To be analyzed
Development

No branches or pull requests

2 participants