chore: fixed content encoded
56a2fbd4
2 file(s) · +36 −3
| 146 | 146 | : post.link?.[0] || post.id |
|
| 147 | 147 | : post.link || post.id, |
|
| 148 | 148 | feedId: result.value.id, |
|
| 149 | - | content: post.content || "", |
|
| 149 | + | content: |
|
| 150 | + | post["content:encoded"] || post.content || "Please open on the web", |
|
| 150 | 151 | }); |
|
| 151 | 152 | } |
|
| 152 | 153 | setUrlInput(""); |
|
| 250 | 251 | </Dialog> |
|
| 251 | 252 | ||
| 252 | 253 | {/* Posts List Panel - Separate from main sidebar */} |
|
| 253 | - | <div className="bg-sidebar text-sidebar-foreground hidden md:flex h-full w-[320px] flex-col border-r"> |
|
| 254 | + | <div className="bg-sidebar text-sidebar-foreground hidden md:flex overflow-y-scroll h-screen w-[320px] flex-col border-r"> |
|
| 254 | 255 | <div className="gap-2 border-b p-3 flex flex-col"> |
|
| 255 | 256 | <div className="flex w-full items-center justify-between"> |
|
| 256 | 257 | <div className="text-foreground text-sm font-semibold truncate"> |
|
| 45 | 45 | ? allPosts.find((p) => p.id === selectedPostId) |
|
| 46 | 46 | : null; |
|
| 47 | 47 | ||
| 48 | + | // Get base URL from the post link to fix relative image paths |
|
| 49 | + | const getBaseUrl = React.useCallback((link: string | null) => { |
|
| 50 | + | if (!link) return ""; |
|
| 51 | + | try { |
|
| 52 | + | const url = new URL(link); |
|
| 53 | + | return `${url.protocol}//${url.host}`; |
|
| 54 | + | } catch (e) { |
|
| 55 | + | return ""; |
|
| 56 | + | } |
|
| 57 | + | }, []); |
|
| 58 | + | ||
| 59 | + | // Custom components for ReactMarkdown to fix image URLs |
|
| 60 | + | const markdownComponents = React.useMemo( |
|
| 61 | + | () => ({ |
|
| 62 | + | img: ({ node, src, alt, ...props }: any) => { |
|
| 63 | + | let fixedSrc = src; |
|
| 64 | + | ||
| 65 | + | // If src starts with / and we have a base URL from the post link |
|
| 66 | + | if (src?.startsWith("/") && selectedPost?.link) { |
|
| 67 | + | const baseUrl = getBaseUrl(selectedPost.link); |
|
| 68 | + | if (baseUrl) { |
|
| 69 | + | fixedSrc = `${baseUrl}${src}`; |
|
| 70 | + | } |
|
| 71 | + | } |
|
| 72 | + | ||
| 73 | + | return <img src={fixedSrc} alt={alt} {...props} />; |
|
| 74 | + | }, |
|
| 75 | + | }), |
|
| 76 | + | [selectedPost?.link, getBaseUrl], |
|
| 77 | + | ); |
|
| 78 | + | ||
| 48 | 79 | return ( |
|
| 49 | 80 | <main className="min-h-screen w-full"> |
|
| 50 | 81 | <SidebarProvider |
|
| 92 | 123 | </BreadcrumbList> |
|
| 93 | 124 | </Breadcrumb> |
|
| 94 | 125 | </header> |
|
| 95 | - | <div className="flex flex-1 flex-col gap-4 p-4 overflow-y-auto"> |
|
| 126 | + | <div className="h-full flex flex-1 flex-col gap-4 p-4 pb-12 overflow-y-auto"> |
|
| 96 | 127 | {selectedPost ? ( |
|
| 97 | 128 | <div className="flex flex-col gap-6 max-w-4xl mx-auto w-full pb-8"> |
|
| 98 | 129 | <div className="flex flex-col gap-3"> |
|
| 124 | 155 | <ReactMarkdown |
|
| 125 | 156 | remarkPlugins={[remarkGfm]} |
|
| 126 | 157 | rehypePlugins={[rehypeRaw, rehypeSanitize]} |
|
| 158 | + | components={markdownComponents} |
|
| 127 | 159 | > |
|
| 128 | 160 | {selectedPost.content} |
|
| 129 | 161 | </ReactMarkdown> |
|