HEX
Server: Apache/2.4.52 (Ubuntu)
System: Linux spn-python 5.15.0-89-generic #99-Ubuntu SMP Mon Oct 30 20:42:41 UTC 2023 x86_64
User: arjun (1000)
PHP: 8.1.2-1ubuntu2.20
Disabled: NONE
Upload Files
File: //home/arjun/projects/buyercall/node_modules/bootstrap-vue-next/src/composables/useCountdown.ts
import {useIntervalFn, type UseIntervalFnOptions} from '@vueuse/core'
import {type MaybeRefOrGetter, readonly, ref, type Ref, toRef, watch, watchEffect} from 'vue'

type VoidFn = () => void

interface CountdownReturn {
  isActive: Readonly<Ref<boolean>>
  isPaused: Readonly<Ref<boolean>>
  restart: VoidFn
  stop: VoidFn
  resume: VoidFn
  pause: VoidFn
  value: Readonly<Ref<number>>
}

/**
 * A simple interval timer that counts down the remaining seconds
 *
 * @param {MaybeRefOrGetter<number>} length the total amount of time to loop through in ms
 * @param {MaybeRefOrGetter<number>} interval how often the interval should refresh. Default 1000
 * @param {UseIntervalFnOptions} intervalOpts opts to pass to the interval fn. Default {}
 * @important ensure that you call `stop()` before unmount in the component
 */
export default (
  length: MaybeRefOrGetter<number>,
  interval: MaybeRefOrGetter<number> = ref(1000),
  intervalOpts: UseIntervalFnOptions = {}
): CountdownReturn => {
  const resolvedLength = readonly(toRef(length))

  const resolvedInterval = readonly(toRef(interval))

  const isPaused = ref(false)

  const intervalsPassed = ref(0)

  const amountOfIntervals = toRef(() => Math.ceil(resolvedLength.value / resolvedInterval.value))

  const value = toRef(() =>
    isActive.value || isPaused.value
      ? Math.round(resolvedLength.value - intervalsPassed.value * resolvedInterval.value)
      : 0
  )

  const {pause, resume, isActive} = useIntervalFn(
    () => {
      intervalsPassed.value = intervalsPassed.value + 1
    },
    interval,
    intervalOpts
  )

  const restart = () => {
    isPaused.value = false
    intervalsPassed.value = 0
    resume()
  }

  const stop = () => {
    isPaused.value = false
    intervalsPassed.value = amountOfIntervals.value
    // pause() // Only here for the sake of demonstrating the flow. It will be called in the watchEffect
  }
  watchEffect(() => {
    if (intervalsPassed.value > amountOfIntervals.value) {
      intervalsPassed.value = amountOfIntervals.value
    }
    if (intervalsPassed.value === amountOfIntervals.value) {
      pause()
    }
  })

  watch([resolvedInterval, resolvedLength], () => {
    stop()
    restart()
  })

  const myPause = () => {
    if (isActive.value === false) return
    isPaused.value = true
    pause()
  }

  const myResume = () => {
    if (intervalsPassed.value === amountOfIntervals.value) return
    isPaused.value = false
    resume()
  }

  return {
    isActive: readonly(isActive),
    isPaused: readonly(isPaused),
    restart,
    stop,
    pause: myPause,
    resume: myResume,
    value,
  }
}