Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • 65-improve-app-metadata
  • master
  • Release_1.0.10_11
  • Release_1.0.11_12
  • Release_1.0.12_13
  • Release_1.0.13_14
  • Release_1.0.14_15
  • Release_1.0.15_16
  • Release_1.0.16_17
  • Release_1.0.17_18
  • Release_1.0.18_19
  • Release_1.0.19_20
  • Release_1.0.20_21
  • Release_1.0.21_22
  • Release_1.0.22_23
  • Release_1.0.23_24
  • Release_1.0.24_25
  • Release_1.0.25_26
  • Release_1.0.26_27
  • Release_1.0.27_28
  • Release_1.0.28_29
  • Release_1.0.29_30
  • Release_1.0.30_31
  • Release_1.0.31_32
  • Release_1.0.32_33
  • Release_1.0.33_34
  • Release_1.0.34_35
  • Release_1.0.35_36
  • Release_1.0.36_37
  • Release_1.0.37_38
  • Release_1.0.38_39
  • Release_1.0.39_40
  • Release_1.0.3_4
  • Release_1.0.40_41
  • Release_1.0.41_42
  • Release_1.0.42_43
  • Release_1.0.43_44
  • Release_1.0.44_45
  • Release_1.0.45_46
  • Release_1.0.46_47
  • Release_1.0.47_48
  • Release_1.0.48_49
  • Release_1.0.49_50
  • Release_1.0.4_5
  • Release_1.0.50_51
  • Release_1.0.51_52
  • Release_1.0.52_53
  • Release_1.0.53_54
  • Release_1.0.54_55
  • Release_1.0.55_56
  • Release_1.0.56_57
  • Release_1.0.57_58
  • Release_1.0.58_59
  • Release_1.0.59_60
  • Release_1.0.5_6
  • Release_1.0.60_61
  • Release_1.0.61_62
  • Release_1.0.62_63
  • Release_1.0.63_64
  • Release_1.0.6_7
  • Release_1.0.7_8
  • Release_1.0.8_9
  • Release_1.0.9_10
  • Release_1.1.0_65
  • Release_1.1.1_66
  • Release_1.1.2_67
  • Release_1.1.3_68
  • Release_1.2.0_69
  • Release_1.2.1_70
  • Release_1.3.0_71
  • Release_1.3.1_72
  • Release_1.3.2_73
  • Release_1.4.0_74
  • Release_1.5.0_75
  • Release_1.6.0_76
  • Release_1.7.0_77
  • Release_1.7.1_78
  • Release_1.7.2_79
  • Release_1.8.0_80
  • Release_3_1.0.2
  • Release_Release_3_1.0.2
81 results

Target

Select target project
  • android/random
1 result
Select Git revision
  • 65-improve-app-metadata
  • master
  • Release_1.0.10_11
  • Release_1.0.11_12
  • Release_1.0.12_13
  • Release_1.0.13_14
  • Release_1.0.14_15
  • Release_1.0.15_16
  • Release_1.0.16_17
  • Release_1.0.17_18
  • Release_1.0.18_19
  • Release_1.0.19_20
  • Release_1.0.20_21
  • Release_1.0.21_22
  • Release_1.0.22_23
  • Release_1.0.23_24
  • Release_1.0.24_25
  • Release_1.0.25_26
  • Release_1.0.26_27
  • Release_1.0.27_28
  • Release_1.0.28_29
  • Release_1.0.29_30
  • Release_1.0.30_31
  • Release_1.0.31_32
  • Release_1.0.32_33
  • Release_1.0.33_34
  • Release_1.0.34_35
  • Release_1.0.35_36
  • Release_1.0.36_37
  • Release_1.0.37_38
  • Release_1.0.38_39
  • Release_1.0.39_40
  • Release_1.0.3_4
  • Release_1.0.40_41
  • Release_1.0.41_42
  • Release_1.0.42_43
  • Release_1.0.43_44
  • Release_1.0.44_45
  • Release_1.0.45_46
  • Release_1.0.46_47
  • Release_1.0.47_48
  • Release_1.0.48_49
  • Release_1.0.49_50
  • Release_1.0.4_5
  • Release_1.0.50_51
  • Release_1.0.51_52
  • Release_1.0.52_53
  • Release_1.0.53_54
  • Release_1.0.54_55
  • Release_1.0.55_56
  • Release_1.0.56_57
  • Release_1.0.57_58
  • Release_1.0.58_59
  • Release_1.0.59_60
  • Release_1.0.5_6
  • Release_1.0.60_61
  • Release_1.0.61_62
  • Release_1.0.62_63
  • Release_1.0.63_64
  • Release_1.0.6_7
  • Release_1.0.7_8
  • Release_1.0.8_9
  • Release_1.0.9_10
  • Release_1.1.0_65
  • Release_1.1.1_66
  • Release_1.1.2_67
  • Release_1.1.3_68
  • Release_1.2.0_69
  • Release_1.2.1_70
  • Release_1.3.0_71
  • Release_1.3.1_72
  • Release_1.3.2_73
  • Release_1.4.0_74
  • Release_1.5.0_75
  • Release_1.6.0_76
  • Release_1.7.0_77
  • Release_1.7.1_78
  • Release_1.7.2_79
  • Release_1.8.0_80
  • Release_3_1.0.2
  • Release_Release_3_1.0.2
