Releases: flyerhq/flutter_chat_ui
v2.9.0
This release introduces two-sided pagination. You can now load newer messages using the new onStartReached
callback, while onEndReached
continues to work for older messages. For pagination to work correctly, messages should be inserted instantly, without animation.
To allow this and offer more granular control, a new optional animated
parameter has been added to all controller operations except update
. This is not a breaking change, but if you'd like to use it, you can update your controller like so:
insertMessage(Message message, {int? index}) // ❌
insertMessage(Message message, {int? index, bool animated = true}) // ✅
ChatOperation.insert(..., animated: animated) // add animated to insert operations
insertAllMessages(List<Message> messages, {int? index}) // ❌
insertAllMessages(List<Message> messages, {int? index, bool animated = true}) // ✅
ChatOperation.insertAll(..., animated: animated) // add animated to insertAll operations
removeMessage(Message message) // ❌
removeMessage(Message message, {bool animated = true}) // ✅
ChatOperation.remove(..., animated: animated) // add animated to remove operations
setMessages(List<Message> messages) // ❌
setMessages(List<Message> messages, {bool animated = true}) // ✅
ChatOperation.set(..., animated: animated) // add animated to set operations
As an optional improvement, you can use this parameter to disable animations when clearing the chat, which is now the default behaviour in the example apps.
ChatOperation.set(messages, animated: messages.isEmpty ? false : animated) // inside the controller
LoadMoreNotifier
was updated for two-sided loading. If you used a custom LoadMore widget and used LoadMoreNotifier
to measure its height, that logic has been removed as it was not used. Additionally, the internal property _isLoading
is now _isLoadingOlder
, and _isLoadingNewer
has been added.
2.8.1
- FIX: composer inputClearMode and fix custom editing controller. (b4872190)
v2.8.0
v2.7.0
v2.6.0
onMessageTap
and onMessageLongPress
added BuildContext
as a first parameter, so if you had something like this:
void _handleMessageLongPress(
Message message, {
int? index,
LongPressStartDetails? details,
})
replace it with this:
void _handleMessageLongPress(
BuildContext context,
Message message, {
int? index,
LongPressStartDetails? details,
})
- FIX: scrollToIndex does not work when starting with an empty list #793. (1948c1f5)
- FEAT: add sendButtonVisibilityMode and allowEmptyMessage to the composer. (7a496607)
- FEAT: add method OnMessageDoubleTapCallback; add param BuildContext context for OnMessageTapCallback and OnMessageLongPressCallback (#817). (6fe68886)
2.5.3
- FIX: update dependencies. (a8ff8b57)
2.5.2
- Update a dependency to the latest release.
2.5.1
- FIX: re-enable composer blur. (791f7308)
v2.5.0
- FIX: introduce status field back (#809). (1aadf874)
- FIX: prevent sending blank messages (#808). (6fbcfc73)
- FIX: perf improvements (#807). (71e6d690)
- FIX: allow to set a different color in Composer when not empty (#794). (788ca0c6)
- FEAT: time and status grouping same minute fix #764 (#792). (61c04002)
v2.4.0
All message builders will also provide isSentByMe
and groupStatus
now. Just pass
{
required bool isSentByMe,
MessageGroupStatus? groupStatus,
}
after the index param. It is fine not to use these fields if not needed.
v2.3.1
Even though this is a patch release, it depends on flutter_chat_core
, which introduced a small breaking change. I realized I didn’t bump flutter_chat_ui
to a new minor version before publishing - sorry about that!
Fix is simple: if you have a custom ChatController, the set
operation now requires a messages array.
- If you were using named parameters like set(messages: messages), change it to: set(messages)
- If you previously used set() with no arguments, replace it with: set([])
v2.3.0
2.3.0
-
Renamed LinkPreview → LinkPreviewData
-
LinkPreview.imageUrl
→LinkPreviewData.image.url
-
Both
LinkPreviewData.image.width
andLinkPreviewData.image.height
are now required
2.2.4
- FIX: add physics param to the ChatAnimatedList(Reversed). (ede3a170)
- FIX: emptyChatList not clickable (#787). (88937baa)
2.2.3
2.2.2
2.2.1
- FIX: list rebuilding when keyboard opens/closes. (48e28e7e)
v2.2.0
2.2.0
ChatAnimatedList
Redesign:- Significantly overhauled for robust handling of asynchronous controller updates.
- The
update
operation (ChatOperation.update
) now requires theindex
of the message to be updated.
- CRITICAL: When implementing custom
ChatController
s, you MUST now fetch the most up-to-date message instance from your data source before passing it toremove
orupdate
operations. The internal list now relies on the exact object reference. Failing to do so will lead to errors or unexpected behavior. (SeeInMemoryChatController
for an example of fetching the actual message before emittingChatOperation.remove
orChatOperation.update
).
✨ Key Enhancements & Fixes ✨
- Asynchronous Operations:
ChatAnimatedList
now uses an internal operation queue to serialize updates, preventing race conditions and resolving priorStreamOperation
issues. - List Factorization: Common logic between normal and reversed
ChatAnimatedList
instances has been factorized, improving maintainability. - Bulk Insertions: Added
insertAllMessages
toChatController
andChatAnimatedList
for efficient bulk message additions with animations. - Diffing & Stability:
ChatController
'ssetMessages
now uses an improvedDiffUtil
(with move support), fixing "out of bounds" errors during complex list updates. - Data Consistency: The controller now fetches the latest message version before updates or deletions to ensure operations use current data.
- Bug Fixes:
- Testing: Introduced integration tests for
ChatAnimatedList
to validate list operations and item positioning.
- FIX: update operation not persisted in the list (#778). (37472015)
- FEAT: Fix StreamOperation Async issues / create insertAll / fixInsert on reverted list (#756). (60395f9b)
2.1.3
2.1.2
- FIX: add audio message type. (8d2b705a)
2.1.1
- FIX: add video message type. (93a13840)
2.1.0
2.1.0
Chat controller methods have been renamed to avoid name conflicts with Riverpod.