Skip to content

Commit

Permalink
Improve interaction modal error handling (mastodon#26795)
Browse files Browse the repository at this point in the history
  • Loading branch information
ClearlyClaire authored Sep 5, 2023
1 parent ea7de25 commit 548c032
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 7 deletions.
2 changes: 2 additions & 0 deletions app/controllers/api/v1/peers/search_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,7 @@ def set_domains
domain = TagManager.instance.normalize_domain(domain)
@domains = Instance.searchable.where(Instance.arel_table[:domain].matches("#{Instance.sanitize_sql_like(domain)}%", false, true)).limit(10).pluck(:domain)
end
rescue Addressable::URI::InvalidURIError
@domains = []
end
end
52 changes: 46 additions & 6 deletions app/javascript/mastodon/features/interaction_modal/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,41 @@ class LoginForm extends React.PureComponent {
this.input = c;
};

isValueValid = (value) => {
let likelyAcct = false;
let url = null;

if (value.startsWith('/')) {
return false;
}

if (value.startsWith('@')) {
value = value.slice(1);
likelyAcct = true;
}

// The user is in the middle of typing something, do not error out
if (value === '') {
return true;
}

if (/^https?:\/\//.test(value) && !likelyAcct) {
url = value;
} else {
url = `https://${value}`;
}

try {
new URL(url);
return true;
} catch(_) {
return false;
}
};

handleChange = ({ target }) => {
this.setState(state => ({ value: target.value, isLoading: true, error: false, options: addInputToOptions(target.value, state.networkOptions) }), () => this._loadOptions());
const error = !this.isValueValid(target.value);
this.setState(state => ({ error, value: target.value, isLoading: true, options: addInputToOptions(target.value, state.networkOptions) }), () => this._loadOptions());
};

handleMessage = (event) => {
Expand All @@ -115,11 +148,18 @@ class LoginForm extends React.PureComponent {
this.setState({ isSubmitting: false, error: true });
} else if (event.data?.type === 'fetchInteractionURL-success') {
if (/^https?:\/\//.test(event.data.template)) {
if (localStorage) {
localStorage.setItem(PERSISTENCE_KEY, event.data.uri_or_domain);
}
try {
const url = new URL(event.data.template.replace('{uri}', encodeURIComponent(resourceUrl)));

window.location.href = event.data.template.replace('{uri}', encodeURIComponent(resourceUrl));
if (localStorage) {
localStorage.setItem(PERSISTENCE_KEY, event.data.uri_or_domain);
}

window.location.href = url;
} catch (e) {
console.error(e);
this.setState({ isSubmitting: false, error: true });
}
} else {
this.setState({ isSubmitting: false, error: true });
}
Expand Down Expand Up @@ -259,7 +299,7 @@ class LoginForm extends React.PureComponent {
spellcheck='false'
/>

<Button onClick={this.handleSubmit} disabled={isSubmitting}><FormattedMessage id='interaction_modal.login.action' defaultMessage='Take me home' /></Button>
<Button onClick={this.handleSubmit} disabled={isSubmitting || error}><FormattedMessage id='interaction_modal.login.action' defaultMessage='Take me home' /></Button>
</div>

{hasPopOut && (
Expand Down
4 changes: 3 additions & 1 deletion app/javascript/packs/remote_interaction_helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,9 @@ const fromAcct = (acct: string) => {
};

const fetchInteractionURL = (uri_or_domain: string) => {
if (/^https?:\/\//.test(uri_or_domain)) {
if (uri_or_domain === '') {
fetchInteractionURLFailure();
} else if (/^https?:\/\//.test(uri_or_domain)) {
fromURL(uri_or_domain);
} else if (uri_or_domain.includes('@')) {
fromAcct(uri_or_domain);
Expand Down

0 comments on commit 548c032

Please sign in to comment.