mirror of
https://github.com/cinnyapp/cinny.git
synced 2025-02-23 21:53:05 +01:00
make server room card view btn clickable
This commit is contained in:
parent
c541c05ff4
commit
6502e2e2e0
5 changed files with 83 additions and 55 deletions
|
@ -29,6 +29,7 @@ import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback';
|
||||||
import { getResizeObserverEntry, useResizeObserver } from '../../hooks/useResizeObserver';
|
import { getResizeObserverEntry, useResizeObserver } from '../../hooks/useResizeObserver';
|
||||||
import { onEnterOrSpace } from '../../utils/keyboard';
|
import { onEnterOrSpace } from '../../utils/keyboard';
|
||||||
import { RoomType } from '../../../types/matrix/room';
|
import { RoomType } from '../../../types/matrix/room';
|
||||||
|
import { useJoinedRoomId } from '../../hooks/useJoinedRoomId';
|
||||||
|
|
||||||
type GridColumnCount = '1' | '2' | '3';
|
type GridColumnCount = '1' | '2' | '3';
|
||||||
const getGridColumnCount = (gridWidth: number): GridColumnCount => {
|
const getGridColumnCount = (gridWidth: number): GridColumnCount => {
|
||||||
|
@ -143,7 +144,7 @@ function ErrorDialog({
|
||||||
|
|
||||||
type RoomCardProps = {
|
type RoomCardProps = {
|
||||||
roomIdOrAlias: string;
|
roomIdOrAlias: string;
|
||||||
joinedRoomId?: string;
|
allRooms: string[];
|
||||||
avatarUrl?: string;
|
avatarUrl?: string;
|
||||||
name?: string;
|
name?: string;
|
||||||
topic?: string;
|
topic?: string;
|
||||||
|
@ -157,7 +158,7 @@ export const RoomCard = as<'div', RoomCardProps>(
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
roomIdOrAlias,
|
roomIdOrAlias,
|
||||||
joinedRoomId,
|
allRooms,
|
||||||
avatarUrl,
|
avatarUrl,
|
||||||
name,
|
name,
|
||||||
topic,
|
topic,
|
||||||
|
@ -173,6 +174,7 @@ export const RoomCard = as<'div', RoomCardProps>(
|
||||||
const avatar = avatarUrl && mx.mxcUrlToHttp(avatarUrl, 96, 96, 'crop');
|
const avatar = avatarUrl && mx.mxcUrlToHttp(avatarUrl, 96, 96, 'crop');
|
||||||
const fallbackName = getMxIdLocalPart(roomIdOrAlias) ?? roomIdOrAlias;
|
const fallbackName = getMxIdLocalPart(roomIdOrAlias) ?? roomIdOrAlias;
|
||||||
const fallbackTopic = roomIdOrAlias;
|
const fallbackTopic = roomIdOrAlias;
|
||||||
|
const joinedRoomId = useJoinedRoomId(allRooms, roomIdOrAlias);
|
||||||
|
|
||||||
const [joinState, join] = useAsyncCallback<Room, MatrixError, []>(
|
const [joinState, join] = useAsyncCallback<Room, MatrixError, []>(
|
||||||
useCallback(() => mx.joinRoom(roomIdOrAlias), [mx, roomIdOrAlias])
|
useCallback(() => mx.joinRoom(roomIdOrAlias), [mx, roomIdOrAlias])
|
||||||
|
|
19
src/app/hooks/useJoinedRoomId.ts
Normal file
19
src/app/hooks/useJoinedRoomId.ts
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import { useMemo } from 'react';
|
||||||
|
import { useMatrixClient } from './useMatrixClient';
|
||||||
|
|
||||||
|
import { getCanonicalAliasRoomId, isRoomAlias } from '../utils/matrix';
|
||||||
|
|
||||||
|
export const useJoinedRoomId = (allRooms: string[], roomIdOrAlias: string): string | undefined => {
|
||||||
|
const mx = useMatrixClient();
|
||||||
|
|
||||||
|
const joinedRoomId = useMemo(() => {
|
||||||
|
const roomId = isRoomAlias(roomIdOrAlias)
|
||||||
|
? getCanonicalAliasRoomId(mx, roomIdOrAlias)
|
||||||
|
: roomIdOrAlias;
|
||||||
|
|
||||||
|
if (roomId && allRooms.includes(roomId)) return roomId;
|
||||||
|
return undefined;
|
||||||
|
}, [mx, allRooms, roomIdOrAlias]);
|
||||||
|
|
||||||
|
return joinedRoomId;
|
||||||
|
};
|
|
@ -1,15 +1,8 @@
|
||||||
import React, { useCallback } from 'react';
|
import React from 'react';
|
||||||
import { Box, Icon, Icons, Scroll, Text } from 'folds';
|
import { Box, Icon, Icons, Scroll, Text } from 'folds';
|
||||||
import { useNavigate } from 'react-router-dom';
|
|
||||||
import { useAtomValue } from 'jotai';
|
import { useAtomValue } from 'jotai';
|
||||||
import { useClientConfig } from '../../../hooks/useClientConfig';
|
import { useClientConfig } from '../../../hooks/useClientConfig';
|
||||||
import { RoomCard, RoomCardGrid } from '../../../components/room-card';
|
import { RoomCard, RoomCardGrid } from '../../../components/room-card';
|
||||||
import {
|
|
||||||
getCanonicalAliasOrRoomId,
|
|
||||||
getCanonicalAliasRoomId,
|
|
||||||
isRoomAlias,
|
|
||||||
} from '../../../utils/matrix';
|
|
||||||
import { useMatrixClient } from '../../../hooks/useMatrixClient';
|
|
||||||
import { allRoomsAtom } from '../../../state/room-list/roomList';
|
import { allRoomsAtom } from '../../../state/room-list/roomList';
|
||||||
import { RoomSummaryLoader } from '../../../components/RoomSummaryLoader';
|
import { RoomSummaryLoader } from '../../../components/RoomSummaryLoader';
|
||||||
import {
|
import {
|
||||||
|
@ -20,54 +13,14 @@ import {
|
||||||
PageHeroSection,
|
PageHeroSection,
|
||||||
} from '../../../components/page';
|
} from '../../../components/page';
|
||||||
import { RoomTopicViewer } from '../../../components/room-topic-viewer';
|
import { RoomTopicViewer } from '../../../components/room-topic-viewer';
|
||||||
import { getHomeRoomPath, getSpacePath, getSpaceRoomPath } from '../../pathUtils';
|
|
||||||
import { getOrphanParents } from '../../../utils/room';
|
|
||||||
import { roomToParentsAtom } from '../../../state/room/roomToParents';
|
|
||||||
import * as css from './style.css';
|
import * as css from './style.css';
|
||||||
|
import { useRoomNavigate } from './hooks';
|
||||||
|
|
||||||
export function FeaturedRooms() {
|
export function FeaturedRooms() {
|
||||||
const mx = useMatrixClient();
|
|
||||||
const { featuredCommunities } = useClientConfig();
|
const { featuredCommunities } = useClientConfig();
|
||||||
const { rooms, spaces } = featuredCommunities ?? {};
|
const { rooms, spaces } = featuredCommunities ?? {};
|
||||||
const allRooms = useAtomValue(allRoomsAtom);
|
const allRooms = useAtomValue(allRoomsAtom);
|
||||||
const navigate = useNavigate();
|
const { navigateSpace, navigateRoom } = useRoomNavigate();
|
||||||
const roomToParents = useAtomValue(roomToParentsAtom);
|
|
||||||
|
|
||||||
const joinedRoomId = useCallback(
|
|
||||||
(roomIdOrAlias: string): string | undefined => {
|
|
||||||
const roomId = isRoomAlias(roomIdOrAlias)
|
|
||||||
? getCanonicalAliasRoomId(mx, roomIdOrAlias)
|
|
||||||
: roomIdOrAlias;
|
|
||||||
|
|
||||||
if (roomId && allRooms.includes(roomId)) return roomId;
|
|
||||||
return undefined;
|
|
||||||
},
|
|
||||||
[mx, allRooms]
|
|
||||||
);
|
|
||||||
|
|
||||||
const navigateSpace = useCallback(
|
|
||||||
(roomId: string) => {
|
|
||||||
const roomIdOrAlias = getCanonicalAliasOrRoomId(mx, roomId);
|
|
||||||
navigate(getSpacePath(roomIdOrAlias));
|
|
||||||
},
|
|
||||||
[mx, navigate]
|
|
||||||
);
|
|
||||||
|
|
||||||
const navigateRoom = useCallback(
|
|
||||||
(roomId: string) => {
|
|
||||||
const roomIdOrAlias = getCanonicalAliasOrRoomId(mx, roomId);
|
|
||||||
|
|
||||||
const orphanParents = getOrphanParents(roomToParents, roomId);
|
|
||||||
if (orphanParents.length > 0) {
|
|
||||||
const pSpaceIdOrAlias = getCanonicalAliasOrRoomId(mx, orphanParents[0]);
|
|
||||||
navigate(getSpaceRoomPath(pSpaceIdOrAlias, roomIdOrAlias));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
navigate(getHomeRoomPath(roomIdOrAlias));
|
|
||||||
},
|
|
||||||
[mx, navigate, roomToParents]
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Page>
|
<Page>
|
||||||
|
@ -93,7 +46,7 @@ export function FeaturedRooms() {
|
||||||
{(roomSummary) => (
|
{(roomSummary) => (
|
||||||
<RoomCard
|
<RoomCard
|
||||||
roomIdOrAlias={roomIdOrAlias}
|
roomIdOrAlias={roomIdOrAlias}
|
||||||
joinedRoomId={joinedRoomId(roomIdOrAlias)}
|
allRooms={allRooms}
|
||||||
avatarUrl={roomSummary?.avatar_url}
|
avatarUrl={roomSummary?.avatar_url}
|
||||||
name={roomSummary?.name}
|
name={roomSummary?.name}
|
||||||
topic={roomSummary?.topic}
|
topic={roomSummary?.topic}
|
||||||
|
@ -122,7 +75,7 @@ export function FeaturedRooms() {
|
||||||
{(roomSummary) => (
|
{(roomSummary) => (
|
||||||
<RoomCard
|
<RoomCard
|
||||||
roomIdOrAlias={roomIdOrAlias}
|
roomIdOrAlias={roomIdOrAlias}
|
||||||
joinedRoomId={joinedRoomId(roomIdOrAlias)}
|
allRooms={allRooms}
|
||||||
avatarUrl={roomSummary?.avatar_url}
|
avatarUrl={roomSummary?.avatar_url}
|
||||||
name={roomSummary?.name}
|
name={roomSummary?.name}
|
||||||
topic={roomSummary?.topic}
|
topic={roomSummary?.topic}
|
||||||
|
|
|
@ -25,6 +25,7 @@ import {
|
||||||
} from 'folds';
|
} from 'folds';
|
||||||
import { useNavigate, useParams, useSearchParams } from 'react-router-dom';
|
import { useNavigate, useParams, useSearchParams } from 'react-router-dom';
|
||||||
import FocusTrap from 'focus-trap-react';
|
import FocusTrap from 'focus-trap-react';
|
||||||
|
import { useAtomValue } from 'jotai';
|
||||||
import { useQuery } from '@tanstack/react-query';
|
import { useQuery } from '@tanstack/react-query';
|
||||||
import { MatrixClient, Method, RoomType } from 'matrix-js-sdk';
|
import { MatrixClient, Method, RoomType } from 'matrix-js-sdk';
|
||||||
import { Page, PageContent, PageContentCenter, PageHeader } from '../../../components/page';
|
import { Page, PageContent, PageContentCenter, PageHeader } from '../../../components/page';
|
||||||
|
@ -34,6 +35,8 @@ import { RoomCard, RoomCardBase, RoomCardGrid } from '../../../components/room-c
|
||||||
import { ExploreServerPathSearchParams } from '../../paths';
|
import { ExploreServerPathSearchParams } from '../../paths';
|
||||||
import { getExploreServerPath, withSearchParam } from '../../pathUtils';
|
import { getExploreServerPath, withSearchParam } from '../../pathUtils';
|
||||||
import * as css from './style.css';
|
import * as css from './style.css';
|
||||||
|
import { allRoomsAtom } from '../../../state/room-list/roomList';
|
||||||
|
import { useRoomNavigate } from './hooks';
|
||||||
|
|
||||||
const getServerSearchParams = (searchParams: URLSearchParams): ExploreServerPathSearchParams => ({
|
const getServerSearchParams = (searchParams: URLSearchParams): ExploreServerPathSearchParams => ({
|
||||||
limit: searchParams.get('limit') ?? undefined,
|
limit: searchParams.get('limit') ?? undefined,
|
||||||
|
@ -224,6 +227,9 @@ function LimitButton({ limit, onLimitChange }: LimitButtonProps) {
|
||||||
export function PublicRooms() {
|
export function PublicRooms() {
|
||||||
const { server } = useParams();
|
const { server } = useParams();
|
||||||
const mx = useMatrixClient();
|
const mx = useMatrixClient();
|
||||||
|
const allRooms = useAtomValue(allRoomsAtom);
|
||||||
|
const { navigateSpace, navigateRoom } = useRoomNavigate();
|
||||||
|
|
||||||
const [searchParams] = useSearchParams();
|
const [searchParams] = useSearchParams();
|
||||||
const serverSearchParams = getServerSearchParams(searchParams);
|
const serverSearchParams = getServerSearchParams(searchParams);
|
||||||
const isSearch = !!serverSearchParams.term;
|
const isSearch = !!serverSearchParams.term;
|
||||||
|
@ -434,12 +440,17 @@ export function PublicRooms() {
|
||||||
<RoomCard
|
<RoomCard
|
||||||
key={chunkRoom.room_id}
|
key={chunkRoom.room_id}
|
||||||
roomIdOrAlias={chunkRoom.canonical_alias ?? chunkRoom.room_id}
|
roomIdOrAlias={chunkRoom.canonical_alias ?? chunkRoom.room_id}
|
||||||
joinedRoomId={mx.getRoom(chunkRoom.room_id)?.roomId}
|
allRooms={allRooms}
|
||||||
avatarUrl={chunkRoom.avatar_url}
|
avatarUrl={chunkRoom.avatar_url}
|
||||||
name={chunkRoom.name}
|
name={chunkRoom.name}
|
||||||
topic={chunkRoom.topic}
|
topic={chunkRoom.topic}
|
||||||
memberCount={chunkRoom.num_joined_members}
|
memberCount={chunkRoom.num_joined_members}
|
||||||
roomType={chunkRoom.room_type}
|
roomType={chunkRoom.room_type}
|
||||||
|
onView={
|
||||||
|
chunkRoom.room_type === RoomType.Space
|
||||||
|
? navigateSpace
|
||||||
|
: navigateRoom
|
||||||
|
}
|
||||||
renderTopicViewer={(name, topic, requestClose) => (
|
renderTopicViewer={(name, topic, requestClose) => (
|
||||||
<RoomTopicViewer
|
<RoomTopicViewer
|
||||||
name={name}
|
name={name}
|
||||||
|
|
43
src/app/pages/client/explore/hooks.ts
Normal file
43
src/app/pages/client/explore/hooks.ts
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
import { useCallback } from 'react';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
import { useAtomValue } from 'jotai';
|
||||||
|
import { getCanonicalAliasOrRoomId } from '../../../utils/matrix';
|
||||||
|
import { getHomeRoomPath, getSpacePath, getSpaceRoomPath } from '../../pathUtils';
|
||||||
|
import { useMatrixClient } from '../../../hooks/useMatrixClient';
|
||||||
|
import { getOrphanParents } from '../../../utils/room';
|
||||||
|
import { roomToParentsAtom } from '../../../state/room/roomToParents';
|
||||||
|
|
||||||
|
export const useRoomNavigate = () => {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const mx = useMatrixClient();
|
||||||
|
const roomToParents = useAtomValue(roomToParentsAtom);
|
||||||
|
|
||||||
|
const navigateSpace = useCallback(
|
||||||
|
(roomId: string) => {
|
||||||
|
const roomIdOrAlias = getCanonicalAliasOrRoomId(mx, roomId);
|
||||||
|
navigate(getSpacePath(roomIdOrAlias));
|
||||||
|
},
|
||||||
|
[mx, navigate]
|
||||||
|
);
|
||||||
|
|
||||||
|
const navigateRoom = useCallback(
|
||||||
|
(roomId: string) => {
|
||||||
|
const roomIdOrAlias = getCanonicalAliasOrRoomId(mx, roomId);
|
||||||
|
|
||||||
|
const orphanParents = getOrphanParents(roomToParents, roomId);
|
||||||
|
if (orphanParents.length > 0) {
|
||||||
|
const pSpaceIdOrAlias = getCanonicalAliasOrRoomId(mx, orphanParents[0]);
|
||||||
|
navigate(getSpaceRoomPath(pSpaceIdOrAlias, roomIdOrAlias));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
navigate(getHomeRoomPath(roomIdOrAlias));
|
||||||
|
},
|
||||||
|
[mx, navigate, roomToParents]
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
navigateSpace,
|
||||||
|
navigateRoom,
|
||||||
|
};
|
||||||
|
};
|
Loading…
Reference in a new issue