- Introduced ReactionService to manage event reactions, including likes and dislikes. - Updated NostrFeed module to register ReactionService in the DI container and initialize it during installation. - Enhanced NostrFeed.vue to utilize the reactions service for displaying and managing likes on posts. - Created useReactions composable for handling reactions, including fetching event reactions and subscribing to updates. These changes enhance user engagement by allowing users to interact with posts through reactions, improving the overall experience within the feed. Refactor reactions handling in NostrFeed module - Renamed `likeEvent` to `toggleLike` in the useReactions composable to better reflect its functionality of toggling likes. - Updated NostrFeed.vue to utilize the new `toggleLike` method for handling like interactions. - Enhanced ReactionService to support deletion of reactions and improved handling of reaction events, including subscription to deletion events. - Added logic to manage user reaction IDs for better tracking of likes and unlikes. These changes streamline the reactions functionality, improving user interaction and feedback within the NostrFeed. Refactor content filters and event inclusion logic in NostrFeed module - Removed market-related content filters from the presets, as they now have a dedicated section. - Updated the handling of reactions in content filters, clarifying that reactions are processed separately by the ReactionService. - Enhanced the FeedService to exclude reactions and deletions from the main feed, ensuring cleaner event management. These changes streamline the content filtering process and improve the clarity of event handling within the NostrFeed. Refactor content filters and FeedService logic for marketplace separation - Removed marketplace-related filters from the general presets in content-filters.ts, as they now have a dedicated section. - Updated FeedService to exclude marketplace events from the main feed, ensuring clearer event management. - Adjusted Home.vue to reflect the removal of the marketplace filter preset. These changes streamline content filtering and improve the organization of marketplace events within the NostrFeed module. Enhance ReactionService to support global deletion monitoring and improve reaction handling - Added functionality to monitor deletion events for reactions, ensuring accurate updates when reactions are deleted. - Implemented logic to handle deletion requests, processing only those from the original reaction authors as per NIP-09 spec. - Updated reaction management to ensure only the latest reaction from each user is counted, improving the accuracy of like/dislike tallies. - Refactored event reaction updates to clear deleted reactions and maintain a clean state. These changes enhance the reliability and user experience of the reactions feature within the NostrFeed module.
169 lines
No EOL
4 KiB
TypeScript
169 lines
No EOL
4 KiB
TypeScript
import type { DIContainer, ServiceToken } from './types'
|
|
|
|
export type { ServiceToken } from './types'
|
|
|
|
interface ServiceRegistration {
|
|
service: any
|
|
scope: 'singleton' | 'transient'
|
|
instance?: any
|
|
}
|
|
|
|
/**
|
|
* Dependency Injection Container
|
|
* Manages service registration and injection across modules
|
|
*/
|
|
export class DIContainerImpl implements DIContainer {
|
|
private services = new Map<ServiceToken, ServiceRegistration>()
|
|
|
|
/**
|
|
* Register a service in the container
|
|
*/
|
|
provide<T>(token: ServiceToken, service: T, scope: 'singleton' | 'transient' = 'singleton'): void {
|
|
this.services.set(token, {
|
|
service,
|
|
scope,
|
|
instance: scope === 'singleton' ? service : undefined
|
|
})
|
|
}
|
|
|
|
/**
|
|
* Inject a service from the container
|
|
*/
|
|
inject<T>(token: ServiceToken): T | undefined {
|
|
const registration = this.services.get(token)
|
|
|
|
if (!registration) {
|
|
return undefined
|
|
}
|
|
|
|
if (registration.scope === 'singleton') {
|
|
return registration.instance as T
|
|
}
|
|
|
|
// For transient services, create new instance
|
|
// Note: This assumes the service is a constructor function
|
|
if (typeof registration.service === 'function') {
|
|
try {
|
|
return new registration.service() as T
|
|
} catch (error) {
|
|
console.error(`Error creating transient service for token ${String(token)}:`, error)
|
|
return undefined
|
|
}
|
|
}
|
|
|
|
return registration.service as T
|
|
}
|
|
|
|
/**
|
|
* Remove a service from the container
|
|
*/
|
|
remove(token: ServiceToken): boolean {
|
|
return this.services.delete(token)
|
|
}
|
|
|
|
/**
|
|
* Clear all services
|
|
*/
|
|
clear(): void {
|
|
this.services.clear()
|
|
}
|
|
|
|
/**
|
|
* Get all registered service tokens
|
|
*/
|
|
getRegisteredTokens(): ServiceToken[] {
|
|
return Array.from(this.services.keys())
|
|
}
|
|
|
|
/**
|
|
* Check if a service is registered
|
|
*/
|
|
has(token: ServiceToken): boolean {
|
|
return this.services.has(token)
|
|
}
|
|
|
|
/**
|
|
* Get service registration info
|
|
*/
|
|
getServiceInfo(token: ServiceToken): { scope: string; hasInstance: boolean } | undefined {
|
|
const registration = this.services.get(token)
|
|
if (!registration) {
|
|
return undefined
|
|
}
|
|
|
|
return {
|
|
scope: registration.scope,
|
|
hasInstance: registration.instance !== undefined
|
|
}
|
|
}
|
|
}
|
|
|
|
// Global DI container instance
|
|
export const container = new DIContainerImpl()
|
|
|
|
// Service token constants
|
|
export const SERVICE_TOKENS = {
|
|
// Core services
|
|
EVENT_BUS: Symbol('eventBus'),
|
|
ROUTER: Symbol('router'),
|
|
|
|
// Nostr services
|
|
RELAY_HUB: Symbol('relayHub'),
|
|
|
|
// Auth services
|
|
AUTH_SERVICE: Symbol('authService'),
|
|
|
|
// Payment services
|
|
PAYMENT_SERVICE: Symbol('paymentService'),
|
|
|
|
// Visibility services
|
|
VISIBILITY_SERVICE: Symbol('visibilityService'),
|
|
|
|
// Storage services
|
|
STORAGE_SERVICE: Symbol('storageService'),
|
|
|
|
// Toast services
|
|
TOAST_SERVICE: Symbol('toastService'),
|
|
|
|
// Market services
|
|
MARKET_STORE: Symbol('marketStore'),
|
|
PAYMENT_MONITOR: Symbol('paymentMonitor'),
|
|
|
|
// Chat services
|
|
CHAT_SERVICE: Symbol('chatService'),
|
|
|
|
// Feed services
|
|
FEED_SERVICE: Symbol('feedService'),
|
|
PROFILE_SERVICE: Symbol('profileService'),
|
|
REACTION_SERVICE: Symbol('reactionService'),
|
|
|
|
// Events services
|
|
EVENTS_SERVICE: Symbol('eventsService'),
|
|
|
|
// Invoice services
|
|
INVOICE_SERVICE: Symbol('invoiceService'),
|
|
|
|
// Nostrmarket services
|
|
NOSTRMARKET_SERVICE: Symbol('nostrmarketService'),
|
|
NOSTRMARKET_API: Symbol('nostrmarketAPI'),
|
|
|
|
// Wallet services
|
|
WALLET_SERVICE: Symbol('walletService'),
|
|
WALLET_WEBSOCKET_SERVICE: Symbol('walletWebSocketService'),
|
|
|
|
// API services
|
|
LNBITS_API: Symbol('lnbitsAPI'),
|
|
} as const
|
|
|
|
// Type-safe injection helpers
|
|
export function injectService<T>(token: ServiceToken): T {
|
|
const service = container.inject<T>(token)
|
|
if (!service) {
|
|
throw new Error(`Service not found for token: ${String(token)}`)
|
|
}
|
|
return service
|
|
}
|
|
|
|
export function tryInjectService<T>(token: ServiceToken): T | undefined {
|
|
return container.inject<T>(token)
|
|
} |