Merge pull request #243 from matrix-org/dbkr/error_messages
Add better user-facing error messages
This commit is contained in:
commit
abe4df5f1c
10 changed files with 176 additions and 21 deletions
|
@ -46,6 +46,7 @@ module.exports.components['views.create_room.Presets'] = require('./components/v
|
||||||
module.exports.components['views.create_room.RoomAlias'] = require('./components/views/create_room/RoomAlias');
|
module.exports.components['views.create_room.RoomAlias'] = require('./components/views/create_room/RoomAlias');
|
||||||
module.exports.components['views.dialogs.ErrorDialog'] = require('./components/views/dialogs/ErrorDialog');
|
module.exports.components['views.dialogs.ErrorDialog'] = require('./components/views/dialogs/ErrorDialog');
|
||||||
module.exports.components['views.dialogs.LogoutPrompt'] = require('./components/views/dialogs/LogoutPrompt');
|
module.exports.components['views.dialogs.LogoutPrompt'] = require('./components/views/dialogs/LogoutPrompt');
|
||||||
|
module.exports.components['views.dialogs.NeedToRegisterDialog'] = require('./components/views/dialogs/NeedToRegisterDialog');
|
||||||
module.exports.components['views.dialogs.QuestionDialog'] = require('./components/views/dialogs/QuestionDialog');
|
module.exports.components['views.dialogs.QuestionDialog'] = require('./components/views/dialogs/QuestionDialog');
|
||||||
module.exports.components['views.dialogs.SetDisplayNameDialog'] = require('./components/views/dialogs/SetDisplayNameDialog');
|
module.exports.components['views.dialogs.SetDisplayNameDialog'] = require('./components/views/dialogs/SetDisplayNameDialog');
|
||||||
module.exports.components['views.dialogs.TextInputDialog'] = require('./components/views/dialogs/TextInputDialog');
|
module.exports.components['views.dialogs.TextInputDialog'] = require('./components/views/dialogs/TextInputDialog');
|
||||||
|
|
|
@ -464,9 +464,18 @@ module.exports = React.createClass({
|
||||||
//this.notifyNewScreen('new');
|
//this.notifyNewScreen('new');
|
||||||
|
|
||||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||||
|
var NeedToRegisterDialog = sdk.getComponent("dialogs.NeedToRegisterDialog");
|
||||||
var Loader = sdk.getComponent("elements.Spinner");
|
var Loader = sdk.getComponent("elements.Spinner");
|
||||||
var modal = Modal.createDialog(Loader);
|
var modal = Modal.createDialog(Loader);
|
||||||
|
|
||||||
|
if (MatrixClientPeg.get().isGuest) {
|
||||||
|
Modal.createDialog(NeedToRegisterDialog, {
|
||||||
|
title: "Please Register",
|
||||||
|
description: "Guest users can't create new rooms. Please register to create room and start a chat."
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// XXX: FIXME: deduplicate this with MemberInfo's 'start chat' impl
|
// XXX: FIXME: deduplicate this with MemberInfo's 'start chat' impl
|
||||||
MatrixClientPeg.get().createRoom({
|
MatrixClientPeg.get().createRoom({
|
||||||
preset: "private_chat",
|
preset: "private_chat",
|
||||||
|
|
|
@ -575,12 +575,28 @@ module.exports = React.createClass({
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!error) return;
|
if (!error) return;
|
||||||
|
|
||||||
|
// https://matrix.org/jira/browse/SYN-659
|
||||||
|
if (
|
||||||
|
error.errcode == 'M_GUEST_ACCESS_FORBIDDEN' ||
|
||||||
|
(
|
||||||
|
error.errcode == 'M_FORBIDDEN' &&
|
||||||
|
MatrixClientPeg.get().isGuest()
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
var NeedToRegisterDialog = sdk.getComponent("dialogs.NeedToRegisterDialog");
|
||||||
|
Modal.createDialog(NeedToRegisterDialog, {
|
||||||
|
title: "Failed to join the room",
|
||||||
|
description: "This room is private or inaccessible to guests. You may be able to join if you register."
|
||||||
|
});
|
||||||
|
} else {
|
||||||
var msg = error.message ? error.message : JSON.stringify(error);
|
var msg = error.message ? error.message : JSON.stringify(error);
|
||||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||||
Modal.createDialog(ErrorDialog, {
|
Modal.createDialog(ErrorDialog, {
|
||||||
title: "Failed to join room",
|
title: "Failed to join room",
|
||||||
description: msg
|
description: msg
|
||||||
});
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
this.setState({
|
this.setState({
|
||||||
joining: true
|
joining: true
|
||||||
|
|
|
@ -570,9 +570,15 @@ var TimelinePanel = React.createClass({
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
var message = "Vector was trying to load a specific point in this room's timeline but ";
|
||||||
|
if (error.errcode == 'M_FORBIDDEN') {
|
||||||
|
message += "you do not have permission to view the message in question.";
|
||||||
|
} else {
|
||||||
|
message += "was unable to find it.";
|
||||||
|
}
|
||||||
Modal.createDialog(ErrorDialog, {
|
Modal.createDialog(ErrorDialog, {
|
||||||
title: "Failed to load event",
|
title: "Failed to load timeline position",
|
||||||
description: msg,
|
description: message,
|
||||||
onFinished: onFinished,
|
onFinished: onFinished,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,9 +91,9 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
onAvatarPickerClick: function(ev) {
|
onAvatarPickerClick: function(ev) {
|
||||||
if (MatrixClientPeg.get().isGuest()) {
|
if (MatrixClientPeg.get().isGuest()) {
|
||||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
var NeedToRegisterDialog = sdk.getComponent("dialogs.NeedToRegisterDialog");
|
||||||
Modal.createDialog(ErrorDialog, {
|
Modal.createDialog(NeedToRegisterDialog, {
|
||||||
title: "Error",
|
title: "Please Register",
|
||||||
description: "Guests can't set avatars. Please register.",
|
description: "Guests can't set avatars. Please register.",
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -20,7 +20,7 @@ limitations under the License.
|
||||||
* title: "some text", (default: "Error")
|
* title: "some text", (default: "Error")
|
||||||
* description: "some more text",
|
* description: "some more text",
|
||||||
* button: "Button Text",
|
* button: "Button Text",
|
||||||
* onClose: someFunction,
|
* onFinished: someFunction,
|
||||||
* focus: true|false (default: true)
|
* focus: true|false (default: true)
|
||||||
* });
|
* });
|
||||||
*/
|
*/
|
||||||
|
|
76
src/components/views/dialogs/NeedToRegisterDialog.js
Normal file
76
src/components/views/dialogs/NeedToRegisterDialog.js
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
Copyright 2016 OpenMarket 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Usage:
|
||||||
|
* Modal.createDialog(NeedToRegisterDialog, {
|
||||||
|
* title: "some text", (default: "Registration required")
|
||||||
|
* description: "some more text",
|
||||||
|
* onFinished: someFunction,
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
|
||||||
|
var React = require("react");
|
||||||
|
var dis = require("../../../dispatcher");
|
||||||
|
|
||||||
|
module.exports = React.createClass({
|
||||||
|
displayName: 'NeedToRegisterDialog',
|
||||||
|
propTypes: {
|
||||||
|
title: React.PropTypes.string,
|
||||||
|
description: React.PropTypes.oneOfType([
|
||||||
|
React.PropTypes.element,
|
||||||
|
React.PropTypes.string,
|
||||||
|
]),
|
||||||
|
onFinished: React.PropTypes.func.isRequired,
|
||||||
|
},
|
||||||
|
|
||||||
|
getDefaultProps: function() {
|
||||||
|
return {
|
||||||
|
title: "Registration required",
|
||||||
|
description: "A registered account is required for this action",
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
onRegisterClicked: function() {
|
||||||
|
dis.dispatch({
|
||||||
|
action: "start_upgrade_registration",
|
||||||
|
});
|
||||||
|
if (this.props.onFinished) {
|
||||||
|
this.props.onFinished();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function() {
|
||||||
|
return (
|
||||||
|
<div className="mx_NeedToRegisterDialog">
|
||||||
|
<div className="mx_Dialog_title">
|
||||||
|
{this.props.title}
|
||||||
|
</div>
|
||||||
|
<div className="mx_Dialog_content">
|
||||||
|
{this.props.description}
|
||||||
|
</div>
|
||||||
|
<div className="mx_Dialog_buttons">
|
||||||
|
<button onClick={this.onRegisterClicked}>
|
||||||
|
Register
|
||||||
|
</button>
|
||||||
|
<button onClick={this.props.onFinished} autoFocus={true}>
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
|
@ -16,8 +16,10 @@ limitations under the License.
|
||||||
var q = require("q");
|
var q = require("q");
|
||||||
var React = require('react');
|
var React = require('react');
|
||||||
|
|
||||||
|
var sdk = require('../../../index');
|
||||||
var Tinter = require('../../../Tinter');
|
var Tinter = require('../../../Tinter');
|
||||||
var MatrixClientPeg = require("../../../MatrixClientPeg");
|
var MatrixClientPeg = require("../../../MatrixClientPeg");
|
||||||
|
var Modal = require("../../../Modal");
|
||||||
|
|
||||||
var ROOM_COLORS = [
|
var ROOM_COLORS = [
|
||||||
// magic room default values courtesy of Ribot
|
// magic room default values courtesy of Ribot
|
||||||
|
@ -74,12 +76,23 @@ module.exports = React.createClass({
|
||||||
if (originalState.primary_color !== this.state.primary_color ||
|
if (originalState.primary_color !== this.state.primary_color ||
|
||||||
originalState.secondary_color !== this.state.secondary_color) {
|
originalState.secondary_color !== this.state.secondary_color) {
|
||||||
console.log("ColorSettings: Saving new color");
|
console.log("ColorSettings: Saving new color");
|
||||||
|
// We would like guests to be able to set room colour but currently
|
||||||
|
// they can't, so we still send the request but display a sensible
|
||||||
|
// error if it fails.
|
||||||
return MatrixClientPeg.get().setRoomAccountData(
|
return MatrixClientPeg.get().setRoomAccountData(
|
||||||
this.props.room.roomId, "org.matrix.room.color_scheme", {
|
this.props.room.roomId, "org.matrix.room.color_scheme", {
|
||||||
primary_color: this.state.primary_color,
|
primary_color: this.state.primary_color,
|
||||||
secondary_color: this.state.secondary_color
|
secondary_color: this.state.secondary_color
|
||||||
}
|
}
|
||||||
);
|
).catch(function(err) {
|
||||||
|
if (err.errcode == 'M_GUEST_ACCESS_FORBIDDEN') {
|
||||||
|
var NeedToRegisterDialog = sdk.getComponent("dialogs.NeedToRegisterDialog");
|
||||||
|
Modal.createDialog(NeedToRegisterDialog, {
|
||||||
|
title: "Please Register",
|
||||||
|
description: "Saving room color settings is only available to registered users"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return q(); // no color diff
|
return q(); // no color diff
|
||||||
},
|
},
|
||||||
|
|
|
@ -170,11 +170,19 @@ module.exports = React.createClass({
|
||||||
// get out of sync if we force setState here!
|
// get out of sync if we force setState here!
|
||||||
console.log("Mod toggle success");
|
console.log("Mod toggle success");
|
||||||
}, function(err) {
|
}, function(err) {
|
||||||
|
if (err.errcode == 'M_GUEST_ACCESS_FORBIDDEN') {
|
||||||
|
var NeedToRegisterDialog = sdk.getComponent("dialogs.NeedToRegisterDialog");
|
||||||
|
Modal.createDialog(NeedToRegisterDialog, {
|
||||||
|
title: "Please Register",
|
||||||
|
description: "This action cannot be performed by a guest user. Please register to be able to do this."
|
||||||
|
});
|
||||||
|
} else {
|
||||||
Modal.createDialog(ErrorDialog, {
|
Modal.createDialog(ErrorDialog, {
|
||||||
title: "Mod error",
|
title: "Mod error",
|
||||||
description: err.message
|
description: err.message
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
);
|
);
|
||||||
this.props.onFinished();
|
this.props.onFinished();
|
||||||
},
|
},
|
||||||
|
@ -293,6 +301,16 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
self.setState({ creatingRoom: true });
|
self.setState({ creatingRoom: true });
|
||||||
|
|
||||||
|
if (MatrixClientPeg.get().isGuest()) {
|
||||||
|
var NeedToRegisterDialog = sdk.getComponent("dialogs.NeedToRegisterDialog");
|
||||||
|
Modal.createDialog(NeedToRegisterDialog, {
|
||||||
|
title: "Please Register",
|
||||||
|
description: "Guest users can't create new rooms. Please register to create room and start a chat."
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
MatrixClientPeg.get().createRoom({
|
MatrixClientPeg.get().createRoom({
|
||||||
// XXX: FIXME: deduplicate this with "view_create_room" in MatrixChat
|
// XXX: FIXME: deduplicate this with "view_create_room" in MatrixChat
|
||||||
invite: [this.props.member.userId],
|
invite: [this.props.member.userId],
|
||||||
|
|
|
@ -142,9 +142,18 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
onInvite: function(inputText) {
|
onInvite: function(inputText) {
|
||||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||||
|
var NeedToRegisterDialog = sdk.getComponent("dialogs.NeedToRegisterDialog");
|
||||||
var self = this;
|
var self = this;
|
||||||
inputText = inputText.trim(); // react requires es5-shim so we know trim() exists
|
inputText = inputText.trim(); // react requires es5-shim so we know trim() exists
|
||||||
|
|
||||||
|
if (MatrixClientPeg.get().isGuest()) {
|
||||||
|
Modal.createDialog(NeedToRegisterDialog, {
|
||||||
|
title: "Unable to Invite",
|
||||||
|
description: "Guest user can't invite new users. Please register to be able to invite new users into a room."
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// email addresses and user IDs do not allow space, comma, semicolon so split
|
// email addresses and user IDs do not allow space, comma, semicolon so split
|
||||||
// on them for bulk inviting.
|
// on them for bulk inviting.
|
||||||
var separators =[ ";", " ", "," ];
|
var separators =[ ";", " ", "," ];
|
||||||
|
@ -222,11 +231,18 @@ module.exports = React.createClass({
|
||||||
}, function(err) {
|
}, function(err) {
|
||||||
if (err !== null) {
|
if (err !== null) {
|
||||||
console.error("Failed to invite: %s", JSON.stringify(err));
|
console.error("Failed to invite: %s", JSON.stringify(err));
|
||||||
|
if (err.errcode == 'M_FORBIDDEN') {
|
||||||
|
Modal.createDialog(ErrorDialog, {
|
||||||
|
title: "Unable to Invite",
|
||||||
|
description: "You do not have permission to invite people to this room."
|
||||||
|
});
|
||||||
|
} else {
|
||||||
Modal.createDialog(ErrorDialog, {
|
Modal.createDialog(ErrorDialog, {
|
||||||
title: "Server error whilst inviting",
|
title: "Server error whilst inviting",
|
||||||
description: err.message
|
description: err.message
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}).finally(function() {
|
}).finally(function() {
|
||||||
self.setState({
|
self.setState({
|
||||||
inviting: false
|
inviting: false
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue