Skip to content

Commit 2061459

Browse files
authored
chore: process snapshot.hasError in future builders (#78)
1 parent 603df53 commit 2061459

13 files changed

+90
-9
lines changed

lib/app/view/error_page.dart

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:yaru/yaru.dart';
3+
import '../../l10n/l10n.dart';
4+
5+
class ErrorPage extends StatelessWidget {
6+
const ErrorPage({super.key, required this.error});
7+
8+
final String error;
9+
10+
@override
11+
Widget build(BuildContext context) {
12+
return Scaffold(
13+
appBar: YaruWindowTitleBar(
14+
title: Text(context.l10n.oopsSomethingWentWrong),
15+
border: BorderSide.none,
16+
backgroundColor: Colors.transparent,
17+
),
18+
body: ErrorBody(error: error),
19+
);
20+
}
21+
}
22+
23+
class ErrorBody extends StatelessWidget {
24+
const ErrorBody({super.key, required this.error});
25+
26+
final String error;
27+
28+
@override
29+
Widget build(BuildContext context) {
30+
return Center(child: Text('An error occurred: $error'));
31+
}
32+
}

lib/app/view/wait_for_registration_page.dart

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import '../../authentication/authentication_model.dart';
55
import '../../authentication/view/chat_login_page.dart';
66
import '../../encryption/view/check_encryption_setup_page.dart';
77
import 'app.dart';
8+
import 'error_page.dart';
89
import 'splash_page.dart';
910

1011
class WaitForRegistrationPage extends StatefulWidget {
@@ -38,7 +39,16 @@ class _WaitForRegistrationPageState extends State<WaitForRegistrationPage> {
3839
@override
3940
Widget build(BuildContext context) => FutureBuilder(
4041
future: _registrationReady,
41-
builder: (context, snapshot) => snapshot.hasData
42+
builder: (context, snapshot) => snapshot.hasError
43+
? App(
44+
themeMode: ThemeMode.system,
45+
lightTheme: widget.lightTheme,
46+
darkTheme: widget.darkTheme,
47+
highContrastDarkTheme: widget.highContrastDarkTheme,
48+
highContrastTheme: widget.highContrastTheme,
49+
child: ErrorPage(error: snapshot.error.toString()),
50+
)
51+
: snapshot.hasData
4252
? App(
4353
lightTheme: widget.lightTheme,
4454
darkTheme: widget.darkTheme,

lib/chat_master/view/chat_room_master_tile_subtitle.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ class ChatRoomLastEvent extends StatelessWidget {
6565
withSenderNamePrefix: true,
6666
),
6767
builder: (context, snapshot) {
68+
if (snapshot.hasError) {
69+
return const Text('?', maxLines: 1);
70+
}
6871
if (snapshot.hasData && lastEvent != null) {
6972
return Text(snapshot.data!, maxLines: 1);
7073
}

lib/chat_room/common/view/chat_room_page.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'package:matrix/matrix.dart';
66
import 'package:super_drag_and_drop/super_drag_and_drop.dart';
77
import 'package:watch_it/watch_it.dart';
88

9+
import '../../../app/view/error_page.dart';
910
import '../../../common/chat_model.dart';
1011
import '../../../common/room_x.dart';
1112
import '../../../common/view/build_context_x.dart';
@@ -148,6 +149,9 @@ class _ChatRoomPageState extends State<ChatRoomPage> {
148149
key: ValueKey(widget.room.id),
149150
future: _timelineFuture,
150151
builder: (context, snapshot) {
152+
if (snapshot.hasError) {
153+
return ErrorBody(error: snapshot.error.toString());
154+
}
151155
if (snapshot.hasData) {
152156
return Padding(
153157
padding: const EdgeInsets.only(

lib/common/client_x.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import 'platforms.dart';
2020

2121
extension ClientX on Client {
2222
static Future<Client> registerAsync() async {
23+
await vod.init(wasmPath: './assets/assets/vodozemac/');
2324
final client = Client(
2425
AppConfig.appId,
2526
nativeImplementations: kIsWeb

lib/common/view/chat_profile_dialog.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import 'package:matrix/matrix.dart';
33
import 'package:watch_it/watch_it.dart';
44
import 'package:yaru/yaru.dart';
55

6+
import '../../app/view/error_page.dart';
67
import '../../l10n/l10n.dart';
78
import '../../settings/view/chat_settings_dialog.dart';
89
import '../chat_model.dart';
@@ -49,6 +50,10 @@ class _ChatProfileState extends State<ChatProfile> {
4950
return FutureBuilder(
5051
future: _future,
5152
builder: (context, snapshot) {
53+
if (snapshot.hasError) {
54+
return ErrorBody(error: snapshot.error.toString());
55+
}
56+
5257
final myProfile =
5358
snapshot.hasData &&
5459
snapshot.data!.userId == di<ChatModel>().myUserId;

lib/encryption/view/check_encryption_setup_page.dart

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'package:flutter/material.dart';
22
import 'package:watch_it/watch_it.dart';
33

4+
import '../../app/view/error_page.dart';
45
import '../../app/view/splash_page.dart';
56
import '../../chat_master/view/chat_master_detail_page.dart';
67
import '../../l10n/l10n.dart';
@@ -28,10 +29,12 @@ class _CheckEncryptionSetupPageState extends State<CheckEncryptionSetupPage> {
2829
@override
2930
Widget build(BuildContext context) => FutureBuilder(
3031
future: _isEncryptionSetupNeeded,
31-
builder: (context, snapshot) => !snapshot.hasData
32-
? SplashPage(title: Text(context.l10n.loadingPleaseWait))
33-
: (snapshot.data == true
32+
builder: (context, snapshot) => snapshot.hasError
33+
? ErrorPage(error: snapshot.error.toString())
34+
: snapshot.hasData
35+
? (snapshot.data == true
3436
? const SetupEncryptedChatPage()
35-
: const ChatMasterDetailPage()),
37+
: const ChatMasterDetailPage())
38+
: SplashPage(title: Text(context.l10n.loadingPleaseWait)),
3639
);
3740
}

lib/events/view/chat_html_message_link_handler.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import 'package:matrix/matrix_api_lite/generated/model.dart';
44
import 'package:url_launcher/url_launcher.dart';
55
import 'package:watch_it/watch_it.dart';
66

7+
import '../../app/view/error_page.dart';
78
import '../../common/chat_model.dart';
89
import '../../common/search_model.dart';
910
import '../../common/view/chat_profile_dialog.dart';
@@ -70,6 +71,11 @@ class _ChatRoomSearchDialogState extends State<ChatRoomSearchDialog> {
7071
return FutureBuilder(
7172
future: _future,
7273
builder: (context, snapshot) {
74+
if (snapshot.hasError) {
75+
return AlertDialog(
76+
content: ErrorBody(error: snapshot.error.toString()),
77+
);
78+
}
7379
return ConfirmationDialog(
7480
confirmEnabled: snapshot.hasData,
7581
onConfirm: snapshot.hasData

lib/events/view/chat_image.dart

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,12 @@ class _ChatImageFutureState extends State<ChatImageFuture> {
139139
@override
140140
Widget build(BuildContext context) => FutureBuilder(
141141
future: _future,
142-
builder: (context, snapshot) => snapshot.hasData
142+
builder: (context, snapshot) => snapshot.hasError
143+
? Icon(
144+
YaruIcons.image_missing,
145+
size: widget.height == null ? 45 : widget.height! / 2,
146+
)
147+
: snapshot.hasData
143148
? AnimatedOpacity(
144149
opacity: snapshot.hasData ? 1 : 0,
145150
duration: const Duration(milliseconds: 300),

lib/events/view/chat_message_image_full_screen_dialog.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import 'package:photo_view/photo_view.dart';
88
import 'package:watch_it/watch_it.dart';
99
import 'package:yaru/yaru.dart';
1010

11+
import '../../app/view/error_page.dart';
1112
import '../../common/date_time_x.dart';
1213
import '../../common/local_image_model.dart';
1314
import '../../common/view/build_context_x.dart';
@@ -160,6 +161,9 @@ class _ChatMessageImageFullScreenDialogState
160161
child: FutureBuilder(
161162
future: _future,
162163
builder: (context, snapshot) {
164+
if (snapshot.hasError) {
165+
return ErrorBody(error: snapshot.error.toString());
166+
}
163167
if (snapshot.hasData) {
164168
return ClipRRect(
165169
child: PhotoView(

0 commit comments

Comments
 (0)