2

Creating a timer app which increases a timer when the user presses and holds screen. If user releases screen the timer stops. I want a 2 sec delay when the user releases the screen. If the user presses and holds the screen within that 2 seconds, I want the timer to continue where it left off. If not then reset the timer to start again.

Almost everything works, the user can hold down the screen and the timer starts, when they release the timer stops. But if the user holds down the screen again, nothing happens, it waits 2 seconds then starts the timer automatically, without the user's press!

Here's the code I'm using:

state:

time:0,
start:0,
isOn:false, 

Function for mouse down and up:

  onItemMouseDown() {
   if(this.state.time === 0 ){

    this.setState({
      time: 0,
      pauseToggle: 'down'

    }, () => { //Remember this call back is an old school alternative to a promise (then)
      this.setState({
        // time: this.state.time,
        start: Date.now() - this.state.time,
        isOn:true,

      }, () => {console.log(this.state.pauseOver+'1'); console.log(this.state.pauseToggle+'1')})

      this.timer = setInterval(() => this.setState({

    time:Date.now() - this.state.start}), 1);

    })
  } else if(this.state.time > 0 && this.state.pauseOver === false){


      this.setState({
        time: this.state.time,
        pauseToggle: 'down',
      }, () => {
        this.setState({
          // time: this.state.time,
          start: Date.now() - this.state.time,
          isOn:true,


        }, () => {console.log(this.state.pauseOver+'2'); console.log(this.state.pauseToggle+'2')})

        this.timer = setInterval(() => this.setState({

          time:Date.now() - this.state.start}), 1);

     })

    } else if((this.state.time > 0) && (this.state.pauseOver === true)){
      this.setState({
        time: 0,
        pauseToggle: 'down',
      }, () => { //Remember this call back is an old school alternative to a promise (then)
        this.setState({
          // time: this.state.time,
          start: Date.now() - this.state.time,
          isOn:true,

        }, () => {console.log(this.state.pauseOver+'3'); console.log(this.state.pauseToggle+'3')})

        this.timer = setInterval(() => this.setState({

      time:Date.now() - this.state.start,
      pauseOver: false,  
    }), 1);

      })
    }

  }

and the render:

 render() {

    if((this.state.isOn) === true){

        return(

          <ImageBackground source={require('./assets/welcome.png')} style={styles.background}>
           <Animated.View
            style={

              {
              opacity: this.state.fadeAnim
              }
            }
           >
           <Image source={require('./assets/Background.png')} style={styles.FadeInImage}></Image>
          <Text>Timer:{ms(this.state.time,{verbose: true})}</Text>

          </Animated.View>
      <TouchableOpacity
         onPressIn={() => {this.fadeIn(); this.onItemMouseDown()}}
         onPressOut={ this.onItemMouseUp}
         >       
      </TouchableOpacity>

         </ImageBackground>
        )

          } else if ((this.state.isOn) === false){  

        return(
          <ImageBackground source={require('./assets/welcome.png')} style={styles.background}>

         <Text>Timer:{ms(this.state.time)}</Text>  

         <TouchableOpacity
         onPressIn={() => {this.fadeIn(); this.onItemMouseDown()}} 
         onPressOut={ this.onItemMouseUp}
         >
         <View>
         <Image source={require('./assets/icon.png')}/>
         </View>      
         </TouchableOpacity>

      </ImageBackground>
   )
  } 
}


I think the setTimeout is in the wrong place, but I'm getting confused over my original code for the timer. So where do I set the timeout to create a 2 seconds delay then continue the timer when the user holds it down for a second time?

I think it the answer may lie in the mouseup function. I need to find a way to stop the setTimeout from triggering, making the this.state.pauseOver change to true. I think even though the user is pressing the screen back down again within the 2 seconds, the setTimeout is still going ahead. Somehow I need to stop that. Would it be an aysnchronous event listener that waits for the onMousedown function which stops the setTimeout??? Just plucking words out from the air there...!

UPDATE: I think I've achieved this but will require testing for memory leaks etc. Have updated the mousedown and up functions with what I believe works.

Could someone have alook to see if I'm headed into dangerous waters there?! T

NightTom
  • 418
  • 15
  • 37
  • 1
    This is so complicated just using brain to debug lol! I think you could simply use [debounce](https://stackoverflow.com/a/41215941/13107433) to set timeout in mouse up listener could achieve your effect? And add a remove timeout in mouse down listener. It could be a little bit different, but can work if it touch many times quickly, and then always called after button up? FYR – 高鵬翔 May 20 '20 at 03:30
  • I think I've got it working with the UPDATE I've included above, but yes your suggestion will probably be better as the performance isn't very good. Down to my code I believe. – NightTom May 20 '20 at 12:20
  • Any chance you could provide example code using debounce? – NightTom Jun 01 '20 at 13:34

0 Answers0