11import 'dart:async' ;
22
3+ import 'package:file_picker/file_picker.dart' ;
34import 'package:flutter/material.dart' ;
45import 'package:flutter/widgets.dart' ;
56import 'package:provider/provider.dart' ;
67import 'package:qiscus_chat_sample/src/state/state.dart' ;
8+ import 'package:qiscus_chat_sample/src/widget/app_bar.dart' ;
79import 'package:qiscus_chat_sample/src/widget/chat_bubble.dart' ;
810
911class ChatPage extends StatefulWidget {
12+ ChatPage ({this .roomId});
13+
14+ final int roomId;
15+
1016 @override
1117 State <StatefulWidget > createState () => _ChatState ();
1218}
1319
1420class _ChatState extends State <ChatPage > {
1521 final scrollController = ScrollController ();
1622
23+ @override
24+ void initState () {
25+ super .initState ();
26+ scheduleMicrotask (() {
27+ _getRoom ();
28+ _getMessages ();
29+ });
30+ }
31+
1732 @override
1833 Widget build (BuildContext ctx) {
19- return FutureBuilder (
20- future: Future .wait ([_getRoom (), _getMessages ()]),
21- builder: (ctx, snapshot) => Scaffold (
22- appBar: buildAppBar (ctx),
34+ return Consumer <RoomState >(
35+ builder: (_, state, __) => Scaffold (
36+ appBar: appBar (
37+ room: state.currentRoom,
38+ onBack: () => Navigator .pushReplacementNamed (context, '/login' ),
39+ ),
2340 body: Column (
2441 children: [
42+ if (isLoading) LinearProgressIndicator (),
2543 _messageList (ctx),
2644 _form (ctx),
2745 ],
@@ -38,33 +56,8 @@ class _ChatState extends State<ChatPage> {
3856 );
3957 }
4058
41- Widget buildAppBar (BuildContext context) {
42- return AppBar (
43- centerTitle: false ,
44- elevation: 0 ,
45- leading: FlatButton (
46- child: Icon (
47- Icons .chevron_left,
48- color: Colors .white,
49- ),
50- onPressed: () {
51- Navigator .of (context).pushReplacementNamed ('/login' );
52- },
53- ),
54- title: Consumer <RoomState >(
55- builder: (_, state, __) {
56- if (state.currentRoom == null ) {
57- return Text ('Loading...' );
58- } else {
59- return Text (state.currentRoom.name);
60- }
61- },
62- ),
63- );
64- }
65-
6659 Widget _form (BuildContext ctx) {
67- var roomId = ModalRoute . of (ctx).settings.arguments ;
60+ var roomId = widget.roomId ;
6861 final controller = TextEditingController ();
6962 final key = GlobalKey <FormState >();
7063 var messageState = Provider .of <MessageState >(context, listen: false );
@@ -81,6 +74,17 @@ class _ChatState extends State<ChatPage> {
8174 key: key,
8275 child: Row (
8376 children: < Widget > [
77+ IconButton (
78+ icon: Icon (Icons .attach_file),
79+ onPressed: () async {
80+ print ('get file' );
81+ var file = await FilePicker .getFile ();
82+ if (file != null ) {
83+ await messageState.sendFile (file);
84+ _animateScrollToBottom ();
85+ }
86+ },
87+ ),
8488 Expanded (
8589 child: Padding (
8690 padding: const EdgeInsets .all (8.0 ),
@@ -110,27 +114,31 @@ class _ChatState extends State<ChatPage> {
110114 );
111115 }
112116
117+ bool isLoading = false ;
118+
113119 Widget _messageList (BuildContext ctx) {
114120 return Expanded (
115- child: Consumer <MessageState >(
116- builder: (_, state, __) {
117- var reversed = state.messages.reversed;
118- return ListView .builder (
119- itemCount: state.messages.length,
120- itemBuilder: (ctx, id) {
121- var message = reversed.elementAt (id);
122- return ChatBubble (message: message);
123- },
124- controller: scrollController,
125- padding: EdgeInsets .symmetric (horizontal: 10 ),
126- );
127- },
128- ),
121+ child: Consumer <MessageState >(builder: (_, state, __) {
122+ var reversed = state.messages.reversed;
123+ return ListView .separated (
124+ separatorBuilder: (_, __) {
125+ return Divider (color: Colors .grey, height: 1.0 );
126+ },
127+ itemCount: state.messages.length,
128+ itemBuilder: (ctx, index) =>
129+ ChatBubble (
130+ message: reversed.elementAt (index),
131+ ),
132+ controller: scrollController,
133+ padding: EdgeInsets .symmetric (horizontal: 10 ),
134+ );
135+ }),
129136 );
130137 }
131138
132139 Future _getMessages () async {
133- var roomId = ModalRoute .of (context).settings.arguments;
140+ var roomId = widget.roomId;
141+ if (roomId == null ) return ;
134142 var messageState = Provider .of <MessageState >(context, listen: false );
135143 await messageState.getAllMessage (roomId);
136144 messageState.subscribeChatRoom (messageReceivedCallback: () {
@@ -149,7 +157,15 @@ class _ChatState extends State<ChatPage> {
149157 }
150158
151159 Future _getRoom () async {
152- var roomId = ModalRoute .of (context).settings.arguments;
153- await Provider .of <RoomState >(context, listen: false ).getRoomWithId (roomId);
160+ var roomId = widget.roomId;
161+ if (roomId == null ) return ;
162+ var roomState = Provider .of <RoomState >(context, listen: false );
163+ var room = await roomState.getRoomWithId (roomId);
164+ roomState.subscribe (room);
165+ }
166+
167+ @override
168+ void dispose () {
169+ super .dispose ();
154170 }
155171}
0 commit comments