mirror of
https://github.com/cinnyapp/cinny.git
synced 2025-02-22 21:23:09 +01:00
open room card topic in viewer
This commit is contained in:
parent
8f729a0ca1
commit
e0632e2425
3 changed files with 73 additions and 4 deletions
|
@ -1,6 +1,19 @@
|
|||
import React, { ReactNode, useCallback, useEffect, useRef } from 'react';
|
||||
import { Avatar, Box, Button, Icon, Icons, Spinner, Text, as } from 'folds';
|
||||
import React, { ReactNode, useCallback, useEffect, useRef, useState } from 'react';
|
||||
import {
|
||||
Avatar,
|
||||
Box,
|
||||
Button,
|
||||
Icon,
|
||||
Icons,
|
||||
Overlay,
|
||||
OverlayBackdrop,
|
||||
OverlayCenter,
|
||||
Spinner,
|
||||
Text,
|
||||
as,
|
||||
} from 'folds';
|
||||
import classNames from 'classnames';
|
||||
import FocusTrap from 'focus-trap-react';
|
||||
import * as css from './style.css';
|
||||
import { RoomAvatar } from '../room-avatar';
|
||||
import { getMxIdLocalPart } from '../../utils/matrix';
|
||||
|
@ -9,6 +22,7 @@ import { millify } from '../../plugins/millify';
|
|||
import { useMatrixClient } from '../../hooks/useMatrixClient';
|
||||
import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback';
|
||||
import { getResizeObserverEntry, useResizeObserver } from '../../hooks/useResizeObserver';
|
||||
import { onEnterOrSpace } from '../../utils/keyboard';
|
||||
|
||||
type GridColumnCount = '1' | '2' | '3';
|
||||
const getGridColumnCount = (gridWidth: number): GridColumnCount => {
|
||||
|
@ -82,9 +96,22 @@ type RoomCardProps = {
|
|||
name?: string;
|
||||
topic?: string;
|
||||
memberCount?: number;
|
||||
renderTopicViewer: (name: string, topic: string, requestClose: () => void) => ReactNode;
|
||||
};
|
||||
export const RoomCard = as<'div', RoomCardProps>(
|
||||
({ roomIdOrAlias, joinedRoomId, avatarUrl, name, topic, memberCount, ...props }, ref) => {
|
||||
(
|
||||
{
|
||||
roomIdOrAlias,
|
||||
joinedRoomId,
|
||||
avatarUrl,
|
||||
name,
|
||||
topic,
|
||||
memberCount,
|
||||
renderTopicViewer,
|
||||
...props
|
||||
},
|
||||
ref
|
||||
) => {
|
||||
const mx = useMatrixClient();
|
||||
const avatar = avatarUrl && mx.mxcUrlToHttp(avatarUrl, 96, 96, 'crop');
|
||||
const fallbackName = getMxIdLocalPart(roomIdOrAlias) ?? roomIdOrAlias;
|
||||
|
@ -96,6 +123,10 @@ export const RoomCard = as<'div', RoomCardProps>(
|
|||
const joining =
|
||||
joinState.status === AsyncStatus.Loading || joinState.status === AsyncStatus.Success;
|
||||
|
||||
const [viewTopic, setViewTopic] = useState(false);
|
||||
const closeTopic = () => setViewTopic(false);
|
||||
const openTopic = () => setViewTopic(true);
|
||||
|
||||
return (
|
||||
<RoomCardBase {...props} ref={ref}>
|
||||
<Avatar size="500">
|
||||
|
@ -111,7 +142,23 @@ export const RoomCard = as<'div', RoomCardProps>(
|
|||
</Avatar>
|
||||
<Box grow="Yes" direction="Column" gap="100">
|
||||
<RoomCardName>{name || fallbackName}</RoomCardName>
|
||||
<RoomCardTopic>{topic || fallbackTopic}</RoomCardTopic>
|
||||
<RoomCardTopic onClick={openTopic} onKeyDown={onEnterOrSpace(openTopic)} tabIndex={0}>
|
||||
{topic || fallbackTopic}
|
||||
</RoomCardTopic>
|
||||
|
||||
<Overlay open={viewTopic} backdrop={<OverlayBackdrop />}>
|
||||
<OverlayCenter>
|
||||
<FocusTrap
|
||||
focusTrapOptions={{
|
||||
initialFocus: false,
|
||||
clickOutsideDeactivates: true,
|
||||
onDeactivate: closeTopic,
|
||||
}}
|
||||
>
|
||||
{renderTopicViewer(name || fallbackName, topic || fallbackTopic, () => closeTopic)}
|
||||
</FocusTrap>
|
||||
</OverlayCenter>
|
||||
</Overlay>
|
||||
</Box>
|
||||
{typeof memberCount === 'number' && (
|
||||
<Box gap="100">
|
||||
|
|
|
@ -8,6 +8,7 @@ import { useMatrixClient } from '../../../hooks/useMatrixClient';
|
|||
import { allRoomsAtom } from '../../../state/room-list/roomList';
|
||||
import { RoomSummaryLoader } from '../../../components/RoomSummaryLoader';
|
||||
import { Content, ContentBody, ContentHero, ContentHeroSection } from '../../../components/content';
|
||||
import { RoomTopicViewer } from '../../../components/room-topic-viewer';
|
||||
|
||||
export function FeaturedRooms() {
|
||||
const mx = useMatrixClient();
|
||||
|
@ -53,6 +54,13 @@ export function FeaturedRooms() {
|
|||
name={roomSummary?.name}
|
||||
topic={roomSummary?.topic}
|
||||
memberCount={roomSummary?.num_joined_members}
|
||||
renderTopicViewer={(name, topic, requestClose) => (
|
||||
<RoomTopicViewer
|
||||
name={name}
|
||||
topic={topic}
|
||||
requestClose={requestClose}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</RoomSummaryLoader>
|
||||
|
@ -74,6 +82,13 @@ export function FeaturedRooms() {
|
|||
name={roomSummary?.name}
|
||||
topic={roomSummary?.topic}
|
||||
memberCount={roomSummary?.num_joined_members}
|
||||
renderTopicViewer={(name, topic, requestClose) => (
|
||||
<RoomTopicViewer
|
||||
name={name}
|
||||
topic={topic}
|
||||
requestClose={requestClose}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</RoomSummaryLoader>
|
||||
|
|
|
@ -23,3 +23,10 @@ export const preventScrollWithArrowKey: KeyboardEventHandler = (evt) => {
|
|||
evt.preventDefault();
|
||||
}
|
||||
};
|
||||
|
||||
export const onEnterOrSpace = (callback: () => void) => (evt: KeyboardEventLike) => {
|
||||
if (isKeyHotkey('enter', evt) || isKeyHotkey('space', evt)) {
|
||||
evt.preventDefault();
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue