Enable sending DM messages

This commit is contained in:
Alessio 2023-12-24 14:21:57 -06:00
parent 3ba8e3ef70
commit e1bc6bba98
5 changed files with 120 additions and 51 deletions

View File

@ -1,6 +1,8 @@
package webserver
import (
"encoding/json"
"io"
"net/http"
"strings"
@ -34,10 +36,24 @@ func (app *Application) Messages(w http.ResponseWriter, r *http.Request) {
return
}
parts := strings.Split(strings.Trim(r.URL.Path, "/"), "/")
room_id := scraper.DMChatRoomID(parts[0])
if len(parts) == 2 && parts[1] == "send" {
body, err := io.ReadAll(r.Body)
panic_if(err)
var message_data struct {
Text string `json:"text"`
}
panic_if(json.Unmarshal(body, &message_data))
trove := scraper.SendDMMessage(room_id, message_data.Text, 0)
app.Profile.SaveDMTrove(trove, false)
go app.Profile.SaveDMTrove(trove, true)
}
chat_view := app.Profile.GetChatRoomsPreview(app.ActiveUser.ID)
if strings.Trim(r.URL.Path, "/") != "" {
chat_view.ActiveRoomID = scraper.DMChatRoomID(strings.Trim(r.URL.Path, "/"))
chat_contents := app.Profile.GetChatRoomContents(chat_view.ActiveRoomID)
chat_view.ActiveRoomID = room_id
chat_contents := app.Profile.GetChatRoomContents(room_id)
chat_view.MergeWith(chat_contents.DMTrove)
chat_view.MessageIDs = chat_contents.MessageIDs
}

View File

@ -446,7 +446,6 @@ input[type="submit"] {
background-color: var(--color-twitter-blue-light);
width: 10em;
padding: 1em;
margin-top: 1em;
border-radius: 1em;
font-size: 1em;
cursor: pointer;
@ -684,9 +683,14 @@ ul.space-participants-list li {
flex-basis: 0;
flex-grow: 7;
border-left: 1px solid var(--color-outline-gray);
overflow-y: scroll;
padding: 0.5em;
box-sizing: border-box;
display: flex;
flex-direction: column;
}
.chats-container #chat-view .chat-messages {
flex-grow: 1;
overflow-y: auto;
}
.chats-container #chat-view .our-message {
align-items: flex-end;
@ -763,5 +767,24 @@ ul.space-participants-list li {
}
.dm-message-content-container .replying-to-label img.svg-icon {
width: 1em;
}
.dm-composer-container {
padding-top: 0.5em;
border-top: 1px solid var(--color-outline-gray);
/* position: absolute;
bottom: 1em;
right: 0.5em;
left: 0.5em;*/
}
.dm-composer-container form {
display: flex;
}
span.composer {
flex-grow: 1;
border: 1px solid #ccc;
font-family: inherit;
font-size: inherit;
padding: 1px 6px;
max-height: 10em;
overflow-y: auto; /* scrollbar only if needed */
}

View File

@ -8,6 +8,7 @@
<link rel='shortcut icon' href='/static/img/favicon.ico' type='image/x-icon'>
<link rel='stylesheet' href='/static/vendor/fonts.css'>
<script src="/static/vendor/htmx.min.js" integrity="sha384-zUfuhFKKZCbHTY6aRR46gxiqszMk5tcHjsVFxnUo8VMus4kHGVdIYVbOYYNlKmHV" crossorigin="anonymous"></script>
<script src="/static/vendor/htmx-extension-json-enc.js"></script>
</head>
<body>
<div class="top-bar">

View File

@ -1,56 +1,85 @@
{{define "chat-view"}}
<div id="chat-view">
{{range .MessageIDs}}
{{$message := (index $.DMTrove.Messages .)}}
{{$user := (user $message.SenderID)}}
{{$is_us := (eq $message.SenderID (active_user).ID)}}
<div class="dm-message-and-reacts-container {{if $is_us}} our-message {{end}}">
<div class="dm-message-container">
<div class="sender-profile-image-container">
<a class="unstyled-link" href="/{{$user.Handle}}">
{{if $user.IsContentDownloaded}}
<img class="profile-image" src="/content/{{$user.GetProfileImageLocalPath}}" />
{{else}}
<img class="profile-image" src="{{$user.ProfileImageUrl}}" />
<div class="chat-messages">
{{range .MessageIDs}}
{{$message := (index $.DMTrove.Messages .)}}
{{$user := (user $message.SenderID)}}
{{$is_us := (eq $message.SenderID (active_user).ID)}}
<div class="dm-message-and-reacts-container {{if $is_us}} our-message {{end}}">
<div class="dm-message-container">
<div class="sender-profile-image-container">
<a class="unstyled-link" href="/{{$user.Handle}}">
{{if $user.IsContentDownloaded}}
<img class="profile-image" src="/content/{{$user.GetProfileImageLocalPath}}" />
{{else}}
<img class="profile-image" src="{{$user.ProfileImageUrl}}" />
{{end}}
</a>
</div>
<div class="dm-message-content-container">
{{if (ne $message.InReplyToID 0)}}
<div class="replying-to-container">
<div class="replying-to-label row">
<img class="svg-icon" src="/static/icons/replying_to.svg" />
<span>Replying to</span>
</div>
<div class="replying-to-message">
{{(index $.DMTrove.Messages $message.InReplyToID).Text}}
</div>
</div>
{{end}}
</a>
</div>
<div class="dm-message-content-container">
{{if (ne $message.InReplyToID 0)}}
<div class="replying-to-container">
<div class="replying-to-label row">
<img class="svg-icon" src="/static/icons/replying_to.svg" />
<span>Replying to</span>
</div>
<div class="replying-to-message">
{{(index $.DMTrove.Messages $message.InReplyToID).Text}}
{{if (ne $message.EmbeddedTweetID 0)}}
<div class="tweet-preview">
{{template "tweet" (dict
"TweetID" $message.EmbeddedTweetID
"RetweetID" 0
"QuoteNestingLevel" 1)
}}
</div>
{{end}}
<div class="dm-message-text-container">
{{template "text-with-entities" $message.Text}}
</div>
{{end}}
{{if (ne $message.EmbeddedTweetID 0)}}
<div class="tweet-preview">
{{template "tweet" (dict
"TweetID" $message.EmbeddedTweetID
"RetweetID" 0
"QuoteNestingLevel" 1)
}}
</div>
{{end}}
<div class="dm-message-text-container">
{{template "text-with-entities" $message.Text}}
</div>
</div>
<div class="dm-message-reactions">
{{range $message.Reactions}}
{{$sender := (user .SenderID)}}
<span title="{{$sender.DisplayName}} (@{{$sender.Handle}})">{{.Emoji}}</span>
{{end}}
</div>
<p class="posted-at">
{{$message.SentAt.Time.Format "Jan 2, 2006 @ 3:04 pm"}}
</p>
</div>
<div class="dm-message-reactions">
{{range $message.Reactions}}
{{$sender := (user .SenderID)}}
<span title="{{$sender.DisplayName}} (@{{$sender.Handle}})">{{.Emoji}}</span>
{{end}}
</div>
<p class="posted-at">
{{$message.SentAt.Time.Format "Jan 2, 2006 @ 3:04 pm"}}
</p>
{{end}}
</div>
{{if $.ActiveRoomID}}
<div class="dm-composer-container">
<form hx-post="/messages/{{$.ActiveRoomID}}/send" hx-target="body" hx-ext="json-enc">
<span
class="composer"
role="textbox"
contenteditable
oninput="var text = this.innerText; document.querySelector('#real-input').value = text"
>
</span>
<input id="real-input" type="hidden" name="text" value="" />
<input type="submit" />
</form>
</div>
<script>
// Make pasting text work for HTML as well as plain text
var editor = document.querySelector("span.composer");
editor.addEventListener("paste", function(e) {
// cancel paste
e.preventDefault();
// get text representation of clipboard
var text = (e.originalEvent || e).clipboardData.getData('text/plain');
// insert text manually
document.execCommand("insertHTML", false, text);
});
</script>
{{end}}
</div>
{{end}}

View File

@ -484,7 +484,7 @@ func (api *API) SendDMMessage(room_id DMChatRoomID, text string, in_reply_to_id
`","text":"` + text + `",` +
replying_to_text + `"cards_platform":"Web-12","include_cards":1,"include_quote_count":true,"dm_users":false}`
var result APIDMResponse
var result APIInbox
err = api.do_http_POST(url.String(), post_data, &result)
return result.UserEvents, err
return result, err
}