refactor: use gorouter for navigation

This commit is contained in:
Gordon Hayes
2022-10-17 15:01:03 +02:00
parent 852bb68f1b
commit bea73ec6a1
27 changed files with 922 additions and 915 deletions
+117 -125
View File
@@ -1,135 +1,127 @@
import 'package:collection/collection.dart';
import 'package:example/pages/advanced_options_page.dart';
import 'package:example/pages/channel_list_page.dart';
import 'package:example/pages/channel_page.dart';
import 'package:example/pages/chat_info_screen.dart';
import 'package:example/pages/group_chat_details_screen.dart';
import 'package:example/pages/group_info_screen.dart';
import 'package:example/pages/new_chat_screen.dart';
import 'package:example/pages/new_group_chat_screen.dart';
import 'package:example/pages/thread_page.dart';
import 'package:example/routes/routes.dart';
import 'package:example/state/new_group_chat_state.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
import '../app.dart';
import '../pages/advanced_options_page.dart';
import '../pages/channel_page.dart';
import '../pages/chat_info_screen.dart';
import '../pages/choose_user_page.dart';
import '../pages/group_chat_details_screen.dart';
import '../pages/group_info_screen.dart';
import '../pages/home_page.dart';
import '../pages/new_chat_screen.dart';
import '../pages/new_group_chat_screen.dart';
import '../pages/thread_page.dart';
import 'routes.dart';
class AppRoutes {
/// Add entry for new route here
static Route<dynamic>? generateRoute(RouteSettings settings) {
final args = settings.arguments;
switch (settings.name) {
case Routes.APP:
return MaterialPageRoute(
settings: RouteSettings(arguments: args, name: Routes.APP),
builder: (_) {
return const StreamChatSampleApp();
});
case Routes.HOME:
return MaterialPageRoute(
settings: RouteSettings(arguments: args, name: Routes.HOME),
builder: (_) {
final homePageArgs = args as HomePageArgs;
return HomePage(
chatClient: homePageArgs.chatClient,
);
});
case Routes.CHOOSE_USER:
return MaterialPageRoute(
settings: RouteSettings(arguments: args, name: Routes.CHOOSE_USER),
builder: (_) {
return const ChooseUserPage();
});
case Routes.ADVANCED_OPTIONS:
return MaterialPageRoute(
settings:
RouteSettings(arguments: args, name: Routes.ADVANCED_OPTIONS),
builder: (_) => const AdvancedOptionsPage(),
);
case Routes.CHANNEL_PAGE:
return MaterialPageRoute(
settings: RouteSettings(arguments: args, name: Routes.CHANNEL_PAGE),
builder: (context) {
final channelPageArgs = args as ChannelPageArgs;
final initialMessage = channelPageArgs.initialMessage;
final appRoutes = [
GoRoute(
name: Routes.CHANNEL_LIST_PAGE.name,
path: Routes.CHANNEL_LIST_PAGE.path,
builder: (BuildContext context, GoRouterState state) =>
const ChannelListPage(),
routes: [
GoRoute(
name: Routes.CHANNEL_PAGE.name,
path: Routes.CHANNEL_PAGE.path,
builder: (context, state) {
final channel =
StreamChat.of(context).client.state.channels[state.params['cid']];
final messageId = state.queryParams['mid'];
final parentId = state.queryParams['pid'];
return StreamChannel(
channel: channelPageArgs.channel!,
initialMessageId: initialMessage?.id,
child: Builder(
builder: (context) {
final parentId = initialMessage?.parentId;
Message? parentMessage;
if (parentId != null) {
final channel = StreamChannel.of(context).channel;
parentMessage = channel.state!.messages
.firstWhereOrNull((it) => it.id == parentId);
}
if (parentMessage != null) {
return ThreadPage(parent: parentMessage);
}
return ChannelPage(
highlightInitialMessage:
channelPageArgs.initialMessage != null,
);
},
),
);
},
);
case Routes.NEW_CHAT:
return MaterialPageRoute(
settings: RouteSettings(arguments: args, name: Routes.NEW_CHAT),
builder: (_) {
return const NewChatScreen();
});
case Routes.NEW_GROUP_CHAT:
return MaterialPageRoute(
settings:
RouteSettings(arguments: args, name: Routes.NEW_GROUP_CHAT),
builder: (_) {
return const NewGroupChatScreen();
});
case Routes.NEW_GROUP_CHAT_DETAILS:
return MaterialPageRoute(
settings: RouteSettings(
arguments: args, name: Routes.NEW_GROUP_CHAT_DETAILS),
builder: (_) {
return GroupChatDetailsScreen(
selectedUsers: args as List<User>?,
Message? parentMessage;
if (parentId != null) {
parentMessage = channel?.state!.messages
.firstWhereOrNull((it) => it.id == parentId);
}
return StreamChannel(
channel: channel!,
initialMessageId: messageId,
child: Builder(
builder: (context) {
return (parentMessage != null)
? ThreadPage(parent: parentMessage)
: ChannelPage(
highlightInitialMessage: messageId != null,
);
},
),
);
},
routes: [
GoRoute(
name: Routes.CHAT_INFO_SCREEN.name,
path: Routes.CHAT_INFO_SCREEN.path,
builder: (BuildContext context, GoRouterState state) {
final channel = StreamChat.of(context)
.client
.state
.channels[state.params['cid']];
return StreamChannel(
channel: channel!,
child: ChatInfoScreen(
user: state.extra as User?,
messageTheme: StreamChatTheme.of(context).ownMessageTheme,
),
);
});
case Routes.CHAT_INFO_SCREEN:
return MaterialPageRoute(
settings:
RouteSettings(arguments: args, name: Routes.CHAT_INFO_SCREEN),
builder: (context) {
return ChatInfoScreen(
user: args as User?,
messageTheme: StreamChatTheme.of(context).ownMessageTheme,
},
),
GoRoute(
name: Routes.GROUP_INFO_SCREEN.name,
path: Routes.GROUP_INFO_SCREEN.path,
builder: (BuildContext context, GoRouterState state) {
final channel = StreamChat.of(context)
.client
.state
.channels[state.params['cid']];
return StreamChannel(
channel: channel!,
child: GroupInfoScreen(
messageTheme: StreamChatTheme.of(context).ownMessageTheme,
),
);
});
case Routes.GROUP_INFO_SCREEN:
return MaterialPageRoute(
settings:
RouteSettings(arguments: args, name: Routes.GROUP_INFO_SCREEN),
builder: (context) {
return GroupInfoScreen(
messageTheme: StreamChatTheme.of(context).ownMessageTheme,
);
});
case Routes.CHANNEL_LIST_PAGE:
return MaterialPageRoute(
settings:
RouteSettings(arguments: args, name: Routes.CHANNEL_LIST_PAGE),
builder: (context) {
return const ChannelListPage();
});
// Default case, should not reach here.
default:
return null;
}
}
}
},
),
],
),
],
),
GoRoute(
name: Routes.NEW_CHAT.name,
path: Routes.NEW_CHAT.path,
builder: (BuildContext context, GoRouterState state) {
return const NewChatScreen();
},
),
GoRoute(
name: Routes.NEW_GROUP_CHAT.name,
path: Routes.NEW_GROUP_CHAT.path,
builder: (BuildContext context, GoRouterState state) {
return const NewGroupChatScreen();
},
),
GoRoute(
name: Routes.NEW_GROUP_CHAT_DETAILS.name,
path: Routes.NEW_GROUP_CHAT_DETAILS.path,
builder: (BuildContext context, GoRouterState state) {
final groupChatState = state.extra as NewGroupChatState;
return GroupChatDetailsScreen(groupChatState: groupChatState);
},
),
GoRoute(
name: Routes.CHOOSE_USER.name,
path: Routes.CHOOSE_USER.path,
builder: (BuildContext context, GoRouterState state) =>
const ChooseUserPage(),
),
GoRoute(
name: Routes.ADVANCED_OPTIONS.name,
path: Routes.ADVANCED_OPTIONS.path,
builder: (BuildContext context, GoRouterState state) =>
const AdvancedOptionsPage(),
),
];
+38 -11
View File
@@ -1,16 +1,43 @@
// ignore_for_file: constant_identifier_names
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
/// Application routes
abstract class Routes {
static const String APP = '/app';
static const String HOME = '/home';
static const String CHOOSE_USER = '/choose_user';
static const String ADVANCED_OPTIONS = '/advance_options';
static const String CHANNEL_PAGE = '/channel_page';
static const String NEW_CHAT = '/new_chat';
static const String NEW_GROUP_CHAT = '/new_group_chat';
static const String NEW_GROUP_CHAT_DETAILS = '/new_group_chat_details';
static const String CHAT_INFO_SCREEN = '/chat_info_screen';
static const String GROUP_INFO_SCREEN = '/group_info_screen';
static const String CHANNEL_LIST_PAGE = '/channel_list_page';
static const RouteConfig CHOOSE_USER =
RouteConfig(name: 'choose_user', path: '/users');
static const RouteConfig ADVANCED_OPTIONS =
RouteConfig(name: 'advanced_options', path: '/options');
static const ChannelRouteConfig CHANNEL_PAGE =
ChannelRouteConfig(name: 'channel_page', path: 'channel/:cid');
static const RouteConfig NEW_CHAT =
RouteConfig(name: 'new_chat', path: '/new_chat');
static const RouteConfig NEW_GROUP_CHAT =
RouteConfig(name: 'new_group_chat', path: '/new_group_chat');
static const RouteConfig NEW_GROUP_CHAT_DETAILS = RouteConfig(
name: 'new_group_chat_details', path: '/new_group_chat_details');
static const ChannelRouteConfig CHAT_INFO_SCREEN =
ChannelRouteConfig(name: 'chat_info_screen', path: 'chat_info_screen');
static const ChannelRouteConfig GROUP_INFO_SCREEN =
ChannelRouteConfig(name: 'group_info_screen', path: 'group_info_screen');
static const RouteConfig CHANNEL_LIST_PAGE =
RouteConfig(name: 'channel_list_page', path: '/channels');
}
class RouteConfig {
final String name;
final String path;
const RouteConfig({required this.name, required this.path});
}
class ChannelRouteConfig extends RouteConfig {
const ChannelRouteConfig({required super.name, required super.path});
Map<String, String> params(Channel channel) => {'cid': channel.cid!};
Map<String, String> queryParams(Message message) => {
'mid': message.id,
if (message.parentId != null) 'pid': message.parentId!
};
}