Make scrolling a lot better in DMs
This commit is contained in:
parent
06dcea0565
commit
b146cd9bb5
@ -14,6 +14,7 @@ import (
|
|||||||
type MessageData struct {
|
type MessageData struct {
|
||||||
persistence.DMChatView
|
persistence.DMChatView
|
||||||
LatestPollingTimestamp int
|
LatestPollingTimestamp int
|
||||||
|
ScrollBottom bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *Application) Messages(w http.ResponseWriter, r *http.Request) {
|
func (app *Application) Messages(w http.ResponseWriter, r *http.Request) {
|
||||||
@ -28,7 +29,7 @@ func (app *Application) Messages(w http.ResponseWriter, r *http.Request) {
|
|||||||
room_id := scraper.DMChatRoomID(parts[0])
|
room_id := scraper.DMChatRoomID(parts[0])
|
||||||
|
|
||||||
if r.URL.Query().Has("poll") {
|
if r.URL.Query().Has("poll") {
|
||||||
// TODO: where is this going to be used?
|
// Not run as a goroutine; this call blocks. It's not actually "background"
|
||||||
app.background_dm_polling_scrape()
|
app.background_dm_polling_scrape()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,6 +58,9 @@ func (app *Application) Messages(w http.ResponseWriter, r *http.Request) {
|
|||||||
chat_view_data.LatestPollingTimestamp, err = strconv.Atoi(latest_timestamp_str)
|
chat_view_data.LatestPollingTimestamp, err = strconv.Atoi(latest_timestamp_str)
|
||||||
panic_if(err)
|
panic_if(err)
|
||||||
}
|
}
|
||||||
|
if r.URL.Query().Get("scroll_bottom") != "0" {
|
||||||
|
chat_view_data.ScrollBottom = true
|
||||||
|
}
|
||||||
chat_contents := app.Profile.GetChatRoomContents(room_id, chat_view_data.LatestPollingTimestamp)
|
chat_contents := app.Profile.GetChatRoomContents(room_id, chat_view_data.LatestPollingTimestamp)
|
||||||
chat_view_data.MergeWith(chat_contents.DMTrove)
|
chat_view_data.MergeWith(chat_contents.DMTrove)
|
||||||
chat_view_data.MessageIDs = chat_contents.MessageIDs
|
chat_view_data.MessageIDs = chat_contents.MessageIDs
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{{define "title"}}Followed Users{{end}}
|
{{define "title"}}Messages{{end}}
|
||||||
|
|
||||||
{{define "main"}}
|
{{define "main"}}
|
||||||
<div class="chats-container">
|
<div class="chats-container">
|
||||||
|
@ -3,5 +3,12 @@
|
|||||||
{{range .RoomIDs}}
|
{{range .RoomIDs}}
|
||||||
{{template "chat-list-entry" (dict "room" (index $.Rooms .) "messages" $.DMTrove.Messages "is_active" (eq $.ActiveRoomID .))}}
|
{{template "chat-list-entry" (dict "room" (index $.Rooms .) "messages" $.DMTrove.Messages "is_active" (eq $.ActiveRoomID .))}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
|
{{/* Scroll the active chat into view, if there is one */}}
|
||||||
|
{{if $.ActiveRoomID}}
|
||||||
|
<script>
|
||||||
|
document.querySelector(".chat.active-chat").scrollIntoViewIfNeeded(true)
|
||||||
|
</script>
|
||||||
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
@ -53,9 +53,9 @@
|
|||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
<div id="new-messages-poller"
|
<div id="new-messages-poller"
|
||||||
hx-swap="outerHTML scroll:.chat-messages:bottom"
|
hx-swap="outerHTML {{if $.ScrollBottom}}scroll:.chat-messages:bottom{{end}}"
|
||||||
hx-trigger="load delay:3s"
|
hx-trigger="load delay:3s"
|
||||||
hx-get="/messages/{{$.ActiveRoomID}}?poll&latest_timestamp={{$.LatestPollingTimestamp}}"
|
hx-get="/messages/{{$.ActiveRoomID}}?poll&latest_timestamp={{$.LatestPollingTimestamp}}&scroll_bottom={{if $.ScrollBottom}}1{{else}}0{{end}}"
|
||||||
></div>
|
></div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
@ -88,6 +88,43 @@
|
|||||||
</script>
|
</script>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
(function () { // Wrap it all in an IIFE to avoid namespace pollution
|
||||||
|
const chat_messages = document.querySelector('.chat-messages');
|
||||||
|
|
||||||
|
// Disable auto-scroll-bottom on new message loads if the user has scrolled up
|
||||||
|
chat_messages.addEventListener('scroll', function() {
|
||||||
|
const _node = document.querySelector("#new-messages-poller");
|
||||||
|
const node = _node.cloneNode()
|
||||||
|
_node.remove(); // Removing and re-inserting the element cancels the HTMX polling, otherwise it will use the old values
|
||||||
|
|
||||||
|
const scrollPosition = chat_messages.scrollTop;
|
||||||
|
var bottomOfElement = chat_messages.scrollHeight - chat_messages.clientHeight;
|
||||||
|
|
||||||
|
var [path, qs] = node.attributes["hx-get"].value.split("?")
|
||||||
|
var params = new URLSearchParams(qs)
|
||||||
|
|
||||||
|
if (scrollPosition === bottomOfElement) {
|
||||||
|
// At bottom; new messages should be scrolled into view
|
||||||
|
node.setAttribute("hx-swap", "outerHTML scroll:.chat-messages:bottom");
|
||||||
|
params.set("scroll_bottom", "1")
|
||||||
|
node.setAttribute("hx-get", [path, params.toString()].join("?"))
|
||||||
|
} else {
|
||||||
|
// User has scrolled up; disable auto-scrolling when new messages arrive
|
||||||
|
node.setAttribute("hx-swap", "outerHTML");
|
||||||
|
params.set("scroll_bottom", "0")
|
||||||
|
node.setAttribute("hx-get", [path, params.toString()].join("?"))
|
||||||
|
}
|
||||||
|
|
||||||
|
chat_messages.appendChild(node);
|
||||||
|
htmx.process(node); // Manually enable HTMX on the manually-added node
|
||||||
|
});
|
||||||
|
|
||||||
|
// Scroll to the bottom of the chat window on initial page load
|
||||||
|
chat_messages.scrollTop = chat_messages.scrollHeight;
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{define "dm-composer"}}
|
{{define "dm-composer"}}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user