Skip to content

Commit 8d061b2

Browse files
CubeRomanMagellanMagellan
andauthored
SK-680: No clear error message profile (#118)
* add and update LoadingOverlay * add more clear error message --------- Co-authored-by: Magellan <magellan@connectycube.com>
1 parent 277c97f commit 8d061b2

4 files changed

Lines changed: 93 additions & 26 deletions

File tree

sama_chat_client/lib/src/features/conversation_group_create/view/group_create_page.dart

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,18 +50,17 @@ class GroupCreatePage extends StatelessWidget {
5050

5151
@override
5252
Widget build(BuildContext context) {
53-
final LoadingOverlay loadingOverlay = LoadingOverlay();
5453
return BlocListener<ConversationCreateBloc, ConversationCreateState>(
5554
listener: (context, state) {
5655
if (state is ConversationCreatedLoading) {
57-
loadingOverlay.show(context);
56+
LoadingOverlay.instance.show(context);
5857
} else if (state is ConversationCreatedState) {
59-
loadingOverlay.hide();
58+
LoadingOverlay.instance.hide();
6059
ConversationModel conversation = state.conversation;
6160
context.go('$conversationListScreenPath/$conversationScreenSubPath',
6261
extra: conversation);
6362
} else if (state is ConversationCreatedStateError) {
64-
loadingOverlay.hide();
63+
LoadingOverlay.instance.hide();
6564
ScaffoldMessenger.of(context)
6665
..hideCurrentSnackBar()
6766
..showSnackBar(

sama_chat_client/lib/src/features/profile/bloc/profile_bloc.dart

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import 'package:bloc/bloc.dart';
44
import 'package:equatable/equatable.dart';
55
import 'package:formz/formz.dart';
66
import 'package:image_picker/image_picker.dart';
7+
import 'package:sama_sdk/api/connection/exceptions.dart';
78

89
import '../../../db/models/models.dart';
910
import '../../../repository/user/user_repository.dart';
@@ -182,8 +183,9 @@ class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
182183
Emitter<ProfileState> emit,
183184
) async {
184185
if (state.isValid) {
185-
emit(state.copyWith(status: FormzSubmissionStatus.inProgress));
186-
186+
emit(state.copyWith(
187+
informationMessage: 'User updating in progress',
188+
status: FormzSubmissionStatus.inProgress));
187189
try {
188190
var user = await _userRepository.updateCurrentUser(
189191
currentPsw: state.userPassword.isValid
@@ -214,7 +216,7 @@ class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
214216
userPhone: UserPhone.pure(user.phone ?? ''),
215217
userEmail: UserEmail.pure(user.email ?? ''),
216218
informationMessage: 'User was successfully updated'));
217-
} catch (e) {
219+
} on ResponseException catch (ex) {
218220
var user = await _userRepository.getCurrentUser();
219221
emit(state.copyWith(
220222
status: FormzSubmissionStatus.failure,
@@ -224,7 +226,7 @@ class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
224226
userPhone: UserPhone.pure(user?.phone ?? ''),
225227
userEmail: UserEmail.pure(user?.email ?? ''),
226228
userPassword: const UserPassword.pure(),
227-
errorMessage: 'User wasn\'t updated: $e'));
229+
errorMessage: 'User wasn\'t updated: ${ex.message}'));
228230
}
229231
}
230232
}

sama_chat_client/lib/src/features/profile/view/profile_form.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import '../../../features/profile/bloc/profile_bloc.dart';
99
import '../../../shared/auth/bloc/auth_bloc.dart';
1010
import '../../../shared/connection/view/connection_checker.dart';
1111
import '../../../shared/ui/colors.dart';
12+
import '../../../shared/ui/view/loading_overlay.dart';
1213
import '../../../shared/ui/view/user_forms.dart';
1314
import '../../../shared/utils/screen_factor.dart';
1415
import '../models/models.dart';
@@ -20,14 +21,19 @@ class ProfileForm extends StatelessWidget {
2021
Widget build(BuildContext context) {
2122
return BlocListener<ProfileBloc, ProfileState>(
2223
listener: (context, state) {
24+
if (state.status.isInProgress) {
25+
LoadingOverlay.instance.show(context);
26+
}
2327
if (state.status.isFailure) {
28+
LoadingOverlay.instance.hide();
2429
ScaffoldMessenger.of(context)
2530
..hideCurrentSnackBar()
2631
..showSnackBar(
2732
SnackBar(content: Text(state.errorMessage ?? '')),
2833
);
2934
} else if (state.status.isSuccess &&
3035
state.informationMessage != null) {
36+
LoadingOverlay.instance.hide();
3137
ScaffoldMessenger.of(context)
3238
..hideCurrentSnackBar()
3339
..showSnackBar(

sama_chat_client/lib/src/shared/ui/view/loading_overlay.dart

Lines changed: 78 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,91 @@
1+
import 'dart:async';
2+
import 'dart:ui';
3+
14
import 'package:flutter/material.dart';
25

36
import '../colors.dart';
47

58
class LoadingOverlay {
6-
OverlayEntry? _overlay;
9+
LoadingOverlay._();
710

8-
LoadingOverlay();
11+
static final LoadingOverlay instance = LoadingOverlay._();
912

10-
void show(BuildContext context) {
11-
if (_overlay == null) {
12-
_overlay = OverlayEntry(
13-
builder: (context) => const ColoredBox(
14-
color: semiBlack,
15-
child: Center(
16-
child: CircularProgressIndicator(),
17-
),
18-
),
19-
);
20-
Overlay.of(context).insert(_overlay!);
21-
}
13+
OverlayEntry? _overlayEntry;
14+
Timer? _autoHideTimer;
15+
16+
bool get isShowing => _overlayEntry != null;
17+
18+
void show(BuildContext context,
19+
{String? message, Duration duration = const Duration(seconds: 10)}) {
20+
if (_overlayEntry != null) return;
21+
22+
_overlayEntry = OverlayEntry(
23+
builder: (_) => _LoaderWidget(message: message),
24+
);
25+
26+
Overlay.of(
27+
context,
28+
rootOverlay: true,
29+
).insert(_overlayEntry!);
30+
31+
_autoHideTimer?.cancel();
32+
33+
_autoHideTimer = Timer(duration, () {
34+
hide();
35+
});
2236
}
2337

2438
void hide() {
25-
if (_overlay != null) {
26-
_overlay!.remove();
27-
_overlay = null;
28-
}
39+
_autoHideTimer?.cancel();
40+
_autoHideTimer = null;
41+
42+
_overlayEntry?.remove();
43+
_overlayEntry = null;
44+
}
45+
}
46+
47+
class _LoaderWidget extends StatelessWidget {
48+
final String? message;
49+
50+
const _LoaderWidget({
51+
this.message,
52+
});
53+
54+
@override
55+
Widget build(BuildContext context) {
56+
return Material(
57+
color: Colors.transparent,
58+
child: Stack(
59+
children: [
60+
Positioned.fill(
61+
child: BackdropFilter(
62+
filter: ImageFilter.blur(
63+
sigmaX: 2,
64+
sigmaY: 2,
65+
),
66+
child: Container(
67+
color: black.withValues(alpha: 0.25),
68+
),
69+
),
70+
),
71+
Center(
72+
child: Column(
73+
mainAxisSize: MainAxisSize.min,
74+
children: [
75+
const CircularProgressIndicator(),
76+
if (message != null) ...[
77+
const SizedBox(height: 16),
78+
Text(
79+
message!,
80+
textAlign: TextAlign.center,
81+
),
82+
],
83+
],
84+
),
85+
),
86+
],
87+
),
88+
);
2989
}
3090
}
3191

0 commit comments

Comments
 (0)