1
0
mirror of https://gitlab.com/comunic/comunicmobile synced 2024-11-22 21:09:21 +00:00
comunicmobile/lib/ui/routes/main_route/main_route.dart
2022-03-12 10:13:32 +01:00

229 lines
7.3 KiB
Dart

import 'package:comunic/helpers/account_helper.dart';
import 'package:comunic/models/conversation.dart';
import 'package:comunic/models/conversation_message.dart';
import 'package:comunic/ui/routes/conversation_message_stats_route.dart';
import 'package:comunic/ui/routes/conversation_route.dart';
import 'package:comunic/ui/routes/main_route/page_info.dart';
import 'package:comunic/ui/routes/settings/account_settings_route.dart';
import 'package:comunic/ui/routes/update_conversation_route.dart';
import 'package:comunic/ui/screens/call_screen.dart';
import 'package:comunic/ui/screens/conversations_list_screen.dart';
import 'package:comunic/ui/screens/friends_list_screen.dart';
import 'package:comunic/ui/screens/group_screen.dart';
import 'package:comunic/ui/screens/groups_list_screen.dart';
import 'package:comunic/ui/screens/newest_posts.dart';
import 'package:comunic/ui/screens/notifications_screen.dart';
import 'package:comunic/ui/screens/other_friends_lists_screen.dart';
import 'package:comunic/ui/screens/search_screen.dart';
import 'package:comunic/ui/screens/user_access_denied_screen.dart';
import 'package:comunic/ui/screens/user_page_screen.dart';
import 'package:comunic/utils/account_utils.dart';
import 'package:comunic/utils/intl_utils.dart';
import 'package:comunic/utils/ui_utils.dart';
import 'package:flutter/material.dart';
/// Abstract main application route
///
/// This mixin contains methods available in all display modes
///
/// @author Pierre Hubert
/// Main controller key statically shared across application
///
/// Do not use it directly to avoid context leak, instead use the access method
/// [MainController.of]
final mainControllerKey = GlobalKey<MainController>();
mixin MainRoute implements StatefulWidget {}
/// Public interface of home controller
abstract class MainController extends State<MainRoute> {
final _pagesStack = <PageInfo>[];
/// Default page of the application
PageInfo get defaultPage;
/// Get the current page being active in the application
PageInfo get currentPage => _pagesStack.last;
/// Get the current number of page in application stack
int get numberOfPages => _pagesStack.length;
/// Get current instance of Home controller
///
/// A future implementation might need context again, that is why it is required
static MainController? of(BuildContext context) {
return mainControllerKey.currentState;
}
@override
void initState() {
super.initState();
_pagesStack.add(defaultPage);
}
/// Push a new page
void pushPage(PageInfo page) {
popUntilMainRoute();
setState(() => _pagesStack.add(page));
}
/// Pop current page. Do not call this method directly.
@protected
void doPopPage() {
if (_pagesStack.length > 0) setState(() => _pagesStack.removeLast());
}
/// Pop until main route is reached
void popUntilMainRoute() => Navigator.of(context).popUntil((settings) =>
ModalRoute.of(context)!.isCurrent || !ModalRoute.of(context)!.isActive);
/// Go to the previous page (use for [WillPop] widget)
@protected
Future<bool> willPop() async {
if (numberOfPages == 1) return true;
popPage();
return false;
}
/// Open notifications page
void openNotificationsPage() => pushPage(PageInfo(
type: PageType.NOTIFICATIONS_PAGE, child: NotificationsScreen()));
/// Open conversations page
void openConversationsPage() => pushPage(PageInfo(
type: PageType.CONVERSATIONS_LIST_PAGE,
child: ConversationsListScreen()));
/// Open latest posts page
void openLatestPostsPage() => pushPage(
PageInfo(type: PageType.LATEST_POSTS_PAGE, child: NewestPostsScreen()));
/// Open user page
void openUserPage(int userID) {
final key = GlobalKey();
pushPage(PageInfo(
type: PageType.USER_PAGE,
child: UserPageScreen(userID: userID, key: key),
id: userID,
widgetKey: key));
}
void openUserAccessDeniedPage(int userID) =>
pushPage(PageInfo(child: UserAccessDeniedScreen(userID: userID)));
/// Open current user page
void openCurrentUserPage() => this.openUserPage(userID()!);
/// Open a specific group page specified by its [groupID]
///
/// [conversationID] is an optional parameter specifying a conversation
/// that should be opened instead of posts thread
void openGroup(int groupID, {int? conversationID}) => pushPage(PageInfo(
type: PageType.GROUP_PAGE,
child: GroupPageScreen(
groupID: groupID,
conversationID: conversationID,
),
id: groupID));
/// Display the list of friends of current user
void openFriendsList() => pushPage(PageInfo(
type: PageType.FRIENDS_LIST_PAGE,
child: FriendsListScreen(),
canShowAsDialog: true,
));
/// Open search page
void openSearchPage() => pushPage(PageInfo(child: SearchScreen()));
/// Open groups list page
void openGroupsListPage() => pushPage(PageInfo(child: GroupsListScreen()));
/// Display the list of friends of a user
void openUserFriendsList(int? id) {
if (id != userID())
pushPage(PageInfo(
child: OtherUserFriendsListScreen(userID: id!),
canShowAsDialog: true,
));
else
openFriendsList();
}
/// Push a new widget
void push(Widget w,
{bool hideNavBar = false, bool canShowAsDialog = false}) =>
pushPage(PageInfo(
child: w, hideNavBar: hideNavBar, canShowAsDialog: canShowAsDialog));
/// Open a conversation in its context (in group page for group conversations)
void openConversation(Conversation conv, {fullScreen: false}) {
if (conv.isGroupConversation)
openGroup(conv.groupID!, conversationID: conv.id);
else
openConversationById(conv.id!, fullScreen: fullScreen);
}
/// Open a conversation
void openConversationById(int convID, {fullScreen: false}) =>
pushPage(PageInfo(
type: PageType.CONVERSATION_PAGE,
id: convID,
child: ConversationRoute(conversationID: convID),
hideNavBar: true,
));
/// Open conversation settings route
void openConversationSettingsRoute(Conversation conv) => pushPage(PageInfo(
child: UpdateConversationRoute(
conversationID: conv.id!,
),
canShowAsDialog: true,
hideNavBar: true,
));
/// Open a conversation message statistics page
void openConversationMessageStats(
Conversation conv, ConversationMessage message) =>
pushPage(PageInfo(
child: ConversationMessageStatsRoute(
conv: conv,
message: message,
),
hideNavBar: true,
canShowAsDialog: true,
));
/// Start a call for a given conversation
void startCall(int convID) =>
pushPage(PageInfo(child: CallScreen(convID: convID), hideNavBar: true));
/// Open settings
void openSettings() => Navigator.of(context)
.push(MaterialPageRoute(builder: (c) => AccountSettingsRoute()));
/// Handle logout requests
void requestLogout() async {
if (!await showConfirmDialog(
context: context,
message: tr("Do you really want to sign out from the application ?"),
title: tr("Sign out"))) return;
popUntilMainRoute();
await AccountHelper().signOut();
}
/// Pop current page. Last page can not be popped
///
/// If the current route is not the main route, we pop one page
void popPage() {
if (!ModalRoute.of(context)!.isCurrent)
Navigator.of(context).pop();
else
doPopPage();
}
}