(READ ONLY) Margin is an open annotation layer for the internet. Powered by the AT Protocol. margin.at
extension web atproto comments
99
fork

Configure Feed

Select the types of activity you want to include in your feed.

fixes

+45 -26
+1 -1
.env.example
··· 11 11 STATIC_DIR=../web/dist 12 12 13 13 # OAuth private key for signing requests (auto-generated if missing) 14 - OAUTH_KEY_PATH=./oauth_private_key.pem 14 + OAUTH_KEY_PATH=/data/oauth_private_key.pem 15 15 16 16 17 17 # Optional: Override default ATProto network URLs (you probably don't need these)
+24
backend/internal/api/annotations.go
··· 64 64 return 65 65 } 66 66 67 + for i, t := range req.Tags { 68 + req.Tags[i] = strings.ToLower(t) 69 + } 70 + 67 71 urlHash := db.HashURL(req.URL) 68 72 69 73 motivation := "commenting" ··· 329 333 return 330 334 } 331 335 rkey := parts[2] 336 + 337 + for i, t := range req.Tags { 338 + req.Tags[i] = strings.ToLower(t) 339 + } 332 340 333 341 tagsJSON := "" 334 342 if len(req.Tags) > 0 { ··· 692 700 if req.URL == "" || req.Selector == nil { 693 701 http.Error(w, "URL and selector are required", http.StatusBadRequest) 694 702 return 703 + } 704 + 705 + for i, t := range req.Tags { 706 + req.Tags[i] = strings.ToLower(t) 695 707 } 696 708 697 709 urlHash := db.HashURL(req.URL) ··· 806 818 return 807 819 } 808 820 821 + for i, t := range req.Tags { 822 + req.Tags[i] = strings.ToLower(t) 823 + } 824 + 809 825 urlHash := db.HashURL(req.URL) 810 826 record := xrpc.NewBookmarkRecord(req.URL, urlHash, req.Title, req.Description) 811 827 if len(req.Tags) > 0 { ··· 960 976 } 961 977 rkey := parts[2] 962 978 979 + for i, t := range req.Tags { 980 + req.Tags[i] = strings.ToLower(t) 981 + } 982 + 963 983 var result *xrpc.PutRecordOutput 964 984 err = s.refresher.ExecuteWithAutoRefresh(r, session, func(client *xrpc.Client, did string) error { 965 985 existing, getErr := client.GetRecord(r.Context(), did, xrpc.CollectionHighlight, rkey) ··· 1066 1086 rkey := parts[2] 1067 1087 1068 1088 var result *xrpc.PutRecordOutput 1089 + for i, t := range req.Tags { 1090 + req.Tags[i] = strings.ToLower(t) 1091 + } 1092 + 1069 1093 err = s.refresher.ExecuteWithAutoRefresh(r, session, func(client *xrpc.Client, did string) error { 1070 1094 existing, getErr := client.GetRecord(r.Context(), did, xrpc.CollectionBookmark, rkey) 1071 1095 if getErr != nil {
+1 -1
backend/internal/api/handler.go
··· 232 232 func (h *Handler) GetFeed(w http.ResponseWriter, r *http.Request) { 233 233 limit := parseIntParam(r, "limit", 50) 234 234 offset := parseIntParam(r, "offset", 0) 235 - tag := r.URL.Query().Get("tag") 235 + tag := strings.ToLower(r.URL.Query().Get("tag")) 236 236 creator := r.URL.Query().Get("creator") 237 237 feedType := r.URL.Query().Get("type") 238 238
+6 -6
backend/internal/db/queries_annotations.go
··· 217 217 rows, err := db.Query(` 218 218 SELECT uri, author_did, motivation, body_value, body_format, body_uri, target_source, target_hash, target_title, selector_json, tags_json, created_at, indexed_at, cid 219 219 FROM annotations 220 - WHERE tags_json::jsonb ? $1 220 + WHERE EXISTS(SELECT 1 FROM jsonb_array_elements_text(tags_json::jsonb) elem WHERE lower(elem) = $1) 221 221 ORDER BY created_at DESC 222 222 LIMIT $2 OFFSET $3 223 223 `, tag, limit, offset) ··· 233 233 rows, err := db.Query(` 234 234 SELECT uri, author_did, motivation, body_value, body_format, body_uri, target_source, target_hash, target_title, selector_json, tags_json, created_at, indexed_at, cid 235 235 FROM annotations 236 - WHERE tags_json::jsonb ? $1 AND uri NOT LIKE '%network.cosmik%' 236 + WHERE EXISTS(SELECT 1 FROM jsonb_array_elements_text(tags_json::jsonb) elem WHERE lower(elem) = $1) AND uri NOT LIKE '%network.cosmik%' 237 237 ORDER BY created_at DESC 238 238 LIMIT $2 OFFSET $3 239 239 `, tag, limit, offset) ··· 249 249 rows, err := db.Query(` 250 250 SELECT uri, author_did, motivation, body_value, body_format, body_uri, target_source, target_hash, target_title, selector_json, tags_json, created_at, indexed_at, cid 251 251 FROM annotations 252 - WHERE tags_json::jsonb ? $1 AND uri LIKE '%network.cosmik%' 252 + WHERE EXISTS(SELECT 1 FROM jsonb_array_elements_text(tags_json::jsonb) elem WHERE lower(elem) = $1) AND uri LIKE '%network.cosmik%' 253 253 ORDER BY created_at DESC 254 254 LIMIT $2 OFFSET $3 255 255 `, tag, limit, offset) ··· 279 279 rows, err := db.Query(` 280 280 SELECT uri, author_did, motivation, body_value, body_format, body_uri, target_source, target_hash, target_title, selector_json, tags_json, created_at, indexed_at, cid 281 281 FROM annotations 282 - WHERE author_did = $1 AND tags_json::jsonb ? $2 282 + WHERE author_did = $1 AND EXISTS(SELECT 1 FROM jsonb_array_elements_text(tags_json::jsonb) elem WHERE lower(elem) = $2) 283 283 ORDER BY created_at DESC 284 284 LIMIT $3 OFFSET $4 285 285 `, authorDID, tag, limit, offset) ··· 295 295 rows, err := db.Query(` 296 296 SELECT uri, author_did, motivation, body_value, body_format, body_uri, target_source, target_hash, target_title, selector_json, tags_json, created_at, indexed_at, cid 297 297 FROM annotations 298 - WHERE author_did = $1 AND tags_json::jsonb ? $2 AND uri NOT LIKE '%network.cosmik%' 298 + WHERE author_did = $1 AND EXISTS(SELECT 1 FROM jsonb_array_elements_text(tags_json::jsonb) elem WHERE lower(elem) = $2) AND uri NOT LIKE '%network.cosmik%' 299 299 ORDER BY created_at DESC 300 300 LIMIT $3 OFFSET $4 301 301 `, authorDID, tag, limit, offset) ··· 311 311 rows, err := db.Query(` 312 312 SELECT uri, author_did, motivation, body_value, body_format, body_uri, target_source, target_hash, target_title, selector_json, tags_json, created_at, indexed_at, cid 313 313 FROM annotations 314 - WHERE author_did = $1 AND tags_json::jsonb ? $2 AND uri LIKE '%network.cosmik%' 314 + WHERE author_did = $1 AND EXISTS(SELECT 1 FROM jsonb_array_elements_text(tags_json::jsonb) elem WHERE lower(elem) = $2) AND uri LIKE '%network.cosmik%' 315 315 ORDER BY created_at DESC 316 316 LIMIT $3 OFFSET $4 317 317 `, authorDID, tag, limit, offset)
+6 -6
backend/internal/db/queries_bookmarks.go
··· 131 131 rows, err := db.Query(` 132 132 SELECT uri, author_did, source, source_hash, title, description, tags_json, created_at, indexed_at, cid 133 133 FROM bookmarks 134 - WHERE tags_json::jsonb ? $1 134 + WHERE EXISTS(SELECT 1 FROM jsonb_array_elements_text(tags_json::jsonb) elem WHERE lower(elem) = $1) 135 135 ORDER BY created_at DESC 136 136 LIMIT $2 OFFSET $3 137 137 `, tag, limit, offset) ··· 147 147 rows, err := db.Query(` 148 148 SELECT uri, author_did, source, source_hash, title, description, tags_json, created_at, indexed_at, cid 149 149 FROM bookmarks 150 - WHERE tags_json::jsonb ? $1 AND uri NOT LIKE '%network.cosmik%' 150 + WHERE EXISTS(SELECT 1 FROM jsonb_array_elements_text(tags_json::jsonb) elem WHERE lower(elem) = $1) AND uri NOT LIKE '%network.cosmik%' 151 151 ORDER BY created_at DESC 152 152 LIMIT $2 OFFSET $3 153 153 `, tag, limit, offset) ··· 163 163 rows, err := db.Query(` 164 164 SELECT uri, author_did, source, source_hash, title, description, tags_json, created_at, indexed_at, cid 165 165 FROM bookmarks 166 - WHERE tags_json::jsonb ? $1 AND uri LIKE '%network.cosmik%' 166 + WHERE EXISTS(SELECT 1 FROM jsonb_array_elements_text(tags_json::jsonb) elem WHERE lower(elem) = $1) AND uri LIKE '%network.cosmik%' 167 167 ORDER BY created_at DESC 168 168 LIMIT $2 OFFSET $3 169 169 `, tag, limit, offset) ··· 179 179 rows, err := db.Query(` 180 180 SELECT uri, author_did, source, source_hash, title, description, tags_json, created_at, indexed_at, cid 181 181 FROM bookmarks 182 - WHERE author_did = $1 AND tags_json::jsonb ? $2 182 + WHERE author_did = $1 AND EXISTS(SELECT 1 FROM jsonb_array_elements_text(tags_json::jsonb) elem WHERE lower(elem) = $2) 183 183 ORDER BY created_at DESC 184 184 LIMIT $3 OFFSET $4 185 185 `, authorDID, tag, limit, offset) ··· 195 195 rows, err := db.Query(` 196 196 SELECT uri, author_did, source, source_hash, title, description, tags_json, created_at, indexed_at, cid 197 197 FROM bookmarks 198 - WHERE author_did = $1 AND tags_json::jsonb ? $2 AND uri NOT LIKE '%network.cosmik%' 198 + WHERE author_did = $1 AND EXISTS(SELECT 1 FROM jsonb_array_elements_text(tags_json::jsonb) elem WHERE lower(elem) = $2) AND uri NOT LIKE '%network.cosmik%' 199 199 ORDER BY created_at DESC 200 200 LIMIT $3 OFFSET $4 201 201 `, authorDID, tag, limit, offset) ··· 211 211 rows, err := db.Query(` 212 212 SELECT uri, author_did, source, source_hash, title, description, tags_json, created_at, indexed_at, cid 213 213 FROM bookmarks 214 - WHERE author_did = $1 AND tags_json::jsonb ? $2 AND uri LIKE '%network.cosmik%' 214 + WHERE author_did = $1 AND EXISTS(SELECT 1 FROM jsonb_array_elements_text(tags_json::jsonb) elem WHERE lower(elem) = $2) AND uri LIKE '%network.cosmik%' 215 215 ORDER BY created_at DESC 216 216 LIMIT $3 OFFSET $4 217 217 `, authorDID, tag, limit, offset)
+6 -6
backend/internal/db/queries_highlights.go
··· 132 132 rows, err := db.Query(` 133 133 SELECT uri, author_did, target_source, target_hash, target_title, selector_json, color, tags_json, created_at, indexed_at, cid 134 134 FROM highlights 135 - WHERE tags_json::jsonb ? $1 135 + WHERE EXISTS(SELECT 1 FROM jsonb_array_elements_text(tags_json::jsonb) elem WHERE lower(elem) = $1) 136 136 ORDER BY created_at DESC 137 137 LIMIT $2 OFFSET $3 138 138 `, tag, limit, offset) ··· 148 148 rows, err := db.Query(` 149 149 SELECT uri, author_did, target_source, target_hash, target_title, selector_json, color, tags_json, created_at, indexed_at, cid 150 150 FROM highlights 151 - WHERE tags_json::jsonb ? $1 AND uri NOT LIKE '%network.cosmik%' 151 + WHERE EXISTS(SELECT 1 FROM jsonb_array_elements_text(tags_json::jsonb) elem WHERE lower(elem) = $1) AND uri NOT LIKE '%network.cosmik%' 152 152 ORDER BY created_at DESC 153 153 LIMIT $2 OFFSET $3 154 154 `, tag, limit, offset) ··· 164 164 rows, err := db.Query(` 165 165 SELECT uri, author_did, target_source, target_hash, target_title, selector_json, color, tags_json, created_at, indexed_at, cid 166 166 FROM highlights 167 - WHERE tags_json::jsonb ? $1 AND uri LIKE '%network.cosmik%' 167 + WHERE EXISTS(SELECT 1 FROM jsonb_array_elements_text(tags_json::jsonb) elem WHERE lower(elem) = $1) AND uri LIKE '%network.cosmik%' 168 168 ORDER BY created_at DESC 169 169 LIMIT $2 OFFSET $3 170 170 `, tag, limit, offset) ··· 180 180 rows, err := db.Query(` 181 181 SELECT uri, author_did, target_source, target_hash, target_title, selector_json, color, tags_json, created_at, indexed_at, cid 182 182 FROM highlights 183 - WHERE author_did = $1 AND tags_json::jsonb ? $2 183 + WHERE author_did = $1 AND EXISTS(SELECT 1 FROM jsonb_array_elements_text(tags_json::jsonb) elem WHERE lower(elem) = $2) 184 184 ORDER BY created_at DESC 185 185 LIMIT $3 OFFSET $4 186 186 `, authorDID, tag, limit, offset) ··· 196 196 rows, err := db.Query(` 197 197 SELECT uri, author_did, target_source, target_hash, target_title, selector_json, color, tags_json, created_at, indexed_at, cid 198 198 FROM highlights 199 - WHERE author_did = $1 AND tags_json::jsonb ? $2 AND uri NOT LIKE '%network.cosmik%' 199 + WHERE author_did = $1 AND EXISTS(SELECT 1 FROM jsonb_array_elements_text(tags_json::jsonb) elem WHERE lower(elem) = $2) AND uri NOT LIKE '%network.cosmik%' 200 200 ORDER BY created_at DESC 201 201 LIMIT $3 OFFSET $4 202 202 `, authorDID, tag, limit, offset) ··· 212 212 rows, err := db.Query(` 213 213 SELECT uri, author_did, target_source, target_hash, target_title, selector_json, color, tags_json, created_at, indexed_at, cid 214 214 FROM highlights 215 - WHERE author_did = $1 AND tags_json::jsonb ? $2 AND uri LIKE '%network.cosmik%' 215 + WHERE author_did = $1 AND EXISTS(SELECT 1 FROM jsonb_array_elements_text(tags_json::jsonb) elem WHERE lower(elem) = $2) AND uri LIKE '%network.cosmik%' 216 216 ORDER BY created_at DESC 217 217 LIMIT $3 OFFSET $4 218 218 `, authorDID, tag, limit, offset)
+1 -6
web/src/views/core/Feed.tsx
··· 162 162 motivation={activeFilter} 163 163 emptyMessage={emptyMessage} 164 164 layout={layout} 165 - tag={ 166 - activeTab === "atmosphereconf" || 167 - tag?.toLowerCase() === "atmosphereconf" 168 - ? "ATmosphereConf" 169 - : tag 170 - } 165 + tag={activeTab === "atmosphereconf" ? "atmosphereconf" : tag?.toLowerCase()} 171 166 /> 172 167 </div> 173 168 );