From 10017522e2556d85018b3a9ebaa165dd39916c0b Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Mon, 19 Dec 2016 17:59:13 +0000 Subject: [PATCH 001/927] Use correct 1-1 room avatar after users leave The correct 1-1 avatar is used with rooms in which there are only two users with either "join" or "invite" as their membership (importantly, not "leave" or otherwise). (This is important when a user moves accounts and re-joins previously left 1-1 chats) --- src/components/views/avatars/RoomAvatar.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/avatars/RoomAvatar.js b/src/components/views/avatars/RoomAvatar.js index dcb25eff61..2bb6caddb7 100644 --- a/src/components/views/avatars/RoomAvatar.js +++ b/src/components/views/avatars/RoomAvatar.js @@ -86,7 +86,7 @@ module.exports = React.createClass({ var userIds = []; // for .. in optimisation to return early if there are >2 keys for (var uid in mlist) { - if (mlist.hasOwnProperty(uid)) { + if (mlist.hasOwnProperty(uid) && ["join", "invite"].includes(mlist[uid].membership)) { userIds.push(uid); } if (userIds.length > 2) { From 583f86eb06d7df4b49378ce7e2101311223b1104 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Mon, 19 Dec 2016 18:41:34 +0000 Subject: [PATCH 002/927] Handle the case where the other 1-1 user left --- src/components/views/avatars/RoomAvatar.js | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/components/views/avatars/RoomAvatar.js b/src/components/views/avatars/RoomAvatar.js index 2bb6caddb7..09a9e6c6c0 100644 --- a/src/components/views/avatars/RoomAvatar.js +++ b/src/components/views/avatars/RoomAvatar.js @@ -84,10 +84,15 @@ module.exports = React.createClass({ var mlist = props.room.currentState.members; var userIds = []; + var leftUserIds = []; // for .. in optimisation to return early if there are >2 keys for (var uid in mlist) { - if (mlist.hasOwnProperty(uid) && ["join", "invite"].includes(mlist[uid].membership)) { - userIds.push(uid); + if (mlist.hasOwnProperty(uid)) { + if (["join", "invite"].includes(mlist[uid].membership)) { + userIds.push(uid); + } else { + leftUserIds.push(uid); + } } if (userIds.length > 2) { return null; @@ -101,12 +106,21 @@ module.exports = React.createClass({ } else { theOtherGuy = mlist[userIds[0]]; } + return theOtherGuy.getAvatarUrl( MatrixClientPeg.get().getHomeserverUrl(), props.width, props.height, props.resizeMethod, false ); } else if (userIds.length == 1) { + // The other 1-1 user left, leaving just the current user, so show the left user's avatar + if (leftUserIds.length === 1) { + return mlist[leftUserIds[0]].getAvatarUrl( + MatrixClientPeg.get().getHomeserverUrl(), + props.width, props.height, props.resizeMethod, + false + ); + } return mlist[userIds[0]].getAvatarUrl( MatrixClientPeg.get().getHomeserverUrl(), props.width, props.height, props.resizeMethod, From 714b63519a8ebac1c58404236cd811f59259a905 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 20 Dec 2016 11:50:35 +0000 Subject: [PATCH 003/927] Remove empty line --- src/components/views/avatars/RoomAvatar.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/views/avatars/RoomAvatar.js b/src/components/views/avatars/RoomAvatar.js index 09a9e6c6c0..f5f42318eb 100644 --- a/src/components/views/avatars/RoomAvatar.js +++ b/src/components/views/avatars/RoomAvatar.js @@ -106,7 +106,6 @@ module.exports = React.createClass({ } else { theOtherGuy = mlist[userIds[0]]; } - return theOtherGuy.getAvatarUrl( MatrixClientPeg.get().getHomeserverUrl(), props.width, props.height, props.resizeMethod, From b644751ca1ac919d4b919a84f43c29388d6497eb Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 28 Aug 2017 00:16:22 +0100 Subject: [PATCH 004/927] skip direct chats which you have left in memberinfo --- src/components/views/rooms/MemberInfo.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/components/views/rooms/MemberInfo.js b/src/components/views/rooms/MemberInfo.js index 64eeddb406..4f7394fd91 100644 --- a/src/components/views/rooms/MemberInfo.js +++ b/src/components/views/rooms/MemberInfo.js @@ -620,17 +620,16 @@ module.exports = withMatrixClient(React.createClass({ const room = this.props.matrixClient.getRoom(roomId); if (room) { const me = room.getMember(this.props.matrixClient.credentials.userId); - const highlight = ( - room.getUnreadNotificationCount('highlight') > 0 || - me.membership == "invite" - ); + if (me.membership === 'leave') continue; + const highlight = room.getUnreadNotificationCount('highlight') > 0 || me.membership === 'invite'; + tiles.push( ); From 433cd505ee02977cf3ed2695f7d66f9f5c50212f Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 28 Aug 2017 00:39:59 +0100 Subject: [PATCH 005/927] skip direct chats which either you or the target have left --- src/components/views/rooms/MemberInfo.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/components/views/rooms/MemberInfo.js b/src/components/views/rooms/MemberInfo.js index 4f7394fd91..6d38797a2d 100644 --- a/src/components/views/rooms/MemberInfo.js +++ b/src/components/views/rooms/MemberInfo.js @@ -620,7 +620,12 @@ module.exports = withMatrixClient(React.createClass({ const room = this.props.matrixClient.getRoom(roomId); if (room) { const me = room.getMember(this.props.matrixClient.credentials.userId); - if (me.membership === 'leave') continue; + // not a DM room if we have left it + if (!me.membership || me.membership === 'leave') continue; + // not a DM room if they have left it + const them = this.props.member; + if (!them.membership || them.membership === 'leave') continue; + const highlight = room.getUnreadNotificationCount('highlight') > 0 || me.membership === 'invite'; tiles.push( From 21af3fe189246b07f68a10d0174ae6d2723398b8 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 28 Aug 2017 00:46:28 +0100 Subject: [PATCH 006/927] modularize and invert logic, so banned etc will count as left --- src/components/views/rooms/MemberInfo.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/components/views/rooms/MemberInfo.js b/src/components/views/rooms/MemberInfo.js index 6d38797a2d..af32d60cef 100644 --- a/src/components/views/rooms/MemberInfo.js +++ b/src/components/views/rooms/MemberInfo.js @@ -40,6 +40,8 @@ import withMatrixClient from '../../../wrappers/withMatrixClient'; import AccessibleButton from '../elements/AccessibleButton'; import GeminiScrollbar from 'react-gemini-scrollbar'; +// States which both sides of the dmRoom must have for it to be considered relevant. +const joinStates = ['invite', 'join']; module.exports = withMatrixClient(React.createClass({ displayName: 'MemberInfo', @@ -620,11 +622,11 @@ module.exports = withMatrixClient(React.createClass({ const room = this.props.matrixClient.getRoom(roomId); if (room) { const me = room.getMember(this.props.matrixClient.credentials.userId); - // not a DM room if we have left it - if (!me.membership || me.membership === 'leave') continue; - // not a DM room if they have left it + // not a DM room if we have are not joined/invited + if (!me.membership || !joinStates.includes(me.membership)) continue; + // not a DM room if they are not joined/invited const them = this.props.member; - if (!them.membership || them.membership === 'leave') continue; + if (!them.membership || !joinStates.includes(them.membership)) continue; const highlight = room.getUnreadNotificationCount('highlight') > 0 || me.membership === 'invite'; From 9658efd6d7f160552a87d4f29622c42c8c283744 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 28 Aug 2017 01:04:18 +0100 Subject: [PATCH 007/927] add comment and remove redundant logic --- src/components/views/rooms/MemberInfo.js | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/components/views/rooms/MemberInfo.js b/src/components/views/rooms/MemberInfo.js index af32d60cef..8ed05023ad 100644 --- a/src/components/views/rooms/MemberInfo.js +++ b/src/components/views/rooms/MemberInfo.js @@ -40,9 +40,6 @@ import withMatrixClient from '../../../wrappers/withMatrixClient'; import AccessibleButton from '../elements/AccessibleButton'; import GeminiScrollbar from 'react-gemini-scrollbar'; -// States which both sides of the dmRoom must have for it to be considered relevant. -const joinStates = ['invite', 'join']; - module.exports = withMatrixClient(React.createClass({ displayName: 'MemberInfo', @@ -613,6 +610,10 @@ module.exports = withMatrixClient(React.createClass({ var startChat, kickButton, banButton, muteButton, giveModButton, spinner; if (this.props.member.userId !== this.props.matrixClient.credentials.userId) { const dmRoomMap = new DMRoomMap(this.props.matrixClient); + // dmRooms will not include dmRooms that we have been invited into but did not join. + // Because DMRoomMap runs off account_data[m.direct] which is only set on join of dm room. + // XXX: we potentially want DMs we have been invited to, to also show up here :L + // especially as logic below concerns specially if we haven't joined but have been invited const dmRooms = dmRoomMap.getDMRoomsForUserId(this.props.member.userId); const RoomTile = sdk.getComponent("rooms.RoomTile"); @@ -622,11 +623,11 @@ module.exports = withMatrixClient(React.createClass({ const room = this.props.matrixClient.getRoom(roomId); if (room) { const me = room.getMember(this.props.matrixClient.credentials.userId); - // not a DM room if we have are not joined/invited - if (!me.membership || !joinStates.includes(me.membership)) continue; - // not a DM room if they are not joined/invited + // not a DM room if we have are not joined + if (!me.membership || me.membership !== 'join') continue; + // not a DM room if they are not joined const them = this.props.member; - if (!them.membership || !joinStates.includes(them.membership)) continue; + if (!them.membership || them.membership !== 'join') continue; const highlight = room.getUnreadNotificationCount('highlight') > 0 || me.membership === 'invite'; From ba386e3417f5c1d86f46c08c2149a8f8dc1aaf36 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 11 Oct 2017 20:08:09 -0600 Subject: [PATCH 008/927] Singularise unsent message prompt, if applicable Adds vector-im/riot-web#1217 Signed-off-by: Travis Ralston --- src/components/structures/RoomStatusBar.js | 7 ++++++- src/components/structures/RoomView.js | 4 +++- src/i18n/strings/en_EN.json | 2 ++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/components/structures/RoomStatusBar.js b/src/components/structures/RoomStatusBar.js index 3a2ab33db8..68d25e9a2a 100644 --- a/src/components/structures/RoomStatusBar.js +++ b/src/components/structures/RoomStatusBar.js @@ -39,6 +39,9 @@ module.exports = React.createClass({ // string to display when there are messages in the room which had errors on send unsentMessageError: React.PropTypes.string, + // the number of messages not sent. + numUnsentMessages: React.PropTypes.number, + // this is true if we are fully scrolled-down, and are looking at // the end of the live timeline. atEndOfLiveTimeline: React.PropTypes.bool, @@ -252,6 +255,8 @@ module.exports = React.createClass({ } if (this.props.unsentMessageError) { + let resendStr = "Resend message or cancel message now."; + if (this.props.numUnsentMessages > 1) resendStr = "Resend all or cancel all now. You can also select individual messages to resend or cancel."; return (
/!\ @@ -259,7 +264,7 @@ module.exports = React.createClass({ { this.props.unsentMessageError }
- { _tJsx("Resend all or cancel all now. You can also select individual messages to resend or cancel.", + { _tJsx(resendStr, [/(.*?)<\/a>/, /(.*?)<\/a>/], [ (sub) => { sub }, diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 14273fc95f..9a1eb9ef31 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -748,7 +748,8 @@ module.exports = React.createClass({ for (const event of unsentMessages) { if (!event.error || event.error.name !== "UnknownDeviceError") { - return _t("Some of your messages have not been sent."); + if (unsentMessages.length > 1) return _t("Some of your messages have not been sent."); + return _t("Your message was not sent."); } } return _t("Message not sent due to unknown devices being present"); @@ -1570,6 +1571,7 @@ module.exports = React.createClass({ isStatusAreaExpanded = this.state.statusBarVisible; statusBar = Resend all or cancel all now. You can also select individual messages to resend or cancel.": "Resend all or cancel all now. You can also select individual messages to resend or cancel.", + "Resend message or cancel message now.": "Resend message or cancel message now.", "(~%(count)s results)|one": "(~%(count)s result)", "(~%(count)s results)|other": "(~%(count)s results)", "Cancel": "Cancel", From 0f8df97a475f02b73d9f7b33917de206d5f46fb2 Mon Sep 17 00:00:00 2001 From: Tong Hui Date: Fri, 10 Nov 2017 14:14:55 +0000 Subject: [PATCH 009/927] Translated using Weblate (Chinese (Simplified)) Currently translated at 70.4% (654 of 928 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/zh_Hans/ --- src/i18n/strings/zh_Hans.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/zh_Hans.json b/src/i18n/strings/zh_Hans.json index 474233909f..317f1b4396 100644 --- a/src/i18n/strings/zh_Hans.json +++ b/src/i18n/strings/zh_Hans.json @@ -710,5 +710,7 @@ "Autocomplete Delay (ms):": "自动完成延迟(毫秒):", "%(widgetName)s widget added by %(senderName)s": "%(widgetName)s 小组建被 %(senderName)s 添加", "%(widgetName)s widget removed by %(senderName)s": "%(widgetName)s 小组建被 %(senderName)s 移除", - "%(widgetName)s widget modified by %(senderName)s": "%(widgetName)s 小组建被 %(senderName)s 修改" + "%(widgetName)s widget modified by %(senderName)s": "%(widgetName)s 小组建被 %(senderName)s 修改", + "Unpin Message": "取消置顶消息", + "Add rooms to this community": "添加聊天室到此社区" } From a97f53099990a1002d19b58094bd6fae801bfa41 Mon Sep 17 00:00:00 2001 From: Krombel Date: Mon, 13 Nov 2017 12:50:27 +0000 Subject: [PATCH 010/927] Translated using Weblate (German) Currently translated at 100.0% (928 of 928 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index db12a69657..eca34954f9 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -963,12 +963,12 @@ "%(names)s and %(count)s others are typing|one": "%(names)s und eine weitere Person schreiben", "Disinvite this user?": "Einladung für diesen Benutzer zurückziehen?", "Kick this user?": "Diesen Benutzer kicken?", - "Unban this user?": "Verbannung dieses Benutzers aufheben?", + "Unban this user?": "Verbannung für diesen Benutzer aufheben?", "Ban this user?": "Diesen Benutzer verbannen?", "Drop here to favourite": "Hierher ziehen, um als Favorit zu markieren", "Drop here to tag direct chat": "Hierher ziehen, um als Direkt-Chat zu markieren", "Drop here to restore": "Hierher ziehen zum Wiederherstellen", - "Drop here to demote": "Hier loslassen um zurückzustufen", + "Drop here to demote": "Hierher ziehen, um herabzustufen", "You have been kicked from this room by %(userName)s.": "Du wurdest von %(userName)s aus diesem Raum gekickt.", "You are trying to access a room.": "Du versuchst, auf einen Raum zuzugreifen.", "Members only (since the point in time of selecting this option)": "Nur Mitglieder (ab dem Zeitpunkt, an dem diese Option ausgewählt wird)", @@ -993,13 +993,13 @@ "An email has been sent to %(emailAddress)s. Once you've followed the link it contains, click below.": "Eine E-Mail wurde an %(emailAddress)s gesendet. Folge dem in der E-Mail enthaltenen Link und klicke dann unten.", "The visibility of '%(roomName)s' in %(groupId)s could not be updated.": "Die Sichtbarkeit von '%(roomName)s' in %(groupId)s konnte nicht aktualisiert werden.", "Visibility in Room List": "Sichtbarkeit in Raum-Liste", - "Visible to everyone": "Für jeden sichtbar", + "Visible to everyone": "Für alle sichtbar", "Only visible to community members": "Nur für Community-Mitglieder sichtbar", "Community Invites": "Community-Einladungen", "Notify the whole room": "Den gesamten Raum benachrichtigen", "Room Notification": "Raum-Benachrichtigung", "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Diese Räume werden Community-Mitgliedern auf der Community-Seite angezeigt. Community-Mitglieder können diesen Räumen beitreten, indem sie auf diese klicken.", - "Show these rooms to non-members on the community page and room list?": "Sollen diese Räume Nicht-Mitgliedern auf der Community-Seite und Raum-Liste gezeigt werden?", - "

HTML for your community's page

\n

\n Use the long description to introduce new members to the community, or distribute\n some important links\n

\n

\n You can even use 'img' tags\n

\n": "

HTML für deine Community-Seite

\n

\n Nutze die lange Beschreibung um neuen Mitgliedern diese Community zu beschreiben\n oder um einige wichtige Informationen oder Links festzuhalten.\n

\n

\n Du kannst auch 'img'-Tags (HTML) verwenden\n

\n", - "Your community hasn't got a Long Description, a HTML page to show to community members.
Click here to open settings and give it one!": "Deine Community hat noch keine lange Beschreibung oder eine HTML-Seite die Community-Mitgliedern gezeigt wird.
Klicke hier um die Einstellungen zu öffnen und ihr eine zu geben!" + "Show these rooms to non-members on the community page and room list?": "Sollen diese Räume Nicht-Mitgliedern auf der Community-Seite und der Raum-Liste angezeigt werden?", + "

HTML for your community's page

\n

\n Use the long description to introduce new members to the community, or distribute\n some important links\n

\n

\n You can even use 'img' tags\n

\n": "

HTML für deine Community-Seite

\n

\n Nutze die ausführliche Beschreibung, um neuen Mitgliedern diese Community vorzustellen\n oder um wichtige Links bereitzustellen.\n

\n

\n Du kannst sogar 'img'-Tags (HTML) verwenden\n

\n", + "Your community hasn't got a Long Description, a HTML page to show to community members.
Click here to open settings and give it one!": "Deine Community hat noch keine ausführliche Beschreibung, d. h. eine HTML-Seite, die Community-Mitgliedern angezeigt wird.
Hier klicken, um die Einstellungen zu öffnen und eine Beschreibung zu erstellen!" } From beebe6b92b57339bee20a998097786b7cbaf75f0 Mon Sep 17 00:00:00 2001 From: Bamstam Date: Mon, 13 Nov 2017 14:05:02 +0000 Subject: [PATCH 011/927] Translated using Weblate (German) Currently translated at 100.0% (928 of 928 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index eca34954f9..05b9392079 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -996,7 +996,7 @@ "Visible to everyone": "Für alle sichtbar", "Only visible to community members": "Nur für Community-Mitglieder sichtbar", "Community Invites": "Community-Einladungen", - "Notify the whole room": "Den gesamten Raum benachrichtigen", + "Notify the whole room": "Alle im Raum benachrichtigen", "Room Notification": "Raum-Benachrichtigung", "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Diese Räume werden Community-Mitgliedern auf der Community-Seite angezeigt. Community-Mitglieder können diesen Räumen beitreten, indem sie auf diese klicken.", "Show these rooms to non-members on the community page and room list?": "Sollen diese Räume Nicht-Mitgliedern auf der Community-Seite und der Raum-Liste angezeigt werden?", From 6c8283b3a8fc1828b21663eb1cff7e8b9632c4d3 Mon Sep 17 00:00:00 2001 From: Szimszon Date: Tue, 14 Nov 2017 06:40:59 +0000 Subject: [PATCH 012/927] Translated using Weblate (Hungarian) Currently translated at 100.0% (932 of 932 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index b316e994a1..8a30c176b3 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -1001,5 +1001,9 @@ "Your community hasn't got a Long Description, a HTML page to show to community members.
Click here to open settings and give it one!": "A közösségednek nincs bő leírása, HTML oldala ami megjelenik a közösség tagjainak.
A létrehozáshoz kattints ide!", "Notify the whole room": "Az egész szoba értesítése", "Room Notification": "Szoba értesítések", - "Show these rooms to non-members on the community page and room list?": "Mutassuk meg ezeket a szobákat kívülállóknak a közösségi oldalon és a szobák listájában?" + "Show these rooms to non-members on the community page and room list?": "Mutassuk meg ezeket a szobákat kívülállóknak a közösségi oldalon és a szobák listájában?", + "Sign in to get started": "Az induláshoz jelentkezz be", + "Status.im theme": "Állapot.im téma", + "Please note you are logging into the %(hs)s server, not matrix.org.": "Figyelem, a %(hs)s szerverre jelentkezel be és nem a matrix.org szerverre.", + "Username on %(hs)s": "Felhasználónév a %(hs)s szerveren" } From acd2be4b68eeba251696894759be796cde2032c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Tue, 14 Nov 2017 10:53:44 +0000 Subject: [PATCH 013/927] Translated using Weblate (French) Currently translated at 100.0% (932 of 932 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index a9b7232e29..da224ce4e1 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -997,5 +997,9 @@ "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Ces salons sont affichés aux membres de la communauté sur la page de la communauté. Les membres de la communauté peuvent rejoindre ces salons en cliquant dessus.", "

HTML for your community's page

\n

\n Use the long description to introduce new members to the community, or distribute\n some important links\n

\n

\n You can even use 'img' tags\n

\n": "

HTML pour votre page de communauté

\n

\n Utilisez la description longue pour présenter la communauté aux nouveaux membres\n ou pour diffuser des liens importants\n

\n

\n Vous pouvez même utiliser des balises \"img\"\n

\n", "Your community hasn't got a Long Description, a HTML page to show to community members.
Click here to open settings and give it one!": "Votre communauté n'a pas de description longue, une page HTML à montrer aux membres de la communauté.
Cliquez ici pour ouvrir les réglages et créez-la !", - "Show these rooms to non-members on the community page and room list?": "Afficher ces salons aux non-membres sur la page de communauté et la liste des salons ?" + "Show these rooms to non-members on the community page and room list?": "Afficher ces salons aux non-membres sur la page de communauté et la liste des salons ?", + "Sign in to get started": "Connectez-vous pour commencer", + "Status.im theme": "Thème Status.im", + "Please note you are logging into the %(hs)s server, not matrix.org.": "Veuillez noter que vous vous connecter au serveur %(hs)s, pas à matrix.org.", + "Username on %(hs)s": "Nom d'utilisateur sur %(hs)s" } From 85f002b21cc3145f35437c9f536f57c357fb6af8 Mon Sep 17 00:00:00 2001 From: Andrey Date: Tue, 14 Nov 2017 03:16:09 +0000 Subject: [PATCH 014/927] Translated using Weblate (Russian) Currently translated at 98.4% (918 of 932 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 8ca50ec72f..d46076e2ff 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -986,5 +986,9 @@ "Community Invites": "Приглашения в сообщества", "Notify the whole room": "Уведомить всю комнату", "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Эти комнаты отображаются для участников сообщества на странице сообщества. Участники сообщества могут присоединиться к комнатам, щелкнув на них.", - "Show these rooms to non-members on the community page and room list?": "Следует ли показывать эти комнаты посторонним на странице сообщества и в комнате?" + "Show these rooms to non-members on the community page and room list?": "Следует ли показывать эти комнаты посторонним на странице сообщества и в комнате?", + "Sign in to get started": "Войдите, чтобы начать", + "Visibility in Room List": "Видимость в списке комнат", + "Visible to everyone": "Видимый для всех", + "Only visible to community members": "Только участникам сообщества" } From 9d1949601194fe995766e272b5027006691c3339 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Tue, 14 Nov 2017 13:19:43 +0000 Subject: [PATCH 015/927] Translated using Weblate (Slovak) Currently translated at 100.0% (932 of 932 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sk/ --- src/i18n/strings/sk.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/sk.json b/src/i18n/strings/sk.json index 837a55e380..11684c5488 100644 --- a/src/i18n/strings/sk.json +++ b/src/i18n/strings/sk.json @@ -926,5 +926,9 @@ "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "Exportovaný súbor je chránený heslom. Súbor môžete importovať len ak zadáte zodpovedajúce heslo.", "File to import": "Importovať zo súboru", "Import": "Importovať", - "Show these rooms to non-members on the community page and room list?": "Zobrazovať tieto miestnosti na domovskej stránke komunity a v zozname miestností aj pre nečlenov?" + "Show these rooms to non-members on the community page and room list?": "Zobrazovať tieto miestnosti na domovskej stránke komunity a v zozname miestností aj pre nečlenov?", + "Sign in to get started": "Začnite prihlásením sa", + "Status.im theme": "Téma status.im", + "Please note you are logging into the %(hs)s server, not matrix.org.": "Všimnite si: Práve sa prihlasujete na server %(hs)s, nie na server matrix.org.", + "Username on %(hs)s": "Meno používateľa na servery %(hs)s" } From 3d677d84fe3292f7c430f98ded726ef5e84436f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Tue, 14 Nov 2017 14:05:15 +0000 Subject: [PATCH 016/927] Translated using Weblate (Slovak) Currently translated at 100.0% (932 of 932 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sk/ --- src/i18n/strings/sk.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/i18n/strings/sk.json b/src/i18n/strings/sk.json index 11684c5488..ab2091d57b 100644 --- a/src/i18n/strings/sk.json +++ b/src/i18n/strings/sk.json @@ -140,7 +140,7 @@ "%(senderName)s made future room history visible to all room members, from the point they are invited.": "%(senderName)s sprístupnil budúcu históriu miestnosti pre všetkých členov, od kedy boli pozvaní.", "%(senderName)s made future room history visible to all room members, from the point they joined.": "%(senderName)s sprístupnil budúcu históriu miestnosti pre všetkých členov, od kedy vstúpili.", "%(senderName)s made future room history visible to all room members.": "%(senderName)s sprístupnil budúcu históriu miestnosti pre všetkých členov.", - "%(senderName)s made future room history visible to anyone.": "%(senderName)s sprístupnil budúcu históriu miestnosti pre všetkých.", + "%(senderName)s made future room history visible to anyone.": "%(senderName)s sprístupnil budúcu históriu miestnosti pre každého.", "%(senderName)s made future room history visible to unknown (%(visibility)s).": "%(senderName)s sprístupnil budúcu históriu miestnosti neznámym (%(visibility)s).", "%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s povolil E2E šifrovanie (algoritmus %(algorithm)s).", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s z %(fromPowerLevel)s na %(toPowerLevel)s", @@ -304,7 +304,7 @@ "Unknown": "Neznámy", "Seen by %(userName)s at %(dateTime)s": "%(userName)s videl %(dateTime)s", "Unnamed room": "Nepomenovaná miestnosť", - "World readable": "Viditeľné pre všetkých", + "World readable": "Viditeľné pre každého", "Guests can join": "Aj hostia môžu vstúpiť", "No rooms to show": "Žiadne miestnosti na zobrazenie", "Failed to set avatar.": "Nepodarilo sa nastaviť avatara.", @@ -505,7 +505,7 @@ "Something went wrong!": "Niečo sa pokazilo!", "The visibility of '%(roomName)s' in %(groupId)s could not be updated.": "Nie je možné aktualizovať viditeľnosť miestnosti '%(roomName)s' v komunite %(groupId)s.", "Visibility in Room List": "Viditeľnosť v zozname miestností", - "Visible to everyone": "Viditeľná pre všetkých", + "Visible to everyone": "Viditeľná pre každého", "Only visible to community members": "Viditeľná len pre členov komunity", "Filter community rooms": "Filtrovať miestnosti v komunite", "Unknown Address": "Neznáma adresa", From 64958d05b9743ee9a1a9f49287ebe108853058dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Tue, 14 Nov 2017 14:18:09 +0000 Subject: [PATCH 017/927] Translated using Weblate (French) Currently translated at 100.0% (933 of 933 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index da224ce4e1..f252786732 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -1001,5 +1001,7 @@ "Sign in to get started": "Connectez-vous pour commencer", "Status.im theme": "Thème Status.im", "Please note you are logging into the %(hs)s server, not matrix.org.": "Veuillez noter que vous vous connecter au serveur %(hs)s, pas à matrix.org.", - "Username on %(hs)s": "Nom d'utilisateur sur %(hs)s" + "Username on %(hs)s": "Nom d'utilisateur sur %(hs)s", + "Restricted": "Restreint", + "Custom of %(powerLevel)s": "Personnalisé de %(powerLevel)s" } From 20beb7990f4f23a6ddc3087e2c284580007f9373 Mon Sep 17 00:00:00 2001 From: Bamstam Date: Tue, 14 Nov 2017 14:21:05 +0000 Subject: [PATCH 018/927] Translated using Weblate (German) Currently translated at 99.4% (928 of 933 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 05b9392079..24036bde89 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -759,7 +759,7 @@ "Create": "Erstelle", "Room creation failed": "Raum-Erstellung fehlgeschlagen", "Featured Rooms:": "Hervorgehobene Räume:", - "Featured Users:": "Hervorgehobene Nutzer:", + "Featured Users:": "Hervorgehobene Benutzer:", "Automatically replace plain text Emoji": "Klartext-Emoji automatisch ersetzen", "Failed to upload image": "Bild-Hochladen fehlgeschlagen", "Hide avatars in user and room mentions": "Profilbilder in Benutzer- und Raum-Erwähnungen verbergen", @@ -880,7 +880,7 @@ "Filter community members": "Community-Mitglieder filtern", "Filter community rooms": "Community-Räume filtern", "Failed to remove room from community": "Entfernen des Raumes aus der Community fehlgeschlagen", - "Removing a room from the community will also remove it from the community page.": "Ein Entfernen eines Raumes aus der Community wird ihn auch von der Community-Seite entfernen.", + "Removing a room from the community will also remove it from the community page.": "Das Entfernen eines Raumes aus der Community wird ihn auch von der Community-Seite entfernen.", "Community IDs may only contain alphanumeric characters": "Community-IDs dürfen nur alphanumerische Zeichen enthalten", "Create Community": "Community erstellen", "Community Name": "Community-Name", @@ -1001,5 +1001,6 @@ "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Diese Räume werden Community-Mitgliedern auf der Community-Seite angezeigt. Community-Mitglieder können diesen Räumen beitreten, indem sie auf diese klicken.", "Show these rooms to non-members on the community page and room list?": "Sollen diese Räume Nicht-Mitgliedern auf der Community-Seite und der Raum-Liste angezeigt werden?", "

HTML for your community's page

\n

\n Use the long description to introduce new members to the community, or distribute\n some important links\n

\n

\n You can even use 'img' tags\n

\n": "

HTML für deine Community-Seite

\n

\n Nutze die ausführliche Beschreibung, um neuen Mitgliedern diese Community vorzustellen\n oder um wichtige Links bereitzustellen.\n

\n

\n Du kannst sogar 'img'-Tags (HTML) verwenden\n

\n", - "Your community hasn't got a Long Description, a HTML page to show to community members.
Click here to open settings and give it one!": "Deine Community hat noch keine ausführliche Beschreibung, d. h. eine HTML-Seite, die Community-Mitgliedern angezeigt wird.
Hier klicken, um die Einstellungen zu öffnen und eine Beschreibung zu erstellen!" + "Your community hasn't got a Long Description, a HTML page to show to community members.
Click here to open settings and give it one!": "Deine Community hat noch keine ausführliche Beschreibung, d. h. eine HTML-Seite, die Community-Mitgliedern angezeigt wird.
Hier klicken, um die Einstellungen zu öffnen und eine Beschreibung zu erstellen!", + "Custom of %(powerLevel)s": "benutzerdefiniert mit Wert %(powerLevel)s" } From 1038e44672d12b4b47232844399ac1a7621b7daa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Tue, 14 Nov 2017 14:10:14 +0000 Subject: [PATCH 019/927] Translated using Weblate (Slovak) Currently translated at 99.7% (931 of 933 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sk/ --- src/i18n/strings/sk.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/sk.json b/src/i18n/strings/sk.json index ab2091d57b..7a38caec82 100644 --- a/src/i18n/strings/sk.json +++ b/src/i18n/strings/sk.json @@ -8,7 +8,7 @@ "Existing Call": "Existujúci hovor", "You are already in a call.": "Už ste súčasťou iného hovoru.", "VoIP is unsupported": "VoIP nie je podporovaný", - "You cannot place VoIP calls in this browser.": "Použitím tohoto webového prehliadača nemôžete uskutočniť hovory.", + "You cannot place VoIP calls in this browser.": "Pomocou tohoto webového prehliadača nemôžete uskutočňovať VoIP hovory.", "You cannot place a call with yourself.": "Nemôžete uskutočniť hovor so samým sebou.", "Conference calls are not supported in this client": "Tento klient nepodporuje konferenčné hovory", "Conference calls are not supported in encrypted rooms": "Konferenčné hovory nie sú podporované v šifrovaných miestnostiach", @@ -107,7 +107,7 @@ "Reason": "Dôvod", "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s prijal pozvanie pre %(displayName)s.", "%(targetName)s accepted an invitation.": "%(targetName)s prijal pozvanie.", - "%(senderName)s requested a VoIP conference.": "%(senderName)s požiadal o VOIP konferenciu.", + "%(senderName)s requested a VoIP conference.": "%(senderName)s požiadal o VoIP konferenciu.", "%(senderName)s invited %(targetName)s.": "%(senderName)s pozval %(targetName)s.", "%(senderName)s banned %(targetName)s.": "%(senderName)s zakázal vstup %(targetName)s.", "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s si zmenil zobrazované meno z %(oldDisplayName)s na %(displayName)s.", From eb2d5d0ac515fbe8733966a74709b47d7e216048 Mon Sep 17 00:00:00 2001 From: Bamstam Date: Tue, 14 Nov 2017 14:32:13 +0000 Subject: [PATCH 020/927] Translated using Weblate (German) Currently translated at 99.4% (928 of 933 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 24036bde89..f6a9e00507 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -33,7 +33,7 @@ "Bans user with given id": "Verbannt den Benutzer mit der angegebenen ID", "Deops user with given id": "Entfernt OP beim Benutzer mit der angegebenen ID", "Invites user with given id to current room": "Lädt den Benutzer mit der angegebenen ID in den aktuellen Raum ein", - "Joins room with given alias": "Betrete Raum mit angegebenen Alias", + "Joins room with given alias": "Raum wird mit dem angegebenen Alias betreten", "Kicks user with given id": "Benutzer mit der angegebenen ID kicken", "Changes your display nickname": "Ändert deinen angezeigten Nicknamen", "Change Password": "Passwort ändern", @@ -904,7 +904,7 @@ "To join an existing community you'll have to know its community identifier; this will look something like +example:matrix.org.": "Um einer bereits bestehenden Community beitreten zu können, musst dir deren Community-ID bekannt sein. Diese sieht z. B. aus wie +example:matrix.org.", "Your Communities": "Deine Communities", "You're not currently a member of any communities.": "Du bist aktuell kein Mitglied einer Community.", - "Create a community to group together users and rooms! Build a custom homepage to mark out your space in the Matrix universe.": "Erzeuge eine Community um Nutzer und Räume zu gruppieren! Erzeuge eine angepasste Homepage um dein Revier im Matrix-Universum zu markieren.", + "Create a community to group together users and rooms! Build a custom homepage to mark out your space in the Matrix universe.": "Erstelle eine Community, um Benutzer und Räume miteinander zu verbinden! Erstelle zusätzlich eine eigene Homepage, um deinen individuellen Bereich im Matrix-Universum zu gestalten.", "Something went wrong whilst creating your community": "Beim Erstellen deiner Community ist ein Fehler aufgetreten", "%(names)s and %(count)s others are typing|other": "%(names)s und %(count)s weitere schreiben", "And %(count)s more...|other": "Und %(count)s weitere...", @@ -999,7 +999,7 @@ "Notify the whole room": "Alle im Raum benachrichtigen", "Room Notification": "Raum-Benachrichtigung", "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Diese Räume werden Community-Mitgliedern auf der Community-Seite angezeigt. Community-Mitglieder können diesen Räumen beitreten, indem sie auf diese klicken.", - "Show these rooms to non-members on the community page and room list?": "Sollen diese Räume Nicht-Mitgliedern auf der Community-Seite und der Raum-Liste angezeigt werden?", + "Show these rooms to non-members on the community page and room list?": "Sollen diese Räume Nicht-Mitgliedern auf der Community-Seite und in der Raum-Liste angezeigt werden?", "

HTML for your community's page

\n

\n Use the long description to introduce new members to the community, or distribute\n some important links\n

\n

\n You can even use 'img' tags\n

\n": "

HTML für deine Community-Seite

\n

\n Nutze die ausführliche Beschreibung, um neuen Mitgliedern diese Community vorzustellen\n oder um wichtige Links bereitzustellen.\n

\n

\n Du kannst sogar 'img'-Tags (HTML) verwenden\n

\n", "Your community hasn't got a Long Description, a HTML page to show to community members.
Click here to open settings and give it one!": "Deine Community hat noch keine ausführliche Beschreibung, d. h. eine HTML-Seite, die Community-Mitgliedern angezeigt wird.
Hier klicken, um die Einstellungen zu öffnen und eine Beschreibung zu erstellen!", "Custom of %(powerLevel)s": "benutzerdefiniert mit Wert %(powerLevel)s" From 07addbe1e025bbf6dc2abcb6f0aecfaed29830e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Tue, 14 Nov 2017 14:39:32 +0000 Subject: [PATCH 021/927] Translated using Weblate (Slovak) Currently translated at 99.7% (931 of 933 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sk/ --- src/i18n/strings/sk.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/sk.json b/src/i18n/strings/sk.json index 7a38caec82..329af0e0a9 100644 --- a/src/i18n/strings/sk.json +++ b/src/i18n/strings/sk.json @@ -105,7 +105,7 @@ "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "Podpisovací kľúč, ktorý ste poskytli súhlasí s podpisovacím kľúčom, ktorý ste dostali zo zariadenia %(deviceId)s používateľa %(userId)s's. Zariadenie je považované za overené.", "Unrecognised command:": "Nerozpoznaný príkaz:", "Reason": "Dôvod", - "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s prijal pozvanie pre %(displayName)s.", + "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s prijal pozvanie do %(displayName)s.", "%(targetName)s accepted an invitation.": "%(targetName)s prijal pozvanie.", "%(senderName)s requested a VoIP conference.": "%(senderName)s požiadal o VoIP konferenciu.", "%(senderName)s invited %(targetName)s.": "%(senderName)s pozval %(targetName)s.", From 3a6e89584ce78824a6782744d10ca1c3820225d3 Mon Sep 17 00:00:00 2001 From: Szimszon Date: Tue, 14 Nov 2017 20:32:13 +0000 Subject: [PATCH 022/927] Translated using Weblate (Hungarian) Currently translated at 100.0% (933 of 933 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 8a30c176b3..b6cebfc403 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -1005,5 +1005,7 @@ "Sign in to get started": "Az induláshoz jelentkezz be", "Status.im theme": "Állapot.im téma", "Please note you are logging into the %(hs)s server, not matrix.org.": "Figyelem, a %(hs)s szerverre jelentkezel be és nem a matrix.org szerverre.", - "Username on %(hs)s": "Felhasználónév a %(hs)s szerveren" + "Username on %(hs)s": "Felhasználónév a %(hs)s szerveren", + "Restricted": "Korlátozott", + "Custom of %(powerLevel)s": "Egyedi beállítás: %(powerLevel)s" } From 955362ee2d38f31cf8d506140bb00341d1d8bb50 Mon Sep 17 00:00:00 2001 From: Bamstam Date: Wed, 15 Nov 2017 00:16:05 +0000 Subject: [PATCH 023/927] Translated using Weblate (German) Currently translated at 99.4% (929 of 934 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index f6a9e00507..6102fc884b 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -1002,5 +1002,6 @@ "Show these rooms to non-members on the community page and room list?": "Sollen diese Räume Nicht-Mitgliedern auf der Community-Seite und in der Raum-Liste angezeigt werden?", "

HTML for your community's page

\n

\n Use the long description to introduce new members to the community, or distribute\n some important links\n

\n

\n You can even use 'img' tags\n

\n": "

HTML für deine Community-Seite

\n

\n Nutze die ausführliche Beschreibung, um neuen Mitgliedern diese Community vorzustellen\n oder um wichtige Links bereitzustellen.\n

\n

\n Du kannst sogar 'img'-Tags (HTML) verwenden\n

\n", "Your community hasn't got a Long Description, a HTML page to show to community members.
Click here to open settings and give it one!": "Deine Community hat noch keine ausführliche Beschreibung, d. h. eine HTML-Seite, die Community-Mitgliedern angezeigt wird.
Hier klicken, um die Einstellungen zu öffnen und eine Beschreibung zu erstellen!", - "Custom of %(powerLevel)s": "benutzerdefiniert mit Wert %(powerLevel)s" + "Custom of %(powerLevel)s": "benutzerdefiniert mit Wert %(powerLevel)s", + "Username on %(hs)s": "Benutzername auf %(hs)s" } From a226a4997be92c5debe67338f8d09b0d32c8082f Mon Sep 17 00:00:00 2001 From: Szimszon Date: Tue, 14 Nov 2017 20:33:16 +0000 Subject: [PATCH 024/927] Translated using Weblate (Hungarian) Currently translated at 100.0% (934 of 934 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index b6cebfc403..3cc3f3e9cd 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -1007,5 +1007,6 @@ "Please note you are logging into the %(hs)s server, not matrix.org.": "Figyelem, a %(hs)s szerverre jelentkezel be és nem a matrix.org szerverre.", "Username on %(hs)s": "Felhasználónév a %(hs)s szerveren", "Restricted": "Korlátozott", - "Custom of %(powerLevel)s": "Egyedi beállítás: %(powerLevel)s" + "Custom of %(powerLevel)s": "Egyedi beállítás: %(powerLevel)s", + "Presence Management": "Jelenlét menedzsment" } From 648be26fb7618df081342e39f3a9c9d22c6eadf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Wed, 15 Nov 2017 16:27:03 +0000 Subject: [PATCH 025/927] Translated using Weblate (French) Currently translated at 100.0% (932 of 932 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index f252786732..cc6f500820 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -1003,5 +1003,11 @@ "Please note you are logging into the %(hs)s server, not matrix.org.": "Veuillez noter que vous vous connecter au serveur %(hs)s, pas à matrix.org.", "Username on %(hs)s": "Nom d'utilisateur sur %(hs)s", "Restricted": "Restreint", - "Custom of %(powerLevel)s": "Personnalisé de %(powerLevel)s" + "Custom of %(powerLevel)s": "Personnalisé de %(powerLevel)s", + "Presence Management": "Gestion de présence", + "Hide avatar changes": "Masquer les changements d'avatar", + "Hide display name changes": "Masquer les changements de nom affiché", + "Enable inline URL previews by default": "Activer l'aperçu des URL par défaut", + "Enable URL previews for this room (only affects you)": "Activer l'aperçu des URL pour ce salon (n'affecte que vous)", + "Enable URL previews by default for participants in this room": "Activer l'aperçu des URL par défaut pour les participants de ce salon" } From 1f1ca152193e28e76b69cb9b34124c6c07d7d63b Mon Sep 17 00:00:00 2001 From: Bamstam Date: Wed, 15 Nov 2017 18:24:20 +0000 Subject: [PATCH 026/927] Translated using Weblate (German) Currently translated at 98.9% (922 of 932 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 6102fc884b..6d4ef41132 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -124,7 +124,7 @@ "Phone": "Telefon", "Please check your email and click on the link it contains. Once this is done, click continue.": "Bitte prüfe deinen E-Mail-Posteingang und klicke auf den in der E-Mail enthaltenen Link. Anschließend auf \"Fortsetzen\" klicken.", "Privacy warning": "Datenschutzwarnung", - "Privileged Users": "Privilegierte Nutzer", + "Privileged Users": "Privilegierte Benutzer", "Profile": "Profil", "Refer a friend to Riot:": "Freunde zu Riot einladen:", "Once you've followed the link it contains, click below": "Nachdem du dem darin enthaltenen Link gefolgt bist, klicke unten", @@ -310,7 +310,7 @@ "Usage": "Verwendung", "Use with caution": "Mit Vorsicht zu verwenden", "%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s hat die Einladung für %(targetName)s zurückgezogen.", - "You need to be able to invite users to do that.": "Du musst die Berechtigung haben, Nutzer einzuladen, um diese Aktion ausführen zu können.", + "You need to be able to invite users to do that.": "Du musst die Berechtigung haben, Benutzer einzuladen, um diese Aktion ausführen zu können.", "You need to be logged in.": "Du musst angemeldet sein.", "There are no visible files in this room": "Es gibt keine sichtbaren Dateien in diesem Raum", "Connectivity to the server has been lost.": "Verbindung zum Server wurde unterbrochen.", @@ -390,7 +390,7 @@ "Unknown room %(roomId)s": "Unbekannter Raum %(roomId)s", "You seem to be in a call, are you sure you want to quit?": "Du scheinst in einem Anruf zu sein. Bist du sicher schließen zu wollen?", "You seem to be uploading files, are you sure you want to quit?": "Du scheinst Dateien hochzuladen. Bist du sicher schließen zu wollen?", - "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Du wirst diese Änderung nicht rückgängig machen können, da der Nutzer dasselbe Berechtigungslevel wie du selbst erhalten wird.", + "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Du wirst diese Änderung nicht rückgängig machen können, da der Benutzer dasselbe Berechtigungslevel wie du selbst erhalten wird.", "Make Moderator": "Zum Moderator ernennen", "Room": "Raum", "Cancel": "Abbrechen", @@ -541,7 +541,7 @@ "Error decrypting video": "Video-Entschlüsselung fehlgeschlagen", "Import room keys": "Raum-Schlüssel importieren", "File to import": "Zu importierende Datei", - "Failed to invite the following users to the %(roomName)s room:": "Das Einladen der folgenden Nutzer in den Raum \"%(roomName)s\" ist fehlgeschlagen:", + "Failed to invite the following users to the %(roomName)s room:": "Das Einladen der folgenden Benutzer in den Raum \"%(roomName)s\" ist fehlgeschlagen:", "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Bist du sicher, dass du dieses Ereignis entfernen (löschen) möchtest? Wenn du die Änderung eines Raum-Namens oder eines Raum-Themas löscht, kann dies dazu führen, dass die ursprüngliche Änderung rückgängig gemacht wird.", "This process allows you to export the keys for messages you have received in encrypted rooms to a local file. You will then be able to import the file into another Matrix client in the future, so that client will also be able to decrypt these messages.": "Dieser Prozess erlaubt es dir, die Schlüssel für die in verschlüsselten Räumen empfangenen Nachrichten in eine lokale Datei zu exportieren. In Zukunft wird es möglich sein, diese Datei in einen anderen Matrix-Client zu importieren, sodass dieser Client diese Nachrichten ebenfalls entschlüsseln kann.", "The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.": "Mit der exportierten Datei kann jeder, der diese Datei lesen kann, jede verschlüsselte Nachricht entschlüsseln, die für dich lesbar ist. Du solltest die Datei also unbedingt sicher verwahren. Um den Vorgang sicherer zu gestalten, solltest du unten eine Passphrase eingeben, die dazu verwendet wird, die exportierten Daten zu verschlüsseln. Anschließend wird es nur möglich sein, die Daten zu importieren, wenn dieselbe Passphrase verwendet wird.", @@ -559,7 +559,7 @@ " (unsupported)": " (nicht unterstützt)", "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "Dieser Prozess erlaubt es dir, die zuvor von einem anderen Matrix-Client exportierten Verschlüsselungs-Schlüssel zu importieren. Danach kannst du alle Nachrichten entschlüsseln, die auch bereits auf dem anderen Client entschlüsselt werden konnten.", "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Dies wird dein Benutzerkonto dauerhaft unbenutzbar machen. Du wirst nicht in der Lage sein, dich mit derselben Benutzer-ID erneut zu registrieren.", - "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Um sicherzustellen, dass diesem Gerät vertraut werden kann, kontaktiere bitte den Eigentümer des Geräts über ein anderes Kommunikationsmittel (z.B. im persönlichen Gespräch oder durch einen Telefon-Anruf) und vergewissere dich, dass der Schlüssel, den der Eigentümer in den Nutzer-Einstellungen für dieses Gerät sieht, mit dem folgenden Schlüssel identisch ist:", + "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Um sicherzustellen, dass diesem Gerät vertraut werden kann, kontaktiere bitte den Eigentümer des Geräts über ein anderes Kommunikationsmittel (z.B. im persönlichen Gespräch oder durch einen Telefonanruf) und vergewissere dich, dass der Schlüssel, den der Eigentümer in den Benutzer-Einstellungen für dieses Gerät sieht, mit dem folgenden Schlüssel identisch ist:", "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "Wenn er identisch ist, bitte den Bestätigen-Button unten verwenden. Falls er nicht identisch sein sollte, hat eine Fremdperson Kontrolle über dieses Gerät und es sollte gesperrt werden.", "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "Bei der Wiederherstellung deiner letzten Sitzung ist ein Fehler aufgetreten. Um fortzufahren, musst du dich erneut anmelden. Ein zuvor verschlüsselter Chatverlauf wird in der Folge nicht mehr lesbar sein.", "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Wenn du zuvor eine aktuellere Version von Riot verwendet hast, ist deine Sitzung eventuell inkompatibel mit dieser Version. Bitte schließe dieses Fenster und kehre zur aktuelleren Version zurück.", @@ -616,7 +616,7 @@ "Save": "Speichern", "Tagged as: ": "Markiert als: ", "This Home Server does not support login using email address.": "Dieser Heimserver unterstützt den Login mittels E-Mail-Adresse nicht.", - "Unknown (user, device) pair:": "Unbekanntes (Nutzer-/Gerät-)Paar:", + "Unknown (user, device) pair:": "Unbekanntes (Benutzer-/Gerät-)Paar:", "Remote addresses for this room:": "Remote-Adressen für diesen Raum:", "Unrecognised command:": "Unbekannter Befehl:", "Unrecognised room alias:": "Unbekannter Raum-Alias:", @@ -649,7 +649,7 @@ "Start Chatting": "Starte Gespräche", "Click on the button below to start chatting!": "Unten auf den Button klicken, um einen Chat zu beginnen!", "Create a new chat or reuse an existing one": "Neuen Chat erstellen oder einen vorhandenen Chat fortsetzen", - "You already have existing direct chats with this user:": "Du hast bereits direkte Chats mit diesem Nutzer:", + "You already have existing direct chats with this user:": "Du hast bereits existierende direkte Chats mit diesem Benutzer:", "Username available": "Benutzername ist verfügbar", "Username not available": "Benutzername ist nicht verfügbar", "Something went wrong!": "Etwas ging schief!", @@ -752,11 +752,11 @@ "Unbans user with given id": "Verbannung aufheben für Benutzer mit angegebener ID", "You are not in this room.": "Du bist nicht in diesem Raum.", "You do not have permission to do that in this room.": "Du hast keine Berechtigung, dies in diesem Raum zu tun.", - "Verifies a user, device, and pubkey tuple": "Verifiziert ein Tupel aus Nutzer, Gerät und öffentlichem Schlüssel", + "Verifies a user, device, and pubkey tuple": "Verifiziert ein Tupel aus Benutzer, Gerät und öffentlichem Schlüssel", "Autocomplete Delay (ms):": "Verzögerung bei Autovervollständigung (ms):", "Loading device info...": "Lädt Geräte-Info...", "Example": "Beispiel", - "Create": "Erstelle", + "Create": "Erstellen", "Room creation failed": "Raum-Erstellung fehlgeschlagen", "Featured Rooms:": "Hervorgehobene Räume:", "Featured Users:": "Hervorgehobene Benutzer:", From 45a90ef038e9a63d675d8a70434581247f9c17b7 Mon Sep 17 00:00:00 2001 From: Andrey Date: Wed, 15 Nov 2017 16:40:07 +0000 Subject: [PATCH 027/927] Translated using Weblate (Russian) Currently translated at 98.3% (917 of 932 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index d46076e2ff..db4174ec0d 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -990,5 +990,12 @@ "Sign in to get started": "Войдите, чтобы начать", "Visibility in Room List": "Видимость в списке комнат", "Visible to everyone": "Видимый для всех", - "Only visible to community members": "Только участникам сообщества" + "Only visible to community members": "Только участникам сообщества", + "Presence Management": "Управление присутствием", + "Hide avatar changes": "Скрыть изменения аватара", + "Hide display name changes": "Скрыть изменения отображаемого имени", + "Enable inline URL previews by default": "Включить просмотр URL-адресов по умолчанию", + "Enable URL previews for this room (only affects you)": "Включить просмотр URL-адресов для этой комнаты (влияет только на вас)", + "Enable URL previews by default for participants in this room": "Включить просмотр URL-адресов по умолчанию для участников этой комнаты", + "Status.im theme": "Тема status.im" } From 0596925a8632ce6bd5e9f304f43a98a5f0fd1b01 Mon Sep 17 00:00:00 2001 From: Szimszon Date: Wed, 15 Nov 2017 19:05:05 +0000 Subject: [PATCH 028/927] Translated using Weblate (Hungarian) Currently translated at 100.0% (932 of 932 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 3cc3f3e9cd..7b57d306fd 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -1008,5 +1008,10 @@ "Username on %(hs)s": "Felhasználónév a %(hs)s szerveren", "Restricted": "Korlátozott", "Custom of %(powerLevel)s": "Egyedi beállítás: %(powerLevel)s", - "Presence Management": "Jelenlét menedzsment" + "Presence Management": "Jelenlét menedzsment", + "Hide avatar changes": "Avatar változások elrejtése", + "Hide display name changes": "Név változások elrejtése", + "Enable inline URL previews by default": "Beágyazott URL előnézetek alapértelmezett engedélyezése", + "Enable URL previews for this room (only affects you)": "URL előnézet engedélyezése ebben a szobában (csak téged érint)", + "Enable URL previews by default for participants in this room": "URL előnézet alapértelmezett engedélyezése a szoba tagságának" } From 843bdd6e13502d85a79ef197142664b64cd56346 Mon Sep 17 00:00:00 2001 From: Bamstam Date: Thu, 16 Nov 2017 00:25:51 +0000 Subject: [PATCH 029/927] Translated using Weblate (German) Currently translated at 99.5% (928 of 932 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 6d4ef41132..9b7bc8f4a5 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -474,7 +474,7 @@ "Passwords can't be empty": "Passwortfelder dürfen nicht leer sein", "Report it": "Melden", "riot-web version:": "Version von riot-web:", - "Scroll to bottom of page": "Zum Ende der Seite springen", + "Scroll to bottom of page": "Zum Seitenende springen", "Show timestamps in 12 hour format (e.g. 2:30pm)": "Zeitstempel im 12-Stunden-Format anzeigen (z. B. 2:30pm)", "Email address": "E-Mail-Adresse", "Error decrypting attachment": "Fehler beim Entschlüsseln des Anhangs", @@ -769,7 +769,7 @@ "Cannot add any more widgets": "Kann keine weiteren Widgets hinzufügen", "Do you want to load widget from URL:": "Möchtest du das Widget von folgender URL laden:", "Integrations Error": "Integrations-Error", - "NOTE: Apps are not end-to-end encrypted": "BEACHTE: Apps sind nicht Ende-zu-Ende verschlüsselt", + "NOTE: Apps are not end-to-end encrypted": "BEACHTE: Apps sind nicht Ende-zu-Ende-verschlüsselt", "%(widgetName)s widget added by %(senderName)s": "%(senderName)s hat das Widget %(widgetName)s hinzugefügt", "%(widgetName)s widget removed by %(senderName)s": "%(senderName)s hat das Widget %(widgetName)s entfernt", "Robot check is currently unavailable on desktop - please use a web browser": "In der Desktop-Version kann derzeit nicht geprüft werden, ob ein Benutzer ein Roboter ist. Bitte einen Webbrowser verwenden", @@ -795,7 +795,7 @@ "Advanced options": "Erweiterte Optionen", "Block users on other matrix homeservers from joining this room": "Benutzer anderer Matrix-Heimserver das Betreten dieses Raumes verbieten", "This setting cannot be changed later!": "Diese Einstellung kann nachträglich nicht mehr geändert werden!", - "Unignore": "Entignorieren", + "Unignore": "Ignorieren aufheben", "User Options": "Benutzer-Optionen", "Unignored user": "Benutzer nicht mehr ignoriert", "Ignored user": "Benutzer ignoriert", @@ -1003,5 +1003,11 @@ "

HTML for your community's page

\n

\n Use the long description to introduce new members to the community, or distribute\n some important links\n

\n

\n You can even use 'img' tags\n

\n": "

HTML für deine Community-Seite

\n

\n Nutze die ausführliche Beschreibung, um neuen Mitgliedern diese Community vorzustellen\n oder um wichtige Links bereitzustellen.\n

\n

\n Du kannst sogar 'img'-Tags (HTML) verwenden\n

\n", "Your community hasn't got a Long Description, a HTML page to show to community members.
Click here to open settings and give it one!": "Deine Community hat noch keine ausführliche Beschreibung, d. h. eine HTML-Seite, die Community-Mitgliedern angezeigt wird.
Hier klicken, um die Einstellungen zu öffnen und eine Beschreibung zu erstellen!", "Custom of %(powerLevel)s": "benutzerdefiniert mit Wert %(powerLevel)s", - "Username on %(hs)s": "Benutzername auf %(hs)s" + "Username on %(hs)s": "Benutzername auf %(hs)s", + "Hide avatar changes": "Profilbild-Änderungen verbergen", + "Hide display name changes": "Anzeigenamen-Änderungen verbergen", + "Enable inline URL previews by default": "URL-Vorschau standardmäßig aktivieren", + "Enable URL previews for this room (only affects you)": "URL-Vorschau für diesen Raum aktivieren (betrifft nur dich)", + "Enable URL previews by default for participants in this room": "URL-Vorschau standardmäßig für Mitglieder dieses Raumes aktivieren", + "Please note you are logging into the %(hs)s server, not matrix.org.": "Hinweis: Du meldest dich auf dem %(hs)s-Server an, nicht auf matrix.org." } From 44e8a2cd545f0d2bea51abd1caa0925fde90c8d1 Mon Sep 17 00:00:00 2001 From: Bamstam Date: Thu, 16 Nov 2017 12:45:37 +0000 Subject: [PATCH 030/927] Translated using Weblate (German) Currently translated at 99.6% (927 of 930 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 9b7bc8f4a5..d4979767ba 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -266,7 +266,7 @@ "%(names)s and one other are typing": "%(names)s und ein weiteres Raum-Mitglied schreiben", "%(senderName)s answered the call.": "%(senderName)s hat den Anruf angenommen.", "%(senderName)s banned %(targetName)s.": "%(senderName)s hat %(targetName)s dauerhaft aus dem Raum verbannt.", - "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s hat den Anzeigenamen von \"%(oldDisplayName)s\" auf \"%(displayName)s\" geändert.", + "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s hat den Anzeigenamen von %(oldDisplayName)s auf %(displayName)s geändert.", "%(senderName)s changed their profile picture.": "%(senderName)s hat das Profilbild geändert.", "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s hat das Berechtigungslevel von %(powerLevelDiffText)s geändert.", "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s hat den Raumnamen geändert zu %(roomName)s.", @@ -1009,5 +1009,8 @@ "Enable inline URL previews by default": "URL-Vorschau standardmäßig aktivieren", "Enable URL previews for this room (only affects you)": "URL-Vorschau für diesen Raum aktivieren (betrifft nur dich)", "Enable URL previews by default for participants in this room": "URL-Vorschau standardmäßig für Mitglieder dieses Raumes aktivieren", - "Please note you are logging into the %(hs)s server, not matrix.org.": "Hinweis: Du meldest dich auf dem %(hs)s-Server an, nicht auf matrix.org." + "Please note you are logging into the %(hs)s server, not matrix.org.": "Hinweis: Du meldest dich auf dem %(hs)s-Server an, nicht auf matrix.org.", + "Resend all or cancel all now. You can also select individual messages to resend or cancel.": "Alle erneut senden oder alle verwerfen. Du kannst auch einzelne Nachrichten erneut senden oder verwerfen.", + "There's no one else here! Would you like to invite others or stop warning about the empty room?": "Sonst ist hier aktuell niemand. Möchtest du Benutzer einladen oder die Warnmeldung bezüglich des leeren Raums deaktivieren?", + "Sign in to get started": "Melde dich an, um loszulegen" } From 02ffa919c476c2404411db18e2b7c3c8aa82bcb3 Mon Sep 17 00:00:00 2001 From: Walter Date: Thu, 16 Nov 2017 12:48:03 +0000 Subject: [PATCH 031/927] Translated using Weblate (Russian) Currently translated at 98.7% (918 of 930 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index db4174ec0d..78d0f7b976 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -997,5 +997,10 @@ "Enable inline URL previews by default": "Включить просмотр URL-адресов по умолчанию", "Enable URL previews for this room (only affects you)": "Включить просмотр URL-адресов для этой комнаты (влияет только на вас)", "Enable URL previews by default for participants in this room": "Включить просмотр URL-адресов по умолчанию для участников этой комнаты", - "Status.im theme": "Тема status.im" + "Status.im theme": "Тема status.im", + "Restricted": "Ограниченный", + "Username on %(hs)s": "Имя пользователя на %(hs)s", + "The visibility of '%(roomName)s' in %(groupId)s could not be updated.": "Видимость '%(roomName)s' в %(groupId)s не может быть актуализирована.", + "%(severalUsers)srejected their invitations %(count)s times|other": "%(severalUsers)s ваше приглашение было отклонено %(count)s раз", + "%(severalUsers)srejected their invitations %(count)s times|one": "%(severalUsers)s ваше приглашение отклонил" } From f4b7741449e25b8ac6d1e51243e343d0573a521a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Thu, 16 Nov 2017 12:54:02 +0000 Subject: [PATCH 032/927] Translated using Weblate (Slovak) Currently translated at 99.7% (928 of 930 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sk/ --- src/i18n/strings/sk.json | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/i18n/strings/sk.json b/src/i18n/strings/sk.json index 329af0e0a9..ae8dd9c336 100644 --- a/src/i18n/strings/sk.json +++ b/src/i18n/strings/sk.json @@ -266,7 +266,7 @@ "Hangup": "Zavesiť", "Voice call": "Audio hovor", "Video call": "Video hovor", - "Hide Apps": "Skriť aplikácie", + "Hide Apps": "Skryť aplikácie", "Show Apps": "Zobraziť aplikácie", "Upload file": "Nahrať súbor", "Show Text Formatting Toolbar": "Zobraziť lištu formátovania textu", @@ -275,7 +275,7 @@ "You do not have permission to post to this room": "Nemáte udelené právo posielať do tejto miestnosti", "Turn Markdown on": "Povoliť Markdown", "Turn Markdown off": "Zakázať Markdown", - "Hide Text Formatting Toolbar": "Skriť lištu formátovania textu", + "Hide Text Formatting Toolbar": "Skryť lištu formátovania textu", "Server error": "Chyba servera", "Server unavailable, overloaded, or something else went wrong.": "Server je nedostupný, preťažený, alebo sa pokazilo niečo iné.", "Command error": "Chyba príkazu", @@ -758,18 +758,18 @@ "Uploading %(filename)s and %(count)s others|zero": "Nahrávanie %(filename)s", "Uploading %(filename)s and %(count)s others|one": "Nahrávanie %(filename)s a %(count)s ďalší súbor", "Autoplay GIFs and videos": "Automaticky prehrávať animované GIF obrázky a videá", - "Hide read receipts": "Skriť potvrdenia o prečítaní", + "Hide read receipts": "Skryť potvrdenia o prečítaní", "Don't send typing notifications": "Neposielať oznámenia keď píšete", "Always show message timestamps": "Vždy zobrazovať časovú značku správ", "Show timestamps in 12 hour format (e.g. 2:30pm)": "Pri zobrazovaní časových značiek používať 12 hodinový formát (napr. 2:30pm)", - "Hide join/leave messages (invites/kicks/bans unaffected)": "Skriť správy o vstupe a opustení miestnosti (netýka sa pozvaní/vykopnutí/zákazov vstupu)", + "Hide join/leave messages (invites/kicks/bans unaffected)": "Skryť správy o vstupe a opustení miestnosti (netýka sa pozvaní/vykopnutí/zákazov vstupu)", "Hide avatar and display name changes": "Skriť zmeny zobrazovaného mena a avatara", "Use compact timeline layout": "Použiť kompaktné rozloženie časovej osy", - "Hide removed messages": "Skriť odstránené správy", + "Hide removed messages": "Skryť odstránené správy", "Enable automatic language detection for syntax highlighting": "Povoliť automatickú detegciu jazyka pre zvýrazňovanie syntaxe", "Automatically replace plain text Emoji": "Automaticky nahrádzať textové Emoji", "Disable Emoji suggestions while typing": "Zakázať návrhy Emoji počas písania", - "Hide avatars in user and room mentions": "Skriť avatarov pri zmienkach miestností a používateľov", + "Hide avatars in user and room mentions": "Skryť avatarov pri zmienkach miestností a používateľov", "Disable big emoji in chat": "Zakázať veľké Emoji v konverzácii", "Mirror local video feed": "Zrkadliť lokálne video", "Opt out of analytics": "Odhlásiť sa zo zberu analytických údajov", @@ -930,5 +930,13 @@ "Sign in to get started": "Začnite prihlásením sa", "Status.im theme": "Téma status.im", "Please note you are logging into the %(hs)s server, not matrix.org.": "Všimnite si: Práve sa prihlasujete na server %(hs)s, nie na server matrix.org.", - "Username on %(hs)s": "Meno používateľa na servery %(hs)s" + "Username on %(hs)s": "Meno používateľa na servery %(hs)s", + "Restricted": "Obmedzené", + "Presence Management": "Spravovanie prítomnosti", + "Hide avatar changes": "Skryť zmeny avatara", + "Hide display name changes": "Skryť zmeny zobrazovaného mena", + "Enable inline URL previews by default": "Predvolene povoliť náhľady URL adries", + "Enable URL previews for this room (only affects you)": "Povoliť náhľady URL adries pre túto miestnosť (ovplyvňuje len vás)", + "Enable URL previews by default for participants in this room": "Predvolene povoliť náhľady URL adries pre členov tejto miestnosti", + "Custom of %(powerLevel)s": "Vlastná úroveň %(powerLevel)s" } From 1d2e13f91dde17e13a0b7432fa9cf30a03cfcba2 Mon Sep 17 00:00:00 2001 From: Andrey Date: Thu, 16 Nov 2017 13:21:52 +0000 Subject: [PATCH 033/927] Translated using Weblate (Russian) Currently translated at 98.7% (920 of 932 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 78d0f7b976..e9eba019c8 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -998,9 +998,11 @@ "Enable URL previews for this room (only affects you)": "Включить просмотр URL-адресов для этой комнаты (влияет только на вас)", "Enable URL previews by default for participants in this room": "Включить просмотр URL-адресов по умолчанию для участников этой комнаты", "Status.im theme": "Тема status.im", - "Restricted": "Ограниченный", + "Restricted": "Ограничен", "Username on %(hs)s": "Имя пользователя на %(hs)s", - "The visibility of '%(roomName)s' in %(groupId)s could not be updated.": "Видимость '%(roomName)s' в %(groupId)s не может быть актуализирована.", - "%(severalUsers)srejected their invitations %(count)s times|other": "%(severalUsers)s ваше приглашение было отклонено %(count)s раз", - "%(severalUsers)srejected their invitations %(count)s times|one": "%(severalUsers)s ваше приглашение отклонил" + "The visibility of '%(roomName)s' in %(groupId)s could not be updated.": "Видимость '%(roomName)s' в %(groupId)s не удалось обновить.", + "%(severalUsers)srejected their invitations %(count)s times|other": "%(severalUsers)s отклонили приглашения %(count)s раз", + "%(severalUsers)srejected their invitations %(count)s times|one": "%(severalUsers)s отклонили приглашения", + "URL previews are enabled by default for participants in this room.": "Предварительный просмотр URL-адресов для участников этой комнаты по умолчанию.", + "URL previews are disabled by default for participants in this room.": "Предварительный просмотр URL-адресов для участников этой комнаты по умолчанию." } From c9a66d375f44c99c6c93bc314e9f7761b34749b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Thu, 16 Nov 2017 14:45:01 +0000 Subject: [PATCH 034/927] Translated using Weblate (Slovak) Currently translated at 99.5% (928 of 932 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sk/ --- src/i18n/strings/sk.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/i18n/strings/sk.json b/src/i18n/strings/sk.json index ae8dd9c336..4ae115a4de 100644 --- a/src/i18n/strings/sk.json +++ b/src/i18n/strings/sk.json @@ -3,7 +3,7 @@ "This phone number is already in use": "Toto telefónne číslo sa už používa", "Failed to verify email address: make sure you clicked the link in the email": "Nepodarilo sa overiť emailovú adresu: Uistite sa, že ste správne klikli na odkaz v emailovej správe", "Call Timeout": "Časový limit hovoru", - "The remote side failed to pick up": "Vzdialenej strane sa nepodarilo priať hovor", + "The remote side failed to pick up": "Vzdialenej strane sa nepodarilo prijať hovor", "Unable to capture screen": "Nie je možné zachytiť obrazovku", "Existing Call": "Existujúci hovor", "You are already in a call.": "Už ste súčasťou iného hovoru.", @@ -469,7 +469,7 @@ "Password:": "Heslo:", "An email has been sent to %(emailAddress)s": "Na adresu %(emailAddress)s bola odoslaná správa", "Please check your email to continue registration.": "Prosím, skontrolujte si emaily, aby ste mohli pokračovať v registrácii.", - "Token incorrect": "Nesprávny token", + "Token incorrect": "Neplatný token", "A text message has been sent to %(msisdn)s": "Na číslo %(msisdn)s bola odoslaná textová správa", "Please enter the code it contains:": "Prosím, zadajte kód z tejto správy:", "Start authentication": "Spustiť overenie", @@ -870,7 +870,7 @@ "This server does not support authentication with a phone number.": "Tento server nepodporuje overenie telefónnym číslom.", "Missing password.": "Chýba heslo.", "Passwords don't match.": "Heslá sa nezhodujú.", - "Password too short (min %(MIN_PASSWORD_LENGTH)s).": "Heslo je veľmi krátke (minimálne %(MIN_PASSWORD_LENGTH)s).", + "Password too short (min %(MIN_PASSWORD_LENGTH)s).": "Heslo je veľmi krátke (minimálne %(MIN_PASSWORD_LENGTH)s znakov).", "This doesn't look like a valid email address.": "Zdá sa, že toto nie je platná emailová adresa.", "This doesn't look like a valid phone number.": "Zdá sa, že toto nie je platné telefónne číslo.", "You need to enter a user name.": "Musíte zadať používateľské meno.", From c025d50400ad625c5b2f47a8293e780d09bbdfca Mon Sep 17 00:00:00 2001 From: Szimszon Date: Thu, 16 Nov 2017 19:42:16 +0000 Subject: [PATCH 035/927] Translated using Weblate (Hungarian) Currently translated at 100.0% (932 of 932 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 7b57d306fd..91e90d1c1e 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -1013,5 +1013,9 @@ "Hide display name changes": "Név változások elrejtése", "Enable inline URL previews by default": "Beágyazott URL előnézetek alapértelmezett engedélyezése", "Enable URL previews for this room (only affects you)": "URL előnézet engedélyezése ebben a szobában (csak téged érint)", - "Enable URL previews by default for participants in this room": "URL előnézet alapértelmezett engedélyezése a szoba tagságának" + "Enable URL previews by default for participants in this room": "URL előnézet alapértelmezett engedélyezése a szoba tagságának", + "URL previews are enabled by default for participants in this room.": "Az URL előnézetek alapértelmezetten engedélyezve vannak a szobában jelenlévőknek.", + "URL previews are disabled by default for participants in this room.": "Az URL előnézet alapértelmezetten tiltva van a szobában jelenlévőknek.", + "Resend all or cancel all now. You can also select individual messages to resend or cancel.": "Mindet újraküldöd vagy mindet megszakítod. De egyenként is kijelölheted az üzenetet elküldésre vagy megszakításra.", + "There's no one else here! Would you like to invite others or stop warning about the empty room?": "Senki más nincs itt! Szeretnél meghívni másokat vagy leállítod a figyelmeztetést az üres szobára?" } From bceb11cde9cc58bac41ba37db727fc66d21d8df2 Mon Sep 17 00:00:00 2001 From: Stefan Parviainen Date: Thu, 16 Nov 2017 20:23:47 +0000 Subject: [PATCH 036/927] Translated using Weblate (Finnish) Currently translated at 89.0% (830 of 932 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fi/ --- src/i18n/strings/fi.json | 199 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 198 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fi.json b/src/i18n/strings/fi.json index aeca03c48d..b6e16a901e 100644 --- a/src/i18n/strings/fi.json +++ b/src/i18n/strings/fi.json @@ -689,5 +689,202 @@ "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Et voi kumota tätä toimintoa koska olet antamassa käyttäjälle saman oikeustason kuin sinullakin on.", "This process allows you to export the keys for messages you have received in encrypted rooms to a local file. You will then be able to import the file into another Matrix client in the future, so that client will also be able to decrypt these messages.": "Tämä prosessi mahdollistaa salatuissa huoneissa vastaanottamasi viestien salausavainten vieminen tiedostoon. Voit sitten myöhemmin tuoda ne toiseen Matrix-asiakasohjelmaan niin että myös se ohjema voi purkaa viestit.", "The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.": "Tämän tiedoston avulla kuka tahansa pystyy purkamaan kaikki salatut viestit jotka sinä voit nähdä, joten sinun täytyy säilyttää se turvallisesti. Helpottaaksesi tätä sinun pitäisi syötää salasana alla jonka avulla tiedosto salataan. Käyttäen samaa salasanaa voit myöhemmin tuoda tiedot ohjelmaan.", - "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "Tämä prosessi mahdollistaa aiemmin tallennettujen salausavainten tuominen toiseen Matrix-asiakasohjelmaan. Tämän jälkeen voit purkaa kaikki salatut viestit jotka toinen asiakasohjelma pystyisi purkamaan." + "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "Tämä prosessi mahdollistaa aiemmin tallennettujen salausavainten tuominen toiseen Matrix-asiakasohjelmaan. Tämän jälkeen voit purkaa kaikki salatut viestit jotka toinen asiakasohjelma pystyisi purkamaan.", + "Who would you like to add to this community?": "Kenet sinä haluaisit lisätä tähän yhteisöön?", + "Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "Varioitus: henkilöt jotka lisäät yhteisöön näkyvät kaikille jotka tietävät yhteisön tunnisteen", + "Invite new community members": "Kutsu uusia jäsenia yhteisöön", + "Name or matrix ID": "Nimi tai Matrix tunniste", + "Invite to Community": "Kutsu yhteisöön", + "Which rooms would you like to add to this community?": "Mitkä huoneet haluaisit listätä tähän yhteisöön?", + "Show these rooms to non-members on the community page and room list?": "Näytetäänkö nämä huoneet ei-jäsenille yhteisön sivulla ja huonelistassa?", + "Add rooms to the community": "Lisää huoneita tähän yhteisöön", + "Room name or alias": "Huoneen nimi taj alias", + "Add to community": "Lisää yhteisöön", + "Failed to invite the following users to %(groupId)s:": "Seuraavien käyttäjien kutsuminen ryhmään %(groupId)s epäonnistui:", + "Failed to invite users to community": "Käyttäjien kutsuminen yhteisöön epäonnostui", + "Failed to invite users to %(groupId)s": "Käyttäjien kutsuminen yhteisöön %(groupId)s epäonnistui", + "Failed to add the following rooms to %(groupId)s:": "Seiraavien huoneiden lisääminen yhteisöön %(groupId)s epäonnistui:", + "Restricted": "Rajoitettu", + "You are now ignoring %(userId)s": "Et enää huomioi käyttäjää %(userId)s", + "You are no longer ignoring %(userId)s": "Huomioit jälleen käyttäjän %(userId)s", + "%(senderName)s removed their profile picture.": "%(senderName)s poisti profiilikuvansa.", + "%(senderName)s set a profile picture.": "%(senderName)s asetti profiilikuvan.", + "%(senderName)s made future room history visible to all room members, from the point they are invited.": "%(senderName)s teki tulevan huonehistorian näkyväksi kaikille huoneen jäsenille, kutsusta lähtien.", + "%(senderName)s made future room history visible to all room members, from the point they joined.": "%(senderName)s teki tulevan huonehistorian näkyväksi kaikille huoneen jäsenille, liittymisestä asti.", + "%(senderName)s made future room history visible to all room members.": "%(senderName)s teki tulevan huonehistorian näkyväksi kaikille huoneen jäsenille.", + "%(senderName)s made future room history visible to anyone.": "%(senderName)s teki tulevan huonehistorian näkyväksi kaikille.", + "%(senderName)s made future room history visible to unknown (%(visibility)s).": "%(senderName)s teki tulevan huonehistorian näkyväksi tuntemattomalle (%(visibility)s).", + "%(senderName)s changed the pinned messages for the room.": "%(senderName) muutti tämän huoneen kiinnitetyt viestit.", + "%(names)s and %(count)s others are typing|other": "%(name)s ja %(count)s muuta kirjoittavat", + "%(names)s and %(count)s others are typing|one": "%(name)s ja yksi muu kirjoittvat", + "Message Pinning": "Kiinnitetyt viestit", + "Disable Emoji suggestions while typing": "Ota pois käytöstä emojiehdotukset kirjoittaessa", + "Hide avatar changes": "Piilota avatarmuutokset", + "Hide display name changes": "Piilota näyttönimimuutokset", + "Hide avatars in user and room mentions": "Piilota avatarit käyttäjä- ja huonemaininnoissa", + "Disable big emoji in chat": "Ota isot emojit pois käytöstä", + "Automatically replace plain text Emoji": "Korvaa automaattisesti teksimuotoiset emojit", + "Mirror local video feed": "Peilaa paikallinen videosyöte", + "Disable Peer-to-Peer for 1:1 calls": "Ota pois käytöstä suora P2P yhteys 1:1 puheluissa", + "Enable inline URL previews by default": "Ota URL esikatselu käyttöön oletusarvoisesti", + "Enable URL previews for this room (only affects you)": "Ota URL esikatselut käyttöön tässä huoneessa (koskee ainoastaan sinua)", + "Enable URL previews by default for participants in this room": "Ota URL esikatselu käyttöön kaikille huoneen jäsenille", + "%(senderName)s sent an image": "%(senderName)s lähetti kuvan", + "%(senderName)s sent a video": "%(senderName)s lähetti videon", + "%(senderName)s uploaded a file": "%(senderName)s latasi tiedoston", + "Disinvite this user?": "Peru tämän käyttäjän kutsu?", + "Kick this user?": "Poista tämä käyttäjä?", + "Unban this user?": "Poista tämän käyttäjän porttikielto?", + "Ban this user?": "Anna porttikielto tälle käyttäjälle?", + "Unignore": "Huomioi käyttäjä jälleen", + "Ignore": "Jätä käyttäjä huomioimatta", + "Jump to read receipt": "Hyppää lukukuittakseen", + "Mention": "Mainitse", + "Invite": "Kutsu", + "User Options": "Käyttäjä-asetukset", + "Make Moderator": "Anna moderaattorioikeudet", + "Admin Tools": "Ylläpitotyökalut", + "Show Apps": "Näytä appit", + "Unpin Message": "Poista viestin kiinnitys", + "Jump to message": "Hyppää viestiin", + "No pinned messages.": "Ei kiinnitettyjä viestejä.", + "Loading...": "Lataa...", + "Pinned Messages": "Kiinnitetyt viestit", + "Unnamed room": "Nimetön huone", + "World readable": "Täysin julkinen", + "Guests can join": "Vierailijat voivat liittyä", + "No rooms to show": "Ei huoneita", + "Failed to set avatar.": "Avatarin asettaminen epäonnistui", + "Upload avatar": "Lataa avatar", + "Remove avatar": "Poista avatar", + "Drop here to favourite": "Pudota tähän lisätäksesi suosikkeihin", + "Drop here to tag direct chat": "Pudota tähän merkitäksesi suoraksi viestittelyksi", + "Drop here to restore": "Pudota tähän palauttaaksesi", + "Drop here to demote": "Pudota tähän antaaksesi alhaisen prioriteetin", + "Community Invites": "Yhteisökutsut", + "You have been kicked from this room by %(userName)s.": "%(userName)s on poistanut sinut tästä huoneesta.", + "You have been banned from this room by %(userName)s.": "%(userName)s on antanut sinulle porttikiellon tähän huoneeseen.", + "You are trying to access a room.": "Yrität liittyä huoneeseen.", + "Banned by %(displayName)s": "%(displayName)s antanut porttikiellon", + "Privileged Users": "Etuoikeutetut käyttäjät", + "Members only (since the point in time of selecting this option)": "Vain jäsenet (tämän valinnat tekemisestä lähtien)", + "Members only (since they were invited)": "Vain jäsenet (heidän kutsustaan lähtien)", + "Members only (since they joined)": "Vain jäsenet (heidän liittymisestään lähtien)", + "To send messages, you must be a": "Voidaksesi ähettääksesi viestejä sinun tulee olla", + "To invite users into the room, you must be a": "Voidaksesi kutsua käyttäjiä huoneseen tulee sinun olla", + "To configure the room, you must be a": "Voidaksesi muokata huoneen asetuksia sinun tulee olla", + "To kick users, you must be a": "Voidaksesi poistaa käyttäjiä huoneesta sinun tulee olla", + "To ban users, you must be a": "Voidaksesi antaa porttikieltoja huoneeseen sinun tulee olla", + "To remove other users' messages, you must be a": "Voidaksesi poistaa muiden käyttäjien viestejä sinun tulee olla", + "To send events of type , you must be a": "Voidaksesi lähettää -tyypin viestejä sinun tulee olla", + "Invalid community ID": "Virheellinen yhteistötunniste", + "'%(groupId)s' is not a valid community ID": "'%(groupId)s' on virheellinen yhteisötunniste", + "Related Communities": "Liittyvät yhteisöt", + "Related communities for this room:": "Tähän huoneeseen liittyvät yhteisöt:", + "This room has no related communities": "Tähän huoneseen ei liity yhtään yhteisöä", + "New community ID (e.g. +foo:%(localDomain)s)": "Uusi yhteisötunniste (esim. +foo:%(localDomain)s)", + "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s muutti huoneen %(roomName)s avatarin", + "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName) poisti huoneen avatarin.", + "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s muutti huoneen avatariksi ", + "You are about to be taken to a third-party site so you can authenticate your account for use with %(integrationsUrl)s. Do you wish to continue?": "Sinut ohjataan kolmannen osapuolen sivustolle jotta voit autentikoida tilisi käyttääksesi %(integrationsUrl)s. Haluatko jatkaa?", + "Message removed by %(userId)s": "Käyttäjän %(userId)s poistama viesti", + "Message removed": "Viesti poistettu", + "Sign in with CAS": "Kirjaudu käyttäen CAS", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.": "Voit kirjautua toiselle Matrix kotipalvelimelle syöttämällä palvelimen URL-osoite palvelin-asetuksissa.", + "This allows you to use this app with an existing Matrix account on a different home server.": "Tämä mahdollistaa tämän ohjelman käytön olemassa olevan toisella palvelimella sijaitsevan Matrix tilin kanssa.", + "You can also set a custom identity server but this will typically prevent interaction with users based on email address.": "Voit myös käyttää toista identiteettipalvelinta mutta tyypillisesti tämä estää sähköpostiosoitteisiin perustuvan kanssakäynnin muiden käyttäjien kanssa.", + "An email has been sent to %(emailAddress)s": "Viesti lähetetty osoitteeseen %(emailAddress)s", + "Please check your email to continue registration.": "Ole hyvä ja tarkista sähköpostisi jatkaaksesi.", + "A text message has been sent to %(msisdn)s": "Tekstiviesti on lähetetty numeroon %(msisdn)s", + "Username on %(hs)s": "Käyttäjänimi palvelimella %(hs)s", + "Custom server": "Muu palvelin", + "Remove from community": "Poista yhteisöstä", + "Disinvite this user from community?": "Peruta tämän käyttäjän kutsu yhteisöön?", + "Remove this user from community?": "Poista tämä käyttäjä yhteisöstä?", + "Failed to withdraw invitation": "Kutsun peruminen epäonnistui", + "Failed to remove user from community": "Käyttäjän poistaminen yhteisöstä epäonnistui", + "Filter community members": "Suodata yhteisön jäsenet", + "Are you sure you want to remove '%(roomName)s' from %(groupId)s?": "Oletko varma että haluat poistaa '%(roomName)s' yhteisöstä %(groupId)s?", + "Removing a room from the community will also remove it from the community page.": "Huoneen poistaminen yhteisöstä poistaa sen myös yhteisösivulta.", + "Failed to remove room from community": "Huoneen poistaminen yhteisöstä epäonnistui", + "Failed to remove '%(roomName)s' from %(groupId)s": "Huoneen '%(roomName)s' poistaminen yhteisöstä %(groupId)s epäonnistui", + "The visibility of '%(roomName)s' in %(groupId)s could not be updated.": "Huoneen '%(roomName)s' näkyvyys yhteisössä %(groupId)s ei voitu päivittää.", + "Visibility in Room List": "Näkyvyys huoneluettelossa", + "Visible to everyone": "Näkyy kaikille", + "Only visible to community members": "Vain näkyvä yhteisön jäsenille", + "Filter community rooms": "Suodata yhteisön huoneet", + "Communities": "Yhteisöt", + "%(nameList)s %(transitionList)s": "%(nameList)s %(transitionList)s", + "were unbanned %(count)s times|other": "porttikiellot poistettiin %(count)s kertaa", + "And %(count)s more...|other": "Ja %(count)s lisää...", + "Matrix ID": "Matrix-tunniste", + "Matrix Room ID": "Matrix huonetunniste", + "email address": "sähköpostiosoite", + "Try using one of the following valid address types: %(validTypesList)s.": "Kokeile käyttää yhtä näistä valideista osoitetyypeistä: %(validTypesList)s.", + "You have entered an invalid address.": "Olet syöttänyt virheellisen sähköpostiosoitteen.", + "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Oletko varma että haluat poistaa tämän tapahtuman? Huomaa että jos poistat huoneen nimen tai aiheen muutoksen, saattaa muutos kumoutua.", + "Community IDs may only contain characters a-z, 0-9, or '=_-./'": "Yhteisötunnisteet voivat sisältää vain merkit a-z, 0-9 tai '=_-/'", + "Something went wrong whilst creating your community": "Jokin epäonnistui yhteisön luomisessa", + "Create Community": "Luo yhteisö", + "Community Name": "Yhteisön nimi", + "Community ID": "Yhteisötunniste", + "example": "esimerkki", + "Advanced options": "Lisäasetukset", + "Block users on other matrix homeservers from joining this room": "Estä käyttäjiä toisilta kotipalvelimilta liittymästä tähän huoneseen", + "This setting cannot be changed later!": "Tätä asetusta ei voi muuttaa enää myöhemmin!", + "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Tämä tekee tilistäsi pysyvästi käyttökelvottoman. Et voi rekisteröidä samaa tunnusta uudestaan.", + "Add rooms to the community summary": "Lisää huoneita yhteisön yhteenvetoon", + "Which rooms would you like to add to this summary?": "Mitkä huoneet haluaisit lisätä tähän yhteenvetoon?", + "Add to summary": "Lisää yhteenvetoon", + "Failed to add the following rooms to the summary of %(groupId)s:": "Seuraavien huoneiden lisääminen yhteisöön %(groupId)s epäonnistui:", + "Add a Room": "Lisää huone", + "Failed to remove the room from the summary of %(groupId)s": "Huoneen poistaminen yhteisön %(groupId)s yhteenvedosta epäonnistui", + "The room '%(roomName)s' could not be removed from the summary.": "Huoneen '%(roomName)s' poistaminen yhteenvedosta epäonnistui.", + "Add users to the community summary": "Lisää käyttäjiä yhteisön yhteenvetoon", + "Who would you like to add to this summary?": "Kenet haluaisit lisätä tähän yhteenvetoon?", + "Failed to add the following users to the summary of %(groupId)s:": "Seuraavien käyttäjien lisääminen yhteisön %(groupId)s yhteenvetoon epäonnistui:", + "Add a User": "Lisää käyttäjä", + "Failed to remove a user from the summary of %(groupId)s": "Käyttäjän poistaminen yhteisöstä %(groupId)s epäonnistui", + "The user '%(displayName)s' could not be removed from the summary.": "Käyttäjän '%(displayName)s' poistaminen yhteenvedosta epäonnistui.", + "Failed to update community": "Yhteisön päivittäminen epäonnistui", + "Unable to accept invite": "Kutsun hyväksyminen epäonnistui", + "Unable to reject invite": "Kutsun hylkääminen epäonnistui", + "Leave Community": "Poistu yhteisöstä", + "Leave %(groupName)s?": "Poistu yhteisöstä %(groupName)s?", + "Leave": "Poistu", + "Unable to leave room": "Poistuminen epäonnistui", + "Community Settings": "Yhteisöasetukset", + "Add rooms to this community": "Lisää huoneita tähän yhteisöön", + "Featured Rooms:": "Esiinnostetut huoneet:", + "Featured Users:": "Esiinnostetut käyttäjät:", + "%(inviter)s has invited you to join this community": "%(inviter)s on kutsunut sinut tähän yhteisöön", + "You are an administrator of this community": "Olet tämän yhteisön ylläpitäjä", + "You are a member of this community": "Olet tämän yhteisön jäsen", + "Community Member Settings": "Yhteisöjäsenasetukset", + "Publish this community on your profile": "Julkaise tämä yhteisö profiilissasi", + "Your community hasn't got a Long Description, a HTML page to show to community members.
Click here to open settings and give it one!": "Sinun yhteistöltäsi puuttuu pitkä kuvaus, HTML sivu joka näytetään yhteistön jäsenille.
Klikkaa tästä avataksesi asetukset luodaksesi sivun!", + "Long Description (HTML)": "Pitkä kuvaus (HTML)", + "Description": "Kuvaus", + "Community %(groupId)s not found": "Yhteisöä %(groupId)s ei löytynyt", + "This Home server does not support communities": "Tämä kotipalvelin ei tue yhteisöjä", + "Failed to load %(groupId)s": "Yhteisön %(groupId)s lataaminen epäonnistui", + "Your Communities": "Sinun yhteistösi", + "You're not currently a member of any communities.": "Et ole minkään yhteisön jäsen tällä hetkellä.", + "Error whilst fetching joined communities": "Virhe ladatessa listaa yhteistöistä joihin olet liittynyt", + "Create a new community": "Luo uusi yhteisö", + "Join an existing community": "Liity olemassaolevaan yhteisöön", + "Light theme": "Vaalea ulkoasu", + "Dark theme": "Tumma ulkoasu", + "Status.im theme": "Status.im ulkoasu", + "Autocomplete Delay (ms):": "Automaattitäydennyksen viive (ms):", + "Ignored Users": "Huomiotta jätetyt käyttäjät:", + "An email has been sent to %(emailAddress)s. Once you've followed the link it contains, click below.": "Viesti on lähetetty osoitteeseen %(emailAddress)s. Klikkaa alla sen jälkeen kun olet seurannut viestin sisältämää linkkiä.", + "Please note you are logging into the %(hs)s server, not matrix.org.": "Huomaa että olet kirjautumassa palvelimelle %(hs)s, etkä palvelimelle matrix.org.", + "Sign in to get started": "Kirjaudu aloittaksesi", + "Upload an avatar:": "Lataa avatar:", + "Deops user with given id": "Poistaa annetun tunnisteen omaavalta käyttäjältä ylläpito-oikeudet", + "Ignores a user, hiding their messages from you": "Jättää käyttäjän huomioimatta jolloin heidän viestejä ei näytetä sinulle", + "Stops ignoring a user, showing their messages going forward": "Lopettaa käyttäjän huomiotta jättämisen jolloin heidän tulevat viestit näytetään sinulle", + "Notify the whole room": "Hälytä koko huone", + "Room Notification": "Huonehälytys" } From 99bb64915fef1c4f4315463a0a59867c8317fbd2 Mon Sep 17 00:00:00 2001 From: Walter Date: Thu, 16 Nov 2017 15:55:40 +0000 Subject: [PATCH 037/927] Translated using Weblate (Russian) Currently translated at 98.8% (921 of 932 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index e9eba019c8..9a29dd9603 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -1004,5 +1004,6 @@ "%(severalUsers)srejected their invitations %(count)s times|other": "%(severalUsers)s отклонили приглашения %(count)s раз", "%(severalUsers)srejected their invitations %(count)s times|one": "%(severalUsers)s отклонили приглашения", "URL previews are enabled by default for participants in this room.": "Предварительный просмотр URL-адресов для участников этой комнаты по умолчанию.", - "URL previews are disabled by default for participants in this room.": "Предварительный просмотр URL-адресов для участников этой комнаты по умолчанию." + "URL previews are disabled by default for participants in this room.": "Предварительный просмотр URL-адресов для участников этой комнаты по умолчанию.", + "%(oneUser)srejected their invitation %(count)s times|other": "%(oneUser)sотклонил приглашения %(count)s раз" } From 4de4b5206bf340d0383e7d2ebb075ade9b0826d4 Mon Sep 17 00:00:00 2001 From: Stefan Parviainen Date: Fri, 17 Nov 2017 07:51:33 +0000 Subject: [PATCH 038/927] Translated using Weblate (Finnish) Currently translated at 89.0% (830 of 932 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fi/ --- src/i18n/strings/fi.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/i18n/strings/fi.json b/src/i18n/strings/fi.json index b6e16a901e..4752d68999 100644 --- a/src/i18n/strings/fi.json +++ b/src/i18n/strings/fi.json @@ -714,9 +714,9 @@ "%(senderName)s made future room history visible to all room members.": "%(senderName)s teki tulevan huonehistorian näkyväksi kaikille huoneen jäsenille.", "%(senderName)s made future room history visible to anyone.": "%(senderName)s teki tulevan huonehistorian näkyväksi kaikille.", "%(senderName)s made future room history visible to unknown (%(visibility)s).": "%(senderName)s teki tulevan huonehistorian näkyväksi tuntemattomalle (%(visibility)s).", - "%(senderName)s changed the pinned messages for the room.": "%(senderName) muutti tämän huoneen kiinnitetyt viestit.", - "%(names)s and %(count)s others are typing|other": "%(name)s ja %(count)s muuta kirjoittavat", - "%(names)s and %(count)s others are typing|one": "%(name)s ja yksi muu kirjoittvat", + "%(senderName)s changed the pinned messages for the room.": "%(senderName)s muutti tämän huoneen kiinnitetyt viestit.", + "%(names)s and %(count)s others are typing|other": "%(names)s ja %(count)s muuta kirjoittavat", + "%(names)s and %(count)s others are typing|one": "%(names)s ja yksi muu kirjoittvat", "Message Pinning": "Kiinnitetyt viestit", "Disable Emoji suggestions while typing": "Ota pois käytöstä emojiehdotukset kirjoittaessa", "Hide avatar changes": "Piilota avatarmuutokset", @@ -754,7 +754,7 @@ "World readable": "Täysin julkinen", "Guests can join": "Vierailijat voivat liittyä", "No rooms to show": "Ei huoneita", - "Failed to set avatar.": "Avatarin asettaminen epäonnistui", + "Failed to set avatar.": "Avatarin asettaminen epäonnistui.", "Upload avatar": "Lataa avatar", "Remove avatar": "Poista avatar", "Drop here to favourite": "Pudota tähän lisätäksesi suosikkeihin", @@ -784,7 +784,7 @@ "This room has no related communities": "Tähän huoneseen ei liity yhtään yhteisöä", "New community ID (e.g. +foo:%(localDomain)s)": "Uusi yhteisötunniste (esim. +foo:%(localDomain)s)", "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s muutti huoneen %(roomName)s avatarin", - "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName) poisti huoneen avatarin.", + "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s poisti huoneen avatarin.", "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s muutti huoneen avatariksi ", "You are about to be taken to a third-party site so you can authenticate your account for use with %(integrationsUrl)s. Do you wish to continue?": "Sinut ohjataan kolmannen osapuolen sivustolle jotta voit autentikoida tilisi käyttääksesi %(integrationsUrl)s. Haluatko jatkaa?", "Message removed by %(userId)s": "Käyttäjän %(userId)s poistama viesti", @@ -877,7 +877,7 @@ "Dark theme": "Tumma ulkoasu", "Status.im theme": "Status.im ulkoasu", "Autocomplete Delay (ms):": "Automaattitäydennyksen viive (ms):", - "Ignored Users": "Huomiotta jätetyt käyttäjät:", + "Ignored Users": "Huomiotta jätetyt käyttäjät", "An email has been sent to %(emailAddress)s. Once you've followed the link it contains, click below.": "Viesti on lähetetty osoitteeseen %(emailAddress)s. Klikkaa alla sen jälkeen kun olet seurannut viestin sisältämää linkkiä.", "Please note you are logging into the %(hs)s server, not matrix.org.": "Huomaa että olet kirjautumassa palvelimelle %(hs)s, etkä palvelimelle matrix.org.", "Sign in to get started": "Kirjaudu aloittaksesi", From ee5d43385cdae68e611c4513dc1c77f43f2e446a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Thu, 16 Nov 2017 16:03:01 +0000 Subject: [PATCH 039/927] Translated using Weblate (French) Currently translated at 100.0% (932 of 932 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index cc6f500820..52a663f501 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -1009,5 +1009,9 @@ "Hide display name changes": "Masquer les changements de nom affiché", "Enable inline URL previews by default": "Activer l'aperçu des URL par défaut", "Enable URL previews for this room (only affects you)": "Activer l'aperçu des URL pour ce salon (n'affecte que vous)", - "Enable URL previews by default for participants in this room": "Activer l'aperçu des URL par défaut pour les participants de ce salon" + "Enable URL previews by default for participants in this room": "Activer l'aperçu des URL par défaut pour les participants de ce salon", + "URL previews are enabled by default for participants in this room.": "Les aperçus d'URL sont activés par défaut pour les participants de ce salon.", + "URL previews are disabled by default for participants in this room.": "Les aperçus d'URL sont désactivés par défaut pour les participants de ce salon.", + "Resend all or cancel all now. You can also select individual messages to resend or cancel.": "Tout renvoyer ou tout annuler maintenant. Vous pouvez également sélectionner des messages individuels à renvoyer ou annuler.", + "There's no one else here! Would you like to invite others or stop warning about the empty room?": "Il n'y a personne d'autre ici ! Souhaitez-vous inviter d'autres personnes ou ne plus être notifié à propos du salon vide ?" } From c60c4c3463509fcd570a124001416d8757ca3cfa Mon Sep 17 00:00:00 2001 From: Bamstam Date: Thu, 16 Nov 2017 22:29:42 +0000 Subject: [PATCH 040/927] Translated using Weblate (German) Currently translated at 99.6% (929 of 932 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index d4979767ba..7715397b0a 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -265,7 +265,7 @@ "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s hat die Einladung für %(displayName)s akzeptiert.", "%(names)s and one other are typing": "%(names)s und ein weiteres Raum-Mitglied schreiben", "%(senderName)s answered the call.": "%(senderName)s hat den Anruf angenommen.", - "%(senderName)s banned %(targetName)s.": "%(senderName)s hat %(targetName)s dauerhaft aus dem Raum verbannt.", + "%(senderName)s banned %(targetName)s.": "%(senderName)s hat %(targetName)s verbannt.", "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s hat den Anzeigenamen von %(oldDisplayName)s auf %(displayName)s geändert.", "%(senderName)s changed their profile picture.": "%(senderName)s hat das Profilbild geändert.", "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s hat das Berechtigungslevel von %(powerLevelDiffText)s geändert.", @@ -279,7 +279,7 @@ "%(senderName)s invited %(targetName)s.": "%(senderName)s hat %(targetName)s eingeladen.", "%(displayName)s is typing": "%(displayName)s schreibt", "%(targetName)s joined the room.": "%(targetName)s hat den Raum betreten.", - "%(senderName)s kicked %(targetName)s.": "%(senderName)s hat %(targetName)s aus dem Raum gekickt.", + "%(senderName)s kicked %(targetName)s.": "%(senderName)s hat %(targetName)s gekickt.", "%(targetName)s left the room.": "%(targetName)s hat den Raum verlassen.", "%(senderName)s made future room history visible to all room members, from the point they are invited.": "%(senderName)s hat den zukünftigen Chatverlauf sichtbar gemacht für alle Raum-Mitglieder (ab dem Zeitpunkt, an dem sie eingeladen wurden).", "%(senderName)s made future room history visible to all room members, from the point they joined.": "%(senderName)s hat den zukünftigen Chatverlauf sichtbar gemacht für alle Raum-Mitglieder (ab dem Zeitpunkt, an dem sie beigetreten sind).", @@ -486,7 +486,7 @@ "Invalid file%(extra)s": "Ungültige Datei%(extra)s", "Remove %(threePid)s?": "%(threePid)s entfernen?", "Please select the destination room for this message": "Bitte den Raum auswählen, an den diese Nachricht gesendet werden soll", - "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s hat den Raum-Namen gelöscht.", + "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s hat den Raum-Namen entfernt.", "Passphrases must match": "Passphrases müssen übereinstimmen", "Passphrase must not be empty": "Passphrase darf nicht leer sein", "Export room keys": "Raum-Schlüssel exportieren", @@ -751,7 +751,7 @@ "Unable to create widget.": "Widget kann nicht erstellt werden.", "Unbans user with given id": "Verbannung aufheben für Benutzer mit angegebener ID", "You are not in this room.": "Du bist nicht in diesem Raum.", - "You do not have permission to do that in this room.": "Du hast keine Berechtigung, dies in diesem Raum zu tun.", + "You do not have permission to do that in this room.": "Du hast dafür keine Berechtigung in diesem Raum.", "Verifies a user, device, and pubkey tuple": "Verifiziert ein Tupel aus Benutzer, Gerät und öffentlichem Schlüssel", "Autocomplete Delay (ms):": "Verzögerung bei Autovervollständigung (ms):", "Loading device info...": "Lädt Geräte-Info...", @@ -793,7 +793,7 @@ "You have entered an invalid address.": "Du hast eine ungültige Adresse eingegeben.", "Matrix ID": "Matrix-ID", "Advanced options": "Erweiterte Optionen", - "Block users on other matrix homeservers from joining this room": "Benutzer anderer Matrix-Heimserver das Betreten dieses Raumes verbieten", + "Block users on other matrix homeservers from joining this room": "Benutzern auf anderen Matrix-Heimservern das Betreten dieses Raumes verbieten", "This setting cannot be changed later!": "Diese Einstellung kann nachträglich nicht mehr geändert werden!", "Unignore": "Ignorieren aufheben", "User Options": "Benutzer-Optionen", @@ -989,7 +989,7 @@ "was unbanned %(count)s times|one": "wurde entbannt", "%(oneUser)schanged their name %(count)s times|one": "%(oneUser)shat den Namen geändert", "%(items)s and %(count)s others|other": "%(items)s und %(count)s andere", - "%(items)s and %(count)s others|one": "%(items)s und ein anderer", + "%(items)s and %(count)s others|one": "%(items)s und noch jemand", "An email has been sent to %(emailAddress)s. Once you've followed the link it contains, click below.": "Eine E-Mail wurde an %(emailAddress)s gesendet. Folge dem in der E-Mail enthaltenen Link und klicke dann unten.", "The visibility of '%(roomName)s' in %(groupId)s could not be updated.": "Die Sichtbarkeit von '%(roomName)s' in %(groupId)s konnte nicht aktualisiert werden.", "Visibility in Room List": "Sichtbarkeit in Raum-Liste", @@ -1012,5 +1012,7 @@ "Please note you are logging into the %(hs)s server, not matrix.org.": "Hinweis: Du meldest dich auf dem %(hs)s-Server an, nicht auf matrix.org.", "Resend all or cancel all now. You can also select individual messages to resend or cancel.": "Alle erneut senden oder alle verwerfen. Du kannst auch einzelne Nachrichten erneut senden oder verwerfen.", "There's no one else here! Would you like to invite others or stop warning about the empty room?": "Sonst ist hier aktuell niemand. Möchtest du Benutzer einladen oder die Warnmeldung bezüglich des leeren Raums deaktivieren?", - "Sign in to get started": "Melde dich an, um loszulegen" + "Sign in to get started": "Melde dich an, um loszulegen", + "URL previews are disabled by default for participants in this room.": "URL-Vorschau ist für Mitglieder dieses Raumes standardmäßig deaktiviert.", + "URL previews are enabled by default for participants in this room.": "URL-Vorschau ist für Mitglieder dieses Raumes standardmäßig aktiviert." } From 979d1194dbc8350006f36233882c5b3850a94769 Mon Sep 17 00:00:00 2001 From: Brenno Martins Date: Thu, 16 Nov 2017 20:21:56 +0000 Subject: [PATCH 041/927] Translated using Weblate (Portuguese (Brazil)) Currently translated at 71.3% (665 of 932 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/pt_BR/ --- src/i18n/strings/pt_BR.json | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/pt_BR.json b/src/i18n/strings/pt_BR.json index fee6bcba31..3e04f9d06a 100644 --- a/src/i18n/strings/pt_BR.json +++ b/src/i18n/strings/pt_BR.json @@ -299,7 +299,7 @@ "Use with caution": "Use com cautela", "VoIP is unsupported": "Chamada de voz não permitida", "%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s desfez o convite a %(targetName)s.", - "You are already in a call.": "Você já está em uma chamada.", + "You are already in a call.": "Você já está em uma chamada.", "You're not in any rooms yet! Press to make a room or to browse the directory": "Você ainda não está em nenhuma sala! Clique em para criar uma sala ou em para navegar pela lista pública de salas", "You are trying to access %(roomName)s.": "Você está tentando acessar a sala %(roomName)s.", "You cannot place a call with yourself.": "Você não pode iniciar uma chamada.", @@ -729,5 +729,18 @@ "Ignore request": "Ignorar o pedido", "You added a new device '%(displayName)s', which is requesting encryption keys.": "Você adicionou um novo dispositivo '%(displayName)s', que está solicitando chaves de criptografia.", "Your unverified device '%(displayName)s' is requesting encryption keys.": "Seu dispositivo não verificado '%(displayName)s' está solicitando chaves de criptografia.", - "Encryption key request": "Solicitação de chave de criptografia" + "Encryption key request": "Solicitação de chave de criptografia", + "Invite to Community": "Convidar à comunidade", + "Restricted": "Restrito", + "Name or matrix ID": "Nome ou ID matrix", + "Add to community": "Adicionar à comunidade", + "Add rooms to the community": "Adicionar salas à comunidade", + "Failed to invite users to community": "Falha ao convidar os usuários à comunidade", + "Failed to invite users to %(groupId)s": "Falha ao convidar os usuários para %(groupId)s", + "Failed to invite the following users to %(groupId)s:": "Falha ao convidar os seguintes usuários para %(groupId)s:", + "Failed to add the following rooms to %(groupId)s:": "Falha ao adicionar as seguintes salas para %(groupId)s:", + "You are not in this room.": "Você não está nesta sala.", + "You do not have permission to do that in this room.": "Você não tem permissão para fazer isto nesta sala.", + "Ignored user": "Usuário ignorado", + "You are no longer ignoring %(userId)s": "Você parou de ignorar %(userId)s" } From 1c8b3061513b8eda4afd2afaaad52c3e7ffc5ef2 Mon Sep 17 00:00:00 2001 From: Andrey Date: Fri, 17 Nov 2017 09:03:26 +0000 Subject: [PATCH 042/927] Translated using Weblate (Russian) Currently translated at 98.8% (921 of 932 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 9a29dd9603..f0321e3364 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -561,7 +561,7 @@ "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Вы действительно хотите удалить это событие? Обратите внимание, что если это смена названия комнаты или темы, то удаление отменит это изменение.", "Unknown error": "Неизвестная ошибка", "Incorrect password": "Неверный пароль", - "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Таким образом, ваша учетная запись будет заблокирована навсегда. Вы не сможете зарегистрироваться снова с тем же идентификатором пользователя.", + "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Ваша учетная запись будет заблокирована навсегда. Вы не сможете повторно зарегистрировать тот же идентификатор пользователя.", "This action is irreversible.": "Это действие необратимо.", "To continue, please enter your password.": "Для продолжения введите ваш пароль.", "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Чтобы удостовериться, что этому устройству можно доверять, пожалуйста, свяжитесь с владельцем другим способом (например, лично или по телефону) и спросите его, совпадает ли ключ, указанный у него в настройках для этого устройства, с ключом ниже:", From ca5ffb202987c41ff195d64e57efe396496840d5 Mon Sep 17 00:00:00 2001 From: Walter Date: Fri, 17 Nov 2017 19:43:58 +0000 Subject: [PATCH 043/927] Translated using Weblate (Russian) Currently translated at 99.4% (927 of 932 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index f0321e3364..6221ac7bdb 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -1005,5 +1005,11 @@ "%(severalUsers)srejected their invitations %(count)s times|one": "%(severalUsers)s отклонили приглашения", "URL previews are enabled by default for participants in this room.": "Предварительный просмотр URL-адресов для участников этой комнаты по умолчанию.", "URL previews are disabled by default for participants in this room.": "Предварительный просмотр URL-адресов для участников этой комнаты по умолчанию.", - "%(oneUser)srejected their invitation %(count)s times|other": "%(oneUser)sотклонил приглашения %(count)s раз" + "%(oneUser)srejected their invitation %(count)s times|other": "%(oneUser)sотклонил их приглашение %(count)s раз", + "%(oneUser)srejected their invitation %(count)s times|one": "%(oneUser)s отклонил приглашение", + "%(severalUsers)shad their invitations withdrawn %(count)s times|other": "%(severalUsers)s снова отозвали приглашение %(count)s раз", + "%(severalUsers)shad their invitations withdrawn %(count)s times|one": "%(severalUsers)s снова отозвали приглашение", + "%(oneUser)shad their invitation withdrawn %(count)s times|other": "%(oneUser)s снова отозвал приглашение %(count)s раз", + "%(oneUser)shad their invitation withdrawn %(count)s times|one": "%(oneUser)s снова отозвал приглашение", + "Please note you are logging into the %(hs)s server, not matrix.org.": "Пожалуйста обратите внимание, что вы регистрируете на %(hs)s-сервере а не на matrix.org." } From f033ada5a35196182a89783b928a99b6b20d8a52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Sat, 18 Nov 2017 11:57:42 +0000 Subject: [PATCH 044/927] Translated using Weblate (Slovak) Currently translated at 100.0% (932 of 932 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sk/ --- src/i18n/strings/sk.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/sk.json b/src/i18n/strings/sk.json index 4ae115a4de..2be5c49474 100644 --- a/src/i18n/strings/sk.json +++ b/src/i18n/strings/sk.json @@ -938,5 +938,9 @@ "Enable inline URL previews by default": "Predvolene povoliť náhľady URL adries", "Enable URL previews for this room (only affects you)": "Povoliť náhľady URL adries pre túto miestnosť (ovplyvňuje len vás)", "Enable URL previews by default for participants in this room": "Predvolene povoliť náhľady URL adries pre členov tejto miestnosti", - "Custom of %(powerLevel)s": "Vlastná úroveň %(powerLevel)s" + "Custom of %(powerLevel)s": "Vlastná úroveň %(powerLevel)s", + "URL previews are enabled by default for participants in this room.": "Náhľady URL adries sú predvolene povolené pre členov tejto miestnosti.", + "URL previews are disabled by default for participants in this room.": "Náhľady URL adries sú predvolene zakázané pre členov tejto miestnosti.", + "Resend all or cancel all now. You can also select individual messages to resend or cancel.": "Znovu odoslať všetky alebo Zrušiť všetky teraz. Môžete tiež znovu poslať alebo zrušiť odosielanie jednotlivých správ zvlášť.", + "There's no one else here! Would you like to invite others or stop warning about the empty room?": "Okrem vás v tejto miestnosti nie je nik iný! Želáte si Pozvať ďalších alebo Prestať upozorňovať na prázdnu miestnosť?" } From 07be7b6032fa9e7593ee404691494068b43081f4 Mon Sep 17 00:00:00 2001 From: grrgui Date: Fri, 17 Nov 2017 22:24:11 +0000 Subject: [PATCH 045/927] Translated using Weblate (French) Currently translated at 100.0% (932 of 932 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index 52a663f501..615c802e5b 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -274,7 +274,7 @@ "Send a message (unencrypted)": "Envoyer un message (non chiffré)", "Send an encrypted message": "Envoyer un message chiffré", "Sender device information": "Informations de l'appareil de l'expéditeur", - "Send Invites": "Envoyer les invitations", + "Send Invites": "Envoyer des invitations", "Send Reset Email": "Envoyer l'e-mail de réinitialisation", "sent an image": "a envoyé une image", "%(senderDisplayName)s sent an image.": "%(senderDisplayName)s a envoyé une image.", @@ -746,7 +746,7 @@ "Sets the room topic": "Défini le sujet du salon", "Show Apps": "Afficher les applications", "To get started, please pick a username!": "Pour commencer, choisissez un nom d'utilisateur !", - "Unable to create widget.": "Impossible de créer le widget.", + "Unable to create widget.": "Impossible de créer un widget.", "Unbans user with given id": "Révoque le bannissement de l'utilisateur à partir de son identifiant", "You are not in this room.": "Vous n'êtes pas dans ce salon.", "You do not have permission to do that in this room.": "Vous n'avez pas la permission d'effectuer cette action dans ce salon.", From 4f05ffcc52acfb8f38c91d4d9df1ff4d81a6a948 Mon Sep 17 00:00:00 2001 From: Andrey Date: Sat, 18 Nov 2017 09:12:20 +0000 Subject: [PATCH 046/927] Translated using Weblate (Russian) Currently translated at 99.4% (927 of 932 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 6221ac7bdb..4a5741545e 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -1006,10 +1006,10 @@ "URL previews are enabled by default for participants in this room.": "Предварительный просмотр URL-адресов для участников этой комнаты по умолчанию.", "URL previews are disabled by default for participants in this room.": "Предварительный просмотр URL-адресов для участников этой комнаты по умолчанию.", "%(oneUser)srejected their invitation %(count)s times|other": "%(oneUser)sотклонил их приглашение %(count)s раз", - "%(oneUser)srejected their invitation %(count)s times|one": "%(oneUser)s отклонил приглашение", - "%(severalUsers)shad their invitations withdrawn %(count)s times|other": "%(severalUsers)s снова отозвали приглашение %(count)s раз", - "%(severalUsers)shad their invitations withdrawn %(count)s times|one": "%(severalUsers)s снова отозвали приглашение", - "%(oneUser)shad their invitation withdrawn %(count)s times|other": "%(oneUser)s снова отозвал приглашение %(count)s раз", - "%(oneUser)shad their invitation withdrawn %(count)s times|one": "%(oneUser)s снова отозвал приглашение", - "Please note you are logging into the %(hs)s server, not matrix.org.": "Пожалуйста обратите внимание, что вы регистрируете на %(hs)s-сервере а не на matrix.org." + "%(oneUser)srejected their invitation %(count)s times|one": "%(oneUser)sотклонил приглашение", + "%(severalUsers)shad their invitations withdrawn %(count)s times|other": "%(severalUsers)sотозвали приглашения %(count)s раз", + "%(severalUsers)shad their invitations withdrawn %(count)s times|one": "%(severalUsers)sотозвали приглашения", + "%(oneUser)shad their invitation withdrawn %(count)s times|other": "%(oneUser)sотклонил приглашение %(count)s раз", + "%(oneUser)shad their invitation withdrawn %(count)s times|one": "%(oneUser)sотозвал приглашение", + "Please note you are logging into the %(hs)s server, not matrix.org.": "Обратите внимание, что вы заходите на сервер %(hs)s, а не на matrix.org." } From f0752572a76da82f73a1cfc6e31babbcc11c8011 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sun, 19 Nov 2017 12:49:26 +0000 Subject: [PATCH 047/927] make RoomDetailRow reusable for the Room Directory Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/RoomDetailList.js | 109 +++-------------- src/components/views/rooms/RoomDetailRow.js | 119 +++++++++++++++++++ 2 files changed, 133 insertions(+), 95 deletions(-) create mode 100644 src/components/views/rooms/RoomDetailRow.js diff --git a/src/components/views/rooms/RoomDetailList.js b/src/components/views/rooms/RoomDetailList.js index 27972af484..11fad41b39 100644 --- a/src/components/views/rooms/RoomDetailList.js +++ b/src/components/views/rooms/RoomDetailList.js @@ -18,121 +18,40 @@ import sdk from '../../../index'; import dis from '../../../dispatcher'; import React from 'react'; import { _t } from '../../../languageHandler'; -import linkifyString from 'linkifyjs/string'; -import sanitizeHtml from 'sanitize-html'; -import { ContentRepo } from 'matrix-js-sdk'; -import MatrixClientPeg from '../../../MatrixClientPeg'; import PropTypes from 'prop-types'; import classNames from 'classnames'; -function getDisplayAliasForRoom(room) { - return room.canonicalAlias || (room.aliases ? room.aliases[0] : ""); -} - -const RoomDetailRow = React.createClass({ - propTypes: { - room: PropTypes.shape({ - name: PropTypes.string, - topic: PropTypes.string, - roomId: PropTypes.string, - avatarUrl: PropTypes.string, - numJoinedMembers: PropTypes.number, - canonicalAlias: PropTypes.string, - aliases: PropTypes.arrayOf(PropTypes.string), - - worldReadable: PropTypes.bool, - guestCanJoin: PropTypes.bool, - }), - }, - - onClick: function(ev) { - ev.preventDefault(); - dis.dispatch({ - action: 'view_room', - room_id: this.props.room.roomId, - room_alias: this.props.room.canonicalAlias || (this.props.room.aliases || [])[0], - }); - }, - - onTopicClick: function(ev) { - // When clicking a link in the topic, prevent the event being propagated - // to `onClick`. - ev.stopPropagation(); - }, - - render: function() { - const BaseAvatar = sdk.getComponent('avatars.BaseAvatar'); - - const room = this.props.room; - const name = room.name || getDisplayAliasForRoom(room) || _t('Unnamed room'); - const topic = linkifyString(sanitizeHtml(room.topic || '')); - - const guestRead = room.worldReadable ? ( -
{ _t('World readable') }
- ) :
; - const guestJoin = room.guestCanJoin ? ( -
{ _t('Guests can join') }
- ) :
; - - const perms = (guestRead || guestJoin) ? (
- { guestRead } - { guestJoin } -
) :
; - - return - - - - -
{ name }
  - { perms } -
-
{ getDisplayAliasForRoom(room) }
- - - { room.numJoinedMembers } - - ; - }, -}); +import {roomShape} from './RoomDetailRow'; export default React.createClass({ displayName: 'RoomDetailList', propTypes: { - rooms: PropTypes.arrayOf(PropTypes.shape({ - name: PropTypes.string, - topic: PropTypes.string, - roomId: PropTypes.string, - avatarUrl: PropTypes.string, - numJoinedMembers: PropTypes.number, - canonicalAlias: PropTypes.string, - aliases: PropTypes.arrayOf(PropTypes.string), - - worldReadable: PropTypes.bool, - guestCanJoin: PropTypes.bool, - })), - + rooms: PropTypes.arrayOf(roomShape), className: PropTypes.string, }, getRows: function() { if (!this.props.rooms) return []; + + const RoomDetailRow = sdk.getComponent('rooms.RoomDetailRow'); return this.props.rooms.map((room, index) => { - return ; + return ; + }); + }, + + onDetailsClick: function(ev, room) { + dis.dispatch({ + action: 'view_room', + room_id: room.roomId, + room_alias: room.canonicalAlias || (room.aliases || [])[0], }); }, render() { const rows = this.getRows(); let rooms; - if (rows.length == 0) { + if (rows.length === 0) { rooms = { _t('No rooms to show') }; } else { rooms = diff --git a/src/components/views/rooms/RoomDetailRow.js b/src/components/views/rooms/RoomDetailRow.js new file mode 100644 index 0000000000..fbb9db4505 --- /dev/null +++ b/src/components/views/rooms/RoomDetailRow.js @@ -0,0 +1,119 @@ +/* +Copyright 2017 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. +*/ + +import sdk from '../../../index'; +import dis from '../../../dispatcher'; +import React from 'react'; +import { _t } from '../../../languageHandler'; +import linkifyElement from 'linkifyjs/element'; +import linkifyMatrix from '../../../linkify-matrix'; +import { ContentRepo } from 'matrix-js-sdk'; +import MatrixClientPeg from '../../../MatrixClientPeg'; +import PropTypes from 'prop-types'; +import classNames from 'classnames'; + +function getDisplayAliasForRoom(room) { + return room.canonicalAlias || (room.aliases ? room.aliases[0] : ""); +} + +export const roomShape = PropTypes.shape({ + name: PropTypes.string, + topic: PropTypes.string, + roomId: PropTypes.string, + avatarUrl: PropTypes.string, + numJoinedMembers: PropTypes.number, + canonicalAlias: PropTypes.string, + aliases: PropTypes.arrayOf(PropTypes.string), + + worldReadable: PropTypes.bool, + guestCanJoin: PropTypes.bool, +}); + +export default React.createClass({ + propTypes: { + room: roomShape, + // passes ev, room as args + onClick: PropTypes.func, + onMouseDown: PropTypes.func, + }, + + _linkifyTopic: function() { + if (this.refs.topic) { + linkifyElement(this.refs.topic, linkifyMatrix.options); + } + }, + + componentDidMount: function() { + this._linkifyTopic(); + }, + + componentDidUpdate: function() { + this._linkifyTopic(); + }, + + onClick: function(ev) { + ev.preventDefault(); + if (this.props.onClick) { + this.props.onClick(ev, this.props.room); + } + }, + + onTopicClick: function(ev) { + // When clicking a link in the topic, prevent the event being propagated + // to `onClick`. + ev.stopPropagation(); + }, + + render: function() { + const BaseAvatar = sdk.getComponent('avatars.BaseAvatar'); + + const room = this.props.room; + const name = room.name || getDisplayAliasForRoom(room) || _t('Unnamed room'); + + const guestRead = room.worldReadable ? ( +
{ _t('World readable') }
+ ) :
; + const guestJoin = room.guestCanJoin ? ( +
{ _t('Guests can join') }
+ ) :
; + + const perms = (guestRead || guestJoin) ? (
+ { guestRead }  + { guestJoin } +
) :
; + + return
+ + + + ; + }, +}); From ff3cef7c7dfe3cda7996bc481021d0cbfe682ed5 Mon Sep 17 00:00:00 2001 From: dark159123 Date: Sat, 18 Nov 2017 21:30:49 +0000 Subject: [PATCH 048/927] Translated using Weblate (Danish) Currently translated at 26.6% (248 of 932 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/da/ --- src/i18n/strings/da.json | 164 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 157 insertions(+), 7 deletions(-) diff --git a/src/i18n/strings/da.json b/src/i18n/strings/da.json index 9f5d3468ca..8727eadfc6 100644 --- a/src/i18n/strings/da.json +++ b/src/i18n/strings/da.json @@ -65,7 +65,7 @@ "Clear Cache": "Ryd cache", "Click here to fix": "Klik her for at rette", "Confirm your new password": "Bekræft din nye adgangskode", - "Continue": "fortsætte", + "Continue": "Fortsæt", "Could not connect to the integration server": "Kunne ikke oprette forbindelse til integrationsserveren", "Create an account": "Opret en brugerkonto", "Create Room": "Opret rum", @@ -76,7 +76,7 @@ "Devices will not yet be able to decrypt history from before they joined the room": "Enhederne vil ikke være i stand til at dekryptere historikken fra, før de kom til rummet", "Disable inline URL previews by default": "Deaktiver forrige weblinks forhåndsvisninger som standard", "Display name": "Visningsnavn", - "Email, name or matrix ID": "E-mail, navn eller matrix-id", + "Email, name or matrix ID": "E-mail, navn eller matrix-ID", "Encrypted messages will not be visible on clients that do not yet implement encryption": "Krypterede meddelelser vil ikke være synlige på klienter, der endnu ikke implementerer kryptering", "Encrypted room": "Krypteret rummet", "Encryption is enabled in this room": "Kryptering er aktiveret i dette rum", @@ -84,21 +84,171 @@ "End-to-end encryption is in beta and may not be reliable": "End-to-end kryptering er i beta og kan ikke være pålidelig", "Error": "Fejl", "Export E2E room keys": "Eksporter E2E rum nøgler", - "Failed to change password. Is your password correct?": "Kunne ikke ændre adgangskode. Er din adgangskode korrekt?", + "Failed to change password. Is your password correct?": "Kunne ikke ændre password. Er dit password korrekt?", "Failed to leave room": "Kunne ikke forlade rum", "Failed to reject invitation": "Kunne ikke afvise invitationen", "Failed to send email": "Kunne ikke sende e-mail", "Failed to set avatar.": "Kunne ikke angive avatar.", "Failed to unban": "Var ikke i stand til at ophæve forbuddet", "Favourite": "Favorit", - "Notifications": "Meddelser", - "Remove": "Fjerne", + "Notifications": "Notifikationer", + "Remove": "Fjern", "Settings": "Indstillinger", "unknown error code": "Ukendt fejlkode", "%(targetName)s accepted an invitation.": "%(targetName)s accepterede en invitation.", - "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s accepteret invitationen til %(displayName)s.", + "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s accepterede invitationen til %(displayName)s.", "%(names)s and %(lastPerson)s are typing": "%(names)s og %(lastPerson)s er ved at skrive", "%(names)s and one other are typing": "%(names)s og den anden skriver", "%(senderName)s answered the call.": "%(senderName)s besvarede opkaldet.", - "Add a widget": "Tilføj en widget" + "Add a widget": "Tilføj en widget", + "OK": "OK", + "Search": "Søg", + "Custom Server Options": "Brugerdefinerede serverindstillinger", + "Dismiss": "Afskedige", + "powered by Matrix": "Drevet af Matrix", + "Close": "Luk", + "Cancel": "Afbryd", + "Edit": "Rediger", + "Unpin Message": "Fasthold ikke længere Besked", + "Failed to forget room %(errCode)s": "Kunne ikke glemme rummet %(errCode)s", + "Mute": "Sæt på lydløs", + "Leave": "Forlad", + "Register": "Registrér", + "Add rooms to this community": "Tilføj rum til dette fællesskab", + "Unnamed room": "Unavngivet rum", + "World readable": "Læselig af alle", + "Guests can join": "Gæster kan deltage", + "No rooms to show": "Ingen rum at vise", + "This email address is already in use": "Denne emailadresse er allerede i brug", + "This phone number is already in use": "Dette telefonnummer er allerede i brug", + "Failed to verify email address: make sure you clicked the link in the email": "Kunne ikke bekræfte emailaddressen: vær sikker på at du klikke på linket i emailen", + "Call Timeout": "Opkalds Timeout", + "The remote side failed to pick up": "Den anden side tog den ikke", + "Unable to capture screen": "Kunne ikke optage skærm", + "Existing Call": "Eksisterende Opkald", + "You are already in a call.": "Du er allerede i et opkald.", + "VoIP is unsupported": "VoIP er ikke understøttet", + "You cannot place VoIP calls in this browser.": "Du kan ikke lave VoIP-opkald i denne browser.", + "You cannot place a call with yourself.": "Du kan ikke ringe til dig selv.", + "Conference calls are not supported in this client": "Konferenceopkald er ikke undersøttede i denne klient", + "Conference calls are not supported in encrypted rooms": "Konferenceopkald er ikke understøttede i krypterede rum", + "Conference calling is in development and may not be reliable.": "Konferenceopkald er under udvikling og kan være utilregnelige.", + "Failed to set up conference call": "Kunne ikke starte konferenceopkald", + "Conference call failed.": "Konferenceopkald fejlede.", + "The file '%(fileName)s' failed to upload": "Filen '%(fileName)s' kunne ikke uploades", + "The file '%(fileName)s' exceeds this home server's size limit for uploads": "Filen '%(fileName)s' overskrider denne home servers størrelsesbegrænsning på uploads", + "Upload Failed": "Upload Fejlede", + "Sun": "Søn", + "Mon": "Man", + "Tue": "Tirs", + "Wed": "Ons", + "Thu": "Tors", + "Fri": "Fre", + "Sat": "Lør", + "Jan": "Jan", + "Feb": "Feb", + "Mar": "Mar", + "Apr": "Apr", + "May": "Maj", + "Jun": "Jun", + "Jul": "Jul", + "Aug": "Aug", + "Sep": "Sep", + "Oct": "Okt", + "Nov": "Nov", + "Dec": "Dec", + "PM": "PM", + "AM": "AM", + "%(weekDayName)s %(time)s": "%(weekDayName)s %(time)s", + "%(weekDayName)s, %(monthName)s %(day)s %(time)s": "%(weekDayName)s, %(monthName)s %(day)s %(time)s", + "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s %(time)s": "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s %(time)s", + "Who would you like to add to this community?": "Hvem vil du tilføje til dette fællesskab?", + "Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "Advarsel: alle personer du tilføjer til et fællesskab vil være synlige for alle der kender Fællesskabs ID'et", + "Invite new community members": "Inviter nye fællesskabsmedlemmer", + "Name or matrix ID": "Navn eller matrix ID", + "Invite to Community": "Inviter til Fællesskab", + "Which rooms would you like to add to this community?": "Hvilke rum vil du tilføje til dette fællesskab?", + "Show these rooms to non-members on the community page and room list?": "Vis disse rum til ikke-medlemmer på fællesskabssiden og rumlisten?", + "Add rooms to the community": "Tilføj rum til fællesskabet", + "Room name or alias": "Rum navn eller alias", + "Add to community": "Tilføj til fællesskab", + "Failed to invite the following users to %(groupId)s:": "Kunne ikke invitere de følgende brugere til %(groupId)s:", + "Failed to invite users to community": "Kunne ikke invitere brugere til fællesskab", + "Failed to invite users to %(groupId)s": "Kunne ikke invitere brugere til %(groupId)s", + "Failed to add the following rooms to %(groupId)s:": "Kunne ikke tilføje de følgende rum til %(groupId)s:", + "Riot does not have permission to send you notifications - please check your browser settings": "Riot har ikke tilladelse til at sende dig notifikationer - tjek venligst dine browser indstillinger", + "Riot was not given permission to send notifications - please try again": "Riot fik ikke tilladelse til at sende notifikationer - prøv igen", + "Unable to enable Notifications": "Kunne ikke slå Notifikationer til", + "This email address was not found": "Denne emailadresse blev ikke fundet", + "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Din emailadresse lader ikke til at være tilknyttet en Matrix ID på denne Homeserver.", + "Restricted": "Begrænset", + "Moderator": "Moderator", + "Start a chat": "Start en chat", + "Who would you like to communicate with?": "Hvem vil du kommunikere med?", + "Start Chat": "Start Chat", + "Invite new room members": "Inviter nye rummedlemmer", + "Who would you like to add to this room?": "Hvem vil du tilføje til dette rum?", + "Send Invites": "Send invitationer", + "Failed to invite user": "Kunne ikke invitere bruger", + "Operation failed": "Operation mislykkedes", + "Failed to invite": "Kunne ikke invitere", + "Failed to invite the following users to the %(roomName)s room:": "Kunne ikke invitere de følgende brugere til %(roomName)s rummet:", + "You need to be logged in.": "Du skal være logget ind.", + "You need to be able to invite users to do that.": "Du skal kunne invitere brugere for at gøre dette.", + "Unable to create widget.": "Kunne ikke lave widget.", + "Failed to send request.": "Kunne ikke sende forespørgsel.", + "This room is not recognised.": "Dette rum kan ikke genkendes.", + "Power level must be positive integer.": "Magtniveau skal være positivt heltal.", + "You are not in this room.": "Du er ikke i dette rum.", + "You do not have permission to do that in this room.": "Du har ikke tilladelse til at gøre dét i dette rum.", + "Missing room_id in request": "Mangler room_id i forespørgsel", + "Must be viewing a room": "Du skal være i gang med at se på rummet", + "Room %(roomId)s not visible": "rum %(roomId)s ikke synligt", + "Missing user_id in request": "Manglende user_id i forespørgsel", + "Failed to lookup current room": "Kunne ikke slå nuværende rum op", + "Usage": "Brug", + "/ddg is not a command": "/ddg er ikke en kommando", + "To use it, just wait for autocomplete results to load and tab through them.": "For at bruge det skal du bare vente på autocomplete resultaterne indlæser og tab'e igennem dem.", + "Unrecognised room alias:": "Ugenkendt rum alias:", + "Ignored user": "Ignoreret bruger", + "You are now ignoring %(userId)s": "Du ignorere nu %(userId)s", + "Unignored user": "Holdt op med at ignorere bruger", + "You are no longer ignoring %(userId)s": "Du ignorer ikke længere %(userId)s", + "Unknown (user, device) pair:": "Ukendt (bruger, enhed) par:", + "Device already verified!": "Enhed allerede verificeret!", + "WARNING: Device already verified, but keys do NOT MATCH!": "ADVARSEL: Enhed allerede verificeret, men nøgler PASSER IKKE!", + "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "ADVARSEL: NØGLE VERIFICERING FEJLEDE! Signaturnøglen for %(userId)s and enhed %(deviceId)s er \"%(fprint)s\" hvilket ikke passer med den oplyste nøgle \"%(fingerprint)s\". Dette kan betyde jeres kommunikation bliver opsnappet!", + "Verified key": "Verificeret nøgle", + "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "Signaturnøglen du oplste passer med nøglen fra %(userId)ss enhed %(deviceId)s. Enheden er markeret som verificeret.", + "Unrecognised command:": "Ukendt kommando:", + "Reason": "Årsag", + "%(senderName)s requested a VoIP conference.": "%(senderName)s forespurgte en VoIP konference.", + "%(senderName)s invited %(targetName)s.": "%(senderName)s inviterede %(targetName)s.", + "%(senderName)s banned %(targetName)s.": "%(senderName)s bannede %(targetName)s.", + "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s ændrede deres viste navn fra %(oldDisplayName)s til %(displayName)s.", + "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s satte deres viste navn til %(displayName)s.", + "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s fjernede deres viste navn (%(oldDisplayName)s).", + "%(senderName)s removed their profile picture.": "%(senderName)s fjernede deres profilbillede.", + "%(senderName)s changed their profile picture.": "%(senderName)s ændrede deres profilbillede.", + "%(senderName)s set a profile picture.": "%(senderName)s indstillede deres profilbillede.", + "VoIP conference started.": "VoIP konference startet.", + "%(targetName)s joined the room.": "%(targetName)s forbandt til rummet.", + "VoIP conference finished.": "VoIP konference afsluttet.", + "%(targetName)s rejected the invitation.": "%(targetName)s afviste invitationen.", + "%(targetName)s left the room.": "%(targetName)s forlod rummet.", + "%(senderName)s unbanned %(targetName)s.": "%(senderName)s unbannede %(targetName)s.", + "%(senderName)s kicked %(targetName)s.": "%(senderName)s kickede %(targetName)s.", + "%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s trak %(targetName)ss invitation tilbage.", + "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s ændrede emnet til \"%(topic)s\".", + "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s fjernede rumnavnet.", + "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s ændrede rumnavnet til %(roomName)s.", + "%(senderDisplayName)s sent an image.": "%(senderDisplayName)s sendte et billed.", + "Someone": "Nogen", + "(not supported by this browser)": "(Ikke understøttet af denne browser)", + "(could not connect media)": "(kunne ikke forbinde til mediet)", + "(no answer)": "(intet svar)", + "(unknown failure: %(reason)s)": "(ukendt fejl: %(reason)s)", + "%(senderName)s ended the call.": "%(senderName)s afsluttede opkaldet.", + "%(senderName)s placed a %(callType)s call.": "%(senderName)s startede et %(callType)s opkald.", + "%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s inviterede %(targetDisplayName)s til rummet." } From d943807ad1e9a8e70071a422bcb641ce27a757aa Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sun, 19 Nov 2017 13:18:06 +0000 Subject: [PATCH 049/927] remove unused imports Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/RoomDetailRow.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/components/views/rooms/RoomDetailRow.js b/src/components/views/rooms/RoomDetailRow.js index fbb9db4505..4725bb4a14 100644 --- a/src/components/views/rooms/RoomDetailRow.js +++ b/src/components/views/rooms/RoomDetailRow.js @@ -15,7 +15,6 @@ limitations under the License. */ import sdk from '../../../index'; -import dis from '../../../dispatcher'; import React from 'react'; import { _t } from '../../../languageHandler'; import linkifyElement from 'linkifyjs/element'; @@ -23,9 +22,8 @@ import linkifyMatrix from '../../../linkify-matrix'; import { ContentRepo } from 'matrix-js-sdk'; import MatrixClientPeg from '../../../MatrixClientPeg'; import PropTypes from 'prop-types'; -import classNames from 'classnames'; -function getDisplayAliasForRoom(room) { +export function getDisplayAliasForRoom(room) { return room.canonicalAlias || (room.aliases ? room.aliases[0] : ""); } From 4d177626b5395345f84f56f65b9c74caaf5651a3 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sun, 19 Nov 2017 13:24:18 +0000 Subject: [PATCH 050/927] init Linkify properly to make tests happy Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/RoomDetailRow.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/views/rooms/RoomDetailRow.js b/src/components/views/rooms/RoomDetailRow.js index 4725bb4a14..f7dc9086ec 100644 --- a/src/components/views/rooms/RoomDetailRow.js +++ b/src/components/views/rooms/RoomDetailRow.js @@ -17,12 +17,15 @@ limitations under the License. import sdk from '../../../index'; import React from 'react'; import { _t } from '../../../languageHandler'; +import * as linkify from 'linkifyjs'; import linkifyElement from 'linkifyjs/element'; import linkifyMatrix from '../../../linkify-matrix'; import { ContentRepo } from 'matrix-js-sdk'; import MatrixClientPeg from '../../../MatrixClientPeg'; import PropTypes from 'prop-types'; +linkifyMatrix(linkify); + export function getDisplayAliasForRoom(room) { return room.canonicalAlias || (room.aliases ? room.aliases[0] : ""); } From f61f858cf723cae37a834cff5b7517822d42599b Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sun, 19 Nov 2017 15:33:07 +0000 Subject: [PATCH 051/927] Add Analytics Info and add Piwik to SdkConfig.DEFAULTS Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/Analytics.js | 101 ++++++++++++++++++---- src/SdkConfig.js | 8 ++ src/components/structures/UserSettings.js | 6 ++ src/i18n/strings/en_EN.json | 15 +++- 4 files changed, 113 insertions(+), 17 deletions(-) diff --git a/src/Analytics.js b/src/Analytics.js index 1b4f45bc6b..602728038e 100644 --- a/src/Analytics.js +++ b/src/Analytics.js @@ -14,25 +14,54 @@ limitations under the License. */ -import { getCurrentLanguage } from './languageHandler'; +import { getCurrentLanguage, _t, _td } from './languageHandler'; import PlatformPeg from './PlatformPeg'; -import SdkConfig from './SdkConfig'; +import SdkConfig, { DEFAULTS } from './SdkConfig'; +import Modal from './Modal'; +import sdk from './index'; + +function getRedactedHash() { + return window.location.hash.replace(/#\/(group|room|user)\/(.+)/, "#/$1/"); +} function getRedactedUrl() { - const redactedHash = window.location.hash.replace(/#\/(group|room|user)\/(.+)/, "#/$1/"); // hardcoded url to make piwik happy - return 'https://riot.im/app/' + redactedHash; + return 'https://riot.im/app/' + getRedactedHash(); } const customVariables = { - 'App Platform': 1, - 'App Version': 2, - 'User Type': 3, - 'Chosen Language': 4, - 'Instance': 5, - 'RTE: Uses Richtext Mode': 6, - 'Homeserver URL': 7, - 'Identity Server URL': 8, + 'App Platform': { + id: 1, + expl: _td('The platform you\'re on'), + }, + 'App Version': { + id: 2, + expl: _td('The version of Riot.im'), + }, + 'User Type': { + id: 3, + expl: _td('Whether or not you\'re logged in (we don\'t record your user name)'), + }, + 'Chosen Language': { + id: 4, + expl: _td('Your language of choice'), + }, + 'Instance': { + id: 5, + expl: _td('Which officially provided instance you are using, if any'), + }, + 'RTE: Uses Richtext Mode': { + id: 6, + expl: _td('Whether or not you\'re using the Richtext mode of the Rich Text Editor'), + }, + 'Homeserver URL': { + id: 7, + expl: _td('Your homeserver\'s URL'), + }, + 'Identity Server URL': { + id: 8, + expl: _td('Your identity server\'s URL'), + }, }; function whitelistRedact(whitelist, str) { @@ -40,9 +69,6 @@ function whitelistRedact(whitelist, str) { return ''; } -const whitelistedHSUrls = ["https://matrix.org"]; -const whitelistedISUrls = ["https://vector.im"]; - class Analytics { constructor() { this._paq = null; @@ -140,11 +166,16 @@ class Analytics { } _setVisitVariable(key, value) { - this._paq.push(['setCustomVariable', customVariables[key], key, value, 'visit']); + this._paq.push(['setCustomVariable', customVariables[key].id, key, value, 'visit']); } setLoggedIn(isGuest, homeserverUrl, identityServerUrl) { if (this.disabled) return; + + const config = SdkConfig.get(); + const whitelistedHSUrls = config.piwik.whitelistedHSUrls || DEFAULTS.piwik.whitelistedHSUrls; + const whitelistedISUrls = config.piwik.whitelistedISUrls || DEFAULTS.piwik.whitelistedISUrls; + this._setVisitVariable('User Type', isGuest ? 'Guest' : 'Logged In'); this._setVisitVariable('Homeserver URL', whitelistRedact(whitelistedHSUrls, homeserverUrl)); this._setVisitVariable('Identity Server URL', whitelistRedact(whitelistedISUrls, identityServerUrl)); @@ -154,6 +185,44 @@ class Analytics { if (this.disabled) return; this._setVisitVariable('RTE: Uses Richtext Mode', state ? 'on' : 'off'); } + + showDetailsModal() { + const Tracker = window.Piwik.getAsyncTracker(); + const rows = Object.values(customVariables).map((v) => Tracker.getCustomVariable(v.id)).filter(Boolean); + + const resolution = `${window.screen.width}x${window.screen.height}`; + + const ErrorDialog = sdk.getComponent('dialogs.ErrorDialog'); + Modal.createTrackedDialog('Analytics Details', '', ErrorDialog, { + title: _t('Analytics'), + description:
+
+ { _t('The following information is sent to us to help make Riot.im better:') } +
+
+ + +
{ name }
  + { perms } +
+ { room.topic } +
+
{ getDisplayAliasForRoom(room) }
+
+ { room.numJoinedMembers } +
+ { rows.map((row) => + + + ) } +
{ _t(customVariables[row[0]].expl) }{ row[1] }
+
+
+ { _t('We also record each page you use in the app (currently ), your User Agent' + + ' () and your device resolution ().', + {}, + { + CurrentPageHash: { getRedactedHash() }, + CurrentUserAgent: { navigator.userAgent }, + CurrentDeviceResolution: { resolution }, + }, + ) } + + { _t('Where this page includes identifiable information, such as a room, ' + + 'user or group ID, that data is removed before being sent to the server.') } +
+
, + }); + } } if (!global.mxAnalytics) { diff --git a/src/SdkConfig.js b/src/SdkConfig.js index 8df725a913..64bf21ecf8 100644 --- a/src/SdkConfig.js +++ b/src/SdkConfig.js @@ -21,6 +21,13 @@ const DEFAULTS = { integrations_rest_url: "https://scalar.vector.im/api", // Where to send bug reports. If not specified, bugs cannot be sent. bug_report_endpoint_url: null, + + piwik: { + url: "https://piwik.riot.im/", + whitelistedHSUrls: ["https://matrix.org"], + whitelistedISUrls: ["https://vector.im", "https://matrix.org"], + siteId: 1, + }, }; class SdkConfig { @@ -45,3 +52,4 @@ class SdkConfig { } module.exports = SdkConfig; +module.exports.DEFAULTS = DEFAULTS; diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index 88619266ce..6e2d3d5669 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -806,6 +806,12 @@ module.exports = React.createClass({

{ _t('Analytics') }

{ _t('Riot collects anonymous analytics to allow us to improve the application.') } +
+ { _t('Privacy is important to us, so we don\'t collect any personal' + + ' or identifiable data for our analytics.') } +
+ { _t('Learn more about how we use analytics.') } +
{ ANALYTICS_SETTINGS.map( this._renderDeviceSetting ) }
; diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 128a07bc15..b45c2708be 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -807,6 +807,8 @@ "Report it": "Report it", "Analytics": "Analytics", "Riot collects anonymous analytics to allow us to improve the application.": "Riot collects anonymous analytics to allow us to improve the application.", + "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.", + "Learn more about how we use analytics.": "Learn more about how we use analytics.", "Labs": "Labs", "These are experimental features that may break in unexpected ways": "These are experimental features that may break in unexpected ways", "Use with caution": "Use with caution", @@ -930,5 +932,16 @@ "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.", "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.", "File to import": "File to import", - "Import": "Import" + "Import": "Import", + "The following information is sent to us to help make Riot.im better:": "The following information is sent to us to help make Riot.im better:", + "We also record each page you use in the app (currently ), your User Agent () and your device resolution ().": "We also record each page you use in the app (currently ), your User Agent () and your device resolution ().", + "Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.": "Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.", + "The platform you're on": "The platform you're on", + "The version of Riot.im": "The version of Riot.im", + "Whether or not you're logged in (we don't record your user name)": "Whether or not you're logged in (we don't record your user name)", + "Your language of choice": "Your language of choice", + "Which officially provided instance you are using, if any": "Which officially provided instance you are using, if any", + "Whether or not you're using the Richtext mode of the Rich Text Editor": "Whether or not you're using the Richtext mode of the Rich Text Editor", + "Your homeserver's URL": "Your homeserver's URL", + "Your identity server's URL": "Your identity server's URL" } From f8bb03cbc8a0d39423ba422edc6561b193ad9ff6 Mon Sep 17 00:00:00 2001 From: Pavel Kardash Date: Mon, 20 Nov 2017 09:56:39 +0000 Subject: [PATCH 052/927] Translated using Weblate (Russian) Currently translated at 99.6% (929 of 932 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 4a5741545e..c274bc7b48 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -1011,5 +1011,7 @@ "%(severalUsers)shad their invitations withdrawn %(count)s times|one": "%(severalUsers)sотозвали приглашения", "%(oneUser)shad their invitation withdrawn %(count)s times|other": "%(oneUser)sотклонил приглашение %(count)s раз", "%(oneUser)shad their invitation withdrawn %(count)s times|one": "%(oneUser)sотозвал приглашение", - "Please note you are logging into the %(hs)s server, not matrix.org.": "Обратите внимание, что вы заходите на сервер %(hs)s, а не на matrix.org." + "Please note you are logging into the %(hs)s server, not matrix.org.": "Обратите внимание, что вы заходите на сервер %(hs)s, а не на matrix.org.", + "Custom of %(powerLevel)s": "Пользовательский %(powerLevel)s", + "

HTML for your community's page

\n

\n Use the long description to introduce new members to the community, or distribute\n some important links\n

\n

\n You can even use 'img' tags\n

\n": "

HTML страницы вашего сообщества

\n

\n Используйте описание для предстваления вашего сообщества новым пользователям, или поделитесь чем-нибудь важным, напримерссылками\n

\n

\n Вы можете также вставлять изображения с помощью тэгов 'img'\n

\n" } From 230d14bf70dfb9df371437d44f5abacd6fa46e39 Mon Sep 17 00:00:00 2001 From: Jan Kudrik Date: Sun, 19 Nov 2017 13:49:33 +0000 Subject: [PATCH 053/927] Translated using Weblate (Czech) Currently translated at 69.4% (647 of 932 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/cs/ --- src/i18n/strings/cs.json | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/cs.json b/src/i18n/strings/cs.json index c797044693..a6ed5d0077 100644 --- a/src/i18n/strings/cs.json +++ b/src/i18n/strings/cs.json @@ -672,5 +672,14 @@ "Add an Integration": "Přidat začlenění", "Message removed": "Zpráva odstraněna", "Robot check is currently unavailable on desktop - please use a web browser": "Ochrana před roboty není aktuálně na desktopu dostupná. Použijte prosím webový prohlížeč", - "An email has been sent to %(emailAddress)s": "Na adresu %(emailAddress)s jsme poslali e-mail" + "An email has been sent to %(emailAddress)s": "Na adresu %(emailAddress)s jsme poslali e-mail", + "File to import": "Soubor k importu", + "none": "žádný", + "Passphrases must match": "Hesla se musí shodovat", + "Passphrase must not be empty": "Heslo nesmí být prázdné", + "Export room keys": "Exportovat klíče místnosti", + "This process allows you to export the keys for messages you have received in encrypted rooms to a local file. You will then be able to import the file into another Matrix client in the future, so that client will also be able to decrypt these messages.": "Tento proces vám umožňuje exportovat do souboru klíče ke zprávám, které jste dostali v šifrovaných místnostech. Když pak tento soubor importujete do jiného Matrix klienta, všechny tyto zprávy bude možné opět dešifrovat.", + "The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.": "Kdokoliv, kdo získá přístup k exportovanému souboru, bude moci dešifrovat všechny vaše přijaté zprávy, a proto je třeba dbát zvýšenou pozornost jeho zabezpečení. Z toho důvodu byste měl/a do kolonky níže zadat heslo, se kterým exportovaná data zašifrujeme. Import pak bude možný pouze se znalostí zadaného hesla.", + "Confirm passphrase": "Potvrďte heslo", + "Import room keys": "Importovat klíče místnosti" } From e25840e376844463d356d66d7ac6819efdc14d09 Mon Sep 17 00:00:00 2001 From: Andrey Date: Mon, 20 Nov 2017 10:15:47 +0000 Subject: [PATCH 054/927] Translated using Weblate (Russian) Currently translated at 99.6% (929 of 932 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index c274bc7b48..e90f34cd1e 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -1012,6 +1012,6 @@ "%(oneUser)shad their invitation withdrawn %(count)s times|other": "%(oneUser)sотклонил приглашение %(count)s раз", "%(oneUser)shad their invitation withdrawn %(count)s times|one": "%(oneUser)sотозвал приглашение", "Please note you are logging into the %(hs)s server, not matrix.org.": "Обратите внимание, что вы заходите на сервер %(hs)s, а не на matrix.org.", - "Custom of %(powerLevel)s": "Пользовательский %(powerLevel)s", - "

HTML for your community's page

\n

\n Use the long description to introduce new members to the community, or distribute\n some important links\n

\n

\n You can even use 'img' tags\n

\n": "

HTML страницы вашего сообщества

\n

\n Используйте описание для предстваления вашего сообщества новым пользователям, или поделитесь чем-нибудь важным, напримерссылками\n

\n

\n Вы можете также вставлять изображения с помощью тэгов 'img'\n

\n" + "Custom of %(powerLevel)s": "Пользовательский уровень %(powerLevel)s", + "

HTML for your community's page

\n

\n Use the long description to introduce new members to the community, or distribute\n some important links\n

\n

\n You can even use 'img' tags\n

\n": "

HTML для страницы вашего сообщества

\n

\n Используйте подробное описание для представления вашего сообщества новым участникам, или\n поделитесь чем-нибудь важным, например ссылками\n

\n

\n Также вы можете использовать теги 'img'\n

\n" } From 588e3f910a4b0c8261bb9f415a51fd3faf6decac Mon Sep 17 00:00:00 2001 From: Krombel Date: Tue, 21 Nov 2017 14:17:20 +0000 Subject: [PATCH 055/927] Translated using Weblate (German) Currently translated at 99.8% (931 of 932 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 7715397b0a..9a8dfe358f 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -1014,5 +1014,7 @@ "There's no one else here! Would you like to invite others or stop warning about the empty room?": "Sonst ist hier aktuell niemand. Möchtest du Benutzer einladen oder die Warnmeldung bezüglich des leeren Raums deaktivieren?", "Sign in to get started": "Melde dich an, um loszulegen", "URL previews are disabled by default for participants in this room.": "URL-Vorschau ist für Mitglieder dieses Raumes standardmäßig deaktiviert.", - "URL previews are enabled by default for participants in this room.": "URL-Vorschau ist für Mitglieder dieses Raumes standardmäßig aktiviert." + "URL previews are enabled by default for participants in this room.": "URL-Vorschau ist für Mitglieder dieses Raumes standardmäßig aktiviert.", + "Restricted": "Eingeschränkt", + "Presence Management": "Präsenz-Verwaltung" } From 46f41a0e732c7aa837cee7ec04388c0eabc2bae8 Mon Sep 17 00:00:00 2001 From: Bamstam Date: Tue, 21 Nov 2017 14:17:31 +0000 Subject: [PATCH 056/927] Translated using Weblate (German) Currently translated at 99.8% (931 of 932 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 9a8dfe358f..72781952df 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -1016,5 +1016,5 @@ "URL previews are disabled by default for participants in this room.": "URL-Vorschau ist für Mitglieder dieses Raumes standardmäßig deaktiviert.", "URL previews are enabled by default for participants in this room.": "URL-Vorschau ist für Mitglieder dieses Raumes standardmäßig aktiviert.", "Restricted": "Eingeschränkt", - "Presence Management": "Präsenz-Verwaltung" + "Presence Management": "Anwesenheitsmanagement" } From 7e440e832aafb85f9938244ec7a358b0b652b9ce Mon Sep 17 00:00:00 2001 From: Krombel Date: Tue, 21 Nov 2017 14:17:58 +0000 Subject: [PATCH 057/927] Translated using Weblate (German) Currently translated at 99.8% (932 of 932 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 72781952df..cbb47208a3 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -1016,5 +1016,6 @@ "URL previews are disabled by default for participants in this room.": "URL-Vorschau ist für Mitglieder dieses Raumes standardmäßig deaktiviert.", "URL previews are enabled by default for participants in this room.": "URL-Vorschau ist für Mitglieder dieses Raumes standardmäßig aktiviert.", "Restricted": "Eingeschränkt", - "Presence Management": "Anwesenheitsmanagement" + "Presence Management": "Anwesenheitsmanagement", + "Status.im theme": "Status.im-Thema" } From d81d2f17a9acf141fbd7e4514382a89487acc349 Mon Sep 17 00:00:00 2001 From: Bamstam Date: Wed, 22 Nov 2017 13:33:10 +0000 Subject: [PATCH 058/927] Translated using Weblate (German) Currently translated at 100.0% (932 of 932 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index cbb47208a3..5a9a4f1e44 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -117,7 +117,7 @@ "Notifications": "Benachrichtigungen", "": "", "No users have specific privileges in this room": "Kein Benutzer hat in diesem Raum besondere Berechtigungen", - "Once encryption is enabled for a room it cannot be turned off again (for now)": "Sobald Verschlüsselung für einen Raum aktiviert wird, kann diese (aktuell noch) nicht wieder deaktiviert werden", + "Once encryption is enabled for a room it cannot be turned off again (for now)": "Sobald die Verschlüsselung für einen Raum aktiviert wird, kann diese (Stand heute) nicht mehr deaktiviert werden", "Only people who have been invited": "Nur Personen, die eingeladen wurden", "Password": "Passwort", "Permissions": "Berechtigungen", @@ -183,7 +183,7 @@ "Voice call": "Sprachanruf", "VoIP conference finished.": "VoIP-Konferenz wurde beendet.", "VoIP conference started.": "VoIP-Konferenz gestartet.", - "(warning: cannot be disabled again!)": "(Warnung: Kann nicht wieder deaktiviert werden!)", + "(warning: cannot be disabled again!)": "(Warnung: Kann anschließend nicht mehr deaktiviert werden!)", "was banned": "wurde aus dem Raum verbannt", "was invited": "wurde eingeladen", "was kicked": "wurde gekickt", From c3afa907a30f60be400a5580aaa0413ab7ba0640 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Wed, 22 Nov 2017 17:49:06 +0000 Subject: [PATCH 059/927] Translated using Weblate (French) Currently translated at 100.0% (936 of 936 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index 615c802e5b..8e305e93a5 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -1013,5 +1013,13 @@ "URL previews are enabled by default for participants in this room.": "Les aperçus d'URL sont activés par défaut pour les participants de ce salon.", "URL previews are disabled by default for participants in this room.": "Les aperçus d'URL sont désactivés par défaut pour les participants de ce salon.", "Resend all or cancel all now. You can also select individual messages to resend or cancel.": "Tout renvoyer ou tout annuler maintenant. Vous pouvez également sélectionner des messages individuels à renvoyer ou annuler.", - "There's no one else here! Would you like to invite others or stop warning about the empty room?": "Il n'y a personne d'autre ici ! Souhaitez-vous inviter d'autres personnes ou ne plus être notifié à propos du salon vide ?" + "There's no one else here! Would you like to invite others or stop warning about the empty room?": "Il n'y a personne d'autre ici ! Souhaitez-vous inviter d'autres personnes ou ne plus être notifié à propos du salon vide ?", + "%(duration)ss": "%(duration)ss", + "%(duration)sm": "%(duration)sm", + "%(duration)sh": "%(duration)sh", + "%(duration)sd": "%(duration)sj", + "Online for %(duration)s": "En ligne depuis %(duration)s", + "Idle for %(duration)s": "Inactif depuis %(duration)s", + "Offline for %(duration)s": "Hors ligne depuis %(duration)s", + "Unknown for %(duration)s": "Inconnu depuis %(duration)s" } From 1083df274d51a208e16a042030008afbf361594c Mon Sep 17 00:00:00 2001 From: Szimszon Date: Wed, 22 Nov 2017 19:20:12 +0000 Subject: [PATCH 060/927] Translated using Weblate (Hungarian) Currently translated at 100.0% (936 of 936 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 91e90d1c1e..4800872ae5 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -1017,5 +1017,13 @@ "URL previews are enabled by default for participants in this room.": "Az URL előnézetek alapértelmezetten engedélyezve vannak a szobában jelenlévőknek.", "URL previews are disabled by default for participants in this room.": "Az URL előnézet alapértelmezetten tiltva van a szobában jelenlévőknek.", "Resend all or cancel all now. You can also select individual messages to resend or cancel.": "Mindet újraküldöd vagy mindet megszakítod. De egyenként is kijelölheted az üzenetet elküldésre vagy megszakításra.", - "There's no one else here! Would you like to invite others or stop warning about the empty room?": "Senki más nincs itt! Szeretnél meghívni másokat vagy leállítod a figyelmeztetést az üres szobára?" + "There's no one else here! Would you like to invite others or stop warning about the empty room?": "Senki más nincs itt! Szeretnél meghívni másokat vagy leállítod a figyelmeztetést az üres szobára?", + "%(duration)ss": "%(duration)s mp.", + "%(duration)sm": "%(duration)s p.", + "%(duration)sh": "%(duration)s ó.", + "%(duration)sd": "%(duration)s nap", + "Online for %(duration)s": "%(duration)s óta elérhető", + "Idle for %(duration)s": "%(duration)s óta tétlen", + "Offline for %(duration)s": "%(duration)s óta elérhetetlen", + "Unknown for %(duration)s": "%(duration)s óta az állapota ismeretlen" } From f91812491d129f16d0cd8c430ac55eb8a9d7e769 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D1=80=D0=BA=D0=BE=20=D0=9C=2E=20=D0=9A=D0=BE?= =?UTF-8?q?=D1=81=D1=82=D0=B8=D1=9B?= Date: Fri, 24 Nov 2017 18:53:04 +0000 Subject: [PATCH 061/927] Added translation using Weblate (Serbian) --- src/i18n/strings/sr.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/i18n/strings/sr.json diff --git a/src/i18n/strings/sr.json b/src/i18n/strings/sr.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/src/i18n/strings/sr.json @@ -0,0 +1 @@ +{} From 56437768c317b22f9eded9a3642343792dd93f47 Mon Sep 17 00:00:00 2001 From: Andrey Date: Wed, 22 Nov 2017 18:16:34 +0000 Subject: [PATCH 062/927] Translated using Weblate (Russian) Currently translated at 99.4% (931 of 936 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index e90f34cd1e..77e2e63bcd 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -1013,5 +1013,11 @@ "%(oneUser)shad their invitation withdrawn %(count)s times|one": "%(oneUser)sотозвал приглашение", "Please note you are logging into the %(hs)s server, not matrix.org.": "Обратите внимание, что вы заходите на сервер %(hs)s, а не на matrix.org.", "Custom of %(powerLevel)s": "Пользовательский уровень %(powerLevel)s", - "

HTML for your community's page

\n

\n Use the long description to introduce new members to the community, or distribute\n some important links\n

\n

\n You can even use 'img' tags\n

\n": "

HTML для страницы вашего сообщества

\n

\n Используйте подробное описание для представления вашего сообщества новым участникам, или\n поделитесь чем-нибудь важным, например ссылками\n

\n

\n Также вы можете использовать теги 'img'\n

\n" + "

HTML for your community's page

\n

\n Use the long description to introduce new members to the community, or distribute\n some important links\n

\n

\n You can even use 'img' tags\n

\n": "

HTML для страницы вашего сообщества

\n

\n Используйте подробное описание для представления вашего сообщества новым участникам, или\n поделитесь чем-нибудь важным, например ссылками\n

\n

\n Также вы можете использовать теги 'img'\n

\n", + "%(duration)ss": "%(duration)sсек", + "%(duration)sm": "%(duration)sмин", + "%(duration)sh": "%(duration)sчас", + "%(duration)sd": "%(duration)sдн", + "Your community hasn't got a Long Description, a HTML page to show to community members.
Click here to open settings and give it one!": "У вашего сообщества нет подробного описания HTML-страницы для показа участникам.
Щелкните здесь, чтобы открыть параметры и добавить его!", + "Resend all or cancel all now. You can also select individual messages to resend or cancel.": "Переотправить все или отменить все сейчас. Можно также выбрать отдельные сообщения для повторной отправки или отмены." } From 3a94b57e4a126e6034117278d5835ef7d352c2fe Mon Sep 17 00:00:00 2001 From: Vlad Date: Sun, 26 Nov 2017 14:24:17 +0000 Subject: [PATCH 063/927] Translated using Weblate (Russian) Currently translated at 100.0% (936 of 936 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 77e2e63bcd..bc3b217263 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -1019,5 +1019,10 @@ "%(duration)sh": "%(duration)sчас", "%(duration)sd": "%(duration)sдн", "Your community hasn't got a Long Description, a HTML page to show to community members.
Click here to open settings and give it one!": "У вашего сообщества нет подробного описания HTML-страницы для показа участникам.
Щелкните здесь, чтобы открыть параметры и добавить его!", - "Resend all or cancel all now. You can also select individual messages to resend or cancel.": "Переотправить все или отменить все сейчас. Можно также выбрать отдельные сообщения для повторной отправки или отмены." + "Resend all or cancel all now. You can also select individual messages to resend or cancel.": "Переотправить все или отменить все сейчас. Можно также выбрать отдельные сообщения для повторной отправки или отмены.", + "Online for %(duration)s": "В сети %(duration)s", + "Offline for %(duration)s": "Не в сети %(duration)s", + "Idle for %(duration)s": "Неактивен %(duration)s", + "Unknown for %(duration)s": "Неизвестно %(duration)s", + "There's no one else here! Would you like to invite others or stop warning about the empty room?": "Здесь никого нет! Хотите пригласить кого-нибудь или выключить уведомления о пустой комнате?" } From 3d9e7322b4e0019880b4b814c78f4508013a6a06 Mon Sep 17 00:00:00 2001 From: Tirifto Date: Thu, 23 Nov 2017 15:25:56 +0000 Subject: [PATCH 064/927] Translated using Weblate (Esperanto) Currently translated at 6.3% (59 of 936 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eo/ --- src/i18n/strings/eo.json | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/eo.json b/src/i18n/strings/eo.json index 363b61faad..4176d41ba0 100644 --- a/src/i18n/strings/eo.json +++ b/src/i18n/strings/eo.json @@ -39,5 +39,23 @@ "Who would you like to add to this community?": "Kiun vi volas aldoni al tiu ĉi komunumo?", "Invite new community members": "Invitu novajn komunumanojn", "Name or matrix ID": "Nomo aŭ Matrix-identigilo", - "Invite to Community": "Inviti al komunumo" + "Invite to Community": "Inviti al komunumo", + "Existing Call": "Jama voko", + "You are already in a call.": "Vi jam partoprenas vokon.", + "VoIP is unsupported": "VoIP ne estas subtenata", + "You cannot place VoIP calls in this browser.": "VoIP-vokoj ne fareblas en tiu ĉi foliumilo.", + "Conference calls are not supported in this client": "Grupaj vokoj ne fareblas en tiu ĉi kliento", + "Conference calls are not supported in encrypted rooms": "Grupaj vokoj ne fareblas en ĉifritaj ĉambroj", + "Conference calling is in development and may not be reliable.": "Grupaj vokoj ankoraŭ evoluas kaj povas malbone funkcii.", + "Failed to set up conference call": "Komenco de grupa voko malsukcesis", + "Conference call failed.": "Grupa voko malsukcesis.", + "The file '%(fileName)s' failed to upload": "Elŝuto de la dosiero «%(fileName)s» malsukcesis", + "The file '%(fileName)s' exceeds this home server's size limit for uploads": "La dosiero «%(fileName)s» estas tro granda por la hejma servilo", + "Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "Averto: ajna persono aldonita al komunumo estos publike videbla al iu ajn, kiu konas la identigilon de tiu komunumo", + "Which rooms would you like to add to this community?": "Kiujn ĉambrojn vi volas aldoni al ĉi tiu komunumo?", + "Show these rooms to non-members on the community page and room list?": "Ĉu la ĉambroj montriĝu al malanoj en la komunuma paĝo kaj listo de ĉambroj?", + "Add rooms to the community": "Aldoni ĉambrojn al la komunumo", + "Room name or alias": "Nomo aŭ kromnomo de ĉambro", + "Add to community": "Aldoni al komunumo", + "Failed to invite the following users to %(groupId)s:": "Malsukcesis inviti jenajn uzantojn al %(groupId)s:" } From ce4c470c829e2508a94c9ef66685731565158f88 Mon Sep 17 00:00:00 2001 From: xmeta Date: Wed, 22 Nov 2017 17:48:20 +0000 Subject: [PATCH 065/927] Translated using Weblate (Japanese) Currently translated at 6.1% (58 of 936 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ja/ --- src/i18n/strings/ja.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ja.json b/src/i18n/strings/ja.json index 73b1a915ec..295d42d5fe 100644 --- a/src/i18n/strings/ja.json +++ b/src/i18n/strings/ja.json @@ -57,5 +57,7 @@ "No Webcams detected": "カメラが見つかりません", "Microphone": "マイク", "Camera": "カメラ", - "Are you sure?": "本当によろしいですか?" + "Are you sure?": "本当によろしいですか?", + "OK": "OK", + "Operation failed": "操作に失敗しました" } From d824be602c4dfadbc59cdb3ca0622183cba38c7a Mon Sep 17 00:00:00 2001 From: Andrey Date: Sun, 26 Nov 2017 15:00:18 +0000 Subject: [PATCH 066/927] Translated using Weblate (Russian) Currently translated at 100.0% (936 of 936 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index bc3b217263..7690243bc7 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -1024,5 +1024,5 @@ "Offline for %(duration)s": "Не в сети %(duration)s", "Idle for %(duration)s": "Неактивен %(duration)s", "Unknown for %(duration)s": "Неизвестно %(duration)s", - "There's no one else here! Would you like to invite others or stop warning about the empty room?": "Здесь никого нет! Хотите пригласить кого-нибудь или выключить уведомления о пустой комнате?" + "There's no one else here! Would you like to invite others or stop warning about the empty room?": "Здесь никого нет! Хотите пригласить кого-нибудь или выключить предупреждение о пустой комнате?" } From 71590477b00a60f4cebd347098276e685c603057 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D1=80=D0=BA=D0=BE=20=D0=9C=2E=20=D0=9A=D0=BE?= =?UTF-8?q?=D1=81=D1=82=D0=B8=D1=9B?= Date: Sat, 25 Nov 2017 08:55:12 +0000 Subject: [PATCH 067/927] Translated using Weblate (Serbian) Currently translated at 9.5% (89 of 936 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sr/ --- src/i18n/strings/sr.json | 92 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/sr.json b/src/i18n/strings/sr.json index 0967ef424b..b43afe6116 100644 --- a/src/i18n/strings/sr.json +++ b/src/i18n/strings/sr.json @@ -1 +1,91 @@ -{} +{ + "This email address is already in use": "Ова мејл адреса се већ користи", + "This phone number is already in use": "Овај број телефона се већ користи", + "Failed to verify email address: make sure you clicked the link in the email": "Нисам успео да потврдим мејл адресу, постарајте се да сте кликнули на везу у мејлу", + "The remote side failed to pick up": "Друга страна није подигла слушалицу", + "Unable to capture screen": "Не могу да ухватим садржај екрана", + "Existing Call": "Постојећи позив", + "You are already in a call.": "Већ сте у позиву.", + "VoIP is unsupported": "VoIP није подржан", + "You cannot place VoIP calls in this browser.": "Не можете правити VoIP позиве у овом прегледачу.", + "You cannot place a call with yourself.": "Не можете позвати сами себе.", + "Conference calls are not supported in this client": "Конференцијски позиви нису подржани у овом клијенту", + "Conference calls are not supported in encrypted rooms": "Конференцијски позиви нису подржани у шифрованим собама", + "Warning!": "Упозорење!", + "Conference calling is in development and may not be reliable.": "Конференцијски позиви су још у развоју и могу бити непоуздани.", + "Failed to set up conference call": "Нисам успео да поставим конференцијски позив", + "Conference call failed.": "Конференцијски позив није успео.", + "The file '%(fileName)s' failed to upload": "Нисам успео да отпремим датотеку „%(fileName)s“", + "The file '%(fileName)s' exceeds this home server's size limit for uploads": "Датотека „%(fileName)s“ премашује ограничење величине отпремања на овом кућном серверу", + "Upload Failed": "Отпремање није успело", + "Sun": "Нед", + "Mon": "Пон", + "Tue": "Уто", + "Wed": "Сре", + "Thu": "Чет", + "Fri": "Пет", + "Sat": "Суб", + "Jan": "Јан", + "Feb": "Феб", + "Mar": "Мар", + "Apr": "Апр", + "May": "Мај", + "Jun": "Јун", + "Jul": "Јул", + "Aug": "Авг", + "Sep": "Сеп", + "Oct": "Окт", + "Nov": "Нов", + "Dec": "Дец", + "PM": "после подне", + "AM": "пре подне", + "%(weekDayName)s %(time)s": "%(weekDayName)s %(time)s", + "%(weekDayName)s, %(monthName)s %(day)s %(time)s": "%(weekDayName)s, %(monthName)s %(day)s %(time)s", + "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s %(time)s": "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s %(time)s", + "Who would you like to add to this community?": "Кога желите додати у ову заједницу?", + "Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "Упозорење: било која особа додата у заједницу биће јавно видљива било коме ко зна ИБ заједнице", + "Invite new community members": "Позови нове чланове заједнице", + "Name or matrix ID": "Назив или матрикс ИБ", + "Invite to Community": "Позови у заједницу", + "Which rooms would you like to add to this community?": "Које собе желите додати у ову заједницу?", + "Show these rooms to non-members on the community page and room list?": "Приказати ове собе нечлановима на страници заједнице и у списку соба?", + "Add rooms to the community": "Додај собе у заједницу", + "Room name or alias": "Назив собе или алијас", + "Add to community": "Додај у заједницу", + "Failed to invite the following users to %(groupId)s:": "Нисам успео да позовем следеће кориснике у %(groupId)s:", + "Failed to invite users to community": "Нисам успео да позовем кориснике у заједницу", + "Failed to invite users to %(groupId)s": "Нисам успео да позовем кориснике у %(groupId)s", + "Failed to add the following rooms to %(groupId)s:": "Нисам успео да додам следеће собе у %(groupId)s:", + "Riot does not have permission to send you notifications - please check your browser settings": "Riot нема овлашћења за слање обавештења, проверите подешавања вашег прегледача", + "Riot was not given permission to send notifications - please try again": "Riot-у није дато овлашћење за слање обавештења, пробајте поново касније", + "Unable to enable Notifications": "Нисам успео да омогућим обавештења", + "This email address was not found": "Ова мејл адреса није нађена", + "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Изгледа да ваша мејл адреса није повезана са Матрикс ИБ-јем на овом кућном серверу.", + "Default": "Подразумевано", + "Restricted": "Ограничено", + "Moderator": "Модератор", + "Admin": "Админ", + "Start a chat": "Крени са ћаскањем", + "Who would you like to communicate with?": "Са киме желите да разговарате?", + "Email, name or matrix ID": "Мејл, име или матрикс ИБ", + "Start Chat": "Ћаскај", + "Invite new room members": "Позови нове чланове у собу", + "Who would you like to add to this room?": "Кога желите да додате у ову собу?", + "Send Invites": "Пошаљи позивнице", + "Failed to invite user": "Неуспех при позивању корисника", + "Operation failed": "Радња није успела", + "Failed to invite": "Нисам успео да пошаљем позивницу", + "Failed to invite the following users to the %(roomName)s room:": "Нисам успео да пошаљем позивницу корисницима за собу %(roomName)s:", + "You need to be logged in.": "Морате бити пријављени.", + "You need to be able to invite users to do that.": "Морате имати могућност слања позивница корисницима да бисте то урадили.", + "Unable to create widget.": "Не могу да направим виџет.", + "Failed to send request.": "Неуспех при слању захтева.", + "This room is not recognised.": "Ова соба није препозната.", + "Power level must be positive integer.": "Ниво моћи мора бити позитивни број.", + "You are not in this room.": "Нисте у овој соби.", + "You do not have permission to do that in this room.": "Немате овлашћење да урадите то у овој соби.", + "Missing room_id in request": "Недостаје room_id у захтеву", + "Must be viewing a room": "Морате гледати собу", + "Room %(roomId)s not visible": "Соба %(roomId)s није видљива", + "Missing user_id in request": "Недостаје user_id у захтеву" +} From 2b57747e2e6ffa120b91014d903dd55fcd99ef0e Mon Sep 17 00:00:00 2001 From: Krombel Date: Mon, 27 Nov 2017 16:22:39 +0000 Subject: [PATCH 068/927] Translated using Weblate (German) Currently translated at 100.0% (936 of 936 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 5a9a4f1e44..7e2c5c677a 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -1017,5 +1017,16 @@ "URL previews are enabled by default for participants in this room.": "URL-Vorschau ist für Mitglieder dieses Raumes standardmäßig aktiviert.", "Restricted": "Eingeschränkt", "Presence Management": "Anwesenheitsmanagement", - "Status.im theme": "Status.im-Thema" + "Status.im theme": "Status.im-Thema", + "%(duration)ss": "%(duration)ss", + "%(duration)sm": "%(duration)sm", + "%(duration)sh": "%(duration)sh", + "%(duration)sd": "%(duration)sd", + "Online for %(duration)s": "Online seit %(duration)s", + "Idle for %(duration)s": "Untätig seit %(duration)s", + "Offline for %(duration)s": "Offline seit %(duration)s", + "Unknown for %(duration)s": "Unbekannt seit %(duration)s", + "Flair": "Flair", + "Showing flair for these communities:": "Flair für diese Communities zeigen:", + "This room is not showing flair for any communities": "Dieser Raum zeigt für keine Communities den Flair an" } From 246b33bd7eca767d4137d7d90e8e77bf8eeb2621 Mon Sep 17 00:00:00 2001 From: Krombel Date: Mon, 27 Nov 2017 16:28:37 +0000 Subject: [PATCH 069/927] Translated using Weblate (German) Currently translated at 100.0% (936 of 936 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 7e2c5c677a..c65e512928 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -1026,7 +1026,7 @@ "Idle for %(duration)s": "Untätig seit %(duration)s", "Offline for %(duration)s": "Offline seit %(duration)s", "Unknown for %(duration)s": "Unbekannt seit %(duration)s", - "Flair": "Flair", - "Showing flair for these communities:": "Flair für diese Communities zeigen:", - "This room is not showing flair for any communities": "Dieser Raum zeigt für keine Communities den Flair an" + "Flair": "Abzeichen", + "Showing flair for these communities:": "Abzeichen für diese Communities zeigen:", + "This room is not showing flair for any communities": "Dieser Raum zeigt für keine Communities die Abzeichen an" } From 88917c77bce149627a3cd8acf2bdb2a2f0409b09 Mon Sep 17 00:00:00 2001 From: Mateo Castro Date: Mon, 27 Nov 2017 16:11:29 +0000 Subject: [PATCH 070/927] Translated using Weblate (Spanish) Currently translated at 60.2% (564 of 936 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/es/ --- src/i18n/strings/es.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/es.json b/src/i18n/strings/es.json index 261700a916..6a8bc3ccee 100644 --- a/src/i18n/strings/es.json +++ b/src/i18n/strings/es.json @@ -472,7 +472,7 @@ "Changes colour scheme of current room": "Cambia el esquema de colores de esta sala", "Delete widget": "Eliminar widget", "Define the power level of a user": "Definir el nivel de poder de los usuarios", - "Edit": "Editar", + "Edit": "Edita", "Enable automatic language detection for syntax highlighting": "Activar la detección automática del lenguaje para resaltar la sintaxis", "Hide Apps": "Ocultar aplicaciones", "Hide join/leave messages (invites/kicks/bans unaffected)": "Ocultar mensajes de entrada/salida (no afecta invitaciones/kicks/bans)", From 3441a4aa5c2dc464f654bee2156fa0b232d031c9 Mon Sep 17 00:00:00 2001 From: Andrey Date: Tue, 28 Nov 2017 11:22:13 +0000 Subject: [PATCH 071/927] Translated using Weblate (Russian) Currently translated at 99.2% (931 of 938 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 7690243bc7..d7763aa86d 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -1024,5 +1024,6 @@ "Offline for %(duration)s": "Не в сети %(duration)s", "Idle for %(duration)s": "Неактивен %(duration)s", "Unknown for %(duration)s": "Неизвестно %(duration)s", - "There's no one else here! Would you like to invite others or stop warning about the empty room?": "Здесь никого нет! Хотите пригласить кого-нибудь или выключить предупреждение о пустой комнате?" + "There's no one else here! Would you like to invite others or stop warning about the empty room?": "Здесь никого нет! Хотите пригласить кого-нибудь или выключить предупреждение о пустой комнате?", + "Something went wrong when trying to get your communities.": "Что-то пошло не так, во время отображения ваших сообществ." } From 6e555509208d11ab20cfcd0061bc1bf1cc70a203 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Tue, 28 Nov 2017 17:49:54 +0000 Subject: [PATCH 072/927] Translated using Weblate (French) Currently translated at 100.0% (941 of 941 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index 8e305e93a5..b64a998b61 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -1021,5 +1021,16 @@ "Online for %(duration)s": "En ligne depuis %(duration)s", "Idle for %(duration)s": "Inactif depuis %(duration)s", "Offline for %(duration)s": "Hors ligne depuis %(duration)s", - "Unknown for %(duration)s": "Inconnu depuis %(duration)s" + "Unknown for %(duration)s": "Inconnu depuis %(duration)s", + "Delete %(count)s devices|one": "Supprimer l'appareil", + "Delete %(count)s devices|other": "Supprimer %(count)s appareils", + "Select devices": "Sélectionner les appareils", + "Something went wrong when trying to get your communities.": "Une erreur est survenue lors de l'obtention de vos communautés.", + "This homeserver doesn't offer any login flows which are supported by this client.": "Ce serveur d'accueil n'offre aucun flux compatible avec ce client.", + "Flair": "Talent", + "Showing flair for these communities:": "Montre les talents pour ces communautés :", + "This room is not showing flair for any communities": "Ce salon n'affiche de talent pour aucune communauté", + "Flair will appear if enabled in room settings": "Les talents apparaîtront s'ils sont activés dans les paramètres du salon", + "Flair will not appear": "Les talents n'apparaîtront pas", + "Display your community flair in rooms configured to show it.": "Afficher vos talents de communauté dans les salons configurés pour les afficher." } From e5d1f2a05b561cc87384537692c146e69fc2cefe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20Koreck=C3=BD?= Date: Wed, 29 Nov 2017 11:49:53 +0000 Subject: [PATCH 073/927] Translated using Weblate (Czech) Currently translated at 100.0% (941 of 941 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/cs/ --- src/i18n/strings/cs.json | 337 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 317 insertions(+), 20 deletions(-) diff --git a/src/i18n/strings/cs.json b/src/i18n/strings/cs.json index a6ed5d0077..b29aedb4db 100644 --- a/src/i18n/strings/cs.json +++ b/src/i18n/strings/cs.json @@ -346,7 +346,7 @@ "These are experimental features that may break in unexpected ways": "Tyto funkce jsou experimentální a mohou se pokazit nečekanými způsoby", "The visibility of existing history will be unchanged": "Viditelnost existující historie nebude změněna", "VoIP is unsupported": "VoIP není podporován", - "Warning!": "Pozor!", + "Warning!": "Varování!", "Who can access this room?": "Kdo má přístup k této místnosti?", "Who can read history?": "Kdo může číst historii?", "Who would you like to add to this room?": "Koho byste chtěli přidat do této místnosti?", @@ -452,20 +452,20 @@ "(warning: cannot be disabled again!)": "(varování: nepůjde znovu zakázat!)", "WARNING: Device already verified, but keys do NOT MATCH!": "VAROVÁNÍ: Zařízení byl již ověřeno, ale klíče se NESHODUJÍ!", "The remote side failed to pick up": "Vzdálené straně se nepodařilo hovor přijmout", - "Who would you like to add to this community?": "Koho chcete přidat do této komunity?", - "Invite new community members": "Pozvěte nové členy komunity", + "Who would you like to add to this community?": "Koho chcete přidat do této skupiny?", + "Invite new community members": "Pozvěte nové členy skupiny", "Name or matrix ID": "Jméno nebo matrix ID", - "Invite to Community": "Pozvat do komunity", - "Which rooms would you like to add to this community?": "Které místnosti chcete přidat do této komunity?", + "Invite to Community": "Pozvat do skupiny", + "Which rooms would you like to add to this community?": "Které místnosti chcete přidat do této skupiny?", "Warning: any room you add to a community will be publicly visible to anyone who knows the community ID": "Varování: místnost, kterou přidáte do této komunity, bude veřejně viditelná každému, kdo zná ID komunity", - "Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "Varování: osoba, kterou přidáte do této komunity, bude veřejně viditelná každému, kdo zná ID komunity", - "Add rooms to the community": "Přidat místnosti do komunity", + "Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "Varování: osoba, kterou přidáte do této skupiny, bude veřejně viditelná každému, kdo zná ID skupiny", + "Add rooms to the community": "Přidat místnosti do skupiny", "Room name or alias": "Název nebo alias místnosti", - "Add to community": "Přidat do komunity", + "Add to community": "Přidat do skupiny", "Failed to invite the following users to %(groupId)s:": "Následující uživatele se nepodařilo přidat do %(groupId)s:", "Invites sent": "Pozvánky odeslány", "Your community invitations have been sent.": "Vaše komunitní pozvánky byly odeslány.", - "Failed to invite users to community": "Nepodařilo se pozvat uživatele do komunity", + "Failed to invite users to community": "Nepodařilo se pozvat uživatele do skupiny", "Failed to invite users to %(groupId)s": "Nepodařilo se pozvat uživatele do %(groupId)s", "%(weekDayName)s %(time)s": "%(weekDayName)s %(time)s", "%(weekDayName)s, %(monthName)s %(day)s %(time)s": "%(weekDayName)s, %(monthName)s %(day)s %(time)s", @@ -479,7 +479,7 @@ "You need to be logged in.": "Musíte být přihlášen/a.", "You are now ignoring %(userId)s": "Nyní ignorujete %(userId)s", "You are no longer ignoring %(userId)s": "Už neignorujete %(userId)s", - "Add rooms to this community": "Přidat místnosti do této komunity", + "Add rooms to this community": "Přidat místnosti do této skupiny", "Unpin Message": "Odepnout zprávu", "Ignored user": "Ignorovaný uživatel", "Unignored user": "Odignorovaný uživatel", @@ -492,7 +492,7 @@ "%(senderName)s requested a VoIP conference.": "%(senderName)s požádal/a o VoIP konferenci.", "%(senderName)s removed their profile picture.": "%(senderName)s odstranil/a svůj profilový obrázek.", "%(targetName)s rejected the invitation.": "%(targetName)s odmítl/a pozvání.", - "Communities": "Komunity", + "Communities": "Skupiny", "Message Pinning": "Připíchnutí zprávy", "Your browser does not support the required cryptography extensions": "Váš prohlížeč nepodporuje požadovaná kryptografická rozšíření", "Do you want to set an email address?": "Chcete nastavit e-mailovou adresu?", @@ -542,8 +542,8 @@ "uploaded a file": "nahrál/a soubor", "Example": "Příklad", "Create Community": "Vytvořit komunitu", - "Community Name": "Název komunity", - "Community ID": "ID komunity", + "Community Name": "Název skupiny", + "Community ID": "ID skupiny", "example": "příklad", "Create": "Vytvořit", "Advanced options": "Pokročilé volby", @@ -587,7 +587,7 @@ "was unbanned": "byl/a přijat/a zpět", "was unbanned %(repeats)s times": "byl/a přijat/a zpět %(repeats)skrát", "were unbanned %(repeats)s times": "byli přijati zpět %(repeats)skrát", - "Leave Community": "Odejít z komunity", + "Leave Community": "Odejít ze skupiny", "Leave %(groupName)s?": "Odejít z %(groupName)s?", "Leave": "Odejít", "Unable to leave room": "Nepodařilo se odejít z místnosti", @@ -596,8 +596,8 @@ "%(oneUser)sjoined and left %(repeats)s times": "%(oneUser)s vstoupil/a a odešel/la %(repeats)skrát", "%(severalUsers)sjoined and left": "%(severalUsers)s vstoupilo a odešlo", "%(oneUser)sjoined and left": "%(oneUser)s vstoupil/a a odešel/la", - "Failed to remove user from community": "Nepodařilo se odebrat uživatele z komunity", - "Failed to remove room from community": "Nepodařilo se odebrat místnost z komunity", + "Failed to remove user from community": "Nepodařilo se odebrat uživatele ze skupiny", + "Failed to remove room from community": "Nepodařilo se odebrat místnost ze skupiny", "Failed to remove '%(roomName)s' from %(groupId)s": "'%(roomName)s' se nepodařilo odebrat z %(groupId)s", "Failed to update community": "Nepodařilo se aktualizovat komunitu", "Failed to load %(groupId)s": "Nepodařilo se načíst %(groupId)s", @@ -636,12 +636,12 @@ "To send events of type , you must be a": "Abyste mohl/a odesílat události typu , musíte být", "You should not yet trust it to secure data": "Zatím byste jeho zabezpečení dat neměl/a důvěřovat", "Remote addresses for this room:": "Vzdálené adresy této místnosti:", - "Invalid community ID": "Neplatné ID komunity", - "'%(groupId)s' is not a valid community ID": "'%(groupId)s' není platné ID komunity", + "Invalid community ID": "Neplatné ID skupiny", + "'%(groupId)s' is not a valid community ID": "'%(groupId)s' není platné ID skupiny", "Related Communities": "Související komunity", "Related communities for this room:": "Komunity související s touto místností:", "This room has no related communities": "Tato místnost nemá žádné související komunity", - "New community ID (e.g. +foo:%(localDomain)s)": "Nové ID komunity (např. +neco:%(localDomain)s)", + "New community ID (e.g. +foo:%(localDomain)s)": "Nové ID skupiny (např. +neco:%(localDomain)s)", "%(names)s and %(count)s others are typing|one": "%(names)s a jeden další píší", "%(senderName)s sent an image": "%(senderName)s poslal/a obrázek", "%(senderName)s sent a video": "%(senderName)s poslal/a video", @@ -681,5 +681,302 @@ "This process allows you to export the keys for messages you have received in encrypted rooms to a local file. You will then be able to import the file into another Matrix client in the future, so that client will also be able to decrypt these messages.": "Tento proces vám umožňuje exportovat do souboru klíče ke zprávám, které jste dostali v šifrovaných místnostech. Když pak tento soubor importujete do jiného Matrix klienta, všechny tyto zprávy bude možné opět dešifrovat.", "The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.": "Kdokoliv, kdo získá přístup k exportovanému souboru, bude moci dešifrovat všechny vaše přijaté zprávy, a proto je třeba dbát zvýšenou pozornost jeho zabezpečení. Z toho důvodu byste měl/a do kolonky níže zadat heslo, se kterým exportovaná data zašifrujeme. Import pak bude možný pouze se znalostí zadaného hesla.", "Confirm passphrase": "Potvrďte heslo", - "Import room keys": "Importovat klíče místnosti" + "Import room keys": "Importovat klíče místnosti", + "Call Timeout": "Časový limit hovoru", + "Show these rooms to non-members on the community page and room list?": "Zobrazovat tyto místnosti na domovské stránce skupiny a v seznamu místností i pro nečleny?", + "Restricted": "Omezené", + "Missing room_id in request": "V zadání chybí room_id", + "Must be viewing a room": "Musí být zobrazena místnost", + "Missing user_id in request": "V zadání chybí user_id", + "Failed to lookup current room": "Nepodařilo se vyhledat aktuální místnost", + "(could not connect media)": "(média se nepodařilo spojit)", + "%(senderName)s placed a %(callType)s call.": "%(senderName)s uskutečnil %(callType)s hovor.", + "%(senderName)s made future room history visible to unknown (%(visibility)s).": "%(senderName)s zpřístupnil budoucí historii místnosti neznámým (%(visibility)s).", + "Not a valid Riot keyfile": "Neplatný soubor s klíčem Riot", + "Presence Management": "Správce účasti", + "Disable Emoji suggestions while typing": "Zakázat návrhy Emoji během psaní", + "Hide avatar changes": "Skrýt změny avatara", + "Hide display name changes": "Skrýt změny zobrazovaného jména", + "Hide avatars in user and room mentions": "Skrýt avatary avatary v poznámkách uživatelů a místností", + "Disable big emoji in chat": "Zakázat velké Emoji v konverzaci", + "Mirror local video feed": "Zrcadlit lokání video", + "Disable Peer-to-Peer for 1:1 calls": "Zakázat Peer-to-Peer pro 1:1 hovory", + "Opt out of analytics": "Odhlásit se z analytiky údajů", + "Never send encrypted messages to unverified devices from this device": "Z tohoto zařízení nikdy neodesílat šifrované zprávy na neověřená zařízení", + "Enable inline URL previews by default": "Nastavit povolení náhledů URL adres jako výchozí", + "Enable URL previews for this room (only affects you)": "Povolit náhledy URL adres pro tuto místnost (ovlivňuje pouze vás)", + "Enable URL previews by default for participants in this room": "Povolit náhledy URL adres pro členy této místnosti jako výchozí", + "Delete %(count)s devices|one": "Smazat zařízení", + "Delete %(count)s devices|other": "Smazat %(count)s zařízení", + "Select devices": "Vybrat zařízení", + " (unsupported)": " (nepodporované)", + "Join as voice or video.": "Připojte se prostřednictvím audio nebo video.", + "Ongoing conference call%(supportedText)s.": "Probíhající konferenční hovor%(supportedText)s.", + "%(duration)ss": "%(duration)ss", + "%(duration)sm": "%(duration)sm", + "%(duration)sh": "%(duration)sh", + "%(duration)sd": "%(duration)sd", + "Online for %(duration)s": "Online po dobu %(duration)s", + "Idle for %(duration)s": "Idle po dobu %(duration)s", + "Offline for %(duration)s": "Offline po dobu %(duration)s", + "Unknown for %(duration)s": "Neznámý po dobu %(duration)s", + "You may wish to login with a different account, or add this email to this account.": "Můžete se přihlásit k jinému účtu anebo přidat tuto emailovou adresu do právě přihlášeného účtu.", + "Flair": "Zájem", + "Showing flair for these communities:": "Zobrazovat zájmy těmto komunitám:", + "This room is not showing flair for any communities": "Tato místnost nezobrazuje zájmy žádné komunitě", + "URL previews are enabled by default for participants in this room.": "Náhledy URL adres jsou defaultně nastavené jako povolené pro členy této místnosti.", + "URL previews are disabled by default for participants in this room.": "Náhledy URL adres jsou defaultně nastavené jako zakázané pro členy této místnosti.", + "Invalid file%(extra)s": "Neplatný soubor%(extra)s", + "You are about to be taken to a third-party site so you can authenticate your account for use with %(integrationsUrl)s. Do you wish to continue?": "Budete přesměrováni na stránku třetí strany k ověření svého účtu pro používání s %(integrationsUrl)s. Chcete pokračovat?", + "Sign in with CAS": "Přihlásit se pomocí CAS", + "This allows you to use this app with an existing Matrix account on a different home server.": "Umožní vám použít aplikaci s existujícím Matrix účtem z jiného domácího serveru.", + "To continue, please enter your password.": "Aby jste mohli pokračovat, zadejte prosím své heslo.", + "Please check your email to continue registration.": "Prosím zkontrolujte své emaily, abyste mohli pokračovat v registraci.", + "Token incorrect": "Neplatný token", + "A text message has been sent to %(msisdn)s": "Na číslo %(msisdn)s byla odeslána textová zpráva", + "Please enter the code it contains:": "Prosím zadejte kód z této zprávy:", + "Username on %(hs)s": "Uživatelské jméno pro %(hs)s", + "%(serverName)s Matrix ID": "%(serverName)s Matrix ID", + "Sign in with": "Přihlásit se s", + "If you don't specify an email address, you won't be able to reset your password. Are you sure?": "Pokud nezadáte vaši emailovou adresu, nebude možné obnovit vaše heslo. Opravdu chcete pokračovat?", + "You are registering with %(SelectedTeamName)s": "Regristrujete se s %(SelectedTeamName)s", + "Default server": "Výchozí server", + "Custom server": "Vlastní server", + "Home server URL": "Adresa domácího serveru", + "What does this mean?": "Co to znamená?", + "Remove from community": "Odstranit ze skupiny", + "Disinvite this user from community?": "Zrušit pozvání tohoto uživatele?", + "Remove this user from community?": "Odstranit tohoto uživatele ze skupiny?", + "Failed to withdraw invitation": "Stažení pozvání selhalo", + "Filter community members": "Filtrovat členy skupiny", + "Flair will appear if enabled in room settings": "Zájmy budou zobrazeny pokud budou povoleny v nastavení místnosti", + "Flair will not appear": "Zájmy se nebudou zobrazovat", + "Are you sure you want to remove '%(roomName)s' from %(groupId)s?": "Opravdu chcete odstranit místnost '%(roomName)s' z %(groupId)s?", + "Removing a room from the community will also remove it from the community page.": "Pokud odstraníte místnost ze skupiny, odstraní se i odkaz do místnosti ze stránky skupiny.", + "Something went wrong!": "Něco se nepodařilo!", + "The visibility of '%(roomName)s' in %(groupId)s could not be updated.": "Zobrazení místnosti '%(roomName)s' ve skupině %(groupId)s nelze aktualizovat.", + "Visibility in Room List": "Zobrazení v Seznamu Místností", + "Visible to everyone": "Zobrazení pro každého", + "Only visible to community members": "Zobrazuje se pouze pro členy skupiny", + "Filter community rooms": "Filtrovat místnosti skupiny", + "Something went wrong when trying to get your communities.": "Při pokusu o nahrání vašich skupin se něco pokazilo.", + "Display your community flair in rooms configured to show it.": "Zobrazit zájmy skupiny v místnostech s povolených zobrazováním.", + "You're not currently a member of any communities.": "V současnosti nejste členem žádné skupiny.", + "Unknown Address": "Neznámá adresa", + "NOTE: Apps are not end-to-end encrypted": "VAROVÁNÍ: Aplikace nejsou end-to-end šifrované", + "Revoke widget access": "Odmítnout přístup k widgetu", + "Unblacklist": "Odstranit z černé listiny", + "Blacklist": "Přidat do černé listiny", + "Unverify": "Zrušit ověřování", + "Verify...": "Ověřit...", + "Integrations Error": "Chyby integrace", + "Manage Integrations": "Správa nastavení", + "%(nameList)s %(transitionList)s": "%(nameList)s %(transitionList)s", + "%(severalUsers)sjoined %(count)s times|other": "%(severalUsers)s%(count)s krát vstoupili", + "%(severalUsers)sjoined %(count)s times|one": "%(severalUsers)svstoupili", + "%(oneUser)sjoined %(count)s times|one": "%(oneUser)svstoupil", + "%(severalUsers)sleft %(count)s times|other": "%(severalUsers)s %(count)s krát opustili", + "%(severalUsers)sleft %(count)s times|one": "%(severalUsers)sopustili", + "%(oneUser)sleft %(count)s times|other": "%(oneUser)s %(count)s krát opustil", + "%(oneUser)sleft %(count)s times|one": "%(oneUser)sopustil", + "%(severalUsers)sjoined and left %(count)s times|other": "%(severalUsers)s %(count)s krát vstoupili a opustili", + "%(severalUsers)sjoined and left %(count)s times|one": "%(severalUsers)svstoupili a opustili", + "%(oneUser)sjoined and left %(count)s times|other": "%(oneUser)s %(count)s krát vstoupil a opustil", + "%(oneUser)sjoined and left %(count)s times|one": "%(oneUser)svstoupil a opustil", + "%(severalUsers)sleft and rejoined %(count)s times|other": "%(severalUsers)s %(count)s krát opustili a znovu vstoupili", + "%(severalUsers)sleft and rejoined %(count)s times|one": "%(severalUsers)sopustili a znovu vstoupili", + "%(oneUser)sleft and rejoined %(count)s times|other": "%(oneUser)s %(count)s krát opustil a znovu vstoupil", + "%(oneUser)sleft and rejoined %(count)s times|one": "%(oneUser)sopustil a znovu vstoupil", + "%(severalUsers)srejected their invitations %(count)s times|other": "%(severalUsers)s %(count)s krát odmítli pozvání", + "%(severalUsers)srejected their invitations %(count)s times|one": "%(severalUsers)sodmítli pozvání", + "%(oneUser)srejected their invitation %(count)s times|other": "%(oneUser)s %(count)s krát odmítl pozvání", + "%(oneUser)srejected their invitation %(count)s times|one": "%(oneUser)sodmítl pozvání", + "%(severalUsers)shad their invitations withdrawn %(count)s times|other": "%(severalUsers)směli %(count)s krát stažené pozvání", + "%(severalUsers)shad their invitations withdrawn %(count)s times|one": "%(severalUsers)smeli stažené pozvání", + "%(oneUser)shad their invitation withdrawn %(count)s times|other": "%(oneUser)směl %(count)s krát stažené pozvání", + "%(oneUser)shad their invitation withdrawn %(count)s times|one": "%(oneUser)směl stažené pozvání", + "were invited %(count)s times|other": "byli %(count)s krát pozvaní", + "were invited %(count)s times|one": "byli pozvaní", + "was invited %(count)s times|other": "byl %(count)s krát pozvaný", + "was invited %(count)s times|one": "byl pozvaný", + "were banned %(count)s times|other": "mělid %(count)s krát zakázaný vstup", + "were banned %(count)s times|one": "měli zakázaný vstup", + "was banned %(count)s times|other": "měl %(count)s krát zakázaný vstup", + "was banned %(count)s times|one": "měl zakázaný vstup", + "were unbanned %(count)s times|other": "měli %(count)s krát povolený vstup", + "were unbanned %(count)s times|one": "měli povolený vstup", + "was unbanned %(count)s times|other": "měl %(count)s krát povolený vstup", + "was unbanned %(count)s times|one": "měl povolený vstup", + "were kicked %(count)s times|other": "byli %(count)s krát vyhozeni", + "were kicked %(count)s times|one": "byli vyhozeni", + "was kicked %(count)s times|other": "byl %(count)s krát vyhozen", + "was kicked %(count)s times|one": "byl vyhozen", + "%(severalUsers)schanged their name %(count)s times|other": "%(severalUsers)ssi %(count)s krát změnili jméno", + "%(severalUsers)schanged their name %(count)s times|one": "%(severalUsers)ssi změnili jméno", + "%(oneUser)schanged their name %(count)s times|other": "%(oneUser)ssi %(count)s krát změnili jméno", + "%(oneUser)schanged their name %(count)s times|one": "%(oneUser)ssi změnili jméno", + "%(severalUsers)schanged their avatar %(count)s times|other": "%(severalUsers)ssi %(count)s krát změnili avatara", + "%(severalUsers)schanged their avatar %(count)s times|one": "%(severalUsers)ssi změnili avatara", + "%(oneUser)schanged their avatar %(count)s times|other": "%(oneUser)ssi %(count)s krát změnil avatara", + "%(oneUser)schanged their avatar %(count)s times|one": "%(oneUser)ssi změnil avatara", + "%(items)s and %(count)s others|other": "%(items)s a %(count)s další", + "%(items)s and %(count)s others|one": "%(items)s a jeden další", + "%(items)s and %(lastItem)s": "%(items)s a také %(lastItem)s", + "Custom of %(powerLevel)s": "Vlastní úroveň %(powerLevel)s", + "And %(count)s more...|other": "A %(count)s dalších...", + "ex. @bob:example.com": "pr. @jan:příklad.com", + "Add User": "Přidat uživatele", + "Matrix ID": "Matrix ID", + "Matrix Room ID": "ID Matrix místnosti", + "email address": "emailová adresa", + "Try using one of the following valid address types: %(validTypesList)s.": "Zkuste použít jeden z následujících správných tvarů adres: %(validTypesList)s.", + "You have entered an invalid address.": "Zadali jste neplatnou adresu.", + "Create a new chat or reuse an existing one": "Vytvořte nový chat anebo se připojte k již existujícímu", + "Start new chat": "Začít nový chat", + "You already have existing direct chats with this user:": "S tímto uživatelem již společně chatujete:", + "Click on the button below to start chatting!": "Pro zahájení chatu klikněte na tlačítko níže!", + "Confirm Removal": "Potvrdit odstranění", + "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Opravdu chcete odstranit (smazat) tuto událost? V případě, že smažete název místnosti anebo změníte téma, je možné, že se změny neprovedou.", + "Community IDs may only contain characters a-z, 0-9, or '=_-./'": "ID skupiny může obsahovat pouze znaky a-z, 0-9, or '=_-./'", + "Something went wrong whilst creating your community": "Něco se pokazilo v během vytváření vaší skupiny", + "Block users on other matrix homeservers from joining this room": "Blokovat vstup do místnosti uživatelům z ostatních domácích matrix serverů", + "This setting cannot be changed later!": "Toto nastavení nelze v budoucnu změnit!", + "Unknown error": "Neznámá chyba", + "Incorrect password": "Nesprávné heslo", + "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Toto způsobí, že váš účet nebude již nikdy použitelný. Zároveň nebude možné se znovu zaregistrovat pod stejným uživatelským ID.", + "This action is irreversible.": "Tuto operaci nebude možné vrátit zpět.", + "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Pokud si chcete ověřit, zda je zařízení skutečně důvěryhodné, kontaktujte vlastníka jiným způsobem (např. osobně anebo telefonicky) a zeptejte se ho na klíč, který má pro toto zařízení zobrazený v nastavení a zda se shoduje s klíčem zobrazeným níže:", + "Device name": "Název zařízení", + "Device key": "Klíč zařízení", + "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "Pokud se klíče shodují, stlačte ověřovací tlačítko uvedené níže. Pokud se neshodují, někdo další odposlouchává toto zařízení a v takovém případě by jste měli místo toho vybrat tlačítko černé listiny.", + "In future this verification process will be more sophisticated.": "V budoucnu plánujeme proces ověřování zařízení zjednodušit.", + "Verify device": "Ověřit zařízení", + "I verify that the keys match": "Ověřil jsem, klíče se shodují", + "You added a new device '%(displayName)s', which is requesting encryption keys.": "Přidali jste nové zařízení s názvem '%(displayName)s', vyžadující šifrovací klíč.", + "Your unverified device '%(displayName)s' is requesting encryption keys.": "Vaše neověřené zařízení s názvem '%(displayName)s' vyžaduje šifrovací klíč.", + "Start verification": "Zahájit ověřování", + "Share without verifying": "Sdílet bez ověření", + "Ignore request": "Ignorovat žádost", + "Encryption key request": "Žádost o šifrovací klíč", + "Unable to restore session": "Nelze obnovit relaci", + "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "Při pokusu o obnovení vaší předcházející relace se vyskytla chyba. Pokud budete pokračovat musíte se znovu přihlásit a historie šifrovaného rozhovoru nebude již dostupná.", + "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Pokud jste se v minulosti již přihlásili s novější verzi programu Riot, vaše relace nemusí být kompatibilní s touto verzí. Zavřete prosím toto okno a přihlaste se znovu pomocí nové verze.", + "Continue anyway": "Přesto pokračovat", + "Please check your email and click on the link it contains. Once this is done, click continue.": "Prosím, zkontrolujte si email a klikněte na odkaz ve zprávě, kterou jsme vám zaslali. V případě, že jste tak již učinili, klikněte na tlačítko Pokračovat.", + "This will allow you to reset your password and receive notifications.": "Toto vám umožní obnovit si heslo a přijímat oznámení emailem.", + "Skip": "Přeskočit", + "User names may only contain letters, numbers, dots, hyphens and underscores.": "Uživatelské jméno může obsahovat pouze písmena, číslice, tečky, pomlčky a podtržítka.", + "Username not available": "Uživatelské jméno není dostupné", + "An error occurred: %(error_string)s": "Vyskytla se chyba: %(error_string)s", + "Username available": "Dostupné uživatelské jméno", + "To get started, please pick a username!": "Začněte tím, že si zvolíte uživatelské jméno!", + "This will be your account name on the homeserver, or you can pick a different server.": "Toto bude název vašeho účtu na domácím serveru , anebo si můžete zvolit jiný server.", + "If you already have a Matrix account you can log in instead.": "Pokud již účet Matrix máte, můžete se ihned Přihlásit.", + "%(oneUser)sjoined %(count)s times|other": "%(oneUser)s %(count)s krát vstoupil", + "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "Neověřená zařízení jsou v této chvíli na černé listině; pokud chcete zasílat zprávy na tato zařízení, musíte je nejdříve ověřit.", + "We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "Doporučujeme vám projít procesem ověřování pro všechna zařízení, abyste si potvrdili, že patří jejich pravým vlastníkům, ale pokud si to přejete, můžete zprávu znovu odeslat bez ověřování.", + "\"%(RoomName)s\" contains devices that you haven't seen before.": "V místnosti \"%(RoomName)s\" jsou zařízení s kterými jste dosud nikdy nekomunikovali.", + "Unknown devices": "Neznámá zařízení", + "Private Chat": "Soukromý chat", + "Public Chat": "Veřejný chat", + "Topic": "Téma", + "Make this room private": "Nastavit místnost jako soukromou", + "Share message history with new users": "Sdílet historii zpráv s novými uživateli", + "Encrypt room": "Zašifrovat místnost", + "You must register to use this functionality": "Musíte být zaregistrovaný pokud chcete využívat této funkce", + "You must join the room to see its files": "Musíte vstoupit do místnosti pokud chcete soubory zobrazit", + "

HTML for your community's page

\n

\n Use the long description to introduce new members to the community, or distribute\n some important links\n

\n

\n You can even use 'img' tags\n

\n": "

HTML kód vaší skupiny

\n

\n Pomocí dlouhého popisu představte skupinu novým členům anebo uvěďte \n nějaké důležité odkazy\n

\n

\n Můžete používat i HTML 'img' značky\n

\n", + "Add rooms to the community summary": "Přidat místnosti do přehledu skupiny", + "Which rooms would you like to add to this summary?": "Které místnosti se přejete přidat do tohoto přehledu?", + "Add to summary": "Přidat do přehledu", + "Failed to add the following rooms to the summary of %(groupId)s:": "Do přehledu skupiny %(groupId)s se nepodařilo přidat následující místnosti:", + "Add a Room": "Přidat místnost", + "Failed to remove the room from the summary of %(groupId)s": "Z přehledu skupiny %(groupId)s se nepodařilo odstranit místnost", + "The room '%(roomName)s' could not be removed from the summary.": "Nelze odstranit místnost '%(roomName)s' z přehledu.", + "Add users to the community summary": "Přidat uživatele do přehledu skupiny", + "Who would you like to add to this summary?": "Koho si přejete přidat do seznamu?", + "Failed to add the following users to the summary of %(groupId)s:": "Do souhrnného seznamu skupiny %(groupId)s se nepodařilo přidat následující uživatele:", + "Add a User": "Přidat uživatele", + "Failed to remove a user from the summary of %(groupId)s": "Ze souhrnného seznamu skupiny %(groupId)s se nepodařilo odstranit uživatele", + "The user '%(displayName)s' could not be removed from the summary.": "Nelze odstranit uživatele '%(displayName)s' ze souhrnného seznamu.", + "Unable to accept invite": "Nelze přijmout pozvání", + "Unable to reject invite": "Nelze odmítnout pozvání", + "Community Settings": "Nastavení skupiny", + "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Tyto místnosti se zobrazují všem členům na stránce skupiny. Členové skupiny mohou vstoupit do místnosti kliknutím.", + "Featured Rooms:": "Hlavní místnosti:", + "Featured Users:": "Významní uživatelé:", + "%(inviter)s has invited you to join this community": "%(inviter)s vás pozval ke vstupu do této místnosti", + "You are an administrator of this community": "Jste správcem této skupiny", + "You are a member of this community": "Jste členem této skupiny", + "Your community hasn't got a Long Description, a HTML page to show to community members.
Click here to open settings and give it one!": "Vaše skupina nemá vyplněný dlouhý popis, který je součástí HTML stránky skupiny a která se zobrazuje jejím členům.
Kliknutím zde otevřete nastavení, kde ho můžete doplnit!", + "Long Description (HTML)": "Dlouhý popis (HTML)", + "Description": "Popis", + "Community %(groupId)s not found": "Skupina %(groupId)s nenalezena", + "This Home server does not support communities": "Tento domácí server nepodporuje skupiny", + "Reject invitation": "Odmítnout pozvání", + "Signed Out": "Jste odhlášeni", + "Your Communities": "Vaše skupiny", + "Error whilst fetching joined communities": "Při získávání vašich skupin se vyskytla chyba", + "Create a new community": "Vytvořit novou skupinu", + "Create a community to group together users and rooms! Build a custom homepage to mark out your space in the Matrix universe.": "Vytvořte skupinu s cílem seskupit uživatele a místnosti! Vytvořte si vlastní domovskou stránku a vymezte tak váš prostor ve světe Matrix.", + "Join an existing community": "Vstoupit do existující skupiny", + "To join an existing community you'll have to know its community identifier; this will look something like +example:matrix.org.": "Aby jste mohli vstoupit do existující skupiny, musíte znát její identifikátor; Měl by vypadat asi takto +priklad:matrix.org.", + "You have no visible notifications": "Nejsou dostupná žádná oznámení", + "Connectivity to the server has been lost.": "Spojení se serverem bylo přerušené.", + "Sent messages will be stored until your connection has returned.": "Odeslané zprávy zůstanou uložené, dokud se spojení znovu neobnoví.", + "Resend all or cancel all now. You can also select individual messages to resend or cancel.": "Znovu odeslat vše nebo zrušit vše nyní. Můžete také znovu odeslat anebo zrušit odesílání jednotlivých zpráv zvlášť.", + "Active call": "Aktivní hovor", + "There's no one else here! Would you like to invite others or stop warning about the empty room?": "Kromě vás není v této místnosti nikdo jiný! Přejete si Pozvat další anebo Přestat upozorňovat na prázdnou místnost?", + "Message not sent due to unknown devices being present": "Zpráva nebyla odeslána vzhledem k nalezeným neznámým zařízením", + "Room": "Místnost", + "Failed to load timeline position": "Nepodařilo se načíst pozici na časové ose", + "Light theme": "Světlý motiv", + "Dark theme": "Tmavý motiv", + "Status.im theme": "Status.im motivu", + "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "S cílem posílit zabezpečení se všechny E2E šifrovací klíče při odhlášení odstraní z tohoto prohlížeče. Pokud chcete dostupnou historii šifrovaných konverzací i při opětovném přihlášení, prosím stáhněte si a bezpečně uložte klíče vašich místností.", + "Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them": "Vaše heslo bylo úspěšně změněno. Na ostatních zařízeních se vám již nebudou zobrazovat okamžitá oznámení do té chvíle než se na nich znovu přihlásíte", + "Remove Contact Information?": "Odstranit kontaktní informace?", + "Remove %(threePid)s?": "Odstranit %(threePid)s?", + "Refer a friend to Riot:": "Doporučit Riot známému:", + "Autocomplete Delay (ms):": "Zpoždění automatického dokončování (ms):", + "Ignored Users": "Ignorovaní uživatelé", + "Analytics": "Analytické údaje", + "Riot collects anonymous analytics to allow us to improve the application.": "Riot sbírá anonymní analytické údaje, které nám umožňují aplikaci dále zlepšovat.", + "Labs": "Experimentální funkce", + "Reject all %(invitedRooms)s invites": "Odmítnutí všech %(invitedRooms)s pozvání", + "Desktop specific": "Specifické pro Desktop zobrazení", + "Start automatically after system login": "Zahájit automaticky po přihlášení do systému", + "No media permissions": "Žádná oprávnění k médiím", + "You may need to manually permit Riot to access your microphone/webcam": "Je možné, že budete potřebovat manuálně povolit Riot přístup k mikrofónu/webkameře", + "Missing Media Permissions, click here to request.": "Kliknutím sem získáte chybějící oprávnění pro přístup k mediálním zařízením.", + "Profile": "Profil", + "To return to your account in future you need to set a password": "Pokud se v budoucnu chcete vrátit k vašemu účtu je třeba si nyní nastavit heslo", + "The email address linked to your account must be entered.": "Musíte zadat emailovou adresu spojenou s vaším účtem.", + "Resetting password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Změna hesla v této chvílí povede k resetu end-to-end šifrovacích klíčů na všech zařízení a nečitelnosti šifrovaných konverzací pokud si klíče vašich místností předem nestáhnete a následně nenaimportujete zpět. Tato funkce bude v budoucnu vylepšena.", + "An email has been sent to %(emailAddress)s. Once you've followed the link it contains, click below.": "Na adresu %(emailAddress)s byla odeslána zpráva. Potom, co přejdete na odkaz z této zprávy, klikněte níže.", + "You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "Byli jste odhlášení ze všech zařízení a nebudete již dále dostávat okamžitá oznámení. Povolíte je tak, že se znovu přihlásíte na každém zařízení zvláš'ť", + "Please note you are logging into the %(hs)s server, not matrix.org.": "Upozornění: právě se přihlašujete na server %(hs)s, a nikoliv na server matrix.org.", + "This homeserver doesn't offer any login flows which are supported by this client.": "Tento domácí server nenabízí žádné přihlašovací toky podporované touto službou/klientem.", + "Sign in to get started": "Začněte přihlášením", + "Set a display name:": "Nastavit zobrazované jméno:", + "Upload an avatar:": "Nahrát avatar:", + "This server does not support authentication with a phone number.": "Tento server nepodporuje ověření telefonním číslem.", + "Missing password.": "Chybí heslo.", + "Passwords don't match.": "Hesla se neshodují.", + "Password too short (min %(MIN_PASSWORD_LENGTH)s).": "Heslo je velmi krátké (min %(MIN_PASSWORD_LENGTH)s znaků).", + "This doesn't look like a valid email address.": "Zdá se, že toto není platná emailová adresa.", + "This doesn't look like a valid phone number.": "Zdá se, že toto není platné telefonní číslo.", + "An unknown error occurred.": "Vyskytla se neznámá chyba.", + "I already have an account": "Už mám účet", + "Deops user with given id": "Zruší stav moderátor uživateli se zadaným ID", + "Searches DuckDuckGo for results": "Vyhledá výsledky na DuckDuckGo", + "Verifies a user, device, and pubkey tuple": "Ověří zadané údaje uživatele, zařízení a veřejný klíč", + "Ignores a user, hiding their messages from you": "Ignoruje uživatele a skryje všechny jeho zprávy", + "Stops ignoring a user, showing their messages going forward": "Přestane ignorovat uživatele a začne zobrazovat jeho zprávy", + "Notify the whole room": "Oznámení pro celou místnost", + "Room Notification": "Oznámení místnosti", + "Curve25519 identity key": "Klíč totožnosti Curve25519", + "Claimed Ed25519 fingerprint key": "Údajný klíč s otiskem prstu Ed25519", + "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "Tento proces vás provede importem šifrovacích klíčů, které jste si stáhli z jiného Matrix klienta. Po úspěšném naimportování budete v tomto klientovi moci dešifrovat všechny zprávy, které jste mohli dešifrovat v původním klientovi.", + "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "Stažený soubor je chráněn heslem. Soubor můžete naimportovat pouze pokud zadáte odpovídající heslo." } From f490adfdd9000b4d4f2fc9b1ab3590cb050e193d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Tue, 28 Nov 2017 17:51:41 +0000 Subject: [PATCH 074/927] Translated using Weblate (French) Currently translated at 100.0% (941 of 941 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index b64a998b61..7b3f29ade5 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -1027,7 +1027,7 @@ "Select devices": "Sélectionner les appareils", "Something went wrong when trying to get your communities.": "Une erreur est survenue lors de l'obtention de vos communautés.", "This homeserver doesn't offer any login flows which are supported by this client.": "Ce serveur d'accueil n'offre aucun flux compatible avec ce client.", - "Flair": "Talent", + "Flair": "Talents", "Showing flair for these communities:": "Montre les talents pour ces communautés :", "This room is not showing flair for any communities": "Ce salon n'affiche de talent pour aucune communauté", "Flair will appear if enabled in room settings": "Les talents apparaîtront s'ils sont activés dans les paramètres du salon", From cb5c9f2c5ae34e019d34b121e1ee32ce4ab7c6c0 Mon Sep 17 00:00:00 2001 From: Stefan Parviainen Date: Wed, 29 Nov 2017 21:13:48 +0100 Subject: [PATCH 075/927] Make Dialogs more accessible Signed-off-by: Stefan Parviainen --- src/components/views/dialogs/BaseDialog.js | 8 ++++++-- src/components/views/dialogs/QuestionDialog.js | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/components/views/dialogs/BaseDialog.js b/src/components/views/dialogs/BaseDialog.js index 295bb21ea1..aec9af4e98 100644 --- a/src/components/views/dialogs/BaseDialog.js +++ b/src/components/views/dialogs/BaseDialog.js @@ -45,6 +45,10 @@ export default React.createClass({ // children should be the content of the dialog children: React.PropTypes.node, + + // Id of content element + // If provided, this is used to add a aria-describedby attribute + contentId: React.PropTypes.string }, _onKeyDown: function(e) { @@ -69,13 +73,13 @@ export default React.createClass({ const TintableSvg = sdk.getComponent("elements.TintableSvg"); return ( -
+
-
+
{ this.props.title }
{ this.props.children } diff --git a/src/components/views/dialogs/QuestionDialog.js b/src/components/views/dialogs/QuestionDialog.js index 339b284e2f..db20fd00ed 100644 --- a/src/components/views/dialogs/QuestionDialog.js +++ b/src/components/views/dialogs/QuestionDialog.js @@ -66,6 +66,7 @@ export default React.createClass({
{ this.props.description } From 6e3c12e754f537c832cc4c9f3fe340547525525c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Tue, 28 Nov 2017 17:51:41 +0000 Subject: [PATCH 076/927] Translated using Weblate (French) Currently translated at 100.0% (941 of 941 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index 7b3f29ade5..fe248746bf 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -1032,5 +1032,6 @@ "This room is not showing flair for any communities": "Ce salon n'affiche de talent pour aucune communauté", "Flair will appear if enabled in room settings": "Les talents apparaîtront s'ils sont activés dans les paramètres du salon", "Flair will not appear": "Les talents n'apparaîtront pas", - "Display your community flair in rooms configured to show it.": "Afficher vos talents de communauté dans les salons configurés pour les afficher." + "Display your community flair in rooms configured to show it.": "Afficher vos talents de communauté dans les salons configurés pour les afficher.", + "Tag Panel": "Panneau des étiquettes" } From 437a440bdfa17553e83e5d7e762b7494bb803ddb Mon Sep 17 00:00:00 2001 From: Stefan Parviainen Date: Thu, 30 Nov 2017 08:32:18 +0100 Subject: [PATCH 077/927] Add missing id Signed-off-by: Stefan Parviainen --- src/components/views/dialogs/QuestionDialog.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/dialogs/QuestionDialog.js b/src/components/views/dialogs/QuestionDialog.js index db20fd00ed..92051a0df7 100644 --- a/src/components/views/dialogs/QuestionDialog.js +++ b/src/components/views/dialogs/QuestionDialog.js @@ -68,7 +68,7 @@ export default React.createClass({ title={this.props.title} contentId='mx_Dialog_content' > -
+
{ this.props.description }
From 4be057ee2caa3f28d858f1ad24af7dcbddc695fc Mon Sep 17 00:00:00 2001 From: Szimszon Date: Thu, 30 Nov 2017 07:51:15 +0000 Subject: [PATCH 078/927] Translated using Weblate (Hungarian) Currently translated at 100.0% (941 of 941 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 4800872ae5..840f12381c 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -1025,5 +1025,17 @@ "Online for %(duration)s": "%(duration)s óta elérhető", "Idle for %(duration)s": "%(duration)s óta tétlen", "Offline for %(duration)s": "%(duration)s óta elérhetetlen", - "Unknown for %(duration)s": "%(duration)s óta az állapota ismeretlen" + "Unknown for %(duration)s": "%(duration)s óta az állapota ismeretlen", + "Delete %(count)s devices|other": "%(count)s darab eszköz törlése", + "Delete %(count)s devices|one": "Eszköz törlése", + "Select devices": "Eszköz kiválasztása", + "Flair": "Jelvény", + "Showing flair for these communities:": "Ezekben a közösségekben mutassa a jelvényt:", + "This room is not showing flair for any communities": "Ez a szoba nem mutat jelvényt egyetlen közösséghez sem", + "Flair will appear if enabled in room settings": "Ha a szoba beállításai megengedik akkor jelennek meg a jelvények", + "Flair will not appear": "Jelvények nem jelennek meg", + "Something went wrong when trying to get your communities.": "Valami nem sikerült a közösségeid elérésénél.", + "Display your community flair in rooms configured to show it.": "Közösségi jelvényeid megjelenítése azokban a szobákban ahol ez engedélyezett.", + "This homeserver doesn't offer any login flows which are supported by this client.": "Ez a saját szerver egyetlen bejelentkezési metódust sem támogat amit ez a kliens ismer.", + "Tag Panel": "Címke panel" } From 09aaafdf2b73f7177bdbd69dde1aaa5570409794 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20Koreck=C3=BD?= Date: Wed, 29 Nov 2017 11:50:58 +0000 Subject: [PATCH 079/927] Translated using Weblate (Czech) Currently translated at 100.0% (941 of 941 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/cs/ --- src/i18n/strings/cs.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/cs.json b/src/i18n/strings/cs.json index b29aedb4db..8380afbc83 100644 --- a/src/i18n/strings/cs.json +++ b/src/i18n/strings/cs.json @@ -978,5 +978,6 @@ "Curve25519 identity key": "Klíč totožnosti Curve25519", "Claimed Ed25519 fingerprint key": "Údajný klíč s otiskem prstu Ed25519", "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "Tento proces vás provede importem šifrovacích klíčů, které jste si stáhli z jiného Matrix klienta. Po úspěšném naimportování budete v tomto klientovi moci dešifrovat všechny zprávy, které jste mohli dešifrovat v původním klientovi.", - "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "Stažený soubor je chráněn heslem. Soubor můžete naimportovat pouze pokud zadáte odpovídající heslo." + "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "Stažený soubor je chráněn heslem. Soubor můžete naimportovat pouze pokud zadáte odpovídající heslo.", + "Tag Panel": "Připnout panel" } From 26c6c25a4cce7a87799ffd52ec86b41a418f6192 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Sun, 3 Dec 2017 11:23:44 +0000 Subject: [PATCH 080/927] Add dom-to-image dep. --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index b443b4c72a..dc526b7105 100644 --- a/package.json +++ b/package.json @@ -58,6 +58,7 @@ "classnames": "^2.1.2", "commonmark": "^0.27.0", "counterpart": "^0.18.0", + "dom-to-image": "^2.6.0", "draft-js": "^0.11.0-alpha", "draft-js-export-html": "^0.6.0", "draft-js-export-markdown": "^0.3.0", From 3a89b90e57c7e2b13a2fe623e71495da2e0603ca Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Sun, 3 Dec 2017 11:25:15 +0000 Subject: [PATCH 081/927] Add stub handler for image snapshot --- src/components/views/elements/AppTile.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index a005406133..db722bd66d 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -221,6 +221,10 @@ export default React.createClass({ }, "mx_IntegrationsManager"); }, + _onSnapshotClick(e) { + console.log("Snapshot widget ID ", this.props.id); + }, + /* If user has permission to modify widgets, delete the widget, * otherwise revoke access for the widget to load in the user's browser */ @@ -379,11 +383,25 @@ export default React.createClass({ deleteClasses += ' mx_AppTileMenuBarWidgetDelete'; } + // Picture snapshot + const showPictureSnapshotButton = true; // FIXME - Make this dynamic + const showPictureSnapshotIcon = 'img/camera_green.svg'; + return (
{ this.formatAppTileName() } + { /* Snapshot widget */ } + { showPictureSnapshotButton && } + { /* Edit widget */ } { showEditButton && Date: Sun, 3 Dec 2017 19:44:59 +0000 Subject: [PATCH 082/927] Workings for future posterity - Can't access iframe content from parent. iframe needs to initiate. Postmessage data up the stack. --- src/components/structures/RoomView.js | 3 +++ src/components/views/elements/AppTile.js | 22 +++++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 1fda05fb76..cf3320b607 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -468,6 +468,9 @@ module.exports = React.createClass({ unsentMessageError: this._getUnsentMessageError(this.state.room), }); break; + case 'picture_snapshot': + this.uploadFile(payload.file); + break; case 'notifier_enabled': case 'upload_failed': case 'upload_started': diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index db722bd66d..a0eb7efe52 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -32,6 +32,7 @@ import AppWarning from './AppWarning'; import MessageSpinner from './MessageSpinner'; import WidgetUtils from '../../../WidgetUtils'; import dis from '../../../dispatcher'; +import domtoimage from 'dom-to-image'; const ALLOWED_APP_URL_SCHEMES = ['https:', 'http:']; @@ -222,7 +223,14 @@ export default React.createClass({ }, _onSnapshotClick(e) { - console.log("Snapshot widget ID ", this.props.id); + const iframe = this.refs.appFrame; + domtoimage.toPng(iframe).then(function(dataUrl) { + console.log("Image data URL:", dataUrl); + dis.dispatch({ + action: 'picture_snapshot', + file: dataURLtoBlob(dataUrl), + }, true); + }); }, /* If user has permission to modify widgets, delete the widget, @@ -428,3 +436,15 @@ export default React.createClass({ ); }, }); + +function dataURLtoBlob(dataurl) { + const arr = dataurl.split(','); + const mime = arr[0].match(/:(.*?);/)[1]; + const bstr = atob(arr[1]); + let n = bstr.length; + const u8arr = new Uint8Array(n); + while (n--) { + u8arr[n] = bstr.charCodeAt(n); + } + return new Blob([u8arr], {type: mime}); +} From 5ccbcf02e200aa8348a7415dda40a0c73e35937d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Sun, 3 Dec 2017 21:38:21 +0100 Subject: [PATCH 083/927] Several changes improving accessibility of the dialogs - Wrapped all the modals inside a react-focus-trap component disabling keyboard navigation outside the modal dialogs - Disabled our custom key handling at dialog level. Cancelling on esc key is now handled via FocusTrap component. - Removed onEnter prop from the BaseDialog component. Dialogs that submit data all now embed a form with onSubmit handler. And since keyboard focus is now managed better via FocusTrap it no longer makes sense for the other dialog types. Fixes https://github.com/vector-im/riot-web/issues/5736 - Set aria-hidden on the matrixChat outer node when showing dialogs to disable navigating outside the modals by using screen reader specific features. --- package.json | 1 + src/Modal.js | 6 +- src/components/views/dialogs/BaseDialog.js | 26 ++++----- .../views/dialogs/ConfirmUserActionDialog.js | 4 +- .../views/dialogs/CreateGroupDialog.js | 1 - .../views/dialogs/CreateRoomDialog.js | 57 +++++++++---------- .../views/dialogs/QuestionDialog.js | 1 - .../views/dialogs/TextInputDialog.js | 29 +++++----- 8 files changed, 60 insertions(+), 65 deletions(-) diff --git a/package.json b/package.json index b443b4c72a..46517230a7 100644 --- a/package.json +++ b/package.json @@ -78,6 +78,7 @@ "react": "^15.4.0", "react-addons-css-transition-group": "15.3.2", "react-dom": "^15.4.0", + "react-focus-trap": "^2.5.0", "react-gemini-scrollbar": "matrix-org/react-gemini-scrollbar#5e97aef", "sanitize-html": "^1.14.1", "text-encoding-utf-8": "^1.0.1", diff --git a/src/Modal.js b/src/Modal.js index 68d75d1ff1..daf66a37de 100644 --- a/src/Modal.js +++ b/src/Modal.js @@ -19,6 +19,7 @@ limitations under the License. const React = require('react'); const ReactDOM = require('react-dom'); +import FocusTrap from 'react-focus-trap'; import Analytics from './Analytics'; import sdk from './index'; @@ -164,6 +165,7 @@ class ModalManager { ); modal.onFinished = props ? props.onFinished : null; modal.className = className; + modal.closeDialog = closeDialog; this._modals.unshift(modal); @@ -194,9 +196,9 @@ class ModalManager { const modal = this._modals[0]; const dialog = (
-
+ { modal.elem } -
+
); diff --git a/src/components/views/dialogs/BaseDialog.js b/src/components/views/dialogs/BaseDialog.js index aec9af4e98..1f29f2d1f4 100644 --- a/src/components/views/dialogs/BaseDialog.js +++ b/src/components/views/dialogs/BaseDialog.js @@ -33,9 +33,6 @@ export default React.createClass({ // onFinished callback to call when Escape is pressed onFinished: React.PropTypes.func.isRequired, - // callback to call when Enter is pressed - onEnterPressed: React.PropTypes.func, - // CSS class to apply to dialog div className: React.PropTypes.string, @@ -51,17 +48,16 @@ export default React.createClass({ contentId: React.PropTypes.string }, - _onKeyDown: function(e) { - if (e.keyCode === KeyCode.ESCAPE) { - e.stopPropagation(); - e.preventDefault(); - this.props.onFinished(); - } else if (e.keyCode === KeyCode.ENTER) { - if (this.props.onEnterPressed) { - e.stopPropagation(); - e.preventDefault(); - this.props.onEnterPressed(e); - } + componentDidMount: function() { + this.applicationNode = document.getElementById('matrixchat'); + if (this.applicationNode) { + this.applicationNode.setAttribute('aria-hidden', 'true'); + } + }, + + componentWillUnmount: function() { + if (this.applicationNode) { + this.applicationNode.setAttribute('aria-hidden', 'false'); } }, @@ -73,7 +69,7 @@ export default React.createClass({ const TintableSvg = sdk.getComponent("elements.TintableSvg"); return ( -
+
diff --git a/src/components/views/dialogs/ConfirmUserActionDialog.js b/src/components/views/dialogs/ConfirmUserActionDialog.js index 78d084b709..1c246a580b 100644 --- a/src/components/views/dialogs/ConfirmUserActionDialog.js +++ b/src/components/views/dialogs/ConfirmUserActionDialog.js @@ -116,10 +116,10 @@ export default React.createClass({ return ( -
+
{ avatar }
diff --git a/src/components/views/dialogs/CreateGroupDialog.js b/src/components/views/dialogs/CreateGroupDialog.js index 168fe75947..8e262a6e51 100644 --- a/src/components/views/dialogs/CreateGroupDialog.js +++ b/src/components/views/dialogs/CreateGroupDialog.js @@ -116,7 +116,6 @@ export default React.createClass({ return (
diff --git a/src/components/views/dialogs/CreateRoomDialog.js b/src/components/views/dialogs/CreateRoomDialog.js index f7be47b3eb..f5a5f87b72 100644 --- a/src/components/views/dialogs/CreateRoomDialog.js +++ b/src/components/views/dialogs/CreateRoomDialog.js @@ -43,38 +43,37 @@ export default React.createClass({ const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); return ( -
-
- -
-
- -
-
- -
- { _t('Advanced options') } -
- - + +
+
+
-
-
-
- - -
+
+ +
+
+ +
+ { _t('Advanced options') } +
+ + +
+
+
+
+ + +
+ ); }, diff --git a/src/components/views/dialogs/QuestionDialog.js b/src/components/views/dialogs/QuestionDialog.js index 92051a0df7..41733470a1 100644 --- a/src/components/views/dialogs/QuestionDialog.js +++ b/src/components/views/dialogs/QuestionDialog.js @@ -64,7 +64,6 @@ export default React.createClass({ }); return ( diff --git a/src/components/views/dialogs/TextInputDialog.js b/src/components/views/dialogs/TextInputDialog.js index 5ea4191e5e..907848b3b8 100644 --- a/src/components/views/dialogs/TextInputDialog.js +++ b/src/components/views/dialogs/TextInputDialog.js @@ -60,25 +60,24 @@ export default React.createClass({ const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); return ( -
-
- +
+
+
+ +
+
+ +
-
- +
+ +
-
-
- - -
+
); }, From c0d9f819283678867777d09c5c35dd93b50c3700 Mon Sep 17 00:00:00 2001 From: Tirifto Date: Sun, 3 Dec 2017 14:15:06 +0000 Subject: [PATCH 084/927] Translated using Weblate (Czech) Currently translated at 100.0% (941 of 941 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/cs/ --- src/i18n/strings/cs.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/i18n/strings/cs.json b/src/i18n/strings/cs.json index 8380afbc83..860b50b8d9 100644 --- a/src/i18n/strings/cs.json +++ b/src/i18n/strings/cs.json @@ -109,7 +109,7 @@ "%(senderName)s changed their profile picture.": "%(senderName)s změnil/a svůj profilový obrázek.", "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s změnil/a název místnosti na %(roomName)s.", "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s odstranil/a název místnosti.", - "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s změnil/a téma na \"%(topic)s\".", + "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s změnil/a téma na „%(topic)s“.", "Changes to who can read history will only apply to future messages in this room": "Změny viditelnosti historie budou platné až pro budoucí zprávy v této místnosti", "Changes your display nickname": "Změní vaši zobrazovanou přezdívku", "Changes colour scheme of current room": "Změní barevné schéma aktuální místnosti", @@ -483,7 +483,7 @@ "Unpin Message": "Odepnout zprávu", "Ignored user": "Ignorovaný uživatel", "Unignored user": "Odignorovaný uživatel", - "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "VAROVÁNÍ: OVĚŘENÍ KLÍČE SELHALO! Podepisovací klíč uživatele %(userId)s a zařízení %(deviceId)s je \"%(fprint)s\", což nesouhlasí s dodaným klíčem \"%(fingerprint)s\". Toto může znamenat, že vaše komunikace je odposlouchávána!", + "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "VAROVÁNÍ: OVĚŘENÍ KLÍČE SELHALO! Podepisovací klíč uživatele %(userId)s a zařízení %(deviceId)s je „%(fprint)s“, což nesouhlasí s dodaným klíčem „%(fingerprint)s“. Toto může znamenat, že vaše komunikace je odposlouchávána!", "Reason": "Důvod", "VoIP conference started.": "VoIP konference započata.", "VoIP conference finished.": "VoIP konference ukončena.", @@ -875,7 +875,7 @@ "%(oneUser)sjoined %(count)s times|other": "%(oneUser)s %(count)s krát vstoupil", "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "Neověřená zařízení jsou v této chvíli na černé listině; pokud chcete zasílat zprávy na tato zařízení, musíte je nejdříve ověřit.", "We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "Doporučujeme vám projít procesem ověřování pro všechna zařízení, abyste si potvrdili, že patří jejich pravým vlastníkům, ale pokud si to přejete, můžete zprávu znovu odeslat bez ověřování.", - "\"%(RoomName)s\" contains devices that you haven't seen before.": "V místnosti \"%(RoomName)s\" jsou zařízení s kterými jste dosud nikdy nekomunikovali.", + "\"%(RoomName)s\" contains devices that you haven't seen before.": "V místnosti „%(RoomName)s“ jsou zařízení s kterými jste dosud nikdy nekomunikovali.", "Unknown devices": "Neznámá zařízení", "Private Chat": "Soukromý chat", "Public Chat": "Veřejný chat", From e56584e39a8f53cf9f8188fbe119a31b4bc44956 Mon Sep 17 00:00:00 2001 From: Tirifto Date: Sun, 3 Dec 2017 13:59:37 +0000 Subject: [PATCH 085/927] Translated using Weblate (Esperanto) Currently translated at 19.0% (179 of 941 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eo/ --- src/i18n/strings/eo.json | 122 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 121 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/eo.json b/src/i18n/strings/eo.json index 4176d41ba0..96a15c5a2d 100644 --- a/src/i18n/strings/eo.json +++ b/src/i18n/strings/eo.json @@ -57,5 +57,125 @@ "Add rooms to the community": "Aldoni ĉambrojn al la komunumo", "Room name or alias": "Nomo aŭ kromnomo de ĉambro", "Add to community": "Aldoni al komunumo", - "Failed to invite the following users to %(groupId)s:": "Malsukcesis inviti jenajn uzantojn al %(groupId)s:" + "Failed to invite the following users to %(groupId)s:": "Malsukcesis inviti jenajn uzantojn al %(groupId)s:", + "Failed to invite users to community": "Malsukcesis inviti novajn uzantojn al komunumo", + "Failed to invite users to %(groupId)s": "Malsukcesis inviti uzantojn al %(groupId)s", + "Failed to add the following rooms to %(groupId)s:": "Malsukcesis aldoni jenajn ĉambrojn al %(groupId)s:", + "Riot does not have permission to send you notifications - please check your browser settings": "Riot ne havas permeson sciigi vin – bonvolu kontroli la agordojn de via foliumilo", + "Riot was not given permission to send notifications - please try again": "Riot ne ricevis permeson sendi sciigojn – bonvolu reprovi", + "Unable to enable Notifications": "Sciigoj ne sendeblas", + "This email address was not found": "Tiu ĉi retpoŝtadreso ne troviĝis", + "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Via retpoŝtareso ŝajne ne ligiĝas al Matrix-identigaĵo sur tiu ĉi hejmservilo.", + "Default": "Norma", + "Restricted": "Limigita", + "Moderator": "Ĉambrestro", + "Admin": "Administranto", + "Start a chat": "Komenci babilon", + "Who would you like to communicate with?": "Kun kiu vi volas komuniki?", + "Email, name or matrix ID": "Retpoŝtadreso, nomo, aŭ Matrix-identigaĵo", + "Start Chat": "Komenci babilon", + "Invite new room members": "Inviti novajn ĉambranojn", + "Who would you like to add to this room?": "Kiun vi ŝatus aldoni al tiu ĉi ĉambro?", + "Send Invites": "Sendi invitojn", + "Failed to invite user": "Malsukcesis inviti uzanton", + "Operation failed": "Ago malsukcesis", + "Failed to invite": "Invito malsukcesis", + "Failed to invite the following users to the %(roomName)s room:": "Malsukcesis inviti la jenajn uzantojn al la ĉambro %(roomName)s:", + "You need to be logged in.": "Vi devas saluti.", + "You need to be able to invite users to do that.": "Vi bezonas permeson inviti uzantojn por tio.", + "Unable to create widget.": "Fenestraĵo ne kreeblas.", + "Failed to send request.": "Malsukcesis sendi peton.", + "This room is not recognised.": "Ĉi tiu ĉambro ne estas rekonita.", + "Power level must be positive integer.": "Nivelo de potenco devas esti entjero pozitiva.", + "You are not in this room.": "Vi ne estas en tiu ĉi ĉambro.", + "You do not have permission to do that in this room.": "Vi ne havas permeson fari tion en tiu ĉi ĉambro.", + "Missing room_id in request": "En peto mankas «room_id»", + "Must be viewing a room": "Necesas vidi ĉambron", + "Room %(roomId)s not visible": "Ĉambro %(roomId)s ne videblas", + "Missing user_id in request": "En peto mankas «user_id»", + "Failed to lookup current room": "Malsukcesis trovi nunan ĉambron", + "Usage": "Uzo", + "/ddg is not a command": "/ddg ne estas komando", + "To use it, just wait for autocomplete results to load and tab through them.": "Por uzi ĝin, atendu aperon de sugestaj rezultoj, kaj tabu tra ili.", + "Unrecognised room alias:": "Nerekonita ĉambra alinomo:", + "Ignored user": "Malatentata uzanto", + "You are now ignoring %(userId)s": "Vi nun malatentas uzanton %(userId)s", + "Unignored user": "Reatentata uzanto", + "You are no longer ignoring %(userId)s": "Vi nun reatentas uzanton %(userId)s", + "Unknown (user, device) pair:": "Nekonata duopo (uzanto, aparato):", + "Device already verified!": "Aparato jam kontroliĝis!", + "WARNING: Device already verified, but keys do NOT MATCH!": "AVERTO: Aparato jam kontroliĝis, sed la ŝlosiloj NE KONGRUAS!", + "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "AVERTO: KONTROLO DE ŜLOSILO MALSUKCESIS! Subskriba ŝlosilo por %(userId)s kaj aparato%(deviceId)s estas «%(fprint)s», kiu ne kongruas kun la donita ŝlosilo «%(fingerprint)s». Eble do via komuniko estas subaŭskultata!", + "Verified key": "Kontrolita ŝlosilo", + "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "La donita subskriba ŝlosilo kongruas kun la ŝlosilo ricevita de %(userId)s por ĝia aparato %(deviceId)s. Aparato markita kiel kontrolita.", + "Unrecognised command:": "Nerekonita komando:", + "Reason": "Kialo", + "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s akceptis la inviton por %(displayName)s.", + "%(targetName)s accepted an invitation.": "%(targetName)s akceptis inviton.", + "%(senderName)s requested a VoIP conference.": "%(senderName)s petis rettelefonan vokon.", + "%(senderName)s invited %(targetName)s.": "%(senderName)s invitis uzanton %(targetName)s.", + "%(senderName)s banned %(targetName)s.": "%(senderName)s forbaris uzanton %(targetName)s.", + "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s ŝanĝis sian vidigan nomon de %(oldDisplayName)s al %(displayName)s.", + "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s agordis sian vidigan nomon al %(displayName)s.", + "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s forigis sian vidigan nomon (%(oldDisplayName)s).", + "%(senderName)s removed their profile picture.": "%(senderName)s forigis sian profilbildon.", + "%(senderName)s changed their profile picture.": "%(senderName)s ŝanĝis sian profilbildon.", + "%(senderName)s set a profile picture.": "%(senderName)s agordis profilbildon.", + "VoIP conference started.": "Rettelefona voko komenciĝis.", + "%(targetName)s joined the room.": "%(targetName)s venis en la ĉambron.", + "VoIP conference finished.": "Rettelefona voko finiĝis.", + "%(targetName)s rejected the invitation.": "%(targetName)s rifuzis la inviton.", + "%(targetName)s left the room.": "%(targetName)s forlasis la ĉambron.", + "%(senderName)s unbanned %(targetName)s.": "%(senderName)s malbaris uzanton %(targetName)s.", + "%(senderName)s kicked %(targetName)s.": "%(senderName)s forpelis uzanton %(targetName)s.", + "%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s nuligis inviton por %(targetName)s.", + "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s ŝanĝis la temon al «%(topic)s».", + "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s forigis nomon de la ĉambro.", + "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s ŝanĝis nomon de la ĉambro al %(roomName)s.", + "%(senderDisplayName)s sent an image.": "%(senderDisplayName)s sendis bildon.", + "Someone": "Iu", + "(not supported by this browser)": "(nesubtenata de tiu ĉi foliumilo)", + "%(senderName)s answered the call.": "%(senderName)s akceptis la vokon.", + "(could not connect media)": "(aŭdvidaĵoj ne kunigeblis)", + "(no answer)": "(sen respondo)", + "(unknown failure: %(reason)s)": "(nekonata eraro: %(reason)s)", + "%(senderName)s ended the call.": "%(senderName)s finis la vokon.", + "%(senderName)s placed a %(callType)s call.": "%(senderName)s faris vokon de speco: %(callType)s.", + "%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s sendis ĉambran inviton al %(targetDisplayName)s.", + "%(senderName)s made future room history visible to all room members, from the point they are invited.": "%(senderName)s videbligis estontan historion de la ĉambro al ĉiuj ĉambranoj, de la tempo de invito.", + "%(senderName)s made future room history visible to all room members, from the point they joined.": "%(senderName)s videbligis estontan historion de la ĉambro al ĉiuj ĉambranoj, de la tempo de aliĝo.", + "%(senderName)s made future room history visible to all room members.": "%(senderName)s videbligis estontan historion de la ĉambro al ĉiuj ĉambranoj.", + "%(senderName)s made future room history visible to anyone.": "%(senderName)s videbligis estontan historion de la ĉambro al ĉiuj.", + "%(senderName)s made future room history visible to unknown (%(visibility)s).": "%(senderName)s videbligis estontan historion de la ĉambro al nekonatoj (%(visibility)s).", + "%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s ŝaltis ĝiscelan ĉifradon (algoritmo: %(algorithm)s).", + "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s de %(fromPowerLevel)s al %(toPowerLevel)s", + "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s ŝanĝis la potencan nivelon de %(powerLevelDiffText)s.", + "%(senderName)s changed the pinned messages for the room.": "%(senderName)s ŝanĝis la fiksitajn mesaĝojn de la ĉambro.", + "%(widgetName)s widget modified by %(senderName)s": "Fenestraĵon %(widgetName)s ŝanĝis %(senderName)s", + "%(widgetName)s widget added by %(senderName)s": "Fenestraĵon %(widgetName)s aldonis %(senderName)s", + "%(widgetName)s widget removed by %(senderName)s": "Fenestraĵon %(widgetName)s forigis %(senderName)s", + "%(displayName)s is typing": "%(displayName)s tajpas", + "%(names)s and %(count)s others are typing|other": "%(names)s kaj %(count)s aliaj tajpas", + "%(names)s and %(count)s others are typing|one": "%(names)s kaj unu alia tajpas", + "%(names)s and %(lastPerson)s are typing": "%(names)s kaj %(lastPerson)s tajpas", + "Failure to create room": "Malsukcesis krei ĉambron", + "Server may be unavailable, overloaded, or you hit a bug.": "Servilo povas esti neatingebla, troŝarĝita, aŭ vi renkontis cimon.", + "Unnamed Room": "Sennoma ĉambro", + "Your browser does not support the required cryptography extensions": "Via foliumilo ne subtenas la bezonatajn ĉifrajn kromprogramojn", + "Not a valid Riot keyfile": "Nevalida ŝlosila dosiero de Riot", + "Authentication check failed: incorrect password?": "Aŭtentiga kontrolo malsukcesis: ĉu pro malĝusta pasvorto?", + "Failed to join room": "Malsukcesis aliĝi al ĉambro", + "Message Pinning": "Fikso de mesaĝoj", + "Presence Management": "Ĉeesta administrado", + "Tag Panel": "Etikeda panelo", + "Disable Emoji suggestions while typing": "Malŝalti mienetajn sugestojn dum tajpado", + "Use compact timeline layout": "Uzi densan okazordan aranĝon", + "Hide removed messages": "Kaŝi forigitajn mesaĝojn", + "Hide join/leave messages (invites/kicks/bans unaffected)": "Kaŝi envenajn/forlasajn mesaĝojn (sed ne invitajn/forpelajn/forbarajn)", + "Hide avatar changes": "Kaŝi profilbildajn ŝanĝojn", + "Hide display name changes": "Kaŝi ŝanĝojn de vidigaj nomoj", + "Hide read receipts": "Kaŝi legokonfrimojn", + "Show timestamps in 12 hour format (e.g. 2:30pm)": "Montri tempindikojn en 12-hora formo (ekz. 2:30 post.)", + "Always show message timestamps": "Ĉiam montri mesaĝajn tempindikojn", + "Autoplay GIFs and videos": "Aŭtomate ludi GIF-bildojn kaj videojn" } From 648174476c42d4ef02a45ba160660b99cea2d0bb Mon Sep 17 00:00:00 2001 From: Andrey Date: Fri, 1 Dec 2017 19:45:17 +0000 Subject: [PATCH 086/927] Translated using Weblate (Russian) Currently translated at 99.3% (935 of 941 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index d7763aa86d..3fedcd37ff 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -1025,5 +1025,10 @@ "Idle for %(duration)s": "Неактивен %(duration)s", "Unknown for %(duration)s": "Неизвестно %(duration)s", "There's no one else here! Would you like to invite others or stop warning about the empty room?": "Здесь никого нет! Хотите пригласить кого-нибудь или выключить предупреждение о пустой комнате?", - "Something went wrong when trying to get your communities.": "Что-то пошло не так, во время отображения ваших сообществ." + "Something went wrong when trying to get your communities.": "Что-то пошло не так, во время отображения ваших сообществ.", + "Tag Panel": "Панель тегов", + "Delete %(count)s devices|other": "Удалить %(count)s устройств", + "Delete %(count)s devices|one": "Удалить устройство", + "Select devices": "Выбрать устройства", + "This homeserver doesn't offer any login flows which are supported by this client.": "Этот домашний сервер не поддерживает метод входа, поддерживаемый клиентом." } From 4f83f6cf25480776c04329a0463d8f6fe82f48ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Tue, 5 Dec 2017 08:50:40 +0100 Subject: [PATCH 087/927] Move keyboard focus management back to the BaseDialog rather than leaving it in the Modal manager. We are using Modal manager to load other components not just BaseDialog and its subclasses and they might require different keyboard handling. Also depend on focus-trap-react rather than react-focus-trap for locking keyboard focus inside the dialog. The experience is much nicer and even the FocusTrap element it-self no longer gains the focus. On a side note using the FocusTrap element outside the dialog (on its parent) stops it from working properly. --- package.json | 2 +- src/Modal.js | 6 ++---- src/components/views/dialogs/BaseDialog.js | 13 +++++++++++-- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 46517230a7..ee089daf29 100644 --- a/package.json +++ b/package.json @@ -65,6 +65,7 @@ "file-saver": "^1.3.3", "filesize": "3.5.6", "flux": "2.1.1", + "focus-trap-react": "^3.0.5", "fuse.js": "^2.2.0", "glob": "^5.0.14", "highlight.js": "^8.9.1", @@ -78,7 +79,6 @@ "react": "^15.4.0", "react-addons-css-transition-group": "15.3.2", "react-dom": "^15.4.0", - "react-focus-trap": "^2.5.0", "react-gemini-scrollbar": "matrix-org/react-gemini-scrollbar#5e97aef", "sanitize-html": "^1.14.1", "text-encoding-utf-8": "^1.0.1", diff --git a/src/Modal.js b/src/Modal.js index daf66a37de..68d75d1ff1 100644 --- a/src/Modal.js +++ b/src/Modal.js @@ -19,7 +19,6 @@ limitations under the License. const React = require('react'); const ReactDOM = require('react-dom'); -import FocusTrap from 'react-focus-trap'; import Analytics from './Analytics'; import sdk from './index'; @@ -165,7 +164,6 @@ class ModalManager { ); modal.onFinished = props ? props.onFinished : null; modal.className = className; - modal.closeDialog = closeDialog; this._modals.unshift(modal); @@ -196,9 +194,9 @@ class ModalManager { const modal = this._modals[0]; const dialog = (
- +
{ modal.elem } - +
); diff --git a/src/components/views/dialogs/BaseDialog.js b/src/components/views/dialogs/BaseDialog.js index 1f29f2d1f4..25909a18fa 100644 --- a/src/components/views/dialogs/BaseDialog.js +++ b/src/components/views/dialogs/BaseDialog.js @@ -15,6 +15,7 @@ limitations under the License. */ import React from 'react'; +import FocusTrap from 'focus-trap-react'; import * as KeyCode from '../../../KeyCode'; import AccessibleButton from '../elements/AccessibleButton'; @@ -61,6 +62,14 @@ export default React.createClass({ } }, + _onKeyDown: function(e) { + if (e.keyCode === KeyCode.ESCAPE) { + e.stopPropagation(); + e.preventDefault(); + this.props.onFinished(); + } + }, + _onCancelClick: function(e) { this.props.onFinished(); }, @@ -69,7 +78,7 @@ export default React.createClass({ const TintableSvg = sdk.getComponent("elements.TintableSvg"); return ( -
+ @@ -79,7 +88,7 @@ export default React.createClass({ { this.props.title }
{ this.props.children } -
+ ); }, }); From 35c7f6e13d02e5bb5ee89e0495da894b7792ace0 Mon Sep 17 00:00:00 2001 From: jfkimmes Date: Mon, 4 Dec 2017 14:58:30 +0000 Subject: [PATCH 088/927] Translated using Weblate (German) Currently translated at 99.1% (933 of 941 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index c65e512928..27f10c0ad8 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -1028,5 +1028,6 @@ "Unknown for %(duration)s": "Unbekannt seit %(duration)s", "Flair": "Abzeichen", "Showing flair for these communities:": "Abzeichen für diese Communities zeigen:", - "This room is not showing flair for any communities": "Dieser Raum zeigt für keine Communities die Abzeichen an" + "This room is not showing flair for any communities": "Dieser Raum zeigt für keine Communities die Abzeichen an", + "Delete %(count)s devices|other": "Lösche %(count)s Geräte" } From a31af39ca8af8da06462d6d2cc3dd8d20093ca64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Tue, 5 Dec 2017 13:52:20 +0100 Subject: [PATCH 089/927] Applied aria-describedby to all other dialogs that are using BaseDialog. Also added initial focus where it has not been set. --- .../views/dialogs/ChatCreateOrReuseDialog.js | 11 +++++----- src/components/views/dialogs/ErrorDialog.js | 14 +++++-------- .../views/dialogs/InteractiveAuthDialog.js | 8 +++++--- .../views/dialogs/KeyShareDialog.js | 7 ++++--- .../dialogs/SessionRestoreErrorDialog.js | 16 +++++++++++---- .../views/dialogs/SetEmailDialog.js | 5 ++++- src/components/views/dialogs/SetMxIdDialog.js | 7 ++++--- .../views/dialogs/UnknownDeviceDialog.js | 5 +++-- .../login/InteractiveAuthEntryComponents.js | 20 +++++++++++++------ 9 files changed, 57 insertions(+), 36 deletions(-) diff --git a/src/components/views/dialogs/ChatCreateOrReuseDialog.js b/src/components/views/dialogs/ChatCreateOrReuseDialog.js index e0578f3b53..0623177e1a 100644 --- a/src/components/views/dialogs/ChatCreateOrReuseDialog.js +++ b/src/components/views/dialogs/ChatCreateOrReuseDialog.js @@ -127,7 +127,7 @@ export default class ChatCreateOrReuseDialog extends React.Component {
{ _t("Start new chat") }
; - content =
+ content =
{ _t('You already have existing direct chats with this user:') }
{ this.state.tiles } @@ -144,7 +144,7 @@ export default class ChatCreateOrReuseDialog extends React.Component { if (this.state.busyProfile) { profile = ; } else if (this.state.profileError) { - profile =
+ profile =
Unable to load profile information for { this.props.userId }
; } else { @@ -160,14 +160,14 @@ export default class ChatCreateOrReuseDialog extends React.Component {
; } content =
-
+

{ _t('Click on the button below to start chatting!') }

{ profile }
-
@@ -179,6 +179,7 @@ export default class ChatCreateOrReuseDialog extends React.Component { { content } @@ -186,7 +187,7 @@ export default class ChatCreateOrReuseDialog extends React.Component { } } -ChatCreateOrReuseDialog.propTyps = { +ChatCreateOrReuseDialog.propTypes = { userId: React.PropTypes.string.isRequired, // Called when clicking outside of the dialog onFinished: React.PropTypes.func.isRequired, diff --git a/src/components/views/dialogs/ErrorDialog.js b/src/components/views/dialogs/ErrorDialog.js index 97ed47e10f..0910264cef 100644 --- a/src/components/views/dialogs/ErrorDialog.js +++ b/src/components/views/dialogs/ErrorDialog.js @@ -51,22 +51,18 @@ export default React.createClass({ }; }, - componentDidMount: function() { - if (this.props.focus) { - this.refs.button.focus(); - } - }, - render: function() { const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); return ( -
+ title={this.props.title || _t('Error')} + contentId='mx_Dialog_content' + > +
{ this.props.description || _t('An error has occurred.') }
-
diff --git a/src/components/views/dialogs/InteractiveAuthDialog.js b/src/components/views/dialogs/InteractiveAuthDialog.js index 59de7c7f59..d1273849ae 100644 --- a/src/components/views/dialogs/InteractiveAuthDialog.js +++ b/src/components/views/dialogs/InteractiveAuthDialog.js @@ -72,11 +72,12 @@ export default React.createClass({ let content; if (this.state.authError) { content = ( -
-
{ this.state.authError.message || this.state.authError.toString() }
+
+
{ this.state.authError.message || this.state.authError.toString() }

{ _t("Dismiss") } @@ -84,7 +85,7 @@ export default React.createClass({ ); } else { content = ( -
+
{ content } diff --git a/src/components/views/dialogs/KeyShareDialog.js b/src/components/views/dialogs/KeyShareDialog.js index 9c8be27c89..821939ff0d 100644 --- a/src/components/views/dialogs/KeyShareDialog.js +++ b/src/components/views/dialogs/KeyShareDialog.js @@ -125,11 +125,11 @@ export default React.createClass({ text = _t(text, {displayName: displayName}); return ( -
+

{ text }

- diff --git a/src/components/views/dialogs/SetEmailDialog.js b/src/components/views/dialogs/SetEmailDialog.js index 2dd996953d..5a9569c1b5 100644 --- a/src/components/views/dialogs/SetEmailDialog.js +++ b/src/components/views/dialogs/SetEmailDialog.js @@ -41,6 +41,7 @@ export default React.createClass({ }, componentDidMount: function() { + this.refs.emailInputField.focus(); }, onEmailAddressChanged: function(value) { @@ -130,6 +131,7 @@ export default React.createClass({ const emailInput = this.state.emailBusy ? :
-

+

{ _t('This will allow you to reset your password and receive notifications.') }

{ emailInput } diff --git a/src/components/views/dialogs/SetMxIdDialog.js b/src/components/views/dialogs/SetMxIdDialog.js index 6fc1d77682..5ef04f5be1 100644 --- a/src/components/views/dialogs/SetMxIdDialog.js +++ b/src/components/views/dialogs/SetMxIdDialog.js @@ -234,14 +234,14 @@ export default React.createClass({ "error": Boolean(this.state.usernameError), "success": usernameAvailable, }); - usernameIndicator =
+ usernameIndicator =
{ usernameAvailable ? _t('Username available') : this.state.usernameError }
; } let authErrorIndicator = null; if (this.state.authError) { - authErrorIndicator =
+ authErrorIndicator =
{ this.state.authError }
; } @@ -253,8 +253,9 @@ export default React.createClass({ -
+
- +

{ _t('"%(RoomName)s" contains devices that you haven\'t seen before.', {RoomName: this.props.room.name}) }

@@ -161,7 +162,7 @@ export default React.createClass({ }}> { _t("Send anyway") } - - +
diff --git a/src/components/views/dialogs/SessionRestoreErrorDialog.js b/src/components/views/dialogs/SessionRestoreErrorDialog.js index e68a097e80..f018a83301 100644 --- a/src/components/views/dialogs/SessionRestoreErrorDialog.js +++ b/src/components/views/dialogs/SessionRestoreErrorDialog.js @@ -54,7 +54,8 @@ export default React.createClass({ { _t( "Otherwise, click here to send a bug report.", {}, - { 'a': (sub) => { sub } }, + { 'a': (sub) => { sub } }, ) }

); diff --git a/src/components/views/dialogs/TextInputDialog.js b/src/components/views/dialogs/TextInputDialog.js index 907848b3b8..4d73752641 100644 --- a/src/components/views/dialogs/TextInputDialog.js +++ b/src/components/views/dialogs/TextInputDialog.js @@ -75,7 +75,7 @@ export default React.createClass({ - +
From 509fbd4331ca4d41d3bb863d67f743efda057b2f Mon Sep 17 00:00:00 2001 From: Szimszon Date: Fri, 8 Dec 2017 18:07:44 +0000 Subject: [PATCH 106/927] Translated using Weblate (Hungarian) Currently translated at 100.0% (958 of 958 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index ee0207d398..f20370f40d 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -1040,5 +1040,19 @@ "Tag Panel": "Címke panel", "Addresses": "Címek", "collapse": "becsuk", - "expand": "kinyit" + "expand": "kinyit", + "Call Failed": "Sikertelen hívás", + "There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "Ismeretlen eszközök vannak ebben a szobában: ha ellenőrzés nélkül folytatod lehetséges, hogy valaki belehallgat a hívásba.", + "Review Devices": "Eszközök áttekintése", + "Call Anyway": "Mindenképpen hívj", + "Answer Anyway": "Mindenképpen felvesz", + "Call": "Hívás", + "Answer": "Felvesz", + "Send": "Elküld", + "Cryptography data migrated": "Titkosítási adatok migrálva", + "A one-off migration of cryptography data has been performed. End-to-end encryption will not work if you go back to an older version of Riot. If you need to use end-to-end cryptography on an older version, log out of Riot first. To retain message history, export and re-import your keys.": "A titkosítási adatok egyszeri migrációja megtörtént. Ha egy régebbi Riot verzióra állsz vissza a végponttól-végpontig titkosítás nem fog működni. Ha régi verzióval szeretnéd használni a végponttól-végpontig titkosítást először jelentkezz ki a Riotból. A régi üzenetek későbbi eléréséhez először mentsd ki a kulcsokat majd töltsd be újra.", + "Old cryptography data detected": "Régi titkosítási adatot találhatók", + "Data from an older version of Riot has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Régebbi Riot verzióból származó adatok találhatók. Ezek hibás működéshez vezethettek a végponttól-végpontig titkosításban régebbi verzióknál. A nemrég küldött/fogadott titkosított üzenetek ha a régi adatokat használták lehetséges hogy nem lesznek visszafejthetők ebben a verzióban. Ha problémákba ütközöl jelentkezz ki és vissza. A régi üzenetek elérésének biztosításához mentsd ki a kulcsokat és töltsd be újra.", + "Show devices or cancel all.": "Eszközök megmutatása vagy mind elutasítása.", + "Warning": "Figyelmeztetés" } From f9d4af155b252267d7cf2cf12b0da5ecfe03ad44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Sat, 9 Dec 2017 18:06:52 +0000 Subject: [PATCH 107/927] Translated using Weblate (French) Currently translated at 100.0% (958 of 958 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index 1b1834e649..9883e0eb21 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -1036,5 +1036,19 @@ "Tag Panel": "Panneau des étiquettes", "Addresses": "Adresses", "expand": "développer", - "collapse": "réduire" + "collapse": "réduire", + "Call Failed": "Échec de l'appel", + "There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "Il y a des appareils inconnus dans ce salon : si vous continuez sans les vérifier, quelqu'un pourrait épier votre appel.", + "Review Devices": "Passer en revue les appareils", + "Call Anyway": "Appeler quand même", + "Answer Anyway": "Répondre quand même", + "Call": "Appel", + "Answer": "Répondre", + "Send": "Envoyer", + "Cryptography data migrated": "Données de chiffrement migrées", + "A one-off migration of cryptography data has been performed. End-to-end encryption will not work if you go back to an older version of Riot. If you need to use end-to-end cryptography on an older version, log out of Riot first. To retain message history, export and re-import your keys.": "Une migration unique des données de chiffrement a été effectuée. Le chiffrement de bout-en-bout ne fonctionnera pas si vous revenez sur une version antérieure de Riot. Si vous avez besoin d'utiliser le chiffrement de bout-en-bout sur une ancienne version, déconnectez-vous de Riot. Pour conserver l'historique des messages, exportez et réimportez vos clés de chiffrement.", + "Old cryptography data detected": "Anciennes données de chiffrement détectées", + "Data from an older version of Riot has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Nous avons détecté des données d'une ancienne version de Riot. Le chiffrement de bout-en-bout n'aura pas fonctionné correctement sur l'ancienne version. Les messages chiffrés échangés récemment dans l'ancienne version ne sont peut-être pas déchiffrables dans cette version. Les échanges de message avec cette version peuvent aussi échouer. Si vous rencontrez des problèmes, déconnectez-vous puis reconnectez-vous. Pour conserver l'historique des messages, exportez puis réimportez vos clés de chiffrement.", + "Show devices or cancel all.": "Afficher les appareils ou tout annuler.", + "Warning": "Attention" } From 0f853915876b10d34ed53f6365c30bb5f7d34ad4 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sun, 10 Dec 2017 12:50:41 +0000 Subject: [PATCH 108/927] Implement Rich Quoting/Replies Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/Quote.js | 138 +++++++++++++++ src/components/views/messages/TextualBody.js | 17 ++ src/components/views/rooms/EventTile.js | 159 ++++++++++-------- .../views/rooms/MessageComposerInput.js | 65 +++---- src/components/views/rooms/QuotePreview.js | 75 +++++++++ src/linkify-matrix.js | 4 +- src/matrix-to.js | 33 ++++ src/stores/RoomViewStore.js | 12 ++ 8 files changed, 405 insertions(+), 98 deletions(-) create mode 100644 src/components/views/elements/Quote.js create mode 100644 src/components/views/rooms/QuotePreview.js create mode 100644 src/matrix-to.js diff --git a/src/components/views/elements/Quote.js b/src/components/views/elements/Quote.js new file mode 100644 index 0000000000..1925cfbd65 --- /dev/null +++ b/src/components/views/elements/Quote.js @@ -0,0 +1,138 @@ +/* +Copyright 2017 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. +*/ +import React from 'react'; +import sdk from '../../../index'; +import dis from '../../../dispatcher'; +import classNames from 'classnames'; +import { Room, RoomMember } from 'matrix-js-sdk'; +import PropTypes from 'prop-types'; +import MatrixClientPeg from '../../../MatrixClientPeg'; +import { getDisplayAliasForRoom } from '../../../Rooms'; +import {makeUserPermalink} from "../../../matrix-to"; +import DateUtils from "../../../DateUtils"; + +// For URLs of matrix.to links in the timeline which have been reformatted by +// HttpUtils transformTags to relative links. This excludes event URLs (with `[^\/]*`) +const REGEX_LOCAL_MATRIXTO = /^#\/room\/(([\#\!])[^\/]*)\/(\$[^\/]*)$/; + +const Quote = React.createClass({ + statics: { + isMessageUrl: (url) => { + return !!REGEX_LOCAL_MATRIXTO.exec(url); + }, + }, + + childContextTypes: { + matrixClient: React.PropTypes.object, + }, + + props: { + // The matrix.to url of the event + url: PropTypes.string, + // Whether to include an avatar in the pill + shouldShowPillAvatar: PropTypes.bool, + }, + + getChildContext: function() { + return { + matrixClient: MatrixClientPeg.get(), + }; + }, + + getInitialState() { + return { + // The room related to this quote + room: null, + // The event related to this quote + event: null, + }; + }, + + componentWillReceiveProps(nextProps) { + let roomId; + let prefix; + let eventId; + + if (nextProps.url) { + // Default to the empty array if no match for simplicity + // resource and prefix will be undefined instead of throwing + const matrixToMatch = REGEX_LOCAL_MATRIXTO.exec(nextProps.url) || []; + + roomId = matrixToMatch[1]; // The room ID + prefix = matrixToMatch[2]; // The first character of prefix + eventId = matrixToMatch[3]; // The event ID + } + + const room = prefix === '#' ? + MatrixClientPeg.get().getRooms().find((r) => { + return r.getAliases().includes(roomId); + }) : MatrixClientPeg.get().getRoom(roomId); + + // Only try and load the event if we know about the room + // otherwise we just leave a `Quote` anchor which can be used to navigate/join the room manually. + if (room) this.getEvent(room, eventId); + }, + + componentWillMount() { + this._unmounted = false; + this.componentWillReceiveProps(this.props); + }, + + componentWillUnmount() { + this._unmounted = true; + }, + + async getEvent(room, eventId) { + let event = room.findEventById(eventId); + if (event) { + this.setState({room, event}); + return; + } + + await MatrixClientPeg.get().getEventTimeline(room.getUnfilteredTimelineSet(), eventId); + event = room.findEventById(eventId); + this.setState({room, event}); + }, + + render: function() { + const ev = this.state.event; + if (ev) { + const EventTile = sdk.getComponent('views.rooms.EventTile'); + // const EmojiText = sdk.getComponent('views.elements.EmojiText'); + // const Pill = sdk.getComponent('views.elements.Pill'); + // const senderUrl = makeUserPermalink(ev.getSender()); + // const EventTileType = sdk.getComponent(EventTile.getHandlerTile(ev)); + /*return */ + return
+ {/**/} + {/**/} + {/* 🔗 { DateUtils.formatTime(new Date(ev.getTs())) }*/} + {/**/} + + {/**/} +
; + /*;*/ + } else { + // Deliberately render nothing if the URL isn't recognised + return
+ Quote +
+
; + } + }, +}); + +export default Quote; diff --git a/src/components/views/messages/TextualBody.js b/src/components/views/messages/TextualBody.js index 4b096d0a76..1899e8428a 100644 --- a/src/components/views/messages/TextualBody.js +++ b/src/components/views/messages/TextualBody.js @@ -1,5 +1,6 @@ /* Copyright 2015, 2016 OpenMarket Ltd +Copyright 2017 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. @@ -56,6 +57,9 @@ module.exports = React.createClass({ /* callback for when our widget has loaded */ onWidgetLoad: React.PropTypes.func, + + /* the shsape of the tile, used */ + tileShape: React.PropTypes.string, }, getInitialState: function() { @@ -179,6 +183,7 @@ module.exports = React.createClass({ // If the link is a (localised) matrix.to link, replace it with a pill const Pill = sdk.getComponent('elements.Pill'); + const Quote = sdk.getComponent('elements.Quote'); if (Pill.isMessagePillUrl(href)) { const pillContainer = document.createElement('span'); @@ -197,6 +202,18 @@ module.exports = React.createClass({ // update the current node with one that's now taken its place node = pillContainer; + } else if (this.props.tileShape !== 'quote' && Quote.isMessageUrl(href)) { + // only allow this branch if we're not already in a quote, as fun as infinite nesting is. + const quoteContainer = document.createElement('span'); + + const quote = ; + + ReactDOM.render(quote, quoteContainer); + node.parentNode.replaceChild(quoteContainer, node); + + pillified = true; + + node = quoteContainer; } } else if (node.nodeType == Node.TEXT_NODE) { const Pill = sdk.getComponent('elements.Pill'); diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index 3407ea159d..645a3fdb71 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -1,5 +1,6 @@ /* Copyright 2015, 2016 OpenMarket Ltd +Copyright 2017 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. @@ -528,79 +529,103 @@ module.exports = withMatrixClient(React.createClass({ const timestamp = this.props.mxEvent.getTs() ? : null; - if (this.props.tileShape === "notif") { - const room = this.props.matrixClient.getRoom(this.props.mxEvent.getRoomId()); - return ( - - ); - } else if (this.props.tileShape === "file_grid") { - return ( -
-
- -
- + switch (this.props.tileShape) { + case 'notif': { + const room = this.props.matrixClient.getRoom(this.props.mxEvent.getRoomId()); + return ( + - ); - } else { - return ( -
-
- { readAvatars }
- { avatar } - { sender } - - ); + ); + } + case 'quote': { + return ( +
+ { avatar } + { sender } +
+ + { timestamp } + + { this._renderE2EPadlock() } + +
+
+ ); + } + default: { + return ( +
+
+ { readAvatars } +
+ { avatar } + { sender } +
+ + { timestamp } + + { this._renderE2EPadlock() } + + { editButton } +
+
+ ); + } } }, })); @@ -653,3 +678,5 @@ function E2ePadlockUnencrypted(props) { function E2ePadlock(props) { return ; } + +module.exports.getHandlerTile = getHandlerTile; diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index cd30f20645..ad7e81ccb1 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -50,6 +50,10 @@ const REGEX_MATRIXTO_MARKDOWN_GLOBAL = new RegExp(MATRIXTO_MD_LINK_PATTERN, 'g') import {asciiRegexp, shortnameToUnicode, emojioneList, asciiList, mapUnicodeToShort} from 'emojione'; import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore"; +import {makeEventPermalink} from "../../../matrix-to"; +import QuotePreview from "./QuotePreview"; +import RoomViewStore from '../../../stores/RoomViewStore'; + const EMOJI_SHORTNAMES = Object.keys(emojioneList); const EMOJI_UNICODE_TO_SHORTNAME = mapUnicodeToShort(); const REGEX_EMOJI_WHITESPACE = new RegExp('(?:^|\\s)(' + asciiRegexp + ')\\s$'); @@ -293,35 +297,6 @@ export default class MessageComposerInput extends React.Component { }); } break; - case 'quote': { - /// XXX: Not doing rich-text quoting from formatted-body because draft-js - /// has regressed such that when links are quoted, errors are thrown. See - /// https://github.com/vector-im/riot-web/issues/4756. - const body = escape(payload.text); - if (body) { - let content = RichText.htmlToContentState(`
${body}
`); - if (!this.state.isRichtextEnabled) { - content = ContentState.createFromText(RichText.stateToMarkdown(content)); - } - - const blockMap = content.getBlockMap(); - let startSelection = SelectionState.createEmpty(contentState.getFirstBlock().getKey()); - contentState = Modifier.splitBlock(contentState, startSelection); - startSelection = SelectionState.createEmpty(contentState.getFirstBlock().getKey()); - contentState = Modifier.replaceWithFragment(contentState, - startSelection, - blockMap); - startSelection = SelectionState.createEmpty(contentState.getFirstBlock().getKey()); - if (this.state.isRichtextEnabled) { - contentState = Modifier.setBlockType(contentState, startSelection, 'blockquote'); - } - let editorState = EditorState.push(this.state.editorState, contentState, 'insert-characters'); - editorState = EditorState.moveSelectionToEnd(editorState); - this.onEditorContentChanged(editorState); - editor.focus(); - } - } - break; } }; @@ -659,7 +634,7 @@ export default class MessageComposerInput extends React.Component { } return false; - } + }; onTextPasted(text: string, html?: string) { const currentSelection = this.state.editorState.getSelection(); @@ -749,9 +724,17 @@ export default class MessageComposerInput extends React.Component { return true; } + const quotingEv = RoomViewStore.getQuotingEvent(); + if (this.state.isRichtextEnabled) { // We should only send HTML if any block is styled or contains inline style let shouldSendHTML = false; + + // If we are quoting we need HTML Content + if (quotingEv) { + shouldSendHTML = true; + } + const blocks = contentState.getBlocksAsArray(); if (blocks.some((block) => block.getType() !== 'unstyled')) { shouldSendHTML = true; @@ -809,7 +792,8 @@ export default class MessageComposerInput extends React.Component { }).join('\n'); const md = new Markdown(pt); - if (md.isPlainText()) { + // if contains no HTML and we're not quoting (needing HTML) + if (md.isPlainText() && !quotingEv) { contentText = md.toPlaintext(); } else { contentHTML = md.toHTML(); @@ -832,6 +816,24 @@ export default class MessageComposerInput extends React.Component { sendTextFn = this.client.sendEmoteMessage; } + if (quotingEv) { + const cli = MatrixClientPeg.get(); + const room = cli.getRoom(quotingEv.getRoomId()); + const sender = room.currentState.getMember(quotingEv.getSender()); + + const {body/*, formatted_body*/} = quotingEv.getContent(); + + const perma = makeEventPermalink(quotingEv.getRoomId(), quotingEv.getId()); + contentText = `${sender.name}:\n> ${body}\n\n${contentText}`; + contentHTML = `Quote
${contentHTML}`; + + // we have finished quoting, clear the quotingEvent + dis.dispatch({ + action: 'quote_event', + event: null, + }); + } + let sendMessagePromise; if (contentHTML) { sendMessagePromise = sendHtmlFn.call( @@ -1144,6 +1146,7 @@ export default class MessageComposerInput extends React.Component { return (
+ this.autocomplete = e} room={this.props.room} diff --git a/src/components/views/rooms/QuotePreview.js b/src/components/views/rooms/QuotePreview.js new file mode 100644 index 0000000000..2259350cdc --- /dev/null +++ b/src/components/views/rooms/QuotePreview.js @@ -0,0 +1,75 @@ +/* +Copyright 2017 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. +*/ + +import React from 'react'; +import dis from '../../../dispatcher'; +import sdk from '../../../index'; +import RoomViewStore from '../../../stores/RoomViewStore'; + +function cancelQuoting() { + dis.dispatch({ + action: 'quote_event', + event: null, + }); +} + +export default class QuotePreview extends React.Component { + constructor(props, context) { + super(props, context); + + this.state = { + event: null, + }; + + this._onRoomViewStoreUpdate = this._onRoomViewStoreUpdate.bind(this); + + this._roomStoreToken = RoomViewStore.addListener(this._onRoomViewStoreUpdate); + this._onRoomViewStoreUpdate(); + } + + componentWillUnmount() { + // Remove RoomStore listener + if (this._roomStoreToken) { + this._roomStoreToken.remove(); + } + } + + _onRoomViewStoreUpdate() { + const event = RoomViewStore.getQuotingEvent(); + if (this.state.event !== event) { + this.setState({ event }); + } + } + + render() { + if (!this.state.event) return null; + + const EventTile = sdk.getComponent('rooms.EventTile'); + const EmojiText = sdk.getComponent('views.elements.EmojiText'); + + return
+
+ 💬 Quoting +
+ +
+
+ +
+
; + } +} diff --git a/src/linkify-matrix.js b/src/linkify-matrix.js index 74489a09ea..6bbea77733 100644 --- a/src/linkify-matrix.js +++ b/src/linkify-matrix.js @@ -14,6 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. */ +import {baseUrl} from "./matrix-to"; + function matrixLinkify(linkify) { // Text tokens const TT = linkify.scanner.TOKENS; @@ -170,7 +172,7 @@ matrixLinkify.VECTOR_URL_PATTERN = "^(?:https?:\/\/)?(?:" matrixLinkify.MATRIXTO_URL_PATTERN = "^(?:https?:\/\/)?(?:www\\.)?matrix\\.to/#/((#|@|!).*)"; matrixLinkify.MATRIXTO_MD_LINK_PATTERN = '\\[([^\\]]*)\\]\\((?:https?:\/\/)?(?:www\\.)?matrix\\.to/#/((#|@|!)[^\\)]*)\\)'; -matrixLinkify.MATRIXTO_BASE_URL= "https://matrix.to"; +matrixLinkify.MATRIXTO_BASE_URL= baseUrl; matrixLinkify.options = { events: function(href, type) { diff --git a/src/matrix-to.js b/src/matrix-to.js new file mode 100644 index 0000000000..72fb3c38fc --- /dev/null +++ b/src/matrix-to.js @@ -0,0 +1,33 @@ +/* +Copyright 2017 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. +*/ + +export const baseUrl = "https://matrix.to"; + +export function makeEventPermalink(roomId, eventId) { + return `${baseUrl}/#/${roomId}/${eventId}`; +} + +export function makeUserPermalink(userId) { + return `${baseUrl}/#/${userId}`; +} + +export function makeRoomPermalink(roomId) { + return `${baseUrl}/#/${roomId}`; +} + +export function makeGroupPermalink(groupId) { + return `${baseUrl}/#/${groupId}`; +} diff --git a/src/stores/RoomViewStore.js b/src/stores/RoomViewStore.js index 0a8eca8797..cf895d2190 100644 --- a/src/stores/RoomViewStore.js +++ b/src/stores/RoomViewStore.js @@ -1,5 +1,6 @@ /* Copyright 2017 Vector Creations Ltd +Copyright 2017 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. @@ -41,6 +42,8 @@ const INITIAL_STATE = { roomLoadError: null, forwardingEvent: null, + + quotingEvent: null, }; /** @@ -108,6 +111,10 @@ class RoomViewStore extends Store { forwardingEvent: payload.event, }); break; + case 'quote_event': + this._setState({ + quotingEvent: payload.event, + }); } } @@ -286,6 +293,11 @@ class RoomViewStore extends Store { return this._state.forwardingEvent; } + // The mxEvent if one is currently being replied to/quoted + getQuotingEvent() { + return this._state.quotingEvent; + } + shouldPeek() { return this._state.shouldPeek; } From b6182f7e6c73e375c16cb5b33a4e982e5acd8dbf Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sun, 10 Dec 2017 12:54:19 +0000 Subject: [PATCH 109/927] Tidy Quote class, removing comments etc Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/Quote.js | 34 +++++--------------------- 1 file changed, 6 insertions(+), 28 deletions(-) diff --git a/src/components/views/elements/Quote.js b/src/components/views/elements/Quote.js index 1925cfbd65..c7f785f2cf 100644 --- a/src/components/views/elements/Quote.js +++ b/src/components/views/elements/Quote.js @@ -15,14 +15,8 @@ limitations under the License. */ import React from 'react'; import sdk from '../../../index'; -import dis from '../../../dispatcher'; -import classNames from 'classnames'; -import { Room, RoomMember } from 'matrix-js-sdk'; import PropTypes from 'prop-types'; import MatrixClientPeg from '../../../MatrixClientPeg'; -import { getDisplayAliasForRoom } from '../../../Rooms'; -import {makeUserPermalink} from "../../../matrix-to"; -import DateUtils from "../../../DateUtils"; // For URLs of matrix.to links in the timeline which have been reformatted by // HttpUtils transformTags to relative links. This excludes event URLs (with `[^\/]*`) @@ -87,14 +81,9 @@ const Quote = React.createClass({ }, componentWillMount() { - this._unmounted = false; this.componentWillReceiveProps(this.props); }, - componentWillUnmount() { - this._unmounted = true; - }, - async getEvent(room, eventId) { let event = room.findEventById(eventId); if (event) { @@ -111,27 +100,16 @@ const Quote = React.createClass({ const ev = this.state.event; if (ev) { const EventTile = sdk.getComponent('views.rooms.EventTile'); - // const EmojiText = sdk.getComponent('views.elements.EmojiText'); - // const Pill = sdk.getComponent('views.elements.Pill'); - // const senderUrl = makeUserPermalink(ev.getSender()); - // const EventTileType = sdk.getComponent(EventTile.getHandlerTile(ev)); - /*return */ return
- {/**/} - {/**/} - {/* 🔗 { DateUtils.formatTime(new Date(ev.getTs())) }*/} - {/**/} - {/**/}
; - /*;*/ - } else { - // Deliberately render nothing if the URL isn't recognised - return
- Quote -
-
; } + + // Deliberately render nothing if the URL isn't recognised + return
+ Quote +
+
; }, }); From a3f74d14a0eff2c12bc927a70ae3ca1cc0a31325 Mon Sep 17 00:00:00 2001 From: Tirifto Date: Sat, 9 Dec 2017 18:03:45 +0000 Subject: [PATCH 110/927] Translated using Weblate (Esperanto) Currently translated at 29.7% (285 of 958 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eo/ --- src/i18n/strings/eo.json | 108 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 107 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/eo.json b/src/i18n/strings/eo.json index 96a15c5a2d..c054daab0c 100644 --- a/src/i18n/strings/eo.json +++ b/src/i18n/strings/eo.json @@ -177,5 +177,111 @@ "Hide read receipts": "Kaŝi legokonfrimojn", "Show timestamps in 12 hour format (e.g. 2:30pm)": "Montri tempindikojn en 12-hora formo (ekz. 2:30 post.)", "Always show message timestamps": "Ĉiam montri mesaĝajn tempindikojn", - "Autoplay GIFs and videos": "Aŭtomate ludi GIF-bildojn kaj videojn" + "Autoplay GIFs and videos": "Aŭtomate ludi GIF-bildojn kaj videojn", + "Call Failed": "Voko malsukcesis", + "There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "En la ĉambro estas nekonataj aparatoj. Se vi pluigos sen ilia kontrolo, iu povos subaŭskulti vian vokon.", + "Review Devices": "Kontroli aparatojn", + "Call Anyway": "Tamen voki", + "Answer Anyway": "Tamen respondi", + "Call": "Voki", + "Answer": "Respondi", + "Send anyway": "Tamen sendi", + "Send": "Sendi", + "Enable automatic language detection for syntax highlighting": "Ŝalti aŭtomatan rekonon de lingvo por sintaksa markado", + "Hide avatars in user and room mentions": "Kaŝi profilbildojn en mencioj de uzantoj kaj ĉambroj", + "Disable big emoji in chat": "Malŝalti grandajn mienetojn en babilo", + "Don't send typing notifications": "Ne elsendi sciigojn pri tajpado", + "Automatically replace plain text Emoji": "Aŭtomate anstataŭigi tekstajn mienetojn", + "Mirror local video feed": "Speguli lokan videon", + "Disable Peer-to-Peer for 1:1 calls": "Malŝalti samtavolajn duopajn vokojn", + "Opt out of analytics": "Malpermesi datuman analizon", + "Never send encrypted messages to unverified devices from this device": "Neniam sendi neĉifritajn mesaĝojn al nekontrolitaj aparatoj de tiu ĉi aparato", + "Never send encrypted messages to unverified devices in this room from this device": "Neniam sendi ĉifritajn mesaĝojn al nekontrolitaj aparatoj en tiu ĉi ĉambro de tiu ĉi aparto", + "Enable inline URL previews by default": "Ŝalti entekstan antaŭrigardon al retadresoj", + "Enable URL previews for this room (only affects you)": "Ŝalti antaŭrigardon al retadresoj por ĉi tiu ĉambro (nur pro vi)", + "Enable URL previews by default for participants in this room": "Ŝalti antaŭrigardon al retadresoj por anoj de ĉi tiu ĉambro", + "Room Colour": "Koloro de ĉambro", + "Active call (%(roomName)s)": "Aktiva voko (%(roomName)s)", + "unknown caller": "nekonata vokanto", + "Incoming voice call from %(name)s": "Envena voĉvoko de %(name)s", + "Incoming video call from %(name)s": "Envena vidvoko de %(name)s", + "Incoming call from %(name)s": "Envena voko de %(name)s", + "Decline": "Rifuzi", + "Accept": "Akcepti", + "Error": "Eraro", + "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "Teksta mesaĝo sendiĝis al +%(msisdn)s. Bonvolu enigi la entenatan kontrolan kodon", + "Incorrect verification code": "Malĝusta kontrola kodo", + "Enter Code": "Enigu kodon", + "Submit": "Sendi", + "Phone": "Telefono", + "Add phone number": "Aldoni telefonan numeron", + "Add": "Aldoni", + "Failed to upload profile picture!": "Malsukcesis alŝuti vian profilbildon!", + "Upload new:": "Alŝuti novan:", + "No display name": "Sen vidiga nomo", + "New passwords don't match": "Novaj pasvortoj ne kongruas", + "Passwords can't be empty": "Pasvortoj ne povas esti malplenaj", + "Continue": "Daŭrigi", + "Export E2E room keys": "Elporti ĝiscele ĉifrajn ŝlosilojn de la ĉambro", + "Do you want to set an email address?": "Ĉu vi volas agordi retpoŝtadreson?", + "Current password": "Nuna pasvorto", + "Password": "Pasvorto", + "New Password": "Nova pasvorto", + "Confirm password": "Konfirmi pasvorton", + "Change Password": "Ŝanĝi pasvorton", + "Your home server does not support device management.": "Via hejma servilo ne subtenas administradon de aparatoj.", + "Unable to load device list": "Listo de aparatoj ne legeblas", + "Authentication": "Aŭtentigo", + "Delete %(count)s devices|other": "Forigi %(count)s aparatojn", + "Delete %(count)s devices|one": "Forigi aparaton", + "Device ID": "Aparata identigaĵo", + "Device Name": "Aparata nomo", + "Last seen": "Laste vidita", + "Select devices": "Elekti aparatojn", + "Failed to set display name": "Malsukcesis agordi vidigan nomon", + "Disable Notifications": "Malŝalti sciigojn", + "Enable Notifications": "Ŝalti sciigojn", + "Cannot add any more widgets": "Pluaj fenestraĵoj ne aldoneblas", + "The maximum permitted number of widgets have already been added to this room.": "La plejgranda nombro da fenestraĵoj jam aldoniĝis al ĉi tiu ĉambro.", + "Add a widget": "Aldoni fenestraĵon", + "Drop File Here": "Demetu dosieron tien ĉi", + "Drop file here to upload": "Demetu dosieron tien ĉi por ĝin alŝuti", + " (unsupported)": " (nesubtenata)", + "Join as voice or video.": "Aliĝu al voko kun voĉovideo.", + "Ongoing conference call%(supportedText)s.": "Nuntempa voko%(supportedText)s.", + "%(senderName)s sent an image": "%(senderName)s sendis bildon", + "%(senderName)s sent a video": "%(senderName)s sendis videon", + "%(senderName)s uploaded a file": "%(senderName)s alŝutis dosieron", + "Options": "Agordoj", + "Undecryptable": "Nemalĉifrebla", + "Encrypted by a verified device": "Ĉifrita de kontrolita aparato", + "Encrypted by an unverified device": "Ĉifrita de nekontrolita aparato", + "Unencrypted message": "Neĉifrita mesaĝo", + "Please select the destination room for this message": "Bonvolu elekti celan ĉambron por ĉi tiu mesaĝo", + "Blacklisted": "Sur nigra listo", + "Verified": "Kontrolita", + "Unverified": "Nekontrolita", + "device id: ": "aparata identigaĵo: ", + "Disinvite": "Malinviti", + "Kick": "Forpeli", + "Disinvite this user?": "Ĉu malinviti ĉi tiun uzanton?", + "Kick this user?": "Ĉu forpeli ĉi tiun uzanton?", + "Failed to kick": "Malsukcesis forpelo", + "Unban": "Malforbari", + "Ban": "Forbari", + "Unban this user?": "Ĉu malforbari ĉi tiun uzanton?", + "Ban this user?": "Ĉu forbari ĉi tiun uzanton?", + "Failed to ban user": "Malsukcesis forbari uzanton", + "Failed to mute user": "Malsukcesis silentigi uzanton", + "Failed to toggle moderator status": "Malsukcesis baskuligi estrecon", + "Failed to change power level": "Malsukcesis ŝanĝi nivelon de potenco", + "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Tiun ĉi ŝanĝon vi ne povos fareblos, ĉar vi donas al la uzanto la saman nivelon de potenco, kiun havas vi mem.", + "Are you sure?": "Ĉu vi certas?", + "No devices with registered encryption keys": "Neniuj aparatoj kun registritaj ĉifraj ŝlosiloj", + "Devices": "Aparatoj", + "Unignore": "Reatenti", + "Ignore": "Malatenti", + "Changing password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Ŝanĝo de pasvorto nuntempe nuligos ĉiujn ĝiscele ĉifrajn ŝlosilojn sur ĉiuj viaj aparatoj. Tio faros ĉifritajn babilajn historiojn nelegeblaj, krom se vi unue elportos viajn ĉambrajn ŝlosilojn kaj reenportos ilin poste. Estontece ĉi tio pliboniĝos.", + "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s ŝanĝis la profilbildon de %(roomName)s", + "You are about to be taken to a third-party site so you can authenticate your account for use with %(integrationsUrl)s. Do you wish to continue?": "Vi estas direktota al ekstera retejo por aŭtentigi vian konton por uzo kun %(integrationsUrl)s. Ĉu vi volas daŭrigi tion?" } From 1131e18368dac2485e1d00eaedd9a016e53efd50 Mon Sep 17 00:00:00 2001 From: EternalElectron Date: Fri, 8 Dec 2017 21:39:33 +0000 Subject: [PATCH 111/927] Translated using Weblate (German) Currently translated at 99.6% (955 of 958 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 0c529c7416..19327771d8 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -803,7 +803,7 @@ "Ignores a user, hiding their messages from you": "Ignoriert einen Benutzer und verbirgt dessen Nachrichten", "Disable Emoji suggestions while typing": "Emoji-Vorschläge während des Schreibens deaktivieren", "Banned by %(displayName)s": "Verbannt von %(displayName)s", - "To send messages, you must be a": "Notwendiges Berechtigungslevel, um Nachrichten zu senden", + "To send messages, you must be a": "Notwendiges Berechtigungslevel, um Nachrichten zu senden:", "To invite users into the room, you must be a": "Notwendiges Berechtigungslevel, um Benutzer in diesen Raum einladen zu können:", "To configure the room, you must be a": "Notwendiges Berechtigungslevel, um diesen Raum zu konfigurieren:", "To kick users, you must be a": "Notwendiges Berechtigungslevel, um Benutzer zu kicken:", @@ -1036,5 +1036,20 @@ "Flair will not appear": "Abzeichen wird nicht angezeigt", "Something went wrong when trying to get your communities.": "Beim Laden deiner Communites ist etwas schief gelaufen.", "Display your community flair in rooms configured to show it.": "Zeige deinen Community-Flair in den Räumen, die es erlauben.", - "This homeserver doesn't offer any login flows which are supported by this client.": "Dieser Heimserver verfügt über keinen, von diesem Client unterstütztes Anmeldeverfahren." + "This homeserver doesn't offer any login flows which are supported by this client.": "Dieser Heimserver verfügt über keinen, von diesem Client unterstütztes Anmeldeverfahren.", + "Call Failed": "Anruf fehlgeschlagen", + "There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "In diesem Raum befinden sich nicht verifizierte Geräte. Wenn du ohne Verifizierung fortfährst, könnten Angreifer den Anruf mithören.", + "Review Devices": "Geräte ansehen", + "Call Anyway": "Trotzdem anrufen", + "Answer Anyway": "Trotzdem annehmen", + "Call": "Anrufen", + "Answer": "Annehmen", + "Send": "Senden", + "Addresses": "Adressen", + "collapse": "Verbergen", + "expand": "Erweitern", + "Cryptography data migrated": "Kryptographie-Schlüssel wurden übertragen", + "Old cryptography data detected": "Alte Kryptografiedaten erkannt", + "Show devices or cancel all.": "Geräte anzeigen oder alle abbrechen.", + "Warning": "Warnung" } From 11d2a88d13567b2ec041a13151a030a91386d4c2 Mon Sep 17 00:00:00 2001 From: GuyOfThePery Date: Mon, 11 Dec 2017 06:39:21 +0000 Subject: [PATCH 112/927] Translated using Weblate (Hebrew) Currently translated at 5.8% (56 of 958 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/he/ --- src/i18n/strings/he.json | 59 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/he.json b/src/i18n/strings/he.json index 0967ef424b..bd96159ae1 100644 --- a/src/i18n/strings/he.json +++ b/src/i18n/strings/he.json @@ -1 +1,58 @@ -{} +{ + "This email address is already in use": "כתובת הדואר הזו כבר בשימוש", + "This phone number is already in use": "מספר הטלפון הזה כבר בשימוש", + "Failed to verify email address: make sure you clicked the link in the email": "אימות כתובת הדוא\"ל נכשלה: וודא שלחצת על הקישור בדוא\"ל", + "Call Failed": "השיחה נכשלה", + "There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "ישנם מכשירים לא ידועים בחדר: המשך ללא אימותם יאפשר למישהו לצוטט לשיחתך.", + "Review Devices": "סקירת מכשירים", + "Call Anyway": "התקשר בכל זאת", + "Answer Anyway": "ענה בכל זאת", + "Call": "התקשר", + "Answer": "ענה", + "The remote side failed to pick up": "הצד המרוחק לא ענה", + "Unable to capture screen": "כישלון בצילום המסך", + "Existing Call": "שיחה קיימת", + "You are already in a call.": "אתה כבר נמצא בשיחה.", + "VoIP is unsupported": "שיחה מעל IP לא נתמכת", + "You cannot place VoIP calls in this browser.": "אין אפשרות ליצור שיחה מעל IP בדפדפן זה.", + "You cannot place a call with yourself.": "אין אפשרות ליצור שיחה עם עצמך.", + "Conference calls are not supported in this client": "שיחות וועידה לא נתמכות בתכנה הזו", + "Conference calls are not supported in encrypted rooms": "שיחות וועידה לא נתמכות בחדרים מוצפנים", + "Warning!": "אזהרה!", + "Conference calling is in development and may not be reliable.": "שיחות וועידה נמצאות תחת פיתוח ועלולות להיות לא אמינות.", + "Failed to set up conference call": "כישלון ביצירת שיחת וועידה", + "Conference call failed.": "שיחת וועידה נכשלה.", + "The file '%(fileName)s' failed to upload": "העלאת הקובץ '%(fileName)s' נכשלה", + "The file '%(fileName)s' exceeds this home server's size limit for uploads": "הקובץ '%(fileName)s' גדול מהגבלת ההעלאה של שרת הבית", + "Upload Failed": "העלאה נכשלה", + "Sun": "ראשון", + "Mon": "שני", + "Tue": "שלישי", + "Wed": "רביעי", + "Thu": "חמישי", + "Fri": "שישי", + "Sat": "שבת", + "Jan": "ינואר", + "Feb": "פברואר", + "Mar": "מרץ", + "Apr": "אפריל", + "May": "מאי", + "Jun": "יוני", + "Jul": "יולי", + "Aug": "אוגוסט", + "Sep": "ספטמבר", + "Oct": "אוקטובר", + "Nov": "נובמבר", + "Dec": "דצמבר", + "PM": "PM", + "AM": "AM", + "Who would you like to add to this community?": "מי תרצה להוסיף לקהילה?", + "Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "אזהרה: כל אחד שיודע את מזהה הקהילה יוכל לראות את האנשים המוזמנים לקהילה", + "Invite new community members": "הזמן חברי קהילה חדשים", + "Name or matrix ID": "שם או מזהה מטריקס", + "Invite to Community": "הזמן לקהילה", + "Which rooms would you like to add to this community?": "אילו חדרים תרצה להוסיף לקהילה?", + "Show these rooms to non-members on the community page and room list?": "הצג חדרים אלה לחסרי-חשבון על דף הקהילה ורשימת החדרים?", + "Add rooms to the community": "הוסף חדרים לקהילה", + "Room name or alias": "שם חדר או כינוי" +} From 85c272ba82b5aa6d0d0d0f6b2b0c5d07698c9e30 Mon Sep 17 00:00:00 2001 From: Andrey Date: Fri, 8 Dec 2017 19:08:55 +0000 Subject: [PATCH 113/927] Translated using Weblate (Russian) Currently translated at 99.3% (952 of 958 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 3fedcd37ff..1550d3d133 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -1030,5 +1030,22 @@ "Delete %(count)s devices|other": "Удалить %(count)s устройств", "Delete %(count)s devices|one": "Удалить устройство", "Select devices": "Выбрать устройства", - "This homeserver doesn't offer any login flows which are supported by this client.": "Этот домашний сервер не поддерживает метод входа, поддерживаемый клиентом." + "This homeserver doesn't offer any login flows which are supported by this client.": "Этот домашний сервер не поддерживает метод входа, поддерживаемый клиентом.", + "Call Failed": "Звонок не удался", + "There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "В этой комнате есть неизвестные устройства: если вы продолжите без их проверки, имейте в виду, что кто-то посторонний может вас прослушать.", + "Review Devices": "Обзор устройств", + "Call Anyway": "Позвонить в любом случае", + "Answer Anyway": "Ответить в любом случае", + "Call": "Вызов", + "Answer": "Ответить", + "Send": "Отправить", + "Addresses": "Адреса", + "collapse": "свернуть", + "expand": "развернуть", + "Cryptography data migrated": "Миграция данных криптографии", + "A one-off migration of cryptography data has been performed. End-to-end encryption will not work if you go back to an older version of Riot. If you need to use end-to-end cryptography on an older version, log out of Riot first. To retain message history, export and re-import your keys.": "Выполнена одноразовая миграция данных криптографии. Сквозное шифрование не будет работать, если вы вернетесь к старой версии Riot. Если требуется использовать сквозную криптографию для более старой версии, сначала выйдите из Riot. Чтобы сохранить журнал сообщений, экспортируйте и повторно импортируйте ключи.", + "Old cryptography data detected": "Обнаружены старые криптографические данные", + "Data from an older version of Riot has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Обнаружены данные из более старой версии Riot. Это приведет к сбою криптографии в более ранней версии. В этой версии не могут быть расшифрованы сообщения, которые использовались недавно при использовании старой версии. Это также может привести к сбою обмена сообщениями с этой версией. Если возникают неполадки, выйдите и снова войдите в систему. Чтобы сохранить журнал сообщений, экспортируйте и повторно импортируйте ключи.", + "Show devices or cancel all.": "Показать устройства или отменить все.", + "Warning": "Предупреждение" } From ab0ff9b7814240f91ba0ad03351adf26cf4a63e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Tue, 12 Dec 2017 18:55:57 +0100 Subject: [PATCH 114/927] BaseDialog: split a very long line --- src/components/views/dialogs/BaseDialog.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/components/views/dialogs/BaseDialog.js b/src/components/views/dialogs/BaseDialog.js index fbeb35c808..db8e530fa0 100644 --- a/src/components/views/dialogs/BaseDialog.js +++ b/src/components/views/dialogs/BaseDialog.js @@ -83,7 +83,12 @@ export default React.createClass({ const TintableSvg = sdk.getComponent("elements.TintableSvg"); return ( - + From 38e8488c2a0003767d89fbde98dee9d3d688d7a4 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 12 Dec 2017 23:25:38 +0000 Subject: [PATCH 115/927] we don't actually use state.room Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/Quote.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/components/views/elements/Quote.js b/src/components/views/elements/Quote.js index c7f785f2cf..96bebf8bcd 100644 --- a/src/components/views/elements/Quote.js +++ b/src/components/views/elements/Quote.js @@ -48,8 +48,6 @@ const Quote = React.createClass({ getInitialState() { return { - // The room related to this quote - room: null, // The event related to this quote event: null, }; From 4666ac7c830c54ff65a51d6bfed54d1e624474a4 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 12 Dec 2017 23:29:43 +0000 Subject: [PATCH 116/927] hide rich quoting behind flags, retaining original quoting for now Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/messages/TextualBody.js | 4 ++- .../views/rooms/MessageComposerInput.js | 32 ++++++++++++++++++- src/settings/Settings.js | 6 ++++ 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/components/views/messages/TextualBody.js b/src/components/views/messages/TextualBody.js index 1899e8428a..4c41cbe669 100644 --- a/src/components/views/messages/TextualBody.js +++ b/src/components/views/messages/TextualBody.js @@ -202,7 +202,9 @@ module.exports = React.createClass({ // update the current node with one that's now taken its place node = pillContainer; - } else if (this.props.tileShape !== 'quote' && Quote.isMessageUrl(href)) { + } else if (SettingsStore.isFeatureEnabled("feature_rich_quoting") && this.props.tileShape !== 'quote' && + Quote.isMessageUrl(href) + ) { // only allow this branch if we're not already in a quote, as fun as infinite nesting is. const quoteContainer = document.createElement('span'); diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index ad7e81ccb1..3305ba7994 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -297,6 +297,36 @@ export default class MessageComposerInput extends React.Component { }); } break; + + case 'quote': { // old quoting, whilst rich quoting is in labs + /// XXX: Not doing rich-text quoting from formatted-body because draft-js + /// has regressed such that when links are quoted, errors are thrown. See + /// https://github.com/vector-im/riot-web/issues/4756. + const body = escape(payload.text); + if (body) { + let content = RichText.htmlToContentState(`
${body}
`); + if (!this.state.isRichtextEnabled) { + content = ContentState.createFromText(RichText.stateToMarkdown(content)); + } + + const blockMap = content.getBlockMap(); + let startSelection = SelectionState.createEmpty(contentState.getFirstBlock().getKey()); + contentState = Modifier.splitBlock(contentState, startSelection); + startSelection = SelectionState.createEmpty(contentState.getFirstBlock().getKey()); + contentState = Modifier.replaceWithFragment(contentState, + startSelection, + blockMap); + startSelection = SelectionState.createEmpty(contentState.getFirstBlock().getKey()); + if (this.state.isRichtextEnabled) { + contentState = Modifier.setBlockType(contentState, startSelection, 'blockquote'); + } + let editorState = EditorState.push(this.state.editorState, contentState, 'insert-characters'); + editorState = EditorState.moveSelectionToEnd(editorState); + this.onEditorContentChanged(editorState); + editor.focus(); + } + } + break; } }; @@ -1146,7 +1176,7 @@ export default class MessageComposerInput extends React.Component { return (
- + { SettingsStore.isFeatureEnabled("feature_rich_quoting") && } this.autocomplete = e} room={this.props.room} diff --git a/src/settings/Settings.js b/src/settings/Settings.js index 07de17ccfd..4a5ed3f661 100644 --- a/src/settings/Settings.js +++ b/src/settings/Settings.js @@ -76,6 +76,12 @@ export const SETTINGS = { // // level is always appended to the end. // supportedLevelsAreOrdered: false, // }, + "feature_rich_quoting": { + isFeature: true, + displayName: _td("Rich Quoting"), + supportedLevels: LEVELS_FEATURE, + default: false, + }, "feature_pinning": { isFeature: true, displayName: _td("Message Pinning"), From 5c229b9ef85374b6d3e9f369fe50f1bb16acd548 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 12 Dec 2017 23:33:40 +0000 Subject: [PATCH 117/927] DRY matrix.to link generation so it is all changeable in one class Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/autocomplete/RoomProvider.js | 3 ++- src/autocomplete/UserProvider.js | 3 ++- src/components/structures/GroupView.js | 5 +++-- src/components/views/rooms/EventTile.js | 5 ++--- src/components/views/rooms/MessageComposerInput.js | 4 ++-- 5 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/autocomplete/RoomProvider.js b/src/autocomplete/RoomProvider.js index 1e1928a1ee..31599703c2 100644 --- a/src/autocomplete/RoomProvider.js +++ b/src/autocomplete/RoomProvider.js @@ -25,6 +25,7 @@ import {PillCompletion} from './Components'; import {getDisplayAliasForRoom} from '../Rooms'; import sdk from '../index'; import _sortBy from 'lodash/sortBy'; +import {makeRoomPermalink} from "../matrix-to"; const ROOM_REGEX = /(?=#)(\S*)/g; @@ -78,7 +79,7 @@ export default class RoomProvider extends AutocompleteProvider { return { completion: displayAlias, suffix: ' ', - href: 'https://matrix.to/#/' + displayAlias, + href: makeRoomPermalink(displayAlias), component: ( } title={room.name} description={displayAlias} /> ), diff --git a/src/autocomplete/UserProvider.js b/src/autocomplete/UserProvider.js index 9d587c2eb4..5814f40437 100644 --- a/src/autocomplete/UserProvider.js +++ b/src/autocomplete/UserProvider.js @@ -28,6 +28,7 @@ import _sortBy from 'lodash/sortBy'; import MatrixClientPeg from '../MatrixClientPeg'; import type {Room, RoomMember} from 'matrix-js-sdk'; +import {makeUserPermalink} from "../matrix-to"; const USER_REGEX = /@\S*/g; @@ -104,7 +105,7 @@ export default class UserProvider extends AutocompleteProvider { // relies on the length of the entity === length of the text in the decoration. completion: user.rawDisplayName.replace(' (IRC)', ''), suffix: range.start === 0 ? ': ' : ' ', - href: 'https://matrix.to/#/' + user.userId, + href: makeUserPermalink(user.userId), component: ( } diff --git a/src/components/structures/GroupView.js b/src/components/structures/GroupView.js index 5ffb97c6ed..64f9955aa9 100644 --- a/src/components/structures/GroupView.js +++ b/src/components/structures/GroupView.js @@ -31,6 +31,7 @@ import GroupStoreCache from '../../stores/GroupStoreCache'; import GroupStore from '../../stores/GroupStore'; import { showGroupAddRoomDialog } from '../../GroupAddressPicker'; import GeminiScrollbar from 'react-gemini-scrollbar'; +import {makeGroupPermalink, makeUserPermalink} from "../../matrix-to"; const LONG_DESC_PLACEHOLDER = _td( `

HTML for your community's page

@@ -209,7 +210,7 @@ const FeaturedRoom = React.createClass({ let permalink = null; if (this.props.summaryInfo.profile && this.props.summaryInfo.profile.canonical_alias) { - permalink = 'https://matrix.to/#/' + this.props.summaryInfo.profile.canonical_alias; + permalink = makeGroupPermalink(this.props.summaryInfo.profile.canonical_alias); } let roomNameNode = null; @@ -366,7 +367,7 @@ const FeaturedUser = React.createClass({ const BaseAvatar = sdk.getComponent("avatars.BaseAvatar"); const name = this.props.summaryInfo.displayname || this.props.summaryInfo.user_id; - const permalink = 'https://matrix.to/#/' + this.props.summaryInfo.user_id; + const permalink = makeUserPermalink(this.props.summaryInfo.user_id); const userNameNode = { name }; const httpUrl = MatrixClientPeg.get() .mxcUrlToHttp(this.props.summaryInfo.avatar_url, 64, 64); diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index 645a3fdb71..3937c490f9 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -29,6 +29,7 @@ import withMatrixClient from '../../../wrappers/withMatrixClient'; const ContextualMenu = require('../../structures/ContextualMenu'); import dis from '../../../dispatcher'; +import {makeEventPermalink} from "../../../matrix-to"; const ObjectUtils = require('../../../ObjectUtils'); @@ -472,9 +473,7 @@ module.exports = withMatrixClient(React.createClass({ mx_EventTile_redacted: isRedacted, }); - const permalink = "https://matrix.to/#/" + - this.props.mxEvent.getRoomId() + "/" + - this.props.mxEvent.getId(); + const permalink = makeEventPermalink(this.props.mxEvent.getRoomId(), this.props.mxEvent.getId()); const readAvatars = this.getReadAvatars(); diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index 3305ba7994..4810f0267b 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -50,7 +50,7 @@ const REGEX_MATRIXTO_MARKDOWN_GLOBAL = new RegExp(MATRIXTO_MD_LINK_PATTERN, 'g') import {asciiRegexp, shortnameToUnicode, emojioneList, asciiList, mapUnicodeToShort} from 'emojione'; import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore"; -import {makeEventPermalink} from "../../../matrix-to"; +import {makeEventPermalink, makeUserPermalink} from "../../../matrix-to"; import QuotePreview from "./QuotePreview"; import RoomViewStore from '../../../stores/RoomViewStore'; @@ -292,7 +292,7 @@ export default class MessageComposerInput extends React.Component { this.setDisplayedCompletion({ completion, selection, - href: `https://matrix.to/#/${payload.user_id}`, + href: makeUserPermalink(payload.user_id), suffix: selection.getStartOffset() === 0 ? ': ' : ' ', }); } From 68f4dcbc23562e96c7744247b77d72f260edea38 Mon Sep 17 00:00:00 2001 From: Tirifto Date: Tue, 12 Dec 2017 10:29:18 +0000 Subject: [PATCH 118/927] Translated using Weblate (Esperanto) Currently translated at 52.6% (504 of 958 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eo/ --- src/i18n/strings/eo.json | 221 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 220 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/eo.json b/src/i18n/strings/eo.json index c054daab0c..3a46ae428c 100644 --- a/src/i18n/strings/eo.json +++ b/src/i18n/strings/eo.json @@ -283,5 +283,224 @@ "Ignore": "Malatenti", "Changing password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Ŝanĝo de pasvorto nuntempe nuligos ĉiujn ĝiscele ĉifrajn ŝlosilojn sur ĉiuj viaj aparatoj. Tio faros ĉifritajn babilajn historiojn nelegeblaj, krom se vi unue elportos viajn ĉambrajn ŝlosilojn kaj reenportos ilin poste. Estontece ĉi tio pliboniĝos.", "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s ŝanĝis la profilbildon de %(roomName)s", - "You are about to be taken to a third-party site so you can authenticate your account for use with %(integrationsUrl)s. Do you wish to continue?": "Vi estas direktota al ekstera retejo por aŭtentigi vian konton por uzo kun %(integrationsUrl)s. Ĉu vi volas daŭrigi tion?" + "You are about to be taken to a third-party site so you can authenticate your account for use with %(integrationsUrl)s. Do you wish to continue?": "Vi estas direktota al ekstera retejo por aŭtentigi vian konton por uzo kun %(integrationsUrl)s. Ĉu vi volas daŭrigi tion?", + "Jump to read receipt": "Salti al legokonfirmo", + "Mention": "Mencio", + "Invite": "Inviti", + "User Options": "Agordoj de uzanto", + "Direct chats": "Rektaj babiloj", + "Unmute": "Malsilentigi", + "Mute": "Silentigi", + "Revoke Moderator": "Forigi estrajn rajtojn", + "Make Moderator": "Kunestrigi", + "Admin Tools": "Estriloj", + "Level:": "Nivelo:", + "and %(count)s others...|other": "kaj %(count)s aliaj…", + "and %(count)s others...|one": "kaj unu alia…", + "Invited": "Invititaj", + "Filter room members": "Filtri ĉambranojn", + "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (potenco je %(powerLevelNumber)s)", + "Attachment": "Kunsendaĵo", + "Upload Files": "Alŝuti dosierojn", + "Are you sure you want to upload the following files?": "Ĉu vi certe volas alŝuti la jenajn dosierojn?", + "Encrypted room": "Ĉifrita ĉambro", + "Unencrypted room": "Neĉifrita ĉambro", + "Hangup": "Fini vokon", + "Voice call": "Voĉvoko", + "Video call": "Vidvoko", + "Hide Apps": "Kaŝi aplikaĵojn", + "Show Apps": "Montri aplikaĵojn", + "Upload file": "Alŝuti dosieron", + "Show Text Formatting Toolbar": "Montri tekstaranĝan breton", + "Send an encrypted message": "Sendi ĉirfitan mesaĝon", + "Send a message (unencrypted)": "Sendi mesaĝon (neĉifritan)", + "You do not have permission to post to this room": "Mankas al vi permeso afiŝi en la ĉambro", + "Turn Markdown on": "Ŝalti Marksubon", + "Turn Markdown off": "Malŝalti Marksubon", + "Hide Text Formatting Toolbar": "Kaŝi tekstaranĝan breton", + "Server error": "Servila eraro", + "Server unavailable, overloaded, or something else went wrong.": "Servilo estas neatingebla, troŝarĝita, aŭ io alia misokazis.", + "Command error": "Komanda eraro", + "bold": "grasa", + "italic": "kursiva", + "strike": "trastrekita", + "underline": "substrekita", + "code": "kodo", + "quote": "citaĵo", + "bullet": "bulo", + "numbullet": "numerita", + "Markdown is disabled": "Marksubo estas malŝaltita", + "Markdown is enabled": "Marksubo estas ŝaltita", + "Unpin Message": "Malfiksi mesaĝon", + "Jump to message": "Salti al mesaĝo", + "No pinned messages.": "Neniuj fiksitaj mesaĝoj.", + "Loading...": "Enleganta…", + "Pinned Messages": "Fiksitaj mesaĝoj", + "%(duration)ss": "%(duration)ss", + "%(duration)sm": "%(duration)sm", + "%(duration)sh": "%(duration)sh", + "%(duration)sd": "%(duration)st", + "Online for %(duration)s": "Enreta jam je %(duration)s", + "Idle for %(duration)s": "Senfara jam je %(duration)s", + "Offline for %(duration)s": "Eksterreta jam je %(duration)s", + "Unknown for %(duration)s": "Nekonata jam je %(duration)s", + "Online": "Enreta", + "Idle": "Senfara", + "Offline": "Eksterreta", + "Unknown": "Nekonata", + "Seen by %(userName)s at %(dateTime)s": "Vidita de %(userName)s je %(dateTime)s", + "Unnamed room": "Sennoma ĉambro", + "World readable": "Legebla de ĉiuj", + "Guests can join": "Gastoj povas aliĝi", + "No rooms to show": "Neniuj ĉambroj montreblas", + "Failed to set avatar.": "Malsukcesis agordi profilbildon.", + "Save": "Konservi", + "(~%(count)s results)|other": "(~%(count)s rezultoj)", + "(~%(count)s results)|one": "(~%(count)s rezulto)", + "Join Room": "Aliĝi al ĉambro", + "Upload avatar": "Alŝuti profilbildon", + "Remove avatar": "Forigi profilbildon", + "Settings": "Agordoj", + "Forget room": "Forgesi ĉambron", + "Search": "Serĉi", + "Show panel": "Montri panelon", + "Drop here to favourite": "Demetu tien ĉi por ŝati", + "Drop here to tag direct chat": "Demeti tien ĉi por marki rektan babilon", + "Drop here to restore": "Demeti tien ĉi por reigi", + "Drop here to demote": "Demeti tien ĉi por malpligravigi", + "Drop here to tag %(section)s": "Demeti tien ĉi por marki %(section)s", + "Press to start a chat with someone": "Premu por komenci babilon kun iu", + "You're not in any rooms yet! Press to make a room or to browse the directory": "Vi ankoraŭ estas en neniuj ĉambroj! Premu por fari ĉambron aŭ por esplori la ĉambrujon", + "Community Invites": "Komunumaj invitoj", + "Invites": "Invitoj", + "Favourites": "Ŝatataj", + "People": "Homoj", + "Rooms": "Ĉambroj", + "Low priority": "Malpli gravaj", + "Historical": "Estintaj", + "Unable to ascertain that the address this invite was sent to matches one associated with your account.": "Ne certigeblas, ke la adreso, kien ĉi tiu invito sendiĝis, kongruas kun tiu rilata al via konto.", + "This invitation was sent to an email address which is not associated with this account:": "Ĉi tiu invito sendiĝis al retpoŝtadreso, kiu ne rilatas al ĉi tiu konto:", + "You may wish to login with a different account, or add this email to this account.": "Vi povas saluti per alia konto, aŭ aldoni ĉi tiun retpoŝtadreson al tiu ĉi konto.", + "You have been invited to join this room by %(inviterName)s": "%(inviterName)s vin invitis al ĉi tiu ĉambro", + "Would you like to accept or decline this invitation?": "Ĉu vi volas akceptirifuzi ĉi tiun inviton?", + "Reason: %(reasonText)s": "Kialo: %(reasonText)s", + "Rejoin": "Realiĝi", + "You have been kicked from %(roomName)s by %(userName)s.": "%(userName)s vin forpelis de %(roomName)s.", + "You have been kicked from this room by %(userName)s.": "%(userName)s vin forpelis de tiu ĉi ĉambro.", + "You have been banned from %(roomName)s by %(userName)s.": "%(userName)s vi forbaris de %(roomName)s.", + "You have been banned from this room by %(userName)s.": "%(userName)s vin forbaris de tiu ĉi ĉambro.", + "This room": "Ĉi tiu ĉambro", + "%(roomName)s does not exist.": "%(roomName)s ne ekzistas.", + "%(roomName)s is not accessible at this time.": "%(roomName)s ne estas atingebla nun.", + "You are trying to access %(roomName)s.": "Vi provas atingi %(roomName)s.", + "You are trying to access a room.": "Vi provas atingi ĉambron.", + "Click here to join the discussion!": "Klaku ĉi tie por aliĝi al la diskuto!", + "This is a preview of this room. Room interactions have been disabled": "Tio ĉi estas antaŭrigardo al la ĉambro. Ĉambraj interagoj estas malŝaltitaj", + "To change the room's avatar, you must be a": "Por ŝanĝi la ĉambran profilbildon, vi devas esti", + "To change the room's name, you must be a": "Por ŝanĝi la ĉambran nomon, videvas esti", + "To change the room's main address, you must be a": "Por ŝanĝi la ĉambran ĉefadreson, vi devas esti", + "To change the room's history visibility, you must be a": "Por ŝanĝi videblecon de la ĉambra historio, vi devas esti", + "To change the permissions in the room, you must be a": "Por ŝanĝi permesojn en la ĉambro, vi devas esti", + "To change the topic, you must be a": "Por ŝanĝi la temon, vi devas esti", + "To modify widgets in the room, you must be a": "Por ŝanĝi fenestraĵojn en la ĉambro, vi devas esti", + "Failed to unban": "Malsukcesis malforbari", + "Banned by %(displayName)s": "Forbarita de %(displayName)s", + "Privacy warning": "Priprivata averto", + "Changes to who can read history will only apply to future messages in this room": "Ŝanĝoj al videbleco de la historio nur efektiviĝos nur por estontaj mesaĝoj en ĉi tiu ĉambro", + "The visibility of existing history will be unchanged": "Videbleco de la jama historio restos senŝanĝa", + "unknown error code": "nekonata kodo de eraro", + "Failed to forget room %(errCode)s": "Malsukcesis forgesi ĉambron %(errCode)s", + "End-to-end encryption is in beta and may not be reliable": "Ĝiscela ĉifrado estas beta-versia kaj eble ne dependebla", + "You should not yet trust it to secure data": "Ankoraŭ ne fidu ĝin pri sekurigo de datumoj", + "Devices will not yet be able to decrypt history from before they joined the room": "Aparatoj ankoraŭ ne povos malĉifri historion de antaŭ ilia aliĝo", + "Once encryption is enabled for a room it cannot be turned off again (for now)": "Post ĉifrado ŝaltiĝos en ĉambro, ĝi ne malŝalteblos (ankoraŭ)", + "Encrypted messages will not be visible on clients that do not yet implement encryption": "Ĉifritaj mesaĝoj ne videblos en klinteoj, kiuj ankoraŭ ne subtenas ĉifradon", + "Enable encryption": "Ŝalti ĉifradon", + "(warning: cannot be disabled again!)": "(averto: ĝi ne malŝalteblas poste!)", + "Encryption is enabled in this room": "Ĉifrado estas ŝaltita en tiu ĉi ĉambro", + "Encryption is not enabled in this room": "Ĉifrado ne estas ŝaltita en tiu ĉi ĉambro", + "Privileged Users": "Privilegiuloj", + "%(user)s is a": "%(user)s estas", + "No users have specific privileges in this room": "Neniuj uzantoj havas specialajn privilegiojn en tiu ĉi ĉambro", + "Banned users": "Forbaritaj uzantoj", + "This room is not accessible by remote Matrix servers": "Ĉi tiu ĉambro ne atingeblas por foraj serviloj de Matrix", + "Leave room": "Eliri el ĉambro", + "Favourite": "Ŝatata", + "Tagged as: ": "Etikedita kiel: ", + "To link to a room it must have an address.": "Por esti ligebla, ĉambro devas havi adreson.", + "Guests cannot join this room even if explicitly invited.": "Gastoj ne povas aliĝi ĉi tiun ĉambron eĉ kun malimplica invito.", + "Click here to fix": "Klaku ĉi tie por riparo", + "Who can access this room?": "Kiu povas atingi ĉi tiun ĉambron?", + "Only people who have been invited": "Nur invititaj uzantoj", + "Anyone who knows the room's link, apart from guests": "Iu ajn kun la ligilo, krom gastoj", + "Anyone who knows the room's link, including guests": "Iu ajn kun la ligilo, inkluzive gastojn", + "Publish this room to the public in %(domain)s's room directory?": "Ĉu publikigi ĉi tiun ĉambron al la publika ĉambrujo de %(domain)s?", + "Who can read history?": "Kiu povas legi la historion?", + "Anyone": "Iu ajn", + "Members only (since the point in time of selecting this option)": "Nur ĉambranoj (ekde ĉi tiu elekto)", + "Members only (since they were invited)": "Nur ĉambranoj (ekde la invito)", + "Members only (since they joined)": "Nur ĉambranoj (ekde la aliĝo)", + "Permissions": "Permesoj", + "The default role for new room members is": "La implicita rolo de novaj ĉambranoj estas", + "To send messages, you must be a": "Por sendi mesaĝojn, vi devas esti", + "To invite users into the room, you must be a": "Por inviti uzantojn al la ĉambro, vi devas esti", + "To configure the room, you must be a": "Por agordi la ĉambron, vi devas esti", + "To kick users, you must be a": "Por forpeli uzantojn, vi devas esti", + "To ban users, you must be a": "Por forbari uzantojn, vi devas esti", + "To remove other users' messages, you must be a": "Por forigi mesaĝojn de aliaj uzantoj, vi devas esti", + "To send events of type , you must be a": "Por sendi okazojn de tipo , vi devas esti", + "Advanced": "Specialaj", + "This room's internal ID is": "Interna identigaĵo de tiu ĉi ĉambro estas", + "Add a topic": "Aldoni temon", + "Cancel": "Nuligi", + "Scroll to unread messages": "Rulumi al nelegitaj mesaĝoj", + "Jump to first unread message.": "Salti al unua nelegita mesaĝo.", + "Close": "Fermi", + "Invalid alias format": "Malvalida formo de kromnomo", + "'%(alias)s' is not a valid format for an alias": "‹%(alias)s› ne estas valida formo de kromnomo", + "Invalid address format": "Malvalida formo de adreso", + "'%(alias)s' is not a valid format for an address": "‹%(alias)s› ne estas valida formo de adreso", + "not specified": "nespecifita", + "not set": "neagordita", + "Remote addresses for this room:": "Foraj adresoj de ĉi tiu ĉambro:", + "Addresses": "Adresoj", + "The main address for this room is": "La ĉefadreso por ĉi tiu ĉambro estas", + "Local addresses for this room:": "Lokaj adresoj por ĉi tiu ĉambro:", + "This room has no local addresses": "Ĉi tiu ĉambro ne havas lokajn adresojn", + "New address (e.g. #foo:%(localDomain)s)": "Nova adreso (ekz-e #io:%(localDomain)s)", + "Invalid community ID": "Malvalida komunuma identigaĵo", + "'%(groupId)s' is not a valid community ID": "‹%(groupId)s› ne estas valida komunuma identigaĵo", + "New community ID (e.g. +foo:%(localDomain)s)": "Nova komunuma identigaĵo (ekz-e +io:%(localDomain)s)", + "You have enabled URL previews by default.": "Vi ŝaltis implicitajn antaŭrigardojn al retpaĝoj.", + "You have disabled URL previews by default.": "Vi malŝaltis implicitajn antaŭrigardojn al retpaĝoj.", + "URL previews are enabled by default for participants in this room.": "Antaŭrigardoj al retpaĝoj estas implicite ŝaltitaj por ĉambranoj ĉi tie.", + "URL previews are disabled by default for participants in this room.": "Antaŭrigardoj al retpaĝoj estas implicite malŝaltitaj por ĉambranoj ĉi tie.", + "URL Previews": "Antaŭrigardoj al retpaĝoj", + "Error decrypting audio": "Eraro malĉifrante sonon", + "Error decrypting attachment": "Eraro malĉifrante kunsendaĵon", + "Decrypt %(text)s": "Malĉifri %(text)s", + "Download %(text)s": "Elŝuti %(text)s", + "Invalid file%(extra)s": "Malvalida dosiero%(extra)s", + "Error decrypting image": "Eraro malĉifrante bildon", + "Image '%(Body)s' cannot be displayed.": "Bildo ‹%(Body)s› ne montreblas.", + "This image cannot be displayed.": "Ĉi tiu bildo ne montreblas.", + "Error decrypting video": "Eraro malĉifrante videon", + "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s forigis la ĉambran profilbildon.", + "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s agordis la ĉambran profilbildon al ", + "Copied!": "Kopiita!", + "Failed to copy": "Malsukcesis kopii", + "Add an Integration": "Aldoni integron", + "Removed or unknown message type": "Forigita aŭ nekonata tipo de mesaĝo", + "Message removed by %(userId)s": "Mesaĝo forigita de %(userId)s", + "Message removed": "Mesaĝo forigita", + "Custom Server Options": "Propraj servilaj elektoj", + "Dismiss": "Rezigni", + "powered by Matrix": "funkciigata de Matrix", + "Warning": "Averto", + "Remove": "Forigi", + "Edit": "Redakti", + "Failed to change password. Is your password correct?": "Malsukcesis ŝanĝi la pasvorton. Ĉu via pasvorto estas ĝusta?", + "Leave": "Foriri", + "Register": "Registriĝi", + "Add rooms to this community": "Aldoni ĉambrojn al ĉi tiu komunumo" } From 83f1beb04fe5c15d514d9ead6789e399116d2387 Mon Sep 17 00:00:00 2001 From: Krombel Date: Tue, 12 Dec 2017 14:56:22 +0000 Subject: [PATCH 119/927] Translated using Weblate (German) Currently translated at 99.8% (957 of 958 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 19327771d8..91c75ff975 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -1051,5 +1051,7 @@ "Cryptography data migrated": "Kryptographie-Schlüssel wurden übertragen", "Old cryptography data detected": "Alte Kryptografiedaten erkannt", "Show devices or cancel all.": "Geräte anzeigen oder alle abbrechen.", - "Warning": "Warnung" + "Warning": "Warnung", + "A one-off migration of cryptography data has been performed. End-to-end encryption will not work if you go back to an older version of Riot. If you need to use end-to-end cryptography on an older version, log out of Riot first. To retain message history, export and re-import your keys.": "Eine tiefgreifende Migration im Kontext der Verschlüsselungsdaten wurde durchgeführt. Ende-zu-Ende-Verschlüsselung wird nicht mehr funktionieren, wenn du zu einer älteren Version von Riot zurückkehrst. Wenn du Ende-zu-Ende-Verschlüssung bei einer älteren Version von Riot brauchst, melde dich bitte vorher ab. Um die Historie zu behalten, ex- und reimportiere deine Schlüssel.", + "Data from an older version of Riot has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Es wurden Daten von einer älteren Version von Riot entdeckt. Dies wird zu Fehlern in der Ende-zu-Ende-Verschlüsselung der älteren Version geführt haben. Ende-zu-Ende verschlüsselte Nachrichten, die ausgetauscht wruden, während die ältere Version genutzt wurde, werden in dieser Version nicht entschlüsselbar sein. Es kann auch zu Fehlern mit Nachrichten führen, die mit dieser Version versendet werden. Wenn du Probleme feststellst, melde dich ab und wieder an. Um die Historie zu behalten, ex- und reimportiere deine Schlüssel." } From 642675c96da9fb31d191539f884872d2b7717c27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Thu, 14 Dec 2017 10:31:28 +0100 Subject: [PATCH 120/927] Address review request comments --- .../views/dialogs/InteractiveAuthDialog.js | 2 +- .../dialogs/SessionRestoreErrorDialog.js | 5 +- .../login/InteractiveAuthEntryComponents.js | 51 ++++++++++++++----- 3 files changed, 43 insertions(+), 15 deletions(-) diff --git a/src/components/views/dialogs/InteractiveAuthDialog.js b/src/components/views/dialogs/InteractiveAuthDialog.js index d1273849ae..5b0e34df2c 100644 --- a/src/components/views/dialogs/InteractiveAuthDialog.js +++ b/src/components/views/dialogs/InteractiveAuthDialog.js @@ -73,7 +73,7 @@ export default React.createClass({ if (this.state.authError) { content = (
-
{ this.state.authError.message || this.state.authError.toString() }
+
{ this.state.authError.message || this.state.authError.toString() }

); } + const shouldFocusContinueButton =!(bugreport==true); return ( -
-
diff --git a/src/components/views/login/InteractiveAuthEntryComponents.js b/src/components/views/login/InteractiveAuthEntryComponents.js index 81b84684fc..a0bb1065f2 100644 --- a/src/components/views/login/InteractiveAuthEntryComponents.js +++ b/src/components/views/login/InteractiveAuthEntryComponents.js @@ -127,6 +127,15 @@ export const PasswordAuthEntry = React.createClass({ ); } + let errorSection; + if (this.props.errorText) { + errorSection = ( +
+ { this.props.errorText } +
+ ); + } + return (

{ _t("To continue, please enter your password.") }

@@ -143,9 +152,7 @@ export const PasswordAuthEntry = React.createClass({ { submitButtonOrSpinner }
-
- { this.props.errorText } -
+ { errorSection }
); }, @@ -180,14 +187,22 @@ export const RecaptchaAuthEntry = React.createClass({ const CaptchaForm = sdk.getComponent("views.login.CaptchaForm"); const sitePublicKey = this.props.stageParams.public_key; + + let errorSection; + if (this.props.errorText) { + errorSection = ( +
+ { this.props.errorText } +
+ ); + } + return (
-
- { this.props.errorText } -
+ { errorSection }
); }, @@ -372,6 +387,14 @@ export const MsisdnAuthEntry = React.createClass({ mx_InteractiveAuthEntryComponents_msisdnSubmit: true, mx_UserSettings_button: true, // XXX button classes }); + let errorSection; + if (this.state.errorText) { + errorSection = ( +
+ { this.state.errorText } +
+ ); + } return (

{ _t("A text message has been sent to %(msisdn)s", @@ -393,9 +416,7 @@ export const MsisdnAuthEntry = React.createClass({ disabled={!enableSubmit} /> -

- { this.state.errorText } -
+ {errorSection}
); @@ -452,12 +473,18 @@ export const FallbackAuthEntry = React.createClass({ }, render: function() { + let errorSection; + if (this.props.errorText) { + errorSection = ( +
+ { this.props.errorText } +
+ ); + } return (
{ _t("Start authentication") } -
- { this.props.errorText } -
+ {errorSection}
); }, From 34e455c6fcdab56ec404ed8f0b677d402850a823 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Fri, 15 Dec 2017 14:12:21 +0000 Subject: [PATCH 121/927] Fix leaking of GroupStore listeners in RoomList --- src/components/views/rooms/RoomList.js | 16 ++++++++++++---- src/stores/GroupStore.js | 6 ++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index d94fef7d31..8c2bdd5994 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -86,6 +86,7 @@ module.exports = React.createClass({ const dmRoomMap = DMRoomMap.shared(); this._groupStores = {}; + this._groupStoreTokens = []; // A map between tags which are group IDs and the room IDs of rooms that should be kept // in the room list when filtering by that tag. this._selectedTagsRoomIdsForGroup = { @@ -100,10 +101,12 @@ module.exports = React.createClass({ return; } this._groupStores[tag] = GroupStoreCache.getGroupStore(tag); - this._groupStores[tag].registerListener(() => { - // This group's rooms or members may have updated, update rooms for its tag - this.updateSelectedTagsRooms(dmRoomMap, [tag]); - }); + this._groupStoreTokens.push( + this._groupStores[tag].registerListener(() => { + // This group's rooms or members may have updated, update rooms for its tag + this.updateSelectedTagsRooms(dmRoomMap, [tag]); + }), + ); }); // Filters themselves have changed, refresh the selected tags this.updateSelectedTagsRooms(dmRoomMap, FilterStore.getSelectedTags()); @@ -182,6 +185,11 @@ module.exports = React.createClass({ this._filterStoreToken.remove(); } + if (this._groupStoreTokens.length > 0) { + // NB: GroupStore is not a Flux.Store + this._groupStoreTokens.forEach((token) => token.unregister()); + } + // cancel any pending calls to the rate_limited_funcs this._delayedRefreshRoomList.cancelPendingCall(); }, diff --git a/src/stores/GroupStore.js b/src/stores/GroupStore.js index 8d95d1975b..483eed96a5 100644 --- a/src/stores/GroupStore.js +++ b/src/stores/GroupStore.js @@ -110,6 +110,12 @@ export default class GroupStore extends EventEmitter { this._fetchSummary(); this._fetchRooms(); this._fetchMembers(); + + return { + unregister: () => { + this.unregisterListener(fn); + }, + }; } unregisterListener(fn) { From c234e209fbb375b8ef227fa1d27648d961bb496b Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Fri, 15 Dec 2017 15:24:22 +0000 Subject: [PATCH 122/927] Add postmessage api and move functions in to class --- src/MatrixPostMessageApi.js | 101 +++++++++++ src/WidgetMessaging.js | 348 +++++++++++++++++++----------------- 2 files changed, 286 insertions(+), 163 deletions(-) create mode 100644 src/MatrixPostMessageApi.js diff --git a/src/MatrixPostMessageApi.js b/src/MatrixPostMessageApi.js new file mode 100644 index 0000000000..dd65cbd8fa --- /dev/null +++ b/src/MatrixPostMessageApi.js @@ -0,0 +1,101 @@ +import Promise from "bluebird"; + + +function defer() { + let resolve, reject; + let isPending = true; + let promise = new Promise(function(...args) { + resolve = args[0]; + reject = args[1]; + }); + return { + resolve: function(...args) { + if (!isPending) { + return; + } + isPending = false; + resolve(args[0]); + }, + reject: function(...args) { + if (!isPending) { + return; + } + isPending = false; + reject(args[0]); + }, + isPending: function() { + return isPending; + }, + promise: promise, + }; +} + +// NOTE: PostMessageApi only handles message events with a data payload with a +// response field +export default class PostMessageApi { + constructor(targetWindow, timeoutMs) { + this._window = targetWindow || window.parent; // default to parent window + this._timeoutMs = timeoutMs || 5000; // default to 5s timer + this._counter = 0; + this._pending = { + // $ID: Deferred + }; + } + + start() { + addEventListener('message', this.getOnMessageCallback()); + } + + stop() { + removeEventListener('message', this.getOnMessageCallback()); + } + + // Somewhat convoluted so we can successfully capture the PostMessageApi 'this' instance. + getOnMessageCallback() { + if (this._onMsgCallback) { + return this._onMsgCallback; + } + let self = this; + this._onMsgCallback = function(ev) { + // THIS IS ALL UNSAFE EXECUTION. + // We do not verify who the sender of `ev` is! + let payload = ev.data; + // NOTE: Workaround for running in a mobile WebView where a + // postMessage immediately triggers this callback even though it is + // not the response. + if (payload.response === undefined) { + return; + } + let deferred = self._pending[payload._id]; + if (!deferred) { + return; + } + if (!deferred.isPending()) { + return; + } + delete self._pending[payload._id]; + deferred.resolve(payload); + }; + return this._onMsgCallback; + } + + exec(action, target) { + this._counter += 1; + target = target || "*"; + action._id = Date.now() + "-" + Math.random().toString(36) + "-" + this._counter; + let d = defer(); + this._pending[action._id] = d; + this._window.postMessage(action, target); + + if (this._timeoutMs > 0) { + setTimeout(function() { + if (!d.isPending()) { + return; + } + console.error("postMessage request timed out. Sent object: " + JSON.stringify(action)); + d.reject(new Error("Timed out")); + }, this._timeoutMs); + } + return d.promise; + } +} diff --git a/src/WidgetMessaging.js b/src/WidgetMessaging.js index 0f23413b5f..7cd18132af 100644 --- a/src/WidgetMessaging.js +++ b/src/WidgetMessaging.js @@ -112,14 +112,14 @@ Example: */ import URL from 'url'; +import dis from './dispatcher'; +import MatrixPostMessageApi from './MatrixPostMessageApi'; const WIDGET_API_VERSION = '0.0.1'; // Current API version const SUPPORTED_WIDGET_API_VERSIONS = [ '0.0.1', ]; -import dis from './dispatcher'; - if (!global.mxWidgetMessagingListenerCount) { global.mxWidgetMessagingListenerCount = 0; } @@ -127,176 +127,205 @@ if (!global.mxWidgetMessagingMessageEndpoints) { global.mxWidgetMessagingMessageEndpoints = []; } - -/** - * Register widget message event listeners - */ -function startListening() { - if (global.mxWidgetMessagingListenerCount === 0) { - window.addEventListener("message", onMessage, false); - } - global.mxWidgetMessagingListenerCount += 1; -} - -/** - * De-register widget message event listeners - */ -function stopListening() { - global.mxWidgetMessagingListenerCount -= 1; - if (global.mxWidgetMessagingListenerCount === 0) { - window.removeEventListener("message", onMessage); - } - if (global.mxWidgetMessagingListenerCount < 0) { - // Make an error so we get a stack trace - const e = new Error( - "WidgetMessaging: mismatched startListening / stopListening detected." + - " Negative count", - ); - console.error(e); - } -} - -/** - * Register a widget endpoint for trusted postMessage communication - * @param {string} widgetId Unique widget identifier - * @param {string} endpointUrl Widget wurl origin (protocol + (optional port) + host) - */ -function addEndpoint(widgetId, endpointUrl) { - const u = URL.parse(endpointUrl); - if (!u || !u.protocol || !u.host) { - console.warn("Invalid origin:", endpointUrl); - return; +export default class WidgetMessaging extends MatrixPostMessageApi { + constructor(targetWindow) { + super(targetWindow); } - const origin = u.protocol + '//' + u.host; - const endpoint = new WidgetMessageEndpoint(widgetId, origin); - if (global.mxWidgetMessagingMessageEndpoints) { - if (global.mxWidgetMessagingMessageEndpoints.some(function(ep) { - return (ep.widgetId === widgetId && ep.endpointUrl === endpointUrl); - })) { - // Message endpoint already registered - console.warn("Endpoint already registered"); + exec(action) { + return super.exec(action).then((data) => { + // check for errors and reject if found + if (data.response === undefined) { // null is valid + throw new Error("Missing 'response' field"); + } + if (data.response && data.response.error) { + const err = data.response.error; + const msg = String(err.message ? err.message : "An error was returned"); + if (err._error) { + console.error(err._error); + } + // Potential XSS attack if 'msg' is not appropriately sanitized, + // as it is untrusted input by our parent window (which we assume is Riot). + // We can't aggressively sanitize [A-z0-9] since it might be a translation. + throw new Error(msg); + } + // return the response field for the request + return data.response; + }); + } + + /** + * Register widget message event listeners + */ + startListening() { + if (global.mxWidgetMessagingListenerCount === 0) { + window.addEventListener("message", this.onMessage, false); + } + global.mxWidgetMessagingListenerCount += 1; + } + + /** + * De-register widget message event listeners + */ + stopListening() { + global.mxWidgetMessagingListenerCount -= 1; + if (global.mxWidgetMessagingListenerCount === 0) { + window.removeEventListener("message", this.onMessage); + } + if (global.mxWidgetMessagingListenerCount < 0) { + // Make an error so we get a stack trace + const e = new Error( + "WidgetMessaging: mismatched startListening / stopListening detected." + + " Negative count", + ); + console.error(e); + } + } + + /** + * Register a widget endpoint for trusted postMessage communication + * @param {string} widgetId Unique widget identifier + * @param {string} endpointUrl Widget wurl origin (protocol + (optional port) + host) + */ + addEndpoint(widgetId, endpointUrl) { + const u = URL.parse(endpointUrl); + if (!u || !u.protocol || !u.host) { + console.warn("Invalid origin:", endpointUrl); return; } - global.mxWidgetMessagingMessageEndpoints.push(endpoint); - } -} -/** - * De-register a widget endpoint from trusted communication sources - * @param {string} widgetId Unique widget identifier - * @param {string} endpointUrl Widget wurl origin (protocol + (optional port) + host) - * @return {boolean} True if endpoint was successfully removed - */ -function removeEndpoint(widgetId, endpointUrl) { - const u = URL.parse(endpointUrl); - if (!u || !u.protocol || !u.host) { - console.warn("Invalid origin"); - return; + const origin = u.protocol + '//' + u.host; + const endpoint = new WidgetMessageEndpoint(widgetId, origin); + if (global.mxWidgetMessagingMessageEndpoints) { + if (global.mxWidgetMessagingMessageEndpoints.some(function(ep) { + return (ep.widgetId === widgetId && ep.endpointUrl === endpointUrl); + })) { + // Message endpoint already registered + console.warn("Endpoint already registered"); + return; + } + global.mxWidgetMessagingMessageEndpoints.push(endpoint); + } } - const origin = u.protocol + '//' + u.host; - if (global.mxWidgetMessagingMessageEndpoints && global.mxWidgetMessagingMessageEndpoints.length > 0) { - const length = global.mxWidgetMessagingMessageEndpoints.length; - global.mxWidgetMessagingMessageEndpoints = global.mxWidgetMessagingMessageEndpoints.filter(function(endpoint) { - return (endpoint.widgetId != widgetId || endpoint.endpointUrl != origin); - }); - return (length > global.mxWidgetMessagingMessageEndpoints.length); - } - return false; -} + /** + * De-register a widget endpoint from trusted communication sources + * @param {string} widgetId Unique widget identifier + * @param {string} endpointUrl Widget wurl origin (protocol + (optional port) + host) + * @return {boolean} True if endpoint was successfully removed + */ + removeEndpoint(widgetId, endpointUrl) { + const u = URL.parse(endpointUrl); + if (!u || !u.protocol || !u.host) { + console.warn("Invalid origin"); + return; + } - -/** - * Handle widget postMessage events - * @param {Event} event Event to handle - * @return {undefined} - */ -function onMessage(event) { - if (!event.origin) { // Handle chrome - event.origin = event.originalEvent.origin; - } - - // Event origin is empty string if undefined - if ( - event.origin.length === 0 || - !trustedEndpoint(event.origin) || - event.data.api !== "widget" || - !event.data.widgetId - ) { - return; // don't log this - debugging APIs like to spam postMessage which floods the log otherwise - } - - const action = event.data.action; - const widgetId = event.data.widgetId; - if (action === 'content_loaded') { - dis.dispatch({ - action: 'widget_content_loaded', - widgetId: widgetId, - }); - sendResponse(event, {success: true}); - } else if (action === 'supported_api_versions') { - sendResponse(event, { - api: "widget", - supported_versions: SUPPORTED_WIDGET_API_VERSIONS, - }); - } else if (action === 'api_version') { - sendResponse(event, { - api: "widget", - version: WIDGET_API_VERSION, - }); - } else { - console.warn("Widget postMessage event unhandled"); - sendError(event, {message: "The postMessage was unhandled"}); - } -} - -/** - * Check if message origin is registered as trusted - * @param {string} origin PostMessage origin to check - * @return {boolean} True if trusted - */ -function trustedEndpoint(origin) { - if (!origin) { + const origin = u.protocol + '//' + u.host; + if (global.mxWidgetMessagingMessageEndpoints && global.mxWidgetMessagingMessageEndpoints.length > 0) { + const length = global.mxWidgetMessagingMessageEndpoints.length; + global.mxWidgetMessagingMessageEndpoints = global.mxWidgetMessagingMessageEndpoints. + filter(function(endpoint) { + return (endpoint.widgetId != widgetId || endpoint.endpointUrl != origin); + }); + return (length > global.mxWidgetMessagingMessageEndpoints.length); + } return false; } - return global.mxWidgetMessagingMessageEndpoints.some((endpoint) => { - return endpoint.endpointUrl === origin; - }); -} -/** - * Send a postmessage response to a postMessage request - * @param {Event} event The original postMessage request event - * @param {Object} res Response data - */ -function sendResponse(event, res) { - const data = JSON.parse(JSON.stringify(event.data)); - data.response = res; - event.source.postMessage(data, event.origin); -} + /** + * Handle widget postMessage events + * @param {Event} event Event to handle + * @return {undefined} + */ + onMessage(event) { + if (!event.origin) { // Handle chrome + event.origin = event.originalEvent.origin; + } -/** - * Send an error response to a postMessage request - * @param {Event} event The original postMessage request event - * @param {string} msg Error message - * @param {Error} nestedError Nested error event (optional) - */ -function sendError(event, msg, nestedError) { - console.error("Action:" + event.data.action + " failed with message: " + msg); - const data = JSON.parse(JSON.stringify(event.data)); - data.response = { - error: { - message: msg, - }, - }; - if (nestedError) { - data.response.error._error = nestedError; + // Event origin is empty string if undefined + if ( + event.origin.length === 0 || + !this.trustedEndpoint(event.origin) || + event.data.api !== "widget" || + !event.data.widgetId + ) { + return; // don't log this - debugging APIs like to spam postMessage which floods the log otherwise + } + + const action = event.data.action; + const widgetId = event.data.widgetId; + if (action === 'content_loaded') { + dis.dispatch({ + action: 'widget_content_loaded', + widgetId: widgetId, + }); + this.sendResponse(event, {success: true}); + } else if (action === 'supported_api_versions') { + this.sendResponse(event, { + api: "widget", + supported_versions: SUPPORTED_WIDGET_API_VERSIONS, + }); + } else if (action === 'api_version') { + this.sendResponse(event, { + api: "widget", + version: WIDGET_API_VERSION, + }); + } else { + console.warn("Widget postMessage event unhandled"); + this.sendError(event, {message: "The postMessage was unhandled"}); + } + } + + /** + * Check if message origin is registered as trusted + * @param {string} origin PostMessage origin to check + * @return {boolean} True if trusted + */ + trustedEndpoint(origin) { + if (!origin) { + return false; + } + + return global.mxWidgetMessagingMessageEndpoints.some((endpoint) => { + return endpoint.endpointUrl === origin; + }); + } + + /** + * Send a postmessage response to a postMessage request + * @param {Event} event The original postMessage request event + * @param {Object} res Response data + */ + sendResponse(event, res) { + const data = JSON.parse(JSON.stringify(event.data)); + data.response = res; + event.source.postMessage(data, event.origin); + } + + /** + * Send an error response to a postMessage request + * @param {Event} event The original postMessage request event + * @param {string} msg Error message + * @param {Error} nestedError Nested error event (optional) + */ + sendError(event, msg, nestedError) { + console.error("Action:" + event.data.action + " failed with message: " + msg); + const data = JSON.parse(JSON.stringify(event.data)); + data.response = { + error: { + message: msg, + }, + }; + if (nestedError) { + data.response.error._error = nestedError; + } + event.source.postMessage(data, event.origin); } - event.source.postMessage(data, event.origin); } + /** * Represents mapping of widget instance to URLs for trusted postMessage communication. */ @@ -317,10 +346,3 @@ class WidgetMessageEndpoint { this.endpointUrl = endpointUrl; } } - -export default { - startListening: startListening, - stopListening: stopListening, - addEndpoint: addEndpoint, - removeEndpoint: removeEndpoint, -}; From 6e832c7d73b93c48187c7692792e03ff26c69e45 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Fri, 15 Dec 2017 16:28:50 +0000 Subject: [PATCH 123/927] Dedupe requests to fetch group profile data --- src/stores/FlairStore.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/stores/FlairStore.js b/src/stores/FlairStore.js index 55c4978925..e9e84e9aa1 100644 --- a/src/stores/FlairStore.js +++ b/src/stores/FlairStore.js @@ -39,6 +39,9 @@ class FlairStore { // avatar_url: 'mxc://...' // } }; + this._groupProfilesPromise = { + // $groupId: Promise + }; this._usersPending = { // $userId: { // prom: Promise @@ -149,15 +152,22 @@ class FlairStore { return this._groupProfiles[groupId]; } - const profile = await matrixClient.getGroupProfile(groupId); + // No request yet, start one + if (!this._groupProfilesPromise[groupId]) { + this._groupProfilesPromise[groupId] = matrixClient.getGroupProfile(groupId); + } + + const profile = await this._groupProfilesPromise[groupId]; this._groupProfiles[groupId] = { groupId, avatarUrl: profile.avatar_url, name: profile.name, shortDescription: profile.short_description, }; + setTimeout(() => { delete this._groupProfiles[groupId]; + delete this._groupProfilesPromise[groupId]; }, GROUP_PROFILES_CACHE_BUST_MS); return this._groupProfiles[groupId]; From 66fb73af5dd4b4baecb016d2936f653904f138af Mon Sep 17 00:00:00 2001 From: Tirifto Date: Fri, 15 Dec 2017 13:33:11 +0000 Subject: [PATCH 124/927] Translated using Weblate (Esperanto) Currently translated at 58.2% (558 of 958 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eo/ --- src/i18n/strings/eo.json | 56 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/eo.json b/src/i18n/strings/eo.json index 3a46ae428c..463713e9ea 100644 --- a/src/i18n/strings/eo.json +++ b/src/i18n/strings/eo.json @@ -502,5 +502,59 @@ "Failed to change password. Is your password correct?": "Malsukcesis ŝanĝi la pasvorton. Ĉu via pasvorto estas ĝusta?", "Leave": "Foriri", "Register": "Registriĝi", - "Add rooms to this community": "Aldoni ĉambrojn al ĉi tiu komunumo" + "Add rooms to this community": "Aldoni ĉambrojn al ĉi tiu komunumo", + "Robot check is currently unavailable on desktop - please use a web browser": "Kontrolo kontraŭ robotoj ne disponeblas sur labortablo – bonvolu uzi retan foliumilon", + "This Home Server would like to make sure you are not a robot": "Tiu ĉi hejmservilo volas certigi, ke vi ne estas roboto", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.": "Vi povas uzi proprajn servilajn elektojn por saluti aliajn servilojn de Matrix per alia hejmservila URL.", + "This allows you to use this app with an existing Matrix account on a different home server.": "Tio ĉi permesos al vi uzi ĉi tiun aplikaĵon kun jama konto de Matrix el alia hejmservilo.", + "You can also set a custom identity server but this will typically prevent interaction with users based on email address.": "Vi ankaŭ povas agordi propran identigan servilon, sed tio kutime malebligas interagadon kun uzantkontoj bazitaj sur retpoŝto.", + "To continue, please enter your password.": "Por daŭrigi, bonvolu enigi vian pasvorton.", + "Password:": "Pasvorto:", + "An email has been sent to %(emailAddress)s": "Retletero sendiĝis al %(emailAddress)s", + "Please check your email to continue registration.": "Bonvolu kontroli vian retpoŝton por daŭrigi la registriĝon.", + "Token incorrect": "Malĝusta ĵetono", + "A text message has been sent to %(msisdn)s": "Tekstmesaĝo sendiĝîs al %(msisdn)s", + "Please enter the code it contains:": "Bonvolu enigi la enhavatan kodon:", + "Start authentication": "Komenci aŭtentigon", + "Username on %(hs)s": "Uzantnomo je %(hs)s", + "User name": "Uzantnomo", + "Mobile phone number": "Telefona numero", + "Forgot your password?": "Ĉu vi forgesis vian pasvorton?", + "%(serverName)s Matrix ID": "%(serverName)s Matrix ID", + "Email address": "Retpoŝtadreso", + "If you don't specify an email address, you won't be able to reset your password. Are you sure?": "Se vi ne enigos retpoŝtadreson, vi ne povos restarigi vian pasvorton. Ĉu vi certas?", + "Email address (optional)": "Retpoŝtadreso (malnepra)", + "You are registering with %(SelectedTeamName)s": "Vi registriĝas kun %(SelectedTeamName)s", + "Mobile phone number (optional)": "Telefona numero (malnepra)", + "Default server": "Implicita servilo", + "Custom server": "Propra servilo", + "Home server URL": "URL de hejmservilo", + "Identity server URL": "URL de identiga servilo", + "What does this mean?": "Kion ĝi signifas?", + "Remove from community": "Forigi de komunumo", + "Disinvite this user from community?": "Ĉu malinviti ĉi tiun uzanton de komunumo?", + "Remove this user from community?": "Ĉu forigi ĉi tiun uzanton de komunumo?", + "Failed to withdraw invitation": "Malsukcesis malinviti", + "Failed to remove user from community": "Malsukcesis forigi uzanton de komunumo", + "Filter community members": "Filtri komunumanojn", + "Are you sure you want to remove '%(roomName)s' from %(groupId)s?": "Ĉu vi certe volas forigi ‹%(roomName)s› de %(groupId)s?", + "Removing a room from the community will also remove it from the community page.": "Per forigo de ĉambro de la komunumo vi ankaŭ forigos ĝin de la paĝo de tiu komunumo.", + "Failed to remove room from community": "Malsukcesis forigi ĉambron de komunumo", + "Failed to remove '%(roomName)s' from %(groupId)s": "Malsukcesis forigi ‹%(roomName)s› de %(groupId)s", + "Something went wrong!": "Io misokazis!", + "The visibility of '%(roomName)s' in %(groupId)s could not be updated.": "Videbleco de ‹%(roomName)s› en %(groupId)s ne ĝisdatigeblis.", + "Visibility in Room List": "Videbleco en Listo de ĉambroj", + "Visible to everyone": "Videbla al ĉiuj", + "Only visible to community members": "Videbla nur al komunumanoj", + "Filter community rooms": "Filtri komunumajn ĉambrojn", + "Something went wrong when trying to get your communities.": "Io misokazis dum legado de viaj komunumoj.", + "You're not currently a member of any communities.": "Vi nuntempe apartenas al neniu komunumo.", + "Unknown Address": "Nekonata adreso", + "NOTE: Apps are not end-to-end encrypted": "RIMARKO: Aplikaĝoj ne estas ĝiscele ĉifritaj", + "Do you want to load widget from URL:": "Ĉu vi volas enlegi fenestraĵon el URL:", + "Allow": "Permesi", + "Delete Widget": "Forigi fenestraĵon", + "Delete widget": "Forigi fenestraĵon", + "Revoke widget access": "Malvalidigi atingon de fenestraĵo", + "Create new room": "Krei novan ĉambron" } From 86f1dc1130c05dbf717c7f62c70ccc16e500db8d Mon Sep 17 00:00:00 2001 From: Juho Ylikorpi Date: Thu, 14 Dec 2017 18:40:10 +0000 Subject: [PATCH 125/927] Translated using Weblate (Finnish) Currently translated at 92.0% (882 of 958 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fi/ --- src/i18n/strings/fi.json | 65 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 3 deletions(-) diff --git a/src/i18n/strings/fi.json b/src/i18n/strings/fi.json index 4752d68999..5c7095b511 100644 --- a/src/i18n/strings/fi.json +++ b/src/i18n/strings/fi.json @@ -255,7 +255,7 @@ "Public Chat": "Julkinen keskustelu", "Reason": "Syy", "Reason: %(reasonText)s": "Syy: %(reasonText)s", - "Register": "Rekisteröi", + "Register": "Rekisteröidy", "Reject invitation": "Hylkää kutsu", "Rejoin": "Liity uudestaan", "Remove Contact Information?": "Poista yhteystiedot?", @@ -854,7 +854,7 @@ "Leave": "Poistu", "Unable to leave room": "Poistuminen epäonnistui", "Community Settings": "Yhteisöasetukset", - "Add rooms to this community": "Lisää huoneita tähän yhteisöön", + "Add rooms to this community": "Lisää huoneita yhteisöön", "Featured Rooms:": "Esiinnostetut huoneet:", "Featured Users:": "Esiinnostetut käyttäjät:", "%(inviter)s has invited you to join this community": "%(inviter)s on kutsunut sinut tähän yhteisöön", @@ -886,5 +886,64 @@ "Ignores a user, hiding their messages from you": "Jättää käyttäjän huomioimatta jolloin heidän viestejä ei näytetä sinulle", "Stops ignoring a user, showing their messages going forward": "Lopettaa käyttäjän huomiotta jättämisen jolloin heidän tulevat viestit näytetään sinulle", "Notify the whole room": "Hälytä koko huone", - "Room Notification": "Huonehälytys" + "Room Notification": "Huonehälytys", + "Call Failed": "Puhelu epäonnistui", + "There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "Huoneessa on tuntemattomia laitteita: jos jatkat varmentamatta niitä, joku voi kuunnella puheluasi.", + "Review Devices": "Näytä Laitteet", + "Call Anyway": "Soita", + "Answer Anyway": "Vastaa", + "Call": "Puhelu", + "Answer": "Vastaa", + "Call Timeout": "Puhelun aikakatkaisu", + "%(weekDayName)s %(time)s": "%(weekDayName)s %(time)s", + "%(weekDayName)s, %(monthName)s %(day)s %(time)s": "%(weekDayName)s, %(monthName)s %(day)s %(time)s", + "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s %(time)s": "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s %(time)s", + "Ignored user": "Estetyt käyttäjät", + "Unignored user": "Sallitut käyttäjät", + "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s tasolta %(fromPowerLevel)s tasolle %(toPowerLevel)s", + "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s muutettiin tehotasoa %(powerLevelDiffText)s.", + "%(widgetName)s widget modified by %(senderName)s": "%(widgetName)s pienoisohjelmaa muokannut %(senderName)s", + "%(widgetName)s widget added by %(senderName)s": "%(widgetName)s pienoisohjelman lisännyt %(senderName)s", + "%(widgetName)s widget removed by %(senderName)s": "%(widgetName)s pienoisohjelman poistanut %(senderName)s", + "Send": "Lähetä", + "Presence Management": "Tilanhallinta", + "Tag Panel": "Tagit", + "Delete %(count)s devices|other": "Poista %(count)s laitetta", + "Delete %(count)s devices|one": "Poista laite", + "Select devices": "Valitse laitteet", + "Ongoing conference call%(supportedText)s.": "Menossa oleva ryhmäpuhelu %(supportedText)s.", + "%(duration)ss": "%(duration)s", + "%(duration)sm": "%(duration)sm", + "%(duration)sh": "%(duration)sh", + "%(duration)sd": "%(duration)s päivä", + "Online for %(duration)s": "Läsnä %(duration)s", + "Idle for %(duration)s": "Toimettomana %(duration)s", + "Offline for %(duration)s": "Poissa %(duration)s", + "Unknown for %(duration)s": "Tuntematon %(duration)s", + "Online": "Online", + "Idle": "Toimeton", + "Offline": "Offline", + "Unknown": "Tuntematon", + "To change the room's avatar, you must be a": "Vaihtaaksesi huoneen kuvan, sinun tulee olla", + "To change the room's name, you must be a": "Vaihtaaksesi huoneen nimen, sinun tulee olla", + "To change the room's main address, you must be a": "Vaihtaaksesi huoneen osoitteen, sinun tulee olla", + "To change the room's history visibility, you must be a": "Vaihtaaksesi huoneen historiatietojen näkyvyyttä, sinun tulee olla", + "To change the permissions in the room, you must be a": "Vaihtaaksesi huoneen oikeuksia, sinun tulee olla", + "To change the topic, you must be a": "Vaihtaaksesi huoneen aihetta, sinun tulee olla", + "To modify widgets in the room, you must be a": "Vaihtaaksesi huoneen pienoisohjelmia, sinun tulee olla", + "Addresses": "Osoitteet", + "Flair": "Tyyppi", + "Showing flair for these communities:": "Yhteisöjen tyypit:", + "This room is not showing flair for any communities": "Tälle huoneelle ei ole määritelty minkään yhteisön tyyppiä", + "URL previews are enabled by default for participants in this room.": "URL esikatselut on päällä oletusarvoisesti tämän huoneen jäsenillä.", + "URL previews are disabled by default for participants in this room.": "URL esikatselut ovat oletuksena pois päältä tämän huoneen jäsenillä.", + "Token incorrect": "Väärä tunniste", + "Flair will appear if enabled in room settings": "Tyyppi näkyy jos määritelty tämän huoneen asetuksissa", + "Flair will not appear": "Tyyppi ei näkyvissä", + "Something went wrong when trying to get your communities.": "Jokin meni pieleen haettaessa yhteisöjäsi.", + "Delete Widget": "Poista pienoisohjelma", + "Revoke widget access": "Poista pienoisohjelman oikeudet", + "Unblacklist": "Poista estolistalta", + "Blacklist": "Estolista", + "%(severalUsers)sjoined %(count)s times|one": "%(severalUsers)s käyttäjää liittyi" } From 74bc992fd94e2af301d9f1ade82909e525b19226 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=B6ller=20Bertalan?= Date: Thu, 14 Dec 2017 18:38:04 +0000 Subject: [PATCH 126/927] Translated using Weblate (Hungarian) Currently translated at 100.0% (958 of 958 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index f20370f40d..35278a5975 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -747,7 +747,7 @@ "PM": "du", "Revoke widget access": "Kisalkalmazás hozzáférésének visszavonása", "Sets the room topic": "Szoba téma beállítás", - "Show Apps": "Alkalmazások megmutatása", + "Show Apps": "Alkalmazások mutatása", "To get started, please pick a username!": "Az induláshoz válassz egy felhasználói nevet!", "Unable to create widget.": "Nem lehet kisalkalmazást létrehozni.", "Unbans user with given id": "Visszaengedi a megadott azonosítójú felhasználót", @@ -1018,9 +1018,9 @@ "URL previews are disabled by default for participants in this room.": "Az URL előnézet alapértelmezetten tiltva van a szobában jelenlévőknek.", "Resend all or cancel all now. You can also select individual messages to resend or cancel.": "Mindet újraküldöd vagy mindet megszakítod. De egyenként is kijelölheted az üzenetet elküldésre vagy megszakításra.", "There's no one else here! Would you like to invite others or stop warning about the empty room?": "Senki más nincs itt! Szeretnél meghívni másokat vagy leállítod a figyelmeztetést az üres szobára?", - "%(duration)ss": "%(duration)s mp.", - "%(duration)sm": "%(duration)s p.", - "%(duration)sh": "%(duration)s ó.", + "%(duration)ss": "%(duration)s mp", + "%(duration)sm": "%(duration)s p", + "%(duration)sh": "%(duration)s ó", "%(duration)sd": "%(duration)s nap", "Online for %(duration)s": "%(duration)s óta elérhető", "Idle for %(duration)s": "%(duration)s óta tétlen", From 56f497d39eddefa036bb9c81fe1c27e9f799f69a Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Fri, 15 Dec 2017 16:39:04 +0000 Subject: [PATCH 127/927] Add comments and outbound postmessage action to request a widget screenshot. --- src/WidgetMessaging.js | 53 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/src/WidgetMessaging.js b/src/WidgetMessaging.js index 7cd18132af..a35dc3d714 100644 --- a/src/WidgetMessaging.js +++ b/src/WidgetMessaging.js @@ -52,8 +52,8 @@ They look like: } The "message" key should be a human-friendly string. -ACTIONS -======= +INBOUND ACTIONS +=============== ** All actions must include an "api" field with valie "widget".** All actions can return an error response instead of the response outlined below. @@ -109,6 +109,45 @@ Example: action: "supported_api_versions", } + +OUTBOUND ACTIONS +================ + +In addition to listening for inbound requests, the API can be used to initiate +actionss in the widget iframe, and request data from the widget instance. + +Outbound actions use the "widget_client" API key / name, which must be included +on all requests. + +{ + api: "widget_client", + action: "screenshot", + widgetId: $WIDGET_ID, + data: {} + // additional request fields +} + + +screenshot +---------- + +Request a screenshot from the widget (if supported). +This can only be supported by widgets that have access to all of their DOM tree. +For example, widgets that nest further levels of iframes can not support this. + +Request: + - No additional fields. +Response: +{ + screenshot: {data...} +} +Example: +{ + api: "widget_client", + action: "screenshot", + widgetId: $WIDGET_ID +} + */ import URL from 'url'; @@ -323,6 +362,16 @@ export default class WidgetMessaging extends MatrixPostMessageApi { } event.source.postMessage(data, event.origin); } + + /** + * Request a screenshot from a widget + */ + getScreenshot() { + const screenshot = this.exec({ + action: "screenshot", + }); + console.warn("got screenshot", screenshot); + } } From 9f733ebc940760059ecf6321163b1c2f67a9098c Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Fri, 15 Dec 2017 16:55:33 +0000 Subject: [PATCH 128/927] Fix binding and promise handling --- src/WidgetMessaging.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/WidgetMessaging.js b/src/WidgetMessaging.js index a35dc3d714..1180dd2df2 100644 --- a/src/WidgetMessaging.js +++ b/src/WidgetMessaging.js @@ -198,7 +198,7 @@ export default class WidgetMessaging extends MatrixPostMessageApi { */ startListening() { if (global.mxWidgetMessagingListenerCount === 0) { - window.addEventListener("message", this.onMessage, false); + window.addEventListener("message", () => this.onMessage, false); } global.mxWidgetMessagingListenerCount += 1; } @@ -209,7 +209,7 @@ export default class WidgetMessaging extends MatrixPostMessageApi { stopListening() { global.mxWidgetMessagingListenerCount -= 1; if (global.mxWidgetMessagingListenerCount === 0) { - window.removeEventListener("message", this.onMessage); + window.removeEventListener("message", () => this.onMessage); } if (global.mxWidgetMessagingListenerCount < 0) { // Make an error so we get a stack trace @@ -367,10 +367,11 @@ export default class WidgetMessaging extends MatrixPostMessageApi { * Request a screenshot from a widget */ getScreenshot() { - const screenshot = this.exec({ + this.exec({ action: "screenshot", + }).then(function(screenshot) { + console.warn("got screenshot", screenshot); }); - console.warn("got screenshot", screenshot); } } From f2ad7be3f3e77a38bb15aa5a2faffa50b54f38c8 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Fri, 15 Dec 2017 16:56:02 +0000 Subject: [PATCH 129/927] Add event handlers and comments. --- src/components/views/elements/AppTile.js | 33 ++++++++++++++++-------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 812d8e8bdd..d97f844038 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -155,12 +155,15 @@ export default React.createClass({ }, componentWillMount() { - WidgetMessaging.startListening(); - WidgetMessaging.addEndpoint(this.props.id, this.props.url); - window.addEventListener('message', this._onMessage, false); this.setScalarToken(); }, + componentDidMount() { + // Legacy Jitsi widget messaging -- TODO replace this with standard widget + // postMessaging API + window.addEventListener('message', this._onMessage, false); + }, + /** * Adds a scalar token to the widget URL, if required * Component initialisation is only complete when this function has resolved @@ -234,6 +237,8 @@ export default React.createClass({ } }, + // Legacy Jitsi widget messaging + // TODO -- This should be replaced with the new widget postMessaging API _onMessage(event) { if (this.props.type !== 'jitsi') { return; @@ -268,14 +273,16 @@ export default React.createClass({ }, _onSnapshotClick(e) { - const iframe = this.refs.appFrame; - domtoimage.toPng(iframe).then(function(dataUrl) { - console.log("Image data URL:", dataUrl); - dis.dispatch({ - action: 'picture_snapshot', - file: dataURLtoBlob(dataUrl), - }, true); - }); + console.warn("Requesting widget snapshot"); + this.widgetMessaging.getScreenshot(); + // const iframe = this.refs.appFrame; + // domtoimage.toPng(iframe).then(function(dataUrl) { + // console.log("Image data URL:", dataUrl); + // dis.dispatch({ + // action: 'picture_snapshot', + // file: dataURLtoBlob(dataUrl), + // }, true); + // }); }, /* If user has permission to modify widgets, delete the widget, @@ -317,6 +324,10 @@ export default React.createClass({ * Called when widget iframe has finished loading */ _onLoaded() { + // console.warn("App frame", this.refs.appFrame.contentWindow); + this.widgetMessaging = new WidgetMessaging(this.refs.appFrame.contentWindow); + this.widgetMessaging.startListening(); + this.widgetMessaging.addEndpoint(this.props.id, this.props.url); this.setState({loading: false}); }, From 6f896098e380c5817fa88e6fc1dfa8e7932270c8 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Fri, 15 Dec 2017 17:14:56 +0000 Subject: [PATCH 130/927] Get Group profile from TagTile instead of TagPanel So that instead of getting all group profiles everytime the tags change order, get them when the TagTile mounts for a group tag. --- src/components/structures/TagPanel.js | 32 +++++---------------- src/components/views/elements/DNDTagTile.js | 6 ++-- src/components/views/elements/TagTile.js | 27 ++++++++++++++--- 3 files changed, 33 insertions(+), 32 deletions(-) diff --git a/src/components/structures/TagPanel.js b/src/components/structures/TagPanel.js index 49d22d8e52..aa35101197 100644 --- a/src/components/structures/TagPanel.js +++ b/src/components/structures/TagPanel.js @@ -18,7 +18,6 @@ import React from 'react'; import PropTypes from 'prop-types'; import { MatrixClient } from 'matrix-js-sdk'; import FilterStore from '../../stores/FilterStore'; -import FlairStore from '../../stores/FlairStore'; import TagOrderStore from '../../stores/TagOrderStore'; import GroupActions from '../../actions/GroupActions'; @@ -36,17 +35,7 @@ const TagPanel = React.createClass({ getInitialState() { return { - // A list of group profiles for tags that are group IDs. The intention in future - // is to allow arbitrary tags to be selected in the TagPanel, not just groups. - // For now, it suffices to maintain a list of ordered group profiles. - orderedGroupTagProfiles: [ - // { - // groupId: '+awesome:foo.bar',{ - // name: 'My Awesome Community', - // avatarUrl: 'mxc://...', - // shortDescription: 'Some description...', - // }, - ], + orderedTags: [], selectedTags: [], }; }, @@ -67,15 +56,8 @@ const TagPanel = React.createClass({ if (this.unmounted) { return; } - - const orderedTags = TagOrderStore.getOrderedTags() || []; - const orderedGroupTags = orderedTags.filter((t) => t[0] === '+'); - // XXX: One profile lookup failing will bring the whole lot down - Promise.all(orderedGroupTags.map( - (groupId) => FlairStore.getGroupProfileCached(this.context.matrixClient, groupId), - )).then((orderedGroupTagProfiles) => { - if (this.unmounted) return; - this.setState({orderedGroupTagProfiles}); + this.setState({ + orderedTags: TagOrderStore.getOrderedTags() || [], }); }); // This could be done by anything with a matrix client @@ -113,11 +95,11 @@ const TagPanel = React.createClass({ const TintableSvg = sdk.getComponent('elements.TintableSvg'); const DNDTagTile = sdk.getComponent('elements.DNDTagTile'); - const tags = this.state.orderedGroupTagProfiles.map((groupProfile, index) => { + const tags = this.state.orderedTags.map((tag, index) => { return ; }); diff --git a/src/components/views/elements/DNDTagTile.js b/src/components/views/elements/DNDTagTile.js index 4d03534980..539163d0dc 100644 --- a/src/components/views/elements/DNDTagTile.js +++ b/src/components/views/elements/DNDTagTile.js @@ -29,7 +29,7 @@ const tagTileSource = { beginDrag: function(props) { // Return the data describing the dragged item return { - tag: props.groupProfile.groupId, + tag: props.tag, }; }, @@ -55,7 +55,7 @@ const tagTileTarget = { dis.dispatch({ action: 'order_tag', tag: monitor.getItem().tag, - targetTag: props.groupProfile.groupId, + targetTag: props.tag, // Note: we indicate that the tag should be after the target when // it's being dragged over the top half of the target. after: draggedY < targetY, @@ -65,7 +65,7 @@ const tagTileTarget = { drop(props) { // Return the data to be returned by getDropResult return { - tag: props.groupProfile.groupId, + tag: props.tag, }; }, }; diff --git a/src/components/views/elements/TagTile.js b/src/components/views/elements/TagTile.js index 124559a838..9bad02e37d 100644 --- a/src/components/views/elements/TagTile.js +++ b/src/components/views/elements/TagTile.js @@ -22,17 +22,36 @@ import sdk from '../../../index'; import dis from '../../../dispatcher'; import { isOnlyCtrlOrCmdKeyEvent } from '../../../Keyboard'; +import FlairStore from '../../../stores/FlairStore'; + export default React.createClass({ displayName: 'TagTile', propTypes: { - groupProfile: PropTypes.object, + tag: PropTypes.string, }, contextTypes: { matrixClient: React.PropTypes.instanceOf(MatrixClient).isRequired, }, + componentWillMount() { + this.unmounted = false; + if (this.props.tag[0] === '+') { + FlairStore.getGroupProfileCached( + this.context.matrixClient, + this.props.tag, + ).then((profile) => { + if (this.unmounted) return; + this.setState({profile}); + }); + } + }, + + componentWillUnmount() { + this.unmounted = true; + }, + getInitialState() { return { hover: false, @@ -44,7 +63,7 @@ export default React.createClass({ e.stopPropagation(); dis.dispatch({ action: 'select_tag', - tag: this.props.groupProfile.groupId, + tag: this.props.tag, ctrlOrCmdKey: isOnlyCtrlOrCmdKeyEvent(e), shiftKey: e.shiftKey, }); @@ -62,8 +81,8 @@ export default React.createClass({ const BaseAvatar = sdk.getComponent('avatars.BaseAvatar'); const AccessibleButton = sdk.getComponent('elements.AccessibleButton'); const RoomTooltip = sdk.getComponent('rooms.RoomTooltip'); - const profile = this.props.groupProfile || {}; - const name = profile.name || profile.groupId; + const profile = this.state.profile || {}; + const name = profile.name || this.props.tag; const avatarHeight = 35; const httpUrl = profile.avatarUrl ? this.context.matrixClient.mxcUrlToHttp( From 4043ea7d5730231775402e59790077aff347c43e Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 15 Dec 2017 17:57:24 +0000 Subject: [PATCH 131/927] change CSS classes and i18n Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/QuotePreview.js | 11 ++++++----- src/i18n/strings/en_EN.json | 3 ++- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/components/views/rooms/QuotePreview.js b/src/components/views/rooms/QuotePreview.js index 2259350cdc..6b30e73a51 100644 --- a/src/components/views/rooms/QuotePreview.js +++ b/src/components/views/rooms/QuotePreview.js @@ -17,6 +17,7 @@ limitations under the License. import React from 'react'; import dis from '../../../dispatcher'; import sdk from '../../../index'; +import { _t } from '../../../languageHandler'; import RoomViewStore from '../../../stores/RoomViewStore'; function cancelQuoting() { @@ -60,14 +61,14 @@ export default class QuotePreview extends React.Component { const EventTile = sdk.getComponent('rooms.EventTile'); const EmojiText = sdk.getComponent('views.elements.EmojiText'); - return
-
- 💬 Quoting -
+ return
+
+ 💬 { _t('Quoting') } +
-
+
; diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index d632692e04..db9f1e35e1 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -939,5 +939,6 @@ "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.", "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.", "File to import": "File to import", - "Import": "Import" + "Import": "Import", + "Quoting": "Quoting" } From 0ad0c0e9f70b6a256692e7e1f6436880fb62a2e4 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 15 Dec 2017 18:39:01 +0000 Subject: [PATCH 132/927] finish i18n, and add a Date Sep to quote if it needs it Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/Quote.js | 31 ++++++++++++++++++-- src/components/views/messages/TextualBody.js | 3 +- src/i18n/strings/en_EN.json | 3 +- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/components/views/elements/Quote.js b/src/components/views/elements/Quote.js index 96bebf8bcd..a417e9a6de 100644 --- a/src/components/views/elements/Quote.js +++ b/src/components/views/elements/Quote.js @@ -15,13 +15,31 @@ limitations under the License. */ import React from 'react'; import sdk from '../../../index'; +import {_t} from '../../../languageHandler'; import PropTypes from 'prop-types'; import MatrixClientPeg from '../../../MatrixClientPeg'; +import {MatrixEvent} from 'matrix-js-sdk'; // For URLs of matrix.to links in the timeline which have been reformatted by // HttpUtils transformTags to relative links. This excludes event URLs (with `[^\/]*`) const REGEX_LOCAL_MATRIXTO = /^#\/room\/(([\#\!])[^\/]*)\/(\$[^\/]*)$/; +const MILLIS_IN_DAY = 86400000; +function wantsDateSeparator(parentEvent, event) { + const parentEventDate = parentEvent.getDate(); + const eventDate = event.getDate(); + if (!eventDate || !parentEventDate) { + return false; + } + // Return early for events that are > 24h apart + if (Math.abs(parentEvent.getTs() - eventDate.getTime()) > MILLIS_IN_DAY) { + return true; + } + + // Compare weekdays + return parentEventDate.getDay() !== eventDate.getDay(); +} + const Quote = React.createClass({ statics: { isMessageUrl: (url) => { @@ -36,6 +54,8 @@ const Quote = React.createClass({ props: { // The matrix.to url of the event url: PropTypes.string, + // The parent event + parentEv: PropTypes.instanceOf(MatrixEvent), // Whether to include an avatar in the pill shouldShowPillAvatar: PropTypes.bool, }, @@ -98,14 +118,21 @@ const Quote = React.createClass({ const ev = this.state.event; if (ev) { const EventTile = sdk.getComponent('views.rooms.EventTile'); - return
+ let dateSep = null; + if (wantsDateSeparator(this.props.parentEv, this.state.event)) { + const DateSeparator = sdk.getComponent('messages.DateSeparator'); + dateSep = ; + } + + return
+ { dateSep }
; } // Deliberately render nothing if the URL isn't recognised return ; }, diff --git a/src/components/views/messages/TextualBody.js b/src/components/views/messages/TextualBody.js index 4c41cbe669..adf79d3135 100644 --- a/src/components/views/messages/TextualBody.js +++ b/src/components/views/messages/TextualBody.js @@ -208,7 +208,8 @@ module.exports = React.createClass({ // only allow this branch if we're not already in a quote, as fun as infinite nesting is. const quoteContainer = document.createElement('span'); - const quote = ; + const quote = + ; ReactDOM.render(quote, quoteContainer); node.parentNode.replaceChild(quoteContainer, node); diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index db9f1e35e1..908a203a42 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -940,5 +940,6 @@ "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.", "File to import": "File to import", "Import": "Import", - "Quoting": "Quoting" + "Quoting": "Quoting", + "Rich Quoting": "Rich Quoting" } From 954c6eecd6665d204a4fb9ec7767971b4db84dc2 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Fri, 15 Dec 2017 19:42:06 +0000 Subject: [PATCH 133/927] Set correct API name. --- src/WidgetMessaging.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/WidgetMessaging.js b/src/WidgetMessaging.js index 1180dd2df2..134f93f0f7 100644 --- a/src/WidgetMessaging.js +++ b/src/WidgetMessaging.js @@ -368,6 +368,7 @@ export default class WidgetMessaging extends MatrixPostMessageApi { */ getScreenshot() { this.exec({ + api: "widget_client", action: "screenshot", }).then(function(screenshot) { console.warn("got screenshot", screenshot); From 9baf71c4fce4566706be50c671553af8a6f298b5 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 15 Dec 2017 19:52:47 +0000 Subject: [PATCH 134/927] only pass one child to EmojiText otherwise it cries Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/QuotePreview.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/views/rooms/QuotePreview.js b/src/components/views/rooms/QuotePreview.js index 6b30e73a51..7241feeac6 100644 --- a/src/components/views/rooms/QuotePreview.js +++ b/src/components/views/rooms/QuotePreview.js @@ -63,7 +63,11 @@ export default class QuotePreview extends React.Component { return
- 💬 { _t('Quoting') } + + + 💬 { _t('Quoting') } + +
From e63f5696a6897341d24909bb53bb97e049654be0 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Fri, 15 Dec 2017 21:36:02 +0000 Subject: [PATCH 135/927] Screenshot handlers --- src/WidgetMessaging.js | 19 ++++++++++++++----- src/components/views/elements/AppTile.js | 17 ++++++++--------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/WidgetMessaging.js b/src/WidgetMessaging.js index 134f93f0f7..2efdc366b6 100644 --- a/src/WidgetMessaging.js +++ b/src/WidgetMessaging.js @@ -153,6 +153,7 @@ Example: import URL from 'url'; import dis from './dispatcher'; import MatrixPostMessageApi from './MatrixPostMessageApi'; +import Promise from 'bluebird'; const WIDGET_API_VERSION = '0.0.1'; // Current API version const SUPPORTED_WIDGET_API_VERSIONS = [ @@ -197,6 +198,7 @@ export default class WidgetMessaging extends MatrixPostMessageApi { * Register widget message event listeners */ startListening() { + this.start(); if (global.mxWidgetMessagingListenerCount === 0) { window.addEventListener("message", () => this.onMessage, false); } @@ -207,6 +209,7 @@ export default class WidgetMessaging extends MatrixPostMessageApi { * De-register widget message event listeners */ stopListening() { + this.stop(); global.mxWidgetMessagingListenerCount -= 1; if (global.mxWidgetMessagingListenerCount === 0) { window.removeEventListener("message", () => this.onMessage); @@ -365,13 +368,19 @@ export default class WidgetMessaging extends MatrixPostMessageApi { /** * Request a screenshot from a widget + * @return {Promise} To be resolved when screenshot has been generated */ getScreenshot() { - this.exec({ - api: "widget_client", - action: "screenshot", - }).then(function(screenshot) { - console.warn("got screenshot", screenshot); + return new Promise((resolve, reject) => { + this.exec({ + api: "widget_client", + action: "screenshot", + }).then(function(response) { + // console.warn("got screenshot", response.screenshot); + resolve(response.screenshot); + }).catch((error) => { + reject(Error("Failed to get screenshot: " + error.message)); + }); }); } } diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index d97f844038..b10d7f91ad 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -274,15 +274,14 @@ export default React.createClass({ _onSnapshotClick(e) { console.warn("Requesting widget snapshot"); - this.widgetMessaging.getScreenshot(); - // const iframe = this.refs.appFrame; - // domtoimage.toPng(iframe).then(function(dataUrl) { - // console.log("Image data URL:", dataUrl); - // dis.dispatch({ - // action: 'picture_snapshot', - // file: dataURLtoBlob(dataUrl), - // }, true); - // }); + this.widgetMessaging.getScreenshot().then((screenshot) => { + dis.dispatch({ + action: 'picture_snapshot', + file: screenshot, + }, true); + }).catch((err) => { + console.error("Failed to get screenshot", err); + }); }, /* If user has permission to modify widgets, delete the widget, From 83f9a4162b1fd3d5dcd279dc227583fb142a25d6 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Sat, 16 Dec 2017 09:16:24 +0000 Subject: [PATCH 136/927] Request capabilities (e.g. ability to take snapshots) from widgets. --- src/WidgetMessaging.js | 14 +++++++++++ src/components/views/elements/AppTile.js | 32 +++++++++++++----------- 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/WidgetMessaging.js b/src/WidgetMessaging.js index 2efdc366b6..d71d86f8f5 100644 --- a/src/WidgetMessaging.js +++ b/src/WidgetMessaging.js @@ -383,6 +383,20 @@ export default class WidgetMessaging extends MatrixPostMessageApi { }); }); } + + getCapabilities() { + return new Promise((resolve, reject) => { + this.exec({ + api: "widget_client", + action: "capabilities", + }).then(function(response) { + // console.warn("got capabilities", response.capabilities); + resolve(response.capabilities); + }).catch((error) => { + reject(Error("Failed to get capabilities: " + error.message)); + }); + }); + } } diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index b10d7f91ad..770406e645 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -33,7 +33,6 @@ import AppWarning from './AppWarning'; import MessageSpinner from './MessageSpinner'; import WidgetUtils from '../../../WidgetUtils'; import dis from '../../../dispatcher'; -import domtoimage from 'dom-to-image'; const ALLOWED_APP_URL_SCHEMES = ['https:', 'http:']; @@ -83,9 +82,20 @@ export default React.createClass({ error: null, deleting: false, widgetPageTitle: newProps.widgetPageTitle, + capabilities: [], }; }, + + /** + * Does the widget support a given capability + * @param {[type]} capability Capability to check for + * @return {Boolean} True if capability supported + */ + _hasCapability(capability) { + return this.state.capabilities.some((c) => {return c === capability;}); + }, + /** * Add widget instance specific parameters to pass in wUrl * Properties passed to widget instance: @@ -327,6 +337,12 @@ export default React.createClass({ this.widgetMessaging = new WidgetMessaging(this.refs.appFrame.contentWindow); this.widgetMessaging.startListening(); this.widgetMessaging.addEndpoint(this.props.id, this.props.url); + this.widgetMessaging.getCapabilities().then((capabilities) => { + console.log("Got widget capabilities", this.widgetId, capabilities); + this.setState({capabilities}); + }).catch((err) => { + console.log("Failed to get widget capabilities", this.widgetId, err); + }); this.setState({loading: false}); }, @@ -468,7 +484,7 @@ export default React.createClass({ } // Picture snapshot - const showPictureSnapshotButton = true; // FIXME - Make this dynamic + const showPictureSnapshotButton = this._hasCapability('screenshot'); const showPictureSnapshotIcon = 'img/camera_green.svg'; const windowStateIcon = (this.props.show ? 'img/minimize.svg' : 'img/maximize.svg'); @@ -525,15 +541,3 @@ export default React.createClass({ ); }, }); - -function dataURLtoBlob(dataurl) { - const arr = dataurl.split(','); - const mime = arr[0].match(/:(.*?);/)[1]; - const bstr = atob(arr[1]); - let n = bstr.length; - const u8arr = new Uint8Array(n); - while (n--) { - u8arr[n] = bstr.charCodeAt(n); - } - return new Blob([u8arr], {type: mime}); -} From dca6fb6b816881ed1f7a4d8b4618f8b635c6dbf7 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sat, 16 Dec 2017 20:04:32 -0700 Subject: [PATCH 137/927] Attempt to re-register for a scalar token if ours is invalid This mostly helps with people migrating between integration managers where their old scalar token may no longer be valid. This also solves the problem of people switching between scalar and scalar-staging in the wild. Signed-off-by: Travis Ralston --- src/ScalarAuthClient.js | 50 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/src/ScalarAuthClient.js b/src/ScalarAuthClient.js index 3e775a94ab..0d67a08eac 100644 --- a/src/ScalarAuthClient.js +++ b/src/ScalarAuthClient.js @@ -38,11 +38,53 @@ class ScalarAuthClient { // Returns a scalar_token string getScalarToken() { - const tok = window.localStorage.getItem("mx_scalar_token"); - if (tok) return Promise.resolve(tok); + const token = window.localStorage.getItem("mx_scalar_token"); - // No saved token, so do the dance to get one. First, we - // need an openid bearer token from the HS. + if (!token) { + return this.registerForToken(); + } else { + return this.validateToken(token).then(userId => { + const me = MatrixClientPeg.get().getUserId(); + if (userId !== me) { + throw new Error("Scalar token is owned by someone else: " + me); + } + return token; + }).catch(err => { + console.error(err); + + // Something went wrong - try to get a new token. + console.warn("Registering for new scalar token"); + return this.registerForToken(); + }) + } + } + + validateToken(token) { + let url = SdkConfig.get().integrations_rest_url + "/account"; + + const defer = Promise.defer(); + request({ + method: "GET", + uri: url, + qs: {scalar_token: token}, + json: true, + }, (err, response, body) => { + if (err) { + defer.reject(err); + } else if (response.statusCode / 100 !== 2) { + defer.reject({statusCode: response.statusCode}); + } else if (!body || !body.user_id) { + defer.reject(new Error("Missing user_id in response")); + } else { + defer.resolve(body.user_id); + } + }); + + return defer.promise; + } + + registerForToken() { + // Get openid bearer token from the HS as the first part of our dance return MatrixClientPeg.get().getOpenIdToken().then((token_object) => { // Now we can send that to scalar and exchange it for a scalar token return this.exchangeForScalarToken(token_object); From 9603b21199a080cbcae58a22e312afa396094fe6 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sun, 17 Dec 2017 20:20:45 +0000 Subject: [PATCH 138/927] s/Quote/Reply/ and ES6 tweaks Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/Quote.js | 54 +++++++++----------- src/components/views/messages/TextualBody.js | 2 +- src/components/views/rooms/QuotePreview.js | 4 +- src/i18n/strings/en_EN.json | 4 +- src/settings/Settings.js | 2 +- 5 files changed, 30 insertions(+), 36 deletions(-) diff --git a/src/components/views/elements/Quote.js b/src/components/views/elements/Quote.js index a417e9a6de..f1fa3bdbac 100644 --- a/src/components/views/elements/Quote.js +++ b/src/components/views/elements/Quote.js @@ -40,38 +40,36 @@ function wantsDateSeparator(parentEvent, event) { return parentEventDate.getDay() !== eventDate.getDay(); } -const Quote = React.createClass({ - statics: { - isMessageUrl: (url) => { - return !!REGEX_LOCAL_MATRIXTO.exec(url); - }, - }, +export default class Quote extends React.Component { + static isMessageUrl(url) { + return !!REGEX_LOCAL_MATRIXTO.exec(url); + } - childContextTypes: { - matrixClient: React.PropTypes.object, - }, + static childContextTypes = { + matrixClient: PropTypes.object, + }; - props: { + static propTypes = { // The matrix.to url of the event url: PropTypes.string, // The parent event parentEv: PropTypes.instanceOf(MatrixEvent), - // Whether to include an avatar in the pill - shouldShowPillAvatar: PropTypes.bool, - }, + }; - getChildContext: function() { - return { - matrixClient: MatrixClientPeg.get(), - }; - }, + constructor(props, context) { + super(props, context); - getInitialState() { - return { + this.state = { // The event related to this quote event: null, }; - }, + } + + getChildContext() { + return { + matrixClient: MatrixClientPeg.get(), + }; + } componentWillReceiveProps(nextProps) { let roomId; @@ -96,11 +94,11 @@ const Quote = React.createClass({ // Only try and load the event if we know about the room // otherwise we just leave a `Quote` anchor which can be used to navigate/join the room manually. if (room) this.getEvent(room, eventId); - }, + } componentWillMount() { this.componentWillReceiveProps(this.props); - }, + } async getEvent(room, eventId) { let event = room.findEventById(eventId); @@ -112,9 +110,9 @@ const Quote = React.createClass({ await MatrixClientPeg.get().getEventTimeline(room.getUnfilteredTimelineSet(), eventId); event = room.findEventById(eventId); this.setState({room, event}); - }, + } - render: function() { + render() { const ev = this.state.event; if (ev) { const EventTile = sdk.getComponent('views.rooms.EventTile'); @@ -135,7 +133,5 @@ const Quote = React.createClass({ { _t('Quote') }
; - }, -}); - -export default Quote; + } +} diff --git a/src/components/views/messages/TextualBody.js b/src/components/views/messages/TextualBody.js index adf79d3135..54576fa794 100644 --- a/src/components/views/messages/TextualBody.js +++ b/src/components/views/messages/TextualBody.js @@ -209,7 +209,7 @@ module.exports = React.createClass({ const quoteContainer = document.createElement('span'); const quote = - ; + ; ReactDOM.render(quote, quoteContainer); node.parentNode.replaceChild(quoteContainer, node); diff --git a/src/components/views/rooms/QuotePreview.js b/src/components/views/rooms/QuotePreview.js index 7241feeac6..a76c9e2d1a 100644 --- a/src/components/views/rooms/QuotePreview.js +++ b/src/components/views/rooms/QuotePreview.js @@ -64,9 +64,7 @@ export default class QuotePreview extends React.Component { return
- - 💬 { _t('Quoting') } - + { '💬' + _t('Replying') }
Date: Sun, 17 Dec 2017 20:53:53 +0000 Subject: [PATCH 139/927] fix missing space Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/QuotePreview.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/rooms/QuotePreview.js b/src/components/views/rooms/QuotePreview.js index a76c9e2d1a..614d51dada 100644 --- a/src/components/views/rooms/QuotePreview.js +++ b/src/components/views/rooms/QuotePreview.js @@ -64,7 +64,7 @@ export default class QuotePreview extends React.Component { return
- { '💬' + _t('Replying') } + { '💬 ' + _t('Replying') }
Date: Sat, 16 Dec 2017 14:45:13 +0000 Subject: [PATCH 140/927] Translated using Weblate (Basque) Currently translated at 75.2% (721 of 958 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eu/ --- src/i18n/strings/eu.json | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/eu.json b/src/i18n/strings/eu.json index 486991d350..4ca09d5d71 100644 --- a/src/i18n/strings/eu.json +++ b/src/i18n/strings/eu.json @@ -40,7 +40,7 @@ "No results": "Emaitzarik ez", "Bug Report": "Arazte-txostena", "Join Room": "Elkartu gelara", - "Register": "Erregistratu", + "Register": "Eman izena", "Submit": "Bidali", "Skip": "Saltatu", "Send Reset Email": "Bidali berrezartzeko e-maila", @@ -796,5 +796,15 @@ "To configure the room, you must be a": "Gela konfiguratzeko hau izan behar zara:", "To kick users, you must be a": "Erabiltzaileak kanporatzeko hau izan behar zara:", "To ban users, you must be a": "Erabiltzaileak debekatzeko hau izan behar zara:", - "To remove other users' messages, you must be a": "Beste erabiltzaileen mezuak kentzeko hau izan behar zara:" + "To remove other users' messages, you must be a": "Beste erabiltzaileen mezuak kentzeko hau izan behar zara:", + "Unpin Message": "Desfinkatu mezua", + "Add rooms to this community": "Gehitu gelak komunitate honetara", + "Call Failed": "Deiak huts egin du", + "There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "Gailu ezezagunak daude gela honetan: hauek egiaztatu gabe aurrera jarraituz gero, posiblea litzateke inork zure deia entzutea.", + "Review Devices": "Aztertu gailuak", + "Call Anyway": "Deitu hala ere", + "Answer Anyway": "Erantzun hala ere", + "Call": "Deitu", + "Answer": "Erantzun", + "Who would you like to add to this community?": "Nor gehitu nahi duzu komunitate honetara?" } From cfedd57920f79c05fc5f81a53f5608b0d977200f Mon Sep 17 00:00:00 2001 From: Tirifto Date: Sat, 16 Dec 2017 22:59:32 +0000 Subject: [PATCH 141/927] Translated using Weblate (Esperanto) Currently translated at 72.6% (696 of 958 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eo/ --- src/i18n/strings/eo.json | 144 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 141 insertions(+), 3 deletions(-) diff --git a/src/i18n/strings/eo.json b/src/i18n/strings/eo.json index 463713e9ea..b16ef6ca34 100644 --- a/src/i18n/strings/eo.json +++ b/src/i18n/strings/eo.json @@ -516,8 +516,8 @@ "A text message has been sent to %(msisdn)s": "Tekstmesaĝo sendiĝîs al %(msisdn)s", "Please enter the code it contains:": "Bonvolu enigi la enhavatan kodon:", "Start authentication": "Komenci aŭtentigon", - "Username on %(hs)s": "Uzantnomo je %(hs)s", - "User name": "Uzantnomo", + "Username on %(hs)s": "Salutnomo je %(hs)s", + "User name": "Salutnomo", "Mobile phone number": "Telefona numero", "Forgot your password?": "Ĉu vi forgesis vian pasvorton?", "%(serverName)s Matrix ID": "%(serverName)s Matrix ID", @@ -556,5 +556,143 @@ "Delete Widget": "Forigi fenestraĵon", "Delete widget": "Forigi fenestraĵon", "Revoke widget access": "Malvalidigi atingon de fenestraĵo", - "Create new room": "Krei novan ĉambron" + "Create new room": "Krei novan ĉambron", + "Verify...": "Kontroli…", + "No results": "Neniuj rezultoj", + "Delete": "Forigi", + "Communities": "Komunumoj", + "Home": "Hejmo", + "Integrations Error": "Integra eraro", + "Could not connect to the integration server": "Malsukcesis konektiĝi al la integra servilo", + "Manage Integrations": "Administri integrojn", + "%(nameList)s %(transitionList)s": "%(nameList)s %(transitionList)s", + "%(severalUsers)sjoined %(count)s times|other": "%(severalUsers)s%(count)s-foje aliĝis", + "%(severalUsers)sjoined %(count)s times|one": "%(severalUsers)saliĝis", + "%(oneUser)sjoined %(count)s times|other": "%(oneUser)s%(count)s-foje aliĝis", + "%(oneUser)sjoined %(count)s times|one": "%(oneUser)saliĝis", + "%(severalUsers)sleft %(count)s times|other": "%(severalUsers)s%(count)s-foje foriris", + "%(severalUsers)sleft %(count)s times|one": "%(severalUsers)sforiris", + "%(oneUser)sleft %(count)s times|other": "%(oneUser)s%(count)s-foje foriris", + "%(oneUser)sleft %(count)s times|one": "%(oneUser)sforiris", + "%(severalUsers)sjoined and left %(count)s times|other": "%(severalUsers)s%(count)s-foje aliĝis kaj foriris", + "%(severalUsers)sjoined and left %(count)s times|one": "%(severalUsers)saliĝis kaj foriris", + "%(oneUser)sjoined and left %(count)s times|other": "%(oneUser)s%(count)s-foje aliĝis kaj foriris", + "%(oneUser)sjoined and left %(count)s times|one": "%(oneUser)saliĝis kaj foriris", + "%(severalUsers)sleft and rejoined %(count)s times|other": "%(severalUsers)s%(count)s-foje foriris kaj realiĝis", + "%(severalUsers)sleft and rejoined %(count)s times|one": "%(severalUsers)sforiris kaj realiĝis", + "%(oneUser)sleft and rejoined %(count)s times|other": "%(oneUser)s%(count)s-foje foriris kaj realiĝis", + "%(oneUser)sleft and rejoined %(count)s times|one": "%(oneUser)sforiris kaj realiĝis", + "%(severalUsers)srejected their invitations %(count)s times|other": "%(severalUsers)s%(count)s-foje rifuzis inviton", + "%(severalUsers)srejected their invitations %(count)s times|one": "%(severalUsers)srifuzis inviton", + "%(oneUser)srejected their invitation %(count)s times|other": "%(oneUser)s%(count)s-foje rifuzis inviton", + "%(oneUser)srejected their invitation %(count)s times|one": "%(oneUser)srifuzis inviton", + "%(severalUsers)shad their invitations withdrawn %(count)s times|other": "%(severalUsers)s%(count)s-foje malinvitiĝis", + "%(severalUsers)shad their invitations withdrawn %(count)s times|one": "%(severalUsers)smalinvitiĝis", + "%(oneUser)shad their invitation withdrawn %(count)s times|other": "%(oneUser)s%(count)s-foje malinvitiĝis", + "%(oneUser)shad their invitation withdrawn %(count)s times|one": "%(oneUser)smalinvitiĝis", + "were invited %(count)s times|other": "%(count)s-foje invitiĝis", + "were invited %(count)s times|one": "invitiĝis", + "was invited %(count)s times|other": "%(count)s-foje invitiĝis", + "was invited %(count)s times|one": "invitiĝis", + "were banned %(count)s times|other": "%(count)s-foje forbariĝis", + "were banned %(count)s times|one": "forbariĝis", + "was banned %(count)s times|other": "%(count)s-foje forbariĝis", + "was banned %(count)s times|one": "forbariĝis", + "were unbanned %(count)s times|other": "%(count)s-foje malforbariĝis", + "were unbanned %(count)s times|one": "malforbariĝis", + "was unbanned %(count)s times|other": "%(count)s-foje malforbariĝis", + "was unbanned %(count)s times|one": "malforbariĝis", + "were kicked %(count)s times|other": "%(count)s-foje forpeliĝis", + "were kicked %(count)s times|one": "forpeliĝis", + "was kicked %(count)s times|other": "%(count)s-foje forpeliĝis", + "was kicked %(count)s times|one": "forpeliĝis", + "%(severalUsers)schanged their name %(count)s times|other": "%(severalUsers)s%(count)s-foje sanĝis sian nomon", + "%(severalUsers)schanged their name %(count)s times|one": "%(severalUsers)sŝanĝis sian nomon", + "%(oneUser)schanged their name %(count)s times|other": "%(oneUser)s%(count)s-foje ŝanĝis sian nomon", + "%(oneUser)schanged their name %(count)s times|one": "%(oneUser)sŝanĝis sian nomon", + "%(severalUsers)schanged their avatar %(count)s times|other": "%(severalUsers)s%(count)s-foje ŝanĝis sian profilbildon", + "%(severalUsers)schanged their avatar %(count)s times|one": "%(severalUsers)sŝanĝis sian profilbildon", + "%(oneUser)schanged their avatar %(count)s times|other": "%(oneUser)s%(count)s-foje ŝanĝis sian profilbildon", + "%(oneUser)schanged their avatar %(count)s times|one": "%(oneUser)sŝanĝis sian profilbildon", + "%(items)s and %(count)s others|other": "%(items)s kaj %(count)s aliaj", + "%(items)s and %(count)s others|one": "%(items)s kaj unu alia", + "%(items)s and %(lastItem)s": "%(items)s kaj %(lastItem)s", + "collapse": "maletendi", + "expand": "etendi", + "Custom of %(powerLevel)s": "Propra nivelo %(powerLevel)s", + "Custom level": "Propra nivelo", + "Room directory": "Ĉambrujo", + "Username not available": "Salutnomo ne disponeblas", + "Username invalid: %(errMessage)s": "Salutnomo ne validas: %(errMessage)s", + "Username available": "Salutnomo disponeblas", + "To get started, please pick a username!": "Por komenci, bonvolu elekti salutnomon!", + "Incorrect username and/or password.": "Malĝusta salutnomo kaj/aŭ pasvorto.", + "User names may only contain letters, numbers, dots, hyphens and underscores.": "Salutnomoj enhavu nur literojn, numerojn, punktojn, streketojn, kaj substrekojn.", + "You need to enter a user name.": "Vi devas enigi salutnomon.", + "Start chat": "Komenci babilon", + "And %(count)s more...|other": "Kaj %(count)s pliaj…", + "ex. @bob:example.com": "ekz-e @nomo:ekzemplo.net", + "Add User": "Aldoni uzanton", + "Matrix ID": "Identigaĵo en Matrix", + "Matrix Room ID": "Ĉambra identigaĵo en Matrix", + "email address": "retpoŝtadreso", + "Try using one of the following valid address types: %(validTypesList)s.": "Provu unu el la sekvaj validaj tipoj de adreso: %(validTypesList)s.", + "You have entered an invalid address.": "Vi enigis malvalidan adreson.", + "Create a new chat or reuse an existing one": "Kreu novan babilon aŭ aliĝu al jama", + "Start new chat": "Komenci novan babilon", + "You already have existing direct chats with this user:": "Vi jam havas rekte babilas kun ĉi tiu uzanto:", + "Start chatting": "Komenci babilon", + "Click on the button below to start chatting!": "Alklaku la butonon sube por komenci babilon!", + "Start Chatting": "Komenci babilon", + "Confirm Removal": "Konfirmi forigon", + "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Ĉu vi certe volas forigi ĉi tiun okazaĵon? Per ŝanĝo de la ĉambra nomo aŭ temo, la ŝanĝo malfareblas.", + "Community IDs may only contain characters a-z, 0-9, or '=_-./'": "Komunuma identigaĵo povas enhavi nur signojn a-z, 0-9, aŭ ‹=_-./› (malinkluzive la citilojn)", + "Something went wrong whilst creating your community": "Io misokazis dum kreado de via komunumo", + "Create Community": "Krei komunumon", + "Community Name": "Komunuma nomo", + "Example": "Ekzemplo", + "Community ID": "Komunuma identigaĵo", + "example": "ekzemplo", + "Create": "Krei", + "Create Room": "Krei ĉambron", + "Room name (optional)": "Ĉambra nomo (malnepra)", + "Advanced options": "Specialaj agordoj", + "Block users on other matrix homeservers from joining this room": "Forbari uzantojn el aliaj hejmserviloj for de ĉi tiu ĉambro", + "This setting cannot be changed later!": "Tiu ĉi agordo ne ŝanĝeblas poste!", + "Unknown error": "Nekonata eraro", + "Incorrect password": "Malĝusta pasvorto", + "Deactivate Account": "Malaktivigi konton", + "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Tio ĉi por ĉiam senuzebligos vian konton. Vi ne povos reregistriĝi kun la sama identigaĵo.", + "This action is irreversible.": "Tiu ĉi ago ne malfareblas.", + "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Por kontroli ke tiu ĉi aparato estas fidinda, bonvolu kontakti ties posedanton per alia maniero (ekz-e persone aŭ telefone) kaj demandi ĝin ĉu la ŝlosilo, kiun ĝi vidas en agordoj de uzanto ĉe si, kongruas kun la ĉi-suba ŝlosilo:", + "Device name": "Aparata nomo", + "Device key": "Aparata ŝlosilo", + "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "Se ĝi kongruas, premu la kontrolan butonon sube. Se ne, tiuokaze iu alia interkaptas ĉi tiun aparaton, kaj eble vi premu la malpermesan butonon anstataŭe.", + "In future this verification process will be more sophisticated.": "Ni planas plifaciligi la kontrolan procedon estontece.", + "Verify device": "Kontroli aparaton", + "I verify that the keys match": "Mi kontrolas, ke la ŝlosiloj kongruas", + "An error has occurred.": "Eraro okazis.", + "OK": "Bone", + "You added a new device '%(displayName)s', which is requesting encryption keys.": "Vi aldonis novan aparaton ‹%(displayName)s›, kiu petas ĉifrajn ŝlasilojn.", + "Your unverified device '%(displayName)s' is requesting encryption keys.": "Via nekontrolita aparato ‹%(displayName)s› petas ĉifrajn ŝlosilojn.", + "Start verification": "Komenci kontrolon", + "Share without verifying": "Kunhavigi sen kontrolo", + "Ignore request": "Malatenti peton", + "Loading device info...": "Enleganta informojn pri aparato…", + "Encryption key request": "Peto por ĉifra ŝlosilo", + "Otherwise, click here to send a bug report.": "Alie, klaku ĉi tie por sendi cimraporton.", + "Unable to restore session": "Seanco ne restaŭreblas", + "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "Okazis eraron dum restaŭro de via antaŭa seanco. Se vi daŭrigos, vi devos denove saluti, kaj ĉifrita babila historio estos nelegebla.", + "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Se vi antaŭe uzis pli novan version de Riot, via seanco eble ne kongruos kun ĉi tiu versio. Fermu ĉi tiun fenestron kaj revenu al la pli nova versio.", + "Continue anyway": "Tamen daŭrigi", + "Invalid Email Address": "Malvalida retpoŝtadreso", + "This doesn't appear to be a valid email address": "Tio ĉi ne ŝajnas esti valida retpoŝtadreso", + "Verification Pending": "Atendanta kontrolon", + "Please check your email and click on the link it contains. Once this is done, click continue.": "Bonvolu kontroli vian retpoŝton, kaj alklaki la ligilon enhavatan en la sendita mesaĝo. Farinte tion, klaku je «daŭrigi».", + "Unable to add email address": "Retpoŝtadreso ne aldoneblas", + "Unable to verify email address.": "Retpoŝtadreso ne kontroleblas.", + "This will allow you to reset your password and receive notifications.": "Tio ĉi permesos al vi restarigi vian pasvorton kaj ricevi sciigojn.", + "Skip": "Preterpasi", + "An error occurred: %(error_string)s": "Okazis eraro: %(error_string)s", + "This will be your account name on the homeserver, or you can pick a different server.": "Tio ĉi estos la nomo de via konto sur la hejmservilo , aŭ vi povas elekti alian servilon." } From 5fddf3bbeb8292efd265ac45b9726b2f1d1931fc Mon Sep 17 00:00:00 2001 From: Juho Ylikorpi Date: Sun, 17 Dec 2017 21:39:09 +0000 Subject: [PATCH 142/927] Translated using Weblate (Finnish) Currently translated at 98.4% (943 of 958 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fi/ --- src/i18n/strings/fi.json | 93 +++++++++++++++++++++++++++++++++------- 1 file changed, 77 insertions(+), 16 deletions(-) diff --git a/src/i18n/strings/fi.json b/src/i18n/strings/fi.json index 5c7095b511..7af645f969 100644 --- a/src/i18n/strings/fi.json +++ b/src/i18n/strings/fi.json @@ -5,7 +5,7 @@ "Cancel": "Peruuta", "Close": "Sulje", "Create new room": "Luo uusi huone", - "Custom Server Options": "Omat palvelinasetukset", + "Custom Server Options": "Palvelinasetukset", "Dismiss": "Hylkää", "Drop here %(toAction)s": "Pudota tänne %(toAction)s", "Error": "Virhe", @@ -22,7 +22,7 @@ "unknown error code": "tuntematon virhekoodi", "Failed to change password. Is your password correct?": "Salasanan muuttaminen epäonnistui. Onko salasanasi oikein?", "Continue": "Jatka", - "powered by Matrix": "Matrix-pohjainen", + "powered by Matrix": "Matrix", "Active call (%(roomName)s)": "Aktivoi puhelu (%(roomName)s)", "Add": "Lisää", "Add a topic": "Lisää aihe", @@ -131,7 +131,7 @@ "Email": "Sähköposti", "Email address": "Sähköpostiosoite", "Email address (optional)": "Sähköpostiosoite (valinnainen)", - "Email, name or matrix ID": "Sähköpostiosoite, nimi, tai Matrix tunniste", + "Email, name or matrix ID": "Sähköpostiosoite, nimi tai Matrix ID", "Emoji": "Emoji", "Enable encryption": "Ota salaus käyttöön", "Enable Notifications": "Ota ilmoitukset käyttöön", @@ -171,7 +171,7 @@ "Failure to create room": "Huoneen luominen epäonnistui", "Favourites": "Suosikit", "Fill screen": "Täytä näyttö", - "Filter room members": "Suodata huoneen jäsenet", + "Filter room members": "Suodata jäsenistä", "Forget room": "Unohda huone", "Forgot your password?": "Unohditko salasanasi?", "For security, this session has been signed out. Please sign in again.": "Turvallisuussyistä tämä istunto on vanhentunut. Ole hyvä ja kirjaudu uudestaan.", @@ -199,7 +199,7 @@ "Invited": "Kutsuttu", "Invites": "Kutsuu", "Invites user with given id to current room": "Kutsuu annetun käyttäjätunnisteen mukaisen käyttäjän huoneeseen", - "Sign in with": "Kirjaudu käyttäen", + "Sign in with": "Tunnistus", "Join Room": "Liity huoneeseen", "Joins room with given alias": "Liittyy huoneeseen jolla on annettu alias", "Jump to first unread message.": "Hyppää ensimmäiseen lukemattomaan viestiin.", @@ -220,10 +220,10 @@ "matrix-react-sdk version:": "Matrix-react-sdk versio:", "Members only": "Vain jäsenet", "Message not sent due to unknown devices being present": "Viestiä ei lähetetty koska paikalla on tuntemattomia laitteita", - "Mobile phone number": "Matkapuhelinnumero", - "Mobile phone number (optional)": "Matkapuhelinnumero (valinnainen)", + "Mobile phone number": "Puhelinnumero", + "Mobile phone number (optional)": "Puhelinnumero (valinnainen)", "Moderator": "Moderaattori", - "%(serverName)s Matrix ID": "%(serverName)s Matrix tunniste", + "%(serverName)s Matrix ID": "%(serverName)s Matrix ID", "Name": "Nimi", "New password": "Uusi salasana", "New passwords don't match": "Uudet salasanat eivät täsmää", @@ -693,7 +693,7 @@ "Who would you like to add to this community?": "Kenet sinä haluaisit lisätä tähän yhteisöön?", "Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "Varioitus: henkilöt jotka lisäät yhteisöön näkyvät kaikille jotka tietävät yhteisön tunnisteen", "Invite new community members": "Kutsu uusia jäsenia yhteisöön", - "Name or matrix ID": "Nimi tai Matrix tunniste", + "Name or matrix ID": "Nimi tai Matrix ID", "Invite to Community": "Kutsu yhteisöön", "Which rooms would you like to add to this community?": "Mitkä huoneet haluaisit listätä tähän yhteisöön?", "Show these rooms to non-members on the community page and room list?": "Näytetäänkö nämä huoneet ei-jäsenille yhteisön sivulla ja huonelistassa?", @@ -709,7 +709,7 @@ "You are no longer ignoring %(userId)s": "Huomioit jälleen käyttäjän %(userId)s", "%(senderName)s removed their profile picture.": "%(senderName)s poisti profiilikuvansa.", "%(senderName)s set a profile picture.": "%(senderName)s asetti profiilikuvan.", - "%(senderName)s made future room history visible to all room members, from the point they are invited.": "%(senderName)s teki tulevan huonehistorian näkyväksi kaikille huoneen jäsenille, kutsusta lähtien.", + "%(senderName)s made future room history visible to all room members, from the point they are invited.": "%(senderName)s muutti tulevat viestit näkyviksi kaikille huoneen jäsenille, alkaen kutsusta huoneeseen.", "%(senderName)s made future room history visible to all room members, from the point they joined.": "%(senderName)s teki tulevan huonehistorian näkyväksi kaikille huoneen jäsenille, liittymisestä asti.", "%(senderName)s made future room history visible to all room members.": "%(senderName)s teki tulevan huonehistorian näkyväksi kaikille huoneen jäsenille.", "%(senderName)s made future room history visible to anyone.": "%(senderName)s teki tulevan huonehistorian näkyväksi kaikille.", @@ -785,12 +785,12 @@ "New community ID (e.g. +foo:%(localDomain)s)": "Uusi yhteisötunniste (esim. +foo:%(localDomain)s)", "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s muutti huoneen %(roomName)s avatarin", "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s poisti huoneen avatarin.", - "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s muutti huoneen avatariksi ", + "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s vaihtoi huoneen kuvaksi ", "You are about to be taken to a third-party site so you can authenticate your account for use with %(integrationsUrl)s. Do you wish to continue?": "Sinut ohjataan kolmannen osapuolen sivustolle jotta voit autentikoida tilisi käyttääksesi %(integrationsUrl)s. Haluatko jatkaa?", "Message removed by %(userId)s": "Käyttäjän %(userId)s poistama viesti", "Message removed": "Viesti poistettu", "Sign in with CAS": "Kirjaudu käyttäen CAS", - "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.": "Voit kirjautua toiselle Matrix kotipalvelimelle syöttämällä palvelimen URL-osoite palvelin-asetuksissa.", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.": "Voit kirjautua toiselle Matrix kotipalvelimelle syöttämällä palvelimen URL-osoite palvelinasetuksissa.", "This allows you to use this app with an existing Matrix account on a different home server.": "Tämä mahdollistaa tämän ohjelman käytön olemassa olevan toisella palvelimella sijaitsevan Matrix tilin kanssa.", "You can also set a custom identity server but this will typically prevent interaction with users based on email address.": "Voit myös käyttää toista identiteettipalvelinta mutta tyypillisesti tämä estää sähköpostiosoitteisiin perustuvan kanssakäynnin muiden käyttäjien kanssa.", "An email has been sent to %(emailAddress)s": "Viesti lähetetty osoitteeseen %(emailAddress)s", @@ -817,7 +817,7 @@ "%(nameList)s %(transitionList)s": "%(nameList)s %(transitionList)s", "were unbanned %(count)s times|other": "porttikiellot poistettiin %(count)s kertaa", "And %(count)s more...|other": "Ja %(count)s lisää...", - "Matrix ID": "Matrix-tunniste", + "Matrix ID": "Matrix ID", "Matrix Room ID": "Matrix huonetunniste", "email address": "sähköpostiosoite", "Try using one of the following valid address types: %(validTypesList)s.": "Kokeile käyttää yhtä näistä valideista osoitetyypeistä: %(validTypesList)s.", @@ -830,8 +830,8 @@ "Community ID": "Yhteisötunniste", "example": "esimerkki", "Advanced options": "Lisäasetukset", - "Block users on other matrix homeservers from joining this room": "Estä käyttäjiä toisilta kotipalvelimilta liittymästä tähän huoneseen", - "This setting cannot be changed later!": "Tätä asetusta ei voi muuttaa enää myöhemmin!", + "Block users on other matrix homeservers from joining this room": "Salli vain tämän palvelimen käyttäjät", + "This setting cannot be changed later!": "Tätä asetusta ei voi muuttaa myöhemmin!", "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Tämä tekee tilistäsi pysyvästi käyttökelvottoman. Et voi rekisteröidä samaa tunnusta uudestaan.", "Add rooms to the community summary": "Lisää huoneita yhteisön yhteenvetoon", "Which rooms would you like to add to this summary?": "Mitkä huoneet haluaisit lisätä tähän yhteenvetoon?", @@ -945,5 +945,66 @@ "Revoke widget access": "Poista pienoisohjelman oikeudet", "Unblacklist": "Poista estolistalta", "Blacklist": "Estolista", - "%(severalUsers)sjoined %(count)s times|one": "%(severalUsers)s käyttäjää liittyi" + "%(severalUsers)sjoined %(count)s times|one": "%(severalUsers)s käyttäjää liittyi", + "You are registering with %(SelectedTeamName)s": "Rekisteröidyt %(SelectedTeamName)s tiimeihin", + "%(oneUser)sjoined %(count)s times|other": "%(oneUser)s liittyi %(count)s kertaa", + "%(oneUser)sjoined %(count)s times|one": "%(oneUser)s liittyi", + "%(severalUsers)sleft %(count)s times|other": "%(severalUsers)s poistui %(count)s kertaa", + "%(severalUsers)sleft %(count)s times|one": "%(severalUsers)s poistui", + "%(oneUser)sleft %(count)s times|other": "%(oneUser)s poistui %(count)s kertaa", + "%(oneUser)sleft %(count)s times|one": "%(oneUser)s poistui", + "%(severalUsers)sjoined and left %(count)s times|other": "%(severalUsers)s liittyi ja poistui %(count)s kertaa", + "%(severalUsers)sjoined and left %(count)s times|one": "%(severalUsers)s liittyi ja poistui", + "%(oneUser)sjoined and left %(count)s times|other": "%(oneUser)s liittyi ja poistui %(count)s kertaa", + "%(oneUser)sjoined and left %(count)s times|one": "%(oneUser)s liittyi ja poistui", + "%(severalUsers)sleft and rejoined %(count)s times|other": "%(severalUsers)s poistui ja liittyi uudelleen %(count)s kertaa", + "%(severalUsers)sleft and rejoined %(count)s times|one": "%(severalUsers)s poistui ja liittyi uudelleen", + "%(oneUser)sleft and rejoined %(count)s times|other": "%(oneUser)s poistui ja liittyi uudelleen %(count)s kertaa", + "%(oneUser)sleft and rejoined %(count)s times|one": "%(oneUser)s poistui ja liittyi uudelleen", + "%(severalUsers)srejected their invitations %(count)s times|other": "%(severalUsers)s hylkäsi kutsun %(count)s kertaa", + "%(severalUsers)srejected their invitations %(count)s times|one": "%(severalUsers)s hylkäsi kutsun", + "%(oneUser)srejected their invitation %(count)s times|other": "%(oneUser)s hylkäsi kutsun %(count)s kertaa", + "%(oneUser)srejected their invitation %(count)s times|one": "%(oneUser)s hylkäsi kutsun", + "%(severalUsers)shad their invitations withdrawn %(count)s times|other": "%(severalUsers)s kutsu peruttiin %(count)s kertaa", + "%(severalUsers)shad their invitations withdrawn %(count)s times|one": "%(severalUsers)s kutsu peruttiin", + "%(oneUser)shad their invitation withdrawn %(count)s times|other": "%(oneUser)s kutsu peruttiin %(count)s kertaa", + "%(oneUser)shad their invitation withdrawn %(count)s times|one": "%(oneUser)s kutsu peruttiin", + "were invited %(count)s times|other": "kutsuttiin %(count)s kertaa", + "were invited %(count)s times|one": "kutsuttiin", + "was invited %(count)s times|other": "kutsuttiin %(count)s kertaa", + "was invited %(count)s times|one": "kutsuttiin", + "were banned %(count)s times|other": "estettiin %(count)s kertaa", + "were banned %(count)s times|one": "estettiin", + "was banned %(count)s times|other": "estettiin %(count)s kertaa", + "was banned %(count)s times|one": "estettiin", + "were unbanned %(count)s times|one": "estoi poistettiin", + "was unbanned %(count)s times|other": "esto poistettiin %(count)s kertaa", + "was unbanned %(count)s times|one": "esto poistettiin", + "were kicked %(count)s times|other": "poistettiin %(count)s kertaa", + "were kicked %(count)s times|one": "poistettiin", + "was kicked %(count)s times|other": "poistettiin %(count)s kertaa", + "was kicked %(count)s times|one": "poistettiin", + "expand": "laajenna", + "collapse": "supista", + "Display your community flair in rooms configured to show it.": "Näytä yhteisöjesi tyylit huoneissa joissa ominaisuus on päällä.", + "Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?": "Pienoisohjelman poistaminen poistaa sen kaikilta huoneen käyttäjiltä. Oletko varma että haluat poistaa pienoisohjelman?", + "%(severalUsers)sjoined %(count)s times|other": "%(severalUsers)s liittyi %(count)s kertaa", + "%(severalUsers)schanged their name %(count)s times|other": "%(severalUsers)s vaihtoi nimensä %(count)s kertaa", + "%(severalUsers)schanged their name %(count)s times|one": "%(severalUsers)s vaihtoi nimensä", + "%(oneUser)schanged their name %(count)s times|other": "%(oneUser)s vaihtoi nimensä %(count)s kertaa", + "%(oneUser)schanged their name %(count)s times|one": "%(oneUser)s vaihtoi nimensä", + "%(severalUsers)schanged their avatar %(count)s times|other": "%(severalUsers)s vaihtoi pienoiskuvansa %(count)s kertaa", + "%(severalUsers)schanged their avatar %(count)s times|one": "%(severalUsers)s vaihtoi pienoiskuvansa", + "%(oneUser)schanged their avatar %(count)s times|other": "%(oneUser)s vaihtoi pienoiskuvansa %(count)s kertaa", + "%(oneUser)schanged their avatar %(count)s times|one": "%(oneUser)s vaihtoi pienoiskuvansa", + "%(items)s and %(count)s others|other": "%(items)s ja %(count)s muuta", + "%(items)s and %(count)s others|one": "%(items)s ja yksi toinen", + "Custom of %(powerLevel)s": "Valinnaiset %(powerLevel)s", + "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Varmistaaksesi että tähän laitteeseen voidaan luottaa, ole yhteydessä omistajaan jollain muulla tavalla (henkilökohtaisesti tai puhelimitse) ja pyydä heitä varmistamaan näkyykö Käyttäjäasetuksissa laite jolla on alla oleva avain:", + "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "Jos avain täsmää, valitse painike alla. Jos avain ei täsmää, niin joku muu salakuuntelee laitetta ja haluat todennäköisesti painaa estopainiketta.", + "Cryptography data migrated": "Salaustiedot siirretty", + "Old cryptography data detected": "Vanhat salaustiedot havaittu", + "Resend all or cancel all now. You can also select individual messages to resend or cancel.": "Lähetä kaikki uudelleen tai peruuta kaikki nyt. Voit myös valita yksittäisiä viestejä uudelleenlähetettäväksi tai peruttavaksi.", + "Warning": "Varoitus", + "Access Token:": "Pääsykoodi:" } From b0b2e761a805ad39cb4565bd3a739bbcb8107bca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Wi=C5=9Bniewski?= Date: Fri, 15 Dec 2017 19:09:43 +0000 Subject: [PATCH 143/927] Translated using Weblate (Polish) Currently translated at 72.6% (696 of 958 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/pl/ --- src/i18n/strings/pl.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/pl.json b/src/i18n/strings/pl.json index 4e7aa2fd55..87d5598d7c 100644 --- a/src/i18n/strings/pl.json +++ b/src/i18n/strings/pl.json @@ -779,5 +779,6 @@ "Invite to Community": "Zaproszenie do Społeczności", "Which rooms would you like to add to this community?": "Które pokoje chcesz dodać do tej społeczności?", "Room name or alias": "Nazwa pokoju lub alias", - "Add to community": "Dodaj do społeczności" + "Add to community": "Dodaj do społeczności", + "Call": "Połącz" } From 47d4e5f8d15dc6bfb63415158dc632801f6bbb24 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 18 Dec 2017 19:28:01 +0000 Subject: [PATCH 144/927] nest quotes, but only when people want to click through them loads pre-emptively Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/Quote.js | 36 +++++++++++++++----- src/components/views/messages/TextualBody.js | 6 ++-- 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/src/components/views/elements/Quote.js b/src/components/views/elements/Quote.js index f1fa3bdbac..6a7e5d058f 100644 --- a/src/components/views/elements/Quote.js +++ b/src/components/views/elements/Quote.js @@ -54,6 +54,8 @@ export default class Quote extends React.Component { url: PropTypes.string, // The parent event parentEv: PropTypes.instanceOf(MatrixEvent), + // Whether this isn't the first Quote, and we're being nested + isNested: PropTypes.bool, }; constructor(props, context) { @@ -62,7 +64,10 @@ export default class Quote extends React.Component { this.state = { // The event related to this quote event: null, + show: !this.props.isNested, }; + + this.onShowNested = this.onShowNested.bind(this); } getChildContext() { @@ -112,20 +117,33 @@ export default class Quote extends React.Component { this.setState({room, event}); } + onShowNested() { + this.setState({ + show: true, + }); + } + render() { const ev = this.state.event; if (ev) { - const EventTile = sdk.getComponent('views.rooms.EventTile'); - let dateSep = null; - if (wantsDateSeparator(this.props.parentEv, this.state.event)) { - const DateSeparator = sdk.getComponent('messages.DateSeparator'); - dateSep = ; + if (this.state.show) { + const EventTile = sdk.getComponent('views.rooms.EventTile'); + let dateSep = null; + if (wantsDateSeparator(this.props.parentEv, this.state.event)) { + const DateSeparator = sdk.getComponent('messages.DateSeparator'); + dateSep = ; + } + + return
+ { dateSep } + +
; } - return
- { dateSep } - -
; + return ; } // Deliberately render nothing if the URL isn't recognised diff --git a/src/components/views/messages/TextualBody.js b/src/components/views/messages/TextualBody.js index 54576fa794..fc5f1cc5f8 100644 --- a/src/components/views/messages/TextualBody.js +++ b/src/components/views/messages/TextualBody.js @@ -202,14 +202,12 @@ module.exports = React.createClass({ // update the current node with one that's now taken its place node = pillContainer; - } else if (SettingsStore.isFeatureEnabled("feature_rich_quoting") && this.props.tileShape !== 'quote' && - Quote.isMessageUrl(href) - ) { + } else if (SettingsStore.isFeatureEnabled("feature_rich_quoting") && Quote.isMessageUrl(href)) { // only allow this branch if we're not already in a quote, as fun as infinite nesting is. const quoteContainer = document.createElement('span'); const quote = - ; + ; ReactDOM.render(quote, quoteContainer); node.parentNode.replaceChild(quoteContainer, node); From 05434e782a0df6292c8c6ec4400e66b2c9d50f6c Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 18 Dec 2017 19:49:38 +0000 Subject: [PATCH 145/927] change Composer placeholder text based on replying/rich quoting state Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/MessageComposer.js | 32 ++++++++++++++++--- src/i18n/strings/en_EN.json | 2 ++ 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index 2841f30423..65e9f5f8ed 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -21,7 +21,7 @@ import MatrixClientPeg from '../../../MatrixClientPeg'; import Modal from '../../../Modal'; import sdk from '../../../index'; import dis from '../../../dispatcher'; -import Autocomplete from './Autocomplete'; +import RoomViewStore from '../../../stores/RoomViewStore'; import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore"; @@ -42,6 +42,7 @@ export default class MessageComposer extends React.Component { this.onToggleMarkdownClicked = this.onToggleMarkdownClicked.bind(this); this.onInputStateChanged = this.onInputStateChanged.bind(this); this.onEvent = this.onEvent.bind(this); + this._onRoomViewStoreUpdate = this._onRoomViewStoreUpdate.bind(this); this.state = { autocompleteQuery: '', @@ -53,6 +54,7 @@ export default class MessageComposer extends React.Component { wordCount: 0, }, showFormatting: SettingsStore.getValue('MessageComposer.showFormatting'), + isQuoting: Boolean(RoomViewStore.getQuotingEvent()), }; } @@ -62,12 +64,16 @@ export default class MessageComposer extends React.Component { // marked as encrypted. // XXX: fragile as all hell - fixme somehow, perhaps with a dedicated Room.encryption event or something. MatrixClientPeg.get().on("event", this.onEvent); + this._roomStoreToken = RoomViewStore.addListener(this._onRoomViewStoreUpdate); } componentWillUnmount() { if (MatrixClientPeg.get()) { MatrixClientPeg.get().removeListener("event", this.onEvent); } + if (this._roomStoreToken) { + this._roomStoreToken.remove(); + } } onEvent(event) { @@ -76,6 +82,12 @@ export default class MessageComposer extends React.Component { this.forceUpdate(); } + _onRoomViewStoreUpdate() { + const isQuoting = Boolean(RoomViewStore.getQuotingEvent()); + if (this.state.isQuoting === isQuoting) return; + this.setState({ isQuoting }); + } + onUploadClick(ev) { if (MatrixClientPeg.get().isGuest()) { dis.dispatch({action: 'view_set_mxid'}); @@ -325,8 +337,20 @@ export default class MessageComposer extends React.Component { key="controls_formatting" /> ); - const placeholderText = roomIsEncrypted ? - _t('Send an encrypted message') + '…' : _t('Send a message (unencrypted)') + '…'; + let placeholderText; + if (this.state.isQuoting) { + if (roomIsEncrypted) { + placeholderText = _t('Send an encrypted reply'); + } else { + placeholderText = _t('Send a reply (unencrypted)'); + } + } else { + if (roomIsEncrypted) { + placeholderText = _t('Send an encrypted message'); + } else { + placeholderText = _t('Send a message (unencrypted)'); + } + } controls.push( , diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 0a7d274c96..81b89d823e 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -298,7 +298,9 @@ "Upload file": "Upload file", "Show Text Formatting Toolbar": "Show Text Formatting Toolbar", "Send an encrypted message": "Send an encrypted message", + "Send an encrypted reply": "Send an encrypted reply", "Send a message (unencrypted)": "Send a message (unencrypted)", + "Send a reply (unencrypted)": "Send a reply (unencrypted)", "You do not have permission to post to this room": "You do not have permission to post to this room", "Turn Markdown on": "Turn Markdown on", "Turn Markdown off": "Turn Markdown off", From 21bca7e2d3c467e081a186e556f80ab59090fb2d Mon Sep 17 00:00:00 2001 From: IMIN <2reeseenmin@gmail.com> Date: Mon, 18 Dec 2017 21:34:17 +0000 Subject: [PATCH 146/927] Translated using Weblate (Korean) Currently translated at 67.7% (649 of 958 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ko/ .(could not connect media) --- src/i18n/strings/ko.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/ko.json b/src/i18n/strings/ko.json index f3d54e9449..7c49e3114d 100644 --- a/src/i18n/strings/ko.json +++ b/src/i18n/strings/ko.json @@ -318,7 +318,7 @@ "Reason: %(reasonText)s": "이유: %(reasonText)s", "Revoke Moderator": "조정자 철회", "Refer a friend to Riot:": "라이엇을 친구에게 추천해주세요:", - "Register": "등록하기", + "Register": "등록", "%(targetName)s rejected the invitation.": "%(targetName)s님이 초대를 거절하셨어요.", "Reject invitation": "초대 거절", "Rejoin": "다시 들어가기", @@ -731,5 +731,6 @@ "Ignore request": "요청 무시하기", "You added a new device '%(displayName)s', which is requesting encryption keys.": "새 장치 '%(displayName)s'를 추가했고 암호화 키를 요청하고 있어요.", "Your unverified device '%(displayName)s' is requesting encryption keys.": "인증하지 않은 장치 '%(displayName)s'가 암호화 키를 요청하고 있어요.", - "Encryption key request": "암호화 키 요청" + "Encryption key request": "암호화 키 요청", + "Edit": "수정하기" } From af2feb5e581f318b89fa2495825f1ad195a6c146 Mon Sep 17 00:00:00 2001 From: Tirifto Date: Tue, 19 Dec 2017 11:26:12 +0000 Subject: [PATCH 147/927] Translated using Weblate (Esperanto) Currently translated at 99.3% (952 of 958 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eo/ --- src/i18n/strings/eo.json | 270 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 263 insertions(+), 7 deletions(-) diff --git a/src/i18n/strings/eo.json b/src/i18n/strings/eo.json index b16ef6ca34..e464a991b7 100644 --- a/src/i18n/strings/eo.json +++ b/src/i18n/strings/eo.json @@ -258,7 +258,7 @@ "Encrypted by an unverified device": "Ĉifrita de nekontrolita aparato", "Unencrypted message": "Neĉifrita mesaĝo", "Please select the destination room for this message": "Bonvolu elekti celan ĉambron por ĉi tiu mesaĝo", - "Blacklisted": "Sur nigra listo", + "Blacklisted": "Senpova legi ĉifritajn mesaĝojn", "Verified": "Kontrolita", "Unverified": "Nekontrolita", "device id: ": "aparata identigaĵo: ", @@ -504,9 +504,9 @@ "Register": "Registriĝi", "Add rooms to this community": "Aldoni ĉambrojn al ĉi tiu komunumo", "Robot check is currently unavailable on desktop - please use a web browser": "Kontrolo kontraŭ robotoj ne disponeblas sur labortablo – bonvolu uzi retan foliumilon", - "This Home Server would like to make sure you are not a robot": "Tiu ĉi hejmservilo volas certigi, ke vi ne estas roboto", - "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.": "Vi povas uzi proprajn servilajn elektojn por saluti aliajn servilojn de Matrix per alia hejmservila URL.", - "This allows you to use this app with an existing Matrix account on a different home server.": "Tio ĉi permesos al vi uzi ĉi tiun aplikaĵon kun jama konto de Matrix el alia hejmservilo.", + "This Home Server would like to make sure you are not a robot": "Tiu ĉi hejma servilo volas certigi, ke vi ne estas roboto", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.": "Vi povas uzi proprajn servilajn elektojn por saluti aliajn servilojn de Matrix per alia adreso de hejma servilo.", + "This allows you to use this app with an existing Matrix account on a different home server.": "Tio ĉi permesos al vi uzi ĉi tiun aplikaĵon kun jama konto de Matrix el alia hejma servilo.", "You can also set a custom identity server but this will typically prevent interaction with users based on email address.": "Vi ankaŭ povas agordi propran identigan servilon, sed tio kutime malebligas interagadon kun uzantkontoj bazitaj sur retpoŝto.", "To continue, please enter your password.": "Por daŭrigi, bonvolu enigi vian pasvorton.", "Password:": "Pasvorto:", @@ -528,7 +528,7 @@ "Mobile phone number (optional)": "Telefona numero (malnepra)", "Default server": "Implicita servilo", "Custom server": "Propra servilo", - "Home server URL": "URL de hejmservilo", + "Home server URL": "Adreso de hejma servilo", "Identity server URL": "URL de identiga servilo", "What does this mean?": "Kion ĝi signifas?", "Remove from community": "Forigi de komunumo", @@ -645,7 +645,7 @@ "Click on the button below to start chatting!": "Alklaku la butonon sube por komenci babilon!", "Start Chatting": "Komenci babilon", "Confirm Removal": "Konfirmi forigon", - "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Ĉu vi certe volas forigi ĉi tiun okazaĵon? Per ŝanĝo de la ĉambra nomo aŭ temo, la ŝanĝo malfareblas.", + "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Ĉu vi certe volas forigi ĉi tiun okazaĵon? Per ŝanĝo de la ĉambra nomo aŭ temo, la ŝanĝo eble malfariĝos.", "Community IDs may only contain characters a-z, 0-9, or '=_-./'": "Komunuma identigaĵo povas enhavi nur signojn a-z, 0-9, aŭ ‹=_-./› (malinkluzive la citilojn)", "Something went wrong whilst creating your community": "Io misokazis dum kreado de via komunumo", "Create Community": "Krei komunumon", @@ -694,5 +694,261 @@ "This will allow you to reset your password and receive notifications.": "Tio ĉi permesos al vi restarigi vian pasvorton kaj ricevi sciigojn.", "Skip": "Preterpasi", "An error occurred: %(error_string)s": "Okazis eraro: %(error_string)s", - "This will be your account name on the homeserver, or you can pick a different server.": "Tio ĉi estos la nomo de via konto sur la hejmservilo , aŭ vi povas elekti alian servilon." + "This will be your account name on the homeserver, or you can pick a different server.": "Tio ĉi estos la nomo de via konto sur la hejmservilo , aŭ vi povas elekti alian servilon.", + "Blacklist": "Malpermesi legadon de ĉifritaj mesaĝoj", + "Unverify": "Malkontroli", + "If you already have a Matrix account you can log in instead.": "Se vi jam havas konton ĉe Matrix, vi povas saluti anstataŭe.", + "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "Vi nun malpermesas legadon de ĉifritaj mesaĝoj al nekontrolitaj aparatoj; por sendi mesaĝojn al tiuj, vi devas ilin kontroli.", + "We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "Ni rekomendas al vi bone kontroli ĉiun aparaton por certigi, ke ĝi apartenas al la verŝajna posedanto, sed vi povas resendi la mesaĝon sen kontrolo, laŭprefere.", + "Room contains unknown devices": "Ĉambro enhavas nekonatajn aparatojn", + "\"%(RoomName)s\" contains devices that you haven't seen before.": "«%(RoomName)s» enhavas aparatojn, kiujn vi neniam vidis antaŭe.", + "Unknown devices": "Nekonataj aparatoj", + "Private Chat": "Privata babilo", + "Public Chat": "Publika babilo", + "Custom": "Propra", + "Alias (optional)": "Kromnomo (malnepra)", + "Name": "Nomo", + "Topic": "Temo", + "Make this room private": "Privatigi ĉi tiun ĉambron", + "Share message history with new users": "Kunhavi mesaĝan historion kun novaj uzantoj", + "Encrypt room": "Ĉifri ĉambron", + "You must register to use this functionality": "Vi devas registriĝî por uzi tiun ĉi funkcion", + "You must join the room to see its files": "Vi devas aliĝi al la ĉambro por vidi tie dosierojn", + "There are no visible files in this room": "En ĉi tiu ĉambro estas neniaj videblaj dosieroj", + "

HTML for your community's page

\n

\n Use the long description to introduce new members to the community, or distribute\n some important links\n

\n

\n You can even use 'img' tags\n

\n": "

HTML por la paĝo de via komunumo

\n

\n Uzu la longan priskribon por enkonduki novajn komunumanojn, aŭ disdoni iujn\n gravajn ligilojn\n

\n

\n Vi povas eĉ uzi etikedojn ‹img›\n

\n", + "Add rooms to the community summary": "Aldoni ĉambrojn al la komunuma superrigardo", + "Which rooms would you like to add to this summary?": "Kiujn ĉambrojn vi volas aldoni al ĉi tiu superrigardo?", + "Add to summary": "Aldoni al superrigardo", + "Failed to add the following rooms to the summary of %(groupId)s:": "Malsukcesis aldoni la jenajn ĉambrojn al la superrigardo de %(groupId)s:", + "Add a Room": "Aldoni ĉambron", + "Failed to remove the room from the summary of %(groupId)s": "Malsukcesis forigi la ĉambron de la superrigardo de %(groupId)s", + "The room '%(roomName)s' could not be removed from the summary.": "Ĉambro ‹%(roomName)s› ne forigeblas de la superrigardo.", + "Add users to the community summary": "Aldoni uzantojn al la komunuma superrigardo", + "Who would you like to add to this summary?": "Kiun vi ŝatus aldoni al tiu ĉi superrigardo?", + "Failed to add the following users to the summary of %(groupId)s:": "Malsukcesis aldoni la jenajn uzantojn al la superrigardo de %(groupId)s:", + "Add a User": "Aldoni uzanton", + "Failed to remove a user from the summary of %(groupId)s": "Malsukcesis forigi uzanton de la superrigardo de %(groupId)s", + "The user '%(displayName)s' could not be removed from the summary.": "Uzanto ‹%(displayName)s› ne forigeblas de la superrigardo.", + "Failed to upload image": "Malsukcesis alŝuti bildon", + "Failed to update community": "Malskucesis ĝisdatigi la komunumon", + "Unable to accept invite": "Invito ne akcepteblas", + "Unable to reject invite": "Invito ne rifuzeblas", + "Leave Community": "Forlasi komunumon", + "Leave %(groupName)s?": "Ĉu foriri el %(groupName)s?", + "Unable to leave room": "Ĉambro ne forlaseblas", + "Community Settings": "Komunumaj agordoj", + "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Tiuj ĉi ĉambroj montriĝas al komunumanoj sur la paĝo de la komunumo. Ili povas aliĝi al la ĉambroj per alklakoj.", + "Featured Rooms:": "Elstarigitaj ĉambroj:", + "Featured Users:": "Elstarigitaj uzantoj:", + "%(inviter)s has invited you to join this community": "%(inviter)s invitis vin al tiu ĉi komunumo", + "You are an administrator of this community": "Vi estas administranto de tiu ĉi komunumo", + "You are a member of this community": "Vi estas ano de tiu ĉi komunumo", + "Your community hasn't got a Long Description, a HTML page to show to community members.
Click here to open settings and give it one!": "Via komunumo ne havas longan priskribon – HTML-paĝon por montri al komunumanoj.
Klaku ĉi tie por malfermi agordojn kaj fari ĝin!", + "Long Description (HTML)": "Longa priskribo (HTML)", + "Description": "Priskribo", + "Community %(groupId)s not found": "Komunumo %(groupId)s ne troviĝis", + "This Home server does not support communities": "Tiu ĉi hejma servilo ne subtenas komunumojn", + "Failed to load %(groupId)s": "Malsukcesis enlegi %(groupId)s", + "Reject invitation": "Rifuzi inviton", + "Are you sure you want to reject the invitation?": "Ĉu vi certe volas rifuzi la inviton?", + "Failed to reject invitation": "Malsukcesis rifuzi la inviton", + "Are you sure you want to leave the room '%(roomName)s'?": "Ĉu vi certe volas forlasi la ĉambron ‹%(roomName)s›?", + "Failed to leave room": "Malsukcesis forlasi la ĉambron", + "Signed Out": "Adiaŭinta", + "Cryptography data migrated": "Kriptografiaj datumoj transmetiĝis", + "A one-off migration of cryptography data has been performed. End-to-end encryption will not work if you go back to an older version of Riot. If you need to use end-to-end cryptography on an older version, log out of Riot first. To retain message history, export and re-import your keys.": "Unufoja transmeto de kriptografiaj datumoj fariĝis. Ĝiscela ĉifrado ne funkcios se vi revenos al pli malnova versio de Riot. Se vi bezonas ĝiscelan ĉifradon ĉe pli malnova versio, adiaŭu unue. Por reteni mesaĝan historion, elportu kaj reenportu viajn ŝlosilojn.", + "Old cryptography data detected": "Malnovaj kriptografiaj datumoj troviĝis", + "Data from an older version of Riot has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Datumoj el malnova versio de Riot troviĝis. Ĉi tio malfunkciigos ĝiscelan ĉifradon en la malnova versio. Ĝiscele ĉifritaj mesaĝoj interŝanĝitaj freŝtempe per la malnova versio eble ne malĉifreblos. Tio povas kaŭzi malsukceson ankaŭ al mesaĝoj interŝanĝitaj kun tiu ĉi versio. Se vin trafos problemoj, adiaŭu kaj resalutu. Por reteni mesaĝan historion, elportu kaj reenportu viajn ŝlosilojn.", + "Logout": "Adiaŭi", + "Your Communities": "Viaj komunumoj", + "Error whilst fetching joined communities": "Okazis eraro dum venigado de viaj komunumoj", + "Create a new community": "Krei novan komunumon", + "Create a community to group together users and rooms! Build a custom homepage to mark out your space in the Matrix universe.": "Kreu komunumon por kunigi uzantojn kaj ĉambrojn! Fari propran hejmpaĝon por montri vian spacon en la universo de Matrix.", + "Join an existing community": "Aliĝi al jama komunumo", + "To join an existing community you'll have to know its community identifier; this will look something like +example:matrix.org.": "Por aliĝi al jama komunumo, vi devos scii ĝian komunuman identigilon; ĝi aspektas proksimume tiel ĉi: +ekzemplo:matrix.org.", + "You have no visible notifications": "Neniuj videblaj sciigoj", + "Scroll to bottom of page": "Rulumi al susbo de la paĝo", + "Message not sent due to unknown devices being present": "Mesaĝoj ne sendiĝis pro ĉeesto de nekonataj aparatoj", + "Show devices or cancel all.": "Montri aparatojnnuligi ĉiujn.", + "Some of your messages have not been sent.": "Iuj viaj mesaĝoj ne sendiĝis.", + "Resend all or cancel all now. You can also select individual messages to resend or cancel.": "Resendi ĉionnuligi ĉion nun. Vi ankaŭ povas elekti unuopajn mesaĝojn por resendo aŭ nuligo.", + "Connectivity to the server has been lost.": "Konekto al la servilo perdiĝis.", + "Sent messages will be stored until your connection has returned.": "Senditaj mesaĝoj konserviĝos ĝis via konekto refunkcios.", + "%(count)s new messages|other": "%(count)s novaj mesaĝoj", + "%(count)s new messages|one": "%(count)s nova mesaĝo", + "Active call": "Aktiva voko", + "There's no one else here! Would you like to invite others or stop warning about the empty room?": "Neniu alia ĉeestas! Ĉu vi ŝatus inviti aliajnĉesigi avertadon pri la malplena ĉambro?", + "You seem to be uploading files, are you sure you want to quit?": "Ŝajne vi alŝutas dosierojn nun; ĉu vi tamen volas foriri?", + "You seem to be in a call, are you sure you want to quit?": "Ŝajne vi vokas nun; ĉu vi tamen volas foriri?", + "Failed to upload file": "Malsukcesis alŝuti dosieron", + "Server may be unavailable, overloaded, or the file too big": "Aŭ la servilo estas neatingebla aŭ troŝargita, aŭ la dosiero estas tro granda", + "Search failed": "Serĉo malsukcesis", + "Server may be unavailable, overloaded, or search timed out :(": "Aŭ la servilo estas neatingebla aŭ troŝargita, aŭ la serĉo eltempiĝis :(", + "No more results": "Neniuj pliaj rezultoj", + "Unknown room %(roomId)s": "Nekonata ĉambro %(roomId)s", + "Room": "Ĉambro", + "Failed to save settings": "Malsukcesis konservi agordojn", + "Failed to reject invite": "Malsukcesis rifuzi inviton", + "Fill screen": "Plenigi ekranon", + "Click to unmute video": "Klaku por ŝalti videon", + "Click to mute video": "Klaku por malŝalti videon", + "Click to unmute audio": "Klaku por ŝalti sonon", + "Click to mute audio": "Klaku por malŝalti sonon", + "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Provis enlegi certan parton de ĉi tiu historio, sed vi ne havas permeson vidi ĝin.", + "Tried to load a specific point in this room's timeline, but was unable to find it.": "Provis enlegi certan parton de ĉi tiu historio, sed malsukcesis ĝin trovi.", + "Failed to load timeline position": "Malsukcesis enlegi lokon en historio", + "Uploading %(filename)s and %(count)s others|other": "Alŝutanta dosieron %(filename)s kaj %(count)s aliajn", + "Uploading %(filename)s and %(count)s others|zero": "Alŝutanta dosieron %(filename)s", + "Uploading %(filename)s and %(count)s others|one": "Alŝutanta dosieron %(filename)s kaj %(count)s alian", + "Light theme": "Hela haŭto", + "Dark theme": "Malhela haŭto", + "Status.im theme": "Temo de status.im", + "Can't load user settings": "Agordoj de uzanto ne enlegeblas", + "Server may be unavailable or overloaded": "Servilo eble estas neatingebla aŭ troŝarĝita", + "Sign out": "Adiaŭi", + "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "Pro sekureco, adiaŭo forigos ĉiujn ĝiscele ĉifrajn ŝlosilojn de tiu ĉi foliumilo. Se vi volas malĉifri vian babilan historion el estontaj seancoj de Riot, bonvolu elporti kaj bone reteni viajn ĉambrojn ŝlosilojn.", + "Success": "Sukceso", + "Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them": "Via pasvorto sukcese ŝanĝiĝis. Vi ne ricevos puŝatentigojn en aliaj aparatoj ĝis vi resalutos ilin", + "Remove Contact Information?": "Ĉu forigi kontaktajn informojn?", + "Remove %(threePid)s?": "Ĉu forigi %(threePid)s?", + "Unable to remove contact information": "Kontaktaj informoj ne forigeblas", + "Refer a friend to Riot:": "Rekomendi programon Riot al konato:", + "Interface Language": "Fasada lingvo", + "User Interface": "Fasado por uzantoj", + "Autocomplete Delay (ms):": "Prokrasto de aŭtomata finado (ms):", + "": "", + "Import E2E room keys": "Enporti ĝiscele ĉifrajn ĉambrajn ŝlosilojn", + "Cryptography": "Kriptografio", + "Device ID:": "Aparata identigilo:", + "Device key:": "Aparata ŝlosilo:", + "Ignored Users": "Malatentataj uzantoj", + "Bug Report": "Cimraporto", + "Found a bug?": "Ĉu vi trovis cimon?", + "Report it": "Raporti ĝin", + "Analytics": "Analizo", + "Riot collects anonymous analytics to allow us to improve the application.": "Riot kolektas sennomaj analizajn datumojn por helpi plibonigadon de la programo.", + "Labs": "Eksperimentaj funkcioj", + "These are experimental features that may break in unexpected ways": "Tiu ĉi funkcioj estas eksperimentaj, kaj povas misfunkcii diversmaniere", + "Use with caution": "Uzu atenteme", + "Deactivate my account": "Malaktivigi mian konton", + "Clear Cache": "Vakigi kaŝmemoron", + "Clear Cache and Reload": "Vakigi kaŝmemoron kaj relegi", + "Updates": "Ĝisdatigoj", + "Check for update": "Kontroli ĝisdatigojn", + "Reject all %(invitedRooms)s invites": "Rifuzi ĉiujn %(invitedRooms)s invitojn", + "Bulk Options": "Amasaj agordoj", + "Desktop specific": "Specialaj al labortablo", + "Start automatically after system login": "Aŭtomate ruli post operaciuma saluto", + "No media permissions": "Neniuj permesoj pri aŭdvidaĵoj", + "You may need to manually permit Riot to access your microphone/webcam": "Eble vi devos permane permesi al Riot atingon de viaj mikrofono/kamerao", + "Missing Media Permissions, click here to request.": "Mankas permesoj pri aŭdvidaĵoj; klaku ĉi tie por peti ilin.", + "No Microphones detected": "Neniu mikrofono troviĝis", + "No Webcams detected": "Neniu kamerao troviĝis", + "Default Device": "Implicita aparato", + "Microphone": "Mikrofono", + "Camera": "Kamerao", + "VoIP": "Rettelefonado", + "Email": "Retpoŝto", + "Add email address": "Aldoni retpoŝtadreson", + "Notifications": "Sciigoj", + "Profile": "Profilo", + "Display name": "Vidiga nomo", + "Account": "Konto", + "To return to your account in future you need to set a password": "Por reveni al via konto estontece, vi devas agordi pasvorton", + "Logged in as:": "Salutinta kiel:", + "Access Token:": "Atinga ĵetono:", + "click to reveal": "klaku por malkovri", + "Homeserver is": "Hejmservilo estas", + "Identity Server is": "Identiga servilo estas", + "matrix-react-sdk version:": "versio de matrix-react-sdk:", + "riot-web version:": "versio de riot-web:", + "olm version:": "versio de olm:", + "Failed to send email": "Malsukcesis sendi retleteron", + "The email address linked to your account must be entered.": "Vi devas enigi retpoŝtadreson ligitan al via konto.", + "A new password must be entered.": "Vi devas enigi novan pasvorton.", + "New passwords must match each other.": "Novaj pasvortoj devas kongrui.", + "Resetting password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Restarigo de pasvorto nun nuligos ĝiscele ĉifrajn ŝlosilojn sur ĉiuj aparatoj, farante babilan historion nelegebla, krom se vi unue elportos viajn ĉambrajn ŝlosilojn kaj reenportos ilin poste. Estontece tio ĉi plifaciliĝos.", + "An email has been sent to %(emailAddress)s. Once you've followed the link it contains, click below.": "Retletero sendiĝis al %(emailAddress)s. Irinte al la ligilo en tiu mesaĝo, klaku sube.", + "I have verified my email address": "Mi kontrolis mian retpoŝtadreson", + "Your password has been reset": "Via pasvorto restariĝis", + "You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "Vi aŭtomate adiaŭis ĉiujn aparatojn kaj ne ricevos plu puŝsciigojn. Por reŝalti sciigojn, saluti denove per ĉiu aparato", + "Return to login screen": "Reiri al saluta paĝo", + "To reset your password, enter the email address linked to your account": "Por restarigi vian pasvorton, enigu la retpoŝtadreson ligitan al via konto", + "New password": "Nova pasvorto", + "Confirm your new password": "Konfirmu vian novan pasvorton", + "Send Reset Email": "Sendi restarigan retleteron", + "Create an account": "Krei konton", + "This Home Server does not support login using email address.": "Tiu ĉi hejma servilo ne subtenas saluton per retpoŝtadreso.", + "Please note you are logging into the %(hs)s server, not matrix.org.": "Sciu, ke vi salutas la servilon %(hs)s, ne la servilon matrix.org.", + "Guest access is disabled on this Home Server.": "Gasta atingo estas malŝaltita en tiu ĉi hejma servilo.", + "The phone number entered looks invalid": "Tiu ĉi telefona numero ŝajnas malvalida", + "This homeserver doesn't offer any login flows which are supported by this client.": "Tiu ĉi hejmservilo ne proponas salutajn fluojn subtenatajn de tiu ĉi kliento.", + "Error: Problem communicating with the given homeserver.": "Eraro: Estas problemo en komunikado kun la hejmservilo.", + "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Hejmservilo ne alkonekteblas per HTTP kun HTTPS URL en via adresbreto. Aŭ uzu HTTPS aŭ ŝaltu malsekurajn skriptojn.", + "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "Ne eblas konekti al hejmservilo – bonvolu kontroli vian konekton, certigi ke la SSL-atestilo de via hejmservilo estas fidata, kaj ke neniu foliumila kromprogramo baras petojn.", + "Login as guest": "Saluti kiel gasto", + "Sign in to get started": "Komencu per saluto", + "Failed to fetch avatar URL": "Malsukcesis venigi adreson de profilbildo", + "Set a display name:": "Agordi vidigan nomon:", + "Upload an avatar:": "Alŝuti profilbildon:", + "This server does not support authentication with a phone number.": "Ĉi tiu servilo ne subtenas aŭtentigon per telefona numero.", + "Missing password.": "Mankas pasvorto.", + "Passwords don't match.": "Pasvortoj ne kongruas.", + "Password too short (min %(MIN_PASSWORD_LENGTH)s).": "Pasvorto estas tro mallonga (malplejlonge %(MIN_PASSWORD_LENGTH)s).", + "This doesn't look like a valid email address.": "Tio ĉi ne ŝajnas esti valida retpoŝtadreso.", + "This doesn't look like a valid phone number.": "Tio ĉi ne ŝajnas esti valida telefona numero.", + "An unknown error occurred.": "Okazis nekonata eraro.", + "I already have an account": "Mi jam havas konton", + "Displays action": "Montras agon", + "Bans user with given id": "Forbaras uzanton kun la donita identigaĵo", + "Unbans user with given id": "Malforbaras uzanton kun la donita identigaĵo", + "Define the power level of a user": "Difini la potencan nivelon de uzanto", + "Deops user with given id": "Senestrigas uzanton kun donita identigaĵo", + "Invites user with given id to current room": "Invitas uzanton kun donita identigaĵo al la nuna ĉambro", + "Joins room with given alias": "Aliĝigas al ĉambro kun la donita kromnomo", + "Sets the room topic": "Agordas la ĉambran temon", + "Kicks user with given id": "Forpelas uzanton kun la donita identigaĵo", + "Changes your display nickname": "Ŝanĝas vian vidigan nomon", + "Searches DuckDuckGo for results": "Serĉas rezultojn per DuckDuckGo", + "Changes colour scheme of current room": "Ŝanĝas kolorsĥemon de la nuna ĉambro", + "Verifies a user, device, and pubkey tuple": "Kontrolas opon de uzanto, aparato, kaj publika ŝlosilo", + "Ignores a user, hiding their messages from you": "Malatentas uzanton, kaŝante ĝiajn mesaĝojn de vi", + "Stops ignoring a user, showing their messages going forward": "Ĉesas malatenti uzanton, montronte ĝiajn pluajn mesaĝojn", + "Commands": "Komandoj", + "Results from DuckDuckGo": "Rezultoj de DuckDuckGo", + "Emoji": "Mienetoj", + "Notify the whole room": "Sciigi la tutan ĉambron", + "Room Notification": "Ĉambra sciigo", + "Users": "Uzantoj", + "unknown device": "nekonata aparato", + "NOT verified": "nekontrolita", + "verified": "kontrolita", + "Verification": "Kontrolo", + "Ed25519 fingerprint": "Premsigno laŭ Ed25519", + "User ID": "Identigaĵo de uzanto", + "Curve25519 identity key": "Identiga ŝlosilo laŭ Curve25519", + "Claimed Ed25519 fingerprint key": "Asertita premsigno laŭ Ed25519", + "Algorithm": "Algoritmo", + "unencrypted": "neĉifritaj", + "Decryption error": "Malĉifra eraro", + "Session ID": "Seanca identigaĵo", + "End-to-end encryption information": "Informoj pri ĝiscela ĉifrado", + "Event information": "Informoj pri okazaĵo", + "Sender device information": "Informoj pri aparato de sendinto", + "Passphrases must match": "Pasfrazoj devas kongrui", + "Passphrase must not be empty": "Pasfrazoj maldevas esti malplenaj", + "Export room keys": "Elporti ĉambrajn ŝlosilojn", + "This process allows you to export the keys for messages you have received in encrypted rooms to a local file. You will then be able to import the file into another Matrix client in the future, so that client will also be able to decrypt these messages.": "Tio ĉi permesos al vi elporti al loka dosiero ŝlosilojn por la mesaĝoj ricevitaj en ĉifritaj ĉambroj. Poste vi povos enporti la dosieron en alian klienton de Matrix, por povigi ĝin malĉifri tiujn mesaĝojn.", + "The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.": "La elportita dosiero permesos al ajna havanto malĉifradon de ĉiuj ĉifritaj mesaĝoj videblaj al vi; tenu ĝin do sekure. Tial vi enigu sube pasfrazon, uzotan por ĉifri la elportitajn datumojn. Tiuj nur enporteblos kun la sama pasfrazo.", + "Enter passphrase": "Enigu pasfrazon", + "Confirm passphrase": "Konfirmu pasfrazon", + "Export": "Elporti", + "Import room keys": "Enporti ĉambrajn ŝlosilojn", + "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "Tio ĉi permesos al vi enporti ĉifrajn ŝlosilojn, kiujn vi antaŭe elportis el alia kliento de Matrix. Poste vi povos malĉifri la samajn mesaĝojn, kiujn la alia kliento povis.", + "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "La elportita dosiero estos protektata de pasfrazo. Por malĉifri ĝin, enigu la pasfrazon ĉi tien.", + "File to import": "Enportota dosiero", + "Import": "Enporti", + "Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?": "Forigo de fenestraĵo efektiviĝos por ĉiuj uzantoj en ĉi tiu ĉambro. Ĉu vi certe volas ĝin forigi?", + "Unblacklist": "Repermesi legadon de ĉifritaj mesaĝoj", + "none": "neniu" } From 774774c365a69ec4a563f972c608bf9f05dd45b5 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Tue, 19 Dec 2017 17:06:08 +0000 Subject: [PATCH 148/927] Remove unused dep. --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 0e2074f381..943c443c59 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,6 @@ "classnames": "^2.1.2", "commonmark": "^0.27.0", "counterpart": "^0.18.0", - "dom-to-image": "^2.6.0", "draft-js": "^0.11.0-alpha", "draft-js-export-html": "^0.6.0", "draft-js-export-markdown": "^0.3.0", From 8e5c3f01b47da99b6188805d671e792d4eb6b0d6 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Tue, 19 Dec 2017 17:08:17 +0000 Subject: [PATCH 149/927] License and linting fixes. --- src/MatrixPostMessageApi.js | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/src/MatrixPostMessageApi.js b/src/MatrixPostMessageApi.js index dd65cbd8fa..d6417f8764 100644 --- a/src/MatrixPostMessageApi.js +++ b/src/MatrixPostMessageApi.js @@ -1,10 +1,26 @@ +/* +Copyright 2017 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. +*/ + import Promise from "bluebird"; - function defer() { - let resolve, reject; + let resolve; + let reject; let isPending = true; - let promise = new Promise(function(...args) { + const promise = new Promise(function(...args) { resolve = args[0]; reject = args[1]; }); @@ -55,18 +71,18 @@ export default class PostMessageApi { if (this._onMsgCallback) { return this._onMsgCallback; } - let self = this; + const self = this; this._onMsgCallback = function(ev) { // THIS IS ALL UNSAFE EXECUTION. // We do not verify who the sender of `ev` is! - let payload = ev.data; + const payload = ev.data; // NOTE: Workaround for running in a mobile WebView where a // postMessage immediately triggers this callback even though it is // not the response. if (payload.response === undefined) { return; } - let deferred = self._pending[payload._id]; + const deferred = self._pending[payload._id]; if (!deferred) { return; } @@ -83,7 +99,7 @@ export default class PostMessageApi { this._counter += 1; target = target || "*"; action._id = Date.now() + "-" + Math.random().toString(36) + "-" + this._counter; - let d = defer(); + const d = defer(); this._pending[action._id] = d; this._window.postMessage(action, target); From 536d4efc4059127c6e407524436e1ea034057a99 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Tue, 19 Dec 2017 17:11:36 +0000 Subject: [PATCH 150/927] Fix comments. --- src/WidgetMessaging.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/WidgetMessaging.js b/src/WidgetMessaging.js index d71d86f8f5..2ca8589b54 100644 --- a/src/WidgetMessaging.js +++ b/src/WidgetMessaging.js @@ -54,7 +54,7 @@ The "message" key should be a human-friendly string. INBOUND ACTIONS =============== -** All actions must include an "api" field with valie "widget".** +** All actions must include an "api" field with value of "widget".** All actions can return an error response instead of the response outlined below. content_loaded @@ -66,7 +66,7 @@ Request: - No additional fields. Response: { - success: true + success: "true" } Example: { @@ -114,7 +114,7 @@ OUTBOUND ACTIONS ================ In addition to listening for inbound requests, the API can be used to initiate -actionss in the widget iframe, and request data from the widget instance. +actions in the widget iframe, and request data from the widget instance. Outbound actions use the "widget_client" API key / name, which must be included on all requests. @@ -135,11 +135,13 @@ Request a screenshot from the widget (if supported). This can only be supported by widgets that have access to all of their DOM tree. For example, widgets that nest further levels of iframes can not support this. +The screenshot is returned as a Blob object. + Request: - No additional fields. Response: { - screenshot: {data...} + screenshot: {data...} } Example: { From 08bcfc5c4e123f7382c06d182350b6df70438c47 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Tue, 19 Dec 2017 17:15:06 +0000 Subject: [PATCH 151/927] Make sure that capabilities array is initialised. --- src/components/views/elements/AppTile.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 770406e645..ea4f07e657 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -339,6 +339,7 @@ export default React.createClass({ this.widgetMessaging.addEndpoint(this.props.id, this.props.url); this.widgetMessaging.getCapabilities().then((capabilities) => { console.log("Got widget capabilities", this.widgetId, capabilities); + capabilities = capabilities || []; this.setState({capabilities}); }).catch((err) => { console.log("Failed to get widget capabilities", this.widgetId, err); From baf472b4a32d91992e3b774c6f2bfeff1df3f306 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Tue, 19 Dec 2017 17:16:38 +0000 Subject: [PATCH 152/927] Only show snapshot button when apps are maximised. --- src/components/views/elements/AppTile.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index ea4f07e657..07a24cba5b 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -484,8 +484,8 @@ export default React.createClass({ deleteClasses += ' mx_AppTileMenuBarWidgetDelete'; } - // Picture snapshot - const showPictureSnapshotButton = this._hasCapability('screenshot'); + // Picture snapshot - only show button when apps are maximised. + const showPictureSnapshotButton = this._hasCapability('screenshot') && this.props.show; const showPictureSnapshotIcon = 'img/camera_green.svg'; const windowStateIcon = (this.props.show ? 'img/minimize.svg' : 'img/maximize.svg'); From 20c485d85e4deaae0a8090496241133902a76486 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Wed, 20 Dec 2017 10:09:26 +0100 Subject: [PATCH 153/927] Move aria-hidden management from the BaseDialog component to the Modal --- src/Modal.js | 14 ++++++++++++++ src/components/views/dialogs/BaseDialog.js | 18 ------------------ 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/Modal.js b/src/Modal.js index 68d75d1ff1..69ff806045 100644 --- a/src/Modal.js +++ b/src/Modal.js @@ -186,11 +186,25 @@ class ModalManager { } _reRender() { + // Retrieve the root node of the Riot application outside the modal + let applicationNode = document.getElementById('matrixchat'); if (this._modals.length == 0) { + if (applicationNode) { + // If there is no modal to render, make all of Riot available + // to screen reader users again + applicationNode.setAttribute('aria-hidden', 'false'); + } ReactDOM.unmountComponentAtNode(this.getOrCreateContainer()); return; } + if (applicationNode) { + // Hide the content outside the modal to screen reader users + // so they won't be able to navigate into it and act on it using + // screen reader specific features + applicationNode.setAttribute('aria-hidden', 'true'); + } + const modal = this._modals[0]; const dialog = (
diff --git a/src/components/views/dialogs/BaseDialog.js b/src/components/views/dialogs/BaseDialog.js index db8e530fa0..7fb642b560 100644 --- a/src/components/views/dialogs/BaseDialog.js +++ b/src/components/views/dialogs/BaseDialog.js @@ -49,24 +49,6 @@ export default React.createClass({ contentId: React.PropTypes.string, }, - componentDidMount: function() { - // Retrieve the root node of the Riot application outside the dialog - this.applicationNode = document.getElementById('matrixchat'); - if (this.applicationNode) { - // Hide the content outside the dialog to screen reader users - // so they won't be able to navigate into it and act on it using - // screen reader specific features - this.applicationNode.setAttribute('aria-hidden', 'true'); - } - }, - - componentWillUnmount: function() { - if (this.applicationNode) { - // When dismissing the dialog, make all of Riot available to screen reader users again - this.applicationNode.setAttribute('aria-hidden', 'false'); - } - }, - _onKeyDown: function(e) { if (e.keyCode === KeyCode.ESCAPE) { e.stopPropagation(); From f2ca02eaf8aa7b4cd997526bc23396bddf25b8ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Wed, 20 Dec 2017 10:13:37 +0100 Subject: [PATCH 154/927] SetEmailDialog: use autoFocus prop on the EditableText rather than using its ref inside onComponentDidMount function. This is shorter better and has been requested. --- src/components/views/dialogs/SetEmailDialog.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/components/views/dialogs/SetEmailDialog.js b/src/components/views/dialogs/SetEmailDialog.js index 5a9569c1b5..ba054b0c27 100644 --- a/src/components/views/dialogs/SetEmailDialog.js +++ b/src/components/views/dialogs/SetEmailDialog.js @@ -40,10 +40,6 @@ export default React.createClass({ }; }, - componentDidMount: function() { - this.refs.emailInputField.focus(); - }, - onEmailAddressChanged: function(value) { this.setState({ emailAddress: value, @@ -131,7 +127,7 @@ export default React.createClass({ const emailInput = this.state.emailBusy ? : Date: Wed, 20 Dec 2017 10:55:39 +0000 Subject: [PATCH 155/927] Translated using Weblate (French) Currently translated at 100.0% (958 of 958 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index 9883e0eb21..980f20ade4 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -219,7 +219,7 @@ "unknown error code": "Code d'erreur inconnu", "OK": "OK", "Once encryption is enabled for a room it cannot be turned off again (for now)": "Une fois le chiffrement activé dans un salon il ne peut pas être désactivé (pour le moment)", - "Only people who have been invited": "Seul les personnes ayant été invitées", + "Only people who have been invited": "Seules les personnes ayant été invitées", "Password": "Mot de passe", "Passwords can't be empty": "Le mot de passe ne peut pas être vide", "People": "Personnes", From ab347c82f7479eca4794b74eb37b2ae728403889 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 21 Dec 2017 12:23:48 +0000 Subject: [PATCH 156/927] Allow argument to op slashcommand to be negative as PLs can be -ve Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/SlashCommands.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SlashCommands.js b/src/SlashCommands.js index 344bac1ddb..711805f8ef 100644 --- a/src/SlashCommands.js +++ b/src/SlashCommands.js @@ -295,7 +295,7 @@ const commands = { // Define the power level of a user op: new Command("op", " []", function(roomId, args) { if (args) { - const matches = args.match(/^(\S+?)( +(\d+))?$/); + const matches = args.match(/^(\S+?)( +(-?\d+))?$/); let powerLevel = 50; // default power level for op if (matches) { const userId = matches[1]; From e1a132b27bdb8d3daf3a6a0869dfe3b44ec1807e Mon Sep 17 00:00:00 2001 From: Joachim Nielandt Date: Fri, 22 Dec 2017 08:59:20 +0000 Subject: [PATCH 157/927] Translated using Weblate (Dutch) Currently translated at 74.1% (710 of 958 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/nl/ --- src/i18n/strings/nl.json | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/src/i18n/strings/nl.json b/src/i18n/strings/nl.json index 357ab92026..ac41825e58 100644 --- a/src/i18n/strings/nl.json +++ b/src/i18n/strings/nl.json @@ -97,7 +97,7 @@ "Failed to forget room %(errCode)s": "Ruimte vergeten mislukt %(errCode)s", "Favourite": "Favoriet", "Mute": "Dempen", - "Notifications": "Meldingen", + "Notifications": "Notificaties", "Operation failed": "Actie mislukt", "powered by Matrix": "mogelijk gemaakt door Matrix", "Remove": "Verwijderen", @@ -142,7 +142,7 @@ "Reason: %(reasonText)s": "Reden: %(reasonText)s", "Revoke Moderator": "Beheerder terugtrekken", "Refer a friend to Riot:": "Laat een vriend weten over Riot:", - "Register": "Registreren", + "Register": "Registreer", "%(targetName)s rejected the invitation.": "%(targetName)s heeft de uitnodiging geweigerd.", "Reject invitation": "Uitnodiging weigeren", "Rejoin": "Opnieuw toetreden", @@ -184,7 +184,7 @@ "Create an account": "Open een account", "Cryptography": "Cryptografie", "Current password": "Huidig wachtwoord", - "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s heeft de naam van de kamer verwijderd.", + "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s heeft de naam van de ruimte verwijderd.", "Create a new chat or reuse an existing one": "Maak een nieuwe chat aan of ga verder met een bestaande", "Create Room": "Maak een kamer aan", "Curve25519 identity key": "Curve25519-identiteitssleutel", @@ -308,7 +308,7 @@ "Sign in with": "Inloggen met", "Join as voice or video.": "Toetreden als spraak of video.", "Join Room": "Ruimte toetreden", - "%(targetName)s joined the room.": "%(targetName)s in de ruimte toegetreden.", + "%(targetName)s joined the room.": "%(targetName)s is aan de ruimte toegevoegd.", "Joins room with given alias": "Treed de ruimte toe met een gegeven naam", "Jump to first unread message.": "Spring naar het eerste ongelezen bericht.", "Labs": "Labs", @@ -367,7 +367,7 @@ "Room name (optional)": "Ruimtenaam (optioneel)", "%(roomName)s does not exist.": "%(roomName)s bestaat niet.", "%(roomName)s is not accessible at this time.": "%(roomName)s is niet toegankelijk op dit moment.", - "Rooms": "Ruimtes", + "Rooms": "Kamers", "Save": "Opslaan", "Scroll to bottom of page": "Scroll naar de onderkant van de pagina", "Scroll to unread messages": "Scroll naar ongelezen berichten", @@ -740,7 +740,7 @@ "Changes colour scheme of current room": "Verander het kleurenschema van de huidige ruimte", "Delete widget": "Widget verwijderen", "Do you want to load widget from URL:": "Wil je de widget laden van de URL:", - "Edit": "Wijzigen", + "Edit": "Aanpassen", "Enable automatic language detection for syntax highlighting": "Automatische taaldetectie voor zinsbouwmarkeringen aanzetten", "Hide Apps": "Apps verbergen", "Hide join/leave messages (invites/kicks/bans unaffected)": "Toetreed/verlaat berichten verbergen (uitnodigingen/verwijderingen/verbanningen zullen ongeschonden blijven)", @@ -775,5 +775,25 @@ "Robot check is currently unavailable on desktop - please use a web browser": "Robot-check is momenteel niet beschikbaar op de desktop - gebruik in plaats daarvan een webbrowser", "%(widgetName)s widget modified by %(senderName)s": "%(widgetName)s-widget aangepast door %(senderName)s", "Copied!": "Gekopieerd!", - "Failed to copy": "Kopiëren mislukt" + "Failed to copy": "Kopiëren mislukt", + "Unpin Message": "Maak pin los", + "Add rooms to this community": "Voeg kamers toe aan deze community", + "Call Failed": "Oproep mislukt", + "Call": "Bel", + "Answer": "Antwoord", + "Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "Opgepast: elke persoon die je toevoegt aan een community zal publiek zichtbaar zijn voor iedereen die het community ID kent", + "Invite new community members": "Nodig nieuwe community leden uit", + "Name or matrix ID": "Naam of Matrix ID", + "Which rooms would you like to add to this community?": "Welke kamers wil je toevoegen aan deze community?", + "Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?": "Een widget verwijderen doet dat voor alle gebruikers in deze ruimte. Ben je zeker dat je het widget wil verwijderen?", + "Delete Widget": "Widget verwijderen", + "There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "Er zijn onbekende toestellen in deze kamer: als je verder gaat zonder ze te verifieren zal het mogelijk zijn dat iemand je oproep afluistert.", + "Review Devices": "Toestellen nakijken", + "Call Anyway": "Bel toch", + "Answer Anyway": "Antwoord toch", + "Who would you like to add to this community?": "Wie wil je toevoegen aan deze community?", + "Invite to Community": "Nodig uit in deze community", + "Show these rooms to non-members on the community page and room list?": "Toon deze ruimtes aan niet-leden op de community pagina en lijst van ruimtes?", + "Add rooms to the community": "Voeg ruimtes toe aan de community", + "Room name or alias": "Ruimte naam of alias" } From 8bb16466d68a06fe9f05bf1e8ddbbe0be34229b1 Mon Sep 17 00:00:00 2001 From: Aidan Gauland Date: Mon, 18 Dec 2017 22:36:12 +1300 Subject: [PATCH 158/927] Rebase AddressSelector on BaseDialog --- .../views/dialogs/AddressPickerDialog.js | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/components/views/dialogs/AddressPickerDialog.js b/src/components/views/dialogs/AddressPickerDialog.js index 837d2f5349..716c6dac29 100644 --- a/src/components/views/dialogs/AddressPickerDialog.js +++ b/src/components/views/dialogs/AddressPickerDialog.js @@ -20,7 +20,6 @@ import PropTypes from 'prop-types'; import { _t } from '../../../languageHandler'; import sdk from '../../../index'; import MatrixClientPeg from '../../../MatrixClientPeg'; -import AccessibleButton from '../elements/AccessibleButton'; import Promise from 'bluebird'; import { addressTypes, getAddressType } from '../../../UserAddress.js'; import GroupStoreCache from '../../../stores/GroupStoreCache'; @@ -507,7 +506,7 @@ module.exports = React.createClass({ }, render: function() { - const TintableSvg = sdk.getComponent("elements.TintableSvg"); + const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); const AddressSelector = sdk.getComponent("elements.AddressSelector"); this.scrollElement = null; @@ -580,14 +579,8 @@ module.exports = React.createClass({ } return ( -
-
- { this.props.title } -
- - - +
@@ -602,7 +595,7 @@ module.exports = React.createClass({ { this.props.button }
-
+ ); }, }); From c5284eb07039845a2d03968c593af6b379529b45 Mon Sep 17 00:00:00 2001 From: Aidan Gauland Date: Mon, 18 Dec 2017 23:06:21 +1300 Subject: [PATCH 159/927] Allow BaseDialog to take a class for the title
Some dialogs need to set additional classes on the `mx_Dialog_title` `div` element (for example `danger`). --- src/components/views/dialogs/BaseDialog.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/dialogs/BaseDialog.js b/src/components/views/dialogs/BaseDialog.js index b88a6c026e..56c8322c0b 100644 --- a/src/components/views/dialogs/BaseDialog.js +++ b/src/components/views/dialogs/BaseDialog.js @@ -75,7 +75,7 @@ export default React.createClass({ > -
+
{ this.props.title }
{ this.props.children } From 9ebd58852c7ccc68a445121389ddd43eec157dc2 Mon Sep 17 00:00:00 2001 From: Aidan Gauland Date: Mon, 18 Dec 2017 23:08:51 +1300 Subject: [PATCH 160/927] Rebase DeactivateAccountDialog on BaseDialog --- .../views/dialogs/DeactivateAccountDialog.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/components/views/dialogs/DeactivateAccountDialog.js b/src/components/views/dialogs/DeactivateAccountDialog.js index c45e072d72..2af9acfbb5 100644 --- a/src/components/views/dialogs/DeactivateAccountDialog.js +++ b/src/components/views/dialogs/DeactivateAccountDialog.js @@ -77,6 +77,7 @@ export default class DeactivateAccountDialog extends React.Component { } render() { + const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); const Loader = sdk.getComponent("elements.Spinner"); let passwordBoxClass = ''; @@ -99,10 +100,11 @@ export default class DeactivateAccountDialog extends React.Component { } return ( -
-
- { _t("Deactivate Account") } -
+

{ _t("This will make your account permanently unusable. You will not be able to re-register the same user ID.") }

@@ -130,7 +132,7 @@ export default class DeactivateAccountDialog extends React.Component { { cancelButton }
-
+ ); } } From 45d86ea7ca764c00dac2ae4c04a09bfc89eb23ab Mon Sep 17 00:00:00 2001 From: Aidan Gauland Date: Thu, 21 Dec 2017 23:48:46 +1300 Subject: [PATCH 161/927] Add DialogButton component A component to normalise the buttons in dialogs. --- .../views/elements/DialogButtons.js | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 src/components/views/elements/DialogButtons.js diff --git a/src/components/views/elements/DialogButtons.js b/src/components/views/elements/DialogButtons.js new file mode 100644 index 0000000000..e730bfb377 --- /dev/null +++ b/src/components/views/elements/DialogButtons.js @@ -0,0 +1,61 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +"use strict"; + +import React from "react"; +import { _t } from '../../../languageHandler'; + +/** + * Basic container for buttons in modal dialogs. + */ +module.exports = React.createClass({ + displayName: "DialogButtons", + + propTypes: { + // The primary button which is styled differently and has default focus. + primaryButton: React.PropTypes.node.isRequired, + + // onClick handler for the primary button. + onPrimaryButtonClick: React.PropTypes.func.isRequired, + + // onClick handler for the cancel button. + onCancel: React.PropTypes.func.isRequired, + + focus: React.PropTypes.bool, + }, + + render: function() { + let primaryButtonClassName = "mx_Dialog_primary"; + if (this.props.primaryButtonClass) { + primaryButtonClassName += " " + this.props.primaryButtonClass; + } + return ( +
+ + { this.props.children } + +
+ ); + }, +}); From 3b2c61e4566512b3f513aacd2ccfece2dbc37e31 Mon Sep 17 00:00:00 2001 From: Aidan Gauland Date: Thu, 21 Dec 2017 23:51:14 +1300 Subject: [PATCH 162/927] Use DialogButtons in QuestionDialog Use DialogButtons to eliminate duplicate button code. --- .../views/dialogs/QuestionDialog.js | 30 ++++++++----------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/src/components/views/dialogs/QuestionDialog.js b/src/components/views/dialogs/QuestionDialog.js index 339b284e2f..4197199bde 100644 --- a/src/components/views/dialogs/QuestionDialog.js +++ b/src/components/views/dialogs/QuestionDialog.js @@ -18,7 +18,6 @@ limitations under the License. import React from 'react'; import sdk from '../../../index'; import { _t } from '../../../languageHandler'; -import classnames from 'classnames'; export default React.createClass({ displayName: 'QuestionDialog', @@ -53,30 +52,27 @@ export default React.createClass({ render: function() { const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); - const cancelButton = this.props.hasCancelButton ? ( - - ) : null; - const buttonClasses = classnames({ - mx_Dialog_primary: true, - danger: this.props.danger, - }); + const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); + let primaryButtonClass = ""; + if (this.props.danger) { + primaryButtonClass = "danger"; + } return (
{ this.props.description } -
-
- +
. + { this.props.extraButtons } - { cancelButton } -
+ ); }, From 0f6125e74958cc7e2e62f4a60916804a72df0311 Mon Sep 17 00:00:00 2001 From: Aidan Gauland Date: Sat, 23 Dec 2017 10:12:47 +1300 Subject: [PATCH 163/927] Use DialogButtons in AddressSelector Use DialogButtons to eliminate duplicate button code. --- src/components/views/dialogs/AddressPickerDialog.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/components/views/dialogs/AddressPickerDialog.js b/src/components/views/dialogs/AddressPickerDialog.js index 716c6dac29..685c4fcde3 100644 --- a/src/components/views/dialogs/AddressPickerDialog.js +++ b/src/components/views/dialogs/AddressPickerDialog.js @@ -507,6 +507,7 @@ module.exports = React.createClass({ render: function() { const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); + const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); const AddressSelector = sdk.getComponent("elements.AddressSelector"); this.scrollElement = null; @@ -590,11 +591,9 @@ module.exports = React.createClass({ { addressSelector } { this.props.extraNode }
-
- -
+ ); }, From c863dbfc7601f254edf3c7ec7bcf7e18575cfd36 Mon Sep 17 00:00:00 2001 From: Aidan Gauland Date: Sat, 23 Dec 2017 13:42:44 +1300 Subject: [PATCH 164/927] Use DialogButtons in CreateRoomDialog Use DialogButtons to eliminate duplicate button code. --- src/components/views/dialogs/CreateRoomDialog.js | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/components/views/dialogs/CreateRoomDialog.js b/src/components/views/dialogs/CreateRoomDialog.js index f7be47b3eb..a53f88f707 100644 --- a/src/components/views/dialogs/CreateRoomDialog.js +++ b/src/components/views/dialogs/CreateRoomDialog.js @@ -41,6 +41,7 @@ export default React.createClass({ render: function() { const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); + const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); return (
-
- - -
+ ); }, From aecb4650bc901d2c610be2e71c1b376ed541f804 Mon Sep 17 00:00:00 2001 From: Aidan Gauland Date: Sat, 23 Dec 2017 13:56:04 +1300 Subject: [PATCH 165/927] Correct order of buttons in CreateGroupDialog We can't use DialogButtons because the primary button is an element. --- src/components/views/dialogs/CreateGroupDialog.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/dialogs/CreateGroupDialog.js b/src/components/views/dialogs/CreateGroupDialog.js index 168fe75947..d811dde09e 100644 --- a/src/components/views/dialogs/CreateGroupDialog.js +++ b/src/components/views/dialogs/CreateGroupDialog.js @@ -159,10 +159,10 @@ export default React.createClass({ { createErrorNode }
+ -
From 7a761dbf6bdfef2067956e8968ef660e214b2caf Mon Sep 17 00:00:00 2001 From: Aidan Gauland Date: Sat, 23 Dec 2017 16:15:28 +1300 Subject: [PATCH 166/927] Use DialogButtons in ChatCreateOrReuseDialog Use DialogButtons to eliminate duplicate button code. --- src/components/views/dialogs/ChatCreateOrReuseDialog.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/components/views/dialogs/ChatCreateOrReuseDialog.js b/src/components/views/dialogs/ChatCreateOrReuseDialog.js index e0578f3b53..22e747a989 100644 --- a/src/components/views/dialogs/ChatCreateOrReuseDialog.js +++ b/src/components/views/dialogs/ChatCreateOrReuseDialog.js @@ -137,6 +137,7 @@ export default class ChatCreateOrReuseDialog extends React.Component { } else { // Show the avatar, name and a button to confirm that a new chat is requested const BaseAvatar = sdk.getComponent('avatars.BaseAvatar'); + const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); const Spinner = sdk.getComponent('elements.Spinner'); title = _t('Start chatting'); @@ -166,11 +167,8 @@ export default class ChatCreateOrReuseDialog extends React.Component {

{ profile }
-
- -
+
; } From 93b789438b90888006d714a8e9cd07dc71a9a598 Mon Sep 17 00:00:00 2001 From: Aidan Gauland Date: Sat, 23 Dec 2017 16:15:53 +1300 Subject: [PATCH 167/927] Use DialogButtons in ConfirmUserActionDialog Use DialogButtons to eliminate duplicate button code. --- .../views/dialogs/ConfirmUserActionDialog.js | 22 ++++++------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/src/components/views/dialogs/ConfirmUserActionDialog.js b/src/components/views/dialogs/ConfirmUserActionDialog.js index 78d084b709..91d2b342a4 100644 --- a/src/components/views/dialogs/ConfirmUserActionDialog.js +++ b/src/components/views/dialogs/ConfirmUserActionDialog.js @@ -76,13 +76,11 @@ export default React.createClass({ render: function() { const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); + const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); const MemberAvatar = sdk.getComponent("views.avatars.MemberAvatar"); const BaseAvatar = sdk.getComponent("views.avatars.BaseAvatar"); - const confirmButtonClass = classnames({ - 'mx_Dialog_primary': true, - 'danger': this.props.danger, - }); + const confirmButtonClass = this.props.danger ? 'danger' : ''; let reasonBox; if (this.props.askReason) { @@ -127,17 +125,11 @@ export default React.createClass({
{ userId }
{ reasonBox } -
- - - -
+ ); }, From a11146f39d890e906f6262909ce2dfa4e57e93eb Mon Sep 17 00:00:00 2001 From: Aidan Gauland Date: Sat, 23 Dec 2017 16:44:32 +1300 Subject: [PATCH 168/927] Use DialogButtons in SessionRestoreErrorDialog Use DialogButtons to eliminate duplicate button code. --- .../views/dialogs/SessionRestoreErrorDialog.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/components/views/dialogs/SessionRestoreErrorDialog.js b/src/components/views/dialogs/SessionRestoreErrorDialog.js index 75ae0eda17..2e384a268f 100644 --- a/src/components/views/dialogs/SessionRestoreErrorDialog.js +++ b/src/components/views/dialogs/SessionRestoreErrorDialog.js @@ -40,6 +40,7 @@ export default React.createClass({ render: function() { const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); + const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); let bugreport; if (SdkConfig.get().bug_report_endpoint_url) { @@ -68,11 +69,9 @@ export default React.createClass({ { bugreport }
-
- -
+ ); }, From 2674fcb6d3f5735d8158b1399000169cce9e00e9 Mon Sep 17 00:00:00 2001 From: Aidan Gauland Date: Sat, 23 Dec 2017 16:50:35 +1300 Subject: [PATCH 169/927] Use DialogButtons in TextInputDialog Use DialogButtons to eliminate duplicate button code. --- src/components/views/dialogs/TextInputDialog.js | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/components/views/dialogs/TextInputDialog.js b/src/components/views/dialogs/TextInputDialog.js index 5ea4191e5e..2e40ee0d67 100644 --- a/src/components/views/dialogs/TextInputDialog.js +++ b/src/components/views/dialogs/TextInputDialog.js @@ -58,6 +58,7 @@ export default React.createClass({ render: function() { const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); + const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); return (
-
- - -
+ ); }, From e6dbc3b863a7010a14e58c24abeddd933eb70870 Mon Sep 17 00:00:00 2001 From: Aidan Gauland Date: Sat, 23 Dec 2017 16:50:45 +1300 Subject: [PATCH 170/927] Use DialogButtons in UnknownDeviceDialog Use DialogButtons to eliminate duplicate button code. --- .../views/dialogs/UnknownDeviceDialog.js | 24 +++++-------------- 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/src/components/views/dialogs/UnknownDeviceDialog.js b/src/components/views/dialogs/UnknownDeviceDialog.js index 9c19ee6eca..b81700cac0 100644 --- a/src/components/views/dialogs/UnknownDeviceDialog.js +++ b/src/components/views/dialogs/UnknownDeviceDialog.js @@ -187,18 +187,11 @@ export default React.createClass({ } }); }); - let sendButton; - if (haveUnknownDevices) { - sendButton = ; - } else { - sendButton = ; - } + const sendButtonOnClick = haveUnknownDevices ? this._onSendAnywayClicked : this._onSendClicked; + const sendButtonLabel = haveUnknownDevices ? this.props.sendAnywayLabel : this.props.sendAnywayLabel; const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); + const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); return ( -
- {sendButton} - -
+
); // XXX: do we want to give the user the option to enable blacklistUnverifiedDevices for this room (or globally) at this point? From 6f674f21f652699da0d0b9855fcfa061f713586f Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 25 Dec 2017 13:27:23 -0700 Subject: [PATCH 171/927] Hide the notification nag bar after enabling notifications and add a bit of documentation around why the notificationsEnabled setting isn't set here. Signed-off-by: Travis Ralston --- src/Notifier.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Notifier.js b/src/Notifier.js index 75b698862c..e69bdf4461 100644 --- a/src/Notifier.js +++ b/src/Notifier.js @@ -135,6 +135,10 @@ const Notifier = { const plaf = PlatformPeg.get(); if (!plaf) return; + // Dev note: We don't set the "notificationsEnabled" setting to true here because it is a + // calculated value. It is determined based upon whether or not the master rule is enabled + // and other flags. Setting it here would cause a circular reference. + Analytics.trackEvent('Notifier', 'Set Enabled', enable); // make sure that we persist the current setting audio_enabled setting @@ -168,7 +172,7 @@ const Notifier = { }); // clear the notifications_hidden flag, so that if notifications are // disabled again in the future, we will show the banner again. - this.setToolbarHidden(false); + this.setToolbarHidden(true); } else { dis.dispatch({ action: "notifier_enabled", From 2815c576c1c2758ec6fce69775b92ff99b6e505e Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 25 Dec 2017 13:29:30 -0700 Subject: [PATCH 172/927] Ignore the default value when calculating if notifications are enabled This is to make the "Enable desktop notifications" checkbox accurately reflect the user's preference. The device-level setting is still respected. Signed-off-by: Travis Ralston --- src/settings/SettingsStore.js | 12 ++++++------ src/settings/controllers/NotificationControllers.js | 4 ++-- src/settings/controllers/SettingController.js | 4 +++- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/settings/SettingsStore.js b/src/settings/SettingsStore.js index d93a48005d..a1b88fb0c2 100644 --- a/src/settings/SettingsStore.js +++ b/src/settings/SettingsStore.js @@ -222,9 +222,9 @@ export default class SettingsStore { if (explicit) { const handler = handlers[level]; - if (!handler) return SettingsStore._tryControllerOverride(settingName, level, roomId, null); + if (!handler) return SettingsStore._tryControllerOverride(settingName, level, roomId, null, null); const value = handler.getValue(settingName, roomId); - return SettingsStore._tryControllerOverride(settingName, level, roomId, value); + return SettingsStore._tryControllerOverride(settingName, level, roomId, value, level); } for (let i = minIndex; i < levelOrder.length; i++) { @@ -234,17 +234,17 @@ export default class SettingsStore { const value = handler.getValue(settingName, roomId); if (value === null || value === undefined) continue; - return SettingsStore._tryControllerOverride(settingName, level, roomId, value); + return SettingsStore._tryControllerOverride(settingName, level, roomId, value, levelOrder[i]); } - return SettingsStore._tryControllerOverride(settingName, level, roomId, null); + return SettingsStore._tryControllerOverride(settingName, level, roomId, null, null); } - static _tryControllerOverride(settingName, level, roomId, calculatedValue) { + static _tryControllerOverride(settingName, level, roomId, calculatedValue, calculatedAtLevel) { const controller = SETTINGS[settingName].controller; if (!controller) return calculatedValue; - const actualValue = controller.getValueOverride(level, roomId, calculatedValue); + const actualValue = controller.getValueOverride(level, roomId, calculatedValue, calculatedAtLevel); if (actualValue !== undefined && actualValue !== null) return actualValue; return calculatedValue; } diff --git a/src/settings/controllers/NotificationControllers.js b/src/settings/controllers/NotificationControllers.js index 9dcf78e26b..e78b67e847 100644 --- a/src/settings/controllers/NotificationControllers.js +++ b/src/settings/controllers/NotificationControllers.js @@ -35,11 +35,11 @@ function isMasterRuleEnabled() { } export class NotificationsEnabledController extends SettingController { - getValueOverride(level, roomId, calculatedValue) { + getValueOverride(level, roomId, calculatedValue, calculatedAtLevel) { const Notifier = require('../../Notifier'); // avoids cyclical references if (!Notifier.isPossible()) return false; - if (calculatedValue === null) { + if (calculatedValue === null || calculatedAtLevel === "default") { return isMasterRuleEnabled(); } diff --git a/src/settings/controllers/SettingController.js b/src/settings/controllers/SettingController.js index a91b616da9..0ebe0042e6 100644 --- a/src/settings/controllers/SettingController.js +++ b/src/settings/controllers/SettingController.js @@ -31,9 +31,11 @@ export default class SettingController { * @param {String} roomId The room ID, may be null. * @param {*} calculatedValue The value that the handlers think the setting should be, * may be null. + * @param {string} calculatedAtLevel The level for which the calculated value was + * calculated at. May be null. * @return {*} The value that should be used, or null if no override is applicable. */ - getValueOverride(level, roomId, calculatedValue) { + getValueOverride(level, roomId, calculatedValue, calculatedAtLevel) { return null; // no override } From e8392dfa0093466a708a3a14ba8da576469e6c60 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 25 Dec 2017 13:39:32 -0700 Subject: [PATCH 173/927] Have /tint use the primary color as the secondary if no secondary was given This is to make the color scheme actually apply itself now that the secondary color is not optional. In order to preserve it being optional in the command, we'll use the primary color as the secondary color as it has no major visual impact. Signed-off-by: Travis Ralston --- src/SlashCommands.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/SlashCommands.js b/src/SlashCommands.js index 344bac1ddb..4e711d6f44 100644 --- a/src/SlashCommands.js +++ b/src/SlashCommands.js @@ -96,6 +96,8 @@ const commands = { colorScheme.primary_color = matches[1]; if (matches[4]) { colorScheme.secondary_color = matches[4]; + } else { + colorScheme.secondary_color = colorScheme.primary_color; } return success( SettingsStore.setValue("roomColor", roomId, SettingLevel.ROOM_ACCOUNT, colorScheme), From e4b86f073069cc93b4bcb4c559db24d684d3002c Mon Sep 17 00:00:00 2001 From: Aidan Gauland Date: Tue, 26 Dec 2017 11:55:15 +1300 Subject: [PATCH 174/927] Fix use of deprecated module Use PropTypes from "prop-types" instead of the deprecated React.PropTypes submodule. --- src/components/views/elements/DialogButtons.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/components/views/elements/DialogButtons.js b/src/components/views/elements/DialogButtons.js index e730bfb377..4f22d43ae0 100644 --- a/src/components/views/elements/DialogButtons.js +++ b/src/components/views/elements/DialogButtons.js @@ -17,6 +17,7 @@ limitations under the License. "use strict"; import React from "react"; +import PropTypes from "prop-types"; import { _t } from '../../../languageHandler'; /** @@ -27,15 +28,15 @@ module.exports = React.createClass({ propTypes: { // The primary button which is styled differently and has default focus. - primaryButton: React.PropTypes.node.isRequired, + primaryButton: PropTypes.node.isRequired, // onClick handler for the primary button. - onPrimaryButtonClick: React.PropTypes.func.isRequired, + onPrimaryButtonClick: PropTypes.func.isRequired, // onClick handler for the cancel button. - onCancel: React.PropTypes.func.isRequired, + onCancel: PropTypes.func.isRequired, - focus: React.PropTypes.bool, + focus: PropTypes.bool, }, render: function() { From 9531b219d21f09f6f92eb41e923a525db268f12e Mon Sep 17 00:00:00 2001 From: Aidan Gauland Date: Tue, 26 Dec 2017 12:53:01 +1300 Subject: [PATCH 175/927] Remove unused imports --- src/components/views/dialogs/ConfirmUserActionDialog.js | 1 - src/components/views/dialogs/TextInputDialog.js | 1 - 2 files changed, 2 deletions(-) diff --git a/src/components/views/dialogs/ConfirmUserActionDialog.js b/src/components/views/dialogs/ConfirmUserActionDialog.js index 91d2b342a4..3515b1f58d 100644 --- a/src/components/views/dialogs/ConfirmUserActionDialog.js +++ b/src/components/views/dialogs/ConfirmUserActionDialog.js @@ -18,7 +18,6 @@ import React from 'react'; import { MatrixClient } from 'matrix-js-sdk'; import sdk from '../../../index'; import { _t } from '../../../languageHandler'; -import classnames from 'classnames'; import { GroupMemberType } from '../../../groups'; /* diff --git a/src/components/views/dialogs/TextInputDialog.js b/src/components/views/dialogs/TextInputDialog.js index 2e40ee0d67..cfe4ae0c99 100644 --- a/src/components/views/dialogs/TextInputDialog.js +++ b/src/components/views/dialogs/TextInputDialog.js @@ -16,7 +16,6 @@ limitations under the License. import React from 'react'; import sdk from '../../../index'; -import { _t } from '../../../languageHandler'; export default React.createClass({ displayName: 'TextInputDialog', From 35780f5ae0050e2e828721b752311006a742c2f2 Mon Sep 17 00:00:00 2001 From: Aidan Gauland Date: Tue, 26 Dec 2017 14:03:18 +1300 Subject: [PATCH 176/927] Remove use of deprecated React.PropTypes Replace all uses of React.PropTypes with PropTypes and importing PropTypes from 'prop-types'. --- src/Modal.js | 3 +- src/Velociraptor.js | 9 +-- .../views/dialogs/EncryptedEventDialog.js | 5 +- .../views/dialogs/ExportE2eKeysDialog.js | 5 +- .../views/dialogs/ImportE2eKeysDialog.js | 5 +- src/autocomplete/Components.js | 19 +++--- src/components/structures/ContextualMenu.js | 11 ++-- src/components/structures/CreateRoom.js | 5 +- src/components/structures/FilePanel.js | 3 +- src/components/structures/GroupView.js | 4 +- src/components/structures/InteractiveAuth.js | 27 ++++---- src/components/structures/LoggedInView.js | 17 +++--- src/components/structures/MatrixChat.js | 29 ++++----- src/components/structures/MessagePanel.js | 37 +++++------ src/components/structures/MyGroups.js | 3 +- src/components/structures/RoomStatusBar.js | 29 ++++----- src/components/structures/RoomView.js | 11 ++-- src/components/structures/ScrollPanel.js | 17 +++--- src/components/structures/TimelinePanel.js | 31 +++++----- src/components/structures/UploadBar.js | 3 +- src/components/structures/UserSettings.js | 13 ++-- .../structures/login/ForgotPassword.js | 15 ++--- src/components/structures/login/Login.js | 23 +++---- .../structures/login/PostRegistration.js | 3 +- .../structures/login/Registration.js | 39 ++++++------ src/components/views/avatars/BaseAvatar.js | 19 +++--- src/components/views/avatars/MemberAvatar.js | 15 ++--- .../views/avatars/MemberPresenceAvatar.js | 9 +-- src/components/views/avatars/RoomAvatar.js | 11 ++-- .../views/create_room/CreateRoomButton.js | 3 +- src/components/views/create_room/Presets.js | 5 +- src/components/views/create_room/RoomAlias.js | 7 ++- src/components/views/dialogs/BaseDialog.js | 11 ++-- .../views/dialogs/ChatCreateOrReuseDialog.js | 9 +-- .../views/dialogs/ConfirmUserActionDialog.js | 15 ++--- .../views/dialogs/CreateRoomDialog.js | 3 +- .../views/dialogs/DeactivateAccountDialog.js | 3 +- .../views/dialogs/DeviceVerifyDialog.js | 7 ++- src/components/views/dialogs/ErrorDialog.js | 15 ++--- .../views/dialogs/InteractiveAuthDialog.js | 17 +++--- .../views/dialogs/KeyShareDialog.js | 9 +-- .../views/dialogs/QuestionDialog.js | 15 ++--- .../dialogs/SessionRestoreErrorDialog.js | 5 +- .../views/dialogs/SetEmailDialog.js | 3 +- src/components/views/dialogs/SetMxIdDialog.js | 7 ++- .../views/dialogs/TextInputDialog.js | 17 +++--- .../views/elements/AccessibleButton.js | 7 ++- .../views/elements/AddressSelector.js | 13 ++-- src/components/views/elements/AddressTile.js | 7 ++- src/components/views/elements/AppTile.js | 19 +++--- .../views/elements/DeviceVerifyButtons.js | 5 +- .../views/elements/DirectorySearchBox.js | 13 ++-- src/components/views/elements/Dropdown.js | 29 ++++----- src/components/views/elements/EditableText.js | 21 ++++--- .../views/elements/EditableTextContainer.js | 11 ++-- src/components/views/elements/EmojiText.js | 5 +- src/components/views/elements/Flair.js | 4 +- .../views/elements/LanguageDropdown.js | 7 ++- .../views/elements/MemberEventListSummary.js | 15 ++--- .../views/elements/PowerSelector.js | 13 ++-- src/components/views/elements/ProgressBar.js | 5 +- src/components/views/elements/SettingsFlag.js | 19 +++--- src/components/views/elements/TagTile.js | 2 +- src/components/views/elements/TintableSvg.js | 9 +-- src/components/views/elements/UserSelector.js | 5 +- src/components/views/groups/GroupRoomTile.js | 2 +- src/components/views/groups/GroupTile.js | 2 +- src/components/views/login/CaptchaForm.js | 5 +- src/components/views/login/CasLogin.js | 3 +- src/components/views/login/CountryDropdown.js | 13 ++-- .../login/InteractiveAuthEntryComponents.js | 61 ++++++++++--------- src/components/views/login/PasswordLogin.js | 23 +++---- .../views/login/RegistrationForm.js | 27 ++++---- src/components/views/login/ServerConfig.js | 15 ++--- src/components/views/messages/MFileBody.js | 3 +- src/components/views/messages/MImageBody.js | 5 +- src/components/views/messages/MVideoBody.js | 5 +- src/components/views/messages/MessageEvent.js | 13 ++-- .../views/messages/RoomAvatarEvent.js | 3 +- src/components/views/messages/TextualBody.js | 11 ++-- src/components/views/messages/TextualEvent.js | 3 +- .../views/room_settings/AliasSettings.js | 11 ++-- .../views/room_settings/ColorSettings.js | 3 +- .../room_settings/RelatedGroupSettings.js | 9 +-- .../views/room_settings/UrlPreviewSettings.js | 3 +- src/components/views/rooms/AppsDrawer.js | 3 +- src/components/views/rooms/AuxPanel.js | 17 +++--- src/components/views/rooms/EntityTile.js | 25 ++++---- src/components/views/rooms/EventTile.js | 35 +++++------ src/components/views/rooms/ForwardMessage.js | 3 +- .../views/rooms/LinkPreviewWidget.js | 9 +-- .../views/rooms/MemberDeviceInfo.js | 5 +- src/components/views/rooms/MemberInfo.js | 5 +- src/components/views/rooms/MemberTile.js | 3 +- src/components/views/rooms/MessageComposer.js | 11 ++-- .../views/rooms/MessageComposerInput.js | 19 +++--- src/components/views/rooms/PinnedEventTile.js | 7 ++- .../views/rooms/PinnedEventsPanel.js | 5 +- src/components/views/rooms/PresenceLabel.js | 7 ++- .../views/rooms/ReadReceiptMarker.js | 19 +++--- src/components/views/rooms/RoomHeader.js | 25 ++++---- src/components/views/rooms/RoomList.js | 7 ++- src/components/views/rooms/RoomNameEditor.js | 3 +- src/components/views/rooms/RoomPreviewBar.js | 21 ++++--- src/components/views/rooms/RoomSettings.js | 13 ++-- src/components/views/rooms/RoomTile.js | 21 ++++--- src/components/views/rooms/RoomTopicEditor.js | 3 +- .../views/rooms/SearchResultTile.js | 9 +-- .../views/rooms/SearchableEntityList.js | 13 ++-- .../views/rooms/SimpleRoomHeader.js | 7 ++- .../views/rooms/TopUnreadMessagesBar.js | 5 +- src/components/views/rooms/UserTile.js | 3 +- .../views/settings/AddPhoneNumber.js | 5 +- src/components/views/settings/ChangeAvatar.js | 13 ++-- .../views/settings/ChangePassword.js | 19 +++--- src/components/views/settings/DevicesPanel.js | 3 +- .../views/settings/DevicesPanelEntry.js | 5 +- src/components/views/voip/CallPreview.js | 3 +- src/components/views/voip/CallView.js | 13 ++-- src/components/views/voip/IncomingCallBox.js | 3 +- src/components/views/voip/VideoFeed.js | 5 +- src/components/views/voip/VideoView.js | 7 ++- src/wrappers/withMatrixClient.js | 3 +- 123 files changed, 750 insertions(+), 632 deletions(-) diff --git a/src/Modal.js b/src/Modal.js index 68d75d1ff1..c9f08772e7 100644 --- a/src/Modal.js +++ b/src/Modal.js @@ -19,6 +19,7 @@ limitations under the License. const React = require('react'); const ReactDOM = require('react-dom'); +import PropTypes from 'prop-types'; import Analytics from './Analytics'; import sdk from './index'; @@ -33,7 +34,7 @@ const AsyncWrapper = React.createClass({ /** A function which takes a 'callback' argument which it will call * with the real component once it loads. */ - loader: React.PropTypes.func.isRequired, + loader: PropTypes.func.isRequired, }, getInitialState: function() { diff --git a/src/Velociraptor.js b/src/Velociraptor.js index 9a674d4f09..af4e6dcb60 100644 --- a/src/Velociraptor.js +++ b/src/Velociraptor.js @@ -1,5 +1,6 @@ const React = require('react'); const ReactDom = require('react-dom'); +import PropTypes from 'prop-types'; const Velocity = require('velocity-vector'); /** @@ -14,16 +15,16 @@ module.exports = React.createClass({ propTypes: { // either a list of child nodes, or a single child. - children: React.PropTypes.any, + children: PropTypes.any, // optional transition information for changing existing children - transition: React.PropTypes.object, + transition: PropTypes.object, // a list of state objects to apply to each child node in turn - startStyles: React.PropTypes.array, + startStyles: PropTypes.array, // a list of transition options from the corresponding startStyle - enterTransitionOpts: React.PropTypes.array, + enterTransitionOpts: PropTypes.array, }, getDefaultProps: function() { diff --git a/src/async-components/views/dialogs/EncryptedEventDialog.js b/src/async-components/views/dialogs/EncryptedEventDialog.js index a8f588d39a..5db8b2365f 100644 --- a/src/async-components/views/dialogs/EncryptedEventDialog.js +++ b/src/async-components/views/dialogs/EncryptedEventDialog.js @@ -15,6 +15,7 @@ limitations under the License. */ const React = require("react"); +import PropTypes from 'prop-types'; import { _t } from '../../../languageHandler'; const sdk = require('../../../index'); const MatrixClientPeg = require("../../../MatrixClientPeg"); @@ -23,8 +24,8 @@ module.exports = React.createClass({ displayName: 'EncryptedEventDialog', propTypes: { - event: React.PropTypes.object.isRequired, - onFinished: React.PropTypes.func.isRequired, + event: PropTypes.object.isRequired, + onFinished: PropTypes.func.isRequired, }, getInitialState: function() { diff --git a/src/async-components/views/dialogs/ExportE2eKeysDialog.js b/src/async-components/views/dialogs/ExportE2eKeysDialog.js index 04274442c2..06fb0668d5 100644 --- a/src/async-components/views/dialogs/ExportE2eKeysDialog.js +++ b/src/async-components/views/dialogs/ExportE2eKeysDialog.js @@ -16,6 +16,7 @@ limitations under the License. import FileSaver from 'file-saver'; import React from 'react'; +import PropTypes from 'prop-types'; import { _t } from '../../../languageHandler'; import * as Matrix from 'matrix-js-sdk'; @@ -29,8 +30,8 @@ export default React.createClass({ displayName: 'ExportE2eKeysDialog', propTypes: { - matrixClient: React.PropTypes.instanceOf(Matrix.MatrixClient).isRequired, - onFinished: React.PropTypes.func.isRequired, + matrixClient: PropTypes.instanceOf(Matrix.MatrixClient).isRequired, + onFinished: PropTypes.func.isRequired, }, getInitialState: function() { diff --git a/src/async-components/views/dialogs/ImportE2eKeysDialog.js b/src/async-components/views/dialogs/ImportE2eKeysDialog.js index a01b6580f1..10744a8911 100644 --- a/src/async-components/views/dialogs/ImportE2eKeysDialog.js +++ b/src/async-components/views/dialogs/ImportE2eKeysDialog.js @@ -15,6 +15,7 @@ limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import * as Matrix from 'matrix-js-sdk'; import * as MegolmExportEncryption from '../../../utils/MegolmExportEncryption'; @@ -40,8 +41,8 @@ export default React.createClass({ displayName: 'ImportE2eKeysDialog', propTypes: { - matrixClient: React.PropTypes.instanceOf(Matrix.MatrixClient).isRequired, - onFinished: React.PropTypes.func.isRequired, + matrixClient: PropTypes.instanceOf(Matrix.MatrixClient).isRequired, + onFinished: PropTypes.func.isRequired, }, getInitialState: function() { diff --git a/src/autocomplete/Components.js b/src/autocomplete/Components.js index a27533f7c2..b09f4e963e 100644 --- a/src/autocomplete/Components.js +++ b/src/autocomplete/Components.js @@ -15,6 +15,7 @@ limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import classNames from 'classnames'; /* These were earlier stateless functional components but had to be converted @@ -42,10 +43,10 @@ export class TextualCompletion extends React.Component { } } TextualCompletion.propTypes = { - title: React.PropTypes.string, - subtitle: React.PropTypes.string, - description: React.PropTypes.string, - className: React.PropTypes.string, + title: PropTypes.string, + subtitle: PropTypes.string, + description: PropTypes.string, + className: PropTypes.string, }; export class PillCompletion extends React.Component { @@ -69,9 +70,9 @@ export class PillCompletion extends React.Component { } } PillCompletion.propTypes = { - title: React.PropTypes.string, - subtitle: React.PropTypes.string, - description: React.PropTypes.string, - initialComponent: React.PropTypes.element, - className: React.PropTypes.string, + title: PropTypes.string, + subtitle: PropTypes.string, + description: PropTypes.string, + initialComponent: PropTypes.element, + className: PropTypes.string, }; diff --git a/src/components/structures/ContextualMenu.js b/src/components/structures/ContextualMenu.js index 3c2308e6a7..94f5713a79 100644 --- a/src/components/structures/ContextualMenu.js +++ b/src/components/structures/ContextualMenu.js @@ -20,6 +20,7 @@ limitations under the License. const classNames = require('classnames'); const React = require('react'); const ReactDOM = require('react-dom'); +import PropTypes from 'prop-types'; // Shamelessly ripped off Modal.js. There's probably a better way // of doing reusable widgets like dialog boxes & menus where we go and @@ -29,11 +30,11 @@ module.exports = { ContextualMenuContainerId: "mx_ContextualMenu_Container", propTypes: { - menuWidth: React.PropTypes.number, - menuHeight: React.PropTypes.number, - chevronOffset: React.PropTypes.number, - menuColour: React.PropTypes.string, - chevronFace: React.PropTypes.string, // top, bottom, left, right + menuWidth: PropTypes.number, + menuHeight: PropTypes.number, + chevronOffset: PropTypes.number, + menuColour: PropTypes.string, + chevronFace: PropTypes.string, // top, bottom, left, right }, getOrCreateContainer: function() { diff --git a/src/components/structures/CreateRoom.js b/src/components/structures/CreateRoom.js index 26454c5ea6..2bb9adb544 100644 --- a/src/components/structures/CreateRoom.js +++ b/src/components/structures/CreateRoom.js @@ -17,6 +17,7 @@ limitations under the License. 'use strict'; import React from 'react'; +import PropTypes from 'prop-types'; import { _t } from '../../languageHandler'; import sdk from '../../index'; import MatrixClientPeg from '../../MatrixClientPeg'; @@ -30,8 +31,8 @@ module.exports = React.createClass({ displayName: 'CreateRoom', propTypes: { - onRoomCreated: React.PropTypes.func, - collapsedRhs: React.PropTypes.bool, + onRoomCreated: PropTypes.func, + collapsedRhs: PropTypes.bool, }, phases: { diff --git a/src/components/structures/FilePanel.js b/src/components/structures/FilePanel.js index ffa5e45249..e86b76333d 100644 --- a/src/components/structures/FilePanel.js +++ b/src/components/structures/FilePanel.js @@ -15,6 +15,7 @@ limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import Matrix from 'matrix-js-sdk'; import sdk from '../../index'; @@ -28,7 +29,7 @@ const FilePanel = React.createClass({ displayName: 'FilePanel', propTypes: { - roomId: React.PropTypes.string.isRequired, + roomId: PropTypes.string.isRequired, }, getInitialState: function() { diff --git a/src/components/structures/GroupView.js b/src/components/structures/GroupView.js index 5ffb97c6ed..8bb6ba49b0 100644 --- a/src/components/structures/GroupView.js +++ b/src/components/structures/GroupView.js @@ -390,7 +390,7 @@ const FeaturedUser = React.createClass({ }); const GroupContext = { - groupStore: React.PropTypes.instanceOf(GroupStore).isRequired, + groupStore: PropTypes.instanceOf(GroupStore).isRequired, }; CategoryRoomList.contextTypes = GroupContext; @@ -408,7 +408,7 @@ export default React.createClass({ }, childContextTypes: { - groupStore: React.PropTypes.instanceOf(GroupStore), + groupStore: PropTypes.instanceOf(GroupStore), }, getChildContext: function() { diff --git a/src/components/structures/InteractiveAuth.js b/src/components/structures/InteractiveAuth.js index 8a2c1b8c79..8428e3c714 100644 --- a/src/components/structures/InteractiveAuth.js +++ b/src/components/structures/InteractiveAuth.js @@ -18,6 +18,7 @@ import Matrix from 'matrix-js-sdk'; const InteractiveAuth = Matrix.InteractiveAuth; import React from 'react'; +import PropTypes from 'prop-types'; import {getEntryComponentForLoginType} from '../views/login/InteractiveAuthEntryComponents'; @@ -26,18 +27,18 @@ export default React.createClass({ propTypes: { // matrix client to use for UI auth requests - matrixClient: React.PropTypes.object.isRequired, + matrixClient: PropTypes.object.isRequired, // response from initial request. If not supplied, will do a request on // mount. - authData: React.PropTypes.shape({ - flows: React.PropTypes.array, - params: React.PropTypes.object, - session: React.PropTypes.string, + authData: PropTypes.shape({ + flows: PropTypes.array, + params: PropTypes.object, + session: PropTypes.string, }), // callback - makeRequest: React.PropTypes.func.isRequired, + makeRequest: PropTypes.func.isRequired, // callback called when the auth process has finished, // successfully or unsuccessfully. @@ -51,22 +52,22 @@ export default React.createClass({ // the auth session. // * clientSecret {string} The client secret used in auth // sessions with the ID server. - onAuthFinished: React.PropTypes.func.isRequired, + onAuthFinished: PropTypes.func.isRequired, // Inputs provided by the user to the auth process // and used by various stages. As passed to js-sdk // interactive-auth - inputs: React.PropTypes.object, + inputs: PropTypes.object, // As js-sdk interactive-auth - makeRegistrationUrl: React.PropTypes.func, - sessionId: React.PropTypes.string, - clientSecret: React.PropTypes.string, - emailSid: React.PropTypes.string, + makeRegistrationUrl: PropTypes.func, + sessionId: PropTypes.string, + clientSecret: PropTypes.string, + emailSid: PropTypes.string, // If true, poll to see if the auth flow has been completed // out-of-band - poll: React.PropTypes.bool, + poll: PropTypes.bool, }, getInitialState: function() { diff --git a/src/components/structures/LoggedInView.js b/src/components/structures/LoggedInView.js index 38b7634edb..4338ea6cab 100644 --- a/src/components/structures/LoggedInView.js +++ b/src/components/structures/LoggedInView.js @@ -18,6 +18,7 @@ limitations under the License. import * as Matrix from 'matrix-js-sdk'; import React from 'react'; +import PropTypes from 'prop-types'; import { DragDropContext } from 'react-dnd'; import HTML5Backend from 'react-dnd-html5-backend'; @@ -44,23 +45,23 @@ const LoggedInView = React.createClass({ displayName: 'LoggedInView', propTypes: { - matrixClient: React.PropTypes.instanceOf(Matrix.MatrixClient).isRequired, - page_type: React.PropTypes.string.isRequired, - onRoomCreated: React.PropTypes.func, - onUserSettingsClose: React.PropTypes.func, + matrixClient: PropTypes.instanceOf(Matrix.MatrixClient).isRequired, + page_type: PropTypes.string.isRequired, + onRoomCreated: PropTypes.func, + onUserSettingsClose: PropTypes.func, // Called with the credentials of a registered user (if they were a ROU that // transitioned to PWLU) - onRegistered: React.PropTypes.func, + onRegistered: PropTypes.func, - teamToken: React.PropTypes.string, + teamToken: PropTypes.string, // and lots and lots of other stuff. }, childContextTypes: { - matrixClient: React.PropTypes.instanceOf(Matrix.MatrixClient), - authCache: React.PropTypes.object, + matrixClient: PropTypes.instanceOf(Matrix.MatrixClient), + authCache: PropTypes.object, }, getChildContext: function() { diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index 3452d13841..733007677b 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -19,6 +19,7 @@ limitations under the License. import Promise from 'bluebird'; import React from 'react'; +import PropTypes from 'prop-types'; import Matrix from "matrix-js-sdk"; import Analytics from "../../Analytics"; @@ -92,38 +93,38 @@ export default React.createClass({ displayName: 'MatrixChat', propTypes: { - config: React.PropTypes.object, - ConferenceHandler: React.PropTypes.any, - onNewScreen: React.PropTypes.func, - registrationUrl: React.PropTypes.string, - enableGuest: React.PropTypes.bool, + config: PropTypes.object, + ConferenceHandler: PropTypes.any, + onNewScreen: PropTypes.func, + registrationUrl: PropTypes.string, + enableGuest: PropTypes.bool, // the queryParams extracted from the [real] query-string of the URI - realQueryParams: React.PropTypes.object, + realQueryParams: PropTypes.object, // the initial queryParams extracted from the hash-fragment of the URI - startingFragmentQueryParams: React.PropTypes.object, + startingFragmentQueryParams: PropTypes.object, // called when we have completed a token login - onTokenLoginCompleted: React.PropTypes.func, + onTokenLoginCompleted: PropTypes.func, // Represents the screen to display as a result of parsing the initial // window.location - initialScreenAfterLogin: React.PropTypes.shape({ - screen: React.PropTypes.string.isRequired, - params: React.PropTypes.object, + initialScreenAfterLogin: PropTypes.shape({ + screen: PropTypes.string.isRequired, + params: PropTypes.object, }), // displayname, if any, to set on the device when logging // in/registering. - defaultDeviceDisplayName: React.PropTypes.string, + defaultDeviceDisplayName: PropTypes.string, // A function that makes a registration URL - makeRegistrationUrl: React.PropTypes.func.isRequired, + makeRegistrationUrl: PropTypes.func.isRequired, }, childContextTypes: { - appConfig: React.PropTypes.object, + appConfig: PropTypes.object, }, AuxPanel: { diff --git a/src/components/structures/MessagePanel.js b/src/components/structures/MessagePanel.js index 53cc660a9b..84441e1317 100644 --- a/src/components/structures/MessagePanel.js +++ b/src/components/structures/MessagePanel.js @@ -16,6 +16,7 @@ limitations under the License. import React from 'react'; import ReactDOM from 'react-dom'; +import PropTypes from 'prop-types'; import classNames from 'classnames'; import shouldHideEvent from '../../shouldHideEvent'; import dis from "../../dispatcher"; @@ -32,63 +33,63 @@ module.exports = React.createClass({ propTypes: { // true to give the component a 'display: none' style. - hidden: React.PropTypes.bool, + hidden: PropTypes.bool, // true to show a spinner at the top of the timeline to indicate // back-pagination in progress - backPaginating: React.PropTypes.bool, + backPaginating: PropTypes.bool, // true to show a spinner at the end of the timeline to indicate // forward-pagination in progress - forwardPaginating: React.PropTypes.bool, + forwardPaginating: PropTypes.bool, // the list of MatrixEvents to display - events: React.PropTypes.array.isRequired, + events: PropTypes.array.isRequired, // ID of an event to highlight. If undefined, no event will be highlighted. - highlightedEventId: React.PropTypes.string, + highlightedEventId: PropTypes.string, // Should we show URL Previews - showUrlPreview: React.PropTypes.bool, + showUrlPreview: PropTypes.bool, // event after which we should show a read marker - readMarkerEventId: React.PropTypes.string, + readMarkerEventId: PropTypes.string, // whether the read marker should be visible - readMarkerVisible: React.PropTypes.bool, + readMarkerVisible: PropTypes.bool, // the userid of our user. This is used to suppress the read marker // for pending messages. - ourUserId: React.PropTypes.string, + ourUserId: PropTypes.string, // true to suppress the date at the start of the timeline - suppressFirstDateSeparator: React.PropTypes.bool, + suppressFirstDateSeparator: PropTypes.bool, // whether to show read receipts - showReadReceipts: React.PropTypes.bool, + showReadReceipts: PropTypes.bool, // true if updates to the event list should cause the scroll panel to // scroll down when we are at the bottom of the window. See ScrollPanel // for more details. - stickyBottom: React.PropTypes.bool, + stickyBottom: PropTypes.bool, // callback which is called when the panel is scrolled. - onScroll: React.PropTypes.func, + onScroll: PropTypes.func, // callback which is called when more content is needed. - onFillRequest: React.PropTypes.func, + onFillRequest: PropTypes.func, // className for the panel - className: React.PropTypes.string.isRequired, + className: PropTypes.string.isRequired, // shape parameter to be passed to EventTiles - tileShape: React.PropTypes.string, + tileShape: PropTypes.string, // show twelve hour timestamps - isTwelveHour: React.PropTypes.bool, + isTwelveHour: PropTypes.bool, // show timestamps always - alwaysShowTimestamps: React.PropTypes.bool, + alwaysShowTimestamps: PropTypes.bool, }, componentWillMount: function() { diff --git a/src/components/structures/MyGroups.js b/src/components/structures/MyGroups.js index 9281fb199e..22157beaca 100644 --- a/src/components/structures/MyGroups.js +++ b/src/components/structures/MyGroups.js @@ -15,6 +15,7 @@ limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import GeminiScrollbar from 'react-gemini-scrollbar'; import sdk from '../../index'; import { _t } from '../../languageHandler'; @@ -26,7 +27,7 @@ export default withMatrixClient(React.createClass({ displayName: 'MyGroups', propTypes: { - matrixClient: React.PropTypes.object.isRequired, + matrixClient: PropTypes.object.isRequired, }, getInitialState: function() { diff --git a/src/components/structures/RoomStatusBar.js b/src/components/structures/RoomStatusBar.js index 77d506d9af..4f9de7eac9 100644 --- a/src/components/structures/RoomStatusBar.js +++ b/src/components/structures/RoomStatusBar.js @@ -16,6 +16,7 @@ limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import Matrix from 'matrix-js-sdk'; import { _t } from '../../languageHandler'; import sdk from '../../index'; @@ -41,59 +42,59 @@ module.exports = React.createClass({ propTypes: { // the room this statusbar is representing. - room: React.PropTypes.object.isRequired, + room: PropTypes.object.isRequired, // the number of messages which have arrived since we've been scrolled up - numUnreadMessages: React.PropTypes.number, + numUnreadMessages: PropTypes.number, // this is true if we are fully scrolled-down, and are looking at // the end of the live timeline. - atEndOfLiveTimeline: React.PropTypes.bool, + atEndOfLiveTimeline: PropTypes.bool, // This is true when the user is alone in the room, but has also sent a message. // Used to suggest to the user to invite someone - sentMessageAndIsAlone: React.PropTypes.bool, + sentMessageAndIsAlone: PropTypes.bool, // true if there is an active call in this room (means we show // the 'Active Call' text in the status bar if there is nothing // more interesting) - hasActiveCall: React.PropTypes.bool, + hasActiveCall: PropTypes.bool, // Number of names to display in typing indication. E.g. set to 3, will // result in "X, Y, Z and 100 others are typing." - whoIsTypingLimit: React.PropTypes.number, + whoIsTypingLimit: PropTypes.number, // callback for when the user clicks on the 'resend all' button in the // 'unsent messages' bar - onResendAllClick: React.PropTypes.func, + onResendAllClick: PropTypes.func, // callback for when the user clicks on the 'cancel all' button in the // 'unsent messages' bar - onCancelAllClick: React.PropTypes.func, + onCancelAllClick: PropTypes.func, // callback for when the user clicks on the 'invite others' button in the // 'you are alone' bar - onInviteClick: React.PropTypes.func, + onInviteClick: PropTypes.func, // callback for when the user clicks on the 'stop warning me' button in the // 'you are alone' bar - onStopWarningClick: React.PropTypes.func, + onStopWarningClick: PropTypes.func, // callback for when the user clicks on the 'scroll to bottom' button - onScrollToBottomClick: React.PropTypes.func, + onScrollToBottomClick: PropTypes.func, // callback for when we do something that changes the size of the // status bar. This is used to trigger a re-layout in the parent // component. - onResize: React.PropTypes.func, + onResize: PropTypes.func, // callback for when the status bar can be hidden from view, as it is // not displaying anything - onHidden: React.PropTypes.func, + onHidden: PropTypes.func, // callback for when the status bar is displaying something and should // be visible - onVisible: React.PropTypes.func, + onVisible: PropTypes.func, }, getDefaultProps: function() { diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index e240ab38d5..0bc825f076 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -24,6 +24,7 @@ import shouldHideEvent from "../../shouldHideEvent"; const React = require("react"); const ReactDOM = require("react-dom"); +import PropTypes from 'prop-types'; import Promise from 'bluebird'; const classNames = require("classnames"); import { _t } from '../../languageHandler'; @@ -58,18 +59,18 @@ if (DEBUG) { module.exports = React.createClass({ displayName: 'RoomView', propTypes: { - ConferenceHandler: React.PropTypes.any, + ConferenceHandler: PropTypes.any, // Called with the credentials of a registered user (if they were a ROU that // transitioned to PWLU) - onRegistered: React.PropTypes.func, + onRegistered: PropTypes.func, // An object representing a third party invite to join this room // Fields: // * inviteSignUrl (string) The URL used to join this room from an email invite // (given as part of the link in the invite email) // * invitedEmail (string) The email address that was invited to this room - thirdPartyInvite: React.PropTypes.object, + thirdPartyInvite: PropTypes.object, // Any data about the room that would normally come from the Home Server // but has been passed out-of-band, eg. the room name and avatar URL @@ -80,10 +81,10 @@ module.exports = React.createClass({ // * avatarUrl (string) The mxc:// avatar URL for the room // * inviterName (string) The display name of the person who // * invited us tovthe room - oobData: React.PropTypes.object, + oobData: PropTypes.object, // is the RightPanel collapsed? - collapsedRhs: React.PropTypes.bool, + collapsedRhs: PropTypes.bool, }, getInitialState: function() { diff --git a/src/components/structures/ScrollPanel.js b/src/components/structures/ScrollPanel.js index 37cb2977aa..cbb6001d5f 100644 --- a/src/components/structures/ScrollPanel.js +++ b/src/components/structures/ScrollPanel.js @@ -16,6 +16,7 @@ limitations under the License. const React = require("react"); const ReactDOM = require("react-dom"); +import PropTypes from 'prop-types'; const GeminiScrollbar = require('react-gemini-scrollbar'); import Promise from 'bluebird'; import { KeyCode } from '../../Keyboard'; @@ -86,7 +87,7 @@ module.exports = React.createClass({ * scroll down to show the new element, rather than preserving the * existing view. */ - stickyBottom: React.PropTypes.bool, + stickyBottom: PropTypes.bool, /* startAtBottom: if set to true, the view is assumed to start * scrolled to the bottom. @@ -95,7 +96,7 @@ module.exports = React.createClass({ * behaviour stays the same for other uses of ScrollPanel. * If so, let's remove this parameter down the line. */ - startAtBottom: React.PropTypes.bool, + startAtBottom: PropTypes.bool, /* onFillRequest(backwards): a callback which is called on scroll when * the user nears the start (backwards = true) or end (backwards = @@ -110,7 +111,7 @@ module.exports = React.createClass({ * directon (at this time) - which will stop the pagination cycle until * the user scrolls again. */ - onFillRequest: React.PropTypes.func, + onFillRequest: PropTypes.func, /* onUnfillRequest(backwards): a callback which is called on scroll when * there are children elements that are far out of view and could be removed @@ -121,24 +122,24 @@ module.exports = React.createClass({ * first element to remove if removing from the front/bottom, and last element * to remove if removing from the back/top. */ - onUnfillRequest: React.PropTypes.func, + onUnfillRequest: PropTypes.func, /* onScroll: a callback which is called whenever any scroll happens. */ - onScroll: React.PropTypes.func, + onScroll: PropTypes.func, /* onResize: a callback which is called whenever the Gemini scroll * panel is resized */ - onResize: React.PropTypes.func, + onResize: PropTypes.func, /* className: classnames to add to the top-level div */ - className: React.PropTypes.string, + className: PropTypes.string, /* style: styles to add to the top-level div */ - style: React.PropTypes.object, + style: PropTypes.object, }, getDefaultProps: function() { diff --git a/src/components/structures/TimelinePanel.js b/src/components/structures/TimelinePanel.js index 98f57a60b5..3760bb37c5 100644 --- a/src/components/structures/TimelinePanel.js +++ b/src/components/structures/TimelinePanel.js @@ -19,6 +19,7 @@ import SettingsStore from "../../settings/SettingsStore"; const React = require('react'); const ReactDOM = require("react-dom"); +import PropTypes from 'prop-types'; import Promise from 'bluebird'; const Matrix = require("matrix-js-sdk"); @@ -58,49 +59,49 @@ var TimelinePanel = React.createClass({ // representing. This may or may not have a room, depending on what it's // a timeline representing. If it has a room, we maintain RRs etc for // that room. - timelineSet: React.PropTypes.object.isRequired, + timelineSet: PropTypes.object.isRequired, - showReadReceipts: React.PropTypes.bool, + showReadReceipts: PropTypes.bool, // Enable managing RRs and RMs. These require the timelineSet to have a room. - manageReadReceipts: React.PropTypes.bool, - manageReadMarkers: React.PropTypes.bool, + manageReadReceipts: PropTypes.bool, + manageReadMarkers: PropTypes.bool, // true to give the component a 'display: none' style. - hidden: React.PropTypes.bool, + hidden: PropTypes.bool, // ID of an event to highlight. If undefined, no event will be highlighted. // typically this will be either 'eventId' or undefined. - highlightedEventId: React.PropTypes.string, + highlightedEventId: PropTypes.string, // id of an event to jump to. If not given, will go to the end of the // live timeline. - eventId: React.PropTypes.string, + eventId: PropTypes.string, // where to position the event given by eventId, in pixels from the // bottom of the viewport. If not given, will try to put the event // half way down the viewport. - eventPixelOffset: React.PropTypes.number, + eventPixelOffset: PropTypes.number, // Should we show URL Previews - showUrlPreview: React.PropTypes.bool, + showUrlPreview: PropTypes.bool, // callback which is called when the panel is scrolled. - onScroll: React.PropTypes.func, + onScroll: PropTypes.func, // callback which is called when the read-up-to mark is updated. - onReadMarkerUpdated: React.PropTypes.func, + onReadMarkerUpdated: PropTypes.func, // maximum number of events to show in a timeline - timelineCap: React.PropTypes.number, + timelineCap: PropTypes.number, // classname to use for the messagepanel - className: React.PropTypes.string, + className: PropTypes.string, // shape property to be passed to EventTiles - tileShape: React.PropTypes.string, + tileShape: PropTypes.string, // placeholder text to use if the timeline is empty - empty: React.PropTypes.string, + empty: PropTypes.string, }, statics: { diff --git a/src/components/structures/UploadBar.js b/src/components/structures/UploadBar.js index ca566d3a64..fed4ff33b3 100644 --- a/src/components/structures/UploadBar.js +++ b/src/components/structures/UploadBar.js @@ -15,6 +15,7 @@ limitations under the License. */ const React = require('react'); +import PropTypes from 'prop-types'; const ContentMessages = require('../../ContentMessages'); const dis = require('../../dispatcher'); const filesize = require('filesize'); @@ -22,7 +23,7 @@ import { _t } from '../../languageHandler'; module.exports = React.createClass({displayName: 'UploadBar', propTypes: { - room: React.PropTypes.object, + room: PropTypes.object, }, componentDidMount: function() { diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index 09844c3d63..3cd13a6ecb 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -19,6 +19,7 @@ import SettingsStore, {SettingLevel} from "../../settings/SettingsStore"; const React = require('react'); const ReactDOM = require('react-dom'); +import PropTypes from 'prop-types'; const sdk = require('../../index'); const MatrixClientPeg = require("../../MatrixClientPeg"); const PlatformPeg = require("../../PlatformPeg"); @@ -125,8 +126,8 @@ const THEMES = [ const IgnoredUser = React.createClass({ propTypes: { - userId: React.PropTypes.string.isRequired, - onUnignored: React.PropTypes.func.isRequired, + userId: PropTypes.string.isRequired, + onUnignored: PropTypes.func.isRequired, }, _onUnignoreClick: function() { @@ -155,16 +156,16 @@ module.exports = React.createClass({ displayName: 'UserSettings', propTypes: { - onClose: React.PropTypes.func, + onClose: PropTypes.func, // The brand string given when creating email pushers - brand: React.PropTypes.string, + brand: PropTypes.string, // The base URL to use in the referral link. Defaults to window.location.origin. - referralBaseUrl: React.PropTypes.string, + referralBaseUrl: PropTypes.string, // Team token for the referral link. If falsy, the referral section will // not appear - teamToken: React.PropTypes.string, + teamToken: PropTypes.string, }, getDefaultProps: function() { diff --git a/src/components/structures/login/ForgotPassword.js b/src/components/structures/login/ForgotPassword.js index 43753bfd38..53688ee6c3 100644 --- a/src/components/structures/login/ForgotPassword.js +++ b/src/components/structures/login/ForgotPassword.js @@ -18,6 +18,7 @@ limitations under the License. 'use strict'; import React from 'react'; +import PropTypes from 'prop-types'; import { _t } from '../../../languageHandler'; import sdk from '../../../index'; import Modal from "../../../Modal"; @@ -29,13 +30,13 @@ module.exports = React.createClass({ displayName: 'ForgotPassword', propTypes: { - defaultHsUrl: React.PropTypes.string, - defaultIsUrl: React.PropTypes.string, - customHsUrl: React.PropTypes.string, - customIsUrl: React.PropTypes.string, - onLoginClick: React.PropTypes.func, - onRegisterClick: React.PropTypes.func, - onComplete: React.PropTypes.func.isRequired, + defaultHsUrl: PropTypes.string, + defaultIsUrl: PropTypes.string, + customHsUrl: PropTypes.string, + customIsUrl: PropTypes.string, + onLoginClick: PropTypes.func, + onRegisterClick: PropTypes.func, + onComplete: PropTypes.func.isRequired, }, getInitialState: function() { diff --git a/src/components/structures/login/Login.js b/src/components/structures/login/Login.js index 9ed710534b..f4c08e8362 100644 --- a/src/components/structures/login/Login.js +++ b/src/components/structures/login/Login.js @@ -18,6 +18,7 @@ limitations under the License. 'use strict'; import React from 'react'; +import PropTypes from 'prop-types'; import { _t } from '../../../languageHandler'; import * as languageHandler from '../../../languageHandler'; import sdk from '../../../index'; @@ -36,27 +37,27 @@ module.exports = React.createClass({ displayName: 'Login', propTypes: { - onLoggedIn: React.PropTypes.func.isRequired, + onLoggedIn: PropTypes.func.isRequired, - enableGuest: React.PropTypes.bool, + enableGuest: PropTypes.bool, - customHsUrl: React.PropTypes.string, - customIsUrl: React.PropTypes.string, - defaultHsUrl: React.PropTypes.string, - defaultIsUrl: React.PropTypes.string, + customHsUrl: PropTypes.string, + customIsUrl: PropTypes.string, + defaultHsUrl: PropTypes.string, + defaultIsUrl: PropTypes.string, // Secondary HS which we try to log into if the user is using // the default HS but login fails. Useful for migrating to a // different home server without confusing users. - fallbackHsUrl: React.PropTypes.string, + fallbackHsUrl: PropTypes.string, - defaultDeviceDisplayName: React.PropTypes.string, + defaultDeviceDisplayName: PropTypes.string, // login shouldn't know or care how registration is done. - onRegisterClick: React.PropTypes.func.isRequired, + onRegisterClick: PropTypes.func.isRequired, // login shouldn't care how password recovery is done. - onForgotPasswordClick: React.PropTypes.func, - onCancelClick: React.PropTypes.func, + onForgotPasswordClick: PropTypes.func, + onCancelClick: PropTypes.func, }, getInitialState: function() { diff --git a/src/components/structures/login/PostRegistration.js b/src/components/structures/login/PostRegistration.js index 184356e852..f6165348bd 100644 --- a/src/components/structures/login/PostRegistration.js +++ b/src/components/structures/login/PostRegistration.js @@ -17,6 +17,7 @@ limitations under the License. 'use strict'; import React from 'react'; +import PropTypes from 'prop-types'; import sdk from '../../../index'; import MatrixClientPeg from '../../../MatrixClientPeg'; import { _t } from '../../../languageHandler'; @@ -25,7 +26,7 @@ module.exports = React.createClass({ displayName: 'PostRegistration', propTypes: { - onComplete: React.PropTypes.func.isRequired, + onComplete: PropTypes.func.isRequired, }, getInitialState: function() { diff --git a/src/components/structures/login/Registration.js b/src/components/structures/login/Registration.js index e57b7fd0c2..b8a85c5f82 100644 --- a/src/components/structures/login/Registration.js +++ b/src/components/structures/login/Registration.js @@ -19,6 +19,7 @@ import Matrix from 'matrix-js-sdk'; import Promise from 'bluebird'; import React from 'react'; +import PropTypes from 'prop-types'; import sdk from '../../../index'; import ServerConfig from '../../views/login/ServerConfig'; @@ -35,31 +36,31 @@ module.exports = React.createClass({ displayName: 'Registration', propTypes: { - onLoggedIn: React.PropTypes.func.isRequired, - clientSecret: React.PropTypes.string, - sessionId: React.PropTypes.string, - makeRegistrationUrl: React.PropTypes.func.isRequired, - idSid: React.PropTypes.string, - customHsUrl: React.PropTypes.string, - customIsUrl: React.PropTypes.string, - defaultHsUrl: React.PropTypes.string, - defaultIsUrl: React.PropTypes.string, - brand: React.PropTypes.string, - email: React.PropTypes.string, - referrer: React.PropTypes.string, - teamServerConfig: React.PropTypes.shape({ + onLoggedIn: PropTypes.func.isRequired, + clientSecret: PropTypes.string, + sessionId: PropTypes.string, + makeRegistrationUrl: PropTypes.func.isRequired, + idSid: PropTypes.string, + customHsUrl: PropTypes.string, + customIsUrl: PropTypes.string, + defaultHsUrl: PropTypes.string, + defaultIsUrl: PropTypes.string, + brand: PropTypes.string, + email: PropTypes.string, + referrer: PropTypes.string, + teamServerConfig: PropTypes.shape({ // Email address to request new teams - supportEmail: React.PropTypes.string.isRequired, + supportEmail: PropTypes.string.isRequired, // URL of the riot-team-server to get team configurations and track referrals - teamServerURL: React.PropTypes.string.isRequired, + teamServerURL: PropTypes.string.isRequired, }), - teamSelected: React.PropTypes.object, + teamSelected: PropTypes.object, - defaultDeviceDisplayName: React.PropTypes.string, + defaultDeviceDisplayName: PropTypes.string, // registration shouldn't know or care how login is done. - onLoginClick: React.PropTypes.func.isRequired, - onCancelClick: React.PropTypes.func, + onLoginClick: PropTypes.func.isRequired, + onCancelClick: PropTypes.func, }, getInitialState: function() { diff --git a/src/components/views/avatars/BaseAvatar.js b/src/components/views/avatars/BaseAvatar.js index f68e98ec3d..47c217eb96 100644 --- a/src/components/views/avatars/BaseAvatar.js +++ b/src/components/views/avatars/BaseAvatar.js @@ -15,6 +15,7 @@ limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import AvatarLogic from '../../../Avatar'; import sdk from '../../../index'; import AccessibleButton from '../elements/AccessibleButton'; @@ -23,16 +24,16 @@ module.exports = React.createClass({ displayName: 'BaseAvatar', propTypes: { - name: React.PropTypes.string.isRequired, // The name (first initial used as default) - idName: React.PropTypes.string, // ID for generating hash colours - title: React.PropTypes.string, // onHover title text - url: React.PropTypes.string, // highest priority of them all, shortcut to set in urls[0] - urls: React.PropTypes.array, // [highest_priority, ... , lowest_priority] - width: React.PropTypes.number, - height: React.PropTypes.number, + name: PropTypes.string.isRequired, // The name (first initial used as default) + idName: PropTypes.string, // ID for generating hash colours + title: PropTypes.string, // onHover title text + url: PropTypes.string, // highest priority of them all, shortcut to set in urls[0] + urls: PropTypes.array, // [highest_priority, ... , lowest_priority] + width: PropTypes.number, + height: PropTypes.number, // XXX resizeMethod not actually used. - resizeMethod: React.PropTypes.string, - defaultToInitialLetter: React.PropTypes.bool, // true to add default url + resizeMethod: PropTypes.string, + defaultToInitialLetter: PropTypes.bool, // true to add default url }, getDefaultProps: function() { diff --git a/src/components/views/avatars/MemberAvatar.js b/src/components/views/avatars/MemberAvatar.js index 89047cd69c..a4fe5e280f 100644 --- a/src/components/views/avatars/MemberAvatar.js +++ b/src/components/views/avatars/MemberAvatar.js @@ -17,6 +17,7 @@ limitations under the License. 'use strict'; const React = require('react'); +import PropTypes from 'prop-types'; const Avatar = require('../../../Avatar'); const sdk = require("../../../index"); const dispatcher = require("../../../dispatcher"); @@ -25,15 +26,15 @@ module.exports = React.createClass({ displayName: 'MemberAvatar', propTypes: { - member: React.PropTypes.object.isRequired, - width: React.PropTypes.number, - height: React.PropTypes.number, - resizeMethod: React.PropTypes.string, + member: PropTypes.object.isRequired, + width: PropTypes.number, + height: PropTypes.number, + resizeMethod: PropTypes.string, // The onClick to give the avatar - onClick: React.PropTypes.func, + onClick: PropTypes.func, // Whether the onClick of the avatar should be overriden to dispatch 'view_user' - viewUserOnClick: React.PropTypes.bool, - title: React.PropTypes.string, + viewUserOnClick: PropTypes.bool, + title: PropTypes.string, }, getDefaultProps: function() { diff --git a/src/components/views/avatars/MemberPresenceAvatar.js b/src/components/views/avatars/MemberPresenceAvatar.js index 49cfee2cff..aa6def00ae 100644 --- a/src/components/views/avatars/MemberPresenceAvatar.js +++ b/src/components/views/avatars/MemberPresenceAvatar.js @@ -17,6 +17,7 @@ 'use strict'; import React from "react"; +import PropTypes from 'prop-types'; import * as sdk from "../../../index"; import MatrixClientPeg from "../../../MatrixClientPeg"; import AccessibleButton from '../elements/AccessibleButton'; @@ -30,10 +31,10 @@ module.exports = React.createClass({ displayName: 'MemberPresenceAvatar', propTypes: { - member: React.PropTypes.object.isRequired, - width: React.PropTypes.number, - height: React.PropTypes.number, - resizeMethod: React.PropTypes.string, + member: PropTypes.object.isRequired, + width: PropTypes.number, + height: PropTypes.number, + resizeMethod: PropTypes.string, }, getDefaultProps: function() { diff --git a/src/components/views/avatars/RoomAvatar.js b/src/components/views/avatars/RoomAvatar.js index 11554b2379..cae02ac408 100644 --- a/src/components/views/avatars/RoomAvatar.js +++ b/src/components/views/avatars/RoomAvatar.js @@ -14,6 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ import React from "react"; +import PropTypes from 'prop-types'; import {ContentRepo} from "matrix-js-sdk"; import MatrixClientPeg from "../../../MatrixClientPeg"; import sdk from "../../../index"; @@ -25,11 +26,11 @@ module.exports = React.createClass({ // oobData.avatarUrl should be set (else there // would be nowhere to get the avatar from) propTypes: { - room: React.PropTypes.object, - oobData: React.PropTypes.object, - width: React.PropTypes.number, - height: React.PropTypes.number, - resizeMethod: React.PropTypes.string, + room: PropTypes.object, + oobData: PropTypes.object, + width: PropTypes.number, + height: PropTypes.number, + resizeMethod: PropTypes.string, }, getDefaultProps: function() { diff --git a/src/components/views/create_room/CreateRoomButton.js b/src/components/views/create_room/CreateRoomButton.js index 8a5f00d942..25f71f542d 100644 --- a/src/components/views/create_room/CreateRoomButton.js +++ b/src/components/views/create_room/CreateRoomButton.js @@ -17,11 +17,12 @@ limitations under the License. 'use strict'; import React from 'react'; +import PropTypes from 'prop-types'; import { _t } from '../../../languageHandler'; module.exports = React.createClass({ displayName: 'CreateRoomButton', propTypes: { - onCreateRoom: React.PropTypes.func, + onCreateRoom: PropTypes.func, }, getDefaultProps: function() { diff --git a/src/components/views/create_room/Presets.js b/src/components/views/create_room/Presets.js index 2073896d87..c9607c0082 100644 --- a/src/components/views/create_room/Presets.js +++ b/src/components/views/create_room/Presets.js @@ -17,6 +17,7 @@ limitations under the License. 'use strict'; const React = require('react'); +import PropTypes from 'prop-types'; import { _t } from '../../../languageHandler'; const Presets = { @@ -28,8 +29,8 @@ const Presets = { module.exports = React.createClass({ displayName: 'CreateRoomPresets', propTypes: { - onChange: React.PropTypes.func, - preset: React.PropTypes.string, + onChange: PropTypes.func, + preset: PropTypes.string, }, Presets: Presets, diff --git a/src/components/views/create_room/RoomAlias.js b/src/components/views/create_room/RoomAlias.js index d4228a8bca..6262db7833 100644 --- a/src/components/views/create_room/RoomAlias.js +++ b/src/components/views/create_room/RoomAlias.js @@ -15,6 +15,7 @@ limitations under the License. */ const React = require('react'); +import PropTypes from 'prop-types'; import { _t } from '../../../languageHandler'; module.exports = React.createClass({ @@ -22,9 +23,9 @@ module.exports = React.createClass({ propTypes: { // Specifying a homeserver will make magical things happen when you, // e.g. start typing in the room alias box. - homeserver: React.PropTypes.string, - alias: React.PropTypes.string, - onChange: React.PropTypes.func, + homeserver: PropTypes.string, + alias: PropTypes.string, + onChange: PropTypes.func, }, getDefaultProps: function() { diff --git a/src/components/views/dialogs/BaseDialog.js b/src/components/views/dialogs/BaseDialog.js index b88a6c026e..518d29aa8c 100644 --- a/src/components/views/dialogs/BaseDialog.js +++ b/src/components/views/dialogs/BaseDialog.js @@ -15,6 +15,7 @@ limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import { KeyCode } from '../../../Keyboard'; import AccessibleButton from '../elements/AccessibleButton'; @@ -31,20 +32,20 @@ export default React.createClass({ propTypes: { // onFinished callback to call when Escape is pressed - onFinished: React.PropTypes.func.isRequired, + onFinished: PropTypes.func.isRequired, // callback to call when Enter is pressed - onEnterPressed: React.PropTypes.func, + onEnterPressed: PropTypes.func, // CSS class to apply to dialog div - className: React.PropTypes.string, + className: PropTypes.string, // Title for the dialog. // (could probably actually be something more complicated than a string if desired) - title: React.PropTypes.string.isRequired, + title: PropTypes.string.isRequired, // children should be the content of the dialog - children: React.PropTypes.node, + children: PropTypes.node, }, _onKeyDown: function(e) { diff --git a/src/components/views/dialogs/ChatCreateOrReuseDialog.js b/src/components/views/dialogs/ChatCreateOrReuseDialog.js index e0578f3b53..ef21db7ecb 100644 --- a/src/components/views/dialogs/ChatCreateOrReuseDialog.js +++ b/src/components/views/dialogs/ChatCreateOrReuseDialog.js @@ -15,6 +15,7 @@ limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import sdk from '../../../index'; import { _t } from '../../../languageHandler'; import MatrixClientPeg from '../../../MatrixClientPeg'; @@ -187,9 +188,9 @@ export default class ChatCreateOrReuseDialog extends React.Component { } ChatCreateOrReuseDialog.propTyps = { - userId: React.PropTypes.string.isRequired, + userId: PropTypes.string.isRequired, // Called when clicking outside of the dialog - onFinished: React.PropTypes.func.isRequired, - onNewDMClick: React.PropTypes.func.isRequired, - onExistingRoomSelected: React.PropTypes.func.isRequired, + onFinished: PropTypes.func.isRequired, + onNewDMClick: PropTypes.func.isRequired, + onExistingRoomSelected: PropTypes.func.isRequired, }; diff --git a/src/components/views/dialogs/ConfirmUserActionDialog.js b/src/components/views/dialogs/ConfirmUserActionDialog.js index 78d084b709..39e1f66f96 100644 --- a/src/components/views/dialogs/ConfirmUserActionDialog.js +++ b/src/components/views/dialogs/ConfirmUserActionDialog.js @@ -15,6 +15,7 @@ limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import { MatrixClient } from 'matrix-js-sdk'; import sdk from '../../../index'; import { _t } from '../../../languageHandler'; @@ -33,20 +34,20 @@ export default React.createClass({ displayName: 'ConfirmUserActionDialog', propTypes: { // matrix-js-sdk (room) member object. Supply either this or 'groupMember' - member: React.PropTypes.object, + member: PropTypes.object, // group member object. Supply either this or 'member' groupMember: GroupMemberType, // needed if a group member is specified - matrixClient: React.PropTypes.instanceOf(MatrixClient), - action: React.PropTypes.string.isRequired, // eg. 'Ban' - title: React.PropTypes.string.isRequired, // eg. 'Ban this user?' + matrixClient: PropTypes.instanceOf(MatrixClient), + action: PropTypes.string.isRequired, // eg. 'Ban' + title: PropTypes.string.isRequired, // eg. 'Ban this user?' // Whether to display a text field for a reason // If true, the second argument to onFinished will // be the string entered. - askReason: React.PropTypes.bool, - danger: React.PropTypes.bool, - onFinished: React.PropTypes.func.isRequired, + askReason: PropTypes.bool, + danger: PropTypes.bool, + onFinished: PropTypes.func.isRequired, }, defaultProps: { diff --git a/src/components/views/dialogs/CreateRoomDialog.js b/src/components/views/dialogs/CreateRoomDialog.js index f7be47b3eb..366c5ac678 100644 --- a/src/components/views/dialogs/CreateRoomDialog.js +++ b/src/components/views/dialogs/CreateRoomDialog.js @@ -15,6 +15,7 @@ limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import sdk from '../../../index'; import SdkConfig from '../../../SdkConfig'; import { _t } from '../../../languageHandler'; @@ -22,7 +23,7 @@ import { _t } from '../../../languageHandler'; export default React.createClass({ displayName: 'CreateRoomDialog', propTypes: { - onFinished: React.PropTypes.func.isRequired, + onFinished: PropTypes.func.isRequired, }, componentDidMount: function() { diff --git a/src/components/views/dialogs/DeactivateAccountDialog.js b/src/components/views/dialogs/DeactivateAccountDialog.js index c45e072d72..7d850fce2b 100644 --- a/src/components/views/dialogs/DeactivateAccountDialog.js +++ b/src/components/views/dialogs/DeactivateAccountDialog.js @@ -15,6 +15,7 @@ limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import sdk from '../../../index'; import Analytics from '../../../Analytics'; @@ -136,5 +137,5 @@ export default class DeactivateAccountDialog extends React.Component { } DeactivateAccountDialog.propTypes = { - onFinished: React.PropTypes.func.isRequired, + onFinished: PropTypes.func.isRequired, }; diff --git a/src/components/views/dialogs/DeviceVerifyDialog.js b/src/components/views/dialogs/DeviceVerifyDialog.js index ba31d2a8c2..6bec933389 100644 --- a/src/components/views/dialogs/DeviceVerifyDialog.js +++ b/src/components/views/dialogs/DeviceVerifyDialog.js @@ -16,6 +16,7 @@ limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import MatrixClientPeg from '../../../MatrixClientPeg'; import sdk from '../../../index'; import * as FormattingUtils from '../../../utils/FormattingUtils'; @@ -71,7 +72,7 @@ export default function DeviceVerifyDialog(props) { } DeviceVerifyDialog.propTypes = { - userId: React.PropTypes.string.isRequired, - device: React.PropTypes.object.isRequired, - onFinished: React.PropTypes.func.isRequired, + userId: PropTypes.string.isRequired, + device: PropTypes.object.isRequired, + onFinished: PropTypes.func.isRequired, }; diff --git a/src/components/views/dialogs/ErrorDialog.js b/src/components/views/dialogs/ErrorDialog.js index 97ed47e10f..2af2d6214f 100644 --- a/src/components/views/dialogs/ErrorDialog.js +++ b/src/components/views/dialogs/ErrorDialog.js @@ -26,20 +26,21 @@ limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import sdk from '../../../index'; import { _t } from '../../../languageHandler'; export default React.createClass({ displayName: 'ErrorDialog', propTypes: { - title: React.PropTypes.string, - description: React.PropTypes.oneOfType([ - React.PropTypes.element, - React.PropTypes.string, + title: PropTypes.string, + description: PropTypes.oneOfType([ + PropTypes.element, + PropTypes.string, ]), - button: React.PropTypes.string, - focus: React.PropTypes.bool, - onFinished: React.PropTypes.func.isRequired, + button: PropTypes.string, + focus: PropTypes.bool, + onFinished: PropTypes.func.isRequired, }, getDefaultProps: function() { diff --git a/src/components/views/dialogs/InteractiveAuthDialog.js b/src/components/views/dialogs/InteractiveAuthDialog.js index 59de7c7f59..a47702305c 100644 --- a/src/components/views/dialogs/InteractiveAuthDialog.js +++ b/src/components/views/dialogs/InteractiveAuthDialog.js @@ -16,6 +16,7 @@ limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import sdk from '../../../index'; import { _t } from '../../../languageHandler'; @@ -27,22 +28,22 @@ export default React.createClass({ propTypes: { // matrix client to use for UI auth requests - matrixClient: React.PropTypes.object.isRequired, + matrixClient: PropTypes.object.isRequired, // response from initial request. If not supplied, will do a request on // mount. - authData: React.PropTypes.shape({ - flows: React.PropTypes.array, - params: React.PropTypes.object, - session: React.PropTypes.string, + authData: PropTypes.shape({ + flows: PropTypes.array, + params: PropTypes.object, + session: PropTypes.string, }), // callback - makeRequest: React.PropTypes.func.isRequired, + makeRequest: PropTypes.func.isRequired, - onFinished: React.PropTypes.func.isRequired, + onFinished: PropTypes.func.isRequired, - title: React.PropTypes.string, + title: PropTypes.string, }, getInitialState: function() { diff --git a/src/components/views/dialogs/KeyShareDialog.js b/src/components/views/dialogs/KeyShareDialog.js index 9c8be27c89..00bcc942a1 100644 --- a/src/components/views/dialogs/KeyShareDialog.js +++ b/src/components/views/dialogs/KeyShareDialog.js @@ -16,6 +16,7 @@ limitations under the License. import Modal from '../../../Modal'; import React from 'react'; +import PropTypes from 'prop-types'; import sdk from '../../../index'; import { _t, _td } from '../../../languageHandler'; @@ -30,10 +31,10 @@ import { _t, _td } from '../../../languageHandler'; */ export default React.createClass({ propTypes: { - matrixClient: React.PropTypes.object.isRequired, - userId: React.PropTypes.string.isRequired, - deviceId: React.PropTypes.string.isRequired, - onFinished: React.PropTypes.func.isRequired, + matrixClient: PropTypes.object.isRequired, + userId: PropTypes.string.isRequired, + deviceId: PropTypes.string.isRequired, + onFinished: PropTypes.func.isRequired, }, getInitialState: function() { diff --git a/src/components/views/dialogs/QuestionDialog.js b/src/components/views/dialogs/QuestionDialog.js index 339b284e2f..719f372cfe 100644 --- a/src/components/views/dialogs/QuestionDialog.js +++ b/src/components/views/dialogs/QuestionDialog.js @@ -16,6 +16,7 @@ limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import sdk from '../../../index'; import { _t } from '../../../languageHandler'; import classnames from 'classnames'; @@ -23,13 +24,13 @@ import classnames from 'classnames'; export default React.createClass({ displayName: 'QuestionDialog', propTypes: { - title: React.PropTypes.string, - description: React.PropTypes.node, - extraButtons: React.PropTypes.node, - button: React.PropTypes.string, - danger: React.PropTypes.bool, - focus: React.PropTypes.bool, - onFinished: React.PropTypes.func.isRequired, + title: PropTypes.string, + description: PropTypes.node, + extraButtons: PropTypes.node, + button: PropTypes.string, + danger: PropTypes.bool, + focus: PropTypes.bool, + onFinished: PropTypes.func.isRequired, }, getDefaultProps: function() { diff --git a/src/components/views/dialogs/SessionRestoreErrorDialog.js b/src/components/views/dialogs/SessionRestoreErrorDialog.js index 75ae0eda17..63b9c64530 100644 --- a/src/components/views/dialogs/SessionRestoreErrorDialog.js +++ b/src/components/views/dialogs/SessionRestoreErrorDialog.js @@ -15,6 +15,7 @@ limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import sdk from '../../../index'; import SdkConfig from '../../../SdkConfig'; import Modal from '../../../Modal'; @@ -25,8 +26,8 @@ export default React.createClass({ displayName: 'SessionRestoreErrorDialog', propTypes: { - error: React.PropTypes.string.isRequired, - onFinished: React.PropTypes.func.isRequired, + error: PropTypes.string.isRequired, + onFinished: PropTypes.func.isRequired, }, _sendBugReport: function() { diff --git a/src/components/views/dialogs/SetEmailDialog.js b/src/components/views/dialogs/SetEmailDialog.js index 2dd996953d..c00cc1122b 100644 --- a/src/components/views/dialogs/SetEmailDialog.js +++ b/src/components/views/dialogs/SetEmailDialog.js @@ -15,6 +15,7 @@ limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import sdk from '../../../index'; import Email from '../../../email'; import AddThreepid from '../../../AddThreepid'; @@ -30,7 +31,7 @@ import Modal from '../../../Modal'; export default React.createClass({ displayName: 'SetEmailDialog', propTypes: { - onFinished: React.PropTypes.func.isRequired, + onFinished: PropTypes.func.isRequired, }, getInitialState: function() { diff --git a/src/components/views/dialogs/SetMxIdDialog.js b/src/components/views/dialogs/SetMxIdDialog.js index 3ffafb0659..6ebc2eb87f 100644 --- a/src/components/views/dialogs/SetMxIdDialog.js +++ b/src/components/views/dialogs/SetMxIdDialog.js @@ -17,6 +17,7 @@ limitations under the License. import Promise from 'bluebird'; import React from 'react'; +import PropTypes from 'prop-types'; import sdk from '../../../index'; import MatrixClientPeg from '../../../MatrixClientPeg'; import classnames from 'classnames'; @@ -35,11 +36,11 @@ const USERNAME_CHECK_DEBOUNCE_MS = 250; export default React.createClass({ displayName: 'SetMxIdDialog', propTypes: { - onFinished: React.PropTypes.func.isRequired, + onFinished: PropTypes.func.isRequired, // Called when the user requests to register with a different homeserver - onDifferentServerClicked: React.PropTypes.func.isRequired, + onDifferentServerClicked: PropTypes.func.isRequired, // Called if the user wants to switch to login instead - onLoginClick: React.PropTypes.func.isRequired, + onLoginClick: PropTypes.func.isRequired, }, getInitialState: function() { diff --git a/src/components/views/dialogs/TextInputDialog.js b/src/components/views/dialogs/TextInputDialog.js index 5ea4191e5e..d45e70c043 100644 --- a/src/components/views/dialogs/TextInputDialog.js +++ b/src/components/views/dialogs/TextInputDialog.js @@ -15,21 +15,22 @@ limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import sdk from '../../../index'; import { _t } from '../../../languageHandler'; export default React.createClass({ displayName: 'TextInputDialog', propTypes: { - title: React.PropTypes.string, - description: React.PropTypes.oneOfType([ - React.PropTypes.element, - React.PropTypes.string, + title: PropTypes.string, + description: PropTypes.oneOfType([ + PropTypes.element, + PropTypes.string, ]), - value: React.PropTypes.string, - button: React.PropTypes.string, - focus: React.PropTypes.bool, - onFinished: React.PropTypes.func.isRequired, + value: PropTypes.string, + button: PropTypes.string, + focus: PropTypes.bool, + onFinished: PropTypes.func.isRequired, }, getDefaultProps: function() { diff --git a/src/components/views/elements/AccessibleButton.js b/src/components/views/elements/AccessibleButton.js index 794e0a4dd7..c6a973270a 100644 --- a/src/components/views/elements/AccessibleButton.js +++ b/src/components/views/elements/AccessibleButton.js @@ -15,6 +15,7 @@ */ import React from 'react'; +import PropTypes from 'prop-types'; /** * AccessibleButton is a generic wrapper for any element that should be treated @@ -44,9 +45,9 @@ export default function AccessibleButton(props) { * implemented exactly like a normal onClick handler. */ AccessibleButton.propTypes = { - children: React.PropTypes.node, - element: React.PropTypes.string, - onClick: React.PropTypes.func.isRequired, + children: PropTypes.node, + element: PropTypes.string, + onClick: PropTypes.func.isRequired, }; AccessibleButton.defaultProps = { diff --git a/src/components/views/elements/AddressSelector.js b/src/components/views/elements/AddressSelector.js index 9330206a39..b4279c7f70 100644 --- a/src/components/views/elements/AddressSelector.js +++ b/src/components/views/elements/AddressSelector.js @@ -18,6 +18,7 @@ limitations under the License. 'use strict'; import React from 'react'; +import PropTypes from 'prop-types'; import sdk from '../../../index'; import classNames from 'classnames'; import { UserAddressType } from '../../../UserAddress'; @@ -26,17 +27,17 @@ export default React.createClass({ displayName: 'AddressSelector', propTypes: { - onSelected: React.PropTypes.func.isRequired, + onSelected: PropTypes.func.isRequired, // List of the addresses to display - addressList: React.PropTypes.arrayOf(UserAddressType).isRequired, + addressList: PropTypes.arrayOf(UserAddressType).isRequired, // Whether to show the address on the address tiles - showAddress: React.PropTypes.bool, - truncateAt: React.PropTypes.number.isRequired, - selected: React.PropTypes.number, + showAddress: PropTypes.bool, + truncateAt: PropTypes.number.isRequired, + selected: PropTypes.number, // Element to put as a header on top of the list - header: React.PropTypes.node, + header: PropTypes.node, }, getInitialState: function() { diff --git a/src/components/views/elements/AddressTile.js b/src/components/views/elements/AddressTile.js index c8ea4062b1..16e340756a 100644 --- a/src/components/views/elements/AddressTile.js +++ b/src/components/views/elements/AddressTile.js @@ -16,6 +16,7 @@ limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import classNames from 'classnames'; import sdk from "../../../index"; import MatrixClientPeg from "../../../MatrixClientPeg"; @@ -28,9 +29,9 @@ export default React.createClass({ propTypes: { address: UserAddressType.isRequired, - canDismiss: React.PropTypes.bool, - onDismissed: React.PropTypes.func, - justified: React.PropTypes.bool, + canDismiss: PropTypes.bool, + onDismissed: PropTypes.func, + justified: PropTypes.bool, }, getDefaultProps: function() { diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 0d67b4c814..a63823555f 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -19,6 +19,7 @@ limitations under the License. import url from 'url'; import qs from 'querystring'; import React from 'react'; +import PropTypes from 'prop-types'; import MatrixClientPeg from '../../../MatrixClientPeg'; import PlatformPeg from '../../../PlatformPeg'; import ScalarAuthClient from '../../../ScalarAuthClient'; @@ -40,19 +41,19 @@ export default React.createClass({ displayName: 'AppTile', propTypes: { - id: React.PropTypes.string.isRequired, - url: React.PropTypes.string.isRequired, - name: React.PropTypes.string.isRequired, - room: React.PropTypes.object.isRequired, - type: React.PropTypes.string.isRequired, + id: PropTypes.string.isRequired, + url: PropTypes.string.isRequired, + name: PropTypes.string.isRequired, + room: PropTypes.object.isRequired, + type: PropTypes.string.isRequired, // Specifying 'fullWidth' as true will render the app tile to fill the width of the app drawer continer. // This should be set to true when there is only one widget in the app drawer, otherwise it should be false. - fullWidth: React.PropTypes.bool, + fullWidth: PropTypes.bool, // UserId of the current user - userId: React.PropTypes.string.isRequired, + userId: PropTypes.string.isRequired, // UserId of the entity that added / modified the widget - creatorUserId: React.PropTypes.string, - waitForIframeLoad: React.PropTypes.bool, + creatorUserId: PropTypes.string, + waitForIframeLoad: PropTypes.bool, }, getDefaultProps() { diff --git a/src/components/views/elements/DeviceVerifyButtons.js b/src/components/views/elements/DeviceVerifyButtons.js index bb89efaa30..c775cba610 100644 --- a/src/components/views/elements/DeviceVerifyButtons.js +++ b/src/components/views/elements/DeviceVerifyButtons.js @@ -15,6 +15,7 @@ limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import MatrixClientPeg from '../../../MatrixClientPeg'; import sdk from '../../../index'; import Modal from '../../../Modal'; @@ -24,8 +25,8 @@ export default React.createClass({ displayName: 'DeviceVerifyButtons', propTypes: { - userId: React.PropTypes.string.isRequired, - device: React.PropTypes.object.isRequired, + userId: PropTypes.string.isRequired, + device: PropTypes.object.isRequired, }, getInitialState: function() { diff --git a/src/components/views/elements/DirectorySearchBox.js b/src/components/views/elements/DirectorySearchBox.js index 7132162d5c..14f79687e1 100644 --- a/src/components/views/elements/DirectorySearchBox.js +++ b/src/components/views/elements/DirectorySearchBox.js @@ -15,6 +15,7 @@ limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import classnames from 'classnames'; export default class DirectorySearchBox extends React.Component { @@ -105,10 +106,10 @@ export default class DirectorySearchBox extends React.Component { } DirectorySearchBox.propTypes = { - className: React.PropTypes.string, - onChange: React.PropTypes.func, - onClear: React.PropTypes.func, - onJoinClick: React.PropTypes.func, - placeholder: React.PropTypes.string, - showJoinButton: React.PropTypes.bool, + className: PropTypes.string, + onChange: PropTypes.func, + onClear: PropTypes.func, + onJoinClick: PropTypes.func, + placeholder: PropTypes.string, + showJoinButton: PropTypes.bool, }; diff --git a/src/components/views/elements/Dropdown.js b/src/components/views/elements/Dropdown.js index b1291710b7..10111e415e 100644 --- a/src/components/views/elements/Dropdown.js +++ b/src/components/views/elements/Dropdown.js @@ -15,6 +15,7 @@ limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import classnames from 'classnames'; import AccessibleButton from './AccessibleButton'; import { _t } from '../../../languageHandler'; @@ -56,14 +57,14 @@ class MenuOption extends React.Component { } MenuOption.propTypes = { - children: React.PropTypes.oneOfType([ - React.PropTypes.arrayOf(React.PropTypes.node), - React.PropTypes.node, + children: PropTypes.oneOfType([ + PropTypes.arrayOf(React.PropTypes.node), + PropTypes.node, ]), - highlighted: React.PropTypes.bool, - dropdownKey: React.PropTypes.string, - onClick: React.PropTypes.func.isRequired, - onMouseEnter: React.PropTypes.func.isRequired, + highlighted: PropTypes.bool, + dropdownKey: PropTypes.string, + onClick: PropTypes.func.isRequired, + onMouseEnter: PropTypes.func.isRequired, }; /* @@ -322,20 +323,20 @@ Dropdown.propTypes = { // The width that the dropdown should be. If specified, // the dropped-down part of the menu will be set to this // width. - menuWidth: React.PropTypes.number, + menuWidth: PropTypes.number, // Called when the selected option changes - onOptionChange: React.PropTypes.func.isRequired, + onOptionChange: PropTypes.func.isRequired, // Called when the value of the search field changes - onSearchChange: React.PropTypes.func, - searchEnabled: React.PropTypes.bool, + onSearchChange: PropTypes.func, + searchEnabled: PropTypes.bool, // Function that, given the key of an option, returns // a node representing that option to be displayed in the // box itself as the currently-selected option (ie. as // opposed to in the actual dropped-down part). If // unspecified, the appropriate child element is used as // in the dropped-down menu. - getShortOption: React.PropTypes.func, - value: React.PropTypes.string, + getShortOption: PropTypes.func, + value: PropTypes.string, // negative for consistency with HTML - disabled: React.PropTypes.bool, + disabled: PropTypes.bool, }; diff --git a/src/components/views/elements/EditableText.js b/src/components/views/elements/EditableText.js index ac8821a0c2..ce1817c272 100644 --- a/src/components/views/elements/EditableText.js +++ b/src/components/views/elements/EditableText.js @@ -17,6 +17,7 @@ limitations under the License. 'use strict'; const React = require('react'); +import PropTypes from 'prop-types'; const KEY_TAB = 9; const KEY_SHIFT = 16; @@ -26,18 +27,18 @@ module.exports = React.createClass({ displayName: 'EditableText', propTypes: { - onValueChanged: React.PropTypes.func, - initialValue: React.PropTypes.string, - label: React.PropTypes.string, - placeholder: React.PropTypes.string, - className: React.PropTypes.string, - labelClassName: React.PropTypes.string, - placeholderClassName: React.PropTypes.string, + onValueChanged: PropTypes.func, + initialValue: PropTypes.string, + label: PropTypes.string, + placeholder: PropTypes.string, + className: PropTypes.string, + labelClassName: PropTypes.string, + placeholderClassName: PropTypes.string, // Overrides blurToSubmit if true - blurToCancel: React.PropTypes.bool, + blurToCancel: PropTypes.bool, // Will cause onValueChanged(value, true) to fire on blur - blurToSubmit: React.PropTypes.bool, - editable: React.PropTypes.bool, + blurToSubmit: PropTypes.bool, + editable: PropTypes.bool, }, Phases: { diff --git a/src/components/views/elements/EditableTextContainer.js b/src/components/views/elements/EditableTextContainer.js index 0025862967..064d2f1c39 100644 --- a/src/components/views/elements/EditableTextContainer.js +++ b/src/components/views/elements/EditableTextContainer.js @@ -15,6 +15,7 @@ limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import sdk from '../../../index'; import Promise from 'bluebird'; @@ -126,21 +127,21 @@ export default class EditableTextContainer extends React.Component { EditableTextContainer.propTypes = { /* callback to retrieve the initial value. */ - getInitialValue: React.PropTypes.func, + getInitialValue: PropTypes.func, /* initial value; used if getInitialValue is not given */ - initialValue: React.PropTypes.string, + initialValue: PropTypes.string, /* placeholder text to use when the value is empty (and not being * edited) */ - placeholder: React.PropTypes.string, + placeholder: PropTypes.string, /* callback to update the value. Called with a single argument: the new * value. */ - onSubmit: React.PropTypes.func, + onSubmit: PropTypes.func, /* should the input submit when focus is lost? */ - blurToSubmit: React.PropTypes.bool, + blurToSubmit: PropTypes.bool, }; diff --git a/src/components/views/elements/EmojiText.js b/src/components/views/elements/EmojiText.js index faab0241ae..9fb650b2c3 100644 --- a/src/components/views/elements/EmojiText.js +++ b/src/components/views/elements/EmojiText.js @@ -16,6 +16,7 @@ */ import React from 'react'; +import PropTypes from 'prop-types'; import {emojifyText, containsEmoji} from '../../../HtmlUtils'; export default function EmojiText(props) { @@ -32,8 +33,8 @@ export default function EmojiText(props) { } EmojiText.propTypes = { - element: React.PropTypes.string, - children: React.PropTypes.string.isRequired, + element: PropTypes.string, + children: PropTypes.string.isRequired, }; EmojiText.defaultProps = { diff --git a/src/components/views/elements/Flair.js b/src/components/views/elements/Flair.js index 25a8d538e1..a487395a87 100644 --- a/src/components/views/elements/Flair.js +++ b/src/components/views/elements/Flair.js @@ -63,7 +63,7 @@ FlairAvatar.propTypes = { }; FlairAvatar.contextTypes = { - matrixClient: React.PropTypes.instanceOf(MatrixClient).isRequired, + matrixClient: PropTypes.instanceOf(MatrixClient).isRequired, }; export default class Flair extends React.Component { @@ -134,5 +134,5 @@ Flair.propTypes = { // this.context.matrixClient everywhere instead of this.props.matrixClient. // See https://github.com/vector-im/riot-web/issues/4951. Flair.contextTypes = { - matrixClient: React.PropTypes.instanceOf(MatrixClient).isRequired, + matrixClient: PropTypes.instanceOf(MatrixClient).isRequired, }; diff --git a/src/components/views/elements/LanguageDropdown.js b/src/components/views/elements/LanguageDropdown.js index 6c86296a38..365f9ded61 100644 --- a/src/components/views/elements/LanguageDropdown.js +++ b/src/components/views/elements/LanguageDropdown.js @@ -16,6 +16,7 @@ limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import sdk from '../../../index'; import * as languageHandler from '../../../languageHandler'; @@ -114,7 +115,7 @@ export default class LanguageDropdown extends React.Component { } LanguageDropdown.propTypes = { - className: React.PropTypes.string, - onOptionChange: React.PropTypes.func.isRequired, - value: React.PropTypes.string, + className: PropTypes.string, + onOptionChange: PropTypes.func.isRequired, + value: PropTypes.string, }; diff --git a/src/components/views/elements/MemberEventListSummary.js b/src/components/views/elements/MemberEventListSummary.js index e2368a2fe3..3c58f90a2b 100644 --- a/src/components/views/elements/MemberEventListSummary.js +++ b/src/components/views/elements/MemberEventListSummary.js @@ -14,6 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import sdk from '../../../index'; const MemberAvatar = require('../avatars/MemberAvatar.js'); import { _t } from '../../../languageHandler'; @@ -23,19 +24,19 @@ module.exports = React.createClass({ propTypes: { // An array of member events to summarise - events: React.PropTypes.array.isRequired, + events: PropTypes.array.isRequired, // An array of EventTiles to render when expanded - children: React.PropTypes.array.isRequired, + children: PropTypes.array.isRequired, // The maximum number of names to show in either each summary e.g. 2 would result "A, B and 234 others left" - summaryLength: React.PropTypes.number, + summaryLength: PropTypes.number, // The maximum number of avatars to display in the summary - avatarsMaxLength: React.PropTypes.number, + avatarsMaxLength: PropTypes.number, // The minimum number of events needed to trigger summarisation - threshold: React.PropTypes.number, + threshold: PropTypes.number, // Called when the MELS expansion is toggled - onToggle: React.PropTypes.func, + onToggle: PropTypes.func, // Whether or not to begin with state.expanded=true - startExpanded: React.PropTypes.bool, + startExpanded: PropTypes.bool, }, getInitialState: function() { diff --git a/src/components/views/elements/PowerSelector.js b/src/components/views/elements/PowerSelector.js index d5c167fac9..f8443c6ecd 100644 --- a/src/components/views/elements/PowerSelector.js +++ b/src/components/views/elements/PowerSelector.js @@ -17,6 +17,7 @@ limitations under the License. 'use strict'; import React from 'react'; +import PropTypes from 'prop-types'; import * as Roles from '../../../Roles'; import { _t } from '../../../languageHandler'; @@ -24,23 +25,23 @@ module.exports = React.createClass({ displayName: 'PowerSelector', propTypes: { - value: React.PropTypes.number.isRequired, + value: PropTypes.number.isRequired, // The maximum value that can be set with the power selector - maxValue: React.PropTypes.number.isRequired, + maxValue: PropTypes.number.isRequired, // Default user power level for the room - usersDefault: React.PropTypes.number.isRequired, + usersDefault: PropTypes.number.isRequired, // if true, the
+
+ +
+ { _t('Advanced options') } +
+ + +
+
Date: Thu, 8 Feb 2018 21:16:25 +0000 Subject: [PATCH 484/927] Translated using Weblate (Serbian) Currently translated at 100.0% (986 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sr/ --- src/i18n/strings/sr.json | 89 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 88 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/sr.json b/src/i18n/strings/sr.json index 9a38d6fac8..39a1f1cf20 100644 --- a/src/i18n/strings/sr.json +++ b/src/i18n/strings/sr.json @@ -898,5 +898,92 @@ "matrix-react-sdk version:": "matrix-react-sdk издање:", "riot-web version:": "riot-web издање:", "olm version:": "olm издање:", - "Failed to send email": "Нисам успео да пошаљем мејл" + "Failed to send email": "Нисам успео да пошаљем мејл", + "The email address linked to your account must be entered.": "Морате унети мејл адресу која је везана за ваш налог.", + "A new password must be entered.": "Морате унети нову лозинку.", + "New passwords must match each other.": "Нове лозинке се морају подударати.", + "Resetting password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Опоравак ваше лозинке ће тренутно поново поставити кључеве за шифровање с краја на крај, на свим вашим уређајима. Ово ће учинити шифровани историјат ћаскања нечитљивим осим ако прво не извезете ваше кључеве собе па их онда увезете касније. Ово ће бити побољшано у будућности.", + "An email has been sent to %(emailAddress)s. Once you've followed the link it contains, click below.": "Мејл је послат на адресу %(emailAddress)s. Када будете испратили везу у њему, кликните испод.", + "I have verified my email address": "Потврдио сам своју мејл адресу", + "Your password has been reset": "Ваша лозинка је опорављена", + "You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "Одјављени сте са свих ваших уређаја и више нећете примати пуш обавештења. Да бисте поново омогућили обавештења, одјавите се и пријавите поново на сваком вашем уређају", + "Return to login screen": "Врати ме на екран за пријаву", + "To reset your password, enter the email address linked to your account": "Да бисте опоравили вашу лозинку, унесите мејл адресу повезану са вашим налогом", + "New password": "Нова лозинка", + "Confirm your new password": "Потврдите вашу нову лозинку", + "Send Reset Email": "Пошаљи мејл за опоравак", + "Create an account": "Направи налог", + "This Home Server does not support login using email address.": "Овај кућни сервер не подржава пријављивање преко мејл адресе.", + "Incorrect username and/or password.": "Нетачно корисничко име и/или лозинка.", + "Please note you are logging into the %(hs)s server, not matrix.org.": "Знајте да се пријављујете на сервер %(hs)s, не на matrix.org.", + "Guest access is disabled on this Home Server.": "Гостински приступ је онемогућен на овом кућном серверу.", + "The phone number entered looks invalid": "Унети број телефона не изгледа исправно", + "This homeserver doesn't offer any login flows which are supported by this client.": "Овај кућни сервер не пружа било који начин пријаве унутар овог клијента.", + "Error: Problem communicating with the given homeserver.": "Грешка: проблем у комуницирању са датим кућним сервером.", + "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Не могу да се повежем на кућни сервер преко HTTP-а када се користи HTTPS адреса у траци вашег прегледача. Или користите HTTPS или омогућите небезбедне скрипте.", + "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "Не могу да се повежем на кућни сервер. Проверите вашу интернет везу, постарајте се да верујете SSL сертификату кућног сервера и да проширење прегледача не блокира захтеве.", + "Login as guest": "Пријави се као гост", + "Sign in to get started": "Пријави се да почнеш", + "Failed to fetch avatar URL": "Нисам успео да добавим адресу аватара", + "Set a display name:": "Постави приказно име:", + "Upload an avatar:": "Отпреми аватар:", + "This server does not support authentication with a phone number.": "Овај сервер не подржава идентификацију преко броја мобилног.", + "Missing password.": "Недостаје лозинка.", + "Passwords don't match.": "Лозинке се не подударају.", + "Password too short (min %(MIN_PASSWORD_LENGTH)s).": "Лозинка је сувише кратка (најмање %(MIN_PASSWORD_LENGTH)s).", + "This doesn't look like a valid email address.": "Мејл адреса не изгледа исправно.", + "This doesn't look like a valid phone number.": "Број телефона не изгледа исправно.", + "You need to enter a user name.": "Морате унети корисничко име.", + "An unknown error occurred.": "Непозната грешка се догодила.", + "I already have an account": "Већ имам налог", + "Displays action": "Приказује радњу", + "Bans user with given id": "Забрањује приступ кориснику са датим иб-јем", + "Unbans user with given id": "Скида забрану приступа кориснику са датим иб-јем", + "Define the power level of a user": "Дефинише ниво моћи корисника", + "Deops user with given id": "Укида админа за корисника са датим иб-јем", + "Invites user with given id to current room": "Позива корисника са датим иб-јем у тренутну собу", + "Joins room with given alias": "Приступа соби са датим алијасем", + "Sets the room topic": "Поставља тему собе", + "Kicks user with given id": "Избацује корисника са датим иб-јем", + "Changes your display nickname": "Мења ваш приказни надимак", + "Searches DuckDuckGo for results": "Претражује DuckDuckGo за резултате", + "Changes colour scheme of current room": "Мења шему боје у тренутној соби", + "Verifies a user, device, and pubkey tuple": "Проверава корисника, уређај и торку јавног кључа", + "Ignores a user, hiding their messages from you": "Занемарује корисника и тиме скрива њихове поруке од вас", + "Stops ignoring a user, showing their messages going forward": "Престаје са занемаривањем корисника и тиме приказује њихове поруке одсад", + "Commands": "Наредбе", + "Results from DuckDuckGo": "Резултати са DuckDuckGo-а", + "Emoji": "Емоџи", + "Notify the whole room": "Обавести све у соби", + "Room Notification": "Собно обавештење", + "Users": "Корисници", + "unknown device": "непознати уређај", + "NOT verified": "НИЈЕ проверен", + "verified": "проверен", + "Verification": "Провера", + "Ed25519 fingerprint": "Ed25519 отисак прста", + "User ID": "Кориснички ИБ", + "Curve25519 identity key": "Curve25519 идентитески кључ", + "none": "ништа", + "Claimed Ed25519 fingerprint key": "Наводни Ed25519 кључ отиска прста", + "Algorithm": "Алгоритам", + "unencrypted": "нешифрован", + "Decryption error": "Грешка дешифровања", + "Session ID": "ИБ сесије", + "End-to-end encryption information": "Подаци о шифровању с краја на крај", + "Event information": "Подаци о догађају", + "Sender device information": "Подаци о уређају пошиљаоца", + "Passphrases must match": "Фразе се морају подударати", + "Passphrase must not be empty": "Фразе не смеју бити празне", + "Export room keys": "Извези кључеве собе", + "This process allows you to export the keys for messages you have received in encrypted rooms to a local file. You will then be able to import the file into another Matrix client in the future, so that client will also be able to decrypt these messages.": "Ова радња вам омогућава да извезете кључеве за примљене поруке у шифрованим собама у локалну датотеку. Онда ћете моћи да увезете датотеку у други Матрикс клијент, у будућности, тако да ће тај клијент моћи да дешифрује ове поруке.", + "The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.": "Извезена датотека ће дозволити свима који је могу прочитати да дешифрују било које шифроване поруке које можете видети те бисте требали да будете пажљиви и да је осигурате. Да бисмо вам помогли са тиме, требало би да унесете фразу испод са којом ће извезени подаци бити шифровани. Поновни увоз података ће бити могућ само уз коришћење исте фразе.", + "Enter passphrase": "Унеси фразу", + "Confirm passphrase": "Потврди фразу", + "Export": "Извези", + "Import room keys": "Увези кључеве собе", + "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "Ова радња вам омогућава да увезете кључеве за шифровање које сте претходно извезли из другог Матрикс клијента. Након тога ћете моћи да дешифрујете било коју поруку коју је други клијент могао да дешифрује.", + "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "Извезена датотека ће бити заштићена са фразом. Требало би да унесете фразу овде, да бисте дешифровали датотеку.", + "File to import": "Датотека за увоз", + "Import": "Увези" } From 410570936a6e301b2eff5591f99bf75a6f838337 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Thu, 8 Feb 2018 22:51:07 +0100 Subject: [PATCH 485/927] Reimplement setting aria-hidden on the main app node by dispatching actions rather than assuming we can find and manipulate the node directly --- src/Modal.js | 25 +++++++++++------------ src/components/structures/LoggedInView.js | 2 +- src/components/structures/MatrixChat.js | 14 +++++++++++++ 3 files changed, 27 insertions(+), 14 deletions(-) diff --git a/src/Modal.js b/src/Modal.js index 8e3b394f87..2565d5c73b 100644 --- a/src/Modal.js +++ b/src/Modal.js @@ -22,6 +22,7 @@ const ReactDOM = require('react-dom'); import PropTypes from 'prop-types'; import Analytics from './Analytics'; import sdk from './index'; +import dis from './dispatcher'; const DIALOG_CONTAINER_ID = "mx_Dialog_Container"; @@ -187,24 +188,22 @@ class ModalManager { } _reRender() { - // Retrieve the root node of the Riot application outside the modal - let applicationNode = document.getElementById('matrixchat'); if (this._modals.length == 0) { - if (applicationNode) { - // If there is no modal to render, make all of Riot available - // to screen reader users again - applicationNode.setAttribute('aria-hidden', 'false'); - } + // If there is no modal to render, make all of Riot available + // to screen reader users again + dis.dispatch({ + action: 'aria_unhide_main_app', + }); ReactDOM.unmountComponentAtNode(this.getOrCreateContainer()); return; } - if (applicationNode) { - // Hide the content outside the modal to screen reader users - // so they won't be able to navigate into it and act on it using - // screen reader specific features - applicationNode.setAttribute('aria-hidden', 'true'); - } + // Hide the content outside the modal to screen reader users + // so they won't be able to navigate into it and act on it using + // screen reader specific features + dis.dispatch({ + action: 'aria_hide_main_app', + }); const modal = this._modals[0]; const dialog = ( diff --git a/src/components/structures/LoggedInView.js b/src/components/structures/LoggedInView.js index e97d9dd0a1..211340f5a8 100644 --- a/src/components/structures/LoggedInView.js +++ b/src/components/structures/LoggedInView.js @@ -327,7 +327,7 @@ const LoggedInView = React.createClass({ } return ( -
+
{ topBar }
{ SettingsStore.isFeatureEnabled("feature_tag_panel") ? :
} diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index d6d0b00c84..380cc697e1 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -171,6 +171,10 @@ export default React.createClass({ register_hs_url: null, register_is_url: null, register_id_sid: null, + + // When showing Modal dialogs we need to set aria-hidden on the root app element + // and disable it when there are no dialogs + hideToSRUsers: false, }; return s; }, @@ -608,6 +612,16 @@ export default React.createClass({ case 'send_event': this.onSendEvent(payload.room_id, payload.event); break; + case 'aria_hide_main_app': + this.setState({ + hideToSRUsers: true, + }); + break; + case 'aria_unhide_main_app': + this.setState({ + hideToSRUsers: false, + }); + break; } }, From cf0d45a65bd0082bc3ce0b9890b61a08a78bfa68 Mon Sep 17 00:00:00 2001 From: Osoitz Date: Fri, 9 Feb 2018 10:28:32 +0000 Subject: [PATCH 486/927] Translated using Weblate (Basque) Currently translated at 100.0% (986 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eu/ --- src/i18n/strings/eu.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/eu.json b/src/i18n/strings/eu.json index 8ec181d879..7592eb0708 100644 --- a/src/i18n/strings/eu.json +++ b/src/i18n/strings/eu.json @@ -980,5 +980,9 @@ "This room is not public. You will not be able to rejoin without an invite.": "Gela hau ez da publikoa. Ezin izango zara berriro elkartu gonbidapenik gabe.", "Community IDs cannot not be empty.": "Komunitate ID-ak ezin dira hutsik egon.", "Show devices, send anyway or cancel.": "Erakutsi gailuak, bidali hala ere edo ezeztatu.", - "In reply to ": "honi erantzunez: " + "In reply to ": "honi erantzunez: ", + "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s erabiltzaileak bere pantaila izena aldatu du %(displayName)s izatera.", + "Failed to set direct chat tag": "Huts egin du txat zuzenarenaren etiketa jartzean", + "Failed to remove tag %(tagName)s from room": "Huts egin du %(tagName)s etiketa gelatik kentzean", + "Failed to add tag %(tagName)s to room": "Huts egin du %(tagName)s etiketa gelara gehitzean" } From 9e3c1fbc7ac6a7e1da09e9a82406497ec388d2af Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Fri, 9 Feb 2018 11:44:27 +0000 Subject: [PATCH 487/927] Pass room name. --- src/ScalarAuthClient.js | 5 ++++- src/components/views/elements/AppTile.js | 2 +- src/components/views/elements/ManageIntegsButton.js | 4 ++-- src/components/views/rooms/AppsDrawer.js | 2 +- src/components/views/rooms/RoomHeader.js | 2 +- src/components/views/rooms/Stickerpack.js | 2 +- 6 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/ScalarAuthClient.js b/src/ScalarAuthClient.js index 3e775a94ab..756965d41e 100644 --- a/src/ScalarAuthClient.js +++ b/src/ScalarAuthClient.js @@ -105,10 +105,13 @@ class ScalarAuthClient { return defer.promise; } - getScalarInterfaceUrlForRoom(roomId, screen, id) { + getScalarInterfaceUrlForRoom(room, screen, id) { + const roomId = room.roomId; + const roomName = room.name; let url = SdkConfig.get().integrations_ui_url; url += "?scalar_token=" + encodeURIComponent(this.scalarToken); url += "&room_id=" + encodeURIComponent(roomId); + url += "&room_name=" + encodeURIComponent(roomName); if (id) { url += '&integ_id=' + encodeURIComponent(id); } diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 9d76e3410e..cc11a8542a 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -277,7 +277,7 @@ export default class AppTile extends React.Component { } else { const IntegrationsManager = sdk.getComponent("views.settings.IntegrationsManager"); const src = this._scalarClient.getScalarInterfaceUrlForRoom( - this.props.room.roomId, 'type_' + this.props.type, this.props.id); + this.props.room, 'type_' + this.props.type, this.props.id); Modal.createTrackedDialog('Integrations Manager', '', IntegrationsManager, { src: src, }, "mx_IntegrationsManager"); diff --git a/src/components/views/elements/ManageIntegsButton.js b/src/components/views/elements/ManageIntegsButton.js index 17dbbeee62..024c5feda5 100644 --- a/src/components/views/elements/ManageIntegsButton.js +++ b/src/components/views/elements/ManageIntegsButton.js @@ -64,7 +64,7 @@ export default class ManageIntegsButton extends React.Component { const IntegrationsManager = sdk.getComponent("views.settings.IntegrationsManager"); Modal.createDialog(IntegrationsManager, { src: (this.scalarClient !== null && this.scalarClient.hasCredentials()) ? - this.scalarClient.getScalarInterfaceUrlForRoom(this.props.roomId) : + this.scalarClient.getScalarInterfaceUrlForRoom(this.props.room) : null, }, "mx_IntegrationsManager"); } @@ -103,5 +103,5 @@ export default class ManageIntegsButton extends React.Component { } ManageIntegsButton.propTypes = { - roomId: PropTypes.string.isRequired, + room: PropTypes.object.isRequired, }; diff --git a/src/components/views/rooms/AppsDrawer.js b/src/components/views/rooms/AppsDrawer.js index 78677e138b..7541b304a2 100644 --- a/src/components/views/rooms/AppsDrawer.js +++ b/src/components/views/rooms/AppsDrawer.js @@ -189,7 +189,7 @@ module.exports = React.createClass({ _launchManageIntegrations: function() { const IntegrationsManager = sdk.getComponent("views.settings.IntegrationsManager"); const src = (this.scalarClient !== null && this.scalarClient.hasCredentials()) ? - this.scalarClient.getScalarInterfaceUrlForRoom(this.props.room.roomId, 'add_integ') : + this.scalarClient.getScalarInterfaceUrlForRoom(this.props.room, 'add_integ') : null; Modal.createTrackedDialog('Integrations Manager', '', IntegrationsManager, { src: src, diff --git a/src/components/views/rooms/RoomHeader.js b/src/components/views/rooms/RoomHeader.js index aee229c5da..67ede1a011 100644 --- a/src/components/views/rooms/RoomHeader.js +++ b/src/components/views/rooms/RoomHeader.js @@ -391,7 +391,7 @@ module.exports = React.createClass({ let manageIntegsButton; if (this.props.room && this.props.room.roomId && this.props.inRoom) { manageIntegsButton = ; } diff --git a/src/components/views/rooms/Stickerpack.js b/src/components/views/rooms/Stickerpack.js index 24bd44c3d3..983a357d86 100644 --- a/src/components/views/rooms/Stickerpack.js +++ b/src/components/views/rooms/Stickerpack.js @@ -208,7 +208,7 @@ export default class Stickerpack extends React.Component { const IntegrationsManager = sdk.getComponent("views.settings.IntegrationsManager"); const src = (this.scalarClient !== null && this.scalarClient.hasCredentials()) ? this.scalarClient.getScalarInterfaceUrlForRoom( - this.props.room.roomId, + this.props.room, 'type_stickerpack', this.widgetId, ) : From 3e4175f3e0e32db28f39935d1a3f45212104328e Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 9 Feb 2018 12:20:05 +0000 Subject: [PATCH 488/927] Add isUrlPermitted function --- src/HtmlUtils.js | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/HtmlUtils.js b/src/HtmlUtils.js index 0c262fe89a..5c6cbd6c1b 100644 --- a/src/HtmlUtils.js +++ b/src/HtmlUtils.js @@ -1,6 +1,6 @@ /* Copyright 2015, 2016 OpenMarket Ltd -Copyright 2017 New Vector Ltd +Copyright 2017, 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. @@ -25,6 +25,7 @@ import escape from 'lodash/escape'; import emojione from 'emojione'; import classNames from 'classnames'; import MatrixClientPeg from './MatrixClientPeg'; +import url from 'url'; emojione.imagePathSVG = 'emojione/svg/'; // Store PNG path for displaying many flags at once (for increased performance over SVG) @@ -44,6 +45,8 @@ const SYMBOL_PATTERN = /([\u2100-\u2bff])/; const EMOJI_REGEX = new RegExp(emojione.unicodeRegexp+"+", "gi"); const COLOR_REGEX = /^#[0-9a-fA-F]{6}$/; +const PERMITTED_URL_SCHEMES = ['http', 'https', 'ftp', 'mailto', 'magnet']; + /* * Return true if the given string contains emoji * Uses a much, much simpler regex than emojione's so will give false @@ -152,6 +155,25 @@ export function sanitizedHtmlNode(insaneHtml) { return
; } +/** + * Tests if a URL from an untrusted source may be safely put into the DOM + * The biggest threat here is javascript: URIs. + * Note that the HTML sanitiser library has its own internal logic for + * doing this, to which we pass the same list of schemes. This is used in + * other places we need to sanitise URLs. + * @return true if permitted, otherwise false + */ +export function isUrlPermitted(inputUrl) { + try { + const parsed = url.parse(inputUrl); + if (!parsed.protocol) return false; + // URL parser protocol includes the trailing colon + return PERMITTED_URL_SCHEMES.includes(parsed.protocol.slice(0, -1)); + } catch (e) { + return false; + } +} + const sanitizeHtmlParams = { allowedTags: [ 'font', // custom to matrix for IRC-style font coloring @@ -172,7 +194,7 @@ const sanitizeHtmlParams = { // Lots of these won't come up by default because we don't allow them selfClosing: ['img', 'br', 'hr', 'area', 'base', 'basefont', 'input', 'link', 'meta'], // URL schemes we permit - allowedSchemes: ['http', 'https', 'ftp', 'mailto', 'magnet'], + allowedSchemes: PERMITTED_URL_SCHEMES, allowProtocolRelative: false, From 52181fde9550192e88a548cbb257ae2c2f631651 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sim=C3=B3=20Albert=20i=20Beltran?= Date: Thu, 8 Feb 2018 19:20:09 +0000 Subject: [PATCH 489/927] Translated using Weblate (Catalan) Currently translated at 88.3% (871 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ca/ --- src/i18n/strings/ca.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ca.json b/src/i18n/strings/ca.json index 691da985f2..1ff3e7f8e9 100644 --- a/src/i18n/strings/ca.json +++ b/src/i18n/strings/ca.json @@ -867,5 +867,7 @@ "Import": "Importa", "The version of Riot.im": "La versió de Riot.im", "Email": "Correu electrònic", - "Add email address": "Afegeix correu electrònic" + "Add email address": "Afegeix correu electrònic", + "I have verified my email address": "He verificat l'adreça de correu electrònic", + "Send Reset Email": "Envia email de reinici" } From 22aedb6075259cf1e58745dc7825c6aca9d78533 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D1=80=D0=BA=D0=BE=20=D0=9C=2E=20=D0=9A=D0=BE?= =?UTF-8?q?=D1=81=D1=82=D0=B8=D1=9B?= Date: Thu, 8 Feb 2018 21:19:42 +0000 Subject: [PATCH 490/927] Translated using Weblate (Serbian) Currently translated at 100.0% (986 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sr/ --- src/i18n/strings/sr.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/i18n/strings/sr.json b/src/i18n/strings/sr.json index 39a1f1cf20..6f1958094a 100644 --- a/src/i18n/strings/sr.json +++ b/src/i18n/strings/sr.json @@ -117,7 +117,7 @@ "%(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.", - "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "УПОЗОРЕЊЕ: ПОТВРДА КЉУЧА НИЈЕ УСПЕЛА! Кључ потписивања за корисника %(userId)s и уређај %(deviceId)s је „%(fprint)s“ а то се не подудара са достављеним кључем „%(fingerprint)s“. Ово можда значи да се ваши разговори прате!", + "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "УПОЗОРЕЊЕ: ПРОВЕРА КЉУЧА НИЈЕ УСПЕЛА! Кључ потписивања за корисника %(userId)s и уређај %(deviceId)s је „%(fprint)s“ а то се не подудара са достављеним кључем „%(fingerprint)s“. Ово можда значи да се ваши разговори прате!", "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "Кључ за потписивање који сте доставили се подудара са кључем за потписивање од корисника %(userId)s и уређаја %(deviceId)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.", @@ -567,7 +567,7 @@ "Create new room": "Направи нову собу", "Unblacklist": "Скини са црног списка", "Blacklist": "Стави на црни списак", - "Unverify": "Скини потврду", + "Unverify": "Означи непровереним", "Verify...": "Провери...", "No results": "Нема резултата", "Delete": "Обриши", @@ -674,15 +674,15 @@ "Device name": "Назив уређаја", "Device key": "Кључ уређаја", "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "Ако се подудара, притисните дугме за потврду провере испод. Ако се не подудара, неко други прислушкује овај уређај и вероватно желите да притиснете дугме за стављање на црни списак.", - "In future this verification process will be more sophisticated.": "У будућности ће овај поступак потврђивања бити напреднији.", + "In future this verification process will be more sophisticated.": "У будућности ће овај поступак провере бити напреднији.", "Verify device": "Провери уређај", "I verify that the keys match": "Потврђујем да се кључеви подударају", "An error has occurred.": "Догодила се грешка.", "OK": "У реду", "You added a new device '%(displayName)s', which is requesting encryption keys.": "Додали сте нови уређај „%(displayName)s“ који захтева кључеве за шифровање.", - "Your unverified device '%(displayName)s' is requesting encryption keys.": "Ваш непотврђени уређај „%(displayName)s“ захтева кључеве за шифровање.", - "Start verification": "Започни потврђивање", - "Share without verifying": "Подели без потврђивања", + "Your unverified device '%(displayName)s' is requesting encryption keys.": "Ваш непроверени уређај „%(displayName)s“ захтева кључеве за шифровање.", + "Start verification": "Започни проверу", + "Share without verifying": "Подели без провере", "Ignore request": "Занемари захтев", "Loading device info...": "Учитавам податке о уређају...", "Encryption key request": "Захтев за кључ шифровања", @@ -693,7 +693,7 @@ "Continue anyway": "Ипак настави", "Invalid Email Address": "Неисправна мејл адреса", "This doesn't appear to be a valid email address": "Изгледа да ово није исправна мејл адреса", - "Verification Pending": "Чека се на потврду", + "Verification Pending": "Чека се на проверу", "Please check your email and click on the link it contains. Once this is done, click continue.": "Проверите ваш мејл и кликните на везу унутар њега. Када ово урадите, кликните на дугме „настави“.", "Unable to add email address": "Не могу да додам мејл адресу", "Unable to verify email address.": "Не могу да проверим мејл адресу.", From e9e0d65401c3ff6b840b2df66a92fab269e76df3 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 9 Feb 2018 12:33:59 +0000 Subject: [PATCH 491/927] Prepare changelog for v0.11.4 --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 87459882c9..055e25b805 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +Changes in [0.11.4](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.11.4) (2018-02-09) +===================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.11.3...v0.11.4) + + * Add isUrlPermitted function to sanity check URLs + Changes in [0.11.3](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.11.3) (2017-12-04) ===================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.11.2...v0.11.3) From 4bf5e44b2043bbe95faa66943878acad23dfb823 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 9 Feb 2018 12:34:00 +0000 Subject: [PATCH 492/927] v0.11.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5c81db2153..36f137e4f4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "0.11.3", + "version": "0.11.4", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { From 9dba4ab569e050dd28492ba633889f392546c0b7 Mon Sep 17 00:00:00 2001 From: Tirifto Date: Fri, 9 Feb 2018 12:30:53 +0000 Subject: [PATCH 493/927] Translated using Weblate (Esperanto) Currently translated at 97.1% (958 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eo/ --- src/i18n/strings/eo.json | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/eo.json b/src/i18n/strings/eo.json index a50d16a2b3..c6a4b81740 100644 --- a/src/i18n/strings/eo.json +++ b/src/i18n/strings/eo.json @@ -944,5 +944,17 @@ "Import": "Enporti", "Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?": "Forigo de fenestraĵo efektiviĝos por ĉiuj uzantoj en ĉi tiu ĉambro. Ĉu vi certe volas ĝin forigi?", "Unblacklist": "Repermesi legadon de ĉifritaj mesaĝoj", - "none": "neniu" + "none": "neniu", + "The version of Riot.im": "Tiu ĉi versio de Riot.im", + "Whether or not you're logged in (we don't record your user name)": "Ĉu vi salutis aŭ ne (ni ne registras vian salutnomon)", + "Your language of choice": "Via preferata lingvo", + "The information being sent to us to help make Riot.im better includes:": "Informoj sendataj al ni por plibonigi la servon Riot.im inkluzivas:", + "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s ŝanĝis sian vidigan nomon al %(displayName)s.", + "Send an encrypted reply…": "Sendi ĉifritan respondon…", + "Send a reply (unencrypted)…": "Sendi respondon (neĉifritan)…", + "Send an encrypted message…": "Sendi ĉifritan mesaĝon…", + "Send a message (unencrypted)…": "Sendi mesaĝon (neĉifritan)…", + "Replying": "Respondanta", + "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "Privato gravas al ni, tial ni ne kolektas personajn aŭ spureblajn datumojn por nia analizo.", + "Learn more about how we use analytics.": "Lernu pli pri nia uzo de analiziloj." } From 55593416fa71c9c2a77382da8053457c6a5d4d39 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Fri, 9 Feb 2018 13:23:34 +0000 Subject: [PATCH 494/927] Hide apps drawer when viewining room settings. --- src/components/structures/RoomView.js | 3 +- src/components/views/rooms/AppsDrawer.js | 40 ++++++++++++++---------- src/components/views/rooms/AuxPanel.js | 9 +++++- 3 files changed, 34 insertions(+), 18 deletions(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 60987fe26e..4873bbc961 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -1605,7 +1605,8 @@ module.exports = React.createClass({ displayConfCallNotification={this.state.displayConfCallNotification} maxHeight={this.state.auxPanelMaxHeight} onResize={this.onChildResize} - showApps={this.state.showApps && !this.state.editingRoomSettings} > + showApps={this.state.showApps} + hideAppsDrawer={this.state.editingRoomSettings} > { aux } ); diff --git a/src/components/views/rooms/AppsDrawer.js b/src/components/views/rooms/AppsDrawer.js index 7541b304a2..a8336edfc3 100644 --- a/src/components/views/rooms/AppsDrawer.js +++ b/src/components/views/rooms/AppsDrawer.js @@ -35,7 +35,15 @@ module.exports = React.createClass({ displayName: 'AppsDrawer', propTypes: { + userId: React.PropTypes.string.isRequired, room: React.PropTypes.object.isRequired, + showApps: React.PropTypes.bool, // Should apps be rendered + hide: React.PropTypes.bool, // If rendered, should apps drawer be visible + }, + + defaultProps: { + showApps: true, + hide: false, }, getInitialState: function() { @@ -46,7 +54,7 @@ module.exports = React.createClass({ componentWillMount: function() { ScalarMessaging.startListening(); - MatrixClientPeg.get().on("RoomState.events", this.onRoomStateEvents); + MatrixClientPeg.get().on('RoomState.events', this.onRoomStateEvents); }, componentDidMount: function() { @@ -56,7 +64,7 @@ module.exports = React.createClass({ this.scalarClient.connect().then(() => { this.forceUpdate(); }).catch((e) => { - console.log("Failed to connect to integrations server"); + console.log('Failed to connect to integrations server'); // TODO -- Handle Scalar errors // this.setState({ // scalar_error: err, @@ -70,7 +78,7 @@ module.exports = React.createClass({ componentWillUnmount: function() { ScalarMessaging.stopListening(); if (MatrixClientPeg.get()) { - MatrixClientPeg.get().removeListener("RoomState.events", this.onRoomStateEvents); + MatrixClientPeg.get().removeListener('RoomState.events', this.onRoomStateEvents); } dis.unregister(this.dispatcherRef); }, @@ -81,7 +89,7 @@ module.exports = React.createClass({ }, onAction: function(action) { - const hideWidgetKey = this.props.room.roomId + "_hide_widget_drawer"; + const hideWidgetKey = this.props.room.roomId + '_hide_widget_drawer'; switch (action.action) { case 'appsDrawer': // When opening the app drawer when there aren't any apps, @@ -109,7 +117,7 @@ module.exports = React.createClass({ * passed through encodeURIComponent. * @param {string} pathTemplate The path with template variables e.g. '/foo/$bar'. * @param {Object} variables The key/value pairs to replace the template - * variables with. E.g. { "$bar": "baz" }. + * variables with. E.g. { '$bar': 'baz' }. * @return {string} The result of replacing all template variables e.g. '/foo/baz'. */ encodeUri: function(pathTemplate, variables) { @@ -187,13 +195,13 @@ module.exports = React.createClass({ }, _launchManageIntegrations: function() { - const IntegrationsManager = sdk.getComponent("views.settings.IntegrationsManager"); + const IntegrationsManager = sdk.getComponent('views.settings.IntegrationsManager'); const src = (this.scalarClient !== null && this.scalarClient.hasCredentials()) ? this.scalarClient.getScalarInterfaceUrlForRoom(this.props.room, 'add_integ') : null; Modal.createTrackedDialog('Integrations Manager', '', IntegrationsManager, { src: src, - }, "mx_IntegrationsManager"); + }, 'mx_IntegrationsManager'); }, onClickAddWidget: function(e) { @@ -201,12 +209,12 @@ module.exports = React.createClass({ // Display a warning dialog if the max number of widgets have already been added to the room const apps = this._getApps(); if (apps && apps.length >= MAX_WIDGETS) { - const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + const ErrorDialog = sdk.getComponent('dialogs.ErrorDialog'); const errorMsg = `The maximum number of ${MAX_WIDGETS} widgets have already been added to this room.`; console.error(errorMsg); Modal.createDialog(ErrorDialog, { - title: _t("Cannot add any more widgets"), - description: _t("The maximum permitted number of widgets have already been added to this room."), + title: _t('Cannot add any more widgets'), + description: _t('The maximum permitted number of widgets have already been added to this room.'), }); return; } @@ -238,11 +246,11 @@ module.exports = React.createClass({ ) { addWidget =
[+] { _t('Add a widget') } @@ -250,8 +258,8 @@ module.exports = React.createClass({ } return ( -
-
+
+
{ apps }
{ this._canUserModify() && addWidget } diff --git a/src/components/views/rooms/AuxPanel.js b/src/components/views/rooms/AuxPanel.js index c0857d9691..749026d5c6 100644 --- a/src/components/views/rooms/AuxPanel.js +++ b/src/components/views/rooms/AuxPanel.js @@ -31,7 +31,8 @@ module.exports = React.createClass({ // js-sdk room object room: React.PropTypes.object.isRequired, userId: React.PropTypes.string.isRequired, - showApps: React.PropTypes.bool, + showApps: React.PropTypes.bool, // Render apps + hideAppsDrawer: React.PropTypes.bool, // Do not display apps drawer and content (may still be rendered) // Conference Handler implementation conferenceHandler: React.PropTypes.object, @@ -51,6 +52,11 @@ module.exports = React.createClass({ onResize: React.PropTypes.func, }, + defaultProps: { + showApps: true, + hideAppsDrawer: false, + }, + shouldComponentUpdate: function(nextProps, nextState) { return (!ObjectUtils.shallowEqual(this.props, nextProps) || !ObjectUtils.shallowEqual(this.state, nextState)); @@ -133,6 +139,7 @@ module.exports = React.createClass({ userId={this.props.userId} maxHeight={this.props.maxHeight} showApps={this.props.showApps} + hide={this.props.hideAppsDrawer} />; return ( From e1410755600b4a3f94400cace45aae3ea2c84406 Mon Sep 17 00:00:00 2001 From: Oskars Date: Sat, 10 Feb 2018 16:38:14 +0000 Subject: [PATCH 495/927] Translated using Weblate (Latvian) Currently translated at 90.3% (891 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/lv/ --- src/i18n/strings/lv.json | 296 +++++++++++++++++++++++++++++++++------ 1 file changed, 251 insertions(+), 45 deletions(-) diff --git a/src/i18n/strings/lv.json b/src/i18n/strings/lv.json index ae290d4d5f..50416f0318 100644 --- a/src/i18n/strings/lv.json +++ b/src/i18n/strings/lv.json @@ -21,7 +21,7 @@ "Default Device": "Noklusējuma ierīce", "Microphone": "Mikrofons", "Camera": "Kamera", - "Advanced": "Īpašie", + "Advanced": "Papildus", "Algorithm": "Algoritms", "Hide removed messages": "Slēpt dzēstos ziņojumus", "Always show message timestamps": "Vienmēr rādīt ziņojumu laika zīmogu", @@ -35,7 +35,7 @@ "Anyone": "Ikviens", "Anyone who knows the room's link, apart from guests": "Ikviens, kurš zina adreses saiti uz istabu, izņemot viesus", "Anyone who knows the room's link, including guests": "Ikviens, kurš zina adreses saiti uz istabu, tai skaitā arī viesi", - "Are you sure?": "Esi pārliecināts/a?", + "Are you sure?": "Vai tiešām to vēlies?", "Are you sure you want to leave the room '%(roomName)s'?": "Vai tiešām vēlies pamest istabas: '%(roomName)s'?", "Are you sure you want to reject the invitation?": "Vai tiešām vēlies noraidīt šo uzaicinājumu?", "Are you sure you want to upload the following files?": "Vai tiešām vēlies augšuplādēt sekojošos failus?", @@ -48,7 +48,7 @@ "Blacklisted": "Melnajā sarakstā iekļautie", "Bug Report": "Paziņojums par kļūdu", "Bulk Options": "Lielapjoma darbības", - "Call Timeout": "Zvana noilgums", + "Call Timeout": "Zvana gaidīšanas noilgums", "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "Neizdevās savienoties ar serveri. Lūdzu pārbaudi savu tīkla savienējumu un pārliecinies, ka tava servera SSL sertifikāts ir uzticams, kā arī pārlūkā instalētie paplašinājumi nebloķē pieprasījumus.", "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Neizdevās savienoties ar serveri izmantojot HTTP protokolu, kad tava pārlūka adreses laukā ir HTTPS saite. Tā vietā izmanto HTTPS savienojumu vai iespējo nedrošos skriptus.", "Can't load user settings": "Neizdevās ielādēt lietotāja uzstādījumus", @@ -77,21 +77,21 @@ "Conference call failed.": "Konferences zvans neizdevās.", "Conference calling is in development and may not be reliable.": "Konferences zvans šobrīd atrodas izstrādes stadijā un var būt nestabils.", "Conference calls are not supported in encrypted rooms": "Konferences zvani nav iespējami istabās, kurās tiek izmantota šifrēšana", - "Conference calls are not supported in this client": "Konferences zvani netiek atbalstīti šajā programmā", + "Conference calls are not supported in this client": "Konferences zvani šajā klienta programmā netiek atbalstīti", "Confirm password": "Apstiprini paroli", "Confirm your new password": "Apstiprini jauno paroli", "Continue": "Turpināt", "Could not connect to the integration server": "Neizdevās savienoties ar integrācijas serveri", "%(count)s new messages|one": "jaunu ziņu skaits: %(count)s", "%(count)s new messages|other": "%(count)s jaunas ziņas", - "Create a new chat or reuse an existing one": "Izveidot jaunu čatu vai izmantot eksistējošu", + "Create a new chat or reuse an existing one": "Izveidot jaunu čalu vai izmantot jau esošu", "Create an account": "Reģistrēt kontu", "Create Room": "Izveidot istabu", "Cryptography": "Kriptogrāfija", "Current password": "Pašreizējā parole", "Curve25519 identity key": "Curve25519 identifikācijas atslēga", "Custom": "Pielāgots", - "Custom level": "Speciāls līmenis", + "Custom level": "Īpašais līmenis", "/ddg is not a command": "/ddg nav komanda", "Deactivate Account": "Deaktivizēt kontu", "Deactivate my account": "Deaktivizēt manu kontu", @@ -116,7 +116,7 @@ "Don't send typing notifications": "Nesūtīt paziņojumus", "Download %(text)s": "Lejupielādēt tekstu: %(text)s", "Drop File Here": "Ievelc failu šeit", - "Drop here to tag %(section)s": "Ievelc šeit uz birkas %(section)s", + "Drop here to tag %(section)s": "Nomest šeit, lai birkotu %(section)s", "Ed25519 fingerprint": "Ed25519 identificējošā zīmju virkne", "Email": "Epasts", "Email address": "Epasta adrese", @@ -140,11 +140,11 @@ "Error decrypting attachment": "Kļūda atšifrējot pielikumu", "Error: Problem communicating with the given homeserver.": "Kļūda: Radās komunikācijas problēma ar norādīto serveri.", "Event information": "Notikuma informācija", - "Existing Call": "Eksistējošs zvans", + "Existing Call": "Pašreizējā saruna (zvans)", "Export": "Eksportēt", "Export E2E room keys": "Eksportēt E2E istabas atslēgas", - "Failed to ban user": "Neizdevās liegt pieeju lietotājam", - "Failed to change password. Is your password correct?": "Neizdevās mainīt paroli. Vai tava parole ir pareiza?", + "Failed to ban user": "Neizdevās bloķēt (liegt pieeju) lietotāju", + "Failed to change password. Is your password correct?": "Neizdevās nomainīt paroli. Vai tā ir pareiza?", "Failed to change power level": "Neizdevās mainīt statusa līmeni", "Power level must be positive integer.": "Statusa līmenim ir jābūt pozitīvam skaitlim.", "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Tu nevarēsi atcelt šo darbību, jo šim lietotājam piešķir tādu pašu statusa līmeni, kāds ir Tev.", @@ -170,12 +170,12 @@ "Failed to upload profile picture!": "Neizdevās augšuplādēt profila attēlu!", "Failed to verify email address: make sure you clicked the link in the email": "Neizdevās apstiprināt epasta adresi. Pārbaudi, vai Tu esi noklikšķinājis/usi saiti epasta ziņā", "Failure to create room": "Neizdevās izveidot istabu", - "Favourite": "Favorīts", + "Favourite": "Tava izlase (favorīti)", "Favourites": "Favorīti", "Fill screen": "Aizpildīt ekrānu", "Filter room members": "Filtrēt istabas biedrus", "Forget room": "\"Aizmirst\" istabu", - "Forgot your password?": "Aizmirsi savu paroli?", + "Forgot your password?": "Aizmirsi paroli?", "For security, this session has been signed out. Please sign in again.": "Drošības nolūkos, šī sesija ir beigusies. Lūdzu, pieraksties par jaunu.", "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "Drošības nolūkos, izrakstīšanās dzēsīs jebkādas ierīce-ierīce šifrēšanas atslēgas no šī pārlūka. Ja Tu vēlies saglabāt iespēju atšifrēt tavu saziņas vēsturi no Riot nākotnes sesijām, lūdzu eksportē tavas istabas atslēgas, saglabājot tās drošā vietā.", "Found a bug?": "Pamanīji kļūdu?", @@ -198,7 +198,7 @@ "Incorrect username and/or password.": "Nepareizs lietotājvārds un/vai parole.", "Incorrect verification code": "Nepareizs verifikācijas kods", "Interface Language": "Saskarnes valoda", - "Invalid alias format": "Nepareizs aizstājējvārda formāts", + "Invalid alias format": "Nepareizs aizstājējvārda (aliases) formāts", "Invalid address format": "Nepareizs adreses formāts", "Invalid Email Address": "Nepareiza epasta adrese", "Invalid file%(extra)s": "Nepareizs faila %(extra)s", @@ -215,7 +215,7 @@ "Join Room": "Pievienoties istabai", "%(targetName)s joined the room.": "%(targetName)s pievienojās istabai.", "Joins room with given alias": "Pievieno istabai ar uzdoto aizstājējvārdu", - "Jump to first unread message.": "Pārlekt uz pirmo neizlasīto ziņu.", + "Jump to first unread message.": "Pāriet uz pirmo neizlasīto ziņu.", "%(senderName)s kicked %(targetName)s.": "%(senderName)s iespēra (kick) %(targetName)s.", "Kick": "Iespert (kick)", "Kicks user with given id": "Iesper (kick) lietotājam pēc norādītā id", @@ -240,7 +240,7 @@ "Turn Markdown off": "Izslēgt formatēšanas iespēju", "Turn Markdown on": "Ieslēgt formatēšanas iespēju", "matrix-react-sdk version:": "matrix-react-sdk versija:", - "The default role for new room members is": "Noklusējuma loma jaunam istabas biedram ir", + "The default role for new room members is": "Jauna istabas biedra statuss pēc noklusējuma ir", "Message not sent due to unknown devices being present": "Ziņa nav nosūtīta, jo tika konstatēta nezināmu ierīču klātbūtne", "Missing room_id in request": "Iztrūkstošs room_id pieprasījumā", "Missing user_id in request": "Iztrūkstošs user_id pieprasījumā", @@ -248,7 +248,7 @@ "Mobile phone number (optional)": "Mobilā telefona numurs (nav obligāts)", "Moderator": "Moderators", "Must be viewing a room": "Jāapskata istaba", - "Mute": "Apklusināt", + "Mute": "Kluss (noklusināt)", "%(serverName)s Matrix ID": "%(serverName)s Matrix ID", "Name": "Vārds", "Never send encrypted messages to unverified devices from this device": "Nekad nesūti no šīs ierīces šifrētas ziņas uz neverificētām ierīcēm", @@ -269,7 +269,7 @@ "No more results": "Nav tālāko rezultātu", "No results": "Nav rezultātu", "No users have specific privileges in this room": "Nav lietotāju ar īpašām privilēģijām šajā istabā", - "OK": "LABI", + "OK": "Labs ir", "olm version:": "olm versija:", "Once encryption is enabled for a room it cannot be turned off again (for now)": "Tiklīdz istabai tiks iespējota šifrēšana, tā vairs nebūs atslēdzama (pašlaik)", "Only people who have been invited": "Vienīgi personas, kuras ir tikušas uzaicinātas", @@ -283,7 +283,7 @@ "Phone": "Telefons", "%(senderName)s placed a %(callType)s call.": "%(senderName)s nolika %(callType)s zvanu.", "Please check your email and click on the link it contains. Once this is done, click continue.": "Lūdzu pārbaudi savu epastu un noklikšķini tajā esošo saiti. Tiklīdz tas ir izdarīts, klikšķini \"turpināt\".", - "Press to start a chat with someone": "Nospied , lai uzsāktu čatu ar kādu", + "Press to start a chat with someone": "Nospied , lai ar kādu uzsāktu čalošanu", "Privacy warning": "Privātuma brīdinājums", "Private Chat": "Privātais čats", "Privileged Users": "Priviliģētie lietotāji", @@ -308,8 +308,8 @@ "Resetting password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Paroles atiestatīšana atiestatīs visas ierīce-ierīce šifrēšanas atslēgas visās ierīcēs, padarot čata šifrēto ziņu vēsturi nelasāmu, ja vien Tu pirms tam neesi eksportējis savas istabas atslēgas un atkārtoti importējis tās atpakaļ. Nākotnē šo ir plānots uzlabot.", "Results from DuckDuckGo": "Rezultāti no DuckDuckGo", "Return to login screen": "Atgriezties uz pierakstīšanās lapu", - "Riot does not have permission to send you notifications - please check your browser settings": "Riot nav atļauts nosūtīt Tev paziņojumus. Lūdzu pārbaudi sava pārlūka uzstādījumus", - "Riot was not given permission to send notifications - please try again": "Riot nav atļauts nosūtīt paziņojumus. Lūdzu mēģini vēlreiz.", + "Riot does not have permission to send you notifications - please check your browser settings": "Riot nav atļauts nosūtīt Tev paziņojumus. Lūdzu pārbaudi sava pārlūka iestatījumus", + "Riot was not given permission to send notifications - please try again": "Riot nav piešķirta atļauja nosūtīt paziņojumus. Lūdzu mēģini vēlreiz", "riot-web version:": "riot-web versija:", "Unable to enable Notifications": "Nav iespējams iespējot paziņojumus", "You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "Tu izrakstījies no visām ierīcēm un vairs nesaņemsi pašpiegādes (push) paziņojumus. Lai iespējotu paziņojumus, pieraksties atkārtoti katrā no ierīcēm", @@ -319,14 +319,14 @@ "Room %(roomId)s not visible": "Istaba %(roomId)s nav redzama", "%(roomName)s does not exist.": "%(roomName)s neeksistē.", "%(roomName)s is not accessible at this time.": "%(roomName)s šobrīd nav pieejama.", - "Seen by %(userName)s at %(dateTime)s": "Redzams %(userName)s %(dateTime)s", + "Seen by %(userName)s at %(dateTime)s": "Redzējis %(userName)s %(dateTime)s", "%(senderDisplayName)s sent an image.": "%(senderDisplayName)s nosūtīja attēlu.", "%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s nosūtīja uzaicinājumu %(targetDisplayName)s pievienoties istabai.", "%(senderName)s set a profile picture.": "%(senderName)s uzstādīja profila attēlu.", "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s uzstādīja redzamo vārdu uz: %(displayName)s.", "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "Tevis uzdotā pierakstīšanās atslēga sakrīt ar atslēgu, kuru Tu saņēmi no %(userId)s ierīces %(deviceId)s. Ierīce tika atzīmēta kā verificēta.", "The file '%(fileName)s' exceeds this home server's size limit for uploads": "Faila '%(fileName)s' izmērs pārsniedz šī mājas servera augšupielādes lieluma ierobežojumu", - "The file '%(fileName)s' failed to upload": "Failu '%(fileName)s' neizdevās augšuplādēt", + "The file '%(fileName)s' failed to upload": "Failu '%(fileName)s' neizdevās nosūtīt (augšuplādēt)", "%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s ieslēdza ierīce-ierīce šifrēšanu (algorithm %(algorithm)s).", "%(senderName)s unbanned %(targetName)s.": "%(senderName)s atcēla pieejas ierobežojumu (atbanoja) %(targetName)s.", "Unknown room %(roomId)s": "Nezināma istaba %(roomId)s", @@ -402,7 +402,7 @@ "This email address is already in use": "Šī epasta adrese jau tiek izmantota", "This email address was not found": "Šāda epasta adrese nav atrasta", "The email address linked to your account must be entered.": "Ir jāievada tavam kontam piesaistītā epasta adrese.", - "The remote side failed to pick up": "Neizdevās uzņemt attālināto pusi", + "The remote side failed to pick up": "Zvana adresāts neatbild", "This Home Server does not support login using email address.": "Šis serveris neatbalsta pierakstīšanos ar epasta adresi.", "This invitation was sent to an email address which is not associated with this account:": "Šis uzaicinājums tika nosūtīts uz epasta adresi, kura nav piesaistīta šim kontam:", "This room has no local addresses": "Šai istabai nav lokālo adrešu", @@ -425,7 +425,7 @@ "Unable to verify email address.": "Nav iespējams apstiprināt epasta adresi.", "Unban": "Atbanot", "Unable to ascertain that the address this invite was sent to matches one associated with your account.": "Nav iespējams pārliecināties, ka šis uzaicinājums tika nosūtīts uz to pašu adresi, kura ir piesaistīta tavam kontam.", - "Unable to capture screen": "Nav iespējams uzņemt ekrānattēlu", + "Unable to capture screen": "Neizdevās uzņemt ekrānattēlu", "Unable to load device list": "Nav iespējams ielādēt ierīču sarakstu", "Undecryptable": "Neatšifrējams", "Unencrypted room": "Nešifrēta istaba", @@ -439,14 +439,14 @@ "Unnamed Room": "Istaba bez nosaukuma", "Cancel": "Atcelt", "Create new room": "Izveidot jaunu istabu", - "Custom Server Options": "Īpaši servera uzstādījumi", - "Dismiss": "Noņemt", + "Custom Server Options": "Iestatāmie servera uzstādījumi", + "Dismiss": "Atteikums", "You have enabled URL previews by default.": "Tev ir pēc noklusējuma iespējots URL adrešu priekšskatījums.", "Unrecognised command:": "Neatpazīta komanda:", "Unrecognised room alias:": "Neatpazīts istabas aizstājējvārds:", "Unverified": "Neverificēts", "Upload avatar": "Augšuplādē profila attēlu", - "Upload Failed": "Augšupielāde neizdevās", + "Upload Failed": "Nosūtīšana (augšupielāde) neizdevās", "Upload Files": "Augšuplādē failus", "Upload file": "Augšuplādē failu", "Upload new:": "Augšuplādē jaunu:", @@ -481,11 +481,11 @@ "Who would you like to add to this room?": "Kuru vēlies pievienot šai istabai?", "Who would you like to communicate with?": "Ar kuru vēlies komunicēt?", "Would you like to accept or decline this invitation?": "Vai vēlies apstiprināt vai noraidīt šo uzaicinājumu?", - "You already have existing direct chats with this user:": "Tev jau ir eksistējošs tiešais čats ar šo lietotāju:", - "You are already in a call.": "Tu jau šobrīd atrodies zvanā.", + "You already have existing direct chats with this user:": "Tev jau ir viens tiešais čats ar šo lietotāju:", + "You are already in a call.": "Tu jau šobrīd esi sarunā.", "You're not in any rooms yet! Press to make a room or to browse the directory": "Šobrīd Tu vēl neatrodies nevienā istabā! Klikšķini lai izveidotu istabu, vai , lai skatītu istabu katalogu", - "You cannot place a call with yourself.": "Tu nevari veikt zvanu sev.", - "You cannot place VoIP calls in this browser.": "Tu nevari veikt VoIP zvanus šajā pārlūkā.", + "You cannot place a call with yourself.": "Nav iespējams piezvanīt sev.", + "You cannot place VoIP calls in this browser.": "VoIP zvani šajā pārlūkā netiek atbalstīti.", "You do not have permission to post to this room": "Tev nav vajadzīgās atļaujas pievienot ziņas šajā istabā", "You have disabled URL previews by default.": "URL priekšskatījums pēc noklusējuma Tev ir atspējots.", "You may wish to login with a different account, or add this email to this account.": "Tu varētu, iespējams, vēlēties pierakstīties no cita konta vai piesaistīt šo epastu šim kontam.", @@ -531,7 +531,7 @@ "An unknown error occurred.": "Notikusi neparedzēta kļūda.", "I already have an account": "Man jau ir konts", "Topic": "Tēma", - "Make Moderator": "Piešķirt moderatora līmeni", + "Make Moderator": "Piešķirt moderatora statusu", "Make this room private": "Padarīt šo istabu privātu", "Share message history with new users": "Kopīgot ziņu vēsturi ar jauniem lietotājiem", "Encrypt room": "Šifrēt istabu", @@ -550,7 +550,7 @@ "numbullet": "lode ar numuru", "Please select the destination room for this message": "Lūdzu izvēlies šīs ziņas mērķa istabu", "Room directory": "Istabu katalogs", - "Start chat": "Uzsākt čatu", + "Start chat": "Uzsākt čalošanu", "New Password": "Jauna parole", "Start automatically after system login": "Uzsākt automātiski pēc pierakstīšanās sistēmā", "Desktop specific": "Darbvirsmai specifiski", @@ -569,7 +569,7 @@ "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "Šis process ļauj Tev importēt tās šifrēšanas atslēgas, kuras Tu iepriekš eksportēji no citas Matrix klienta aplikācijas. Importētās atslēgas ļaus vajadzīgajā klienta aplikācijā lasīt atšifrētās ziņas.", "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "Eksporta fails būs aizsargāts ar paroles frāzi. Tā ir jāievada šeit, lai atšifrētu failu.", "You must join the room to see its files": "Tev ir jāpievienojas istabai, lai redzētu tās failus", - "Start new chat": "Uzsākt jaunu čatu", + "Start new chat": "Uzsākt jaunu čalu", "Failed to invite": "Neizdevās uzaicināt", "Failed to invite user": "Neizdevās uzaicināt lietotāju", "Confirm Removal": "Apstiprini dzēšanu", @@ -596,7 +596,7 @@ "Blacklist": "Melnais saraksts", "Unverify": "Atverificēt", "Verify...": "Verificē...", - "ex. @bob:example.com": "piemēram, @janis:majaslapa.lv", + "ex. @bob:example.com": "piemēram, @valters:smaidu.lv", "Add User": "Pievienot lietotāju", "This Home Server would like to make sure you are not a robot": "Šis mājas serveris vēlas pārliecināties, ka Tu neesi robots", "Sign in with CAS": "Pierakstīties ar CAS", @@ -606,7 +606,7 @@ "Please check your email to continue registration.": "Lūdzu pārbaudi savu epastu lai turpinātu reģistrāciju.", "Token incorrect": "Nepareizs autentifikācijas kods", "Please enter the code it contains:": "Lūdzu ievadi tajā ietverto kodu:", - "powered by Matrix": "spēcināts ar Matrix", + "powered by Matrix": "Tiek darbināts ar Matrix", "If you don't specify an email address, you won't be able to reset your password. Are you sure?": "Ja Tu nenorādīsi epasta adresi, tev nebūs iespējams izmantot paroles atiestatīšanu. Vai esi pārliecināts/a?", "Default server": "Noklusējuma serveris", "Custom server": "Īpašs serveris", @@ -617,18 +617,18 @@ "Error decrypting image": "Kļūda atšifrējot attēlu", "Error decrypting video": "Kļūda atšifrējot video", "Add an Integration": "Pievienot integrāciju", - "Removed or unknown message type": "Dzēsts vai nezināms ziņas veids", + "Removed or unknown message type": "Dzēsts vai nezināms ziņas tips", "URL Previews": "URL adrešu priekšskatījumi", "Drop file here to upload": "Ievelc failu šeit lai augšuplādētu", " (unsupported)": " (netiek atbalstīts)", - "Online": "Tiešsaistē", + "Online": "Tiešsaistē (pieslēgumā)", "Idle": "Dīkstāve", - "Offline": "Nav tiešsaistē", + "Offline": "Atsaistē (ārpus tīkla)", "Updates": "Atjauninājumi", "Check for update": "Pārbaudīt, vai ir atjauninājumi", - "Start chatting": "Sākt čatošanu", - "Start Chatting": "Sākt čatošanu", - "Click on the button below to start chatting!": "Klikšķini uz zemāk esošās pogas, lai uzsāktu čatošanu!", + "Start chatting": "Sākt čalošanu", + "Start Chatting": "Sākt čalošanu", + "Click on the button below to start chatting!": "Klikšķini uz zemāk esošās pogas, lai uzsāktu čalošanu!", "Username available": "Lietotājvārds ir pieejams", "Username not available": "Lietotājvārds nav pieejams", "Something went wrong!": "Kaut kas nogāja greizi!", @@ -653,14 +653,14 @@ "Delete widget": "Dzēst widžetu", "Define the power level of a user": "Definēt lietotāja pakāpes līmeni", "Do you want to load widget from URL:": "Vai vēlies ielādēt widžetu no URL:", - "Edit": "Labot", + "Edit": "Rediģēt", "Enable automatic language detection for syntax highlighting": "Iespējot automātisko valodas noteikšanu sintakses iezīmējumiem", "Hide Apps": "Slēpt aplikācijas", "Hide join/leave messages (invites/kicks/bans unaffected)": "Slēpt pievienoties/pamest ziņas (tas neietekmē uzaicinājumus, vai kick/bana darbības)", "Integrations Error": "Integrācijas kļūda", "Publish this room to the public in %(domain)s's room directory?": "Publicēt šo istabu publiskajā %(domain)s katalogā?", "AM": "AM", - "PM": "PZ", + "PM": "PM", "NOTE: Apps are not end-to-end encrypted": "PIEZĪME: Aplikācijās nav ierīce-ierīce šifrēšanas", "Sets the room topic": "Uzstāda istabas tēmas nosaukumu", "Show Apps": "Rādīt aplikācijas", @@ -683,5 +683,211 @@ "%(widgetName)s widget added by %(senderName)s": "%(senderName)s pievienoja %(widgetName)s vidžetu", "%(widgetName)s widget removed by %(senderName)s": "%(senderName)s dzēsa vidžetu %(widgetName)s", "Robot check is currently unavailable on desktop - please use a web browser": "Robotu pārbaude šobrīd nav pieejama darbvirsmas versijā. Lūdzu izmanto web pārlūku", - "Revoke widget access": "Atsaukt vidžeta piekļuvi" + "Revoke widget access": "Atsaukt vidžeta piekļuvi", + "Unpin Message": "Atkabināt ziņu", + "Add rooms to this community": "Pievienot istabas šai komūnai", + "Failed to set direct chat tag": "Neizdevās tiešajam čatam uzstādīt birku", + "Warning": "Brīdinājums", + "Send": "Sūtīt", + "Leave": "Pamest", + "Unnamed room": "Nenosaukta istaba", + "Guests can join": "Var pievienoties viesi", + "The platform you're on": "Izmantotā operētājsistēma", + "The version of Riot.im": "Riot.im versija", + "Whether or not you're logged in (we don't record your user name)": "Neatkarīgi no tā, vai esi vai neesi iegājis sistēmā (netiek fiksēts Tavs lietotājvārds)", + "Your language of choice": "Izvēlētā valoda", + "Which officially provided instance you are using, if any": "Kuru oficiāli izlaisto versiju izmantojat (ja to darat)", + "Whether or not you're using the Richtext mode of the Rich Text Editor": "Neatkarīgi no tā, vai izmantojat Richtext režīmu redaktorā Rich Text Editor", + "Your homeserver's URL": "Mājasservera URL adrese", + "Your identity server's URL": "Tava identitātes servera URL adrese", + "The information being sent to us to help make Riot.im better includes:": "Informācija, kura mums tiek nosūtīta, lai ļautu padarīt Riot.im labāku, ietver:", + "We also record each page you use in the app (currently ), your User Agent () and your device resolution ().": "Mēs arī fiksējam katru lapu, kuru tu izmanto programmā (currently ), Tavu lietotāja aģentu () un Tavas ierīces ekrāna izšķirtspēju ().", + "Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.": "Ja šī lapa ietver identificējamu informāciju, tādu kā istaba, lietotājs, grupas ID, šie dati tiek noņemti pirms nosūtīšanas uz serveri.", + "Call Failed": "Zvans neizdevās", + "There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "Šajā istabā ir nepazīstamas ierīces: ja Tu turpināsi bez to pārbaudes, ir iespējams, ka kāda nepiederoša persona var noklausīties Tavas sarunas.", + "Review Devices": "Ierīču pārskats", + "Call Anyway": "Vienalga zvanīt", + "Answer Anyway": "Vienalga atbildēt", + "Call": "Zvans", + "Answer": "Atbildēt", + "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s", + "Who would you like to add to this community?": "Kurus cilvēkus Tu vēlētos pievienot šai komūnai?", + "Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "Brīdinājums: ikviens, kurš tiek pievienots komūnai būs publiski redzams visiem, kuri zin komūnas ID", + "Invite new community members": "Uzaicināt jaunus komūnas biedrus", + "Name or matrix ID": "Vārds vai Matrix ID", + "Invite to Community": "Uzaicināt komūnā", + "Which rooms would you like to add to this community?": "Kuras istabas vēlies pievienot šai komūnai?", + "Show these rooms to non-members on the community page and room list?": "Vai ne-biedriem rādīt komūnas lapā un istabu sarakstā šīs istabas?", + "Add rooms to the community": "Istabu pievienošana komūnai", + "Room name or alias": "Istabas nosaukums vai aliase", + "Add to community": "Pievienot komūnai", + "Failed to invite the following users to %(groupId)s:": "Neizdevās uzaicināt sekojošus lietotājus grupā %(groupId)s:", + "Failed to invite users to community": "Neizdevās uzaicināt lietotājus komūnā", + "Failed to invite users to %(groupId)s": "Neizdevās uzaicināt lietotājus grupā %(groupId)s:", + "Failed to add the following rooms to %(groupId)s:": "Neizdevās pievienot sekojošas istabas grupai %(groupId)s:", + "Restricted": "Ierobežots", + "Ignored user": "Ignorējams lietotājs", + "You are now ignoring %(userId)s": "Tagad Tu ignorē %(userId)s", + "Unignored user": "Neignorējams lietotājs", + "You are no longer ignoring %(userId)s": "Tu vairāk neignorē %(userId)s", + "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s nomainīja savu attēlojamo vārdu uz %(displayName)s.", + "%(senderName)s changed the pinned messages for the room.": "%(senderName)s šai istabai nomainīja piekabinātās ziņas.", + "%(widgetName)s widget modified by %(senderName)s": "%(widgetName)s vidžets, kuru mainīja %(senderName)s", + "%(names)s and %(count)s others are typing|other": "%(names)s un %(count)s citi raksta", + "%(names)s and %(count)s others are typing|one": "%(names)s un vēl kāds raksta", + "Message Replies": "Atbildes uz ziņām", + "Message Pinning": "Ziņu piekabināšana", + "Presence Management": "Klātbūtnes vadība", + "Tag Panel": "Birku panelis", + "Disable Emoji suggestions while typing": "Atspējot Emoji ieteikumus teksta rakstīšanas laikā", + "Hide avatar changes": "Slēpt avatara izmaiņas", + "Hide display name changes": "Slēpt attēlojamā vārda izmaiņas", + "Disable big emoji in chat": "Atspējot čatā lielos emoji", + "Mirror local video feed": "Spoguļots vietējā video attēlojums", + "Enable inline URL previews by default": "Ieslēgt URL adrešu priekšskatījumu pēc noklusējuma", + "Enable URL previews for this room (only affects you)": "Ieslēgt URL adrešu priekšskatījumus šai istabai (ietekmē tikai Tevi pašu)", + "Enable URL previews by default for participants in this room": "Ieslēgt URL adrešu priekšskatījumus pēc noklusējuma visiem šīs istabas dalībniekiem", + "Delete %(count)s devices|other": "Dzēst %(count)s ierīces", + "Delete %(count)s devices|one": "Dzēst ierīci", + "Select devices": "Izvēlēties ierīces", + "%(senderName)s sent an image": "%(senderName)s nosūtīja bildi", + "%(senderName)s sent a video": "%(senderName)s nosūtīja video", + "%(senderName)s uploaded a file": "%(senderName)s augšupielādēja failu", + "Disinvite this user?": "Atcelt ielūgumu šim lietotājam?", + "Kick this user?": "Padzīt šo lietotāju?", + "Unban this user?": "Atbloķēt šo lietotāju (atcelt liegumu šim lietotājam)?", + "Ban this user?": "Bloķēt šo lietotāju (uzlikt liegumu šim lietotājam)?", + "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.": "Jūs nevarēsiet atcelt šīs izmaiņas pēc sava statusa pazemināšanas. Gadījumā, ja esat pēdējais priviliģētais lietotājs istabā, būs neiespējami atgūt šīs privilēģijas.", + "Unignore": "Atcelt ignorēšanu", + "Ignore": "Ignorēt", + "Jump to read receipt": "Pāriet uz izlasīšanas apstiprinājumu", + "Mention": "Atsauce (pieminējums)", + "Invite": "Uzaicināt", + "User Options": "Lietotāja uzstādījumi", + "Send an encrypted reply…": "Sūtīt šifrētu atbildi…", + "Send a reply (unencrypted)…": "Sūtīt nešifrētu atbildi…", + "Send an encrypted message…": "Sūtīt šifrētu ziņu…", + "Send a message (unencrypted)…": "Sūtīt NEšifrētu ziņu…", + "Jump to message": "Pāriet uz ziņu", + "No pinned messages.": "Nav piestiprinātu ziņu.", + "Loading...": "Ielāde...", + "Pinned Messages": "Piestiprinātās ziņas", + "%(duration)ss": "%(duration)s sek", + "%(duration)sm": "%(duration)smin", + "%(duration)sh": "%(duration)sstundas", + "%(duration)sd": "%(duration)sdienas", + "Online for %(duration)s": "Pieslēgumā %(duration)s", + "Idle for %(duration)s": "Dīkstāvē (neaktīvs) %(duration)s", + "Offline for %(duration)s": "Atslēgumā %(duration)s", + "Unknown for %(duration)s": "Neskaidrā statusā %(duration)s", + "Unknown": "Neskaidrs statuss", + "Replying": "Atbildot uz", + "No rooms to show": "Nav istabu, kuras parādīt", + "World readable": "Pieejams ikvienam no visurienes", + "Remove avatar": "Dzēst avataru", + "Drop here to favourite": "Nomest šeit (atvilt uz šejieni), lai iekļautu izlasē (favorītos)", + "Drop here to tag direct chat": "Nomest šeit, lai pievienotu atzīmi \"Tiešais čats\"", + "Drop here to restore": "Nomest šeit, lai atgrieztu", + "Drop here to demote": "Nomest šeit, lai pazeminātu", + "Failed to remove tag %(tagName)s from room": "Neizdevās istabai noņemt birku %(tagName)s", + "Failed to add tag %(tagName)s to room": "Neizdevās istabai pievienot birku %(tagName)s", + "Community Invites": "Uzaicinājums uz komūnu", + "You have been kicked from this room by %(userName)s.": "%(userName)s padzina Tevi no šīs istabas.", + "You have been banned from this room by %(userName)s.": "%(userName)s nobloķēja Tevi (liedza piekļuvi) šajā istabā.", + "You are trying to access a room.": "Tu centies gūt piekļuvi istabai.", + "To change the room's avatar, you must be a": "Lai izmainītu istabas avatāru, Tev jābūt", + "To change the room's name, you must be a": "Lai izmainītu istabas nosaukumu, Tev jābūt", + "To change the room's main address, you must be a": "Lai izmainītu istabas pamatadresi, Tev jābūt", + "To change the room's history visibility, you must be a": "Lai izmainītu istabas vēstures redzamību, Tev jābūt", + "To change the permissions in the room, you must be a": "Lai istabā izmainītu atļaujas, Tev jābūt", + "To change the topic, you must be a": "Lai izmainītu tematu, Tev jābūt", + "To modify widgets in the room, you must be a": "Lai istabā izmainītu vidžetus, Tev jābūt", + "Banned by %(displayName)s": "Nobloķējis (liedzis piekļuvi) %(displayName)s", + "Members only (since the point in time of selecting this option)": "Tikai biedri (no šī parametra iestatīšanas brīža)", + "Members only (since they were invited)": "Tikai biedri (no to uzaicināšanas brīža)", + "Members only (since they joined)": "Tikai biedri (kopš pievienošanās)", + "To send messages, you must be a": "Lai sūtītu ziņas, Tev jābūt", + "To invite users into the room, you must be a": "Lai aicinātu istabā lietotājus, ir jābūt", + "To configure the room, you must be a": "Lai konfigurētu istabu, ir jābūt", + "To kick users, you must be a": "Lai padzītu lietotājus, ir jābūt", + "To ban users, you must be a": "Lai bloķētu (liegtu pieeju) lietotājiem, ir jābūt", + "To remove other users' messages, you must be a": "Lai dzēstu citu lietotāju ziņas, ir jābūt", + "To send events of type , you must be a": "Lai sūtītu tipa notikumus, ir jābūt", + "Addresses": "Adreses", + "Invalid community ID": "Nederīgs komūnas ID", + "'%(groupId)s' is not a valid community ID": "'%(groupId)s' nav derīgs komūnas ID", + "Flair": "Gaidas (nojauta)", + "Showing flair for these communities:": "Parādīt Tavas gaidas šajās komūnās:", + "This room is not showing flair for any communities": "Šajā istabā neparādās gaidas, kas uzstādītas komūnās", + "New community ID (e.g. +foo:%(localDomain)s)": "Jaunās komūnas ID (piem. +foo:%(localDomain)s)", + "URL previews are enabled by default for participants in this room.": "URL adrešu priekšskats šīs istabas dalībniekiem ir iespējots pēc noklusējuma.", + "URL previews are disabled by default for participants in this room.": "ULR adrešu priešskats šīs istabas dalībniekiem pēc noklusējuma ir atspējots.", + "Copied!": "Nokopēts!", + "Failed to copy": "Nokopēt neizdevās", + "Message removed by %(userId)s": "Ziņu dzēsis %(userId)s", + "Message removed": "Ziņa dzēsta", + "An email has been sent to %(emailAddress)s": "Vēstule tika nosūtīta uz %(emailAddress)s", + "A text message has been sent to %(msisdn)s": "Teksta ziņa tika nosūtīts uz %(msisdn)s", + "Username on %(hs)s": "Lietotājvārds uz %(hs)s", + "Remove from community": "Izdzēst no komūnas", + "Disinvite this user from community?": "Atcelt šim lietotājam nosūtīto uzaicinājumu pievienoties komūnai?", + "Remove this user from community?": "Izdzēst šo lietotāju no kopienas?", + "Failed to withdraw invitation": "Neizdevās atcelt uzaicinājumu", + "Failed to remove user from community": "Neizdevās izdzēst lietotāju no kopienas", + "Filter community members": "Kopienas biedru filtrs", + "Flair will appear if enabled in room settings": "Gaidas parādīsies, ja tās iespējotas istabas iestatījumos", + "Flair will not appear": "Gaidas neparādīsies", + "Are you sure you want to remove '%(roomName)s' from %(groupId)s?": "Vai tiešām vēlies izdzēst '%(roomName)s' no %(groupId)s?", + "Removing a room from the community will also remove it from the community page.": "Dzēšot istabu no kopienas tā tiks dzēsta arī no kopienas lapas.", + "Failed to remove room from community": "Neizdevās dzēst istabu no kopienas", + "Failed to remove '%(roomName)s' from %(groupId)s": "Neizdevās dzēst '%(roomName)s' no %(groupId)s", + "The visibility of '%(roomName)s' in %(groupId)s could not be updated.": "Istabas '%(roomName)s' redzamību %(groupId)s nebija iespējams atjaunot.", + "Visibility in Room List": "Redzamība istabu sarakstā", + "Visible to everyone": "Redzama visiem", + "Only visible to community members": "Tikai komūnas dalībniekiem", + "Filter community rooms": "Kopienas istabu filtrs", + "Something went wrong when trying to get your communities.": "Kaut kas nogāja greizi, kad tika mēģināts attēlot Tavas kopienas.", + "Display your community flair in rooms configured to show it.": "Parādīt Tavas gaidas istabās, kurās to parādīšana iespējota.", + "You're not currently a member of any communities.": "Pašreiz Tu neesi neesi nevienas komūnas piederīgais.", + "Delete Widget": "Dzēst vidžetu", + "Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?": "Vidžeta dzēšana to dzēš visiem šīs istabas lietotājiem. Vai tiešām vēlies dzēst šo vidžetu?", + "Minimize apps": "Minimizēt lietotājprogrammas", + "Communities": "Kopienas", + "%(nameList)s %(transitionList)s": "%(nameList)s %(transitionList)s", + "%(severalUsers)sjoined %(count)s times|other": "%(severalUsers)spievienojās %(count)s reizes", + "%(severalUsers)sjoined %(count)s times|one": "%(severalUsers)spievienojās", + "%(oneUser)sjoined %(count)s times|other": "%(oneUser)spievienojās %(count)s reizes", + "%(oneUser)sjoined %(count)s times|one": "%(oneUser)s pievienojās", + "%(severalUsers)sleft %(count)s times|other": "%(severalUsers)s izgāja %(count)s reizes", + "%(severalUsers)sleft %(count)s times|one": "%(severalUsers)s izgāja (atvienojās)", + "%(oneUser)sleft %(count)s times|other": "%(oneUser)s izgāja (atvienojās) %(count)s reizes", + "%(oneUser)sleft %(count)s times|one": "%(oneUser)s izgāja", + "%(severalUsers)sjoined and left %(count)s times|other": "%(severalUsers)s pievienojās un izgāja %(count)s reizes", + "%(severalUsers)sjoined and left %(count)s times|one": "%(severalUsers)s pievienojās un izgāja", + "%(oneUser)sjoined and left %(count)s times|other": "%(oneUser)s pievienojās un izgāja %(count)s reizes", + "%(oneUser)sjoined and left %(count)s times|one": "%(oneUser)s pievienojās un izgāja", + "%(severalUsers)sleft and rejoined %(count)s times|other": "%(severalUsers)s izgāja un atkalpievienojās %(count)s reizes", + "%(severalUsers)srejected their invitations %(count)s times|other": "%(severalUsers)s noraidīja uzaicinājumus %(count)s reizes", + "%(severalUsers)shad their invitations withdrawn %(count)s times|other": "%(severalUsers)s atsauca izsniegtos uzaicinājumus %(count)s reizes", + "were banned %(count)s times|other": "tika bloķēti (liegta piekļuve) %(count)s reizes", + "was banned %(count)s times|other": "tika bloķēts (liegta piekļuve) %(count)s reizes", + "were unbanned %(count)s times|other": "tika atbloķēti (atgriezta pieeja) %(count)s reizes", + "were kicked %(count)s times|other": "tika padzīti %(count)s reizes", + "collapse": "sakļaut", + "expand": "izvērst", + "Custom of %(powerLevel)s": "Lietotāja līmenis %(powerLevel)s", + "In reply to ": "Atbildē uz ", + "And %(count)s more...|other": "Un par %(count)s vairāk...", + "Matrix ID": "Matrix ID", + "Matrix Room ID": "Matrix istabas ID", + "email address": "e-pasta adrese", + "Try using one of the following valid address types: %(validTypesList)s.": "Mēģiniet izmantot vienu no sekojošiem pieļautajiem adrešu tipiem: %(validTypesList)s.", + "You have entered an invalid address.": "Ievadīta nederīga adrese.", + "Community IDs cannot not be empty.": "Kopienas IDs nevar būt tukšs.", + "Community IDs may only contain characters a-z, 0-9, or '=_-./'": "Kopienas IDs var saturēt tikai simbolus a-z, 0-9, or '=_-./'", + "Something went wrong whilst creating your community": "Radot Tavu kopienu kaut kas nogāja greizi", + "Create Community": "Radīt kopienu", + "Community Name": "Kopienas nosaukums", + "Community ID": "Kopienas ID", + "example": "piemērs" } From 97ce84c8e36eaf20c0306242a4700c03e9419ef6 Mon Sep 17 00:00:00 2001 From: Aidan Gauland Date: Sun, 11 Feb 2018 16:14:17 +1300 Subject: [PATCH 496/927] Add display name to the read receipt view Show the user's display name (aka nick) in the ReadReceiptMarker title (mouseover text), and then the user ID in parentheses. --- src/components/views/rooms/ReadReceiptMarker.js | 6 ++++-- src/i18n/strings/en_EN.json | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/components/views/rooms/ReadReceiptMarker.js b/src/components/views/rooms/ReadReceiptMarker.js index 5dd62ff6b7..d5436efc76 100644 --- a/src/components/views/rooms/ReadReceiptMarker.js +++ b/src/components/views/rooms/ReadReceiptMarker.js @@ -186,8 +186,10 @@ module.exports = React.createClass({ let title; if (this.props.timestamp) { title = _t( - "Seen by %(userName)s at %(dateTime)s", - {userName: this.props.member.userId, dateTime: formatDate(new Date(this.props.timestamp), this.props.showTwelveHour)}, + "Seen by %(displayName)s (%(userName)s) at %(dateTime)s", + {displayName: this.props.member.name, + userName: this.props.member.userId, + dateTime: formatDate(new Date(this.props.timestamp), this.props.showTwelveHour)}, ); } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 6139ac2a91..2be4bf2e48 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -360,7 +360,7 @@ "Offline": "Offline", "Unknown": "Unknown", "Replying": "Replying", - "Seen by %(userName)s at %(dateTime)s": "Seen by %(userName)s at %(dateTime)s", + "Seen by %(displayName)s (%(userName)s) at %(dateTime)s": "Seen by %(displayName)s (%(userName)s) at %(dateTime)s", "No rooms to show": "No rooms to show", "Unnamed room": "Unnamed room", "World readable": "World readable", From 0fd9b3e9b2d89965bb3966839d8f55700e17e7b9 Mon Sep 17 00:00:00 2001 From: Aidan Gauland Date: Sun, 11 Feb 2018 16:27:07 +1300 Subject: [PATCH 497/927] Avoid doubling up username in read receipt view In the ReadReceiptMarker title, use the RoomMember.rawDisplayName because RoomMember.name may already include the username, which we are going to add ourselves. --- src/components/views/rooms/ReadReceiptMarker.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/rooms/ReadReceiptMarker.js b/src/components/views/rooms/ReadReceiptMarker.js index d5436efc76..8dc3c0f7d0 100644 --- a/src/components/views/rooms/ReadReceiptMarker.js +++ b/src/components/views/rooms/ReadReceiptMarker.js @@ -187,7 +187,7 @@ module.exports = React.createClass({ if (this.props.timestamp) { title = _t( "Seen by %(displayName)s (%(userName)s) at %(dateTime)s", - {displayName: this.props.member.name, + {displayName: this.props.member.rawDisplayName, userName: this.props.member.userId, dateTime: formatDate(new Date(this.props.timestamp), this.props.showTwelveHour)}, ); From 0f5dc5a7e4fa9eff05d59732389085e504225d67 Mon Sep 17 00:00:00 2001 From: Oskars Date: Mon, 12 Feb 2018 00:54:12 +0000 Subject: [PATCH 498/927] Translated using Weblate (Latvian) Currently translated at 96.5% (952 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/lv/ --- src/i18n/strings/lv.json | 177 ++++++++++++++++++++++++++------------- 1 file changed, 119 insertions(+), 58 deletions(-) diff --git a/src/i18n/strings/lv.json b/src/i18n/strings/lv.json index 50416f0318..b888050e29 100644 --- a/src/i18n/strings/lv.json +++ b/src/i18n/strings/lv.json @@ -4,19 +4,19 @@ "%(targetName)s accepted an invitation.": "%(targetName)s apstiprināja uzaicinājumu.", "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s apstiprināja uzaicinājumu no %(displayName)s.", "Account": "Konts", - "Access Token:": "Pieejas atslēga:", + "Access Token:": "Pieejas tokens:", "Active call (%(roomName)s)": "Aktīvs zvans (%(roomName)s)", "Add": "Pievienot", "Add a topic": "Pievieno tematu", - "Add email address": "Pievieno Epasta adresi", + "Add email address": "Pievieno epasta adresi", "Add phone number": "Pievieno tālruņa numuru", "Admin": "Administrators", "Admin Tools": "Administratora rīki", "VoIP": "VoIP", - "Missing Media Permissions, click here to request.": "Nav pieejas medija saturam. Klikšķini šeit, lai pieprasītu.", - "No Microphones detected": "Mikrofoni nav atrasti", - "No Webcams detected": "Webkameras nav atrastas", - "No media permissions": "Nav pieejas mediju saturam", + "Missing Media Permissions, click here to request.": "Nav atļauju piekļūt ierīcei. Klikšķini šeit, lai tās pieprasītu.", + "No Microphones detected": "Nav mikrofonu", + "No Webcams detected": "Nav webkameru", + "No media permissions": "Nav datu nesēju, kuriem atļauta piekļuve", "You may need to manually permit Riot to access your microphone/webcam": "Tev varētu būt nepieciešams manuāli atļaut Riot pieslēgties tavam mikrofonam/webkamerai", "Default Device": "Noklusējuma ierīce", "Microphone": "Mikrofons", @@ -44,14 +44,14 @@ "%(senderName)s banned %(targetName)s.": "%(senderName)s liedza pieeju %(targetName)s.", "Ban": "Liegt pieeju (Bans)", "Banned users": "Lietotāji, kuriem ir liegta pieeja (banotie)", - "Bans user with given id": "Liedz pieeju lietotājam pēc uzdotā ID (Bans)", + "Bans user with given id": "Bloķē (liedz pieeju) lietotāju pēc uzdotā ID (nobano)", "Blacklisted": "Melnajā sarakstā iekļautie", "Bug Report": "Paziņojums par kļūdu", - "Bulk Options": "Lielapjoma darbības", + "Bulk Options": "Grupveida darbību parametri", "Call Timeout": "Zvana gaidīšanas noilgums", - "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "Neizdevās savienoties ar serveri. Lūdzu pārbaudi savu tīkla savienējumu un pārliecinies, ka tava servera SSL sertifikāts ir uzticams, kā arī pārlūkā instalētie paplašinājumi nebloķē pieprasījumus.", - "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Neizdevās savienoties ar serveri izmantojot HTTP protokolu, kad tava pārlūka adreses laukā ir HTTPS saite. Tā vietā izmanto HTTPS savienojumu vai iespējo nedrošos skriptus.", - "Can't load user settings": "Neizdevās ielādēt lietotāja uzstādījumus", + "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "Neizdodas savienoties ar bāzes serveri. Pārbaudi tīkla savienojumu un pārliecinies, ka bāzes servera SSL sertifikāts ir uzticams, kā arī pārlūkā instalētie paplašinājumi nebloķē pieprasījumus.", + "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Neizdodas savienoties ar bāzes serveri izmantojot HTTP protokolu, kad Tava pārlūka adreses laukā norādīts HTTPS protokols. Tā vietā izmanto HTTPS vai iespējo nedrošos skriptus.", + "Can't load user settings": "Neizdevās ielādēt lietotāja iestatījumus", "Change Password": "Paroles maiņa", "%(senderName)s changed their profile picture.": "%(senderName)s nomainīja profila attēlu.", "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s nomainīja statusa līmeni %(powerLevelDiffText)s.", @@ -59,18 +59,18 @@ "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s dzēsa istabas nosaukumu.", "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s nomainīja tēmas nosaukumu uz \"%(topic)s\".", "Changes to who can read history will only apply to future messages in this room": "Izmaiņas attiecībā uz to, kurš varēs lasīt vēstures ziņas, stāsies spēkā tikai uz ziņām,kuras vēl tiks pievienotas šajā istabā", - "Changes your display nickname": "Nomaina tavu publisko segvārdu (niku)", + "Changes your display nickname": "Nomaina Tavu publisko segvārdu (niku)", "Changing password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Paroles maiņa dzēsīs pašreizējās šifrēšanas atslēgas visās savstarpēji saistītajās ierīcēs, padarot čata vēsturi neizlasāmu, ja vien vien istabas atslēgas nav tikušas iepriekš eksportētas un no jauna importētas atpakaļ. Nākotnē to plānojam uzlabot.", - "Claimed Ed25519 fingerprint key": "Norādīta Ed25519 identificējošās zīmju virknes atslēga", + "Claimed Ed25519 fingerprint key": "Ed25519 pieprasītā nospieduma (fingerprint) atslēga", "Clear Cache and Reload": "Iztīri kešatmiņu un pārlādē", "Clear Cache": "Iztīri kešatmiņu", "Click here to join the discussion!": "Klikšķini šeit lai pievienotos diskusijai!", "Click here to fix": "Klikšķini šeit, lai izlabotu", - "Click to mute audio": "Klikšķini, lai izslēgtu skaņu", - "Click to mute video": "Klikšķini, lai izslēgtu video skaņu", - "click to reveal": "Klikšķini, lai atvērtu", - "Click to unmute video": "Klikšķini, lai ieslēgtu video skaņu", - "Click to unmute audio": "Klikšķini, lai ieslēgtu audio skaņu", + "Click to mute audio": "Klikšķini, lai audio skaņu izslēgtu", + "Click to mute video": "Klikšķini, lai video skaņu izslēgtu", + "click to reveal": "Klikšķini, lai atsegtu", + "Click to unmute video": "Klikšķini, lai video skaņu ieslēgtu", + "Click to unmute audio": "Klikšķini, lai audio skaņu ieslēgtu", "Close": "Aizvērt", "Command error": "Komandas kļūda", "Commands": "Komandas", @@ -93,13 +93,13 @@ "Custom": "Pielāgots", "Custom level": "Īpašais līmenis", "/ddg is not a command": "/ddg nav komanda", - "Deactivate Account": "Deaktivizēt kontu", - "Deactivate my account": "Deaktivizēt manu kontu", + "Deactivate Account": "Deaktivēt kontu", + "Deactivate my account": "Deaktivēt manu kontu", "Decline": "Noraidīt", "Decrypt %(text)s": "Atšifrēt %(text)s", "Decryption error": "Atšifrēšanas kļūda", "Delete": "Dzēst", - "Deops user with given id": "Noņemt operatora statusu lietotājam ar norādīto id", + "Deops user with given id": "Atceļ operatora statusu lietotājam ar norādīto ID", "Default": "Noklusējuma", "Device already verified!": "Ierīce ir jau verificēta!", "Device ID": "Ierīces ID", @@ -111,13 +111,13 @@ "Direct chats": "Tiešie čati", "Disable Notifications": "Atslēgt paziņojumus", "Disinvite": "Atsaukt", - "Display name": "Redzamais vārds", + "Display name": "Attēlojamais vārds", "Displays action": "Parāda darbību", "Don't send typing notifications": "Nesūtīt paziņojumus", "Download %(text)s": "Lejupielādēt tekstu: %(text)s", "Drop File Here": "Ievelc failu šeit", "Drop here to tag %(section)s": "Nomest šeit, lai birkotu %(section)s", - "Ed25519 fingerprint": "Ed25519 identificējošā zīmju virkne", + "Ed25519 fingerprint": "Ed25519 nospiedums (fingerprint), zīmju virkne", "Email": "Epasts", "Email address": "Epasta adrese", "Email address (optional)": "Epasta adrese (neobligāta)", @@ -138,7 +138,7 @@ "Enter passphrase": "Ievadi paroles frāzi", "Error": "Kļūda", "Error decrypting attachment": "Kļūda atšifrējot pielikumu", - "Error: Problem communicating with the given homeserver.": "Kļūda: Radās komunikācijas problēma ar norādīto serveri.", + "Error: Problem communicating with the given homeserver.": "Kļūda: Saziņas problēma ar norādīto bāzes serveri.", "Event information": "Notikuma informācija", "Existing Call": "Pašreizējā saruna (zvans)", "Export": "Eksportēt", @@ -166,7 +166,7 @@ "Failed to set up conference call": "Neizdevās iestatīt konferences zvanu", "Failed to toggle moderator status": "Neizdevās pārslēgt moderatora statusu", "Failed to unban": "Neizdevās atcelt pieejas liegumu (atbanot)", - "Failed to upload file": "Neizdevās augšuplādēt failu", + "Failed to upload file": "Neizdevās augšupielādēt failu", "Failed to upload profile picture!": "Neizdevās augšuplādēt profila attēlu!", "Failed to verify email address: make sure you clicked the link in the email": "Neizdevās apstiprināt epasta adresi. Pārbaudi, vai Tu esi noklikšķinājis/usi saiti epasta ziņā", "Failure to create room": "Neizdevās izveidot istabu", @@ -180,14 +180,14 @@ "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "Drošības nolūkos, izrakstīšanās dzēsīs jebkādas ierīce-ierīce šifrēšanas atslēgas no šī pārlūka. Ja Tu vēlies saglabāt iespēju atšifrēt tavu saziņas vēsturi no Riot nākotnes sesijām, lūdzu eksportē tavas istabas atslēgas, saglabājot tās drošā vietā.", "Found a bug?": "Pamanīji kļūdu?", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s no %(fromPowerLevel)s uz %(toPowerLevel)s", - "Guest access is disabled on this Home Server.": "Šajā serverī viesu pierakstīšanās nav iespējama.", + "Guest access is disabled on this Home Server.": "Šajā bāzes serverī viesu pierakstīšanās nav iespējama.", "Guests cannot join this room even if explicitly invited.": "Viesi nevar pievienoties šai istabai pat ja ir uzaicināti.", "Hangup": "Aizturēt", "Hide read receipts": "Slēpt izlasītās receptes", "Hide Text Formatting Toolbar": "Slēpt teksta formatēšanas rīkjoslu", "Historical": "Vēsturiskais", "Home": "Mājup", - "Homeserver is": "Serveris ir", + "Homeserver is": "Bāzes serveris ir", "Identity Server is": "Indentifikācijas serveris ir", "I have verified my email address": "Mana epasta adrese ir verificēta", "Import": "Importēt", @@ -214,11 +214,11 @@ "Join as voice or video.": "Pievienoties kā balss vai video.", "Join Room": "Pievienoties istabai", "%(targetName)s joined the room.": "%(targetName)s pievienojās istabai.", - "Joins room with given alias": "Pievieno istabai ar uzdoto aizstājējvārdu", + "Joins room with given alias": "Pievienojas istabai ar minēto aliasi (pseidonīmu)", "Jump to first unread message.": "Pāriet uz pirmo neizlasīto ziņu.", "%(senderName)s kicked %(targetName)s.": "%(senderName)s iespēra (kick) %(targetName)s.", "Kick": "Iespert (kick)", - "Kicks user with given id": "Iesper (kick) lietotājam pēc norādītā id", + "Kicks user with given id": "Padzen (kick) lietotāju ar norādīto ID", "Labs": "Laboratorija", "Last seen": "Pēdējo reizi redzēts/a", "Leave room": "Pamest istabu", @@ -226,7 +226,7 @@ "Level:": "Līmenis:", "Local addresses for this room:": "Šīs istabas lokālās adreses:", "Logged in as:": "Pierakstījās kā:", - "Login as guest": "Pierakstīties kā viesis", + "Login as guest": "Pierakstīties kā viesim", "Logout": "Izrakstīties", "Low priority": "Zema prioritāte", "%(senderName)s made future room history visible to all room members, from the point they are invited.": "%(senderName)s uzstādīja nākotnes istabas ziņu vēsturi redzamu visi istabas biedri secībā, kādā tika uzaicināti.", @@ -257,7 +257,7 @@ "New password": "Jauna parole", "New passwords don't match": "Jaunās paroles nesakrīt", "New passwords must match each other.": "Jaunajām parolēm ir jāsakrīt vienai ar otru.", - "none": "nekāds", + "none": "neviens", "not set": "nav iestatījuma", "not specified": "nav noteikts", "Notifications": "Paziņojumi", @@ -292,7 +292,7 @@ "Reason": "Iemesls", "Reason: %(reasonText)s": "Iemesls: %(reasonText)s", "Revoke Moderator": "Atcelt moderatoru", - "Refer a friend to Riot:": "Nosūtīt draugu uz Riot:", + "Refer a friend to Riot:": "Rekomendēt draugam Riot:", "Register": "Reģistrēties", "%(targetName)s rejected the invitation.": "%(targetName)s noraidīja uzaicinājumu.", "Reject invitation": "Noraidīt uzaicinājumu", @@ -370,14 +370,14 @@ "Scroll to unread messages": "Aizritināt uz nelasītajām ziņām", "Search": "Meklēt", "Search failed": "Meklēšana neizdevās", - "Searches DuckDuckGo for results": "Meklē DuckDuckGo rezultātus", + "Searches DuckDuckGo for results": "Meklēšanai izmanto DuckDuckGo", "Send anyway": "Nosūtīt jebkurā gadījumā", "Sender device information": "Nosūtītāja ierīces informācija", "Send Invites": "Nosūtīt uzaicinājumus", "Send Reset Email": "Nosūtīt atiestatīšanas epastu", "Server error": "Servera kļūda", "Server may be unavailable or overloaded": "Serveris var nebūt pieejams vai ir pārslogots", - "Server may be unavailable, overloaded, or search timed out :(": "Serveris var nebūt pieejams, ir pārslogots, vai arī meklēšana beidzās ar savienojuma noilgumu :(", + "Server may be unavailable, overloaded, or search timed out :(": "Serveris izskatās nepieejams, ir pārslogots, vai arī meklēšana beidzās ar savienojuma noildzi :(", "Server may be unavailable, overloaded, or the file too big": "Serveris var nebūt pieejams, ir pārslogots, vai arī faila izmērs ir par lielu", "Server may be unavailable, overloaded, or you hit a bug.": "Serveris var nebūt pieejams, ir pārslogots, vai arī sastapi neparedzētu kļūdu.", "Server unavailable, overloaded, or something else went wrong.": "Serveris nav pieejams, ir pārslogots, vai arī ir notikusi cita, neparedzēta, kļūda.", @@ -395,19 +395,19 @@ "Start authentication": "Sākt autentifikāciju", "Start Chat": "Sākt čatu", "Submit": "Iesniegt", - "Success": "Veiksmīgi", + "Success": "Izdevās", "Tagged as: ": "Atzīmēts,kā: ", "The main address for this room is": "Galvenā šīs istabas adrese ir", "The phone number entered looks invalid": "Ievadītais telefona numurs izskatās nepareizs", "This email address is already in use": "Šī epasta adrese jau tiek izmantota", "This email address was not found": "Šāda epasta adrese nav atrasta", - "The email address linked to your account must be entered.": "Ir jāievada tavam kontam piesaistītā epasta adrese.", + "The email address linked to your account must be entered.": "Ir jāievada Tavam kontam piesaistītā epasta adrese.", "The remote side failed to pick up": "Zvana adresāts neatbild", - "This Home Server does not support login using email address.": "Šis serveris neatbalsta pierakstīšanos ar epasta adresi.", + "This Home Server does not support login using email address.": "Šis bāzes serveris neatbalsta pierakstīšanos ar epasta adresi.", "This invitation was sent to an email address which is not associated with this account:": "Šis uzaicinājums tika nosūtīts uz epasta adresi, kura nav piesaistīta šim kontam:", "This room has no local addresses": "Šai istabai nav lokālo adrešu", "This room is not recognised.": "Šī istaba netika atpazīta.", - "These are experimental features that may break in unexpected ways": "Šīs ir eksperimentālās iespējas, kuras var būt dažādos veidos nestrādājošas", + "These are experimental features that may break in unexpected ways": "Šīs ir eksperimentālas funkcijas, kuras reizēm var novest pie negaidītiem rezultātiem", "The visibility of existing history will be unchanged": "Esošās ziņu vēstures redzamība paliks nemainīga", "This doesn't appear to be a valid email address": "Šī neizskatās pēc derīgas epasta adreses", "This is a preview of this room. Room interactions have been disabled": "Šis ir esošās istabas priekšskatījums. Istabas mijiedarbība ir atspējota", @@ -416,10 +416,10 @@ "This room is not accessible by remote Matrix servers": "Šī istaba nav pieejama no attālinātajiem Matrix serveriem", "This room's internal ID is": "Šīs istabas iekšējais ID ir", "To link to a room it must have an address.": "Lai ieliktu saiti uz istabu, tai ir jābūt piešķirtai adresei.", - "To reset your password, enter the email address linked to your account": "Lai atiestatītu savu paroli, ievadi tavam kontam piesaistīto epasta adresi", + "To reset your password, enter the email address linked to your account": "Lai atiestatītu savu paroli, ievadi savam kontam piesaistīto epasta adresi", "To use it, just wait for autocomplete results to load and tab through them.": "Lai to izmantotu, vienkārši gaidi, kamēr ielādējas automātiski ieteiktie rezultāti, un pārvietojies caur tiem.", "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Notika mēģinājums ielādēt šīs istabas specifisku laikpaziņojumu sadaļu, bet Tev nav atļaujas skatīt šo ziņu.", - "Tried to load a specific point in this room's timeline, but was unable to find it.": "Notika mēģinājums ielādēt šīs istabas specifisku laikpaziņojumu sadaļu, bet tā netika atrasta.", + "Tried to load a specific point in this room's timeline, but was unable to find it.": "Mēģinājums ielādēt šīs istabas čata vēstures izvēlēto posmu neizdevās, jo tas netika atrasts.", "Unable to add email address": "Nav iespējams pievienot epasta adresi", "Unable to remove contact information": "Nav iespējams dzēst kontaktinformāciju", "Unable to verify email address.": "Nav iespējams apstiprināt epasta adresi.", @@ -518,10 +518,10 @@ "Oct": "Okt.", "Nov": "Nov.", "Dec": "Dec.", - "Set a display name:": "Iestatīt redzamo vārdu:", + "Set a display name:": "Iestatīt attēloto vārdu:", "This image cannot be displayed.": "Šo attēlu nav iespējams parādīt.", "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s nomainīja istabas attēlu uz ", - "Upload an avatar:": "Augšuplādē profila attēlu:", + "Upload an avatar:": "Augšuplādē avataru (profila attēlu):", "This server does not support authentication with a phone number.": "Šis serveris neatbalsta autentifikāciju pēc telefona numura.", "Missing password.": "Trūkst parole.", "Passwords don't match.": "Paroles nesakrīt.", @@ -530,14 +530,14 @@ "User names may only contain letters, numbers, dots, hyphens and underscores.": "Lietotājvārdi drīkst saturēt vienīgi alfabēta burtus, skaitļus, punktus, defises un apakšsvītras.", "An unknown error occurred.": "Notikusi neparedzēta kļūda.", "I already have an account": "Man jau ir konts", - "Topic": "Tēma", + "Topic": "Temats", "Make Moderator": "Piešķirt moderatora statusu", "Make this room private": "Padarīt šo istabu privātu", "Share message history with new users": "Kopīgot ziņu vēsturi ar jauniem lietotājiem", "Encrypt room": "Šifrēt istabu", "There are no visible files in this room": "Nav redzamu failu šajā istabā", "Room": "Istaba", - "Connectivity to the server has been lost.": "Savienojums ar serveri tika zaudēts.", + "Connectivity to the server has been lost.": "Savienojums ar serveri pārtrūka.", "Sent messages will be stored until your connection has returned.": "Nosūtītās ziņas tiks saglabātas tiklīdz savienojums tiks atjaunots.", "Active call": "Aktīvs zvans", "bold": "trekns", @@ -552,8 +552,8 @@ "Room directory": "Istabu katalogs", "Start chat": "Uzsākt čalošanu", "New Password": "Jauna parole", - "Start automatically after system login": "Uzsākt automātiski pēc pierakstīšanās sistēmā", - "Desktop specific": "Darbvirsmai specifiski", + "Start automatically after system login": "Palaist programmu automātiski pie sistēmas ielādes", + "Desktop specific": "Darbvirsmai specifiskie", "Analytics": "Analītika", "Opt out of analytics": "Atteikties no analītikas", "Options": "Iespējas", @@ -564,9 +564,9 @@ "Confirm passphrase": "Apstiprināt paroles frāzi", "Import room keys": "Importēt istabas atslēgas", "File to import": "Importējamais fails", - "This process allows you to export the keys for messages you have received in encrypted rooms to a local file. You will then be able to import the file into another Matrix client in the future, so that client will also be able to decrypt these messages.": "Šī darbība atļauj Tev eksportēt lokālā failā atslēgas tām ziņām, kuras Tu saņēmi šifrētās istabās. Pēc tam nākotnē Tu varēsi importēt šo failu citā Matrix klienta aplikācijā, lai tajā būtu iespējams atšifrēt šīs ziņas.", - "The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.": "Eksportētais fails atļaus ikvienam, kurš to ir nolasījis, atšifrēt jebkuras tev redzamās šifrētās ziņas, tāpēc ievēro piesardzību, un glabā šo failu drošā vietā. Lai palīdzētu to nodrošināt, Tev ir jāievada paroles frāze, kura tiks izmantota eksportēto datu šifrēšanai. Datu importēšana būs iespējama tikai izmantojot šo pašu paroles frāzi.", - "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "Šis process ļauj Tev importēt tās šifrēšanas atslēgas, kuras Tu iepriekš eksportēji no citas Matrix klienta aplikācijas. Importētās atslēgas ļaus vajadzīgajā klienta aplikācijā lasīt atšifrētās ziņas.", + "This process allows you to export the keys for messages you have received in encrypted rooms to a local file. You will then be able to import the file into another Matrix client in the future, so that client will also be able to decrypt these messages.": "Šī darbība ļauj Tev uz lokālo failu eksportēt atslēgas priekš tām ziņām, kuras Tu saņēmi šifrētās istabās. Tu varēsi importēt šo failu citā Matrix klientā, lai tajā būtu iespējams lasīt šīs ziņas atšifrētas.", + "The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.": "Eksportētais fails ļaus ikvienam, kurš to spēj lasīt, atšifrēt jebkuras Tavas šifrētās ziņas, tāpēc ievēro piesardzību, un glabā šo failu drošā vietā. Lai palīdzētu to nodrošināt, Tev jāievada paroles frāze, kura tiks izmantota eksportēto datu šifrēšanai. Datu importēšana būs iespējama tikai izmantojot šo pašu paroles frāzi.", + "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "Šis process ļaus Tev importēt šifrēšanas atslēgas, kuras Tu iepriekš eksportēji no cita Matrix klienta. Tas ļaus Tev atšifrēt čata vēsturi.", "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "Eksporta fails būs aizsargāts ar paroles frāzi. Tā ir jāievada šeit, lai atšifrētu failu.", "You must join the room to see its files": "Tev ir jāpievienojas istabai, lai redzētu tās failus", "Start new chat": "Uzsākt jaunu čalu", @@ -586,7 +586,7 @@ "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "Ja tā sakrīt, tad nospied zemāk esošo verifikācijas pogu . Ja nesakrīt, tad kāds cits ir piekļuvis šai ierīcei un šādā gadījumā Tu, iespējams, vēlies izmantot \"melnais saraksts\" iespēju.", "Verify device": "Verificēt ierīci", "I verify that the keys match": "Es pārbaudu, vai atslēgas sakrīt", - "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "Mēs sastapāmies ar kļūdu, mēģinot atjaunot tavu iepriekšējo sesiju. Ja vēlies turpināt, tev ir jāpierakstās par jaunu un šifrēta čata ziņu vēsture nebūs izlasāma.", + "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "Atgadījās kļūda, mēģinot atjaunot tavu iepriekšējo sesiju. Ja vēlies turpināt, Tev ir jāpierakstās no jauna, taču šifrētā čata ziņu vēsture nebūs izlasāma.", "Unable to restore session": "Nav iespējams atjaunot sesiju", "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Ja Tu iepriekš izmantoji jaunāku Riot versiju, tava sesija var nebūt saderīga ar šo versiju. Aizver šo logu un atgriezies jaunākajā versijā.", "Continue anyway": "Turpināt jebkurā gadījumā", @@ -624,8 +624,8 @@ "Online": "Tiešsaistē (pieslēgumā)", "Idle": "Dīkstāve", "Offline": "Atsaistē (ārpus tīkla)", - "Updates": "Atjauninājumi", - "Check for update": "Pārbaudīt, vai ir atjauninājumi", + "Updates": "Aktualizācijas", + "Check for update": "Pārbaudīt, vai ir aktualizācijas", "Start chatting": "Sākt čalošanu", "Start Chatting": "Sākt čalošanu", "Click on the button below to start chatting!": "Klikšķini uz zemāk esošās pogas, lai uzsāktu čalošanu!", @@ -651,7 +651,7 @@ "Cannot add any more widgets": "Nav iespējams pievienot vairāk vidžetu", "Changes colour scheme of current room": "Nomaina pašreizējās istabas krāsu paleti", "Delete widget": "Dzēst widžetu", - "Define the power level of a user": "Definēt lietotāja pakāpes līmeni", + "Define the power level of a user": "Definē lietotāja statusu", "Do you want to load widget from URL:": "Vai vēlies ielādēt widžetu no URL:", "Edit": "Rediģēt", "Enable automatic language detection for syntax highlighting": "Iespējot automātisko valodas noteikšanu sintakses iezīmējumiem", @@ -662,12 +662,12 @@ "AM": "AM", "PM": "PM", "NOTE: Apps are not end-to-end encrypted": "PIEZĪME: Aplikācijās nav ierīce-ierīce šifrēšanas", - "Sets the room topic": "Uzstāda istabas tēmas nosaukumu", + "Sets the room topic": "Uzstāda istabas tematu", "Show Apps": "Rādīt aplikācijas", "The maximum permitted number of widgets have already been added to this room.": "Atļautais vidžetu skaits jau ir sasniegts šai istabai.", "To get started, please pick a username!": "Lai sāktu, lūdzu izvēlies lietotājvārdu!", "Unable to create widget.": "Nav iespējams izveidot widžetu.", - "Unbans user with given id": "Atceļ pieejas liegumu (atbano) lietotāju pēc norādītā id", + "Unbans user with given id": "Atbloķē (atceļ pieejas liegumu) lietotāju pēc norādītā ID (atbano)", "You are not in this room.": "Tu neatrodies šajā istabā.", "You do not have permission to do that in this room.": "Tev nav atļaujas šai darbībai šajā istabā.", "Verifies a user, device, and pubkey tuple": "Verificē lietotāju, ierīci, un publiskās atslēgas", @@ -685,11 +685,11 @@ "Robot check is currently unavailable on desktop - please use a web browser": "Robotu pārbaude šobrīd nav pieejama darbvirsmas versijā. Lūdzu izmanto web pārlūku", "Revoke widget access": "Atsaukt vidžeta piekļuvi", "Unpin Message": "Atkabināt ziņu", - "Add rooms to this community": "Pievienot istabas šai komūnai", + "Add rooms to this community": "Pievienot istabas šai kopienai", "Failed to set direct chat tag": "Neizdevās tiešajam čatam uzstādīt birku", "Warning": "Brīdinājums", "Send": "Sūtīt", - "Leave": "Pamest", + "Leave": "Atstāt", "Unnamed room": "Nenosaukta istaba", "Guests can join": "Var pievienoties viesi", "The platform you're on": "Izmantotā operētājsistēma", @@ -889,5 +889,66 @@ "Create Community": "Radīt kopienu", "Community Name": "Kopienas nosaukums", "Community ID": "Kopienas ID", - "example": "piemērs" + "example": "piemērs", + "Advanced options": "Papildus parametri", + "Block users on other matrix homeservers from joining this room": "Neļaut lietotājiem no citiem mājasserveriem pievienoties šai istabai", + "This setting cannot be changed later!": "Šo parametru vēlāk izmainīt nebūs iespējams!", + "%(severalUsers)sleft and rejoined %(count)s times|one": "%(severalUsers)s aizgājuši un atgriezušies", + "%(oneUser)sleft and rejoined %(count)s times|other": "%(oneUser)s aizgājis un atgriezies %(count)s reizes", + "%(oneUser)sleft and rejoined %(count)s times|one": "%(oneUser)s aizgājis un atgriezies", + "%(severalUsers)srejected their invitations %(count)s times|one": "%(severalUsers)s nepieņēma uzaicinājumus", + "were invited %(count)s times|one": "tika uzaicināti", + "was invited %(count)s times|other": "tika uzaicināta %(count)s reizes", + "was invited %(count)s times|one": "tika uzaicināts(a)", + "were unbanned %(count)s times|one": "tika atbloķēti (atcelts pieejas liegums)", + "was unbanned %(count)s times|other": "tika atbloķēts %(count)s reizes", + "was banned %(count)s times|one": "tika bloķēts", + "were banned %(count)s times|one": "tika bloķēti", + "was unbanned %(count)s times|one": "tika atbloķēts", + "were kicked %(count)s times|one": "tika padzīti", + "was kicked %(count)s times|other": "tika padzīts %(count)s reizes", + "was kicked %(count)s times|one": "tika padzīts", + "%(severalUsers)schanged their name %(count)s times|other": "%(severalUsers)s izmainīja savu lietotājvārdu %(count)s reizes", + "%(severalUsers)schanged their name %(count)s times|one": "%(severalUsers)s izmainīja savu lietotājvārdu", + "

HTML for your community's page

\n

\n Use the long description to introduce new members to the community, or distribute\n some important links\n

\n

\n You can even use 'img' tags\n

\n": "

Tavas kopienas lapas HTML

\n

\n Izmanto garāku aprakstu, lai iepazīstinātu jaunos lietoājus ar kopienu, \n vai padalies ar kādām attiecināmām web-saitēm\n

\n

\n Vari izmantot arī 'img' birkas\n

\n", + "Add rooms to the community summary": "Pievienot istabas kopienas informatīvajā kopsavilkumā", + "Which rooms would you like to add to this summary?": "Kuras istabas vēlaties pievienot šim kopsavilkumam?", + "Add to summary": "Pievienot kopsavilkumam", + "Failed to add the following rooms to the summary of %(groupId)s:": "Neizdevās sekojošās istabas pievienot %(groupId)s kopsavilkumam:", + "Add a Room": "Pievienot istabu", + "Failed to remove the room from the summary of %(groupId)s": "Neizdevās dzēst istabu no %(groupId)s kopsavilkuma", + "The room '%(roomName)s' could not be removed from the summary.": "Istabu '%(roomName)s' neizdevās dzēst no kopsavilkuma.", + "Leave Community": "Atstāt kopienu", + "Unable to leave room": "Nav iespējams atstāt istabu", + "Community Settings": "Kopienas iestatījumi", + "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Šīs istabas tiek rādītas kopienas dalībniekiem šīs kopienas lapā. Kopienas dalībnieki var pievienoties istabām, uzklikšķinot uz tām.", + "Your community hasn't got a Long Description, a HTML page to show to community members.
Click here to open settings and give it one!": "Jūsu kopienai nav plašāka HTML-lapas apraksta ko parādīt dalībniekiem.
Klikšķini šeit, lai atvērtu iestatījumus un to pievienotu!", + "Description": "Apraksts", + "Failed to load %(groupId)s": "Neizdevās ielādēt %(groupId)s", + "This Home server does not support communities": "Šis mitināšanas serveris neatbalsta kopienas", + "This room is not public. You will not be able to rejoin without an invite.": "Šīs istaba nav publiska. Tu nevari tajā ieiet bez uzaicinājuma.", + "Cryptography data migrated": "Sifrēšanas dati tika pārnesti", + "A one-off migration of cryptography data has been performed. End-to-end encryption will not work if you go back to an older version of Riot. If you need to use end-to-end cryptography on an older version, log out of Riot first. To retain message history, export and re-import your keys.": "Veikta vienreizēja šifrēšanas datu pārnese. Sifrēšana (end-to-end) nedarbosies, ja Tu atgriezīses pie vecākas Riot versijas. Ja nepieciešams izmantot end-to-end šifrēšanu, izmantojot vecāku versija, vispirms izraksties no Riot. Lai saglabātu ziņu vēsturi, eksportē un tad importē savas kripto-atslēgas.", + "Old cryptography data detected": "Tika uzieti novecojuši šifrēšanas dati", + "Data from an older version of Riot has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Uzieti dati no vecākas Riot versijas. Tas novedīs pie end-to-end šifrēšanas problēmām vecākajā versijā. Šajā versijā nevar tikt atšifrēti ziņojumi, kuri radīti izmantojot vecākajā versijā end-to-end šifrētas ziņas. Tas var arī novest pie ziņapmaiņas, kas veikta ar šo versiju. Ja rodas ķibeles, izraksties un par jaunu pieraksties sistēmā. Lai saglabātu ziņu vēsturi, eksportē un tad importē savas šifrēšanas atslēgas.", + "Create a community to group together users and rooms! Build a custom homepage to mark out your space in the Matrix universe.": "Radi kopienu, lai apvienotu lietotājus un istabas. Izveido mājaslapu, lai iezīmētu Matrix visumā savu klātbūtni, vietu un telpu.", + "Error whilst fetching joined communities": "Ielādējot kopienas radās kļūda", + "%(count)s of your messages have not been sent.|one": "Tava ziņa netika nosūtīta.", + "Show devices, send anyway or cancel.": "Parādīt ierīces, vienalga nosūtīt vai sūtīšanu atcelt.", + "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|one": "Atkārtoti nosūtīt ziņu vai atcelt sūtīšanu.", + "There's no one else here! Would you like to invite others or stop warning about the empty room?": "Šeit neviena nav. Ja vēlies kādu uzaicināt vai atslēgt paziņojumu par tukšu istabu?", + "Light theme": "Gaiša tēma", + "Dark theme": "Tumša tēma", + "Status.im theme": "Status.im tēma", + "Ignored Users": "Ignorētie lietotāji", + "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "Privātumu augstu respektējam, tādēļ nevācam nekādus personas un identificējamus datus analītikas mērķiem.", + "Learn more about how we use analytics.": "Sīkāk par to, kā tiek izmantota analītika.", + "An email has been sent to %(emailAddress)s. Once you've followed the link it contains, click below.": "Epasts ir nosūtīts uz %(emailAddress)s. Izmantojiet epastā nosūtīto tīmekļa saiti un tad noklišķiniet šeit zemāk.", + "Please note you are logging into the %(hs)s server, not matrix.org.": "Lūdzu ņem vērā, ka Tu pieraksties %(hs)s serverī, nevis matrix.org serverī.", + "This homeserver doesn't offer any login flows which are supported by this client.": "Šis bāzes serveris neatbalsta nevienu pierakstīšanās metodi, kuru piedāvā šis Riot klients.", + "Sign in to get started": "Pierakstīties, lai sāktu", + "Ignores a user, hiding their messages from you": "Ignorē lietotāju, Tev nerādot viņa sūtītās ziņas", + "Stops ignoring a user, showing their messages going forward": "Atceļ lietotāja ignorēšanu, rādot viņa turpmāk sūtītās ziņas", + "Notify the whole room": "Paziņot visai istabai", + "Room Notification": "Istabas paziņojums" } From e3f68f12c859e23342b6f7266338d9feb2655f50 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Mon, 12 Feb 2018 18:01:08 +0000 Subject: [PATCH 499/927] Add context menu to TagTile With two options: View Community and Remove, which removes the tag from the panel. --- src/actions/TagOrderActions.js | 47 ++++++++++++++++++++++++ src/components/views/elements/TagTile.js | 35 ++++++++++++++++++ src/i18n/strings/en_EN.json | 2 +- src/stores/TagOrderStore.js | 20 +++++++++- 4 files changed, 101 insertions(+), 3 deletions(-) diff --git a/src/actions/TagOrderActions.js b/src/actions/TagOrderActions.js index dd4df6a9d4..3504adb09b 100644 --- a/src/actions/TagOrderActions.js +++ b/src/actions/TagOrderActions.js @@ -56,4 +56,51 @@ TagOrderActions.moveTag = function(matrixClient, tag, destinationIx) { }); }; +/** + * Creates an action thunk that will do an asynchronous request to + * label a tag as removed in im.vector.web.tag_ordering account data. + * + * The reason this is implemented with new state `removedTags` is that + * we incrementally and initially populate `tags` with groups that + * have been joined. If we remove a group from `tags`, it will just + * get added (as it looks like a group we've recently joined). + * + * NB: If we ever support adding of tags (which is planned), we should + * take special care to remove the tag from `removedTags` when we add + * it. + * + * @param {MatrixClient} matrixClient the matrix client to set the + * account data on. + * @param {string} tag the tag to remove. + * @returns {function} an action thunk that will dispatch actions + * indicating the status of the request. + * @see asyncAction + */ +TagOrderActions.removeTag = function(matrixClient, tag) { + // Don't change tags, just removedTags + const tags = TagOrderStore.getOrderedTags(); + const removedTags = TagOrderStore.getRemovedTagsAccountData() || []; + + if (removedTags.includes(tag)) { + // Return a thunk that doesn't do anything, we don't even need + // an asynchronous action here, the tag is already removed. + return () => {}; + } + + removedTags.push(tag); + + const storeId = TagOrderStore.getStoreId(); + + return asyncAction('TagOrderActions.removeTag', () => { + Analytics.trackEvent('TagOrderActions', 'removeTag'); + return matrixClient.setAccountData( + 'im.vector.web.tag_ordering', + {tags, removedTags, _storeId: storeId}, + ); + }, () => { + // For an optimistic update + return {removedTags}; + }); +}; + export default TagOrderActions; diff --git a/src/components/views/elements/TagTile.js b/src/components/views/elements/TagTile.js index f52f758cc0..8d801d986d 100644 --- a/src/components/views/elements/TagTile.js +++ b/src/components/views/elements/TagTile.js @@ -21,6 +21,7 @@ import { MatrixClient } from 'matrix-js-sdk'; import sdk from '../../../index'; import dis from '../../../dispatcher'; import { isOnlyCtrlOrCmdIgnoreShiftKeyEvent } from '../../../Keyboard'; +import ContextualMenu from '../../structures/ContextualMenu'; import FlairStore from '../../../stores/FlairStore'; @@ -81,6 +82,35 @@ export default React.createClass({ }); }, + onContextButtonClick: function(e) { + e.preventDefault(); + e.stopPropagation(); + + // Hide the (...) immediately + this.setState({ hover: false }); + + const TagTileContextMenu = sdk.getComponent('context_menus.TagTileContextMenu'); + const elementRect = e.target.getBoundingClientRect(); + + // The window X and Y offsets are to adjust position when zoomed in to page + const x = elementRect.right + window.pageXOffset + 3; + const chevronOffset = 12; + let y = (elementRect.top + (elementRect.height / 2) + window.pageYOffset); + y = y - (chevronOffset + 8); // where 8 is half the height of the chevron + + const self = this; + ContextualMenu.createMenu(TagTileContextMenu, { + chevronOffset: chevronOffset, + left: x, + top: y, + tag: this.props.tag, + onFinished: function() { + self.setState({ menuDisplayed: false }); + }, + }); + this.setState({ menuDisplayed: true }); + }, + onMouseOver: function() { this.setState({hover: true}); }, @@ -109,10 +139,15 @@ export default React.createClass({ const tip = this.state.hover ? :
; + const contextButton = this.state.hover || this.state.menuDisplayed ? +
+ { "\u00B7\u00B7\u00B7" } +
:
; return
{ tip } + { contextButton }
; }, diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 6139ac2a91..3cfbe24122 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -500,8 +500,8 @@ "Download %(text)s": "Download %(text)s", "Invalid file%(extra)s": "Invalid file%(extra)s", "Error decrypting image": "Error decrypting image", - "Image '%(Body)s' cannot be displayed.": "Image '%(Body)s' cannot be displayed.", "This image cannot be displayed.": "This image cannot be displayed.", + "Image '%(Body)s' cannot be displayed.": "Image '%(Body)s' cannot be displayed.", "Error decrypting video": "Error decrypting video", "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s changed the avatar for %(roomName)s", "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s removed the room avatar.", diff --git a/src/stores/TagOrderStore.js b/src/stores/TagOrderStore.js index 69b22797fb..3ec751d075 100644 --- a/src/stores/TagOrderStore.js +++ b/src/stores/TagOrderStore.js @@ -55,6 +55,7 @@ class TagOrderStore extends Store { const tagOrderingEventContent = tagOrderingEvent ? tagOrderingEvent.getContent() : {}; this._setState({ orderedTagsAccountData: tagOrderingEventContent.tags || null, + removedTagsAccountData: tagOrderingEventContent.removedTags || null, hasSynced: true, }); this._updateOrderedTags(); @@ -70,6 +71,7 @@ class TagOrderStore extends Store { this._setState({ orderedTagsAccountData: payload.event_content ? payload.event_content.tags : null, + removedTagsAccountData: payload.event_content ? payload.event_content.removedTags : null, }); this._updateOrderedTags(); break; @@ -90,6 +92,14 @@ class TagOrderStore extends Store { }); break; } + case 'TagOrderActions.removeTag.pending': { + // Optimistic update of a removed tag + this._setState({ + removedTagsAccountData: payload.request.removedTags, + }); + this._updateOrderedTags(); + break; + } case 'select_tag': { let newTags = []; // Shift-click semantics @@ -165,13 +175,15 @@ class TagOrderStore extends Store { _mergeGroupsAndTags() { const groupIds = this._state.joinedGroupIds || []; const tags = this._state.orderedTagsAccountData || []; + const removedTags = this._state.removedTagsAccountData || []; + const tagsToKeep = tags.filter( - (t) => t[0] !== '+' || groupIds.includes(t), + (t) => (t[0] !== '+' || groupIds.includes(t)) && !removedTags.includes(t), ); const groupIdsToAdd = groupIds.filter( - (groupId) => !tags.includes(groupId), + (groupId) => !tags.includes(groupId) && !removedTags.includes(groupId), ); return tagsToKeep.concat(groupIdsToAdd); @@ -181,6 +193,10 @@ class TagOrderStore extends Store { return this._state.orderedTags; } + getRemovedTagsAccountData() { + return this._state.removedTagsAccountData; + } + getStoreId() { // Generate a random ID to prevent this store from clobbering its // state with redundant remote echos. From 7a4c1994c327e4616a801c0a5d4aa1495fbdbb67 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Mon, 12 Feb 2018 18:35:13 +0000 Subject: [PATCH 500/927] Use Boolean() instead of assuming filter is based on truthiness --- src/components/views/rooms/RoomList.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index 269f04c963..4a491c8a03 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -371,7 +371,7 @@ module.exports = React.createClass({ return; } - return isRoomVisible[taggedRoom.roomId]; + return Boolean(isRoomVisible[taggedRoom.roomId]); }); }); From 3eeef064bf5e7abaca367f2c62dce174d9707644 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Mon, 12 Feb 2018 18:37:54 +0000 Subject: [PATCH 501/927] Remove unused asyncId --- src/actions/actionCreators.js | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/actions/actionCreators.js b/src/actions/actionCreators.js index 697930414c..967ce609e7 100644 --- a/src/actions/actionCreators.js +++ b/src/actions/actionCreators.js @@ -33,28 +33,25 @@ limitations under the License. * `${id}.failure`. * * The shape of each are: - * { action: '${id}.pending', request, asyncId } - * { action: '${id}.success', result, asyncId } - * { action: '${id}.failure', err, asyncId } + * { action: '${id}.pending', request } + * { action: '${id}.success', result } + * { action: '${id}.failure', err } * - * where `request` is returned by `pendingFn`, result - * is the result of the promise returned by `fn` and - * `asyncId` is a unique ID for each dispatch of the - * asynchronous action. + * where `request` is returned by `pendingFn` and + * result is the result of the promise returned by + * `fn`. */ export function asyncAction(id, fn, pendingFn) { return (dispatch) => { - const asyncId = Math.random().toString(16).slice(2, 10); dispatch({ action: id + '.pending', request: typeof pendingFn === 'function' ? pendingFn() : undefined, - asyncId, }); fn().then((result) => { - dispatch({action: id + '.success', result, asyncId}); + dispatch({action: id + '.success', result}); }).catch((err) => { - dispatch({action: id + '.failure', err, asyncId}); + dispatch({action: id + '.failure', err}); }); }; } From 322012cf889c00fe5b2bc790a01c52e6ca1e689e Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Mon, 12 Feb 2018 18:46:36 +0000 Subject: [PATCH 502/927] Add comment to explain hacky optimism --- src/stores/RoomListStore.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/stores/RoomListStore.js b/src/stores/RoomListStore.js index 193784811c..b71e1c5cc1 100644 --- a/src/stores/RoomListStore.js +++ b/src/stores/RoomListStore.js @@ -79,6 +79,11 @@ class RoomListStore extends Store { } break; case 'RoomListActions.tagRoom.pending': { + // XXX: we only show one optimistic update at any one time. + // Ideally we should be making a list of in-flight requests + // that are backed by transaction IDs. Until the js-sdk + // supports this, we're stuck with only being able to use + // the most recent optimistic update. this._generateRoomLists(payload.request); } break; From 5e9368e794eac546569d93ae2738bd24566cdc74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Mon, 12 Feb 2018 21:13:53 +0100 Subject: [PATCH 503/927] Add comments explaining our non standard usage of aria-described-by --- src/components/views/dialogs/BaseDialog.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/components/views/dialogs/BaseDialog.js b/src/components/views/dialogs/BaseDialog.js index 08fd972621..053aef66c3 100644 --- a/src/components/views/dialogs/BaseDialog.js +++ b/src/components/views/dialogs/BaseDialog.js @@ -76,6 +76,12 @@ export default React.createClass({ className={this.props.className} role="dialog" aria-labelledby='mx_BaseDialog_title' + // This should point to a node describing the dialog. + // If we were about to completelly follow this recommendation we'd need to + // make all the components relying on BaseDialog to be aware of it. + // So instead we will use the whole content as the description. + // Description comes first and if the content contains more text, + // AT users can skip its presentation. aria-describedby={this.props.contentId} > Date: Tue, 13 Feb 2018 09:44:00 +0000 Subject: [PATCH 504/927] Move groups button to TagPanel --- src/components/structures/TagPanel.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/components/structures/TagPanel.js b/src/components/structures/TagPanel.js index 49a7a4020a..f10936e802 100644 --- a/src/components/structures/TagPanel.js +++ b/src/components/structures/TagPanel.js @@ -111,8 +111,7 @@ const TagPanel = React.createClass({ }, render() { - const AccessibleButton = sdk.getComponent('elements.AccessibleButton'); - const TintableSvg = sdk.getComponent('elements.TintableSvg'); + const GroupsButton = sdk.getComponent('elements.GroupsButton'); const DNDTagTile = sdk.getComponent('elements.DNDTagTile'); const tags = this.state.orderedTags.map((tag, index) => { @@ -142,9 +141,9 @@ const TagPanel = React.createClass({ ) } - - - +
+ +
; }, }); From 493116b17e57d56036a896ef60ab9886ebb97112 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 13 Feb 2018 11:43:22 +0000 Subject: [PATCH 505/927] Give the login page its spinner back --- src/components/structures/login/Login.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/structures/login/Login.js b/src/components/structures/login/Login.js index 5042ca1fd0..7f4aa0325a 100644 --- a/src/components/structures/login/Login.js +++ b/src/components/structures/login/Login.js @@ -431,10 +431,10 @@ module.exports = React.createClass({ // FIXME: remove status.im theme tweaks const theme = SettingsStore.getValue("theme"); if (theme !== "status") { - header =

{ _t('Sign in') }

; + header =

{ _t('Sign in') } { loader }

; } else { if (!this.state.errorText) { - header =

{ _t('Sign in to get started') }

; + header =

{ _t('Sign in to get started') } { loader }

; } } From 8377abcd1987a34cecbb3b363f807731f5dd861e Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 13 Feb 2018 11:49:59 +0000 Subject: [PATCH 506/927] Store component state for editors to prevent a forceUpdate from /sync causing the editors to revert before the user had a chance to hit "Save". Part of fixing https://github.com/vector-im/riot-web/issues/6019 --- src/components/views/rooms/RoomNameEditor.js | 21 ++++++++++++++--- src/components/views/rooms/RoomTopicEditor.js | 23 +++++++++++++++---- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/src/components/views/rooms/RoomNameEditor.js b/src/components/views/rooms/RoomNameEditor.js index 5c224d79c0..d073a0be25 100644 --- a/src/components/views/rooms/RoomNameEditor.js +++ b/src/components/views/rooms/RoomNameEditor.js @@ -29,13 +29,21 @@ module.exports = React.createClass({ room: PropTypes.object.isRequired, }, + getInitialState: function() { + return { + name: null, + }; + }, + componentWillMount: function() { const room = this.props.room; const name = room.currentState.getStateEvents('m.room.name', ''); const myId = MatrixClientPeg.get().credentials.userId; const defaultName = room.getDefaultRoomName(myId); - this._initialName = name ? name.getContent().name : ''; + this.setState({ + name: name ? name.getContent().name : '', + }); this._placeholderName = _t("Unnamed Room"); if (defaultName && defaultName !== 'Empty room') { // default name from JS SDK, needs no translation as we don't ever show it. @@ -44,7 +52,13 @@ module.exports = React.createClass({ }, getRoomName: function() { - return this.refs.editor.getValue(); + return this.state.name; + }, + + _onValueChanged: function(value, shouldSubmit) { + this.setState({ + name: value, + }); }, render: function() { @@ -57,7 +71,8 @@ module.exports = React.createClass({ placeholderClassName="mx_RoomHeader_placeholder" placeholder={this._placeholderName} blurToCancel={false} - initialValue={this._initialName} + initialValue={this.state.name} + onValueChanged={this._onValueChanged} dir="auto" />
); diff --git a/src/components/views/rooms/RoomTopicEditor.js b/src/components/views/rooms/RoomTopicEditor.js index 8f950d625c..7ad02f264c 100644 --- a/src/components/views/rooms/RoomTopicEditor.js +++ b/src/components/views/rooms/RoomTopicEditor.js @@ -28,26 +28,41 @@ module.exports = React.createClass({ room: PropTypes.object.isRequired, }, + getInitialState: function() { + return { + topic: null, + }; + }, + componentWillMount: function() { const room = this.props.room; const topic = room.currentState.getStateEvents('m.room.topic', ''); - this._initialTopic = topic ? topic.getContent().topic : ''; + this.setState({ + topic: topic ? topic.getContent().topic : '', + }); }, getTopic: function() { - return this.refs.editor.getValue(); + return this.state.topic; + }, + + _onValueChanged: function(value) { + this.setState({ + topic: value, + }); }, render: function() { const EditableText = sdk.getComponent("elements.EditableText"); return ( - ); }, From 36e8bf1f20661c380bec1ad5a2337f914480cd0a Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 13 Feb 2018 14:13:47 +0000 Subject: [PATCH 507/927] Change CSS class for message panel spinner to stop scrollbars appearing when we - jump to a message or, - permalink that is to an not paginated in event --- src/components/structures/TimelinePanel.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/structures/TimelinePanel.js b/src/components/structures/TimelinePanel.js index 4ade78af85..12f745146e 100644 --- a/src/components/structures/TimelinePanel.js +++ b/src/components/structures/TimelinePanel.js @@ -1121,9 +1121,9 @@ var TimelinePanel = React.createClass({ // exist. if (this.state.timelineLoading) { return ( -
- -
+
+ +
); } From 5af560f625ef48000063c1a5b9ee3b060bf6d46e Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 13 Feb 2018 14:43:34 +0000 Subject: [PATCH 508/927] Make removedTags a Set for perf --- src/stores/TagOrderStore.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/stores/TagOrderStore.js b/src/stores/TagOrderStore.js index 3ec751d075..78e4a6e95d 100644 --- a/src/stores/TagOrderStore.js +++ b/src/stores/TagOrderStore.js @@ -175,15 +175,15 @@ class TagOrderStore extends Store { _mergeGroupsAndTags() { const groupIds = this._state.joinedGroupIds || []; const tags = this._state.orderedTagsAccountData || []; - const removedTags = this._state.removedTagsAccountData || []; + const removedTags = new Set(this._state.removedTagsAccountData || []); const tagsToKeep = tags.filter( - (t) => (t[0] !== '+' || groupIds.includes(t)) && !removedTags.includes(t), + (t) => (t[0] !== '+' || groupIds.includes(t)) && !removedTags.has(t), ); const groupIdsToAdd = groupIds.filter( - (groupId) => !tags.includes(groupId) && !removedTags.includes(groupId), + (groupId) => !tags.includes(groupId) && !removedTags.has(groupId), ); return tagsToKeep.concat(groupIdsToAdd); From f16bc93fee1c46dddf90f323d82e1646fab4b5a4 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 13 Feb 2018 16:09:17 +0000 Subject: [PATCH 509/927] If a tag is unrecognised, assume manual ordering (as we did previously) Fixes https://github.com/vector-im/riot-web/issues/6135 --- src/stores/RoomListStore.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/stores/RoomListStore.js b/src/stores/RoomListStore.js index b71e1c5cc1..693275952b 100644 --- a/src/stores/RoomListStore.js +++ b/src/stores/RoomListStore.js @@ -176,12 +176,13 @@ class RoomListStore extends Store { listOrders[order].forEach((listKey) => { let comparator; switch (order) { - case "manual": - comparator = this._getManualComparator(listKey, optimisticRequest); - break; case "recent": comparator = this._recentsComparator; break; + case "manual": + default: + comparator = this._getManualComparator(listKey, optimisticRequest); + break; } lists[listKey].sort(comparator); }); From 06b18dda1856b45b9d17a2f7c1707cbcbddbcb78 Mon Sep 17 00:00:00 2001 From: Ralitsa Bozhkova Date: Tue, 13 Feb 2018 17:23:42 +0000 Subject: [PATCH 510/927] Added translation using Weblate (Bulgarian) --- src/i18n/strings/bg.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/i18n/strings/bg.json diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/src/i18n/strings/bg.json @@ -0,0 +1 @@ +{} From bee0a952c37c1d7c6abc3b2092430f4fc815affa Mon Sep 17 00:00:00 2001 From: Ralitsa Bozhkova Date: Tue, 13 Feb 2018 18:57:09 +0000 Subject: [PATCH 511/927] Translated using Weblate (Bulgarian) Currently translated at 0.2% (2 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/bg/ --- src/i18n/strings/bg.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json index 0967ef424b..1300a32895 100644 --- a/src/i18n/strings/bg.json +++ b/src/i18n/strings/bg.json @@ -1 +1,4 @@ -{} +{ + "OK": "ОК", + "Operation failed": "Операцията е неуспешна" +} From 02e0663409b965bcc165dcf8703aadbc8ae80c20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sim=C3=B3=20Albert=20i=20Beltran?= Date: Tue, 13 Feb 2018 18:44:58 +0000 Subject: [PATCH 512/927] Translated using Weblate (Catalan) Currently translated at 88.3% (871 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ca/ --- src/i18n/strings/ca.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/ca.json b/src/i18n/strings/ca.json index 1ff3e7f8e9..0b1a7b10ef 100644 --- a/src/i18n/strings/ca.json +++ b/src/i18n/strings/ca.json @@ -376,7 +376,7 @@ "Idle for %(duration)s": "Inactiu durant %(duration)s", "Offline for %(duration)s": "Desconnectat durant %(duration)s", "Unknown for %(duration)s": "Desconegut durant %(duration)s", - "Online": "En línia", + "Online": "Conectat", "Idle": "Inactiu", "Offline": "Desconnectat", "Unknown": "Desconegut", From ed871cbd83987e6f2492327f8df7d6a308e17293 Mon Sep 17 00:00:00 2001 From: Walter Date: Tue, 13 Feb 2018 18:55:45 +0000 Subject: [PATCH 513/927] Translated using Weblate (Russian) Currently translated at 100.0% (986 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index e7cc2f2319..d24ee71de1 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -536,7 +536,7 @@ "Drop file here to upload": "Перетащите файл сюда для отправки", " (unsupported)": " (не поддерживается)", "Ongoing conference call%(supportedText)s.": "Установлен групповой вызов %(supportedText)s.", - "Online": "В сети", + "Online": "Онлайн", "Idle": "Неактивен", "Offline": "Не в сети", "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s сменил аватар комнаты на ", From db2f6f863a8c63ec434c4cd11b7fa52cae846ea5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sim=C3=B3=20Albert=20i=20Beltran?= Date: Tue, 13 Feb 2018 18:00:22 +0000 Subject: [PATCH 514/927] Translated using Weblate (Spanish) Currently translated at 58.1% (573 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/es/ --- src/i18n/strings/es.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/es.json b/src/i18n/strings/es.json index 1b513cc51f..ccfd6f7761 100644 --- a/src/i18n/strings/es.json +++ b/src/i18n/strings/es.json @@ -571,5 +571,6 @@ "Nov": "Nov", "Dec": "Dic", "Warning": "Advertencia", - "Unpin Message": "Desmarcar Mensaje" + "Unpin Message": "Desmarcar Mensaje", + "Online": "Conectado" } From 3020c8cd94a08210070a7633bfa35a93a049c367 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 14 Feb 2018 11:23:29 +0000 Subject: [PATCH 515/927] Fix custom tags not being ordered manually Actually fixes vector-im/riot-web#6135 unlike #1748, which incorrectly assumed that custom tags would be included in listOrders. This fix makes sure that the `default` case in the `switch` is actually used. --- src/stores/RoomListStore.js | 42 ++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/src/stores/RoomListStore.js b/src/stores/RoomListStore.js index 693275952b..fdd9ca6692 100644 --- a/src/stores/RoomListStore.js +++ b/src/stores/RoomListStore.js @@ -160,32 +160,26 @@ class RoomListStore extends Store { }); const listOrders = { - "manual": [ - "m.favourite", - ], - "recent": [ - "im.vector.fake.invite", - "im.vector.fake.recent", - "im.vector.fake.direct", - "m.lowpriority", - "im.vector.fake.archived", - ], + "m.favourite": "manual", + "im.vector.fake.invite": "recent", + "im.vector.fake.recent": "recent", + "im.vector.fake.direct": "recent", + "m.lowpriority": "recent", + "im.vector.fake.archived": "recent", }; - Object.keys(listOrders).forEach((order) => { - listOrders[order].forEach((listKey) => { - let comparator; - switch (order) { - case "recent": - comparator = this._recentsComparator; - break; - case "manual": - default: - comparator = this._getManualComparator(listKey, optimisticRequest); - break; - } - lists[listKey].sort(comparator); - }); + Object.keys(lists).forEach((listKey) => { + let comparator; + switch (listOrders[listKey]) { + case "recent": + comparator = this._recentsComparator; + break; + case "manual": + default: + comparator = this._getManualComparator(listKey, optimisticRequest); + break; + } + lists[listKey].sort(comparator); }); this._setState({ From db4f0cb0bffc091df477899f00eded9c265bedc7 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 14 Feb 2018 16:40:24 +0000 Subject: [PATCH 516/927] Handle adding previously removed tags --- src/actions/TagOrderActions.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/actions/TagOrderActions.js b/src/actions/TagOrderActions.js index 3504adb09b..38bada2228 100644 --- a/src/actions/TagOrderActions.js +++ b/src/actions/TagOrderActions.js @@ -35,6 +35,7 @@ const TagOrderActions = {}; TagOrderActions.moveTag = function(matrixClient, tag, destinationIx) { // Only commit tags if the state is ready, i.e. not null let tags = TagOrderStore.getOrderedTags(); + let removedTags = TagOrderStore.getRemovedTagsAccountData(); if (!tags) { return; } @@ -42,17 +43,19 @@ TagOrderActions.moveTag = function(matrixClient, tag, destinationIx) { tags = tags.filter((t) => t !== tag); tags = [...tags.slice(0, destinationIx), tag, ...tags.slice(destinationIx)]; + removedTags = removedTags.filter((t) => t !== tag); + const storeId = TagOrderStore.getStoreId(); return asyncAction('TagOrderActions.moveTag', () => { Analytics.trackEvent('TagOrderActions', 'commitTagOrdering'); return matrixClient.setAccountData( 'im.vector.web.tag_ordering', - {tags, _storeId: storeId}, + {tags, removedTags, _storeId: storeId}, ); }, () => { // For an optimistic update - return {tags}; + return {tags, removedTags}; }); }; From b626420eb93e4f25333cd5c98758d7d3cc586265 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 14 Feb 2018 16:40:58 +0000 Subject: [PATCH 517/927] Move DND context to LoggedInView so that we can drag things from any part of the logged in app to another. (Specifically GroupView and TagPanel). --- src/components/structures/LoggedInView.js | 70 +++++++++++++++++++---- 1 file changed, 60 insertions(+), 10 deletions(-) diff --git a/src/components/structures/LoggedInView.js b/src/components/structures/LoggedInView.js index d7fe699156..f6bbfd247b 100644 --- a/src/components/structures/LoggedInView.js +++ b/src/components/structures/LoggedInView.js @@ -19,6 +19,7 @@ limitations under the License. import * as Matrix from 'matrix-js-sdk'; import React from 'react'; import PropTypes from 'prop-types'; +import { DragDropContext } from 'react-beautiful-dnd'; import { KeyCode, isOnlyCtrlOrCmdKeyEvent } from '../../Keyboard'; import Notifier from '../../Notifier'; @@ -30,6 +31,9 @@ import sessionStore from '../../stores/SessionStore'; import MatrixClientPeg from '../../MatrixClientPeg'; import SettingsStore from "../../settings/SettingsStore"; +import TagOrderActions from '../../actions/TagOrderActions'; +import RoomListActions from '../../actions/RoomListActions'; + /** * This is what our MatrixChat shows when we are logged in. The precise view is * determined by the page_type property. @@ -207,6 +211,50 @@ const LoggedInView = React.createClass({ } }, + _onDragEnd: function(result) { + // Dragged to an invalid destination, not onto a droppable + if (!result.destination) { + return; + } + + const dest = result.destination.droppableId; + + if (dest === 'tag-panel-droppable') { + // Could be "GroupTile +groupId:domain" + const draggableId = result.draggableId.split(' ').pop(); + + // Dispatch synchronously so that the TagPanel receives an + // optimistic update from TagOrderStore before the previous + // state is shown. + dis.dispatch(TagOrderActions.moveTag( + this._matrixClient, + draggableId, + result.destination.index, + ), true); + } else if (dest.startsWith('room-sub-list-droppable_')) { + this._onRoomTileEndDrag(result); + } + }, + + _onRoomTileEndDrag: function(result) { + let newTag = result.destination.droppableId.split('_')[1]; + let prevTag = result.source.droppableId.split('_')[1]; + if (newTag === 'undefined') newTag = undefined; + if (prevTag === 'undefined') prevTag = undefined; + + const roomId = result.draggableId.split('_')[1]; + + const oldIndex = result.source.index; + const newIndex = result.destination.index; + + dis.dispatch(RoomListActions.tagRoom( + this._matrixClient, + this._matrixClient.getRoom(roomId), + prevTag, newTag, + oldIndex, newIndex, + ), true); + }, + render: function() { const LeftPanel = sdk.getComponent('structures.LeftPanel'); const RightPanel = sdk.getComponent('structures.RightPanel'); @@ -328,16 +376,18 @@ const LoggedInView = React.createClass({ return (
{ topBar } -
- -
- { page_element } -
- { right_panel } -
+ +
+ +
+ { page_element } +
+ { right_panel } +
+
); }, From 74c8a74e7d2106057b9c1e368914146c8d2ad8d3 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 14 Feb 2018 16:43:01 +0000 Subject: [PATCH 518/927] Add Droppable to GroupView to contain the GroupTiles as Draggables --- src/components/structures/MyGroups.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/components/structures/MyGroups.js b/src/components/structures/MyGroups.js index 22157beaca..4c9229a2ea 100644 --- a/src/components/structures/MyGroups.js +++ b/src/components/structures/MyGroups.js @@ -17,6 +17,7 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; import GeminiScrollbar from 'react-gemini-scrollbar'; +import { Droppable } from 'react-beautiful-dnd'; import sdk from '../../index'; import { _t } from '../../languageHandler'; import dis from '../../dispatcher'; @@ -74,7 +75,13 @@ export default withMatrixClient(React.createClass({ contentHeader = groupNodes.length > 0 ?

{ _t('Your Communities') }

:
; content = groupNodes.length > 0 ? - { groupNodes } + + { (provided, snapshot) => ( +
+ { groupNodes } +
+ ) } +
:
{ _t( From 3850b552a5bddb753d21da3634d30914ed1f520f Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 14 Feb 2018 16:46:06 +0000 Subject: [PATCH 519/927] Make GroupTile avatar draggable --- src/components/views/groups/GroupTile.js | 32 +++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/src/components/views/groups/GroupTile.js b/src/components/views/groups/GroupTile.js index ce426a9b78..70947afa65 100644 --- a/src/components/views/groups/GroupTile.js +++ b/src/components/views/groups/GroupTile.js @@ -17,10 +17,12 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; import {MatrixClient} from 'matrix-js-sdk'; +import { Draggable } from 'react-beautiful-dnd'; import sdk from '../../../index'; import dis from '../../../dispatcher'; import FlairStore from '../../../stores/FlairStore'; + const GroupTile = React.createClass({ displayName: 'GroupTile', @@ -78,9 +80,33 @@ const GroupTile = React.createClass({ profile.avatarUrl, avatarHeight, avatarHeight, "crop", ) : null; return -
- -
+ + { (provided, snapshot) => ( +
+
+
+ +
+
+ { /* Instead of a blank placeholder, use a copy of the avatar itself. */ } + { provided.placeholder ? +
+ +
: +
+ } +
+ ) } +
{ name }
{ descElement } From 389d96bc46047bf2791b2fc6bf8200d68f7673ed Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 14 Feb 2018 16:47:29 +0000 Subject: [PATCH 520/927] Use optimistic removedTagsAccountData state in TagOrderStore when receiving TagOrderActions.moveTag.pending, which now exposes this state. --- src/stores/TagOrderStore.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/stores/TagOrderStore.js b/src/stores/TagOrderStore.js index 78e4a6e95d..eef078d8da 100644 --- a/src/stores/TagOrderStore.js +++ b/src/stores/TagOrderStore.js @@ -89,6 +89,7 @@ class TagOrderStore extends Store { // Optimistic update of a moved tag this._setState({ orderedTags: payload.request.tags, + removedTagsAccountData: payload.request.removedTags, }); break; } From 3948ee8ca14d5f00f2a0163a692569f303be9811 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 14 Feb 2018 17:53:54 +0000 Subject: [PATCH 521/927] Give each GroupTile avatar its own droppable so that they can be dragged and dropped without interacting with each other, as they would do if GroupView contained one droppable to contain them all. --- src/components/structures/MyGroups.js | 13 ++---- src/components/views/groups/GroupTile.js | 56 +++++++++++++----------- 2 files changed, 35 insertions(+), 34 deletions(-) diff --git a/src/components/structures/MyGroups.js b/src/components/structures/MyGroups.js index 4c9229a2ea..116607fb08 100644 --- a/src/components/structures/MyGroups.js +++ b/src/components/structures/MyGroups.js @@ -17,7 +17,6 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; import GeminiScrollbar from 'react-gemini-scrollbar'; -import { Droppable } from 'react-beautiful-dnd'; import sdk from '../../index'; import { _t } from '../../languageHandler'; import dis from '../../dispatcher'; @@ -74,14 +73,10 @@ export default withMatrixClient(React.createClass({ }); contentHeader = groupNodes.length > 0 ?

{ _t('Your Communities') }

:
; content = groupNodes.length > 0 ? - - - { (provided, snapshot) => ( -
- { groupNodes } -
- ) } -
+ +
+ { groupNodes } +
:
{ _t( diff --git a/src/components/views/groups/GroupTile.js b/src/components/views/groups/GroupTile.js index 70947afa65..f1dbb75988 100644 --- a/src/components/views/groups/GroupTile.js +++ b/src/components/views/groups/GroupTile.js @@ -17,7 +17,7 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; import {MatrixClient} from 'matrix-js-sdk'; -import { Draggable } from 'react-beautiful-dnd'; +import { Draggable, Droppable } from 'react-beautiful-dnd'; import sdk from '../../../index'; import dis from '../../../dispatcher'; import FlairStore from '../../../stores/FlairStore'; @@ -80,33 +80,39 @@ const GroupTile = React.createClass({ profile.avatarUrl, avatarHeight, avatarHeight, "crop", ) : null; return - - { (provided, snapshot) => ( -
-
+ { (droppableProvided, droppableSnapshot) => ( +
+ -
- -
-
- { /* Instead of a blank placeholder, use a copy of the avatar itself. */ } - { provided.placeholder ? -
- -
: -
- } + { (provided, snapshot) => ( +
+
+
+ +
+
+ { /* Instead of a blank placeholder, use a copy of the avatar itself. */ } + { provided.placeholder ? +
+ +
: +
+ } +
+ ) } +
) } - +
{ name }
{ descElement } From a4c7da63afe4a58551a8497c221e91e1d97fdeec Mon Sep 17 00:00:00 2001 From: Ralitsa Bozhkova Date: Thu, 15 Feb 2018 10:47:20 +0000 Subject: [PATCH 522/927] Translated using Weblate (Bulgarian) Currently translated at 4.6% (46 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/bg/ --- src/i18n/strings/bg.json | 46 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json index 1300a32895..a05100dd3f 100644 --- a/src/i18n/strings/bg.json +++ b/src/i18n/strings/bg.json @@ -1,4 +1,48 @@ { "OK": "ОК", - "Operation failed": "Операцията е неуспешна" + "Operation failed": "Операцията е неуспешна", + "Search": "Търсене", + "Custom Server Options": "Потребителски опции за сървър", + "Dismiss": "Отказ", + "powered by Matrix": "базирано на Matrix", + "Warning": "Предупреждение", + "Error": "Грешка", + "Remove": "Премахни", + "Close": "Затвори", + "Cancel": "Отказ", + "Send": "Изпрати", + "Edit": "Редактирай", + "Continue": "Продължи", + "Failed to change password. Is your password correct?": "Неуспешна промяна. Правилно ли сте въвели Вашата парола?", + "Unpin Message": "Откачи съобщението", + "Sun": "нд.", + "Mon": "пн.", + "Tue": "вт.", + "Wed": "ср.", + "Thu": "чт.", + "Fri": "пт.", + "Sat": "сб.", + "Jan": "ян.", + "Feb": "февр.", + "Mar": "март", + "Apr": "апр.", + "May": "май", + "Jun": "юни", + "Jul": "юли", + "Aug": "авг.", + "Sep": "септ.", + "Oct": "окт.", + "Nov": "ноем.", + "Dec": "дек.", + "%(weekDayName)s %(time)s": "%(weekDayName)s %(time)s", + "%(weekDayName)s, %(monthName)s %(day)s %(time)s": "%(weekDayName)s, %(day)s %(monthName)s %(time)s", + "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(day)s %(monthName)s %(fullYear)s, %(weekDayName)s", + "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s %(time)s": "%(weekDayName)s, %(day)s %(monthName)s %(fullYear)s %(time)s", + "Online": "Онлайн", + "Failed to remove tag %(tagName)s from room": "Неуспешно премахване на %(tagName)s етикет от стаята", + "unknown error code": "неизвестен код за грешка", + "Failed to forget room %(errCode)s": "Не успешно забравяне на стаята %(errCode)s", + "Mute": "Заглуши", + "Leave": "Напусни", + "Favourite": "Любим" } From ceec40551908db8b35a0bd33d9fff6aa01b83b87 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 15 Feb 2018 11:23:00 +0000 Subject: [PATCH 523/927] Remove RoomListStore listener This caused the the RoomList component to leak (although in practice only accross logins because that's the only time it's unmounted) --- package.json | 2 +- src/components/views/rooms/RoomList.js | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index bb8db64d28..9d5013de28 100644 --- a/package.json +++ b/package.json @@ -128,7 +128,7 @@ "require-json": "0.0.1", "rimraf": "^2.4.3", "sinon": "^1.17.3", - "source-map-loader": "^0.1.5", + "source-map-loader": "^0.1.6", "walk": "^2.3.9", "webpack": "^1.12.14" } diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index 4a491c8a03..41a200420d 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -191,6 +191,10 @@ module.exports = React.createClass({ this._tagStoreToken.remove(); } + if (this._roomListStoreToken) { + this._roomListStoreToken.remove(); + } + if (this._groupStoreTokens.length > 0) { // NB: GroupStore is not a Flux.Store this._groupStoreTokens.forEach((token) => token.unregister()); From 44964e80a9c3f8974be669b9bf453375649ea986 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 15 Feb 2018 11:25:40 +0000 Subject: [PATCH 524/927] undo unintentional commit --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9d5013de28..bb8db64d28 100644 --- a/package.json +++ b/package.json @@ -128,7 +128,7 @@ "require-json": "0.0.1", "rimraf": "^2.4.3", "sinon": "^1.17.3", - "source-map-loader": "^0.1.6", + "source-map-loader": "^0.1.5", "walk": "^2.3.9", "webpack": "^1.12.14" } From 39af04f09048d872beef7c0059148aa7cd978d2c Mon Sep 17 00:00:00 2001 From: Ralitsa Bozhkova Date: Thu, 15 Feb 2018 13:18:15 +0000 Subject: [PATCH 525/927] Translated using Weblate (Bulgarian) Currently translated at 5.5% (55 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/bg/ --- src/i18n/strings/bg.json | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json index a05100dd3f..6ce4acf267 100644 --- a/src/i18n/strings/bg.json +++ b/src/i18n/strings/bg.json @@ -44,5 +44,14 @@ "Failed to forget room %(errCode)s": "Не успешно забравяне на стаята %(errCode)s", "Mute": "Заглуши", "Leave": "Напусни", - "Favourite": "Любим" + "Favourite": "Любим", + "Register": "Регистрация", + "Notifications": "Известия", + "Rooms": "Стаи", + "Add rooms to this community": "Добави стаи в това общество", + "Unnamed room": "Ненаименувана стая", + "World readable": "Четимо за всички", + "Guests can join": "Гости могат да се присъединят", + "No rooms to show": "Няма стаи, които да бъдат показани", + "Failed to add tag %(tagName)s to room": "Неуспешно добавяне на %(tagName)s етикет в стаята" } From 57419a7f8d485c621b6de0a85467a499874c3c45 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 15 Feb 2018 14:11:45 +0000 Subject: [PATCH 526/927] Give emptySubListTip a container for correct bg colour --- src/components/views/rooms/RoomList.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index 4a491c8a03..e53b7b6536 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -544,17 +544,20 @@ module.exports = React.createClass({ const RoomDirectoryButton = sdk.getComponent('elements.RoomDirectoryButton'); const CreateRoomButton = sdk.getComponent('elements.CreateRoomButton'); + let tip = null; + switch (section) { case 'im.vector.fake.direct': - return
+ tip =
{ _t( "Press to start a chat with someone", {}, { 'StartChatButton': }, ) }
; + break; case 'im.vector.fake.recent': - return
+ tip =
{ _t( "You're not in any rooms yet! Press to make a room or"+ " to browse the directory", @@ -565,6 +568,13 @@ module.exports = React.createClass({ }, ) }
; + break; + } + + if (tip) { + return
+ { tip } +
; } // We don't want to display drop targets if there are no room tiles to drag'n'drop From 19b6684089e7a50e5bb80ed2bc8ba4c7d6e6961e Mon Sep 17 00:00:00 2001 From: Ralitsa Bozhkova Date: Thu, 15 Feb 2018 14:50:16 +0000 Subject: [PATCH 527/927] Translated using Weblate (Bulgarian) Currently translated at 7.0% (70 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/bg/ --- src/i18n/strings/bg.json | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json index 6ce4acf267..7574c0278f 100644 --- a/src/i18n/strings/bg.json +++ b/src/i18n/strings/bg.json @@ -53,5 +53,20 @@ "World readable": "Четимо за всички", "Guests can join": "Гости могат да се присъединят", "No rooms to show": "Няма стаи, които да бъдат показани", - "Failed to add tag %(tagName)s to room": "Неуспешно добавяне на %(tagName)s етикет в стаята" + "Failed to add tag %(tagName)s to room": "Неуспешно добавяне на %(tagName)s етикет в стаята", + "This email address is already in use": "Този имейл адрес е вече зает", + "This phone number is already in use": "Този телефонен номер е вече зает", + "Failed to verify email address: make sure you clicked the link in the email": "Неуспешно потвърждаване на имейл адреса: уверете се, че сте кликнали върху връзката в имейла", + "The platform you're on": "Платформата, която използвате", + "The version of Riot.im": "Версията на Riot.im", + "Whether or not you're logged in (we don't record your user name)": "Независимо дали сте в профила си или не (не записваме Вашето потребителско име)", + "Your language of choice": "Вашият език по избор", + "Which officially provided instance you are using, if any": "Коя официално предоставена инстанция използвате, ако има такава", + "Whether or not you're using the Richtext mode of the Rich Text Editor": "Независимо дали използвате Richtext режим на Rich Text Editor", + "Your homeserver's URL": "Адрес на Вашия Home сървър", + "Your identity server's URL": "Адрес на Вашия сървър за самоличност", + "Analytics": "Статистика", + "The information being sent to us to help make Riot.im better includes:": "За да направи Riot по-добър, информацията изпратена до нас включва:", + "Call Failed": "Неуспешно повикване", + "Call": "Обаждане" } From 07b691a45d14fa817fe9d08d8ed1ecc2886b313c Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Thu, 15 Feb 2018 20:20:19 +0000 Subject: [PATCH 528/927] typo --- src/components/views/messages/MFileBody.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/messages/MFileBody.js b/src/components/views/messages/MFileBody.js index c324c291e7..90efe24df3 100644 --- a/src/components/views/messages/MFileBody.js +++ b/src/components/views/messages/MFileBody.js @@ -82,7 +82,7 @@ Tinter.registerTintable(updateTintedDownloadImage); // downloaded. This limit does not seem to apply when the url is used as // the source attribute of an image tag. // -// Blob URLs are generated using window.URL.createObjectURL and unforuntately +// Blob URLs are generated using window.URL.createObjectURL and unfortunately // for our purposes they inherit the origin of the page that created them. // This means that any scripts that run when the URL is viewed will be able // to access local storage. From b111a824e88fc4ceb29ec03ef7c2765480ada2d1 Mon Sep 17 00:00:00 2001 From: Ralitsa Bozhkova Date: Thu, 15 Feb 2018 19:36:52 +0000 Subject: [PATCH 529/927] Translated using Weblate (Bulgarian) Currently translated at 12.0% (119 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/bg/ --- src/i18n/strings/bg.json | 53 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json index 7574c0278f..948181fa9d 100644 --- a/src/i18n/strings/bg.json +++ b/src/i18n/strings/bg.json @@ -49,7 +49,7 @@ "Notifications": "Известия", "Rooms": "Стаи", "Add rooms to this community": "Добави стаи в това общество", - "Unnamed room": "Ненаименувана стая", + "Unnamed room": "Стая без име", "World readable": "Четимо за всички", "Guests can join": "Гости могат да се присъединят", "No rooms to show": "Няма стаи, които да бъдат показани", @@ -68,5 +68,54 @@ "Analytics": "Статистика", "The information being sent to us to help make Riot.im better includes:": "За да направи Riot по-добър, информацията изпратена до нас включва:", "Call Failed": "Неуспешно повикване", - "Call": "Обаждане" + "Call": "Обаждане", + "Answer": "Отговори, приеми", + "You are already in a call.": "Вече сте в разговор.", + "VoIP is unsupported": "Не се поддържа VoIP", + "You cannot place VoIP calls in this browser.": "Не може да осъществите VoIP разговори в този браузър.", + "You cannot place a call with yourself.": "Не може да осъществите разговор със себе си.", + "Existing Call": "Съществуващ разговор", + "Conference calls are not supported in this client": "Групови разговори не се поддържат в тази програма", + "Conference calls are not supported in encrypted rooms": "Групови разговори не се поддържат в шифровани стаи", + "Warning!": "Внимание!", + "Conference calling is in development and may not be reliable.": "Груповите разговори са в процес на разработка и не са надеждни.", + "Review Devices": "Преглед на устройства", + "Failed to set up conference call": "Неуспешно осъществяване на групов чат", + "Conference call failed.": "Неуспешен групов разговор.", + "The file '%(fileName)s' failed to upload": "Неуспешно качване на файл '%(fileName)s'", + "The file '%(fileName)s' exceeds this home server's size limit for uploads": "Файлът '%(fileName)s' надхвърля ограничението на размера за качвания на този Home сървър", + "Upload Failed": "Качването е неуспешно", + "PM": "PM", + "AM": "AM", + "Who would you like to add to this community?": "Кой бихте желали да добавите в това общество?", + "Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "Предупреждение: Всеки човек, който добавяте в дадено общество, ще бъде публично видим за знаещите идентификатора на обществото", + "Invite new community members": "Покани нови членове на обществото", + "Name or matrix ID": "Име или matrix ID", + "Invite to Community": "Покани в обществото", + "Which rooms would you like to add to this community?": "Кои стаи бихте желали да добавите в това общество?", + "Show these rooms to non-members on the community page and room list?": "Показване на тези стаи на не-членове на страницата на обществата и списъка със стаи?", + "Add rooms to the community": "Добави стаи в обществото", + "Room name or alias": "Име или псевдоним на стая", + "Add to community": "Добави в обществото", + "Failed to invite the following users to %(groupId)s:": "Следните потребители не могат да бъдат поканени в %(groupId)s:", + "Failed to invite users to community": "Потребителите не могат да бъдат поканени в обществото", + "Failed to invite users to %(groupId)s": "Потребителите не могат да бъдат поканени в %(groupId)s", + "Failed to add the following rooms to %(groupId)s:": "Следните стаи не могат да бъдат добавени в %(groupId)s:", + "Riot does not have permission to send you notifications - please check your browser settings": "Riot няма разрешение да Ви изпраща известия - моля проверете вашите настройки на браузъра", + "Riot was not given permission to send notifications - please try again": "Riot не е получил разрешение да изпраща известия - моля опитайте отново", + "Unable to enable Notifications": "Неупешно включване на известия", + "This email address was not found": "Този имейл адрес не беше открит", + "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Изглежда вашият имейл адрес не може да се асоциира с Matrix ID на този Home сървър.", + "Default": "По подразбиране", + "Restricted": "Ограничен", + "Moderator": "Модератор", + "Admin": "Администратор", + "Start a chat": "Започване на чат", + "Who would you like to communicate with?": "С кой бихте желали да си комуникирате?", + "Email, name or matrix ID": "Имейл, име или matrix ID", + "Start Chat": "Започни чат", + "Invite new room members": "Покани нови членове на стаята", + "Who would you like to add to this room?": "Кой бихте желали да добавите в тази стая?", + "Send Invites": "Изпрати покани", + "Failed to invite user": "Неуспешна покана на потребителя" } From 94a0a904574ba3e63bf80dffc381db2f20842747 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Fri, 16 Feb 2018 14:16:50 +0000 Subject: [PATCH 530/927] Make RoomListStore aware of Room.timeline events so that we can do reorderings of lists ordered by most recent event. No optimisations here; we only update for timeline events on live timelines that could update the "unread count". --- src/actions/MatrixActionCreators.js | 10 ++++++ src/components/views/rooms/RoomList.js | 9 ------ src/stores/RoomListStore.js | 43 +++++++++++++++++--------- 3 files changed, 39 insertions(+), 23 deletions(-) diff --git a/src/actions/MatrixActionCreators.js b/src/actions/MatrixActionCreators.js index dbfe910533..27fbb6dda5 100644 --- a/src/actions/MatrixActionCreators.js +++ b/src/actions/MatrixActionCreators.js @@ -66,6 +66,15 @@ function createRoomTagsAction(matrixClient, roomTagsEvent, room) { return { action: 'MatrixActions.Room.tags', room }; } +function createRoomTimelineAction(matrixClient, timelineEvent, room, toStartOfTimeline, removed, data) { + return { + action: 'MatrixActions.Room.timeline', + event: timelineEvent, + isLiveEvent: data.liveEvent, + room, + }; +} + function createRoomMembershipAction(matrixClient, membershipEvent, member, oldMembership) { return { action: 'MatrixActions.RoomMember.membership', member }; } @@ -87,6 +96,7 @@ export default { this._addMatrixClientListener(matrixClient, 'sync', createSyncAction); this._addMatrixClientListener(matrixClient, 'accountData', createAccountDataAction); this._addMatrixClientListener(matrixClient, 'Room.tags', createRoomTagsAction); + this._addMatrixClientListener(matrixClient, 'Room.timeline', createRoomTimelineAction); this._addMatrixClientListener(matrixClient, 'RoomMember.membership', createRoomMembershipAction); }, diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index 41a200420d..bab8054c60 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -76,7 +76,6 @@ module.exports = React.createClass({ cli.on("Room", this.onRoom); cli.on("deleteRoom", this.onDeleteRoom); - cli.on("Room.timeline", this.onRoomTimeline); cli.on("Room.name", this.onRoomName); cli.on("Room.receipt", this.onRoomReceipt); cli.on("RoomState.events", this.onRoomStateEvents); @@ -177,7 +176,6 @@ module.exports = React.createClass({ if (MatrixClientPeg.get()) { MatrixClientPeg.get().removeListener("Room", this.onRoom); MatrixClientPeg.get().removeListener("deleteRoom", this.onDeleteRoom); - MatrixClientPeg.get().removeListener("Room.timeline", this.onRoomTimeline); MatrixClientPeg.get().removeListener("Room.name", this.onRoomName); MatrixClientPeg.get().removeListener("Room.receipt", this.onRoomReceipt); MatrixClientPeg.get().removeListener("RoomState.events", this.onRoomStateEvents); @@ -236,13 +234,6 @@ module.exports = React.createClass({ this._updateStickyHeaders(true, scrollToPosition); }, - onRoomTimeline: function(ev, room, toStartOfTimeline, removed, data) { - if (toStartOfTimeline) return; - if (!room) return; - if (data.timeline.getTimelineSet() !== room.getUnfilteredTimelineSet()) return; - this._delayedRefreshRoomList(); - }, - onRoomReceipt: function(receiptEvent, room) { // because if we read a notification, it will affect notification count // only bother updating if there's a receipt from us diff --git a/src/stores/RoomListStore.js b/src/stores/RoomListStore.js index fdd9ca6692..707a9da17e 100644 --- a/src/stores/RoomListStore.js +++ b/src/stores/RoomListStore.js @@ -23,6 +23,16 @@ import Unread from '../Unread'; * the RoomList. */ class RoomListStore extends Store { + + static _listOrders = { + "m.favourite": "manual", + "im.vector.fake.invite": "recent", + "im.vector.fake.recent": "recent", + "im.vector.fake.direct": "recent", + "m.lowpriority": "recent", + "im.vector.fake.archived": "recent", + }; + constructor() { super(dis); @@ -68,6 +78,14 @@ class RoomListStore extends Store { this._generateRoomLists(); } break; + case 'MatrixActions.Room.timeline': { + if (!this._state.ready || + !payload.isLiveEvent || + !this._eventTriggersRecentReorder(payload.event) + ) break; + this._generateRoomLists(); + } + break; case 'MatrixActions.accountData': { if (payload.event_type !== 'm.direct') break; this._generateRoomLists(); @@ -159,18 +177,9 @@ class RoomListStore extends Store { } }); - const listOrders = { - "m.favourite": "manual", - "im.vector.fake.invite": "recent", - "im.vector.fake.recent": "recent", - "im.vector.fake.direct": "recent", - "m.lowpriority": "recent", - "im.vector.fake.archived": "recent", - }; - Object.keys(lists).forEach((listKey) => { let comparator; - switch (listOrders[listKey]) { + switch (RoomListStore._listOrders[listKey]) { case "recent": comparator = this._recentsComparator; break; @@ -188,13 +197,17 @@ class RoomListStore extends Store { }); } + _eventTriggersRecentReorder(ev) { + return ev.getTs() && ( + Unread.eventTriggersUnreadCount(ev) || + ev.getSender() === this._matrixClient.credentials.userId + ); + } + _tsOfNewestEvent(room) { for (let i = room.timeline.length - 1; i >= 0; --i) { const ev = room.timeline[i]; - if (ev.getTs() && - (Unread.eventTriggersUnreadCount(ev) || - (ev.getSender() === this._matrixClient.credentials.userId)) - ) { + if (this._eventTriggersRecentReorder(ev)) { return ev.getTs(); } } @@ -210,6 +223,8 @@ class RoomListStore extends Store { } _recentsComparator(roomA, roomB) { + // XXX: We could use a cache here and update it when we see new + // events that trigger a reorder return this._tsOfNewestEvent(roomB) - this._tsOfNewestEvent(roomA); } From 84ab1ae3e2996157c358f0ca152669585be93863 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Fri, 16 Feb 2018 15:52:15 +0000 Subject: [PATCH 531/927] Do not assume that tags have been removed when moving tags --- src/actions/TagOrderActions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/actions/TagOrderActions.js b/src/actions/TagOrderActions.js index 38bada2228..a257ff16d8 100644 --- a/src/actions/TagOrderActions.js +++ b/src/actions/TagOrderActions.js @@ -35,7 +35,7 @@ const TagOrderActions = {}; TagOrderActions.moveTag = function(matrixClient, tag, destinationIx) { // Only commit tags if the state is ready, i.e. not null let tags = TagOrderStore.getOrderedTags(); - let removedTags = TagOrderStore.getRemovedTagsAccountData(); + let removedTags = TagOrderStore.getRemovedTagsAccountData() || []; if (!tags) { return; } From cca820c3538ae6e806fd6929b34f728eaf35d109 Mon Sep 17 00:00:00 2001 From: Ralitsa Bozhkova Date: Fri, 16 Feb 2018 11:48:04 +0000 Subject: [PATCH 532/927] Translated using Weblate (Bulgarian) Currently translated at 15.2% (150 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/bg/ --- src/i18n/strings/bg.json | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json index 948181fa9d..5df65775fe 100644 --- a/src/i18n/strings/bg.json +++ b/src/i18n/strings/bg.json @@ -117,5 +117,36 @@ "Invite new room members": "Покани нови членове на стаята", "Who would you like to add to this room?": "Кой бихте желали да добавите в тази стая?", "Send Invites": "Изпрати покани", - "Failed to invite user": "Неуспешна покана на потребителя" + "Failed to invite user": "Неуспешна покана на потребителя", + "Failed to invite": "Неуспешна покана", + "Failed to invite the following users to the %(roomName)s room:": "Следните потребителите не успяха да бъдат добавени в %(roomName)s:", + "You need to be logged in.": "Трябва да влезете в профила си.", + "You need to be able to invite users to do that.": "Трябва да имате право да добавите потребители, за да извършите това.", + "Unable to create widget.": "Неуспешно създаване на приспособление.", + "Failed to send request.": "Неуспешно изпращане на запитване.", + "This room is not recognised.": "Стаята не е разпозната.", + "Power level must be positive integer.": "Нивото на достъп трябва да бъде позитивно число.", + "Call Anyway": "Обади се въпреки това", + "Answer Anyway": "Отговори въпреки това", + "Call Timeout": "Изтекло време за повикване", + "The remote side failed to pick up": "Отсрещната страна не успя да отговори", + "Unable to capture screen": "Неуспешно заснемане на екрана", + "You are not in this room.": "Не сте в тази стая.", + "You do not have permission to do that in this room.": "Нямате достъп да направите това в тази стая.", + "Missing room_id in request": "Липсва room_id в заявката", + "Room %(roomId)s not visible": "Стая %(roomId)s не е видима", + "Missing user_id in request": "Липсва user_id в заявката", + "Failed to lookup current room": "Неуспешно намиране на текущата стая", + "/ddg is not a command": "/ddg не е команда", + "To use it, just wait for autocomplete results to load and tab through them.": "За използване, изчакайте зареждането на списъка с предложения и изберете от него.", + "Unrecognised room alias:": "Непознат псевдоним на стая:", + "Ignored user": "Игнориран потребител", + "You are now ignoring %(userId)s": "Вече игнорирате %(userId)s", + "Unignored user": "Неигнориран потребител", + "You are no longer ignoring %(userId)s": "Вече не игнорирате %(userId)s", + "Device already verified!": "Устройството е вече верифицирано!", + "WARNING: Device already verified, but keys do NOT MATCH!": "ВНИМАНИЕ: Устройстовото е верифицирано, но ключовете не съвпадат!", + "Verified key": "Верифициран ключ", + "Unrecognised command:": "Неразпозната команда:", + "Reason": "Причина" } From f2903d1439eb62cdc97dca0b2eb71ed586c39472 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 16 Feb 2018 08:45:19 +0000 Subject: [PATCH 533/927] Translated using Weblate (Finnish) Currently translated at 95.2% (939 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fi/ --- src/i18n/strings/fi.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/fi.json b/src/i18n/strings/fi.json index fc7eac51a7..48a8ea755f 100644 --- a/src/i18n/strings/fi.json +++ b/src/i18n/strings/fi.json @@ -561,7 +561,7 @@ "Sep": "syyskuu", "Oct": "lokakuu", "Nov": "marraskuu", - "Dec": "jolukuu", + "Dec": "joulukuu", "User names may only contain letters, numbers, dots, hyphens and underscores.": "Käyttäjänimet voivat sisältää vain kirjaimia, numeroita, pisteitä, viivoja ja alaviivoja.", "To continue, please enter your password.": "Ole hyvä ja syötä salasanasi jatkaaksesi.", "Verifies a user, device, and pubkey tuple": "Varmentaa käyttäjän, laitteen ja julkisen avaimen kolmikon", From 3f6c15506c4116cb7bbe016c167d8d759842ab1f Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Fri, 16 Feb 2018 16:17:47 +0000 Subject: [PATCH 534/927] Remove unused `room` parameter of MatrixActions.Room.timeline --- src/actions/MatrixActionCreators.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/actions/MatrixActionCreators.js b/src/actions/MatrixActionCreators.js index 27fbb6dda5..a9ea671fbe 100644 --- a/src/actions/MatrixActionCreators.js +++ b/src/actions/MatrixActionCreators.js @@ -71,7 +71,6 @@ function createRoomTimelineAction(matrixClient, timelineEvent, room, toStartOfTi action: 'MatrixActions.Room.timeline', event: timelineEvent, isLiveEvent: data.liveEvent, - room, }; } From cbeee72062c6e9f4fb7fb3e24b91beb92454d1f6 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 16 Feb 2018 10:11:04 -0700 Subject: [PATCH 535/927] Don't show empty custom tags when filtering tags Signed-off-by: Travis Ralston --- src/components/views/rooms/RoomList.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index 41a200420d..68b171b0ee 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -34,6 +34,7 @@ import RoomListStore from '../../../stores/RoomListStore'; import GroupStoreCache from '../../../stores/GroupStoreCache'; const HIDE_CONFERENCE_CHANS = true; +const STANDARD_TAGS_REGEX = /^(m\.(favourite|lowpriority)|im\.vector\.fake\.(invite|recent|direct|archived))$/; function phraseForSection(section) { switch (section) { @@ -365,7 +366,7 @@ module.exports = React.createClass({ }); Object.keys(lists).forEach((tagName) => { - filteredLists[tagName] = lists[tagName].filter((taggedRoom) => { + const filteredRooms = lists[tagName].filter((taggedRoom) => { // Somewhat impossible, but guard against it anyway if (!taggedRoom) { return; @@ -377,6 +378,10 @@ module.exports = React.createClass({ return Boolean(isRoomVisible[taggedRoom.roomId]); }); + + if (filteredRooms.length > 0 || tagName.match(STANDARD_TAGS_REGEX)) { + filteredLists[tagName] = filteredRooms; + } }); return filteredLists; @@ -682,7 +687,7 @@ module.exports = React.createClass({ onShowMoreRooms={self.onShowMoreRooms} /> { Object.keys(self.state.lists).map((tagName) => { - if (!tagName.match(/^(m\.(favourite|lowpriority)|im\.vector\.fake\.(invite|recent|direct|archived))$/)) { + if (!tagName.match(STANDARD_TAGS_REGEX)) { return Date: Fri, 16 Feb 2018 17:43:24 +0000 Subject: [PATCH 536/927] Implement global filter to deselect all tags and make TagPanel scrollable whilst we're at it. --- src/components/structures/TagPanel.js | 51 +++++++++++++++++---------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/src/components/structures/TagPanel.js b/src/components/structures/TagPanel.js index 6e3bcf521b..74b6656b79 100644 --- a/src/components/structures/TagPanel.js +++ b/src/components/structures/TagPanel.js @@ -17,6 +17,7 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; import { MatrixClient } from 'matrix-js-sdk'; +import GeminiScrollbar from 'react-gemini-scrollbar'; import TagOrderStore from '../../stores/TagOrderStore'; import GroupActions from '../../actions/GroupActions'; @@ -93,9 +94,14 @@ const TagPanel = React.createClass({ dis.dispatch({action: 'view_create_group'}); }, + onLogoClick(ev) { + dis.dispatch({action: 'deselect_tags'}); + }, + render() { const GroupsButton = sdk.getComponent('elements.GroupsButton'); const DNDTagTile = sdk.getComponent('elements.DNDTagTile'); + const AccessibleButton = sdk.getComponent('elements.AccessibleButton'); const tags = this.state.orderedTags.map((tag, index) => { return ; }); return
- - { (provided, snapshot) => ( -
- { tags } - { provided.placeholder } -
- ) } -
+ + + +
+ + + { (provided, snapshot) => ( +
+ { tags } + { provided.placeholder } +
+ ) } +
+
+
From 7a0c82a327b7df5e28160c10cfd89fb55ee9b798 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Fri, 16 Feb 2018 18:08:29 +0000 Subject: [PATCH 537/927] Fix click background to deselect --- src/components/structures/TagPanel.js | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/components/structures/TagPanel.js b/src/components/structures/TagPanel.js index 74b6656b79..d614588ccc 100644 --- a/src/components/structures/TagPanel.js +++ b/src/components/structures/TagPanel.js @@ -84,8 +84,6 @@ const TagPanel = React.createClass({ }, onClick(e) { - // Ignore clicks on children - if (e.target !== e.currentTarget) return; dis.dispatch({action: 'deselect_tags'}); }, @@ -116,7 +114,11 @@ const TagPanel = React.createClass({
- + { tags } { provided.placeholder } From 2d5a2a9d48b3c7446cb00a2b3c8014b4edac3b11 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Fri, 16 Feb 2018 23:59:48 +0000 Subject: [PATCH 538/927] improve origin check of ScalarMessaging postmessage API. ensures that https://scalar.ve can't access the API. many thanks to @rugk for pointing out the potential vuln. cc @rxl881 in case this bug has been transplanted elsewhere. --- src/ScalarMessaging.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ScalarMessaging.js b/src/ScalarMessaging.js index 3c164c6551..fc8ee9edf6 100644 --- a/src/ScalarMessaging.js +++ b/src/ScalarMessaging.js @@ -563,7 +563,7 @@ const onMessage = function(event) { const url = SdkConfig.get().integrations_ui_url; if ( event.origin.length === 0 || - !url.startsWith(event.origin) || + !url.startsWith(event.origin + '/') || !event.data.action || event.data.api // Ignore messages with specific API set ) { From 32130fbc28bc315adae9cd88bc19226f9ff121a6 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Mon, 19 Feb 2018 09:56:03 +0000 Subject: [PATCH 539/927] Don't regenerate RoomListStore state for notifs/scrollback/etc. Only do so for the live timeline of rooms. --- src/actions/MatrixActionCreators.js | 2 ++ src/stores/RoomListStore.js | 1 + 2 files changed, 3 insertions(+) diff --git a/src/actions/MatrixActionCreators.js b/src/actions/MatrixActionCreators.js index a9ea671fbe..a307af6f57 100644 --- a/src/actions/MatrixActionCreators.js +++ b/src/actions/MatrixActionCreators.js @@ -71,6 +71,8 @@ function createRoomTimelineAction(matrixClient, timelineEvent, room, toStartOfTi action: 'MatrixActions.Room.timeline', event: timelineEvent, isLiveEvent: data.liveEvent, + isLiveUnfilteredRoomTimelineEvent: + room && data.timeline.getTimelineSet() === room.getUnfilteredTimelineSet(), }; } diff --git a/src/stores/RoomListStore.js b/src/stores/RoomListStore.js index 707a9da17e..8a3af309fc 100644 --- a/src/stores/RoomListStore.js +++ b/src/stores/RoomListStore.js @@ -81,6 +81,7 @@ class RoomListStore extends Store { case 'MatrixActions.Room.timeline': { if (!this._state.ready || !payload.isLiveEvent || + !payload.isLiveUnfilteredRoomTimelineEvent || !this._eventTriggersRecentReorder(payload.event) ) break; this._generateRoomLists(); From da35871cb1952255335ab502aebf2ad5939825f6 Mon Sep 17 00:00:00 2001 From: Ralitsa Bozhkova Date: Sun, 18 Feb 2018 20:21:27 +0000 Subject: [PATCH 540/927] Translated using Weblate (Bulgarian) Currently translated at 24.4% (241 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/bg/ --- src/i18n/strings/bg.json | 93 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 92 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json index 5df65775fe..ae049dff52 100644 --- a/src/i18n/strings/bg.json +++ b/src/i18n/strings/bg.json @@ -148,5 +148,96 @@ "WARNING: Device already verified, but keys do NOT MATCH!": "ВНИМАНИЕ: Устройстовото е верифицирано, но ключовете не съвпадат!", "Verified key": "Верифициран ключ", "Unrecognised command:": "Неразпозната команда:", - "Reason": "Причина" + "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.": "VoIP конференцията приключи.", + "%(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 и още един човек пишат", + "%(names)s and %(lastPerson)s are typing": "%(names)s и %(lastPerson)s пишат", + "Failure to create room": "Неуспешно създаване на стая", + "Server may be unavailable, overloaded, or you hit a bug.": "Сървърът може би е претоварен, недостъпен или се натъкнахте на проблем.", + "Send anyway": "Изпрати така или иначе", + "Unnamed Room": "Стая без име", + "Your browser does not support the required cryptography extensions": "Вашият браузър не поддържа необходимите разширения за шифроване", + "Not a valid Riot keyfile": "Невалиден Riot ключов файл", + "Authentication check failed: incorrect password?": "Неуспешна автентикация: неправилна парола?", + "Failed to join room": "Неуспешно присъединяване към стаята", + "Message Replies": "Отговори на съобщението", + "Message Pinning": "Закачания на съобщението", + "Presence Management": "Управление на присъствието", + "Tag Panel": "Панел с етикети", + "Disable Emoji suggestions while typing": "Деактивиране на предложенията за емотиконите при писане", + "Use compact timeline layout": "Използване на компактно оформление за списъка със съобщения", + "Hide removed messages": "Скриване на премахнати съобщения", + "Hide join/leave messages (invites/kicks/bans unaffected)": "Скриване на съобщения присъединяване/напускане (покани/изгонвания/блокиране незасегнати)", + "Hide avatar changes": "Скриване промени на аватара", + "Hide display name changes": "Скриване промени на името", + "Hide read receipts": "Скриване", + "Show timestamps in 12 hour format (e.g. 2:30pm)": "Показване на времето в 12-часов формат (напр. 2:30pm)", + "Always show message timestamps": "Винаги показвай времето", + "Autoplay GIFs and videos": "Автоматично възпроизвеждане на GIF-файлове и видеа", + "Enable automatic language detection for syntax highlighting": "Активиране на автоматичното разпознаване на език за подчертаване на синтаксиса", + "Disable big emoji in chat": "Деактивиране на големи емотикони в чата", + "Don't send typing notifications": "Не изпращай известия за писане", + "Automatically replace plain text Emoji": "Автоматично откриване и заместване на емотикони в текста", + "Mirror local video feed": "Огледален образ", + "Disable Peer-to-Peer for 1:1 calls": "Деактивиране на Peer-to-Peer в 1:1 разговор", + "Opt out of analytics": "Отказване от събиране на статистически данни", + "Never send encrypted messages to unverified devices from this device": "Никога не изпращай шифровани съобщения до непотвърдени устройства от това устройство", + "Never send encrypted messages to unverified devices in this room from this device": "Никога не изпращай шифровани съобщение до непотвърдени устройства в тази стая от това устройство", + "Enable inline URL previews by default": "Включване по подразбиране на URL прегледи", + "Enable URL previews for this room (only affects you)": "Включване на URL прегледи за тази стая (засяга само Вас)", + "Enable URL previews by default for participants in this room": "Включване по подразбиране на URL прегледи за участниците в тази стая", + "Room Colour": "Цвят на стая", + "Active call (%(roomName)s)": "Активен разговор (%(roomName)s)", + "unknown caller": "повикване от непознат", + "Incoming voice call from %(name)s": "Входящо гласово повикване от %(name)s", + "Incoming video call from %(name)s": "Входящо видео повикване от %(name)s", + "Incoming call from %(name)s": "Входящо повикване от %(name)s", + "Decline": "Откажи", + "Accept": "Приеми", + "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "Съобщение е изпратено до +%(msisdn)s. Моля въведете кода за потвърждение, което то съдържа", + "Incorrect verification code": "Неправилен код за потвърждение" } From 71a1de1e73e77367d8d51841bb312633a0b3ee4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sim=C3=B3=20Albert=20i=20Beltran?= Date: Sat, 17 Feb 2018 13:40:44 +0000 Subject: [PATCH 541/927] Translated using Weblate (Catalan) Currently translated at 89.2% (880 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ca/ --- src/i18n/strings/ca.json | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ca.json b/src/i18n/strings/ca.json index 0b1a7b10ef..120134e296 100644 --- a/src/i18n/strings/ca.json +++ b/src/i18n/strings/ca.json @@ -869,5 +869,14 @@ "Email": "Correu electrònic", "Add email address": "Afegeix correu electrònic", "I have verified my email address": "He verificat l'adreça de correu electrònic", - "Send Reset Email": "Envia email de reinici" + "Send Reset Email": "Envia email de reinici", + "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", + "Report it": "Informa", + "Found a bug?": "Has trobat un error?", + "Display name": "Nom visible", + "Identity Server is": "El servidor d'identitat es" } From 4998890a0ef656f2d5a979f3ed57a6e551bd40fe Mon Sep 17 00:00:00 2001 From: Ralitsa Bozhkova Date: Mon, 19 Feb 2018 16:12:43 +0000 Subject: [PATCH 542/927] Translated using Weblate (Bulgarian) Currently translated at 27.7% (274 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/bg/ --- src/i18n/strings/bg.json | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json index ae049dff52..d5dd208602 100644 --- a/src/i18n/strings/bg.json +++ b/src/i18n/strings/bg.json @@ -239,5 +239,38 @@ "Decline": "Откажи", "Accept": "Приеми", "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "Съобщение е изпратено до +%(msisdn)s. Моля въведете кода за потвърждение, което то съдържа", - "Incorrect verification code": "Неправилен код за потвърждение" + "Incorrect verification code": "Неправилен код за потвърждение", + "Enter Code": "Въведи код", + "Submit": "Изпрати", + "Phone": "Телефон", + "Add phone number": "Добави телефонен номер", + "Add": "Добави", + "Failed to upload profile picture!": "Неуспешно качване на профилна снимка!", + "Upload new:": "Качи нов:", + "No display name": "Няма име", + "New passwords don't match": "Новите пароли не съвпадат", + "Passwords can't be empty": "Полето с парола не може да е празно", + "Export E2E room keys": "Експортиране E2E ключове на стая", + "Do you want to set an email address?": "Искате ли да зададете имейл адрес?", + "Current password": "Текуща парола", + "Password": "Парола", + "New Password": "Нова парола", + "Confirm password": "Потвърждаване на парола", + "Change Password": "Смяна на парола", + "Your home server does not support device management.": "Вашият home сървър не поддръжа управление на устройства.", + "Unable to load device list": "Неуспешно зареждане на списък с устройства", + "Authentication": "Автентикация", + "Delete %(count)s devices|other": "Изтрий %(count)s устройства", + "Delete %(count)s devices|one": "Изтрий устройство", + "Device ID": "Идентификатор на устройство", + "Device Name": "Име на устройство", + "Last seen": "Последно видян", + "Select devices": "Избери устройства", + "Failed to set display name": "Неуспешно задаване на име", + "Disable Notifications": "Изключване на известия", + "Enable Notifications": "Включване на известия", + "Cannot add any more widgets": "Не могат да се добавят повече приспособления", + "The maximum permitted number of widgets have already been added to this room.": "Максимално разрешеният брой приспособления е вече добавен към тази стая.", + "Add a widget": "Добавяне на приспособление", + "Drop File Here": "Постави файл тук" } From 1c96c1f4d9262cabc1841f0504abc1aee10fc88f Mon Sep 17 00:00:00 2001 From: Ralitsa Bozhkova Date: Tue, 20 Feb 2018 10:17:13 +0000 Subject: [PATCH 543/927] Translated using Weblate (Bulgarian) Currently translated at 38.0% (375 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/bg/ --- src/i18n/strings/bg.json | 109 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 105 insertions(+), 4 deletions(-) diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json index d5dd208602..1c7c2026ed 100644 --- a/src/i18n/strings/bg.json +++ b/src/i18n/strings/bg.json @@ -144,9 +144,9 @@ "You are now ignoring %(userId)s": "Вече игнорирате %(userId)s", "Unignored user": "Неигнориран потребител", "You are no longer ignoring %(userId)s": "Вече не игнорирате %(userId)s", - "Device already verified!": "Устройството е вече верифицирано!", - "WARNING: Device already verified, but keys do NOT MATCH!": "ВНИМАНИЕ: Устройстовото е верифицирано, но ключовете не съвпадат!", - "Verified key": "Верифициран ключ", + "Device already verified!": "Устройството е вече потвърдено!", + "WARNING: Device already verified, but keys do NOT MATCH!": "ВНИМАНИЕ: Устройстовото е потвърдено, но ключовете не съвпадат!", + "Verified key": "Потвърден ключ", "Unrecognised command:": "Неразпозната команда:", "Reason": "Причина", "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s прие поканата за %(displayName)s.", @@ -272,5 +272,106 @@ "Cannot add any more widgets": "Не могат да се добавят повече приспособления", "The maximum permitted number of widgets have already been added to this room.": "Максимално разрешеният брой приспособления е вече добавен към тази стая.", "Add a widget": "Добавяне на приспособление", - "Drop File Here": "Постави файл тук" + "Drop File Here": "Пусни файла тук", + "Drop file here to upload": "Пуснете файла тук, за да се качи", + " (unsupported)": " (не се поддържа)", + "Join as voice or video.": "Присъединете се като voice или video.", + "Ongoing conference call%(supportedText)s.": "Текущ групов разговор %(supportedText)s.", + "%(senderName)s sent an image": "%(senderName)s изпрати снимка", + "%(senderName)s sent a video": "%(senderName)s изпрати видео", + "%(senderName)s uploaded a file": "%(senderName)s качи файл", + "Options": "Настройки", + "Undecryptable": "Невъзможно разшифроване", + "Encrypted by a verified device": "Шифровано от потвърдено устройство", + "Encrypted by an unverified device": "Шифровано от непотвърдено устройство", + "Unencrypted message": "Нешифровано съобщение", + "Please select the destination room for this message": "Моля изберете стаята, в която искате да изпратите това съобщение", + "Blacklisted": "В черен списък", + "Verified": "Потвърдено", + "Unverified": "Непотвърдено", + "device id: ": "идентификатор на устройството: ", + "Disinvite": "Отмени поканата", + "Kick": "Изгони", + "Disinvite this user?": "Отмени поканата към този потребител?", + "Kick this user?": "Изгони този потребител?", + "Failed to kick": "Неуспешно изгонване", + "Unban": "Отблокирай", + "Ban": "Блокирай", + "Unban this user?": "Отблокирай този потребител?", + "Ban this user?": "Блокирай този потребител?", + "Failed to ban user": "Неуспешно блокиране на потребителя", + "Failed to mute user": "Неуспешно заглушаване на потребителя", + "Failed to toggle moderator status": "Неуспешна промяна на статуса на модератора", + "Failed to change power level": "Неуспешна промяна на нивото на достъп", + "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.": "След като си намалите нивото на достъп, няма да можете да възвърнете тази промяна. Ако сте потребителя с най-малко привилегии в тази стая, ще бъде невъзможно да възвърнете своите привилегии.", + "Are you sure?": "Сигурни ли сте?", + "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Няма да можете да възвърнете тази промяна, тъй като повишавате този потребител да има същото ниво на достъп като Вашето.", + "No devices with registered encryption keys": "Няма устройства с регистрирани шифровани ключове", + "Devices": "Устройства", + "Unignore": "Премахни игнорирането", + "Ignore": "Игнориране", + "Mention": "Спомени", + "Direct chats": "Директни чатове", + "User Options": "Опции на потребителя", + "Invite": "Покани", + "Unmute": "Премахни заглушаването", + "Make Moderator": "Направи потребителя модератор", + "Admin Tools": "Инструменти на администратора", + "Level:": "Ниво:", + "and %(count)s others...|other": "и %(count)s други...", + "and %(count)s others...|one": "и още един...", + "Invited": "Поканен", + "Filter room members": "Филтриране на членовете в стаята", + "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (ниво на достъп %(powerLevelNumber)s)", + "Attachment": "Прикачване", + "Upload Files": "Качи файлове", + "Are you sure you want to upload the following files?": "Сигурни ли сте, че искате да качите тези файлове?", + "Encrypted room": "Шифрована стая", + "Unencrypted room": "Нешифрована стая", + "Hangup": "Затвори", + "Voice call": "Гласово повикване", + "Video call": "Видео повикване", + "Hide Apps": "Скрий приложенията", + "Show Apps": "Покани приложенията", + "Upload file": "Качи файл", + "Show Text Formatting Toolbar": "Показване на лентата с инструменти за форматиране на текст", + "Send an encrypted reply…": "Изпрати шифрован отговор…", + "Send a reply (unencrypted)…": "Отговори (нешифрованo)…", + "Send an encrypted message…": "Изпрати шифровано съобщение…", + "Send a message (unencrypted)…": "Изпрати съобщение (нешифровано)…", + "You do not have permission to post to this room": "Нямате разрешение да публикувате в тази стая", + "Turn Markdown on": "Включи Markdown", + "Turn Markdown off": "Изключи Markdown", + "Hide Text Formatting Toolbar": "Скриване на лентата с инструменти за форматиране на текст", + "Server error": "Сървърна грешка", + "Server unavailable, overloaded, or something else went wrong.": "Сървърът е недостъпен, претоварен или нещо друго се обърка.", + "Command error": "Грешка в командата", + "bold": "удебелен", + "italic": "курсивен", + "strike": "задраскан", + "underline": "подчертан", + "code": "код", + "quote": "цитат", + "bullet": "списък", + "numbullet": "номериран списък", + "Markdown is disabled": "Markdown е изключен", + "Markdown is enabled": "Markdown е включен", + "No pinned messages.": "Няма закачени съобщения.", + "Loading...": "Зареждане...", + "Pinned Messages": "Закачени съобщения", + "%(duration)ss": "%(duration)sсек", + "%(duration)sm": "%(duration)sмин", + "%(duration)sh": "%(duration)sч", + "%(duration)sd": "%(duration)sд", + "Online for %(duration)s": "Онлайн от %(duration)s", + "Idle for %(duration)s": "Неактивен от %(duration)s", + "Offline for %(duration)s": "Офлайн от %(duration)s", + "Unknown for %(duration)s": "Неизвестен от %(duration)s", + "Idle": "Неактивен", + "Offline": "Офлайн", + "Unknown": "Неизвестен", + "Replying": "Отговаря", + "Seen by %(userName)s at %(dateTime)s": "Видяно от %(userName)s в %(dateTime)s", + "Failed to set avatar.": "Неуспешно задаване на аватар.", + "Save": "Запази" } From c5ad486c57d59eef7044126be2f21fe36ae61748 Mon Sep 17 00:00:00 2001 From: Ralitsa Bozhkova Date: Mon, 19 Feb 2018 20:17:44 +0000 Subject: [PATCH 544/927] Translated using Weblate (Catalan) Currently translated at 89.2% (880 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ca/ --- src/i18n/strings/ca.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/ca.json b/src/i18n/strings/ca.json index 120134e296..40fbcc53b4 100644 --- a/src/i18n/strings/ca.json +++ b/src/i18n/strings/ca.json @@ -873,7 +873,7 @@ "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", + "%(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", "Report it": "Informa", "Found a bug?": "Has trobat un error?", From d21f55633dfb3d5f99cf8b58f37d969b85da736e Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 20 Feb 2018 14:03:43 +0000 Subject: [PATCH 545/927] Fix DMs being marked as with the current user ("me") Whilst testing various DM paths, @lukebarnard1 found that there were many failures to add the room as a DM against the correct user. It turned out most of the failures seen were because the user chosen was the current user. If the user accepted an invite it would often be marked as with themselves because we chose the sender of the join event as the DM user. This fix makes the DM room setting process the same for both the inviting client and the invited client. A RoomState.members event causes the DM room state to be set in the room, regardless of whether we are currently `joining` (see previous impl.) The two cases for setting a DM are: - this user accepting an invite with is_direct - this user inviting someone with is_direct This should handle all cases for setting DM state. --- src/components/structures/RoomView.js | 61 +++++++++++++++------------ 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 5304f38901..c827a63057 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -678,21 +678,40 @@ module.exports = React.createClass({ // refresh the conf call notification state this._updateConfCallNotification(); - // if we are now a member of the room, where we were not before, that - // means we have finished joining a room we were previously peeking - // into. - const me = MatrixClientPeg.get().credentials.userId; - if (this.state.joining && this.state.room.hasMembershipState(me, "join")) { - // Having just joined a room, check to see if it looks like a DM room, and if so, - // mark it as one. This is to work around the fact that some clients don't support - // is_direct. We should remove this once they do. - const me = this.state.room.getMember(MatrixClientPeg.get().credentials.userId); - if (Rooms.looksLikeDirectMessageRoom(this.state.room, me)) { - // XXX: There's not a whole lot we can really do if this fails: at best - // perhaps we could try a couple more times, but since it's a temporary - // compatability workaround, let's not bother. - Rooms.setDMRoom(this.state.room.roomId, me.events.member.getSender()).done(); - } + const me = this.state.room.getMember(MatrixClientPeg.get().credentials.userId); + if (!me || me.membership !== "join") { + return; + } + + // The user may have accepted an invite with is_direct set + if (me.events.member.getPrevContent().membership === "invite" && + me.events.member.getPrevContent().is_direct + ) { + // This is a DM with the sender of the invite event (which we assume + // preceded the join event) + Rooms.setDMRoom( + this.state.room.roomId, + me.events.member.getUnsigned().prev_sender, + ); + return; + } + + const invitedMembers = this.state.room.getMembersWithMembership("invite"); + const joinedMembers = this.state.room.getMembersWithMembership("join"); + + // There must be one invited member and one joined member + if (invitedMembers.length !== 1 || joinedMembers.length !== 1) { + return; + } + + // The user may have sent an invite with is_direct sent + const other = invitedMembers[0]; + if (other && + other.membership === "invite" && + other.events.member.getContent().is_direct + ) { + Rooms.setDMRoom(this.state.room.roomId, other.userId); + return; } }, 500), @@ -826,18 +845,6 @@ module.exports = React.createClass({ action: 'join_room', opts: { inviteSignUrl: signUrl }, }); - - // if this is an invite and has the 'direct' hint set, mark it as a DM room now. - if (this.state.room) { - const me = this.state.room.getMember(MatrixClientPeg.get().credentials.userId); - if (me && me.membership == 'invite') { - if (me.events.member.getContent().is_direct) { - // The 'direct' hint is there, so declare that this is a DM room for - // whoever invited us. - return Rooms.setDMRoom(this.state.room.roomId, me.events.member.getSender()); - } - } - } return Promise.resolve(); }); }, From bc15303358c58226c4ef47793d34276d58d9b1ee Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 20 Feb 2018 14:10:34 +0000 Subject: [PATCH 546/927] Factor out updateDmState --- src/components/structures/RoomView.js | 75 ++++++++++++++------------- 1 file changed, 39 insertions(+), 36 deletions(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index c827a63057..8ceba2a850 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -677,42 +677,7 @@ module.exports = React.createClass({ // a member state changed in this room // refresh the conf call notification state this._updateConfCallNotification(); - - const me = this.state.room.getMember(MatrixClientPeg.get().credentials.userId); - if (!me || me.membership !== "join") { - return; - } - - // The user may have accepted an invite with is_direct set - if (me.events.member.getPrevContent().membership === "invite" && - me.events.member.getPrevContent().is_direct - ) { - // This is a DM with the sender of the invite event (which we assume - // preceded the join event) - Rooms.setDMRoom( - this.state.room.roomId, - me.events.member.getUnsigned().prev_sender, - ); - return; - } - - const invitedMembers = this.state.room.getMembersWithMembership("invite"); - const joinedMembers = this.state.room.getMembersWithMembership("join"); - - // There must be one invited member and one joined member - if (invitedMembers.length !== 1 || joinedMembers.length !== 1) { - return; - } - - // The user may have sent an invite with is_direct sent - const other = invitedMembers[0]; - if (other && - other.membership === "invite" && - other.events.member.getContent().is_direct - ) { - Rooms.setDMRoom(this.state.room.roomId, other.userId); - return; - } + this._updateDMState(); }, 500), _checkIfAlone: function(room) { @@ -753,6 +718,44 @@ module.exports = React.createClass({ }); }, + _updateDMState() { + const me = this.state.room.getMember(MatrixClientPeg.get().credentials.userId); + if (!me || me.membership !== "join") { + return; + } + + // The user may have accepted an invite with is_direct set + if (me.events.member.getPrevContent().membership === "invite" && + me.events.member.getPrevContent().is_direct + ) { + // This is a DM with the sender of the invite event (which we assume + // preceded the join event) + Rooms.setDMRoom( + this.state.room.roomId, + me.events.member.getUnsigned().prev_sender, + ); + return; + } + + const invitedMembers = this.state.room.getMembersWithMembership("invite"); + const joinedMembers = this.state.room.getMembersWithMembership("join"); + + // There must be one invited member and one joined member + if (invitedMembers.length !== 1 || joinedMembers.length !== 1) { + return; + } + + // The user may have sent an invite with is_direct sent + const other = invitedMembers[0]; + if (other && + other.membership === "invite" && + other.events.member.getContent().is_direct + ) { + Rooms.setDMRoom(this.state.room.roomId, other.userId); + return; + } + }, + onSearchResultsResize: function() { dis.dispatch({ action: 'timeline_resize' }, true); }, From f227d13dfe701b4b96a2cfb1e1e75b3d868195bd Mon Sep 17 00:00:00 2001 From: Ralitsa Bozhkova Date: Tue, 20 Feb 2018 14:21:24 +0000 Subject: [PATCH 547/927] Translated using Weblate (Bulgarian) Currently translated at 43.8% (432 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/bg/ --- src/i18n/strings/bg.json | 63 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 3 deletions(-) diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json index 1c7c2026ed..f47b3b24ee 100644 --- a/src/i18n/strings/bg.json +++ b/src/i18n/strings/bg.json @@ -41,7 +41,7 @@ "Online": "Онлайн", "Failed to remove tag %(tagName)s from room": "Неуспешно премахване на %(tagName)s етикет от стаята", "unknown error code": "неизвестен код за грешка", - "Failed to forget room %(errCode)s": "Не успешно забравяне на стаята %(errCode)s", + "Failed to forget room %(errCode)s": "Неуспешно забравяне на стаята %(errCode)s", "Mute": "Заглуши", "Leave": "Напусни", "Favourite": "Любим", @@ -372,6 +372,63 @@ "Unknown": "Неизвестен", "Replying": "Отговаря", "Seen by %(userName)s at %(dateTime)s": "Видяно от %(userName)s в %(dateTime)s", - "Failed to set avatar.": "Неуспешно задаване на аватар.", - "Save": "Запази" + "Failed to set avatar.": "Неуспешно задаване на профилна снимка.", + "Save": "Запази", + "(~%(count)s results)|other": "(~%(count)s резултати)", + "(~%(count)s results)|one": "(~%(count)s резултат)", + "Join Room": "Присъедини се към стаята", + "Upload avatar": "Качи профилната снимка", + "Remove avatar": "Премахни профилната снимка", + "Settings": "Настройки", + "Forget room": "Забрави стаята", + "Show panel": "Покажи панелa", + "Drop here to favourite": "За любим пуснeте тук", + "Drop here to tag direct chat": "Пуснете тук, за да означите директен чат", + "Drop here to restore": "Пуснете тук за възстановяване", + "Drop here to demote": "Пуснете тук за", + "Drop here to tag %(section)s": "Пуснете тук, за да означите %(section)s", + "Failed to set direct chat tag": "Неуспешно означаване на директен чат", + "Press to start a chat with someone": "Натиснете , за да започнете чат с някого", + "You're not in any rooms yet! Press to make a room or to browse the directory": "Все още не сте в нито една стая! Натиснете , за да направите такава или , за да прегледате директорията", + "Community Invites": "Покани за общества", + "Invites": "Покани", + "Favourites": "Любими", + "People": "Хора", + "Low priority": "Нисък приоритет", + "Historical": "Архив", + "Unable to ascertain that the address this invite was sent to matches one associated with your account.": "Не може да се потвърди, че адреса към който е изпратена тази покана е обвързан с акаунта Ви.", + "This invitation was sent to an email address which is not associated with this account:": "Тази покана е изпратена на имейл адрес, който не е свързан с този профил:", + "You may wish to login with a different account, or add this email to this account.": "Може да искате да влезете с друг профил или да добавите този имейл в този профил.", + "You have been invited to join this room by %(inviterName)s": "Вие сте поканен да се присъедините към тази стая от %(inviterName)s", + "Would you like to accept or decline this invitation?": "Желаете да приемете или да откажете тази покана?", + "Reason: %(reasonText)s": "Причина: %(reasonText)s", + "Rejoin": "Повторно присъединяване", + "You have been kicked from %(roomName)s by %(userName)s.": "Вие сте изгонен от %(roomName)s от %(userName)s.", + "You have been kicked from this room by %(userName)s.": "Вие сте изгонен от тази стая от %(userName)s.", + "You have been banned from %(roomName)s by %(userName)s.": "Вие сте блокиран в %(roomName)s от %(userName)s.", + "You have been banned from this room by %(userName)s.": "Вие сте блокиран в тази стая от %(userName)s.", + "This room": "В тази стая", + "%(roomName)s does not exist.": "%(roomName)s не съществува.", + "%(roomName)s is not accessible at this time.": "%(roomName)s не е достъпна към този момент.", + "You are trying to access %(roomName)s.": "Опитвате се да влезете в %(roomName)s.", + "You are trying to access a room.": "Опитвате се да влезете в стая.", + "Click here to join the discussion!": "Натиснете тук, за да се присъедините към дискусията!", + "This is a preview of this room. Room interactions have been disabled": "Това е преглед на стаята. Интеракции в нея са деактивирани", + "To change the room's avatar, you must be a": "За да смените снимката на стаята, трябва да бъдете", + "To change the room's name, you must be a": "За да смените името на стаята, трябва да бъдете", + "To change the room's main address, you must be a": "За да смените основния адрес на стаята, трябва да бъдете", + "To change the room's history visibility, you must be a": "За да смените видимостта на историята на стаята, трябва да бъдете", + "To change the permissions in the room, you must be a": "За да промените разрешенията в стаята, трябва да бъдете", + "To change the topic, you must be a": "За да смените темата, трябва да бъдете", + "To modify widgets in the room, you must be a": "За да промените приспособленията в стаята, трябва да бъдете", + "Failed to unban": "Неуспешно отблокиране", + "Banned by %(displayName)s": "Блокиран от %(displayName)s", + "Privacy warning": "Предупреждение за сигурност", + "Changes to who can read history will only apply to future messages in this room": "Промени за това кой може да чете историята ще се отнасят само за бъдещи съобщения в тази стая", + "The visibility of existing history will be unchanged": "Видимостта на съществуващата история ще остане непроменена", + "End-to-end encryption is in beta and may not be reliable": "Шифроване от край до край е в бета версия и може да не е надеждно", + "Devices will not yet be able to decrypt history from before they joined the room": "Устройства все още не могат да разшифроват история от преди присъединяването към стая", + "Once encryption is enabled for a room it cannot be turned off again (for now)": "Веднъж включено шифроване в стаята не може да бъде изключено (за сега)", + "Encrypted messages will not be visible on clients that do not yet implement encryption": "Шифровани съобщения не са видими за клиенти, които все още не поддържат шифроване", + "Enable encryption": "Включване на шифроване" } From 644ddbf9b9d7488c247129f4718afed523185d90 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 20 Feb 2018 17:57:46 +0000 Subject: [PATCH 548/927] Regenerate room lists on Room event To make sure that we handle rooms that our client has not seen previously, we regenerate the room list when the room is stored - which is indicated by the js-sdk by the Room event. --- src/actions/MatrixActionCreators.js | 5 +++++ src/stores/RoomListStore.js | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/src/actions/MatrixActionCreators.js b/src/actions/MatrixActionCreators.js index a307af6f57..78c653c551 100644 --- a/src/actions/MatrixActionCreators.js +++ b/src/actions/MatrixActionCreators.js @@ -62,6 +62,10 @@ function createAccountDataAction(matrixClient, accountDataEvent) { }; } +function createRoomAction(matrixClient, room) { + return { action: 'MatrixActions.Room', room }; +} + function createRoomTagsAction(matrixClient, roomTagsEvent, room) { return { action: 'MatrixActions.Room.tags', room }; } @@ -96,6 +100,7 @@ export default { start(matrixClient) { this._addMatrixClientListener(matrixClient, 'sync', createSyncAction); this._addMatrixClientListener(matrixClient, 'accountData', createAccountDataAction); + this._addMatrixClientListener(matrixClient, 'Room', createRoomAction); this._addMatrixClientListener(matrixClient, 'Room.tags', createRoomTagsAction); this._addMatrixClientListener(matrixClient, 'Room.timeline', createRoomTimelineAction); this._addMatrixClientListener(matrixClient, 'RoomMember.membership', createRoomMembershipAction); diff --git a/src/stores/RoomListStore.js b/src/stores/RoomListStore.js index 8a3af309fc..80db6ca9a8 100644 --- a/src/stores/RoomListStore.js +++ b/src/stores/RoomListStore.js @@ -97,6 +97,14 @@ class RoomListStore extends Store { this._generateRoomLists(); } break; + // This could be a new room that we've been invited to, joined or created + // we won't get a RoomMember.membership for these cases if we're not already + // a member. + case 'MatrixActions.Room': { + if (!this._state.ready || !this._matrixClient.credentials.userId) break; + this._generateRoomLists(); + } + break; case 'RoomListActions.tagRoom.pending': { // XXX: we only show one optimistic update at any one time. // Ideally we should be making a list of in-flight requests From a78575929c47f6895cfe09ec812c5bcfdde3d6ce Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 21 Feb 2018 10:15:52 +0000 Subject: [PATCH 549/927] Document a few action creators --- src/actions/MatrixActionCreators.js | 79 +++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/src/actions/MatrixActionCreators.js b/src/actions/MatrixActionCreators.js index 78c653c551..1998ecfef2 100644 --- a/src/actions/MatrixActionCreators.js +++ b/src/actions/MatrixActionCreators.js @@ -62,14 +62,75 @@ function createAccountDataAction(matrixClient, accountDataEvent) { }; } +/** + * @typedef RoomAction + * @type {Object} + * @property {string} action 'MatrixActions.Room'. + * @property {Room} room the Room that was stored. + */ + +/** + * Create a MatrixActions.Room action that represents a MatrixClient `Room` + * matrix event, emitted when a Room is stored in the client. + * + * @param {MatrixClient} matrixClient the matrix client. + * @param {Room} room the Room that was stored. + * @returns {RoomAction} an action of type `MatrixActions.Room`. + */ function createRoomAction(matrixClient, room) { return { action: 'MatrixActions.Room', room }; } +/** + * @typedef RoomTagsAction + * @type {Object} + * @property {string} action 'MatrixActions.Room.tags'. + * @property {Room} room the Room whose tags changed. + */ + +/** + * Create a MatrixActions.Room.tags action that represents a MatrixClient + * `Room.tags` matrix event, emitted when the m.tag room account data + * event is updated. + * + * @param {MatrixClient} matrixClient the matrix client. + * @param {MatrixEvent} roomTagsEvent the m.tag event. + * @param {Room} room the Room whose tags were changed. + * @returns {RoomTagsAction} an action of type `MatrixActions.Room.tags`. + */ function createRoomTagsAction(matrixClient, roomTagsEvent, room) { return { action: 'MatrixActions.Room.tags', room }; } +/** + * @typedef RoomTimelineAction + * @type {Object} + * @property {string} action 'MatrixActions.Room.timeline'. + * @property {boolean} isLiveEvent whether the event was attached to a + * live timeline. + * @property {boolean} isLiveUnfilteredRoomTimelineEvent whether the + * event was attached to a timeline in the set of unfiltered timelines. + * @property {Room} room the Room whose tags changed. + */ + +/** + * Create a MatrixActions.Room.timeline action that represents a + * MatrixClient `Room.timeline` matrix event, emitted when an event + * is added to or removed from a timeline of a room. + * + * @param {MatrixClient} matrixClient the matrix client. + * @param {MatrixEvent} timelineEvent the event that was added/removed. + * @param {Room} room the Room that was stored. + * @param {boolean} toStartOfTimeline whether the event is being added + * to the start (and not the end) of the timeline. + * @param {boolean} removed whether the event was removed from the + * timeline. + * @param {Object} data + * @param {boolean} data.liveEvent whether the event is a live event, + * belonging to a live timeline. + * @param {EventTimeline} data.timeline the timeline being altered. + * @returns {RoomTimelineAction} an action of type `MatrixActions.Room.timeline`. + */ function createRoomTimelineAction(matrixClient, timelineEvent, room, toStartOfTimeline, removed, data) { return { action: 'MatrixActions.Room.timeline', @@ -80,6 +141,24 @@ function createRoomTimelineAction(matrixClient, timelineEvent, room, toStartOfTi }; } +/** + * @typedef RoomMembershipAction + * @type {Object} + * @property {string} action 'MatrixActions.RoomMember.membership'. + * @property {RoomMember} member the member whose membership was updated. + */ + +/** + * Create a MatrixActions.RoomMember.membership action that represents + * a MatrixClient `RoomMember.membership` matrix event, emitted when a + * member's membership is updated. + * + * @param {MatrixClient} matrixClient the matrix client. + * @param {MatrixEvent} membershipEvent the m.room.member event. + * @param {RoomMember} member the member whose membership was updated. + * @param {string} oldMembership the member's previous membership. + * @returns {RoomMembershipAction} an action of type `MatrixActions.RoomMember.membership`. + */ function createRoomMembershipAction(matrixClient, membershipEvent, member, oldMembership) { return { action: 'MatrixActions.RoomMember.membership', member }; } From b7601f86d1dbdb347c439c73e4477dc3ee799583 Mon Sep 17 00:00:00 2001 From: Ralitsa Bozhkova Date: Wed, 21 Feb 2018 13:37:58 +0000 Subject: [PATCH 550/927] Translated using Weblate (Bulgarian) Currently translated at 76.8% (758 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/bg/ --- src/i18n/strings/bg.json | 356 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 341 insertions(+), 15 deletions(-) diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json index f47b3b24ee..35505c0038 100644 --- a/src/i18n/strings/bg.json +++ b/src/i18n/strings/bg.json @@ -48,7 +48,7 @@ "Register": "Регистрация", "Notifications": "Известия", "Rooms": "Стаи", - "Add rooms to this community": "Добави стаи в това общество", + "Add rooms to this community": "Добави стаи в тази общност", "Unnamed room": "Стая без име", "World readable": "Четимо за всички", "Guests can join": "Гости могат да се присъединят", @@ -87,18 +87,18 @@ "Upload Failed": "Качването е неуспешно", "PM": "PM", "AM": "AM", - "Who would you like to add to this community?": "Кой бихте желали да добавите в това общество?", - "Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "Предупреждение: Всеки човек, който добавяте в дадено общество, ще бъде публично видим за знаещите идентификатора на обществото", - "Invite new community members": "Покани нови членове на обществото", + "Who would you like to add to this community?": "Кого бихте желали да добавите в тaзи общност?", + "Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "Предупреждение: Всеки човек, който добавяте в дадена общност, ще бъде публично видим за знаещите идентификатора на общността", + "Invite new community members": "Покани нови членове в общността", "Name or matrix ID": "Име или matrix ID", - "Invite to Community": "Покани в обществото", - "Which rooms would you like to add to this community?": "Кои стаи бихте желали да добавите в това общество?", - "Show these rooms to non-members on the community page and room list?": "Показване на тези стаи на не-членове на страницата на обществата и списъка със стаи?", - "Add rooms to the community": "Добави стаи в обществото", + "Invite to Community": "Покани в общността", + "Which rooms would you like to add to this community?": "Кои стаи бихте желали да добавите в тази общност?", + "Show these rooms to non-members on the community page and room list?": "Показване на тези стаи на не-членове на страницата на общностите и списъка със стаи?", + "Add rooms to the community": "Добави стаи в общността", "Room name or alias": "Име или псевдоним на стая", - "Add to community": "Добави в обществото", + "Add to community": "Добави в общност", "Failed to invite the following users to %(groupId)s:": "Следните потребители не могат да бъдат поканени в %(groupId)s:", - "Failed to invite users to community": "Потребителите не могат да бъдат поканени в обществото", + "Failed to invite users to community": "Потребителите не могат да бъдат поканени в общността", "Failed to invite users to %(groupId)s": "Потребителите не могат да бъдат поканени в %(groupId)s", "Failed to add the following rooms to %(groupId)s:": "Следните стаи не могат да бъдат добавени в %(groupId)s:", "Riot does not have permission to send you notifications - please check your browser settings": "Riot няма разрешение да Ви изпраща известия - моля проверете вашите настройки на браузъра", @@ -123,7 +123,7 @@ "You need to be logged in.": "Трябва да влезете в профила си.", "You need to be able to invite users to do that.": "Трябва да имате право да добавите потребители, за да извършите това.", "Unable to create widget.": "Неуспешно създаване на приспособление.", - "Failed to send request.": "Неуспешно изпращане на запитване.", + "Failed to send request.": "Неуспешно изпращане на заявката.", "This room is not recognised.": "Стаята не е разпозната.", "Power level must be positive integer.": "Нивото на достъп трябва да бъде позитивно число.", "Call Anyway": "Обади се въпреки това", @@ -198,7 +198,7 @@ "%(names)s and %(lastPerson)s are typing": "%(names)s и %(lastPerson)s пишат", "Failure to create room": "Неуспешно създаване на стая", "Server may be unavailable, overloaded, or you hit a bug.": "Сървърът може би е претоварен, недостъпен или се натъкнахте на проблем.", - "Send anyway": "Изпрати така или иначе", + "Send anyway": "Изпрати въпреки това", "Unnamed Room": "Стая без име", "Your browser does not support the required cryptography extensions": "Вашият браузър не поддържа необходимите разширения за шифроване", "Not a valid Riot keyfile": "Невалиден Riot ключов файл", @@ -286,7 +286,7 @@ "Encrypted by an unverified device": "Шифровано от непотвърдено устройство", "Unencrypted message": "Нешифровано съобщение", "Please select the destination room for this message": "Моля изберете стаята, в която искате да изпратите това съобщение", - "Blacklisted": "В черен списък", + "Blacklisted": "В черния списък", "Verified": "Потвърдено", "Unverified": "Непотвърдено", "device id: ": "идентификатор на устройството: ", @@ -390,7 +390,7 @@ "Failed to set direct chat tag": "Неуспешно означаване на директен чат", "Press to start a chat with someone": "Натиснете , за да започнете чат с някого", "You're not in any rooms yet! Press to make a room or to browse the directory": "Все още не сте в нито една стая! Натиснете , за да направите такава или , за да прегледате директорията", - "Community Invites": "Покани за общества", + "Community Invites": "Покани за общност", "Invites": "Покани", "Favourites": "Любими", "People": "Хора", @@ -430,5 +430,331 @@ "Devices will not yet be able to decrypt history from before they joined the room": "Устройства все още не могат да разшифроват история от преди присъединяването към стая", "Once encryption is enabled for a room it cannot be turned off again (for now)": "Веднъж включено шифроване в стаята не може да бъде изключено (за сега)", "Encrypted messages will not be visible on clients that do not yet implement encryption": "Шифровани съобщения не са видими за клиенти, които все още не поддържат шифроване", - "Enable encryption": "Включване на шифроване" + "Enable encryption": "Включване на шифроване", + "(warning: cannot be disabled again!)": "(внимание: не може да бъде изключено отново!)", + "Encryption is enabled in this room": "Шифроването е включено в тази стая", + "Encryption is not enabled in this room": "Шифроването не е включено в тази стая", + "Privileged Users": "Потребители с привилегии", + "%(user)s is a": "%(user)s е", + "No users have specific privileges in this room": "Никой няма специфични привилегии в тази стая", + "Banned users": "Блокирани потребители", + "This room is not accessible by remote Matrix servers": "Тази стая не е достъпна за далечни Matrix сървъри", + "Leave room": "Напусни стаята", + "Tagged as: ": "Означен като: ", + "To link to a room it must have an address.": "За да дадете линк към стаята, тя трябва да има адрес.", + "Guests cannot join this room even if explicitly invited.": "Гости не могат да се присъединят към тази стая, дори изрично поканени.", + "Click here to fix": "Натиснете тук за поправяне", + "Who can access this room?": "Кой има достъп до тази стая?", + "Only people who have been invited": "Само хора, които са поканени", + "Anyone who knows the room's link, apart from guests": "Всеки, който знае адреса на стаята, освен гости", + "Anyone who knows the room's link, including guests": "Всеки, който знае адрес на стаята, включително гости", + "Publish this room to the public in %(domain)s's room directory?": "Публично публикуване на тази стая в директорията на %(domain)s?", + "Who can read history?": "Кой може да чете историята?", + "Anyone": "Всеки", + "Members only (since the point in time of selecting this option)": "Само членове (от момента на избиране на тази опция)", + "Members only (since they were invited)": "Само членове (от момента, в който те са поканени)", + "Members only (since they joined)": "Само членове (от момента, в който са се присъединили)", + "Permissions": "Разрешения", + "The default role for new room members is": "По подразбиране ролята за нови членове в стаята е", + "To send messages, you must be a": "За да изпращате съобщения, трябва да бъдете", + "To invite users into the room, you must be a": "За да поканите потребители в стаята, трябва да бъдете", + "To configure the room, you must be a": "За да конфигурирате стаята, трябва да бъдете", + "To kick users, you must be a": "За да изгоните потребител, трябва да бъдете", + "To ban users, you must be a": "За да блокирате потребител, трябва да бъдете", + "To remove other users' messages, you must be a": "За да премахнете съобщения на друг потребител, трябва да бъдете", + "To send events of type , you must be a": "За да изпратите събития от вида , трябва да бъдете", + "Advanced": "Разширени", + "This room's internal ID is": "Вътрешният идентификатор на тази стая е", + "Add a topic": "Добавете тема", + "Jump to first unread message.": "Отиди до първото непрочетено съобщение.", + "Scroll to unread messages": "Скролирай до непрочетените съобщения", + "Invalid alias format": "Невалиден формат на псевдонима", + "'%(alias)s' is not a valid format for an alias": "%(alias)s не е валиден формат на псевдоним", + "Invalid address format": "Невалиден формат на адреса", + "'%(alias)s' is not a valid format for an address": "%(alias)s не е валиден формат на адрес", + "not specified": "неопределен", + "not set": "незададен", + "Remote addresses for this room:": "Далечни адреси на тази стая:", + "Addresses": "Адреси", + "The main address for this room is": "Основният адрес на тази стая е", + "Local addresses for this room:": "Локалните адреси на тази стая са:", + "This room has no local addresses": "Тази стая няма локални адреси", + "New address (e.g. #foo:%(localDomain)s)": "Нов адрес (напр. #foo:%(localDomain)s)", + "Invalid community ID": "Невалиден идентификатор на общност", + "'%(groupId)s' is not a valid community ID": "'%(groupId)s' е невалиден идентификатор на общност", + "Flair": "Значка", + "Showing flair for these communities:": "Показване на значки за тези общности:", + "This room is not showing flair for any communities": "Тази стая не показва значки за нито една общност", + "New community ID (e.g. +foo:%(localDomain)s)": "Нов идентификатор на общност (напр. +foo:%(localDomain)s)", + "You have enabled URL previews by default.": "Вие сте включил URL прегледи по подразбиране.", + "You have disabled URL previews by default.": "Вие сте изключил URL прегледи по подразбиране.", + "URL previews are enabled by default for participants in this room.": "URL прегледи са включени по подразбиране за участниците в тази стая.", + "URL previews are disabled by default for participants in this room.": "URL прегледи са изключени по подразбиране за участниците в тази стая.", + "URL Previews": "URL прегледи", + "Error decrypting audio": "Грешка при разшифроване на аудио файл", + "Error decrypting attachment": "Грешка при разшифроване на прикачване", + "Decrypt %(text)s": "Разшифровай %(text)s", + "Download %(text)s": "Изтегли %(text)s", + "(could not connect media)": "(неуспешно свързване на медийните устройства)", + "Must be viewing a room": "Трябва да видите стаята", + "Usage": "Употреба", + "Remove from community": "Премахни от общността", + "Disinvite this user from community?": "Оттегляне на поканата към този потребител от общността?", + "Remove this user from community?": "Премахване на този потребител от общността?", + "Failed to remove user from community": "Неуспешно премахване на потребителя от тази общност", + "Filter community members": "Филтриране на членовете на общността", + "Removing a room from the community will also remove it from the community page.": "Премахване на стая от общността ще бъде също премахната от страницата с общността.", + "Failed to remove room from community": "Неуспешно премахване на стаята от общността", + "Only visible to community members": "Видимо само за членове на общността", + "Filter community rooms": "Филтрирай стаи на общността", + "Community IDs cannot not be empty.": "Идентификаторите на общността не могат да бъдат празни.", + "Create Community": "Създай общност", + "Community Name": "Име на общност", + "Community ID": "Идентификатор на общност", + "

HTML for your community's page

\n

\n Use the long description to introduce new members to the community, or distribute\n some important links\n

\n

\n You can even use 'img' tags\n

\n": "

HTML за страница на Вашата общност

\n

\n Използвайте дългото описание, за да въведете нови членове в общността, \n или да разпространите важни връзки\n

\n

\n Можете дори да използвате 'img' тагове\n

\n", + "Add rooms to the community summary": "Добавете стаи към обобщението на общността", + "Add users to the community summary": "Добавете потребители към обобщението на общността", + "Failed to update community": "Неуспешно обновяване на общността", + "Leave Community": "Напусни общността", + "Community Settings": "Настройки на общността", + "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Тези стаи са показани на членове на общността на страницата на общността. Членовете на общността могат да се присъединят към стаите като натиснат върху тях.", + "%(inviter)s has invited you to join this community": "%(inviter)s Ви покани да се присъедините към тази общност", + "You are an administrator of this community": "Вие сте администратор на тази общност", + "You are a member of this community": "Вие сте член на тази общност", + "Your community hasn't got a Long Description, a HTML page to show to community members.
Click here to open settings and give it one!": "Вашата общност няма дълго описание - HTML страница, която да се показва на членовете на общността.
Натиснете тук, за да отворите настройките и да създадете такова!", + "Community %(groupId)s not found": "Общност %(groupId)s не е намерена", + "Create a new community": "Създаване на нова общност", + "Create a community to group together users and rooms! Build a custom homepage to mark out your space in the Matrix universe.": "Създайте общност, за да обедините заедно потребители и стаи! Изградете персонализирана начална страница, за да маркирате своето пространство във Вселената на матрицата.", + "Join an existing community": "Присъединяване към вече съществуваща общност", + "To join an existing community you'll have to know its community identifier; this will look something like +example:matrix.org.": "За да се присъедините към вече съществуваща общност, трябва да знаете неиния идентификатор; това изглежда нещо подобно на +example:matrix.org.", + "Unknown (user, device) pair:": "Непозната двойка (потребител, устройство):", + "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "Подписващият ключ, който сте предоставили, съвпада с подписващия ключ, който сте получили от устройството %(deviceId)s на %(userId)s. Устройството е маркирано като потвърдено.", + "Hide avatars in user and room mentions": "Скриване на профилната снимка при споменаване на потребители и стаи", + "Jump to message": "Отиди до съобщението", + "Jump to read receipt": "Отиди до потвърдението за прочетено", + "Revoke Moderator": "Премахване на правата на модератора", + "You should not yet trust it to secure data": "Все още не трябва да се доверявате на това, че ще запази Вашите данни", + "Invalid file%(extra)s": "Невалиден файл%(extra)s", + "Error decrypting image": "Грешка при разшифроване на снимка", + "This image cannot be displayed.": "Тази снимка не може да бъде показана.", + "Image '%(Body)s' cannot be displayed.": "Снимката '%(Body)s' не може да бъде показана.", + "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": "Добавяне на интеграция", + "Removed or unknown message type": "Премахнато или неизвестен тип съобщение", + "Message removed by %(userId)s": "Съобщението е премахнато от %(userId)s", + "Message removed": "Съобщението е премахнато", + "This Home Server would like to make sure you are not a robot": "Този Home сървър би искал да се увери, че не сте робот", + "Sign in with CAS": "Влез с CAS", + "To continue, please enter your password.": "За да продължите, моля, въведете своята парола.", + "Password:": "Парола:", + "An email has been sent to %(emailAddress)s": "Имейл беше изпратен на %(emailAddress)s", + "Please check your email to continue registration.": "Моля, проверете имейла си, за да продължите регистрацията.", + "Token incorrect": "Неправителен token", + "A text message has been sent to %(msisdn)s": "Текстово съобщение беше изпратено на %(msisdn)s", + "Please enter the code it contains:": "Моля, въведете кода, който то съдържа:", + "Start authentication": "Започнете автентикация", + "Username on %(hs)s": "Потребителско име на %(hs)s", + "User name": "Потребителско име", + "Mobile phone number": "Мобилен номер", + "Forgot your password?": "Забравена парола?", + "%(serverName)s Matrix ID": "%(serverName)s Matrix ID", + "Sign in with": "Влезте с", + "Email address": "Имейл адрес", + "Sign in": "Вход", + "If you don't specify an email address, you won't be able to reset your password. Are you sure?": "Ако не посочите имейл адрес, няма да бъде възможно да възстановите Вашата парола. Сигурни ли сте?", + "Email address (optional)": "Имейл адрес (по избор)", + "You are registering with %(SelectedTeamName)s": "Регистрирате се с %(SelectedTeamName)s", + "Mobile phone number (optional)": "Мобилен номер (по избор)", + "Default server": "Сървър по подразбиране", + "Custom server": "Потребителски сървър", + "Home server URL": "Адрес на home сървър", + "Identity server URL": "Адрес на сървър за самоличност", + "What does this mean?": "Какво означава това?", + "Failed to withdraw invitation": "Неуспешно оттегляне на поканата", + "Flair will appear if enabled in room settings": "Значката ще се покаже, ако е включена в настройките на стаята", + "Flair will not appear": "Значката няма да се покаже", + "Are you sure you want to remove '%(roomName)s' from %(groupId)s?": "Сигурни ли сте, че искате да премахнете '%(roomName)s' от %(groupId)s?", + "Failed to remove '%(roomName)s' from %(groupId)s": "Неуспешно премахване на '%(roomName)s' от %(groupId)s", + "Something went wrong!": "Нещо се обърка!", + "The visibility of '%(roomName)s' in %(groupId)s could not be updated.": "Видимостта на '%(roomName)s' в %(groupId)s не може да бъде обновена.", + "Visibility in Room List": "Видимост в списъка със стаи", + "Visible to everyone": "Видимо за всеки", + "Something went wrong when trying to get your communities.": "Нещо се обърка при зареждането на Вашите общности.", + "Display your community flair in rooms configured to show it.": "Показване на значката на общността в стаи, кофигурирани да я показват.", + "You're not currently a member of any communities.": "Към момента не сте член на нито една общност.", + "Unknown Address": "Неизвестен адрес", + "NOTE: Apps are not end-to-end encrypted": "ЗАБЕЛЕЖКА: Приложенията не са шифровани от край до край", + "Do you want to load widget from URL:": "Искате ли да заредите приспособление от URL адреса:", + "Allow": "Позволение", + "Delete Widget": "Изтриване на приспособление", + "Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?": "Изтриването на приспособление го премахва за всички потребители в тази стая. Сигурни ли сте, че искате да изтриете това приспособление?", + "Delete widget": "Изтрий приспособлението", + "Revoke widget access": "Премахване на достъпа до приспособления", + "Minimize apps": "Минимизирай приложенията", + "Create new room": "Създай нова стая", + "Unblacklist": "Премахване от черния списък", + "Blacklist": "Черен списък", + "Unverify": "Махни потвърждението", + "Verify...": "Потвърди...", + "Your unverified device '%(displayName)s' is requesting encryption keys.": "Вашето непотвърдено устройство '%(displayName)s' изисква ключове за шифроване.", + "I have verified my email address": "Потвърдих имейл адреса си", + "NOT verified": "НЕ е потвърдено", + "verified": "потвърдено", + "No results": "Няма резултати", + "Delete": "Изтрий", + "Communities": "Общности", + "Home": "Начална страница", + "Integrations Error": "Грешка при интеграциите", + "Could not connect to the integration server": "Неуспешно свързване със сървъра с интеграции", + "Manage Integrations": "Управление на интеграциите", + "%(nameList)s %(transitionList)s": "%(nameList)s %(transitionList)s", + "%(severalUsers)sjoined %(count)s times|other": "%(severalUsers)sсе присъединиха %(count)s пъти", + "%(severalUsers)sjoined %(count)s times|one": "%(severalUsers)sсе присъединиха", + "%(oneUser)sjoined %(count)s times|other": "%(oneUser)sсе присъедини %(count)s пъти", + "%(oneUser)sjoined %(count)s times|one": "%(oneUser)sсе присъедини", + "%(severalUsers)sleft %(count)s times|other": "%(severalUsers)sнапуснаха %(count)s пъти", + "%(severalUsers)sleft %(count)s times|one": "%(severalUsers)sнапуснаха", + "%(oneUser)sleft %(count)s times|other": "%(oneUser)sнапусна %(count)s пъти", + "%(oneUser)sleft %(count)s times|one": "%(oneUser)sнапусна", + "%(severalUsers)sjoined and left %(count)s times|other": "%(severalUsers)sсе присъединиха и напуснаха %(count)s пъти", + "%(severalUsers)sjoined and left %(count)s times|one": "%(severalUsers)sсе присъединиха и напуснаха", + "%(oneUser)sjoined and left %(count)s times|other": "%(oneUser)sсе присъедини и напусна %(count)s пъти", + "%(oneUser)sjoined and left %(count)s times|one": "%(oneUser)sсе присъедини и напусна", + "%(severalUsers)sleft and rejoined %(count)s times|other": "%(severalUsers)sнапуснаха и се присъединиха отново %(count)s пъти", + "%(severalUsers)sleft and rejoined %(count)s times|one": "%(severalUsers)sнапуснаха и се присъединиха отново", + "%(oneUser)sleft and rejoined %(count)s times|other": "%(oneUser)sнапусна и се присъедини отново %(count)s пъти", + "%(oneUser)sleft and rejoined %(count)s times|one": "%(oneUser)sнапусна и се присъедини отново", + "%(severalUsers)srejected their invitations %(count)s times|other": "%(severalUsers)sотказаха своите покани %(count)s пъти", + "%(severalUsers)srejected their invitations %(count)s times|one": "%(severalUsers)sотказаха своите покани", + "%(oneUser)srejected their invitation %(count)s times|other": "%(oneUser)sотказа своята покана %(count)s пъти", + "%(oneUser)srejected their invitation %(count)s times|one": "%(oneUser)sотказа своята покана", + "%(severalUsers)shad their invitations withdrawn %(count)s times|other": "%(severalUsers)sоттеглиха своите покани %(count)s пъти", + "%(severalUsers)shad their invitations withdrawn %(count)s times|one": "%(severalUsers)sоттеглиха своите покани", + "%(oneUser)shad their invitation withdrawn %(count)s times|other": "%(oneUser)sоттегли своята покана %(count)s пъти", + "%(oneUser)shad their invitation withdrawn %(count)s times|one": "%(oneUser)sоттегли своята покана", + "were invited %(count)s times|other": "бяха поканени %(count)s пъти", + "were invited %(count)s times|one": "бяха поканени", + "was invited %(count)s times|other": "беше поканен %(count)s пъти", + "was invited %(count)s times|one": "беше поканен", + "were banned %(count)s times|other": "бяха блокирани %(count)s пъти", + "were banned %(count)s times|one": "бяха блокирани", + "was banned %(count)s times|other": "беше блокиран %(count)s пъти", + "was banned %(count)s times|one": "беше блокиран", + "were unbanned %(count)s times|other": "бяха отблокирани %(count)s пъти", + "were unbanned %(count)s times|one": "бяха отблокирани", + "was unbanned %(count)s times|other": "беше отблокиран %(count)s пъти", + "was unbanned %(count)s times|one": "беше отблокиран", + "were kicked %(count)s times|other": "бяха изгонени %(count)s пъти", + "were kicked %(count)s times|one": "бяха изгонени", + "was kicked %(count)s times|other": "беше изгонен %(count)s пъти", + "was kicked %(count)s times|one": "беше изгонен", + "%(severalUsers)schanged their name %(count)s times|other": "%(severalUsers)sсмениха своето име %(count)s пъти", + "%(severalUsers)schanged their name %(count)s times|one": "%(severalUsers)sсмениха своето име", + "%(oneUser)schanged their name %(count)s times|other": "%(oneUser)sсмени своето име %(count)s пъти", + "%(oneUser)schanged their name %(count)s times|one": "%(oneUser)sсмени своето име", + "%(severalUsers)schanged their avatar %(count)s times|other": "%(severalUsers)sсмениха своята профилна снимка %(count)s пъти", + "%(severalUsers)schanged their avatar %(count)s times|one": "%(severalUsers)sсмениха своята профилна снимка", + "%(oneUser)schanged their avatar %(count)s times|other": "%(oneUser)sсмени своята профилна снимка %(count)s пъти", + "%(oneUser)schanged their avatar %(count)s times|one": "%(oneUser)sсмени своята профилна снимка", + "%(items)s and %(count)s others|other": "%(items)s и %(count)s други", + "%(items)s and %(count)s others|one": "%(items)s и още един", + "%(items)s and %(lastItem)s": "%(items)s и %(lastItem)s", + "collapse": "свий", + "expand": "разшири", + "Custom of %(powerLevel)s": "Персонализирано със стойност %(powerLevel)s", + "Custom level": "Персонализирано ниво", + "Custom": "Персонализирано", + "In reply to ": "В отговор на ", + "Room directory": "Директория на стаята", + "Start chat": "Започни чат", + "And %(count)s more...|other": "И %(count)s други...", + "ex. @bob:example.com": "напр. @bob:example.com", + "Add User": "Добави потребител", + "Matrix ID": "Matrix ID", + "Matrix Room ID": "Идентификатор на стаята", + "email address": "имейл адрес", + "Try using one of the following valid address types: %(validTypesList)s.": "Опитайте се да използвате един от следните видове валидни адреси: %(validTypesList)s.", + "You have entered an invalid address.": "Въвели сте невалиден адрес.", + "Create a new chat or reuse an existing one": "Създаване на нов чат или повторно използване на съществуващ", + "Start new chat": "Започни нов чат", + "You already have existing direct chats with this user:": "Вече имате налични директни чатове с този потребител:", + "Start chatting": "Започнете чата", + "Click on the button below to start chatting!": "Натиснете бутона по-долу, за да започнете чата!", + "Start Chatting": "Започнете чата", + "Confirm Removal": "Потвърдете премахването", + "Community IDs may only contain characters a-z, 0-9, or '=_-./'": "Идентификаторите на общността могат да съдържат само a-z, 0-9, или '=_-./'", + "Something went wrong whilst creating your community": "Нещо се обърка по време на създаването на Вашата общност", + "Example": "Пример", + "example": "пример", + "Create": "Създай", + "Create Room": "Създай стая", + "Room name (optional)": "Име на стая (по избор)", + "Advanced options": "Разширени настройки", + "Block users on other matrix homeservers from joining this room": "Не позволявай на потребители от други matrix home сървъри да се присъединяват към тази стая", + "This setting cannot be changed later!": "Тази настройка не може да бъде променена по-късно!", + "Unknown error": "Непозната грешка", + "Incorrect password": "Неправилна парола", + "Deactivate Account": "Деактивация на профила", + "Deactivate my account": "Деактивирай моя профил", + "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Това ще направи профил Ви перманентно неизползваем. Няма да можете да се регистрирате отново със същия потребителски идентификатор.", + "This action is irreversible.": "Това действие е необратимо.", + "Device name": "Име на устройството", + "Device key": "Ключ на устройството", + "In future this verification process will be more sophisticated.": "В бъдеще този процес на потвърждение ще бъде по-лесен.", + "Verify device": "Потвърди устройството", + "Start verification": "Започни потвърждението", + "Verification Pending": "Очакване на потвърждението", + "Verification": "Потвърждение", + "I verify that the keys match": "Потвърждавам, че ключовете съвпадат", + "An error has occurred.": "Възникна грешка.", + "You added a new device '%(displayName)s', which is requesting encryption keys.": "Добавихте ново устройство '%(displayName)s', което изисква ключове за шифроване.", + "Share without verifying": "Сподели без потвърждение", + "Ignore request": "Игнорирай поканата", + "Loading device info...": "Зареждане на информация за устройството...", + "Encryption key request": "Шифроване на ключове за заявка", + "Otherwise, click here to send a bug report.": "В противен случай, натиснете тук, за да изпратите съобщение за грешка.", + "Report it": "Съобщете го", + "Bug Report": "Съобщение за грешка", + "Unable to restore session": "Неуспешно възстановяване на сесията", + "Continue anyway": "Продължете въпреки това", + "Invalid Email Address": "Невалиден имейл адрес", + "This doesn't appear to be a valid email address": "Това не изглежда да е валиден имейл адрес", + "Please check your email and click on the link it contains. Once this is done, click continue.": "Моля, проверете своя имейл адрес и натиснете връзката, която той съдържа. След като направите това, натиснете продължи.", + "Unable to add email address": "Неуспешно добавяне на имейл адрес", + "Unable to verify email address.": "Неуспешно потвърждение на имейл адрес.", + "Unable to accept invite": "Неуспешно приемане на поканата", + "Unable to reject invite": "Неуспешно отхвърляне на поканата", + "Unable to leave room": "Неуспешно напускане на стаята", + "Tried to load a specific point in this room's timeline, but was unable to find it.": "Опита се да зареди конкретна точка в хронологията на тази стая, но не успя да я намери.", + "Unable to remove contact information": "Неуспешно премахване на информацията на контакта", + "This will allow you to reset your password and receive notifications.": "Това ще Ви позволи да възстановите Вашата парола и да получавате известия.", + "Skip": "Пропусни", + "User names may only contain letters, numbers, dots, hyphens and underscores.": "Потребителските имена могат да съдържат само букви, цифри, точки, тирета и долни черти.", + "Username not available": "Потребителското име е заето", + "Username invalid: %(errMessage)s": "Невалидно потребителско име: %(errMessage)s", + "An error occurred: %(error_string)s": "Възникна грешка: %(error_string)s", + "Username available": "Потребителското име не е заето", + "To get started, please pick a username!": "За да започнете, моля изберете потребителско име!", + "If you already have a Matrix account you can log in instead.": "Ако вече имате Matrix профил, можете да влезете с него.", + "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "В момента Вие блокирате непотвърдени устройства; за да изпращате съобщения до тези устройства, трябва да ги потвърдите.", + "Room contains unknown devices": "Стаята съдържа непознати устройства", + "\"%(RoomName)s\" contains devices that you haven't seen before.": "\"%(RoomName)s\" съдържа устройства, който не сте виждали до сега.", + "Unknown devices": "Непознати устройства", + "Private Chat": "Личен чат", + "Public Chat": "Публичен чат", + "Alias (optional)": "Псевдоним (по избор)", + "Name": "Име", + "Topic": "Тема", + "Make this room private": "Направи тази стая лична", + "Share message history with new users": "Сподели историята на съобщението с новите потребители", + "Encrypt room": "Шифровай стаята", + "You must register to use this functionality": "Трябва да се регистрирате, за да използвате тази функционалност", + "You must join the room to see its files": "Трябва да се присъедините към стаята, за да видите файловете, които съдържа", + "There are no visible files in this room": "Няма видими файлове в тази стая", + "Which rooms would you like to add to this summary?": "Кои стаи бихте искали да добавите в това обобщение?" } From 5e90da73f0489d5e6c25c8f31bf017889116c951 Mon Sep 17 00:00:00 2001 From: Ralitsa Bozhkova Date: Wed, 21 Feb 2018 11:56:55 +0000 Subject: [PATCH 551/927] Translated using Weblate (Galician) Currently translated at 98.7% (974 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/gl/ --- src/i18n/strings/gl.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/gl.json b/src/i18n/strings/gl.json index 7a1fd567ee..d972376d41 100644 --- a/src/i18n/strings/gl.json +++ b/src/i18n/strings/gl.json @@ -768,7 +768,7 @@ "Create a new community": "Crear unha nova comunidade", "Create a community to group together users and rooms! Build a custom homepage to mark out your space in the Matrix universe.": "Crear unha comunidade para agrupar usuarias e salas! Poña unha páxina de inicio personalizada para destacar o seu lugar no universo Matrix.", "Join an existing community": "Unirse a unha comunidade existente", - "To join an existing community you'll have to know its community identifier; this will look something like +example:matrix.org.": "Para unirse a unha comunidade existente deberá coñecer o identificador de esa comunidade; terá un aspecto como +exemplo:matrix.org", + "To join an existing community you'll have to know its community identifier; this will look something like +example:matrix.org.": "Para unirse a unha comunidade existente deberá coñecer o identificador de esa comunidade; terá un aspecto como +exemplo:matrix.org.", "You have no visible notifications": "Non ten notificacións visibles", "Scroll to bottom of page": "Desplácese ate o final da páxina", "Message not sent due to unknown devices being present": "Non se enviou a mensaxe porque hai dispositivos non coñecidos", From fc73442cdc4fba8cf7c610bee8a45c76aee8b67b Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 21 Feb 2018 15:06:10 +0000 Subject: [PATCH 552/927] Change icon from "R" to "X" --- src/components/structures/TagPanel.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/structures/TagPanel.js b/src/components/structures/TagPanel.js index d614588ccc..59365d8139 100644 --- a/src/components/structures/TagPanel.js +++ b/src/components/structures/TagPanel.js @@ -111,7 +111,7 @@ const TagPanel = React.createClass({ }); return
- +
Date: Wed, 21 Feb 2018 17:15:43 +0000 Subject: [PATCH 553/927] Only show "X" when filtering, add alt/title --- src/components/structures/TagPanel.js | 17 ++++++++++++++--- src/i18n/strings/en_EN.json | 9 +++++---- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/components/structures/TagPanel.js b/src/components/structures/TagPanel.js index 59365d8139..46e539fa04 100644 --- a/src/components/structures/TagPanel.js +++ b/src/components/structures/TagPanel.js @@ -24,6 +24,7 @@ import GroupActions from '../../actions/GroupActions'; import sdk from '../../index'; import dis from '../../dispatcher'; +import { _t } from '../../languageHandler'; import { Droppable } from 'react-beautiful-dnd'; @@ -92,7 +93,7 @@ const TagPanel = React.createClass({ dis.dispatch({action: 'view_create_group'}); }, - onLogoClick(ev) { + onClearFilterClick(ev) { dis.dispatch({action: 'deselect_tags'}); }, @@ -109,9 +110,19 @@ const TagPanel = React.createClass({ selected={this.state.selectedTags.includes(tag)} />; }); + + const clearButton = this.state.selectedTags.length > 0 ? + {_t("Clear : +
; + return
- - + + { clearButton }
to start a chat with someone": "Press to start a chat with someone", "You're not in any rooms yet! Press to make a room or to browse the directory": "You're not in any rooms yet! Press to make a room or to browse the directory", "Community Invites": "Community Invites", @@ -826,6 +823,7 @@ "Click to mute video": "Click to mute video", "Click to unmute audio": "Click to unmute audio", "Click to mute audio": "Click to mute audio", + "Clear filter": "Clear filter", "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.", "Tried to load a specific point in this room's timeline, but was unable to find it.": "Tried to load a specific point in this room's timeline, but was unable to find it.", "Failed to load timeline position": "Failed to load timeline position", @@ -984,5 +982,8 @@ "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.", "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.", "File to import": "File to import", - "Import": "Import" + "Import": "Import", + "Failed to set direct chat tag": "Failed to set direct chat tag", + "Failed to remove tag %(tagName)s from room": "Failed to remove tag %(tagName)s from room", + "Failed to add tag %(tagName)s to room": "Failed to add tag %(tagName)s to room" } From bb386c05d906eda9e519a7c70812ee5b98948e65 Mon Sep 17 00:00:00 2001 From: Ralitsa Bozhkova Date: Wed, 21 Feb 2018 14:27:58 +0000 Subject: [PATCH 554/927] Translated using Weblate (Bulgarian) Currently translated at 79.5% (784 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/bg/ --- src/i18n/strings/bg.json | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json index 35505c0038..4b0993e4ba 100644 --- a/src/i18n/strings/bg.json +++ b/src/i18n/strings/bg.json @@ -756,5 +756,31 @@ "You must register to use this functionality": "Трябва да се регистрирате, за да използвате тази функционалност", "You must join the room to see its files": "Трябва да се присъедините към стаята, за да видите файловете, които съдържа", "There are no visible files in this room": "Няма видими файлове в тази стая", - "Which rooms would you like to add to this summary?": "Кои стаи бихте искали да добавите в това обобщение?" + "Which rooms would you like to add to this summary?": "Кои стаи бихте искали да добавите в това обобщение?", + "Add to summary": "Добави в обобщението", + "Failed to add the following rooms to the summary of %(groupId)s:": "Неуспешно добавяне на следните стаи в обобщението на %(groupId)s:", + "Add a Room": "Добавяне на стая", + "Failed to remove the room from the summary of %(groupId)s": "Неуспешно премахване на стаята от обобщението на %(groupId)s", + "The room '%(roomName)s' could not be removed from the summary.": "Стаята '%(roomName)s' не може да бъде премахната от обобщението.", + "Who would you like to add to this summary?": "Кого бихте желали да добавите в това обобщение?", + "Failed to add the following users to the summary of %(groupId)s:": "Неуспешно добавяне на следните потребители в обобщението на %(groupId)s:", + "Add a User": "Добавяне на потребител", + "Failed to remove a user from the summary of %(groupId)s": "Неуспешно премахване на потребител от обобщението на %(groupId)s", + "The user '%(displayName)s' could not be removed from the summary.": "Потребителят '%(displayName)s' не може да бъде премахнат от обобщението.", + "Failed to upload image": "Неуспешно качване на снимка", + "Leave %(groupName)s?": "Напускане на %(groupName)s?", + "Featured Rooms:": "Препоръчани стаи:", + "Featured Users:": "Препоръчани потребители:", + "Long Description (HTML)": "Дълго описание (HTML)", + "Description": "Описание", + "This Home server does not support communities": "Този Home сървър не поддържа общности", + "Failed to load %(groupId)s": "Неуспешно зареждане на %(groupId)s", + "Reject invitation": "Отхвърли поканата", + "Are you sure you want to reject the invitation?": "Сигурни ли сте, че искате да отхвърлите поканата?", + "Failed to reject invitation": "Неуспешно отхвърляне на поканата", + "This room is not public. You will not be able to rejoin without an invite.": "Тази стая не е публична. Няма да можете да се присъедините отново без покана.", + "Are you sure you want to leave the room '%(roomName)s'?": "Сигурни ли сте, че искате да напуснете стаята '%(roomName)s'?", + "Failed to leave room": "Неуспешно напускане на стаята", + "Old cryptography data detected": "Старите криптирани данни са изтрити", + "Your Communities": "Вашите общности" } From d9032d706f5ea80b51edaaad86dbbdbe8d748144 Mon Sep 17 00:00:00 2001 From: Walter Date: Tue, 13 Feb 2018 18:55:45 +0000 Subject: [PATCH 555/927] Translated using Weblate (Russian) Currently translated at 100.0% (987 of 987 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index d24ee71de1..c07ea1e1fb 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -984,5 +984,6 @@ "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s изменил отображаемое имя на %(displayName)s.", "Failed to set direct chat tag": "Не удалось установить тег прямого чата", "Failed to remove tag %(tagName)s from room": "Не удалось удалить тег %(tagName)s из комнаты", - "Failed to add tag %(tagName)s to room": "Не удалось добавить тег %(tagName)s в комнату" + "Failed to add tag %(tagName)s to room": "Не удалось добавить тег %(tagName)s в комнату", + "Clear filter": "Очистить фильтр" } From 296e2bd928e703d1afbb48a778bde338e0d81c00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Tue, 6 Feb 2018 19:11:45 +0000 Subject: [PATCH 556/927] Translated using Weblate (French) Currently translated at 100.0% (987 of 987 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index f0f9b2dae9..7efbf5f548 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -984,5 +984,6 @@ "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s a changé son nom affiché en %(displayName)s.", "Failed to set direct chat tag": "Échec de l'ajout de l'étiquette discussion directe", "Failed to remove tag %(tagName)s from room": "Échec de la suppression de l'étiquette %(tagName)s du salon", - "Failed to add tag %(tagName)s to room": "Échec de l'ajout de l'étiquette %(tagName)s au salon" + "Failed to add tag %(tagName)s to room": "Échec de l'ajout de l'étiquette %(tagName)s au salon", + "Clear filter": "Supprimer les filtres" } From 5cd7a7fc061784bff84795c961782d73866c97f2 Mon Sep 17 00:00:00 2001 From: lukebarnard Date: Wed, 21 Feb 2018 19:26:14 +0000 Subject: [PATCH 557/927] Fix group member spinner being out of flex order --- src/components/views/groups/GroupMemberInfo.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/views/groups/GroupMemberInfo.js b/src/components/views/groups/GroupMemberInfo.js index 305aec8cdd..097fb1f7db 100644 --- a/src/components/views/groups/GroupMemberInfo.js +++ b/src/components/views/groups/GroupMemberInfo.js @@ -132,7 +132,9 @@ module.exports = React.createClass({ render: function() { if (this.state.removingUser) { const Spinner = sdk.getComponent("elements.Spinner"); - return ; + return
+ +
; } let adminTools; From ffb524b6a5a614734d9ae30401b95b44eb62ca48 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Wed, 21 Feb 2018 23:10:08 +0000 Subject: [PATCH 558/927] Allow widget iframes to request camera and microphone permissions. --- src/components/views/elements/AppTile.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index a63823555f..b325dace84 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -393,6 +393,10 @@ export default React.createClass({ const sandboxFlags = "allow-forms allow-popups allow-popups-to-escape-sandbox "+ "allow-same-origin allow-scripts allow-presentation"; + // Additional iframe feature pemissions + // (see - https://sites.google.com/a/chromium.org/dev/Home/chromium-security/deprecating-permissions-in-cross-origin-iframes and https://wicg.github.io/feature-policy/) + const iframeFeatures = "microphone; camera; encrypted-media;"; + if (this.props.show) { const loadingElement = (
@@ -413,6 +417,8 @@ export default React.createClass({
{ this.state.loading && loadingElement }