refactored HTTP error handling and streamlined UI components by centralizing shared logic and removing redundant parameters
This commit is contained in:
@@ -5,14 +5,12 @@ class AsyncDialogAction extends StatefulWidget {
|
||||
final AsyncActionCallback onConfirm;
|
||||
final String? cancelLabel;
|
||||
final AsyncErrorBuilder? errorBuilder;
|
||||
final ButtonStyle? confirmStyle;
|
||||
|
||||
const AsyncDialogAction({
|
||||
required this.confirmLabel,
|
||||
required this.onConfirm,
|
||||
this.cancelLabel = 'Abbrechen',
|
||||
this.errorBuilder,
|
||||
this.confirmStyle,
|
||||
super.key,
|
||||
});
|
||||
|
||||
@@ -58,7 +56,6 @@ class _AsyncDialogActionState extends State<AsyncDialogAction> {
|
||||
child: Text(widget.cancelLabel!),
|
||||
),
|
||||
TextButton(
|
||||
style: widget.confirmStyle,
|
||||
onPressed: _controller.busy
|
||||
? null
|
||||
: () async {
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
|
||||
import '../routing/app_routes.dart';
|
||||
import 'details_bottom_sheet.dart';
|
||||
import 'file_pick.dart';
|
||||
|
||||
/// Result of the user's choice inside [showAvatarActionsSheet]. The sheet
|
||||
@@ -32,69 +33,50 @@ Future<AvatarSheetResult?> showAvatarActionsSheet(
|
||||
required bool allowRemove,
|
||||
}) async {
|
||||
AvatarSheetResult? result;
|
||||
await showModalBottomSheet<void>(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
showDragHandle: true,
|
||||
useSafeArea: true,
|
||||
builder: (sheetContext) => SafeArea(
|
||||
child: SingleChildScrollView(
|
||||
padding: EdgeInsets.only(
|
||||
bottom: 16 + MediaQuery.viewInsetsOf(sheetContext).bottom,
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
ListTile(
|
||||
leading: const Icon(Icons.photo_library_outlined),
|
||||
title: const Text('Aus Galerie wählen'),
|
||||
onTap: () async {
|
||||
final bytes = await _pickAndCrop(
|
||||
sheetContext,
|
||||
FilePick.singleGalleryPick,
|
||||
);
|
||||
if (bytes == null || !sheetContext.mounted) return;
|
||||
result = AvatarUploadResult(bytes);
|
||||
Navigator.of(sheetContext).pop();
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
leading: const Icon(Icons.photo_camera_outlined),
|
||||
title: const Text('Foto aufnehmen'),
|
||||
onTap: () async {
|
||||
final bytes = await _pickAndCrop(
|
||||
sheetContext,
|
||||
FilePick.cameraPick,
|
||||
);
|
||||
if (bytes == null || !sheetContext.mounted) return;
|
||||
result = AvatarUploadResult(bytes);
|
||||
Navigator.of(sheetContext).pop();
|
||||
},
|
||||
),
|
||||
if (allowRemove) ...[
|
||||
const Divider(),
|
||||
ListTile(
|
||||
leading: Icon(
|
||||
Icons.delete_outline,
|
||||
color: Theme.of(sheetContext).colorScheme.error,
|
||||
),
|
||||
title: Text(
|
||||
'Profilbild entfernen',
|
||||
style: TextStyle(
|
||||
color: Theme.of(sheetContext).colorScheme.error,
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
result = const AvatarRemoveResult();
|
||||
Navigator.of(sheetContext).pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
await showDetailsBottomSheet(
|
||||
context,
|
||||
children: (sheetContext) => [
|
||||
ListTile(
|
||||
leading: const Icon(Icons.photo_library_outlined),
|
||||
title: const Text('Aus Galerie wählen'),
|
||||
onTap: () async {
|
||||
final bytes = await _pickAndCrop(
|
||||
sheetContext,
|
||||
FilePick.singleGalleryPick,
|
||||
);
|
||||
if (bytes == null || !sheetContext.mounted) return;
|
||||
result = AvatarUploadResult(bytes);
|
||||
Navigator.of(sheetContext).pop();
|
||||
},
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
leading: const Icon(Icons.photo_camera_outlined),
|
||||
title: const Text('Foto aufnehmen'),
|
||||
onTap: () async {
|
||||
final bytes = await _pickAndCrop(sheetContext, FilePick.cameraPick);
|
||||
if (bytes == null || !sheetContext.mounted) return;
|
||||
result = AvatarUploadResult(bytes);
|
||||
Navigator.of(sheetContext).pop();
|
||||
},
|
||||
),
|
||||
if (allowRemove) ...[
|
||||
const Divider(),
|
||||
ListTile(
|
||||
leading: Icon(
|
||||
Icons.delete_outline,
|
||||
color: Theme.of(sheetContext).colorScheme.error,
|
||||
),
|
||||
title: Text(
|
||||
'Profilbild entfernen',
|
||||
style: TextStyle(color: Theme.of(sheetContext).colorScheme.error),
|
||||
),
|
||||
onTap: () {
|
||||
result = const AvatarRemoveResult();
|
||||
Navigator.of(sheetContext).pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
],
|
||||
);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
|
||||
import '../routing/app_routes.dart';
|
||||
import 'details_bottom_sheet.dart';
|
||||
import 'file_pick.dart';
|
||||
|
||||
/// Bottom sheet with "from gallery" and "take photo" actions for choosing a
|
||||
@@ -13,44 +14,30 @@ import 'file_pick.dart';
|
||||
/// cancelled everything.
|
||||
Future<Uint8List?> showChatBackgroundPickerSheet(BuildContext context) async {
|
||||
Uint8List? result;
|
||||
await showModalBottomSheet<void>(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
showDragHandle: true,
|
||||
useSafeArea: true,
|
||||
builder: (sheetContext) => SafeArea(
|
||||
child: SingleChildScrollView(
|
||||
padding: EdgeInsets.only(
|
||||
bottom: 16 + MediaQuery.viewInsetsOf(sheetContext).bottom,
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
ListTile(
|
||||
leading: const Icon(Icons.photo_library_outlined),
|
||||
title: const Text('Aus Galerie wählen'),
|
||||
onTap: () async {
|
||||
final bytes = await _pickRaw(FilePick.singleGalleryPick);
|
||||
if (bytes == null || !sheetContext.mounted) return;
|
||||
result = bytes;
|
||||
Navigator.of(sheetContext).pop();
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
leading: const Icon(Icons.photo_camera_outlined),
|
||||
title: const Text('Foto aufnehmen'),
|
||||
onTap: () async {
|
||||
final bytes = await _pickRaw(FilePick.cameraPick);
|
||||
if (bytes == null || !sheetContext.mounted) return;
|
||||
result = bytes;
|
||||
Navigator.of(sheetContext).pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
await showDetailsBottomSheet(
|
||||
context,
|
||||
children: (sheetContext) => [
|
||||
ListTile(
|
||||
leading: const Icon(Icons.photo_library_outlined),
|
||||
title: const Text('Aus Galerie wählen'),
|
||||
onTap: () async {
|
||||
final bytes = await _pickRaw(FilePick.singleGalleryPick);
|
||||
if (bytes == null || !sheetContext.mounted) return;
|
||||
result = bytes;
|
||||
Navigator.of(sheetContext).pop();
|
||||
},
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
leading: const Icon(Icons.photo_camera_outlined),
|
||||
title: const Text('Foto aufnehmen'),
|
||||
onTap: () async {
|
||||
final bytes = await _pickRaw(FilePick.cameraPick);
|
||||
if (bytes == null || !sheetContext.mounted) return;
|
||||
result = bytes;
|
||||
Navigator.of(sheetContext).pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -33,7 +33,6 @@ class CacheView extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _CacheViewState extends State<CacheView> {
|
||||
final Localstore storage = Localstore.instance;
|
||||
late Future<Map<String, dynamic>?> files;
|
||||
|
||||
@override
|
||||
|
||||
@@ -15,8 +15,7 @@ class DebugTile {
|
||||
context.read<SettingsCubit>().val().devToolsEnabled &&
|
||||
(onlyInDebug ? kDebugMode : true);
|
||||
|
||||
Widget jsonData(Map<String, dynamic> data, {bool ignoreConfig = false}) =>
|
||||
callback(
|
||||
Widget jsonData(Map<String, dynamic> data) => callback(
|
||||
title: 'JSON daten anzeigen',
|
||||
onTab: () => JsonViewer.asDialog(context, data),
|
||||
);
|
||||
|
||||
@@ -4,21 +4,7 @@ import 'package:flutter/material.dart';
|
||||
|
||||
import '../../utils/clipboard_helper.dart';
|
||||
|
||||
class JsonViewer extends StatelessWidget {
|
||||
final String title;
|
||||
final Map<String, dynamic> data;
|
||||
|
||||
const JsonViewer({super.key, required this.title, required this.data});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => Scaffold(
|
||||
appBar: AppBar(title: Text(title)),
|
||||
body: SingleChildScrollView(
|
||||
scrollDirection: Axis.vertical,
|
||||
child: Text(format(data)),
|
||||
),
|
||||
);
|
||||
|
||||
class JsonViewer {
|
||||
static final _encoder = const JsonEncoder.withIndent(' ');
|
||||
|
||||
static String format(Map<String, dynamic> jsonInput) =>
|
||||
|
||||
Reference in New Issue
Block a user