stream.place chat terminal ui

in multistream chats, mentions which chat record is from

Changed files
+56 -22
+2 -1
README.md
··· 7 7 did:plc:25z6ogppprfvijcnqo2fsfce` 8 8 9 9 if you want to see the union of alice and bob's chats, and their dids are 10 - `did:plc:12345` and `did:plc:abcde`, then do `go run . did:plc:12345 did:plc:abcde` 10 + `did:plc:12345` and `did:plc:abcde`, then do `go run . did:plc:12345 11 + did:plc:abcde` 11 12 12 13 pretty simple! 13 14
+54 -21
beeper.go
··· 32 32 } 33 33 34 34 var ( 35 - hasArgs bool 35 + hasArgs bool 36 + didToHandle map[syntax.DID]*syntax.Handle 37 + noNeedForFrom bool 36 38 ) 37 39 38 40 func main() { 39 41 fmt.Println("beep") 40 42 if len(os.Args) != 1 { 41 43 hasArgs = true 44 + } 45 + if len(os.Args) == 2 { 46 + noNeedForFrom = true 42 47 } 43 48 f, err := os.Open("thread_notification.wav") 44 49 if err != nil { ··· 64 69 np, 65 70 tp, 66 71 } 72 + didToHandle = make(map[syntax.DID]*syntax.Handle) 67 73 go consumeLoop(context.Background(), ns) 68 74 ns.tp.Run() 69 75 } ··· 138 144 139 145 func (h *handler) HandleEvent(ctx context.Context, event *models.Event) error { 140 146 if event.Commit != nil && event.Commit.Collection == "place.stream.chat.message" && event.Commit.Operation == "create" { 141 - dd := identity.DefaultDirectory() 142 - did, err := syntax.ParseDID(event.Did) 147 + handle, err := getHandle(event.Did, ctx) 143 148 if err != nil { 144 149 panic(err) 145 - } 146 - id, err := dd.LookupDID(ctx, did) 147 - if err != nil { 148 - return nil 149 150 } 150 151 var v ChatMessage 151 152 err = json.Unmarshal(event.Commit.Record, &v) ··· 161 162 } 162 163 } 163 164 if shouldSend { 164 - h.ns.Notify(v.Text, id.Handle) 165 + var streamer string 166 + if !noNeedForFrom { 167 + streamer, err = getHandle(v.Streamer, ctx) 168 + if err != nil { 169 + panic(err) 170 + } 171 + } 172 + h.ns.Notify(v.Text, handle, streamer) 165 173 } 166 174 } 167 175 return nil 168 176 } 169 177 170 - func (ns *NotificationSystem) Notify(text string, handle syntax.Handle) { 178 + func getHandle(did string, ctx context.Context) (string, error) { 179 + sdid, err := syntax.ParseDID(did) 180 + if err != nil { 181 + return "", err 182 + } 183 + h, ok := didToHandle[sdid] 184 + if ok { 185 + return h.String(), nil 186 + } 187 + dd := identity.DefaultDirectory() 188 + id, err := dd.LookupDID(ctx, sdid) 189 + if err != nil { 190 + return "failed.to.lookup", nil 191 + } 192 + didToHandle[sdid] = &id.Handle 193 + return id.Handle.String(), nil 194 + } 171 195 172 - streamer := ns.np.audioData.Streamer(0, ns.np.audioData.Len()) 173 - speaker.Play(streamer) 174 - h := handle.String() 175 - ns.tp.Send(ChatMsg{text: &text, handle: &h}) 196 + func (ns *NotificationSystem) Notify(text string, handle string, streamer string) { 197 + 198 + noise := ns.np.audioData.Streamer(0, ns.np.audioData.Len()) 199 + speaker.Play(noise) 200 + ns.tp.Send(ChatMsg{text: &text, handle: &handle, streamer: &streamer}) 176 201 } 177 202 178 203 type model struct { ··· 182 207 } 183 208 184 209 type record struct { 185 - handle *string 186 - text *string 210 + handle *string 211 + text *string 212 + streamer *string 187 213 } 188 214 189 215 func initialModel() model { ··· 200 226 //15191e 201 227 202 228 type ChatMsg struct { 203 - handle *string 204 - text *string 229 + handle *string 230 + text *string 231 + streamer *string 205 232 } 206 233 207 234 func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { ··· 216 243 m.height = msg.Height 217 244 case ChatMsg: 218 245 record := record{ 219 - text: msg.text, 220 - handle: msg.handle, 246 + text: msg.text, 247 + handle: msg.handle, 248 + streamer: msg.streamer, 221 249 } 222 250 m.records = append(m.records, &record) 223 251 } ··· 229 257 for _, record := range m.records { 230 258 str := "invalid handle" 231 259 if record.handle != nil { 232 - str = fmt.Sprintf("%s ", *record.handle) 260 + str = fmt.Sprintf("%s", *record.handle) 233 261 } 234 262 bold := lipgloss.NewStyle().Bold(true).Foreground(lipgloss.Color(hashStringToColor(str))) 235 263 bdy := "" 236 264 if record.text != nil { 237 265 bdy = fmt.Sprintf("%s", *record.text) 238 266 } 267 + middleText := "\n" 268 + if !noNeedForFrom { 269 + boldStrmr := lipgloss.NewStyle().Bold(true).Foreground(lipgloss.Color(hashStringToColor(*record.streamer))) 270 + middleText = fmt.Sprintf(" in %s's chat\n", boldStrmr.Render(*record.streamer)) 271 + } 239 272 style := lipgloss.NewStyle().Width(m.width) 240 - s = s + "\n" + bold.Render(str) + "\n" + style.Render(bdy) + "\n" 273 + s = s + "\n" + bold.Render(str) + middleText + style.Render(bdy) + "\n" 241 274 } 242 275 return s 243 276 }