From d2368a9b1bf5e0aa24d5d880a74e5475423b2aa0 Mon Sep 17 00:00:00 2001 From: leonardo2204 Date: Sun, 24 May 2020 23:52:19 -0300 Subject: [PATCH] Add bottom_bar bloc and allow app share --- lib/bloc/home_page.dart | 111 +++++++++++---------- lib/blocs/bloc.dart | 3 + lib/blocs/bottom_bar/bottom_bar_bloc.dart | 20 ++++ lib/blocs/bottom_bar/bottom_bar_event.dart | 14 +++ lib/blocs/bottom_bar/bottom_bar_state.dart | 19 ++++ lib/widgets/main_bottom_bar.dart | 84 ++++++++-------- lib/widgets/sliver_search_bar.dart | 43 ++++---- pubspec.lock | 7 ++ pubspec.yaml | 3 +- 9 files changed, 192 insertions(+), 112 deletions(-) create mode 100644 lib/blocs/bottom_bar/bottom_bar_bloc.dart create mode 100644 lib/blocs/bottom_bar/bottom_bar_event.dart create mode 100644 lib/blocs/bottom_bar/bottom_bar_state.dart diff --git a/lib/bloc/home_page.dart b/lib/bloc/home_page.dart index c4ebca3..990976b 100644 --- a/lib/bloc/home_page.dart +++ b/lib/bloc/home_page.dart @@ -8,6 +8,7 @@ import 'package:confs_tech/widgets/main_bottom_bar.dart'; import 'package:confs_tech/widgets/sliver_search_bar.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:share/share.dart'; class HomePage extends StatefulWidget { @override @@ -28,60 +29,68 @@ class _HomePageState extends State { @override Widget build(BuildContext context) { - return Scaffold( - appBar: SearchBar( - actions: [ - PopupMenuButton( - itemBuilder: (context){ - return {'Feedback', 'About'}.map((item) => - PopupMenuItem( - value: item, - child: Text(item), - ) - ).toList(); - }, - onSelected: (selected) { - if (selected == 'Feedback') { - Navigator.pushNamed(context, '/feedback'); - } else if (selected == 'About') { - showAboutDialog( - context: context, - applicationName: "Confs.tech", - applicationIcon: Image( - image: AssetImage("images/logo_icon.png"), - width: 32, - height: 32, + return BlocProvider( + create: (context) => BottomBarBloc(), + child: Scaffold( + appBar: SearchBar( + actions: [ + PopupMenuButton( + itemBuilder: (context){ + return {'Feedback', 'Share the app', 'About'}.map((item) => + PopupMenuItem( + value: item, + child: Text(item), + ) + ).toList(); + }, + onSelected: (selected) { + if (selected == 'Feedback') { + Navigator.pushNamed(context, '/feedback'); + } else if (selected == 'About') { + showAboutDialog( + context: context, + applicationName: "Confs.tech", + applicationIcon: Image( + image: AssetImage("images/logo_icon.png"), + width: 32, + height: 32, + ), + applicationVersion: "1.0", + children: [ + ConfsAboutDialog.AboutDialog() + ] + ); + } else if (selected == 'Share the app') { + //CHANGE THE URL TO iOS and Android!!! + Share.share('Hey, check out this conference events app: ' + 'https://play.google.com/store/apps/details?id=leonardo2204.com.confs_tech'); + } + }, + ) + ], + onSearchTextChanged: (text) { + BlocProvider.of(context) + .add(SearchChanged(searchQuery: text)); + }, + ), + body: SafeArea( + child: MultiBlocProvider( + providers: [ + BlocProvider( + create: (BuildContext ctx) => _eventBloc + ), + BlocProvider( + create: (BuildContext ctx) => + FilterStatsBloc( + filteredEventsBloc: BlocProvider.of(context) ), - applicationVersion: "1.0", - children: [ - ConfsAboutDialog.AboutDialog() - ] - ); - } - }, - ) - ], - onSearchTextChanged: (text) { - BlocProvider.of(context) - .add(SearchChanged(searchQuery: text)); - }, - ), - body: SafeArea( - child: MultiBlocProvider( - providers: [ - BlocProvider( - create: (BuildContext ctx) => _eventBloc - ), - BlocProvider( - create: (BuildContext ctx) => - FilterStatsBloc( - filteredEventsBloc: BlocProvider.of(context) - ), - ),], - child: SearchBody(), + ), + ], + child: SearchBody(), + ), ), + bottomNavigationBar: MainBottomBar(), ), - bottomNavigationBar: MainBottomBar(), ); } } \ No newline at end of file diff --git a/lib/blocs/bloc.dart b/lib/blocs/bloc.dart index 01e520e..ec32d6d 100644 --- a/lib/blocs/bloc.dart +++ b/lib/blocs/bloc.dart @@ -1,3 +1,6 @@ +export 'bottom_bar/bottom_bar_bloc.dart'; +export 'bottom_bar/bottom_bar_event.dart'; +export 'bottom_bar/bottom_bar_state.dart'; export 'event/event_bloc.dart'; export 'event/event_event.dart'; export 'event/event_state.dart'; diff --git a/lib/blocs/bottom_bar/bottom_bar_bloc.dart b/lib/blocs/bottom_bar/bottom_bar_bloc.dart new file mode 100644 index 0000000..0624248 --- /dev/null +++ b/lib/blocs/bottom_bar/bottom_bar_bloc.dart @@ -0,0 +1,20 @@ +import 'dart:async'; + +import 'package:bloc/bloc.dart'; + +import '../bloc.dart'; + + +class BottomBarBloc extends Bloc { + @override + BottomBarState get initialState => InitialBottomBarState(); + + @override + Stream mapEventToState( + BottomBarEvent event, + ) async* { + if (event is BottomBarSelected) { + yield BottomBarSelectedSuccess(selectedIndex: event.selectedIndex); + } + } +} diff --git a/lib/blocs/bottom_bar/bottom_bar_event.dart b/lib/blocs/bottom_bar/bottom_bar_event.dart new file mode 100644 index 0000000..ecafa28 --- /dev/null +++ b/lib/blocs/bottom_bar/bottom_bar_event.dart @@ -0,0 +1,14 @@ +import 'package:equatable/equatable.dart'; + +abstract class BottomBarEvent extends Equatable { + const BottomBarEvent(); +} + +class BottomBarSelected extends BottomBarEvent { + final int selectedIndex; + + BottomBarSelected(this.selectedIndex); + + @override + List get props => [selectedIndex]; +} \ No newline at end of file diff --git a/lib/blocs/bottom_bar/bottom_bar_state.dart b/lib/blocs/bottom_bar/bottom_bar_state.dart new file mode 100644 index 0000000..e05ea1e --- /dev/null +++ b/lib/blocs/bottom_bar/bottom_bar_state.dart @@ -0,0 +1,19 @@ +import 'package:equatable/equatable.dart'; + +abstract class BottomBarState extends Equatable { + final int selectedIndex; + const BottomBarState({ this.selectedIndex = 0 }); +} + +class InitialBottomBarState extends BottomBarState { + @override + List get props => []; +} + +class BottomBarSelectedSuccess extends BottomBarState { + BottomBarSelectedSuccess({ selectedIndex = 0 }) + : super(selectedIndex: selectedIndex); + + @override + List get props => [selectedIndex]; +} \ No newline at end of file diff --git a/lib/widgets/main_bottom_bar.dart b/lib/widgets/main_bottom_bar.dart index f2ab82d..1ebdda2 100644 --- a/lib/widgets/main_bottom_bar.dart +++ b/lib/widgets/main_bottom_bar.dart @@ -10,51 +10,49 @@ class MainBottomBar extends StatefulWidget{ } class _MainBottomBarState extends State { - int selectedIdx = 0; - @override Widget build(BuildContext context) { - return BottomNavigationBar( - currentIndex: selectedIdx, - onTap: (int selected){ - switch (selected) { - case 0: - BlocProvider.of(context) - .add(UpcomingSelected()); - setState(() { - selectedIdx = 0; - }); - break; - case 1: - BlocProvider.of(context) - .add(CallForPaperSelected()); - setState(() { - selectedIdx = 1; - }); - break; - case 2: - BlocProvider.of(context) - .add(ShowPastSelected()); - setState(() { - selectedIdx = 2; - }); - break; - } - }, - items: [ - BottomNavigationBarItem( - icon: Icon(Icons.event), - title: Text("Upcoming"), - ), - BottomNavigationBarItem( - icon: Icon(Icons.note_add), - title: Text("Call for Papers"), - ), - BottomNavigationBarItem( - icon: Icon(Icons.event_available), - title: Text("Past"), - ) - ], + return BlocBuilder( + bloc: BlocProvider.of(context), + builder: (context, state) => BottomNavigationBar( + currentIndex: state.selectedIndex, + onTap: (int selected){ + switch (selected) { + case 0: + BlocProvider.of(context) + .add(BottomBarSelected(0)); + BlocProvider.of(context) + .add(UpcomingSelected()); + break; + case 1: + BlocProvider.of(context) + .add(BottomBarSelected(1)); + BlocProvider.of(context) + .add(CallForPaperSelected()); + break; + case 2: + BlocProvider.of(context) + .add(BottomBarSelected(2)); + BlocProvider.of(context) + .add(ShowPastSelected()); + break; + } + }, + items: [ + BottomNavigationBarItem( + icon: Icon(Icons.event), + title: Text("Upcoming"), + ), + BottomNavigationBarItem( + icon: Icon(Icons.note_add), + title: Text("Call for Papers"), + ), + BottomNavigationBarItem( + icon: Icon(Icons.event_available), + title: Text("Past"), + ) + ], + ), ); } diff --git a/lib/widgets/sliver_search_bar.dart b/lib/widgets/sliver_search_bar.dart index c08dec5..1761ea8 100644 --- a/lib/widgets/sliver_search_bar.dart +++ b/lib/widgets/sliver_search_bar.dart @@ -1,5 +1,7 @@ +import 'package:confs_tech/blocs/bloc.dart'; import 'package:confs_tech/widgets/ellipsis_painter.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; class SearchBar extends StatefulWidget implements PreferredSizeWidget { final List actions; @@ -75,24 +77,31 @@ class _SearchBarState extends State with SingleTickerProviderStateMix }, child: Stack( children: [ - AppBar( - backgroundColor: isInSearchMode ? - Colors.white : Theme.of(context).primaryColor, - title: _appBarTitle, - leading: isInSearchMode ? IconButton( - icon: Icon(Icons.arrow_back), - onPressed: _toggleAppBarStatus, - ) : null, - actions: List.unmodifiable(() sync* { - if (!isInSearchMode) yield - GestureDetector( - child: Icon(Icons.search), - onTapUp: onSearchTapUp, - ); - if (!isInSearchMode && this.actions != null) { - yield* this.actions; + BlocListener( + listener: (BuildContext context, BottomBarState state) { + if (state is BottomBarSelectedSuccess && isInSearchMode) { + _toggleAppBarStatus(); } - }()), + }, + child: AppBar( + backgroundColor: isInSearchMode ? + Colors.white : Theme.of(context).primaryColor, + title: _appBarTitle, + leading: isInSearchMode ? IconButton( + icon: Icon(Icons.arrow_back), + onPressed: _toggleAppBarStatus, + ) : null, + actions: List.unmodifiable(() sync* { + if (!isInSearchMode) yield + GestureDetector( + child: Icon(Icons.search), + onTapUp: onSearchTapUp, + ); + if (!isInSearchMode && this.actions != null) { + yield* this.actions; + } + }()), + ), ), !isInSearchMode ? AnimatedBuilder( animation: _animation, diff --git a/pubspec.lock b/pubspec.lock index a5c5c3c..7b0a315 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -212,6 +212,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.24.0" + share: + dependency: "direct main" + description: + name: share + url: "https://pub.dartlang.org" + source: hosted + version: "0.6.4+3" sky_engine: dependency: transitive description: flutter diff --git a/pubspec.yaml b/pubspec.yaml index 6f74441..1a69927 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -11,7 +11,7 @@ description: Find your next conference # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+3 +version: 1.0.1+0 environment: sdk: ">=2.2.0 <3.0.0" @@ -28,6 +28,7 @@ dependencies: intl: ^0.16.1 url_launcher: ^5.4.2 collection: ^1.14.11 + share: ^0.6.4+3 # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons.