diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5aac4e2974..151888a17e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,86 @@
+Changes in [3.10.0](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v3.10.0) (2020-12-07)
+=====================================================================================================
+[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v3.10.0-rc.1...v3.10.0)
+
+ * Upgrade to JS SDK 9.3.0
+
+Changes in [3.10.0-rc.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v3.10.0-rc.1) (2020-12-02)
+===============================================================================================================
+[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v3.9.0...v3.10.0-rc.1)
+
+ * Upgrade to JS SDK 9.3.0-rc.1
+ * Translations update from Weblate
+ [\#5461](https://github.com/matrix-org/matrix-react-sdk/pull/5461)
+ * Fix VoIP call plinth on dark theme
+ [\#5460](https://github.com/matrix-org/matrix-react-sdk/pull/5460)
+ * Add sanity checking around widget pinning
+ [\#5459](https://github.com/matrix-org/matrix-react-sdk/pull/5459)
+ * Update i18n for Appearance User Settings
+ [\#5457](https://github.com/matrix-org/matrix-react-sdk/pull/5457)
+ * Only show 'answered elsewhere' if we tried to answer too
+ [\#5455](https://github.com/matrix-org/matrix-react-sdk/pull/5455)
+ * Fixed Avatar for 3PID invites
+ [\#5442](https://github.com/matrix-org/matrix-react-sdk/pull/5442)
+ * Slightly better error if we can't capture user media
+ [\#5449](https://github.com/matrix-org/matrix-react-sdk/pull/5449)
+ * Make it possible in-code to hide rooms from the room list
+ [\#5445](https://github.com/matrix-org/matrix-react-sdk/pull/5445)
+ * Fix the stickerpicker
+ [\#5447](https://github.com/matrix-org/matrix-react-sdk/pull/5447)
+ * Add live password validation to change password dialog
+ [\#5436](https://github.com/matrix-org/matrix-react-sdk/pull/5436)
+ * LaTeX rendering in element-web using KaTeX
+ [\#5244](https://github.com/matrix-org/matrix-react-sdk/pull/5244)
+ * Add lifecycle customisation point after logout
+ [\#5448](https://github.com/matrix-org/matrix-react-sdk/pull/5448)
+ * Simplify UserMenu for Guests as they can't use most of the options
+ [\#5421](https://github.com/matrix-org/matrix-react-sdk/pull/5421)
+ * Fix known issues with modal widgets
+ [\#5444](https://github.com/matrix-org/matrix-react-sdk/pull/5444)
+ * Fix existing widgets not having approved capabilities for their function
+ [\#5443](https://github.com/matrix-org/matrix-react-sdk/pull/5443)
+ * Use the WidgetDriver to run OIDC requests
+ [\#5440](https://github.com/matrix-org/matrix-react-sdk/pull/5440)
+ * Add a customisation point for widget permissions and fix amnesia issues
+ [\#5439](https://github.com/matrix-org/matrix-react-sdk/pull/5439)
+ * Fix Widget event notification text including spurious space
+ [\#5441](https://github.com/matrix-org/matrix-react-sdk/pull/5441)
+ * Move call listener out of MatrixChat
+ [\#5438](https://github.com/matrix-org/matrix-react-sdk/pull/5438)
+ * New Look in-Call View
+ [\#5432](https://github.com/matrix-org/matrix-react-sdk/pull/5432)
+ * Support arbitrary widgets sticking to the screen + sending stickers
+ [\#5435](https://github.com/matrix-org/matrix-react-sdk/pull/5435)
+ * Auth typescripting and validation tweaks
+ [\#5433](https://github.com/matrix-org/matrix-react-sdk/pull/5433)
+ * Add new widget API actions for changing rooms and sending/receiving events
+ [\#5385](https://github.com/matrix-org/matrix-react-sdk/pull/5385)
+ * Revert room header click behaviour to opening room settings
+ [\#5434](https://github.com/matrix-org/matrix-react-sdk/pull/5434)
+ * Add option to send/edit a message with Ctrl + Enter / Command + Enter
+ [\#5160](https://github.com/matrix-org/matrix-react-sdk/pull/5160)
+ * Add Analytics instrumentation to the Homepage
+ [\#5409](https://github.com/matrix-org/matrix-react-sdk/pull/5409)
+ * Fix encrypted video playback in Chrome-based browsers
+ [\#5430](https://github.com/matrix-org/matrix-react-sdk/pull/5430)
+ * Add border-radius for video
+ [\#5333](https://github.com/matrix-org/matrix-react-sdk/pull/5333)
+ * Push name to the end, near text, in IRC layout
+ [\#5166](https://github.com/matrix-org/matrix-react-sdk/pull/5166)
+ * Disable notifications for the room you have recently been active in
+ [\#5325](https://github.com/matrix-org/matrix-react-sdk/pull/5325)
+ * Search through the list of unfiltered rooms rather than the rooms in the
+ state which are already filtered by the search text
+ [\#5331](https://github.com/matrix-org/matrix-react-sdk/pull/5331)
+ * Lighten blockquote colour in dark mode
+ [\#5353](https://github.com/matrix-org/matrix-react-sdk/pull/5353)
+ * Specify community description img must be mxc urls
+ [\#5364](https://github.com/matrix-org/matrix-react-sdk/pull/5364)
+ * Add keyboard shortcut to close the current conversation
+ [\#5253](https://github.com/matrix-org/matrix-react-sdk/pull/5253)
+ * Redirect user home from auth screens if they are already logged in
+ [\#5423](https://github.com/matrix-org/matrix-react-sdk/pull/5423)
+
Changes in [3.9.0](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v3.9.0) (2020-11-23)
===================================================================================================
[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v3.9.0-rc.1...v3.9.0)
diff --git a/package.json b/package.json
index 1e778f9875..d4a2c568d5 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "matrix-react-sdk",
- "version": "3.9.0",
+ "version": "3.10.0",
"description": "SDK for matrix.org using React",
"author": "matrix.org",
"repository": {
@@ -58,6 +58,7 @@
"blueimp-canvas-to-blob": "^3.27.0",
"browser-encrypt-attachment": "^0.3.0",
"browser-request": "^0.3.3",
+ "cheerio": "^1.0.0-rc.3",
"classnames": "^2.2.6",
"commonmark": "^0.29.1",
"counterpart": "^0.18.6",
@@ -77,7 +78,6 @@
"html-entities": "^1.3.1",
"is-ip": "^2.0.0",
"katex": "^0.12.0",
- "cheerio": "^1.0.0-rc.3",
"linkifyjs": "^2.1.9",
"lodash": "^4.17.19",
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#develop",
diff --git a/scripts/ci/riot-unit-tests.sh b/scripts/ci/riot-unit-tests.sh
deleted file mode 120000
index 199dfb58fd..0000000000
--- a/scripts/ci/riot-unit-tests.sh
+++ /dev/null
@@ -1 +0,0 @@
-app-tests.sh
\ No newline at end of file
diff --git a/src/CallHandler.tsx b/src/CallHandler.tsx
index b5f696008d..2c30c51041 100644
--- a/src/CallHandler.tsx
+++ b/src/CallHandler.tsx
@@ -393,14 +393,14 @@ export default class CallHandler {
title = _t("Unable to access microphone");
description =
{_t(
- "Call failed because no microphone could not be accessed. " +
+ "Call failed because microphone could not be accessed. " +
"Check that a microphone is plugged in and set up correctly.",
)}
;
} else if (call.type === CallType.Video) {
title = _t("Unable to access webcam / microphone");
description =
- {_t("Call failed because no webcam or microphone could not be accessed. Check that:")}
+ {_t("Call failed because webcam or microphone could not be accessed. Check that:")}
- {_t("A microphone and webcam are plugged in and set up correctly")}
- {_t("Permission is granted to use the webcam")}
diff --git a/src/SlashCommands.tsx b/src/SlashCommands.tsx
index 9af5ebcbfb..e2ae875ac3 100644
--- a/src/SlashCommands.tsx
+++ b/src/SlashCommands.tsx
@@ -46,6 +46,7 @@ import { EffectiveMembership, getEffectiveMembership, leaveRoomBehaviour } from
import SdkConfig from "./SdkConfig";
import SettingsStore from "./settings/SettingsStore";
import {UIFeature} from "./settings/UIFeature";
+import {CHAT_EFFECTS} from "./effects"
import CallHandler from "./CallHandler";
// XXX: workaround for https://github.com/microsoft/TypeScript/issues/31816
@@ -78,6 +79,7 @@ export const CommandCategories = {
"actions": _td("Actions"),
"admin": _td("Admin"),
"advanced": _td("Advanced"),
+ "effects": _td("Effects"),
"other": _td("Other"),
};
@@ -1094,6 +1096,30 @@ export const Commands = [
category: CommandCategories.messages,
hideCompletionAfterSpace: true,
}),
+
+ ...CHAT_EFFECTS.map((effect) => {
+ return new Command({
+ command: effect.command,
+ description: effect.description(),
+ args: '',
+ runFn: function(roomId, args) {
+ return success((async () => {
+ if (!args) {
+ args = effect.fallbackMessage();
+ MatrixClientPeg.get().sendEmoteMessage(roomId, args);
+ } else {
+ const content = {
+ msgtype: effect.msgType,
+ body: args,
+ };
+ MatrixClientPeg.get().sendMessage(roomId, content);
+ }
+ dis.dispatch({action: `effects.${effect.command}`});
+ })());
+ },
+ category: CommandCategories.effects,
+ })
+ }),
];
// build a map from names and aliases to the Command objects.
diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx
index adcb401ec1..d2d473fd3d 100644
--- a/src/components/structures/RoomView.tsx
+++ b/src/components/structures/RoomView.tsx
@@ -69,6 +69,9 @@ import AuxPanel from "../views/rooms/AuxPanel";
import RoomHeader from "../views/rooms/RoomHeader";
import {XOR} from "../../@types/common";
import { IThreepidInvite } from "../../stores/ThreepidInviteStore";
+import EffectsOverlay from "../views/elements/EffectsOverlay";
+import {containsEmoji} from '../../effects/utils';
+import {CHAT_EFFECTS} from '../../effects';
import { CallState, MatrixCall } from "matrix-js-sdk/src/webrtc/call";
import WidgetStore from "../../stores/WidgetStore";
import {UPDATE_EVENT} from "../../stores/AsyncStore";
@@ -248,6 +251,8 @@ export default class RoomView extends React.Component {
this.context.on("deviceVerificationChanged", this.onDeviceVerificationChanged);
this.context.on("userTrustStatusChanged", this.onUserVerificationChanged);
this.context.on("crossSigning.keysChanged", this.onCrossSigningKeysChanged);
+ this.context.on("Event.decrypted", this.onEventDecrypted);
+ this.context.on("event", this.onEvent);
// Start listening for RoomViewStore updates
this.roomStoreToken = RoomViewStore.addListener(this.onRoomViewStoreUpdate);
this.rightPanelStoreToken = RightPanelStore.getSharedInstance().addListener(this.onRightPanelStoreUpdate);
@@ -581,6 +586,8 @@ export default class RoomView extends React.Component {
this.context.removeListener("deviceVerificationChanged", this.onDeviceVerificationChanged);
this.context.removeListener("userTrustStatusChanged", this.onUserVerificationChanged);
this.context.removeListener("crossSigning.keysChanged", this.onCrossSigningKeysChanged);
+ this.context.removeListener("Event.decrypted", this.onEventDecrypted);
+ this.context.removeListener("event", this.onEvent);
}
window.removeEventListener('beforeunload', this.onPageUnload);
@@ -781,6 +788,27 @@ export default class RoomView extends React.Component {
}
};
+ private onEventDecrypted = (ev) => {
+ if (ev.isDecryptionFailure()) return;
+ this.handleEffects(ev);
+ };
+
+ private onEvent = (ev) => {
+ if (ev.isBeingDecrypted() || ev.isDecryptionFailure()) return;
+ this.handleEffects(ev);
+ };
+
+ private handleEffects = (ev) => {
+ if (!this.state.room ||
+ !this.state.matrixClientIsReady ||
+ this.state.room.getUnreadNotificationCount() === 0) return;
+ CHAT_EFFECTS.forEach(effect => {
+ if (containsEmoji(ev.getContent(), effect.emojis) || ev.getContent().msgtype === effect.msgType) {
+ dis.dispatch({action: `effects.${effect.command}`});
+ }
+ })
+ };
+
private onRoomName = (room: Room) => {
if (this.state.room && room.roomId == this.state.room.roomId) {
this.forceUpdate();
@@ -1946,9 +1974,14 @@ export default class RoomView extends React.Component {
mx_RoomView_inCall: Boolean(activeCall),
});
+ const showChatEffects = SettingsStore.getValue('showChatEffects');
+
return (
+ {showChatEffects && this.roomView.current &&
+
+ }
{
const ConfirmRedactDialog = sdk.getComponent("dialogs.ConfirmRedactDialog");
Modal.createTrackedDialog('Confirm Redact Dialog', '', ConfirmRedactDialog, {
- onFinished: async (proceed) => {
+ onFinished: async (proceed, reason) => {
if (!proceed) return;
const cli = MatrixClientPeg.get();
@@ -157,6 +157,8 @@ export default class MessageContextMenu extends React.Component {
await cli.redactEvent(
this.props.mxEvent.getRoomId(),
this.props.mxEvent.getId(),
+ undefined,
+ reason ? { reason } : {},
);
} catch (e) {
const code = e.errcode || e.statusCode;
diff --git a/src/components/views/dialogs/ConfirmRedactDialog.js b/src/components/views/dialogs/ConfirmRedactDialog.js
index 3106df1d5b..2216f9a93a 100644
--- a/src/components/views/dialogs/ConfirmRedactDialog.js
+++ b/src/components/views/dialogs/ConfirmRedactDialog.js
@@ -23,15 +23,17 @@ import { _t } from '../../../languageHandler';
*/
export default class ConfirmRedactDialog extends React.Component {
render() {
- const QuestionDialog = sdk.getComponent('views.dialogs.QuestionDialog');
+ const TextInputDialog = sdk.getComponent('views.dialogs.TextInputDialog');
return (
-
-
+
);
}
}
diff --git a/src/components/views/dialogs/ServerPickerDialog.tsx b/src/components/views/dialogs/ServerPickerDialog.tsx
index 9eb819c98e..4d967220e0 100644
--- a/src/components/views/dialogs/ServerPickerDialog.tsx
+++ b/src/components/views/dialogs/ServerPickerDialog.tsx
@@ -14,7 +14,8 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-import React, {createRef} from 'react';
+import React, {createRef} from "react";
+import {AutoDiscovery} from "matrix-js-sdk/src/autodiscovery";
import AutoDiscoveryUtils, {ValidatedServerConfig} from "../../../utils/AutoDiscoveryUtils";
import BaseDialog from './BaseDialog';
@@ -47,9 +48,10 @@ export default class ServerPickerDialog extends React.PureComponent({
- deriveData: async ({ value: hsUrl }) => {
- // Always try and use the defaults first
- const defaultConfig: ValidatedServerConfig = SdkConfig.get()["validated_server_config"];
- if (defaultConfig.hsUrl === hsUrl) return {};
+ deriveData: async ({ value }) => {
+ let hsUrl = value.trim(); // trim to account for random whitespace
+
+ // if the URL has no protocol, try validate it as a serverName via well-known
+ if (!hsUrl.includes("://")) {
+ try {
+ const discoveryResult = await AutoDiscovery.findClientConfig(hsUrl);
+ this.validatedConf = AutoDiscoveryUtils.buildValidatedConfigFromDiscovery(hsUrl, discoveryResult);
+ return {}; // we have a validated config, we don't need to try the other paths
+ } catch (e) {
+ console.error(`Attempted ${hsUrl} as a server_name but it failed`, e);
+ }
+ }
+
+ // if we got to this stage then either the well-known failed or the URL had a protocol specified,
+ // so validate statically only. If the URL has no protocol, default to https.
+ if (!hsUrl.includes("://")) {
+ hsUrl = "https://" + hsUrl;
+ }
try {
this.validatedConf = await AutoDiscoveryUtils.validateServerConfigWithStaticUrls(hsUrl);
@@ -81,17 +98,22 @@ export default class ServerPickerDialog extends React.PureComponent