From f67fc443f6909c8dff851282b055d5c3c83f3435 Mon Sep 17 00:00:00 2001 From: Alessio Date: Tue, 14 Nov 2023 11:12:23 -0800 Subject: [PATCH] Add Messages page --- internal/webserver/handler_messages.go | 54 ++++++++++++++ internal/webserver/server.go | 2 + internal/webserver/static/styles.css | 72 +++++++++++++++++++ .../webserver/tpl/includes/nav_sidebar.tpl | 2 +- internal/webserver/tpl/messages.tpl | 9 +++ .../tpl/tweet_page_includes/chat_list.tpl | 18 +++++ .../tpl/tweet_page_includes/chat_view.tpl | 25 +++++++ 7 files changed, 181 insertions(+), 1 deletion(-) create mode 100644 internal/webserver/handler_messages.go create mode 100644 internal/webserver/tpl/messages.tpl create mode 100644 internal/webserver/tpl/tweet_page_includes/chat_list.tpl create mode 100644 internal/webserver/tpl/tweet_page_includes/chat_view.tpl diff --git a/internal/webserver/handler_messages.go b/internal/webserver/handler_messages.go new file mode 100644 index 0000000..a697a13 --- /dev/null +++ b/internal/webserver/handler_messages.go @@ -0,0 +1,54 @@ +package webserver + +import ( + "net/http" + "strings" + + "gitlab.com/offline-twitter/twitter_offline_engine/pkg/persistence" + "gitlab.com/offline-twitter/twitter_offline_engine/pkg/scraper" +) + +type MessageData persistence.DMChatView + +func (t MessageData) Tweet(id scraper.TweetID) scraper.Tweet { + return t.Tweets[id] +} +func (t MessageData) User(id scraper.UserID) scraper.User { + return t.Users[id] +} +func (t MessageData) Retweet(id scraper.TweetID) scraper.Retweet { + return t.Retweets[id] +} +func (t MessageData) Space(id scraper.SpaceID) scraper.Space { + return t.Spaces[id] +} +func (t MessageData) FocusedTweetID() scraper.TweetID { + return scraper.TweetID(0) +} + +func (app *Application) Messages(w http.ResponseWriter, r *http.Request) { + app.traceLog.Printf("'Lists' handler (path: %q)", r.URL.Path) + + // TODO: what if no active user? + + chat_view := app.Profile.GetChatRoomsPreview(app.ActiveUser.ID) + if strings.Trim(r.URL.Path, "/") != "" { + message_id := scraper.DMChatRoomID(strings.Trim(r.URL.Path, "/")) + chat_contents := app.Profile.GetChatRoomContents(message_id) + chat_view.MergeWith(chat_contents.DMTrove) + chat_view.MessageIDs = chat_contents.MessageIDs + + if r.Header.Get("HX-Request") == "true" { + app.buffered_render_tweet_htmx(w, "chat-view", MessageData(chat_view)) + return + } + } + + app.buffered_render_tweet_page(w, "tpl/messages.tpl", MessageData(chat_view)) +} + +// type DMChatView struct { +// scraper.DMTrove +// RoomIDs []scraper.DMChatRoomID +// MessageIDs []scraper.DMMessageID +// } diff --git a/internal/webserver/server.go b/internal/webserver/server.go index 06f185b..0816b5f 100644 --- a/internal/webserver/server.go +++ b/internal/webserver/server.go @@ -123,6 +123,8 @@ func (app *Application) ServeHTTP(w http.ResponseWriter, r *http.Request) { http.StripPrefix("/search", http.HandlerFunc(app.Search)).ServeHTTP(w, r) case "lists": app.Lists(w, r) + case "messages": + http.StripPrefix("/messages", http.HandlerFunc(app.Messages)).ServeHTTP(w, r) default: app.UserFeed(w, r) } diff --git a/internal/webserver/static/styles.css b/internal/webserver/static/styles.css index a60d7bc..64219eb 100644 --- a/internal/webserver/static/styles.css +++ b/internal/webserver/static/styles.css @@ -208,6 +208,7 @@ h3 { .profile-image { border-radius: 50%; width: 3em; + height: 3em; display: inline; border: 1px solid var(--color-outline-gray); } @@ -221,6 +222,7 @@ h3 { } .user-feed-header .profile-image { width: 8em; + height: 8em; } .tabs-container { outline: 1px solid var(--color-outline-gray); @@ -612,6 +614,7 @@ ul.dropdown-items { } .users-list-container .author-info .profile-image { width: 4em; + height: 4em; } .users-list-container .user { border-color: var(--color-twitter-off-white-dark); @@ -636,3 +639,72 @@ ul.dropdown-items { .sort-order-container .sort-order-label { font-weight: bold; } + +.chats-container { + display: flex; + flex-direction: row; + + /** Setup to allow the two panes to scroll independently **/ + height: 100vh; + padding-top: 4em; + margin-top: -4em; + box-sizing: border-box; +} +.chats-container .chat-list { + width: 30%; + display: flex; + flex-direction: column; + overflow-y: scroll; +} +.chats-container .chat-list .chat { + border-bottom: 1px solid var(--color-outline-gray); + padding: 0.5em; + box-sizing: border-box; +} +.chats-container #chat-view { + width: 70%; + border-left: 1px solid var(--color-outline-gray); + overflow-y: scroll; + padding: 0.5em; + box-sizing: border-box; +} +.chats-container #chat-view .our-message { + justify-content: flex-end; +} +.dm-message-and-reacts-container { + display: flex; + flex-direction: column; + margin: 1em 0; +} +p.dm-message-text { + display: inline-block; + padding: 1em; + background-color: #ddd; + border-radius: 1em; + margin: 0; +} +.our-message p.dm-message-text { + background-color: var(--color-twitter-blue-light); +} +.sender-profile-image-container { + display: flex; + align-items: flex-end; +} +.sender-profile-image-container a { + line-height: 0; /* TODO: This is redundant with ".author-info a" rule above */ +} +.dm-message-container { + display: flex; + align-items: stretch; + gap: 0.5em; +} +.our-message .dm-message-container { + flex-direction: row-reverse; +} +.dm-message-reactions { + display: flex; + padding: 0 4em; +} +.our-message .dm-message-reactions { + flex-direction: row-reverse; +} diff --git a/internal/webserver/tpl/includes/nav_sidebar.tpl b/internal/webserver/tpl/includes/nav_sidebar.tpl index 4f5cb94..fcf1800 100644 --- a/internal/webserver/tpl/includes/nav_sidebar.tpl +++ b/internal/webserver/tpl/includes/nav_sidebar.tpl @@ -25,7 +25,7 @@ Notifications - +