diff --git a/flutter/lib/components/error_display/error_display.dart b/flutter/lib/components/error_display/error_display.dart new file mode 100644 index 0000000..a005fcc --- /dev/null +++ b/flutter/lib/components/error_display/error_display.dart @@ -0,0 +1,38 @@ +import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; + +class ErrorDisplay extends StatelessWidget { + final String errorMessage; + + const ErrorDisplay({Key? key, required this.errorMessage}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Center( + child: Padding( + padding: const EdgeInsets.all(32.0), + child: Container( + constraints: const BoxConstraints(maxWidth: 300), + padding: const EdgeInsets.all(16.0), + decoration: BoxDecoration( + color: Colors.red[100], + border: Border.all(color: Colors.red[300]!), + borderRadius: BorderRadius.circular(12.0), + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Icon(FontAwesomeIcons.triangleExclamation, color: Colors.red, size: 48.0), + const SizedBox(height: 16.0), + Text( + errorMessage, + textAlign: TextAlign.center, + style: TextStyle(color: Colors.red[900], fontSize: 16.0), + ), + ], + ), + ), + ), + ); + } +} diff --git a/flutter/lib/components/modals/filter_modal_channel.dart b/flutter/lib/components/modals/filter_modal_channel.dart index b019e93..b0c64dd 100644 --- a/flutter/lib/components/modals/filter_modal_channel.dart +++ b/flutter/lib/components/modals/filter_modal_channel.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:simplecloudnotifier/api/api_client.dart'; +import 'package:simplecloudnotifier/components/error_display/error_display.dart'; import 'package:simplecloudnotifier/models/channel.dart'; import 'package:simplecloudnotifier/pages/message_list/message_filter_chiplet.dart'; import 'package:simplecloudnotifier/state/app_auth.dart'; @@ -61,7 +62,7 @@ class _FilterModalChannelState extends State { if (_futureChannels?.value != null) { return _buildList(context, _futureChannels!.value!); } else if (snapshot.connectionState == ConnectionState.done && snapshot.hasError) { - return Text('Error: ${snapshot.error}'); //TODO better error display + return ErrorDisplay(errorMessage: '${snapshot.error}'); } else if (snapshot.connectionState == ConnectionState.done) { return _buildList(context, snapshot.data!); } else { diff --git a/flutter/lib/components/modals/filter_modal_keytoken.dart b/flutter/lib/components/modals/filter_modal_keytoken.dart index 270abc9..bac9456 100644 --- a/flutter/lib/components/modals/filter_modal_keytoken.dart +++ b/flutter/lib/components/modals/filter_modal_keytoken.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:simplecloudnotifier/api/api_client.dart'; +import 'package:simplecloudnotifier/components/error_display/error_display.dart'; import 'package:simplecloudnotifier/models/keytoken.dart'; import 'package:simplecloudnotifier/pages/message_list/message_filter_chiplet.dart'; import 'package:simplecloudnotifier/state/app_auth.dart'; @@ -61,7 +62,7 @@ class _FilterModalKeytokenState extends State { if (_futureKeyTokens?.value != null) { return _buildList(context, _futureKeyTokens!.value!); } else if (snapshot.connectionState == ConnectionState.done && snapshot.hasError) { - return Text('Error: ${snapshot.error}'); //TODO better error display + return ErrorDisplay(errorMessage: '${snapshot.error}'); } else if (snapshot.connectionState == ConnectionState.done) { return _buildList(context, snapshot.data!); } else { diff --git a/flutter/lib/components/modals/filter_modal_sendername.dart b/flutter/lib/components/modals/filter_modal_sendername.dart index 7a1c8c7..d8a79ce 100644 --- a/flutter/lib/components/modals/filter_modal_sendername.dart +++ b/flutter/lib/components/modals/filter_modal_sendername.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:simplecloudnotifier/api/api_client.dart'; +import 'package:simplecloudnotifier/components/error_display/error_display.dart'; import 'package:simplecloudnotifier/pages/message_list/message_filter_chiplet.dart'; import 'package:simplecloudnotifier/state/app_auth.dart'; import 'package:simplecloudnotifier/state/app_events.dart'; @@ -59,7 +60,7 @@ class _FilterModalSendernameState extends State { if (_futureSenders?.value != null) { return _buildList(context, _futureSenders!.value!); } else if (snapshot.connectionState == ConnectionState.done && snapshot.hasError) { - return Text('Error: ${snapshot.error}'); //TODO better error display + return ErrorDisplay(errorMessage: '${snapshot.error}'); } else if (snapshot.connectionState == ConnectionState.done) { return _buildList(context, snapshot.data!); } else { diff --git a/flutter/lib/pages/account/account.dart b/flutter/lib/pages/account/account.dart index bdacaad..bc9ea2f 100644 --- a/flutter/lib/pages/account/account.dart +++ b/flutter/lib/pages/account/account.dart @@ -5,6 +5,7 @@ import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:provider/provider.dart'; import 'package:simplecloudnotifier/api/api_client.dart'; +import 'package:simplecloudnotifier/components/error_display/error_display.dart'; import 'package:simplecloudnotifier/models/user.dart'; import 'package:simplecloudnotifier/pages/account/login.dart'; import 'package:simplecloudnotifier/pages/channel_list/channel_list_extended.dart'; @@ -196,7 +197,7 @@ class _AccountRootPageState extends State { if (futureUser?.value != null) { return _buildShowAccount(context, acc, futureUser!.value!); } else if (snapshot.connectionState == ConnectionState.done && snapshot.hasError) { - return Text('Error: ${snapshot.error}'); //TODO better error display + return ErrorDisplay(errorMessage: '${snapshot.error}'); } else if (snapshot.connectionState == ConnectionState.done) { return _buildShowAccount(context, acc, snapshot.data!); } else { diff --git a/flutter/lib/pages/channel_scanner/channel_scanner_result_channelsubscribe.dart b/flutter/lib/pages/channel_scanner/channel_scanner_result_channelsubscribe.dart index 433e9e8..c7eba3a 100644 --- a/flutter/lib/pages/channel_scanner/channel_scanner_result_channelsubscribe.dart +++ b/flutter/lib/pages/channel_scanner/channel_scanner_result_channelsubscribe.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:provider/provider.dart'; import 'package:simplecloudnotifier/api/api_client.dart'; +import 'package:simplecloudnotifier/components/error_display/error_display.dart'; import 'package:simplecloudnotifier/models/channel.dart'; import 'package:simplecloudnotifier/models/scan_result.dart'; import 'package:simplecloudnotifier/models/subscription.dart'; @@ -73,7 +74,7 @@ class _ChannelScannerResultChannelSubscribeState extends State { if (loadingState == ChannelViewPageInitState.loading) { child = Center(child: CircularProgressIndicator()); } else if (loadingState == ChannelViewPageInitState.error) { - child = Center(child: Text('Error: ' + errorMessage)); //TODO better error + child = ErrorDisplay(errorMessage: errorMessage); } else if (loadingState == ChannelViewPageInitState.okay && channelPreview!.ownerUserID == userAcc.userID) { child = _buildOwnedChannelView(context, this.channel!); } else { diff --git a/flutter/lib/pages/debug/debug_persistence_failurelogfile.dart b/flutter/lib/pages/debug/debug_persistence_failurelogfile.dart index a0d83b7..43f2e31 100644 --- a/flutter/lib/pages/debug/debug_persistence_failurelogfile.dart +++ b/flutter/lib/pages/debug/debug_persistence_failurelogfile.dart @@ -1,6 +1,7 @@ import 'dart:io'; import 'package:flutter/material.dart'; +import 'package:simplecloudnotifier/components/error_display/error_display.dart'; import 'package:simplecloudnotifier/components/layout/scaffold.dart'; import 'package:simplecloudnotifier/types/immediate_future.dart'; @@ -39,7 +40,7 @@ class _DebugFailureLogFilePageState extends State { if (_futureContent?.value != null) { return _buildContent(context, _futureContent!.value!); } else if (snapshot.connectionState == ConnectionState.done && snapshot.hasError) { - return Text('Error: ${snapshot.error}'); //TODO better error display + return ErrorDisplay(errorMessage: '${snapshot.error}'); } else if (snapshot.connectionState == ConnectionState.done) { return _buildContent(context, snapshot.data!); } else { diff --git a/flutter/lib/pages/keytoken_view/keytoken_view.dart b/flutter/lib/pages/keytoken_view/keytoken_view.dart index 9326a7e..2bdb955 100644 --- a/flutter/lib/pages/keytoken_view/keytoken_view.dart +++ b/flutter/lib/pages/keytoken_view/keytoken_view.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:intl/intl.dart'; import 'package:simplecloudnotifier/api/api_client.dart'; +import 'package:simplecloudnotifier/components/error_display/error_display.dart'; import 'package:simplecloudnotifier/components/layout/scaffold.dart'; import 'package:simplecloudnotifier/models/keytoken.dart'; import 'package:simplecloudnotifier/models/user.dart'; @@ -128,7 +129,7 @@ class _KeyTokenViewPageState extends State { if (loadingState == KeyTokenViewPageInitState.loading) { child = Center(child: CircularProgressIndicator()); } else if (loadingState == KeyTokenViewPageInitState.error) { - child = Center(child: Text('Error: ' + errorMessage)); //TODO better error + child = ErrorDisplay(errorMessage: errorMessage); } else if (loadingState == KeyTokenViewPageInitState.okay && keytokenPreview!.ownerUserID == userAcc.userID) { child = _buildOwnedKeyTokenView(context, this.keytoken!); title = this.keytoken!.name; diff --git a/flutter/lib/pages/message_view/message_view.dart b/flutter/lib/pages/message_view/message_view.dart index 4152700..75993bd 100644 --- a/flutter/lib/pages/message_view/message_view.dart +++ b/flutter/lib/pages/message_view/message_view.dart @@ -195,15 +195,15 @@ class _MessageViewPageState extends State { context: context, icon: FontAwesomeIcons.solidUser, title: 'User', - values: [user?.userID ?? '...', user?.username ?? ''], - mainAction: () => {/*TODO*/}, + values: [user?.userID ?? message.senderUserID, user?.username ?? ''], + mainAction: () => FilteredMessageViewPage(title: user?.username ?? message.senderUserID, filter: MessageFilter(senderUserID: [message.senderUserID])), ), UI.metaCard( context: context, icon: FontAwesomeIcons.solidBolt, title: 'Priority', values: [_prettyPrintPriority(message.priority)], - mainAction: () => {/*TODO*/}, + mainAction: () => FilteredMessageViewPage(title: "Priority ${message.priority}", filter: MessageFilter(priority: [message.priority])), ), if (message.senderUserID == userAccUserID) UI.button(text: "Delete Message", onPressed: () {/*TODO*/}, color: Colors.red[900]), ], diff --git a/flutter/lib/pages/send/send.dart b/flutter/lib/pages/send/send.dart index f840dcb..84edde3 100644 --- a/flutter/lib/pages/send/send.dart +++ b/flutter/lib/pages/send/send.dart @@ -3,6 +3,7 @@ import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:provider/provider.dart'; import 'package:qr_flutter/qr_flutter.dart'; import 'package:simplecloudnotifier/api/api_client.dart'; +import 'package:simplecloudnotifier/components/error_display/error_display.dart'; import 'package:simplecloudnotifier/state/application_log.dart'; import 'package:simplecloudnotifier/state/globals.dart'; import 'package:simplecloudnotifier/utils/toaster.dart'; @@ -228,7 +229,7 @@ class _SendRootPageState extends State { ); } if (snapshot.hasError) { - return Text('Error: ${snapshot.error}'); //TODO better error display + return ErrorDisplay(errorMessage: '${snapshot.error}'); } if (snapshot.connectionState != ConnectionState.done) { return Text('...'); //? diff --git a/flutter/lib/pages/subscription_view/subscription_view.dart b/flutter/lib/pages/subscription_view/subscription_view.dart index 9065b40..5158950 100644 --- a/flutter/lib/pages/subscription_view/subscription_view.dart +++ b/flutter/lib/pages/subscription_view/subscription_view.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:intl/intl.dart'; import 'package:simplecloudnotifier/api/api_client.dart'; +import 'package:simplecloudnotifier/components/error_display/error_display.dart'; import 'package:simplecloudnotifier/components/layout/scaffold.dart'; import 'package:simplecloudnotifier/models/channel.dart'; import 'package:simplecloudnotifier/models/subscription.dart'; @@ -136,7 +137,7 @@ class _SubscriptionViewPageState extends State { if (loadingState == SubscriptionViewPageInitState.loading) { child = Center(child: CircularProgressIndicator()); } else if (loadingState == SubscriptionViewPageInitState.error) { - child = Center(child: Text('Error: ' + errorMessage)); //TODO better error + child = ErrorDisplay(errorMessage: errorMessage); } else if (loadingState == SubscriptionViewPageInitState.okay) { if (subscription!.channelOwnerUserID == userAcc.userID && subscription!.subscriberUserID == userAcc.userID) { child = _buildOwnedSubscriptionView(context, this.subscription!); @@ -145,10 +146,10 @@ class _SubscriptionViewPageState extends State { } else if (subscription!.subscriberUserID == userAcc.userID) { child = _buildOutgoingSubscriptionView(context, this.subscription!); } else { - child = Center(child: Text('Error: Invalid subscription state!')); //TODO better error + child = ErrorDisplay(errorMessage: 'Invalid subscription state!'); } } else { - child = Center(child: Text('Error: page state!')); //TODO better error + child = ErrorDisplay(errorMessage: 'Invalid page state!'); } return SCNScaffold(