Documentation

Listening for Events

The UserView Flutter SDK exposes all events as Dart Streams. Subscribe to them for reactive event handling.

Listening for Events

import 'dart:async';
import 'package:upscopeio_flutter_sdk/upscopeio_flutter_sdk.dart';

class MyWidget extends StatefulWidget {
  const MyWidget({super.key});

  @override
  State<MyWidget> createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  final List<StreamSubscription> _subscriptions = [];

  @override
  void initState() {
    super.initState();

    _subscriptions.add(
      Upscope.instance.connectionState.listen((state) {
        switch (state) {
          case ConnectionState.inactive:
            print('Inactive');
          case ConnectionState.connecting:
            print('Connecting...');
          case ConnectionState.connected:
            print('Connected');
          case ConnectionState.reconnecting:
            print('Reconnecting...');
          case ConnectionState.error:
            print('Error');
        }
      }),
    );

    _subscriptions.add(
      Upscope.instance.onSessionStarted.listen((_) {
        print('Session started');
      }),
    );

    _subscriptions.add(
      Upscope.instance.onSessionEnded.listen((reason) {
        switch (reason) {
          case SessionEndReason.userStopped:
            print('User ended session');
          case SessionEndReason.agentStopped:
            print('Agent ended session');
          case SessionEndReason.timeout:
            print('Session timed out');
          case SessionEndReason.error:
            print('Session error');
        }
      }),
    );

    _subscriptions.add(
      Upscope.instance.onCustomMessageReceived.listen((msg) {
        print('Message from ${msg.observerId}: ${msg.message}');
      }),
    );

    _subscriptions.add(
      Upscope.instance.onError.listen((error) {
        print('Error: ${error.code} - ${error.message}');
      }),
    );

    _subscriptions.add(
      Upscope.instance.onObserverJoined.listen((observer) {
        print('Observer joined: ${observer.name ?? observer.id}');
      }),
    );

    _subscriptions.add(
      Upscope.instance.onObserverLeft.listen((observerId) {
        print('Observer left: $observerId');
      }),
    );

    _subscriptions.add(
      Upscope.instance.onObserverCountChanged.listen((count) {
        print('Observers: $count');
      }),
    );
  }

  @override
  void dispose() {
    for (final sub in _subscriptions) {
      sub.cancel();
    }
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return const SizedBox.shrink();
  }
}

Event Reference

StreamTypeDescription
connectionStateConnectionStateConnection state changed.
onSessionStartedString?A screen sharing session has started. Emits the agent's name, if available.
onSessionEndedSessionEndReasonA session has ended. Reason indicates why (userStopped, agentStopped, timeout, or error).
onCustomMessageReceivedCustomMessageA custom message was received from an observer. Includes message and observerId.
onErrorUpscopeErrorAn SDK error occurred. Includes code and message.
onObserverJoinedObserverAn agent started observing the session. The Observer includes id, name, screen dimensions, and focus state.
onObserverLeftStringAn agent stopped observing the session. Emits the observer ID.
onObserverCountChangedintThe total number of active observers changed.

Using StreamBuilder

For reactive UI updates, use StreamBuilder instead of manual subscriptions:

StreamBuilder<ConnectionState>(
  stream: Upscope.instance.connectionState,
  builder: (context, snapshot) {
    if (!snapshot.hasData) return const SizedBox.shrink();
    return Text('Status: ${snapshot.data!.name}');
  },
)