Flutter smoke dev chat¶
Smoke Test App with chat¶
chat smoke app¶
Screencasts¶
tc159 Demo the Secret Sauce
tc461 Explains main.dart structure
tc591 Widgets are immutable and ephemeral
tc639 class MyApp Explained and hotload shown
tc709 class ChatScreenState explain how to send messages in _buildTextComposer add new Flexible a TextField:
new Flexible( child: new TextField( controller: _textController, onSubmitted: _handleSubmitted, onChanged: _handleMessageChanged, decoration: new InputDecoration.collapsed(hintText: 'Send a message'), ), ),
tc812 go handle submitted function:
void _handleSubmitted(String text) { _textController.clear(); _addMessage(name: _name, text: text); }); }
tc855 update the view to redraw sent messages:
var message = new ChatMessage( sender: sender, text: text, imageUrl: imageUrl, textOverlay: textOverlay, animationController: animationController); setState(() { _messages.insert(0, message); });
tc915 Make pretty via a theme:
class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( title: 'Memechat', theme: defaultTargetPlatform == TargetPlatform.iOS ? kIOSTheme : kDefaultTheme, home: new ChatScreen(), ); } }tc1008 Add some animationController:
void _addMessage( {String name, String text, String imageUrl, String textOverlay, String senderImageUrl}) { var animationController = new AnimationController( duration: new Duration(milliseconds: 700), vsync: this, ); .... also added SizeTransistion in ChatMessageListItem
tc1088 Bug in code.. they go fix it (simple typo but the point was to see debug).
tc1161 Add plugin dependencies via pubspec.yaml
tc1239 Add Google Sign-in plugin in main.dart
void _handleSubmitted(String text) { _textController.clear(); _googleSignIn.signIn().then((user) { var message = { 'sender': {'name': user.displayName, 'imageUrl': user.photoUrl}, 'text': text, }; _messagesReference.push().set(message); }); } ..... display profile photo children: [ new Container( margin: const EdgeInsets.only(right: 16.0), child: new GoogleUserCircleAvatar(message.sender.imageUrl), ),
tc1330 Add Firebase Database:
@override void initState() { super.initState(); _googleSignIn.signInSilently(); FirebaseAuth.instance.signInAnonymously().then((user) { _messagesReference.onChildAdded.listen((Event event) { var val = event.snapshot.value; _addMessage( name: val['sender']['name'], senderImageUrl: val['sender']['imageUrl'], text: val['text'], imageUrl: val['imageUrl'], textOverlay: val['textOverlay']); }); }); } ..... void _handleSubmitted(String text) { _textController.clear(); _googleSignIn.signIn().then((user) { var message = { 'sender': {'name': user.displayName, 'imageUrl': user.photoUrl}, 'text': text, }; _messagesReference.push().set(message); }); }
tc1482 Add send images via Image Picker and Storage.
tc1504 Add icon button:
child: new IconButton( icon: new Icon(Icons.photo), onPressed: _handlePhotoButtonPressed, ), ),
tc1525 Add _handlePhotoButtonPressed function:
Future<Null> _handlePhotoButtonPressed() async { var account = await _googleSignIn.signIn(); var imageFile = await ImagePicker.pickImage(); var random = new Random().nextInt(10000); var ref = FirebaseStorage.instance.ref().child('image_$random.jpg'); var uploadTask = ref.put(imageFile); var textOverlay = await Navigator.push(context, new TypeMemeRoute(imageFile)); if (textOverlay == null) return; var downloadUrl = (await uploadTask.future).downloadUrl; var message = { 'sender': {'name': account.displayName, 'imageUrl': account.photoUrl}, 'imageUrl': downloadUrl.toString(), 'textOverlay': textOverlay, }; _messagesReference.push().set(message); }
tc1656 Add text overlay (which was what the Navigator textOverlay above).
References¶
- Tutorial via GoogleIO-17 “Single Codebase, Two Apps with Flutter and Firebase” see youtube-flutter-chat-tutorial
- Github source for tutorial youtube-flutter-chat-github