Adds scheduled events to the feed
Implements NIP-52 scheduled events, allowing users to view and interact with calendar events. A new `ScheduledEventService` is introduced to manage fetching, storing, and completing scheduled events. A new `ScheduledEventCard` component is introduced for displaying the scheduled events.
This commit is contained in:
parent
b6d8a78cd8
commit
9b05bcc238
8 changed files with 716 additions and 1 deletions
|
|
@ -13,9 +13,12 @@ import { Megaphone, RefreshCw, AlertCircle } from 'lucide-vue-next'
|
|||
import { useFeed } from '../composables/useFeed'
|
||||
import { useProfiles } from '../composables/useProfiles'
|
||||
import { useReactions } from '../composables/useReactions'
|
||||
import { useScheduledEvents } from '../composables/useScheduledEvents'
|
||||
import ThreadedPost from './ThreadedPost.vue'
|
||||
import ScheduledEventCard from './ScheduledEventCard.vue'
|
||||
import appConfig from '@/app.config'
|
||||
import type { ContentFilter, FeedPost } from '../services/FeedService'
|
||||
import type { ScheduledEvent } from '../services/ScheduledEventService'
|
||||
import { injectService, SERVICE_TOKENS } from '@/core/di-container'
|
||||
import type { AuthService } from '@/modules/base/auth/auth-service'
|
||||
import type { RelayHub } from '@/modules/base/nostr/relay-hub'
|
||||
|
|
@ -95,6 +98,12 @@ const { getDisplayName, fetchProfiles } = useProfiles()
|
|||
// Use reactions service for likes/hearts
|
||||
const { getEventReactions, subscribeToReactions, toggleLike } = useReactions()
|
||||
|
||||
// Use scheduled events service
|
||||
const { getTodaysEvents, getCompletion, toggleComplete } = useScheduledEvents()
|
||||
|
||||
// Get today's scheduled events (reactive)
|
||||
const todaysScheduledEvents = computed(() => getTodaysEvents())
|
||||
|
||||
// Watch for new posts and fetch their profiles and reactions
|
||||
watch(notes, async (newNotes) => {
|
||||
if (newNotes.length > 0) {
|
||||
|
|
@ -158,6 +167,15 @@ async function onToggleLike(note: FeedPost) {
|
|||
}
|
||||
}
|
||||
|
||||
// Handle scheduled event completion toggle
|
||||
async function onToggleComplete(event: ScheduledEvent) {
|
||||
try {
|
||||
await toggleComplete(event)
|
||||
} catch (error) {
|
||||
console.error('Failed to toggle event completion:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// Handle collapse toggle with cascading behavior
|
||||
function onToggleCollapse(postId: string) {
|
||||
const newCollapsed = new Set(collapsedPosts.value)
|
||||
|
|
@ -369,7 +387,29 @@ function cancelDelete() {
|
|||
|
||||
<!-- Posts List - Natural flow without internal scrolling -->
|
||||
<div v-else>
|
||||
<div class="md:space-y-4 md:py-4">
|
||||
<!-- Today's Scheduled Events Section -->
|
||||
<div v-if="todaysScheduledEvents.length > 0" class="mb-6 md:mb-8">
|
||||
<h3 class="text-sm font-semibold text-muted-foreground uppercase tracking-wide px-4 md:px-0 mb-3">
|
||||
📅 Today's Events
|
||||
</h3>
|
||||
<div class="md:space-y-3">
|
||||
<ScheduledEventCard
|
||||
v-for="event in todaysScheduledEvents"
|
||||
:key="`${event.pubkey}:${event.dTag}`"
|
||||
:event="event"
|
||||
:completion="getCompletion(`31922:${event.pubkey}:${event.dTag}`)"
|
||||
:get-display-name="getDisplayName"
|
||||
:admin-pubkeys="adminPubkeys"
|
||||
@toggle-complete="onToggleComplete"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Posts Section -->
|
||||
<div v-if="threadedPosts.length > 0" class="md:space-y-4 md:py-4">
|
||||
<h3 v-if="todaysScheduledEvents.length > 0" class="text-sm font-semibold text-muted-foreground uppercase tracking-wide px-4 md:px-0 mb-3 mt-6">
|
||||
💬 Posts
|
||||
</h3>
|
||||
<ThreadedPost
|
||||
v-for="post in threadedPosts"
|
||||
:key="post.id"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue