flutter_chat_ui icon indicating copy to clipboard operation
flutter_chat_ui copied to clipboard

How do I stream messages like chatgpt?

Open ReAlign opened this issue 1 year ago • 3 comments

As the title.

ReAlign avatar Apr 25 '24 13:04 ReAlign

no possible with v1. Will try to do in v2. (but please do not wait for me cause it might take lots of time - find an alternative if possible)

demchenkoalex avatar Apr 25 '24 21:04 demchenkoalex

When do you plan to release v2 ?

lumpidu avatar May 01 '24 18:05 lumpidu

As a workaround, if you get a stream, you can use something like this when you receive the stream.

  void _updateFirstMessageText(String newText, {bool replace = false}) {
    assert(
      _messages.first is types.TextMessage,
      'First message must be a text message',
    );

    final firstMessage = _messages.first as types.TextMessage;
    final updatedText = replace ? newText : firstMessage.text + newText;
    final updatedMessage = firstMessage.copyWith(
      text: updatedText,
    ) as types.TextMessage;

    setState(() {
      _messages.removeAt(0);
      _addMessage(updatedMessage);
    });
  }

You can also emulate streamed text with something like this

bool _isStreaming = false;
final List<String> _messageQueue = [];

  void _onTextReceived(String newText) {
    _messageQueue.add(newText);
    if (!_isStreaming) {
    setState(() {
      final updatedMessage = _messages.first.copyWith(
        text: _messages.first.text + newText,
      ) as types.TextMessage;
      _messages.removeAt(0);
      _addMessage(updatedMessage);
    });
    }
  }

Future<void> _startStreamingMessages() async {
    _isStreaming = true;
    while (_messageQueue.isNotEmpty) {
      final nextMessage = _messageQueue.removeAt(0);
      await _streamText(nextMessage);
    }
    _isStreaming = false;
  }

  Future<void> _streamText(String message) async {
    var currentIndex = 0;
    final completer = Completer<void>();

    Timer.periodic(const Duration(milliseconds: 15), (timer) { // adjust this for the "speed" of the stream
      if (currentIndex < message.length) {
        setState(() {
          final updatedMessage = _messages.first.copyWith(
            text: _messages.first.text + message[currentIndex],
          ) as types.TextMessage;
          _messages.removeAt(0);
          _addMessage(updatedMessage);
          currentIndex++;
        });
      } else {
        timer.cancel();
        completer.complete();
      }
    });

bawahakim avatar May 10 '24 07:05 bawahakim