run method

  1. @override
Future<void> run()
override

the SimpleFrameApp subclass implements application-specific code

Implementation

@override
Future<void> run() async {
  currentState = ApplicationState.running;
  if (mounted) setState(() {});

  try {
    // create the bubble for this message, and we'll update it as speech-to-text updates come in
    final textMessage = types.TextMessage(
      author: _user,
      createdAt: DateTime.now().millisecondsSinceEpoch,
      id: const Uuid().v4(),
      text: '',
    );
    _addMessage(textMessage);

    // listen for STT
    await _speechToText.listen(
        listenOptions: SpeechListenOptions(
          cancelOnError: true,
          onDevice: false,
          listenMode: ListenMode.dictation,
          autoPunctuation: true,
          partialResults: true,
        ),
        localeId: _currentLocaleId,
        onResult: (SpeechRecognitionResult result) async {
          if (currentState == ApplicationState.ready) {
            // user has cancelled already, don't process result
            // (need to comment this out if testing while Frame is unavailable)
            return;
          }

          if (result.finalResult) {
            // on a final result we query the LLM
            _finalResult = result.recognizedWords;
            _partialResult = '';
            _log.fine('Final result: $_finalResult');
            _stopListening();

            // put the final text in the bubble
            _updateLatestMessage(_finalResult);

            // send off the query to the LLM
            _handleTextQuery(_finalResult);

            // send final request text to Frame
            if (_finalResult != _prevText) {
              //await frame!.sendMessage(TxPlainText(msgCode: 0x0a, text: _finalResult));
              // TODO can send a TextSpriteBlock in future with the final request before the LLM response
              _prevText = _finalResult;
            }

            currentState = ApplicationState.ready;
            if (mounted) setState(() {});
          } else {
            // partial result - just display in-progress text
            _partialResult = result.recognizedWords;
            _updateLatestMessage(_partialResult);

            _log.fine(
                'Partial result: $_partialResult, ${result.alternates}');
            if (_partialResult != _prevText) {
              // TODO can send a TextSpriteBlock in future to echo the request on Frame before the response comes
              //await frame!.sendMessage(TxPlainText(msgCode: 0x0a, text: _partialResult));
              _prevText = _partialResult;
            }
          }
        });
  } catch (e) {
    _log.fine('Error executing application logic: $e');
    currentState = ApplicationState.ready;
    if (mounted) setState(() {});
  }
}