diff --git a/plugin/markdown/markdown.go b/plugin/markdown/markdown.go index 06cc9429e..dbafa5c4f 100644 --- a/plugin/markdown/markdown.go +++ b/plugin/markdown/markdown.go @@ -244,15 +244,20 @@ func (s *service) GenerateSnippet(content []byte, maxLength int) (string, error) lastNodeWasBlock = false - // Only extract plain text nodes - if textNode, ok := n.(*gast.Text); ok { - segment := textNode.Segment + // Extract text from various node types + switch node := n.(type) { + case *gast.Text: + segment := node.Segment buf.Write(segment.Value(content)) - - // Add space if this is a soft line break - if textNode.SoftLineBreak() { + if node.SoftLineBreak() { buf.WriteByte(' ') } + case *gast.AutoLink: + buf.Write(node.URL(content)) + return gast.WalkSkipChildren, nil + case *mast.TagNode: + buf.WriteByte('#') + buf.Write(node.Tag) } // Stop walking if we've exceeded double the max length diff --git a/plugin/markdown/markdown_test.go b/plugin/markdown/markdown_test.go index 3b642b289..56da08b38 100644 --- a/plugin/markdown/markdown_test.go +++ b/plugin/markdown/markdown_test.go @@ -94,6 +94,18 @@ func TestGenerateSnippet(t *testing.T) { maxLength: 100, expected: "Item 1 Item 2 Item 3", }, + { + name: "plain URL autolink", + content: "https://usememos.com", + maxLength: 100, + expected: "https://usememos.com", + }, + { + name: "text with plain URL", + content: "Check out https://usememos.com for more info.", + maxLength: 100, + expected: "Check out https://usememos.com for more info.", + }, } for _, tt := range tests { @@ -103,6 +115,35 @@ func TestGenerateSnippet(t *testing.T) { assert.Equal(t, tt.expected, snippet) }) } + + // Test with tag extension enabled (matches production config). + svcWithTags := NewService(WithTagExtension()) + tagTests := []struct { + name string + content string + maxLength int + expected string + }{ + { + name: "tag only", + content: "#todo", + maxLength: 100, + expected: "#todo", + }, + { + name: "text with tags", + content: "Remember to #review the #code", + maxLength: 100, + expected: "Remember to #review the #code", + }, + } + for _, tt := range tagTests { + t.Run(tt.name, func(t *testing.T) { + snippet, err := svcWithTags.GenerateSnippet([]byte(tt.content), tt.maxLength) + require.NoError(t, err) + assert.Equal(t, tt.expected, snippet) + }) + } } func TestExtractProperties(t *testing.T) { diff --git a/web/src/components/MemoEditor/components/AttachmentList.tsx b/web/src/components/MemoEditor/components/AttachmentList.tsx index a35416d6a..e8cf2c390 100644 --- a/web/src/components/MemoEditor/components/AttachmentList.tsx +++ b/web/src/components/MemoEditor/components/AttachmentList.tsx @@ -141,7 +141,7 @@ const AttachmentList: FC = ({ attachments, localFiles = [],
- Attachments ({items.length}) + Attachments ({items.length})
diff --git a/web/src/components/MemoEditor/components/RelationList.tsx b/web/src/components/MemoEditor/components/RelationList.tsx index 00651f5ed..eef356270 100644 --- a/web/src/components/MemoEditor/components/RelationList.tsx +++ b/web/src/components/MemoEditor/components/RelationList.tsx @@ -78,7 +78,7 @@ const RelationList: FC = ({ relations, onRelationsChange, par
- Relations ({referenceRelations.length}) + Relations ({referenceRelations.length})
diff --git a/web/src/components/MemoView/components/MemoCommentListView.tsx b/web/src/components/MemoView/components/MemoCommentListView.tsx index 16fc13e65..b08c67b2c 100644 --- a/web/src/components/MemoView/components/MemoCommentListView.tsx +++ b/web/src/components/MemoView/components/MemoCommentListView.tsx @@ -3,6 +3,7 @@ import { Link } from "react-router-dom"; import { extractMemoIdFromName } from "@/helpers/resource-names"; import { useMemoComments } from "@/hooks/useMemoQueries"; import { useMemoViewContext, useMemoViewDerived } from "../MemoViewContext"; +import MemoSnippetLink from "./MemoSnippetLink"; const MemoCommentListView: React.FC = () => { const { memo } = useMemoViewContext(); @@ -23,7 +24,7 @@ const MemoCommentListView: React.FC = () => { Comments{commentAmount > 1 ? ` (${commentAmount})` : ""} View all @@ -32,13 +33,13 @@ const MemoCommentListView: React.FC = () => { {displayedComments.map((comment) => { const uid = extractMemoIdFromName(comment.name); return ( - - {comment.content} - + className="bg-muted/40 rounded-md" + /> ); })}
diff --git a/web/src/components/MemoView/components/MemoSnippetLink.tsx b/web/src/components/MemoView/components/MemoSnippetLink.tsx new file mode 100644 index 000000000..c094c56df --- /dev/null +++ b/web/src/components/MemoView/components/MemoSnippetLink.tsx @@ -0,0 +1,34 @@ +import { Link } from "react-router-dom"; +import { extractMemoIdFromName } from "@/helpers/resource-names"; +import { cn } from "@/lib/utils"; + +interface MemoSnippetLinkProps { + name: string; + snippet: string; + to: string; + state?: object; + className?: string; +} + +const MemoSnippetLink = ({ name, snippet, to, state, className }: MemoSnippetLinkProps) => { + const memoId = extractMemoIdFromName(name); + + return ( + + + {memoId.slice(0, 6)} + + {snippet} + + ); +}; + +export default MemoSnippetLink; diff --git a/web/src/components/MemoView/components/metadata/RelationCard.tsx b/web/src/components/MemoView/components/metadata/RelationCard.tsx index c81df3441..729719166 100644 --- a/web/src/components/MemoView/components/metadata/RelationCard.tsx +++ b/web/src/components/MemoView/components/metadata/RelationCard.tsx @@ -1,7 +1,5 @@ -import { Link } from "react-router-dom"; -import { extractMemoIdFromName } from "@/helpers/resource-names"; -import { cn } from "@/lib/utils"; import type { MemoRelation_Memo } from "@/types/proto/api/v1/memo_service_pb"; +import MemoSnippetLink from "../MemoSnippetLink"; interface RelationCardProps { memo: MemoRelation_Memo; @@ -10,23 +8,8 @@ interface RelationCardProps { } const RelationCard = ({ memo, parentPage, className }: RelationCardProps) => { - const memoId = extractMemoIdFromName(memo.name); - return ( - - - {memoId.slice(0, 6)} - - {memo.snippet} - + ); }; diff --git a/web/src/components/MemoView/components/metadata/SectionHeader.tsx b/web/src/components/MemoView/components/metadata/SectionHeader.tsx index 18be4b796..7ae1de43b 100644 --- a/web/src/components/MemoView/components/metadata/SectionHeader.tsx +++ b/web/src/components/MemoView/components/metadata/SectionHeader.tsx @@ -27,7 +27,7 @@ const SectionHeader = ({ icon: Icon, title, count, tabs }: SectionHeaderProps) = onClick={tab.onClick} className={cn( "text-xs px-0 py-0 transition-colors", - tab.active ? "text-foreground" : "text-muted-foreground hover:text-foreground", + tab.active ? "text-muted-foreground" : "text-muted-foreground/60 hover:text-muted-foreground", )} > {tab.label} ({tab.count}) @@ -37,7 +37,7 @@ const SectionHeader = ({ icon: Icon, title, count, tabs }: SectionHeaderProps) = ))}
) : ( - + {title} ({count}) )}