mirror of
https://github.com/Iconica-Development/flutter_chat.git
synced 2025-05-18 18:33:49 +02:00
feat: improve loading visualisation on the chatdetailscreen
This commit is contained in:
parent
5975e2f1c0
commit
313ead2029
6 changed files with 47 additions and 36 deletions
|
@ -21,6 +21,7 @@
|
|||
- Added chatScreenBuilder to the userstory configuration to customize the specific chat screen with a ChatModel as argument
|
||||
- Added senderTitleResolver to the ChatOptions to resolve the title of the sender in the chat message
|
||||
- Added imageProviderResolver to the ChatOptions to resolve ImageProvider for all images in the userstory
|
||||
- Added enabled boolean to the messageInputBuilder and made parameters named
|
||||
|
||||
## 4.0.0
|
||||
- Move to the new user story architecture
|
||||
|
|
|
@ -122,12 +122,13 @@ typedef ImagePickerBuilder = Future<Uint8List?> Function(
|
|||
|
||||
/// The text input builder
|
||||
typedef TextInputBuilder = Widget Function(
|
||||
BuildContext context,
|
||||
TextEditingController textEditingController,
|
||||
Widget suffixIcon,
|
||||
ChatTranslations translations,
|
||||
VoidCallback onSubmit,
|
||||
);
|
||||
BuildContext context, {
|
||||
required TextEditingController textEditingController,
|
||||
required Widget suffixIcon,
|
||||
required ChatTranslations translations,
|
||||
required VoidCallback onSubmit,
|
||||
required bool enabled,
|
||||
});
|
||||
|
||||
/// The base screen builder
|
||||
/// [title] is the title of the screen and can be null while loading
|
||||
|
|
|
@ -11,7 +11,7 @@ class ChatOptions {
|
|||
ChatOptions({
|
||||
this.dateformat,
|
||||
this.groupChatEnabled = true,
|
||||
this.enableLoadingIndicator = false,
|
||||
this.enableLoadingIndicator = true,
|
||||
this.translations = const ChatTranslations.empty(),
|
||||
this.builders = const ChatBuilders(),
|
||||
this.spacing = const ChatSpacing(),
|
||||
|
|
|
@ -69,6 +69,10 @@ class ChatDetailScreen extends HookWidget {
|
|||
var usersSnapshot = useStream(allUsersStream);
|
||||
var allUsers = usersSnapshot.data ?? [];
|
||||
|
||||
var chatIsloading =
|
||||
chatSnapshot.connectionState == ConnectionState.waiting ||
|
||||
usersSnapshot.connectionState == ConnectionState.waiting;
|
||||
|
||||
useEffect(
|
||||
() {
|
||||
if (chat == null) return;
|
||||
|
@ -106,6 +110,7 @@ class ChatDetailScreen extends HookWidget {
|
|||
onUploadImage: onUploadImage,
|
||||
onMessageSubmit: onMessageSubmit,
|
||||
onReadChat: onReadChat,
|
||||
chatIsLoading: chatIsloading,
|
||||
);
|
||||
|
||||
if (options.builders.chatScreenBuilder != null) {
|
||||
|
@ -231,6 +236,7 @@ class _ChatBody extends HookWidget {
|
|||
required this.onUploadImage,
|
||||
required this.onMessageSubmit,
|
||||
required this.onReadChat,
|
||||
required this.chatIsLoading,
|
||||
});
|
||||
|
||||
final String chatId;
|
||||
|
@ -240,6 +246,7 @@ class _ChatBody extends HookWidget {
|
|||
final Function(Uint8List image) onUploadImage;
|
||||
final Function(String text) onMessageSubmit;
|
||||
final Function(ChatModel chat) onReadChat;
|
||||
final bool chatIsLoading;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -377,11 +384,6 @@ class _ChatBody extends HookWidget {
|
|||
[autoScrollEnabled.value],
|
||||
);
|
||||
|
||||
if (chat == null) {
|
||||
if (!options.enableLoadingIndicator) return const SizedBox.shrink();
|
||||
return options.builders.loadingWidgetBuilder.call(context);
|
||||
}
|
||||
|
||||
var userMap = <String, UserModel>{};
|
||||
for (var u in chatUsers) {
|
||||
userMap[u.id] = u;
|
||||
|
@ -424,18 +426,23 @@ class _ChatBody extends HookWidget {
|
|||
|
||||
return Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
reverse: false,
|
||||
controller: scrollController,
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
padding: const EdgeInsets.only(top: 24),
|
||||
itemCount: listViewChildren.length,
|
||||
itemBuilder: (context, index) => listViewChildren[index],
|
||||
if (chatIsLoading && options.enableLoadingIndicator) ...[
|
||||
Expanded(child: options.builders.loadingWidgetBuilder.call(context)),
|
||||
] else ...[
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
reverse: false,
|
||||
controller: scrollController,
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
padding: const EdgeInsets.only(top: 24),
|
||||
itemCount: listViewChildren.length,
|
||||
itemBuilder: (context, index) => listViewChildren[index],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
ChatBottomInputSection(
|
||||
chat: chat!,
|
||||
chat: chat,
|
||||
isLoading: chatIsLoading,
|
||||
onPressSelectImage: () async => onPressSelectImage(
|
||||
context,
|
||||
options,
|
||||
|
|
|
@ -8,13 +8,18 @@ class ChatBottomInputSection extends HookWidget {
|
|||
/// Creates a new [ChatBottomInputSection].
|
||||
const ChatBottomInputSection({
|
||||
required this.chat,
|
||||
required this.isLoading,
|
||||
required this.onMessageSubmit,
|
||||
this.onPressSelectImage,
|
||||
super.key,
|
||||
});
|
||||
|
||||
/// The chat model.
|
||||
final ChatModel chat;
|
||||
final ChatModel? chat;
|
||||
|
||||
/// Whether the chat is still loading.
|
||||
/// The inputfield is disabled when the chat is loading.
|
||||
final bool isLoading;
|
||||
|
||||
/// Callback function invoked when a message is submitted.
|
||||
final Function(String text) onMessageSubmit;
|
||||
|
@ -65,7 +70,7 @@ class ChatBottomInputSection extends HookWidget {
|
|||
children: [
|
||||
IconButton(
|
||||
alignment: Alignment.bottomRight,
|
||||
onPressed: onPressSelectImage,
|
||||
onPressed: isLoading ? null : onPressSelectImage,
|
||||
icon: Icon(
|
||||
Icons.image_outlined,
|
||||
color: options.iconEnabledColor,
|
||||
|
@ -75,7 +80,7 @@ class ChatBottomInputSection extends HookWidget {
|
|||
alignment: Alignment.bottomRight,
|
||||
disabledColor: options.iconDisabledColor,
|
||||
color: options.iconEnabledColor,
|
||||
onPressed: onClickSendMessage,
|
||||
onPressed: isLoading ? null : onClickSendMessage,
|
||||
icon: const Icon(Icons.send_rounded),
|
||||
),
|
||||
],
|
||||
|
@ -95,6 +100,7 @@ class ChatBottomInputSection extends HookWidget {
|
|||
keyboardType: TextInputType.multiline,
|
||||
maxLines: null,
|
||||
controller: textController,
|
||||
enabled: !isLoading,
|
||||
decoration: InputDecoration(
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(25),
|
||||
|
@ -141,10 +147,11 @@ class ChatBottomInputSection extends HookWidget {
|
|||
constraints: const BoxConstraints(maxHeight: 120, minHeight: 45),
|
||||
child: options.builders.messageInputBuilder?.call(
|
||||
context,
|
||||
textController,
|
||||
messageSendButtons,
|
||||
options.translations,
|
||||
onSubmitField,
|
||||
textEditingController: textController,
|
||||
suffixIcon: messageSendButtons,
|
||||
translations: options.translations,
|
||||
onSubmit: onSubmitField,
|
||||
enabled: !isLoading,
|
||||
) ??
|
||||
defaultInputField,
|
||||
),
|
||||
|
|
|
@ -11,13 +11,8 @@ class DefaultChatLoadingOverlay extends StatelessWidget {
|
|||
const DefaultChatLoadingOverlay();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => const Column(
|
||||
children: [
|
||||
SizedBox(height: 12),
|
||||
Center(child: CircularProgressIndicator()),
|
||||
SizedBox(height: 12),
|
||||
],
|
||||
);
|
||||
Widget build(BuildContext context) =>
|
||||
const Center(child: CircularProgressIndicator());
|
||||
}
|
||||
|
||||
/// A small row spinner item to show partial loading
|
||||
|
|
Loading…
Reference in a new issue