Last active
February 18, 2022 17:26
-
-
Save HayesGordon/75faaf6f7cab48ff06a803b3b7d7124c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
import 'package:stream_chat_flutter/scrollable_positioned_list/scrollable_positioned_list.dart'; | |
import 'package:stream_chat_flutter/stream_chat_flutter.dart'; | |
Future<void> main() async { | |
final client = StreamChatClient( | |
'YOUR-KEY', | |
logLevel: Level.INFO, | |
); | |
await client.connectUser(YOUR-USER); | |
runApp( | |
MyApp( | |
client: client, | |
), | |
); | |
} | |
class MyApp extends StatelessWidget { | |
const MyApp({ | |
Key? key, | |
required this.client, | |
}) : super(key: key); | |
final StreamChatClient client; | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
builder: (context, child) => StreamChat( | |
client: client, | |
child: child, | |
), | |
home: const ChannelListPage(), | |
); | |
} | |
} | |
class ChannelListPage extends StatelessWidget { | |
const ChannelListPage({ | |
Key? key, | |
}) : super(key: key); | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
body: ChannelsBloc( | |
child: ChannelListView( | |
filter: Filter.in_( | |
'members', | |
[StreamChat.of(context).currentUser!.id], | |
), | |
sort: const [SortOption('last_message_at')], | |
limit: 20, | |
channelWidget: const ChannelPage(), | |
), | |
), | |
); | |
} | |
} | |
class ChannelPage extends StatelessWidget { | |
const ChannelPage({ | |
Key? key, | |
this.jumpToLastUnread = 0, | |
}) : super(key: key); | |
final int jumpToLastUnread; | |
@override | |
Widget build(BuildContext context) { | |
final channel = StreamChannel.of(context).channel; | |
return Scaffold( | |
appBar: const ChannelHeader(), | |
body: Column( | |
children: <Widget>[ | |
Expanded( | |
child: MyMessageList( | |
channel: channel, | |
), | |
), | |
const MessageInput(), | |
], | |
), | |
); | |
} | |
} | |
class MyMessageList extends StatefulWidget { | |
const MyMessageList({ | |
Key? key, | |
required this.channel, | |
}) : super(key: key); | |
final Channel channel; | |
@override | |
State<MyMessageList> createState() => _MyMessageListState(); | |
} | |
class _MyMessageListState extends State<MyMessageList> { | |
final controller = ItemScrollController(); | |
@override | |
Widget build(BuildContext context) => Stack( | |
children: [ | |
MessageListView( | |
showScrollToBottom: false, | |
scrollController: controller, | |
), | |
Align( | |
alignment: Alignment.bottomRight, | |
child: Padding( | |
padding: const EdgeInsets.all(16), | |
child: ScrollToUnreadButton( | |
channel: widget.channel, | |
scrollController: controller, | |
), | |
), | |
) | |
], | |
); | |
} | |
class ScrollToUnreadButton extends StatelessWidget { | |
const ScrollToUnreadButton({ | |
Key? key, | |
required this.channel, | |
required this.scrollController, | |
}) : super(key: key); | |
final Channel channel; | |
final ItemScrollController scrollController; | |
Future<void> _scrollTo( | |
BuildContext context, { | |
required int index, | |
required double alignment, | |
}) async { | |
if (!channel.state!.isUpToDate) { | |
await StreamChannel.of(context).loadChannelAtMessage( | |
null, | |
before: index + 25, | |
); | |
WidgetsBinding.instance?.addPostFrameCallback((_) { | |
scrollController.jumpTo(index: index); | |
}); | |
} else { | |
scrollController.scrollTo( | |
index: index, | |
duration: const Duration(seconds: 1), | |
curve: Curves.easeInOut, | |
); | |
} | |
} | |
@override | |
Widget build(BuildContext context) => BetterStreamBuilder<int>( | |
stream: channel.state?.unreadCountStream, | |
initialData: channel.state?.unreadCount, | |
builder: (context, count) { | |
if (count == 0 || count == 0) { | |
return const SizedBox.shrink(); | |
} | |
return FloatingActionButton( | |
onPressed: () { | |
_scrollTo(context, index: count, alignment: 0); | |
}, | |
child: const Icon(Icons.arrow_downward), | |
); | |
}, | |
); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment