Use typographical quotes in no threads UI (#7713)
This commit is contained in:
parent
ec92102fe3
commit
544957bdad
5 changed files with 44 additions and 28 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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>
|
||||||
<ContextMenuButton className="mx_ThreadPanel_dropdown" inputRef={button} isExpanded={menuDisplayed} onClick={() => menuDisplayed ? closeMenu() : openMenu()}>
|
{ !empty && <>
|
||||||
{ `${_t('Show:')} ${value.label}` }
|
<ContextMenuButton className="mx_ThreadPanel_dropdown" inputRef={button} isExpanded={menuDisplayed} onClick={() => menuDisplayed ? closeMenu() : openMenu()}>
|
||||||
</ContextMenuButton>
|
{ `${_t('Show:')} ${value.label}` }
|
||||||
{ contextMenu }
|
</ContextMenuButton>
|
||||||
|
{ 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}
|
||||||
|
|
|
@ -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.",
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue