2020-05-10 16:29:43 +00:00
|
|
|
import 'package:comunic/helpers/account_helper.dart';
|
2021-03-11 16:27:20 +00:00
|
|
|
import 'package:comunic/models/conversation.dart';
|
|
|
|
import 'package:comunic/models/conversation_message.dart';
|
|
|
|
import 'package:comunic/ui/routes/conversation_message_stats_route.dart';
|
2020-05-10 16:29:43 +00:00
|
|
|
import 'package:comunic/ui/routes/conversation_route.dart';
|
|
|
|
import 'package:comunic/ui/routes/main_route/page_info.dart';
|
2020-05-12 16:42:33 +00:00
|
|
|
import 'package:comunic/ui/routes/settings/account_settings_route.dart';
|
2021-04-06 16:41:51 +00:00
|
|
|
import 'package:comunic/ui/routes/update_conversation_route.dart';
|
2020-05-10 16:29:43 +00:00
|
|
|
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';
|
2020-05-05 11:21:37 +00:00
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
|
|
|
/// Abstract main application route
|
|
|
|
///
|
|
|
|
/// This mixin contains methods available in all display modes
|
|
|
|
///
|
|
|
|
/// @author Pierre Hubert
|
|
|
|
|
2020-05-09 12:07:14 +00:00
|
|
|
/// 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>();
|
|
|
|
|
2020-05-05 11:21:37 +00:00
|
|
|
mixin MainRoute implements StatefulWidget {}
|
|
|
|
|
|
|
|
/// Public interface of home controller
|
2020-05-09 12:18:09 +00:00
|
|
|
abstract class MainController extends State<MainRoute> {
|
2021-03-13 14:28:34 +00:00
|
|
|
final _pagesStack = <PageInfo>[];
|
2020-05-10 16:29:43 +00:00
|
|
|
|
|
|
|
/// 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;
|
|
|
|
|
2020-05-05 11:21:37 +00:00
|
|
|
/// Get current instance of Home controller
|
2022-03-10 18:39:57 +00:00
|
|
|
static MainController? of(BuildContext context) {
|
2020-05-09 12:07:14 +00:00
|
|
|
assert(context != null); // A future implementation might need context again
|
|
|
|
return mainControllerKey.currentState;
|
|
|
|
}
|
2020-05-05 11:21:37 +00:00
|
|
|
|
2020-05-10 16:29:43 +00:00
|
|
|
@override
|
|
|
|
void initState() {
|
|
|
|
super.initState();
|
|
|
|
_pagesStack.add(defaultPage);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Push a new page
|
2020-05-13 16:36:20 +00:00
|
|
|
void pushPage(PageInfo page) {
|
|
|
|
popUntilMainRoute();
|
|
|
|
setState(() => _pagesStack.add(page));
|
|
|
|
}
|
2020-05-10 16:29:43 +00:00
|
|
|
|
|
|
|
/// Pop current page. Do not call this method directly.
|
|
|
|
@protected
|
|
|
|
void doPopPage() {
|
|
|
|
if (_pagesStack.length > 0) setState(() => _pagesStack.removeLast());
|
|
|
|
}
|
|
|
|
|
2020-05-09 12:56:33 +00:00
|
|
|
/// Pop until main route is reached
|
|
|
|
void popUntilMainRoute() => Navigator.of(context).popUntil((settings) =>
|
2022-03-10 18:39:57 +00:00
|
|
|
ModalRoute.of(context)!.isCurrent || !ModalRoute.of(context)!.isActive);
|
2020-05-09 12:56:33 +00:00
|
|
|
|
2020-05-11 16:32:58 +00:00
|
|
|
/// Go to the previous page (use for [WillPop] widget)
|
|
|
|
@protected
|
|
|
|
Future<bool> willPop() async {
|
|
|
|
if (numberOfPages == 1) return true;
|
|
|
|
|
|
|
|
popPage();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-05-10 16:29:43 +00:00
|
|
|
/// 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()));
|
|
|
|
|
2020-05-05 11:21:37 +00:00
|
|
|
/// Open user page
|
2020-05-10 16:29:43 +00:00
|
|
|
void openUserPage(int userID) => pushPage(PageInfo(
|
2020-05-11 11:38:51 +00:00
|
|
|
type: PageType.USER_PAGE,
|
|
|
|
child: UserPageScreen(userID: userID),
|
|
|
|
id: userID));
|
2020-05-10 16:29:43 +00:00
|
|
|
|
|
|
|
void openUserAccessDeniedPage(int userID) =>
|
|
|
|
pushPage(PageInfo(child: UserAccessDeniedScreen(userID: userID)));
|
2020-05-05 11:21:37 +00:00
|
|
|
|
2020-05-10 16:29:43 +00:00
|
|
|
/// Open current user page
|
2022-03-10 18:39:57 +00:00
|
|
|
void openCurrentUserPage() => this.openUserPage(userID()!);
|
2020-05-05 11:21:37 +00:00
|
|
|
|
|
|
|
/// Open a specific group page specified by its [groupID]
|
2021-04-06 16:22:45 +00:00
|
|
|
///
|
|
|
|
/// [conversationID] is an optional parameter specifying a conversation
|
|
|
|
/// that should be opened instead of posts thread
|
2022-03-10 18:39:57 +00:00
|
|
|
void openGroup(int groupID, {int? conversationID}) => pushPage(PageInfo(
|
2020-05-11 11:50:13 +00:00
|
|
|
type: PageType.GROUP_PAGE,
|
2021-04-06 16:22:45 +00:00
|
|
|
child: GroupPageScreen(
|
|
|
|
groupID: groupID,
|
|
|
|
conversationID: conversationID,
|
|
|
|
),
|
2020-05-11 11:50:13 +00:00
|
|
|
id: groupID));
|
2020-05-10 16:29:43 +00:00
|
|
|
|
|
|
|
/// Display the list of friends of current user
|
2020-05-16 15:36:52 +00:00
|
|
|
void openFriendsList() => pushPage(PageInfo(
|
|
|
|
type: PageType.FRIENDS_LIST_PAGE,
|
|
|
|
child: FriendsListScreen(),
|
|
|
|
canShowAsDialog: true,
|
|
|
|
));
|
2020-05-10 16:29:43 +00:00
|
|
|
|
|
|
|
/// Open search page
|
|
|
|
void openSearchPage() => pushPage(PageInfo(child: SearchScreen()));
|
|
|
|
|
|
|
|
/// Open groups list page
|
|
|
|
void openGroupsListPage() => pushPage(PageInfo(child: GroupsListScreen()));
|
2020-05-05 11:21:37 +00:00
|
|
|
|
|
|
|
/// Display the list of friends of a user
|
2022-03-10 18:39:57 +00:00
|
|
|
void openUserFriendsList(int? id) {
|
2020-05-16 15:24:47 +00:00
|
|
|
if (id != userID())
|
2020-05-16 15:36:52 +00:00
|
|
|
pushPage(PageInfo(
|
2022-03-10 18:39:57 +00:00
|
|
|
child: OtherUserFriendsListScreen(userID: id!),
|
2020-05-16 15:36:52 +00:00
|
|
|
canShowAsDialog: true,
|
|
|
|
));
|
2020-05-16 15:24:47 +00:00
|
|
|
else
|
|
|
|
openFriendsList();
|
|
|
|
}
|
2020-05-10 16:29:43 +00:00
|
|
|
|
|
|
|
/// Push a new widget
|
|
|
|
void push(Widget w,
|
|
|
|
{bool hideNavBar = false, bool canShowAsDialog = false}) =>
|
|
|
|
pushPage(PageInfo(
|
|
|
|
child: w, hideNavBar: hideNavBar, canShowAsDialog: canShowAsDialog));
|
|
|
|
|
2021-04-06 16:22:45 +00:00
|
|
|
/// Open a conversation in its context (in group page for group conversations)
|
2021-04-07 14:35:18 +00:00
|
|
|
void openConversation(Conversation conv, {fullScreen: false}) {
|
2021-04-06 16:22:45 +00:00
|
|
|
if (conv.isGroupConversation)
|
2022-03-10 18:39:57 +00:00
|
|
|
openGroup(conv.groupID!, conversationID: conv.id);
|
2021-04-06 16:22:45 +00:00
|
|
|
else
|
2022-03-10 18:39:57 +00:00
|
|
|
openConversationById(conv.id!, fullScreen: fullScreen);
|
2021-04-06 16:22:45 +00:00
|
|
|
}
|
|
|
|
|
2020-05-10 16:29:43 +00:00
|
|
|
/// Open a conversation
|
2021-04-06 16:22:45 +00:00
|
|
|
void openConversationById(int convID, {fullScreen: false}) =>
|
|
|
|
pushPage(PageInfo(
|
2020-05-10 16:29:43 +00:00
|
|
|
type: PageType.CONVERSATION_PAGE,
|
2020-05-11 16:12:49 +00:00
|
|
|
id: convID,
|
2020-05-10 16:29:43 +00:00
|
|
|
child: ConversationRoute(conversationID: convID),
|
|
|
|
hideNavBar: true,
|
|
|
|
));
|
|
|
|
|
2021-04-06 16:41:51 +00:00
|
|
|
/// Open conversation settings route
|
|
|
|
void openConversationSettingsRoute(Conversation conv) => pushPage(PageInfo(
|
|
|
|
child: UpdateConversationRoute(
|
2022-03-10 18:39:57 +00:00
|
|
|
conversationID: conv.id!,
|
2021-04-06 16:41:51 +00:00
|
|
|
),
|
|
|
|
canShowAsDialog: true,
|
|
|
|
hideNavBar: true,
|
|
|
|
));
|
|
|
|
|
2021-03-11 16:27:20 +00:00
|
|
|
/// Open a conversation message statistics page
|
|
|
|
void openConversationMessageStats(
|
|
|
|
Conversation conv, ConversationMessage message) =>
|
|
|
|
pushPage(PageInfo(
|
|
|
|
child: ConversationMessageStatsRoute(
|
|
|
|
conv: conv,
|
|
|
|
message: message,
|
|
|
|
),
|
|
|
|
hideNavBar: true,
|
|
|
|
canShowAsDialog: true,
|
|
|
|
));
|
|
|
|
|
2020-05-10 16:29:43 +00:00
|
|
|
/// Start a call for a given conversation
|
|
|
|
void startCall(int convID) =>
|
2020-05-10 16:34:54 +00:00
|
|
|
pushPage(PageInfo(child: CallScreen(convID: convID), hideNavBar: true));
|
2020-05-10 16:29:43 +00:00
|
|
|
|
2020-05-12 16:40:07 +00:00
|
|
|
/// Open settings
|
|
|
|
void openSettings() => Navigator.of(context)
|
2020-05-10 16:29:43 +00:00
|
|
|
.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();
|
|
|
|
}
|
2020-05-05 11:21:37 +00:00
|
|
|
|
|
|
|
/// Pop current page. Last page can not be popped
|
2020-05-09 12:18:09 +00:00
|
|
|
///
|
|
|
|
/// If the current route is not the main route, we pop one page
|
|
|
|
void popPage() {
|
2022-03-10 18:39:57 +00:00
|
|
|
if (!ModalRoute.of(context)!.isCurrent)
|
2020-05-09 12:18:09 +00:00
|
|
|
Navigator.of(context).pop();
|
|
|
|
else
|
|
|
|
doPopPage();
|
|
|
|
}
|
2020-05-09 05:28:17 +00:00
|
|
|
}
|