web/roomlist: add sender name to previews

This commit is contained in:
Tulir Asokan 2024-10-12 16:09:15 +03:00
parent a7caf8a71f
commit 2b6c00fa04
4 changed files with 38 additions and 9 deletions

View file

@ -194,6 +194,7 @@ export interface RoomListEntry {
room_id: RoomID room_id: RoomID
sorting_timestamp: number sorting_timestamp: number
preview_event?: MemDBEvent preview_event?: MemDBEvent
preview_sender?: MemDBEvent
name: string name: string
avatar?: ContentURI avatar?: ContentURI
} }
@ -212,10 +213,13 @@ export class StateStore {
if (!room) { if (!room) {
room = this.rooms.get(entry.meta.room_id) room = this.rooms.get(entry.meta.room_id)
} }
const preview_event = room?.eventsByRowID.get(entry.meta.preview_event_rowid)
const preview_sender = preview_event && room?.getStateEvent("m.room.member", preview_event.sender)
return { return {
room_id: entry.meta.room_id, room_id: entry.meta.room_id,
sorting_timestamp: entry.meta.sorting_timestamp, sorting_timestamp: entry.meta.sorting_timestamp,
preview_event: room?.eventsByRowID.get(entry.meta.preview_event_rowid), preview_event,
preview_sender,
name: entry.meta.name ?? "Unnamed room", name: entry.meta.name ?? "Unnamed room",
avatar: entry.meta.avatar, avatar: entry.meta.avatar,
} }

View file

@ -15,7 +15,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
import { getMediaURL } from "../../api/media.ts" import { getMediaURL } from "../../api/media.ts"
import type { RoomListEntry } from "../../api/statestore.ts" import type { RoomListEntry } from "../../api/statestore.ts"
import type { MemDBEvent } from "../../api/types" import type { MemDBEvent, MemberEventContent } from "../../api/types"
export interface RoomListEntryProps { export interface RoomListEntryProps {
room: RoomListEntry room: RoomListEntry
@ -23,18 +23,25 @@ export interface RoomListEntryProps {
isActive: boolean isActive: boolean
} }
function makePreviewText(evt?: MemDBEvent): string { function makePreviewText(evt?: MemDBEvent, senderMemberEvt?: MemDBEvent): [string, string] {
if (!evt) { if (!evt) {
return "" return ["", ""]
} }
if ((evt.type === "m.room.message" || evt.type === "m.sticker") && typeof evt.content.body === "string") { if ((evt.type === "m.room.message" || evt.type === "m.sticker") && typeof evt.content.body === "string") {
return evt.content.body let displayname = (senderMemberEvt?.content as MemberEventContent)?.displayname
if (!displayname) {
displayname = evt.sender.slice(1).split(":")[0]
}
return [
`${displayname}: ${evt.content.body}`,
`${displayname.length > 16 ? displayname.slice(0, 12) + "…" : displayname}: ${evt.content.body}`,
]
} }
return "" return ["", ""]
} }
const Entry = ({ room, setActiveRoom, isActive }: RoomListEntryProps) => { const Entry = ({ room, setActiveRoom, isActive }: RoomListEntryProps) => {
const previewText = makePreviewText(room.preview_event) const [previewText, croppedPreviewText] = makePreviewText(room.preview_event, room.preview_sender)
return <div return <div
className={`room-entry ${isActive ? "active" : ""}`} className={`room-entry ${isActive ? "active" : ""}`}
onClick={setActiveRoom} onClick={setActiveRoom}
@ -45,7 +52,7 @@ const Entry = ({ room, setActiveRoom, isActive }: RoomListEntryProps) => {
</div> </div>
<div className="room-entry-right"> <div className="room-entry-right">
<div className="room-name">{room.name}</div> <div className="room-name">{room.name}</div>
{previewText && <div className="message-preview" title={previewText}>{previewText}</div>} {previewText && <div className="message-preview" title={previewText}>{croppedPreviewText}</div>}
</div> </div>
</div> </div>
} }

View file

@ -45,6 +45,16 @@ div.room-list {
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
> span.sender-name {
display: block;
max-width: 6rem;
overflow: hidden;
}
> span.preview-text {
display: block;
}
} }
} }
} }

View file

@ -254,11 +254,19 @@ func (gmx *Gomuks) sendInitialData(ctx context.Context, conn *websocket.Conn) {
return return
} }
if previewEvent != nil { if previewEvent != nil {
previewMember, err := gmx.Client.DB.CurrentState.Get(ctx, room.ID, event.StateMember, previewEvent.Sender.String())
if err != nil {
log.Err(err).Msg("Failed to get preview member event for room")
} else if previewMember != nil {
syncRoom.Events = append(syncRoom.Events, previewMember)
syncRoom.State[event.StateMember] = map[string]database.EventRowID{
*previewMember.StateKey: previewMember.RowID,
}
}
if previewEvent.LastEditRowID != nil { if previewEvent.LastEditRowID != nil {
lastEdit, err := gmx.Client.DB.Event.GetByRowID(ctx, *previewEvent.LastEditRowID) lastEdit, err := gmx.Client.DB.Event.GetByRowID(ctx, *previewEvent.LastEditRowID)
if err != nil { if err != nil {
log.Err(err).Msg("Failed to get last edit for preview event") log.Err(err).Msg("Failed to get last edit for preview event")
return
} else if lastEdit != nil { } else if lastEdit != nil {
syncRoom.Events = append(syncRoom.Events, lastEdit) syncRoom.Events = append(syncRoom.Events, lastEdit)
} }