All Downloads are FREE. Search and download functionalities are using the official Maven repository.

crystal.react.hooks.UseThrottlingStateView.scala Maven / Gradle / Ivy

There is a newer version: 0.45.2
Show newest version
// Copyright (c) 2016-2023 Association of Universities for Research in Astronomy, Inc. (AURA)
// For license information see LICENSE or https://opensource.org/licenses/BSD-3-Clause

package crystal.react.hooks

import crystal.Pot
import crystal.react.ThrottlingView
import crystal.react.ViewThrottler
import japgolly.scalajs.react.*
import japgolly.scalajs.react.hooks.CustomHook

import scala.concurrent.duration.FiniteDuration

object UseThrottlingStateView {
  def hook[A]: CustomHook[(A, FiniteDuration), Pot[ThrottlingView[A]]] =
    CustomHook[(A, FiniteDuration)]
      .useStateViewBy(props => props._1)
      .useEffectResultOnMountBy((props, _) => ViewThrottler[A](props._2))
      .buildReturning: (_, view, throttler) =>
        throttler.map(_.throttle(view))

  object HooksApiExt {
    sealed class Primary[Ctx, Step <: HooksApi.AbstractStep](api: HooksApi.Primary[Ctx, Step]) {

      /** Creates component state as a `ThrottlingView`. See `ViewThrottler[A]`. */
      final def useThrottlingStateView[A](initialValue: => A, timeout: FiniteDuration)(using
        step: Step
      ): step.Next[Pot[ThrottlingView[A]]] =
        useThrottlingStateViewBy(_ => (initialValue, timeout))

      /** Creates component state as a `ThrottlingView`. See `ViewThrottler[A]`. */
      final def useThrottlingStateViewBy[A](props: Ctx => (A, FiniteDuration))(using
        step: Step
      ): step.Next[Pot[ThrottlingView[A]]] =
        api.customBy { ctx =>
          val hookInstance = hook[A]
          hookInstance(props(ctx))
        }
    }

    final class Secondary[Ctx, CtxFn[_], Step <: HooksApi.SubsequentStep[Ctx, CtxFn]](
      api: HooksApi.Secondary[Ctx, CtxFn, Step]
    ) extends Primary[Ctx, Step](api) {

      /** Creates component state as a `ThrottlingView`. See `ViewThrottler[A]`. */
      def useThrottlingStateViewBy[A](props: CtxFn[(A, FiniteDuration)])(using
        step: Step
      ): step.Next[Pot[ThrottlingView[A]]] =
        useThrottlingStateViewBy(step.squash(props)(_))
    }
  }

  protected trait HooksApiExt {
    import HooksApiExt.*

    implicit def hooksExtThrottlingStateView1[Ctx, Step <: HooksApi.AbstractStep](
      api: HooksApi.Primary[Ctx, Step]
    ): Primary[Ctx, Step] =
      new Primary(api)

    implicit def hooksExtThrottlingStateView2[Ctx, CtxFn[_], Step <: HooksApi.SubsequentStep[
      Ctx,
      CtxFn
    ]](
      api: HooksApi.Secondary[Ctx, CtxFn, Step]
    ): Secondary[Ctx, CtxFn, Step] =
      new Secondary(api)
  }

  object syntax extends HooksApiExt
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy