Implemented settings, new scan, enhanced UI/UX

This commit is contained in:
Dennis Nemec
2025-11-04 16:52:39 +01:00
parent b19a6e1cd4
commit 7ea9108f62
79 changed files with 3306 additions and 566 deletions

View File

@ -0,0 +1,40 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:hl_lieferservice/feature/settings/bloc/settings_event.dart';
import 'package:hl_lieferservice/feature/settings/bloc/settings_state.dart';
import 'package:hl_lieferservice/feature/settings/model/settings.dart';
import 'package:hl_lieferservice/feature/settings/repository/settings_repository.dart';
class SettingsBloc extends Bloc<SettingsEvent, SettingsState> {
SettingsRepository repository;
SettingsBloc()
: repository = SettingsRepository(),
super(AppSettingsInitial()) {
on<LoadSettings>(_load);
on<UpdateSettings>(_update);
}
void _load(LoadSettings event, Emitter<SettingsState> emit) async {
try {
Settings settings = await repository.getSettings();
debugPrint("use ${settings.useHardwareScanner}");
emit(AppSettingsLoaded(settings: settings));
} catch (e, st) {
debugPrint("Failed to load settings: $e}");
debugPrint("Stacktrace: ${st.toString()}");
emit(AppSettingsFailed());
}
}
void _update(UpdateSettings event, Emitter<SettingsState> emit) {
try {
repository.saveSettings(event.settings);
emit(AppSettingsLoaded(settings: event.settings.copyWith()));
} catch (e, st) {
debugPrint("Failed to save settings: $e}");
debugPrint("Stacktrace: ${st.toString()}");
emit(AppSettingsFailed());
}
}
}

View File

@ -0,0 +1,10 @@
import 'package:hl_lieferservice/feature/settings/model/settings.dart';
abstract class SettingsEvent {}
class UpdateSettings extends SettingsEvent {
UpdateSettings({required this.settings});
Settings settings;
}
class LoadSettings extends SettingsEvent {}

View File

@ -0,0 +1,11 @@
import 'package:hl_lieferservice/feature/settings/model/settings.dart';
abstract class SettingsState {}
class AppSettingsInitial extends SettingsState {}
class AppSettingsFailed extends SettingsState {}
class AppSettingsLoaded extends SettingsState {
AppSettingsLoaded({required this.settings});
Settings settings;
}

View File

@ -0,0 +1,10 @@
class Settings {
Settings({required this.useHardwareScanner});
bool useHardwareScanner;
Settings copyWith({bool? useHardwareScanner}) {
return Settings(
useHardwareScanner: useHardwareScanner ?? this.useHardwareScanner);
}
}

View File

@ -0,0 +1,132 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:hl_lieferservice/feature/settings/bloc/settings_bloc.dart';
import 'package:hl_lieferservice/feature/settings/bloc/settings_event.dart';
import 'package:hl_lieferservice/feature/settings/bloc/settings_state.dart';
import 'package:hl_lieferservice/feature/settings/model/settings.dart';
class SettingsPage extends StatefulWidget {
const SettingsPage({super.key});
@override
State<StatefulWidget> createState() => _SettingsPage();
}
class _SettingsPage extends State<SettingsPage> {
void _logout() {}
void _changePassword() {}
Widget _scanSettings() {
return BlocBuilder<SettingsBloc, SettingsState>(
builder: (context, state) {
final currentState = state;
if (currentState is AppSettingsLoaded) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.all(20),
child: Text(
"Scaneinstellungen",
style: Theme.of(context).textTheme.headlineSmall,
),
),
ListTile(
title: const Text("Hardware-Scanner"),
subtitle: const Text(
"Schaltet die Kamera beim Scannen aus und nutzt den Hardware-Scanner",
),
trailing: Switch(
value: currentState.settings.useHardwareScanner,
onChanged: (value) {
Settings newSettings = currentState.settings.copyWith();
newSettings.useHardwareScanner = value;
context.read<SettingsBloc>().add(
UpdateSettings(settings: newSettings),
);
},
),
tileColor: Theme.of(context).colorScheme.onSecondary,
),
],
);
}
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.all(20),
child: Text(
"Scaneinstellungen",
style: Theme.of(context).textTheme.headlineSmall,
),
),
Card(
color: Theme.of(context).colorScheme.onSecondary,
child: Padding(
padding: const EdgeInsets.all(20),
child: Center(
child: Text("Fehler beim Lesen der Scan-Einstellungen"),
),
),
),
],
);
},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: ListView(
children: [
_scanSettings(),
Padding(
padding: const EdgeInsets.all(20),
child: Text(
"Kontoeinstellungen",
style: Theme.of(context).textTheme.headlineSmall,
),
),
ListTile(
title: const Text("Passwort öndern"),
trailing: Padding(
padding: const EdgeInsets.all(2),
child: IconButton(
onPressed: _changePassword,
icon: FilledButton(
onPressed: _changePassword,
child: const Text("Ändern"),
),
),
),
tileColor: Theme.of(context).colorScheme.onSecondary,
),
ListTile(
title: const Text("Ausloggen"),
trailing: IconButton(
onPressed: _logout,
icon: Icon(Icons.logout, color: Colors.redAccent),
),
tileColor: Theme.of(context).colorScheme.onSecondary,
),
],
),
appBar: AppBar(
title: Text(
"Einstellungen",
style: Theme.of(context).textTheme.headlineMedium,
),
),
);
}
}

View File

@ -0,0 +1,22 @@
import 'package:hl_lieferservice/feature/settings/model/settings.dart';
import 'package:shared_preferences/shared_preferences.dart';
class SettingsRepository {
Future<Settings> getSettings() async {
final prefs = await SharedPreferences.getInstance();
bool? useHardwareScanner = prefs.getBool("useHardwareScanner");
if (useHardwareScanner == null) {
await prefs.setBool("useHardwareScanner", false);
useHardwareScanner = false;
}
return Settings(useHardwareScanner: useHardwareScanner);
}
Future<void> saveSettings(Settings settings) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setBool("useHardwareScanner", settings.useHardwareScanner);
}
}