diff --git a/matrixgw_frontend/src/utils/RoomEventsManager.ts b/matrixgw_frontend/src/utils/RoomEventsManager.ts index 78dcedb..4f74bb1 100644 --- a/matrixgw_frontend/src/utils/RoomEventsManager.ts +++ b/matrixgw_frontend/src/utils/RoomEventsManager.ts @@ -12,7 +12,8 @@ export interface MessageReaction { export interface Message { event_id: string; - sent: number; + account: string; + time_sent: number; modified: boolean; reactions: MessageReaction[]; content: string; @@ -75,9 +76,10 @@ export class RoomEventsManager { this.messages.push({ event_id: evt.id, + account: evt.sender, modified: false, reactions: [], - sent: evt.time, + time_sent: evt.time, image: data.content.file?.url, content: data.content.body, }); diff --git a/matrixgw_frontend/src/widgets/messages/AccountIcon.tsx b/matrixgw_frontend/src/widgets/messages/AccountIcon.tsx new file mode 100644 index 0000000..3c6e23a --- /dev/null +++ b/matrixgw_frontend/src/widgets/messages/AccountIcon.tsx @@ -0,0 +1,15 @@ +import { Avatar } from "@mui/material"; +import type { UserProfile } from "../../api/matrix/MatrixApiProfile"; +import { MatrixApiMedia } from "../../api/matrix/MatrixApiMedia"; + +export function AccountIcon(p: { user: UserProfile }): React.ReactElement { + return ( + + {p.user.display_name?.slice(0, 1)} + + ); +} diff --git a/matrixgw_frontend/src/widgets/messages/RoomMessagesList.tsx b/matrixgw_frontend/src/widgets/messages/RoomMessagesList.tsx new file mode 100644 index 0000000..1848fcd --- /dev/null +++ b/matrixgw_frontend/src/widgets/messages/RoomMessagesList.tsx @@ -0,0 +1,61 @@ +import dayjs from "dayjs"; +import type { UsersMap } from "../../api/matrix/MatrixApiProfile"; +import type { Message, RoomEventsManager } from "../../utils/RoomEventsManager"; +import { AccountIcon } from "./AccountIcon"; +import { MatrixApiMedia } from "../../api/matrix/MatrixApiMedia"; + +export function RoomMessagesList(p: { + users: UsersMap; + mgr: RoomEventsManager; +}): React.ReactElement { + return ( +
+ {p.mgr.messages.map((m, idx) => ( + 0 && + p.mgr.messages[idx - 1].account === m.account && + m.time_sent - p.mgr.messages[idx - 1].time_sent < 60 * 3 * 1000 + } + /> + ))} +
+ ); +} + +function RoomMessage(p: { + users: UsersMap; + message: Message; + previousFromSamePerson: boolean; +}): React.ReactElement { + const user = p.users.get(p.message.account); + return ( + <> + {!p.previousFromSamePerson && user && ( +
+ +   + {user.display_name} +
+ )} + +
+ {dayjs.unix(p.message.time_sent / 1000).format("HH:mm")}{" "} + {p.message.image ? ( + + ) : ( + p.message.content + )} +
+ + ); +} diff --git a/matrixgw_frontend/src/widgets/messages/RoomWidget.tsx b/matrixgw_frontend/src/widgets/messages/RoomWidget.tsx index de26ea7..a5aeaf0 100644 --- a/matrixgw_frontend/src/widgets/messages/RoomWidget.tsx +++ b/matrixgw_frontend/src/widgets/messages/RoomWidget.tsx @@ -4,6 +4,7 @@ import type { UsersMap } from "../../api/matrix/MatrixApiProfile"; import type { Room } from "../../api/matrix/MatrixApiRoom"; import { RoomEventsManager } from "../../utils/RoomEventsManager"; import { AsyncWidget } from "../AsyncWidget"; +import { RoomMessagesList } from "./RoomMessagesList"; export function RoomWidget(p: { room: Room; @@ -24,7 +25,12 @@ export function RoomWidget(p: { ready={!!roomMgr} load={load} errMsg="Failed to load room!" - build={() => <>room} + build={() => ( +
+ +
Send message form
+
+ )} /> ); }