mirror of
https://github.com/vector-im/element-web.git
synced 2025-12-25 11:11:31 +01:00
Merge branch 'develop' into midhun/new-memberlist
This commit is contained in:
commit
f52d7a8e20
27
Dockerfile
27
Dockerfile
@ -1,20 +1,17 @@
|
||||
# Builder
|
||||
FROM --platform=$BUILDPLATFORM node:22-bullseye as builder
|
||||
FROM --platform=$BUILDPLATFORM node:22-bullseye AS builder
|
||||
|
||||
# Support custom branch of the js-sdk. This also helps us build images of element-web develop.
|
||||
ARG USE_CUSTOM_SDKS=false
|
||||
ARG JS_SDK_REPO="https://github.com/matrix-org/matrix-js-sdk.git"
|
||||
ARG JS_SDK_BRANCH="master"
|
||||
|
||||
RUN apt-get update && apt-get install -y git dos2unix
|
||||
|
||||
WORKDIR /src
|
||||
|
||||
COPY . /src
|
||||
RUN dos2unix /src/scripts/docker-link-repos.sh && bash /src/scripts/docker-link-repos.sh
|
||||
RUN /src/scripts/docker-link-repos.sh
|
||||
RUN yarn --network-timeout=200000 install
|
||||
|
||||
RUN dos2unix /src/scripts/docker-package.sh /src/scripts/get-version-from-git.sh /src/scripts/normalize-version.sh && bash /src/scripts/docker-package.sh
|
||||
RUN /src/scripts/docker-package.sh
|
||||
|
||||
# Copy the config now so that we don't create another layer in the app image
|
||||
RUN cp /src/config.sample.json /src/webapp/config.json
|
||||
@ -24,8 +21,22 @@ FROM nginx:alpine-slim
|
||||
|
||||
COPY --from=builder /src/webapp /app
|
||||
|
||||
# Override default nginx config
|
||||
COPY /nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf
|
||||
# Override default nginx config. Templates in `/etc/nginx/templates` are passed
|
||||
# through `envsubst` by the nginx docker image entry point.
|
||||
COPY /docker/nginx-templates/* /etc/nginx/templates/
|
||||
|
||||
# Tell nginx to put its pidfile elsewhere, so it can run as non-root
|
||||
RUN sed -i -e 's,/var/run/nginx.pid,/tmp/nginx.pid,' /etc/nginx/nginx.conf
|
||||
|
||||
# nginx user must own the cache and etc directory to write cache and tweak the nginx config
|
||||
RUN chown -R nginx:0 /var/cache/nginx /etc/nginx
|
||||
RUN chmod -R g+w /var/cache/nginx /etc/nginx
|
||||
|
||||
RUN rm -rf /usr/share/nginx/html \
|
||||
&& ln -s /app /usr/share/nginx/html
|
||||
|
||||
# Run as nginx user by default
|
||||
USER nginx
|
||||
|
||||
# HTTP listen port
|
||||
ENV ELEMENT_WEB_PORT=80
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
listen ${ELEMENT_WEB_PORT};
|
||||
listen [::]:${ELEMENT_WEB_PORT};
|
||||
server_name localhost;
|
||||
|
||||
root /usr/share/nginx/html;
|
||||
@ -60,6 +60,22 @@ would be:
|
||||
docker run --rm -p 127.0.0.1:80:80 -v /etc/element-web/config.json:/app/config.json vectorim/element-web
|
||||
```
|
||||
|
||||
The Docker image is configured to run as an unprivileged (non-root) user by
|
||||
default. This should be fine on modern Docker runtimes, but binding to port 80
|
||||
on other runtimes may require root privileges. To resolve this, either run the
|
||||
image as root (`docker run --user 0`) or, better, change the port that nginx
|
||||
listens on via the `ELEMENT_WEB_PORT` environment variable.
|
||||
|
||||
The behaviour of the docker image can be customised via the following
|
||||
environment variables:
|
||||
|
||||
- `ELEMENT_WEB_PORT`
|
||||
|
||||
The port to listen on (within the docker container) for HTTP
|
||||
traffic. Defaults to `80`.
|
||||
|
||||
### Building the docker image
|
||||
|
||||
To build the image yourself:
|
||||
|
||||
```bash
|
||||
|
||||
@ -90,7 +90,7 @@
|
||||
"@types/png-chunks-extract": "^1.0.2",
|
||||
"@vector-im/compound-design-tokens": "^2.1.0",
|
||||
"@vector-im/compound-web": "^7.5.0",
|
||||
"@vector-im/matrix-wysiwyg": "2.37.13",
|
||||
"@vector-im/matrix-wysiwyg": "2.38.0",
|
||||
"@zxcvbn-ts/core": "^3.0.4",
|
||||
"@zxcvbn-ts/language-common": "^3.0.4",
|
||||
"@zxcvbn-ts/language-en": "^3.0.2",
|
||||
|
||||
@ -53,6 +53,8 @@ test.describe("Cryptography", function () {
|
||||
|
||||
// Even though Alice has seen Bob's join event, Bob may not have done so yet. Wait for the sync to arrive.
|
||||
await bob.awaitRoomMembership(testRoomId);
|
||||
|
||||
await app.client.network.setupRoute();
|
||||
});
|
||||
|
||||
test("should show the correct shield on e2e events", async ({
|
||||
|
||||
@ -25,12 +25,13 @@ test.describe("Lazy Loading", () => {
|
||||
});
|
||||
});
|
||||
|
||||
test.beforeEach(async ({ page, homeserver, user, bot }) => {
|
||||
test.beforeEach(async ({ page, homeserver, user, bot, app }) => {
|
||||
for (let i = 1; i <= 10; i++) {
|
||||
const displayName = `Charly #${i}`;
|
||||
const bot = new Bot(page, homeserver, { displayName, startClient: false, autoAcceptInvites: false });
|
||||
charlies.push(bot);
|
||||
}
|
||||
await app.client.network.setupRoute();
|
||||
});
|
||||
|
||||
const name = "Lazy Loading Test";
|
||||
|
||||
@ -13,6 +13,8 @@ import { Client } from "../../pages/client";
|
||||
import { ElementAppPage } from "../../pages/ElementAppPage";
|
||||
import { Bot } from "../../pages/bot";
|
||||
|
||||
type RoomRef = { name: string; roomId: string };
|
||||
|
||||
/**
|
||||
* Set up for pinned message tests.
|
||||
*/
|
||||
@ -47,7 +49,7 @@ export class Helpers {
|
||||
* @param room - the name of the room to send messages into
|
||||
* @param messages - the list of messages to send, these can be strings or implementations of MessageSpec like `editOf`
|
||||
*/
|
||||
async receiveMessages(room: string | { name: string }, messages: string[]) {
|
||||
async receiveMessages(room: RoomRef, messages: string[]) {
|
||||
await this.sendMessageAsClient(this.bot, room, messages);
|
||||
}
|
||||
|
||||
@ -55,9 +57,8 @@ export class Helpers {
|
||||
* Use the supplied client to send messages or perform actions as specified by
|
||||
* the supplied {@link Message} items.
|
||||
*/
|
||||
private async sendMessageAsClient(cli: Client, roomName: string | { name: string }, messages: string[]) {
|
||||
const room = await this.findRoomByName(typeof roomName === "string" ? roomName : roomName.name);
|
||||
const roomId = await room.evaluate((room) => room.roomId);
|
||||
private async sendMessageAsClient(cli: Client, room: RoomRef, messages: string[]) {
|
||||
const roomId = room.roomId;
|
||||
|
||||
for (const message of messages) {
|
||||
await cli.sendMessage(roomId, { body: message, msgtype: "m.text" });
|
||||
@ -73,22 +74,11 @@ export class Helpers {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a room by its name
|
||||
* @param roomName
|
||||
* @private
|
||||
*/
|
||||
private async findRoomByName(roomName: string) {
|
||||
return this.app.client.evaluateHandle((cli, roomName) => {
|
||||
return cli.getRooms().find((r) => r.name === roomName);
|
||||
}, roomName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the room with the supplied name.
|
||||
*/
|
||||
async goTo(room: string | { name: string }) {
|
||||
await this.app.viewRoomByName(typeof room === "string" ? room : room.name);
|
||||
async goTo(room: RoomRef) {
|
||||
await this.app.viewRoomByName(room.name);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -120,7 +120,7 @@ test.describe("Read receipts", { tag: "@mergequeue" }, () => {
|
||||
await util.assertUnread(room2, 40);
|
||||
|
||||
// When I jump to a message in the middle and page up
|
||||
await msg.jumpTo(room2.name, "x\ny\nz\nMsg0020");
|
||||
await msg.jumpTo(room2, "x\ny\nz\nMsg0020");
|
||||
await util.pageUp();
|
||||
|
||||
// Then the room is still unread
|
||||
|
||||
@ -13,6 +13,8 @@ import { Bot } from "../../pages/bot";
|
||||
import { Client } from "../../pages/client";
|
||||
import { ElementAppPage } from "../../pages/ElementAppPage";
|
||||
|
||||
type RoomRef = { name: string; roomId: string };
|
||||
|
||||
/**
|
||||
* Set up for a read receipt test:
|
||||
* - Create a user with the supplied name
|
||||
@ -22,9 +24,9 @@ import { ElementAppPage } from "../../pages/ElementAppPage";
|
||||
*/
|
||||
export const test = base.extend<{
|
||||
roomAlphaName?: string;
|
||||
roomAlpha: { name: string; roomId: string };
|
||||
roomAlpha: RoomRef;
|
||||
roomBetaName?: string;
|
||||
roomBeta: { name: string; roomId: string };
|
||||
roomBeta: RoomRef;
|
||||
msg: MessageBuilder;
|
||||
util: Helpers;
|
||||
}>({
|
||||
@ -248,12 +250,13 @@ export class MessageBuilder {
|
||||
/**
|
||||
* Find and display a message.
|
||||
*
|
||||
* @param roomName the name of the room to look inside
|
||||
* @param roomRef the ref of the room to look inside
|
||||
* @param message the content of the message to fine
|
||||
* @param includeThreads look for messages inside threads, not just the main timeline
|
||||
*/
|
||||
async jumpTo(roomName: string, message: string, includeThreads = false) {
|
||||
const room = await this.helpers.findRoomByName(roomName);
|
||||
async jumpTo(roomRef: RoomRef, message: string, includeThreads = false) {
|
||||
const room = await this.helpers.findRoomById(roomRef.roomId);
|
||||
expect(room).toBeTruthy();
|
||||
const foundMessage = await this.getMessage(room, message, includeThreads);
|
||||
const roomId = await room.evaluate((room) => room.roomId);
|
||||
const foundMessageId = await foundMessage.evaluate((ev) => ev.getId());
|
||||
@ -333,9 +336,10 @@ class Helpers {
|
||||
* Use the supplied client to send messages or perform actions as specified by
|
||||
* the supplied {@link Message} items.
|
||||
*/
|
||||
async sendMessageAsClient(cli: Client, roomName: string | { name: string }, messages: Message[]) {
|
||||
const room = await this.findRoomByName(typeof roomName === "string" ? roomName : roomName.name);
|
||||
const roomId = await room.evaluate((room) => room.roomId);
|
||||
async sendMessageAsClient(cli: Client, roomRef: RoomRef, messages: Message[]) {
|
||||
const roomId = roomRef.roomId;
|
||||
const room = await this.findRoomById(roomId);
|
||||
expect(room).toBeTruthy();
|
||||
|
||||
for (const message of messages) {
|
||||
if (typeof message === "string") {
|
||||
@ -359,7 +363,7 @@ class Helpers {
|
||||
/**
|
||||
* Open the room with the supplied name.
|
||||
*/
|
||||
async goTo(room: string | { name: string }) {
|
||||
async goTo(room: RoomRef) {
|
||||
await this.app.viewRoomByName(typeof room === "string" ? room : room.name);
|
||||
}
|
||||
|
||||
@ -423,17 +427,16 @@ class Helpers {
|
||||
});
|
||||
}
|
||||
|
||||
getRoomListTile(room: string | { name: string }) {
|
||||
const roomName = typeof room === "string" ? room : room.name;
|
||||
return this.page.getByRole("treeitem", { name: new RegExp("^" + roomName) });
|
||||
getRoomListTile(label: string) {
|
||||
return this.page.getByRole("treeitem", { name: new RegExp("^" + label) });
|
||||
}
|
||||
|
||||
/**
|
||||
* Click the "Mark as Read" context menu item on the room with the supplied name
|
||||
* in the room list.
|
||||
*/
|
||||
async markAsRead(room: string | { name: string }) {
|
||||
await this.getRoomListTile(room).click({ button: "right" });
|
||||
async markAsRead(room: RoomRef) {
|
||||
await this.getRoomListTile(room.name).click({ button: "right" });
|
||||
await this.page.getByText("Mark as read").click();
|
||||
}
|
||||
|
||||
@ -441,8 +444,8 @@ class Helpers {
|
||||
* Assert that the room with the supplied name is "read" in the room list - i.g.
|
||||
* has not dot or count of unread messages.
|
||||
*/
|
||||
async assertRead(room: string | { name: string }) {
|
||||
const tile = this.getRoomListTile(room);
|
||||
async assertRead(room: RoomRef) {
|
||||
const tile = this.getRoomListTile(room.name);
|
||||
await expect(tile.locator(".mx_NotificationBadge_dot")).not.toBeVisible();
|
||||
await expect(tile.locator(".mx_NotificationBadge_count")).not.toBeVisible();
|
||||
}
|
||||
@ -452,7 +455,7 @@ class Helpers {
|
||||
* (In practice, this just waits a short while to allow any unread marker to
|
||||
* appear, and then asserts that the room is read.)
|
||||
*/
|
||||
async assertStillRead(room: string | { name: string }) {
|
||||
async assertStillRead(room: RoomRef) {
|
||||
await this.page.waitForTimeout(200);
|
||||
await this.assertRead(room);
|
||||
}
|
||||
@ -462,8 +465,8 @@ class Helpers {
|
||||
* @param room - the name of the room to check
|
||||
* @param count - the numeric count to assert, or if "." specified then a bold/dot (no count) state is asserted
|
||||
*/
|
||||
async assertUnread(room: string | { name: string }, count: number | ".") {
|
||||
const tile = this.getRoomListTile(room);
|
||||
async assertUnread(room: RoomRef, count: number | ".") {
|
||||
const tile = this.getRoomListTile(room.name);
|
||||
if (count === ".") {
|
||||
await expect(tile.locator(".mx_NotificationBadge_dot")).toBeVisible();
|
||||
} else {
|
||||
@ -478,8 +481,8 @@ class Helpers {
|
||||
* @param room - the name of the room to check
|
||||
* @param lessThan - the number of unread messages that is too many
|
||||
*/
|
||||
async assertUnreadLessThan(room: string | { name: string }, lessThan: number) {
|
||||
const tile = this.getRoomListTile(room);
|
||||
async assertUnreadLessThan(room: RoomRef, lessThan: number) {
|
||||
const tile = this.getRoomListTile(room.name);
|
||||
// https://playwright.dev/docs/test-assertions#expectpoll
|
||||
// .toBeLessThan doesn't have a retry mechanism, so we use .poll
|
||||
await expect
|
||||
@ -496,8 +499,8 @@ class Helpers {
|
||||
* @param room - the name of the room to check
|
||||
* @param greaterThan - the number of unread messages that is too few
|
||||
*/
|
||||
async assertUnreadGreaterThan(room: string | { name: string }, greaterThan: number) {
|
||||
const tile = this.getRoomListTile(room);
|
||||
async assertUnreadGreaterThan(room: RoomRef, greaterThan: number) {
|
||||
const tile = this.getRoomListTile(room.name);
|
||||
// https://playwright.dev/docs/test-assertions#expectpoll
|
||||
// .toBeGreaterThan doesn't have a retry mechanism, so we use .poll
|
||||
await expect
|
||||
@ -531,10 +534,10 @@ class Helpers {
|
||||
});
|
||||
}
|
||||
|
||||
async findRoomByName(roomName: string): Promise<JSHandle<Room>> {
|
||||
return this.app.client.evaluateHandle((cli, roomName) => {
|
||||
return cli.getRooms().find((r) => r.name === roomName);
|
||||
}, roomName);
|
||||
async findRoomById(roomId: string): Promise<JSHandle<Room>> {
|
||||
return this.app.client.evaluateHandle((cli, roomId) => {
|
||||
return cli.getRooms().find((r) => r.roomId === roomId);
|
||||
}, roomId);
|
||||
}
|
||||
|
||||
private async getThreadListTile(rootMessage: string) {
|
||||
@ -578,7 +581,7 @@ class Helpers {
|
||||
* @param room - the name of the room to send messages into
|
||||
* @param messages - the list of messages to send, these can be strings or implementations of MessageSpec like `editOf`
|
||||
*/
|
||||
async receiveMessages(room: string | { name: string }, messages: Message[]) {
|
||||
async receiveMessages(room: RoomRef, messages: Message[]) {
|
||||
await this.sendMessageAsClient(this.bot, room, messages);
|
||||
}
|
||||
|
||||
|
||||
@ -101,7 +101,7 @@ test.describe("Read receipts", { tag: "@mergequeue" }, () => {
|
||||
await util.goTo(room1);
|
||||
|
||||
// When I read an older message in the thread
|
||||
await msg.jumpTo(room2.name, "InThread0000", true);
|
||||
await msg.jumpTo(room2, "InThread0000", true);
|
||||
|
||||
// Then the thread is still marked as unread
|
||||
await util.backToThreadsList();
|
||||
|
||||
@ -59,7 +59,7 @@ test.describe("Read receipts", { tag: "@mergequeue" }, () => {
|
||||
await util.assertUnread(room2, 30);
|
||||
|
||||
// When I jump to one of the older messages
|
||||
await msg.jumpTo(room2.name, "Msg0001");
|
||||
await msg.jumpTo(room2, "Msg0001");
|
||||
|
||||
// Then the room is still unread, but some messages were read
|
||||
await util.assertUnreadLessThan(room2, 30);
|
||||
|
||||
@ -49,7 +49,7 @@ test.describe("Read receipts", { tag: "@mergequeue" }, () => {
|
||||
await util.assertUnread(room2, 61); // Sanity
|
||||
|
||||
// When I jump to an old message and read the thread
|
||||
await msg.jumpTo(room2.name, "beforeThread0000");
|
||||
await msg.jumpTo(room2, "beforeThread0000");
|
||||
// When the thread is opened, the timeline is scrolled until the thread root reached the center
|
||||
await util.openThread("ThreadRoot");
|
||||
|
||||
|
||||
@ -196,7 +196,7 @@ test.describe("Read receipts", { tag: "@mergequeue" }, () => {
|
||||
await sendThreadedReadReceipt(app, thread1a, main1);
|
||||
|
||||
// Then the room has only one unread - the one in the thread
|
||||
await util.goTo(otherRoomName);
|
||||
await util.goTo({ name: otherRoomName, roomId: otherRoomId });
|
||||
await util.assertUnreadThread("Message 1");
|
||||
});
|
||||
|
||||
@ -214,7 +214,7 @@ test.describe("Read receipts", { tag: "@mergequeue" }, () => {
|
||||
|
||||
// Then the room has no unreads
|
||||
await expect(page.getByLabel(`${otherRoomName}`)).toBeVisible();
|
||||
await util.goTo(otherRoomName);
|
||||
await util.goTo({ name: otherRoomName, roomId: otherRoomId });
|
||||
await util.assertReadThread("Message 1");
|
||||
});
|
||||
|
||||
@ -239,7 +239,7 @@ test.describe("Read receipts", { tag: "@mergequeue" }, () => {
|
||||
// receipt is for a later event. The room should therefore be
|
||||
// read, and the thread unread.
|
||||
await expect(page.getByLabel(`${otherRoomName}`)).toBeVisible();
|
||||
await util.goTo(otherRoomName);
|
||||
await util.goTo({ name: otherRoomName, roomId: otherRoomId });
|
||||
await util.assertUnreadThread("Message 1");
|
||||
});
|
||||
|
||||
|
||||
@ -8,17 +8,57 @@ Please see LICENSE files in the repository root for full details.
|
||||
|
||||
import { Page, Request } from "@playwright/test";
|
||||
|
||||
import { test, expect } from "../../element-web-test";
|
||||
import { test as base, expect } from "../../element-web-test";
|
||||
import type { ElementAppPage } from "../../pages/ElementAppPage";
|
||||
import type { Bot } from "../../pages/bot";
|
||||
import { ProxyInstance, SlidingSyncProxy } from "../../plugins/sliding-sync-proxy";
|
||||
|
||||
const test = base.extend<{
|
||||
slidingSyncProxy: ProxyInstance;
|
||||
testRoom: { roomId: string; name: string };
|
||||
joinedBot: Bot;
|
||||
}>({
|
||||
slidingSyncProxy: async ({ context, page, homeserver }, use) => {
|
||||
const proxy = new SlidingSyncProxy(homeserver.config.dockerUrl, context);
|
||||
const proxyInstance = await proxy.start();
|
||||
const proxyAddress = `http://localhost:${proxyInstance.port}`;
|
||||
await page.addInitScript((proxyAddress) => {
|
||||
window.localStorage.setItem(
|
||||
"mx_local_settings",
|
||||
JSON.stringify({
|
||||
feature_sliding_sync_proxy_url: proxyAddress,
|
||||
}),
|
||||
);
|
||||
window.localStorage.setItem("mx_labs_feature_feature_sliding_sync", "true");
|
||||
}, proxyAddress);
|
||||
await use(proxyInstance);
|
||||
await proxy.stop();
|
||||
},
|
||||
// Ensure slidingSyncProxy is set up before the user fixture as it relies on an init script
|
||||
credentials: async ({ slidingSyncProxy, credentials }, use) => {
|
||||
await use(credentials);
|
||||
},
|
||||
testRoom: async ({ user, app }, use) => {
|
||||
const name = "Test Room";
|
||||
const roomId = await app.client.createRoom({ name });
|
||||
await use({ roomId, name });
|
||||
},
|
||||
joinedBot: async ({ app, bot, testRoom }, use) => {
|
||||
const roomId = testRoom.roomId;
|
||||
await bot.prepareClient();
|
||||
const bobUserId = await bot.evaluate((client) => client.getUserId());
|
||||
await app.client.evaluate(
|
||||
async (client, { bobUserId, roomId }) => {
|
||||
await client.invite(roomId, bobUserId);
|
||||
},
|
||||
{ bobUserId, roomId },
|
||||
);
|
||||
await bot.joinRoom(roomId);
|
||||
await use(bot);
|
||||
},
|
||||
});
|
||||
|
||||
test.describe("Sliding Sync", () => {
|
||||
let roomId: string;
|
||||
|
||||
test.beforeEach(async ({ slidingSyncProxy, page, user, app }) => {
|
||||
roomId = await app.client.createRoom({ name: "Test Room" });
|
||||
});
|
||||
|
||||
const checkOrder = async (wantOrder: string[], page: Page) => {
|
||||
await expect(page.getByRole("group", { name: "Rooms" }).locator(".mx_RoomTile_title")).toHaveText(wantOrder);
|
||||
};
|
||||
@ -32,22 +72,13 @@ test.describe("Sliding Sync", () => {
|
||||
});
|
||||
};
|
||||
|
||||
const createAndJoinBot = async (app: ElementAppPage, bot: Bot): Promise<Bot> => {
|
||||
await bot.prepareClient();
|
||||
const bobUserId = await bot.evaluate((client) => client.getUserId());
|
||||
await app.client.evaluate(
|
||||
async (client, { bobUserId, roomId }) => {
|
||||
await client.invite(roomId, bobUserId);
|
||||
},
|
||||
{ bobUserId, roomId },
|
||||
);
|
||||
await bot.joinRoom(roomId);
|
||||
return bot;
|
||||
};
|
||||
// Load the user fixture for all tests
|
||||
test.beforeEach(({ user }) => {});
|
||||
|
||||
test.skip("should render the Rooms list in reverse chronological order by default and allowing sorting A-Z", async ({
|
||||
test("should render the Rooms list in reverse chronological order by default and allowing sorting A-Z", async ({
|
||||
page,
|
||||
app,
|
||||
testRoom,
|
||||
}) => {
|
||||
// create rooms and check room names are correct
|
||||
for (const fruit of ["Apple", "Pineapple", "Orange"]) {
|
||||
@ -55,7 +86,7 @@ test.describe("Sliding Sync", () => {
|
||||
await expect(page.getByRole("treeitem", { name: fruit })).toBeVisible();
|
||||
}
|
||||
|
||||
// Check count, 3 fruits + 1 room created in beforeEach = 4
|
||||
// Check count, 3 fruits + 1 testRoom = 4
|
||||
await expect(page.locator(".mx_RoomSublist_tiles").getByRole("treeitem")).toHaveCount(4);
|
||||
await checkOrder(["Orange", "Pineapple", "Apple", "Test Room"], page);
|
||||
|
||||
@ -71,7 +102,7 @@ test.describe("Sliding Sync", () => {
|
||||
await checkOrder(["Apple", "Orange", "Pineapple", "Test Room"], page);
|
||||
});
|
||||
|
||||
test.skip("should move rooms around as new events arrive", async ({ page, app }) => {
|
||||
test("should move rooms around as new events arrive", async ({ page, app, testRoom }) => {
|
||||
// create rooms and check room names are correct
|
||||
const roomIds: string[] = [];
|
||||
for (const fruit of ["Apple", "Pineapple", "Orange"]) {
|
||||
@ -94,7 +125,7 @@ test.describe("Sliding Sync", () => {
|
||||
await checkOrder(["Pineapple", "Orange", "Apple", "Test Room"], page);
|
||||
});
|
||||
|
||||
test.skip("should not move the selected room: it should be sticky", async ({ page, app }) => {
|
||||
test("should not move the selected room: it should be sticky", async ({ page, app, testRoom }) => {
|
||||
// create rooms and check room names are correct
|
||||
const roomIds: string[] = [];
|
||||
for (const fruit of ["Apple", "Pineapple", "Orange"]) {
|
||||
@ -122,11 +153,9 @@ test.describe("Sliding Sync", () => {
|
||||
await checkOrder(["Apple", "Orange", "Pineapple", "Test Room"], page);
|
||||
});
|
||||
|
||||
test.skip("should show the right unread notifications", async ({ page, app, user, bot }) => {
|
||||
const bob = await createAndJoinBot(app, bot);
|
||||
|
||||
test.skip("should show the right unread notifications", async ({ page, user, joinedBot: bob, testRoom }) => {
|
||||
// send a message in the test room: unread notification count should increment
|
||||
await bob.sendMessage(roomId, "Hello World");
|
||||
await bob.sendMessage(testRoom.roomId, "Hello World");
|
||||
|
||||
const treeItemLocator1 = page.getByRole("treeitem", { name: "Test Room 1 unread message." });
|
||||
await expect(treeItemLocator1.locator(".mx_NotificationBadge_count")).toHaveText("1");
|
||||
@ -136,7 +165,7 @@ test.describe("Sliding Sync", () => {
|
||||
);
|
||||
|
||||
// send an @mention: highlight count (red) should be 2.
|
||||
await bob.sendMessage(roomId, `Hello ${user.displayName}`);
|
||||
await bob.sendMessage(testRoom.roomId, `Hello ${user.displayName}`);
|
||||
const treeItemLocator2 = page.getByRole("treeitem", {
|
||||
name: "Test Room 2 unread messages including mentions.",
|
||||
});
|
||||
@ -150,9 +179,8 @@ test.describe("Sliding Sync", () => {
|
||||
).not.toBeAttached();
|
||||
});
|
||||
|
||||
test.skip("should not show unread indicators", async ({ page, app, bot }) => {
|
||||
test("should not show unread indicators", async ({ page, app, joinedBot: bot, testRoom }) => {
|
||||
// TODO: for now. Later we should.
|
||||
await createAndJoinBot(app, bot);
|
||||
|
||||
// disable notifs in this room (TODO: CS API call?)
|
||||
const locator = page.getByRole("treeitem", { name: "Test Room" });
|
||||
@ -165,7 +193,7 @@ test.describe("Sliding Sync", () => {
|
||||
|
||||
await checkOrder(["Dummy", "Test Room"], page);
|
||||
|
||||
await bot.sendMessage(roomId, "Do you read me?");
|
||||
await bot.sendMessage(testRoom.roomId, "Do you read me?");
|
||||
|
||||
// wait for this message to arrive, tell by the room list resorting
|
||||
await checkOrder(["Test Room", "Dummy"], page);
|
||||
@ -178,15 +206,18 @@ test.describe("Sliding Sync", () => {
|
||||
test("should update user settings promptly", async ({ page, app }) => {
|
||||
await app.settings.openUserSettings("Preferences");
|
||||
const locator = page.locator(".mx_SettingsFlag").filter({ hasText: "Show timestamps in 12 hour format" });
|
||||
expect(locator).toBeVisible();
|
||||
expect(locator.locator(".mx_ToggleSwitch_on")).not.toBeAttached();
|
||||
await expect(locator).toBeVisible();
|
||||
await expect(locator.locator(".mx_ToggleSwitch_on")).not.toBeAttached();
|
||||
await locator.locator(".mx_ToggleSwitch_ball").click();
|
||||
expect(locator.locator(".mx_ToggleSwitch_on")).toBeAttached();
|
||||
await expect(locator.locator(".mx_ToggleSwitch_on")).toBeAttached();
|
||||
});
|
||||
|
||||
test.skip("should show and be able to accept/reject/rescind invites", async ({ page, app, bot }) => {
|
||||
await createAndJoinBot(app, bot);
|
||||
|
||||
test("should show and be able to accept/reject/rescind invites", async ({
|
||||
page,
|
||||
app,
|
||||
joinedBot: bot,
|
||||
testRoom,
|
||||
}) => {
|
||||
const clientUserId = await app.client.evaluate((client) => client.getUserId());
|
||||
|
||||
// invite bot into 3 rooms:
|
||||
@ -262,10 +293,10 @@ test.describe("Sliding Sync", () => {
|
||||
|
||||
// Regression test for a bug in SS mode, but would be useful to have in non-SS mode too.
|
||||
// This ensures we are setting RoomViewStore state correctly.
|
||||
test.skip("should clear the reply to field when swapping rooms", async ({ page, app }) => {
|
||||
test("should clear the reply to field when swapping rooms", async ({ page, app, testRoom }) => {
|
||||
await app.client.createRoom({ name: "Other Room" });
|
||||
await expect(page.getByRole("treeitem", { name: "Other Room" })).toBeVisible();
|
||||
await app.client.sendMessage(roomId, "Hello world");
|
||||
await app.client.sendMessage(testRoom.roomId, "Hello world");
|
||||
|
||||
// select the room
|
||||
await page.getByRole("treeitem", { name: "Test Room" }).click();
|
||||
@ -294,11 +325,11 @@ test.describe("Sliding Sync", () => {
|
||||
});
|
||||
|
||||
// Regression test for https://github.com/vector-im/element-web/issues/21462
|
||||
test.skip("should not cancel replies when permalinks are clicked", async ({ page, app }) => {
|
||||
test("should not cancel replies when permalinks are clicked", async ({ page, app, testRoom }) => {
|
||||
// we require a first message as you cannot click the permalink text with the avatar in the way
|
||||
await app.client.sendMessage(roomId, "First message");
|
||||
await app.client.sendMessage(roomId, "Permalink me");
|
||||
await app.client.sendMessage(roomId, "Reply to me");
|
||||
await app.client.sendMessage(testRoom.roomId, "First message");
|
||||
await app.client.sendMessage(testRoom.roomId, "Permalink me");
|
||||
await app.client.sendMessage(testRoom.roomId, "Reply to me");
|
||||
|
||||
// select the room
|
||||
await page.getByRole("treeitem", { name: "Test Room" }).click();
|
||||
@ -322,7 +353,7 @@ test.describe("Sliding Sync", () => {
|
||||
await expect(page.locator(".mx_ReplyPreview")).toBeVisible();
|
||||
});
|
||||
|
||||
test.skip("should send unsubscribe_rooms for every room switch", async ({ page, app }) => {
|
||||
test("should send unsubscribe_rooms for every room switch", async ({ page, app }) => {
|
||||
// create rooms and check room names are correct
|
||||
const roomIds: string[] = [];
|
||||
for (const fruit of ["Apple", "Pineapple", "Orange"]) {
|
||||
|
||||
@ -14,6 +14,8 @@ import { Bot } from "../../../pages/bot";
|
||||
import { Client } from "../../../pages/client";
|
||||
import { ElementAppPage } from "../../../pages/ElementAppPage";
|
||||
|
||||
type RoomRef = { name: string; roomId: string };
|
||||
|
||||
/**
|
||||
* Set up for a read receipt test:
|
||||
* - Create a user with the supplied name
|
||||
@ -181,9 +183,10 @@ export class Helpers {
|
||||
* Use the supplied client to send messages or perform actions as specified by
|
||||
* the supplied {@link Message} items.
|
||||
*/
|
||||
async sendMessageAsClient(cli: Client, roomName: string | { name: string }, messages: Message[]) {
|
||||
const room = await this.findRoomByName(typeof roomName === "string" ? roomName : roomName.name);
|
||||
const roomId = await room.evaluate((room) => room.roomId);
|
||||
async sendMessageAsClient(cli: Client, roomRef: RoomRef, messages: Message[]) {
|
||||
const roomId = roomRef.roomId;
|
||||
const room = await this.findRoomById(roomId);
|
||||
expect(room).toBeTruthy();
|
||||
|
||||
for (const message of messages) {
|
||||
if (typeof message === "string") {
|
||||
@ -205,7 +208,7 @@ export class Helpers {
|
||||
/**
|
||||
* Open the room with the supplied name.
|
||||
*/
|
||||
async goTo(room: string | { name: string }) {
|
||||
async goTo(room: RoomRef) {
|
||||
await this.app.viewRoomByName(typeof room === "string" ? room : room.name);
|
||||
}
|
||||
|
||||
@ -220,10 +223,10 @@ export class Helpers {
|
||||
await expect(this.page.locator(".mx_ThreadView_timelinePanelWrapper")).toBeVisible();
|
||||
}
|
||||
|
||||
async findRoomByName(roomName: string): Promise<JSHandle<Room>> {
|
||||
return this.app.client.evaluateHandle((cli, roomName) => {
|
||||
return cli.getRooms().find((r) => r.name === roomName);
|
||||
}, roomName);
|
||||
async findRoomById(roomId: string): Promise<JSHandle<Room | undefined>> {
|
||||
return this.app.client.evaluateHandle((cli, roomId) => {
|
||||
return cli.getRooms().find((r) => r.roomId === roomId);
|
||||
}, roomId);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -231,7 +234,7 @@ export class Helpers {
|
||||
* @param room - the name of the room to send messages into
|
||||
* @param messages - the list of messages to send, these can be strings or implementations of MessageSpec like `editOf`
|
||||
*/
|
||||
async receiveMessages(room: string | { name: string }, messages: Message[]) {
|
||||
async receiveMessages(room: RoomRef, messages: Message[]) {
|
||||
await this.sendMessageAsClient(this.bot, room, messages);
|
||||
}
|
||||
|
||||
|
||||
@ -23,7 +23,6 @@ import { OAuthServer } from "./plugins/oauth_server";
|
||||
import { Crypto } from "./pages/crypto";
|
||||
import { Toasts } from "./pages/toasts";
|
||||
import { Bot, CreateBotOpts } from "./pages/bot";
|
||||
import { ProxyInstance, SlidingSyncProxy } from "./plugins/sliding-sync-proxy";
|
||||
import { Webserver } from "./plugins/webserver";
|
||||
|
||||
// Enable experimental service worker support
|
||||
@ -121,7 +120,6 @@ export interface Fixtures {
|
||||
uut?: Locator; // Unit Under Test, useful place to refer a prepared locator
|
||||
botCreateOpts: CreateBotOpts;
|
||||
bot: Bot;
|
||||
slidingSyncProxy: ProxyInstance;
|
||||
labsFlags: string[];
|
||||
webserver: Webserver;
|
||||
disablePresence: boolean;
|
||||
@ -258,6 +256,7 @@ export const test = base.extend<Fixtures>({
|
||||
app: async ({ page }, use) => {
|
||||
const app = new ElementAppPage(page);
|
||||
await use(app);
|
||||
await app.cleanup();
|
||||
},
|
||||
crypto: async ({ page, homeserver, request }, use) => {
|
||||
await use(new Crypto(page, homeserver, request));
|
||||
@ -281,25 +280,6 @@ export const test = base.extend<Fixtures>({
|
||||
await mailhog.stop();
|
||||
},
|
||||
|
||||
slidingSyncProxy: async ({ page, user, homeserver }, use) => {
|
||||
const proxy = new SlidingSyncProxy(homeserver.config.dockerUrl);
|
||||
const proxyInstance = await proxy.start();
|
||||
const proxyAddress = `http://localhost:${proxyInstance.port}`;
|
||||
await page.addInitScript((proxyAddress) => {
|
||||
window.localStorage.setItem(
|
||||
"mx_local_settings",
|
||||
JSON.stringify({
|
||||
feature_sliding_sync_proxy_url: proxyAddress,
|
||||
}),
|
||||
);
|
||||
window.localStorage.setItem("mx_labs_feature_feature_sliding_sync", "true");
|
||||
}, proxyAddress);
|
||||
await page.goto("/");
|
||||
await page.waitForSelector(".mx_MatrixChat", { timeout: 30000 });
|
||||
await use(proxyInstance);
|
||||
await proxy.stop();
|
||||
},
|
||||
|
||||
// eslint-disable-next-line no-empty-pattern
|
||||
webserver: async ({}, use) => {
|
||||
const webserver = new Webserver();
|
||||
|
||||
@ -37,6 +37,10 @@ export class ElementAppPage {
|
||||
return this._timeline;
|
||||
}
|
||||
|
||||
public async cleanup() {
|
||||
await this._client?.cleanup();
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the top left user menu, returning a Locator to the resulting context menu.
|
||||
*/
|
||||
|
||||
@ -52,6 +52,10 @@ export class Client {
|
||||
this.network = new Network(page, this);
|
||||
}
|
||||
|
||||
public async cleanup() {
|
||||
await this.network.destroyRoute();
|
||||
}
|
||||
|
||||
public evaluate<R, Arg, O extends MatrixClient = MatrixClient>(
|
||||
pageFunction: PageFunctionOn<O, Arg, R>,
|
||||
arg: Arg,
|
||||
@ -175,18 +179,18 @@ export class Client {
|
||||
public async createRoom(options: ICreateRoomOpts): Promise<string> {
|
||||
const client = await this.prepareClient();
|
||||
return await client.evaluate(async (cli, options) => {
|
||||
const resp = await cli.createRoom(options);
|
||||
const roomId = resp.room_id;
|
||||
const roomPromise = new Promise<void>((resolve) => {
|
||||
const onRoom = (room: Room) => {
|
||||
if (room.roomId === roomId) {
|
||||
cli.off(window.matrixcs.ClientEvent.Room, onRoom);
|
||||
resolve();
|
||||
}
|
||||
};
|
||||
cli.on(window.matrixcs.ClientEvent.Room, onRoom);
|
||||
});
|
||||
const { room_id: roomId } = await cli.createRoom(options);
|
||||
if (!cli.getRoom(roomId)) {
|
||||
await new Promise<void>((resolve) => {
|
||||
const onRoom = (room: Room) => {
|
||||
if (room.roomId === roomId) {
|
||||
cli.off(window.matrixcs.ClientEvent.Room, onRoom);
|
||||
resolve();
|
||||
}
|
||||
};
|
||||
cli.on(window.matrixcs.ClientEvent.Room, onRoom);
|
||||
});
|
||||
await roomPromise;
|
||||
}
|
||||
return roomId;
|
||||
}, options);
|
||||
|
||||
@ -6,19 +6,22 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import type { Page, Request } from "@playwright/test";
|
||||
import type { Page, Request, Route } from "@playwright/test";
|
||||
import type { Client } from "./client";
|
||||
|
||||
/**
|
||||
* Utility class to simulate offline mode by blocking all requests to the homeserver.
|
||||
* Will not affect any requests before `setupRoute` is called,
|
||||
* which happens implicitly using the goOffline/goOnline methods.
|
||||
*/
|
||||
export class Network {
|
||||
private isOffline = false;
|
||||
private readonly setupPromise: Promise<void>;
|
||||
private setupPromise?: Promise<void>;
|
||||
|
||||
constructor(
|
||||
private page: Page,
|
||||
private client: Client,
|
||||
) {
|
||||
this.setupPromise = this.setupRoute();
|
||||
}
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Checks if the request is from the client associated with this network object.
|
||||
@ -30,25 +33,47 @@ export class Network {
|
||||
return authHeader === `Bearer ${accessToken}`;
|
||||
}
|
||||
|
||||
private async setupRoute() {
|
||||
await this.page.route("**/_matrix/**", async (route) => {
|
||||
if (this.isOffline && (await this.isRequestFromOurClient(route.request()))) {
|
||||
route.abort();
|
||||
} else {
|
||||
route.continue();
|
||||
}
|
||||
});
|
||||
private handler = async (route: Route) => {
|
||||
if (this.isOffline && (await this.isRequestFromOurClient(route.request()))) {
|
||||
await route.abort();
|
||||
} else {
|
||||
await route.continue();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Intercept all /_matrix/ networking requests for client ready to continue/abort them based on offline status
|
||||
* which is set by the goOffline/goOnline methods
|
||||
*/
|
||||
public async setupRoute() {
|
||||
if (!this.setupPromise) {
|
||||
this.setupPromise = this.page.route("**/_matrix/**", this.handler);
|
||||
}
|
||||
await this.setupPromise;
|
||||
}
|
||||
|
||||
// Intercept all /_matrix/ networking requests for client and fail them
|
||||
/**
|
||||
* Cease intercepting all /_matrix/ networking requests for client
|
||||
*/
|
||||
public async destroyRoute() {
|
||||
if (!this.setupPromise) return;
|
||||
await this.page.unroute("**/_matrix/**", this.handler);
|
||||
this.setupPromise = undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reject all /_matrix/ networking requests for client
|
||||
*/
|
||||
async goOffline(): Promise<void> {
|
||||
await this.setupPromise;
|
||||
await this.setupRoute();
|
||||
this.isOffline = true;
|
||||
}
|
||||
|
||||
// Remove intercept on all /_matrix/ networking requests for this client
|
||||
/**
|
||||
* Continue all /_matrix/ networking requests for this client
|
||||
*/
|
||||
async goOnline(): Promise<void> {
|
||||
await this.setupPromise;
|
||||
await this.setupRoute();
|
||||
this.isOffline = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import type { BrowserContext, Route } from "@playwright/test";
|
||||
import { getFreePort } from "../utils/port";
|
||||
import { Docker } from "../docker";
|
||||
import { PG_PASSWORD, PostgresDocker } from "../postgres";
|
||||
@ -24,7 +25,19 @@ export class SlidingSyncProxy {
|
||||
private readonly postgresDocker = new PostgresDocker("sliding-sync");
|
||||
private instance: ProxyInstance;
|
||||
|
||||
constructor(private synapseIp: string) {}
|
||||
constructor(
|
||||
private synapseIp: string,
|
||||
private context: BrowserContext,
|
||||
) {}
|
||||
|
||||
private syncHandler = async (route: Route) => {
|
||||
if (!this.instance) return route.abort("blockedbyclient");
|
||||
|
||||
const baseUrl = `http://localhost:${this.instance.port}`;
|
||||
await route.continue({
|
||||
url: new URL(route.request().url().split("/").slice(3).join("/"), baseUrl).href,
|
||||
});
|
||||
};
|
||||
|
||||
async start(): Promise<ProxyInstance> {
|
||||
console.log(new Date(), "Starting sliding sync proxy...");
|
||||
@ -50,10 +63,13 @@ export class SlidingSyncProxy {
|
||||
console.log(new Date(), "started!");
|
||||
|
||||
this.instance = { containerId, postgresId, port };
|
||||
await this.context.route("**/_matrix/client/unstable/org.matrix.msc3575/sync*", this.syncHandler);
|
||||
return this.instance;
|
||||
}
|
||||
|
||||
async stop(): Promise<void> {
|
||||
await this.context.unroute("**/_matrix/client/unstable/org.matrix.msc3575/sync*", this.syncHandler);
|
||||
|
||||
await this.postgresDocker.stop();
|
||||
await this.proxyDocker.stop();
|
||||
console.log(new Date(), "Stopped sliding sync proxy.");
|
||||
|
||||
@ -235,7 +235,6 @@
|
||||
"oidc": {
|
||||
"error_title": "Nemohli jsme vás přihlásit",
|
||||
"generic_auth_error": "Během autentizace se něco pokazilo. Přejděte na přihlašovací stránku a zkuste to znovu.",
|
||||
"logout_redirect_warning": "Budete přesměrováni na poskytovatele ověřování vašeho serveru, kde dokončíte odhlášení.",
|
||||
"missing_or_invalid_stored_state": "Požádali jsme prohlížeč, aby si zapamatoval, který domovský server používáte k přihlášení, ale váš prohlížeč to bohužel zapomněl. Přejděte na přihlašovací stránku a zkuste to znovu."
|
||||
},
|
||||
"password_field_keep_going_prompt": "Pokračujte…",
|
||||
@ -1391,8 +1390,6 @@
|
||||
"notification_settings_beta_caption": "Představujeme jednodušší způsob, jak změnit nastavení oznámení. Přizpůsobte svůj %(brand)s přesně tak, jak se vám líbí.",
|
||||
"notification_settings_beta_title": "Nastavení oznámení",
|
||||
"notifications": "Zapnout panel oznámení v záhlaví místnosti",
|
||||
"oidc_native_flow": "Nativní autentizace OIDC",
|
||||
"oidc_native_flow_description": "⚠ VAROVÁNÍ: Experimentální. Použijte nativní ověřování OIDC, pokud je serverem podporováno.",
|
||||
"render_reaction_images": "Vykreslování vlastních obrázků v reakcích",
|
||||
"render_reaction_images_description": "Někdy se označují jako \"vlastní emoji\".",
|
||||
"report_to_moderators": "Nahlásit moderátorům",
|
||||
|
||||
@ -129,7 +129,7 @@
|
||||
"try_again": "Erneut versuchen",
|
||||
"unban": "Verbannung aufheben",
|
||||
"unignore": "Freigeben",
|
||||
"unpin": "Nicht mehr anheften",
|
||||
"unpin": "Loslösen",
|
||||
"unsubscribe": "Deabonnieren",
|
||||
"update": "Aktualisieren",
|
||||
"upgrade": "Aktualisieren",
|
||||
@ -238,7 +238,6 @@
|
||||
"oidc": {
|
||||
"error_title": "Wir konnten dich nicht anmelden",
|
||||
"generic_auth_error": "Etwas ist während der Authentifizierung schiefgelaufen. Geh zurück zur Anmeldeseite und probiere es erneut.",
|
||||
"logout_redirect_warning": "Sie werden zum Server Authentifizierungsanbieter weitergeleitet, um die Abmeldung abzuschließen.",
|
||||
"missing_or_invalid_stored_state": "Wir haben deinen Browser gebeten, sich zu merken, bei welchem Heim-Server du dich anmeldest, aber dein Browser hat dies leider vergessen. Gehe zur Anmeldeseite und versuche es erneut."
|
||||
},
|
||||
"password_field_keep_going_prompt": "Fortfahren …",
|
||||
@ -567,7 +566,7 @@
|
||||
"system_alerts": "Systembenachrichtigung",
|
||||
"theme": "Design",
|
||||
"thread": "Thema",
|
||||
"threads": "Themen",
|
||||
"threads": "Threads",
|
||||
"timeline": "Verlauf",
|
||||
"trusted": "Vertrauenswürdig",
|
||||
"unavailable": "Nicht verfügbar",
|
||||
@ -914,6 +913,9 @@
|
||||
"warning": "Wenn du die Wiederherstellungsmethode nicht gelöscht hast, kann ein Angreifer versuchen, Zugang zu deinem Konto zu bekommen. Ändere dein Passwort und richte sofort eine neue Wiederherstellungsmethode in den Einstellungen ein."
|
||||
},
|
||||
"reset_all_button": "Hast du alle Wiederherstellungsmethoden vergessen? <a>Setze sie hier zurück</a>",
|
||||
"set_up_recovery": "Wiederherstellung einrichten",
|
||||
"set_up_recovery_later": "Nicht jetzt",
|
||||
"set_up_recovery_toast_description": "Generieren Sie einen Wiederherstellungsschlüssel, damit Sie Ihren verschlüsselten Nachrichtenverlauf wiederherstellen können, falls Sie den Zugriff auf Ihre Geräte verlieren.",
|
||||
"set_up_toast_description": "Schütze dich vor dem Verlust verschlüsselter Nachrichten und Daten",
|
||||
"set_up_toast_title": "Schlüsselsicherung einrichten",
|
||||
"setup_secure_backup": {
|
||||
@ -1391,7 +1393,7 @@
|
||||
"space": "Leertaste",
|
||||
"switch_to_space": "Mit Nummer zu Leerzeichen springen",
|
||||
"toggle_hidden_events": "Sichtbarkeit versteckter Ereignisse umschalten",
|
||||
"toggle_microphone_mute": "Mikrofon an-/ausschalten",
|
||||
"toggle_microphone_mute": "Mikrofon ein-/ausschalten",
|
||||
"toggle_right_panel": "Rechtes Panel ein-/ausblenden",
|
||||
"toggle_space_panel": "Space-Panel ein/aus",
|
||||
"toggle_top_left_menu": "Menü oben links ein-/ausblenden",
|
||||
@ -1458,8 +1460,6 @@
|
||||
"notification_settings_beta_caption": "Einen einfacheren Weg um die Einstellungen für Benachrichtigungen zu ändern vorstellen. Passe Deine %(brand)s so an wie Du willst.",
|
||||
"notification_settings_beta_title": "Benachrichtigungseinstellungen",
|
||||
"notifications": "Benachrichtigungen in der Kopfleiste des Raums anschalten",
|
||||
"oidc_native_flow": "Native OIDC Authentifizierung",
|
||||
"oidc_native_flow_description": "⚠ Warnung: Experimentell. Nutze OIDC native Authentifizierung wenn dies vom Server unterstützt wird.",
|
||||
"release_announcement": "Release Ankündigung",
|
||||
"render_reaction_images": "Benutzerdefinierte Bilder in Reaktionen anzeigen",
|
||||
"render_reaction_images_description": "Werden manchmal auch als „benutzerdefinierte Emojis“ bezeichnet.",
|
||||
@ -1846,9 +1846,9 @@
|
||||
},
|
||||
"reply_thread": "Auf <link>Nachricht im Thread</link> antworten",
|
||||
"unpin_all": {
|
||||
"button": "Alle Nachrichten lösen",
|
||||
"button": "Alle Nachrichten loslösen",
|
||||
"content": "Stellen Sie sicher, dass Sie wirklich alle angehefteten Nachrichten entfernen möchten. Diese Aktion kann nicht rückgängig gemacht werden.",
|
||||
"title": "Alle Nachrichten lösen?"
|
||||
"title": "Alle Nachrichten loslösen?"
|
||||
},
|
||||
"view": "Im Nachrichtenverlauf ansehen"
|
||||
},
|
||||
@ -2032,7 +2032,7 @@
|
||||
"button_view_all": "Alle anzeigen",
|
||||
"description": "In diesem Raum sind Nachrichten angeheftet. Klicken Sie hier, um sie anzusehen.",
|
||||
"go_to_message": "Fixierte Nachrichten im Nachrichtenverlauf anzeigen.",
|
||||
"title": "<bold>%(index)s of %(length)s</bold> Angeheftete Nachrichten"
|
||||
"title": "<bold>%(index)s of %(length)s</bold> Fixierte Nachrichten"
|
||||
},
|
||||
"read_topic": "Klicke, um das Thema zu lesen",
|
||||
"rejecting": "Lehne Einladung ab …",
|
||||
@ -2417,7 +2417,7 @@
|
||||
},
|
||||
"settings": {
|
||||
"account": {
|
||||
"dialog_title": "<strong>Einstellunge:</strong> Konto",
|
||||
"dialog_title": "<strong>Einstellungen:</strong> Konto",
|
||||
"title": "Konto"
|
||||
},
|
||||
"all_rooms_home": "Alle Räume auf Startseite anzeigen",
|
||||
@ -2603,7 +2603,7 @@
|
||||
"title": "Tastatur"
|
||||
},
|
||||
"labs": {
|
||||
"dialog_title": "<strong>Einstellungen:</strong> Labore"
|
||||
"dialog_title": "<strong>Einstellungen:</strong> Labor"
|
||||
},
|
||||
"labs_mjolnir": {
|
||||
"dialog_title": "<strong>Einstellungen:</strong> Blockierte Benutzer"
|
||||
@ -2819,6 +2819,7 @@
|
||||
"inactive_sessions_list_description": "Erwäge, dich aus alten (%(inactiveAgeDays)s Tage oder mehr), nicht mehr verwendeten Sitzungen abzumelden.",
|
||||
"ip": "IP-Adresse",
|
||||
"last_activity": "Neueste Aktivität",
|
||||
"manage": "Diese Sitzung verwalten",
|
||||
"mobile_session": "Mobil-Sitzung",
|
||||
"n_sessions_selected": {
|
||||
"one": "%(count)s Sitzung ausgewählt",
|
||||
@ -3014,7 +3015,7 @@
|
||||
"topic_room_error": "Thema des Raums konnte nicht ermittelt werden: Raum kann nicht gefunden werden (%(roomId)s",
|
||||
"tovirtual": "Zum virtuellen Raum dieses Raums wechseln, sofern vorhanden",
|
||||
"tovirtual_not_found": "Kein virtueller Raum für diesen Raum",
|
||||
"unban": "Entbannt den Benutzer mit der angegebenen ID",
|
||||
"unban": "Entsperrt den Benutzer mit der angegebenen ID",
|
||||
"unflip": "Stellt ┬──┬ ノ( ゜-゜ノ) einer Klartextnachricht voran",
|
||||
"unholdcall": "Beendet das Halten des Anrufs",
|
||||
"unignore": "Benutzer freigeben und ihre neuen Nachrichten wieder anzeigen",
|
||||
@ -3413,7 +3414,7 @@
|
||||
"remove_name": "%(senderName)s hat den alten Anzeigenamen %(oldDisplayName)s entfernt",
|
||||
"set_avatar": "%(senderName)s hat das Profilbild gesetzt",
|
||||
"set_name": "%(senderName)s hat den Anzeigenamen zu %(displayName)s geändert",
|
||||
"unban": "%(senderName)s hat %(targetName)s entbannt",
|
||||
"unban": "%(senderName)s hat die Verbannung von %(targetName)s aufgehoben",
|
||||
"withdrew_invite": "%(senderName)s hat die Einladung für %(targetName)s zurückgezogen",
|
||||
"withdrew_invite_reason": "%(senderName)s hat die Einladung für %(targetName)s zurückgezogen: %(reason)s"
|
||||
},
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
"add_people": "Añadir gente",
|
||||
"apply": "Aplicar",
|
||||
"approve": "Aprobar",
|
||||
"ask_to_join": "Pedir acceso",
|
||||
"back": "Volver",
|
||||
"call": "Llamar",
|
||||
"cancel": "Cancelar",
|
||||
@ -40,6 +41,7 @@
|
||||
"create_account": "Crear cuenta",
|
||||
"decline": "Rechazar",
|
||||
"delete": "Borrar",
|
||||
"deny": "Denegar",
|
||||
"disable": "Desactivar",
|
||||
"disconnect": "Desconectarse",
|
||||
"dismiss": "Omitir",
|
||||
@ -76,10 +78,13 @@
|
||||
"new_room": "Nueva sala",
|
||||
"new_video_room": "Nueva sala de vídeo",
|
||||
"next": "Siguiente",
|
||||
"no": "No",
|
||||
"ok": "Vale",
|
||||
"open": "Abrir",
|
||||
"pause": "Pausar",
|
||||
"pin": "Fijar",
|
||||
"play": "Reproducir",
|
||||
"proceed": "Continuar",
|
||||
"quote": "Citar",
|
||||
"react": "Reaccionar",
|
||||
"refresh": "Refrescar",
|
||||
@ -389,12 +394,14 @@
|
||||
"other": "y %(count)s más…",
|
||||
"one": "y otro más…"
|
||||
},
|
||||
"android": "Android",
|
||||
"appearance": "Apariencia",
|
||||
"application": "Aplicación",
|
||||
"are_you_sure": "¿Estás seguro?",
|
||||
"attachment": "Adjunto",
|
||||
"authentication": "Autenticación",
|
||||
"avatar": "Imagen de perfil",
|
||||
"beta": "Beta",
|
||||
"camera": "Cámara",
|
||||
"cameras": "Cámaras",
|
||||
"capabilities": "Funcionalidades",
|
||||
@ -409,6 +416,7 @@
|
||||
"email_address": "Dirección de correo electrónico",
|
||||
"encrypted": "Cifrado",
|
||||
"encryption_enabled": "El cifrado está activado",
|
||||
"error": "Error",
|
||||
"faq": "Preguntas frecuentes",
|
||||
"favourites": "Favoritos",
|
||||
"feedback": "Danos tu opinión",
|
||||
@ -423,12 +431,14 @@
|
||||
"identity_server": "Servidor de identidad",
|
||||
"image": "Imagen",
|
||||
"integration_manager": "Gestor de integración",
|
||||
"ios": "iOS",
|
||||
"joined": "Te has unido",
|
||||
"labs": "Experimentos",
|
||||
"light": "Claro",
|
||||
"loading": "Cargando…",
|
||||
"location": "Ubicación",
|
||||
"low_priority": "Prioridad baja",
|
||||
"matrix": "Matrix",
|
||||
"message": "Mensaje",
|
||||
"message_layout": "Diseño del mensaje",
|
||||
"microphone": "Micrófono",
|
||||
@ -1012,7 +1022,10 @@
|
||||
"format": "Formato",
|
||||
"from_the_beginning": "Desde el principio",
|
||||
"generating_zip": "Generar un archivo ZIP",
|
||||
"html": "HTML",
|
||||
"html_title": "Datos exportados",
|
||||
"include_attachments": "Incluir archivos adjuntos",
|
||||
"json": "JSON",
|
||||
"media_omitted": "Archivo omitido",
|
||||
"media_omitted_file_size": "Archivo omitido - supera el límite de tamaño",
|
||||
"messages": "Mensajes",
|
||||
@ -1171,6 +1184,7 @@
|
||||
},
|
||||
"keyboard": {
|
||||
"activate_button": "Activar botón seleccionado",
|
||||
"alt": "Alt",
|
||||
"autocomplete_cancel": "Cancelar autocompletar",
|
||||
"autocomplete_force": "Forzar a que termine",
|
||||
"autocomplete_navigate_next": "Sugerencia siguiente",
|
||||
@ -1194,8 +1208,11 @@
|
||||
"composer_toggle_link": "Alternar enlace",
|
||||
"composer_toggle_quote": "Alternar cita",
|
||||
"composer_undo": "Deshacer edición",
|
||||
"control": "Ctrl",
|
||||
"dismiss_read_marker_and_jump_bottom": "Descartar el marcador de lectura y saltar al final",
|
||||
"end": "Fin",
|
||||
"enter": "Intro",
|
||||
"escape": "Esc",
|
||||
"go_home_view": "Ir a la vista de inicio",
|
||||
"home": "Inicio",
|
||||
"jump_first_message": "Ir al primer mensaje",
|
||||
@ -1224,6 +1241,7 @@
|
||||
"scroll_up_timeline": "Subir en la línea de tiempo",
|
||||
"search": "Buscar (si está activado)",
|
||||
"send_sticker": "Enviar una pegatina",
|
||||
"shift": "Mayús",
|
||||
"space": "Espacio",
|
||||
"switch_to_space": "Ir a un espacio por número",
|
||||
"toggle_hidden_events": "Alternar visibilidad del evento oculto",
|
||||
@ -1281,7 +1299,6 @@
|
||||
"location_share_live_description": "Implementación temporal. Las ubicaciones persisten en el historial de la sala.",
|
||||
"mjolnir": "Nuevas maneras de ignorar a otras personas",
|
||||
"msc3531_hide_messages_pending_moderation": "Permitir a los moderadores ocultar mensajes a la espera de revisión.",
|
||||
"oidc_native_flow": "Activar flujos de OIDC nativos (en desarrollo)",
|
||||
"report_to_moderators": "Denunciar ante los moderadores",
|
||||
"report_to_moderators_description": "En las salas que sean compatible con la moderación, el botón de «Denunciar» avisará a los moderadores de la sala.",
|
||||
"sliding_sync": "Modo de sincronización progresiva",
|
||||
@ -2780,8 +2797,11 @@
|
||||
"n_minutes_ago": "hace %(num)s minutos",
|
||||
"seconds_left": "%(seconds)ss restantes",
|
||||
"short_days": "%(value)s d",
|
||||
"short_days_hours_minutes_seconds": "%(days)sd %(hours)sh %(minutes)sm %(seconds)ss",
|
||||
"short_hours": "%(value)s h",
|
||||
"short_hours_minutes_seconds": "%(hours)sh %(minutes)sm %(seconds)ss",
|
||||
"short_minutes": "%(value)s min",
|
||||
"short_minutes_seconds": "%(minutes)sm %(seconds)ss",
|
||||
"short_seconds": "%(value)s s"
|
||||
},
|
||||
"timeline": {
|
||||
|
||||
@ -235,7 +235,6 @@
|
||||
"oidc": {
|
||||
"error_title": "Meil ei õnnestunud sind sisse logida",
|
||||
"generic_auth_error": "Autentimisel läks midagi valesti. Mine sisselogimise lehele ja proovi uuesti.",
|
||||
"logout_redirect_warning": "Sind suunatakse välja logimise lõpuleviimiseks ümber oma serveri autentimise teenusepakkujale.",
|
||||
"missing_or_invalid_stored_state": "Me sättisime nii, et sinu veebibrauser jätaks järgmiseks sisselogimiseks meelde sinu koduserveri, kuid kahjuks on ta selle unustanud. Palun mine sisselogimise lehele ja proovi uuesti."
|
||||
},
|
||||
"password_field_keep_going_prompt": "Jätka…",
|
||||
@ -1387,8 +1386,6 @@
|
||||
"notification_settings": "Uued teavituste seadistused",
|
||||
"notification_settings_beta_title": "Teavituste seadistused",
|
||||
"notifications": "Kasuta jututoa päises teavituste riba",
|
||||
"oidc_native_flow": "OIDC-põhine autentimine",
|
||||
"oidc_native_flow_description": "⚠ HOIATUS: Kasuta OIDC liidestust, kui server seda võimaldab (aktiivselt arendamisel).",
|
||||
"report_to_moderators": "Teata moderaatoritele",
|
||||
"report_to_moderators_description": "Kui jututoas on modereerimine kasutusel, siis nupust „Teata sisust“ avaneva vormi abil saad jututoa reegleid rikkuvast sisust teatada moderaatoritele.",
|
||||
"sliding_sync": "Järkjärgulise sünkroniseerimise režiim",
|
||||
|
||||
@ -238,7 +238,6 @@
|
||||
"oidc": {
|
||||
"error_title": "Nous n’avons pas pu vous connecter",
|
||||
"generic_auth_error": "Une erreur s’est produite lors de l’authentification. Allez à la page de connexion et réessayez.",
|
||||
"logout_redirect_warning": "Vous allez être redirigé vers le fournisseur d’authentification de votre serveur pour terminer la déconnexion.",
|
||||
"missing_or_invalid_stored_state": "Nous avons demandé à votre navigateur de mémoriser votre serveur d’accueil, mais il semble l’avoir oublié. Rendez-vous à la page de connexion et réessayez."
|
||||
},
|
||||
"password_field_keep_going_prompt": "En cours…",
|
||||
@ -1458,8 +1457,6 @@
|
||||
"notification_settings_beta_caption": "Introduit une manière plus simple de changer vos préférences de notifications. Customisez %(brand)s, comme ça vous convient.",
|
||||
"notification_settings_beta_title": "Paramètres de notification",
|
||||
"notifications": "Active le panneau de notifications dans l’en-tête du salon",
|
||||
"oidc_native_flow": "Authentification native OIDC",
|
||||
"oidc_native_flow_description": "⚠ ATTENTION : Expérimental. Utilise l’authentification OIDC native lorsqu’elle est prise en charge par le serveur.",
|
||||
"release_announcement": "Annonce de sortie",
|
||||
"render_reaction_images": "Afficher les images personnalisées des réactions",
|
||||
"render_reaction_images_description": "Parfois appelés « émojis personnalisés ».",
|
||||
|
||||
@ -229,7 +229,6 @@
|
||||
"no_hs_url_provided": "Nincs megadva a Matrix-kiszolgáló webcíme",
|
||||
"oidc": {
|
||||
"error_title": "Sajnos nem tudtuk bejelentkeztetni",
|
||||
"logout_redirect_warning": "Át lesz irányítva a kiszolgáló hitelesítésszolgáltatójához a kijelentkezés befejezéséhez.",
|
||||
"missing_or_invalid_stored_state": "A böngészőt arra kértük, hogy jegyezze meg, melyik Matrix-kiszolgálót használta a bejelentkezéshez, de sajnos a böngészője elfelejtette. Navigáljon a bejelentkezési oldalra, és próbálja újra."
|
||||
},
|
||||
"password_field_keep_going_prompt": "Így tovább…",
|
||||
|
||||
@ -229,7 +229,6 @@
|
||||
"no_hs_url_provided": "Tidak ada URL homeserver yang disediakan",
|
||||
"oidc": {
|
||||
"error_title": "Kami tidak dapat memasukkan Anda",
|
||||
"logout_redirect_warning": "Anda akan diarahkan ke penyedia autentikasi server Anda untuk menyelesaikan proses keluar.",
|
||||
"missing_or_invalid_stored_state": "Kami menanyakan browser ini untuk mengingat homeserver apa yang Anda gunakan untuk membantu Anda masuk, tetapi sayangnya browser ini melupakannya. Pergi ke halaman masuk dan coba lagi."
|
||||
},
|
||||
"password_field_keep_going_prompt": "Lanjutkan…",
|
||||
@ -1368,7 +1367,6 @@
|
||||
"notification_settings_beta_caption": "Perkenalkan cara yang lebih sederhana untuk mengubah pengaturan notifikasi Anda. Sesuaikan %(brand)s Anda, sesuai keinginan Anda.",
|
||||
"notification_settings_beta_title": "Pengaturan Notifikasi",
|
||||
"notifications": "Aktifkan panel notifikasi di tajuk ruangan",
|
||||
"oidc_native_flow": "Autentikasi asli OIDC",
|
||||
"render_reaction_images": "Render gambar khusus dalam reaksi",
|
||||
"render_reaction_images_description": "Terkadang disebut sebagai \"emoji khusus\".",
|
||||
"report_to_moderators": "Laporkan ke moderator",
|
||||
|
||||
@ -235,7 +235,6 @@
|
||||
"oidc": {
|
||||
"error_title": "Non abbiamo potuto farti accedere",
|
||||
"generic_auth_error": "Qualcosa è andato storto durante l'autenticazione. Vai alla pagina di accesso e riprova.",
|
||||
"logout_redirect_warning": "Verrai reindirizzato al fornitore di autenticazione del tuo server per completare la disconnessione.",
|
||||
"missing_or_invalid_stored_state": "Abbiamo chiesto al browser di ricordare quale homeserver usi per farti accedere, ma sfortunatamente l'ha dimenticato. Vai alla pagina di accesso e riprova."
|
||||
},
|
||||
"password_field_keep_going_prompt": "Continua…",
|
||||
@ -1390,8 +1389,6 @@
|
||||
"notification_settings_beta_caption": "Ti presentiamo un modo più semplice per modificare le impostazioni delle notifiche. Personalizza il tuo %(brand)s, proprio come piace a te.",
|
||||
"notification_settings_beta_title": "Impostazioni di notifica",
|
||||
"notifications": "Attiva il pannello delle notifiche nell'intestazione della stanza",
|
||||
"oidc_native_flow": "Autenticazione nativa OIDC",
|
||||
"oidc_native_flow_description": "⚠ ATTENZIONE: sperimentale. Usa l'autenticazione nativa OIDC se supportata dal server.",
|
||||
"render_reaction_images": "Mostra immagini personalizzate nelle reazioni",
|
||||
"render_reaction_images_description": "A volte chiamati \"emoji personalizzati\".",
|
||||
"report_to_moderators": "Segnala ai moderatori",
|
||||
|
||||
@ -238,7 +238,6 @@
|
||||
"oidc": {
|
||||
"error_title": "Nie mogliśmy Cię zalogować",
|
||||
"generic_auth_error": "Coś poszło nie tak podczas uwierzytelniania. Przejdź do strony logowania i spróbuj ponownie.",
|
||||
"logout_redirect_warning": "Zostaniesz przekierowany do dostawcy uwierzytelniania Twojego serwera w celu zakończenia wylogowania.",
|
||||
"missing_or_invalid_stored_state": "Poprosiliśmy przeglądarkę, aby zapamiętała za pomocą jakiego serwera domowego się logujesz, lecz niestety go zapomniała. Przejdź do strony logowania i spróbuj ponownie."
|
||||
},
|
||||
"password_field_keep_going_prompt": "Kontynuuj…",
|
||||
@ -918,6 +917,9 @@
|
||||
"warning": "Jeśli nie usunąłeś metody odzyskiwania, atakujący może próbować dostać się na Twoje konto. Zmień hasło konta i natychmiast ustaw nową metodę odzyskiwania w Ustawieniach."
|
||||
},
|
||||
"reset_all_button": "Zapomniałeś lub straciłeś wszystkie opcje odzyskiwania? <a>Resetuj wszystko</a>",
|
||||
"set_up_recovery": "Skonfiguruj przywracanie",
|
||||
"set_up_recovery_later": "Nie teraz",
|
||||
"set_up_recovery_toast_description": "Wygeneruj klucz przywracania, którego można użyć do przywrócenia zaszyfrowanej historii wiadomości w przypadku utraty dostępu do swoich urządzeń.",
|
||||
"set_up_toast_description": "Zabezpiecz się przed utratą dostępu do szyfrowanych wiadomości i danych",
|
||||
"set_up_toast_title": "Skonfiguruj bezpieczną kopię zapasową",
|
||||
"setup_secure_backup": {
|
||||
@ -1468,8 +1470,6 @@
|
||||
"notification_settings_beta_caption": "Przedstawiamy prostszy sposób zmiany ustawień powiadomień. Dostosuj %(brand)s wedle swojego upodobania.",
|
||||
"notification_settings_beta_title": "Ustawienia powiadomień",
|
||||
"notifications": "Włącz panel powiadomień w nagłówku pokoju.",
|
||||
"oidc_native_flow": "Uwierzytelnianie natywne OIDC",
|
||||
"oidc_native_flow_description": "⚠ OSTRZEŻENIE: Funkcja eksperymentalna. Użyj uwierzytelniania natywnego OIDC, gdy jest wspierane przez serwer.",
|
||||
"release_announcement": "Ogłoszenie o wydaniu",
|
||||
"render_reaction_images": "Renderuj niestandardowe obrazy w reakcjach",
|
||||
"render_reaction_images_description": "Czasami określane jako \"emoji niestandardowe\".",
|
||||
@ -2513,8 +2513,8 @@
|
||||
"discovery_email_empty": "Opcje odkrywania pojawią się, gdy dodasz adres e-mail.",
|
||||
"discovery_email_verification_instructions": "Zweryfikuj link w swojej skrzynce odbiorczej",
|
||||
"discovery_msisdn_empty": "Opcje odkrywania pojawią się, gdy dodasz numer telefonu.",
|
||||
"discovery_needs_terms": "Wyrażasz zgodę na warunki użytkowania serwera%(serverName)s aby pozwolić na odkrywanie Ciebie za pomocą adresu e-mail oraz numeru telefonu.",
|
||||
"discovery_needs_terms_title": "Pozwól ludziom Cię znaleźć",
|
||||
"discovery_needs_terms": "Musisz wyrazić zgodę na warunki świadczenia usług serwera (%(serverName)s), aby umożliwić odkrywanie Cię za pomocą adresu e-mail oraz numeru telefonu.",
|
||||
"discovery_needs_terms_title": "Zezwól ludziom na znalezienie Cię",
|
||||
"display_name": "Wyświetlana nazwa",
|
||||
"display_name_error": "Nie można ustawić wyświetlanej nazwy",
|
||||
"email_address_in_use": "Podany adres e-mail jest już w użyciu",
|
||||
@ -3176,7 +3176,7 @@
|
||||
"identity_server_no_terms_description_1": "Ta czynność wymaga dostępu do domyślnego serwera tożsamości <server /> do walidacji adresu e-mail, czy numeru telefonu, ale serwer nie określa warunków korzystania z usługi.",
|
||||
"identity_server_no_terms_description_2": "Kontynuj tylko wtedy, gdy ufasz właścicielowi serwera.",
|
||||
"identity_server_no_terms_title": "Serwer tożsamości nie posiada warunków użytkowania",
|
||||
"inline_intro_text": "Zaakceptuj <policyLink /> aby kontynuować:",
|
||||
"inline_intro_text": "Zaakceptuj <policyLink />, aby kontynuować:",
|
||||
"integration_manager": "Używaj botów, mostków, widżetów i zestawów naklejek",
|
||||
"intro": "Aby kontynuować, musisz zaakceptować zasady użytkowania.",
|
||||
"summary_identity_server_1": "Odnajdź innych z użyciem numeru telefonu lub adresu e-mail",
|
||||
|
||||
3993
src/i18n/strings/pt.json
Normal file
3993
src/i18n/strings/pt.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -230,7 +230,6 @@
|
||||
"oidc": {
|
||||
"error_title": "Нам не удалось войти в систему",
|
||||
"generic_auth_error": "Во время аутентификации что-то пошло не так. Перейдите на страницу входа и попробуйте еще раз.",
|
||||
"logout_redirect_warning": "Вы будете перенаправлены к поставщику аутентификации вашего сервера для завершения выхода из системы.",
|
||||
"missing_or_invalid_stored_state": "Мы попросили браузер запомнить, какой домашний сервер вы используете для входа в систему, но, к сожалению, ваш браузер забыл об этом. Перейдите на страницу входа и попробуйте ещё раз."
|
||||
},
|
||||
"password_field_keep_going_prompt": "Продолжить",
|
||||
@ -1380,8 +1379,6 @@
|
||||
"notification_settings_beta_caption": "Представляем вам более простой способ изменения настроек уведомлений. Настройте свои настройки так %(brand)s, как вам удобно.",
|
||||
"notification_settings_beta_title": "Настройки уведомлений",
|
||||
"notifications": "Включить панель уведомлений в заголовке комнаты",
|
||||
"oidc_native_flow": "Встроенная аутентификация OIDC",
|
||||
"oidc_native_flow_description": "⚠ ВНИМАНИЕ: Экспериментально. Используйте встроенную аутентификацию OIDC, если она поддерживается сервером.",
|
||||
"render_reaction_images": "Обработка пользовательских изображений в реакциях",
|
||||
"render_reaction_images_description": "Иногда их называют \"пользовательскими эмодзи\".",
|
||||
"report_to_moderators": "Пожаловаться модераторам",
|
||||
|
||||
@ -230,7 +230,6 @@
|
||||
"oidc": {
|
||||
"error_title": "Nemohli sme vás prihlásiť",
|
||||
"generic_auth_error": "Počas overenia sa niečo pokazilo. Prejdite na stránku prihlásenia a skúste to znova.",
|
||||
"logout_redirect_warning": "Na dokončenie odhlásenia budete presmerovaní na vášho poskytovateľa autentifikácie servera.",
|
||||
"missing_or_invalid_stored_state": "Požiadali sme prehliadač, aby si zapamätal, ktorý domovský server používate na prihlásenie, ale bohužiaľ váš prehliadač to zabudol. Prejdite na stránku prihlásenia a skúste to znova."
|
||||
},
|
||||
"password_field_keep_going_prompt": "Pokračujte…",
|
||||
@ -1385,8 +1384,6 @@
|
||||
"notification_settings_beta_caption": "Predstavujeme jednoduchší spôsob zmeny nastavení oznámení. Prispôsobte si svoju aplikáciu %(brand)s, presne podľa svojich predstáv.",
|
||||
"notification_settings_beta_title": "Nastavenia oznámení",
|
||||
"notifications": "Povolenie panelu oznámení v záhlaví miestnosti",
|
||||
"oidc_native_flow": "Povoliť nové natívne toky OIDC (v štádiu aktívneho vývoja)",
|
||||
"oidc_native_flow_description": "⚠ VAROVANIE: Experimentálne. Použite natívne overenie OIDC, ak je podporované serverom.",
|
||||
"render_reaction_images": "Vykresľovať vlastné obrázky v reakciách",
|
||||
"render_reaction_images_description": "Niekedy sa označujú ako „vlastné emotikony“.",
|
||||
"report_to_moderators": "Nahlásiť moderátorom",
|
||||
|
||||
@ -110,6 +110,7 @@
|
||||
"save": "Spara",
|
||||
"search": "Sök",
|
||||
"send_report": "Skicka rapport",
|
||||
"set_avatar": "Ställ in profilbild",
|
||||
"share": "Dela",
|
||||
"show": "Visa",
|
||||
"show_advanced": "Visa avancerat",
|
||||
@ -133,6 +134,7 @@
|
||||
"update": "Uppdatera",
|
||||
"upgrade": "Uppgradera",
|
||||
"upload": "Ladda upp",
|
||||
"upload_file": "Ladda upp fil",
|
||||
"verify": "Verifiera",
|
||||
"view": "Visa",
|
||||
"view_all": "Visa alla",
|
||||
@ -227,6 +229,7 @@
|
||||
},
|
||||
"misconfigured_body": "Be din %(brand)s-administratör att kolla <a>din konfiguration</a> efter felaktiga eller duplicerade poster.",
|
||||
"misconfigured_title": "Din %(brand)s är felkonfigurerad",
|
||||
"mobile_create_account_title": "Du håller på att skapa ett konto på%(hsName)s",
|
||||
"msisdn_field_description": "Andra användare kan bjuda in dig till rum med dina kontaktuppgifter",
|
||||
"msisdn_field_label": "Telefon",
|
||||
"msisdn_field_number_invalid": "Det telefonnumret ser inte korrekt ut, vänligen kolla det och försök igen",
|
||||
@ -235,7 +238,6 @@
|
||||
"oidc": {
|
||||
"error_title": "Vi kunde inte logga in dig",
|
||||
"generic_auth_error": "Något gick fel under autentiseringen. Gå till inloggningssidan och försök igen.",
|
||||
"logout_redirect_warning": "Du kommer att omdirigeras till din servers autentiseringsleverantör för att slutföra utloggningen.",
|
||||
"missing_or_invalid_stored_state": "Vi bad webbläsaren att komma ihåg vilken hemserver du använder för att logga in, men tyvärr har din webbläsare glömt det. Gå till inloggningssidan och försök igen."
|
||||
},
|
||||
"password_field_keep_going_prompt": "Fortsätter …",
|
||||
@ -245,12 +247,40 @@
|
||||
"phone_label": "Telefon",
|
||||
"phone_optional_label": "Telefon (valfritt)",
|
||||
"qr_code_login": {
|
||||
"check_code_explainer": "Detta kommer att verifiera att anslutningen till din andra enhet är säker.",
|
||||
"check_code_heading": "Ange numret som visas på din andra enhet",
|
||||
"check_code_input_label": "2-siffrig kod",
|
||||
"check_code_mismatch": "Siffrorna stämmer inte överens",
|
||||
"completing_setup": "Slutför inställning av din nya enhet",
|
||||
"error_etag_missing": "Ett oväntat fel inträffade. Detta kan bero på felkonfiguration av webbläsartillägg, proxyserver eller server.",
|
||||
"error_expired": "Inloggningen har upphört att gälla. Försök igen.",
|
||||
"error_expired_title": "Inloggningen slutfördes inte i tid",
|
||||
"error_insecure_channel_detected": "En säker anslutning kunde inte göras till den nya enheten. Dina befintliga enheter är fortfarande säkra och du behöver inte oroa dig för dem.",
|
||||
"error_insecure_channel_detected_instructions": "Vad händer nu?",
|
||||
"error_insecure_channel_detected_instructions_1": "Försök logga in på den andra enheten igen med en QR-kod om detta var ett nätverksproblem",
|
||||
"error_insecure_channel_detected_instructions_2": "Om du stöter på samma problem, prova ett annat wifi-nätverk eller använd din mobildata istället för wifi",
|
||||
"error_insecure_channel_detected_instructions_3": "Om det inte fungerar loggar du in manuellt",
|
||||
"error_insecure_channel_detected_title": "Anslutningen är inte säker",
|
||||
"error_other_device_already_signed_in": "Du behöver inte göra något mer.",
|
||||
"error_other_device_already_signed_in_title": "Din andra enhet är redan inloggad",
|
||||
"error_rate_limited": "För många försök under för kort tid. Vänta ett tag innan du försöker igen.",
|
||||
"error_unexpected": "Ett oväntade fel inträffade.",
|
||||
"scan_code_instruction": "Skanna QR-koden nedan med din andra enhet som är utloggad.",
|
||||
"scan_qr_code": "Skanna QR-kod",
|
||||
"select_qr_code": "Välj '%(scanQRCode)s'",
|
||||
"error_unexpected": "Ett oväntat fel inträffade. Begäran om att ansluta din andra enhet har avbrutits.",
|
||||
"error_unsupported_protocol": "Den här enheten stöder inte inloggning på den andra enheten med en QR-kod.",
|
||||
"error_unsupported_protocol_title": "Annan enhet är inte kompatibel",
|
||||
"error_user_cancelled": "Inloggningen avbröts på den andra enheten.",
|
||||
"error_user_cancelled_title": "Inloggningsbegäran avbröts",
|
||||
"error_user_declined": "Du eller kontoleverantören har avvisat inloggningsbegäran.",
|
||||
"error_user_declined_title": "Inloggningen nekades",
|
||||
"follow_remaining_instructions": "Följ de återstående instruktionerna",
|
||||
"open_element_other_device": "Öppna %(brand)s på din andra enhet",
|
||||
"point_the_camera": "Skanna QR-koden som visas här",
|
||||
"scan_code_instruction": "Skanna QR-koden med en annan enhet",
|
||||
"scan_qr_code": "Logga in med QR-kod",
|
||||
"security_code": "Säkerhetskod",
|
||||
"security_code_prompt": "Om du blir ombedd anger du koden nedan på din andra enhet.",
|
||||
"select_qr_code": "Välj \"%(scanQRCode)s”",
|
||||
"unsupported_explainer": "Din kontoleverantör stöder inte inloggning på en ny enhet med en QR-kod.",
|
||||
"unsupported_heading": "QR-kod stöds inte",
|
||||
"waiting_for_device": "Väntar på att enheter loggar in"
|
||||
},
|
||||
"register_action": "Skapa konto",
|
||||
@ -339,6 +369,8 @@
|
||||
"email_resend_prompt": "Fick du inte den? <a>Skicka igen</a>",
|
||||
"email_resent": "Skickade igen!",
|
||||
"fallback_button": "Starta autentisering",
|
||||
"mas_cross_signing_reset_cta": "Gå till ditt konto",
|
||||
"mas_cross_signing_reset_description": "Återställ din identitet via din kontoleverantör och kom sedan tillbaka och klicka på ”Försök igen”.",
|
||||
"msisdn": "Ett SMS har skickats till %(msisdn)s",
|
||||
"msisdn_token_incorrect": "Felaktig token",
|
||||
"msisdn_token_prompt": "Vänligen ange koden det innehåller:",
|
||||
@ -429,6 +461,7 @@
|
||||
"beta": "Beta",
|
||||
"camera": "Kamera",
|
||||
"cameras": "Kameror",
|
||||
"cancel": "Avbryt",
|
||||
"capabilities": "Förmågor",
|
||||
"copied": "Kopierat!",
|
||||
"credits": "Medverkande",
|
||||
@ -470,6 +503,7 @@
|
||||
"matrix": "Matrix",
|
||||
"message": "Meddelande",
|
||||
"message_layout": "Meddelandearrangemang",
|
||||
"message_timestamp_invalid": "Ogiltig tidsstämpel",
|
||||
"microphone": "Mikrofon",
|
||||
"model": "Modell",
|
||||
"modern": "Modernt",
|
||||
@ -511,6 +545,8 @@
|
||||
"room": "Rum",
|
||||
"room_name": "Rumsnamn",
|
||||
"rooms": "Rum",
|
||||
"save": "Spara",
|
||||
"saved": "Sparat",
|
||||
"saving": "Sparar …",
|
||||
"secure_backup": "Säker säkerhetskopiering",
|
||||
"security": "Säkerhet",
|
||||
@ -539,6 +575,7 @@
|
||||
"unnamed_room": "Namnlöst rum",
|
||||
"unnamed_space": "Namnlöst utrymme",
|
||||
"unverified": "Overifierad",
|
||||
"updating": "Uppdaterar...",
|
||||
"user": "Användare",
|
||||
"user_avatar": "Profilbild",
|
||||
"username": "Användarnamn",
|
||||
@ -867,6 +904,8 @@
|
||||
"warning": "Om du inte har ställt in den nya återställningsmetoden kan en angripare försöka komma åt ditt konto. Byt ditt kontolösenord och ställ in en ny återställningsmetod omedelbart i inställningarna."
|
||||
},
|
||||
"not_supported": "<stöds inte>",
|
||||
"pinned_identity_changed": "%(displayName)ss (<b>%(userId)s</b> ) identitet verkar ha ändrats.<a> Läs mer</a>",
|
||||
"pinned_identity_changed_no_displayname": "<b>%(userId)s</b>:s identitet verkar ha ändrats. <a>Läs mer</a>",
|
||||
"recovery_method_removed": {
|
||||
"description_1": "Den här sessionen har detekterat att din säkerhetsfras och -nyckel för säkra meddelanden har tagits bort.",
|
||||
"description_2": "Om du gjorde det av misstag kan du ställa in säkra meddelanden på den här sessionen som krypterar sessionens meddelandehistorik igen med en ny återställningsmetod.",
|
||||
@ -929,6 +968,7 @@
|
||||
"qr_reciprocate_same_shield_device": "Nästan klar! Visar din andra enhet samma sköld?",
|
||||
"qr_reciprocate_same_shield_user": "Nästan klar! Visar %(displayName)s samma sköld?",
|
||||
"request_toast_accept": "Verifiera session",
|
||||
"request_toast_accept_user": "Verifiera användare",
|
||||
"request_toast_decline_counter": "Ignorera (%(counter)s)",
|
||||
"request_toast_detail": "%(deviceId)s från %(ip)s",
|
||||
"reset_proceed_prompt": "Fortsätt återställning",
|
||||
@ -1060,7 +1100,15 @@
|
||||
"you": "Du reagerade med %(reaction)s till %(message)s"
|
||||
},
|
||||
"m.sticker": "%(senderName)s: %(stickerName)s",
|
||||
"m.text": "%(senderName)s: %(message)s"
|
||||
"m.text": "%(senderName)s: %(message)s",
|
||||
"prefix": {
|
||||
"audio": "Ljud",
|
||||
"file": "Fil",
|
||||
"image": "Bild",
|
||||
"poll": "Omröstning",
|
||||
"video": "Video"
|
||||
},
|
||||
"preview": "<bold>%(prefix)s: </bold> %(preview)s"
|
||||
},
|
||||
"export_chat": {
|
||||
"cancelled": "Exportering avbruten",
|
||||
@ -1183,7 +1231,19 @@
|
||||
"other": "I %(spaceName)s och %(count)s andra utrymmen."
|
||||
},
|
||||
"incompatible_browser": {
|
||||
"title": "Webbläsaren stöds ej"
|
||||
"continue": "Fortsätt ändå",
|
||||
"description": "%(brand)sanvänder vissa webbläsarfunktioner som inte är tillgängliga i din nuvarande webbläsare. %(detail)s",
|
||||
"detail_can_continue": "Om du fortsätter kan vissa funktioner sluta fungera och det finns en risk att du kan förlora data i framtiden.",
|
||||
"detail_no_continue": "Försök uppdatera den här webbläsaren om du inte använder den senaste versionen och försök igen.",
|
||||
"learn_more": "Läs mer",
|
||||
"linux": "Linux",
|
||||
"macos": "Mac",
|
||||
"supported_browsers": "För bästa upplevelse, använd <Chrome>Chrome</Chrome>, <Firefox>Firefox</Firefox>, <Edge>Edge</Edge>, eller <Safari>Safari</Safari>.",
|
||||
"title": "Webbläsaren stöds ej",
|
||||
"use_desktop_heading": "Använd %(brand)s skrivbord istället",
|
||||
"use_mobile_heading": "Använd %(brand)s på mobilen istället",
|
||||
"use_mobile_heading_after_desktop": "Eller använd vår mobilapp",
|
||||
"windows": "Windows (%(bits)s -bit)"
|
||||
},
|
||||
"info_tooltip_title": "Information",
|
||||
"integration_manager": {
|
||||
@ -1307,12 +1367,14 @@
|
||||
"navigate_next_message_edit": "Navigera till nästa meddelande att redigera",
|
||||
"navigate_prev_history": "Föregående nyligen besökta rum eller utrymme",
|
||||
"navigate_prev_message_edit": "Navigera till förra meddelandet att redigera",
|
||||
"next_landmark": "Gå till nästa landmärke",
|
||||
"next_room": "Nästa rum eller DM",
|
||||
"next_unread_room": "Nästa olästa rum eller DM",
|
||||
"number": "[nummer]",
|
||||
"open_user_settings": "Öppna användarinställningar",
|
||||
"page_down": "Page Down",
|
||||
"page_up": "Page Up",
|
||||
"prev_landmark": "Gå till föregående landmärke",
|
||||
"prev_room": "Förra rummet eller DM:en",
|
||||
"prev_unread_room": "Förra olästa rummet eller DM:en",
|
||||
"room_list_collapse_section": "Kollapsa rumslistsektionen",
|
||||
@ -1357,8 +1419,11 @@
|
||||
"dynamic_room_predecessors": "Dynamiska rumsföregångare",
|
||||
"dynamic_room_predecessors_description": "Aktivera MSC3946 (för att stöda sen-ankomna rumsarkiv)",
|
||||
"element_call_video_rooms": "Element Call videorum",
|
||||
"exclude_insecure_devices": "Uteslut osäkra enheter när du skickar/tar emot meddelanden",
|
||||
"exclude_insecure_devices_description": "När det här läget är aktiverat delas inte krypterade meddelanden med obekräftade enheter, och meddelanden från obekräftade enheter visas som ett fel. Observera att om du aktiverar det här läget kanske du inte kan kommunicera med användare som inte har verifierat sina enheter.",
|
||||
"experimental_description": "Känner du dig äventyrlig? Pröva våra senaste idéer under utveckling. Dessa funktioner är inte slutförda; de kan vara instabila, kan ändras, eller kan tas bort helt. <a>Läs mer</a>.",
|
||||
"experimental_section": "Tidiga förhandstittar",
|
||||
"extended_profiles_msc_support": "Kräver att din server har stöd för MSC4133",
|
||||
"feature_disable_call_per_sender_encryption": "Inaktivera kryptering per avsändare för Element Call",
|
||||
"feature_wysiwyg_composer_description": "Använd rik text istället för Markdown i meddelanderedigeraren.",
|
||||
"group_calls": "Ny gruppsamtalsupplevelse",
|
||||
@ -1372,6 +1437,7 @@
|
||||
"group_spaces": "Utrymmen",
|
||||
"group_themes": "Teman",
|
||||
"group_threads": "Trådar",
|
||||
"group_ui": "Användargränssnitt",
|
||||
"group_voip": "Röst & video",
|
||||
"group_widgets": "Widgets",
|
||||
"hidebold": "Dölj aviseringspunkt (visa bara räknarmärken)",
|
||||
@ -1391,8 +1457,7 @@
|
||||
"notification_settings_beta_caption": "Vi introducerar ett enklare sätt att ändra dina aviseringsinställningar. Anpassa din %(brand)s precis som du vill ha den.",
|
||||
"notification_settings_beta_title": "Aviseringsinställningar",
|
||||
"notifications": "Aktivera aviseringspanelen i rumshuvudet",
|
||||
"oidc_native_flow": "Inbyggd OIDC-autentisering",
|
||||
"oidc_native_flow_description": "⚠ VARNING: Experimentellt. Använd inbyggd OIDC-autentisering när den stöds av servern.",
|
||||
"release_announcement": "Releasemeddelande",
|
||||
"render_reaction_images": "Återge anpassade bilder i reaktioner",
|
||||
"render_reaction_images_description": "Ibland kallat för ”anpassade emojis”.",
|
||||
"report_to_moderators": "Rapportera till moderatorer",
|
||||
@ -1400,7 +1465,7 @@
|
||||
"sliding_sync": "Sliding sync-läge",
|
||||
"sliding_sync_description": "Under aktiv utveckling, kan inte inaktiveras.",
|
||||
"sliding_sync_disabled_notice": "Logga ut och in igen för att inaktivera",
|
||||
"sliding_sync_server_no_support": "Din server saknar nativt stöd",
|
||||
"sliding_sync_server_no_support": "Din server saknar support",
|
||||
"under_active_development": "Under aktiv utveckling.",
|
||||
"unrealiable_e2e": "Otillförlitlig i krypterade rum",
|
||||
"video_rooms": "Videorum",
|
||||
@ -1452,6 +1517,8 @@
|
||||
"last_person_warning": "Du är den enda personen här. Om du lämnar så kommer ingen kunna gå med igen, inklusive du.",
|
||||
"leave_room_question": "Vill du lämna rummet '%(roomName)s'?",
|
||||
"leave_space_question": "Är du säker på att du vill lämna utrymmet '%(spaceName)s'?",
|
||||
"room_leave_admin_warning": "Du är den enda administratören i det här rummet. Om du lämnar kommer ingen att kunna ändra rumsinställningar eller vidta andra viktiga åtgärder.",
|
||||
"room_leave_mod_warning": "Du är den enda moderatorn i det här rummet. Om du lämnar kommer ingen att kunna ändra rumsinställningar eller vidta andra viktiga åtgärder.",
|
||||
"room_rejoin_warning": "Det här rummet är inte offentligt. Du kommer inte kunna gå med igen utan en inbjudan.",
|
||||
"space_rejoin_warning": "Det här utrymmet är inte offentligt. Du kommer inte kunna gå med igen utan en inbjudan."
|
||||
},
|
||||
@ -1516,7 +1583,7 @@
|
||||
},
|
||||
"member_list_back_action_label": "Rumsmedlemmar",
|
||||
"message_edit_dialog_title": "Meddelanderedigeringar",
|
||||
"migrating_crypto": "Häng kvar. Vi uppdaterar Element för att göra kryptering snabbare och mer tillförlitlig.",
|
||||
"migrating_crypto": "Häng kvar. Vi håller på att uppdatera%(brand)s för att göra kryptering snabbare och mer tillförlitlig.",
|
||||
"mobile_guide": {
|
||||
"toast_accept": "Använd app",
|
||||
"toast_description": "%(brand)s är experimentell i mobila webbläsare. För en bättre upplevelse och de senaste funktionerna använd våran nativa app.",
|
||||
@ -1572,8 +1639,8 @@
|
||||
"download_brand_desktop": "Ladda ner %(brand)s skrivbord",
|
||||
"download_f_droid": "Hämta den på F-Droid",
|
||||
"download_google_play": "Hämta den på Google Play",
|
||||
"enable_notifications": "Sätt på aviseringar",
|
||||
"enable_notifications_action": "Aktivera aviseringar",
|
||||
"enable_notifications": "Aktivera skrivbordsaviseringar",
|
||||
"enable_notifications_action": "Öppna inställningar",
|
||||
"enable_notifications_description": "Missa inget svar eller viktigt meddelande",
|
||||
"explore_rooms": "Utforska offentliga rum",
|
||||
"find_community_members": "Hitta och bjud in dina gemenskapsmedlemmar",
|
||||
@ -1752,14 +1819,37 @@
|
||||
"restore_failed_error": "Kunde inte återställa säkerhetskopia"
|
||||
},
|
||||
"right_panel": {
|
||||
"add_integrations": "Lägg till widgets, bryggor och bottar",
|
||||
"add_integrations": "Lägg till tillägg",
|
||||
"add_topic": "Lägg till ämne",
|
||||
"extensions_button": "Tillägg",
|
||||
"extensions_empty_description": "Välj "%(addIntegrations)s ” för att bläddra och lägga till tillägg till det här rummet",
|
||||
"extensions_empty_title": "Öka produktiviteten med fler verktyg, widgets och botar",
|
||||
"files_button": "Filer",
|
||||
"pinned_messages": {
|
||||
"empty_description": "Välj ett meddelande och välj ”%(pinAction)s” för att inkludera det här.",
|
||||
"empty_title": "Fäst viktiga meddelanden så att de lätt kan upptäckas",
|
||||
"header": {
|
||||
"one": "1 Fäst meddelande",
|
||||
"other": "%(count)sFästa meddelanden"
|
||||
},
|
||||
"limits": {
|
||||
"other": "Du kan bara fästa upp till %(count)s widgets"
|
||||
}
|
||||
},
|
||||
"menu": "Öppna menyn",
|
||||
"release_announcement": {
|
||||
"close": "OK",
|
||||
"description": "Du hittar alla fästa meddelanden här. För muspekaren över ett meddelande och välj \"Fäst\" för att lägga till det.",
|
||||
"title": "Alla nya fästa meddelanden"
|
||||
},
|
||||
"reply_thread": "Svara på ett <link> trådmeddelande </link>",
|
||||
"unpin_all": {
|
||||
"button": "Lossa alla meddelanden",
|
||||
"content": "Se till att du verkligen vill ta bort alla fästa meddelanden. Den här åtgärden kan inte ångras.",
|
||||
"title": "Lossa alla meddelanden?"
|
||||
},
|
||||
"view": "Visa i tidslinjen"
|
||||
},
|
||||
"pinned_messages_button": "Fäst",
|
||||
"pinned_messages_button": "Fästa meddelanden",
|
||||
"poll": {
|
||||
"active_heading": "Aktiva omröstningar",
|
||||
"empty_active": "Det finns inga aktiva omröstningar i det här rummet",
|
||||
@ -1784,7 +1874,7 @@
|
||||
"view_in_timeline": "Se omröstningen i tidslinjen",
|
||||
"view_poll": "Visa omröstning"
|
||||
},
|
||||
"polls_button": "Omröstningshistorik",
|
||||
"polls_button": "Omröstningar",
|
||||
"room_summary_card": {
|
||||
"title": "Rumsinfo"
|
||||
},
|
||||
@ -1813,6 +1903,7 @@
|
||||
"forget": "Glöm rum",
|
||||
"low_priority": "Låg prioritet",
|
||||
"mark_read": "Markera som läst",
|
||||
"mark_unread": "Markera som oläst",
|
||||
"notifications_default": "Matcha förvalsinställning",
|
||||
"notifications_mute": "Tysta rum",
|
||||
"title": "Rumsinställningar",
|
||||
@ -1861,7 +1952,8 @@
|
||||
},
|
||||
"room_is_public": "Det här rummet är offentligt"
|
||||
},
|
||||
"header_face_pile_tooltip": "Växla medlemslista",
|
||||
"header_avatar_open_settings_label": "Öppna rumsinställningar",
|
||||
"header_face_pile_tooltip": "Människor",
|
||||
"header_untrusted_label": "Ej betrodd",
|
||||
"inaccessible": "Det är rummet eller utrymmet är inte åtkomligt för tillfället.",
|
||||
"inaccessible_name": "%(roomName)s är inte tillgängligt för tillfället.",
|
||||
@ -1888,7 +1980,7 @@
|
||||
"invite_reject_ignore": "Avvisa och ignorera användare",
|
||||
"invite_sent_to_email": "Denna inbjudan skickades till %(email)s",
|
||||
"invite_sent_to_email_room": "Denna inbjudan till %(roomName)s skickades till %(email)s",
|
||||
"invite_subtitle": "<userName/> bjöd in dig",
|
||||
"invite_subtitle": "Inbjuden av <userName/>",
|
||||
"invite_this_room": "Bjud in till rummet",
|
||||
"invite_title": "Vill du gå med i %(roomName)s?",
|
||||
"inviter_unknown": "Okänt",
|
||||
@ -1931,11 +2023,24 @@
|
||||
"not_found_title": "Det här rummet eller utrymmet finns inte.",
|
||||
"not_found_title_name": "%(roomName)s finns inte.",
|
||||
"peek_join_prompt": "Du förhandsgranskar %(roomName)s. Vill du gå med i det?",
|
||||
"pinned_message_badge": "Fäst meddelande",
|
||||
"pinned_message_banner": {
|
||||
"button_close_list": "Stäng listan",
|
||||
"button_view_all": "Visa alla",
|
||||
"description": "Det här rummet har fästa meddelanden. Klicka för att se dem.",
|
||||
"go_to_message": "Visa det fästa meddelandet på tidslinjen.",
|
||||
"title": "<bold>%(index)s av %(length)s</bold> fästa meddelanden"
|
||||
},
|
||||
"read_topic": "Klicka för att läsa ämne",
|
||||
"rejecting": "Nekar inbjudan …",
|
||||
"rejoin_button": "Gå med igen",
|
||||
"search": {
|
||||
"all_rooms_button": "Sök i alla rum",
|
||||
"placeholder": "Sök meddelanden...",
|
||||
"summary": {
|
||||
"one": "1 resultat hittades för ”<query/>”",
|
||||
"other": "%(count)sResultat hittades för ”<query/>”"
|
||||
},
|
||||
"this_room_button": "Sök i det här rummet"
|
||||
},
|
||||
"status_bar": {
|
||||
@ -2071,6 +2176,8 @@
|
||||
"error_deleting_alias_description": "Ett fel inträffade vid borttagning av adressen. Den kanske inte längre existerar, eller så inträffade ett tillfälligt fel.",
|
||||
"error_deleting_alias_description_forbidden": "Du har inte behörighet att radera den där adressen.",
|
||||
"error_deleting_alias_title": "Fel vi borttagning av adress",
|
||||
"error_publishing": "Det gick inte att publicera rummet",
|
||||
"error_publishing_detail": "Det uppstod ett fel när det här rummet skulle publiceras",
|
||||
"error_save_space_settings": "Misslyckades att spara utrymmesinställningar.",
|
||||
"error_updating_alias_description": "Ett fel inträffade vid uppdatering av rummets alternativa adresser. Det kanske inte tillåts av servern, eller så inträffade ett tillfälligt fel.",
|
||||
"error_updating_canonical_alias_description": "Ett fel inträffade vid uppdatering av rummets huvudadress. Det kanske inte tillåts av servern, eller så inträffade ett tillfälligt fel.",
|
||||
@ -2297,6 +2404,7 @@
|
||||
"brand_version": "%(brand)s-version:",
|
||||
"clear_cache_reload": "Rensa cache och ladda om",
|
||||
"crypto_version": "Kryptoversion:",
|
||||
"dialog_title": "<strong>Inställningar: </strong> Hjälp & Om",
|
||||
"help_link": "För hjälp med att använda %(brand)s, klicka <a>här</a>.",
|
||||
"homeserver": "Hemservern är <code>%(homeserverUrl)s</code>",
|
||||
"identity_server": "Identitetsservern är <code>%(identityServerUrl)s</code>",
|
||||
@ -2305,18 +2413,30 @@
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"account": {
|
||||
"dialog_title": "<strong>Inställningar: </strong> Konto",
|
||||
"title": "Konto"
|
||||
},
|
||||
"all_rooms_home": "Visa alla rum i Hem",
|
||||
"all_rooms_home_description": "Alla rum du är in kommer att visas i Hem.",
|
||||
"always_show_message_timestamps": "Visa alltid tidsstämplar för meddelanden",
|
||||
"appearance": {
|
||||
"bundled_emoji_font": "Använd medföljande emoji-teckensnitt",
|
||||
"compact_layout": "Visa kompakta texter och meddelanden",
|
||||
"compact_layout_description": "Modern layout måste väljas för att använda den här funktionen.",
|
||||
"custom_font": "Använd systemets teckensnitt",
|
||||
"custom_font_description": "Sätt namnet för ett teckensnitt installerat på ditt system så kommer %(brand)s att försöka använda det.",
|
||||
"custom_font_name": "Namn på systemets teckensnitt",
|
||||
"custom_font_size": "Använd anpassad storlek",
|
||||
"custom_theme_error_downloading": "Fel vid nedladdning av temainformation.",
|
||||
"custom_theme_add": "Lägg till anpassat tema",
|
||||
"custom_theme_downloading": "Laddar ned anpassat tema...",
|
||||
"custom_theme_error_downloading": "Fel vid nedladdning av tema",
|
||||
"custom_theme_help": "Ange webbadressen till ett anpassat tema som du vill använda.",
|
||||
"custom_theme_invalid": "Ogiltigt temaschema.",
|
||||
"dialog_title": "<strong>Inställningar:</strong> Utseende",
|
||||
"font_size": "Teckenstorlek",
|
||||
"font_size_default": "%(fontSize)s(standard)",
|
||||
"high_contrast": "Hög kontrast",
|
||||
"image_size_default": "Standard",
|
||||
"image_size_large": "Stor",
|
||||
"layout_bubbles": "Meddelandebubblor",
|
||||
@ -2331,6 +2451,9 @@
|
||||
"code_block_expand_default": "Expandera kodblock för förval",
|
||||
"code_block_line_numbers": "Visa radnummer i kodblock",
|
||||
"disable_historical_profile": "Visa nuvarande profilbild och namn för användare i meddelandehistoriken",
|
||||
"discovery": {
|
||||
"title": "Hur man hittar dig"
|
||||
},
|
||||
"emoji_autocomplete": "Aktivera emojiförslag medan du skriver",
|
||||
"enable_markdown": "Aktivera Markdown",
|
||||
"enable_markdown_description": "Börja meddelanden med <code>/plain</code> för att skicka utan markdown.",
|
||||
@ -2346,6 +2469,14 @@
|
||||
"add_msisdn_dialog_title": "Lägg till telefonnummer",
|
||||
"add_msisdn_instructions": "Ett SMS har skickats till +%(msisdn)s. Ange verifieringskoden som det innehåller.",
|
||||
"add_msisdn_misconfigured": "Flöde för tilläggning/bindning med MSISDN är felkonfigurerat",
|
||||
"allow_spellcheck": "Tillåt stavningskontroll",
|
||||
"application_language": "Språk för ansökan",
|
||||
"application_language_reload_hint": "Appen laddas om efter att ha valt ett annat språk",
|
||||
"avatar_remove_progress": "Tar bort bild...",
|
||||
"avatar_save_progress": "Laddar upp bild...",
|
||||
"avatar_upload_error_text": "Filformatet stöds inte eller bilden är större än%(size)s.",
|
||||
"avatar_upload_error_text_generic": "Filformatet kanske inte stöds.",
|
||||
"avatar_upload_error_title": "Det gick inte att ladda upp avatarbilden",
|
||||
"confirm_adding_email_body": "Klicka på knappen nedan för att bekräfta tilläggning av e-postadressen.",
|
||||
"confirm_adding_email_title": "Bekräfta tilläggning av e-postadressen",
|
||||
"deactivate_confirm_body": "Är du säker på att du vill inaktivera ditt konto? Detta är oåterkalleligt.",
|
||||
@ -2361,10 +2492,13 @@
|
||||
"deactivate_confirm_erase_label": "Dölj mina meddelanden för nya som går med",
|
||||
"deactivate_section": "Inaktivera konto",
|
||||
"deactivate_warning": "Avaktivering av ditt konto är en permanent handling — var försiktig!",
|
||||
"discovery_email_empty": "Upptäcktsalternativ kommer att visas när du har lagt till en e-postadress ovan.",
|
||||
"discovery_email_empty": "När du har lagt till en e-postadress visas alternativ för att upptäcka den.",
|
||||
"discovery_email_verification_instructions": "Verifiera länken i din inkorg",
|
||||
"discovery_msisdn_empty": "Upptäcktsalternativ kommer att visas när du har lagt till ett telefonnummer ovan.",
|
||||
"discovery_msisdn_empty": "När du har lagt till ett telefonnummer visas alternativ för att upptäcka det.",
|
||||
"discovery_needs_terms": "Samtyck till identitetsserverns (%(serverName)s) användarvillkor för att låta dig själv vara upptäckbar med e-postadress eller telefonnummer.",
|
||||
"discovery_needs_terms_title": "Låt andra hitta dig",
|
||||
"display_name": "Visningsnamn",
|
||||
"display_name_error": "Det gick inte att ställa in visningsnamn",
|
||||
"email_address_in_use": "Den här e-postadressen används redan",
|
||||
"email_address_label": "E-postadress",
|
||||
"email_not_verified": "Din e-postadress har inte verifierats än",
|
||||
@ -2389,7 +2523,7 @@
|
||||
"error_share_msisdn_discovery": "Kunde inte dela telefonnummer",
|
||||
"identity_server_no_token": "Ingen identitetsåtkomsttoken hittades",
|
||||
"identity_server_not_set": "Identitetsserver inte inställd",
|
||||
"language_section": "Språk och region",
|
||||
"language_section": "Språk",
|
||||
"msisdn_in_use": "Detta telefonnummer används redan",
|
||||
"msisdn_label": "Telefonnummer",
|
||||
"msisdn_verification_field_label": "Verifieringskod",
|
||||
@ -2398,9 +2532,15 @@
|
||||
"oidc_manage_button": "Hantera konto",
|
||||
"password_change_section": "Sätt ett nytt kontolösenord …",
|
||||
"password_change_success": "Ditt lösenord byttes framgångsrikt.",
|
||||
"personal_info": "Personlig information",
|
||||
"profile_subtitle": "Så här visas du för andra i appen.",
|
||||
"profile_subtitle_oidc": "Ditt konto hanteras separat av en identitetsleverantör och därför kan vissa av dina personuppgifter inte ändras här.",
|
||||
"remove_email_prompt": "Ta bort %(email)s?",
|
||||
"remove_msisdn_prompt": "Ta bort %(phone)s?",
|
||||
"spell_check_locale_placeholder": "Välj en lokalisering"
|
||||
"spell_check_locale_placeholder": "Välj en lokalisering",
|
||||
"unable_to_load_emails": "Det gick inte att ladda e-postadresser",
|
||||
"unable_to_load_msisdns": "Det går inte att läsa in telefonnummer",
|
||||
"username": "Användarnamn"
|
||||
},
|
||||
"image_thumbnails": "Visa förhandsgranskning/miniatyr för bilder",
|
||||
"inline_url_previews_default": "Aktivera inbäddad URL-förhandsgranskning som standard",
|
||||
@ -2456,12 +2596,20 @@
|
||||
"phrase_strong_enough": "Bra! Den här lösenfrasen ser tillräckligt stark ut"
|
||||
},
|
||||
"keyboard": {
|
||||
"dialog_title": "<strong>Inställningar: </strong> Tangentbord",
|
||||
"title": "Tangentbord"
|
||||
},
|
||||
"labs": {
|
||||
"dialog_title": "<strong>Inställningar: </strong> Labs"
|
||||
},
|
||||
"labs_mjolnir": {
|
||||
"dialog_title": "<strong>Inställningar:</strong> Ignorerade användare"
|
||||
},
|
||||
"notifications": {
|
||||
"default_setting_description": "Denna inställning kommer att tillämpas som standard för alla dina rum.",
|
||||
"default_setting_section": "Jag vill bli meddelad för (Standardinställning)",
|
||||
"desktop_notification_message_preview": "Visa förhandsgranskning av meddelanden i skrivbordsmeddelanden",
|
||||
"dialog_title": "<strong>Inställningar:</strong> Aviseringar",
|
||||
"email_description": "Få en sammanfattning av missade aviseringar via e-post",
|
||||
"email_section": "E-postsammanfattning",
|
||||
"email_select": "Välj vilka e-postadresser du vill skicka sammanfattningar till. Hantera dina e-postadresser i <button>Allmänt</button>.",
|
||||
@ -2520,12 +2668,15 @@
|
||||
"code_blocks_heading": "Kodblock",
|
||||
"compact_modern": "Använd ett mer kompakt 'modernt' arrangemang",
|
||||
"composer_heading": "Meddelandefält",
|
||||
"default_timezone": "Webbläsarens standard (%(timezone)s)",
|
||||
"dialog_title": "<strong>Inställningar:</strong> Alternativ",
|
||||
"enable_hardware_acceleration": "Aktivera hårdvaruaccelerering",
|
||||
"enable_tray_icon": "Visa ikon i systembrickan och minimera programmet till den när fönstret stängs",
|
||||
"keyboard_heading": "Tangentbordsgenvägar",
|
||||
"keyboard_view_shortcuts_button": "För att se alla tangentbordsgenvägar, <a>klicka här</a>.",
|
||||
"media_heading": "Bilder, GIF:ar och videor",
|
||||
"presence_description": "Dela din aktivitet och status med andra.",
|
||||
"publish_timezone": "Publicera tidszon på offentlig profil",
|
||||
"rm_lifetime": "Läsmarkörens livstid (ms)",
|
||||
"rm_lifetime_offscreen": "Läsmarkörens livstid utanför skärmen (ms)",
|
||||
"room_directory_heading": "Rumskatalog",
|
||||
@ -2534,7 +2685,8 @@
|
||||
"show_checklist_shortcuts": "Visa genväg till välkomstchecklistan ovanför rumslistan",
|
||||
"show_polls_button": "Visa omröstningsknapp",
|
||||
"surround_text": "Inneslut valt text vid skrivning av specialtecken",
|
||||
"time_heading": "Tidvisning"
|
||||
"time_heading": "Tidvisning",
|
||||
"user_timezone": "Ange tidszon"
|
||||
},
|
||||
"prompt_invite": "Fråga innan inbjudningar skickas till potentiellt ogiltiga Matrix-ID:n",
|
||||
"replace_plain_emoji": "Ersätt automatiskt textemotikoner med emojier",
|
||||
@ -2565,8 +2717,11 @@
|
||||
"cross_signing_self_signing_private_key": "Privat nyckel för självsignering:",
|
||||
"cross_signing_user_signing_private_key": "Privat nyckel för användarsignering:",
|
||||
"cryptography_section": "Kryptografi",
|
||||
"dehydrated_device_description": "Funktionen offlineenhet låter dig ta emot krypterade meddelanden även när du inte är inloggad på någon enhet",
|
||||
"dehydrated_device_enabled": "Offlineenhet aktiverad",
|
||||
"delete_backup": "Radera säkerhetskopia",
|
||||
"delete_backup_confirm_description": "Är du säker? Du kommer att förlora dina krypterade meddelanden om dina nycklar inte säkerhetskopieras ordentligt.",
|
||||
"dialog_title": "<strong>Inställningar:</strong> Säkerhet och integritet",
|
||||
"e2ee_default_disabled_warning": "Din serveradministratör har inaktiverat totalsträckskryptering som förval för privata rum och direktmeddelanden.",
|
||||
"enable_message_search": "Aktivera meddelandesökning i krypterade rum",
|
||||
"encryption_section": "Kryptering",
|
||||
@ -2644,6 +2799,7 @@
|
||||
"device_unverified_description_current": "Verifiera din nuvarande session för förbättrade säkra meddelanden.",
|
||||
"device_verified_description": "Den här sessionen är redo för säkra meddelanden.",
|
||||
"device_verified_description_current": "Din nuvarande session är redo för säkra meddelanden.",
|
||||
"dialog_title": "<strong>Inställningar: </strong> Sessioner",
|
||||
"error_pusher_state": "Misslyckades att sätta pusharläge",
|
||||
"error_set_name": "Misslyckades att ange sessionsnamn",
|
||||
"filter_all": "Alla",
|
||||
@ -2683,9 +2839,10 @@
|
||||
"security_recommendations_description": "Förbättra din kontosäkerhet genom att följa dessa rekommendationer.",
|
||||
"session_id": "Sessions-ID",
|
||||
"show_details": "Visa detaljer",
|
||||
"sign_in_with_qr": "Logga in med QR-kod",
|
||||
"sign_in_with_qr": "Länka ny enhet",
|
||||
"sign_in_with_qr_button": "Visa QR-kod",
|
||||
"sign_in_with_qr_description": "Du kan använda den här enheten för att logga in en ny enhet med en QR-kod. Du kommer behöva skanna QR-koden som visas på den här enheten med din enhet som är utloggad.",
|
||||
"sign_in_with_qr_description": "Använd en QR-kod för att logga in på en annan enhet och konfigurera säkra meddelanden.",
|
||||
"sign_in_with_qr_unsupported": "Stöds inte av din kontoleverantör",
|
||||
"sign_out": "Logga ut den här sessionen",
|
||||
"sign_out_all_other_sessions": "Logga ut ur alla andra sessioner (%(otherSessionsCount)s)",
|
||||
"sign_out_confirm_description": {
|
||||
@ -2725,7 +2882,9 @@
|
||||
"show_redaction_placeholder": "Visa en platshållare för borttagna meddelanden",
|
||||
"show_stickers_button": "Visa dekalknapp",
|
||||
"show_typing_notifications": "Visa \"skriver\"-statusar",
|
||||
"showbold": "Visa all aktivitet i rumslistan (prickar eller antal olästa meddelanden)",
|
||||
"sidebar": {
|
||||
"dialog_title": "<strong>Inställningar:</strong> Sidofält",
|
||||
"metaspaces_favourites_description": "Gruppera alla dina favoritrum och -personer på ett ställe.",
|
||||
"metaspaces_home_all_rooms": "Visa alla rum",
|
||||
"metaspaces_home_all_rooms_description": "Visa alla dina rum i Hem, även om de är i ett utrymme.",
|
||||
@ -2734,10 +2893,14 @@
|
||||
"metaspaces_orphans_description": "Gruppera alla dina rum som inte är en del av ett utrymme på ett ställe.",
|
||||
"metaspaces_people_description": "Gruppera alla dina personer på ett ställe.",
|
||||
"metaspaces_subsection": "Utrymmen att visa",
|
||||
"metaspaces_video_rooms": "Videorum och konferenser",
|
||||
"metaspaces_video_rooms_description": "Gruppera alla privata videorum och konferenser.",
|
||||
"metaspaces_video_rooms_description_invite_extension": "I konferenser kan du bjuda in personer utanför Matrix.",
|
||||
"spaces_explainer": "Utrymmen är sätt att gruppera rum och personer. Vid sidan av de utrymmen du befinner dig i kan du också använda några förbyggda.",
|
||||
"title": "Sidofält"
|
||||
},
|
||||
"start_automatically": "Starta automatiskt vid systeminloggning",
|
||||
"tac_only_notifications": "Visa endast notiser i aktivitetscentret för trådar",
|
||||
"use_12_hour_format": "Visa tidsstämplar i 12-timmarsformat (t.ex. 2:30em)",
|
||||
"use_command_enter_send_message": "Använd Kommando + Enter för att skicka ett meddelande",
|
||||
"use_command_f_search": "Använd Kommando + F för att söka på tidslinjen",
|
||||
@ -2751,6 +2914,7 @@
|
||||
"audio_output_empty": "Inga ljudutgångar hittades",
|
||||
"auto_gain_control": "Automatisk förstärkningskontroll",
|
||||
"connection_section": "Anslutning",
|
||||
"dialog_title": "<strong>Inställningar: </strong> Röst och video",
|
||||
"echo_cancellation": "Ekoreducering",
|
||||
"enable_fallback_ice_server": "Tillåt reservserver för samtalsassistans (%(server)s)",
|
||||
"enable_fallback_ice_server_description": "Gäller endast om din hemserver inte erbjuder en. Din IP-adress delas under samtal.",
|
||||
@ -2769,8 +2933,12 @@
|
||||
"warning": "<w>VARNING:</w> <description/>"
|
||||
},
|
||||
"share": {
|
||||
"link_copied": "Länken kopierad",
|
||||
"permalink_message": "Länk till valt meddelande",
|
||||
"permalink_most_recent": "Länk till senaste meddelandet",
|
||||
"share_call": "Länk till konferensinbjudan",
|
||||
"share_call_subtitle": "Länk för externa användare att gå med i samtalet utan ett Matrixkonto:",
|
||||
"title_link": "Dela länk",
|
||||
"title_message": "Dela rumsmeddelande",
|
||||
"title_room": "Dela rum",
|
||||
"title_user": "Dela användare"
|
||||
@ -3012,14 +3180,21 @@
|
||||
"one": "%(count)s svar",
|
||||
"other": "%(count)s svar"
|
||||
},
|
||||
"empty_description": "Använd ”%(replyInThread)s” när du håller muspekaren över ett meddelande.",
|
||||
"empty_title": "Trådar underlättar för att hålla konversationer till ämnet och gör dem lättare att följa.",
|
||||
"error_start_thread_existing_relation": "Kan inte skapa tråd från en händelse med en existerande relation",
|
||||
"mark_all_read": "Markera allt som läst",
|
||||
"my_threads": "Mina trådar",
|
||||
"my_threads_description": "Visar alla trådar du har medverkat i",
|
||||
"open_thread": "Öppna tråd",
|
||||
"show_thread_filter": "Visa:"
|
||||
},
|
||||
"threads_activity_centre": {
|
||||
"header": "Aktivitet för trådar"
|
||||
"header": "Aktivitet för trådar",
|
||||
"no_rooms_with_threads_notifs": "Du har inga rum med trådaviseringar ännu.",
|
||||
"no_rooms_with_unread_threads": "Du har inga rum med olästa trådar än.",
|
||||
"release_announcement_description": "Meddelanden om trådar har flyttats, du hittar dem här från och med nu.",
|
||||
"release_announcement_header": "Aktivitetscenter för Trådar"
|
||||
},
|
||||
"time": {
|
||||
"about_day_ago": "cirka en dag sedan",
|
||||
@ -3062,9 +3237,21 @@
|
||||
},
|
||||
"creation_summary_dm": "%(creator)s skapade den här DM:en.",
|
||||
"creation_summary_room": "%(creator)s skapade och konfigurerade rummet.",
|
||||
"decryption_failure": {
|
||||
"blocked": "Avsändaren har blockerat dig från att ta emot det här meddelandet eftersom din enhet inte är verifierad",
|
||||
"historical_event_no_key_backup": "Historiska meddelanden är inte tillgängliga på den här enheten",
|
||||
"historical_event_unverified_device": "Du måste verifiera den här enheten för att få åtkomst till historiska meddelanden",
|
||||
"historical_event_user_not_joined": "Du har inte tillgång till det här meddelandet",
|
||||
"sender_identity_previously_verified": "Avsändarens verifierade identitet har ändrats",
|
||||
"sender_unsigned_device": "Skickat från en osäker enhet.",
|
||||
"unable_to_decrypt": "Det gick inte att dekryptera meddelandet"
|
||||
},
|
||||
"disambiguated_profile": "%(displayName)s (%(matrixId)s)",
|
||||
"download_action_decrypting": "Avkrypterar",
|
||||
"download_action_downloading": "Laddar ner",
|
||||
"download_failed": "Nedladdning misslyckades",
|
||||
"download_failed_description": "Ett fel uppstod när den här filen laddades ned",
|
||||
"e2e_state": "Tillståndet för end-to-end-krypteringen",
|
||||
"edits": {
|
||||
"tooltip_label": "Redigerat vid %(date)s. Klicka för att visa redigeringar.",
|
||||
"tooltip_sub": "Klicka för att visa redigeringar",
|
||||
@ -3118,7 +3305,7 @@
|
||||
},
|
||||
"m.file": {
|
||||
"error_decrypting": "Fel vid avkryptering av bilagan",
|
||||
"error_invalid": "Felaktig fil%(extra)s"
|
||||
"error_invalid": "Ogiltig fil"
|
||||
},
|
||||
"m.image": {
|
||||
"error": "Kunde inte visa bild på grund av fel",
|
||||
@ -3305,7 +3492,8 @@
|
||||
"reactions": {
|
||||
"add_reaction_prompt": "Lägg till reaktion",
|
||||
"custom_reaction_fallback_label": "Anpassad reaktion",
|
||||
"label": "%(reactors)s reagerade med %(content)s"
|
||||
"label": "%(reactors)s reagerade med %(content)s",
|
||||
"tooltip_caption": "reagerade med %(shortName)s"
|
||||
},
|
||||
"read_receipt_title": {
|
||||
"one": "Sedd av %(count)s person",
|
||||
@ -3490,6 +3678,10 @@
|
||||
"truncated_list_n_more": {
|
||||
"other": "Och %(count)s till…"
|
||||
},
|
||||
"unsupported_browser": {
|
||||
"description": "Om du fortsätter kan vissa funktioner sluta fungera och det finns en risk att du kan förlora data i framtiden. Uppdatera din webbläsare för att fortsätta använda%(brand)s.",
|
||||
"title": "%(brand)sstöder inte den här webbläsaren"
|
||||
},
|
||||
"unsupported_server_description": "Servern använder en äldre version av Matrix. Uppgradera till Matrix %(version)s för att använda %(brand)s utan fel.",
|
||||
"unsupported_server_title": "Din server stöds inte",
|
||||
"update": {
|
||||
@ -3507,6 +3699,12 @@
|
||||
"toast_title": "Uppdatera %(brand)s",
|
||||
"unavailable": "Otillgänglig"
|
||||
},
|
||||
"update_room_access_modal": {
|
||||
"description": "För att skapa en delningslänk måste du tillåta gäster att gå med i det här rummet. Detta kan göra rummet mindre säkert. När du är klar med samtalet kan du göra rummet privat igen.",
|
||||
"dont_change_description": "Alternativt kan du hålla samtalet i ett separat rum.",
|
||||
"no_change": "Jag vill inte ändra åtkomstnivån.",
|
||||
"title": "Ändra åtkomstnivå för rummet"
|
||||
},
|
||||
"upload_failed_generic": "Filen '%(fileName)s' kunde inte laddas upp.",
|
||||
"upload_failed_size": "Filen '%(fileName)s' överstiger denna hemserverns storleksgräns för uppladdningar",
|
||||
"upload_failed_title": "Uppladdning misslyckades",
|
||||
@ -3516,6 +3714,7 @@
|
||||
"error_files_too_large": "Dessa filer är <b>för stora</b> för att laddas upp. Filstorleksgränsen är %(limit)s.",
|
||||
"error_some_files_too_large": "Vissa filer är <b>för stora</b> för att laddas upp. Filstorleksgränsen är %(limit)s.",
|
||||
"error_title": "Uppladdningsfel",
|
||||
"not_image": "Filen du har valt är inte en giltig bildfil.",
|
||||
"title": "Ladda upp filer",
|
||||
"title_progress": "Ladda upp filer (%(current)s av %(total)s)",
|
||||
"upload_all_button": "Ladda upp alla",
|
||||
@ -3542,6 +3741,7 @@
|
||||
"deactivate_confirm_action": "Inaktivera användaren",
|
||||
"deactivate_confirm_description": "Vid inaktivering av användare loggas den ut och förhindras från att logga in igen. Den kommer dessutom att lämna alla rum den befinner sig i. Den här åtgärden kan inte ångras. Är du säker på att du vill inaktivera den här användaren?",
|
||||
"deactivate_confirm_title": "Inaktivera användare?",
|
||||
"dehydrated_device_enabled": "Offlineenhet aktiverad",
|
||||
"demote_button": "Degradera",
|
||||
"demote_self_confirm_description_space": "Du kommer inte kunna ångra den här ändringen eftersom du degraderar dig själv, och om du är den sista privilegierade användaren i utrymmet så kommer det att vara omöjligt att återfå utrymmet.",
|
||||
"demote_self_confirm_room": "Du kommer inte att kunna ångra den här ändringen eftersom du degraderar dig själv. Om du är den sista privilegierade användaren i rummet blir det omöjligt att återfå behörigheter.",
|
||||
@ -3558,6 +3758,7 @@
|
||||
"error_revoke_3pid_invite_title": "Misslyckades att återkalla inbjudan",
|
||||
"hide_sessions": "Dölj sessioner",
|
||||
"hide_verified_sessions": "Dölj verifierade sessioner",
|
||||
"ignore_button": "Ignorera",
|
||||
"ignore_confirm_description": "Alla meddelanden och inbjudningar från den här användaren kommer att döljas. Är du säker på att du vill ignorera denne?",
|
||||
"ignore_confirm_title": "Ignorera %(user)s",
|
||||
"invited_by": "Inbjuden av %(sender)s",
|
||||
@ -3585,23 +3786,26 @@
|
||||
"no_recent_messages_description": "Pröva att skrolla upp i tidslinjen för att se om det finns några tidigare.",
|
||||
"no_recent_messages_title": "Inga nyliga meddelanden från %(user)s hittades"
|
||||
},
|
||||
"redact_button": "Ta bort nyliga meddelanden",
|
||||
"redact_button": "Ta bort meddelanden",
|
||||
"revoke_invite": "Återkalla inbjudan",
|
||||
"room_encrypted": "Meddelanden i det här rummet är totalsträckskrypterade.",
|
||||
"room_encrypted_detail": "Dina meddelanden är säkrade och endast du och mottagaren har de unika nycklarna för att låsa upp dem.",
|
||||
"room_unencrypted": "Meddelanden i detta rum är inte totalsträckskrypterade.",
|
||||
"room_unencrypted_detail": "I krypterade rum är dina meddelanden säkrade och endast du och mottagaren har de unika nycklarna för att låsa upp dem.",
|
||||
"share_button": "Dela länk till användare",
|
||||
"send_message": "Skicka meddelande",
|
||||
"share_button": "Dela profil",
|
||||
"unban_button_room": "Avbanna i rum",
|
||||
"unban_button_space": "Avbanna i utrymme",
|
||||
"unban_room_confirm_title": "Avbanna från %(roomName)s",
|
||||
"unban_space_everything": "Avbanna dem från allt jag kan",
|
||||
"unban_space_specific": "Avbanna dem från specifika saker jag kan",
|
||||
"unban_space_warning": "Personen kommer inte kunna komma åt saker du inte är admin för.",
|
||||
"unignore_button": "Avignorera",
|
||||
"verify_button": "Verifiera användare",
|
||||
"verify_explainer": "För extra säkerhet, verifiera den här användaren genom att kolla en engångskod på båda era enheter."
|
||||
},
|
||||
"user_menu": {
|
||||
"link_new_device": "Länka ny enhet",
|
||||
"settings": "Alla inställningar",
|
||||
"switch_theme_dark": "Byt till mörkt läge",
|
||||
"switch_theme_light": "Byt till ljust läge"
|
||||
@ -3643,15 +3847,19 @@
|
||||
"enable_camera": "Sätt på kamera",
|
||||
"enable_microphone": "Slå på mikrofonen",
|
||||
"expand": "Återgå till samtal",
|
||||
"get_call_link": "Dela samtalslänk",
|
||||
"hangup": "Lägg på",
|
||||
"hide_sidebar_button": "Göm sidopanel",
|
||||
"input_devices": "Ingångsenheter",
|
||||
"jitsi_call": "Jitsi-gruppsamtal",
|
||||
"join_button_tooltip_call_full": "Tyvärr - det här samtalet är för närvarande fullt",
|
||||
"join_button_tooltip_connecting": "Ansluter",
|
||||
"legacy_call": "Gammal samtalsfunktion",
|
||||
"legacy_call": "Standardsamtal",
|
||||
"maximise": "Fyll skärmen",
|
||||
"maximise_call": "Maximera samtal",
|
||||
"metaspace_video_rooms": {
|
||||
"conference_room_section": "Konferenser"
|
||||
},
|
||||
"minimise_call": "Minimera samtal",
|
||||
"misconfigured_server": "Anrop misslyckades på grund av felkonfigurerad server",
|
||||
"misconfigured_server_description": "Be administratören för din hemserver (<code>%(homeserverDomain)s</code>) att konfigurera en TURN-server för att samtal ska fungera pålitligt.",
|
||||
@ -3809,7 +4017,7 @@
|
||||
"title": "Tillåt att den här widgeten verifierar din identitet"
|
||||
},
|
||||
"popout": "Poppa ut widget",
|
||||
"set_room_layout": "Sätt mitt rumsarrangemang för alla",
|
||||
"set_room_layout": "Ställ in layout för alla",
|
||||
"shared_data_avatar": "URL för din profilbild",
|
||||
"shared_data_device_id": "Ditt enhets-ID",
|
||||
"shared_data_lang": "Ditt språk",
|
||||
|
||||
@ -1349,7 +1349,6 @@
|
||||
"msc3531_hide_messages_pending_moderation": "Дозволити модераторам ховати повідомлення у черзі модерування.",
|
||||
"notification_settings": "Нові налаштування сповіщень",
|
||||
"notification_settings_beta_title": "Налаштування сповіщень",
|
||||
"oidc_native_flow": "Увімкнути нові вбудовані потоки OIDC (в активній розробці)",
|
||||
"report_to_moderators": "Поскаржитись модераторам",
|
||||
"report_to_moderators_description": "У кімнатах, які підтримують модерацію, кнопка «Поскаржитися» дає змогу повідомити про зловживання модераторам кімнати.",
|
||||
"sliding_sync": "Режим ковзної синхронізації",
|
||||
|
||||
@ -230,7 +230,6 @@
|
||||
"oidc": {
|
||||
"error_title": "我们无法使你登入",
|
||||
"generic_auth_error": "验证时出了问题。前往登录页面并重试。",
|
||||
"logout_redirect_warning": "你将被重定向到服务器的验证提供者以完成登出。",
|
||||
"missing_or_invalid_stored_state": "我们已要求浏览器记住你使用的家服务器,但不幸的是你的浏览器已忘记。请前往登录页面重试。"
|
||||
},
|
||||
"password_field_keep_going_prompt": "继续前进……",
|
||||
|
||||
@ -1352,7 +1352,6 @@
|
||||
"msc3531_hide_messages_pending_moderation": "讓版主能夠隱藏待審核的訊息。",
|
||||
"notification_settings": "新通知設定",
|
||||
"notification_settings_beta_title": "通知設定",
|
||||
"oidc_native_flow": "啟用新的原生 OIDC 流程(正在積極開發中)",
|
||||
"report_to_moderators": "回報給版主",
|
||||
"report_to_moderators_description": "在支援審核的聊天室中,「回報」按鈕讓您可以回報濫用行為給聊天室管理員。",
|
||||
"sliding_sync": "滑動同步模式",
|
||||
|
||||
@ -83,9 +83,8 @@ export function pillifyLinks(
|
||||
</StrictMode>
|
||||
);
|
||||
|
||||
pills.render(pill, pillContainer);
|
||||
|
||||
node.parentNode?.replaceChild(pillContainer, node);
|
||||
pills.render(pill, pillContainer, node);
|
||||
node.replaceWith(pillContainer);
|
||||
// Pills within pills aren't going to go well, so move on
|
||||
pillified = true;
|
||||
|
||||
@ -147,8 +146,8 @@ export function pillifyLinks(
|
||||
</StrictMode>
|
||||
);
|
||||
|
||||
pills.render(pill, pillContainer);
|
||||
roomNotifTextNode.parentNode?.replaceChild(pillContainer, roomNotifTextNode);
|
||||
pills.render(pill, pillContainer, roomNotifTextNode);
|
||||
roomNotifTextNode.replaceWith(pillContainer);
|
||||
}
|
||||
// Nothing else to do for a text node (and we don't need to advance
|
||||
// the loop pointer because we did it above)
|
||||
|
||||
@ -15,7 +15,7 @@ import { createRoot, Root } from "react-dom/client";
|
||||
export class ReactRootManager {
|
||||
private roots: Root[] = [];
|
||||
private rootElements: Element[] = [];
|
||||
private revertElements: Array<null | Element> = [];
|
||||
private revertElements: Array<Node | null> = [];
|
||||
|
||||
public get elements(): Element[] {
|
||||
return this.rootElements;
|
||||
@ -26,12 +26,13 @@ export class ReactRootManager {
|
||||
* @param children the React component to render
|
||||
* @param rootElement the root element to render the component into
|
||||
* @param revertElement the element to replace the root element with when unmounting
|
||||
* needed to support double-rendering in React 18 Strict Dev mode
|
||||
*/
|
||||
public render(children: ReactNode, rootElement: Element, revertElement?: Element): void {
|
||||
public render(children: ReactNode, rootElement: Element, revertElement: Node | null): void {
|
||||
const root = createRoot(rootElement);
|
||||
this.roots.push(root);
|
||||
this.rootElements.push(rootElement);
|
||||
this.revertElements.push(revertElement ?? null);
|
||||
this.revertElements.push(revertElement);
|
||||
root.render(children);
|
||||
}
|
||||
|
||||
|
||||
@ -66,7 +66,7 @@ export function tooltipifyLinks(
|
||||
</StrictMode>
|
||||
);
|
||||
|
||||
tooltips.render(tooltip, node);
|
||||
tooltips.render(tooltip, node, null);
|
||||
} else if (node.childNodes?.length) {
|
||||
tooltipifyLinks(node.childNodes as NodeListOf<Element>, ignoredNodes, tooltips);
|
||||
}
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
/* eslint @typescript-eslint/no-unused-vars: ["error", { "varsIgnorePattern": "^_" }] */
|
||||
// Copyright 2024 New Vector Ltd.
|
||||
// Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
@ -24,7 +23,7 @@ describe("<SyntaxHighlight />", () => {
|
||||
const { container } = render(<SyntaxHighlight language={lang}>// Hello, World</SyntaxHighlight>);
|
||||
await waitFor(() => expect(container.querySelector(`.language-${lang}`)).toBeTruthy());
|
||||
|
||||
const [_lang, opts] = mock.mock.lastCall!;
|
||||
const [, opts] = mock.mock.lastCall!;
|
||||
expect((opts as unknown as HighlightOptions)["language"]).toBe(lang);
|
||||
});
|
||||
});
|
||||
|
||||
@ -10,6 +10,7 @@ import * as React from "react";
|
||||
import { EventType, MatrixEvent, RoomMember, THREAD_RELATION_TYPE } from "matrix-js-sdk/src/matrix";
|
||||
import { act, fireEvent, render, screen, waitFor } from "jest-matrix-react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import { initOnce } from "@vector-im/matrix-wysiwyg";
|
||||
|
||||
import {
|
||||
clearAllModals,
|
||||
@ -52,6 +53,8 @@ const expectVoiceMessageRecordingTriggered = (): void => {
|
||||
expect(screen.getByText("No microphone found")).toBeInTheDocument();
|
||||
};
|
||||
|
||||
beforeAll(initOnce, 10000);
|
||||
|
||||
describe("MessageComposer", () => {
|
||||
stubClient();
|
||||
const cli = createTestClient();
|
||||
|
||||
@ -9,6 +9,7 @@ Please see LICENSE files in the repository root for full details.
|
||||
import "@testing-library/jest-dom";
|
||||
import React from "react";
|
||||
import { fireEvent, render, screen, waitFor } from "jest-matrix-react";
|
||||
import { initOnce } from "@vector-im/matrix-wysiwyg";
|
||||
|
||||
import MatrixClientContext from "../../../../../../src/contexts/MatrixClientContext";
|
||||
import defaultDispatcher from "../../../../../../src/dispatcher/dispatcher";
|
||||
@ -24,6 +25,8 @@ import * as EmojiButton from "../../../../../../src/components/views/rooms/Emoji
|
||||
import { createMocks } from "./utils";
|
||||
import { ScopedRoomContextProvider } from "../../../../../../src/contexts/ScopedRoomContext.tsx";
|
||||
|
||||
beforeAll(initOnce, 10000);
|
||||
|
||||
describe("EditWysiwygComposer", () => {
|
||||
afterEach(() => {
|
||||
jest.resetAllMocks();
|
||||
@ -46,17 +49,6 @@ describe("EditWysiwygComposer", () => {
|
||||
);
|
||||
};
|
||||
|
||||
beforeAll(
|
||||
async () => {
|
||||
// Load the dynamic import
|
||||
const component = customRender(false);
|
||||
await component.findByRole("textbox");
|
||||
component.unmount();
|
||||
},
|
||||
// it can take a while to load the wasm
|
||||
20000,
|
||||
);
|
||||
|
||||
it("Should not render the component when not ready", async () => {
|
||||
// When
|
||||
const { rerender } = customRender(false);
|
||||
|
||||
@ -9,6 +9,7 @@ Please see LICENSE files in the repository root for full details.
|
||||
import "@testing-library/jest-dom";
|
||||
import React from "react";
|
||||
import { act, fireEvent, render, screen, waitFor } from "jest-matrix-react";
|
||||
import { initOnce } from "@vector-im/matrix-wysiwyg";
|
||||
|
||||
import MatrixClientContext from "../../../../../../src/contexts/MatrixClientContext";
|
||||
import defaultDispatcher from "../../../../../../src/dispatcher/dispatcher";
|
||||
@ -31,6 +32,8 @@ jest.mock("../../../../../../src/components/views/rooms/EmojiButton", () => ({
|
||||
},
|
||||
}));
|
||||
|
||||
beforeAll(initOnce, 10000);
|
||||
|
||||
describe("SendWysiwygComposer", () => {
|
||||
afterEach(() => {
|
||||
jest.resetAllMocks();
|
||||
|
||||
@ -9,6 +9,7 @@ Please see LICENSE files in the repository root for full details.
|
||||
import React from "react";
|
||||
import { act, render, screen } from "jest-matrix-react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import { initOnce } from "@vector-im/matrix-wysiwyg";
|
||||
|
||||
import { PlainTextComposer } from "../../../../../../../src/components/views/rooms/wysiwyg_composer/components/PlainTextComposer";
|
||||
import * as mockUseSettingsHook from "../../../../../../../src/hooks/useSettings";
|
||||
@ -16,6 +17,8 @@ import * as mockKeyboard from "../../../../../../../src/Keyboard";
|
||||
import { createMocks } from "../utils";
|
||||
import { ScopedRoomContextProvider } from "../../../../../../../src/contexts/ScopedRoomContext.tsx";
|
||||
|
||||
beforeAll(initOnce, 10000);
|
||||
|
||||
describe("PlainTextComposer", () => {
|
||||
const customRender = (
|
||||
onChange = (_content: string): void => void 0,
|
||||
|
||||
@ -9,6 +9,7 @@ Please see LICENSE files in the repository root for full details.
|
||||
import "@testing-library/jest-dom";
|
||||
import React, { createRef } from "react";
|
||||
import { render, screen, waitFor } from "jest-matrix-react";
|
||||
import { initOnce } from "@vector-im/matrix-wysiwyg";
|
||||
|
||||
import MatrixClientContext from "../../../../../../../src/contexts/MatrixClientContext";
|
||||
import { WysiwygAutocomplete } from "../../../../../../../src/components/views/rooms/wysiwyg_composer/components/WysiwygAutocomplete";
|
||||
@ -42,6 +43,8 @@ const constructMockProvider = (data: ICompletion[]) =>
|
||||
renderCompletions: jest.fn().mockImplementation((components) => components),
|
||||
}) as unknown as AutocompleteProvider;
|
||||
|
||||
beforeAll(initOnce, 10000);
|
||||
|
||||
describe("WysiwygAutocomplete", () => {
|
||||
beforeAll(() => {
|
||||
// scrollTo not implemented in JSDOM
|
||||
|
||||
@ -10,6 +10,7 @@ import "@testing-library/jest-dom";
|
||||
import React from "react";
|
||||
import { act, fireEvent, render, screen, waitFor } from "jest-matrix-react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import { initOnce } from "@vector-im/matrix-wysiwyg";
|
||||
|
||||
import { WysiwygComposer } from "../../../../../../../src/components/views/rooms/wysiwyg_composer/components/WysiwygComposer";
|
||||
import SettingsStore from "../../../../../../../src/settings/SettingsStore";
|
||||
@ -33,6 +34,8 @@ import * as Permalinks from "../../../../../../../src/utils/permalinks/Permalink
|
||||
import { PermalinkParts } from "../../../../../../../src/utils/permalinks/PermalinkConstructor";
|
||||
import { ScopedRoomContextProvider } from "../../../../../../../src/contexts/ScopedRoomContext.tsx";
|
||||
|
||||
beforeAll(initOnce, 10000);
|
||||
|
||||
describe("WysiwygComposer", () => {
|
||||
const customRender = (onChange = jest.fn(), onSend = jest.fn(), disabled = false, initialContent?: string) => {
|
||||
const { mockClient, defaultRoomContext } = createMocks();
|
||||
|
||||
@ -5,7 +5,9 @@ Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { MsgType } from "matrix-js-sdk/src/matrix";
|
||||
import { initOnce } from "@vector-im/matrix-wysiwyg";
|
||||
|
||||
import { filterConsole, mkEvent } from "../../../../../../test-utils";
|
||||
import {
|
||||
@ -13,6 +15,8 @@ import {
|
||||
EMOTE_PREFIX,
|
||||
} from "../../../../../../../src/components/views/rooms/wysiwyg_composer/utils/createMessageContent";
|
||||
|
||||
beforeAll(initOnce, 10000);
|
||||
|
||||
describe("createMessageContent", () => {
|
||||
const message = "<em><b>hello</b> world</em>";
|
||||
|
||||
@ -25,13 +29,6 @@ describe("createMessageContent", () => {
|
||||
"WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm`",
|
||||
);
|
||||
|
||||
beforeAll(async () => {
|
||||
// Warm up by creating the component once, with a long timeout.
|
||||
// This prevents tests timing out because of the time spent loading
|
||||
// the WASM component.
|
||||
await createMessageContent(message, true, {});
|
||||
}, 10000);
|
||||
|
||||
it("Should create html message", async () => {
|
||||
// When
|
||||
const content = await createMessageContent(message, true, {});
|
||||
|
||||
88
yarn.lock
88
yarn.lock
@ -259,11 +259,6 @@
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz#1aabb72ee72ed35789b4bbcad3ca2862ce614e8c"
|
||||
integrity sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==
|
||||
|
||||
"@babel/helper-validator-identifier@^7.24.5":
|
||||
version "7.25.7"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.7.tgz#77b7f60c40b15c97df735b38a66ba1d7c3e93da5"
|
||||
integrity sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==
|
||||
|
||||
"@babel/helper-validator-identifier@^7.24.7", "@babel/helper-validator-identifier@^7.25.7", "@babel/helper-validator-identifier@^7.25.9":
|
||||
version "7.25.9"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz#24b64e2c3ec7cd3b3c547729b8d16871f22cbdc7"
|
||||
@ -1549,21 +1544,6 @@
|
||||
minimatch "^3.1.2"
|
||||
strip-json-comments "^3.1.1"
|
||||
|
||||
"@eslint/eslintrc@^3.0.2":
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-3.1.0.tgz#dbd3482bfd91efa663cbe7aa1f506839868207b6"
|
||||
integrity sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==
|
||||
dependencies:
|
||||
ajv "^6.12.4"
|
||||
debug "^4.3.2"
|
||||
espree "^10.0.1"
|
||||
globals "^14.0.0"
|
||||
ignore "^5.2.0"
|
||||
import-fresh "^3.2.1"
|
||||
js-yaml "^4.1.0"
|
||||
minimatch "^3.1.2"
|
||||
strip-json-comments "^3.1.1"
|
||||
|
||||
"@eslint/js@8.57.1":
|
||||
version "8.57.1"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.57.1.tgz#de633db3ec2ef6a3c89e2f19038063e8a122e2c2"
|
||||
@ -3425,12 +3405,16 @@
|
||||
ts-xor "^1.3.0"
|
||||
vaul "^1.0.0"
|
||||
|
||||
"@vector-im/matrix-wysiwyg@2.37.13":
|
||||
version "2.37.13"
|
||||
resolved "https://registry.yarnpkg.com/@vector-im/matrix-wysiwyg/-/matrix-wysiwyg-2.37.13.tgz#7b64e7652a196e811c0470dcbff8d36e2229cd46"
|
||||
integrity sha512-3ilnJBJSzeTfAQXNJJ29EAqa14exrkca3acTPssdoh3WhTKwXyQ0xU8sS50d6gqlAP/Nahw1y2k+PzajXo1SsQ==
|
||||
"@vector-im/matrix-wysiwyg-wasm@link:../../bindings/wysiwyg-wasm":
|
||||
version "0.0.0"
|
||||
uid ""
|
||||
|
||||
"@vector-im/matrix-wysiwyg@2.38.0":
|
||||
version "2.38.0"
|
||||
resolved "https://registry.yarnpkg.com/@vector-im/matrix-wysiwyg/-/matrix-wysiwyg-2.38.0.tgz#af862ffd231dc0a6b8d6f2cb3601e68456c0ff24"
|
||||
integrity sha512-cMEVicFYVzFxuSyWON0aVGjAJMcgJZ+LxuLTEp8EGuu8cRacuh0RN5rapb11YVZygzFvE7X1cMedJ/fKd5vRLA==
|
||||
dependencies:
|
||||
eslint-plugin-unicorn "^54.0.0"
|
||||
"@vector-im/matrix-wysiwyg-wasm" "link:../../Library/Caches/Yarn/v6/npm-@vector-im-matrix-wysiwyg-2.38.0-af862ffd231dc0a6b8d6f2cb3601e68456c0ff24-integrity/node_modules/bindings/wysiwyg-wasm"
|
||||
|
||||
"@webassemblyjs/ast@1.14.1", "@webassemblyjs/ast@^1.14.1":
|
||||
version "1.14.1"
|
||||
@ -3628,7 +3612,7 @@ acorn-walk@^8.0.0, acorn-walk@^8.0.2, acorn-walk@^8.1.1:
|
||||
dependencies:
|
||||
acorn "^8.11.0"
|
||||
|
||||
acorn@^8.0.4, acorn@^8.1.0, acorn@^8.11.0, acorn@^8.12.0, acorn@^8.4.1, acorn@^8.9.0:
|
||||
acorn@^8.0.4, acorn@^8.1.0, acorn@^8.11.0, acorn@^8.4.1, acorn@^8.9.0:
|
||||
version "8.13.0"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.13.0.tgz#2a30d670818ad16ddd6a35d3842dacec9e5d7ca3"
|
||||
integrity sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==
|
||||
@ -4636,13 +4620,6 @@ copy-webpack-plugin@^12.0.0:
|
||||
schema-utils "^4.2.0"
|
||||
serialize-javascript "^6.0.2"
|
||||
|
||||
core-js-compat@^3.37.0:
|
||||
version "3.38.1"
|
||||
resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.38.1.tgz#2bc7a298746ca5a7bcb9c164bcb120f2ebc09a09"
|
||||
integrity sha512-JRH6gfXxGmrzF3tZ57lFx97YARxCXPaMzPo6jELZhv88pBH5VXpQ+y0znKGlFnzuaihqhLbefxSJxWJMPtfDzw==
|
||||
dependencies:
|
||||
browserslist "^4.23.3"
|
||||
|
||||
core-js-compat@^3.38.0, core-js-compat@^3.38.1:
|
||||
version "3.39.0"
|
||||
resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.39.0.tgz#b12dccb495f2601dc860bdbe7b4e3ffa8ba63f61"
|
||||
@ -5716,28 +5693,6 @@ eslint-plugin-react@^7.28.0:
|
||||
string.prototype.matchall "^4.0.11"
|
||||
string.prototype.repeat "^1.0.0"
|
||||
|
||||
eslint-plugin-unicorn@^54.0.0:
|
||||
version "54.0.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-unicorn/-/eslint-plugin-unicorn-54.0.0.tgz#ce3ea853e8fd7ca2bda2fd6065bf065adb5d8b6d"
|
||||
integrity sha512-XxYLRiYtAWiAjPv6z4JREby1TAE2byBC7wlh0V4vWDCpccOSU1KovWV//jqPXF6bq3WKxqX9rdjoRQ1EhdmNdQ==
|
||||
dependencies:
|
||||
"@babel/helper-validator-identifier" "^7.24.5"
|
||||
"@eslint-community/eslint-utils" "^4.4.0"
|
||||
"@eslint/eslintrc" "^3.0.2"
|
||||
ci-info "^4.0.0"
|
||||
clean-regexp "^1.0.0"
|
||||
core-js-compat "^3.37.0"
|
||||
esquery "^1.5.0"
|
||||
indent-string "^4.0.0"
|
||||
is-builtin-module "^3.2.1"
|
||||
jsesc "^3.0.2"
|
||||
pluralize "^8.0.0"
|
||||
read-pkg-up "^7.0.1"
|
||||
regexp-tree "^0.1.27"
|
||||
regjsparser "^0.10.0"
|
||||
semver "^7.6.1"
|
||||
strip-indent "^3.0.0"
|
||||
|
||||
eslint-plugin-unicorn@^56.0.0:
|
||||
version "56.0.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-unicorn/-/eslint-plugin-unicorn-56.0.1.tgz#d10a3df69ba885939075bdc95a65a0c872e940d4"
|
||||
@ -5791,11 +5746,6 @@ eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4
|
||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800"
|
||||
integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==
|
||||
|
||||
eslint-visitor-keys@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.1.0.tgz#1f785cc5e81eb7534523d85922248232077d2f8c"
|
||||
integrity sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg==
|
||||
|
||||
eslint-visitor-keys@^4.2.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz#687bacb2af884fcdda8a6e7d65c606f46a14cd45"
|
||||
@ -5845,15 +5795,6 @@ eslint@8.57.1:
|
||||
strip-ansi "^6.0.1"
|
||||
text-table "^0.2.0"
|
||||
|
||||
espree@^10.0.1:
|
||||
version "10.2.0"
|
||||
resolved "https://registry.yarnpkg.com/espree/-/espree-10.2.0.tgz#f4bcead9e05b0615c968e85f83816bc386a45df6"
|
||||
integrity sha512-upbkBJbckcCNBDBDXEbuhjbP68n+scUd3k/U2EkyM9nw+I/jPiL4cLF/Al06CF96wRltFda16sxDFrxsI1v0/g==
|
||||
dependencies:
|
||||
acorn "^8.12.0"
|
||||
acorn-jsx "^5.3.2"
|
||||
eslint-visitor-keys "^4.1.0"
|
||||
|
||||
espree@^10.3.0:
|
||||
version "10.3.0"
|
||||
resolved "https://registry.yarnpkg.com/espree/-/espree-10.3.0.tgz#29267cf5b0cb98735b65e64ba07e0ed49d1eed8a"
|
||||
@ -5877,7 +5818,7 @@ esprima@^4.0.0, esprima@^4.0.1:
|
||||
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
|
||||
integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
|
||||
|
||||
esquery@^1.4.2, esquery@^1.5.0, esquery@^1.6.0:
|
||||
esquery@^1.4.2, esquery@^1.6.0:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.6.0.tgz#91419234f804d852a82dceec3e16cdc22cf9dae7"
|
||||
integrity sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==
|
||||
@ -6518,11 +6459,6 @@ globals@^13.19.0:
|
||||
dependencies:
|
||||
type-fest "^0.20.2"
|
||||
|
||||
globals@^14.0.0:
|
||||
version "14.0.0"
|
||||
resolved "https://registry.yarnpkg.com/globals/-/globals-14.0.0.tgz#898d7413c29babcf6bafe56fcadded858ada724e"
|
||||
integrity sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==
|
||||
|
||||
globals@^15.9.0:
|
||||
version "15.13.0"
|
||||
resolved "https://registry.yarnpkg.com/globals/-/globals-15.13.0.tgz#bbec719d69aafef188ecd67954aae76a696010fc"
|
||||
@ -10568,7 +10504,7 @@ semver@^6.3.0, semver@^6.3.1:
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4"
|
||||
integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
|
||||
|
||||
semver@^7.5.2, semver@^7.5.3, semver@^7.5.4, semver@^7.6.0, semver@^7.6.1, semver@^7.6.3:
|
||||
semver@^7.5.2, semver@^7.5.3, semver@^7.5.4, semver@^7.6.0, semver@^7.6.3:
|
||||
version "7.6.3"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143"
|
||||
integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user