Fix 3 bugs in DMs

- escape HTML entities in messages so "<" doesn't scrape as "&lt;"
- escape quotes in sent messages, so they no longer fail to send
- fix the web UI receiving the last 50 messages after every sent message instead of just the new ones
This commit is contained in:
Alessio 2024-05-05 10:58:39 -07:00
parent f7ad9ba63c
commit 71230e3886
3 changed files with 33 additions and 2 deletions

View File

@ -39,16 +39,22 @@ func (app *Application) message_detail(w http.ResponseWriter, r *http.Request) {
panic_if(err) panic_if(err)
var message_data struct { var message_data struct {
Text string `json:"text"` Text string `json:"text"`
LatestPollingTimestamp int `json:"latest_polling_timestamp,string"`
} }
panic_if(json.Unmarshal(body, &message_data)) panic_if(json.Unmarshal(body, &message_data))
trove := scraper.SendDMMessage(room_id, message_data.Text, 0) trove := scraper.SendDMMessage(room_id, message_data.Text, 0)
app.Profile.SaveDMTrove(trove, false) app.Profile.SaveDMTrove(trove, false)
app.buffered_render_htmx(w, "dm-composer", global_data, chat_view_data) // Wipe the chat box app.buffered_render_htmx(w, "dm-composer", global_data, chat_view_data) // Wipe the chat box
go app.Profile.SaveDMTrove(trove, true) go app.Profile.SaveDMTrove(trove, true)
chat_view_data.LatestPollingTimestamp = message_data.LatestPollingTimestamp // We're going to return some messages
} else {
chat_view_data.LatestPollingTimestamp = -1 // TODO: why not 0? If `0` then it won't generate a SQL `where` clause
} }
// TODO: Why are the input (parsed out of the HTTP request) and output (computed from the messsages
// fetched and printed into the HTTP response) using the same variable in `chat_view_data`?
chat_view_data.ActiveRoomID = room_id chat_view_data.ActiveRoomID = room_id
chat_view_data.LatestPollingTimestamp = -1 // TODO: why not 0? If `0` then it won't generate a SQL `where` clause
if latest_timestamp_str := r.URL.Query().Get("latest_timestamp"); latest_timestamp_str != "" { if latest_timestamp_str := r.URL.Query().Get("latest_timestamp"); latest_timestamp_str != "" {
var err error var err error
chat_view_data.LatestPollingTimestamp, err = strconv.Atoi(latest_timestamp_str) chat_view_data.LatestPollingTimestamp, err = strconv.Atoi(latest_timestamp_str)
@ -78,6 +84,9 @@ func (app *Application) message_detail(w http.ResponseWriter, r *http.Request) {
// Polling for updates and sending a message should add messages at the bottom of the page (newest) // Polling for updates and sending a message should add messages at the bottom of the page (newest)
if r.URL.Query().Has("poll") || is_sending { if r.URL.Query().Has("poll") || is_sending {
app.buffered_render_htmx(w, "messages-with-poller", global_data, chat_view_data) app.buffered_render_htmx(w, "messages-with-poller", global_data, chat_view_data)
// OOB-swap the composer polling timestamp field since it may have updated
app.buffered_render_htmx(w, "composer-polling-timestamp-field", global_data, map[string]interface{}{"LatestPollingTimestamp": chat_view_data.LatestPollingTimestamp, "oob": true})
return return
} }

View File

@ -93,6 +93,18 @@
></div> ></div>
{{end}} {{end}}
{{define "composer-polling-timestamp-field"}}
<input id="composerPollingTimestamp"
type="hidden"
name="latest_polling_timestamp"
value="{{.LatestPollingTimestamp}}"
{{if .oob}}
{{/* See comment about `oob` in the "dm-composer" template. Here we pass a parameter to say oob or not */}}
hx-swap-oob="true"
{{end}}
>
{{end}}
{{define "chat-view"}} {{define "chat-view"}}
<div id="chat-view"> <div id="chat-view">
{{if .ActiveRoomID}} {{if .ActiveRoomID}}
@ -128,6 +140,7 @@
> >
{{template "dm-composer"}} {{template "dm-composer"}}
<input id="realInput" type="hidden" name="text" value="" /> <input id="realInput" type="hidden" name="text" value="" />
{{template "composer-polling-timestamp-field" (dict "LatestPollingTimestamp" .LatestPollingTimestamp "oob" false)}}
<input type="submit" /> <input type="submit" />
</form> </form>
</div> </div>

View File

@ -4,6 +4,8 @@ import (
"fmt" "fmt"
"net/url" "net/url"
"strings" "strings"
"html"
"encoding/json"
"github.com/google/uuid" "github.com/google/uuid"
) )
@ -71,6 +73,7 @@ func (m *APIDMMessage) NormalizeContent() {
m.MessageData.Text = strings.Replace(m.MessageData.Text, m.MessageData.Attachment.Video.URL, "", 1) m.MessageData.Text = strings.Replace(m.MessageData.Text, m.MessageData.Attachment.Video.URL, "", 1)
} }
m.MessageData.Text = html.UnescapeString(m.MessageData.Text)
m.MessageData.Text = strings.TrimSpace(m.MessageData.Text) m.MessageData.Text = strings.TrimSpace(m.MessageData.Text)
} }
@ -503,9 +506,15 @@ func (api *API) SendDMMessage(room_id DMChatRoomID, text string, in_reply_to_id
replying_to_text = fmt.Sprintf(`"reply_to_dm_id":"%d",`, in_reply_to_id) replying_to_text = fmt.Sprintf(`"reply_to_dm_id":"%d",`, in_reply_to_id)
} }
// Format safely as JSON (escape quotes, etc)
sanitized_text, err := json.Marshal(text)
if err != nil {
panic(err)
}
post_data := `{"conversation_id":"` + string(room_id) + post_data := `{"conversation_id":"` + string(room_id) +
`","recipient_ids":false,"request_id":"` + request_id.String() + `","recipient_ids":false,"request_id":"` + request_id.String() +
`","text":"` + text + `",` + `","text":` + string(sanitized_text) + `,` +
replying_to_text + `"cards_platform":"Web-12","include_cards":1,"include_quote_count":true,"dm_users":false}` replying_to_text + `"cards_platform":"Web-12","include_cards":1,"include_quote_count":true,"dm_users":false}`
var result APIInbox var result APIInbox