mirror of
https://github.com/Iconica-Development/flutter_chat.git
synced 2025-05-19 10:53:51 +02:00
fix: remove NavigationWrapper to be more consistent with flutter_availability userstory
This commit is contained in:
parent
1500a3a9e2
commit
b0601bf4cd
3 changed files with 414 additions and 397 deletions
|
@ -1,87 +1,16 @@
|
||||||
// SPDX-FileCopyrightText: 2023 Iconica
|
// SPDX-FileCopyrightText: 2023 Iconica
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
import "package:chat_repository_interface/chat_repository_interface.dart";
|
import "package:chat_repository_interface/chat_repository_interface.dart";
|
||||||
import "package:flutter/material.dart";
|
import "package:flutter/material.dart";
|
||||||
import "package:flutter_chat/src/config/chat_options.dart";
|
import "package:flutter_chat/src/config/chat_options.dart";
|
||||||
import "package:flutter_chat/src/routes.dart";
|
import "package:flutter_chat/src/routes.dart";
|
||||||
import "package:flutter_chat/src/services/pop_handler.dart";
|
import "package:flutter_chat/src/services/pop_handler.dart";
|
||||||
import "package:flutter_chat/src/util/scope.dart";
|
import "package:flutter_chat/src/util/scope.dart";
|
||||||
|
import "package:flutter_hooks/flutter_hooks.dart";
|
||||||
/// Base class for both chat navigator user stories.
|
|
||||||
abstract class BaseChatNavigatorUserstory extends StatefulWidget {
|
|
||||||
/// Constructs a [BaseChatNavigatorUserstory].
|
|
||||||
const BaseChatNavigatorUserstory({
|
|
||||||
required this.userId,
|
|
||||||
required this.options,
|
|
||||||
this.onExit,
|
|
||||||
super.key,
|
|
||||||
});
|
|
||||||
|
|
||||||
/// The user ID of the person starting the chat userstory.
|
|
||||||
final String userId;
|
|
||||||
|
|
||||||
/// The chat userstory configuration.
|
|
||||||
final ChatOptions options;
|
|
||||||
|
|
||||||
/// Callback for when the user wants to navigate back to a previous screen
|
|
||||||
final VoidCallback? onExit;
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<BaseChatNavigatorUserstory> createState();
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class _BaseChatNavigatorUserstoryState<
|
|
||||||
T extends BaseChatNavigatorUserstory> extends State<T> {
|
|
||||||
late ChatService _service = ChatService(
|
|
||||||
userId: widget.userId,
|
|
||||||
chatRepository: widget.options.chatRepository,
|
|
||||||
userRepository: widget.options.userRepository,
|
|
||||||
);
|
|
||||||
|
|
||||||
late final PopHandler _popHandler = PopHandler();
|
|
||||||
final GlobalKey<NavigatorState> _nestedNavigatorKey =
|
|
||||||
GlobalKey<NavigatorState>();
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) => ChatScope(
|
|
||||||
userId: widget.userId,
|
|
||||||
options: widget.options,
|
|
||||||
service: _service,
|
|
||||||
popHandler: _popHandler,
|
|
||||||
child: NavigatorPopHandler(
|
|
||||||
onPop: () => _popHandler.handlePop(),
|
|
||||||
child: Navigator(
|
|
||||||
key: _nestedNavigatorKey,
|
|
||||||
onGenerateRoute: (settings) => MaterialPageRoute(
|
|
||||||
builder: (context) => buildInitialScreen(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
@override
|
|
||||||
void didUpdateWidget(covariant T oldWidget) {
|
|
||||||
super.didUpdateWidget(oldWidget);
|
|
||||||
if (oldWidget.userId != widget.userId ||
|
|
||||||
oldWidget.options != widget.options) {
|
|
||||||
setState(() {
|
|
||||||
_service = ChatService(
|
|
||||||
userId: widget.userId,
|
|
||||||
chatRepository: widget.options.chatRepository,
|
|
||||||
userRepository: widget.options.userRepository,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Implemented by subclasses to provide the initial screen of the userstory.
|
|
||||||
Widget buildInitialScreen();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Default Chat Userstory that starts at the chat list screen.
|
/// Default Chat Userstory that starts at the chat list screen.
|
||||||
class FlutterChatNavigatorUserstory extends BaseChatNavigatorUserstory {
|
class FlutterChatNavigatorUserstory extends _BaseChatNavigatorUserstory {
|
||||||
/// Constructs a [FlutterChatNavigatorUserstory].
|
/// Constructs a [FlutterChatNavigatorUserstory].
|
||||||
const FlutterChatNavigatorUserstory({
|
const FlutterChatNavigatorUserstory({
|
||||||
required super.userId,
|
required super.userId,
|
||||||
|
@ -91,23 +20,21 @@ class FlutterChatNavigatorUserstory extends BaseChatNavigatorUserstory {
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<BaseChatNavigatorUserstory> createState() =>
|
MaterialPageRoute buildInitialRoute(
|
||||||
_FlutterChatNavigatorUserstoryState();
|
BuildContext context,
|
||||||
}
|
ChatService service,
|
||||||
|
PopHandler popHandler,
|
||||||
class _FlutterChatNavigatorUserstoryState
|
) =>
|
||||||
extends _BaseChatNavigatorUserstoryState<FlutterChatNavigatorUserstory> {
|
chatOverviewRoute(
|
||||||
@override
|
userId: userId,
|
||||||
Widget buildInitialScreen() => NavigatorWrapper(
|
chatService: service,
|
||||||
userId: widget.userId,
|
chatOptions: options,
|
||||||
chatService: _service,
|
onExit: onExit,
|
||||||
chatOptions: widget.options,
|
|
||||||
onExit: widget.onExit,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Chat Userstory that starts directly in a chat detail screen.
|
/// Chat Userstory that starts directly in a chat detail screen.
|
||||||
class FlutterChatDetailNavigatorUserstory extends BaseChatNavigatorUserstory {
|
class FlutterChatDetailNavigatorUserstory extends _BaseChatNavigatorUserstory {
|
||||||
/// Constructs a [FlutterChatDetailNavigatorUserstory].
|
/// Constructs a [FlutterChatDetailNavigatorUserstory].
|
||||||
const FlutterChatDetailNavigatorUserstory({
|
const FlutterChatDetailNavigatorUserstory({
|
||||||
required super.userId,
|
required super.userId,
|
||||||
|
@ -121,22 +48,74 @@ class FlutterChatDetailNavigatorUserstory extends BaseChatNavigatorUserstory {
|
||||||
final ChatModel chat;
|
final ChatModel chat;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<BaseChatNavigatorUserstory> createState() =>
|
MaterialPageRoute buildInitialRoute(
|
||||||
_FlutterChatDetailNavigatorUserstoryState();
|
BuildContext context,
|
||||||
}
|
ChatService service,
|
||||||
|
PopHandler popHandler,
|
||||||
class _FlutterChatDetailNavigatorUserstoryState
|
) =>
|
||||||
extends _BaseChatNavigatorUserstoryState<
|
chatDetailRoute(
|
||||||
FlutterChatDetailNavigatorUserstory> {
|
chat: chat,
|
||||||
@override
|
userId: userId,
|
||||||
Widget buildInitialScreen() => NavigatorWrapper(
|
chatService: service,
|
||||||
userId: widget.userId,
|
chatOptions: options,
|
||||||
chatService: _service,
|
onExit: onExit,
|
||||||
chatOptions: widget.options,
|
|
||||||
onExit: widget.onExit,
|
|
||||||
).chatDetailScreen(
|
|
||||||
context,
|
|
||||||
widget.chat,
|
|
||||||
widget.onExit,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Base hook widget for chat navigator userstories.
|
||||||
|
abstract class _BaseChatNavigatorUserstory extends HookWidget {
|
||||||
|
/// Constructs a [_BaseChatNavigatorUserstory].
|
||||||
|
const _BaseChatNavigatorUserstory({
|
||||||
|
required this.userId,
|
||||||
|
required this.options,
|
||||||
|
this.onExit,
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
/// The user ID of the person starting the chat userstory.
|
||||||
|
final String userId;
|
||||||
|
|
||||||
|
/// The chat userstory configuration.
|
||||||
|
final ChatOptions options;
|
||||||
|
|
||||||
|
/// Callback for when the user wants to navigate back.
|
||||||
|
final VoidCallback? onExit;
|
||||||
|
|
||||||
|
/// Implemented by subclasses to provide the initial route of the userstory.
|
||||||
|
MaterialPageRoute buildInitialRoute(
|
||||||
|
BuildContext context,
|
||||||
|
ChatService service,
|
||||||
|
PopHandler popHandler,
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
var service = useMemoized(
|
||||||
|
() => ChatService(
|
||||||
|
userId: userId,
|
||||||
|
chatRepository: options.chatRepository,
|
||||||
|
userRepository: options.userRepository,
|
||||||
|
),
|
||||||
|
[userId, options],
|
||||||
|
);
|
||||||
|
|
||||||
|
var popHandler = useMemoized(PopHandler.new, []);
|
||||||
|
var nestedNavigatorKey = useMemoized(GlobalKey<NavigatorState>.new, []);
|
||||||
|
|
||||||
|
return ChatScope(
|
||||||
|
userId: userId,
|
||||||
|
options: options,
|
||||||
|
service: service,
|
||||||
|
popHandler: popHandler,
|
||||||
|
child: NavigatorPopHandler(
|
||||||
|
onPop: () => popHandler.handlePop(),
|
||||||
|
child: Navigator(
|
||||||
|
key: nestedNavigatorKey,
|
||||||
|
onGenerateInitialRoutes: (_, __) => [
|
||||||
|
buildInitialRoute(context, service, popHandler),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -10,85 +10,56 @@ import "package:flutter_chat/src/screens/creation/new_chat_screen.dart";
|
||||||
import "package:flutter_chat/src/screens/creation/new_group_chat_overview.dart";
|
import "package:flutter_chat/src/screens/creation/new_group_chat_overview.dart";
|
||||||
import "package:flutter_chat/src/screens/creation/new_group_chat_screen.dart";
|
import "package:flutter_chat/src/screens/creation/new_group_chat_screen.dart";
|
||||||
|
|
||||||
/// The navigator wrapper
|
/// Pushes the chat overview screen
|
||||||
class NavigatorWrapper extends StatelessWidget {
|
MaterialPageRoute chatOverviewRoute({
|
||||||
/// Constructs a [NavigatorWrapper].
|
required String userId,
|
||||||
const NavigatorWrapper({
|
required ChatService chatService,
|
||||||
required this.userId,
|
required ChatOptions chatOptions,
|
||||||
required this.chatService,
|
required VoidCallback? onExit,
|
||||||
required this.chatOptions,
|
}) =>
|
||||||
this.onExit,
|
MaterialPageRoute(
|
||||||
super.key,
|
builder: (context) => ChatScreen(
|
||||||
});
|
|
||||||
|
|
||||||
/// The user ID of the person starting the chat userstory
|
|
||||||
final String userId;
|
|
||||||
|
|
||||||
/// The chat service containing the chat repository and user repository
|
|
||||||
final ChatService chatService;
|
|
||||||
|
|
||||||
/// The chat userstory configuration
|
|
||||||
final ChatOptions chatOptions;
|
|
||||||
|
|
||||||
/// Callback for when the user wants to navigate back
|
|
||||||
final VoidCallback? onExit;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) => chatScreen(context);
|
|
||||||
|
|
||||||
/// The chat overview screen
|
|
||||||
Widget chatScreen(BuildContext context) => ChatScreen(
|
|
||||||
onExit: onExit,
|
onExit: onExit,
|
||||||
onPressChat: (chat) async => _routeToScreen(
|
onPressChat: (chat) async => _routeToScreen(
|
||||||
context,
|
context,
|
||||||
chatDetailScreen(
|
chatDetailRoute(
|
||||||
|
chat: chat,
|
||||||
|
userId: userId,
|
||||||
|
chatService: chatService,
|
||||||
|
chatOptions: chatOptions,
|
||||||
|
onExit: () => Navigator.of(context).pop(),
|
||||||
|
).builder(context),
|
||||||
|
),
|
||||||
|
onDeleteChat: (chat) async => chatService.deleteChat(chatId: chat.id),
|
||||||
|
onPressStartChat: () async => _routeToScreen(
|
||||||
context,
|
context,
|
||||||
chat,
|
_newChatRoute(
|
||||||
() => Navigator.of(context).pop(),
|
userId: userId,
|
||||||
|
chatService: chatService,
|
||||||
|
chatOptions: chatOptions,
|
||||||
|
).builder(context),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
onDeleteChat: (chat) async {
|
|
||||||
await chatService.deleteChat(chatId: chat.id);
|
|
||||||
},
|
|
||||||
onPressStartChat: () async =>
|
|
||||||
_routeToScreen(context, newChatScreen(context)),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
/// The chat screen
|
/// Pushes the chat detail screen
|
||||||
Widget chatDetailScreen(
|
MaterialPageRoute chatDetailRoute({
|
||||||
BuildContext context,
|
required ChatModel chat,
|
||||||
ChatModel chat,
|
required String userId,
|
||||||
VoidCallback? onExit,
|
required ChatService chatService,
|
||||||
) =>
|
required ChatOptions chatOptions,
|
||||||
ChatDetailScreen(
|
required VoidCallback? onExit,
|
||||||
|
}) =>
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) => ChatDetailScreen(
|
||||||
chat: chat,
|
chat: chat,
|
||||||
onExit: onExit,
|
onExit: onExit,
|
||||||
onReadChat: (chat) async => chatService.markAsRead(chatId: chat.id),
|
onReadChat: (chat) async => chatService.markAsRead(chatId: chat.id),
|
||||||
onPressChatTitle: (chat) async {
|
|
||||||
if (chat.isGroupChat) {
|
|
||||||
return _routeToScreen(
|
|
||||||
context,
|
|
||||||
chatProfileScreen(context, null, chat),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
var otherUserId = chat.getOtherUser(userId);
|
|
||||||
var otherUser = await chatService.getUser(userId: otherUserId).first;
|
|
||||||
|
|
||||||
if (!context.mounted) return;
|
|
||||||
return _routeToScreen(
|
|
||||||
context,
|
|
||||||
chatProfileScreen(context, otherUser, null),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
onPressUserProfile: (user) async =>
|
|
||||||
_routeToScreen(context, chatProfileScreen(context, user, null)),
|
|
||||||
onUploadImage: (data) async {
|
onUploadImage: (data) async {
|
||||||
var path = await chatService.uploadImage(
|
var path = await chatService.uploadImage(
|
||||||
path: "chats/${chat.id}-$userId-${DateTime.now()}",
|
path: "chats/${chat.id}-$userId-${DateTime.now()}",
|
||||||
image: data,
|
image: data,
|
||||||
);
|
);
|
||||||
|
|
||||||
await chatService.sendMessage(
|
await chatService.sendMessage(
|
||||||
messageId: "${chat.id}-$userId-${DateTime.now()}",
|
messageId: "${chat.id}-$userId-${DateTime.now()}",
|
||||||
chatId: chat.id,
|
chatId: chat.id,
|
||||||
|
@ -104,71 +75,153 @@ class NavigatorWrapper extends StatelessWidget {
|
||||||
text: text,
|
text: text,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
onPressChatTitle: (chat) async {
|
||||||
|
if (chat.isGroupChat) {
|
||||||
|
await _routeToScreen(
|
||||||
|
context,
|
||||||
|
_chatProfileRoute(
|
||||||
|
userId: userId,
|
||||||
|
chatService: chatService,
|
||||||
|
chatOptions: chatOptions,
|
||||||
|
chat: chat,
|
||||||
|
onExit: () => Navigator.of(context).pop(),
|
||||||
|
).builder(context),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
var otherUserId = chat.getOtherUser(userId);
|
||||||
|
var otherUser =
|
||||||
|
await chatService.getUser(userId: otherUserId).first;
|
||||||
|
if (!context.mounted) return;
|
||||||
|
await _routeToScreen(
|
||||||
|
context,
|
||||||
|
_chatProfileRoute(
|
||||||
|
userId: userId,
|
||||||
|
chatService: chatService,
|
||||||
|
chatOptions: chatOptions,
|
||||||
|
user: otherUser,
|
||||||
|
onExit: () => Navigator.of(context).pop(),
|
||||||
|
).builder(context),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onPressUserProfile: (user) async => _routeToScreen(
|
||||||
|
context,
|
||||||
|
_chatProfileRoute(
|
||||||
|
userId: userId,
|
||||||
|
chatService: chatService,
|
||||||
|
chatOptions: chatOptions,
|
||||||
|
user: user,
|
||||||
|
onExit: () => Navigator.of(context).pop(),
|
||||||
|
).builder(context),
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
/// The chat profile screen
|
MaterialPageRoute _chatProfileRoute({
|
||||||
Widget chatProfileScreen(
|
required String userId,
|
||||||
BuildContext context,
|
required ChatService chatService,
|
||||||
|
required ChatOptions chatOptions,
|
||||||
|
required VoidCallback onExit,
|
||||||
UserModel? user,
|
UserModel? user,
|
||||||
ChatModel? chat,
|
ChatModel? chat,
|
||||||
) =>
|
}) =>
|
||||||
ChatProfileScreen(
|
MaterialPageRoute(
|
||||||
|
builder: (context) => ChatProfileScreen(
|
||||||
userModel: user,
|
userModel: user,
|
||||||
chatModel: chat,
|
chatModel: chat,
|
||||||
onExit: () => Navigator.of(context).pop(),
|
onExit: onExit,
|
||||||
onTapUser: (userId) async {
|
onTapUser: (userId) async {
|
||||||
var user = await chatService.getUser(userId: userId).first;
|
var user = await chatService.getUser(userId: userId).first;
|
||||||
|
|
||||||
if (!context.mounted) return;
|
if (!context.mounted) return;
|
||||||
await _routeToScreen(context, chatProfileScreen(context, user, null));
|
await _routeToScreen(
|
||||||
|
context,
|
||||||
|
_chatProfileRoute(
|
||||||
|
userId: userId,
|
||||||
|
chatService: chatService,
|
||||||
|
chatOptions: chatOptions,
|
||||||
|
user: user,
|
||||||
|
onExit: () => Navigator.of(context).pop(),
|
||||||
|
).builder(context),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
onPressStartChat: (userId) async {
|
onPressStartChat: (userId) async {
|
||||||
var chat = await _createChat(userId);
|
var chat = await _createChat(userId, chatService, userId);
|
||||||
|
|
||||||
if (!context.mounted) return;
|
if (!context.mounted) return;
|
||||||
return _routeToScreen(
|
await _routeToScreen(
|
||||||
context,
|
context,
|
||||||
chatDetailScreen(
|
chatDetailRoute(
|
||||||
context,
|
chat: chat,
|
||||||
chat,
|
userId: userId,
|
||||||
() => Navigator.of(context).pop(),
|
chatService: chatService,
|
||||||
),
|
chatOptions: chatOptions,
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
/// The new chat screen
|
|
||||||
Widget newChatScreen(BuildContext context) => NewChatScreen(
|
|
||||||
onExit: () => Navigator.of(context).pop(),
|
onExit: () => Navigator.of(context).pop(),
|
||||||
onPressCreateGroupChat: () async =>
|
).builder(context),
|
||||||
_routeToScreen(context, newGroupChatScreen(context)),
|
|
||||||
onPressCreateChat: (user) async {
|
|
||||||
var chat = await _createChat(user.id);
|
|
||||||
|
|
||||||
if (!context.mounted) return;
|
|
||||||
return _replaceCurrentScreen(
|
|
||||||
context,
|
|
||||||
chatDetailScreen(
|
|
||||||
context,
|
|
||||||
chat,
|
|
||||||
() => Navigator.of(context).pop(),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
/// The new group chat screen
|
MaterialPageRoute _newChatRoute({
|
||||||
Widget newGroupChatScreen(BuildContext context) => NewGroupChatScreen(
|
required String userId,
|
||||||
|
required ChatService chatService,
|
||||||
|
required ChatOptions chatOptions,
|
||||||
|
}) =>
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) => NewChatScreen(
|
||||||
|
onExit: () => Navigator.of(context).pop(),
|
||||||
|
onPressCreateGroupChat: () async => _routeToScreen(
|
||||||
|
context,
|
||||||
|
_newGroupChatRoute(
|
||||||
|
userId: userId,
|
||||||
|
chatService: chatService,
|
||||||
|
chatOptions: chatOptions,
|
||||||
|
).builder(context),
|
||||||
|
),
|
||||||
|
onPressCreateChat: (user) async {
|
||||||
|
var chat = await _createChat(user.id, chatService, userId);
|
||||||
|
if (!context.mounted) return;
|
||||||
|
await _replaceCurrentScreen(
|
||||||
|
context,
|
||||||
|
chatDetailRoute(
|
||||||
|
chat: chat,
|
||||||
|
userId: userId,
|
||||||
|
chatService: chatService,
|
||||||
|
chatOptions: chatOptions,
|
||||||
|
onExit: () => Navigator.of(context).pop(),
|
||||||
|
).builder(context),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
MaterialPageRoute _newGroupChatRoute({
|
||||||
|
required String userId,
|
||||||
|
required ChatService chatService,
|
||||||
|
required ChatOptions chatOptions,
|
||||||
|
}) =>
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) => NewGroupChatScreen(
|
||||||
onExit: () => Navigator.of(context).pop(),
|
onExit: () => Navigator.of(context).pop(),
|
||||||
onContinue: (users) async => _replaceCurrentScreen(
|
onContinue: (users) async => _replaceCurrentScreen(
|
||||||
context,
|
context,
|
||||||
newGroupChatOverview(context, users),
|
_newGroupChatOverviewRoute(
|
||||||
|
userId: userId,
|
||||||
|
chatService: chatService,
|
||||||
|
chatOptions: chatOptions,
|
||||||
|
users: users,
|
||||||
|
).builder(context),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
/// The new group chat overview screen
|
MaterialPageRoute _newGroupChatOverviewRoute({
|
||||||
Widget newGroupChatOverview(BuildContext context, List<UserModel> users) =>
|
required String userId,
|
||||||
NewGroupChatOverview(
|
required ChatService chatService,
|
||||||
|
required ChatOptions chatOptions,
|
||||||
|
required List<UserModel> users,
|
||||||
|
}) =>
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) => NewGroupChatOverview(
|
||||||
users: users,
|
users: users,
|
||||||
onExit: () => Navigator.of(context).pop(),
|
onExit: () => Navigator.of(context).pop(),
|
||||||
onComplete: (users, title, description, image) async {
|
onComplete: (users, title, description, image) async {
|
||||||
|
@ -184,26 +237,64 @@ class NavigatorWrapper extends StatelessWidget {
|
||||||
title,
|
title,
|
||||||
description,
|
description,
|
||||||
path,
|
path,
|
||||||
|
chatService,
|
||||||
|
userId,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!context.mounted) return;
|
if (!context.mounted) return;
|
||||||
return _replaceCurrentScreen(
|
await _replaceCurrentScreen(
|
||||||
context,
|
context,
|
||||||
chatDetailScreen(
|
chatDetailRoute(
|
||||||
context,
|
chat: chat,
|
||||||
chat,
|
userId: userId,
|
||||||
() => Navigator.of(context).pop(),
|
chatService: chatService,
|
||||||
),
|
chatOptions: chatOptions,
|
||||||
|
onExit: () => Navigator.of(context).pop(),
|
||||||
|
).builder(context),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Creates a group chat
|
/// Helper function to create a chat
|
||||||
|
Future<ChatModel> _createChat(
|
||||||
|
String otherUserId,
|
||||||
|
ChatService chatService,
|
||||||
|
String userId,
|
||||||
|
) async {
|
||||||
|
ChatModel? chat;
|
||||||
|
try {
|
||||||
|
chat = await chatService.getChatByUser(
|
||||||
|
currentUser: userId,
|
||||||
|
otherUser: otherUserId,
|
||||||
|
);
|
||||||
|
} on Exception catch (_) {
|
||||||
|
chat = null;
|
||||||
|
}
|
||||||
|
if (chat == null) {
|
||||||
|
await chatService.createChat(
|
||||||
|
isGroupChat: false,
|
||||||
|
users: [
|
||||||
|
await chatService.getUser(userId: userId).first,
|
||||||
|
await chatService.getUser(userId: otherUserId).first,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
chat = await chatService.getChatByUser(
|
||||||
|
currentUser: userId,
|
||||||
|
otherUser: otherUserId,
|
||||||
|
);
|
||||||
|
if (chat == null) throw Exception("Chat not created");
|
||||||
|
}
|
||||||
|
return chat;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Helper function to create a group chat
|
||||||
Future<ChatModel> _createGroupChat(
|
Future<ChatModel> _createGroupChat(
|
||||||
List<UserModel> userModels,
|
List<UserModel> userModels,
|
||||||
String title,
|
String title,
|
||||||
String description,
|
String description,
|
||||||
String? imageUrl,
|
String? imageUrl,
|
||||||
|
ChatService chatService,
|
||||||
|
String userId,
|
||||||
) async {
|
) async {
|
||||||
ChatModel? chat;
|
ChatModel? chat;
|
||||||
try {
|
try {
|
||||||
|
@ -231,7 +322,7 @@ class NavigatorWrapper extends StatelessWidget {
|
||||||
imageUrl: imageUrl,
|
imageUrl: imageUrl,
|
||||||
);
|
);
|
||||||
|
|
||||||
var chat = await chatService.getGroupChatByUser(
|
chat = await chatService.getGroupChatByUser(
|
||||||
currentUser: userId,
|
currentUser: userId,
|
||||||
otherUsers: otherUsers,
|
otherUsers: otherUsers,
|
||||||
chatName: title,
|
chatName: title,
|
||||||
|
@ -239,47 +330,8 @@ class NavigatorWrapper extends StatelessWidget {
|
||||||
);
|
);
|
||||||
|
|
||||||
if (chat == null) {
|
if (chat == null) {
|
||||||
throw Exception("Chat not created");
|
throw Exception("Group chat not created");
|
||||||
}
|
}
|
||||||
|
|
||||||
return chat;
|
|
||||||
}
|
|
||||||
|
|
||||||
return chat;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a chat
|
|
||||||
Future<ChatModel> _createChat(String otherUserId) async {
|
|
||||||
ChatModel? chat;
|
|
||||||
|
|
||||||
try {
|
|
||||||
chat = await chatService.getChatByUser(
|
|
||||||
currentUser: userId,
|
|
||||||
otherUser: otherUserId,
|
|
||||||
);
|
|
||||||
} on Exception catch (_) {
|
|
||||||
chat = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chat == null) {
|
|
||||||
var currentUser = await chatService.getUser(userId: userId).first;
|
|
||||||
var otherUser = await chatService.getUser(userId: otherUserId).first;
|
|
||||||
|
|
||||||
await chatService.createChat(
|
|
||||||
isGroupChat: false,
|
|
||||||
users: [currentUser, otherUser],
|
|
||||||
);
|
|
||||||
|
|
||||||
var chat = await chatService.getChatByUser(
|
|
||||||
currentUser: userId,
|
|
||||||
otherUser: otherUserId,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (chat == null) {
|
|
||||||
throw Exception("Chat not created");
|
|
||||||
}
|
|
||||||
|
|
||||||
return chat;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return chat;
|
return chat;
|
||||||
|
@ -296,4 +348,3 @@ class NavigatorWrapper extends StatelessWidget {
|
||||||
Navigator.of(context).pushReplacement(
|
Navigator.of(context).pushReplacement(
|
||||||
MaterialPageRoute(builder: (context) => screen),
|
MaterialPageRoute(builder: (context) => screen),
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
|
@ -47,14 +47,13 @@ class ChatProfileScreen extends HookWidget {
|
||||||
return () => chatScope.popHandler.remove(onExit);
|
return () => chatScope.popHandler.remove(onExit);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (options.builders.baseScreenBuilder == null) {
|
var appBar = _AppBar(
|
||||||
return Scaffold(
|
|
||||||
appBar: _AppBar(
|
|
||||||
user: userModel,
|
user: userModel,
|
||||||
chat: chatModel,
|
chat: chatModel,
|
||||||
options: options,
|
options: options,
|
||||||
),
|
);
|
||||||
body: _Body(
|
|
||||||
|
var body = _Body(
|
||||||
currentUser: userId,
|
currentUser: userId,
|
||||||
options: options,
|
options: options,
|
||||||
service: service,
|
service: service,
|
||||||
|
@ -62,27 +61,20 @@ class ChatProfileScreen extends HookWidget {
|
||||||
chat: chatModel,
|
chat: chatModel,
|
||||||
onTapUser: onTapUser,
|
onTapUser: onTapUser,
|
||||||
onPressStartChat: onPressStartChat,
|
onPressStartChat: onPressStartChat,
|
||||||
),
|
);
|
||||||
|
|
||||||
|
if (options.builders.baseScreenBuilder == null) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: appBar,
|
||||||
|
body: body,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return options.builders.baseScreenBuilder!.call(
|
return options.builders.baseScreenBuilder!.call(
|
||||||
context,
|
context,
|
||||||
mapScreenType,
|
mapScreenType,
|
||||||
_AppBar(
|
appBar,
|
||||||
user: userModel,
|
body,
|
||||||
chat: chatModel,
|
|
||||||
options: options,
|
|
||||||
),
|
|
||||||
_Body(
|
|
||||||
currentUser: userId,
|
|
||||||
options: options,
|
|
||||||
service: service,
|
|
||||||
user: userModel,
|
|
||||||
chat: chatModel,
|
|
||||||
onTapUser: onTapUser,
|
|
||||||
onPressStartChat: onPressStartChat,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -102,8 +94,7 @@ class _AppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var theme = Theme.of(context);
|
var theme = Theme.of(context);
|
||||||
return AppBar(
|
return AppBar(
|
||||||
iconTheme: theme.appBarTheme.iconTheme ??
|
iconTheme: theme.appBarTheme.iconTheme,
|
||||||
const IconThemeData(color: Colors.white),
|
|
||||||
title: Text(
|
title: Text(
|
||||||
user != null
|
user != null
|
||||||
? "${user!.fullname}"
|
? "${user!.fullname}"
|
||||||
|
@ -143,6 +134,7 @@ class _Body extends StatelessWidget {
|
||||||
|
|
||||||
var chatUserDisplay = Wrap(
|
var chatUserDisplay = Wrap(
|
||||||
children: [
|
children: [
|
||||||
|
if (chat != null) ...[
|
||||||
...chat!.users.map(
|
...chat!.users.map(
|
||||||
(tappedUser) => Padding(
|
(tappedUser) => Padding(
|
||||||
padding: const EdgeInsets.only(
|
padding: const EdgeInsets.only(
|
||||||
|
@ -150,9 +142,7 @@ class _Body extends StatelessWidget {
|
||||||
right: 8,
|
right: 8,
|
||||||
),
|
),
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap: () {
|
onTap: () => onTapUser?.call(tappedUser),
|
||||||
onTapUser?.call(tappedUser);
|
|
||||||
},
|
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
@ -160,7 +150,8 @@ class _Body extends StatelessWidget {
|
||||||
FutureBuilder<UserModel>(
|
FutureBuilder<UserModel>(
|
||||||
future: service.getUser(userId: tappedUser).first,
|
future: service.getUser(userId: tappedUser).first,
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
if (snapshot.connectionState == ConnectionState.waiting) {
|
if (snapshot.connectionState ==
|
||||||
|
ConnectionState.waiting) {
|
||||||
return const CircularProgressIndicator();
|
return const CircularProgressIndicator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,6 +186,7 @@ class _Body extends StatelessWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
var targetUser = user ??
|
var targetUser = user ??
|
||||||
|
@ -210,6 +202,7 @@ class _Body extends StatelessWidget {
|
||||||
firstName: options.translations.groupNameEmpty,
|
firstName: options.translations.groupNameEmpty,
|
||||||
),
|
),
|
||||||
) as UserModel;
|
) as UserModel;
|
||||||
|
|
||||||
return Stack(
|
return Stack(
|
||||||
children: [
|
children: [
|
||||||
ListView(
|
ListView(
|
||||||
|
@ -268,23 +261,17 @@ class _Body extends StatelessWidget {
|
||||||
options.translations.groupProfileBioHeader,
|
options.translations.groupProfileBioHeader,
|
||||||
style: theme.textTheme.titleMedium,
|
style: theme.textTheme.titleMedium,
|
||||||
),
|
),
|
||||||
const SizedBox(
|
const SizedBox(height: 12),
|
||||||
height: 12,
|
|
||||||
),
|
|
||||||
Text(
|
Text(
|
||||||
chat!.description ?? "",
|
chat!.description ?? "",
|
||||||
style: theme.textTheme.bodyMedium,
|
style: theme.textTheme.bodyMedium,
|
||||||
),
|
),
|
||||||
const SizedBox(
|
const SizedBox(height: 12),
|
||||||
height: 12,
|
|
||||||
),
|
|
||||||
Text(
|
Text(
|
||||||
options.translations.chatProfileUsers,
|
options.translations.chatProfileUsers,
|
||||||
style: theme.textTheme.titleMedium,
|
style: theme.textTheme.titleMedium,
|
||||||
),
|
),
|
||||||
const SizedBox(
|
const SizedBox(height: 12),
|
||||||
height: 12,
|
|
||||||
),
|
|
||||||
chatUserDisplay,
|
chatUserDisplay,
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
Loading…
Reference in a new issue