From 766591546fe1be78cdda5eacdbf4d4f2daf6caed Mon Sep 17 00:00:00 2001 From: Joshua Date: Sat, 6 Jul 2024 15:25:43 -0600 Subject: [PATCH] Re-implemented bottom navigation bar w/ successful page changes. --- mobile/app/lib/main.dart | 82 +++- .../lib/pages/conversations_list_widget.dart | 363 +++++++++--------- mobile/app/lib/theme.dart | 6 +- mobile/app/pubspec.lock | 8 +- mobile/app/pubspec.yaml | 2 +- 5 files changed, 263 insertions(+), 198 deletions(-) diff --git a/mobile/app/lib/main.dart b/mobile/app/lib/main.dart index 501f923..76fe504 100644 --- a/mobile/app/lib/main.dart +++ b/mobile/app/lib/main.dart @@ -1,21 +1,91 @@ import 'package:app/pages/settings_widget.dart'; +import 'package:app/pages/conversations_list_widget.dart'; import 'package:flutter/material.dart'; -import 'theme.dart'; +import 'package:provider/provider.dart'; +import 'package:app/theme.dart'; + +// my_state.dart (Provider for selected index) +final _selectedIndex = ValueNotifier(0); + +class MyState with ChangeNotifier { + int get selectedIndex => _selectedIndex.value; + + set selectedIndex(int value) { + _selectedIndex.value = value; + notifyListeners(); + } +} + +// This function creates a BottomNavigationBarItem for each page +BottomNavigationBarItem _buildNavigationItem(int index) { + String label = ""; + IconData iconData = Icons.error; + switch (index) { + case 0: + label = 'Home'; + iconData = Icons.home; + break; + case 1: + label = 'Settings'; + iconData = Icons.settings; + break; + } + return BottomNavigationBarItem( + icon: Icon(iconData), + label: label, + ); +} + +// main.dart void main() { - runApp(const MyApp()); + runApp( + ChangeNotifierProvider( + create: (_) => MyState(), + child: MyApp(), + ), + ); } class MyApp extends StatelessWidget { - const MyApp({super.key}); + MyApp({super.key}); + + // This list holds the pages to navigate between + final List _pages = [ + // Replace with the widget for your first page (e.g., HomeScreen()) + const Center(child: ConversationsListWidget()), + // Replace with the widget for your second page (e.g., SettingsPage()) + const Center(child: SettingsWidget()), + ]; // This widget is the root of your application. @override Widget build(BuildContext context) { + int selectedIndex = Provider.of(context).selectedIndex; - return const MaterialApp( - title: 'Flutter Demo', - home: SettingsWidget(), + return MaterialApp( + title: 'App', + home: Scaffold( + backgroundColor: AppTheme.secondaryBackground, + appBar: AppBar( + backgroundColor: AppTheme.secondaryBackground, + automaticallyImplyLeading: false, + title: const Text( + 'App', + style: AppTheme.headlineLarge, + ), + actions: const [], + centerTitle: false, + elevation: 0, + ), + body: _pages[Provider.of(context, listen: false).selectedIndex], + bottomNavigationBar: BottomNavigationBar( + // Set the number of items to the length of the pages list + items: List.generate(_pages.length, (index) => _buildNavigationItem(index)), + currentIndex: selectedIndex, + onTap: (index) => Provider.of(context, listen: false).selectedIndex = index, // Update using Provider + ), + ), ); } } diff --git a/mobile/app/lib/pages/conversations_list_widget.dart b/mobile/app/lib/pages/conversations_list_widget.dart index c2fe95b..a08c023 100644 --- a/mobile/app/lib/pages/conversations_list_widget.dart +++ b/mobile/app/lib/pages/conversations_list_widget.dart @@ -1,5 +1,3 @@ -import 'dart:nativewrappers/_internal/vm/lib/internal_patch.dart'; - import '/components/conversation_options/conversation_options_widget.dart'; import 'package:flutterflow_ui/flutterflow_ui.dart'; import 'package:flutter/material.dart'; @@ -43,198 +41,195 @@ class _ConversationsListWidgetState extends State { onTap: () => _model.unfocusNode.canRequestFocus ? FocusScope.of(context).requestFocus(_model.unfocusNode) : FocusScope.of(context).unfocus(), - child: Scaffold( - key: scaffoldKey, - backgroundColor: AppTheme.secondaryBackground, - floatingActionButton: InkWell( - splashColor: Colors.transparent, - focusColor: Colors.transparent, - hoverColor: Colors.transparent, - highlightColor: Colors.transparent, - onLongPress: () async { - await showModalBottomSheet( - isScrollControlled: true, - backgroundColor: Colors.transparent, - enableDrag: false, - context: context, - builder: (context) { - return GestureDetector( - onTap: () => _model.unfocusNode.canRequestFocus - ? FocusScope.of(context).requestFocus(_model.unfocusNode) - : FocusScope.of(context).unfocus(), - child: Padding( - padding: MediaQuery.viewInsetsOf(context), - child: const ConversationOptionsWidget(), + child: SafeArea( + top: true, + child: Column( + mainAxisSize: MainAxisSize.max, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Padding( + padding: EdgeInsetsDirectional.fromSTEB(16, 0, 0, 0), + child: Text( + 'AI conversations', + style: AppTheme.labelMedium, ), - ); - }, - ).then((value) => safeSetState(() {})); - - // TODO - //context.pushNamed('Conversation'); - }, - child: FloatingActionButton( - // TODO - // onPressed: () async { - // context.pushNamed('Conversation'); - // }, - onPressed: () { - print("fab pressed"); - }, - backgroundColor: AppTheme.primary, - elevation: 8, - child: const Icon( - Icons.add, - color: AppTheme.info, - size: 24, - ), - ), - ), - appBar: AppBar( - backgroundColor: AppTheme.secondaryBackground, - automaticallyImplyLeading: false, - title: const Text( - 'My Chats', - style: AppTheme.headlineLarge, - ), - actions: const [], - centerTitle: false, - elevation: 0, - ), - body: SafeArea( - top: true, - child: Column( - mainAxisSize: MainAxisSize.max, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const Padding( - padding: EdgeInsetsDirectional.fromSTEB(16, 0, 0, 0), - child: Text( - 'AI conversations', - style: AppTheme.labelMedium, ), - ), - Expanded( - child: Align( - alignment: const AlignmentDirectional(0, 0), - child: ListView( - padding: EdgeInsets.zero, - reverse: true, - scrollDirection: Axis.vertical, - children: [ - Align( - alignment: const AlignmentDirectional(0, 0), - child: InkWell( - splashColor: Colors.transparent, - focusColor: Colors.transparent, - hoverColor: Colors.transparent, - highlightColor: Colors.transparent, - // TODO - // onTap: () async { - // context.pushNamed('Conversation'); - // }, - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Container( - width: 100, - height: 100, - decoration: const BoxDecoration( - color: AppTheme - .secondaryBackground, + Expanded( + child: Align( + alignment: const AlignmentDirectional(0, 0), + child: ListView( + padding: EdgeInsets.zero, + reverse: true, + scrollDirection: Axis.vertical, + children: [ + Align( + alignment: const AlignmentDirectional(0, 0), + child: InkWell( + splashColor: Colors.transparent, + focusColor: Colors.transparent, + hoverColor: Colors.transparent, + highlightColor: Colors.transparent, + // TODO + // onTap: () async { + // context.pushNamed('Conversation'); + // }, + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + width: 100, + height: 100, + decoration: const BoxDecoration( + color: AppTheme.secondaryBackground, + ), + child: const Align( + alignment: AlignmentDirectional(0, 0), + child: Icon( + Icons.settings_outlined, + color: AppTheme.secondaryText, + size: 48, + ), + ), ), - child: const Align( - alignment: AlignmentDirectional(0, 0), - child: Icon( - Icons.settings_outlined, - color: AppTheme - .secondaryText, + Expanded( + child: Align( + alignment: const AlignmentDirectional(-1, 0), + child: Container( + width: 100, + height: 100, + constraints: BoxConstraints( + minWidth: + MediaQuery.sizeOf(context).width, + ), + decoration: const BoxDecoration( + color: AppTheme.secondaryBackground, + shape: BoxShape.rectangle, + ), + child: const Column( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: + MainAxisAlignment.spaceEvenly, + crossAxisAlignment: + CrossAxisAlignment.center, + children: [ + Align( + alignment: + AlignmentDirectional(-1, 0), + child: Row( + mainAxisSize: MainAxisSize.max, + children: [ + Text( + 'Hello World', + style: AppTheme.headlineLarge, + ), + ], + ), + ), + Align( + alignment: + AlignmentDirectional(-1, 0), + child: Row( + mainAxisSize: MainAxisSize.max, + children: [ + Expanded( + child: Text( + 'Hello World', + style: AppTheme.bodyMedium, + ), + ), + ], + ), + ), + ], + ), + ), + ), + ), + Container( + width: 100, + height: 100, + decoration: const BoxDecoration( + color: AppTheme.secondaryBackground, + ), + child: const Icon( + Icons.chevron_right_rounded, + color: AppTheme.secondaryText, size: 48, ), ), - ), - Expanded( - child: Align( - alignment: const AlignmentDirectional(-1, 0), - child: Container( - width: 100, - height: 100, - constraints: BoxConstraints( - minWidth: - MediaQuery.sizeOf(context).width, - ), - decoration: const BoxDecoration( - color: AppTheme - .secondaryBackground, - shape: BoxShape.rectangle, - ), - child: const Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: - MainAxisAlignment.spaceEvenly, - crossAxisAlignment: - CrossAxisAlignment.center, - children: [ - Align( - alignment: - AlignmentDirectional(-1, 0), - child: Row( - mainAxisSize: MainAxisSize.max, - children: [ - Text( - 'Hello World', - style: AppTheme.headlineLarge, - ), - ], - ), - ), - Align( - alignment: - AlignmentDirectional(-1, 0), - child: Row( - mainAxisSize: MainAxisSize.max, - children: [ - Expanded( - child: Text( - 'Hello World', - style: AppTheme.bodyMedium, - ), - ), - ], - ), - ), - ], - ), - ), - ), - ), - Container( - width: 100, - height: 100, - decoration: const BoxDecoration( - color: AppTheme - .secondaryBackground, - ), - child: const Icon( - Icons.chevron_right_rounded, - color: AppTheme - .secondaryText, - size: 48, - ), - ), - ], + ], + ), ), ), - ), - ], + ], + ), ), ), - ), - ], - ), - ), + ], + ), + // child: Scaffold( + // key: scaffoldKey, + // backgroundColor: AppTheme.secondaryBackground, + // floatingActionButton: InkWell( + // splashColor: Colors.transparent, + // focusColor: Colors.transparent, + // hoverColor: Colors.transparent, + // highlightColor: Colors.transparent, + // onLongPress: () async { + // await showModalBottomSheet( + // isScrollControlled: true, + // backgroundColor: Colors.transparent, + // enableDrag: false, + // context: context, + // builder: (context) { + // return GestureDetector( + // onTap: () => _model.unfocusNode.canRequestFocus + // ? FocusScope.of(context).requestFocus(_model.unfocusNode) + // : FocusScope.of(context).unfocus(), + // child: Padding( + // padding: MediaQuery.viewInsetsOf(context), + // child: const ConversationOptionsWidget(), + // ), + // ); + // }, + // ).then((value) => safeSetState(() {})); + // + // // TODO + // //context.pushNamed('Conversation'); + // }, + // child: FloatingActionButton( + // // TODO + // // onPressed: () async { + // // context.pushNamed('Conversation'); + // // }, + // onPressed: () { + // print("fab pressed"); + // }, + // backgroundColor: AppTheme.primaryBackground, + // elevation: 8, + // child: const Icon( + // Icons.add, + // color: AppTheme.info, + // size: 24, + // ), + // ), + // ), + // appBar: AppBar( + // backgroundColor: AppTheme.secondaryBackground, + // automaticallyImplyLeading: false, + // title: const Text( + // 'My Chats', + // style: AppTheme.headlineLarge, + // ), + // actions: const [], + // centerTitle: false, + // elevation: 0, + // ), + // body: SafeArea( + // + // ), ), ); } diff --git a/mobile/app/lib/theme.dart b/mobile/app/lib/theme.dart index b947a32..1d38ccd 100644 --- a/mobile/app/lib/theme.dart +++ b/mobile/app/lib/theme.dart @@ -4,13 +4,13 @@ class AppTheme { static const primary = Colors.deepPurple; static const secondary = Colors.deepPurpleAccent; static const tertiary = Colors.white; - static const alternate = Colors.purple; + static const alternate = Colors.deepPurple; static const accent1 = Colors.amber; static const accent4 = Colors.amber; - static const primaryBackground = Colors.purple; - static const secondaryBackground = Colors.purpleAccent; + static const primaryBackground = Colors.deepPurpleAccent; + static const secondaryBackground = Colors.deepPurple; static const primaryTextColor = Colors.white; static const primaryText = TextStyle(color: primaryTextColor, fontSize: 12); diff --git a/mobile/app/pubspec.lock b/mobile/app/pubspec.lock index ac7fad9..c58d091 100644 --- a/mobile/app/pubspec.lock +++ b/mobile/app/pubspec.lock @@ -314,10 +314,10 @@ packages: dependency: "direct dev" description: name: flutter_lints - sha256: "9e8c3858111da373efc5aa341de011d9bd23e2c5c5e0c62bccf32438e192d7b1" + sha256: "3f41d009ba7172d5ff9be5f6e6e6abb4300e263aab8866d2a0842ed2a70f8f0c" url: "https://pub.dev" source: hosted - version: "3.0.2" + version: "4.0.0" flutter_plugin_android_lifecycle: dependency: transitive description: @@ -548,10 +548,10 @@ packages: dependency: transitive description: name: lints - sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290 + sha256: "976c774dd944a42e83e2467f4cc670daef7eed6295b10b36ae8c85bcbf828235" url: "https://pub.dev" source: hosted - version: "3.0.0" + version: "4.0.0" mapbox_search: dependency: transitive description: diff --git a/mobile/app/pubspec.yaml b/mobile/app/pubspec.yaml index 3fa09a3..a5820ab 100644 --- a/mobile/app/pubspec.yaml +++ b/mobile/app/pubspec.yaml @@ -53,7 +53,7 @@ dev_dependencies: # activated in the `analysis_options.yaml` file located at the root of your # package. See that file for information about deactivating specific lint # rules and activating additional ones. - flutter_lints: ^3.0.0 + flutter_lints: ^4.0.0 # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec