useDM Store
File: src/stores/useDM.ts
Overview
Exports
- DMUser - interface export
- DMConversation - interface export
- DMCache - interface export
- useDMStore - const export
Functions
isUserOnline(userId: string)
No description available.
Parameters:
userId: string
Returns: Promise<boolean>
const isUserOnline = async (userId: string): Promise<boolean> =>evictOldestCache()
No description available.
Parameters: None
Returns: Unknown
const evictOldestCache = () =>isCacheValid(conversationId: string)
No description available.
Parameters:
conversationId: string
Returns: boolean
const isCacheValid = (conversationId: string): boolean =>loadCachedMessages(conversationId: string)
No description available.
Parameters:
conversationId: string
Returns: Unknown
const loadCachedMessages = (conversationId: string) =>addMessageToCache(message: Message)
No description available.
Parameters:
message: Message
Returns: Unknown
const addMessageToCache = (message: Message) =>updateMessageInCache(messageId: string, updatedMessage: Message)
No description available.
Parameters:
messageId: stringupdatedMessage: Message
Returns: Unknown
const updateMessageInCache = (messageId: string, updatedMessage: Message) =>reprocessEncryptedDMMessages()
No description available.
Parameters: None
Returns: Unknown
const reprocessEncryptedDMMessages = async () =>setupEncryptionKeyListener()
No description available.
Parameters: None
Returns: Unknown
const setupEncryptionKeyListener = () =>removeMessageFromCache(messageId: string)
No description available.
Parameters:
messageId: string
Returns: Unknown
const removeMessageFromCache = (messageId: string) =>fetchReplyMessage(messageId: string)
No description available.
Parameters:
messageId: string
Returns: Promise<Message | null>
const fetchReplyMessage = async (messageId: string): Promise<Message | null> =>checkCache()
No description available.
Parameters: None
Returns: Unknown
const checkCache = () =>_fetchSingleMessage(messageId: string)
No description available.
Parameters:
messageId: string
Returns: Promise<Message | null>
const _fetchSingleMessage = async (messageId: string): Promise<Message | null> =>initializeDMEnvironment(userId: string, forceRefresh = false, metadataOnly = false, loadStrategy: 'lazy' | 'partial' | 'immediate' = 'partial')
No description available.
Parameters:
userId: stringforceRefresh = falsemetadataOnly = falseloadStrategy: 'lazy' | 'partial' | 'immediate' = 'partial'
Returns: Unknown
/**
* Initialize DM environment with configurable loading strategies:
* - 'lazy': User profiles load only on hover (maximum performance, placeholder UX)
* - 'partial': Load user profiles for 20 most recent conversations immediately (balanced)
* - 'immediate': Load ALL user profiles right away (best UX, more database load)
*/
const initializeDMEnvironment = async (userId: string, forceRefresh = false, metadataOnly = false, loadStrategy: 'lazy' | 'partial' | 'immediate' = 'partial') =>fetchUserConversationsMetadata(userId: string, loadStrategy: 'lazy' | 'partial' | 'immediate' = 'partial')
No description available.
Parameters:
userId: stringloadStrategy: 'lazy' | 'partial' | 'immediate' = 'partial'
Returns: Unknown
const fetchUserConversationsMetadata = async (userId: string, loadStrategy: 'lazy' | 'partial' | 'immediate' = 'partial') =>fetchPromise(async ()
No description available.
Parameters:
async (
Returns: Unknown
const fetchPromise = (async () =>fetchConversationDetails(conversationId: string, currentUserId: string)
No description available.
Parameters:
conversationId: stringcurrentUserId: string
Returns: Unknown
const fetchConversationDetails = async (conversationId: string, currentUserId: string) =>_fetchSpecificConversation(conversationId: string)
No description available.
Parameters:
conversationId: string
Returns: Unknown
const _fetchSpecificConversation = async (conversationId: string) =>initializeDMEnvironmentForDirectAccess(userId: string, conversationId?: string)
No description available.
Parameters:
userId: stringconversationId?: string
Returns: Unknown
const initializeDMEnvironmentForDirectAccess = async (userId: string, conversationId?: string) =>fetchUserConversations(userId: string)
No description available.
Parameters:
userId: string
Returns: Unknown
const fetchUserConversations = async (userId: string) =>_fetchRawConversations(userId: string)
No description available.
Parameters:
userId: string
Returns: Unknown
const _fetchRawConversations = async (userId: string) =>_preloadUserProfiles(conversationsData: any[])
No description available.
Parameters:
conversationsData: any[]
Returns: Unknown
const _preloadUserProfiles = async (conversationsData: any[]) =>_processConversationData(conv: any, userId: string)
No description available.
Parameters:
conv: anyuserId: string
Returns: Promise<DMConversation | null>
const _processConversationData = async (conv: any, userId: string): Promise<DMConversation | null> =>_fetchUserProfile(userId: string)
No description available.
Parameters:
userId: string
Returns: Unknown
const _fetchUserProfile = async (userId: string) =>_normalizeUserObject(user: any)
No description available.
Parameters:
user: any
Returns: DMUser
const _normalizeUserObject = (user: any): DMUser =>_fetchLastMessage(conversationId: string)
No description available.
Parameters:
conversationId: string
Returns: Unknown
const _fetchLastMessage = async (conversationId: string) =>fetchConversationMessages(conversationId: string, beforeMessageId?: string, signal?: AbortSignal)
No description available.
Parameters:
conversationId: stringbeforeMessageId?: stringsignal?: AbortSignal
Returns: Unknown
const fetchConversationMessages = async (conversationId: string, beforeMessageId?: string, signal?: AbortSignal) =>searchUsers(query: string, currentUserId: string)
No description available.
Parameters:
query: stringcurrentUserId: string
Returns: Unknown
const searchUsers = async (query: string, currentUserId: string) =>_searchLocalUsers(query: string, currentUserId: string)
No description available.
Parameters:
query: stringcurrentUserId: string
Returns: Unknown
const _searchLocalUsers = async (query: string, currentUserId: string) =>createOrGetConversation(user1Id: string, user2Id: string)
No description available.
Parameters:
user1Id: stringuser2Id: string
Returns: Promise<string | null>
const createOrGetConversation = async (user1Id: string, user2Id: string): Promise<string | null> =>_createOrFindConversation(user1Id: string, user2Id: string)
No description available.
Parameters:
user1Id: stringuser2Id: string
Returns: Promise<string | null>
const _createOrFindConversation = async (user1Id: string, user2Id: string): Promise<string | null> =>sendDMMessage(conversationId: string, userId: string, content: MessagePart[], replyTo?: string)
No description available.
Parameters:
conversationId: stringuserId: stringcontent: MessagePart[]replyTo?: string
Returns: Promise<boolean>
const sendDMMessage = async (
conversationId: string,
userId: string,
content: MessagePart[],
replyTo?: string
): Promise<boolean> =>setCurrentConversation(conversationId: string | null)
No description available.
Parameters:
conversationId: string | null
Returns: Unknown
const setCurrentConversation = (conversationId: string | null) =>switchToConversation(conversationId: string)
No description available.
Parameters:
conversationId: string
Returns: Unknown
const switchToConversation = async (conversationId: string) =>clearDMMessages()
No description available.
Parameters: None
Returns: Unknown
const clearDMMessages = () =>cleanupRealtimeSubscriptions()
No description available.
Parameters: None
Returns: Unknown
const cleanupRealtimeSubscriptions = () =>cleanupConversationSubscription(conversationId: string)
No description available.
Parameters:
conversationId: string
Returns: Unknown
const cleanupConversationSubscription = (conversationId: string) =>setupRealtimeSubscriptions(userId: string)
No description available.
Parameters:
userId: string
Returns: Unknown
/**
* Setup global DM realtime subscriptions using RealtimeConnectionManager
* Includes conversations updates and reactions
*/
const setupRealtimeSubscriptions = async (userId: string) =>reactionsUnsubscribe()
No description available.
Parameters: None
Returns: Unknown
const reactionsUnsubscribe = () =>setupConversationSubscription(conversationId: string)
No description available.
Parameters:
conversationId: string
Returns: Unknown
/**
* Setup subscription for a specific DM conversation using RealtimeConnectionManager
* Handles INSERT, UPDATE, DELETE events with automatic reconnection
*/
const setupConversationSubscription = (conversationId: string) =>updateConversationFromMessage(message: any)
No description available.
Parameters:
message: any
Returns: Unknown
const updateConversationFromMessage = (message: any) =>cleanup()
No description available.
Parameters: None
Returns: Unknown
const cleanup = () =>processFederatedDM(activity: any, note: any)
No description available.
Parameters:
activity: anynote: any
Returns: Unknown
const processFederatedDM = async (activity: any, note: any) =>validateMentionTag(tag: any)
No description available.
Parameters:
tag: any
Returns: boolean
const validateMentionTag = (tag: any): boolean =>generateActivityPubMentionTags(content: MessagePart[], recipientUrls: string[], instanceDomain: string)
No description available.
Parameters:
content: MessagePart[]recipientUrls: string[]instanceDomain: string
Returns: any[]
const generateActivityPubMentionTags = (
content: MessagePart[],
recipientUrls: string[],
instanceDomain: string
): any[] =>debugConversationQueries(userId?: string)
No description available.
Parameters:
userId?: string
Returns: Unknown
const debugConversationQueries = async (userId?: string) =>checkMigrationStatus()
No description available.
Parameters: None
Returns: Unknown
const checkMigrationStatus = async () =>`createGroupConversation(options: {
participantIds: string[] // User IDs
name?: string
isPrivate?: boolean
})`
No description available.
Parameters:
options: { participantIds: string[] // User IDs name?: string isPrivate?: boolean }
Returns: Promise<string | null>
/**
* Create a group conversation with multiple participants
*/
const createGroupConversation = async (options: {
participantIds: string[] // User IDs
name?: string
isPrivate?: boolean
}): Promise<string | null> =>addUsersToConversation(conversationId: string, userIds: string[], currentUserId: string)
No description available.
Parameters:
conversationId: stringuserIds: string[]currentUserId: string
Returns: Promise<boolean | string>
/**
* Add users to an existing conversation (convert 1:1 to group or add to group)
*/
const addUsersToConversation = async (
conversationId: string,
userIds: string[],
currentUserId: string
): Promise<boolean | string> =>getConversationParticipants(conversationId: string)
No description available.
Parameters:
conversationId: string
Returns: Promise<DMUser[]>
/**
* Get all participants of a conversation
*/
const getConversationParticipants = async (conversationId: string): Promise<DMUser[]> =>federateGroupDMMessage(message: any, participants: DMUser[])
No description available.
Parameters:
message: anyparticipants: DMUser[]
Returns: Promise<boolean>
/**
* ActivityPub federation for group DMs
*
* NOTE: Federation is handled AUTOMATICALLY by the federation-backend service.
* The DatabaseListener.handleNewDM() function handles:
* 1. Getting all conversation participants
* 2. Filtering to remote/federated users only
* 3. Creating private ActivityPub Notes with direct addressing (to: [recipient])
* 4. Adding proper mention tags for all participants
* 5. Delivering to each external participant's inbox via DeliveryQueue
* 6. Handling delivery failures and retries
*
* This client-side function is for validation/logging only.
* The actual federation happens when a message is inserted into the messages table.
*
* @see federation-backend/src/listeners/DatabaseListener.ts handleNewDM()
*/
const federateGroupDMMessage = async (
message: any,
participants: DMUser[]
): Promise<boolean> =>loadConversationUserProfile(conversationId: string)
No description available.
Parameters:
conversationId: string
Returns: Promise<boolean>
const loadConversationUserProfile = async (conversationId: string): Promise<boolean> =>loadMultipleConversationUserProfiles(conversationIds: string[])
No description available.
Parameters:
conversationIds: string[]
Returns: Promise<void>
const loadMultipleConversationUserProfiles = async (conversationIds: string[]): Promise<void> =>Interfaces
DMUser
No description available.
interface DMUser {
id: string
username: string
display_name?: string
avatar_url?: string
is_online?: boolean
last_seen?: string
// Federated user support
domain?: string
is_local?: boolean
federated_id?: string
handle?: string
color?: string // Optional color for UI
// Optimization: Track if this is placeholder data that needs to be loaded
_isPlaceholder?: boolean
}DMConversation
No description available.
interface DMConversation {
id: string
created_at: string
last_activity?: string
last_message?: Message
unread_count?: number
other_user?: DMUser // For direct conversations
type?: string // 'direct' | 'group'
participant_count?: number
// Group conversation fields
name?: string // Group name
icon_url?: string // Group icon
created_by?: string // Creator user ID
participants?: DMUser[] // All participants for group chats
}DMCache
No description available.
interface DMCache {
messages: Message[]
lastFetchedAt: Date
oldestMessageId: string | null
allMessagesLoaded: boolean
lastModified: Date
}Source Code Insights
File Size: 94702 characters Lines of Code: 2573 Imports: 13
Usage Example
import { DMUser, DMConversation, DMCache, useDMStore } from '@/stores/useDM'
// Example usage
isUserOnline()This documentation was automatically generated from the source code.
