diff --git a/web/modals/threads/sidebars/sidebar.react.js b/web/modals/threads/sidebars/sidebar.react.js
index c8f13113e..6d710b290 100644
--- a/web/modals/threads/sidebars/sidebar.react.js
+++ b/web/modals/threads/sidebars/sidebar.react.js
@@ -1,91 +1,101 @@
// @flow
import classNames from 'classnames';
import * as React from 'react';
import { useModalContext } from 'lib/components/modal-provider.react.js';
import type { ChatThreadItem } from 'lib/selectors/chat-selectors.js';
import { useMessagePreview } from 'lib/shared/message-utils.js';
import { shortAbsoluteDate } from 'lib/utils/date-utils.js';
import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js';
import css from './sidebars-modal.css';
import Button from '../../../components/button.react.js';
+import ThreadAvatar from '../../../components/thread-avatar.react.js';
import { getDefaultTextMessageRules } from '../../../markdown/rules.react.js';
import { useOnClickThread } from '../../../selectors/thread-selectors.js';
type Props = {
+sidebar: ChatThreadItem,
+isLastItem?: boolean,
};
function Sidebar(props: Props): React.Node {
const { sidebar, isLastItem } = props;
const { threadInfo, lastUpdatedTime, mostRecentMessageInfo } = sidebar;
const { unread } = threadInfo.currentUser;
const { popModal } = useModalContext();
const navigateToThread = useOnClickThread(threadInfo);
const onClickThread = React.useCallback(
event => {
popModal();
navigateToThread(event);
},
[popModal, navigateToThread],
);
const sidebarInfoClassName = classNames({
[css.sidebarInfo]: true,
[css.unread]: unread,
});
+ const previewTextClassName = classNames({
+ [css.longTextEllipsis]: true,
+ [css.avatarOffset]: true,
+ });
+
const lastActivity = React.useMemo(
() => shortAbsoluteDate(lastUpdatedTime),
[lastUpdatedTime],
);
const messagePreviewResult = useMessagePreview(
mostRecentMessageInfo,
threadInfo,
getDefaultTextMessageRules().simpleMarkdownRules,
);
const lastMessage = React.useMemo(() => {
if (!messagePreviewResult) {
return
No messages
;
}
const { message, username } = messagePreviewResult;
const previewText = username
? `${username.text}: ${message.text}`
: message.text;
return (
<>
- {previewText}
+ {previewText}
{lastActivity}
>
);
- }, [lastActivity, messagePreviewResult]);
+ }, [lastActivity, messagePreviewResult, previewTextClassName]);
const { uiName } = useResolvedThreadInfo(threadInfo);
+
return (
);
}
export default Sidebar;
diff --git a/web/modals/threads/sidebars/sidebars-modal.css b/web/modals/threads/sidebars/sidebars-modal.css
index c9ab9e196..8744e7b95 100644
--- a/web/modals/threads/sidebars/sidebars-modal.css
+++ b/web/modals/threads/sidebars/sidebars-modal.css
@@ -1,73 +1,83 @@
div.sidebarListContainer {
display: flex;
flex-direction: column;
line-height: var(--line-height-text);
width: 383px;
height: 458px;
}
div.sidebarList {
overflow: auto;
color: var(--sidebars-modal-color);
}
div.noSidebars {
padding: 16px;
text-align: center;
color: var(--sidebars-modal-color);
}
button.sidebarContainer {
padding: 0 16px;
column-gap: 8px;
align-items: flex-start;
width: 100%;
font-size: inherit;
text-align: inherit;
line-height: inherit;
color: inherit;
background: inherit;
}
button.sidebarContainer:hover {
color: var(--sidebars-modal-color-hover);
}
div.sidebarInfo {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
padding: 8px 0;
}
+div.avatarContainer {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
+
+div.avatarOffset {
+ margin-left: 24px;
+}
+
div.longTextEllipsis {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
div.lastMessage {
display: flex;
justify-content: space-between;
column-gap: 14px;
}
div.noMessage {
text-align: center;
font-style: italic;
}
div.lastActivity {
white-space: nowrap;
}
div.unread {
color: var(--fg);
font-weight: var(--semi-bold);
}
img.sidebarArrow {
position: relative;
top: -12px;
}
diff --git a/web/modals/threads/subchannels/subchannel.react.js b/web/modals/threads/subchannels/subchannel.react.js
index b2dc9ea75..8ecd3aa5d 100644
--- a/web/modals/threads/subchannels/subchannel.react.js
+++ b/web/modals/threads/subchannels/subchannel.react.js
@@ -1,88 +1,89 @@
// @flow
import classNames from 'classnames';
import * as React from 'react';
import { useModalContext } from 'lib/components/modal-provider.react.js';
-import SWMansionIcon from 'lib/components/SWMansionIcon.react.js';
import { type ChatThreadItem } from 'lib/selectors/chat-selectors.js';
import { useMessagePreview } from 'lib/shared/message-utils.js';
import { shortAbsoluteDate } from 'lib/utils/date-utils.js';
import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js';
import css from './subchannels-modal.css';
import Button from '../../../components/button.react.js';
+import ThreadAvatar from '../../../components/thread-avatar.react.js';
import { getDefaultTextMessageRules } from '../../../markdown/rules.react.js';
import { useOnClickThread } from '../../../selectors/thread-selectors.js';
type Props = {
+chatThreadItem: ChatThreadItem,
};
function Subchannel(props: Props): React.Node {
const { chatThreadItem } = props;
const {
threadInfo,
mostRecentMessageInfo,
lastUpdatedTimeIncludingSidebars,
} = chatThreadItem;
const { unread } = threadInfo.currentUser;
const subchannelTitleClassName = classNames({
[css.subchannelInfo]: true,
[css.unread]: unread,
});
const { popModal } = useModalContext();
const navigateToThread = useOnClickThread(threadInfo);
const onClickThread = React.useCallback(
event => {
popModal();
navigateToThread(event);
},
[popModal, navigateToThread],
);
const lastActivity = React.useMemo(
() => shortAbsoluteDate(lastUpdatedTimeIncludingSidebars),
[lastUpdatedTimeIncludingSidebars],
);
const messagePreviewResult = useMessagePreview(
mostRecentMessageInfo,
threadInfo,
getDefaultTextMessageRules().simpleMarkdownRules,
);
const lastMessage = React.useMemo(() => {
if (!messagePreviewResult) {
return No messages
;
}
const { message, username } = messagePreviewResult;
const previewText = username
? `${username.text}: ${message.text}`
: message.text;
return (
<>
{previewText}
{lastActivity}
>
);
}, [lastActivity, messagePreviewResult]);
const { uiName } = useResolvedThreadInfo(threadInfo);
+
return (
);
}
export default Subchannel;