From d59fa058124e363d0d3c7855539e1208679002bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Fri, 12 Aug 2022 13:42:19 +0200 Subject: [PATCH 1/7] Add more context to post edit notification MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- app/soapbox/features/notifications/components/notification.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/soapbox/features/notifications/components/notification.tsx b/app/soapbox/features/notifications/components/notification.tsx index 642b92a7f..cbf67c4dd 100644 --- a/app/soapbox/features/notifications/components/notification.tsx +++ b/app/soapbox/features/notifications/components/notification.tsx @@ -104,7 +104,7 @@ const messages: Record = defineMessages({ }, update: { id: 'notification.update', - defaultMessage: '{name} edited a post', + defaultMessage: '{name} edited a post you interacted with', }, }); From 66216bd5b678cd8d1107262a25bccf30be0fcf32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Fri, 12 Aug 2022 13:47:32 +0200 Subject: [PATCH 2/7] Use Array.includes instead of indexOf MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- app/soapbox/base_polyfills.ts | 2 +- app/soapbox/components/autosuggest_input.tsx | 2 +- app/soapbox/components/autosuggest_textarea.tsx | 2 +- .../features/account_gallery/components/media_item.js | 4 ++-- app/soapbox/features/emoji/emoji_mart_search_light.js | 8 ++++---- app/soapbox/features/emoji/emoji_utils.js | 6 +++--- app/soapbox/features/status/components/card.tsx | 2 +- app/soapbox/features/ui/components/modal_root.js | 2 +- app/soapbox/features/ui/components/user_panel.tsx | 2 +- app/soapbox/features/ui/index.tsx | 2 +- app/soapbox/selectors/index.ts | 2 +- 11 files changed, 17 insertions(+), 17 deletions(-) diff --git a/app/soapbox/base_polyfills.ts b/app/soapbox/base_polyfills.ts index 53146d222..a6e92bb3c 100644 --- a/app/soapbox/base_polyfills.ts +++ b/app/soapbox/base_polyfills.ts @@ -37,7 +37,7 @@ if (!HTMLCanvasElement.prototype.toBlob) { const dataURL = this.toDataURL(type, quality); let data; - if (dataURL.indexOf(BASE64_MARKER) >= 0) { + if (dataURL.includes(BASE64_MARKER)) { const [, base64] = dataURL.split(BASE64_MARKER); data = decodeBase64(base64); } else { diff --git a/app/soapbox/components/autosuggest_input.tsx b/app/soapbox/components/autosuggest_input.tsx index e6a4af6d6..54f126a23 100644 --- a/app/soapbox/components/autosuggest_input.tsx +++ b/app/soapbox/components/autosuggest_input.tsx @@ -30,7 +30,7 @@ const textAtCursorMatchesToken = (str: string, caretPosition: number, searchToke word = str.slice(left, right + caretPosition); } - if (!word || word.trim().length < 3 || searchTokens.indexOf(word[0]) === -1) { + if (!word || word.trim().length < 3 || !searchTokens.includes(word[0])) { return [null, null]; } diff --git a/app/soapbox/components/autosuggest_textarea.tsx b/app/soapbox/components/autosuggest_textarea.tsx index b5d54b670..a475e5ce2 100644 --- a/app/soapbox/components/autosuggest_textarea.tsx +++ b/app/soapbox/components/autosuggest_textarea.tsx @@ -23,7 +23,7 @@ const textAtCursorMatchesToken = (str: string, caretPosition: number) => { word = str.slice(left, right + caretPosition); } - if (!word || word.trim().length < 3 || ['@', ':', '#'].indexOf(word[0]) === -1) { + if (!word || word.trim().length < 3 || !['@', ':', '#'].includes(word[0])) { return [null, null]; } diff --git a/app/soapbox/features/account_gallery/components/media_item.js b/app/soapbox/features/account_gallery/components/media_item.js index fe8c6cc85..aa15e39e2 100644 --- a/app/soapbox/features/account_gallery/components/media_item.js +++ b/app/soapbox/features/account_gallery/components/media_item.js @@ -51,7 +51,7 @@ class MediaItem extends ImmutablePureComponent { hoverToPlay = () => { const { autoPlayGif } = this.props; - return !autoPlayGif && ['gifv', 'video'].indexOf(this.props.attachment.get('type')) !== -1; + return !autoPlayGif && ['gifv', 'video'].includes(this.props.attachment.get('type')); } handleClick = e => { @@ -93,7 +93,7 @@ class MediaItem extends ImmutablePureComponent { style={{ objectPosition: `${x}% ${y}%` }} /> ); - } else if (['gifv', 'video'].indexOf(attachment.get('type')) !== -1) { + } else if (['gifv', 'video'].includes(attachment.get('type'))) { const conditionalAttributes = {}; if (isIOS()) { conditionalAttributes.playsInline = '1'; diff --git a/app/soapbox/features/emoji/emoji_mart_search_light.js b/app/soapbox/features/emoji/emoji_mart_search_light.js index 89e25785f..f16918ada 100644 --- a/app/soapbox/features/emoji/emoji_mart_search_light.js +++ b/app/soapbox/features/emoji/emoji_mart_search_light.js @@ -85,8 +85,8 @@ export function search(value, { emojisToShowFilter, maxResults, include, exclude pool = {}; data.categories.forEach(category => { - const isIncluded = include && include.length ? include.indexOf(category.name.toLowerCase()) > -1 : true; - const isExcluded = exclude && exclude.length ? exclude.indexOf(category.name.toLowerCase()) > -1 : false; + const isIncluded = include && include.length ? include.includes(category.name.toLowerCase()) : true; + const isExcluded = exclude && exclude.length ? exclude.includes(category.name.toLowerCase()) : false; if (!isIncluded || isExcluded) { return; } @@ -95,8 +95,8 @@ export function search(value, { emojisToShowFilter, maxResults, include, exclude }); if (custom.length) { - const customIsIncluded = include && include.length ? include.indexOf('custom') > -1 : true; - const customIsExcluded = exclude && exclude.length ? exclude.indexOf('custom') > -1 : false; + const customIsIncluded = include && include.length ? include.includes('custom') : true; + const customIsExcluded = exclude && exclude.length ? exclude.includes('custom') : false; if (customIsIncluded && !customIsExcluded) { addCustomToPool(custom, pool); } diff --git a/app/soapbox/features/emoji/emoji_utils.js b/app/soapbox/features/emoji/emoji_utils.js index 1f4629edf..ad0319598 100644 --- a/app/soapbox/features/emoji/emoji_utils.js +++ b/app/soapbox/features/emoji/emoji_utils.js @@ -15,7 +15,7 @@ const buildSearch = (data) => { (split ? string.split(/[-|_|\s]+/) : [string]).forEach((s) => { s = s.toLowerCase(); - if (search.indexOf(s) === -1) { + if (!search.includes(s)) { search.push(s); } }); @@ -190,7 +190,7 @@ function getData(emoji, skin, set) { function uniq(arr) { return arr.reduce((acc, item) => { - if (acc.indexOf(item) === -1) { + if (!acc.includes(item)) { acc.push(item); } return acc; @@ -201,7 +201,7 @@ function intersect(a, b) { const uniqA = uniq(a); const uniqB = uniq(b); - return uniqA.filter(item => uniqB.indexOf(item) >= 0); + return uniqA.filter(item => uniqB.includes(item)); } function deepMerge(a, b) { diff --git a/app/soapbox/features/status/components/card.tsx b/app/soapbox/features/status/components/card.tsx index fbbe0648d..d15eaadf3 100644 --- a/app/soapbox/features/status/components/card.tsx +++ b/app/soapbox/features/status/components/card.tsx @@ -26,7 +26,7 @@ const addAutoPlay = (html: string): string => { const iframe = document.querySelector('iframe'); if (iframe) { - if (iframe.src.indexOf('?') !== -1) { + if (iframe.src.includes('?')) { iframe.src += '&'; } else { iframe.src += '?'; diff --git a/app/soapbox/features/ui/components/modal_root.js b/app/soapbox/features/ui/components/modal_root.js index 62f9fa50f..f7b9b007c 100644 --- a/app/soapbox/features/ui/components/modal_root.js +++ b/app/soapbox/features/ui/components/modal_root.js @@ -92,7 +92,7 @@ export default class ModalRoot extends React.PureComponent { } renderLoading = modalId => () => { - return ['MEDIA', 'VIDEO', 'BOOST', 'CONFIRM', 'ACTIONS'].indexOf(modalId) === -1 ? : null; + return !['MEDIA', 'VIDEO', 'BOOST', 'CONFIRM', 'ACTIONS'].includes(modalId) ? : null; } renderError = (props) => { diff --git a/app/soapbox/features/ui/components/user_panel.tsx b/app/soapbox/features/ui/components/user_panel.tsx index 6bf77b659..3c801fd25 100644 --- a/app/soapbox/features/ui/components/user_panel.tsx +++ b/app/soapbox/features/ui/components/user_panel.tsx @@ -28,7 +28,7 @@ const UserPanel: React.FC = ({ accountId, action, badges, domain }) if (!account) return null; const displayNameHtml = { __html: account.get('display_name_html') }; - const acct = account.get('acct').indexOf('@') === -1 && domain ? `${account.get('acct')}@${domain}` : account.get('acct'); + const acct = !account.get('acct').includes('@') && domain ? `${account.get('acct')}@${domain}` : account.get('acct'); const header = account.get('header'); const verified = account.get('verified'); diff --git a/app/soapbox/features/ui/index.tsx b/app/soapbox/features/ui/index.tsx index b9fdab67d..e7c0f74e2 100644 --- a/app/soapbox/features/ui/index.tsx +++ b/app/soapbox/features/ui/index.tsx @@ -352,7 +352,7 @@ const UI: React.FC = ({ children }) => { const handleDragEnter = (e: DragEvent) => { e.preventDefault(); - if (e.target && dragTargets.current.indexOf(e.target) === -1) { + if (e.target && !dragTargets.current.includes(e.target)) { dragTargets.current.push(e.target); } diff --git a/app/soapbox/selectors/index.ts b/app/soapbox/selectors/index.ts index c1ab55532..2a026afe1 100644 --- a/app/soapbox/selectors/index.ts +++ b/app/soapbox/selectors/index.ts @@ -93,7 +93,7 @@ const toServerSideType = (columnType: string): string => { case 'thread': return columnType; default: - if (columnType.indexOf('list:') > -1) { + if (columnType.includes('list:')) { return 'home'; } else { return 'public'; // community, account, hashtag From e402660bc1f1813e9bed19f40a98796ce627237f Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Fri, 12 Aug 2022 10:15:21 -0500 Subject: [PATCH 3/7] StatusPage: convert to TSX --- app/soapbox/pages/status_page.js | 69 ------------------------------- app/soapbox/pages/status_page.tsx | 57 +++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 69 deletions(-) delete mode 100644 app/soapbox/pages/status_page.js create mode 100644 app/soapbox/pages/status_page.tsx diff --git a/app/soapbox/pages/status_page.js b/app/soapbox/pages/status_page.js deleted file mode 100644 index e4ff9955e..000000000 --- a/app/soapbox/pages/status_page.js +++ /dev/null @@ -1,69 +0,0 @@ -import React from 'react'; -import ImmutablePureComponent from 'react-immutable-pure-component'; -import { connect } from 'react-redux'; - -import LinkFooter from 'soapbox/features/ui/components/link_footer'; -import { - WhoToFollowPanel, - TrendsPanel, - SignUpPanel, - CtaBanner, -} from 'soapbox/features/ui/util/async-components'; -// import GroupSidebarPanel from '../features/groups/sidebar_panel'; -import { getFeatures } from 'soapbox/utils/features'; - -import { Layout } from '../components/ui'; -import BundleContainer from '../features/ui/containers/bundle_container'; - -const mapStateToProps = state => { - const me = state.get('me'); - const features = getFeatures(state.get('instance')); - - return { - me, - showTrendsPanel: features.trends, - showWhoToFollowPanel: features.suggestions, - }; -}; - -export default @connect(mapStateToProps) -class StatusPage extends ImmutablePureComponent { - - render() { - const { me, children, showTrendsPanel, showWhoToFollowPanel } = this.props; - - return ( - <> - - {children} - - {!me && ( - - {Component => } - - )} - - - - {!me && ( - - {Component => } - - )} - {showTrendsPanel && ( - - {Component => } - - )} - {showWhoToFollowPanel && ( - - {Component => } - - )} - - - - ); - } - -} diff --git a/app/soapbox/pages/status_page.tsx b/app/soapbox/pages/status_page.tsx new file mode 100644 index 000000000..2c35947ad --- /dev/null +++ b/app/soapbox/pages/status_page.tsx @@ -0,0 +1,57 @@ +import React from 'react'; + +import LinkFooter from 'soapbox/features/ui/components/link_footer'; +import { + WhoToFollowPanel, + TrendsPanel, + SignUpPanel, + CtaBanner, +} from 'soapbox/features/ui/util/async-components'; +import { useAppSelector, useFeatures } from 'soapbox/hooks'; + +import { Layout } from '../components/ui'; +import BundleContainer from '../features/ui/containers/bundle_container'; + +interface IStatusPage { + children: React.ReactNode, +} + +const StatusPage: React.FC = ({ children }) => { + const me = useAppSelector(state => state.me); + const features = useFeatures(); + + return ( + <> + + {children} + + {!me && ( + + {Component => } + + )} + + + + {!me && ( + + {Component => } + + )} + {features.trends && ( + + {Component => } + + )} + {features.suggestions && ( + + {Component => } + + )} + + + + ); +}; + +export default StatusPage; From 538613511291b1b0764439581e959ba8eff830d0 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Fri, 12 Aug 2022 10:22:30 -0500 Subject: [PATCH 4/7] WrappedRoute: fix PageProps type to include children --- app/soapbox/features/ui/util/react_router_helpers.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/app/soapbox/features/ui/util/react_router_helpers.tsx b/app/soapbox/features/ui/util/react_router_helpers.tsx index b7dbdb192..992a60e2b 100644 --- a/app/soapbox/features/ui/util/react_router_helpers.tsx +++ b/app/soapbox/features/ui/util/react_router_helpers.tsx @@ -13,6 +13,7 @@ import BundleContainer from '../containers/bundle_container'; type PageProps = { params?: MatchType['params'], layout?: any, + children: React.ReactNode, }; interface IWrappedRoute extends RouteProps { From 7615111eb0587f0bdcd97ca54329a605da660fa7 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Fri, 12 Aug 2022 10:42:26 -0500 Subject: [PATCH 5/7] IconButton: add themes --- app/soapbox/components/ui/icon-button/icon-button.tsx | 7 +++++-- app/soapbox/features/account/components/header.tsx | 9 ++++++--- .../features/ui/components/subscription-button.tsx | 3 ++- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/app/soapbox/components/ui/icon-button/icon-button.tsx b/app/soapbox/components/ui/icon-button/icon-button.tsx index 352c7a92c..6b4f5414a 100644 --- a/app/soapbox/components/ui/icon-button/icon-button.tsx +++ b/app/soapbox/components/ui/icon-button/icon-button.tsx @@ -12,12 +12,14 @@ interface IIconButton extends React.ButtonHTMLAttributes { /** Text to display next ot the button. */ text?: string, /** Don't render a background behind the icon. */ - transparent?: boolean + transparent?: boolean, + /** Predefined styles to display for the button. */ + theme?: 'seamless' | 'outlined', } /** A clickable icon. */ const IconButton = React.forwardRef((props: IIconButton, ref: React.ForwardedRef): JSX.Element => { - const { src, className, iconClassName, text, transparent = false, ...filteredProps } = props; + const { src, className, iconClassName, text, transparent = false, theme = 'seamless', ...filteredProps } = props; return (