diff --git a/android/gradle.properties b/android/gradle.properties index 4172535e230f55aa61b49528f4373eee71c530c5..79b0a521ccefab573594bb786103d6e5fc762883 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,5 +1,5 @@ org.gradle.jvmargs=-Xmx1536M android.useAndroidX=true android.enableJetifier=true -app.versionName=1.0.34 -app.versionCode=35 +app.versionName=1.0.35 +app.versionCode=36 diff --git a/lib/cubit/bottom_nav_cubit.dart b/lib/cubit/bottom_nav_cubit.dart index ff21cc4493ea290205ca5fe8ed0099fa3b0f619a..177572b02aa306afe9bd9c25242001e02ba684b1 100644 --- a/lib/cubit/bottom_nav_cubit.dart +++ b/lib/cubit/bottom_nav_cubit.dart @@ -3,15 +3,21 @@ import 'package:hydrated_bloc/hydrated_bloc.dart'; class BottomNavCubit extends HydratedCubit<int> { BottomNavCubit() : super(0); - void updateIndex(int index) => emit(index); + int pagesCount = 4; - void movePrevious() => emit((state > 0) ? state - 1 : state); - void moveNext() => emit((state < 3) ? state + 1 : state); + void updateIndex(int index) { + if (isIndexAllowed(index)) { + emit(index); + } else { + goToHomePage(); + } + } + + bool isIndexAllowed(int index) { + return (index >= 0) && (index < pagesCount); + } - void getDemoPage() => emit(0); - void getGraphPage() => emit(1); - void getSettingsPage() => emit(2); - void getAboutPage() => emit(3); + void goToHomePage() => emit(0); @override int? fromJson(Map<String, dynamic> json) { diff --git a/lib/ui/skeleton.dart b/lib/ui/skeleton.dart index cf3414ee1e453f3f69a97f53eea9989af5a7732e..0f016729734e52cddb7c280e65a53d20b3096f3b 100644 --- a/lib/ui/skeleton.dart +++ b/lib/ui/skeleton.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_swipe/flutter_swipe.dart'; import 'package:random/cubit/bottom_nav_cubit.dart'; import 'package:random/cubit/settings_cubit.dart'; @@ -9,7 +10,6 @@ import 'package:random/ui/screens/graph_page.dart'; import 'package:random/ui/screens/settings_page.dart'; import 'package:random/ui/widgets/app_bar.dart'; import 'package:random/ui/widgets/bottom_nav_bar.dart'; -import 'package:random/ui/widgets/debug_bloc.dart'; class SkeletonScreen extends StatefulWidget { const SkeletonScreen({super.key}); @@ -30,44 +30,37 @@ class _SkeletonScreenState extends State<SkeletonScreen> { AboutPage(), ]; - String debug = ''; - return BlocProvider<SettingsCubit>( create: (BuildContext context) => SettingsCubit(), child: BlocProvider<BottomNavCubit>( create: (BuildContext context) => BottomNavCubit(), child: BlocBuilder<BottomNavCubit, int>( builder: (BuildContext context, int state) { - return GestureDetector( - onHorizontalDragEnd: (dragDetail) { - debug = dragDetail.velocity.pixelsPerSecond.toString(); - print('debug: ' + debug); - - if (dragDetail.velocity.pixelsPerSecond.dx < 1) { - context.read<BottomNavCubit>().moveNext(); - } else { - context.read<BottomNavCubit>().movePrevious(); - } - }, - child: Scaffold( - extendBodyBehindAppBar: false, - appBar: StandardAppBar(), - body: BlocBuilder<BottomNavCubit, int>( - builder: (BuildContext context, int state) { - return AnimatedSwitcher( - duration: const Duration(milliseconds: 300), - child: Stack( - children: [ - pageNavigation.elementAt(state), - debug != '' ? DebugBloc(content: debug) : SizedBox(), - ], - ), - ); - }, + return Scaffold( + extendBodyBehindAppBar: false, + appBar: StandardAppBar(), + body: Swiper( + itemCount: BlocProvider.of<BottomNavCubit>(context).pagesCount, + itemBuilder: (BuildContext context, int index) { + return AnimatedSwitcher( + duration: const Duration(milliseconds: 300), + child: pageNavigation.elementAt(index), + ); + }, + pagination: SwiperPagination( + builder: SwiperCustomPagination( + builder: (BuildContext context, SwiperPluginConfig config) { + return BottomNavBar(swipeController: config.controller); + }, + ), ), - bottomNavigationBar: const BottomNavBar(), - backgroundColor: Theme.of(context).colorScheme.background, + onIndexChanged: (newPageIndex) { + BlocProvider.of<BottomNavCubit>(context).updateIndex(newPageIndex); + }, + outer: true, + loop: false, ), + backgroundColor: Theme.of(context).colorScheme.background, ); }, ), diff --git a/lib/ui/widgets/bottom_nav_bar.dart b/lib/ui/widgets/bottom_nav_bar.dart index f0ec9f4143d392f32f6b937cf6126bcd208aae2b..1349c7ec91661e5dd28e79c1d5a61ad72d3d27af 100644 --- a/lib/ui/widgets/bottom_nav_bar.dart +++ b/lib/ui/widgets/bottom_nav_bar.dart @@ -1,17 +1,24 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_swipe/flutter_swipe.dart'; import 'package:unicons/unicons.dart'; import 'package:random/cubit/bottom_nav_cubit.dart'; class BottomNavBar extends StatelessWidget { - const BottomNavBar({super.key}); + const BottomNavBar({super.key, required this.swipeController}); + + final SwiperController swipeController; @override Widget build(BuildContext context) { return Card( - margin: const EdgeInsets.only(top: 1, right: 4, left: 4), + margin: const EdgeInsets.only( + top: 1, + right: 0, + left: 0, + ), elevation: 4, shadowColor: Theme.of(context).colorScheme.shadow, color: Theme.of(context).colorScheme.surfaceVariant, @@ -25,7 +32,10 @@ class BottomNavBar extends StatelessWidget { builder: (BuildContext context, int state) { return BottomNavigationBar( currentIndex: state, - onTap: (int index) => context.read<BottomNavCubit>().updateIndex(index), + onTap: (int index) { + context.read<BottomNavCubit>().updateIndex(index); + swipeController.move(index); + }, type: BottomNavigationBarType.fixed, elevation: 0, backgroundColor: Colors.transparent, diff --git a/lib/ui/widgets/settings_form.dart b/lib/ui/widgets/settings_form.dart index f9d821cc549efb2ca6675b47071988746785a9c9..ac40063bd0d2c5ebdb911ec3e744dfd31c6e3ec4 100644 --- a/lib/ui/widgets/settings_form.dart +++ b/lib/ui/widgets/settings_form.dart @@ -3,7 +3,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:unicons/unicons.dart'; -import 'package:random/cubit/bottom_nav_cubit.dart'; import 'package:random/cubit/settings_cubit.dart'; import 'package:random/config/theme.dart'; import 'package:random/models/interface_type.dart'; @@ -48,8 +47,6 @@ class _SettingsFormState extends State<SettingsForm> { securityToken: securityTokenController.text, interfaceType: _selectedInterfaceType[0] ? InterfaceType.basic : InterfaceType.expert, ); - - BlocProvider.of<BottomNavCubit>(context).getDemoPage(); } return Column( diff --git a/pubspec.lock b/pubspec.lock index 426a507a4f752b326e35c1ca97797cfa3ff952f4..131944004fd3d998e236c23c8eb60b8884508340 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -115,6 +115,14 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_swipe: + dependency: "direct main" + description: + name: flutter_swipe + sha256: dc6541bac3a0545ce15a3fa15913f6250532062960bf6b0ad4562d02f14a8545 + url: "https://pub.dev" + source: hosted + version: "1.0.1" flutter_web_plugins: dependency: transitive description: flutter diff --git a/pubspec.yaml b/pubspec.yaml index 8c68fd5f440bd8db77ec499be923380f2c34a318..7edccdd2e5f2cc5a2c75fab9be5961333205eb11 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,7 +3,7 @@ description: A random application, for testing purpose only. publish_to: 'none' -version: 1.0.34+35 +version: 1.0.35+36 environment: sdk: '^3.0.0' @@ -19,6 +19,7 @@ dependencies: hydrated_bloc: ^9.0.0 unicons: ^2.1.1 package_info_plus: ^5.0.1 + flutter_swipe: ^1.0.1 flutter: uses-material-design: false