-
+
Download {text}
diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js
index ab163297d7..0b4bc6ecb9 100644
--- a/src/components/views/messages/MImageBody.js
+++ b/src/components/views/messages/MImageBody.js
@@ -56,6 +56,7 @@ module.exports = React.createClass({
const ImageView = sdk.getComponent("elements.ImageView");
const params = {
src: httpUrl,
+ name: content.body && content.body.length > 0 ? content.body : 'Attachment',
mxEvent: this.props.mxEvent,
};
diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js
index 9df0499eb2..9dc1087ce5 100644
--- a/src/components/views/rooms/EventTile.js
+++ b/src/components/views/rooms/EventTile.js
@@ -284,6 +284,12 @@ module.exports = WithMatrixClient(React.createClass({
},
getReadAvatars: function() {
+
+ // return early if there are no read receipts
+ if (!this.props.readReceipts || this.props.readReceipts.length === 0) {
+ return (
);
+ }
+
const ReadReceiptMarker = sdk.getComponent('rooms.ReadReceiptMarker');
const avatars = [];
const receiptOffset = 15;
diff --git a/src/components/views/rooms/MemberInfo.js b/src/components/views/rooms/MemberInfo.js
index 1459ad3eb7..1a9a8d5e0f 100644
--- a/src/components/views/rooms/MemberInfo.js
+++ b/src/components/views/rooms/MemberInfo.js
@@ -241,8 +241,8 @@ module.exports = WithMatrixClient(React.createClass({
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
console.error("Kick error: " + err);
Modal.createDialog(ErrorDialog, {
- title: "Error",
- description: "Failed to kick user",
+ title: "Failed to kick",
+ description: ((err && err.message) ? err.message : "Operation failed"),
});
}
).finally(()=>{
diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js
index 51c9ba881b..417d003226 100644
--- a/src/components/views/rooms/MessageComposerInput.js
+++ b/src/components/views/rooms/MessageComposerInput.js
@@ -355,6 +355,7 @@ export default class MessageComposerInput extends React.Component {
}
sendTyping(isTyping) {
+ if (UserSettingsStore.getSyncedSetting('dontSendTypingNotifications', false)) return;
MatrixClientPeg.get().sendTyping(
this.props.room.roomId,
this.isTyping, TYPING_SERVER_TIMEOUT
@@ -509,7 +510,7 @@ export default class MessageComposerInput extends React.Component {
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createDialog(ErrorDialog, {
title: "Server error",
- description: "Server unavailable, overloaded, or something else went wrong.",
+ description: ((err && err.message) ? err.message : "Server unavailable, overloaded, or something else went wrong."),
});
});
}
diff --git a/src/components/views/rooms/MessageComposerInputOld.js b/src/components/views/rooms/MessageComposerInputOld.js
index f0b650eb04..378644478c 100644
--- a/src/components/views/rooms/MessageComposerInputOld.js
+++ b/src/components/views/rooms/MessageComposerInputOld.js
@@ -20,6 +20,7 @@ var SlashCommands = require("../../../SlashCommands");
var Modal = require("../../../Modal");
var MemberEntry = require("../../../TabCompleteEntries").MemberEntry;
var sdk = require('../../../index');
+import UserSettingsStore from "../../../UserSettingsStore";
var dis = require("../../../dispatcher");
var KeyCode = require("../../../KeyCode");
@@ -311,7 +312,7 @@ export default React.createClass({
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createDialog(ErrorDialog, {
title: "Server error",
- description: "Server unavailable, overloaded, or something else went wrong.",
+ description: ((err && err.message) ? err.message : "Server unavailable, overloaded, or something else went wrong."),
});
});
}
@@ -420,6 +421,7 @@ export default React.createClass({
},
sendTyping: function(isTyping) {
+ if (UserSettingsStore.getSyncedSetting('dontSendTypingNotifications', false)) return;
MatrixClientPeg.get().sendTyping(
this.props.room.roomId,
this.isTyping, TYPING_SERVER_TIMEOUT
diff --git a/src/components/views/rooms/PresenceLabel.js b/src/components/views/rooms/PresenceLabel.js
index 2ece4c771e..52d831fcf6 100644
--- a/src/components/views/rooms/PresenceLabel.js
+++ b/src/components/views/rooms/PresenceLabel.js
@@ -75,7 +75,7 @@ module.exports = React.createClass({
render: function() {
if (this.props.activeAgo >= 0) {
- var ago = this.props.currentlyActive ? "now" : (this.getDuration(this.props.activeAgo) + " ago");
+ var ago = this.props.currentlyActive ? "" : "for " + (this.getDuration(this.props.activeAgo));
// var ago = this.getDuration(this.props.activeAgo) + " ago";
// if (this.props.currentlyActive) ago += " (now?)";
return (
diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js
index 394de8876b..96ff65498f 100644
--- a/src/components/views/rooms/RoomList.js
+++ b/src/components/views/rooms/RoomList.js
@@ -265,9 +265,16 @@ module.exports = React.createClass({
},
onRoomStateMember: function(ev, state, member) {
- constantTimeDispatcher.dispatch(
- "RoomTile.refresh", member.roomId, {}
- );
+ if (ev.getStateKey() === MatrixClientPeg.get().credentials.userId &&
+ ev.getPrevContent() && ev.getPrevContent().membership === "invite")
+ {
+ this._delayedRefreshRoomList();
+ }
+ else {
+ constantTimeDispatcher.dispatch(
+ "RoomTile.refresh", member.roomId, {}
+ );
+ }
},
onRoomMemberName: function(ev, member) {
@@ -449,11 +456,10 @@ module.exports = React.createClass({
var panel = ReactDOM.findDOMNode(this);
if (!panel) return null;
- if (panel.classList.contains('gm-prevented')) {
- return panel;
- } else {
- return panel.children[2]; // XXX: Fragile!
- }
+ // empirically, if we have gm-prevented for some reason, the scroll node
+ // is still the 3rd child (i.e. the view child). This looks to be due
+ // to vdh's improved resize updater logic...?
+ return panel.children[2]; // XXX: Fragile!
},
_whenScrolling: function(e) {
@@ -476,7 +482,7 @@ module.exports = React.createClass({
// Use the offset of the top of the scroll area from the window
// as this is used to calculate the CSS fixed top position for the stickies
var scrollAreaOffset = scrollArea.getBoundingClientRect().top + window.pageYOffset;
- // Use the offset of the top of the componet from the window
+ // Use the offset of the top of the component from the window
// as this is used to calculate the CSS fixed top position for the stickies
var scrollAreaHeight = ReactDOM.findDOMNode(this).getBoundingClientRect().height;
@@ -499,7 +505,7 @@ module.exports = React.createClass({
// Use the offset of the top of the scroll area from the window
// as this is used to calculate the CSS fixed top position for the stickies
var scrollAreaOffset = scrollArea.getBoundingClientRect().top + window.pageYOffset;
- // Use the offset of the top of the componet from the window
+ // Use the offset of the top of the component from the window
// as this is used to calculate the CSS fixed top position for the stickies
var scrollAreaHeight = ReactDOM.findDOMNode(this).getBoundingClientRect().height;
@@ -599,7 +605,7 @@ module.exports = React.createClass({
return (
+ autoshow={true} onScroll={ self._whenScrolling } onResize={ self._whenScrolling } ref="gemscroll">
{
- this.forceUpdate();
- }, (err) => {
- this.setState({
- scalar_error: err
+ this.scalarClient = null;
+ if (SdkConfig.get().integrations_ui_url && SdkConfig.get().integrations_rest_url) {
+ this.scalarClient = new ScalarAuthClient();
+ this.scalarClient.connect().done(() => {
+ this.forceUpdate();
+ }, (err) => {
+ this.setState({
+ scalar_error: err
+ });
});
- });
+ }
dis.dispatch({
action: 'ui_opacity',
@@ -490,7 +493,7 @@ module.exports = React.createClass({
ev.preventDefault();
var IntegrationsManager = sdk.getComponent("views.settings.IntegrationsManager");
Modal.createDialog(IntegrationsManager, {
- src: this.scalarClient.hasCredentials() ?
+ src: (this.scalarClient !== null && this.scalarClient.hasCredentials()) ?
this.scalarClient.getScalarInterfaceUrlForRoom(this.props.room.roomId) :
null,
onFinished: ()=>{
@@ -765,36 +768,39 @@ module.exports = React.createClass({
;
}
- var integrationsButton;
- var integrationsError;
- if (this.state.showIntegrationsError && this.state.scalar_error) {
- console.error(this.state.scalar_error);
- integrationsError = (
-
- Could not connect to the integration server
-
- );
- }
+ let integrationsButton;
+ let integrationsError;
- if (this.scalarClient.hasCredentials()) {
- integrationsButton = (
+ if (this.scalarClient !== null) {
+ if (this.state.showIntegrationsError && this.state.scalar_error) {
+ console.error(this.state.scalar_error);
+ integrationsError = (
+
+ Could not connect to the integration server
+
+ );
+ }
+
+ if (this.scalarClient.hasCredentials()) {
+ integrationsButton = (
- Manage Integrations
-
- );
- } else if (this.state.scalar_error) {
- integrationsButton = (
+ Manage Integrations
+
+ );
+ } else if (this.state.scalar_error) {
+ integrationsButton = (