@convokitapp/vue-ui 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,8 +1,10 @@
1
- import { Conversation as Conversation$1, Message, MessageMedia, RealtimeSubscription, ReadEvent, TypingEvent, ConvoKitClient } from '@convokitapp/sdk';
1
+ import { Conversation as Conversation$1, MessageListOptions, Message, MessageMedia, RealtimeConnectionHandlers, RealtimeSubscription, MessageEvent, MessageDeletedEvent, ReadEvent, TypingEvent, ConvoKitClient } from '@convokitapp/sdk';
2
2
  import * as vue from 'vue';
3
3
  import { CSSProperties, HTMLAttributes, Ref, VNodeChild, PropType, MaybeRefOrGetter, TextareaHTMLAttributes } from 'vue';
4
4
 
5
+ /** Custom adapters must expose an identity unique to each login, including same-user logins. */
5
6
  interface ConvoKitUiClient {
7
+ readonly sessionIdentity: object | null;
6
8
  readonly currentUserId: string;
7
9
  getConversations(options: {
8
10
  limit: number;
@@ -10,11 +12,10 @@ interface ConvoKitUiClient {
10
12
  archived: boolean;
11
13
  }): Promise<Conversation$1[]>;
12
14
  getConversation(conversationId: string): Promise<Conversation$1>;
13
- getMessages(options: {
14
- conversationId: string;
15
- limit: number;
16
- offset: number;
17
- }): Promise<Message[]>;
15
+ /** Newest first, with a paired value cursor; never derive an offset from rendered rows. */
16
+ getMessages(options: MessageListOptions): Promise<Message[]>;
17
+ /** Complete authorized message, including related media absent from raw row events. */
18
+ getMessage(id: string): Promise<Message>;
18
19
  sendMessage(input: {
19
20
  conversationId: string;
20
21
  text?: string;
@@ -25,10 +26,13 @@ interface ConvoKitUiClient {
25
26
  conversationId: string;
26
27
  isTyping: boolean;
27
28
  }): Promise<void>;
28
- onMessage(conversationId: string, handler: (message: Message) => void, onError?: (error: Error) => void): RealtimeSubscription;
29
+ onConnectionEvent(handlers: RealtimeConnectionHandlers): RealtimeSubscription;
30
+ onMessage(conversationId: string, handler: (event: MessageEvent) => void, onError?: (error: Error) => void): RealtimeSubscription;
31
+ onMessageDeleted(conversationId: string, handler: (event: MessageDeletedEvent) => void, onError?: (error: Error) => void): RealtimeSubscription;
29
32
  onReadReceipt(conversationId: string, handler: (event: ReadEvent) => void, onError?: (error: Error) => void): RealtimeSubscription;
30
33
  onTyping(conversationId: string, handler: (event: TypingEvent) => void, onError?: (error: Error) => void): RealtimeSubscription;
31
34
  }
35
+
32
36
  interface ConversationFilter {
33
37
  query?: string;
34
38
  archived?: boolean;
@@ -59,6 +63,7 @@ interface ConversationState {
59
63
  readAtByUserId: Readonly<Ref<ReadonlyMap<string, Date>>>;
60
64
  isInitialLoading: Readonly<Ref<boolean>>;
61
65
  isLoadingOlder: Readonly<Ref<boolean>>;
66
+ isReconciling: Readonly<Ref<boolean>>;
62
67
  isSending: Readonly<Ref<boolean>>;
63
68
  hasOlderMessages: Readonly<Ref<boolean>>;
64
69
  hasLoaded: Readonly<Ref<boolean>>;
@@ -172,7 +177,7 @@ interface ConversationController extends ConversationState {
172
177
  updateTyping(isTyping: boolean): Promise<void>;
173
178
  dispose(): Promise<void>;
174
179
  }
175
- /** Owns one conversation's history, realtime state, sending, and read positions. */
180
+ /** Each room/login gets an independent owner; disposal also stops reactive reloads. */
176
181
  declare function useConversation(options: UseConversationOptions): ConversationController;
177
182
 
178
183
  interface ConversationViewProps extends ConvoKitAppearanceProps {
@@ -505,11 +510,14 @@ declare const ConversationView: vue.DefineComponent<vue.ExtractPropTypes<{
505
510
  "onAdd-attachment"?: (...args: any[]) => any;
506
511
  "onUpdate:modelValue"?: (...args: any[]) => any;
507
512
  }>, {
513
+ readonly typingUserIds: ReadonlySet<string>;
508
514
  readonly readAtByUserId: ReadonlyMap<string, Date>;
515
+ readonly isInitialLoading: boolean;
516
+ readonly isLoadingOlder: boolean;
517
+ readonly isSending: boolean;
518
+ readonly hasOlderMessages: boolean;
509
519
  readonly readersResolver: (message: Message) => ReadonlySet<string>;
510
520
  readonly onLoadOlder: () => void | Promise<void>;
511
- readonly hasOlderMessages: boolean;
512
- readonly isLoadingOlder: boolean;
513
521
  readonly onAttachmentClick: (media: MessageMedia, message: Message) => void;
514
522
  readonly paginationThreshold: number;
515
523
  readonly stickToBottom: boolean;
@@ -519,13 +527,10 @@ declare const ConversationView: vue.DefineComponent<vue.ExtractPropTypes<{
519
527
  readonly styles: Partial<Record<ConvoKitUiPart, CSSProperties>>;
520
528
  readonly density: ConvoKitUiDensity;
521
529
  readonly unstyled: boolean;
522
- readonly typingUserIds: ReadonlySet<string>;
523
530
  readonly onBack: () => void;
524
531
  readonly onRefresh: () => void | Promise<void>;
525
532
  readonly onTypingChange: (isTyping: boolean) => void | Promise<void>;
526
533
  readonly onAddAttachment: () => void;
527
- readonly isInitialLoading: boolean;
528
- readonly isSending: boolean;
529
534
  readonly displayNameForUser: (userId: string) => string | null | undefined;
530
535
  readonly reverseMessages: boolean;
531
536
  readonly composerPlaceholder: string;
@@ -902,12 +907,15 @@ declare const Conversation: vue.DefineComponent<vue.ExtractPropTypes<{
902
907
  }>, {
903
908
  messages: readonly Message[];
904
909
  conversation: Conversation$1;
905
- currentUserId: string;
910
+ typingUserIds: ReadonlySet<string>;
906
911
  readAtByUserId: ReadonlyMap<string, Date>;
912
+ isInitialLoading: boolean;
913
+ isLoadingOlder: boolean;
914
+ isSending: boolean;
915
+ hasOlderMessages: boolean;
916
+ currentUserId: string;
907
917
  readersResolver: (message: Message) => ReadonlySet<string>;
908
918
  onLoadOlder: () => void | Promise<void>;
909
- hasOlderMessages: boolean;
910
- isLoadingOlder: boolean;
911
919
  onAttachmentClick: (media: MessageMedia, message: Message) => void;
912
920
  paginationThreshold: number;
913
921
  stickToBottom: boolean;
@@ -918,13 +926,10 @@ declare const Conversation: vue.DefineComponent<vue.ExtractPropTypes<{
918
926
  density: ConvoKitUiDensity;
919
927
  unstyled: boolean;
920
928
  onSendMessage: (text: string) => boolean | void | Promise<boolean | void>;
921
- typingUserIds: ReadonlySet<string>;
922
929
  onBack: () => void;
923
930
  onRefresh: () => void | Promise<void>;
924
931
  onTypingChange: (isTyping: boolean) => void | Promise<void>;
925
932
  onAddAttachment: () => void;
926
- isInitialLoading: boolean;
927
- isSending: boolean;
928
933
  displayNameForUser: (userId: string) => string | null | undefined;
929
934
  reverseMessages: boolean;
930
935
  composerPlaceholder: string;
@@ -956,7 +961,6 @@ interface ConversationListController extends ConversationListState {
956
961
  setQuery(query: string): Promise<void>;
957
962
  dispose(): Promise<void>;
958
963
  }
959
- /** Loads, de-duplicates, filters, and paginates conversations. */
960
964
  declare function useConversationList(options: UseConversationListOptions): ConversationListController;
961
965
 
962
966
  interface ConversationListViewProps extends ConvoKitAppearanceProps {
@@ -1117,6 +1121,7 @@ declare const ConversationListView: vue.DefineComponent<vue.ExtractPropTypes<{
1117
1121
  "onConversation-select"?: (_conversation: Conversation$1) => any;
1118
1122
  "onLoad-more"?: () => any;
1119
1123
  }>, {
1124
+ readonly isInitialLoading: boolean;
1120
1125
  readonly scrollElement: Ref<HTMLElement | null, HTMLElement | null>;
1121
1126
  readonly paginationThreshold: number;
1122
1127
  readonly classNames: Partial<Record<ConvoKitUiPart, string>>;
@@ -1124,12 +1129,11 @@ declare const ConversationListView: vue.DefineComponent<vue.ExtractPropTypes<{
1124
1129
  readonly density: ConvoKitUiDensity;
1125
1130
  readonly unstyled: boolean;
1126
1131
  readonly onRefresh: () => void | Promise<void>;
1127
- readonly isInitialLoading: boolean;
1132
+ readonly isLoadingMore: boolean;
1133
+ readonly hasMore: boolean;
1128
1134
  readonly selectedConversationId: string;
1129
1135
  readonly onConversationSelect: (conversation: Conversation$1) => void;
1130
1136
  readonly onLoadMore: () => void | Promise<void>;
1131
- readonly isLoadingMore: boolean;
1132
- readonly hasMore: boolean;
1133
1137
  readonly ariaLabel: string;
1134
1138
  }, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
1135
1139
  interface ConversationListProps extends Omit<ConversationListViewProps, 'conversations' | 'onRefresh' | 'onLoadMore' | 'isInitialLoading' | 'isLoadingMore' | 'hasMore' | 'error'>, Omit<UseConversationListOptions, 'client'> {
@@ -1321,6 +1325,7 @@ declare const ConversationList: vue.DefineComponent<vue.ExtractPropTypes<{
1321
1325
  "onController-change"?: (...args: any[]) => any;
1322
1326
  "onConversation-select"?: (...args: any[]) => any;
1323
1327
  }>, {
1328
+ isInitialLoading: boolean;
1324
1329
  scrollElement: Ref<HTMLElement | null, HTMLElement | null>;
1325
1330
  paginationThreshold: number;
1326
1331
  classNames: Partial<Record<ConvoKitUiPart, string>>;
@@ -1328,15 +1333,14 @@ declare const ConversationList: vue.DefineComponent<vue.ExtractPropTypes<{
1328
1333
  density: ConvoKitUiDensity;
1329
1334
  unstyled: boolean;
1330
1335
  onRefresh: () => void | Promise<void>;
1331
- isInitialLoading: boolean;
1332
1336
  autoLoad: boolean;
1333
1337
  onControllerChange: (controller: ConversationListController) => void;
1334
1338
  conversations: readonly Conversation$1[];
1339
+ isLoadingMore: boolean;
1340
+ hasMore: boolean;
1335
1341
  selectedConversationId: string;
1336
1342
  onConversationSelect: (conversation: Conversation$1) => void;
1337
1343
  onLoadMore: () => void | Promise<void>;
1338
- isLoadingMore: boolean;
1339
- hasMore: boolean;
1340
1344
  ariaLabel: string;
1341
1345
  pageLoader: ConversationPageLoader;
1342
1346
  initialFilter: ConversationFilter;
@@ -1535,10 +1539,10 @@ declare const MessageListView: vue.DefineComponent<vue.ExtractPropTypes<{
1535
1539
  }>, {
1536
1540
  reverse: boolean;
1537
1541
  readAtByUserId: ReadonlyMap<string, Date>;
1542
+ isLoadingOlder: boolean;
1543
+ hasOlderMessages: boolean;
1538
1544
  readersResolver: (message: Message) => ReadonlySet<string>;
1539
1545
  onLoadOlder: () => void | Promise<void>;
1540
- hasOlderMessages: boolean;
1541
- isLoadingOlder: boolean;
1542
1546
  onAttachmentClick: (media: MessageMedia, message: Message) => void;
1543
1547
  scrollElement: Ref<HTMLElement | null, HTMLElement | null>;
1544
1548
  paginationThreshold: number;
@@ -1603,6 +1607,8 @@ declare const ConvoKitThemeProvider: vue.DefineComponent<vue.ExtractPropTypes<{
1603
1607
  }, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
1604
1608
  declare function useConvoKitTheme(): Readonly<Ref<ConvoKitTheme>>;
1605
1609
 
1610
+ /** Whether a message is an optimistic row awaiting server acknowledgement. */
1611
+ declare function isConvoKitPendingMessage(message: Message): boolean;
1606
1612
  declare function matchesConversation(conversation: Conversation$1, filter: ConversationFilter): boolean;
1607
1613
  declare function applyConversationFilter(conversations: readonly Conversation$1[], filter: ConversationFilter): Conversation$1[];
1608
1614
  declare function mergeConversations(current: readonly Conversation$1[], incoming: readonly Conversation$1[]): Conversation$1[];
@@ -1610,4 +1616,4 @@ declare function mergeMessages(current: readonly Message[], incoming: readonly M
1610
1616
  declare function readerIdsFor(message: Message, readAtByUserId: ReadonlyMap<string, Date>): ReadonlySet<string>;
1611
1617
  declare function formatFileSize(size: number | undefined): string | null;
1612
1618
 
1613
- export { type BaseViewProps, type ComposerSlotProps, Conversation, type ConversationController, type ConversationFilter, type ConversationItemSlotProps, ConversationList, type ConversationListController, type ConversationListProps, type ConversationListState, ConversationListView, type ConversationListViewProps, type ConversationPageLoader, type ConversationPageRequest, type ConversationProps, type ConversationState, ConversationView, type ConversationViewProps, type ConvoKitAppearanceProps, ConvoKitAvatar, type ConvoKitTheme, ConvoKitThemeProvider, type ConvoKitUiClient, type ConvoKitUiDensity, type ConvoKitUiPart, type ErrorSlot, type ErrorSlotProps, type MediaSlotProps, MessageListView, type MessageListViewProps, type MessageSlotProps, type ReadReceiptSlotProps, type ScrollOptions, type StateSlot, type TypingSlotProps, type UseConversationListOptions, type UseConversationOptions, applyConversationFilter, createConvoKitUiClient, defaultConvoKitTheme, defaultReadersResolver, formatFileSize, matchesConversation, mergeConversations, mergeMessages, readerIdsFor, useConversation, useConversationList, useConvoKitTheme };
1619
+ export { type BaseViewProps, type ComposerSlotProps, Conversation, type ConversationController, type ConversationFilter, type ConversationItemSlotProps, ConversationList, type ConversationListController, type ConversationListProps, type ConversationListState, ConversationListView, type ConversationListViewProps, type ConversationPageLoader, type ConversationPageRequest, type ConversationProps, type ConversationState, ConversationView, type ConversationViewProps, type ConvoKitAppearanceProps, ConvoKitAvatar, type ConvoKitTheme, ConvoKitThemeProvider, type ConvoKitUiClient, type ConvoKitUiDensity, type ConvoKitUiPart, type ErrorSlot, type ErrorSlotProps, type MediaSlotProps, MessageListView, type MessageListViewProps, type MessageSlotProps, type ReadReceiptSlotProps, type ScrollOptions, type StateSlot, type TypingSlotProps, type UseConversationListOptions, type UseConversationOptions, applyConversationFilter, createConvoKitUiClient, defaultConvoKitTheme, defaultReadersResolver, formatFileSize, isConvoKitPendingMessage, matchesConversation, mergeConversations, mergeMessages, readerIdsFor, useConversation, useConversationList, useConvoKitTheme };
package/dist/index.d.ts CHANGED
@@ -1,8 +1,10 @@
1
- import { Conversation as Conversation$1, Message, MessageMedia, RealtimeSubscription, ReadEvent, TypingEvent, ConvoKitClient } from '@convokitapp/sdk';
1
+ import { Conversation as Conversation$1, MessageListOptions, Message, MessageMedia, RealtimeConnectionHandlers, RealtimeSubscription, MessageEvent, MessageDeletedEvent, ReadEvent, TypingEvent, ConvoKitClient } from '@convokitapp/sdk';
2
2
  import * as vue from 'vue';
3
3
  import { CSSProperties, HTMLAttributes, Ref, VNodeChild, PropType, MaybeRefOrGetter, TextareaHTMLAttributes } from 'vue';
4
4
 
5
+ /** Custom adapters must expose an identity unique to each login, including same-user logins. */
5
6
  interface ConvoKitUiClient {
7
+ readonly sessionIdentity: object | null;
6
8
  readonly currentUserId: string;
7
9
  getConversations(options: {
8
10
  limit: number;
@@ -10,11 +12,10 @@ interface ConvoKitUiClient {
10
12
  archived: boolean;
11
13
  }): Promise<Conversation$1[]>;
12
14
  getConversation(conversationId: string): Promise<Conversation$1>;
13
- getMessages(options: {
14
- conversationId: string;
15
- limit: number;
16
- offset: number;
17
- }): Promise<Message[]>;
15
+ /** Newest first, with a paired value cursor; never derive an offset from rendered rows. */
16
+ getMessages(options: MessageListOptions): Promise<Message[]>;
17
+ /** Complete authorized message, including related media absent from raw row events. */
18
+ getMessage(id: string): Promise<Message>;
18
19
  sendMessage(input: {
19
20
  conversationId: string;
20
21
  text?: string;
@@ -25,10 +26,13 @@ interface ConvoKitUiClient {
25
26
  conversationId: string;
26
27
  isTyping: boolean;
27
28
  }): Promise<void>;
28
- onMessage(conversationId: string, handler: (message: Message) => void, onError?: (error: Error) => void): RealtimeSubscription;
29
+ onConnectionEvent(handlers: RealtimeConnectionHandlers): RealtimeSubscription;
30
+ onMessage(conversationId: string, handler: (event: MessageEvent) => void, onError?: (error: Error) => void): RealtimeSubscription;
31
+ onMessageDeleted(conversationId: string, handler: (event: MessageDeletedEvent) => void, onError?: (error: Error) => void): RealtimeSubscription;
29
32
  onReadReceipt(conversationId: string, handler: (event: ReadEvent) => void, onError?: (error: Error) => void): RealtimeSubscription;
30
33
  onTyping(conversationId: string, handler: (event: TypingEvent) => void, onError?: (error: Error) => void): RealtimeSubscription;
31
34
  }
35
+
32
36
  interface ConversationFilter {
33
37
  query?: string;
34
38
  archived?: boolean;
@@ -59,6 +63,7 @@ interface ConversationState {
59
63
  readAtByUserId: Readonly<Ref<ReadonlyMap<string, Date>>>;
60
64
  isInitialLoading: Readonly<Ref<boolean>>;
61
65
  isLoadingOlder: Readonly<Ref<boolean>>;
66
+ isReconciling: Readonly<Ref<boolean>>;
62
67
  isSending: Readonly<Ref<boolean>>;
63
68
  hasOlderMessages: Readonly<Ref<boolean>>;
64
69
  hasLoaded: Readonly<Ref<boolean>>;
@@ -172,7 +177,7 @@ interface ConversationController extends ConversationState {
172
177
  updateTyping(isTyping: boolean): Promise<void>;
173
178
  dispose(): Promise<void>;
174
179
  }
175
- /** Owns one conversation's history, realtime state, sending, and read positions. */
180
+ /** Each room/login gets an independent owner; disposal also stops reactive reloads. */
176
181
  declare function useConversation(options: UseConversationOptions): ConversationController;
177
182
 
178
183
  interface ConversationViewProps extends ConvoKitAppearanceProps {
@@ -505,11 +510,14 @@ declare const ConversationView: vue.DefineComponent<vue.ExtractPropTypes<{
505
510
  "onAdd-attachment"?: (...args: any[]) => any;
506
511
  "onUpdate:modelValue"?: (...args: any[]) => any;
507
512
  }>, {
513
+ readonly typingUserIds: ReadonlySet<string>;
508
514
  readonly readAtByUserId: ReadonlyMap<string, Date>;
515
+ readonly isInitialLoading: boolean;
516
+ readonly isLoadingOlder: boolean;
517
+ readonly isSending: boolean;
518
+ readonly hasOlderMessages: boolean;
509
519
  readonly readersResolver: (message: Message) => ReadonlySet<string>;
510
520
  readonly onLoadOlder: () => void | Promise<void>;
511
- readonly hasOlderMessages: boolean;
512
- readonly isLoadingOlder: boolean;
513
521
  readonly onAttachmentClick: (media: MessageMedia, message: Message) => void;
514
522
  readonly paginationThreshold: number;
515
523
  readonly stickToBottom: boolean;
@@ -519,13 +527,10 @@ declare const ConversationView: vue.DefineComponent<vue.ExtractPropTypes<{
519
527
  readonly styles: Partial<Record<ConvoKitUiPart, CSSProperties>>;
520
528
  readonly density: ConvoKitUiDensity;
521
529
  readonly unstyled: boolean;
522
- readonly typingUserIds: ReadonlySet<string>;
523
530
  readonly onBack: () => void;
524
531
  readonly onRefresh: () => void | Promise<void>;
525
532
  readonly onTypingChange: (isTyping: boolean) => void | Promise<void>;
526
533
  readonly onAddAttachment: () => void;
527
- readonly isInitialLoading: boolean;
528
- readonly isSending: boolean;
529
534
  readonly displayNameForUser: (userId: string) => string | null | undefined;
530
535
  readonly reverseMessages: boolean;
531
536
  readonly composerPlaceholder: string;
@@ -902,12 +907,15 @@ declare const Conversation: vue.DefineComponent<vue.ExtractPropTypes<{
902
907
  }>, {
903
908
  messages: readonly Message[];
904
909
  conversation: Conversation$1;
905
- currentUserId: string;
910
+ typingUserIds: ReadonlySet<string>;
906
911
  readAtByUserId: ReadonlyMap<string, Date>;
912
+ isInitialLoading: boolean;
913
+ isLoadingOlder: boolean;
914
+ isSending: boolean;
915
+ hasOlderMessages: boolean;
916
+ currentUserId: string;
907
917
  readersResolver: (message: Message) => ReadonlySet<string>;
908
918
  onLoadOlder: () => void | Promise<void>;
909
- hasOlderMessages: boolean;
910
- isLoadingOlder: boolean;
911
919
  onAttachmentClick: (media: MessageMedia, message: Message) => void;
912
920
  paginationThreshold: number;
913
921
  stickToBottom: boolean;
@@ -918,13 +926,10 @@ declare const Conversation: vue.DefineComponent<vue.ExtractPropTypes<{
918
926
  density: ConvoKitUiDensity;
919
927
  unstyled: boolean;
920
928
  onSendMessage: (text: string) => boolean | void | Promise<boolean | void>;
921
- typingUserIds: ReadonlySet<string>;
922
929
  onBack: () => void;
923
930
  onRefresh: () => void | Promise<void>;
924
931
  onTypingChange: (isTyping: boolean) => void | Promise<void>;
925
932
  onAddAttachment: () => void;
926
- isInitialLoading: boolean;
927
- isSending: boolean;
928
933
  displayNameForUser: (userId: string) => string | null | undefined;
929
934
  reverseMessages: boolean;
930
935
  composerPlaceholder: string;
@@ -956,7 +961,6 @@ interface ConversationListController extends ConversationListState {
956
961
  setQuery(query: string): Promise<void>;
957
962
  dispose(): Promise<void>;
958
963
  }
959
- /** Loads, de-duplicates, filters, and paginates conversations. */
960
964
  declare function useConversationList(options: UseConversationListOptions): ConversationListController;
961
965
 
962
966
  interface ConversationListViewProps extends ConvoKitAppearanceProps {
@@ -1117,6 +1121,7 @@ declare const ConversationListView: vue.DefineComponent<vue.ExtractPropTypes<{
1117
1121
  "onConversation-select"?: (_conversation: Conversation$1) => any;
1118
1122
  "onLoad-more"?: () => any;
1119
1123
  }>, {
1124
+ readonly isInitialLoading: boolean;
1120
1125
  readonly scrollElement: Ref<HTMLElement | null, HTMLElement | null>;
1121
1126
  readonly paginationThreshold: number;
1122
1127
  readonly classNames: Partial<Record<ConvoKitUiPart, string>>;
@@ -1124,12 +1129,11 @@ declare const ConversationListView: vue.DefineComponent<vue.ExtractPropTypes<{
1124
1129
  readonly density: ConvoKitUiDensity;
1125
1130
  readonly unstyled: boolean;
1126
1131
  readonly onRefresh: () => void | Promise<void>;
1127
- readonly isInitialLoading: boolean;
1132
+ readonly isLoadingMore: boolean;
1133
+ readonly hasMore: boolean;
1128
1134
  readonly selectedConversationId: string;
1129
1135
  readonly onConversationSelect: (conversation: Conversation$1) => void;
1130
1136
  readonly onLoadMore: () => void | Promise<void>;
1131
- readonly isLoadingMore: boolean;
1132
- readonly hasMore: boolean;
1133
1137
  readonly ariaLabel: string;
1134
1138
  }, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
1135
1139
  interface ConversationListProps extends Omit<ConversationListViewProps, 'conversations' | 'onRefresh' | 'onLoadMore' | 'isInitialLoading' | 'isLoadingMore' | 'hasMore' | 'error'>, Omit<UseConversationListOptions, 'client'> {
@@ -1321,6 +1325,7 @@ declare const ConversationList: vue.DefineComponent<vue.ExtractPropTypes<{
1321
1325
  "onController-change"?: (...args: any[]) => any;
1322
1326
  "onConversation-select"?: (...args: any[]) => any;
1323
1327
  }>, {
1328
+ isInitialLoading: boolean;
1324
1329
  scrollElement: Ref<HTMLElement | null, HTMLElement | null>;
1325
1330
  paginationThreshold: number;
1326
1331
  classNames: Partial<Record<ConvoKitUiPart, string>>;
@@ -1328,15 +1333,14 @@ declare const ConversationList: vue.DefineComponent<vue.ExtractPropTypes<{
1328
1333
  density: ConvoKitUiDensity;
1329
1334
  unstyled: boolean;
1330
1335
  onRefresh: () => void | Promise<void>;
1331
- isInitialLoading: boolean;
1332
1336
  autoLoad: boolean;
1333
1337
  onControllerChange: (controller: ConversationListController) => void;
1334
1338
  conversations: readonly Conversation$1[];
1339
+ isLoadingMore: boolean;
1340
+ hasMore: boolean;
1335
1341
  selectedConversationId: string;
1336
1342
  onConversationSelect: (conversation: Conversation$1) => void;
1337
1343
  onLoadMore: () => void | Promise<void>;
1338
- isLoadingMore: boolean;
1339
- hasMore: boolean;
1340
1344
  ariaLabel: string;
1341
1345
  pageLoader: ConversationPageLoader;
1342
1346
  initialFilter: ConversationFilter;
@@ -1535,10 +1539,10 @@ declare const MessageListView: vue.DefineComponent<vue.ExtractPropTypes<{
1535
1539
  }>, {
1536
1540
  reverse: boolean;
1537
1541
  readAtByUserId: ReadonlyMap<string, Date>;
1542
+ isLoadingOlder: boolean;
1543
+ hasOlderMessages: boolean;
1538
1544
  readersResolver: (message: Message) => ReadonlySet<string>;
1539
1545
  onLoadOlder: () => void | Promise<void>;
1540
- hasOlderMessages: boolean;
1541
- isLoadingOlder: boolean;
1542
1546
  onAttachmentClick: (media: MessageMedia, message: Message) => void;
1543
1547
  scrollElement: Ref<HTMLElement | null, HTMLElement | null>;
1544
1548
  paginationThreshold: number;
@@ -1603,6 +1607,8 @@ declare const ConvoKitThemeProvider: vue.DefineComponent<vue.ExtractPropTypes<{
1603
1607
  }, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
1604
1608
  declare function useConvoKitTheme(): Readonly<Ref<ConvoKitTheme>>;
1605
1609
 
1610
+ /** Whether a message is an optimistic row awaiting server acknowledgement. */
1611
+ declare function isConvoKitPendingMessage(message: Message): boolean;
1606
1612
  declare function matchesConversation(conversation: Conversation$1, filter: ConversationFilter): boolean;
1607
1613
  declare function applyConversationFilter(conversations: readonly Conversation$1[], filter: ConversationFilter): Conversation$1[];
1608
1614
  declare function mergeConversations(current: readonly Conversation$1[], incoming: readonly Conversation$1[]): Conversation$1[];
@@ -1610,4 +1616,4 @@ declare function mergeMessages(current: readonly Message[], incoming: readonly M
1610
1616
  declare function readerIdsFor(message: Message, readAtByUserId: ReadonlyMap<string, Date>): ReadonlySet<string>;
1611
1617
  declare function formatFileSize(size: number | undefined): string | null;
1612
1618
 
1613
- export { type BaseViewProps, type ComposerSlotProps, Conversation, type ConversationController, type ConversationFilter, type ConversationItemSlotProps, ConversationList, type ConversationListController, type ConversationListProps, type ConversationListState, ConversationListView, type ConversationListViewProps, type ConversationPageLoader, type ConversationPageRequest, type ConversationProps, type ConversationState, ConversationView, type ConversationViewProps, type ConvoKitAppearanceProps, ConvoKitAvatar, type ConvoKitTheme, ConvoKitThemeProvider, type ConvoKitUiClient, type ConvoKitUiDensity, type ConvoKitUiPart, type ErrorSlot, type ErrorSlotProps, type MediaSlotProps, MessageListView, type MessageListViewProps, type MessageSlotProps, type ReadReceiptSlotProps, type ScrollOptions, type StateSlot, type TypingSlotProps, type UseConversationListOptions, type UseConversationOptions, applyConversationFilter, createConvoKitUiClient, defaultConvoKitTheme, defaultReadersResolver, formatFileSize, matchesConversation, mergeConversations, mergeMessages, readerIdsFor, useConversation, useConversationList, useConvoKitTheme };
1619
+ export { type BaseViewProps, type ComposerSlotProps, Conversation, type ConversationController, type ConversationFilter, type ConversationItemSlotProps, ConversationList, type ConversationListController, type ConversationListProps, type ConversationListState, ConversationListView, type ConversationListViewProps, type ConversationPageLoader, type ConversationPageRequest, type ConversationProps, type ConversationState, ConversationView, type ConversationViewProps, type ConvoKitAppearanceProps, ConvoKitAvatar, type ConvoKitTheme, ConvoKitThemeProvider, type ConvoKitUiClient, type ConvoKitUiDensity, type ConvoKitUiPart, type ErrorSlot, type ErrorSlotProps, type MediaSlotProps, MessageListView, type MessageListViewProps, type MessageSlotProps, type ReadReceiptSlotProps, type ScrollOptions, type StateSlot, type TypingSlotProps, type UseConversationListOptions, type UseConversationOptions, applyConversationFilter, createConvoKitUiClient, defaultConvoKitTheme, defaultReadersResolver, formatFileSize, isConvoKitPendingMessage, matchesConversation, mergeConversations, mergeMessages, readerIdsFor, useConversation, useConversationList, useConvoKitTheme };