From b26779801040455b8c6ecfc1a9ab058edfd7f156 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 13 Aug 2018 19:15:42 +0100 Subject: [PATCH 01/77] Kill FuzzyMatcher This has been commented out for ages. Just remove it and make things use QueryMatcher directly rather than looking like they do fuzzy matching but not. --- src/autocomplete/CommandProvider.js | 4 +- src/autocomplete/CommunityProvider.js | 4 +- src/autocomplete/EmojiProvider.js | 6 +- src/autocomplete/FuzzyMatcher.js | 107 -------------------------- src/autocomplete/RoomProvider.js | 4 +- src/autocomplete/UserProvider.js | 8 +- 6 files changed, 14 insertions(+), 119 deletions(-) delete mode 100644 src/autocomplete/FuzzyMatcher.js diff --git a/src/autocomplete/CommandProvider.js b/src/autocomplete/CommandProvider.js index a35a31966a..609a8fa9a1 100644 --- a/src/autocomplete/CommandProvider.js +++ b/src/autocomplete/CommandProvider.js @@ -20,7 +20,7 @@ limitations under the License. import React from 'react'; import {_t} from '../languageHandler'; import AutocompleteProvider from './AutocompleteProvider'; -import FuzzyMatcher from './FuzzyMatcher'; +import QueryMatcher from './QueryMatcher'; import {TextualCompletion} from './Components'; import type {Completion, SelectionRange} from "./Autocompleter"; import {CommandMap} from '../SlashCommands'; @@ -32,7 +32,7 @@ const COMMAND_RE = /(^\/\w*)(?: .*)?/g; export default class CommandProvider extends AutocompleteProvider { constructor() { super(COMMAND_RE); - this.matcher = new FuzzyMatcher(COMMANDS, { + this.matcher = new QueryMatcher(COMMANDS, { keys: ['command', 'args', 'description'], }); } diff --git a/src/autocomplete/CommunityProvider.js b/src/autocomplete/CommunityProvider.js index 6bcf1a02fd..d164fab46a 100644 --- a/src/autocomplete/CommunityProvider.js +++ b/src/autocomplete/CommunityProvider.js @@ -19,7 +19,7 @@ import React from 'react'; import { _t } from '../languageHandler'; import AutocompleteProvider from './AutocompleteProvider'; import MatrixClientPeg from '../MatrixClientPeg'; -import FuzzyMatcher from './FuzzyMatcher'; +import QueryMatcher from './QueryMatcher'; import {PillCompletion} from './Components'; import sdk from '../index'; import _sortBy from 'lodash/sortBy'; @@ -41,7 +41,7 @@ function score(query, space) { export default class CommunityProvider extends AutocompleteProvider { constructor() { super(COMMUNITY_REGEX); - this.matcher = new FuzzyMatcher([], { + this.matcher = new QueryMatcher([], { keys: ['groupId', 'name', 'shortDescription'], }); } diff --git a/src/autocomplete/EmojiProvider.js b/src/autocomplete/EmojiProvider.js index 719550d59f..8c6495101f 100644 --- a/src/autocomplete/EmojiProvider.js +++ b/src/autocomplete/EmojiProvider.js @@ -20,7 +20,7 @@ import React from 'react'; import { _t } from '../languageHandler'; import AutocompleteProvider from './AutocompleteProvider'; import {shortnameToUnicode, asciiRegexp, unicodeRegexp} from 'emojione'; -import FuzzyMatcher from './FuzzyMatcher'; +import QueryMatcher from './QueryMatcher'; import sdk from '../index'; import {PillCompletion} from './Components'; import type {Completion, SelectionRange} from './Autocompleter'; @@ -84,12 +84,12 @@ function score(query, space) { export default class EmojiProvider extends AutocompleteProvider { constructor() { super(EMOJI_REGEX); - this.matcher = new FuzzyMatcher(EMOJI_SHORTNAMES, { + this.matcher = new QueryMatcher(EMOJI_SHORTNAMES, { keys: ['aliases_ascii', 'shortname', 'aliases'], // For matching against ascii equivalents shouldMatchWordsOnly: false, }); - this.nameMatcher = new FuzzyMatcher(EMOJI_SHORTNAMES, { + this.nameMatcher = new QueryMatcher(EMOJI_SHORTNAMES, { keys: ['name'], // For removing punctuation shouldMatchWordsOnly: true, diff --git a/src/autocomplete/FuzzyMatcher.js b/src/autocomplete/FuzzyMatcher.js deleted file mode 100644 index 1aa0782c22..0000000000 --- a/src/autocomplete/FuzzyMatcher.js +++ /dev/null @@ -1,107 +0,0 @@ -/* -Copyright 2017 Aviral Dasgupta - -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 Levenshtein from 'liblevenshtein'; -//import _at from 'lodash/at'; -//import _flatMap from 'lodash/flatMap'; -//import _sortBy from 'lodash/sortBy'; -//import _sortedUniq from 'lodash/sortedUniq'; -//import _keys from 'lodash/keys'; -// -//class KeyMap { -// keys: Array; -// objectMap: {[String]: Array}; -// priorityMap: {[String]: number} -//} -// -//const DEFAULT_RESULT_COUNT = 10; -//const DEFAULT_DISTANCE = 5; - -// FIXME Until Fuzzy matching works better, we use prefix matching. - -import PrefixMatcher from './QueryMatcher'; -export default PrefixMatcher; - -//class FuzzyMatcher { // eslint-disable-line no-unused-vars -// /** -// * @param {object[]} objects the objects to perform a match on -// * @param {string[]} keys an array of keys within each object to match on -// * Keys can refer to object properties by name and as in JavaScript (for nested properties) -// * -// * To use, simply presort objects by required criteria, run through this function and create a FuzzyMatcher with the -// * resulting KeyMap. -// * -// * TODO: Handle arrays and objects (Fuse did this, RoomProvider uses it) -// * @return {KeyMap} -// */ -// static valuesToKeyMap(objects: Array, keys: Array): KeyMap { -// const keyMap = new KeyMap(); -// const map = {}; -// const priorities = {}; -// -// objects.forEach((object, i) => { -// const keyValues = _at(object, keys); -// console.log(object, keyValues, keys); -// for (const keyValue of keyValues) { -// if (!map.hasOwnProperty(keyValue)) { -// map[keyValue] = []; -// } -// map[keyValue].push(object); -// } -// priorities[object] = i; -// }); -// -// keyMap.objectMap = map; -// keyMap.priorityMap = priorities; -// keyMap.keys = _sortBy(_keys(map), [(value) => priorities[value]]); -// return keyMap; -// } -// -// constructor(objects: Array, options: {[Object]: Object} = {}) { -// this.options = options; -// this.keys = options.keys; -// this.setObjects(objects); -// } -// -// setObjects(objects: Array) { -// this.keyMap = FuzzyMatcher.valuesToKeyMap(objects, this.keys); -// console.log(this.keyMap.keys); -// this.matcher = new Levenshtein.Builder() -// .dictionary(this.keyMap.keys, true) -// .algorithm('transposition') -// .sort_candidates(false) -// .case_insensitive_sort(true) -// .include_distance(true) -// .maximum_candidates(this.options.resultCount || DEFAULT_RESULT_COUNT) // result count 0 doesn't make much sense -// .build(); -// } -// -// match(query: String): Array { -// const candidates = this.matcher.transduce(query, this.options.distance || DEFAULT_DISTANCE); -// // TODO FIXME This is hideous. Clean up when possible. -// const val = _sortedUniq(_sortBy(_flatMap(candidates, (candidate) => { -// return this.keyMap.objectMap[candidate[0]].map((value) => { -// return { -// distance: candidate[1], -// ...value, -// }; -// }); -// }), -// [(candidate) => candidate.distance, (candidate) => this.keyMap.priorityMap[candidate]])); -// console.log(val); -// return val; -// } -//} diff --git a/src/autocomplete/RoomProvider.js b/src/autocomplete/RoomProvider.js index 38e2ab8373..483506557f 100644 --- a/src/autocomplete/RoomProvider.js +++ b/src/autocomplete/RoomProvider.js @@ -21,7 +21,7 @@ import React from 'react'; import { _t } from '../languageHandler'; import AutocompleteProvider from './AutocompleteProvider'; import MatrixClientPeg from '../MatrixClientPeg'; -import FuzzyMatcher from './FuzzyMatcher'; +import QueryMatcher from './QueryMatcher'; import {PillCompletion} from './Components'; import {getDisplayAliasForRoom} from '../Rooms'; import sdk from '../index'; @@ -43,7 +43,7 @@ function score(query, space) { export default class RoomProvider extends AutocompleteProvider { constructor() { super(ROOM_REGEX); - this.matcher = new FuzzyMatcher([], { + this.matcher = new QueryMatcher([], { keys: ['displayedAlias', 'name'], }); } diff --git a/src/autocomplete/UserProvider.js b/src/autocomplete/UserProvider.js index e9cbf7945b..ed9c8ee62b 100644 --- a/src/autocomplete/UserProvider.js +++ b/src/autocomplete/UserProvider.js @@ -23,7 +23,7 @@ import { _t } from '../languageHandler'; import AutocompleteProvider from './AutocompleteProvider'; import {PillCompletion} from './Components'; import sdk from '../index'; -import FuzzyMatcher from './FuzzyMatcher'; +import QueryMatcher from './QueryMatcher'; import _sortBy from 'lodash/sortBy'; import MatrixClientPeg from '../MatrixClientPeg'; @@ -44,7 +44,7 @@ export default class UserProvider extends AutocompleteProvider { constructor(room) { super(USER_REGEX, FORCED_USER_REGEX); this.room = room; - this.matcher = new FuzzyMatcher([], { + this.matcher = new QueryMatcher([], { keys: ['name', 'userId'], shouldMatchPrefix: true, shouldMatchWordsOnly: false, @@ -104,7 +104,9 @@ export default class UserProvider extends AutocompleteProvider { const fullMatch = command[0]; // Don't search if the query is a single "@" if (fullMatch && fullMatch !== '@') { - completions = this.matcher.match(fullMatch).map((user) => { + // Don't include the '@' in our search query - it's only used as a way to trigger completion + const query = fullMatch.startsWith('@') ? fullMatch.substring(1) : fullMatch; + completions = this.matcher.match(query).map((user) => { const displayName = (user.name || user.userId || ''); return { // Length of completion should equal length of text in decorator. draft-js From c5ff0b1d6b011e954958b2d00d1cf05f8b834f4c Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 11 Oct 2018 15:34:40 +0100 Subject: [PATCH 02/77] js-sdk rc.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e699c0f887..67faa09420 100644 --- a/package.json +++ b/package.json @@ -75,7 +75,7 @@ "linkifyjs": "^2.1.6", "lodash": "^4.13.1", "lolex": "2.3.2", - "matrix-js-sdk": "0.11.1", + "matrix-js-sdk": "0.12.0-rc.1", "optimist": "^0.6.1", "pako": "^1.0.5", "prop-types": "^15.5.8", From ab35dac6e14b80fd3863915bce0567784950b180 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 11 Oct 2018 15:37:17 +0100 Subject: [PATCH 03/77] Prepare changelog for v0.14.0-rc.1 --- CHANGELOG.md | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a52034d305..191651ad36 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,64 @@ +Changes in [0.14.0-rc.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.14.0-rc.1) (2018-10-11) +=============================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.13.6...v0.14.0-rc.1) + + * turn LL on by default! + [\#2209](https://github.com/matrix-org/matrix-react-sdk/pull/2209) + * Update from Weblate. + [\#2207](https://github.com/matrix-org/matrix-react-sdk/pull/2207) + * Fix quote post slate update + [\#2206](https://github.com/matrix-org/matrix-react-sdk/pull/2206) + * Handle InvalidStoreError from js-sdk + [\#2205](https://github.com/matrix-org/matrix-react-sdk/pull/2205) + * Fall back to default avatar in RR when member isn't loaded yet + [\#2204](https://github.com/matrix-org/matrix-react-sdk/pull/2204) + * Update to new version of slate + [\#2202](https://github.com/matrix-org/matrix-react-sdk/pull/2202) + * Update karma to webpack 4 + [\#2203](https://github.com/matrix-org/matrix-react-sdk/pull/2203) + * More accessible buttons - take 2 + [\#2194](https://github.com/matrix-org/matrix-react-sdk/pull/2194) + * log correct error code when opening log idb + [\#2200](https://github.com/matrix-org/matrix-react-sdk/pull/2200) + * show warning when LL is disabled but was enabled before + [\#2201](https://github.com/matrix-org/matrix-react-sdk/pull/2201) + * Fall back to another store if indexeddb start fails + [\#2195](https://github.com/matrix-org/matrix-react-sdk/pull/2195) + * Silence bluebird warnings + [\#2198](https://github.com/matrix-org/matrix-react-sdk/pull/2198) + * Use createObjectURL instead of readAsDataURL for videos + [\#2197](https://github.com/matrix-org/matrix-react-sdk/pull/2197) + * Revert "Use createObjectURL instead of readAsDataURL for videos" + [\#2196](https://github.com/matrix-org/matrix-react-sdk/pull/2196) + * Track how far the user travels before dismissing their user settings + [\#2183](https://github.com/matrix-org/matrix-react-sdk/pull/2183) + * Drop (IRC) suffix hacks + [\#2193](https://github.com/matrix-org/matrix-react-sdk/pull/2193) + * Use createObjectURL instead of readAsDataURL for videos + [\#2176](https://github.com/matrix-org/matrix-react-sdk/pull/2176) + * Remove old migration code + [\#2192](https://github.com/matrix-org/matrix-react-sdk/pull/2192) + * Fix brace style in TextForEvent.js + [\#2191](https://github.com/matrix-org/matrix-react-sdk/pull/2191) + * Fix error logging + [\#2190](https://github.com/matrix-org/matrix-react-sdk/pull/2190) + * Fix Promise.defer warning in ScalarAuthClient.js + [\#2188](https://github.com/matrix-org/matrix-react-sdk/pull/2188) + * Communicate early that a 3pid is required during registration if needed + [\#2180](https://github.com/matrix-org/matrix-react-sdk/pull/2180) + * try to encourage people to attach logs to bugs + [\#2185](https://github.com/matrix-org/matrix-react-sdk/pull/2185) + * Show the 'homeserver unavailable' warning when the first sync fails + [\#2182](https://github.com/matrix-org/matrix-react-sdk/pull/2182) + * allow passing initial is_url like hs_url in query params + [\#2083](https://github.com/matrix-org/matrix-react-sdk/pull/2083) + * Update karma + [\#2177](https://github.com/matrix-org/matrix-react-sdk/pull/2177) + * fudge hangup reasons + [\#2184](https://github.com/matrix-org/matrix-react-sdk/pull/2184) + * Provide more helpful errors when i18n generation fails + [\#2181](https://github.com/matrix-org/matrix-react-sdk/pull/2181) + Changes in [0.13.6](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.13.6) (2018-10-08) ===================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.13.5...v0.13.6) From 15f08ab0a18704a70c381c01a3154862358ec66d Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 11 Oct 2018 15:39:55 +0100 Subject: [PATCH 04/77] Prepare changelog for v0.14.0-rc.1 --- CHANGELOG.md | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 191651ad36..d4f2c4efa4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,6 +59,67 @@ Changes in [0.14.0-rc.1](https://github.com/matrix-org/matrix-react-sdk/releases * Provide more helpful errors when i18n generation fails [\#2181](https://github.com/matrix-org/matrix-react-sdk/pull/2181) +Changes in [0.14.0-rc.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.14.0-rc.1) (2018-10-11) +=============================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.13.6...v0.14.0-rc.1) + + * turn LL on by default! + [\#2209](https://github.com/matrix-org/matrix-react-sdk/pull/2209) + * Update from Weblate. + [\#2207](https://github.com/matrix-org/matrix-react-sdk/pull/2207) + * Fix quote post slate update + [\#2206](https://github.com/matrix-org/matrix-react-sdk/pull/2206) + * Handle InvalidStoreError from js-sdk + [\#2205](https://github.com/matrix-org/matrix-react-sdk/pull/2205) + * Fall back to default avatar in RR when member isn't loaded yet + [\#2204](https://github.com/matrix-org/matrix-react-sdk/pull/2204) + * Update to new version of slate + [\#2202](https://github.com/matrix-org/matrix-react-sdk/pull/2202) + * Update karma to webpack 4 + [\#2203](https://github.com/matrix-org/matrix-react-sdk/pull/2203) + * More accessible buttons - take 2 + [\#2194](https://github.com/matrix-org/matrix-react-sdk/pull/2194) + * log correct error code when opening log idb + [\#2200](https://github.com/matrix-org/matrix-react-sdk/pull/2200) + * show warning when LL is disabled but was enabled before + [\#2201](https://github.com/matrix-org/matrix-react-sdk/pull/2201) + * Fall back to another store if indexeddb start fails + [\#2195](https://github.com/matrix-org/matrix-react-sdk/pull/2195) + * Silence bluebird warnings + [\#2198](https://github.com/matrix-org/matrix-react-sdk/pull/2198) + * Use createObjectURL instead of readAsDataURL for videos + [\#2197](https://github.com/matrix-org/matrix-react-sdk/pull/2197) + * Revert "Use createObjectURL instead of readAsDataURL for videos" + [\#2196](https://github.com/matrix-org/matrix-react-sdk/pull/2196) + * Track how far the user travels before dismissing their user settings + [\#2183](https://github.com/matrix-org/matrix-react-sdk/pull/2183) + * Drop (IRC) suffix hacks + [\#2193](https://github.com/matrix-org/matrix-react-sdk/pull/2193) + * Use createObjectURL instead of readAsDataURL for videos + [\#2176](https://github.com/matrix-org/matrix-react-sdk/pull/2176) + * Remove old migration code + [\#2192](https://github.com/matrix-org/matrix-react-sdk/pull/2192) + * Fix brace style in TextForEvent.js + [\#2191](https://github.com/matrix-org/matrix-react-sdk/pull/2191) + * Fix error logging + [\#2190](https://github.com/matrix-org/matrix-react-sdk/pull/2190) + * Fix Promise.defer warning in ScalarAuthClient.js + [\#2188](https://github.com/matrix-org/matrix-react-sdk/pull/2188) + * Communicate early that a 3pid is required during registration if needed + [\#2180](https://github.com/matrix-org/matrix-react-sdk/pull/2180) + * try to encourage people to attach logs to bugs + [\#2185](https://github.com/matrix-org/matrix-react-sdk/pull/2185) + * Show the 'homeserver unavailable' warning when the first sync fails + [\#2182](https://github.com/matrix-org/matrix-react-sdk/pull/2182) + * allow passing initial is_url like hs_url in query params + [\#2083](https://github.com/matrix-org/matrix-react-sdk/pull/2083) + * Update karma + [\#2177](https://github.com/matrix-org/matrix-react-sdk/pull/2177) + * fudge hangup reasons + [\#2184](https://github.com/matrix-org/matrix-react-sdk/pull/2184) + * Provide more helpful errors when i18n generation fails + [\#2181](https://github.com/matrix-org/matrix-react-sdk/pull/2181) + Changes in [0.13.6](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.13.6) (2018-10-08) ===================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.13.5...v0.13.6) From 15f3d996deff9185ad443b3f7ecc97875eed848f Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 11 Oct 2018 15:39:56 +0100 Subject: [PATCH 05/77] v0.14.0-rc.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 67faa09420..88d93f2e6d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "0.13.6", + "version": "0.14.0-rc.1", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { From 9c8c84485a2deb3d2aa7fb7b21cabeeac249c7ca Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 11 Oct 2018 18:34:01 +0100 Subject: [PATCH 06/77] Fix user autocompleting This rewrites quite a lot of QueryMatcher. * Remove FuzzyMatcher which was a whole file of commented out code that just deferred to QueryMatcher * Simplify & remove some cruft from QueryMatcher, eg. most of the KeyMap stuff was completely unused. * Don't rely on object iteration order, which fixes a bug where users whose display names were entirely numeric would always appear first... * Add options.funcs to QueryMatcher to allow for indexing by things other than keys on the objects * Use above to index users by username minus the leading '@' * Don't include the '@' in the query when autocomple is triggered by typing '@'. Fixes https://github.com/vector-im/riot-web/issues/6782 --- src/autocomplete/QueryMatcher.js | 115 ++++++++++++++++--------------- src/autocomplete/UserProvider.js | 3 +- 2 files changed, 60 insertions(+), 58 deletions(-) diff --git a/src/autocomplete/QueryMatcher.js b/src/autocomplete/QueryMatcher.js index 9d4d4d0598..a28d3003cf 100644 --- a/src/autocomplete/QueryMatcher.js +++ b/src/autocomplete/QueryMatcher.js @@ -2,6 +2,7 @@ /* Copyright 2017 Aviral Dasgupta Copyright 2018 Michael Telatynski <7t3chguy@gmail.com> +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. @@ -20,99 +21,99 @@ import _at from 'lodash/at'; import _flatMap from 'lodash/flatMap'; import _sortBy from 'lodash/sortBy'; import _uniq from 'lodash/uniq'; -import _keys from 'lodash/keys'; - -class KeyMap { - keys: Array; - objectMap: {[String]: Array}; - priorityMap = new Map(); -} function stripDiacritics(str: string): string { return str.normalize('NFD').replace(/[\u0300-\u036f]/g, ''); } +/** + * Simple search matcher that matches any results with the query string anywhere + * in the search string. Returns matches in the order the query string appears + * in the search key, earliest first, then in the order the items appeared in + * the source array. + * + * @param {Object[]} objects Initial list of objects. Equivalent to calling + * setObjects() after construction + * @param {Object} options Options object + * @param {string[]} options.keys List of keys to use as indexes on the objects + * @param {function[]} options.funcs List of functions that when called with the + * object as an arg will return a string to use as an index + */ export default class QueryMatcher { - /** - * @param {object[]} objects the objects to perform a match on - * @param {string[]} keys an array of keys within each object to match on - * Keys can refer to object properties by name and as in JavaScript (for nested properties) - * - * To use, simply presort objects by required criteria, run through this function and create a QueryMatcher with the - * resulting KeyMap. - * - * TODO: Handle arrays and objects (Fuse did this, RoomProvider uses it) - * @return {KeyMap} - */ - static valuesToKeyMap(objects: Array, keys: Array): KeyMap { - const keyMap = new KeyMap(); - const map = {}; - - objects.forEach((object, i) => { - const keyValues = _at(object, keys); - for (const keyValue of keyValues) { - const key = stripDiacritics(keyValue).toLowerCase(); - if (!map.hasOwnProperty(key)) { - map[key] = []; - } - map[key].push(object); - } - keyMap.priorityMap.set(object, i); - }); - - keyMap.objectMap = map; - keyMap.keys = _keys(map); - return keyMap; - } - constructor(objects: Array, options: {[Object]: Object} = {}) { - this.options = options; - this.keys = options.keys; + this._options = options; + this._keys = options.keys; + this._funcs = options.funcs || []; + this.setObjects(objects); // By default, we remove any non-alphanumeric characters ([^A-Za-z0-9_]) from the // query and the value being queried before matching - if (this.options.shouldMatchWordsOnly === undefined) { - this.options.shouldMatchWordsOnly = true; + if (this._options.shouldMatchWordsOnly === undefined) { + this._options.shouldMatchWordsOnly = true; } // By default, match anywhere in the string being searched. If enabled, only return // matches that are prefixed with the query. - if (this.options.shouldMatchPrefix === undefined) { - this.options.shouldMatchPrefix = false; + if (this._options.shouldMatchPrefix === undefined) { + this._options.shouldMatchPrefix = false; } } setObjects(objects: Array) { - this.keyMap = QueryMatcher.valuesToKeyMap(objects, this.keys); + this._items = new Map(); + + for (const object of objects) { + const keyValues = _at(object, this._keys); + + for (const f of this._funcs) { + keyValues.push(f(object)); + } + + for (const keyValue of keyValues) { + const key = stripDiacritics(keyValue).toLowerCase(); + if (!this._items.has(key)) { + this._items.set(key, []); + } + this._items.get(key).push(object); + } + } } match(query: String): Array { query = stripDiacritics(query).toLowerCase(); - if (this.options.shouldMatchWordsOnly) { + if (this._options.shouldMatchWordsOnly) { query = query.replace(/[^\w]/g, ''); } if (query.length === 0) { return []; } const results = []; - this.keyMap.keys.forEach((key) => { + // Iterate through the map & check each key. + // ES6 Map iteration order is defined to be insertion order, so results + // here will come out in the order they were put in. + for (const key of this._items.keys()) { let resultKey = key; - if (this.options.shouldMatchWordsOnly) { + if (this._options.shouldMatchWordsOnly) { resultKey = resultKey.replace(/[^\w]/g, ''); } const index = resultKey.indexOf(query); - if (index !== -1 && (!this.options.shouldMatchPrefix || index === 0)) { + if (index !== -1 && (!this._options.shouldMatchPrefix || index === 0)) { results.push({key, index}); } + } + + // Sort them by where the query appeared in the search key + // lodash sortBy is a stable sort, so results where the query + // appeared in the same place will retain their order with + // respect to each other. + const sortedResults = _sortBy(results, (candidate) => { + return candidate.index; }); - return _uniq(_flatMap(_sortBy(results, (candidate) => { - return candidate.index; - }).map((candidate) => { - // return an array of objects (those given to setObjects) that have the given - // key as a property. - return this.keyMap.objectMap[candidate.key]; - }))); + // Now map the keys to the result objects. Each result object is a list, so + // flatMap will flatten those lists out into a single list. Also remove any + // duplicates. + return _uniq(_flatMap(sortedResults, (candidate) => this._items.get(candidate.key))); } } diff --git a/src/autocomplete/UserProvider.js b/src/autocomplete/UserProvider.js index ed9c8ee62b..2eae053d72 100644 --- a/src/autocomplete/UserProvider.js +++ b/src/autocomplete/UserProvider.js @@ -45,7 +45,8 @@ export default class UserProvider extends AutocompleteProvider { super(USER_REGEX, FORCED_USER_REGEX); this.room = room; this.matcher = new QueryMatcher([], { - keys: ['name', 'userId'], + keys: ['name'], + funcs: [obj => obj.userId.slice(1)], // index by user id minus the leading '@' shouldMatchPrefix: true, shouldMatchWordsOnly: false, }); From 53e13be0479257ef7cf246996e8d565c354ad00b Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 11 Oct 2018 20:50:48 +0100 Subject: [PATCH 07/77] Add some unit tests for QueryMatcher Which 1) has a fairly complex interface with lots of subtleties and 2) is really trivial to unit test. --- test/autocomplete/QueryMatcher-test.js | 136 +++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 test/autocomplete/QueryMatcher-test.js diff --git a/test/autocomplete/QueryMatcher-test.js b/test/autocomplete/QueryMatcher-test.js new file mode 100644 index 0000000000..d461279614 --- /dev/null +++ b/test/autocomplete/QueryMatcher-test.js @@ -0,0 +1,136 @@ +/* +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 expect from 'expect'; + +import QueryMatcher from '../../src/autocomplete/QueryMatcher'; + +const OBJECTS = [ + { name: "Mel B", nick: "Scary" }, + { name: "Mel C", nick: "Sporty" }, + { name: "Emma", nick: "Baby" }, + { name: "Geri", nick: "Ginger" }, + { name: "Victoria", nick: "Posh" }, +]; + +describe('QueryMatcher', function() { + it('Returns results by key', function() { + const qm = new QueryMatcher(OBJECTS, {keys: ["name"]}); + const results = qm.match('Geri'); + + expect(results.length).toBe(1); + expect(results[0].name).toBe('Geri'); + }); + + it('Returns results by prefix', function() { + const qm = new QueryMatcher(OBJECTS, {keys: ["name"]}); + const results = qm.match('Ge'); + + expect(results.length).toBe(1); + expect(results[0].name).toBe('Geri'); + }); + + it('Matches case-insensitive', function() { + const qm = new QueryMatcher(OBJECTS, {keys: ["name"]}); + const results = qm.match('geri'); + + expect(results.length).toBe(1); + expect(results[0].name).toBe('Geri'); + }); + + it('Matches ignoring accents', function() { + const qm = new QueryMatcher([{name: "Gëri", foo: 46}], {keys: ["name"]}); + const results = qm.match('geri'); + + expect(results.length).toBe(1); + expect(results[0].foo).toBe(46); + }); + + it('Returns multiple results in order of search string appearance', function() { + const qm = new QueryMatcher(OBJECTS, {keys: ["name", "nick"]}); + const results = qm.match('or'); + + expect(results.length).toBe(2); + expect(results[0].name).toBe('Mel C'); + expect(results[1].name).toBe('Victoria'); + + + qm.setObjects(OBJECTS.slice().reverse()); + const reverseResults = qm.match('or'); + + // should still be in the same order: search string position + // takes precedence over input order + expect(reverseResults.length).toBe(2); + expect(reverseResults[0].name).toBe('Mel C'); + expect(reverseResults[1].name).toBe('Victoria'); + }); + + it('Returns results with search string in same place in insertion order', function() { + const qm = new QueryMatcher(OBJECTS, {keys: ["name"]}); + const results = qm.match('Mel'); + + expect(results.length).toBe(2); + expect(results[0].name).toBe('Mel B'); + expect(results[1].name).toBe('Mel C'); + + + qm.setObjects(OBJECTS.slice().reverse()); + + const reverseResults = qm.match('Mel'); + + expect(reverseResults.length).toBe(2); + expect(reverseResults[0].name).toBe('Mel C'); + expect(reverseResults[1].name).toBe('Mel B'); + }); + + it('Returns numeric results in correct order (input pos)', function() { + // regression test for depending on object iteration order + const qm = new QueryMatcher([ + {name: "123456badger"}, + {name: "123456"}, + ], {keys: ["name"]}); + const results = qm.match('123456'); + + expect(results.length).toBe(2); + expect(results[0].name).toBe('123456badger'); + expect(results[1].name).toBe('123456'); + }); + + it('Returns numeric results in correct order (query pos)', function() { + const qm = new QueryMatcher([ + {name: "999999123456"}, + {name: "123456badger"}, + ], {keys: ["name"]}); + const results = qm.match('123456'); + + expect(results.length).toBe(2); + expect(results[0].name).toBe('123456badger'); + expect(results[1].name).toBe('999999123456'); + }); + + it('Returns results by function', function() { + const qm = new QueryMatcher(OBJECTS, { + keys: ["name"], + funcs: [x => x.name.replace('Mel', 'Emma')], + }); + + const results = qm.match('Emma'); + expect(results.length).toBe(3); + expect(results[0].name).toBe('Mel B'); + expect(results[1].name).toBe('Mel C'); + expect(results[2].name).toBe('Emma'); + }); +}); From a58de9e18981388002536bfee20b4b08d4f025c6 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 11 Oct 2018 21:04:50 +0100 Subject: [PATCH 08/77] Also test the two options while we're at it --- test/autocomplete/QueryMatcher-test.js | 39 ++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/test/autocomplete/QueryMatcher-test.js b/test/autocomplete/QueryMatcher-test.js index d461279614..864e1da81d 100644 --- a/test/autocomplete/QueryMatcher-test.js +++ b/test/autocomplete/QueryMatcher-test.js @@ -26,6 +26,11 @@ const OBJECTS = [ { name: "Victoria", nick: "Posh" }, ]; +const NONWORDOBJECTS = [ + { name: "B.O.B" }, + { name: "bob" }, +]; + describe('QueryMatcher', function() { it('Returns results by key', function() { const qm = new QueryMatcher(OBJECTS, {keys: ["name"]}); @@ -133,4 +138,38 @@ describe('QueryMatcher', function() { expect(results[1].name).toBe('Mel C'); expect(results[2].name).toBe('Emma'); }); + + it('Matches words only by default', function() { + const qm = new QueryMatcher(NONWORDOBJECTS, { keys: ["name"] }); + + const results = qm.match('bob'); + expect(results.length).toBe(2); + expect(results[0].name).toBe('B.O.B'); + expect(results[1].name).toBe('bob'); + }); + + it('Matches all chars with words-only off', function() { + const qm = new QueryMatcher(NONWORDOBJECTS, { + keys: ["name"], + shouldMatchWordsOnly: false, + }); + + const results = qm.match('bob'); + expect(results.length).toBe(1); + expect(results[0].name).toBe('bob'); + }); + + it('Matches only by prefix with shouldMatchPrefix on', function() { + const qm = new QueryMatcher([ + {name: "Victoria"}, + {name: "Tori"}, + ], { + keys: ["name"], + shouldMatchPrefix: true, + }); + + const results = qm.match('tori'); + expect(results.length).toBe(1); + expect(results[0].name).toBe('Tori'); + }); }); From ebcc65dc7eafa4ab0d45558464f1cce65de9fb6f Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 12 Oct 2018 13:52:58 -0600 Subject: [PATCH 09/77] Apply the user's tint once the MatrixClientPeg is moderately ready Any earlier and we risk getting NPEs from the peg not existing. Fixes https://github.com/vector-im/riot-web/issues/6424 --- src/MatrixClientPeg.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/MatrixClientPeg.js b/src/MatrixClientPeg.js index f02c751a2c..3fca482aba 100644 --- a/src/MatrixClientPeg.js +++ b/src/MatrixClientPeg.js @@ -26,6 +26,7 @@ import EventTimelineSet from 'matrix-js-sdk/lib/models/event-timeline-set'; import createMatrixClient from './utils/createMatrixClient'; import SettingsStore from './settings/SettingsStore'; import MatrixActionCreators from './actions/MatrixActionCreators'; +import Tinter from "./Tinter"; interface MatrixClientCreds { homeserverUrl: string, @@ -128,6 +129,9 @@ class MatrixClientPeg { opts.lazyLoadMembers = true; } + const color_scheme = SettingsStore.getValue("roomColor"); + Tinter.tint(color_scheme.primary_color, color_scheme.secondary_color); + // Connect the matrix client to the dispatcher MatrixActionCreators.start(this.matrixClient); From b813e3b71479badf13aa8555e3739b85f79f1ad6 Mon Sep 17 00:00:00 2001 From: Karol Kosek Date: Fri, 12 Oct 2018 16:31:25 +0000 Subject: [PATCH 10/77] Translated using Weblate (Polish) Currently translated at 89.9% (1140 of 1267 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/pl/ --- src/i18n/strings/pl.json | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/pl.json b/src/i18n/strings/pl.json index 3bbc9b1d73..245ee0c395 100644 --- a/src/i18n/strings/pl.json +++ b/src/i18n/strings/pl.json @@ -1146,5 +1146,14 @@ "was invited %(count)s times|one": "został zaproszony", "was banned %(count)s times|one": "został zablokowany", "was kicked %(count)s times|one": "został wyrzucony", - "Whether or not you're using the Richtext mode of the Rich Text Editor": "" + "Whether or not you're using the Richtext mode of the Rich Text Editor": "", + "Call in Progress": "Łączenie w toku", + "Permission Required": "Wymagane Pozwolenie", + "Registration Required": "Wymagana Rejestracja", + "You need to register to do this. Would you like to register now?": "Musisz się zarejestrować, aby to zrobić. Czy chcesz się teraz zarejestrować?", + "underlined": "podkreślenie", + "deleted": "przekreślenie", + "numbered-list": "lista numerowana", + "bulleted-list": "wykropkowana lista", + "block-quote": "blok cytowany" } From 127fcf58a998158dae3899418dd96e1bfbc1f2e7 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Mon, 15 Oct 2018 13:57:06 +0200 Subject: [PATCH 11/77] add missing sticker translation --- src/i18n/strings/en_EN.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 338f744a9f..00b4051c9e 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1265,5 +1265,6 @@ "You've previously used Riot on %(host)s with lazy loading of members enabled. In this version lazy loading is disabled. As the local cache is not compatible between these two settings, Riot needs to resync your account.": "You've previously used Riot on %(host)s with lazy loading of members enabled. In this version lazy loading is disabled. As the local cache is not compatible between these two settings, Riot needs to resync your account.", "If the other version of Riot is still open in another tab, please close it as using Riot on the same host with both lazy loading enabled and disabled simultaneously will cause issues.": "If the other version of Riot is still open in another tab, please close it as using Riot on the same host with both lazy loading enabled and disabled simultaneously will cause issues.", "Incompatible local cache": "Incompatible local cache", - "Clear cache and resync": "Clear cache and resync" + "Clear cache and resync": "Clear cache and resync", + "Add some now": "Add some now" } From 259d3608ee1cff18c866aaddb8586dc34530a440 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 15 Oct 2018 15:23:44 +0100 Subject: [PATCH 12/77] Make rageshake use less memory If an individual log is larger than the max size, ignore the rest of it. Also build the string as we go rather than joining it all together at the end, that way we only need the whole string + one chunk in memory at once, rather than the whole string x 2. --- src/rageshake/rageshake.js | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/rageshake/rageshake.js b/src/rageshake/rageshake.js index 4c7d8ea6c6..29dbe4f41d 100644 --- a/src/rageshake/rageshake.js +++ b/src/rageshake/rageshake.js @@ -241,20 +241,27 @@ class IndexedDBLogStore { // Returns: a string representing the concatenated logs for this ID. function fetchLogs(id) { - const o = db.transaction("logs", "readonly").objectStore("logs"); - return selectQuery(o.index("id"), IDBKeyRange.only(id), - (cursor) => { - return { - lines: cursor.value.lines, - index: cursor.value.index, + const objectStore = db.transaction("logs", "readonly").objectStore("logs"); + + return new Promise((resolve, reject) => { + const query = objectStore.index("id").openCursor(IDBKeyRange.only(id), 'next'); + let lines = ''; + query.onerror = (event) => { + reject(new Error("Query failed: " + event.target.errorCode)); + }; + query.onsuccess = (event) => { + const cursor = event.target.result; + if (!cursor) { + resolve(lines); + return; // end of results + } + lines += cursor.value.lines; + if (lines.length >= MAX_LOG_SIZE) { + resolve(lines); + } else { + cursor.continue(); + } }; - }).then((linesArray) => { - // We have been storing logs periodically, so string them all - // together *in order of index* now - linesArray.sort((a, b) => { - return a.index - b.index; - }); - return linesArray.map((l) => l.lines).join(""); }); } @@ -322,9 +329,6 @@ class IndexedDBLogStore { if (i > 0 && size + lines.length > MAX_LOG_SIZE) { // the remaining log IDs should be removed. If we go out of // bounds this is just [] - // - // XXX: there's nothing stopping the current session exceeding - // MAX_LOG_SIZE. We ought to think about culling it. removeLogIds = allLogIds.slice(i + 1); break; } From 2ac9b262576c0f2765341b6335a34364cd8903f4 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Mon, 15 Oct 2018 16:40:51 +0200 Subject: [PATCH 13/77] phased rollout expired function --- src/PhasedRollOut.js | 62 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 src/PhasedRollOut.js diff --git a/src/PhasedRollOut.js b/src/PhasedRollOut.js new file mode 100644 index 0000000000..db91f8ab76 --- /dev/null +++ b/src/PhasedRollOut.js @@ -0,0 +1,62 @@ +/* +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. +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 SdkConfig from './SdkConfig'; + +function hashCode(str) { + var hash = 0, i, chr; + if (str.length === 0) return hash; + for (i = 0; i < str.length; i++) { + chr = str.charCodeAt(i); + hash = ((hash << 5) - hash) + chr; + hash |= 0; + } + return Math.abs(hash); +} + +export function phasedRollOutExpiredForUser(username, feature, now, rollOutConfig = SdkConfig.get().phasedRollOut) { + if (!rollOutConfig) { + console.log(`no phased rollout configuration, so enabling ${feature}`); + return true; + } + const featureConfig = rollOutConfig[feature]; + if (!featureConfig) { + console.log(`${feature} doesn't have phased rollout configured, so enabling`); + return true; + } + if (!Number.isFinite(featureConfig.offset) || !Number.isFinite(featureConfig.period)) { + console.error(`phased rollout of ${feature} is misconfigured, offset and/or period are not numbers, so disabling`, featureConfig); + return false; + } + + const hash = hashCode(username); + //ms -> min, enable users at minute granularity + const bucketRatio = 1000 * 60; + const bucketCount = featureConfig.period / bucketRatio; + const userBucket = hash % bucketCount; + const userMs = userBucket * bucketRatio; + const enableAt = featureConfig.offset + userMs; + const result = now >= enableAt; + const bucketStr = `(bucket ${userBucket}/${bucketCount})`; + if (result) { + console.log(`${feature} enabled for ${username} ${bucketStr}`) + } else { + console.log(`${feature} will be enabled for ${username} in ${Math.ceil((enableAt - now)/1000)}s ${bucketStr}`); + } + return result; +} From f717c5697bf14b141dcda71b5c51ee532250ff43 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Mon, 15 Oct 2018 16:41:04 +0200 Subject: [PATCH 14/77] tests for phased rollout function --- test/PhasedRollOut-test.js | 75 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 test/PhasedRollOut-test.js diff --git a/test/PhasedRollOut-test.js b/test/PhasedRollOut-test.js new file mode 100644 index 0000000000..918fe87543 --- /dev/null +++ b/test/PhasedRollOut-test.js @@ -0,0 +1,75 @@ +/* +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 expect from 'expect'; +import {phasedRollOutExpiredForUser} from '../src/PhasedRollOut'; + +const OFFSET = 6000000; +// phasedRollOutExpiredForUser enables users in bucks of 1 minute +const MS_IN_MINUTE = 60 * 1000; + +describe('PhasedRollOut', function() { + it('should return true if phased rollout is not configured', function() { + expect(phasedRollOutExpiredForUser("@user:hs", "feature_test", 0, null)).toBeTruthy(); + }); + + it('should return true if phased rollout feature is not configured', function() { + expect(phasedRollOutExpiredForUser("@user:hs", "feature_test", 0, { + "feature_other": {offset: 0, period: 0} + })).toBeTruthy(); + }); + + it('should return false if phased rollout for feature is misconfigured', function() { + expect(phasedRollOutExpiredForUser("@user:hs", "feature_test", 0, { + "feature_test": {} + })).toBeFalsy(); + }); + + it("should return false if phased rollout hasn't started yet", function() { + expect(phasedRollOutExpiredForUser("@user:hs", "feature_test", 5000000,{ + "feature_test": {offset: OFFSET, period: MS_IN_MINUTE} + })).toBeFalsy(); + }); + + it("should start to return true in bucket 2/10 for '@user:hs'", function() { + expect(phasedRollOutExpiredForUser("@user:hs", "feature_test", + OFFSET + (MS_IN_MINUTE * 2) - 1, { + "feature_test": {offset: OFFSET, period: MS_IN_MINUTE * 10} + })).toBeFalsy(); + expect(phasedRollOutExpiredForUser("@user:hs", "feature_test", + OFFSET + (MS_IN_MINUTE * 2), { + "feature_test": {offset: OFFSET, period: MS_IN_MINUTE * 10} + })).toBeTruthy(); + }); + + it("should start to return true in bucket 4/10 for 'alice@other-hs'", function() { + expect(phasedRollOutExpiredForUser("alice@other-hs", "feature_test", + OFFSET + (MS_IN_MINUTE * 4) - 1, { + "feature_test": {offset: OFFSET, period: MS_IN_MINUTE * 10} + })).toBeFalsy(); + expect(phasedRollOutExpiredForUser("alice@other-hs", "feature_test", + OFFSET + (MS_IN_MINUTE * 4), { + "feature_test": {offset: OFFSET, period: MS_IN_MINUTE * 10} + })).toBeTruthy(); + }); + + it("should return true after complete rollout period'", function() { + expect(phasedRollOutExpiredForUser("user:hs", "feature_test", + OFFSET + (MS_IN_MINUTE * 20), { + "feature_test": {offset: OFFSET, period: MS_IN_MINUTE * 10} + })).toBeTruthy(); + }); + + + +}); From ef204b6e99b2cbd253c71fe00781c287796db459 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Mon, 15 Oct 2018 16:41:24 +0200 Subject: [PATCH 15/77] check if phased rollout has expired before trying to enable LL --- src/MatrixClientPeg.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/MatrixClientPeg.js b/src/MatrixClientPeg.js index f02c751a2c..04b3b47e43 100644 --- a/src/MatrixClientPeg.js +++ b/src/MatrixClientPeg.js @@ -26,6 +26,7 @@ import EventTimelineSet from 'matrix-js-sdk/lib/models/event-timeline-set'; import createMatrixClient from './utils/createMatrixClient'; import SettingsStore from './settings/SettingsStore'; import MatrixActionCreators from './actions/MatrixActionCreators'; +import {phasedRollOutExpiredForUser} from "./PhasedRollOut"; interface MatrixClientCreds { homeserverUrl: string, @@ -124,8 +125,12 @@ class MatrixClientPeg { // the react sdk doesn't work without this, so don't allow opts.pendingEventOrdering = "detached"; - if (SettingsStore.isFeatureEnabled('feature_lazyloading')) { - opts.lazyLoadMembers = true; + const LAZY_LOADING_FEATURE = "feature_lazyloading"; + if (SettingsStore.isFeatureEnabled(LAZY_LOADING_FEATURE)) { + const userId = this.matrixClient.credentials.userId; + if (phasedRollOutExpiredForUser(userId, LAZY_LOADING_FEATURE, Date.now())) { + opts.lazyLoadMembers = true; + } } // Connect the matrix client to the dispatcher From 478c06c32ea5d9d64bb3c506a303a88c7cb27b69 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Mon, 15 Oct 2018 16:43:52 +0200 Subject: [PATCH 16/77] this file starts in 2018 --- src/PhasedRollOut.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/PhasedRollOut.js b/src/PhasedRollOut.js index db91f8ab76..c0e01110ea 100644 --- a/src/PhasedRollOut.js +++ b/src/PhasedRollOut.js @@ -1,6 +1,4 @@ /* -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"); From f9f7abb0d1ae413bf79f9fb67959c1e04427cb34 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Mon, 15 Oct 2018 17:01:30 +0200 Subject: [PATCH 17/77] fix lint --- src/PhasedRollOut.js | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/PhasedRollOut.js b/src/PhasedRollOut.js index c0e01110ea..a9029d07e6 100644 --- a/src/PhasedRollOut.js +++ b/src/PhasedRollOut.js @@ -17,14 +17,18 @@ limitations under the License. import SdkConfig from './SdkConfig'; function hashCode(str) { - var hash = 0, i, chr; - if (str.length === 0) return hash; - for (i = 0; i < str.length; i++) { - chr = str.charCodeAt(i); - hash = ((hash << 5) - hash) + chr; - hash |= 0; - } - return Math.abs(hash); + let hash = 0; + let i; + let chr; + if (str.length === 0) { + return hash; + } + for (i = 0; i < str.length; i++) { + chr = str.charCodeAt(i); + hash = ((hash << 5) - hash) + chr; + hash |= 0; + } + return Math.abs(hash); } export function phasedRollOutExpiredForUser(username, feature, now, rollOutConfig = SdkConfig.get().phasedRollOut) { @@ -38,7 +42,8 @@ export function phasedRollOutExpiredForUser(username, feature, now, rollOutConfi return true; } if (!Number.isFinite(featureConfig.offset) || !Number.isFinite(featureConfig.period)) { - console.error(`phased rollout of ${feature} is misconfigured, offset and/or period are not numbers, so disabling`, featureConfig); + console.error(`phased rollout of ${feature} is misconfigured, ` + + `offset and/or period are not numbers, so disabling`, featureConfig); return false; } @@ -52,7 +57,7 @@ export function phasedRollOutExpiredForUser(username, feature, now, rollOutConfi const result = now >= enableAt; const bucketStr = `(bucket ${userBucket}/${bucketCount})`; if (result) { - console.log(`${feature} enabled for ${username} ${bucketStr}`) + console.log(`${feature} enabled for ${username} ${bucketStr}`); } else { console.log(`${feature} will be enabled for ${username} in ${Math.ceil((enableAt - now)/1000)}s ${bucketStr}`); } From 63f1c41d18ca028ef33f2547021d3ffa47f823ed Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Mon, 15 Oct 2018 17:15:22 +0200 Subject: [PATCH 18/77] fix test lint --- test/PhasedRollOut-test.js | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/test/PhasedRollOut-test.js b/test/PhasedRollOut-test.js index 918fe87543..600b9051f7 100644 --- a/test/PhasedRollOut-test.js +++ b/test/PhasedRollOut-test.js @@ -25,51 +25,48 @@ describe('PhasedRollOut', function() { it('should return true if phased rollout feature is not configured', function() { expect(phasedRollOutExpiredForUser("@user:hs", "feature_test", 0, { - "feature_other": {offset: 0, period: 0} + "feature_other": {offset: 0, period: 0}, })).toBeTruthy(); }); it('should return false if phased rollout for feature is misconfigured', function() { expect(phasedRollOutExpiredForUser("@user:hs", "feature_test", 0, { - "feature_test": {} + "feature_test": {}, })).toBeFalsy(); }); it("should return false if phased rollout hasn't started yet", function() { - expect(phasedRollOutExpiredForUser("@user:hs", "feature_test", 5000000,{ - "feature_test": {offset: OFFSET, period: MS_IN_MINUTE} + expect(phasedRollOutExpiredForUser("@user:hs", "feature_test", 5000000, { + "feature_test": {offset: OFFSET, period: MS_IN_MINUTE}, })).toBeFalsy(); }); it("should start to return true in bucket 2/10 for '@user:hs'", function() { expect(phasedRollOutExpiredForUser("@user:hs", "feature_test", OFFSET + (MS_IN_MINUTE * 2) - 1, { - "feature_test": {offset: OFFSET, period: MS_IN_MINUTE * 10} + "feature_test": {offset: OFFSET, period: MS_IN_MINUTE * 10}, })).toBeFalsy(); expect(phasedRollOutExpiredForUser("@user:hs", "feature_test", OFFSET + (MS_IN_MINUTE * 2), { - "feature_test": {offset: OFFSET, period: MS_IN_MINUTE * 10} + "feature_test": {offset: OFFSET, period: MS_IN_MINUTE * 10}, })).toBeTruthy(); }); it("should start to return true in bucket 4/10 for 'alice@other-hs'", function() { expect(phasedRollOutExpiredForUser("alice@other-hs", "feature_test", OFFSET + (MS_IN_MINUTE * 4) - 1, { - "feature_test": {offset: OFFSET, period: MS_IN_MINUTE * 10} + "feature_test": {offset: OFFSET, period: MS_IN_MINUTE * 10}, })).toBeFalsy(); expect(phasedRollOutExpiredForUser("alice@other-hs", "feature_test", OFFSET + (MS_IN_MINUTE * 4), { - "feature_test": {offset: OFFSET, period: MS_IN_MINUTE * 10} + "feature_test": {offset: OFFSET, period: MS_IN_MINUTE * 10}, })).toBeTruthy(); }); it("should return true after complete rollout period'", function() { expect(phasedRollOutExpiredForUser("user:hs", "feature_test", OFFSET + (MS_IN_MINUTE * 20), { - "feature_test": {offset: OFFSET, period: MS_IN_MINUTE * 10} + "feature_test": {offset: OFFSET, period: MS_IN_MINUTE * 10}, })).toBeTruthy(); }); - - - }); From 94aac62f255859a95d22b813e4e1004dca21449c Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 15 Oct 2018 14:26:02 -0600 Subject: [PATCH 19/77] Move the login box from the left sidebar to where the composer is Fixes https://github.com/vector-im/riot-web/issues/4227 This includes removing the collapse button that isn't needed anymore. --- res/css/structures/_LoginBox.scss | 1 + src/components/structures/LeftPanel.js | 10 +---- src/components/structures/LoginBox.js | 62 ++++++-------------------- src/components/structures/RoomView.js | 7 ++- 4 files changed, 22 insertions(+), 58 deletions(-) diff --git a/res/css/structures/_LoginBox.scss b/res/css/structures/_LoginBox.scss index 7f6199c451..0a3e21a980 100644 --- a/res/css/structures/_LoginBox.scss +++ b/res/css/structures/_LoginBox.scss @@ -19,6 +19,7 @@ limitations under the License. height: unset !important; padding-top: 13px !important; padding-bottom: 14px !important; + order: 4; } .mx_LoginBox_loginButton_wrapper { diff --git a/src/components/structures/LeftPanel.js b/src/components/structures/LeftPanel.js index ebe5d7f507..72d640bcac 100644 --- a/src/components/structures/LeftPanel.js +++ b/src/components/structures/LeftPanel.js @@ -181,14 +181,8 @@ var LeftPanel = React.createClass({ const BottomLeftMenu = sdk.getComponent('structures.BottomLeftMenu'); const CallPreview = sdk.getComponent('voip.CallPreview'); - let topBox; - if (this.context.matrixClient.isGuest()) { - const LoginBox = sdk.getComponent('structures.LoginBox'); - topBox = ; - } else { - const SearchBox = sdk.getComponent('structures.SearchBox'); - topBox = ; - } + const SearchBox = sdk.getComponent('structures.SearchBox'); + const topBox = ; const classes = classNames( "mx_LeftPanel", diff --git a/src/components/structures/LoginBox.js b/src/components/structures/LoginBox.js index a9ea1f95c6..a2269706ee 100644 --- a/src/components/structures/LoginBox.js +++ b/src/components/structures/LoginBox.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. @@ -16,31 +17,15 @@ limitations under the License. 'use strict'; -var React = require('react'); +const React = require('react'); import { _t } from '../../languageHandler'; -var sdk = require('../../index') -var dis = require('../../dispatcher'); -var rate_limited_func = require('../../ratelimitedfunc'); -var AccessibleButton = require('../../components/views/elements/AccessibleButton'); +const dis = require('../../dispatcher'); +const AccessibleButton = require('../../components/views/elements/AccessibleButton'); module.exports = React.createClass({ displayName: 'LoginBox', propTypes: { - collapsed: React.PropTypes.bool, - }, - - onToggleCollapse: function(show) { - if (show) { - dis.dispatch({ - action: 'show_left_panel', - }); - } - else { - dis.dispatch({ - action: 'hide_left_panel', - }); - } }, onLoginClick: function() { @@ -52,41 +37,20 @@ module.exports = React.createClass({ }, render: function() { - var TintableSvg = sdk.getComponent('elements.TintableSvg'); - - var toggleCollapse; - if (this.props.collapsed) { - toggleCollapse = - - + const loginButton = ( +
+ + { _t("Login") } - } - else { - toggleCollapse = - - + + { _t("Register") } - } +
+ ); - var loginButton; - if (!this.props.collapsed) { - loginButton = ( -
- - { _t("Login") } - - - { _t("Register") } - -
- ); - } - - var self = this; return ( -
+
{ loginButton } - { toggleCollapse }
); } diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 32121d6de5..62c596e939 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -1669,7 +1669,7 @@ module.exports = React.createClass({ let messageComposer, searchInfo; const canSpeak = ( // joined and not showing search results - myMembership == 'join' && !this.state.searchResults + myMembership === 'join' && !this.state.searchResults ); if (canSpeak) { messageComposer = @@ -1683,6 +1683,11 @@ module.exports = React.createClass({ />; } + if (MatrixClientPeg.get().isGuest()) { + const LoginBox = sdk.getComponent('structures.LoginBox'); + messageComposer = ; + } + // TODO: Why aren't we storing the term/scope/count in this format // in this.state if this is what RoomHeader desires? if (this.state.searchResults) { From 2d62fda86262547c32887bbb17c64d40842d572f Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 15 Oct 2018 14:35:36 -0600 Subject: [PATCH 20/77] Don't show the invite nag bar when peeking --- src/components/structures/RoomStatusBar.js | 6 +++++- src/components/structures/RoomView.js | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/components/structures/RoomStatusBar.js b/src/components/structures/RoomStatusBar.js index 4f9ac153f5..c6a6e1e2d3 100644 --- a/src/components/structures/RoomStatusBar.js +++ b/src/components/structures/RoomStatusBar.js @@ -66,6 +66,10 @@ module.exports = React.createClass({ // result in "X, Y, Z and 100 others are typing." whoIsTypingLimit: PropTypes.number, + // true if the room is being peeked at. This affects components that shouldn't + // logically be shown when peeking, such as a prompt to invite people to a room. + isPeeking: PropTypes.bool, + // callback for when the user clicks on the 'resend all' button in the // 'unsent messages' bar onResendAllClick: PropTypes.func, @@ -457,7 +461,7 @@ module.exports = React.createClass({ } // If you're alone in the room, and have sent a message, suggest to invite someone - if (this.props.sentMessageAndIsAlone) { + if (this.props.sentMessageAndIsAlone && !this.props.isPeeking) { return (
{ _t("There's no one else here! Would you like to invite others " + diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 32121d6de5..8e226bdfcf 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -1595,6 +1595,7 @@ module.exports = React.createClass({ atEndOfLiveTimeline={this.state.atEndOfLiveTimeline} sentMessageAndIsAlone={this.state.isAlone} hasActiveCall={inCall} + isPeeking={myMembership !== "join"} onInviteClick={this.onInviteButtonClick} onStopWarningClick={this.onStopAloneWarningClick} onScrollToBottomClick={this.jumpToLiveTimeline} From 6323d78b0cfc5857fde1b72fa9831daa25cc360c Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 15 Oct 2018 14:41:00 -0600 Subject: [PATCH 21/77] Move tinter init to MatrixChat This is a much better place for it to live --- src/MatrixClientPeg.js | 4 ---- src/components/structures/MatrixChat.js | 5 +++++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/MatrixClientPeg.js b/src/MatrixClientPeg.js index b524033b70..04b3b47e43 100644 --- a/src/MatrixClientPeg.js +++ b/src/MatrixClientPeg.js @@ -27,7 +27,6 @@ import createMatrixClient from './utils/createMatrixClient'; import SettingsStore from './settings/SettingsStore'; import MatrixActionCreators from './actions/MatrixActionCreators'; import {phasedRollOutExpiredForUser} from "./PhasedRollOut"; -import Tinter from "./Tinter"; interface MatrixClientCreds { homeserverUrl: string, @@ -134,9 +133,6 @@ class MatrixClientPeg { } } - const color_scheme = SettingsStore.getValue("roomColor"); - Tinter.tint(color_scheme.primary_color, color_scheme.secondary_color); - // Connect the matrix client to the dispatcher MatrixActionCreators.start(this.matrixClient); diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index db5e898946..f385aacd40 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -1403,6 +1403,11 @@ export default React.createClass({ break; } }); + + // Fire the tinter right on startup to ensure the default theme is applied + // A later sync can/will correct the tint to be the right value for the user + const color_scheme = SettingsStore.getValue("roomColor"); + Tinter.tint(color_scheme.primary_color, color_scheme.secondary_color); }, /** From d87ab8aac0d3dc2343d46be99e33ea99aa04a490 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 15 Oct 2018 16:12:42 -0600 Subject: [PATCH 22/77] Support m.login.terms during registration Fixes https://github.com/vector-im/riot-web/issues/7168 Requires https://github.com/matrix-org/synapse/pull/4004 --- .../login/InteractiveAuthEntryComponents.js | 99 +++++++++++++++++++ src/i18n/strings/en_EN.json | 2 + 2 files changed, 101 insertions(+) diff --git a/src/components/views/login/InteractiveAuthEntryComponents.js b/src/components/views/login/InteractiveAuthEntryComponents.js index bfdfbb63bf..d4c2f58aa9 100644 --- a/src/components/views/login/InteractiveAuthEntryComponents.js +++ b/src/components/views/login/InteractiveAuthEntryComponents.js @@ -22,6 +22,7 @@ import classnames from 'classnames'; import sdk from '../../../index'; import { _t } from '../../../languageHandler'; +import SettingsStore from "../../../settings/SettingsStore"; /* This file contains a collection of components which are used by the * InteractiveAuth to prompt the user to enter the information needed @@ -209,6 +210,103 @@ export const RecaptchaAuthEntry = React.createClass({ }, }); +export const TermsAuthEntry = React.createClass({ + displayName: 'TermsAuthEntry', + + statics: { + LOGIN_TYPE: "m.login.terms", + }, + + propTypes: { + submitAuthDict: PropTypes.func.isRequired, + stageParams: PropTypes.object.isRequired, + errorText: PropTypes.string, + busy: PropTypes.bool, + }, + + componentWillMount: function() { + const allPolicies = this.props.stageParams.policies || {}; + const prefLang = SettingsStore.getValue("language"); + const initToggles = {}; + const pickedPolicies = []; + for (const policyId of Object.keys(allPolicies)) { + const policy = allPolicies[policyId]; + + // Pick a language based on the user's language, falling back to english, + // and finally to the first language available. If there's still no policy + // available then the homeserver isn't respecting the spec. + const availableLangs = Object.keys(policy).filter(e => e !== "version"); + let langPolicy = policy[prefLang]; + if (!langPolicy) langPolicy = "en"; + if (!langPolicy) langPolicy = policy[availableLangs[0]]; // last resort + if (!langPolicy) throw new Error("Failed to find a policy to show the user"); + + initToggles[policyId] = false; + + langPolicy.id = policyId; + pickedPolicies.push(langPolicy); + } + + this.setState({ + "toggledPolicies": initToggles, + "policies": pickedPolicies, + }); + }, + + _trySubmit: function(policyId) { + const newToggles = {}; + let allChecked = true; + for (const policy of this.state.policies) { + let checked = this.state.toggledPolicies[policy.id]; + if (policy.id === policyId) checked = !checked; + + newToggles[policy.id] = checked; + allChecked = allChecked && checked; + } + + this.setState({"toggledPolicies": newToggles}); + if (allChecked) this.props.submitAuthDict({type: TermsAuthEntry.LOGIN_TYPE}); + }, + + render: function() { + if (this.props.busy) { + const Loader = sdk.getComponent("elements.Spinner"); + return ; + } + + let checkboxes = []; + let allChecked = true; + for (const policy of this.state.policies) { + const checked = this.state.toggledPolicies[policy.id]; + allChecked = allChecked && checked; + + checkboxes.push( + + ); + } + + let errorSection; + if (this.props.errorText) { + errorSection = ( +
+ { this.props.errorText } +
+ ); + } + + return ( +
+

{_t("Please review and accept the policies of this homeserver:")}

+ { checkboxes } + { errorSection } +
+ ); + }, +}); + export const EmailIdentityAuthEntry = React.createClass({ displayName: 'EmailIdentityAuthEntry', @@ -496,6 +594,7 @@ const AuthEntryComponents = [ RecaptchaAuthEntry, EmailIdentityAuthEntry, MsisdnAuthEntry, + TermsAuthEntry, ]; export function getEntryComponentForLoginType(loginType) { diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 338f744a9f..e00be22d1c 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -643,6 +643,8 @@ "Dismiss": "Dismiss", "To continue, please enter your password.": "To continue, please enter your password.", "Password:": "Password:", + "Please accept all of the policies": "Please accept all of the policies", + "Please review and accept the policies of this homeserver:": "Please review and accept the policies of this homeserver:", "An email has been sent to %(emailAddress)s": "An email has been sent to %(emailAddress)s", "Please check your email to continue registration.": "Please check your email to continue registration.", "Token incorrect": "Token incorrect", From cbe642f56969d5924bb1afd3f1b73d16931b29c9 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 16 Oct 2018 10:50:02 +0100 Subject: [PATCH 23/77] released js-sdk --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 88d93f2e6d..58fe88c1f1 100644 --- a/package.json +++ b/package.json @@ -75,7 +75,7 @@ "linkifyjs": "^2.1.6", "lodash": "^4.13.1", "lolex": "2.3.2", - "matrix-js-sdk": "0.12.0-rc.1", + "matrix-js-sdk": "0.12.0", "optimist": "^0.6.1", "pako": "^1.0.5", "prop-types": "^15.5.8", From 0e69490b6a24ad22ed62d11adf47ba53ce1b5a75 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 16 Oct 2018 10:53:43 +0100 Subject: [PATCH 24/77] Prepare changelog for v0.14.0 --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d4f2c4efa4..40cb8c5283 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +Changes in [0.14.0](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.14.0) (2018-10-16) +===================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.14.0-rc.1...v0.14.0) + + * Phased rollout of lazy loading + [\#2218](https://github.com/matrix-org/matrix-react-sdk/pull/2218) + Changes in [0.14.0-rc.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.14.0-rc.1) (2018-10-11) =============================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.13.6...v0.14.0-rc.1) From cbb117552f75f63ef9023716d57f56a57b43742b Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 16 Oct 2018 10:54:19 +0100 Subject: [PATCH 25/77] v0.14.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 58fe88c1f1..93cbcd1c67 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "0.14.0-rc.1", + "version": "0.14.0", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { From 8015bdfed77bc5a33ddc9aca2760639501cf422c Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 16 Oct 2018 10:57:32 +0100 Subject: [PATCH 26/77] Update deps or, apparently, mostly just add 'github' prefixes --- package.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 93cbcd1c67..5b28053256 100644 --- a/package.json +++ b/package.json @@ -67,15 +67,15 @@ "flux": "2.1.1", "focus-trap-react": "^3.0.5", "fuse.js": "^2.2.0", - "gemini-scrollbar": "matrix-org/gemini-scrollbar#b302279", + "gemini-scrollbar": "github:matrix-org/gemini-scrollbar#b302279", "gfm.css": "^1.1.1", "glob": "^5.0.14", - "highlight.js": "^9.0.0", + "highlight.js": "^9.13.0", "isomorphic-fetch": "^2.2.1", "linkifyjs": "^2.1.6", "lodash": "^4.13.1", "lolex": "2.3.2", - "matrix-js-sdk": "0.12.0", + "matrix-js-sdk": "matrix-org/matrix-js-sdk#develop", "optimist": "^0.6.1", "pako": "^1.0.5", "prop-types": "^15.5.8", @@ -85,16 +85,16 @@ "react-addons-css-transition-group": "15.3.2", "react-beautiful-dnd": "^4.0.1", "react-dom": "^15.6.0", - "react-gemini-scrollbar": "matrix-org/react-gemini-scrollbar#5e97aef", + "react-gemini-scrollbar": "github:matrix-org/react-gemini-scrollbar#5e97aef", "resize-observer-polyfill": "^1.5.0", "sanitize-html": "^1.18.4", "slate": "^0.41.2", "slate-html-serializer": "^0.6.1", - "slate-md-serializer": "matrix-org/slate-md-serializer#f7c4ad3", + "slate-md-serializer": "github:matrix-org/slate-md-serializer#f7c4ad3", "slate-react": "^0.18.10", "text-encoding-utf-8": "^1.0.1", "url": "^0.11.0", - "velocity-vector": "vector-im/velocity#059e3b2", + "velocity-vector": "github:vector-im/velocity#059e3b2", "whatwg-fetch": "^1.1.1" }, "devDependencies": { From b929c362223f1c72efda035b0e2173baf66968e6 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 16 Oct 2018 09:19:36 -0600 Subject: [PATCH 27/77] Documentation++ --- .../login/InteractiveAuthEntryComponents.js | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/components/views/login/InteractiveAuthEntryComponents.js b/src/components/views/login/InteractiveAuthEntryComponents.js index d4c2f58aa9..6e0e5d538a 100644 --- a/src/components/views/login/InteractiveAuthEntryComponents.js +++ b/src/components/views/login/InteractiveAuthEntryComponents.js @@ -225,6 +225,25 @@ export const TermsAuthEntry = React.createClass({ }, componentWillMount: function() { + // example stageParams: + // + // { + // "policies": { + // "privacy_policy": { + // "version": "1.0", + // "en": { + // "name": "Privacy Policy", + // "url": "https://example.org/privacy-1.0-en.html", + // }, + // "fr": { + // "name": "Politique de confidentialité", + // "url": "https://example.org/privacy-1.0-fr.html", + // }, + // }, + // "other_policy": { ... }, + // } + // } + const allPolicies = this.props.stageParams.policies || {}; const prefLang = SettingsStore.getValue("language"); const initToggles = {}; @@ -235,10 +254,13 @@ export const TermsAuthEntry = React.createClass({ // Pick a language based on the user's language, falling back to english, // and finally to the first language available. If there's still no policy // available then the homeserver isn't respecting the spec. - const availableLangs = Object.keys(policy).filter(e => e !== "version"); let langPolicy = policy[prefLang]; - if (!langPolicy) langPolicy = "en"; - if (!langPolicy) langPolicy = policy[availableLangs[0]]; // last resort + if (!langPolicy) langPolicy = policy["en"]; + if (!langPolicy) { + // last resort + const firstLang = Object.keys(policy).find(e => e !== "version"); + langPolicy = policy[firstLang]; + } if (!langPolicy) throw new Error("Failed to find a policy to show the user"); initToggles[policyId] = false; From d504cdeb8592adc6ff9834559ee51e2c7170343b Mon Sep 17 00:00:00 2001 From: Krombel Date: Tue, 16 Oct 2018 15:51:58 +0000 Subject: [PATCH 28/77] Translated using Weblate (German) Currently translated at 100.0% (1269 of 1269 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 b183c8bfcd..5cb856b651 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -1289,5 +1289,7 @@ "You've previously used Riot on %(host)s with lazy loading of members enabled. In this version lazy loading is disabled. As the local cache is not compatible between these two settings, Riot needs to resync your account.": "Du hast zuvor Riot auf %(host)s ohne verzögertem Laden von Mitgliedern genutzt. In dieser Version war das verzögerte Laden deaktiviert. Da die lokal zwischengespeicherten Daten zwischen diesen Einstellungen nicht kompatibel ist, muss Riot dein Konto neu synchronisieren.", "If the other version of Riot is still open in another tab, please close it as using Riot on the same host with both lazy loading enabled and disabled simultaneously will cause issues.": "Wenn Riot mit der alten Version in einem anderen Tab geöffnet ist, schließe dies bitte, da das parallele Nutzen von Riot auf demselben Host mit aktivierten und deaktivierten verzögertem Laden, Probleme verursachen wird.", "Incompatible local cache": "Inkompatibler lokaler Zwischenspeicher", - "Clear cache and resync": "Zwischenspeicher löschen und erneut synchronisieren" + "Clear cache and resync": "Zwischenspeicher löschen und erneut synchronisieren", + "Please accept all of the policies": "Bitte akzeptiere alle Bedingungen", + "Please review and accept the policies of this homeserver:": "Bitte sieh dir alle Bedingungen dieses Heimservers an und akzeptiere sie:" } From 7d60e09f8ebef8fb6330f33d220ed1cbb08b49e8 Mon Sep 17 00:00:00 2001 From: Szimszon Date: Tue, 16 Oct 2018 18:03:52 +0000 Subject: [PATCH 29/77] Translated using Weblate (Hungarian) Currently translated at 100.0% (1269 of 1269 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 51105ed5c5..5a7c5d210a 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -1291,5 +1291,7 @@ "You've previously used Riot on %(host)s with lazy loading of members enabled. In this version lazy loading is disabled. As the local cache is not compatible between these two settings, Riot needs to resync your account.": "Előzőleg a szoba tagság késleltetett betöltésének engedélyével itt használtad a Riotot: %(host)s. Ebben a verzióban viszont a késleltetett betöltés nem engedélyezett. Mivel a két gyorsítótár nem kompatibilis egymással így Riotnak újra kell szinkronizálnia a fiókot.", "If the other version of Riot is still open in another tab, please close it as using Riot on the same host with both lazy loading enabled and disabled simultaneously will cause issues.": "Ha a másik Riot verzió fut még egy másik fülön, kérlek zárd be, mivel ha ugyanott használod a Riotot bekapcsolt késleltetett betöltéssel és kikapcsolva is akkor problémák adódhatnak.", "Incompatible local cache": "A helyi gyorsítótár nem kompatibilis ezzel a verzióval", - "Clear cache and resync": "Gyorsítótár törlése és újraszinkronizálás" + "Clear cache and resync": "Gyorsítótár törlése és újraszinkronizálás", + "Please accept all of the policies": "Kérlek fogadd el az összes előírást", + "Please review and accept the policies of this homeserver:": "Kérlek nézd át és fogadd el a Matrix szerver felhasználói feltételeit:" } From 8668faa6b0f3d1ee643b70884253978fcfda5626 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 16 Oct 2018 19:14:06 -0600 Subject: [PATCH 30/77] Show the group member list again Fixes https://github.com/vector-im/riot-web/issues/7511 --- res/css/views/rooms/_MemberList.scss | 3 --- 1 file changed, 3 deletions(-) diff --git a/res/css/views/rooms/_MemberList.scss b/res/css/views/rooms/_MemberList.scss index 83fc70aefb..cfac8797b9 100644 --- a/res/css/views/rooms/_MemberList.scss +++ b/res/css/views/rooms/_MemberList.scss @@ -111,6 +111,3 @@ limitations under the License. width: 100%; } -.mx_MemberList_outerWrapper { - height: 0px; -} From 2295347d8d3356337e6893410b20e54cb29dbfc4 Mon Sep 17 00:00:00 2001 From: random Date: Wed, 17 Oct 2018 09:24:25 +0000 Subject: [PATCH 31/77] Translated using Weblate (Italian) Currently translated at 100.0% (1269 of 1269 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/it/ --- src/i18n/strings/it.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/it.json b/src/i18n/strings/it.json index d877be6c9e..962e179cc8 100644 --- a/src/i18n/strings/it.json +++ b/src/i18n/strings/it.json @@ -1288,5 +1288,7 @@ "You've previously used Riot on %(host)s with lazy loading of members enabled. In this version lazy loading is disabled. As the local cache is not compatible between these two settings, Riot needs to resync your account.": "Hai usato Riot precedentemente su %(host)s con il caricamento lento dei membri attivato. In questa versione il caricamento lento è disattivato. Dato che la cache locale non è compatibile tra queste due impostazioni, Riot deve risincronizzare il tuo account.", "If the other version of Riot is still open in another tab, please close it as using Riot on the same host with both lazy loading enabled and disabled simultaneously will cause issues.": "Se l'altra versione di Riot è ancora aperta in un'altra scheda, chiudila perchè usare Riot nello stesso host con il caricamento lento sia attivato che disattivato può causare errori.", "Incompatible local cache": "Cache locale non compatibile", - "Clear cache and resync": "Svuota cache e risincronizza" + "Clear cache and resync": "Svuota cache e risincronizza", + "Please accept all of the policies": "Si prega di accettare tutte le condizioni", + "Please review and accept the policies of this homeserver:": "Consulta ed accetta le condizioni di questo homeserver:" } From 482360742ffdffe5a976a97aab48a4b442f38361 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Tue, 16 Oct 2018 22:07:53 +0000 Subject: [PATCH 32/77] Translated using Weblate (French) Currently translated at 100.0% (1269 of 1269 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 ede9c26656..196ea4bcd9 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -1291,5 +1291,7 @@ "You've previously used Riot on %(host)s with lazy loading of members enabled. In this version lazy loading is disabled. As the local cache is not compatible between these two settings, Riot needs to resync your account.": "Vous avez utilisé auparavant Riot sur %(host)s avec le chargement différé activé. Dans cette version le chargement différé est désactivé. Comme le cache local n'est pas compatible entre ces deux réglages, Riot doit resynchroniser votre compte.", "If the other version of Riot is still open in another tab, please close it as using Riot on the same host with both lazy loading enabled and disabled simultaneously will cause issues.": "Si l'autre version de Riot est encore ouverte dans un autre onglet, merci de le fermer car l'utilisation de Riot sur le même hôte avec le chargement différé activé et désactivé à la fois causera des problèmes.", "Incompatible local cache": "Cache local incompatible", - "Clear cache and resync": "Vider le cache et resynchroniser" + "Clear cache and resync": "Vider le cache et resynchroniser", + "Please accept all of the policies": "Veuillez accepter toutes les politiques", + "Please review and accept the policies of this homeserver:": "Veuillez lire et accepter les politiques de ce serveur d'accueil :" } From 336ea96c91d869ef2b975e70b4f1c7f116981a08 Mon Sep 17 00:00:00 2001 From: Szimszon Date: Tue, 16 Oct 2018 18:06:25 +0000 Subject: [PATCH 33/77] Translated using Weblate (Hungarian) Currently translated at 100.0% (1269 of 1269 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 5a7c5d210a..e4bf2e3036 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -1292,6 +1292,6 @@ "If the other version of Riot is still open in another tab, please close it as using Riot on the same host with both lazy loading enabled and disabled simultaneously will cause issues.": "Ha a másik Riot verzió fut még egy másik fülön, kérlek zárd be, mivel ha ugyanott használod a Riotot bekapcsolt késleltetett betöltéssel és kikapcsolva is akkor problémák adódhatnak.", "Incompatible local cache": "A helyi gyorsítótár nem kompatibilis ezzel a verzióval", "Clear cache and resync": "Gyorsítótár törlése és újraszinkronizálás", - "Please accept all of the policies": "Kérlek fogadd el az összes előírást", + "Please accept all of the policies": "Kérlek fogadd el a felhasználói feltételeket", "Please review and accept the policies of this homeserver:": "Kérlek nézd át és fogadd el a Matrix szerver felhasználói feltételeit:" } From e1be8966bcf805bcdb5de3d542e453b7c4f88112 Mon Sep 17 00:00:00 2001 From: Osoitz Date: Wed, 17 Oct 2018 15:45:48 +0000 Subject: [PATCH 34/77] Translated using Weblate (Basque) Currently translated at 100.0% (1270 of 1270 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 | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/eu.json b/src/i18n/strings/eu.json index 96f201672d..5adbe476e7 100644 --- a/src/i18n/strings/eu.json +++ b/src/i18n/strings/eu.json @@ -1285,5 +1285,12 @@ "

HTML for your community's page

\r\n

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

\r\n

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

\r\n": "

Zure komunitatearen orriaren HTMLa

\n

\n Erabili deskripzio luzea kide berriek komunitatea ezagutu dezaten, edo eman ezagutzera esteka garrantzitsuak\n

\n

\n 'img' etiketak erabili ditzakezu ere\n

\n", "Submit Debug Logs": "Bidali arazketa egunkariak", "An email address is required to register on this homeserver.": "e-mail helbide bat behar da hasiera-zerbitzari honetan izena emateko.", - "A phone number is required to register on this homeserver.": "telefono zenbaki bat behar da hasiera-zerbitzari honetan izena emateko." + "A phone number is required to register on this homeserver.": "telefono zenbaki bat behar da hasiera-zerbitzari honetan izena emateko.", + "Please accept all of the policies": "Onartu mesedez politika guztiak", + "Please review and accept the policies of this homeserver:": "Irakurri eta onartu hasiera zerbitzari honen politikak:", + "You've previously used Riot on %(host)s with lazy loading of members enabled. In this version lazy loading is disabled. As the local cache is not compatible between these two settings, Riot needs to resync your account.": "Aurretik Riot erabili duzu %(host)s zerbitzarian kideen karga alferra gaituta zenuela. Bertsio honetan karga alferra desgaituta dago. Katxe lokala bi ezarpen hauen artean bateragarria ez denez, Riotek zure kontua berriro sinkronizatu behar du.", + "If the other version of Riot is still open in another tab, please close it as using Riot on the same host with both lazy loading enabled and disabled simultaneously will cause issues.": "Rioten beste bertsioa oraindik beste fitxat batean irekita badago, itxi ezazu zerbitzari bera aldi berean karga alferra gaituta eta desgaituta erabiltzeak arazoak sor ditzakeelako.", + "Incompatible local cache": "Katxe lokal bateraezina", + "Clear cache and resync": "Garbitu katxea eta sinkronizatu berriro", + "Add some now": "Gehitu batzuk orain" } From 2f94631720a870ca881a494acaccc90853ddd832 Mon Sep 17 00:00:00 2001 From: Szimszon Date: Tue, 16 Oct 2018 18:06:25 +0000 Subject: [PATCH 35/77] Translated using Weblate (Hungarian) Currently translated at 100.0% (1270 of 1270 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index e4bf2e3036..8ce023f377 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -1293,5 +1293,6 @@ "Incompatible local cache": "A helyi gyorsítótár nem kompatibilis ezzel a verzióval", "Clear cache and resync": "Gyorsítótár törlése és újraszinkronizálás", "Please accept all of the policies": "Kérlek fogadd el a felhasználói feltételeket", - "Please review and accept the policies of this homeserver:": "Kérlek nézd át és fogadd el a Matrix szerver felhasználói feltételeit:" + "Please review and accept the policies of this homeserver:": "Kérlek nézd át és fogadd el a Matrix szerver felhasználói feltételeit:", + "Add some now": "Adj hozzá párat" } From af8dfda9a7a78873d5e0b7f5aede5cd266ed270c Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 17 Oct 2018 13:53:12 -0600 Subject: [PATCH 36/77] Add a bit of text to explain the purpose of the RoomPreviewSpinner Fixes https://github.com/vector-im/riot-web/issues/5869 --- res/css/views/rooms/_RoomPreviewBar.scss | 4 ++++ src/components/structures/RoomView.js | 3 +++ src/components/views/rooms/RoomPreviewBar.js | 11 ++++++++++- src/i18n/strings/en_EN.json | 1 + 4 files changed, 18 insertions(+), 1 deletion(-) diff --git a/res/css/views/rooms/_RoomPreviewBar.scss b/res/css/views/rooms/_RoomPreviewBar.scss index 331eb582ea..8196740499 100644 --- a/res/css/views/rooms/_RoomPreviewBar.scss +++ b/res/css/views/rooms/_RoomPreviewBar.scss @@ -56,3 +56,7 @@ limitations under the License. .mx_RoomPreviewBar_warningIcon { padding: 12px; } + +.mx_RoomPreviewBar_spinnerIntro { + margin-top: 50px; +} \ No newline at end of file diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 8e226bdfcf..52264266a8 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -1514,6 +1514,7 @@ module.exports = React.createClass({ canPreview={false} error={this.state.roomLoadError} roomAlias={roomAlias} spinner={this.state.joining} + spinnerState="joining" inviterName={inviterName} invitedEmail={invitedEmail} room={this.state.room} @@ -1558,6 +1559,7 @@ module.exports = React.createClass({ inviterName={inviterName} canPreview={false} spinner={this.state.joining} + spinnerState="joining" room={this.state.room} />
@@ -1645,6 +1647,7 @@ module.exports = React.createClass({ onForgetClick={this.onForgetClick} onRejectClick={this.onRejectThreepidInviteButtonClicked} spinner={this.state.joining} + spinnerState="joining" inviterName={inviterName} invitedEmail={invitedEmail} canPreview={this.state.canPeek} diff --git a/src/components/views/rooms/RoomPreviewBar.js b/src/components/views/rooms/RoomPreviewBar.js index 5ec19d185e..9d3dbe5217 100644 --- a/src/components/views/rooms/RoomPreviewBar.js +++ b/src/components/views/rooms/RoomPreviewBar.js @@ -44,9 +44,13 @@ module.exports = React.createClass({ error: PropTypes.object, canPreview: PropTypes.bool, - spinner: PropTypes.bool, room: PropTypes.object, + // When a spinner is present, a spinnerState can be specified to indicate the + // purpose of the spinner. + spinner: PropTypes.bool, + spinnerState: PropTypes.oneOf(["joining"]), + // The alias that was used to access this room, if appropriate // If given, this will be how the room is referred to (eg. // in error messages). @@ -93,7 +97,12 @@ module.exports = React.createClass({ if (this.props.spinner || this.state.busy) { const Spinner = sdk.getComponent("elements.Spinner"); + let spinnerIntro = ""; + if (this.props.spinnerState === "joining") { + spinnerIntro = _t("Joining room..."); + } return (
+

{ spinnerIntro }

); } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index e42d3ce434..e0f4663532 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -512,6 +512,7 @@ "You have no historical rooms": "You have no historical rooms", "Historical": "Historical", "System Alerts": "System Alerts", + "Joining room...": "Joining room...", "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.", "This invitation was sent to an email address which is not associated with this account:": "This invitation was sent to an email address which is not associated with this account:", "You may wish to login with a different account, or add this email to this account.": "You may wish to login with a different account, or add this email to this account.", From 7b8506ba653548a040822a75814ea3a19c553c38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Tue, 16 Oct 2018 22:07:53 +0000 Subject: [PATCH 37/77] Translated using Weblate (French) Currently translated at 100.0% (1270 of 1270 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 196ea4bcd9..125ac49b79 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -1293,5 +1293,6 @@ "Incompatible local cache": "Cache local incompatible", "Clear cache and resync": "Vider le cache et resynchroniser", "Please accept all of the policies": "Veuillez accepter toutes les politiques", - "Please review and accept the policies of this homeserver:": "Veuillez lire et accepter les politiques de ce serveur d'accueil :" + "Please review and accept the policies of this homeserver:": "Veuillez lire et accepter les politiques de ce serveur d'accueil :", + "Add some now": "En ajouter maintenant" } From fc4d4acacea7418dfd71eaa6011ac2e66f70e6cf Mon Sep 17 00:00:00 2001 From: Slavi Pantaleev Date: Thu, 18 Oct 2018 12:07:22 +0000 Subject: [PATCH 38/77] Translated using Weblate (Bulgarian) Currently translated at 100.0% (1270 of 1270 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/bg/ --- src/i18n/strings/bg.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json index 9921662964..b49384891c 100644 --- a/src/i18n/strings/bg.json +++ b/src/i18n/strings/bg.json @@ -1288,5 +1288,8 @@ "You've previously used Riot on %(host)s with lazy loading of members enabled. In this version lazy loading is disabled. As the local cache is not compatible between these two settings, Riot needs to resync your account.": "Преди сте използвали Riot на %(host)s с включено постепенно зареждане на членове. В тази версия, тази настройка е изключена. Понеже локалният кеш не е съвместим при тези две настройки, Riot трябва да синхронизира акаунта Ви наново.", "If the other version of Riot is still open in another tab, please close it as using Riot on the same host with both lazy loading enabled and disabled simultaneously will cause issues.": "Ако другата версия на Riot все още е отворена в друг таб, моля затворете я. Използването на Riot на един адрес във версии с постепенно и без постепенно зареждане ще причини проблеми.", "Incompatible local cache": "Несъвместим локален кеш", - "Clear cache and resync": "Изчисти кеша и ресинхронизирай" + "Clear cache and resync": "Изчисти кеша и ресинхронизирай", + "Please accept all of the policies": "Моля, приемете всички политики", + "Please review and accept the policies of this homeserver:": "Моля, прегледайте и приемете политиките на този сървър:", + "Add some now": "Добави сега" } From eb517fe2e9a1199a070152f90f1e1e229aea27bc Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Fri, 19 Oct 2018 01:18:29 +0000 Subject: [PATCH 39/77] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (1270 of 1270 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 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json index 5b259066a7..e3492d1ef6 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -1289,5 +1289,8 @@ "You've previously used Riot on %(host)s with lazy loading of members enabled. In this version lazy loading is disabled. As the local cache is not compatible between these two settings, Riot needs to resync your account.": "您之前曾在 %(host)s 上使用 Riot 並啟用成員列表的延遲載入。在此版本中延遲載入已停用。由於本機快取在這兩個設定間不相容,Riot 必須重新同步您的帳號。", "If the other version of Riot is still open in another tab, please close it as using Riot on the same host with both lazy loading enabled and disabled simultaneously will cause issues.": "若其他分頁仍有不同版本的 Riot,請將其關閉,因為在同一個主機上同時啟用和停用延遲載入將會發生問題。", "Incompatible local cache": "不相容的本機快取", - "Clear cache and resync": "清除快取並重新同步" + "Clear cache and resync": "清除快取並重新同步", + "Please accept all of the policies": "請接受所有政策", + "Please review and accept the policies of this homeserver:": "請審閱並接受此家伺服器的政策:", + "Add some now": "現在就新增一些" } From fa14d0ed3c2e6f84ab38448faac2c14b51bc3e96 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 15 Oct 2018 14:41:00 -0600 Subject: [PATCH 40/77] Move tinter init to MatrixChat This is a much better place for it to live --- src/components/structures/MatrixChat.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index db5e898946..f385aacd40 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -1403,6 +1403,11 @@ export default React.createClass({ break; } }); + + // Fire the tinter right on startup to ensure the default theme is applied + // A later sync can/will correct the tint to be the right value for the user + const color_scheme = SettingsStore.getValue("roomColor"); + Tinter.tint(color_scheme.primary_color, color_scheme.secondary_color); }, /** From 0f592f5887575470f47adcf9b84f02d9441b0bd7 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Fri, 19 Oct 2018 16:39:07 +0200 Subject: [PATCH 41/77] Prepare changelog for v0.14.1 --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 40cb8c5283..00b035ac9c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +Changes in [0.14.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.14.1) (2018-10-19) +===================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.14.0...v0.14.1) + + * Apply the user's tint once the MatrixClientPeg is moderately ready + [\#2214](https://github.com/matrix-org/matrix-react-sdk/pull/2214) + Changes in [0.14.0](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.14.0) (2018-10-16) ===================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.14.0-rc.1...v0.14.0) From 167746f41d891d053643e061a583489f2826755a Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Fri, 19 Oct 2018 16:39:08 +0200 Subject: [PATCH 42/77] v0.14.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 93cbcd1c67..38ed26f23c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "0.14.0", + "version": "0.14.1", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { From 49efefa6307e6eb42ac64dfb0a9f7af5e8220b00 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 19 Oct 2018 14:18:05 -0600 Subject: [PATCH 43/77] Fix an error where React doesn't like value=null on a select This only happens when there are no canonical aliases for a room. --- src/components/views/room_settings/AliasSettings.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/views/room_settings/AliasSettings.js b/src/components/views/room_settings/AliasSettings.js index f9bf52cd24..92a025f10c 100644 --- a/src/components/views/room_settings/AliasSettings.js +++ b/src/components/views/room_settings/AliasSettings.js @@ -220,8 +220,9 @@ module.exports = React.createClass({ let canonical_alias_section; if (this.props.canSetCanonicalAlias) { let found = false; + const canonicalValue = this.state.canonicalAlias || ""; canonical_alias_section = ( - { Object.keys(self.state.domainToAliases).map((domain, i) => { From 9582c1e65a490c7797236b1740332d014a3bd66e Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 19 Oct 2018 15:33:23 -0600 Subject: [PATCH 44/77] Move all dialog buttons to the right and fix their order Fixes https://github.com/vector-im/riot-web/issues/5689 Some dialogs had their own CSS that prevented the buttons from being placed in the right spot. This has been fixed by using a generic standard for the buttons. The only strange dialog that needed more CSS was the devtools dialog due to the header. Not all dialogs have been checked - I spot-checked about half of them and verified the CSS manually on an established account. It's hard to get at all the dialogs without convoluted testing. --- res/css/_common.scss | 5 +++++ res/css/_components.scss | 1 - res/css/views/dialogs/_ChatInviteDialog.scss | 8 -------- res/css/views/dialogs/_DevtoolsDialog.scss | 4 ++++ res/css/views/dialogs/_QuestionDialog.scss | 18 ------------------ src/components/views/dialogs/DevtoolsDialog.js | 4 ++-- src/components/views/elements/DialogButtons.js | 10 +++++----- 7 files changed, 16 insertions(+), 34 deletions(-) delete mode 100644 res/css/views/dialogs/_QuestionDialog.scss diff --git a/res/css/_common.scss b/res/css/_common.scss index 38f576a532..bf67edc1c3 100644 --- a/res/css/_common.scss +++ b/res/css/_common.scss @@ -222,6 +222,11 @@ textarea { word-wrap: break-word; } +.mx_Dialog_buttons { + padding-right: 58px; + text-align: right; +} + .mx_Dialog button, .mx_Dialog input[type="submit"] { @mixin mx_DialogButton; margin-left: 0px; diff --git a/res/css/_components.scss b/res/css/_components.scss index 0e40b40a29..a09f895d5f 100644 --- a/res/css/_components.scss +++ b/res/css/_components.scss @@ -38,7 +38,6 @@ @import "./views/dialogs/_DevtoolsDialog.scss"; @import "./views/dialogs/_EncryptedEventDialog.scss"; @import "./views/dialogs/_GroupAddressPicker.scss"; -@import "./views/dialogs/_QuestionDialog.scss"; @import "./views/dialogs/_RoomUpgradeDialog.scss"; @import "./views/dialogs/_SetEmailDialog.scss"; @import "./views/dialogs/_SetMxIdDialog.scss"; diff --git a/res/css/views/dialogs/_ChatInviteDialog.scss b/res/css/views/dialogs/_ChatInviteDialog.scss index 6fc211743d..dcc0f5921a 100644 --- a/res/css/views/dialogs/_ChatInviteDialog.scss +++ b/res/css/views/dialogs/_ChatInviteDialog.scss @@ -14,14 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -.mx_ChatInviteDialog { - /* XXX: padding-left is on mx_Dialog but padding-right has subsequently - * been added on other dialogs. Surely all our dialogs should have consistent - * right hand padding? - */ - padding-right: 58px; -} - /* Using a textarea for this element, to circumvent autofill */ .mx_ChatInviteDialog_input, .mx_ChatInviteDialog_input:focus diff --git a/res/css/views/dialogs/_DevtoolsDialog.scss b/res/css/views/dialogs/_DevtoolsDialog.scss index a4a868bd11..3764bb13b3 100644 --- a/res/css/views/dialogs/_DevtoolsDialog.scss +++ b/res/css/views/dialogs/_DevtoolsDialog.scss @@ -14,6 +14,10 @@ See the License for the specific language governing permissions and limitations under the License. */ +.mx_DevTools_dialog { + padding-right: 58px; +} + .mx_DevTools_content { margin: 10px 0; } diff --git a/res/css/views/dialogs/_QuestionDialog.scss b/res/css/views/dialogs/_QuestionDialog.scss deleted file mode 100644 index 3d47f17592..0000000000 --- a/res/css/views/dialogs/_QuestionDialog.scss +++ /dev/null @@ -1,18 +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. -*/ -.mx_QuestionDialog { - padding-right: 58px; -} diff --git a/src/components/views/dialogs/DevtoolsDialog.js b/src/components/views/dialogs/DevtoolsDialog.js index ea198461c5..22ee44f81a 100644 --- a/src/components/views/dialogs/DevtoolsDialog.js +++ b/src/components/views/dialogs/DevtoolsDialog.js @@ -625,7 +625,7 @@ export default class DevtoolsDialog extends React.Component { let body; if (this.state.mode) { - body =
+ body =
{ this.state.mode.getLabel() }
Room ID: { this.props.roomId }
@@ -634,7 +634,7 @@ export default class DevtoolsDialog extends React.Component { } else { const classes = "mx_DevTools_RoomStateExplorer_button"; body =
-
+
{ _t('Toolbox') }
Room ID: { this.props.roomId }
diff --git a/src/components/views/elements/DialogButtons.js b/src/components/views/elements/DialogButtons.js index baf831415f..f314588caa 100644 --- a/src/components/views/elements/DialogButtons.js +++ b/src/components/views/elements/DialogButtons.js @@ -70,15 +70,15 @@ module.exports = React.createClass({ } return (
+ { cancelButton } + { this.props.children } - { this.props.children } - { cancelButton }
); }, From 275d88dd4f4f0a7c6fea946518294183b4165858 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 19 Oct 2018 16:22:20 -0600 Subject: [PATCH 45/77] Redirect widgets to another location before deleting them This is so that shutdown hooks in the widget can correctly fire, such as Jitsi's hook to abandon its hold on the webcam. Fixes https://github.com/vector-im/riot-web/issues/7351 --- src/components/views/elements/AppTile.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 7be0bab33c..71cd65c89f 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -318,6 +318,19 @@ export default class AppTile extends React.Component { } this.setState({deleting: true}); + // HACK: This is a really dirty way to ensure that Jitsi cleans up + // its hold on the webcam. Without this, the widget holds a media + // stream open, even after death. See https://github.com/vector-im/riot-web/issues/7351 + if (this.refs.appFrame) { + // In practice we could just do `+= ''` to trick the browser + // into thinking the URL changed, however I can foresee this + // being optimized out by a browser. Instead, we'll just point + // the iframe at a page that is reasonably safe to use in the + // event the iframe doesn't wink away. + // This is relative to where the Riot instance is located. + this.refs.appFrame.src = '/config.json'; + } + WidgetUtils.setRoomWidget( this.props.room.roomId, this.props.id, From c75beb01963228c21e0b4420caaa909851f555f4 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 19 Oct 2018 16:22:20 -0600 Subject: [PATCH 46/77] Revert "Redirect widgets to another location before deleting them" This reverts commit 275d88dd4f4f0a7c6fea946518294183b4165858. --- src/components/views/elements/AppTile.js | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 71cd65c89f..7be0bab33c 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -318,19 +318,6 @@ export default class AppTile extends React.Component { } this.setState({deleting: true}); - // HACK: This is a really dirty way to ensure that Jitsi cleans up - // its hold on the webcam. Without this, the widget holds a media - // stream open, even after death. See https://github.com/vector-im/riot-web/issues/7351 - if (this.refs.appFrame) { - // In practice we could just do `+= ''` to trick the browser - // into thinking the URL changed, however I can foresee this - // being optimized out by a browser. Instead, we'll just point - // the iframe at a page that is reasonably safe to use in the - // event the iframe doesn't wink away. - // This is relative to where the Riot instance is located. - this.refs.appFrame.src = '/config.json'; - } - WidgetUtils.setRoomWidget( this.props.room.roomId, this.props.id, From 51a03a700a08eaf625d2f7f0f22af3154e555fe6 Mon Sep 17 00:00:00 2001 From: Oliwer Date: Sat, 20 Oct 2018 15:16:06 +0000 Subject: [PATCH 47/77] Translated using Weblate (Polish) Currently translated at 91.6% (1164 of 1270 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/pl/ --- src/i18n/strings/pl.json | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/pl.json b/src/i18n/strings/pl.json index 245ee0c395..cc6d7ebd84 100644 --- a/src/i18n/strings/pl.json +++ b/src/i18n/strings/pl.json @@ -1146,7 +1146,7 @@ "was invited %(count)s times|one": "został zaproszony", "was banned %(count)s times|one": "został zablokowany", "was kicked %(count)s times|one": "został wyrzucony", - "Whether or not you're using the Richtext mode of the Rich Text Editor": "", + "Whether or not you're using the Richtext mode of the Rich Text Editor": "Niezależnie od tego, czy używasz trybu Richtext edytora tekstu w formacie RTF", "Call in Progress": "Łączenie w toku", "Permission Required": "Wymagane Pozwolenie", "Registration Required": "Wymagana Rejestracja", @@ -1155,5 +1155,28 @@ "deleted": "przekreślenie", "numbered-list": "lista numerowana", "bulleted-list": "wykropkowana lista", - "block-quote": "blok cytowany" + "block-quote": "blok cytowany", + "A conference call could not be started because the intgrations server is not available": "Połączenie grupowe nie może zostać rozpoczęte, ponieważ serwer jest niedostępny", + "A call is currently being placed!": "W tej chwili trwa rozmowa!", + "A call is already in progress!": "W tej chwili trwa połączenie!", + "You do not have permission to start a conference call in this room": "Nie posiadasz permisji do rozpoczęcia rozmowy grupowej w tym pokoju", + "Unignored user": "Nieignorowany użytkownik", + "Forces the current outbound group session in an encrypted room to be discarded": "Wymusza odrzucenie bieżącej sesji grupy wychodzącej w zaszyfrowanym pokoju", + "%(senderName)s added %(count)s %(addedAddresses)s as addresses for this room.|other": "%(senderName)s dodał %(addedAddresses)s jako adres tego pokoju.", + "%(senderName)s added %(count)s %(addedAddresses)s as addresses for this room.|one": "%(senderName)s dodał %(addedAddresses)s jako adresy tego pokoju.", + "%(senderName)s removed %(count)s %(removedAddresses)s as addresses for this room.|other": "%(senderName)s usunął %(removedAddresses)s jako adres tego pokoju.", + "%(senderName)s removed %(count)s %(removedAddresses)s as addresses for this room.|one": "%(senderName)s usunął %(removedAddresses)s jako adresy tego pokoju.", + "%(senderName)s added %(addedAddresses)s and removed %(removedAddresses)s as addresses for this room.": "%(senderName)s dodał %(addedAddresses)s i %(removedAddresses)s usunął adresy z tego pokoju.", + "%(senderName)s set the main address for this room to %(address)s.": "%(senderName)s ustawił domyślny adres dla tego pokoju jako %(address)s.", + "%(senderName)s removed the main address for this room.": "%(senderName)s usunął domyślny adres tego pokoju.", + "This homeserver has hit its Monthly Active User limit.": "Ten serwer osiągnął miesięczny limit aktywnego użytkownika.", + "This homeserver has exceeded one of its resource limits.": "Ten serwer przekroczył jeden z limitów.", + "Please contact your service administrator to continue using the service.": "Proszę, skontaktuj się z administratorem aby korzystać dalej z funkcji.", + "Unable to connect to Homeserver. Retrying...": "Nie można się połączyć z serwerem. Ponawanianie...", + "Sorry, your homeserver is too old to participate in this room.": "Przepraszamy, twój serwer jest zbyt stary by wziąć udział w tym pokoju.", + "Please contact your homeserver administrator.": "Proszę o kontakt z administratorem serwera.", + "Increase performance by only loading room members on first view": "Zwiększ wydajność, ładując tylko członków pokoju w pierwszym widoku", + "Enable widget screenshots on supported widgets": "Włącz widżety zrzutów ekranów na obsługiwanych widżetach", + "Show empty room list headings": "Pokaż nagłówki z pustym pokojem", + "In encrypted rooms, like this one, URL previews are disabled by default to ensure that your homeserver (where the previews are generated) cannot gather information about links you see in this room.": "W zaszyfrowanych pokojach, takich jak ten, podgląd adresów URL jest domyślnie wyłączony, aby upewnić się, że serwer (w którym generowane są podglądy) nie może zbierać informacji o linkach widocznych w tym pokoju." } From 2a6ae17e6a80d5b395da6ae3f152efc9194bb862 Mon Sep 17 00:00:00 2001 From: Karol Kosek Date: Sat, 20 Oct 2018 15:47:21 +0000 Subject: [PATCH 48/77] Translated using Weblate (Polish) Currently translated at 91.6% (1164 of 1270 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/pl/ --- src/i18n/strings/pl.json | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/i18n/strings/pl.json b/src/i18n/strings/pl.json index cc6d7ebd84..ee868b4d0b 100644 --- a/src/i18n/strings/pl.json +++ b/src/i18n/strings/pl.json @@ -143,11 +143,11 @@ "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Nie można nawiązać połączenia z serwerem przy użyciu HTTP podczas korzystania z HTTPS dla bieżącej strony. Użyj HTTPS lub włącz niebezpieczne skrypty.", "Can't load user settings": "Nie można załadować ustawień użytkownika", "Cannot add any more widgets": "Nie można dodać już więcej widżetów", - "%(senderName)s changed their profile picture.": "%(senderName)s zmienił swoje zdjęcie profilowe.", - "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s zmienił poziom mocy %(powerLevelDiffText)s.", - "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s zmienił nazwę pokoju na %(roomName)s.", - "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s usunął nazwę pokoju.", - "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s zmienił temat na \"%(topic)s\".", + "%(senderName)s changed their profile picture.": "%(senderName)s zmienił(a) swoje zdjęcie profilowe.", + "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s zmienił(a) poziom mocy %(powerLevelDiffText)s.", + "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s zmienił(a) nazwę pokoju na %(roomName)s.", + "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s usunął(-ęła) nazwę pokoju.", + "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s zmienił(a) temat na \"%(topic)s\".", "Changes to who can read history will only apply to future messages in this room": "Zmiany w dostępie do historii będą dotyczyć tylko przyszłych wiadomości w tym pokoju", "Changes your display nickname": "Zmień swój pseudonim", "Changes colour scheme of current room": "Zmień schemat kolorystyczny bieżącego pokoju", @@ -370,8 +370,8 @@ "Rejoin": "Dołącz ponownie", "Remote addresses for this room:": "Adresy zdalne dla tego pokoju:", "Remove Contact Information?": "Usunąć dane kontaktowe?", - "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s usunął swoją nazwę ekranową (%(oldDisplayName)s).", - "%(senderName)s removed their profile picture.": "%(senderName)s usunął swoje zdjęcie profilowe.", + "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s usunął(-ęła) swoją wyświetlaną nazwę (%(oldDisplayName)s).", + "%(senderName)s removed their profile picture.": "%(senderName)s usunął(-ęła) swoje zdjęcie profilowe.", "Remove %(threePid)s?": "Usunąć %(threePid)s?", "%(senderName)s requested a VoIP conference.": "%(senderName)s zażądał grupowego połączenia głosowego VoIP.", "Results from DuckDuckGo": "Wyniki z DuckDuckGo", @@ -629,9 +629,9 @@ " (unsupported)": " (niewspierany)", "Idle": "Bezczynny", "Check for update": "Sprawdź aktualizacje", - "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s zmienił awatar pokoju na ", - "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s usunął awatar pokoju.", - "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s zmienił awatar %(roomName)s", + "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s zmienił(a) awatar pokoju na ", + "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s usunął(-ęła) awatar pokoju.", + "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s zmienił(a) awatar %(roomName)s", "This will be your account name on the homeserver, or you can pick a different server.": "To będzie twoja nazwa konta na serwerze domowym; możesz też wybrać inny serwer.", "If you already have a Matrix account you can log in instead.": "Jeśli już posiadasz konto Matrix możesz się zalogować.", "Not a valid Riot keyfile": "Niepoprawny plik klucza Riot", @@ -640,7 +640,7 @@ "Do you want to set an email address?": "Czy chcesz ustawić adres e-mail?", "To return to your account in future you need to set a password": "By móc powrócić do swojego konta w przyszłości musisz ustawić hasło", "Share without verifying": "Udostępnij bez weryfikacji", - "You added a new device '%(displayName)s', which is requesting encryption keys.": "Dodałeś nowe urządzenie '%(displayName)s', które żąda kluczy szyfrujących.", + "You added a new device '%(displayName)s', which is requesting encryption keys.": "Dodałeś(-aś) nowe urządzenie '%(displayName)s', które żąda kluczy szyfrujących.", "Your unverified device '%(displayName)s' is requesting encryption keys.": "Twoje niezweryfikowane urządzenie '%(displayName)s' żąda kluczy szyfrujących.", "Encryption key request": "Żądanie klucza szyfrującego", "Autocomplete Delay (ms):": "Opóźnienie autouzupełniania (ms):", @@ -700,8 +700,8 @@ "Ignored user": "Użytkownik ignorowany", "You are now ignoring %(userId)s": "Ignorujesz teraz %(userId)s", "You are no longer ignoring %(userId)s": "Nie ignorujesz już %(userId)s", - "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s zmienił swoją wyświetlaną nazwę na %(displayName)s.", - "%(senderName)s changed the pinned messages for the room.": "%(senderName)s zmienił przypiętą wiadomość dla tego pokoju.", + "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s zmienił(a) swoją wyświetlaną nazwę na %(displayName)s.", + "%(senderName)s changed the pinned messages for the room.": "%(senderName)s zmienił(a) przypiętą wiadomość dla tego pokoju.", "Message Pinning": "Przypinanie wiadomości", "%(names)s and %(count)s others are typing|other": "%(names)s oraz %(count)s innych piszą", "%(names)s and %(count)s others are typing|one": "%(names)s oraz jedna inna osoba piszą", @@ -1162,13 +1162,13 @@ "You do not have permission to start a conference call in this room": "Nie posiadasz permisji do rozpoczęcia rozmowy grupowej w tym pokoju", "Unignored user": "Nieignorowany użytkownik", "Forces the current outbound group session in an encrypted room to be discarded": "Wymusza odrzucenie bieżącej sesji grupy wychodzącej w zaszyfrowanym pokoju", - "%(senderName)s added %(count)s %(addedAddresses)s as addresses for this room.|other": "%(senderName)s dodał %(addedAddresses)s jako adres tego pokoju.", - "%(senderName)s added %(count)s %(addedAddresses)s as addresses for this room.|one": "%(senderName)s dodał %(addedAddresses)s jako adresy tego pokoju.", - "%(senderName)s removed %(count)s %(removedAddresses)s as addresses for this room.|other": "%(senderName)s usunął %(removedAddresses)s jako adres tego pokoju.", - "%(senderName)s removed %(count)s %(removedAddresses)s as addresses for this room.|one": "%(senderName)s usunął %(removedAddresses)s jako adresy tego pokoju.", + "%(senderName)s added %(count)s %(addedAddresses)s as addresses for this room.|other": "%(senderName)s dodał(a) %(addedAddresses)s jako adres tego pokoju.", + "%(senderName)s added %(count)s %(addedAddresses)s as addresses for this room.|one": "%(senderName)s dodał(a) %(addedAddresses)s jako adres tego pokoju.", + "%(senderName)s removed %(count)s %(removedAddresses)s as addresses for this room.|other": "%(senderName)s usunął(-ęła) %(removedAddresses)s jako adres tego pokoju.", + "%(senderName)s removed %(count)s %(removedAddresses)s as addresses for this room.|one": "%(senderName)s usunął(-ęła) %(removedAddresses)s jako adres tego pokoju.", "%(senderName)s added %(addedAddresses)s and removed %(removedAddresses)s as addresses for this room.": "%(senderName)s dodał %(addedAddresses)s i %(removedAddresses)s usunął adresy z tego pokoju.", - "%(senderName)s set the main address for this room to %(address)s.": "%(senderName)s ustawił domyślny adres dla tego pokoju jako %(address)s.", - "%(senderName)s removed the main address for this room.": "%(senderName)s usunął domyślny adres tego pokoju.", + "%(senderName)s set the main address for this room to %(address)s.": "%(senderName)s ustawił(a) główny adres dla tego pokoju na %(address)s.", + "%(senderName)s removed the main address for this room.": "%(senderName)s usunął(-ęła) główny adres tego pokoju.", "This homeserver has hit its Monthly Active User limit.": "Ten serwer osiągnął miesięczny limit aktywnego użytkownika.", "This homeserver has exceeded one of its resource limits.": "Ten serwer przekroczył jeden z limitów.", "Please contact your service administrator to continue using the service.": "Proszę, skontaktuj się z administratorem aby korzystać dalej z funkcji.", From 2ac10dd6b15edc8bb9a3d782546fccb46017dae2 Mon Sep 17 00:00:00 2001 From: FeiYang Date: Sat, 20 Oct 2018 09:54:35 +0000 Subject: [PATCH 49/77] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (1270 of 1270 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 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json index e3492d1ef6..ad14a6a94c 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -165,7 +165,7 @@ "Success": "成功", "The default role for new room members is": "此聊天室新成員的預設角色是", "The main address for this room is": "此聊天室的主要地址是", - "This email address is already in use": "此電子郵件地址已經被使用", + "This email address is already in use": "這個電子郵件位址已被使用", "This email address was not found": "未找到此電子郵件地址", "The email address linked to your account must be entered.": "必須輸入和你帳號關聯的電子郵件地址。", "The file '%(fileName)s' exceeds this home server's size limit for uploads": "文件 '%(fileName)s' 超過了這個家伺服器的上傳大小限制", From b3d5612746048364128a521489a1953395e3c10f Mon Sep 17 00:00:00 2001 From: Victor Grousset Date: Sun, 21 Oct 2018 15:19:21 +0000 Subject: [PATCH 50/77] Translated using Weblate (Esperanto) Currently translated at 86.4% (1098 of 1270 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eo/ --- src/i18n/strings/eo.json | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/i18n/strings/eo.json b/src/i18n/strings/eo.json index 74cd5b255f..ccbf327f59 100644 --- a/src/i18n/strings/eo.json +++ b/src/i18n/strings/eo.json @@ -251,7 +251,7 @@ "Encrypted by a verified device": "Ĉifrita de kontrolita aparato", "Encrypted by an unverified device": "Ĉifrita de nekontrolita aparato", "Unencrypted message": "Neĉifrita mesaĝo", - "Please select the destination room for this message": "Bonvolu elekti celan ĉambron por ĉi tiu mesaĝo", + "Please select the destination room for this message": "Bonvolu elekti celan babilejon por tiu mesaĝo", "Blacklisted": "Senpova legi ĉifritajn mesaĝojn", "Verified": "Kontrolita", "Unverified": "Nekontrolita", @@ -292,19 +292,19 @@ "and %(count)s others...|other": "kaj %(count)s aliaj…", "and %(count)s others...|one": "kaj unu alia…", "Invited": "Invititaj", - "Filter room members": "Filtri ĉambranojn", + "Filter room members": "Filtri babilejanojn", "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (potenco je %(powerLevelNumber)s)", "Attachment": "Kunsendaĵo", "Upload Files": "Alŝuti dosierojn", "Are you sure you want to upload the following files?": "Ĉu vi certe volas alŝuti la jenajn dosierojn?", - "Encrypted room": "Ĉifrita ĉambro", - "Unencrypted room": "Neĉifrita ĉambro", + "Encrypted room": "Ĉifrita babilejo", + "Unencrypted room": "Neĉifrita babilejo", "Hangup": "Fini vokon", "Voice call": "Voĉvoko", "Video call": "Vidvoko", "Upload file": "Alŝuti dosieron", "Show Text Formatting Toolbar": "Montri tekstaranĝan breton", - "You do not have permission to post to this room": "Mankas al vi permeso afiŝi en la ĉambro", + "You do not have permission to post to this room": "Mankas al vi permeso afiŝi en tiu babilejo", "Turn Markdown on": "Ŝalti Marksubon", "Turn Markdown off": "Malŝalti Marksubon", "Hide Text Formatting Toolbar": "Kaŝi tekstaranĝan breton", @@ -339,7 +339,7 @@ "Offline": "Eksterreta", "Unknown": "Nekonata", "Seen by %(userName)s at %(dateTime)s": "Vidita de %(userName)s je %(dateTime)s", - "Unnamed room": "Sennoma ĉambro", + "Unnamed room": "Sennoma babilejo", "World readable": "Legebla de ĉiuj", "Guests can join": "Gastoj povas aliĝi", "No rooms to show": "Neniuj ĉambroj montreblas", @@ -347,11 +347,11 @@ "Save": "Konservi", "(~%(count)s results)|other": "(~%(count)s rezultoj)", "(~%(count)s results)|one": "(~%(count)s rezulto)", - "Join Room": "Aliĝi al ĉambro", + "Join Room": "Aliĝi al Babilejo", "Upload avatar": "Alŝuti profilbildon", "Remove avatar": "Forigi profilbildon", "Settings": "Agordoj", - "Forget room": "Forgesi ĉambron", + "Forget room": "Forgesi babilejon", "Search": "Serĉi", "Show panel": "Montri panelon", "Drop here to favourite": "Demetu tien ĉi por ŝati", @@ -453,17 +453,17 @@ "not set": "neagordita", "Remote addresses for this room:": "Foraj adresoj de ĉi tiu ĉambro:", "Addresses": "Adresoj", - "The main address for this room is": "La ĉefadreso por ĉi tiu ĉambro estas", - "Local addresses for this room:": "Lokaj adresoj por ĉi tiu ĉambro:", - "This room has no local addresses": "Ĉi tiu ĉambro ne havas lokajn adresojn", + "The main address for this room is": "La ĉefadreso por ĉi tiu babilejo estas", + "Local addresses for this room:": "Lokaj adresoj por ĉi tiu babilejo:", + "This room has no local addresses": "Ĉi tiu babilejo ne havas lokajn adresojn", "New address (e.g. #foo:%(localDomain)s)": "Nova adreso (ekz-e #io:%(localDomain)s)", "Invalid community ID": "Malvalida komunuma identigaĵo", "'%(groupId)s' is not a valid community ID": "‹%(groupId)s› ne estas valida komunuma identigaĵo", "New community ID (e.g. +foo:%(localDomain)s)": "Nova komunuma identigaĵo (ekz-e +io:%(localDomain)s)", "You have enabled URL previews by default.": "Vi ŝaltis implicitajn antaŭrigardojn al retpaĝoj.", "You have disabled URL previews by default.": "Vi malŝaltis implicitajn antaŭrigardojn al retpaĝoj.", - "URL previews are enabled by default for participants in this room.": "Antaŭrigardoj al retpaĝoj estas implicite ŝaltitaj por ĉambranoj ĉi tie.", - "URL previews are disabled by default for participants in this room.": "Antaŭrigardoj al retpaĝoj estas implicite malŝaltitaj por ĉambranoj ĉi tie.", + "URL previews are enabled by default for participants in this room.": "Antaŭrigardoj de URL-oj estas implicite ŝaltitaj por anoj de tiu ĉi babilejo.", + "URL previews are disabled by default for participants in this room.": "Antaŭrigardoj de URL-oj estas implicite malŝaltitaj por anoj de tiu ĉi babilejo.", "URL Previews": "Antaŭrigardoj al retpaĝoj", "Error decrypting audio": "Eraro malĉifrante sonon", "Error decrypting attachment": "Eraro malĉifrante kunsendaĵon", From 83ebe3752dce748509f0cc3cbc9075296bcf177c Mon Sep 17 00:00:00 2001 From: hamster Date: Sat, 20 Oct 2018 16:07:20 +0000 Subject: [PATCH 51/77] Translated using Weblate (Polish) Currently translated at 91.8% (1166 of 1270 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/pl/ --- src/i18n/strings/pl.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/pl.json b/src/i18n/strings/pl.json index ee868b4d0b..977b94c718 100644 --- a/src/i18n/strings/pl.json +++ b/src/i18n/strings/pl.json @@ -1178,5 +1178,7 @@ "Increase performance by only loading room members on first view": "Zwiększ wydajność, ładując tylko członków pokoju w pierwszym widoku", "Enable widget screenshots on supported widgets": "Włącz widżety zrzutów ekranów na obsługiwanych widżetach", "Show empty room list headings": "Pokaż nagłówki z pustym pokojem", - "In encrypted rooms, like this one, URL previews are disabled by default to ensure that your homeserver (where the previews are generated) cannot gather information about links you see in this room.": "W zaszyfrowanych pokojach, takich jak ten, podgląd adresów URL jest domyślnie wyłączony, aby upewnić się, że serwer (w którym generowane są podglądy) nie może zbierać informacji o linkach widocznych w tym pokoju." + "In encrypted rooms, like this one, URL previews are disabled by default to ensure that your homeserver (where the previews are generated) cannot gather information about links you see in this room.": "W zaszyfrowanych pokojach, takich jak ten, podgląd adresów URL jest domyślnie wyłączony, aby upewnić się, że serwer (w którym generowane są podglądy) nie może zbierać informacji o linkach widocznych w tym pokoju.", + "When someone puts a URL in their message, a URL preview can be shown to give more information about that link such as the title, description, and an image from the website.": "Gdy ktoś umieści URL w wiadomości, można wyświetlić podgląd adresu URL, aby podać więcej informacji o tym łączu, takich jak tytuł, opis i obraz ze strony internetowej.", + "This event could not be displayed": "Ten event nie może zostać wyświetlony" } From e9a62bff2ebd0398fc313a6aec0c3f8ecf2e2fe7 Mon Sep 17 00:00:00 2001 From: sergio Date: Sat, 20 Oct 2018 19:20:01 +0000 Subject: [PATCH 52/77] Translated using Weblate (Russian) Currently translated at 95.9% (1219 of 1270 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 25e0d0b78d..b711b43447 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -1234,5 +1234,7 @@ "Put a link back to the old room at the start of the new room so people can see old messages": "Разместим ссылку на старую комнату, чтобы люди могли видеть старые сообщения", "Please contact your service administrator to continue using this service.": "Пожалуйста, обратитесь к вашему администратору, чтобы продолжить использовать этот сервис.", "Increase performance by only loading room members on first view": "Увеличьте производительность, загрузив только список участников комнаты", - "Lazy loading members not supported": "Задержка загрузки элементов не поддерживается" + "Lazy loading members not supported": "Задержка загрузки элементов не поддерживается", + "Registration Required": "Требуется регистрация", + "You need to register to do this. Would you like to register now?": "Необходимо зарегистрироваться. Хотите зарегистрироваться?" } From 4335dfea16875804fdacfd2fc5d25dedc93b27ad Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Mon, 22 Oct 2018 09:56:55 +0000 Subject: [PATCH 53/77] Translated using Weblate (English (United States)) Currently translated at 65.1% (828 of 1270 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/en_US/ --- src/i18n/strings/en_US.json | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/en_US.json b/src/i18n/strings/en_US.json index 6f0708f0c2..d8733ab05a 100644 --- a/src/i18n/strings/en_US.json +++ b/src/i18n/strings/en_US.json @@ -567,7 +567,7 @@ "Active call (%(roomName)s)": "Active call (%(roomName)s)", "Accept": "Accept", "Add": "Add", - "Admin Tools": "Admin tools", + "Admin Tools": "Admin Tools", "Alias (optional)": "Alias (optional)", "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.": "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.", "Click here to join the discussion!": "Click here to join the discussion!", @@ -828,5 +828,15 @@ "Collapse panel": "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!": "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...": "Checking for an update...", - "There are advanced notifications which are not shown here": "There are advanced notifications which are not shown here" + "There are advanced notifications which are not shown here": "There are advanced notifications which are not shown here", + "The platform you're on": "The platform you're on", + "The version of Riot.im": "The version of Riot.im", + "Whether or not you're logged in (we don't record your user name)": "Whether or not you're logged in (we don't record your user name)", + "Your language of choice": "Your language of choice", + "Which officially provided instance you are using, if any": "Which officially provided instance you are using, if any", + "Whether or not you're using the Richtext mode of the Rich Text Editor": "Whether or not you're using the Richtext mode of the Rich Text Editor", + "Your homeserver's URL": "Your homeserver's URL", + "Your identity server's URL": "Your identity server's URL", + "e.g. %(exampleValue)s": "e.g. %(exampleValue)s", + "Every page you use in the app": "Every page you use in the app" } From 60b1b30c5194105bcfd78744990266b431077c72 Mon Sep 17 00:00:00 2001 From: Victor Grousset Date: Mon, 22 Oct 2018 16:58:20 +0000 Subject: [PATCH 54/77] Translated using Weblate (Esperanto) Currently translated at 86.4% (1098 of 1270 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eo/ --- src/i18n/strings/eo.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/eo.json b/src/i18n/strings/eo.json index ccbf327f59..6835ca355c 100644 --- a/src/i18n/strings/eo.json +++ b/src/i18n/strings/eo.json @@ -360,7 +360,7 @@ "Drop here to demote": "Demeti tien ĉi por malpligravigi", "Drop here to tag %(section)s": "Demeti tien ĉi por marki %(section)s", "Press to start a chat with someone": "Premu por komenci babilon kun iu", - "You're not in any rooms yet! Press to make a room or to browse the directory": "Vi ankoraŭ estas en neniu ĉambro! Premu por krei ĉambron aŭ por esplori la ĉambrujon", + "You're not in any rooms yet! Press to make a room or to browse the directory": "Vi ankoraŭ estas en neniuj Babilejoj! Premu por krei Babilejon aŭ por esplori la Babilejujon", "Community Invites": "Komunumaj invitoj", "Invites": "Invitoj", "Favourites": "Ŝatataj", @@ -371,7 +371,7 @@ "Unable to ascertain that the address this invite was sent to matches one associated with your account.": "Ne certigeblas, ke la adreso, kien ĉi tiu invito sendiĝis, kongruas kun tiu rilata al via konto.", "This invitation was sent to an email address which is not associated with this account:": "Ĉi tiu invito sendiĝis al retpoŝtadreso, kiu ne rilatas al ĉi tiu konto:", "You may wish to login with a different account, or add this email to this account.": "Vi povas saluti per alia konto, aŭ aldoni ĉi tiun retpoŝtadreson al tiu ĉi konto.", - "You have been invited to join this room by %(inviterName)s": "%(inviterName)s vin invitis al ĉi tiu ĉambro", + "You have been invited to join this room by %(inviterName)s": "%(inviterName)s vin invitis al ĉi tiu babilejo", "Would you like to accept or decline this invitation?": "Ĉu vi volas akceptirifuzi ĉi tiun inviton?", "Reason: %(reasonText)s": "Kialo: %(reasonText)s", "Rejoin": "Realiĝi", From 2b9a646760da91163eb22a2875f6e55453ac2e0f Mon Sep 17 00:00:00 2001 From: Szimszon Date: Wed, 17 Oct 2018 17:50:11 +0000 Subject: [PATCH 55/77] Translated using Weblate (Hungarian) Currently translated at 100.0% (1271 of 1271 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 8ce023f377..05dc1d479c 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -1294,5 +1294,6 @@ "Clear cache and resync": "Gyorsítótár törlése és újraszinkronizálás", "Please accept all of the policies": "Kérlek fogadd el a felhasználói feltételeket", "Please review and accept the policies of this homeserver:": "Kérlek nézd át és fogadd el a Matrix szerver felhasználói feltételeit:", - "Add some now": "Adj hozzá párat" + "Add some now": "Adj hozzá párat", + "Joining room...": "Belépés a szobába.." } From 78f527cf950a9c8ec6b27fc09b3e5b9f7e208a74 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 22 Oct 2018 15:14:21 -0600 Subject: [PATCH 56/77] Remove unused classes --- src/components/views/groups/GroupMemberList.js | 2 +- src/components/views/rooms/MemberList.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/views/groups/GroupMemberList.js b/src/components/views/groups/GroupMemberList.js index faf172083f..38c679a5b5 100644 --- a/src/components/views/groups/GroupMemberList.js +++ b/src/components/views/groups/GroupMemberList.js @@ -165,7 +165,7 @@ export default React.createClass({ return (
{ inputBox } - + { joined } { invited } diff --git a/src/components/views/rooms/MemberList.js b/src/components/views/rooms/MemberList.js index 67a6effc81..41434cc6f9 100644 --- a/src/components/views/rooms/MemberList.js +++ b/src/components/views/rooms/MemberList.js @@ -447,7 +447,7 @@ module.exports = React.createClass({ return (
{ inputBox } - + Date: Mon, 22 Oct 2018 20:55:21 -0500 Subject: [PATCH 57/77] Change leave room button text, OK -> Leave Signed-off-by: Aaron Raimist --- src/components/structures/MatrixChat.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index f385aacd40..b725e5f9ab 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -1034,6 +1034,7 @@ export default React.createClass({ { warnings } ), + button: _t("Leave"), onFinished: (shouldLeave) => { if (shouldLeave) { const d = MatrixClientPeg.get().leave(roomId); From 6774fd7acc12aa1472f0ba1775f9bd9f1c0b2112 Mon Sep 17 00:00:00 2001 From: FeiYang Date: Sat, 20 Oct 2018 09:54:35 +0000 Subject: [PATCH 58/77] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (1271 of 1271 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 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json index ad14a6a94c..ba23947fc2 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -1292,5 +1292,6 @@ "Clear cache and resync": "清除快取並重新同步", "Please accept all of the policies": "請接受所有政策", "Please review and accept the policies of this homeserver:": "請審閱並接受此家伺服器的政策:", - "Add some now": "現在就新增一些" + "Add some now": "現在就新增一些", + "Joining room...": "正在加入聊天室……" } From 4b3c86595949b49ba278938ad18e038e2178d3ec Mon Sep 17 00:00:00 2001 From: Aaron Raimist Date: Mon, 22 Oct 2018 23:07:41 -0500 Subject: [PATCH 59/77] lint: make colorScheme camel case Signed-off-by: Aaron Raimist --- src/components/structures/MatrixChat.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index f385aacd40..dce1ac698d 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -1406,8 +1406,8 @@ export default React.createClass({ // Fire the tinter right on startup to ensure the default theme is applied // A later sync can/will correct the tint to be the right value for the user - const color_scheme = SettingsStore.getValue("roomColor"); - Tinter.tint(color_scheme.primary_color, color_scheme.secondary_color); + const colorScheme = SettingsStore.getValue("roomColor"); + Tinter.tint(colorScheme.primary_color, colorScheme.secondary_color); }, /** From cb033bcaddb08e649b2f3de804c992e7dca6ca2f Mon Sep 17 00:00:00 2001 From: Aaron Raimist Date: Mon, 22 Oct 2018 23:15:28 -0500 Subject: [PATCH 60/77] Why not change it everywhere while we're at it Signed-off-by: Aaron Raimist --- src/components/structures/RoomView.js | 10 +++++----- src/settings/handlers/RoomAccountSettingsHandler.js | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 54f51c7a71..5bf6146525 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -678,8 +678,8 @@ module.exports = React.createClass({ if (!room) return; console.log("Tinter.tint from updateTint"); - const color_scheme = SettingsStore.getValue("roomColor", room.roomId); - Tinter.tint(color_scheme.primary_color, color_scheme.secondary_color); + const colorScheme = SettingsStore.getValue("roomColor", room.roomId); + Tinter.tint(colorScheme.primary_color, colorScheme.secondary_color); }, onAccountData: function(event) { @@ -693,11 +693,11 @@ module.exports = React.createClass({ onRoomAccountData: function(event, room) { if (room.roomId == this.state.roomId) { const type = event.getType(); - if (type === "org.matrix.room.color_scheme") { - const color_scheme = event.getContent(); + if (type === "org.matrix.room.colorScheme") { + const colorScheme = event.getContent(); // XXX: we should validate the event console.log("Tinter.tint from onRoomAccountData"); - Tinter.tint(color_scheme.primary_color, color_scheme.secondary_color); + Tinter.tint(colorScheme.primary_color, colorScheme.secondary_color); } else if (type === "org.matrix.room.preview_urls" || type === "im.vector.web.settings") { // non-e2ee url previews are stored in legacy event type `org.matrix.room.preview_urls` this._updatePreviewUrlVisibility(room); diff --git a/src/settings/handlers/RoomAccountSettingsHandler.js b/src/settings/handlers/RoomAccountSettingsHandler.js index d0dadc2de7..ae8fb79297 100644 --- a/src/settings/handlers/RoomAccountSettingsHandler.js +++ b/src/settings/handlers/RoomAccountSettingsHandler.js @@ -36,7 +36,7 @@ export default class RoomAccountSettingsHandler extends SettingsHandler { // The event content should already be in an appropriate format, we just need // to get the right value. // don't fallback to {} because thats truthy and would imply there is an event specifying tint - return this._getSettings(roomId, "org.matrix.room.color_scheme"); + return this._getSettings(roomId, "org.matrix.room.colorScheme"); } const settings = this._getSettings(roomId) || {}; @@ -54,7 +54,7 @@ export default class RoomAccountSettingsHandler extends SettingsHandler { // Special case room color if (settingName === "roomColor") { // The new value should match our requirements, we just need to store it in the right place. - return MatrixClientPeg.get().setRoomAccountData(roomId, "org.matrix.room.color_scheme", newValue); + return MatrixClientPeg.get().setRoomAccountData(roomId, "org.matrix.room.colorScheme", newValue); } const content = this._getSettings(roomId) || {}; From 1aa308595859469cd592a7166c1ac1c37f23c059 Mon Sep 17 00:00:00 2001 From: Aaron Raimist Date: Mon, 22 Oct 2018 23:33:33 -0500 Subject: [PATCH 61/77] Oh right, can't change these Signed-off-by: Aaron Raimist --- src/components/structures/RoomView.js | 2 +- src/settings/handlers/RoomAccountSettingsHandler.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 5bf6146525..e20ac54006 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -693,7 +693,7 @@ module.exports = React.createClass({ onRoomAccountData: function(event, room) { if (room.roomId == this.state.roomId) { const type = event.getType(); - if (type === "org.matrix.room.colorScheme") { + if (type === "org.matrix.room.color_scheme") { const colorScheme = event.getContent(); // XXX: we should validate the event console.log("Tinter.tint from onRoomAccountData"); diff --git a/src/settings/handlers/RoomAccountSettingsHandler.js b/src/settings/handlers/RoomAccountSettingsHandler.js index ae8fb79297..d0dadc2de7 100644 --- a/src/settings/handlers/RoomAccountSettingsHandler.js +++ b/src/settings/handlers/RoomAccountSettingsHandler.js @@ -36,7 +36,7 @@ export default class RoomAccountSettingsHandler extends SettingsHandler { // The event content should already be in an appropriate format, we just need // to get the right value. // don't fallback to {} because thats truthy and would imply there is an event specifying tint - return this._getSettings(roomId, "org.matrix.room.colorScheme"); + return this._getSettings(roomId, "org.matrix.room.color_scheme"); } const settings = this._getSettings(roomId) || {}; @@ -54,7 +54,7 @@ export default class RoomAccountSettingsHandler extends SettingsHandler { // Special case room color if (settingName === "roomColor") { // The new value should match our requirements, we just need to store it in the right place. - return MatrixClientPeg.get().setRoomAccountData(roomId, "org.matrix.room.colorScheme", newValue); + return MatrixClientPeg.get().setRoomAccountData(roomId, "org.matrix.room.color_scheme", newValue); } const content = this._getSettings(roomId) || {}; From 690405d3f6fa545033f8840c68ee48584ca7ecc2 Mon Sep 17 00:00:00 2001 From: RainSlide Date: Tue, 23 Oct 2018 05:12:50 +0000 Subject: [PATCH 62/77] Translated using Weblate (Chinese (Simplified)) Currently translated at 98.7% (1255 of 1271 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 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/i18n/strings/zh_Hans.json b/src/i18n/strings/zh_Hans.json index cd8ae2f0e3..90c162e39b 100644 --- a/src/i18n/strings/zh_Hans.json +++ b/src/i18n/strings/zh_Hans.json @@ -17,7 +17,7 @@ "Disinvite": "取消邀请", "Display name": "昵称", "Displays action": "显示操作", - "Don't send typing notifications": "不要发送我的打字状态", + "Don't send typing notifications": "不要发送“正在输入”提示", "Download %(text)s": "下载 %(text)s", "Email": "电子邮箱", "Email address": "邮箱地址", @@ -488,7 +488,7 @@ "This room is not recognised.": "无法识别此聊天室。", "To get started, please pick a username!": "请点击用户名!", "Unable to add email address": "无法添加邮箱地址", - "Automatically replace plain text Emoji": "文字、表情自动转换", + "Automatically replace plain text Emoji": "将符号表情转换为 Emoji", "To reset your password, enter the email address linked to your account": "要重置你的密码,请输入关联你的帐号的邮箱地址", "Unable to verify email address.": "无法验证邮箱地址。", "Unknown room %(roomId)s": "未知聊天室 %(roomId)s", @@ -1210,7 +1210,7 @@ "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "这些聊天室对社区成员可见。社区成员可通过点击来加入它们。", "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 页面。
点击这里即可打开设置添加详细介绍!", "Failed to load %(groupId)s": "%(groupId)s 加载失败", - "This room is not public. You will not be able to rejoin without an invite.": "此聊天室不是公开的。没有邀请的话,您将无法重新加入。", + "This room is not public. You will not be able to rejoin without an invite.": "此聊天室不是公开聊天室。如果没有成员邀请,您将无法重新加入。", "Can't leave Server Notices room": "无法退出服务器公告聊天室", "This room is used for important messages from the Homeserver, so you cannot leave it.": "此聊天室是用于发布来自主服务器的重要讯息的,所以您不能退出它。", "Terms and Conditions": "条款与要求", From a6c78ace4fbb2e64ca7935c19edf189517e3042e Mon Sep 17 00:00:00 2001 From: Aaron Raimist Date: Tue, 23 Oct 2018 12:25:08 -0500 Subject: [PATCH 63/77] Add warning when administrator leaves community Signed-off-by: Aaron Raimist --- src/components/structures/GroupView.js | 28 ++++++++- src/i18n/strings/en_EN.json | 85 +++++++++++++------------- 2 files changed, 68 insertions(+), 45 deletions(-) diff --git a/src/components/structures/GroupView.js b/src/components/structures/GroupView.js index d104019a01..ddd3cb87bb 100644 --- a/src/components/structures/GroupView.js +++ b/src/components/structures/GroupView.js @@ -746,13 +746,37 @@ export default React.createClass({ }); }, + _leaveGroupWarnings: function() { + const warnings = []; + + if (this.state.isUserPrivileged) { + warnings.push(( + + { " " /* Whitespace, otherwise the sentences get smashed together */ } + { _t("You are an administrator of this community") + ". " } + { _t("You will not be able to rejoin without an invite from another administrator.") } + + )); + } + + return warnings; + }, + + _onLeaveClick: function() { const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); + const warnings = this._leaveGroupWarnings(); + Modal.createTrackedDialog('Leave Group', '', QuestionDialog, { title: _t("Leave Community"), - description: _t("Leave %(groupName)s?", {groupName: this.props.groupId}), + description: ( + + { _t("Leave %(groupName)s?", {groupName: this.props.groupId}) } + { warnings } + + ), button: _t("Leave"), - danger: true, + danger: this.state.isUserPrivileged, onFinished: async (confirmed) => { if (!confirmed) return; diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index e0f4663532..364aaeac9a 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -43,10 +43,6 @@ "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", @@ -86,7 +82,6 @@ "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", @@ -211,6 +206,11 @@ "%(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", "This homeserver has hit its Monthly Active User limit.": "This homeserver has hit its Monthly Active User limit.", "This homeserver has exceeded one of its resource limits.": "This homeserver has exceeded one of its resource limits.", "Please contact your service administrator to continue using the service.": "Please contact your service administrator to continue using the service.", @@ -331,31 +331,6 @@ "Off": "Off", "On": "On", "Noisy": "Noisy", - "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.", - "In encrypted rooms, like this one, URL previews are disabled by default to ensure that your homeserver (where the previews are generated) cannot gather information about links you see in this room.": "In encrypted rooms, like this one, URL previews are disabled by default to ensure that your homeserver (where the previews are generated) cannot gather information about links you see in this room.", - "URL Previews": "URL Previews", - "When someone puts a URL in their message, a URL preview can be shown to give more information about that link such as the title, description, and an image from the website.": "When someone puts a URL in their message, a URL preview can be shown to give more information about that link such as the title, description, and an image from the website.", "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", @@ -419,6 +394,7 @@ "Make Moderator": "Make Moderator", "Admin Tools": "Admin Tools", "Level:": "Level:", + "Close": "Close", "and %(count)s others...|other": "and %(count)s others...", "and %(count)s others...|one": "and one other...", "Invited": "Invited", @@ -460,11 +436,11 @@ "At this time it is not possible to reply with an emote.": "At this time it is not possible to reply with an emote.", "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", @@ -599,13 +575,37 @@ "All Rooms": "All Rooms", "Cancel": "Cancel", "You don't currently have any stickerpacks enabled": "You don't currently have any stickerpacks enabled", - "Add a stickerpack": "Add a stickerpack", + "Add some now": "Add some now", "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", + "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.", + "In encrypted rooms, like this one, URL previews are disabled by default to ensure that your homeserver (where the previews are generated) cannot gather information about links you see in this room.": "In encrypted rooms, like this one, URL previews are disabled by default to ensure that your homeserver (where the previews are generated) cannot gather information about links you see in this room.", + "URL Previews": "URL Previews", + "When someone puts a URL in their message, a URL preview can be shown to give more information about that link such as the title, description, and an image from the website.": "When someone puts a URL in their message, a URL preview can be shown to give more information about that link such as the title, description, and an image from the website.", "Sunday": "Sunday", "Monday": "Monday", "Tuesday": "Tuesday", @@ -644,7 +644,6 @@ "Dismiss": "Dismiss", "To continue, please enter your password.": "To continue, please enter your password.", "Password:": "Password:", - "Please accept all of the policies": "Please accept all of the policies", "Please review and accept the policies of this homeserver:": "Please review and accept the policies of this homeserver:", "An email has been sent to %(emailAddress)s": "An email has been sent to %(emailAddress)s", "Please check your email to continue registration.": "Please check your email to continue registration.", @@ -887,6 +886,10 @@ "Ignore request": "Ignore request", "Loading device info...": "Loading device info...", "Encryption key request": "Encryption key request", + "You've previously used Riot on %(host)s with lazy loading of members enabled. In this version lazy loading is disabled. As the local cache is not compatible between these two settings, Riot needs to resync your account.": "You've previously used Riot on %(host)s with lazy loading of members enabled. In this version lazy loading is disabled. As the local cache is not compatible between these two settings, Riot needs to resync your account.", + "If the other version of Riot is still open in another tab, please close it as using Riot on the same host with both lazy loading enabled and disabled simultaneously will cause issues.": "If the other version of Riot is still open in another tab, please close it as using Riot on the same host with both lazy loading enabled and disabled simultaneously will cause issues.", + "Incompatible local cache": "Incompatible local cache", + "Clear cache and resync": "Clear cache and resync", "Riot now uses 3-5x less memory, by only loading information about other users when needed. Please wait whilst we resynchronise with the server!": "Riot now uses 3-5x less memory, by only loading information about other users when needed. Please wait whilst we resynchronise with the server!", "Updating Riot": "Updating Riot", "Failed to upgrade room": "Failed to upgrade room", @@ -987,7 +990,7 @@ "You must register to use this functionality": "You must register to use this functionality", "You must join the room to see its files": "You must join the room to see its files", "There are no visible files in this room": "There are no visible files in this room", - "

HTML for your community's page

\r\n

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

\r\n

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

\r\n": "

HTML for your community's page

\r\n

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

\r\n

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

\r\n", + "

HTML for your community's page

\n

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

\n

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

\n": "

HTML 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", "Add rooms to the community summary": "Add rooms to the community summary", "Which rooms would you like to add to this summary?": "Which rooms would you like to add to this summary?", "Add to summary": "Add to summary", @@ -1005,6 +1008,8 @@ "Failed to update community": "Failed to update community", "Unable to accept invite": "Unable to accept invite", "Unable to join community": "Unable to join community", + "You are an administrator of this community": "You are an administrator of this community", + "You will not be able to rejoin without an invite from another administrator.": "You will not be able to rejoin without an invite from another administrator.", "Leave Community": "Leave Community", "Leave %(groupName)s?": "Leave %(groupName)s?", "Unable to leave community": "Unable to leave community", @@ -1017,7 +1022,6 @@ "%(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", "Who can join this community?": "Who can join this community?", "Everyone": "Everyone", @@ -1264,10 +1268,5 @@ "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", - "You've previously used Riot on %(host)s with lazy loading of members enabled. In this version lazy loading is disabled. As the local cache is not compatible between these two settings, Riot needs to resync your account.": "You've previously used Riot on %(host)s with lazy loading of members enabled. In this version lazy loading is disabled. As the local cache is not compatible between these two settings, Riot needs to resync your account.", - "If the other version of Riot is still open in another tab, please close it as using Riot on the same host with both lazy loading enabled and disabled simultaneously will cause issues.": "If the other version of Riot is still open in another tab, please close it as using Riot on the same host with both lazy loading enabled and disabled simultaneously will cause issues.", - "Incompatible local cache": "Incompatible local cache", - "Clear cache and resync": "Clear cache and resync", - "Add some now": "Add some now" + "Failed to add tag %(tagName)s to room": "Failed to add tag %(tagName)s to room" } From 92bfb42784393b0e83dc52740fbe2cb4248f7b26 Mon Sep 17 00:00:00 2001 From: Aaron Raimist Date: Tue, 23 Oct 2018 13:11:34 -0500 Subject: [PATCH 64/77] Use one string instead of two Signed-off-by: Aaron Raimist --- src/components/structures/GroupView.js | 5 +++-- src/i18n/strings/en_EN.json | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/components/structures/GroupView.js b/src/components/structures/GroupView.js index ddd3cb87bb..8a2b7a23ca 100644 --- a/src/components/structures/GroupView.js +++ b/src/components/structures/GroupView.js @@ -753,8 +753,9 @@ export default React.createClass({ warnings.push(( { " " /* Whitespace, otherwise the sentences get smashed together */ } - { _t("You are an administrator of this community") + ". " } - { _t("You will not be able to rejoin without an invite from another administrator.") } + { /* eslint-disable max-len */ } + { _t("You are an administrator of this community. You will not be able to rejoin without an invite from another administrator.") } + { /* eslint-enable max-len */ } )); } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 364aaeac9a..2885eb68a7 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1008,8 +1008,7 @@ "Failed to update community": "Failed to update community", "Unable to accept invite": "Unable to accept invite", "Unable to join community": "Unable to join community", - "You are an administrator of this community": "You are an administrator of this community", - "You will not be able to rejoin without an invite from another administrator.": "You will not be able to rejoin without an invite from another administrator.", + "You are an administrator of this community. You will not be able to rejoin without an invite from another administrator.": "You are an administrator of this community. You will not be able to rejoin without an invite from another administrator.", "Leave Community": "Leave Community", "Leave %(groupName)s?": "Leave %(groupName)s?", "Unable to leave community": "Unable to leave community", @@ -1022,6 +1021,7 @@ "%(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", "Who can join this community?": "Who can join this community?", "Everyone": "Everyone", From fe901142aa669e329458ec517560e11194d6b1ad Mon Sep 17 00:00:00 2001 From: Aaron Raimist Date: Tue, 23 Oct 2018 17:20:54 -0500 Subject: [PATCH 65/77] Split long string over two lines Signed-off-by: Aaron Raimist --- src/components/structures/GroupView.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/components/structures/GroupView.js b/src/components/structures/GroupView.js index 8a2b7a23ca..5d23194702 100644 --- a/src/components/structures/GroupView.js +++ b/src/components/structures/GroupView.js @@ -753,9 +753,8 @@ export default React.createClass({ warnings.push(( { " " /* Whitespace, otherwise the sentences get smashed together */ } - { /* eslint-disable max-len */ } - { _t("You are an administrator of this community. You will not be able to rejoin without an invite from another administrator.") } - { /* eslint-enable max-len */ } + { _t("You are an administrator of this community. You will not be " + + "able to rejoin without an invite from another administrator.") } )); } From ef50e05580d9c2dc09d80d8b095d4e6ddb09d7fe Mon Sep 17 00:00:00 2001 From: Victor Grousset Date: Tue, 23 Oct 2018 12:26:40 +0000 Subject: [PATCH 66/77] Translated using Weblate (Esperanto) Currently translated at 86.3% (1098 of 1271 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eo/ --- src/i18n/strings/eo.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/i18n/strings/eo.json b/src/i18n/strings/eo.json index 6835ca355c..84912dccf9 100644 --- a/src/i18n/strings/eo.json +++ b/src/i18n/strings/eo.json @@ -376,14 +376,14 @@ "Reason: %(reasonText)s": "Kialo: %(reasonText)s", "Rejoin": "Realiĝi", "You have been kicked from %(roomName)s by %(userName)s.": "%(userName)s vin forpelis de %(roomName)s.", - "You have been kicked from this room by %(userName)s.": "%(userName)s vin forpelis de tiu ĉi ĉambro.", + "You have been kicked from this room by %(userName)s.": "%(userName)s vin forpelis de tiu babilejo.", "You have been banned from %(roomName)s by %(userName)s.": "%(userName)s vi forbaris de %(roomName)s.", - "You have been banned from this room by %(userName)s.": "%(userName)s vin forbaris de tiu ĉi ĉambro.", - "This room": "Ĉi tiu ĉambro", + "You have been banned from this room by %(userName)s.": "%(userName)s vin forbaris de tiu babilejo.", + "This room": "Ĉi tiu babilejo", "%(roomName)s does not exist.": "%(roomName)s ne ekzistas.", "%(roomName)s is not accessible at this time.": "%(roomName)s ne estas atingebla nun.", "You are trying to access %(roomName)s.": "Vi provas atingi %(roomName)s.", - "You are trying to access a room.": "Vi provas atingi ĉambron.", + "You are trying to access a room.": "Vi provas aliri babilejon.", "Click here to join the discussion!": "Klaku ĉi tie por aliĝi al la diskuto!", "This is a preview of this room. Room interactions have been disabled": "Tio ĉi estas antaŭrigardo al la ĉambro. Ĉambraj interagoj estas malŝaltitaj", "To change the room's avatar, you must be a": "Por ŝanĝi la ĉambran profilbildon, vi devas esti", @@ -419,7 +419,7 @@ "To link to a room it must have an address.": "Por esti ligebla, ĉambro devas havi adreson.", "Guests cannot join this room even if explicitly invited.": "Gastoj ne povas aliĝi ĉi tiun ĉambron eĉ kun malimplica invito.", "Click here to fix": "Klaku ĉi tie por riparo", - "Who can access this room?": "Kiu povas atingi ĉi tiun ĉambron?", + "Who can access this room?": "Kiu povas aliri ĉi tiun ĉambron?", "Only people who have been invited": "Nur invititaj uzantoj", "Anyone who knows the room's link, apart from guests": "Iu ajn kun la ligilo, krom gastoj", "Anyone who knows the room's link, including guests": "Iu ajn kun la ligilo, inkluzive gastojn", From 78d8d22457fd481e4b961e7c65cd5646c1b15557 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 24 Oct 2018 16:46:06 +0100 Subject: [PATCH 67/77] Fix emoji replacement in composer * Re-scan the slate document tree on each emoji replacement since doing a replacement will invalidate all the offsets we have. * Reset the emoji regex each time we use it. Fixes https://github.com/vector-im/riot-web/issues/7550 --- .../views/rooms/MessageComposerInput.js | 56 ++++++++++++------- 1 file changed, 35 insertions(+), 21 deletions(-) diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index 04f9299825..604c797fe4 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -573,29 +573,43 @@ export default class MessageComposerInput extends React.Component { } // emojioneify any emoji - editorState.document.getTexts().forEach(node => { - if (node.text !== '' && HtmlUtils.containsEmoji(node.text)) { - let match; - while ((match = EMOJI_REGEX.exec(node.text)) !== null) { - const range = Range.create({ - anchor: { - key: node.key, - offset: match.index, - }, - focus: { - key: node.key, - offset: match.index + match[0].length, - }, - }); - const inline = Inline.create({ - type: 'emoji', - data: { emojiUnicode: match[0] }, - }); - change = change.insertInlineAtRange(range, inline); - editorState = change.value; + while (true) { + let foundEmoji = false; + + for (const node of editorState.document.getTexts()) { + if (node.text !== '' && HtmlUtils.containsEmoji(node.text)) { + let match; + EMOJI_REGEX.lastIndex = 0; + while ((match = EMOJI_REGEX.exec(node.text)) !== null) { + const range = Range.create({ + anchor: { + key: node.key, + offset: match.index, + }, + focus: { + key: node.key, + offset: match.index + match[0].length, + }, + }); + const inline = Inline.create({ + type: 'emoji', + data: { emojiUnicode: match[0] }, + }); + change = change.insertInlineAtRange(range, inline); + editorState = change.value; + + // if we replaced an emoji, start again looking for more + // emoji in the new editor state since doing the replacement + // will change the node structure & offsets so we can't compute + // insertion ranges from node.key / match.index anymore. + foundEmoji = true; + break; + } } } - }); + + if (!foundEmoji) break; + } // work around weird bug where inserting emoji via the macOS // emoji picker can leave the selection stuck in the emoji's From 79d467c551c1ebaf60abed2375f9b29be0563046 Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Wed, 24 Oct 2018 17:36:58 +0100 Subject: [PATCH 68/77] Add button to open devtools in roomsettings --- src/components/views/rooms/RoomSettings.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/components/views/rooms/RoomSettings.js b/src/components/views/rooms/RoomSettings.js index 46869c1773..23c2dbc93d 100644 --- a/src/components/views/rooms/RoomSettings.js +++ b/src/components/views/rooms/RoomSettings.js @@ -590,6 +590,11 @@ module.exports = React.createClass({ } }, + _openDevtools: function() { + const DevtoolsDialog = sdk.getComponent('dialogs.DevtoolsDialog'); + Modal.createDialog(DevtoolsDialog, {roomId: this.props.room.roomId}); + }, + _renderEncryptionSection: function() { const SettingsFlag = sdk.getComponent("elements.SettingsFlag"); @@ -942,6 +947,10 @@ module.exports = React.createClass({ ; } + devtoolsButton = + { _t("Open Devtools") } + ; + return (
@@ -1055,6 +1064,7 @@ module.exports = React.createClass({ { _t('Internal room ID: ') } { this.props.room.roomId }
{ _t('Room version number: ') } { this.props.room.getVersion() }
{ roomUpgradeButton } + { devtoolsButton }
); From 06c34cff9c2e7dddca4b69f2826dfbd3b218a3d7 Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Wed, 24 Oct 2018 17:37:13 +0100 Subject: [PATCH 69/77] Add devtools string --- src/i18n/strings/en_EN.json | 3 ++- src/i18n/strings/en_US.json | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 2885eb68a7..cbb688f448 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1268,5 +1268,6 @@ "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" + "Failed to add tag %(tagName)s to room": "Failed to add tag %(tagName)s to room", + "Open Devtools": "Open Devtools", } diff --git a/src/i18n/strings/en_US.json b/src/i18n/strings/en_US.json index d8733ab05a..9146fdf586 100644 --- a/src/i18n/strings/en_US.json +++ b/src/i18n/strings/en_US.json @@ -838,5 +838,6 @@ "Your homeserver's URL": "Your homeserver's URL", "Your identity server's URL": "Your identity server's URL", "e.g. %(exampleValue)s": "e.g. %(exampleValue)s", - "Every page you use in the app": "Every page you use in the app" + "Every page you use in the app": "Every page you use in the app", + "Open Devtools": "Open Devtools" } From 44a41b589d55a3cb8cbc7828353ddc75ad3f2a13 Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Wed, 24 Oct 2018 17:50:15 +0100 Subject: [PATCH 70/77] Comma on strings and styling button --- res/css/views/rooms/_RoomSettings.scss | 7 +++++++ src/components/views/rooms/RoomSettings.js | 2 +- src/i18n/strings/en_EN.json | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/res/css/views/rooms/_RoomSettings.scss b/res/css/views/rooms/_RoomSettings.scss index f04042ea77..b3858f3ba7 100644 --- a/res/css/views/rooms/_RoomSettings.scss +++ b/res/css/views/rooms/_RoomSettings.scss @@ -28,6 +28,13 @@ limitations under the License. margin-right: 8px; } +.mx_RoomSettings_devtoolsButton { + @mixin mx_DialogButton; + position: relative; + padding: 4px 1.5em; + margin-top: 8px; +} + .mx_RoomSettings_upgradeButton, .mx_RoomSettings_leaveButton:hover, .mx_RoomSettings_unbanButton:hover { diff --git a/src/components/views/rooms/RoomSettings.js b/src/components/views/rooms/RoomSettings.js index 23c2dbc93d..774d136e45 100644 --- a/src/components/views/rooms/RoomSettings.js +++ b/src/components/views/rooms/RoomSettings.js @@ -947,7 +947,7 @@ module.exports = React.createClass({ ; } - devtoolsButton = + const devtoolsButton = { _t("Open Devtools") } ; diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index cbb688f448..45fb0351a7 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1269,5 +1269,5 @@ "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", - "Open Devtools": "Open Devtools", + "Open Devtools": "Open Devtools" } From 3c045f3f65f4940889d1a646fafeb85f544173fb Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Wed, 24 Oct 2018 18:02:45 +0100 Subject: [PATCH 71/77] Revert i18n changes for en_US --- src/i18n/strings/en_US.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/i18n/strings/en_US.json b/src/i18n/strings/en_US.json index 9146fdf586..d8733ab05a 100644 --- a/src/i18n/strings/en_US.json +++ b/src/i18n/strings/en_US.json @@ -838,6 +838,5 @@ "Your homeserver's URL": "Your homeserver's URL", "Your identity server's URL": "Your identity server's URL", "e.g. %(exampleValue)s": "e.g. %(exampleValue)s", - "Every page you use in the app": "Every page you use in the app", - "Open Devtools": "Open Devtools" + "Every page you use in the app": "Every page you use in the app" } From a5ae599dcb819c0c919af61065d998c652934bb4 Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Wed, 24 Oct 2018 18:15:25 +0100 Subject: [PATCH 72/77] Add show developer tools option --- src/settings/Settings.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/settings/Settings.js b/src/settings/Settings.js index 021942c6f2..547c71bac8 100644 --- a/src/settings/Settings.js +++ b/src/settings/Settings.js @@ -290,4 +290,9 @@ export const SETTINGS = { displayName: _td('Show empty room list headings'), default: true, }, + "showDeveloperTools": { + supportedLevels: LEVELS_ACCOUNT_SETTINGS, + displayName: _td('Show developer tools'), + default: false, + }, }; From 8118a9c71a394665a1497e9408d9a2b6d54fb1d5 Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Wed, 24 Oct 2018 18:15:35 +0100 Subject: [PATCH 73/77] Wall devtools button behind a setting --- src/components/views/rooms/RoomSettings.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/views/rooms/RoomSettings.js b/src/components/views/rooms/RoomSettings.js index 774d136e45..b69938a117 100644 --- a/src/components/views/rooms/RoomSettings.js +++ b/src/components/views/rooms/RoomSettings.js @@ -947,9 +947,10 @@ module.exports = React.createClass({ ; } - const devtoolsButton = + const devtoolsButton = SettingsStore.getValue("showDeveloperTools") ? + ( { _t("Open Devtools") } - ; + ) : null; return (
From 27a0f0ca62ab93b2390556003406fdc9f98434e0 Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Wed, 24 Oct 2018 18:16:55 +0100 Subject: [PATCH 74/77] Add i18n string --- src/i18n/strings/en_EN.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 45fb0351a7..8e1f75f25c 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1269,5 +1269,6 @@ "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", - "Open Devtools": "Open Devtools" + "Open Devtools": "Open Devtools", + "Show developer tools": "Show developer tools" } From def0b2d8fb393bfa027b605f04b4ebc819763a92 Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Wed, 24 Oct 2018 18:20:16 +0100 Subject: [PATCH 75/77] Add developertools option to UserSettings --- src/components/structures/UserSettings.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index 129278907f..f32026511b 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -82,6 +82,7 @@ const SIMPLE_SETTINGS = [ { id: "TagPanel.disableTagPanel" }, { id: "enableWidgetScreenshots" }, { id: "RoomSubList.showEmpty" }, + { id: "showDeveloperTools" }, ]; // These settings must be defined in SettingsStore From 401f6333ed18e0981a0c3fff2936e303d9e1fef3 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 25 Oct 2018 14:54:32 +0100 Subject: [PATCH 76/77] Do...while loops are a thing --- src/components/views/rooms/MessageComposerInput.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index 604c797fe4..792dcede8a 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -573,7 +573,7 @@ export default class MessageComposerInput extends React.Component { } // emojioneify any emoji - while (true) { + do { let foundEmoji = false; for (const node of editorState.document.getTexts()) { @@ -607,9 +607,7 @@ export default class MessageComposerInput extends React.Component { } } } - - if (!foundEmoji) break; - } + } while (foundEmoji); // work around weird bug where inserting emoji via the macOS // emoji picker can leave the selection stuck in the emoji's From 5e81e5b8b84ff3954bb9b19cffeb80b679cabc44 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 25 Oct 2018 15:07:19 +0100 Subject: [PATCH 77/77] Fix variable scope --- src/components/views/rooms/MessageComposerInput.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index 792dcede8a..570cb8a59b 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -573,8 +573,9 @@ export default class MessageComposerInput extends React.Component { } // emojioneify any emoji + let foundEmoji; do { - let foundEmoji = false; + foundEmoji = false; for (const node of editorState.document.getTexts()) { if (node.text !== '' && HtmlUtils.containsEmoji(node.text)) {