mirror of
https://github.com/Iconica-Development/flutter_chat.git
synced 2025-05-19 02:43:50 +02:00
feat: rework the existing navigator userstory to look more like flutter_availability userstory
This commit is contained in:
parent
4c48cf8cd4
commit
15604bf264
4 changed files with 137 additions and 110 deletions
|
@ -3,7 +3,7 @@ export "package:chat_repository_interface/chat_repository_interface.dart";
|
||||||
|
|
||||||
// User story
|
// User story
|
||||||
export "package:flutter_chat/src/flutter_chat_entry_widget.dart";
|
export "package:flutter_chat/src/flutter_chat_entry_widget.dart";
|
||||||
export "package:flutter_chat/src/flutter_chat_navigator_userstory.dart";
|
export "package:flutter_chat/src/flutter_chat_navigator_userstories.dart";
|
||||||
|
|
||||||
// Options
|
// Options
|
||||||
export "src/config/chat_builders.dart";
|
export "src/config/chat_builders.dart";
|
||||||
|
|
|
@ -81,7 +81,7 @@ class _FlutterChatEntryWidgetState extends State<FlutterChatEntryWidget> {
|
||||||
Widget build(BuildContext context) => InkWell(
|
Widget build(BuildContext context) => InkWell(
|
||||||
onTap: () async =>
|
onTap: () async =>
|
||||||
widget.onTap?.call() ??
|
widget.onTap?.call() ??
|
||||||
Navigator.of(context).pushReplacement(
|
Navigator.of(context).push(
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (context) => FlutterChatNavigatorUserstory(
|
builder: (context) => FlutterChatNavigatorUserstory(
|
||||||
userId: widget.userId,
|
userId: widget.userId,
|
||||||
|
@ -122,7 +122,7 @@ class _FlutterChatEntryWidgetState extends State<FlutterChatEntryWidget> {
|
||||||
),
|
),
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
"${snapshot.data ?? 0}",
|
snapshot.data?.toString() ?? "0",
|
||||||
style: widget.textStyle,
|
style: widget.textStyle,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
// SPDX-FileCopyrightText: 2023 Iconica
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
import "package:chat_repository_interface/chat_repository_interface.dart";
|
||||||
|
import "package:flutter/material.dart";
|
||||||
|
import "package:flutter_chat/src/config/chat_options.dart";
|
||||||
|
import "package:flutter_chat/src/routes.dart";
|
||||||
|
import "package:flutter_chat/src/services/pop_handler.dart";
|
||||||
|
import "package:flutter_chat/src/util/scope.dart";
|
||||||
|
|
||||||
|
/// The flutter chat navigator userstory
|
||||||
|
/// [userId] is the id of the user
|
||||||
|
/// [chatService] is the chat service
|
||||||
|
/// [chatOptions] are the chat options
|
||||||
|
/// This widget is the entry point for the chat UI
|
||||||
|
class FlutterChatNavigatorUserstory extends StatefulWidget {
|
||||||
|
/// Constructs a [FlutterChatNavigatorUserstory].
|
||||||
|
const FlutterChatNavigatorUserstory({
|
||||||
|
required this.userId,
|
||||||
|
required this.options,
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
/// The user ID of the person currently looking at the chat
|
||||||
|
final String userId;
|
||||||
|
|
||||||
|
/// The chat options
|
||||||
|
final ChatOptions options;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<FlutterChatNavigatorUserstory> createState() =>
|
||||||
|
_FlutterChatNavigatorUserstoryState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _FlutterChatNavigatorUserstoryState
|
||||||
|
extends State<FlutterChatNavigatorUserstory> {
|
||||||
|
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(
|
||||||
|
// ignore: deprecated_member_use
|
||||||
|
onPop: () => _popHandler.handlePop(),
|
||||||
|
child: Navigator(
|
||||||
|
key: _nestedNavigatorKey,
|
||||||
|
onGenerateRoute: (settings) => MaterialPageRoute(
|
||||||
|
builder: (context) => NavigatorWrapper(
|
||||||
|
userId: widget.userId,
|
||||||
|
chatService: _service,
|
||||||
|
chatOptions: widget.options,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didUpdateWidget(covariant FlutterChatNavigatorUserstory 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,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,3 @@
|
||||||
// SPDX-FileCopyrightText: 2023 Iconica
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
|
|
||||||
import "dart:async";
|
import "dart:async";
|
||||||
|
|
||||||
import "package:chat_repository_interface/chat_repository_interface.dart";
|
import "package:chat_repository_interface/chat_repository_interface.dart";
|
||||||
|
@ -13,125 +9,66 @@ import "package:flutter_chat/src/screens/chat_screen.dart";
|
||||||
import "package:flutter_chat/src/screens/creation/new_chat_screen.dart";
|
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";
|
||||||
import "package:flutter_chat/src/services/pop_handler.dart";
|
|
||||||
import "package:flutter_chat/src/util/scope.dart";
|
|
||||||
|
|
||||||
/// The flutter chat navigator userstory
|
/// The navigator wrapper
|
||||||
/// [userId] is the id of the user
|
class NavigatorWrapper extends StatelessWidget {
|
||||||
/// [chatService] is the chat service
|
/// Constructs a [NavigatorWrapper].
|
||||||
/// [chatOptions] are the chat options
|
const NavigatorWrapper({
|
||||||
/// This widget is the entry point for the chat UI
|
|
||||||
class FlutterChatNavigatorUserstory extends StatefulWidget {
|
|
||||||
/// Constructs a [FlutterChatNavigatorUserstory].
|
|
||||||
const FlutterChatNavigatorUserstory({
|
|
||||||
required this.userId,
|
|
||||||
required this.options,
|
|
||||||
super.key,
|
|
||||||
});
|
|
||||||
|
|
||||||
/// The user ID of the person currently looking at the chat
|
|
||||||
final String userId;
|
|
||||||
|
|
||||||
/// The chat options
|
|
||||||
final ChatOptions options;
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<FlutterChatNavigatorUserstory> createState() =>
|
|
||||||
_FlutterChatNavigatorUserstoryState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _FlutterChatNavigatorUserstoryState
|
|
||||||
extends State<FlutterChatNavigatorUserstory> {
|
|
||||||
late ChatService _service = ChatService(
|
|
||||||
userId: widget.userId,
|
|
||||||
chatRepository: widget.options.chatRepository,
|
|
||||||
userRepository: widget.options.userRepository,
|
|
||||||
);
|
|
||||||
|
|
||||||
late final PopHandler _popHandler = PopHandler();
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) => ChatScope(
|
|
||||||
userId: widget.userId,
|
|
||||||
options: widget.options,
|
|
||||||
service: _service,
|
|
||||||
popHandler: _popHandler,
|
|
||||||
child: NavigatorPopHandler(
|
|
||||||
// ignore: deprecated_member_use
|
|
||||||
onPop: _popHandler.handlePop,
|
|
||||||
child: Navigator(
|
|
||||||
key: const ValueKey(
|
|
||||||
"chat_navigator",
|
|
||||||
),
|
|
||||||
onGenerateRoute: (settings) => MaterialPageRoute(
|
|
||||||
builder: (context) => _NavigatorWrapper(
|
|
||||||
userId: widget.userId,
|
|
||||||
chatService: _service,
|
|
||||||
chatOptions: widget.options,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
@override
|
|
||||||
void didUpdateWidget(covariant FlutterChatNavigatorUserstory 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,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class _NavigatorWrapper extends StatelessWidget {
|
|
||||||
const _NavigatorWrapper({
|
|
||||||
required this.userId,
|
required this.userId,
|
||||||
required this.chatService,
|
required this.chatService,
|
||||||
required this.chatOptions,
|
required this.chatOptions,
|
||||||
|
super.key,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/// The user ID of the person starting the chat userstory
|
||||||
final String userId;
|
final String userId;
|
||||||
|
|
||||||
|
/// The chat service containing the chat repository and user repository
|
||||||
final ChatService chatService;
|
final ChatService chatService;
|
||||||
|
|
||||||
|
/// The chat userstory configuration
|
||||||
final ChatOptions chatOptions;
|
final ChatOptions chatOptions;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) => chatScreen(context);
|
Widget build(BuildContext context) => chatScreen(context);
|
||||||
|
|
||||||
|
/// The chat overview screen
|
||||||
Widget chatScreen(BuildContext context) => ChatScreen(
|
Widget chatScreen(BuildContext context) => ChatScreen(
|
||||||
chatService: chatService,
|
chatService: chatService,
|
||||||
chatOptions: chatOptions,
|
chatOptions: chatOptions,
|
||||||
onPressChat: (chat) => route(context, chatDetailScreen(context, chat)),
|
onPressChat: (chat) async =>
|
||||||
|
_routeToScreen(context, chatDetailScreen(context, chat)),
|
||||||
onDeleteChat: (chat) async {
|
onDeleteChat: (chat) async {
|
||||||
await chatService.deleteChat(chatId: chat.id);
|
await chatService.deleteChat(chatId: chat.id);
|
||||||
},
|
},
|
||||||
onPressStartChat: () => route(context, newChatScreen(context)),
|
onPressStartChat: () async =>
|
||||||
|
_routeToScreen(context, newChatScreen(context)),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// The chat screen
|
||||||
Widget chatDetailScreen(BuildContext context, ChatModel chat) =>
|
Widget chatDetailScreen(BuildContext context, ChatModel chat) =>
|
||||||
ChatDetailScreen(
|
ChatDetailScreen(
|
||||||
chat: chat,
|
chat: chat,
|
||||||
onReadChat: (chat) async => chatService.markAsRead(chatId: chat.id),
|
onReadChat: (chat) async => chatService.markAsRead(chatId: chat.id),
|
||||||
onPressChatTitle: (chat) async {
|
onPressChatTitle: (chat) async {
|
||||||
if (chat.isGroupChat) {
|
if (chat.isGroupChat) {
|
||||||
return route(context, chatProfileScreen(context, null, chat));
|
return _routeToScreen(
|
||||||
|
context,
|
||||||
|
chatProfileScreen(context, null, chat),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
var otherUserId = chat.getOtherUser(userId);
|
var otherUserId = chat.getOtherUser(userId);
|
||||||
var otherUser = await chatService.getUser(userId: otherUserId).first;
|
var otherUser = await chatService.getUser(userId: otherUserId).first;
|
||||||
|
|
||||||
if (!context.mounted) return;
|
if (!context.mounted) return;
|
||||||
return route(context, chatProfileScreen(context, otherUser, null));
|
return _routeToScreen(
|
||||||
|
context,
|
||||||
|
chatProfileScreen(context, otherUser, null),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
onPressUserProfile: (user) =>
|
onPressUserProfile: (user) async =>
|
||||||
route(context, chatProfileScreen(context, user, null)),
|
_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()}",
|
||||||
|
@ -155,6 +92,7 @@ class _NavigatorWrapper extends StatelessWidget {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// The chat profile screen
|
||||||
Widget chatProfileScreen(
|
Widget chatProfileScreen(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
UserModel? user,
|
UserModel? user,
|
||||||
|
@ -170,38 +108,41 @@ class _NavigatorWrapper extends StatelessWidget {
|
||||||
var user = await chatService.getUser(userId: userId).first;
|
var user = await chatService.getUser(userId: userId).first;
|
||||||
|
|
||||||
if (!context.mounted) return;
|
if (!context.mounted) return;
|
||||||
route(context, chatProfileScreen(context, user, null));
|
await _routeToScreen(context, chatProfileScreen(context, user, null));
|
||||||
},
|
},
|
||||||
onPressStartChat: (userId) async {
|
onPressStartChat: (userId) async {
|
||||||
var chat = await createChat(userId);
|
var chat = await _createChat(userId);
|
||||||
|
|
||||||
if (!context.mounted) return;
|
if (!context.mounted) return;
|
||||||
return route(context, chatDetailScreen(context, chat));
|
return _routeToScreen(context, chatDetailScreen(context, chat));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// The new chat screen
|
||||||
Widget newChatScreen(BuildContext context) => NewChatScreen(
|
Widget newChatScreen(BuildContext context) => NewChatScreen(
|
||||||
userId: userId,
|
userId: userId,
|
||||||
chatService: chatService,
|
chatService: chatService,
|
||||||
chatOptions: chatOptions,
|
chatOptions: chatOptions,
|
||||||
onPressCreateGroupChat: () =>
|
onPressCreateGroupChat: () async =>
|
||||||
route(context, newGroupChatScreen(context)),
|
_routeToScreen(context, newGroupChatScreen(context)),
|
||||||
onPressCreateChat: (user) async {
|
onPressCreateChat: (user) async {
|
||||||
var chat = await createChat(user.id);
|
var chat = await _createChat(user.id);
|
||||||
|
|
||||||
if (!context.mounted) return;
|
if (!context.mounted) return;
|
||||||
return route(context, chatDetailScreen(context, chat));
|
return _routeToScreen(context, chatDetailScreen(context, chat));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// The new group chat screen
|
||||||
Widget newGroupChatScreen(BuildContext context) => NewGroupChatScreen(
|
Widget newGroupChatScreen(BuildContext context) => NewGroupChatScreen(
|
||||||
userId: userId,
|
userId: userId,
|
||||||
chatService: chatService,
|
chatService: chatService,
|
||||||
chatOptions: chatOptions,
|
chatOptions: chatOptions,
|
||||||
onContinue: (users) =>
|
onContinue: (users) async =>
|
||||||
route(context, newGroupChatOverview(context, users)),
|
_routeToScreen(context, newGroupChatOverview(context, users)),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// The new group chat overview screen
|
||||||
Widget newGroupChatOverview(BuildContext context, List<UserModel> users) =>
|
Widget newGroupChatOverview(BuildContext context, List<UserModel> users) =>
|
||||||
NewGroupChatOverview(
|
NewGroupChatOverview(
|
||||||
options: chatOptions,
|
options: chatOptions,
|
||||||
|
@ -214,7 +155,7 @@ class _NavigatorWrapper extends StatelessWidget {
|
||||||
image: image,
|
image: image,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
var chat = await createGroupChat(
|
var chat = await _createGroupChat(
|
||||||
users,
|
users,
|
||||||
title,
|
title,
|
||||||
description,
|
description,
|
||||||
|
@ -222,11 +163,12 @@ class _NavigatorWrapper extends StatelessWidget {
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!context.mounted) return;
|
if (!context.mounted) return;
|
||||||
return route(context, chatDetailScreen(context, chat));
|
return _routeToScreen(context, chatDetailScreen(context, chat));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
Future<ChatModel> createGroupChat(
|
/// Creates a group chat
|
||||||
|
Future<ChatModel> _createGroupChat(
|
||||||
List<UserModel> userModels,
|
List<UserModel> userModels,
|
||||||
String title,
|
String title,
|
||||||
String description,
|
String description,
|
||||||
|
@ -275,7 +217,8 @@ class _NavigatorWrapper extends StatelessWidget {
|
||||||
return chat;
|
return chat;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<ChatModel> createChat(String otherUserId) async {
|
/// Creates a chat
|
||||||
|
Future<ChatModel> _createChat(String otherUserId) async {
|
||||||
ChatModel? chat;
|
ChatModel? chat;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -311,11 +254,9 @@ class _NavigatorWrapper extends StatelessWidget {
|
||||||
return chat;
|
return chat;
|
||||||
}
|
}
|
||||||
|
|
||||||
void route(BuildContext context, Widget screen) {
|
/// Routes to a new screen for the userstory
|
||||||
unawaited(
|
Future _routeToScreen(BuildContext context, Widget screen) async =>
|
||||||
Navigator.of(context).push(
|
Navigator.of(context).push(
|
||||||
MaterialPageRoute(builder: (context) => screen),
|
MaterialPageRoute(builder: (context) => screen),
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
Loading…
Reference in a new issue