commit 709dcc61e86de38ca750bd736e9795c7ad58521b
parent 5f0629533de647a9335d0a280bc0d513abf62782
Author: MTRNord <mtrnord1@gmail.com>
Date: Tue, 9 May 2023 16:52:41 +0200
Add unknown state for presence
Diffstat:
11 files changed, 104 insertions(+), 47 deletions(-)
diff --git a/src/app/sdk/api/otherEnums.ts b/src/app/sdk/api/otherEnums.ts
@@ -0,0 +1,5 @@
+export enum OnlineState {
+ Online,
+ Offline,
+ Unknown
+}
diff --git a/src/app/sdk/room.ts b/src/app/sdk/room.ts
@@ -3,6 +3,7 @@ import { IRoomEvent, IRoomStateEvent, isRoomAvatarEvent, isRoomCreateEvent, isRo
import { MatrixClient } from "./client";
import { useEffect, useState } from "react";
import { EncryptionAlgorithm, EncryptionSettings, RoomId } from "@mtrnord/matrix-sdk-crypto-js";
+import { OnlineState } from "./api/otherEnums";
export interface RoomEvents {
// Used to notify about changes to the event list
@@ -179,9 +180,9 @@ export class Room extends EventEmitter {
return this.is_dm;
}
- public isOnline(): boolean {
+ public get presence(): OnlineState {
// TODO: Implement this
- return false;
+ return OnlineState.Unknown;
}
public getEvents(): IRoomEvent[] {
diff --git a/src/components/avatar/avatar.stories.tsx b/src/components/avatar/avatar.stories.tsx
@@ -1,5 +1,6 @@
import { Meta, StoryObj } from '@storybook/react';
import Avatar from './avatar';
+import { OnlineState } from '../../app/sdk/api/otherEnums';
const meta: Meta<typeof Avatar> = {
title: 'Chat/Avatar',
@@ -39,7 +40,7 @@ export const Fallback: Story = {
args: {
displayname: "test",
dm: false,
- online: false,
+ online: OnlineState.Unknown,
avatarUrl: ""
}
};
@@ -49,7 +50,7 @@ export const Image: Story = {
displayname: "test",
avatarUrl: "https://randomuser.me/api/portraits/men/62.jpg",
dm: false,
- online: false,
+ online: OnlineState.Unknown,
}
};
@@ -58,7 +59,17 @@ export const DMOffline: Story = {
displayname: "test",
avatarUrl: "https://randomuser.me/api/portraits/men/62.jpg",
dm: true,
- online: false,
+ online: OnlineState.Offline,
+ }
+};
+
+
+export const DMUnknown: Story = {
+ args: {
+ displayname: "test",
+ avatarUrl: "https://randomuser.me/api/portraits/men/62.jpg",
+ dm: true,
+ online: OnlineState.Unknown,
}
};
@@ -67,7 +78,7 @@ export const DMOnline: Story = {
displayname: "test",
avatarUrl: "https://randomuser.me/api/portraits/men/62.jpg",
dm: true,
- online: true,
+ online: OnlineState.Online,
}
};
@@ -76,7 +87,16 @@ export const DMNoAvatarOffline: Story = {
displayname: "test",
avatarUrl: "",
dm: true,
- online: false,
+ online: OnlineState.Offline,
+ }
+};
+
+export const DMNoAvatarUnknown: Story = {
+ args: {
+ displayname: "test",
+ avatarUrl: "",
+ dm: true,
+ online: OnlineState.Unknown,
}
};
@@ -85,6 +105,6 @@ export const DMNoAvatarOnline: Story = {
displayname: "test",
avatarUrl: "",
dm: true,
- online: true,
+ online: OnlineState.Online,
}
};
\ No newline at end of file
diff --git a/src/components/avatar/avatar.tsx b/src/components/avatar/avatar.tsx
@@ -1,4 +1,5 @@
import { FC, memo, useState } from "react";
+import { OnlineState } from "../../app/sdk/api/otherEnums";
type AvatarProps = {
/**
@@ -16,10 +17,10 @@ type AvatarProps = {
/**
* Wether the user is online. Only used if dm is true.
*/
- online: boolean
+ online: OnlineState
};
-const Avatar: FC<AvatarProps> = memo(({ avatarUrl, displayname, dm = false, online = false }: AvatarProps) => {
+const Avatar: FC<AvatarProps> = memo(({ avatarUrl, displayname, dm = false, online = OnlineState.Unknown }: AvatarProps) => {
const [error, setError] = useState(false);
if (avatarUrl && !error) {
@@ -29,9 +30,10 @@ const Avatar: FC<AvatarProps> = memo(({ avatarUrl, displayname, dm = false, onli
{
dm ?
(
- online ?
+ online === OnlineState.Online ?
<div className="bg-green-500 rounded-full w-3 h-3 absolute right-0 bottom-0"></div> :
- <div className="bg-red-500 rounded-full w-3 h-3 absolute right-0 bottom-0"></div>
+ (online === OnlineState.Offline ? <div className="bg-red-500 rounded-full w-3 h-3 absolute right-0 bottom-0"></div> :
+ <div className="bg-gray-500 rounded-full w-3 h-3 absolute right-0 bottom-0"></div>)
) :
<></>
}
@@ -44,9 +46,10 @@ const Avatar: FC<AvatarProps> = memo(({ avatarUrl, displayname, dm = false, onli
{
dm ?
(
- online ?
- <div className="bg-green-500 rounded-full w-3 h-3 absolute bottom-0 right-0"></div> :
- <div className="bg-red-500 rounded-full w-3 h-3 absolute bottom-0 right-0"></div>
+ online === OnlineState.Online ?
+ <div className="bg-green-500 rounded-full w-3 h-3 absolute right-0 bottom-0"></div> :
+ (online === OnlineState.Offline ? <div className="bg-red-500 rounded-full w-3 h-3 absolute right-0 bottom-0"></div> :
+ <div className="bg-gray-500 rounded-full w-3 h-3 absolute right-0 bottom-0"></div>)
) :
<></>
}
diff --git a/src/components/events/messageEvent.tsx b/src/components/events/messageEvent.tsx
@@ -11,6 +11,7 @@ import { decryptAttachment } from "matrix-encrypt-attachment";
import Waveform from './helpers/Waveform';
import hljs from 'highlight.js';
import 'highlight.js/styles/base16/solarized-dark.css';
+import { OnlineState } from "../../app/sdk/api/otherEnums";
type MessageEventProps = {
/**
@@ -111,7 +112,7 @@ const MessageEvent: FC<MessageEventProps> = memo(({ event, roomID, hasPreviousEv
{!hasPreviousEvent && <Avatar
displayname={room?.getMemberName(event.sender) || event.sender}
avatarUrl={room?.getMemberAvatar(event.sender)}
- online={room?.isOnline() || false}
+ online={room?.presence || OnlineState.Unknown}
dm={room?.isDM() || false}
/>}
<div className={!hasPreviousEvent ? "flex flex-col gap-1" : "ml-[3.7rem]"}>
@@ -189,7 +190,7 @@ const MessageEvent: FC<MessageEventProps> = memo(({ event, roomID, hasPreviousEv
{!hasPreviousEvent && <Avatar
displayname={room?.getMemberName(event.sender) || event.sender}
avatarUrl={room?.getMemberAvatar(event.sender)}
- online={room?.isOnline() || false}
+ online={room?.presence || OnlineState.Unknown}
dm={room?.isDM() || false}
/>}
<div className={!hasPreviousEvent ? "flex flex-col gap-1" : "flex-1 ml-[3.7rem]"}>
@@ -204,7 +205,7 @@ const MessageEvent: FC<MessageEventProps> = memo(({ event, roomID, hasPreviousEv
{!hasPreviousEvent && <Avatar
displayname={room?.getMemberName(event.sender) || event.sender}
avatarUrl={room?.getMemberAvatar(event.sender)}
- online={room?.isOnline() || false}
+ online={room?.presence || OnlineState.Unknown}
dm={room?.isDM() || false}
/>}
<div className={!hasPreviousEvent ? "flex flex-col gap-1" : "ml-[3.7rem]"}>
@@ -308,7 +309,7 @@ const TextMessage: FC<TextMessage> = memo(({ event, roomID, hasPreviousEvent, me
{!hasPreviousEvent && <Avatar
displayname={room?.getMemberName(event.sender) || event.sender}
avatarUrl={room?.getMemberAvatar(event.sender)}
- online={room?.isOnline() || false}
+ online={room?.presence || OnlineState.Unknown}
dm={room?.isDM() || false}
/>}
<div className={!hasPreviousEvent ? "flex flex-col gap-1" : "ml-[3.7rem]"}>
@@ -324,7 +325,7 @@ const TextMessage: FC<TextMessage> = memo(({ event, roomID, hasPreviousEvent, me
{!hasPreviousEvent && <Avatar
displayname={room?.getMemberName(event.sender) || event.sender}
avatarUrl={room?.getMemberAvatar(event.sender)}
- online={room?.isOnline() || false}
+ online={room?.presence || OnlineState.Unknown}
dm={room?.isDM() || false}
/>}
<div className={!hasPreviousEvent ? "flex flex-col gap-1" : "ml-[3.7rem]"}>
diff --git a/src/components/events/unknownEvent.tsx b/src/components/events/unknownEvent.tsx
@@ -4,6 +4,7 @@ import { FC } from "react";
import { useRoom } from "../../app/sdk/client";
import Linkify from "linkify-react";
import Avatar from "../avatar/avatar";
+import { OnlineState } from "../../app/sdk/api/otherEnums";
type UnknownEventProps = {
/**
@@ -35,7 +36,7 @@ const UnknownEvent: FC<UnknownEventProps> = memo(({ event, roomID, hasPreviousEv
{!hasPreviousEvent && <Avatar
displayname={room?.getMemberName(event.sender) || event.sender}
avatarUrl={room?.getMemberAvatar(event.sender)}
- online={room?.isOnline() || false}
+ online={room?.presence || OnlineState.Unknown}
dm={room?.isDM() || false}
/>}
<div className={!hasPreviousEvent ? "flex flex-col gap-1" : "ml-[3.7rem]"}>
@@ -71,7 +72,7 @@ export const UndecryptableEvent: FC<UndecryptableEventProps> = memo(({ event, ro
{!hasPreviousEvent && <Avatar
displayname={room?.getMemberName(event.sender) || event.sender}
avatarUrl={room?.getMemberAvatar(event.sender)}
- online={room?.isOnline() || false}
+ online={room?.presence || OnlineState.Unknown}
dm={room?.isDM() || false}
/>}
<div className={!hasPreviousEvent ? "flex flex-col gap-1" : "ml-[3.7rem]"}>
@@ -109,7 +110,7 @@ export const RedactedEvent: FC<RedactedEventProps> = memo(({ event, redacted_bec
{!hasPreviousEvent && <Avatar
displayname={room?.getMemberName(event.sender) || event.sender}
avatarUrl={room?.getMemberAvatar(event.sender)}
- online={room?.isOnline() || false}
+ online={room?.presence || OnlineState.Unknown}
dm={room?.isDM() || false}
/>}
<div className={!hasPreviousEvent ? "flex flex-col gap-1" : "ml-[3.7rem]"}>
diff --git a/src/components/roomList/roomList.stories.tsx b/src/components/roomList/roomList.stories.tsx
@@ -1,6 +1,7 @@
import { Meta, StoryObj } from '@storybook/react';
import RoomList from './roomList';
import { withRouter } from 'storybook-addon-react-router-v6';
+import { OnlineState } from '../../app/sdk/api/otherEnums';
const meta: Meta<typeof RoomList> = {
title: 'Chat/RoomList',
@@ -33,19 +34,19 @@ export const RootList: Story = {
displayname: "test",
avatarUrl: "https://randomuser.me/api/portraits/men/62.jpg",
dm: true,
- online: true,
+ online: OnlineState.Online,
},
{
roomID: "2",
displayname: "test1",
dm: false,
- online: false,
+ online: OnlineState.Unknown,
},
{
roomID: "3",
displayname: "test2",
dm: false,
- online: false,
+ online: OnlineState.Unknown,
}
],
sections: [
@@ -56,13 +57,13 @@ export const RootList: Story = {
roomID: "2",
displayname: "test1",
dm: false,
- online: false,
+ online: OnlineState.Unknown,
},
{
roomID: "3",
displayname: "test2",
dm: false,
- online: false,
+ online: OnlineState.Unknown,
}
],
roomID: "12",
@@ -75,7 +76,7 @@ export const RootList: Story = {
displayname: "test",
avatarUrl: "https://randomuser.me/api/portraits/men/62.jpg",
dm: true,
- online: true,
+ online: OnlineState.Online,
}
],
roomID: "14",
diff --git a/src/components/roomList/roomList.tsx b/src/components/roomList/roomList.tsx
@@ -5,6 +5,7 @@ import './roomList.scss';
import { useNavigate } from "react-router-dom";
import { MatrixContext } from "../../app/sdk/client";
import { useInView } from "react-intersection-observer";
+import { OnlineState } from "../../app/sdk/api/otherEnums";
type Room = {
/**
@@ -22,7 +23,7 @@ type Room = {
/**
* Wether the user is online. Only used if dm is true.
*/
- online: boolean
+ online: OnlineState
/**
* The roomid of the Room
*/
diff --git a/src/components/roomList/roomListItem/roomListItem.stories.tsx b/src/components/roomList/roomListItem/roomListItem.stories.tsx
@@ -1,5 +1,6 @@
import { Meta, StoryObj } from '@storybook/react';
import RoomListItem from './roomListItem';
+import { OnlineState } from '../../../app/sdk/api/otherEnums';
const meta: Meta<typeof RoomListItem> = {
title: 'Chat/RoomList/Item',
@@ -46,7 +47,7 @@ export const Fallback: Story = {
args: {
displayname: "test",
dm: false,
- online: false,
+ online: OnlineState.Unknown,
avatarUrl: "",
active: false,
}
@@ -56,7 +57,7 @@ export const FallbackActive: Story = {
args: {
displayname: "test",
dm: false,
- online: false,
+ online: OnlineState.Unknown,
avatarUrl: "",
active: true,
}
@@ -68,7 +69,7 @@ export const Image: Story = {
displayname: "test",
avatarUrl: "https://randomuser.me/api/portraits/men/62.jpg",
dm: false,
- online: false,
+ online: OnlineState.Unknown,
active: false,
}
};
@@ -79,7 +80,7 @@ export const ImageActive: Story = {
displayname: "test",
avatarUrl: "https://randomuser.me/api/portraits/men/62.jpg",
dm: false,
- online: false,
+ online: OnlineState.Unknown,
active: true,
}
};
@@ -89,7 +90,7 @@ export const DMOffline: Story = {
displayname: "test",
avatarUrl: "https://randomuser.me/api/portraits/men/62.jpg",
dm: true,
- online: false,
+ online: OnlineState.Offline,
active: false,
}
};
@@ -99,17 +100,38 @@ export const DMOfflineActive: Story = {
displayname: "test",
avatarUrl: "https://randomuser.me/api/portraits/men/62.jpg",
dm: true,
- online: false,
+ online: OnlineState.Online,
active: true,
}
};
+export const DMUnknown: Story = {
+ args: {
+ displayname: "test",
+ avatarUrl: "https://randomuser.me/api/portraits/men/62.jpg",
+ dm: true,
+ online: OnlineState.Unknown,
+ active: false,
+ }
+};
+
+export const DMUnknownActive: Story = {
+ args: {
+ displayname: "test",
+ avatarUrl: "https://randomuser.me/api/portraits/men/62.jpg",
+ dm: true,
+ online: OnlineState.Unknown,
+ active: true,
+ }
+};
+
+
export const DMOnline: Story = {
args: {
displayname: "test",
avatarUrl: "https://randomuser.me/api/portraits/men/62.jpg",
dm: true,
- online: true,
+ online: OnlineState.Online,
active: false,
}
};
@@ -119,7 +141,7 @@ export const DMOnlineActive: Story = {
displayname: "test",
avatarUrl: "https://randomuser.me/api/portraits/men/62.jpg",
dm: true,
- online: true,
+ online: OnlineState.Online,
active: true,
}
};
@@ -129,7 +151,7 @@ export const DMNoAvatarOffline: Story = {
displayname: "test",
avatarUrl: "",
dm: true,
- online: false,
+ online: OnlineState.Offline,
active: false,
}
};
@@ -139,7 +161,7 @@ export const DMNoAvatarOnline: Story = {
displayname: "test",
avatarUrl: "",
dm: true,
- online: true,
+ online: OnlineState.Online,
active: false,
}
};
\ No newline at end of file
diff --git a/src/components/roomList/roomListItem/roomListItem.tsx b/src/components/roomList/roomListItem/roomListItem.tsx
@@ -2,6 +2,7 @@ import { useInView } from "react-intersection-observer";
import Avatar from "../../avatar/avatar";
import { FC, memo, useContext } from "react";
import { MatrixContext } from "../../../app/sdk/client";
+import { OnlineState } from "../../../app/sdk/api/otherEnums";
type RoomListItemProps = {
/**
@@ -23,7 +24,7 @@ type RoomListItemProps = {
/**
* Wether the user is online. Only used if dm is true.
*/
- online: boolean
+ online: OnlineState
/**
* Wether the current room is selected
*/
@@ -38,7 +39,7 @@ type RoomListItemProps = {
hidden: boolean
};
-const RoomListItem: FC<RoomListItemProps> = memo(({ roomId, avatarUrl, displayname, dm = false, online = false, active = false, onClick, hidden }: RoomListItemProps) => {
+const RoomListItem: FC<RoomListItemProps> = memo(({ roomId, avatarUrl, displayname, dm = false, online = OnlineState.Unknown, active = false, onClick, hidden }: RoomListItemProps) => {
const matrixClient = useContext(MatrixContext);
const { ref, inView } = useInView({
triggerOnce: true,
diff --git a/src/pages/MainPage.tsx b/src/pages/MainPage.tsx
@@ -14,6 +14,7 @@ import MemberEvent from '../components/events/memberEvent';
import { IRoomEvent, IRoomMemberEvent } from '../app/sdk/api/apiTypes';
import Linkify from 'linkify-react';
import { RoomId } from '@mtrnord/matrix-sdk-crypto-js';
+import { OnlineState } from '../app/sdk/api/otherEnums';
type ChatViewProps = {
/**
@@ -266,7 +267,7 @@ const MainPage = memo(() => {
displayname: room.getName(),
avatarUrl: room.getAvatarURL(),
dm: room.isDM(),
- online: room.isOnline(),
+ online: room.presence,
}
});
@@ -279,7 +280,7 @@ const MainPage = memo(() => {
displayname: room.getName(),
avatarUrl: room.getAvatarURL(),
dm: room.isDM(),
- online: room.isOnline(),
+ online: room.presence,
}
});
@@ -313,7 +314,7 @@ const MainPage = memo(() => {
displayname: room.getName(),
avatarUrl: room.getAvatarURL(),
dm: room.isDM(),
- online: room.isOnline(),
+ online: room.presence,
}
});
@@ -334,7 +335,7 @@ const MainPage = memo(() => {
return <div className='flex flex-row gap-2 min-h-screen h-screen'>
<div className='flex flex-col bg-gradient-to-br from-slate-100 via-gray-200 to-orange-200 border-r-[1px] border-slate-300'>
<div className='flex flex-row gap-2 m-2 p-1 items-center border-b-2'>
- <Avatar displayname={profile.displayname || client.mxid!} avatarUrl={profile?.avatar_url} dm={false} online={false} />
+ <Avatar displayname={profile.displayname || client.mxid!} avatarUrl={profile?.avatar_url} dm={false} online={OnlineState.Unknown} />
<div className='flex flex-row justify-between items-center w-full'>
<span className='text-base font-semibold'>{profile?.displayname}</span>
<Settings size={28} stroke='unset' className='stroke-slate-600 rounded-full hover:bg-slate-300 p-1 cursor-pointer' />
@@ -345,7 +346,7 @@ const MainPage = memo(() => {
{
room && <div className='flex-1 flex flex-col'>
<div className='pb-2 flex flex-row items-center border-b-2 mt-4 ml-2'>
- <Avatar displayname={room.getName()} avatarUrl={room.getAvatarURL()} dm={room.isDM()} online={room.isOnline()} />
+ <Avatar displayname={room.getName()} avatarUrl={room.getAvatarURL()} dm={room.isDM()} online={room.presence} />
<div className='flex flex-row items-start'>
<h1 className='text-black font-semibold text-lg flex-shrink-0'>{room.getName()}</h1>
<Linkify options={linkifyOptions} as='p' className="ml-4 text-slate-700 font-normal text-base line-clamp-2 text-ellipsis">{room.getTopic()}</Linkify>