favorites_view.go RawHistoryFolder
1package systemviews
2
3import (
4 "fmt"
5 "strings"
6
7 "github.com/bnema/dumber/internal/domain/entity"
8)
9
10const defaultTagColor = "#808080"
11
12type favoritesRenderData struct {
13 Favorites []*entity.Favorite
14 Tags []*entity.Tag
15 TagFilter *entity.TagID
16 UntaggedFilter bool
17 Notice string
18 Error string
19}
20
21func favoritesHTML(data favoritesRenderData) string {
22 return mustRenderComponent(FavoritesView(data))
23}
24
25func favoritesDocumentTitle(data favoritesRenderData) string {
26 count := len(data.Favorites)
27 if data.TagFilter != nil || data.UntaggedFilter {
28 if count == 1 {
29 return "Favorites — 1 filtered bookmark"
30 }
31 return fmt.Sprintf("Favorites — %d filtered bookmarks", count)
32 }
33 if count == 1 {
34 return "Favorites — 1 bookmark"
35 }
36 return fmt.Sprintf("Favorites — %d bookmarks", count)
37}
38
39func favoritesSummary(data favoritesRenderData) string {
40 return fmt.Sprintf("%d favorites · %d tags", len(data.Favorites), len(data.Tags))
41}
42
43func tagsSummary(data favoritesRenderData) string {
44 return fmt.Sprintf("%d tags", len(data.Tags))
45}
46
47func favoriteFilterClass(active bool) string {
48 classes := "sv-button sv-button-secondary"
49 if active {
50 classes += " sv-button-active"
51 }
52 return classes
53}
54
55func favoriteUntaggedFilterActive(data favoritesRenderData) bool {
56 return data.UntaggedFilter
57}
58
59func favoriteAllFilterActive(data favoritesRenderData) bool {
60 return data.TagFilter == nil && !data.UntaggedFilter
61}
62
63func favoriteTagFilterActive(data favoritesRenderData, tagID entity.TagID) bool {
64 return data.TagFilter != nil && *data.TagFilter == tagID
65}
66
67func favoriteItemLabel(favorite *entity.Favorite) string {
68 if favorite == nil {
69 return ""
70 }
71 label := strings.TrimSpace(favorite.Title)
72 if label == "" {
73 label = favorite.URL
74 }
75 return label
76}
77
78func favoriteMetaText(favorite *entity.Favorite) string {
79 if favorite == nil || favorite.ShortcutKey == nil {
80 return ""
81 }
82 return fmt.Sprintf("Shortcut %d", *favorite.ShortcutKey)
83}
84
85func favoriteTagButtonAction(favorite *entity.Favorite, tag *entity.Tag) string {
86 if favorite != nil && tag != nil && favorite.HasTag(tag.ID) {
87 return tagActionRemove
88 }
89 return tagActionAssign
90}
91
92func favoriteTagButtonLabel(favorite *entity.Favorite, tag *entity.Tag) string {
93 if tag == nil {
94 return ""
95 }
96 if favorite != nil && favorite.HasTag(tag.ID) {
97 return "✓ " + tag.Name
98 }
99 return "+ " + tag.Name
100}
101
102func favoriteTagButtonClass(favorite *entity.Favorite, tag *entity.Tag) string {
103 classes := "sv-button sv-button-secondary sv-tag-button"
104 if favorite != nil && tag != nil && favorite.HasTag(tag.ID) {
105 classes += " sv-button-active sv-tag-button-active"
106 }
107 return classes
108}
109
110func safeTagColor(raw string) string {
111 value := strings.TrimSpace(raw)
112 if len(value) != 4 && len(value) != 7 {
113 return defaultTagColor
114 }
115 if value[0] != '#' {
116 return defaultTagColor
117 }
118 for _, ch := range value[1:] {
119 if (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F') {
120 continue
121 }
122 return defaultTagColor
123 }
124 return value
125}
126
127func shortcutSelected(selected *int, value int) bool {
128 return selected != nil && *selected == value
129}
130
131func filterFavorites(favorites []*entity.Favorite, tagID *entity.TagID, untagged bool) []*entity.Favorite {
132 if tagID == nil && !untagged {
133 return favorites
134 }
135 out := make([]*entity.Favorite, 0, len(favorites))
136 for _, favorite := range favorites {
137 if favorite == nil {
138 continue
139 }
140 if untagged {
141 if len(favorite.Tags) != 0 {
142 continue
143 }
144 } else if tagID != nil && !favorite.HasTag(*tagID) {
145 continue
146 }
147 out = append(out, favorite)
148 }
149 return out
150}