diff --git a/.eslintrc.js b/.eslintrc.js
index 164949e65..0ecb15a5b 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -277,6 +277,7 @@ module.exports = {
files: ['**/*.ts', '**/*.tsx'],
rules: {
'no-undef': 'off', // https://stackoverflow.com/a/69155899
+ 'space-before-function-paren': 'off',
},
parser: '@typescript-eslint/parser',
},
diff --git a/app/soapbox/__fixtures__/truthsocial-status-in-moderation.json b/app/soapbox/__fixtures__/truthsocial-status-in-moderation.json
index e9402876f..7613ebd93 100644
--- a/app/soapbox/__fixtures__/truthsocial-status-in-moderation.json
+++ b/app/soapbox/__fixtures__/truthsocial-status-in-moderation.json
@@ -82,4 +82,4 @@
"emojis": [],
"card": null,
"poll": null
-}
+}
\ No newline at end of file
diff --git a/app/soapbox/actions/auth.ts b/app/soapbox/actions/auth.ts
index d3252e7fb..5a686d045 100644
--- a/app/soapbox/actions/auth.ts
+++ b/app/soapbox/actions/auth.ts
@@ -20,6 +20,7 @@ import KVStore from 'soapbox/storage/kv_store';
import { getLoggedInAccount, parseBaseURL } from 'soapbox/utils/auth';
import sourceCode from 'soapbox/utils/code';
import { getFeatures } from 'soapbox/utils/features';
+import { normalizeUsername } from 'soapbox/utils/input';
import { isStandalone } from 'soapbox/utils/state';
import api, { baseClient } from '../api';
@@ -207,16 +208,6 @@ export const loadCredentials = (token: string, accountUrl: string) =>
})
.catch(() => dispatch(verifyCredentials(token, accountUrl)));
-/** Trim the username and strip the leading @. */
-const normalizeUsername = (username: string): string => {
- const trimmed = username.trim();
- if (trimmed[0] === '@') {
- return trimmed.slice(1);
- } else {
- return trimmed;
- }
-};
-
export const logIn = (username: string, password: string) =>
(dispatch: AppDispatch) => dispatch(getAuthApp()).then(() => {
return dispatch(createUserToken(normalizeUsername(username), password));
diff --git a/app/soapbox/actions/compose.ts b/app/soapbox/actions/compose.ts
index df519fe6c..0859199b1 100644
--- a/app/soapbox/actions/compose.ts
+++ b/app/soapbox/actions/compose.ts
@@ -323,11 +323,13 @@ const uploadCompose = (composeId: string, files: FileList, intl: IntlShape) =>
const maxVideoSize = getState().instance.configuration.getIn(['media_attachments', 'video_size_limit']) as number | undefined;
const maxVideoDuration = getState().instance.configuration.getIn(['media_attachments', 'video_duration_limit']) as number | undefined;
- const media = getState().compose.get(composeId)!.media_attachments;
+ const media = getState().compose.get(composeId)?.media_attachments;
const progress = new Array(files.length).fill(0);
let total = Array.from(files).reduce((a, v) => a + v.size, 0);
- if (files.length + media.size > attachmentLimit) {
+ const mediaCount = media ? media.size : 0;
+
+ if (files.length + mediaCount > attachmentLimit) {
dispatch(showAlert(undefined, messages.uploadErrorLimit, 'error'));
return;
}
@@ -335,7 +337,7 @@ const uploadCompose = (composeId: string, files: FileList, intl: IntlShape) =>
dispatch(uploadComposeRequest(composeId));
Array.from(files).forEach(async(f, i) => {
- if (media.size + i > attachmentLimit - 1) return;
+ if (mediaCount + i > attachmentLimit - 1) return;
const isImage = f.type.match(/image.*/);
const isVideo = f.type.match(/video.*/);
diff --git a/app/soapbox/actions/moderation.tsx b/app/soapbox/actions/moderation.tsx
index ea5861eca..bf0ccf332 100644
--- a/app/soapbox/actions/moderation.tsx
+++ b/app/soapbox/actions/moderation.tsx
@@ -5,6 +5,8 @@ import { fetchAccountByUsername } from 'soapbox/actions/accounts';
import { deactivateUsers, deleteUsers, deleteStatus, toggleStatusSensitivity } from 'soapbox/actions/admin';
import { openModal } from 'soapbox/actions/modals';
import snackbar from 'soapbox/actions/snackbar';
+import OutlineBox from 'soapbox/components/outline-box';
+import { Stack, Text } from 'soapbox/components/ui';
import AccountContainer from 'soapbox/containers/account_container';
import { isLocal } from 'soapbox/utils/accounts';
@@ -43,10 +45,22 @@ const deactivateUserModal = (intl: IntlShape, accountId: string, afterConfirm =
const acct = state.accounts.get(accountId)!.acct;
const name = state.accounts.get(accountId)!.username;
+ const message = (
+
+
+
+
+
+
+ {intl.formatMessage(messages.deactivateUserPrompt, { acct })}
+
+
+ );
+
dispatch(openModal('CONFIRM', {
icon: require('@tabler/icons/user-off.svg'),
heading: intl.formatMessage(messages.deactivateUserHeading, { acct }),
- message: intl.formatMessage(messages.deactivateUserPrompt, { acct }),
+ message,
confirm: intl.formatMessage(messages.deactivateUserConfirm, { name }),
onConfirm: () => {
dispatch(deactivateUsers([accountId])).then(() => {
@@ -64,22 +78,21 @@ const deleteUserModal = (intl: IntlShape, accountId: string, afterConfirm = () =
const account = state.accounts.get(accountId)!;
const acct = account.acct;
const name = account.username;
- const favicon = account.pleroma.get('favicon');
const local = isLocal(account);
- const message = (<>
-
- {intl.formatMessage(messages.deleteUserPrompt, { acct })}
- >);
+ const message = (
+
+
+
+
- const confirm = (<>
- {favicon &&
-
-

-
}
- {intl.formatMessage(messages.deleteUserConfirm, { name })}
- >);
+
+ {intl.formatMessage(messages.deleteUserPrompt, { acct })}
+
+
+ );
+ const confirm = intl.formatMessage(messages.deleteUserConfirm, { name });
const checkbox = local ? intl.formatMessage(messages.deleteLocalUserCheckbox) : false;
dispatch(openModal('CONFIRM', {
diff --git a/app/soapbox/actions/security.ts b/app/soapbox/actions/security.ts
index 430691a06..196e54dcb 100644
--- a/app/soapbox/actions/security.ts
+++ b/app/soapbox/actions/security.ts
@@ -7,6 +7,7 @@
import snackbar from 'soapbox/actions/snackbar';
import { getLoggedInAccount } from 'soapbox/utils/auth';
import { parseVersion, TRUTHSOCIAL } from 'soapbox/utils/features';
+import { normalizeUsername } from 'soapbox/utils/input';
import api from '../api';
@@ -84,15 +85,16 @@ const changePassword = (oldPassword: string, newPassword: string, confirmation:
const resetPassword = (usernameOrEmail: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
+ const input = normalizeUsername(usernameOrEmail);
const state = getState();
const v = parseVersion(state.instance.version);
dispatch({ type: RESET_PASSWORD_REQUEST });
const params =
- usernameOrEmail.includes('@')
- ? { email: usernameOrEmail }
- : { nickname: usernameOrEmail, username: usernameOrEmail };
+ input.includes('@')
+ ? { email: input }
+ : { nickname: input, username: input };
const endpoint =
v.software === TRUTHSOCIAL
diff --git a/app/soapbox/components/media_gallery.js b/app/soapbox/components/media_gallery.js
index f8e9dc51e..7bbbbd5b7 100644
--- a/app/soapbox/components/media_gallery.js
+++ b/app/soapbox/components/media_gallery.js
@@ -7,7 +7,6 @@ import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import { connect } from 'react-redux';
import { getSettings } from 'soapbox/actions/settings';
-import { getSoapboxConfig } from 'soapbox/actions/soapbox';
import Blurhash from 'soapbox/components/blurhash';
import Icon from 'soapbox/components/icon';
import StillImage from 'soapbox/components/still_image';
@@ -264,14 +263,9 @@ class Item extends React.PureComponent {
}
-const mapStateToMediaGalleryProps = state => {
- const { links } = getSoapboxConfig(state);
-
- return {
- displayMedia: getSettings(state).get('displayMedia'),
- links,
- };
-};
+const mapStateToMediaGalleryProps = state => ({
+ displayMedia: getSettings(state).get('displayMedia'),
+});
export default @connect(mapStateToMediaGalleryProps)
@injectIntl
@@ -291,7 +285,6 @@ class MediaGallery extends React.PureComponent {
onToggleVisibility: PropTypes.func,
displayMedia: PropTypes.string,
compact: PropTypes.bool,
- links: ImmutablePropTypes.map,
};
static defaultProps = {
@@ -575,7 +568,7 @@ class MediaGallery extends React.PureComponent {
}
render() {
- const { media, intl, sensitive, compact, inReview, links } = this.props;
+ const { media, intl, sensitive, compact } = this.props;
const { visible } = this.state;
const sizeData = this.getSizeData(media.size);
@@ -594,22 +587,14 @@ class MediaGallery extends React.PureComponent {
/>
));
- let warning, summary;
+ let warning;
if (sensitive) {
warning = ;
- } else if (inReview) {
- warning = ;
} else {
warning = ;
}
- if (inReview) {
- summary = ;
- } else {
- summary = ;
- }
-
return (
- {(sensitive || inReview) && (
+ {sensitive && (
(visible || compact) ? (