mirror of
https://github.com/Novaloop-AG/healthchat-web.git
synced 2026-11-05 22:25:36 +00:00
Merge branch 'develop' of github.com:matrix-org/matrix-react-sdk into t3chguy/dedup-icons
This commit is contained in:
@@ -50,7 +50,7 @@ test.describe("FilePanel", () => {
|
||||
test.describe("render", () => {
|
||||
test("should render empty state", async ({ page }) => {
|
||||
// Wait until the information about the empty state is rendered
|
||||
await expect(page.locator(".mx_FilePanel_empty")).toBeVisible();
|
||||
await expect(page.locator(".mx_EmptyState")).toBeVisible();
|
||||
|
||||
// Take a snapshot of RightPanel - fix https://github.com/vector-im/element-web/issues/25332
|
||||
await expect(page.locator(".mx_RightPanel")).toMatchScreenshot("empty.png");
|
||||
|
||||
@@ -35,7 +35,7 @@ test.describe("NotificationPanel", () => {
|
||||
await page.getByRole("button", { name: "Notifications" }).click();
|
||||
|
||||
// Wait until the information about the empty state is rendered
|
||||
await expect(page.locator(".mx_NotificationPanel_empty")).toBeVisible();
|
||||
await expect(page.locator(".mx_EmptyState")).toBeVisible();
|
||||
|
||||
// Take a snapshot of RightPanel
|
||||
await expect(page.locator(".mx_RightPanel")).toMatchScreenshot("empty.png");
|
||||
|
||||
@@ -104,7 +104,7 @@ test.describe("RightPanel", () => {
|
||||
|
||||
await page.getByRole("menuitem", { name: "Files" }).click();
|
||||
await expect(page.locator(".mx_FilePanel")).toBeVisible();
|
||||
await expect(page.locator(".mx_FilePanel_empty")).toBeVisible();
|
||||
await expect(page.locator(".mx_EmptyState")).toBeVisible();
|
||||
|
||||
await page.getByTestId("base-card-back-button").click();
|
||||
await checkRoomSummaryCard(page, ROOM_NAME);
|
||||
|
||||
@@ -28,7 +28,7 @@ import { randB64Bytes } from "../../utils/rand";
|
||||
// Docker tag to use for `matrixdotorg/synapse` image.
|
||||
// We target a specific digest as every now and then a Synapse update will break our CI.
|
||||
// This digest is updated by the playwright-image-updates.yaml workflow periodically.
|
||||
const DOCKER_TAG = "develop@sha256:ee66fc1ebbf15f9dde375cdb2afd544491b88b81ac3c82e6c4282bc3b7f332bc";
|
||||
const DOCKER_TAG = "develop@sha256:14ca769c834220a478a1e97df041361c6fb0a541ccb2f0666d3ce911224f5f7e";
|
||||
|
||||
async function cfgDirFromTemplate(opts: StartHomeserverOpts): Promise<Omit<HomeserverConfig, "dockerUrl">> {
|
||||
const templateDir = path.join(__dirname, "templates", opts.template);
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 71 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 70 KiB |
@@ -73,7 +73,6 @@
|
||||
@import "./structures/_MatrixChat.pcss";
|
||||
@import "./structures/_MessagePanel.pcss";
|
||||
@import "./structures/_NonUrgentToastContainer.pcss";
|
||||
@import "./structures/_NotificationPanel.pcss";
|
||||
@import "./structures/_QuickSettingsButton.pcss";
|
||||
@import "./structures/_RightPanel.pcss";
|
||||
@import "./structures/_RoomSearch.pcss";
|
||||
@@ -259,6 +258,7 @@
|
||||
@import "./views/polls/pollHistory/_PollHistory.pcss";
|
||||
@import "./views/polls/pollHistory/_PollHistoryList.pcss";
|
||||
@import "./views/right_panel/_BaseCard.pcss";
|
||||
@import "./views/right_panel/_EmptyState.pcss";
|
||||
@import "./views/right_panel/_EncryptionInfo.pcss";
|
||||
@import "./views/right_panel/_PinnedMessagesCard.pcss";
|
||||
@import "./views/right_panel/_RightPanelTabs.pcss";
|
||||
|
||||
@@ -102,7 +102,3 @@ limitations under the License.
|
||||
padding-inline-start: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_FilePanel_empty::before {
|
||||
--maskImage: url("$(res)/img/element-icons/room/files.svg"); /* See: _RightPanel.pcss */
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
.mx_NotificationPanel_empty::before {
|
||||
--maskImage: url("$(res)/img/element-icons/notifications.svg"); /* See: _RightPanel.pcss */
|
||||
}
|
||||
@@ -72,30 +72,3 @@ limitations under the License.
|
||||
order: 2;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.mx_RightPanel_empty {
|
||||
margin-right: -28px;
|
||||
|
||||
h2 {
|
||||
font-weight: 700;
|
||||
margin: 16px 0;
|
||||
}
|
||||
|
||||
h2,
|
||||
p {
|
||||
font: var(--cpd-font-body-md-regular);
|
||||
}
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
display: block;
|
||||
margin: 11px auto 29px auto;
|
||||
height: 42px;
|
||||
width: 42px;
|
||||
background-color: $header-panel-text-primary-color;
|
||||
mask-image: var(--maskImage);
|
||||
mask-repeat: no-repeat;
|
||||
mask-size: contain;
|
||||
mask-position: center;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
Copyright 2024 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
.mx_EmptyState {
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: var(--cpd-space-4x);
|
||||
text-align: center;
|
||||
|
||||
svg {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
box-sizing: border-box;
|
||||
border-radius: 8px;
|
||||
padding: var(--cpd-space-3x);
|
||||
background-color: $panel-actions;
|
||||
}
|
||||
|
||||
&::before {
|
||||
/* Bloom using magic numbers directly out of Figma */
|
||||
content: "";
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
width: 642px;
|
||||
height: 775px;
|
||||
right: -253.77px;
|
||||
top: 0;
|
||||
background: radial-gradient(49.95% 49.95% at 50% 50%, rgba(13, 189, 139, 0.12) 0%, rgba(18, 115, 235, 0) 100%);
|
||||
transform: rotate(-89.69deg);
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
@@ -106,10 +106,17 @@ limitations under the License.
|
||||
}
|
||||
|
||||
.mx_RoomView_messagePanel {
|
||||
/* To avoid the rule from being applied to .mx_ThreadPanel_empty */
|
||||
&.mx_RoomView_messageListWrapper {
|
||||
position: initial;
|
||||
}
|
||||
|
||||
.mx_RoomView_messageListWrapper {
|
||||
width: calc(100% + 6px); /* 8px - 2px */
|
||||
}
|
||||
|
||||
.mx_RoomView_empty {
|
||||
display: contents;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_RoomView_MessageList {
|
||||
@@ -168,72 +175,6 @@ limitations under the License.
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/link.svg");
|
||||
}
|
||||
|
||||
.mx_ThreadPanel_empty {
|
||||
border-radius: 8px;
|
||||
background: $background;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
padding: 20px;
|
||||
box-sizing: border-box; /* Include padding and border */
|
||||
width: 100%;
|
||||
|
||||
h2 {
|
||||
color: $primary-content;
|
||||
font-weight: var(--cpd-font-weight-semibold);
|
||||
font-size: $font-18px;
|
||||
margin-top: 24px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: $font-15px;
|
||||
color: $secondary-content;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
button {
|
||||
border: none;
|
||||
background: none;
|
||||
color: $accent;
|
||||
font-size: $font-15px;
|
||||
|
||||
&:hover,
|
||||
&:active {
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_ThreadPanel_empty_tip {
|
||||
font-size: $font-12px;
|
||||
line-height: $font-15px;
|
||||
|
||||
> b {
|
||||
font-weight: var(--cpd-font-weight-semibold);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mx_ThreadPanel_largeIcon {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
padding: 18px;
|
||||
background: $system;
|
||||
border-radius: 50%;
|
||||
|
||||
&::after {
|
||||
@mixin ThreadSummaryIcon;
|
||||
width: inherit;
|
||||
height: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_ContextualMenu_wrapper {
|
||||
.mx_ThreadPanel_Header_FilterOptionItem {
|
||||
display: flex;
|
||||
|
||||
@@ -28,6 +28,7 @@ import {
|
||||
TimelineWindow,
|
||||
} from "matrix-js-sdk/src/matrix";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { Icon as FilesIcon } from "@vector-im/compound-design-tokens/icons/files.svg";
|
||||
|
||||
import { MatrixClientPeg } from "../../MatrixClientPeg";
|
||||
import EventIndexPeg from "../../indexing/EventIndexPeg";
|
||||
@@ -40,6 +41,7 @@ import Spinner from "../views/elements/Spinner";
|
||||
import { Layout } from "../../settings/enums/Layout";
|
||||
import RoomContext, { TimelineRenderingType } from "../../contexts/RoomContext";
|
||||
import Measured from "../views/elements/Measured";
|
||||
import EmptyState from "../views/right_panel/EmptyState";
|
||||
|
||||
interface IProps {
|
||||
roomId: string;
|
||||
@@ -255,10 +257,11 @@ class FilePanel extends React.Component<IProps, IState> {
|
||||
// wrap a TimelinePanel with the jump-to-event bits turned off.
|
||||
|
||||
const emptyState = (
|
||||
<div className="mx_RightPanel_empty mx_FilePanel_empty">
|
||||
<h2>{_t("file_panel|empty_heading")}</h2>
|
||||
<p>{_t("file_panel|empty_description")}</p>
|
||||
</div>
|
||||
<EmptyState
|
||||
Icon={FilesIcon}
|
||||
title={_t("file_panel|empty_heading")}
|
||||
description={_t("file_panel|empty_description")}
|
||||
/>
|
||||
);
|
||||
|
||||
const isRoomEncrypted = this.noRoom ? false : MatrixClientPeg.safeGet().isRoomEncrypted(this.props.roomId);
|
||||
|
||||
@@ -16,6 +16,7 @@ limitations under the License.
|
||||
|
||||
import React from "react";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { Icon as NotificationsIcon } from "@vector-im/compound-design-tokens/icons/notifications.svg";
|
||||
|
||||
import { _t } from "../../languageHandler";
|
||||
import { MatrixClientPeg } from "../../MatrixClientPeg";
|
||||
@@ -26,6 +27,7 @@ import { Layout } from "../../settings/enums/Layout";
|
||||
import RoomContext, { TimelineRenderingType } from "../../contexts/RoomContext";
|
||||
import Measured from "../views/elements/Measured";
|
||||
import Heading from "../views/typography/Heading";
|
||||
import EmptyState from "../views/right_panel/EmptyState";
|
||||
|
||||
interface IProps {
|
||||
onClose(): void;
|
||||
@@ -57,10 +59,11 @@ export default class NotificationPanel extends React.PureComponent<IProps, IStat
|
||||
|
||||
public render(): React.ReactNode {
|
||||
const emptyState = (
|
||||
<div className="mx_RightPanel_empty mx_NotificationPanel_empty">
|
||||
<h2>{_t("notif_panel|empty_heading")}</h2>
|
||||
<p>{_t("notif_panel|empty_description")}</p>
|
||||
</div>
|
||||
<EmptyState
|
||||
Icon={NotificationsIcon}
|
||||
title={_t("notif_panel|empty_heading")}
|
||||
description={_t("notif_panel|empty_description")}
|
||||
/>
|
||||
);
|
||||
|
||||
let content: JSX.Element;
|
||||
|
||||
@@ -19,6 +19,7 @@ import React, { useContext, useEffect, useRef, useState } from "react";
|
||||
import { EventTimelineSet, Room, Thread } from "matrix-js-sdk/src/matrix";
|
||||
import { IconButton, Tooltip } from "@vector-im/compound-web";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { Icon as ThreadsIcon } from "@vector-im/compound-design-tokens/icons/threads.svg";
|
||||
|
||||
import { Icon as MarkAllThreadsReadIcon } from "../../../res/img/element-icons/check-all.svg";
|
||||
import BaseCard from "../views/right_panel/BaseCard";
|
||||
@@ -37,6 +38,7 @@ import { ButtonEvent } from "../views/elements/AccessibleButton";
|
||||
import Spinner from "../views/elements/Spinner";
|
||||
import Heading from "../views/typography/Heading";
|
||||
import { clearRoomNotification } from "../../utils/notifications";
|
||||
import EmptyState from "../views/right_panel/EmptyState";
|
||||
|
||||
interface IProps {
|
||||
roomId: string;
|
||||
@@ -73,8 +75,7 @@ export const ThreadPanelHeaderFilterOptionItem: React.FC<
|
||||
export const ThreadPanelHeader: React.FC<{
|
||||
filterOption: ThreadFilterType;
|
||||
setFilterOption: (filterOption: ThreadFilterType) => void;
|
||||
empty: boolean;
|
||||
}> = ({ filterOption, setFilterOption, empty }) => {
|
||||
}> = ({ filterOption, setFilterOption }) => {
|
||||
const mxClient = useMatrixClientContext();
|
||||
const roomContext = useRoomContext();
|
||||
const [menuDisplayed, button, openMenu, closeMenu] = useContextMenu<HTMLElement>();
|
||||
@@ -140,86 +141,24 @@ export const ThreadPanelHeader: React.FC<{
|
||||
<Heading size="4" className="mx_BaseCard_header_title_heading">
|
||||
{_t("common|threads")}
|
||||
</Heading>
|
||||
{!empty && (
|
||||
<>
|
||||
<Tooltip label={_t("threads|mark_all_read")}>
|
||||
<IconButton
|
||||
onClick={onMarkAllThreadsReadClick}
|
||||
aria-label={_t("threads|mark_all_read")}
|
||||
size="24px"
|
||||
>
|
||||
<MarkAllThreadsReadIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<div className="mx_ThreadPanel_vertical_separator" />
|
||||
<ContextMenuButton
|
||||
className="mx_ThreadPanel_dropdown"
|
||||
ref={button}
|
||||
isExpanded={menuDisplayed}
|
||||
onClick={(ev: ButtonEvent) => {
|
||||
openMenu();
|
||||
PosthogTrackers.trackInteraction("WebRightPanelThreadPanelFilterDropdown", ev);
|
||||
}}
|
||||
>
|
||||
{`${_t("threads|show_thread_filter")} ${value?.label}`}
|
||||
</ContextMenuButton>
|
||||
{contextMenu}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
interface EmptyThreadIProps {
|
||||
hasThreads: boolean;
|
||||
filterOption: ThreadFilterType;
|
||||
showAllThreadsCallback: () => void;
|
||||
}
|
||||
|
||||
const EmptyThread: React.FC<EmptyThreadIProps> = ({ hasThreads, filterOption, showAllThreadsCallback }) => {
|
||||
let body: JSX.Element;
|
||||
if (hasThreads) {
|
||||
body = (
|
||||
<>
|
||||
<p>
|
||||
{_t("threads|empty_has_threads_tip", {
|
||||
replyInThread: _t("action|reply_in_thread"),
|
||||
})}
|
||||
</p>
|
||||
<p>
|
||||
{/* Always display that paragraph to prevent layout shift when hiding the button */}
|
||||
{filterOption === ThreadFilterType.My ? (
|
||||
<button onClick={showAllThreadsCallback}>{_t("threads|show_all_threads")}</button>
|
||||
) : (
|
||||
<> </>
|
||||
)}
|
||||
</p>
|
||||
</>
|
||||
);
|
||||
} else {
|
||||
body = (
|
||||
<>
|
||||
<p>{_t("threads|empty_explainer")}</p>
|
||||
<p className="mx_ThreadPanel_empty_tip">
|
||||
{_t(
|
||||
"threads|empty_tip",
|
||||
{
|
||||
replyInThread: _t("action|reply_in_thread"),
|
||||
},
|
||||
{
|
||||
b: (sub) => <b>{sub}</b>,
|
||||
},
|
||||
)}
|
||||
</p>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="mx_ThreadPanel_empty">
|
||||
<div className="mx_ThreadPanel_largeIcon" />
|
||||
<h2>{_t("threads|empty_heading")}</h2>
|
||||
{body}
|
||||
<Tooltip label={_t("threads|mark_all_read")}>
|
||||
<IconButton onClick={onMarkAllThreadsReadClick} aria-label={_t("threads|mark_all_read")} size="24px">
|
||||
<MarkAllThreadsReadIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<div className="mx_ThreadPanel_vertical_separator" />
|
||||
<ContextMenuButton
|
||||
className="mx_ThreadPanel_dropdown"
|
||||
ref={button}
|
||||
isExpanded={menuDisplayed}
|
||||
onClick={(ev: ButtonEvent) => {
|
||||
openMenu();
|
||||
PosthogTrackers.trackInteraction("WebRightPanelThreadPanelFilterDropdown", ev);
|
||||
}}
|
||||
>
|
||||
{`${_t("threads|show_thread_filter")} ${value?.label}`}
|
||||
</ContextMenuButton>
|
||||
{contextMenu}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -268,11 +207,7 @@ const ThreadPanel: React.FC<IProps> = ({ roomId, onClose, permalinkCreator }) =>
|
||||
<BaseCard
|
||||
hideHeaderButtons
|
||||
header={
|
||||
<ThreadPanelHeader
|
||||
filterOption={filterOption}
|
||||
setFilterOption={setFilterOption}
|
||||
empty={!hasThreads}
|
||||
/>
|
||||
hasThreads && <ThreadPanelHeader filterOption={filterOption} setFilterOption={setFilterOption} />
|
||||
}
|
||||
id="thread-panel"
|
||||
className="mx_ThreadPanel"
|
||||
@@ -295,10 +230,12 @@ const ThreadPanel: React.FC<IProps> = ({ roomId, onClose, permalinkCreator }) =>
|
||||
timelineSet={timelineSet}
|
||||
showUrlPreview={false} // No URL previews at the threads list level
|
||||
empty={
|
||||
<EmptyThread
|
||||
hasThreads={hasThreads}
|
||||
filterOption={filterOption}
|
||||
showAllThreadsCallback={() => setFilterOption(ThreadFilterType.All)}
|
||||
<EmptyState
|
||||
Icon={ThreadsIcon}
|
||||
title={_t("threads|empty_title")}
|
||||
description={_t("threads|empty_description", {
|
||||
replyInThread: _t("action|reply_in_thread"),
|
||||
})}
|
||||
/>
|
||||
}
|
||||
alwaysShowTimestamps={true}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
Copyright 2024 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { ComponentType } from "react";
|
||||
import { Text } from "@vector-im/compound-web";
|
||||
|
||||
import { Flex } from "../../utils/Flex";
|
||||
|
||||
interface Props {
|
||||
Icon: ComponentType<React.SVGAttributes<SVGElement>>;
|
||||
title: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
const EmptyState: React.FC<Props> = ({ Icon, title, description }) => {
|
||||
return (
|
||||
<Flex className="mx_EmptyState" direction="column" gap="var(--cpd-space-4x)" align="center" justify="center">
|
||||
<Icon width="32px" height="32px" />
|
||||
<Text size="lg" weight="semibold">
|
||||
{title}
|
||||
</Text>
|
||||
<Text size="md" weight="regular">
|
||||
{description}
|
||||
</Text>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
export default EmptyState;
|
||||
@@ -3097,15 +3097,10 @@
|
||||
"one": "%(count)s odpověď",
|
||||
"other": "%(count)s odpovědí"
|
||||
},
|
||||
"empty_explainer": "Vlákna pomáhají udržovat konverzace k tématu a snadno je sledovat.",
|
||||
"empty_has_threads_tip": "Odpovědět na probíhající vlákno nebo použít \"%(replyInThread)s\", když najedete na zprávu a začnete novou.",
|
||||
"empty_heading": "Udržujte diskuse organizované pomocí vláken",
|
||||
"empty_tip": "<b>Tip:</b> Použijte \"%(replyInThread)s\" při najetí na zprávu.",
|
||||
"error_start_thread_existing_relation": "Nelze založit vlákno ve vlákně",
|
||||
"my_threads": "Moje vlákna",
|
||||
"my_threads_description": "Zobrazit všechna vlákna, kterých jste se zúčastnili",
|
||||
"open_thread": "Otevřít vlákno",
|
||||
"show_all_threads": "Zobrazit všechna vlákna",
|
||||
"show_thread_filter": "Zobrazit:"
|
||||
},
|
||||
"threads_activity_centre": {
|
||||
|
||||
@@ -3073,15 +3073,10 @@
|
||||
"one": "%(count)s Antwort",
|
||||
"other": "%(count)s Antworten"
|
||||
},
|
||||
"empty_explainer": "Threads helfen dabei, dass deine Konversationen beim Thema und leicht nachverfolgbar bleiben.",
|
||||
"empty_has_threads_tip": "Antworte auf einen Thread oder klicke bei einer Nachricht auf „%(replyInThread)s“, um einen Thread zu starten.",
|
||||
"empty_heading": "Organisiere Diskussionen mit Threads",
|
||||
"empty_tip": "<b>Tipp:</b> Nutze “%(replyInThread)s” beim Schweben über eine Nachricht.",
|
||||
"error_start_thread_existing_relation": "Du kannst keinen Thread in einem Thread starten",
|
||||
"my_threads": "Meine Threads",
|
||||
"my_threads_description": "Zeigt alle Threads, an denen du teilgenommen hast",
|
||||
"open_thread": "Thread anzeigen",
|
||||
"show_all_threads": "Alle Threads anzeigen",
|
||||
"show_thread_filter": "Zeige:"
|
||||
},
|
||||
"time": {
|
||||
|
||||
@@ -2441,14 +2441,10 @@
|
||||
"one": "%(count)s απάντηση",
|
||||
"other": "%(count)s απαντήσεις"
|
||||
},
|
||||
"empty_explainer": "Τα νήματα σας βοηθούν να οργανώνετε και να παρακολουθείτε καλύτερα τις συνομιλίες σας.",
|
||||
"empty_has_threads_tip": "Απαντήστε σε ένα νήμα εκτέλεσης που βρίσκεται σε εξέλιξη ή χρησιμοποιήστε το \"%(replyInThread)s\" όταν τοποθετείτε το δείκτη του ποντικιού πάνω από ένα μήνυμα για να ξεκινήσετε ένα νέο.",
|
||||
"empty_heading": "Διατηρήστε τις συζητήσεις οργανωμένες με νήματα",
|
||||
"error_start_thread_existing_relation": "Δεν είναι δυνατή η δημιουργία νήματος από ένα συμβάν με μια υπάρχουσα σχέση",
|
||||
"my_threads": "Τα νήματα μου",
|
||||
"my_threads_description": "Εμφανίζει όλα τα νήματα στα οποία έχετε συμμετάσχει",
|
||||
"open_thread": "Άνοιγμα νήματος",
|
||||
"show_all_threads": "Εμφάνιση όλων των νημάτων",
|
||||
"show_thread_filter": "Εμφάνισε:"
|
||||
},
|
||||
"time": {
|
||||
|
||||
@@ -3193,16 +3193,13 @@
|
||||
"one": "%(count)s reply",
|
||||
"other": "%(count)s replies"
|
||||
},
|
||||
"empty_explainer": "Threads help keep your conversations on-topic and easy to track.",
|
||||
"empty_has_threads_tip": "Reply to an ongoing thread or use “%(replyInThread)s” when hovering over a message to start a new one.",
|
||||
"empty_heading": "Keep discussions organised with threads",
|
||||
"empty_tip": "<b>Tip:</b> Use “%(replyInThread)s” when hovering over a message.",
|
||||
"empty_description": "Use “%(replyInThread)s” when hovering over a message.",
|
||||
"empty_title": "Threads help keep your conversations on-topic and easy to track.",
|
||||
"error_start_thread_existing_relation": "Can't create a thread from an event with an existing relation",
|
||||
"mark_all_read": "Mark all as read",
|
||||
"my_threads": "My threads",
|
||||
"my_threads_description": "Shows all threads you've participated in",
|
||||
"open_thread": "Open thread",
|
||||
"show_all_threads": "Show all threads",
|
||||
"show_thread_filter": "Show:"
|
||||
},
|
||||
"threads_activity_centre": {
|
||||
|
||||
@@ -2822,15 +2822,10 @@
|
||||
"one": "%(count)s respuesta",
|
||||
"other": "%(count)s respuestas"
|
||||
},
|
||||
"empty_explainer": "Los hilos ayudan a mantener tus conversaciones centradas y a que sean fáciles de seguir.",
|
||||
"empty_has_threads_tip": "Responde a un hilo en curso o usa «%(replyInThread)s» al pasar el ratón por encima de un mensaje para iniciar uno nuevo.",
|
||||
"empty_heading": "Organiza los temas de conversación en hilos",
|
||||
"empty_tip": "<b>Consejo:</b> Usa «%(replyInThread)s» mientras pasas el ratón sobre un mensaje.",
|
||||
"error_start_thread_existing_relation": "No ha sido posible crear un hilo a partir de un evento con una relación existente",
|
||||
"my_threads": "Mis hilos",
|
||||
"my_threads_description": "Ver todos los hilos en los que has participado",
|
||||
"open_thread": "Abrir hilo",
|
||||
"show_all_threads": "Ver todos los hilos",
|
||||
"show_thread_filter": "Mostrar:"
|
||||
},
|
||||
"time": {
|
||||
|
||||
@@ -3044,15 +3044,10 @@
|
||||
"one": "%(count)s vastus",
|
||||
"other": "%(count)s vastust"
|
||||
},
|
||||
"empty_explainer": "Jutulõngad aitavad hoida vestlused teemakohastena ning mugavalt loetavatena.",
|
||||
"empty_has_threads_tip": "Vasta jätkuvas jutulõngas või uue jutulõnga loomiseks kasuta „%(replyInThread)s“ valikut, mida kuvatakse hiire liigutamisel sõnumi kohal.",
|
||||
"empty_heading": "Halda vestlusi jutulõngadena",
|
||||
"empty_tip": "<b>Soovitus:</b> Sõnumi kohal avanevast valikust kasuta „%(replyInThread)s“ võimalust.",
|
||||
"error_start_thread_existing_relation": "Jutulõnga ei saa luua sõnumist, mis juba on jutulõnga osa",
|
||||
"my_threads": "Minu jutulõngad",
|
||||
"my_threads_description": "Näitab kõiki jutulõngasid, kus sa oled osalenud",
|
||||
"open_thread": "Ava jutulõng",
|
||||
"show_all_threads": "Näita kõiki jutulõngasid",
|
||||
"show_thread_filter": "Näita:"
|
||||
},
|
||||
"time": {
|
||||
|
||||
@@ -2695,12 +2695,9 @@
|
||||
"one": "%(count)s vastaus",
|
||||
"other": "%(count)s vastausta"
|
||||
},
|
||||
"empty_explainer": "Ketjut auttavat pitämään keskustelut asiayhteyteen sopivina ja helposti seurattavina.",
|
||||
"empty_heading": "Pidä keskustelut järjestyksessä ketjuissa",
|
||||
"my_threads": "Omat ketjut",
|
||||
"my_threads_description": "Näyttää kaikki ketjut, joissa olet ollut osallinen",
|
||||
"open_thread": "Avaa ketju",
|
||||
"show_all_threads": "Näytä kaikki ketjut",
|
||||
"show_thread_filter": "Näytä:"
|
||||
},
|
||||
"time": {
|
||||
|
||||
@@ -3125,16 +3125,11 @@
|
||||
"one": "%(count)s réponse",
|
||||
"other": "%(count)s réponses"
|
||||
},
|
||||
"empty_explainer": "Les fils de discussion vous permettent de recentrer vos conversations et de les rendre facile à suivre.",
|
||||
"empty_has_threads_tip": "Répondez à un fil de discussion en cours ou utilisez \"%(replyInThread)s\" lorsque vous passez la souris sur un message pour en commencer un nouveau.",
|
||||
"empty_heading": "Garde les discussions organisées à l’aide de fils de discussion",
|
||||
"empty_tip": "<b>Conseil :</b> Utilisez « %(replyInThread)s » en survolant un message.",
|
||||
"error_start_thread_existing_relation": "Impossible de créer un fil de discussion à partir d’un événement avec une relation existante",
|
||||
"mark_all_read": "Tout marquer comme lu",
|
||||
"my_threads": "Mes fils de discussion",
|
||||
"my_threads_description": "Affiche tous les fils de discussion auxquels vous avez participé",
|
||||
"open_thread": "Ouvrir le fil de discussion",
|
||||
"show_all_threads": "Afficher tous les fils de discussion",
|
||||
"show_thread_filter": "Affiche :"
|
||||
},
|
||||
"threads_activity_centre": {
|
||||
|
||||
@@ -2598,15 +2598,10 @@
|
||||
"one": "%(count)s resposta",
|
||||
"other": "%(count)s respostas"
|
||||
},
|
||||
"empty_explainer": "Os fíos axúdanche a manter as conversas no tema e facilitan o seguimento.",
|
||||
"empty_has_threads_tip": "Responde a unha conversa en curso ou usa \"%(replyInThread)s\" cando pasas por enriba dunha mensaxe co rato para iniciar unha nova.",
|
||||
"empty_heading": "Manter as conversas organizadas con fíos",
|
||||
"empty_tip": "<b>Truco:</b> Usa \"%(replyInThread)s\" ao poñerte enriba dunha mensaxe.",
|
||||
"error_start_thread_existing_relation": "Non se pode crear un tema con unha relación existente desde un evento",
|
||||
"my_threads": "As miñas conversas",
|
||||
"my_threads_description": "Mostra tódalas conversas nas que participaches",
|
||||
"open_thread": "Abrir fío",
|
||||
"show_all_threads": "Mostra tódolos temas",
|
||||
"show_thread_filter": "Mostrar:"
|
||||
},
|
||||
"time": {
|
||||
|
||||
@@ -2076,15 +2076,10 @@
|
||||
"threads": {
|
||||
"all_threads": "כל הקישורים",
|
||||
"all_threads_description": "הצג את כל הקישורים מחדר זה",
|
||||
"empty_explainer": "שרשורים עוזרים לשמור על השיחות שלכם בנושא וקל למעקב.",
|
||||
"empty_has_threads_tip": "השיבו לשרשור מתמשך או השתמשו ב-\"%(replyInThread)s\" כשאתם מרחפים מעל הודעה כדי להתחיל הודעה חדשה.",
|
||||
"empty_heading": "שימרו על דיונים מאורגנים בשרשורים",
|
||||
"empty_tip": "<b>טיפ:</b> השתמש ב-\"%(replyInThread)s\" כשאתם מרחפים מעל הודעה.",
|
||||
"error_start_thread_existing_relation": "לא ניתן ליצור שרשור מאירוע עם קשר קיים",
|
||||
"my_threads": "הקישורים שלי",
|
||||
"my_threads_description": "הצג את כל השרשורים שאתם משתתפים בהם",
|
||||
"open_thread": "פתיחת שרשור",
|
||||
"show_all_threads": "הצג את כל השרשורים",
|
||||
"show_thread_filter": "הצג:"
|
||||
},
|
||||
"time": {
|
||||
|
||||
@@ -3012,15 +3012,10 @@
|
||||
"one": "%(count)s válasz",
|
||||
"other": "%(count)s válasz"
|
||||
},
|
||||
"empty_explainer": "Az üzenetszálak segítenek a különböző témájú beszélgetések figyelemmel kísérésében.",
|
||||
"empty_has_threads_tip": "Válaszoljon egy meglévő üzenetszálban, vagy új üzenetszál indításához használja a „%(replyInThread)s” lehetőséget az üzenet sarkában megjelenő menüben.",
|
||||
"empty_heading": "Beszélgetések üzenetszálakba rendezése",
|
||||
"empty_tip": "<b>Tipp:</b> Használja a „%(replyInThread)s” lehetőséget a szöveg fölé navigálva.",
|
||||
"error_start_thread_existing_relation": "Nem lehet üzenetszálat indítani olyan eseményről ami már rendelkezik kapcsolattal",
|
||||
"my_threads": "Saját üzenetszálak",
|
||||
"my_threads_description": "Minden üzenetszál megjelenítése, amelyben részt vesz",
|
||||
"open_thread": "Üzenetszál megnyitása",
|
||||
"show_all_threads": "Minden üzenetszál megjelenítése",
|
||||
"show_thread_filter": "Megjelenítés:"
|
||||
},
|
||||
"time": {
|
||||
|
||||
@@ -3046,15 +3046,10 @@
|
||||
"one": "%(count)s balasan",
|
||||
"other": "%(count)s balasan"
|
||||
},
|
||||
"empty_explainer": "Utasan membantu membuat obrolan sesuai topik dan mudah untuk dilacak.",
|
||||
"empty_has_threads_tip": "Balas ke utasan yang sedang terjadi atau gunakan “%(replyInThread)s” ketika kursor diletakkan pada pesan untuk memulai yang baru.",
|
||||
"empty_heading": "Buat diskusi tetap teratur dengan utasan",
|
||||
"empty_tip": "<b>Tip:</b> Gunakan “%(replyInThread)s” ketika kursor di atas pesan.",
|
||||
"error_start_thread_existing_relation": "Tidak dapat membuat utasan dari sebuah peristiwa dengan relasi yang sudah ada",
|
||||
"my_threads": "Utasan saya",
|
||||
"my_threads_description": "Menampilkan semua utasan yang Anda berpartisipasi",
|
||||
"open_thread": "Buka utasan",
|
||||
"show_all_threads": "Tampilkan semua utasan",
|
||||
"show_thread_filter": "Tampilkan:"
|
||||
},
|
||||
"time": {
|
||||
|
||||
@@ -2505,12 +2505,9 @@
|
||||
"one": "%(count)s svar",
|
||||
"other": "%(count)s svör"
|
||||
},
|
||||
"empty_explainer": "Spjallþræðir hjálpa til við að halda samræðum við efnið og gerir auðveldara að rekja þær.",
|
||||
"empty_heading": "Haltu umræðum skipulögðum með spjallþráðum",
|
||||
"my_threads": "Spjallþræðirnir mínir",
|
||||
"my_threads_description": "Birtir alla spjallþræði sem þú hefur tekið þátt í",
|
||||
"open_thread": "Opna spjallþráð",
|
||||
"show_all_threads": "Birta alla spjallþræði",
|
||||
"show_thread_filter": "Sýna:"
|
||||
},
|
||||
"time": {
|
||||
|
||||
@@ -3090,15 +3090,10 @@
|
||||
"one": "%(count)s risposta",
|
||||
"other": "%(count)s risposte"
|
||||
},
|
||||
"empty_explainer": "Le conversazioni ti aiutano a tenere le tue discussioni in tema e rintracciabili.",
|
||||
"empty_has_threads_tip": "Rispondi ad una conversazione in corso o usa \"%(replyInThread)s\" passando sopra ad un messaggio per iniziarne una nuova.",
|
||||
"empty_heading": "Tieni le discussioni organizzate in conversazioni",
|
||||
"empty_tip": "<b>Consiglio:</b> usa \"%(replyInThread)s\" passando sopra un messaggio.",
|
||||
"error_start_thread_existing_relation": "Impossibile creare una conversazione da un evento con una relazione esistente",
|
||||
"my_threads": "Le mie conversazioni",
|
||||
"my_threads_description": "Mostra tutte le conversazioni a cui hai partecipato",
|
||||
"open_thread": "Apri conversazione",
|
||||
"show_all_threads": "Mostra tutte le conversazioni",
|
||||
"show_thread_filter": "Mostra:"
|
||||
},
|
||||
"threads_activity_centre": {
|
||||
|
||||
@@ -2827,15 +2827,10 @@
|
||||
"other": "%(count)s件の返信",
|
||||
"one": "%(count)s件の返信"
|
||||
},
|
||||
"empty_explainer": "スレッド機能を使うと、会話のテーマを維持したり、会話を簡単に追跡したりすることができます。",
|
||||
"empty_has_threads_tip": "既存のスレッドに返信するか、メッセージの「%(replyInThread)s」機能を使用すると新しいスレッドを開始できます。",
|
||||
"empty_heading": "スレッド機能を使って、会話をまとめましょう",
|
||||
"empty_tip": "<b>ヒント:</b>メッセージの「%(replyInThread)s」機能を使用すると新しいスレッドを開始できます。",
|
||||
"error_start_thread_existing_relation": "既存の関係のあるイベントからスレッドを作成することはできません",
|
||||
"my_threads": "自分のスレッド",
|
||||
"my_threads_description": "参加している全スレッドを表示",
|
||||
"open_thread": "スレッドを開く",
|
||||
"show_all_threads": "全てのスレッドを表示",
|
||||
"show_thread_filter": "表示:"
|
||||
},
|
||||
"time": {
|
||||
|
||||
@@ -2457,15 +2457,10 @@
|
||||
"one": "%(count)s ຕອບກັບ",
|
||||
"other": "%(count)s ຕອບກັບ"
|
||||
},
|
||||
"empty_explainer": "ກະທູ້ຊ່ວຍໃຫ້ການສົນທະນາຂອງທ່ານຢູ່ໃນຫົວຂໍ້ ແລະ ງ່າຍຕໍ່ການຕິດຕາມ.",
|
||||
"empty_has_threads_tip": "ຕອບກັບຫາກະທູ້ທີ່ກຳລັງດຳເນີນ ຫຼືໃຊ້ ຢູ່“%(replyInThread)s” ເມື່ອເລື່ອນໃສ່ຂໍ້ຄວາມເພື່ອເລີ່ມຕົ້ນອັນໃໝ່.",
|
||||
"empty_heading": "ຮັກສາການສົນທະນາທີ່ມີການຈັດລະບຽບ",
|
||||
"empty_tip": "<b>ເຄັດລັບ:</b> ໃຊ້ “%(replyInThread)s” ເມື່ອເລື່ອນໃສ່ຂໍ້ຄວາມ.",
|
||||
"error_start_thread_existing_relation": "ບໍ່ສາມາດສ້າງກະທູ້ຈາກເຫດການທີ່ມີຄວາມສໍາພັນທີ່ມີຢູ່ແລ້ວ",
|
||||
"my_threads": "ກະທູ້ຂອງຂ້ອຍ",
|
||||
"my_threads_description": "ສະແດງຫົວຂໍ້ທັງໝົດທີ່ທ່ານໄດ້ເຂົ້າຮ່ວມ",
|
||||
"open_thread": "ເປີດກະທູ້",
|
||||
"show_all_threads": "ສະແດງຫົວຂໍ້ທັງໝົດ",
|
||||
"show_thread_filter": "ສະແດງ:"
|
||||
},
|
||||
"time": {
|
||||
|
||||
@@ -2620,15 +2620,10 @@
|
||||
"one": "%(count)s reactie",
|
||||
"other": "%(count)s reacties"
|
||||
},
|
||||
"empty_explainer": "Threads helpen jou gesprekken on-topic te houden en gemakkelijk bij te houden.",
|
||||
"empty_has_threads_tip": "Reageer op een lopende thread of gebruik \"%(replyInThread)s\" wanneer je de muisaanwijzer op een bericht plaatst om een nieuwe te starten.",
|
||||
"empty_heading": "Houd threads georganiseerd",
|
||||
"empty_tip": "<b>Tip:</b> Gebruik “%(replyInThread)s” met de muiscursor boven een bericht.",
|
||||
"error_start_thread_existing_relation": "Kan geen discussie maken van een gebeurtenis met een bestaande relatie",
|
||||
"my_threads": "Mijn discussies",
|
||||
"my_threads_description": "Toon alle threads waarin je hebt bijgedragen",
|
||||
"open_thread": "Open discussie",
|
||||
"show_all_threads": "Threads weergeven",
|
||||
"show_thread_filter": "Toon:"
|
||||
},
|
||||
"time": {
|
||||
|
||||
@@ -3197,16 +3197,11 @@
|
||||
"one": "%(count)s odpowiedź",
|
||||
"other": "%(count)s odpowiedzi"
|
||||
},
|
||||
"empty_explainer": "Dzięki wątkom Twoje rozmowy są zorganizowane i łatwe do śledzenia.",
|
||||
"empty_has_threads_tip": "Odpowiedz do trwającego już wątku lub użyj “%(replyInThread)s” najeżdżając na wiadomość, aby rozpocząć nową.",
|
||||
"empty_heading": "Organizuj dyskusje za pomocą wątków",
|
||||
"empty_tip": "<b>Tip:</b> Użyj “%(replyInThread)s” najeżdżając na wiadomość.",
|
||||
"error_start_thread_existing_relation": "Nie można utworzyć wątku z wydarzenia z istniejącą relacją",
|
||||
"mark_all_read": "Oznacz wszystkie jako przeczytane",
|
||||
"my_threads": "Moje wątki",
|
||||
"my_threads_description": "Pokazuje wszystkie wątki, w których brałeś udział",
|
||||
"open_thread": "Otwórz wątek",
|
||||
"show_all_threads": "Pokaż wszystkie wątki",
|
||||
"show_thread_filter": "Pokaż:"
|
||||
},
|
||||
"threads_activity_centre": {
|
||||
|
||||
@@ -3074,15 +3074,10 @@
|
||||
"one": "%(count)s ответ",
|
||||
"other": "%(count)s ответов"
|
||||
},
|
||||
"empty_explainer": "Обсуждения помогают поддерживать и легко отслеживать тематику бесед.",
|
||||
"empty_has_threads_tip": "Ответьте в текущее обсуждение или создайте новое, наведя курсор на сообщение и нажав «%(replyInThread)s».",
|
||||
"empty_heading": "Организуйте обсуждения с помощью обсуждений",
|
||||
"empty_tip": "<b>Совет:</b> Используйте “%(replyInThread)s” при наведении курсора на сообщение.",
|
||||
"error_start_thread_existing_relation": "Невозможно создать обсуждение из события с существующей связью",
|
||||
"my_threads": "Мои обсуждения",
|
||||
"my_threads_description": "Показывает все обсуждения, в которых вы принимали участие",
|
||||
"open_thread": "Открыть ветку",
|
||||
"show_all_threads": "Показать все обсуждения",
|
||||
"show_thread_filter": "Показать:"
|
||||
},
|
||||
"time": {
|
||||
|
||||
@@ -3077,15 +3077,10 @@
|
||||
"one": "%(count)s odpoveď",
|
||||
"other": "%(count)s odpovedí"
|
||||
},
|
||||
"empty_explainer": "Vlákna pomáhajú udržiavať konverzácie v téme a uľahčujú ich sledovanie.",
|
||||
"empty_has_threads_tip": "Odpovedzte na prebiehajúce vlákno alebo použite \"%(replyInThread)s\", keď prejdete nad správu a začnete novú.",
|
||||
"empty_heading": "Udržujte diskusie organizované pomocou vlákien",
|
||||
"empty_tip": "<b>Tip:</b> Použite položku “%(replyInThread)s”, keď prejdete ponad správu.",
|
||||
"error_start_thread_existing_relation": "Nie je možné vytvoriť vlákno z udalosti s existujúcim vzťahom",
|
||||
"my_threads": "Moje vlákna",
|
||||
"my_threads_description": "Zobrazí všetky vlákna, v ktorých ste sa zúčastnili",
|
||||
"open_thread": "Otvoriť vlákno",
|
||||
"show_all_threads": "Zobraziť všetky vlákna",
|
||||
"show_thread_filter": "Zobraziť:"
|
||||
},
|
||||
"time": {
|
||||
|
||||
@@ -2894,15 +2894,10 @@
|
||||
"one": "%(count)s përgjigje",
|
||||
"other": "%(count)s përgjigje"
|
||||
},
|
||||
"empty_explainer": "Rrjedhat ndihmojnë që të mbahen bisedat tuaja brenda temës dhe të ndiqen kollaj.",
|
||||
"empty_has_threads_tip": "Përgjigjuni te një rrjedhë në zhvillim e sipër, ose përdorni “%(replyInThread)s”, kur kalohet kursori sipër një mesazhi për të filluar një të re.",
|
||||
"empty_heading": "Mbajini diskutimet të sistemuara në rrjedha",
|
||||
"empty_tip": "<b>Ndihmëz:</b> Përdorni “%(replyInThread)s”, teksa kaloni kursorin sipër një mesazhi.",
|
||||
"error_start_thread_existing_relation": "S’mund të krijohet një rrjedhë prej një akti me një marrëdhënie ekzistuese",
|
||||
"my_threads": "Rrjedhat e mia",
|
||||
"my_threads_description": "Shfaq krejt rrjedhat ku keni marrë pjesë",
|
||||
"open_thread": "Hape rrjedhën",
|
||||
"show_all_threads": "Shfaqi krejt rrjedhat",
|
||||
"show_thread_filter": "Shfaq:"
|
||||
},
|
||||
"time": {
|
||||
|
||||
@@ -3089,15 +3089,10 @@
|
||||
"one": "%(count)s svar",
|
||||
"other": "%(count)s svar"
|
||||
},
|
||||
"empty_explainer": "Trådar underlättar för att hålla konversationer till ämnet och gör dem lättare att följa.",
|
||||
"empty_has_threads_tip": "Svara i en pågående tråd eller använd \"%(replyInThread)s\" när du håller över ett meddelande för att starta en ny tråd.",
|
||||
"empty_heading": "Håll diskussioner organiserade med trådar",
|
||||
"empty_tip": "<b>Tips:</b> Välj \"%(replyInThread)s\" när du håller över ett meddelande.",
|
||||
"error_start_thread_existing_relation": "Kan inte skapa tråd från en händelse med en existerande relation",
|
||||
"my_threads": "Mina trådar",
|
||||
"my_threads_description": "Visar alla trådar du har medverkat i",
|
||||
"open_thread": "Öppna tråd",
|
||||
"show_all_threads": "Visa alla trådar",
|
||||
"show_thread_filter": "Visa:"
|
||||
},
|
||||
"threads_activity_centre": {
|
||||
|
||||
@@ -3009,15 +3009,10 @@
|
||||
"one": "%(count)s відповідь",
|
||||
"other": "%(count)s відповідей"
|
||||
},
|
||||
"empty_explainer": "Гілки допомагають підтримувати розмови за темою та за ними легко стежити.",
|
||||
"empty_has_threads_tip": "Дайте відповідь у наявну гілку, або створіть нову, навівши курсор на повідомлення й натиснувши «%(replyInThread)s».",
|
||||
"empty_heading": "Упорядкуйте обговорення за допомогою гілок",
|
||||
"empty_tip": "<b>Порада:</b> Використовуйте «%(replyInThread)s» навівши вказівник на повідомлення.",
|
||||
"error_start_thread_existing_relation": "Неможливо створити гілку з події з наявним відношенням",
|
||||
"my_threads": "Мої гілки",
|
||||
"my_threads_description": "Показує всі гілки, де ви брали участь",
|
||||
"open_thread": "Відкрити гілку",
|
||||
"show_all_threads": "Показати всі гілки",
|
||||
"show_thread_filter": "Показати:"
|
||||
},
|
||||
"time": {
|
||||
|
||||
@@ -2768,10 +2768,8 @@
|
||||
"one": "%(count)s trả lời",
|
||||
"other": "%(count)s trả lời"
|
||||
},
|
||||
"empty_heading": "Giữ các cuộc thảo luận được tổ chức với các chủ đề này",
|
||||
"my_threads": "Các chủ đề của tôi",
|
||||
"my_threads_description": "Hiển thị tất cả các chủ đề bạn đã tham gia",
|
||||
"show_all_threads": "Hiển thị tất cả chủ đề",
|
||||
"show_thread_filter": "Hiển thị:"
|
||||
},
|
||||
"time": {
|
||||
|
||||
@@ -2752,15 +2752,10 @@
|
||||
"one": "%(count)s 条回复",
|
||||
"other": "%(count)s 条回复"
|
||||
},
|
||||
"empty_explainer": "消息列帮助保持你的对话切题并易于追踪。",
|
||||
"empty_has_threads_tip": "回复进行中的消息列或当悬停在消息上时使用%(replyInThread)s来发起新的消息列。",
|
||||
"empty_heading": "用消息列使讨论井然有序",
|
||||
"empty_tip": "<b>实用提示:</b>悬停在消息上时使用“%(replyInThread)s”。",
|
||||
"error_start_thread_existing_relation": "无法从既有关系的事件创建消息列",
|
||||
"my_threads": "我的消息列",
|
||||
"my_threads_description": "显示您参与的所有消息列",
|
||||
"open_thread": "打开消息列",
|
||||
"show_all_threads": "显示所有消息列",
|
||||
"show_thread_filter": "显示:"
|
||||
},
|
||||
"time": {
|
||||
|
||||
@@ -3004,15 +3004,10 @@
|
||||
"one": "%(count)s 回覆",
|
||||
"other": "%(count)s 回覆"
|
||||
},
|
||||
"empty_explainer": "「討論串」功能可以協助您的對話不離題且易於追蹤。",
|
||||
"empty_has_threads_tip": "將滑鼠游標停留在訊息上來開始新的討論串時,回覆正在進行的討論串或使用「%(replyInThread)s」。",
|
||||
"empty_heading": "使用「討論串」功能,讓討論保持有條不紊",
|
||||
"empty_tip": "<b>秘訣:</b>在滑鼠游標停於訊息上時使用「%(replyInThread)s」。",
|
||||
"error_start_thread_existing_relation": "無法從討論串既有的關係建立活動",
|
||||
"my_threads": "我的討論串",
|
||||
"my_threads_description": "顯示您參與的所有討論串",
|
||||
"open_thread": "開啟討論串",
|
||||
"show_all_threads": "顯示所有討論串",
|
||||
"show_thread_filter": "顯示:"
|
||||
},
|
||||
"time": {
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
Copyright 2024 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import { EventTimelineSet, PendingEventOrdering, Room } from "matrix-js-sdk/src/matrix";
|
||||
import { screen, render, waitFor } from "@testing-library/react";
|
||||
import { mocked } from "jest-mock";
|
||||
|
||||
import FilePanel from "../../../src/components/structures/FilePanel";
|
||||
import ResizeNotifier from "../../../src/utils/ResizeNotifier";
|
||||
import { stubClient } from "../../test-utils";
|
||||
import { MatrixClientPeg } from "../../../src/MatrixClientPeg";
|
||||
|
||||
jest.mock("matrix-js-sdk/src/matrix", () => ({
|
||||
...jest.requireActual("matrix-js-sdk/src/matrix"),
|
||||
TimelineWindow: jest.fn().mockReturnValue({
|
||||
load: jest.fn().mockResolvedValue(null),
|
||||
getEvents: jest.fn().mockReturnValue([]),
|
||||
canPaginate: jest.fn().mockReturnValue(false),
|
||||
}),
|
||||
}));
|
||||
|
||||
describe("FilePanel", () => {
|
||||
beforeEach(() => {
|
||||
stubClient();
|
||||
});
|
||||
|
||||
it("renders empty state", async () => {
|
||||
const cli = MatrixClientPeg.safeGet();
|
||||
const room = new Room("!room:server", cli, cli.getSafeUserId(), {
|
||||
pendingEventOrdering: PendingEventOrdering.Detached,
|
||||
});
|
||||
const timelineSet = new EventTimelineSet(room);
|
||||
room.getOrCreateFilteredTimelineSet = jest.fn().mockReturnValue(timelineSet);
|
||||
mocked(cli.getRoom).mockReturnValue(room);
|
||||
|
||||
const { asFragment } = render(
|
||||
<FilePanel roomId={room.roomId} onClose={jest.fn()} resizeNotifier={new ResizeNotifier()} />,
|
||||
);
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText("No files visible in this room")).toBeInTheDocument();
|
||||
});
|
||||
expect(asFragment()).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
@@ -43,44 +43,21 @@ describe("ThreadPanel", () => {
|
||||
describe("Header", () => {
|
||||
it("expect that All filter for ThreadPanelHeader properly renders Show: All threads", () => {
|
||||
const { asFragment } = render(
|
||||
<ThreadPanelHeader
|
||||
empty={false}
|
||||
filterOption={ThreadFilterType.All}
|
||||
setFilterOption={() => undefined}
|
||||
/>,
|
||||
<ThreadPanelHeader filterOption={ThreadFilterType.All} setFilterOption={() => undefined} />,
|
||||
);
|
||||
expect(asFragment()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("expect that My filter for ThreadPanelHeader properly renders Show: My threads", () => {
|
||||
const { asFragment } = render(
|
||||
<ThreadPanelHeader
|
||||
empty={false}
|
||||
filterOption={ThreadFilterType.My}
|
||||
setFilterOption={() => undefined}
|
||||
/>,
|
||||
);
|
||||
expect(asFragment()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("matches snapshot when no threads", () => {
|
||||
const { asFragment } = render(
|
||||
<ThreadPanelHeader
|
||||
empty={true}
|
||||
filterOption={ThreadFilterType.All}
|
||||
setFilterOption={() => undefined}
|
||||
/>,
|
||||
<ThreadPanelHeader filterOption={ThreadFilterType.My} setFilterOption={() => undefined} />,
|
||||
);
|
||||
expect(asFragment()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("expect that ThreadPanelHeader properly opens a context menu when clicked on the button", () => {
|
||||
const { container } = render(
|
||||
<ThreadPanelHeader
|
||||
empty={false}
|
||||
filterOption={ThreadFilterType.All}
|
||||
setFilterOption={() => undefined}
|
||||
/>,
|
||||
<ThreadPanelHeader filterOption={ThreadFilterType.All} setFilterOption={() => undefined} />,
|
||||
);
|
||||
const found = container.querySelector(".mx_ThreadPanel_dropdown");
|
||||
expect(found).toBeTruthy();
|
||||
@@ -91,11 +68,7 @@ describe("ThreadPanel", () => {
|
||||
|
||||
it("expect that ThreadPanelHeader has the correct option selected in the context menu", () => {
|
||||
const { container } = render(
|
||||
<ThreadPanelHeader
|
||||
empty={false}
|
||||
filterOption={ThreadFilterType.All}
|
||||
setFilterOption={() => undefined}
|
||||
/>,
|
||||
<ThreadPanelHeader filterOption={ThreadFilterType.All} setFilterOption={() => undefined} />,
|
||||
);
|
||||
fireEvent.click(container.querySelector(".mx_ThreadPanel_dropdown")!);
|
||||
const found = screen.queryAllByRole("menuitemradio");
|
||||
@@ -118,11 +91,7 @@ describe("ThreadPanel", () => {
|
||||
const { container } = render(
|
||||
<RoomContext.Provider value={roomContextObject}>
|
||||
<MatrixClientContext.Provider value={mockClient}>
|
||||
<ThreadPanelHeader
|
||||
empty={false}
|
||||
filterOption={ThreadFilterType.All}
|
||||
setFilterOption={() => undefined}
|
||||
/>
|
||||
<ThreadPanelHeader filterOption={ThreadFilterType.All} setFilterOption={() => undefined} />
|
||||
</MatrixClientContext.Provider>
|
||||
</RoomContext.Provider>,
|
||||
);
|
||||
@@ -136,11 +105,7 @@ describe("ThreadPanel", () => {
|
||||
const mockClient = createTestClient();
|
||||
const { container } = render(
|
||||
<MatrixClientContext.Provider value={mockClient}>
|
||||
<ThreadPanelHeader
|
||||
empty={false}
|
||||
filterOption={ThreadFilterType.All}
|
||||
setFilterOption={() => undefined}
|
||||
/>
|
||||
<ThreadPanelHeader filterOption={ThreadFilterType.All} setFilterOption={() => undefined} />
|
||||
</MatrixClientContext.Provider>,
|
||||
);
|
||||
fireEvent.click(getByRole(container, "button", { name: "Mark all as read" }));
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`FilePanel renders empty state 1`] = `
|
||||
<DocumentFragment>
|
||||
<div
|
||||
class="mx_BaseCard mx_FilePanel"
|
||||
>
|
||||
<div
|
||||
class="mx_BaseCard_header"
|
||||
>
|
||||
<div
|
||||
class="mx_BaseCard_header_spacer"
|
||||
/>
|
||||
<button
|
||||
class="_icon-button_bh2qc_17 _subtle-bg_bh2qc_38"
|
||||
data-testid="base-card-close-button"
|
||||
role="button"
|
||||
style="--cpd-icon-button-size: 28px;"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="_indicator-icon_133tf_26"
|
||||
style="--cpd-icon-button-size: 100%;"
|
||||
>
|
||||
<div />
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="mx_RoomView_messagePanel mx_RoomView_messageListWrapper"
|
||||
>
|
||||
<div
|
||||
class="mx_RoomView_empty"
|
||||
>
|
||||
<div
|
||||
class="mx_Flex mx_EmptyState"
|
||||
style="--mx-flex-display: flex; --mx-flex-direction: column; --mx-flex-align: center; --mx-flex-justify: center; --mx-flex-gap: var(--cpd-space-4x);"
|
||||
>
|
||||
<div
|
||||
height="32px"
|
||||
width="32px"
|
||||
/>
|
||||
<p
|
||||
class="_typography_yh5dq_162 _font-body-lg-semibold_yh5dq_83"
|
||||
>
|
||||
No files visible in this room
|
||||
</p>
|
||||
<p
|
||||
class="_typography_yh5dq_162 _font-body-md-regular_yh5dq_59"
|
||||
>
|
||||
Attach files from chat or just drag and drop them anywhere in a room.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</DocumentFragment>
|
||||
`;
|
||||
@@ -95,17 +95,3 @@ exports[`ThreadPanel Header expect that ThreadPanelHeader has the correct option
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`ThreadPanel Header matches snapshot when no threads 1`] = `
|
||||
<DocumentFragment>
|
||||
<div
|
||||
class="mx_BaseCard_header_title"
|
||||
>
|
||||
<h4
|
||||
class="mx_Heading_h4 mx_BaseCard_header_title_heading"
|
||||
>
|
||||
Threads
|
||||
</h4>
|
||||
</div>
|
||||
</DocumentFragment>
|
||||
`;
|
||||
|
||||
@@ -274,6 +274,7 @@ export function createTestClient(): MatrixClient {
|
||||
matrixRTC: createStubMatrixRTC(),
|
||||
isFallbackICEServerAllowed: jest.fn().mockReturnValue(false),
|
||||
getAuthIssuer: jest.fn(),
|
||||
getOrCreateFilter: jest.fn(),
|
||||
} as unknown as MatrixClient;
|
||||
|
||||
client.reEmitter = new ReEmitter(client);
|
||||
|
||||
Reference in New Issue
Block a user