Various improvements to Messages UI
- Chat list previews look a bit nicer, and display the time of last message - Chat messages show sent_at time - Messages with line breaks will actually display as paragraphs now - Misc spacing improvements - BUGFIX: fix preview DB query crashing if there's no messages in a chat
This commit is contained in:
parent
c6d0bbce65
commit
6e9a370073
@ -27,7 +27,7 @@ func (t MessageData) FocusedTweetID() scraper.TweetID {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (app *Application) Messages(w http.ResponseWriter, r *http.Request) {
|
func (app *Application) Messages(w http.ResponseWriter, r *http.Request) {
|
||||||
app.traceLog.Printf("'Lists' handler (path: %q)", r.URL.Path)
|
app.traceLog.Printf("'Messages' handler (path: %q)", r.URL.Path)
|
||||||
|
|
||||||
// TODO: what if no active user?
|
// TODO: what if no active user?
|
||||||
|
|
||||||
|
@ -148,12 +148,15 @@ a.entity {
|
|||||||
color: var(--color-twitter-blue);
|
color: var(--color-twitter-blue);
|
||||||
}
|
}
|
||||||
|
|
||||||
.tweet .text {
|
.tweet .text, .dm-message-text-container .text {
|
||||||
display: block;
|
display: block;
|
||||||
margin-bottom: 0.4em;
|
margin-bottom: 0.4em;
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
overflow-wrap: anywhere;
|
overflow-wrap: anywhere;
|
||||||
}
|
}
|
||||||
|
.dm-message-text-container .text:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
#focused-tweet .text {
|
#focused-tweet .text {
|
||||||
font-size: 1.4em;
|
font-size: 1.4em;
|
||||||
}
|
}
|
||||||
@ -651,39 +654,57 @@ ul.dropdown-items {
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
.chats-container .chat-list {
|
.chats-container .chat-list {
|
||||||
width: 30%;
|
flex-basis: 0;
|
||||||
|
flex-grow: 4;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
}
|
}
|
||||||
.chats-container .chat-list .chat {
|
.chats-container .chat-list .chat {
|
||||||
border-bottom: 1px solid var(--color-outline-gray);
|
border-bottom: 1px solid var(--color-outline-gray);
|
||||||
padding: 0.5em;
|
padding: 1em 1em 0 1em;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
.chats-container .chat-list .chat .chat-preview-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.chats-container .chat-list .chat .chat-preview-header .posted-at {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.chats-container .chat-list .chat .chat-preview {
|
||||||
|
font-size: 0.9em;
|
||||||
|
color: var(--color-twitter-text-gray);
|
||||||
|
padding: 0 1em;
|
||||||
|
border-left: 1px solid var(--color-outline-gray);
|
||||||
|
}
|
||||||
|
|
||||||
.chats-container #chat-view {
|
.chats-container #chat-view {
|
||||||
width: 70%;
|
flex-basis: 0;
|
||||||
|
flex-grow: 7;
|
||||||
border-left: 1px solid var(--color-outline-gray);
|
border-left: 1px solid var(--color-outline-gray);
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
.chats-container #chat-view .our-message {
|
.chats-container #chat-view .our-message {
|
||||||
justify-content: flex-end;
|
align-items: flex-end;
|
||||||
}
|
}
|
||||||
.dm-message-and-reacts-container {
|
.dm-message-and-reacts-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
margin: 1em 0;
|
margin: 1em 0;
|
||||||
}
|
}
|
||||||
p.dm-message-text {
|
.dm-message-text-container {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
background-color: #ddd;
|
background-color: #ddd;
|
||||||
border-radius: 1em;
|
border-radius: 1em;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
.our-message p.dm-message-text {
|
.our-message .dm-message-text-container {
|
||||||
background-color: var(--color-twitter-blue-light);
|
background-color: var(--color-twitter-blue-light);
|
||||||
}
|
}
|
||||||
.sender-profile-image-container {
|
.sender-profile-image-container {
|
||||||
@ -708,3 +729,6 @@ p.dm-message-text {
|
|||||||
.our-message .dm-message-reactions {
|
.our-message .dm-message-reactions {
|
||||||
flex-direction: row-reverse;
|
flex-direction: row-reverse;
|
||||||
}
|
}
|
||||||
|
.dm-message-and-reacts-container p.posted-at {
|
||||||
|
margin: 0 4.5em;
|
||||||
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
{{range .RoomIDs}}
|
{{range .RoomIDs}}
|
||||||
{{$room := (index $.Rooms .)}}
|
{{$room := (index $.Rooms .)}}
|
||||||
<div class="chat" hx-get="/messages/{{$room.ID}}" hx-target="#chat-view" hx-swap="outerHTML" hx-push-url="true">
|
<div class="chat" hx-get="/messages/{{$room.ID}}" hx-target="#chat-view" hx-swap="outerHTML" hx-push-url="true">
|
||||||
|
<div class="chat-preview-header">
|
||||||
{{range $room.Participants}}
|
{{range $room.Participants}}
|
||||||
{{if (ne .UserID (active_user).ID)}}
|
{{if (ne .UserID (active_user).ID)}}
|
||||||
<!-- This is some fuckery; I have no idea why "hx-target" is needed, but otherwise it targets the #chat-view. -->
|
<!-- This is some fuckery; I have no idea why "hx-target" is needed, but otherwise it targets the #chat-view. -->
|
||||||
@ -11,6 +12,14 @@
|
|||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
<div class="chat-preview-timestamp .posted-at-container">
|
||||||
|
<p class="posted-at">
|
||||||
|
{{$room.LastMessagedAt.Time.Format "Jan 2, 2006"}}
|
||||||
|
<br/>
|
||||||
|
{{$room.LastMessagedAt.Time.Format "3:04 pm"}}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<p class="chat-preview">{{(index $.DMTrove.Messages $room.LastMessageID).Text}}</p>
|
<p class="chat-preview">{{(index $.DMTrove.Messages $room.LastMessageID).Text}}</p>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
<img class="profile-image" src="/content/{{$user.GetProfileImageLocalPath}}" />
|
<img class="profile-image" src="/content/{{$user.GetProfileImageLocalPath}}" />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<p class="dm-message-text">{{$message.Text}}</p>
|
<div class="dm-message-text-container">{{template "text-with-entities" $message.Text}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="dm-message-reactions">
|
<div class="dm-message-reactions">
|
||||||
{{range $message.Reactions}}
|
{{range $message.Reactions}}
|
||||||
@ -19,6 +19,9 @@
|
|||||||
<span title="{{$sender.DisplayName}} (@{{$sender.Handle}})">{{.Emoji}}</span>
|
<span title="{{$sender.DisplayName}} (@{{$sender.Handle}})">{{.Emoji}}</span>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
<p class="posted-at">
|
||||||
|
{{$message.SentAt.Time.Format "Jan 2, 2006 @ 3:04 pm"}}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package persistence
|
package persistence
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -188,7 +190,10 @@ func (p Profile) GetChatRoomsPreview(id UserID) DMChatView {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
err = p.DB.Get(&msg, q, args...)
|
err = p.DB.Get(&msg, q, args...)
|
||||||
if err != nil {
|
if errors.Is(err, sql.ErrNoRows) {
|
||||||
|
// TODO
|
||||||
|
fmt.Printf("No messages found in chat; skipping preview\n")
|
||||||
|
} else if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user