From 750ac4886592330f7eef581fc96c15a4f53a47a9 Mon Sep 17 00:00:00 2001 From: Sam Hariri <137707942+samh-nl@users.noreply.github.com> Date: Tue, 5 Sep 2023 14:14:57 +0200 Subject: [PATCH 1/5] feat: support accountid attribute in user mentions --- .../HTMLRenderers/MentionUserRenderer.js | 58 +++++++++++++------ 1 file changed, 39 insertions(+), 19 deletions(-) diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/MentionUserRenderer.js b/src/components/HTMLEngineProvider/HTMLRenderers/MentionUserRenderer.js index 7f7753dfea44..992f8494dc1f 100644 --- a/src/components/HTMLEngineProvider/HTMLRenderers/MentionUserRenderer.js +++ b/src/components/HTMLEngineProvider/HTMLRenderers/MentionUserRenderer.js @@ -1,6 +1,8 @@ import React from 'react'; import _ from 'underscore'; import {TNodeChildrenRenderer} from 'react-native-render-html'; +import {withOnyx} from 'react-native-onyx'; +import lodashGet from 'lodash/get'; import Navigation from '../../../libs/Navigation/Navigation'; import ROUTES from '../../../ROUTES'; import Text from '../../Text'; @@ -10,52 +12,63 @@ import withCurrentUserPersonalDetails from '../../withCurrentUserPersonalDetails import personalDetailsPropType from '../../../pages/personalDetailsPropType'; import * as StyleUtils from '../../../styles/StyleUtils'; import * as PersonalDetailsUtils from '../../../libs/PersonalDetailsUtils'; +import compose from '../../../libs/compose'; import TextLink from '../../TextLink'; +import ONYXKEYS from '../../../ONYXKEYS'; +import useLocalize from '../../../hooks/useLocalize'; const propTypes = { ...htmlRendererPropTypes, - /** - * Current user personal details - */ + /** Current user personal details */ currentUserPersonalDetails: personalDetailsPropType.isRequired, -}; -/** - * Navigates to user details screen based on email - * @param {String} email - * @returns {void} - * */ -const showUserDetails = (email) => Navigation.navigate(ROUTES.getDetailsRoute(email)); + /** Personal details of all users */ + personalDetails: personalDetailsPropType.isRequired, +}; function MentionUserRenderer(props) { + const {translate} = useLocalize(); const defaultRendererProps = _.omit(props, ['TDefaultRenderer', 'style']); + const htmlAttribAccountID = lodashGet(props.tnode.attributes, 'accountid'); + + let accountID; + let displayNameOrLogin; + let navigationRoute; - // We need to remove the leading @ from data as it is not part of the login - const loginWithoutLeadingAt = props.tnode.data ? props.tnode.data.slice(1) : ''; + if (!_.isEmpty(htmlAttribAccountID)) { + const user = lodashGet(props.personalDetails, htmlAttribAccountID); + accountID = parseInt(htmlAttribAccountID, 10); + displayNameOrLogin = lodashGet(user, 'login', '') || lodashGet(user, 'displayName', '') || translate('common.hidden'); + navigationRoute = ROUTES.getProfileRoute(htmlAttribAccountID); + } else { + // We need to remove the leading @ from data as it is not part of the login + displayNameOrLogin = props.tnode.data ? props.tnode.data.slice(1) : ''; - const accountID = _.first(PersonalDetailsUtils.getAccountIDsByLogins([loginWithoutLeadingAt])); + accountID = _.first(PersonalDetailsUtils.getAccountIDsByLogins([displayNameOrLogin])); + navigationRoute = ROUTES.getDetailsRoute(displayNameOrLogin); + } - const isOurMention = loginWithoutLeadingAt === props.currentUserPersonalDetails.login; + const isOurMention = accountID === props.currentUserPersonalDetails.accountID; return ( showUserDetails(loginWithoutLeadingAt)} + onPress={() => Navigation.navigate(navigationRoute)} // Add testID so it is NOT selected as an anchor tag by SelectionScraper testID="span" > - + {!_.isEmpty(htmlAttribAccountID) ? `@${displayNameOrLogin}` : } @@ -65,4 +78,11 @@ function MentionUserRenderer(props) { MentionUserRenderer.propTypes = propTypes; MentionUserRenderer.displayName = 'MentionUserRenderer'; -export default withCurrentUserPersonalDetails(MentionUserRenderer); +export default compose( + withCurrentUserPersonalDetails, + withOnyx({ + personalDetails: { + key: ONYXKEYS.PERSONAL_DETAILS_LIST, + }, + }), +)(MentionUserRenderer); From 19faf7deb3ed7043108a3ad7162fcbd90bb45901 Mon Sep 17 00:00:00 2001 From: Sam Hariri <137707942+samh-nl@users.noreply.github.com> Date: Wed, 6 Sep 2023 12:52:57 +0200 Subject: [PATCH 2/5] feat: remove navigation and tooltip when hidden --- .../HTMLRenderers/MentionUserRenderer.js | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/MentionUserRenderer.js b/src/components/HTMLEngineProvider/HTMLRenderers/MentionUserRenderer.js index 992f8494dc1f..087334061fa2 100644 --- a/src/components/HTMLEngineProvider/HTMLRenderers/MentionUserRenderer.js +++ b/src/components/HTMLEngineProvider/HTMLRenderers/MentionUserRenderer.js @@ -10,6 +10,7 @@ import UserDetailsTooltip from '../../UserDetailsTooltip'; import htmlRendererPropTypes from './htmlRendererPropTypes'; import withCurrentUserPersonalDetails from '../../withCurrentUserPersonalDetails'; import personalDetailsPropType from '../../../pages/personalDetailsPropType'; +import styles from '../../../styles/styles'; import * as StyleUtils from '../../../styles/StyleUtils'; import * as PersonalDetailsUtils from '../../../libs/PersonalDetailsUtils'; import compose from '../../../libs/compose'; @@ -39,8 +40,13 @@ function MentionUserRenderer(props) { if (!_.isEmpty(htmlAttribAccountID)) { const user = lodashGet(props.personalDetails, htmlAttribAccountID); accountID = parseInt(htmlAttribAccountID, 10); - displayNameOrLogin = lodashGet(user, 'login', '') || lodashGet(user, 'displayName', '') || translate('common.hidden'); - navigationRoute = ROUTES.getProfileRoute(htmlAttribAccountID); + displayNameOrLogin = lodashGet(user, 'login', '') || lodashGet(user, 'displayName', ''); + + if (_.isEmpty(displayNameOrLogin)) { + displayNameOrLogin = translate('common.hidden'); + } else { + navigationRoute = ROUTES.getProfileRoute(htmlAttribAccountID); + } } else { // We need to remove the leading @ from data as it is not part of the login displayNameOrLogin = props.tnode.data ? props.tnode.data.slice(1) : ''; @@ -50,26 +56,33 @@ function MentionUserRenderer(props) { } const isOurMention = accountID === props.currentUserPersonalDetails.accountID; + const TextLinkComponent = _.isEmpty(navigationRoute) ? Text : TextLink; return ( - Navigation.navigate(navigationRoute)} + style={[ + _.omit(props.style, 'color'), + StyleUtils.getMentionStyle(isOurMention), + {color: StyleUtils.getMentionTextColor(isOurMention)}, + _.isEmpty(navigationRoute) && styles.cursorDefault, + ]} + href={_.isEmpty(navigationRoute) ? undefined : `/${navigationRoute}`} + onPress={_.isEmpty(navigationRoute) ? undefined : () => Navigation.navigate(navigationRoute)} // Add testID so it is NOT selected as an anchor tag by SelectionScraper testID="span" > {!_.isEmpty(htmlAttribAccountID) ? `@${displayNameOrLogin}` : } - + ); From 2af817dfd68a3d0b34b50a52de8c34edb58ba515 Mon Sep 17 00:00:00 2001 From: Sam Hariri <137707942+samh-nl@users.noreply.github.com> Date: Wed, 6 Sep 2023 14:28:07 +0200 Subject: [PATCH 3/5] fix: ensure proptype is adhered to --- .../HTMLEngineProvider/HTMLRenderers/MentionUserRenderer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/MentionUserRenderer.js b/src/components/HTMLEngineProvider/HTMLRenderers/MentionUserRenderer.js index 087334061fa2..155596fb23b0 100644 --- a/src/components/HTMLEngineProvider/HTMLRenderers/MentionUserRenderer.js +++ b/src/components/HTMLEngineProvider/HTMLRenderers/MentionUserRenderer.js @@ -74,7 +74,7 @@ function MentionUserRenderer(props) { _.omit(props.style, 'color'), StyleUtils.getMentionStyle(isOurMention), {color: StyleUtils.getMentionTextColor(isOurMention)}, - _.isEmpty(navigationRoute) && styles.cursorDefault, + _.isEmpty(navigationRoute) ? styles.cursorDefault : {}, ]} href={_.isEmpty(navigationRoute) ? undefined : `/${navigationRoute}`} onPress={_.isEmpty(navigationRoute) ? undefined : () => Navigation.navigate(navigationRoute)} From 942b3268fca17392e5d71fc73c046c2eb48234ce Mon Sep 17 00:00:00 2001 From: Sam Hariri <137707942+samh-nl@users.noreply.github.com> Date: Mon, 18 Sep 2023 15:45:57 +0200 Subject: [PATCH 4/5] Revert "feat: remove navigation and tooltip when hidden" This reverts commit 19faf7deb3ed7043108a3ad7162fcbd90bb45901. --- .../HTMLRenderers/MentionUserRenderer.js | 29 +++++-------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/MentionUserRenderer.js b/src/components/HTMLEngineProvider/HTMLRenderers/MentionUserRenderer.js index 155596fb23b0..992f8494dc1f 100644 --- a/src/components/HTMLEngineProvider/HTMLRenderers/MentionUserRenderer.js +++ b/src/components/HTMLEngineProvider/HTMLRenderers/MentionUserRenderer.js @@ -10,7 +10,6 @@ import UserDetailsTooltip from '../../UserDetailsTooltip'; import htmlRendererPropTypes from './htmlRendererPropTypes'; import withCurrentUserPersonalDetails from '../../withCurrentUserPersonalDetails'; import personalDetailsPropType from '../../../pages/personalDetailsPropType'; -import styles from '../../../styles/styles'; import * as StyleUtils from '../../../styles/StyleUtils'; import * as PersonalDetailsUtils from '../../../libs/PersonalDetailsUtils'; import compose from '../../../libs/compose'; @@ -40,13 +39,8 @@ function MentionUserRenderer(props) { if (!_.isEmpty(htmlAttribAccountID)) { const user = lodashGet(props.personalDetails, htmlAttribAccountID); accountID = parseInt(htmlAttribAccountID, 10); - displayNameOrLogin = lodashGet(user, 'login', '') || lodashGet(user, 'displayName', ''); - - if (_.isEmpty(displayNameOrLogin)) { - displayNameOrLogin = translate('common.hidden'); - } else { - navigationRoute = ROUTES.getProfileRoute(htmlAttribAccountID); - } + displayNameOrLogin = lodashGet(user, 'login', '') || lodashGet(user, 'displayName', '') || translate('common.hidden'); + navigationRoute = ROUTES.getProfileRoute(htmlAttribAccountID); } else { // We need to remove the leading @ from data as it is not part of the login displayNameOrLogin = props.tnode.data ? props.tnode.data.slice(1) : ''; @@ -56,33 +50,26 @@ function MentionUserRenderer(props) { } const isOurMention = accountID === props.currentUserPersonalDetails.accountID; - const TextLinkComponent = _.isEmpty(navigationRoute) ? Text : TextLink; return ( - Navigation.navigate(navigationRoute)} + href={`/${navigationRoute}`} + style={[_.omit(props.style, 'color'), StyleUtils.getMentionStyle(isOurMention), {color: StyleUtils.getMentionTextColor(isOurMention)}]} + onPress={() => Navigation.navigate(navigationRoute)} // Add testID so it is NOT selected as an anchor tag by SelectionScraper testID="span" > {!_.isEmpty(htmlAttribAccountID) ? `@${displayNameOrLogin}` : } - + ); From 8e5aba99f32d40c7db244dec9f1bdd6ce5140dfb Mon Sep 17 00:00:00 2001 From: Sam Hariri <137707942+samh-nl@users.noreply.github.com> Date: Mon, 18 Sep 2023 16:47:48 +0200 Subject: [PATCH 5/5] feat: don't render when no account id or email --- .../HTMLRenderers/MentionUserRenderer.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/MentionUserRenderer.js b/src/components/HTMLEngineProvider/HTMLRenderers/MentionUserRenderer.js index 992f8494dc1f..ccace94142d5 100644 --- a/src/components/HTMLEngineProvider/HTMLRenderers/MentionUserRenderer.js +++ b/src/components/HTMLEngineProvider/HTMLRenderers/MentionUserRenderer.js @@ -41,12 +41,15 @@ function MentionUserRenderer(props) { accountID = parseInt(htmlAttribAccountID, 10); displayNameOrLogin = lodashGet(user, 'login', '') || lodashGet(user, 'displayName', '') || translate('common.hidden'); navigationRoute = ROUTES.getProfileRoute(htmlAttribAccountID); - } else { + } else if (!_.isEmpty(props.tnode.data)) { // We need to remove the leading @ from data as it is not part of the login - displayNameOrLogin = props.tnode.data ? props.tnode.data.slice(1) : ''; + displayNameOrLogin = props.tnode.data.slice(1); accountID = _.first(PersonalDetailsUtils.getAccountIDsByLogins([displayNameOrLogin])); navigationRoute = ROUTES.getDetailsRoute(displayNameOrLogin); + } else { + // If neither an account ID or email is provided, don't render anything + return null; } const isOurMention = accountID === props.currentUserPersonalDetails.accountID;