diff --git a/res/css/views/rooms/_PresenceIconView.pcss b/res/css/views/rooms/_PresenceIconView.pcss new file mode 100644 index 0000000000..6be4ac4782 --- /dev/null +++ b/res/css/views/rooms/_PresenceIconView.pcss @@ -0,0 +1,32 @@ +/* +Copyright 2024 New Vector Ltd. + +SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only +Please see LICENSE files in the repository root for full details. +*/ + +.mx_PresenceIconView { + position: absolute; + top: 24px; + left: 24px; + width: 12px; + height: 12px; + display: flex; + justify-content: center; + align-items: center; + background: var(--cpd-color-bg-canvas-default); + border-radius: 100%; + + .mx_PresenceIconView_online { + color: var(--cpd-color-icon-accent-primary); + } + + .mx_PresenceIconView_offline, + .mx_PresenceIconView_dnd { + color: var(--cpd-color-icon-tertiary); + } + + .mx_PresenceIconView_unavailable { + color: var(--cpd-color-icon-quaternary); + } +} diff --git a/src/components/views/rooms/MemberList/tiles/common/PresenceIconView.tsx b/src/components/views/rooms/MemberList/tiles/common/PresenceIconView.tsx new file mode 100644 index 0000000000..18aaa13a23 --- /dev/null +++ b/src/components/views/rooms/MemberList/tiles/common/PresenceIconView.tsx @@ -0,0 +1,44 @@ +/* +Copyright 2024 New Vector Ltd. + +SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only +Please see LICENSE files in the repository root for full details. +*/ + +import React from "react"; +import OnlineOrUnavailableIcon from "@vector-im/compound-design-tokens/assets/web/icons/presence-solid-8x8"; +import OfflineIcon from "@vector-im/compound-design-tokens/assets/web/icons/presence-outline-8x8"; +import DNDIcon from "@vector-im/compound-design-tokens/assets/web/icons/presence-strikethrough-8x8"; +import classNames from "classnames"; +import { UnstableValue } from "matrix-js-sdk/src/NamespacedValue"; + +interface Props { + className?: string; + presenceState: string; +} + +export const BUSY_PRESENCE_NAME = new UnstableValue("busy", "org.matrix.msc3026.busy"); + +function getIconForPresenceState(state: string): React.JSX.Element { + switch (state) { + case "online": + return ; + case "offline": + return ; + case "unavailable": + case "io.element.unreachable": + return ; + case BUSY_PRESENCE_NAME.name: + case BUSY_PRESENCE_NAME.altName: + return ; + default: + throw new Error(`Presence state "${state}" is unknown.`); + } +} + +const AvatarPresenceIconView: React.FC = ({ className, presenceState }) => { + const names = classNames("mx_PresenceIconView", className); + return {getIconForPresenceState(presenceState)}; +}; + +export default AvatarPresenceIconView;