Skip to content
Snippets Groups Projects
Commit 6338fc09 authored by Benoît Harrault's avatar Benoît Harrault
Browse files

Merge branch '33-add-navigation' into 'master'

Resolve "Add navigation"

Closes #33

See merge request !31
parents 637e33e6 aa315b4b
No related branches found
No related tags found
1 merge request!31Resolve "Add navigation"
Pipeline #4487 passed
org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true
android.enableJetifier=true
app.versionName=1.0.22
app.versionCode=23
app.versionName=1.0.23
app.versionCode=24
{
"app_name": "Random application",
"bottom_nav_sample": "Sample",
"bottom_nav_chart": "Graph",
"TOP": "TOP",
"BOTTOM": "BOTTOM"
......
{
"app_name": "Random application",
"bottom_nav_sample": "Démo",
"bottom_nav_chart": "Graph",
"TOP": "HAUT",
"BOTTOM": "BAS"
......
......@@ -2,39 +2,10 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
class ActivityDemoPage extends StatelessWidget {
static const String code = 'demo';
static const String route = '/' + code;
const ActivityDemoPage({super.key});
@override
Widget build(BuildContext context) {
Scaffold pageContent = Scaffold(
appBar: AppBar(
elevation: 0,
actions: <Widget>[
IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () {
print('reset activity');
Navigator.pop(context);
},
),
],
),
backgroundColor: Theme.of(context).colorScheme.background,
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Text('TOP').tr(),
SizedBox(height: 2),
Text('BOTTOM').tr(),
],
),
),
);
return SizedBox.expand(
child: Container(
child: FittedBox(
......@@ -43,7 +14,18 @@ class ActivityDemoPage extends StatelessWidget {
child: SizedBox(
height: (MediaQuery.of(context).size.height),
width: (MediaQuery.of(context).size.width),
child: pageContent,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Text('TOP').tr(),
SizedBox(height: 2),
Text('BOTTOM').tr(),
],
),
),
),
),
),
......
......@@ -2,56 +2,12 @@ import 'package:flutter/material.dart';
import 'package:random/painters/GraphPainter.dart';
class ActivityGraphPage extends StatelessWidget {
static const String code = 'graph';
static const String route = '/' + code;
const ActivityGraphPage({super.key});
@override
Widget build(BuildContext context) {
double boardWidth = MediaQuery.of(context).size.width;
Scaffold pageContent = Scaffold(
appBar: AppBar(
elevation: 0,
actions: <Widget>[
IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () {
print('reset activity');
Navigator.pop(context);
},
),
],
),
backgroundColor: Theme.of(context).colorScheme.background,
body: SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Center(
child: GestureDetector(
onTapUp: (details) {
double xTap = details.localPosition.dx;
double yTap = details.localPosition.dy;
print('[' + xTap.toString() + ',' + yTap.toString() + ']');
},
child: Container(
margin: EdgeInsets.all(4),
padding: EdgeInsets.all(4),
child: CustomPaint(
size: Size(boardWidth, boardWidth),
willChange: false,
painter: GraphPainter(),
isComplex: true,
),
),
),
),
],
),
),
);
return SizedBox.expand(
child: Container(
child: FittedBox(
......@@ -60,7 +16,33 @@ class ActivityGraphPage extends StatelessWidget {
child: SizedBox(
height: (MediaQuery.of(context).size.height),
width: (MediaQuery.of(context).size.width),
child: pageContent,
child: SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Center(
child: GestureDetector(
onTapUp: (details) {
double xTap = details.localPosition.dx;
double yTap = details.localPosition.dy;
print('[' + xTap.toString() + ',' + yTap.toString() + ']');
},
child: Container(
margin: EdgeInsets.all(4),
padding: EdgeInsets.all(4),
child: CustomPaint(
size: Size(boardWidth, boardWidth),
willChange: false,
painter: GraphPainter(),
isComplex: true,
),
),
),
),
],
),
),
),
),
),
......
import 'package:hydrated_bloc/hydrated_bloc.dart';
class BottomNavCubit extends HydratedCubit<int> {
BottomNavCubit() : super(0);
void updateIndex(int index) => emit(index);
void getFirstScreen() => emit(0);
void getSecondScreen() => emit(1);
@override
int? fromJson(Map<String, dynamic> json) {
return json['pageIndex'] as int?;
}
@override
Map<String, dynamic>? toJson(int state) {
return <String, int>{'pageIndex': state};
}
}
import 'dart:io';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
import 'package:hydrated_bloc/hydrated_bloc.dart';
import 'package:path_provider/path_provider.dart';
import 'package:random/ui/screens/skeleton_screen.dart';
import 'package:random/config/theme.dart';
import 'package:random/activities/ActivityDemoPage.dart';
import 'package:random/activities/ActivityGraphPage.dart';
void main() async {
/// Initialize packages
WidgetsFlutterBinding.ensureInitialized();
await EasyLocalization.ensureInitialized();
final Directory tmpDir = await getTemporaryDirectory();
Hive.init(tmpDir.toString());
HydratedBloc.storage = await HydratedStorage.build(
storageDirectory: tmpDir,
);
runApp(
EasyLocalization(
......@@ -33,32 +42,6 @@ class MyApp extends StatelessWidget {
title: 'Random application',
theme: appTheme,
home: SkeletonScreen(),
onGenerateRoute: (settings) {
switch (settings.name) {
case ActivityDemoPage.route:
{
return MaterialPageRoute(
builder: (context) => ActivityDemoPage(),
);
}
case ActivityGraphPage.route:
{
return MaterialPageRoute(
builder: (context) => ActivityGraphPage(),
);
}
default:
{
print("Unknown menu entry: " + settings.name.toString());
}
break;
}
return null;
},
// Localization stuff
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
locale: context.locale,
......
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:random/activities/ActivityDemoPage.dart';
import 'package:random/activities/ActivityGraphPage.dart';
import 'package:random/cubit/bottom_nav_cubit.dart';
import 'package:random/ui/widgets/custom_app_bar.dart';
import 'package:random/ui/widgets/bottom_nav_bar.dart';
class SkeletonScreen extends StatelessWidget {
static const String id = 'home';
const SkeletonScreen({super.key});
@override
Widget build(BuildContext context) {
double screenWidth = MediaQuery.of(context).size.width;
const List<Widget> pageNavigation = <Widget>[
ActivityDemoPage(),
ActivityGraphPage(),
];
Container _menuItem(String activityCode) {
double imageSize = screenWidth / 4;
String imageAsset = 'assets/menu/' + activityCode + '.png';
return Container(
margin: EdgeInsets.all(2),
child: TextButton(
style: TextButton.styleFrom(
padding: EdgeInsets.all(4),
backgroundColor: Theme.of(context).colorScheme.background,
),
child: Image(
image: AssetImage(imageAsset),
width: imageSize,
height: imageSize,
fit: BoxFit.fill,
),
onPressed: () {
Navigator.pushNamed(
context,
'/' + activityCode,
);
return BlocProvider<BottomNavCubit>(
create: (BuildContext context) => BottomNavCubit(),
child: Scaffold(
extendBodyBehindAppBar: true,
appBar: const CustomAppBarGone(),
body: BlocBuilder<BottomNavCubit, int>(
builder: (BuildContext context, int state) {
return AnimatedSwitcher(
duration: const Duration(milliseconds: 300),
child: pageNavigation.elementAt(state));
},
),
);
}
return Scaffold(
extendBodyBehindAppBar: true,
backgroundColor: Theme.of(context).colorScheme.background,
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
_menuItem(ActivityDemoPage.code),
_menuItem(ActivityGraphPage.code),
],
),
bottomNavigationBar: const BottomNavBar(),
backgroundColor: Theme.of(context).colorScheme.background,
),
);
}
......
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:ionicons/ionicons.dart';
import 'package:random/cubit/bottom_nav_cubit.dart';
class BottomNavBar extends StatelessWidget {
const BottomNavBar({super.key});
@override
Widget build(BuildContext context) {
return Card(
margin: const EdgeInsets.only(top: 1, right: 4, left: 4),
elevation: 4,
shadowColor: Theme.of(context).colorScheme.shadow,
color: Theme.of(context).colorScheme.surfaceVariant,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(16),
topRight: Radius.circular(16),
),
),
child: BlocBuilder<BottomNavCubit, int>(builder: (BuildContext context, int state) {
return BottomNavigationBar(
currentIndex: state,
onTap: (int index) => context.read<BottomNavCubit>().updateIndex(index),
type: BottomNavigationBarType.fixed,
elevation: 0,
backgroundColor: Colors.transparent,
selectedItemColor: Theme.of(context).colorScheme.primary,
unselectedItemColor: Theme.of(context).textTheme.bodySmall!.color,
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: const Icon(Ionicons.image_outline),
label: tr('bottom_nav_sample'),
),
BottomNavigationBarItem(
icon: const Icon(Ionicons.pencil_outline),
label: tr('bottom_nav_chart'),
),
],
);
}),
);
}
}
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class CustomAppBarGone extends StatelessWidget implements PreferredSizeWidget {
const CustomAppBarGone({super.key});
@override
Widget build(BuildContext context) {
final Brightness brightness = Theme.of(context).colorScheme.brightness;
return AppBar(
systemOverlayStyle: SystemUiOverlayStyle(
statusBarBrightness: brightness,
systemStatusBarContrastEnforced: false,
statusBarColor: Theme.of(context).colorScheme.background,
statusBarIconBrightness:
brightness == Brightness.dark ? Brightness.light : Brightness.dark,
),
backgroundColor: Colors.transparent,
excludeHeaderSemantics: true,
shadowColor: Colors.transparent,
scrolledUnderElevation: 0,
surfaceTintColor: Colors.transparent,
foregroundColor: Colors.transparent,
elevation: 0,
bottomOpacity: 0,
toolbarOpacity: 0,
);
}
@override
Size get preferredSize => const Size.fromHeight(0);
}
......@@ -9,6 +9,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.4.2"
bloc:
dependency: transitive
description:
name: bloc
sha256: "3820f15f502372d979121de1f6b97bfcf1630ebff8fe1d52fb2b0bfa49be5b49"
url: "https://pub.dev"
source: hosted
version: "8.1.2"
characters:
dependency: transitive
description:
......@@ -33,6 +41,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.17.2"
crypto:
dependency: transitive
description:
name: crypto
sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab
url: "https://pub.dev"
source: hosted
version: "3.0.3"
easy_localization:
dependency: "direct main"
description:
......@@ -70,6 +86,14 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
flutter_bloc:
dependency: "direct main"
description:
name: flutter_bloc
sha256: e74efb89ee6945bcbce74a5b3a5a3376b088e5f21f55c263fc38cbdc6237faae
url: "https://pub.dev"
source: hosted
version: "8.1.3"
flutter_localizations:
dependency: transitive
description: flutter
......@@ -80,6 +104,22 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
hive:
dependency: transitive
description:
name: hive
sha256: "8dcf6db979d7933da8217edcec84e9df1bdb4e4edc7fc77dbd5aa74356d6d941"
url: "https://pub.dev"
source: hosted
version: "2.2.3"
hydrated_bloc:
dependency: "direct main"
description:
name: hydrated_bloc
sha256: "24994e61f64904d911683cce1a31dc4ef611619da5253f1de2b7b8fc6f79a118"
url: "https://pub.dev"
source: hosted
version: "9.1.2"
intl:
dependency: transitive
description:
......@@ -88,6 +128,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.18.1"
ionicons:
dependency: "direct main"
description:
name: ionicons
sha256: "5496bc65a16115ecf05b15b78f494ee4a8869504357668f0a11d689e970523cf"
url: "https://pub.dev"
source: hosted
version: "0.2.2"
material_color_utilities:
dependency: transitive
description:
......@@ -104,6 +152,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.9.1"
nested:
dependency: transitive
description:
name: nested
sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20"
url: "https://pub.dev"
source: hosted
version: "1.0.0"
path:
dependency: transitive
description:
......@@ -112,6 +168,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.8.3"
path_provider:
dependency: "direct main"
description:
name: path_provider
sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa
url: "https://pub.dev"
source: hosted
version: "2.1.1"
path_provider_android:
dependency: transitive
description:
name: path_provider_android
sha256: e595b98692943b4881b219f0a9e3945118d3c16bd7e2813f98ec6e532d905f72
url: "https://pub.dev"
source: hosted
version: "2.2.1"
path_provider_foundation:
dependency: transitive
description:
name: path_provider_foundation
sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d"
url: "https://pub.dev"
source: hosted
version: "2.3.1"
path_provider_linux:
dependency: transitive
description:
......@@ -152,6 +232,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.6"
provider:
dependency: transitive
description:
name: provider
sha256: cdbe7530b12ecd9eb455bdaa2fcb8d4dad22e80b8afb4798b41479d5ce26847f
url: "https://pub.dev"
source: hosted
version: "6.0.5"
shared_preferences:
dependency: transitive
description:
......@@ -213,6 +301,22 @@ packages:
description: flutter
source: sdk
version: "0.0.99"
synchronized:
dependency: transitive
description:
name: synchronized
sha256: "5fcbd27688af6082f5abd611af56ee575342c30e87541d0245f7ff99faa02c60"
url: "https://pub.dev"
source: hosted
version: "3.1.0"
typed_data:
dependency: transitive
description:
name: typed_data
sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
url: "https://pub.dev"
source: hosted
version: "1.3.2"
vector_math:
dependency: transitive
description:
......
......@@ -3,7 +3,7 @@ description: A random application, for testing purpose only.
publish_to: 'none'
version: 1.0.22+23
version: 1.0.23+24
environment:
sdk: '^3.0.0'
......@@ -13,9 +13,13 @@ dependencies:
sdk: flutter
easy_localization: ^3.0.1
flutter_bloc: ^8.1.1
path_provider: ^2.0.11
hydrated_bloc: ^9.0.0
ionicons: ^0.2.2
flutter:
uses-material-design: true
uses-material-design: false
assets:
- assets/menu/
- assets/translations/
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment