Add Rideshare functionality to NostrFeed module
- Introduced a new RideshareComposer component for creating rideshare posts, allowing users to specify ride details such as type, locations, date, time, and contact methods. - Enhanced NostrFeed.vue to display rideshare badges for relevant posts, improving visibility and categorization of rideshare content. - Updated Home.vue to integrate the RideshareComposer, providing users with an option to compose rideshare requests or offers alongside regular notes. These changes enhance the user experience by facilitating rideshare interactions within the NostrFeed module, promoting community engagement.
This commit is contained in:
parent
667a7c2d89
commit
dfd3ddd112
3 changed files with 564 additions and 10 deletions
|
|
@ -36,15 +36,24 @@
|
|||
|
||||
<!-- Main Feed Area - Takes remaining height -->
|
||||
<div class="flex-1 overflow-hidden">
|
||||
<!-- Collapsible Note Composer -->
|
||||
<!-- Collapsible Composer -->
|
||||
<div v-if="showComposer || replyTo" class="border-b bg-background">
|
||||
<div class="px-4 py-3 sm:px-6">
|
||||
<!-- Regular Note Composer -->
|
||||
<NoteComposer
|
||||
v-if="composerType === 'note' || replyTo"
|
||||
:reply-to="replyTo"
|
||||
@note-published="onNotePublished"
|
||||
@clear-reply="onClearReply"
|
||||
@close="onCloseComposer"
|
||||
/>
|
||||
|
||||
<!-- Rideshare Composer -->
|
||||
<RideshareComposer
|
||||
v-else-if="composerType === 'rideshare'"
|
||||
@rideshare-published="onRidesharePublished"
|
||||
@close="onCloseComposer"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -61,15 +70,44 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Floating Action Button for Compose -->
|
||||
<!-- Floating Action Buttons for Compose -->
|
||||
<div v-if="!showComposer && !replyTo" class="fixed bottom-6 right-6 z-50">
|
||||
<Button
|
||||
@click="showComposer = true"
|
||||
size="lg"
|
||||
class="h-14 w-14 rounded-full shadow-lg hover:shadow-xl transition-all bg-primary hover:bg-primary/90 border-2 border-primary-foreground/20 flex items-center justify-center p-0"
|
||||
>
|
||||
<Plus class="h-6 w-6 stroke-[2.5]" />
|
||||
</Button>
|
||||
<!-- Main compose button -->
|
||||
<div class="flex flex-col items-end gap-3">
|
||||
<!-- Secondary buttons (when expanded) -->
|
||||
<div v-if="showComposerOptions" class="flex flex-col gap-2">
|
||||
<Button
|
||||
@click="openComposer('note')"
|
||||
size="lg"
|
||||
variant="secondary"
|
||||
class="h-12 px-4 rounded-full shadow-md hover:shadow-lg transition-all gap-2"
|
||||
>
|
||||
<MessageSquare class="h-4 w-4" />
|
||||
<span class="text-sm">Note</span>
|
||||
</Button>
|
||||
<Button
|
||||
@click="openComposer('rideshare')"
|
||||
size="lg"
|
||||
variant="secondary"
|
||||
class="h-12 px-4 rounded-full shadow-md hover:shadow-lg transition-all gap-2"
|
||||
>
|
||||
<Car class="h-4 w-4" />
|
||||
<span class="text-sm">Rideshare</span>
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<!-- Main FAB -->
|
||||
<Button
|
||||
@click="toggleComposerOptions"
|
||||
size="lg"
|
||||
class="h-14 w-14 rounded-full shadow-lg hover:shadow-xl transition-all bg-primary hover:bg-primary/90 border-2 border-primary-foreground/20 flex items-center justify-center p-0"
|
||||
>
|
||||
<Plus
|
||||
class="h-6 w-6 stroke-[2.5] transition-transform duration-200"
|
||||
:class="{ 'rotate-45': showComposerOptions }"
|
||||
/>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Quick Filters Bar (Mobile) -->
|
||||
|
|
@ -97,10 +135,11 @@
|
|||
// import NotificationPermission from '@/components/notifications/NotificationPermission.vue'
|
||||
import { ref, computed, watch } from 'vue'
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
|
||||
import { Filter, Plus } from 'lucide-vue-next'
|
||||
import { Filter, Plus, MessageSquare, Car } from 'lucide-vue-next'
|
||||
import PWAInstallPrompt from '@/components/pwa/PWAInstallPrompt.vue'
|
||||
import FeedFilters from '@/modules/nostr-feed/components/FeedFilters.vue'
|
||||
import NoteComposer from '@/modules/nostr-feed/components/NoteComposer.vue'
|
||||
import RideshareComposer from '@/modules/nostr-feed/components/RideshareComposer.vue'
|
||||
import NostrFeed from '@/modules/nostr-feed/components/NostrFeed.vue'
|
||||
import { FILTER_PRESETS } from '@/modules/nostr-feed/config/content-filters'
|
||||
import appConfig from '@/app.config'
|
||||
|
|
@ -113,6 +152,8 @@ const adminPubkeys = appConfig.modules['nostr-feed']?.config?.adminPubkeys || []
|
|||
// UI state
|
||||
const showFilters = ref(false)
|
||||
const showComposer = ref(false)
|
||||
const showComposerOptions = ref(false)
|
||||
const composerType = ref<'note' | 'rideshare'>('note')
|
||||
|
||||
// Feed configuration
|
||||
const selectedFilters = ref<ContentFilter[]>(FILTER_PRESETS.all)
|
||||
|
|
@ -191,6 +232,27 @@ const onReplyToNote = (note: ReplyToNote) => {
|
|||
|
||||
const onCloseComposer = () => {
|
||||
showComposer.value = false
|
||||
showComposerOptions.value = false
|
||||
replyTo.value = undefined
|
||||
}
|
||||
|
||||
// New composer methods
|
||||
const toggleComposerOptions = () => {
|
||||
showComposerOptions.value = !showComposerOptions.value
|
||||
}
|
||||
|
||||
const openComposer = (type: 'note' | 'rideshare') => {
|
||||
composerType.value = type
|
||||
showComposer.value = true
|
||||
showComposerOptions.value = false
|
||||
}
|
||||
|
||||
const onRidesharePublished = (noteId: string) => {
|
||||
console.log('Rideshare post published:', noteId)
|
||||
// Refresh the feed to show the new rideshare post
|
||||
feedKey.value++
|
||||
// Hide composer
|
||||
showComposer.value = false
|
||||
showComposerOptions.value = false
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue