From 1c3d8cbe6e27781b568753a39fd1a73c15d306f2 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sat, 10 Feb 2018 11:19:43 +0000 Subject: [PATCH 001/190] initial refactor of Replies to use `B` explicit over-the-wire format Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/Quote.js | 230 +++++++++--------- src/components/views/messages/TextualBody.js | 19 -- src/components/views/rooms/EventTile.js | 6 +- .../views/rooms/MessageComposerInput.js | 54 ++-- src/components/views/rooms/QuotePreview.js | 4 +- 5 files changed, 140 insertions(+), 173 deletions(-) diff --git a/src/components/views/elements/Quote.js b/src/components/views/elements/Quote.js index 761f7aa151..fa571aa063 100644 --- a/src/components/views/elements/Quote.js +++ b/src/components/views/elements/Quote.js @@ -21,33 +21,20 @@ import MatrixClientPeg from '../../../MatrixClientPeg'; import {wantsDateSeparator} from '../../../DateUtils'; import {MatrixEvent} from 'matrix-js-sdk'; import {makeUserPermalink} from "../../../matrix-to"; - -// 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\/([\#\!][^\/]*)\/(\$[^\/]*)$/; +import SettingsStore from "../../../settings/SettingsStore"; export default class Quote extends React.Component { - static isMessageUrl(url) { - return !!REGEX_LOCAL_MATRIXTO.exec(url); - } - - static childContextTypes = { - matrixClient: PropTypes.object, - addRichQuote: PropTypes.func, - }; - static propTypes = { - // The matrix.to url of the event - url: PropTypes.string, - // The original node that was rendered - node: PropTypes.instanceOf(Element), // The parent event parentEv: PropTypes.instanceOf(MatrixEvent), + + onWidgetLoad: PropTypes.func.isRequired, }; constructor(props, context) { super(props, context); + /* this.state = { // The event related to this quote and their nested rich quotes events: [], @@ -55,45 +42,54 @@ export default class Quote extends React.Component { show: true, // Whether an error was encountered fetching nested older event, show node if it does err: false, + loading: true, + };*/ + + this.state = { + // The loaded events to be rendered as linear-replies + events: [], + + // The latest loaded event which has not yet been shown + loadedEv: null, + // Whether the component is still loading more events + loading: true, + + // Whether as error was encountered fetching a replied to event. + err: null, }; this.onQuoteClick = this.onQuoteClick.bind(this); - this.addRichQuote = this.addRichQuote.bind(this); - } - - getChildContext() { - return { - matrixClient: MatrixClientPeg.get(), - addRichQuote: this.addRichQuote, - }; - } - - parseUrl(url) { - if (!url) return; - - // 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(url) || []; - - const [, roomIdentifier, eventId] = matrixToMatch; - return {roomIdentifier, eventId}; - } - - componentWillReceiveProps(nextProps) { - const {roomIdentifier, eventId} = this.parseUrl(nextProps.url); - if (!roomIdentifier || !eventId) return; - - const room = this.getRoom(roomIdentifier); - if (!room) return; - - // 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. - this.setState({ events: [] }); - if (room) this.getEvent(room, eventId, true); } componentWillMount() { - this.componentWillReceiveProps(this.props); + this.room = this.getRoom(this.props.parentEv.getRoomId()); + this.initialize(); + } + + async initialize() { + const {parentEv} = this.props; + const inReplyTo = Quote.getInReplyTo(parentEv); + + const ev = await this.getEvent(this.room, inReplyTo['event_id']); + this.setState({ + events: [ev], + }, this.loadNextEvent); + } + + async loadNextEvent() { + this.props.onWidgetLoad(); + const ev = this.state.events[0]; + const inReplyTo = Quote.getInReplyTo(ev); + + if (!inReplyTo) { + this.setState({ + loading: false, + }); + return; + } + + const loadedEv = await this.getEvent(this.room, inReplyTo['event_id']); + this.setState({loadedEv}); } getRoom(id) { @@ -105,84 +101,84 @@ export default class Quote extends React.Component { }); } - async getEvent(room, eventId, show) { + async getEvent(room, eventId) { const event = room.findEventById(eventId); - if (event) { - this.addEvent(event, show); - return; - } + if (event) return event; await MatrixClientPeg.get().getEventTimeline(room.getUnfilteredTimelineSet(), eventId); - this.addEvent(room.findEventById(eventId), show); - } - - addEvent(event, show) { - const events = [event].concat(this.state.events); - this.setState({events, show}); - } - - // addRichQuote(roomId, eventId) { - addRichQuote(href) { - const {roomIdentifier, eventId} = this.parseUrl(href); - if (!roomIdentifier || !eventId) { - this.setState({ err: true }); - return; - } - - const room = this.getRoom(roomIdentifier); - if (!room) { - this.setState({ err: true }); - return; - } - - this.getEvent(room, eventId, false); + return room.findEventById(eventId); } onQuoteClick() { - this.setState({ show: true }); + const events = [this.state.loadedEv].concat(this.state.events); + + this.setState({ + loadedEv: null, + events, + }, this.loadNextEvent); + } + + static getInReplyTo(ev) { + if (ev.isRedacted()) return; + + const {'m.relates_to': mRelatesTo} = ev.getContent(); + if (mRelatesTo) { + return mRelatesTo['m.in_reply_to']; + } + } + + static getRelationship(ev) { + return { + 'm.relates_to': { + 'm.in_reply_to': { + 'event_id': ev.getId(), + }, + }, + }; + } + + static getQuote(parentEv, onWidgetLoad) { + if (!SettingsStore.isFeatureEnabled("feature_rich_quoting") || !Quote.getInReplyTo(parentEv)) return null; + return ; } render() { - const events = this.state.events.slice(); - if (events.length) { - const evTiles = []; - - if (!this.state.show) { - const oldestEv = events.shift(); - const Pill = sdk.getComponent('elements.Pill'); - const room = MatrixClientPeg.get().getRoom(oldestEv.getRoomId()); - - evTiles.push(
- { - _t('In reply to ', {}, { - 'a': (sub) => { sub }, - 'pill': , - }) - } -
); - } - - const EventTile = sdk.getComponent('views.rooms.EventTile'); - const DateSeparator = sdk.getComponent('messages.DateSeparator'); - events.forEach((ev) => { - let dateSep = null; - - if (wantsDateSeparator(this.props.parentEv.getDate(), ev.getDate())) { - dateSep = ; + let header = null; + if (this.state.loadedEv) { + const ev = this.state.loadedEv; + const Pill = sdk.getComponent('elements.Pill'); + const room = MatrixClientPeg.get().getRoom(ev.getRoomId()); + header =
+ { + _t('In reply to ', {}, { + 'a': (sub) => { sub }, + 'pill': , + }) } - - evTiles.push(
- { dateSep } - -
); - }); - - return
{ evTiles }
; +
; + } else if (this.state.loading) { + header =
LOADING...
; } - // Deliberately render nothing if the URL isn't recognised - // in case we get an undefined/falsey node, replace it with null to make React happy - return this.props.node || null; + const EventTile = sdk.getComponent('views.rooms.EventTile'); + const DateSeparator = sdk.getComponent('messages.DateSeparator'); + const evTiles = this.state.events.map((ev) => { + let dateSep = null; + + if (wantsDateSeparator(this.props.parentEv.getDate(), ev.getDate())) { + dateSep = ; + } + + return
+ { dateSep } + +
; + }); + + return
+
{ header }
+
{ evTiles }
+
; } } diff --git a/src/components/views/messages/TextualBody.js b/src/components/views/messages/TextualBody.js index 31c1df7b44..7da4dd8644 100644 --- a/src/components/views/messages/TextualBody.js +++ b/src/components/views/messages/TextualBody.js @@ -61,10 +61,6 @@ module.exports = React.createClass({ tileShape: PropTypes.string, }, - contextTypes: { - addRichQuote: PropTypes.func, - }, - getInitialState: function() { return { // the URLs (if any) to be previewed with a LinkPreviewWidget @@ -205,21 +201,6 @@ 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") && Quote.isMessageUrl(href)) { - if (this.context.addRichQuote) { // We're already a Rich Quote so just append the next one above - this.context.addRichQuote(href); - node.remove(); - } else { // We're the first in the chain - const quoteContainer = document.createElement('span'); - - const quote = - ; - - ReactDOM.render(quote, quoteContainer); - node.parentNode.replaceChild(quoteContainer, node); - node = quoteContainer; - } - pillified = true; } } 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 1d8df4c7a6..7e9a7a75f1 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -18,6 +18,8 @@ limitations under the License. 'use strict'; +import Quote from "../elements/Quote"; + const React = require('react'); import PropTypes from 'prop-types'; const classNames = require("classnames"); @@ -517,7 +519,7 @@ module.exports = withMatrixClient(React.createClass({ if (needsSenderProfile) { let text = null; - if (!this.props.tileShape || this.props.tileShape === 'quote') { + if (!this.props.tileShape) { if (msgtype === 'm.image') text = _td('%(senderName)s sent an image'); else if (msgtype === 'm.video') text = _td('%(senderName)s sent a video'); else if (msgtype === 'm.file') text = _td('%(senderName)s uploaded a file'); @@ -598,7 +600,6 @@ module.exports = withMatrixClient(React.createClass({ { this._renderE2EPadlock() } { this._renderE2EPadlock() } + { Quote.getQuote(this.props.mxEvent, this.props.onWidgetLoad) } block.getType() !== 'unstyled')) { shouldSendHTML = true; @@ -820,15 +815,15 @@ export default class MessageComposerInput extends React.Component { const md = new Markdown(pt); // if contains no HTML and we're not quoting (needing HTML) - if (md.isPlainText() && !quotingEv) { + if (md.isPlainText()) { contentText = md.toPlaintext(); } else { contentHTML = md.toHTML(); } } - let sendHtmlFn = this.client.sendHtmlMessage; - let sendTextFn = this.client.sendTextMessage; + let sendHtmlFn = ContentHelpers.makeHtmlMessage; + let sendTextFn = ContentHelpers.makeTextMessage; this.historyManager.save( contentState, @@ -839,35 +834,26 @@ export default class MessageComposerInput extends React.Component { contentText = contentText.substring(4); // bit of a hack, but the alternative would be quite complicated if (contentHTML) contentHTML = contentHTML.replace(/\/me ?/, ''); - sendHtmlFn = this.client.sendHtmlEmote; - sendTextFn = this.client.sendEmoteMessage; + sendHtmlFn = ContentHelpers.makeHtmlEmote; + sendTextFn = ContentHelpers.makeEmoteMessage; } - 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, - }); - } + const quotingEv = RoomViewStore.getQuotingEvent(); + const content = quotingEv ? Quote.getRelationship(quotingEv) : {}; + // we have finished quoting, clear the quotingEvent + // TODO maybe delay this until the event actually sends? + dis.dispatch({ + action: 'quote_event', + event: null, + }); let sendMessagePromise; if (contentHTML) { - sendMessagePromise = sendHtmlFn.call( - this.client, this.props.room.roomId, contentText, contentHTML, - ); + Object.assign(content, sendHtmlFn(contentText, contentHTML)); + sendMessagePromise = this.client.sendMessage(this.props.room.roomId, content); } else { - sendMessagePromise = sendTextFn.call(this.client, this.props.room.roomId, contentText); + Object.assign(content, sendTextFn(contentText)); + sendMessagePromise = this.client.sendMessage(this.props.room.roomId, content); } sendMessagePromise.done((res) => { diff --git a/src/components/views/rooms/QuotePreview.js b/src/components/views/rooms/QuotePreview.js index 614d51dada..590ee21b8f 100644 --- a/src/components/views/rooms/QuotePreview.js +++ b/src/components/views/rooms/QuotePreview.js @@ -71,8 +71,10 @@ export default class QuotePreview extends React.Component { onClick={cancelQuoting} />
- +
; } } + +function dummyOnWidgetLoad() {} From 18145460b2764e0fbc637ce23832ca98100ca7ee Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sat, 10 Feb 2018 12:31:22 +0000 Subject: [PATCH 002/190] fix Replies for e2e Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/Quote.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/views/elements/Quote.js b/src/components/views/elements/Quote.js index fa571aa063..33819d522a 100644 --- a/src/components/views/elements/Quote.js +++ b/src/components/views/elements/Quote.js @@ -121,9 +121,10 @@ export default class Quote extends React.Component { static getInReplyTo(ev) { if (ev.isRedacted()) return; - const {'m.relates_to': mRelatesTo} = ev.getContent(); + const mRelatesTo = ev.getWireContent()['m.relates_to']; if (mRelatesTo) { - return mRelatesTo['m.in_reply_to']; + const mInReplyTo = mRelatesTo['m.in_reply_to']; + if ('event_id' in mInReplyTo) return mInReplyTo; } } From fbb950e06433fd3aa4166b398ab3a2940538ebc2 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sat, 10 Feb 2018 12:38:25 +0000 Subject: [PATCH 003/190] mass s/Quote/Reply Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- .../views/elements/{Quote.js => Reply.js} | 18 +++++++++--------- src/components/views/messages/TextualBody.js | 1 - src/components/views/rooms/EventTile.js | 8 ++++---- .../views/rooms/MessageComposerInput.js | 8 ++++---- .../rooms/{QuotePreview.js => ReplyPreview.js} | 14 +++++++------- 5 files changed, 24 insertions(+), 25 deletions(-) rename src/components/views/elements/{Quote.js => Reply.js} (91%) rename src/components/views/rooms/{QuotePreview.js => ReplyPreview.js} (83%) diff --git a/src/components/views/elements/Quote.js b/src/components/views/elements/Reply.js similarity index 91% rename from src/components/views/elements/Quote.js rename to src/components/views/elements/Reply.js index 33819d522a..6d456cf6b4 100644 --- a/src/components/views/elements/Quote.js +++ b/src/components/views/elements/Reply.js @@ -23,7 +23,7 @@ import {MatrixEvent} from 'matrix-js-sdk'; import {makeUserPermalink} from "../../../matrix-to"; import SettingsStore from "../../../settings/SettingsStore"; -export default class Quote extends React.Component { +export default class Reply extends React.Component { static propTypes = { // The parent event parentEv: PropTypes.instanceOf(MatrixEvent), @@ -68,7 +68,7 @@ export default class Quote extends React.Component { async initialize() { const {parentEv} = this.props; - const inReplyTo = Quote.getInReplyTo(parentEv); + const inReplyTo = Reply.getInReplyTo(parentEv); const ev = await this.getEvent(this.room, inReplyTo['event_id']); this.setState({ @@ -79,7 +79,7 @@ export default class Quote extends React.Component { async loadNextEvent() { this.props.onWidgetLoad(); const ev = this.state.events[0]; - const inReplyTo = Quote.getInReplyTo(ev); + const inReplyTo = Reply.getInReplyTo(ev); if (!inReplyTo) { this.setState({ @@ -139,8 +139,8 @@ export default class Quote extends React.Component { } static getQuote(parentEv, onWidgetLoad) { - if (!SettingsStore.isFeatureEnabled("feature_rich_quoting") || !Quote.getInReplyTo(parentEv)) return null; - return ; + if (!SettingsStore.isFeatureEnabled("feature_rich_quoting") || !Reply.getInReplyTo(parentEv)) return null; + return ; } render() { @@ -149,10 +149,10 @@ export default class Quote extends React.Component { const ev = this.state.loadedEv; const Pill = sdk.getComponent('elements.Pill'); const room = MatrixClientPeg.get().getRoom(ev.getRoomId()); - header =
+ header =
{ _t('In reply to ', {}, { - 'a': (sub) => { sub }, + 'a': (sub) => { sub }, 'pill': , }) @@ -171,9 +171,9 @@ export default class Quote extends React.Component { dateSep = ; } - return
+ return
{ dateSep } - +
; }); diff --git a/src/components/views/messages/TextualBody.js b/src/components/views/messages/TextualBody.js index 7da4dd8644..c91178d9b5 100644 --- a/src/components/views/messages/TextualBody.js +++ b/src/components/views/messages/TextualBody.js @@ -182,7 +182,6 @@ 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'); diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index 7e9a7a75f1..3b72525fbd 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -18,7 +18,7 @@ limitations under the License. 'use strict'; -import Quote from "../elements/Quote"; +import Reply from "../elements/Reply"; const React = require('react'); import PropTypes from 'prop-types'; @@ -589,12 +589,12 @@ module.exports = withMatrixClient(React.createClass({ ); } - case 'quote': { + case 'reply': { return (
{ avatar } { sender } -
+
{ timestamp } @@ -622,7 +622,7 @@ module.exports = withMatrixClient(React.createClass({ { timestamp } { this._renderE2EPadlock() } - { Quote.getQuote(this.props.mxEvent, this.props.onWidgetLoad) } + { Reply.getQuote(this.props.mxEvent, this.props.onWidgetLoad) }
- { SettingsStore.isFeatureEnabled("feature_rich_quoting") && } + { SettingsStore.isFeatureEnabled("feature_rich_quoting") && } this.autocomplete = e} room={this.props.room} diff --git a/src/components/views/rooms/QuotePreview.js b/src/components/views/rooms/ReplyPreview.js similarity index 83% rename from src/components/views/rooms/QuotePreview.js rename to src/components/views/rooms/ReplyPreview.js index 590ee21b8f..045c3da9b3 100644 --- a/src/components/views/rooms/QuotePreview.js +++ b/src/components/views/rooms/ReplyPreview.js @@ -27,7 +27,7 @@ function cancelQuoting() { }); } -export default class QuotePreview extends React.Component { +export default class ReplyPreview extends React.Component { constructor(props, context) { super(props, context); @@ -61,17 +61,17 @@ export default class QuotePreview extends React.Component { const EventTile = sdk.getComponent('rooms.EventTile'); const EmojiText = sdk.getComponent('views.elements.EmojiText'); - return
-
- + return
+
+ { '💬 ' + _t('Replying') } -
+
-
- +
+
; } From 23c0daa83ab2789b996f14cf20172d1656dfd9b5 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sat, 10 Feb 2018 12:41:31 +0000 Subject: [PATCH 004/190] pass onWidgetLoad to fix console err for e2e Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/Reply.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/elements/Reply.js b/src/components/views/elements/Reply.js index 6d456cf6b4..3ab7af6ced 100644 --- a/src/components/views/elements/Reply.js +++ b/src/components/views/elements/Reply.js @@ -173,7 +173,7 @@ export default class Reply extends React.Component { return
{ dateSep } - +
; }); From 7425d01b212e7707482ac1e54365b60acf65c398 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sat, 10 Feb 2018 15:45:42 +0000 Subject: [PATCH 005/190] tidy, improve error handling and improve Replies, run gen-i18n Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/Reply.js | 51 ++++++++++++++++---------- src/i18n/strings/en_EN.json | 5 ++- 2 files changed, 35 insertions(+), 21 deletions(-) diff --git a/src/components/views/elements/Reply.js b/src/components/views/elements/Reply.js index 3ab7af6ced..ff2a6fc36a 100644 --- a/src/components/views/elements/Reply.js +++ b/src/components/views/elements/Reply.js @@ -23,6 +23,9 @@ import {MatrixEvent} from 'matrix-js-sdk'; import {makeUserPermalink} from "../../../matrix-to"; import SettingsStore from "../../../settings/SettingsStore"; +// This component does no cycle detection, simply because the only way to make such a cycle +// would be to craft event_id's, using a custom homeserver; even then the impact would be low +// as each event being loaded (after the first) is triggered by an explicit user action. export default class Reply extends React.Component { static propTypes = { // The parent event @@ -34,17 +37,6 @@ export default class Reply extends React.Component { constructor(props, context) { super(props, context); - /* - this.state = { - // The event related to this quote and their nested rich quotes - events: [], - // Whether the top (oldest) event should be shown or spoilered - show: true, - // Whether an error was encountered fetching nested older event, show node if it does - err: false, - loading: true, - };*/ - this.state = { // The loaded events to be rendered as linear-replies events: [], @@ -55,7 +47,7 @@ export default class Reply extends React.Component { loading: true, // Whether as error was encountered fetching a replied to event. - err: null, + err: false, }; this.onQuoteClick = this.onQuoteClick.bind(this); @@ -71,9 +63,13 @@ export default class Reply extends React.Component { const inReplyTo = Reply.getInReplyTo(parentEv); const ev = await this.getEvent(this.room, inReplyTo['event_id']); - this.setState({ - events: [ev], - }, this.loadNextEvent); + if (ev) { + this.setState({ + events: [ev], + }, this.loadNextEvent); + } else { + this.setState({err: true}); + } } async loadNextEvent() { @@ -89,7 +85,11 @@ export default class Reply extends React.Component { } const loadedEv = await this.getEvent(this.room, inReplyTo['event_id']); - this.setState({loadedEv}); + if (loadedEv) { + this.setState({loadedEv}); + } else { + this.setState({err: true}); + } } getRoom(id) { @@ -105,7 +105,11 @@ export default class Reply extends React.Component { const event = room.findEventById(eventId); if (event) return event; - await MatrixClientPeg.get().getEventTimeline(room.getUnfilteredTimelineSet(), eventId); + try { + await MatrixClientPeg.get().getEventTimeline(room.getUnfilteredTimelineSet(), eventId); + } catch (e) { + return; + } return room.findEventById(eventId); } @@ -145,7 +149,15 @@ export default class Reply extends React.Component { render() { let header = null; - if (this.state.loadedEv) { + + if (this.state.err) { + header =
+ { + _t('Unable to load event that was replied to, ' + + 'it either does not exist or you do not have permission to view it.') + } +
; + } else if (this.state.loadedEv) { const ev = this.state.loadedEv; const Pill = sdk.getComponent('elements.Pill'); const room = MatrixClientPeg.get().getRoom(ev.getRoomId()); @@ -159,7 +171,8 @@ export default class Reply extends React.Component { }
; } else if (this.state.loading) { - header =
LOADING...
; + const Spinner = sdk.getComponent("elements.Spinner"); + header = ; } const EventTile = sdk.getComponent('views.rooms.EventTile'); diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 6139ac2a91..5bde93f46c 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -359,8 +359,8 @@ "Idle": "Idle", "Offline": "Offline", "Unknown": "Unknown", - "Replying": "Replying", "Seen by %(userName)s at %(dateTime)s": "Seen by %(userName)s at %(dateTime)s", + "Replying": "Replying", "No rooms to show": "No rooms to show", "Unnamed room": "Unnamed room", "World readable": "World readable", @@ -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.", @@ -648,6 +648,7 @@ "expand": "expand", "Custom of %(powerLevel)s": "Custom of %(powerLevel)s", "Custom level": "Custom level", + "Unable to load event that was replied to, it either does not exist or you do not have permission to view it.": "Unable to load event that was replied to, it either does not exist or you do not have permission to view it.", "In reply to ": "In reply to ", "Room directory": "Room directory", "Start chat": "Start chat", From 25bc9cfbe7469db03a40d9f5672dd513774f9c4b Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sat, 10 Feb 2018 15:47:32 +0000 Subject: [PATCH 006/190] make spinner size more appropriate Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/Reply.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/elements/Reply.js b/src/components/views/elements/Reply.js index ff2a6fc36a..c513535e85 100644 --- a/src/components/views/elements/Reply.js +++ b/src/components/views/elements/Reply.js @@ -172,7 +172,7 @@ export default class Reply extends React.Component {
; } else if (this.state.loading) { const Spinner = sdk.getComponent("elements.Spinner"); - header = ; + header = ; } const EventTile = sdk.getComponent('views.rooms.EventTile'); From 7bf05b071533a9cf407637f00daa71bd9508c2fa Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sat, 10 Feb 2018 16:01:19 +0000 Subject: [PATCH 007/190] add unmounted guard Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/Reply.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/components/views/elements/Reply.js b/src/components/views/elements/Reply.js index c513535e85..31e94e1d4a 100644 --- a/src/components/views/elements/Reply.js +++ b/src/components/views/elements/Reply.js @@ -51,6 +51,8 @@ export default class Reply extends React.Component { }; this.onQuoteClick = this.onQuoteClick.bind(this); + + this.unmounted = false; } componentWillMount() { @@ -58,11 +60,17 @@ export default class Reply extends React.Component { this.initialize(); } + componentWillUnmount() { + this.unmounted = true; + } + async initialize() { const {parentEv} = this.props; const inReplyTo = Reply.getInReplyTo(parentEv); const ev = await this.getEvent(this.room, inReplyTo['event_id']); + if (this.unmounted) return; + if (ev) { this.setState({ events: [ev], @@ -78,6 +86,7 @@ export default class Reply extends React.Component { const inReplyTo = Reply.getInReplyTo(ev); if (!inReplyTo) { + if (this.unmounted) return; this.setState({ loading: false, }); @@ -85,6 +94,8 @@ export default class Reply extends React.Component { } const loadedEv = await this.getEvent(this.room, inReplyTo['event_id']); + if (this.unmounted) return; + if (loadedEv) { this.setState({loadedEv}); } else { From aeedf48d841b89ab75736d4b3cd4f5e65ea0822e Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sun, 11 Feb 2018 11:45:13 +0000 Subject: [PATCH 008/190] fix weird `in` op behaviour with null Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/Reply.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/views/elements/Reply.js b/src/components/views/elements/Reply.js index 31e94e1d4a..944d90cdbd 100644 --- a/src/components/views/elements/Reply.js +++ b/src/components/views/elements/Reply.js @@ -137,9 +137,9 @@ export default class Reply extends React.Component { if (ev.isRedacted()) return; const mRelatesTo = ev.getWireContent()['m.relates_to']; - if (mRelatesTo) { + if (mRelatesTo && mRelatesTo['m.in_reply_to']) { const mInReplyTo = mRelatesTo['m.in_reply_to']; - if ('event_id' in mInReplyTo) return mInReplyTo; + if (mInReplyTo['event_id']) return mInReplyTo; } } From 8062494692d5781cb223d2dc63c4ef42391ad94f Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 16 Feb 2018 20:58:39 +0000 Subject: [PATCH 009/190] show replies in ReplyPreview Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/EventTile.js | 21 +++++++++++++++++++++ src/components/views/rooms/ReplyPreview.js | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index 3b72525fbd..36fc87b7cd 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -609,6 +609,27 @@ module.exports = withMatrixClient(React.createClass({ ); } + case 'reply_preview': { + return ( +
+ { avatar } + { sender } +
+ + { timestamp } + + { this._renderE2EPadlock() } + { Reply.getQuote(this.props.mxEvent, this.props.onWidgetLoad) } + +
+
+ ); + } default: { return (
diff --git a/src/components/views/rooms/ReplyPreview.js b/src/components/views/rooms/ReplyPreview.js index 045c3da9b3..0404511c9f 100644 --- a/src/components/views/rooms/ReplyPreview.js +++ b/src/components/views/rooms/ReplyPreview.js @@ -71,7 +71,7 @@ export default class ReplyPreview extends React.Component { onClick={cancelQuoting} />
- +
; } From cb293a852dec1ba884ade960e65b9288f4039851 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 16 Feb 2018 21:07:25 +0000 Subject: [PATCH 010/190] reply and reply_preview only differ in whether they contain Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/EventTile.js | 29 ++++++------------------- 1 file changed, 7 insertions(+), 22 deletions(-) diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index 36fc87b7cd..5ccba1cf0f 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -589,37 +589,22 @@ module.exports = withMatrixClient(React.createClass({ ); } - case 'reply': { - return ( -
- { avatar } - { sender } -
- - { timestamp } - - { this._renderE2EPadlock() } - -
-
- ); - } + + case 'reply': case 'reply_preview': { return (
{ avatar } { sender } -
+
{ timestamp } { this._renderE2EPadlock() } - { Reply.getQuote(this.props.mxEvent, this.props.onWidgetLoad) } + { + this.props.tileShape === 'reply_preview' + && Reply.getQuote(this.props.mxEvent, this.props.onWidgetLoad) + } Date: Fri, 16 Feb 2018 21:14:03 +0000 Subject: [PATCH 011/190] fix 12/24h in Reply/ReplyPreview Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/Reply.js | 5 ++++- src/components/views/rooms/ReplyPreview.js | 7 ++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/components/views/elements/Reply.js b/src/components/views/elements/Reply.js index 944d90cdbd..f9161c7ada 100644 --- a/src/components/views/elements/Reply.js +++ b/src/components/views/elements/Reply.js @@ -197,7 +197,10 @@ export default class Reply extends React.Component { return
{ dateSep } - +
; }); diff --git a/src/components/views/rooms/ReplyPreview.js b/src/components/views/rooms/ReplyPreview.js index 0404511c9f..18e21c5ebc 100644 --- a/src/components/views/rooms/ReplyPreview.js +++ b/src/components/views/rooms/ReplyPreview.js @@ -19,6 +19,7 @@ import dis from '../../../dispatcher'; import sdk from '../../../index'; import { _t } from '../../../languageHandler'; import RoomViewStore from '../../../stores/RoomViewStore'; +import SettingsStore from "../../../settings/SettingsStore"; function cancelQuoting() { dis.dispatch({ @@ -71,7 +72,11 @@ export default class ReplyPreview extends React.Component { onClick={cancelQuoting} />
- +
; } From 0d6fc9bd3a31ffa64e93030ff36ebb40db146250 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 16 Feb 2018 21:17:41 +0000 Subject: [PATCH 012/190] fix Composer focus after twiddling with Replies Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/Reply.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/views/elements/Reply.js b/src/components/views/elements/Reply.js index f9161c7ada..4a9d0d3380 100644 --- a/src/components/views/elements/Reply.js +++ b/src/components/views/elements/Reply.js @@ -17,6 +17,7 @@ import React from 'react'; import sdk from '../../../index'; import {_t} from '../../../languageHandler'; import PropTypes from 'prop-types'; +import dis from '../../../dispatcher'; import MatrixClientPeg from '../../../MatrixClientPeg'; import {wantsDateSeparator} from '../../../DateUtils'; import {MatrixEvent} from 'matrix-js-sdk'; @@ -131,6 +132,8 @@ export default class Reply extends React.Component { loadedEv: null, events, }, this.loadNextEvent); + + dis.dispatch({action: 'focus_composer'}); } static getInReplyTo(ev) { From 4c08c51044e5bca4523b7374310d486d23e1507c Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 16 Feb 2018 21:24:42 +0000 Subject: [PATCH 013/190] Reply; delay call to onWidgetLoad until after async setState completes Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/Reply.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/components/views/elements/Reply.js b/src/components/views/elements/Reply.js index 4a9d0d3380..bbcfa00b25 100644 --- a/src/components/views/elements/Reply.js +++ b/src/components/views/elements/Reply.js @@ -82,7 +82,6 @@ export default class Reply extends React.Component { } async loadNextEvent() { - this.props.onWidgetLoad(); const ev = this.state.events[0]; const inReplyTo = Reply.getInReplyTo(ev); @@ -90,7 +89,7 @@ export default class Reply extends React.Component { if (this.unmounted) return; this.setState({ loading: false, - }); + }, this.props.onWidgetLoad); return; } @@ -98,9 +97,9 @@ export default class Reply extends React.Component { if (this.unmounted) return; if (loadedEv) { - this.setState({loadedEv}); + this.setState({loadedEv}, this.props.onWidgetLoad); } else { - this.setState({err: true}); + this.setState({err: true}, this.props.onWidgetLoad); } } From 8fa56f8c9a882299c1308ba9c42b6098ca1408b5 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 19 Feb 2018 14:27:10 +0000 Subject: [PATCH 014/190] update and improve comments Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/Reply.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/views/elements/Reply.js b/src/components/views/elements/Reply.js index bbcfa00b25..6da589e7f2 100644 --- a/src/components/views/elements/Reply.js +++ b/src/components/views/elements/Reply.js @@ -24,14 +24,14 @@ import {MatrixEvent} from 'matrix-js-sdk'; import {makeUserPermalink} from "../../../matrix-to"; import SettingsStore from "../../../settings/SettingsStore"; -// This component does no cycle detection, simply because the only way to make such a cycle -// would be to craft event_id's, using a custom homeserver; even then the impact would be low -// as each event being loaded (after the first) is triggered by an explicit user action. +// This component does no cycle detection, simply because the only way to make such a cycle would be to +// craft event_id's, using a homeserver that generates predictable event IDs; even then the impact would +// be low as each event being loaded (after the first) is triggered by an explicit user action. export default class Reply extends React.Component { static propTypes = { - // The parent event + // the latest event in this chain of replies parentEv: PropTypes.instanceOf(MatrixEvent), - + // called when the preview's contents has loaded onWidgetLoad: PropTypes.func.isRequired, }; From 6510989ac6affa725a026d348cceb623883de37a Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 19 Feb 2018 14:28:31 +0000 Subject: [PATCH 015/190] move unmounted init to willMount Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/Reply.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/views/elements/Reply.js b/src/components/views/elements/Reply.js index 6da589e7f2..67e6b9d9ca 100644 --- a/src/components/views/elements/Reply.js +++ b/src/components/views/elements/Reply.js @@ -52,11 +52,10 @@ export default class Reply extends React.Component { }; this.onQuoteClick = this.onQuoteClick.bind(this); - - this.unmounted = false; } componentWillMount() { + this.unmounted = false; this.room = this.getRoom(this.props.parentEv.getRoomId()); this.initialize(); } From 34b427d15e106eb46a459ff0a1fe8722e8a57701 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 19 Feb 2018 23:41:07 +0000 Subject: [PATCH 016/190] s/quote_event/reply_to_event/ Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- .../views/rooms/MessageComposerInput.js | 11 ++--------- src/components/views/rooms/ReplyPreview.js | 2 +- src/stores/RoomViewStore.js | 16 +++++++++++----- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index c051471ba6..1de53b4cfc 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -275,7 +275,7 @@ export default class MessageComposerInput extends React.Component { let contentState = this.state.editorState.getCurrentContent(); switch (payload.action) { - case 'quote_event': + case 'reply_to_event': case 'focus_composer': editor.focus(); break; @@ -838,14 +838,7 @@ export default class MessageComposerInput extends React.Component { sendTextFn = ContentHelpers.makeEmoteMessage; } - const quotingEv = RoomViewStore.getQuotingEvent(); - const content = quotingEv ? Reply.getRelationship(quotingEv) : {}; - // we have finished quoting, clear the quotingEvent - // TODO maybe delay this until the event actually sends? - dis.dispatch({ - action: 'quote_event', - event: null, - }); + const content = Reply.getMRelatesTo(RoomViewStore.getQuotingEvent()); let sendMessagePromise; if (contentHTML) { diff --git a/src/components/views/rooms/ReplyPreview.js b/src/components/views/rooms/ReplyPreview.js index 18e21c5ebc..dd11b0df33 100644 --- a/src/components/views/rooms/ReplyPreview.js +++ b/src/components/views/rooms/ReplyPreview.js @@ -23,7 +23,7 @@ import SettingsStore from "../../../settings/SettingsStore"; function cancelQuoting() { dis.dispatch({ - action: 'quote_event', + action: 'reply_to_event', event: null, }); } diff --git a/src/stores/RoomViewStore.js b/src/stores/RoomViewStore.js index 4c010f4e8e..2c81f9de23 100644 --- a/src/stores/RoomViewStore.js +++ b/src/stores/RoomViewStore.js @@ -111,10 +111,16 @@ class RoomViewStore extends Store { forwardingEvent: payload.event, }); break; - case 'quote_event': + case 'reply_to_event': this._setState({ - quotingEvent: payload.event, + replyingToEvent: payload.event, }); + break; + case 'message_sent': + this._setState({ + replyingToEvent: null, + }); + break; } } @@ -132,8 +138,8 @@ class RoomViewStore extends Store { shouldPeek: payload.should_peek === undefined ? true : payload.should_peek, // have we sent a join request for this room and are waiting for a response? joining: payload.joining || false, - // Reset quotingEvent because we don't want cross-room because bad UX - quotingEvent: null, + // Reset replyingToEvent because we don't want cross-room because bad UX + replyingToEvent: null, }; if (this._state.forwardingEvent) { @@ -297,7 +303,7 @@ class RoomViewStore extends Store { // The mxEvent if one is currently being replied to/quoted getQuotingEvent() { - return this._state.quotingEvent; + return this._state.replyingToEvent; } shouldPeek() { From 7048d85246200aefa04dfa4bfbc8d1aa8b31836a Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 19 Feb 2018 23:42:04 +0000 Subject: [PATCH 017/190] attach message_sent and replies to file uploads Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/ContentMessages.js | 6 +++--- src/components/structures/RoomView.js | 13 ++++++++--- src/components/views/elements/Reply.js | 30 +++++++++++--------------- 3 files changed, 26 insertions(+), 23 deletions(-) diff --git a/src/ContentMessages.js b/src/ContentMessages.js index 8d40b65124..f0e8736aba 100644 --- a/src/ContentMessages.js +++ b/src/ContentMessages.js @@ -275,13 +275,13 @@ class ContentMessages { this.nextId = 0; } - sendContentToRoom(file, roomId, matrixClient) { - const content = { + sendContentToRoom(file, roomId, matrixClient, baseContent) { + const content = Object.assign({}, baseContent, { body: file.name || 'Attachment', info: { size: file.size, }, - }; + }); // if we have a mime type for the file, add it to the message metadata if (file.type) { diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 5304f38901..869dffcf9b 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -45,6 +45,7 @@ import { KeyCode, isOnlyCtrlOrCmdKeyEvent } from '../../Keyboard'; import RoomViewStore from '../../stores/RoomViewStore'; import RoomScrollStateStore from '../../stores/RoomScrollStateStore'; import SettingsStore from "../../settings/SettingsStore"; +import Reply from "../views/elements/Reply"; const DEBUG = false; let debuglog = function() {}; @@ -895,11 +896,17 @@ module.exports = React.createClass({ return; } + const baseContent = Reply.getMRelatesTo(RoomViewStore.getQuotingEvent()); + ContentMessages.sendContentToRoom( - file, this.state.room.roomId, MatrixClientPeg.get(), - ).done(undefined, (error) => { + file, this.state.room.roomId, MatrixClientPeg.get(), baseContent, + ).done(() => { + dis.dispatch({ + action: 'message_sent', + }); + }, (error) => { if (error.name === "UnknownDeviceError") { - // Let the staus bar handle this + // Let the status bar handle this return; } const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); diff --git a/src/components/views/elements/Reply.js b/src/components/views/elements/Reply.js index 67e6b9d9ca..5b213690cc 100644 --- a/src/components/views/elements/Reply.js +++ b/src/components/views/elements/Reply.js @@ -56,7 +56,7 @@ export default class Reply extends React.Component { componentWillMount() { this.unmounted = false; - this.room = this.getRoom(this.props.parentEv.getRoomId()); + this.room = MatrixClientPeg.get().getRoom(this.props.parentEv.getRoomId()); this.initialize(); } @@ -67,8 +67,12 @@ export default class Reply extends React.Component { async initialize() { const {parentEv} = this.props; const inReplyTo = Reply.getInReplyTo(parentEv); + if (!inReplyTo) { + this.setState({err: true}); + return; + } - const ev = await this.getEvent(this.room, inReplyTo['event_id']); + const ev = await Reply.getEvent(this.room, inReplyTo['event_id']); if (this.unmounted) return; if (ev) { @@ -81,18 +85,18 @@ export default class Reply extends React.Component { } async loadNextEvent() { + if (this.unmounted) return; const ev = this.state.events[0]; const inReplyTo = Reply.getInReplyTo(ev); if (!inReplyTo) { - if (this.unmounted) return; this.setState({ loading: false, }, this.props.onWidgetLoad); return; } - const loadedEv = await this.getEvent(this.room, inReplyTo['event_id']); + const loadedEv = await Reply.getEvent(this.room, inReplyTo['event_id']); if (this.unmounted) return; if (loadedEv) { @@ -102,23 +106,14 @@ export default class Reply extends React.Component { } } - getRoom(id) { - const cli = MatrixClientPeg.get(); - if (id[0] === '!') return cli.getRoom(id); - - return cli.getRooms().find((r) => { - return r.getAliases().includes(id); - }); - } - - async getEvent(room, eventId) { + static async getEvent(room, eventId) { const event = room.findEventById(eventId); if (event) return event; try { await MatrixClientPeg.get().getEventTimeline(room.getUnfilteredTimelineSet(), eventId); } catch (e) { - return; + return null; } return room.findEventById(eventId); } @@ -144,7 +139,8 @@ export default class Reply extends React.Component { } } - static getRelationship(ev) { + static getMRelatesTo(ev) { + if (!ev) return {}; return { 'm.relates_to': { 'm.in_reply_to': { @@ -155,7 +151,7 @@ export default class Reply extends React.Component { } static getQuote(parentEv, onWidgetLoad) { - if (!SettingsStore.isFeatureEnabled("feature_rich_quoting") || !Reply.getInReplyTo(parentEv)) return null; + if (!SettingsStore.isFeatureEnabled("feature_rich_quoting") || !Reply.getInReplyTo(parentEv)) return
; return ; } From 90f9badbf3c0f18eb799a9b80bb7dd23a9d1e453 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 20 Feb 2018 15:40:19 +0000 Subject: [PATCH 018/190] s/Reply/ReplyThread/ Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/structures/RoomView.js | 2 +- .../views/elements/{Reply.js => ReplyThread.js} | 8 ++++---- src/components/views/rooms/EventTile.js | 2 +- src/components/views/rooms/MessageComposerInput.js | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) rename src/components/views/elements/{Reply.js => ReplyThread.js} (96%) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 869dffcf9b..ae9522e511 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -45,7 +45,7 @@ import { KeyCode, isOnlyCtrlOrCmdKeyEvent } from '../../Keyboard'; import RoomViewStore from '../../stores/RoomViewStore'; import RoomScrollStateStore from '../../stores/RoomScrollStateStore'; import SettingsStore from "../../settings/SettingsStore"; -import Reply from "../views/elements/Reply"; +import Reply from "../views/elements/ReplyThread"; const DEBUG = false; let debuglog = function() {}; diff --git a/src/components/views/elements/Reply.js b/src/components/views/elements/ReplyThread.js similarity index 96% rename from src/components/views/elements/Reply.js rename to src/components/views/elements/ReplyThread.js index 5b213690cc..24ab6163fb 100644 --- a/src/components/views/elements/Reply.js +++ b/src/components/views/elements/ReplyThread.js @@ -159,7 +159,7 @@ export default class Reply extends React.Component { let header = null; if (this.state.err) { - header =
+ header =
{ _t('Unable to load event that was replied to, ' + 'it either does not exist or you do not have permission to view it.') @@ -169,10 +169,10 @@ export default class Reply extends React.Component { const ev = this.state.loadedEv; const Pill = sdk.getComponent('elements.Pill'); const room = MatrixClientPeg.get().getRoom(ev.getRoomId()); - header =
+ header =
{ _t('In reply to ', {}, { - 'a': (sub) => { sub }, + 'a': (sub) => { sub }, 'pill': , }) @@ -192,7 +192,7 @@ export default class Reply extends React.Component { dateSep = ; } - return
+ return
{ dateSep } Date: Tue, 20 Feb 2018 15:45:25 +0000 Subject: [PATCH 019/190] restrict to m.text for now Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/ContentMessages.js | 6 +++--- src/components/structures/RoomView.js | 4 +--- src/components/views/rooms/MessageComposerInput.js | 5 +++++ src/stores/RoomViewStore.js | 5 ----- 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/ContentMessages.js b/src/ContentMessages.js index f0e8736aba..8d40b65124 100644 --- a/src/ContentMessages.js +++ b/src/ContentMessages.js @@ -275,13 +275,13 @@ class ContentMessages { this.nextId = 0; } - sendContentToRoom(file, roomId, matrixClient, baseContent) { - const content = Object.assign({}, baseContent, { + sendContentToRoom(file, roomId, matrixClient) { + const content = { body: file.name || 'Attachment', info: { size: file.size, }, - }); + }; // if we have a mime type for the file, add it to the message metadata if (file.type) { diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index ae9522e511..75fa316030 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -896,10 +896,8 @@ module.exports = React.createClass({ return; } - const baseContent = Reply.getMRelatesTo(RoomViewStore.getQuotingEvent()); - ContentMessages.sendContentToRoom( - file, this.state.room.roomId, MatrixClientPeg.get(), baseContent, + file, this.state.room.roomId, MatrixClientPeg.get(), ).done(() => { dis.dispatch({ action: 'message_sent', diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index e8725bdf05..c2fcfd9688 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -853,6 +853,11 @@ export default class MessageComposerInput extends React.Component { dis.dispatch({ action: 'message_sent', }); + // Once replies are not only for text, we can use message_sent for this + dis.dispatch({ + action: 'reply_to_event', + event: null, + }); }, (e) => onSendMessageFailed(e, this.props.room)); this.setState({ diff --git a/src/stores/RoomViewStore.js b/src/stores/RoomViewStore.js index 2c81f9de23..1e7e50eae0 100644 --- a/src/stores/RoomViewStore.js +++ b/src/stores/RoomViewStore.js @@ -116,11 +116,6 @@ class RoomViewStore extends Store { replyingToEvent: payload.event, }); break; - case 'message_sent': - this._setState({ - replyingToEvent: null, - }); - break; } } From df56a67fda56947a1ea223fdd3b958473394ca13 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sun, 4 Mar 2018 12:39:34 +0000 Subject: [PATCH 020/190] Add reply fallback and run gen-i18n Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/HtmlUtils.js | 14 +++- src/components/views/elements/ReplyThread.js | 54 +++++++++++--- src/components/views/messages/TextualBody.js | 3 + .../views/rooms/MessageComposerInput.js | 37 +++++++--- src/i18n/strings/en_EN.json | 70 ++++++++++--------- 5 files changed, 123 insertions(+), 55 deletions(-) diff --git a/src/HtmlUtils.js b/src/HtmlUtils.js index 5c6cbd6c1b..139c522932 100644 --- a/src/HtmlUtils.js +++ b/src/HtmlUtils.js @@ -17,6 +17,8 @@ limitations under the License. 'use strict'; +import ReplyThread from "./components/views/elements/ReplyThread"; + const React = require('react'); const sanitizeHtml = require('sanitize-html'); const highlight = require('highlight.js'); @@ -184,6 +186,7 @@ const sanitizeHtmlParams = { ], allowedAttributes: { // custom ones first: + blockquote: ['data-mx-reply'], // for reply fallback font: ['color', 'data-mx-bg-color', 'data-mx-color', 'style'], // custom to matrix span: ['data-mx-bg-color', 'data-mx-color', 'style'], // custom to matrix a: ['href', 'name', 'target', 'rel'], // remote target: custom to matrix @@ -408,10 +411,19 @@ class TextHighlighter extends BaseHighlighter { * * opts.highlightLink: optional href to add to highlighted words * opts.disableBigEmoji: optional argument to disable the big emoji class. + * opts.stripReplyFallback: optional argument specifying the event is a reply and so fallback needs removing */ export function bodyToHtml(content, highlights, opts={}) { const isHtml = (content.format === "org.matrix.custom.html"); - const body = isHtml ? content.formatted_body : escape(content.body); + let body; + if (isHtml) { + body = content.formatted_body; + // Part of Replies fallback support + if (opts.stripReplyFallback) body = ReplyThread.stripHTMLReply(body); + } else { + // Part of Replies fallback support - special because strip must be before escape + body = opts.stripReplyFallback ? ReplyThread.stripPlainReply(content.body) : escape(content.body); + } let bodyHasEmoji = false; diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index 24ab6163fb..a4728ac67a 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -21,13 +21,13 @@ import dis from '../../../dispatcher'; import MatrixClientPeg from '../../../MatrixClientPeg'; import {wantsDateSeparator} from '../../../DateUtils'; import {MatrixEvent} from 'matrix-js-sdk'; -import {makeUserPermalink} from "../../../matrix-to"; +import {makeEventPermalink, makeUserPermalink} from "../../../matrix-to"; import SettingsStore from "../../../settings/SettingsStore"; // This component does no cycle detection, simply because the only way to make such a cycle would be to // craft event_id's, using a homeserver that generates predictable event IDs; even then the impact would // be low as each event being loaded (after the first) is triggered by an explicit user action. -export default class Reply extends React.Component { +export default class ReplyThread extends React.Component { static propTypes = { // the latest event in this chain of replies parentEv: PropTypes.instanceOf(MatrixEvent), @@ -66,13 +66,13 @@ export default class Reply extends React.Component { async initialize() { const {parentEv} = this.props; - const inReplyTo = Reply.getInReplyTo(parentEv); + const inReplyTo = ReplyThread.getInReplyTo(parentEv); if (!inReplyTo) { this.setState({err: true}); return; } - const ev = await Reply.getEvent(this.room, inReplyTo['event_id']); + const ev = await ReplyThread.getEvent(this.room, inReplyTo['event_id']); if (this.unmounted) return; if (ev) { @@ -87,7 +87,7 @@ export default class Reply extends React.Component { async loadNextEvent() { if (this.unmounted) return; const ev = this.state.events[0]; - const inReplyTo = Reply.getInReplyTo(ev); + const inReplyTo = ReplyThread.getInReplyTo(ev); if (!inReplyTo) { this.setState({ @@ -96,7 +96,7 @@ export default class Reply extends React.Component { return; } - const loadedEv = await Reply.getEvent(this.room, inReplyTo['event_id']); + const loadedEv = await ReplyThread.getEvent(this.room, inReplyTo['event_id']); if (this.unmounted) return; if (loadedEv) { @@ -130,7 +130,7 @@ export default class Reply extends React.Component { } static getInReplyTo(ev) { - if (ev.isRedacted()) return; + if (!ev || ev.isRedacted()) return; const mRelatesTo = ev.getWireContent()['m.relates_to']; if (mRelatesTo && mRelatesTo['m.in_reply_to']) { @@ -139,7 +139,39 @@ export default class Reply extends React.Component { } } - static getMRelatesTo(ev) { + // Part of Replies fallback support + static stripPlainReply(body) { + const lines = body.split('\n'); + while (lines[0].startsWith('> ')) lines.shift(); + return lines.join('\n'); + } + + // Part of Replies fallback support + static stripHTMLReply(html) { + return html.replace(/^
[\s\S]+?<\/blockquote>/, ''); + } + + // Part of Replies fallback support + static getNestedReplyText(ev) { + if (!ev) return null; + + let {body, formatted_body: html} = ev.getContent(); + if (this.getInReplyTo(ev)) { + if (body) body = this.stripPlainReply(body); + if (html) html = this.stripHTMLReply(html); + } + + html = `
In reply to ` + + `${ev.getSender()} ${html || body}
`; + // `<${ev.getSender()}> ${html || body}
`; + const lines = body.split('\n'); + const first = `> <${ev.getSender()}> ${lines.shift()}`; + body = first + lines.map((line) => `> ${line}`).join('\n') + '\n'; + + return {body, html}; + } + + static getReplyEvContent(ev) { if (!ev) return {}; return { 'm.relates_to': { @@ -151,8 +183,10 @@ export default class Reply extends React.Component { } static getQuote(parentEv, onWidgetLoad) { - if (!SettingsStore.isFeatureEnabled("feature_rich_quoting") || !Reply.getInReplyTo(parentEv)) return
; - return ; + if (!SettingsStore.isFeatureEnabled("feature_rich_quoting") || !ReplyThread.getInReplyTo(parentEv)) { + return
; + } + return ; } render() { diff --git a/src/components/views/messages/TextualBody.js b/src/components/views/messages/TextualBody.js index c91178d9b5..a4ea9e4f06 100644 --- a/src/components/views/messages/TextualBody.js +++ b/src/components/views/messages/TextualBody.js @@ -35,6 +35,7 @@ import MatrixClientPeg from '../../../MatrixClientPeg'; import ContextualMenu from '../../structures/ContextualMenu'; import SettingsStore from "../../../settings/SettingsStore"; import PushProcessor from 'matrix-js-sdk/lib/pushprocessor'; +import ReplyThread from "../elements/ReplyThread"; linkifyMatrix(linkify); @@ -423,6 +424,8 @@ module.exports = React.createClass({ let body = HtmlUtils.bodyToHtml(content, this.props.highlights, { disableBigEmoji: SettingsStore.getValue('TextualBody.disableBigEmoji'), + // Part of Replies fallback support + stripReplyFallback: Boolean(ReplyThread.getInReplyTo(mxEvent)), }); if (this.props.highlightLink) { diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index c2fcfd9688..1b3299ab94 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -54,7 +54,7 @@ import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore"; import {makeUserPermalink} from "../../../matrix-to"; import ReplyPreview from "./ReplyPreview"; import RoomViewStore from '../../../stores/RoomViewStore'; -import Reply from "../elements/ReplyThread"; +import ReplyThread from "../elements/ReplyThread"; import {ContentHelpers} from 'matrix-js-sdk'; const EMOJI_SHORTNAMES = Object.keys(emojioneList); @@ -830,7 +830,18 @@ export default class MessageComposerInput extends React.Component { this.state.isRichtextEnabled ? 'html' : 'markdown', ); + const replyingToEv = RoomViewStore.getQuotingEvent(); + if (contentText.startsWith('/me')) { + if (replyingToEv) { + const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + Modal.createTrackedDialog('Emote Reply Fail', '', ErrorDialog, { + title: _t("Unable to reply"), + description: _t("At this time it is not possible to reply with an emote."), + }); + return false; + } + contentText = contentText.substring(4); // bit of a hack, but the alternative would be quite complicated if (contentHTML) contentHTML = contentHTML.replace(/\/me ?/, ''); @@ -838,18 +849,24 @@ export default class MessageComposerInput extends React.Component { sendTextFn = ContentHelpers.makeEmoteMessage; } - const content = Reply.getMRelatesTo(RoomViewStore.getQuotingEvent()); - let sendMessagePromise; - if (contentHTML) { - Object.assign(content, sendHtmlFn(contentText, contentHTML)); - sendMessagePromise = this.client.sendMessage(this.props.room.roomId, content); - } else { - Object.assign(content, sendTextFn(contentText)); - sendMessagePromise = this.client.sendMessage(this.props.room.roomId, content); + let content = contentHTML || replyingToEv ? sendHtmlFn(contentText, contentHTML) : sendTextFn(contentText); + + if (replyingToEv) { + const replyContent = ReplyThread.getReplyEvContent(replyingToEv); + content = Object.assign(replyContent, content); + + // Part of Replies fallback support - prepend the text we're sending with the text we're replying to + const nestedReply = ReplyThread.getNestedReplyText(replyingToEv); + if (nestedReply) { + if (content.formatted_body) { + content.formatted_body = nestedReply.html + content.formatted_body; + } + content.body = nestedReply.body + content.body; + } } - sendMessagePromise.done((res) => { + this.client.sendMessage(this.props.room.roomId, content).done((res) => { dis.dispatch({ action: 'message_sent', }); diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 5bde93f46c..2bb6448fa0 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -38,6 +38,10 @@ "The file '%(fileName)s' failed to upload": "The file '%(fileName)s' failed to upload", "The file '%(fileName)s' exceeds this home server's size limit for uploads": "The file '%(fileName)s' exceeds this home server's size limit for uploads", "Upload Failed": "Upload Failed", + "Failure to create room": "Failure to create room", + "Server may be unavailable, overloaded, or you hit a bug.": "Server may be unavailable, overloaded, or you hit a bug.", + "Send anyway": "Send anyway", + "Send": "Send", "Sun": "Sun", "Mon": "Mon", "Tue": "Tue", @@ -77,6 +81,7 @@ "Failed to invite users to community": "Failed to invite users to community", "Failed to invite users to %(groupId)s": "Failed to invite users to %(groupId)s", "Failed to add the following rooms to %(groupId)s:": "Failed to add the following rooms to %(groupId)s:", + "Unnamed Room": "Unnamed Room", "Riot does not have permission to send you notifications - please check your browser settings": "Riot does not have permission to send you notifications - please check your browser settings", "Riot was not given permission to send notifications - please try again": "Riot was not given permission to send notifications - please try again", "Unable to enable Notifications": "Unable to enable Notifications", @@ -174,11 +179,6 @@ "%(names)s and %(count)s others are typing|other": "%(names)s and %(count)s others are typing", "%(names)s and %(count)s others are typing|one": "%(names)s and one other is typing", "%(names)s and %(lastPerson)s are typing": "%(names)s and %(lastPerson)s are typing", - "Failure to create room": "Failure to create room", - "Server may be unavailable, overloaded, or you hit a bug.": "Server may be unavailable, overloaded, or you hit a bug.", - "Send anyway": "Send anyway", - "Send": "Send", - "Unnamed Room": "Unnamed Room", "Your browser does not support the required cryptography extensions": "Your browser does not support the required cryptography extensions", "Not a valid Riot keyfile": "Not a valid Riot keyfile", "Authentication check failed: incorrect password?": "Authentication check failed: incorrect password?", @@ -252,6 +252,29 @@ "Failed to set display name": "Failed to set display name", "Disable Notifications": "Disable Notifications", "Enable Notifications": "Enable Notifications", + "Invalid alias format": "Invalid alias format", + "'%(alias)s' is not a valid format for an alias": "'%(alias)s' is not a valid format for an alias", + "Invalid address format": "Invalid address format", + "'%(alias)s' is not a valid format for an address": "'%(alias)s' is not a valid format for an address", + "not specified": "not specified", + "not set": "not set", + "Remote addresses for this room:": "Remote addresses for this room:", + "Addresses": "Addresses", + "The main address for this room is": "The main address for this room is", + "Local addresses for this room:": "Local addresses for this room:", + "This room has no local addresses": "This room has no local addresses", + "New address (e.g. #foo:%(localDomain)s)": "New address (e.g. #foo:%(localDomain)s)", + "Invalid community ID": "Invalid community ID", + "'%(groupId)s' is not a valid community ID": "'%(groupId)s' is not a valid community ID", + "Flair": "Flair", + "Showing flair for these communities:": "Showing flair for these communities:", + "This room is not showing flair for any communities": "This room is not showing flair for any communities", + "New community ID (e.g. +foo:%(localDomain)s)": "New community ID (e.g. +foo:%(localDomain)s)", + "You have enabled URL previews by default.": "You have enabled URL previews by default.", + "You have disabled URL previews by default.": "You have disabled URL previews by default.", + "URL previews are enabled by default for participants in this room.": "URL previews are enabled by default for participants in this room.", + "URL previews are disabled by default for participants in this room.": "URL previews are disabled by default for participants in this room.", + "URL Previews": "URL Previews", "Cannot add any more widgets": "Cannot add any more widgets", "The maximum permitted number of widgets have already been added to this room.": "The maximum permitted number of widgets have already been added to this room.", "Add a widget": "Add a widget", @@ -332,6 +355,8 @@ "Server error": "Server error", "Server unavailable, overloaded, or something else went wrong.": "Server unavailable, overloaded, or something else went wrong.", "Command error": "Command error", + "Unable to reply": "Unable to reply", + "At this time it is not possible to reply with an emote.": "At this time it is not possible to reply with an emote.", "bold": "bold", "italic": "italic", "strike": "strike", @@ -342,11 +367,11 @@ "numbullet": "numbullet", "Markdown is disabled": "Markdown is disabled", "Markdown is enabled": "Markdown is enabled", - "Unpin Message": "Unpin Message", - "Jump to message": "Jump to message", "No pinned messages.": "No pinned messages.", "Loading...": "Loading...", "Pinned Messages": "Pinned Messages", + "Unpin Message": "Unpin Message", + "Jump to message": "Jump to message", "%(duration)ss": "%(duration)ss", "%(duration)sm": "%(duration)sm", "%(duration)sh": "%(duration)sh", @@ -381,9 +406,6 @@ "Drop here to restore": "Drop here to restore", "Drop here to demote": "Drop here to demote", "Drop here to tag %(section)s": "Drop here to tag %(section)s", - "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", "Press 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", @@ -471,29 +493,6 @@ "Scroll to unread messages": "Scroll to unread messages", "Jump to first unread message.": "Jump to first unread message.", "Close": "Close", - "Invalid alias format": "Invalid alias format", - "'%(alias)s' is not a valid format for an alias": "'%(alias)s' is not a valid format for an alias", - "Invalid address format": "Invalid address format", - "'%(alias)s' is not a valid format for an address": "'%(alias)s' is not a valid format for an address", - "not specified": "not specified", - "not set": "not set", - "Remote addresses for this room:": "Remote addresses for this room:", - "Addresses": "Addresses", - "The main address for this room is": "The main address for this room is", - "Local addresses for this room:": "Local addresses for this room:", - "This room has no local addresses": "This room has no local addresses", - "New address (e.g. #foo:%(localDomain)s)": "New address (e.g. #foo:%(localDomain)s)", - "Invalid community ID": "Invalid community ID", - "'%(groupId)s' is not a valid community ID": "'%(groupId)s' is not a valid community ID", - "Flair": "Flair", - "Showing flair for these communities:": "Showing flair for these communities:", - "This room is not showing flair for any communities": "This room is not showing flair for any communities", - "New community ID (e.g. +foo:%(localDomain)s)": "New community ID (e.g. +foo:%(localDomain)s)", - "You have enabled URL previews by default.": "You have enabled URL previews by default.", - "You have disabled URL previews by default.": "You have disabled URL previews by default.", - "URL previews are enabled by default for participants in this room.": "URL previews are enabled by default for participants in this room.", - "URL previews are disabled by default for participants in this room.": "URL previews are disabled by default for participants in this room.", - "URL Previews": "URL Previews", "Error decrypting audio": "Error decrypting audio", "Error decrypting attachment": "Error decrypting attachment", "Decrypt %(text)s": "Decrypt %(text)s", @@ -985,5 +984,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 3b02766be98854c6c1b71211a6f1f0db47dc98cf Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 5 Mar 2018 07:33:18 +0000 Subject: [PATCH 021/190] isHtml makes no sense if there is no formatted_body this is a bug pre-replies but replies exacerbates it Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/HtmlUtils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/HtmlUtils.js b/src/HtmlUtils.js index 139c522932..026c6b1499 100644 --- a/src/HtmlUtils.js +++ b/src/HtmlUtils.js @@ -414,7 +414,7 @@ class TextHighlighter extends BaseHighlighter { * opts.stripReplyFallback: optional argument specifying the event is a reply and so fallback needs removing */ export function bodyToHtml(content, highlights, opts={}) { - const isHtml = (content.format === "org.matrix.custom.html"); + const isHtml = (content.format === "org.matrix.custom.html") && content.formatted_body; let body; if (isHtml) { body = content.formatted_body; From ed8f087eb6bedf6b973fcb26dd325b13e3f99785 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 6 Mar 2018 15:17:57 +0000 Subject: [PATCH 022/190] fix access of element [0] of array even though it sometimes does not exist Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/ReplyThread.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index a4728ac67a..059df7a01c 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -142,7 +142,7 @@ export default class ReplyThread extends React.Component { // Part of Replies fallback support static stripPlainReply(body) { const lines = body.split('\n'); - while (lines[0].startsWith('> ')) lines.shift(); + while (lines.length && lines[0].startsWith('> ')) lines.shift(); return lines.join('\n'); } From 023632e7e435fe41e1f884bab7b0c35b79c2c86b Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 9 Mar 2018 23:12:13 +0000 Subject: [PATCH 023/190] only strip reply fallbacks if the lab is enabled Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/messages/TextualBody.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/views/messages/TextualBody.js b/src/components/views/messages/TextualBody.js index a4ea9e4f06..b0f258f7e3 100644 --- a/src/components/views/messages/TextualBody.js +++ b/src/components/views/messages/TextualBody.js @@ -422,10 +422,11 @@ module.exports = React.createClass({ const mxEvent = this.props.mxEvent; const content = mxEvent.getContent(); + const stripReply = SettingsStore.isFeatureEnabled("feature_rich_quoting") && ReplyThread.getInReplyTo(mxEvent); let body = HtmlUtils.bodyToHtml(content, this.props.highlights, { disableBigEmoji: SettingsStore.getValue('TextualBody.disableBigEmoji'), // Part of Replies fallback support - stripReplyFallback: Boolean(ReplyThread.getInReplyTo(mxEvent)), + stripReplyFallback: stripReply, }); if (this.props.highlightLink) { From 14f29e47406e3103758ecc76266664689a7c11c1 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 9 Mar 2018 23:37:42 +0000 Subject: [PATCH 024/190] fix the bugs Tulir found - THANKS Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/ReplyThread.js | 11 ++++++----- src/components/views/rooms/MessageComposerInput.js | 11 +++++++---- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index 059df7a01c..650a3845e3 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -162,11 +162,12 @@ export default class ReplyThread extends React.Component { } html = `
In reply to ` - + `${ev.getSender()} ${html || body}
`; - // `<${ev.getSender()}> ${html || body}
`; - const lines = body.split('\n'); - const first = `> <${ev.getSender()}> ${lines.shift()}`; - body = first + lines.map((line) => `> ${line}`).join('\n') + '\n'; + + `${ev.getSender()}
${html || body}
`; + const lines = body.trim().split('\n'); + if (lines.length > 0) { + lines[0] = `<${ev.getSender()}> ${lines[0]}`; + body = lines.map((line) => `> ${line}`).join('\n') + '\n\n'; + } return {body, html}; } diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index 1b3299ab94..956091215f 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -753,10 +753,15 @@ export default class MessageComposerInput extends React.Component { return true; } + const replyingToEv = RoomViewStore.getQuotingEvent(); + const mustSendHTML = Boolean(replyingToEv); + if (this.state.isRichtextEnabled) { // We should only send HTML if any block is styled or contains inline style let shouldSendHTML = false; + if (mustSendHTML) shouldSendHTML = true; + const blocks = contentState.getBlocksAsArray(); if (blocks.some((block) => block.getType() !== 'unstyled')) { shouldSendHTML = true; @@ -815,7 +820,7 @@ export default class MessageComposerInput extends React.Component { const md = new Markdown(pt); // if contains no HTML and we're not quoting (needing HTML) - if (md.isPlainText()) { + if (md.isPlainText() && !mustSendHTML) { contentText = md.toPlaintext(); } else { contentHTML = md.toHTML(); @@ -830,8 +835,6 @@ export default class MessageComposerInput extends React.Component { this.state.isRichtextEnabled ? 'html' : 'markdown', ); - const replyingToEv = RoomViewStore.getQuotingEvent(); - if (contentText.startsWith('/me')) { if (replyingToEv) { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); @@ -850,7 +853,7 @@ export default class MessageComposerInput extends React.Component { } - let content = contentHTML || replyingToEv ? sendHtmlFn(contentText, contentHTML) : sendTextFn(contentText); + let content = contentHTML ? sendHtmlFn(contentText, contentHTML) : sendTextFn(contentText); if (replyingToEv) { const replyContent = ReplyThread.getReplyEvContent(replyingToEv); From 0ed35637489e8f9f776b5515ac4f74dc5180de3c Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 16 Mar 2018 00:03:50 +0100 Subject: [PATCH 025/190] clear quoting event even on send fail, as then we can click retry Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/MessageComposerInput.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index 956091215f..fcd3d4ed03 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -869,15 +869,15 @@ export default class MessageComposerInput extends React.Component { } } - this.client.sendMessage(this.props.room.roomId, content).done((res) => { - dis.dispatch({ - action: 'message_sent', - }); - // Once replies are not only for text, we can use message_sent for this + this.client.sendMessage(this.props.room.roomId, content).finally(() => { dis.dispatch({ action: 'reply_to_event', event: null, }); + }).done((res) => { + dis.dispatch({ + action: 'message_sent', + }); }, (e) => onSendMessageFailed(e, this.props.room)); this.setState({ From 661073493b01af56e541f768656f5a52376206f7 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 16 Mar 2018 18:31:17 +0100 Subject: [PATCH 026/190] implement desired m.room.message->m.text fallbacks Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/ReplyThread.js | 56 +++++++++++++++++--- 1 file changed, 50 insertions(+), 6 deletions(-) diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index 650a3845e3..de6ff46610 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -161,12 +161,56 @@ export default class ReplyThread extends React.Component { if (html) html = this.stripHTMLReply(html); } - html = `
In reply to ` - + `${ev.getSender()}
${html || body}
`; - const lines = body.trim().split('\n'); - if (lines.length > 0) { - lines[0] = `<${ev.getSender()}> ${lines[0]}`; - body = lines.map((line) => `> ${line}`).join('\n') + '\n\n'; + const evLink = makeEventPermalink(ev.getRoomId(), ev.getId()); + const userLink = makeUserPermalink(ev.getSender()); + const mxid = ev.getSender(); + + // This fallback contains text that is explicitly EN. + switch (ev.getContent().msgtype) { + case 'm.text': + case 'm.notice': { + html = `
In reply to ${mxid}` + + `
${html || body}
`; + const lines = body.trim().split('\n'); + if (lines.length > 0) { + lines[0] = `<${mxid}> ${lines[0]}`; + body = lines.map((line) => `> ${line}`).join('\n') + '\n\n'; + } + break; + } + + case 'm.image': + html = `
In reply to ${mxid}` + + `
sent an image.
`; + body = `> <${mxid}> sent an image.\n\n${body}`; + break; + case 'm.video': + html = `
In reply to ${mxid}` + + `
sent a video.
`; + body = `> <${mxid}> sent a video.\n\n${body}`; + break; + case 'm.audio': + html = `
In reply to ${mxid}` + + `
sent an audio file.
`; + body = `> <${mxid}> sent an audio file.\n\n${body}`; + break; + case 'm.file': + html = `
In reply to ${mxid}` + + `
sent a file.
`; + body = `> <${mxid}> sent a file.\n\n${body}`; + break; + case 'm.emote': { + html = `
In reply to * ` + + `${mxid}
${html || body}
`; + const lines = body.trim().split('\n'); + if (lines.length > 0) { + lines[0] = `* <${mxid}> ${lines[0]}`; + body = lines.map((line) => `> ${line}`).join('\n') + '\n\n'; + } + break; + } + default: + return null; } return {body, html}; From a390cecf9284cd8d7ae3697aa28cb88c80632620 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 29 Mar 2018 17:34:08 +0100 Subject: [PATCH 027/190] fix missing null-guard Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/HtmlUtils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/HtmlUtils.js b/src/HtmlUtils.js index c621d8314e..8db17d6796 100644 --- a/src/HtmlUtils.js +++ b/src/HtmlUtils.js @@ -437,7 +437,7 @@ export function bodyToHtml(content, highlights, opts={}) { } let formattedBody = content.formatted_body; - if (opts.stripReplyFallback) formattedBody = ReplyThread.stripHTMLReply(content.formatted_body); + if (opts.stripReplyFallback && formattedBody) formattedBody = ReplyThread.stripHTMLReply(formattedBody); strippedBody = opts.stripReplyFallback ? ReplyThread.stripPlainReply(content.body) : content.body; bodyHasEmoji = containsEmoji(isHtml ? formattedBody : content.body); From 9c2e3e25f03803cc413c2f1593b97405f5f039f5 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 4 Apr 2018 10:34:39 +0100 Subject: [PATCH 028/190] clear reply_to_event at queue not send time Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/MessageComposerInput.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index fcd3d4ed03..5e4aae5ba2 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -869,12 +869,14 @@ export default class MessageComposerInput extends React.Component { } } - this.client.sendMessage(this.props.room.roomId, content).finally(() => { - dis.dispatch({ - action: 'reply_to_event', - event: null, - }); - }).done((res) => { + // Clear reply_to_event as we put the message into the queue + // if the send fails, retry will handle resending. + dis.dispatch({ + action: 'reply_to_event', + event: null, + }); + + this.client.sendMessage(this.props.room.roomId, content).done((res) => { dis.dispatch({ action: 'message_sent', }); From 2854f2b6c85ab95411c17295e7efeabf6a66c000 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 4 Apr 2018 10:36:48 +0100 Subject: [PATCH 029/190] allow BigEmoji calc to ignore replies fallback if enabled Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/HtmlUtils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/HtmlUtils.js b/src/HtmlUtils.js index 8db17d6796..17566957c7 100644 --- a/src/HtmlUtils.js +++ b/src/HtmlUtils.js @@ -468,7 +468,7 @@ export function bodyToHtml(content, highlights, opts={}) { let emojiBody = false; if (!opts.disableBigEmoji && bodyHasEmoji) { EMOJI_REGEX.lastIndex = 0; - const contentBodyTrimmed = content.body !== undefined ? content.body.trim() : ''; + const contentBodyTrimmed = strippedBody !== undefined ? strippedBody.trim() : ''; const match = EMOJI_REGEX.exec(contentBodyTrimmed); emojiBody = match && match[0] && match[0].length === contentBodyTrimmed.length; } From 9df2f7ddc8a4329fb8f929d97e84225b7311756f Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 4 Apr 2018 11:19:13 +0100 Subject: [PATCH 030/190] Add warning to Upload Confirm prompt if replying, as can't reply with file Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/MessageComposer.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index ff46f7423e..955c189c9d 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -111,6 +111,14 @@ export default class MessageComposer extends React.Component { ); } + const isQuoting = Boolean(RoomViewStore.getQuotingEvent()); + let replyToWarning = null; + if (isQuoting) { + replyToWarning =

{ + _t('At this time it is not possible to reply with a file so this will be sent without being a reply.') + }

; + } + Modal.createTrackedDialog('Upload Files confirmation', '', QuestionDialog, { title: _t('Upload Files'), description: ( @@ -119,6 +127,7 @@ export default class MessageComposer extends React.Component {
    { fileList }
+ { replyToWarning }
), onFinished: (shouldUpload) => { From 408132173314db5c1d6bd735420c8cad78193a1d Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 4 Apr 2018 11:19:28 +0100 Subject: [PATCH 031/190] run i18n prune and gen Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/i18n/strings/bg.json | 8 -------- src/i18n/strings/ca.json | 4 ---- src/i18n/strings/cs.json | 5 ----- src/i18n/strings/de_DE.json | 5 ----- src/i18n/strings/el.json | 3 --- src/i18n/strings/en_EN.json | 26 ++++++++++++-------------- src/i18n/strings/en_US.json | 3 --- src/i18n/strings/eo.json | 5 ----- src/i18n/strings/es.json | 3 --- src/i18n/strings/eu.json | 8 +------- src/i18n/strings/fi.json | 5 ----- src/i18n/strings/fr.json | 8 +------- src/i18n/strings/gl.json | 5 ----- src/i18n/strings/hu.json | 5 ----- src/i18n/strings/it.json | 1 - src/i18n/strings/ko.json | 3 --- src/i18n/strings/lv.json | 7 ------- src/i18n/strings/nl.json | 8 -------- src/i18n/strings/pl.json | 3 --- src/i18n/strings/pt.json | 3 --- src/i18n/strings/pt_BR.json | 7 ------- src/i18n/strings/ru.json | 8 +------- src/i18n/strings/sk.json | 5 ----- src/i18n/strings/sr.json | 8 -------- src/i18n/strings/sv.json | 3 --- src/i18n/strings/th.json | 3 --- src/i18n/strings/tr.json | 3 --- src/i18n/strings/zh_Hans.json | 4 ---- src/i18n/strings/zh_Hant.json | 8 +------- 29 files changed, 16 insertions(+), 151 deletions(-) diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json index 4968907a81..4205a8bbd0 100644 --- a/src/i18n/strings/bg.json +++ b/src/i18n/strings/bg.json @@ -207,7 +207,6 @@ "Message Replies": "Отговори на съобщението", "Message Pinning": "Функция за закачане на съобщения", "Presence Management": "Управление на присъствието", - "Tag Panel": "Панел с етикети", "Disable Emoji suggestions while typing": "Изключване на предложенията за емотиконите при писане", "Use compact timeline layout": "Използване на компактно оформление за списъка със съобщения", "Hide removed messages": "Скриване на премахнати съобщения", @@ -435,7 +434,6 @@ "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 сървъри", @@ -718,8 +716,6 @@ "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": "Невалиден имейл адрес", @@ -729,7 +725,6 @@ "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.": "Това ще Ви позволи да възстановите Вашата парола и да получавате известия.", @@ -786,7 +781,6 @@ "Failed to fetch avatar URL": "Неуспешно изтегляне от адреса на аватара", "Signed Out": "Излязохте", "For security, this session has been signed out. Please sign in again.": "Поради мерки за сигурност, тази сесия е прекратена. Моля, влезте отново.", - "Cryptography data migrated": "Бяха мигрирани криптографските данни", "Logout": "Излез", "Sign out": "Изход", "Error whilst fetching joined communities": "Грешка при извличането на общности, към които сте присъединени", @@ -848,7 +842,6 @@ "Device ID:": "Идентификатор на устройството:", "Device key:": "Ключ на устройството:", "Ignored Users": "Игнорирани потребители", - "Found a bug?": "Намерихте грешка?", "Riot collects anonymous analytics to allow us to improve the application.": "Riot събира анонимни статистики, за да ни позволи да подобрим приложението.", "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.": "Научете повече за това как използваме статистическите данни.", @@ -976,7 +969,6 @@ "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.": "Ако преди сте използвали по-нова версия на Riot, Вашата сесия може да не бъде съвместима с текущата версия. Затворете този прозорец и се върнете в по-новата версия.", "This will be your account name on the homeserver, or you can pick a different server.": "Това ще бъде името на профила Ви на Home сървъра, или можете да изберете друг сървър.", "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.": "Препоръчваме Ви да минете през процеса за потвърждение за всяко устройство, за да потвърдите, че принадлежат на легитимен собственик. Ако предпочитате, можете да изпратите съобщение без потвърждение.", - "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. За да запазите историята на съобщенията, експортирайте и импортирайте отново Вашите ключове.", "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. Това ще доведе до неправилна работа на криптографията от край до край в по-старата версия. Шифрованите от край до край съобщения, които са били обменени наскоро (при използването на по-стара версия), може да не успеят да бъдат разшифровани в тази версия. Това също може да доведе до неуспех в обмяната на съобщения в тази версия. Ако имате проблеми, излезте и влезте отново в профила си. За да запазите историята на съобщенията, експортирайте и импортирайте отново Вашите ключове.", "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.": "Възстановяването на парола ще нулира всички ключове за шифроване от край до край за всички устройства, правейки историята на шифрования чат невъзможна за четене, освен ако първо не експортирате Вашите ключове за стаята и ги импортирате отново след това. В бъдеще това ще бъде подобрено.", "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": "Вие сте излязли от профила си от всички устройства и вече няма да получавате известия. За да включите известията отново, влезте в профила си от всички устройства", diff --git a/src/i18n/strings/ca.json b/src/i18n/strings/ca.json index 465b0de506..ab0c690068 100644 --- a/src/i18n/strings/ca.json +++ b/src/i18n/strings/ca.json @@ -214,7 +214,6 @@ "Message Replies": "Respostes del missatge", "Message Pinning": "Fixació de missatges", "Presence Management": "Gestió de presència", - "Tag Panel": "Tauler d'etiquetes", "Disable Emoji suggestions while typing": "Desactiva els suggeriments d'Emoji mentre s'escriu", "Use compact timeline layout": "Utilitza el disseny compacte de la línia de temps", "Hide join/leave messages (invites/kicks/bans unaffected)": "Amaga els missatges d'entrada i sortida (no afecta a les invitacions, expulsions o prohibicions)", @@ -756,7 +755,6 @@ "Leave Community": "Abandona la comunitat", "Leave %(groupName)s?": "Voleu sortir de la comunitat %(groupName)s?", "Leave": "Surt", - "Unable to leave room": "No s'ha pogut sortir de la sala", "Community Settings": "Paràmetres de la comunitat", "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Aquestes sales es mostren a la pàgina de la comunitat als seus membres i poden entrar-hi fent clic sobre elles.", "Featured Rooms:": "Sales destacades:", @@ -872,8 +870,6 @@ "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" } diff --git a/src/i18n/strings/cs.json b/src/i18n/strings/cs.json index 4267954d4c..6b8263d62a 100644 --- a/src/i18n/strings/cs.json +++ b/src/i18n/strings/cs.json @@ -90,7 +90,6 @@ "Are you sure you want to upload the following files?": "Určitě chcete nahrát následující soubory?", "Attachment": "Příloha", "Autoplay GIFs and videos": "Automaticky přehrávat GIFy a videa", - "Bug Report": "Hlášení o chybě", "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.": "Nelze se připojit k domovskému serveru – zkontrolujte prosím své připojení, prověřte, zdali je SSL certifikát vašeho domovského serveru důvěryhodný, a že některé z rozšíření prohlížeče neblokuje komunikaci.", "Anyone who knows the room's link, apart from guests": "Kdokoliv, kdo má odkaz na místnost, kromě hostů", "Anyone who knows the room's link, including guests": "Kdokoliv, kdo má odkaz na místnost, a to i hosté", @@ -207,7 +206,6 @@ "%(senderName)s answered the call.": "%(senderName)s přijal/a hovor.", "Click to mute audio": "Kliknutím ztlumíte zvuk", "Failed to verify email address: make sure you clicked the link in the email": "E-mailovou adresu se nepodařilo ověřit. Přesvědčte se, že jste kliknul/a na zaslaný odkaz", - "Found a bug?": "Našli jste chybu?", "Guest access is disabled on this Home Server.": "Na tomto domovském serveru je hostům vstup odepřen.", "Guests cannot join this room even if explicitly invited.": "Hosté nemohou vstoupit do této místnosti, i když jsou přímo pozváni.", "Hide read receipts": "Skrýt potvrzení o přečtení", @@ -278,7 +276,6 @@ "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Tuto změnu nepůjde vrátit zpět, protože tomuto uživateli nastavujete stejnou úroveň moci, jakou máte vy.", "Alias (optional)": "Alias (nepovinný)", "Room name (optional)": "Název místnosti (nepovinný)", - "Report it": "Nahlásit to", "Results from DuckDuckGo": "Výsledky z DuckDuckGo", "Return to login screen": "Vrátit k přihlašovací obrazovce", "Riot does not have permission to send you notifications - please check your browser settings": "Riot není oprávněn posílat vám upozornění – zkontrolujte prosím nastavení svého prohlížeče", @@ -560,7 +557,6 @@ "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", "Hide join/leave messages (invites/kicks/bans unaffected)": "Skrýt zprávy o vstupu či odejití (pozvánky, vykopnutí a vykázání zůstanou)", "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", @@ -934,7 +930,6 @@ "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.", - "Tag Panel": "Připnout panel", "Call Failed": "Hovor selhal", "There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "V této místnosti jsou neznámá zařízení: Pokud budete pokračovat bez jejich ověření, někdo může Váš hovor odposlouchávat.", "Review Devices": "Ověřit zařízení", diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 7931d9723f..1392de5c95 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -51,7 +51,6 @@ "Are you sure you want to reject the invitation?": "Bist du sicher, dass du die Einladung ablehnen willst?", "Are you sure you want to upload the following files?": "Bist du sicher, dass du die folgenden Dateien hochladen möchtest?", "Banned users": "Verbannte Benutzer", - "Bug Report": "Fehlerbericht", "Changes to who can read history will only apply to future messages in this room": "Änderungen, die bestimmen, wer den Chatverlauf lesen kann, gelten nur für zukünftige Nachrichten in diesem Raum", "Clear Cache and Reload": "Cache leeren und neu laden", "Confirm your new password": "Neues Passwort bestätigen", @@ -89,7 +88,6 @@ "Forgot your password?": "Passwort vergessen?", "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.": "Aus Sicherheitsgründen werden beim Ausloggen alle Ende-zu-Ende-Verschlüsselungs-Schlüssel in diesem Browser gelöscht. Wenn du in späteren Riot-Sitzungen den bisherigen Chatverlauf entschlüsseln möchtest, exportiere bitte deine Schlüssel zur sicheren Aufbewahrung.", "For security, this session has been signed out. Please sign in again.": "Aus Sicherheitsgründen wurde diese Sitzung beendet. Bitte melde dich erneut an.", - "Found a bug?": "Fehler gefunden?", "Guests cannot join this room even if explicitly invited.": "Gäste können diesem Raum nicht beitreten, auch wenn sie explizit eingeladen wurden.", "Hangup": "Auflegen", "Homeserver is": "Home-Server:", @@ -398,7 +396,6 @@ "New passwords don't match": "Die neuen Passwörter stimmen nicht überein", "olm version:": "Version von olm:", "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 Seitenende springen", "Show timestamps in 12 hour format (e.g. 2:30pm)": "Zeitstempel im 12-Stunden-Format anzeigen (z. B. 2:30pm)", @@ -692,7 +689,6 @@ "You are no longer ignoring %(userId)s": "%(userId)s wird nicht mehr ignoriert", "Message removed by %(userId)s": "Nachricht wurde von %(userId)s entfernt", "Name or matrix ID": "Name oder Matrix-ID", - "Unable to leave room": "Verlassen des Raumes fehlgeschlagen", "Leave": "Verlassen", "Failed to invite the following users to %(groupId)s:": "Die folgenden Benutzer konnten nicht in die Gruppe %(groupId)s eingeladen werden:", "Leave %(groupName)s?": "%(groupName)s verlassen?", @@ -967,7 +963,6 @@ "Your homeserver's URL": "Die URL deines Homeservers", "Your identity server's URL": "Die URL deines Identitätsservers", "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s", - "Tag Panel": "Beschriftungsfeld", "Message Replies": "Antworten auf Nachrichten", "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.": "Du wirst nicht in der Lage sein, die Änderung zurückzusetzen, da du dich degradierst. Wenn du der letze Nutzer mit Berechtigungen bist, wird es unmöglich sein die Privilegien zurückzubekommen.", "Community IDs cannot not be empty.": "Community-IDs können nicht leer sein.", diff --git a/src/i18n/strings/el.json b/src/i18n/strings/el.json index ab16f215bc..58edb86568 100644 --- a/src/i18n/strings/el.json +++ b/src/i18n/strings/el.json @@ -36,7 +36,6 @@ "Attachment": "Επισύναψη", "%(senderName)s banned %(targetName)s.": "Ο χρήστης %(senderName)s έδιωξε τον χρήστη %(targetName)s.", "Autoplay GIFs and videos": "Αυτόματη αναπαραγωγή GIFs και βίντεο", - "Bug Report": "Αναφορά σφάλματος", "Anyone who knows the room's link, apart from guests": "Oποιοσδήποτε", "%(items)s and %(lastItem)s": "%(items)s %(lastItem)s", "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "Ένα μήνυμα στάλθηκε στο +%(msisdn)s. Παρακαλώ γράψε τον κωδικό επαλήθευσης που περιέχει", @@ -117,7 +116,6 @@ "Forgot your password?": "Ξεχάσατε τoν κωδικό πρόσβασης σας;", "For security, this session has been signed out. Please sign in again.": "Για λόγους ασφαλείας, αυτή η συνεδρία έχει τερματιστεί. Παρακαλούμε συνδεθείτε ξανά.", "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.": "Για λόγους ασφαλείας, τα κλειδιά κρυπτογράφησης θα διαγράφονται από τον περιηγητή κατά την αποσύνδεση σας. Εάν επιθυμείτε να αποκρυπτογραφήσετε τις συνομιλίες σας στο μέλλον, εξάγετε τα κλειδιά σας και κρατήστε τα ασφαλή.", - "Found a bug?": "Βρήκατε κάποιο πρόβλημα;", "Hangup": "Κλείσιμο", "Historical": "Ιστορικό", "Homeserver is": "Ο διακομιστής είναι", @@ -262,7 +260,6 @@ "Remote addresses for this room:": "Απομακρυσμένες διευθύνσεις για το δωμάτιο:", "Remove Contact Information?": "Αφαίρεση πληροφοριών επαφής;", "Remove %(threePid)s?": "Αφαίρεση %(threePid)s;", - "Report it": "Αναφορά", "Results from DuckDuckGo": "Αποτελέσματα από DuckDuckGo", "Return to login screen": "Επιστροφή στην οθόνη σύνδεσης", "Room %(roomId)s not visible": "Το δωμάτιο %(roomId)s δεν είναι ορατό", diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 25c3813a4c..c7e3e17383 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -100,6 +100,7 @@ "You need to be logged in.": "You need to be logged in.", "You need to be able to invite users to do that.": "You need to be able to invite users to do that.", "Unable to create widget.": "Unable to create widget.", + "Missing roomId.": "Missing roomId.", "Failed to send request.": "Failed to send request.", "This room is not recognised.": "This room is not recognised.", "Power level must be positive integer.": "Power level must be positive integer.", @@ -186,6 +187,8 @@ "Message Replies": "Message Replies", "Message Pinning": "Message Pinning", "Presence Management": "Presence Management", + "Tag Panel": "Tag Panel", + "Sticker Messages": "Sticker Messages", "Disable Emoji suggestions while typing": "Disable Emoji suggestions while typing", "Use compact timeline layout": "Use compact timeline layout", "Hide removed messages": "Hide removed messages", @@ -255,13 +258,6 @@ "Cannot add any more widgets": "Cannot add any more widgets", "The maximum permitted number of widgets have already been added to this room.": "The maximum permitted number of widgets have already been added to this room.", "Add a widget": "Add a widget", - "Stickerpack": "Stickerpack", - "Sticker Messages": "Sticker Messages", - "You don't currently have any stickerpacks enabled": "You don't currently have any stickerpacks enabled", - "Click": "Click", - "here": "here", - "to add some!": "to add some!", - "Add a stickerpack": "Add a stickerpack", "Drop File Here": "Drop File Here", "Drop file here to upload": "Drop file here to upload", " (unsupported)": " (unsupported)", @@ -322,6 +318,7 @@ "Filter room members": "Filter room members", "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (power %(powerLevelNumber)s)", "Attachment": "Attachment", + "At this time it is not possible to reply with a file so this will be sent without being a reply.": "At this time it is not possible to reply with a file so this will be sent without being a reply.", "Upload Files": "Upload Files", "Are you sure you want to upload the following files?": "Are you sure you want to upload the following files?", "Encrypted room": "Encrypted room", @@ -329,10 +326,6 @@ "Hangup": "Hangup", "Voice call": "Voice call", "Video call": "Video call", - "Hide Apps": "Hide Apps", - "Show Apps": "Show Apps", - "Hide Stickers": "Hide Stickers", - "Show Stickers": "Show Stickers", "Upload file": "Upload file", "Show Text Formatting Toolbar": "Show Text Formatting Toolbar", "Send an encrypted reply…": "Send an encrypted reply…", @@ -376,8 +369,8 @@ "Offline": "Offline", "Unknown": "Unknown", "Seen by %(userName)s at %(dateTime)s": "Seen by %(userName)s at %(dateTime)s", - "Replying": "Replying", "Seen by %(displayName)s (%(userName)s) at %(dateTime)s": "Seen by %(displayName)s (%(userName)s) at %(dateTime)s", + "Replying": "Replying", "No rooms to show": "No rooms to show", "Unnamed room": "Unnamed room", "World readable": "World readable", @@ -482,6 +475,11 @@ "This room's internal ID is": "This room's internal ID is", "Add a topic": "Add a topic", "Cancel": "Cancel", + "You don't currently have any stickerpacks enabled": "You don't currently have any stickerpacks enabled", + "Add a stickerpack": "Add a stickerpack", + "Stickerpack": "Stickerpack", + "Hide Stickers": "Hide Stickers", + "Show Stickers": "Show Stickers", "Scroll to unread messages": "Scroll to unread messages", "Jump to first unread message.": "Jump to first unread message.", "Close": "Close", @@ -589,12 +587,12 @@ "NOTE: Apps are not end-to-end encrypted": "NOTE: Apps are not end-to-end encrypted", "Do you want to load widget from URL:": "Do you want to load widget from URL:", "Allow": "Allow", - "Manage sticker packs": "Manage sticker packs", "Delete Widget": "Delete Widget", "Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?": "Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?", "Delete widget": "Delete widget", "Revoke widget access": "Revoke widget access", "Minimize apps": "Minimize apps", + "Picture": "Picture", "Edit": "Edit", "Create new room": "Create new room", "Unblacklist": "Unblacklist", @@ -788,9 +786,9 @@ "Featured Users:": "Featured Users:", "%(inviter)s has invited you to join this community": "%(inviter)s has invited you to join this community", "Join this community": "Join this community", + "Leave this community": "Leave this community", "You are an administrator of this community": "You are an administrator of this community", "You are a member of this community": "You are a member of this community", - "Leave this community": "Leave 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!": "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!", "Long Description (HTML)": "Long Description (HTML)", "Description": "Description", diff --git a/src/i18n/strings/en_US.json b/src/i18n/strings/en_US.json index 2ce5cb541b..d86b465f57 100644 --- a/src/i18n/strings/en_US.json +++ b/src/i18n/strings/en_US.json @@ -46,7 +46,6 @@ "Banned users": "Banned users", "Bans user with given id": "Bans user with given id", "Blacklisted": "Blacklisted", - "Bug Report": "Bug Report", "Bulk Options": "Bulk Options", "Call Timeout": "Call Timeout", "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.", @@ -159,7 +158,6 @@ "Forgot your password?": "Forgot your password?", "For security, this session has been signed out. Please sign in again.": "For security, this session has been signed out. Please sign in again.", "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.": "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.", - "Found a bug?": "Found a bug?", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s", "Guest access is disabled on this Home Server.": "Guest access is disabled on this Home Server.", "Guests cannot join this room even if explicitly invited.": "Guests cannot join this room even if explicitly invited.", @@ -282,7 +280,6 @@ "Remove": "Remove", "Remove %(threePid)s?": "Remove %(threePid)s?", "%(senderName)s requested a VoIP conference.": "%(senderName)s requested a VoIP conference.", - "Report it": "Report it", "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.": "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.", "Results from DuckDuckGo": "Results from DuckDuckGo", "Return to login screen": "Return to login screen", diff --git a/src/i18n/strings/eo.json b/src/i18n/strings/eo.json index f40b9c711f..8ef7844f06 100644 --- a/src/i18n/strings/eo.json +++ b/src/i18n/strings/eo.json @@ -166,7 +166,6 @@ "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", @@ -731,7 +730,6 @@ "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:", @@ -813,9 +811,6 @@ "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", diff --git a/src/i18n/strings/es.json b/src/i18n/strings/es.json index 274ad0d59f..6c54677b23 100644 --- a/src/i18n/strings/es.json +++ b/src/i18n/strings/es.json @@ -29,7 +29,6 @@ "Banned users": "Usuarios bloqueados", "Bans user with given id": "Bloquear usuario por ID", "Blacklisted": "En lista negra", - "Bug Report": "Reporte de fallo", "Bulk Options": "Opciones masivas", "Call Timeout": "Tiempo de espera de la llamada", "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "No se puede conectar al servidor via HTTP, cuando es necesario un enlace HTTPS en la barra de direcciones de tu navegador. Ya sea usando HTTPS o habilitando los scripts inseguros.", @@ -132,7 +131,6 @@ "Forgot your password?": "¿Olvidaste tu clave?", "For security, this session has been signed out. Please sign in again.": "Por seguridad, esta sesión ha sido cerrada. Por favor inicia sesión nuevamente.", "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.": "Por seguridad, al cerrar la sesión borrará cualquier clave de encriptación de extremo a extremo en este navegador. Si quieres ser capaz de descifrar tu historial de conversación, para las futuras sesiones en Riot, por favor exporta las claves de la sala para protegerlas.", - "Found a bug?": "¿Encontraste un error?", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s de %(fromPowerLevel)s a %(toPowerLevel)s", "Guests cannot join this room even if explicitly invited.": "Invitados no pueden unirse a esta sala aun cuando han sido invitados explícitamente.", "Hangup": "Colgar", @@ -376,7 +374,6 @@ "Remove": "Eliminar", "Remove %(threePid)s?": "¿Eliminar %(threePid)s?", "%(senderName)s requested a VoIP conference.": "%(senderName)s ha solicitado una conferencia Voz-IP.", - "Report it": "Informar", "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.": "Reiniciar la contraseña también reiniciará las claves de cifrado extremo-a-extremo, haciendo ilegible el historial de las conversaciones, salvo que exporte previamente las claves de sala, y las importe posteriormente. Esto será mejorado en futuras versiones.", "Results from DuckDuckGo": "Resultados desde DuckDuckGo", "Return to login screen": "Volver a la pantalla de inicio de sesión", diff --git a/src/i18n/strings/eu.json b/src/i18n/strings/eu.json index 5d90b7f219..7c66935cc2 100644 --- a/src/i18n/strings/eu.json +++ b/src/i18n/strings/eu.json @@ -36,7 +36,6 @@ "Invites": "Gonbidapenak", "Low priority": "Lehentasun baxua", "No results": "Emaitzarik ez", - "Bug Report": "Arazte-txostena", "Join Room": "Elkartu gelara", "Register": "Eman izena", "Submit": "Bidali", @@ -135,7 +134,6 @@ "Start Chat": "Hasi txata", "Success": "Arrakasta", "For security, this session has been signed out. Please sign in again.": "Segurtasunagatik saio hau amaitu da. Hasi saioa berriro.", - "Found a bug?": "Akats bat aurkitu duzu?", "Guests cannot join this room even if explicitly invited.": "Bisitariak ezin dira gela honetara elkartu ez bazaie zuzenean gonbidatu.", "Hangup": "Eseki", "Homeserver is": "Hasiera zerbitzaria:", @@ -357,7 +355,6 @@ "%(senderName)s removed their profile picture.": "%(senderName)s erabiltzaileak bere profileko argazkia kendu du.", "Remove %(threePid)s?": "Kendu %(threePid)s?", "%(senderName)s requested a VoIP conference.": "%(senderName)s erabiltzaileak VoIP konferentzia bat eskatu du.", - "Report it": "Eman berri", "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.": "Oraingoz pasahitza aldatzeak gailu guztietako muturretik muturrerako zifratze-gakoak berrezarriko ditu, eta ezin izango dituzu zifratutako txatetako historialak irakurri ez badituzu aurretik zure gelako gakoak esportatzen eta aldaketa eta gero berriro inportatzen.", "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "Une honetan egiaztatu gabeko gailuak blokeatzen ari zara, gailu hauetara mezuak bidali ahal izateko egiaztatu behar dituzu.", "Results from DuckDuckGo": "DuckDuckGo bilatzaileko emaitzak", @@ -737,7 +734,6 @@ "Send": "Bidali", "Message Pinning": "Mezuak finkatzea", "Presence Management": "Presentzia-kudeaketa", - "Tag Panel": "Etiketen panela", "Hide avatar changes": "Ezkutatu abatar aldaketak", "Hide display name changes": "Ezkutatu pantaila izenen aldaketak", "Disable big emoji in chat": "Desgaitu emoji handiak txatean", @@ -812,7 +808,6 @@ "Leave Community": "Atera komunitatetik", "Leave %(groupName)s?": "Atera %(groupName)s komunitatetik?", "Leave": "Atera", - "Unable to leave room": "Ezin izan da gelatik atera", "Community Settings": "Komunitatearen ezarpenak", "You are an administrator of this community": "Komunitate honen administratzailea zara", "You are a member of this community": "Komunitate honetako kidea zara", @@ -991,6 +986,5 @@ "If your other devices do not have the key for this message you will not be able to decrypt them.": "Zure beste gailuek mezu honetarako gakoa ez badute ezin izango dute deszifratu.", "Key request sent.": "Gako eskaria bidalita.", "Re-request encryption keys from your other devices.": "Berriz eskatu zifratze-gakoak zure beste gailuetatik.", - "%(user)s is a %(userRole)s": "%(user)s %(userRole)s da", - "Changes made to your community might not be seen by other users for up to 30 minutes.": "Zure komunitateari egindako aldaketak agian ez dira beste erabiltzaileentzat ikusgai egongo 30 minutu pasatu arte." + "%(user)s is a %(userRole)s": "%(user)s %(userRole)s da" } diff --git a/src/i18n/strings/fi.json b/src/i18n/strings/fi.json index ae12f57e28..7a065eedf2 100644 --- a/src/i18n/strings/fi.json +++ b/src/i18n/strings/fi.json @@ -71,7 +71,6 @@ "Ban": "Anna porttikielto", "Banned users": "Porttikiellon saanneet käyttäjät", "Bans user with given id": "Antaa porttikiellon käyttäjälle jolla on annettu tunniste", - "Bug Report": "Virheraportti", "Bulk Options": "Bulkkiasetukset", "Changes your display nickname": "Muuttaa näyttönimesi", "Changes colour scheme of current room": "Muuttaa tamänhetkisen huoneen väritystä", @@ -166,7 +165,6 @@ "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.", "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.": "Turvallusuussyistä uloskirjautuminen poistaa kaikki päästä päähän-salausavaimet tästä selaimesta. Jos haluat purkaa keskustelujen salaukset tulevaisuudessa pitää sinun viedä purkuavaimet ja pitää ne turvallisesti tallessa.", - "Found a bug?": "Löysitkö virheen?", "Hide Apps": "Piilota sovellukset", "Hide read receipts": "Piilota lukukuittaukset", "Hide Text Formatting Toolbar": "Piilota tekstinmuotoilutyökalupalkki", @@ -475,7 +473,6 @@ "%(targetName)s rejected the invitation.": "%(targetName)s hylkäsi kutsun.", "Remote addresses for this room:": "Tämän huoneen etäosoitteet:", "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s poisti näyttönimensä (%(oldDisplayName)s).", - "Report it": "Ilmoita siitä", "Riot does not have permission to send you notifications - please check your browser settings": "Riotilla ei ole oikeuksia lähettää sinulle ilmoituksia. Ole hyvä ja tarkista selaimen asetukset", "Riot was not given permission to send notifications - please try again": "Riotilla ei saannut oikeuksia lähettää ilmoituksia. Ole hyvä ja yritä uudelleen", "Room %(roomId)s not visible": "Huone %(roomId)s ei ole näkyvissä", @@ -785,7 +782,6 @@ "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 yhteisöön", "Featured Rooms:": "Esiinnostetut huoneet:", @@ -838,7 +834,6 @@ "%(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", diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index a07a6fbbc9..73805d66f0 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -57,7 +57,6 @@ "Banned users": "Utilisateurs bannis", "Bans user with given id": "Bannit l'utilisateur à partir de son identifiant", "Blacklisted": "Sur liste noire", - "Bug Report": "Rapport d'erreur", "Call Timeout": "Délai d’appel expiré", "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Impossible de se connecter au serveur d'accueil en HTTP si l'URL dans la barre de votre explorateur est en HTTPS. Utilisez HTTPS ou activez le support des scripts non-vérifiés.", "Can't load user settings": "Impossible de charger les paramètres de l'utilisateur", @@ -133,7 +132,6 @@ "Forget room": "Oublier le salon", "Forgot your password?": "Mot de passe oublié ?", "For security, this session has been signed out. Please sign in again.": "Par mesure de sécurité, la session a expiré. Merci de vous authentifier à nouveau.", - "Found a bug?": "Vous avez trouvé un problème ?", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s de %(fromPowerLevel)s à %(toPowerLevel)s", "Hangup": "Raccrocher", "Hide read receipts": "Cacher les accusés de lecture", @@ -241,7 +239,6 @@ "%(senderName)s removed their profile picture.": "%(senderName)s a supprimé son image de profil.", "Remove %(threePid)s?": "Supprimer %(threePid)s ?", "%(senderName)s requested a VoIP conference.": "%(senderName)s a demandé une téléconférence audio.", - "Report it": "Le signaler", "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.": "Pour le moment, réinitialiser le mot de passe va réinitialiser les clés de chiffrement sur tous les appareils, rendant l’historique des salons chiffrés illisible, à moins que vous exportiez d'abord les clés de salon puis que vous les ré-importiez après. Cela sera amélioré prochainement.", "Return to login screen": "Retourner à l’écran de connexion", "Riot does not have permission to send you notifications - please check your browser settings": "Riot n’a pas la permission de vous envoyer des notifications - merci de vérifier les paramètres de votre navigateur", @@ -862,7 +859,6 @@ "Leave Community": "Quitter la communauté", "Leave %(groupName)s?": "Quitter %(groupName)s ?", "Leave": "Quitter", - "Unable to leave room": "Impossible de partir du salon", "Community Settings": "Paramètres de la communauté", "Add rooms to this community": "Ajouter des salons à cette communauté", "%(inviter)s has invited you to join this community": "%(inviter)s vous a invité à rejoindre cette communauté", @@ -934,7 +930,6 @@ "Flair will appear if enabled in room settings": "Les badges n'apparaîtront que s'ils sont activés dans les paramètres de chaque salon", "Flair will not appear": "Les badges n'apparaîtront pas", "Display your community flair in rooms configured to show it.": "Sélectionnez les badges dans les paramètres de chaque salon pour les afficher.", - "Tag Panel": "Panneau des étiquettes", "Addresses": "Adresses", "expand": "développer", "collapse": "réduire", @@ -991,6 +986,5 @@ "If your other devices do not have the key for this message you will not be able to decrypt them.": "Si vos autres appareils n'ont pas la clé pour ce message, vous ne pourrez pas le déchiffrer.", "Key request sent.": "Demande de clé envoyée.", "Re-request encryption keys from your other devices.": "Re-demander les clés de chiffrement depuis vos autres appareils.", - "%(user)s is a %(userRole)s": "%(user)s est %(userRole)s", - "Changes made to your community might not be seen by other users for up to 30 minutes.": "Les changements effectués sur votre communauté peuvent ne pas apparaître pour les autres utilisateurs avant 30 minutes." + "%(user)s is a %(userRole)s": "%(user)s est %(userRole)s" } diff --git a/src/i18n/strings/gl.json b/src/i18n/strings/gl.json index 7c6e221f5a..c2486cefe7 100644 --- a/src/i18n/strings/gl.json +++ b/src/i18n/strings/gl.json @@ -170,7 +170,6 @@ "Failed to join room": "Non se puido unir a sala", "Message Pinning": "Fixando mensaxe", "Presence Management": "Xestión da presenza", - "Tag Panel": "Panel de etiquetas", "Disable Emoji suggestions while typing": "Deshabilitar a suxestión de Emoji mentras escribe", "Use compact timeline layout": "Utilizar a disposición compacta da liña temporal", "Hide removed messages": "Ocultar mensaxes eliminadas", @@ -736,7 +735,6 @@ "Leave Community": "Deixar a comunidade", "Leave %(groupName)s?": "Deixar %(groupName)s?", "Leave": "Saír", - "Unable to leave room": "Non puido deixar a sala", "Community Settings": "Axustes da comunidade", "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Estas salas son mostradas aos membros da comunidade na páxina da comunidade. Os membros da comunidade poden unirse as salas pulsando en elas.", "Add rooms to this community": "Engadir salas a esta comunidade", @@ -826,9 +824,6 @@ "Device ID:": "ID de dispositivo:", "Device key:": "Chave do dispositivo:", "Ignored Users": "Usuarias ignoradas", - "Bug Report": "Informe de fallo", - "Found a bug?": "Atopou un fallo?", - "Report it": "Informe", "Analytics": "Analytics", "Riot collects anonymous analytics to allow us to improve the application.": "Riot recolle información analítica anónima para permitirnos mellorar o aplicativo.", "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "A intimidade impórtanos, así que non recollemos información personal ou identificable nos datos dos nosos análises.", diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 3fdb117d4f..8889f52097 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -69,7 +69,6 @@ "Banned users": "Kitiltott felhasználók", "Bans user with given id": "Kitiltja a felhasználót a megadott ID-vel", "Blacklisted": "Fekete listára téve", - "Bug Report": "Hiba jelentés", "Bulk Options": "Tömeges beállítások", "Call Timeout": "Hívás időtúllépés", "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.": "Nem lehet kapcsolódni a saját szerverhez - ellenőrizd a kapcsolatot, biztosítsd, hogy a saját szerver tanúsítványa hiteles legyen, és a böngésző kiterjesztések ne blokkolják a kéréseket.", @@ -192,7 +191,6 @@ "Forgot your password?": "Elfelejtetted a jelszavad?", "For security, this session has been signed out. Please sign in again.": "A biztonság érdekében ez a kapcsolat le lesz bontva. Légy szíves jelentkezz be újra.", "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.": "A biztonság érdekében a kilépéskor a ponttól pontig való (E2E) titkosításhoz szükséges kulcsok törlésre kerülnek a böngészőből. Ha a régi üzeneteket továbbra is el szeretnéd olvasni, kérlek mentsed ki a szobákhoz tartozó kulcsot.", - "Found a bug?": "Hibát találtál?", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s : %(fromPowerLevel)s -> %(toPowerLevel)s", "Guest access is disabled on this Home Server.": "Vendég belépés tiltva van a Saját szerveren.", "Guests cannot join this room even if explicitly invited.": "Vendégek akkor sem csatlakozhatnak ehhez a szobához ha külön meghívók kaptak.", @@ -309,7 +307,6 @@ "%(senderName)s removed their profile picture.": "%(senderName)s törölte a profil képét.", "Remove %(threePid)s?": "Töröl: %(threePid)s?", "%(senderName)s requested a VoIP conference.": "%(senderName)s VoIP konferenciát kezdeményez.", - "Report it": "Jelent", "Results from DuckDuckGo": "Eredmények a DuckDuckGo-ból", "Return to login screen": "Vissza a bejelentkezési képernyőre", "Riot does not have permission to send you notifications - please check your browser settings": "Riotnak nincs jogosultsága értesítést küldeni neked - ellenőrizd a böngésző beállításait", @@ -719,7 +716,6 @@ "Description": "Leírás", "Name or matrix ID": "Név vagy Matrix azonosító", "Unable to accept invite": "A meghívót nem lehet elfogadni", - "Unable to leave room": "A szobát nem lehet elhagyni", "Leave": "Elhagy", "Failed to invite the following users to %(groupId)s:": "Az alábbi felhasználókat nem sikerült meghívni a(z) %(groupId)s:", "Failed to invite users to %(groupId)s": "Nem sikerült meghívni a felhasználókat ebbe a csoportba: %(groupId)s", @@ -934,7 +930,6 @@ "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", "Addresses": "Címek", "collapse": "becsuk", "expand": "kinyit", diff --git a/src/i18n/strings/it.json b/src/i18n/strings/it.json index b518dd866b..3db600cc26 100644 --- a/src/i18n/strings/it.json +++ b/src/i18n/strings/it.json @@ -233,7 +233,6 @@ "Authentication check failed: incorrect password?": "Controllo di autenticazione fallito: password sbagliata?", "Failed to join room": "Accesso alla stanza fallito", "Presence Management": "Gestione della presenza", - "Tag Panel": "Pannello etichette", "Disable Emoji suggestions while typing": "Disattiva i suggerimenti delle emoji durante la digitazione", "Use compact timeline layout": "Usa impaginazione cronologia compatta", "Hide join/leave messages (invites/kicks/bans unaffected)": "Nascondi i messaggi di entrata/uscita (inviti/kick/ban esclusi)", diff --git a/src/i18n/strings/ko.json b/src/i18n/strings/ko.json index 183a519320..6c259010d1 100644 --- a/src/i18n/strings/ko.json +++ b/src/i18n/strings/ko.json @@ -47,7 +47,6 @@ "Ban": "차단", "Banned users": "차단한 사용자", "Blacklisted": "요주의", - "Bug Report": "오류 보고", "Can't load user settings": "사용사 설정을 불러올 수 없어요", "Change Password": "비밀번호 바꾸기", "Changes your display nickname": "보여줄 별명을 바꾸기", @@ -193,7 +192,6 @@ "Forgot your password?": "비밀번호를 잊어버리셨어요?", "For security, this session has been signed out. Please sign in again.": "보안을 위해서, 이 세션에서 로그아웃했어요. 다시 로그인해주세요.", "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.": "보안을 위해서, 로그아웃하면 이 브라우저에서 모든 종단간 암호화 키를 없앨 거에요. 이후 라이엇에서 이야기를 해독하고 싶으시면, 방 키를 내보내서 안전하게 보관하세요.", - "Found a bug?": "오류를 찾으셨나요?", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s를 %(fromPowerLevel)s에서 %(toPowerLevel)s로", "Guest access is disabled on this Home Server.": "손님은 이 홈 서버에 접근하실 수 없어요.", "Guests cannot join this room even if explicitly invited.": "손님은 분명하게 초대받았어도 이 방에 들어가실 수 없어요.", @@ -314,7 +312,6 @@ "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s님이 별명 (%(oldDisplayName)s)을 지우셨어요.", "Remove %(threePid)s?": "%(threePid)s 지우시겠어요?", "%(senderName)s requested a VoIP conference.": "%(senderName)s님이 인터넷전화 회의를 요청하셨어요.", - "Report it": "보고하기", "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.": "비밀번호를 다시 설정하면 현재 모든 장치의 종단간 암호화 키가 다시 설정되고, 먼저 방의 키를 내보내고 나중에 다시 불러오지 않는 한, 암호화한 이야기 기록을 읽을 수 없게 되어요. 앞으로는 이 기능을 더 좋게 만들 거에요.", "Results from DuckDuckGo": "덕덕고에서 검색한 결과", "Return to login screen": "로그인 화면으로 돌아가기", diff --git a/src/i18n/strings/lv.json b/src/i18n/strings/lv.json index 752f5e84b6..6280c027db 100644 --- a/src/i18n/strings/lv.json +++ b/src/i18n/strings/lv.json @@ -46,7 +46,6 @@ "Banned users": "Lietotāji, kuriem ir liegta pieeja (banotie)", "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": "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.": "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.", @@ -178,7 +177,6 @@ "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?", "%(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ā 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.", @@ -304,7 +302,6 @@ "Remove": "Dzēst", "Remove %(threePid)s?": "Dzēst %(threePid)s?", "%(senderName)s requested a VoIP conference.": "%(senderName)s vēlas VoIP konferenci.", - "Report it": "Ziņot par to", "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", @@ -737,7 +734,6 @@ "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", @@ -918,7 +914,6 @@ "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!", @@ -926,8 +921,6 @@ "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.", diff --git a/src/i18n/strings/nl.json b/src/i18n/strings/nl.json index d4bda9c6da..d8c1cde0ca 100644 --- a/src/i18n/strings/nl.json +++ b/src/i18n/strings/nl.json @@ -29,7 +29,6 @@ "Banned users": "Verbannen gebruikers", "Bans user with given id": "Verbant de gebruiker met het gegeven ID", "Blacklisted": "Buitengesloten", - "Bug Report": "Bug report", "Bulk Options": "Bulk opties", "Call Timeout": "Gesprek time-out", "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Kan niet met de thuisserver verbinden via HTTP wanneer er een HTTPS-URL in je browser balk staat. Gebruik HTTPS of activeer onveilige scripts.", @@ -262,7 +261,6 @@ "Forgot your password?": "Wachtwoord vergeten?", "For security, this session has been signed out. Please sign in again.": "Voor veiligheidsredenen is deze sessie uitgelogd. Log alsjeblieft opnieuw in.", "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.": "In verband met veiligheidsredenen zullen alle end-to-endbeveiligingsleutels van deze browser verwijderd worden. Als je je gespreksgeschiedenis van toekomstige Riot sessies wilt kunnen ontsleutelen, exporteer en bewaar dan de ruimte sleutels.", - "Found a bug?": "Een fout gevonden?", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s van %(fromPowerLevel)s naar %(toPowerLevel)s", "Guest access is disabled on this Home Server.": "Gasttoegang is uitgeschakeld op deze thuisserver.", "Guests cannot join this room even if explicitly invited.": "Gasten kunnen niet tot deze ruimte toetreden, zelfs als ze expliciet uitgenodigd zijn.", @@ -340,7 +338,6 @@ "Press to start a chat with someone": "Druk op om een gesprek met iemand te starten", "Remove %(threePid)s?": "%(threePid)s verwijderen?", "%(senderName)s requested a VoIP conference.": "%(senderName)s heeft een VoIP-gesprek aangevraagd.", - "Report it": "Melden", "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.": "Het wachtwoord veranderen betekent momenteel dat alle end-to-endbeveiligingssleutels op alle apparaten veranderen waardoor versleutelde gespreksgeschiedenis onleesbaar wordt, behalve als je eerst de ruimte sleutels exporteert en daarna opnieuw importeert. Dit zal in de toekomst verbeterd worden.", "Results from DuckDuckGo": "Resultaten van DuckDuckGo", "Return to login screen": "Naar het inlogscherm terugkeren", @@ -723,7 +720,6 @@ "Message Pinning": "Boodschap vastpinnen", "Message Replies": "Antwoorden op bericht", "Presence Management": "Presentie Beheer", - "Tag Panel": "Label Paneel", "Disable Emoji suggestions while typing": "Emoji suggesties tijdens het typen uitzetten", "Hide avatar changes": "Avatar veranderingen verbergen", "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(day)s %(monthName)s %(fullYear)s", @@ -888,7 +884,6 @@ "collapse": "inklappen", "expand": "openklappen", "Custom of %(powerLevel)s": "Aangepast rank van %(powerLevel)s", - "Quote": "Citeren", "And %(count)s more...|other": "En %(count)s meer...", "Matrix ID": "Matrix ID", "Matrix Room ID": "Matrix Ruimte ID", @@ -925,7 +920,6 @@ "Leave Community": "Gemeenschap Verlaten", "Leave %(groupName)s?": "%(groupName)s verlaten?", "Leave": "Verlaten", - "Unable to leave room": "De ruimte kon niet verlaten worden", "Community Settings": "Gemeenschapsinstellingen", "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Deze ruimtes worden aan gemeenschapsleden getoond op de gemeenschapspagina. Gemeenschapsleden kunnen tot de ruimtes toetreden door er op te klikken.", "%(inviter)s has invited you to join this community": "%(inviter)s heeft jou uitgenodigd om tot deze gemeenschap toe te treden", @@ -937,8 +931,6 @@ "Community %(groupId)s not found": "Gemeenschap %(groupId)s is niet gevonden", "This Home server does not support communities": "Deze Thuisserver ondersteunt geen gemeenschappen", "Failed to load %(groupId)s": "Het is niet gelukt om %(groupId)s te laden", - "Cryptography data migrated": "Cryptografie gegevens zijn gemigreerd", - "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.": "Een eenmalige migratie van cryptografie gegevens heeft plaatsgevonden. Eind-tot-eind versleuteling zal niet werken als je terug gaat naar een oudere versie van Riot. Log eerst uit op Riot als je eind-tot-eind versleuteling wil gebruiken op een oudere versie. Exporteer je sleutels en importeer ze achteraf weer als je de berichtgeschiedenis wilt behouden.", "Old cryptography data detected": "Oude cryptografie gegevens gedetecteerd", "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.": "Er zijn gegevens van een oudere versie van Riot gedetecteerd. Dit zal eind-tot-eind versleuteling laten storen in de oudere versie. Eind-tot-eind berichten dat recent zijn uitgewisseld zal misschien niet ontsleutelbaar zijn in deze versie. Dit zou er misschien ook voor kunnen zorgen dat berichten die zijn uitgewisseld in deze versie falen. Indien je problemen ervaart, log opnieuw in. Om de berichtgeschiedenis te behouden, exporteer de sleutels en importeer ze achteraf weer.", "Your Communities": "Jouw Gemeenschappen", diff --git a/src/i18n/strings/pl.json b/src/i18n/strings/pl.json index ae410232e3..2db7892964 100644 --- a/src/i18n/strings/pl.json +++ b/src/i18n/strings/pl.json @@ -138,7 +138,6 @@ "Missing Media Permissions, click here to request.": "Brakuje uprawnień mediów. Kliknij tutaj, aby ich zażądać.", "and %(count)s others...|other": "i %(count)s innych...", "and %(count)s others...|one": "i jeden inny...", - "Bug Report": "Raport błędu", "Bulk Options": "Masowe opcje", "Call Timeout": "Upłynął limit czasu połączenia", "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.": "Nie można nawiązać połączenia z serwerem - proszę sprawdź twoje połączenie, upewnij się, że certyfikat SSL serwera jest zaufany, i że dodatki przeglądarki nie blokują żądania.", @@ -257,7 +256,6 @@ "Forgot your password?": "Zapomniałeś hasła?", "For security, this session has been signed out. Please sign in again.": "Ze względów bezpieczeństwa ta sesja została wylogowana. Zaloguj się jeszcze raz.", "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.": "Ze względów bezpieczeństwa, wylogowanie skasuje z tej przeglądarki wszystkie klucze szyfrowania końcówka-do-końcówki. Jeśli chcesz móc odszyfrować swoje historie konwersacji z przyszłych sesji Riot-a, proszę wyeksportuj swoje klucze pokojów do bezpiecznego miejsca.", - "Found a bug?": "Znalazłeś błąd?", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s z %(fromPowerLevel)s na %(toPowerLevel)s", "Guest access is disabled on this Home Server.": "Dostęp dla gości jest wyłączony na tym serwerze.", "Deops user with given id": "Usuwa prawa administratora użytkownikowi o danym ID", @@ -381,7 +379,6 @@ "Remove %(threePid)s?": "Usunąć %(threePid)s?", "Hide Apps": "Ukryj aplikacje", "%(senderName)s requested a VoIP conference.": "%(senderName)s zażądał grupowego połączenia głosowego VoIP.", - "Report it": "Zgłoś", "Results from DuckDuckGo": "Wyniki z DuckDuckGo", "Return to login screen": "Wróć do ekranu logowania", "Riot does not have permission to send you notifications - please check your browser settings": "Riot nie ma uprawnień, by wysyłać ci powiadomienia - sprawdź ustawienia swojej przeglądarki", diff --git a/src/i18n/strings/pt.json b/src/i18n/strings/pt.json index 2a99cd191c..bb907af6e3 100644 --- a/src/i18n/strings/pt.json +++ b/src/i18n/strings/pt.json @@ -14,7 +14,6 @@ "Banned users": "Usuárias/os banidas/os", "Bans user with given id": "Banir usuários com o identificador informado", "Blacklisted": "Bloqueado", - "Bug Report": "Repotar problemas de funcionamento", "Bulk Options": "Opcões de Batelada", "Can't load user settings": "Não é possível carregar configurações de usuário", "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s mudou o tópico para \"%(topic)s\".", @@ -68,7 +67,6 @@ "Forgot your password?": "Esqueceu sua senha?", "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.": "Por segurança, deslogar irá remover qualquer chave de criptografia ponta-a-ponta deste navegador. Caso deseje descriptografar o histórico das suas conversas E2E em sessões Riot futuras, por favor exporte as chaves da sala para sua garantia.", "For security, this session has been signed out. Please sign in again.": "Por questões de segurança, esta sessão foi encerrada. Por gentileza conecte-se novamente.", - "Found a bug?": "Encontrou um problema de funcionamento do sistema?", "Guests cannot join this room even if explicitly invited.": "Visitantes não podem entrar nesta sala, mesmo se forem explicitamente convidadas/os.", "Hangup": "Desligar", "Historical": "Histórico", @@ -405,7 +403,6 @@ "olm version:": "versão do olm:", "Operation failed": "A operação falhou", "Remove %(threePid)s?": "Remover %(threePid)s?", - "Report it": "Reportar", "riot-web version:": "versão do riot-web:", "Show timestamps in 12 hour format (e.g. 2:30pm)": "Mostrar os horários em formato de 12h (p.ex: 2:30pm)", "Unmute": "Tirar do mudo", diff --git a/src/i18n/strings/pt_BR.json b/src/i18n/strings/pt_BR.json index 3b37b1ab80..6ce317713b 100644 --- a/src/i18n/strings/pt_BR.json +++ b/src/i18n/strings/pt_BR.json @@ -14,7 +14,6 @@ "Banned users": "Usuárias/os banidas/os", "Bans user with given id": "Banir usuários com o identificador informado", "Blacklisted": "Bloqueado", - "Bug Report": "Repotar problemas de funcionamento", "Bulk Options": "Opcões de Batelada", "Can't load user settings": "Não é possível carregar configurações de usuário", "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s mudou o tópico para \"%(topic)s\".", @@ -68,7 +67,6 @@ "Forgot your password?": "Esqueceu sua senha?", "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.": "Por segurança, deslogar irá remover qualquer chave de criptografia ponta-a-ponta deste navegador. Caso deseje descriptografar o histórico das suas conversas E2E em sessões Riot futuras, por favor exporte as chaves da sala para sua garantia.", "For security, this session has been signed out. Please sign in again.": "Por questões de segurança, esta sessão foi encerrada. Por gentileza conecte-se novamente.", - "Found a bug?": "Encontrou um problema de funcionamento do sistema?", "Guests cannot join this room even if explicitly invited.": "Visitantes não podem entrar nesta sala, mesmo se forem explicitamente convidadas/os.", "Hangup": "Desligar", "Historical": "Histórico", @@ -407,7 +405,6 @@ "olm version:": "versão do olm:", "Operation failed": "A operação falhou", "Remove %(threePid)s?": "Remover %(threePid)s?", - "Report it": "Reportar", "riot-web version:": "versão do riot-web:", "Show timestamps in 12 hour format (e.g. 2:30pm)": "Mostrar os horários em formato de 12h (p.ex: 2:30pm)", "Unmute": "Tirar do mudo", @@ -699,7 +696,6 @@ "Message Replies": "Respostas", "Message Pinning": "Fixar mensagem", "Presence Management": "Gestão da presença", - "Tag Panel": "Painel de tags", "Disable Emoji suggestions while typing": "Desativar sugestões de emojis enquanto estiver escrevendo", "Hide join/leave messages (invites/kicks/bans unaffected)": "Ocultar mensagens de entrada e de saída (não afeta convites, expulsões e banimentos)", "Hide avatar changes": "Ocultar alterações da imagem de perfil", @@ -928,7 +924,6 @@ "Leave Community": "Deixar a comunidade", "Leave %(groupName)s?": "Quer sair da comunidade %(groupName)s?", "Leave": "Sair", - "Unable to leave room": "Não foi possível sair da sala", "Community Settings": "Configurações da comunidade", "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Estas salas são exibidas para as/os integrantes da comunidade na página da comunidade. Integrantes da comunidade podem entrar nas salas ao clicar nas mesmas.", "Featured Rooms:": "Salas em destaque:", @@ -943,8 +938,6 @@ "This Home server does not support communities": "Este servidor de base não permite comunidades", "Failed to load %(groupId)s": "Não foi possível carregar a comunidade %(groupId)s", "This room is not public. You will not be able to rejoin without an invite.": "Esta sala não é pública. Você não poderá voltar sem ser convidada/o.", - "Cryptography data migrated": "Dados de criptografia migrados", - "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.": "Uma migração única de dados criptografados foi realizada. A criptografia ponta-a-ponta não vai funcionar se você voltar para uma versão anterior do Riot. Se você necessitar usar criptografia ponta-a-ponta em uma versão anterior, primeiro faça logout do Riot. Para manter o histórico de mensagens, exporte e reimporte suas chaves.", "Old cryptography data detected": "Dados de criptografia antigos foram detectados", "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.": "Dados de uma versão anterior do Riot foram detectados. Isso fará com que a criptografia ponta-a-ponta não funcione na versão anterior. Mensagens criptografadas ponta-a-ponta que foram trocadas recentemente usando a versão antiga do Riot talvez não possam ser decriptografadas nesta versão. Isso também pode fazer com que mensagens trocadas com esta versão falhem. Se você tiver problemas desta natureza, faça logout e entre novamente. Para manter o histórico de mensagens, exporte e reimporte suas chaves de criptografia.", "Your Communities": "Suas comunidades", diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index a8ffc6d086..2058ec3e0f 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -13,7 +13,6 @@ "Banned users": "Заблокированные пользователи", "Bans user with given id": "Блокирует пользователя с заданным ID", "Blacklisted": "В черном списке", - "Bug Report": "Отчет об ошибке", "Bulk Options": "Групповые параметры", "Can't load user settings": "Невозможно загрузить пользовательские настройки", "Changes to who can read history will only apply to future messages in this room": "Изменения того, кто может прочитать историю, будут применяться только к будущим сообщениям в этой комнате", @@ -61,7 +60,6 @@ "Forget room": "Забыть комнату", "Forgot your password?": "Забыли пароль?", "For security, this session has been signed out. Please sign in again.": "Для обеспечения безопасности ваша сессия была завершена. Пожалуйста, войдите снова.", - "Found a bug?": "Нашли ошибку?", "Hangup": "Закончить", "Historical": "Архив", "Homeserver is": "Домашний сервер это", @@ -314,7 +312,6 @@ "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s удалил свое отображаемое имя (%(oldDisplayName)s).", "%(senderName)s removed their profile picture.": "%(senderName)s удалил свое изображение профиля.", "%(senderName)s requested a VoIP conference.": "%(senderName)s хочет начать VoIP-конференцию.", - "Report it": "Сообщить об этом", "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.": "Сброс пароля на данный момент сбрасывает ключи шифрования на всех устройствах, делая зашифрованную историю чатов нечитаемой. Чтобы избежать этого, экспортируйте ключи комнат и импортируйте их после сброса пароля. В будущем это будет исправлено.", "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 не получил разрешение на отправку уведомлений, пожалуйста, попробуйте снова", @@ -719,7 +716,6 @@ "Description": "Описание", "Name or matrix ID": "Имя или matrix ID", "Unable to accept invite": "Невозможно принять приглашение", - "Unable to leave room": "Невозможно покинуть комнату", "Leave": "Покинуть", "Failed to invite the following users to %(groupId)s:": "Не удалось пригласить следующих пользователей в %(groupId)s:", "Failed to remove '%(roomName)s' from %(groupId)s": "Не удалось удалить '%(roomName)s' из %(groupId)s", @@ -924,7 +920,6 @@ "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.": "Что-то пошло не так, во время отображения ваших сообществ.", - "Tag Panel": "Панель тегов", "Delete %(count)s devices|other": "Удалить %(count)s устройств", "Delete %(count)s devices|one": "Удалить устройство", "Select devices": "Выбрать устройства", @@ -991,6 +986,5 @@ "Re-request encryption keys from your other devices.": "Повторно запросить ключи шифрования с других устройств.", "%(user)s is a %(userRole)s": "%(user)s является %(userRole)s", "Your key share request has been sent - please check your other devices for key share requests.": "Ваш запрос на передачу ключей отправлен - пожалуйста, проверьте другие ваши устройства на запросы передачи ключей.", - "Key share requests are sent to your other devices automatically. If you rejected or dismissed the key share request on your other devices, click here to request the keys for this session again.": "Запросы передачи ключей автоматически отправляются на другие устройства. Если вы отклонили или отменили запрос на передачу ключей на других устройствах, нажмите здесь, чтобы запросить ключи для этого сеанса повторно.", - "Changes made to your community might not be seen by other users for up to 30 minutes.": "Изменения, сделанные в вашем сообществе, могут не отображаться для других пользователей в течение 30 минут." + "Key share requests are sent to your other devices automatically. If you rejected or dismissed the key share request on your other devices, click here to request the keys for this session again.": "Запросы передачи ключей автоматически отправляются на другие устройства. Если вы отклонили или отменили запрос на передачу ключей на других устройствах, нажмите здесь, чтобы запросить ключи для этого сеанса повторно." } diff --git a/src/i18n/strings/sk.json b/src/i18n/strings/sk.json index ab7812321b..96e0ee925a 100644 --- a/src/i18n/strings/sk.json +++ b/src/i18n/strings/sk.json @@ -673,7 +673,6 @@ "Leave Community": "Opustiť komunitu", "Leave %(groupName)s?": "Opustiť komunitu %(groupName)s?", "Leave": "Opustiť", - "Unable to leave room": "Nie je možné opustiť miestnosť", "Community Settings": "Nastavenia komunity", "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Tieto miestnosti sú zobrazené všetkým členom na stránke komunity. Členovia komunity môžu vstúpiť do miestnosti kliknutím.", "Add rooms to this community": "Pridať miestnosti do tejto komunity", @@ -773,9 +772,6 @@ "Device ID:": "ID zariadenia:", "Device key:": "Kľúč zariadenia:", "Ignored Users": "Ignorovaní používatelia", - "Bug Report": "Hlásenie chyby", - "Found a bug?": "Našli ste chybu?", - "Report it": "Ohláste ju", "Analytics": "Analytické údaje", "Riot collects anonymous analytics to allow us to improve the application.": "Riot zbiera anonymné analytické údaje, čo nám umožňuje aplikáciu ďalej zlepšovať.", "Labs": "Experimenty", @@ -923,7 +919,6 @@ "Call": "Hovor", "Answer": "Prijať", "Send": "Odoslať", - "Tag Panel": "Panel so značkami", "Delete %(count)s devices|other": "Vymazať %(count)s zariadení", "Delete %(count)s devices|one": "Vymazať zariadenie", "Select devices": "Vybrať zariadenia", diff --git a/src/i18n/strings/sr.json b/src/i18n/strings/sr.json index a6d8ab8540..6bbbf8ac8f 100644 --- a/src/i18n/strings/sr.json +++ b/src/i18n/strings/sr.json @@ -173,7 +173,6 @@ "Message Replies": "Одговори", "Message Pinning": "Закачене поруке", "Presence Management": "Управљање присутношћу", - "Tag Panel": "Означи површ", "Disable Emoji suggestions while typing": "Онемогући предлагање емоџија приликом куцања", "Use compact timeline layout": "Користи збијени распоред временске линије", "Hide removed messages": "Сакриј уклоњене поруке", @@ -631,7 +630,6 @@ "expand": "рашири", "Custom of %(powerLevel)s": "Прилагођени ниво %(powerLevel)s", "Custom level": "Прилагођени ниво", - "Quote": "Цитат", "Room directory": "Фасцикла са собама", "Start chat": "Започни ћаскање", "And %(count)s more...|other": "И %(count)s других...", @@ -744,7 +742,6 @@ "Leave Community": "Напусти заједницу", "Leave %(groupName)s?": "Напустити %(groupName)s?", "Leave": "Напусти", - "Unable to leave room": "Не могу да напустим собу", "Community Settings": "Подешавања заједнице", "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Ове собе су приказане члановима заједнице на страници заједнице. Чланови заједнице могу приступити собама кликом на њих.", "Add rooms to this community": "Додај собе у ову заједницу", @@ -766,8 +763,6 @@ "Failed to leave room": "Нисам успео да напустим собу", "Signed Out": "Одјављен", "For security, this session has been signed out. Please sign in again.": "Зарад безбедности, одјављени сте из ове сесије. Пријавите се поново.", - "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": "Нађени су стари криптографски подаци", "The platform you're on": "Платформа коју користите", "The version of Riot.im": "Riot.im издање", @@ -855,9 +850,6 @@ "Device ID:": "ИБ уређаја:", "Device key:": "Кључ уређаја:", "Ignored Users": "Занемарени корисници", - "Bug Report": "Извештај о грешци", - "Found a bug?": "Нашли сте грешку?", - "Report it": "Пријавите је", "Riot collects anonymous analytics to allow us to improve the application.": "Riot прикупља анонимне податке о коришћењу да бисмо побољшали апликацију.", "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.": "Сазнајте више о нашем начину употребе аналитике.", diff --git a/src/i18n/strings/sv.json b/src/i18n/strings/sv.json index 482233e2b4..eca49ac8a9 100644 --- a/src/i18n/strings/sv.json +++ b/src/i18n/strings/sv.json @@ -37,7 +37,6 @@ "Autoplay GIFs and videos": "Spela automatiskt upp GIFar och videor", "Are you sure you want to reject the invitation?": "Vill du avvisa inbjudan?", "Bulk Options": "Volymhandlingar", - "Bug Report": "Buggrapport", "Blacklisted": "Svartlistad", "%(senderName)s banned %(targetName)s.": "%(senderName)s bannade %(targetName)s.", "Banned users": "Bannade användare", @@ -178,7 +177,6 @@ "Forgot your password?": "Glömt lösenord?", "For security, this session has been signed out. Please sign in again.": "Av säkerhetsskäl har den här sessionen loggats ut. Vänligen logga in igen.", "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.": "Av säkerhetsskäl kommer alla krypteringsnycklar att raderas från den här webbläsaren om du loggar ut. Om du vill läsa din krypterade meddelandehistorik från framtida Riot-sessioner, exportera nycklarna till förvar.", - "Found a bug?": "Hittade du en bugg?", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s från %(fromPowerLevel)s till %(toPowerLevel)s", "Guest access is disabled on this Home Server.": "Gäståtkomst är inte aktiverat på den här hemservern.", "Guests cannot join this room even if explicitly invited.": "Gäster kan inte gå med i det här rummet fastän de är uttryckligen inbjudna.", @@ -301,7 +299,6 @@ "Remove": "Ta bort", "Remove %(threePid)s?": "Ta bort %(threePid)s?", "%(senderName)s requested a VoIP conference.": "%(senderName)s begärde en VoIP-konferens.", - "Report it": "Rapportera det", "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.": "Om du återställer ditt lösenord kommer alla krypteringsnycklar på alla enheter att återställas, vilket gör krypterad meddelandehistorik oläsbar om du inte först exporterar dina rumsnycklar och sedan importerar dem igen. I framtiden kommer det här att förbättras.", "Results from DuckDuckGo": "Resultat från DuckDuckGo", "Return to login screen": "TIllbaka till login-skärmen", diff --git a/src/i18n/strings/th.json b/src/i18n/strings/th.json index 540902c8f1..d37714d163 100644 --- a/src/i18n/strings/th.json +++ b/src/i18n/strings/th.json @@ -6,7 +6,6 @@ "Camera": "กล้อง", "Advanced": "ขึ้นสูง", "Ban": "แบน", - "Bug Report": "รายงานจุดบกพร่อง", "Change Password": "เปลี่ยนรหัสผ่าน", "Create Room": "สรัางห้อง", "Delete": "ลบ", @@ -23,7 +22,6 @@ "Emoji": "อีโมจิ", "Enable encryption": "เปิดใช้งานการเข้ารหัส", "Error": "ข้อผิดพลาด", - "Found a bug?": "พบจุดบกพร่อง?", "%(displayName)s is typing": "%(displayName)s กำลังพิมพ์", "Kick": "เตะ", "Low priority": "ความสำคัญต่ำ", @@ -49,7 +47,6 @@ "Settings": "การตั้งค่า", "unknown error code": "รหัสข้อผิดพลาดที่ไม่รู้จัก", "olm version:": "เวอร์ชัน olm:", - "Report it": "รายงานเลย", "Remove": "ลบ", "Custom Server Options": "กำหนดเซิร์ฟเวอร์เอง", "Favourite": "รายการโปรด", diff --git a/src/i18n/strings/tr.json b/src/i18n/strings/tr.json index 922bdc33a1..42e92c2cb4 100644 --- a/src/i18n/strings/tr.json +++ b/src/i18n/strings/tr.json @@ -48,7 +48,6 @@ "Banned users": "Yasaklanan(Banlanan) Kullanıcılar", "Bans user with given id": "Yasaklanan(Banlanan) Kullanıcılar , ID'leri ile birlikte", "Blacklisted": "Kara listeye alınanlar", - "Bug Report": "Hata Raporu", "Bulk Options": "Toplu Seçenekler", "Call Timeout": "Arama Zaman Aşımı", "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.": "Ana Sunucu'ya bağlanılamıyor - lütfen bağlantınızı kontrol edin , Ana Sunucu SSL sertifikanızın güvenilir olduğundan ve bir tarayıcı uzantısının istekleri engellemiyor olduğundan emin olun.", @@ -178,7 +177,6 @@ "Forgot your password?": "Şifrenizi mi unuttunuz ?", "For security, this session has been signed out. Please sign in again.": "Güvenlik için , bu oturuma çıkış yapıldı . Lütfen tekrar oturum açın.", "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.": "Güvenlik için , çıkış yaparsanız bu tarayıcıdan tüm uçtan uca şifreleme anahtarları silinecek . Konuşma geçmişinizi çözebilmek isterseniz gelecekteki Riot oturumlarında , lütfen Oda Anahtarlarını güvenlik amaçlı Dışa Aktarın.", - "Found a bug?": "Hata buldunuz mu ?", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s %(fromPowerLevel)s den %(toPowerLevel)s ' ye", "Guest access is disabled on this Home Server.": "Misafir erişimi bu Ana Sunucu için devre dışı.", "Guests cannot join this room even if explicitly invited.": "Misafirler açıkca davet edilseler bile bu odaya katılamazlar.", @@ -301,7 +299,6 @@ "Remove": "Kaldır", "Remove %(threePid)s?": "%(threePid)s 'i kaldır ?", "%(senderName)s requested a VoIP conference.": "%(senderName)s bir VoIP konferansı talep etti.", - "Report it": "Bunu rapor et", "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.": "Şifrenizi sıfırlamak , eğer Oda Anahtarlarınızı dışa aktarmaz ve daha sonra içe aktarmaz iseniz , şu anda tüm cihazlarda uçtan uca şifreleme anahtarlarını sıfırlayarak şifreli sohbetleri okunamaz hale getirecek . Gelecekte bu iyileştirilecek.", "Results from DuckDuckGo": "DuckDuckGo Sonuçları", "Return to login screen": "Giriş ekranına dön", diff --git a/src/i18n/strings/zh_Hans.json b/src/i18n/strings/zh_Hans.json index 06b8dbbe30..0b01a5d0d6 100644 --- a/src/i18n/strings/zh_Hans.json +++ b/src/i18n/strings/zh_Hans.json @@ -65,7 +65,6 @@ "Forgot your password?": "忘记密码?", "For security, this session has been signed out. Please sign in again.": "出于安全考虑,此会话已被注销。请重新登录。.", "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.": "出于安全考虑,用户注销时会清除浏览器里的端到端加密密钥。如果你想要下次登录 Riot 时能解密过去的聊天记录,请导出你的聊天室密钥。", - "Found a bug?": "发现漏洞?", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s 从 %(fromPowerLevel)s 变为 %(toPowerLevel)s", "Guests cannot join this room even if explicitly invited.": "游客不能加入此聊天室,即使有人主动邀请。.", "Hangup": "挂断", @@ -82,7 +81,6 @@ "Invalid address format": "地址格式错误", "Invalid Email Address": "邮箱地址格式错误", "Invalid file%(extra)s": "非法文件%(extra)s", - "Report it": "报告", "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.": "重设密码会导致所有设备上的端到端加密密钥被重置,使得加密的聊天记录不可读,除非你事先导出密钥,修改密码后再导入。此问题将来会得到改善。.", "Return to login screen": "返回登录页面", "Riot does not have permission to send you notifications - please check your browser settings": "Riot 未被允许向你推送消息 - 请检查浏览器设置", @@ -184,7 +182,6 @@ "Are you sure you want to upload the following files?": "你确定要上传这些文件吗?", "Bans user with given id": "封禁指定 ID 的用户", "Blacklisted": "已列入黑名单", - "Bug Report": "反馈漏洞", "Bulk Options": "批量操作", "Call Timeout": "通话超时", "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 证书被信任,且没有浏览器插件拦截请求。", @@ -727,7 +724,6 @@ "You have entered an invalid address.": "你输入了一个无效地址。", "Advanced options": "高级选项", "Leave": "离开", - "Unable to leave room": "无法离开聊天室", "Description": "描述", "Warning": "警告", "Light theme": "浅色主题", diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json index 759ef2bac8..11eae215f9 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -12,7 +12,6 @@ "Ban": "封禁", "Banned users": "被封禁的用戶", "Blacklisted": "已列入黑名單", - "Bug Report": "臭蟲回報", "Call Timeout": "通話超時", "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "當瀏覽器網址列裡有 HTTPS URL 時,不能使用 HTTP 連線到家伺服器。請採用 HTTPS 或者允許不安全的指令稿。", "Can't load user settings": "無法載入使用者設定", @@ -102,7 +101,6 @@ "Forgot your password?": "忘記密碼?", "For security, this session has been signed out. Please sign in again.": "因為安全因素,此工作階段已被登出。請重新登入。", "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.": "因為安全因素,登出將會從此瀏覽器刪除任何端到端加密的金鑰。若您想要在未來的 Riot 工作階段中解密您的對話紀錄,請將您的聊天室金鑰匯出並好好存放。", - "Found a bug?": "發現漏洞?", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s 從 %(fromPowerLevel)s 變為 %(toPowerLevel)s", "Guests cannot join this room even if explicitly invited.": "游客不能加入此聊天室,即使有人主動邀請。.", "Hangup": "掛斷", @@ -127,7 +125,6 @@ "Leave room": "離開聊天室", "Login as guest": "以游客的身份登錄", "New password": "新密碼", - "Report it": "報告", "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.": "重設密碼目前會把所有裝置上的端到端加密金鑰重設,讓已加密的聊天歷史不可讀,除非您先匯出您的聊天室金鑰並在稍後重新匯入。這會在未來改進。", "Return to login screen": "返回登錄頁面", "Riot does not have permission to send you notifications - please check your browser settings": "Riot 未被允許向你推送通知 ── 請檢查您的瀏覽器設定", @@ -719,7 +716,6 @@ "Message Replies": "訊息回覆", "Message Pinning": "訊息釘選", "Presence Management": "出席管理", - "Tag Panel": "標籤面板", "Disable Emoji suggestions while typing": "在輸入時停用繪文字建議", "Hide avatar changes": "隱藏大頭貼變更", "Hide display name changes": "隱藏顯示名稱變更", @@ -923,7 +919,6 @@ "Leave Community": "離開社群", "Leave %(groupName)s?": "離開 %(groupName)s?", "Leave": "離開", - "Unable to leave room": "無法離開聊天室", "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 已經邀請您加入此社群", @@ -991,6 +986,5 @@ "If your other devices do not have the key for this message you will not be able to decrypt them.": "若您的其他裝置沒有這個訊息的金鑰,您將無法將它們解密。", "Key request sent.": "金鑰請求已傳送。", "Re-request encryption keys from your other devices.": "從您的其他裝置重新請求加密金鑰。", - "%(user)s is a %(userRole)s": "%(user)s 是 %(userRole)s", - "Changes made to your community might not be seen by other users for up to 30 minutes.": "其他使用者在最多 30 分鐘內可能不會慨到您對社群所做的變更。" + "%(user)s is a %(userRole)s": "%(user)s 是 %(userRole)s" } From 871fee26f8e5b9152fca97c699f70b9343052cc3 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 4 Apr 2018 11:28:31 +0100 Subject: [PATCH 032/190] run i18n prune and gen Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/i18n/strings/da.json | 1 - src/i18n/strings/id.json | 3 --- src/i18n/strings/te.json | 2 -- src/i18n/strings/uk.json | 1 - 4 files changed, 7 deletions(-) diff --git a/src/i18n/strings/da.json b/src/i18n/strings/da.json index dbcc9fbb2c..bccb8c28c2 100644 --- a/src/i18n/strings/da.json +++ b/src/i18n/strings/da.json @@ -52,7 +52,6 @@ "Are you sure you want to reject the invitation?": "Er du sikker på du vil afvise invitationen?", "Are you sure you want to upload the following files?": "Er du sikker på du vil sende de følgende filer?", "Banned users": "Bortviste brugere", - "Bug Report": "Fejlrapport", "Bulk Options": "Masseindstillinger", "Can't load user settings": "Kan ikke indlæse brugerindstillinger", "Changes to who can read history will only apply to future messages in this room": "Ændringer til hvem der kan læse historie gælder kun for fremtidige meddelelser i dette rum", diff --git a/src/i18n/strings/id.json b/src/i18n/strings/id.json index e95f3b13af..bb79908ae3 100644 --- a/src/i18n/strings/id.json +++ b/src/i18n/strings/id.json @@ -13,7 +13,6 @@ "Are you sure?": "Anda yakin?", "An error has occurred.": "Telah terjadi kesalahan.", "Are you sure you want to reject the invitation?": "Anda yakin menolak undangannya?", - "Bug Report": "Laporan Bug", "Can't load user settings": "Tidak dapat memuat pengaturan pengguna", "Change Password": "Ubah Password", "Click here to fix": "Klik di sini untuk perbaiki", @@ -56,7 +55,6 @@ "Favourite": "Favorit", "Favourites": "Favorit", "Forgot your password?": "Lupa password?", - "Found a bug?": "Menemukan bug?", "Import": "Impor", "Incorrect verification code": "Kode verifikasi tidak benar", "Invalid Email Address": "Alamat email tidak benar", @@ -88,7 +86,6 @@ "Public Chat": "Obrolan Publik", "Reason": "Alasan", "Register": "Registrasi", - "Report it": "Laporkan", "riot-web version:": "riot-web versi:", "Return to login screen": "Kembali ke halaman masuk", "Room Colour": "Warna Ruang", diff --git a/src/i18n/strings/te.json b/src/i18n/strings/te.json index ec45eefadf..12ebf9c908 100644 --- a/src/i18n/strings/te.json +++ b/src/i18n/strings/te.json @@ -44,7 +44,6 @@ "Banned users": "నిషేధించిన వినియోగదారులు", "Bans user with given id": "ఇచ్చిన ఐడి తో వినియోగదారుని నిషేధించారు", "Blacklisted": "నిరోధిత జాబితాలోని", - "Bug Report": "బగ్ నివేదిక", "Bulk Options": "సమూహ ఐచ్ఛికాలు", "Call Timeout": "కాల్ గడువు ముగిసింది", "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.": "గృహనిర్వాహకులకు కనెక్ట్ చేయలేరు - దయచేసి మీ కనెక్టివిటీని తనిఖీ చేయండి, మీ 1 హోమరుసు యొక్క ఎస్ఎస్ఎల్ సర్టిఫికేట్ 2 ని విశ్వసనీయపరుచుకొని, బ్రౌజర్ పొడిగింపు అభ్యర్థనలను నిరోధించబడదని నిర్ధారించుకోండి.", @@ -170,7 +169,6 @@ "riot-web version:": "రయట్-వెబ్ సంస్కరణ:", "Riot was not given permission to send notifications - please try again": "రయట్ కు ప్రకటనలను పంపడానికి అనుమతి లేదు - దయచేసి మళ్ళీ ప్రయత్నించండి", "Unable to restore session": "సెషన్ను పునరుద్ధరించడానికి సాధ్యపడలేదు", - "Report it": "దానిని నివేదించండి", "Remove": "తొలగించు", "Room directory": "గది వివరము", "Create new room": "క్రొత్త గది సృష్టించండి", diff --git a/src/i18n/strings/uk.json b/src/i18n/strings/uk.json index 2ff04fec65..8b101fb36b 100644 --- a/src/i18n/strings/uk.json +++ b/src/i18n/strings/uk.json @@ -73,7 +73,6 @@ "Banned users": "Заблоковані користувачі", "Bans user with given id": "Блокує користувача з заданим ID", "Blacklisted": "В чорному списку", - "Bug Report": "Звіт про помилку", "Bulk Options": "Групові параметри", "Call Timeout": "Час очікування виклика", "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-сертифікат домашнього сервера є довіреним і що розширення браузера не блокує запити.", From f765db7d167f11f2c69e35aa2a09b14b67bab3df Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sat, 7 Apr 2018 12:18:53 +0100 Subject: [PATCH 033/190] only clear reply_to_event if there was one to begin with Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/MessageComposerInput.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index 5e4aae5ba2..d0ad2371d3 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -867,14 +867,15 @@ export default class MessageComposerInput extends React.Component { } content.body = nestedReply.body + content.body; } + + // Clear reply_to_event as we put the message into the queue + // if the send fails, retry will handle resending. + dis.dispatch({ + action: 'reply_to_event', + event: null, + }); } - // Clear reply_to_event as we put the message into the queue - // if the send fails, retry will handle resending. - dis.dispatch({ - action: 'reply_to_event', - event: null, - }); this.client.sendMessage(this.props.room.roomId, content).done((res) => { dis.dispatch({ From a90bd6cd4f077b78912d180936bc5871464130b1 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 13 Apr 2018 12:28:58 +0100 Subject: [PATCH 034/190] Allow collapsing ReplyThread from MessageContextMenu Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/ReplyThread.js | 14 ++++++++++++-- src/components/views/rooms/EventTile.js | 12 ++++++++---- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index de6ff46610..6796e2bcc7 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -52,6 +52,8 @@ export default class ReplyThread extends React.Component { }; this.onQuoteClick = this.onQuoteClick.bind(this); + this.canCollapse = this.canCollapse.bind(this); + this.collapse = this.collapse.bind(this); } componentWillMount() { @@ -64,6 +66,14 @@ export default class ReplyThread extends React.Component { this.unmounted = true; } + canCollapse() { + return this.state.events.length > 1; + } + + collapse() { + this.initialize(); + } + async initialize() { const {parentEv} = this.props; const inReplyTo = ReplyThread.getInReplyTo(parentEv); @@ -227,11 +237,11 @@ export default class ReplyThread extends React.Component { }; } - static getQuote(parentEv, onWidgetLoad) { + static getThread(parentEv, onWidgetLoad, ref) { if (!SettingsStore.isFeatureEnabled("feature_rich_quoting") || !ReplyThread.getInReplyTo(parentEv)) { return
; } - return ; + return ; } render() { diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index c754f7ceeb..50c0e29ed4 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -18,7 +18,7 @@ limitations under the License. 'use strict'; -import Reply from "../elements/ReplyThread"; +import ReplyThread from "../elements/ReplyThread"; const React = require('react'); import PropTypes from 'prop-types'; @@ -302,12 +302,16 @@ module.exports = withMatrixClient(React.createClass({ const x = buttonRect.right + window.pageXOffset; const y = (buttonRect.top + (buttonRect.height / 2) + window.pageYOffset) - 19; const self = this; + + const {tile, replyThread} = this.refs; + ContextualMenu.createMenu(MessageContextMenu, { chevronOffset: 10, mxEvent: this.props.mxEvent, left: x, top: y, - eventTileOps: this.refs.tile && this.refs.tile.getEventTileOps ? this.refs.tile.getEventTileOps() : undefined, + eventTileOps: tile && tile.getEventTileOps ? tile.getEventTileOps() : undefined, + collapseReplyThread: replyThread && replyThread.canCollapse() ? replyThread.collapse : undefined, onFinished: function() { self.setState({menu: false}); }, @@ -662,7 +666,7 @@ module.exports = withMatrixClient(React.createClass({ { this._renderE2EPadlock() } { this.props.tileShape === 'reply_preview' - && Reply.getQuote(this.props.mxEvent, this.props.onWidgetLoad) + && ReplyThread.getThread(this.props.mxEvent, this.props.onWidgetLoad, 'replyThread') } { this._renderE2EPadlock() } - { Reply.getQuote(this.props.mxEvent, this.props.onWidgetLoad) } + { ReplyThread.getThread(this.props.mxEvent, this.props.onWidgetLoad, 'replyThread') } Date: Fri, 20 Apr 2018 09:23:27 +0100 Subject: [PATCH 035/190] post BigMerge fixup - merge in stuff from riot-web PR Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- res/css/_components.scss | 4 +- .../{_Quote.scss => _ReplyThread.scss} | 12 +++-- res/css/views/rooms/_EventTile.scss | 39 ++++++-------- res/css/views/rooms/_QuotePreview.scss | 36 ------------- res/css/views/rooms/_ReplyPreview.scss | 52 +++++++++++++++++++ .../views/context_menus/MessageContextMenu.js | 26 ++++++++-- 6 files changed, 102 insertions(+), 67 deletions(-) rename res/css/views/elements/{_Quote.scss => _ReplyThread.scss} (74%) delete mode 100644 res/css/views/rooms/_QuotePreview.scss create mode 100644 res/css/views/rooms/_ReplyPreview.scss diff --git a/res/css/_components.scss b/res/css/_components.scss index 9770010324..50e8eb11d1 100644 --- a/res/css/_components.scss +++ b/res/css/_components.scss @@ -53,7 +53,7 @@ @import "./views/elements/_InlineSpinner.scss"; @import "./views/elements/_MemberEventListSummary.scss"; @import "./views/elements/_ProgressBar.scss"; -@import "./views/elements/_Quote.scss"; +@import "./views/elements/_ReplyThread.scss"; @import "./views/elements/_RichText.scss"; @import "./views/elements/_RoleButton.scss"; @import "./views/elements/_Spinner.scss"; @@ -89,7 +89,7 @@ @import "./views/rooms/_PinnedEventTile.scss"; @import "./views/rooms/_PinnedEventsPanel.scss"; @import "./views/rooms/_PresenceLabel.scss"; -@import "./views/rooms/_QuotePreview.scss"; +@import "./views/rooms/_ReplyPreview.scss"; @import "./views/rooms/_RoomDropTarget.scss"; @import "./views/rooms/_RoomHeader.scss"; @import "./views/rooms/_RoomList.scss"; diff --git a/res/css/views/elements/_Quote.scss b/res/css/views/elements/_ReplyThread.scss similarity index 74% rename from res/css/views/elements/_Quote.scss rename to res/css/views/elements/_ReplyThread.scss index 0af555b5aa..a02f42751c 100644 --- a/res/css/views/elements/_Quote.scss +++ b/res/css/views/elements/_ReplyThread.scss @@ -1,5 +1,5 @@ /* -Copyright 2017 Vector Creations Ltd +Copyright 2018 Vector Creations Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,13 +14,19 @@ See the License for the specific language governing permissions and limitations under the License. */ -.mx_Quote .mx_DateSeparator { +.mx_ReplyThread .mx_DateSeparator { font-size: 1em !important; margin-bottom: 0; padding-bottom: 1px; bottom: -5px; } -.mx_Quote_show { +.mx_ReplyThread_show { cursor: pointer; } + +blockquote.mx_ReplyThread { + margin-left: 0; + padding-left: 10px; + border-left: 4px solid $blockquote-bar-color; +} diff --git a/res/css/views/rooms/_EventTile.scss b/res/css/views/rooms/_EventTile.scss index 4bb81a2e53..d721e1f7cd 100644 --- a/res/css/views/rooms/_EventTile.scss +++ b/res/css/views/rooms/_EventTile.scss @@ -84,7 +84,7 @@ limitations under the License. position: absolute; } -.mx_EventTile_line { +.mx_EventTile_line, .mx_EventTile_reply { position: relative; /* ideally should be 100px, but 95px gives us a max thumbnail size of 800x600, which is nice */ margin-right: 110px; @@ -96,7 +96,7 @@ limitations under the License. line-height: 22px; } -.mx_EventTile_quote { +.mx_EventTile_reply { margin-right: 10px; } @@ -119,7 +119,7 @@ limitations under the License. background-color: $event-selected-color; } -.mx_EventTile:hover .mx_EventTile_line:not(.mx_EventTile_quote), +..mx_EventTile:hover .mx_EventTile_line, .mx_EventTile.menu .mx_EventTile_line { background-color: $event-selected-color; @@ -157,7 +157,8 @@ limitations under the License. color: $event-notsent-color; } -.mx_EventTile_redacted .mx_EventTile_line .mx_UnknownBody { +.mx_EventTile_redacted .mx_EventTile_line .mx_UnknownBody, +.mx_EventTile_redacted .mx_EventTile_reply .mx_UnknownBody { display: block; width: 100%; height: 22px; @@ -202,10 +203,9 @@ limitations under the License. text-decoration: none; } -.mx_EventTile_last .mx_MessageTimestamp, -.mx_EventTile:hover .mx_MessageTimestamp, -.mx_EventTile.menu .mx_MessageTimestamp -{ +.mx_EventTile_last > div > a > .mx_MessageTimestamp, +.mx_EventTile:hover > div > a > .mx_MessageTimestamp, +.mx_EventTile.menu > div > a > .mx_MessageTimestamp { visibility: visible; } @@ -235,12 +235,7 @@ limitations under the License. } .mx_EventTile:hover .mx_EventTile_editButton, -.mx_EventTile.menu .mx_EventTile_editButton -{ - visibility: visible; -} - -.mx_EventTile.menu .mx_MessageTimestamp { +.mx_EventTile.menu .mx_EventTile_editButton { visibility: visible; } @@ -348,8 +343,8 @@ limitations under the License. border-left: $e2e-unverified-color 5px solid; } -.mx_EventTile:hover.mx_EventTile_verified .mx_MessageTimestamp, -.mx_EventTile:hover.mx_EventTile_unverified .mx_MessageTimestamp { +.mx_EventTile:hover.mx_EventTile_verified .mx_EventTile_line > a > .mx_MessageTimestamp, +.mx_EventTile:hover.mx_EventTile_unverified .mx_EventTile_line > a > .mx_MessageTimestamp { left: 3px; width: auto; } @@ -360,8 +355,8 @@ limitations under the License. } */ -.mx_EventTile:hover.mx_EventTile_verified .mx_EventTile_e2eIcon, -.mx_EventTile:hover.mx_EventTile_unverified .mx_EventTile_e2eIcon { +.mx_EventTile:hover.mx_EventTile_verified .mx_EventTile_line > .mx_EventTile_e2eIcon, +.mx_EventTile:hover.mx_EventTile_unverified .mx_EventTile_line > .mx_EventTile_e2eIcon { display: block; left: 41px; } @@ -456,7 +451,7 @@ limitations under the License. // same as the padding for non-compact .mx_EventTile.mx_EventTile_info padding-top: 0px; font-size: 13px; - .mx_EventTile_line { + .mx_EventTile_line, .mx_EventTile_reply { line-height: 20px; } .mx_EventTile_avatar { @@ -474,7 +469,7 @@ limitations under the License. .mx_EventTile_avatar { top: 2px; } - .mx_EventTile_line { + .mx_EventTile_line, .mx_EventTile_reply { padding-top: 0px; padding-bottom: 1px; } @@ -482,13 +477,13 @@ limitations under the License. .mx_EventTile.mx_EventTile_emote.mx_EventTile_continuation { padding-top: 0; - .mx_EventTile_line { + .mx_EventTile_line, .mx_EventTile_reply { padding-top: 0px; padding-bottom: 0px; } } - .mx_EventTile_line { + .mx_EventTile_line, .mx_EventTile_reply { padding-top: 0px; padding-bottom: 0px; } diff --git a/res/css/views/rooms/_QuotePreview.scss b/res/css/views/rooms/_QuotePreview.scss deleted file mode 100644 index 86fd79d473..0000000000 --- a/res/css/views/rooms/_QuotePreview.scss +++ /dev/null @@ -1,36 +0,0 @@ -.mx_QuotePreview { - position: absolute; - bottom: 0; - z-index: 1000; - width: 100%; - border: 1px solid $primary-hairline-color; - background: $primary-bg-color; - border-bottom: none; - border-radius: 4px 4px 0 0; - max-height: 50vh; - overflow: auto -} - -.mx_QuotePreview_section { - border-bottom: 1px solid $primary-hairline-color; -} - -.mx_QuotePreview_header { - margin: 12px; - color: $primary-fg-color; - font-weight: 400; - opacity: 0.4; -} - -.mx_QuotePreview_title { - float: left; -} - -.mx_QuotePreview_cancel { - float: right; - cursor: pointer; -} - -.mx_QuotePreview_clear { - clear: both; -} diff --git a/res/css/views/rooms/_ReplyPreview.scss b/res/css/views/rooms/_ReplyPreview.scss new file mode 100644 index 0000000000..5bf4adff27 --- /dev/null +++ b/res/css/views/rooms/_ReplyPreview.scss @@ -0,0 +1,52 @@ +/* +Copyright 2018 Vector Creations Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_ReplyPreview { + position: absolute; + bottom: 0; + z-index: 1000; + width: 100%; + border: 1px solid $primary-hairline-color; + background: $primary-bg-color; + border-bottom: none; + border-radius: 4px 4px 0 0; + max-height: 50vh; + overflow: auto +} + +.mx_ReplyPreview_section { + border-bottom: 1px solid $primary-hairline-color; +} + +.mx_ReplyPreview_header { + margin: 12px; + color: $primary-fg-color; + font-weight: 400; + opacity: 0.4; +} + +.mx_ReplyPreview_title { + float: left; +} + +.mx_ReplyPreview_cancel { + float: right; + cursor: pointer; +} + +.mx_ReplyPreview_clear { + clear: both; +} diff --git a/src/components/views/context_menus/MessageContextMenu.js b/src/components/views/context_menus/MessageContextMenu.js index 860d94ea0e..dc6f4d45d0 100644 --- a/src/components/views/context_menus/MessageContextMenu.js +++ b/src/components/views/context_menus/MessageContextMenu.js @@ -18,6 +18,7 @@ limitations under the License. 'use strict'; import React from 'react'; +import PropTypes from 'prop-types'; import MatrixClientPeg from '../../../MatrixClientPeg'; import dis from '../../../dispatcher'; @@ -34,13 +35,16 @@ module.exports = React.createClass({ propTypes: { /* the MatrixEvent associated with the context menu */ - mxEvent: React.PropTypes.object.isRequired, + mxEvent: PropTypes.object.isRequired, /* an optional EventTileOps implementation that can be used to unhide preview widgets */ - eventTileOps: React.PropTypes.object, + eventTileOps: PropTypes.object, + + /* an optional function which allows to collapse reply thread */ + collapseReplyThread: PropTypes.func, /* callback called when the menu is dismissed */ - onFinished: React.PropTypes.func, + onFinished: PropTypes.func, }, getInitialState: function() { @@ -182,12 +186,17 @@ module.exports = React.createClass({ onReplyClick: function() { dis.dispatch({ - action: 'quote_event', + action: 'reply_to_event', event: this.props.mxEvent, }); this.closeMenu(); }, + onCollapseReplyThreadClick: function() { + this.props.collapseReplyThread(); + this.closeMenu(); + }, + render: function() { const eventStatus = this.props.mxEvent.status; let resendButton; @@ -200,6 +209,7 @@ module.exports = React.createClass({ let externalURLButton; let quoteButton; let replyButton; + let collapseReplyThread; if (eventStatus === 'not_sent') { resendButton = ( @@ -305,6 +315,13 @@ module.exports = React.createClass({ ); } + if (this.props.collapseReplyThread) { + collapseReplyThread = ( +
+ { _t('Collapse Reply Thread') } +
+ ); + } return (
@@ -320,6 +337,7 @@ module.exports = React.createClass({ { quoteButton } { replyButton } { externalURLButton } + { collapseReplyThread }
); }, From 563fc9adc767fd87da3333c926dcd8e13f10ee9b Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 20 Apr 2018 09:37:25 +0100 Subject: [PATCH 036/190] fix bad copy-paste from other diff Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- res/css/views/rooms/_EventTile.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/css/views/rooms/_EventTile.scss b/res/css/views/rooms/_EventTile.scss index d721e1f7cd..9217a64040 100644 --- a/res/css/views/rooms/_EventTile.scss +++ b/res/css/views/rooms/_EventTile.scss @@ -119,7 +119,7 @@ limitations under the License. background-color: $event-selected-color; } -..mx_EventTile:hover .mx_EventTile_line, +.mx_EventTile:hover .mx_EventTile_line, .mx_EventTile.menu .mx_EventTile_line { background-color: $event-selected-color; From 7e8288f7ae12cc5c83843fcd07ef19378efef77c Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 20 Apr 2018 09:39:14 +0100 Subject: [PATCH 037/190] i18n-gen, i18n-prune Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/i18n/strings/ar.json | 1 - src/i18n/strings/bg.json | 4 ---- src/i18n/strings/ca.json | 4 ---- src/i18n/strings/cs.json | 4 ---- src/i18n/strings/da.json | 3 --- src/i18n/strings/de_DE.json | 4 ---- src/i18n/strings/en_EN.json | 6 +----- src/i18n/strings/eo.json | 4 ---- src/i18n/strings/es.json | 3 --- src/i18n/strings/eu.json | 4 ---- src/i18n/strings/fi.json | 5 ----- src/i18n/strings/fr.json | 4 ---- src/i18n/strings/gl.json | 4 ---- src/i18n/strings/he.json | 2 -- src/i18n/strings/hu.json | 4 ---- src/i18n/strings/id.json | 1 - src/i18n/strings/it.json | 4 ---- src/i18n/strings/ko.json | 2 -- src/i18n/strings/lt.json | 3 --- src/i18n/strings/lv.json | 4 ---- src/i18n/strings/ml.json | 1 - src/i18n/strings/nl.json | 4 ---- src/i18n/strings/pl.json | 3 --- src/i18n/strings/pt.json | 1 - src/i18n/strings/pt_BR.json | 4 ---- src/i18n/strings/ru.json | 4 ---- src/i18n/strings/sk.json | 4 ---- src/i18n/strings/sq.json | 2 -- src/i18n/strings/sr.json | 4 ---- src/i18n/strings/sv.json | 3 --- src/i18n/strings/ta.json | 1 - src/i18n/strings/uk.json | 3 --- src/i18n/strings/zh_Hans.json | 3 --- src/i18n/strings/zh_Hant.json | 4 ---- 34 files changed, 1 insertion(+), 110 deletions(-) diff --git a/src/i18n/strings/ar.json b/src/i18n/strings/ar.json index cb223f5aaf..d461240e4b 100644 --- a/src/i18n/strings/ar.json +++ b/src/i18n/strings/ar.json @@ -43,7 +43,6 @@ "Collecting logs": "تجميع السجلات", "No update available.": "لا يوجد هناك أي تحديث.", "An error occurred whilst saving your email notification preferences.": "حدث خطأ ما أثناء عملية حفظ إعدادات الإشعارات عبر البريد الإلكتروني.", - "Bug report sent": "تم إرسال تقرير الأخطاء", "Collecting app version information": "تجميع المعلومات حول نسخة التطبيق", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "إلغاء مُعرف الغرفة %(alias)s وحذف %(name)s من الدليل؟", "Changelog": "سِجل التغييرات", diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json index 55cc648535..ede5624d88 100644 --- a/src/i18n/strings/bg.json +++ b/src/i18n/strings/bg.json @@ -206,7 +206,6 @@ "Failed to join room": "Неуспешно присъединяване към стаята", "Message Replies": "Отговори на съобщението", "Message Pinning": "Функция за закачане на съобщения", - "Presence Management": "Управление на присъствието", "Disable Emoji suggestions while typing": "Изключване на предложенията за емотиконите при писане", "Use compact timeline layout": "Използване на компактно оформление за списъка със съобщения", "Hide removed messages": "Скриване на премахнати съобщения", @@ -1070,7 +1069,6 @@ "Preparing to send logs": "Подготовка за изпращане на логове", "Explore Account Data": "Преглед на данните от профила", "All messages (noisy)": "Всички съобщения (шумно)", - "Away": "Отсъстващ", "Saturday": "Събота", "Remember, you can always set an email address in user settings if you change your mind.": "Ако си промените мнението, винаги може да зададете имейл адрес в настройки на потребителя.", "Direct Chat": "Директен чат", @@ -1107,7 +1105,6 @@ "Notify for all other messages/rooms": "Извести ме за всички други съобщения/стаи", "Unable to look up room ID from server": "Стая с такъв идентификатор не е намерена на сървъра", "Couldn't find a matching Matrix room": "Не успяхме да намерим съответната Matrix стая", - "Bug report sent": "Докладът за грешки е изпратен", "Invite to this room": "Покани в тази стая", "You cannot delete this message. (%(code)s)": "Това съобщение не може да бъде изтрито. (%(code)s)", "Thursday": "Четвъртък", @@ -1128,7 +1125,6 @@ "Low Priority": "Нисък приоритет", "What's New": "Какво ново", "Set Password": "Задаване на парола", - "Appear Offline": "Показване като офлайн", "An error occurred whilst saving your email notification preferences.": "Възникна грешка при запазване на настройките за имейл известяване.", "Enable audible notifications in web client": "Включване на звукови известия в уеб клиент", "Permalink": "Permalink", diff --git a/src/i18n/strings/ca.json b/src/i18n/strings/ca.json index d85b88ddf1..f2cb1c713b 100644 --- a/src/i18n/strings/ca.json +++ b/src/i18n/strings/ca.json @@ -213,7 +213,6 @@ "Failed to join room": "No s'ha pogut entrar a la sala", "Message Replies": "Respostes del missatge", "Message Pinning": "Fixació de missatges", - "Presence Management": "Gestió de presència", "Disable Emoji suggestions while typing": "Desactiva els suggeriments d'Emoji mentre s'escriu", "Use compact timeline layout": "Utilitza el disseny compacte de la línia de temps", "Hide join/leave messages (invites/kicks/bans unaffected)": "Amaga els missatges d'entrada i sortida (no afecta a les invitacions, expulsions o prohibicions)", @@ -955,7 +954,6 @@ "Preparing to send logs": "Preparant l'enviament de logs", "Explore Account Data": "Explora les dades del compte", "Remove from Directory": "Elimina del directori", - "Away": "Absent", "Saturday": "Dissabte", "Remember, you can always set an email address in user settings if you change your mind.": "Recordeu-ho, si canvieu d'idea, sempre podreu establir una adreça de correu electrònic a las vostra configuració d'usuari.", "Direct Chat": "Xat directe", @@ -992,7 +990,6 @@ "Notify for all other messages/rooms": "Notifica per a tots els altres missatges o sales", "Unable to look up room ID from server": "No s'ha pogut cercar l'ID de la sala en el servidor", "Couldn't find a matching Matrix room": "No s'ha pogut trobar una sala de Matrix que coincideixi", - "Bug report sent": "S'ha enviat l'informe d'error", "Invite to this room": "Convida a aquesta sala", "You cannot delete this message. (%(code)s)": "No podeu eliminar aquest missatge. (%(code)s)", "Thursday": "Dijous", @@ -1013,7 +1010,6 @@ "Login": "Inicia sessió", "Low Priority": "Baixa prioritat", "Unable to fetch notification target list": "No s'ha pogut obtenir la llista d'objectius de les notificacions", - "Appear Offline": "Apareix sense connexió", "Set Password": "Establiu una contrasenya", "Enable audible notifications in web client": "Habilita les notificacions d'àudio al client web", "Permalink": "Enllaç permanent", diff --git a/src/i18n/strings/cs.json b/src/i18n/strings/cs.json index 4bac6cd5d2..11dd85ba50 100644 --- a/src/i18n/strings/cs.json +++ b/src/i18n/strings/cs.json @@ -643,7 +643,6 @@ "%(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", @@ -1017,7 +1016,6 @@ "Enable desktop notifications": "Zapnout upozornění na ploše", "Explore Account Data": "Prozkoumat data o účtu", "Remove from Directory": "Odebrat z adresáře", - "Away": "Pryč", "Saturday": "Sobota", "Messages in one-to-one chats": "Zprávy v individuálních chatech", "Direct Chat": "Přímý chat", @@ -1031,7 +1029,6 @@ "Toolbox": "Sada nástrojů", "Collecting logs": "Sbírání logů", "more": "více", - "Bug report sent": "Hlášení o chybě bylo odesláno", "You must specify an event type!": "Musíte určit typ události!", "(HTTP status %(httpStatus)s)": "(HTTP status %(httpStatus)s)", "Invite to this room": "Pozvat do této místnosti", @@ -1070,7 +1067,6 @@ "Low Priority": "Nízká priorita", "Riot does not know how to join a room on this network": "Riot neví, jak vstoupit do místosti na této síti", "Set Password": "Nastavit heslo", - "Appear Offline": "Jevit se offline", "An error occurred whilst saving your email notification preferences.": "Při ukládání nastavení e-mailových upozornění nastala chyba.", "Enable audible notifications in web client": "Povolit zvuková upozornění ve webové aplikaci", "Permalink": "Trvalý odkaz", diff --git a/src/i18n/strings/da.json b/src/i18n/strings/da.json index 044c251e94..ed49d32ebe 100644 --- a/src/i18n/strings/da.json +++ b/src/i18n/strings/da.json @@ -317,7 +317,6 @@ "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot bruger mange avancerede browser funktioner, hvoraf nogle af dem ikke er tilgængelige eller er eksperimentelle i din browser.", "Event sent!": "Begivenhed sendt!", "Explore Account Data": "Udforsk Konto Data", - "Away": "Ikke til stede", "Saturday": "Lørdag", "Remember, you can always set an email address in user settings if you change your mind.": "Husk, du kan altid indstille en emailadresse i dine bruger indstillinger hvis du ombestemmer dig.", "Direct Chat": "Personlig Chat", @@ -351,7 +350,6 @@ "Notify for all other messages/rooms": "Underret om alle andre meddelelser / rum", "Unable to look up room ID from server": "Kunne ikke slå rum-id op på server", "Couldn't find a matching Matrix room": "Kunne ikke finde et matchende Matrix-rum", - "Bug report sent": "Fejl rapporteret", "All Rooms": "Alle rum", "You cannot delete this message. (%(code)s)": "Du kan ikke slette denne besked. (%(code)s)", "Thursday": "Torsdag", @@ -369,7 +367,6 @@ "Event Type": "Begivenhedstype", "Low Priority": "Lav prioritet", "Unable to fetch notification target list": "Kan ikke hente meddelelsesmålliste", - "Appear Offline": "Fremstå Offline", "Set Password": "Indstil Password", "Enable audible notifications in web client": "Aktivér hørbare underretninger i webklienten", "Permalink": "Permanent link", diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 831e3c5d6f..b709c283c3 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -907,7 +907,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", "Status.im theme": "Status.im-Thema", "%(duration)ss": "%(duration)ss", "%(duration)sm": "%(duration)sm", @@ -1073,7 +1072,6 @@ "Remember, you can always set an email address in user settings if you change your mind.": "Vergiss nicht, dass du in den Benutzereinstellungen jederzeit eine E-Mail-Adresse setzen kannst, wenn du deine Meinung änderst.", "Explore Account Data": "Benutzerkonto-Daten analysieren", "All messages (noisy)": "Alle Nachrichten (laut)", - "Away": "Abwesend", "Saturday": "Samstag", "I understand the risks and wish to continue": "Ich verstehe das Risiko und möchte fortfahren", "Direct Chat": "Direkt-Chat", @@ -1088,7 +1086,6 @@ "Collecting logs": "Protokolle werden abgerufen", "more": "mehr", "GitHub issue link:": "Link des GitHub-Problems:", - "Bug report sent": "Fehlerbericht wurde gesendet", "You must specify an event type!": "Du musst einen Event-Typ spezifizieren!", "(HTTP status %(httpStatus)s)": "(HTTP-Status %(httpStatus)s)", "Invite to this room": "In diesen Raum einladen", @@ -1129,7 +1126,6 @@ "Login": "Anmeldung", "Low Priority": "Niedrige Priorität", "Unable to fetch notification target list": "Liste der Benachrichtigungsempfänger konnte nicht abgerufen werden", - "Appear Offline": "Als offline anzeigen", "Set Password": "Passwort einrichten", "Enable audible notifications in web client": "Audio-Benachrichtigungen im Web-Client aktivieren", "Permalink": "Permanenter Link", diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 1317736fcf..1e2f51f513 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -171,7 +171,6 @@ "%(widgetName)s widget modified by %(senderName)s": "%(widgetName)s widget modified by %(senderName)s", "%(widgetName)s widget added by %(senderName)s": "%(widgetName)s widget added by %(senderName)s", "%(widgetName)s widget removed by %(senderName)s": "%(widgetName)s widget removed by %(senderName)s", - "Message Pinning": "Message Pinning", "%(displayName)s is typing": "%(displayName)s is typing", "%(names)s and %(count)s others are typing|other": "%(names)s and %(count)s others are typing", "%(names)s and %(count)s others are typing|one": "%(names)s and one other is typing", @@ -187,7 +186,6 @@ "Failed to join room": "Failed to join room", "Message Replies": "Message Replies", "Message Pinning": "Message Pinning", - "Presence Management": "Presence Management", "Tag Panel": "Tag Panel", "Sticker Messages": "Sticker Messages", "Disable Emoji suggestions while typing": "Disable Emoji suggestions while typing", @@ -742,7 +740,6 @@ "Try using one of the following valid address types: %(validTypesList)s.": "Try using one of the following valid address types: %(validTypesList)s.", "You have entered an invalid address.": "You have entered an invalid address.", "Preparing to send logs": "Preparing to send logs", - "Bug report sent": "Bug report sent", "Logs sent": "Logs sent", "Thank you!": "Thank you!", "Failed to send logs: ": "Failed to send logs: ", @@ -860,8 +857,7 @@ "Permalink": "Permalink", "Quote": "Quote", "Source URL": "Source URL", - "Away": "Away", - "Appear Offline": "Appear Offline", + "Collapse Reply Thread": "Collapse Reply Thread", "Failed to set Direct Message status of room": "Failed to set Direct Message status of room", "All messages (noisy)": "All messages (noisy)", "All messages": "All messages", diff --git a/src/i18n/strings/eo.json b/src/i18n/strings/eo.json index 4a90bb8c0b..928caf9243 100644 --- a/src/i18n/strings/eo.json +++ b/src/i18n/strings/eo.json @@ -165,7 +165,6 @@ "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", "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", @@ -1030,7 +1029,6 @@ "Event sent!": "Okazo sendiĝis!", "Explore Account Data": "Esplori kontajn datumojn", "All messages (noisy)": "Ĉiuj mesaĝoj (lauta)", - "Away": "Foresta", "Saturday": "Sabato", "Remember, you can always set an email address in user settings if you change your mind.": "Memoru: vi ĉiam povas agordi retpoŝtadreson en viaj agordoj por uzantoj.", "Direct Chat": "Rekta babilo", @@ -1044,7 +1042,6 @@ "Toolbox": "Ilaro", "Collecting logs": "Kolektante protokolon", "more": "pli", - "Bug report sent": "Cimraporto sendiĝis", "You must specify an event type!": "Vi devas specifi tipon de okazo!", "(HTTP status %(httpStatus)s)": "(stato de HTTP %(httpStatus)s)", "Invite to this room": "Inviti al ĉi tiu ĉambro", @@ -1085,7 +1082,6 @@ "Login": "Saluti", "Low Priority": "Malalta prioritato", "Unable to fetch notification target list": "Malsukcesis akiri la liston de celoj por sciigoj", - "Appear Offline": "Montriĝi kiel eksterreta", "Set Password": "Agordi pasvorton", "Enable audible notifications in web client": "Ŝalti aŭdeblajn sciigojn en la retkliento", "Permalink": "Konstanta ligilo", diff --git a/src/i18n/strings/es.json b/src/i18n/strings/es.json index 36bf4b7b3b..07b38d7566 100644 --- a/src/i18n/strings/es.json +++ b/src/i18n/strings/es.json @@ -666,7 +666,6 @@ "Unnamed room": "Sala sin nombre", "Explore Account Data": "Explorar Datos de la Cuenta", "Remove from Directory": "Retirar del Directorio", - "Away": "Ausente", "Saturday": "Sábado", "Remember, you can always set an email address in user settings if you change your mind.": "Recuerda que si es necesario puedes establecer una dirección de email en las preferencias de usuario.", "Direct Chat": "Conversación directa", @@ -681,7 +680,6 @@ "Collecting logs": "Recolectando registros", "more": "más", "GitHub issue link:": "Enlace de incidencia en GitHub:", - "Bug report sent": "Informe de fallo enviado", "You must specify an event type!": "Debes especificar un tipo de evento!", "(HTTP status %(httpStatus)s)": "(estado HTTP %(httpStatus)s)", "Invite to this room": "Invitar a esta sala", @@ -722,7 +720,6 @@ "Login": "Iniciar sesión", "Low Priority": "Baja Prioridad", "Riot does not know how to join a room on this network": "Riot no sabe cómo unirse a una sala en esta red", - "Appear Offline": "Mostrarse Desconectado", "Set Password": "Establecer contraseña", "Enable audible notifications in web client": "Habilitar notificaciones audibles en el cliente web", "Permalink": "Enlace permanente", diff --git a/src/i18n/strings/eu.json b/src/i18n/strings/eu.json index 538a3c2c1c..83995ea723 100644 --- a/src/i18n/strings/eu.json +++ b/src/i18n/strings/eu.json @@ -731,7 +731,6 @@ "%(names)s and %(count)s others are typing|one": "%(names)s eta beste bat idazten ari dira", "Send": "Bidali", "Message Pinning": "Mezuak finkatzea", - "Presence Management": "Presentzia-kudeaketa", "Hide avatar changes": "Ezkutatu abatar aldaketak", "Hide display name changes": "Ezkutatu pantaila izenen aldaketak", "Disable big emoji in chat": "Desgaitu emoji handiak txatean", @@ -1073,7 +1072,6 @@ "Remember, you can always set an email address in user settings if you change your mind.": "Gogoratu, e-mail helbide bat ezarri dezakezu erabiltzaile-ezarpenetan iritzia aldatzen baduzu.", "Explore Account Data": "Miatu kantuaren datuak", "All messages (noisy)": "Mezu guztiak (ozen)", - "Away": "Teklatutik at", "Saturday": "Larunbata", "I understand the risks and wish to continue": "Arriskua ulertzen dut eta jarraitu nahi dut", "Direct Chat": "Txat zuzena", @@ -1088,7 +1086,6 @@ "Collecting logs": "Egunkariak biltzen", "more": "gehiago", "GitHub issue link:": "Arazoaren esteka GitHuben:", - "Bug report sent": "Arazte-txostena bidali da", "You must specify an event type!": "Gertaera mota bat zehaztu behar duzu!", "(HTTP status %(httpStatus)s)": "(HTTP egoera %(httpStatus)s)", "All Rooms": "Gela guztiak", @@ -1130,7 +1127,6 @@ "Login": "Hasi saioa", "Low Priority": "Lehentasun baxua", "Unable to fetch notification target list": "Ezin izan da jakinarazpen helburuen zerrenda eskuratu", - "Appear Offline": "Agertu deskonektatuta", "Set Password": "Ezarri pasahitza", "Enable audible notifications in web client": "Gaitu jakinarazpen entzungarriak web bezeroan", "Permalink": "Esteka iraunkorra", diff --git a/src/i18n/strings/fi.json b/src/i18n/strings/fi.json index 9bcf0a64e3..7f532c542c 100644 --- a/src/i18n/strings/fi.json +++ b/src/i18n/strings/fi.json @@ -165,7 +165,6 @@ "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.", "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.": "Turvallusuussyistä uloskirjautuminen poistaa kaikki päästä päähän-salausavaimet tästä selaimesta. Jos haluat purkaa keskustelujen salaukset tulevaisuudessa pitää sinun viedä purkuavaimet ja pitää ne turvallisesti tallessa.", - "Hide Apps": "Piilota sovellukset", "Hide read receipts": "Piilota lukukuittaukset", "Hide Text Formatting Toolbar": "Piilota tekstinmuotoilutyökalupalkki", "Homeserver is": "Kotipalvelin on", @@ -832,7 +831,6 @@ "%(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", "Delete %(count)s devices|other": "Poista %(count)s laitetta", "Delete %(count)s devices|one": "Poista laite", "Select devices": "Valitse laitteet", @@ -1004,7 +1002,6 @@ "Enable desktop notifications": "Ota käyttöön työpöytäilmoitukset", "Explore Account Data": "Tilitiedot", "All messages (noisy)": "Kaikki viestit (äänekkäästi)", - "Away": "Poissa", "Saturday": "Lauantai", "Remember, you can always set an email address in user settings if you change your mind.": "Muista että voit aina asettaa sähköpostiosoitteen käyttäjäasetuksista jos muutat mielesi.", "Direct Chat": "Suora viestittely", @@ -1019,7 +1016,6 @@ "Toolbox": "Työkalut", "Collecting logs": "Haetaan lokitietoja", "more": "lisää", - "Bug report sent": "Virheraportti lähetetty", "You must specify an event type!": "Sinun on määritettävä tapahtuman tyyppi!", "(HTTP status %(httpStatus)s)": "(HTTP tila %(httpStatus)s)", "All Rooms": "Kaikki huoneet", @@ -1058,7 +1054,6 @@ "Low Priority": "Matala prioriteetti", "Unable to fetch notification target list": "Ilmoituskohdelistan haku epäonnistui", "Set Password": "Aseta salasana", - "Appear Offline": "Offline-tila", "An error occurred whilst saving your email notification preferences.": "Sähköposti-ilmoitusasetuksia tallettaessa tapahtui virhe.", "Enable audible notifications in web client": "Ota käyttöön äänelliset ilmoitukset", "Permalink": "Pysyvä linkki", diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index 562e601ab1..4b01c65e1d 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -900,7 +900,6 @@ "Username on %(hs)s": "Nom d'utilisateur sur %(hs)s", "Restricted": "Restreint", "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", @@ -1078,7 +1077,6 @@ "Remember, you can always set an email address in user settings if you change your mind.": "Souvenez-vous que vous pourrez toujours définir une adresse e-mail dans les paramètres de l'utilisateur si vous changez d’avis.", "Explore Account Data": "Explorer les données du compte", "Remove from Directory": "Supprimer du répertoire", - "Away": "Absent", "Saturday": "Samedi", "I understand the risks and wish to continue": "Je comprends les risques et souhaite continuer", "Direct Chat": "Discussion directe", @@ -1092,7 +1090,6 @@ "Toolbox": "Boîte à outils", "Collecting logs": "Récupération des journaux", "more": "plus", - "Bug report sent": "Rapport d'erreur envoyé", "You must specify an event type!": "Vous devez spécifier un type d'événement !", "(HTTP status %(httpStatus)s)": "(état HTTP %(httpStatus)s)", "Invite to this room": "Inviter dans ce salon", @@ -1131,7 +1128,6 @@ "Login": "Connexion", "Low Priority": "Priorité basse", "Unable to fetch notification target list": "Impossible de récupérer la liste des appareils recevant les notifications", - "Appear Offline": "Apparaître Hors ligne", "Set Password": "Définir un mot de passe", "Enable audible notifications in web client": "Activer les notifications sonores pour le client web", "Permalink": "Permalien", diff --git a/src/i18n/strings/gl.json b/src/i18n/strings/gl.json index aca58e2e23..c2e451f814 100644 --- a/src/i18n/strings/gl.json +++ b/src/i18n/strings/gl.json @@ -169,7 +169,6 @@ "Authentication check failed: incorrect password?": "Fallou a comprobación de autenticación: contrasinal incorrecto?", "Failed to join room": "Non se puido unir a sala", "Message Pinning": "Fixando mensaxe", - "Presence Management": "Xestión da presenza", "Disable Emoji suggestions while typing": "Deshabilitar a suxestión de Emoji mentras escribe", "Use compact timeline layout": "Utilizar a disposición compacta da liña temporal", "Hide removed messages": "Ocultar mensaxes eliminadas", @@ -1073,7 +1072,6 @@ "Remember, you can always set an email address in user settings if you change your mind.": "Lembre, sempre poderá poñer un enderezo de correo nos axustes de usuario si cambia de idea.", "Explore Account Data": "Explorar datos da conta", "All messages (noisy)": "Todas as mensaxes (alto)", - "Away": "Fóra", "Saturday": "Sábado", "I understand the risks and wish to continue": "Entendos os riscos e desexo continuar", "Direct Chat": "Chat directo", @@ -1088,7 +1086,6 @@ "Collecting logs": "Obtendo rexistros", "more": "máis", "GitHub issue link:": "Ligazón ao reporte en GitHub:", - "Bug report sent": "Enviado o informe de fallo", "You must specify an event type!": "Debe indicar un tipo de evento!", "(HTTP status %(httpStatus)s)": "(Estado HTTP %(httpStatus)s)", "All Rooms": "Todas as Salas", @@ -1130,7 +1127,6 @@ "Login": "Conectar", "Low Priority": "Baixa prioridade", "Unable to fetch notification target list": "Non se puido procesar a lista de obxetivo de notificacións", - "Appear Offline": "Aparecer fora de liña", "Set Password": "Establecer contrasinal", "Enable audible notifications in web client": "Habilitar notificacións audibles no cliente web", "Permalink": "Ligazón permanente", diff --git a/src/i18n/strings/he.json b/src/i18n/strings/he.json index 9543a64b8f..7e747428a6 100644 --- a/src/i18n/strings/he.json +++ b/src/i18n/strings/he.json @@ -164,7 +164,6 @@ "Remember, you can always set an email address in user settings if you change your mind.": "להזכירך: תמיד ניתן לשנות כתובת אימייל בהגדרות משתש. למקרה שתתחרט/י.", "Explore Account Data": "גלה פרטי משתמש", "All messages (noisy)": "כל ההודעות (רועש)", - "Away": "מרוחק", "Saturday": "שבת", "I understand the risks and wish to continue": "אני מבין את הסיכונים אבל מבקש להמשיך", "Direct Chat": "שיחה ישירה", @@ -221,7 +220,6 @@ "Login": "התחבר", "Low Priority": "עדיפות נמוכה", "Unable to fetch notification target list": "לא ניתן לאחזר רשימת יעדי התראה", - "Appear Offline": "מופיע מקוון", "Set Password": "הגדר סיסמא", "Enable audible notifications in web client": "אפשר התראות קוליות בדפדפן", "Permalink": "קישור קבוע", diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 6eeafe57db..64bdbbc7c3 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -900,7 +900,6 @@ "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", "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", @@ -1081,7 +1080,6 @@ "Remember, you can always set an email address in user settings if you change your mind.": "Ha meggondolod magad, bármikor beállíthatod az e-mail címed a felhasználói beállításoknál.", "Explore Account Data": "Fiókadatok felderítése", "Remove from Directory": "Törlés a listából", - "Away": "Távol", "Saturday": "Szombat", "I understand the risks and wish to continue": "Megértettem a kockázatot és folytatom", "Direct Chat": "Közvetlen csevegés", @@ -1096,7 +1094,6 @@ "Collecting logs": "Naplók összegyűjtése", "more": "tovább", "GitHub issue link:": "GitHub hibajegy hivatkozás:", - "Bug report sent": "Hibajelentés elküldve", "You must specify an event type!": "Meg kell jelölnöd az eseménytípust!", "(HTTP status %(httpStatus)s)": "(HTTP állapot: %(httpStatus)s)", "Invite to this room": "Meghívás a szobába", @@ -1137,7 +1134,6 @@ "Login": "Bejelentkezés", "Low Priority": "Alacsony prioritás", "Unable to fetch notification target list": "Nem sikerült letölteni az értesítési célok listáját", - "Appear Offline": "Offline látszik", "Set Password": "Jelszó beállítása", "Enable audible notifications in web client": "Hangértesítések engedélyezése a webkliensben", "Permalink": "Állandó hivatkozás", diff --git a/src/i18n/strings/id.json b/src/i18n/strings/id.json index 5eccf72100..9db1a4a99c 100644 --- a/src/i18n/strings/id.json +++ b/src/i18n/strings/id.json @@ -285,7 +285,6 @@ "Messages containing my user name": "Pesan mengandung nama pengguna saya", "Collecting logs": "Mengumpulkan catatan", "more": "lagi", - "Bug report sent": "Laporan bug terkirim", "(HTTP status %(httpStatus)s)": "(status HTTP %(httpStatus)s)", "Failed to forget room %(errCode)s": "Gagal melupakan ruang %(errCode)s", "Wednesday": "Rabu", diff --git a/src/i18n/strings/it.json b/src/i18n/strings/it.json index fad64d496f..3a4691bae7 100644 --- a/src/i18n/strings/it.json +++ b/src/i18n/strings/it.json @@ -232,7 +232,6 @@ "Not a valid Riot keyfile": "Non è una chiave di Riot valida", "Authentication check failed: incorrect password?": "Controllo di autenticazione fallito: password sbagliata?", "Failed to join room": "Accesso alla stanza fallito", - "Presence Management": "Gestione della presenza", "Disable Emoji suggestions while typing": "Disattiva i suggerimenti delle emoji durante la digitazione", "Use compact timeline layout": "Usa impaginazione cronologia compatta", "Hide join/leave messages (invites/kicks/bans unaffected)": "Nascondi i messaggi di entrata/uscita (inviti/kick/ban esclusi)", @@ -1073,7 +1072,6 @@ "Remember, you can always set an email address in user settings if you change your mind.": "Ricorda, puoi sempre specificare un indirizzo email nelle impostazioni utente se cambi idea.", "Explore Account Data": "Esplora dati account", "All messages (noisy)": "Tutti i messaggi (rumoroso)", - "Away": "Assente", "Saturday": "Sabato", "I understand the risks and wish to continue": "Sono consapevole dei rischi e vorrei continuare", "Direct Chat": "Chat Diretta", @@ -1088,7 +1086,6 @@ "Collecting logs": "Sto recuperando i log", "more": "altro", "GitHub issue link:": "Link segnalazione su GitHub:", - "Bug report sent": "Rapporto inviato", "You must specify an event type!": "Devi specificare un tipo di evento!", "(HTTP status %(httpStatus)s)": "(stato HTTP %(httpStatus)s)", "All Rooms": "Tutte le stanze", @@ -1131,7 +1128,6 @@ "Login": "Entra", "Low Priority": "Priorità bassa", "What's New": "Novità", - "Appear Offline": "Appari offline", "Set Password": "Imposta Password", "Enable audible notifications in web client": "Abilita notifiche audio nel client web", "Permalink": "Link permanente", diff --git a/src/i18n/strings/ko.json b/src/i18n/strings/ko.json index 32ca09aee1..ff5ebd72d7 100644 --- a/src/i18n/strings/ko.json +++ b/src/i18n/strings/ko.json @@ -725,7 +725,6 @@ "Toolbox": "도구상자", "Collecting logs": "로그 수집 중", "more": "더 보기", - "Bug report sent": "오류 보고서를 보냈어요", "(HTTP status %(httpStatus)s)": "(HTTP 상태 %(httpStatus)s)", "All Rooms": "모든 방", "Failed to get public room list": "공개한 방 목록을 얻지 못했어요", @@ -761,7 +760,6 @@ "Error encountered (%(errorDetail)s).": "오류가 일어났어요 (%(errorDetail)s).", "Low Priority": "낮은 우선순위", "Riot does not know how to join a room on this network": "라이엇이 이 네트워크에서 방에 들어가는 법을 알 수 없어요", - "Appear Offline": "미접속으로 표시하기", "Set Password": "비밀번호 설정", "Enable audible notifications in web client": "웹 클라이언트에서 알림 소리 켜기", "Permalink": "고유주소", diff --git a/src/i18n/strings/lt.json b/src/i18n/strings/lt.json index 277b0cf427..efa5cf9d5e 100644 --- a/src/i18n/strings/lt.json +++ b/src/i18n/strings/lt.json @@ -97,12 +97,10 @@ "Remove %(name)s from the directory?": "Ar ištrinti %(name)s iš katalogo?", "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot naudoja daug išplėstinių naršyklės funkcionalumų, kai kurie iš jų yra neprieinami ar eksperimentinei Jūsų naršyklėje.", "Event sent!": "Įvykis išsiųstas!", - "Bug report sent": "Klaidos ataskaita išsiųsta", "Unnamed room": "Kambarys be pavadinimo", "Dismiss": "Nutraukti", "Explore Account Data": "Peržiūrėti paskyros duomenis", "Remove from Directory": "Šalinti iš katalogo", - "Away": "Neaktyvus", "Download this file": "Atsisiųsti šį failą", "Saturday": "Šeštadienis", "Remember, you can always set an email address in user settings if you change your mind.": "Nepamirškite, kad galite, bet kada įrašyti savo el. pašto adresą paskyros nustatymuose.", @@ -162,7 +160,6 @@ "Low Priority": "Nesvarbūs", "Riot does not know how to join a room on this network": "Riot nežino kaip prisijungti prie kambario šiame tinkle", "Set Password": "Nustatyti slaptažodį", - "Appear Offline": "Neprisijungęs", "An error occurred whilst saving your email notification preferences.": "Įrašant pranešimų el. paštu nuostatas, įvyko klaida.", "Unable to join network": "Nepavyko prisijungti prie tinklo", "Permalink": "Pastovioji nuoroda", diff --git a/src/i18n/strings/lv.json b/src/i18n/strings/lv.json index bb4225216f..35ffa35b14 100644 --- a/src/i18n/strings/lv.json +++ b/src/i18n/strings/lv.json @@ -731,7 +731,6 @@ "%(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ātesamības vadība", "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ā/redzamā vārda izmaiņas", @@ -1067,7 +1066,6 @@ "Enable desktop notifications": "Iespējot darbvirsmas paziņojumus", "Explore Account Data": "Aplūkot konta datus", "All messages (noisy)": "Visas ziņas (ar skaņu)", - "Away": "Prom (nav uz vietas)", "Saturday": "sestdiena", "Remember, you can always set an email address in user settings if you change your mind.": "Atceries, ka vienmēr vari iestatīt epasta adresi lietotāja uzstādījumos, ja pārdomā.", "Direct Chat": "Tiešais čats", @@ -1083,7 +1081,6 @@ "Collecting logs": "Tiek iegūti logfaili", "more": "vairāk", "GitHub issue link:": "GitHub problēmpaziņojuma saite:", - "Bug report sent": "Kļūdas atskaite nosūtīta", "You must specify an event type!": "Jānorāda notikuma tips!", "(HTTP status %(httpStatus)s)": "(HTTP statuss %(httpStatus)s)", "All Rooms": "visās istabās", @@ -1125,7 +1122,6 @@ "Login": "Ierakstīties", "Low Priority": "Zemas prioritātes", "Unable to fetch notification target list": "Neizdevās iegūt paziņojumu mērķu sarakstu", - "Appear Offline": "Šķiet nesaistē (oflainā)", "Set Password": "Iestatīt paroli", "Enable audible notifications in web client": "Iespējot skaņus paziņojumus web klientā", "Permalink": "Pastāvīgā saite", diff --git a/src/i18n/strings/ml.json b/src/i18n/strings/ml.json index 098c062006..6de7e92df7 100644 --- a/src/i18n/strings/ml.json +++ b/src/i18n/strings/ml.json @@ -102,7 +102,6 @@ "Messages containing my user name": "എന്റെ യൂസര്‍ നെയിം അടങ്ങിയിരിക്കുന്ന സന്ദേശങ്ങള്‍ക്ക്", "Collecting logs": "നാള്‍വഴി ശേഖരിക്കുന്നു", "more": "കൂടുതല്‍", - "Bug report sent": "ബഗ് റിപ്പോർട്ട് അയയ്ക്കുക", "(HTTP status %(httpStatus)s)": "(HTTP സ്റ്റാറ്റസ് %(httpStatus)s)", "All Rooms": "എല്ലാ മുറികളും കാണുക", "Wednesday": "ബുധന്‍", diff --git a/src/i18n/strings/nl.json b/src/i18n/strings/nl.json index d272e628f0..c41ab7899d 100644 --- a/src/i18n/strings/nl.json +++ b/src/i18n/strings/nl.json @@ -717,7 +717,6 @@ "Send": "Verstuur", "Message Pinning": "Boodschap vastpinnen", "Message Replies": "Antwoorden op bericht", - "Presence Management": "Presentie Beheer", "Disable Emoji suggestions while typing": "Emoji suggesties tijdens het typen uitzetten", "Hide avatar changes": "Avatar veranderingen verbergen", "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(day)s %(monthName)s %(fullYear)s", @@ -1059,7 +1058,6 @@ "Enable desktop notifications": "Desktopmeldingen aanzetten", "Explore Account Data": "Bekijk account informatie", "Remove from Directory": "Uit de kamerlijst verwijderen", - "Away": "Afwezig", "Saturday": "Zaterdag", "Remember, you can always set an email address in user settings if you change your mind.": "Onthoud dat u altijd een e-mailadres in kan stellen in de gebruikersinstellingen als u zich bedenkt.", "Direct Chat": "Privégesprek", @@ -1073,7 +1071,6 @@ "Toolbox": "Eigenschappen", "Collecting logs": "Logboeken verzamelen", "more": "meer", - "Bug report sent": "Bug report verzonden", "You must specify an event type!": "Je moet een event-type specificeren!", "(HTTP status %(httpStatus)s)": "(HTTP-status %(httpStatus)s)", "Invite to this room": "Uitnodigen voor deze kamer", @@ -1110,7 +1107,6 @@ "Login": "Aanmelden", "Low Priority": "Lage prioriteit", "Unable to fetch notification target list": "Het is mislukt om de lijst van notificatiedoelen op te halen", - "Appear Offline": "Lijk offline", "Set Password": "Wachtwoord instellen", "Enable audible notifications in web client": "Geluidsmeldingen in de webclient aanzetten", "Permalink": "Permanente link", diff --git a/src/i18n/strings/pl.json b/src/i18n/strings/pl.json index 042df8aebc..f39edb4972 100644 --- a/src/i18n/strings/pl.json +++ b/src/i18n/strings/pl.json @@ -777,7 +777,6 @@ "Remember, you can always set an email address in user settings if you change your mind.": "Pamiętaj, że zawsze możesz zmienić swój e-mail lub hasło w panelu ustawień użytkownika.", "Explore Account Data": "Odkryj dane konta", "All messages (noisy)": "Wszystkie wiadomości (głośno)", - "Away": "Niedostępny", "Saturday": "Sobota", "I understand the risks and wish to continue": "Rozumiem ryzyko i chcę kontynuować", "Direct Chat": "Rozmowa bezpośrednia", @@ -792,7 +791,6 @@ "Collecting logs": "Zbieranie dzienników", "more": "więcej", "GitHub issue link:": "Link do wątku na GitHubie:", - "Bug report sent": "Raport błędu wysłany", "You must specify an event type!": "Musisz określić typ wydarzenia!", "(HTTP status %(httpStatus)s)": "(status HTTP %(httpStatus)s)", "All Rooms": "Wszystkie pokoje", @@ -835,7 +833,6 @@ "Login": "Logowanie", "Low Priority": "Niski priorytet", "Unable to fetch notification target list": "Nie można pobrać listy docelowej dla powiadomień", - "Appear Offline": "Ustaw status niedostępny", "Set Password": "Ustaw hasło", "Enable audible notifications in web client": "Włącz dźwiękowe powiadomienia w kliencie internetowym", "Permalink": "Odnośnik bezpośredni", diff --git a/src/i18n/strings/pt.json b/src/i18n/strings/pt.json index d8b9d11040..12339e6757 100644 --- a/src/i18n/strings/pt.json +++ b/src/i18n/strings/pt.json @@ -817,7 +817,6 @@ "Notify for all other messages/rooms": "Notificar para todas as outras mensagens/salas", "Unable to look up room ID from server": "Não foi possível obter a identificação da sala do servidor", "Couldn't find a matching Matrix room": "Não foi possível encontrar uma sala correspondente no servidor Matrix", - "Bug report sent": "Relatório de erros enviado", "All Rooms": "Todas as salas", "You cannot delete this message. (%(code)s)": "Não pode apagar esta mensagem. (%(code)s)", "Thursday": "Quinta-feira", diff --git a/src/i18n/strings/pt_BR.json b/src/i18n/strings/pt_BR.json index eccce3d2a0..0abb10edce 100644 --- a/src/i18n/strings/pt_BR.json +++ b/src/i18n/strings/pt_BR.json @@ -695,7 +695,6 @@ "Send": "Enviar", "Message Replies": "Respostas", "Message Pinning": "Fixar mensagem", - "Presence Management": "Gestão da presença", "Disable Emoji suggestions while typing": "Desativar sugestões de emojis enquanto estiver escrevendo", "Hide join/leave messages (invites/kicks/bans unaffected)": "Ocultar mensagens de entrada e de saída (não afeta convites, expulsões e banimentos)", "Hide avatar changes": "Ocultar alterações da imagem de perfil", @@ -1060,7 +1059,6 @@ "Enable desktop notifications": "Ativar notificações no desktop", "Explore Account Data": "Explorar Dados da Conta", "Remove from Directory": "Remover da lista pública de salas", - "Away": "Ausente", "Saturday": "Sábado", "Remember, you can always set an email address in user settings if you change your mind.": "Lembre-se: você pode sempre definir um endereço de e-mail nas configurações de usuário, se mudar de ideia.", "Direct Chat": "Conversa pessoal", @@ -1074,7 +1072,6 @@ "Toolbox": "Ferramentas", "Collecting logs": "Coletando logs", "more": "ver mais", - "Bug report sent": "Relatório do bug enviado", "You must specify an event type!": "Você precisa especificar um tipo do evento!", "(HTTP status %(httpStatus)s)": "(Status HTTP %(httpStatus)s)", "Invite to this room": "Convidar para esta sala", @@ -1110,7 +1107,6 @@ "Login": "Fazer login", "Low Priority": "Baixa prioridade", "Unable to fetch notification target list": "Não foi possível obter a lista de alvos de notificação", - "Appear Offline": "Aparecer Desconectado", "Set Password": "Definir senha", "Enable audible notifications in web client": "Ativar notificações de áudio no cliente web", "Permalink": "Link permanente", diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 955920bd0a..d3a283d6d7 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -884,7 +884,6 @@ "Visibility in Room List": "Видимость в списке комнат", "Visible to everyone": "Видимый для всех", "Only visible to community members": "Только участникам сообщества", - "Presence Management": "Управление присутствием", "Hide avatar changes": "Скрыть изменения аватара", "Hide display name changes": "Скрыть изменения отображаемого имени", "Enable inline URL previews by default": "Включить просмотр URL-адресов по умолчанию", @@ -1077,7 +1076,6 @@ "Enable desktop notifications": "Включить оповещения на рабочем столе", "Explore Account Data": "Просмотр данных аккаунта", "All messages (noisy)": "Все сообщения (со звуком)", - "Away": "Нет на месте", "Saturday": "Суббота", "Remember, you can always set an email address in user settings if you change your mind.": "Помните, что вы всегда сможете задать адрес email в настройках пользователя, если передумаете.", "Direct Chat": "Прямой чат", @@ -1092,7 +1090,6 @@ "Collecting logs": "Сбор журналов", "more": "больше", "GitHub issue link:": "Ссылка на проблему в GitHub:", - "Bug report sent": "Отчет об ошибке отправлен", "You must specify an event type!": "Необходимо указать тип мероприятия!", "(HTTP status %(httpStatus)s)": "(статус HTTP %(httpStatus)s)", "Invite to this room": "Пригласить в комнату", @@ -1131,7 +1128,6 @@ "Login": "Войти", "Low Priority": "Низкий приоритет", "Unable to fetch notification target list": "Не удалось получить список целей уведомления", - "Appear Offline": "Отображать как не в сети", "Set Password": "Задать пароль", "Enable audible notifications in web client": "Включить звуковые уведомления в веб-клиенте", "Permalink": "Постоянная ссылка", diff --git a/src/i18n/strings/sk.json b/src/i18n/strings/sk.json index db08989273..5daa56e0fe 100644 --- a/src/i18n/strings/sk.json +++ b/src/i18n/strings/sk.json @@ -899,7 +899,6 @@ "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", "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", @@ -1071,7 +1070,6 @@ "Enable desktop notifications": "Povoliť oznámenia na pracovnej ploche", "Explore Account Data": "Preskúmať Údaje účtu", "All messages (noisy)": "Všetky správy (hlučné)", - "Away": "Preč", "Saturday": "Sobota", "Remember, you can always set an email address in user settings if you change your mind.": "Všimnite si, Emailovú adresu môžete pridať aj neskôr v časti nastavenia, ak zmeníte svoj názor.", "Direct Chat": "Priama konverzácia", @@ -1108,7 +1106,6 @@ "Notify for all other messages/rooms": "oznamovať všetky ostatné správy / miestnosti", "Unable to look up room ID from server": "Nie je možné vyhľadať ID miestnosti na servery", "Couldn't find a matching Matrix room": "Nie je možné nájsť zodpovedajúcu Matrix miestnosť", - "Bug report sent": "Hlásenie chyby odoslané", "Invite to this room": "Pozvať do tejto miestnosti", "You cannot delete this message. (%(code)s)": "Nemôžete vymazať túto správu. (%(code)s)", "Thursday": "Štvrtok", @@ -1129,7 +1126,6 @@ "Low Priority": "Nízka priorita", "What's New": "Čo Je Nové", "Set Password": "Nastaviť Heslo", - "Appear Offline": "Zdá sa byť nedostupný", "An error occurred whilst saving your email notification preferences.": "Počas ukladania vašich nastavení oznamovania emailom sa vyskytla chyba.", "Enable audible notifications in web client": "Povoliť zvukové oznámenia vo webovom klientovi", "Permalink": "Trvalý odkaz", diff --git a/src/i18n/strings/sq.json b/src/i18n/strings/sq.json index dc26c7c283..d36995bc5b 100644 --- a/src/i18n/strings/sq.json +++ b/src/i18n/strings/sq.json @@ -207,7 +207,6 @@ "Dismiss": "Mos e merr parasysh", "Explore Account Data": "Eksploroni të Dhëna Llogarie", "All messages (noisy)": "Tërë Mesazhet (e zhurmshme)", - "Away": "Larguar", "Saturday": "E shtunë", "Remember, you can always set an email address in user settings if you change your mind.": "Mos harroni, mundeni përherë të caktoni një adresë email te rregullimet e përdoruesit, nëse ndërroni mendje.", "Direct Chat": "Fjalosje e Drejtpërdrejtë", @@ -270,7 +269,6 @@ "Low Priority": "Përparësi e Ulët", "What's New": "Ç’ka të Re", "Set Password": "Caktoni Fjalëkalim", - "Appear Offline": "Shfaqju Si Jo Në Linjë", "An error occurred whilst saving your email notification preferences.": "Ndodhi një gabim teksa ruheshin parapëlqimet tuaja për njoftime me email.", "Enable audible notifications in web client": "Aktivizoni njoftime audio te klienti web", "Permalink": "Permalidhje", diff --git a/src/i18n/strings/sr.json b/src/i18n/strings/sr.json index c11a058adc..3ea5c9c8c9 100644 --- a/src/i18n/strings/sr.json +++ b/src/i18n/strings/sr.json @@ -172,7 +172,6 @@ "Failed to join room": "Нисам успео да уђем у собу", "Message Replies": "Одговори", "Message Pinning": "Закачене поруке", - "Presence Management": "Управљање присутношћу", "Disable Emoji suggestions while typing": "Онемогући предлагање емоџија приликом куцања", "Use compact timeline layout": "Користи збијени распоред временске линије", "Hide removed messages": "Сакриј уклоњене поруке", @@ -1056,7 +1055,6 @@ "Event sent!": "Догађај је послат!", "Explore Account Data": "Истражи податке налога", "All messages (noisy)": "Све поруке (гласно)", - "Away": "Одустан", "Saturday": "Субота", "Remember, you can always set an email address in user settings if you change your mind.": "Запамтите, увек можете поставити мејл адресу у корисничким подешавањима, уколико се предомислите.", "Direct Chat": "Директно ћаскање", @@ -1090,7 +1088,6 @@ "Notify for all other messages/rooms": "Обавести за све друге поруке и собе", "Unable to look up room ID from server": "Не могу да погледам ИБ собе на серверу", "Couldn't find a matching Matrix room": "Не могу да нађем одговарајућу Матрикс собу", - "Bug report sent": "Извештај о грешци послат", "Invite to this room": "Позови у ову собу", "You cannot delete this message. (%(code)s)": "Не можете обрисати ову поруку. (%(code)s)", "Thursday": "Четвртак", @@ -1109,7 +1106,6 @@ "Low Priority": "Најмања важност", "What's New": "Шта је ново", "Set Password": "Постави лозинку", - "Appear Offline": "Прикажи себе као ван мреже", "An error occurred whilst saving your email notification preferences.": "Догодила се грешка при чувању ваших поставки мејл обавештења.", "Enable audible notifications in web client": "Омогући звучна обавештења у веб клијенту", "Permalink": "Трајна веза", diff --git a/src/i18n/strings/sv.json b/src/i18n/strings/sv.json index cd502e5bb7..c55ee40cba 100644 --- a/src/i18n/strings/sv.json +++ b/src/i18n/strings/sv.json @@ -501,7 +501,6 @@ "Enable desktop notifications": "Sätt på skrivbordsaviseringar", "Remember, you can always set an email address in user settings if you change your mind.": "Kom ihåg att du alltid kan välja en e-postadress i dina användarinställningar om du ändrar dig.", "All messages (noisy)": "Alla meddelanden (högljudd)", - "Away": "Borta", "Saturday": "lördag", "I understand the risks and wish to continue": "Jag förstår riskerna och vill fortsätta", "Direct Chat": "Direkt-chatt", @@ -514,7 +513,6 @@ "Messages containing my user name": "Meddelanden som innehåller mitt användarnamn", "Collecting logs": "Samlar in loggar", "more": "mera", - "Bug report sent": "Buggraporten skickades", "(HTTP status %(httpStatus)s)": "(HTTP-status %(httpStatus)s)", "All Rooms": "Alla rum", "Wednesday": "onsdag", @@ -548,7 +546,6 @@ "Error encountered (%(errorDetail)s).": "Fel påträffat (%(errorDetail)s).", "Low Priority": "Låg prioritet", "Unable to fetch notification target list": "Det gick inte att hämta aviseringsmållistan", - "Appear Offline": "Visa som utloggad", "Set Password": "Välj lösenord", "Enable audible notifications in web client": "Sätt på högljudda aviseringar i webbklienten", "Permalink": "Permanent länk", diff --git a/src/i18n/strings/ta.json b/src/i18n/strings/ta.json index 202e5326f0..6aecb54bfd 100644 --- a/src/i18n/strings/ta.json +++ b/src/i18n/strings/ta.json @@ -119,7 +119,6 @@ "You cannot delete this image. (%(code)s)": "இந்த படத்தை நீங்கள் அழிக்க முடியாது. (%(code)s)", "You cannot delete this message. (%(code)s)": "இந்த செய்தியை நீங்கள் அழிக்க முடியாது. (%(code)s)", "You are not receiving desktop notifications": "திரை அறிவிப்புகளை நீங்கள் பெறவில்லை", - "Bug report sent": "வழு அறிக்கை அனுப்பப்பட்டது", "OK": "சரி", "Show message in desktop notification": "திரை அறிவிப்புகளில் செய்தியை காண்பிக்கவும்", "Sunday": "ஞாயிறு", diff --git a/src/i18n/strings/uk.json b/src/i18n/strings/uk.json index 25a70e0522..02a650ac3a 100644 --- a/src/i18n/strings/uk.json +++ b/src/i18n/strings/uk.json @@ -177,7 +177,6 @@ "Unnamed room": "Неназвана кімната", "Explore Account Data": "Продивитись данні аккаунта", "All messages (noisy)": "Усі повідомлення (гучно)", - "Away": "Нема на місці", "Saturday": "Субота", "I understand the risks and wish to continue": "Я ознайомлений з ризиками і хочу продовжити", "Direct Chat": "Прямий чат", @@ -192,7 +191,6 @@ "Toolbox": "Панель інструментів", "Collecting logs": "Збір журналів", "more": "докладніше", - "Bug report sent": "Звіт про помилки відправлений", "You must specify an event type!": "Необхідно вказати тип захода!", "(HTTP status %(httpStatus)s)": "(статус HTTP %(httpStatus)s)", "All Rooms": "Усі кімнати", @@ -233,7 +231,6 @@ "Login": "Зайти", "Low Priority": "Неважливі", "Unable to fetch notification target list": "Неможливо отримати перелік цілей сповіщення", - "Appear Offline": "Відображати як не в мережі", "Set Password": "Задати пароль", "Enable audible notifications in web client": "Увімкнути звукові сповіщення у мережевому застосунку", "Permalink": "Постійне посилання", diff --git a/src/i18n/strings/zh_Hans.json b/src/i18n/strings/zh_Hans.json index 89709bf97f..b5e4d76454 100644 --- a/src/i18n/strings/zh_Hans.json +++ b/src/i18n/strings/zh_Hans.json @@ -875,7 +875,6 @@ "Remember, you can always set an email address in user settings if you change your mind.": "请记住,如果您改变想法,您永远可以在用户设置中设置电子邮件。", "Explore Account Data": "探索账户数据", "All messages (noisy)": "全部消息(高亮)", - "Away": "离开", "Saturday": "星期六", "I understand the risks and wish to continue": "我了解这些风险并愿意继续", "Direct Chat": "私聊", @@ -890,7 +889,6 @@ "Collecting logs": "正在收集日志", "more": "更多", "GitHub issue link:": "Github issue 链接:", - "Bug report sent": "发送DEBUG报告", "You must specify an event type!": "你必须制定一个事件类型!", "(HTTP status %(httpStatus)s)": "(HTTP 状态 %(httpStatus)s)", "All Rooms": "全部聊天室", @@ -932,7 +930,6 @@ "Login": "登录", "Low Priority": "低优先级", "Unable to fetch notification target list": "无法获取通知目标列表", - "Appear Offline": "似乎离线了", "Set Password": "设置密码", "Enable audible notifications in web client": "在网页客户端启用音频通知", "Permalink": "永久链接", diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json index 9157a92331..2bfe08a2a1 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -713,7 +713,6 @@ "Send": "傳送", "Message Replies": "訊息回覆", "Message Pinning": "訊息釘選", - "Presence Management": "出席管理", "Disable Emoji suggestions while typing": "在輸入時停用繪文字建議", "Hide avatar changes": "隱藏大頭貼變更", "Hide display name changes": "隱藏顯示名稱變更", @@ -1081,7 +1080,6 @@ "Enable desktop notifications": "啟用桌面通知", "Explore Account Data": "探索帳號資料", "All messages (noisy)": "所有訊息(吵鬧)", - "Away": "離開", "Saturday": "星期六", "Remember, you can always set an email address in user settings if you change your mind.": "記住,如果您改變心意了,您永遠可以在使用者設定中設定電子郵件地址。", "Direct Chat": "私人聊天", @@ -1096,7 +1094,6 @@ "Collecting logs": "收集記錄", "more": "更多", "GitHub issue link:": "GitHub 問題回報連結:", - "Bug report sent": "已傳送臭蟲回報", "You must specify an event type!": "您必須指定事件類型!", "(HTTP status %(httpStatus)s)": "(HTTP 狀態 %(httpStatus)s)", "All Rooms": "所有的聊天室", @@ -1137,7 +1134,6 @@ "Login": "登入", "Low Priority": "低優先度", "Riot does not know how to join a room on this network": "Riot 不知道如何在此網路中加入聊天室", - "Appear Offline": "顯示為離線", "Set Password": "設定密碼", "Enable audible notifications in web client": "在網頁客戶端啟用音訊通知", "Permalink": "永久連結", From 941bb94234fbaae2c7c9aee93ac0c906839b0ada Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 20 Apr 2018 10:15:15 +0100 Subject: [PATCH 038/190] fix reply fallback blunder Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/ReplyThread.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index 6796e2bcc7..57401a03f2 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -192,22 +192,22 @@ export default class ReplyThread extends React.Component { case 'm.image': html = `
In reply to ${mxid}` + `
sent an image.
`; - body = `> <${mxid}> sent an image.\n\n${body}`; + body = `> <${mxid}> sent an image.\n\n`; break; case 'm.video': html = `
In reply to ${mxid}` + `
sent a video.
`; - body = `> <${mxid}> sent a video.\n\n${body}`; + body = `> <${mxid}> sent a video.\n\n`; break; case 'm.audio': html = `
In reply to ${mxid}` + `
sent an audio file.
`; - body = `> <${mxid}> sent an audio file.\n\n${body}`; + body = `> <${mxid}> sent an audio file.\n\n`; break; case 'm.file': html = `
In reply to ${mxid}` + `
sent a file.
`; - body = `> <${mxid}> sent a file.\n\n${body}`; + body = `> <${mxid}> sent a file.\n\n`; break; case 'm.emote': { html = `
In reply to * ` From 3ea5fc9185c9d8a54ed6c09730b6989e44103e15 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 20 Apr 2018 14:06:09 +0100 Subject: [PATCH 039/190] Fix rageshake aka. Module Variables Are Not Global Variables pt. 319 --- src/rageshake/rageshake.js | 39 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/src/rageshake/rageshake.js b/src/rageshake/rageshake.js index 11e19a709e..93a52ba1aa 100644 --- a/src/rageshake/rageshake.js +++ b/src/rageshake/rageshake.js @@ -395,9 +395,6 @@ function selectQuery(store, keyRange, resultMapper) { } -let store = null; -let logger = null; -let initPromise = null; module.exports = { /** @@ -406,11 +403,11 @@ module.exports = { * @return {Promise} Resolves when set up. */ init: function() { - if (initPromise) { - return initPromise; + if (global.mx_rage_initPromise) { + return global.mx_rage_initPromise; } - logger = new ConsoleLogger(); - logger.monkeyPatch(window.console); + global.mx_rage_logger = new ConsoleLogger(); + global.mx_rage_logger.monkeyPatch(window.console); // just *accessing* indexedDB throws an exception in firefox with // indexeddb disabled. @@ -420,19 +417,19 @@ module.exports = { } catch(e) {} if (indexedDB) { - store = new IndexedDBLogStore(indexedDB, logger); - initPromise = store.connect(); - return initPromise; + global.mx_rage_store = new IndexedDBLogStore(indexedDB, global.mx_rage_logger); + global.mx_rage_initPromise = global.mx_rage_store.connect(); + return global.mx_rage_initPromise; } - initPromise = Promise.resolve(); - return initPromise; + global.mx_rage_initPromise = Promise.resolve(); + return global.mx_rage_initPromise; }, flush: function() { - if (!store) { + if (!global.mx_rage_store) { return; } - store.flush(); + global.mx_rage_store.flush(); }, /** @@ -440,10 +437,10 @@ module.exports = { * @return Promise Resolves if cleaned logs. */ cleanup: async function() { - if (!store) { + if (!global.mx_rage_store) { return; } - await store.consume(); + await global.mx_rage_store.consume(); }, /** @@ -452,21 +449,21 @@ module.exports = { * @return {Array<{lines: string, id, string}>} list of log data */ getLogsForReport: async function() { - if (!logger) { + if (!global.mx_rage_logger) { throw new Error( "No console logger, did you forget to call init()?" ); } // If in incognito mode, store is null, but we still want bug report // sending to work going off the in-memory console logs. - if (store) { + if (global.mx_rage_store) { // flush most recent logs - await store.flush(); - return await store.consume(); + await global.mx_rage_store.flush(); + return await global.mx_rage_store.consume(); } else { return [{ - lines: logger.flush(true), + lines: global.mx_rage_logger.flush(true), id: "-", }]; } From 3b859204245ec6ec99ed8cd9f2d8ada2a0170308 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 20 Apr 2018 14:28:20 +0100 Subject: [PATCH 040/190] Use mxid as sender name on set display name As it was, " set their display name to " which is unhelpful because you never knew them as "" before. They would previously have been displayed with their matrix ID, so that's what should be here. --- src/TextForEvent.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TextForEvent.js b/src/TextForEvent.js index e60bde4094..712150af4d 100644 --- a/src/TextForEvent.js +++ b/src/TextForEvent.js @@ -58,7 +58,7 @@ function textForMemberEvent(ev) { }); } else if (!prevContent.displayname && content.displayname) { return _t('%(senderName)s set their display name to %(displayName)s.', { - senderName, + senderName: ev.getSender(), displayName: content.displayname, }); } else if (prevContent.displayname && !content.displayname) { From ffba7e0d32a63b0c8e63a91a291f2afc10085fbb Mon Sep 17 00:00:00 2001 From: Krombel Date: Fri, 20 Apr 2018 14:57:39 +0000 Subject: [PATCH 041/190] Translated using Weblate (German) Currently translated at 100.0% (1161 of 1161 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 2030b4285a..41c9353a52 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -1157,5 +1157,7 @@ "Collapse panel": "Panel einklappen", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "In deinem aktuell verwendeten Browser können Aussehen und Handhabung der Anwendung unter Umständen noch komplett fehlerhaft sein, so dass einige bzw. im Extremfall alle Funktionen nicht zur Verfügung stehen. Du kannst es trotzdem versuchen und fortfahren, bist dabei aber bezüglich aller auftretenden Probleme auf dich allein gestellt!", "Checking for an update...": "Nach Updates suchen...", - "There are advanced notifications which are not shown here": "Es existieren erweiterte Benachrichtigungen, welche hier nicht angezeigt werden" + "There are advanced notifications which are not shown here": "Es existieren erweiterte Benachrichtigungen, welche hier nicht angezeigt werden", + "Missing roomId.": "Fehlende Raum-ID.", + "Picture": "Bild" } From 144ba30e6b10f601287bea20fec0b3c2f4933ee7 Mon Sep 17 00:00:00 2001 From: Andrey Date: Fri, 20 Apr 2018 18:58:59 +0000 Subject: [PATCH 042/190] Translated using Weblate (Russian) Currently translated at 100.0% (1161 of 1161 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 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 8de9983f22..e1d2cde38c 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -1156,5 +1156,8 @@ "Collapse panel": "Свернуть панель", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "В текущем браузере внешний вид приложения может быть полностью неверным, а некоторые или все функции могут не работать. Если вы хотите попробовать в любом случае, то можете продолжить, но с теми проблемами, с которыми вы можете столкнуться вам придется разбираться самостоятельно!", "Checking for an update...": "Проверка обновлений...", - "There are advanced notifications which are not shown here": "Существуют дополнительные уведомления, которые не показаны здесь" + "There are advanced notifications which are not shown here": "Существуют дополнительные уведомления, которые не показаны здесь", + "Missing roomId.": "Отсутствует идентификатор комнаты.", + "You don't currently have any stickerpacks enabled": "У вас нет доступных стикеров", + "Picture": "Изображение" } From 99c49510744e12893f6ac61fb9a4293ae016178b Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Sat, 21 Apr 2018 02:44:20 +0000 Subject: [PATCH 043/190] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (1161 of 1161 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/zh_Hant/ --- src/i18n/strings/zh_Hant.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json index 10844783cc..458e801c9f 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -1157,5 +1157,7 @@ "Collapse panel": "摺疊面板", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "您目前的瀏覽器,其應用程式的外觀和感覺可能完全不正確,有些或全部功能可以無法使用。如果您仍想要繼續嘗試,可以繼續,但必須自行承擔後果!", "Checking for an update...": "正在檢查更新...", - "There are advanced notifications which are not shown here": "有些進階的通知並未在此顯示" + "There are advanced notifications which are not shown here": "有些進階的通知並未在此顯示", + "Missing roomId.": "缺少 roomid。", + "Picture": "圖片" } From 8ed2dadc3b6ce7bca5a8e4a7bfd2dd74744dbbdc Mon Sep 17 00:00:00 2001 From: Szimszon Date: Sat, 21 Apr 2018 06:31:59 +0000 Subject: [PATCH 044/190] Translated using Weblate (Hungarian) Currently translated at 100.0% (1161 of 1161 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 5fe1e90163..c65379496d 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -1157,5 +1157,7 @@ "Collapse panel": "Panel becsukása", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Ebben a böngészőben az alkalmazás felülete tele lehet hibával, és az is lehet, hogy egyáltalán nem működik. Ha így is ki szeretnéd próbálni, megteheted, de ha valami gondod van, nem tudunk segíteni!", "Checking for an update...": "Frissítés keresése...", - "There are advanced notifications which are not shown here": "Vannak itt nem látható, haladó értesítések" + "There are advanced notifications which are not shown here": "Vannak itt nem látható, haladó értesítések", + "Missing roomId.": "Hiányzó szoba azonosító.", + "Picture": "Kép" } From 269190266a600360bf8d175882e98e338e592ad0 Mon Sep 17 00:00:00 2001 From: Slavi Pantaleev Date: Sat, 21 Apr 2018 11:38:56 +0000 Subject: [PATCH 045/190] Translated using Weblate (Bulgarian) Currently translated at 100.0% (1161 of 1161 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 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json index 88d70777f1..7745e988aa 100644 --- a/src/i18n/strings/bg.json +++ b/src/i18n/strings/bg.json @@ -1157,5 +1157,7 @@ "Collapse panel": "Свий панела", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "С текущия Ви браузър, изглеждането и усещането на приложението може да бъде неточно, и някои или всички от функциите може да не функционират,работят......... Ако искате може да продължите така или иначе, но сте сами по отношение на евентуалните проблеми, които може да срещнете!", "Checking for an update...": "Проверяване за нова версия...", - "There are advanced notifications which are not shown here": "Съществуват разширени настройки за известия, които не са показани тук" + "There are advanced notifications which are not shown here": "Съществуват разширени настройки за известия, които не са показани тук", + "Missing roomId.": "Липсва идентификатор на стая.", + "Picture": "Изображение" } From 9d27cb0751729824aa74b462deb15aba4d65728a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Sat, 21 Apr 2018 13:09:18 +0000 Subject: [PATCH 046/190] Translated using Weblate (French) Currently translated at 99.9% (1160 of 1161 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 d9fc51ce28..cd42533b2c 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -1156,5 +1156,7 @@ "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Les rapports de débogage contiennent des données d'usage de l'application qui incluent votre nom d'utilisateur, les identifiants ou alias des salons ou groupes auxquels vous avez rendu visite ainsi que les noms des autres utilisateurs. Ils ne contiennent aucun message.", "Failed to send logs: ": "Échec lors de l'envoi des rapports : ", "Notes:": "Notes :", - "Preparing to send logs": "Préparation d'envoi des rapports" + "Preparing to send logs": "Préparation d'envoi des rapports", + "Missing roomId.": "Identifiant de salon manquant.", + "Picture": "Image" } From 03b46e766b877507cfb17230b8d27263f106fce9 Mon Sep 17 00:00:00 2001 From: Val Date: Sat, 21 Apr 2018 13:09:39 +0000 Subject: [PATCH 047/190] Translated using Weblate (French) Currently translated at 99.9% (1161 of 1161 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 cd42533b2c..9b4d2f16c5 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -1158,5 +1158,6 @@ "Notes:": "Notes :", "Preparing to send logs": "Préparation d'envoi des rapports", "Missing roomId.": "Identifiant de salon manquant.", - "Picture": "Image" + "Picture": "Image", + "Click here to create a GitHub issue.": "Cliquez ici pour créer un signalement sur GitHub." } From 301798a7f54ce90f331361556cac079bc2c46887 Mon Sep 17 00:00:00 2001 From: RainSlide Date: Fri, 20 Apr 2018 18:12:20 +0000 Subject: [PATCH 048/190] Translated using Weblate (Chinese (Simplified)) Currently translated at 97.5% (1132 of 1161 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 | 172 +++++++++++++++++----------------- 1 file changed, 88 insertions(+), 84 deletions(-) diff --git a/src/i18n/strings/zh_Hans.json b/src/i18n/strings/zh_Hans.json index fe8ef8c16f..ab299837c9 100644 --- a/src/i18n/strings/zh_Hans.json +++ b/src/i18n/strings/zh_Hans.json @@ -10,7 +10,7 @@ "Decryption error": "解密出错", "Delete": "删除", "Default": "默认", - "Device ID": "设备识别码", + "Device ID": "设备 ID", "Devices": "设备列表", "Devices will not yet be able to decrypt history from before they joined the room": "新加入聊天室的设备不能解密加入之前的聊天记录", "Direct chats": "私聊", @@ -20,8 +20,8 @@ "Don't send typing notifications": "不要发送我的打字状态", "Download %(text)s": "下载 %(text)s", "Email": "电子邮箱", - "Email address": "电子邮箱地址", - "Email, name or matrix ID": "电子邮箱,姓名或者matrix ID", + "Email address": "邮箱地址", + "Email, name or matrix ID": "邮箱地址,名称或者Matrix ID", "Emoji": "表情", "Enable encryption": "启用加密", "Encrypted messages will not be visible on clients that do not yet implement encryption": "不支持加密的客户端将看不到加密的消息", @@ -29,7 +29,7 @@ "%(senderName)s ended the call.": "%(senderName)s 结束了通话。.", "End-to-end encryption information": "端到端加密信息", "End-to-end encryption is in beta and may not be reliable": "端到端加密现为 beta 版,不一定可靠", - "Enter Code": "输入代码", + "Enter Code": "输入验证码", "Error": "错误", "Error decrypting attachment": "解密附件时出错", "Event information": "事件信息", @@ -40,7 +40,7 @@ "Failed to forget room %(errCode)s": "忘记聊天室失败,错误代码: %(errCode)s", "Failed to join room": "无法加入聊天室", "Failed to kick": "踢人失败", - "Failed to leave room": "无法离开聊天室", + "Failed to leave room": "无法退出聊天室", "Failed to load timeline position": "无法加载时间轴位置", "Failed to lookup current room": "找不到当前聊天室", "Failed to mute user": "禁言用户失败", @@ -48,7 +48,7 @@ "Failed to reject invitation": "拒绝邀请失败", "Failed to save settings": "保存设置失败", "Failed to send email": "发送邮件失败", - "Failed to send request.": "发送请求失败。", + "Failed to send request.": "请求发送失败。", "Failed to set avatar.": "设置头像失败。.", "Failed to set display name": "设置昵称失败", "Failed to set up conference call": "无法启动群组通话", @@ -129,7 +129,7 @@ "The file '%(fileName)s' exceeds this home server's size limit for uploads": "文件 '%(fileName)s' 超过了此主服务器的上传大小限制", "The file '%(fileName)s' failed to upload": "文件 '%(fileName)s' 上传失败", "Add email address": "添加邮件地址", - "Add phone number": "添加电话号码", + "Add phone number": "添加手机号码", "Advanced": "高级", "Algorithm": "算法", "Always show message timestamps": "总是显示消息时间戳", @@ -152,7 +152,7 @@ "%(targetName)s joined the room.": "%(targetName)s 已加入聊天室。", "Jump to first unread message.": "跳到第一条未读消息。", "%(senderName)s kicked %(targetName)s.": "%(senderName)s 把 %(targetName)s 踢出了聊天室。.", - "Leave room": "离开聊天室", + "Leave room": "退出聊天室", "Login as guest": "以游客的身份登录", "New password": "新密码", "Add a topic": "添加一个主题", @@ -177,10 +177,10 @@ "Anyone who knows the room's link, apart from guests": "任何知道聊天室链接的人,游客除外", "Anyone who knows the room's link, including guests": "任何知道聊天室链接的人,包括游客", "Are you sure?": "你确定吗?", - "Are you sure you want to leave the room '%(roomName)s'?": "你确定要离开聊天室 “%(roomName)s” 吗?", + "Are you sure you want to leave the room '%(roomName)s'?": "你确定要退出聊天室 “%(roomName)s” 吗?", "Are you sure you want to reject the invitation?": "你确定要拒绝邀请吗?", "Are you sure you want to upload the following files?": "你确定要上传这些文件吗?", - "Bans user with given id": "封禁指定 ID 的用户", + "Bans user with given id": "按照 ID 封禁指定的用户", "Blacklisted": "已列入黑名单", "Bulk Options": "批量操作", "Call Timeout": "通话超时", @@ -210,8 +210,8 @@ "Conference calling is in development and may not be reliable.": "视频会议功能还在开发状态,可能不稳定。", "Conference calls are not supported in encrypted rooms": "加密聊天室不支持视频会议", "Conference calls are not supported in this client": "此客户端不支持视频会议", - "%(count)s new messages|one": "%(count)s 条新消息", - "%(count)s new messages|other": "%(count)s 新消息", + "%(count)s new messages|one": "%(count)s 条未读消息", + "%(count)s new messages|other": "%(count)s 未读消息", "Create a new chat or reuse an existing one": "创建新聊天或使用已有的聊天", "Custom": "自定义", "Custom level": "自定义级别", @@ -222,7 +222,7 @@ "Device key:": "设备密钥 :", "Disable Notifications": "关闭消息通知", "Drop File Here": "把文件拖拽到这里", - "Email address (optional)": "电子邮件地址 (可选)", + "Email address (optional)": "邮箱地址 (可选)", "Enable Notifications": "启用消息通知", "Encrypted by a verified device": "由一个已验证的设备加密", "Encrypted by an unverified device": "由一个未经验证的设备加密", @@ -232,31 +232,31 @@ "Error: Problem communicating with the given homeserver.": "错误: 与指定的主服务器通信时出错。", "Export": "导出", "Failed to fetch avatar URL": "获取 Avatar URL 失败", - "Failed to upload profile picture!": "无法上传头像!", + "Failed to upload profile picture!": "头像上传失败!", "Guest access is disabled on this Home Server.": "此服务器禁用了游客访问。", "Home": "主页面", "Import": "导入", "Incoming call from %(name)s": "来自 %(name)s 的通话", "Incoming video call from %(name)s": "来自 %(name)s 的视频通话", - "Incoming voice call from %(name)s": "来自 %(name)s 的视频通话", + "Incoming voice call from %(name)s": "来自 %(name)s 的语音通话", "Incorrect username and/or password.": "用户名或密码错误。", "%(senderName)s invited %(targetName)s.": "%(senderName)s 邀请了 %(targetName)s。", "Invited": "已邀请", "Invites": "邀请", - "Invites user with given id to current room": "邀请指定 ID 的用户加入当前聊天室", - "'%(alias)s' is not a valid format for an address": "'%(alias)s' 不是一个合法的电子邮件地址格式", + "Invites user with given id to current room": "按照 ID 邀请指定用户加入当前聊天室", + "'%(alias)s' is not a valid format for an address": "'%(alias)s' 不是一个合法的邮箱地址格式", "'%(alias)s' is not a valid format for an alias": "'%(alias)s' 不是一个合法的昵称格式", "%(displayName)s is typing": "%(displayName)s 正在打字", "Sign in with": "第三方登录", "Message not sent due to unknown devices being present": "消息未发送,因为有未知的设备存在", - "Missing room_id in request": "请求中没有 room_id", + "Missing room_id in request": "请求中没有 聊天室 ID", "Missing user_id in request": "请求中没有 user_id", "Mobile phone number": "手机号码", "Mobile phone number (optional)": "手机号码 (可选)", "Moderator": "协管员", "Mute": "静音", "Name": "姓名", - "Never send encrypted messages to unverified devices from this device": "不要从此设备向未验证的设备发送消息", + "Never send encrypted messages to unverified devices from this device": "在此设备上不向未经验证的设备发送消息", "New passwords don't match": "两次输入的新密码不符", "none": "无", "not set": "未设置", @@ -274,7 +274,7 @@ "Password:": "密码:", "Passwords can't be empty": "密码不能为空", "Permissions": "权限", - "Phone": "电话", + "Phone": "手机号码", "Cancel": "取消", "Create new room": "创建新聊天室", "Custom Server Options": "自定义服务器选项", @@ -293,7 +293,7 @@ "Edit": "编辑", "Joins room with given alias": "以指定的别名加入聊天室", "Labs": "实验室", - "%(targetName)s left the room.": "%(targetName)s 离开了聊天室。", + "%(targetName)s left the room.": "%(targetName)s 退出了聊天室。", "Logged in as:": "登录为:", "Logout": "登出", "Low priority": "低优先级", @@ -365,11 +365,11 @@ "Unverify": "取消验证", "ex. @bob:example.com": "例如 @bob:example.com", "Add User": "添加用户", - "This Home Server would like to make sure you are not a robot": "这个Home Server想要确认你不是一个机器人", + "This Home Server would like to make sure you are not a robot": "此主服务器想确认你不是机器人", "Token incorrect": "令牌错误", "Default server": "默认服务器", "Custom server": "自定义服务器", - "URL Previews": "URL 预览", + "URL Previews": "链接预览", "Drop file here to upload": "把文件拖到这里以上传", "Online": "在线", "Idle": "空闲", @@ -396,7 +396,7 @@ "Enable automatic language detection for syntax highlighting": "启用自动语言检测用于语法高亮", "Failed to change power level": "修改特权级别失败", "Kick": "踢出", - "Kicks user with given id": "踢出指定 ID 的用户", + "Kicks user with given id": "按照 ID 移除特定的用户", "Last seen": "上次看见", "Level:": "级别:", "Local addresses for this room:": "这个聊天室的本地地址:", @@ -416,9 +416,9 @@ "Sets the room topic": "设置聊天室主题", "Show Text Formatting Toolbar": "显示文字格式工具栏", "This room has no local addresses": "这个聊天室没有本地地址", - "This doesn't appear to be a valid email address": "这看起来不是一个合法的电子邮件地址", + "This doesn't appear to be a valid email address": "这看起来不是一个合法的邮箱地址", "This is a preview of this room. Room interactions have been disabled": "这是这个聊天室的一个预览。聊天室交互已禁用", - "This phone number is already in use": "此电话号码已被使用", + "This phone number is already in use": "此手机号码已被使用", "This room": "这个聊天室", "This room is not accessible by remote Matrix servers": "这个聊天室无法被远程 Matrix 服务器访问", "This room's internal ID is": "这个聊天室的内部 ID 是", @@ -433,7 +433,7 @@ "Unencrypted room": "未加密的聊天室", "unencrypted": "未加密的", "Unencrypted message": "未加密的消息", - "unknown caller": "未知的呼叫者", + "unknown caller": "未知呼叫者", "unknown device": "未知设备", "Unnamed Room": "未命名的聊天室", "Unverified": "未验证", @@ -452,7 +452,7 @@ "Not a valid Riot keyfile": "不是一个合法的 Riot 密钥文件", "%(targetName)s accepted an invitation.": "%(targetName)s 接受了一个邀请。", "Do you want to load widget from URL:": "你想从此 URL 加载小组件吗:", - "Hide join/leave messages (invites/kicks/bans unaffected)": "隐藏加入/离开消息(邀请/踢出/封禁不受影响)", + "Hide join/leave messages (invites/kicks/bans unaffected)": "隐藏加入/退出消息(邀请/踢出/封禁不受影响)", "Integrations Error": "集成错误", "Publish this room to the public in %(domain)s's room directory?": "把这个聊天室发布到 %(domain)s 的聊天室目录吗?", "Manage Integrations": "管理集成", @@ -464,12 +464,12 @@ "%(senderName)s requested a VoIP conference.": "%(senderName)s 请求一个 VoIP 会议。", "Seen by %(userName)s at %(dateTime)s": "在 %(dateTime)s 被 %(userName)s 看到", "Tagged as: ": "标记为: ", - "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "验证码将发送到+%(msisdn)s,请输入接收到的验证码", + "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "验证码将发送至 +%(msisdn)s,请输入收到的验证码", "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s 接受了 %(displayName)s 的邀请。", - "Active call (%(roomName)s)": "%(roomName)s 的呼叫", + "Active call (%(roomName)s)": "当前通话 (来自聊天室 %(roomName)s)", "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s 将级别调整到%(powerLevelDiffText)s 。", "Changes colour scheme of current room": "修改了样式", - "Deops user with given id": "Deops user", + "Deops user with given id": "按照 ID 取消特定用户的管理员权限", "Join as voice or video.": "通过 语言 或者 视频加入.", "%(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 设定历史浏览功能为 所有聊天室成员,从他们加入开始.", @@ -486,16 +486,16 @@ "%(roomName)s is not accessible at this time.": "%(roomName)s 此时无法访问。", "Start authentication": "开始认证", "The maximum permitted number of widgets have already been added to this room.": "小部件的最大允许数量已经添加到这个聊天室了。", - "The phone number entered looks invalid": "输入的电话号码看起来无效", + "The phone number entered looks invalid": "输入的手机号码看起来无效", "The remote side failed to pick up": "远端未能接收到", - "This Home Server does not support login using email address.": "HS不支持使用电子邮件地址登陆。", - "This invitation was sent to an email address which is not associated with this account:": "此邀请被发送到与此帐户不相关的电子邮件地址:", + "This Home Server does not support login using email address.": "HS不支持使用邮箱地址登陆。", + "This invitation was sent to an email address which is not associated with this account:": "此邀请被发送到与此帐户不相关的邮箱地址:", "This room is not recognised.": "无法识别此聊天室。", "To get started, please pick a username!": "请点击用户名!", - "Unable to add email address": "无法添加电子邮件地址", + "Unable to add email address": "无法添加邮箱地址", "Automatically replace plain text Emoji": "文字、表情自动转换", - "To reset your password, enter the email address linked to your account": "要重置你的密码,请输入关联你的帐号的电子邮箱地址", - "Unable to verify email address.": "无法验证电子邮箱地址。", + "To reset your password, enter the email address linked to your account": "要重置你的密码,请输入关联你的帐号的邮箱地址", + "Unable to verify email address.": "无法验证邮箱地址。", "Unknown room %(roomId)s": "未知聊天室 %(roomId)s", "Unknown (user, device) pair:": "未知(用户,设备)对:", "Unrecognised command:": "无法识别的命令:", @@ -515,18 +515,18 @@ "You cannot place VoIP calls in this browser.": "你不能在这个浏览器中发起 VoIP 通话。", "You do not have permission to post to this room": "你没有发送到这个聊天室的权限", "You have been invited to join this room by %(inviterName)s": "你已经被 %(inviterName)s 邀请加入这个聊天室", - "You seem to be in a call, are you sure you want to quit?": "你好像在一个通话中,你确定要退出吗?", - "You seem to be uploading files, are you sure you want to quit?": "你好像正在上传文件,你确定要退出吗?", + "You seem to be in a call, are you sure you want to quit?": "您似乎正在进行通话,确定要退出吗?", + "You seem to be uploading files, are you sure you want to quit?": "您似乎正在上传文件,确定要退出吗?", "You should not yet trust it to secure data": "你不应该相信它来保护你的数据", "Upload an avatar:": "上传一个头像:", - "This doesn't look like a valid email address.": "这看起来不是一个合法的电子邮件地址。", - "This doesn't look like a valid phone number.": "这看起来不是一个合法的电话号码。", + "This doesn't look like a valid email address.": "这看起来不是一个合法的邮箱地址。", + "This doesn't look like a valid phone number.": "这看起来不是一个合法的手机号码。", "User names may only contain letters, numbers, dots, hyphens and underscores.": "用户名只可以包含字母、数字、点、连字号和下划线。", "An unknown error occurred.": "一个未知错误出现了。", "An error occurred: %(error_string)s": "一个错误出现了: %(error_string)s", "Encrypt room": "加密聊天室", "There are no visible files in this room": "这个聊天室里面没有可见的文件", - "Active call": "活跃的通话", + "Active call": "当前通话", "Verify...": "验证...", "Error decrypting audio": "解密音频时出错", "Error decrypting image": "解密图像时出错", @@ -537,7 +537,7 @@ "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s 移除了聊天室头像。", "Something went wrong!": "出了点问题!", "If you already have a Matrix account you can log in instead.": "如果你已经有一个 Matrix 帐号,你可以登录。", - "Do you want to set an email address?": "你要设置一个电子邮箱地址吗?", + "Do you want to set an email address?": "你要设置一个邮箱地址吗?", "New address (e.g. #foo:%(localDomain)s)": "新的地址(例如 #foo:%(localDomain)s)", "Upload new:": "上传新的:", "User ID": "用户 ID", @@ -552,11 +552,11 @@ "You cannot place a call with yourself.": "你不能和你自己发起一个通话。", "You have been kicked from %(roomName)s by %(userName)s.": "你已经被 %(userName)s 踢出了 %(roomName)s.", "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": "你已经登出了所有的设备并不再接收推送通知。要重新启用通知,请再在每个设备上登录", - "You have disabled URL previews by default.": "你已经默认 禁用 URL 预览。", - "You have enabled URL previews by default.": "你已经默认 启用 URL 预览。", + "You have disabled URL previews by default.": "你已经默认 禁用 链接预览。", + "You have enabled URL previews by default.": "你已经默认 启用 链接预览。", "Your home server does not support device management.": "你的 home server 不支持设备管理。", "Set a display name:": "设置一个昵称:", - "This server does not support authentication with a phone number.": "这个服务器不支持用电话号码认证。", + "This server does not support authentication with a phone number.": "这个服务器不支持用手机号码认证。", "Password too short (min %(MIN_PASSWORD_LENGTH)s).": "密码过短(最短为 %(MIN_PASSWORD_LENGTH)s)。", "Make this room private": "使这个聊天室私密", "Share message history with new users": "和新用户共享消息历史", @@ -593,7 +593,7 @@ "You must join the room to see its files": "你必须加入聊天室以看到它的文件", "Failed to invite the following users to the %(roomName)s room:": "邀请以下用户到 %(roomName)s 聊天室失败:", "Confirm Removal": "确认移除", - "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "这会让你的账户永远不可用。你无法重新注册同一个用户 ID.", + "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "这将会导致您的账户永远无法使用。你将无法重新注册同样的用户 ID。", "Verifies a user, device, and pubkey tuple": "验证一个用户、设备和密钥元组", "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.": "我们在尝试恢复你之前的会话时遇到了一个错误。如果你继续,你将需要重新登录,加密的聊天历史将会不可读。", "Unknown devices": "未知设备", @@ -609,9 +609,9 @@ "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.": "你可以使用自定义的服务器选项来通过指定一个不同的主服务器 URL 来登录其他 Matrix 服务器。", "This allows you to use this app with an existing Matrix account on a different home server.": "这允许你用一个已有在不同主服务器的 Matrix 账户使用这个应用。", "Please check your email to continue registration.": "请查看你的电子邮件以继续注册。", - "If you don't specify an email address, you won't be able to reset your password. Are you sure?": "如果你不指定一个电子邮箱地址,你将不能重置你的密码。你确定吗?", + "If you don't specify an email address, you won't be able to reset your password. Are you sure?": "如果你不指定一个邮箱地址,你将不能重置你的密码。你确定吗?", "Home server URL": "主服务器 URL", - "Identity server URL": "身份服务器 URL", + "Identity server URL": "身份认证服务器 URL", "What does this mean?": "这是什么意思?", "Image '%(Body)s' cannot be displayed.": "图像 '%(Body)s' 无法显示。", "This image cannot be displayed.": "图像无法显示。", @@ -625,7 +625,7 @@ "This will allow you to reset your password and receive notifications.": "这将允许你重置你的密码和接收通知。", "Share without verifying": "不验证就分享", "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' 正在请求加密密钥。", + "Your unverified device '%(displayName)s' is requesting encryption keys.": "你的未经验证的设备 '%(displayName)s' 正在请求加密密钥。", "Encryption key request": "加密密钥请求", "Autocomplete Delay (ms):": "自动补全延迟(毫秒):", "%(widgetName)s widget added by %(senderName)s": "%(widgetName)s 小组建被 %(senderName)s 添加", @@ -659,9 +659,9 @@ "Hide avatar changes": "隐藏头像修改", "Hide display name changes": "隐藏昵称的修改", "Disable big emoji in chat": "禁用聊天中的大Emoji", - "Never send encrypted messages to unverified devices in this room from this device": "在这个聊天室永不从这个设备发送加密消息到未验证的设备", - "Enable URL previews for this room (only affects you)": "在这个聊天室启用 URL 预览(只影响你)", - "Enable URL previews by default for participants in this room": "对这个聊天室的参与者默认启用 URL 预览", + "Never send encrypted messages to unverified devices in this room from this device": "在此设备上,在此聊天室中不向未经验证的设备发送加密的消息", + "Enable URL previews for this room (only affects you)": "在此聊天室启用链接预览(只影响你)", + "Enable URL previews by default for participants in this room": "对这个聊天室的参与者默认启用 链接预览", "Delete %(count)s devices|other": "删除了 %(count)s 个设备", "Delete %(count)s devices|one": "删除设备", "Select devices": "选择设备", @@ -706,10 +706,10 @@ "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 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 次", @@ -718,10 +718,10 @@ "%(items)s and %(count)s others|one": "%(items)s 和另一个人", "collapse": "折叠", "expand": "展开", - "email address": "电子邮箱地址", + "email address": "邮箱地址", "You have entered an invalid address.": "你输入了一个无效地址。", "Advanced options": "高级选项", - "Leave": "离开", + "Leave": "退出", "Description": "描述", "Warning": "警告", "Light theme": "浅色主题", @@ -745,7 +745,7 @@ "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s,%(monthName)s %(day)s %(fullYear)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": "警告:您添加的用户对一切知道这个社区的 ID 的人公开", + "Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "警告:您添加的一切用户都将会对一切知道此社区的 ID 的人公开", "Name or matrix ID": "名称或 Matrix ID", "Which rooms would you like to add to this community?": "您想把哪个聊天室添加到这个社区中?", "Add rooms to the community": "添加聊天室到社区", @@ -753,7 +753,7 @@ "Failed to invite users to community": "邀请用户到社区失败", "Message Replies": "消息回复", "Disable Peer-to-Peer for 1:1 calls": "在1:1通话中禁用点到点", - "Enable inline URL previews by default": "默认启用自动网址预览", + "Enable inline URL previews by default": "默认启用网址预览", "Disinvite this user?": "取消邀请这个用户?", "Kick this user?": "踢出这个用户?", "Unban this user?": "解除这个用户的封禁?", @@ -790,7 +790,7 @@ "Add a User": "添加一个用户", "Unable to accept invite": "无法接受邀请", "Unable to reject invite": "无法拒绝邀请", - "Leave Community": "离开社区", + "Leave Community": "退出社区", "Community Settings": "社区设置", "Community %(groupId)s not found": "找不到社区 %(groupId)s", "Your Communities": "你的社区", @@ -802,13 +802,13 @@ "Failed to invite users to %(groupId)s": "邀请用户到 %(groupId)s 失败", "Failed to invite the following users to %(groupId)s:": "邀请下列用户到 %(groupId)s 失败:", "Failed to add the following rooms to %(groupId)s:": "添加以下聊天室到 %(groupId)s 失败:", - "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "你似乎没有将此邮箱地址同在此主服务器上的任何一个 Matrix 账号相关联。", + "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "你似乎没有将此邮箱地址同在此主服务器上的任何一个 Matrix 账号绑定。", "Restricted": "受限用户", "To use it, just wait for autocomplete results to load and tab through them.": "若要使用自动补全,只要等待自动补全结果加载完成,按 Tab 键切换即可。", "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s 将他们的昵称修改成了 %(displayName)s 。", "Hide avatars in user and room mentions": "隐藏头像", "Disable Community Filter Panel": "停用社区面板", - "Opt out of analytics": "禁用开发数据上传", + "Opt out of analytics": "退出统计分析服务", "Stickerpack": "贴图集", "Sticker Messages": "贴图消息", "You don't currently have any stickerpacks enabled": "您目前没有启用任何贴纸包", @@ -849,13 +849,13 @@ "%(serverName)s Matrix ID": "%(serverName)s Matrix ID", "You are registering with %(SelectedTeamName)s": "你将注册为 %(SelectedTeamName)s", "Remove from community": "从社区中移除", - "Disinvite this user from community?": "是否要取消邀请此用户加入社区?", + "Disinvite this user from community?": "是否不再邀请此用户加入本社区?", "Remove this user from community?": "是否要从社区中移除此用户?", "Failed to withdraw invitation": "撤回邀请失败", "Failed to remove user from community": "移除用户失败", "Filter community members": "过滤社区成员", "Flair will not appear": "将不会显示 Flair", - "Are you sure you want to remove '%(roomName)s' from %(groupId)s?": "你确定要从 %(groupId)s 中删除1吗?", + "Are you sure you want to remove '%(roomName)s' from %(groupId)s?": "你确定要从 %(groupId)s 中移除 %(roomName)s 吗?", "Removing a room from the community will also remove it from the community page.": "从社区中移除房间时,同时也会将其从社区页面中移除。", "Failed to remove room from community": "从社区中移除聊天室失败", "Failed to remove '%(roomName)s' from %(groupId)s": "从 %(groupId)s 中移除 “%(roomName)s” 失败", @@ -868,18 +868,18 @@ "%(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)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|one": "%(severalUsers)s 拒绝了他们的邀请", "%(severalUsers)srejected their invitations %(count)s times|other": "%(severalUsers)s 拒绝了他们的邀请共 %(count)s 次", "%(oneUser)srejected their invitation %(count)s times|other": "%(oneUser)s 拒绝了他们的邀请共 %(count)s 次", @@ -893,7 +893,7 @@ "Community IDs cannot not be empty.": "社区 ID 不能为空。", "Community IDs may only contain characters a-z, 0-9, or '=_-./'": "社区 ID 只能包含 a-z、0-9 或 “=_-./” 等字符", "Something went wrong whilst creating your community": "创建社区时出现问题", - "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "您目前默认将未验证的设备列入黑名单;在发送消息到这些设备上之前,您必须先验证它们。", + "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "您目前默认将未经验证的设备列入黑名单;在发送消息到这些设备上之前,您必须先验证它们。", "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.": "如果您之前使用过较新版本的 Riot,则您的会话可能与当前版本不兼容。请关闭此窗口并使用最新版本。", "To change the room's avatar, you must be a": "无法修改此聊天室的头像,因为您不是此聊天室的", "To change the room's name, you must be a": "无法修改此聊天室的名称,因为您不是此聊天室的", @@ -906,7 +906,7 @@ "URL previews are enabled by default for participants in this room.": "此聊天室默认启用链接预览。", "URL previews are disabled by default for participants in this room.": "此聊天室默认禁用链接预览。", "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s 将聊天室的头像更改为 ", - "You can also set a custom identity server but this will typically prevent interaction with users based on email address.": "您也可以自定义身份验证服务器,但这通常会阻止基于电子邮件地址的与用户的交互。", + "You can also set a custom identity server but this will typically prevent interaction with users based on email address.": "您也可以自定义身份认证服务器,但这通常会阻止基于邮箱地址的与用户的交互。", "Please enter the code it contains:": "请输入它包含的代码:", "Flair will appear if enabled in room settings": "如果在聊天室设置中启用, flair 将会显示", "Matrix ID": "Matrix ID", @@ -956,7 +956,7 @@ "Please note you are logging into the %(hs)s server, not matrix.org.": "请注意,您正在登录的服务器是 %(hs)s,不是 matrix.org。", "This homeserver doesn't offer any login flows which are supported by this client.": "此主服务器不兼容本客户端支持的任何登录方式。", "Sign in to get started": "登录以开始使用", - "Unbans user with given id": "使用 ID 解封特定的用户", + "Unbans user with given id": "按照 ID 解封特定的用户", "Opens the Developer Tools dialog": "打开开发者工具窗口", "Notify the whole room": "通知聊天室全体成员", "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.": "此操作允许您将加密聊天室中收到的消息的密钥导出为本地文件。您可以将文件导入其他 Matrix 客户端,以便让别的客户端在未收到密钥的情况下解密这些消息。", @@ -990,7 +990,7 @@ "Friday": "星期五", "Update": "更新", "What's New": "新鲜事", - "Add an email address above to configure email notifications": "请在上方输入电子邮件地址以接收邮件通知", + "Add an email address above to configure email notifications": "请在上方输入邮箱地址以接收邮件通知", "Expand panel": "展开面板", "On": "打开", "%(count)s Members|other": "%(count)s 位成员", @@ -1044,7 +1044,7 @@ "Tuesday": "星期二", "Enter keywords separated by a comma:": "输入以逗号间隔的关键字:", "Forward Message": "转发消息", - "You have successfully set a password and an email address!": "您已经成功设置了密码和电子邮件地址!", + "You have successfully set a password and an email address!": "您已经成功设置了密码和邮箱地址!", "Remove %(name)s from the directory?": "从目录中移除 %(name)s 吗?", "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot 使用了许多先进的浏览器功能,有些在你目前所用的浏览器上无法使用或仅为实验性的功能。", "Developer Tools": "开发者工具", @@ -1129,5 +1129,9 @@ "Collapse panel": "折叠面板", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "您目前的浏览器,应用程序的外观和感觉完全不正确,有些或全部功能可能无法使用。如果您仍想继续尝试,可以继续,但请自行负担其后果!", "Checking for an update...": "正在检查更新…", - "There are advanced notifications which are not shown here": "更多的通知并没有在此显示出来" + "There are advanced notifications which are not shown here": "更多的通知并没有在此显示出来", + "There's no one else here! Would you like to invite others or stop warning about the empty room?": "这里没有其他人了!你是想 邀请用户 还是 不再提示?", + "You need to be able to invite users to do that.": "你需要有邀请用户的权限才能进行此操作。", + "Missing roomId.": "找不到此聊天室 ID 所对应的聊天室。", + "Tag Panel": "标签面板" } From 3d58474295568f43c1dc38140a9dd0856ebdefe9 Mon Sep 17 00:00:00 2001 From: Szimszon Date: Sat, 21 Apr 2018 06:40:36 +0000 Subject: [PATCH 049/190] Translated using Weblate (Hungarian) Currently translated at 100.0% (1161 of 1161 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 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index c65379496d..792fa2735f 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -362,7 +362,7 @@ "This email address was not found": "Az e-mail cím nem található", "The email address linked to your account must be entered.": "A fiókodhoz kötött e-mail címet add meg.", "Press to start a chat with someone": "Nyomd meg a gombot ha szeretnél csevegni valakivel", - "Privacy warning": "Magánéleti figyelmeztetés", + "Privacy warning": "Titoktartási figyelmeztetés", "The file '%(fileName)s' exceeds this home server's size limit for uploads": "'%(fileName)s' fájl túllépte a Saját szerverben beállított feltöltési méret határt", "The file '%(fileName)s' failed to upload": "'%(fileName)s' fájl feltöltése sikertelen", "The remote side failed to pick up": "A hívott fél nem vette fel", From d42fa9d17a3db14bcc78291a216c20c95fe696e5 Mon Sep 17 00:00:00 2001 From: Eric Newport Date: Sun, 22 Apr 2018 22:30:37 -0400 Subject: [PATCH 050/190] Hide inline encryption icons except when hovering over a message Closes https://github.com/vector-im/riot-web/issues/2882 This is a redo of https://github.com/matrix-org/matrix-react-sdk/pull/1707 (see associated discussion there and here: https://github.com/vector-im/riot-web/pull/5988) I tried several times to resolve the conflicts correctly, but could not. Thus, fresh PR. --- res/css/views/rooms/_EventTile.scss | 10 ++++++++++ src/components/structures/UserSettings.js | 1 + src/components/views/rooms/EventTile.js | 6 +++++- src/i18n/strings/en_EN.json | 1 + src/settings/Settings.js | 5 +++++ 5 files changed, 22 insertions(+), 1 deletion(-) diff --git a/res/css/views/rooms/_EventTile.scss b/res/css/views/rooms/_EventTile.scss index 4bb81a2e53..3aa1622e05 100644 --- a/res/css/views/rooms/_EventTile.scss +++ b/res/css/views/rooms/_EventTile.scss @@ -298,6 +298,16 @@ limitations under the License. cursor: pointer; } +.mx_EventTile_e2eIcon[hidden] { + display: none; +} + +/* always override hidden attribute for blocked and warning */ +.mx_EventTile_e2eIcon[hidden][src="img/e2e-blocked.svg"], +.mx_EventTile_e2eIcon[hidden][src="img/e2e-warning.svg"] { + display: block; +} + .mx_EventTile_keyRequestInfo { font-size: 12px; } diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index 85223c4eef..d0a7275da2 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -63,6 +63,7 @@ const gHVersionLabel = function(repo, token='') { const SIMPLE_SETTINGS = [ { id: "urlPreviewsEnabled" }, { id: "autoplayGifsAndVideos" }, + { id: "alwaysShowEncryptionIcons" }, { id: "hideReadReceipts" }, { id: "dontSendTypingNotifications" }, { id: "alwaysShowTimestamps" }, diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index ed7851bf2d..565c8b5977 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -742,7 +742,11 @@ function E2ePadlockUnencrypted(props) { } function E2ePadlock(props) { - return ; + if (SettingsStore.getValue("alwaysShowEncryptionIcons")) { + return ; + } else { + return ; + } } module.exports.getHandlerTile = getHandlerTile; diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index d90b120bad..33acb04f31 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -198,6 +198,7 @@ "Show timestamps in 12 hour format (e.g. 2:30pm)": "Show timestamps in 12 hour format (e.g. 2:30pm)", "Always show message timestamps": "Always show message timestamps", "Autoplay GIFs and videos": "Autoplay GIFs and videos", + "Always show encryption icons": "Always show encryption icons", "Enable automatic language detection for syntax highlighting": "Enable automatic language detection for syntax highlighting", "Hide avatars in user and room mentions": "Hide avatars in user and room mentions", "Disable big emoji in chat": "Disable big emoji in chat", diff --git a/src/settings/Settings.js b/src/settings/Settings.js index 8e94be3be1..d214d5417f 100644 --- a/src/settings/Settings.js +++ b/src/settings/Settings.js @@ -150,6 +150,11 @@ export const SETTINGS = { displayName: _td('Autoplay GIFs and videos'), default: false, }, + "alwaysShowEncryptionIcons": { + supportedLevels: LEVELS_ACCOUNT_SETTINGS, + displayName: _td('Always show encryption icons'), + default: true, + }, "enableSyntaxHighlightLanguageDetection": { supportedLevels: LEVELS_ACCOUNT_SETTINGS, displayName: _td('Enable automatic language detection for syntax highlighting'), From c32fc677b2615f43eeb4a6c4afdd43e59c826173 Mon Sep 17 00:00:00 2001 From: Osoitz Date: Mon, 23 Apr 2018 04:18:28 +0000 Subject: [PATCH 051/190] Translated using Weblate (Basque) Currently translated at 100.0% (1161 of 1161 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 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/eu.json b/src/i18n/strings/eu.json index 853a2de6c0..d0d035f40b 100644 --- a/src/i18n/strings/eu.json +++ b/src/i18n/strings/eu.json @@ -1157,5 +1157,7 @@ "Collapse panel": "Tolestu panela", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Zure oraingo nabigatzailearekin aplikazioaren itxura eta portaera guztiz okerra izan daiteke, eta funtzio batzuk ez dira ibiliko. Hala ere aurrera jarraitu dezakezu saiatu nahi baduzu, baina zure erantzukizunaren menpe geratzen dira aurkitu ditzakezun arazoak!", "Checking for an update...": "Eguneraketarik dagoen egiaztatzen...", - "There are advanced notifications which are not shown here": "Hemen erakusten ez diren jakinarazpen aurreratuak daude" + "There are advanced notifications which are not shown here": "Hemen erakusten ez diren jakinarazpen aurreratuak daude", + "Missing roomId.": "Gelaren ID-a falta da.", + "Picture": "Irudia" } From 057815ac9ff807acffd976fa3d4087c944d110f2 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 23 Apr 2018 10:30:14 +0100 Subject: [PATCH 052/190] Reset accidental merge changes Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/i18n/strings/cs.json | 160 ++-------------------------- src/i18n/strings/de_DE.json | 173 ++---------------------------- src/i18n/strings/fr.json | 172 +++--------------------------- src/i18n/strings/hu.json | 179 ++++--------------------------- src/i18n/strings/nl.json | 184 ++------------------------------ src/i18n/strings/ru.json | 175 +++--------------------------- src/i18n/strings/sk.json | 206 +++++------------------------------- src/i18n/strings/sr.json | 158 ++------------------------- 8 files changed, 116 insertions(+), 1291 deletions(-) diff --git a/src/i18n/strings/cs.json b/src/i18n/strings/cs.json index 11dd85ba50..4267954d4c 100644 --- a/src/i18n/strings/cs.json +++ b/src/i18n/strings/cs.json @@ -90,6 +90,7 @@ "Are you sure you want to upload the following files?": "Určitě chcete nahrát následující soubory?", "Attachment": "Příloha", "Autoplay GIFs and videos": "Automaticky přehrávat GIFy a videa", + "Bug Report": "Hlášení o chybě", "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.": "Nelze se připojit k domovskému serveru – zkontrolujte prosím své připojení, prověřte, zdali je SSL certifikát vašeho domovského serveru důvěryhodný, a že některé z rozšíření prohlížeče neblokuje komunikaci.", "Anyone who knows the room's link, apart from guests": "Kdokoliv, kdo má odkaz na místnost, kromě hostů", "Anyone who knows the room's link, including guests": "Kdokoliv, kdo má odkaz na místnost, a to i hosté", @@ -206,6 +207,7 @@ "%(senderName)s answered the call.": "%(senderName)s přijal/a hovor.", "Click to mute audio": "Kliknutím ztlumíte zvuk", "Failed to verify email address: make sure you clicked the link in the email": "E-mailovou adresu se nepodařilo ověřit. Přesvědčte se, že jste kliknul/a na zaslaný odkaz", + "Found a bug?": "Našli jste chybu?", "Guest access is disabled on this Home Server.": "Na tomto domovském serveru je hostům vstup odepřen.", "Guests cannot join this room even if explicitly invited.": "Hosté nemohou vstoupit do této místnosti, i když jsou přímo pozváni.", "Hide read receipts": "Skrýt potvrzení o přečtení", @@ -276,6 +278,7 @@ "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Tuto změnu nepůjde vrátit zpět, protože tomuto uživateli nastavujete stejnou úroveň moci, jakou máte vy.", "Alias (optional)": "Alias (nepovinný)", "Room name (optional)": "Název místnosti (nepovinný)", + "Report it": "Nahlásit to", "Results from DuckDuckGo": "Výsledky z DuckDuckGo", "Return to login screen": "Vrátit k přihlašovací obrazovce", "Riot does not have permission to send you notifications - please check your browser settings": "Riot není oprávněn posílat vám upozornění – zkontrolujte prosím nastavení svého prohlížeče", @@ -303,6 +306,7 @@ "%(senderName)s set a profile picture.": "%(senderName)s si nastavil/a profilový obrázek.", "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s si změnil/a zobrazované jméno na %(displayName)s.", "Sets the room topic": "Nastavuje téma místnosti", + "Show Apps": "Zobrazit aplikace", "Show panel": "Zobrazit panel", "Show timestamps in 12 hour format (e.g. 2:30pm)": "Zobrazovat časové značky v 12hodinovém formátu (např. 2:30 odp.)", "Sign in": "Přihlásit", @@ -526,6 +530,7 @@ "Make Moderator": "Udělit moderátorství", "and %(count)s others...|one": "a někdo další...", "Hangup": "Zavěsit", + "Hide Apps": "Skrýt aplikace", "Show Text Formatting Toolbar": "Zobrazit nástroje formátování textu", "Hide Text Formatting Toolbar": "Skrýt nástroje formátování textu", "Jump to message": "Přeskočit na zprávu", @@ -555,6 +560,7 @@ "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", "Hide join/leave messages (invites/kicks/bans unaffected)": "Skrýt zprávy o vstupu či odejití (pozvánky, vykopnutí a vykázání zůstanou)", "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", @@ -643,6 +649,7 @@ "%(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", @@ -927,6 +934,7 @@ "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.", + "Tag Panel": "Připnout panel", "Call Failed": "Hovor selhal", "There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "V této místnosti jsou neznámá zařízení: Pokud budete pokračovat bez jejich ověření, někdo může Váš hovor odposlouchávat.", "Review Devices": "Ověřit zařízení", @@ -940,155 +948,5 @@ "expand": "rozbalit", "Old cryptography data detected": "Nalezeny starší šifrované datové zprávy", "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.": "Nalezeny datové zprávy ze starší verze Riot. Důsledkem bude, že E2E šifrování nebude ve starší verzi Riot správně fungovat. Šifrované zprávy ze starší verze nemusí být čitelné v nové verzi. Může dojít i k selhání zasílaní zpráv s touto verzí Riot. Pokud zaznamenáte některý z uvedených problému, odhlaste se a přihlaste znovu. Pro zachování historie zpráv exportujte a znovu importujte vaše klíče.", - "Warning": "Upozornění", - "Fetching third party location failed": "Nepodařilo se zjistit umístění třetí strany", - "A new version of Riot is available.": "Je dostupná nová verze Riotu.", - "I understand the risks and wish to continue": "Rozumím rizikům a přeji si pokračovat", - "Couldn't load home page": "Nepodařilo se nahrát úvodní stránku", - "Send Account Data": "Poslat data o účtu", - "Advanced notification settings": "Pokročilé nastavení upozornění", - "Uploading report": "Nahrávám hlášení", - "Sunday": "Neděle", - "Messages sent by bot": "Zprávy poslané robotem", - "Notification targets": "Cíle upozornění", - "Failed to set direct chat tag": "Nepodařilo se nastavit štítek přímého chatu", - "Today": "Dnes", - "Files": "Soubory", - "You are not receiving desktop notifications": "Nedostáváte upozornění na desktopu", - "Friday": "Pátek", - "Update": "Aktualizace", - "What's New": "Co je nového", - "Add an email address above to configure email notifications": "Abyste mohli nastavovat e-mailová upozornění, musíte uvést svoji e-mailovou adresu v kolonce výše", - "Expand panel": "Rozbalit panel", - "On": "Zapnout", - "%(count)s Members|other": "%(count)s Členů", - "Filter room names": "Filtrovat místnosti dle názvu", - "Changelog": "Seznam změn", - "Waiting for response from server": "Čekám na odezvu ze serveru", - "Send Custom Event": "Odeslat vlastní událost", - "All notifications are currently disabled for all targets.": "Veškeré notifikace jsou aktuálně pro všechny cíle vypnuty.", - "delete the alias.": "smazat alias.", - "To return to your account in future you need to set a password": "Abyste se mohli ke svému účtu v budoucnu vrátit, musíte si nastavit heslo", - "Forget": "Zapomenout", - "Hide panel": "Skrýt panel", - "You cannot delete this image. (%(code)s)": "Tento obrázek nemůžete smazat. (%(code)s)", - "Cancel Sending": "Zrušit odesílání", - "This Room": "Tato místnost", - "The Home Server may be too old to support third party networks": "Tento domovský server může být příliš zastaralý na to, aby podporoval sítě třetích stran", - "Noisy": "Hlučný", - "Room not found": "Místnost nenalezena", - "Messages containing my display name": "Zprávy obsahující mé zobrazované jméno", - "Remember, you can always set an email address in user settings if you change your mind.": "Vězte, že kdybyste si to rozmysleli, e-mailovou adresu můžete kdykoliv doplnit v uživatelském nastavení.", - "Unavailable": "Nedostupné", - "Error saving email notification preferences": "Chyba při ukládání nastavení e-mailových upozornění", - "View Decrypted Source": "Zobrazit dešifrovaný zdroj", - "Failed to update keywords": "Nepodařilo se aktualizovat klíčová slova", - "remove %(name)s from the directory.": "odebrat %(name)s z adresáře.", - "Notifications on the following keywords follow rules which can’t be displayed here:": "Upozornění na následující klíčová slova se řídí pravidly, která zde nelze zobrazit:", - "Safari and Opera work too.": "Safari a Opera fungují taky.", - "Please set a password!": "Prosím nastavte si heslo!", - "You have successfully set a password!": "Úspěšně jste si nastavili heslo!", - "Explore Room State": "Prohlížet stav místnosti", - "Source URL": "Zdrojová URL", - "Failed to add tag %(tagName)s to room": "Nepodařilo se přidat štítek %(tagName)s k místnosti", - "Filter results": "Filtrovat výsledky", - "Members": "Členové", - "No update available.": "Není dostupná žádná aktualizace.", - "Resend": "Poslat znovu", - "Failed to get protocol list from Home Server": "Z domovského serveru se nepodařilo získat seznam protokolů", - "Collecting app version information": "Sbírání informací o verzi aplikace", - "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Smazat alias místnosti %(alias)s a odstranit %(name)s z adresáře?", - "This will allow you to return to your account after signing out, and sign in on other devices.": "Toto vám umožní vrátit se po odhlášení ke svému účtu a používat jej na ostatních zařízeních.", - "Keywords": "Klíčová slova", - "Enable notifications for this account": "Zapnout upozornění na tomto účtu", - "Directory": "Adresář", - "Invite to this community": "Pozvat do této komunity", - "Search for a room": "Hledat místnost", - "Messages containing keywords": "Zprávy obsahující klíčová slova", - "View Source": "Zobrazit zdroj", - "Tuesday": "Úterý", - "Enter keywords separated by a comma:": "Vložte klíčová slova oddělená čárkou:", - "Forward Message": "Přeposlat zprávu", - "You have successfully set a password and an email address!": "Úspěšně jste si nastavili heslo a e-mailovou adresu!", - "Remove %(name)s from the directory?": "Odebrat %(name)s z adresáře?", - "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot používá mnoho pokročilých funkcí, z nichž některé jsou ve vašem současném prohlížeči nedostupné nebo experimentální.", - "Developer Tools": "Nástroje pro vývojáře", - "Enable desktop notifications": "Zapnout upozornění na ploše", - "Explore Account Data": "Prozkoumat data o účtu", - "Remove from Directory": "Odebrat z adresáře", - "Saturday": "Sobota", - "Messages in one-to-one chats": "Zprávy v individuálních chatech", - "Direct Chat": "Přímý chat", - "The server may be unavailable or overloaded": "Server může být nedostupný nebo přetížený", - "Reject": "Odmítnout", - "Failed to set Direct Message status of room": "Nepodařilo se přiřadit místnosti status Přímé zprávy", - "Monday": "Pondělí", - "All messages (noisy)": "Všechny zprávy (hlasitě)", - "Enable them now": "Povolit nyní", - "Messages containing my user name": "Zprávy obsahující mé uživatelské jméno", - "Toolbox": "Sada nástrojů", - "Collecting logs": "Sbírání logů", - "more": "více", - "You must specify an event type!": "Musíte určit typ události!", - "(HTTP status %(httpStatus)s)": "(HTTP status %(httpStatus)s)", - "Invite to this room": "Pozvat do této místnosti", - "Please install Chrome or Firefox for the best experience.": "Pro nejlepší zážitek si prosím nainstalujte Chrome nebo Firefox.", - "Failed to get public room list": "Nepodařilo se získat seznam veřejných místností", - "Send logs": "Odeslat záznamy", - "All messages": "Všechny zprávy", - "Call invitation": "Pozvánka k hovoru", - "Downloading update...": "Stahování aktualizace...", - "State Key": "Stavový klíč", - "Failed to send custom event.": "Nepodařilo se odeslat vlastní událost.", - "What's new?": "Co je nového?", - "Notify me for anything else": "Upozorni mě na cokoliv jiného", - "When I'm invited to a room": "Pokud jsem pozván do místnosti", - "Can't update user notification settings": "Nelze aktualizovat uživatelské nastavení upozornění", - "Notify for all other messages/rooms": "Upozorni na všechny ostatní zprávy/místnosti", - "Unable to look up room ID from server": "Nelze získat ID místnosti ze serveru", - "Couldn't find a matching Matrix room": "Odpovídající Matrix místost nenalezena", - "All Rooms": "Všechny místnosti", - "You cannot delete this message. (%(code)s)": "Tuto zprávu nemůžete smazat. (%(code)s)", - "Thursday": "Čtvrtek", - "Search…": "Vyhledat…", - "Back": "Zpět", - "Failed to change settings": "Nepodařilo se změnit nastavení", - "Reply": "Odpovědět", - "Show message in desktop notification": "Zobrazovat zprávu v upozornění na ploše", - "Unhide Preview": "Zobrazit náhled", - "Unable to join network": "Nelze se připojit k síti", - "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Snad jste je nastavili v jiném klientu než Riot. V Riotu je nemůžete upravit, ale přesto platí", - "Sorry, your browser is not able to run Riot.": "Omlouváme se, váš prohlížeč není schopný spustit Riot.", - "Uploaded on %(date)s by %(user)s": "Nahráno %(date)s uživatelem %(user)s", - "Messages in group chats": "Zprávy ve skupinových chatech", - "Yesterday": "Včera", - "Error encountered (%(errorDetail)s).": "Nastala chyba (%(errorDetail)s).", - "Login": "Přihlásit", - "Low Priority": "Nízká priorita", - "Riot does not know how to join a room on this network": "Riot neví, jak vstoupit do místosti na této síti", - "Set Password": "Nastavit heslo", - "An error occurred whilst saving your email notification preferences.": "Při ukládání nastavení e-mailových upozornění nastala chyba.", - "Enable audible notifications in web client": "Povolit zvuková upozornění ve webové aplikaci", - "Permalink": "Trvalý odkaz", - "Off": "Vypnout", - "#example": "#příklad", - "Mentions only": "Pouze zmínky", - "Failed to remove tag %(tagName)s from room": "Nepodařilo se odstranit štítek %(tagName)s z místnosti", - "Wednesday": "Středa", - "You can now return to your account after signing out, and sign in on other devices.": "Nyní se můžete ke svému účtu vrátit i po odhlášení a používat jej na ostatních zařízeních.", - "Enable email notifications": "Zapnout upozornění přes e-mail", - "Event Type": "Typ události", - "Download this file": "Stáhnout tento soubor", - "Pin Message": "Připíchnout zprávu", - "Thank you!": "Děkujeme vám!", - "View Community": "Zobrazit Komunitu", - "%(count)s Members|one": "%(count)s Člen", - "Event sent!": "Událost odeslána!", - "Event Content": "Obsah události", - "Unable to fetch notification target list": "Nepodařilo se získat seznam cílů upozornění", - "Quote": "Citace", - "Collapse panel": "Sbalit panel", - "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Vzhled a chování aplikace může být ve vašem aktuální prohlížeči nesprávné a některé nebo všechny funkce mohou být chybné. Chcete-li i přes to pokračovat, nebudeme vám bránit, ale se všemi problémy, na které narazíte, si musíte poradit sami!", - "Checking for an update...": "Kontrola aktualizací...", - "There are advanced notifications which are not shown here": "Jsou k dispozici pokročilá upozornění, která zde nejsou zobrazena" + "Warning": "Upozornění" } diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 724ec8d11e..e67c9fcaaa 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -51,6 +51,7 @@ "Are you sure you want to reject the invitation?": "Bist du sicher, dass du die Einladung ablehnen willst?", "Are you sure you want to upload the following files?": "Bist du sicher, dass du die folgenden Dateien hochladen möchtest?", "Banned users": "Verbannte Benutzer", + "Bug Report": "Fehlerbericht", "Changes to who can read history will only apply to future messages in this room": "Änderungen, die bestimmen, wer den Chatverlauf lesen kann, gelten nur für zukünftige Nachrichten in diesem Raum", "Clear Cache and Reload": "Cache leeren und neu laden", "Confirm your new password": "Neues Passwort bestätigen", @@ -88,6 +89,7 @@ "Forgot your password?": "Passwort vergessen?", "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.": "Aus Sicherheitsgründen werden beim Ausloggen alle Ende-zu-Ende-Verschlüsselungs-Schlüssel in diesem Browser gelöscht. Wenn du in späteren Riot-Sitzungen den bisherigen Chatverlauf entschlüsseln möchtest, exportiere bitte deine Schlüssel zur sicheren Aufbewahrung.", "For security, this session has been signed out. Please sign in again.": "Aus Sicherheitsgründen wurde diese Sitzung beendet. Bitte melde dich erneut an.", + "Found a bug?": "Fehler gefunden?", "Guests cannot join this room even if explicitly invited.": "Gäste können diesem Raum nicht beitreten, auch wenn sie explizit eingeladen wurden.", "Hangup": "Auflegen", "Homeserver is": "Home-Server:", @@ -396,6 +398,7 @@ "New passwords don't match": "Die neuen Passwörter stimmen nicht überein", "olm version:": "Version von olm:", "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 Seitenende springen", "Show timestamps in 12 hour format (e.g. 2:30pm)": "Zeitstempel im 12-Stunden-Format anzeigen (z. B. 2:30pm)", @@ -650,9 +653,11 @@ "Define the power level of a user": "Setze das Berechtigungslevel eines Benutzers", "Edit": "Editieren", "Enable automatic language detection for syntax highlighting": "Automatische Spracherkennung für die Syntax-Hervorhebung aktivieren", + "Hide Apps": "Apps verbergen", "Hide join/leave messages (invites/kicks/bans unaffected)": "Betreten-/Verlassen-Benachrichtigungen verbergen (gilt nicht für Einladungen/Kicks/Bans)", "Revoke widget access": "Ziehe Widget-Zugriff zurück", "Sets the room topic": "Setzt das Raum-Thema", + "Show Apps": "Apps anzeigen", "To get started, please pick a username!": "Um zu starten, wähle bitte einen Nutzernamen!", "Unable to create widget.": "Widget kann nicht erstellt werden.", "Unbans user with given id": "Verbannung aufheben für Benutzer mit angegebener ID", @@ -687,6 +692,7 @@ "You are no longer ignoring %(userId)s": "%(userId)s wird nicht mehr ignoriert", "Message removed by %(userId)s": "Nachricht wurde von %(userId)s entfernt", "Name or matrix ID": "Name oder Matrix-ID", + "Unable to leave room": "Verlassen des Raumes fehlgeschlagen", "Leave": "Verlassen", "Failed to invite the following users to %(groupId)s:": "Die folgenden Benutzer konnten nicht in die Gruppe %(groupId)s eingeladen werden:", "Leave %(groupName)s?": "%(groupName)s verlassen?", @@ -907,6 +913,7 @@ "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", "Status.im theme": "Status.im-Thema", "%(duration)ss": "%(duration)ss", "%(duration)sm": "%(duration)sm", @@ -960,6 +967,7 @@ "Your homeserver's URL": "Die URL deines Homeservers", "Your identity server's URL": "Die URL deines Identitätsservers", "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s", + "Tag Panel": "Beschriftungsfeld", "Message Replies": "Antworten auf Nachrichten", "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.": "Du wirst nicht in der Lage sein, die Änderung zurückzusetzen, da du dich degradierst. Wenn du der letze Nutzer mit Berechtigungen bist, wird es unmöglich sein die Privilegien zurückzubekommen.", "Community IDs cannot not be empty.": "Community-IDs können nicht leer sein.", @@ -984,6 +992,7 @@ "Key request sent.": "Schlüssel-Anfragen gesendet.", "Re-request encryption keys from your other devices.": "Verschlüsselungs-Schlüssel von deinen anderen Geräten erneut anfragen.", "%(user)s is a %(userRole)s": "%(user)s ist ein %(userRole)s", + "Changes made to your community might not be seen by other users for up to 30 minutes.": "Änderungen, die an deiner Community gemacht werden, können bis zu 30 Minuten brauchen, bis sie für andere sichtbar sind.", "Debug Logs Submission": "Einsenden des Fehlerprotokolls", "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contian messages.": "Wenn du einen Fehler via GitHub gemeldet hast, können Fehlerberichte uns helfen um das Problem zu finden. Sie enthalten Anwendungsdaten wie deinen Nutzernamen, Raum- und Gruppen-ID's und Aliase die du besucht hast und Nutzernamen anderer Nutzer. Sie enthalten keine Nachrichten.", "Submit debug logs": "Fehlerberichte einreichen", @@ -994,167 +1003,5 @@ "Unable to leave community": "Community konnte nicht verlassen werden", "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Änderungen am Namen und Bild deiner Community werden evtl. erst nach 30 Minuten von anderen Nutzern gesehen werden.", "Join this community": "Community beitreten", - "Leave this community": "Community verlassen", - "Sticker Messages": "Sticker-Nachrichten", - "You don't currently have any stickerpacks enabled": "Du hast aktuell keine Stickerpacks aktiviert", - "Add a stickerpack": "Füge ein Stickerpack hinzu", - "Hide Stickers": "Sticker verbergen", - "Show Stickers": "Sticker zeigen", - "Who can join this community?": "Wer kann dieser Community beitreten?", - "Everyone": "Jeder", - "Stickerpack": "Stickerpack", - "Fetching third party location failed": "Das Abrufen des Drittanbieterstandorts ist fehlgeschlagen", - "A new version of Riot is available.": "Eine neue Version von Riot ist verfügbar.", - "Couldn't load home page": "Startseite konnte nicht geladen werden", - "Send Account Data": "Benutzerkonto-Daten senden", - "All notifications are currently disabled for all targets.": "Aktuell sind alle Benachrichtigungen für alle Ziele deaktiviert.", - "Uploading report": "Lade Bericht hoch", - "Sunday": "Sonntag", - "Notification targets": "Benachrichtigungsziele", - "Today": "Heute", - "Files": "Dateien", - "You are not receiving desktop notifications": "Du erhältst keine Desktop-Benachrichtigungen", - "Friday": "Freitag", - "Update": "Aktualisieren", - "What's New": "Was ist neu", - "Add an email address above to configure email notifications": "Füge oben eine E-Mail-Adresse hinzu, um die E-Mail-Benachrichtigungseinstellungen zu konfigurieren", - "Expand panel": "Panel ausklappen", - "On": "An", - "%(count)s Members|other": "%(count)s Mitglieder", - "Filter room names": "Raum-Namen filtern", - "Changelog": "Änderungsprotokoll", - "Waiting for response from server": "Auf Antwort vom Server warten", - "Send Custom Event": "Benutzerdefiniertes Event senden", - "Advanced notification settings": "Erweiterte Benachrichtigungs-Einstellungen", - "Failed to send logs: ": "Senden von Logs fehlgeschlagen: ", - "delete the alias.": "Lösche den Alias.", - "To return to your account in future you need to set a password": "Um in Zukunft auf dein Benutzerkonto zugreifen zu können, musst du ein Passwort setzen", - "Forget": "Entfernen", - "#example": "#Beispiel", - "Hide panel": "Panel verbergen", - "You cannot delete this image. (%(code)s)": "Das Bild kann nicht gelöscht werden. (%(code)s)", - "Cancel Sending": "Senden abbrechen", - "This Room": "In diesem Raum", - "The Home Server may be too old to support third party networks": "Der Home-Server ist eventuell zu alt, um Drittanbieter-Netzwerke zu unterstützen", - "Resend": "Erneut senden", - "Room not found": "Raum nicht gefunden", - "Messages containing my display name": "Nachrichten, die meinen Anzeigenamen enthalten", - "Messages in one-to-one chats": "Nachrichten in Einzel-Chats", - "Unavailable": "Nicht verfügbar", - "View Decrypted Source": "Entschlüsselten Quellcode ansehen", - "Failed to update keywords": "Schlüsselwörter konnten nicht aktualisiert werden", - "Notes:": "Notizen:", - "remove %(name)s from the directory.": "entferne %(name)s aus dem Verzeichnis.", - "Notifications on the following keywords follow rules which can’t be displayed here:": "Die Benachrichtigungen zu den folgenden Schlüsselwörtern folgen Regeln, die hier nicht angezeigt werden können:", - "Safari and Opera work too.": "Safari und Opera sind weitere Alternativen.", - "Please set a password!": "Bitte setze ein Passwort!", - "You have successfully set a password!": "Du hast erfolgreich ein Passwort gesetzt!", - "An error occurred whilst saving your email notification preferences.": "Beim Speichern deiner E-Mail-Benachrichtigungseinstellungen ist ein Fehler aufgetreten.", - "Explore Room State": "Raum-Status erkunden", - "Source URL": "Quell-URL", - "Messages sent by bot": "Nachrichten von Bots", - "Filter results": "Ergebnisse filtern", - "Members": "Mitglieder", - "No update available.": "Kein Update verfügbar.", - "Noisy": "Laut", - "Failed to get protocol list from Home Server": "Fehler beim Abrufen der Protokoll-Liste vom Home-Server", - "Collecting app version information": "App-Versionsinformationen werden abgerufen", - "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Soll der Raum-Alias %(alias)s gelöscht und der %(name)s aus dem Verzeichnis entfernt werden?", - "This will allow you to return to your account after signing out, and sign in on other devices.": "Dies erlaubt dir, dich wieder an deinem Konto anzumelden, nachdem du dich abgemeldet hast.", - "Keywords": "Schlüsselwörter", - "Enable notifications for this account": "Benachrichtigungen für dieses Benutzerkonto aktivieren", - "Directory": "Raum-Verzeichnis", - "Invite to this community": "In diese Community einladen", - "Failed to get public room list": "Die Liste der öffentlichen Räume konnte nicht geladen werden", - "Messages containing keywords": "Nachrichten, die Schlüsselwörter enthalten", - "Error saving email notification preferences": "Fehler beim Speichern der E-Mail-Benachrichtigungseinstellungen", - "Tuesday": "Dienstag", - "Enter keywords separated by a comma:": "Schlüsselwörter kommagetrennt eingeben:", - "Forward Message": "Nachricht weiterleiten", - "You have successfully set a password and an email address!": "Du hast erfolgreich ein Passwort und eine E-Mail-Adresse gesetzt!", - "Remove %(name)s from the directory?": "Soll der Raum %(name)s aus dem Verzeichnis entfernt werden?", - "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot nutzt zahlreiche fortgeschrittene Browser-Funktionen, die teilweise in deinem aktuell verwendeten Browser noch nicht verfügbar sind oder sich noch im experimentellen Status befinden.", - "Developer Tools": "Entwicklerwerkzeuge", - "Preparing to send logs": "Senden von Logs wird vorbereitet", - "Enable desktop notifications": "Desktop-Benachrichtigungen aktivieren", - "Remember, you can always set an email address in user settings if you change your mind.": "Vergiss nicht, dass du in den Benutzereinstellungen jederzeit eine E-Mail-Adresse setzen kannst, wenn du deine Meinung änderst.", - "Explore Account Data": "Benutzerkonto-Daten analysieren", - "All messages (noisy)": "Alle Nachrichten (laut)", - "Saturday": "Samstag", - "I understand the risks and wish to continue": "Ich verstehe das Risiko und möchte fortfahren", - "Direct Chat": "Direkt-Chat", - "The server may be unavailable or overloaded": "Der Server ist vermutlich nicht erreichbar oder überlastet", - "Reject": "Ablehnen", - "Failed to set Direct Message status of room": "Konnte den direkten Benachrichtigungsstatus nicht setzen", - "Monday": "Montag", - "Remove from Directory": "Aus dem Raum-Verzeichnis entfernen", - "Enable them now": "Aktiviere diese jetzt", - "Messages containing my user name": "Nachrichten, die meinen Benutzernamen enthalten", - "Toolbox": "Werkzeugkasten", - "Collecting logs": "Protokolle werden abgerufen", - "more": "mehr", - "GitHub issue link:": "Link des GitHub-Problems:", - "You must specify an event type!": "Du musst einen Event-Typ spezifizieren!", - "(HTTP status %(httpStatus)s)": "(HTTP-Status %(httpStatus)s)", - "Invite to this room": "In diesen Raum einladen", - "Please install Chrome or Firefox for the best experience.": "Bitte installiere Chrome oder Firefox für ein optimales Anwendungsergebnis.", - "Wednesday": "Mittwoch", - "You cannot delete this message. (%(code)s)": "Diese Nachricht kann nicht gelöscht werden. (%(code)s)", - "Quote": "Zitat", - "Send logs": "Logdateien übermitteln", - "All messages": "Alle Nachrichten", - "Call invitation": "Anruf-Einladung", - "Downloading update...": "Update wird heruntergeladen...", - "State Key": "Status-Schlüssel", - "Failed to send custom event.": "Senden des benutzerdefinierten Events fehlgeschlagen.", - "What's new?": "Was ist neu?", - "Notify me for anything else": "Über alles andere benachrichtigen", - "When I'm invited to a room": "Wenn ich in einen Raum eingeladen werde", - "Click here to create a GitHub issue.": "Klicke hier um ein GithHub-Problem zu erstellen.", - "Can't update user notification settings": "Benachrichtigungs-Einstellungen des Benutzers konnten nicht aktualisiert werden", - "Notify for all other messages/rooms": "Benachrichtigungen für alle anderen Mitteilungen/Räume aktivieren", - "Unable to look up room ID from server": "Es ist nicht möglich, die Raum-ID auf dem Server nachzuschlagen", - "Couldn't find a matching Matrix room": "Konnte keinen entsprechenden Matrix-Raum finden", - "All Rooms": "In allen Räumen", - "Search for a room": "Nach einem Raum suchen", - "Thursday": "Donnerstag", - "Search…": "Suchen…", - "Logs sent": "Logs gesendet", - "Back": "Zurück", - "Reply": "Antworten", - "Show message in desktop notification": "Nachricht in der Desktop-Benachrichtigung anzeigen", - "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Fehlerberichte enthalten Anwendungsdaten wie deinen Nutzernamen, Raum- und Gruppen-ID's und Aliase die du besucht hast sowie Nutzernamen anderer Nutzer. Sie enthalten keine Nachrichten.", - "Unhide Preview": "Vorschau wieder anzeigen", - "Unable to join network": "Es ist nicht möglich, dem Netzwerk beizutreten", - "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Du hast sie eventuell auf einem anderen Matrix-Client und nicht in Riot konfiguriert. Sie können in Riot nicht verändert werden, gelten aber trotzdem", - "Sorry, your browser is not able to run Riot.": "Es tut uns leid, aber dein Browser kann Riot nicht ausführen.", - "Messages in group chats": "Nachrichten in Gruppen-Chats", - "Yesterday": "Gestern", - "Error encountered (%(errorDetail)s).": "Es ist ein Fehler aufgetreten (%(errorDetail)s).", - "Login": "Anmeldung", - "Low Priority": "Niedrige Priorität", - "Unable to fetch notification target list": "Liste der Benachrichtigungsempfänger konnte nicht abgerufen werden", - "Set Password": "Passwort einrichten", - "Enable audible notifications in web client": "Audio-Benachrichtigungen im Web-Client aktivieren", - "Permalink": "Permanenter Link", - "Off": "Aus", - "Riot does not know how to join a room on this network": "Riot weiß nicht, wie es einem Raum auf diesem Netzwerk beitreten soll", - "Mentions only": "Nur, wenn du erwähnt wirst", - "You can now return to your account after signing out, and sign in on other devices.": "Du kannst nun zu deinem Benutzerkonto zurückkehren, nachdem du dich abgemeldet hast. Anschließend kannst du dich an anderen Geräten anmelden.", - "Enable email notifications": "E-Mail-Benachrichtigungen aktivieren", - "Event Type": "Event-Typ", - "Download this file": "Datei herunterladen", - "Pin Message": "Nachricht anheften", - "Failed to change settings": "Einstellungen konnten nicht geändert werden", - "View Community": "Community ansehen", - "%(count)s Members|one": "%(count)s Mitglied", - "Event sent!": "Event gesendet!", - "View Source": "Quellcode ansehen", - "Event Content": "Event-Inhalt", - "Thank you!": "Danke!", - "Uploaded on %(date)s by %(user)s": "Hochgeladen: %(date)s von %(user)s", - "Collapse panel": "Panel einklappen", - "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "In deinem aktuell verwendeten Browser können Aussehen und Handhabung der Anwendung unter Umständen noch komplett fehlerhaft sein, so dass einige bzw. im Extremfall alle Funktionen nicht zur Verfügung stehen. Du kannst es trotzdem versuchen und fortfahren, bist dabei aber bezüglich aller auftretenden Probleme auf dich allein gestellt!", - "Checking for an update...": "Nach Updates suchen...", - "There are advanced notifications which are not shown here": "Es existieren erweiterte Benachrichtigungen, welche hier nicht angezeigt werden" + "Leave this community": "Community verlassen" } diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index cadf232ecf..25cfc6cc82 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -57,6 +57,7 @@ "Banned users": "Utilisateurs bannis", "Bans user with given id": "Bannit l'utilisateur à partir de son identifiant", "Blacklisted": "Sur liste noire", + "Bug Report": "Rapport d'erreur", "Call Timeout": "Délai d’appel expiré", "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Impossible de se connecter au serveur d'accueil en HTTP si l'URL dans la barre de votre explorateur est en HTTPS. Utilisez HTTPS ou activez le support des scripts non-vérifiés.", "Can't load user settings": "Impossible de charger les paramètres de l'utilisateur", @@ -92,8 +93,8 @@ "Current password": "Mot de passe actuel", "Curve25519 identity key": "Clé d’identité Curve25519", "/ddg is not a command": "/ddg n'est pas une commande", - "Deactivate Account": "Désactiver le compte", - "Deactivate my account": "Désactiver mon compte", + "Deactivate Account": "Supprimer le compte", + "Deactivate my account": "Supprimer mon compte", "Decrypt %(text)s": "Déchiffrer %(text)s", "Decryption error": "Erreur de déchiffrement", "Delete": "Supprimer", @@ -132,6 +133,7 @@ "Forget room": "Oublier le salon", "Forgot your password?": "Mot de passe oublié ?", "For security, this session has been signed out. Please sign in again.": "Par mesure de sécurité, la session a expiré. Merci de vous authentifier à nouveau.", + "Found a bug?": "Vous avez trouvé un problème ?", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s de %(fromPowerLevel)s à %(toPowerLevel)s", "Hangup": "Raccrocher", "Hide read receipts": "Cacher les accusés de lecture", @@ -239,6 +241,7 @@ "%(senderName)s removed their profile picture.": "%(senderName)s a supprimé son image de profil.", "Remove %(threePid)s?": "Supprimer %(threePid)s ?", "%(senderName)s requested a VoIP conference.": "%(senderName)s a demandé une téléconférence audio.", + "Report it": "Le signaler", "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.": "Pour le moment, réinitialiser le mot de passe va réinitialiser les clés de chiffrement sur tous les appareils, rendant l’historique des salons chiffrés illisible, à moins que vous exportiez d'abord les clés de salon puis que vous les ré-importiez après. Cela sera amélioré prochainement.", "Return to login screen": "Retourner à l’écran de connexion", "Riot does not have permission to send you notifications - please check your browser settings": "Riot n’a pas la permission de vous envoyer des notifications - merci de vérifier les paramètres de votre navigateur", @@ -648,9 +651,11 @@ "Define the power level of a user": "Définir le rang d'un utilisateur", "Edit": "Modifier", "Enable automatic language detection for syntax highlighting": "Activer la détection automatique de la langue pour la correction orthographique", + "Hide Apps": "Masquer les applications", "Hide join/leave messages (invites/kicks/bans unaffected)": "Masquer les messages d'arrivée/départ (n'affecte pas les invitations/exclusions/bannissements)", "Revoke widget access": "Révoquer les accès du widget", "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 un widget.", "Unbans user with given id": "Révoque le bannissement de l'utilisateur à partir de son identifiant", @@ -857,6 +862,7 @@ "Leave Community": "Quitter la communauté", "Leave %(groupName)s?": "Quitter %(groupName)s ?", "Leave": "Quitter", + "Unable to leave room": "Impossible de partir du salon", "Community Settings": "Paramètres de la communauté", "Add rooms to this community": "Ajouter des salons à cette communauté", "%(inviter)s has invited you to join this community": "%(inviter)s vous a invité à rejoindre cette communauté", @@ -900,6 +906,7 @@ "Username on %(hs)s": "Nom d'utilisateur sur %(hs)s", "Restricted": "Restreint", "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", @@ -927,6 +934,7 @@ "Flair will appear if enabled in room settings": "Les badges n'apparaîtront que s'ils sont activés dans les paramètres de chaque salon", "Flair will not appear": "Les badges n'apparaîtront pas", "Display your community flair in rooms configured to show it.": "Sélectionnez les badges dans les paramètres de chaque salon pour les afficher.", + "Tag Panel": "Panneau des étiquettes", "Addresses": "Adresses", "expand": "développer", "collapse": "réduire", @@ -984,6 +992,7 @@ "Key request sent.": "Demande de clé envoyée.", "Re-request encryption keys from your other devices.": "Re-demander les clés de chiffrement depuis vos autres appareils.", "%(user)s is a %(userRole)s": "%(user)s est %(userRole)s", + "Changes made to your community might not be seen by other users for up to 30 minutes.": "Les changements effectués sur votre communauté peuvent ne pas apparaître pour les autres utilisateurs avant 30 minutes.", "Seen by %(displayName)s (%(userName)s) at %(dateTime)s": "Vu par %(displayName)s (%(userName)s) à %(dateTime)s", "Code": "Code", "Debug Logs Submission": "Envoi des journaux de débogage", @@ -998,162 +1007,13 @@ "Stickerpack": "Pack de stickers", "Sticker Messages": "Messages sticker", "You don't currently have any stickerpacks enabled": "Vous n'avez activé aucun pack de stickers pour l'instant", + "Click": "Cliquer", + "here": "ici", + "to add some!": "pour en ajouter !", "Add a stickerpack": "Ajouter un pack de stickers", "Hide Stickers": "Masquer les stickers", "Show Stickers": "Afficher les stickers", + "Manage sticker packs": "Gérer les packs de stickers", "Who can join this community?": "Qui peut rejoindre cette communauté ?", - "Everyone": "Tout le monde", - "Fetching third party location failed": "Échec de la récupération de la localisation tierce", - "A new version of Riot is available.": "Une nouvelle version de Riot est disponible.", - "Couldn't load home page": "Impossible de charger la page d'accueil", - "Send Account Data": "Envoyer les données du compte", - "All notifications are currently disabled for all targets.": "Toutes les notifications sont désactivées pour tous les appareils.", - "Uploading report": "Envoi du rapport", - "Sunday": "Dimanche", - "Notification targets": "Appareils recevant les notifications", - "Today": "Aujourd'hui", - "Files": "Fichiers", - "You are not receiving desktop notifications": "Vous ne recevez pas les notifications sur votre bureau", - "Friday": "Vendredi", - "Update": "Mettre à jour", - "What's New": "Nouveautés", - "Add an email address above to configure email notifications": "Ajouter une adresse e-mail pour la configuration des notifications par e-mail", - "Expand panel": "Dévoiler le panneau", - "On": "Activé", - "%(count)s Members|other": "%(count)s membres", - "Filter room names": "Filtrer les salons par nom", - "Changelog": "Journal des modifications", - "Waiting for response from server": "En attente d’une réponse du serveur", - "Send Custom Event": "Envoyer l'événement personnalisé", - "Advanced notification settings": "Paramètres de notification avancés", - "delete the alias.": "supprimer l'alias.", - "To return to your account in future you need to set a password": "Pour pouvoir retrouver votre compte dans le futur, vous devez définir un mot de passe", - "Forget": "Oublier", - "#example": "#exemple", - "Hide panel": "Cacher le panneau", - "You cannot delete this image. (%(code)s)": "Vous ne pouvez pas supprimer cette image. (%(code)s)", - "Cancel Sending": "Annuler l'envoi", - "This Room": "Ce salon", - "The Home Server may be too old to support third party networks": "Le serveur d'accueil semble trop ancien pour supporter des réseaux tiers", - "Noisy": "Bruyant", - "Room not found": "Salon non trouvé", - "Messages containing my display name": "Messages contenant mon nom affiché", - "Messages in one-to-one chats": "Messages dans les discussions directes", - "Unavailable": "Indisponible", - "View Decrypted Source": "Voir la source déchiffrée", - "Failed to update keywords": "Échec dans la mise à jour des mots-clés", - "remove %(name)s from the directory.": "supprimer %(name)s du répertoire.", - "Notifications on the following keywords follow rules which can’t be displayed here:": "Les notifications pour les mots-clés suivant répondent à des critères qui ne peuvent pas être affichés ici :", - "Safari and Opera work too.": "Safari et Opera fonctionnent également.", - "Please set a password!": "Veuillez définir un mot de passe !", - "You have successfully set a password!": "Vous avez défini un mot de passe avec succès !", - "An error occurred whilst saving your email notification preferences.": "Une erreur est survenue lors de la sauvegarde de vos préférences de notification par e-mail.", - "Explore Room State": "Parcourir l'état du salon", - "Source URL": "URL de la source", - "Messages sent by bot": "Messages envoyés par des robots", - "Filter results": "Filtrer les résultats", - "Members": "Membres", - "No update available.": "Aucune mise à jour disponible.", - "Resend": "Renvoyer", - "Failed to get protocol list from Home Server": "Échec lors de la récupération de la liste sur le serveur", - "Collecting app version information": "Récupération des informations de version de l’application", - "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Supprimer l'alias %(alias)s du salon et supprimer %(name)s du répertoire ?", - "This will allow you to return to your account after signing out, and sign in on other devices.": "Cela vous permettra de retourner sur votre compte après vous être déconnecté, et de vous identifier sur d'autres appareils.", - "Keywords": "Mots-clés", - "Enable notifications for this account": "Activer les notifications pour ce compte", - "Directory": "Répertoire", - "Invite to this community": "Inviter à cette communauté", - "Failed to get public room list": "Échec lors de la récupération de la liste des salons publics", - "Messages containing keywords": "Messages contenant des mots-clés", - "Error saving email notification preferences": "Erreur lors de la sauvegarde des préférences de notification par e-mail", - "Tuesday": "Mardi", - "Enter keywords separated by a comma:": "Entrez les mots-clés séparés par une virgule :", - "Search…": "Rechercher…", - "You have successfully set a password and an email address!": "Vous avez défini un mot de passe et une adresse e-mail avec succès !", - "Remove %(name)s from the directory?": "Supprimer %(name)s du répertoire ?", - "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot utilise de nombreuses fonctionnalités avancées du navigateur, certaines ne sont pas disponibles ou expérimentales dans votre navigateur actuel.", - "Developer Tools": "Outils de développement", - "Enable desktop notifications": "Activer les notifications de bureau", - "Remember, you can always set an email address in user settings if you change your mind.": "Souvenez-vous que vous pourrez toujours définir une adresse e-mail dans les paramètres de l'utilisateur si vous changez d’avis.", - "Explore Account Data": "Explorer les données du compte", - "Remove from Directory": "Supprimer du répertoire", - "Saturday": "Samedi", - "I understand the risks and wish to continue": "Je comprends les risques et souhaite continuer", - "Direct Chat": "Discussion directe", - "The server may be unavailable or overloaded": "Le serveur est indisponible ou surchargé", - "Reject": "Rejeter", - "Failed to set Direct Message status of room": "Échec du réglage de l'état du salon en Discussion directe", - "Monday": "Lundi", - "All messages (noisy)": "Tous les messages (fort)", - "Enable them now": "Les activer maintenant", - "Messages containing my user name": "Message contenant mon nom d'utilisateur", - "Toolbox": "Boîte à outils", - "Collecting logs": "Récupération des journaux", - "more": "plus", - "You must specify an event type!": "Vous devez spécifier un type d'événement !", - "(HTTP status %(httpStatus)s)": "(état HTTP %(httpStatus)s)", - "Invite to this room": "Inviter dans ce salon", - "Please install Chrome or Firefox for the best experience.": "Veuillez installer Chrome ou Firefox pour une expérience optimale.", - "Wednesday": "Mercredi", - "You cannot delete this message. (%(code)s)": "Vous ne pouvez pas supprimer ce message. (%(code)s)", - "Quote": "Citer", - "Send logs": "Envoyer les journaux", - "All messages": "Tous les messages", - "Call invitation": "Appel entrant", - "Downloading update...": "Mise à jour en cours de téléchargement...", - "State Key": "Clé d'état", - "Failed to send custom event.": "Échec de l'envoi de l'événement personnalisé.", - "What's new?": "Nouveautés ?", - "Notify me for anything else": "Me notifier pour tout le reste", - "View Source": "Voir la source", - "Can't update user notification settings": "Impossible de mettre à jour les paramètres de notification de l'utilisateur", - "Notify for all other messages/rooms": "Me notifier pour tous les autres messages/salons", - "Unable to look up room ID from server": "Impossible de récupérer l'ID du salon sur le serveur", - "Couldn't find a matching Matrix room": "Impossible de trouver un salon Matrix correspondant", - "All Rooms": "Tous les salons", - "Search for a room": "Rechercher un salon", - "Thursday": "Jeudi", - "Forward Message": "Transférer le message", - "Back": "Retour", - "Reply": "Répondre", - "Show message in desktop notification": "Afficher le message dans les notifications de bureau", - "Unhide Preview": "Dévoiler l'aperçu", - "Unable to join network": "Impossible de rejoindre le réseau", - "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Vous les avez probablement configurées dans un autre client que Riot. Vous ne pouvez pas les configurer dans Riot mais elles s'appliquent quand même", - "Sorry, your browser is not able to run Riot.": "Désolé, Riot n'est pas supporté par votre navigateur.", - "Uploaded on %(date)s by %(user)s": "Téléchargé le %(date)s par %(user)s", - "Messages in group chats": "Messages dans les discussions de groupe", - "Yesterday": "Hier", - "Error encountered (%(errorDetail)s).": "Erreur rencontrée (%(errorDetail)s).", - "Login": "Connexion", - "Low Priority": "Priorité basse", - "Unable to fetch notification target list": "Impossible de récupérer la liste des appareils recevant les notifications", - "Set Password": "Définir un mot de passe", - "Enable audible notifications in web client": "Activer les notifications sonores pour le client web", - "Permalink": "Permalien", - "Off": "Désactivé", - "Riot does not know how to join a room on this network": "Riot ne peut pas joindre un salon sur ce réseau", - "Mentions only": "Seulement les mentions", - "You can now return to your account after signing out, and sign in on other devices.": "Vous pouvez maintenant revenir sur votre compte après vous être déconnecté, et vous identifier sur d'autres appareils.", - "Enable email notifications": "Activer les notifications par e-mail", - "Event Type": "Type d'événement", - "Download this file": "Télécharger ce fichier", - "Pin Message": "Épingler le message", - "Failed to change settings": "Échec de la mise à jour des paramètres", - "View Community": "Voir la communauté", - "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Depuis votre navigateur actuel, le visuel et le ressenti de l'application pourraient être complètement erronés, et certaines fonctionnalités pourraient ne pas être supportées. Vous pouvez continuer malgré tout, mais vous n'aurez aucune aide si vous rencontrez des problèmes !", - "%(count)s Members|one": "%(count)s membre", - "Event sent!": "Événement envoyé !", - "Event Content": "Contenu de l'événement", - "Thank you!": "Merci !", - "Collapse panel": "Cacher le panneau", - "When I'm invited to a room": "Quand je suis invité dans un salon", - "Checking for an update...": "Recherche de mise à jour...", - "There are advanced notifications which are not shown here": "Il existe une configuration avancée des notifications qui ne peut être affichée ici", - "Logs sent": "Rapports envoyés", - "GitHub issue link:": "Lien du signalement GitHub :", - "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Les rapports de débogage contiennent des données d'usage de l'application qui incluent votre nom d'utilisateur, les identifiants ou alias des salons ou groupes auxquels vous avez rendu visite ainsi que les noms des autres utilisateurs. Ils ne contiennent aucun message.", - "Failed to send logs: ": "Échec lors de l'envoi des rapports : ", - "Notes:": "Notes :", - "Preparing to send logs": "Préparation d'envoi des rapports" + "Everyone": "Tout le monde" } diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 35dd348378..b7f20d52f7 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -10,7 +10,7 @@ "Mute": "Elnémít", "Notifications": "Értesítések", "Operation failed": "Sikertelen művelet", - "powered by Matrix": "Matrix hajtja", + "powered by Matrix": "A Matrix hajtja", "Remove": "Eltávolítás", "Settings": "Beállítások", "unknown error code": "ismeretlen hibakód", @@ -69,6 +69,7 @@ "Banned users": "Kitiltott felhasználók", "Bans user with given id": "Kitiltja a felhasználót a megadott ID-vel", "Blacklisted": "Fekete listára téve", + "Bug Report": "Hiba jelentés", "Bulk Options": "Tömeges beállítások", "Call Timeout": "Hívás időtúllépés", "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.": "Nem lehet kapcsolódni a saját szerverhez - ellenőrizd a kapcsolatot, biztosítsd, hogy a saját szerver tanúsítványa hiteles legyen, és a böngésző kiterjesztések ne blokkolják a kéréseket.", @@ -191,6 +192,7 @@ "Forgot your password?": "Elfelejtetted a jelszavad?", "For security, this session has been signed out. Please sign in again.": "A biztonság érdekében ez a kapcsolat le lesz bontva. Légy szíves jelentkezz be újra.", "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.": "A biztonság érdekében a kilépéskor a ponttól pontig való (E2E) titkosításhoz szükséges kulcsok törlésre kerülnek a böngészőből. Ha a régi üzeneteket továbbra is el szeretnéd olvasni, kérlek mentsed ki a szobákhoz tartozó kulcsot.", + "Found a bug?": "Hibát találtál?", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s : %(fromPowerLevel)s -> %(toPowerLevel)s", "Guest access is disabled on this Home Server.": "Vendég belépés tiltva van a Saját szerveren.", "Guests cannot join this room even if explicitly invited.": "Vendégek akkor sem csatlakozhatnak ehhez a szobához ha külön meghívók kaptak.", @@ -307,6 +309,7 @@ "%(senderName)s removed their profile picture.": "%(senderName)s törölte a profil képét.", "Remove %(threePid)s?": "Töröl: %(threePid)s?", "%(senderName)s requested a VoIP conference.": "%(senderName)s VoIP konferenciát kezdeményez.", + "Report it": "Jelent", "Results from DuckDuckGo": "Eredmények a DuckDuckGo-ból", "Return to login screen": "Vissza a bejelentkezési képernyőre", "Riot does not have permission to send you notifications - please check your browser settings": "Riotnak nincs jogosultsága értesítést küldeni neked - ellenőrizd a böngésző beállításait", @@ -649,11 +652,13 @@ "Define the power level of a user": "A felhasználó szintjének meghatározása", "Edit": "Szerkeszt", "Enable automatic language detection for syntax highlighting": "Nyelv automatikus felismerése szintaxis kiemeléshez", + "Hide Apps": "Alkalmazások elrejtése", "Hide join/leave messages (invites/kicks/bans unaffected)": "Belép/kilép üzenetek elrejtése (meghívók, kirúgások, kitiltások nem érintettek)", "AM": "de", "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 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", @@ -697,7 +702,7 @@ "Disable Emoji suggestions while typing": "Emoji ajánlások kikapcsolása gépelés közben", "Banned by %(displayName)s": "Kitiltotta: %(displayName)s", "Message removed by %(userId)s": "Üzenetet törölte: %(userId)s", - "To send messages, you must be a": "Ahhoz, hogy üzenetet tudj küldeni, ilyen szinten kell lenned:", + "To send messages, you must be a": "Ahhoz, hogy üzenetet tudj küldeni, neked ilyen szinten kell lenned:", "To invite users into the room, you must be a": "Hogy meghívj valakit a szobába, ilyen szinten kell lenned:", "To configure the room, you must be a": "A szoba beállításához ilyen szinten kell lenned:", "To kick users, you must be a": "Felhasználó kirúgásához ilyen szinten kell lenned:", @@ -707,13 +712,14 @@ "To change the room's avatar, you must be a": "A szoba avatarjának a megváltoztatásához ilyen szinten kell lenned:", "To change the room's name, you must be a": "A szoba nevének megváltoztatásához ilyen szinten kell lenned:", "To change the room's main address, you must be a": "A szoba elsődleges címének a megváltoztatásához ilyen szinten kell lenned:", - "To change the room's history visibility, you must be a": "A szoba napló elérhetőségének a megváltoztatásához ilyen szinten kell lenned:", + "To change the room's history visibility, you must be a": "A szoba naplója elérhetőségének a megváltoztatásához ilyen szinten kell lenned:", "To change the permissions in the room, you must be a": "A szobában a jogosultság megváltoztatásához ilyen szinten kell lenned:", "To change the topic, you must be a": "A téma megváltoztatásához ilyen szinten kell lenned:", "To modify widgets in the room, you must be a": "A szoba kisalkalmazásainak megváltoztatásához ilyen szinten kell lenned:", "Description": "Leírás", "Name or matrix ID": "Név vagy Matrix azonosító", "Unable to accept invite": "A meghívót nem lehet elfogadni", + "Unable to leave room": "A szobát nem lehet elhagyni", "Leave": "Elhagy", "Failed to invite the following users to %(groupId)s:": "Az alábbi felhasználókat nem sikerült meghívni a(z) %(groupId)s:", "Failed to invite users to %(groupId)s": "Nem sikerült meghívni a felhasználókat ebbe a csoportba: %(groupId)s", @@ -730,7 +736,7 @@ "Failed to remove the room from the summary of %(groupId)s": "Az alábbi szobákat nem sikerült eltávolítani a(z) %(groupId)s csoport összefoglalójából", "The room '%(roomName)s' could not be removed from the summary.": "Nem sikerült törölni az összefoglalóból ezt a szobát: '%(roomName)s'.", "Failed to remove a user from the summary of %(groupId)s": "Nem sikerült törölni az összefoglalóból ezt a felhasználót: %(groupId)s", - "The user '%(displayName)s' could not be removed from the summary.": "Nem sikerült törölni az összefoglalóból a(z) %(displayName)s felhasználót", + "The user '%(displayName)s' could not be removed from the summary.": "Nem sikerült törölni az összefoglalóból ezt a felhasználót: %(groupId)s.", "Light theme": "Világos téma", "Dark theme": "Sötét téma", "Unknown": "Ismeretlen", @@ -900,6 +906,7 @@ "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", "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", @@ -927,6 +934,7 @@ "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", "Addresses": "Címek", "collapse": "becsuk", "expand": "kinyit", @@ -976,7 +984,7 @@ "Failed to add tag %(tagName)s to room": "Nem sikerült hozzáadni a szobához ezt: %(tagName)s", "Clear filter": "Szűrő törlése", "Disable Community Filter Panel": "Közösség keresési panel tiltása", - "Did you know: you can use communities to filter your Riot.im experience!": "Tudtad, hogy a Riot.im élmény fokozásához használhatsz közösségeket?", + "Did you know: you can use communities to filter your Riot.im experience!": "Tudtad, hogy a közösségeket használhatod a Riot.im élmény fokozásához?", "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "A szűrő beállításához húzd a közösség avatarját a szűrő panel fölé a képernyő bal szélén. A szűrő panelen az avatarra kattintva bármikor leszűrheted azokat a szobákat és embereket akik a megadott közösséghez tartoznak.", "Your key share request has been sent - please check your other devices for key share requests.": "A kulcs megosztási kérést elküldtük - ellenőrizd a többi eszközödön a kulcs megosztási kéréseket.", "Key share requests are sent to your other devices automatically. If you rejected or dismissed the key share request on your other devices, click here to request the keys for this session again.": "A kulcs megosztási kérelem automatikusan el lett küldve a többi eszközödre. Ha elutasítottad vagy törölted a kérést a másik eszközön ide kattintva újra kérheted a kulcsokat.", @@ -984,6 +992,7 @@ "Key request sent.": "Kulcs kérés elküldve.", "Re-request encryption keys from your other devices.": "Kulcsok újrakérése a többi eszközödtől.", "%(user)s is a %(userRole)s": "%(user)s egy %(userRole)s", + "Changes made to your community might not be seen by other users for up to 30 minutes.": "A közösségedben végrehajtott változtatás valószínűleg legalább 30 percig nem lesz látható mások számára.", "Code": "Kód", "Debug Logs Submission": "Hibakeresési napló elküldése", "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contian messages.": "Ha a GitHubon keresztül küldted be a hibát, a hibakeresési napló segíthet nekünk a javításban. A napló felhasználási adatokat tartalmaz mint a felhasználói neved, az általad meglátogatott szobák vagy csoportok azonosítóját vagy alternatív nevét és mások felhasználói nevét. De nem tartalmazzák az üzeneteket.", @@ -998,163 +1007,13 @@ "Stickerpack": "Matrica csomag", "Sticker Messages": "Matrica üzenetek", "You don't currently have any stickerpacks enabled": "Nincs engedélyezett matrica csomagod", + "Click": "Kattints", + "here": "ide", + "to add some!": "hogy adj hozzá párat!", "Add a stickerpack": "Matrica csomag hozzáadása", "Hide Stickers": "Matricák elrejtése", "Show Stickers": "Matricák megjelenítése", + "Manage sticker packs": "Matrica csomagok kezelése", "Who can join this community?": "Ki tud csatlakozni ehhez a közösséghez?", - "Everyone": "Mindenki", - "Fetching third party location failed": "Nem sikerült lekérdezni a harmadik fél helyét", - "A new version of Riot is available.": "Elérhető egy új Riot verzió.", - "Couldn't load home page": "Nem sikerült betölteni a kezdőlapot", - "Send Account Data": "Fiókadatok küldése", - "All notifications are currently disabled for all targets.": "Minden céleszközön minden értesítés tiltva van.", - "Uploading report": "Jelentés feltöltése", - "Sunday": "Vasárnap", - "Notification targets": "Értesítések célpontja", - "Today": "Ma", - "Files": "Fájlok", - "You are not receiving desktop notifications": "Nem fogadsz asztali értesítéseket", - "Friday": "Péntek", - "Update": "Frissítés", - "What's New": "Újdonságok", - "Add an email address above to configure email notifications": "E-mail értesítések beállításához adj meg egy e-mail címet", - "Expand panel": "Panel kinyitása", - "On": "Be", - "%(count)s Members|other": "%(count)s tag", - "Filter room names": "Szobanevek szűrése", - "Changelog": "Változások", - "Waiting for response from server": "Várakozás a szerver válaszára", - "Send Custom Event": "Egyéni esemény elküldése", - "Advanced notification settings": "Haladó értesítési beállítások", - "Failed to send logs: ": "Hiba a napló küldésénél: ", - "delete the alias.": "becenév törlése.", - "To return to your account in future you need to set a password": "Hogy később visszaléphess a fiókodba, be kell állítanod egy jelszót", - "Forget": "Elfelejt", - "#example": "#példa", - "Hide panel": "Panel elrejtése", - "You cannot delete this image. (%(code)s)": "Nem törölheted ezt a képet. (%(code)s)", - "Cancel Sending": "Küldés megszakítása", - "This Room": "Ebben a szobában", - "The Home Server may be too old to support third party networks": "Lehet, hogy a saját szerver túl régi és nem támogatja a csatlakozást más hálózatokhoz", - "Resend": "Küldés újra", - "Room not found": "A szoba nem található", - "Messages containing my display name": "A profilnevemet tartalmazó üzenetek", - "Messages in one-to-one chats": "Személyes beszélgetések üzenetei", - "Unavailable": "Elérhetetlen", - "View Decrypted Source": "Visszafejtett forrás megjelenítése", - "Failed to update keywords": "Nem lehet frissíteni a kulcsszavakat", - "Notes:": "Jegyzetek:", - "remove %(name)s from the directory.": "%(name)s szoba törlése a listából.", - "Notifications on the following keywords follow rules which can’t be displayed here:": "Az alábbi kulcsszavakról jövő értesítések szabályait nem lehet itt megjeleníteni:", - "Safari and Opera work too.": "Safarival és Operával is működik.", - "Please set a password!": "Állíts be egy jelszót!", - "You have successfully set a password!": "Sikerült beállítani a jelszót!", - "An error occurred whilst saving your email notification preferences.": "Hiba történt az e-mail értesítési beállításaid mentése közben.", - "Explore Room State": "Szoba állapot felderítése", - "Source URL": "Forrás URL", - "Messages sent by bot": "Botok üzenetei", - "Filter results": "Találatok szűrése", - "Members": "Résztvevők", - "No update available.": "Nincs elérhető frissítés.", - "Noisy": "Hangos", - "Failed to get protocol list from Home Server": "Nem sikerült a protokoll listát lekérni a saját szerverről", - "Collecting app version information": "Alkalmazás verzió információk összegyűjtése", - "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Törlöd a szoba nevét (%(alias)s) és eltávolítod a listából ezt: %(name)s?", - "This will allow you to return to your account after signing out, and sign in on other devices.": "Így kijelentkezés után is vissza tudsz lépni a fiókodba, illetve más készülékekről is be tudsz lépni.", - "Keywords": "Kulcsszavak", - "Enable notifications for this account": "Értesítések engedélyezése ehhez a fiókhoz", - "Directory": "Könyvtár", - "Invite to this community": "Meghívás ebbe a közösségbe", - "Search for a room": "Szoba keresése", - "Messages containing keywords": "Kulcsszavakat tartalmazó üzenetek", - "Error saving email notification preferences": "Hiba az e-mail értesítési beállítások mentésekor", - "Tuesday": "Kedd", - "Enter keywords separated by a comma:": "Kulcsszavak vesszővel elválasztva:", - "Forward Message": "Üzenet továbbítása", - "You have successfully set a password and an email address!": "Sikerült beállítani a jelszavad és e-mail címed!", - "Remove %(name)s from the directory?": "Törlöd ezt a szobát a listából: %(name)s?", - "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "A Riot sok fejlett böngészőfunkciót használ, amelyeknek egy része egyáltalán nem, vagy csak kísérleti jelleggel érhető el a jelenlegi böngésződben.", - "Developer Tools": "Fejlesztői eszközök", - "Preparing to send logs": "Előkészülés napló küldéshez", - "Enable desktop notifications": "Asztali értesítések engedélyezése", - "Remember, you can always set an email address in user settings if you change your mind.": "Ha meggondolod magad, bármikor beállíthatod az e-mail címed a felhasználói beállításoknál.", - "Explore Account Data": "Fiókadatok felderítése", - "Remove from Directory": "Törlés a listából", - "Saturday": "Szombat", - "I understand the risks and wish to continue": "Megértettem a kockázatot és folytatom", - "Direct Chat": "Közvetlen csevegés", - "The server may be unavailable or overloaded": "A szerver nem elérhető vagy túlterhelt", - "Reject": "Elutasít", - "Failed to set Direct Message status of room": "Nem lehet beállítani a szoba közvetlen beszélgetés státuszát", - "Monday": "Hétfő", - "All messages (noisy)": "Minden üzenet (hangos)", - "Enable them now": "Engedélyezés most", - "Messages containing my user name": "A felhasználónevemet tartalmazó üzenetek", - "Toolbox": "Eszköztár", - "Collecting logs": "Naplók összegyűjtése", - "more": "tovább", - "GitHub issue link:": "GitHub hibajegy hivatkozás:", - "You must specify an event type!": "Meg kell jelölnöd az eseménytípust!", - "(HTTP status %(httpStatus)s)": "(HTTP állapot: %(httpStatus)s)", - "Invite to this room": "Meghívás a szobába", - "Please install Chrome or Firefox for the best experience.": "A legjobb élmény érdekében telepíts Chrome vagy Firefox böngészőt.", - "Failed to get public room list": "Nem sikerült lekérdezni a nyilvános szobák listáját", - "Quote": "Idéz", - "Send logs": "Naplófájlok elküldése", - "All messages": "Minden üzenet", - "Call invitation": "Hívás meghívó", - "Downloading update...": "Frissítés letöltése...", - "State Key": "Állapotkulcs", - "Failed to send custom event.": "Nem sikerült elküldeni az egyéni eseményt.", - "What's new?": "Mik az újdonságok?", - "Notify me for anything else": "Értesíts minden egyéb esetben", - "When I'm invited to a room": "Amikor meghívnak egy szobába", - "Click here to create a GitHub issue.": "Kattints ide GitHub hibajegy nyitásához .", - "Can't update user notification settings": "Nem lehet frissíteni az értesítési beállításokat", - "Notify for all other messages/rooms": "Értesítés minden más üzenethez/szobához", - "Unable to look up room ID from server": "Nem lehet a szoba azonosítóját megkeresni a szerveren", - "Couldn't find a matching Matrix room": "Nem található a keresett Matrix szoba", - "All Rooms": "Minden szobában", - "You cannot delete this message. (%(code)s)": "Nem törölheted ezt az üzenetet. (%(code)s)", - "Thursday": "Csütörtök", - "Search…": "Keresés…", - "Logs sent": "Napló elküldve", - "Back": "Vissza", - "Reply": "Válasz", - "Show message in desktop notification": "Üzenetek megjelenítése az asztali értesítéseknél", - "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "A hibakereső napló alkalmazás használati adatokat tartalmaz beleértve a felhasználói nevedet, az általad meglátogatott szobák és csoportok azonosítóit alternatív neveit és más felhasználói neveket. Csevegés üzenetek szövegét nem tartalmazza.", - "Unhide Preview": "Előnézet mutatása", - "Unable to join network": "Nem sikerült kapcsolódni a hálózathoz", - "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Egy másik, nem Riot-klienssel állítothattad be. A Riotban módosítani nem tudod ezeket, de érvényben vannak", - "Sorry, your browser is not able to run Riot.": "Elnézést, a böngésződben nem fut a Riot.", - "Uploaded on %(date)s by %(user)s": "Feltöltötte %(user)s ekkor: %(date)s", - "Messages in group chats": "Csoportszobák üzenetei", - "Yesterday": "Tegnap", - "Error encountered (%(errorDetail)s).": "Hiba történt (%(errorDetail)s).", - "Login": "Bejelentkezés", - "Low Priority": "Alacsony prioritás", - "Unable to fetch notification target list": "Nem sikerült letölteni az értesítési célok listáját", - "Set Password": "Jelszó beállítása", - "Enable audible notifications in web client": "Hangértesítések engedélyezése a webkliensben", - "Permalink": "Állandó hivatkozás", - "Off": "Ki", - "Riot does not know how to join a room on this network": "A Riot nem tud csatlakozni szobához ezen a hálózaton", - "Mentions only": "Csak ha megemlítenek", - "Wednesday": "Szerda", - "You can now return to your account after signing out, and sign in on other devices.": "Most már kijelentkezés után is vissza tudsz lépni a fiókodba, és más készülékekről is be tudsz lépni.", - "Enable email notifications": "E-mail értesítések engedélyezése", - "Event Type": "Esemény típusa", - "Download this file": "Fájl letöltése", - "Pin Message": "Üzenet rögzítése", - "Failed to change settings": "A beállítások megváltoztatása nem sikerült", - "View Community": "Közösség megtekintése", - "%(count)s Members|one": "%(count)s tag", - "Event sent!": "Az esemény elküldve!", - "View Source": "Forrás megjelenítése", - "Event Content": "Esemény tartalma", - "Thank you!": "Köszönjük!", - "Collapse panel": "Panel becsukása", - "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Ebben a böngészőben az alkalmazás felülete tele lehet hibával, és az is lehet, hogy egyáltalán nem működik. Ha így is ki szeretnéd próbálni, megteheted, de ha valami gondod van, nem tudunk segíteni!", - "Checking for an update...": "Frissítés keresése...", - "There are advanced notifications which are not shown here": "Vannak itt nem látható, haladó értesítések" + "Everyone": "Mindenki" } diff --git a/src/i18n/strings/nl.json b/src/i18n/strings/nl.json index 5f0b3fc683..d4bda9c6da 100644 --- a/src/i18n/strings/nl.json +++ b/src/i18n/strings/nl.json @@ -29,6 +29,7 @@ "Banned users": "Verbannen gebruikers", "Bans user with given id": "Verbant de gebruiker met het gegeven ID", "Blacklisted": "Buitengesloten", + "Bug Report": "Bug report", "Bulk Options": "Bulk opties", "Call Timeout": "Gesprek time-out", "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Kan niet met de thuisserver verbinden via HTTP wanneer er een HTTPS-URL in je browser balk staat. Gebruik HTTPS of activeer onveilige scripts.", @@ -261,6 +262,7 @@ "Forgot your password?": "Wachtwoord vergeten?", "For security, this session has been signed out. Please sign in again.": "Voor veiligheidsredenen is deze sessie uitgelogd. Log alsjeblieft opnieuw in.", "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.": "In verband met veiligheidsredenen zullen alle end-to-endbeveiligingsleutels van deze browser verwijderd worden. Als je je gespreksgeschiedenis van toekomstige Riot sessies wilt kunnen ontsleutelen, exporteer en bewaar dan de ruimte sleutels.", + "Found a bug?": "Een fout gevonden?", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s van %(fromPowerLevel)s naar %(toPowerLevel)s", "Guest access is disabled on this Home Server.": "Gasttoegang is uitgeschakeld op deze thuisserver.", "Guests cannot join this room even if explicitly invited.": "Gasten kunnen niet tot deze ruimte toetreden, zelfs als ze expliciet uitgenodigd zijn.", @@ -338,6 +340,7 @@ "Press to start a chat with someone": "Druk op om een gesprek met iemand te starten", "Remove %(threePid)s?": "%(threePid)s verwijderen?", "%(senderName)s requested a VoIP conference.": "%(senderName)s heeft een VoIP-gesprek aangevraagd.", + "Report it": "Melden", "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.": "Het wachtwoord veranderen betekent momenteel dat alle end-to-endbeveiligingssleutels op alle apparaten veranderen waardoor versleutelde gespreksgeschiedenis onleesbaar wordt, behalve als je eerst de ruimte sleutels exporteert en daarna opnieuw importeert. Dit zal in de toekomst verbeterd worden.", "Results from DuckDuckGo": "Resultaten van DuckDuckGo", "Return to login screen": "Naar het inlogscherm terugkeren", @@ -651,6 +654,7 @@ "Do you want to load widget from URL:": "Wil je de widget laden van de URL:", "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)", "Integrations Error": "Integratiesfout", "Publish this room to the public in %(domain)s's room directory?": "Deze ruimte publiekelijk maken in %(domain)s's ruimte catalogus?", @@ -659,6 +663,7 @@ "NOTE: Apps are not end-to-end encrypted": "OPMERKING: Apps zijn niet end-to-endbeveiligd", "Revoke widget access": "Toegang tot widget intrekken", "Sets the room topic": "Wijzigt het ruimte-onderwerp", + "Show Apps": "Apps Weergeven", "The maximum permitted number of widgets have already been added to this room.": "Het maximum aantal toegestane widgets is al aan deze ruimte toegevoegd.", "To get started, please pick a username!": "Om te beginnen, kies een gebruikersnaam!", "Unable to create widget.": "Niet in staat om een widget te maken.", @@ -717,6 +722,7 @@ "Send": "Verstuur", "Message Pinning": "Boodschap vastpinnen", "Message Replies": "Antwoorden op bericht", + "Presence Management": "Presentie Beheer", "Tag Panel": "Label Paneel", "Disable Emoji suggestions while typing": "Emoji suggesties tijdens het typen uitzetten", "Hide avatar changes": "Avatar veranderingen verbergen", @@ -882,6 +888,7 @@ "collapse": "inklappen", "expand": "openklappen", "Custom of %(powerLevel)s": "Aangepast rank van %(powerLevel)s", + "Quote": "Citeren", "And %(count)s more...|other": "En %(count)s meer...", "Matrix ID": "Matrix ID", "Matrix Room ID": "Matrix Ruimte ID", @@ -918,6 +925,7 @@ "Leave Community": "Gemeenschap Verlaten", "Leave %(groupName)s?": "%(groupName)s verlaten?", "Leave": "Verlaten", + "Unable to leave room": "De ruimte kon niet verlaten worden", "Community Settings": "Gemeenschapsinstellingen", "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Deze ruimtes worden aan gemeenschapsleden getoond op de gemeenschapspagina. Gemeenschapsleden kunnen tot de ruimtes toetreden door er op te klikken.", "%(inviter)s has invited you to join this community": "%(inviter)s heeft jou uitgenodigd om tot deze gemeenschap toe te treden", @@ -929,6 +937,8 @@ "Community %(groupId)s not found": "Gemeenschap %(groupId)s is niet gevonden", "This Home server does not support communities": "Deze Thuisserver ondersteunt geen gemeenschappen", "Failed to load %(groupId)s": "Het is niet gelukt om %(groupId)s te laden", + "Cryptography data migrated": "Cryptografie gegevens zijn gemigreerd", + "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.": "Een eenmalige migratie van cryptografie gegevens heeft plaatsgevonden. Eind-tot-eind versleuteling zal niet werken als je terug gaat naar een oudere versie van Riot. Log eerst uit op Riot als je eind-tot-eind versleuteling wil gebruiken op een oudere versie. Exporteer je sleutels en importeer ze achteraf weer als je de berichtgeschiedenis wilt behouden.", "Old cryptography data detected": "Oude cryptografie gegevens gedetecteerd", "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.": "Er zijn gegevens van een oudere versie van Riot gedetecteerd. Dit zal eind-tot-eind versleuteling laten storen in de oudere versie. Eind-tot-eind berichten dat recent zijn uitgewisseld zal misschien niet ontsleutelbaar zijn in deze versie. Dit zou er misschien ook voor kunnen zorgen dat berichten die zijn uitgewisseld in deze versie falen. Indien je problemen ervaart, log opnieuw in. Om de berichtgeschiedenis te behouden, exporteer de sleutels en importeer ze achteraf weer.", "Your Communities": "Jouw Gemeenschappen", @@ -984,177 +994,5 @@ "Clear filter": "Filter vrijmaken", "Failed to set direct chat tag": "Het is niet gelukt om de 'privégesprek' label in te stellen", "Failed to remove tag %(tagName)s from room": "Het is niet gelukt om de label %(tagName)s van de ruimte te verwijderen", - "Failed to add tag %(tagName)s to room": "Het is niet gelukt om de label %(tagName)s aan deze ruimte toe te voegen", - "Stickerpack": "Stickerpakket", - "Sticker Messages": "Sticker Berichten", - "You don't currently have any stickerpacks enabled": "Je hebt momenteel geen stickerpakketten aan staan", - "Add a stickerpack": "Stickerpakket toevoegen", - "Hide Stickers": "Stickers verbergen", - "Show Stickers": "Stickers weergeven", - "Seen by %(displayName)s (%(userName)s) at %(dateTime)s": "Gezien door %(displayName)s (%(userName)s) op %(dateTime)s", - "Code": "Code", - "Unable to join community": "Je kon niet tot de gemeenschap toetreden", - "Unable to leave community": "Je kon de gemeenschap niet verlaten", - "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Veranderingen die aan je gemeenschap naam en avatar zijn aangebracht zullen misschien niet gezien worden door anderen tot maximaal 30 minuten.", - "Join this community": "Tot deze gemeenschap toetreden", - "Who can join this community?": "Wie kan tot deze gemeenschap toetreden?", - "Everyone": "Iedereen", - "Leave this community": "Deze gemeenschap verlaten", - "Debug Logs Submission": "Debug Logs Indienen", - "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contian messages.": "Als je een bug via Github hebt ingediend kunnen debug logs ons helpen om het probleem te vinden. Debug logs bevatten applicatie-gebruik data inclusief je gebruikersnaam, de ID's of namen van de ruimtes en groepen die je hebt bezocht en de gebruikersnamen van andere gebruikers. Ze bevatten geen berichten.", - "Submit debug logs": "Debug logs indienen", - "Opens the Developer Tools dialog": "Opent het Ontwikkelaars Gereedschappen dialoog", - "Fetching third party location failed": "Het ophalen van de locatie van de derde partij is mislukt", - "A new version of Riot is available.": "Er is een nieuwe versie van Riot beschikbaar.", - "I understand the risks and wish to continue": "Ik begrijp de risico's en wil graag verder gaan", - "Couldn't load home page": "Kon de home pagina niet laden", - "Send Account Data": "Stuur account informatie", - "All notifications are currently disabled for all targets.": "Alle meldingen zijn momenteel uitgeschakeld voor alle doelen.", - "Uploading report": "Rapport uploaden", - "Sunday": "Zondag", - "Notification targets": "Meldingsdoelen", - "Today": "Vandaag", - "Files": "Bestanden", - "You are not receiving desktop notifications": "Je ontvangt momenteel geen desktopmeldingen", - "Friday": "Vrijdag", - "Update": "Bijwerken", - "What's New": "Wat is er nieuw", - "Add an email address above to configure email notifications": "Voeg een e-mailadres toe om e-mailmeldingen te ontvangen", - "Expand panel": "Paneel uitklappen", - "On": "Aan", - "%(count)s Members|other": "%(count)s Deelnemers", - "Filter room names": "Filter kamernamen", - "Changelog": "Logboek van wijzigingen", - "Waiting for response from server": "Wachten op antwoord van de server", - "Send Custom Event": "Verzend aangepast evenement", - "Advanced notification settings": "Geavanceerde meldingsinstellingen", - "delete the alias.": "verwijder de alias.", - "To return to your account in future you need to set a password": "Om in de toekomst naar je account terug te gaan moet je een wachtwoord instellen", - "Forget": "Vergeten", - "#example": "#voorbeeld", - "Hide panel": "Paneel verbergen", - "You cannot delete this image. (%(code)s)": "Je kunt deze afbeelding niet verwijderen. (%(code)s)", - "Cancel Sending": "Versturen annuleren", - "This Room": "Deze kamer", - "The Home Server may be too old to support third party networks": "De thuisserver is misschien te oud om netwerken van derde partijen te ondersteunen", - "Resend": "Opnieuw verzenden", - "Error saving email notification preferences": "Fout bij het opslaan van de meldingsvoorkeuren voor e-mail", - "Messages containing my display name": "Berichten die mijn weergavenaam bevatten", - "Messages in one-to-one chats": "Berichten in één-op-één-gesprekken", - "Unavailable": "Niet beschikbaar", - "View Decrypted Source": "Bekijk ontsleutelde bron", - "Failed to update keywords": "Trefwoorden bijwerken mislukt", - "remove %(name)s from the directory.": "verwijder %(name)s uit de kamerlijst.", - "Notifications on the following keywords follow rules which can’t be displayed here:": "Meldingen op de volgende trefwoorden volgen regels die hier niet kunnen worden getoond:", - "Safari and Opera work too.": "Safari en Opera werken ook.", - "Please set a password!": "Stel een wachtwoord in!", - "You have successfully set a password!": "U heeft met succes een wachtwoord ingesteld!", - "An error occurred whilst saving your email notification preferences.": "Er is een fout opgetreden tijdens het opslaan van uw e-mailmeldingsvoorkeuren.", - "Explore Room State": "Verken Ruimtetoestand", - "Source URL": "Bron-URL", - "Messages sent by bot": "Berichten verzonden door een bot", - "Filter results": "Resultaten filteren", - "Members": "Leden", - "No update available.": "Geen update beschikbaar.", - "Noisy": "Luidruchtig", - "Failed to get protocol list from Home Server": "Protocollijst ophalen van de homeserver mislukt", - "Collecting app version information": "App-versieinformatie verzamelen", - "Delete the room alias %(alias)s and remove %(name)s from the directory?": "De alias %(alias)s verwijderen en %(name)s uit de kamerlijst verwijderen?", - "This will allow you to return to your account after signing out, and sign in on other devices.": "Hiermee kunt u naar uw account terugkeren nadat u zich heeft afgemeld, en u aanmelden op andere apparaten.", - "Keywords": "Trefwoorden", - "Enable notifications for this account": "Meldingen voor dit account aanzetten", - "Directory": "Kamerlijst", - "Invite to this community": "Nodig uit in deze community", - "Search for a room": "Een kamer opzoeken", - "Messages containing keywords": "Berichten die trefwoorden bevatten", - "Room not found": "De kamer is niet gevonden", - "Tuesday": "Dinsdag", - "Enter keywords separated by a comma:": "Voeg trefwoorden toe, gescheiden door een komma:", - "Search…": "Zoeken…", - "You have successfully set a password and an email address!": "Het instellen van een wachtwoord en e-mailadres is geslaagd!", - "Remove %(name)s from the directory?": "%(name)s uit de kamerlijst verwijderen?", - "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot gebrukt veel geavanceerde browserfuncties, waarvan enkele niet (of experimenteel) in uw webbrowser beschikbaar zijn.", - "Developer Tools": "Ontwikkelaarsgereedschap", - "Enable desktop notifications": "Desktopmeldingen aanzetten", - "Explore Account Data": "Bekijk account informatie", - "Remove from Directory": "Uit de kamerlijst verwijderen", - "Saturday": "Zaterdag", - "Remember, you can always set an email address in user settings if you change your mind.": "Onthoud dat u altijd een e-mailadres in kan stellen in de gebruikersinstellingen als u zich bedenkt.", - "Direct Chat": "Privégesprek", - "The server may be unavailable or overloaded": "De server is misschien niet beschikbaar of overbelast", - "Reject": "Afwijzen", - "Failed to set Direct Message status of room": "Het is mislukt om de directe-berichtenstatus van de kamer in te stellen", - "Monday": "Maandag", - "All messages (noisy)": "Alle berichten (luid)", - "Enable them now": "Deze nu aanzetten", - "Messages containing my user name": "Berichten die mijn gebruikersnaam bevatten", - "Toolbox": "Eigenschappen", - "Collecting logs": "Logboeken verzamelen", - "more": "meer", - "You must specify an event type!": "Je moet een event-type specificeren!", - "(HTTP status %(httpStatus)s)": "(HTTP-status %(httpStatus)s)", - "Invite to this room": "Uitnodigen voor deze kamer", - "Please install Chrome or Firefox for the best experience.": "Installeer alstublieft Chrome of Firefox voor de beste gebruikerservaring.", - "Failed to get public room list": "Lijst met publieke kamers ophalen mislukt", - "Send logs": "Logboeken versturen", - "All messages": "Alle berichten", - "Call invitation": "Oproep-uitnodiging", - "Downloading update...": "Update aan het downloaden...", - "State Key": "Toestandssleutel", - "Failed to send custom event.": "Aangepast Event verzenden mislukt.", - "What's new?": "Wat is er nieuw?", - "Notify me for anything else": "Stuur een melding voor al het andere", - "When I'm invited to a room": "Wanneer ik uitgenodigd word voor een kamer", - "Can't update user notification settings": "Het is niet gelukt om de meldingsinstellingen van de gebruiker bij te werken", - "Notify for all other messages/rooms": "Stuur een melding voor alle andere berichten/kamers", - "Unable to look up room ID from server": "Het is mislukt om de kamer-ID op te halen van de server", - "Couldn't find a matching Matrix room": "Het is niet gelukt om een bijbehorende Matrix-kamer te vinden", - "All Rooms": "Alle kamers", - "You cannot delete this message. (%(code)s)": "Je kunt dit bericht niet verwijderen. (%(code)s)", - "Thursday": "Donderdag", - "Forward Message": "Bericht doorsturen", - "Back": "Terug", - "Reply": "Beantwoord", - "Show message in desktop notification": "Toon boodschap in bureaublad popup", - "Unhide Preview": "Zichtbaar maken preview", - "Unable to join network": "Het is mislukt om toe te treden tot dit netwerk", - "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Je hebt ze mogelijk ingesteld in een andere client dan Riot. Je kunt ze niet aanpassen in Riot maar ze zijn wel actief", - "Sorry, your browser is not able to run Riot.": "Sorry, uw browser werkt niet met Riot.", - "Uploaded on %(date)s by %(user)s": "Geüpload op %(date)s door %(user)s", - "Messages in group chats": "Berichten in groepsgesprekken", - "Yesterday": "Gisteren", - "Error encountered (%(errorDetail)s).": "Fout ondervonden (%(errorDetail)s).", - "Login": "Aanmelden", - "Low Priority": "Lage prioriteit", - "Unable to fetch notification target list": "Het is mislukt om de lijst van notificatiedoelen op te halen", - "Set Password": "Wachtwoord instellen", - "Enable audible notifications in web client": "Geluidsmeldingen in de webclient aanzetten", - "Permalink": "Permanente link", - "Off": "Uit", - "Riot does not know how to join a room on this network": "Riot weet niet hoe het moet deelnemen in een kamer op dit netwerk", - "Mentions only": "Alleen vermeldingen", - "Wednesday": "Woensdag", - "You can now return to your account after signing out, and sign in on other devices.": "U kunt nu terugkeren naar uw account nadat u bent afgemeld, en u aanmelden op andere apparaten.", - "Enable email notifications": "E-mailmeldingen aanzetten", - "Event Type": "Event-type", - "Download this file": "Download dit bestand", - "Pin Message": "Bericht vastpinnen", - "Failed to change settings": "Instellingen wijzigen mislukt", - "View Community": "Gemeenschap Weergeven", - "%(count)s Members|one": "%(count)s Deelnemer", - "Event sent!": "Event verstuurd!", - "View Source": "Bekijk bron", - "Event Content": "Event-inhoud", - "Thank you!": "Bedankt!", - "Collapse panel": "Paneel inklappen", - "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Met uw huidige browser kan de applicatie er volledig incorrect uitzien. Tevens is het mogelijk dat niet alle functies naar behoren werken. U kunt doorgaan als u het toch wil proberen, maar bij problemen bent u volledig op uzelf aangewezen!", - "Checking for an update...": "Aan het kijken voor een update...", - "There are advanced notifications which are not shown here": "Er zijn geavanceerde notificaties die hier niet getoond worden", - "Logs sent": "Logs verstuurd", - "Click here to create a GitHub issue.": "Klik hier om een Github opgave in te dienen.", - "GitHub issue link:": "GitHub opgave link:", - "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Debug logs bevatten applicatie-gebruik data inclusief je gebruikersnaam, de ID's of namen van de ruimtes en groepen die je hebt bezocht en de gebruikersnamen van andere gebruikers. Ze bevatten geen berichten.", - "Failed to send logs: ": "Het is niet gelukt om de logs te versturen: ", - "Notes:": "Constateringen:", - "Preparing to send logs": "Voorbereiden om logs te versturen" + "Failed to add tag %(tagName)s to room": "Het is niet gelukt om de label %(tagName)s aan deze ruimte toe te voegen" } diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index a68e612155..d732be55da 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -13,6 +13,7 @@ "Banned users": "Заблокированные пользователи", "Bans user with given id": "Блокирует пользователя с заданным ID", "Blacklisted": "В черном списке", + "Bug Report": "Отчет об ошибке", "Bulk Options": "Групповые параметры", "Can't load user settings": "Невозможно загрузить пользовательские настройки", "Changes to who can read history will only apply to future messages in this room": "Изменения того, кто может прочитать историю, будут применяться только к будущим сообщениям в этой комнате", @@ -60,6 +61,7 @@ "Forget room": "Забыть комнату", "Forgot your password?": "Забыли пароль?", "For security, this session has been signed out. Please sign in again.": "Для обеспечения безопасности ваша сессия была завершена. Пожалуйста, войдите снова.", + "Found a bug?": "Нашли ошибку?", "Hangup": "Закончить", "Historical": "Архив", "Homeserver is": "Домашний сервер это", @@ -312,6 +314,7 @@ "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s удалил свое отображаемое имя (%(oldDisplayName)s).", "%(senderName)s removed their profile picture.": "%(senderName)s удалил свое изображение профиля.", "%(senderName)s requested a VoIP conference.": "%(senderName)s хочет начать VoIP-конференцию.", + "Report it": "Сообщить об этом", "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.": "Сброс пароля на данный момент сбрасывает ключи шифрования на всех устройствах, делая зашифрованную историю чатов нечитаемой. Чтобы избежать этого, экспортируйте ключи комнат и импортируйте их после сброса пароля. В будущем это будет исправлено.", "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 не получил разрешение на отправку уведомлений, пожалуйста, попробуйте снова", @@ -651,6 +654,7 @@ "Do you want to load widget from URL:": "Загрузить виджет из URL-адреса:", "Edit": "Редактировать", "Enable automatic language detection for syntax highlighting": "Включить автоматическое определение языка для подсветки синтаксиса", + "Hide Apps": "Скрыть приложения", "Hide join/leave messages (invites/kicks/bans unaffected)": "Скрыть сообщения о входе/выходе (не применяется к приглашениям/выкидываниям/банам)", "Integrations Error": "Ошибка интеграции", "AM": "AM", @@ -658,6 +662,7 @@ "NOTE: Apps are not end-to-end encrypted": "ПРИМЕЧАНИЕ: приложения не защищены сквозным шифрованием", "Revoke widget access": "Отозвать доступ к виджетам", "Sets the room topic": "Задать тему комнаты", + "Show Apps": "Показать приложения", "The maximum permitted number of widgets have already been added to this room.": "Максимально допустимое количество виджетов уже добавлено в эту комнату.", "To get started, please pick a username!": "Чтобы начать, выберите имя пользователя!", "Unable to create widget.": "Не удалось создать виджет.", @@ -714,6 +719,7 @@ "Description": "Описание", "Name or matrix ID": "Имя или matrix ID", "Unable to accept invite": "Невозможно принять приглашение", + "Unable to leave room": "Невозможно покинуть комнату", "Leave": "Покинуть", "Failed to invite the following users to %(groupId)s:": "Не удалось пригласить следующих пользователей в %(groupId)s:", "Failed to remove '%(roomName)s' from %(groupId)s": "Не удалось удалить '%(roomName)s' из %(groupId)s", @@ -884,6 +890,7 @@ "Visibility in Room List": "Видимость в списке комнат", "Visible to everyone": "Видимый для всех", "Only visible to community members": "Только участникам сообщества", + "Presence Management": "Управление присутствием", "Hide avatar changes": "Скрыть изменения аватара", "Hide display name changes": "Скрыть изменения отображаемого имени", "Enable inline URL previews by default": "Включить просмотр URL-адресов по умолчанию", @@ -917,6 +924,7 @@ "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.": "Что-то пошло не так, во время отображения ваших сообществ.", + "Tag Panel": "Панель тегов", "Delete %(count)s devices|other": "Удалить %(count)s устройств", "Delete %(count)s devices|one": "Удалить устройство", "Select devices": "Выбрать устройства", @@ -950,7 +958,7 @@ "Send a reply (unencrypted)…": "Отправить ответ (незашифрованный)…", "Send an encrypted message…": "Отправить зашифрованное сообщение…", "Send a message (unencrypted)…": "Отправить сообщение (незашифрованное)…", - "Replying": "Отвечает", + "Replying": "Отвечая", "Minimize apps": "Свернуть приложения", "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.": "Подробнее о том, как мы используем аналитику.", @@ -984,6 +992,7 @@ "%(user)s is a %(userRole)s": "%(user)s является %(userRole)s", "Your key share request has been sent - please check your other devices for key share requests.": "Ваш запрос на передачу ключей отправлен - пожалуйста, проверьте другие ваши устройства на запросы передачи ключей.", "Key share requests are sent to your other devices automatically. If you rejected or dismissed the key share request on your other devices, click here to request the keys for this session again.": "Запросы передачи ключей автоматически отправляются на другие устройства. Если вы отклонили или отменили запрос на передачу ключей на других устройствах, нажмите здесь, чтобы запросить ключи для этого сеанса повторно.", + "Changes made to your community might not be seen by other users for up to 30 minutes.": "Изменения, сделанные в вашем сообществе, могут не отображаться для других пользователей в течение 30 минут.", "Code": "Код", "Debug Logs Submission": "Отправка журналов отладки", "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contian messages.": "Если вы отправили ошибку через GitHub, журналы отладки могут помочь нам выявить проблему. Журналы отладки содержат данные об использовании приложения, включая ваше имя пользователя, идентификаторы или псевдонимы комнат или групп, которые вы посетили, а также имена других пользователей. Они не содержат сообщений.", @@ -995,165 +1004,9 @@ "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Изменения имени и аватара, внесенные в ваше сообщество, могут не отображаться другим пользователям в течение 30 минут.", "Join this community": "Присоединиться к сообществу", "Leave this community": "Покинуть это сообщество", + "here": "здесь", + "to add some!": "для добавления!", + "Click": "Нажмите", "Who can join this community?": "Кто может присоединиться к этому сообществу?", - "Everyone": "Все", - "Stickerpack": "Этикетки", - "Sticker Messages": "Сообщения этикеткой", - "Add a stickerpack": "Добавить этикетки", - "Hide Stickers": "Скрыть этикетки", - "Show Stickers": "Показать этикетки", - "Fetching third party location failed": "Не удалось извлечь местоположение третьей стороны", - "A new version of Riot is available.": "Доступна новая версия Riot.", - "I understand the risks and wish to continue": "Я понимаю риски и желаю продолжить", - "Couldn't load home page": "Не удалось загрузить домашнюю страницу", - "Send Account Data": "Отправить данные аккаунта", - "All notifications are currently disabled for all targets.": "Все оповещения для всех устройств отключены.", - "Uploading report": "Отправка отчета", - "Sunday": "Воскресенье", - "Notification targets": "Цели уведомления", - "Today": "Сегодня", - "Files": "Файлы", - "You are not receiving desktop notifications": "Вы не получаете уведомления на рабочем столе", - "Friday": "Пятница", - "Update": "Обновление", - "What's New": "Что нового", - "Add an email address above to configure email notifications": "Добавьте email адрес для оповещений", - "Expand panel": "Развернуть панель", - "On": "Включить", - "%(count)s Members|other": "%(count)s членов", - "Filter room names": "Фильтр по названию комнат", - "Changelog": "История изменений", - "Waiting for response from server": "Ожидание ответа от сервера", - "Uploaded on %(date)s by %(user)s": "Отправлено %(date)s для %(user)s", - "Send Custom Event": "Отправить индивидуальное мероприятие", - "Advanced notification settings": "Дополнительные параметры уведомлений", - "Failed to send logs: ": "Не удалось отправить журналы: ", - "delete the alias.": "удалить псевдоним.", - "To return to your account in future you need to set a password": "Чтобы вернуться к учетной записи в будущем, необходимо задать пароль", - "Forget": "Забыть", - "#example": "#пример", - "Hide panel": "Скрыть панель", - "You cannot delete this image. (%(code)s)": "Это изображение нельзя удалить. (%(code)s)", - "Cancel Sending": "Отменить отправку", - "This Room": "Эта комната", - "The Home Server may be too old to support third party networks": "Домашний сервер может быть слишком старым для поддержки сетей сторонних производителей", - "Noisy": "Со звуком", - "Room not found": "Комната не найдена", - "Messages containing my display name": "Сообщения, содержащие мое имя", - "Messages in one-to-one chats": "Сообщения в индивидуальных чатах", - "Unavailable": "Недоступен", - "Error saving email notification preferences": "Ошибка при сохранении настроек уведомлений по email", - "View Decrypted Source": "Просмотр расшифрованного источника", - "Failed to update keywords": "Не удалось обновить ключевые слова", - "Notes:": "Заметки:", - "remove %(name)s from the directory.": "удалить %(name)s из каталога.", - "Notifications on the following keywords follow rules which can’t be displayed here:": "Уведомления по следующим ключевым словам соответствуют правилам, которые нельзя отобразить здесь:", - "Safari and Opera work too.": "Safari и Opera работают тоже.", - "Please set a password!": "Пожалуйста, установите пароль!", - "You have successfully set a password!": "Вы успешно установили пароль!", - "An error occurred whilst saving your email notification preferences.": "Возникла ошибка при сохранении настроек оповещения по email.", - "Explore Room State": "Просмотр статуса комнаты", - "Source URL": "Исходный URL-адрес", - "Messages sent by bot": "Сообщения, отправленные ботом", - "Filter results": "Фильтрация результатов", - "Members": "Участники", - "No update available.": "Нет доступных обновлений.", - "Resend": "Переотправить", - "Failed to get protocol list from Home Server": "Не удалось получить список протоколов с домашнего сервера", - "Collecting app version information": "Сбор информации о версии приложения", - "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Удалить псевдоним комнаты %(alias)s и удалить %(name)s из каталога?", - "This will allow you to return to your account after signing out, and sign in on other devices.": "Это позволит вам вернуться к учетной записи после выхода из системы и войти на других устройствах.", - "Keywords": "Ключевые слова", - "Enable notifications for this account": "Включить уведомления для этой учетной записи", - "Directory": "Каталог", - "Invite to this community": "Пригласить в это сообщество", - "Search for a room": "Поиск комнаты", - "Messages containing keywords": "Сообщения, содержащие определенные ключевые слова", - "View Source": "Просмотр источника", - "Tuesday": "Вторник", - "Enter keywords separated by a comma:": "Введите ключевые слова, разделенные запятой:", - "Search…": "Поиск.…", - "You have successfully set a password and an email address!": "Вы успешно установили пароль и адрес email!", - "Remove %(name)s from the directory?": "Удалить %(name)s из каталога?", - "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot использует многие передовые возможности браузера, некоторые из которых недоступны или являются экспериментальным в вашем текущем браузере.", - "Developer Tools": "Инструменты разработчика", - "Preparing to send logs": "Подготовка к отправке журналов", - "Enable desktop notifications": "Включить оповещения на рабочем столе", - "Explore Account Data": "Просмотр данных аккаунта", - "All messages (noisy)": "Все сообщения (со звуком)", - "Saturday": "Суббота", - "Remember, you can always set an email address in user settings if you change your mind.": "Помните, что вы всегда сможете задать адрес email в настройках пользователя, если передумаете.", - "Direct Chat": "Прямой чат", - "The server may be unavailable or overloaded": "Сервер, вероятно, недоступен или перегружен", - "Reject": "Отклонить", - "Failed to set Direct Message status of room": "Не удалось установить статус прямого сообщения в комнате", - "Monday": "Понедельник", - "Remove from Directory": "Удалить из каталога", - "Enable them now": "Включить сейчас", - "Messages containing my user name": "Сообщение, содержащие мое имя пользователя", - "Toolbox": "Панель инструментов", - "Collecting logs": "Сбор журналов", - "more": "больше", - "GitHub issue link:": "Ссылка на проблему в GitHub:", - "You must specify an event type!": "Необходимо указать тип мероприятия!", - "(HTTP status %(httpStatus)s)": "(статус HTTP %(httpStatus)s)", - "Invite to this room": "Пригласить в комнату", - "Please install Chrome or Firefox for the best experience.": "Лучший опыт вы получите, установив Chrome или Firefox.", - "Failed to get public room list": "Не удалось получить список общедоступных комнат", - "Send logs": "Отправка журналов", - "All messages": "Все сообщения", - "Call invitation": "Пригласительный звонок", - "Downloading update...": "Загрузка обновления...", - "State Key": "Ключ состояния", - "Failed to send custom event.": "Не удалось отправить индивидуальное мероприятие.", - "What's new?": "Что нового?", - "Notify me for anything else": "Уведомлять во всех остальных случаях", - "When I'm invited to a room": "Когда меня приглашают в комнату", - "Click here to create a GitHub issue.": "Нажмите здесь для создания запроса о проблеме на GitHub.", - "Can't update user notification settings": "Не удается обновить пользовательские настройки оповещения", - "Notify for all other messages/rooms": "Уведомлять обо всех других сообщениях/комнатах", - "Unable to look up room ID from server": "Не удалось найти ID комнаты на сервере", - "Couldn't find a matching Matrix room": "Не удалось найти подходящую комнату Matrix", - "All Rooms": "Все комнаты", - "You cannot delete this message. (%(code)s)": "Это сообщение нельзя удалить. (%(code)s)", - "Thursday": "Четверг", - "Forward Message": "Переслать сообщение", - "Logs sent": "Журналы отправлены", - "Back": "Назад", - "Reply": "Ответить", - "Show message in desktop notification": "Показывать сообщение в уведомлении на рабочем столе", - "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Журналы отладки содержат данные об использовании приложения, включая ваше имя пользователя, идентификаторы или псевдонимы комнат или групп, которые вы посетили, а также имена других пользователей. Они не содержат сообщений.", - "Unhide Preview": "Показать предварительный просмотр", - "Unable to join network": "Не удается подключиться к сети", - "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Возможно вы настроили их не в Riot, а в другом Matrix-клиенте. Настроить их в Riot не удастся, но они будут в нем применяться", - "Sorry, your browser is not able to run Riot.": "К сожалению, ваш браузер не способен запустить Riot.", - "Messages in group chats": "Сообщения в групповых чатах", - "Yesterday": "Вчера", - "Error encountered (%(errorDetail)s).": "Обнаружена ошибка (%(errorDetail)s).", - "Login": "Войти", - "Low Priority": "Низкий приоритет", - "Unable to fetch notification target list": "Не удалось получить список целей уведомления", - "Set Password": "Задать пароль", - "Enable audible notifications in web client": "Включить звуковые уведомления в веб-клиенте", - "Permalink": "Постоянная ссылка", - "Off": "Выключить", - "Riot does not know how to join a room on this network": "Riot не знает, как присоединиться к комнате, принадлежащей к этой сети", - "Mentions only": "Только при упоминаниях", - "Wednesday": "Среда", - "You can now return to your account after signing out, and sign in on other devices.": "Теперь вы сможете вернуться к своей учетной записи после выхода из системы и войти на других устройствах.", - "Enable email notifications": "Включить уведомления по email", - "Event Type": "Тип мероприятия", - "Download this file": "Скачать этот файл", - "Pin Message": "Закрепить сообщение", - "Failed to change settings": "Не удалось изменить настройки", - "View Community": "Просмотр сообщества", - "%(count)s Members|one": "%(count)s член", - "Event sent!": "Мероприятие отправлено!", - "Event Content": "Содержание мероприятия", - "Thank you!": "Спасибо!", - "Quote": "Цитата", - "Collapse panel": "Свернуть панель", - "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "В текущем браузере внешний вид приложения может быть полностью неверным, а некоторые или все функции могут не работать. Если вы хотите попробовать в любом случае, то можете продолжить, но с теми проблемами, с которыми вы можете столкнуться вам придется разбираться самостоятельно!", - "Checking for an update...": "Проверка обновлений...", - "There are advanced notifications which are not shown here": "Существуют дополнительные уведомления, которые не показаны здесь" + "Everyone": "Все" } diff --git a/src/i18n/strings/sk.json b/src/i18n/strings/sk.json index 537d7d5069..72ba11b6d4 100644 --- a/src/i18n/strings/sk.json +++ b/src/i18n/strings/sk.json @@ -263,6 +263,8 @@ "Hangup": "Zavesiť", "Voice call": "Audio hovor", "Video call": "Video hovor", + "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", "You do not have permission to post to this room": "Nemáte udelené právo posielať do tejto miestnosti", @@ -294,15 +296,15 @@ "Seen by %(userName)s at %(dateTime)s": "%(userName)s videl %(dateTime)s", "Unnamed room": "Nepomenovaná miestnosť", "World readable": "Viditeľné pre každého", - "Guests can join": "Môžu vstúpiť aj hostia", + "Guests can join": "Aj hostia môžu vstúpiť", "No rooms to show": "Žiadne miestnosti na zobrazenie", - "Failed to set avatar.": "Nepodarilo sa nastaviť obrázok.", + "Failed to set avatar.": "Nepodarilo sa nastaviť avatara.", "Save": "Uložiť", "(~%(count)s results)|other": "(~%(count)s výsledkov)", "(~%(count)s results)|one": "(~%(count)s výsledok)", "Join Room": "Vstúpiť do miestnosti", - "Upload avatar": "Nahrať obrázok", - "Remove avatar": "Odstrániť obrázok", + "Upload avatar": "Nahrať avatara", + "Remove avatar": "Odstrániť avatara", "Settings": "Nastavenia", "Forget room": "Zabudnúť miestnosť", "Search": "Hľadať", @@ -339,7 +341,7 @@ "You are trying to access a room.": "Pristupujete k miestnosti.", "Click here to join the discussion!": "Kliknutím sem vstúpite do diskusie!", "This is a preview of this room. Room interactions have been disabled": "Toto je náhľad na miestnosť. Všetky akcie pre túto miestnosť sú zakázané", - "To change the room's avatar, you must be a": "Aby ste mohli meniť obrázok miestnosti, musíte byť", + "To change the room's avatar, you must be a": "Aby ste mohli meniť avatara miestnosti, musíte byť", "To change the room's name, you must be a": "Aby ste mohli meniť názov miestnosti, musíte byť", "To change the room's main address, you must be a": "Aby ste mohli meniť hlavnú adresu miestnosti, musíte byť", "To change the room's history visibility, you must be a": "Aby ste mohli meniť viditeľnosť histórie miestnosti, musíte byť", @@ -426,9 +428,9 @@ "Image '%(Body)s' cannot be displayed.": "Nie je možné zobraziť obrázok '%(Body)s'.", "This image cannot be displayed.": "Tento obrázok nie je možné zobraziť.", "Error decrypting video": "Chyba pri dešifrovaní videa", - "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s zmenil obrázok miestnosti %(roomName)s", - "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s odstránil obrázok miestnosti.", - "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s zmenil obrázok miestnosti ", + "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s zmenil avatara pre %(roomName)s", + "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s z miestnosti odstránil avatara.", + "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s zmenil avatara miestnosti na ", "Copied!": "Skopírované!", "Failed to copy": "Nepodarilo sa skopírovať", "Add an Integration": "Pridať integráciu", @@ -551,10 +553,10 @@ "%(severalUsers)schanged their name %(count)s times|one": "%(severalUsers)ssi zmenili meno", "%(oneUser)schanged their name %(count)s times|other": "%(oneUser)ssi %(count)s krát zmenil meno", "%(oneUser)schanged their name %(count)s times|one": "%(oneUser)ssi zmenil meno", - "%(severalUsers)schanged their avatar %(count)s times|other": "%(severalUsers)ssi %(count)s krát zmenili obrázok v profile", - "%(severalUsers)schanged their avatar %(count)s times|one": "%(severalUsers)ssi zmenili obrázok v profile", - "%(oneUser)schanged their avatar %(count)s times|other": "%(oneUser)ssi %(count)s krát zmenil obrázok v profile", - "%(oneUser)schanged their avatar %(count)s times|one": "%(oneUser)ssi zmenil obrázok v profile", + "%(severalUsers)schanged their avatar %(count)s times|other": "%(severalUsers)ssi %(count)s krát zmenili avatara", + "%(severalUsers)schanged their avatar %(count)s times|one": "%(severalUsers)ssi zmenili avatara", + "%(oneUser)schanged their avatar %(count)s times|other": "%(oneUser)ssi %(count)s krát zmenil avatara", + "%(oneUser)schanged their avatar %(count)s times|one": "%(oneUser)ssi zmenil avatara", "%(items)s and %(count)s others|other": "%(items)s a %(count)s ďalší", "%(items)s and %(count)s others|one": "%(items)s a jeden ďalší", "%(items)s and %(lastItem)s": "%(items)s a tiež %(lastItem)s", @@ -671,6 +673,7 @@ "Leave Community": "Opustiť komunitu", "Leave %(groupName)s?": "Opustiť komunitu %(groupName)s?", "Leave": "Opustiť", + "Unable to leave room": "Nie je možné opustiť miestnosť", "Community Settings": "Nastavenia komunity", "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Tieto miestnosti sú zobrazené všetkým členom na stránke komunity. Členovia komunity môžu vstúpiť do miestnosti kliknutím.", "Add rooms to this community": "Pridať miestnosti do tejto komunity", @@ -770,6 +773,9 @@ "Device ID:": "ID zariadenia:", "Device key:": "Kľúč zariadenia:", "Ignored Users": "Ignorovaní používatelia", + "Bug Report": "Hlásenie chyby", + "Found a bug?": "Našli ste chybu?", + "Report it": "Ohláste ju", "Analytics": "Analytické údaje", "Riot collects anonymous analytics to allow us to improve the application.": "Riot zbiera anonymné analytické údaje, čo nám umožňuje aplikáciu ďalej zlepšovať.", "Labs": "Experimenty", @@ -831,9 +837,9 @@ "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "K domovskému serveru nie je možné pripojiť sa použitím protokolu HTTP keďže v adresnom riadku prehliadača máte HTTPS adresu. Použite protokol HTTPS alebo povolte nezabezpečené skripty.", "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.": "Nie je možné pripojiť sa k domovskému serveru - skontrolujte prosím funkčnosť vašeho pripojenia na internet, uistite sa že certifikát domovského servera je dôverihodný, a že žiaden doplnok nainštalovaný v prehliadači nemôže blokovať požiadavky.", "Login as guest": "Prihlásiť sa ako hosť", - "Failed to fetch avatar URL": "Nepodarilo sa získať URL adresu obrázka", + "Failed to fetch avatar URL": "Nepodarilo sa získať URL adresu avatara", "Set a display name:": "Nastaviť zobrazované meno:", - "Upload an avatar:": "Nahrať obrázok:", + "Upload an avatar:": "Nahrať avatara:", "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ú.", @@ -899,7 +905,8 @@ "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", "Restricted": "Obmedzené", - "Hide avatar changes": "Skryť zmeny obrázka v profile", + "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)", @@ -916,6 +923,7 @@ "Call": "Hovor", "Answer": "Prijať", "Send": "Odoslať", + "Tag Panel": "Panel so značkami", "Delete %(count)s devices|other": "Vymazať %(count)s zariadení", "Delete %(count)s devices|one": "Vymazať zariadenie", "Select devices": "Vybrať zariadenia", @@ -985,176 +993,14 @@ "Code": "Kód", "Unable to join community": "Nie je možné vstúpiť do komunity", "Unable to leave community": "Nie je možné opustiť komunitu", - "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Zmeny vykonané vo vašej komunite názov a obrázok nemusia byť nasledujúcich 30 minút viditeľné všetkými používateľmi.", + "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Zmeny vykonané vo vašej komunite name and avatar nemusia byť nasledujúcich 30 minút viditeľné všetkými používateľmi.", "Join this community": "Vstúpiť do tejto komunity", "Leave this community": "Opustiť túto komunitu", "Did you know: you can use communities to filter your Riot.im experience!": "Vedeli ste: Že prácu s Riot.im si môžete spríjemníť použitím komunít!", - "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "Ak si chcete nastaviť filter, pretiahnite obrázok komunity na panel filtrovania úplne na ľavej strane obrazovky. Potom môžete kedykoľvek kliknúť na obrázok komunity na tomto panely a Riot.im vám bude zobrazovať len miestnosti a ľudí z komunity, na ktorej obrázok ste klikli.", + "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "Ak si chcete nastaviť filter, pretiahnite avatara komunity na panel filtrovania úplne na ľavej strane obrazovky. Potom môžete kedykoľvek kliknúť na avatara komunity na tomto panely a Riot.im vám bude zobrazovať len miestnosti a ľudí z komunity, na ktorej avatar ste klikli.", "Clear filter": "Zrušiť filter", "Debug Logs Submission": "Odoslanie ladiacich záznamov", "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contian messages.": "Ak ste nám poslali hlásenie o chybe cez Github, ladiace záznamy nám môžu pomôcť lepšie identifikovať chybu. Ladiace záznamy obsahujú údaje o používaní aplikácii, vrátane vašeho používateľského mena, názvy a aliasy miestností a komunít, ku ktorým ste sa pripojili a mená ostatných používateľov. Tieto záznamy neobsahujú samotný obsah vašich správ.", "Submit debug logs": "Odoslať ladiace záznamy", - "Opens the Developer Tools dialog": "Otvorí dialóg nástroje pre vývojárov", - "Stickerpack": "Balíček nálepiek", - "Sticker Messages": "Správy s nálepkami", - "You don't currently have any stickerpacks enabled": "Momentálne nemáte aktívne žiadne balíčky s nálepkami", - "Add a stickerpack": "Pridať balíček s nálepkami", - "Hide Stickers": "Skryť nálepky", - "Show Stickers": "Zobraziť nálepky", - "Who can join this community?": "Kto môže vstúpiť do tejto komunity?", - "Everyone": "Ktokoľvek", - "Fetching third party location failed": "Nepodarilo sa získať umiestnenie tretej strany", - "A new version of Riot is available.": "Dostupná je nová verzia Riot.", - "Couldn't load home page": "Nie je možné načítať domovskú stránku", - "Send Account Data": "Odoslať Údaje Účtu", - "All notifications are currently disabled for all targets.": "Momentálne sú zakázané všetky oznámenia pre všetky ciele.", - "Uploading report": "Prebieha odovzdanie hlásenia", - "Sunday": "Nedeľa", - "Notification targets": "Ciele oznámení", - "Today": "Dnes", - "Files": "Súbory", - "You are not receiving desktop notifications": "Nedostávate oznámenia na pracovnej ploche", - "Friday": "Piatok", - "Update": "Aktualizovať", - "Unable to fetch notification target list": "Nie je možné získať zoznam cieľov oznámení", - "Add an email address above to configure email notifications": "Ak si chcete nastaviť oznamovanie emailom, pridajte si emailovú adresu vyššie", - "Expand panel": "Rozbaliť panel", - "On": "Povolené", - "%(count)s Members|other": "%(count)s Členov", - "Filter room names": "Filtrovať názvy miestností", - "Changelog": "Zoznam zmien", - "Waiting for response from server": "Čakanie na odpoveď zo servera", - "Uploaded on %(date)s by %(user)s": "Nahral používateľ %(user)s dňa %(date)s", - "Send Custom Event": "Odoslať vlastnú udalosť", - "Advanced notification settings": "Pokročilé nastavenia oznámení", - "Failed to send logs: ": "Nepodarilo sa odoslať záznamy: ", - "delete the alias.": "vymazať alias.", - "To return to your account in future you need to set a password": "Aby ste sa v budúcnosti mohli vrátiť k vašemu účtu mali by ste si teraz nastaviť heslo", - "Forget": "Zabudnuť", - "Hide panel": "Skryť panel", - "You cannot delete this image. (%(code)s)": "Nemôžete vymazať tento obrázok. (%(code)s)", - "Cancel Sending": "Zrušiť odosielanie", - "This Room": "V tejto miestnosti", - "The Home Server may be too old to support third party networks": "Domovský server môže byť natoľko zastaralý, že nepodporuje siete tretíh strán", - "Resend": "Poslať znovu", - "Room not found": "Miestnosť nenájdená", - "Downloading update...": "Sťahovanie aktualizácie...", - "Messages in one-to-one chats": "Správy v priamych konverzáciách", - "Unavailable": "Nedostupné", - "View Decrypted Source": "Zobraziť dešifrovaný zdroj", - "Failed to update keywords": "Nepodarilo sa aktualizovať kľúčové slová", - "Notes:": "Poznámky:", - "remove %(name)s from the directory.": "odstrániť %(name)s z adresára.", - "Notifications on the following keywords follow rules which can’t be displayed here:": "Oznámenia nasledujúcich kľúčových slov sa riadia pravidlami, ktoré nie je možné zobraziť na tomto mieste:", - "Safari and Opera work too.": "Správne fungujú aj Safari a Opera.", - "Please set a password!": "Prosím, nastavte si heslo!", - "You have successfully set a password!": "Ǔspešne ste si nastavili heslo!", - "Explore Room State": "Preskúmať Stav Miestnosti", - "Source URL": "Pôvodná URL", - "Messages sent by bot": "Správy odosielané robotmi", - "Filter results": "Filtrovať výsledky", - "Members": "Členovia", - "No update available.": "K dispozícii nie je žiadna aktualizácia.", - "Noisy": "Hlučné", - "Failed to get protocol list from Home Server": "Nepodarilo sa získať zoznam protokolov z domovského servera", - "Collecting app version information": "Získavajú sa informácie o verzii aplikácii", - "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Vymazať alias %(alias)s a odstrániť miestnosť %(name)s z adresára?", - "This will allow you to return to your account after signing out, and sign in on other devices.": "Toto vám v budúcnosti umožní vrátiť sa k vašemu účtu aj po odhlásení, alebo tiež prihlásiť sa na iných zariadeniach.", - "Keywords": "Kľúčové slová", - "Enable notifications for this account": "Povoliť oznámenia pre tento účet", - "Directory": "Adresár", - "Invite to this community": "Pozvať do tejto komunity", - "Failed to get public room list": "Nepodarilo sa získať zoznam verejných miestností", - "Search…": "Hľadať…", - "Messages containing keywords": "Správy obsahujúce kľúčové slová", - "Error saving email notification preferences": "Chyba pri ukladaní nastavení oznamovania emailom", - "Tuesday": "Utorok", - "Enter keywords separated by a comma:": "Zadajte kľúčové slová oddelené čiarkou:", - "Forward Message": "Preposlať správu", - "Remove %(name)s from the directory?": "Odstrániť miestnosť %(name)s z adresára?", - "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot sa spolieha na mnohé pokročilé vlastnosti prehliadača internetu, a niektoré z nich sú vo vašom prehliadači experimentálne alebo nie sú k dispozícii vôbec.", - "Event sent!": "Udalosť odoslaná!", - "Preparing to send logs": "príprava odoslania záznamov", - "Enable desktop notifications": "Povoliť oznámenia na pracovnej ploche", - "Explore Account Data": "Preskúmať Údaje účtu", - "All messages (noisy)": "Všetky správy (hlučné)", - "Saturday": "Sobota", - "Remember, you can always set an email address in user settings if you change your mind.": "Všimnite si, Emailovú adresu môžete pridať aj neskôr v časti nastavenia, ak zmeníte svoj názor.", - "Direct Chat": "Priama konverzácia", - "The server may be unavailable or overloaded": "Server môže byť nedostupný alebo preťažený", - "Reject": "Odmietnuť", - "Failed to set Direct Message status of room": "Nepodarilo sa nastaviť stav miestnosti priama konverzácia", - "Monday": "Pondelok", - "Remove from Directory": "Odstrániť z adresára", - "Enable them now": "Povolte si ich teraz", - "Messages containing my user name": "Správy obsahujúce moje používateľské meno", - "Toolbox": "Nástroje", - "Collecting logs": "Získavajú sa záznamy", - "more": "viac", - "GitHub issue link:": "Odkaz hlásenia na Github:", - "Search for a room": "Vyhľadať miestnosť", - "You must specify an event type!": "Musíte nastaviť typ udalosti!", - "(HTTP status %(httpStatus)s)": "(HTTP status %(httpStatus)s)", - "All Rooms": "Vo všetkych miestnostiach", - "State Key": "State Key", - "Please install Chrome or Firefox for the best experience.": "Aby ste s používania mali čo možno najlepší dojem, nainštalujte si Chrome alebo Firefox.", - "Wednesday": "Streda", - "Quote": "Citácia", - "Send logs": "Zahrnúť záznamy", - "All messages": "Všetky správy", - "Call invitation": "Audio / Video hovory", - "Messages containing my display name": "Správy obsahujúce moje zobrazované meno", - "You have successfully set a password and an email address!": "Úspešne si si nastavili heslo aj emailovú adresu!", - "Failed to send custom event.": "Odoslanie vlastnej udalosti zlyhalo.", - "What's new?": "Čo je nové?", - "Notify me for anything else": "Oznamovať mi všetko ostatné", - "When I'm invited to a room": "Pozvania vstúpiť do miestnosti", - "Click here to create a GitHub issue.": "Kliknutím sem nám pošlete hlásenie o chybe cez Github.", - "Can't update user notification settings": "Nie je možné aktualizovať používateľské nastavenia oznamovania", - "Notify for all other messages/rooms": "oznamovať všetky ostatné správy / miestnosti", - "Unable to look up room ID from server": "Nie je možné vyhľadať ID miestnosti na servery", - "Couldn't find a matching Matrix room": "Nie je možné nájsť zodpovedajúcu Matrix miestnosť", - "Invite to this room": "Pozvať do tejto miestnosti", - "You cannot delete this message. (%(code)s)": "Nemôžete vymazať túto správu. (%(code)s)", - "Thursday": "Štvrtok", - "I understand the risks and wish to continue": "Rozumiem rizikám a želám si pokračovať", - "Logs sent": "Záznamy boli odoslané", - "Back": "Naspäť", - "Reply": "Odpovedať", - "Show message in desktop notification": "Zobraziť text správy v oznámení na pracovnej ploche", - "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Ladiace záznamy obsahujú údaje o používaní aplikácii, vrátane vašeho používateľského mena, názvy a aliasy miestností a komunít, ku ktorým ste sa pripojili a mená ostatných používateľov. Tieto záznamy neobsahujú samotný obsah vašich správ.", - "Unhide Preview": "Zobraziť náhľad", - "Unable to join network": "Nie je možné sa pripojiť k sieti", - "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Tieto nastavenia oznámení sa použijú aj napriek tomu, že ich nemôžete meniť cez Riot. Pravdepodobne ste si ich nastavili v inej aplikácii", - "Sorry, your browser is not able to run Riot.": "Prepáčte, vo vašom prehliadači nie je možné spustiť Riot.", - "Messages in group chats": "Správy v skupinových konverzáciách", - "Yesterday": "Včera", - "Error encountered (%(errorDetail)s).": "Vyskytla sa chyba (%(errorDetail)s).", - "Event Type": "Typ Udalosti", - "Low Priority": "Nízka priorita", - "What's New": "Čo Je Nové", - "Set Password": "Nastaviť Heslo", - "An error occurred whilst saving your email notification preferences.": "Počas ukladania vašich nastavení oznamovania emailom sa vyskytla chyba.", - "Enable audible notifications in web client": "Povoliť zvukové oznámenia vo webovom klientovi", - "Permalink": "Trvalý odkaz", - "Off": "Zakázané", - "Riot does not know how to join a room on this network": "Riot nedokáže vstúpiť do miestnosti na tejto sieti", - "Mentions only": "Len zmienky", - "You can now return to your account after signing out, and sign in on other devices.": "Odteraz sa budete k svojmu účtu vedieť vrátiť aj po odhlásení, alebo tiež prihlásiť na iných zariadeniach.", - "Enable email notifications": "Povoliť oznamovanie emailom", - "Login": "Prihlásiť", - "Download this file": "Stiahnuť tento súbor", - "Pin Message": "Pripnúť správu", - "Failed to change settings": "Nepodarilo sa zmeniť nastavenia", - "View Community": "Zobraziť komunitu", - "%(count)s Members|one": "%(count)s Člen", - "Developer Tools": "Vývojárske Nástroje", - "View Source": "Zobraziť zdroj", - "Event Content": "Obsah Udalosti", - "Thank you!": "Ďakujeme!", - "#example": "#príklad", - "Collapse panel": "Zbaliť panel", - "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Vo vašom súčasnom prehliadači nemusí Riot vizerať ani fungovať správne a niektoré alebo všetky vlastnosti môžu chýbať. Ak to chcete vyskúšať, môžete pokračovať, no pri riešení problémov s tým spojených si budete musieť poradiť na vlastnú päsť!", - "Checking for an update...": "Kontrola dostupnosti aktualizácie...", - "There are advanced notifications which are not shown here": "Niektoré pokročilé oznámenia nemôžu byť zobrazené" + "Opens the Developer Tools dialog": "Otvorí dialóg nástroje pre vývojárov" } diff --git a/src/i18n/strings/sr.json b/src/i18n/strings/sr.json index 3c1a8a1f20..a6d8ab8540 100644 --- a/src/i18n/strings/sr.json +++ b/src/i18n/strings/sr.json @@ -172,6 +172,7 @@ "Failed to join room": "Нисам успео да уђем у собу", "Message Replies": "Одговори", "Message Pinning": "Закачене поруке", + "Presence Management": "Управљање присутношћу", "Tag Panel": "Означи површ", "Disable Emoji suggestions while typing": "Онемогући предлагање емоџија приликом куцања", "Use compact timeline layout": "Користи збијени распоред временске линије", @@ -303,6 +304,8 @@ "Hangup": "Спусти слушалицу", "Voice call": "Гласовни позив", "Video call": "Видео позив", + "Hide Apps": "Сакриј апликације", + "Show Apps": "Прикажи апликације", "Upload file": "Отпреми датотеку", "Show Text Formatting Toolbar": "Прикажи алатницу за форматирање текста", "Send an encrypted reply…": "Пошаљи шифровани одговор…", @@ -628,6 +631,7 @@ "expand": "рашири", "Custom of %(powerLevel)s": "Прилагођени ниво %(powerLevel)s", "Custom level": "Прилагођени ниво", + "Quote": "Цитат", "Room directory": "Фасцикла са собама", "Start chat": "Започни ћаскање", "And %(count)s more...|other": "И %(count)s других...", @@ -740,6 +744,7 @@ "Leave Community": "Напусти заједницу", "Leave %(groupName)s?": "Напустити %(groupName)s?", "Leave": "Напусти", + "Unable to leave room": "Не могу да напустим собу", "Community Settings": "Подешавања заједнице", "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Ове собе су приказане члановима заједнице на страници заједнице. Чланови заједнице могу приступити собама кликом на њих.", "Add rooms to this community": "Додај собе у ову заједницу", @@ -761,6 +766,8 @@ "Failed to leave room": "Нисам успео да напустим собу", "Signed Out": "Одјављен", "For security, this session has been signed out. Please sign in again.": "Зарад безбедности, одјављени сте из ове сесије. Пријавите се поново.", + "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": "Нађени су стари криптографски подаци", "The platform you're on": "Платформа коју користите", "The version of Riot.im": "Riot.im издање", @@ -848,6 +855,9 @@ "Device ID:": "ИБ уређаја:", "Device key:": "Кључ уређаја:", "Ignored Users": "Занемарени корисници", + "Bug Report": "Извештај о грешци", + "Found a bug?": "Нашли сте грешку?", + "Report it": "Пријавите је", "Riot collects anonymous analytics to allow us to improve the application.": "Riot прикупља анонимне податке о коришћењу да бисмо побољшали апликацију.", "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.": "Сазнајте више о нашем начину употребе аналитике.", @@ -984,151 +994,5 @@ "Key request sent.": "Захтев за дељење кључа послат.", "Re-request encryption keys from your other devices.": "Поново затражи кључеве за шифровање са осталих ваших уређаја.", "%(user)s is a %(userRole)s": "Корисник %(user)s је у улози %(userRole)s", - "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "Да бисте поставили филтер, повуците аватар заједнице на површ филтрирања скроз на леву страну екрана. Можете кликнути на аватар у површи филтрирања било када да бисте видели само собе и особе везане за ту заједницу.", - "Fetching third party location failed": "Добављање локације треће стране није успело", - "A new version of Riot is available.": "Ново издање RIot-а је доступно.", - "Couldn't load home page": "Нисам могао да учитам почетну страну", - "Send Account Data": "Пошаљи податке налога", - "All notifications are currently disabled for all targets.": "Сва обавештења су тренутно онемогућена за све циљеве.", - "Uploading report": "Отпремам извештај", - "Sunday": "Недеља", - "Notification targets": "Циљеви обавештења", - "Today": "Данас", - "Files": "Датотеке", - "You are not receiving desktop notifications": "Не примате стона обавештења", - "Friday": "Петак", - "Update": "Ажурирај", - "Unable to fetch notification target list": "Не могу да досегнем списак циљева за обавештења", - "Add an email address above to configure email notifications": "Додајте мејл адресу изнад да бисте подесили мејл обавештења", - "Expand panel": "Прошири површ", - "On": "Укључено", - "%(count)s Members|other": "%(count)s чланова", - "Filter room names": "Филтрирај називе соба", - "Changelog": "Записник о изменама", - "Waiting for response from server": "Чекам на одговор са сервера", - "Uploaded on %(date)s by %(user)s": "Отпремљено датума %(date)s од корисника %(user)s", - "Send Custom Event": "Пошаљи прилагођени догађај", - "Off": "Искључено", - "Advanced notification settings": "Напредна подешавања обавештења", - "delete the alias.": "обриши алијас.", - "To return to your account in future you need to set a password": "Да бисте се вратили на ваш налог у будућности, морате поставити лозинку", - "Forget": "Заборави", - "Hide panel": "Сакриј површ", - "You cannot delete this image. (%(code)s)": "Не можете обрисати ову слику. (%(code)s)", - "Cancel Sending": "Откажи слање", - "This Room": "Ова соба", - "The Home Server may be too old to support third party networks": "Кућни сервер је можда сувише застарео да би подржао мреже трећих страна", - "Room not found": "Соба није пронађена", - "Downloading update...": "Преузимам ажурирање...", - "Messages in one-to-one chats": "Поруке у један-на-један ћаскањима", - "Unavailable": "Недоступан", - "View Decrypted Source": "Погледај дешифровани извор", - "Failed to update keywords": "Нисам успео да ажурирам кључне речи", - "remove %(name)s from the directory.": "уклони %(name)s из фасцикле.", - "Notifications on the following keywords follow rules which can’t be displayed here:": "Обавештења за следеће кључне речи прате правила која не могу бити приказана овде:", - "Safari and Opera work too.": "Сафари и Опера такође раде.", - "Please set a password!": "Поставите лозинку!", - "You have successfully set a password!": "Успешно сте поставили лозинку!", - "Explore Room State": "Истражи стање собе", - "Source URL": "Адреса извора", - "Messages sent by bot": "Поруке послате од бота", - "Filter results": "Филтрирај резултате", - "Members": "Чланови", - "No update available.": "Нема нових ажурирања.", - "Noisy": "Бучно", - "Failed to get protocol list from Home Server": "Нисам успео да добијем списак протокола од кућног сервера", - "Collecting app version information": "Прикупљам податке о издању апликације", - "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Обрисати алијас собе %(alias)s и уклонити %(name)s из фасцикле?", - "This will allow you to return to your account after signing out, and sign in on other devices.": "Ово ће вам омогућити да се вратите у ваш налог након што се одјавите и пријавите, на другим уређајима.", - "Keywords": "Кључне речи", - "Enable notifications for this account": "Омогући обавештења за овај налог", - "Directory": "Фасцикла", - "Invite to this community": "Позови у ову заједницу", - "Failed to get public room list": "Нисам успео да добавим списак јавних соба", - "Search…": "Претрага…", - "Messages containing keywords": "Поруке које садрже кључне речи", - "Error saving email notification preferences": "Грешка при чувању поставки мејл обавештења", - "Tuesday": "Уторак", - "Enter keywords separated by a comma:": "Унесите кључне речи одвојене зарезима:", - "Forward Message": "Проследи поруку", - "Remove %(name)s from the directory?": "Уклонити %(name)s из фасцикле?", - "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot користи напредне могућности прегледача од којих неке нису доступне или су у пробној фази, у вашем прегледачу.", - "Event sent!": "Догађај је послат!", - "Explore Account Data": "Истражи податке налога", - "All messages (noisy)": "Све поруке (гласно)", - "Saturday": "Субота", - "Remember, you can always set an email address in user settings if you change your mind.": "Запамтите, увек можете поставити мејл адресу у корисничким подешавањима, уколико се предомислите.", - "Direct Chat": "Директно ћаскање", - "The server may be unavailable or overloaded": "Сервер је можда недоступан или преоптерећен", - "Reject": "Одбаци", - "Failed to set Direct Message status of room": "Нисам успео да подесим стање директне поруке собе", - "Monday": "Понедељак", - "Remove from Directory": "Уклони из фасцикле", - "Enable them now": "Омогућите их сада", - "Messages containing my user name": "Поруке које садрже моје корисничко име", - "Toolbox": "Алатница", - "Collecting logs": "Прикупљам записнике", - "more": "више", - "Search for a room": "Потражи собу", - "You must specify an event type!": "Морате навести врсту догађаја!", - "(HTTP status %(httpStatus)s)": "(HTTP стање %(httpStatus)s)", - "All Rooms": "Све собе", - "State Key": "Кључ стања", - "Please install Chrome or Firefox for the best experience.": "Инсталирајте Хром (Chrome) или Фајерфокс (Firefox) за најбољи угођај.", - "Wednesday": "Среда", - "Send logs": "Пошаљи записнике", - "All messages": "Све поруке", - "Call invitation": "Позивница за позив", - "Messages containing my display name": "Поруке које садрже моје приказно име", - "You have successfully set a password and an email address!": "Успешно сте поставили лозинку и мејл адресу!", - "Failed to send custom event.": "Нисам успео да пошаљем прилагођени догађај.", - "What's new?": "Шта је ново?", - "Notify me for anything else": "Обавести ме за било шта друго", - "When I'm invited to a room": "Када сам позван у собу", - "Can't update user notification settings": "Не могу да ажурирам корисничка подешавања обавештења", - "Notify for all other messages/rooms": "Обавести за све друге поруке и собе", - "Unable to look up room ID from server": "Не могу да погледам ИБ собе на серверу", - "Couldn't find a matching Matrix room": "Не могу да нађем одговарајућу Матрикс собу", - "Invite to this room": "Позови у ову собу", - "You cannot delete this message. (%(code)s)": "Не можете обрисати ову поруку. (%(code)s)", - "Thursday": "Четвртак", - "I understand the risks and wish to continue": "Разумем опасност и желим да наставим", - "Back": "Назад", - "Reply": "Одговори", - "Show message in desktop notification": "Прикажи поруку у стоном обавештењу", - "Unhide Preview": "Откриј преглед", - "Unable to join network": "Не могу да приступим мрежи", - "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Можда сте их подесили у неком другом клијенту а не Riot-у. Не можете их преправљати у Riot-у али се и даље примењују", - "Sorry, your browser is not able to run Riot.": "Нажалост, ваш прегледач не може да покреће Riot.", - "Messages in group chats": "Поруке у групним ћаскањима", - "Yesterday": "Јуче", - "Error encountered (%(errorDetail)s).": "Догодила се грешка (%(errorDetail)s).", - "Event Type": "Врста догађаја", - "Low Priority": "Најмања важност", - "What's New": "Шта је ново", - "Set Password": "Постави лозинку", - "An error occurred whilst saving your email notification preferences.": "Догодила се грешка при чувању ваших поставки мејл обавештења.", - "Enable audible notifications in web client": "Омогући звучна обавештења у веб клијенту", - "Permalink": "Трајна веза", - "Resend": "Поново пошаљи", - "Riot does not know how to join a room on this network": "Riot не зна како да приступи соби на овој мрежи", - "Mentions only": "Само спомињања", - "You can now return to your account after signing out, and sign in on other devices.": "Можете се вратити у ваш налог након што се одјавите и пријавите поново, на другим уређајима.", - "Enable desktop notifications": "Омогући стона обавештења", - "Enable email notifications": "Омогући мејл обавештења", - "Login": "Пријава", - "Download this file": "Преузми ову датотеку", - "Pin Message": "Закачи поруку", - "Failed to change settings": "Нисам успео да променим подешавања", - "View Community": "Погледај заједницу", - "%(count)s Members|one": "%(count)s члан", - "Developer Tools": "Програмерске алатке", - "View Source": "Погледај извор", - "Event Content": "Садржај догађаја", - "Thank you!": "Хвала вам!", - "#example": "#пример", - "Collapse panel": "Скупи површ", - "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Са вашим тренутним прегледачем изглед и угођај ове апликације може бити скроз неправилан и неке могућности можда неће радити. Уколико желите да ипак пробате, можете наставити али ћете бити без подршке за било које проблеме на које налетите!", - "Checking for an update...": "Проверавам ажурирања...", - "There are advanced notifications which are not shown here": "Постоје напредна обавештења која нису приказана овде" + "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "Да бисте поставили филтер, повуците аватар заједнице на површ филтрирања скроз на леву страну екрана. Можете кликнути на аватар у површи филтрирања било када да бисте видели само собе и особе везане за ту заједницу." } From 5f920f729bf0331818a2eab014c3cf0f003f5a62 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 23 Apr 2018 10:35:02 +0100 Subject: [PATCH 053/190] Reset accidental merge changes 2.0 Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/i18n/strings/cs.json | 159 ++++++++++++++++++++++++++-- src/i18n/strings/de_DE.json | 172 ++++++++++++++++++++++++++++-- src/i18n/strings/fr.json | 171 +++++++++++++++++++++++++++--- src/i18n/strings/hu.json | 178 +++++++++++++++++++++++++++---- src/i18n/strings/nl.json | 183 ++++++++++++++++++++++++++++++-- src/i18n/strings/ru.json | 174 +++++++++++++++++++++++++++--- src/i18n/strings/sk.json | 205 +++++++++++++++++++++++++++++++----- src/i18n/strings/sr.json | 157 +++++++++++++++++++++++++-- 8 files changed, 1291 insertions(+), 108 deletions(-) diff --git a/src/i18n/strings/cs.json b/src/i18n/strings/cs.json index 4267954d4c..d19f17e097 100644 --- a/src/i18n/strings/cs.json +++ b/src/i18n/strings/cs.json @@ -90,7 +90,6 @@ "Are you sure you want to upload the following files?": "Určitě chcete nahrát následující soubory?", "Attachment": "Příloha", "Autoplay GIFs and videos": "Automaticky přehrávat GIFy a videa", - "Bug Report": "Hlášení o chybě", "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.": "Nelze se připojit k domovskému serveru – zkontrolujte prosím své připojení, prověřte, zdali je SSL certifikát vašeho domovského serveru důvěryhodný, a že některé z rozšíření prohlížeče neblokuje komunikaci.", "Anyone who knows the room's link, apart from guests": "Kdokoliv, kdo má odkaz na místnost, kromě hostů", "Anyone who knows the room's link, including guests": "Kdokoliv, kdo má odkaz na místnost, a to i hosté", @@ -207,7 +206,6 @@ "%(senderName)s answered the call.": "%(senderName)s přijal/a hovor.", "Click to mute audio": "Kliknutím ztlumíte zvuk", "Failed to verify email address: make sure you clicked the link in the email": "E-mailovou adresu se nepodařilo ověřit. Přesvědčte se, že jste kliknul/a na zaslaný odkaz", - "Found a bug?": "Našli jste chybu?", "Guest access is disabled on this Home Server.": "Na tomto domovském serveru je hostům vstup odepřen.", "Guests cannot join this room even if explicitly invited.": "Hosté nemohou vstoupit do této místnosti, i když jsou přímo pozváni.", "Hide read receipts": "Skrýt potvrzení o přečtení", @@ -278,7 +276,6 @@ "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Tuto změnu nepůjde vrátit zpět, protože tomuto uživateli nastavujete stejnou úroveň moci, jakou máte vy.", "Alias (optional)": "Alias (nepovinný)", "Room name (optional)": "Název místnosti (nepovinný)", - "Report it": "Nahlásit to", "Results from DuckDuckGo": "Výsledky z DuckDuckGo", "Return to login screen": "Vrátit k přihlašovací obrazovce", "Riot does not have permission to send you notifications - please check your browser settings": "Riot není oprávněn posílat vám upozornění – zkontrolujte prosím nastavení svého prohlížeče", @@ -306,7 +303,6 @@ "%(senderName)s set a profile picture.": "%(senderName)s si nastavil/a profilový obrázek.", "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s si změnil/a zobrazované jméno na %(displayName)s.", "Sets the room topic": "Nastavuje téma místnosti", - "Show Apps": "Zobrazit aplikace", "Show panel": "Zobrazit panel", "Show timestamps in 12 hour format (e.g. 2:30pm)": "Zobrazovat časové značky v 12hodinovém formátu (např. 2:30 odp.)", "Sign in": "Přihlásit", @@ -530,7 +526,6 @@ "Make Moderator": "Udělit moderátorství", "and %(count)s others...|one": "a někdo další...", "Hangup": "Zavěsit", - "Hide Apps": "Skrýt aplikace", "Show Text Formatting Toolbar": "Zobrazit nástroje formátování textu", "Hide Text Formatting Toolbar": "Skrýt nástroje formátování textu", "Jump to message": "Přeskočit na zprávu", @@ -560,7 +555,6 @@ "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", "Hide join/leave messages (invites/kicks/bans unaffected)": "Skrýt zprávy o vstupu či odejití (pozvánky, vykopnutí a vykázání zůstanou)", "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", @@ -649,7 +643,6 @@ "%(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", @@ -948,5 +941,155 @@ "expand": "rozbalit", "Old cryptography data detected": "Nalezeny starší šifrované datové zprávy", "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.": "Nalezeny datové zprávy ze starší verze Riot. Důsledkem bude, že E2E šifrování nebude ve starší verzi Riot správně fungovat. Šifrované zprávy ze starší verze nemusí být čitelné v nové verzi. Může dojít i k selhání zasílaní zpráv s touto verzí Riot. Pokud zaznamenáte některý z uvedených problému, odhlaste se a přihlaste znovu. Pro zachování historie zpráv exportujte a znovu importujte vaše klíče.", - "Warning": "Upozornění" + "Warning": "Upozornění", + "Fetching third party location failed": "Nepodařilo se zjistit umístění třetí strany", + "A new version of Riot is available.": "Je dostupná nová verze Riotu.", + "I understand the risks and wish to continue": "Rozumím rizikům a přeji si pokračovat", + "Couldn't load home page": "Nepodařilo se nahrát úvodní stránku", + "Send Account Data": "Poslat data o účtu", + "Advanced notification settings": "Pokročilé nastavení upozornění", + "Uploading report": "Nahrávám hlášení", + "Sunday": "Neděle", + "Messages sent by bot": "Zprávy poslané robotem", + "Notification targets": "Cíle upozornění", + "Failed to set direct chat tag": "Nepodařilo se nastavit štítek přímého chatu", + "Today": "Dnes", + "Files": "Soubory", + "You are not receiving desktop notifications": "Nedostáváte upozornění na desktopu", + "Friday": "Pátek", + "Update": "Aktualizace", + "What's New": "Co je nového", + "Add an email address above to configure email notifications": "Abyste mohli nastavovat e-mailová upozornění, musíte uvést svoji e-mailovou adresu v kolonce výše", + "Expand panel": "Rozbalit panel", + "On": "Zapnout", + "%(count)s Members|other": "%(count)s Členů", + "Filter room names": "Filtrovat místnosti dle názvu", + "Changelog": "Seznam změn", + "Waiting for response from server": "Čekám na odezvu ze serveru", + "Send Custom Event": "Odeslat vlastní událost", + "All notifications are currently disabled for all targets.": "Veškeré notifikace jsou aktuálně pro všechny cíle vypnuty.", + "delete the alias.": "smazat alias.", + "To return to your account in future you need to set a password": "Abyste se mohli ke svému účtu v budoucnu vrátit, musíte si nastavit heslo", + "Forget": "Zapomenout", + "Hide panel": "Skrýt panel", + "You cannot delete this image. (%(code)s)": "Tento obrázek nemůžete smazat. (%(code)s)", + "Cancel Sending": "Zrušit odesílání", + "This Room": "Tato místnost", + "The Home Server may be too old to support third party networks": "Tento domovský server může být příliš zastaralý na to, aby podporoval sítě třetích stran", + "Noisy": "Hlučný", + "Room not found": "Místnost nenalezena", + "Messages containing my display name": "Zprávy obsahující mé zobrazované jméno", + "Remember, you can always set an email address in user settings if you change your mind.": "Vězte, že kdybyste si to rozmysleli, e-mailovou adresu můžete kdykoliv doplnit v uživatelském nastavení.", + "Unavailable": "Nedostupné", + "Error saving email notification preferences": "Chyba při ukládání nastavení e-mailových upozornění", + "View Decrypted Source": "Zobrazit dešifrovaný zdroj", + "Failed to update keywords": "Nepodařilo se aktualizovat klíčová slova", + "remove %(name)s from the directory.": "odebrat %(name)s z adresáře.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Upozornění na následující klíčová slova se řídí pravidly, která zde nelze zobrazit:", + "Safari and Opera work too.": "Safari a Opera fungují taky.", + "Please set a password!": "Prosím nastavte si heslo!", + "You have successfully set a password!": "Úspěšně jste si nastavili heslo!", + "Explore Room State": "Prohlížet stav místnosti", + "Source URL": "Zdrojová URL", + "Failed to add tag %(tagName)s to room": "Nepodařilo se přidat štítek %(tagName)s k místnosti", + "Filter results": "Filtrovat výsledky", + "Members": "Členové", + "No update available.": "Není dostupná žádná aktualizace.", + "Resend": "Poslat znovu", + "Failed to get protocol list from Home Server": "Z domovského serveru se nepodařilo získat seznam protokolů", + "Collecting app version information": "Sbírání informací o verzi aplikace", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Smazat alias místnosti %(alias)s a odstranit %(name)s z adresáře?", + "This will allow you to return to your account after signing out, and sign in on other devices.": "Toto vám umožní vrátit se po odhlášení ke svému účtu a používat jej na ostatních zařízeních.", + "Keywords": "Klíčová slova", + "Enable notifications for this account": "Zapnout upozornění na tomto účtu", + "Directory": "Adresář", + "Invite to this community": "Pozvat do této komunity", + "Search for a room": "Hledat místnost", + "Messages containing keywords": "Zprávy obsahující klíčová slova", + "View Source": "Zobrazit zdroj", + "Tuesday": "Úterý", + "Enter keywords separated by a comma:": "Vložte klíčová slova oddělená čárkou:", + "Forward Message": "Přeposlat zprávu", + "You have successfully set a password and an email address!": "Úspěšně jste si nastavili heslo a e-mailovou adresu!", + "Remove %(name)s from the directory?": "Odebrat %(name)s z adresáře?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot používá mnoho pokročilých funkcí, z nichž některé jsou ve vašem současném prohlížeči nedostupné nebo experimentální.", + "Developer Tools": "Nástroje pro vývojáře", + "Enable desktop notifications": "Zapnout upozornění na ploše", + "Explore Account Data": "Prozkoumat data o účtu", + "Remove from Directory": "Odebrat z adresáře", + "Saturday": "Sobota", + "Messages in one-to-one chats": "Zprávy v individuálních chatech", + "Direct Chat": "Přímý chat", + "The server may be unavailable or overloaded": "Server může být nedostupný nebo přetížený", + "Reject": "Odmítnout", + "Failed to set Direct Message status of room": "Nepodařilo se přiřadit místnosti status Přímé zprávy", + "Monday": "Pondělí", + "All messages (noisy)": "Všechny zprávy (hlasitě)", + "Enable them now": "Povolit nyní", + "Messages containing my user name": "Zprávy obsahující mé uživatelské jméno", + "Toolbox": "Sada nástrojů", + "Collecting logs": "Sbírání logů", + "more": "více", + "You must specify an event type!": "Musíte určit typ události!", + "(HTTP status %(httpStatus)s)": "(HTTP status %(httpStatus)s)", + "Invite to this room": "Pozvat do této místnosti", + "Please install Chrome or Firefox for the best experience.": "Pro nejlepší zážitek si prosím nainstalujte Chrome nebo Firefox.", + "Failed to get public room list": "Nepodařilo se získat seznam veřejných místností", + "Send logs": "Odeslat záznamy", + "All messages": "Všechny zprávy", + "Call invitation": "Pozvánka k hovoru", + "Downloading update...": "Stahování aktualizace...", + "State Key": "Stavový klíč", + "Failed to send custom event.": "Nepodařilo se odeslat vlastní událost.", + "What's new?": "Co je nového?", + "Notify me for anything else": "Upozorni mě na cokoliv jiného", + "When I'm invited to a room": "Pokud jsem pozván do místnosti", + "Can't update user notification settings": "Nelze aktualizovat uživatelské nastavení upozornění", + "Notify for all other messages/rooms": "Upozorni na všechny ostatní zprávy/místnosti", + "Unable to look up room ID from server": "Nelze získat ID místnosti ze serveru", + "Couldn't find a matching Matrix room": "Odpovídající Matrix místost nenalezena", + "All Rooms": "Všechny místnosti", + "You cannot delete this message. (%(code)s)": "Tuto zprávu nemůžete smazat. (%(code)s)", + "Thursday": "Čtvrtek", + "Search…": "Vyhledat…", + "Back": "Zpět", + "Failed to change settings": "Nepodařilo se změnit nastavení", + "Reply": "Odpovědět", + "Show message in desktop notification": "Zobrazovat zprávu v upozornění na ploše", + "Unhide Preview": "Zobrazit náhled", + "Unable to join network": "Nelze se připojit k síti", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Snad jste je nastavili v jiném klientu než Riot. V Riotu je nemůžete upravit, ale přesto platí", + "Sorry, your browser is not able to run Riot.": "Omlouváme se, váš prohlížeč není schopný spustit Riot.", + "Uploaded on %(date)s by %(user)s": "Nahráno %(date)s uživatelem %(user)s", + "Messages in group chats": "Zprávy ve skupinových chatech", + "Yesterday": "Včera", + "Error encountered (%(errorDetail)s).": "Nastala chyba (%(errorDetail)s).", + "Login": "Přihlásit", + "Low Priority": "Nízká priorita", + "Riot does not know how to join a room on this network": "Riot neví, jak vstoupit do místosti na této síti", + "Set Password": "Nastavit heslo", + "An error occurred whilst saving your email notification preferences.": "Při ukládání nastavení e-mailových upozornění nastala chyba.", + "Enable audible notifications in web client": "Povolit zvuková upozornění ve webové aplikaci", + "Permalink": "Trvalý odkaz", + "Off": "Vypnout", + "#example": "#příklad", + "Mentions only": "Pouze zmínky", + "Failed to remove tag %(tagName)s from room": "Nepodařilo se odstranit štítek %(tagName)s z místnosti", + "Wednesday": "Středa", + "You can now return to your account after signing out, and sign in on other devices.": "Nyní se můžete ke svému účtu vrátit i po odhlášení a používat jej na ostatních zařízeních.", + "Enable email notifications": "Zapnout upozornění přes e-mail", + "Event Type": "Typ události", + "Download this file": "Stáhnout tento soubor", + "Pin Message": "Připíchnout zprávu", + "Thank you!": "Děkujeme vám!", + "View Community": "Zobrazit Komunitu", + "%(count)s Members|one": "%(count)s Člen", + "Event sent!": "Událost odeslána!", + "Event Content": "Obsah události", + "Unable to fetch notification target list": "Nepodařilo se získat seznam cílů upozornění", + "Quote": "Citace", + "Collapse panel": "Sbalit panel", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Vzhled a chování aplikace může být ve vašem aktuální prohlížeči nesprávné a některé nebo všechny funkce mohou být chybné. Chcete-li i přes to pokračovat, nebudeme vám bránit, ale se všemi problémy, na které narazíte, si musíte poradit sami!", + "Checking for an update...": "Kontrola aktualizací...", + "There are advanced notifications which are not shown here": "Jsou k dispozici pokročilá upozornění, která zde nejsou zobrazena" } diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index e67c9fcaaa..2030b4285a 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -51,7 +51,6 @@ "Are you sure you want to reject the invitation?": "Bist du sicher, dass du die Einladung ablehnen willst?", "Are you sure you want to upload the following files?": "Bist du sicher, dass du die folgenden Dateien hochladen möchtest?", "Banned users": "Verbannte Benutzer", - "Bug Report": "Fehlerbericht", "Changes to who can read history will only apply to future messages in this room": "Änderungen, die bestimmen, wer den Chatverlauf lesen kann, gelten nur für zukünftige Nachrichten in diesem Raum", "Clear Cache and Reload": "Cache leeren und neu laden", "Confirm your new password": "Neues Passwort bestätigen", @@ -89,7 +88,6 @@ "Forgot your password?": "Passwort vergessen?", "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.": "Aus Sicherheitsgründen werden beim Ausloggen alle Ende-zu-Ende-Verschlüsselungs-Schlüssel in diesem Browser gelöscht. Wenn du in späteren Riot-Sitzungen den bisherigen Chatverlauf entschlüsseln möchtest, exportiere bitte deine Schlüssel zur sicheren Aufbewahrung.", "For security, this session has been signed out. Please sign in again.": "Aus Sicherheitsgründen wurde diese Sitzung beendet. Bitte melde dich erneut an.", - "Found a bug?": "Fehler gefunden?", "Guests cannot join this room even if explicitly invited.": "Gäste können diesem Raum nicht beitreten, auch wenn sie explizit eingeladen wurden.", "Hangup": "Auflegen", "Homeserver is": "Home-Server:", @@ -398,7 +396,6 @@ "New passwords don't match": "Die neuen Passwörter stimmen nicht überein", "olm version:": "Version von olm:", "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 Seitenende springen", "Show timestamps in 12 hour format (e.g. 2:30pm)": "Zeitstempel im 12-Stunden-Format anzeigen (z. B. 2:30pm)", @@ -653,11 +650,9 @@ "Define the power level of a user": "Setze das Berechtigungslevel eines Benutzers", "Edit": "Editieren", "Enable automatic language detection for syntax highlighting": "Automatische Spracherkennung für die Syntax-Hervorhebung aktivieren", - "Hide Apps": "Apps verbergen", "Hide join/leave messages (invites/kicks/bans unaffected)": "Betreten-/Verlassen-Benachrichtigungen verbergen (gilt nicht für Einladungen/Kicks/Bans)", "Revoke widget access": "Ziehe Widget-Zugriff zurück", "Sets the room topic": "Setzt das Raum-Thema", - "Show Apps": "Apps anzeigen", "To get started, please pick a username!": "Um zu starten, wähle bitte einen Nutzernamen!", "Unable to create widget.": "Widget kann nicht erstellt werden.", "Unbans user with given id": "Verbannung aufheben für Benutzer mit angegebener ID", @@ -692,7 +687,6 @@ "You are no longer ignoring %(userId)s": "%(userId)s wird nicht mehr ignoriert", "Message removed by %(userId)s": "Nachricht wurde von %(userId)s entfernt", "Name or matrix ID": "Name oder Matrix-ID", - "Unable to leave room": "Verlassen des Raumes fehlgeschlagen", "Leave": "Verlassen", "Failed to invite the following users to %(groupId)s:": "Die folgenden Benutzer konnten nicht in die Gruppe %(groupId)s eingeladen werden:", "Leave %(groupName)s?": "%(groupName)s verlassen?", @@ -913,7 +907,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", "Status.im theme": "Status.im-Thema", "%(duration)ss": "%(duration)ss", "%(duration)sm": "%(duration)sm", @@ -992,7 +985,6 @@ "Key request sent.": "Schlüssel-Anfragen gesendet.", "Re-request encryption keys from your other devices.": "Verschlüsselungs-Schlüssel von deinen anderen Geräten erneut anfragen.", "%(user)s is a %(userRole)s": "%(user)s ist ein %(userRole)s", - "Changes made to your community might not be seen by other users for up to 30 minutes.": "Änderungen, die an deiner Community gemacht werden, können bis zu 30 Minuten brauchen, bis sie für andere sichtbar sind.", "Debug Logs Submission": "Einsenden des Fehlerprotokolls", "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contian messages.": "Wenn du einen Fehler via GitHub gemeldet hast, können Fehlerberichte uns helfen um das Problem zu finden. Sie enthalten Anwendungsdaten wie deinen Nutzernamen, Raum- und Gruppen-ID's und Aliase die du besucht hast und Nutzernamen anderer Nutzer. Sie enthalten keine Nachrichten.", "Submit debug logs": "Fehlerberichte einreichen", @@ -1003,5 +995,167 @@ "Unable to leave community": "Community konnte nicht verlassen werden", "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Änderungen am Namen und Bild deiner Community werden evtl. erst nach 30 Minuten von anderen Nutzern gesehen werden.", "Join this community": "Community beitreten", - "Leave this community": "Community verlassen" + "Leave this community": "Community verlassen", + "Sticker Messages": "Sticker-Nachrichten", + "You don't currently have any stickerpacks enabled": "Du hast aktuell keine Stickerpacks aktiviert", + "Add a stickerpack": "Füge ein Stickerpack hinzu", + "Hide Stickers": "Sticker verbergen", + "Show Stickers": "Sticker zeigen", + "Who can join this community?": "Wer kann dieser Community beitreten?", + "Everyone": "Jeder", + "Stickerpack": "Stickerpack", + "Fetching third party location failed": "Das Abrufen des Drittanbieterstandorts ist fehlgeschlagen", + "A new version of Riot is available.": "Eine neue Version von Riot ist verfügbar.", + "Couldn't load home page": "Startseite konnte nicht geladen werden", + "Send Account Data": "Benutzerkonto-Daten senden", + "All notifications are currently disabled for all targets.": "Aktuell sind alle Benachrichtigungen für alle Ziele deaktiviert.", + "Uploading report": "Lade Bericht hoch", + "Sunday": "Sonntag", + "Notification targets": "Benachrichtigungsziele", + "Today": "Heute", + "Files": "Dateien", + "You are not receiving desktop notifications": "Du erhältst keine Desktop-Benachrichtigungen", + "Friday": "Freitag", + "Update": "Aktualisieren", + "What's New": "Was ist neu", + "Add an email address above to configure email notifications": "Füge oben eine E-Mail-Adresse hinzu, um die E-Mail-Benachrichtigungseinstellungen zu konfigurieren", + "Expand panel": "Panel ausklappen", + "On": "An", + "%(count)s Members|other": "%(count)s Mitglieder", + "Filter room names": "Raum-Namen filtern", + "Changelog": "Änderungsprotokoll", + "Waiting for response from server": "Auf Antwort vom Server warten", + "Send Custom Event": "Benutzerdefiniertes Event senden", + "Advanced notification settings": "Erweiterte Benachrichtigungs-Einstellungen", + "Failed to send logs: ": "Senden von Logs fehlgeschlagen: ", + "delete the alias.": "Lösche den Alias.", + "To return to your account in future you need to set a password": "Um in Zukunft auf dein Benutzerkonto zugreifen zu können, musst du ein Passwort setzen", + "Forget": "Entfernen", + "#example": "#Beispiel", + "Hide panel": "Panel verbergen", + "You cannot delete this image. (%(code)s)": "Das Bild kann nicht gelöscht werden. (%(code)s)", + "Cancel Sending": "Senden abbrechen", + "This Room": "In diesem Raum", + "The Home Server may be too old to support third party networks": "Der Home-Server ist eventuell zu alt, um Drittanbieter-Netzwerke zu unterstützen", + "Resend": "Erneut senden", + "Room not found": "Raum nicht gefunden", + "Messages containing my display name": "Nachrichten, die meinen Anzeigenamen enthalten", + "Messages in one-to-one chats": "Nachrichten in Einzel-Chats", + "Unavailable": "Nicht verfügbar", + "View Decrypted Source": "Entschlüsselten Quellcode ansehen", + "Failed to update keywords": "Schlüsselwörter konnten nicht aktualisiert werden", + "Notes:": "Notizen:", + "remove %(name)s from the directory.": "entferne %(name)s aus dem Verzeichnis.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Die Benachrichtigungen zu den folgenden Schlüsselwörtern folgen Regeln, die hier nicht angezeigt werden können:", + "Safari and Opera work too.": "Safari und Opera sind weitere Alternativen.", + "Please set a password!": "Bitte setze ein Passwort!", + "You have successfully set a password!": "Du hast erfolgreich ein Passwort gesetzt!", + "An error occurred whilst saving your email notification preferences.": "Beim Speichern deiner E-Mail-Benachrichtigungseinstellungen ist ein Fehler aufgetreten.", + "Explore Room State": "Raum-Status erkunden", + "Source URL": "Quell-URL", + "Messages sent by bot": "Nachrichten von Bots", + "Filter results": "Ergebnisse filtern", + "Members": "Mitglieder", + "No update available.": "Kein Update verfügbar.", + "Noisy": "Laut", + "Failed to get protocol list from Home Server": "Fehler beim Abrufen der Protokoll-Liste vom Home-Server", + "Collecting app version information": "App-Versionsinformationen werden abgerufen", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Soll der Raum-Alias %(alias)s gelöscht und der %(name)s aus dem Verzeichnis entfernt werden?", + "This will allow you to return to your account after signing out, and sign in on other devices.": "Dies erlaubt dir, dich wieder an deinem Konto anzumelden, nachdem du dich abgemeldet hast.", + "Keywords": "Schlüsselwörter", + "Enable notifications for this account": "Benachrichtigungen für dieses Benutzerkonto aktivieren", + "Directory": "Raum-Verzeichnis", + "Invite to this community": "In diese Community einladen", + "Failed to get public room list": "Die Liste der öffentlichen Räume konnte nicht geladen werden", + "Messages containing keywords": "Nachrichten, die Schlüsselwörter enthalten", + "Error saving email notification preferences": "Fehler beim Speichern der E-Mail-Benachrichtigungseinstellungen", + "Tuesday": "Dienstag", + "Enter keywords separated by a comma:": "Schlüsselwörter kommagetrennt eingeben:", + "Forward Message": "Nachricht weiterleiten", + "You have successfully set a password and an email address!": "Du hast erfolgreich ein Passwort und eine E-Mail-Adresse gesetzt!", + "Remove %(name)s from the directory?": "Soll der Raum %(name)s aus dem Verzeichnis entfernt werden?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot nutzt zahlreiche fortgeschrittene Browser-Funktionen, die teilweise in deinem aktuell verwendeten Browser noch nicht verfügbar sind oder sich noch im experimentellen Status befinden.", + "Developer Tools": "Entwicklerwerkzeuge", + "Preparing to send logs": "Senden von Logs wird vorbereitet", + "Enable desktop notifications": "Desktop-Benachrichtigungen aktivieren", + "Remember, you can always set an email address in user settings if you change your mind.": "Vergiss nicht, dass du in den Benutzereinstellungen jederzeit eine E-Mail-Adresse setzen kannst, wenn du deine Meinung änderst.", + "Explore Account Data": "Benutzerkonto-Daten analysieren", + "All messages (noisy)": "Alle Nachrichten (laut)", + "Saturday": "Samstag", + "I understand the risks and wish to continue": "Ich verstehe das Risiko und möchte fortfahren", + "Direct Chat": "Direkt-Chat", + "The server may be unavailable or overloaded": "Der Server ist vermutlich nicht erreichbar oder überlastet", + "Reject": "Ablehnen", + "Failed to set Direct Message status of room": "Konnte den direkten Benachrichtigungsstatus nicht setzen", + "Monday": "Montag", + "Remove from Directory": "Aus dem Raum-Verzeichnis entfernen", + "Enable them now": "Aktiviere diese jetzt", + "Messages containing my user name": "Nachrichten, die meinen Benutzernamen enthalten", + "Toolbox": "Werkzeugkasten", + "Collecting logs": "Protokolle werden abgerufen", + "more": "mehr", + "GitHub issue link:": "Link des GitHub-Problems:", + "You must specify an event type!": "Du musst einen Event-Typ spezifizieren!", + "(HTTP status %(httpStatus)s)": "(HTTP-Status %(httpStatus)s)", + "Invite to this room": "In diesen Raum einladen", + "Please install Chrome or Firefox for the best experience.": "Bitte installiere Chrome oder Firefox für ein optimales Anwendungsergebnis.", + "Wednesday": "Mittwoch", + "You cannot delete this message. (%(code)s)": "Diese Nachricht kann nicht gelöscht werden. (%(code)s)", + "Quote": "Zitat", + "Send logs": "Logdateien übermitteln", + "All messages": "Alle Nachrichten", + "Call invitation": "Anruf-Einladung", + "Downloading update...": "Update wird heruntergeladen...", + "State Key": "Status-Schlüssel", + "Failed to send custom event.": "Senden des benutzerdefinierten Events fehlgeschlagen.", + "What's new?": "Was ist neu?", + "Notify me for anything else": "Über alles andere benachrichtigen", + "When I'm invited to a room": "Wenn ich in einen Raum eingeladen werde", + "Click here to create a GitHub issue.": "Klicke hier um ein GithHub-Problem zu erstellen.", + "Can't update user notification settings": "Benachrichtigungs-Einstellungen des Benutzers konnten nicht aktualisiert werden", + "Notify for all other messages/rooms": "Benachrichtigungen für alle anderen Mitteilungen/Räume aktivieren", + "Unable to look up room ID from server": "Es ist nicht möglich, die Raum-ID auf dem Server nachzuschlagen", + "Couldn't find a matching Matrix room": "Konnte keinen entsprechenden Matrix-Raum finden", + "All Rooms": "In allen Räumen", + "Search for a room": "Nach einem Raum suchen", + "Thursday": "Donnerstag", + "Search…": "Suchen…", + "Logs sent": "Logs gesendet", + "Back": "Zurück", + "Reply": "Antworten", + "Show message in desktop notification": "Nachricht in der Desktop-Benachrichtigung anzeigen", + "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Fehlerberichte enthalten Anwendungsdaten wie deinen Nutzernamen, Raum- und Gruppen-ID's und Aliase die du besucht hast sowie Nutzernamen anderer Nutzer. Sie enthalten keine Nachrichten.", + "Unhide Preview": "Vorschau wieder anzeigen", + "Unable to join network": "Es ist nicht möglich, dem Netzwerk beizutreten", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Du hast sie eventuell auf einem anderen Matrix-Client und nicht in Riot konfiguriert. Sie können in Riot nicht verändert werden, gelten aber trotzdem", + "Sorry, your browser is not able to run Riot.": "Es tut uns leid, aber dein Browser kann Riot nicht ausführen.", + "Messages in group chats": "Nachrichten in Gruppen-Chats", + "Yesterday": "Gestern", + "Error encountered (%(errorDetail)s).": "Es ist ein Fehler aufgetreten (%(errorDetail)s).", + "Login": "Anmeldung", + "Low Priority": "Niedrige Priorität", + "Unable to fetch notification target list": "Liste der Benachrichtigungsempfänger konnte nicht abgerufen werden", + "Set Password": "Passwort einrichten", + "Enable audible notifications in web client": "Audio-Benachrichtigungen im Web-Client aktivieren", + "Permalink": "Permanenter Link", + "Off": "Aus", + "Riot does not know how to join a room on this network": "Riot weiß nicht, wie es einem Raum auf diesem Netzwerk beitreten soll", + "Mentions only": "Nur, wenn du erwähnt wirst", + "You can now return to your account after signing out, and sign in on other devices.": "Du kannst nun zu deinem Benutzerkonto zurückkehren, nachdem du dich abgemeldet hast. Anschließend kannst du dich an anderen Geräten anmelden.", + "Enable email notifications": "E-Mail-Benachrichtigungen aktivieren", + "Event Type": "Event-Typ", + "Download this file": "Datei herunterladen", + "Pin Message": "Nachricht anheften", + "Failed to change settings": "Einstellungen konnten nicht geändert werden", + "View Community": "Community ansehen", + "%(count)s Members|one": "%(count)s Mitglied", + "Event sent!": "Event gesendet!", + "View Source": "Quellcode ansehen", + "Event Content": "Event-Inhalt", + "Thank you!": "Danke!", + "Uploaded on %(date)s by %(user)s": "Hochgeladen: %(date)s von %(user)s", + "Collapse panel": "Panel einklappen", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "In deinem aktuell verwendeten Browser können Aussehen und Handhabung der Anwendung unter Umständen noch komplett fehlerhaft sein, so dass einige bzw. im Extremfall alle Funktionen nicht zur Verfügung stehen. Du kannst es trotzdem versuchen und fortfahren, bist dabei aber bezüglich aller auftretenden Probleme auf dich allein gestellt!", + "Checking for an update...": "Nach Updates suchen...", + "There are advanced notifications which are not shown here": "Es existieren erweiterte Benachrichtigungen, welche hier nicht angezeigt werden" } diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index 25cfc6cc82..d9fc51ce28 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -57,7 +57,6 @@ "Banned users": "Utilisateurs bannis", "Bans user with given id": "Bannit l'utilisateur à partir de son identifiant", "Blacklisted": "Sur liste noire", - "Bug Report": "Rapport d'erreur", "Call Timeout": "Délai d’appel expiré", "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Impossible de se connecter au serveur d'accueil en HTTP si l'URL dans la barre de votre explorateur est en HTTPS. Utilisez HTTPS ou activez le support des scripts non-vérifiés.", "Can't load user settings": "Impossible de charger les paramètres de l'utilisateur", @@ -93,8 +92,8 @@ "Current password": "Mot de passe actuel", "Curve25519 identity key": "Clé d’identité Curve25519", "/ddg is not a command": "/ddg n'est pas une commande", - "Deactivate Account": "Supprimer le compte", - "Deactivate my account": "Supprimer mon compte", + "Deactivate Account": "Désactiver le compte", + "Deactivate my account": "Désactiver mon compte", "Decrypt %(text)s": "Déchiffrer %(text)s", "Decryption error": "Erreur de déchiffrement", "Delete": "Supprimer", @@ -133,7 +132,6 @@ "Forget room": "Oublier le salon", "Forgot your password?": "Mot de passe oublié ?", "For security, this session has been signed out. Please sign in again.": "Par mesure de sécurité, la session a expiré. Merci de vous authentifier à nouveau.", - "Found a bug?": "Vous avez trouvé un problème ?", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s de %(fromPowerLevel)s à %(toPowerLevel)s", "Hangup": "Raccrocher", "Hide read receipts": "Cacher les accusés de lecture", @@ -241,7 +239,6 @@ "%(senderName)s removed their profile picture.": "%(senderName)s a supprimé son image de profil.", "Remove %(threePid)s?": "Supprimer %(threePid)s ?", "%(senderName)s requested a VoIP conference.": "%(senderName)s a demandé une téléconférence audio.", - "Report it": "Le signaler", "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.": "Pour le moment, réinitialiser le mot de passe va réinitialiser les clés de chiffrement sur tous les appareils, rendant l’historique des salons chiffrés illisible, à moins que vous exportiez d'abord les clés de salon puis que vous les ré-importiez après. Cela sera amélioré prochainement.", "Return to login screen": "Retourner à l’écran de connexion", "Riot does not have permission to send you notifications - please check your browser settings": "Riot n’a pas la permission de vous envoyer des notifications - merci de vérifier les paramètres de votre navigateur", @@ -651,11 +648,9 @@ "Define the power level of a user": "Définir le rang d'un utilisateur", "Edit": "Modifier", "Enable automatic language detection for syntax highlighting": "Activer la détection automatique de la langue pour la correction orthographique", - "Hide Apps": "Masquer les applications", "Hide join/leave messages (invites/kicks/bans unaffected)": "Masquer les messages d'arrivée/départ (n'affecte pas les invitations/exclusions/bannissements)", "Revoke widget access": "Révoquer les accès du widget", "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 un widget.", "Unbans user with given id": "Révoque le bannissement de l'utilisateur à partir de son identifiant", @@ -862,7 +857,6 @@ "Leave Community": "Quitter la communauté", "Leave %(groupName)s?": "Quitter %(groupName)s ?", "Leave": "Quitter", - "Unable to leave room": "Impossible de partir du salon", "Community Settings": "Paramètres de la communauté", "Add rooms to this community": "Ajouter des salons à cette communauté", "%(inviter)s has invited you to join this community": "%(inviter)s vous a invité à rejoindre cette communauté", @@ -906,7 +900,6 @@ "Username on %(hs)s": "Nom d'utilisateur sur %(hs)s", "Restricted": "Restreint", "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", @@ -992,7 +985,6 @@ "Key request sent.": "Demande de clé envoyée.", "Re-request encryption keys from your other devices.": "Re-demander les clés de chiffrement depuis vos autres appareils.", "%(user)s is a %(userRole)s": "%(user)s est %(userRole)s", - "Changes made to your community might not be seen by other users for up to 30 minutes.": "Les changements effectués sur votre communauté peuvent ne pas apparaître pour les autres utilisateurs avant 30 minutes.", "Seen by %(displayName)s (%(userName)s) at %(dateTime)s": "Vu par %(displayName)s (%(userName)s) à %(dateTime)s", "Code": "Code", "Debug Logs Submission": "Envoi des journaux de débogage", @@ -1007,13 +999,162 @@ "Stickerpack": "Pack de stickers", "Sticker Messages": "Messages sticker", "You don't currently have any stickerpacks enabled": "Vous n'avez activé aucun pack de stickers pour l'instant", - "Click": "Cliquer", - "here": "ici", - "to add some!": "pour en ajouter !", "Add a stickerpack": "Ajouter un pack de stickers", "Hide Stickers": "Masquer les stickers", "Show Stickers": "Afficher les stickers", - "Manage sticker packs": "Gérer les packs de stickers", "Who can join this community?": "Qui peut rejoindre cette communauté ?", - "Everyone": "Tout le monde" + "Everyone": "Tout le monde", + "Fetching third party location failed": "Échec de la récupération de la localisation tierce", + "A new version of Riot is available.": "Une nouvelle version de Riot est disponible.", + "Couldn't load home page": "Impossible de charger la page d'accueil", + "Send Account Data": "Envoyer les données du compte", + "All notifications are currently disabled for all targets.": "Toutes les notifications sont désactivées pour tous les appareils.", + "Uploading report": "Envoi du rapport", + "Sunday": "Dimanche", + "Notification targets": "Appareils recevant les notifications", + "Today": "Aujourd'hui", + "Files": "Fichiers", + "You are not receiving desktop notifications": "Vous ne recevez pas les notifications sur votre bureau", + "Friday": "Vendredi", + "Update": "Mettre à jour", + "What's New": "Nouveautés", + "Add an email address above to configure email notifications": "Ajouter une adresse e-mail pour la configuration des notifications par e-mail", + "Expand panel": "Dévoiler le panneau", + "On": "Activé", + "%(count)s Members|other": "%(count)s membres", + "Filter room names": "Filtrer les salons par nom", + "Changelog": "Journal des modifications", + "Waiting for response from server": "En attente d’une réponse du serveur", + "Send Custom Event": "Envoyer l'événement personnalisé", + "Advanced notification settings": "Paramètres de notification avancés", + "delete the alias.": "supprimer l'alias.", + "To return to your account in future you need to set a password": "Pour pouvoir retrouver votre compte dans le futur, vous devez définir un mot de passe", + "Forget": "Oublier", + "#example": "#exemple", + "Hide panel": "Cacher le panneau", + "You cannot delete this image. (%(code)s)": "Vous ne pouvez pas supprimer cette image. (%(code)s)", + "Cancel Sending": "Annuler l'envoi", + "This Room": "Ce salon", + "The Home Server may be too old to support third party networks": "Le serveur d'accueil semble trop ancien pour supporter des réseaux tiers", + "Noisy": "Bruyant", + "Room not found": "Salon non trouvé", + "Messages containing my display name": "Messages contenant mon nom affiché", + "Messages in one-to-one chats": "Messages dans les discussions directes", + "Unavailable": "Indisponible", + "View Decrypted Source": "Voir la source déchiffrée", + "Failed to update keywords": "Échec dans la mise à jour des mots-clés", + "remove %(name)s from the directory.": "supprimer %(name)s du répertoire.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Les notifications pour les mots-clés suivant répondent à des critères qui ne peuvent pas être affichés ici :", + "Safari and Opera work too.": "Safari et Opera fonctionnent également.", + "Please set a password!": "Veuillez définir un mot de passe !", + "You have successfully set a password!": "Vous avez défini un mot de passe avec succès !", + "An error occurred whilst saving your email notification preferences.": "Une erreur est survenue lors de la sauvegarde de vos préférences de notification par e-mail.", + "Explore Room State": "Parcourir l'état du salon", + "Source URL": "URL de la source", + "Messages sent by bot": "Messages envoyés par des robots", + "Filter results": "Filtrer les résultats", + "Members": "Membres", + "No update available.": "Aucune mise à jour disponible.", + "Resend": "Renvoyer", + "Failed to get protocol list from Home Server": "Échec lors de la récupération de la liste sur le serveur", + "Collecting app version information": "Récupération des informations de version de l’application", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Supprimer l'alias %(alias)s du salon et supprimer %(name)s du répertoire ?", + "This will allow you to return to your account after signing out, and sign in on other devices.": "Cela vous permettra de retourner sur votre compte après vous être déconnecté, et de vous identifier sur d'autres appareils.", + "Keywords": "Mots-clés", + "Enable notifications for this account": "Activer les notifications pour ce compte", + "Directory": "Répertoire", + "Invite to this community": "Inviter à cette communauté", + "Failed to get public room list": "Échec lors de la récupération de la liste des salons publics", + "Messages containing keywords": "Messages contenant des mots-clés", + "Error saving email notification preferences": "Erreur lors de la sauvegarde des préférences de notification par e-mail", + "Tuesday": "Mardi", + "Enter keywords separated by a comma:": "Entrez les mots-clés séparés par une virgule :", + "Search…": "Rechercher…", + "You have successfully set a password and an email address!": "Vous avez défini un mot de passe et une adresse e-mail avec succès !", + "Remove %(name)s from the directory?": "Supprimer %(name)s du répertoire ?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot utilise de nombreuses fonctionnalités avancées du navigateur, certaines ne sont pas disponibles ou expérimentales dans votre navigateur actuel.", + "Developer Tools": "Outils de développement", + "Enable desktop notifications": "Activer les notifications de bureau", + "Remember, you can always set an email address in user settings if you change your mind.": "Souvenez-vous que vous pourrez toujours définir une adresse e-mail dans les paramètres de l'utilisateur si vous changez d’avis.", + "Explore Account Data": "Explorer les données du compte", + "Remove from Directory": "Supprimer du répertoire", + "Saturday": "Samedi", + "I understand the risks and wish to continue": "Je comprends les risques et souhaite continuer", + "Direct Chat": "Discussion directe", + "The server may be unavailable or overloaded": "Le serveur est indisponible ou surchargé", + "Reject": "Rejeter", + "Failed to set Direct Message status of room": "Échec du réglage de l'état du salon en Discussion directe", + "Monday": "Lundi", + "All messages (noisy)": "Tous les messages (fort)", + "Enable them now": "Les activer maintenant", + "Messages containing my user name": "Message contenant mon nom d'utilisateur", + "Toolbox": "Boîte à outils", + "Collecting logs": "Récupération des journaux", + "more": "plus", + "You must specify an event type!": "Vous devez spécifier un type d'événement !", + "(HTTP status %(httpStatus)s)": "(état HTTP %(httpStatus)s)", + "Invite to this room": "Inviter dans ce salon", + "Please install Chrome or Firefox for the best experience.": "Veuillez installer Chrome ou Firefox pour une expérience optimale.", + "Wednesday": "Mercredi", + "You cannot delete this message. (%(code)s)": "Vous ne pouvez pas supprimer ce message. (%(code)s)", + "Quote": "Citer", + "Send logs": "Envoyer les journaux", + "All messages": "Tous les messages", + "Call invitation": "Appel entrant", + "Downloading update...": "Mise à jour en cours de téléchargement...", + "State Key": "Clé d'état", + "Failed to send custom event.": "Échec de l'envoi de l'événement personnalisé.", + "What's new?": "Nouveautés ?", + "Notify me for anything else": "Me notifier pour tout le reste", + "View Source": "Voir la source", + "Can't update user notification settings": "Impossible de mettre à jour les paramètres de notification de l'utilisateur", + "Notify for all other messages/rooms": "Me notifier pour tous les autres messages/salons", + "Unable to look up room ID from server": "Impossible de récupérer l'ID du salon sur le serveur", + "Couldn't find a matching Matrix room": "Impossible de trouver un salon Matrix correspondant", + "All Rooms": "Tous les salons", + "Search for a room": "Rechercher un salon", + "Thursday": "Jeudi", + "Forward Message": "Transférer le message", + "Back": "Retour", + "Reply": "Répondre", + "Show message in desktop notification": "Afficher le message dans les notifications de bureau", + "Unhide Preview": "Dévoiler l'aperçu", + "Unable to join network": "Impossible de rejoindre le réseau", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Vous les avez probablement configurées dans un autre client que Riot. Vous ne pouvez pas les configurer dans Riot mais elles s'appliquent quand même", + "Sorry, your browser is not able to run Riot.": "Désolé, Riot n'est pas supporté par votre navigateur.", + "Uploaded on %(date)s by %(user)s": "Téléchargé le %(date)s par %(user)s", + "Messages in group chats": "Messages dans les discussions de groupe", + "Yesterday": "Hier", + "Error encountered (%(errorDetail)s).": "Erreur rencontrée (%(errorDetail)s).", + "Login": "Connexion", + "Low Priority": "Priorité basse", + "Unable to fetch notification target list": "Impossible de récupérer la liste des appareils recevant les notifications", + "Set Password": "Définir un mot de passe", + "Enable audible notifications in web client": "Activer les notifications sonores pour le client web", + "Permalink": "Permalien", + "Off": "Désactivé", + "Riot does not know how to join a room on this network": "Riot ne peut pas joindre un salon sur ce réseau", + "Mentions only": "Seulement les mentions", + "You can now return to your account after signing out, and sign in on other devices.": "Vous pouvez maintenant revenir sur votre compte après vous être déconnecté, et vous identifier sur d'autres appareils.", + "Enable email notifications": "Activer les notifications par e-mail", + "Event Type": "Type d'événement", + "Download this file": "Télécharger ce fichier", + "Pin Message": "Épingler le message", + "Failed to change settings": "Échec de la mise à jour des paramètres", + "View Community": "Voir la communauté", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Depuis votre navigateur actuel, le visuel et le ressenti de l'application pourraient être complètement erronés, et certaines fonctionnalités pourraient ne pas être supportées. Vous pouvez continuer malgré tout, mais vous n'aurez aucune aide si vous rencontrez des problèmes !", + "%(count)s Members|one": "%(count)s membre", + "Event sent!": "Événement envoyé !", + "Event Content": "Contenu de l'événement", + "Thank you!": "Merci !", + "Collapse panel": "Cacher le panneau", + "When I'm invited to a room": "Quand je suis invité dans un salon", + "Checking for an update...": "Recherche de mise à jour...", + "There are advanced notifications which are not shown here": "Il existe une configuration avancée des notifications qui ne peut être affichée ici", + "Logs sent": "Rapports envoyés", + "GitHub issue link:": "Lien du signalement GitHub :", + "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Les rapports de débogage contiennent des données d'usage de l'application qui incluent votre nom d'utilisateur, les identifiants ou alias des salons ou groupes auxquels vous avez rendu visite ainsi que les noms des autres utilisateurs. Ils ne contiennent aucun message.", + "Failed to send logs: ": "Échec lors de l'envoi des rapports : ", + "Notes:": "Notes :", + "Preparing to send logs": "Préparation d'envoi des rapports" } diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index b7f20d52f7..5fe1e90163 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -10,7 +10,7 @@ "Mute": "Elnémít", "Notifications": "Értesítések", "Operation failed": "Sikertelen művelet", - "powered by Matrix": "A Matrix hajtja", + "powered by Matrix": "Matrix hajtja", "Remove": "Eltávolítás", "Settings": "Beállítások", "unknown error code": "ismeretlen hibakód", @@ -69,7 +69,6 @@ "Banned users": "Kitiltott felhasználók", "Bans user with given id": "Kitiltja a felhasználót a megadott ID-vel", "Blacklisted": "Fekete listára téve", - "Bug Report": "Hiba jelentés", "Bulk Options": "Tömeges beállítások", "Call Timeout": "Hívás időtúllépés", "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.": "Nem lehet kapcsolódni a saját szerverhez - ellenőrizd a kapcsolatot, biztosítsd, hogy a saját szerver tanúsítványa hiteles legyen, és a böngésző kiterjesztések ne blokkolják a kéréseket.", @@ -192,7 +191,6 @@ "Forgot your password?": "Elfelejtetted a jelszavad?", "For security, this session has been signed out. Please sign in again.": "A biztonság érdekében ez a kapcsolat le lesz bontva. Légy szíves jelentkezz be újra.", "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.": "A biztonság érdekében a kilépéskor a ponttól pontig való (E2E) titkosításhoz szükséges kulcsok törlésre kerülnek a böngészőből. Ha a régi üzeneteket továbbra is el szeretnéd olvasni, kérlek mentsed ki a szobákhoz tartozó kulcsot.", - "Found a bug?": "Hibát találtál?", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s : %(fromPowerLevel)s -> %(toPowerLevel)s", "Guest access is disabled on this Home Server.": "Vendég belépés tiltva van a Saját szerveren.", "Guests cannot join this room even if explicitly invited.": "Vendégek akkor sem csatlakozhatnak ehhez a szobához ha külön meghívók kaptak.", @@ -309,7 +307,6 @@ "%(senderName)s removed their profile picture.": "%(senderName)s törölte a profil képét.", "Remove %(threePid)s?": "Töröl: %(threePid)s?", "%(senderName)s requested a VoIP conference.": "%(senderName)s VoIP konferenciát kezdeményez.", - "Report it": "Jelent", "Results from DuckDuckGo": "Eredmények a DuckDuckGo-ból", "Return to login screen": "Vissza a bejelentkezési képernyőre", "Riot does not have permission to send you notifications - please check your browser settings": "Riotnak nincs jogosultsága értesítést küldeni neked - ellenőrizd a böngésző beállításait", @@ -652,13 +649,11 @@ "Define the power level of a user": "A felhasználó szintjének meghatározása", "Edit": "Szerkeszt", "Enable automatic language detection for syntax highlighting": "Nyelv automatikus felismerése szintaxis kiemeléshez", - "Hide Apps": "Alkalmazások elrejtése", "Hide join/leave messages (invites/kicks/bans unaffected)": "Belép/kilép üzenetek elrejtése (meghívók, kirúgások, kitiltások nem érintettek)", "AM": "de", "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 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", @@ -702,7 +697,7 @@ "Disable Emoji suggestions while typing": "Emoji ajánlások kikapcsolása gépelés közben", "Banned by %(displayName)s": "Kitiltotta: %(displayName)s", "Message removed by %(userId)s": "Üzenetet törölte: %(userId)s", - "To send messages, you must be a": "Ahhoz, hogy üzenetet tudj küldeni, neked ilyen szinten kell lenned:", + "To send messages, you must be a": "Ahhoz, hogy üzenetet tudj küldeni, ilyen szinten kell lenned:", "To invite users into the room, you must be a": "Hogy meghívj valakit a szobába, ilyen szinten kell lenned:", "To configure the room, you must be a": "A szoba beállításához ilyen szinten kell lenned:", "To kick users, you must be a": "Felhasználó kirúgásához ilyen szinten kell lenned:", @@ -712,14 +707,13 @@ "To change the room's avatar, you must be a": "A szoba avatarjának a megváltoztatásához ilyen szinten kell lenned:", "To change the room's name, you must be a": "A szoba nevének megváltoztatásához ilyen szinten kell lenned:", "To change the room's main address, you must be a": "A szoba elsődleges címének a megváltoztatásához ilyen szinten kell lenned:", - "To change the room's history visibility, you must be a": "A szoba naplója elérhetőségének a megváltoztatásához ilyen szinten kell lenned:", + "To change the room's history visibility, you must be a": "A szoba napló elérhetőségének a megváltoztatásához ilyen szinten kell lenned:", "To change the permissions in the room, you must be a": "A szobában a jogosultság megváltoztatásához ilyen szinten kell lenned:", "To change the topic, you must be a": "A téma megváltoztatásához ilyen szinten kell lenned:", "To modify widgets in the room, you must be a": "A szoba kisalkalmazásainak megváltoztatásához ilyen szinten kell lenned:", "Description": "Leírás", "Name or matrix ID": "Név vagy Matrix azonosító", "Unable to accept invite": "A meghívót nem lehet elfogadni", - "Unable to leave room": "A szobát nem lehet elhagyni", "Leave": "Elhagy", "Failed to invite the following users to %(groupId)s:": "Az alábbi felhasználókat nem sikerült meghívni a(z) %(groupId)s:", "Failed to invite users to %(groupId)s": "Nem sikerült meghívni a felhasználókat ebbe a csoportba: %(groupId)s", @@ -736,7 +730,7 @@ "Failed to remove the room from the summary of %(groupId)s": "Az alábbi szobákat nem sikerült eltávolítani a(z) %(groupId)s csoport összefoglalójából", "The room '%(roomName)s' could not be removed from the summary.": "Nem sikerült törölni az összefoglalóból ezt a szobát: '%(roomName)s'.", "Failed to remove a user from the summary of %(groupId)s": "Nem sikerült törölni az összefoglalóból ezt a felhasználót: %(groupId)s", - "The user '%(displayName)s' could not be removed from the summary.": "Nem sikerült törölni az összefoglalóból ezt a felhasználót: %(groupId)s.", + "The user '%(displayName)s' could not be removed from the summary.": "Nem sikerült törölni az összefoglalóból a(z) %(displayName)s felhasználót", "Light theme": "Világos téma", "Dark theme": "Sötét téma", "Unknown": "Ismeretlen", @@ -906,7 +900,6 @@ "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", "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", @@ -984,7 +977,7 @@ "Failed to add tag %(tagName)s to room": "Nem sikerült hozzáadni a szobához ezt: %(tagName)s", "Clear filter": "Szűrő törlése", "Disable Community Filter Panel": "Közösség keresési panel tiltása", - "Did you know: you can use communities to filter your Riot.im experience!": "Tudtad, hogy a közösségeket használhatod a Riot.im élmény fokozásához?", + "Did you know: you can use communities to filter your Riot.im experience!": "Tudtad, hogy a Riot.im élmény fokozásához használhatsz közösségeket?", "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "A szűrő beállításához húzd a közösség avatarját a szűrő panel fölé a képernyő bal szélén. A szűrő panelen az avatarra kattintva bármikor leszűrheted azokat a szobákat és embereket akik a megadott közösséghez tartoznak.", "Your key share request has been sent - please check your other devices for key share requests.": "A kulcs megosztási kérést elküldtük - ellenőrizd a többi eszközödön a kulcs megosztási kéréseket.", "Key share requests are sent to your other devices automatically. If you rejected or dismissed the key share request on your other devices, click here to request the keys for this session again.": "A kulcs megosztási kérelem automatikusan el lett küldve a többi eszközödre. Ha elutasítottad vagy törölted a kérést a másik eszközön ide kattintva újra kérheted a kulcsokat.", @@ -992,7 +985,6 @@ "Key request sent.": "Kulcs kérés elküldve.", "Re-request encryption keys from your other devices.": "Kulcsok újrakérése a többi eszközödtől.", "%(user)s is a %(userRole)s": "%(user)s egy %(userRole)s", - "Changes made to your community might not be seen by other users for up to 30 minutes.": "A közösségedben végrehajtott változtatás valószínűleg legalább 30 percig nem lesz látható mások számára.", "Code": "Kód", "Debug Logs Submission": "Hibakeresési napló elküldése", "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contian messages.": "Ha a GitHubon keresztül küldted be a hibát, a hibakeresési napló segíthet nekünk a javításban. A napló felhasználási adatokat tartalmaz mint a felhasználói neved, az általad meglátogatott szobák vagy csoportok azonosítóját vagy alternatív nevét és mások felhasználói nevét. De nem tartalmazzák az üzeneteket.", @@ -1007,13 +999,163 @@ "Stickerpack": "Matrica csomag", "Sticker Messages": "Matrica üzenetek", "You don't currently have any stickerpacks enabled": "Nincs engedélyezett matrica csomagod", - "Click": "Kattints", - "here": "ide", - "to add some!": "hogy adj hozzá párat!", "Add a stickerpack": "Matrica csomag hozzáadása", "Hide Stickers": "Matricák elrejtése", "Show Stickers": "Matricák megjelenítése", - "Manage sticker packs": "Matrica csomagok kezelése", "Who can join this community?": "Ki tud csatlakozni ehhez a közösséghez?", - "Everyone": "Mindenki" + "Everyone": "Mindenki", + "Fetching third party location failed": "Nem sikerült lekérdezni a harmadik fél helyét", + "A new version of Riot is available.": "Elérhető egy új Riot verzió.", + "Couldn't load home page": "Nem sikerült betölteni a kezdőlapot", + "Send Account Data": "Fiókadatok küldése", + "All notifications are currently disabled for all targets.": "Minden céleszközön minden értesítés tiltva van.", + "Uploading report": "Jelentés feltöltése", + "Sunday": "Vasárnap", + "Notification targets": "Értesítések célpontja", + "Today": "Ma", + "Files": "Fájlok", + "You are not receiving desktop notifications": "Nem fogadsz asztali értesítéseket", + "Friday": "Péntek", + "Update": "Frissítés", + "What's New": "Újdonságok", + "Add an email address above to configure email notifications": "E-mail értesítések beállításához adj meg egy e-mail címet", + "Expand panel": "Panel kinyitása", + "On": "Be", + "%(count)s Members|other": "%(count)s tag", + "Filter room names": "Szobanevek szűrése", + "Changelog": "Változások", + "Waiting for response from server": "Várakozás a szerver válaszára", + "Send Custom Event": "Egyéni esemény elküldése", + "Advanced notification settings": "Haladó értesítési beállítások", + "Failed to send logs: ": "Hiba a napló küldésénél: ", + "delete the alias.": "becenév törlése.", + "To return to your account in future you need to set a password": "Hogy később visszaléphess a fiókodba, be kell állítanod egy jelszót", + "Forget": "Elfelejt", + "#example": "#példa", + "Hide panel": "Panel elrejtése", + "You cannot delete this image. (%(code)s)": "Nem törölheted ezt a képet. (%(code)s)", + "Cancel Sending": "Küldés megszakítása", + "This Room": "Ebben a szobában", + "The Home Server may be too old to support third party networks": "Lehet, hogy a saját szerver túl régi és nem támogatja a csatlakozást más hálózatokhoz", + "Resend": "Küldés újra", + "Room not found": "A szoba nem található", + "Messages containing my display name": "A profilnevemet tartalmazó üzenetek", + "Messages in one-to-one chats": "Személyes beszélgetések üzenetei", + "Unavailable": "Elérhetetlen", + "View Decrypted Source": "Visszafejtett forrás megjelenítése", + "Failed to update keywords": "Nem lehet frissíteni a kulcsszavakat", + "Notes:": "Jegyzetek:", + "remove %(name)s from the directory.": "%(name)s szoba törlése a listából.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Az alábbi kulcsszavakról jövő értesítések szabályait nem lehet itt megjeleníteni:", + "Safari and Opera work too.": "Safarival és Operával is működik.", + "Please set a password!": "Állíts be egy jelszót!", + "You have successfully set a password!": "Sikerült beállítani a jelszót!", + "An error occurred whilst saving your email notification preferences.": "Hiba történt az e-mail értesítési beállításaid mentése közben.", + "Explore Room State": "Szoba állapot felderítése", + "Source URL": "Forrás URL", + "Messages sent by bot": "Botok üzenetei", + "Filter results": "Találatok szűrése", + "Members": "Résztvevők", + "No update available.": "Nincs elérhető frissítés.", + "Noisy": "Hangos", + "Failed to get protocol list from Home Server": "Nem sikerült a protokoll listát lekérni a saját szerverről", + "Collecting app version information": "Alkalmazás verzió információk összegyűjtése", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Törlöd a szoba nevét (%(alias)s) és eltávolítod a listából ezt: %(name)s?", + "This will allow you to return to your account after signing out, and sign in on other devices.": "Így kijelentkezés után is vissza tudsz lépni a fiókodba, illetve más készülékekről is be tudsz lépni.", + "Keywords": "Kulcsszavak", + "Enable notifications for this account": "Értesítések engedélyezése ehhez a fiókhoz", + "Directory": "Könyvtár", + "Invite to this community": "Meghívás ebbe a közösségbe", + "Search for a room": "Szoba keresése", + "Messages containing keywords": "Kulcsszavakat tartalmazó üzenetek", + "Error saving email notification preferences": "Hiba az e-mail értesítési beállítások mentésekor", + "Tuesday": "Kedd", + "Enter keywords separated by a comma:": "Kulcsszavak vesszővel elválasztva:", + "Forward Message": "Üzenet továbbítása", + "You have successfully set a password and an email address!": "Sikerült beállítani a jelszavad és e-mail címed!", + "Remove %(name)s from the directory?": "Törlöd ezt a szobát a listából: %(name)s?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "A Riot sok fejlett böngészőfunkciót használ, amelyeknek egy része egyáltalán nem, vagy csak kísérleti jelleggel érhető el a jelenlegi böngésződben.", + "Developer Tools": "Fejlesztői eszközök", + "Preparing to send logs": "Előkészülés napló küldéshez", + "Enable desktop notifications": "Asztali értesítések engedélyezése", + "Remember, you can always set an email address in user settings if you change your mind.": "Ha meggondolod magad, bármikor beállíthatod az e-mail címed a felhasználói beállításoknál.", + "Explore Account Data": "Fiókadatok felderítése", + "Remove from Directory": "Törlés a listából", + "Saturday": "Szombat", + "I understand the risks and wish to continue": "Megértettem a kockázatot és folytatom", + "Direct Chat": "Közvetlen csevegés", + "The server may be unavailable or overloaded": "A szerver nem elérhető vagy túlterhelt", + "Reject": "Elutasít", + "Failed to set Direct Message status of room": "Nem lehet beállítani a szoba közvetlen beszélgetés státuszát", + "Monday": "Hétfő", + "All messages (noisy)": "Minden üzenet (hangos)", + "Enable them now": "Engedélyezés most", + "Messages containing my user name": "A felhasználónevemet tartalmazó üzenetek", + "Toolbox": "Eszköztár", + "Collecting logs": "Naplók összegyűjtése", + "more": "tovább", + "GitHub issue link:": "GitHub hibajegy hivatkozás:", + "You must specify an event type!": "Meg kell jelölnöd az eseménytípust!", + "(HTTP status %(httpStatus)s)": "(HTTP állapot: %(httpStatus)s)", + "Invite to this room": "Meghívás a szobába", + "Please install Chrome or Firefox for the best experience.": "A legjobb élmény érdekében telepíts Chrome vagy Firefox böngészőt.", + "Failed to get public room list": "Nem sikerült lekérdezni a nyilvános szobák listáját", + "Quote": "Idéz", + "Send logs": "Naplófájlok elküldése", + "All messages": "Minden üzenet", + "Call invitation": "Hívás meghívó", + "Downloading update...": "Frissítés letöltése...", + "State Key": "Állapotkulcs", + "Failed to send custom event.": "Nem sikerült elküldeni az egyéni eseményt.", + "What's new?": "Mik az újdonságok?", + "Notify me for anything else": "Értesíts minden egyéb esetben", + "When I'm invited to a room": "Amikor meghívnak egy szobába", + "Click here to create a GitHub issue.": "Kattints ide GitHub hibajegy nyitásához .", + "Can't update user notification settings": "Nem lehet frissíteni az értesítési beállításokat", + "Notify for all other messages/rooms": "Értesítés minden más üzenethez/szobához", + "Unable to look up room ID from server": "Nem lehet a szoba azonosítóját megkeresni a szerveren", + "Couldn't find a matching Matrix room": "Nem található a keresett Matrix szoba", + "All Rooms": "Minden szobában", + "You cannot delete this message. (%(code)s)": "Nem törölheted ezt az üzenetet. (%(code)s)", + "Thursday": "Csütörtök", + "Search…": "Keresés…", + "Logs sent": "Napló elküldve", + "Back": "Vissza", + "Reply": "Válasz", + "Show message in desktop notification": "Üzenetek megjelenítése az asztali értesítéseknél", + "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "A hibakereső napló alkalmazás használati adatokat tartalmaz beleértve a felhasználói nevedet, az általad meglátogatott szobák és csoportok azonosítóit alternatív neveit és más felhasználói neveket. Csevegés üzenetek szövegét nem tartalmazza.", + "Unhide Preview": "Előnézet mutatása", + "Unable to join network": "Nem sikerült kapcsolódni a hálózathoz", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Egy másik, nem Riot-klienssel állítothattad be. A Riotban módosítani nem tudod ezeket, de érvényben vannak", + "Sorry, your browser is not able to run Riot.": "Elnézést, a böngésződben nem fut a Riot.", + "Uploaded on %(date)s by %(user)s": "Feltöltötte %(user)s ekkor: %(date)s", + "Messages in group chats": "Csoportszobák üzenetei", + "Yesterday": "Tegnap", + "Error encountered (%(errorDetail)s).": "Hiba történt (%(errorDetail)s).", + "Login": "Bejelentkezés", + "Low Priority": "Alacsony prioritás", + "Unable to fetch notification target list": "Nem sikerült letölteni az értesítési célok listáját", + "Set Password": "Jelszó beállítása", + "Enable audible notifications in web client": "Hangértesítések engedélyezése a webkliensben", + "Permalink": "Állandó hivatkozás", + "Off": "Ki", + "Riot does not know how to join a room on this network": "A Riot nem tud csatlakozni szobához ezen a hálózaton", + "Mentions only": "Csak ha megemlítenek", + "Wednesday": "Szerda", + "You can now return to your account after signing out, and sign in on other devices.": "Most már kijelentkezés után is vissza tudsz lépni a fiókodba, és más készülékekről is be tudsz lépni.", + "Enable email notifications": "E-mail értesítések engedélyezése", + "Event Type": "Esemény típusa", + "Download this file": "Fájl letöltése", + "Pin Message": "Üzenet rögzítése", + "Failed to change settings": "A beállítások megváltoztatása nem sikerült", + "View Community": "Közösség megtekintése", + "%(count)s Members|one": "%(count)s tag", + "Event sent!": "Az esemény elküldve!", + "View Source": "Forrás megjelenítése", + "Event Content": "Esemény tartalma", + "Thank you!": "Köszönjük!", + "Collapse panel": "Panel becsukása", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Ebben a böngészőben az alkalmazás felülete tele lehet hibával, és az is lehet, hogy egyáltalán nem működik. Ha így is ki szeretnéd próbálni, megteheted, de ha valami gondod van, nem tudunk segíteni!", + "Checking for an update...": "Frissítés keresése...", + "There are advanced notifications which are not shown here": "Vannak itt nem látható, haladó értesítések" } diff --git a/src/i18n/strings/nl.json b/src/i18n/strings/nl.json index d4bda9c6da..6c78265a4d 100644 --- a/src/i18n/strings/nl.json +++ b/src/i18n/strings/nl.json @@ -29,7 +29,6 @@ "Banned users": "Verbannen gebruikers", "Bans user with given id": "Verbant de gebruiker met het gegeven ID", "Blacklisted": "Buitengesloten", - "Bug Report": "Bug report", "Bulk Options": "Bulk opties", "Call Timeout": "Gesprek time-out", "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Kan niet met de thuisserver verbinden via HTTP wanneer er een HTTPS-URL in je browser balk staat. Gebruik HTTPS of activeer onveilige scripts.", @@ -262,7 +261,6 @@ "Forgot your password?": "Wachtwoord vergeten?", "For security, this session has been signed out. Please sign in again.": "Voor veiligheidsredenen is deze sessie uitgelogd. Log alsjeblieft opnieuw in.", "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.": "In verband met veiligheidsredenen zullen alle end-to-endbeveiligingsleutels van deze browser verwijderd worden. Als je je gespreksgeschiedenis van toekomstige Riot sessies wilt kunnen ontsleutelen, exporteer en bewaar dan de ruimte sleutels.", - "Found a bug?": "Een fout gevonden?", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s van %(fromPowerLevel)s naar %(toPowerLevel)s", "Guest access is disabled on this Home Server.": "Gasttoegang is uitgeschakeld op deze thuisserver.", "Guests cannot join this room even if explicitly invited.": "Gasten kunnen niet tot deze ruimte toetreden, zelfs als ze expliciet uitgenodigd zijn.", @@ -340,7 +338,6 @@ "Press to start a chat with someone": "Druk op om een gesprek met iemand te starten", "Remove %(threePid)s?": "%(threePid)s verwijderen?", "%(senderName)s requested a VoIP conference.": "%(senderName)s heeft een VoIP-gesprek aangevraagd.", - "Report it": "Melden", "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.": "Het wachtwoord veranderen betekent momenteel dat alle end-to-endbeveiligingssleutels op alle apparaten veranderen waardoor versleutelde gespreksgeschiedenis onleesbaar wordt, behalve als je eerst de ruimte sleutels exporteert en daarna opnieuw importeert. Dit zal in de toekomst verbeterd worden.", "Results from DuckDuckGo": "Resultaten van DuckDuckGo", "Return to login screen": "Naar het inlogscherm terugkeren", @@ -654,7 +651,6 @@ "Do you want to load widget from URL:": "Wil je de widget laden van de URL:", "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)", "Integrations Error": "Integratiesfout", "Publish this room to the public in %(domain)s's room directory?": "Deze ruimte publiekelijk maken in %(domain)s's ruimte catalogus?", @@ -663,7 +659,6 @@ "NOTE: Apps are not end-to-end encrypted": "OPMERKING: Apps zijn niet end-to-endbeveiligd", "Revoke widget access": "Toegang tot widget intrekken", "Sets the room topic": "Wijzigt het ruimte-onderwerp", - "Show Apps": "Apps Weergeven", "The maximum permitted number of widgets have already been added to this room.": "Het maximum aantal toegestane widgets is al aan deze ruimte toegevoegd.", "To get started, please pick a username!": "Om te beginnen, kies een gebruikersnaam!", "Unable to create widget.": "Niet in staat om een widget te maken.", @@ -722,7 +717,6 @@ "Send": "Verstuur", "Message Pinning": "Boodschap vastpinnen", "Message Replies": "Antwoorden op bericht", - "Presence Management": "Presentie Beheer", "Tag Panel": "Label Paneel", "Disable Emoji suggestions while typing": "Emoji suggesties tijdens het typen uitzetten", "Hide avatar changes": "Avatar veranderingen verbergen", @@ -925,7 +919,6 @@ "Leave Community": "Gemeenschap Verlaten", "Leave %(groupName)s?": "%(groupName)s verlaten?", "Leave": "Verlaten", - "Unable to leave room": "De ruimte kon niet verlaten worden", "Community Settings": "Gemeenschapsinstellingen", "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Deze ruimtes worden aan gemeenschapsleden getoond op de gemeenschapspagina. Gemeenschapsleden kunnen tot de ruimtes toetreden door er op te klikken.", "%(inviter)s has invited you to join this community": "%(inviter)s heeft jou uitgenodigd om tot deze gemeenschap toe te treden", @@ -937,8 +930,6 @@ "Community %(groupId)s not found": "Gemeenschap %(groupId)s is niet gevonden", "This Home server does not support communities": "Deze Thuisserver ondersteunt geen gemeenschappen", "Failed to load %(groupId)s": "Het is niet gelukt om %(groupId)s te laden", - "Cryptography data migrated": "Cryptografie gegevens zijn gemigreerd", - "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.": "Een eenmalige migratie van cryptografie gegevens heeft plaatsgevonden. Eind-tot-eind versleuteling zal niet werken als je terug gaat naar een oudere versie van Riot. Log eerst uit op Riot als je eind-tot-eind versleuteling wil gebruiken op een oudere versie. Exporteer je sleutels en importeer ze achteraf weer als je de berichtgeschiedenis wilt behouden.", "Old cryptography data detected": "Oude cryptografie gegevens gedetecteerd", "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.": "Er zijn gegevens van een oudere versie van Riot gedetecteerd. Dit zal eind-tot-eind versleuteling laten storen in de oudere versie. Eind-tot-eind berichten dat recent zijn uitgewisseld zal misschien niet ontsleutelbaar zijn in deze versie. Dit zou er misschien ook voor kunnen zorgen dat berichten die zijn uitgewisseld in deze versie falen. Indien je problemen ervaart, log opnieuw in. Om de berichtgeschiedenis te behouden, exporteer de sleutels en importeer ze achteraf weer.", "Your Communities": "Jouw Gemeenschappen", @@ -994,5 +985,177 @@ "Clear filter": "Filter vrijmaken", "Failed to set direct chat tag": "Het is niet gelukt om de 'privégesprek' label in te stellen", "Failed to remove tag %(tagName)s from room": "Het is niet gelukt om de label %(tagName)s van de ruimte te verwijderen", - "Failed to add tag %(tagName)s to room": "Het is niet gelukt om de label %(tagName)s aan deze ruimte toe te voegen" + "Failed to add tag %(tagName)s to room": "Het is niet gelukt om de label %(tagName)s aan deze ruimte toe te voegen", + "Stickerpack": "Stickerpakket", + "Sticker Messages": "Sticker Berichten", + "You don't currently have any stickerpacks enabled": "Je hebt momenteel geen stickerpakketten aan staan", + "Add a stickerpack": "Stickerpakket toevoegen", + "Hide Stickers": "Stickers verbergen", + "Show Stickers": "Stickers weergeven", + "Seen by %(displayName)s (%(userName)s) at %(dateTime)s": "Gezien door %(displayName)s (%(userName)s) op %(dateTime)s", + "Code": "Code", + "Unable to join community": "Je kon niet tot de gemeenschap toetreden", + "Unable to leave community": "Je kon de gemeenschap niet verlaten", + "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Veranderingen die aan je gemeenschap naam en avatar zijn aangebracht zullen misschien niet gezien worden door anderen tot maximaal 30 minuten.", + "Join this community": "Tot deze gemeenschap toetreden", + "Who can join this community?": "Wie kan tot deze gemeenschap toetreden?", + "Everyone": "Iedereen", + "Leave this community": "Deze gemeenschap verlaten", + "Debug Logs Submission": "Debug Logs Indienen", + "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contian messages.": "Als je een bug via Github hebt ingediend kunnen debug logs ons helpen om het probleem te vinden. Debug logs bevatten applicatie-gebruik data inclusief je gebruikersnaam, de ID's of namen van de ruimtes en groepen die je hebt bezocht en de gebruikersnamen van andere gebruikers. Ze bevatten geen berichten.", + "Submit debug logs": "Debug logs indienen", + "Opens the Developer Tools dialog": "Opent het Ontwikkelaars Gereedschappen dialoog", + "Fetching third party location failed": "Het ophalen van de locatie van de derde partij is mislukt", + "A new version of Riot is available.": "Er is een nieuwe versie van Riot beschikbaar.", + "I understand the risks and wish to continue": "Ik begrijp de risico's en wil graag verder gaan", + "Couldn't load home page": "Kon de home pagina niet laden", + "Send Account Data": "Stuur account informatie", + "All notifications are currently disabled for all targets.": "Alle meldingen zijn momenteel uitgeschakeld voor alle doelen.", + "Uploading report": "Rapport uploaden", + "Sunday": "Zondag", + "Notification targets": "Meldingsdoelen", + "Today": "Vandaag", + "Files": "Bestanden", + "You are not receiving desktop notifications": "Je ontvangt momenteel geen desktopmeldingen", + "Friday": "Vrijdag", + "Update": "Bijwerken", + "What's New": "Wat is er nieuw", + "Add an email address above to configure email notifications": "Voeg een e-mailadres toe om e-mailmeldingen te ontvangen", + "Expand panel": "Paneel uitklappen", + "On": "Aan", + "%(count)s Members|other": "%(count)s Deelnemers", + "Filter room names": "Filter kamernamen", + "Changelog": "Logboek van wijzigingen", + "Waiting for response from server": "Wachten op antwoord van de server", + "Send Custom Event": "Verzend aangepast evenement", + "Advanced notification settings": "Geavanceerde meldingsinstellingen", + "delete the alias.": "verwijder de alias.", + "To return to your account in future you need to set a password": "Om in de toekomst naar je account terug te gaan moet je een wachtwoord instellen", + "Forget": "Vergeten", + "#example": "#voorbeeld", + "Hide panel": "Paneel verbergen", + "You cannot delete this image. (%(code)s)": "Je kunt deze afbeelding niet verwijderen. (%(code)s)", + "Cancel Sending": "Versturen annuleren", + "This Room": "Deze kamer", + "The Home Server may be too old to support third party networks": "De thuisserver is misschien te oud om netwerken van derde partijen te ondersteunen", + "Resend": "Opnieuw verzenden", + "Error saving email notification preferences": "Fout bij het opslaan van de meldingsvoorkeuren voor e-mail", + "Messages containing my display name": "Berichten die mijn weergavenaam bevatten", + "Messages in one-to-one chats": "Berichten in één-op-één-gesprekken", + "Unavailable": "Niet beschikbaar", + "View Decrypted Source": "Bekijk ontsleutelde bron", + "Failed to update keywords": "Trefwoorden bijwerken mislukt", + "remove %(name)s from the directory.": "verwijder %(name)s uit de kamerlijst.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Meldingen op de volgende trefwoorden volgen regels die hier niet kunnen worden getoond:", + "Safari and Opera work too.": "Safari en Opera werken ook.", + "Please set a password!": "Stel een wachtwoord in!", + "You have successfully set a password!": "U heeft met succes een wachtwoord ingesteld!", + "An error occurred whilst saving your email notification preferences.": "Er is een fout opgetreden tijdens het opslaan van uw e-mailmeldingsvoorkeuren.", + "Explore Room State": "Verken Ruimtetoestand", + "Source URL": "Bron-URL", + "Messages sent by bot": "Berichten verzonden door een bot", + "Filter results": "Resultaten filteren", + "Members": "Leden", + "No update available.": "Geen update beschikbaar.", + "Noisy": "Luidruchtig", + "Failed to get protocol list from Home Server": "Protocollijst ophalen van de homeserver mislukt", + "Collecting app version information": "App-versieinformatie verzamelen", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "De alias %(alias)s verwijderen en %(name)s uit de kamerlijst verwijderen?", + "This will allow you to return to your account after signing out, and sign in on other devices.": "Hiermee kunt u naar uw account terugkeren nadat u zich heeft afgemeld, en u aanmelden op andere apparaten.", + "Keywords": "Trefwoorden", + "Enable notifications for this account": "Meldingen voor dit account aanzetten", + "Directory": "Kamerlijst", + "Invite to this community": "Nodig uit in deze community", + "Search for a room": "Een kamer opzoeken", + "Messages containing keywords": "Berichten die trefwoorden bevatten", + "Room not found": "De kamer is niet gevonden", + "Tuesday": "Dinsdag", + "Enter keywords separated by a comma:": "Voeg trefwoorden toe, gescheiden door een komma:", + "Search…": "Zoeken…", + "You have successfully set a password and an email address!": "Het instellen van een wachtwoord en e-mailadres is geslaagd!", + "Remove %(name)s from the directory?": "%(name)s uit de kamerlijst verwijderen?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot gebrukt veel geavanceerde browserfuncties, waarvan enkele niet (of experimenteel) in uw webbrowser beschikbaar zijn.", + "Developer Tools": "Ontwikkelaarsgereedschap", + "Enable desktop notifications": "Desktopmeldingen aanzetten", + "Explore Account Data": "Bekijk account informatie", + "Remove from Directory": "Uit de kamerlijst verwijderen", + "Saturday": "Zaterdag", + "Remember, you can always set an email address in user settings if you change your mind.": "Onthoud dat u altijd een e-mailadres in kan stellen in de gebruikersinstellingen als u zich bedenkt.", + "Direct Chat": "Privégesprek", + "The server may be unavailable or overloaded": "De server is misschien niet beschikbaar of overbelast", + "Reject": "Afwijzen", + "Failed to set Direct Message status of room": "Het is mislukt om de directe-berichtenstatus van de kamer in te stellen", + "Monday": "Maandag", + "All messages (noisy)": "Alle berichten (luid)", + "Enable them now": "Deze nu aanzetten", + "Messages containing my user name": "Berichten die mijn gebruikersnaam bevatten", + "Toolbox": "Eigenschappen", + "Collecting logs": "Logboeken verzamelen", + "more": "meer", + "You must specify an event type!": "Je moet een event-type specificeren!", + "(HTTP status %(httpStatus)s)": "(HTTP-status %(httpStatus)s)", + "Invite to this room": "Uitnodigen voor deze kamer", + "Please install Chrome or Firefox for the best experience.": "Installeer alstublieft Chrome of Firefox voor de beste gebruikerservaring.", + "Failed to get public room list": "Lijst met publieke kamers ophalen mislukt", + "Send logs": "Logboeken versturen", + "All messages": "Alle berichten", + "Call invitation": "Oproep-uitnodiging", + "Downloading update...": "Update aan het downloaden...", + "State Key": "Toestandssleutel", + "Failed to send custom event.": "Aangepast Event verzenden mislukt.", + "What's new?": "Wat is er nieuw?", + "Notify me for anything else": "Stuur een melding voor al het andere", + "When I'm invited to a room": "Wanneer ik uitgenodigd word voor een kamer", + "Can't update user notification settings": "Het is niet gelukt om de meldingsinstellingen van de gebruiker bij te werken", + "Notify for all other messages/rooms": "Stuur een melding voor alle andere berichten/kamers", + "Unable to look up room ID from server": "Het is mislukt om de kamer-ID op te halen van de server", + "Couldn't find a matching Matrix room": "Het is niet gelukt om een bijbehorende Matrix-kamer te vinden", + "All Rooms": "Alle kamers", + "You cannot delete this message. (%(code)s)": "Je kunt dit bericht niet verwijderen. (%(code)s)", + "Thursday": "Donderdag", + "Forward Message": "Bericht doorsturen", + "Back": "Terug", + "Reply": "Beantwoord", + "Show message in desktop notification": "Toon boodschap in bureaublad popup", + "Unhide Preview": "Zichtbaar maken preview", + "Unable to join network": "Het is mislukt om toe te treden tot dit netwerk", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Je hebt ze mogelijk ingesteld in een andere client dan Riot. Je kunt ze niet aanpassen in Riot maar ze zijn wel actief", + "Sorry, your browser is not able to run Riot.": "Sorry, uw browser werkt niet met Riot.", + "Uploaded on %(date)s by %(user)s": "Geüpload op %(date)s door %(user)s", + "Messages in group chats": "Berichten in groepsgesprekken", + "Yesterday": "Gisteren", + "Error encountered (%(errorDetail)s).": "Fout ondervonden (%(errorDetail)s).", + "Login": "Aanmelden", + "Low Priority": "Lage prioriteit", + "Unable to fetch notification target list": "Het is mislukt om de lijst van notificatiedoelen op te halen", + "Set Password": "Wachtwoord instellen", + "Enable audible notifications in web client": "Geluidsmeldingen in de webclient aanzetten", + "Permalink": "Permanente link", + "Off": "Uit", + "Riot does not know how to join a room on this network": "Riot weet niet hoe het moet deelnemen in een kamer op dit netwerk", + "Mentions only": "Alleen vermeldingen", + "Wednesday": "Woensdag", + "You can now return to your account after signing out, and sign in on other devices.": "U kunt nu terugkeren naar uw account nadat u bent afgemeld, en u aanmelden op andere apparaten.", + "Enable email notifications": "E-mailmeldingen aanzetten", + "Event Type": "Event-type", + "Download this file": "Download dit bestand", + "Pin Message": "Bericht vastpinnen", + "Failed to change settings": "Instellingen wijzigen mislukt", + "View Community": "Gemeenschap Weergeven", + "%(count)s Members|one": "%(count)s Deelnemer", + "Event sent!": "Event verstuurd!", + "View Source": "Bekijk bron", + "Event Content": "Event-inhoud", + "Thank you!": "Bedankt!", + "Collapse panel": "Paneel inklappen", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Met uw huidige browser kan de applicatie er volledig incorrect uitzien. Tevens is het mogelijk dat niet alle functies naar behoren werken. U kunt doorgaan als u het toch wil proberen, maar bij problemen bent u volledig op uzelf aangewezen!", + "Checking for an update...": "Aan het kijken voor een update...", + "There are advanced notifications which are not shown here": "Er zijn geavanceerde notificaties die hier niet getoond worden", + "Logs sent": "Logs verstuurd", + "Click here to create a GitHub issue.": "Klik hier om een Github opgave in te dienen.", + "GitHub issue link:": "GitHub opgave link:", + "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Debug logs bevatten applicatie-gebruik data inclusief je gebruikersnaam, de ID's of namen van de ruimtes en groepen die je hebt bezocht en de gebruikersnamen van andere gebruikers. Ze bevatten geen berichten.", + "Failed to send logs: ": "Het is niet gelukt om de logs te versturen: ", + "Notes:": "Constateringen:", + "Preparing to send logs": "Voorbereiden om logs te versturen" } diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index d732be55da..8de9983f22 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -13,7 +13,6 @@ "Banned users": "Заблокированные пользователи", "Bans user with given id": "Блокирует пользователя с заданным ID", "Blacklisted": "В черном списке", - "Bug Report": "Отчет об ошибке", "Bulk Options": "Групповые параметры", "Can't load user settings": "Невозможно загрузить пользовательские настройки", "Changes to who can read history will only apply to future messages in this room": "Изменения того, кто может прочитать историю, будут применяться только к будущим сообщениям в этой комнате", @@ -61,7 +60,6 @@ "Forget room": "Забыть комнату", "Forgot your password?": "Забыли пароль?", "For security, this session has been signed out. Please sign in again.": "Для обеспечения безопасности ваша сессия была завершена. Пожалуйста, войдите снова.", - "Found a bug?": "Нашли ошибку?", "Hangup": "Закончить", "Historical": "Архив", "Homeserver is": "Домашний сервер это", @@ -314,7 +312,6 @@ "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s удалил свое отображаемое имя (%(oldDisplayName)s).", "%(senderName)s removed their profile picture.": "%(senderName)s удалил свое изображение профиля.", "%(senderName)s requested a VoIP conference.": "%(senderName)s хочет начать VoIP-конференцию.", - "Report it": "Сообщить об этом", "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.": "Сброс пароля на данный момент сбрасывает ключи шифрования на всех устройствах, делая зашифрованную историю чатов нечитаемой. Чтобы избежать этого, экспортируйте ключи комнат и импортируйте их после сброса пароля. В будущем это будет исправлено.", "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 не получил разрешение на отправку уведомлений, пожалуйста, попробуйте снова", @@ -654,7 +651,6 @@ "Do you want to load widget from URL:": "Загрузить виджет из URL-адреса:", "Edit": "Редактировать", "Enable automatic language detection for syntax highlighting": "Включить автоматическое определение языка для подсветки синтаксиса", - "Hide Apps": "Скрыть приложения", "Hide join/leave messages (invites/kicks/bans unaffected)": "Скрыть сообщения о входе/выходе (не применяется к приглашениям/выкидываниям/банам)", "Integrations Error": "Ошибка интеграции", "AM": "AM", @@ -662,7 +658,6 @@ "NOTE: Apps are not end-to-end encrypted": "ПРИМЕЧАНИЕ: приложения не защищены сквозным шифрованием", "Revoke widget access": "Отозвать доступ к виджетам", "Sets the room topic": "Задать тему комнаты", - "Show Apps": "Показать приложения", "The maximum permitted number of widgets have already been added to this room.": "Максимально допустимое количество виджетов уже добавлено в эту комнату.", "To get started, please pick a username!": "Чтобы начать, выберите имя пользователя!", "Unable to create widget.": "Не удалось создать виджет.", @@ -719,7 +714,6 @@ "Description": "Описание", "Name or matrix ID": "Имя или matrix ID", "Unable to accept invite": "Невозможно принять приглашение", - "Unable to leave room": "Невозможно покинуть комнату", "Leave": "Покинуть", "Failed to invite the following users to %(groupId)s:": "Не удалось пригласить следующих пользователей в %(groupId)s:", "Failed to remove '%(roomName)s' from %(groupId)s": "Не удалось удалить '%(roomName)s' из %(groupId)s", @@ -890,7 +884,6 @@ "Visibility in Room List": "Видимость в списке комнат", "Visible to everyone": "Видимый для всех", "Only visible to community members": "Только участникам сообщества", - "Presence Management": "Управление присутствием", "Hide avatar changes": "Скрыть изменения аватара", "Hide display name changes": "Скрыть изменения отображаемого имени", "Enable inline URL previews by default": "Включить просмотр URL-адресов по умолчанию", @@ -958,7 +951,7 @@ "Send a reply (unencrypted)…": "Отправить ответ (незашифрованный)…", "Send an encrypted message…": "Отправить зашифрованное сообщение…", "Send a message (unencrypted)…": "Отправить сообщение (незашифрованное)…", - "Replying": "Отвечая", + "Replying": "Отвечает", "Minimize apps": "Свернуть приложения", "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.": "Подробнее о том, как мы используем аналитику.", @@ -992,7 +985,6 @@ "%(user)s is a %(userRole)s": "%(user)s является %(userRole)s", "Your key share request has been sent - please check your other devices for key share requests.": "Ваш запрос на передачу ключей отправлен - пожалуйста, проверьте другие ваши устройства на запросы передачи ключей.", "Key share requests are sent to your other devices automatically. If you rejected or dismissed the key share request on your other devices, click here to request the keys for this session again.": "Запросы передачи ключей автоматически отправляются на другие устройства. Если вы отклонили или отменили запрос на передачу ключей на других устройствах, нажмите здесь, чтобы запросить ключи для этого сеанса повторно.", - "Changes made to your community might not be seen by other users for up to 30 minutes.": "Изменения, сделанные в вашем сообществе, могут не отображаться для других пользователей в течение 30 минут.", "Code": "Код", "Debug Logs Submission": "Отправка журналов отладки", "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contian messages.": "Если вы отправили ошибку через GitHub, журналы отладки могут помочь нам выявить проблему. Журналы отладки содержат данные об использовании приложения, включая ваше имя пользователя, идентификаторы или псевдонимы комнат или групп, которые вы посетили, а также имена других пользователей. Они не содержат сообщений.", @@ -1004,9 +996,165 @@ "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Изменения имени и аватара, внесенные в ваше сообщество, могут не отображаться другим пользователям в течение 30 минут.", "Join this community": "Присоединиться к сообществу", "Leave this community": "Покинуть это сообщество", - "here": "здесь", - "to add some!": "для добавления!", - "Click": "Нажмите", "Who can join this community?": "Кто может присоединиться к этому сообществу?", - "Everyone": "Все" + "Everyone": "Все", + "Stickerpack": "Этикетки", + "Sticker Messages": "Сообщения этикеткой", + "Add a stickerpack": "Добавить этикетки", + "Hide Stickers": "Скрыть этикетки", + "Show Stickers": "Показать этикетки", + "Fetching third party location failed": "Не удалось извлечь местоположение третьей стороны", + "A new version of Riot is available.": "Доступна новая версия Riot.", + "I understand the risks and wish to continue": "Я понимаю риски и желаю продолжить", + "Couldn't load home page": "Не удалось загрузить домашнюю страницу", + "Send Account Data": "Отправить данные аккаунта", + "All notifications are currently disabled for all targets.": "Все оповещения для всех устройств отключены.", + "Uploading report": "Отправка отчета", + "Sunday": "Воскресенье", + "Notification targets": "Цели уведомления", + "Today": "Сегодня", + "Files": "Файлы", + "You are not receiving desktop notifications": "Вы не получаете уведомления на рабочем столе", + "Friday": "Пятница", + "Update": "Обновление", + "What's New": "Что нового", + "Add an email address above to configure email notifications": "Добавьте email адрес для оповещений", + "Expand panel": "Развернуть панель", + "On": "Включить", + "%(count)s Members|other": "%(count)s членов", + "Filter room names": "Фильтр по названию комнат", + "Changelog": "История изменений", + "Waiting for response from server": "Ожидание ответа от сервера", + "Uploaded on %(date)s by %(user)s": "Отправлено %(date)s для %(user)s", + "Send Custom Event": "Отправить индивидуальное мероприятие", + "Advanced notification settings": "Дополнительные параметры уведомлений", + "Failed to send logs: ": "Не удалось отправить журналы: ", + "delete the alias.": "удалить псевдоним.", + "To return to your account in future you need to set a password": "Чтобы вернуться к учетной записи в будущем, необходимо задать пароль", + "Forget": "Забыть", + "#example": "#пример", + "Hide panel": "Скрыть панель", + "You cannot delete this image. (%(code)s)": "Это изображение нельзя удалить. (%(code)s)", + "Cancel Sending": "Отменить отправку", + "This Room": "Эта комната", + "The Home Server may be too old to support third party networks": "Домашний сервер может быть слишком старым для поддержки сетей сторонних производителей", + "Noisy": "Со звуком", + "Room not found": "Комната не найдена", + "Messages containing my display name": "Сообщения, содержащие мое имя", + "Messages in one-to-one chats": "Сообщения в индивидуальных чатах", + "Unavailable": "Недоступен", + "Error saving email notification preferences": "Ошибка при сохранении настроек уведомлений по email", + "View Decrypted Source": "Просмотр расшифрованного источника", + "Failed to update keywords": "Не удалось обновить ключевые слова", + "Notes:": "Заметки:", + "remove %(name)s from the directory.": "удалить %(name)s из каталога.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Уведомления по следующим ключевым словам соответствуют правилам, которые нельзя отобразить здесь:", + "Safari and Opera work too.": "Safari и Opera работают тоже.", + "Please set a password!": "Пожалуйста, установите пароль!", + "You have successfully set a password!": "Вы успешно установили пароль!", + "An error occurred whilst saving your email notification preferences.": "Возникла ошибка при сохранении настроек оповещения по email.", + "Explore Room State": "Просмотр статуса комнаты", + "Source URL": "Исходный URL-адрес", + "Messages sent by bot": "Сообщения, отправленные ботом", + "Filter results": "Фильтрация результатов", + "Members": "Участники", + "No update available.": "Нет доступных обновлений.", + "Resend": "Переотправить", + "Failed to get protocol list from Home Server": "Не удалось получить список протоколов с домашнего сервера", + "Collecting app version information": "Сбор информации о версии приложения", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Удалить псевдоним комнаты %(alias)s и удалить %(name)s из каталога?", + "This will allow you to return to your account after signing out, and sign in on other devices.": "Это позволит вам вернуться к учетной записи после выхода из системы и войти на других устройствах.", + "Keywords": "Ключевые слова", + "Enable notifications for this account": "Включить уведомления для этой учетной записи", + "Directory": "Каталог", + "Invite to this community": "Пригласить в это сообщество", + "Search for a room": "Поиск комнаты", + "Messages containing keywords": "Сообщения, содержащие определенные ключевые слова", + "View Source": "Просмотр источника", + "Tuesday": "Вторник", + "Enter keywords separated by a comma:": "Введите ключевые слова, разделенные запятой:", + "Search…": "Поиск.…", + "You have successfully set a password and an email address!": "Вы успешно установили пароль и адрес email!", + "Remove %(name)s from the directory?": "Удалить %(name)s из каталога?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot использует многие передовые возможности браузера, некоторые из которых недоступны или являются экспериментальным в вашем текущем браузере.", + "Developer Tools": "Инструменты разработчика", + "Preparing to send logs": "Подготовка к отправке журналов", + "Enable desktop notifications": "Включить оповещения на рабочем столе", + "Explore Account Data": "Просмотр данных аккаунта", + "All messages (noisy)": "Все сообщения (со звуком)", + "Saturday": "Суббота", + "Remember, you can always set an email address in user settings if you change your mind.": "Помните, что вы всегда сможете задать адрес email в настройках пользователя, если передумаете.", + "Direct Chat": "Прямой чат", + "The server may be unavailable or overloaded": "Сервер, вероятно, недоступен или перегружен", + "Reject": "Отклонить", + "Failed to set Direct Message status of room": "Не удалось установить статус прямого сообщения в комнате", + "Monday": "Понедельник", + "Remove from Directory": "Удалить из каталога", + "Enable them now": "Включить сейчас", + "Messages containing my user name": "Сообщение, содержащие мое имя пользователя", + "Toolbox": "Панель инструментов", + "Collecting logs": "Сбор журналов", + "more": "больше", + "GitHub issue link:": "Ссылка на проблему в GitHub:", + "You must specify an event type!": "Необходимо указать тип мероприятия!", + "(HTTP status %(httpStatus)s)": "(статус HTTP %(httpStatus)s)", + "Invite to this room": "Пригласить в комнату", + "Please install Chrome or Firefox for the best experience.": "Лучший опыт вы получите, установив Chrome или Firefox.", + "Failed to get public room list": "Не удалось получить список общедоступных комнат", + "Send logs": "Отправка журналов", + "All messages": "Все сообщения", + "Call invitation": "Пригласительный звонок", + "Downloading update...": "Загрузка обновления...", + "State Key": "Ключ состояния", + "Failed to send custom event.": "Не удалось отправить индивидуальное мероприятие.", + "What's new?": "Что нового?", + "Notify me for anything else": "Уведомлять во всех остальных случаях", + "When I'm invited to a room": "Когда меня приглашают в комнату", + "Click here to create a GitHub issue.": "Нажмите здесь для создания запроса о проблеме на GitHub.", + "Can't update user notification settings": "Не удается обновить пользовательские настройки оповещения", + "Notify for all other messages/rooms": "Уведомлять обо всех других сообщениях/комнатах", + "Unable to look up room ID from server": "Не удалось найти ID комнаты на сервере", + "Couldn't find a matching Matrix room": "Не удалось найти подходящую комнату Matrix", + "All Rooms": "Все комнаты", + "You cannot delete this message. (%(code)s)": "Это сообщение нельзя удалить. (%(code)s)", + "Thursday": "Четверг", + "Forward Message": "Переслать сообщение", + "Logs sent": "Журналы отправлены", + "Back": "Назад", + "Reply": "Ответить", + "Show message in desktop notification": "Показывать сообщение в уведомлении на рабочем столе", + "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Журналы отладки содержат данные об использовании приложения, включая ваше имя пользователя, идентификаторы или псевдонимы комнат или групп, которые вы посетили, а также имена других пользователей. Они не содержат сообщений.", + "Unhide Preview": "Показать предварительный просмотр", + "Unable to join network": "Не удается подключиться к сети", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Возможно вы настроили их не в Riot, а в другом Matrix-клиенте. Настроить их в Riot не удастся, но они будут в нем применяться", + "Sorry, your browser is not able to run Riot.": "К сожалению, ваш браузер не способен запустить Riot.", + "Messages in group chats": "Сообщения в групповых чатах", + "Yesterday": "Вчера", + "Error encountered (%(errorDetail)s).": "Обнаружена ошибка (%(errorDetail)s).", + "Login": "Войти", + "Low Priority": "Низкий приоритет", + "Unable to fetch notification target list": "Не удалось получить список целей уведомления", + "Set Password": "Задать пароль", + "Enable audible notifications in web client": "Включить звуковые уведомления в веб-клиенте", + "Permalink": "Постоянная ссылка", + "Off": "Выключить", + "Riot does not know how to join a room on this network": "Riot не знает, как присоединиться к комнате, принадлежащей к этой сети", + "Mentions only": "Только при упоминаниях", + "Wednesday": "Среда", + "You can now return to your account after signing out, and sign in on other devices.": "Теперь вы сможете вернуться к своей учетной записи после выхода из системы и войти на других устройствах.", + "Enable email notifications": "Включить уведомления по email", + "Event Type": "Тип мероприятия", + "Download this file": "Скачать этот файл", + "Pin Message": "Закрепить сообщение", + "Failed to change settings": "Не удалось изменить настройки", + "View Community": "Просмотр сообщества", + "%(count)s Members|one": "%(count)s член", + "Event sent!": "Мероприятие отправлено!", + "Event Content": "Содержание мероприятия", + "Thank you!": "Спасибо!", + "Quote": "Цитата", + "Collapse panel": "Свернуть панель", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "В текущем браузере внешний вид приложения может быть полностью неверным, а некоторые или все функции могут не работать. Если вы хотите попробовать в любом случае, то можете продолжить, но с теми проблемами, с которыми вы можете столкнуться вам придется разбираться самостоятельно!", + "Checking for an update...": "Проверка обновлений...", + "There are advanced notifications which are not shown here": "Существуют дополнительные уведомления, которые не показаны здесь" } diff --git a/src/i18n/strings/sk.json b/src/i18n/strings/sk.json index 72ba11b6d4..c915ae04b4 100644 --- a/src/i18n/strings/sk.json +++ b/src/i18n/strings/sk.json @@ -263,8 +263,6 @@ "Hangup": "Zavesiť", "Voice call": "Audio hovor", "Video call": "Video hovor", - "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", "You do not have permission to post to this room": "Nemáte udelené právo posielať do tejto miestnosti", @@ -296,15 +294,15 @@ "Seen by %(userName)s at %(dateTime)s": "%(userName)s videl %(dateTime)s", "Unnamed room": "Nepomenovaná miestnosť", "World readable": "Viditeľné pre každého", - "Guests can join": "Aj hostia môžu vstúpiť", + "Guests can join": "Môžu vstúpiť aj hostia", "No rooms to show": "Žiadne miestnosti na zobrazenie", - "Failed to set avatar.": "Nepodarilo sa nastaviť avatara.", + "Failed to set avatar.": "Nepodarilo sa nastaviť obrázok.", "Save": "Uložiť", "(~%(count)s results)|other": "(~%(count)s výsledkov)", "(~%(count)s results)|one": "(~%(count)s výsledok)", "Join Room": "Vstúpiť do miestnosti", - "Upload avatar": "Nahrať avatara", - "Remove avatar": "Odstrániť avatara", + "Upload avatar": "Nahrať obrázok", + "Remove avatar": "Odstrániť obrázok", "Settings": "Nastavenia", "Forget room": "Zabudnúť miestnosť", "Search": "Hľadať", @@ -341,7 +339,7 @@ "You are trying to access a room.": "Pristupujete k miestnosti.", "Click here to join the discussion!": "Kliknutím sem vstúpite do diskusie!", "This is a preview of this room. Room interactions have been disabled": "Toto je náhľad na miestnosť. Všetky akcie pre túto miestnosť sú zakázané", - "To change the room's avatar, you must be a": "Aby ste mohli meniť avatara miestnosti, musíte byť", + "To change the room's avatar, you must be a": "Aby ste mohli meniť obrázok miestnosti, musíte byť", "To change the room's name, you must be a": "Aby ste mohli meniť názov miestnosti, musíte byť", "To change the room's main address, you must be a": "Aby ste mohli meniť hlavnú adresu miestnosti, musíte byť", "To change the room's history visibility, you must be a": "Aby ste mohli meniť viditeľnosť histórie miestnosti, musíte byť", @@ -428,9 +426,9 @@ "Image '%(Body)s' cannot be displayed.": "Nie je možné zobraziť obrázok '%(Body)s'.", "This image cannot be displayed.": "Tento obrázok nie je možné zobraziť.", "Error decrypting video": "Chyba pri dešifrovaní videa", - "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s zmenil avatara pre %(roomName)s", - "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s z miestnosti odstránil avatara.", - "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s zmenil avatara miestnosti na ", + "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s zmenil obrázok miestnosti %(roomName)s", + "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s odstránil obrázok miestnosti.", + "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s zmenil obrázok miestnosti ", "Copied!": "Skopírované!", "Failed to copy": "Nepodarilo sa skopírovať", "Add an Integration": "Pridať integráciu", @@ -553,10 +551,10 @@ "%(severalUsers)schanged their name %(count)s times|one": "%(severalUsers)ssi zmenili meno", "%(oneUser)schanged their name %(count)s times|other": "%(oneUser)ssi %(count)s krát zmenil meno", "%(oneUser)schanged their name %(count)s times|one": "%(oneUser)ssi zmenil meno", - "%(severalUsers)schanged their avatar %(count)s times|other": "%(severalUsers)ssi %(count)s krát zmenili avatara", - "%(severalUsers)schanged their avatar %(count)s times|one": "%(severalUsers)ssi zmenili avatara", - "%(oneUser)schanged their avatar %(count)s times|other": "%(oneUser)ssi %(count)s krát zmenil avatara", - "%(oneUser)schanged their avatar %(count)s times|one": "%(oneUser)ssi zmenil avatara", + "%(severalUsers)schanged their avatar %(count)s times|other": "%(severalUsers)ssi %(count)s krát zmenili obrázok v profile", + "%(severalUsers)schanged their avatar %(count)s times|one": "%(severalUsers)ssi zmenili obrázok v profile", + "%(oneUser)schanged their avatar %(count)s times|other": "%(oneUser)ssi %(count)s krát zmenil obrázok v profile", + "%(oneUser)schanged their avatar %(count)s times|one": "%(oneUser)ssi zmenil obrázok v profile", "%(items)s and %(count)s others|other": "%(items)s a %(count)s ďalší", "%(items)s and %(count)s others|one": "%(items)s a jeden ďalší", "%(items)s and %(lastItem)s": "%(items)s a tiež %(lastItem)s", @@ -673,7 +671,6 @@ "Leave Community": "Opustiť komunitu", "Leave %(groupName)s?": "Opustiť komunitu %(groupName)s?", "Leave": "Opustiť", - "Unable to leave room": "Nie je možné opustiť miestnosť", "Community Settings": "Nastavenia komunity", "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Tieto miestnosti sú zobrazené všetkým členom na stránke komunity. Členovia komunity môžu vstúpiť do miestnosti kliknutím.", "Add rooms to this community": "Pridať miestnosti do tejto komunity", @@ -773,9 +770,6 @@ "Device ID:": "ID zariadenia:", "Device key:": "Kľúč zariadenia:", "Ignored Users": "Ignorovaní používatelia", - "Bug Report": "Hlásenie chyby", - "Found a bug?": "Našli ste chybu?", - "Report it": "Ohláste ju", "Analytics": "Analytické údaje", "Riot collects anonymous analytics to allow us to improve the application.": "Riot zbiera anonymné analytické údaje, čo nám umožňuje aplikáciu ďalej zlepšovať.", "Labs": "Experimenty", @@ -837,9 +831,9 @@ "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "K domovskému serveru nie je možné pripojiť sa použitím protokolu HTTP keďže v adresnom riadku prehliadača máte HTTPS adresu. Použite protokol HTTPS alebo povolte nezabezpečené skripty.", "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.": "Nie je možné pripojiť sa k domovskému serveru - skontrolujte prosím funkčnosť vašeho pripojenia na internet, uistite sa že certifikát domovského servera je dôverihodný, a že žiaden doplnok nainštalovaný v prehliadači nemôže blokovať požiadavky.", "Login as guest": "Prihlásiť sa ako hosť", - "Failed to fetch avatar URL": "Nepodarilo sa získať URL adresu avatara", + "Failed to fetch avatar URL": "Nepodarilo sa získať URL adresu obrázka", "Set a display name:": "Nastaviť zobrazované meno:", - "Upload an avatar:": "Nahrať avatara:", + "Upload an avatar:": "Nahrať obrázok:", "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ú.", @@ -905,8 +899,7 @@ "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", "Restricted": "Obmedzené", - "Presence Management": "Spravovanie prítomnosti", - "Hide avatar changes": "Skryť zmeny avatara", + "Hide avatar changes": "Skryť zmeny obrázka v profile", "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)", @@ -993,14 +986,176 @@ "Code": "Kód", "Unable to join community": "Nie je možné vstúpiť do komunity", "Unable to leave community": "Nie je možné opustiť komunitu", - "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Zmeny vykonané vo vašej komunite name and avatar nemusia byť nasledujúcich 30 minút viditeľné všetkými používateľmi.", + "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Zmeny vykonané vo vašej komunite názov a obrázok nemusia byť nasledujúcich 30 minút viditeľné všetkými používateľmi.", "Join this community": "Vstúpiť do tejto komunity", "Leave this community": "Opustiť túto komunitu", "Did you know: you can use communities to filter your Riot.im experience!": "Vedeli ste: Že prácu s Riot.im si môžete spríjemníť použitím komunít!", - "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "Ak si chcete nastaviť filter, pretiahnite avatara komunity na panel filtrovania úplne na ľavej strane obrazovky. Potom môžete kedykoľvek kliknúť na avatara komunity na tomto panely a Riot.im vám bude zobrazovať len miestnosti a ľudí z komunity, na ktorej avatar ste klikli.", + "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "Ak si chcete nastaviť filter, pretiahnite obrázok komunity na panel filtrovania úplne na ľavej strane obrazovky. Potom môžete kedykoľvek kliknúť na obrázok komunity na tomto panely a Riot.im vám bude zobrazovať len miestnosti a ľudí z komunity, na ktorej obrázok ste klikli.", "Clear filter": "Zrušiť filter", "Debug Logs Submission": "Odoslanie ladiacich záznamov", "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contian messages.": "Ak ste nám poslali hlásenie o chybe cez Github, ladiace záznamy nám môžu pomôcť lepšie identifikovať chybu. Ladiace záznamy obsahujú údaje o používaní aplikácii, vrátane vašeho používateľského mena, názvy a aliasy miestností a komunít, ku ktorým ste sa pripojili a mená ostatných používateľov. Tieto záznamy neobsahujú samotný obsah vašich správ.", "Submit debug logs": "Odoslať ladiace záznamy", - "Opens the Developer Tools dialog": "Otvorí dialóg nástroje pre vývojárov" + "Opens the Developer Tools dialog": "Otvorí dialóg nástroje pre vývojárov", + "Stickerpack": "Balíček nálepiek", + "Sticker Messages": "Správy s nálepkami", + "You don't currently have any stickerpacks enabled": "Momentálne nemáte aktívne žiadne balíčky s nálepkami", + "Add a stickerpack": "Pridať balíček s nálepkami", + "Hide Stickers": "Skryť nálepky", + "Show Stickers": "Zobraziť nálepky", + "Who can join this community?": "Kto môže vstúpiť do tejto komunity?", + "Everyone": "Ktokoľvek", + "Fetching third party location failed": "Nepodarilo sa získať umiestnenie tretej strany", + "A new version of Riot is available.": "Dostupná je nová verzia Riot.", + "Couldn't load home page": "Nie je možné načítať domovskú stránku", + "Send Account Data": "Odoslať Údaje Účtu", + "All notifications are currently disabled for all targets.": "Momentálne sú zakázané všetky oznámenia pre všetky ciele.", + "Uploading report": "Prebieha odovzdanie hlásenia", + "Sunday": "Nedeľa", + "Notification targets": "Ciele oznámení", + "Today": "Dnes", + "Files": "Súbory", + "You are not receiving desktop notifications": "Nedostávate oznámenia na pracovnej ploche", + "Friday": "Piatok", + "Update": "Aktualizovať", + "Unable to fetch notification target list": "Nie je možné získať zoznam cieľov oznámení", + "Add an email address above to configure email notifications": "Ak si chcete nastaviť oznamovanie emailom, pridajte si emailovú adresu vyššie", + "Expand panel": "Rozbaliť panel", + "On": "Povolené", + "%(count)s Members|other": "%(count)s Členov", + "Filter room names": "Filtrovať názvy miestností", + "Changelog": "Zoznam zmien", + "Waiting for response from server": "Čakanie na odpoveď zo servera", + "Uploaded on %(date)s by %(user)s": "Nahral používateľ %(user)s dňa %(date)s", + "Send Custom Event": "Odoslať vlastnú udalosť", + "Advanced notification settings": "Pokročilé nastavenia oznámení", + "Failed to send logs: ": "Nepodarilo sa odoslať záznamy: ", + "delete the alias.": "vymazať alias.", + "To return to your account in future you need to set a password": "Aby ste sa v budúcnosti mohli vrátiť k vašemu účtu mali by ste si teraz nastaviť heslo", + "Forget": "Zabudnuť", + "Hide panel": "Skryť panel", + "You cannot delete this image. (%(code)s)": "Nemôžete vymazať tento obrázok. (%(code)s)", + "Cancel Sending": "Zrušiť odosielanie", + "This Room": "V tejto miestnosti", + "The Home Server may be too old to support third party networks": "Domovský server môže byť natoľko zastaralý, že nepodporuje siete tretíh strán", + "Resend": "Poslať znovu", + "Room not found": "Miestnosť nenájdená", + "Downloading update...": "Sťahovanie aktualizácie...", + "Messages in one-to-one chats": "Správy v priamych konverzáciách", + "Unavailable": "Nedostupné", + "View Decrypted Source": "Zobraziť dešifrovaný zdroj", + "Failed to update keywords": "Nepodarilo sa aktualizovať kľúčové slová", + "Notes:": "Poznámky:", + "remove %(name)s from the directory.": "odstrániť %(name)s z adresára.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Oznámenia nasledujúcich kľúčových slov sa riadia pravidlami, ktoré nie je možné zobraziť na tomto mieste:", + "Safari and Opera work too.": "Správne fungujú aj Safari a Opera.", + "Please set a password!": "Prosím, nastavte si heslo!", + "You have successfully set a password!": "Ǔspešne ste si nastavili heslo!", + "Explore Room State": "Preskúmať Stav Miestnosti", + "Source URL": "Pôvodná URL", + "Messages sent by bot": "Správy odosielané robotmi", + "Filter results": "Filtrovať výsledky", + "Members": "Členovia", + "No update available.": "K dispozícii nie je žiadna aktualizácia.", + "Noisy": "Hlučné", + "Failed to get protocol list from Home Server": "Nepodarilo sa získať zoznam protokolov z domovského servera", + "Collecting app version information": "Získavajú sa informácie o verzii aplikácii", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Vymazať alias %(alias)s a odstrániť miestnosť %(name)s z adresára?", + "This will allow you to return to your account after signing out, and sign in on other devices.": "Toto vám v budúcnosti umožní vrátiť sa k vašemu účtu aj po odhlásení, alebo tiež prihlásiť sa na iných zariadeniach.", + "Keywords": "Kľúčové slová", + "Enable notifications for this account": "Povoliť oznámenia pre tento účet", + "Directory": "Adresár", + "Invite to this community": "Pozvať do tejto komunity", + "Failed to get public room list": "Nepodarilo sa získať zoznam verejných miestností", + "Search…": "Hľadať…", + "Messages containing keywords": "Správy obsahujúce kľúčové slová", + "Error saving email notification preferences": "Chyba pri ukladaní nastavení oznamovania emailom", + "Tuesday": "Utorok", + "Enter keywords separated by a comma:": "Zadajte kľúčové slová oddelené čiarkou:", + "Forward Message": "Preposlať správu", + "Remove %(name)s from the directory?": "Odstrániť miestnosť %(name)s z adresára?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot sa spolieha na mnohé pokročilé vlastnosti prehliadača internetu, a niektoré z nich sú vo vašom prehliadači experimentálne alebo nie sú k dispozícii vôbec.", + "Event sent!": "Udalosť odoslaná!", + "Preparing to send logs": "príprava odoslania záznamov", + "Enable desktop notifications": "Povoliť oznámenia na pracovnej ploche", + "Explore Account Data": "Preskúmať Údaje účtu", + "All messages (noisy)": "Všetky správy (hlučné)", + "Saturday": "Sobota", + "Remember, you can always set an email address in user settings if you change your mind.": "Všimnite si, Emailovú adresu môžete pridať aj neskôr v časti nastavenia, ak zmeníte svoj názor.", + "Direct Chat": "Priama konverzácia", + "The server may be unavailable or overloaded": "Server môže byť nedostupný alebo preťažený", + "Reject": "Odmietnuť", + "Failed to set Direct Message status of room": "Nepodarilo sa nastaviť stav miestnosti priama konverzácia", + "Monday": "Pondelok", + "Remove from Directory": "Odstrániť z adresára", + "Enable them now": "Povolte si ich teraz", + "Messages containing my user name": "Správy obsahujúce moje používateľské meno", + "Toolbox": "Nástroje", + "Collecting logs": "Získavajú sa záznamy", + "more": "viac", + "GitHub issue link:": "Odkaz hlásenia na Github:", + "Search for a room": "Vyhľadať miestnosť", + "You must specify an event type!": "Musíte nastaviť typ udalosti!", + "(HTTP status %(httpStatus)s)": "(HTTP status %(httpStatus)s)", + "All Rooms": "Vo všetkych miestnostiach", + "State Key": "State Key", + "Please install Chrome or Firefox for the best experience.": "Aby ste s používania mali čo možno najlepší dojem, nainštalujte si Chrome alebo Firefox.", + "Wednesday": "Streda", + "Quote": "Citácia", + "Send logs": "Zahrnúť záznamy", + "All messages": "Všetky správy", + "Call invitation": "Audio / Video hovory", + "Messages containing my display name": "Správy obsahujúce moje zobrazované meno", + "You have successfully set a password and an email address!": "Úspešne si si nastavili heslo aj emailovú adresu!", + "Failed to send custom event.": "Odoslanie vlastnej udalosti zlyhalo.", + "What's new?": "Čo je nové?", + "Notify me for anything else": "Oznamovať mi všetko ostatné", + "When I'm invited to a room": "Pozvania vstúpiť do miestnosti", + "Click here to create a GitHub issue.": "Kliknutím sem nám pošlete hlásenie o chybe cez Github.", + "Can't update user notification settings": "Nie je možné aktualizovať používateľské nastavenia oznamovania", + "Notify for all other messages/rooms": "oznamovať všetky ostatné správy / miestnosti", + "Unable to look up room ID from server": "Nie je možné vyhľadať ID miestnosti na servery", + "Couldn't find a matching Matrix room": "Nie je možné nájsť zodpovedajúcu Matrix miestnosť", + "Invite to this room": "Pozvať do tejto miestnosti", + "You cannot delete this message. (%(code)s)": "Nemôžete vymazať túto správu. (%(code)s)", + "Thursday": "Štvrtok", + "I understand the risks and wish to continue": "Rozumiem rizikám a želám si pokračovať", + "Logs sent": "Záznamy boli odoslané", + "Back": "Naspäť", + "Reply": "Odpovedať", + "Show message in desktop notification": "Zobraziť text správy v oznámení na pracovnej ploche", + "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Ladiace záznamy obsahujú údaje o používaní aplikácii, vrátane vašeho používateľského mena, názvy a aliasy miestností a komunít, ku ktorým ste sa pripojili a mená ostatných používateľov. Tieto záznamy neobsahujú samotný obsah vašich správ.", + "Unhide Preview": "Zobraziť náhľad", + "Unable to join network": "Nie je možné sa pripojiť k sieti", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Tieto nastavenia oznámení sa použijú aj napriek tomu, že ich nemôžete meniť cez Riot. Pravdepodobne ste si ich nastavili v inej aplikácii", + "Sorry, your browser is not able to run Riot.": "Prepáčte, vo vašom prehliadači nie je možné spustiť Riot.", + "Messages in group chats": "Správy v skupinových konverzáciách", + "Yesterday": "Včera", + "Error encountered (%(errorDetail)s).": "Vyskytla sa chyba (%(errorDetail)s).", + "Event Type": "Typ Udalosti", + "Low Priority": "Nízka priorita", + "What's New": "Čo Je Nové", + "Set Password": "Nastaviť Heslo", + "An error occurred whilst saving your email notification preferences.": "Počas ukladania vašich nastavení oznamovania emailom sa vyskytla chyba.", + "Enable audible notifications in web client": "Povoliť zvukové oznámenia vo webovom klientovi", + "Permalink": "Trvalý odkaz", + "Off": "Zakázané", + "Riot does not know how to join a room on this network": "Riot nedokáže vstúpiť do miestnosti na tejto sieti", + "Mentions only": "Len zmienky", + "You can now return to your account after signing out, and sign in on other devices.": "Odteraz sa budete k svojmu účtu vedieť vrátiť aj po odhlásení, alebo tiež prihlásiť na iných zariadeniach.", + "Enable email notifications": "Povoliť oznamovanie emailom", + "Login": "Prihlásiť", + "Download this file": "Stiahnuť tento súbor", + "Pin Message": "Pripnúť správu", + "Failed to change settings": "Nepodarilo sa zmeniť nastavenia", + "View Community": "Zobraziť komunitu", + "%(count)s Members|one": "%(count)s Člen", + "Developer Tools": "Vývojárske Nástroje", + "View Source": "Zobraziť zdroj", + "Event Content": "Obsah Udalosti", + "Thank you!": "Ďakujeme!", + "#example": "#príklad", + "Collapse panel": "Zbaliť panel", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Vo vašom súčasnom prehliadači nemusí Riot vizerať ani fungovať správne a niektoré alebo všetky vlastnosti môžu chýbať. Ak to chcete vyskúšať, môžete pokračovať, no pri riešení problémov s tým spojených si budete musieť poradiť na vlastnú päsť!", + "Checking for an update...": "Kontrola dostupnosti aktualizácie...", + "There are advanced notifications which are not shown here": "Niektoré pokročilé oznámenia nemôžu byť zobrazené" } diff --git a/src/i18n/strings/sr.json b/src/i18n/strings/sr.json index a6d8ab8540..87d5ec782e 100644 --- a/src/i18n/strings/sr.json +++ b/src/i18n/strings/sr.json @@ -172,7 +172,6 @@ "Failed to join room": "Нисам успео да уђем у собу", "Message Replies": "Одговори", "Message Pinning": "Закачене поруке", - "Presence Management": "Управљање присутношћу", "Tag Panel": "Означи површ", "Disable Emoji suggestions while typing": "Онемогући предлагање емоџија приликом куцања", "Use compact timeline layout": "Користи збијени распоред временске линије", @@ -304,8 +303,6 @@ "Hangup": "Спусти слушалицу", "Voice call": "Гласовни позив", "Video call": "Видео позив", - "Hide Apps": "Сакриј апликације", - "Show Apps": "Прикажи апликације", "Upload file": "Отпреми датотеку", "Show Text Formatting Toolbar": "Прикажи алатницу за форматирање текста", "Send an encrypted reply…": "Пошаљи шифровани одговор…", @@ -744,7 +741,6 @@ "Leave Community": "Напусти заједницу", "Leave %(groupName)s?": "Напустити %(groupName)s?", "Leave": "Напусти", - "Unable to leave room": "Не могу да напустим собу", "Community Settings": "Подешавања заједнице", "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Ове собе су приказане члановима заједнице на страници заједнице. Чланови заједнице могу приступити собама кликом на њих.", "Add rooms to this community": "Додај собе у ову заједницу", @@ -766,8 +762,6 @@ "Failed to leave room": "Нисам успео да напустим собу", "Signed Out": "Одјављен", "For security, this session has been signed out. Please sign in again.": "Зарад безбедности, одјављени сте из ове сесије. Пријавите се поново.", - "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": "Нађени су стари криптографски подаци", "The platform you're on": "Платформа коју користите", "The version of Riot.im": "Riot.im издање", @@ -855,9 +849,6 @@ "Device ID:": "ИБ уређаја:", "Device key:": "Кључ уређаја:", "Ignored Users": "Занемарени корисници", - "Bug Report": "Извештај о грешци", - "Found a bug?": "Нашли сте грешку?", - "Report it": "Пријавите је", "Riot collects anonymous analytics to allow us to improve the application.": "Riot прикупља анонимне податке о коришћењу да бисмо побољшали апликацију.", "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.": "Сазнајте више о нашем начину употребе аналитике.", @@ -994,5 +985,151 @@ "Key request sent.": "Захтев за дељење кључа послат.", "Re-request encryption keys from your other devices.": "Поново затражи кључеве за шифровање са осталих ваших уређаја.", "%(user)s is a %(userRole)s": "Корисник %(user)s је у улози %(userRole)s", - "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "Да бисте поставили филтер, повуците аватар заједнице на површ филтрирања скроз на леву страну екрана. Можете кликнути на аватар у површи филтрирања било када да бисте видели само собе и особе везане за ту заједницу." + "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "Да бисте поставили филтер, повуците аватар заједнице на површ филтрирања скроз на леву страну екрана. Можете кликнути на аватар у површи филтрирања било када да бисте видели само собе и особе везане за ту заједницу.", + "Fetching third party location failed": "Добављање локације треће стране није успело", + "A new version of Riot is available.": "Ново издање RIot-а је доступно.", + "Couldn't load home page": "Нисам могао да учитам почетну страну", + "Send Account Data": "Пошаљи податке налога", + "All notifications are currently disabled for all targets.": "Сва обавештења су тренутно онемогућена за све циљеве.", + "Uploading report": "Отпремам извештај", + "Sunday": "Недеља", + "Notification targets": "Циљеви обавештења", + "Today": "Данас", + "Files": "Датотеке", + "You are not receiving desktop notifications": "Не примате стона обавештења", + "Friday": "Петак", + "Update": "Ажурирај", + "Unable to fetch notification target list": "Не могу да досегнем списак циљева за обавештења", + "Add an email address above to configure email notifications": "Додајте мејл адресу изнад да бисте подесили мејл обавештења", + "Expand panel": "Прошири површ", + "On": "Укључено", + "%(count)s Members|other": "%(count)s чланова", + "Filter room names": "Филтрирај називе соба", + "Changelog": "Записник о изменама", + "Waiting for response from server": "Чекам на одговор са сервера", + "Uploaded on %(date)s by %(user)s": "Отпремљено датума %(date)s од корисника %(user)s", + "Send Custom Event": "Пошаљи прилагођени догађај", + "Off": "Искључено", + "Advanced notification settings": "Напредна подешавања обавештења", + "delete the alias.": "обриши алијас.", + "To return to your account in future you need to set a password": "Да бисте се вратили на ваш налог у будућности, морате поставити лозинку", + "Forget": "Заборави", + "Hide panel": "Сакриј површ", + "You cannot delete this image. (%(code)s)": "Не можете обрисати ову слику. (%(code)s)", + "Cancel Sending": "Откажи слање", + "This Room": "Ова соба", + "The Home Server may be too old to support third party networks": "Кућни сервер је можда сувише застарео да би подржао мреже трећих страна", + "Room not found": "Соба није пронађена", + "Downloading update...": "Преузимам ажурирање...", + "Messages in one-to-one chats": "Поруке у један-на-један ћаскањима", + "Unavailable": "Недоступан", + "View Decrypted Source": "Погледај дешифровани извор", + "Failed to update keywords": "Нисам успео да ажурирам кључне речи", + "remove %(name)s from the directory.": "уклони %(name)s из фасцикле.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Обавештења за следеће кључне речи прате правила која не могу бити приказана овде:", + "Safari and Opera work too.": "Сафари и Опера такође раде.", + "Please set a password!": "Поставите лозинку!", + "You have successfully set a password!": "Успешно сте поставили лозинку!", + "Explore Room State": "Истражи стање собе", + "Source URL": "Адреса извора", + "Messages sent by bot": "Поруке послате од бота", + "Filter results": "Филтрирај резултате", + "Members": "Чланови", + "No update available.": "Нема нових ажурирања.", + "Noisy": "Бучно", + "Failed to get protocol list from Home Server": "Нисам успео да добијем списак протокола од кућног сервера", + "Collecting app version information": "Прикупљам податке о издању апликације", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Обрисати алијас собе %(alias)s и уклонити %(name)s из фасцикле?", + "This will allow you to return to your account after signing out, and sign in on other devices.": "Ово ће вам омогућити да се вратите у ваш налог након што се одјавите и пријавите, на другим уређајима.", + "Keywords": "Кључне речи", + "Enable notifications for this account": "Омогући обавештења за овај налог", + "Directory": "Фасцикла", + "Invite to this community": "Позови у ову заједницу", + "Failed to get public room list": "Нисам успео да добавим списак јавних соба", + "Search…": "Претрага…", + "Messages containing keywords": "Поруке које садрже кључне речи", + "Error saving email notification preferences": "Грешка при чувању поставки мејл обавештења", + "Tuesday": "Уторак", + "Enter keywords separated by a comma:": "Унесите кључне речи одвојене зарезима:", + "Forward Message": "Проследи поруку", + "Remove %(name)s from the directory?": "Уклонити %(name)s из фасцикле?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot користи напредне могућности прегледача од којих неке нису доступне или су у пробној фази, у вашем прегледачу.", + "Event sent!": "Догађај је послат!", + "Explore Account Data": "Истражи податке налога", + "All messages (noisy)": "Све поруке (гласно)", + "Saturday": "Субота", + "Remember, you can always set an email address in user settings if you change your mind.": "Запамтите, увек можете поставити мејл адресу у корисничким подешавањима, уколико се предомислите.", + "Direct Chat": "Директно ћаскање", + "The server may be unavailable or overloaded": "Сервер је можда недоступан или преоптерећен", + "Reject": "Одбаци", + "Failed to set Direct Message status of room": "Нисам успео да подесим стање директне поруке собе", + "Monday": "Понедељак", + "Remove from Directory": "Уклони из фасцикле", + "Enable them now": "Омогућите их сада", + "Messages containing my user name": "Поруке које садрже моје корисничко име", + "Toolbox": "Алатница", + "Collecting logs": "Прикупљам записнике", + "more": "више", + "Search for a room": "Потражи собу", + "You must specify an event type!": "Морате навести врсту догађаја!", + "(HTTP status %(httpStatus)s)": "(HTTP стање %(httpStatus)s)", + "All Rooms": "Све собе", + "State Key": "Кључ стања", + "Please install Chrome or Firefox for the best experience.": "Инсталирајте Хром (Chrome) или Фајерфокс (Firefox) за најбољи угођај.", + "Wednesday": "Среда", + "Send logs": "Пошаљи записнике", + "All messages": "Све поруке", + "Call invitation": "Позивница за позив", + "Messages containing my display name": "Поруке које садрже моје приказно име", + "You have successfully set a password and an email address!": "Успешно сте поставили лозинку и мејл адресу!", + "Failed to send custom event.": "Нисам успео да пошаљем прилагођени догађај.", + "What's new?": "Шта је ново?", + "Notify me for anything else": "Обавести ме за било шта друго", + "When I'm invited to a room": "Када сам позван у собу", + "Can't update user notification settings": "Не могу да ажурирам корисничка подешавања обавештења", + "Notify for all other messages/rooms": "Обавести за све друге поруке и собе", + "Unable to look up room ID from server": "Не могу да погледам ИБ собе на серверу", + "Couldn't find a matching Matrix room": "Не могу да нађем одговарајућу Матрикс собу", + "Invite to this room": "Позови у ову собу", + "You cannot delete this message. (%(code)s)": "Не можете обрисати ову поруку. (%(code)s)", + "Thursday": "Четвртак", + "I understand the risks and wish to continue": "Разумем опасност и желим да наставим", + "Back": "Назад", + "Reply": "Одговори", + "Show message in desktop notification": "Прикажи поруку у стоном обавештењу", + "Unhide Preview": "Откриј преглед", + "Unable to join network": "Не могу да приступим мрежи", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Можда сте их подесили у неком другом клијенту а не Riot-у. Не можете их преправљати у Riot-у али се и даље примењују", + "Sorry, your browser is not able to run Riot.": "Нажалост, ваш прегледач не може да покреће Riot.", + "Messages in group chats": "Поруке у групним ћаскањима", + "Yesterday": "Јуче", + "Error encountered (%(errorDetail)s).": "Догодила се грешка (%(errorDetail)s).", + "Event Type": "Врста догађаја", + "Low Priority": "Најмања важност", + "What's New": "Шта је ново", + "Set Password": "Постави лозинку", + "An error occurred whilst saving your email notification preferences.": "Догодила се грешка при чувању ваших поставки мејл обавештења.", + "Enable audible notifications in web client": "Омогући звучна обавештења у веб клијенту", + "Permalink": "Трајна веза", + "Resend": "Поново пошаљи", + "Riot does not know how to join a room on this network": "Riot не зна како да приступи соби на овој мрежи", + "Mentions only": "Само спомињања", + "You can now return to your account after signing out, and sign in on other devices.": "Можете се вратити у ваш налог након што се одјавите и пријавите поново, на другим уређајима.", + "Enable desktop notifications": "Омогући стона обавештења", + "Enable email notifications": "Омогући мејл обавештења", + "Login": "Пријава", + "Download this file": "Преузми ову датотеку", + "Pin Message": "Закачи поруку", + "Failed to change settings": "Нисам успео да променим подешавања", + "View Community": "Погледај заједницу", + "%(count)s Members|one": "%(count)s члан", + "Developer Tools": "Програмерске алатке", + "View Source": "Погледај извор", + "Event Content": "Садржај догађаја", + "Thank you!": "Хвала вам!", + "#example": "#пример", + "Collapse panel": "Скупи површ", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Са вашим тренутним прегледачем изглед и угођај ове апликације може бити скроз неправилан и неке могућности можда неће радити. Уколико желите да ипак пробате, можете наставити али ћете бити без подршке за било које проблеме на које налетите!", + "Checking for an update...": "Проверавам ажурирања...", + "There are advanced notifications which are not shown here": "Постоје напредна обавештења која нису приказана овде" } From 0f11bc62cc9014297bbf800f6d9871e0a570524c Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@googlemail.com> Date: Mon, 23 Apr 2018 10:58:39 +0100 Subject: [PATCH 054/190] undo code style change --- src/HtmlUtils.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/HtmlUtils.js b/src/HtmlUtils.js index 17566957c7..8d352eb4f6 100644 --- a/src/HtmlUtils.js +++ b/src/HtmlUtils.js @@ -479,11 +479,9 @@ export function bodyToHtml(content, highlights, opts={}) { 'markdown-body': isHtml, }); - if (isHtml) { - return ; - } - - return { strippedBody }; + return isHtml ? + : + { strippedBody }; } export function emojifyText(text) { From f5956c87f677af268997b8d0af21459d39492b50 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 23 Apr 2018 18:14:59 +0100 Subject: [PATCH 055/190] Bind onImageError in constructor Tt uses `this` but wasn't bound anywhere so the error handler was just throwing an exception. --- src/components/views/messages/MImageBody.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index 6a95b3c16e..d5ce533bda 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -49,6 +49,7 @@ export default class extends React.Component { super(props); this.onAction = this.onAction.bind(this); + this.onImageError = this.onImageError.bind(this); this.onImageEnter = this.onImageEnter.bind(this); this.onImageLeave = this.onImageLeave.bind(this); this.onClientSync = this.onClientSync.bind(this); From b6157499a8fc42087319ad044d2582158f4d205d Mon Sep 17 00:00:00 2001 From: Szimszon Date: Mon, 23 Apr 2018 15:40:50 +0000 Subject: [PATCH 056/190] Translated using Weblate (Hungarian) Currently translated at 100.0% (1161 of 1161 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 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 792fa2735f..77b2a2d37d 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -362,7 +362,7 @@ "This email address was not found": "Az e-mail cím nem található", "The email address linked to your account must be entered.": "A fiókodhoz kötött e-mail címet add meg.", "Press to start a chat with someone": "Nyomd meg a gombot ha szeretnél csevegni valakivel", - "Privacy warning": "Titoktartási figyelmeztetés", + "Privacy warning": "Adatvédelmi figyelmeztetés", "The file '%(fileName)s' exceeds this home server's size limit for uploads": "'%(fileName)s' fájl túllépte a Saját szerverben beállított feltöltési méret határt", "The file '%(fileName)s' failed to upload": "'%(fileName)s' fájl feltöltése sikertelen", "The remote side failed to pick up": "A hívott fél nem vette fel", From 166474d869d70284a9b864adb27470b875e4ff3e Mon Sep 17 00:00:00 2001 From: Ivan Shapovalov Date: Tue, 24 Apr 2018 10:00:40 +0000 Subject: [PATCH 057/190] Translated using Weblate (Russian) Currently translated at 100.0% (1161 of 1161 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, 4 insertions(+), 4 deletions(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index e1d2cde38c..94c8a353ae 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -159,7 +159,7 @@ "Failed to lookup current room": "Не удалось выполнить поиск текущий комнаты", "Failed to send request.": "Не удалось отправить запрос.", "Failed to set up conference call": "Не удалось настроить групповой вызов", - "Failed to verify email address: make sure you clicked the link in the email": "Не удалось проверить адрес email: убедитесь, что вы перешли по ссылке в письме", + "Failed to verify email address: make sure you clicked the link in the email": "Не удалось проверить email-адрес: убедитесь, что вы перешли по ссылке в письме", "Failure to create room": "Не удалось создать комнату", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s с %(fromPowerLevel)s на %(toPowerLevel)s", "click to reveal": "нажмите для открытия", @@ -337,7 +337,7 @@ "Success": "Успех", "The default role for new room members is": "Роль по умолчанию для новых участников комнаты", "The main address for this room is": "Основной адрес для этой комнаты", - "This email address is already in use": "Этот адрес email уже используется", + "This email address is already in use": "Этот email-адрес уже используется", "This email address was not found": "Этот адрес электронной почты не найден", "The email address linked to your account must be entered.": "Необходимо ввести адрес электронной почты, связанный с вашей учетной записью.", "The file '%(fileName)s' failed to upload": "Не удалось отправить файл '%(fileName)s'", @@ -368,7 +368,7 @@ "numbullet": "нумерованный список", "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Не удается подключиться к домашнему серверу через HTTP, так как в адресной строке браузера указан URL HTTPS. Используйте HTTPS или либо включите небезопасные сценарии.", "Dismiss": "Отклонить", - "Custom Server Options": "Настраиваемые параметры сервера", + "Custom Server Options": "Выбор другого сервера", "Mute": "Беззвучный", "Operation failed": "Сбой операции", "powered by Matrix": "Основано на Matrix", @@ -960,7 +960,7 @@ "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 version of Riot.im": "Версия 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 homeserver's URL": "URL-адрес домашнего сервера", "Your identity server's URL": "URL-адрес вашего идентификационного сервера", From 5732b3ac0e73248695270f8f160528308e40f9de Mon Sep 17 00:00:00 2001 From: Ivan Shapovalov Date: Tue, 24 Apr 2018 10:01:22 +0000 Subject: [PATCH 058/190] Translated using Weblate (Russian) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (1161 of 1161 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ по аналогии с "the platform you're on" — там нет местоимения --- 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 94c8a353ae..eae84df3f8 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -961,7 +961,7 @@ "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": "Выбранный вами язык", + "Your language of choice": "Выбранный язык", "Your homeserver's URL": "URL-адрес домашнего сервера", "Your identity server's URL": "URL-адрес вашего идентификационного сервера", "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s", From 20454b92ab3564f8634b84f8a3176012a0c7853f Mon Sep 17 00:00:00 2001 From: Ivan Shapovalov Date: Tue, 24 Apr 2018 10:10:41 +0000 Subject: [PATCH 059/190] Translated using Weblate (Russian) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (1161 of 1161 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, 3 insertions(+), 3 deletions(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index eae84df3f8..e667aaaf88 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -960,13 +960,13 @@ "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 version of Riot.im": "Версия 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 homeserver's URL": "URL-адрес домашнего сервера", "Your identity server's URL": "URL-адрес вашего идентификационного сервера", "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s", - "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", + "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", "This room is not public. You will not be able to rejoin without an invite.": "Эта комната не является публичной. Вы не сможете войти без приглашения.", "Show devices, send anyway or cancel.": "Показать устройства, отправить в любом случае или отменить.", "Community IDs cannot not be empty.": "ID сообществ не могут быть пустыми.", From 4ec1973888e78e2f4d2b324a0736fc6634d26e6e Mon Sep 17 00:00:00 2001 From: Ivan Shapovalov Date: Tue, 24 Apr 2018 12:33:06 +0000 Subject: [PATCH 060/190] Translated using Weblate (Russian) Currently translated at 100.0% (1161 of 1161 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 | 206 +++++++++++++++++++-------------------- 1 file changed, 103 insertions(+), 103 deletions(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index e667aaaf88..9808a2043a 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -32,14 +32,14 @@ "Deactivate Account": "Деактивировать учетную запись", "Deactivate my account": "Деактивировать мою учетную запись", "Decryption error": "Ошибка расшифровки", - "Default": "По умолчанию", + "Default": "Обычный пользователь", "Deops user with given id": "Снимает полномочия оператора с пользователя с заданным ID", "Device ID": "ID устройства", "Devices will not yet be able to decrypt history from before they joined the room": "Устройства пока не могут дешифровать историю до их входа в комнату", "Display name": "Отображаемое имя", "Displays action": "Отображение действий", "Ed25519 fingerprint": "Ed25519 отпечаток", - "Email, name or matrix ID": "Email, имя или matrix ID", + "Email, name or matrix ID": "Email-адрес, имя или идентификатор", "Emoji": "Смайлы", "Encrypted messages will not be visible on clients that do not yet implement encryption": "Зашифрованные сообщения не будут видны в клиентах, которые еще не подключили шифрование", "Encrypted room": "Зашифрованная комната", @@ -67,7 +67,7 @@ "I have verified my email address": "Я подтвердил свой адрес email", "Import E2E room keys": "Импорт ключей сквозного шифрования", "Invalid Email Address": "Недопустимый адрес email", - "Invite new room members": "Пригласить новых участников в комнату", + "Invite new room members": "Пригласить в комнату новых участников", "Invites": "Приглашает", "Invites user with given id to current room": "Приглашает пользователя с заданным ID в текущую комнату", "Sign in with": "Войти, используя", @@ -101,8 +101,8 @@ "Return to login screen": "Вернуться к экрану входа", "Send Reset Email": "Отправить письмо со ссылкой для сброса пароля", "Settings": "Настройки", - "Start a chat": "Начать чат", - "Start Chat": "Начать чат", + "Start a chat": "Начать разговор", + "Start Chat": "Начать разговор", "Unable to add email address": "Не удается добавить адрес email", "Unable to remove contact information": "Не удалось удалить контактную информацию", "Unable to verify email address.": "Не удалось проверить адрес email.", @@ -123,13 +123,13 @@ "verified": "проверенный", "Video call": "Видеозвонок", "Voice call": "Голосовой вызов", - "VoIP conference finished.": "VoIP-конференция закончилась.", - "VoIP conference started.": "VoIP-конференция началась.", + "VoIP conference finished.": "Конференц-звонок окончен.", + "VoIP conference started.": "Конференц-звонок начался.", "(warning: cannot be disabled again!)": "(предупреждение: отключить будет невозможно!)", "Warning!": "Внимание!", "Who can access this room?": "Кто может получить доступ к этой комнате?", "Who can read history?": "Кто может читать историю?", - "Who would you like to add to this room?": "Кого бы вы хотели добавить в эту комнату?", + "Who would you like to add to this room?": "Кого бы вы хотели пригласить в эту комнату?", "Who would you like to communicate with?": "С кем бы вы хотели связаться?", "You do not have permission to post to this room": "Вы не можете писать в эту комнату", "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": "Вы вышли из всех устройств и больше не будете получать push-уведомления. Чтобы повторно активировать уведомления, войдите снова на каждом из устройств", @@ -141,41 +141,41 @@ "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s принял приглашение от %(displayName)s.", "Active call": "Активный вызов", "%(names)s and %(lastPerson)s are typing": "%(names)s и %(lastPerson)s печатает", - "%(senderName)s answered the call.": "%(senderName)s ответил на звонок.", + "%(senderName)s answered the call.": "%(senderName)s ответил(а) на звонок.", "%(senderName)s banned %(targetName)s.": "%(senderName)s заблокировал(а) %(targetName)s.", - "Call Timeout": "Время ожидания вызова", - "%(senderName)s changed their profile picture.": "%(senderName)s изменил изображение профиля.", - "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s изменил(а) уровень доступа для %(powerLevelDiffText)s.", + "Call Timeout": "Нет ответа", + "%(senderName)s changed their profile picture.": "%(senderName)s изменил(а) свой аватар.", + "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s изменил(а) уровни прав %(powerLevelDiffText)s.", "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s изменил(а) название комнаты на %(roomName)s.", - "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s изменил тему на %(topic)s.", - "Conference call failed.": "Не удалось выполнить групповой вызов.", - "Conference calling is in development and may not be reliable.": "Групповые вызовы находятся в разработке и могут быть нестабильны.", - "Conference calls are not supported in encrypted rooms": "Групповые вызовы не поддерживаются в зашифрованных комнатах", - "Conference calls are not supported in this client": "Групповые вызовы в этом клиенте не поддерживаются", - "/ddg is not a command": "/ddg не команда", + "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s изменил(а) тему комнаты на \"%(topic)s\".", + "Conference call failed.": "Сбой конференц-звонка.", + "Conference calling is in development and may not be reliable.": "Конференц-связь находится в разработке и может не работать.", + "Conference calls are not supported in encrypted rooms": "Конференц-связь не поддерживается в зашифрованных комнатах", + "Conference calls are not supported in this client": "Конференц-связь в этом клиенте не поддерживается", + "/ddg is not a command": "/ddg — это не команда", "Drop here to tag %(section)s": "Перетащите сюда для тега %(section)s", - "%(senderName)s ended the call.": "%(senderName)s завершил звонок.", + "%(senderName)s ended the call.": "%(senderName)s завершил(а) звонок.", "Existing Call": "Текущий вызов", - "Failed to lookup current room": "Не удалось выполнить поиск текущий комнаты", + "Failed to lookup current room": "Не удалось найти текущую комнату", "Failed to send request.": "Не удалось отправить запрос.", - "Failed to set up conference call": "Не удалось настроить групповой вызов", + "Failed to set up conference call": "Не удалось сделать конференц-звонок", "Failed to verify email address: make sure you clicked the link in the email": "Не удалось проверить email-адрес: убедитесь, что вы перешли по ссылке в письме", "Failure to create room": "Не удалось создать комнату", - "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s с %(fromPowerLevel)s на %(toPowerLevel)s", + "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "для %(userId)s с %(fromPowerLevel)s на %(toPowerLevel)s", "click to reveal": "нажмите для открытия", "%(senderName)s invited %(targetName)s.": "%(senderName)s приглашает %(targetName)s.", "%(displayName)s is typing": "%(displayName)s печатает", - "%(targetName)s joined the room.": "%(targetName)s вошел(ла) в комнату.", - "%(senderName)s kicked %(targetName)s.": "%(senderName)s выкинул %(targetName)s.", - "%(targetName)s left the room.": "%(targetName)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).", + "%(targetName)s joined the room.": "%(targetName)s вошёл(-ла) в комнату.", + "%(senderName)s kicked %(targetName)s.": "%(senderName)s исключил(а) %(targetName)s из комнаты.", + "%(targetName)s left the room.": "%(targetName)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).", "Missing room_id in request": "Отсутствует room_id в запросе", "Missing user_id in request": "Отсутствует user_id в запросе", - "Must be viewing a room": "Необходимо посмотреть комнату", + "Must be viewing a room": "Вы должны просматривать комнату", "(not supported by this browser)": "(не поддерживается этим браузером)", "Connectivity to the server has been lost.": "Связь с сервером потеряна.", "Sent messages will be stored until your connection has returned.": "Отправленные сообщения будут сохранены, пока соединение не восстановится.", @@ -197,25 +197,25 @@ "Encrypt room": "Шифрование комнаты", "%(weekDayName)s %(time)s": "%(weekDayName)s %(time)s", "Upload an avatar:": "Загрузите аватар:", - "You need to be logged in.": "Вы должны быть авторизованы.", + "You need to be logged in.": "Вы должны войти в систему.", "You need to be able to invite users to do that.": "Для этого вы должны иметь возможность приглашать пользователей.", - "You cannot place VoIP calls in this browser.": "VoIP звонки не поддерживаются в этом браузере.", - "You are already in a call.": "Вы уже совершаете вызов.", + "You cannot place VoIP calls in this browser.": "Звонки не поддерживаются в этом браузере.", + "You are already in a call.": "Вы уже сделали звонок.", "You are trying to access %(roomName)s.": "Вы пытаетесь получить доступ к %(roomName)s.", - "You cannot place a call with yourself.": "Вы не можете сделать вызов самому себе.", - "%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s отозвал %(targetName)s's приглашение.", - "Sep": "Сен.", - "Jan": "Янв.", - "Feb": "Фев.", - "Mar": "Мар.", - "Apr": "Апр.", + "You cannot place a call with yourself.": "Вы не можете позвонить самому себе.", + "%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s отозвал(а) своё приглашение %(targetName)s.", + "Sep": "Сен", + "Jan": "Янв", + "Feb": "Фев", + "Mar": "Мар", + "Apr": "Апр", "May": "Май", - "Jun": "Июн.", - "Jul": "Июл.", - "Aug": "Авг.", - "Oct": "Окт.", - "Nov": "Ноя.", - "Dec": "Дек.", + "Jun": "Июн", + "Jul": "Июл", + "Aug": "Авг", + "Oct": "Окт", + "Nov": "Ноя", + "Dec": "Дек", "%(weekDayName)s, %(monthName)s %(day)s %(time)s": "%(weekDayName)s, %(day)s %(monthName)s %(time)s", "Mon": "Пн", "Sun": "Вс", @@ -224,16 +224,16 @@ "Thu": "Чт", "Fri": "Пт", "Sat": "Сб", - "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Ваш адрес email, кажется, не связан с Matrix ID на этом домашнем сервере.", - "To use it, just wait for autocomplete results to load and tab through them.": "Для того, чтобы использовать эту функцию, просто подождите автозаполнения результатов, а затем используйте клавишу TAB для прокрутки.", - "%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s включено сквозное шифрование (algorithm %(algorithm)s).", + "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Ваш email-адрес не связан ни с одним пользователем на этом сервере.", + "To use it, just wait for autocomplete results to load and tab through them.": "Чтобы воспользоваться этой функцией, дождитесь загрузки результатов в окне автодополнения, а затем используйте Tab для прокрутки.", + "%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s включил(а) в комнате сквозное шифрование (алгоритм %(algorithm)s).", "%(senderName)s unbanned %(targetName)s.": "%(senderName)s разблокировал(а) %(targetName)s.", "Unable to capture screen": "Не удается сделать снимок экрана", "Unable to enable Notifications": "Не удалось включить уведомления", - "Upload Failed": "Сбой при отправке", + "Upload Failed": "Сбой отправки файла", "Usage": "Использование", "Use with caution": "Использовать с осторожностью", - "VoIP is unsupported": "VoIP не поддерживается", + "VoIP is unsupported": "Звонки не поддерживаются", "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "Текстовое сообщение было отправлено на +%(msisdn)s. Введите проверочный код, который оно содержит", "and %(count)s others...|other": "и %(count)s других...", "and %(count)s others...|one": "и еще один...", @@ -301,19 +301,19 @@ "OK": "OK", "Only people who have been invited": "Только приглашенные люди", "Passwords can't be empty": "Пароли не могут быть пустыми", - "%(senderName)s placed a %(callType)s call.": "%(senderName)s выполнил %(callType)s вызов.", + "%(senderName)s placed a %(callType)s call.": "%(senderName)s начал(а) %(callType)s-звонок.", "Please check your email and click on the link it contains. Once this is done, click continue.": "Проверьте свою электронную почту и нажмите на содержащуюся ссылку. После этого нажмите кнопку Продолжить.", - "Power level must be positive integer.": "Уровень авторизации должен быть положительным целым числом.", + "Power level must be positive integer.": "Уровень прав должен быть положительным целым числом.", "Profile": "Профиль", "Reason": "Причина", - "%(targetName)s rejected the invitation.": "%(targetName)s отклонил приглашение.", + "%(targetName)s rejected the invitation.": "%(targetName)s отклонил(а) приглашение.", "Reject invitation": "Отклонить приглашение", "Remove Contact Information?": "Удалить контактную информацию?", - "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s удалил свое отображаемое имя (%(oldDisplayName)s).", - "%(senderName)s removed their profile picture.": "%(senderName)s удалил свое изображение профиля.", - "%(senderName)s requested a VoIP conference.": "%(senderName)s хочет начать VoIP-конференцию.", + "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s удалил(а) свое отображаемое имя (%(oldDisplayName)s).", + "%(senderName)s removed their profile picture.": "%(senderName)s удалил(а) свой аватар.", + "%(senderName)s requested a VoIP conference.": "%(senderName)s хочет начать конференц-звонок.", "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.": "Сброс пароля на данный момент сбрасывает ключи шифрования на всех устройствах, делая зашифрованную историю чатов нечитаемой. Чтобы избежать этого, экспортируйте ключи комнат и импортируйте их после сброса пароля. В будущем это будет исправлено.", - "Riot does not have permission to send you notifications - please check your browser settings": "У Riot нет разрешений на отправку уведомлений - проверьте настройки браузера", + "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 не получил разрешение на отправку уведомлений, пожалуйста, попробуйте снова", "riot-web version:": "версия riot-web:", "Room %(roomId)s not visible": "Комната %(roomId)s невидима", @@ -326,8 +326,8 @@ "Search failed": "Поиск не удался", "Sender device information": "Информация об устройстве отправителя", "Send Invites": "Отправить приглашения", - "%(senderDisplayName)s sent an image.": "%(senderDisplayName)s отправил изображение.", - "%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s отправил(а) приглашение для %(targetDisplayName)s войти в комнату.", + "%(senderDisplayName)s sent an image.": "%(senderDisplayName)s отправил(а) изображение.", + "%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s пригласил(а) %(targetDisplayName)s в комнату.", "Show panel": "Показать панель", "Sign in": "Войти", "Sign out": "Выйти", @@ -341,7 +341,7 @@ "This email address was not found": "Этот адрес электронной почты не найден", "The email address linked to your account must be entered.": "Необходимо ввести адрес электронной почты, связанный с вашей учетной записью.", "The file '%(fileName)s' failed to upload": "Не удалось отправить файл '%(fileName)s'", - "The remote side failed to pick up": "Вызываемый абонент не ответил", + "The remote side failed to pick up": "Собеседник не ответил на ваш звонок", "This room has no local addresses": "В этой комнате нет локальных адресов", "This room is not recognised.": "Эта комната не опознана.", "These are experimental features that may break in unexpected ways": "Это экспериментальные функции, которые могут себя вести неожиданным образом", @@ -397,7 +397,7 @@ "You may need to manually permit Riot to access your microphone/webcam": "Вам необходимо предоставить Riot доступ к микрофону или веб-камере вручную", "Anyone": "Все", "Are you sure you want to leave the room '%(roomName)s'?": "Вы уверены, что хотите покинуть '%(roomName)s'?", - "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s удалил имя комнаты.", + "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s удалил(а) имя комнаты.", "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.": "Смена пароля на данный момент сбрасывает ключи сквозного шифрования на всех устройствах, делая зашифрованную историю чата нечитаемой. Чтобы избежать этого, экспортируйте ключи комнат и импортируйте их после смены пароля. В будущем это будет исправлено.", "Custom level": "Пользовательский уровень", "Device already verified!": "Устройство уже проверено!", @@ -434,12 +434,12 @@ "Server may be unavailable, overloaded, or you hit a bug.": "Сервер может быть недоступен, перегружен или возникла ошибка.", "Server unavailable, overloaded, or something else went wrong.": "Сервер может быть недоступен, перегружен или что-то пошло не так.", "Session ID": "ID сессии", - "%(senderName)s set a profile picture.": "%(senderName)s установил изображение профиля.", - "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s изменил отображаемое имя на %(displayName)s.", + "%(senderName)s set a profile picture.": "%(senderName)s установил(а) себе аватар.", + "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s изменил(а) отображаемое имя на %(displayName)s.", "Signed Out": "Выполнен выход", "Tagged as: ": "Теги: ", - "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. Устройство помечено как проверенное.", - "The file '%(fileName)s' exceeds this home server's size limit for uploads": "Файл '%(fileName)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. Это устройство помечено как проверенное.", + "The file '%(fileName)s' exceeds this home server's size limit for uploads": "Файл '%(fileName)s' слишком большой для отправки на этот сервер", "This Home Server does not support login using email address.": "Этот домашний сервер не поддерживает авторизацию с использованием адреса электронной почты.", "The visibility of existing history will be unchanged": "Видимость существующей истории не изменится", "This room is not accessible by remote Matrix servers": "Это комната недоступна с удаленных серверов Matrix", @@ -447,11 +447,11 @@ "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.": "Попытка загрузить выбранный интервал истории чата этой комнаты не удалась, так как запрошенный элемент не найден.", "Unable to load device list": "Не удалось загрузить список устройств", - "Unknown (user, device) pair:": "Неизвестная пара (пользователь, устройство):", + "Unknown (user, device) pair:": "Неизвестная пара пользователь-устройство:", "Unmute": "Включить звук", "Unrecognised command:": "Нераспознанная команда:", - "Unrecognised room alias:": "Нераспознанный псевдоним комнаты:", - "Verified key": "Проверенный ключ", + "Unrecognised room alias:": "Нераспознанное имя комнаты:", + "Verified key": "Ключ проверен", "WARNING: Device already verified, but keys do NOT MATCH!": "ВНИМАНИЕ: устройство уже было проверено, однако ключи НЕ СОВПАДАЮТ!", "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\". Это может означать, что ваше общение перехватывается!", "You have disabled URL previews by default.": "Предварительный просмотр ссылок отключен по-умолчанию.", @@ -477,7 +477,7 @@ "Start new chat": "Начать новый чат", "Failed to invite": "Пригласить не удалось", "Failed to invite user": "Не удалось пригласить пользователя", - "Failed to invite the following users to the %(roomName)s room:": "Не удалось пригласить следующих пользователей в %(roomName)s:", + "Failed to invite the following users to the %(roomName)s room:": "Не удалось пригласить этих пользователей в %(roomName)s:", "Confirm Removal": "Подтвердите удаление", "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": "Неизвестная ошибка", @@ -621,9 +621,9 @@ "You have been kicked from %(roomName)s by %(userName)s.": "%(userName)s выгнал вас из %(roomName)s.", "You may wish to login with a different account, or add this email to this account.": "При желании вы можете войти в систему с другой учетной записью или добавить этот адрес email в эту учетную запись.", "Your home server does not support device management.": "Ваш домашний сервер не поддерживает управление устройствами.", - "(could not connect media)": "(подключение к СМИ не может быть установлено)", + "(could not connect media)": "(сбой подключения)", "(no answer)": "(нет ответа)", - "(unknown failure: %(reason)s)": "(неизвестная ошибка: %(reason)s", + "(unknown failure: %(reason)s)": "(неизвестная ошибка: %(reason)s)", "Disable Peer-to-Peer for 1:1 calls": "Отключить Peer-to-Peer для 1:1 звонков", "Not a valid Riot keyfile": "Недействительный файл ключа Riot", "Your browser does not support the required cryptography extensions": "Ваш браузер не поддерживает требуемые криптографические расширения", @@ -653,8 +653,8 @@ "Enable automatic language detection for syntax highlighting": "Включить автоматическое определение языка для подсветки синтаксиса", "Hide join/leave messages (invites/kicks/bans unaffected)": "Скрыть сообщения о входе/выходе (не применяется к приглашениям/выкидываниям/банам)", "Integrations Error": "Ошибка интеграции", - "AM": "AM", - "PM": "PM", + "AM": "ДП", + "PM": "ПП", "NOTE: Apps are not end-to-end encrypted": "ПРИМЕЧАНИЕ: приложения не защищены сквозным шифрованием", "Revoke widget access": "Отозвать доступ к виджетам", "Sets the room topic": "Задать тему комнаты", @@ -662,8 +662,8 @@ "To get started, please pick a username!": "Чтобы начать, выберите имя пользователя!", "Unable to create widget.": "Не удалось создать виджет.", "Unbans user with given id": "Разбанить пользователя с заданным ID", - "You are not in this room.": "Вас нет в этой комнате.", - "You do not have permission to do that in this room.": "У вас нет разрешения на это в этой комнате.", + "You are not in this room.": "Вас сейчас нет в этой комнате.", + "You do not have permission to do that in this room.": "У вас нет разрешения на это в данной комнате.", "Verifies a user, device, and pubkey tuple": "Проверка пользователя, устройства и открытого ключа", "Autocomplete Delay (ms):": "Задержка автозаполнения (мс):", "Loading device info...": "Загрузка информации об устройстве...", @@ -674,11 +674,11 @@ "Automatically replace plain text Emoji": "Автоматически заменять обычный текст на Emoji", "Failed to upload image": "Не удалось загрузить изображение", "Hide avatars in user and room mentions": "Скрыть аватары в упоминаниях пользователей и комнат", - "%(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 added by %(senderName)s": "Виджет %(widgetName)s был добавлен %(senderName)s", + "%(widgetName)s widget removed by %(senderName)s": "Виджет %(widgetName)s был удалён %(senderName)s", "Robot check is currently unavailable on desktop - please use a web browser": "Проверка робота в настоящее время недоступна на компьютере - пожалуйста, используйте браузер", "Publish this room to the public in %(domain)s's room directory?": "Опубликовать эту комнату для пользователей в %(domain)s каталоге комнат?", - "%(widgetName)s widget modified by %(senderName)s": "%(widgetName)s виджет, измененный %(senderName)s", + "%(widgetName)s widget modified by %(senderName)s": "Виджет %(widgetName)s был изменён %(senderName)s", "Copied!": "Скопировано!", "Failed to copy": "Не удалось скопировать", "Advanced options": "Дополнительные параметры", @@ -690,8 +690,8 @@ "User Options": "Параметры пользователя", "You are now ignoring %(userId)s": "Теперь вы игнорируете %(userId)s", "You are no longer ignoring %(userId)s": "Вы больше не игнорируете %(userId)s", - "Unignored user": "Неигнорируемый пользователь", - "Ignored user": "Игнорируемый пользователь", + "Unignored user": "Пользователь убран из списка игнорирования", + "Ignored user": "Пользователь добавлен в список игнорирования", "Stops ignoring a user, showing their messages going forward": "Прекращает игнорирование пользователя, показывая их будущие сообщения", "Ignores a user, hiding their messages from you": "Игнорирует пользователя, скрывая сообщения от вас", "Disable Emoji suggestions while typing": "Отключить предложения Emoji при наборе текста", @@ -712,10 +712,10 @@ "To change the topic, you must be a": "Чтобы изменить тему, необходимо быть", "To modify widgets in the room, you must be a": "Чтобы изменить виджеты в комнате, необходимо быть", "Description": "Описание", - "Name or matrix ID": "Имя или matrix ID", + "Name or matrix ID": "Имя или идентификатор Matrix", "Unable to accept invite": "Невозможно принять приглашение", "Leave": "Покинуть", - "Failed to invite the following users to %(groupId)s:": "Не удалось пригласить следующих пользователей в %(groupId)s:", + "Failed to invite the following users to %(groupId)s:": "Не удалось пригласить этих пользователей в %(groupId)s:", "Failed to remove '%(roomName)s' from %(groupId)s": "Не удалось удалить '%(roomName)s' из %(groupId)s", "Are you sure you want to remove '%(roomName)s' from %(groupId)s?": "Вы действительно хотите удалить '%(roomName)s' из %(groupId)s?", "Jump to read receipt": "Перейти к подтверждению о прочтении", @@ -731,9 +731,9 @@ "Add to summary": "Добавить в сводку", "Failed to add the following users to the summary of %(groupId)s:": "Не удалось добавить следующих пользователей в сводку %(groupId)s:", "Which rooms would you like to add to this summary?": "Какие комнаты вы хотите добавить в эту сводку?", - "Room name or alias": "Название комнаты или псевдоним", + "Room name or alias": "Название или идентификатор комнаты", "Pinned Messages": "Закрепленные сообщения", - "%(senderName)s changed the pinned messages for the room.": "%(senderName)s изменил закрепленные сообщения для этой комнаты.", + "%(senderName)s changed the pinned messages for the room.": "%(senderName)s изменил(а) закрепленные в этой комнате сообщения.", "Failed to add the following rooms to the summary of %(groupId)s:": "Не удалось добавить следующие комнаты в сводку %(groupId)s:", "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' не удалось удалить из сводки.", @@ -742,7 +742,7 @@ "Light theme": "Светлая тема", "Dark theme": "Темная тема", "Unknown": "Неизвестно", - "Failed to add the following rooms to %(groupId)s:": "Не удалось добавить следующие комнаты в %(groupId)s:", + "Failed to add the following rooms to %(groupId)s:": "Не удалось добавить эти комнаты в %(groupId)s:", "Matrix ID": "Matrix ID", "Matrix Room ID": "Matrix ID комнаты", "email address": "адрес email", @@ -760,11 +760,11 @@ "Community Settings": "Настройки сообщества", "Invite to Community": "Пригласить в сообщество", "Add to community": "Добавить в сообщество", - "Add rooms to the community": "Добавление комнат в сообщество", + "Add rooms to the community": "Добавить комнаты в сообщество", "Which rooms would you like to add to this community?": "Какие комнаты вы хотите добавить в это сообщество?", - "Who would you like to add to this community?": "Кого бы вы хотели добавить в это сообщество?", - "Invite new community members": "Пригласить новых членов сообщества", - "Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "Предупреждение: любой, кого вы добавляете в сообщество, будет виден всем, кто знает ID сообщества", + "Who would you like to add to this community?": "Кого бы вы хотели пригласить в это сообщество?", + "Invite new community members": "Пригласить в сообщество новых участников", + "Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "Предупреждение: любой, кого вы приглашаете в сообщество, будет виден всем, кто знает имя этого сообщества", "Add rooms to this community": "Добавить комнаты в это сообщество", "Failed to invite users to community": "Не удалось пригласить пользователей в сообщество", "Communities": "Сообщества", @@ -879,7 +879,7 @@ "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": "Видимый для всех", @@ -890,7 +890,7 @@ "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 раз", @@ -923,11 +923,11 @@ "Select devices": "Выбрать устройства", "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": "Обзор устройств", + "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": "Вызов", + "Call": "Позвонить", "Answer": "Ответить", "Send": "Отправить", "Addresses": "Адреса", @@ -955,23 +955,23 @@ "Minimize apps": "Свернуть приложения", "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.": "Подробнее о том, как мы используем аналитику.", - "The information being sent to us to help make Riot.im better includes:": "Информация направляемая нам, чтобы помочь сделать Riot.im лучше включает в себя:", - "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.": "Если на этой странице содержатся идентифицируемые сведения, например номер, идентификатор пользователя или группы, эти данные удаляются перед отправкой на сервер.", + "The information being sent to us to help make Riot.im better includes:": "Информация, отправляемая нам, чтобы помочь нам сделать Riot.im лучше, включает в себя:", + "We also record each page you use in the app (currently ), your User Agent () and your device resolution ().": "Мы также записываем, какими страницами в приложении вы пользуетесь (сейчас — ), ваш User-Agent () и разрешение экрана вашего устройства ().", + "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 version of Riot.im": "Версия Riot.im", "Whether or not you're logged in (we don't record your user name)": "Вошли вы в систему или нет (мы не храним ваше имя пользователя)", "Your language of choice": "Выбранный язык", - "Your homeserver's URL": "URL-адрес домашнего сервера", - "Your identity server's URL": "URL-адрес вашего идентификационного сервера", - "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s", + "Your homeserver's URL": "URL-адрес сервера", + "Your identity server's URL": "URL-адрес сервера идентификации", + "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(day)s %(monthName)s %(fullYear)s", "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", "This room is not public. You will not be able to rejoin without an invite.": "Эта комната не является публичной. Вы не сможете войти без приглашения.", "Show devices, send anyway or cancel.": "Показать устройства, отправить в любом случае или отменить.", "Community IDs cannot not be empty.": "ID сообществ не могут быть пустыми.", "In reply to ": "В ответ на ", - "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s изменил отображаемое имя на %(displayName)s.", + "%(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 в комнату", From c097a8239dbd72b0adb935ddb7dee792a860e0f1 Mon Sep 17 00:00:00 2001 From: Ivan Shapovalov Date: Tue, 24 Apr 2018 12:35:35 +0000 Subject: [PATCH 061/190] Translated using Weblate (Russian) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (1161 of 1161 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 9808a2043a..006950e234 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -799,7 +799,7 @@ "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.": "Чтобы присоединиться к существующему сообществу, вам нужно знать его ID; это будет выглядеть примерно так+primer:matrix.org.", "Something went wrong whilst creating your community": "При создании сообщества что-то пошло не так", - "%(names)s and %(count)s others are typing|other": "%(names)s и %(count)s другие печатают", + "%(names)s and %(count)s others are typing|other": "%(names)s и ещё %(count)s печатают", "And %(count)s more...|other": "И более %(count)s...", "Delete Widget": "Удалить виджет", "Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?": "Удаление виджета удаляет его для всех пользователей этой комнаты. Вы действительно хотите удалить этот виджет?", From e3ad75cca6bcbbaceeb5a77f3fbb7e79675bf641 Mon Sep 17 00:00:00 2001 From: Ivan Shapovalov Date: Tue, 24 Apr 2018 12:49:38 +0000 Subject: [PATCH 062/190] Translated using Weblate (Russian) Currently translated at 100.0% (1161 of 1161 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 | 48 ++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 006950e234..6ef2c177f8 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -140,7 +140,7 @@ "%(targetName)s accepted an invitation.": "%(targetName)s принял приглашение.", "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s принял приглашение от %(displayName)s.", "Active call": "Активный вызов", - "%(names)s and %(lastPerson)s are typing": "%(names)s и %(lastPerson)s печатает", + "%(names)s and %(lastPerson)s are typing": "%(names)s и %(lastPerson)s печатают", "%(senderName)s answered the call.": "%(senderName)s ответил(а) на звонок.", "%(senderName)s banned %(targetName)s.": "%(senderName)s заблокировал(а) %(targetName)s.", "Call Timeout": "Нет ответа", @@ -238,7 +238,7 @@ "and %(count)s others...|other": "и %(count)s других...", "and %(count)s others...|one": "и еще один...", "Are you sure?": "Вы уверены?", - "Autoplay GIFs and videos": "Автовоспроизведение GIF и видео", + "Autoplay GIFs and videos": "Автоматически воспроизводить GIF-анимации и видео", "Click to mute audio": "Щелкните, чтобы выключить звук", "Click to mute video": "Щелкните, чтобы выключить видео", "Click to unmute video": "Щелкните, чтобы включить видео", @@ -248,7 +248,7 @@ "Devices": "Устройства", "Direct chats": "Прямые чаты", "Disinvite": "Отозвать приглашение", - "Don't send typing notifications": "Не оповещать, когда я печатаю", + "Don't send typing notifications": "Не отправлять оповещения о том, когда я печатаю", "Download %(text)s": "Загрузить %(text)s", "Enable encryption": "Включить шифрование", "Enter Code": "Ввести код", @@ -257,7 +257,7 @@ "Failed to forget room %(errCode)s": "Не удалось удалить комнату %(errCode)s", "Failed to join room": "Не удалось войти в комнату", "Access Token:": "Токен доступа:", - "Always show message timestamps": "Всегда показывать временные метки сообщений", + "Always show message timestamps": "Всегда показывать время отправки сообщений", "Authentication": "Аутентификация", "olm version:": "Версия olm:", "%(items)s and %(lastItem)s": "%(items)s и %(lastItem)s", @@ -277,7 +277,7 @@ "Failed to set display name": "Не удалось задать отображаемое имя", "Failed to toggle moderator status": "Не удалось изменить статус модератора", "Fill screen": "Заполнить экран", - "Hide read receipts": "Скрыть отметки о прочтении", + "Hide read receipts": "Скрывать отметки о прочтении", "Hide Text Formatting Toolbar": "Скрыть панель форматирования текста", "Incorrect verification code": "Неверный код подтверждения", "Interface Language": "Язык интерфейса", @@ -373,9 +373,9 @@ "Operation failed": "Сбой операции", "powered by Matrix": "Основано на Matrix", "Add a topic": "Добавить тему", - "Show timestamps in 12 hour format (e.g. 2:30pm)": "Отображать время в 12-часовом формате (напр. 2:30pm)", - "Use compact timeline layout": "Использовать компактный макет временной шкалы", - "Hide removed messages": "Скрыть удаленные сообщения", + "Show timestamps in 12 hour format (e.g. 2:30pm)": "Отображать время в 12-часовом формате (напр. 2:30 ПП)", + "Use compact timeline layout": "Использовать компактный вид списка сообщений", + "Hide removed messages": "Скрывать удалённые сообщения", "No Microphones detected": "Микрофоны не обнаружены", "Unknown devices": "Неизвестное устройство", "Camera": "Камера", @@ -431,7 +431,7 @@ "Server may be unavailable or overloaded": "Сервер может быть недоступен или перегружен", "Server may be unavailable, overloaded, or search timed out :(": "Сервер может быть недоступен, перегружен или поиск прекращен по тайм-ауту :(", "Server may be unavailable, overloaded, or the file too big": "Сервер может быть недоступен, перегружен или размер файла слишком большой", - "Server may be unavailable, overloaded, or you hit a bug.": "Сервер может быть недоступен, перегружен или возникла ошибка.", + "Server may be unavailable, overloaded, or you hit a bug.": "Возможно, сервер недоступен, перегружен или случилась ошибка.", "Server unavailable, overloaded, or something else went wrong.": "Сервер может быть недоступен, перегружен или что-то пошло не так.", "Session ID": "ID сессии", "%(senderName)s set a profile picture.": "%(senderName)s установил(а) себе аватар.", @@ -609,7 +609,7 @@ "Undecryptable": "Невозможно расшифровать", "Unencrypted message": "Незашифрованное сообщение", "unknown caller": "неизвестный абонент", - "Unnamed Room": "Комната без имени", + "Unnamed Room": "Комната без названия", "Unverified": "Не проверено", "Upload new:": "Отправить новый:", "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (уровень доступа %(powerLevelNumber)s)", @@ -625,9 +625,9 @@ "(no answer)": "(нет ответа)", "(unknown failure: %(reason)s)": "(неизвестная ошибка: %(reason)s)", "Disable Peer-to-Peer for 1:1 calls": "Отключить Peer-to-Peer для 1:1 звонков", - "Not a valid Riot keyfile": "Недействительный файл ключа Riot", + "Not a valid Riot keyfile": "Недействительный файл ключей Riot", "Your browser does not support the required cryptography extensions": "Ваш браузер не поддерживает требуемые криптографические расширения", - "Authentication check failed: incorrect password?": "Ошибка аутентификации: неправильный пароль?", + "Authentication check failed: incorrect password?": "Ошибка аутентификации: возможно, неправильный пароль?", "Do you want to set an email address?": "Хотите указать адрес email?", "This will allow you to reset your password and receive notifications.": "Это позволит при необходимости сбросить пароль и получать уведомления.", "Press to start a chat with someone": "Нажмите для начала чата с кем-либо", @@ -650,8 +650,8 @@ "Define the power level of a user": "Определить уровень доступа пользователя", "Do you want to load widget from URL:": "Загрузить виджет из URL-адреса:", "Edit": "Редактировать", - "Enable automatic language detection for syntax highlighting": "Включить автоматическое определение языка для подсветки синтаксиса", - "Hide join/leave messages (invites/kicks/bans unaffected)": "Скрыть сообщения о входе/выходе (не применяется к приглашениям/выкидываниям/банам)", + "Enable automatic language detection for syntax highlighting": "Автоматически определять язык подсветки синтаксиса", + "Hide join/leave messages (invites/kicks/bans unaffected)": "Скрывать уведомления о входе/выходе из комнаты (не применяется к приглашениям/выкидываниям/банам)", "Integrations Error": "Ошибка интеграции", "AM": "ДП", "PM": "ПП", @@ -671,9 +671,9 @@ "Create": "Создать", "Featured Rooms:": "Рекомендуемые комнаты:", "Featured Users:": "Избранные пользователи:", - "Automatically replace plain text Emoji": "Автоматически заменять обычный текст на Emoji", + "Automatically replace plain text Emoji": "Автоматически заменять текстовые смайлики на Emoji", "Failed to upload image": "Не удалось загрузить изображение", - "Hide avatars in user and room mentions": "Скрыть аватары в упоминаниях пользователей и комнат", + "Hide avatars in user and room mentions": "Скрывать аватары в упоминаниях пользователей и комнат", "%(widgetName)s widget added by %(senderName)s": "Виджет %(widgetName)s был добавлен %(senderName)s", "%(widgetName)s widget removed by %(senderName)s": "Виджет %(widgetName)s был удалён %(senderName)s", "Robot check is currently unavailable on desktop - please use a web browser": "Проверка робота в настоящее время недоступна на компьютере - пожалуйста, используйте браузер", @@ -694,7 +694,7 @@ "Ignored user": "Пользователь добавлен в список игнорирования", "Stops ignoring a user, showing their messages going forward": "Прекращает игнорирование пользователя, показывая их будущие сообщения", "Ignores a user, hiding their messages from you": "Игнорирует пользователя, скрывая сообщения от вас", - "Disable Emoji suggestions while typing": "Отключить предложения Emoji при наборе текста", + "Disable Emoji suggestions while typing": "Не предлагать Emoji при наборе текста", "Banned by %(displayName)s": "Запрещено %(displayName)s", "Message removed by %(userId)s": "Сообщение удалено %(userId)s", "To send messages, you must be a": "Для отправки сообщений необходимо быть", @@ -719,8 +719,8 @@ "Failed to remove '%(roomName)s' from %(groupId)s": "Не удалось удалить '%(roomName)s' из %(groupId)s", "Are you sure you want to remove '%(roomName)s' from %(groupId)s?": "Вы действительно хотите удалить '%(roomName)s' из %(groupId)s?", "Jump to read receipt": "Перейти к подтверждению о прочтении", - "Disable big emoji in chat": "Отключить большие emoji в чате", - "Message Pinning": "Закрепление сообщений", + "Disable big emoji in chat": "Отключить большие Emoji в чате", + "Message Pinning": "Закреплённые сообщения", "Remove avatar": "Удалить аватар", "Failed to invite users to %(groupId)s": "Не удалось пригласить пользователей в %(groupId)s", "Unable to reject invite": "Невозможно отклонить приглашение", @@ -809,7 +809,7 @@ "Mention": "Упоминание", "Failed to withdraw invitation": "Не удалось отозвать приглашение", "Community IDs may only contain characters a-z, 0-9, or '=_-./'": "ID сообществ могут содержать только символы a-z, 0-9, или '=_-./'", - "%(names)s and %(count)s others are typing|one": "%(names)s и еще кто-то печатает", + "%(names)s and %(count)s others are typing|one": "%(names)s и еще один собеседник печатают", "%(senderName)s sent an image": "%(senderName)s отправил(а) изображение", "%(senderName)s sent a video": "%(senderName)s отправил(а) видео", "%(senderName)s uploaded a file": "%(senderName)s загрузил(а) файл", @@ -884,8 +884,8 @@ "Visibility in Room List": "Видимость в списке комнат", "Visible to everyone": "Видимый для всех", "Only visible to community members": "Только участникам сообщества", - "Hide avatar changes": "Скрыть изменения аватара", - "Hide display name changes": "Скрыть изменения отображаемого имени", + "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-адресов по умолчанию для участников этой комнаты", @@ -946,7 +946,7 @@ "%(count)s of your messages have not been sent.|one": "Ваше сообщение не было отправлено.", "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|other": "Отправить все или отменить все сейчас. Можно также выбрать отдельные сообщения для отправки или отмены.", "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|one": "Отправить или отменить сообщение сейчас.", - "Message Replies": "Ответы на сообщения", + "Message Replies": "Сообщения-ответы", "Send an encrypted reply…": "Отправить зашифрованный ответ…", "Send a reply (unencrypted)…": "Отправить ответ (незашифрованный)…", "Send an encrypted message…": "Отправить зашифрованное сообщение…", @@ -999,7 +999,7 @@ "Who can join this community?": "Кто может присоединиться к этому сообществу?", "Everyone": "Все", "Stickerpack": "Этикетки", - "Sticker Messages": "Сообщения этикеткой", + "Sticker Messages": "Стикеры", "Add a stickerpack": "Добавить этикетки", "Hide Stickers": "Скрыть этикетки", "Show Stickers": "Показать этикетки", From a3c407992be4d56e176de24acfc9378a1c96ec10 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 24 Apr 2018 13:59:18 +0100 Subject: [PATCH 063/190] Don't autocomplete users for single "@" --- src/autocomplete/UserProvider.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/autocomplete/UserProvider.js b/src/autocomplete/UserProvider.js index e636f95751..ce8f1020a1 100644 --- a/src/autocomplete/UserProvider.js +++ b/src/autocomplete/UserProvider.js @@ -101,8 +101,13 @@ export default class UserProvider extends AutocompleteProvider { let completions = []; const {command, range} = this.getCurrentCommand(query, selection, force); - if (command) { - completions = this.matcher.match(command[0]).map((user) => { + + if (!command) return completions; + + const fullMatch = command[0]; + // Don't search if the query is a single "@" + if (fullMatch && fullMatch !== '@') { + completions = this.matcher.match(fullMatch).map((user) => { const displayName = (user.name || user.userId || '').replace(' (IRC)', ''); // FIXME when groups are done return { // Length of completion should equal length of text in decorator. draft-js From ae15db8208d50466f8cf98ee154624df82880ae4 Mon Sep 17 00:00:00 2001 From: Ivan Shapovalov Date: Tue, 24 Apr 2018 13:00:10 +0000 Subject: [PATCH 064/190] Translated using Weblate (Russian) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (1161 of 1161 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 | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 6ef2c177f8..13b58b877d 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -83,8 +83,8 @@ "Moderator": "Модератор", "%(serverName)s Matrix ID": "%(serverName)s Matrix ID", "Name": "Имя", - "Never send encrypted messages to unverified devices from this device": "Никогда не отправлять зашифрованные сообщения на непроверенные устройства с этого устройства", - "Never send encrypted messages to unverified devices in this room from this device": "Никогда не отправлять зашифрованные сообщения на непроверенные устройства в этой комнате с этого устройства", + "Never send encrypted messages to unverified devices from this device": "Никогда не отправлять зашифрованные сообщения на непроверенные устройства (с этого устройства)", + "Never send encrypted messages to unverified devices in this room from this device": "Никогда не отправлять зашифрованные сообщения на непроверенные устройства (в этой комнате, с этого устройства)", "New password": "Новый пароль", "New passwords must match each other.": "Новые пароли должны совпадать.", "none": "никто", @@ -384,7 +384,7 @@ "Start automatically after system login": "Автозапуск при входе в систему", "Analytics": "Аналитика", "Riot collects anonymous analytics to allow us to improve the application.": "Riot собирает анонимные данные, позволяющие нам улучшить приложение.", - "Opt out of analytics": "Не собирать аналитические данные", + "Opt out of analytics": "Не отправлять данные для аналитики", "Logged in as:": "Вы вошли как:", "Default Device": "Устройство по умолчанию", "No Webcams detected": "Веб-камера не обнаружена", @@ -804,7 +804,7 @@ "Delete Widget": "Удалить виджет", "Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?": "Удаление виджета удаляет его для всех пользователей этой комнаты. Вы действительно хотите удалить этот виджет?", "Message removed": "Сообщение удалено", - "Mirror local video feed": "Зеркальное отображение видео", + "Mirror local video feed": "Зеркально отражать видео со своей камеры", "Invite": "Пригласить", "Mention": "Упоминание", "Failed to withdraw invitation": "Не удалось отозвать приглашение", @@ -886,9 +886,9 @@ "Only visible to community members": "Только участникам сообщества", "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-адресов по умолчанию для участников этой комнаты", + "Enable inline URL previews by default": "Включить предпросмотр ссылок по умолчанию", + "Enable URL previews for this room (only affects you)": "Включить предпросмотр ссылок в этой комнате (влияет только на вас)", + "Enable URL previews by default for participants in this room": "Включить предпросмотр ссылок для участников этой комнаты по умолчанию", "Status.im theme": "Тема status.im", "Restricted": "Ограниченный пользователь", "Username on %(hs)s": "Имя пользователя на %(hs)s", @@ -978,7 +978,7 @@ "Clear filter": "Очистить фильтр", "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "Чтобы настроить фильтр, перетащите аватар сообщества на панель фильтров в левой части экрана. Вы можете нажать на аватар в панели фильтров в любое время, чтобы увидеть только комнаты и людей, связанных с этим сообществом.", "Did you know: you can use communities to filter your Riot.im experience!": "Знаете ли вы: вы можете использовать сообщества, чтобы фильтровать в Riot.im!", - "Disable Community Filter Panel": "Отключить панель фильтра сообщества", + "Disable Community Filter Panel": "Отключить панель сообществ", "If your other devices do not have the key for this message you will not be able to decrypt them.": "Если у других устройств нет ключа для этого сообщения, вы не сможете его расшифровать.", "Key request sent.": "Запрос ключа отправлен.", "Re-request encryption keys from your other devices.": "Повторно запросить ключи шифрования с других устройств.", @@ -1040,7 +1040,7 @@ "The Home Server may be too old to support third party networks": "Домашний сервер может быть слишком старым для поддержки сетей сторонних производителей", "Noisy": "Со звуком", "Room not found": "Комната не найдена", - "Messages containing my display name": "Сообщения, содержащие мое имя", + "Messages containing my display name": "Сообщения, упоминающие моё имя", "Messages in one-to-one chats": "Сообщения в индивидуальных чатах", "Unavailable": "Недоступен", "Error saving email notification preferences": "Ошибка при сохранении настроек уведомлений по email", @@ -1091,7 +1091,7 @@ "Monday": "Понедельник", "Remove from Directory": "Удалить из каталога", "Enable them now": "Включить сейчас", - "Messages containing my user name": "Сообщение, содержащие мое имя пользователя", + "Messages containing my user name": "Сообщение, упоминающие моё имя пользователя", "Toolbox": "Панель инструментов", "Collecting logs": "Сбор журналов", "more": "больше", From 9123ad0659d349a0a46d37d17e164695c23d13f6 Mon Sep 17 00:00:00 2001 From: Ivan Shapovalov Date: Tue, 24 Apr 2018 13:04:52 +0000 Subject: [PATCH 065/190] Translated using Weblate (Russian) Currently translated at 100.0% (1161 of 1161 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 | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 13b58b877d..860a73ee9b 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -234,7 +234,7 @@ "Usage": "Использование", "Use with caution": "Использовать с осторожностью", "VoIP is unsupported": "Звонки не поддерживаются", - "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "Текстовое сообщение было отправлено на +%(msisdn)s. Введите проверочный код, который оно содержит", + "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "Текстовое сообщение было отправлено на +%(msisdn)s. Введите проверочный код из сообщения", "and %(count)s others...|other": "и %(count)s других...", "and %(count)s others...|one": "и еще один...", "Are you sure?": "Вы уверены?", @@ -266,7 +266,7 @@ "Ban": "Заблокировать", "Change Password": "Сменить пароль", "Command error": "Ошибка команды", - "Confirm password": "Подтвердите пароль", + "Confirm password": "Подтвердите новый пароль", "Current password": "Текущий пароль", "Email": "Электронная почта", "Failed to kick": "Не удалось выгнать", @@ -398,7 +398,7 @@ "Anyone": "Все", "Are you sure you want to leave the room '%(roomName)s'?": "Вы уверены, что хотите покинуть '%(roomName)s'?", "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s удалил(а) имя комнаты.", - "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.": "Смена пароля на данный момент сбрасывает ключи сквозного шифрования на всех устройствах, делая зашифрованную историю чата нечитаемой. Чтобы избежать этого, экспортируйте ключи комнат и импортируйте их после смены пароля. В будущем это будет исправлено.", + "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.": "Смена пароля на данный момент сбрасывает ключи сквозного шифрования на всех устройствах, делая историю зашифрованных чатов нечитаемой. Чтобы избежать этого, экспортируйте ключи сквозного шифрования и импортируйте их после смены пароля. В будущем это будет исправлено.", "Custom level": "Пользовательский уровень", "Device already verified!": "Устройство уже проверено!", "Device ID:": "ID устройства:", @@ -566,7 +566,7 @@ "If you already have a Matrix account you can log in instead.": "Если у вас уже есть учетная запись Matrix, вы можете войти.", "Home": "Старт", "Accept": "Принять", - "Active call (%(roomName)s)": "Активный вызов (%(roomName)s)", + "Active call (%(roomName)s)": "Текущий вызов (%(roomName)s)", "Admin Tools": "Инструменты администратора", "Alias (optional)": "Псевдоним (опционально)", "Click here to join the discussion!": "Нажмите здесь, чтобы присоединиться к обсуждению!", @@ -578,7 +578,7 @@ "Encrypted by an unverified device": "Зашифровано непроверенным устройством", "Encryption is enabled in this room": "Шифрование в этой комнате включено", "Encryption is not enabled in this room": "Шифрование в этой комнате не включено", - "Failed to upload profile picture!": "Не удалось отправить изображение профиля!", + "Failed to upload profile picture!": "Не удалось загрузить аватар!", "Incoming call from %(name)s": "Входящий вызов от %(name)s", "Incoming video call from %(name)s": "Входящий видеовызов от %(name)s", "Incoming voice call from %(name)s": "Входящий голосовой вызов от %(name)s", @@ -611,7 +611,7 @@ "unknown caller": "неизвестный абонент", "Unnamed Room": "Комната без названия", "Unverified": "Не проверено", - "Upload new:": "Отправить новый:", + "Upload new:": "Загрузить новый:", "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (уровень доступа %(powerLevelNumber)s)", "Verified": "Проверено", "Would you like to accept or decline this invitation?": "Вы хотели бы подтвердить или отклонить это приглашение?", @@ -620,7 +620,7 @@ "You have been banned from %(roomName)s by %(userName)s.": "%(userName)s заблокировал вас в %(roomName)s.", "You have been kicked from %(roomName)s by %(userName)s.": "%(userName)s выгнал вас из %(roomName)s.", "You may wish to login with a different account, or add this email to this account.": "При желании вы можете войти в систему с другой учетной записью или добавить этот адрес email в эту учетную запись.", - "Your home server does not support device management.": "Ваш домашний сервер не поддерживает управление устройствами.", + "Your home server does not support device management.": "Ваш сервер не поддерживает управление устройствами.", "(could not connect media)": "(сбой подключения)", "(no answer)": "(нет ответа)", "(unknown failure: %(reason)s)": "(неизвестная ошибка: %(reason)s)", @@ -628,7 +628,7 @@ "Not a valid Riot keyfile": "Недействительный файл ключей Riot", "Your browser does not support the required cryptography extensions": "Ваш браузер не поддерживает требуемые криптографические расширения", "Authentication check failed: incorrect password?": "Ошибка аутентификации: возможно, неправильный пароль?", - "Do you want to set an email address?": "Хотите указать адрес email?", + "Do you want to set an email address?": "Хотите указать email-адрес?", "This will allow you to reset your password and receive notifications.": "Это позволит при необходимости сбросить пароль и получать уведомления.", "Press to start a chat with someone": "Нажмите для начала чата с кем-либо", "You're not in any rooms yet! Press to make a room or to browse the directory": "Вы еще не вошли ни в одну из комнат! Нажмите , чтобы создать комнату или для просмотра каталога", @@ -1041,7 +1041,7 @@ "Noisy": "Со звуком", "Room not found": "Комната не найдена", "Messages containing my display name": "Сообщения, упоминающие моё имя", - "Messages in one-to-one chats": "Сообщения в индивидуальных чатах", + "Messages in one-to-one chats": "Сообщения в 1:1 чатах", "Unavailable": "Недоступен", "Error saving email notification preferences": "Ошибка при сохранении настроек уведомлений по email", "View Decrypted Source": "Просмотр расшифрованного источника", @@ -1055,7 +1055,7 @@ "An error occurred whilst saving your email notification preferences.": "Возникла ошибка при сохранении настроек оповещения по email.", "Explore Room State": "Просмотр статуса комнаты", "Source URL": "Исходный URL-адрес", - "Messages sent by bot": "Сообщения, отправленные ботом", + "Messages sent by bot": "Сообщения от ботов", "Filter results": "Фильтрация результатов", "Members": "Участники", "No update available.": "Нет доступных обновлений.", @@ -1103,13 +1103,13 @@ "Failed to get public room list": "Не удалось получить список общедоступных комнат", "Send logs": "Отправка журналов", "All messages": "Все сообщения", - "Call invitation": "Пригласительный звонок", + "Call invitation": "Приглашения на звонки", "Downloading update...": "Загрузка обновления...", "State Key": "Ключ состояния", "Failed to send custom event.": "Не удалось отправить индивидуальное мероприятие.", "What's new?": "Что нового?", "Notify me for anything else": "Уведомлять во всех остальных случаях", - "When I'm invited to a room": "Когда меня приглашают в комнату", + "When I'm invited to a room": "Приглашения в комнаты", "Click here to create a GitHub issue.": "Нажмите здесь для создания запроса о проблеме на GitHub.", "Can't update user notification settings": "Не удается обновить пользовательские настройки оповещения", "Notify for all other messages/rooms": "Уведомлять обо всех других сообщениях/комнатах", @@ -1128,7 +1128,7 @@ "Unable to join network": "Не удается подключиться к сети", "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Возможно вы настроили их не в Riot, а в другом Matrix-клиенте. Настроить их в Riot не удастся, но они будут в нем применяться", "Sorry, your browser is not able to run Riot.": "К сожалению, ваш браузер не способен запустить Riot.", - "Messages in group chats": "Сообщения в групповых чатах", + "Messages in group chats": "Сообщения в конференциях", "Yesterday": "Вчера", "Error encountered (%(errorDetail)s).": "Обнаружена ошибка (%(errorDetail)s).", "Login": "Войти", From 04d06d42ce78be41e587a87534e7b879503affbd Mon Sep 17 00:00:00 2001 From: Ivan Shapovalov Date: Tue, 24 Apr 2018 13:05:44 +0000 Subject: [PATCH 066/190] Translated using Weblate (Russian) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (1161 of 1161 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 860a73ee9b..57d8e2ea88 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -583,7 +583,7 @@ "Incoming video call from %(name)s": "Входящий видеовызов от %(name)s", "Incoming voice call from %(name)s": "Входящий голосовой вызов от %(name)s", "Join as voice or video.": "Войти как голос или видео.", - "Last seen": "Последний визит", + "Last seen": "Последний вход", "Level:": "Уровень:", "No display name": "Нет отображаемого имени", "Otherwise, click here to send a bug report.": "В противном случае, нажмите 2 для отправки отчета об ошибке.", From f53b1e9a3d8a4f37b635e508bb3d1d0e18a89a7f Mon Sep 17 00:00:00 2001 From: Ivan Shapovalov Date: Tue, 24 Apr 2018 13:40:03 +0000 Subject: [PATCH 067/190] Translated using Weblate (Russian) Currently translated at 100.0% (1161 of 1161 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 | 58 ++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 57d8e2ea88..d1bab0da76 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -166,7 +166,7 @@ "%(senderName)s invited %(targetName)s.": "%(senderName)s приглашает %(targetName)s.", "%(displayName)s is typing": "%(displayName)s печатает", "%(targetName)s joined the room.": "%(targetName)s вошёл(-ла) в комнату.", - "%(senderName)s kicked %(targetName)s.": "%(senderName)s исключил(а) %(targetName)s из комнаты.", + "%(senderName)s kicked %(targetName)s.": "%(senderName)s выгнал(а) %(targetName)s.", "%(targetName)s left the room.": "%(targetName)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 сделал(а) историю разговора видимой для всех собеседников с момента их входа в комнату.", @@ -246,14 +246,14 @@ "Decrypt %(text)s": "Расшифровать %(text)s", "Delete": "Удалить", "Devices": "Устройства", - "Direct chats": "Прямые чаты", + "Direct chats": "Личные чаты", "Disinvite": "Отозвать приглашение", "Don't send typing notifications": "Не отправлять оповещения о том, когда я печатаю", "Download %(text)s": "Загрузить %(text)s", "Enable encryption": "Включить шифрование", "Enter Code": "Ввести код", "Failed to ban user": "Не удалось заблокировать пользователя", - "Failed to change power level": "Не удалось изменить уровень привилегий", + "Failed to change power level": "Не удалось изменить уровень прав", "Failed to forget room %(errCode)s": "Не удалось удалить комнату %(errCode)s", "Failed to join room": "Не удалось войти в комнату", "Access Token:": "Токен доступа:", @@ -275,7 +275,7 @@ "Failed to reject invite": "Не удалось отклонить приглашение", "Failed to save settings": "Не удалось сохранить настройки", "Failed to set display name": "Не удалось задать отображаемое имя", - "Failed to toggle moderator status": "Не удалось изменить статус модератора", + "Failed to toggle moderator status": "Не удалось переключить статус модератора", "Fill screen": "Заполнить экран", "Hide read receipts": "Скрывать отметки о прочтении", "Hide Text Formatting Toolbar": "Скрыть панель форматирования текста", @@ -458,8 +458,8 @@ "You have enabled URL previews by default.": "Предварительный просмотр ссылок включен по-умолчанию.", "You need to enter a user name.": "Необходимо ввести имя пользователя.", "You seem to be in a call, are you sure you want to quit?": "Звонок не завершен, вы уверены, что хотите выйти?", - "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Вы не сможете отменить это изменение, так как этот пользователь получит уровень доступа, аналогичный вашему.", - "Please select the destination room for this message": "Выберите комнату для отправки этого сообщения", + "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Вы не сможете отменить это действие, так как этот пользователь получит уровень прав, равный вашему.", + "Please select the destination room for this message": "Выберите, куда отправить это сообщение", "Options": "Настройки", "Passphrases must match": "Пароли должны совпадать", "Passphrase must not be empty": "Пароль не должен быть пустым", @@ -532,7 +532,7 @@ "URL Previews": "Предварительный просмотр URL-адресов", "Drop file here to upload": "Перетащите файл сюда для отправки", " (unsupported)": " (не поддерживается)", - "Ongoing conference call%(supportedText)s.": "Установлен групповой вызов %(supportedText)s.", + "Ongoing conference call%(supportedText)s.": "Идёт конференц-звонок%(supportedText)s.", "Online": "Онлайн", "Idle": "Неактивен", "Offline": "Не в сети", @@ -582,7 +582,7 @@ "Incoming call from %(name)s": "Входящий вызов от %(name)s", "Incoming video call from %(name)s": "Входящий видеовызов от %(name)s", "Incoming voice call from %(name)s": "Входящий голосовой вызов от %(name)s", - "Join as voice or video.": "Войти как голос или видео.", + "Join as voice or video.": "Присоединиться с голосом или с видео.", "Last seen": "Последний вход", "Level:": "Уровень:", "No display name": "Нет отображаемого имени", @@ -607,7 +607,7 @@ "To link to a room it must have an address.": "Чтобы связаться с комнатой, она должна иметь адрес.", "Unable to ascertain that the address this invite was sent to matches one associated with your account.": "Не удалось установить соответствует ли адрес, по которому этому приглашение было послано, вашей учетной записи.", "Undecryptable": "Невозможно расшифровать", - "Unencrypted message": "Незашифрованное сообщение", + "Unencrypted message": "Нешифрованное сообщение", "unknown caller": "неизвестный абонент", "Unnamed Room": "Комната без названия", "Unverified": "Не проверено", @@ -687,7 +687,7 @@ "Ignored Users": "Игнорируемые пользователи", "Ignore": "Игнорировать", "Unignore": "Перестать игнорировать", - "User Options": "Параметры пользователя", + "User Options": "Действия", "You are now ignoring %(userId)s": "Теперь вы игнорируете %(userId)s", "You are no longer ignoring %(userId)s": "Вы больше не игнорируете %(userId)s", "Unignored user": "Пользователь убран из списка игнорирования", @@ -718,7 +718,7 @@ "Failed to invite the following users to %(groupId)s:": "Не удалось пригласить этих пользователей в %(groupId)s:", "Failed to remove '%(roomName)s' from %(groupId)s": "Не удалось удалить '%(roomName)s' из %(groupId)s", "Are you sure you want to remove '%(roomName)s' from %(groupId)s?": "Вы действительно хотите удалить '%(roomName)s' из %(groupId)s?", - "Jump to read receipt": "Перейти к подтверждению о прочтении", + "Jump to read receipt": "Перейти к последнему прочтённому им сообщению", "Disable big emoji in chat": "Отключить большие Emoji в чате", "Message Pinning": "Закреплённые сообщения", "Remove avatar": "Удалить аватар", @@ -806,14 +806,14 @@ "Message removed": "Сообщение удалено", "Mirror local video feed": "Зеркально отражать видео со своей камеры", "Invite": "Пригласить", - "Mention": "Упоминание", + "Mention": "Упомянуть", "Failed to withdraw invitation": "Не удалось отозвать приглашение", "Community IDs may only contain characters a-z, 0-9, or '=_-./'": "ID сообществ могут содержать только символы a-z, 0-9, или '=_-./'", "%(names)s and %(count)s others are typing|one": "%(names)s и еще один собеседник печатают", "%(senderName)s sent an image": "%(senderName)s отправил(а) изображение", "%(senderName)s sent a video": "%(senderName)s отправил(а) видео", - "%(senderName)s uploaded a file": "%(senderName)s загрузил(а) файл", - "Disinvite this user?": "Отменить приглашение этого пользователя?", + "%(senderName)s uploaded a file": "%(senderName)s отправил(а) файл", + "Disinvite this user?": "Отозвать приглашение этого пользователя?", "Kick this user?": "Выгнать этого пользователя?", "Unban this user?": "Разблокировать этого пользователя?", "Ban this user?": "Заблокировать этого пользователя?", @@ -942,7 +942,7 @@ "Flair": "Талант", "Flair will not appear": "Талант не отображается", "Display your community flair in rooms configured to show it.": "Покажите свой талант в комнатах, которых это разрешено.", - "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.": "Вы не сможете отменить это изменение после понижения себя, в случае если вы являетесь последним привилегированным пользователем в этой комнате.", + "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.": "После понижения своих привилегий вы не сможете это отменить. Если вы являетесь последним привилегированным пользователем в этой комнате, выдать права кому-либо заново будет невозможно.", "%(count)s of your messages have not been sent.|one": "Ваше сообщение не было отправлено.", "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|other": "Отправить все или отменить все сейчас. Можно также выбрать отдельные сообщения для отправки или отмены.", "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|one": "Отправить или отменить сообщение сейчас.", @@ -979,12 +979,12 @@ "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "Чтобы настроить фильтр, перетащите аватар сообщества на панель фильтров в левой части экрана. Вы можете нажать на аватар в панели фильтров в любое время, чтобы увидеть только комнаты и людей, связанных с этим сообществом.", "Did you know: you can use communities to filter your Riot.im experience!": "Знаете ли вы: вы можете использовать сообщества, чтобы фильтровать в Riot.im!", "Disable Community Filter Panel": "Отключить панель сообществ", - "If your other devices do not have the key for this message you will not be able to decrypt them.": "Если у других устройств нет ключа для этого сообщения, вы не сможете его расшифровать.", + "If your other devices do not have the key for this message you will not be able to decrypt them.": "Если на других устройствах тоже нет ключа для этого сообщения, вы не сможете его расшифровать.", "Key request sent.": "Запрос ключа отправлен.", "Re-request encryption keys from your other devices.": "Повторно запросить ключи шифрования с других устройств.", "%(user)s is a %(userRole)s": "%(user)s является %(userRole)s", - "Your key share request has been sent - please check your other devices for key share requests.": "Ваш запрос на передачу ключей отправлен - пожалуйста, проверьте другие ваши устройства на запросы передачи ключей.", - "Key share requests are sent to your other devices automatically. If you rejected or dismissed the key share request on your other devices, click here to request the keys for this session again.": "Запросы передачи ключей автоматически отправляются на другие устройства. Если вы отклонили или отменили запрос на передачу ключей на других устройствах, нажмите здесь, чтобы запросить ключи для этого сеанса повторно.", + "Your key share request has been sent - please check your other devices for key share requests.": "Запрос на передачу ключей отправлен — проверьте остальные устройства.", + "Key share requests are sent to your other devices automatically. If you rejected or dismissed the key share request on your other devices, click here to request the keys for this session again.": "Запросы на передачу ключей автоматически отправляются на другие устройства. Если вы отклонили или отменили запрос на другом устройстве, нажмите, чтобы запросить ключи повторно.", "Code": "Код", "Debug Logs Submission": "Отправка журналов отладки", "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contian messages.": "Если вы отправили ошибку через GitHub, журналы отладки могут помочь нам выявить проблему. Журналы отладки содержат данные об использовании приложения, включая ваше имя пользователя, идентификаторы или псевдонимы комнат или групп, которые вы посетили, а также имена других пользователей. Они не содержат сообщений.", @@ -1011,14 +1011,14 @@ "All notifications are currently disabled for all targets.": "Все оповещения для всех устройств отключены.", "Uploading report": "Отправка отчета", "Sunday": "Воскресенье", - "Notification targets": "Цели уведомления", + "Notification targets": "Устройства для уведомлений", "Today": "Сегодня", "Files": "Файлы", "You are not receiving desktop notifications": "Вы не получаете уведомления на рабочем столе", "Friday": "Пятница", "Update": "Обновление", "What's New": "Что нового", - "Add an email address above to configure email notifications": "Добавьте email адрес для оповещений", + "Add an email address above to configure email notifications": "Добавьте email-адрес выше для настройки email-уведомлений", "Expand panel": "Развернуть панель", "On": "Включить", "%(count)s Members|other": "%(count)s членов", @@ -1038,21 +1038,21 @@ "Cancel Sending": "Отменить отправку", "This Room": "Эта комната", "The Home Server may be too old to support third party networks": "Домашний сервер может быть слишком старым для поддержки сетей сторонних производителей", - "Noisy": "Со звуком", + "Noisy": "Вкл. (со звуком)", "Room not found": "Комната не найдена", "Messages containing my display name": "Сообщения, упоминающие моё имя", "Messages in one-to-one chats": "Сообщения в 1:1 чатах", "Unavailable": "Недоступен", - "Error saving email notification preferences": "Ошибка при сохранении настроек уведомлений по email", + "Error saving email notification preferences": "Ошибка сохранения настроек email-уведомлений", "View Decrypted Source": "Просмотр расшифрованного источника", "Failed to update keywords": "Не удалось обновить ключевые слова", "Notes:": "Заметки:", "remove %(name)s from the directory.": "удалить %(name)s из каталога.", - "Notifications on the following keywords follow rules which can’t be displayed here:": "Уведомления по следующим ключевым словам соответствуют правилам, которые нельзя отобразить здесь:", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Уведомления по этим ключевым словам соответствуют правилам, которые нельзя отобразить здесь:", "Safari and Opera work too.": "Safari и Opera работают тоже.", "Please set a password!": "Пожалуйста, установите пароль!", "You have successfully set a password!": "Вы успешно установили пароль!", - "An error occurred whilst saving your email notification preferences.": "Возникла ошибка при сохранении настроек оповещения по email.", + "An error occurred whilst saving your email notification preferences.": "Возникла ошибка при сохранении настроек email-уведомлений.", "Explore Room State": "Просмотр статуса комнаты", "Source URL": "Исходный URL-адрес", "Messages sent by bot": "Сообщения от ботов", @@ -1111,8 +1111,8 @@ "Notify me for anything else": "Уведомлять во всех остальных случаях", "When I'm invited to a room": "Приглашения в комнаты", "Click here to create a GitHub issue.": "Нажмите здесь для создания запроса о проблеме на GitHub.", - "Can't update user notification settings": "Не удается обновить пользовательские настройки оповещения", - "Notify for all other messages/rooms": "Уведомлять обо всех других сообщениях/комнатах", + "Can't update user notification settings": "Не удалось обновить пользовательские настройки оповещения", + "Notify for all other messages/rooms": "Уведомлять обо всех остальных сообщениях и комнатах", "Unable to look up room ID from server": "Не удалось найти ID комнаты на сервере", "Couldn't find a matching Matrix room": "Не удалось найти подходящую комнату Matrix", "All Rooms": "Все комнаты", @@ -1122,18 +1122,18 @@ "Logs sent": "Журналы отправлены", "Back": "Назад", "Reply": "Ответить", - "Show message in desktop notification": "Показывать сообщение в уведомлении на рабочем столе", + "Show message in desktop notification": "Показывать текст сообщения в уведомлениях на рабочем столе", "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Журналы отладки содержат данные об использовании приложения, включая ваше имя пользователя, идентификаторы или псевдонимы комнат или групп, которые вы посетили, а также имена других пользователей. Они не содержат сообщений.", "Unhide Preview": "Показать предварительный просмотр", "Unable to join network": "Не удается подключиться к сети", - "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Возможно вы настроили их не в Riot, а в другом Matrix-клиенте. Настроить их в Riot не удастся, но они будут в нем применяться", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Возможно, вы настроили их не в Riot, а в другом Matrix-клиенте. Настроить их в Riot не удастся, но они будут продолжать работать и здесь", "Sorry, your browser is not able to run Riot.": "К сожалению, ваш браузер не способен запустить Riot.", "Messages in group chats": "Сообщения в конференциях", "Yesterday": "Вчера", "Error encountered (%(errorDetail)s).": "Обнаружена ошибка (%(errorDetail)s).", "Login": "Войти", "Low Priority": "Низкий приоритет", - "Unable to fetch notification target list": "Не удалось получить список целей уведомления", + "Unable to fetch notification target list": "Не удалось получить список устройств для уведомлений", "Set Password": "Задать пароль", "Enable audible notifications in web client": "Включить звуковые уведомления в веб-клиенте", "Permalink": "Постоянная ссылка", From d67125d40f653016a84c0a0e709e6c68cbe4459a Mon Sep 17 00:00:00 2001 From: Ivan Shapovalov Date: Tue, 24 Apr 2018 13:54:22 +0000 Subject: [PATCH 068/190] Translated using Weblate (Russian) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (1161 of 1161 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 | 50 ++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index d1bab0da76..8753ce8940 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -9,7 +9,7 @@ "Anyone who knows the room's link, apart from guests": "Любой, кто знает ссылку на комнату, кроме гостей", "Anyone who knows the room's link, including guests": "Любой, кто знает ссылку на комнату, включая гостей", "Are you sure you want to reject the invitation?": "Вы уверены что вы хотите отклонить приглашение?", - "Are you sure you want to upload the following files?": "Вы уверены что вы хотите отправить следующие файлы?", + "Are you sure you want to upload the following files?": "Вы уверены, что вы хотите отправить эти файлы?", "Banned users": "Заблокированные пользователи", "Bans user with given id": "Блокирует пользователя с заданным ID", "Blacklisted": "В черном списке", @@ -56,11 +56,11 @@ "Failed to upload file": "Не удалось отправить файл", "Favourite": "Избранное", "Favourites": "Избранные", - "Filter room members": "Фильтр участников комнаты", + "Filter room members": "Поиск по участникам", "Forget room": "Забыть комнату", "Forgot your password?": "Забыли пароль?", "For security, this session has been signed out. Please sign in again.": "Для обеспечения безопасности ваша сессия была завершена. Пожалуйста, войдите снова.", - "Hangup": "Закончить", + "Hangup": "Повесить трубку", "Historical": "Архив", "Homeserver is": "Домашний сервер это", "Identity Server is": "Сервер идентификации это", @@ -107,13 +107,13 @@ "Unable to remove contact information": "Не удалось удалить контактную информацию", "Unable to verify email address.": "Не удалось проверить адрес email.", "Unban": "Разблокировать", - "Unencrypted room": "Незашифрованная комната", + "Unencrypted room": "Нешифрованная комната", "unencrypted": "без шифрования", "unknown device": "неизвестное устройство", "unknown error code": "неизвестный код ошибки", "Upload avatar": "Загрузить аватар", "Upload Files": "Отправка файлов", - "Upload file": "Отправка файла", + "Upload file": "Отправить файл", "User ID": "ID пользователя", "User Interface": "Пользовательский интерфейс", "User name": "Имя пользователя", @@ -121,7 +121,7 @@ "Verification Pending": "В ожидании подтверждения", "Verification": "Проверка", "verified": "проверенный", - "Video call": "Видеозвонок", + "Video call": "Видеовызов", "Voice call": "Голосовой вызов", "VoIP conference finished.": "Конференц-звонок окончен.", "VoIP conference started.": "Конференц-звонок начался.", @@ -278,7 +278,7 @@ "Failed to toggle moderator status": "Не удалось переключить статус модератора", "Fill screen": "Заполнить экран", "Hide read receipts": "Скрывать отметки о прочтении", - "Hide Text Formatting Toolbar": "Скрыть панель форматирования текста", + "Hide Text Formatting Toolbar": "Скрыть инструменты форматирования текста", "Incorrect verification code": "Неверный код подтверждения", "Interface Language": "Язык интерфейса", "Invalid alias format": "Недопустимый формат псевдонима", @@ -359,17 +359,17 @@ "Room": "Комната", "Cancel": "Отмена", "bold": "жирный", - "italic": "курсивный", + "italic": "курсив", "strike": "перечеркнутый", "underline": "подчеркнутый", "code": "код", "quote": "цитата", - "bullet": "список", - "numbullet": "нумерованный список", + "bullet": "элемент списка", + "numbullet": "элемент нумерованного списка", "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Не удается подключиться к домашнему серверу через HTTP, так как в адресной строке браузера указан URL HTTPS. Используйте HTTPS или либо включите небезопасные сценарии.", "Dismiss": "Отклонить", "Custom Server Options": "Выбор другого сервера", - "Mute": "Беззвучный", + "Mute": "Заглушить", "Operation failed": "Сбой операции", "powered by Matrix": "Основано на Matrix", "Add a topic": "Добавить тему", @@ -412,7 +412,7 @@ "Import": "Импорт", "Incorrect username and/or password.": "Неверное имя пользователя и/или пароль.", "Invalid file%(extra)s": "Недопустимый файл%(extra)s", - "Invited": "Приглашен", + "Invited": "Приглашён", "Jump to first unread message.": "Перейти к первому непрочитанному сообщению.", "Message not sent due to unknown devices being present": "Сообщение не отправлено из-за присутствия неизвестных устройств", "Mobile phone number (optional)": "Номер мобильного телефона (не обязательно)", @@ -432,7 +432,7 @@ "Server may be unavailable, overloaded, or search timed out :(": "Сервер может быть недоступен, перегружен или поиск прекращен по тайм-ауту :(", "Server may be unavailable, overloaded, or the file too big": "Сервер может быть недоступен, перегружен или размер файла слишком большой", "Server may be unavailable, overloaded, or you hit a bug.": "Возможно, сервер недоступен, перегружен или случилась ошибка.", - "Server unavailable, overloaded, or something else went wrong.": "Сервер может быть недоступен, перегружен или что-то пошло не так.", + "Server unavailable, overloaded, or something else went wrong.": "Возможно, сервер недоступен, перегружен или что-то ещё пошло не так.", "Session ID": "ID сессии", "%(senderName)s set a profile picture.": "%(senderName)s установил(а) себе аватар.", "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s изменил(а) отображаемое имя на %(displayName)s.", @@ -448,7 +448,7 @@ "Tried to load a specific point in this room's timeline, but was unable to find it.": "Попытка загрузить выбранный интервал истории чата этой комнаты не удалась, так как запрошенный элемент не найден.", "Unable to load device list": "Не удалось загрузить список устройств", "Unknown (user, device) pair:": "Неизвестная пара пользователь-устройство:", - "Unmute": "Включить звук", + "Unmute": "Вернуть право речи", "Unrecognised command:": "Нераспознанная команда:", "Unrecognised room alias:": "Нераспознанное имя комнаты:", "Verified key": "Ключ проверен", @@ -600,9 +600,9 @@ "Room contains unknown devices": "Комната содержит непроверенные устройства", "%(roomName)s does not exist.": "%(roomName)s не существует.", "%(roomName)s is not accessible at this time.": "%(roomName)s на данный момент недоступна.", - "Seen by %(userName)s at %(dateTime)s": "Просмотрено %(userName)s в %(dateTime)s", + "Seen by %(userName)s at %(dateTime)s": "Прочитано %(userName)s в %(dateTime)s", "Send anyway": "Отправить в любом случае", - "Show Text Formatting Toolbar": "Показать панель инструментов форматирования текста", + "Show Text Formatting Toolbar": "Показать инструменты форматирования текста", "This invitation was sent to an email address which is not associated with this account:": "Это приглашение было отправлено на адрес email, не связанный с этой учетной записью:", "To link to a room it must have an address.": "Чтобы связаться с комнатой, она должна иметь адрес.", "Unable to ascertain that the address this invite was sent to matches one associated with your account.": "Не удалось установить соответствует ли адрес, по которому этому приглашение было послано, вашей учетной записи.", @@ -612,7 +612,7 @@ "Unnamed Room": "Комната без названия", "Unverified": "Не проверено", "Upload new:": "Загрузить новый:", - "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (уровень доступа %(powerLevelNumber)s)", + "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (уровень прав %(powerLevelNumber)s)", "Verified": "Проверено", "Would you like to accept or decline this invitation?": "Вы хотели бы подтвердить или отклонить это приглашение?", "(~%(count)s results)|one": "(~%(count)s результат)", @@ -755,7 +755,7 @@ "Unnamed room": "Комната без названия", "World readable": "Доступно всем", "Guests can join": "Гости могут присоединиться", - "No rooms to show": "Нет комнат для отображения", + "No rooms to show": "Нет комнат, нечего показывать", "Long Description (HTML)": "Длинное описание (HTML)", "Community Settings": "Настройки сообщества", "Invite to Community": "Пригласить в сообщество", @@ -906,10 +906,10 @@ "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", - "%(duration)ss": "%(duration)sсек", - "%(duration)sm": "%(duration)sмин", - "%(duration)sh": "%(duration)sчас", - "%(duration)sd": "%(duration)sдн", + "%(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-страницы для показа участникам.
Щелкните здесь, чтобы открыть параметры и добавить его!", "Online for %(duration)s": "В сети %(duration)s", "Offline for %(duration)s": "Не в сети %(duration)s", @@ -948,9 +948,9 @@ "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|one": "Отправить или отменить сообщение сейчас.", "Message Replies": "Сообщения-ответы", "Send an encrypted reply…": "Отправить зашифрованный ответ…", - "Send a reply (unencrypted)…": "Отправить ответ (незашифрованный)…", + "Send a reply (unencrypted)…": "Отправить ответ (нешифрованный)…", "Send an encrypted message…": "Отправить зашифрованное сообщение…", - "Send a message (unencrypted)…": "Отправить сообщение (незашифрованное)…", + "Send a message (unencrypted)…": "Отправить сообщение (нешифрованное)…", "Replying": "Отвечает", "Minimize apps": "Свернуть приложения", "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "Конфиденциальность важна для нас, поэтому мы не собираем никаких личных или идентифицируемых данных для нашей аналитики.", @@ -990,7 +990,7 @@ "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contian messages.": "Если вы отправили ошибку через GitHub, журналы отладки могут помочь нам выявить проблему. Журналы отладки содержат данные об использовании приложения, включая ваше имя пользователя, идентификаторы или псевдонимы комнат или групп, которые вы посетили, а также имена других пользователей. Они не содержат сообщений.", "Submit debug logs": "Отправка журналов отладки", "Opens the Developer Tools dialog": "Открывает Инструменты разработчика", - "Seen by %(displayName)s (%(userName)s) at %(dateTime)s": "Просмотрено %(displayName)s (%(userName)s) в %(dateTime)s", + "Seen by %(displayName)s (%(userName)s) at %(dateTime)s": "Прочитано %(displayName)s (%(userName)s) в %(dateTime)s", "Unable to join community": "Не удалось присоединиться к сообществу", "Unable to leave community": "Не удалось покинуть сообщество", "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Изменения имени и аватара, внесенные в ваше сообщество, могут не отображаться другим пользователям в течение 30 минут.", From c4a1fa531ad127316cb0d43cd4479200969927ee Mon Sep 17 00:00:00 2001 From: RainSlide Date: Tue, 24 Apr 2018 11:27:48 +0000 Subject: [PATCH 069/190] Translated using Weblate (Chinese (Simplified)) Currently translated at 97.5% (1132 of 1161 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 | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/i18n/strings/zh_Hans.json b/src/i18n/strings/zh_Hans.json index ab299837c9..ee61c73c85 100644 --- a/src/i18n/strings/zh_Hans.json +++ b/src/i18n/strings/zh_Hans.json @@ -39,7 +39,7 @@ "Failed to change password. Is your password correct?": "修改密码失败。确认原密码输入正确吗?", "Failed to forget room %(errCode)s": "忘记聊天室失败,错误代码: %(errCode)s", "Failed to join room": "无法加入聊天室", - "Failed to kick": "踢人失败", + "Failed to kick": "移除失败", "Failed to leave room": "无法退出聊天室", "Failed to load timeline position": "无法加载时间轴位置", "Failed to lookup current room": "找不到当前聊天室", @@ -104,7 +104,7 @@ "Server may be unavailable or overloaded": "服务器可能不可用或者超载", "Server may be unavailable, overloaded, or search timed out :(": "服务器可能不可用、超载,或者搜索超时 :(", "Server may be unavailable, overloaded, or the file too big": "服务器可能不可用、超载,或者文件过大", - "Server may be unavailable, overloaded, or you hit a bug.": "服务器可能不可用、超载,或者你遇到了一个漏洞.", + "Server may be unavailable, overloaded, or you hit a bug.": "服务器可能不可用、超载,或者你遇到了一个 bug。", "Server unavailable, overloaded, or something else went wrong.": "服务器可能不可用、超载,或者其他东西出错了.", "Session ID": "会话 ID", "%(senderName)s set a profile picture.": "%(senderName)s 设置了头像。.", @@ -133,7 +133,7 @@ "Advanced": "高级", "Algorithm": "算法", "Always show message timestamps": "总是显示消息时间戳", - "%(names)s and %(lastPerson)s are typing": "%(names)s 和 %(lastPerson)s 正在打字", + "%(names)s and %(lastPerson)s are typing": "%(names)s 和 %(lastPerson)s 正在输入", "A new password must be entered.": "一个新的密码必须被输入。.", "%(senderName)s answered the call.": "%(senderName)s 接了通话。.", "An error has occurred.": "一个错误出现了。", @@ -246,7 +246,7 @@ "Invites user with given id to current room": "按照 ID 邀请指定用户加入当前聊天室", "'%(alias)s' is not a valid format for an address": "'%(alias)s' 不是一个合法的邮箱地址格式", "'%(alias)s' is not a valid format for an alias": "'%(alias)s' 不是一个合法的昵称格式", - "%(displayName)s is typing": "%(displayName)s 正在打字", + "%(displayName)s is typing": "%(displayName)s 正在输入", "Sign in with": "第三方登录", "Message not sent due to unknown devices being present": "消息未发送,因为有未知的设备存在", "Missing room_id in request": "请求中没有 聊天室 ID", @@ -395,7 +395,7 @@ "Drop here to tag %(section)s": "拖拽到这里标记 %(section)s", "Enable automatic language detection for syntax highlighting": "启用自动语言检测用于语法高亮", "Failed to change power level": "修改特权级别失败", - "Kick": "踢出", + "Kick": "移除", "Kicks user with given id": "按照 ID 移除特定的用户", "Last seen": "上次看见", "Level:": "级别:", @@ -449,7 +449,7 @@ "Passwords don't match.": "密码不匹配。", "I already have an account": "我已经有一个帐号", "Unblacklist": "移出黑名单", - "Not a valid Riot keyfile": "不是一个合法的 Riot 密钥文件", + "Not a valid Riot keyfile": "不是一个有效的 Riot 密钥文件", "%(targetName)s accepted an invitation.": "%(targetName)s 接受了一个邀请。", "Do you want to load widget from URL:": "你想从此 URL 加载小组件吗:", "Hide join/leave messages (invites/kicks/bans unaffected)": "隐藏加入/退出消息(邀请/踢出/封禁不受影响)", @@ -547,7 +547,7 @@ "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 和 device %(deviceId)s 的签名密钥是 \"%(fprint)s\",和提供的咪呀 \"%(fingerprint)s\" 不匹配。这可能意味着你的通信正在被窃听!", "%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s 收回了 %(targetName)s 的邀请。", "Would you like to accept or decline this invitation?": "你想要 接受 还是 拒绝 这个邀请?", - "You already have existing direct chats with this user:": "你已经有和这个用户的直接聊天:", + "You already have existing direct chats with this user:": "你已经有和此用户的直接聊天:", "You're not in any rooms yet! Press to make a room or to browse the directory": "你现在还不再任何聊天室!按下 来创建一个聊天室或者 来浏览目录", "You cannot place a call with yourself.": "你不能和你自己发起一个通话。", "You have been kicked from %(roomName)s by %(userName)s.": "你已经被 %(userName)s 踢出了 %(roomName)s.", @@ -620,7 +620,7 @@ "Ongoing conference call%(supportedText)s.": "正在进行的会议通话 %(supportedText)s.", "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s 修改了 %(roomName)s 的头像", "This will be your account name on the homeserver, or you can pick a different server.": "这将会成为你在 主服务器上的账户名,或者你可以选择一个 不同的服务器。", - "Your browser does not support the required cryptography extensions": "你的浏览器不支持所需的密码学扩展", + "Your browser does not support the required cryptography extensions": "你的浏览器不支持 Riot 所需的密码学特性", "Authentication check failed: incorrect password?": "身份验证失败:密码错误?", "This will allow you to reset your password and receive notifications.": "这将允许你重置你的密码和接收通知。", "Share without verifying": "不验证就分享", @@ -650,14 +650,14 @@ "%(senderName)s unbanned %(targetName)s.": "%(senderName)s 解除了 %(targetName)s 的封禁。", "(could not connect media)": "(无法连接媒体)", "%(senderName)s changed the pinned messages for the room.": "%(senderName)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 %(count)s others are typing|other": "%(names)s 和另外 %(count)s 个人正在输入", + "%(names)s and %(count)s others are typing|one": "%(names)s 和另一个人正在输入", "Send": "发送", "Message Pinning": "消息置顶", - "Disable Emoji suggestions while typing": "禁用打字时Emoji建议", + "Disable Emoji suggestions while typing": "输入时禁用 Emoji 建议", "Use compact timeline layout": "使用紧凑的时间线布局", "Hide avatar changes": "隐藏头像修改", - "Hide display name changes": "隐藏昵称的修改", + "Hide display name changes": "隐藏昵称修改", "Disable big emoji in chat": "禁用聊天中的大Emoji", "Never send encrypted messages to unverified devices in this room from this device": "在此设备上,在此聊天室中不向未经验证的设备发送加密的消息", "Enable URL previews for this room (only affects you)": "在此聊天室启用链接预览(只影响你)", @@ -754,10 +754,10 @@ "Message Replies": "消息回复", "Disable Peer-to-Peer for 1:1 calls": "在1:1通话中禁用点到点", "Enable inline URL previews by default": "默认启用网址预览", - "Disinvite this user?": "取消邀请这个用户?", - "Kick this user?": "踢出这个用户?", - "Unban this user?": "解除这个用户的封禁?", - "Ban this user?": "封紧这个用户?", + "Disinvite this user?": "取消邀请此用户?", + "Kick this user?": "移除此用户?", + "Unban this user?": "解除此用户的封禁?", + "Ban this user?": "封紧此用户?", "Send an encrypted reply…": "发送加密的回复…", "Send a reply (unencrypted)…": "发送回复(未加密)…", "Send an encrypted message…": "发送加密消息…", From 8c008c244b26494bee2e37fd838bf5f0d812ea91 Mon Sep 17 00:00:00 2001 From: Ivan Shapovalov Date: Tue, 24 Apr 2018 14:08:31 +0000 Subject: [PATCH 070/190] Translated using Weblate (Russian) Currently translated at 100.0% (1161 of 1161 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 | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 8753ce8940..2cf57d3f60 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -68,7 +68,7 @@ "Import E2E room keys": "Импорт ключей сквозного шифрования", "Invalid Email Address": "Недопустимый адрес email", "Invite new room members": "Пригласить в комнату новых участников", - "Invites": "Приглашает", + "Invites": "Приглашения", "Invites user with given id to current room": "Приглашает пользователя с заданным ID в текущую комнату", "Sign in with": "Войти, используя", "Joins room with given alias": "Входит в комнату с заданным псевдонимом", @@ -77,7 +77,7 @@ "Leave room": "Покинуть комнату", "Login as guest": "Войти как гость", "Logout": "Выйти", - "Low priority": "Низкий приоритет", + "Low priority": "Неважные", "Manage Integrations": "Управление интеграциями", "Mobile phone number": "Номер мобильного телефона", "Moderator": "Модератор", @@ -153,7 +153,7 @@ "Conference calls are not supported in encrypted rooms": "Конференц-связь не поддерживается в зашифрованных комнатах", "Conference calls are not supported in this client": "Конференц-связь в этом клиенте не поддерживается", "/ddg is not a command": "/ddg — это не команда", - "Drop here to tag %(section)s": "Перетащите сюда для тега %(section)s", + "Drop here to tag %(section)s": "Перетащите сюда, чтобы пометить как %(section)s", "%(senderName)s ended the call.": "%(senderName)s завершил(а) звонок.", "Existing Call": "Текущий вызов", "Failed to lookup current room": "Не удалось найти текущую комнату", @@ -201,7 +201,7 @@ "You need to be able to invite users to do that.": "Для этого вы должны иметь возможность приглашать пользователей.", "You cannot place VoIP calls in this browser.": "Звонки не поддерживаются в этом браузере.", "You are already in a call.": "Вы уже сделали звонок.", - "You are trying to access %(roomName)s.": "Вы пытаетесь получить доступ к %(roomName)s.", + "You are trying to access %(roomName)s.": "Вы пытаетесь войти в %(roomName)s.", "You cannot place a call with yourself.": "Вы не можете позвонить самому себе.", "%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s отозвал(а) своё приглашение %(targetName)s.", "Sep": "Сен", @@ -352,7 +352,7 @@ "Turn Markdown off": "Выключить Markdown", "Turn Markdown on": "Включить Markdown", "Unknown room %(roomId)s": "Неизвестная комната %(roomId)s", - "You have been invited to join this room by %(inviterName)s": "%(inviterName)s приглашает вас в комнату", + "You have been invited to join this room by %(inviterName)s": "%(inviterName)s приглашает вас в эту комнату", "You seem to be uploading files, are you sure you want to quit?": "Похоже, вы отправляете файлы, вы уверены, что хотите выйти?", "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s %(time)s": "%(weekDayName)s, %(day)s %(monthName)s %(fullYear)s %(time)s", "Make Moderator": "Сделать модератором", @@ -592,8 +592,8 @@ "Reason: %(reasonText)s": "Причина: %(reasonText)s", "Rejoin": "Войти повторно", "Start authentication": "Начать проверку подлинности", - "This room": "В этой комнате", - "(~%(count)s results)|other": "(~%(count)s результаты)", + "This room": "Эта комната", + "(~%(count)s results)|other": "(~%(count)s результатов)", "Device Name": "Имя устройства", "Custom": "Пользовательские", "Decline": "Отклонить", @@ -603,9 +603,9 @@ "Seen by %(userName)s at %(dateTime)s": "Прочитано %(userName)s в %(dateTime)s", "Send anyway": "Отправить в любом случае", "Show Text Formatting Toolbar": "Показать инструменты форматирования текста", - "This invitation was sent to an email address which is not associated with this account:": "Это приглашение было отправлено на адрес email, не связанный с этой учетной записью:", + "This invitation was sent to an email address which is not associated with this account:": "Это приглашение было отправлено на email-адрес, не связанный с вашей учетной записью:", "To link to a room it must have an address.": "Чтобы связаться с комнатой, она должна иметь адрес.", - "Unable to ascertain that the address this invite was sent to matches one associated with your account.": "Не удалось установить соответствует ли адрес, по которому этому приглашение было послано, вашей учетной записи.", + "Unable to ascertain that the address this invite was sent to matches one associated with your account.": "Не удалось установить, что адрес в этом приглашении соответствует вашей учетной записи.", "Undecryptable": "Невозможно расшифровать", "Unencrypted message": "Нешифрованное сообщение", "unknown caller": "неизвестный абонент", @@ -614,12 +614,12 @@ "Upload new:": "Загрузить новый:", "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (уровень прав %(powerLevelNumber)s)", "Verified": "Проверено", - "Would you like to accept or decline this invitation?": "Вы хотели бы подтвердить или отклонить это приглашение?", + "Would you like to accept or decline this invitation?": "Вы хотите подтвердить или отклонить это приглашение?", "(~%(count)s results)|one": "(~%(count)s результат)", "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-сертификат домашнего сервера является доверенным и что расширение браузера не блокирует запросы.", - "You have been banned from %(roomName)s by %(userName)s.": "%(userName)s заблокировал вас в %(roomName)s.", - "You have been kicked from %(roomName)s by %(userName)s.": "%(userName)s выгнал вас из %(roomName)s.", - "You may wish to login with a different account, or add this email to this account.": "При желании вы можете войти в систему с другой учетной записью или добавить этот адрес email в эту учетную запись.", + "You have been banned from %(roomName)s by %(userName)s.": "%(userName)s заблокировал(а) вас в %(roomName)s.", + "You have been kicked from %(roomName)s by %(userName)s.": "%(userName)s выгнал(а) вас из %(roomName)s.", + "You may wish to login with a different account, or add this email to this account.": "При желании вы можете войти в систему под другим именем или привязать этот email-адрес к вашей учетной записи.", "Your home server does not support device management.": "Ваш сервер не поддерживает управление устройствами.", "(could not connect media)": "(сбой подключения)", "(no answer)": "(нет ответа)", @@ -630,8 +630,8 @@ "Authentication check failed: incorrect password?": "Ошибка аутентификации: возможно, неправильный пароль?", "Do you want to set an email address?": "Хотите указать email-адрес?", "This will allow you to reset your password and receive notifications.": "Это позволит при необходимости сбросить пароль и получать уведомления.", - "Press to start a chat with someone": "Нажмите для начала чата с кем-либо", - "You're not in any rooms yet! Press to make a room or to browse the directory": "Вы еще не вошли ни в одну из комнат! Нажмите , чтобы создать комнату или для просмотра каталога", + "Press to start a chat with someone": "Нажмите , чтобы начать разговор с кем-либо", + "You're not in any rooms yet! Press to make a room or to browse the directory": "Вы еще не вошли ни в одну из комнат! Нажмите , чтобы создать комнату, или , чтобы посмотреть каталог комнат", "To return to your account in future you need to set a password": "Чтобы вернуться к учетной записи в будущем, необходимо задать пароль", "Skip": "Пропустить", "Start verification": "Начать проверку", @@ -753,8 +753,8 @@ "No pinned messages.": "Нет прикрепленных сообщений.", "Loading...": "Загрузка...", "Unnamed room": "Комната без названия", - "World readable": "Доступно всем", - "Guests can join": "Гости могут присоединиться", + "World readable": "Открыта для чтения", + "Guests can join": "Открыта для участия", "No rooms to show": "Нет комнат, нечего показывать", "Long Description (HTML)": "Длинное описание (HTML)", "Community Settings": "Настройки сообщества", @@ -873,9 +873,9 @@ "%(items)s and %(count)s others|one": "%(items)s и один другой", "An email has been sent to %(emailAddress)s. Once you've followed the link it contains, click below.": "Сообщение отправлено на %(emailAddress)s. После перехода по ссылке в отправленном вам письме, щелкните ниже.", "Room Notification": "Уведомления комнаты", - "Drop here to tag direct chat": "Перетащите сюда, чтобы отметить как прямой чат", - "Drop here to restore": "Перетащиет сюда для восстановления", - "Drop here to demote": "Перетащите сюда для понижения", + "Drop here to tag direct chat": "Перетащите сюда, чтобы пометить как личный чат", + "Drop here to restore": "Перетащиет сюда, чтобы вернуть", + "Drop here to demote": "Перетащите сюда, чтобы понизить", "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.": "Эти комнаты отображаются для участников сообщества на странице сообщества. Участники сообщества могут присоединиться к комнатам, щелкнув на них.", From 79c3335765eb9aee0376349076c05ec5c69df580 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 24 Apr 2018 16:05:14 +0100 Subject: [PATCH 071/190] Support origin lock in cross-origin renderer This adds a URL parameter to the cross-origin renderer that makes it only accept messages from a given domain. This adds an extra layer of security to the cross-origin iframe and is backwards compatible in both directions. --- src/components/views/messages/MFileBody.js | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/components/views/messages/MFileBody.js b/src/components/views/messages/MFileBody.js index 90efe24df3..fbce53e07a 100644 --- a/src/components/views/messages/MFileBody.js +++ b/src/components/views/messages/MFileBody.js @@ -1,5 +1,6 @@ /* Copyright 2015, 2016 OpenMarket Ltd +Copyright 2018 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -99,16 +100,27 @@ Tinter.registerTintable(updateTintedDownloadImage); // overridable so that people running their own version of the client can // choose a different renderer. // -// To that end the first version of the blob generation will be the following +// To that end the current version of the blob generation is the following // html: // // // // This waits to receive a message event sent using the window.postMessage API. // When it receives the event it evals a javascript function in data.code and -// runs the function passing the event as an argument. +// runs the function passing the event as an argument. This version adds +// support for a query parameter controlling the origin from which messages +// will be processed as an extra layer of security (note that the default URL +// is still 'v1' since it is backwards compatible). // // In particular it means that the rendering function can be written as a // ordinary javascript function which then is turned into a string using @@ -325,6 +337,7 @@ module.exports = React.createClass({ if (this.context.appConfig && this.context.appConfig.cross_origin_renderer_url) { renderer_url = this.context.appConfig.cross_origin_renderer_url; } + renderer_url += "?origin=" + encodeURIComponent(document.origin); return (
From 80837a9199dfc4302de86b60654dd8f56564b2fb Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 24 Apr 2018 17:53:23 +0100 Subject: [PATCH 072/190] s/contian/contain/g Fixes https://github.com/vector-im/riot-web/issues/6565 --- src/components/structures/UserSettings.js | 2 +- src/i18n/strings/bg.json | 2 +- src/i18n/strings/de_DE.json | 2 +- src/i18n/strings/en_EN.json | 2 +- src/i18n/strings/eu.json | 2 +- src/i18n/strings/fr.json | 2 +- src/i18n/strings/gl.json | 2 +- src/i18n/strings/hu.json | 2 +- src/i18n/strings/it.json | 2 +- src/i18n/strings/lv.json | 2 +- src/i18n/strings/nl.json | 2 +- src/i18n/strings/ru.json | 2 +- src/i18n/strings/sk.json | 2 +- src/i18n/strings/zh_Hans.json | 2 +- src/i18n/strings/zh_Hant.json | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index 85223c4eef..7948f4fb5d 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -801,7 +801,7 @@ module.exports = React.createClass({ "us track down the problem. Debug logs contain application " + "usage data including your username, the IDs or aliases of " + "the rooms or groups you have visited and the usernames of " + - "other users. They do not contian messages.", + "other users. They do not contain messages.", ) }

{ this.props.children } -
From 71acf87c04e6b3063116cf0c40dc6a8ecb3faba5 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 27 Apr 2018 11:13:09 +0100 Subject: [PATCH 097/190] Add comments to _EventTile.scss Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- res/css/views/rooms/_EventTile.scss | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/res/css/views/rooms/_EventTile.scss b/res/css/views/rooms/_EventTile.scss index 9217a64040..2339d92913 100644 --- a/res/css/views/rooms/_EventTile.scss +++ b/res/css/views/rooms/_EventTile.scss @@ -203,9 +203,10 @@ limitations under the License. text-decoration: none; } +// Explicit relationships so that it doesn't apply to nested EventTile components (e.g in Replies) .mx_EventTile_last > div > a > .mx_MessageTimestamp, .mx_EventTile:hover > div > a > .mx_MessageTimestamp, -.mx_EventTile.menu > div > a > .mx_MessageTimestamp { +.mx_EventTile.menu > div > a > .mx_MessageTimestamp { visibility: visible; } @@ -343,6 +344,7 @@ limitations under the License. border-left: $e2e-unverified-color 5px solid; } +// Explicit relationships so that it doesn't apply to nested EventTile components (e.g in Replies) .mx_EventTile:hover.mx_EventTile_verified .mx_EventTile_line > a > .mx_MessageTimestamp, .mx_EventTile:hover.mx_EventTile_unverified .mx_EventTile_line > a > .mx_MessageTimestamp { left: 3px; @@ -355,6 +357,7 @@ limitations under the License. } */ +// Explicit relationships so that it doesn't apply to nested EventTile components (e.g in Replies) .mx_EventTile:hover.mx_EventTile_verified .mx_EventTile_line > .mx_EventTile_e2eIcon, .mx_EventTile:hover.mx_EventTile_unverified .mx_EventTile_line > .mx_EventTile_e2eIcon { display: block; From 3de679b08491405493176bdf5e641429f3d7b69f Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 27 Apr 2018 11:14:50 +0100 Subject: [PATCH 098/190] Add comment to HtmlUtils.js Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/HtmlUtils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/HtmlUtils.js b/src/HtmlUtils.js index 17566957c7..7f241310e6 100644 --- a/src/HtmlUtils.js +++ b/src/HtmlUtils.js @@ -186,7 +186,7 @@ const sanitizeHtmlParams = { ], allowedAttributes: { // custom ones first: - blockquote: ['data-mx-reply'], // for reply fallback + blockquote: ['data-mx-reply'], // used to allow explicit removal of a reply fallback blockquote, value ignored font: ['color', 'data-mx-bg-color', 'data-mx-color', 'style'], // custom to matrix span: ['data-mx-bg-color', 'data-mx-color', 'style'], // custom to matrix a: ['href', 'name', 'target', 'rel'], // remote target: custom to matrix From 82d117974f073dfc3eaff7937fe9aef8c7be65f0 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 27 Apr 2018 11:16:29 +0100 Subject: [PATCH 099/190] Remove unused import Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/structures/RoomView.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 0a6fd7944f..8e24a75d68 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -45,7 +45,6 @@ import { KeyCode, isOnlyCtrlOrCmdKeyEvent } from '../../Keyboard'; import RoomViewStore from '../../stores/RoomViewStore'; import RoomScrollStateStore from '../../stores/RoomScrollStateStore'; import SettingsStore from "../../settings/SettingsStore"; -import Reply from "../views/elements/ReplyThread"; const DEBUG = false; let debuglog = function() {}; From db1401f48444b08780b1709d67c43f03403e72e3 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 27 Apr 2018 11:19:14 +0100 Subject: [PATCH 100/190] Pass false to onFinished from BaseDialog Everywhere else, onFinished takes a boolean indicating whether the dialog was confirmed on cancelled, and had function that were expecting this variable and getting undefined. --- src/components/views/dialogs/BaseDialog.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/components/views/dialogs/BaseDialog.js b/src/components/views/dialogs/BaseDialog.js index 21a2477c37..7959e7cb10 100644 --- a/src/components/views/dialogs/BaseDialog.js +++ b/src/components/views/dialogs/BaseDialog.js @@ -36,6 +36,9 @@ export default React.createClass({ propTypes: { // onFinished callback to call when Escape is pressed + // Take a boolean which is true is the dialog was dismissed + // with a positive / confirm action or false if it was + // cancelled (from BaseDialog, this is always false). onFinished: PropTypes.func.isRequired, // called when a key is pressed @@ -77,12 +80,12 @@ export default React.createClass({ if (e.keyCode === KeyCode.ESCAPE) { e.stopPropagation(); e.preventDefault(); - this.props.onFinished(); + this.props.onFinished(false); } }, _onCancelClick: function(e) { - this.props.onFinished(); + this.props.onFinished(false); }, render: function() { From 0323f8ed0c0db59746b98443d6d07250beab6cef Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 27 Apr 2018 11:25:13 +0100 Subject: [PATCH 101/190] Wrap exception handling around all of loadSession The user might (probably does) have a session even if we haven't actually tried to load it yet, so wrap the whole loadSession code in the error handler we were using for restoring sessions so we gracefully handle exceptions that happen before trying to restore sessions too. Remove the catch in MatrixChat that sent you to the login screen. This is never the right way to handle an error condition: we should only display the login screen if we successfully determined that the user has no session, or they explicitly chose to blow their sessions away. --- src/Lifecycle.js | 120 +++++++++--------- src/components/structures/MatrixChat.js | 8 +- .../dialogs/SessionRestoreErrorDialog.js | 1 + 3 files changed, 67 insertions(+), 62 deletions(-) diff --git a/src/Lifecycle.js b/src/Lifecycle.js index 793b0f956b..6c35c6ed06 100644 --- a/src/Lifecycle.js +++ b/src/Lifecycle.js @@ -1,6 +1,7 @@ /* Copyright 2015, 2016 OpenMarket Ltd Copyright 2017 Vector Creations Ltd +Copyright 2018 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -65,32 +66,33 @@ import sdk from './index'; * failed. */ export function loadSession(opts) { - const fragmentQueryParams = opts.fragmentQueryParams || {}; - let enableGuest = opts.enableGuest || false; - const guestHsUrl = opts.guestHsUrl; - const guestIsUrl = opts.guestIsUrl; - const defaultDeviceDisplayName = opts.defaultDeviceDisplayName; + return new Promise.resolve().then(() => { + const fragmentQueryParams = opts.fragmentQueryParams || {}; + let enableGuest = opts.enableGuest || false; + const guestHsUrl = opts.guestHsUrl; + const guestIsUrl = opts.guestIsUrl; + const defaultDeviceDisplayName = opts.defaultDeviceDisplayName; - if (!guestHsUrl) { - console.warn("Cannot enable guest access: can't determine HS URL to use"); - enableGuest = false; - } + if (!guestHsUrl) { + console.warn("Cannot enable guest access: can't determine HS URL to use"); + enableGuest = false; + } - if (enableGuest && - fragmentQueryParams.guest_user_id && - fragmentQueryParams.guest_access_token - ) { - console.log("Using guest access credentials"); - return _doSetLoggedIn({ - userId: fragmentQueryParams.guest_user_id, - accessToken: fragmentQueryParams.guest_access_token, - homeserverUrl: guestHsUrl, - identityServerUrl: guestIsUrl, - guest: true, - }, true).then(() => true); - } - - return _restoreFromLocalStorage().then((success) => { + if (enableGuest && + fragmentQueryParams.guest_user_id && + fragmentQueryParams.guest_access_token + ) { + console.log("Using guest access credentials"); + return _doSetLoggedIn({ + userId: fragmentQueryParams.guest_user_id, + accessToken: fragmentQueryParams.guest_access_token, + homeserverUrl: guestHsUrl, + identityServerUrl: guestIsUrl, + guest: true, + }, true).then(() => true); + } + return _restoreFromLocalStorage(); + }).then((success) => { if (success) { return true; } @@ -101,6 +103,8 @@ export function loadSession(opts) { // fall back to login screen return false; + }).catch((e) => { + return _handleLoadSessionFailure(e); }); } @@ -196,43 +200,43 @@ function _registerAsGuest(hsUrl, isUrl, defaultDeviceDisplayName) { // SessionStore to avoid bugs where the view becomes out-of-sync with // localStorage (e.g. teamToken, isGuest etc.) function _restoreFromLocalStorage() { - if (!localStorage) { - return Promise.resolve(false); - } - const hsUrl = localStorage.getItem("mx_hs_url"); - const isUrl = localStorage.getItem("mx_is_url") || 'https://matrix.org'; - const accessToken = localStorage.getItem("mx_access_token"); - const userId = localStorage.getItem("mx_user_id"); - const deviceId = localStorage.getItem("mx_device_id"); + return Promise.resolve().then(() => { + if (!localStorage) { + return Promise.resolve(false); + } + const hsUrl = localStorage.getItem("mx_hs_url"); + const isUrl = localStorage.getItem("mx_is_url") || 'https://matrix.org'; + const accessToken = localStorage.getItem("mx_access_token"); + const userId = localStorage.getItem("mx_user_id"); + const deviceId = localStorage.getItem("mx_device_id"); - let isGuest; - if (localStorage.getItem("mx_is_guest") !== null) { - isGuest = localStorage.getItem("mx_is_guest") === "true"; - } else { - // legacy key name - isGuest = localStorage.getItem("matrix-is-guest") === "true"; - } + let isGuest; + if (localStorage.getItem("mx_is_guest") !== null) { + isGuest = localStorage.getItem("mx_is_guest") === "true"; + } else { + // legacy key name + isGuest = localStorage.getItem("matrix-is-guest") === "true"; + } - if (accessToken && userId && hsUrl) { - console.log(`Restoring session for ${userId}`); - return _doSetLoggedIn({ - userId: userId, - deviceId: deviceId, - accessToken: accessToken, - homeserverUrl: hsUrl, - identityServerUrl: isUrl, - guest: isGuest, - }, false).catch((e) => { - return _handleRestoreFailure(e); - }).then(() => true); - } else { - console.log("No previous session found."); - return Promise.resolve(false); - } + if (accessToken && userId && hsUrl) { + console.log(`Restoring session for ${userId}`); + return _doSetLoggedIn({ + userId: userId, + deviceId: deviceId, + accessToken: accessToken, + homeserverUrl: hsUrl, + identityServerUrl: isUrl, + guest: isGuest, + }, false).then(() => true); + } else { + console.log("No previous session found."); + return Promise.resolve(false); + } + }); } -function _handleRestoreFailure(e) { - console.log("Unable to restore session", e); +function _handleLoadSessionFailure(e) { + console.log("Unable to load session", e); const def = Promise.defer(); const SessionRestoreErrorDialog = @@ -253,7 +257,7 @@ function _handleRestoreFailure(e) { } // try, try again - return _restoreFromLocalStorage(); + return loadSession(); }); } diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index 1eb96c9f11..cdeb99ef53 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -1,7 +1,7 @@ /* Copyright 2015, 2016 OpenMarket Ltd Copyright 2017 Vector Creations 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. @@ -351,15 +351,15 @@ export default React.createClass({ guestIsUrl: this.getCurrentIsUrl(), defaultDeviceDisplayName: this.props.defaultDeviceDisplayName, }); - }).catch((e) => { - console.error('Error attempting to load session', e); - return false; }).then((loadedSession) => { if (!loadedSession) { // fall back to showing the login screen dis.dispatch({action: "start_login"}); } }); + // Note we don't catch errors from this: we catch everything within + // loadSession as there's logic there to ask the user if they want + // to try logging out. }).done(); }, diff --git a/src/components/views/dialogs/SessionRestoreErrorDialog.js b/src/components/views/dialogs/SessionRestoreErrorDialog.js index 401550043b..f101381ebf 100644 --- a/src/components/views/dialogs/SessionRestoreErrorDialog.js +++ b/src/components/views/dialogs/SessionRestoreErrorDialog.js @@ -1,5 +1,6 @@ /* Copyright 2017 Vector Creations Ltd +Copyright 2018 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. From 97fecaedc2d53fd1f0c8f542c4130d45e1706f92 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 27 Apr 2018 11:26:42 +0100 Subject: [PATCH 102/190] improve wording Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/context_menus/MessageContextMenu.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/context_menus/MessageContextMenu.js b/src/components/views/context_menus/MessageContextMenu.js index dc6f4d45d0..99ec493ced 100644 --- a/src/components/views/context_menus/MessageContextMenu.js +++ b/src/components/views/context_menus/MessageContextMenu.js @@ -40,7 +40,7 @@ module.exports = React.createClass({ /* an optional EventTileOps implementation that can be used to unhide preview widgets */ eventTileOps: PropTypes.object, - /* an optional function which allows to collapse reply thread */ + /* an optional function to be called when the user clicks collapse thread, if not provided hide button */ collapseReplyThread: PropTypes.func, /* callback called when the menu is dismissed */ From 88f48914b41035bd7c4a8cefa9a9ed2c6d12582a Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 27 Apr 2018 11:28:17 +0100 Subject: [PATCH 103/190] improve comment Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/ReplyThread.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index 57401a03f2..ed284c1da2 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -31,7 +31,7 @@ export default class ReplyThread extends React.Component { static propTypes = { // the latest event in this chain of replies parentEv: PropTypes.instanceOf(MatrixEvent), - // called when the preview's contents has loaded + // called when the ReplyThread contents has changed, including EventTiles thereof onWidgetLoad: PropTypes.func.isRequired, }; From 3ba9f560d44b2c62998f2cc85c1494bf76bfa3ff Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 27 Apr 2018 11:30:47 +0100 Subject: [PATCH 104/190] get MatrixClient from context Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/ReplyThread.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index ed284c1da2..51cb53efea 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -18,9 +18,8 @@ import sdk from '../../../index'; import {_t} from '../../../languageHandler'; import PropTypes from 'prop-types'; import dis from '../../../dispatcher'; -import MatrixClientPeg from '../../../MatrixClientPeg'; import {wantsDateSeparator} from '../../../DateUtils'; -import {MatrixEvent} from 'matrix-js-sdk'; +import {MatrixEvent, MatrixClient} from 'matrix-js-sdk'; import {makeEventPermalink, makeUserPermalink} from "../../../matrix-to"; import SettingsStore from "../../../settings/SettingsStore"; @@ -35,6 +34,10 @@ export default class ReplyThread extends React.Component { onWidgetLoad: PropTypes.func.isRequired, }; + static contextTypes = { + matrixClient: PropTypes.instanceOf(MatrixClient).isRequired, + }; + constructor(props, context) { super(props, context); @@ -58,7 +61,7 @@ export default class ReplyThread extends React.Component { componentWillMount() { this.unmounted = false; - this.room = MatrixClientPeg.get().getRoom(this.props.parentEv.getRoomId()); + this.room = this.context.matrixClient.getRoom(this.props.parentEv.getRoomId()); this.initialize(); } @@ -121,7 +124,7 @@ export default class ReplyThread extends React.Component { if (event) return event; try { - await MatrixClientPeg.get().getEventTimeline(room.getUnfilteredTimelineSet(), eventId); + await this.context.matrixClient.getEventTimeline(room.getUnfilteredTimelineSet(), eventId); } catch (e) { return null; } @@ -257,7 +260,7 @@ export default class ReplyThread extends React.Component { } else if (this.state.loadedEv) { const ev = this.state.loadedEv; const Pill = sdk.getComponent('elements.Pill'); - const room = MatrixClientPeg.get().getRoom(ev.getRoomId()); + const room = this.context.matrixClient.getRoom(ev.getRoomId()); header =
{ _t('In reply to ', {}, { From fdf63fd440422acb4b8ace3e647e9987930a8212 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 27 Apr 2018 11:31:04 +0100 Subject: [PATCH 105/190] replace concat on comment from review Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/ReplyThread.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index 51cb53efea..1e23dfdc8a 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -132,7 +132,7 @@ export default class ReplyThread extends React.Component { } onQuoteClick() { - const events = [this.state.loadedEv].concat(this.state.events); + const events = [this.state.loadedEv, ...this.state.events]; this.setState({ loadedEv: null, From ca766df598ba5594e8512dd3c56e677119f28a79 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 27 Apr 2018 11:32:04 +0100 Subject: [PATCH 106/190] call onWidgetLoad on componentDidUpdate Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/ReplyThread.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index 1e23dfdc8a..d6d6c9fb44 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -65,6 +65,10 @@ export default class ReplyThread extends React.Component { this.initialize(); } + componentDidUpdate() { + this.props.onWidgetLoad(); + } + componentWillUnmount() { this.unmounted = true; } @@ -105,7 +109,7 @@ export default class ReplyThread extends React.Component { if (!inReplyTo) { this.setState({ loading: false, - }, this.props.onWidgetLoad); + }); return; } @@ -113,9 +117,9 @@ export default class ReplyThread extends React.Component { if (this.unmounted) return; if (loadedEv) { - this.setState({loadedEv}, this.props.onWidgetLoad); + this.setState({loadedEv}); } else { - this.setState({err: true}, this.props.onWidgetLoad); + this.setState({err: true}); } } From 3050553fc2880f585e951542336b77af333e3cdf Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 27 Apr 2018 11:44:14 +0100 Subject: [PATCH 107/190] rename and change getInReplyTo Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/ReplyThread.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index d6d6c9fb44..a7a026508c 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -83,7 +83,7 @@ export default class ReplyThread extends React.Component { async initialize() { const {parentEv} = this.props; - const inReplyTo = ReplyThread.getInReplyTo(parentEv); + const inReplyTo = ReplyThread.getParentEventId(parentEv); if (!inReplyTo) { this.setState({err: true}); return; @@ -104,7 +104,7 @@ export default class ReplyThread extends React.Component { async loadNextEvent() { if (this.unmounted) return; const ev = this.state.events[0]; - const inReplyTo = ReplyThread.getInReplyTo(ev); + const inReplyTo = ReplyThread.getParentEventId(ev); if (!inReplyTo) { this.setState({ @@ -146,13 +146,13 @@ export default class ReplyThread extends React.Component { dis.dispatch({action: 'focus_composer'}); } - static getInReplyTo(ev) { + static getParentEventId(ev) { if (!ev || ev.isRedacted()) return; const mRelatesTo = ev.getWireContent()['m.relates_to']; if (mRelatesTo && mRelatesTo['m.in_reply_to']) { const mInReplyTo = mRelatesTo['m.in_reply_to']; - if (mInReplyTo['event_id']) return mInReplyTo; + if (mInReplyTo && mInReplyTo['event_id']) return mInReplyTo['event_id']; } } @@ -173,7 +173,7 @@ export default class ReplyThread extends React.Component { if (!ev) return null; let {body, formatted_body: html} = ev.getContent(); - if (this.getInReplyTo(ev)) { + if (this.getParentEventId(ev)) { if (body) body = this.stripPlainReply(body); if (html) html = this.stripHTMLReply(html); } @@ -195,7 +195,6 @@ export default class ReplyThread extends React.Component { } break; } - case 'm.image': html = `
In reply to ${mxid}` + `
sent an image.
`; @@ -245,7 +244,7 @@ export default class ReplyThread extends React.Component { } static getThread(parentEv, onWidgetLoad, ref) { - if (!SettingsStore.isFeatureEnabled("feature_rich_quoting") || !ReplyThread.getInReplyTo(parentEv)) { + if (!SettingsStore.isFeatureEnabled("feature_rich_quoting") || !ReplyThread.getParentEventId(parentEv)) { return
; } return ; From 68dd57f56e590c3490444697466b3744fa26a260 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 27 Apr 2018 11:47:18 +0100 Subject: [PATCH 108/190] rename two methods Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/ReplyThread.js | 4 ++-- src/components/views/rooms/EventTile.js | 4 ++-- src/components/views/rooms/MessageComposerInput.js | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index a7a026508c..473d6ef201 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -232,7 +232,7 @@ export default class ReplyThread extends React.Component { return {body, html}; } - static getReplyEvContent(ev) { + static makeReplyMixIn(ev) { if (!ev) return {}; return { 'm.relates_to': { @@ -243,7 +243,7 @@ export default class ReplyThread extends React.Component { }; } - static getThread(parentEv, onWidgetLoad, ref) { + static makeThread(parentEv, onWidgetLoad, ref) { if (!SettingsStore.isFeatureEnabled("feature_rich_quoting") || !ReplyThread.getParentEventId(parentEv)) { return
; } diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index 50c0e29ed4..56ac082f2a 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -666,7 +666,7 @@ module.exports = withMatrixClient(React.createClass({ { this._renderE2EPadlock() } { this.props.tileShape === 'reply_preview' - && ReplyThread.getThread(this.props.mxEvent, this.props.onWidgetLoad, 'replyThread') + && ReplyThread.makeThread(this.props.mxEvent, this.props.onWidgetLoad, 'replyThread') } { this._renderE2EPadlock() } - { ReplyThread.getThread(this.props.mxEvent, this.props.onWidgetLoad, 'replyThread') } + { ReplyThread.makeThread(this.props.mxEvent, this.props.onWidgetLoad, 'replyThread') } Date: Fri, 27 Apr 2018 12:12:01 +0100 Subject: [PATCH 109/190] improve stripPlainReply comment and fix leading NewLine Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/ReplyThread.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index 473d6ef201..b2ea8a90a3 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -158,8 +158,11 @@ export default class ReplyThread extends React.Component { // Part of Replies fallback support static stripPlainReply(body) { + // Removes lines beginning with `> ` until you reach one that doesn't. const lines = body.split('\n'); while (lines.length && lines[0].startsWith('> ')) lines.shift(); + // Reply fallback has a blank line after it, so remove it to prevent leading newline + if (lines[0] === '') lines.shift(); return lines.join('\n'); } From 6d9e07580bab42722e3d0c89bd7e13720845682b Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 27 Apr 2018 12:38:49 +0100 Subject: [PATCH 110/190] UI fixes in SessionRestoreErrorDialog * Make the 'delete my data' button not the default * Make it red * Give it a confirmation dialog * Remove the 'cancel' button: what does it mean to cancel an error? In this case, it tried again and almost certainly got the same error. * Remove the top-right 'x' and don't cancel on esc for the same reason. * Move 'send bug report' to a button rather than a 'click here' link * Add a 'refresh' button which, even if it's no more likely to work, will at least look like it's doing something (it's mostly so if you don't have a bug report endpoint, there's still a button other than the one that deletes all your data). --- res/css/_common.scss | 1 + src/components/views/dialogs/BaseDialog.js | 20 +++++- .../dialogs/SessionRestoreErrorDialog.js | 70 +++++++++++-------- .../views/elements/DialogButtons.js | 18 +++-- src/i18n/strings/en_EN.json | 13 ++-- 5 files changed, 79 insertions(+), 43 deletions(-) diff --git a/res/css/_common.scss b/res/css/_common.scss index e81c228430..c4cda6821e 100644 --- a/res/css/_common.scss +++ b/res/css/_common.scss @@ -250,6 +250,7 @@ textarea { .mx_Dialog button.danger, .mx_Dialog input[type="submit"].danger { background-color: $warning-color; border: solid 1px $warning-color; + color: $accent-fg-color; } .mx_Dialog button:disabled, .mx_Dialog input[type="submit"]:disabled { diff --git a/src/components/views/dialogs/BaseDialog.js b/src/components/views/dialogs/BaseDialog.js index 7959e7cb10..fb116cdffe 100644 --- a/src/components/views/dialogs/BaseDialog.js +++ b/src/components/views/dialogs/BaseDialog.js @@ -1,5 +1,6 @@ /* Copyright 2017 Vector Creations Ltd +Copyright 2018 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -41,6 +42,13 @@ export default React.createClass({ // cancelled (from BaseDialog, this is always false). onFinished: PropTypes.func.isRequired, + // Whether the dialog should have a 'close' button that will + // cause the dialog to be cancelled. This should only be set + // to true if there is nothing the app can sensibly do if the + // dialog is cancelled, eg. "We can't restore your session and + // the app cannot work". + hasCancel: PropTypes.bool, + // called when a key is pressed onKeyDown: PropTypes.func, @@ -59,6 +67,12 @@ export default React.createClass({ contentId: React.PropTypes.string, }, + getDefaultProps: function() { + return { + hasCancel: true, + }; + }, + childContextTypes: { matrixClient: PropTypes.instanceOf(MatrixClient), }, @@ -77,7 +91,7 @@ export default React.createClass({ if (this.props.onKeyDown) { this.props.onKeyDown(e); } - if (e.keyCode === KeyCode.ESCAPE) { + if (this.props.hasCancel && e.keyCode === KeyCode.ESCAPE) { e.stopPropagation(); e.preventDefault(); this.props.onFinished(false); @@ -104,11 +118,11 @@ export default React.createClass({ // AT users can skip its presentation. aria-describedby={this.props.contentId} > - - + : null }
{ this.props.title }
diff --git a/src/components/views/dialogs/SessionRestoreErrorDialog.js b/src/components/views/dialogs/SessionRestoreErrorDialog.js index f101381ebf..2e152df4b0 100644 --- a/src/components/views/dialogs/SessionRestoreErrorDialog.js +++ b/src/components/views/dialogs/SessionRestoreErrorDialog.js @@ -31,63 +31,73 @@ export default React.createClass({ onFinished: PropTypes.func.isRequired, }, - componentDidMount: function() { - if (this.refs.bugreportLink) { - this.refs.bugreportLink.focus(); - } - }, - _sendBugReport: function() { const BugReportDialog = sdk.getComponent("dialogs.BugReportDialog"); Modal.createTrackedDialog('Session Restore Error', 'Send Bug Report Dialog', BugReportDialog, {}); }, - _onContinueClick: function() { - this.props.onFinished(true); + _onClearStorageClick: function() { + const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); + Modal.createTrackedDialog('Session Restore Confirm Logout', '', QuestionDialog, { + title: _t("Sign out"), + description: +
{ _t("Log out and remove encryption keys?") }
, + button: _t("Sign out"), + danger: true, + onFinished: this.props.onFinished, + }); }, - _onCancelClick: function() { - this.props.onFinished(false); + _onRefreshClick: function() { + // Is this likely to help? Probably not, but giving only one button + // that clears your storage seems awful. + window.location.reload(true); }, render: function() { const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); - let bugreport; + let dialogButtons; if (SdkConfig.get().bug_report_endpoint_url) { - bugreport = ( -

- { _t( - "Otherwise, click here to send a bug report.", - {}, - { 'a': (sub) => { sub } }, - ) } -

- ); + dialogButtons = + + + } else { + dialogButtons = + + } - const shouldFocusContinueButton =!(bugreport==true); return (
-

{ _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.") }

+

{ _t("We encountered an error trying to restore your previous session.") }

{ _t("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.") }

- { bugreport } +

{ _t("Clearing your browser's storage may fix the problem, but will sign you " + + "out and cause any encrypted chat history to become unreadable.") }

- + { dialogButtons }
); }, diff --git a/src/components/views/elements/DialogButtons.js b/src/components/views/elements/DialogButtons.js index 537f906a74..73e47cbde2 100644 --- a/src/components/views/elements/DialogButtons.js +++ b/src/components/views/elements/DialogButtons.js @@ -1,5 +1,6 @@ /* Copyright 2017 Aidan Gauland +Copyright 2018 New Vector Ltd. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,8 +15,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; - import React from "react"; import PropTypes from "prop-types"; import { _t } from '../../../languageHandler'; @@ -33,12 +32,21 @@ module.exports = React.createClass({ // onClick handler for the primary button. onPrimaryButtonClick: PropTypes.func.isRequired, + // should there be a cancel button? default: true + hasCancel: PropTypes.bool, + // onClick handler for the cancel button. - onCancel: PropTypes.func.isRequired, + onCancel: PropTypes.func, focus: PropTypes.bool, }, + getDefaultProps: function() { + return { + hasCancel: true, + } + }, + _onCancelClick: function() { this.props.onCancel(); }, @@ -57,9 +65,9 @@ module.exports = React.createClass({ { this.props.primaryButton } { this.props.children } - + : null }
); }, diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 33f18e47a4..3c8dd5b66f 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -103,7 +103,6 @@ "You need to be logged in.": "You need to be logged in.", "You need to be able to invite users to do that.": "You need to be able to invite users to do that.", "Unable to create widget.": "Unable to create widget.", - "Popout widget": "Popout widget", "Missing roomId.": "Missing roomId.", "Failed to send request.": "Failed to send request.", "This room is not recognised.": "This room is not recognised.", @@ -655,6 +654,7 @@ "Delete widget": "Delete widget", "Revoke widget access": "Revoke widget access", "Minimize apps": "Minimize apps", + "Popout widget": "Popout widget", "Picture": "Picture", "Edit": "Edit", "Create new room": "Create new room", @@ -807,11 +807,15 @@ "Ignore request": "Ignore request", "Loading device info...": "Loading device info...", "Encryption key request": "Encryption key request", - "Otherwise, click here to send a bug report.": "Otherwise, click here to send a bug report.", + "Sign out": "Sign out", + "Log out and remove encryption keys?": "Log out and remove encryption keys?", + "Send Logs": "Send Logs", + "Clear Storage and Sign Out": "Clear Storage and Sign Out", + "Refresh": "Refresh", "Unable to restore session": "Unable to restore session", - "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.": "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.", + "We encountered an error trying to restore your previous session.": "We encountered an error trying to restore your previous session.", "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.": "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.", - "Continue anyway": "Continue anyway", + "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.", "Invalid Email Address": "Invalid Email Address", "This doesn't appear to be a valid email address": "This doesn't appear to be a valid email address", "Verification Pending": "Verification Pending", @@ -1015,7 +1019,6 @@ "Status.im theme": "Status.im theme", "Can't load user settings": "Can't load user settings", "Server may be unavailable or overloaded": "Server may be unavailable or overloaded", - "Sign out": "Sign out", "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.": "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.", "Success": "Success", "Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them": "Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them", From bec81d82d2dba1964d4eb11a54271c12995e7491 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 27 Apr 2018 12:57:01 +0100 Subject: [PATCH 111/190] Update version of hoek --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6dd02674be..23ffa68bef 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3719,9 +3719,9 @@ "integrity": "sha1-uKnFSTISqTkvAiK2SclhFJfr+4g=" }, "hoek": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz", - "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ==" + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", + "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==" }, "home-or-tmp": { "version": "2.0.0", From 75ab618c054e8a12ee064c15a493388c8d8eac50 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 27 Apr 2018 14:20:09 +0100 Subject: [PATCH 112/190] Fix variable scopes --- src/Lifecycle.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Lifecycle.js b/src/Lifecycle.js index 6c35c6ed06..7e8107c8b7 100644 --- a/src/Lifecycle.js +++ b/src/Lifecycle.js @@ -66,12 +66,13 @@ import sdk from './index'; * failed. */ export function loadSession(opts) { + let enableGuest = opts.enableGuest || false; + const guestHsUrl = opts.guestHsUrl; + const guestIsUrl = opts.guestIsUrl; + const fragmentQueryParams = opts.fragmentQueryParams || {}; + const defaultDeviceDisplayName = opts.defaultDeviceDisplayName; + return new Promise.resolve().then(() => { - const fragmentQueryParams = opts.fragmentQueryParams || {}; - let enableGuest = opts.enableGuest || false; - const guestHsUrl = opts.guestHsUrl; - const guestIsUrl = opts.guestIsUrl; - const defaultDeviceDisplayName = opts.defaultDeviceDisplayName; if (!guestHsUrl) { console.warn("Cannot enable guest access: can't determine HS URL to use"); From a1c442422438866fda9371c2128c5dcca63fd5ef Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Fri, 27 Apr 2018 14:28:24 +0100 Subject: [PATCH 113/190] Add tests for GroupView --- package.json | 1 + test/components/structures/GroupView-test.js | 378 +++++++++++++++++++ test/test-utils.js | 1 + 3 files changed, 380 insertions(+) create mode 100644 test/components/structures/GroupView-test.js diff --git a/package.json b/package.json index de0179c870..1f979369e3 100644 --- a/package.json +++ b/package.json @@ -125,6 +125,7 @@ "karma-spec-reporter": "^0.0.31", "karma-summary-reporter": "^1.3.3", "karma-webpack": "^1.7.0", + "matrix-mock-request": "^1.2.1", "matrix-react-test-utils": "^0.1.1", "mocha": "^5.0.5", "parallelshell": "^3.0.2", diff --git a/test/components/structures/GroupView-test.js b/test/components/structures/GroupView-test.js new file mode 100644 index 0000000000..2df0599f89 --- /dev/null +++ b/test/components/structures/GroupView-test.js @@ -0,0 +1,378 @@ +/* +Copyright 2018 New Vector Ltd. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import React from 'react'; +import ReactDOM from 'react-dom'; +import ReactTestUtils from 'react-dom/test-utils'; +import expect from 'expect'; +import Promise from 'bluebird'; + +import MockHttpBackend from 'matrix-mock-request'; +import MatrixClientPeg from '../../../src/MatrixClientPeg'; +import sdk from 'matrix-react-sdk'; +import Matrix from 'matrix-js-sdk'; + +import * as TestUtils from 'test-utils'; + +const GroupView = sdk.getComponent('structures.GroupView'); +const WrappedGroupView = TestUtils.wrapInMatrixClientContext(GroupView); + +const Spinner = sdk.getComponent('elements.Spinner'); + +/** + * Call fn before calling componentDidUpdate on a react component instance, inst. + * @param {React.Component} inst an instance of a React component. + * @returns {Promise} promise that resolves when componentDidUpdate is called on + * given component instance. + */ +function waitForUpdate(inst) { + return new Promise((resolve, reject) => { + const cdu = inst.componentDidUpdate; + + inst.componentDidUpdate = (prevProps, prevState, snapshot) => { + resolve(); + + if (cdu) cdu(prevProps, prevState, snapshot); + + inst.componentDidUpdate = cdu; + }; + }); +} + +describe.only('GroupView', function() { + let root; + let rootElement; + let httpBackend; + let summaryResponse; + let summaryResponseWithComplicatedLongDesc; + let summaryResponseWithNoLongDesc; + let summaryResponseWithBadImg; + let groupId; + let groupIdEncoded; + + // Summary response fields + const user = { + is_privileged: true, // can edit the group + is_public: true, // appear as a member to non-members + is_publicised: true, // display flair + }; + const usersSection = { + roles: {}, + total_user_count_estimate: 0, + users: [], + }; + const roomsSection = { + categories: {}, + rooms: [], + total_room_count_estimate: 0, + }; + + beforeEach(function() { + TestUtils.beforeEach(this); + + httpBackend = new MockHttpBackend(); + + Matrix.request(httpBackend.requestFn); + + MatrixClientPeg.get = () => Matrix.createClient({ + baseUrl: 'https://my.home.server', + userId: '@me:here', + accessToken: '123456789', + }); + + summaryResponse = { + profile: { + avatar_url: "mxc://someavatarurl", + is_openly_joinable: true, + is_public: true, + long_description: "This is a LONG description.", + name: "The name of a community", + short_description: "This is a community", + }, + user, + users_section: usersSection, + rooms_section: roomsSection, + }; + summaryResponseWithNoLongDesc = { + profile: { + avatar_url: "mxc://someavatarurl", + is_openly_joinable: true, + is_public: true, + long_description: null, + name: "The name of a community", + short_description: "This is a community", + }, + user, + users_section: usersSection, + rooms_section: roomsSection, + }; + summaryResponseWithComplicatedLongDesc = { + profile: { + avatar_url: "mxc://someavatarurl", + is_openly_joinable: true, + is_public: true, + long_description: ` +

This is a more complicated group page

+

With paragraphs

+
    +
  • And lists!
  • +
  • With list items.
  • +
+

And also images:

`, + name: "The name of a community", + short_description: "This is a community", + }, + user, + users_section: usersSection, + rooms_section: roomsSection, + }; + + summaryResponseWithBadImg = { + profile: { + avatar_url: "mxc://someavatarurl", + is_openly_joinable: true, + is_public: true, + long_description: '

Evil image:

', + name: "The name of a community", + short_description: "This is a community", + }, + user, + users_section: usersSection, + rooms_section: roomsSection, + }; + + groupId = "+" + Math.random().toString(16).slice(2) + ':domain'; + groupIdEncoded = encodeURIComponent(groupId); + + rootElement = document.createElement('div'); + root = ReactDOM.render(, rootElement); + }); + + afterEach(function() { + ReactDOM.unmountComponentAtNode(rootElement); + }); + + it('should show a spinner when first displayed', function() { + ReactTestUtils.findRenderedComponentWithType(root, Spinner); + + // If we don't respond here, the rate limiting done to ensure a maximum of + // 3 concurrent network requests for GroupStore will block subsequent requests + // in other tests. + // + // This is a good case for doing the rate limiting somewhere other than the module + // scope of GroupStore.js + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/summary').respond(200, summaryResponse); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/users').respond(200, { chunk: [] }); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/invited_users').respond(200, { chunk: [] }); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/rooms').respond(200, { chunk: [] }); + + return httpBackend.flush(undefined, undefined, 0); + }); + + it('should indicate failure after failed /summary', function() { + const groupView = ReactTestUtils.findRenderedComponentWithType(root, GroupView); + const prom = waitForUpdate(groupView).then(() => { + ReactTestUtils.findRenderedDOMComponentWithClass(root, 'mx_GroupView_error'); + }); + + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/summary').respond(500, {}); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/users').respond(200, { chunk: [] }); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/invited_users').respond(200, { chunk: [] }); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/rooms').respond(200, { chunk: [] }); + + httpBackend.flush(undefined, undefined, 0); + return prom; + }); + + it('should show a group avatar, name, id and short description after successful /summary', function() { + const groupView = ReactTestUtils.findRenderedComponentWithType(root, GroupView); + const prom = waitForUpdate(groupView).then(() => { + ReactTestUtils.findRenderedDOMComponentWithClass(root, 'mx_GroupView'); + + const avatar = ReactTestUtils.findRenderedComponentWithType(root, sdk.getComponent('avatars.GroupAvatar')); + const img = ReactTestUtils.findRenderedDOMComponentWithTag(avatar, 'img'); + const avatarImgElement = ReactDOM.findDOMNode(img); + expect(avatarImgElement).toExist(); + expect(avatarImgElement.src).toInclude( + 'https://my.home.server/_matrix/media/v1/thumbnail/' + + 'someavatarurl?width=48&height=48&method=crop', + ); + + const name = ReactTestUtils.findRenderedDOMComponentWithClass(root, 'mx_GroupView_header_name'); + const nameElement = ReactDOM.findDOMNode(name); + expect(nameElement).toExist(); + expect(nameElement.innerText).toInclude('The name of a community'); + expect(nameElement.innerText).toInclude(groupId); + + const shortDesc = ReactTestUtils.findRenderedDOMComponentWithClass(root, 'mx_GroupView_header_shortDesc'); + const shortDescElement = ReactDOM.findDOMNode(shortDesc); + expect(shortDescElement).toExist(); + expect(shortDescElement.innerText).toBe('This is a community'); + }); + + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/summary').respond(200, summaryResponse); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/users').respond(200, { chunk: [] }); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/invited_users').respond(200, { chunk: [] }); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/rooms').respond(200, { chunk: [] }); + + httpBackend.flush(undefined, undefined, 0); + return prom; + }); + + it('should show a simple long description after successful /summary', function() { + const groupView = ReactTestUtils.findRenderedComponentWithType(root, GroupView); + const prom = waitForUpdate(groupView).then(() => { + ReactTestUtils.findRenderedDOMComponentWithClass(root, 'mx_GroupView'); + + const longDesc = ReactTestUtils.findRenderedDOMComponentWithClass(root, 'mx_GroupView_groupDesc'); + const longDescElement = ReactDOM.findDOMNode(longDesc); + expect(longDescElement).toExist(); + expect(longDescElement.innerText).toBe('This is a LONG description.'); + expect(longDescElement.innerHTML).toBe('
This is a LONG description.
'); + }); + + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/summary').respond(200, summaryResponse); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/users').respond(200, { chunk: [] }); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/invited_users').respond(200, { chunk: [] }); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/rooms').respond(200, { chunk: [] }); + + httpBackend.flush(undefined, undefined, 0); + return prom; + }); + + it('should show a placeholder if a long description is not set', function() { + const groupView = ReactTestUtils.findRenderedComponentWithType(root, GroupView); + const prom = waitForUpdate(groupView).then(() => { + const placeholder = ReactTestUtils + .findRenderedDOMComponentWithClass(root, 'mx_GroupView_groupDesc_placeholder'); + const placeholderElement = ReactDOM.findDOMNode(placeholder); + expect(placeholderElement).toExist(); + }); + + httpBackend + .when('GET', '/groups/' + groupIdEncoded + '/summary') + .respond(200, summaryResponseWithNoLongDesc); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/users').respond(200, { chunk: [] }); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/invited_users').respond(200, { chunk: [] }); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/rooms').respond(200, { chunk: [] }); + + httpBackend.flush(undefined, undefined, 0); + return prom; + }); + + it('should show a complicated long description after successful /summary', function() { + const groupView = ReactTestUtils.findRenderedComponentWithType(root, GroupView); + const prom = waitForUpdate(groupView).then(() => { + const longDesc = ReactTestUtils.findRenderedDOMComponentWithClass(root, 'mx_GroupView_groupDesc'); + const longDescElement = ReactDOM.findDOMNode(longDesc); + expect(longDescElement).toExist(); + + expect(longDescElement.innerHTML).toInclude('

This is a more complicated group page

'); + expect(longDescElement.innerHTML).toInclude('

With paragraphs

'); + expect(longDescElement.innerHTML).toInclude('
    '); + expect(longDescElement.innerHTML).toInclude('
  • And lists!
  • '); + + const imgSrc = "https://my.home.server/_matrix/media/v1/thumbnail/someimageurl?width=800&height=600"; + expect(longDescElement.innerHTML).toInclude(''); + }); + + httpBackend + .when('GET', '/groups/' + groupIdEncoded + '/summary') + .respond(200, summaryResponseWithComplicatedLongDesc); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/users').respond(200, { chunk: [] }); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/invited_users').respond(200, { chunk: [] }); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/rooms').respond(200, { chunk: [] }); + + httpBackend.flush(undefined, undefined, 0); + return prom; + }); + + it('should disallow images with non-mxc URLs', function() { + const groupView = ReactTestUtils.findRenderedComponentWithType(root, GroupView); + const prom = waitForUpdate(groupView).then(() => { + const longDesc = ReactTestUtils.findRenderedDOMComponentWithClass(root, 'mx_GroupView_groupDesc'); + const longDescElement = ReactDOM.findDOMNode(longDesc); + expect(longDescElement).toExist(); + + // If this fails, the URL could be in an img `src`, which is what we care about but + // there's no harm in keeping this simple and checking the entire HTML string. + expect(longDescElement.innerHTML).toExclude('evilimageurl'); + }); + + httpBackend + .when('GET', '/groups/' + groupIdEncoded + '/summary') + .respond(200, summaryResponseWithBadImg); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/users').respond(200, { chunk: [] }); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/invited_users').respond(200, { chunk: [] }); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/rooms').respond(200, { chunk: [] }); + + httpBackend.flush(undefined, undefined, 0); + return prom; + }); + + it('should show a RoomDetailList after a successful /summary & /rooms (no rooms returned)', function() { + const groupView = ReactTestUtils.findRenderedComponentWithType(root, GroupView); + const prom = waitForUpdate(groupView).then(() => { + const roomDetailList = ReactTestUtils.findRenderedDOMComponentWithClass(root, 'mx_RoomDetailList'); + const roomDetailListElement = ReactDOM.findDOMNode(roomDetailList); + expect(roomDetailListElement).toExist(); + }); + + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/summary').respond(200, summaryResponse); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/users').respond(200, { chunk: [] }); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/invited_users').respond(200, { chunk: [] }); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/rooms').respond(200, { chunk: [] }); + + httpBackend.flush(undefined, undefined, 0); + return prom; + }); + + it('should show a RoomDetailList after a successful /summary & /rooms (with a single room)', function() { + const groupView = ReactTestUtils.findRenderedComponentWithType(root, GroupView); + const prom = waitForUpdate(groupView).then(() => { + const roomDetailList = ReactTestUtils.findRenderedDOMComponentWithClass(root, 'mx_RoomDetailList'); + const roomDetailListElement = ReactDOM.findDOMNode(roomDetailList); + expect(roomDetailListElement).toExist(); + + const roomDetailListRoomName = ReactTestUtils.findRenderedDOMComponentWithClass( + root, + 'mx_RoomDirectory_name', + ); + const roomDetailListRoomNameElement = ReactDOM.findDOMNode(roomDetailListRoomName); + + expect(roomDetailListRoomNameElement).toExist(); + expect(roomDetailListRoomNameElement.innerText).toEqual('Some room name'); + }); + + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/summary').respond(200, summaryResponse); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/users').respond(200, { chunk: [] }); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/invited_users').respond(200, { chunk: [] }); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/rooms').respond(200, { chunk: [{ + avatar_url: "mxc://someroomavatarurl", + canonical_alias: "#somealias:domain", + guest_can_join: true, + is_public: true, + name: "Some room name", + num_joined_members: 123, + room_id: "!someroomid", + topic: "some topic", + world_readable: true, + }] }); + + httpBackend.flush(undefined, undefined, 0); + return prom; + }); +}); diff --git a/test/test-utils.js b/test/test-utils.js index b593761bd4..d2c685b371 100644 --- a/test/test-utils.js +++ b/test/test-utils.js @@ -92,6 +92,7 @@ export function createTestClient() { content: {}, }); }, + mxcUrlToHttp: (mxc) => 'http://this.is.a.url/', setAccountData: sinon.stub(), sendTyping: sinon.stub().returns(Promise.resolve({})), sendTextMessage: () => Promise.resolve({}), From 7915d97ed70cf5cab3f0b83d807db228aa978f10 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Fri, 27 Apr 2018 14:56:48 +0100 Subject: [PATCH 114/190] Also run other tests --- test/components/structures/GroupView-test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/components/structures/GroupView-test.js b/test/components/structures/GroupView-test.js index 2df0599f89..71df26da46 100644 --- a/test/components/structures/GroupView-test.js +++ b/test/components/structures/GroupView-test.js @@ -52,7 +52,7 @@ function waitForUpdate(inst) { }); } -describe.only('GroupView', function() { +describe('GroupView', function() { let root; let rootElement; let httpBackend; From 2cc50d35c680f036f54b3b61dd5f18d19563a9b8 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 27 Apr 2018 15:06:36 +0100 Subject: [PATCH 115/190] Lint --- src/Lifecycle.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Lifecycle.js b/src/Lifecycle.js index 7e8107c8b7..a22a5aeebd 100644 --- a/src/Lifecycle.js +++ b/src/Lifecycle.js @@ -72,8 +72,7 @@ export function loadSession(opts) { const fragmentQueryParams = opts.fragmentQueryParams || {}; const defaultDeviceDisplayName = opts.defaultDeviceDisplayName; - return new Promise.resolve().then(() => { - + return Promise.resolve().then(() => { if (!guestHsUrl) { console.warn("Cannot enable guest access: can't determine HS URL to use"); enableGuest = false; From efd29193b7e32445c65e0bd396e3a6767f28ead8 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 27 Apr 2018 15:19:08 +0100 Subject: [PATCH 116/190] Fix UX issues with bug report dialog * Make it use BaseDialog / DialogButtons (also gives it has a top-right 'x' & escape to cancel works) * Stop misusing the 'danger' CSS class on the buttons. There is nothing dangerous about submitting logs. * Continued campaign against 'Click here' links. Fixes https://github.com/vector-im/riot-web/issues/6622 --- src/components/structures/UserSettings.js | 4 +- .../views/dialogs/BugReportDialog.js | 42 +++++++------------ .../views/elements/DialogButtons.js | 14 +++++-- src/i18n/strings/en_EN.json | 2 +- 4 files changed, 30 insertions(+), 32 deletions(-) diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index 7948f4fb5d..44e2f93d63 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -1,7 +1,7 @@ /* Copyright 2015, 2016 OpenMarket Ltd Copyright 2017 Vector Creations 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. @@ -804,7 +804,7 @@ module.exports = React.createClass({ "other users. They do not contain messages.", ) }

    -
diff --git a/src/components/views/dialogs/BugReportDialog.js b/src/components/views/dialogs/BugReportDialog.js index 2025b6fc81..83cdb1f07f 100644 --- a/src/components/views/dialogs/BugReportDialog.js +++ b/src/components/views/dialogs/BugReportDialog.js @@ -1,5 +1,6 @@ /* Copyright 2017 OpenMarket Ltd +Copyright 2018 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -105,6 +106,8 @@ export default class BugReportDialog extends React.Component { render() { const Loader = sdk.getComponent("elements.Spinner"); + const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); + const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); let error = null; if (this.state.err) { @@ -113,13 +116,6 @@ export default class BugReportDialog extends React.Component {
; } - let cancelButton = null; - if (!this.state.busy) { - cancelButton = ; - } - let progress = null; if (this.state.busy) { progress = ( @@ -131,11 +127,11 @@ export default class BugReportDialog extends React.Component { } return ( -
-
- { _t("Submit debug logs") } -
-
+ +

{ _t( "Debug logs contain application usage data including your " + @@ -146,7 +142,7 @@ export default class BugReportDialog extends React.Component {

{ _t( - "Click here to create a GitHub issue.", + "Riot bugs are tracked on GitHub: create a GitHub issue.", {}, { a: (sub) => -

-
+ +
); } } diff --git a/src/components/views/elements/DialogButtons.js b/src/components/views/elements/DialogButtons.js index 73e47cbde2..c8c90ddc47 100644 --- a/src/components/views/elements/DialogButtons.js +++ b/src/components/views/elements/DialogButtons.js @@ -39,11 +39,14 @@ module.exports = React.createClass({ onCancel: PropTypes.func, focus: PropTypes.bool, + + disabled: PropTypes.bool, }, getDefaultProps: function() { return { hasCancel: true, + disabled: false, } }, @@ -56,18 +59,23 @@ module.exports = React.createClass({ if (this.props.primaryButtonClass) { primaryButtonClassName += " " + this.props.primaryButtonClass; } + let cancelButton; + if (this.props.hasCancel) { + cancelButton = ; + } return (
{ this.props.children } - { this.props.hasCancel ? : null } + { cancelButton }
); }, diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 3c8dd5b66f..daf0ce605d 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -745,7 +745,7 @@ "Failed to send logs: ": "Failed to send logs: ", "Submit debug logs": "Submit debug logs", "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.", - "
Click here to create a GitHub issue.": "Click here to create a GitHub issue.", + "Riot bugs are tracked on GitHub: create a GitHub issue.": "Riot bugs are tracked on GitHub: create a GitHub issue.", "GitHub issue link:": "GitHub issue link:", "Notes:": "Notes:", "Send logs": "Send logs", From 27b18c457e31605b7d86c4e0b82f463ed60005cf Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 27 Apr 2018 15:56:28 +0100 Subject: [PATCH 117/190] Lint --- src/components/views/dialogs/SessionRestoreErrorDialog.js | 4 ++-- src/components/views/elements/DialogButtons.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/views/dialogs/SessionRestoreErrorDialog.js b/src/components/views/dialogs/SessionRestoreErrorDialog.js index 2e152df4b0..779e54cfba 100644 --- a/src/components/views/dialogs/SessionRestoreErrorDialog.js +++ b/src/components/views/dialogs/SessionRestoreErrorDialog.js @@ -68,7 +68,7 @@ export default React.createClass({ - + ; } else { dialogButtons = { _t("Clear Storage and Sign Out") } - + ; } return ( diff --git a/src/components/views/elements/DialogButtons.js b/src/components/views/elements/DialogButtons.js index 73e47cbde2..c99ea10143 100644 --- a/src/components/views/elements/DialogButtons.js +++ b/src/components/views/elements/DialogButtons.js @@ -44,7 +44,7 @@ module.exports = React.createClass({ getDefaultProps: function() { return { hasCancel: true, - } + }; }, _onCancelClick: function() { From fed74646b0eb8b6fa5cc55fff92a613810714e64 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 27 Apr 2018 17:49:53 +0100 Subject: [PATCH 118/190] Rewrite to use async / await --- src/Lifecycle.js | 84 +++++++++++++++++++++++------------------------- 1 file changed, 41 insertions(+), 43 deletions(-) diff --git a/src/Lifecycle.js b/src/Lifecycle.js index a22a5aeebd..7378e982ef 100644 --- a/src/Lifecycle.js +++ b/src/Lifecycle.js @@ -65,14 +65,14 @@ import sdk from './index'; * Resolves to `true` if we ended up starting a session, or `false` if we * failed. */ -export function loadSession(opts) { - let enableGuest = opts.enableGuest || false; - const guestHsUrl = opts.guestHsUrl; - const guestIsUrl = opts.guestIsUrl; - const fragmentQueryParams = opts.fragmentQueryParams || {}; - const defaultDeviceDisplayName = opts.defaultDeviceDisplayName; +export async function loadSession(opts) { + try { + let enableGuest = opts.enableGuest || false; + const guestHsUrl = opts.guestHsUrl; + const guestIsUrl = opts.guestIsUrl; + const fragmentQueryParams = opts.fragmentQueryParams || {}; + const defaultDeviceDisplayName = opts.defaultDeviceDisplayName; - return Promise.resolve().then(() => { if (!guestHsUrl) { console.warn("Cannot enable guest access: can't determine HS URL to use"); enableGuest = false; @@ -91,8 +91,7 @@ export function loadSession(opts) { guest: true, }, true).then(() => true); } - return _restoreFromLocalStorage(); - }).then((success) => { + const success = await _restoreFromLocalStorage(); if (success) { return true; } @@ -103,9 +102,9 @@ export function loadSession(opts) { // fall back to login screen return false; - }).catch((e) => { + } catch (e) { return _handleLoadSessionFailure(e); - }); + } } /** @@ -199,40 +198,39 @@ function _registerAsGuest(hsUrl, isUrl, defaultDeviceDisplayName) { // The plan is to gradually move the localStorage access done here into // SessionStore to avoid bugs where the view becomes out-of-sync with // localStorage (e.g. teamToken, isGuest etc.) -function _restoreFromLocalStorage() { - return Promise.resolve().then(() => { - if (!localStorage) { - return Promise.resolve(false); - } - const hsUrl = localStorage.getItem("mx_hs_url"); - const isUrl = localStorage.getItem("mx_is_url") || 'https://matrix.org'; - const accessToken = localStorage.getItem("mx_access_token"); - const userId = localStorage.getItem("mx_user_id"); - const deviceId = localStorage.getItem("mx_device_id"); +async function _restoreFromLocalStorage() { + if (!localStorage) { + return false; + } + const hsUrl = localStorage.getItem("mx_hs_url"); + const isUrl = localStorage.getItem("mx_is_url") || 'https://matrix.org'; + const accessToken = localStorage.getItem("mx_access_token"); + const userId = localStorage.getItem("mx_user_id"); + const deviceId = localStorage.getItem("mx_device_id"); - let isGuest; - if (localStorage.getItem("mx_is_guest") !== null) { - isGuest = localStorage.getItem("mx_is_guest") === "true"; - } else { - // legacy key name - isGuest = localStorage.getItem("matrix-is-guest") === "true"; - } + let isGuest; + if (localStorage.getItem("mx_is_guest") !== null) { + isGuest = localStorage.getItem("mx_is_guest") === "true"; + } else { + // legacy key name + isGuest = localStorage.getItem("matrix-is-guest") === "true"; + } - if (accessToken && userId && hsUrl) { - console.log(`Restoring session for ${userId}`); - return _doSetLoggedIn({ - userId: userId, - deviceId: deviceId, - accessToken: accessToken, - homeserverUrl: hsUrl, - identityServerUrl: isUrl, - guest: isGuest, - }, false).then(() => true); - } else { - console.log("No previous session found."); - return Promise.resolve(false); - } - }); + if (accessToken && userId && hsUrl) { + console.log(`Restoring session for ${userId}`); + await _doSetLoggedIn({ + userId: userId, + deviceId: deviceId, + accessToken: accessToken, + homeserverUrl: hsUrl, + identityServerUrl: isUrl, + guest: isGuest, + }, false); + return true; + } else { + console.log("No previous session found."); + return false; + } } function _handleLoadSessionFailure(e) { From 0c309c88add295798689fbab993d326bd1549cf0 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 27 Apr 2018 17:52:25 +0100 Subject: [PATCH 119/190] Bluebird has no need for your .done() --- src/components/structures/MatrixChat.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index cdeb99ef53..8df46d2f7c 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -360,7 +360,7 @@ export default React.createClass({ // Note we don't catch errors from this: we catch everything within // loadSession as there's logic there to ask the user if they want // to try logging out. - }).done(); + }); }, componentWillUnmount: function() { From d3c368e19fe97d8e429fcb8cef0762638ff1f89a Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 27 Apr 2018 17:53:11 +0100 Subject: [PATCH 120/190] typo --- 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 7959e7cb10..54623e6510 100644 --- a/src/components/views/dialogs/BaseDialog.js +++ b/src/components/views/dialogs/BaseDialog.js @@ -36,7 +36,7 @@ export default React.createClass({ propTypes: { // onFinished callback to call when Escape is pressed - // Take a boolean which is true is the dialog was dismissed + // Take a boolean which is true if the dialog was dismissed // with a positive / confirm action or false if it was // cancelled (from BaseDialog, this is always false). onFinished: PropTypes.func.isRequired, From 873993a7cae2ceae8a3207bb9cf6cc10dbf78a38 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 27 Apr 2018 17:56:33 +0100 Subject: [PATCH 121/190] Clarify, hopefully --- 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 54623e6510..51d9180885 100644 --- a/src/components/views/dialogs/BaseDialog.js +++ b/src/components/views/dialogs/BaseDialog.js @@ -38,7 +38,7 @@ export default React.createClass({ // onFinished callback to call when Escape is pressed // Take a boolean which is true if the dialog was dismissed // with a positive / confirm action or false if it was - // cancelled (from BaseDialog, this is always false). + // cancelled (BaseDialog itself only calls this with false). onFinished: PropTypes.func.isRequired, // called when a key is pressed From 55566b35a25ffa001369a7759e55ed0bbc5532e0 Mon Sep 17 00:00:00 2001 From: Eric Newport Date: Sat, 28 Apr 2018 12:39:25 -0400 Subject: [PATCH 122/190] convert attribute to class --- res/css/views/rooms/_EventTile.scss | 6 +++--- src/components/views/rooms/EventTile.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/res/css/views/rooms/_EventTile.scss b/res/css/views/rooms/_EventTile.scss index 3aa1622e05..db62930be2 100644 --- a/res/css/views/rooms/_EventTile.scss +++ b/res/css/views/rooms/_EventTile.scss @@ -298,13 +298,13 @@ limitations under the License. cursor: pointer; } -.mx_EventTile_e2eIcon[hidden] { +.mx_EventTile_e2eIcon.hidden { display: none; } /* always override hidden attribute for blocked and warning */ -.mx_EventTile_e2eIcon[hidden][src="img/e2e-blocked.svg"], -.mx_EventTile_e2eIcon[hidden][src="img/e2e-warning.svg"] { +.mx_EventTile_e2eIcon.hidden[src="img/e2e-blocked.svg"], +.mx_EventTile_e2eIcon.hidden[src="img/e2e-warning.svg"] { display: block; } diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index 565c8b5977..0c85b27162 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -745,7 +745,7 @@ function E2ePadlock(props) { if (SettingsStore.getValue("alwaysShowEncryptionIcons")) { return ; } else { - return ; + return ; } } From bbf4d3e39f6d52851ed4ca45f9f70d884566f365 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sun, 29 Apr 2018 00:34:27 +0100 Subject: [PATCH 123/190] add comment Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/structures/RoomView.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 8e24a75d68..b4735ce0a3 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -917,6 +917,7 @@ module.exports = React.createClass({ ContentMessages.sendContentToRoom( file, this.state.room.roomId, MatrixClientPeg.get(), ).done(() => { + // Send message_sent callback, for things like _checkIfAlone because after all a file is still a message. dis.dispatch({ action: 'message_sent', }); From 5bb15b1002d978715e39fe8e7072530830456c13 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sun, 29 Apr 2018 00:48:44 +0100 Subject: [PATCH 124/190] simplify logic Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/ReplyThread.js | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index b2ea8a90a3..0e9c96f908 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -83,13 +83,8 @@ export default class ReplyThread extends React.Component { async initialize() { const {parentEv} = this.props; - const inReplyTo = ReplyThread.getParentEventId(parentEv); - if (!inReplyTo) { - this.setState({err: true}); - return; - } - - const ev = await ReplyThread.getEvent(this.room, inReplyTo['event_id']); + // at time of making this component we checked that props.parentEv has a parentEventId + const ev = await ReplyThread.getEvent(this.room, ReplyThread.getParentEventId(parentEv)); if (this.unmounted) return; if (ev) { @@ -104,16 +99,16 @@ export default class ReplyThread extends React.Component { async loadNextEvent() { if (this.unmounted) return; const ev = this.state.events[0]; - const inReplyTo = ReplyThread.getParentEventId(ev); + const inReplyToEventId = ReplyThread.getParentEventId(ev); - if (!inReplyTo) { + if (!inReplyToEventId) { this.setState({ loading: false, }); return; } - const loadedEv = await ReplyThread.getEvent(this.room, inReplyTo['event_id']); + const loadedEv = await ReplyThread.getEvent(this.room, inReplyToEventId); if (this.unmounted) return; if (loadedEv) { From 407be88c929c5b8e00caf79d7e9caec5f0b5732e Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sun, 29 Apr 2018 00:51:39 +0100 Subject: [PATCH 125/190] add comment Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/ReplyThread.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index 0e9c96f908..4268cb86f6 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -123,6 +123,8 @@ export default class ReplyThread extends React.Component { if (event) return event; try { + // ask the client to fetch the event we want using the context API, only interface to do so is to ask + // for a timeline with that event, but once it is loaded we can use findEventById to look up the ev map await this.context.matrixClient.getEventTimeline(room.getUnfilteredTimelineSet(), eventId); } catch (e) { return null; From c00c52e537d3562ecf39f888358faa650a9c8a96 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sun, 29 Apr 2018 00:53:35 +0100 Subject: [PATCH 126/190] added another comment Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/ReplyThread.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index 4268cb86f6..e40ef4170e 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -127,6 +127,8 @@ export default class ReplyThread extends React.Component { // for a timeline with that event, but once it is loaded we can use findEventById to look up the ev map await this.context.matrixClient.getEventTimeline(room.getUnfilteredTimelineSet(), eventId); } catch (e) { + // if it fails, capture the error and dump it because it'll make findEventById return false, which + // captures a superset of errors. return null; } return room.findEventById(eventId); From 4021fc049c9843cb2301d8bb081acc00d1046610 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sun, 29 Apr 2018 00:54:54 +0100 Subject: [PATCH 127/190] re-arrange method order to group statics before instance methods Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/ReplyThread.js | 70 ++++++++++---------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index e40ef4170e..249cdcfcb0 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -59,28 +59,6 @@ export default class ReplyThread extends React.Component { this.collapse = this.collapse.bind(this); } - componentWillMount() { - this.unmounted = false; - this.room = this.context.matrixClient.getRoom(this.props.parentEv.getRoomId()); - this.initialize(); - } - - componentDidUpdate() { - this.props.onWidgetLoad(); - } - - componentWillUnmount() { - this.unmounted = true; - } - - canCollapse() { - return this.state.events.length > 1; - } - - collapse() { - this.initialize(); - } - async initialize() { const {parentEv} = this.props; // at time of making this component we checked that props.parentEv has a parentEventId @@ -134,17 +112,6 @@ export default class ReplyThread extends React.Component { return room.findEventById(eventId); } - onQuoteClick() { - const events = [this.state.loadedEv, ...this.state.events]; - - this.setState({ - loadedEv: null, - events, - }, this.loadNextEvent); - - dis.dispatch({action: 'focus_composer'}); - } - static getParentEventId(ev) { if (!ev || ev.isRedacted()) return; @@ -189,7 +156,7 @@ export default class ReplyThread extends React.Component { case 'm.text': case 'm.notice': { html = `
In reply to ${mxid}` - + `
${html || body}
`; + + `
${html || body}
`; const lines = body.trim().split('\n'); if (lines.length > 0) { lines[0] = `<${mxid}> ${lines[0]}`; @@ -199,7 +166,7 @@ export default class ReplyThread extends React.Component { } case 'm.image': html = `
In reply to ${mxid}` - + `
sent an image.
`; + + `
sent an image.`; body = `> <${mxid}> sent an image.\n\n`; break; case 'm.video': @@ -252,6 +219,39 @@ export default class ReplyThread extends React.Component { return ; } + componentWillMount() { + this.unmounted = false; + this.room = this.context.matrixClient.getRoom(this.props.parentEv.getRoomId()); + this.initialize(); + } + + componentDidUpdate() { + this.props.onWidgetLoad(); + } + + componentWillUnmount() { + this.unmounted = true; + } + + canCollapse() { + return this.state.events.length > 1; + } + + collapse() { + this.initialize(); + } + + onQuoteClick() { + const events = [this.state.loadedEv, ...this.state.events]; + + this.setState({ + loadedEv: null, + events, + }, this.loadNextEvent); + + dis.dispatch({action: 'focus_composer'}); + } + render() { let header = null; From 9701fd32b7b7cf56a85f53ca3af450e6e81af339 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sun, 29 Apr 2018 03:07:31 +0100 Subject: [PATCH 128/190] switch back to blob urls for rendering e2e attachments Based on @walle303's work at https://github.com/matrix-org/matrix-react-sdk/pull/1820 Deliberately reverts https://github.com/matrix-org/matrix-react-sdk/commit/8f778f54fd10428836c99d08346cf89f038dd0ce Mitigates XSS by whitelisting the mime-types of the attachments so that malicious ones should not be recognised and executed by the browser. --- src/components/views/messages/MAudioBody.js | 4 +- src/components/views/messages/MImageBody.js | 6 +- src/components/views/messages/MVideoBody.js | 6 +- src/utils/DecryptFile.js | 82 ++++++++++++++++----- 4 files changed, 73 insertions(+), 25 deletions(-) diff --git a/src/components/views/messages/MAudioBody.js b/src/components/views/messages/MAudioBody.js index ab53918987..1e9962846c 100644 --- a/src/components/views/messages/MAudioBody.js +++ b/src/components/views/messages/MAudioBody.js @@ -20,7 +20,7 @@ import React from 'react'; import MFileBody from './MFileBody'; import MatrixClientPeg from '../../../MatrixClientPeg'; -import { decryptFile, readBlobAsDataUri } from '../../../utils/DecryptFile'; +import { decryptFile } from '../../../utils/DecryptFile'; import { _t } from '../../../languageHandler'; export default class MAudioBody extends React.Component { @@ -54,7 +54,7 @@ export default class MAudioBody extends React.Component { let decryptedBlob; decryptFile(content.file).then(function(blob) { decryptedBlob = blob; - return readBlobAsDataUri(decryptedBlob); + return URL.createObjectURL(decryptedBlob); }).done((url) => { this.setState({ decryptedUrl: url, diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index d5ce533bda..bb36e9b1ef 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -25,7 +25,7 @@ import ImageUtils from '../../../ImageUtils'; import Modal from '../../../Modal'; import sdk from '../../../index'; import dis from '../../../dispatcher'; -import { decryptFile, readBlobAsDataUri } from '../../../utils/DecryptFile'; +import { decryptFile } from '../../../utils/DecryptFile'; import Promise from 'bluebird'; import { _t } from '../../../languageHandler'; import SettingsStore from "../../../settings/SettingsStore"; @@ -169,14 +169,14 @@ export default class extends React.Component { thumbnailPromise = decryptFile( content.info.thumbnail_file, ).then(function(blob) { - return readBlobAsDataUri(blob); + return URL.createObjectURL(blob); }); } let decryptedBlob; thumbnailPromise.then((thumbnailUrl) => { return decryptFile(content.file).then(function(blob) { decryptedBlob = blob; - return readBlobAsDataUri(blob); + return URL.createObjectURL(blob); }).then((contentUrl) => { this.setState({ decryptedUrl: contentUrl, diff --git a/src/components/views/messages/MVideoBody.js b/src/components/views/messages/MVideoBody.js index 21edbae9a2..345c3f02e2 100644 --- a/src/components/views/messages/MVideoBody.js +++ b/src/components/views/messages/MVideoBody.js @@ -20,7 +20,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import MFileBody from './MFileBody'; import MatrixClientPeg from '../../../MatrixClientPeg'; -import { decryptFile, readBlobAsDataUri } from '../../../utils/DecryptFile'; +import { decryptFile } from '../../../utils/DecryptFile'; import Promise from 'bluebird'; import { _t } from '../../../languageHandler'; import SettingsStore from "../../../settings/SettingsStore"; @@ -94,14 +94,14 @@ module.exports = React.createClass({ thumbnailPromise = decryptFile( content.info.thumbnail_file, ).then(function(blob) { - return readBlobAsDataUri(blob); + return URL.createObjectURL(blob); }); } let decryptedBlob; thumbnailPromise.then((thumbnailUrl) => { return decryptFile(content.file).then(function(blob) { decryptedBlob = blob; - return readBlobAsDataUri(blob); + return URL.createObjectURL(blob); }).then((contentUrl) => { this.setState({ decryptedUrl: contentUrl, diff --git a/src/utils/DecryptFile.js b/src/utils/DecryptFile.js index cb5e407407..f8327832d1 100644 --- a/src/utils/DecryptFile.js +++ b/src/utils/DecryptFile.js @@ -1,5 +1,6 @@ /* Copyright 2016 OpenMarket Ltd +Copyright 2018 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -22,25 +23,62 @@ import 'isomorphic-fetch'; import MatrixClientPeg from '../MatrixClientPeg'; import Promise from 'bluebird'; +// WARNING: We have to be very careful about what mime-types we allow into blobs, +// as for performance reasons these are now rendered via URL.createObjectURL() +// rather than by converting into data: URIs. +// +// This means that the content is rendered using the origin of the script which +// called createObjectURL(), and so if the content contains any scripting then it +// will pose a XSS vulnerability when the browser renders it. This is particularly +// bad if the user right-clicks the URI and pastes it into a new window or tab, +// as the blob will then execute with access to Riot's full JS environment(!) +// +// See https://github.com/matrix-org/matrix-react-sdk/pull/1820#issuecomment-385210647 +// for details. +// +// We mitigate this by only allowing mime-types into blobs which we know don't +// contain any scripting, and instantiate all others as application/octet-stream +// regardless of what mime-type the event claimed. Even if the payload itself +// is some malicious HTML, the fact we instantiate it with a media mimetype or +// application/octet-stream means the browser doesn't try to render it as such. +// +// One interesting edge case is image/svg+xml, which empirically *is* rendered +// correctly if the blob is set to the src attribute of an img tag (for thumbnails) +// *even if the mimetype is application/octet-stream*. However, empirically JS +// in the SVG isn't executed in this scenario, so we seem to be okay. +// +// Tested on Chrome 65 and Firefox 60 +// +// The list below is taken mainly from +// https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats +// N.B. Matrix doesn't currently specify which mimetypes are valid in given +// events, so we pick the ones which HTML5 browsers should be able to display +// +// For the record, mime-types which must NEVER enter this list below include: +// text/html, text/xhtml, image/svg, image/svg+xml, image/pdf, and similar. -/** - * Read blob as a data:// URI. - * @return {Promise} A promise that resolves with the data:// URI. - */ -export function readBlobAsDataUri(file) { - const deferred = Promise.defer(); - const reader = new FileReader(); - reader.onload = function(e) { - deferred.resolve(e.target.result); - }; - reader.onerror = function(e) { - deferred.reject(e); - }; - reader.readAsDataURL(file); - return deferred.promise; +const ALLOWED_BLOB_MIMETYPES = { + 'image/jpeg': true, + 'image/gif': true, + 'image/png': true, + + 'video/mp4': true, + 'video/webm': true, + 'video/ogg': true, + + 'audio/mp4': true, + 'audio/webm': true, + 'audio/aac': true, + 'audio/mpeg': true, + 'audio/ogg': true, + 'audio/wave': true, + 'audio/wav': true, + 'audio/x-wav': true, + 'audio/x-pn-wav': true, + 'audio/flac': true, + 'audio/x-flac': true, } - /** * Decrypt a file attached to a matrix event. * @param file {Object} The json taken from the matrix event. @@ -61,7 +99,17 @@ export function decryptFile(file) { return encrypt.decryptAttachment(responseData, file); }).then(function(dataArray) { // Turn the array into a Blob and give it the correct MIME-type. - const blob = new Blob([dataArray], {type: file.mimetype}); + + // IMPORTANT: we must not allow scriptable mime-types into Blobs otherwise + // they introduce XSS attacks if the Blob URI is viewed directly in the + // browser (e.g. by copying the URI into a new tab or window.) + // See warning at top of file. + const mimetype = file.mimetype ? file.mimetype.split(";")[0].trim() : ''; + if (!ALLOWED_BLOB_MIMETYPES[mimetype]) { + mimetype = 'application/octet-stream'; + } + + const blob = new Blob([dataArray], {type: mimetype}); return blob; }); } From bffd5bb891dfa0a874d28bd24d5ac7ca0ae54eac Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sun, 29 Apr 2018 03:09:17 +0100 Subject: [PATCH 129/190] fix constness --- src/utils/DecryptFile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/DecryptFile.js b/src/utils/DecryptFile.js index f8327832d1..92c2e3644d 100644 --- a/src/utils/DecryptFile.js +++ b/src/utils/DecryptFile.js @@ -104,7 +104,7 @@ export function decryptFile(file) { // they introduce XSS attacks if the Blob URI is viewed directly in the // browser (e.g. by copying the URI into a new tab or window.) // See warning at top of file. - const mimetype = file.mimetype ? file.mimetype.split(";")[0].trim() : ''; + let mimetype = file.mimetype ? file.mimetype.split(";")[0].trim() : ''; if (!ALLOWED_BLOB_MIMETYPES[mimetype]) { mimetype = 'application/octet-stream'; } From 9c5407c21ffa9021ed3b746a278d9da5693a6672 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sun, 29 Apr 2018 03:17:55 +0100 Subject: [PATCH 130/190] revokeObjectURLs --- src/components/views/messages/MAudioBody.js | 6 ++++++ src/components/views/messages/MImageBody.js | 8 ++++++++ src/components/views/messages/MVideoBody.js | 9 +++++++++ 3 files changed, 23 insertions(+) diff --git a/src/components/views/messages/MAudioBody.js b/src/components/views/messages/MAudioBody.js index 1e9962846c..efc6c4a069 100644 --- a/src/components/views/messages/MAudioBody.js +++ b/src/components/views/messages/MAudioBody.js @@ -69,6 +69,12 @@ export default class MAudioBody extends React.Component { } } + componentWillUnmount() { + if (this.state.decryptedUrl) { + URL.revokeObjectURL(this.state.decryptedUrl); + } + } + render() { const content = this.props.mxEvent.getContent(); diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index bb36e9b1ef..c22832467e 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -71,6 +71,7 @@ export default class extends React.Component { this.context.matrixClient.on('sync', this.onClientSync); } + // FIXME: factor this out and aplpy it to MVideoBody and MAudioBody too! onClientSync(syncState, prevState) { if (this.unmounted) return; // Consider the client reconnected if there is no error with syncing. @@ -206,6 +207,13 @@ export default class extends React.Component { dis.unregister(this.dispatcherRef); this.context.matrixClient.removeListener('sync', this.onClientSync); this._afterComponentWillUnmount(); + + if (this.state.decryptedUrl) { + URL.revokeObjectURL(this.state.decryptedUrl); + } + if (this.state.decryptedThumbnailUrl) { + URL.revokeObjectURL(this.state.decryptedThumbnailUrl); + } } // To be overridden by subclasses (e.g. MStickerBody) for further diff --git a/src/components/views/messages/MVideoBody.js b/src/components/views/messages/MVideoBody.js index 345c3f02e2..5365daee03 100644 --- a/src/components/views/messages/MVideoBody.js +++ b/src/components/views/messages/MVideoBody.js @@ -120,6 +120,15 @@ module.exports = React.createClass({ } }, + componentWillUnmount: function() { + if (this.state.decryptedUrl) { + URL.revokeObjectURL(this.state.decryptedUrl); + } + if (this.state.decryptedThumbnailUrl) { + URL.revokeObjectURL(this.state.decryptedThumbnailUrl); + } + }, + render: function() { const content = this.props.mxEvent.getContent(); From c254d043c5f69838be4feab0fc08fe652a691ddc Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sun, 29 Apr 2018 03:58:17 +0100 Subject: [PATCH 131/190] fix ugly img errors and correctly render SVG thumbnails Fixes https://github.com/vector-im/riot-web/issues/6271 Fixes https://github.com/vector-im/riot-web/issues/1341 --- src/components/views/messages/MImageBody.js | 60 ++++++++++----------- 1 file changed, 27 insertions(+), 33 deletions(-) diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index d5ce533bda..7ecbf91365 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -154,7 +154,16 @@ export default class extends React.Component { return this.state.decryptedThumbnailUrl; } return this.state.decryptedUrl; - } else { + } + else if (content.info.mimetype == "image/svg+xml" && content.info.thumbnail_url) { + // special case to return client-generated thumbnails for SVGs, if any, + // given we deliberately don't thumbnail them serverside to prevent + // billion lol attacks and similar + return this.context.matrixClient.mxcUrlToHttp( + content.info.thumbnail_url, 800, 600 + ); + } + else { return this.context.matrixClient.mxcUrlToHttp(content.url, 800, 600); } } @@ -230,6 +239,9 @@ export default class extends React.Component { const maxHeight = 600; // let images take up as much width as they can so long as the height doesn't exceed 600px. // the alternative here would be 600*timelineWidth/800; to scale them down to fit inside a 4:3 bounding box + // FIXME: this will break on clientside generated thumbnails (as per e2e rooms) + // which may well be much smaller than the 800x600 bounding box. + //console.log("trying to fit image into timelineWidth of " + this.refs.body.offsetWidth + " or " + this.refs.body.clientWidth); let thumbHeight = null; if (content.info) { @@ -240,18 +252,22 @@ export default class extends React.Component { } _messageContent(contentUrl, thumbUrl, content) { + const thumbnail = ( + + {content.body} + + ); + return ( - - {content.body} - + { thumbUrl && !this.state.imgError ? thumbnail : '' } - + ); } @@ -286,14 +302,6 @@ export default class extends React.Component { ); } - if (this.state.imgError) { - return ( - - { _t("This image cannot be displayed.") } - - ); - } - const contentUrl = this._getContentUrl(); let thumbUrl; if (this._isGif() && SettingsStore.getValue("autoplayGifsAndVideos")) { @@ -302,20 +310,6 @@ export default class extends React.Component { thumbUrl = this._getThumbUrl(); } - if (thumbUrl) { - return this._messageContent(contentUrl, thumbUrl, content); - } else if (content.body) { - return ( - - { _t("Image '%(Body)s' cannot be displayed.", {Body: content.body}) } - - ); - } else { - return ( - - { _t("This image cannot be displayed.") } - - ); - } + return this._messageContent(contentUrl, thumbUrl, content); } } From 731f1fa7d3a91b90555e9211db692c7bf1c57820 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sun, 29 Apr 2018 04:00:02 +0100 Subject: [PATCH 132/190] clarify another scrolljump bug --- src/components/views/messages/MImageBody.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index 7ecbf91365..034e700793 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -242,6 +242,8 @@ export default class extends React.Component { // FIXME: this will break on clientside generated thumbnails (as per e2e rooms) // which may well be much smaller than the 800x600 bounding box. + // FIXME: It will also break really badly for images with broken or missing thumbnails + //console.log("trying to fit image into timelineWidth of " + this.refs.body.offsetWidth + " or " + this.refs.body.clientWidth); let thumbHeight = null; if (content.info) { From 551d3ebda0e78c4a0d505d1cb12705a8edbad71c Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sun, 29 Apr 2018 04:28:15 +0100 Subject: [PATCH 133/190] correctly fix up thumbnail height onload. fixes https://github.com/vector-im/riot-web/issues/6492, although popping is inevitable in the current implementation as it only fixes up the thumbnail size once the image has loaded. --- src/components/views/messages/MImageBody.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index 034e700793..99135fdf8c 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -50,6 +50,7 @@ export default class extends React.Component { this.onAction = this.onAction.bind(this); this.onImageError = this.onImageError.bind(this); + this.onImageLoad = this.onImageLoad.bind(this); this.onImageEnter = this.onImageEnter.bind(this); this.onImageLeave = this.onImageLeave.bind(this); this.onClientSync = this.onClientSync.bind(this); @@ -137,6 +138,11 @@ export default class extends React.Component { }); } + onImageLoad() { + this.fixupHeight(); + this.props.onWidgetLoad(); + } + _getContentUrl() { const content = this.props.mxEvent.getContent(); if (content.file !== undefined) { @@ -170,7 +176,6 @@ export default class extends React.Component { componentDidMount() { this.dispatcherRef = dis.register(this.onAction); - this.fixupHeight(); const content = this.props.mxEvent.getContent(); if (content.file !== undefined && this.state.decryptedUrl === null) { let thumbnailPromise = Promise.resolve(null); @@ -192,7 +197,6 @@ export default class extends React.Component { decryptedThumbnailUrl: thumbnailUrl, decryptedBlob: decryptedBlob, }); - this.props.onWidgetLoad(); }); }).catch((err) => { console.warn("Unable to decrypt attachment: ", err); @@ -244,7 +248,7 @@ export default class extends React.Component { // FIXME: It will also break really badly for images with broken or missing thumbnails - //console.log("trying to fit image into timelineWidth of " + this.refs.body.offsetWidth + " or " + this.refs.body.clientWidth); + // console.log("trying to fit image into timelineWidth of " + this.refs.body.offsetWidth + " or " + this.refs.body.clientWidth); let thumbHeight = null; if (content.info) { thumbHeight = ImageUtils.thumbHeight(content.info.w, content.info.h, timelineWidth, maxHeight); @@ -259,7 +263,7 @@ export default class extends React.Component { {content.body} From be523b3edc4259fd19a3fcd306af80fb463744ed Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sun, 29 Apr 2018 04:31:30 +0100 Subject: [PATCH 134/190] lint --- src/components/views/messages/MImageBody.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index 99135fdf8c..b02c458642 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -160,16 +160,14 @@ export default class extends React.Component { return this.state.decryptedThumbnailUrl; } return this.state.decryptedUrl; - } - else if (content.info.mimetype == "image/svg+xml" && content.info.thumbnail_url) { + } else if (content.info.mimetype == "image/svg+xml" && content.info.thumbnail_url) { // special case to return client-generated thumbnails for SVGs, if any, // given we deliberately don't thumbnail them serverside to prevent // billion lol attacks and similar return this.context.matrixClient.mxcUrlToHttp( - content.info.thumbnail_url, 800, 600 + content.info.thumbnail_url, 800, 600, ); - } - else { + } else { return this.context.matrixClient.mxcUrlToHttp(content.url, 800, 600); } } From 8538cc1666eaba2d8792ba18b870b554040e6eea Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sun, 29 Apr 2018 04:41:30 +0100 Subject: [PATCH 135/190] fix regressions introduced by https://github.com/vector-im/riot-web/commit/00b7cc512b3a9f0e0a36e4ea7d1f4a6c3011ff66 --- res/css/structures/_FilePanel.scss | 4 ++-- src/components/views/messages/MFileBody.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/res/css/structures/_FilePanel.scss b/res/css/structures/_FilePanel.scss index 58e090645f..87dc0aa756 100644 --- a/res/css/structures/_FilePanel.scss +++ b/res/css/structures/_FilePanel.scss @@ -50,13 +50,13 @@ limitations under the License. margin-right: 0px; } -.mx_FilePanel .mx_EventTile .mx_MImageBody_download { +.mx_FilePanel .mx_EventTile .mx_MFileBody_download { display: flex; font-size: 14px; color: $event-timestamp-color; } -.mx_FilePanel .mx_EventTile .mx_MImageBody_downloadLink { +.mx_FilePanel .mx_EventTile .mx_MFileBody_downloadLink { flex: 1 1 auto; color: $light-fg-color; } diff --git a/src/components/views/messages/MFileBody.js b/src/components/views/messages/MFileBody.js index d9ce61582e..246ea6891f 100644 --- a/src/components/views/messages/MFileBody.js +++ b/src/components/views/messages/MFileBody.js @@ -361,7 +361,7 @@ module.exports = React.createClass({ return (
- + { fileName }
From 45c0c0eddd0744bb337a18a0d50179802b26658a Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sun, 29 Apr 2018 04:50:44 +0100 Subject: [PATCH 136/190] add CSS destroyed by stickerpacks fixing mangling from https://github.com/vector-im/riot-web/commit/9fc7435ea2ef7af161fadf4b3f9abc4a4aadcb73#diff-be2f1d72c9704840ceddf019c825e825 and https://github.com/vector-im/riot-web/commit/38efebb8d3946f321e6814cbd957afd042505538#diff-be2f1d72c9704840ceddf019c825e825 also fixes https://github.com/vector-im/riot-web/issues/6492 --- res/css/views/messages/_MImageBody.scss | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/res/css/views/messages/_MImageBody.scss b/res/css/views/messages/_MImageBody.scss index bf483feda3..1c809f0743 100644 --- a/res/css/views/messages/_MImageBody.scss +++ b/res/css/views/messages/_MImageBody.scss @@ -15,6 +15,10 @@ limitations under the License. */ .mx_MImageBody { - display: block; - margin-right: 34px; + display: block; + margin-right: 34px; } + +.mx_MImageBody_thumbnail { + max-width: 100%; +} \ No newline at end of file From db5fc53853951238dd0b44df833ae9578819f8d4 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sun, 29 Apr 2018 04:53:32 +0100 Subject: [PATCH 137/190] final comment --- src/components/views/messages/MImageBody.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index b02c458642..2372c38f4b 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -246,6 +246,10 @@ export default class extends React.Component { // FIXME: It will also break really badly for images with broken or missing thumbnails + // FIXME: Because we don't know what size of thumbnail the server's actually going to send + // us, we can't even really layout the page nicely for it. Instead we have to assume + // it'll target 800x600 and we'll downsize if needed to make things fit. + // console.log("trying to fit image into timelineWidth of " + this.refs.body.offsetWidth + " or " + this.refs.body.clientWidth); let thumbHeight = null; if (content.info) { From 41af9f7a9610e7c75852b8a4bf47591554895ea8 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sun, 29 Apr 2018 08:23:35 +0100 Subject: [PATCH 138/190] fix changed method name Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/messages/TextualBody.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/views/messages/TextualBody.js b/src/components/views/messages/TextualBody.js index 14e80acec1..a4a4b4ebe8 100644 --- a/src/components/views/messages/TextualBody.js +++ b/src/components/views/messages/TextualBody.js @@ -422,7 +422,8 @@ module.exports = React.createClass({ const mxEvent = this.props.mxEvent; const content = mxEvent.getContent(); - const stripReply = SettingsStore.isFeatureEnabled("feature_rich_quoting") && ReplyThread.getInReplyTo(mxEvent); + const stripReply = SettingsStore.isFeatureEnabled("feature_rich_quoting") && + ReplyThread.getParentEventId(mxEvent); let body = HtmlUtils.bodyToHtml(content, this.props.highlights, { disableBigEmoji: SettingsStore.getValue('TextualBody.disableBigEmoji'), // Part of Replies fallback support From fc136607f107a24351bd44893a370413453dbaea Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 27 Apr 2018 12:38:49 +0100 Subject: [PATCH 139/190] UI fixes in SessionRestoreErrorDialog * Make the 'delete my data' button not the default * Make it red * Give it a confirmation dialog * Remove the 'cancel' button: what does it mean to cancel an error? In this case, it tried again and almost certainly got the same error. * Remove the top-right 'x' and don't cancel on esc for the same reason. * Move 'send bug report' to a button rather than a 'click here' link * Add a 'refresh' button which, even if it's no more likely to work, will at least look like it's doing something (it's mostly so if you don't have a bug report endpoint, there's still a button other than the one that deletes all your data). --- res/css/_common.scss | 1 + src/components/views/dialogs/BaseDialog.js | 20 +++++- .../dialogs/SessionRestoreErrorDialog.js | 70 +++++++++++-------- .../views/elements/DialogButtons.js | 18 +++-- src/i18n/strings/en_EN.json | 13 ++-- 5 files changed, 79 insertions(+), 43 deletions(-) diff --git a/res/css/_common.scss b/res/css/_common.scss index e81c228430..c4cda6821e 100644 --- a/res/css/_common.scss +++ b/res/css/_common.scss @@ -250,6 +250,7 @@ textarea { .mx_Dialog button.danger, .mx_Dialog input[type="submit"].danger { background-color: $warning-color; border: solid 1px $warning-color; + color: $accent-fg-color; } .mx_Dialog button:disabled, .mx_Dialog input[type="submit"]:disabled { diff --git a/src/components/views/dialogs/BaseDialog.js b/src/components/views/dialogs/BaseDialog.js index 51d9180885..2f2d6fe8cb 100644 --- a/src/components/views/dialogs/BaseDialog.js +++ b/src/components/views/dialogs/BaseDialog.js @@ -1,5 +1,6 @@ /* Copyright 2017 Vector Creations Ltd +Copyright 2018 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -41,6 +42,13 @@ export default React.createClass({ // cancelled (BaseDialog itself only calls this with false). onFinished: PropTypes.func.isRequired, + // Whether the dialog should have a 'close' button that will + // cause the dialog to be cancelled. This should only be set + // to true if there is nothing the app can sensibly do if the + // dialog is cancelled, eg. "We can't restore your session and + // the app cannot work". + hasCancel: PropTypes.bool, + // called when a key is pressed onKeyDown: PropTypes.func, @@ -59,6 +67,12 @@ export default React.createClass({ contentId: React.PropTypes.string, }, + getDefaultProps: function() { + return { + hasCancel: true, + }; + }, + childContextTypes: { matrixClient: PropTypes.instanceOf(MatrixClient), }, @@ -77,7 +91,7 @@ export default React.createClass({ if (this.props.onKeyDown) { this.props.onKeyDown(e); } - if (e.keyCode === KeyCode.ESCAPE) { + if (this.props.hasCancel && e.keyCode === KeyCode.ESCAPE) { e.stopPropagation(); e.preventDefault(); this.props.onFinished(false); @@ -104,11 +118,11 @@ export default React.createClass({ // AT users can skip its presentation. aria-describedby={this.props.contentId} > - - + : null }
{ this.props.title }
diff --git a/src/components/views/dialogs/SessionRestoreErrorDialog.js b/src/components/views/dialogs/SessionRestoreErrorDialog.js index f101381ebf..2e152df4b0 100644 --- a/src/components/views/dialogs/SessionRestoreErrorDialog.js +++ b/src/components/views/dialogs/SessionRestoreErrorDialog.js @@ -31,63 +31,73 @@ export default React.createClass({ onFinished: PropTypes.func.isRequired, }, - componentDidMount: function() { - if (this.refs.bugreportLink) { - this.refs.bugreportLink.focus(); - } - }, - _sendBugReport: function() { const BugReportDialog = sdk.getComponent("dialogs.BugReportDialog"); Modal.createTrackedDialog('Session Restore Error', 'Send Bug Report Dialog', BugReportDialog, {}); }, - _onContinueClick: function() { - this.props.onFinished(true); + _onClearStorageClick: function() { + const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); + Modal.createTrackedDialog('Session Restore Confirm Logout', '', QuestionDialog, { + title: _t("Sign out"), + description: +
{ _t("Log out and remove encryption keys?") }
, + button: _t("Sign out"), + danger: true, + onFinished: this.props.onFinished, + }); }, - _onCancelClick: function() { - this.props.onFinished(false); + _onRefreshClick: function() { + // Is this likely to help? Probably not, but giving only one button + // that clears your storage seems awful. + window.location.reload(true); }, render: function() { const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); - let bugreport; + let dialogButtons; if (SdkConfig.get().bug_report_endpoint_url) { - bugreport = ( -

- { _t( - "Otherwise, click here to send a bug report.", - {}, - { 'a': (sub) => { sub } }, - ) } -

- ); + dialogButtons = + + + } else { + dialogButtons = + + } - const shouldFocusContinueButton =!(bugreport==true); return (
-

{ _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.") }

+

{ _t("We encountered an error trying to restore your previous session.") }

{ _t("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.") }

- { bugreport } +

{ _t("Clearing your browser's storage may fix the problem, but will sign you " + + "out and cause any encrypted chat history to become unreadable.") }

- + { dialogButtons }
); }, diff --git a/src/components/views/elements/DialogButtons.js b/src/components/views/elements/DialogButtons.js index 537f906a74..73e47cbde2 100644 --- a/src/components/views/elements/DialogButtons.js +++ b/src/components/views/elements/DialogButtons.js @@ -1,5 +1,6 @@ /* Copyright 2017 Aidan Gauland +Copyright 2018 New Vector Ltd. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,8 +15,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; - import React from "react"; import PropTypes from "prop-types"; import { _t } from '../../../languageHandler'; @@ -33,12 +32,21 @@ module.exports = React.createClass({ // onClick handler for the primary button. onPrimaryButtonClick: PropTypes.func.isRequired, + // should there be a cancel button? default: true + hasCancel: PropTypes.bool, + // onClick handler for the cancel button. - onCancel: PropTypes.func.isRequired, + onCancel: PropTypes.func, focus: PropTypes.bool, }, + getDefaultProps: function() { + return { + hasCancel: true, + } + }, + _onCancelClick: function() { this.props.onCancel(); }, @@ -57,9 +65,9 @@ module.exports = React.createClass({ { this.props.primaryButton } { this.props.children } - + : null }
); }, diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 33f18e47a4..3c8dd5b66f 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -103,7 +103,6 @@ "You need to be logged in.": "You need to be logged in.", "You need to be able to invite users to do that.": "You need to be able to invite users to do that.", "Unable to create widget.": "Unable to create widget.", - "Popout widget": "Popout widget", "Missing roomId.": "Missing roomId.", "Failed to send request.": "Failed to send request.", "This room is not recognised.": "This room is not recognised.", @@ -655,6 +654,7 @@ "Delete widget": "Delete widget", "Revoke widget access": "Revoke widget access", "Minimize apps": "Minimize apps", + "Popout widget": "Popout widget", "Picture": "Picture", "Edit": "Edit", "Create new room": "Create new room", @@ -807,11 +807,15 @@ "Ignore request": "Ignore request", "Loading device info...": "Loading device info...", "Encryption key request": "Encryption key request", - "Otherwise, click here to send a bug report.": "Otherwise, click here to send a bug report.", + "Sign out": "Sign out", + "Log out and remove encryption keys?": "Log out and remove encryption keys?", + "Send Logs": "Send Logs", + "Clear Storage and Sign Out": "Clear Storage and Sign Out", + "Refresh": "Refresh", "Unable to restore session": "Unable to restore session", - "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.": "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.", + "We encountered an error trying to restore your previous session.": "We encountered an error trying to restore your previous session.", "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.": "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.", - "Continue anyway": "Continue anyway", + "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.", "Invalid Email Address": "Invalid Email Address", "This doesn't appear to be a valid email address": "This doesn't appear to be a valid email address", "Verification Pending": "Verification Pending", @@ -1015,7 +1019,6 @@ "Status.im theme": "Status.im theme", "Can't load user settings": "Can't load user settings", "Server may be unavailable or overloaded": "Server may be unavailable or overloaded", - "Sign out": "Sign out", "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.": "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.", "Success": "Success", "Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them": "Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them", From 37cb8abf13008362875f64fd853e5e17d9b83594 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 27 Apr 2018 15:19:08 +0100 Subject: [PATCH 140/190] Fix UX issues with bug report dialog * Make it use BaseDialog / DialogButtons (also gives it has a top-right 'x' & escape to cancel works) * Stop misusing the 'danger' CSS class on the buttons. There is nothing dangerous about submitting logs. * Continued campaign against 'Click here' links. Fixes https://github.com/vector-im/riot-web/issues/6622 --- src/components/structures/UserSettings.js | 4 +- .../views/dialogs/BugReportDialog.js | 42 +++++++------------ .../views/elements/DialogButtons.js | 14 +++++-- src/i18n/strings/en_EN.json | 2 +- 4 files changed, 30 insertions(+), 32 deletions(-) diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index 7948f4fb5d..44e2f93d63 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -1,7 +1,7 @@ /* Copyright 2015, 2016 OpenMarket Ltd Copyright 2017 Vector Creations 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. @@ -804,7 +804,7 @@ module.exports = React.createClass({ "other users. They do not contain messages.", ) }

-
diff --git a/src/components/views/dialogs/BugReportDialog.js b/src/components/views/dialogs/BugReportDialog.js index 2025b6fc81..83cdb1f07f 100644 --- a/src/components/views/dialogs/BugReportDialog.js +++ b/src/components/views/dialogs/BugReportDialog.js @@ -1,5 +1,6 @@ /* Copyright 2017 OpenMarket Ltd +Copyright 2018 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -105,6 +106,8 @@ export default class BugReportDialog extends React.Component { render() { const Loader = sdk.getComponent("elements.Spinner"); + const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); + const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); let error = null; if (this.state.err) { @@ -113,13 +116,6 @@ export default class BugReportDialog extends React.Component { ; } - let cancelButton = null; - if (!this.state.busy) { - cancelButton = ; - } - let progress = null; if (this.state.busy) { progress = ( @@ -131,11 +127,11 @@ export default class BugReportDialog extends React.Component { } return ( -
-
- { _t("Submit debug logs") } -
-
+ +

{ _t( "Debug logs contain application usage data including your " + @@ -146,7 +142,7 @@ export default class BugReportDialog extends React.Component {

{ _t( - "Click here to create a GitHub issue.", + "Riot bugs are tracked on GitHub: create a GitHub issue.", {}, { a: (sub) => -

-
+ +
); } } diff --git a/src/components/views/elements/DialogButtons.js b/src/components/views/elements/DialogButtons.js index 73e47cbde2..c8c90ddc47 100644 --- a/src/components/views/elements/DialogButtons.js +++ b/src/components/views/elements/DialogButtons.js @@ -39,11 +39,14 @@ module.exports = React.createClass({ onCancel: PropTypes.func, focus: PropTypes.bool, + + disabled: PropTypes.bool, }, getDefaultProps: function() { return { hasCancel: true, + disabled: false, } }, @@ -56,18 +59,23 @@ module.exports = React.createClass({ if (this.props.primaryButtonClass) { primaryButtonClassName += " " + this.props.primaryButtonClass; } + let cancelButton; + if (this.props.hasCancel) { + cancelButton = ; + } return (
{ this.props.children } - { this.props.hasCancel ? : null } + { cancelButton }
); }, diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 3c8dd5b66f..daf0ce605d 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -745,7 +745,7 @@ "Failed to send logs: ": "Failed to send logs: ", "Submit debug logs": "Submit debug logs", "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.", - "
Click here to create a GitHub issue.": "Click here to create a GitHub issue.", + "Riot bugs are tracked on GitHub: create a GitHub issue.": "Riot bugs are tracked on GitHub: create a GitHub issue.", "GitHub issue link:": "GitHub issue link:", "Notes:": "Notes:", "Send logs": "Send logs", From a9b6db3f2ecbd2a9f27d3d2b9f033a95bf303709 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 27 Apr 2018 15:56:28 +0100 Subject: [PATCH 141/190] Lint --- src/components/views/dialogs/SessionRestoreErrorDialog.js | 4 ++-- src/components/views/elements/DialogButtons.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/views/dialogs/SessionRestoreErrorDialog.js b/src/components/views/dialogs/SessionRestoreErrorDialog.js index 2e152df4b0..779e54cfba 100644 --- a/src/components/views/dialogs/SessionRestoreErrorDialog.js +++ b/src/components/views/dialogs/SessionRestoreErrorDialog.js @@ -68,7 +68,7 @@ export default React.createClass({ - + ; } else { dialogButtons = { _t("Clear Storage and Sign Out") } - + ; } return ( diff --git a/src/components/views/elements/DialogButtons.js b/src/components/views/elements/DialogButtons.js index c8c90ddc47..267127568d 100644 --- a/src/components/views/elements/DialogButtons.js +++ b/src/components/views/elements/DialogButtons.js @@ -47,7 +47,7 @@ module.exports = React.createClass({ return { hasCancel: true, disabled: false, - } + }; }, _onCancelClick: function() { From 5d46efc3e82a33d02158a7da66fbba5a2f3eb4d0 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 30 Apr 2018 14:17:21 +0100 Subject: [PATCH 142/190] Get docs right on hasCancel --- src/components/views/dialogs/BaseDialog.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/views/dialogs/BaseDialog.js b/src/components/views/dialogs/BaseDialog.js index 2f2d6fe8cb..71a5da224c 100644 --- a/src/components/views/dialogs/BaseDialog.js +++ b/src/components/views/dialogs/BaseDialog.js @@ -44,9 +44,9 @@ export default React.createClass({ // Whether the dialog should have a 'close' button that will // cause the dialog to be cancelled. This should only be set - // to true if there is nothing the app can sensibly do if the + // to false if there is nothing the app can sensibly do if the // dialog is cancelled, eg. "We can't restore your session and - // the app cannot work". + // the app cannot work". Default: true. hasCancel: PropTypes.bool, // called when a key is pressed From 54cccab0c78de06eb89cfb23a711d266390af115 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 30 Apr 2018 14:22:18 +0100 Subject: [PATCH 143/190] Factor out clearStorageButton --- .../views/dialogs/SessionRestoreErrorDialog.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/components/views/dialogs/SessionRestoreErrorDialog.js b/src/components/views/dialogs/SessionRestoreErrorDialog.js index 779e54cfba..808c12712f 100644 --- a/src/components/views/dialogs/SessionRestoreErrorDialog.js +++ b/src/components/views/dialogs/SessionRestoreErrorDialog.js @@ -58,6 +58,12 @@ export default React.createClass({ const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); + const clearStorageButton = ( + + ); + let dialogButtons; if (SdkConfig.get().bug_report_endpoint_url) { dialogButtons = - + {clearStorageButton} ; } else { dialogButtons = - + {clearStorageButton} ; } From c3420c37fd5ab748394f6fe55c4a368b586b9a8a Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 30 Apr 2018 14:25:42 +0100 Subject: [PATCH 144/190] Indentation --- .../views/dialogs/SessionRestoreErrorDialog.js | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/components/views/dialogs/SessionRestoreErrorDialog.js b/src/components/views/dialogs/SessionRestoreErrorDialog.js index 808c12712f..bc90788a28 100644 --- a/src/components/views/dialogs/SessionRestoreErrorDialog.js +++ b/src/components/views/dialogs/SessionRestoreErrorDialog.js @@ -92,12 +92,16 @@ export default React.createClass({

{ _t("We encountered an error trying to restore your previous session.") }

-

{ _t("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.") }

+

{ _t( + "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." + ) }

-

{ _t("Clearing your browser's storage may fix the problem, but will sign you " + - "out and cause any encrypted chat history to become unreadable.") }

+

{ _t( + "Clearing your browser's storage may fix the problem, but will sign you " + + "out and cause any encrypted chat history to become unreadable." + ) }

{ dialogButtons } From e28a927da9ce8b8d8eb75d1a830886b56583d8bf Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 30 Apr 2018 14:34:14 +0100 Subject: [PATCH 145/190] lint --- src/components/views/dialogs/SessionRestoreErrorDialog.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/views/dialogs/SessionRestoreErrorDialog.js b/src/components/views/dialogs/SessionRestoreErrorDialog.js index bc90788a28..60430b995e 100644 --- a/src/components/views/dialogs/SessionRestoreErrorDialog.js +++ b/src/components/views/dialogs/SessionRestoreErrorDialog.js @@ -71,7 +71,7 @@ export default React.createClass({ focus={true} hasCancel={false} > - {clearStorageButton} + { clearStorageButton } ; } else { dialogButtons = - {clearStorageButton} + { clearStorageButton } ; } @@ -95,12 +95,12 @@ export default React.createClass({

{ _t( "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." + "to the more recent version.", ) }

{ _t( "Clearing your browser's storage may fix the problem, but will sign you " + - "out and cause any encrypted chat history to become unreadable." + "out and cause any encrypted chat history to become unreadable.", ) }

{ dialogButtons } From e037cf006310609d441d808d8a07be0b3e53a82e Mon Sep 17 00:00:00 2001 From: Eric Newport Date: Mon, 30 Apr 2018 12:22:16 -0400 Subject: [PATCH 146/190] namespace CSS better and fix bug --- res/css/views/rooms/_EventTile.scss | 6 +++--- src/components/views/rooms/EventTile.js | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/res/css/views/rooms/_EventTile.scss b/res/css/views/rooms/_EventTile.scss index db62930be2..788940fe0e 100644 --- a/res/css/views/rooms/_EventTile.scss +++ b/res/css/views/rooms/_EventTile.scss @@ -298,13 +298,13 @@ limitations under the License. cursor: pointer; } -.mx_EventTile_e2eIcon.hidden { +.mx_EventTile_e2eIcon_hidden { display: none; } /* always override hidden attribute for blocked and warning */ -.mx_EventTile_e2eIcon.hidden[src="img/e2e-blocked.svg"], -.mx_EventTile_e2eIcon.hidden[src="img/e2e-warning.svg"] { +.mx_EventTile_e2eIcon_hidden[src="img/e2e-blocked.svg"], +.mx_EventTile_e2eIcon_hidden[src="img/e2e-warning.svg"] { display: block; } diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index 0c85b27162..84acfb160e 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -31,6 +31,7 @@ import withMatrixClient from '../../../wrappers/withMatrixClient'; const ContextualMenu = require('../../structures/ContextualMenu'); import dis from '../../../dispatcher'; import {makeEventPermalink} from "../../../matrix-to"; +import SettingsStore from "../../../settings/SettingsStore"; const ObjectUtils = require('../../../ObjectUtils'); @@ -745,7 +746,7 @@ function E2ePadlock(props) { if (SettingsStore.getValue("alwaysShowEncryptionIcons")) { return ; } else { - return ; + return ; } } From bbce6eea5be3fb228ee105480efe1dfa1421f478 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 30 Apr 2018 23:28:55 +0100 Subject: [PATCH 147/190] update comment Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/ReplyThread.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index 249cdcfcb0..40db914941 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -105,8 +105,8 @@ export default class ReplyThread extends React.Component { // for a timeline with that event, but once it is loaded we can use findEventById to look up the ev map await this.context.matrixClient.getEventTimeline(room.getUnfilteredTimelineSet(), eventId); } catch (e) { - // if it fails, capture the error and dump it because it'll make findEventById return false, which - // captures a superset of errors. + // if it fails catch the error and return early, there's no point trying to find the event in this case. + // Return null as it is falsey and thus should be treated as an error (as the event cannot be resolved). return null; } return room.findEventById(eventId); From 023daef4b784f1891f83aeca5fc8a427af8df658 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 1 May 2018 11:18:45 +0100 Subject: [PATCH 148/190] Refactor GroupStores into one global GroupStore Take a step closer to a flux-like architecture for group data, for the purposes of providing features that require it. Now the app has a single GroupStore that can be poked to fetch updates for a particular group. --- src/GroupAddressPicker.js | 7 +- src/components/structures/GroupView.js | 103 ++++---- src/components/structures/RightPanel.js | 15 +- .../views/dialogs/AddressPickerDialog.js | 5 +- .../views/groups/GroupMemberInfo.js | 26 +- .../views/groups/GroupMemberList.js | 13 +- .../views/groups/GroupPublicityToggle.js | 10 +- src/components/views/groups/GroupRoomInfo.js | 23 +- src/components/views/groups/GroupRoomList.js | 25 +- src/components/views/rooms/RoomList.js | 32 +-- src/stores/GroupStore.js | 223 +++++++++--------- src/stores/GroupStoreCache.js | 38 --- src/utils/MultiInviter.js | 6 +- 13 files changed, 245 insertions(+), 281 deletions(-) delete mode 100644 src/stores/GroupStoreCache.js diff --git a/src/GroupAddressPicker.js b/src/GroupAddressPicker.js index c45a335ab6..91380b6eed 100644 --- a/src/GroupAddressPicker.js +++ b/src/GroupAddressPicker.js @@ -19,7 +19,7 @@ import sdk from './'; import MultiInviter from './utils/MultiInviter'; import { _t } from './languageHandler'; import MatrixClientPeg from './MatrixClientPeg'; -import GroupStoreCache from './stores/GroupStoreCache'; +import GroupStore from './stores/GroupStore'; export function showGroupInviteDialog(groupId) { return new Promise((resolve, reject) => { @@ -116,11 +116,10 @@ function _onGroupInviteFinished(groupId, addrs) { function _onGroupAddRoomFinished(groupId, addrs, addRoomsPublicly) { const matrixClient = MatrixClientPeg.get(); - const groupStore = GroupStoreCache.getGroupStore(groupId); const errorList = []; return Promise.all(addrs.map((addr) => { - return groupStore - .addRoomToGroup(addr.address, addRoomsPublicly) + return GroupStore + .addRoomToGroup(groupId, addr.address, addRoomsPublicly) .catch(() => { errorList.push(addr.address); }) .then(() => { const roomId = addr.address; diff --git a/src/components/structures/GroupView.js b/src/components/structures/GroupView.js index 62fdb1070a..534d8d3df8 100644 --- a/src/components/structures/GroupView.js +++ b/src/components/structures/GroupView.js @@ -27,7 +27,6 @@ import AccessibleButton from '../views/elements/AccessibleButton'; import Modal from '../../Modal'; import classnames from 'classnames'; -import GroupStoreCache from '../../stores/GroupStoreCache'; import GroupStore from '../../stores/GroupStore'; import FlairStore from '../../stores/FlairStore'; import { showGroupAddRoomDialog } from '../../GroupAddressPicker'; @@ -93,8 +92,8 @@ const CategoryRoomList = React.createClass({ if (!success) return; const errorList = []; Promise.all(addrs.map((addr) => { - return this.context.groupStore - .addRoomToGroupSummary(addr.address) + return GroupStore + .addRoomToGroupSummary(this.props.groupId, addr.address) .catch(() => { errorList.push(addr.address); }) .reflect(); })).then(() => { @@ -174,7 +173,8 @@ const FeaturedRoom = React.createClass({ onDeleteClicked: function(e) { e.preventDefault(); e.stopPropagation(); - this.context.groupStore.removeRoomFromGroupSummary( + GroupStore.removeRoomFromGroupSummary( + this.props.groupId, this.props.summaryInfo.room_id, ).catch((err) => { console.error('Error whilst removing room from group summary', err); @@ -269,7 +269,7 @@ const RoleUserList = React.createClass({ if (!success) return; const errorList = []; Promise.all(addrs.map((addr) => { - return this.context.groupStore + return GroupStore .addUserToGroupSummary(addr.address) .catch(() => { errorList.push(addr.address); }) .reflect(); @@ -344,7 +344,8 @@ const FeaturedUser = React.createClass({ onDeleteClicked: function(e) { e.preventDefault(); e.stopPropagation(); - this.context.groupStore.removeUserFromGroupSummary( + GroupStore.removeUserFromGroupSummary( + this.props.groupId, this.props.summaryInfo.user_id, ).catch((err) => { console.error('Error whilst removing user from group summary', err); @@ -390,15 +391,6 @@ const FeaturedUser = React.createClass({ }, }); -const GroupContext = { - groupStore: PropTypes.instanceOf(GroupStore).isRequired, -}; - -CategoryRoomList.contextTypes = GroupContext; -FeaturedRoom.contextTypes = GroupContext; -RoleUserList.contextTypes = GroupContext; -FeaturedUser.contextTypes = GroupContext; - const GROUP_JOINPOLICY_OPEN = "open"; const GROUP_JOINPOLICY_INVITE = "invite"; @@ -415,12 +407,6 @@ export default React.createClass({ groupStore: PropTypes.instanceOf(GroupStore), }, - getChildContext: function() { - return { - groupStore: this._groupStore, - }; - }, - getInitialState: function() { return { summary: null, @@ -440,6 +426,7 @@ export default React.createClass({ }, componentWillMount: function() { + this._unmounted = false; this._matrixClient = MatrixClientPeg.get(); this._matrixClient.on("Group.myMembership", this._onGroupMyMembership); @@ -448,8 +435,8 @@ export default React.createClass({ }, componentWillUnmount: function() { + this._unmounted = true; this._matrixClient.removeListener("Group.myMembership", this._onGroupMyMembership); - this._groupStore.removeAllListeners(); }, componentWillReceiveProps: function(newProps) { @@ -464,8 +451,7 @@ export default React.createClass({ }, _onGroupMyMembership: function(group) { - if (group.groupId !== this.props.groupId) return; - + if (this._unmounted || group.groupId !== this.props.groupId) return; if (group.myMembership === 'leave') { // Leave settings - the user might have clicked the "Leave" button this._closeSettings(); @@ -478,34 +464,11 @@ export default React.createClass({ if (group && group.inviter && group.inviter.userId) { this._fetchInviterProfile(group.inviter.userId); } - this._groupStore = GroupStoreCache.getGroupStore(groupId); - this._groupStore.registerListener(() => { - const summary = this._groupStore.getSummary(); - if (summary.profile) { - // Default profile fields should be "" for later sending to the server (which - // requires that the fields are strings, not null) - ["avatar_url", "long_description", "name", "short_description"].forEach((k) => { - summary.profile[k] = summary.profile[k] || ""; - }); - } - this.setState({ - summary, - summaryLoading: !this._groupStore.isStateReady(GroupStore.STATE_KEY.Summary), - isGroupPublicised: this._groupStore.getGroupPublicity(), - isUserPrivileged: this._groupStore.isUserPrivileged(), - groupRooms: this._groupStore.getGroupRooms(), - groupRoomsLoading: !this._groupStore.isStateReady(GroupStore.STATE_KEY.GroupRooms), - isUserMember: this._groupStore.getGroupMembers().some( - (m) => m.userId === this._matrixClient.credentials.userId, - ), - error: null, - }); - if (this.props.groupIsNew && firstInit) { - this._onEditClick(); - } - }); + GroupStore.registerListener(groupId, this.onGroupStoreUpdated.bind(this, firstInit)); let willDoOnboarding = false; - this._groupStore.on('error', (err) => { + // XXX: This should be more fluxy - let's get the error from GroupStore .getError or something + GroupStore.on('error', (err, errorGroupId) => { + if (this._unmounted || groupId !== errorGroupId) return; if (err.errcode === 'M_GUEST_ACCESS_FORBIDDEN' && !willDoOnboarding) { dis.dispatch({ action: 'do_after_sync_prepared', @@ -524,11 +487,40 @@ export default React.createClass({ }); }, + onGroupStoreUpdated(firstInit) { + if (this._unmounted) return; + const summary = GroupStore.getSummary(this.props.groupId); + if (summary.profile) { + // Default profile fields should be "" for later sending to the server (which + // requires that the fields are strings, not null) + ["avatar_url", "long_description", "name", "short_description"].forEach((k) => { + summary.profile[k] = summary.profile[k] || ""; + }); + } + this.setState({ + summary, + summaryLoading: !GroupStore.isStateReady(this.props.groupId, GroupStore.STATE_KEY.Summary), + isGroupPublicised: GroupStore.getGroupPublicity(this.props.groupId), + isUserPrivileged: GroupStore.isUserPrivileged(this.props.groupId), + groupRooms: GroupStore.getGroupRooms(this.props.groupId), + groupRoomsLoading: !GroupStore.isStateReady(this.props.groupId, GroupStore.STATE_KEY.GroupRooms), + isUserMember: GroupStore.getGroupMembers(this.props.groupId).some( + (m) => m.userId === this._matrixClient.credentials.userId, + ), + error: null, + }); + // XXX: This might not work but this.props.groupIsNew unused anyway + if (this.props.groupIsNew && firstInit) { + this._onEditClick(); + } + }, + _fetchInviterProfile(userId) { this.setState({ inviterProfileBusy: true, }); this._matrixClient.getProfileInfo(userId).then((resp) => { + if (this._unmounted) return; this.setState({ inviterProfile: { avatarUrl: resp.avatar_url, @@ -538,6 +530,7 @@ export default React.createClass({ }).catch((e) => { console.error('Error getting group inviter profile', e); }).finally(() => { + if (this._unmounted) return; this.setState({ inviterProfileBusy: false, }); @@ -677,7 +670,7 @@ export default React.createClass({ // spinner disappearing after we have fetched new group data. await Promise.delay(500); - this._groupStore.acceptGroupInvite().then(() => { + GroupStore.acceptGroupInvite(this.props.groupId).then(() => { // don't reset membershipBusy here: wait for the membership change to come down the sync }).catch((e) => { this.setState({membershipBusy: false}); @@ -696,7 +689,7 @@ export default React.createClass({ // spinner disappearing after we have fetched new group data. await Promise.delay(500); - this._groupStore.leaveGroup().then(() => { + GroupStore.leaveGroup(this.props.groupId).then(() => { // don't reset membershipBusy here: wait for the membership change to come down the sync }).catch((e) => { this.setState({membershipBusy: false}); @@ -715,7 +708,7 @@ export default React.createClass({ // spinner disappearing after we have fetched new group data. await Promise.delay(500); - this._groupStore.joinGroup().then(() => { + GroupStore.joinGroup(this.props.groupId).then(() => { // don't reset membershipBusy here: wait for the membership change to come down the sync }).catch((e) => { this.setState({membershipBusy: false}); @@ -743,7 +736,7 @@ export default React.createClass({ // spinner disappearing after we have fetched new group data. await Promise.delay(500); - this._groupStore.leaveGroup().then(() => { + GroupStore.leaveGroup(this.props.groupId).then(() => { // don't reset membershipBusy here: wait for the membership change to come down the sync }).catch((e) => { this.setState({membershipBusy: false}); diff --git a/src/components/structures/RightPanel.js b/src/components/structures/RightPanel.js index ca1e331d15..18523ceb59 100644 --- a/src/components/structures/RightPanel.js +++ b/src/components/structures/RightPanel.js @@ -27,7 +27,7 @@ import Analytics from '../../Analytics'; import RateLimitedFunc from '../../ratelimitedfunc'; import AccessibleButton from '../../components/views/elements/AccessibleButton'; import { showGroupInviteDialog, showGroupAddRoomDialog } from '../../GroupAddressPicker'; -import GroupStoreCache from '../../stores/GroupStoreCache'; +import GroupStore from '../../stores/GroupStore'; import { formatCount } from '../../utils/FormattingUtils'; @@ -120,7 +120,7 @@ module.exports = React.createClass({ if (this.context.matrixClient) { this.context.matrixClient.removeListener("RoomState.members", this.onRoomStateMember); } - this._unregisterGroupStore(); + this._unregisterGroupStore(this.props.groupId); }, getInitialState: function() { @@ -132,26 +132,23 @@ module.exports = React.createClass({ componentWillReceiveProps(newProps) { if (newProps.groupId !== this.props.groupId) { - this._unregisterGroupStore(); + this._unregisterGroupStore(this.props.groupId); this._initGroupStore(newProps.groupId); } }, _initGroupStore(groupId) { if (!groupId) return; - this._groupStore = GroupStoreCache.getGroupStore(groupId); - this._groupStore.registerListener(this.onGroupStoreUpdated); + GroupStore.registerListener(groupId, this.onGroupStoreUpdated); }, _unregisterGroupStore() { - if (this._groupStore) { - this._groupStore.unregisterListener(this.onGroupStoreUpdated); - } + GroupStore.unregisterListener(this.onGroupStoreUpdated); }, onGroupStoreUpdated: function() { this.setState({ - isUserPrivilegedInGroup: this._groupStore.isUserPrivileged(), + isUserPrivilegedInGroup: GroupStore.isUserPrivileged(this.props.groupId), }); }, diff --git a/src/components/views/dialogs/AddressPickerDialog.js b/src/components/views/dialogs/AddressPickerDialog.js index 685c4fcde3..0d0b7456b5 100644 --- a/src/components/views/dialogs/AddressPickerDialog.js +++ b/src/components/views/dialogs/AddressPickerDialog.js @@ -22,7 +22,7 @@ import sdk from '../../../index'; import MatrixClientPeg from '../../../MatrixClientPeg'; import Promise from 'bluebird'; import { addressTypes, getAddressType } from '../../../UserAddress.js'; -import GroupStoreCache from '../../../stores/GroupStoreCache'; +import GroupStore from '../../../stores/GroupStore'; const TRUNCATE_QUERY_LIST = 40; const QUERY_USER_DIRECTORY_DEBOUNCE_MS = 200; @@ -243,9 +243,8 @@ module.exports = React.createClass({ _doNaiveGroupRoomSearch: function(query) { const lowerCaseQuery = query.toLowerCase(); - const groupStore = GroupStoreCache.getGroupStore(this.props.groupId); const results = []; - groupStore.getGroupRooms().forEach((r) => { + GroupStore.getGroupRooms(this.props.groupId).forEach((r) => { const nameMatch = (r.name || '').toLowerCase().includes(lowerCaseQuery); const topicMatch = (r.topic || '').toLowerCase().includes(lowerCaseQuery); const aliasMatch = (r.canonical_alias || '').toLowerCase().includes(lowerCaseQuery); diff --git a/src/components/views/groups/GroupMemberInfo.js b/src/components/views/groups/GroupMemberInfo.js index 4970a26e5b..4fed293bec 100644 --- a/src/components/views/groups/GroupMemberInfo.js +++ b/src/components/views/groups/GroupMemberInfo.js @@ -23,7 +23,7 @@ import Modal from '../../../Modal'; import sdk from '../../../index'; import { _t } from '../../../languageHandler'; import { GroupMemberType } from '../../../groups'; -import GroupStoreCache from '../../../stores/GroupStoreCache'; +import GroupStore from '../../../stores/GroupStore'; import AccessibleButton from '../elements/AccessibleButton'; module.exports = React.createClass({ @@ -47,33 +47,37 @@ module.exports = React.createClass({ }, componentWillMount: function() { + this._unmounted = false; this._initGroupStore(this.props.groupId); }, componentWillReceiveProps(newProps) { if (newProps.groupId !== this.props.groupId) { - this._unregisterGroupStore(); + this._unregisterGroupStore(this.props.groupId); this._initGroupStore(newProps.groupId); } }, - _initGroupStore(groupId) { - this._groupStore = GroupStoreCache.getGroupStore(this.props.groupId); - this._groupStore.registerListener(this.onGroupStoreUpdated); + componentWillUnmount() { + this._unmounted = true; + this._unregisterGroupStore(this.props.groupId); }, - _unregisterGroupStore() { - if (this._groupStore) { - this._groupStore.unregisterListener(this.onGroupStoreUpdated); - } + _initGroupStore(groupId) { + GroupStore.registerListener(groupId, this.onGroupStoreUpdated); + }, + + _unregisterGroupStore(groupId) { + GroupStore.unregisterListener(this.onGroupStoreUpdated); }, onGroupStoreUpdated: function() { + if (this._unmounted) return; this.setState({ - isUserInvited: this._groupStore.getGroupInvitedMembers().some( + isUserInvited: GroupStore.getGroupInvitedMembers(this.props.groupId).some( (m) => m.userId === this.props.groupMember.userId, ), - isUserPrivilegedInGroup: this._groupStore.isUserPrivileged(), + isUserPrivilegedInGroup: GroupStore.isUserPrivileged(this.props.groupId), }); }, diff --git a/src/components/views/groups/GroupMemberList.js b/src/components/views/groups/GroupMemberList.js index 17a91d83fa..faf172083f 100644 --- a/src/components/views/groups/GroupMemberList.js +++ b/src/components/views/groups/GroupMemberList.js @@ -17,7 +17,7 @@ limitations under the License. import React from 'react'; import { _t } from '../../../languageHandler'; import sdk from '../../../index'; -import GroupStoreCache from '../../../stores/GroupStoreCache'; +import GroupStore from '../../../stores/GroupStore'; import PropTypes from 'prop-types'; const INITIAL_LOAD_NUM_MEMBERS = 30; @@ -42,9 +42,12 @@ export default React.createClass({ this._initGroupStore(this.props.groupId); }, + componentWillUnmount: function() { + this._unmounted = true; + }, + _initGroupStore: function(groupId) { - this._groupStore = GroupStoreCache.getGroupStore(groupId); - this._groupStore.registerListener(() => { + GroupStore.registerListener(groupId, () => { this._fetchMembers(); }); }, @@ -52,8 +55,8 @@ export default React.createClass({ _fetchMembers: function() { if (this._unmounted) return; this.setState({ - members: this._groupStore.getGroupMembers(), - invitedMembers: this._groupStore.getGroupInvitedMembers(), + members: GroupStore.getGroupMembers(this.props.groupId), + invitedMembers: GroupStore.getGroupInvitedMembers(this.props.groupId), }); }, diff --git a/src/components/views/groups/GroupPublicityToggle.js b/src/components/views/groups/GroupPublicityToggle.js index 0fcabb4ef8..0dd35784a0 100644 --- a/src/components/views/groups/GroupPublicityToggle.js +++ b/src/components/views/groups/GroupPublicityToggle.js @@ -17,7 +17,6 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; import sdk from '../../../index'; -import GroupStoreCache from '../../../stores/GroupStoreCache'; import GroupStore from '../../../stores/GroupStore'; import { _t } from '../../../languageHandler.js'; @@ -41,11 +40,10 @@ export default React.createClass({ }, _initGroupStore: function(groupId) { - this._groupStore = GroupStoreCache.getGroupStore(groupId); - this._groupStore.registerListener(() => { + GroupStore.registerListener(groupId, () => { this.setState({ - isGroupPublicised: this._groupStore.getGroupPublicity(), - ready: this._groupStore.isStateReady(GroupStore.STATE_KEY.Summary), + isGroupPublicised: GroupStore.getGroupPublicity(groupId), + ready: GroupStore.isStateReady(groupId, GroupStore.STATE_KEY.Summary), }); }); }, @@ -57,7 +55,7 @@ export default React.createClass({ // Optimistic early update isGroupPublicised: !this.state.isGroupPublicised, }); - this._groupStore.setGroupPublicity(!this.state.isGroupPublicised).then(() => { + GroupStore.setGroupPublicity(this.props.groupId, !this.state.isGroupPublicised).then(() => { this.setState({ busy: false, }); diff --git a/src/components/views/groups/GroupRoomInfo.js b/src/components/views/groups/GroupRoomInfo.js index 2d2b4e655c..41e5f68736 100644 --- a/src/components/views/groups/GroupRoomInfo.js +++ b/src/components/views/groups/GroupRoomInfo.js @@ -21,7 +21,7 @@ import dis from '../../../dispatcher'; import Modal from '../../../Modal'; import sdk from '../../../index'; import { _t } from '../../../languageHandler'; -import GroupStoreCache from '../../../stores/GroupStoreCache'; +import GroupStore from '../../../stores/GroupStore'; module.exports = React.createClass({ displayName: 'GroupRoomInfo', @@ -50,29 +50,26 @@ module.exports = React.createClass({ componentWillReceiveProps(newProps) { if (newProps.groupId !== this.props.groupId) { - this._unregisterGroupStore(); + this._unregisterGroupStore(this.props.groupId); this._initGroupStore(newProps.groupId); } }, componentWillUnmount() { - this._unregisterGroupStore(); + this._unregisterGroupStore(this.props.groupId); }, _initGroupStore(groupId) { - this._groupStore = GroupStoreCache.getGroupStore(this.props.groupId); - this._groupStore.registerListener(this.onGroupStoreUpdated); + GroupStore.registerListener(groupId, this.onGroupStoreUpdated); }, - _unregisterGroupStore() { - if (this._groupStore) { - this._groupStore.unregisterListener(this.onGroupStoreUpdated); - } + _unregisterGroupStore(groupId) { + GroupStore.unregisterListener(this.onGroupStoreUpdated); }, _updateGroupRoom() { this.setState({ - groupRoom: this._groupStore.getGroupRooms().find( + groupRoom: GroupStore.getGroupRooms(this.props.groupId).find( (r) => r.roomId === this.props.groupRoomId, ), }); @@ -80,7 +77,7 @@ module.exports = React.createClass({ onGroupStoreUpdated: function() { this.setState({ - isUserPrivilegedInGroup: this._groupStore.isUserPrivileged(), + isUserPrivilegedInGroup: GroupStore.isUserPrivileged(this.props.groupId), }); this._updateGroupRoom(); }, @@ -100,7 +97,7 @@ module.exports = React.createClass({ this.setState({groupRoomRemoveLoading: true}); const groupId = this.props.groupId; const roomId = this.props.groupRoomId; - this._groupStore.removeRoomFromGroup(roomId).then(() => { + GroupStore.removeRoomFromGroup(this.props.groupId, roomId).then(() => { dis.dispatch({ action: "view_group_room_list", }); @@ -134,7 +131,7 @@ module.exports = React.createClass({ const groupId = this.props.groupId; const roomId = this.props.groupRoomId; const roomName = this.state.groupRoom.displayname; - this._groupStore.updateGroupRoomVisibility(roomId, isPublic).catch((err) => { + GroupStore.updateGroupRoomVisibility(this.props.groupId, roomId, isPublic).catch((err) => { console.error(`Error whilst changing visibility of ${roomId} in ${groupId} to ${isPublic}`, err); const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); Modal.createTrackedDialog('Failed to remove room from group', '', ErrorDialog, { diff --git a/src/components/views/groups/GroupRoomList.js b/src/components/views/groups/GroupRoomList.js index 0515865c6b..cfd2b806d4 100644 --- a/src/components/views/groups/GroupRoomList.js +++ b/src/components/views/groups/GroupRoomList.js @@ -16,7 +16,7 @@ limitations under the License. import React from 'react'; import { _t } from '../../../languageHandler'; import sdk from '../../../index'; -import GroupStoreCache from '../../../stores/GroupStoreCache'; +import GroupStore from '../../../stores/GroupStore'; import PropTypes from 'prop-types'; const INITIAL_LOAD_NUM_ROOMS = 30; @@ -39,22 +39,31 @@ export default React.createClass({ this._initGroupStore(this.props.groupId); }, + componentWillUnmount() { + this._unmounted = true; + this._unregisterGroupStore(); + }, + + _unregisterGroupStore() { + GroupStore.unregisterListener(this.onGroupStoreUpdated); + }, + _initGroupStore: function(groupId) { - this._groupStore = GroupStoreCache.getGroupStore(groupId); - this._groupStore.registerListener(() => { - this._fetchRooms(); - }); - this._groupStore.on('error', (err) => { + GroupStore.registerListener(groupId, this.onGroupStoreUpdated); + // XXX: This should be more fluxy - let's get the error from GroupStore .getError or something + // XXX: This is also leaked - we should remove it when unmounting + GroupStore.on('error', (err, errorGroupId) => { + if (errorGroupId !== groupId) return; this.setState({ rooms: null, }); }); }, - _fetchRooms: function() { + onGroupStoreUpdated: function() { if (this._unmounted) return; this.setState({ - rooms: this._groupStore.getGroupRooms(), + rooms: GroupStore.getGroupRooms(this.props.groupId), }); }, diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index acf04831e8..5be28ae6fa 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -30,7 +30,7 @@ import DMRoomMap from '../../../utils/DMRoomMap'; const Receipt = require('../../../utils/Receipt'); import TagOrderStore from '../../../stores/TagOrderStore'; import RoomListStore from '../../../stores/RoomListStore'; -import GroupStoreCache from '../../../stores/GroupStoreCache'; +import GroupStore from '../../../stores/GroupStore'; const HIDE_CONFERENCE_CHANS = true; const STANDARD_TAGS_REGEX = /^(m\.(favourite|lowpriority)|im\.vector\.fake\.(invite|recent|direct|archived))$/; @@ -83,8 +83,6 @@ module.exports = React.createClass({ cli.on("Group.myMembership", this._onGroupMyMembership); 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._visibleRoomsForGroup = { @@ -96,17 +94,14 @@ module.exports = React.createClass({ // When the selected tags are changed, initialise a group store if necessary this._tagStoreToken = TagOrderStore.addListener(() => { (TagOrderStore.getOrderedTags() || []).forEach((tag) => { - if (tag[0] !== '+' || this._groupStores[tag]) { + if (tag[0] !== '+') { return; } - this._groupStores[tag] = GroupStoreCache.getGroupStore(tag); - this._groupStoreTokens.push( - this._groupStores[tag].registerListener(() => { - // This group's rooms or members may have updated, update rooms for its tag - this.updateVisibleRoomsForTag(dmRoomMap, tag); - this.updateVisibleRooms(); - }), - ); + this.groupStoreToken = GroupStore.registerListener(tag, () => { + // This group's rooms or members may have updated, update rooms for its tag + this.updateVisibleRoomsForTag(dmRoomMap, tag); + this.updateVisibleRooms(); + }); }); // Filters themselves have changed, refresh the selected tags this.updateVisibleRooms(); @@ -183,10 +178,8 @@ module.exports = React.createClass({ this._roomListStoreToken.remove(); } - if (this._groupStoreTokens.length > 0) { - // NB: GroupStore is not a Flux.Store - this._groupStoreTokens.forEach((token) => token.unregister()); - } + // NB: GroupStore is not a Flux.Store + this._groupStoreToken.unregister(); // cancel any pending calls to the rate_limited_funcs this._delayedRefreshRoomList.cancelPendingCall(); @@ -259,12 +252,11 @@ module.exports = React.createClass({ updateVisibleRoomsForTag: function(dmRoomMap, tag) { if (!this.mounted) return; // For now, only handle group tags - const store = this._groupStores[tag]; - if (!store) return; + if (tag[0] !== '+') return; this._visibleRoomsForGroup[tag] = []; - store.getGroupRooms().forEach((room) => this._visibleRoomsForGroup[tag].push(room.roomId)); - store.getGroupMembers().forEach((member) => { + GroupStore.getGroupRooms(tag).forEach((room) => this._visibleRoomsForGroup[tag].push(room.roomId)); + GroupStore.getGroupMembers(tag).forEach((member) => { if (member.userId === MatrixClientPeg.get().credentials.userId) return; dmRoomMap.getDMRoomsForUserId(member.userId).forEach( (roomId) => this._visibleRoomsForGroup[tag].push(roomId), diff --git a/src/stores/GroupStore.js b/src/stores/GroupStore.js index d4f0b09ff9..23ce5314ec 100644 --- a/src/stores/GroupStore.js +++ b/src/stores/GroupStore.js @@ -70,84 +70,90 @@ function limitConcurrency(fn) { } /** - * Stores the group summary for a room and provides an API to change it and - * other useful group APIs that may have an effect on the group summary. + * Global store for tracking group summary, members, invited members and rooms. */ -export default class GroupStore extends EventEmitter { - - static STATE_KEY = { +class GroupStore extends EventEmitter { + STATE_KEY = { GroupMembers: 'GroupMembers', GroupInvitedMembers: 'GroupInvitedMembers', Summary: 'Summary', GroupRooms: 'GroupRooms', }; - constructor(groupId) { + constructor() { super(); - if (!groupId) { - throw new Error('GroupStore needs a valid groupId to be created'); - } - this.groupId = groupId; this._state = {}; - this._state[GroupStore.STATE_KEY.Summary] = {}; - this._state[GroupStore.STATE_KEY.GroupRooms] = []; - this._state[GroupStore.STATE_KEY.GroupMembers] = []; - this._state[GroupStore.STATE_KEY.GroupInvitedMembers] = []; - this._ready = {}; + this._state[this.STATE_KEY.Summary] = {}; + this._state[this.STATE_KEY.GroupRooms] = {}; + this._state[this.STATE_KEY.GroupMembers] = {}; + this._state[this.STATE_KEY.GroupInvitedMembers] = {}; + + this._ready = {}; + this._ready[this.STATE_KEY.Summary] = {}; + this._ready[this.STATE_KEY.GroupRooms] = {}; + this._ready[this.STATE_KEY.GroupMembers] = {}; + this._ready[this.STATE_KEY.GroupInvitedMembers] = {}; + + this._fetchResourcePromise = { + [this.STATE_KEY.Summary]: {}, + [this.STATE_KEY.GroupRooms]: {}, + [this.STATE_KEY.GroupMembers]: {}, + [this.STATE_KEY.GroupInvitedMembers]: {}, + }; - this._fetchResourcePromise = {}; this._resourceFetcher = { - [GroupStore.STATE_KEY.Summary]: () => { + [this.STATE_KEY.Summary]: (groupId) => { return limitConcurrency( - () => MatrixClientPeg.get().getGroupSummary(this.groupId), + () => MatrixClientPeg.get().getGroupSummary(groupId), ); }, - [GroupStore.STATE_KEY.GroupRooms]: () => { + [this.STATE_KEY.GroupRooms]: (groupId) => { return limitConcurrency( - () => MatrixClientPeg.get().getGroupRooms(this.groupId).then(parseRoomsResponse), + () => MatrixClientPeg.get().getGroupRooms(groupId).then(parseRoomsResponse), ); }, - [GroupStore.STATE_KEY.GroupMembers]: () => { + [this.STATE_KEY.GroupMembers]: (groupId) => { return limitConcurrency( - () => MatrixClientPeg.get().getGroupUsers(this.groupId).then(parseMembersResponse), + () => MatrixClientPeg.get().getGroupUsers(groupId).then(parseMembersResponse), ); }, - [GroupStore.STATE_KEY.GroupInvitedMembers]: () => { + [this.STATE_KEY.GroupInvitedMembers]: (groupId) => { return limitConcurrency( - () => MatrixClientPeg.get().getGroupInvitedUsers(this.groupId).then(parseMembersResponse), + () => MatrixClientPeg.get().getGroupInvitedUsers(groupId).then(parseMembersResponse), ); }, }; - this.on('error', (err) => { - console.error(`GroupStore for ${this.groupId} encountered error`, err); + this.on('error', (err, groupId) => { + console.error(`GroupStore encountered error whilst fetching data for ${groupId}`, err); }); } - _fetchResource(stateKey) { + _fetchResource(stateKey, groupId) { // Ongoing request, ignore - if (this._fetchResourcePromise[stateKey]) return; + if (this._fetchResourcePromise[stateKey][groupId]) return; - const clientPromise = this._resourceFetcher[stateKey](); + const clientPromise = this._resourceFetcher[stateKey](groupId); // Indicate ongoing request - this._fetchResourcePromise[stateKey] = clientPromise; + this._fetchResourcePromise[stateKey][groupId] = clientPromise; clientPromise.then((result) => { - this._state[stateKey] = result; - this._ready[stateKey] = true; + this._state[stateKey][groupId] = result; + console.info(this._state); + this._ready[stateKey][groupId] = true; this._notifyListeners(); }).catch((err) => { // Invited users not visible to non-members - if (stateKey === GroupStore.STATE_KEY.GroupInvitedMembers && err.httpStatus === 403) { + if (stateKey === this.STATE_KEY.GroupInvitedMembers && err.httpStatus === 403) { return; } - console.error("Failed to get resource " + stateKey + ":" + err); - this.emit('error', err); + console.error(`Failed to get resource ${stateKey} for ${groupId}`, err); + this.emit('error', err, groupId); }).finally(() => { // Indicate finished request, allow for future fetches - delete this._fetchResourcePromise[stateKey]; + delete this._fetchResourcePromise[stateKey][groupId]; }); return clientPromise; @@ -162,25 +168,26 @@ export default class GroupStore extends EventEmitter { * immediately triggers an update to send the current state of the * store (which could be the initial state). * - * This also causes a fetch of all group data, which might cause - * 4 separate HTTP requests, but only said requests aren't already - * ongoing. + * This also causes a fetch of all data of the specified group, + * which might cause 4 separate HTTP requests, but only if said + * requests aren't already ongoing. * + * @param {string} groupId the ID of the group to fetch data for. * @param {function} fn the function to call when the store updates. * @return {Object} tok a registration "token" with a single * property `unregister`, a function that can * be called to unregister the listener such * that it won't be called any more. */ - registerListener(fn) { + registerListener(groupId, fn) { this.on('update', fn); // Call to set initial state (before fetching starts) this.emit('update'); - this._fetchResource(GroupStore.STATE_KEY.Summary); - this._fetchResource(GroupStore.STATE_KEY.GroupRooms); - this._fetchResource(GroupStore.STATE_KEY.GroupMembers); - this._fetchResource(GroupStore.STATE_KEY.GroupInvitedMembers); + this._fetchResource(this.STATE_KEY.Summary, groupId); + this._fetchResource(this.STATE_KEY.GroupRooms, groupId); + this._fetchResource(this.STATE_KEY.GroupMembers, groupId); + this._fetchResource(this.STATE_KEY.GroupInvitedMembers, groupId); // Similar to the Store of flux/utils, we return a "token" that // can be used to unregister the listener. @@ -195,123 +202,129 @@ export default class GroupStore extends EventEmitter { this.removeListener('update', fn); } - isStateReady(id) { - return this._ready[id]; + isStateReady(groupId, id) { + return this._ready[id][groupId]; } - getSummary() { - return this._state[GroupStore.STATE_KEY.Summary]; + getSummary(groupId) { + return this._state[this.STATE_KEY.Summary][groupId] || {}; } - getGroupRooms() { - return this._state[GroupStore.STATE_KEY.GroupRooms]; + getGroupRooms(groupId) { + return this._state[this.STATE_KEY.GroupRooms][groupId] || []; } - getGroupMembers() { - return this._state[GroupStore.STATE_KEY.GroupMembers]; + getGroupMembers(groupId) { + return this._state[this.STATE_KEY.GroupMembers][groupId] || []; } - getGroupInvitedMembers() { - return this._state[GroupStore.STATE_KEY.GroupInvitedMembers]; + getGroupInvitedMembers(groupId) { + return this._state[this.STATE_KEY.GroupInvitedMembers][groupId] || []; } - getGroupPublicity() { - return this._state[GroupStore.STATE_KEY.Summary].user ? - this._state[GroupStore.STATE_KEY.Summary].user.is_publicised : null; + getGroupPublicity(groupId) { + return (this._state[this.STATE_KEY.Summary][groupId] || {}).user ? + (this._state[this.STATE_KEY.Summary][groupId] || {}).user.is_publicised : null; } - isUserPrivileged() { - return this._state[GroupStore.STATE_KEY.Summary].user ? - this._state[GroupStore.STATE_KEY.Summary].user.is_privileged : null; + isUserPrivileged(groupId) { + return (this._state[this.STATE_KEY.Summary][groupId] || {}).user ? + (this._state[this.STATE_KEY.Summary][groupId] || {}).user.is_privileged : null; } - addRoomToGroup(roomId, isPublic) { + addRoomToGroup(groupId, roomId, isPublic) { return MatrixClientPeg.get() - .addRoomToGroup(this.groupId, roomId, isPublic) - .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.GroupRooms)); + .addRoomToGroup(groupId, roomId, isPublic) + .then(this._fetchResource.bind(this, this.STATE_KEY.GroupRooms, groupId)); } - updateGroupRoomVisibility(roomId, isPublic) { + updateGroupRoomVisibility(groupId, roomId, isPublic) { return MatrixClientPeg.get() - .updateGroupRoomVisibility(this.groupId, roomId, isPublic) - .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.GroupRooms)); + .updateGroupRoomVisibility(groupId, roomId, isPublic) + .then(this._fetchResource.bind(this, this.STATE_KEY.GroupRooms, groupId)); } - removeRoomFromGroup(roomId) { + removeRoomFromGroup(groupId, roomId) { return MatrixClientPeg.get() - .removeRoomFromGroup(this.groupId, roomId) + .removeRoomFromGroup(groupId, roomId) // Room might be in the summary, refresh just in case - .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.Summary)) - .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.GroupRooms)); + .then(this._fetchResource.bind(this, this.STATE_KEY.Summary, groupId)) + .then(this._fetchResource.bind(this, this.STATE_KEY.GroupRooms, groupId)); } - inviteUserToGroup(userId) { - return MatrixClientPeg.get().inviteUserToGroup(this.groupId, userId) - .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.GroupInvitedMembers)); + inviteUserToGroup(groupId, userId) { + return MatrixClientPeg.get().inviteUserToGroup(groupId, userId) + .then(this._fetchResource.bind(this, this.STATE_KEY.GroupInvitedMembers, groupId)); } - acceptGroupInvite() { - return MatrixClientPeg.get().acceptGroupInvite(this.groupId) + acceptGroupInvite(groupId) { + return MatrixClientPeg.get().acceptGroupInvite(groupId) // The user should now be able to access (personal) group settings - .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.Summary)) + .then(this._fetchResource.bind(this, this.STATE_KEY.Summary, groupId)) // The user might be able to see more rooms now - .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.GroupRooms)) + .then(this._fetchResource.bind(this, this.STATE_KEY.GroupRooms, groupId)) // The user should now appear as a member - .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.GroupMembers)) + .then(this._fetchResource.bind(this, this.STATE_KEY.GroupMembers, groupId)) // The user should now not appear as an invited member - .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.GroupInvitedMembers)); + .then(this._fetchResource.bind(this, this.STATE_KEY.GroupInvitedMembers, groupId)); } - joinGroup() { - return MatrixClientPeg.get().joinGroup(this.groupId) + joinGroup(groupId) { + return MatrixClientPeg.get().joinGroup(groupId) // The user should now be able to access (personal) group settings - .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.Summary)) + .then(this._fetchResource.bind(this, this.STATE_KEY.Summary, groupId)) // The user might be able to see more rooms now - .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.GroupRooms)) + .then(this._fetchResource.bind(this, this.STATE_KEY.GroupRooms, groupId)) // The user should now appear as a member - .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.GroupMembers)) + .then(this._fetchResource.bind(this, this.STATE_KEY.GroupMembers, groupId)) // The user should now not appear as an invited member - .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.GroupInvitedMembers)); + .then(this._fetchResource.bind(this, this.STATE_KEY.GroupInvitedMembers, groupId)); } - leaveGroup() { - return MatrixClientPeg.get().leaveGroup(this.groupId) + leaveGroup(groupId) { + return MatrixClientPeg.get().leaveGroup(groupId) // The user should now not be able to access group settings - .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.Summary)) + .then(this._fetchResource.bind(this, this.STATE_KEY.Summary, groupId)) // The user might only be able to see a subset of rooms now - .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.GroupRooms)) + .then(this._fetchResource.bind(this, this.STATE_KEY.GroupRooms, groupId)) // The user should now not appear as a member - .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.GroupMembers)); + .then(this._fetchResource.bind(this, this.STATE_KEY.GroupMembers, groupId)); } - addRoomToGroupSummary(roomId, categoryId) { + addRoomToGroupSummary(groupId, roomId, categoryId) { return MatrixClientPeg.get() - .addRoomToGroupSummary(this.groupId, roomId, categoryId) - .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.Summary)); + .addRoomToGroupSummary(groupId, roomId, categoryId) + .then(this._fetchResource.bind(this, this.STATE_KEY.Summary, groupId)); } - addUserToGroupSummary(userId, roleId) { + addUserToGroupSummary(groupId, userId, roleId) { return MatrixClientPeg.get() - .addUserToGroupSummary(this.groupId, userId, roleId) - .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.Summary)); + .addUserToGroupSummary(groupId, userId, roleId) + .then(this._fetchResource.bind(this, this.STATE_KEY.Summary, groupId)); } - removeRoomFromGroupSummary(roomId) { + removeRoomFromGroupSummary(groupId, roomId) { return MatrixClientPeg.get() - .removeRoomFromGroupSummary(this.groupId, roomId) - .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.Summary)); + .removeRoomFromGroupSummary(groupId, roomId) + .then(this._fetchResource.bind(this, this.STATE_KEY.Summary, groupId)); } - removeUserFromGroupSummary(userId) { + removeUserFromGroupSummary(groupId, userId) { return MatrixClientPeg.get() - .removeUserFromGroupSummary(this.groupId, userId) - .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.Summary)); + .removeUserFromGroupSummary(groupId, userId) + .then(this._fetchResource.bind(this, this.STATE_KEY.Summary, groupId)); } - setGroupPublicity(isPublished) { + setGroupPublicity(groupId, isPublished) { return MatrixClientPeg.get() - .setGroupPublicity(this.groupId, isPublished) + .setGroupPublicity(groupId, isPublished) .then(() => { FlairStore.invalidatePublicisedGroups(MatrixClientPeg.get().credentials.userId); }) - .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.Summary)); + .then(this._fetchResource.bind(this, this.STATE_KEY.Summary, groupId)); } } + +let singletonGroupStore = null; +if (!singletonGroupStore) { + singletonGroupStore = new GroupStore(); +} +module.exports = singletonGroupStore; diff --git a/src/stores/GroupStoreCache.js b/src/stores/GroupStoreCache.js deleted file mode 100644 index 8b4286831b..0000000000 --- a/src/stores/GroupStoreCache.js +++ /dev/null @@ -1,38 +0,0 @@ -/* -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 GroupStore from './GroupStore'; - -class GroupStoreCache { - constructor() { - this.groupStore = null; - } - - getGroupStore(groupId) { - if (!this.groupStore || this.groupStore.groupId !== groupId) { - // This effectively throws away the reference to any previous GroupStore, - // allowing it to be GCd once the components referencing it have stopped - // referencing it. - this.groupStore = new GroupStore(groupId); - } - return this.groupStore; - } -} - -if (global.singletonGroupStoreCache === undefined) { - global.singletonGroupStoreCache = new GroupStoreCache(); -} -export default global.singletonGroupStoreCache; diff --git a/src/utils/MultiInviter.js b/src/utils/MultiInviter.js index a0f33f5c39..b3e7fc495a 100644 --- a/src/utils/MultiInviter.js +++ b/src/utils/MultiInviter.js @@ -18,7 +18,7 @@ limitations under the License. import MatrixClientPeg from '../MatrixClientPeg'; import {getAddressType} from '../UserAddress'; import {inviteToRoom} from '../RoomInvite'; -import GroupStoreCache from '../stores/GroupStoreCache'; +import GroupStore from '../stores/GroupStore'; import Promise from 'bluebird'; /** @@ -118,9 +118,7 @@ export default class MultiInviter { let doInvite; if (this.groupId !== null) { - doInvite = GroupStoreCache - .getGroupStore(this.groupId) - .inviteUserToGroup(addr); + doInvite = GroupStore.inviteUserToGroup(this.groupId, addr); } else { doInvite = inviteToRoom(this.roomId, addr); } From 28e8ce967fe9d403c9697755f293f1e99ca8698c Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 1 May 2018 11:38:57 +0100 Subject: [PATCH 149/190] Correctly unregister group store listener when unmounting RoomList --- src/components/views/rooms/RoomList.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index 5be28ae6fa..b70c4a994e 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -97,7 +97,7 @@ module.exports = React.createClass({ if (tag[0] !== '+') { return; } - this.groupStoreToken = GroupStore.registerListener(tag, () => { + this._groupStoreToken = GroupStore.registerListener(tag, () => { // This group's rooms or members may have updated, update rooms for its tag this.updateVisibleRoomsForTag(dmRoomMap, tag); this.updateVisibleRooms(); @@ -179,7 +179,9 @@ module.exports = React.createClass({ } // NB: GroupStore is not a Flux.Store - this._groupStoreToken.unregister(); + if (this._groupStoreToken) { + this._groupStoreToken.unregister(); + } // cancel any pending calls to the rate_limited_funcs this._delayedRefreshRoomList.cancelPendingCall(); From 38d7a5d39405816ed8cbcee3be67f5286b0fce48 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 1 May 2018 11:50:14 +0100 Subject: [PATCH 150/190] Remove GroupStore listener when unmounting GroupPublicityToggle --- src/components/views/groups/GroupPublicityToggle.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/views/groups/GroupPublicityToggle.js b/src/components/views/groups/GroupPublicityToggle.js index 0dd35784a0..78522c2f55 100644 --- a/src/components/views/groups/GroupPublicityToggle.js +++ b/src/components/views/groups/GroupPublicityToggle.js @@ -40,7 +40,7 @@ export default React.createClass({ }, _initGroupStore: function(groupId) { - GroupStore.registerListener(groupId, () => { + this._groupStoreToken = GroupStore.registerListener(groupId, () => { this.setState({ isGroupPublicised: GroupStore.getGroupPublicity(groupId), ready: GroupStore.isStateReady(groupId, GroupStore.STATE_KEY.Summary), @@ -48,6 +48,10 @@ export default React.createClass({ }); }, + componentWillUnmount() { + if (this._groupStoreToken) this._groupStoreToken.unregister(); + }, + _onPublicityToggle: function(e) { e.stopPropagation(); this.setState({ From 25690336c3abd18eead0feac37055f480129d4eb Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 1 May 2018 11:52:02 +0100 Subject: [PATCH 151/190] Prevent user getting trapped in group settings when an error occurs --- src/components/structures/GroupView.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/structures/GroupView.js b/src/components/structures/GroupView.js index 534d8d3df8..ce79ccadfa 100644 --- a/src/components/structures/GroupView.js +++ b/src/components/structures/GroupView.js @@ -483,6 +483,7 @@ export default React.createClass({ this.setState({ summary: null, error: err, + editing: false, }); }); }, From e3a07be12790ddade32caa990a7fb40fb95a211f Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 1 May 2018 13:14:01 +0100 Subject: [PATCH 152/190] Remove GroupStore logging --- src/stores/GroupStore.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/stores/GroupStore.js b/src/stores/GroupStore.js index 23ce5314ec..49596550ea 100644 --- a/src/stores/GroupStore.js +++ b/src/stores/GroupStore.js @@ -140,7 +140,6 @@ class GroupStore extends EventEmitter { clientPromise.then((result) => { this._state[stateKey][groupId] = result; - console.info(this._state); this._ready[stateKey][groupId] = true; this._notifyListeners(); }).catch((err) => { From f0bd4a54e73ebd2c4a2cdf347263c2431be76c00 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 1 May 2018 13:26:24 +0100 Subject: [PATCH 153/190] Refactor tests to understand sendMessage instead of send{Text,Html}Message Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- .../views/rooms/MessageComposerInput-test.js | 82 +++++++++---------- test/test-utils.js | 3 +- 2 files changed, 41 insertions(+), 44 deletions(-) diff --git a/test/components/views/rooms/MessageComposerInput-test.js b/test/components/views/rooms/MessageComposerInput-test.js index 1f0ede6ae2..eadd923726 100644 --- a/test/components/views/rooms/MessageComposerInput-test.js +++ b/test/components/views/rooms/MessageComposerInput-test.js @@ -75,39 +75,37 @@ describe('MessageComposerInput', () => { }); it('should not send messages when composer is empty', () => { - const textSpy = sinon.spy(client, 'sendTextMessage'); - const htmlSpy = sinon.spy(client, 'sendHtmlMessage'); + const spy = sinon.spy(client, 'sendMessage'); mci.enableRichtext(true); mci.handleReturn(sinon.stub()); - expect(textSpy.calledOnce).toEqual(false, 'should not send text message'); - expect(htmlSpy.calledOnce).toEqual(false, 'should not send html message'); + expect(spy.calledOnce).toEqual(false, 'should not send message'); }); it('should not change content unnecessarily on RTE -> Markdown conversion', () => { - const spy = sinon.spy(client, 'sendTextMessage'); + const spy = sinon.spy(client, 'sendMessage'); mci.enableRichtext(true); addTextToDraft('a'); mci.handleKeyCommand('toggle-mode'); mci.handleReturn(sinon.stub()); expect(spy.calledOnce).toEqual(true); - expect(spy.args[0][1]).toEqual('a'); + expect(spy.args[0][1].body).toEqual('a'); }); it('should not change content unnecessarily on Markdown -> RTE conversion', () => { - const spy = sinon.spy(client, 'sendTextMessage'); + const spy = sinon.spy(client, 'sendMessage'); mci.enableRichtext(false); addTextToDraft('a'); mci.handleKeyCommand('toggle-mode'); mci.handleReturn(sinon.stub()); expect(spy.calledOnce).toEqual(true); - expect(spy.args[0][1]).toEqual('a'); + expect(spy.args[0][1].body).toEqual('a'); }); it('should send emoji messages when rich text is enabled', () => { - const spy = sinon.spy(client, 'sendTextMessage'); + const spy = sinon.spy(client, 'sendMessage'); mci.enableRichtext(true); addTextToDraft('☹'); mci.handleReturn(sinon.stub()); @@ -116,7 +114,7 @@ describe('MessageComposerInput', () => { }); it('should send emoji messages when Markdown is enabled', () => { - const spy = sinon.spy(client, 'sendTextMessage'); + const spy = sinon.spy(client, 'sendMessage'); mci.enableRichtext(false); addTextToDraft('☹'); mci.handleReturn(sinon.stub()); @@ -149,98 +147,98 @@ describe('MessageComposerInput', () => { // }); it('should insert formatting characters in Markdown mode', () => { - const spy = sinon.spy(client, 'sendTextMessage'); + const spy = sinon.spy(client, 'sendMessage'); mci.enableRichtext(false); mci.handleKeyCommand('italic'); mci.handleReturn(sinon.stub()); - expect(['__', '**']).toContain(spy.args[0][1]); + expect(['__', '**']).toContain(spy.args[0][1].body); }); it('should not entity-encode " in Markdown mode', () => { - const spy = sinon.spy(client, 'sendTextMessage'); + const spy = sinon.spy(client, 'sendMessage'); mci.enableRichtext(false); addTextToDraft('"'); mci.handleReturn(sinon.stub()); expect(spy.calledOnce).toEqual(true); - expect(spy.args[0][1]).toEqual('"'); + expect(spy.args[0][1].body).toEqual('"'); }); it('should escape characters without other markup in Markdown mode', () => { - const spy = sinon.spy(client, 'sendTextMessage'); + const spy = sinon.spy(client, 'sendMessage'); mci.enableRichtext(false); addTextToDraft('\\*escaped\\*'); mci.handleReturn(sinon.stub()); expect(spy.calledOnce).toEqual(true); - expect(spy.args[0][1]).toEqual('*escaped*'); + expect(spy.args[0][1].body).toEqual('*escaped*'); }); it('should escape characters with other markup in Markdown mode', () => { - const spy = sinon.spy(client, 'sendHtmlMessage'); + const spy = sinon.spy(client, 'sendMessage'); mci.enableRichtext(false); addTextToDraft('\\*escaped\\* *italic*'); mci.handleReturn(sinon.stub()); expect(spy.calledOnce).toEqual(true); - expect(spy.args[0][1]).toEqual('\\*escaped\\* *italic*'); - expect(spy.args[0][2]).toEqual('*escaped* italic'); + expect(spy.args[0][1].body).toEqual('\\*escaped\\* *italic*'); + expect(spy.args[0][1].formatted_body).toEqual('*escaped* italic'); }); it('should not convert -_- into a horizontal rule in Markdown mode', () => { - const spy = sinon.spy(client, 'sendTextMessage'); + const spy = sinon.spy(client, 'sendMessage'); mci.enableRichtext(false); addTextToDraft('-_-'); mci.handleReturn(sinon.stub()); expect(spy.calledOnce).toEqual(true); - expect(spy.args[0][1]).toEqual('-_-'); + expect(spy.args[0][1].body).toEqual('-_-'); }); it('should not strip tags in Markdown mode', () => { - const spy = sinon.spy(client, 'sendHtmlMessage'); + const spy = sinon.spy(client, 'sendMessage'); mci.enableRichtext(false); addTextToDraft('striked-out'); mci.handleReturn(sinon.stub()); expect(spy.calledOnce).toEqual(true); - expect(spy.args[0][1]).toEqual('striked-out'); - expect(spy.args[0][2]).toEqual('striked-out'); + expect(spy.args[0][1].body).toEqual('striked-out'); + expect(spy.args[0][1].formatted_body).toEqual('striked-out'); }); it('should not strike-through ~~~ in Markdown mode', () => { - const spy = sinon.spy(client, 'sendTextMessage'); + const spy = sinon.spy(client, 'sendMessage'); mci.enableRichtext(false); addTextToDraft('~~~striked-out~~~'); mci.handleReturn(sinon.stub()); expect(spy.calledOnce).toEqual(true); - expect(spy.args[0][1]).toEqual('~~~striked-out~~~'); + expect(spy.args[0][1].body).toEqual('~~~striked-out~~~'); }); it('should not mark single unmarkedup paragraphs as HTML in Markdown mode', () => { - const spy = sinon.spy(client, 'sendTextMessage'); + const spy = sinon.spy(client, 'sendMessage'); mci.enableRichtext(false); addTextToDraft('Lorem ipsum dolor sit amet, consectetur adipiscing elit.'); mci.handleReturn(sinon.stub()); expect(spy.calledOnce).toEqual(true); - expect(spy.args[0][1]).toEqual('Lorem ipsum dolor sit amet, consectetur adipiscing elit.'); + expect(spy.args[0][1].body).toEqual('Lorem ipsum dolor sit amet, consectetur adipiscing elit.'); }); it('should not mark two unmarkedup paragraphs as HTML in Markdown mode', () => { - const spy = sinon.spy(client, 'sendTextMessage'); + const spy = sinon.spy(client, 'sendMessage'); mci.enableRichtext(false); addTextToDraft('Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n\nFusce congue sapien sed neque molestie volutpat.'); mci.handleReturn(sinon.stub()); expect(spy.calledOnce).toEqual(true); - expect(spy.args[0][1]).toEqual('Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n\nFusce congue sapien sed neque molestie volutpat.'); + expect(spy.args[0][1].body).toEqual('Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n\nFusce congue sapien sed neque molestie volutpat.'); }); it('should strip tab-completed mentions so that only the display name is sent in the plain body in Markdown mode', () => { // Sending a HTML message because we have entities in the composer (because of completions) - const spy = sinon.spy(client, 'sendHtmlMessage'); + const spy = sinon.spy(client, 'sendMessage'); mci.enableRichtext(false); mci.setDisplayedCompletion({ completion: 'Some Member', @@ -250,11 +248,11 @@ describe('MessageComposerInput', () => { mci.handleReturn(sinon.stub()); - expect(spy.args[0][1]).toEqual( + expect(spy.args[0][1].body).toEqual( 'Some Member', 'the plaintext body should only include the display name', ); - expect(spy.args[0][2]).toEqual( + expect(spy.args[0][1].formatted_body).toEqual( 'Some Member', 'the html body should contain an anchor tag with a matrix.to href and display name text', ); @@ -262,7 +260,7 @@ describe('MessageComposerInput', () => { it('should strip tab-completed mentions so that only the display name is sent in the plain body in RTE mode', () => { // Sending a HTML message because we have entities in the composer (because of completions) - const spy = sinon.spy(client, 'sendHtmlMessage'); + const spy = sinon.spy(client, 'sendMessage'); mci.enableRichtext(true); mci.setDisplayedCompletion({ completion: 'Some Member', @@ -272,33 +270,33 @@ describe('MessageComposerInput', () => { mci.handleReturn(sinon.stub()); - expect(spy.args[0][1]).toEqual('Some Member'); - expect(spy.args[0][2]).toEqual('Some Member'); + expect(spy.args[0][1].body).toEqual('Some Member'); + expect(spy.args[0][1].formatted_body).toEqual('Some Member'); }); it('should not strip non-tab-completed mentions when manually typing MD', () => { // Sending a HTML message because we have entities in the composer (because of completions) - const spy = sinon.spy(client, 'sendHtmlMessage'); + const spy = sinon.spy(client, 'sendMessage'); // Markdown mode enabled mci.enableRichtext(false); addTextToDraft('[My Not-Tab-Completed Mention](https://matrix.to/#/@some_member:domain.bla)'); mci.handleReturn(sinon.stub()); - expect(spy.args[0][1]).toEqual('[My Not-Tab-Completed Mention](https://matrix.to/#/@some_member:domain.bla)'); - expect(spy.args[0][2]).toEqual('My Not-Tab-Completed Mention'); + expect(spy.args[0][1].body).toEqual('[My Not-Tab-Completed Mention](https://matrix.to/#/@some_member:domain.bla)'); + expect(spy.args[0][1].formatted_body).toEqual('My Not-Tab-Completed Mention'); }); it('should not strip arbitrary typed (i.e. not tab-completed) MD links', () => { // Sending a HTML message because we have entities in the composer (because of completions) - const spy = sinon.spy(client, 'sendHtmlMessage'); + const spy = sinon.spy(client, 'sendMessage'); // Markdown mode enabled mci.enableRichtext(false); addTextToDraft('[Click here](https://some.lovely.url)'); mci.handleReturn(sinon.stub()); - expect(spy.args[0][1]).toEqual('[Click here](https://some.lovely.url)'); - expect(spy.args[0][2]).toEqual('Click here'); + expect(spy.args[0][1].body).toEqual('[Click here](https://some.lovely.url)'); + expect(spy.args[0][1].formatted_body).toEqual('Click here'); }); }); diff --git a/test/test-utils.js b/test/test-utils.js index b593761bd4..3acd8bb861 100644 --- a/test/test-utils.js +++ b/test/test-utils.js @@ -94,8 +94,7 @@ export function createTestClient() { }, setAccountData: sinon.stub(), sendTyping: sinon.stub().returns(Promise.resolve({})), - sendTextMessage: () => Promise.resolve({}), - sendHtmlMessage: () => Promise.resolve({}), + sendMessage: () => Promise.resolve({}), getSyncState: () => "SYNCING", generateClientSecret: () => "t35tcl1Ent5ECr3T", isGuest: () => false, From da1a5616eb03dddb7cb31d4c7e33f1b8dd552d62 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 1 May 2018 14:04:13 +0100 Subject: [PATCH 154/190] Prevent error responses wedging group request concurrency limit Fixes https://github.com/vector-im/riot-web/issues/6592 --- src/stores/GroupStore.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/stores/GroupStore.js b/src/stores/GroupStore.js index 23ce5314ec..f4a66f432f 100644 --- a/src/stores/GroupStore.js +++ b/src/stores/GroupStore.js @@ -62,6 +62,11 @@ function limitConcurrency(fn) { } }) .then(fn) + .catch((err) => { + ongoingRequestCount--; + checkBacklog(); + throw err; + }) .then((result) => { ongoingRequestCount--; checkBacklog(); From 4d8394954c2db411608608dd9cf3fac57034b788 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 1 May 2018 14:24:58 +0100 Subject: [PATCH 155/190] Only create one group store listener in RoomList Instead of creating several and destroying the reference to the one created before. --- src/components/views/rooms/RoomList.js | 19 +++++++++++-------- src/stores/GroupStore.js | 10 ++++++---- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index b70c4a994e..fc1872249f 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -91,19 +91,22 @@ module.exports = React.createClass({ // All rooms that should be kept in the room list when filtering. // By default, show all rooms. this._visibleRooms = MatrixClientPeg.get().getRooms(); - // When the selected tags are changed, initialise a group store if necessary - this._tagStoreToken = TagOrderStore.addListener(() => { + + // Listen to updates to group data. RoomList cares about members and rooms in order + // to filter the room list when group tags are selected. + this._groupStoreToken = GroupStore.registerListener(null, () => { (TagOrderStore.getOrderedTags() || []).forEach((tag) => { if (tag[0] !== '+') { return; } - this._groupStoreToken = GroupStore.registerListener(tag, () => { - // This group's rooms or members may have updated, update rooms for its tag - this.updateVisibleRoomsForTag(dmRoomMap, tag); - this.updateVisibleRooms(); - }); + // This group's rooms or members may have updated, update rooms for its tag + this.updateVisibleRoomsForTag(dmRoomMap, tag); + this.updateVisibleRooms(); }); - // Filters themselves have changed, refresh the selected tags + }); + + this._tagStoreToken = TagOrderStore.addListener(() => { + // Filters themselves have changed this.updateVisibleRooms(); }); diff --git a/src/stores/GroupStore.js b/src/stores/GroupStore.js index 49596550ea..b0c7f8f19f 100644 --- a/src/stores/GroupStore.js +++ b/src/stores/GroupStore.js @@ -183,10 +183,12 @@ class GroupStore extends EventEmitter { // Call to set initial state (before fetching starts) this.emit('update'); - this._fetchResource(this.STATE_KEY.Summary, groupId); - this._fetchResource(this.STATE_KEY.GroupRooms, groupId); - this._fetchResource(this.STATE_KEY.GroupMembers, groupId); - this._fetchResource(this.STATE_KEY.GroupInvitedMembers, groupId); + if (groupId) { + this._fetchResource(this.STATE_KEY.Summary, groupId); + this._fetchResource(this.STATE_KEY.GroupRooms, groupId); + this._fetchResource(this.STATE_KEY.GroupMembers, groupId); + this._fetchResource(this.STATE_KEY.GroupInvitedMembers, groupId); + } // Similar to the Store of flux/utils, we return a "token" that // can be used to unregister the listener. From 56ec7713bb81804a9cda6ae97aa19915ea2e4971 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 1 May 2018 16:54:14 +0100 Subject: [PATCH 156/190] Refresh group rooms and members when selecting a tag --- src/components/views/elements/TagTile.js | 12 ++++++++++++ src/stores/GroupStore.js | 8 ++++++++ 2 files changed, 20 insertions(+) diff --git a/src/components/views/elements/TagTile.js b/src/components/views/elements/TagTile.js index 4ea1b65123..c5fdea0a54 100644 --- a/src/components/views/elements/TagTile.js +++ b/src/components/views/elements/TagTile.js @@ -24,6 +24,7 @@ import { isOnlyCtrlOrCmdIgnoreShiftKeyEvent } from '../../../Keyboard'; import ContextualMenu from '../../structures/ContextualMenu'; import FlairStore from '../../../stores/FlairStore'; +import GroupStore from '../../../stores/GroupStore'; // A class for a child of TagPanel (possibly wrapped in a DNDTagTile) that represents // a thing to click on for the user to filter the visible rooms in the RoomList to: @@ -57,6 +58,8 @@ export default React.createClass({ if (this.props.tag[0] === '+') { FlairStore.addListener('updateGroupProfile', this._onFlairStoreUpdated); this._onFlairStoreUpdated(); + // New rooms or members may have been added to the group, fetch async + this._refreshGroup(this.props.tag); } }, @@ -80,6 +83,11 @@ export default React.createClass({ }); }, + _refreshGroup(groupId) { + GroupStore.refreshGroupRooms(groupId); + GroupStore.refreshGroupMembers(groupId); + }, + onClick: function(e) { e.preventDefault(); e.stopPropagation(); @@ -89,6 +97,10 @@ export default React.createClass({ ctrlOrCmdKey: isOnlyCtrlOrCmdIgnoreShiftKeyEvent(e), shiftKey: e.shiftKey, }); + if (this.props.tag[0] === '+') { + // New rooms or members may have been added to the group, fetch async + this._refreshGroup(this.props.tag); + } }, onContextButtonClick: function(e) { diff --git a/src/stores/GroupStore.js b/src/stores/GroupStore.js index b0c7f8f19f..e750dc1a6b 100644 --- a/src/stores/GroupStore.js +++ b/src/stores/GroupStore.js @@ -233,6 +233,14 @@ class GroupStore extends EventEmitter { (this._state[this.STATE_KEY.Summary][groupId] || {}).user.is_privileged : null; } + refreshGroupRooms(groupId) { + return this._fetchResource(this.STATE_KEY.GroupRooms, groupId); + } + + refreshGroupMembers(groupId) { + return this._fetchResource(this.STATE_KEY.GroupMembers, groupId); + } + addRoomToGroup(groupId, roomId, isPublic) { return MatrixClientPeg.get() .addRoomToGroup(groupId, roomId, isPublic) From bd703b17e58041d6e1cdb886af2939d0e30112b3 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 1 May 2018 16:57:28 +0100 Subject: [PATCH 157/190] Update documentation for GroupStore.registerListener --- src/stores/GroupStore.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/stores/GroupStore.js b/src/stores/GroupStore.js index e750dc1a6b..03132cd80f 100644 --- a/src/stores/GroupStore.js +++ b/src/stores/GroupStore.js @@ -167,11 +167,12 @@ class GroupStore extends EventEmitter { * immediately triggers an update to send the current state of the * store (which could be the initial state). * - * This also causes a fetch of all data of the specified group, - * which might cause 4 separate HTTP requests, but only if said - * requests aren't already ongoing. + * If a group ID is specified, this also causes a fetch of all data + * of the specified group, which might cause 4 separate HTTP + * requests, but only if said requests aren't already ongoing. * - * @param {string} groupId the ID of the group to fetch data for. + * @param {string?} groupId the ID of the group to fetch data for. + * Optional. * @param {function} fn the function to call when the store updates. * @return {Object} tok a registration "token" with a single * property `unregister`, a function that can From 11ae0805b07874bb08f6411e304694d92769afe5 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 1 May 2018 17:42:58 +0100 Subject: [PATCH 158/190] re-order ReplyThread methods for readability Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/ReplyThread.js | 74 ++++++++++---------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index 40db914941..138431259f 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -59,43 +59,6 @@ export default class ReplyThread extends React.Component { this.collapse = this.collapse.bind(this); } - async initialize() { - const {parentEv} = this.props; - // at time of making this component we checked that props.parentEv has a parentEventId - const ev = await ReplyThread.getEvent(this.room, ReplyThread.getParentEventId(parentEv)); - if (this.unmounted) return; - - if (ev) { - this.setState({ - events: [ev], - }, this.loadNextEvent); - } else { - this.setState({err: true}); - } - } - - async loadNextEvent() { - if (this.unmounted) return; - const ev = this.state.events[0]; - const inReplyToEventId = ReplyThread.getParentEventId(ev); - - if (!inReplyToEventId) { - this.setState({ - loading: false, - }); - return; - } - - const loadedEv = await ReplyThread.getEvent(this.room, inReplyToEventId); - if (this.unmounted) return; - - if (loadedEv) { - this.setState({loadedEv}); - } else { - this.setState({err: true}); - } - } - static async getEvent(room, eventId) { const event = room.findEventById(eventId); if (event) return event; @@ -233,6 +196,43 @@ export default class ReplyThread extends React.Component { this.unmounted = true; } + async initialize() { + const {parentEv} = this.props; + // at time of making this component we checked that props.parentEv has a parentEventId + const ev = await ReplyThread.getEvent(this.room, ReplyThread.getParentEventId(parentEv)); + if (this.unmounted) return; + + if (ev) { + this.setState({ + events: [ev], + }, this.loadNextEvent); + } else { + this.setState({err: true}); + } + } + + async loadNextEvent() { + if (this.unmounted) return; + const ev = this.state.events[0]; + const inReplyToEventId = ReplyThread.getParentEventId(ev); + + if (!inReplyToEventId) { + this.setState({ + loading: false, + }); + return; + } + + const loadedEv = await ReplyThread.getEvent(this.room, inReplyToEventId); + if (this.unmounted) return; + + if (loadedEv) { + this.setState({loadedEv}); + } else { + this.setState({err: true}); + } + } + canCollapse() { return this.state.events.length > 1; } From 71c1198d12b5028147f69e6117f592e28afbaf36 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 1 May 2018 18:01:25 +0100 Subject: [PATCH 159/190] Rewrite limitConcurrency to fix error catching Make sure that we only catch errors that are a result of calling fn() --- src/stores/GroupStore.js | 44 ++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/stores/GroupStore.js b/src/stores/GroupStore.js index f4a66f432f..0e2e8e6b86 100644 --- a/src/stores/GroupStore.js +++ b/src/stores/GroupStore.js @@ -48,30 +48,30 @@ function checkBacklog() { // Limit the maximum number of ongoing promises returned by fn to LIMIT and // use a FIFO queue to handle the backlog. -function limitConcurrency(fn) { - return new Promise((resolve, reject) => { - const item = () => { - ongoingRequestCount++; - resolve(); - }; - if (ongoingRequestCount >= LIMIT) { - // Enqueue this request for later execution - backlogQueue.push(item); - } else { - item(); - } - }) - .then(fn) - .catch((err) => { +async function limitConcurrency(fn) { + if (ongoingRequestCount >= LIMIT) { + // Enqueue this request for later execution + await new Promise((resolve, reject) => { + backlogQueue.push(resolve); + }); + } + + let result; + let error; + + ongoingRequestCount++; + try { + result = await fn(); + } catch (err) { + error = err; + } finally { ongoingRequestCount--; checkBacklog(); - throw err; - }) - .then((result) => { - ongoingRequestCount--; - checkBacklog(); - return result; - }); + } + + if (error) throw error; + + return result; } /** From db55f87699bfa4dd52118e4dfc2525d446d2d3b6 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 1 May 2018 18:14:35 +0100 Subject: [PATCH 160/190] avoid `.done` and `.then` anti-pattern Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/structures/RoomView.js | 6 ++---- src/components/views/rooms/MessageComposerInput.js | 6 ++++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index b4735ce0a3..cb6250c2d3 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -914,14 +914,12 @@ module.exports = React.createClass({ return; } - ContentMessages.sendContentToRoom( - file, this.state.room.roomId, MatrixClientPeg.get(), - ).done(() => { + ContentMessages.sendContentToRoom(file, this.state.room.roomId, MatrixClientPeg.get()).then(() => { // Send message_sent callback, for things like _checkIfAlone because after all a file is still a message. dis.dispatch({ action: 'message_sent', }); - }, (error) => { + }).catch((error) => { if (error.name === "UnknownDeviceError") { // Let the status bar handle this return; diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index f7c4215d88..97e8780f0f 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -877,11 +877,13 @@ export default class MessageComposerInput extends React.Component { } - this.client.sendMessage(this.props.room.roomId, content).done((res) => { + this.client.sendMessage(this.props.room.roomId, content).then((res) => { dis.dispatch({ action: 'message_sent', }); - }, (e) => onSendMessageFailed(e, this.props.room)); + }).catch((e) => { + onSendMessageFailed(e, this.props.room); + }); this.setState({ editorState: this.createEditorState(), From ec4ec4717df240fe68df270368332e328a5c6e4f Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 1 May 2018 18:15:12 +0100 Subject: [PATCH 161/190] clean up EventTile:onWidgetLoad optional/required mess Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/EventTile.js | 5 +++++ src/components/views/rooms/ReplyPreview.js | 3 --- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index 56ac082f2a..c2e51d878b 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -154,6 +154,11 @@ module.exports = withMatrixClient(React.createClass({ isTwelveHour: PropTypes.bool, }, + defaultProps: { + // no-op function because onWidgetLoad is optional yet some subcomponents assume its existence + onWidgetLoad: function() {}, + }, + getInitialState: function() { return { // Whether the context menu is being displayed. diff --git a/src/components/views/rooms/ReplyPreview.js b/src/components/views/rooms/ReplyPreview.js index dd11b0df33..46e2826634 100644 --- a/src/components/views/rooms/ReplyPreview.js +++ b/src/components/views/rooms/ReplyPreview.js @@ -75,11 +75,8 @@ export default class ReplyPreview extends React.Component {
; } } - -function dummyOnWidgetLoad() {} From 2dfb3146b00f8d5264dc72b416754c6e7966c3fe Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 2 May 2018 10:39:15 +0100 Subject: [PATCH 162/190] Simplify concurrent request error handling --- src/stores/GroupStore.js | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/stores/GroupStore.js b/src/stores/GroupStore.js index 0e2e8e6b86..e7cea5667e 100644 --- a/src/stores/GroupStore.js +++ b/src/stores/GroupStore.js @@ -56,22 +56,16 @@ async function limitConcurrency(fn) { }); } - let result; - let error; - ongoingRequestCount++; try { - result = await fn(); + return await fn(); } catch (err) { - error = err; + // We explicitly do not handle the error here, but let it propogate. + throw err; } finally { ongoingRequestCount--; checkBacklog(); } - - if (error) throw error; - - return result; } /** From 730512bc3f26d3b0106ce76ce9b29b7f0bc1e128 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 2 May 2018 10:58:43 +0100 Subject: [PATCH 163/190] Use the right js-sdk branch when testing On the react-sdk tests not just riot-web --- .travis-test-riot.sh | 9 +-------- scripts/travis.sh | 4 ++++ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/.travis-test-riot.sh b/.travis-test-riot.sh index 87200871a5..eeba4d0b7e 100755 --- a/.travis-test-riot.sh +++ b/.travis-test-riot.sh @@ -9,16 +9,9 @@ set -ev RIOT_WEB_DIR=riot-web REACT_SDK_DIR=`pwd` -curbranch="${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH}" -echo "Determined branch to be $curbranch" - -git clone https://github.com/vector-im/riot-web.git \ - "$RIOT_WEB_DIR" - +scripts/fetchdep.sh vector-im riot-web cd "$RIOT_WEB_DIR" -git checkout "$curbranch" || git checkout develop - mkdir node_modules npm install diff --git a/scripts/travis.sh b/scripts/travis.sh index c4a06c1bd1..7c96a02eb5 100755 --- a/scripts/travis.sh +++ b/scripts/travis.sh @@ -2,6 +2,10 @@ set -ex +scripts/fetchdep.sh matrix-org matrix-js-sdk +rm -r node_modules/matrix-js-sdk || true +ln -s matrix-js-sdk node_modules/matrix-js-sdk + npm run test ./.travis-test-riot.sh From b44582777bbcf680093955b874867b88783353a9 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 2 May 2018 11:03:40 +0100 Subject: [PATCH 164/190] Would if I added the script --- scripts/fetchdep.sh | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100755 scripts/fetchdep.sh diff --git a/scripts/fetchdep.sh b/scripts/fetchdep.sh new file mode 100755 index 0000000000..424a8b034c --- /dev/null +++ b/scripts/fetchdep.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +set -e + +org="$1" +repo="$2" + +curbranch="${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH}" +echo "Determined branch to be $curbranch" + +git clone https://github.com/$org/$repo.git $repo --branch "$curbranch" || git clone https://github.com/$org/$repo.git $repo --branch develop + From c54198464ba396868a1c76e1f7991c427e398c3f Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 2 May 2018 11:09:28 +0100 Subject: [PATCH 165/190] npm install the js-sdk --- scripts/travis.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/travis.sh b/scripts/travis.sh index 7c96a02eb5..5c084145da 100755 --- a/scripts/travis.sh +++ b/scripts/travis.sh @@ -6,6 +6,10 @@ scripts/fetchdep.sh matrix-org matrix-js-sdk rm -r node_modules/matrix-js-sdk || true ln -s matrix-js-sdk node_modules/matrix-js-sdk +pushd node_modules/matrix-js-sdk +npm install +popd + npm run test ./.travis-test-riot.sh From 825d610938bcb30e509639782c1b4ce34ebe785d Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 2 May 2018 11:13:16 +0100 Subject: [PATCH 166/190] Bah, no pushd. Also this npm install should now be unnecessary --- .travis.yml | 1 - scripts/travis.sh | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 954f14a4da..ec07243a28 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,6 +15,5 @@ addons: chrome: stable install: - npm install - - (cd node_modules/matrix-js-sdk && npm install) script: ./scripts/travis.sh diff --git a/scripts/travis.sh b/scripts/travis.sh index 5c084145da..b3f87bfed0 100755 --- a/scripts/travis.sh +++ b/scripts/travis.sh @@ -6,9 +6,9 @@ scripts/fetchdep.sh matrix-org matrix-js-sdk rm -r node_modules/matrix-js-sdk || true ln -s matrix-js-sdk node_modules/matrix-js-sdk -pushd node_modules/matrix-js-sdk +cd node_modules/matrix-js-sdk npm install -popd +cd ../.. npm run test ./.travis-test-riot.sh From dc20f32ad7b0dbde599f05ea2ef8986e2711d0ea Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 2 May 2018 11:19:01 +0100 Subject: [PATCH 167/190] Move waitForUpdate to test-utils --- test/components/structures/GroupView-test.js | 21 +------------------- test/test-utils.js | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/test/components/structures/GroupView-test.js b/test/components/structures/GroupView-test.js index 71df26da46..76baafe1c8 100644 --- a/test/components/structures/GroupView-test.js +++ b/test/components/structures/GroupView-test.js @@ -26,32 +26,13 @@ import sdk from 'matrix-react-sdk'; import Matrix from 'matrix-js-sdk'; import * as TestUtils from 'test-utils'; +const { waitForUpdate } = TestUtils; const GroupView = sdk.getComponent('structures.GroupView'); const WrappedGroupView = TestUtils.wrapInMatrixClientContext(GroupView); const Spinner = sdk.getComponent('elements.Spinner'); -/** - * Call fn before calling componentDidUpdate on a react component instance, inst. - * @param {React.Component} inst an instance of a React component. - * @returns {Promise} promise that resolves when componentDidUpdate is called on - * given component instance. - */ -function waitForUpdate(inst) { - return new Promise((resolve, reject) => { - const cdu = inst.componentDidUpdate; - - inst.componentDidUpdate = (prevProps, prevState, snapshot) => { - resolve(); - - if (cdu) cdu(prevProps, prevState, snapshot); - - inst.componentDidUpdate = cdu; - }; - }); -} - describe('GroupView', function() { let root; let rootElement; diff --git a/test/test-utils.js b/test/test-utils.js index d2c685b371..e7d3412722 100644 --- a/test/test-utils.js +++ b/test/test-utils.js @@ -302,3 +302,23 @@ export function wrapInMatrixClientContext(WrappedComponent) { } return Wrapper; } + +/** + * Call fn before calling componentDidUpdate on a react component instance, inst. + * @param {React.Component} inst an instance of a React component. + * @returns {Promise} promise that resolves when componentDidUpdate is called on + * given component instance. + */ +export function waitForUpdate(inst) { + return new Promise((resolve, reject) => { + const cdu = inst.componentDidUpdate; + + inst.componentDidUpdate = (prevProps, prevState, snapshot) => { + resolve(); + + if (cdu) cdu(prevProps, prevState, snapshot); + + inst.componentDidUpdate = cdu; + }; + }); +} From 9bccecf449533b5d48552a13f1e845983acc54c1 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 2 May 2018 11:23:57 +0100 Subject: [PATCH 168/190] Get symlink right Also No need to cd into the symlink, can just go straight there --- scripts/travis.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/travis.sh b/scripts/travis.sh index b3f87bfed0..48410ea904 100755 --- a/scripts/travis.sh +++ b/scripts/travis.sh @@ -4,11 +4,11 @@ set -ex scripts/fetchdep.sh matrix-org matrix-js-sdk rm -r node_modules/matrix-js-sdk || true -ln -s matrix-js-sdk node_modules/matrix-js-sdk +ln -s ../matrix-js-sdk node_modules/matrix-js-sdk -cd node_modules/matrix-js-sdk +cd matrix-js-sdk npm install -cd ../.. +cd .. npm run test ./.travis-test-riot.sh From 4c3f8110509be237e7287349cf6ec346de18caff Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 2 May 2018 13:14:47 +0100 Subject: [PATCH 169/190] switch RoomView:uploadFile to async to clean up then/catch handling Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/structures/RoomView.js | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index cb6250c2d3..c5f6a75cc5 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -908,18 +908,15 @@ module.exports = React.createClass({ this.setState({ draggingFile: false }); }, - uploadFile: function(file) { + uploadFile: async function(file) { if (MatrixClientPeg.get().isGuest()) { dis.dispatch({action: 'view_set_mxid'}); return; } - ContentMessages.sendContentToRoom(file, this.state.room.roomId, MatrixClientPeg.get()).then(() => { - // Send message_sent callback, for things like _checkIfAlone because after all a file is still a message. - dis.dispatch({ - action: 'message_sent', - }); - }).catch((error) => { + try { + await ContentMessages.sendContentToRoom(file, this.state.room.roomId, MatrixClientPeg.get()); + } catch (error) { if (error.name === "UnknownDeviceError") { // Let the status bar handle this return; @@ -931,6 +928,14 @@ module.exports = React.createClass({ description: ((error && error.message) ? error.message : _t("Server may be unavailable, overloaded, or the file too big")), }); + + // bail early to avoid calling the dispatch below + return; + } + + // Send message_sent callback, for things like _checkIfAlone because after all a file is still a message. + dis.dispatch({ + action: 'message_sent', }); }, From 0040ea0d9f76b27eef56b64db02d6cccc262e532 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 2 May 2018 15:53:38 +0100 Subject: [PATCH 170/190] Use develop js-sdk in travis build --- jenkins.sh | 5 +++-- scripts/fetchdep.sh | 14 +++++++++++--- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/jenkins.sh b/jenkins.sh index 3a2d66739e..0f7a58ee69 100755 --- a/jenkins.sh +++ b/jenkins.sh @@ -11,8 +11,9 @@ set -x # install the other dependencies npm install -# we may be using a dev branch of js-sdk in which case we need to build it -(cd node_modules/matrix-js-sdk && npm install) +scripts/fetchdep.sh matrix-org matrix-js-sdk +ln -s ../matrix-js-sdk node_modules/matrix-js-sdk +(cd matrix-js-sdk && npm install) # run the mocha tests npm run test -- --no-colors diff --git a/scripts/fetchdep.sh b/scripts/fetchdep.sh index 424a8b034c..14111576bf 100755 --- a/scripts/fetchdep.sh +++ b/scripts/fetchdep.sh @@ -5,8 +5,16 @@ set -e org="$1" repo="$2" -curbranch="${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH}" -echo "Determined branch to be $curbranch" +curbranch="$TRAVIS_PULL_REQUEST_BRANCH" +[ -z "$curbranch" ] && curbranch="$TRAVIS_BRANCH" +[ -z "$curbranch" ] && curbranch="$GIT_BRANCH" # jenkins -git clone https://github.com/$org/$repo.git $repo --branch "$curbranch" || git clone https://github.com/$org/$repo.git $repo --branch develop +if [ -n "$curbranch" ] +then + echo "Determined branch to be $curbranch" + git clone https://github.com/$org/$repo.git $repo --branch "$curbranch" && exit 0 +fi + +echo "Checking out develop branch" +git clone https://github.com/$org/$repo.git $repo --branch develop From 183947615f68083a73813ad671e039e1f8cd5869 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 2 May 2018 16:39:10 +0100 Subject: [PATCH 171/190] Fux up jenkins origin/ branches --- scripts/fetchdep.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/fetchdep.sh b/scripts/fetchdep.sh index 14111576bf..9e7e47fe5b 100755 --- a/scripts/fetchdep.sh +++ b/scripts/fetchdep.sh @@ -7,7 +7,7 @@ repo="$2" curbranch="$TRAVIS_PULL_REQUEST_BRANCH" [ -z "$curbranch" ] && curbranch="$TRAVIS_BRANCH" -[ -z "$curbranch" ] && curbranch="$GIT_BRANCH" # jenkins +[ -z "$curbranch" ] && curbranch=`"$GIT_BRANCH" | sed -e 's/^origin\///'` # jenkins if [ -n "$curbranch" ] then From 82349ec933cc369179814931e303602e05e169f4 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 2 May 2018 16:43:51 +0100 Subject: [PATCH 172/190] Fix sed --- scripts/fetchdep.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/fetchdep.sh b/scripts/fetchdep.sh index 9e7e47fe5b..a8551cf15d 100755 --- a/scripts/fetchdep.sh +++ b/scripts/fetchdep.sh @@ -7,7 +7,7 @@ repo="$2" curbranch="$TRAVIS_PULL_REQUEST_BRANCH" [ -z "$curbranch" ] && curbranch="$TRAVIS_BRANCH" -[ -z "$curbranch" ] && curbranch=`"$GIT_BRANCH" | sed -e 's/^origin\///'` # jenkins +[ -z "$curbranch" ] && curbranch=`"echo $GIT_BRANCH" | sed -e 's/^origin\///'` # jenkins if [ -n "$curbranch" ] then From 9f8202c8a9f42235b396d62430f75d6b1120ebd6 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 2 May 2018 16:49:08 +0100 Subject: [PATCH 173/190] Remove directories if they exist --- jenkins.sh | 1 + scripts/fetchdep.sh | 2 ++ 2 files changed, 3 insertions(+) diff --git a/jenkins.sh b/jenkins.sh index 0f7a58ee69..8cf5ee4a1f 100755 --- a/jenkins.sh +++ b/jenkins.sh @@ -12,6 +12,7 @@ set -x npm install scripts/fetchdep.sh matrix-org matrix-js-sdk +rm -r node_modules/matrix-js-sdk || true ln -s ../matrix-js-sdk node_modules/matrix-js-sdk (cd matrix-js-sdk && npm install) diff --git a/scripts/fetchdep.sh b/scripts/fetchdep.sh index a8551cf15d..73c622133b 100755 --- a/scripts/fetchdep.sh +++ b/scripts/fetchdep.sh @@ -5,6 +5,8 @@ set -e org="$1" repo="$2" +rm -r "$repo" || true + curbranch="$TRAVIS_PULL_REQUEST_BRANCH" [ -z "$curbranch" ] && curbranch="$TRAVIS_BRANCH" [ -z "$curbranch" ] && curbranch=`"echo $GIT_BRANCH" | sed -e 's/^origin\///'` # jenkins From bf8612f8642346fb42cc96b20d3b2597dc9c294b Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 2 May 2018 17:30:37 +0100 Subject: [PATCH 174/190] Update eslint-plugin-react Enables jsx-no-bind checking (although we may have to stop erroring on this as we currently break this rule in a few places) --- package-lock.json | 423 +++++++++++++++++++++++++++++----------------- package.json | 2 +- 2 files changed, 270 insertions(+), 155 deletions(-) diff --git a/package-lock.json b/package-lock.json index 23ffa68bef..f183f1635d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "0.10.7", + "version": "0.12.2", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -268,7 +268,7 @@ "glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", "dev": true, "requires": { "fs.realpath": "1.0.0", @@ -1203,10 +1203,7 @@ "boom": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", - "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", - "requires": { - "hoek": "4.2.0" - } + "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=" }, "brace-expansion": { "version": "1.1.8", @@ -1238,6 +1235,12 @@ "resolved": "https://registry.npmjs.org/browser-request/-/browser-request-0.3.3.tgz", "integrity": "sha1-ns5bWsqJopkyJC4Yv5M975h2zBc=" }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, "browserify-aes": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-0.4.0.tgz", @@ -1254,6 +1257,14 @@ "dev": true, "requires": { "pako": "0.2.9" + }, + "dependencies": { + "pako": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", + "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=", + "dev": true + } } }, "buffer": { @@ -1449,9 +1460,9 @@ "dev": true }, "commonmark": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/commonmark/-/commonmark-0.27.0.tgz", - "integrity": "sha1-2GwmK5YoIelIPGnFR7xYhAwEezQ=", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/commonmark/-/commonmark-0.28.1.tgz", + "integrity": "sha1-Buq41SM4uDn6Gi11rwCF7tGxvq4=", "requires": { "entities": "1.1.1", "mdurl": "1.0.1", @@ -1580,10 +1591,7 @@ "boom": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", - "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", - "requires": { - "hoek": "4.2.0" - } + "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==" } } }, @@ -1705,12 +1713,6 @@ "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=", "dev": true }, - "diff": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz", - "integrity": "sha1-fyjS657nsVqX79ic5j3P2qPMur8=", - "dev": true - }, "doctrine": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz", @@ -2139,7 +2141,7 @@ "glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", "dev": true, "requires": { "fs.realpath": "1.0.0", @@ -2183,15 +2185,26 @@ } }, "eslint-plugin-react": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.4.0.tgz", - "integrity": "sha512-tvjU9u3VqmW2vVuYnE8Qptq+6ji4JltjOjJ9u7VAOxVYkUkyBZWRvNYKbDv5fN+L6wiA+4we9+qQahZ0m63XEA==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.7.0.tgz", + "integrity": "sha512-KC7Snr4YsWZD5flu6A5c0AcIZidzW3Exbqp7OT67OaD2AppJtlBr/GuPrW/vaQM/yfZotEvKAdrxrO+v8vwYJA==", "dev": true, "requires": { - "doctrine": "2.0.0", + "doctrine": "2.1.0", "has": "1.0.1", "jsx-ast-utils": "2.0.1", "prop-types": "15.6.0" + }, + "dependencies": { + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "2.0.2" + } + } } }, "espree": { @@ -2238,7 +2251,7 @@ "estree-walker": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.5.0.tgz", - "integrity": "sha512-/bEAy+yKAZQrEWUhGmS3H9XpGqSDBtRzX0I2PgMw9kA2n1jN22uV5B5p7MFdZdvWdXCRJztXAfx6ZeRfgkEETg==", + "integrity": "sha1-quO1fELeuAEONJyJJGLw5xxd0ao=", "dev": true }, "esutils": { @@ -2554,6 +2567,22 @@ } } }, + "focus-trap": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-2.4.3.tgz", + "integrity": "sha512-sT5Ip9nyAIxWq8Apt1Fdv6yTci5GotaOtO5Ro1/+F3PizttNBcCYz8j/Qze54PPFK73KUbOqh++HUCiyNPqvhA==", + "requires": { + "tabbable": "1.1.2" + } + }, + "focus-trap-react": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/focus-trap-react/-/focus-trap-react-3.1.2.tgz", + "integrity": "sha512-MoQmONoy9gRPyrC5DGezkcOMGgx7MtIOAQDHe098UtL2sA2vmucJwEmQisb+8LRXNYFHxuw5zJ1oLFeKu4Mteg==", + "requires": { + "focus-trap": "2.4.3" + } + }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -2629,7 +2658,7 @@ "fsevents": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.2.tgz", - "integrity": "sha512-Sn44E5wQW4bTHXvQmvSHwqbuiXtduD6Rrjm2ZtUEGbyrig+nUH3t/QD4M4/ZXViY556TBpRgZkHLDx3JxPwxiw==", + "integrity": "sha1-MoK3E/s62A7eDp/PRhG1qm/AM/Q=", "dev": true, "optional": true, "requires": { @@ -3562,6 +3591,11 @@ "assert-plus": "1.0.0" } }, + "gfm.css": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/gfm.css/-/gfm.css-1.1.2.tgz", + "integrity": "sha512-KhK3rqxMj+UTLRxWnfUA5n8XZYMWfHrrcCxtWResYR2B3hWIqBM6v9FPGZSlVuX+ScLewizOvNkjYXuPs95ThQ==" + }, "glob": { "version": "5.0.15", "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", @@ -3596,7 +3630,7 @@ "globals": { "version": "9.18.0", "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "integrity": "sha1-qjiWs+abSH8X4x7SFD1pqOMMLYo=", "dev": true }, "globby": { @@ -3616,7 +3650,7 @@ "glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", "dev": true, "requires": { "fs.realpath": "1.0.0", @@ -3635,12 +3669,6 @@ "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", "dev": true }, - "growl": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", - "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=", - "dev": true - }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -3709,19 +3737,24 @@ "requires": { "boom": "4.3.1", "cryptiles": "3.1.2", - "hoek": "4.2.0", "sntp": "2.0.2" } }, - "highlight.js": { - "version": "8.9.1", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-8.9.1.tgz", - "integrity": "sha1-uKnFSTISqTkvAiK2SclhFJfr+4g=" + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true }, - "hoek": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", - "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==" + "highlight.js": { + "version": "9.12.0", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.12.0.tgz", + "integrity": "sha1-5tnb5Xy+/mB1HwKvM2GVhwyQwB4=" + }, + "hoist-non-react-statics": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.0.tgz", + "integrity": "sha512-6Bl6XsDT1ntE0lHbIhr4Kp2PGcleGZ66qu5Jqk8lc0Xc/IeG6gVLmwUGs/K0Us+L8VWoKgj0uWdPMataOsm31w==" }, "home-or-tmp": { "version": "2.0.0", @@ -3862,7 +3895,6 @@ "version": "2.2.2", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=", - "dev": true, "requires": { "loose-envify": "1.3.1" } @@ -4137,30 +4169,6 @@ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, - "jade": { - "version": "0.26.3", - "resolved": "https://registry.npmjs.org/jade/-/jade-0.26.3.tgz", - "integrity": "sha1-jxDXl32NefL2/4YqgbBRPMslaGw=", - "dev": true, - "requires": { - "commander": "0.6.1", - "mkdirp": "0.3.0" - }, - "dependencies": { - "commander": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-0.6.1.tgz", - "integrity": "sha1-+mihT2qUXVTbvlDYzbMyDp47GgY=", - "dev": true - }, - "mkdirp": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz", - "integrity": "sha1-G79asbqCevI1dRQ0kEJkVfSB/h4=", - "dev": true - } - } - }, "jquery": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.2.1.tgz", @@ -4303,7 +4311,7 @@ "glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", "dev": true, "requires": { "fs.realpath": "1.0.0", @@ -4472,6 +4480,11 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" }, + "lodash-es": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.10.tgz", + "integrity": "sha512-iesFYPmxYYGTcmQK0sL8bX3TGHyM6b2qREaB4kamHfQyfPJP0xgoGxp19nsH16nsfquLdiyKyX3mQkfiSGV8Rg==" + }, "lodash.assign": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", @@ -4547,17 +4560,28 @@ "dev": true }, "matrix-js-sdk": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/matrix-js-sdk/-/matrix-js-sdk-0.8.5.tgz", - "integrity": "sha1-1ZAVTx53ADVyZw+p28rH5APnbk8=", + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/matrix-js-sdk/-/matrix-js-sdk-0.10.1.tgz", + "integrity": "sha512-BLo+Okn2o///TyWBKtjFXvhlD32vGfr10eTE51hHx/jwaXO82VyGMzMi+IDPS4SDYUbvXI7PpamECeh9TXnV2w==", "requires": { "another-json": "0.2.0", + "babel-runtime": "6.26.0", "bluebird": "3.5.1", "browser-request": "0.3.3", "content-type": "1.0.4", "request": "2.83.0" } }, + "matrix-mock-request": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/matrix-mock-request/-/matrix-mock-request-1.2.1.tgz", + "integrity": "sha1-2aWrqNPYJG6I/3YyWYuZwUE/QjI=", + "dev": true, + "requires": { + "bluebird": "3.5.1", + "expect": "1.20.2" + } + }, "matrix-react-test-utils": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/matrix-react-test-utils/-/matrix-react-test-utils-0.1.1.tgz", @@ -4579,6 +4603,11 @@ "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", "dev": true }, + "memoize-one": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-3.1.1.tgz", + "integrity": "sha512-YqVh744GsMlZu6xkhGslPSqSurOv6P+kLN2J3ysBZfagLcL5FdRK/0UpgLoL8hwjjEvvAVkjJZyFP+1T6p1vgA==" + }, "memory-fs": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", @@ -4632,7 +4661,7 @@ "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", "requires": { "brace-expansion": "1.1.8" } @@ -4660,75 +4689,73 @@ } }, "mocha": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-2.5.3.tgz", - "integrity": "sha1-FhvlvetJZ3HrmzV0UFC2IrWu/Fg=", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.1.1.tgz", + "integrity": "sha512-kKKs/H1KrMMQIEsWNxGmb4/BGsmj0dkeyotEvbrAuQ01FcWRLssUNXCEUZk6SZtyJBi6EE7SL0zDDtItw1rGhw==", "dev": true, "requires": { - "commander": "2.3.0", - "debug": "2.2.0", - "diff": "1.4.0", - "escape-string-regexp": "1.0.2", - "glob": "3.2.11", - "growl": "1.9.2", - "jade": "0.26.3", + "browser-stdout": "1.3.1", + "commander": "2.11.0", + "debug": "3.1.0", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.3", + "he": "1.1.1", + "minimatch": "3.0.4", "mkdirp": "0.5.1", - "supports-color": "1.2.0", - "to-iso-string": "0.0.2" + "supports-color": "4.4.0" }, "dependencies": { - "commander": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.3.0.tgz", - "integrity": "sha1-/UMOiJgy7DU7ms0d4hfBHLPu+HM=", - "dev": true - }, "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "requires": { - "ms": "0.7.1" + "ms": "2.0.0" } }, - "escape-string-regexp": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz", - "integrity": "sha1-Tbwv5nTnGUnK8/smlc5/LcHZqNE=", + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", "dev": true }, "glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz", - "integrity": "sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0=", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "dev": true, "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", "inherits": "2.0.3", - "minimatch": "0.3.0" + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" } }, - "minimatch": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz", - "integrity": "sha1-J12O2qxPG7MyZHIInnlJyDlGmd0=", - "dev": true, - "requires": { - "lru-cache": "2.2.4", - "sigmund": "1.0.1" - } + "growl": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", + "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", + "dev": true }, - "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", "dev": true }, "supports-color": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-1.2.0.tgz", - "integrity": "sha1-/x7R5hFp0Gs88tWI4YixjYhH4X4=", - "dev": true + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } } } }, @@ -4979,10 +5006,9 @@ } }, "pako": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", - "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=", - "dev": true + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz", + "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg==" }, "parallelshell": { "version": "3.0.2", @@ -5205,10 +5231,23 @@ "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", "dev": true }, + "raf": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.0.tgz", + "integrity": "sha512-pDP/NMRAXoTfrhCfyfSEwJAKLaxBU9eApMeBPB1TkDouZmvPerIClV8lTAd+uF8ZiTaVl69e1FCxQrAd/VTjGw==", + "requires": { + "performance-now": "2.1.0" + } + }, + "raf-schd": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/raf-schd/-/raf-schd-2.1.1.tgz", + "integrity": "sha512-ngcBQygUeE3kHlOaBSqgWKv7BT9kx5kQ6fAwFJRNRT7TD54M+hx1kpNHb8sONRskcYQedJg2RC2xKlAHRUQBig==" + }, "randomatic": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", - "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", + "integrity": "sha1-x6vpzIuHwLqodrGf3oP9RkeX44w=", "dev": true, "requires": { "is-number": "3.0.0", @@ -5287,6 +5326,23 @@ "integrity": "sha1-wStu/cIkfBDae4dw0YUICnsEcVY=", "dev": true }, + "react-beautiful-dnd": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/react-beautiful-dnd/-/react-beautiful-dnd-4.0.1.tgz", + "integrity": "sha512-d73RMu4QOFCyjUELLWFyY/EuclnfqulI9pECx+2gIuJvV0ycf1uR88o+1x0RSB9ILD70inHMzCBKNkWVbbt+vA==", + "requires": { + "babel-runtime": "6.26.0", + "invariant": "2.2.2", + "memoize-one": "3.1.1", + "prop-types": "15.6.0", + "raf-schd": "2.1.1", + "react-motion": "0.5.2", + "react-redux": "5.0.7", + "redux": "3.7.2", + "redux-thunk": "2.2.0", + "reselect": "3.0.1" + } + }, "react-dom": { "version": "15.6.2", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-15.6.2.tgz", @@ -5304,6 +5360,43 @@ "gemini-scrollbar": "github:matrix-org/gemini-scrollbar#b302279810d05319ac5ff1bd34910bff32325c7b" } }, + "react-motion": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/react-motion/-/react-motion-0.5.2.tgz", + "integrity": "sha512-9q3YAvHoUiWlP3cK0v+w1N5Z23HXMj4IF4YuvjvWegWqNPfLXsOBE/V7UvQGpXxHFKRQQcNcVQE31g9SB/6qgQ==", + "requires": { + "performance-now": "0.2.0", + "prop-types": "15.6.0", + "raf": "3.4.0" + }, + "dependencies": { + "performance-now": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", + "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=" + } + } + }, + "react-redux": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-5.0.7.tgz", + "integrity": "sha512-5VI8EV5hdgNgyjfmWzBbdrqUkrVRKlyTKk1sGH3jzM2M2Mhj/seQgPXaz6gVAj2lz/nz688AdTqMO18Lr24Zhg==", + "requires": { + "hoist-non-react-statics": "2.5.0", + "invariant": "2.2.2", + "lodash": "4.17.10", + "lodash-es": "4.17.10", + "loose-envify": "1.3.1", + "prop-types": "15.6.0" + }, + "dependencies": { + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==" + } + } + }, "readable-stream": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", @@ -5350,6 +5443,22 @@ "resolve": "1.4.0" } }, + "redux": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/redux/-/redux-3.7.2.tgz", + "integrity": "sha512-pNqnf9q1hI5HHZRBkj3bAngGZW/JMCmexDlOxw4XagXY2o1327nHH54LoTjiPJ0gizoqPDRqWyX/00g0hD6w+A==", + "requires": { + "lodash": "4.17.4", + "lodash-es": "4.17.10", + "loose-envify": "1.3.1", + "symbol-observable": "1.2.0" + } + }, + "redux-thunk": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.2.0.tgz", + "integrity": "sha1-5hWhbha0ehmlFXZhM9Hj6Zt4UuU=" + }, "regenerate": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.3.tgz", @@ -5498,6 +5607,11 @@ "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", "dev": true }, + "reselect": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-3.0.1.tgz", + "integrity": "sha1-79qpjqdFEyTQkrKyFjpqHXqaIUc=" + }, "resolve": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz", @@ -5544,7 +5658,7 @@ "glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", "dev": true, "requires": { "fs.realpath": "1.0.0", @@ -5642,7 +5756,7 @@ "glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", "dev": true, "requires": { "fs.realpath": "1.0.0", @@ -5655,12 +5769,6 @@ } } }, - "sigmund": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", - "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", - "dev": true - }, "sinon": { "version": "1.17.7", "resolved": "https://registry.npmjs.org/sinon/-/sinon-1.17.7.tgz", @@ -5688,10 +5796,7 @@ "sntp": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.0.2.tgz", - "integrity": "sha1-UGQRDwr4X3z9t9a2ekACjOUrSys=", - "requires": { - "hoek": "4.2.0" - } + "integrity": "sha1-UGQRDwr4X3z9t9a2ekACjOUrSys=" }, "socket.io": { "version": "1.7.3", @@ -5848,24 +5953,30 @@ "dev": true }, "source-map-loader": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-0.1.6.tgz", - "integrity": "sha1-wJkD2m1zueU7ftjuUkVZcFHpjpE=", + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-0.2.3.tgz", + "integrity": "sha512-MYbFX9DYxmTQFfy2v8FC1XZwpwHKYxg3SK8Wb7VPBKuhDjz8gi9re2819MsG4p49HDyiOSUKlmZ+nQBArW5CGw==", "dev": true, "requires": { - "async": "0.9.2", + "async": "2.6.0", "loader-utils": "0.2.17", - "source-map": "0.1.43" + "source-map": "0.6.1" }, "dependencies": { - "source-map": { - "version": "0.1.43", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", - "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", + "async": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", + "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", "dev": true, "requires": { - "amdefine": "1.0.1" + "lodash": "4.17.4" } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true } } }, @@ -5917,7 +6028,7 @@ "stream-http": { "version": "2.7.2", "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.7.2.tgz", - "integrity": "sha512-c0yTD2rbQzXtSsFSVhtpvY/vS6u066PcXOX9kBB3mSO76RiUQzL340uJkGBWnlBg4/HZzqiUXtaVA7wcRcJgEw==", + "integrity": "sha1-QKBQ7I3DtTsz2ZCUFcAsC/Gr+60=", "dev": true, "requires": { "builtin-status-codes": "3.0.0", @@ -5983,6 +6094,16 @@ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true }, + "symbol-observable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", + "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==" + }, + "tabbable": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-1.1.2.tgz", + "integrity": "sha512-77oqsKEPrxIwgRcXUwipkj9W5ItO97L6eUT1Ar7vh+El16Zm4M6V+YU1cbipHEa6q0Yjw8O3Hoh8oRgatV5s7A==" + }, "table": { "version": "3.8.3", "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", @@ -6111,12 +6232,6 @@ "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", "dev": true }, - "to-iso-string": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/to-iso-string/-/to-iso-string-0.0.2.tgz", - "integrity": "sha1-TcGeZk38y+Jb2NtQiwDG2hWCVdE=", - "dev": true - }, "tough-cookie": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", diff --git a/package.json b/package.json index 1f979369e3..47ef08f546 100644 --- a/package.json +++ b/package.json @@ -110,7 +110,7 @@ "eslint-config-google": "^0.7.1", "eslint-plugin-babel": "^4.0.1", "eslint-plugin-flowtype": "^2.30.0", - "eslint-plugin-react": "^7.4.0", + "eslint-plugin-react": "^7.7.0", "estree-walker": "^0.5.0", "expect": "^1.16.0", "flow-parser": "^0.57.3", From adf3e2f376cc5722b6085519b55db94777eca7b6 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 2 May 2018 17:36:29 +0100 Subject: [PATCH 175/190] Change jsx-no-bind to warn --- .eslintrc.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.eslintrc.js b/.eslintrc.js index c6aeb0d1be..9c14917e1f 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -41,7 +41,8 @@ module.exports = { "react/jsx-uses-react": "error", // bind or arrow function in props causes performance issues - "react/jsx-no-bind": ["error", { + // (but we currently use them in some places) + "react/jsx-no-bind": ["warn", { "ignoreRefs": true, }], "react/jsx-key": ["error"], From 2475295a24e24083cadafa2d499cdbb3aeb636c5 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 2 May 2018 17:42:23 +0100 Subject: [PATCH 176/190] Up the max warning count :( --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 47ef08f546..5e58b90264 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "start": "parallelshell \"npm run build:watch\" \"npm run reskindex:watch\"", "lint": "eslint src/", "lintall": "eslint src/ test/", - "lintwithexclusions": "eslint --max-warnings 0 --ignore-path .eslintignore.errorfiles src test", + "lintwithexclusions": "eslint --max-warnings 10 --ignore-path .eslintignore.errorfiles src test", "clean": "rimraf lib", "prepublish": "npm run clean && npm run build && git rev-parse HEAD > git-revision.txt", "test": "karma start --single-run=true --browsers ChromeHeadless", From 09dcfb0a00af06be374218e6aec01fd3607da4f8 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Wed, 2 May 2018 23:27:19 +0100 Subject: [PATCH 177/190] relax lint for jsx-curly-spacing and arrow-parens --- .eslintrc.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index c6aeb0d1be..12ccd0e337 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -50,7 +50,12 @@ module.exports = { // // // https://github.com/yannickcr/eslint-plugin-react/blob/HEAD/docs/rules/jsx-curly-spacing.md - "react/jsx-curly-spacing": ["error", {"when": "never", "children": {"when": "always"}}], + // + // Disabled for now - if anything we'd like to *enforce* spacing in JSX + // curly brackets for legibility, but in practice it's not clear that the + // consistency particularly improves legibility here. --Matthew + // + // "react/jsx-curly-spacing": ["error", {"when": "never", "children": {"when": "always"}}], // Assert spacing before self-closing JSX tags, and no spacing before or // after the closing slash, and no spacing after the opening bracket of @@ -88,7 +93,6 @@ module.exports = { "valid-jsdoc": ["warn"], "new-cap": ["warn"], "key-spacing": ["warn"], - "arrow-parens": ["warn"], "prefer-const": ["warn"], // crashes currently: https://github.com/eslint/eslint/issues/6274 From 71a12b6bbbe2cb0e383d7e75a49d32c8e7c17989 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 3 May 2018 11:23:41 +0100 Subject: [PATCH 178/190] fix getDefaultProps mixup Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/EventTile.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index c7150da67c..bfcf8ac9d4 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -155,9 +155,11 @@ module.exports = withMatrixClient(React.createClass({ isTwelveHour: PropTypes.bool, }, - defaultProps: { - // no-op function because onWidgetLoad is optional yet some subcomponents assume its existence - onWidgetLoad: function() {}, + getDefaultProps: function() { + return { + // no-op function because onWidgetLoad is optional yet some sub-components assume its existence + onWidgetLoad: function() {}, + }; }, getInitialState: function() { From 4892694e770cb5dea68aea4f19e76f2fd835260e Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 3 May 2018 11:24:10 +0100 Subject: [PATCH 179/190] use more explicit reply fallback closing tag construct to fix 6657 Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/ReplyThread.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index 138431259f..c7ca4b2d41 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -97,7 +97,7 @@ export default class ReplyThread extends React.Component { // Part of Replies fallback support static stripHTMLReply(html) { - return html.replace(/^
[\s\S]+?<\/blockquote>/, ''); + return html.replace(/^
[\s\S]+?<\/blockquote>/, ''); } // Part of Replies fallback support @@ -119,7 +119,7 @@ export default class ReplyThread extends React.Component { case 'm.text': case 'm.notice': { html = `
In reply to ${mxid}` - + `
${html || body}
`; + + `
${html || body}
`; const lines = body.trim().split('\n'); if (lines.length > 0) { lines[0] = `<${mxid}> ${lines[0]}`; @@ -129,27 +129,27 @@ export default class ReplyThread extends React.Component { } case 'm.image': html = `
In reply to ${mxid}` - + `
sent an image.
`; + + `
sent an image.
`; body = `> <${mxid}> sent an image.\n\n`; break; case 'm.video': html = `
In reply to ${mxid}` - + `
sent a video.
`; + + `
sent a video.`; body = `> <${mxid}> sent a video.\n\n`; break; case 'm.audio': html = `
In reply to ${mxid}` - + `
sent an audio file.
`; + + `
sent an audio file.`; body = `> <${mxid}> sent an audio file.\n\n`; break; case 'm.file': html = `
In reply to ${mxid}` - + `
sent a file.
`; + + `
sent a file.`; body = `> <${mxid}> sent a file.\n\n`; break; case 'm.emote': { html = `
In reply to * ` - + `${mxid}
${html || body}
`; + + `${mxid}
${html || body}`; const lines = body.trim().split('\n'); if (lines.length > 0) { lines[0] = `* <${mxid}> ${lines[0]}`; From 22f2d6f292be9a5c4b8b52d973e20ac7b21f688d Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 3 May 2018 14:08:10 +0100 Subject: [PATCH 180/190] Fix crash when browser doesn't report page change measurement --- src/Analytics.js | 9 ++++++--- src/components/structures/MatrixChat.js | 4 ++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/Analytics.js b/src/Analytics.js index 8b55bdfd64..0d1313f48d 100644 --- a/src/Analytics.js +++ b/src/Analytics.js @@ -164,9 +164,13 @@ class Analytics { } trackPageChange(generationTimeMs) { - if (typeof generationTimeMs !== 'number') { - throw new Error('Analytics.trackPageChange: expected generationTimeMs to be a number'); + if (typeof generationTimeMs === 'number') { + this._paq.push(['setGenerationTimeMs', generationTimeMs]); + } else { + console.warn('Analytics.trackPageChange: expected generationTimeMs to be a number'); + // But continue anyway because we still want to track the change } + if (this.disabled) return; if (this.firstPage) { // De-duplicate first page @@ -175,7 +179,6 @@ class Analytics { return; } this._paq.push(['setCustomUrl', getRedactedUrl()]); - this._paq.push(['setGenerationTimeMs', generationTimeMs]); this._paq.push(['trackPageView']); } diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index 8df46d2f7c..3005bc86ad 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -413,6 +413,10 @@ export default React.createClass({ performance.clearMarks('riot_MatrixChat_page_change_start'); performance.clearMarks('riot_MatrixChat_page_change_stop'); const measurement = performance.getEntriesByName('riot_MatrixChat_page_change_delta').pop(); + + // In practice, sometimes the entries list is empty, so we get no measurement + if (!measurement) return null; + return measurement.duration; }, From 97d344483ebec8f622a211c435c6b75686f5fd29 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 3 May 2018 14:32:13 +0100 Subject: [PATCH 181/190] fix thinko when changing from ClientPeg to context in static method (DUH Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/ReplyThread.js | 36 ++++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index c7ca4b2d41..cd444fb090 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -59,22 +59,6 @@ export default class ReplyThread extends React.Component { this.collapse = this.collapse.bind(this); } - static async getEvent(room, eventId) { - const event = room.findEventById(eventId); - if (event) return event; - - try { - // ask the client to fetch the event we want using the context API, only interface to do so is to ask - // for a timeline with that event, but once it is loaded we can use findEventById to look up the ev map - await this.context.matrixClient.getEventTimeline(room.getUnfilteredTimelineSet(), eventId); - } catch (e) { - // if it fails catch the error and return early, there's no point trying to find the event in this case. - // Return null as it is falsey and thus should be treated as an error (as the event cannot be resolved). - return null; - } - return room.findEventById(eventId); - } - static getParentEventId(ev) { if (!ev || ev.isRedacted()) return; @@ -199,7 +183,7 @@ export default class ReplyThread extends React.Component { async initialize() { const {parentEv} = this.props; // at time of making this component we checked that props.parentEv has a parentEventId - const ev = await ReplyThread.getEvent(this.room, ReplyThread.getParentEventId(parentEv)); + const ev = await this.getEvent(ReplyThread.getParentEventId(parentEv)); if (this.unmounted) return; if (ev) { @@ -223,7 +207,7 @@ export default class ReplyThread extends React.Component { return; } - const loadedEv = await ReplyThread.getEvent(this.room, inReplyToEventId); + const loadedEv = await this.getEvent(inReplyToEventId); if (this.unmounted) return; if (loadedEv) { @@ -233,6 +217,22 @@ export default class ReplyThread extends React.Component { } } + async getEvent(eventId) { + const event = this.room.findEventById(eventId); + if (event) return event; + + try { + // ask the client to fetch the event we want using the context API, only interface to do so is to ask + // for a timeline with that event, but once it is loaded we can use findEventById to look up the ev map + await this.context.matrixClient.getEventTimeline(this.room.getUnfilteredTimelineSet(), eventId); + } catch (e) { + // if it fails catch the error and return early, there's no point trying to find the event in this case. + // Return null as it is falsey and thus should be treated as an error (as the event cannot be resolved). + return null; + } + return this.room.findEventById(eventId); + } + canCollapse() { return this.state.events.length > 1; } From 3e55a456019a5016b5e196ac5da7cd987af7a71b Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 3 May 2018 15:24:41 +0100 Subject: [PATCH 182/190] Mock getGroups on MatrixClient for RoomList _makeGroupInviteTiles --- test/test-utils.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/test-utils.js b/test/test-utils.js index e7d3412722..fb21c62170 100644 --- a/test/test-utils.js +++ b/test/test-utils.js @@ -74,6 +74,7 @@ export function createTestClient() { getPushActionsForEvent: sinon.stub(), getRoom: sinon.stub().returns(mkStubRoom()), getRooms: sinon.stub().returns([]), + getGroups: sinon.stub().returns([]), loginFlows: sinon.stub(), on: sinon.stub(), removeListener: sinon.stub(), From 8fcb530e6f677869a5d06b7a5701b231f41174e3 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 3 May 2018 15:25:14 +0100 Subject: [PATCH 183/190] Install lolex for clock mocking in tests --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 1f979369e3..146cb86082 100644 --- a/package.json +++ b/package.json @@ -74,6 +74,7 @@ "isomorphic-fetch": "^2.2.1", "linkifyjs": "^2.1.3", "lodash": "^4.13.1", + "lolex": "^2.3.2", "matrix-js-sdk": "0.10.1", "optimist": "^0.6.1", "pako": "^1.0.5", From 80d251b6223077e03c6cbaf85674e4967e6f6730 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 3 May 2018 15:41:35 +0100 Subject: [PATCH 184/190] Add tests for optimistic updates of moving room tiles --- test/components/views/rooms/RoomList-test.js | 185 +++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 test/components/views/rooms/RoomList-test.js diff --git a/test/components/views/rooms/RoomList-test.js b/test/components/views/rooms/RoomList-test.js new file mode 100644 index 0000000000..bb92d59201 --- /dev/null +++ b/test/components/views/rooms/RoomList-test.js @@ -0,0 +1,185 @@ +import React from 'react'; +import ReactTestUtils from 'react-addons-test-utils'; +import ReactDOM from 'react-dom'; +import expect from 'expect'; +import lolex from 'lolex'; + +import * as TestUtils from 'test-utils'; + +import sdk from '../../../../src/index'; +import MatrixClientPeg from '../../../../src/MatrixClientPeg'; +import { DragDropContext } from 'react-beautiful-dnd'; + +import dis from '../../../../src/dispatcher'; +import DMRoomMap from '../../../../src/utils/DMRoomMap.js'; + +import { Room, RoomMember } from 'matrix-js-sdk'; + +describe('RoomList', () => { + let parentDiv = null; + let sandbox = null; + let client = null; + let root = null; + const myUserId = '@me:domain'; + let clock = null; + + beforeEach(function() { + TestUtils.beforeEach(this); + sandbox = TestUtils.stubClient(sandbox); + client = MatrixClientPeg.get(); + client.credentials = {userId: myUserId}; + + clock = lolex.install(); + + DMRoomMap.makeShared(); + + parentDiv = document.createElement('div'); + document.body.appendChild(parentDiv); + + const RoomList = sdk.getComponent('views.rooms.RoomList'); + const WrappedRoomList = TestUtils.wrapInMatrixClientContext(RoomList); + root = ReactDOM.render( + + + + , parentDiv); + ReactTestUtils.findRenderedComponentWithType(root, RoomList); + }); + + afterEach((done) => { + if (parentDiv) { + ReactDOM.unmountComponentAtNode(parentDiv); + parentDiv.remove(); + parentDiv = null; + } + sandbox.restore(); + + clock.uninstall(); + + done(); + }); + + describe('when no tags are selected', () => { + describe('does correct optimistic update when dragging from', () => { + const movingRoomId = '!someroomid'; + const movingRoom = new Room(movingRoomId); + + // Mock joined member + const myMember = new RoomMember(movingRoomId, myUserId); + myMember.membership = 'join'; + movingRoom.getMember = (userId) => ({ + [client.credentials.userId]: myMember, + }[userId]); + + function expectRoomInSubList(room, subListTest) { + const RoomSubList = sdk.getComponent('structures.RoomSubList'); + const RoomTile = sdk.getComponent('views.rooms.RoomTile'); + + const subLists = ReactTestUtils.scryRenderedComponentsWithType(root, RoomSubList); + const containingSubList = subLists.find(subListTest); + + let expectedRoomTile; + try { + expectedRoomTile = ReactTestUtils.findRenderedComponentWithType(containingSubList, RoomTile); + } catch (err) { + // truncate the error message because it's spammy + err.message = 'Error finding RoomTile: ' + err.message.split('componentType')[0] + '...'; + throw err; + } + + expect(expectedRoomTile).toExist(); + expect(expectedRoomTile.props.room).toBe(room); + } + + function expectCorrectMove(oldTag, newTag) { + const getTagSubListTest = (tag) => { + if (tag === undefined) return (s) => s.props.label.endsWith('Rooms'); + return (s) => s.props.tagName === tag; + }; + + // Default to finding the destination sublist with newTag + const destSubListTest = getTagSubListTest(newTag); + const srcSubListTest = getTagSubListTest(oldTag); + + // Mock the matrix client + client.getRooms = () => [movingRoom]; + + if (['m.favourite', 'm.lowpriority'].includes(oldTag)) movingRoom.tags = {[oldTag]: {}}; + if (oldTag === 'im.vector.fake.direct') { + // Mock inverse m.direct + DMRoomMap.shared().roomToUser = { + [movingRoom.roomId]: '@someotheruser:domain', + }; + } + + dis.dispatch({action: 'MatrixActions.sync', prevState: null, state: 'PREPARED', matrixClient: client}); + + clock.runAll(); + + expectRoomInSubList(movingRoom, srcSubListTest); + + dis.dispatch({action: 'RoomListActions.tagRoom.pending', request: { + oldTag, newTag, room: movingRoom, + }}); + + // Run all setTimeouts for dispatches and room list rate limiting + clock.runAll(); + + expectRoomInSubList(movingRoom, destSubListTest); + } + + it('rooms to people', () => { + expectCorrectMove(undefined, 'im.vector.fake.direct'); + }); + + it('rooms to favourites', () => { + expectCorrectMove(undefined, 'm.favourite'); + }); + + it('rooms to low priority', () => { + expectCorrectMove(undefined, 'm.lowpriority'); + }); + + // XXX: Known to fail - the view does not update immediately to reflect the change. + // Whe running the app live, it updates when some other event occurs (likely the + // m.direct arriving) that these tests do not fire. + xit('people to rooms', () => { + expectCorrectMove('im.vector.fake.direct', undefined); + }); + + it('people to favourites', () => { + expectCorrectMove('im.vector.fake.direct', 'm.favourite'); + }); + + it('people to lowpriority', () => { + expectCorrectMove('im.vector.fake.direct', 'm.lowpriority'); + }); + + it('low priority to rooms', () => { + expectCorrectMove('m.lowpriority', undefined); + }); + + it('low priority to people', () => { + expectCorrectMove('m.lowpriority', 'im.vector.fake.direct'); + }); + + it('low priority to low priority', () => { + expectCorrectMove('m.lowpriority', 'm.lowpriority'); + }); + + it('favourites to rooms', () => { + expectCorrectMove('m.favourite', undefined); + }); + + it('favourites to people', () => { + expectCorrectMove('m.favourite', 'im.vector.fake.direct'); + }); + + it('favourites to low priority', () => { + expectCorrectMove('m.favourite', 'm.lowpriority'); + }); + }); + }); +}); + + From e15b39092dd70b0ddb7ba3b3d007ec30d406c379 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 3 May 2018 18:04:01 +0100 Subject: [PATCH 185/190] Add tests for testing room tile updates when tags (groups in LLP) are selected --- test/components/views/rooms/RoomList-test.js | 244 +++++++++++++------ 1 file changed, 176 insertions(+), 68 deletions(-) diff --git a/test/components/views/rooms/RoomList-test.js b/test/components/views/rooms/RoomList-test.js index bb92d59201..f40a89777b 100644 --- a/test/components/views/rooms/RoomList-test.js +++ b/test/components/views/rooms/RoomList-test.js @@ -12,9 +12,22 @@ import { DragDropContext } from 'react-beautiful-dnd'; import dis from '../../../../src/dispatcher'; import DMRoomMap from '../../../../src/utils/DMRoomMap.js'; +import GroupStore from '../../../../src/stores/GroupStore.js'; import { Room, RoomMember } from 'matrix-js-sdk'; +function generateRoomId() { + return '!' + Math.random().toString().slice(2, 10) + ':domain'; +} + +function createRoom(opts) { + const room = new Room(generateRoomId()); + if (opts) { + Object.assign(room, opts); + } + return room; +} + describe('RoomList', () => { let parentDiv = null; let sandbox = null; @@ -23,6 +36,13 @@ describe('RoomList', () => { const myUserId = '@me:domain'; let clock = null; + const movingRoomId = '!someroomid'; + let movingRoom; + let otherRoom; + + let myMember; + let myOtherMember; + beforeEach(function() { TestUtils.beforeEach(this); sandbox = TestUtils.stubClient(sandbox); @@ -44,6 +64,40 @@ describe('RoomList', () => { , parentDiv); ReactTestUtils.findRenderedComponentWithType(root, RoomList); + + movingRoom = createRoom({name: 'Moving room'}); + expect(movingRoom.roomId).toNotBe(null); + + // Mock joined member + myMember = new RoomMember(movingRoomId, myUserId); + myMember.membership = 'join'; + movingRoom.getMember = (userId) => ({ + [client.credentials.userId]: myMember, + }[userId]); + + otherRoom = createRoom({name: 'Other room'}); + myOtherMember = new RoomMember(otherRoom.roomId, myUserId); + myOtherMember.membership = 'join'; + otherRoom.getMember = (userId) => ({ + [client.credentials.userId]: myOtherMember, + }[userId]); + + // Mock the matrix client + client.getRooms = () => [ + movingRoom, + otherRoom, + createRoom({tags: {'m.favourite': {order: 0.1}}, name: 'Some other room'}), + createRoom({tags: {'m.favourite': {order: 0.2}}, name: 'Some other room 2'}), + createRoom({tags: {'m.lowpriority': {}}, name: 'Some unimportant room'}), + createRoom({tags: {'custom.tag': {}}, name: 'Some room customly tagged'}), + ]; + + const roomMap = {}; + client.getRooms().forEach((r) => { + roomMap[r.roomId] = r; + }); + + client.getRoom = (roomId) => roomMap[roomId]; }); afterEach((done) => { @@ -59,75 +113,68 @@ describe('RoomList', () => { done(); }); - describe('when no tags are selected', () => { + function expectRoomInSubList(room, subListTest) { + const RoomSubList = sdk.getComponent('structures.RoomSubList'); + const RoomTile = sdk.getComponent('views.rooms.RoomTile'); + + const subLists = ReactTestUtils.scryRenderedComponentsWithType(root, RoomSubList); + const containingSubList = subLists.find(subListTest); + + let expectedRoomTile; + try { + const roomTiles = ReactTestUtils.scryRenderedComponentsWithType(containingSubList, RoomTile); + console.info({roomTiles: roomTiles.length}); + expectedRoomTile = roomTiles.find((tile) => tile.props.room === room); + } catch (err) { + // truncate the error message because it's spammy + err.message = 'Error finding RoomTile for ' + room.roomId + ' in ' + + subListTest + ': ' + + err.message.split('componentType')[0] + '...'; + throw err; + } + + expect(expectedRoomTile).toExist(); + expect(expectedRoomTile.props.room).toBe(room); + } + + function expectCorrectMove(oldTag, newTag) { + const getTagSubListTest = (tag) => { + if (tag === undefined) return (s) => s.props.label.endsWith('Rooms'); + return (s) => s.props.tagName === tag; + }; + + // Default to finding the destination sublist with newTag + const destSubListTest = getTagSubListTest(newTag); + const srcSubListTest = getTagSubListTest(oldTag); + + // Set up the room that will be moved such that it has the correct state for a room in + // the section for oldTag + if (['m.favourite', 'm.lowpriority'].includes(oldTag)) movingRoom.tags = {[oldTag]: {}}; + if (oldTag === 'im.vector.fake.direct') { + // Mock inverse m.direct + DMRoomMap.shared().roomToUser = { + [movingRoom.roomId]: '@someotheruser:domain', + }; + } + + dis.dispatch({action: 'MatrixActions.sync', prevState: null, state: 'PREPARED', matrixClient: client}); + + clock.runAll(); + + expectRoomInSubList(movingRoom, srcSubListTest); + + dis.dispatch({action: 'RoomListActions.tagRoom.pending', request: { + oldTag, newTag, room: movingRoom, + }}); + + // Run all setTimeouts for dispatches and room list rate limiting + clock.runAll(); + + expectRoomInSubList(movingRoom, destSubListTest); + } + + function itDoesCorrectOptimisticUpdatesForDraggedRoomTiles() { describe('does correct optimistic update when dragging from', () => { - const movingRoomId = '!someroomid'; - const movingRoom = new Room(movingRoomId); - - // Mock joined member - const myMember = new RoomMember(movingRoomId, myUserId); - myMember.membership = 'join'; - movingRoom.getMember = (userId) => ({ - [client.credentials.userId]: myMember, - }[userId]); - - function expectRoomInSubList(room, subListTest) { - const RoomSubList = sdk.getComponent('structures.RoomSubList'); - const RoomTile = sdk.getComponent('views.rooms.RoomTile'); - - const subLists = ReactTestUtils.scryRenderedComponentsWithType(root, RoomSubList); - const containingSubList = subLists.find(subListTest); - - let expectedRoomTile; - try { - expectedRoomTile = ReactTestUtils.findRenderedComponentWithType(containingSubList, RoomTile); - } catch (err) { - // truncate the error message because it's spammy - err.message = 'Error finding RoomTile: ' + err.message.split('componentType')[0] + '...'; - throw err; - } - - expect(expectedRoomTile).toExist(); - expect(expectedRoomTile.props.room).toBe(room); - } - - function expectCorrectMove(oldTag, newTag) { - const getTagSubListTest = (tag) => { - if (tag === undefined) return (s) => s.props.label.endsWith('Rooms'); - return (s) => s.props.tagName === tag; - }; - - // Default to finding the destination sublist with newTag - const destSubListTest = getTagSubListTest(newTag); - const srcSubListTest = getTagSubListTest(oldTag); - - // Mock the matrix client - client.getRooms = () => [movingRoom]; - - if (['m.favourite', 'm.lowpriority'].includes(oldTag)) movingRoom.tags = {[oldTag]: {}}; - if (oldTag === 'im.vector.fake.direct') { - // Mock inverse m.direct - DMRoomMap.shared().roomToUser = { - [movingRoom.roomId]: '@someotheruser:domain', - }; - } - - dis.dispatch({action: 'MatrixActions.sync', prevState: null, state: 'PREPARED', matrixClient: client}); - - clock.runAll(); - - expectRoomInSubList(movingRoom, srcSubListTest); - - dis.dispatch({action: 'RoomListActions.tagRoom.pending', request: { - oldTag, newTag, room: movingRoom, - }}); - - // Run all setTimeouts for dispatches and room list rate limiting - clock.runAll(); - - expectRoomInSubList(movingRoom, destSubListTest); - } - it('rooms to people', () => { expectCorrectMove(undefined, 'im.vector.fake.direct'); }); @@ -179,6 +226,67 @@ describe('RoomList', () => { expectCorrectMove('m.favourite', 'm.lowpriority'); }); }); + } + + describe('when no tags are selected', () => { + itDoesCorrectOptimisticUpdatesForDraggedRoomTiles(); + }); + + describe('when tags are selected', () => { + function setupSelectedTag() { + // Simulate a complete sync BEFORE dispatching anything else + dis.dispatch({ + action: 'MatrixActions.sync', + prevState: null, + state: 'PREPARED', + matrixClient: client, + }, true); + + // Simulate joined groups being received + dis.dispatch({ + action: 'GroupActions.fetchJoinedGroups.success', + result: { + groups: ['+group:domain'], + }, + }, true); + + // Simulate receiving tag ordering account data + dis.dispatch({ + action: 'MatrixActions.accountData', + event_type: 'im.vector.web.tag_ordering', + event_content: { + tags: ['+group:domain'], + }, + }, true); + + // GroupStore is not flux, mock and notify + GroupStore.getGroupRooms = (groupId) => { + return [movingRoom]; + }; + GroupStore._notifyListeners(); + + // Select tag + dis.dispatch({action: 'select_tag', tag: '+group:domain'}, true); + } + + beforeEach(() => { + setupSelectedTag(); + }); + + it('displays the correct rooms when the groups rooms are changed', () => { + GroupStore.getGroupRooms = (groupId) => { + return [movingRoom, otherRoom]; + }; + GroupStore._notifyListeners(); + + // Run through RoomList debouncing + clock.runAll(); + + // By default, the test will + expectRoomInSubList(otherRoom, (s) => s.props.label.endsWith('Rooms')); + }); + + itDoesCorrectOptimisticUpdatesForDraggedRoomTiles(); }); }); From c06a04af97de05698e6e15773843c0c237deafd7 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 3 May 2018 18:11:32 +0100 Subject: [PATCH 186/190] Fix unrelated linting issue --- test/components/structures/GroupView-test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/components/structures/GroupView-test.js b/test/components/structures/GroupView-test.js index 76baafe1c8..3b3510f26e 100644 --- a/test/components/structures/GroupView-test.js +++ b/test/components/structures/GroupView-test.js @@ -18,7 +18,6 @@ import React from 'react'; import ReactDOM from 'react-dom'; import ReactTestUtils from 'react-dom/test-utils'; import expect from 'expect'; -import Promise from 'bluebird'; import MockHttpBackend from 'matrix-mock-request'; import MatrixClientPeg from '../../../src/MatrixClientPeg'; From 3ba51ba69586f9a015fdb5dc265445ca0b22ad2c Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 3 May 2018 18:25:00 +0100 Subject: [PATCH 187/190] Null check before accessing _paq --- src/Analytics.js | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/Analytics.js b/src/Analytics.js index 0d1313f48d..ec8234eb83 100644 --- a/src/Analytics.js +++ b/src/Analytics.js @@ -164,13 +164,6 @@ class Analytics { } trackPageChange(generationTimeMs) { - if (typeof generationTimeMs === 'number') { - this._paq.push(['setGenerationTimeMs', generationTimeMs]); - } else { - console.warn('Analytics.trackPageChange: expected generationTimeMs to be a number'); - // But continue anyway because we still want to track the change - } - if (this.disabled) return; if (this.firstPage) { // De-duplicate first page @@ -178,6 +171,14 @@ class Analytics { this.firstPage = false; return; } + + if (typeof generationTimeMs === 'number') { + this._paq.push(['setGenerationTimeMs', generationTimeMs]); + } else { + console.warn('Analytics.trackPageChange: expected generationTimeMs to be a number'); + // But continue anyway because we still want to track the change + } + this._paq.push(['setCustomUrl', getRedactedUrl()]); this._paq.push(['trackPageView']); } From 14bcfdd5c60a3dfe069c468c64164ed5ba0065f7 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sat, 5 May 2018 22:08:37 +0100 Subject: [PATCH 188/190] fix NPE --- src/components/views/messages/MImageBody.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index a42e45c55d..b50b7a114c 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -161,7 +161,10 @@ export default class extends React.Component { return this.state.decryptedThumbnailUrl; } return this.state.decryptedUrl; - } else if (content.info.mimetype == "image/svg+xml" && content.info.thumbnail_url) { + } else if (content.info && + content.info.mimetype == "image/svg+xml" && + content.info.thumbnail_url) + { // special case to return client-generated thumbnails for SVGs, if any, // given we deliberately don't thumbnail them serverside to prevent // billion lol attacks and similar From ccd99f4a49105359de874af0a3aafd6cddeea31c Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sat, 5 May 2018 22:27:54 +0100 Subject: [PATCH 189/190] increase max-warnings temporarily --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index aad9739770..b0f0d26c56 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "start": "parallelshell \"npm run build:watch\" \"npm run reskindex:watch\"", "lint": "eslint src/", "lintall": "eslint src/ test/", - "lintwithexclusions": "eslint --max-warnings 10 --ignore-path .eslintignore.errorfiles src test", + "lintwithexclusions": "eslint --max-warnings 20 --ignore-path .eslintignore.errorfiles src test", "clean": "rimraf lib", "prepublish": "npm run clean && npm run build && git rev-parse HEAD > git-revision.txt", "test": "karma start --single-run=true --browsers ChromeHeadless", From af5be5c36c518627fa40342818efec1e0dd1e938 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sat, 5 May 2018 22:28:09 +0100 Subject: [PATCH 190/190] appease the fascist linter --- src/components/views/messages/MImageBody.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index b50b7a114c..6cc492acf8 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -163,8 +163,7 @@ export default class extends React.Component { return this.state.decryptedUrl; } else if (content.info && content.info.mimetype == "image/svg+xml" && - content.info.thumbnail_url) - { + content.info.thumbnail_url) { // special case to return client-generated thumbnails for SVGs, if any, // given we deliberately don't thumbnail them serverside to prevent // billion lol attacks and similar