From 98ff406ddf444421cc4d018dbf01ca3b87943bbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Sun, 10 Apr 2022 12:46:25 +0200 Subject: [PATCH] typescript MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- .../components/autosuggest_textarea.js | 4 +- .../compose/components/autosuggest_account.js | 20 ------- .../components/autosuggest_account.tsx | 21 +++++++ .../compose/components/compose_form.js | 4 +- .../components/text_character_counter.js | 31 ---------- .../components/text_character_counter.tsx | 28 +++++++++ .../compose/components/upload_form.js | 37 ------------ .../compose/components/upload_form.tsx | 33 +++++++++++ .../components/visual_character_counter.js | 43 -------------- .../components/visual_character_counter.tsx | 35 +++++++++++ .../autosuggest_account_container.js | 16 ----- .../containers/upload_form_container.js | 9 --- .../compose/util/{counter.js => counter.ts} | 2 +- .../util/{url_regex.js => url_regex.ts} | 7 +-- .../generic_not_found/{index.js => index.tsx} | 0 .../features/ui/components/accordion.js | 59 ------------------- .../features/ui/components/accordion.tsx | 52 ++++++++++++++++ 17 files changed, 177 insertions(+), 224 deletions(-) delete mode 100644 app/soapbox/features/compose/components/autosuggest_account.js create mode 100644 app/soapbox/features/compose/components/autosuggest_account.tsx delete mode 100644 app/soapbox/features/compose/components/text_character_counter.js create mode 100644 app/soapbox/features/compose/components/text_character_counter.tsx delete mode 100644 app/soapbox/features/compose/components/upload_form.js create mode 100644 app/soapbox/features/compose/components/upload_form.tsx delete mode 100644 app/soapbox/features/compose/components/visual_character_counter.js create mode 100644 app/soapbox/features/compose/components/visual_character_counter.tsx delete mode 100644 app/soapbox/features/compose/containers/autosuggest_account_container.js delete mode 100644 app/soapbox/features/compose/containers/upload_form_container.js rename app/soapbox/features/compose/util/{counter.js => counter.ts} (81%) rename app/soapbox/features/compose/util/{url_regex.js => url_regex.ts} (98%) rename app/soapbox/features/generic_not_found/{index.js => index.tsx} (100%) delete mode 100644 app/soapbox/features/ui/components/accordion.js create mode 100644 app/soapbox/features/ui/components/accordion.tsx diff --git a/app/soapbox/components/autosuggest_textarea.js b/app/soapbox/components/autosuggest_textarea.js index 9b5d186f5..69ec5d7a1 100644 --- a/app/soapbox/components/autosuggest_textarea.js +++ b/app/soapbox/components/autosuggest_textarea.js @@ -6,7 +6,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePureComponent from 'react-immutable-pure-component'; import Textarea from 'react-textarea-autosize'; -import AutosuggestAccountContainer from '../features/compose/containers/autosuggest_account_container'; +import AutosuggestAccount from '../features/compose/components/autosuggest_account'; import { isRtl } from '../rtl'; import AutosuggestEmoji from './autosuggest_emoji'; @@ -205,7 +205,7 @@ export default class AutosuggestTextarea extends ImmutablePureComponent { inner = suggestion; key = suggestion; } else { - inner = ; + inner = ; key = suggestion; } diff --git a/app/soapbox/features/compose/components/autosuggest_account.js b/app/soapbox/features/compose/components/autosuggest_account.js deleted file mode 100644 index 9cb997835..000000000 --- a/app/soapbox/features/compose/components/autosuggest_account.js +++ /dev/null @@ -1,20 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { useSelector } from 'react-redux'; - -import Account from '../../../components/account'; -import { makeGetAccount } from '../../../selectors'; - -const AutosuggestAccount = ({ id }) => { - const getAccount = makeGetAccount(); - const account = useSelector((state) => getAccount(state, id)); - - return ; - -}; - -AutosuggestAccount.propTypes = { - id: PropTypes.number.isRequired, -}; - -export default AutosuggestAccount; diff --git a/app/soapbox/features/compose/components/autosuggest_account.tsx b/app/soapbox/features/compose/components/autosuggest_account.tsx new file mode 100644 index 000000000..6b65f8341 --- /dev/null +++ b/app/soapbox/features/compose/components/autosuggest_account.tsx @@ -0,0 +1,21 @@ +import React from 'react'; + +import Account from 'soapbox/components/account'; +import { useAppSelector } from 'soapbox/hooks'; +import { makeGetAccount } from 'soapbox/selectors'; + +interface IAutosuggestAccount { + id: string, +} + +const AutosuggestAccount: React.FC = ({ id }) => { + const getAccount = makeGetAccount(); + const account = useAppSelector((state) => getAccount(state, id)); + + if (!account) return null; + + return ; + +}; + +export default AutosuggestAccount; diff --git a/app/soapbox/features/compose/components/compose_form.js b/app/soapbox/features/compose/components/compose_form.js index 1c17c5ae1..675abe4bf 100644 --- a/app/soapbox/features/compose/components/compose_form.js +++ b/app/soapbox/features/compose/components/compose_form.js @@ -15,6 +15,7 @@ import AutosuggestTextarea from '../../../components/autosuggest_textarea'; import { Button } from '../../../components/ui'; import { isMobile } from '../../../is_mobile'; import ReplyMentions from '../components/reply_mentions'; +import UploadForm from '../components/upload_form'; import Warning from '../components/warning'; import EmojiPickerDropdown from '../containers/emoji_picker_dropdown_container'; import MarkdownButtonContainer from '../containers/markdown_button_container'; @@ -27,7 +28,6 @@ import ScheduleButtonContainer from '../containers/schedule_button_container'; import ScheduleFormContainer from '../containers/schedule_form_container'; import SpoilerButtonContainer from '../containers/spoiler_button_container'; import UploadButtonContainer from '../containers/upload_button_container'; -import UploadFormContainer from '../containers/upload_form_container'; import WarningContainer from '../containers/warning_container'; import { countableText } from '../util/counter'; @@ -354,7 +354,7 @@ class ComposeForm extends ImmutablePureComponent { { !condensed &&
- +
diff --git a/app/soapbox/features/compose/components/text_character_counter.js b/app/soapbox/features/compose/components/text_character_counter.js deleted file mode 100644 index 08eec99fe..000000000 --- a/app/soapbox/features/compose/components/text_character_counter.js +++ /dev/null @@ -1,31 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import React from 'react'; -import { length } from 'stringz'; - -export default class TextCharacterCounter extends React.PureComponent { - - static propTypes = { - text: PropTypes.string.isRequired, - max: PropTypes.number.isRequired, - }; - - checkRemainingText(diff) { - return ( - = 0, - 'text-danger-600': diff < 0, - })} - > - {diff} - - ); - } - - render() { - const diff = this.props.max - length(this.props.text); - return this.checkRemainingText(diff); - } - -} diff --git a/app/soapbox/features/compose/components/text_character_counter.tsx b/app/soapbox/features/compose/components/text_character_counter.tsx new file mode 100644 index 000000000..823d24f6f --- /dev/null +++ b/app/soapbox/features/compose/components/text_character_counter.tsx @@ -0,0 +1,28 @@ +import classNames from 'classnames'; +import React from 'react'; +import { length } from 'stringz'; + +interface ITextCharacterCounter { + max: number, + text: string, +} + +const TextCharacterCounter: React.FC = ({ text, max }) => { + const checkRemainingText = (diff: number) => { + return ( + = 0, + 'text-danger-600': diff < 0, + })} + > + {diff} + + ); + }; + + const diff = max - length(text); + return checkRemainingText(diff); +}; + +export default TextCharacterCounter; diff --git a/app/soapbox/features/compose/components/upload_form.js b/app/soapbox/features/compose/components/upload_form.js deleted file mode 100644 index 71e89517a..000000000 --- a/app/soapbox/features/compose/components/upload_form.js +++ /dev/null @@ -1,37 +0,0 @@ -import classNames from 'classnames'; -import React from 'react'; -import ImmutablePropTypes from 'react-immutable-proptypes'; -import ImmutablePureComponent from 'react-immutable-pure-component'; - -// import SensitiveButtonContainer from '../containers/sensitive_button_container'; -import UploadProgress from '../components/upload-progress'; -import UploadContainer from '../containers/upload_container'; - -export default class UploadForm extends ImmutablePureComponent { - - static propTypes = { - mediaIds: ImmutablePropTypes.list.isRequired, - }; - - render() { - const { mediaIds } = this.props; - const classes = classNames('compose-form__uploads-wrapper', { - 'contains-media': mediaIds.size !== 0, - }); - - return ( -
- - -
- {mediaIds.map(id => ( - - ))} -
- - {/* {!mediaIds.isEmpty() && } */} -
- ); - } - -} diff --git a/app/soapbox/features/compose/components/upload_form.tsx b/app/soapbox/features/compose/components/upload_form.tsx new file mode 100644 index 000000000..4ab98f3a8 --- /dev/null +++ b/app/soapbox/features/compose/components/upload_form.tsx @@ -0,0 +1,33 @@ +import classNames from 'classnames'; +import React from 'react'; + +import { useAppSelector } from 'soapbox/hooks'; + +import type { Attachment as AttachmentEntity } from 'soapbox/types/entities'; + +// import SensitiveButtonContainer from '../containers/sensitive_button_container'; +import UploadProgress from '../components/upload-progress'; +import UploadContainer from '../containers/upload_container'; + +const UploadForm = () => { + const mediaIds = useAppSelector((state) => state.compose.get('media_attachments').map((item: AttachmentEntity) => item.get('id'))); + const classes = classNames('compose-form__uploads-wrapper', { + 'contains-media': mediaIds.size !== 0, + }); + + return ( +
+ + +
+ {mediaIds.map((id: string) => ( + + ))} +
+ + {/* {!mediaIds.isEmpty() && } */} +
+ ); +}; + +export default UploadForm; diff --git a/app/soapbox/features/compose/components/visual_character_counter.js b/app/soapbox/features/compose/components/visual_character_counter.js deleted file mode 100644 index b90ba668d..000000000 --- a/app/soapbox/features/compose/components/visual_character_counter.js +++ /dev/null @@ -1,43 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { injectIntl, defineMessages } from 'react-intl'; -import { length } from 'stringz'; - -import ProgressCircle from 'soapbox/components/progress_circle'; - -const messages = defineMessages({ - title: { id: 'compose.character_counter.title', defaultMessage: 'Used {chars} out of {maxChars} characters' }, -}); - -/** - * Renders a character counter - * @param {string} props.text - text to use to measure - * @param {number} props.max - max text allowed - */ -class VisualCharacterCounter extends React.PureComponent { - - render() { - const { intl, text, max } = this.props; - - const textLength = length(text); - const progress = textLength / max; - - return ( - - ); - } - -} - -VisualCharacterCounter.propTypes = { - intl: PropTypes.object.isRequired, - text: PropTypes.string.isRequired, - max: PropTypes.number.isRequired, -}; - -export default injectIntl(VisualCharacterCounter); diff --git a/app/soapbox/features/compose/components/visual_character_counter.tsx b/app/soapbox/features/compose/components/visual_character_counter.tsx new file mode 100644 index 000000000..bba7053e8 --- /dev/null +++ b/app/soapbox/features/compose/components/visual_character_counter.tsx @@ -0,0 +1,35 @@ +import React from 'react'; +import { defineMessages, useIntl } from 'react-intl'; +import { length } from 'stringz'; + +import ProgressCircle from 'soapbox/components/progress_circle'; + +const messages = defineMessages({ + title: { id: 'compose.character_counter.title', defaultMessage: 'Used {chars} out of {maxChars} characters' }, +}); + +interface IVisualCharacterCounter { + /** max text allowed */ + max: number, + /** text to use to measure */ + text: string, +} + +/** Renders a character counter */ +const VisualCharacterCounter: React.FC = ({ text, max }) => { + const intl = useIntl(); + + const textLength = length(text); + const progress = textLength / max; + + return ( + + ); +}; + +export default VisualCharacterCounter; diff --git a/app/soapbox/features/compose/containers/autosuggest_account_container.js b/app/soapbox/features/compose/containers/autosuggest_account_container.js deleted file mode 100644 index f86f01bd9..000000000 --- a/app/soapbox/features/compose/containers/autosuggest_account_container.js +++ /dev/null @@ -1,16 +0,0 @@ -import { connect } from 'react-redux'; - -import { makeGetAccount } from '../../../selectors'; -import AutosuggestAccount from '../components/autosuggest_account'; - -const makeMapStateToProps = () => { - const getAccount = makeGetAccount(); - - const mapStateToProps = (state, { id }) => ({ - account: getAccount(state, id), - }); - - return mapStateToProps; -}; - -export default connect(makeMapStateToProps)(AutosuggestAccount); diff --git a/app/soapbox/features/compose/containers/upload_form_container.js b/app/soapbox/features/compose/containers/upload_form_container.js deleted file mode 100644 index 336525cf5..000000000 --- a/app/soapbox/features/compose/containers/upload_form_container.js +++ /dev/null @@ -1,9 +0,0 @@ -import { connect } from 'react-redux'; - -import UploadForm from '../components/upload_form'; - -const mapStateToProps = state => ({ - mediaIds: state.getIn(['compose', 'media_attachments']).map(item => item.get('id')), -}); - -export default connect(mapStateToProps)(UploadForm); diff --git a/app/soapbox/features/compose/util/counter.js b/app/soapbox/features/compose/util/counter.ts similarity index 81% rename from app/soapbox/features/compose/util/counter.js rename to app/soapbox/features/compose/util/counter.ts index 95dc34a20..0ae62a598 100644 --- a/app/soapbox/features/compose/util/counter.js +++ b/app/soapbox/features/compose/util/counter.ts @@ -2,7 +2,7 @@ import { urlRegex } from './url_regex'; const urlPlaceholder = 'xxxxxxxxxxxxxxxxxxxxxxx'; -export function countableText(inputText) { +export function countableText(inputText: string) { return inputText .replace(urlRegex, urlPlaceholder) .replace(/(^|[^\/\w])@(([a-z0-9_]+)@[a-z0-9\.\-]+[a-z0-9]+)/ig, '$1@$3'); diff --git a/app/soapbox/features/compose/util/url_regex.js b/app/soapbox/features/compose/util/url_regex.ts similarity index 98% rename from app/soapbox/features/compose/util/url_regex.js rename to app/soapbox/features/compose/util/url_regex.ts index 4ac11ca05..302519662 100644 --- a/app/soapbox/features/compose/util/url_regex.js +++ b/app/soapbox/features/compose/util/url_regex.ts @@ -1,7 +1,6 @@ -const regexen = {}; +const regexen: { [x: string]: string | RegExp } = {}; -const regexSupplant = function(regex, flags) { - flags = flags || ''; +const regexSupplant = function(regex: string | RegExp, flags = '') { if (typeof regex !== 'string') { if (regex.global && flags.indexOf('g') < 0) { flags += 'g'; @@ -24,7 +23,7 @@ const regexSupplant = function(regex, flags) { }), flags); }; -const stringSupplant = function(str, values) { +const stringSupplant = function(str: string, values: { [x: string]: any; }) { return str.replace(/#\{(\w+)\}/g, function(match, name) { return values[name] || ''; }); diff --git a/app/soapbox/features/generic_not_found/index.js b/app/soapbox/features/generic_not_found/index.tsx similarity index 100% rename from app/soapbox/features/generic_not_found/index.js rename to app/soapbox/features/generic_not_found/index.tsx diff --git a/app/soapbox/features/ui/components/accordion.js b/app/soapbox/features/ui/components/accordion.js deleted file mode 100644 index 6b2b7b2bb..000000000 --- a/app/soapbox/features/ui/components/accordion.js +++ /dev/null @@ -1,59 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import React from 'react'; -import { defineMessages, injectIntl } from 'react-intl'; - -import DropdownMenu from 'soapbox/containers/dropdown_menu_container'; - -const messages = defineMessages({ - collapse: { id: 'accordion.collapse', defaultMessage: 'Collapse' }, - expand: { id: 'accordion.expand', defaultMessage: 'Expand' }, -}); - -export default @injectIntl class Accordion extends React.PureComponent { - - static propTypes = { - headline: PropTypes.node.isRequired, - children: PropTypes.oneOfType([PropTypes.string, PropTypes.element, PropTypes.node]), - menu: PropTypes.array, - expanded: PropTypes.bool, - onToggle: PropTypes.func, - intl: PropTypes.object.isRequired, - }; - - static defaultProps = { - expanded: false, - onToggle: () => {}, - } - - handleToggle = (e) => { - this.props.onToggle(!this.props.expanded); - e.preventDefault(); - } - - render() { - const { headline, children, menu, expanded, intl } = this.props; - - return ( -
- {menu && ( -
- -
- )} - -
- {children} -
-
- ); - } - -} diff --git a/app/soapbox/features/ui/components/accordion.tsx b/app/soapbox/features/ui/components/accordion.tsx new file mode 100644 index 000000000..b3f04262b --- /dev/null +++ b/app/soapbox/features/ui/components/accordion.tsx @@ -0,0 +1,52 @@ +import classNames from 'classnames'; +import React from 'react'; +import { defineMessages, useIntl } from 'react-intl'; + +import DropdownMenu from 'soapbox/containers/dropdown_menu_container'; + +import type { Menu } from 'soapbox/components/dropdown_menu'; + +const messages = defineMessages({ + collapse: { id: 'accordion.collapse', defaultMessage: 'Collapse' }, + expand: { id: 'accordion.expand', defaultMessage: 'Expand' }, +}); + +interface IAccordion { + headline: React.ReactNode, + children?: string | React.ReactNode, + menu?: Menu, + expanded?: boolean, + onToggle?: (value: boolean) => void, +} + +const Accordion: React.FC = ({ headline, children, menu, expanded = false, onToggle = () => {} }) => { + const intl = useIntl(); + + const handleToggle = (e: React.MouseEvent) => { + onToggle(!expanded); + e.preventDefault(); + }; + + return ( +
+ {menu && ( +
+ +
+ )} + +
+ {children} +
+
+ ); +}; + +export default Accordion;