import 'package:flutter/material.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; class ThreadPage extends StatefulWidget { final Message? parent; final int? initialScrollIndex; final double? initialAlignment; ThreadPage({ Key? key, this.parent, this.initialScrollIndex, this.initialAlignment, }) : super(key: key); @override _ThreadPageState createState() => _ThreadPageState(); } class _ThreadPageState extends State { Message? _quotedMessage; FocusNode _focusNode = FocusNode(); @override void dispose() { _focusNode.dispose(); super.dispose(); } void _reply(Message message) { setState(() => _quotedMessage = message); WidgetsBinding.instance!.addPostFrameCallback((timeStamp) { _focusNode.requestFocus(); }); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: StreamChatTheme.of(context).colorTheme.appBg, appBar: ThreadHeader( parent: widget.parent!, ), body: Column( children: [ Expanded( child: MessageListView( parentMessage: widget.parent, initialScrollIndex: widget.initialScrollIndex, initialAlignment: widget.initialAlignment, onMessageSwiped: _reply, messageFilter: defaultFilter, messageBuilder: (context, details, messages, defaultMessage) { return defaultMessage.copyWith( onReplyTap: _reply, deletedBottomRowBuilder: (context, message) { return const VisibleFootnote(); }, ); }, pinPermissions: ['owner', 'admin', 'member'], ), ), if (widget.parent!.type != 'deleted') MessageInput( parentMessage: widget.parent, focusNode: _focusNode, quotedMessage: _quotedMessage, onQuotedMessageCleared: () { setState(() => _quotedMessage = null); _focusNode.unfocus(); }, ), ], ), ); } bool defaultFilter(Message m) { var _currentUser = StreamChat.of(context).currentUser; final isMyMessage = m.user?.id == _currentUser?.id; final isDeletedOrShadowed = m.isDeleted == true || m.shadowed == true; if (isDeletedOrShadowed && !isMyMessage) return false; return true; } }