blog_markdown_render.go (1799B)
1 package tui 2 3 import ( 4 "strconv" 5 "strings" 6 7 tea "github.com/charmbracelet/bubbletea" 8 ) 9 10 type blogMarkdownRenderedMsg struct { 11 blogID string 12 width int 13 rendered string 14 } 15 16 func (m portfolioModel) cachedBlogMarkdown(blogID string, width int) (string, bool) { 17 byWidth, ok := m.blogMarkdownRender[blogID] 18 if !ok { 19 return "", false 20 } 21 22 rendered, ok := byWidth[width] 23 return rendered, ok 24 } 25 26 func (m *portfolioModel) setCachedBlogMarkdown(blogID string, width int, rendered string) { 27 byWidth := m.blogMarkdownRender[blogID] 28 if byWidth == nil { 29 byWidth = make(map[int]string) 30 m.blogMarkdownRender[blogID] = byWidth 31 } 32 33 byWidth[width] = rendered 34 } 35 36 func blogMarkdownLoadKey(blogID string, width int) string { 37 return blogID + ":" + strconv.Itoa(width) 38 } 39 40 func (m *portfolioModel) maybeRenderSelectedBlogCmd() tea.Cmd { 41 if m.activeTab != tabBlog || len(m.blogs) == 0 { 42 return nil 43 } 44 45 blog := m.blogs[m.blogIndex] 46 markdown := normalizeBlogMarkdown(blog.Markdown, blog.Description) 47 if strings.TrimSpace(markdown) == "" { 48 return nil 49 } 50 51 width := m.blogMarkdownWidth() 52 if _, ok := m.cachedBlogMarkdown(blog.ID, width); ok { 53 return nil 54 } 55 56 loadKey := blogMarkdownLoadKey(blog.ID, width) 57 if m.blogMarkdownLoads[loadKey] { 58 return nil 59 } 60 61 m.blogMarkdownLoads[loadKey] = true 62 return renderBlogMarkdownCmd(blog.ID, markdown, width) 63 } 64 65 func (m *portfolioModel) maybeRenderOpenBlogCmd() tea.Cmd { 66 if !m.blogOpen { 67 return nil 68 } 69 70 return m.maybeRenderSelectedBlogCmd() 71 } 72 73 func renderBlogMarkdownCmd(blogID string, markdown string, width int) tea.Cmd { 74 return func() tea.Msg { 75 rendered := renderMarkdown(markdown, width) 76 if rendered == "" { 77 rendered = markdown 78 } 79 80 return blogMarkdownRenderedMsg{ 81 blogID: blogID, 82 width: width, 83 rendered: rendered, 84 } 85 } 86 }