diff --git a/lib/screens/timeline_tabs.dart b/lib/screens/timeline_tabs.dart index 3c42ceb..cf117d9 100644 --- a/lib/screens/timeline_tabs.dart +++ b/lib/screens/timeline_tabs.dart @@ -8,6 +8,8 @@ import 'package:feathr/utils/messages.dart'; import 'package:feathr/widgets/drawer.dart'; import 'package:feathr/widgets/timeline.dart'; +import 'package:feathr/widgets/status_form.dart'; + /// The [TimelineTabs] widget represents the tab wrapper for the main /// view of the Feathr app. class TimelineTabs extends StatefulWidget { @@ -87,6 +89,31 @@ class _TimelineTabsState extends State { ); } + /// Displays a dialog box with a form to post a status. + void postStatusAction() { + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: const Text( + "Compose a new status", + textAlign: TextAlign.center, + ), + titleTextStyle: TextStyle( + fontSize: 18.0, + ), + content: StatusForm( + apiService: widget.apiService, + onSuccessfulSubmit: () { + // Hide the dialog box + Navigator.of(context).pop(); + }, + ), + ); + }, + ); + } + @override Widget build(BuildContext context) { final List tabs = [ @@ -127,8 +154,18 @@ class _TimelineTabsState extends State { ), ), drawer: getDrawer(context), - body: TabBarView( - children: tabs, + body: Stack( + children: [ + TabBarView(children: tabs), + Positioned( + bottom: 32.0, + right: 32.0, + child: FloatingActionButton( + onPressed: postStatusAction, + child: const Icon(Icons.create_rounded), + ), + ), + ], ), ), ); diff --git a/lib/widgets/buttons.dart b/lib/widgets/buttons.dart index 3320047..02f839d 100644 --- a/lib/widgets/buttons.dart +++ b/lib/widgets/buttons.dart @@ -11,14 +11,17 @@ class FeathrActionButton extends StatelessWidget { @override Widget build(BuildContext context) { - return ElevatedButton( - onPressed: onPressed, - style: ElevatedButton.styleFrom(backgroundColor: Colors.teal), - child: Text( - buttonText, - style: const TextStyle( - fontFamily: "Urbanist", - fontSize: 18, + return Container( + margin: const EdgeInsets.only(top: 24.0), + child: ElevatedButton( + onPressed: onPressed, + style: ElevatedButton.styleFrom(backgroundColor: Colors.deepPurple), + child: Text( + buttonText, + style: const TextStyle( + fontFamily: "Urbanist", + fontSize: 18, + ), ), ), ); diff --git a/lib/widgets/status_form.dart b/lib/widgets/status_form.dart new file mode 100644 index 0000000..898fb55 --- /dev/null +++ b/lib/widgets/status_form.dart @@ -0,0 +1,67 @@ +import 'package:feathr/services/api.dart'; +import 'package:flutter/material.dart'; + +import 'package:feathr/widgets/buttons.dart'; + +/// [StatusForm] is a form widget that allows the user to compose +/// a new status (text input) and submit it to the server. +class StatusForm extends StatefulWidget { + /// A function that performs an action, to be called when the user submits + /// a valid input. + final Function onSuccessfulSubmit; + + /// Main instance of the API service to use in the widget. + final ApiService apiService; + + const StatusForm({ + required this.apiService, + required this.onSuccessfulSubmit, + super.key, + }); + + @override + StatusFormState createState() { + return StatusFormState(); + } +} + +/// The [StatusFormState] class wraps up logic and state for the +/// [StatusForm] screen. +class StatusFormState extends State { + /// Global key that uniquely identifies this form. + final _formKey = GlobalKey(); + + /// Controller for the `status` text field, to preserve and access the + /// value set on the input field on this class. + final statusController = TextEditingController(); + + @override + Widget build(BuildContext context) { + // Build a Form widget using the _formKey created above. + return Form( + key: _formKey, + autovalidateMode: AutovalidateMode.onUserInteraction, + child: Column(mainAxisSize: MainAxisSize.min, children: [ + TextFormField( + keyboardType: TextInputType.text, + decoration: const InputDecoration( + helperText: "What's on your mind?", + ), + controller: statusController, + validator: (value) => value == null || value.isEmpty + ? 'This field should not be empty' + : null, + ), + FeathrActionButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + // TODO: Implement the API call to submit the status + widget.onSuccessfulSubmit(); + } + }, + buttonText: 'Post', + ), + ]), + ); + } +}