Rephrase everything to be "invite anyways" rather than "retry"
Also handle profile errors betterpull/21833/head
parent
c351ee3d30
commit
a05c0f9214
|
@ -23,20 +23,20 @@ import SettingsStore from "../../../settings/SettingsStore";
|
||||||
|
|
||||||
export default React.createClass({
|
export default React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
failedInvites: PropTypes.object.isRequired, // { address: { errcode, errorText } }
|
unknownProfileUsers: PropTypes.array.isRequired, // [ {userId, errorText}... ]
|
||||||
onTryAgain: PropTypes.func.isRequired,
|
onInviteAnyways: PropTypes.func.isRequired,
|
||||||
onGiveUp: PropTypes.func.isRequired,
|
onGiveUp: PropTypes.func.isRequired,
|
||||||
onFinished: PropTypes.func.isRequired,
|
onFinished: PropTypes.func.isRequired,
|
||||||
},
|
},
|
||||||
|
|
||||||
_onTryAgainClicked: function() {
|
_onInviteClicked: function() {
|
||||||
this.props.onTryAgain();
|
this.props.onInviteAnyways();
|
||||||
this.props.onFinished(true);
|
this.props.onFinished(true);
|
||||||
},
|
},
|
||||||
|
|
||||||
_onTryAgainNeverWarnClicked: function() {
|
_onInviteNeverWarnClicked: function() {
|
||||||
SettingsStore.setValue("alwaysRetryInvites", null, SettingLevel.ACCOUNT, true);
|
SettingsStore.setValue("alwaysInviteUnknownUsers", null, SettingLevel.ACCOUNT, true);
|
||||||
this.props.onTryAgain();
|
this.props.onInviteAnyways();
|
||||||
this.props.onFinished(true);
|
this.props.onFinished(true);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -48,28 +48,31 @@ export default React.createClass({
|
||||||
render: function() {
|
render: function() {
|
||||||
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
|
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
|
||||||
|
|
||||||
const errorList = Object.keys(this.props.failedInvites)
|
const errorList = this.props.unknownProfileUsers
|
||||||
.map(address => <p key={address}>{address}: {this.props.failedInvites[address].errorText}</p>);
|
.map(address => <li key={address.userId}>{address.userId}: {address.errorText}</li>);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BaseDialog className='mx_RetryInvitesDialog'
|
<BaseDialog className='mx_RetryInvitesDialog'
|
||||||
onFinished={this._onGiveUpClicked}
|
onFinished={this._onGiveUpClicked}
|
||||||
title={_t('Failed to invite the following users')}
|
title={_t('The following users may not exist')}
|
||||||
contentId='mx_Dialog_content'
|
contentId='mx_Dialog_content'
|
||||||
>
|
>
|
||||||
<div id='mx_Dialog_content'>
|
<div id='mx_Dialog_content'>
|
||||||
{ errorList }
|
<p>{_t("The following users may not exist - would you like to invite them anyways?")}</p>
|
||||||
|
<ul>
|
||||||
|
{ errorList }
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mx_Dialog_buttons">
|
<div className="mx_Dialog_buttons">
|
||||||
<button onClick={this._onGiveUpClicked}>
|
<button onClick={this._onGiveUpClicked}>
|
||||||
{ _t('Close') }
|
{ _t('Close') }
|
||||||
</button>
|
</button>
|
||||||
<button onClick={this._onTryAgainNeverWarnClicked}>
|
<button onClick={this._onInviteNeverWarnClicked}>
|
||||||
{ _t('Try again and never warn me again') }
|
{ _t('Invite anyways and never warn me again') }
|
||||||
</button>
|
</button>
|
||||||
<button onClick={this._onTryAgainClicked} autoFocus="true">
|
<button onClick={this._onInviteClicked} autoFocus="true">
|
||||||
{ _t('Try again') }
|
{ _t('Invite anyways') }
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</BaseDialog>
|
</BaseDialog>
|
|
@ -293,7 +293,7 @@
|
||||||
"Pin unread rooms to the top of the room list": "Pin unread rooms to the top of the room list",
|
"Pin unread rooms to the top of the room list": "Pin unread rooms to the top of the room list",
|
||||||
"Enable widget screenshots on supported widgets": "Enable widget screenshots on supported widgets",
|
"Enable widget screenshots on supported widgets": "Enable widget screenshots on supported widgets",
|
||||||
"Show empty room list headings": "Show empty room list headings",
|
"Show empty room list headings": "Show empty room list headings",
|
||||||
"Always retry invites for unknown users": "Always retry invites for unknown users",
|
"Always invite users which may not exist": "Always invite users which may not exist",
|
||||||
"Show developer tools": "Show developer tools",
|
"Show developer tools": "Show developer tools",
|
||||||
"Collecting app version information": "Collecting app version information",
|
"Collecting app version information": "Collecting app version information",
|
||||||
"Collecting logs": "Collecting logs",
|
"Collecting logs": "Collecting logs",
|
||||||
|
@ -884,6 +884,10 @@
|
||||||
"That doesn't look like a valid email address": "That doesn't look like a valid email address",
|
"That doesn't look like a valid email address": "That doesn't look like a valid email address",
|
||||||
"You have entered an invalid address.": "You have entered an invalid address.",
|
"You have entered an invalid address.": "You have entered an invalid address.",
|
||||||
"Try using one of the following valid address types: %(validTypesList)s.": "Try using one of the following valid address types: %(validTypesList)s.",
|
"Try using one of the following valid address types: %(validTypesList)s.": "Try using one of the following valid address types: %(validTypesList)s.",
|
||||||
|
"The following users may not exist": "The following users may not exist",
|
||||||
|
"The following users may not exist - would you like to invite them anyways?": "The following users may not exist - would you like to invite them anyways?",
|
||||||
|
"Invite anyways and never warn me again": "Invite anyways and never warn me again",
|
||||||
|
"Invite anyways": "Invite anyways",
|
||||||
"Preparing to send logs": "Preparing to send logs",
|
"Preparing to send logs": "Preparing to send logs",
|
||||||
"Logs sent": "Logs sent",
|
"Logs sent": "Logs sent",
|
||||||
"Thank you!": "Thank you!",
|
"Thank you!": "Thank you!",
|
||||||
|
@ -968,9 +972,6 @@
|
||||||
"Clear cache and resync": "Clear cache and resync",
|
"Clear cache and resync": "Clear cache and resync",
|
||||||
"Riot now uses 3-5x less memory, by only loading information about other users when needed. Please wait whilst we resynchronise with the server!": "Riot now uses 3-5x less memory, by only loading information about other users when needed. Please wait whilst we resynchronise with the server!",
|
"Riot now uses 3-5x less memory, by only loading information about other users when needed. Please wait whilst we resynchronise with the server!": "Riot now uses 3-5x less memory, by only loading information about other users when needed. Please wait whilst we resynchronise with the server!",
|
||||||
"Updating Riot": "Updating Riot",
|
"Updating Riot": "Updating Riot",
|
||||||
"Failed to invite the following users": "Failed to invite the following users",
|
|
||||||
"Try again and never warn me again": "Try again and never warn me again",
|
|
||||||
"Try again": "Try again",
|
|
||||||
"Failed to upgrade room": "Failed to upgrade room",
|
"Failed to upgrade room": "Failed to upgrade room",
|
||||||
"The room upgrade could not be completed": "The room upgrade could not be completed",
|
"The room upgrade could not be completed": "The room upgrade could not be completed",
|
||||||
"Upgrade this room to version %(version)s": "Upgrade this room to version %(version)s",
|
"Upgrade this room to version %(version)s": "Upgrade this room to version %(version)s",
|
||||||
|
|
|
@ -317,9 +317,9 @@ export const SETTINGS = {
|
||||||
displayName: _td('Show empty room list headings'),
|
displayName: _td('Show empty room list headings'),
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
"alwaysRetryInvites": {
|
"alwaysInviteUnknownUsers": {
|
||||||
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
|
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
|
||||||
displayName: _td('Always retry invites for unknown users'),
|
displayName: _td('Always invite users which may not exist'),
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
"showDeveloperTools": {
|
"showDeveloperTools": {
|
||||||
|
|
|
@ -101,13 +101,18 @@ export default class MultiInviter {
|
||||||
if (addrType === 'email') {
|
if (addrType === 'email') {
|
||||||
return MatrixClientPeg.get().inviteByEmail(roomId, addr);
|
return MatrixClientPeg.get().inviteByEmail(roomId, addr);
|
||||||
} else if (addrType === 'mx-user-id') {
|
} else if (addrType === 'mx-user-id') {
|
||||||
if (!ignoreProfile && !SettingsStore.getValue("alwaysRetryInvites", this.roomId)) {
|
if (!ignoreProfile && !SettingsStore.getValue("alwaysInviteUnknownUsers", this.roomId)) {
|
||||||
const profile = await MatrixClientPeg.get().getProfileInfo(addr);
|
try {
|
||||||
if (!profile) {
|
const profile = await MatrixClientPeg.get().getProfileInfo(addr);
|
||||||
return Promise.reject({
|
if (!profile) {
|
||||||
errcode: "M_NOT_FOUND",
|
// noinspection ExceptionCaughtLocallyJS
|
||||||
error: "User does not have a profile or does not exist.",
|
throw new Error("User has no profile");
|
||||||
});
|
}
|
||||||
|
} catch (e) {
|
||||||
|
throw {
|
||||||
|
errcode: "RIOT.USER_NOT_FOUND",
|
||||||
|
error: "User does not have a profile or does not exist."
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,6 +124,8 @@ export default class MultiInviter {
|
||||||
|
|
||||||
_doInvite(address, ignoreProfile) {
|
_doInvite(address, ignoreProfile) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
console.log(`Inviting ${address}`);
|
||||||
|
|
||||||
let doInvite;
|
let doInvite;
|
||||||
if (this.groupId !== null) {
|
if (this.groupId !== null) {
|
||||||
doInvite = GroupStore.inviteUserToGroup(this.groupId, address);
|
doInvite = GroupStore.inviteUserToGroup(this.groupId, address);
|
||||||
|
@ -151,13 +158,13 @@ export default class MultiInviter {
|
||||||
this._doInvite(address, ignoreProfile).then(resolve, reject);
|
this._doInvite(address, ignoreProfile).then(resolve, reject);
|
||||||
}, 5000);
|
}, 5000);
|
||||||
return;
|
return;
|
||||||
} else if (['M_NOT_FOUND', 'M_USER_NOT_FOUND'].includes(err.errcode)) {
|
} else if (['M_NOT_FOUND', 'M_USER_NOT_FOUND', 'RIOT.USER_NOT_FOUND'].includes(err.errcode)) {
|
||||||
errorText = _t("User %(user_id)s does not exist", {user_id: address});
|
errorText = _t("User %(user_id)s does not exist", {user_id: address});
|
||||||
} else if (err.errcode === 'M_PROFILE_UNKNOWN') {
|
} else if (err.errcode === 'M_PROFILE_UNDISCLOSED') {
|
||||||
errorText = _t("User %(user_id)s may or may not exist", {user_id: address});
|
errorText = _t("User %(user_id)s may or may not exist", {user_id: address});
|
||||||
} else if (err.errcode === 'M_PROFILE_NOT_FOUND' && !ignoreProfile) {
|
} else if (err.errcode === 'M_PROFILE_NOT_FOUND' && !ignoreProfile) {
|
||||||
// Invite without the profile check
|
// Invite without the profile check
|
||||||
console.warn(`User ${address} does not have a profile - trying invite again`);
|
console.warn(`User ${address} does not have a profile - inviting anyways automatically`);
|
||||||
this._doInvite(address, true).then(resolve, reject);
|
this._doInvite(address, true).then(resolve, reject);
|
||||||
} else {
|
} else {
|
||||||
errorText = _t('Unknown server error');
|
errorText = _t('Unknown server error');
|
||||||
|
@ -188,28 +195,28 @@ export default class MultiInviter {
|
||||||
if (Object.keys(this.errors).length > 0 && !this.groupId) {
|
if (Object.keys(this.errors).length > 0 && !this.groupId) {
|
||||||
// There were problems inviting some people - see if we can invite them
|
// There were problems inviting some people - see if we can invite them
|
||||||
// without caring if they exist or not.
|
// without caring if they exist or not.
|
||||||
const reinviteErrors = ['M_NOT_FOUND', 'M_USER_NOT_FOUND', 'M_PROFILE_UNKNOWN', 'M_PROFILE_NOT_FOUND'];
|
const unknownProfileErrors = ['M_NOT_FOUND', 'M_USER_NOT_FOUND', 'M_PROFILE_UNDISCLOSED', 'M_PROFILE_NOT_FOUND', 'RIOT.USER_NOT_FOUND'];
|
||||||
const reinvitableUsers = Object.keys(this.errors).filter(a => reinviteErrors.includes(this.errors[a].errcode));
|
const unknownProfileUsers = Object.keys(this.errors).filter(a => unknownProfileErrors.includes(this.errors[a].errcode));
|
||||||
|
|
||||||
if (reinvitableUsers.length > 0) {
|
if (unknownProfileUsers.length > 0) {
|
||||||
const retryInvites = () => {
|
const inviteUnknowns = () => {
|
||||||
const promises = reinvitableUsers.map(u => this._doInvite(u, true));
|
const promises = unknownProfileUsers.map(u => this._doInvite(u, true));
|
||||||
Promise.all(promises).then(() => this.deferred.resolve(this.completionStates));
|
Promise.all(promises).then(() => this.deferred.resolve(this.completionStates));
|
||||||
};
|
};
|
||||||
|
|
||||||
if (SettingsStore.getValue("alwaysRetryInvites", this.roomId)) {
|
if (SettingsStore.getValue("alwaysInviteUnknownUsers", this.roomId)) {
|
||||||
retryInvites();
|
inviteUnknowns();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const RetryInvitesDialog = sdk.getComponent("dialogs.RetryInvitesDialog");
|
const AskInviteAnywayDialog = sdk.getComponent("dialogs.AskInviteAnywayDialog");
|
||||||
console.log("Showing failed to invite dialog...");
|
console.log("Showing failed to invite dialog...");
|
||||||
Modal.createTrackedDialog('Failed to invite the following users to the room', '', RetryInvitesDialog, {
|
Modal.createTrackedDialog('Failed to invite the following users to the room', '', AskInviteAnywayDialog, {
|
||||||
failedInvites: this.errors,
|
unknownProfileUsers: unknownProfileUsers.map(u => {return {userId: u, errorText: this.errors[u].errorText};}),
|
||||||
onTryAgain: () => retryInvites(),
|
onInviteAnyways: () => inviteUnknowns(),
|
||||||
onGiveUp: () => {
|
onGiveUp: () => {
|
||||||
// Fake all the completion states because we already warned the user
|
// Fake all the completion states because we already warned the user
|
||||||
for (const addr of Object.keys(this.completionStates)) {
|
for (const addr of unknownProfileUsers) {
|
||||||
this.completionStates[addr] = 'invited';
|
this.completionStates[addr] = 'invited';
|
||||||
}
|
}
|
||||||
this.deferred.resolve(this.completionStates);
|
this.deferred.resolve(this.completionStates);
|
||||||
|
@ -223,7 +230,6 @@ export default class MultiInviter {
|
||||||
}
|
}
|
||||||
|
|
||||||
const addr = this.addrs[nextIndex];
|
const addr = this.addrs[nextIndex];
|
||||||
console.log(`Inviting ${addr}`);
|
|
||||||
|
|
||||||
// don't try to invite it if it's an invalid address
|
// don't try to invite it if it's an invalid address
|
||||||
// (it will already be marked as an error though,
|
// (it will already be marked as an error though,
|
||||||
|
|
Loading…
Reference in New Issue