Notifications
@@ -986,7 +988,7 @@ module.exports = React.createClass({
// we are using a version old version of olm. We assume the former.
let olmVersionString = "";
if (olmVersion !== undefined) {
- olmVersionString = `v${olmVersion[0]}.${olmVersion[1]}.${olmVersion[2]}`;
+ olmVersionString = `${olmVersion[0]}.${olmVersion[1]}.${olmVersion[2]}`;
}
return (
@@ -1044,7 +1046,7 @@ module.exports = React.createClass({
{this._renderReferral()}
- {notification_area}
+ {notificationArea}
{this._renderUserInterfaceSettings()}
{this._renderLabs()}
@@ -1061,7 +1063,10 @@ module.exports = React.createClass({
Logged in as {this._me}
- Access Token: <click to reveal>
+ Access Token: <click to reveal>
Homeserver is { MatrixClientPeg.get().getHomeserverUrl() }
@@ -1071,11 +1076,11 @@ module.exports = React.createClass({
matrix-react-sdk version: {(REACT_SDK_VERSION !== '
')
- ? {REACT_SDK_VERSION}
+ ? gHVersionLabel('matrix-org/matrix-react-sdk', REACT_SDK_VERSION)
: REACT_SDK_VERSION
}
riot-web version: {(this.state.vectorVersion !== null)
- ? {this.state.vectorVersion}
+ ? gHVersionLabel('vector-im/riot-web', this.state.vectorVersion)
: 'unknown'
}
olm version: {olmVersionString}
@@ -1089,5 +1094,5 @@ module.exports = React.createClass({
);
- }
+ },
});
diff --git a/src/components/structures/login/Login.js b/src/components/structures/login/Login.js
index 315a0ea242..a3635177e2 100644
--- a/src/components/structures/login/Login.js
+++ b/src/components/structures/login/Login.js
@@ -23,6 +23,9 @@ import url from 'url';
import sdk from '../../../index';
import Login from '../../../Login';
+// For validating phone numbers without country codes
+const PHONE_NUMBER_REGEX = /^[0-9\(\)\-\s]*$/;
+
/**
* A wire component which glues together login UI components and Login logic
*/
@@ -125,7 +128,16 @@ module.exports = React.createClass({
},
onPhoneNumberChanged: function(phoneNumber) {
- this.setState({ phoneNumber: phoneNumber });
+ // Validate the phone number entered
+ if (!PHONE_NUMBER_REGEX.test(phoneNumber)) {
+ this.setState({ errorText: 'The phone number entered looks invalid' });
+ return;
+ }
+
+ this.setState({
+ phoneNumber: phoneNumber,
+ errorText: null,
+ });
},
onServerConfigChange: function(config) {
diff --git a/src/components/views/avatars/RoomAvatar.js b/src/components/views/avatars/RoomAvatar.js
index bfa7575b0c..8041fd5cd7 100644
--- a/src/components/views/avatars/RoomAvatar.js
+++ b/src/components/views/avatars/RoomAvatar.js
@@ -59,7 +59,9 @@ module.exports = React.createClass({
ContentRepo.getHttpUriForMxc(
MatrixClientPeg.get().getHomeserverUrl(),
props.oobData.avatarUrl,
- props.width, props.height, props.resizeMethod
+ Math.floor(props.width * window.devicePixelRatio),
+ Math.floor(props.height * window.devicePixelRatio),
+ props.resizeMethod
), // highest priority
this.getRoomAvatarUrl(props),
this.getOneToOneAvatar(props),
@@ -74,7 +76,9 @@ module.exports = React.createClass({
return props.room.getAvatarUrl(
MatrixClientPeg.get().getHomeserverUrl(),
- props.width, props.height, props.resizeMethod,
+ Math.floor(props.width * window.devicePixelRatio),
+ Math.floor(props.height * window.devicePixelRatio),
+ props.resizeMethod,
false
);
},
@@ -103,14 +107,18 @@ module.exports = React.createClass({
}
return theOtherGuy.getAvatarUrl(
MatrixClientPeg.get().getHomeserverUrl(),
- props.width, props.height, props.resizeMethod,
+ Math.floor(props.width * window.devicePixelRatio),
+ Math.floor(props.height * window.devicePixelRatio),
+ props.resizeMethod,
false
);
} else if (userIds.length == 1) {
return mlist[userIds[0]].getAvatarUrl(
MatrixClientPeg.get().getHomeserverUrl(),
- props.width, props.height, props.resizeMethod,
- false
+ Math.floor(props.width * window.devicePixelRatio),
+ Math.floor(props.height * window.devicePixelRatio),
+ props.resizeMethod,
+ false
);
} else {
return null;
diff --git a/src/components/views/elements/MemberEventListSummary.js b/src/components/views/elements/MemberEventListSummary.js
index 63bd2a7c39..ae8678894d 100644
--- a/src/components/views/elements/MemberEventListSummary.js
+++ b/src/components/views/elements/MemberEventListSummary.js
@@ -369,6 +369,7 @@ module.exports = React.createClass({
render: function() {
const eventsToRender = this.props.events;
+ const eventIds = eventsToRender.map(e => e.getId()).join(',');
const fewEvents = eventsToRender.length < this.props.threshold;
const expanded = this.state.expanded || fewEvents;
@@ -379,7 +380,7 @@ module.exports = React.createClass({
if (fewEvents) {
return (
-
+
{expandedEvents}
);
@@ -437,7 +438,7 @@ module.exports = React.createClass({
);
return (
-
+
{toggleButton}
{summaryContainer}
{expanded ?
: null}
diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js
index 96ff65498f..49af1560f1 100644
--- a/src/components/views/rooms/RoomList.js
+++ b/src/components/views/rooms/RoomList.js
@@ -97,7 +97,7 @@ module.exports = React.createClass({
if (this.props.selectedRoom) {
constantTimeDispatcher.dispatch(
"RoomTile.select", this.props.selectedRoom, {}
- );
+ );
}
constantTimeDispatcher.dispatch(
"RoomTile.select", nextProps.selectedRoom, { selected: true }
@@ -265,7 +265,7 @@ module.exports = React.createClass({
},
onRoomStateMember: function(ev, state, member) {
- if (ev.getStateKey() === MatrixClientPeg.get().credentials.userId &&
+ if (ev.getStateKey() === MatrixClientPeg.get().credentials.userId &&
ev.getPrevContent() && ev.getPrevContent().membership === "invite")
{
this._delayedRefreshRoomList();
@@ -290,7 +290,7 @@ module.exports = React.createClass({
this._delayedRefreshRoomList();
}
else if (ev.getType() == 'm.push_rules') {
- this._delayedRefreshRoomList();
+ this._delayedRefreshRoomList();
}
},
@@ -318,7 +318,7 @@ module.exports = React.createClass({
// as needed.
// Alternatively we'd do something magical with Immutable.js or similar.
this.setState(this.getRoomLists());
-
+
// this._lastRefreshRoomListTs = Date.now();
},
@@ -341,7 +341,7 @@ module.exports = React.createClass({
MatrixClientPeg.get().getRooms().forEach(function(room) {
const me = room.getMember(MatrixClientPeg.get().credentials.userId);
if (!me) return;
-
+
// console.log("room = " + room.name + ", me.membership = " + me.membership +
// ", sender = " + me.events.member.getSender() +
// ", target = " + me.events.member.getStateKey() +
@@ -391,51 +391,10 @@ module.exports = React.createClass({
}
});
- if (s.lists["im.vector.fake.direct"].length == 0 &&
- MatrixClientPeg.get().getAccountData('m.direct') === undefined &&
- !MatrixClientPeg.get().isGuest())
- {
- // scan through the 'recents' list for any rooms which look like DM rooms
- // and make them DM rooms
- const oldRecents = s.lists["im.vector.fake.recent"];
- s.lists["im.vector.fake.recent"] = [];
-
- for (const room of oldRecents) {
- const me = room.getMember(MatrixClientPeg.get().credentials.userId);
-
- if (me && Rooms.looksLikeDirectMessageRoom(room, me)) {
- self.listsForRoomId[room.roomId].push("im.vector.fake.direct");
- s.lists["im.vector.fake.direct"].push(room);
- } else {
- self.listsForRoomId[room.roomId].push("im.vector.fake.recent");
- s.lists["im.vector.fake.recent"].push(room);
- }
- }
-
- // save these new guessed DM rooms into the account data
- const newMDirectEvent = {};
- for (const room of s.lists["im.vector.fake.direct"]) {
- const me = room.getMember(MatrixClientPeg.get().credentials.userId);
- const otherPerson = Rooms.getOnlyOtherMember(room, me);
- if (!otherPerson) continue;
-
- const roomList = newMDirectEvent[otherPerson.userId] || [];
- roomList.push(room.roomId);
- newMDirectEvent[otherPerson.userId] = roomList;
- }
-
- console.warn("Resetting room DM state to be " + JSON.stringify(newMDirectEvent));
-
- // if this fails, fine, we'll just do the same thing next time we get the room lists
- MatrixClientPeg.get().setAccountData('m.direct', newMDirectEvent).done();
- }
-
- //console.log("calculated new roomLists; im.vector.fake.recent = " + s.lists["im.vector.fake.recent"]);
-
// we actually apply the sorting to this when receiving the prop in RoomSubLists.
// we'll need this when we get to iterating through lists programatically - e.g. ctrl-shift-up/down
-/*
+/*
this.listOrder = [
"im.vector.fake.invite",
"m.favourite",
diff --git a/src/components/views/rooms/SearchResultTile.js b/src/components/views/rooms/SearchResultTile.js
index 7fac244481..1aba7c9196 100644
--- a/src/components/views/rooms/SearchResultTile.js
+++ b/src/components/views/rooms/SearchResultTile.js
@@ -60,7 +60,7 @@ module.exports = React.createClass({
}
}
return (
-
+
{ret}
);
},
diff --git a/src/components/views/rooms/SimpleRoomHeader.js b/src/components/views/rooms/SimpleRoomHeader.js
index 40995d2a72..a6f342af86 100644
--- a/src/components/views/rooms/SimpleRoomHeader.js
+++ b/src/components/views/rooms/SimpleRoomHeader.js
@@ -19,6 +19,7 @@ limitations under the License.
import React from 'react';
import dis from '../../../dispatcher';
import AccessibleButton from '../elements/AccessibleButton';
+import sdk from '../../../index';
// cancel button which is shared between room header and simple room header
export function CancelButton(props) {
@@ -45,6 +46,9 @@ export default React.createClass({
// is the RightPanel collapsed?
collapsedRhs: React.PropTypes.bool,
+
+ // `src` to a TintableSvg. Optional.
+ icon: React.PropTypes.string,
},
onShowRhsClick: function(ev) {
@@ -53,9 +57,17 @@ export default React.createClass({
render: function() {
let cancelButton;
+ let icon;
if (this.props.onCancelClick) {
cancelButton =
;
}
+ if (this.props.icon) {
+ const TintableSvg = sdk.getComponent('elements.TintableSvg');
+ icon =
;
+ }
let showRhsButton;
/* // don't bother cluttering things up with this for now.
@@ -73,6 +85,7 @@ export default React.createClass({
+ { icon }
{ this.props.title }
{ showRhsButton }
{ cancelButton }
diff --git a/test/components/structures/ScrollPanel-test.js b/test/components/structures/ScrollPanel-test.js
index eacaeb5fb4..7ecb74be6f 100644
--- a/test/components/structures/ScrollPanel-test.js
+++ b/test/components/structures/ScrollPanel-test.js
@@ -115,7 +115,7 @@ var Tester = React.createClass({
//
// there is an extra 50 pixels of margin at the bottom.
return (
-
+
{key}