Use typographical quotes in no threads UI (#7713)

This commit is contained in:
Germain 2022-02-07 15:13:34 +00:00 committed by GitHub
parent ec92102fe3
commit 544957bdad
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 44 additions and 28 deletions

View file

@ -106,6 +106,13 @@ limitations under the License.
padding-right: 16px; padding-right: 16px;
} }
&.mx_ThreadView .mx_AutoHideScrollbar {
/* the scrollbar is 8px wide, and we want a 12px gap with the side of the
panel. Hence the magic number, 8+4=12 */
width: calc(100% - 4px);
padding-right: 4px;
}
.mx_RoomView_MessageList { .mx_RoomView_MessageList {
padding-left: 12px; padding-left: 12px;
padding-right: 0; padding-right: 0;
@ -182,6 +189,7 @@ limitations under the License.
.mx_MessageTimestamp { .mx_MessageTimestamp {
font-size: $font-12px; font-size: $font-12px;
color: $secondary-content;
} }
} }

View file

@ -793,7 +793,7 @@ $left-gutter: 64px;
.mx_ThreadInfo_threads-amount { .mx_ThreadInfo_threads-amount {
font-weight: 600; font-weight: 600;
position: relative; position: relative;
padding: 0 8px; padding: 0 12px 0 8px;
white-space: nowrap; white-space: nowrap;
} }
@ -962,7 +962,7 @@ $left-gutter: 64px;
.mx_RedactedBody, .mx_RedactedBody,
.mx_ReplyChain_wrapper { .mx_ReplyChain_wrapper {
margin-left: 36px; margin-left: 36px;
margin-right: 50px; margin-right: 8px;
.mx_EventTile_content, .mx_EventTile_content,
.mx_HiddenBody, .mx_HiddenBody,
@ -974,14 +974,12 @@ $left-gutter: 64px;
.mx_ReactionsRow { .mx_ReactionsRow {
margin-left: 36px; margin-left: 36px;
margin-right: 50px; margin-right: 8px;
} }
.mx_MessageTimestamp { .mx_MessageTimestamp {
left: auto; top: 2px !important;
right: 2px !important; width: auto;
top: 1px !important;
text-align: right;
} }
.mx_EventTile_senderDetails { .mx_EventTile_senderDetails {

View file

@ -139,22 +139,23 @@ export const ThreadPanelHeaderFilterOptionItem = ({
</MenuItemRadio>; </MenuItemRadio>;
}; };
export const ThreadPanelHeader = ({ filterOption, setFilterOption }: { export const ThreadPanelHeader = ({ filterOption, setFilterOption, empty }: {
filterOption: ThreadFilterType; filterOption: ThreadFilterType;
setFilterOption: (filterOption: ThreadFilterType) => void; setFilterOption: (filterOption: ThreadFilterType) => void;
empty: boolean;
}) => { }) => {
const [menuDisplayed, button, openMenu, closeMenu] = useContextMenu<HTMLElement>(); const [menuDisplayed, button, openMenu, closeMenu] = useContextMenu<HTMLElement>();
const options: readonly ThreadPanelHeaderOption[] = [ const options: readonly ThreadPanelHeaderOption[] = [
{
label: _t("My threads"),
description: _t("Shows all threads you've participated in"),
key: ThreadFilterType.My,
},
{ {
label: _t("All threads"), label: _t("All threads"),
description: _t('Shows all threads from current room'), description: _t('Shows all threads from current room'),
key: ThreadFilterType.All, key: ThreadFilterType.All,
}, },
{
label: _t("My threads"),
description: _t("Shows all threads you've participated in"),
key: ThreadFilterType.My,
},
]; ];
const value = options.find(option => option.key === filterOption); const value = options.find(option => option.key === filterOption);
@ -179,10 +180,12 @@ export const ThreadPanelHeader = ({ filterOption, setFilterOption }: {
</ContextMenu> : null; </ContextMenu> : null;
return <div className="mx_ThreadPanel__header"> return <div className="mx_ThreadPanel__header">
<span>{ _t("Threads") }</span> <span>{ _t("Threads") }</span>
{ !empty && <>
<ContextMenuButton className="mx_ThreadPanel_dropdown" inputRef={button} isExpanded={menuDisplayed} onClick={() => menuDisplayed ? closeMenu() : openMenu()}> <ContextMenuButton className="mx_ThreadPanel_dropdown" inputRef={button} isExpanded={menuDisplayed} onClick={() => menuDisplayed ? closeMenu() : openMenu()}>
{ `${_t('Show:')} ${value.label}` } { `${_t('Show:')} ${value.label}` }
</ContextMenuButton> </ContextMenuButton>
{ contextMenu } { contextMenu }
</> }
</div>; </div>;
}; };
@ -195,9 +198,8 @@ const EmptyThread: React.FC<EmptyThreadIProps> = ({ filterOption, showAllThreads
return <aside className="mx_ThreadPanel_empty"> return <aside className="mx_ThreadPanel_empty">
<div className="mx_ThreadPanel_largeIcon" /> <div className="mx_ThreadPanel_largeIcon" />
<h2>{ _t("Keep discussions organised with threads") }</h2> <h2>{ _t("Keep discussions organised with threads") }</h2>
<p>{ _t("Threads help you keep conversations on-topic and easily " <p>{ _t("Reply to an ongoing thread or use “Reply in thread”"
+ "track them over time. Create the first one by using the " + "when hovering over a message to start a new one.") }
+ "\"Reply in thread\" button on a message.") }
</p> </p>
<p> <p>
{ /* Always display that paragraph to prevent layout shift { /* Always display that paragraph to prevent layout shift
@ -217,6 +219,8 @@ const ThreadPanel: React.FC<IProps> = ({ roomId, onClose, permalinkCreator }) =>
const [filterOption, setFilterOption] = useState<ThreadFilterType>(ThreadFilterType.All); const [filterOption, setFilterOption] = useState<ThreadFilterType>(ThreadFilterType.All);
const ref = useRef<TimelinePanel>(); const ref = useRef<TimelinePanel>();
const [threadCount, setThreadCount] = useState(room.threads.size);
const [timelineSet, setTimelineSet] = useState<EventTimelineSet | null>(null); const [timelineSet, setTimelineSet] = useState<EventTimelineSet | null>(null);
useEffect(() => { useEffect(() => {
getThreadTimelineSet(mxClient, room, filterOption) getThreadTimelineSet(mxClient, room, filterOption)
@ -232,6 +236,7 @@ const ThreadPanel: React.FC<IProps> = ({ roomId, onClose, permalinkCreator }) =>
}); });
useEventEmitter(room, ThreadEvent.New, async (thread: Thread) => { useEventEmitter(room, ThreadEvent.New, async (thread: Thread) => {
setThreadCount(room.threads.size);
if (timelineSet) { if (timelineSet) {
const capabilities = await mxClient.getCapabilities(); const capabilities = await mxClient.getCapabilities();
const serverSupportsThreads = capabilities['io.element.thread']?.enabled; const serverSupportsThreads = capabilities['io.element.thread']?.enabled;
@ -267,7 +272,11 @@ const ThreadPanel: React.FC<IProps> = ({ roomId, onClose, permalinkCreator }) =>
showHiddenEventsInTimeline: true, showHiddenEventsInTimeline: true,
}}> }}>
<BaseCard <BaseCard
header={<ThreadPanelHeader filterOption={filterOption} setFilterOption={setFilterOption} />} header={<ThreadPanelHeader
filterOption={filterOption}
setFilterOption={setFilterOption}
empty={threadCount === 0}
/>}
className="mx_ThreadPanel" className="mx_ThreadPanel"
onClose={onClose} onClose={onClose}
withoutScrollContainer={true} withoutScrollContainer={true}

View file

@ -3159,13 +3159,13 @@
"You can add more later too, including already existing ones.": "You can add more later too, including already existing ones.", "You can add more later too, including already existing ones.": "You can add more later too, including already existing ones.",
"What projects are your team working on?": "What projects are your team working on?", "What projects are your team working on?": "What projects are your team working on?",
"We'll create rooms for each of them. You can add more later too, including already existing ones.": "We'll create rooms for each of them. You can add more later too, including already existing ones.", "We'll create rooms for each of them. You can add more later too, including already existing ones.": "We'll create rooms for each of them. You can add more later too, including already existing ones.",
"My threads": "My threads",
"Shows all threads you've participated in": "Shows all threads you've participated in",
"All threads": "All threads", "All threads": "All threads",
"Shows all threads from current room": "Shows all threads from current room", "Shows all threads from current room": "Shows all threads from current room",
"My threads": "My threads",
"Shows all threads you've participated in": "Shows all threads you've participated in",
"Show:": "Show:", "Show:": "Show:",
"Keep discussions organised with threads": "Keep discussions organised with threads", "Keep discussions organised with threads": "Keep discussions organised with threads",
"Threads help you keep conversations on-topic and easily track them over time. Create the first one by using the \"Reply in thread\" button on a message.": "Threads help you keep conversations on-topic and easily track them over time. Create the first one by using the \"Reply in thread\" button on a message.", "Reply to an ongoing thread or use “Reply in thread”when hovering over a message to start a new one.": "Reply to an ongoing thread or use “Reply in thread”when hovering over a message to start a new one.",
"Show all threads": "Show all threads", "Show all threads": "Show all threads",
"Thread": "Thread", "Thread": "Thread",
"Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.", "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.",

View file

@ -59,9 +59,10 @@ exports[`ThreadPanel Header expect that ThreadPanelHeader has the correct option
Object { Object {
"current": <div "current": <div
aria-checked="true" aria-checked="true"
class="mx_AccessibleButton mx_ThreadPanel_Header_FilterOptionItem" class="mx_AccessibleButton mx_ThreadPanel_Header_FilterOptionItem focus-visible"
data-focus-visible-added=""
role="menuitemradio" role="menuitemradio"
tabindex="-1" tabindex="0"
> >
<span> <span>
All threads All threads
@ -75,7 +76,7 @@ exports[`ThreadPanel Header expect that ThreadPanelHeader has the correct option
onClick={[Function]} onClick={[Function]}
onFocus={[Function]} onFocus={[Function]}
role="menuitemradio" role="menuitemradio"
tabIndex={-1} tabIndex={0}
> >
<div <div
aria-checked={true} aria-checked={true}
@ -85,7 +86,7 @@ exports[`ThreadPanel Header expect that ThreadPanelHeader has the correct option
onKeyDown={[Function]} onKeyDown={[Function]}
onKeyUp={[Function]} onKeyUp={[Function]}
role="menuitemradio" role="menuitemradio"
tabIndex={-1} tabIndex={0}
> >
<span> <span>
All threads All threads