diff --git a/CHANGELOG.md b/CHANGELOG.md index 07e478fa02..02c085d0b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,159 @@ +Changes in [2.3.0](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v2.3.0) (2020-03-30) +=================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v2.3.0-rc.1...v2.3.0) + + * Upgrade JS SDK to 5.2.0 + +Changes in [2.3.0-rc.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v2.3.0-rc.1) (2020-03-26) +============================================================================================================= +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v2.2.3...v2.3.0-rc.1) + + * Upgrade JS SDK to 5.2.0-rc.1 + * Add a flag to control whether cross-signing signatures are trusted + [\#4277](https://github.com/matrix-org/matrix-react-sdk/pull/4277) + * Update from Weblate + [\#4282](https://github.com/matrix-org/matrix-react-sdk/pull/4282) + * Update copy on SSSS symmetric upgrade toast + [\#4281](https://github.com/matrix-org/matrix-react-sdk/pull/4281) + * Wait for SSSS upgrade to complete + [\#4270](https://github.com/matrix-org/matrix-react-sdk/pull/4270) + * Update cross-signing verification copy and fix i18n + [\#4278](https://github.com/matrix-org/matrix-react-sdk/pull/4278) + * Fix soft-crash on bad permalinks + [\#4280](https://github.com/matrix-org/matrix-react-sdk/pull/4280) + * Fix: make self-verification wait for incoming request + [\#4267](https://github.com/matrix-org/matrix-react-sdk/pull/4267) + * Fall back to non-standard persisted api for Safari + [\#4272](https://github.com/matrix-org/matrix-react-sdk/pull/4272) + * Respond to backup key sharing requests + [\#4275](https://github.com/matrix-org/matrix-react-sdk/pull/4275) + * Log and display secret sharing cache state + [\#4268](https://github.com/matrix-org/matrix-react-sdk/pull/4268) + * Support sending config and ready events to capable widgets (Jitsi) + [\#4266](https://github.com/matrix-org/matrix-react-sdk/pull/4266) + * If cached keys are present in the key backup dialog, use them + [\#4273](https://github.com/matrix-org/matrix-react-sdk/pull/4273) + * Fix formatbar not hidden on highlighted message sent + [\#4265](https://github.com/matrix-org/matrix-react-sdk/pull/4265) + * Support Jitsi conferences sent/received on Riot Mobile and older Riot Webs + [\#4252](https://github.com/matrix-org/matrix-react-sdk/pull/4252) + * Use unified function to check cross-signing is ready + [\#4263](https://github.com/matrix-org/matrix-react-sdk/pull/4263) + * Migrate SSSS to symmetric + [\#4224](https://github.com/matrix-org/matrix-react-sdk/pull/4224) + * Migration to symmetric SSSS + [\#4242](https://github.com/matrix-org/matrix-react-sdk/pull/4242) + * Always display verification request toasts on top + [\#4262](https://github.com/matrix-org/matrix-react-sdk/pull/4262) + * Fix: assume SAS is supported when starting request with .start + [\#4249](https://github.com/matrix-org/matrix-react-sdk/pull/4249) + * Fix logout when Olm failed to load. + [\#4261](https://github.com/matrix-org/matrix-react-sdk/pull/4261) + * Improve naming of Jitsi conferences + [\#4251](https://github.com/matrix-org/matrix-react-sdk/pull/4251) + * Handle matrix.to user permalink in-room rather than solo + [\#4245](https://github.com/matrix-org/matrix-react-sdk/pull/4245) + * Fix: filter room list (again) by canonical and alternative aliases + [\#4260](https://github.com/matrix-org/matrix-react-sdk/pull/4260) + * EventIndex: Add some logging to the file panel populating. + [\#4250](https://github.com/matrix-org/matrix-react-sdk/pull/4250) + * Update from Weblate + [\#4259](https://github.com/matrix-org/matrix-react-sdk/pull/4259) + * Migrate RoomView to React Contexts in the hope for better temporal stability + [\#4258](https://github.com/matrix-org/matrix-react-sdk/pull/4258) + * Update WidgetUtils.js fix Jitsi path + [\#4256](https://github.com/matrix-org/matrix-react-sdk/pull/4256) + * Fix local jitsi build url fail and missing argument + [\#4255](https://github.com/matrix-org/matrix-react-sdk/pull/4255) + * Add shortcut CmdOrCtrl+. to toggle right panel + [\#4244](https://github.com/matrix-org/matrix-react-sdk/pull/4244) + * Improve Keyboard Shortcuts. Add alt-arrows & alt-shift-arrows + [\#4241](https://github.com/matrix-org/matrix-react-sdk/pull/4241) + * Bring back legacy verification by comparing public device keys + [\#4240](https://github.com/matrix-org/matrix-react-sdk/pull/4240) + * Searching: Return an empty result if the search term is an empty string. + [\#4248](https://github.com/matrix-org/matrix-react-sdk/pull/4248) + * Break continuation on showHiddenEvents-rendered events + [\#4247](https://github.com/matrix-org/matrix-react-sdk/pull/4247) + * Watch for show-RR settings changes, use room-specific and fix margins + [\#4246](https://github.com/matrix-org/matrix-react-sdk/pull/4246) + * Register Mac electron specific Cmd+, shortcut to User Settings + [\#4243](https://github.com/matrix-org/matrix-react-sdk/pull/4243) + * Use a local wrapper for Jitsi calls + [\#4234](https://github.com/matrix-org/matrix-react-sdk/pull/4234) + * Invite Dialog fixes + [\#4233](https://github.com/matrix-org/matrix-react-sdk/pull/4233) + * RoomPreviewBar word-break the sender name too + [\#4239](https://github.com/matrix-org/matrix-react-sdk/pull/4239) + * Report to the user when a key signature upload fails + [\#4229](https://github.com/matrix-org/matrix-react-sdk/pull/4229) + * pre-send megolm keys when possible when a user starts typing + [\#4235](https://github.com/matrix-org/matrix-react-sdk/pull/4235) + * we don't do mx_fadable anymore so get rid of broken RightPanel disabling + [\#4238](https://github.com/matrix-org/matrix-react-sdk/pull/4238) + * Fix left left panel overflowing vertically + [\#4237](https://github.com/matrix-org/matrix-react-sdk/pull/4237) + * Fix custom tags causing left panel to over-expand + [\#4236](https://github.com/matrix-org/matrix-react-sdk/pull/4236) + * Add Keyboard shortcuts dialog + [\#4231](https://github.com/matrix-org/matrix-react-sdk/pull/4231) + * Don't use buildkite agent to upload logs + [\#4232](https://github.com/matrix-org/matrix-react-sdk/pull/4232) + * Remove Gemini Scrollbars + [\#4217](https://github.com/matrix-org/matrix-react-sdk/pull/4217) + * Room Directory Explore Servers redesign + [\#4209](https://github.com/matrix-org/matrix-react-sdk/pull/4209) + * Fix redo keyboard shortcut on macOS + [\#4110](https://github.com/matrix-org/matrix-react-sdk/pull/4110) + * Fix: ensure local state for aliases doesn't get garbled up + [\#4230](https://github.com/matrix-org/matrix-react-sdk/pull/4230) + * Rename 'jump to bottom' to avoid ublock block + [\#4208](https://github.com/matrix-org/matrix-react-sdk/pull/4208) + * Restore key backup in background after complete security + [\#4225](https://github.com/matrix-org/matrix-react-sdk/pull/4225) + * Fix key backup trust text for cross-signing + [\#4223](https://github.com/matrix-org/matrix-react-sdk/pull/4223) + * Add default on config setting to control call button in composer + [\#4227](https://github.com/matrix-org/matrix-react-sdk/pull/4227) + * Fix: make alternative addresses UX less confusing + [\#4221](https://github.com/matrix-org/matrix-react-sdk/pull/4221) + * Wait for verification request on login + [\#4222](https://github.com/matrix-org/matrix-react-sdk/pull/4222) + * EventIndex: Add support to delete events from the index. + [\#4204](https://github.com/matrix-org/matrix-react-sdk/pull/4204) + * EventIndex: Remove a checkpoint if the HTTP request returns a 403. + [\#4214](https://github.com/matrix-org/matrix-react-sdk/pull/4214) + * Move to composer when typing letters with Shift held + [\#4216](https://github.com/matrix-org/matrix-react-sdk/pull/4216) + * Wrap large room names when previewing them + [\#4213](https://github.com/matrix-org/matrix-react-sdk/pull/4213) + * Rename Review Devices to Review Sessions + [\#4219](https://github.com/matrix-org/matrix-react-sdk/pull/4219) + * Fix typo in tabIndex to make React happy + [\#4215](https://github.com/matrix-org/matrix-react-sdk/pull/4215) + * Proof of concept for custom theme adding + [\#4148](https://github.com/matrix-org/matrix-react-sdk/pull/4148) + * Remove stuff that yarn install doesn't think we need + [\#4205](https://github.com/matrix-org/matrix-react-sdk/pull/4205) + * Declare jsx in tsconfig for IDEs + [\#4207](https://github.com/matrix-org/matrix-react-sdk/pull/4207) + * Fix: best-effort to join room without canonical alias over federation from + room directory + [\#4210](https://github.com/matrix-org/matrix-react-sdk/pull/4210) + * Test for cross-signing homeserver support during login, toasts + [\#4206](https://github.com/matrix-org/matrix-react-sdk/pull/4206) + * Send verification request to a single device in a way compatible with non- + cross-signing + [\#4202](https://github.com/matrix-org/matrix-react-sdk/pull/4202) + * Fixes for removing local alias + [\#4199](https://github.com/matrix-org/matrix-react-sdk/pull/4199) + * yarn upgrade + [\#4201](https://github.com/matrix-org/matrix-react-sdk/pull/4201) + * Support TypeScript for React components + [\#4203](https://github.com/matrix-org/matrix-react-sdk/pull/4203) + * When room name is changed, show both the old and new name + [\#4183](https://github.com/matrix-org/matrix-react-sdk/pull/4183) + Changes in [2.2.3](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v2.2.3) (2020-03-17) =================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v2.2.3-rc.1...v2.2.3) diff --git a/package.json b/package.json index 1ff0fb6f55..7001b1cb21 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "2.2.3", + "version": "2.3.0", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { diff --git a/res/css/structures/_AutoHideScrollbar.scss b/res/css/structures/_AutoHideScrollbar.scss index 3d91293c98..50842c71bc 100644 --- a/res/css/structures/_AutoHideScrollbar.scss +++ b/res/css/structures/_AutoHideScrollbar.scss @@ -14,28 +14,31 @@ See the License for the specific language governing permissions and limitations under the License. */ -.mx_AutoHideScrollbar { - overflow-x: hidden; - overflow-y: auto; - overflow-y: overlay; // where supported - -ms-overflow-style: -ms-autohiding-scrollbar; - - &::-webkit-scrollbar { - width: 6px; - height: 6px; - background-color: transparent; - } - - &::-webkit-scrollbar-thumb { - border-radius: 3px; - background-color: transparent; - } - - scrollbar-color: transparent transparent; +// make any scrollbar grey and thin +html { + scrollbar-color: $scrollbar-thumb-color $scrollbar-track-color; +} +// scrollbar-width is not inherited (but -color is, why?!), +// so declare it on every element +* { scrollbar-width: thin; } +::-webkit-scrollbar { + width: 6px; + height: 6px; + background-color: $scrollbar-track-color; +} + +::-webkit-scrollbar-thumb { + border-radius: 3px; + background-color: $scrollbar-thumb-color; +} + +// make auto-hide scrollbars not transparent again on hover .mx_AutoHideScrollbar:hover { + scrollbar-color: $scrollbar-thumb-color $scrollbar-track-color; + &::-webkit-scrollbar { background-color: $scrollbar-track-color; } @@ -43,5 +46,22 @@ limitations under the License. &::-webkit-scrollbar-thumb { background-color: $scrollbar-thumb-color; } - scrollbar-color: $scrollbar-thumb-color $scrollbar-track-color; +} + +// make scrollbars transparent for autohide scrollbars +.mx_AutoHideScrollbar { + overflow-x: hidden; + overflow-y: auto; + overflow-y: overlay; // where supported + -ms-overflow-style: -ms-autohiding-scrollbar; + + &::-webkit-scrollbar { + background-color: transparent; + } + + &::-webkit-scrollbar-thumb { + background-color: transparent; + } + + scrollbar-color: transparent transparent; } diff --git a/src/CrossSigningManager.js b/src/CrossSigningManager.js index 29eb3cb8be..da7c0673d2 100644 --- a/src/CrossSigningManager.js +++ b/src/CrossSigningManager.js @@ -216,19 +216,19 @@ export async function promptForBackupPassphrase() { * * @param {Function} [func] An operation to perform once secret storage has been * bootstrapped. Optional. - * @param {bool} [force] Reset secret storage even if it's already set up + * @param {bool} [forceReset] Reset secret storage even if it's already set up */ -export async function accessSecretStorage(func = async () => { }, force = false) { +export async function accessSecretStorage(func = async () => { }, forceReset = false) { const cli = MatrixClientPeg.get(); secretStorageBeingAccessed = true; try { - if (!await cli.hasSecretStorageKey() || force) { + if (!await cli.hasSecretStorageKey() || forceReset) { // This dialog calls bootstrap itself after guiding the user through // passphrase creation. const { finished } = Modal.createTrackedDialogAsync('Create Secret Storage dialog', '', import("./async-components/views/dialogs/secretstorage/CreateSecretStorageDialog"), { - force, + force: forceReset, }, null, /* priority = */ false, /* static = */ true, ); diff --git a/src/DeviceListener.js b/src/DeviceListener.js index 9161a462eb..f8555c7602 100644 --- a/src/DeviceListener.js +++ b/src/DeviceListener.js @@ -119,89 +119,85 @@ export default class DeviceListener { const crossSigningReady = await cli.isCrossSigningReady(); - if (!crossSigningReady) { - if (this._dismissedThisDeviceToast) { - ToastStore.sharedInstance().dismissToast(THIS_DEVICE_TOAST_KEY); - return; - } - - // cross signing isn't enabled - nag to enable it - // There are 3 different toasts for: - if (cli.getStoredCrossSigningForUser(cli.getUserId())) { - // Cross-signing on account but this device doesn't trust the master key (verify this session) - ToastStore.sharedInstance().addOrReplaceToast({ - key: THIS_DEVICE_TOAST_KEY, - title: _t("Verify this session"), - icon: "verification_warning", - props: {kind: 'verify_this_session'}, - component: sdk.getComponent("toasts.SetupEncryptionToast"), - }); - } else { - const backupInfo = await this._getKeyBackupInfo(); - if (backupInfo) { - // No cross-signing on account but key backup available (upgrade encryption) + if (this._dismissedThisDeviceToast) { + ToastStore.sharedInstance().dismissToast(THIS_DEVICE_TOAST_KEY); + } else { + if (!crossSigningReady) { + // cross signing isn't enabled - nag to enable it + // There are 3 different toasts for: + if (cli.getStoredCrossSigningForUser(cli.getUserId())) { + // Cross-signing on account but this device doesn't trust the master key (verify this session) ToastStore.sharedInstance().addOrReplaceToast({ key: THIS_DEVICE_TOAST_KEY, - title: _t("Encryption upgrade available"), + title: _t("Verify this session"), icon: "verification_warning", - props: {kind: 'upgrade_encryption'}, + props: {kind: 'verify_this_session'}, component: sdk.getComponent("toasts.SetupEncryptionToast"), }); } else { - // No cross-signing or key backup on account (set up encryption) + const backupInfo = await this._getKeyBackupInfo(); + if (backupInfo) { + // No cross-signing on account but key backup available (upgrade encryption) + ToastStore.sharedInstance().addOrReplaceToast({ + key: THIS_DEVICE_TOAST_KEY, + title: _t("Encryption upgrade available"), + icon: "verification_warning", + props: {kind: 'upgrade_encryption'}, + component: sdk.getComponent("toasts.SetupEncryptionToast"), + }); + } else { + // No cross-signing or key backup on account (set up encryption) + ToastStore.sharedInstance().addOrReplaceToast({ + key: THIS_DEVICE_TOAST_KEY, + title: _t("Set up encryption"), + icon: "verification_warning", + props: {kind: 'set_up_encryption'}, + component: sdk.getComponent("toasts.SetupEncryptionToast"), + }); + } + } + return; + } else if (await cli.secretStorageKeyNeedsUpgrade()) { + ToastStore.sharedInstance().addOrReplaceToast({ + key: THIS_DEVICE_TOAST_KEY, + title: _t("Encryption upgrade available"), + icon: "verification_warning", + props: {kind: 'upgrade_ssss'}, + component: sdk.getComponent("toasts.SetupEncryptionToast"), + }); + } + } + + // as long as cross-signing isn't ready, + // you can't see or dismiss any device toasts + if (crossSigningReady) { + const newActiveToasts = new Set(); + + const devices = await cli.getStoredDevicesForUser(cli.getUserId()); + for (const device of devices) { + if (device.deviceId == cli.deviceId) continue; + + const deviceTrust = await cli.checkDeviceTrust(cli.getUserId(), device.deviceId); + if (deviceTrust.isCrossSigningVerified() || this._dismissed.has(device.deviceId)) { + ToastStore.sharedInstance().dismissToast(toastKey(device.deviceId)); + } else { + this._activeNagToasts.add(device.deviceId); ToastStore.sharedInstance().addOrReplaceToast({ - key: THIS_DEVICE_TOAST_KEY, - title: _t("Set up encryption"), + key: toastKey(device.deviceId), + title: _t("Unverified login. Was this you?"), icon: "verification_warning", - props: {kind: 'set_up_encryption'}, - component: sdk.getComponent("toasts.SetupEncryptionToast"), + props: { device }, + component: sdk.getComponent("toasts.UnverifiedSessionToast"), }); + newActiveToasts.add(device.deviceId); } } - return; - } else if (await cli.secretStorageKeyNeedsUpgrade()) { - if (this._dismissedThisDeviceToast) { - ToastStore.sharedInstance().dismissToast(THIS_DEVICE_TOAST_KEY); - return; + + // clear any other outstanding toasts (eg. logged out devices) + for (const deviceId of this._activeNagToasts) { + if (!newActiveToasts.has(deviceId)) ToastStore.sharedInstance().dismissToast(toastKey(deviceId)); } - - ToastStore.sharedInstance().addOrReplaceToast({ - key: THIS_DEVICE_TOAST_KEY, - title: _t("Encryption upgrade available"), - icon: "verification_warning", - props: {kind: 'upgrade_ssss'}, - component: sdk.getComponent("toasts.SetupEncryptionToast"), - }); - } else { - ToastStore.sharedInstance().dismissToast(THIS_DEVICE_TOAST_KEY); + this._activeNagToasts = newActiveToasts; } - - const newActiveToasts = new Set(); - - const devices = await cli.getStoredDevicesForUser(cli.getUserId()); - for (const device of devices) { - if (device.deviceId == cli.deviceId) continue; - - const deviceTrust = await cli.checkDeviceTrust(cli.getUserId(), device.deviceId); - if (deviceTrust.isCrossSigningVerified() || this._dismissed.has(device.deviceId)) { - ToastStore.sharedInstance().dismissToast(toastKey(device.deviceId)); - } else { - this._activeNagToasts.add(device.deviceId); - ToastStore.sharedInstance().addOrReplaceToast({ - key: toastKey(device.deviceId), - title: _t("Unverified login. Was this you?"), - icon: "verification_warning", - props: { device }, - component: sdk.getComponent("toasts.UnverifiedSessionToast"), - }); - newActiveToasts.add(device.deviceId); - } - } - - // clear any other outstanding toasts (eg. logged out devices) - for (const deviceId of this._activeNagToasts) { - if (!newActiveToasts.has(deviceId)) ToastStore.sharedInstance().dismissToast(toastKey(deviceId)); - } - this._activeNagToasts = newActiveToasts; } } diff --git a/src/accessibility/KeyboardShortcuts.tsx b/src/accessibility/KeyboardShortcuts.tsx index c2739beefa..bcbf3d6810 100644 --- a/src/accessibility/KeyboardShortcuts.tsx +++ b/src/accessibility/KeyboardShortcuts.tsx @@ -118,6 +118,11 @@ const shortcuts: Record = { key: Key.ARROW_DOWN, }], description: _td("Navigate composer history"), + }, { + keybinds: [{ + key: Key.ESCAPE, + }], + description: _td("Cancel replying to a message"), }, ], diff --git a/src/async-components/views/dialogs/eventindex/ManageEventIndexDialog.js b/src/async-components/views/dialogs/eventindex/ManageEventIndexDialog.js index 371fdcaf64..3d7249b5a1 100644 --- a/src/async-components/views/dialogs/eventindex/ManageEventIndexDialog.js +++ b/src/async-components/views/dialogs/eventindex/ManageEventIndexDialog.js @@ -168,7 +168,6 @@ export default class ManageEventIndexDialog extends React.Component { totalRooms: formatCountLong(this.state.roomCount), })}
{_t("Enter your account password to confirm the upgrade:")}
{ private _renderTabPanel(tab: Tab): React.ReactNode { return (
-
+ {tab.body} -
+
); } diff --git a/src/components/structures/auth/ForgotPassword.js b/src/components/structures/auth/ForgotPassword.js index e921951512..c849edf260 100644 --- a/src/components/structures/auth/ForgotPassword.js +++ b/src/components/structures/auth/ForgotPassword.js @@ -296,7 +296,6 @@ export default createReactClass({
{introText}

{error} { _t("Confirm your identity by entering your account password below.") }

- this[FIELD_EMAIL] = field} type="text" label={emailPlaceholder} @@ -524,7 +523,6 @@ export default createReactClass({ onOptionChange={this.onPhoneCountryChange} />; return this[FIELD_PHONE_NUMBER] = field} type="text" label={phoneLabel} diff --git a/src/components/views/auth/ServerConfig.js b/src/components/views/auth/ServerConfig.js index a9e26b8fb7..37517c7484 100644 --- a/src/components/views/auth/ServerConfig.js +++ b/src/components/views/auth/ServerConfig.js @@ -223,7 +223,8 @@ export default class ServerConfig extends React.PureComponent { {sub} , })} - , })} -

- this._aliasFieldRef = ref} onChange={this.onAliasChange} domain={domain} value={this.state.alias} /> + this._aliasFieldRef = ref} onChange={this.onAliasChange} domain={domain} value={this.state.alias} />
); } else { @@ -188,8 +188,8 @@ export default createReactClass({ >
- this._nameFieldRef = ref} label={ _t('Name') } onChange={this.onNameChange} onValidate={this.onNameValidate} value={this.state.name} className="mx_CreateRoomDialog_name" /> - + this._nameFieldRef = ref} label={ _t('Name') } onChange={this.onNameChange} onValidate={this.onNameValidate} value={this.state.name} className="mx_CreateRoomDialog_name" /> + { privateLabel } { publicLabel } diff --git a/src/components/views/dialogs/DeactivateAccountDialog.js b/src/components/views/dialogs/DeactivateAccountDialog.js index d7468933df..4c14f356e4 100644 --- a/src/components/views/dialogs/DeactivateAccountDialog.js +++ b/src/components/views/dialogs/DeactivateAccountDialog.js @@ -174,7 +174,6 @@ export default class DeactivateAccountDialog extends React.Component {

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

- {adminMessage}
- diff --git a/src/components/views/elements/Field.js b/src/components/views/elements/Field.js index 8583c91a01..797c83bc06 100644 --- a/src/components/views/elements/Field.js +++ b/src/components/views/elements/Field.js @@ -23,9 +23,15 @@ import { debounce } from 'lodash'; // Invoke validation from user input (when typing, etc.) at most once every N ms. const VALIDATION_THROTTLE_MS = 200; +const BASE_ID = "mx_Field"; +let count = 1; +function getId() { + return `${BASE_ID}_${count++}`; +} + export default class Field extends React.PureComponent { static propTypes = { - // The field's ID, which binds the input and label together. + // The field's ID, which binds the input and label together. Immutable. id: PropTypes.string.isRequired, // The element to create. Defaults to "input". // To define options for a select, use @@ -63,13 +69,15 @@ export default class Field extends React.PureComponent { // All other props pass through to the . }; - constructor() { - super(); + constructor(props) { + super(props); this.state = { valid: undefined, feedback: undefined, focused: false, }; + + this.id = this.props.id || getId(); } onFocus = (ev) => { @@ -167,6 +175,7 @@ export default class Field extends React.PureComponent { inputProps.type = inputProps.type || "text"; inputProps.ref = input => this.input = input; inputProps.placeholder = inputProps.placeholder || inputProps.label; + inputProps.id = this.id; // this overwrites the id from props inputProps.onFocus = this.onFocus; inputProps.onChange = this.onChange; @@ -211,7 +220,7 @@ export default class Field extends React.PureComponent { return
{prefixContainer} {fieldInput} - + {postfixContainer} {fieldTooltip}
; diff --git a/src/components/views/elements/PowerSelector.js b/src/components/views/elements/PowerSelector.js index 2f4c08922a..eff14979a9 100644 --- a/src/components/views/elements/PowerSelector.js +++ b/src/components/views/elements/PowerSelector.js @@ -132,7 +132,7 @@ export default createReactClass({ const label = typeof this.props.label === "undefined" ? _t("Power level") : this.props.label; if (this.state.custom) { picker = ( - @@ -151,7 +151,7 @@ export default createReactClass({ }); picker = ( - {options} diff --git a/src/components/views/elements/RoomAliasField.js b/src/components/views/elements/RoomAliasField.js index b38047cd3b..d3de6a5d34 100644 --- a/src/components/views/elements/RoomAliasField.js +++ b/src/components/views/elements/RoomAliasField.js @@ -23,7 +23,6 @@ import {MatrixClientPeg} from '../../../MatrixClientPeg'; // Controlled form component wrapping Field for inputting a room alias scoped to a given domain export default class RoomAliasField extends React.PureComponent { static propTypes = { - id: PropTypes.string.isRequired, domain: PropTypes.string.isRequired, onChange: PropTypes.func, value: PropTypes.string.isRequired, @@ -50,7 +49,6 @@ export default class RoomAliasField extends React.PureComponent { className="mx_RoomAliasField" prefix={poundSign} postfix={domain} - id={this.props.id} ref={ref => this._fieldRef = ref} onValidate={this._onValidate} placeholder={_t("e.g. my-room")} diff --git a/src/components/views/emojipicker/EmojiPicker.js b/src/components/views/emojipicker/EmojiPicker.js index ca8f0c0565..cacc15a5f9 100644 --- a/src/components/views/emojipicker/EmojiPicker.js +++ b/src/components/views/emojipicker/EmojiPicker.js @@ -22,6 +22,7 @@ import { _t } from '../../../languageHandler'; import * as recent from '../../../emojipicker/recent'; import {DATA_BY_CATEGORY, getEmojiFromUnicode} from "../../../emoji"; +import AutoHideScrollbar from "../../structures/AutoHideScrollbar"; export const CATEGORY_HEADER_HEIGHT = 22; export const EMOJI_HEIGHT = 37; @@ -214,7 +215,7 @@ class EmojiPicker extends React.Component {
-
+ this.bodyRef.current = e} onScroll={this.onScroll}> {this.categories.map(category => { const emojis = this.memoizedDataByCategory[category.id]; const categoryElement = ( + {this.state.previewEmoji || !this.props.showQuickReactions ? : } diff --git a/src/components/views/room_settings/AliasSettings.js b/src/components/views/room_settings/AliasSettings.js index 857a80c34a..3994d78390 100644 --- a/src/components/views/room_settings/AliasSettings.js +++ b/src/components/views/room_settings/AliasSettings.js @@ -62,7 +62,6 @@ class EditableAliasesList extends EditableItemList { className="mx_EditableItemList_newItem" >
- + { stateViews } { appsDrawer } { fileDropTarget } { callView } { conferenceCallNotification } { this.props.children } -
+ ); }, }); diff --git a/src/components/views/rooms/RoomTile.js b/src/components/views/rooms/RoomTile.js index 478d6703b4..0c913b32da 100644 --- a/src/components/views/rooms/RoomTile.js +++ b/src/components/views/rooms/RoomTile.js @@ -37,7 +37,7 @@ import E2EIcon from './E2EIcon'; import InviteOnlyIcon from './InviteOnlyIcon'; // eslint-disable-next-line camelcase import rate_limited_func from '../../../ratelimitedfunc'; -import { shieldStatusForMembership } from '../../../utils/ShieldUtils'; +import { shieldStatusForRoom } from '../../../utils/ShieldUtils'; export default createReactClass({ displayName: 'RoomTile', @@ -157,7 +157,7 @@ export default createReactClass({ /* At this point, the user has encryption on and cross-signing on */ this.setState({ - e2eStatus: await shieldStatusForMembership(cli, this.props.room), + e2eStatus: await shieldStatusForRoom(cli, this.props.room), }); }, diff --git a/src/components/views/rooms/SendMessageComposer.js b/src/components/views/rooms/SendMessageComposer.js index 90c37780fe..d87d99dc46 100644 --- a/src/components/views/rooms/SendMessageComposer.js +++ b/src/components/views/rooms/SendMessageComposer.js @@ -131,8 +131,13 @@ export default class SendMessageComposer extends React.Component { this.onVerticalArrow(event, false); } else if (this._prepareToEncrypt) { this._prepareToEncrypt(); + } else if (event.key === Key.ESCAPE) { + dis.dispatch({ + action: 'reply_to_event', + event: null, + }); } - } + }; onVerticalArrow(e, up) { // arrows from an initial-caret composer navigates recent messages to edit diff --git a/src/components/views/settings/ChangePassword.js b/src/components/views/settings/ChangePassword.js index b51ff6cf9d..6607458b40 100644 --- a/src/components/views/settings/ChangePassword.js +++ b/src/components/views/settings/ChangePassword.js @@ -235,7 +235,7 @@ export default createReactClass({ if (!this.state.cachedPassword) { currentPassword = (
-
{ + _bootstrapSecureSecretStorage = async (forceReset=false) => { this.setState({ error: null }); try { - await accessSecretStorage(() => undefined, force); + await accessSecretStorage(() => undefined, forceReset); } catch (e) { this.setState({ error: e }); console.error("Error bootstrapping secret storage", e); diff --git a/src/components/views/settings/ProfileSettings.js b/src/components/views/settings/ProfileSettings.js index 72dfe7a983..23ab60423a 100644 --- a/src/components/views/settings/ProfileSettings.js +++ b/src/components/views/settings/ProfileSettings.js @@ -153,7 +153,7 @@ export default class ProfileSettings extends React.Component { {this.state.userId} {hostingSignup}

-
diff --git a/src/components/views/settings/SetIdServer.js b/src/components/views/settings/SetIdServer.js index 995959dc90..cb37271452 100644 --- a/src/components/views/settings/SetIdServer.js +++ b/src/components/views/settings/SetIdServer.js @@ -403,8 +403,8 @@ export default class SetIdServer extends React.Component { {bodyText} - - -
- - {_t("Theme")} {systemThemeSection} - diff --git a/src/components/views/settings/tabs/user/MjolnirUserSettingsTab.js b/src/components/views/settings/tabs/user/MjolnirUserSettingsTab.js index 7f3a2c401d..d22b7ec183 100644 --- a/src/components/views/settings/tabs/user/MjolnirUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/MjolnirUserSettingsTab.js @@ -272,7 +272,6 @@ export default class MjolnirUserSettingsTab extends React.Component {
0) { const defaultDevice = getDefaultDevice(audioOutputs); speakerDropdown = ( - {this._renderDeviceOptions(audioOutputs, 'audioOutput')} @@ -175,7 +175,7 @@ export default class VoiceUserSettingsTab extends React.Component { if (audioInputs.length > 0) { const defaultDevice = getDefaultDevice(audioInputs); microphoneDropdown = ( - {this._renderDeviceOptions(audioInputs, 'audioInput')} @@ -187,7 +187,7 @@ export default class VoiceUserSettingsTab extends React.Component { if (videoInputs.length > 0) { const defaultDevice = getDefaultDevice(videoInputs); webcamDropdown = ( - {this._renderDeviceOptions(videoInputs, 'videoInput')} diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index a6e195aa16..2f19fc982c 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -2216,6 +2216,7 @@ "Navigate recent messages to edit": "Navigate recent messages to edit", "Jump to start/end of the composer": "Jump to start/end of the composer", "Navigate composer history": "Navigate composer history", + "Cancel replying to a message": "Cancel replying to a message", "Toggle microphone mute": "Toggle microphone mute", "Toggle video on/off": "Toggle video on/off", "Jump to room search": "Jump to room search", diff --git a/src/utils/ShieldUtils.ts b/src/utils/ShieldUtils.ts index f427b0b0b6..9bf6fe2327 100644 --- a/src/utils/ShieldUtils.ts +++ b/src/utils/ShieldUtils.ts @@ -18,7 +18,7 @@ interface Room { roomId: string; } -export async function shieldStatusForMembership(client: Client, room: Room): Promise { +export async function shieldStatusForRoom(client: Client, room: Room): Promise { const members = (await room.getEncryptionTargetMembers()).map(({userId}) => userId); const inDMMap = !!DMRoomMap.shared().getUserIdForRoomId(room.roomId); @@ -41,8 +41,8 @@ export async function shieldStatusForMembership(client: Client, room: Room): Pro /* Don't alarm if no other users are verified */ const includeUser = (verified.length > 0) && // Don't alarm for self in rooms where nobody else is verified !inDMMap && // Don't alarm for self in DMs with other users - (members.length !== 2) || // Don't alarm for self in 1:1 chats with other users - (members.length === 1); // Do alarm for self if we're alone in a room + (members.length !== 2) || // Don't alarm for self in 1:1 chats with other users + (members.length === 1); // Do alarm for self if we're alone in a room const targets = includeUser ? [...verified, client.getUserId()] : verified; for (const userId of targets) { const devices = await client.getStoredDevicesForUser(userId); diff --git a/test/utils/ShieldUtils-test.js b/test/utils/ShieldUtils-test.js index 973798fa4b..949f0ed42b 100644 --- a/test/utils/ShieldUtils-test.js +++ b/test/utils/ShieldUtils-test.js @@ -1,4 +1,4 @@ -import { shieldStatusForMembership } from '../../src/utils/ShieldUtils'; +import { shieldStatusForRoom } from '../../src/utils/ShieldUtils'; import DMRoomMap from '../../src/utils/DMRoomMap'; function mkClient(selfTrust) { @@ -55,7 +55,7 @@ describe("shieldStatusForMembership self-trust behaviour", function() { roomId: dm ? "DM" : "other", getEncryptionTargetMembers: () => ["@self:localhost", "@FF1:h", "@FF2:h"].map((userId) => ({userId})), }; - const status = await shieldStatusForMembership(client, room); + const status = await shieldStatusForRoom(client, room); expect(status).toEqual("normal"); }); @@ -68,7 +68,7 @@ describe("shieldStatusForMembership self-trust behaviour", function() { roomId: dm ? "DM" : "other", getEncryptionTargetMembers: () => ["@self:localhost", "@TT1:h", "@TT2:h"].map((userId) => ({userId})), }; - const status = await shieldStatusForMembership(client, room); + const status = await shieldStatusForRoom(client, room); expect(status).toEqual(result); }); @@ -81,7 +81,7 @@ describe("shieldStatusForMembership self-trust behaviour", function() { roomId: dm ? "DM" : "other", getEncryptionTargetMembers: () => ["@self:localhost", "@TT1:h", "@FF2:h"].map((userId) => ({userId})), }; - const status = await shieldStatusForMembership(client, room); + const status = await shieldStatusForRoom(client, room); expect(status).toEqual(result); }); @@ -94,7 +94,7 @@ describe("shieldStatusForMembership self-trust behaviour", function() { roomId: dm ? "DM" : "other", getEncryptionTargetMembers: () => ["@self:localhost"].map((userId) => ({userId})), }; - const status = await shieldStatusForMembership(client, room); + const status = await shieldStatusForRoom(client, room); expect(status).toEqual(result); }); @@ -107,7 +107,7 @@ describe("shieldStatusForMembership self-trust behaviour", function() { roomId: dm ? "DM" : "other", getEncryptionTargetMembers: () => ["@self:localhost", "@TT:h"].map((userId) => ({userId})), }; - const status = await shieldStatusForMembership(client, room); + const status = await shieldStatusForRoom(client, room); expect(status).toEqual(result); }); @@ -120,7 +120,7 @@ describe("shieldStatusForMembership self-trust behaviour", function() { roomId: dm ? "DM" : "other", getEncryptionTargetMembers: () => ["@self:localhost", "@FF:h"].map((userId) => ({userId})), }; - const status = await shieldStatusForMembership(client, room); + const status = await shieldStatusForRoom(client, room); expect(status).toEqual(result); }); }); @@ -140,7 +140,7 @@ describe("shieldStatusForMembership other-trust behaviour", function() { roomId: dm ? "DM" : "other", getEncryptionTargetMembers: () => ["@self:localhost", "@TF:h"].map((userId) => ({userId})), }; - const status = await shieldStatusForMembership(client, room); + const status = await shieldStatusForRoom(client, room); expect(status).toEqual(result); }); @@ -152,7 +152,7 @@ describe("shieldStatusForMembership other-trust behaviour", function() { roomId: dm ? "DM" : "other", getEncryptionTargetMembers: () => ["@self:localhost", "@TF:h", "@TT: h"].map((userId) => ({userId})), }; - const status = await shieldStatusForMembership(client, room); + const status = await shieldStatusForRoom(client, room); expect(status).toEqual(result); }); @@ -164,7 +164,7 @@ describe("shieldStatusForMembership other-trust behaviour", function() { roomId: dm ? "DM" : "other", getEncryptionTargetMembers: () => ["@self:localhost", "@FF:h", "@FT: h"].map((userId) => ({userId})), }; - const status = await shieldStatusForMembership(client, room); + const status = await shieldStatusForRoom(client, room); expect(status).toEqual(result); }); }); diff --git a/yarn.lock b/yarn.lock index 582d89137e..c5fc8268a1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5690,8 +5690,8 @@ mathml-tag-names@^2.0.1: integrity sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg== "matrix-js-sdk@github:matrix-org/matrix-js-sdk#develop": - version "5.1.1" - resolved "https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/b2e154377a4268441a3b27b183dd7f7018187035" + version "5.2.0" + resolved "https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/223d37ffce674a23ca73702f04b9ba31cfd84196" dependencies: "@babel/runtime" "^7.8.3" another-json "^0.2.0"