rawEvents method

  1. @override
Stream<Map<String, Object?>> rawEvents(
  1. RawSensorConfig config
)
override

Raw sensor events. The sensor runs only while the stream is listened to.

Implementation

@override
Stream<Map<String, Object?>> rawEvents(RawSensorConfig config) {
  late StreamController<Map<String, Object?>> controller;
  JSFunction? absoluteListener;
  JSFunction? plainListener;

  double? number(JSObject event, String name) {
    final value = event[name];
    if (value.isUndefinedOrNull) return null;
    final n = (value as JSNumber).toDartDouble;
    return n.isFinite ? n : null;
  }

  void onEvent(web.Event raw, {required bool absoluteEvent}) {
    final event = raw as JSObject;
    final rotation = _screenRotation();
    final webkit = number(event, 'webkitCompassHeading');
    if (webkit != null) {
      controller.add({
        'kind': 'heading',
        'heading': webkit,
        'compensated': false,
        'screenRotation': rotation,
        // iOS Safari: webkitCompassAccuracy is degrees, negative = invalid.
        'errorDegrees': number(event, 'webkitCompassAccuracy'),
      });
      return;
    }
    final alpha = number(event, 'alpha');
    final beta = number(event, 'beta');
    final gamma = number(event, 'gamma');
    if (alpha == null || beta == null || gamma == null) return;
    final flag = event['absolute'];
    final absolute = absoluteEvent ||
        (!flag.isUndefinedOrNull && (flag as JSBoolean).toDart);
    controller.add({
      'kind': 'euler',
      'alpha': alpha,
      'beta': beta,
      'gamma': gamma,
      'absolute': absolute,
      'screenRotation': rotation,
    });
  }

  controller = StreamController<Map<String, Object?>>(
    onListen: () {
      absoluteListener =
          ((web.Event e) => onEvent(e, absoluteEvent: true)).toJS;
      plainListener =
          ((web.Event e) => onEvent(e, absoluteEvent: false)).toJS;
      web.window
          .addEventListener('deviceorientationabsolute', absoluteListener);
      web.window.addEventListener('deviceorientation', plainListener);
    },
    onCancel: () {
      if (absoluteListener != null) {
        web.window.removeEventListener(
            'deviceorientationabsolute', absoluteListener);
      }
      if (plainListener != null) {
        web.window.removeEventListener('deviceorientation', plainListener);
      }
    },
  );
  return controller.stream;
}