From a6a3ac3b24c5bddda4c109d3047c2c41113b0931 Mon Sep 17 00:00:00 2001
From: Ajay Bura <32841439+ajbura@users.noreply.github.com>
Date: Thu, 25 Sep 2025 12:17:44 +0530
Subject: [PATCH] redesign thread selector
---
.../thread-selector/ThreadSelector.tsx | 90 ---------------
.../components/thread-selector/styles.css.ts | 20 ----
src/app/features/room/RoomTimeline.tsx | 10 +-
.../thread-selector/ThreadSelector.tsx | 105 ++++++++++++++++++
.../room/message}/thread-selector/index.ts | 0
.../message/thread-selector/styles.css.ts | 37 ++++++
.../room/threads-menu/ThreadsMenu.tsx | 5 +-
src/app/hooks/useRoomThreads.ts | 2 +-
8 files changed, 154 insertions(+), 115 deletions(-)
delete mode 100644 src/app/components/thread-selector/ThreadSelector.tsx
delete mode 100644 src/app/components/thread-selector/styles.css.ts
create mode 100644 src/app/features/room/message/thread-selector/ThreadSelector.tsx
rename src/app/{components => features/room/message}/thread-selector/index.ts (100%)
create mode 100644 src/app/features/room/message/thread-selector/styles.css.ts
diff --git a/src/app/components/thread-selector/ThreadSelector.tsx b/src/app/components/thread-selector/ThreadSelector.tsx
deleted file mode 100644
index 75eb1590..00000000
--- a/src/app/components/thread-selector/ThreadSelector.tsx
+++ /dev/null
@@ -1,90 +0,0 @@
-import { Avatar, Box, Icon, Icons, Text } from 'folds';
-import React, { ReactNode } from 'react';
-import classNames from 'classnames';
-import { IThreadBundledRelationship, Room } from 'matrix-js-sdk';
-import { ContainerColor } from '../../styles/ContainerColor.css';
-import * as css from './styles.css';
-import { UserAvatar } from '../user-avatar';
-import { getMemberAvatarMxc, getMemberDisplayName } from '../../utils/room';
-import { useMatrixClient } from '../../hooks/useMatrixClient';
-import { useMediaAuthentication } from '../../hooks/useMediaAuthentication';
-import { getMxIdLocalPart, mxcUrlToHttp } from '../../utils/matrix';
-
-export function ThreadSelectorContainer({ children }: { children: ReactNode }) {
- return {children};
-}
-
-type ThreadSelectorProps = {
- room: Room;
- senderId: string;
- threadDetail: IThreadBundledRelationship;
- outlined?: boolean;
-};
-
-export function ThreadSelector({ room, senderId, threadDetail, outlined }: ThreadSelectorProps) {
- const mx = useMatrixClient();
- const useAuthentication = useMediaAuthentication();
- const senderAvatarMxc = getMemberAvatarMxc(room, senderId);
-
- const latestEvent = threadDetail.latest_event;
- const latestSenderId = latestEvent.sender;
- const latestSenderAvatarMxc = getMemberAvatarMxc(room, latestSenderId);
- const latestDisplayName =
- getMemberDisplayName(room, latestSenderId) ??
- getMxIdLocalPart(latestSenderId) ??
- latestSenderId;
-
- const latestEventTs = latestEvent.origin_server_ts;
-
- return (
-
-
-
- }
- />
-
- {latestSenderId && (
-
- }
- />
-
- )}
-
-
-
- {threadDetail.count} {threadDetail.count === 1 ? 'Reply' : 'Replies'}
-
-
- {/* TODO: date */}
- Last Reply by {latestDisplayName} at {new Date(latestEventTs).getTime()}
-
-
-
-
- );
-}
diff --git a/src/app/components/thread-selector/styles.css.ts b/src/app/components/thread-selector/styles.css.ts
deleted file mode 100644
index fe580b68..00000000
--- a/src/app/components/thread-selector/styles.css.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import { style } from '@vanilla-extract/css';
-import { color, config } from 'folds';
-
-export const ThreadSelectorContainer = style({
- paddingTop: config.space.S100,
-});
-
-export const ThreadSelector = style({
- padding: config.space.S200,
- borderRadius: config.radii.R400,
-});
-
-export const ThreadSectorOutlined = style({
- borderWidth: config.borderWidth.B300,
-});
-
-export const ThreadRepliesCount = style({
- color: color.Primary.Main,
- flexShrink: 0,
-});
diff --git a/src/app/features/room/RoomTimeline.tsx b/src/app/features/room/RoomTimeline.tsx
index 93c3cf66..71674b0f 100644
--- a/src/app/features/room/RoomTimeline.tsx
+++ b/src/app/features/room/RoomTimeline.tsx
@@ -127,7 +127,7 @@ import { useAccessiblePowerTagColors, useGetMemberPowerTag } from '../../hooks/u
import { useTheme } from '../../hooks/useTheme';
import { useRoomCreatorsTag } from '../../hooks/useRoomCreatorsTag';
import { usePowerLevelTags } from '../../hooks/usePowerLevelTags';
-import { ThreadSelector, ThreadSelectorContainer } from '../../components/thread-selector';
+import { ThreadSelector, ThreadSelectorContainer } from './message/thread-selector';
const TimelineFloat = as<'div', css.TimelineFloatVariants>(
({ position, className, ...props }, ref) => (
@@ -1113,7 +1113,13 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli
{threadDetail && (
-
+
)}
diff --git a/src/app/features/room/message/thread-selector/ThreadSelector.tsx b/src/app/features/room/message/thread-selector/ThreadSelector.tsx
new file mode 100644
index 00000000..3701948c
--- /dev/null
+++ b/src/app/features/room/message/thread-selector/ThreadSelector.tsx
@@ -0,0 +1,105 @@
+import { Avatar, Box, Icon, Icons, Line, Text } from 'folds';
+import React, { ReactNode } from 'react';
+import classNames from 'classnames';
+import { IThreadBundledRelationship, Room } from 'matrix-js-sdk';
+import * as css from './styles.css';
+import { UserAvatar } from '../../../../components/user-avatar';
+import { getMemberAvatarMxc, getMemberDisplayName } from '../../../../utils/room';
+import { useMatrixClient } from '../../../../hooks/useMatrixClient';
+import { useMediaAuthentication } from '../../../../hooks/useMediaAuthentication';
+import { getMxIdLocalPart, mxcUrlToHttp } from '../../../../utils/matrix';
+import { Time } from '../../../../components/message';
+
+export function ThreadSelectorContainer({ children }: { children: ReactNode }) {
+ return {children};
+}
+
+type ThreadSelectorProps = {
+ room: Room;
+ threadDetail: IThreadBundledRelationship;
+ outlined?: boolean;
+ hour24Clock: boolean;
+ dateFormatString: string;
+};
+
+export function ThreadSelector({
+ room,
+ threadDetail,
+ outlined,
+ hour24Clock,
+ dateFormatString,
+}: ThreadSelectorProps) {
+ const mx = useMatrixClient();
+ const useAuthentication = useMediaAuthentication();
+
+ const latestEvent = threadDetail.latest_event;
+
+ const latestSenderId = latestEvent.sender;
+ const latestSenderAvatarMxc = getMemberAvatarMxc(room, latestSenderId);
+ const latestDisplayName =
+ getMemberDisplayName(room, latestSenderId) ??
+ getMxIdLocalPart(latestSenderId) ??
+ latestSenderId;
+
+ const latestEventTs = latestEvent.origin_server_ts;
+
+ return (
+
+
+
+
+ {threadDetail.count} {threadDetail.count === 1 ? 'Thread Reply' : 'Thread Replies'}
+
+
+ {latestSenderId && (
+ <>
+
+
+
+
+ }
+ />
+
+
+
+
+ Latest by {latestDisplayName} at{' '}
+
+
+
+
+
+ >
+ )}
+
+ );
+}
diff --git a/src/app/components/thread-selector/index.ts b/src/app/features/room/message/thread-selector/index.ts
similarity index 100%
rename from src/app/components/thread-selector/index.ts
rename to src/app/features/room/message/thread-selector/index.ts
diff --git a/src/app/features/room/message/thread-selector/styles.css.ts b/src/app/features/room/message/thread-selector/styles.css.ts
new file mode 100644
index 00000000..fbd15ecc
--- /dev/null
+++ b/src/app/features/room/message/thread-selector/styles.css.ts
@@ -0,0 +1,37 @@
+import { style } from '@vanilla-extract/css';
+import { color, config, toRem } from 'folds';
+import { ContainerColor } from '../../../../styles/ContainerColor.css';
+
+export const ThreadSelectorContainer = style({
+ marginTop: config.space.S200,
+});
+
+export const ThreadSelector = style([
+ ContainerColor({ variant: 'SurfaceVariant' }),
+ {
+ padding: `${config.space.S200} ${config.space.S300}`,
+ borderRadius: config.radii.R400,
+ cursor: 'pointer',
+
+ selectors: {
+ '&:hover, &:focus-visible': {
+ backgroundColor: color.SurfaceVariant.ContainerHover,
+ },
+ '&:active': {
+ backgroundColor: color.SurfaceVariant.ContainerActive,
+ },
+ },
+ },
+]);
+
+export const ThreadSectorOutlined = style({
+ borderWidth: config.borderWidth.B300,
+});
+
+export const ThreadSelectorDivider = style({
+ height: toRem(16),
+});
+
+export const ThreadRepliesCount = style({
+ color: color.Primary.Main,
+});
diff --git a/src/app/features/room/threads-menu/ThreadsMenu.tsx b/src/app/features/room/threads-menu/ThreadsMenu.tsx
index 5ff308e6..375b97da 100644
--- a/src/app/features/room/threads-menu/ThreadsMenu.tsx
+++ b/src/app/features/room/threads-menu/ThreadsMenu.tsx
@@ -80,7 +80,7 @@ import {
} from '../../../hooks/useMemberPowerTag';
import { useRoomCreatorsTag } from '../../../hooks/useRoomCreatorsTag';
import { useRoomMyThreads } from '../../../hooks/useRoomThreads';
-import { ThreadSelector, ThreadSelectorContainer } from '../../../components/thread-selector';
+import { ThreadSelector, ThreadSelectorContainer } from '../message/thread-selector';
type ThreadMessageProps = {
room: Room;
@@ -287,9 +287,10 @@ export const ThreadsMenu = forwardRef(
)}
diff --git a/src/app/hooks/useRoomThreads.ts b/src/app/hooks/useRoomThreads.ts
index d5ef24d6..a8ed0933 100644
--- a/src/app/hooks/useRoomThreads.ts
+++ b/src/app/hooks/useRoomThreads.ts
@@ -14,7 +14,7 @@ export const useRoomMyThreads = (room: Room): MatrixEvent[] | undefined => {
null,
30,
Direction.Backward,
- ThreadFilterType.My
+ ThreadFilterType.All
),
[mx, room]
)