simplify: dedupe boilerplate and remove dead code across all layers
This commit is contained in:
@@ -166,13 +166,24 @@ Future<void> _afterExternalFilesUploaded(
|
||||
GetRoomResponseObject room,
|
||||
List<String> uploadedRemotePaths,
|
||||
PendingShare share,
|
||||
) async {
|
||||
) => _runShareFlow(
|
||||
context,
|
||||
action: () =>
|
||||
shareFilesToChat(token: room.token, remoteFilePaths: uploadedRemotePaths),
|
||||
onSuccess: () => _setExternalDraftAndOpenChat(context, room, share),
|
||||
);
|
||||
|
||||
/// Shared share-flow scaffolding: shows the blocking spinner, runs [action],
|
||||
/// maps failures to an error dialog (popping the spinner first), and invokes
|
||||
/// [onSuccess] on success while still mounted.
|
||||
Future<void> _runShareFlow(
|
||||
BuildContext context, {
|
||||
required Future<void> Function() action,
|
||||
required VoidCallback onSuccess,
|
||||
}) async {
|
||||
unawaited(_showBlockingSpinner(context));
|
||||
try {
|
||||
await shareFilesToChat(
|
||||
token: room.token,
|
||||
remoteFilePaths: uploadedRemotePaths,
|
||||
);
|
||||
await action();
|
||||
} catch (e) {
|
||||
if (context.mounted) Navigator.of(context).pop();
|
||||
if (context.mounted) {
|
||||
@@ -186,7 +197,7 @@ Future<void> _afterExternalFilesUploaded(
|
||||
return;
|
||||
}
|
||||
if (!context.mounted) return;
|
||||
_setExternalDraftAndOpenChat(context, room, share);
|
||||
onSuccess();
|
||||
}
|
||||
|
||||
void _setExternalDraftAndOpenChat(
|
||||
@@ -213,61 +224,30 @@ Future<void> _internalShareFlow(
|
||||
BuildContext context,
|
||||
GetRoomResponseObject room,
|
||||
RemoteFileRef file,
|
||||
) async {
|
||||
unawaited(_showBlockingSpinner(context));
|
||||
try {
|
||||
await shareFilesToChat(
|
||||
token: room.token,
|
||||
remoteFilePaths: [file.path],
|
||||
);
|
||||
} catch (e) {
|
||||
if (context.mounted) Navigator.of(context).pop();
|
||||
if (context.mounted) {
|
||||
InfoDialog.show(
|
||||
context,
|
||||
errorToUserMessage(e),
|
||||
title: 'Fehler',
|
||||
copyable: true,
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!context.mounted) return;
|
||||
_finishWithChat(context, room);
|
||||
}
|
||||
) => _runShareFlow(
|
||||
context,
|
||||
action: () =>
|
||||
shareFilesToChat(token: room.token, remoteFilePaths: [file.path]),
|
||||
onSuccess: () => _finishWithChat(context, room),
|
||||
);
|
||||
|
||||
Future<void> _forwardMessageFlow(
|
||||
BuildContext context,
|
||||
GetRoomResponseObject room,
|
||||
String? text,
|
||||
RemoteFileRef? file,
|
||||
) async {
|
||||
unawaited(_showBlockingSpinner(context));
|
||||
try {
|
||||
) => _runShareFlow(
|
||||
context,
|
||||
action: () async {
|
||||
if (file != null) {
|
||||
await shareFilesToChat(
|
||||
token: room.token,
|
||||
remoteFilePaths: [file.path],
|
||||
);
|
||||
await shareFilesToChat(token: room.token, remoteFilePaths: [file.path]);
|
||||
}
|
||||
if (text != null && text.isNotEmpty) {
|
||||
await SendMessage(room.token, SendMessageParams(text)).run();
|
||||
}
|
||||
} catch (e) {
|
||||
if (context.mounted) Navigator.of(context).pop();
|
||||
if (context.mounted) {
|
||||
InfoDialog.show(
|
||||
context,
|
||||
errorToUserMessage(e),
|
||||
title: 'Fehler',
|
||||
copyable: true,
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!context.mounted) return;
|
||||
_finishWithChat(context, room);
|
||||
}
|
||||
},
|
||||
onSuccess: () => _finishWithChat(context, room),
|
||||
);
|
||||
|
||||
/// Modal progress overlay shown during share-API roundtrips. The dialog is
|
||||
/// popped together with the picker by the subsequent popUntil(isFirst).
|
||||
|
||||
@@ -121,26 +121,15 @@ class ShareTargetPage extends StatelessWidget {
|
||||
|
||||
Widget _buildFilePreview(BuildContext context) {
|
||||
if (share.filePaths.length == 1) {
|
||||
final path = share.filePaths.first;
|
||||
final name = path.split(Platform.pathSeparator).last;
|
||||
return ConstrainedBox(
|
||||
constraints: const BoxConstraints(maxHeight: 320),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.surfaceContainer,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: _isImagePath(path)
|
||||
? Image.file(
|
||||
File(path),
|
||||
fit: BoxFit.contain,
|
||||
// Decode at most ~1080px so 50-MP gallery photos don't
|
||||
// balloon the decode buffer just to render at <320px high.
|
||||
cacheWidth: 1080,
|
||||
errorBuilder: (_, _, _) => _fileFallbackLarge(name),
|
||||
)
|
||||
: _fileFallbackLarge(name),
|
||||
// Decode at most ~1080px so 50-MP gallery photos don't balloon the
|
||||
// decode buffer just to render at <320px high.
|
||||
child: _filePreviewTile(
|
||||
context,
|
||||
share.filePaths.first,
|
||||
fit: BoxFit.contain,
|
||||
cacheWidth: 1080,
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -153,28 +142,38 @@ class ShareTargetPage extends StatelessWidget {
|
||||
mainAxisSpacing: 10,
|
||||
),
|
||||
itemCount: share.filePaths.length,
|
||||
itemBuilder: (context, i) {
|
||||
final path = share.filePaths[i];
|
||||
final name = path.split(Platform.pathSeparator).last;
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.surfaceContainer,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: _isImagePath(path)
|
||||
? Image.file(
|
||||
File(path),
|
||||
fit: BoxFit.cover,
|
||||
// Grid tiles are ~half-screen wide; 480px decode is
|
||||
// sharp on 3x displays without blowing up memory when
|
||||
// many files are shared at once.
|
||||
cacheWidth: 480,
|
||||
errorBuilder: (_, _, _) => _fileFallbackLarge(name),
|
||||
)
|
||||
: _fileFallbackLarge(name),
|
||||
);
|
||||
},
|
||||
// Grid tiles are ~half-screen wide; 480px decode is sharp on 3x displays
|
||||
// without blowing up memory when many files are shared at once.
|
||||
itemBuilder: (context, i) => _filePreviewTile(
|
||||
context,
|
||||
share.filePaths[i],
|
||||
fit: BoxFit.cover,
|
||||
cacheWidth: 480,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _filePreviewTile(
|
||||
BuildContext context,
|
||||
String path, {
|
||||
required BoxFit fit,
|
||||
required int cacheWidth,
|
||||
}) {
|
||||
final name = path.split(Platform.pathSeparator).last;
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.surfaceContainer,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: _isImagePath(path)
|
||||
? Image.file(
|
||||
File(path),
|
||||
fit: fit,
|
||||
cacheWidth: cacheWidth,
|
||||
errorBuilder: (_, _, _) => _fileFallbackLarge(name),
|
||||
)
|
||||
: _fileFallbackLarge(name),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user