From 2f36296c7f74beabb5c4b5932dd767d06f084632 Mon Sep 17 00:00:00 2001 From: Patrick Mulligan Date: Thu, 1 Jan 2026 18:03:35 +0100 Subject: [PATCH] feat(nostr-feed): Add Reddit/Lemmy-style UI components (Phase 2/3) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement minimal, information-dense submission feed UI inspired by old Reddit and Lemmy designs. New components: - VoteControls.vue: Compact vertical upvote/downvote arrows with score - SubmissionThumbnail.vue: Small square thumbnail with fallback icons - SubmissionRow.vue: Single submission row with title, metadata, actions - SortTabs.vue: Sort tabs (hot, new, top, controversial) with time range - SubmissionList.vue: Main container composing all components UI features: - Dense layout showing many items at once - Hover-reveal secondary actions (share, save, hide, report) - Domain display for link posts - NSFW blur/badge support - Rank numbers (optional) - Time-ago formatting - Score formatting (e.g., 1.2k) 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .../nostr-feed/components/SortTabs.vue | 96 +++++++ .../nostr-feed/components/SubmissionList.vue | 229 ++++++++++++++++ .../nostr-feed/components/SubmissionRow.vue | 247 ++++++++++++++++++ .../components/SubmissionThumbnail.vue | 114 ++++++++ .../nostr-feed/components/VoteControls.vue | 107 ++++++++ src/modules/nostr-feed/index.ts | 15 +- 6 files changed, 806 insertions(+), 2 deletions(-) create mode 100644 src/modules/nostr-feed/components/SortTabs.vue create mode 100644 src/modules/nostr-feed/components/SubmissionList.vue create mode 100644 src/modules/nostr-feed/components/SubmissionRow.vue create mode 100644 src/modules/nostr-feed/components/SubmissionThumbnail.vue create mode 100644 src/modules/nostr-feed/components/VoteControls.vue diff --git a/src/modules/nostr-feed/components/SortTabs.vue b/src/modules/nostr-feed/components/SortTabs.vue new file mode 100644 index 0000000..ff9bb3c --- /dev/null +++ b/src/modules/nostr-feed/components/SortTabs.vue @@ -0,0 +1,96 @@ + + + diff --git a/src/modules/nostr-feed/components/SubmissionList.vue b/src/modules/nostr-feed/components/SubmissionList.vue new file mode 100644 index 0000000..e635ad0 --- /dev/null +++ b/src/modules/nostr-feed/components/SubmissionList.vue @@ -0,0 +1,229 @@ + + + + + diff --git a/src/modules/nostr-feed/components/SubmissionRow.vue b/src/modules/nostr-feed/components/SubmissionRow.vue new file mode 100644 index 0000000..3f21620 --- /dev/null +++ b/src/modules/nostr-feed/components/SubmissionRow.vue @@ -0,0 +1,247 @@ + + + diff --git a/src/modules/nostr-feed/components/SubmissionThumbnail.vue b/src/modules/nostr-feed/components/SubmissionThumbnail.vue new file mode 100644 index 0000000..868e159 --- /dev/null +++ b/src/modules/nostr-feed/components/SubmissionThumbnail.vue @@ -0,0 +1,114 @@ + + + diff --git a/src/modules/nostr-feed/components/VoteControls.vue b/src/modules/nostr-feed/components/VoteControls.vue new file mode 100644 index 0000000..689cc9c --- /dev/null +++ b/src/modules/nostr-feed/components/VoteControls.vue @@ -0,0 +1,107 @@ + + + diff --git a/src/modules/nostr-feed/index.ts b/src/modules/nostr-feed/index.ts index 7e26d7b..e73896e 100644 --- a/src/modules/nostr-feed/index.ts +++ b/src/modules/nostr-feed/index.ts @@ -2,7 +2,12 @@ import type { App } from 'vue' import type { ModulePlugin } from '@/core/types' import { container, SERVICE_TOKENS } from '@/core/di-container' import NostrFeed from './components/NostrFeed.vue' +import SubmissionList from './components/SubmissionList.vue' +import SubmissionRow from './components/SubmissionRow.vue' +import VoteControls from './components/VoteControls.vue' +import SortTabs from './components/SortTabs.vue' import { useFeed } from './composables/useFeed' +import { useSubmissions } from './composables/useSubmissions' import { FeedService } from './services/FeedService' import { ProfileService } from './services/ProfileService' import { ReactionService } from './services/ReactionService' @@ -63,15 +68,21 @@ export const nostrFeedModule: ModulePlugin = { // Register components globally app.component('NostrFeed', NostrFeed) + app.component('SubmissionList', SubmissionList) console.log('nostr-feed module: Installation complete') }, components: { - NostrFeed + NostrFeed, + SubmissionList, + SubmissionRow, + VoteControls, + SortTabs }, composables: { - useFeed + useFeed, + useSubmissions } }