', {widgetName}, {sender});
}
}
From b97aa77acac821a429e727edce3ce46365e88819 Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Fri, 15 Jun 2018 19:27:23 +0100
Subject: [PATCH 02/10] factor out warn self demote and apply to muting
yourself
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
---
src/components/views/rooms/MemberInfo.js | 53 +++++++++++++++++-------
1 file changed, 37 insertions(+), 16 deletions(-)
diff --git a/src/components/views/rooms/MemberInfo.js b/src/components/views/rooms/MemberInfo.js
index 2789c0e4cd..4a163b6a00 100644
--- a/src/components/views/rooms/MemberInfo.js
+++ b/src/components/views/rooms/MemberInfo.js
@@ -332,13 +332,42 @@ module.exports = withMatrixClient(React.createClass({
});
},
- onMuteToggle: function() {
+ _warnSelfDemote: function() {
+ const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
+ return new Promise((resolve) => {
+ Modal.createTrackedDialog('Demoting Self', '', QuestionDialog, {
+ title: _t("Warning!"),
+ description:
+
+ { _t("You will not be able to undo this change as you are demoting yourself, " +
+ "if you are the last privileged user in the room it will be impossible " +
+ "to regain privileges.") }
+
+ { _t("Are you sure?") }
+
,
+ button: _t("Continue"),
+ onFinished: resolve,
+ });
+ });
+ },
+
+ onMuteToggle: async function() {
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
const roomId = this.props.member.roomId;
const target = this.props.member.userId;
const room = this.props.matrixClient.getRoom(roomId);
if (!room) return;
+ // if muting self, warn as it may be irreversible
+ if (target === this.props.matrixClient.getUserId()) {
+ try {
+ if (!await this._warnSelfDemote()) return;
+ } catch (e) {
+ console.error("Failed to warn about self demotion: ", e);
+ return;
+ }
+ }
+
const powerLevelEvent = room.currentState.getStateEvents("m.room.power_levels", "");
if (!powerLevelEvent) return;
@@ -436,7 +465,7 @@ module.exports = withMatrixClient(React.createClass({
}).done();
},
- onPowerChange: function(powerLevel) {
+ onPowerChange: async function(powerLevel) {
const roomId = this.props.member.roomId;
const target = this.props.member.userId;
const room = this.props.matrixClient.getRoom(roomId);
@@ -455,20 +484,12 @@ module.exports = withMatrixClient(React.createClass({
// If we are changing our own PL it can only ever be decreasing, which we cannot reverse.
if (myUserId === target) {
- Modal.createTrackedDialog('Demoting Self', '', QuestionDialog, {
- title: _t("Warning!"),
- description:
-
- { _t("You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.") }
- { _t("Are you sure?") }
-
,
- button: _t("Continue"),
- onFinished: (confirmed) => {
- if (confirmed) {
- this._applyPowerChange(roomId, target, powerLevel, powerLevelEvent);
- }
- },
- });
+ try {
+ if (!await this._warnSelfDemote()) return;
+ this._applyPowerChange(roomId, target, powerLevel, powerLevelEvent);
+ } catch (e) {
+ console.error("Failed to warn about self demotion: ", e);
+ }
return;
}
From df1584148334646e0e278617b6041f7520989b82 Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Fri, 15 Jun 2018 19:28:23 +0100
Subject: [PATCH 03/10] split too long line
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
---
src/components/views/rooms/MemberInfo.js | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/components/views/rooms/MemberInfo.js b/src/components/views/rooms/MemberInfo.js
index 4a163b6a00..6680e7d02c 100644
--- a/src/components/views/rooms/MemberInfo.js
+++ b/src/components/views/rooms/MemberInfo.js
@@ -499,7 +499,8 @@ module.exports = withMatrixClient(React.createClass({
title: _t("Warning!"),
description:
- { _t("You will not be able to undo this change as you are promoting the user to have the same power level as yourself.") }
+ { _t("You will not be able to undo this change as you are promoting the user " +
+ "to have the same power level as yourself.") }
{ _t("Are you sure?") }
,
button: _t("Continue"),
From 1d91469104bae6f94c33cc772130cb5c67b52847 Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Fri, 29 Jun 2018 14:52:25 +0100
Subject: [PATCH 04/10] switch to and use `` over
``
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
---
src/TextForEvent.js | 68 +++++++++++++++++++++++++++------------------
1 file changed, 41 insertions(+), 27 deletions(-)
diff --git a/src/TextForEvent.js b/src/TextForEvent.js
index 0cdaaac4ab..3d2e3c1fb5 100644
--- a/src/TextForEvent.js
+++ b/src/TextForEvent.js
@@ -19,16 +19,30 @@ import { _t } from './languageHandler';
import * as Roles from './Roles';
import dis from "./dispatcher";
import React from 'react';
+import PropTypes from 'prop-types';
-function onUsernameClick(e) {
- dis.dispatch({
- action: 'insert_mention',
- user_id: e.target.id,
- });
-}
+class ClickableUsername extends React.PureComponent {
+ static propTypes = {
+ mxid: PropTypes.string.isRequired,
+ text: PropTypes.string.isRequired,
+ };
-function makeUsernameSpan(mxid, text) {
- return { text };
+ constructor(props) {
+ super(props);
+ this.onClick = this.onClick.bind(this);
+ }
+
+ onClick() {
+ dis.dispatch({
+ action: 'insert_mention',
+ user_id: this.props.mxid,
+ });
+ }
+
+ render() {
+ const {mxid, text} = this.props;
+ return { text };
+ }
}
function textForMemberEvent(ev) {
@@ -36,8 +50,8 @@ function textForMemberEvent(ev) {
const senderName = ev.sender ? ev.sender.name : ev.getSender();
const targetName = ev.target ? ev.target.name : ev.getStateKey();
- const sender = makeUsernameSpan(ev.getSender(), senderName);
- const target = makeUsernameSpan(ev.getStateKey(), targetName);
+ const sender = ;
+ const target = ;
const prevContent = ev.getPrevContent();
const content = ev.getContent();
@@ -71,18 +85,18 @@ function textForMemberEvent(ev) {
if (prevContent && prevContent.membership === 'join') {
if (prevContent.displayname && content.displayname && prevContent.displayname !== content.displayname) {
return _t(' changed their display name to .', {}, {
- oldDisplayName: makeUsernameSpan(ev.getStateKey(), prevContent.displayname),
- displayName: makeUsernameSpan(ev.getStateKey(), content.displayname),
+ oldDisplayName: ,
+ displayName: ,
});
} else if (!prevContent.displayname && content.displayname) {
return _t(' set their display name to .', {}, {
sender,
- displayName: makeUsernameSpan(ev.getSender(), content.displayname),
+ displayName: ,
});
} else if (prevContent.displayname && !content.displayname) {
return _t(' removed their display name ().', {
sender,
- oldDisplayName: makeUsernameSpan(ev.getSender(), prevContent.displayname),
+ oldDisplayName: ,
});
} else if (prevContent.avatar_url && !content.avatar_url) {
return _t(' removed their profile picture.', {}, {sender});
@@ -129,13 +143,13 @@ function textForTopicEvent(ev) {
return _t(' changed the topic to "%(topic)s".', {
topic: ev.getContent().topic,
}, {
- sender: makeUsernameSpan(ev.getSender(), senderDisplayName),
+ sender: ,
});
}
function textForRoomNameEvent(ev) {
const senderDisplayName = ev.sender && ev.sender.name ? ev.sender.name : ev.getSender();
- const sender = makeUsernameSpan(ev.getSender(), senderDisplayName);
+ const sender = ;
if (!ev.getContent().name || ev.getContent().name.trim().length === 0) {
return _t(' removed the room name.', {}, {sender});
@@ -154,7 +168,7 @@ function textForMessageEvent(ev) {
message = "* " + senderDisplayName + " " + message;
} else if (ev.getContent().msgtype === "m.image") {
message = _t(' sent an image.', {}, {
- sender: makeUsernameSpan(ev.getSender(), senderDisplayName),
+ sender: ,
});
}
return message;
@@ -164,7 +178,7 @@ function textForCallAnswerEvent(event) {
const senderName = event.sender ? event.sender.name : _t('Someone');
const supported = MatrixClientPeg.get().supportsVoip() ? '' : _t('(not supported by this browser)');
return _t(' answered the call.', {}, {
- sender: makeUsernameSpan(event.getSender(), senderName),
+ sender: ,
}) + ' ' + supported;
}
@@ -184,13 +198,13 @@ function textForCallHangupEvent(event) {
}
}
return _t(' ended the call.', {}, {
- sender: makeUsernameSpan(event.getSender(), senderName),
+ sender: ,
}) + ' ' + reason;
}
function textForCallInviteEvent(event) {
const senderName = event.sender ? event.sender.name : _t('Someone');
- const sender = makeUsernameSpan(event.getSender(), senderName);
+ const sender = ;
// FIXME: Find a better way to determine this from the event?
let callType = "voice";
if (event.getContent().offer && event.getContent().offer.sdp &&
@@ -206,13 +220,13 @@ function textForThreePidInviteEvent(event) {
return _t(' sent an invitation to %(targetDisplayName)s to join the room.', {
targetDisplayName: event.getContent().display_name,
}, {
- sender: makeUsernameSpan(event.getSender(), senderName),
+ sender: ,
});
}
function textForHistoryVisibilityEvent(event) {
const senderName = event.sender ? event.sender.name : event.getSender();
- const sender = makeUsernameSpan(event.getSender(), senderName);
+ const sender = ;
switch (event.getContent().history_visibility) {
case 'invited':
return _t(' made future room history visible to all room members, '
@@ -238,7 +252,7 @@ function textForEncryptionEvent(event) {
return _t(' turned on end-to-end encryption (algorithm %(algorithm)s).', {
algorithm: event.getContent().algorithm,
}, {
- sender: makeUsernameSpan(event.getSender(), senderName),
+ sender: ,
});
}
@@ -274,7 +288,7 @@ function textForPowerEvent(event) {
fromPowerLevel: Roles.textualPowerLevel(from, userDefault),
toPowerLevel: Roles.textualPowerLevel(to, userDefault),
}, {
- user: makeUsernameSpan(userId, userId),
+ user: ,
}),
);
}
@@ -285,19 +299,19 @@ function textForPowerEvent(event) {
return _t(' changed the power level of %(powerLevelDiffText)s.', {
powerLevelDiffText: diff.join(", "),
}, {
- sender: makeUsernameSpan(event.getSender(), senderName),
+ sender: ,
});
}
function textForPinnedEvent(event) {
const senderName = event.sender ? event.sender.name : event.getSender();
- const sender = makeUsernameSpan(event.getSender(), senderName);
+ const sender = ;
return _t(" changed the pinned messages for the room.", {}, {sender});
}
function textForWidgetEvent(event) {
const senderName = event.sender ? event.sender.name : event.getSender();
- const sender = makeUsernameSpan(event.getSender(), senderName);
+ const sender = ;
const {name: prevName, type: prevType, url: prevUrl} = event.getPrevContent();
const {name, type, url} = event.getContent() || {};
From dddf7991b904353eb6884b185d17fd877256b226 Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Fri, 29 Jun 2018 14:52:50 +0100
Subject: [PATCH 05/10] create map-i18n to aid with transforming the i18n
entries not to waste them
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
---
scripts/map-i18n.js | 69 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 69 insertions(+)
create mode 100644 scripts/map-i18n.js
diff --git a/scripts/map-i18n.js b/scripts/map-i18n.js
new file mode 100644
index 0000000000..32f81d5e82
--- /dev/null
+++ b/scripts/map-i18n.js
@@ -0,0 +1,69 @@
+#!/usr/bin/env node
+
+/*
+Copyright 2018 New Vector Ltd
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * Looks through all the translation files and maps matches of fromRegex
+ * in both key and value of the i18n translation to toStr where i18nKeyRegex
+ * matches. Simplifies changing from text to react replacements.
+ * e.g:
+ * node scripts\map-i18n.js "%\(targetName\)s accepted the invitation for %\(displayName\)s\." "%\(targetName\)s" ""
+ */
+
+const fs = require('fs');
+const path = require('path');
+
+const I18NDIR = 'src/i18n/strings';
+
+if (process.argv.length !== 5) {
+ console.error("Required exactly 3 arguments");
+ console.info("Usage: ");
+ return;
+}
+
+const [, , i18nKey, fromStr, toStr] = process.argv;
+const i18nKeyRegex = new RegExp(i18nKey, 'i');
+const fromRegex = new RegExp(fromStr, 'i');
+
+console.info(`Replacing instances of "${fromRegex}" with "${toStr}" in keys and values where key matches "${i18nKey}"`);
+
+for (const filename of fs.readdirSync(I18NDIR)) {
+ if (!filename.endsWith('.json')) continue;
+
+ let numChanged = 0;
+
+ const trs = JSON.parse(fs.readFileSync(path.join(I18NDIR, filename)));
+ for (const tr of Object.keys(trs)) {
+ if (i18nKeyRegex.test(tr) && (fromRegex.test(tr) || fromRegex.test(tr))) {
+ const v = trs[tr];
+ delete trs[tr];
+
+ trs[tr.replace(fromRegex, toStr)] = v.replace(fromRegex, toStr);
+ numChanged++;
+ }
+ }
+
+ if (numChanged > 0) {
+ console.log(`${filename}: transformed ${numChanged} translations`);
+ // XXX: This is totally relying on the impl serialising the JSON object in the
+ // same order as they were parsed from the file. JSON.stringify() has a specific argument
+ // that can be used to control the order, but JSON.parse() lacks any kind of equivalent.
+ // Empirically this does maintain the order on my system, so I'm going to leave it like
+ // this for now.
+ fs.writeFileSync(path.join(I18NDIR, filename), JSON.stringify(trs, undefined, 4) + "\n");
+ }
+}
From 36ace9dcb935b7b91f87963c3d8815566ecc0e69 Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Fri, 29 Jun 2018 15:21:44 +0100
Subject: [PATCH 06/10] using map-i18n remap all changed `%(...)s` => `<...>`
to keep i18n
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
---
src/i18n/strings/bg.json | 80 +++++++++++++++++------------------
src/i18n/strings/ca.json | 80 +++++++++++++++++------------------
src/i18n/strings/cs.json | 78 +++++++++++++++++-----------------
src/i18n/strings/da.json | 48 ++++++++++-----------
src/i18n/strings/de_DE.json | 80 +++++++++++++++++------------------
src/i18n/strings/el.json | 80 +++++++++++++++++------------------
src/i18n/strings/en_EN.json | 80 +++++++++++++++++------------------
src/i18n/strings/en_US.json | 76 ++++++++++++++++-----------------
src/i18n/strings/eo.json | 80 +++++++++++++++++------------------
src/i18n/strings/es.json | 64 ++++++++++++++--------------
src/i18n/strings/eu.json | 80 +++++++++++++++++------------------
src/i18n/strings/fi.json | 78 +++++++++++++++++-----------------
src/i18n/strings/fr.json | 80 +++++++++++++++++------------------
src/i18n/strings/gl.json | 80 +++++++++++++++++------------------
src/i18n/strings/hu.json | 80 +++++++++++++++++------------------
src/i18n/strings/id.json | 20 ++++-----
src/i18n/strings/is.json | 10 ++---
src/i18n/strings/it.json | 80 +++++++++++++++++------------------
src/i18n/strings/ja.json | 4 +-
src/i18n/strings/ko.json | 70 +++++++++++++++---------------
src/i18n/strings/lv.json | 80 +++++++++++++++++------------------
src/i18n/strings/nl.json | 80 +++++++++++++++++------------------
src/i18n/strings/pl.json | 80 +++++++++++++++++------------------
src/i18n/strings/pt.json | 76 ++++++++++++++++-----------------
src/i18n/strings/pt_BR.json | 80 +++++++++++++++++------------------
src/i18n/strings/ru.json | 80 +++++++++++++++++------------------
src/i18n/strings/sk.json | 80 +++++++++++++++++------------------
src/i18n/strings/sr.json | 80 +++++++++++++++++------------------
src/i18n/strings/sv.json | 80 +++++++++++++++++------------------
src/i18n/strings/te.json | 10 ++---
src/i18n/strings/th.json | 48 ++++++++++-----------
src/i18n/strings/tr.json | 70 +++++++++++++++---------------
src/i18n/strings/uk.json | 20 ++++-----
src/i18n/strings/zh_Hans.json | 80 +++++++++++++++++------------------
src/i18n/strings/zh_Hant.json | 80 +++++++++++++++++------------------
35 files changed, 1176 insertions(+), 1176 deletions(-)
diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json
index 5ec9a93bc5..cd5cf5058e 100644
--- a/src/i18n/strings/bg.json
+++ b/src/i18n/strings/bg.json
@@ -148,49 +148,13 @@
"Verified key": "Потвърден ключ",
"Unrecognised command:": "Неразпозната команда:",
"Reason": "Причина",
- "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s прие поканата за %(displayName)s.",
- "%(targetName)s accepted an invitation.": "%(targetName)s прие поканата.",
- "%(senderName)s requested a VoIP conference.": "%(senderName)s заяви VoIP групов разговор.",
- "%(senderName)s invited %(targetName)s.": "%(senderName)s покани %(targetName)s.",
- "%(senderName)s banned %(targetName)s.": "%(senderName)s блокира %(targetName)s.",
- "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s смени своето име на %(displayName)s.",
- "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s си сложи име %(displayName)s.",
- "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s премахна своето име (%(oldDisplayName)s).",
- "%(senderName)s removed their profile picture.": "%(senderName)s премахна своята профилна снимка.",
- "%(senderName)s changed their profile picture.": "%(senderName)s промени своята профилна снимка.",
- "%(senderName)s set a profile picture.": "%(senderName)s зададе снимка на профила си.",
"VoIP conference started.": "Започна VoIP групов разговор.",
- "%(targetName)s joined the room.": "%(targetName)s се присъедини към стаята.",
"VoIP conference finished.": "Груповият разговор приключи.",
- "%(targetName)s rejected the invitation.": "%(targetName)s отхвърли поканата.",
- "%(targetName)s left the room.": "%(targetName)s напусна стаята.",
- "%(senderName)s unbanned %(targetName)s.": "%(senderName)s отблокира %(targetName)s.",
- "%(senderName)s kicked %(targetName)s.": "%(senderName)s изгони %(targetName)s.",
- "%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s оттегли поканата си за %(targetName)s.",
- "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s смени темата на \"%(topic)s\".",
- "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s премахна името на стаята.",
- "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s промени името на стаята на %(roomName)s.",
"%(senderDisplayName)s sent an image.": "%(senderDisplayName)s изпрати снимка.",
"Someone": "Някой",
"(not supported by this browser)": "(не се поддържа от този браузър)",
- "%(senderName)s answered the call.": "%(senderName)s отговори на повикването.",
"(no answer)": "(няма отговор)",
"(unknown failure: %(reason)s)": "(неизвестна грешка: %(reason)s)",
- "%(senderName)s ended the call.": "%(senderName)s прекрати разговора.",
- "%(senderName)s placed a %(callType)s call.": "%(senderName)s започна %(callType)s разговор.",
- "%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s изпрати покана на %(targetDisplayName)s да се присъедини към стаята.",
- "%(senderName)s made future room history visible to all room members, from the point they are invited.": "%(senderName)s направи бъдещата история на стаята видима за всички членове, от момента на поканването им в нея.",
- "%(senderName)s made future room history visible to all room members, from the point they joined.": "%(senderName)s направи бъдещата история на стаята видима за всички членове, от момента на присъединяването им в нея.",
- "%(senderName)s made future room history visible to all room members.": "%(senderName)s направи бъдещата история на стаята видима за всички членове в нея.",
- "%(senderName)s made future room history visible to anyone.": "%(senderName)s направи бъдещата история на стаята видима за всеки.",
- "%(senderName)s made future room history visible to unknown (%(visibility)s).": "%(senderName)s направи бъдещата история на стаята видима по непознат начин (%(visibility)s).",
- "%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s включи шифроване от край до край (алгоритъм %(algorithm)s).",
- "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s от %(fromPowerLevel)s на %(toPowerLevel)s",
- "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s смени нивото на достъп на %(powerLevelDiffText)s.",
- "%(senderName)s changed the pinned messages for the room.": "%(senderName)s смени закачените съобщения за стаята.",
- "%(widgetName)s widget modified by %(senderName)s": "Приспособлението %(widgetName)s беше променено от %(senderName)s",
- "%(widgetName)s widget added by %(senderName)s": "Приспособлението %(widgetName)s беше добавено от %(senderName)s",
- "%(widgetName)s widget removed by %(senderName)s": "Приспособлението %(widgetName)s беше премахнато от %(senderName)s",
"%(displayName)s is typing": "%(displayName)s пише",
"%(names)s and %(count)s others are typing|other": "%(names)s и %(count)s други пишат",
"%(names)s and %(count)s others are typing|one": "%(names)s и още един човек пишат",
@@ -526,9 +490,6 @@
"Invalid file%(extra)s": "Невалиден файл%(extra)s",
"Error decrypting image": "Грешка при разшифроване на снимка",
"Error decrypting video": "Грешка при разшифроване на видео",
- "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s промени аватара на %(roomName)s",
- "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s премахна аватара на стаята.",
- "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s промени аватара на стаята на ",
"Copied!": "Копирано!",
"Failed to copy": "Неуспешно копиране",
"Add an Integration": "Добавяне на интеграция",
@@ -1181,5 +1142,44 @@
"To continue using the %(homeserverDomain)s homeserver you must review and agree to our terms and conditions.": "За да продължите да ползвате %(homeserverDomain)s е необходимо да прегледате и да се съгласите с правилата и условията за ползване.",
"Review terms and conditions": "Прегледай правилата и условията",
"Failed to indicate account erasure": "Неуспешно указване на желанието за изтриване на акаунта",
- "Try the app first": "Първо пробвайте приложението"
+ "Try the app first": "Първо пробвайте приложението",
+ " accepted the invitation for %(displayName)s.": " прие поканата за %(displayName)s.",
+ " accepted an invitation.": " прие поканата.",
+ " requested a VoIP conference.": " заяви VoIP групов разговор.",
+ " invited .": " покани .",
+ " banned .": " блокира .",
+ " changed their display name to .": " смени своето име на .",
+ " set their display name to .": " си сложи име .",
+ " removed their display name ().": " премахна своето име ().",
+ " removed their profile picture.": " премахна своята профилна снимка.",
+ " changed their profile picture.": " промени своята профилна снимка.",
+ " set a profile picture.": " зададе снимка на профила си.",
+ " joined the room.": " се присъедини към стаята.",
+ " rejected the invitation.": " отхвърли поканата.",
+ " left the room.": " напусна стаята.",
+ " unbanned .": " отблокира .",
+ " kicked .": " изгони .",
+ " withdrew 's invitation.": " оттегли поканата си за .",
+ " changed the topic to \"%(topic)s\".": " смени темата на \"%(topic)s\".",
+ " changed the room name to %(roomName)s.": " промени името на стаята на %(roomName)s.",
+ " changed the avatar for %(roomName)s": " промени аватара на %(roomName)s",
+ " changed the room avatar to ": " промени аватара на стаята на ",
+ " removed the room name.": " премахна името на стаята.",
+ " removed the room avatar.": " премахна аватара на стаята.",
+ " answered the call.": " отговори на повикването.",
+ " ended the call.": " прекрати разговора.",
+ " placed a %(callType)s call.": " започна %(callType)s разговор.",
+ " sent an invitation to %(targetDisplayName)s to join the room.": " изпрати покана на %(targetDisplayName)s да се присъедини към стаята.",
+ " made future room history visible to all room members, from the point they are invited.": " направи бъдещата история на стаята видима за всички членове, от момента на поканването им в нея.",
+ " made future room history visible to all room members, from the point they joined.": " направи бъдещата история на стаята видима за всички членове, от момента на присъединяването им в нея.",
+ " made future room history visible to all room members.": " направи бъдещата история на стаята видима за всички членове в нея.",
+ " made future room history visible to anyone.": " направи бъдещата история на стаята видима за всеки.",
+ " made future room history visible to unknown (%(visibility)s).": " направи бъдещата история на стаята видима по непознат начин (%(visibility)s).",
+ " turned on end-to-end encryption (algorithm %(algorithm)s).": " включи шифроване от край до край (алгоритъм %(algorithm)s).",
+ " from %(fromPowerLevel)s to %(toPowerLevel)s": " от %(fromPowerLevel)s на %(toPowerLevel)s",
+ " changed the power level of %(powerLevelDiffText)s.": " смени нивото на достъп на %(powerLevelDiffText)s.",
+ " changed the pinned messages for the room.": " смени закачените съобщения за стаята.",
+ "%(widgetName)s widget modified by ": "Приспособлението %(widgetName)s беше променено от ",
+ "%(widgetName)s widget added by ": "Приспособлението %(widgetName)s беше добавено от ",
+ "%(widgetName)s widget removed by ": "Приспособлението %(widgetName)s беше премахнато от "
}
diff --git a/src/i18n/strings/ca.json b/src/i18n/strings/ca.json
index 98d51e99ac..2e84e60e4c 100644
--- a/src/i18n/strings/ca.json
+++ b/src/i18n/strings/ca.json
@@ -153,49 +153,14 @@
"The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "La clau de signatura que heu proporcionat coincideix amb la clau de signatura que heu rebut del dispositiu %(deviceId)s de l'usuari %(userId)s. S'ha marcat el dispositiu com a dispositiu verificat.",
"Unrecognised command:": "Ordre no reconegut:",
"Reason": "Raó",
- "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s ha acceptat la invitació de %(displayName)s.",
- "%(targetName)s accepted an invitation.": "%(targetName)s ha acceptat una invitació.",
- "%(senderName)s requested a VoIP conference.": "%(senderName)s ha sol·licitat una conferència VoIP.",
- "%(senderName)s invited %(targetName)s.": "%(senderName)s ha convidat a %(targetName)s.",
- "%(senderName)s banned %(targetName)s.": "%(senderName)s ha expulsat a %(targetName)s.",
- "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s ha establert %(displayName)s com el seu nom visible.",
- "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s ha retirat el seu nom visible %(oldDisplayName)s.",
- "%(senderName)s removed their profile picture.": "%(senderName)s ha retirat la seva foto de perfil.",
- "%(senderName)s changed their profile picture.": "%(senderName)s ha canviat la seva foto de perfil.",
- "%(senderName)s set a profile picture.": "%(senderName)s ha establert una foto de perfil.",
"VoIP conference started.": "S'ha iniciat la conferència VoIP.",
- "%(targetName)s joined the room.": "%(targetName)s ha entrat a la sala.",
"VoIP conference finished.": "S'ha finalitzat la conferència VoIP.",
- "%(targetName)s rejected the invitation.": "%(targetName)s ha rebutjat la invitació.",
- "%(targetName)s left the room.": "%(targetName)s ha sortir de la sala.",
- "%(senderName)s unbanned %(targetName)s.": "%(senderName)s ha readmès a %(targetName)s.",
- "%(senderName)s kicked %(targetName)s.": "%(senderName)s ha fet fora a %(targetName)s.",
- "%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s ha retirat la invitació per a %(targetName)s.",
- "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s ha canviat el tema a \"%(topic)s\".",
- "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s ha eliminat el nom de la sala.",
- "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s ha canviat el nom de la sala a %(roomName)s.",
"%(senderDisplayName)s sent an image.": "%(senderDisplayName)s ha enviat una imatge.",
"Someone": "Algú",
"(not supported by this browser)": "(no és compatible amb aquest navegador)",
- "%(senderName)s answered the call.": "%(senderName)s ha contestat la trucada.",
"(could not connect media)": "(no s'ha pogut connectar el medi)",
"(no answer)": "(sense resposta)",
"(unknown failure: %(reason)s)": "(error desconegut: %(reason)s)",
- "%(senderName)s ended the call.": "%(senderName)s ha penjat.",
- "%(senderName)s placed a %(callType)s call.": "%(senderName)s ha col·locat una trucada de %(callType)s.",
- "%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s ha enviat una invitació a %(targetDisplayName)s a entrar a aquesta sala.",
- "%(senderName)s made future room history visible to all room members, from the point they are invited.": "%(senderName)s ha fet visible l'històric futur de la sala per a tots els membres, a partir de que hi són convidats.",
- "%(senderName)s made future room history visible to all room members, from the point they joined.": "%(senderName)s ha fet visible l'històric futur de la sala a tots els membres, des de que entren a la sala.",
- "%(senderName)s made future room history visible to all room members.": "%(senderName)s ha fet visible l'històric futur de la sala a tots els membres de la sala.",
- "%(senderName)s made future room history visible to anyone.": "%(senderName)s ha fet visible l´historial de la sala per a tothom.",
- "%(senderName)s made future room history visible to unknown (%(visibility)s).": "%(senderName)s ha fet visible l'històric de la sala per a desconeguts (%(visibility)s).",
- "%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s ha activat l'encriptació d'extrem a extrem (algoritme %(algorithm)s).",
- "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s de %(fromPowerLevel)s fins %(toPowerLevel)s",
- "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s ha canviat el nivell de potència de %(powerLevelDiffText)s.",
- "%(senderName)s changed the pinned messages for the room.": "%(senderName)s ha canviat els missatges fixats de la sala.",
- "%(widgetName)s widget modified by %(senderName)s": "%(senderName)s ha modificat el giny %(widgetName)s",
- "%(widgetName)s widget added by %(senderName)s": "%(senderName)s ha afegit el giny %(widgetName)s",
- "%(widgetName)s widget removed by %(senderName)s": "%(senderName)s ha eliminat el giny %(widgetName)s",
"%(displayName)s is typing": "%(displayName)s està escrivint",
"%(names)s and %(count)s others are typing|other": "%(names)s i %(count)s més estan escrivint",
"%(names)s and %(count)s others are typing|one": "%(names)s i algú altre està escrivint",
@@ -495,9 +460,6 @@
"Invalid file%(extra)s": "Fitxer invàlid%(extra)s",
"Error decrypting image": "S'ha produït un error en desencriptar la imatge",
"Error decrypting video": "S'ha produït un error en desencriptar el vídeo",
- "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s ha canviat el seu avatar per a la sala %(roomName)s",
- "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s ha eliminat l'avatar de la sala.",
- "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s ha canviat l'avatar de la sala per aquest ",
"Copied!": "Copiat!",
"Failed to copy": "No s'ha pogut copiar",
"Add an Integration": "Afegeix una integració",
@@ -851,7 +813,6 @@
"Your homeserver's URL": "URL del teu homeserver",
"Your identity server's URL": "URL del teu servidor d'identitat",
"Analytics": "Analítiques",
- "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s ha canviat el seu nom visible a %(displayName)s.",
"Server may be unavailable or overloaded": "El servidor pot estar inaccessible o sobrecarregat",
"Display name": "Nom visible",
"Identity Server is": "El servidor d'identitat es",
@@ -1016,5 +977,44 @@
"Collapse panel": "Col·lapsa el tauler",
"With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Amb el vostre navegador actual, l'aparença de l'aplicació pot ser completament incorrecta i algunes o totes les funcions poden no funcionar correctament. Si voleu provar-ho de totes maneres, podeu continuar, però esteu sols pel que fa als problemes que pugueu trobar!",
"Checking for an update...": "Comprovant si hi ha actualitzacions...",
- "There are advanced notifications which are not shown here": "Hi ha notificacions avançades que no es mostren aquí"
+ "There are advanced notifications which are not shown here": "Hi ha notificacions avançades que no es mostren aquí",
+ " accepted the invitation for %(displayName)s.": " ha acceptat la invitació de %(displayName)s.",
+ " accepted an invitation.": " ha acceptat una invitació.",
+ " requested a VoIP conference.": " ha sol·licitat una conferència VoIP.",
+ " invited .": " ha convidat a .",
+ " banned .": " ha expulsat a .",
+ " changed their display name to .": " ha canviat el seu nom visible a .",
+ " set their display name to .": " ha establert com el seu nom visible.",
+ " removed their display name ().": " ha retirat el seu nom visible .",
+ " removed their profile picture.": " ha retirat la seva foto de perfil.",
+ " changed their profile picture.": " ha canviat la seva foto de perfil.",
+ " set a profile picture.": " ha establert una foto de perfil.",
+ " joined the room.": " ha entrat a la sala.",
+ " rejected the invitation.": " ha rebutjat la invitació.",
+ " left the room.": " ha sortir de la sala.",
+ " unbanned .": " ha readmès a .",
+ " kicked .": " ha fet fora a .",
+ " withdrew 's invitation.": " ha retirat la invitació per a .",
+ " changed the topic to \"%(topic)s\".": " ha canviat el tema a \"%(topic)s\".",
+ " changed the room name to %(roomName)s.": " ha canviat el nom de la sala a %(roomName)s.",
+ " changed the avatar for %(roomName)s": " ha canviat el seu avatar per a la sala %(roomName)s",
+ " changed the room avatar to ": " ha canviat l'avatar de la sala per aquest ",
+ " removed the room name.": " ha eliminat el nom de la sala.",
+ " removed the room avatar.": " ha eliminat l'avatar de la sala.",
+ " answered the call.": " ha contestat la trucada.",
+ " ended the call.": " ha penjat.",
+ " placed a %(callType)s call.": " ha col·locat una trucada de %(callType)s.",
+ " sent an invitation to %(targetDisplayName)s to join the room.": " ha enviat una invitació a %(targetDisplayName)s a entrar a aquesta sala.",
+ " made future room history visible to all room members, from the point they are invited.": " ha fet visible l'històric futur de la sala per a tots els membres, a partir de que hi són convidats.",
+ " made future room history visible to all room members, from the point they joined.": " ha fet visible l'històric futur de la sala a tots els membres, des de que entren a la sala.",
+ " made future room history visible to all room members.": " ha fet visible l'històric futur de la sala a tots els membres de la sala.",
+ " made future room history visible to anyone.": " ha fet visible l´historial de la sala per a tothom.",
+ " made future room history visible to unknown (%(visibility)s).": " ha fet visible l'històric de la sala per a desconeguts (%(visibility)s).",
+ " turned on end-to-end encryption (algorithm %(algorithm)s).": " ha activat l'encriptació d'extrem a extrem (algoritme %(algorithm)s).",
+ " from %(fromPowerLevel)s to %(toPowerLevel)s": " de %(fromPowerLevel)s fins %(toPowerLevel)s",
+ " changed the power level of %(powerLevelDiffText)s.": " ha canviat el nivell de potència de %(powerLevelDiffText)s.",
+ " changed the pinned messages for the room.": " ha canviat els missatges fixats de la sala.",
+ "%(widgetName)s widget modified by ": " ha modificat el giny %(widgetName)s",
+ "%(widgetName)s widget added by