81 results
Show changes
Commits on Source (8)
Showing
with 316 additions and 154 deletions
org.gradle.jvmargs=-Xmx1536M org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true android.useAndroidX=true
android.enableJetifier=true android.enableJetifier=true
app.versionName=1.0.32 app.versionName=1.0.36
app.versionCode=33 app.versionCode=37
...@@ -9,6 +9,9 @@ ...@@ -9,6 +9,9 @@
"settings_title": "Settings", "settings_title": "Settings",
"settings_label_api_url": "API URL:", "settings_label_api_url": "API URL:",
"settings_label_security_token": "Security token:", "settings_label_security_token": "Security token:",
"settings_label_interface_type": "Interface type:",
"interface_type_basic": "basic",
"interface_type_expert": "expert",
"settings_button_save": "Save", "settings_button_save": "Save",
"about_title": "About", "about_title": "About",
......
...@@ -9,6 +9,9 @@ ...@@ -9,6 +9,9 @@
"settings_title": "Paramètres", "settings_title": "Paramètres",
"settings_label_api_url": "URL de l'API :", "settings_label_api_url": "URL de l'API :",
"settings_label_security_token": "Jeton de sécurité :", "settings_label_security_token": "Jeton de sécurité :",
"settings_label_interface_type": "Type d'interface :",
"interface_type_basic": "simple",
"interface_type_expert": "expert",
"settings_button_save": "Enregistrer", "settings_button_save": "Enregistrer",
"about_title": "À propos", "about_title": "À propos",
......
...@@ -3,15 +3,21 @@ import 'package:hydrated_bloc/hydrated_bloc.dart'; ...@@ -3,15 +3,21 @@ import 'package:hydrated_bloc/hydrated_bloc.dart';
class BottomNavCubit extends HydratedCubit<int> { class BottomNavCubit extends HydratedCubit<int> {
BottomNavCubit() : super(0); BottomNavCubit() : super(0);
void updateIndex(int index) => emit(index); int pagesCount = 4;
void movePrevious() => emit((state > 0) ? state - 1 : state); void updateIndex(int index) {
void moveNext() => emit((state < 3) ? state + 1 : state); if (isIndexAllowed(index)) {
emit(index);
} else {
goToHomePage();
}
}
bool isIndexAllowed(int index) {
return (index >= 0) && (index < pagesCount);
}
void getDemoPage() => emit(0); void goToHomePage() => emit(0);
void getGraphPage() => emit(1);
void getSettingsPage() => emit(2);
void getAboutPage() => emit(3);
@override @override
int? fromJson(Map<String, dynamic> json) { int? fromJson(Map<String, dynamic> json) {
......
...@@ -11,6 +11,10 @@ class DataCubit extends HydratedCubit<DataState> { ...@@ -11,6 +11,10 @@ class DataCubit extends HydratedCubit<DataState> {
emit(state); emit(state);
} }
void updateCounter(int delta) {
emit(DataState(counter: (state.counter ?? 0) + delta));
}
@override @override
DataState? fromJson(Map<String, dynamic> json) { DataState? fromJson(Map<String, dynamic> json) {
int counter = json['counter'] as int; int counter = json['counter'] as int;
......
...@@ -2,12 +2,14 @@ import 'package:equatable/equatable.dart'; ...@@ -2,12 +2,14 @@ import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hydrated_bloc/hydrated_bloc.dart'; import 'package:hydrated_bloc/hydrated_bloc.dart';
import 'package:random/models/interface_type.dart';
part 'settings_state.dart'; part 'settings_state.dart';
class SettingsCubit extends HydratedCubit<SettingsState> { class SettingsCubit extends HydratedCubit<SettingsState> {
SettingsCubit() : super(const SettingsState()); SettingsCubit() : super(const SettingsState());
String getSetting(String key, [String? defaultValue]) { Object getSetting(String key, [String? defaultValue]) {
if (state.values.keys.contains(key)) { if (state.values.keys.contains(key)) {
return state.values[key] ?? defaultValue ?? ''; return state.values[key] ?? defaultValue ?? '';
} }
...@@ -15,13 +17,27 @@ class SettingsCubit extends HydratedCubit<SettingsState> { ...@@ -15,13 +17,27 @@ class SettingsCubit extends HydratedCubit<SettingsState> {
return defaultValue ?? ''; return defaultValue ?? '';
} }
String getApiUrl() {
return state.apiUrl ?? '';
}
String getSecurityToken() {
return state.securityToken ?? '';
}
InterfaceType getInterfaceType() {
return state.interfaceType ?? InterfaceType.basic;
}
void setValues({ void setValues({
String? apiUrl, String? apiUrl,
String? securityToken, String? securityToken,
InterfaceType? interfaceType,
}) { }) {
emit(SettingsState( emit(SettingsState(
apiUrl: apiUrl != null ? apiUrl : state.apiUrl, apiUrl: apiUrl != null ? apiUrl : state.apiUrl,
securityToken: securityToken != null ? securityToken : state.securityToken, securityToken: securityToken != null ? securityToken : state.securityToken,
interfaceType: interfaceType != null ? interfaceType : state.interfaceType,
)); ));
} }
...@@ -29,10 +45,23 @@ class SettingsCubit extends HydratedCubit<SettingsState> { ...@@ -29,10 +45,23 @@ class SettingsCubit extends HydratedCubit<SettingsState> {
SettingsState? fromJson(Map<String, dynamic> json) { SettingsState? fromJson(Map<String, dynamic> json) {
String apiUrl = json['apiUrl'] as String; String apiUrl = json['apiUrl'] as String;
String securityToken = json['securityToken'] as String; String securityToken = json['securityToken'] as String;
InterfaceType interfaceType;
switch (json['interfaceType'] as String) {
case 'InterfaceType.basic':
interfaceType = InterfaceType.basic;
break;
case 'InterfaceType.expert':
interfaceType = InterfaceType.expert;
break;
default:
interfaceType = InterfaceType.basic;
}
return SettingsState( return SettingsState(
apiUrl: apiUrl, apiUrl: apiUrl,
securityToken: securityToken, securityToken: securityToken,
interfaceType: interfaceType,
); );
} }
...@@ -41,6 +70,7 @@ class SettingsCubit extends HydratedCubit<SettingsState> { ...@@ -41,6 +70,7 @@ class SettingsCubit extends HydratedCubit<SettingsState> {
return <String, String>{ return <String, String>{
'apiUrl': state.apiUrl ?? '', 'apiUrl': state.apiUrl ?? '',
'securityToken': state.securityToken ?? '', 'securityToken': state.securityToken ?? '',
'interfaceType': state.interfaceType.toString(),
}; };
} }
} }
...@@ -5,19 +5,23 @@ class SettingsState extends Equatable { ...@@ -5,19 +5,23 @@ class SettingsState extends Equatable {
const SettingsState({ const SettingsState({
this.apiUrl, this.apiUrl,
this.securityToken, this.securityToken,
this.interfaceType,
}); });
final String? apiUrl; final String? apiUrl;
final String? securityToken; final String? securityToken;
final InterfaceType? interfaceType;
@override @override
List<String?> get props => <String?>[ List<String?> get props => <String?>[
apiUrl, apiUrl,
securityToken, securityToken,
interfaceType.toString(),
]; ];
Map<String, String?> get values => <String, String?>{ Map<String, String?> get values => <String, String?>{
'apiUrl': apiUrl, 'apiUrl': apiUrl,
'securityToken': securityToken, 'securityToken': securityToken,
'interfaceType': interfaceType.toString(),
}; };
} }
...@@ -2,11 +2,15 @@ import 'dart:io'; ...@@ -2,11 +2,15 @@ import 'dart:io';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
import 'package:hydrated_bloc/hydrated_bloc.dart'; import 'package:hydrated_bloc/hydrated_bloc.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:random/config/theme.dart'; import 'package:random/config/theme.dart';
import 'package:random/cubit/bottom_nav_cubit.dart';
import 'package:random/cubit/data_cubit.dart';
import 'package:random/cubit/settings_cubit.dart';
import 'package:random/ui/skeleton.dart'; import 'package:random/ui/skeleton.dart';
void main() async { void main() async {
...@@ -38,7 +42,13 @@ class MyApp extends StatelessWidget { ...@@ -38,7 +42,13 @@ class MyApp extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MaterialApp( return MultiBlocProvider(
providers: [
BlocProvider<SettingsCubit>(create: (context) => SettingsCubit()),
BlocProvider<BottomNavCubit>(create: (context) => BottomNavCubit()),
BlocProvider<DataCubit>(create: (context) => DataCubit()),
],
child: MaterialApp(
title: 'Random application', title: 'Random application',
theme: appTheme, theme: appTheme,
home: SkeletonScreen(), home: SkeletonScreen(),
...@@ -46,6 +56,7 @@ class MyApp extends StatelessWidget { ...@@ -46,6 +56,7 @@ class MyApp extends StatelessWidget {
supportedLocales: context.supportedLocales, supportedLocales: context.supportedLocales,
locale: context.locale, locale: context.locale,
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
),
); );
} }
} }
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
enum InterfaceType {
basic,
expert,
}
class InterfaceTypes {
static List<Widget> selectWidgets = <Widget>[
Text('interface_type_basic').tr(),
Text('interface_type_expert').tr(),
];
}
...@@ -5,7 +5,9 @@ import 'package:flutter/material.dart'; ...@@ -5,7 +5,9 @@ import 'package:flutter/material.dart';
import 'package:random/config/app_colors.dart'; import 'package:random/config/app_colors.dart';
class GraphPainter extends CustomPainter { class GraphPainter extends CustomPainter {
const GraphPainter(); const GraphPainter({required this.linesCount});
final int linesCount;
double random(double max) { double random(double max) {
return 0.05 * max + Random().nextDouble() * max * 0.9; return 0.05 * max + Random().nextDouble() * max * 0.9;
...@@ -40,8 +42,7 @@ class GraphPainter extends CustomPainter { ...@@ -40,8 +42,7 @@ class GraphPainter extends CustomPainter {
Paint paintLine = Paint(); Paint paintLine = Paint();
paintLine.style = PaintingStyle.fill; paintLine.style = PaintingStyle.fill;
int linesCount = 20; for (int i = 0; i < this.linesCount; i++) {
for (int i = 0; i < linesCount; i++) {
paintLine.color = getRandomColor(); paintLine.color = getRandomColor();
paintLine.strokeWidth = Random().nextDouble() * 4 + 2; paintLine.strokeWidth = Random().nextDouble() * 4 + 2;
......
...@@ -21,7 +21,10 @@ class DemoPage extends StatelessWidget { ...@@ -21,7 +21,10 @@ class DemoPage extends StatelessWidget {
SizedBox(height: 8), SizedBox(height: 8),
AppHeader(text: 'TOP'), AppHeader(text: 'TOP'),
SizedBox(height: 20), SizedBox(height: 20),
persistedCounterBlock(), persistedCounterBlock(BlocProvider.of<DataCubit>(context)),
SizedBox(height: 20),
testBlocConsumer(),
testBlocBuilder(),
SizedBox(height: 20), SizedBox(height: 20),
fakeApiCall(), fakeApiCall(),
SizedBox(height: 20), SizedBox(height: 20),
...@@ -31,17 +34,7 @@ class DemoPage extends StatelessWidget { ...@@ -31,17 +34,7 @@ class DemoPage extends StatelessWidget {
); );
} }
Widget persistedCounterBlock() { Widget persistedCounterBlock(DataCubit dataCubit) {
return BlocProvider<DataCubit>(
create: (BuildContext context) => DataCubit(),
child: BlocBuilder<DataCubit, DataState>(
builder: (BuildContext context, DataState state) {
void updateCounter(int delta) {
BlocProvider.of<DataCubit>(context).getData(
DataState(counter: (state.counter ?? 0) + delta),
);
}
return Row( return Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
...@@ -49,42 +42,60 @@ class DemoPage extends StatelessWidget { ...@@ -49,42 +42,60 @@ class DemoPage extends StatelessWidget {
IconButton( IconButton(
icon: Icon(UniconsSolid.arrow_circle_down), icon: Icon(UniconsSolid.arrow_circle_down),
color: appTheme.primaryColor, color: appTheme.primaryColor,
onPressed: () => updateCounter(-1), onPressed: () => dataCubit.updateCounter(-1),
),
Padding(
padding: EdgeInsets.all(10),
child: Text(state.counter.toString()),
), ),
testBlocConsumer(),
IconButton( IconButton(
icon: Icon(UniconsSolid.arrow_circle_up), icon: Icon(UniconsSolid.arrow_circle_up),
color: appTheme.primaryColor, color: appTheme.primaryColor,
onPressed: () => updateCounter(1), onPressed: () => dataCubit.updateCounter(1),
), ),
], ],
); );
},
),
);
} }
Widget fakeApiCall() { Widget fakeApiCall() {
return BlocProvider<SettingsCubit>( return BlocBuilder<SettingsCubit, SettingsState>(
create: (BuildContext context) => SettingsCubit(), builder: (context, settingsSate) {
child: BlocBuilder<SettingsCubit, SettingsState>(
builder: (BuildContext context, SettingsState state) {
SettingsCubit settings = BlocProvider.of<SettingsCubit>(context);
return Column( return Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
Text('apiUrl: ' + settings.getSetting('apiUrl')), Text('apiUrl: ' + settingsSate.apiUrl.toString()),
Text('securityToken: ' + settings.getSetting('securityToken')), Text('securityToken: ' + (settingsSate.securityToken.toString())),
Text('unknown: ' + settings.getSetting('unknown', 'undefined')), Text('interfaceType: ' + settingsSate.interfaceType.toString()),
], ],
); );
}, },
), );
}
Widget testBlocConsumer() {
return BlocConsumer<DataCubit, DataState>(
listener: (context, dataState) {
// do stuff here based on state
},
builder: (context, dataState) {
// return widget here based on state
return Text('BlocConsumer / ' + dataState.toString());
},
);
}
Widget testBlocListener() {
return BlocListener<DataCubit, DataState>(
listener: (context, dataState) {
// do stuff here based on state
},
);
}
Widget testBlocBuilder() {
return BlocBuilder<DataCubit, DataState>(
builder: (context, dataState) {
// return widget here based on state
return Text('BlocBuilder / ' + dataState.toString());
},
); );
} }
} }
...@@ -2,9 +2,16 @@ import 'package:flutter/material.dart'; ...@@ -2,9 +2,16 @@ import 'package:flutter/material.dart';
import 'package:random/ui/painters/graph_painter.dart'; import 'package:random/ui/painters/graph_painter.dart';
class GraphPage extends StatelessWidget { class GraphPage extends StatefulWidget {
const GraphPage({super.key}); const GraphPage({super.key});
@override
State<GraphPage> createState() => _GraphPageState();
}
class _GraphPageState extends State<GraphPage> {
double _currentSliderValue = 20;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
double boardWidth = MediaQuery.of(context).size.width; double boardWidth = MediaQuery.of(context).size.width;
...@@ -35,11 +42,22 @@ class GraphPage extends StatelessWidget { ...@@ -35,11 +42,22 @@ class GraphPage extends StatelessWidget {
child: CustomPaint( child: CustomPaint(
size: Size(boardWidth, boardWidth), size: Size(boardWidth, boardWidth),
willChange: false, willChange: false,
painter: GraphPainter(), painter: GraphPainter(linesCount: _currentSliderValue.toInt()),
isComplex: true, ),
), ),
), ),
), ),
Slider(
value: _currentSliderValue,
min: 10,
max: 50,
divisions: 5,
label: _currentSliderValue.round().toString(),
onChanged: (double value) {
setState(() {
_currentSliderValue = value;
});
},
), ),
], ],
), ),
......
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.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/bottom_nav_cubit.dart';
import 'package:random/cubit/settings_cubit.dart';
import 'package:random/ui/screens/about_page.dart'; import 'package:random/ui/screens/about_page.dart';
import 'package:random/ui/screens/demo_page.dart'; import 'package:random/ui/screens/demo_page.dart';
import 'package:random/ui/screens/graph_page.dart'; import 'package:random/ui/screens/graph_page.dart';
import 'package:random/ui/screens/settings_page.dart'; import 'package:random/ui/screens/settings_page.dart';
import 'package:random/ui/widgets/app_bar.dart'; import 'package:random/ui/widgets/app_bar.dart';
import 'package:random/ui/widgets/bottom_nav_bar.dart'; import 'package:random/ui/widgets/bottom_nav_bar.dart';
import 'package:random/ui/widgets/debug_bloc.dart';
class SkeletonScreen extends StatefulWidget { class SkeletonScreen extends StatefulWidget {
const SkeletonScreen({super.key}); const SkeletonScreen({super.key});
...@@ -28,48 +27,28 @@ class _SkeletonScreenState extends State<SkeletonScreen> { ...@@ -28,48 +27,28 @@ class _SkeletonScreenState extends State<SkeletonScreen> {
AboutPage(), AboutPage(),
]; ];
String debug = ''; return Scaffold(
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, extendBodyBehindAppBar: false,
appBar: StandardAppBar(), appBar: StandardAppBar(),
body: BlocBuilder<BottomNavCubit, int>( body: Swiper(
builder: (BuildContext context, int state) { itemCount: BlocProvider.of<BottomNavCubit>(context).pagesCount,
return AnimatedSwitcher( itemBuilder: (BuildContext context, int index) {
duration: const Duration(milliseconds: 300), return pageNavigation.elementAt(index);
child: Stack( },
children: [ pagination: SwiperPagination(
pageNavigation.elementAt(state), builder: SwiperCustomPagination(
debug != '' ? DebugBloc(content: debug) : SizedBox(), 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,
); );
} }
} }
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:unicons/unicons.dart';
import 'package:random/ui/widgets/header_app.dart'; import 'package:random/ui/widgets/header_app.dart';
...@@ -9,12 +8,9 @@ class StandardAppBar extends StatelessWidget implements PreferredSizeWidget { ...@@ -9,12 +8,9 @@ class StandardAppBar extends StatelessWidget implements PreferredSizeWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return AppBar( return AppBar(
title: const AppHeader(text: 'app_name'), title: AppHeader(text: 'app_name'),
actions: [ actions: [
IconButton( //
onPressed: () {},
icon: const Icon(UniconsSolid.refresh),
),
], ],
); );
} }
......
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_swipe/flutter_swipe.dart';
import 'package:unicons/unicons.dart'; import 'package:unicons/unicons.dart';
import 'package:random/cubit/bottom_nav_cubit.dart'; import 'package:random/cubit/bottom_nav_cubit.dart';
class BottomNavBar extends StatelessWidget { class BottomNavBar extends StatelessWidget {
const BottomNavBar({super.key}); const BottomNavBar({super.key, required this.swipeController});
final SwiperController swipeController;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Card( return Card(
margin: const EdgeInsets.only(top: 1, right: 4, left: 4), margin: const EdgeInsets.only(
top: 1,
right: 0,
left: 0,
),
elevation: 4, elevation: 4,
shadowColor: Theme.of(context).colorScheme.shadow, shadowColor: Theme.of(context).colorScheme.shadow,
color: Theme.of(context).colorScheme.surfaceVariant, color: Theme.of(context).colorScheme.surfaceVariant,
...@@ -25,7 +32,10 @@ class BottomNavBar extends StatelessWidget { ...@@ -25,7 +32,10 @@ class BottomNavBar extends StatelessWidget {
builder: (BuildContext context, int state) { builder: (BuildContext context, int state) {
return BottomNavigationBar( return BottomNavigationBar(
currentIndex: state, currentIndex: state,
onTap: (int index) => context.read<BottomNavCubit>().updateIndex(index), onTap: (int index) {
context.read<BottomNavCubit>().updateIndex(index);
swipeController.move(index);
},
type: BottomNavigationBarType.fixed, type: BottomNavigationBarType.fixed,
elevation: 0, elevation: 0,
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
......
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:random/cubit/data_cubit.dart';
import 'package:random/cubit/settings_cubit.dart';
import 'package:random/models/interface_type.dart';
class AppHeader extends StatelessWidget { class AppHeader extends StatelessWidget {
const AppHeader({super.key, required this.text}); const AppHeader({super.key, required this.text});
...@@ -8,10 +13,38 @@ class AppHeader extends StatelessWidget { ...@@ -8,10 +13,38 @@ class AppHeader extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Text( return Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
tr(text), tr(text),
textAlign: TextAlign.start, textAlign: TextAlign.start,
style: Theme.of(context).textTheme.headlineMedium!.apply(fontWeightDelta: 2), style: Theme.of(context).textTheme.headlineMedium!.apply(fontWeightDelta: 2),
),
SizedBox(width: 2),
expertInterfaceIndicator(),
SizedBox(width: 2),
dataCounterIndicator(),
],
);
}
Widget expertInterfaceIndicator() {
return BlocBuilder<SettingsCubit, SettingsState>(
builder: (BuildContext context, SettingsState settingsState) {
bool isExpert = settingsState.interfaceType == InterfaceType.expert;
return Text(isExpert ? '⭐' : '');
},
);
}
Widget dataCounterIndicator() {
return BlocBuilder<DataCubit, DataState>(
builder: (context, dataState) {
return Text('(' + dataState.counter.toString() + ')');
},
); );
} }
} }
...@@ -3,8 +3,9 @@ import 'package:flutter/material.dart'; ...@@ -3,8 +3,9 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:unicons/unicons.dart'; import 'package:unicons/unicons.dart';
import 'package:random/cubit/bottom_nav_cubit.dart';
import 'package:random/cubit/settings_cubit.dart'; import 'package:random/cubit/settings_cubit.dart';
import 'package:random/config/theme.dart';
import 'package:random/models/interface_type.dart';
class SettingsForm extends StatefulWidget { class SettingsForm extends StatefulWidget {
const SettingsForm({super.key}); const SettingsForm({super.key});
...@@ -16,6 +17,7 @@ class SettingsForm extends StatefulWidget { ...@@ -16,6 +17,7 @@ class SettingsForm extends StatefulWidget {
class _SettingsFormState extends State<SettingsForm> { class _SettingsFormState extends State<SettingsForm> {
final apiUrlController = TextEditingController(); final apiUrlController = TextEditingController();
final securityTokenController = TextEditingController(); final securityTokenController = TextEditingController();
final List<Widget> interfaceTypesWidgets = InterfaceTypes.selectWidgets;
@override @override
void dispose() { void dispose() {
...@@ -24,20 +26,27 @@ class _SettingsFormState extends State<SettingsForm> { ...@@ -24,20 +26,27 @@ class _SettingsFormState extends State<SettingsForm> {
super.dispose(); super.dispose();
} }
List<bool> _selectedInterfaceType = <bool>[];
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SettingsCubit settings = BlocProvider.of<SettingsCubit>(context); SettingsCubit settings = BlocProvider.of<SettingsCubit>(context);
apiUrlController.text = settings.getSetting('apiUrl'); apiUrlController.text = settings.getApiUrl();
securityTokenController.text = settings.getSetting('securityToken'); securityTokenController.text = settings.getSecurityToken();
if (_selectedInterfaceType.length != 2) {
_selectedInterfaceType = <bool>[
settings.getInterfaceType() == InterfaceType.basic,
settings.getInterfaceType() == InterfaceType.expert,
];
}
void saveSettings() { void saveSettings() {
BlocProvider.of<SettingsCubit>(context).setValues( BlocProvider.of<SettingsCubit>(context).setValues(
apiUrl: apiUrlController.text, apiUrl: apiUrlController.text,
securityToken: securityTokenController.text, securityToken: securityTokenController.text,
interfaceType: _selectedInterfaceType[0] ? InterfaceType.basic : InterfaceType.expert,
); );
BlocProvider.of<BottomNavCubit>(context).getDemoPage();
} }
return Column( return Column(
...@@ -61,6 +70,27 @@ class _SettingsFormState extends State<SettingsForm> { ...@@ -61,6 +70,27 @@ class _SettingsFormState extends State<SettingsForm> {
), ),
), ),
SizedBox(height: 16), SizedBox(height: 16),
Text('settings_label_interface_type').tr(),
ToggleButtons(
direction: Axis.horizontal,
onPressed: (int index) {
setState(() {
_selectedInterfaceType = index == 0 ? [true, false] : [false, true];
});
},
borderRadius: const BorderRadius.all(Radius.circular(8)),
selectedBorderColor: appTheme.primaryColor,
selectedColor: appTheme.colorScheme.onSecondary,
fillColor: appTheme.colorScheme.secondary,
color: appTheme.primaryColor,
constraints: const BoxConstraints(
minHeight: 40.0,
minWidth: 80.0,
),
isSelected: _selectedInterfaceType,
children: interfaceTypesWidgets,
),
SizedBox(height: 20),
ElevatedButton( ElevatedButton(
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
......
...@@ -45,10 +45,10 @@ packages: ...@@ -45,10 +45,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: collection name: collection
sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.17.2" version: "1.18.0"
crypto: crypto:
dependency: transitive dependency: transitive
description: description:
...@@ -115,6 +115,14 @@ packages: ...@@ -115,6 +115,14 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" 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: flutter_web_plugins:
dependency: transitive dependency: transitive
description: flutter description: flutter
...@@ -172,10 +180,10 @@ packages: ...@@ -172,10 +180,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: meta name: meta
sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.9.1" version: "1.10.0"
nested: nested:
dependency: transitive dependency: transitive
description: description:
...@@ -188,10 +196,10 @@ packages: ...@@ -188,10 +196,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: package_info_plus name: package_info_plus
sha256: "7e76fad405b3e4016cd39d08f455a4eb5199723cf594cd1b8916d47140d93017" sha256: "88bc797f44a94814f2213db1c9bd5badebafdfb8290ca9f78d4b9ee2a3db4d79"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.2.0" version: "5.0.1"
package_info_plus_platform_interface: package_info_plus_platform_interface:
dependency: transitive dependency: transitive
description: description:
...@@ -268,18 +276,18 @@ packages: ...@@ -268,18 +276,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: plugin_platform_interface name: plugin_platform_interface
sha256: da3fdfeccc4d4ff2da8f8c556704c08f912542c5fb3cf2233ed75372384a034d sha256: f4f88d4a900933e7267e2b353594774fc0d07fb072b47eedcd5b54e1ea3269f8
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.6" version: "2.1.7"
provider: provider:
dependency: transitive dependency: transitive
description: description:
name: provider name: provider
sha256: cdbe7530b12ecd9eb455bdaa2fcb8d4dad22e80b8afb4798b41479d5ce26847f sha256: "9a96a0a19b594dbc5bf0f1f27d2bc67d5f95957359b461cd9feb44ed6ae75096"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.0.5" version: "6.1.1"
shared_preferences: shared_preferences:
dependency: transitive dependency: transitive
description: description:
...@@ -324,10 +332,10 @@ packages: ...@@ -324,10 +332,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: shared_preferences_web name: shared_preferences_web
sha256: d762709c2bbe80626ecc819143013cc820fa49ca5e363620ee20a8b15a3e3daf sha256: "7b15ffb9387ea3e237bb7a66b8a23d2147663d391cafc5c8f37b2e7b4bde5d21"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.2.1" version: "2.2.2"
shared_preferences_windows: shared_preferences_windows:
dependency: transitive dependency: transitive
description: description:
...@@ -401,18 +409,18 @@ packages: ...@@ -401,18 +409,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: web name: web
sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.1.4-beta" version: "0.3.0"
win32: win32:
dependency: transitive dependency: transitive
description: description:
name: win32 name: win32
sha256: "350a11abd2d1d97e0cc7a28a81b781c08002aa2864d9e3f192ca0ffa18b06ed3" sha256: "7c99c0e1e2fa190b48d25c81ca5e42036d5cac81430ef249027d97b0935c553f"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "5.0.9" version: "5.1.0"
xdg_directories: xdg_directories:
dependency: transitive dependency: transitive
description: description:
...@@ -422,5 +430,5 @@ packages: ...@@ -422,5 +430,5 @@ packages:
source: hosted source: hosted
version: "1.0.3" version: "1.0.3"
sdks: sdks:
dart: ">=3.1.0-185.0.dev <4.0.0" dart: ">=3.2.0 <4.0.0"
flutter: ">=3.7.0" flutter: ">=3.16.0"
...@@ -3,7 +3,7 @@ description: A random application, for testing purpose only. ...@@ -3,7 +3,7 @@ description: A random application, for testing purpose only.
publish_to: 'none' publish_to: 'none'
version: 1.0.32+33 version: 1.0.36+37
environment: environment:
sdk: '^3.0.0' sdk: '^3.0.0'
...@@ -18,7 +18,8 @@ dependencies: ...@@ -18,7 +18,8 @@ dependencies:
path_provider: ^2.0.11 path_provider: ^2.0.11
hydrated_bloc: ^9.0.0 hydrated_bloc: ^9.0.0
unicons: ^2.1.1 unicons: ^2.1.1
package_info_plus: ^4.2.0 package_info_plus: ^5.0.1
flutter_swipe: ^1.0.1
flutter: flutter:
uses-material-design: false uses-material-design: false
......