diff --git a/src/components/NoteMoreMenu.tsx b/src/components/NoteMoreMenu.tsx
index 030c7b8b..3c0a557a 100644
--- a/src/components/NoteMoreMenu.tsx
+++ b/src/components/NoteMoreMenu.tsx
@@ -14,6 +14,7 @@ import {
Trash2,
StickyNote,
ListPlus,
+ PanelLeft,
Copy,
Check,
} from 'lucide-react';
@@ -48,6 +49,7 @@ import { useCurrentUser } from '@/hooks/useCurrentUser';
import { useAuthor } from '@/hooks/useAuthor';
import { useMuteList } from '@/hooks/useMuteList';
import { useDeleteEvent } from '@/hooks/useDeleteEvent';
+import { useFeedSettings } from '@/hooks/useFeedSettings';
import { genUserName } from '@/lib/genUserName';
import { timeAgo } from '@/lib/timeAgo';
import { toast } from '@/hooks/useToast';
@@ -241,9 +243,12 @@ function NoteMoreMenuContent({ event, open, onOpenChange, onReport, onMention, o
const { addMute, removeMute, isMuted } = useMuteList();
const userMuted = isMuted('pubkey', event.pubkey);
const { mutate: deleteEvent, isPending: isDeleting } = useDeleteEvent();
+ const { addToSidebar, removeFromSidebar, orderedItems } = useFeedSettings();
const [deleteConfirmOpen, setDeleteConfirmOpen] = useState(false);
const nip19Id = encodeEventNip19(event);
+ const nostrUri = `nostr:${nip19Id}`;
+ const isInSidebar = orderedItems.includes(nostrUri);
const close = () => onOpenChange(false);
@@ -264,6 +269,17 @@ function NoteMoreMenuContent({ event, open, onOpenChange, onReport, onMention, o
close();
};
+ const handleToggleSidebar = () => {
+ if (isInSidebar) {
+ removeFromSidebar(nostrUri);
+ toast({ title: 'Removed from sidebar' });
+ } else {
+ addToSidebar(nostrUri);
+ toast({ title: 'Added to sidebar' });
+ }
+ close();
+ };
+
const handleTogglePin = () => {
togglePin.mutate(event.id, {
onSuccess: () => {
@@ -383,6 +399,11 @@ function NoteMoreMenuContent({ event, open, onOpenChange, onReport, onMention, o
onClick={() => { onAddToList(); }}
/>
)}
+ : }
+ label={isInSidebar ? 'Remove from sidebar' : 'Add to sidebar'}
+ onClick={handleToggleSidebar}
+ />
diff --git a/src/pages/ExternalContentPage.tsx b/src/pages/ExternalContentPage.tsx
index 7375379e..da3b835b 100644
--- a/src/pages/ExternalContentPage.tsx
+++ b/src/pages/ExternalContentPage.tsx
@@ -1,6 +1,6 @@
import { useCallback, useMemo, useRef, useState } from 'react';
import { useSeoMeta } from '@unhead/react';
-import { ArrowLeft, Globe, Heart, MessageSquare, Repeat2, Star, AlertTriangle } from 'lucide-react';
+import { ArrowLeft, Globe, Heart, MessageSquare, MoreHorizontal, Repeat2, Star, AlertTriangle, PanelLeft, Trash2 } from 'lucide-react';
import { Link, useLocation, useParams } from 'react-router-dom';
import { Skeleton } from '@/components/ui/skeleton';
import { Badge } from '@/components/ui/badge';
@@ -9,6 +9,9 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { Avatar, AvatarImage, AvatarFallback } from '@/components/ui/avatar';
import { getAvatarShape } from '@/lib/avatarShape';
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
+import {
+ DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger,
+} from '@/components/ui/dropdown-menu';
import { ThreadedReplyList } from '@/components/ThreadedReplyList';
import { ComposeBox } from '@/components/ComposeBox';
import { ReplyComposeModal } from '@/components/ReplyComposeModal';
@@ -36,6 +39,7 @@ import { useLinkPreview } from '@/hooks/useLinkPreview';
import { useLayoutOptions } from '@/contexts/LayoutContext';
import { useCurrentUser } from '@/hooks/useCurrentUser';
import { useNostrPublish } from '@/hooks/useNostrPublish';
+import { useFeedSettings } from '@/hooks/useFeedSettings';
import { useQueryClient } from '@tanstack/react-query';
import { useToast } from '@/hooks/useToast';
import { getDisplayName } from '@/lib/getDisplayName';
@@ -73,6 +77,19 @@ function ExternalActionBar({ content }: { content: ExternalContent }) {
const queryClient = useQueryClient();
const { toast } = useToast();
const identifier = content.value;
+ const { addToSidebar, removeFromSidebar, orderedItems } = useFeedSettings();
+
+ const isInSidebar = orderedItems.includes(identifier);
+
+ const handleAddToSidebar = useCallback(() => {
+ addToSidebar(identifier);
+ toast({ title: 'Added to sidebar' });
+ }, [identifier, addToSidebar, toast]);
+
+ const handleRemoveFromSidebar = useCallback(() => {
+ removeFromSidebar(identifier);
+ toast({ title: 'Removed from sidebar' });
+ }, [identifier, removeFromSidebar, toast]);
const userReactionData = useExternalUserReaction(content);
const reactionCount = useExternalReactionCount(content);
@@ -224,6 +241,34 @@ function ExternalActionBar({ content }: { content: ExternalContent }) {
)}
+ {/* Spacer pushes the 3-dots menu to the right */}
+
+
+ {/* 3-dots menu with sidebar action */}
+
+
+
+
+
+ {isInSidebar ? (
+
+
+ Remove from sidebar
+
+ ) : (
+
+
+ Add to sidebar
+
+ )}
+
+
+
{shareOpen && (