From d8133347f056f5254e82856a17bc78dcbdf8bcc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20B=C3=B6sche?= Date: Sat, 24 Jan 2026 21:53:13 +0100 Subject: [PATCH] Refactor ShareFileDialog to improve UI layout, error handling, and share link management --- .../lib/widgets/share_file_dialog.dart | 169 ++++++++++-------- 1 file changed, 95 insertions(+), 74 deletions(-) diff --git a/b0esche_cloud/lib/widgets/share_file_dialog.dart b/b0esche_cloud/lib/widgets/share_file_dialog.dart index 7ddd091..da00aca 100644 --- a/b0esche_cloud/lib/widgets/share_file_dialog.dart +++ b/b0esche_cloud/lib/widgets/share_file_dialog.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import '../services/api_client.dart'; import '../theme/app_theme.dart'; +import '../theme/modern_glass_button.dart'; import '../injection.dart'; class ShareFileDialog extends StatefulWidget { @@ -24,7 +25,6 @@ class _ShareFileDialogState extends State { bool _isLoading = true; String? _shareUrl; String? _error; - late final TextEditingController _urlController = TextEditingController(); @override void initState() { @@ -32,12 +32,6 @@ class _ShareFileDialogState extends State { _loadShareLink(); } - @override - void dispose() { - _urlController.dispose(); - super.dispose(); - } - Future _loadShareLink() async { setState(() { _isLoading = true; @@ -53,7 +47,6 @@ class _ShareFileDialogState extends State { if (response['exists'] == true) { setState(() { _shareUrl = response['url']; - _urlController.text = _shareUrl!; _isLoading = false; }); } else { @@ -81,7 +74,6 @@ class _ShareFileDialogState extends State { setState(() { _shareUrl = response['url']; - _urlController.text = _shareUrl!; _isLoading = false; }); } catch (e) { @@ -106,7 +98,6 @@ class _ShareFileDialogState extends State { setState(() { _shareUrl = null; - _urlController.clear(); _isLoading = false; }); } catch (e) { @@ -129,78 +120,108 @@ class _ShareFileDialogState extends State { @override Widget build(BuildContext context) { return Dialog( - backgroundColor: Colors.transparent, - child: ConstrainedBox( - constraints: const BoxConstraints(maxWidth: 500), - child: Container( - decoration: AppTheme.glassDecoration, - padding: const EdgeInsets.all(24), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'Share "${widget.fileName}"', - style: TextStyle( - color: AppTheme.primaryText, - fontSize: 20, - fontWeight: FontWeight.bold, - ), - ), - const SizedBox(height: 16), - if (_isLoading) - const Center( - child: CircularProgressIndicator( - valueColor: AlwaysStoppedAnimation( - AppTheme.accentColor, - ), + backgroundColor: AppTheme.primaryBackground, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), + child: Container( + width: 500, + constraints: const BoxConstraints(maxHeight: 400), + padding: const EdgeInsets.all(24), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + // Header + Row( + children: [ + Text( + 'Share "${widget.fileName}"', + style: TextStyle( + color: AppTheme.primaryText, + fontSize: 20, + fontWeight: FontWeight.bold, ), - ) - else if (_error != null) - Text(_error!, style: TextStyle(color: Colors.red[400])) - else - Column( - crossAxisAlignment: CrossAxisAlignment.start, + ), + const Spacer(), + IconButton( + onPressed: () => Navigator.of(context).pop(), + icon: Icon(Icons.close, color: AppTheme.secondaryText), + splashColor: Colors.transparent, + highlightColor: Colors.transparent, + ), + ], + ), + const SizedBox(height: 16), + if (_isLoading) + const Center( + child: CircularProgressIndicator( + valueColor: AlwaysStoppedAnimation( + AppTheme.accentColor, + ), + ), + ) + else if (_error != null) + Center( + child: Column( + mainAxisSize: MainAxisSize.min, children: [ Text( - 'Share link created. Anyone with this link can view and download the file.', - style: TextStyle(color: AppTheme.secondaryText), + _error!, + style: TextStyle(color: AppTheme.errorColor), + textAlign: TextAlign.center, ), const SizedBox(height: 16), - TextField( - controller: _urlController, - readOnly: true, - maxLines: 2, - decoration: InputDecoration( - labelText: 'Share link', - border: const OutlineInputBorder(), - suffixIcon: IconButton( - icon: const Icon(Icons.copy), - onPressed: _copyToClipboard, - ), - ), - ), - const SizedBox(height: 16), - Row( - children: [ - TextButton( - onPressed: _revokeShareLink, - style: TextButton.styleFrom( - foregroundColor: Colors.red[400], - ), - child: const Text('Revoke Link'), - ), - const Spacer(), - TextButton( - onPressed: () => Navigator.of(context).pop(), - child: const Text('Close'), - ), - ], + ModernGlassButton( + onPressed: _loadShareLink, + child: const Text('Retry'), ), ], ), - ], - ), + ) + else + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Share link created. Anyone with this link can view and download the file.', + style: TextStyle(color: AppTheme.secondaryText), + ), + const SizedBox(height: 16), + Row( + children: [ + Expanded( + child: Text( + _shareUrl!, + maxLines: 2, + overflow: TextOverflow.ellipsis, + style: TextStyle(color: AppTheme.primaryText), + ), + ), + const SizedBox(width: 16), + ModernGlassButton( + onPressed: _copyToClipboard, + child: const Icon(Icons.content_copy), + ), + ], + ), + const SizedBox(height: 16), + Row( + children: [ + ModernGlassButton( + onPressed: _revokeShareLink, + child: Text( + 'Revoke Link', + style: TextStyle(color: AppTheme.errorColor), + ), + ), + const Spacer(), + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: const Text('Close'), + ), + ], + ), + ], + ), + ], ), ), );