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

Add settings page (username, security token)

parent ae63e6b1
No related branches found
No related tags found
1 merge request!37Resolve "Add settings page with security token"
Pipeline #4659 passed
This commit is part of merge request !37. Comments created here will be created in the context of that merge request.
org.gradle.jvmargs=-Xmx1536M org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true android.useAndroidX=true
android.enableJetifier=true android.enableJetifier=true
app.versionName=0.0.34 app.versionName=0.0.35
app.versionCode=34 app.versionCode=35
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
"bottom_nav_home": "Home", "bottom_nav_home": "Home",
"bottom_nav_discoveries": "Discoveries", "bottom_nav_discoveries": "Discoveries",
"bottom_nav_repartition": "Statistics", "bottom_nav_repartition": "Statistics",
"bottom_nav_settings": "Settings",
"global_statistics": "Global statistics", "global_statistics": "Global statistics",
"statistics_total_scrobbles_count": "Total scrobbles count: {count}", "statistics_total_scrobbles_count": "Total scrobbles count: {count}",
...@@ -23,6 +24,11 @@ ...@@ -23,6 +24,11 @@
"top_artists_title": "Top artists ({daysCount} days)", "top_artists_title": "Top artists ({daysCount} days)",
"settings_title": "Settings",
"settings_label_username": "Username: ",
"settings_label_security_token": "Security token: ",
"settings_button_save": "Save",
"MON": "MON", "MON": "MON",
"TUE": "TUE", "TUE": "TUE",
"WED": "WED", "WED": "WED",
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
"bottom_nav_home": "Accueil", "bottom_nav_home": "Accueil",
"bottom_nav_discoveries": "Découvertes", "bottom_nav_discoveries": "Découvertes",
"bottom_nav_repartition": "Statistiques", "bottom_nav_repartition": "Statistiques",
"bottom_nav_settings": "Paramètres",
"global_statistics": "Statistiques globales d'écoutes", "global_statistics": "Statistiques globales d'écoutes",
"statistics_total_scrobbles_count": "Nombre total d'écoutes : {count}", "statistics_total_scrobbles_count": "Nombre total d'écoutes : {count}",
...@@ -23,6 +24,11 @@ ...@@ -23,6 +24,11 @@
"top_artists_title": "Top artistes ({daysCount} jours)", "top_artists_title": "Top artistes ({daysCount} jours)",
"settings_title": "Paramètres",
"settings_label_username": "Utilisateur : ",
"settings_label_security_token": "Jeton de sécurité : ",
"settings_button_save": "Enregistrer",
"MON": "LUN", "MON": "LUN",
"TUE": "MAR", "TUE": "MAR",
"WED": "MER", "WED": "MER",
......
Add settings page (username, security token).
Ajout d'une page de paramètres (nom d'utilisateur, jeton de sécurité).
...@@ -3,7 +3,7 @@ import 'package:hydrated_bloc/hydrated_bloc.dart'; ...@@ -3,7 +3,7 @@ import 'package:hydrated_bloc/hydrated_bloc.dart';
class BottomNavCubit extends HydratedCubit<int> { class BottomNavCubit extends HydratedCubit<int> {
BottomNavCubit() : super(0); BottomNavCubit() : super(0);
int pagesCount = 3; int pagesCount = 4;
void updateIndex(int index) { void updateIndex(int index) {
if (isIndexAllowed(index)) { if (isIndexAllowed(index)) {
......
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:hydrated_bloc/hydrated_bloc.dart';
part 'settings_state.dart';
class SettingsCubit extends HydratedCubit<SettingsState> {
SettingsCubit() : super(const SettingsState());
String getUsername() {
return state.username ?? '';
}
String getSecurityToken() {
return state.securityToken ?? '';
}
void setValues({
String? username,
String? securityToken,
}) {
emit(SettingsState(
username: username != null ? username : state.username,
securityToken: securityToken != null ? securityToken : state.securityToken,
));
}
@override
SettingsState? fromJson(Map<String, dynamic> json) {
String username = json['username'] as String;
String securityToken = json['securityToken'] as String;
return SettingsState(
username: username,
securityToken: securityToken,
);
}
@override
Map<String, String>? toJson(SettingsState state) {
return <String, String>{
'username': state.username ?? '',
'securityToken': state.securityToken ?? '',
};
}
}
part of 'settings_cubit.dart';
@immutable
class SettingsState extends Equatable {
const SettingsState({
this.username,
this.securityToken,
});
final String? username;
final String? securityToken;
@override
List<String?> get props => <String?>[
username,
securityToken,
];
Map<String, String?> get values => <String, String?>{
'username': username,
'securityToken': securityToken,
};
}
...@@ -16,6 +16,7 @@ import 'package:scrobbles/cubit/data_statistics_global_cubit.dart'; ...@@ -16,6 +16,7 @@ import 'package:scrobbles/cubit/data_statistics_global_cubit.dart';
import 'package:scrobbles/cubit/data_statistics_recent_cubit.dart'; import 'package:scrobbles/cubit/data_statistics_recent_cubit.dart';
import 'package:scrobbles/cubit/data_timeline_cubit.dart'; import 'package:scrobbles/cubit/data_timeline_cubit.dart';
import 'package:scrobbles/cubit/data_top_artists_cubit.dart'; import 'package:scrobbles/cubit/data_top_artists_cubit.dart';
import 'package:scrobbles/cubit/settings_cubit.dart';
import 'package:scrobbles/ui/skeleton.dart'; import 'package:scrobbles/ui/skeleton.dart';
void main() async { void main() async {
...@@ -49,6 +50,7 @@ class MyApp extends StatelessWidget { ...@@ -49,6 +50,7 @@ class MyApp extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MultiBlocProvider( return MultiBlocProvider(
providers: [ providers: [
BlocProvider<SettingsCubit>(create: (context) => SettingsCubit()),
BlocProvider<BottomNavCubit>(create: (context) => BottomNavCubit()), BlocProvider<BottomNavCubit>(create: (context) => BottomNavCubit()),
BlocProvider<DataCountsByDayCubit>(create: (context) => DataCountsByDayCubit()), BlocProvider<DataCountsByDayCubit>(create: (context) => DataCountsByDayCubit()),
BlocProvider<DataCountsByHourCubit>(create: (context) => DataCountsByHourCubit()), BlocProvider<DataCountsByHourCubit>(create: (context) => DataCountsByHourCubit()),
......
import 'package:flutter/material.dart';
import 'package:scrobbles/ui/widgets/header_app.dart';
import 'package:scrobbles/ui/widgets/settings_form.dart';
class ScreenSettings extends StatelessWidget {
const ScreenSettings({super.key});
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
SizedBox(height: 8),
AppHeader(text: 'settings_title'),
SizedBox(height: 8),
SettingsForm(),
],
);
}
}
...@@ -5,6 +5,7 @@ import 'package:flutter_swipe/flutter_swipe.dart'; ...@@ -5,6 +5,7 @@ import 'package:flutter_swipe/flutter_swipe.dart';
import 'package:scrobbles/cubit/bottom_nav_cubit.dart'; import 'package:scrobbles/cubit/bottom_nav_cubit.dart';
import 'package:scrobbles/ui/screens/discoveries.dart'; import 'package:scrobbles/ui/screens/discoveries.dart';
import 'package:scrobbles/ui/screens/home.dart'; import 'package:scrobbles/ui/screens/home.dart';
import 'package:scrobbles/ui/screens/settings.dart';
import 'package:scrobbles/ui/screens/statistics.dart'; import 'package:scrobbles/ui/screens/statistics.dart';
import 'package:scrobbles/ui/widgets/app_bar.dart'; import 'package:scrobbles/ui/widgets/app_bar.dart';
import 'package:scrobbles/ui/widgets/bottom_nav_bar.dart'; import 'package:scrobbles/ui/widgets/bottom_nav_bar.dart';
...@@ -23,6 +24,7 @@ class _SkeletonScreenState extends State<SkeletonScreen> { ...@@ -23,6 +24,7 @@ class _SkeletonScreenState extends State<SkeletonScreen> {
const ScreenHome(), const ScreenHome(),
const ScreenDiscoveries(), const ScreenDiscoveries(),
const ScreenStatistics(), const ScreenStatistics(),
const ScreenSettings(),
]; ];
return Scaffold( return Scaffold(
......
...@@ -54,6 +54,10 @@ class BottomNavBar extends StatelessWidget { ...@@ -54,6 +54,10 @@ class BottomNavBar extends StatelessWidget {
icon: const Icon(Ionicons.bar_chart_outline), icon: const Icon(Ionicons.bar_chart_outline),
label: tr('bottom_nav_repartition'), label: tr('bottom_nav_repartition'),
), ),
BottomNavigationBarItem(
icon: const Icon(Ionicons.settings_outline),
label: tr('bottom_nav_settings'),
),
], ],
); );
}, },
......
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:unicons/unicons.dart';
import 'package:scrobbles/cubit/settings_cubit.dart';
class SettingsForm extends StatefulWidget {
const SettingsForm({super.key});
@override
State<SettingsForm> createState() => _SettingsFormState();
}
class _SettingsFormState extends State<SettingsForm> {
final usernameController = TextEditingController();
final securityTokenController = TextEditingController();
@override
void dispose() {
usernameController.dispose();
securityTokenController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
SettingsCubit settings = BlocProvider.of<SettingsCubit>(context);
usernameController.text = settings.getUsername();
securityTokenController.text = settings.getSecurityToken();
void saveSettings() {
BlocProvider.of<SettingsCubit>(context).setValues(
username: usernameController.text,
securityToken: securityTokenController.text,
);
}
return Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Text('settings_label_username').tr(),
TextFormField(
controller: usernameController,
decoration: InputDecoration(
border: UnderlineInputBorder(),
),
),
SizedBox(height: 16),
Text('settings_label_security_token').tr(),
TextFormField(
controller: securityTokenController,
decoration: InputDecoration(
border: UnderlineInputBorder(),
),
),
SizedBox(height: 20),
ElevatedButton(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Icon(UniconsLine.save),
SizedBox(width: 8),
Text('settings_button_save').tr(),
],
),
onPressed: () => saveSettings(),
),
],
);
}
}
...@@ -3,7 +3,7 @@ description: Display scrobbles data and charts ...@@ -3,7 +3,7 @@ description: Display scrobbles data and charts
publish_to: 'none' publish_to: 'none'
version: 0.0.34+34 version: 0.0.35+35
environment: environment:
sdk: '^3.0.0' sdk: '^3.0.0'
......
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