Add pagination to DM conversation and scrolling back using 'show more' button
This commit is contained in:
parent
4d6407492a
commit
af3e496468
@ -57,10 +57,18 @@ func (app *Application) message_detail(w http.ResponseWriter, r *http.Request) {
|
|||||||
if r.URL.Query().Get("scroll_bottom") != "0" {
|
if r.URL.Query().Get("scroll_bottom") != "0" {
|
||||||
chat_view_data.ScrollBottom = true
|
chat_view_data.ScrollBottom = true
|
||||||
}
|
}
|
||||||
chat_contents := app.Profile.GetChatRoomContents(room_id, chat_view_data.LatestPollingTimestamp)
|
|
||||||
chat_view_data.MergeWith(chat_contents.DMTrove)
|
c := persistence.NewConversationCursor(room_id)
|
||||||
|
c.SinceTimestamp = scraper.TimestampFromUnixMilli(int64(chat_view_data.LatestPollingTimestamp))
|
||||||
|
if cursor_value := r.URL.Query().Get("cursor"); cursor_value != "" {
|
||||||
|
until_time, err := strconv.Atoi(cursor_value)
|
||||||
|
panic_if(err) // TODO: 400 not 500
|
||||||
|
c.UntilTimestamp = scraper.TimestampFromUnixMilli(int64(until_time))
|
||||||
|
}
|
||||||
|
chat_contents := app.Profile.GetChatRoomMessagesByCursor(c)
|
||||||
chat_view_data.DMChatView.MergeWith(chat_contents.DMTrove)
|
chat_view_data.DMChatView.MergeWith(chat_contents.DMTrove)
|
||||||
chat_view_data.MessageIDs = chat_contents.MessageIDs
|
chat_view_data.MessageIDs = chat_contents.MessageIDs
|
||||||
|
chat_view_data.Cursor = chat_contents.Cursor
|
||||||
if len(chat_view_data.MessageIDs) > 0 {
|
if len(chat_view_data.MessageIDs) > 0 {
|
||||||
last_message_id := chat_view_data.MessageIDs[len(chat_view_data.MessageIDs)-1]
|
last_message_id := chat_view_data.MessageIDs[len(chat_view_data.MessageIDs)-1]
|
||||||
chat_view_data.LatestPollingTimestamp = int(chat_view_data.Messages[last_message_id].SentAt.UnixMilli())
|
chat_view_data.LatestPollingTimestamp = int(chat_view_data.Messages[last_message_id].SentAt.UnixMilli())
|
||||||
@ -72,6 +80,12 @@ func (app *Application) message_detail(w http.ResponseWriter, r *http.Request) {
|
|||||||
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)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Scrolling-back should add new messages to the top of the page
|
||||||
|
if r.URL.Query().Has("cursor") {
|
||||||
|
app.buffered_render_htmx(w, "messages-top", global_data, chat_view_data)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
app.buffered_render_page(w, "tpl/messages.tpl", global_data, chat_view_data)
|
app.buffered_render_page(w, "tpl/messages.tpl", global_data, chat_view_data)
|
||||||
|
@ -821,3 +821,24 @@ func TestMessagesRoomPollForUpdatesEmptyResult(t *testing.T) {
|
|||||||
Val: "/messages/1488963321701171204-1178839081222115328?poll&latest_timestamp=1686025129144&scroll_bottom=1",
|
Val: "/messages/1488963321701171204-1178839081222115328?poll&latest_timestamp=1686025129144&scroll_bottom=1",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Scroll back in the messages
|
||||||
|
func TestMessagesPaginate(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
require := require.New(t)
|
||||||
|
|
||||||
|
// Boilerplate for setting an active user
|
||||||
|
app := webserver.NewApp(profile)
|
||||||
|
app.IsScrapingDisabled = true
|
||||||
|
app.ActiveUser = scraper.User{ID: 1488963321701171204, Handle: "Offline_Twatter"} // Simulate a login
|
||||||
|
|
||||||
|
// Chat detail
|
||||||
|
recorder := httptest.NewRecorder()
|
||||||
|
req := httptest.NewRequest("GET", "/messages/1488963321701171204-1178839081222115328?cursor=1686025129142", nil)
|
||||||
|
req.Header.Set("HX-Request", "true")
|
||||||
|
app.ServeHTTP(recorder, req)
|
||||||
|
resp := recorder.Result()
|
||||||
|
root, err := html.Parse(resp.Body)
|
||||||
|
require.NoError(err)
|
||||||
|
assert.Len(cascadia.QueryAll(root, selector(".dm-message")), 2)
|
||||||
|
}
|
||||||
|
@ -106,6 +106,7 @@
|
|||||||
{{end}}
|
{{end}}
|
||||||
<div class="chat-messages">
|
<div class="chat-messages">
|
||||||
{{if .ActiveRoomID}}
|
{{if .ActiveRoomID}}
|
||||||
|
{{template "conversation-top" .}}
|
||||||
{{template "messages-with-poller" .}}
|
{{template "messages-with-poller" .}}
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
@ -190,3 +191,24 @@
|
|||||||
{{end}}
|
{{end}}
|
||||||
></span>
|
></span>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
|
{{define "conversation-top"}}
|
||||||
|
<div class="conversation-top">
|
||||||
|
{{if .Cursor.CursorPosition.IsEnd}}
|
||||||
|
<!-- TODO: make a reusable eof-indicator -->
|
||||||
|
<div class="eof-indicator">Beginning of conversation</div>
|
||||||
|
{{else}}
|
||||||
|
<a class="show-more-button button"
|
||||||
|
hx-get="?cursor={{.Cursor.CursorValue}}" {{/* TODO: this might require a `cursor_to_query_params` if the same view is used for searching */}}
|
||||||
|
hx-target=".conversation-top"
|
||||||
|
hx-swap="outerHTML"
|
||||||
|
>Show more</a>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
{{/* convenience template for htmx requests */}}
|
||||||
|
{{define "messages-top"}}
|
||||||
|
{{template "conversation-top" .}}
|
||||||
|
{{template "messages" .}}
|
||||||
|
{{end}}
|
||||||
|
@ -264,9 +264,14 @@ func (p Profile) GetChatRoomsPreview(id UserID) DMChatView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get chat room detail, including participants and messages
|
// Get chat room detail, including participants and messages
|
||||||
|
// TODO: get rid of this function (behavior has been moved to GetChatRoomMessagesByCursor)
|
||||||
func (p Profile) GetChatRoomContents(id DMChatRoomID, latest_timestamp int) DMChatView {
|
func (p Profile) GetChatRoomContents(id DMChatRoomID, latest_timestamp int) DMChatView {
|
||||||
c := NewConversationCursor(id)
|
c := NewConversationCursor(id)
|
||||||
c.SinceTimestamp = TimestampFromUnixMilli(int64(latest_timestamp))
|
c.SinceTimestamp = TimestampFromUnixMilli(int64(latest_timestamp))
|
||||||
|
return p.GetChatRoomMessagesByCursor(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p Profile) GetChatRoomMessagesByCursor(c DMCursor) DMChatView {
|
||||||
ret := p.NextDMPage(c)
|
ret := p.NextDMPage(c)
|
||||||
|
|
||||||
var room DMChatRoom
|
var room DMChatRoom
|
||||||
@ -274,7 +279,7 @@ func (p Profile) GetChatRoomContents(id DMChatRoomID, latest_timestamp int) DMCh
|
|||||||
select `+CHAT_ROOMS_ALL_SQL_FIELDS+`
|
select `+CHAT_ROOMS_ALL_SQL_FIELDS+`
|
||||||
from chat_rooms
|
from chat_rooms
|
||||||
where id = ?
|
where id = ?
|
||||||
`, id)
|
`, c.ConversationId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user