Skip to content

Commit

Permalink
feat: add error page
Browse files Browse the repository at this point in the history
  • Loading branch information
Julian KOUNE authored and hoangdat committed Sep 20, 2023
1 parent ff378ca commit 6dddb42
Show file tree
Hide file tree
Showing 10 changed files with 370 additions and 11 deletions.
161 changes: 161 additions & 0 deletions assets/images/ic_error_page.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions assets/images/ic_error_page_background.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 4 additions & 1 deletion assets/l10n/intl_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -2713,5 +2713,8 @@
}
},
"notInAChatYet": "You're not in a chat yet",
"blankChatTitle": "Choose a chat or hit #EditIcon# to make one."
"blankChatTitle": "Choose a chat or hit #EditIcon# to make one.",
"errorPageTitle": "Something's not right",
"errorPageDescription": "That page doesn't exist.",
"errorPageButton": "Back to chat"
}
8 changes: 8 additions & 0 deletions lib/config/go_routes/go_router.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import 'package:fluffychat/pages/chat_blank/chat_blank.dart';
import 'package:fluffychat/pages/chat_details/chat_details.dart';
import 'package:fluffychat/pages/chat_draft/draft_chat.dart';
import 'package:fluffychat/pages/chat_encryption_settings/chat_encryption_settings.dart';
import 'package:fluffychat/pages/error_page/error_page.dart';
import 'package:fluffychat/pages/homeserver_picker/homeserver_picker.dart';
import 'package:fluffychat/pages/share/share.dart';
import 'package:fluffychat/pages/story/story_page.dart';
Expand Down Expand Up @@ -103,6 +104,13 @@ abstract class AppRoutes {
const LogViewer(),
),
),
GoRoute(
path: '/error',
pageBuilder: (context, state) => defaultPageBuilder(
context,
const ErrorPage(),
),
),
ShellRoute(
pageBuilder: (context, state, child) => defaultPageBuilder(
context,
Expand Down
6 changes: 5 additions & 1 deletion lib/pages/chat/chat.dart
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,10 @@ class ChatController extends State<Chat>
);
super.initState();
SchedulerBinding.instance.addPostFrameCallback((_) async {
if (room == null) {
return context.go("/error");
}

_askToAcceptInvitation();
if (shareFile != null && room != null && shareFile!.filePath != null) {
final sendFileInteractor = getIt.get<SendFileInteractor>();
Expand All @@ -323,7 +327,7 @@ class ChatController extends State<Chat>
}

void _askToAcceptInvitation() async {
if (room!.membership != Membership.invite) return;
if (room?.membership != Membership.invite) return;

final result = await showDialog<DialogAcceptInviteResult>(
context: context,
Expand Down
10 changes: 1 addition & 9 deletions lib/pages/chat/chat_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -115,15 +115,7 @@ class ChatView extends StatelessWidget {
controller.sendingClient ??= client;
controller.room = controller.sendingClient!.getRoomById(controller.roomId!);
if (controller.room == null) {
return Scaffold(
appBar: AppBar(
toolbarHeight: 120,
title: Text(L10n.of(context)!.oopsSomethingWentWrong),
),
body: Center(
child: Text(L10n.of(context)!.youAreNoLongerParticipatingInThisChat),
),
);
return const SizedBox.shrink();
}

final bottomSheetPadding = FluffyThemes.isColumnMode(context) ? 16.0 : 8.0;
Expand Down
114 changes: 114 additions & 0 deletions lib/pages/error_page/error_page.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import 'package:fluffychat/pages/error_page/error_page_style.dart';
import 'package:fluffychat/resource/image_paths.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:go_router/go_router.dart';

class ErrorPage extends StatelessWidget {
const ErrorPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
// Add invisible appbar to make status bar on Android tablets bright.
appBar: AppBar(
automaticallyImplyLeading: false,
elevation: 0,
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
),
extendBodyBehindAppBar: true,
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ErrorPageStyle.responsiveUtils.isMobile(context)
? const _ErrorPageBackgroundMobile()
: const _ErrorPageBackgroundWeb(),
const _ErrorPageText(),
const _ErrorPageBackButton(),
],
),
),
);
}
}

class _ErrorPageBackgroundWeb extends StatelessWidget {
const _ErrorPageBackgroundWeb();

@override
Widget build(BuildContext context) {
return Stack(
alignment: Alignment.bottomCenter,
children: [
SvgPicture.asset(
ImagePaths.icErrorPageBackground,
colorFilter: ErrorPageStyle.backgroundColorFilter(context),
fit: BoxFit.contain,
),
SvgPicture.asset(
ImagePaths.icErrorPage,
width: ErrorPageStyle.backgroundIconWidthWeb,
fit: BoxFit.contain,
),
],
);
}
}

class _ErrorPageBackgroundMobile extends StatelessWidget {
const _ErrorPageBackgroundMobile();

@override
Widget build(BuildContext context) {
return SvgPicture.asset(
ImagePaths.icErrorPage,
width: ErrorPageStyle.backgroundIconWidthMobile,
fit: BoxFit.contain,
);
}
}

class _ErrorPageBackButton extends StatelessWidget {
const _ErrorPageBackButton();

@override
Widget build(BuildContext context) {
return TextButton.icon(
icon: const Icon(Icons.arrow_back),
onPressed: () => _goToRooms,
label: Text(
L10n.of(context)!.errorPageButton,
),
style: ErrorPageStyle.buttonStyle(context),
);
}

void _goToRooms(BuildContext context) {
context.go('/rooms');
}
}

class _ErrorPageText extends StatelessWidget {
const _ErrorPageText();

@override
Widget build(BuildContext context) {
return Padding(
padding: ErrorPageStyle.textPadding,
child: Column(
children: [
Text(
L10n.of(context)!.errorPageTitle,
style: ErrorPageStyle.titleTextStyle(context),
),
const SizedBox(height: ErrorPageStyle.textsGap),
Text(
L10n.of(context)!.errorPageDescription,
style: ErrorPageStyle.descriptionTextStyle(context),
),
],
),
);
}
}
63 changes: 63 additions & 0 deletions lib/pages/error_page/error_page_style.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import 'package:fluffychat/di/global/get_it_initializer.dart';
import 'package:fluffychat/utils/responsive/responsive_utils.dart';
import 'package:flutter/material.dart';
import 'package:linagora_design_flutter/linagora_design_flutter.dart';

class ErrorPageStyle {
static final ResponsiveUtils responsiveUtils = getIt.get<ResponsiveUtils>();

static ColorFilter backgroundColorFilter(BuildContext context) =>
ColorFilter.mode(
Theme.of(context).colorScheme.primaryContainer,
BlendMode.srcATop,
);

static const double backgroundIconWidthWeb = 448.0;
static const double backgroundIconWidthMobile = 280.0;

static const EdgeInsets textPadding = EdgeInsets.symmetric(vertical: 32.0);

static TextStyle? titleTextStyle(BuildContext context) =>
ErrorPageStyle.responsiveUtils.isMobile(context)
? Theme.of(context).textTheme.headlineSmall?.copyWith(
fontWeight: FontWeight.w600,
color: Theme.of(context).colorScheme.onSurface,
)
: Theme.of(context).textTheme.headlineLarge?.copyWith(
fontWeight: FontWeight.w600,
color: Theme.of(context).colorScheme.onSurface,
);
static TextStyle? descriptionTextStyle(BuildContext context) =>
ErrorPageStyle.responsiveUtils.isMobile(context)
? Theme.of(context).textTheme.labelLarge?.copyWith(
fontWeight: FontWeight.w500,
color: LinagoraRefColors.material().tertiary[20],
)
: Theme.of(context).textTheme.bodyLarge?.copyWith(
fontWeight: FontWeight.w500,
color: LinagoraRefColors.material().tertiary[20],
);

static ButtonStyle buttonStyle(BuildContext context) => ButtonStyle(
iconSize: MaterialStateProperty.all<double>(18),
textStyle: MaterialStateProperty.all(
Theme.of(context).textTheme.labelLarge?.copyWith(
fontWeight: FontWeight.w500,
color: Theme.of(context).colorScheme.onPrimary,
),
),
backgroundColor: MaterialStateProperty.all<Color>(
Theme.of(context).colorScheme.primary,
),
foregroundColor: MaterialStateProperty.all<Color>(
Theme.of(context).colorScheme.onPrimary,
),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(100),
),
),
);

static const double textsGap = 12.0;
}
3 changes: 3 additions & 0 deletions lib/resource/image_paths.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ class ImagePaths {
static String get icUsersOutline => _getImagePath('ic_users_outline.svg');
static String get icReply => _getImagePath('ic_reply.svg');
static String get icEmptyPage => _getImagePath('ic_empty_page.svg');
static String get icErrorPage => _getImagePath('ic_error_page.svg');
static String get icErrorPageBackground =>
_getImagePath('ic_error_page_background.svg');

static String _getImagePath(String imageName) {
return AssetsPaths.images + imageName;
Expand Down
4 changes: 4 additions & 0 deletions lib/widgets/twake_app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ class TwakeApp extends StatefulWidget {
static final GoRouter router = GoRouter(
routes: AppRoutes.routes,
debugLogDiagnostics: true,
onException: (context, state, router) {
Logs().e('GoRouter exception: ${state.error}');
return router.go('/error');
},
);

@override
Expand Down

0 comments on commit 6dddb42

Please sign in to comment.