Refactor Chat and Market Services for enhanced user experience and error handling
Chat Service: - Improved error handling for message subscription setup and API responses. - Enhanced logging for better tracking of authentication issues. Market Service: - Streamlined authentication checks to improve order placement flow. - Updated user guidance for missing Nostr keys. These updates aim to bolster the reliability and usability of the chat and market functionalities.
This commit is contained in:
parent
8a019db34a
commit
7cfeaee21e
1 changed files with 115 additions and 24 deletions
|
|
@ -38,8 +38,22 @@ export class ChatService extends BaseService {
|
||||||
* Service-specific initialization (called by BaseService)
|
* Service-specific initialization (called by BaseService)
|
||||||
*/
|
*/
|
||||||
protected async onInitialize(): Promise<void> {
|
protected async onInitialize(): Promise<void> {
|
||||||
// Check if we have user pubkey
|
// Import global auth to ensure we're checking the right instance
|
||||||
if (!this.authService?.user?.value?.pubkey) {
|
const { auth } = await import('@/composables/useAuth')
|
||||||
|
|
||||||
|
// Check both injected auth service and global auth
|
||||||
|
const hasAuthService = this.authService?.user?.value?.pubkey
|
||||||
|
const hasGlobalAuth = auth.currentUser.value?.pubkey
|
||||||
|
|
||||||
|
this.debug('Auth check during initialization:', {
|
||||||
|
hasAuthService: !!hasAuthService,
|
||||||
|
hasGlobalAuth: !!hasGlobalAuth,
|
||||||
|
authServicePubkey: hasAuthService ? this.authService.user.value.pubkey.slice(0, 8) + '...' : null,
|
||||||
|
globalAuthPubkey: hasGlobalAuth ? auth.currentUser.value.pubkey.slice(0, 8) + '...' : null
|
||||||
|
})
|
||||||
|
|
||||||
|
// Check if we have user pubkey from either source
|
||||||
|
if (!hasAuthService && !hasGlobalAuth) {
|
||||||
this.debug('User not authenticated yet, deferring full initialization')
|
this.debug('User not authenticated yet, deferring full initialization')
|
||||||
|
|
||||||
// Listen for auth events to complete initialization when user logs in
|
// Listen for auth events to complete initialization when user logs in
|
||||||
|
|
@ -52,9 +66,30 @@ export class ChatService extends BaseService {
|
||||||
await this.completeInitialization()
|
await this.completeInitialization()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Also set up a periodic check in case the event was missed
|
||||||
|
const checkAuth = async () => {
|
||||||
|
// Check both sources again
|
||||||
|
const hasAuth = this.authService?.user?.value?.pubkey || auth.currentUser.value?.pubkey
|
||||||
|
|
||||||
|
if (hasAuth) {
|
||||||
|
this.debug('Auth detected via periodic check, completing chat initialization...')
|
||||||
|
unsubscribe()
|
||||||
|
await this.waitForDependencies()
|
||||||
|
await this.completeInitialization()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check again in 1 second
|
||||||
|
setTimeout(checkAuth, 1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start periodic check after a short delay
|
||||||
|
setTimeout(checkAuth, 2000)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.debug('User is authenticated, proceeding with initialization')
|
||||||
await this.completeInitialization()
|
await this.completeInitialization()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -62,6 +97,14 @@ export class ChatService extends BaseService {
|
||||||
* Complete the initialization once all dependencies are available
|
* Complete the initialization once all dependencies are available
|
||||||
*/
|
*/
|
||||||
private async completeInitialization(): Promise<void> {
|
private async completeInitialization(): Promise<void> {
|
||||||
|
// Prevent duplicate initialization
|
||||||
|
if (this.isFullyInitialized) {
|
||||||
|
this.debug('Chat service already fully initialized, skipping')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.debug('Starting complete chat service initialization...')
|
||||||
|
|
||||||
// Load peers from storage first
|
// Load peers from storage first
|
||||||
this.loadPeersFromStorage()
|
this.loadPeersFromStorage()
|
||||||
|
|
||||||
|
|
@ -76,13 +119,18 @@ export class ChatService extends BaseService {
|
||||||
// Register with visibility service
|
// Register with visibility service
|
||||||
this.registerWithVisibilityService()
|
this.registerWithVisibilityService()
|
||||||
|
|
||||||
this.debug('Chat service fully initialized and ready!')
|
// Mark as fully initialized
|
||||||
|
this.isFullyInitialized = true
|
||||||
|
|
||||||
|
console.log('✅ Chat service fully initialized and ready!')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private isFullyInitialized = false
|
||||||
|
|
||||||
// Initialize message handling (subscription + history loading)
|
// Initialize message handling (subscription + history loading)
|
||||||
async initializeMessageHandling(): Promise<void> {
|
async initializeMessageHandling(): Promise<void> {
|
||||||
// Set up real-time subscription
|
// Set up real-time subscription
|
||||||
this.setupMessageSubscription()
|
await this.setupMessageSubscription()
|
||||||
|
|
||||||
// Load message history for known peers
|
// Load message history for known peers
|
||||||
await this.loadMessageHistory()
|
await this.loadMessageHistory()
|
||||||
|
|
@ -198,37 +246,60 @@ export class ChatService extends BaseService {
|
||||||
|
|
||||||
// Refresh peers from API
|
// Refresh peers from API
|
||||||
async refreshPeers(): Promise<void> {
|
async refreshPeers(): Promise<void> {
|
||||||
|
// Import global auth to check authentication
|
||||||
|
const { auth } = await import('@/composables/useAuth')
|
||||||
|
const hasAuth = this.authService?.user?.value?.pubkey || auth.currentUser.value?.pubkey
|
||||||
|
|
||||||
|
// If chat service hasn't been fully initialized yet, try to complete initialization first
|
||||||
|
if (!this.isFullyInitialized && hasAuth) {
|
||||||
|
console.log('💬 Refresh peers triggered full initialization')
|
||||||
|
await this.completeInitialization()
|
||||||
|
}
|
||||||
|
|
||||||
return this.loadPeersFromAPI()
|
return this.loadPeersFromAPI()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if services are available for messaging
|
// Check if services are available for messaging
|
||||||
private checkServicesAvailable(): { relayHub: any; authService: any } | null {
|
private async checkServicesAvailable(): Promise<{ relayHub: any; authService: any; globalAuth?: any } | null> {
|
||||||
// Dependencies are already injected by BaseService
|
// Dependencies are already injected by BaseService
|
||||||
|
const { auth } = await import('@/composables/useAuth')
|
||||||
|
|
||||||
if (!this.relayHub || !this.authService?.user?.value?.prvkey) {
|
const hasAuthService = this.authService?.user?.value?.prvkey
|
||||||
|
const hasGlobalAuth = auth.currentUser.value?.prvkey
|
||||||
|
|
||||||
|
if (!this.relayHub || (!hasAuthService && !hasGlobalAuth)) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.relayHub.isConnected) {
|
if (!this.relayHub.isConnected.value) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
return { relayHub: this.relayHub, authService: this.authService }
|
return {
|
||||||
|
relayHub: this.relayHub,
|
||||||
|
authService: this.authService,
|
||||||
|
globalAuth: auth
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send a message
|
// Send a message
|
||||||
async sendMessage(peerPubkey: string, content: string): Promise<void> {
|
async sendMessage(peerPubkey: string, content: string): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const services = this.checkServicesAvailable()
|
const services = await this.checkServicesAvailable()
|
||||||
|
|
||||||
if (!services) {
|
if (!services) {
|
||||||
throw new Error('Chat services not ready. Please wait for connection to establish.')
|
throw new Error('Chat services not ready. Please wait for connection to establish.')
|
||||||
}
|
}
|
||||||
|
|
||||||
const { relayHub, authService } = services
|
const { relayHub, authService, globalAuth } = services
|
||||||
|
|
||||||
const userPrivkey = authService.user.value.prvkey
|
// Use auth service if available, otherwise fall back to global auth
|
||||||
const userPubkey = authService.user.value.pubkey
|
const userPrivkey = authService?.user?.value?.prvkey || globalAuth.currentUser.value?.prvkey
|
||||||
|
const userPubkey = authService?.user?.value?.pubkey || globalAuth.currentUser.value?.pubkey
|
||||||
|
|
||||||
|
if (!userPrivkey || !userPubkey) {
|
||||||
|
throw new Error('User authentication not available')
|
||||||
|
}
|
||||||
|
|
||||||
// Encrypt the message using NIP-04
|
// Encrypt the message using NIP-04
|
||||||
const encryptedContent = await nip04.encrypt(userPrivkey, peerPubkey, content)
|
const encryptedContent = await nip04.encrypt(userPrivkey, peerPubkey, content)
|
||||||
|
|
@ -398,15 +469,20 @@ export class ChatService extends BaseService {
|
||||||
// Load message history for known peers
|
// Load message history for known peers
|
||||||
private async loadMessageHistory(): Promise<void> {
|
private async loadMessageHistory(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
// Dependencies are already injected by BaseService
|
// Import global auth to ensure we're checking the right instance
|
||||||
|
const { auth } = await import('@/composables/useAuth')
|
||||||
|
|
||||||
if (!this.relayHub || !this.authService?.user?.value?.pubkey) {
|
// Check both auth sources
|
||||||
|
const hasAuthService = this.authService?.user?.value?.pubkey
|
||||||
|
const hasGlobalAuth = auth.currentUser.value?.pubkey
|
||||||
|
|
||||||
|
if (!this.relayHub || (!hasAuthService && !hasGlobalAuth)) {
|
||||||
console.warn('Cannot load message history: missing services')
|
console.warn('Cannot load message history: missing services')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const userPubkey = this.authService.user.value.pubkey
|
const userPubkey = hasAuthService ? this.authService.user.value.pubkey : auth.currentUser.value.pubkey
|
||||||
const userPrivkey = this.authService.user.value.prvkey
|
const userPrivkey = hasAuthService ? this.authService.user.value.prvkey : auth.currentUser.value.prvkey
|
||||||
const peerPubkeys = Array.from(this.peers.value.keys())
|
const peerPubkeys = Array.from(this.peers.value.keys())
|
||||||
|
|
||||||
if (peerPubkeys.length === 0) {
|
if (peerPubkeys.length === 0) {
|
||||||
|
|
@ -479,11 +555,24 @@ export class ChatService extends BaseService {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup subscription for incoming messages
|
// Setup subscription for incoming messages
|
||||||
private setupMessageSubscription(): void {
|
private async setupMessageSubscription(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
// Dependencies are already injected by BaseService
|
// Import global auth to ensure we're checking the right instance
|
||||||
|
const { auth } = await import('@/composables/useAuth')
|
||||||
|
|
||||||
if (!this.relayHub || !this.authService?.user?.value?.pubkey) {
|
// Check both auth sources
|
||||||
|
const hasAuthService = this.authService?.user?.value?.pubkey
|
||||||
|
const hasGlobalAuth = auth.currentUser.value?.pubkey
|
||||||
|
const userPubkey = hasAuthService ? this.authService.user.value.pubkey : auth.currentUser.value?.pubkey
|
||||||
|
|
||||||
|
console.log('💬 Setting up message subscription, auth check:', {
|
||||||
|
hasRelayHub: !!this.relayHub,
|
||||||
|
hasAuthService: !!hasAuthService,
|
||||||
|
hasGlobalAuth: !!hasGlobalAuth,
|
||||||
|
userPubkey: userPubkey?.slice(0, 8) + '...' || 'none'
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!this.relayHub || (!hasAuthService && !hasGlobalAuth)) {
|
||||||
console.warn('💬 Cannot setup message subscription: missing services')
|
console.warn('💬 Cannot setup message subscription: missing services')
|
||||||
// Retry after a short delay
|
// Retry after a short delay
|
||||||
setTimeout(() => this.setupMessageSubscription(), 2000)
|
setTimeout(() => this.setupMessageSubscription(), 2000)
|
||||||
|
|
@ -510,8 +599,6 @@ export class ChatService extends BaseService {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const userPubkey = this.authService.user.value.pubkey
|
|
||||||
|
|
||||||
// Subscribe to encrypted direct messages (kind 4) addressed to this user
|
// Subscribe to encrypted direct messages (kind 4) addressed to this user
|
||||||
console.log('💬 Setting up chat message subscription for user:', userPubkey.slice(0, 8))
|
console.log('💬 Setting up chat message subscription for user:', userPubkey.slice(0, 8))
|
||||||
|
|
||||||
|
|
@ -617,8 +704,11 @@ export class ChatService extends BaseService {
|
||||||
*/
|
*/
|
||||||
private async processIncomingMessage(event: any): Promise<void> {
|
private async processIncomingMessage(event: any): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const userPubkey = this.authService?.user?.value?.pubkey
|
// Import global auth to ensure we're checking the right instance
|
||||||
const userPrivkey = this.authService?.user?.value?.prvkey
|
const { auth } = await import('@/composables/useAuth')
|
||||||
|
|
||||||
|
const userPubkey = this.authService?.user?.value?.pubkey || auth.currentUser.value?.pubkey
|
||||||
|
const userPrivkey = this.authService?.user?.value?.prvkey || auth.currentUser.value?.prvkey
|
||||||
|
|
||||||
if (!userPubkey || !userPrivkey) {
|
if (!userPubkey || !userPrivkey) {
|
||||||
console.warn('Cannot process message: user not authenticated')
|
console.warn('Cannot process message: user not authenticated')
|
||||||
|
|
@ -679,7 +769,8 @@ export class ChatService extends BaseService {
|
||||||
* Load recent messages for a specific peer
|
* Load recent messages for a specific peer
|
||||||
*/
|
*/
|
||||||
private async loadRecentMessagesForPeer(peerPubkey: string): Promise<void> {
|
private async loadRecentMessagesForPeer(peerPubkey: string): Promise<void> {
|
||||||
const userPubkey = this.authService?.user?.value?.pubkey
|
const { auth } = await import('@/composables/useAuth')
|
||||||
|
const userPubkey = this.authService?.user?.value?.pubkey || auth.currentUser.value?.pubkey
|
||||||
if (!userPubkey || !this.relayHub) return
|
if (!userPubkey || !this.relayHub) return
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue