convokit_flutter_ui 0.6.0 copy "convokit_flutter_ui: ^0.6.0" to clipboard
convokit_flutter_ui: ^0.6.0 copied to clipboard

Extensible, plug-and-play Flutter UI components for ConvoKit conversations and messaging.

Changelog #

0.6.0 #

  • Inbox previews and accurate unread counts. SDK-backed ConvoKitConversationListControllers page GET /api/v1/inbox by opaque cursor in activity order (activityAt desc, id desc) instead of getConversations by offset. state.summaries maps every loaded conversation id to the core SDK's InboxSummary (latest message preview, unreadCount, unreadCountCapped, the caller's readPosition/lastReadAt and activityAt); state.currentUserId carries the connected user id while the list is bound to a session in inbox mode (null without a session, in legacy mode and after disposal). state.conversations, filters, predicates, comparators and onConversationSelected are unchanged.
  • Default rows show the preview (You: for the connected user's own message, <name>: in rooms with more than two participants, the trimmed text or Photo / file name / File / Location / Contact for a media-only message), the activity time in the device zone, a bold title while unread and an unread badge (99+ above 99 or when the server capped the count) announced as <count> unread. Rows without a summary render as before.
  • New ConvoKitInboxRow { conversation, summary, index, currentUserId } and ConvoKitInboxItemBuilder, exposed as rowBuilder on ConvoKitConversationListView and ConvoKitConversationList; it wins over itemBuilder, whose signature is unchanged. Controlled lists accept summaries and currentUserId. convoKitInboxPreview, convoKitInboxTimeLabel and ConvoKitUnreadBadge are public so custom rows can reuse the default rules.
  • New theme token ConvoKitUiThemeData.badgeColor (optional; defaults to primaryColor through effectiveBadgeColor), in copyWith and lerp.
  • Live updates: the list subscribes to the core SDK's inbox_activity signal (message insert or edit, read-position advance) and refreshes at most once per activityRefreshWindowMs (default 500; 0 refreshes immediately) using a max-wait timer that later signals do not extend. inboxChanges (structural changes, verified joins and rejoins) still refreshes immediately and drops any pending activity timer. Room controllers ignore activity signals.
  • Refresh walks the inbox from its head with limit = min(100, target - consumed) where target = max(pageSize, loadedCount), continues past fully hidden head pages, merges pages by conversation id (a later entry wins, then re-sorted by activity), and swaps rows, summaries, cursor and hasMore atomically. Pages are validated by shape (entries.length <= limit, non-blank unique ids) and by cursor advance (nextCursor must differ from the requested cursor; an empty page with a cursor is invalid: "Inbox pagination did not advance"). A full page of already-loaded ids is legitimate in inbox mode; the offset-era "did not advance" rule now applies to the legacy path only.
  • A 404 from listInbox (backend without the route) switches the controller to the offset getConversations path for the rest of its session without clearing rows (summaries become empty), warns once through debugPrint, and re-runs the same operation; loadInitial() retries the inbox endpoint. 401/403 from either endpoint and 404 from the legacy endpoint still evict; 400 (for example INVALID_CURSOR) keeps rows and sets state.error.
  • Ordering: server order is authoritative within a page and the local (activityAt desc, id desc) order is applied whenever pages are merged. Setting ConvoKitConversationFilter.comparator replaces it. Custom pageLoaders keep offset requests, creation order and no summaries.
  • Inline error retry requests the next page when hasMore is true and onLoadMore is bound (bypassing the view's duplicate-request guard), otherwise calls onRefresh; the default button renders only when one of those callbacks exists.
  • 0.6.0 adapter change: ConvoKitUiClient gains Future<InboxPage> listInbox({required int limit, String? cursor, required bool archived}) and Stream<void> get inboxActivity. Custom implements adapters must add both: forward listInbox to the core SDK (or serve the same page shape) and reject an absent endpoint with a ConvoKitException whose statusCode is 404 so the controller falls back to getConversations; emit empty activity signals (never synthesised on joins) or return const Stream.empty(). The default adapter forwards to ConvoKit.listInbox and ConvoKit.realtime.onInboxActivity(ConvoKit.clientId).
  • Requires convokit_flutter 0.6.x and the coordinated backend release.

0.5.0 #

  • Compute read receipts from precise read positions. state.readPositionByUserId holds the newest message each participant has confirmed reading as the server's (createdAt, id) cursor; readerIdsFor(message) and the default rows apply one rule: the position when present, otherwise the acknowledgement time (readAtByUserId, kept for custom "seen at" renderers and legacy memberships). Equal creation times fall back to id order. Positions only advance; the connected user's own read is never fabricated from the device clock.
  • ConvoKitConversationView and ConvoKitMessageListView accept readPositionByUserId beside readAtByUserId; readReceiptBuilder, messageBuilder and readersResolver signatures are unchanged.
  • Acknowledge through a concrete message. Every automatic read (markReadOnLoad, markReadOnReceive) and markRead() targets the newest non-pending row of the rendered list by (createdAt, id), never a raw realtime row: a media-only message is acknowledged once hydration renders it, a refresh that discovers new foreign rows acknowledges the newest, and a room with nothing rendered sends nothing. One request is in flight at a time; a follow-up resolves its target when sent and is skipped at or below the last acknowledged target.
  • Gate acknowledgements on visibility. ConvoKitConversationController.setVisible(bool) defers reads while hidden and re-issues only a suppressed one on becoming visible; an unreported state counts as visible. ConvoKitConversation maps AppLifecycleState.resumed to visible and paused, inactive, hidden and detached to hidden through a WidgetsBindingObserver. With both markReadOnLoad and markReadOnReceive false no request is ever sent, including on visibility changes.
  • Retarget a lost acknowledgement target. A targeted read rejected with ConvoKitException.code == 'MESSAGE_NOT_FOUND', or deletion (event or hydration 404) of the in-flight or last acknowledged target, marks that id unacknowledgeable and re-issues once for the next newest rendered row without surfacing an error. A 404 without that code (membership gone) still surfaces as an error and evicts the room like any other access denial.
  • 0.5.0 adapter change: ConvoKitUiClient.markConversationRead is now markConversationRead(String conversationId, {String? throughMessageId}). Custom implements adapters must add the parameter, forward it to the core SDK (or their backend), and reject a missing target with a ConvoKitException carrying code: 'MESSAGE_NOT_FOUND'. The default adapter forwards it.
  • Requires convokit_flutter 0.5.x and the coordinated backend release. Mixed fleet: precise receipts need the sender and the reader on 0.5; 0.4 readers keep timestamp semantics and still parse the additive payloads.

0.4.1 #

  • Announce the outgoing status icon as Sent (single check) or Read (double check) to assistive technology. ConvoKit does not report recipient delivery; visible layout, pending rows and read indicators are unchanged.

0.4.0 #

  • Refresh SDK-backed inboxes automatically on private app invalidations and verified joins; preserve filters, loaded pages and visible rows while fetching.
  • Reconcile open rooms after membership, metadata and cascade changes; discard old-session responses and clear caches on authoritative access denial.
  • Replace optimistic bubbles atomically using clientMessageId from live, history or HTTP confirmation. Never match by text or media similarity.
  • Preserve media-only previews, newer edits and deletions when HTTP finishes late; a lost acknowledgement cannot turn a confirmed send into a failed draft.
  • Breaking custom-client additions: inboxChanges, forwarding the optional send clientMessageId, and preserving that field on returned messages. Requires core 0.4.0 and the coordinated backend release.

0.3.0 #

  • Renew typing during continued input without broadcasting every keystroke; stop on idle and ignore failures from superseded or disconnected requests.

  • Fetch complete related media after raw row events, retain images/files during edits, and discard stale, deleted or retired-session hydration results.

  • Bound and coalesce lookups across reloads; reconcile all viewed live messages and retain snapshot-discovered deletion markers against delayed send ACKs.

  • Reconcile pending sends only by the acknowledged ID, never matching content. Release send state without waiting for the typing-stop request.

  • Require getMessage(id) on custom adapters and the coordinated core SDK's Message.updatedAt field. Add real SDK/provider and decoded-image widget tests.

  • Consume authorized ID-only private deletion events and remove affected rows. Retain deletion markers across reconciliation so delayed HTTP responses and older Realtime rows cannot resurrect messages; cancel listeners on session end.

  • Preserve a live edit that arrives before the original send acknowledgement.

  • Reconcile missed messages, loaded edits/deletions and persisted receipts on private room rejoin without clearing pending sends or the loaded view.

  • Page history by a timestamp/ID cursor; preserve live changes arriving during REST reads and prevent older receipts from rewinding the displayed read state.

  • Bind conversation and inbox controllers to a session identity, discard late work after user/session replacement, and evict room caches on access denial.

  • Expire remote typing indicators and clear them on interruption.

  • Breaking custom-client contract: implement sessionIdentity, connectionEvents, onMessageDeleted, and the getMessages(before:) value cursor. Replace MessageChangeType.delete with MessageDeletedEvent on the separate deletion stream. The default adapter requires the core 0.3.x connection/cursor/deletion APIs. Do not publish this source with the existing package versions/dependency floor; coordinate new SDK/UI versions and backend deployment first.

0.2.2 #

  • Show Sending… for optimistic messages instead of a device-clock timestamp that can jump after acknowledgement.
  • Keep pending messages after canonical history and exclude them from read receipts.
  • Continue displaying acknowledged server timestamps in the viewer's local timezone.

0.2.1 #

  • Show outgoing messages immediately while the request completes, then reconcile the server response and realtime echo without duplicates.
  • Clear the composer immediately and restore its draft after a failed send when the user has not typed a replacement.

0.2.0 #

  • Require ConvoKit Flutter SDK 0.2.x for private Realtime channels and publishable-key discovery.
  • Preserve the existing Flutter component and configuration API.

0.1.4 #

  • Document the managed ConvoKit API endpoint used by the core SDK.
  • Remove endpoint configuration from the standard setup example.
  • Support inserted, updated, and deleted message events from core SDK 0.0.4.

0.1.3 #

  • Point the public package metadata to the accessible examples repository.

0.1.2 #

  • Point the component gallery to the public examples-only repository.
  • Add trusted GitHub Actions publishing for semantic-version tags.

0.1.1 #

  • Add real screenshots rendered from the public component showcase.
  • Document standard, branded support, and compact UI configurations.
  • Add public repository and issue tracker metadata.

0.1.0 #

  • Add SDK-backed and controlled conversation list components.
  • Add filterable offset pagination and automatic infinite scrolling.
  • Add SDK-backed conversation history, sending, realtime typing, and receipts.
  • Add extensible message, media, header, composer, state, and theme builders.
0
likes
0
points
919
downloads

Publisher

verified publisherconvokit.app

Weekly Downloads

Extensible, plug-and-play Flutter UI components for ConvoKit conversations and messaging.

Homepage
Repository (GitHub)
View/report issues

Topics

#chat #messaging #realtime #ui

License

unknown (license)

Dependencies

convokit_flutter, flutter

More

Packages that depend on convokit_flutter_ui