Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: EWM-253 #487

Merged
merged 6 commits into from
Sep 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion lib/app/service/messenger/message.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ enum MessageType {
class Message {
Message({
required this.type,
required this.context,
required this.message,
this.duration = defaultMessageDisplayDuration,
this.debounceTime = defaultInfoMessageDebounceDuration,
Expand All @@ -34,12 +35,14 @@ class Message {

factory Message.error({
required String message,
BuildContext? context,
Duration duration = defaultMessageDisplayDuration,
Duration debounceTime = defaultErrorMessageDebounceDuration,
String? actionText,
VoidCallback? onAction,
}) =>
Message(
context: context,
type: MessageType.error,
message: message,
duration: duration,
Expand All @@ -50,12 +53,14 @@ class Message {

factory Message.info({
required String message,
BuildContext? context,
Duration duration = defaultMessageDisplayDuration,
Duration debounceTime = defaultInfoMessageDebounceDuration,
String? actionText,
VoidCallback? onAction,
}) =>
Message(
context: context,
type: MessageType.info,
message: message,
duration: duration,
Expand All @@ -66,12 +71,14 @@ class Message {

factory Message.successful({
required String message,
BuildContext? context,
Duration duration = defaultMessageDisplayDuration,
Duration debounceTime = defaultInfoMessageDebounceDuration,
String? actionText,
VoidCallback? onAction,
}) =>
Message(
context: context,
type: MessageType.successful,
message: message,
duration: duration,
Expand All @@ -80,6 +87,7 @@ class Message {
onAction: onAction,
);

final BuildContext? context;
final MessageType type;
final String message;
final Duration duration;
Expand All @@ -89,9 +97,10 @@ class Message {

final String hashString;

Toast get toastByMessage {
Toast toastByMessage(VoidCallback onTapClosed) {
return Toast(
type: _toastType,
onTapClosed: onTapClosed,
description: message,
icon: _icon,
actions: [
Expand Down
4 changes: 3 additions & 1 deletion lib/app/service/messenger/service/messenger_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'dart:async';

import 'package:app/app/service/messenger/message.dart';
import 'package:app/generated/generated.dart';
import 'package:flutter/material.dart';
import 'package:injectable/injectable.dart';

/// Service that shows messages to the user. Keep it simple and stupid, use only
Expand All @@ -19,9 +20,10 @@ class MessengerService {
_messageStreamController.add(message);
}

void showConnectionError() {
void showConnectionError(BuildContext? context) {
show(
Message.error(
context: context,
message: LocaleKeys.connectingNetworkFailed.tr(),
),
);
Expand Down
59 changes: 47 additions & 12 deletions lib/app/service/messenger/widget/messenger_service_widget.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import 'dart:async';

import 'package:app/app/service/messenger/cubit/messenger_cubit.dart';
import 'package:app/app/service/service.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:in_app_notification/in_app_notification.dart';
import 'package:ui_components_lib/ui_components_lib.dart';

class MessengerServiceWidget extends StatefulWidget {
Expand Down Expand Up @@ -35,10 +38,10 @@ class _MessengerServiceWidgetState extends State<MessengerServiceWidget> {

void _onDismiss() {
_isSnackbarShown = false;
_showNextMessage();
_showNextMessage(context);
}

void _showNextMessage() {
void _showNextMessage(BuildContext? context) {
// Wait for the current snackbar to be dismissed
if (_isSnackbarShown) {
return;
Expand All @@ -56,21 +59,53 @@ class _MessengerServiceWidgetState extends State<MessengerServiceWidget> {
}

_isSnackbarShown = true;
if (context != null) {
Timer(message.duration, () {
if (_isSnackbarShown) {
_onDismiss();
}
});

showSnackbar(
context: ctx,
toast: message.toastByMessage,
duration: message.duration,
onDismiss: _onDismiss,
);
InAppNotification.show(
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: DimensSizeV2.d16,
vertical: DimensSizeV2.d48,
),
child: message.toastByMessage(() {
_onDismiss();
InAppNotification.dismiss(context: context);
}),
),
context: ctx,
onTap: _onDismiss,
duration: message.duration,
);
} else {
showSnackbar(
context: ctx,
toast: message.toastByMessage(_onDismiss),
duration: message.duration,
onDismiss: _onDismiss,
);
}
}

@override
Widget build(BuildContext context) {
return BlocListener<MessengerCubit, MessengerState>(
bloc: _cubit,
listener: (_, __) => _showNextMessage(),
child: widget.child,
return SafeArea(
child: BlocListener<MessengerCubit, MessengerState>(
bloc: _cubit,
listener: (ctx, state) {
if (state.messagesToShow.isNotEmpty) {
final context = state.messagesToShow.last.context;
_showNextMessage(context);
} else {
_showNextMessage(null);
}
},
child: widget.child,
),
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ class ConnectionService {
);
_log.finest('updateTransportByConnection completed!');
} catch (e, t) {
inject<MessengerService>().showConnectionError();
inject<MessengerService>().showConnectionError(null);
_log.severe('updateTransportByConnection', e, t);

// allow level above to track fail
Expand Down
11 changes: 7 additions & 4 deletions lib/app/view/app_root_widgets.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:app/app/service/service.dart';
import 'package:flutter/widgets.dart';
import 'package:in_app_notification/in_app_notification.dart';

/// Widget that should be placed at the root of the app
/// This is a good place to put services that should be available
Expand All @@ -14,10 +15,12 @@ class AppRootWidgets extends StatelessWidget {

@override
Widget build(BuildContext context) {
return CrashDetectorServiceWidget(
child: LocalizationServiceWidget(
child: MessengerServiceWidget(
child: NavigationServiceWidget(child: child),
return InAppNotification(
child: CrashDetectorServiceWidget(
child: LocalizationServiceWidget(
child: MessengerServiceWidget(
child: NavigationServiceWidget(child: child),
),
),
),
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// ignore_for_file: use_build_context_synchronously

import 'package:app/app/service/network_connection/network_connection_service.dart';
import 'package:app/app/service/service.dart';
import 'package:app/data/models/seed/seed_phrase_model.dart';
Expand Down Expand Up @@ -67,8 +69,8 @@ class CreateSeedPasswordCubit extends Cubit<CreateSeedPasswordState>
return super.close();
}

Future<void> nextAction() async {
if (seedPhrase.isEmpty || !await checkConnection()) {
Future<void> nextAction(BuildContext context) async {
if (seedPhrase.isEmpty || !await checkConnection(context)) {
return;
}

Expand All @@ -92,7 +94,8 @@ class CreateSeedPasswordCubit extends Cubit<CreateSeedPasswordState>
} catch (e) {
Logger('CreateSeedPasswordCubit').severe(e);
emit(state.copyWith(isLoading: false));
messengerService.show(Message.error(message: e.toString()));
messengerService
.show(Message.error(context: context, message: e.toString()));
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// ignore_for_file: use_build_context_synchronously

import 'package:app/app/service/biometry_service.dart';
import 'package:app/app/service/messenger/message.dart';
import 'package:app/app/service/messenger/service/messenger_service.dart';
Expand All @@ -6,6 +8,7 @@ import 'package:app/data/models/seed/seed_phrase_model.dart';
import 'package:app/feature/add_seed/create_password/screens/create_seed_password/create_seed_password_screen.dart';
import 'package:app/feature/constants.dart';
import 'package:elementary/elementary.dart';
import 'package:flutter/material.dart';
import 'package:logging/logging.dart';
import 'package:nekoton_repository/nekoton_repository.dart' hide Message;

Expand All @@ -27,6 +30,7 @@ class CreateSeedPasswordScreenModel extends ElementaryModel {
final SeedPhraseModel? _phrase;

Future<void> next({
required BuildContext context,
required String password,
}) async {
late SeedPhraseModel seed;
Expand All @@ -51,7 +55,9 @@ class CreateSeedPasswordScreenModel extends ElementaryModel {
);
} catch (e) {
Logger('CreateSeedPasswordCubit').severe(e);
_messengerService.show(Message.error(message: e.toString()));
_messengerService.show(
Message.error(context: context, message: e.toString()),
);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ class CreateSeedPasswordScreenWidgetModel extends CustomWidgetModel<
_loadState.accept(true);

await model.next(
context: context,
password: passwordController.text,
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class CreateSeedPasswordProfilePage extends StatelessWidget {
needBiometryIfPossible: false,
passwordController: cubit.passwordController,
confirmController: cubit.confirmController,
onPressedNext: cubit.nextAction,
onPressedNext: () => cubit.nextAction(context),
passwordStatus: state.status,
isLoading: state.isLoading,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,12 @@ typedef EnterSeedPhraseConfirmCallback = void Function(String phrase);
/// Cubit that manages the state of the seed phrase entering page.
class EnterSeedPhraseCubit extends Cubit<EnterSeedPhraseState>
with ConnectionMixin {
EnterSeedPhraseCubit(this.confirmCallback)
EnterSeedPhraseCubit(this.context, this.confirmCallback)
: super(const EnterSeedPhraseState.initial());

final _log = Logger('EnterSeedPhraseCubit');

final BuildContext context;
final EnterSeedPhraseConfirmCallback confirmCallback;

final formKey = GlobalKey<FormState>();
Expand Down Expand Up @@ -158,7 +159,7 @@ class EnterSeedPhraseCubit extends Cubit<EnterSeedPhraseState>
}

Future<void> confirmAction() async {
if (!await checkConnection()) {
if (!await checkConnection(context)) {
return;
}

Expand Down Expand Up @@ -341,6 +342,7 @@ class EnterSeedPhraseCubit extends Cubit<EnterSeedPhraseState>
void _showValidateError(String message) {
inject<MessengerService>().show(
Message.error(
context: context,
message: message,
debounceTime: defaultInfoMessageDebounceDuration,
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class EnterSeedPhrasePage extends StatelessWidget {
final theme = context.themeStyleV2;
return BlocProvider<EnterSeedPhraseCubit>(
create: (context) => EnterSeedPhraseCubit(
context,
// ignore: prefer-extracting-callbacks
(phrase) {
final path =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@ class ImportWalletScreenModel extends ElementaryModel with ConnectionMixin {

final NekotonRepository nekotonRepository;

void showValidateError(String message) {
void showValidateError(BuildContext context, String message) {
messengerService.show(
Message.error(
context: context,
message: message,
debounceTime: defaultInfoMessageDebounceDuration,
),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// ignore_for_file: use_build_context_synchronously

import 'package:app/app/router/app_route.dart';
import 'package:app/app/router/routs/add_seed/add_seed.dart';
import 'package:app/core/wm/custom_wm.dart';
Expand Down Expand Up @@ -42,7 +44,7 @@ class ImportWalletScreenWidgetModel
int? _currentValue;

Future<void> onPressedImport() async {
if (!await model.checkConnection()) {
if (!await model.checkConnection(context)) {
return;
}

Expand Down Expand Up @@ -73,7 +75,7 @@ class ImportWalletScreenWidgetModel
preserveQueryParams: true,
);
} else {
model.showValidateError(LocaleKeys.incorrectWordsFormat.tr());
model.showValidateError(context, LocaleKeys.incorrectWordsFormat.tr());
}
} on Exception catch (e, s) {
_log.severe('confirmAction', e, s);
Expand All @@ -83,7 +85,7 @@ class ImportWalletScreenWidgetModel
error = LocaleKeys.wrongSeed.tr();
}
if (error != null) {
model.showValidateError(error);
model.showValidateError(context, error);
}
}

Expand Down Expand Up @@ -111,7 +113,7 @@ class ImportWalletScreenWidgetModel
}

if (seed.isEmpty) {
model.showValidateError(LocaleKeys.incorrectWordsFormat.tr());
model.showValidateError(context, LocaleKeys.incorrectWordsFormat.tr());
return;
} else {
final halfLength = (seed.wordsCount / 2).floor();
Expand Down
Loading
Loading