diff --git a/CHANGELOG.md b/CHANGELOG.md
index a20b902a6e..b161a9d908 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,10 @@
+Changes in [0.12.5](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.12.5) (2018-05-17)
+=====================================================================================================
+[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.12.4...v0.12.5)
+
+ * Fix image size jumping regression
+ [\#1909](https://github.com/matrix-org/matrix-react-sdk/pull/1909)
+
Changes in [0.12.4](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.12.4) (2018-05-16)
=====================================================================================================
[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.12.4-rc.6...v0.12.4)
diff --git a/package.json b/package.json
index 60f65f4c39..6c34979c43 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "matrix-react-sdk",
- "version": "0.12.4",
+ "version": "0.12.5",
"description": "SDK for matrix.org using React",
"author": "matrix.org",
"repository": {
diff --git a/src/HtmlUtils.js b/src/HtmlUtils.js
index 58572cf144..7ca404be31 100644
--- a/src/HtmlUtils.js
+++ b/src/HtmlUtils.js
@@ -413,12 +413,13 @@ class TextHighlighter extends BaseHighlighter {
* opts.stripReplyFallback: optional argument specifying the event is a reply and so fallback needs removing
*/
export function bodyToHtml(content, highlights, opts={}) {
- let isHtml = content.format === "org.matrix.custom.html" && content.formatted_body;
+ const isHtmlMessage = content.format === "org.matrix.custom.html" && content.formatted_body;
let bodyHasEmoji = false;
let strippedBody;
let safeBody;
+ let isDisplayedWithHtml;
// XXX: We sanitize the HTML whilst also highlighting its text nodes, to avoid accidentally trying
// to highlight HTML tags themselves. However, this does mean that we don't highlight textnodes which
// are interrupted by HTML tags (not that we did before) - e.g. foobar won't get highlighted
@@ -439,17 +440,18 @@ export function bodyToHtml(content, highlights, opts={}) {
if (opts.stripReplyFallback && formattedBody) formattedBody = ReplyThread.stripHTMLReply(formattedBody);
strippedBody = opts.stripReplyFallback ? ReplyThread.stripPlainReply(content.body) : content.body;
- bodyHasEmoji = containsEmoji(isHtml ? formattedBody : content.body);
+ bodyHasEmoji = containsEmoji(isHtmlMessage ? formattedBody : content.body);
// Only generate safeBody if the message was sent as org.matrix.custom.html
- if (isHtml) {
+ if (isHtmlMessage) {
+ isDisplayedWithHtml = true;
safeBody = sanitizeHtml(formattedBody, sanitizeHtmlParams);
} else {
// ... or if there are emoji, which we insert as HTML alongside the
// escaped plaintext body.
if (bodyHasEmoji) {
- isHtml = true;
+ isDisplayedWithHtml = true;
safeBody = sanitizeHtml(escape(strippedBody), sanitizeHtmlParams);
}
}
@@ -475,10 +477,10 @@ export function bodyToHtml(content, highlights, opts={}) {
const className = classNames({
'mx_EventTile_body': true,
'mx_EventTile_bigEmoji': emojiBody,
- 'markdown-body': isHtml,
+ 'markdown-body': isHtmlMessage,
});
- return isHtml ?
+ return isDisplayedWithHtml ?
:
{ strippedBody };
}
diff --git a/src/RoomInvite.js b/src/RoomInvite.js
index 31541148d9..0bcc08eb06 100644
--- a/src/RoomInvite.js
+++ b/src/RoomInvite.js
@@ -57,6 +57,7 @@ export function showStartChatInviteDialog() {
title: _t('Start a chat'),
description: _t("Who would you like to communicate with?"),
placeholder: _t("Email, name or matrix ID"),
+ validAddressTypes: ['mx-user-id', 'email'],
button: _t("Start Chat"),
onFinished: _onStartChatFinished,
});
diff --git a/src/components/structures/LoggedInView.js b/src/components/structures/LoggedInView.js
index d9ac9de693..2dd5a75c47 100644
--- a/src/components/structures/LoggedInView.js
+++ b/src/components/structures/LoggedInView.js
@@ -266,6 +266,7 @@ const LoggedInView = React.createClass({
const GroupView = sdk.getComponent('structures.GroupView');
const MyGroups = sdk.getComponent('structures.MyGroups');
const MatrixToolbar = sdk.getComponent('globals.MatrixToolbar');
+ const CookieBar = sdk.getComponent('globals.CookieBar');
const NewVersionBar = sdk.getComponent('globals.NewVersionBar');
const UpdateCheckBar = sdk.getComponent('globals.UpdateCheckBar');
const PasswordNagBar = sdk.getComponent('globals.PasswordNagBar');
@@ -353,7 +354,12 @@ const LoggedInView = React.createClass({
let topBar;
const isGuest = this.props.matrixClient.isGuest();
- if (this.props.hasNewVersion) {
+ if (this.props.showCookieBar &&
+ this.props.config.piwik
+ ) {
+ const policyUrl = this.props.config.piwik.policyUrl || null;
+ topBar = ;
+ } else if (this.props.hasNewVersion) {
topBar = ;
diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js
index 3005bc86ad..051b9ed10b 100644
--- a/src/components/structures/MatrixChat.js
+++ b/src/components/structures/MatrixChat.js
@@ -165,6 +165,8 @@ export default React.createClass({
newVersionReleaseNotes: null,
checkingForUpdate: null,
+ showCookieBar: false,
+
// Parameters used in the registration dance with the IS
register_client_secret: null,
register_session_id: null,
@@ -227,8 +229,6 @@ export default React.createClass({
componentWillMount: function() {
SdkConfig.put(this.props.config);
- if (!SettingsStore.getValue("analyticsOptOut")) Analytics.enable();
-
// Used by _viewRoom before getting state from sync
this.firstSyncComplete = false;
this.firstSyncPromise = Promise.defer();
@@ -361,6 +361,16 @@ export default React.createClass({
// loadSession as there's logic there to ask the user if they want
// to try logging out.
});
+
+ if (SettingsStore.getValue("showCookieBar")) {
+ this.setState({
+ showCookieBar: true,
+ });
+ }
+
+ if (SettingsStore.getValue("analyticsOptIn")) {
+ Analytics.enable();
+ }
},
componentWillUnmount: function() {
@@ -673,6 +683,23 @@ export default React.createClass({
hideToSRUsers: false,
});
break;
+ case 'accept_cookies':
+ SettingsStore.setValue("analyticsOptIn", null, SettingLevel.DEVICE, true);
+ SettingsStore.setValue("showCookieBar", null, SettingLevel.DEVICE, false);
+
+ this.setState({
+ showCookieBar: false,
+ });
+ Analytics.enable();
+ break;
+ case 'reject_cookies':
+ SettingsStore.setValue("analyticsOptIn", null, SettingLevel.DEVICE, false);
+ SettingsStore.setValue("showCookieBar", null, SettingLevel.DEVICE, false);
+
+ this.setState({
+ showCookieBar: false,
+ });
+ break;
}
},
@@ -1621,6 +1648,7 @@ export default React.createClass({
onRegistered={this.onRegistered}
currentRoomId={this.state.currentRoomId}
teamToken={this._teamToken}
+ showCookieBar={this.state.showCookieBar}
{...this.props}
{...this.state}
/>
diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js
index 35a55284fd..c8ce79905d 100644
--- a/src/components/structures/UserSettings.js
+++ b/src/components/structures/UserSettings.js
@@ -86,9 +86,9 @@ const SIMPLE_SETTINGS = [
// These settings must be defined in SettingsStore
const ANALYTICS_SETTINGS = [
{
- id: 'analyticsOptOut',
+ id: 'analyticsOptIn',
fn: function(checked) {
- Analytics[checked ? 'disable' : 'enable']();
+ checked ? Analytics.enable() : Analytics.disable();
},
},
];
diff --git a/src/components/views/globals/CookieBar.js b/src/components/views/globals/CookieBar.js
new file mode 100644
index 0000000000..8fab64be67
--- /dev/null
+++ b/src/components/views/globals/CookieBar.js
@@ -0,0 +1,78 @@
+/*
+Copyright 2018 New Vector Ltd.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+import React from 'react';
+import PropTypes from 'prop-types';
+import dis from '../../../dispatcher';
+import { _t } from '../../../languageHandler';
+import sdk from '../../../index';
+
+export default class CookieBar extends React.Component {
+ static propTypes = {
+ policyUrl: PropTypes.string,
+ }
+
+ constructor() {
+ super();
+ }
+
+ onAccept() {
+ dis.dispatch({
+ action: 'accept_cookies',
+ });
+ }
+
+ onReject() {
+ dis.dispatch({
+ action: 'reject_cookies',
+ });
+ }
+
+ render() {
+ const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
+ const toolbarClasses = "mx_MatrixToolbar";
+ return (
+
+
+
+ { this.props.policyUrl ? _t(
+ "Help improve Riot by sending usage data? " +
+ "This will use a cookie. " +
+ "(See our
cookie and privacy policies).",
+ {},
+ {
+ // XXX: We need to link to the page that explains our cookies
+ 'PolicyLink': (sub) =>
+ { sub }
+
+ ,
+ },
+ ) : _t("Help improve Riot by sending usage data? This will use a cookie.") }
+
+
+ { _t("Yes please") }
+
+
+
+
+
+ );
+ }
+}
diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js
index 03dad5e439..f27124238e 100644
--- a/src/components/views/messages/MImageBody.js
+++ b/src/components/views/messages/MImageBody.js
@@ -1,5 +1,6 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
+Copyright 2018 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -210,6 +211,7 @@ export default class extends React.Component {
});
}).done();
}
+ this.fixupHeight();
this._afterComponentDidMount();
}
diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json
index 957deb35c5..239b45c32e 100644
--- a/src/i18n/strings/en_EN.json
+++ b/src/i18n/strings/en_EN.json
@@ -209,7 +209,7 @@
"Mirror local video feed": "Mirror local video feed",
"Disable Community Filter Panel": "Disable Community Filter Panel",
"Disable Peer-to-Peer for 1:1 calls": "Disable Peer-to-Peer for 1:1 calls",
- "Opt out of analytics": "Opt out of analytics",
+ "Send analytics data": "Send analytics data",
"Never send encrypted messages to unverified devices from this device": "Never send encrypted messages to unverified devices from this device",
"Never send encrypted messages to unverified devices in this room from this device": "Never send encrypted messages to unverified devices in this room from this device",
"Enable inline URL previews by default": "Enable inline URL previews by default",
@@ -634,6 +634,9 @@
"Something went wrong when trying to get your communities.": "Something went wrong when trying to get your communities.",
"Display your community flair in rooms configured to show it.": "Display your community flair in rooms configured to show it.",
"You're not currently a member of any communities.": "You're not currently a member of any communities.",
+ "Help improve Riot by sending usage data? This will use a cookie. (See our cookie and privacy policies).": "Help improve Riot by sending usage data? This will use a cookie. (See our cookie and privacy policies).",
+ "Help improve Riot by sending usage data? This will use a cookie.": "Help improve Riot by sending usage data? This will use a cookie.",
+ "Yes please": "Yes please",
"You are not receiving desktop notifications": "You are not receiving desktop notifications",
"Enable them now": "Enable them now",
"What's New": "What's New",
diff --git a/src/settings/Settings.js b/src/settings/Settings.js
index 663318f990..b1bc4161fd 100644
--- a/src/settings/Settings.js
+++ b/src/settings/Settings.js
@@ -213,11 +213,15 @@ export const SETTINGS = {
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG,
default: "en",
},
- "analyticsOptOut": {
+ "analyticsOptIn": {
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG,
- displayName: _td('Opt out of analytics'),
+ displayName: _td('Send analytics data'),
default: false,
},
+ "showCookieBar": {
+ supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG,
+ default: true,
+ },
"autocompleteDelay": {
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG,
default: 200,