This repository has no description
1package models
2
3import (
4 "encoding/json"
5 "strings"
6
7 lexutil "github.com/bluesky-social/indigo/lex/util"
8)
9
10// decodeBlob parses a single JSON-encoded LexBlob as submitted by the markdown
11// editor. Returns ok=false for malformed JSON or a blob without a CID.
12func decodeBlob(s string) (*lexutil.LexBlob, bool) {
13 var b lexutil.LexBlob
14 if err := json.Unmarshal([]byte(s), &b); err != nil {
15 return nil, false
16 }
17 if !b.Ref.Defined() {
18 return nil, false
19 }
20 return &b, true
21}
22
23// ParseBlobs decodes the blob refs submitted by the editor, keeping only those
24// still referenced in body. Referencing them on the record pins them against
25// PDS garbage collection; the body filter drops orphans the user removed.
26func ParseBlobs(raw []string, body string) []*lexutil.LexBlob {
27 return MergeBlobs(nil, raw, body)
28}
29
30// MergeBlobs unions already-committed blobs with newly-submitted ones, keeping
31// only CIDs still in body. Used on edit to preserve earlier images.
32func MergeBlobs(existing []*lexutil.LexBlob, raw []string, body string) []*lexutil.LexBlob {
33 seen := make(map[string]struct{})
34 var out []*lexutil.LexBlob
35
36 keep := func(b *lexutil.LexBlob) {
37 if b == nil || !b.Ref.Defined() {
38 return
39 }
40 cid := b.Ref.String()
41 if _, dup := seen[cid]; dup {
42 return
43 }
44 if !strings.Contains(body, cid) {
45 return
46 }
47 seen[cid] = struct{}{}
48 out = append(out, b)
49 }
50
51 for _, b := range existing {
52 keep(b)
53 }
54 for _, s := range raw {
55 if b, ok := decodeBlob(s); ok {
56 keep(b)
57 }
58 }
59
60 return out
61}