notifyPending method

void notifyPending(
  1. int deviceId,
  2. ExerciseMode exerciseMode,
  3. ProviderContainer container, {
  4. VoidCallback? onTimeout,
})

Notify that an exercise has been started on the device with the given ID, and an update to the device's status is pending.

Implementation

void notifyPending(
  int deviceId,
  ExerciseMode exerciseMode,
  ProviderContainer container, {
  VoidCallback? onTimeout,
}) {
  final currentSub = state[deviceId];
  currentSub?.cancel(shouldRemove: false);

  bool shouldCancel = false;
  PendingExerciseSubscription? nextSub;

  nextSub = PendingExerciseSubscription(
    deviceId: deviceId,
    exerciseMode: exerciseMode,
    notifier: this,
    timer: Timer(kPendingTimeout, () {
      if (nextSub != null) {
        nextSub.cancel();
        onTimeout?.call();
      } else {
        shouldCancel = true;
      }
    }),
    subscription: container.listen<AsyncValue<Device>>(
      cachedDeviceFamily(deviceId),
      fireImmediately: true,
      (previous, next) {
        // Close the pending notifier if the status is no longer ready-to-run
        // after starting an exercise.
        //
        // Additionally, generators may transition to 'running' before
        // 'running exercise' because there are intermediary states that are
        // shared between both statuses.
        final status = next.valueOrNull?.status;
        if (status != DeviceStatus.readyToRun &&
            status != DeviceStatus.running) {
          if (nextSub != null) {
            nextSub.cancel();
          } else {
            shouldCancel = true;
          }
        }
      },
    ),
  );

  if (!shouldCancel) {
    state = Map.unmodifiable({
      ...state,
      deviceId: nextSub,
    });
  } else {
    nextSub.cancel();
  }
}