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

Target

Select target project
  • android/random
1 result
Select Git revision
Show changes
Commits on Source (2)
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.33
app.versionCode=33 app.versionCode=34
...@@ -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",
......
...@@ -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(),
}; };
} }
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(),
];
}
...@@ -78,9 +78,10 @@ class DemoPage extends StatelessWidget { ...@@ -78,9 +78,10 @@ class DemoPage extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
Text('apiUrl: ' + settings.getSetting('apiUrl')), Text('apiUrl: ' + settings.getApiUrl()),
Text('securityToken: ' + settings.getSetting('securityToken')), Text('securityToken: ' + settings.getSecurityToken()),
Text('unknown: ' + settings.getSetting('unknown', 'undefined')), Text('interfaceType: ' + settings.getInterfaceType().toString()),
Text('unknown: ' + settings.getSetting('unknown', 'undefined').toString()),
], ],
); );
}, },
......
...@@ -21,6 +21,8 @@ class SkeletonScreen extends StatefulWidget { ...@@ -21,6 +21,8 @@ class SkeletonScreen extends StatefulWidget {
class _SkeletonScreenState extends State<SkeletonScreen> { class _SkeletonScreenState extends State<SkeletonScreen> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
print('SkeletonScreen - build');
const List<Widget> pageNavigation = <Widget>[ const List<Widget> pageNavigation = <Widget>[
DemoPage(), DemoPage(),
GraphPage(), GraphPage(),
......
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';
...@@ -8,13 +7,12 @@ class StandardAppBar extends StatelessWidget implements PreferredSizeWidget { ...@@ -8,13 +7,12 @@ class StandardAppBar extends StatelessWidget implements PreferredSizeWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
print('StandardAppBar - build');
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: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 +12,24 @@ class AppHeader extends StatelessWidget { ...@@ -8,10 +12,24 @@ class AppHeader extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
print('AppHeader - build (' + this.text + ')');
return BlocProvider<SettingsCubit>(
create: (BuildContext context) => SettingsCubit(),
child: BlocBuilder<SettingsCubit, SettingsState>(
builder: (BuildContext context, SettingsState state) {
SettingsCubit settings = BlocProvider.of<SettingsCubit>(context);
bool isExpert = settings.getInterfaceType() == InterfaceType.expert;
String titleSuffix = isExpert ? ' ⭐' : '';
return Text( return Text(
tr(text), tr(text) + titleSuffix,
textAlign: TextAlign.start, textAlign: TextAlign.start,
style: Theme.of(context).textTheme.headlineMedium!.apply(fontWeightDelta: 2), style: Theme.of(context).textTheme.headlineMedium!.apply(fontWeightDelta: 2),
); );
},
),
);
} }
} }
...@@ -5,6 +5,8 @@ import 'package:unicons/unicons.dart'; ...@@ -5,6 +5,8 @@ import 'package:unicons/unicons.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/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 +18,7 @@ class SettingsForm extends StatefulWidget { ...@@ -16,6 +18,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,17 +27,26 @@ class _SettingsFormState extends State<SettingsForm> { ...@@ -24,17 +27,26 @@ 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(); BlocProvider.of<BottomNavCubit>(context).getDemoPage();
...@@ -61,6 +73,27 @@ class _SettingsFormState extends State<SettingsForm> { ...@@ -61,6 +73,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:
...@@ -172,10 +172,10 @@ packages: ...@@ -172,10 +172,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 +188,10 @@ packages: ...@@ -188,10 +188,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 +268,18 @@ packages: ...@@ -268,18 +268,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 +324,10 @@ packages: ...@@ -324,10 +324,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 +401,18 @@ packages: ...@@ -401,18 +401,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 +422,5 @@ packages: ...@@ -422,5 +422,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.33+34
environment: environment:
sdk: '^3.0.0' sdk: '^3.0.0'
...@@ -18,7 +18,7 @@ dependencies: ...@@ -18,7 +18,7 @@ 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: flutter:
uses-material-design: false uses-material-design: false
......