tangled
alpha
login
or
join now
moth11.net
/
ttyxcvr
0
fork
atom
xcvr tui
0
fork
atom
overview
issues
pulls
pipelines
beepin and borpin
moth11.net
5 months ago
7254ae5a
fa5d4d10
+2272
-43
7 changed files
expand all
collapse all
unified
split
README.md
diff.go
go.mod
go.sum
lex
lexicons_cbor.go
types.go
main.go
+4
README.md
···
1
1
+
# tty!xcvr
2
2
+
3
3
+
talk to you! transceiver is everyone's favorite ATP application, brought to
4
4
+
the teletypewriter!
+233
diff.go
···
1
1
+
package main
2
2
+
3
3
+
import ()
4
4
+
5
5
+
type EditType = int
6
6
+
7
7
+
const (
8
8
+
EditAdd EditType = iota
9
9
+
EditKeep
10
10
+
EditDel
11
11
+
EditNil
12
12
+
)
13
13
+
14
14
+
type Edit struct {
15
15
+
EditType EditType
16
16
+
Utf16Text []uint16
17
17
+
}
18
18
+
19
19
+
type Editstring struct {
20
20
+
EditType EditType
21
21
+
Text string
22
22
+
}
23
23
+
24
24
+
type EditSegment struct {
25
25
+
weight int
26
26
+
aidx int
27
27
+
bidx int
28
28
+
parent *EditSegment
29
29
+
}
30
30
+
31
31
+
type coordinate struct {
32
32
+
a int
33
33
+
b int
34
34
+
}
35
35
+
36
36
+
type SegmentHeap struct {
37
37
+
segments []*EditSegment
38
38
+
searched map[coordinate]bool
39
39
+
}
40
40
+
41
41
+
func NewSegmentHeap() SegmentHeap {
42
42
+
segments := make([]*EditSegment, 0, 10)
43
43
+
searched := make(map[coordinate]bool)
44
44
+
return SegmentHeap{segments, searched}
45
45
+
}
46
46
+
47
47
+
func (h *SegmentHeap) Add(seg *EditSegment) {
48
48
+
searched := h.searched[coordinate{seg.aidx, seg.bidx}]
49
49
+
if searched {
50
50
+
return
51
51
+
}
52
52
+
h.segments = append(h.segments, seg)
53
53
+
h.searched[coordinate{seg.aidx, seg.bidx}] = true
54
54
+
h.siftUp(len(h.segments) - 1)
55
55
+
}
56
56
+
57
57
+
func (h *SegmentHeap) PopFront() *EditSegment {
58
58
+
if len(h.segments) == 0 {
59
59
+
return nil
60
60
+
}
61
61
+
front := h.segments[0]
62
62
+
if len(h.segments) == 1 {
63
63
+
h.segments = nil
64
64
+
return front
65
65
+
}
66
66
+
h.segments[0] = h.segments[len(h.segments)-1]
67
67
+
h.segments = h.segments[:len(h.segments)-1]
68
68
+
h.siftDown(0)
69
69
+
return front
70
70
+
}
71
71
+
72
72
+
func (h *SegmentHeap) siftUp(idx int) {
73
73
+
if idx == 0 {
74
74
+
return
75
75
+
}
76
76
+
loweridx := idx
77
77
+
upperidx := (idx - 1) / 2
78
78
+
lower := h.segments[loweridx]
79
79
+
upper := h.segments[upperidx]
80
80
+
if lower.lighter(upper) {
81
81
+
h.segments[upperidx] = lower
82
82
+
h.segments[loweridx] = upper
83
83
+
h.siftUp(upperidx)
84
84
+
}
85
85
+
}
86
86
+
87
87
+
func (h *SegmentHeap) siftDown(idx int) {
88
88
+
upperidx := idx
89
89
+
var swap *EditSegment
90
90
+
loweridx := idx*2 + 1
91
91
+
lower2idx := idx*2 + 2
92
92
+
if loweridx < len(h.segments) && h.segments[loweridx].lighter(h.segments[upperidx]) {
93
93
+
swap = h.segments[upperidx]
94
94
+
h.segments[upperidx] = h.segments[loweridx]
95
95
+
h.segments[loweridx] = swap
96
96
+
h.siftDown(loweridx)
97
97
+
return
98
98
+
}
99
99
+
if lower2idx < len(h.segments) && h.segments[lower2idx].lighter(h.segments[upperidx]) {
100
100
+
swap = h.segments[upperidx]
101
101
+
h.segments[upperidx] = h.segments[lower2idx]
102
102
+
h.segments[lower2idx] = swap
103
103
+
h.siftDown(lower2idx)
104
104
+
return
105
105
+
}
106
106
+
107
107
+
}
108
108
+
109
109
+
func (seg *EditSegment) lighter(A *EditSegment) bool {
110
110
+
if seg.weight < A.weight {
111
111
+
return true
112
112
+
} else if seg.weight > A.weight {
113
113
+
return false
114
114
+
} else {
115
115
+
return seg.aidx+seg.bidx > A.aidx+A.bidx
116
116
+
}
117
117
+
}
118
118
+
119
119
+
// Diff calculates the diff between wordA and wordB as a miniaml slice of
120
120
+
// edits that you have to make to wordA so that you end up with wordB
121
121
+
func Diff(wordA []uint16, wordB []uint16) []Edit {
122
122
+
heap := NewSegmentHeap()
123
123
+
head := EditSegment{0, 0, 0, nil}
124
124
+
heap.Add(&head)
125
125
+
segment := heap.PopFront()
126
126
+
for !(segment.aidx == len(wordA) && segment.bidx == len(wordB)) {
127
127
+
if segment.aidx != len(wordA) &&
128
128
+
segment.bidx != len(wordB) &&
129
129
+
wordA[segment.aidx] == wordB[segment.bidx] {
130
130
+
newSegment := EditSegment{segment.weight, segment.aidx + 1, segment.bidx + 1, segment}
131
131
+
heap.Add(&newSegment)
132
132
+
}
133
133
+
if segment.aidx != len(wordA) {
134
134
+
newSegment := EditSegment{segment.weight + 1, segment.aidx + 1, segment.bidx, segment}
135
135
+
heap.Add(&newSegment)
136
136
+
}
137
137
+
if segment.bidx != len(wordB) {
138
138
+
newSegment := EditSegment{segment.weight + 1, segment.aidx, segment.bidx + 1, segment}
139
139
+
heap.Add(&newSegment)
140
140
+
}
141
141
+
segment = heap.PopFront()
142
142
+
}
143
143
+
prevSegment := segment.parent
144
144
+
edits := make([]Edit, 0)
145
145
+
currentEdit := Edit{EditNil, nil}
146
146
+
for prevSegment != nil {
147
147
+
diffA := prevSegment.aidx != segment.aidx
148
148
+
diffB := prevSegment.bidx != segment.bidx
149
149
+
var et EditType
150
150
+
var char uint16
151
151
+
if diffA && diffB {
152
152
+
et = EditKeep
153
153
+
char = wordA[prevSegment.aidx]
154
154
+
} else if diffA {
155
155
+
et = EditDel
156
156
+
char = wordA[prevSegment.aidx]
157
157
+
} else if diffB {
158
158
+
et = EditAdd
159
159
+
char = wordB[prevSegment.bidx]
160
160
+
} else {
161
161
+
et = EditNil
162
162
+
}
163
163
+
if currentEdit.EditType != et {
164
164
+
if currentEdit.EditType != EditNil {
165
165
+
edits = append([]Edit{currentEdit}, edits...)
166
166
+
}
167
167
+
currentEdit = Edit{et, []uint16{char}}
168
168
+
} else {
169
169
+
currentEdit.Utf16Text = append([]uint16{char}, currentEdit.Utf16Text...)
170
170
+
}
171
171
+
segment = prevSegment
172
172
+
prevSegment = segment.parent
173
173
+
}
174
174
+
edits = append([]Edit{currentEdit}, edits...)
175
175
+
return edits
176
176
+
}
177
177
+
178
178
+
func Diffs(wordA string, wordB string) []Editstring {
179
179
+
heap := NewSegmentHeap()
180
180
+
head := EditSegment{0, 0, 0, nil}
181
181
+
heap.Add(&head)
182
182
+
segment := heap.PopFront()
183
183
+
for !(segment.aidx == len(wordA) && segment.bidx == len(wordB)) {
184
184
+
if segment.aidx != len(wordA) &&
185
185
+
segment.bidx != len(wordB) &&
186
186
+
wordA[segment.aidx] == wordB[segment.bidx] {
187
187
+
newSegment := EditSegment{segment.weight, segment.aidx + 1, segment.bidx + 1, segment}
188
188
+
heap.Add(&newSegment)
189
189
+
}
190
190
+
if segment.aidx != len(wordA) {
191
191
+
newSegment := EditSegment{segment.weight + 1, segment.aidx + 1, segment.bidx, segment}
192
192
+
heap.Add(&newSegment)
193
193
+
}
194
194
+
if segment.bidx != len(wordB) {
195
195
+
newSegment := EditSegment{segment.weight + 1, segment.aidx, segment.bidx + 1, segment}
196
196
+
heap.Add(&newSegment)
197
197
+
}
198
198
+
segment = heap.PopFront()
199
199
+
}
200
200
+
prevSegment := segment.parent
201
201
+
edits := make([]Editstring, 0)
202
202
+
currentEdit := Editstring{EditNil, ""}
203
203
+
for prevSegment != nil {
204
204
+
diffA := prevSegment.aidx != segment.aidx
205
205
+
diffB := prevSegment.bidx != segment.bidx
206
206
+
var et EditType
207
207
+
var char string
208
208
+
if diffA && diffB {
209
209
+
et = EditKeep
210
210
+
char = string(wordA[prevSegment.aidx])
211
211
+
} else if diffA {
212
212
+
et = EditDel
213
213
+
char = string(wordA[prevSegment.aidx])
214
214
+
} else if diffB {
215
215
+
et = EditAdd
216
216
+
char = string(wordB[prevSegment.bidx])
217
217
+
} else {
218
218
+
et = EditNil
219
219
+
}
220
220
+
if currentEdit.EditType != et {
221
221
+
if currentEdit.EditType != EditNil {
222
222
+
edits = append([]Editstring{currentEdit}, edits...)
223
223
+
}
224
224
+
currentEdit = Editstring{et, char}
225
225
+
} else {
226
226
+
currentEdit.Text = char + currentEdit.Text
227
227
+
}
228
228
+
segment = prevSegment
229
229
+
prevSegment = segment.parent
230
230
+
}
231
231
+
edits = append([]Editstring{currentEdit}, edits...)
232
232
+
return edits
233
233
+
}
+32
-5
go.mod
···
3
3
go 1.24.2
4
4
5
5
require (
6
6
+
github.com/bluesky-social/indigo v0.0.0-20250925152209-0f22fe8b39a8
6
7
github.com/charmbracelet/bubbles v0.21.0
7
8
github.com/charmbracelet/bubbletea v1.3.10
9
9
+
github.com/charmbracelet/lipgloss v1.1.0
10
10
+
github.com/gorilla/websocket v1.5.3
11
11
+
github.com/ipfs/go-cid v0.4.1
12
12
+
github.com/rachel-mp4/lrcproto v0.0.0-20250905154858-2ddb78e31d0c
13
13
+
github.com/whyrusleeping/cbor-gen v0.2.1-0.20241030202151-b7a6831be65e
14
14
+
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028
15
15
+
google.golang.org/protobuf v1.36.6
8
16
)
9
17
10
18
require (
11
19
github.com/atotto/clipboard v0.1.4 // indirect
12
20
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
21
21
+
github.com/beorn7/perks v1.0.1 // indirect
22
22
+
github.com/carlmjohnson/versioninfo v0.22.5 // indirect
23
23
+
github.com/cespare/xxhash/v2 v2.2.0 // indirect
13
24
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect
14
14
-
github.com/charmbracelet/lipgloss v1.1.0 // indirect
15
25
github.com/charmbracelet/x/ansi v0.10.1 // indirect
16
26
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect
17
27
github.com/charmbracelet/x/term v0.2.1 // indirect
18
28
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
19
19
-
github.com/gorilla/websocket v1.5.3 // indirect
29
29
+
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
30
30
+
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
20
31
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
21
32
github.com/mattn/go-isatty v0.0.20 // indirect
22
33
github.com/mattn/go-localereader v0.0.1 // indirect
23
34
github.com/mattn/go-runewidth v0.0.16 // indirect
35
35
+
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
36
36
+
github.com/minio/sha256-simd v1.0.1 // indirect
37
37
+
github.com/mr-tron/base58 v1.2.0 // indirect
24
38
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
25
39
github.com/muesli/cancelreader v0.2.2 // indirect
26
40
github.com/muesli/termenv v0.16.0 // indirect
27
27
-
github.com/rachel-mp4/lrcproto v0.0.0-20250905154858-2ddb78e31d0c // indirect
41
41
+
github.com/multiformats/go-base32 v0.1.0 // indirect
42
42
+
github.com/multiformats/go-base36 v0.2.0 // indirect
43
43
+
github.com/multiformats/go-multibase v0.2.0 // indirect
44
44
+
github.com/multiformats/go-multihash v0.2.3 // indirect
45
45
+
github.com/multiformats/go-varint v0.0.7 // indirect
46
46
+
github.com/prometheus/client_golang v1.17.0 // indirect
47
47
+
github.com/prometheus/client_model v0.5.0 // indirect
48
48
+
github.com/prometheus/common v0.45.0 // indirect
49
49
+
github.com/prometheus/procfs v0.12.0 // indirect
28
50
github.com/rivo/uniseg v0.4.7 // indirect
29
51
github.com/sahilm/fuzzy v0.1.1 // indirect
52
52
+
github.com/spaolacci/murmur3 v1.1.0 // indirect
30
53
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
54
54
+
gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b // indirect
55
55
+
gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02 // indirect
56
56
+
golang.org/x/crypto v0.21.0 // indirect
31
57
golang.org/x/sys v0.36.0 // indirect
32
32
-
golang.org/x/text v0.3.8 // indirect
33
33
-
google.golang.org/protobuf v1.36.6 // indirect
58
58
+
golang.org/x/text v0.14.0 // indirect
59
59
+
golang.org/x/time v0.3.0 // indirect
60
60
+
lukechampine.com/blake3 v1.2.1 // indirect
34
61
)
+127
-4
go.sum
···
4
4
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
5
5
github.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWpi6yML8=
6
6
github.com/aymanbagabas/go-udiff v0.2.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA=
7
7
+
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
8
8
+
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
9
9
+
github.com/bluesky-social/indigo v0.0.0-20250925152209-0f22fe8b39a8 h1:+YD75cZtvj0uFVOjb8XglqJ4Ev4UFKyAvzR3TOMREW0=
10
10
+
github.com/bluesky-social/indigo v0.0.0-20250925152209-0f22fe8b39a8/go.mod h1:n6QE1NDPFoi7PRbMUZmc2y7FibCqiVU4ePpsvhHUBR8=
11
11
+
github.com/carlmjohnson/versioninfo v0.22.5 h1:O00sjOLUAFxYQjlN/bzYTuZiS0y6fWDQjMRvwtKgwwc=
12
12
+
github.com/carlmjohnson/versioninfo v0.22.5/go.mod h1:QT9mph3wcVfISUKd0i9sZfVrPviHuSF+cUtLjm2WSf8=
13
13
+
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
14
14
+
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
7
15
github.com/charmbracelet/bubbles v0.21.0 h1:9TdC97SdRVg/1aaXNVWfFH3nnLAwOXr8Fn6u6mfQdFs=
8
16
github.com/charmbracelet/bubbles v0.21.0/go.mod h1:HF+v6QUR4HkEpz62dx7ym2xc71/KBHg+zKwJtMw+qtg=
9
17
github.com/charmbracelet/bubbletea v1.3.10 h1:otUDHWMMzQSB0Pkc87rm691KZ3SWa4KUlvF9nRvCICw=
···
20
28
github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U=
21
29
github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ=
22
30
github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg=
31
31
+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
32
32
+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
23
33
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
24
34
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
35
35
+
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
36
36
+
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
37
37
+
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
38
38
+
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
39
39
+
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
40
40
+
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
41
41
+
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
42
42
+
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
43
43
+
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
44
44
+
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
45
45
+
github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=
46
46
+
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
25
47
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
26
48
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
49
49
+
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
50
50
+
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
51
51
+
github.com/hashicorp/go-retryablehttp v0.7.5 h1:bJj+Pj19UZMIweq/iie+1u5YCdGrnxCT9yvm0e+Nd5M=
52
52
+
github.com/hashicorp/go-retryablehttp v0.7.5/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8=
53
53
+
github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c=
54
54
+
github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
55
55
+
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
56
56
+
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
57
57
+
github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs=
58
58
+
github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0=
59
59
+
github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs=
60
60
+
github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM=
61
61
+
github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s=
62
62
+
github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk=
63
63
+
github.com/ipfs/go-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0Myk=
64
64
+
github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8O4Vn9YAT8=
65
65
+
github.com/ipfs/go-ipfs-blockstore v1.3.1 h1:cEI9ci7V0sRNivqaOr0elDsamxXFxJMMMy7PTTDQNsQ=
66
66
+
github.com/ipfs/go-ipfs-blockstore v1.3.1/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE=
67
67
+
github.com/ipfs/go-ipfs-ds-help v1.1.1 h1:B5UJOH52IbcfS56+Ul+sv8jnIV10lbjLF5eOO0C66Nw=
68
68
+
github.com/ipfs/go-ipfs-ds-help v1.1.1/go.mod h1:75vrVCkSdSFidJscs8n4W+77AtTpCIAdDGAwjitJMIo=
69
69
+
github.com/ipfs/go-ipfs-util v0.0.3 h1:2RFdGez6bu2ZlZdI+rWfIdbQb1KudQp3VGwPtdNCmE0=
70
70
+
github.com/ipfs/go-ipfs-util v0.0.3/go.mod h1:LHzG1a0Ig4G+iZ26UUOMjHd+lfM84LZCrn17xAKWBvs=
71
71
+
github.com/ipfs/go-ipld-cbor v0.1.0 h1:dx0nS0kILVivGhfWuB6dUpMa/LAwElHPw1yOGYopoYs=
72
72
+
github.com/ipfs/go-ipld-cbor v0.1.0/go.mod h1:U2aYlmVrJr2wsUBU67K4KgepApSZddGRDWBYR0H4sCk=
73
73
+
github.com/ipfs/go-ipld-format v0.6.0 h1:VEJlA2kQ3LqFSIm5Vu6eIlSxD/Ze90xtc4Meten1F5U=
74
74
+
github.com/ipfs/go-ipld-format v0.6.0/go.mod h1:g4QVMTn3marU3qXchwjpKPKgJv+zF+OlaKMyhJ4LHPg=
75
75
+
github.com/ipfs/go-log v1.0.5 h1:2dOuUCB1Z7uoczMWgAyDck5JLb72zHzrMnGnCNNbvY8=
76
76
+
github.com/ipfs/go-log v1.0.5/go.mod h1:j0b8ZoR+7+R99LD9jZ6+AJsrzkPbSXbZfGakb5JPtIo=
77
77
+
github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY=
78
78
+
github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI=
79
79
+
github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg=
80
80
+
github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY=
81
81
+
github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o=
82
82
+
github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4=
83
83
+
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
84
84
+
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
27
85
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
28
86
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
29
87
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
···
34
92
github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
35
93
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
36
94
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
95
95
+
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg=
96
96
+
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k=
97
97
+
github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM=
98
98
+
github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8=
99
99
+
github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
100
100
+
github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
37
101
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI=
38
102
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo=
39
103
github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=
40
104
github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
41
105
github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc=
42
106
github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk=
107
107
+
github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE=
108
108
+
github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI=
109
109
+
github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0=
110
110
+
github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4=
111
111
+
github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g=
112
112
+
github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk=
113
113
+
github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U=
114
114
+
github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM=
115
115
+
github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8=
116
116
+
github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU=
117
117
+
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
118
118
+
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
119
119
+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
120
120
+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
121
121
+
github.com/polydawn/refmt v0.89.1-0.20221221234430-40501e09de1f h1:VXTQfuJj9vKR4TCkEuWIckKvdHFeJH/huIFJ9/cXOB0=
122
122
+
github.com/polydawn/refmt v0.89.1-0.20221221234430-40501e09de1f/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw=
123
123
+
github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q=
124
124
+
github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY=
125
125
+
github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw=
126
126
+
github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI=
127
127
+
github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM=
128
128
+
github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY=
129
129
+
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
130
130
+
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
43
131
github.com/rachel-mp4/lrcproto v0.0.0-20250905154858-2ddb78e31d0c h1:t33xVlfSwvB80nj1jroRXUaq/RTgjWwD4l7p/ISatUQ=
44
132
github.com/rachel-mp4/lrcproto v0.0.0-20250905154858-2ddb78e31d0c/go.mod h1:hQzO36tQELGbkmRnUtKeM6NMU34t79ZcTlhM+MO7pHw=
45
133
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
···
47
135
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
48
136
github.com/sahilm/fuzzy v0.1.1 h1:ceu5RHF8DGgoi+/dR5PsECjCDH1BE3Fnmpo7aVXOdRA=
49
137
github.com/sahilm/fuzzy v0.1.1/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y=
138
138
+
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
139
139
+
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
140
140
+
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
141
141
+
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
142
142
+
github.com/whyrusleeping/cbor-gen v0.2.1-0.20241030202151-b7a6831be65e h1:28X54ciEwwUxyHn9yrZfl5ojgF4CBNLWX7LR0rvBkf4=
143
143
+
github.com/whyrusleeping/cbor-gen v0.2.1-0.20241030202151-b7a6831be65e/go.mod h1:pM99HXyEbSQHcosHc0iW7YFmwnscr+t9Te4ibko05so=
50
144
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
51
145
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
52
52
-
golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZtfTpbJLDr/lwfgO53E=
53
53
-
golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
146
146
+
gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b h1:CzigHMRySiX3drau9C6Q5CAbNIApmLdat5jPMqChvDA=
147
147
+
gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b/go.mod h1:/y/V339mxv2sZmYYR64O07VuCpdNZqCTwO8ZcouTMI8=
148
148
+
gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02 h1:qwDnMxjkyLmAFgcfgTnfJrmYKWhHnci3GjDqcZp1M3Q=
149
149
+
gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02/go.mod h1:JTnUj0mpYiAsuZLmKjTx/ex3AtMowcCgnE7YNyCEP0I=
150
150
+
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 h1:aFJWCqJMNjENlcleuuOkGAPH82y0yULBScfXcIEdS24=
151
151
+
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1/go.mod h1:sEGXWArGqc3tVa+ekntsN65DmVbVeW+7lTKTjZF3/Fo=
152
152
+
go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc=
153
153
+
go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo=
154
154
+
go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4=
155
155
+
go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM=
156
156
+
go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc=
157
157
+
go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ=
158
158
+
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
159
159
+
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
160
160
+
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
161
161
+
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
162
162
+
go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
163
163
+
go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
164
164
+
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
165
165
+
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
166
166
+
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ=
167
167
+
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE=
54
168
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
169
169
+
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
55
170
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
56
171
golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k=
57
172
golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
58
58
-
golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY=
59
59
-
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
173
173
+
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
174
174
+
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
175
175
+
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
176
176
+
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
177
177
+
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU=
178
178
+
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
60
179
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
61
180
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
181
181
+
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
182
182
+
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
183
183
+
lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI=
184
184
+
lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k=
+1207
lex/lexicons_cbor.go
···
1
1
+
// Code generated by github.com/whyrusleeping/cbor-gen. DO NOT EDIT.
2
2
+
3
3
+
package lex
4
4
+
5
5
+
import (
6
6
+
"fmt"
7
7
+
"io"
8
8
+
"math"
9
9
+
"sort"
10
10
+
11
11
+
util "github.com/bluesky-social/indigo/lex/util"
12
12
+
cid "github.com/ipfs/go-cid"
13
13
+
cbg "github.com/whyrusleeping/cbor-gen"
14
14
+
xerrors "golang.org/x/xerrors"
15
15
+
)
16
16
+
17
17
+
var _ = xerrors.Errorf
18
18
+
var _ = cid.Undef
19
19
+
var _ = math.E
20
20
+
var _ = sort.Sort
21
21
+
22
22
+
func (t *ProfileRecord) MarshalCBOR(w io.Writer) error {
23
23
+
if t == nil {
24
24
+
_, err := w.Write(cbg.CborNull)
25
25
+
return err
26
26
+
}
27
27
+
28
28
+
cw := cbg.NewCborWriter(w)
29
29
+
fieldCount := 6
30
30
+
31
31
+
if t.DisplayName == nil {
32
32
+
fieldCount--
33
33
+
}
34
34
+
35
35
+
if t.DefaultNick == nil {
36
36
+
fieldCount--
37
37
+
}
38
38
+
39
39
+
if t.Status == nil {
40
40
+
fieldCount--
41
41
+
}
42
42
+
43
43
+
if t.Avatar == nil {
44
44
+
fieldCount--
45
45
+
}
46
46
+
47
47
+
if t.Color == nil {
48
48
+
fieldCount--
49
49
+
}
50
50
+
51
51
+
if _, err := cw.Write(cbg.CborEncodeMajorType(cbg.MajMap, uint64(fieldCount))); err != nil {
52
52
+
return err
53
53
+
}
54
54
+
55
55
+
// t.LexiconTypeID (string) (string)
56
56
+
if len("$type") > 8192 {
57
57
+
return xerrors.Errorf("Value in field \"$type\" was too long")
58
58
+
}
59
59
+
60
60
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("$type"))); err != nil {
61
61
+
return err
62
62
+
}
63
63
+
if _, err := cw.WriteString(string("$type")); err != nil {
64
64
+
return err
65
65
+
}
66
66
+
67
67
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("org.xcvr.actor.profile"))); err != nil {
68
68
+
return err
69
69
+
}
70
70
+
if _, err := cw.WriteString(string("org.xcvr.actor.profile")); err != nil {
71
71
+
return err
72
72
+
}
73
73
+
74
74
+
// t.Color (uint64) (uint64)
75
75
+
if t.Color != nil {
76
76
+
77
77
+
if len("color") > 8192 {
78
78
+
return xerrors.Errorf("Value in field \"color\" was too long")
79
79
+
}
80
80
+
81
81
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("color"))); err != nil {
82
82
+
return err
83
83
+
}
84
84
+
if _, err := cw.WriteString(string("color")); err != nil {
85
85
+
return err
86
86
+
}
87
87
+
88
88
+
if t.Color == nil {
89
89
+
if _, err := cw.Write(cbg.CborNull); err != nil {
90
90
+
return err
91
91
+
}
92
92
+
} else {
93
93
+
if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(*t.Color)); err != nil {
94
94
+
return err
95
95
+
}
96
96
+
}
97
97
+
98
98
+
}
99
99
+
100
100
+
// t.Avatar (util.LexBlob) (struct)
101
101
+
if t.Avatar != nil {
102
102
+
103
103
+
if len("avatar") > 8192 {
104
104
+
return xerrors.Errorf("Value in field \"avatar\" was too long")
105
105
+
}
106
106
+
107
107
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("avatar"))); err != nil {
108
108
+
return err
109
109
+
}
110
110
+
if _, err := cw.WriteString(string("avatar")); err != nil {
111
111
+
return err
112
112
+
}
113
113
+
114
114
+
if err := t.Avatar.MarshalCBOR(cw); err != nil {
115
115
+
return err
116
116
+
}
117
117
+
}
118
118
+
119
119
+
// t.Status (string) (string)
120
120
+
if t.Status != nil {
121
121
+
122
122
+
if len("status") > 8192 {
123
123
+
return xerrors.Errorf("Value in field \"status\" was too long")
124
124
+
}
125
125
+
126
126
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("status"))); err != nil {
127
127
+
return err
128
128
+
}
129
129
+
if _, err := cw.WriteString(string("status")); err != nil {
130
130
+
return err
131
131
+
}
132
132
+
133
133
+
if t.Status == nil {
134
134
+
if _, err := cw.Write(cbg.CborNull); err != nil {
135
135
+
return err
136
136
+
}
137
137
+
} else {
138
138
+
if len(*t.Status) > 8192 {
139
139
+
return xerrors.Errorf("Value in field t.Status was too long")
140
140
+
}
141
141
+
142
142
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(*t.Status))); err != nil {
143
143
+
return err
144
144
+
}
145
145
+
if _, err := cw.WriteString(string(*t.Status)); err != nil {
146
146
+
return err
147
147
+
}
148
148
+
}
149
149
+
}
150
150
+
151
151
+
// t.DefaultNick (string) (string)
152
152
+
if t.DefaultNick != nil {
153
153
+
154
154
+
if len("defaultNick") > 8192 {
155
155
+
return xerrors.Errorf("Value in field \"defaultNick\" was too long")
156
156
+
}
157
157
+
158
158
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("defaultNick"))); err != nil {
159
159
+
return err
160
160
+
}
161
161
+
if _, err := cw.WriteString(string("defaultNick")); err != nil {
162
162
+
return err
163
163
+
}
164
164
+
165
165
+
if t.DefaultNick == nil {
166
166
+
if _, err := cw.Write(cbg.CborNull); err != nil {
167
167
+
return err
168
168
+
}
169
169
+
} else {
170
170
+
if len(*t.DefaultNick) > 8192 {
171
171
+
return xerrors.Errorf("Value in field t.DefaultNick was too long")
172
172
+
}
173
173
+
174
174
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(*t.DefaultNick))); err != nil {
175
175
+
return err
176
176
+
}
177
177
+
if _, err := cw.WriteString(string(*t.DefaultNick)); err != nil {
178
178
+
return err
179
179
+
}
180
180
+
}
181
181
+
}
182
182
+
183
183
+
// t.DisplayName (string) (string)
184
184
+
if t.DisplayName != nil {
185
185
+
186
186
+
if len("displayName") > 8192 {
187
187
+
return xerrors.Errorf("Value in field \"displayName\" was too long")
188
188
+
}
189
189
+
190
190
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("displayName"))); err != nil {
191
191
+
return err
192
192
+
}
193
193
+
if _, err := cw.WriteString(string("displayName")); err != nil {
194
194
+
return err
195
195
+
}
196
196
+
197
197
+
if t.DisplayName == nil {
198
198
+
if _, err := cw.Write(cbg.CborNull); err != nil {
199
199
+
return err
200
200
+
}
201
201
+
} else {
202
202
+
if len(*t.DisplayName) > 8192 {
203
203
+
return xerrors.Errorf("Value in field t.DisplayName was too long")
204
204
+
}
205
205
+
206
206
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(*t.DisplayName))); err != nil {
207
207
+
return err
208
208
+
}
209
209
+
if _, err := cw.WriteString(string(*t.DisplayName)); err != nil {
210
210
+
return err
211
211
+
}
212
212
+
}
213
213
+
}
214
214
+
return nil
215
215
+
}
216
216
+
217
217
+
func (t *ProfileRecord) UnmarshalCBOR(r io.Reader) (err error) {
218
218
+
*t = ProfileRecord{}
219
219
+
220
220
+
cr := cbg.NewCborReader(r)
221
221
+
222
222
+
maj, extra, err := cr.ReadHeader()
223
223
+
if err != nil {
224
224
+
return err
225
225
+
}
226
226
+
defer func() {
227
227
+
if err == io.EOF {
228
228
+
err = io.ErrUnexpectedEOF
229
229
+
}
230
230
+
}()
231
231
+
232
232
+
if maj != cbg.MajMap {
233
233
+
return fmt.Errorf("cbor input should be of type map")
234
234
+
}
235
235
+
236
236
+
if extra > cbg.MaxLength {
237
237
+
return fmt.Errorf("ProfileRecord: map struct too large (%d)", extra)
238
238
+
}
239
239
+
240
240
+
n := extra
241
241
+
242
242
+
nameBuf := make([]byte, 11)
243
243
+
for i := uint64(0); i < n; i++ {
244
244
+
nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 8192)
245
245
+
if err != nil {
246
246
+
return err
247
247
+
}
248
248
+
249
249
+
if !ok {
250
250
+
// Field doesn't exist on this type, so ignore it
251
251
+
if err := cbg.ScanForLinks(cr, func(cid.Cid) {}); err != nil {
252
252
+
return err
253
253
+
}
254
254
+
continue
255
255
+
}
256
256
+
257
257
+
switch string(nameBuf[:nameLen]) {
258
258
+
// t.LexiconTypeID (string) (string)
259
259
+
case "$type":
260
260
+
261
261
+
{
262
262
+
sval, err := cbg.ReadStringWithMax(cr, 8192)
263
263
+
if err != nil {
264
264
+
return err
265
265
+
}
266
266
+
267
267
+
t.LexiconTypeID = string(sval)
268
268
+
}
269
269
+
// t.Color (uint64) (uint64)
270
270
+
case "color":
271
271
+
272
272
+
{
273
273
+
274
274
+
b, err := cr.ReadByte()
275
275
+
if err != nil {
276
276
+
return err
277
277
+
}
278
278
+
if b != cbg.CborNull[0] {
279
279
+
if err := cr.UnreadByte(); err != nil {
280
280
+
return err
281
281
+
}
282
282
+
maj, extra, err = cr.ReadHeader()
283
283
+
if err != nil {
284
284
+
return err
285
285
+
}
286
286
+
if maj != cbg.MajUnsignedInt {
287
287
+
return fmt.Errorf("wrong type for uint64 field")
288
288
+
}
289
289
+
typed := uint64(extra)
290
290
+
t.Color = &typed
291
291
+
}
292
292
+
293
293
+
}
294
294
+
// t.Avatar (util.LexBlob) (struct)
295
295
+
case "avatar":
296
296
+
297
297
+
{
298
298
+
299
299
+
b, err := cr.ReadByte()
300
300
+
if err != nil {
301
301
+
return err
302
302
+
}
303
303
+
if b != cbg.CborNull[0] {
304
304
+
if err := cr.UnreadByte(); err != nil {
305
305
+
return err
306
306
+
}
307
307
+
t.Avatar = new(util.LexBlob)
308
308
+
if err := t.Avatar.UnmarshalCBOR(cr); err != nil {
309
309
+
return xerrors.Errorf("unmarshaling t.Avatar pointer: %w", err)
310
310
+
}
311
311
+
}
312
312
+
313
313
+
}
314
314
+
// t.Status (string) (string)
315
315
+
case "status":
316
316
+
317
317
+
{
318
318
+
b, err := cr.ReadByte()
319
319
+
if err != nil {
320
320
+
return err
321
321
+
}
322
322
+
if b != cbg.CborNull[0] {
323
323
+
if err := cr.UnreadByte(); err != nil {
324
324
+
return err
325
325
+
}
326
326
+
327
327
+
sval, err := cbg.ReadStringWithMax(cr, 8192)
328
328
+
if err != nil {
329
329
+
return err
330
330
+
}
331
331
+
332
332
+
t.Status = (*string)(&sval)
333
333
+
}
334
334
+
}
335
335
+
// t.DefaultNick (string) (string)
336
336
+
case "defaultNick":
337
337
+
338
338
+
{
339
339
+
b, err := cr.ReadByte()
340
340
+
if err != nil {
341
341
+
return err
342
342
+
}
343
343
+
if b != cbg.CborNull[0] {
344
344
+
if err := cr.UnreadByte(); err != nil {
345
345
+
return err
346
346
+
}
347
347
+
348
348
+
sval, err := cbg.ReadStringWithMax(cr, 8192)
349
349
+
if err != nil {
350
350
+
return err
351
351
+
}
352
352
+
353
353
+
t.DefaultNick = (*string)(&sval)
354
354
+
}
355
355
+
}
356
356
+
// t.DisplayName (string) (string)
357
357
+
case "displayName":
358
358
+
359
359
+
{
360
360
+
b, err := cr.ReadByte()
361
361
+
if err != nil {
362
362
+
return err
363
363
+
}
364
364
+
if b != cbg.CborNull[0] {
365
365
+
if err := cr.UnreadByte(); err != nil {
366
366
+
return err
367
367
+
}
368
368
+
369
369
+
sval, err := cbg.ReadStringWithMax(cr, 8192)
370
370
+
if err != nil {
371
371
+
return err
372
372
+
}
373
373
+
374
374
+
t.DisplayName = (*string)(&sval)
375
375
+
}
376
376
+
}
377
377
+
378
378
+
default:
379
379
+
// Field doesn't exist on this type, so ignore it
380
380
+
if err := cbg.ScanForLinks(r, func(cid.Cid) {}); err != nil {
381
381
+
return err
382
382
+
}
383
383
+
}
384
384
+
}
385
385
+
386
386
+
return nil
387
387
+
}
388
388
+
func (t *ChannelRecord) MarshalCBOR(w io.Writer) error {
389
389
+
if t == nil {
390
390
+
_, err := w.Write(cbg.CborNull)
391
391
+
return err
392
392
+
}
393
393
+
394
394
+
cw := cbg.NewCborWriter(w)
395
395
+
fieldCount := 5
396
396
+
397
397
+
if t.Topic == nil {
398
398
+
fieldCount--
399
399
+
}
400
400
+
401
401
+
if _, err := cw.Write(cbg.CborEncodeMajorType(cbg.MajMap, uint64(fieldCount))); err != nil {
402
402
+
return err
403
403
+
}
404
404
+
405
405
+
// t.Host (string) (string)
406
406
+
if len("host") > 8192 {
407
407
+
return xerrors.Errorf("Value in field \"host\" was too long")
408
408
+
}
409
409
+
410
410
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("host"))); err != nil {
411
411
+
return err
412
412
+
}
413
413
+
if _, err := cw.WriteString(string("host")); err != nil {
414
414
+
return err
415
415
+
}
416
416
+
417
417
+
if len(t.Host) > 8192 {
418
418
+
return xerrors.Errorf("Value in field t.Host was too long")
419
419
+
}
420
420
+
421
421
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Host))); err != nil {
422
422
+
return err
423
423
+
}
424
424
+
if _, err := cw.WriteString(string(t.Host)); err != nil {
425
425
+
return err
426
426
+
}
427
427
+
428
428
+
// t.LexiconTypeID (string) (string)
429
429
+
if len("$type") > 8192 {
430
430
+
return xerrors.Errorf("Value in field \"$type\" was too long")
431
431
+
}
432
432
+
433
433
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("$type"))); err != nil {
434
434
+
return err
435
435
+
}
436
436
+
if _, err := cw.WriteString(string("$type")); err != nil {
437
437
+
return err
438
438
+
}
439
439
+
440
440
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("org.xcvr.feed.channel"))); err != nil {
441
441
+
return err
442
442
+
}
443
443
+
if _, err := cw.WriteString(string("org.xcvr.feed.channel")); err != nil {
444
444
+
return err
445
445
+
}
446
446
+
447
447
+
// t.Title (string) (string)
448
448
+
if len("title") > 8192 {
449
449
+
return xerrors.Errorf("Value in field \"title\" was too long")
450
450
+
}
451
451
+
452
452
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("title"))); err != nil {
453
453
+
return err
454
454
+
}
455
455
+
if _, err := cw.WriteString(string("title")); err != nil {
456
456
+
return err
457
457
+
}
458
458
+
459
459
+
if len(t.Title) > 8192 {
460
460
+
return xerrors.Errorf("Value in field t.Title was too long")
461
461
+
}
462
462
+
463
463
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Title))); err != nil {
464
464
+
return err
465
465
+
}
466
466
+
if _, err := cw.WriteString(string(t.Title)); err != nil {
467
467
+
return err
468
468
+
}
469
469
+
470
470
+
// t.Topic (string) (string)
471
471
+
if t.Topic != nil {
472
472
+
473
473
+
if len("topic") > 8192 {
474
474
+
return xerrors.Errorf("Value in field \"topic\" was too long")
475
475
+
}
476
476
+
477
477
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("topic"))); err != nil {
478
478
+
return err
479
479
+
}
480
480
+
if _, err := cw.WriteString(string("topic")); err != nil {
481
481
+
return err
482
482
+
}
483
483
+
484
484
+
if t.Topic == nil {
485
485
+
if _, err := cw.Write(cbg.CborNull); err != nil {
486
486
+
return err
487
487
+
}
488
488
+
} else {
489
489
+
if len(*t.Topic) > 8192 {
490
490
+
return xerrors.Errorf("Value in field t.Topic was too long")
491
491
+
}
492
492
+
493
493
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(*t.Topic))); err != nil {
494
494
+
return err
495
495
+
}
496
496
+
if _, err := cw.WriteString(string(*t.Topic)); err != nil {
497
497
+
return err
498
498
+
}
499
499
+
}
500
500
+
}
501
501
+
502
502
+
// t.CreatedAt (string) (string)
503
503
+
if len("createdAt") > 8192 {
504
504
+
return xerrors.Errorf("Value in field \"createdAt\" was too long")
505
505
+
}
506
506
+
507
507
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("createdAt"))); err != nil {
508
508
+
return err
509
509
+
}
510
510
+
if _, err := cw.WriteString(string("createdAt")); err != nil {
511
511
+
return err
512
512
+
}
513
513
+
514
514
+
if len(t.CreatedAt) > 8192 {
515
515
+
return xerrors.Errorf("Value in field t.CreatedAt was too long")
516
516
+
}
517
517
+
518
518
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.CreatedAt))); err != nil {
519
519
+
return err
520
520
+
}
521
521
+
if _, err := cw.WriteString(string(t.CreatedAt)); err != nil {
522
522
+
return err
523
523
+
}
524
524
+
return nil
525
525
+
}
526
526
+
527
527
+
func (t *ChannelRecord) UnmarshalCBOR(r io.Reader) (err error) {
528
528
+
*t = ChannelRecord{}
529
529
+
530
530
+
cr := cbg.NewCborReader(r)
531
531
+
532
532
+
maj, extra, err := cr.ReadHeader()
533
533
+
if err != nil {
534
534
+
return err
535
535
+
}
536
536
+
defer func() {
537
537
+
if err == io.EOF {
538
538
+
err = io.ErrUnexpectedEOF
539
539
+
}
540
540
+
}()
541
541
+
542
542
+
if maj != cbg.MajMap {
543
543
+
return fmt.Errorf("cbor input should be of type map")
544
544
+
}
545
545
+
546
546
+
if extra > cbg.MaxLength {
547
547
+
return fmt.Errorf("ChannelRecord: map struct too large (%d)", extra)
548
548
+
}
549
549
+
550
550
+
n := extra
551
551
+
552
552
+
nameBuf := make([]byte, 9)
553
553
+
for i := uint64(0); i < n; i++ {
554
554
+
nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 8192)
555
555
+
if err != nil {
556
556
+
return err
557
557
+
}
558
558
+
559
559
+
if !ok {
560
560
+
// Field doesn't exist on this type, so ignore it
561
561
+
if err := cbg.ScanForLinks(cr, func(cid.Cid) {}); err != nil {
562
562
+
return err
563
563
+
}
564
564
+
continue
565
565
+
}
566
566
+
567
567
+
switch string(nameBuf[:nameLen]) {
568
568
+
// t.Host (string) (string)
569
569
+
case "host":
570
570
+
571
571
+
{
572
572
+
sval, err := cbg.ReadStringWithMax(cr, 8192)
573
573
+
if err != nil {
574
574
+
return err
575
575
+
}
576
576
+
577
577
+
t.Host = string(sval)
578
578
+
}
579
579
+
// t.LexiconTypeID (string) (string)
580
580
+
case "$type":
581
581
+
582
582
+
{
583
583
+
sval, err := cbg.ReadStringWithMax(cr, 8192)
584
584
+
if err != nil {
585
585
+
return err
586
586
+
}
587
587
+
588
588
+
t.LexiconTypeID = string(sval)
589
589
+
}
590
590
+
// t.Title (string) (string)
591
591
+
case "title":
592
592
+
593
593
+
{
594
594
+
sval, err := cbg.ReadStringWithMax(cr, 8192)
595
595
+
if err != nil {
596
596
+
return err
597
597
+
}
598
598
+
599
599
+
t.Title = string(sval)
600
600
+
}
601
601
+
// t.Topic (string) (string)
602
602
+
case "topic":
603
603
+
604
604
+
{
605
605
+
b, err := cr.ReadByte()
606
606
+
if err != nil {
607
607
+
return err
608
608
+
}
609
609
+
if b != cbg.CborNull[0] {
610
610
+
if err := cr.UnreadByte(); err != nil {
611
611
+
return err
612
612
+
}
613
613
+
614
614
+
sval, err := cbg.ReadStringWithMax(cr, 8192)
615
615
+
if err != nil {
616
616
+
return err
617
617
+
}
618
618
+
619
619
+
t.Topic = (*string)(&sval)
620
620
+
}
621
621
+
}
622
622
+
// t.CreatedAt (string) (string)
623
623
+
case "createdAt":
624
624
+
625
625
+
{
626
626
+
sval, err := cbg.ReadStringWithMax(cr, 8192)
627
627
+
if err != nil {
628
628
+
return err
629
629
+
}
630
630
+
631
631
+
t.CreatedAt = string(sval)
632
632
+
}
633
633
+
634
634
+
default:
635
635
+
// Field doesn't exist on this type, so ignore it
636
636
+
if err := cbg.ScanForLinks(r, func(cid.Cid) {}); err != nil {
637
637
+
return err
638
638
+
}
639
639
+
}
640
640
+
}
641
641
+
642
642
+
return nil
643
643
+
}
644
644
+
func (t *MessageRecord) MarshalCBOR(w io.Writer) error {
645
645
+
if t == nil {
646
646
+
_, err := w.Write(cbg.CborNull)
647
647
+
return err
648
648
+
}
649
649
+
650
650
+
cw := cbg.NewCborWriter(w)
651
651
+
fieldCount := 6
652
652
+
653
653
+
if t.Nick == nil {
654
654
+
fieldCount--
655
655
+
}
656
656
+
657
657
+
if t.Color == nil {
658
658
+
fieldCount--
659
659
+
}
660
660
+
661
661
+
if _, err := cw.Write(cbg.CborEncodeMajorType(cbg.MajMap, uint64(fieldCount))); err != nil {
662
662
+
return err
663
663
+
}
664
664
+
665
665
+
// t.Body (string) (string)
666
666
+
if len("body") > 8192 {
667
667
+
return xerrors.Errorf("Value in field \"body\" was too long")
668
668
+
}
669
669
+
670
670
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("body"))); err != nil {
671
671
+
return err
672
672
+
}
673
673
+
if _, err := cw.WriteString(string("body")); err != nil {
674
674
+
return err
675
675
+
}
676
676
+
677
677
+
if len(t.Body) > 8192 {
678
678
+
return xerrors.Errorf("Value in field t.Body was too long")
679
679
+
}
680
680
+
681
681
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Body))); err != nil {
682
682
+
return err
683
683
+
}
684
684
+
if _, err := cw.WriteString(string(t.Body)); err != nil {
685
685
+
return err
686
686
+
}
687
687
+
688
688
+
// t.Nick (string) (string)
689
689
+
if t.Nick != nil {
690
690
+
691
691
+
if len("nick") > 8192 {
692
692
+
return xerrors.Errorf("Value in field \"nick\" was too long")
693
693
+
}
694
694
+
695
695
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("nick"))); err != nil {
696
696
+
return err
697
697
+
}
698
698
+
if _, err := cw.WriteString(string("nick")); err != nil {
699
699
+
return err
700
700
+
}
701
701
+
702
702
+
if t.Nick == nil {
703
703
+
if _, err := cw.Write(cbg.CborNull); err != nil {
704
704
+
return err
705
705
+
}
706
706
+
} else {
707
707
+
if len(*t.Nick) > 8192 {
708
708
+
return xerrors.Errorf("Value in field t.Nick was too long")
709
709
+
}
710
710
+
711
711
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(*t.Nick))); err != nil {
712
712
+
return err
713
713
+
}
714
714
+
if _, err := cw.WriteString(string(*t.Nick)); err != nil {
715
715
+
return err
716
716
+
}
717
717
+
}
718
718
+
}
719
719
+
720
720
+
// t.LexiconTypeID (string) (string)
721
721
+
if len("$type") > 8192 {
722
722
+
return xerrors.Errorf("Value in field \"$type\" was too long")
723
723
+
}
724
724
+
725
725
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("$type"))); err != nil {
726
726
+
return err
727
727
+
}
728
728
+
if _, err := cw.WriteString(string("$type")); err != nil {
729
729
+
return err
730
730
+
}
731
731
+
732
732
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("org.xcvr.lrc.message"))); err != nil {
733
733
+
return err
734
734
+
}
735
735
+
if _, err := cw.WriteString(string("org.xcvr.lrc.message")); err != nil {
736
736
+
return err
737
737
+
}
738
738
+
739
739
+
// t.Color (uint64) (uint64)
740
740
+
if t.Color != nil {
741
741
+
742
742
+
if len("color") > 8192 {
743
743
+
return xerrors.Errorf("Value in field \"color\" was too long")
744
744
+
}
745
745
+
746
746
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("color"))); err != nil {
747
747
+
return err
748
748
+
}
749
749
+
if _, err := cw.WriteString(string("color")); err != nil {
750
750
+
return err
751
751
+
}
752
752
+
753
753
+
if t.Color == nil {
754
754
+
if _, err := cw.Write(cbg.CborNull); err != nil {
755
755
+
return err
756
756
+
}
757
757
+
} else {
758
758
+
if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(*t.Color)); err != nil {
759
759
+
return err
760
760
+
}
761
761
+
}
762
762
+
763
763
+
}
764
764
+
765
765
+
// t.PostedAt (string) (string)
766
766
+
if len("postedAt") > 8192 {
767
767
+
return xerrors.Errorf("Value in field \"postedAt\" was too long")
768
768
+
}
769
769
+
770
770
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("postedAt"))); err != nil {
771
771
+
return err
772
772
+
}
773
773
+
if _, err := cw.WriteString(string("postedAt")); err != nil {
774
774
+
return err
775
775
+
}
776
776
+
777
777
+
if len(t.PostedAt) > 8192 {
778
778
+
return xerrors.Errorf("Value in field t.PostedAt was too long")
779
779
+
}
780
780
+
781
781
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.PostedAt))); err != nil {
782
782
+
return err
783
783
+
}
784
784
+
if _, err := cw.WriteString(string(t.PostedAt)); err != nil {
785
785
+
return err
786
786
+
}
787
787
+
788
788
+
// t.SignetURI (string) (string)
789
789
+
if len("signetURI") > 8192 {
790
790
+
return xerrors.Errorf("Value in field \"signetURI\" was too long")
791
791
+
}
792
792
+
793
793
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("signetURI"))); err != nil {
794
794
+
return err
795
795
+
}
796
796
+
if _, err := cw.WriteString(string("signetURI")); err != nil {
797
797
+
return err
798
798
+
}
799
799
+
800
800
+
if len(t.SignetURI) > 8192 {
801
801
+
return xerrors.Errorf("Value in field t.SignetURI was too long")
802
802
+
}
803
803
+
804
804
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.SignetURI))); err != nil {
805
805
+
return err
806
806
+
}
807
807
+
if _, err := cw.WriteString(string(t.SignetURI)); err != nil {
808
808
+
return err
809
809
+
}
810
810
+
return nil
811
811
+
}
812
812
+
813
813
+
func (t *MessageRecord) UnmarshalCBOR(r io.Reader) (err error) {
814
814
+
*t = MessageRecord{}
815
815
+
816
816
+
cr := cbg.NewCborReader(r)
817
817
+
818
818
+
maj, extra, err := cr.ReadHeader()
819
819
+
if err != nil {
820
820
+
return err
821
821
+
}
822
822
+
defer func() {
823
823
+
if err == io.EOF {
824
824
+
err = io.ErrUnexpectedEOF
825
825
+
}
826
826
+
}()
827
827
+
828
828
+
if maj != cbg.MajMap {
829
829
+
return fmt.Errorf("cbor input should be of type map")
830
830
+
}
831
831
+
832
832
+
if extra > cbg.MaxLength {
833
833
+
return fmt.Errorf("MessageRecord: map struct too large (%d)", extra)
834
834
+
}
835
835
+
836
836
+
n := extra
837
837
+
838
838
+
nameBuf := make([]byte, 9)
839
839
+
for i := uint64(0); i < n; i++ {
840
840
+
nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 8192)
841
841
+
if err != nil {
842
842
+
return err
843
843
+
}
844
844
+
845
845
+
if !ok {
846
846
+
// Field doesn't exist on this type, so ignore it
847
847
+
if err := cbg.ScanForLinks(cr, func(cid.Cid) {}); err != nil {
848
848
+
return err
849
849
+
}
850
850
+
continue
851
851
+
}
852
852
+
853
853
+
switch string(nameBuf[:nameLen]) {
854
854
+
// t.Body (string) (string)
855
855
+
case "body":
856
856
+
857
857
+
{
858
858
+
sval, err := cbg.ReadStringWithMax(cr, 8192)
859
859
+
if err != nil {
860
860
+
return err
861
861
+
}
862
862
+
863
863
+
t.Body = string(sval)
864
864
+
}
865
865
+
// t.Nick (string) (string)
866
866
+
case "nick":
867
867
+
868
868
+
{
869
869
+
b, err := cr.ReadByte()
870
870
+
if err != nil {
871
871
+
return err
872
872
+
}
873
873
+
if b != cbg.CborNull[0] {
874
874
+
if err := cr.UnreadByte(); err != nil {
875
875
+
return err
876
876
+
}
877
877
+
878
878
+
sval, err := cbg.ReadStringWithMax(cr, 8192)
879
879
+
if err != nil {
880
880
+
return err
881
881
+
}
882
882
+
883
883
+
t.Nick = (*string)(&sval)
884
884
+
}
885
885
+
}
886
886
+
// t.LexiconTypeID (string) (string)
887
887
+
case "$type":
888
888
+
889
889
+
{
890
890
+
sval, err := cbg.ReadStringWithMax(cr, 8192)
891
891
+
if err != nil {
892
892
+
return err
893
893
+
}
894
894
+
895
895
+
t.LexiconTypeID = string(sval)
896
896
+
}
897
897
+
// t.Color (uint64) (uint64)
898
898
+
case "color":
899
899
+
900
900
+
{
901
901
+
902
902
+
b, err := cr.ReadByte()
903
903
+
if err != nil {
904
904
+
return err
905
905
+
}
906
906
+
if b != cbg.CborNull[0] {
907
907
+
if err := cr.UnreadByte(); err != nil {
908
908
+
return err
909
909
+
}
910
910
+
maj, extra, err = cr.ReadHeader()
911
911
+
if err != nil {
912
912
+
return err
913
913
+
}
914
914
+
if maj != cbg.MajUnsignedInt {
915
915
+
return fmt.Errorf("wrong type for uint64 field")
916
916
+
}
917
917
+
typed := uint64(extra)
918
918
+
t.Color = &typed
919
919
+
}
920
920
+
921
921
+
}
922
922
+
// t.PostedAt (string) (string)
923
923
+
case "postedAt":
924
924
+
925
925
+
{
926
926
+
sval, err := cbg.ReadStringWithMax(cr, 8192)
927
927
+
if err != nil {
928
928
+
return err
929
929
+
}
930
930
+
931
931
+
t.PostedAt = string(sval)
932
932
+
}
933
933
+
// t.SignetURI (string) (string)
934
934
+
case "signetURI":
935
935
+
936
936
+
{
937
937
+
sval, err := cbg.ReadStringWithMax(cr, 8192)
938
938
+
if err != nil {
939
939
+
return err
940
940
+
}
941
941
+
942
942
+
t.SignetURI = string(sval)
943
943
+
}
944
944
+
945
945
+
default:
946
946
+
// Field doesn't exist on this type, so ignore it
947
947
+
if err := cbg.ScanForLinks(r, func(cid.Cid) {}); err != nil {
948
948
+
return err
949
949
+
}
950
950
+
}
951
951
+
}
952
952
+
953
953
+
return nil
954
954
+
}
955
955
+
func (t *SignetRecord) MarshalCBOR(w io.Writer) error {
956
956
+
if t == nil {
957
957
+
_, err := w.Write(cbg.CborNull)
958
958
+
return err
959
959
+
}
960
960
+
961
961
+
cw := cbg.NewCborWriter(w)
962
962
+
fieldCount := 5
963
963
+
964
964
+
if t.StartedAt == nil {
965
965
+
fieldCount--
966
966
+
}
967
967
+
968
968
+
if _, err := cw.Write(cbg.CborEncodeMajorType(cbg.MajMap, uint64(fieldCount))); err != nil {
969
969
+
return err
970
970
+
}
971
971
+
972
972
+
// t.Author (string) (string)
973
973
+
if len("nick") > 8192 {
974
974
+
return xerrors.Errorf("Value in field \"nick\" was too long")
975
975
+
}
976
976
+
977
977
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("nick"))); err != nil {
978
978
+
return err
979
979
+
}
980
980
+
if _, err := cw.WriteString(string("nick")); err != nil {
981
981
+
return err
982
982
+
}
983
983
+
984
984
+
if len(t.AuthorHandle) > 8192 {
985
985
+
return xerrors.Errorf("Value in field t.Author was too long")
986
986
+
}
987
987
+
988
988
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.AuthorHandle))); err != nil {
989
989
+
return err
990
990
+
}
991
991
+
if _, err := cw.WriteString(string(t.AuthorHandle)); err != nil {
992
992
+
return err
993
993
+
}
994
994
+
995
995
+
// t.LexiconTypeID (string) (string)
996
996
+
if len("$type") > 8192 {
997
997
+
return xerrors.Errorf("Value in field \"$type\" was too long")
998
998
+
}
999
999
+
1000
1000
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("$type"))); err != nil {
1001
1001
+
return err
1002
1002
+
}
1003
1003
+
if _, err := cw.WriteString(string("$type")); err != nil {
1004
1004
+
return err
1005
1005
+
}
1006
1006
+
1007
1007
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("org.xcvr.lrc.signet"))); err != nil {
1008
1008
+
return err
1009
1009
+
}
1010
1010
+
if _, err := cw.WriteString(string("org.xcvr.lrc.signet")); err != nil {
1011
1011
+
return err
1012
1012
+
}
1013
1013
+
1014
1014
+
// t.LRCID (uint64) (uint64)
1015
1015
+
if len("lrcID") > 8192 {
1016
1016
+
return xerrors.Errorf("Value in field \"lrcID\" was too long")
1017
1017
+
}
1018
1018
+
1019
1019
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("lrcID"))); err != nil {
1020
1020
+
return err
1021
1021
+
}
1022
1022
+
if _, err := cw.WriteString(string("lrcID")); err != nil {
1023
1023
+
return err
1024
1024
+
}
1025
1025
+
1026
1026
+
if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.LRCID)); err != nil {
1027
1027
+
return err
1028
1028
+
}
1029
1029
+
1030
1030
+
// t.StartedAt (string) (string)
1031
1031
+
if t.StartedAt != nil {
1032
1032
+
1033
1033
+
if len("startedAt") > 8192 {
1034
1034
+
return xerrors.Errorf("Value in field \"startedAt\" was too long")
1035
1035
+
}
1036
1036
+
1037
1037
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("startedAt"))); err != nil {
1038
1038
+
return err
1039
1039
+
}
1040
1040
+
if _, err := cw.WriteString(string("startedAt")); err != nil {
1041
1041
+
return err
1042
1042
+
}
1043
1043
+
1044
1044
+
if t.StartedAt == nil {
1045
1045
+
if _, err := cw.Write(cbg.CborNull); err != nil {
1046
1046
+
return err
1047
1047
+
}
1048
1048
+
} else {
1049
1049
+
if len(*t.StartedAt) > 8192 {
1050
1050
+
return xerrors.Errorf("Value in field t.StartedAt was too long")
1051
1051
+
}
1052
1052
+
1053
1053
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(*t.StartedAt))); err != nil {
1054
1054
+
return err
1055
1055
+
}
1056
1056
+
if _, err := cw.WriteString(string(*t.StartedAt)); err != nil {
1057
1057
+
return err
1058
1058
+
}
1059
1059
+
}
1060
1060
+
}
1061
1061
+
1062
1062
+
// t.ChannelURI (string) (string)
1063
1063
+
if len("channelURI") > 8192 {
1064
1064
+
return xerrors.Errorf("Value in field \"channelURI\" was too long")
1065
1065
+
}
1066
1066
+
1067
1067
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("channelURI"))); err != nil {
1068
1068
+
return err
1069
1069
+
}
1070
1070
+
if _, err := cw.WriteString(string("channelURI")); err != nil {
1071
1071
+
return err
1072
1072
+
}
1073
1073
+
1074
1074
+
if len(t.ChannelURI) > 8192 {
1075
1075
+
return xerrors.Errorf("Value in field t.ChannelURI was too long")
1076
1076
+
}
1077
1077
+
1078
1078
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.ChannelURI))); err != nil {
1079
1079
+
return err
1080
1080
+
}
1081
1081
+
if _, err := cw.WriteString(string(t.ChannelURI)); err != nil {
1082
1082
+
return err
1083
1083
+
}
1084
1084
+
return nil
1085
1085
+
}
1086
1086
+
1087
1087
+
func (t *SignetRecord) UnmarshalCBOR(r io.Reader) (err error) {
1088
1088
+
*t = SignetRecord{}
1089
1089
+
1090
1090
+
cr := cbg.NewCborReader(r)
1091
1091
+
1092
1092
+
maj, extra, err := cr.ReadHeader()
1093
1093
+
if err != nil {
1094
1094
+
return err
1095
1095
+
}
1096
1096
+
defer func() {
1097
1097
+
if err == io.EOF {
1098
1098
+
err = io.ErrUnexpectedEOF
1099
1099
+
}
1100
1100
+
}()
1101
1101
+
1102
1102
+
if maj != cbg.MajMap {
1103
1103
+
return fmt.Errorf("cbor input should be of type map")
1104
1104
+
}
1105
1105
+
1106
1106
+
if extra > cbg.MaxLength {
1107
1107
+
return fmt.Errorf("SignetRecord: map struct too large (%d)", extra)
1108
1108
+
}
1109
1109
+
1110
1110
+
n := extra
1111
1111
+
1112
1112
+
nameBuf := make([]byte, 10)
1113
1113
+
for i := uint64(0); i < n; i++ {
1114
1114
+
nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 8192)
1115
1115
+
if err != nil {
1116
1116
+
return err
1117
1117
+
}
1118
1118
+
1119
1119
+
if !ok {
1120
1120
+
// Field doesn't exist on this type, so ignore it
1121
1121
+
if err := cbg.ScanForLinks(cr, func(cid.Cid) {}); err != nil {
1122
1122
+
return err
1123
1123
+
}
1124
1124
+
continue
1125
1125
+
}
1126
1126
+
1127
1127
+
switch string(nameBuf[:nameLen]) {
1128
1128
+
// t.Author (string) (string)
1129
1129
+
case "authorHandle":
1130
1130
+
1131
1131
+
{
1132
1132
+
sval, err := cbg.ReadStringWithMax(cr, 8192)
1133
1133
+
if err != nil {
1134
1134
+
return err
1135
1135
+
}
1136
1136
+
1137
1137
+
t.AuthorHandle = string(sval)
1138
1138
+
}
1139
1139
+
// t.LexiconTypeID (string) (string)
1140
1140
+
case "$type":
1141
1141
+
1142
1142
+
{
1143
1143
+
sval, err := cbg.ReadStringWithMax(cr, 8192)
1144
1144
+
if err != nil {
1145
1145
+
return err
1146
1146
+
}
1147
1147
+
1148
1148
+
t.LexiconTypeID = string(sval)
1149
1149
+
}
1150
1150
+
// t.LRCID (uint64) (uint64)
1151
1151
+
case "lrcID":
1152
1152
+
1153
1153
+
{
1154
1154
+
1155
1155
+
maj, extra, err = cr.ReadHeader()
1156
1156
+
if err != nil {
1157
1157
+
return err
1158
1158
+
}
1159
1159
+
if maj != cbg.MajUnsignedInt {
1160
1160
+
return fmt.Errorf("wrong type for uint64 field")
1161
1161
+
}
1162
1162
+
t.LRCID = uint64(extra)
1163
1163
+
1164
1164
+
}
1165
1165
+
// t.StartedAt (string) (string)
1166
1166
+
case "startedAt":
1167
1167
+
1168
1168
+
{
1169
1169
+
b, err := cr.ReadByte()
1170
1170
+
if err != nil {
1171
1171
+
return err
1172
1172
+
}
1173
1173
+
if b != cbg.CborNull[0] {
1174
1174
+
if err := cr.UnreadByte(); err != nil {
1175
1175
+
return err
1176
1176
+
}
1177
1177
+
1178
1178
+
sval, err := cbg.ReadStringWithMax(cr, 8192)
1179
1179
+
if err != nil {
1180
1180
+
return err
1181
1181
+
}
1182
1182
+
1183
1183
+
t.StartedAt = (*string)(&sval)
1184
1184
+
}
1185
1185
+
}
1186
1186
+
// t.ChannelURI (string) (string)
1187
1187
+
case "channelURI":
1188
1188
+
1189
1189
+
{
1190
1190
+
sval, err := cbg.ReadStringWithMax(cr, 8192)
1191
1191
+
if err != nil {
1192
1192
+
return err
1193
1193
+
}
1194
1194
+
1195
1195
+
t.ChannelURI = string(sval)
1196
1196
+
}
1197
1197
+
1198
1198
+
default:
1199
1199
+
// Field doesn't exist on this type, so ignore it
1200
1200
+
if err := cbg.ScanForLinks(r, func(cid.Cid) {}); err != nil {
1201
1201
+
return err
1202
1202
+
}
1203
1203
+
}
1204
1204
+
}
1205
1205
+
1206
1206
+
return nil
1207
1207
+
}
+71
lex/types.go
···
1
1
+
package lex
2
2
+
3
3
+
import (
4
4
+
"github.com/bluesky-social/indigo/lex/util"
5
5
+
)
6
6
+
7
7
+
func init() {
8
8
+
util.RegisterType("org.xcvr.actor.profile", &ProfileRecord{})
9
9
+
util.RegisterType("org.xcvr.feed.channel", &ChannelRecord{})
10
10
+
util.RegisterType("org.xcvr.lrc.message", &MessageRecord{})
11
11
+
util.RegisterType("org.xcvr.lrc.signet", &SignetRecord{})
12
12
+
}
13
13
+
14
14
+
type ProfileRecord struct {
15
15
+
LexiconTypeID string `json:"$type,const=org.xcvr.actor.profile" cborgen:"$type,const=org.xcvr.actor.profile"`
16
16
+
DisplayName *string `json:"displayName,omitempty" cborgen:"displayName,omitempty"`
17
17
+
DefaultNick *string `json:"defaultNick,omitempty" cborgen:"defaultNick,omitempty"`
18
18
+
Status *string `json:"status,omitempty" cborgen:"status,omitempty"`
19
19
+
Avatar *util.LexBlob `json:"avatar,omitempty" cborgen:"avatar,omitempty"`
20
20
+
Color *uint64 `json:"color,omitempty" cborgen:"color,omitempty"`
21
21
+
}
22
22
+
23
23
+
type ChannelRecord struct {
24
24
+
LexiconTypeID string `json:"$type,const=org.xcvr.feed.channel" cborgen:"$type,const=org.xcvr.feed.channel"`
25
25
+
Title string `json:"title" cborgen:"title"`
26
26
+
Topic *string `json:"topic,omitempty" cborgen:"topic,omitempty"`
27
27
+
CreatedAt string `json:"createdAt" cborgen:"createdAt"`
28
28
+
Host string `json:"host" cborgen:"host"`
29
29
+
}
30
30
+
31
31
+
type MessageRecord struct {
32
32
+
LexiconTypeID string `json:"$type,const=org.xcvr.lrc.message" cborgen:"$type,const=org.xcvr.lrc.message"`
33
33
+
SignetURI string `json:"signetURI" cborgen:"signetURI"`
34
34
+
Body string `json:"body" cborgen:"body"`
35
35
+
Nick *string `json:"nick,omitempty" cborgen:"nick,omitempty"`
36
36
+
Color *uint64 `json:"color,omitempty" cborgen:"color,omitempty"`
37
37
+
PostedAt string `json:"postedAt" cborgen:"postedAt"`
38
38
+
}
39
39
+
40
40
+
type SignetRecord struct {
41
41
+
LexiconTypeID string `json:"$type,const=org.xcvr.lrc.signet" cborgen:"$type,const=org.xcvr.lrc.signet"`
42
42
+
ChannelURI string `json:"channelURI" cborgen:"channelURI"`
43
43
+
LRCID uint64 `json:"lrcID" cborgen:"lrcID"`
44
44
+
AuthorHandle string `json:"authorHandle" cborgen:"authorHandle"`
45
45
+
StartedAt *string `json:"startedAt,omitempty" cborgen:"startedAt,omitempty"`
46
46
+
}
47
47
+
48
48
+
type MediaRecord struct {
49
49
+
LexiconTypeID string `json:"$type,const=org.xcvr.lrc.media" cborgen:"$type,const=org.xcvr.lrc.media"`
50
50
+
SignetURI string `json:"signetURI" cborgen:"signetURI"`
51
51
+
Media Media `json:"media" cborgen:"media"`
52
52
+
Nick *string `json:"nick,omitempty" cborgen:"nick,omitempty"`
53
53
+
Color *uint64 `json:"color,omitempty" cborgen:"color,omitempty"`
54
54
+
PostedAt string `json:"postedAt" cborgen:"postedAt"`
55
55
+
}
56
56
+
57
57
+
type Media struct {
58
58
+
Image *Image
59
59
+
}
60
60
+
61
61
+
type Image struct {
62
62
+
LexiconTypeID string `json:"$type,const=org.xcvr.lrc.image" cborgen:"$type,const=org.xcvr.lrc.image"`
63
63
+
Alt string `json:"alt" cborgen:"alt"`
64
64
+
AspectRatio *AspectRatio `json:"aspectRatio,omitempty" cborgen:"aspectRatio,omitempty"`
65
65
+
Image *util.BlobSchema `json:"image,omitempty" cborgen:"image,omitempty"`
66
66
+
}
67
67
+
68
68
+
type AspectRatio struct {
69
69
+
Height int64 `json:"height" cborgen:"height"`
70
70
+
Width int64 `json:"width" cborgen:"width"`
71
71
+
}
+598
-34
main.go
···
8
8
"io"
9
9
"net/http"
10
10
"os"
11
11
+
"strconv"
11
12
"strings"
12
13
"time"
13
14
"unicode/utf16"
14
15
16
16
+
"github.com/bluesky-social/indigo/api/atproto"
17
17
+
"github.com/bluesky-social/indigo/atproto/client"
18
18
+
"github.com/bluesky-social/indigo/atproto/identity"
19
19
+
"github.com/bluesky-social/indigo/atproto/syntax"
20
20
+
"github.com/bluesky-social/indigo/lex/util"
15
21
"github.com/charmbracelet/bubbles/list"
22
22
+
"github.com/charmbracelet/bubbles/textinput"
16
23
"github.com/charmbracelet/bubbles/viewport"
17
24
tea "github.com/charmbracelet/bubbletea"
18
25
"github.com/charmbracelet/lipgloss"
19
26
"github.com/gorilla/websocket"
20
27
"github.com/rachel-mp4/lrcproto/gen/go"
28
28
+
"github.com/rachel-mp4/ttyxcvr/lex"
21
29
"google.golang.org/protobuf/proto"
22
30
)
23
31
···
60
68
width int
61
69
height int
62
70
error *error
63
63
-
command *string
71
71
+
prompt textinput.Model
72
72
+
draft *textinput.Model
73
73
+
sentmsg *string
64
74
channels *[]Channel
65
75
list *list.Model
66
76
curchannel *Channel
67
77
wsurl *string
68
78
lrcconn *websocket.Conn
79
79
+
lexconn *websocket.Conn
80
80
+
evtchan chan []byte
69
81
cancel func()
70
82
vp *viewport.Model
71
83
msgs map[uint32]*Message
84
84
+
myid *uint32
72
85
renders []*string
73
86
topic *string
74
87
color *uint32
75
88
nick *string
76
89
handle *string
90
90
+
signeturi *string
91
91
+
xrpc *PasswordClient
77
92
}
78
93
79
94
type Message struct {
···
140
155
var desc string
141
156
var uri string
142
157
var host string
158
158
+
var color *uint32
159
159
+
var author string
143
160
if i, ok := item.(ChannelItem); ok {
144
161
title = i.Title()
145
162
desc = i.Description()
146
146
-
host = subduedStyle.Render(fmt.Sprintf("(hosted by %s)", i.Host()))
163
163
+
author = fmt.Sprintf("(%s)", renderName(i.channel.Creator.DisplayName, i.channel.Creator.Handle))
164
164
+
host = subduedStyle.Render(fmt.Sprintf("(hosted on %s)", i.Host()))
147
165
if desc == "" {
148
166
desc = subduedStyle.Render("no provided description")
149
167
}
150
168
uri = i.URI()
169
169
+
color = i.channel.Creator.Color
151
170
} else {
152
171
return
153
172
}
154
173
if index == m.Index() {
155
155
-
greenStyle := lipgloss.NewStyle().Foreground(Green)
156
156
-
title = fmt.Sprintf("│%s %s", greenStyle.Render(title), host)
174
174
+
greenStyle := lipgloss.NewStyle().Foreground(ColorFromInt(color))
175
175
+
title = fmt.Sprintf("│%s %s", greenStyle.Render(title), author)
157
176
desc = fmt.Sprintf("│%s", desc)
158
177
uri = fmt.Sprintf("└%s", strings.Repeat("─", m.Width()-1))
159
178
} else {
160
179
s := lipgloss.NewStyle()
161
180
s = s.Foreground(subduedColor)
162
181
uri = s.Render(uri)
182
182
+
host = subduedStyle.Render(author)
163
183
}
164
184
fmt.Fprintf(w, "%s %s\n%s\n%s", title, host, desc, uri)
165
185
}
166
186
167
187
func initialModel() model {
188
188
+
prompt := textinput.New()
189
189
+
prompt.Prompt = ":"
190
190
+
nick := "wanderer"
191
191
+
color := uint32(33096)
168
192
return model{
169
193
state: Splash,
170
194
mode: Normal,
195
195
+
prompt: prompt,
171
196
width: 30,
172
197
height: 20,
198
198
+
nick: &nick,
199
199
+
color: &color,
173
200
}
174
201
}
175
202
func (m model) Init() tea.Cmd {
···
213
240
214
241
type errMsg struct{ err error }
215
242
243
243
+
func login(handle string, secret string) tea.Cmd {
244
244
+
return func() tea.Msg {
245
245
+
hdl, err := syntax.ParseHandle(handle)
246
246
+
if err != nil {
247
247
+
err = errors.New("handle failed to parse: " + err.Error())
248
248
+
return errMsg{err}
249
249
+
}
250
250
+
id, err := identity.DefaultDirectory().LookupHandle(context.Background(), hdl)
251
251
+
if err != nil {
252
252
+
err = errors.New("handle failed to loopup: " + err.Error())
253
253
+
return errMsg{err}
254
254
+
}
255
255
+
xrpc := NewPasswordClient(id.DID.String(), id.PDSEndpoint())
256
256
+
err = xrpc.CreateSession(context.Background(), handle, secret)
257
257
+
if err != nil {
258
258
+
return errMsg{err}
259
259
+
}
260
260
+
return loggedInMsg{xrpc}
261
261
+
}
262
262
+
}
263
263
+
264
264
+
type loggedInMsg struct {
265
265
+
xrpc *PasswordClient
266
266
+
}
267
267
+
216
268
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
217
269
switch msg := msg.(type) {
218
270
case errMsg:
219
271
m.state = Error
220
272
m.error = &msg.err
273
273
+
return m, nil
274
274
+
case svMsg:
275
275
+
if m.myid != nil && msg.signetView.LrcId == *m.myid {
276
276
+
m.signeturi = &msg.signetView.URI
277
277
+
return m, nil
278
278
+
}
279
279
+
280
280
+
case loginMsg:
281
281
+
if len(msg.value) == 2 {
282
282
+
return m, login(msg.value[0], msg.value[1])
283
283
+
}
284
284
+
case loggedInMsg:
285
285
+
m.xrpc = msg.xrpc
286
286
+
return m, nil
287
287
+
288
288
+
case setMsg:
289
289
+
key, val, found := strings.Cut(msg.value, "=")
290
290
+
if !found {
291
291
+
return m, nil
292
292
+
}
293
293
+
switch key {
294
294
+
case "color", "c":
295
295
+
i, err := strconv.Atoi(val)
296
296
+
if err != nil {
297
297
+
return m, nil
298
298
+
}
299
299
+
b := uint32(i)
300
300
+
m.color = &b
301
301
+
if m.draft != nil {
302
302
+
m.draft.PromptStyle = lipgloss.NewStyle().Foreground(ColorFromInt(&b))
303
303
+
}
304
304
+
err = sendSet(m.evtchan, m.nick, m.handle, m.color)
305
305
+
if err != nil {
306
306
+
send(errMsg{err})
307
307
+
}
308
308
+
return m, nil
309
309
+
case "nick", "name", "n":
310
310
+
m.nick = &val
311
311
+
if m.draft != nil {
312
312
+
m.draft.Prompt = renderName(m.nick, m.handle) + " "
313
313
+
}
314
314
+
err := sendSet(m.evtchan, m.nick, m.handle, m.color)
315
315
+
if err != nil {
316
316
+
send(errMsg{err})
317
317
+
}
318
318
+
return m, nil
319
319
+
case "handle", "h", "at", "@":
320
320
+
m.handle = &val
321
321
+
if m.draft != nil {
322
322
+
m.draft.Prompt = renderName(m.nick, m.handle) + " "
323
323
+
}
324
324
+
err := sendSet(m.evtchan, m.nick, m.handle, m.color)
325
325
+
if err != nil {
326
326
+
send(errMsg{err})
327
327
+
}
328
328
+
return m, nil
329
329
+
}
221
330
222
331
case tea.WindowSizeMsg:
223
332
m.height = msg.Height
224
333
m.width = msg.Width
334
334
+
if m.vp != nil {
335
335
+
m.vp.Width = msg.Width
336
336
+
m.vp.Height = msg.Height - 2
337
337
+
}
338
338
+
if m.renders != nil {
339
339
+
for _, message := range m.msgs {
340
340
+
message.renderMessage(msg.Width)
341
341
+
}
342
342
+
m.vp.SetContent(JoinDeref(m.renders, ""))
343
343
+
}
344
344
+
if m.list != nil {
345
345
+
m.list.SetSize(msg.Width, msg.Height)
346
346
+
}
347
347
+
return m, nil
225
348
226
349
case tea.KeyMsg:
227
350
switch msg.String() {
···
257
380
m.error = &err
258
381
return m, nil
259
382
}
383
383
+
id := msg.e.Id
260
384
switch msg := msg.e.Msg.(type) {
261
385
case *lrcpb.Event_Ping:
262
386
return m, nil
···
269
393
m.error = &err
270
394
return m, nil
271
395
}
396
396
+
if msg.Init.Echoed != nil && *msg.Init.Echoed {
397
397
+
m.myid = msg.Init.Id
398
398
+
}
272
399
m.vp.SetContent(JoinDeref(m.renders, ""))
273
400
return m, nil
274
401
case *lrcpb.Event_Pub:
···
310
437
}
311
438
return m, nil
312
439
case *lrcpb.Event_Editbatch:
440
440
+
if id == nil {
441
441
+
return m, nil
442
442
+
}
443
443
+
err := editMessage(*id, msg.Editbatch.Edits, m.msgs, &m.renders, m.width)
444
444
+
if err != nil {
445
445
+
m.state = Error
446
446
+
m.error = &err
447
447
+
return m, nil
448
448
+
}
449
449
+
m.vp.SetContent(JoinDeref(m.renders, ""))
313
450
return m, nil
451
451
+
}
452
452
+
case tea.KeyMsg:
453
453
+
switch m.mode {
454
454
+
case Normal:
455
455
+
switch msg.String() {
456
456
+
case "i", "a":
457
457
+
m.mode = Insert
458
458
+
return m, m.draft.Focus()
459
459
+
case ":":
460
460
+
m.mode = Command
461
461
+
return m, m.prompt.Focus()
462
462
+
}
463
463
+
case Insert:
464
464
+
switch msg.String() {
465
465
+
case "esc":
466
466
+
m.mode = Normal
467
467
+
m.draft.Blur()
468
468
+
return m, nil
469
469
+
case "enter":
470
470
+
if m.sentmsg != nil {
471
471
+
if m.xrpc != nil && m.signeturi != nil {
472
472
+
var color64 *uint64
473
473
+
if m.color != nil {
474
474
+
c64 := uint64(*m.color)
475
475
+
color64 = &c64
476
476
+
}
477
477
+
lmr := lex.MessageRecord{
478
478
+
SignetURI: *m.signeturi,
479
479
+
Body: *m.sentmsg,
480
480
+
Nick: m.nick,
481
481
+
Color: color64,
482
482
+
PostedAt: syntax.DatetimeNow().String(),
483
483
+
}
484
484
+
m.draft.SetValue("")
485
485
+
m.sentmsg = nil
486
486
+
m.myid = nil
487
487
+
m.signeturi = nil
488
488
+
return m, tea.Batch(sendPub(m.lrcconn), createMSGCmd(m.xrpc, &lmr))
489
489
+
}
490
490
+
m.draft.SetValue("")
491
491
+
m.sentmsg = nil
492
492
+
return m, sendPub(m.lrcconn)
493
493
+
}
494
494
+
return m, nil
495
495
+
}
496
496
+
case Command:
497
497
+
switch msg.String() {
498
498
+
case "esc":
499
499
+
m.mode = Normal
500
500
+
m.prompt.Blur()
501
501
+
m.prompt.SetValue("")
502
502
+
return m, nil
503
503
+
case "enter":
504
504
+
m.mode = Normal
505
505
+
m.prompt.Blur()
506
506
+
v := m.prompt.Value()
507
507
+
m.prompt.SetValue("")
508
508
+
return m, evaluateCommand(v)
509
509
+
default:
510
510
+
}
511
511
+
}
512
512
+
}
513
513
+
switch m.mode {
514
514
+
case Normal:
515
515
+
vp, cmd := m.vp.Update(msg)
516
516
+
m.vp = &vp
517
517
+
return m, cmd
518
518
+
case Command:
519
519
+
prompt, cmd := m.prompt.Update(msg)
520
520
+
m.prompt = prompt
521
521
+
return m, cmd
522
522
+
case Insert:
523
523
+
draft, cmd := m.draft.Update(msg)
524
524
+
if m.sentmsg == nil && draft.Value() != "" {
525
525
+
nv := draft.Value()
526
526
+
m.sentmsg = &nv
527
527
+
m.draft = &draft
528
528
+
return m, tea.Batch(cmd, sendInsert(m.lrcconn, nv, 0, true))
529
529
+
}
530
530
+
if m.sentmsg != nil && *m.sentmsg != draft.Value() {
531
531
+
draftutf16 := utf16.Encode([]rune(draft.Value()))
532
532
+
sentutf16 := utf16.Encode([]rune(*m.sentmsg))
533
533
+
edits := Diff(sentutf16, draftutf16)
534
534
+
m.draft = &draft
535
535
+
sentmsg := draft.Value()
536
536
+
m.sentmsg = &sentmsg
537
537
+
return m, tea.Batch(cmd, sendEditBatch(m.evtchan, edits))
538
538
+
}
539
539
+
m.draft = &draft
540
540
+
return m, cmd
541
541
+
}
542
542
+
return m, nil
543
543
+
}
314
544
545
545
+
func createMSGCmd(xrpc *PasswordClient, lmr *lex.MessageRecord) tea.Cmd {
546
546
+
return func() tea.Msg {
547
547
+
_, _, err := xrpc.CreateXCVRMessage(lmr, context.Background())
548
548
+
if err != nil {
549
549
+
return errMsg{err}
315
550
}
551
551
+
return nil
316
552
}
317
317
-
vp, cmd := m.vp.Update(msg)
318
318
-
m.vp = &vp
319
319
-
return m, cmd
553
553
+
}
554
554
+
555
555
+
func sendEditBatch(datachan chan []byte, edits []Edit) tea.Cmd {
556
556
+
return func() tea.Msg {
557
557
+
idx := 0
558
558
+
batch := make([]*lrcpb.Edit, 0)
559
559
+
for _, edit := range edits {
560
560
+
switch edit.EditType {
561
561
+
case EditDel:
562
562
+
idx2 := idx + len(edit.Utf16Text)
563
563
+
evt := makeDelete(uint32(idx), uint32(idx2))
564
564
+
edit := lrcpb.Edit{Edit: &lrcpb.Edit_Delete{Delete: evt.GetDelete()}}
565
565
+
batch = append(batch, &edit)
566
566
+
case EditKeep:
567
567
+
idx = idx + len(edit.Utf16Text)
568
568
+
case EditAdd:
569
569
+
evt := makeInsert(string(utf16.Decode(edit.Utf16Text)), uint32(idx))
570
570
+
idx = idx + len(edit.Utf16Text)
571
571
+
edit := lrcpb.Edit{Edit: &lrcpb.Edit_Insert{Insert: evt.GetInsert()}}
572
572
+
batch = append(batch, &edit)
573
573
+
}
574
574
+
}
575
575
+
evt := lrcpb.Event{Msg: &lrcpb.Event_Editbatch{Editbatch: &lrcpb.EditBatch{Edits: batch}}}
576
576
+
data, err := proto.Marshal(&evt)
577
577
+
if err != nil {
578
578
+
return errMsg{err}
579
579
+
}
580
580
+
datachan <- data
581
581
+
return nil
582
582
+
}
583
583
+
}
584
584
+
585
585
+
func sendPub(conn *websocket.Conn) tea.Cmd {
586
586
+
return func() tea.Msg {
587
587
+
evt := &lrcpb.Event{Msg: &lrcpb.Event_Pub{Pub: &lrcpb.Pub{}}}
588
588
+
data, err := proto.Marshal(evt)
589
589
+
if err != nil {
590
590
+
return errMsg{err}
591
591
+
}
592
592
+
err = conn.WriteMessage(websocket.BinaryMessage, data)
593
593
+
if err != nil {
594
594
+
return errMsg{err}
595
595
+
}
596
596
+
return nil
597
597
+
}
598
598
+
}
599
599
+
600
600
+
func makeDelete(start uint32, end uint32) *lrcpb.Event {
601
601
+
evt := &lrcpb.Event{Msg: &lrcpb.Event_Delete{Delete: &lrcpb.Delete{Utf16Start: start, Utf16End: end}}}
602
602
+
return evt
603
603
+
}
604
604
+
605
605
+
func makeInsert(body string, idx uint32) *lrcpb.Event {
606
606
+
evt := &lrcpb.Event{Msg: &lrcpb.Event_Insert{Insert: &lrcpb.Insert{Body: body, Utf16Index: idx}}}
607
607
+
return evt
608
608
+
}
609
609
+
610
610
+
func sendInsert(conn *websocket.Conn, body string, utf16idx uint32, init bool) tea.Cmd {
611
611
+
return func() tea.Msg {
612
612
+
if init {
613
613
+
evt := &lrcpb.Event{Msg: &lrcpb.Event_Init{Init: &lrcpb.Init{}}}
614
614
+
data, err := proto.Marshal(evt)
615
615
+
if err != nil {
616
616
+
return errMsg{err}
617
617
+
}
618
618
+
if conn == nil {
619
619
+
return nil
620
620
+
}
621
621
+
err = conn.WriteMessage(websocket.BinaryMessage, data)
622
622
+
if err != nil {
623
623
+
return errMsg{err}
624
624
+
}
625
625
+
}
626
626
+
evt := &lrcpb.Event{Msg: &lrcpb.Event_Insert{Insert: &lrcpb.Insert{Body: body, Utf16Index: utf16idx}}}
627
627
+
data, err := proto.Marshal(evt)
628
628
+
if err != nil {
629
629
+
return errMsg{err}
630
630
+
}
631
631
+
err = conn.WriteMessage(websocket.BinaryMessage, data)
632
632
+
if err != nil {
633
633
+
return errMsg{err}
634
634
+
}
635
635
+
return nil
636
636
+
}
637
637
+
}
638
638
+
639
639
+
func evaluateCommand(command string) tea.Cmd {
640
640
+
return func() tea.Msg {
641
641
+
parts := strings.Split(command, " ")
642
642
+
if parts == nil {
643
643
+
return nil
644
644
+
}
645
645
+
switch parts[0] {
646
646
+
case "q":
647
647
+
return tea.QuitMsg{}
648
648
+
case "se", "set":
649
649
+
if len(parts) != 1 {
650
650
+
return setMsg{parts[1]}
651
651
+
}
652
652
+
case "resize":
653
653
+
return tea.WindowSize()
654
654
+
case "login":
655
655
+
if len(parts) != 1 {
656
656
+
return loginMsg{parts[1:]}
657
657
+
}
658
658
+
}
659
659
+
return nil
660
660
+
}
661
661
+
}
662
662
+
663
663
+
type loginMsg struct {
664
664
+
value []string
665
665
+
}
666
666
+
667
667
+
type setMsg struct {
668
668
+
value string
320
669
}
321
670
322
671
// i think that the type of renders is a bit awkward, but i want deletemessage + friends to just modify the rendered
···
372
721
result = append(result, baseUTF16Units[end:]...)
373
722
resultRunes := utf16.Decode(result)
374
723
return string(resultRunes)
724
724
+
}
725
725
+
726
726
+
func editMessage(id uint32, edits []*lrcpb.Edit, msgmap map[uint32]*Message, renders *[]*string, width int) error {
727
727
+
for _, edit := range edits {
728
728
+
switch e := edit.Edit.(type) {
729
729
+
case *lrcpb.Edit_Insert:
730
730
+
ins := e.Insert
731
731
+
ins.Id = &id
732
732
+
err := insertMessage(ins, msgmap, renders, width)
733
733
+
if err != nil {
734
734
+
return err
735
735
+
}
736
736
+
case *lrcpb.Edit_Delete:
737
737
+
del := e.Delete
738
738
+
del.Id = &id
739
739
+
err := deleteMessage(del, msgmap, renders, width)
740
740
+
if err != nil {
741
741
+
return err
742
742
+
}
743
743
+
}
744
744
+
}
745
745
+
return nil
375
746
}
376
747
377
748
func insertMessage(msg *lrcpb.Insert, msgmap map[uint32]*Message, renders *[]*string, width int) error {
···
474
845
return
475
846
}
476
847
stylem := lipgloss.NewStyle().Width(width).Align(lipgloss.Left)
477
477
-
styleh := stylem.Foreground(Green)
848
848
+
styleh := stylem.Foreground(ColorFromInt(m.color))
478
849
if m.active {
479
850
styleh = styleh.Reverse(true)
480
851
stylem = styleh
481
852
}
482
482
-
var nick string
483
483
-
if m.nick != nil {
484
484
-
nick = *m.nick
485
485
-
}
486
486
-
var handle string
487
487
-
if m.handle != nil && *m.handle != "" {
488
488
-
handle = fmt.Sprintf("@%s", *m.handle)
489
489
-
}
490
490
-
header := styleh.Render(fmt.Sprintf("%s%s", nick, handle))
853
853
+
header := styleh.Render(renderName(m.nick, m.handle))
491
854
body := stylem.Render(m.text)
492
855
*m.rendered = fmt.Sprintf("%s\n%s\n", header, body)
493
856
}
···
498
861
m.state = Connected
499
862
m.cancel = msg.cancel
500
863
m.msgs = make(map[uint32]*Message)
501
501
-
vp := viewport.New(m.width, m.height-1)
864
864
+
vp := viewport.New(m.width, m.height-2)
502
865
m.vp = &vp
503
503
-
go startLRCHandlers(msg.conn)
866
866
+
draft := textinput.New()
867
867
+
draft.Prompt = renderName(m.nick, m.handle) + " "
868
868
+
draft.PromptStyle = lipgloss.NewStyle().Foreground(ColorFromInt(m.color))
869
869
+
draft.Placeholder = "press i to start typing"
870
870
+
draft.Width = m.width
871
871
+
m.draft = &draft
872
872
+
go startLRCHandlers(msg.conn, msg.lexconn, m.nick, m.handle, m.color)
873
873
+
m.lrcconn = msg.conn
874
874
+
m.lexconn = msg.lexconn
875
875
+
m.evtchan = make(chan []byte)
876
876
+
go LRCWriter(m.lrcconn, m.evtchan)
504
877
return m, nil
505
878
}
506
879
return m, nil
507
880
}
508
881
509
509
-
func startLRCHandlers(conn *websocket.Conn) {
882
882
+
func LRCWriter(conn *websocket.Conn, datachan chan []byte) {
883
883
+
for data := range datachan {
884
884
+
err := conn.WriteMessage(websocket.BinaryMessage, data)
885
885
+
if err != nil {
886
886
+
send(errMsg{err})
887
887
+
return
888
888
+
}
889
889
+
}
890
890
+
}
891
891
+
892
892
+
func renderName(nick *string, handle *string) string {
893
893
+
var n string
894
894
+
if nick != nil {
895
895
+
n = *nick
896
896
+
}
897
897
+
var h string
898
898
+
if handle != nil {
899
899
+
h = fmt.Sprintf("@%s", *handle)
900
900
+
}
901
901
+
return fmt.Sprintf("%s%s", n, h)
902
902
+
}
903
903
+
904
904
+
func sendSet(datachan chan []byte, nick *string, handle *string, color *uint32) error {
905
905
+
evt := &lrcpb.Event{Msg: &lrcpb.Event_Set{Set: &lrcpb.Set{Nick: nick, ExternalID: handle, Color: color}}}
906
906
+
data, err := proto.Marshal(evt)
907
907
+
if err != nil {
908
908
+
return err
909
909
+
}
910
910
+
datachan <- data
911
911
+
return nil
912
912
+
913
913
+
}
914
914
+
915
915
+
func startLRCHandlers(conn *websocket.Conn, lexconn *websocket.Conn, nick *string, handle *string, color *uint32) {
510
916
if conn == nil {
511
917
send(errMsg{errors.New("provided nil conn")})
512
918
return
513
919
}
514
514
-
nick := "wanderer"
515
515
-
evt := &lrcpb.Event{Msg: &lrcpb.Event_Set{Set: &lrcpb.Set{Nick: &nick}}}
920
920
+
evt := &lrcpb.Event{Msg: &lrcpb.Event_Set{Set: &lrcpb.Set{Nick: nick, ExternalID: handle, Color: color}}}
516
921
data, err := proto.Marshal(evt)
517
922
if err != nil {
518
923
send(errMsg{errors.New("failed to marshal: " + err.Error())})
519
924
return
520
925
}
926
926
+
conn.WriteMessage(websocket.BinaryMessage, data)
521
927
522
522
-
evt = &lrcpb.Event{Msg: &lrcpb.Event_Get{Get: &lrcpb.Get{Topic: &nick}}}
928
928
+
bep := "bep"
929
929
+
evt = &lrcpb.Event{Msg: &lrcpb.Event_Get{Get: &lrcpb.Get{Topic: &bep}}}
523
930
data, err = proto.Marshal(evt)
524
931
if err != nil {
525
932
send(errMsg{errors.New("failed to marshal: " + err.Error())})
···
527
934
}
528
935
conn.WriteMessage(websocket.BinaryMessage, data)
529
936
go listenToConn(conn)
937
937
+
go listenToLexConn(lexconn)
938
938
+
}
939
939
+
940
940
+
type typedJSON struct {
941
941
+
Type string `json:"$type"`
942
942
+
}
943
943
+
944
944
+
func listenToLexConn(conn *websocket.Conn) {
945
945
+
for {
946
946
+
var rawMsg json.RawMessage
947
947
+
err := conn.ReadJSON(&rawMsg)
948
948
+
if err != nil {
949
949
+
send(errMsg{err})
950
950
+
return
951
951
+
}
952
952
+
var typed typedJSON
953
953
+
err = json.Unmarshal(rawMsg, &typed)
954
954
+
if err != nil {
955
955
+
send(errMsg{err})
956
956
+
return
957
957
+
}
958
958
+
switch typed.Type {
959
959
+
case "org.xcvr.lrc.defs#signetView":
960
960
+
var sv SignetView
961
961
+
err = json.Unmarshal(rawMsg, &sv)
962
962
+
if err != nil {
963
963
+
send(errMsg{err})
964
964
+
return
965
965
+
}
966
966
+
send(svMsg{&sv})
967
967
+
}
968
968
+
}
969
969
+
}
970
970
+
971
971
+
type svMsg struct {
972
972
+
signetView *SignetView
973
973
+
}
974
974
+
975
975
+
type SignetView struct {
976
976
+
Type string `json:"$type,const=org.xcvr.lrc.defs#signetView"`
977
977
+
URI string `json:"uri"`
978
978
+
IssuerHandle string `json:"issuerHandle"`
979
979
+
ChannelURI string `json:"channelURI"`
980
980
+
LrcId uint32 `json:"lrcID"`
981
981
+
AuthorHandle string `json:"authorHandle"`
982
982
+
StartedAt time.Time `json:"startedAt"`
530
983
}
531
984
532
985
func listenToConn(conn *websocket.Conn) {
···
568
1021
if err != nil {
569
1022
return errMsg{err}
570
1023
}
571
571
-
return connMsg{conn, cancel}
1024
1024
+
1025
1025
+
dialer = websocket.DefaultDialer
1026
1026
+
lexconn, _, err := dialer.DialContext(ctx, fmt.Sprintf("wss://xcvr.org/xrpc/org.xcvr.lrc.subscribeLexStream?uri=%s", m.curchannel.URI), http.Header{})
1027
1027
+
if err != nil {
1028
1028
+
return errMsg{err}
1029
1029
+
}
1030
1030
+
return connMsg{conn, lexconn, cancel}
572
1031
}
573
1032
}
574
1033
575
1034
type connMsg struct {
576
576
-
conn *websocket.Conn
577
577
-
cancel func()
1035
1035
+
conn *websocket.Conn
1036
1036
+
lexconn *websocket.Conn
1037
1037
+
cancel func()
578
1038
}
579
1039
580
1040
const (
···
707
1167
}
708
1168
remainingspace := m.width - len(address) - len(topic)
709
1169
var footertext string
710
710
-
if remainingspace < 1 {
711
711
-
footertext = address
1170
1170
+
if m.mode == Command {
1171
1171
+
footertext = m.prompt.View()
1172
1172
+
} else if remainingspace < 1 {
1173
1173
+
footertext = fmt.Sprintf("%s%s", address, strings.Repeat(" ", m.width-len(address)))
712
1174
} else {
713
1175
footertext = fmt.Sprintf("%s%s%s", address, strings.Repeat(" ", remainingspace), topic)
714
1176
}
715
1177
insert := m.mode == Insert
716
716
-
footerstyle := lipgloss.NewStyle().Foreground(Green).Reverse(insert)
1178
1178
+
footerstyle := lipgloss.NewStyle().Reverse(insert)
1179
1179
+
if m.mode != Command {
1180
1180
+
footerstyle = footerstyle.Foreground(ColorFromInt(m.color))
1181
1181
+
}
717
1182
footer := footerstyle.Render(footertext)
718
718
-
return fmt.Sprintf("%s\n%s", vpt, footer)
1183
1183
+
var draftText string
1184
1184
+
if m.draft != nil {
1185
1185
+
draftText = m.draft.View()
1186
1186
+
}
1187
1187
+
return fmt.Sprintf("%s\n%s\n%s", vpt, draftText, footer)
719
1188
}
1189
1189
+
720
1190
func (m model) connectingView() string {
721
1191
blip := m.wsurl
722
1192
if blip == nil {
···
731
1201
732
1202
func (m model) splashView() string {
733
1203
style := lipgloss.NewStyle().Foreground(Green)
734
734
-
part1 := "\n %%%%%%% "
1204
1204
+
part00 := "\n ⣰⡀ ⢀⣀ ⡇ ⡇⡠ ⣰⡀ ⢀⡀ ⡀⢀ ⢀⡀ ⡀⢀ ⡇"
1205
1205
+
part01 := "\n ⠘⠤ ⠣⠼ ⠣ ⠏⠢ ⠘⠤ ⠣⠜ ⣑⡺ ⠣⠜ ⠣⠼ ⠅"
1206
1206
+
part02 := "\n ⣰⡀ ⡀⣀ ⢀⣀ ⣀⡀ ⢀⣀ ⢀⣀ ⢀⡀ ⠄ ⡀⢀ ⢀⡀ ⡀⣀"
1207
1207
+
part03 := "\n ⠘⠤ ⠏ ⠣⠼ ⠇⠸ ⠭⠕ ⠣⠤ ⠣⠭ ⠇ ⠱⠃ ⠣⠭ ⠏"
1208
1208
+
part1 := "\n\n %%%%%%% "
735
1209
text1 := "tty!xcvr\n"
736
1210
part2 := ` %%%%%%%%%% %%% % % %%%%%%%%
737
1211
%%%%%%%%%%%%%%%%% %%%% %%%%%%%%%%%%%%%%%%
···
753
1227
press a key
754
1228
to start!
755
1229
`
756
756
-
s := fmt.Sprintf("%s%s%s%s%s%s%s%s%s", style.Render(part1), text1, style.Render(part2), style.Render(part25), text2, style.Render(part3), text3, style.Render(part4), text4)
757
757
-
758
758
-
return s
1230
1230
+
s := fmt.Sprintf("\n\n\n\n%s%s%s%s%s%s%s%s%s%s%s%s%s", style.Render(part00), style.Render(part01), style.Render(part02), style.Render(part03), style.Render(part1), text1, style.Render(part2), style.Render(part25), text2, style.Render(part3), text3, style.Render(part4), text4)
1231
1231
+
offset := lipgloss.NewStyle().MarginLeft((m.width - 58) / 2)
1232
1232
+
return offset.Render(s)
759
1233
}
760
1234
761
1235
var send func(msg tea.Msg)
···
899
1373
}
900
1374
return b.String()
901
1375
}
1376
1376
+
1377
1377
+
type PasswordClient struct {
1378
1378
+
xrpc *client.APIClient
1379
1379
+
accessjwt *string
1380
1380
+
refreshjwt *string
1381
1381
+
did *string
1382
1382
+
}
1383
1383
+
1384
1384
+
func NewPasswordClient(did string, host string) *PasswordClient {
1385
1385
+
return &PasswordClient{
1386
1386
+
xrpc: client.NewAPIClient(host),
1387
1387
+
did: &did,
1388
1388
+
}
1389
1389
+
}
1390
1390
+
1391
1391
+
func (c *PasswordClient) CreateSession(ctx context.Context, identity string, secret string) error {
1392
1392
+
input := atproto.ServerCreateSession_Input{
1393
1393
+
Identifier: identity,
1394
1394
+
Password: secret,
1395
1395
+
}
1396
1396
+
var out atproto.ServerCreateSession_Output
1397
1397
+
err := c.xrpc.LexDo(ctx, "POST", "application/json", "com.atproto.server.createSession", nil, input, &out)
1398
1398
+
if err != nil {
1399
1399
+
return errors.New("I couldn't create a session: " + err.Error())
1400
1400
+
}
1401
1401
+
c.accessjwt = &out.AccessJwt
1402
1402
+
c.refreshjwt = &out.RefreshJwt
1403
1403
+
return nil
1404
1404
+
}
1405
1405
+
1406
1406
+
func (c *PasswordClient) RefreshSession(ctx context.Context) error {
1407
1407
+
c.xrpc.Headers.Set("Authorization", fmt.Sprintf("Bearer %s", *c.refreshjwt))
1408
1408
+
var out atproto.ServerRefreshSession_Output
1409
1409
+
err := c.xrpc.LexDo(ctx, "POST", "application/json", "com.atproto.server.refreshSession", nil, nil, &out)
1410
1410
+
if err != nil {
1411
1411
+
return errors.New("failed to refresh session! " + err.Error())
1412
1412
+
}
1413
1413
+
c.accessjwt = &out.AccessJwt
1414
1414
+
c.refreshjwt = &out.RefreshJwt
1415
1415
+
return nil
1416
1416
+
}
1417
1417
+
1418
1418
+
func (c *PasswordClient) CreateXCVRMessage(message *lex.MessageRecord, ctx context.Context) (cid string, uri string, err error) {
1419
1419
+
input := atproto.RepoCreateRecord_Input{
1420
1420
+
Collection: "org.xcvr.lrc.message",
1421
1421
+
Repo: *c.did,
1422
1422
+
Record: &util.LexiconTypeDecoder{Val: message},
1423
1423
+
}
1424
1424
+
return c.createMyRecord(input, ctx)
1425
1425
+
}
1426
1426
+
1427
1427
+
func (c *PasswordClient) createMyRecord(input atproto.RepoCreateRecord_Input, ctx context.Context) (cid string, uri string, err error) {
1428
1428
+
if c.accessjwt == nil {
1429
1429
+
err = errors.New("must create a session first")
1430
1430
+
return
1431
1431
+
}
1432
1432
+
c.xrpc.Headers.Set("Authorization", fmt.Sprintf("Bearer %s", *c.accessjwt))
1433
1433
+
var out atproto.RepoCreateRecord_Output
1434
1434
+
err = c.xrpc.LexDo(ctx, "POST", "application/json", "com.atproto.repo.createRecord", nil, input, &out)
1435
1435
+
if err != nil {
1436
1436
+
err1 := err.Error()
1437
1437
+
err = c.RefreshSession(ctx)
1438
1438
+
if err != nil {
1439
1439
+
err = errors.New(fmt.Sprintf("failed to refresh session while creating %s! first %s then %s", input.Collection, err1, err.Error()))
1440
1440
+
return
1441
1441
+
}
1442
1442
+
c.xrpc.Headers.Set("Authorization", fmt.Sprintf("Bearer %s", *c.accessjwt))
1443
1443
+
out = atproto.RepoCreateRecord_Output{}
1444
1444
+
err = c.xrpc.LexDo(ctx, "POST", "application/json", "com.atproto.repo.createRecord", nil, input, &out)
1445
1445
+
if err != nil {
1446
1446
+
err = errors.New(fmt.Sprintf("not good, failed to create %s after failing then refreshing session! first %s then %s", input.Collection, err1, err.Error()))
1447
1447
+
return
1448
1448
+
}
1449
1449
+
cid = out.Cid
1450
1450
+
uri = out.Uri
1451
1451
+
return
1452
1452
+
}
1453
1453
+
cid = out.Cid
1454
1454
+
uri = out.Uri
1455
1455
+
return
1456
1456
+
}
1457
1457
+
1458
1458
+
func ColorFromInt(c *uint32) lipgloss.Color {
1459
1459
+
if c == nil {
1460
1460
+
return Green
1461
1461
+
}
1462
1462
+
ui := *c
1463
1463
+
guess := fmt.Sprintf("#%06x", ui)
1464
1464
+
return lipgloss.Color(guess[0:7])
1465
1465
+
}