{"version":3,"file":"js/34269-4e82b6d589ca352bfcc1.js","mappings":"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","sources":["webpack://StravaModern/./app/javascript/api/athlete/athlete.js","webpack://StravaModern/./app/javascript/components/shared/InviteFriends/components/InviteFriendsButton/InviteFriendsButton.scss?21f1","webpack://StravaModern/./app/javascript/components/shared/InviteFriends/constants/invite-friends-constants.js","webpack://StravaModern/./app/javascript/components/shared/InviteFriends/utils/invite-friends-utils.js","webpack://StravaModern/./app/javascript/components/shared/InviteFriends/components/InviteFriendsModal/InviteFriendsModal.scss?143d","webpack://StravaModern/./app/javascript/components/shared/InviteFriends/state/InviteFriendsContext.js","webpack://StravaModern/./app/javascript/components/shared/InviteFriends/state/InviteFriends.actions.js","webpack://StravaModern/./app/javascript/hooks/externalSocialPartners/useGoogle.js","webpack://StravaModern/./app/javascript/components/shared/InviteFriends/components/InviteFriendsModal/components/EmailTabContent/EmailTabContent.scss?f2d3","webpack://StravaModern/./app/javascript/components/shared/InviteFriends/components/InviteFriendsModal/components/EmailTabContent/components/LinkGoogleAccount/LinkGoogleAccount.scss?841b","webpack://StravaModern/./app/javascript/components/shared/InviteFriends/components/InviteFriendsModal/components/EmailTabContent/components/LinkGoogleAccount/LinkGoogleAccount.js","webpack://StravaModern/./app/javascript/components/shared/InviteFriends/components/InviteFriendsModal/components/EmailTabContent/components/GmailContactList/GmailContactList.scss?0bdd","webpack://StravaModern/./app/javascript/components/shared/InviteFriends/components/InviteFriendsModal/components/EmailTabContent/components/GmailContactList/components/ContactEntry.scss?f7d7","webpack://StravaModern/./app/javascript/components/shared/InviteFriends/components/InviteFriendsModal/components/EmailTabContent/EmailTabContent.utils.js","webpack://StravaModern/./app/javascript/components/shared/InviteFriends/components/InviteFriendsModal/components/EmailTabContent/components/GmailContactList/components/ContactEntry.js","webpack://StravaModern/./app/javascript/components/shared/InviteFriends/components/InviteFriendsModal/components/EmailTabContent/components/GmailContactList/GmailContactList.js","webpack://StravaModern/./app/javascript/components/shared/InviteFriends/components/InviteFriendsModal/components/EmailTabContent/EmailTabContent.js","webpack://StravaModern/./app/javascript/components/shared/InviteFriends/components/InviteFriendsModal/InviteFriendsModal.js","webpack://StravaModern/./app/javascript/components/shared/InviteFriends/state/InviteFriends.reducer.js","webpack://StravaModern/./app/javascript/components/shared/InviteFriends/components/InviteFriendsButton/InviteFriendsButton.js","webpack://StravaModern/./app/javascript/hooks/externalSocialPartners/useFacebook.js","webpack://StravaModern/./app/javascript/components/shared/friends/components/shared/LinkFacebookButton/LinkFacebookButton.scss?235a","webpack://StravaModern/./app/javascript/components/shared/friends/components/shared/LinkFacebookButton/LinkFacebookButton.js","webpack://StravaModern/./app/javascript/components/shared/friends/components/LinkFacebookAccount/LinkFacebookAccount.scss?b824","webpack://StravaModern/./app/javascript/components/shared/friends/components/LinkFacebookAccount/LinkFacebookAccount.js","webpack://StravaModern/./app/javascript/components/shared/friends/components/FacebookFriendList/InviteFriendsHeader/InviteFriendsHeader.scss?9139","webpack://StravaModern/./app/javascript/components/shared/friends/components/FacebookFriendList/InviteFriendsHeader/InviteFriendsHeader.js","webpack://StravaModern/./app/javascript/components/shared/friends/components/FacebookFriendList/FacebookFriendList.js","webpack://StravaModern/./app/javascript/components/shared/friends/FindFacebookFriends/FindFacebookFriends.scss?ea55","webpack://StravaModern/./app/javascript/components/shared/friends/FindFacebookFriends/FindFacebookFriends.js","webpack://StravaModern/./app/javascript/components/shared/friends/components/shared/FriendList/FriendList.scss?6e23","webpack://StravaModern/./app/javascript/components/shared/friends/components/shared/FriendList/FriendList.js","webpack://StravaModern/./app/javascript/components/shared/friends/components/shared/AthleteInfo/AthleteInfo.scss?a41a","webpack://StravaModern/./app/javascript/components/shared/friends/components/shared/AthleteInfo/AthleteInfo.js","webpack://StravaModern/./app/javascript/components/shared/friends/utils/useCtaAction.js","webpack://StravaModern/./app/javascript/components/shared/friends/components/shared/FriendListItem/FriendListItem.js","webpack://StravaModern/./app/javascript/components/shared/friends/state/FriendsContext.js","webpack://StravaModern/./app/javascript/components/shared/friends/state/friendsActions.js","webpack://StravaModern/./app/javascript/components/shared/friends/state/friendsReducer.js","webpack://StravaModern/./app/javascript/components/shared/friends/utils/friendsConstants.js","webpack://StravaModern/./app/javascript/components/shared/friends/utils/friendsUtils.js","webpack://StravaModern/./app/javascript/constants/follows/following-constants.js","webpack://StravaModern/./app/javascript/hooks/externalSocialPartners/constants/auth-status-constants.js"],"sourcesContent":["import createNetworkingClient from 'utils/networking-client';\nimport { StatusCodes } from 'http-status-codes';\nimport { FOLLOWING_STATUS } from '../../constants/follows/following-constants';\nimport { logError } from '../../utils/sentry';\n\n/**\n * Follows an athlete on strava.\n *\n * @param {Object} param\n * @param {string} param.followerId - id for the athlete who is requesting the follow\n * @param {string} param.followingId - id for the athlete to be followed\n * @returns {Promise} - enum value PENDING or FOLLOWING\n */\nexport const followAthlete = ({ followerId, followingId }) => {\n return new Promise((resolve) => {\n createNetworkingClient()\n .post(`/athletes/${followerId}/follows`, {\n follow: {\n follower_id: followerId,\n following_id: followingId\n }\n })\n .then((response) => {\n if (response?.status === StatusCodes.OK) {\n const { data } = response;\n if (data.approved) {\n resolve(FOLLOWING_STATUS.following);\n } else {\n resolve(FOLLOWING_STATUS.pending);\n }\n } else {\n resolve(FOLLOWING_STATUS.error);\n // TODO log sentry error\n }\n })\n .catch(() => {\n resolve(FOLLOWING_STATUS.error);\n // TODO log sentry error\n });\n });\n};\n\nexport const bulkFollow = ({ followeeIds }) => {\n return new Promise((resolve) => {\n createNetworkingClient()\n .post('/athlete/bulk_follow', {\n followee_ids: followeeIds\n })\n .then((response) => {\n const { success, followed_athlete_ids: ids } = response.data;\n resolve({ success, followedAthleteIds: ids || [] });\n })\n .catch((e) => {\n logError(e);\n resolve({ success: false });\n });\n });\n};\n\nexport const unfollowAthlete = ({ followerId, followingId }) => {\n return new Promise((resolve) => {\n createNetworkingClient()\n .delete(\n `/athletes/${followerId}/follows/${followingId}`,\n {\n data: {\n follow: {\n follower_id: followerId,\n following_id: followingId\n }\n }\n },\n { headers: { Accept: 'text/javascript' } }\n )\n .then((response) => {\n if (response?.status === StatusCodes.NO_CONTENT) {\n resolve(true);\n } else {\n logError(response);\n resolve(false);\n }\n })\n .catch((e) => {\n logError(e);\n resolve(false);\n });\n });\n};\n\n/**\n * Gets suggested follow list\n *\n * @param {Object} param\n * @param {string} param.callsite - source making the get request\n * @returns {Promise} - list of suggested friends to follow\n */\nexport const getSuggestedFollows = ({ callsite }) => {\n return new Promise((resolve, reject) => {\n createNetworkingClient()\n .get('/athlete/suggested_follows', {\n params: { callsite }\n })\n .then((response) => {\n if (response?.status === StatusCodes.OK) {\n const { data } = response;\n resolve(data);\n } else {\n logError(response.error);\n resolve(response.error);\n }\n })\n .catch((e) => {\n logError(e);\n reject(e);\n });\n });\n};\n\nexport default { followAthlete, unfollowAthlete, getSuggestedFollows };\n","// extracted by mini-css-extract-plugin\nexport default {\"dashboard-sidebar\":\"InviteFriendsButton--dashboard-sidebar--BoJFT\",\"dashboardSidebar\":\"InviteFriendsButton--dashboard-sidebar--BoJFT\",\"onboarding\":\"InviteFriendsButton--onboarding--8znw0\",\"header-menu\":\"InviteFriendsButton--header-menu--VJUik\",\"headerMenu\":\"InviteFriendsButton--header-menu--VJUik\"};","export const I18nPrefix = 'components.invite_your_friends';\n\nexport default { I18nPrefix };\n","import I18n from 'utils/I18n';\nimport { I18nPrefix } from '../constants/invite-friends-constants';\n\nexport const t = (key, params) => I18n.t(`${I18nPrefix}.${key}`, { ...params });\n\nexport default { t };\n","// extracted by mini-css-extract-plugin\nexport default {\"tab-panels\":\"InviteFriendsModal--tab-panels--04Cpi\",\"tabPanels\":\"InviteFriendsModal--tab-panels--04Cpi\",\"tab-list\":\"InviteFriendsModal--tab-list--ClIK5\",\"tabList\":\"InviteFriendsModal--tab-list--ClIK5\"};","import React from 'react';\n\nconst InviteFriendsContext = React.createContext();\n// Context object accepts a displayName string property.\n// React DevTools uses this string to determine what to display for the context.\nInviteFriendsContext.displayName = 'InviteFriendsContext';\n\nexport function useInviteFriendsContext() {\n return React.useContext(InviteFriendsContext);\n}\n\nexport default InviteFriendsContext;\n","export const ADD_ALERT = 'ADD_ALERT';\nexport const CHANGE_TAB = 'CHANGE_TAB';\nexport const CLEAR_ALERT = 'CLEAR_ALERT';\nexport const CLEAR_EMAILS = 'CLEAR_EMAILS';\nexport const CLOSE_MODAL = 'CLOSE_MODAL';\nexport const OPEN_MODAL = 'OPEN_MODAL';\nexport const UPDATE_EMAILS = 'UPDATE_EMAILS';\nexport const UPDATE_FB_FRIENDS = 'UPDATE_FB_FRIENDS';\nexport const UPDATE_FB_FRIEND_FOLLOWING_STATUS =\n 'UPDATE_FB_FRIEND_FOLLOWING_STATUS';\nexport const UPDATE_INVITED_EMAILS_LIST = 'UPDATE_INVITED_EMAILS_LIST';\n\nexport default {\n ADD_ALERT,\n CHANGE_TAB,\n CLEAR_ALERT,\n CLOSE_MODAL,\n OPEN_MODAL,\n UPDATE_EMAILS,\n UPDATE_FB_FRIENDS,\n UPDATE_FB_FRIEND_FOLLOWING_STATUS,\n UPDATE_INVITED_EMAILS_LIST\n};\n","import { isNil } from 'lodash-es';\nimport { useEffect, useState } from 'react';\nimport createNetworkingClient from 'utils/networking-client';\nimport { injectGoogleScript } from 'externalSocialPartners';\nimport { timeout } from 'utils/devUtils';\nimport { AuthorizationStatus } from './constants/auth-status-constants';\nimport { logError } from '../../utils/sentry';\n\nconst PEOPLE_BASE_URL = 'https://people.googleapis.com/v1/';\n\n/**\n * Fetches a list of contacts from an authenticated google account.\n */\nconst useGoogle = ({ clientId, mocked = false }) => {\n const [contacts, setContacts] = useState([]);\n const [token, setToken] = useState(undefined);\n const [authorizationStatus, setAuthorizationStatus] = useState(\n AuthorizationStatus.INITIATED\n );\n\n const mockedConnections = () => {\n return new Promise((resolve) => {\n import('./data/google_connections_sample.json').then(async (c) => {\n await timeout(2000); // delaying things on purpose so we can see the spinner when mocking data\n resolve(c.connections);\n });\n });\n };\n\n /**\n * callback method called when the athlete signs into their google account.\n * This method attempts to retrieve contacts from the authenticated google account.\n */\n const handleSignInContactsScope = (tokenResponse) => {\n if (tokenResponse && tokenResponse.access_token) {\n const accessToken = tokenResponse.access_token;\n setToken(accessToken);\n\n const requestedScope =\n 'https://www.googleapis.com/auth/contacts.readonly';\n if (\n window.google.accounts.oauth2.hasGrantedAllScopes(\n tokenResponse,\n requestedScope\n )\n ) {\n const headers = { Authorization: `Bearer ${accessToken}` };\n const url = `${PEOPLE_BASE_URL}people/me/connections?personFields=names,photos,emailAddresses`;\n\n setAuthorizationStatus(AuthorizationStatus.AUTHORIZED);\n createNetworkingClient({ headers })\n .get(url, { params: { alt: 'json' } })\n .then(async (response) => {\n if (response && response.status === 200) {\n let { connections } = response.data;\n if (mocked) {\n connections = await mockedConnections();\n }\n setContacts(connections || []);\n setAuthorizationStatus(AuthorizationStatus.DATA_FETCHED);\n } else {\n setAuthorizationStatus(AuthorizationStatus.ERROR);\n logError(response.error);\n }\n })\n .catch((e) => {\n setAuthorizationStatus(AuthorizationStatus.ERROR);\n logError(e);\n });\n } else {\n // unauthorized\n setAuthorizationStatus(AuthorizationStatus.UNAUTHORIZED);\n window.google.accounts.oauth2.revoke(accessToken);\n }\n }\n };\n\n /**\n * Initializes a client that is used by athletes to request a token\n */\n const initializeGsiTokenClient = (scope, callback) => {\n const client = window.google.accounts.oauth2.initTokenClient({\n client_id: clientId,\n scope,\n callback\n });\n return client;\n };\n\n /**\n * injects GSI javascript library when the component that uses this hook is mounted\n */\n useEffect(() => {\n injectGoogleScript(async () => {\n if (mocked) {\n await timeout(2000);\n }\n setAuthorizationStatus(AuthorizationStatus.READY);\n });\n\n return () => {\n window?.google?.accounts?.id?.cancel();\n };\n }, [mocked]);\n\n const requestContacts = () => {\n setAuthorizationStatus(AuthorizationStatus.READY);\n setContacts([]);\n\n const requestedScope = 'https://www.googleapis.com/auth/contacts.readonly';\n\n const client = initializeGsiTokenClient(\n requestedScope,\n handleSignInContactsScope\n );\n client.requestAccessToken();\n };\n\n const disconnect = () => {\n setContacts([]);\n setAuthorizationStatus(AuthorizationStatus.READY);\n if (!isNil(token)) {\n window.google.accounts.oauth2.revoke(token);\n }\n };\n\n return {\n authorizationStatus,\n contacts,\n requestContacts,\n disconnect\n };\n};\n\nexport default useGoogle;\n","// extracted by mini-css-extract-plugin\nexport default {\"flex-grid\":\"EmailTabContent--flex-grid--Mga-F\",\"flexGrid\":\"EmailTabContent--flex-grid--Mga-F\",\"col\":\"EmailTabContent--col--QG6K6\",\"email-column\":\"EmailTabContent--email-column--C8DUs\",\"emailColumn\":\"EmailTabContent--email-column--C8DUs\",\"email-input\":\"EmailTabContent--email-input--Xkzv2\",\"emailInput\":\"EmailTabContent--email-input--Xkzv2\",\"email-body\":\"EmailTabContent--email-body--lNZfZ\",\"emailBody\":\"EmailTabContent--email-body--lNZfZ\",\"headline\":\"EmailTabContent--headline--wy3OM\",\"email-validation-error\":\"EmailTabContent--email-validation-error--KbaR0\",\"emailValidationError\":\"EmailTabContent--email-validation-error--KbaR0\",\"spinner\":\"EmailTabContent--spinner--7dkIg\",\"label\":\"EmailTabContent--label--VrcIr\",\"textarea\":\"EmailTabContent--textarea--1h97A\",\"error-border\":\"EmailTabContent--error-border--b31sY\",\"errorBorder\":\"EmailTabContent--error-border--b31sY\",\"send-button\":\"EmailTabContent--send-button--R4a2H\",\"sendButton\":\"EmailTabContent--send-button--R4a2H\"};","// extracted by mini-css-extract-plugin\nexport default {\"headline\":\"LinkGoogleAccount--headline--HvrbG\",\"content\":\"LinkGoogleAccount--content--wzkX7\",\"btn-label\":\"LinkGoogleAccount--btn-label--B5Uw8\",\"btnLabel\":\"LinkGoogleAccount--btn-label--B5Uw8\",\"gmail-button\":\"LinkGoogleAccount--gmail-button--u3CEQ\",\"gmailButton\":\"LinkGoogleAccount--gmail-button--u3CEQ\",\"active\":\"LinkGoogleAccount--active--EQMr3\",\"focus\":\"LinkGoogleAccount--focus--mpuxT\"};","import React from 'react';\nimport PropTypes from 'prop-types';\nimport GoogleButton from 'react-google-button';\nimport styles from './LinkGoogleAccount.scss';\n\nimport { t } from '../../../../../../utils/invite-friends-utils';\nimport { useInviteFriendsContext } from '../../../../../../state/InviteFriendsContext';\nimport { CLEAR_ALERT } from '../../../../../../state/InviteFriends.actions';\n\nconst LinkGoogleAccount = ({ requestContacts }) => {\n const { dispatch, track } = useInviteFriendsContext();\n\n const handleOnClick = () => {\n track({\n element: 'add_gmail_contacts',\n action: 'click',\n properties: { current_tab: 'email' }\n });\n dispatch({ type: CLEAR_ALERT });\n requestContacts();\n };\n return (\n <>\n

\n {t('modal.email.gmail_request.title')}\n

\n
\n

{t('modal.email.gmail_request.message')}

\n

\n {t('modal.email.gmail_request.disclaimer')}\n

\n
\n \n \n );\n};\n\nLinkGoogleAccount.propTypes = {\n requestContacts: PropTypes.func.isRequired\n};\n\nexport default LinkGoogleAccount;\n","// extracted by mini-css-extract-plugin\nexport default {\"headline\":\"GmailContactList--headline--wIxQ3\",\"disconnect-btn\":\"GmailContactList--disconnect-btn--ce6fi\",\"disconnectBtn\":\"GmailContactList--disconnect-btn--ce6fi\",\"search-input\":\"GmailContactList--search-input--pwQ4B\",\"searchInput\":\"GmailContactList--search-input--pwQ4B\",\"contact-list\":\"GmailContactList--contact-list--W2QgU\",\"contactList\":\"GmailContactList--contact-list--W2QgU\",\"fadeIn\":\"GmailContactList--fadeIn--ZgZO1\",\"spinner\":\"GmailContactList--spinner--Et4+N\",\"no-results\":\"GmailContactList--no-results--N3Xpe\",\"noResults\":\"GmailContactList--no-results--N3Xpe\",\"newKudo\":\"GmailContactList--newKudo--Hritm\",\"enterFadeOut\":\"GmailContactList--enterFadeOut--jZgsD\"};","// extracted by mini-css-extract-plugin\nexport default {\"athlete-metadata\":\"components--athlete-metadata--L1G69\",\"athleteMetadata\":\"components--athlete-metadata--L1G69\",\"name-and-email\":\"components--name-and-email--9n4AE\",\"nameAndEmail\":\"components--name-and-email--9n4AE\",\"name\":\"components--name--Bot7S\",\"disabled\":\"components--disabled--Pikmj\",\"email\":\"components--email--L8Vc8\",\"action-btn\":\"components--action-btn--ln6CC\",\"actionBtn\":\"components--action-btn--ln6CC\"};","import { compact, isEmpty, isNil, split, toLower, trim } from 'lodash-es';\n\n/**\n * Extracts the primary entry from an entries with multiple values.\n * If it cant be determined what the primary entry is, the first entry\n * in the list will be picked.\n *\n * entry example -\n * [ { displayName: 'Athlete Name_1', metadata: { primary: false } },\n * { displayName: 'Athlete Name_2', metadata: { primary: true } } ]\n *\n * @param {Object} entries - a list of entries with metadata that include a boolean which indicates\n * whether an entry is primary or not.\n * @returns\n */\nconst getPrimaryEntry = (entries) => {\n if (isNil(entries)) {\n return null;\n }\n const primary = entries.find((entry) => {\n const { metadata } = entry;\n return metadata ? metadata.primary : false;\n });\n return isEmpty(primary) ? entries[0] : primary;\n};\n\nexport const processContactsForUI = (contacts) => {\n const processedContacts = contacts.map((c, index) => {\n const { names, emailAddresses, photos } = c;\n\n const displayContact = {\n key: index,\n isOnStrava: false\n };\n // email address (required)\n if (isNil(getPrimaryEntry(emailAddresses))) {\n return null;\n }\n displayContact.email = getPrimaryEntry(emailAddresses).value;\n\n // display name (optional)\n if (isEmpty(names)) {\n displayContact.name = '';\n } else {\n displayContact.name = getPrimaryEntry(names).displayName;\n }\n // avatar picture (optional)\n if (isEmpty(photos)) {\n displayContact.picture = ''; // @strava/ui/Avatar requires blank string (vs null)\n } else {\n displayContact.picture = getPrimaryEntry(photos).url;\n }\n\n return displayContact;\n });\n return compact(processedContacts);\n};\n\nexport const extractEmailsFromString = (emails) => {\n return compact(split(toLower(emails), ',').map((email) => trim(email)));\n};\n\nexport default { processContactsForUI, extractEmailsFromString };\n","import React, { useEffect, useState } from 'react';\nimport PropTypes from 'prop-types';\nimport Button from '@strava/ui/Button';\n\nimport { isEmpty } from 'lodash-es';\nimport Avatar from '@strava/ui/Avatar';\nimport clsx from '@strava/ui/clsx';\nimport {\n FOLLOW_ACTIONS,\n FOLLOWING_STATUS\n} from 'constants/follows/following-constants';\nimport { followAthlete } from 'api/athlete';\nimport styles from './ContactEntry.scss';\nimport { t } from '../../../../../../../utils/invite-friends-utils';\nimport { useInviteFriendsContext } from '../../../../../../../state/InviteFriendsContext';\nimport {\n UPDATE_EMAILS,\n ADD_ALERT,\n CLEAR_ALERT\n} from '../../../../../../../state/InviteFriends.actions';\nimport { extractEmailsFromString } from '../../../EmailTabContent.utils';\n\nconst ContactEntry = ({ contact }) => {\n const [config, setConfig] = useState({\n action: FOLLOW_ACTIONS.add,\n disabled: false\n });\n const [currentFollowingStatus, setCurrentFollowingStatus] = useState(\n contact.followingStatus\n );\n\n const [isLoading, setIsLoading] = useState(false);\n\n const { state, dispatch, track } = useInviteFriendsContext();\n const { emails, currentAthlete, invitedEmailsList } = state;\n\n useEffect(() => {\n let action;\n let disabled = false;\n if (contact.isOnStrava) {\n if (currentFollowingStatus === FOLLOWING_STATUS.pending) {\n action = FOLLOW_ACTIONS.followRequested;\n disabled = true;\n } else if (currentFollowingStatus === FOLLOWING_STATUS.following) {\n action = FOLLOW_ACTIONS.following;\n disabled = true;\n } else {\n action = contact.approveFollowers\n ? FOLLOW_ACTIONS.requestToFollow\n : FOLLOW_ACTIONS.follow;\n }\n } else {\n action = FOLLOW_ACTIONS.add;\n const { email } = contact;\n disabled =\n invitedEmailsList.includes(email) ||\n extractEmailsFromString(emails).includes(email);\n }\n setConfig((prev) => {\n return { ...prev, action, disabled };\n });\n }, [\n contact,\n contact.approveFollowers,\n contact.email,\n contact.isOnStrava,\n currentFollowingStatus,\n emails,\n invitedEmailsList\n ]);\n\n const disabledTextStyle = config.disabled ? styles.disabled : '';\n\n const handleBtnClick = (action) => {\n dispatch({ type: CLEAR_ALERT });\n track({\n element: `${action}_btn`,\n action: 'click',\n properties: {\n current_tab: 'email',\n athlete_id: contact.id\n }\n });\n\n switch (action) {\n case FOLLOW_ACTIONS.add: {\n const separator = isEmpty(emails) ? '' : ',';\n dispatch({\n type: UPDATE_EMAILS,\n payload: { emails: emails.concat(separator, contact.email) }\n });\n setConfig((prev) => {\n return { ...prev, disabled: true };\n });\n break;\n }\n\n case FOLLOW_ACTIONS.follow:\n case FOLLOW_ACTIONS.requestToFollow: {\n setIsLoading(true);\n followAthlete({\n followerId: currentAthlete.id,\n followingId: contact.id\n })\n .then((status) => {\n if (status === FOLLOWING_STATUS.error) {\n dispatch({\n type: ADD_ALERT,\n payload: {\n alert: {\n severity: 'error',\n message: t(`modal.errors.generic`)\n }\n }\n });\n } else {\n setCurrentFollowingStatus(status);\n }\n })\n .finally(() => {\n setIsLoading(false);\n });\n break;\n }\n default: // noop\n }\n };\n\n return (\n <>\n
\n \n
\n

\n {contact.name}\n

\n

\n {contact.email}\n

\n
\n
\n handleBtnClick(config.action)}\n disabled={config.disabled || isLoading}\n >\n {t(`modal.email.gmail_authorized.contact_cta.${config.action}`)}\n \n \n );\n};\n\nContactEntry.propTypes = {\n contact: PropTypes.shape({\n id: PropTypes.number,\n name: PropTypes.string,\n picture: PropTypes.string,\n badge: PropTypes.string,\n email: PropTypes.string.isRequired,\n isOnStrava: PropTypes.bool.isRequired,\n followingStatus: PropTypes.oneOf([\n 'following',\n 'pending',\n 'can_follow',\n 'can_request'\n ]),\n approveFollowers: PropTypes.bool\n }).isRequired\n};\n\nexport default ContactEntry;\n","import React, { useEffect, useRef, useState } from 'react';\nimport PropTypes from 'prop-types';\nimport Button from '@strava/ui/Button';\nimport { isEmpty, size } from 'lodash-es';\nimport Spinner from '@strava/ui/Spinner';\nimport styles from './GmailContactList.scss';\n\nimport { t } from '../../../../../../utils/invite-friends-utils';\nimport ContactEntry from './components/ContactEntry';\nimport { useInviteFriendsContext } from '../../../../../../state/InviteFriendsContext';\nimport { CLEAR_ALERT } from '../../../../../../state/InviteFriends.actions';\n\nconst GmailContactList = ({ contacts, disconnect, isLoading }) => {\n const [searchKeyword, setSearchKeyword] = useState(''); // value entered in the search field\n const [filterResults, setFilterResults] = useState(contacts);\n\n const { dispatch, track } = useInviteFriendsContext();\n\n // keeps track if its the initial search results (with no filter applied).\n // This is necessary because filtered results change based on the search box input\n // and we dont want to re-register a screen-enter at that point.\n const initialResults = useRef(true);\n\n useEffect(() => {\n if (!isLoading && initialResults.current) {\n track({\n element: 'google_contacts_feed',\n action: 'screen_enter',\n properties: {\n current_tab: 'email',\n contacts_count: filterResults.length,\n already_on_strava_count: size(\n filterResults.filter((contact) => contact.isOnStrava)\n )\n }\n });\n initialResults.current = false;\n }\n }, [isLoading, filterResults, track]);\n\n useEffect(() => {\n setFilterResults(contacts);\n }, [contacts]);\n\n const filterContacts = (e) => {\n dispatch({\n type: CLEAR_ALERT\n });\n\n const keyword = e.target.value;\n if (keyword !== '') {\n const results = contacts.filter((contact) => {\n return (\n contact.name.toLowerCase().includes(keyword.toLowerCase()) ||\n contact.email.toLowerCase().includes(keyword.toLowerCase())\n );\n });\n setFilterResults(results);\n } else {\n setFilterResults(contacts); // show all contacts\n }\n setSearchKeyword(keyword);\n };\n\n const handleOnDisconnect = () => {\n track({\n element: 'disconnect_gmail_contacts',\n action: 'click',\n properties: { current_tab: 'email' }\n });\n dispatch({ type: CLEAR_ALERT });\n disconnect();\n };\n\n return (\n <>\n

\n {t('modal.email.gmail_authorized.title')}\n

\n \n {t('modal.email.gmail_authorized.disconnect')}\n \n\n \n\n \n \n );\n};\n\nconst ResultsFeed = ({ isLoading, results }) => {\n if (isLoading) {\n return (\n
\n \n
\n );\n }\n if (results && results.length > 0) {\n return (\n
    \n {results.map((contact) => (\n
  • \n \n
  • \n ))}\n
\n );\n }\n return (\n

\n {t('modal.email.gmail_authorized.no_results_found')}\n

\n );\n};\n\nResultsFeed.propTypes = {\n isLoading: PropTypes.bool.isRequired,\n results: PropTypes.arrayOf(PropTypes.shape({})).isRequired\n};\n\nGmailContactList.propTypes = {\n contacts: PropTypes.arrayOf(PropTypes.shape({})).isRequired,\n disconnect: PropTypes.func.isRequired,\n isLoading: PropTypes.bool.isRequired\n};\n\nexport default GmailContactList;\n","import React, { useEffect, useRef, useCallback } from 'react';\nimport Button from '@strava/ui/Button';\nimport useGoogle from 'hooks/externalSocialPartners/useGoogle';\nimport Spinner from '@strava/ui/Spinner';\nimport { AuthorizationStatus } from 'hooks/externalSocialPartners/constants/auth-status-constants';\nimport {\n remove,\n uniqBy,\n isEmpty,\n find,\n isNil,\n escape,\n toLower,\n orderBy\n} from 'lodash-es';\nimport createNetworkingClient from 'utils/networking-client';\nimport * as EmailValidator from 'email-validator';\nimport clsx from '@strava/ui/clsx';\nimport { timeout } from 'utils/generalUtils';\nimport StravaAlert from 'components/StravaAlert';\nimport { Markup } from 'interweave';\nimport { FOLLOWING_STATUS } from 'constants/follows/following-constants';\nimport { useSafeState, useSafeDispatch } from '@strava/react-hooks';\nimport { useInviteFriendsContext } from '../../../../state/InviteFriendsContext';\n\nimport styles from './EmailTabContent.scss';\nimport LinkGoogleAccount from './components/LinkGoogleAccount';\n\nimport { t } from '../../../../utils/invite-friends-utils';\nimport GmailContactList from './components/GmailContactList/GmailContactList';\nimport {\n extractEmailsFromString,\n processContactsForUI\n} from './EmailTabContent.utils';\nimport {\n ADD_ALERT,\n CLEAR_ALERT,\n CLEAR_EMAILS,\n UPDATE_EMAILS,\n UPDATE_INVITED_EMAILS_LIST\n} from '../../../../state/InviteFriends.actions';\nimport { logError } from '../../../../../../../utils/sentry';\n\nconst EmailTabContent = () => {\n const { state, dispatch, track } = useInviteFriendsContext();\n const safeDispatch = useSafeDispatch(dispatch);\n\n const { currentAthlete, googleClientId, mocked, emails, alert } = state;\n\n const {\n authorizationStatus,\n contacts,\n requestContacts,\n disconnect\n } = useGoogle({\n clientId: googleClientId,\n mocked\n });\n\n const [processedContacts, setProcessedContacts] = useSafeState([]);\n const [isProcessingContacts, setIsProcessingContacts] = useSafeState(true);\n const [isSendingEmails, setIsSendingEmails] = useSafeState(false);\n\n const emailInputRef = useRef(null);\n\n const emailMessage = t('modal.email.message');\n\n const dispatchAlert = useSafeDispatch(\n useCallback(\n ({ severity, message, target }) => {\n dispatch({\n type: ADD_ALERT,\n payload: {\n alert: {\n severity,\n message,\n target\n }\n }\n });\n },\n [dispatch]\n )\n );\n\n useEffect(() => {\n if (authorizationStatus === AuthorizationStatus.UNAUTHORIZED) {\n dispatchAlert({\n severity: 'warning',\n message: t('modal.email.unauthorized')\n });\n } else if (authorizationStatus === AuthorizationStatus.DATA_FETCHED) {\n // extract primary entries for each contact and remove entries without email addresses\n let results = processContactsForUI(contacts);\n // eliminate duplicates\n results = uniqBy(results, 'email');\n // remove logged-in athlete from the results\n remove(results, (c) => c.email === currentAthlete.email);\n\n if (isEmpty(results)) {\n setIsProcessingContacts(false);\n } else {\n const importedEmails = results.map((c) => c.email);\n\n // find friends who are already on strava and update their entries with strava data\n createNetworkingClient()\n .post('/athletes/email_contacts_on_strava', {\n emails: importedEmails\n })\n .then((response) => {\n if (response && response.status === 200) {\n const { data: friendsAlreadyOnStrava } = response;\n friendsAlreadyOnStrava.forEach((friend) => {\n const contact = find(\n results,\n (c) => toLower(c.email) === toLower(friend.email)\n );\n if (!isNil(contact)) {\n contact.isOnStrava = true;\n contact.id = friend.id;\n contact.picture = friend.picture;\n contact.approveFollowers = friend.approve_followers;\n contact.followingStatus = friend.following_status;\n contact.name = friend.display_name;\n contact.badge = friend.badge;\n }\n });\n } else {\n dispatchAlert({\n severity: 'error',\n message: t(`modal.errors.generic`)\n });\n }\n results = orderBy(\n results,\n [\n (contact) =>\n [\n FOLLOWING_STATUS.canFollow,\n FOLLOWING_STATUS.canRequest\n ].includes(contact.followingStatus), // 1st - followable athletes\n (contact) => contact.isOnStrava, // 2nd - all other strava athletes\n (contact) => isNil(contact.name) || contact.name === '', // 3rd - google contacts with display name\n (contact) => contact.name // 4th - the rest, order all groups by display name\n ],\n ['desc', 'desc', 'asc', 'asc']\n );\n\n setProcessedContacts(results);\n })\n .catch(() => {\n dispatchAlert({\n severity: 'error',\n message: t(`modal.errors.generic`)\n });\n })\n .finally(() => {\n setIsProcessingContacts(false);\n });\n }\n }\n }, [\n authorizationStatus,\n contacts,\n currentAthlete.email,\n dispatchAlert,\n setIsProcessingContacts,\n setProcessedContacts\n ]);\n\n useEffect(() => {\n if (emailInputRef.current) {\n emailInputRef.current.focus();\n }\n }, [emailInputRef]);\n\n // show error message to athlete when something goes wrong during authorization\n useEffect(() => {\n if (authorizationStatus === AuthorizationStatus.ERROR) {\n dispatchAlert({ severity: 'error', message: t(`modal.errors.generic`) });\n }\n }, [authorizationStatus, dispatchAlert]);\n\n const alreadyOnStravaMessage = (alreadyOnStrava) => {\n let message;\n const numOnStrava = alreadyOnStrava.length;\n\n if (numOnStrava === 1) {\n message = t('modal.email.already_on_strava', {\n email_address: escape(alreadyOnStrava[0])\n });\n } else if (numOnStrava === 2) {\n message = t('modal.email.x_and_y_already', {\n email_address: escape(alreadyOnStrava[0]),\n other_email_address: escape(alreadyOnStrava[1])\n });\n } else {\n message = t('modal.email.x_and_y_and_other_already', {\n email_address: escape(alreadyOnStrava[0]),\n other_email_address: escape(alreadyOnStrava[1]),\n count: numOnStrava - 2\n });\n }\n return message;\n };\n\n const isValidEmailList = (emailList) => {\n return isNil(emailList.find((email) => !EmailValidator.validate(email)));\n };\n\n const handleFormSubmission = async (event) => {\n event.preventDefault();\n\n dispatch({ type: CLEAR_ALERT });\n const emailList = extractEmailsFromString(emails);\n\n track({\n action: 'click',\n element: 'send_email',\n properties: {\n current_tab: 'email',\n email_count: emailList.length,\n is_valid_email_list: isValidEmailList(emailList),\n emails: emailList.toString()\n }\n });\n\n // validate emails\n for (let i = 0; i < emailList.length; i++) {\n if (!EmailValidator.validate(emailList[i])) {\n dispatchAlert({\n severity: 'error',\n message: t(`modal.errors.invalid_email`),\n target: 'email-input'\n });\n emailInputRef.current.focus();\n return;\n }\n }\n\n setIsSendingEmails(true);\n createNetworkingClient()\n .post(`/invites`, {\n to: emailList,\n body: emailMessage,\n invite_dialog: true\n })\n .then(async (response) => {\n if (response.status === 200) {\n const { sent, not_sent: notSent } = response.data;\n if (!isEmpty(sent)) {\n dispatchAlert({\n severity: 'success',\n message: t('modal.email.sent')\n });\n dispatch({\n type: UPDATE_INVITED_EMAILS_LIST,\n payload: sent\n });\n dispatch({ type: CLEAR_EMAILS });\n\n // `emails sent` message auto-clears after 4 seconds\n await timeout(4000);\n\n safeDispatch({ type: CLEAR_ALERT });\n }\n if (!isEmpty(notSent)) {\n const { already_on_strava: alreadyOnStrava } = notSent;\n if (!isEmpty(alreadyOnStrava)) {\n dispatchAlert({\n severity: 'warning',\n message: (\n \n )\n });\n }\n }\n } else {\n logError(response.error);\n dispatchAlert({\n severity: 'error',\n message: t('modal.errors.generic')\n });\n }\n })\n .catch((e) => {\n logError(e);\n dispatchAlert({\n severity: 'error',\n message: t('modal.errors.generic')\n });\n })\n .finally(() => {\n setIsSendingEmails(false);\n });\n };\n\n const handleInputChange = (event) => {\n dispatch({ type: CLEAR_ALERT });\n dispatch({ type: UPDATE_EMAILS, payload: { emails: event.target.value } });\n };\n\n return (\n <>\n {!isEmpty(alert) && (\n {alert.message}\n )}\n
\n
\n

{t('modal.email.subtitle')}

\n
\n \n \n\n \n \n\n \n {isSendingEmails\n ? t('modal.email.sending')\n : t('modal.email.send')}\n \n \n
\n
\n {[\n AuthorizationStatus.AUTHORIZED,\n AuthorizationStatus.DATA_FETCHED\n ].includes(authorizationStatus) && (\n \n )}\n {[\n AuthorizationStatus.READY,\n AuthorizationStatus.ERROR,\n AuthorizationStatus.UNAUTHORIZED\n ].includes(authorizationStatus) && (\n \n )}\n {authorizationStatus === AuthorizationStatus.INITIATED && (\n
\n \n
\n )}\n
\n
\n \n );\n};\n\nexport default EmailTabContent;\n","import React, { useEffect } from 'react';\n\nimport ModalWithTabs, {\n ModalTabs,\n ModalTabList,\n ModalTab,\n ModalTabPanels,\n ModalTabPanel\n} from '@strava/ui/ModalWithTabs';\nimport { t } from '../../utils/invite-friends-utils';\nimport styles from './InviteFriendsModal.scss';\nimport { useInviteFriendsContext } from '../../state/InviteFriendsContext';\nimport {\n CLEAR_ALERT,\n CHANGE_TAB,\n CLOSE_MODAL\n} from '../../state/InviteFriends.actions';\nimport EmailTabContent from './components/EmailTabContent/EmailTabContent';\nimport FindFacebookFriends from '../../../friends/FindFacebookFriends';\nimport { INVITE_FRIENDS } from '../../../friends/utils/friendsConstants';\n\nconst InviteFriendsModal = () => {\n const { state, dispatch, track } = useInviteFriendsContext();\n const {\n isModalOpen,\n modalTabIndex,\n currentAthlete,\n fbAppId,\n fbVersion,\n locale\n } = state;\n\n useEffect(() => {\n track({\n action: 'screen_enter'\n });\n }, [track]);\n\n const handleTabsChange = (selectedTab) => {\n dispatch({ type: CHANGE_TAB, payload: { modalTabIndex: selectedTab } });\n dispatch({ type: CLEAR_ALERT });\n track({\n element: selectedTab === 0 ? 'email' : 'facebook',\n action: 'click'\n });\n };\n\n return (\n dispatch({ type: CLOSE_MODAL })}\n title={t('modal.title')}\n aria-label={t('modal.aria-label')}\n data-cy=\"invite-friends-modal\"\n >\n \n \n {t('modal.email.title')}\n {t('modal.facebook.title')}\n \n \n \n \n \n \n \n \n \n \n \n );\n};\n\nexport default InviteFriendsModal;\n","import {\n ADD_ALERT,\n CHANGE_TAB,\n CLEAR_ALERT,\n CLEAR_EMAILS,\n CLOSE_MODAL,\n OPEN_MODAL,\n UPDATE_EMAILS,\n UPDATE_FB_FRIENDS,\n UPDATE_FB_FRIEND_FOLLOWING_STATUS,\n UPDATE_INVITED_EMAILS_LIST\n} from './InviteFriends.actions';\n\nexport function reducer(state, action) {\n switch (action.type) {\n case CLOSE_MODAL: {\n return { ...state, isModalOpen: false };\n }\n case OPEN_MODAL: {\n return { ...state, isModalOpen: true };\n }\n case UPDATE_EMAILS: {\n const { emails } = action.payload;\n return {\n ...state,\n emails\n };\n }\n\n case UPDATE_INVITED_EMAILS_LIST: {\n return {\n ...state,\n invitedEmailsList: [...state.invitedEmailsList, ...action.payload]\n };\n }\n\n case UPDATE_FB_FRIENDS: {\n const { fbFriends } = action.payload;\n return {\n ...state,\n fbFriends\n };\n }\n case UPDATE_FB_FRIEND_FOLLOWING_STATUS: {\n const { id, isFollowable, followingStatus } = action.payload;\n const friend = state.fbFriends[id];\n return {\n ...state,\n fbFriends: {\n ...state.fbFriends,\n [id]: { ...friend, isFollowable, followingStatus }\n }\n };\n }\n case ADD_ALERT: {\n const { alert } = action.payload;\n return {\n ...state,\n alert\n };\n }\n case CLEAR_ALERT: {\n return {\n ...state,\n alert: {}\n };\n }\n case CHANGE_TAB: {\n const { modalTabIndex } = action.payload;\n return { ...state, modalTabIndex };\n }\n case CLEAR_EMAILS: {\n return { ...state, emails: '' };\n }\n default: {\n throw new Error(`${action.type} - not recognized`);\n }\n }\n}\n\nexport default { reducer };\n","import React, { useCallback, useEffect, useMemo, useReducer } from 'react';\nimport PropTypes from 'prop-types';\n\nimport Button from '@strava/ui/Button';\nimport cx from '@strava/ui/clsx';\nimport { camelCase } from 'lodash-es';\nimport FacebookLogo from '@strava/icons/LogosFacebookXsmall';\nimport { trackV2 } from 'utils/analytics';\nimport { useInView } from 'react-intersection-observer';\nimport styles from './InviteFriendsButton.scss';\nimport { t } from '../../utils/invite-friends-utils';\nimport InviteFriendsModal from '../InviteFriendsModal/InviteFriendsModal';\nimport InviteFriendsContext from '../../state/InviteFriendsContext';\nimport { reducer } from '../../state/InviteFriends.reducer';\nimport { OPEN_MODAL } from '../../state/InviteFriends.actions';\n\nconst InviteFriendsButton = ({\n source,\n googleClientId,\n currentAthlete,\n locale,\n fbAppId,\n fbVersion,\n mocked,\n defaultTabIndex\n}) => {\n const [intersectionObserverRef, inView] = useInView({\n threshold: 1\n });\n\n const track = useCallback(\n (fields) => {\n trackV2({\n page: 'find_and_invite',\n category: 'connections',\n ...fields,\n properties: {\n source,\n default_tab: defaultTabIndex === 0 ? 'email' : 'facebook',\n ...fields.properties\n }\n });\n },\n [defaultTabIndex, source]\n );\n\n const [state, dispatch] = useReducer(reducer, {\n isModalOpen: false,\n googleClientId,\n currentAthlete,\n locale,\n fbAppId,\n fbVersion,\n fbFriends: {},\n invitedEmailsList: [],\n mocked,\n emails: '',\n alert: {},\n modalTabIndex: defaultTabIndex\n });\n\n const providerState = useMemo(\n () => ({\n state,\n dispatch,\n track\n }),\n [state, track]\n );\n\n const element = 'invite_friends_btn';\n\n useEffect(() => {\n if (inView) {\n track({ page: source, element, action: 'screen_enter' });\n }\n }, [inView, source, track]);\n\n const config = (() => {\n let cta = t('cta.find_and_invite_friends');\n let variant = 'text';\n let logo = null;\n\n if (source === 'onboarding') {\n variant = 'primary';\n cta = t('cta.connect_with_facebook');\n logo = ;\n } else if (\n [\n 'athlete_search',\n 'follows_following',\n 'follows_suggested',\n 'follows_followers',\n 'follows_blocked'\n ].includes(source)\n ) {\n variant = 'primary';\n } else if (source === 'header_menu') {\n cta = t('cta.find_friends');\n }\n return { cta, variant, logo };\n })();\n\n const handleButtonClick = () => {\n dispatch({ type: OPEN_MODAL });\n track({ page: source, element, action: 'click' });\n };\n\n return (\n \n \n {config.logo}\n {config.cta}\n \n\n {state.isModalOpen && }\n \n );\n};\n\nInviteFriendsButton.defaultProps = {\n mocked: false,\n defaultTabIndex: 0 // defaults to first tab (email)\n};\n\nInviteFriendsButton.propTypes = {\n source: PropTypes.oneOf([\n 'athlete_search',\n 'dashboard_sidebar',\n 'follows_blocked',\n 'follows_followers',\n 'follows_following',\n 'follows_suggested',\n 'header_menu',\n 'onboarding' // facebook button on onboarding dashboard feed\n ]).isRequired,\n googleClientId: PropTypes.string.isRequired,\n mocked: PropTypes.bool,\n fbAppId: PropTypes.number.isRequired,\n fbVersion: PropTypes.string.isRequired,\n locale: PropTypes.string.isRequired,\n currentAthlete: PropTypes.shape({\n email: PropTypes.string.isRequired,\n id: PropTypes.number.isRequired\n }).isRequired,\n defaultTabIndex: PropTypes.oneOf([0, 1]) // 0 - email, 1 - FB\n};\n\nexport default InviteFriendsButton;\n","import { useEffect, useState } from 'react';\nimport createNetworkingClient from 'utils/networking-client';\nimport { injectFacebookScript } from 'externalSocialPartners';\nimport { difference, isEmpty, split } from 'lodash-es';\nimport { isDev, timeout } from 'utils/devUtils';\nimport { FOLLOWING_STATUS } from 'constants/follows/following-constants';\nimport { AuthorizationStatus } from './constants/auth-status-constants';\nimport { logError } from '../../utils/sentry';\n\n/**\n * Permissions required by FB graph endpoints - see https://developers.facebook.com/docs/permissions/reference/\n */\nconst Permissions = Object.freeze({\n FRIEND_LIST: ['user_friends']\n});\n\n/**\n *\n * Requests for user permissions before attempting to interact with Facebook Graph API.\n * eg. athletes can request for their friends which will prompt them to give strava the right permissions\n * if the permissions are missing.\n *\n * DEVELOPMENT NOTE: The FB api doesn't work locally, so we get around it with local data, while still\n * preserving the flow as much as possible\n *\n * @param {Object} arg\n * @param {number} arg.appId - Strava app client id which changes based on the environment (dev, staging and prod).\n * @param {string} arg.version - Facebook graph version.\n * @param {string} arg.locale - current athlete's locale\n * @param {boolean} arg.autoSync - whether to auto sync and try to pull FB friends before athlete clicks connect FB btn\n * (optional, defaults to true)\n * @param {string} arg.source - the page/component calling the hook\n * @returns {Object} response\n * @returns {boolean} response.ready - Whether FB javascript has been injected in the document.\n * @returns {string} response.authorizationStatus - enum value representing an athletes FB authorization state.\n * @returns {string} response.friends - Populated with a list of FB friends when requested by athlete.\n */\nconst useFacebook = ({ appId, version, locale, autoSync = true, source }) => {\n const [authorizationStatus, setAuthorizationStatus] = useState(\n AuthorizationStatus.INITIATED\n );\n const [fbFriends, setFbFriends] = useState([]);\n\n /**\n * If autoSync is on, during the first request to retrieve data from FB graph, we check if the athlete is already\n * connected to FB and if they have granted the right permissions for strava to retrieve\n * the requested data from their account without showing any FB verification/prompt UI.\n */\n const [isInitialRequest, setIsInitialRequest] = useState(true);\n\n /**\n * Inject FB graph api JS.\n *\n * Note - We need to do this for components that are mounted in haml templates since we are not\n * guaranteed that the script is available when the components attempt to request for FB graph data\n * on component mount.\n */\n useEffect(() => {\n injectFacebookScript({\n appId,\n version,\n locale,\n callback: () =>\n setAuthorizationStatus(\n autoSync\n ? AuthorizationStatus.READY // use auth status === READY to trigger call to #requestFriends\n : AuthorizationStatus.REQUEST_PERMISSIONS // use REQUEST_PERMISSIONS to show connect FB CTA\n )\n });\n }, [appId, autoSync, locale, version]);\n\n /**\n *\n * Checks to see if all the requested scopes were granted by the athlete.\n *\n * @param {Object} arg\n * @param {string} arg.grantedScopes - list of scopes that have been granted by the athlete\n * @param {string} arg.requestedScopes - list of scopes that are required by fb graph in order for strava\n * to retrieve requested user information.\n * @returns {boolean} - boolean value indicating whether the connected account has\n * all the required permissions or not.\n */\n const checkPermissions = ({ grantedScopes, requestedScopes }) => {\n if (isEmpty(grantedScopes)) {\n return false;\n }\n return difference(requestedScopes, grantedScopes).length === 0;\n };\n\n /**\n * FB graph `permissions` endpoint returns permissions in the following format\n * [{\n * \"permission\": \"user_friends\",\n * \"status\": \"granted\"\n * }, {...}, ...]\n * See - https://developers.facebook.com/docs/facebook-login/web/permissions/\n *\n * Retrieves only granted permissions and process them into an array - eg. ['user_friends', ... ]\n * which is then used by #checkPermissions in #stravaFbProxyPostPermissions\n *\n * @param {Array} data - the data from the `permissions` endpoint response\n */\n const getGrantedScopes = (data) => {\n return data.filter((p) => p.status === 'granted').map((p) => p.permission);\n };\n\n /**\n * Uses `active` as a proxy to check if the given token has all the permissions\n * that are requested.\n *\n * @param {Object} arg\n * @param {string} arg.accessToken - token for connected FB account\n * @param {Array} arg.requestedScopes - List of permissions required for the requested data to be retrieved\n * form FB graph\n * @returns {Promise} - boolean value indicating whether the connected account has\n * all the required permissions or not.\n */\n const stravaFbProxyPostPermissions = ({ accessToken, requestedScopes }) => {\n if (isDev()) {\n return new Promise((resolve) => {\n // import mock permissions data dynamically\n import('./data/facebook_permissions_sample.json').then((module) => {\n resolve(\n checkPermissions({\n grantedScopes: getGrantedScopes(module.default),\n requestedScopes\n })\n );\n });\n });\n }\n return new Promise((resolve, reject) => {\n createNetworkingClient()\n .post('/facebook_open_graph_actions/permissions', {\n access_token: accessToken\n })\n .then((response) => {\n if (response && response.status === 200) {\n resolve(\n checkPermissions({\n grantedScopes: getGrantedScopes(response.data),\n requestedScopes\n })\n );\n } else {\n reject(response.error);\n }\n })\n .catch((e) => reject(e));\n });\n };\n\n /**\n * Uses `active` as a proxy to retrieve friends data from FB graph\n *\n * @param {Object} arg\n * @param {string} arg.accessToken - token for connected FB account\n * @returns {Promise} - List of friends for the connected FB account.\n */\n const stravaFbProxyPostFriends = ({ accessToken }) => {\n if (isDev()) {\n return new Promise((resolve) => {\n // import mock friend data dynamically\n import('./data/facebook_friends_sample.json').then(async (module) => {\n await timeout(5);\n resolve(module.default);\n });\n });\n }\n return new Promise((resolve, reject) => {\n createNetworkingClient()\n .post('/facebook_open_graph_actions/friends', {\n access_token: accessToken,\n source\n })\n .then((response) => {\n if (response && response.status === 200) {\n resolve(response.data);\n } else {\n reject(response.error);\n }\n })\n .catch((e) => {\n reject(e);\n });\n });\n };\n\n /**\n * Hits Strava endpoint to get the Strava athletes associated with FB user ids\n *\n * @param {Object} arg\n * @param {Array} arg.facebookUIDs - list of facebook UIDs\n * @returns {Promise} - list of FB friends as Strava athletes\n */\n const stravaUsersFromFbIds = ({ facebookUIDs }) => {\n return new Promise((resolve, reject) => {\n createNetworkingClient()\n .post('/athletes/facebook_friends_on_strava', {\n facebook_uids: facebookUIDs\n })\n .then((response) => {\n if (response && response.status === 200) {\n resolve(response.data);\n } else {\n reject(response.error);\n }\n })\n .catch((e) => {\n reject(e);\n });\n });\n };\n\n /**\n * Uses FB graph to prompt the user to log in with the given list of\n * permissions.\n *\n * @param {Array} requestedScopes - list of permissions that are required to retrieve requested data\n * @returns {Promise} -An object with the following attributes:\n * `hasPermissions` - a boolean indicating whether the athlete authorized all permissions\n * `accessToken` - token for the connected FB account\n */\n const fbGraphApiLogin = (requestedScopes) => {\n return new Promise((resolve) => {\n const options = { scope: requestedScopes, return_scopes: true };\n if (authorizationStatus === AuthorizationStatus.REQUEST_NEW_PERMISSIONS) {\n options.auth_type = 'rerequest';\n }\n window.FB.login((response) => {\n if (response.authResponse) {\n const { accessToken, grantedScopes } = response.authResponse;\n /**\n * grantedScopes is a comma-separated list of granted scopes eg.\n * `email, user_friends ...`\n *\n * The next step generates an array of permissions eg. eg. ['user_friends', ... ]\n * which is then used by #checkPermissions\n */\n const grantedScopesList = split(grantedScopes, ',');\n resolve({\n hasPermissions: checkPermissions({\n grantedScopes: grantedScopesList,\n requestedScopes\n }),\n accessToken\n });\n } else {\n resolve({ hasPermissions: false });\n }\n }, options);\n });\n };\n\n /**\n * Checks the permissions for an already logged-in athlete and request for new permissions if the permissions\n * are insufficient. A UI dialog is used to request for more permissions if necessary.\n *\n * @param {Array} requestedScopes - list of permissions that are required to retrieve requested data\n * @returns {Promise} -An object with the following attributes:\n * `status` - enum representing the authorization status (see auth-status-constants#AuthorizationStatus)\n * `accessToken` - token for the connected FB account\n * */\n const requestPermissions = (requestedScopes) => {\n return new Promise((resolve, reject) => {\n if (autoSync && isInitialRequest) {\n /**\n * The component that is requesting data from FB has been mounted on the page, before prompting the user to\n * provide permissions, we check if they have already provided the permissions. If they are connected\n * but do not have the required permissions, then we update the status to `RequestNewPermissions` (which can\n * be used by the UI to show `Login with FB` button)\n */\n window.FB.getLoginStatus((response) => {\n // see https://developers.facebook.com/docs/facebook-login/web/ for possible status types\n if (response.status === 'connected') {\n const { accessToken } = response.authResponse;\n stravaFbProxyPostPermissions({\n accessToken,\n requestedScopes\n })\n .then((hasPermissions) => {\n const status = hasPermissions\n ? AuthorizationStatus.AUTHORIZED\n : AuthorizationStatus.REQUEST_NEW_PERMISSIONS;\n resolve({ status, accessToken });\n })\n .catch((e) => {\n reject(e);\n });\n } else {\n resolve({ status: AuthorizationStatus.REQUEST_NEW_PERMISSIONS });\n }\n });\n setIsInitialRequest(false);\n } else {\n /**\n * At this point, it has been determined that either the connected account does not have sufficient permissions or\n * an account is not connected at all.\n * The athlete is presented with the FB login button which when clicked will open a dialog requesting for\n * the required permissions. If they do not provide all of the permissions, the status will be updated to Unauthorized.\n * */\n fbGraphApiLogin(requestedScopes).then(\n ({ hasPermissions, accessToken }) => {\n const status = hasPermissions\n ? AuthorizationStatus.AUTHORIZED\n : AuthorizationStatus.UNAUTHORIZED;\n resolve({ status, accessToken });\n }\n );\n }\n });\n };\n\n /**\n * Request for friends data from FB graph\n */\n const requestFriends = () => {\n setAuthorizationStatus(AuthorizationStatus.READY); // reset auth status before flow\n requestPermissions(Permissions.FRIEND_LIST)\n .then(({ status, accessToken }) => {\n setAuthorizationStatus(status); // possible values - Authorized, UnAuthorized and NewPermissions\n if (status === AuthorizationStatus.AUTHORIZED) {\n stravaFbProxyPostFriends({ accessToken })\n .then((fbData) => {\n if (fbData.length > 0) {\n // pull out FB uids and get Strava athletes associated with them\n const facebookUIDs = fbData.map((friend) => friend.id);\n stravaUsersFromFbIds({ facebookUIDs })\n .then((stravaData) => {\n const camelCaseFriends = stravaData.map((athlete) => {\n return {\n id: athlete.id,\n picture: athlete.picture,\n followingStatus: athlete.following_status,\n isFollowable:\n athlete.following_status ===\n FOLLOWING_STATUS.canFollow ||\n athlete.following_status ===\n FOLLOWING_STATUS.canRequest,\n approveFollowers: athlete.approve_followers,\n badge: athlete.badge,\n displayName: athlete.display_name,\n subtitle: athlete.display_location\n };\n });\n setFbFriends(camelCaseFriends);\n setAuthorizationStatus(AuthorizationStatus.DATA_FETCHED);\n })\n .catch((e) => {\n // something went wrong while retrieving or processing Strava athletes from FB data\n setAuthorizationStatus(AuthorizationStatus.ERROR);\n logError(e);\n });\n } else {\n // there were no FB uids to get Strava athletes from\n setFbFriends([]);\n setAuthorizationStatus(AuthorizationStatus.DATA_FETCHED);\n }\n })\n .catch((e) => {\n // something went wrong while retrieving or processing friend data\n setAuthorizationStatus(AuthorizationStatus.ERROR);\n logError(e);\n });\n }\n })\n .catch((e) => {\n // something went wrong while requesting or checking permissions\n setAuthorizationStatus(AuthorizationStatus.ERROR);\n logError(e);\n });\n };\n\n return {\n fbFriends,\n authorizationStatus,\n requestFriends\n };\n};\n\nexport default useFacebook;\n","// extracted by mini-css-extract-plugin\nexport default {\"facebook-button\":\"LinkFacebookButton--facebook-button--+5rmt\",\"facebookButton\":\"LinkFacebookButton--facebook-button--+5rmt\",\"full-width\":\"LinkFacebookButton--full-width--WXCxj\",\"fullWidth\":\"LinkFacebookButton--full-width--WXCxj\"};","import React from 'react';\nimport PropTypes from 'prop-types';\nimport Button from '@strava/ui/Button';\nimport clsx from '@strava/ui/clsx';\nimport LogosFacebookSmall from '@strava/icons/LogosFacebookSmall';\nimport styles from './LinkFacebookButton.scss';\n\nconst LinkFacebookButton = ({ children, onClick, fullWidth, className }) => (\n \n \n {children}\n \n);\n\nLinkFacebookButton.defaultProps = {\n className: null,\n fullWidth: false\n};\n\nLinkFacebookButton.propTypes = {\n onClick: PropTypes.func.isRequired,\n children: PropTypes.node.isRequired,\n className: PropTypes.string,\n fullWidth: PropTypes.bool\n};\n\nexport default LinkFacebookButton;\n","// extracted by mini-css-extract-plugin\nexport default {\"headline\":\"LinkFacebookAccount--headline--H3YIb\"};","import React, { useEffect } from 'react';\nimport PropTypes from 'prop-types';\nimport { INVITE_FRIENDS } from '../../utils/friendsConstants';\nimport { t } from '../../utils/friendsUtils';\nimport { CLEAR_ALERT } from '../../state/friendsActions';\nimport { useFriendsContext } from '../../state/FriendsContext';\nimport LinkFacebookButton from '../shared/LinkFacebookButton';\n\nimport styles from './LinkFacebookAccount.scss';\n\n/* display connect with FB cta */\nconst LinkFacebookAccount = ({ requestFriends, authorizationStatus }) => {\n const { state, dispatch, track } = useFriendsContext();\n const { source } = state;\n const isInviteFriends = source === INVITE_FRIENDS;\n const analyticsBySource = isInviteFriends\n ? {\n element: 'connect_with_facebook',\n properties: { current_tab: 'facebook' }\n }\n : {\n element: 'connect_fb',\n properties: {}\n };\n\n useEffect(() => {\n track({\n ...analyticsBySource,\n action: 'screen_enter',\n properties: {\n ...analyticsBySource.properties,\n authorization_status: authorizationStatus\n }\n });\n // `analyticsBySource` and `track` both deliberately left out of\n // dependencies to ensure `screen_enter` event is only triggered\n // when component mounts (or `authorizationStatus` updates, though it shouldn't)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [authorizationStatus]);\n\n const handleClick = () => {\n dispatch({ type: CLEAR_ALERT });\n track({\n ...analyticsBySource,\n action: 'click',\n properties: {\n ...analyticsBySource.properties\n }\n });\n requestFriends();\n };\n\n return (\n <>\n {isInviteFriends && (\n <>\n

{t('invite_friends.title')}

\n

{t('invite_friends.message')}

\n \n )}\n \n {isInviteFriends ? t('invite_friends.button') : t('onboarding.button')}\n \n \n );\n};\n\nLinkFacebookAccount.propTypes = {\n requestFriends: PropTypes.func.isRequired,\n authorizationStatus: PropTypes.string.isRequired\n};\n\nexport default LinkFacebookAccount;\n","// extracted by mini-css-extract-plugin\nexport default {\"fb-header\":\"InviteFriendsHeader--fb-header--EzGjF\",\"fbHeader\":\"InviteFriendsHeader--fb-header--EzGjF\",\"headline\":\"InviteFriendsHeader--headline--E93dU\"};","import React, { useState } from 'react';\nimport PropTypes from 'prop-types';\nimport Button from '@strava/ui/Button';\nimport { bulkFollow } from 'api/athlete';\nimport { FOLLOWING_STATUS } from 'constants/follows/following-constants';\nimport { useFriendsContext } from '../../../state/FriendsContext';\nimport {\n CLEAR_ALERT,\n ADD_ALERT,\n UPDATE_FRIEND_FOLLOWING_STATUS\n} from '../../../state/friendsActions';\nimport { t } from '../../../utils/friendsUtils';\n\nimport styles from './InviteFriendsHeader.scss';\n\n/* invite friends version of the fb friends modal has header with `follow all` button */\nconst InviteFriendsHeader = ({ sortedFriends }) => {\n const { state, dispatch, track } = useFriendsContext();\n const [isProcessing, setIsProcessing] = useState(false);\n\n const handleFollowAll = async () => {\n setIsProcessing(true);\n dispatch({ type: CLEAR_ALERT });\n\n const followeeIds = sortedFriends\n .filter((friend) => friend.isFollowable)\n .map((friend) => friend.id);\n\n bulkFollow({ followeeIds })\n .then(({ success, followedAthleteIds }) => {\n if (success) {\n followedAthleteIds.forEach((id) => {\n const friend = state.friends[id];\n dispatch({\n type: UPDATE_FRIEND_FOLLOWING_STATUS,\n payload: {\n id: friend.id,\n isFollowable: false,\n followingStatus: friend.approveFollowers\n ? FOLLOWING_STATUS.pending\n : FOLLOWING_STATUS.following\n }\n });\n });\n } else {\n dispatch({\n type: ADD_ALERT,\n payload: {\n alert: { severity: 'error', message: t(`errors.generic`) }\n }\n });\n }\n track({\n element: 'follow_all_btn',\n action: 'click',\n properties: {\n current_tab: 'facebook',\n follow_all_count: followeeIds.length,\n follow_all_status: success ? 'success' : 'error'\n }\n });\n })\n .finally(() => setIsProcessing(false));\n };\n\n return (\n
\n

\n {t('invite_friends.friends_on_strava')}\n

\n {sortedFriends.length > 0 && (\n // follow all\n friend.isFollowable)\n }\n onClick={handleFollowAll}\n >\n {t('cta_actions.follow_all')}\n \n )}\n
\n );\n};\n\nInviteFriendsHeader.propTypes = {\n sortedFriends: PropTypes.arrayOf(\n PropTypes.shape({\n id: PropTypes.number,\n picture: PropTypes.string,\n followingStatus: PropTypes.oneOf([\n FOLLOWING_STATUS.canFollow,\n FOLLOWING_STATUS.canRequest,\n FOLLOWING_STATUS.pending,\n FOLLOWING_STATUS.following\n ]),\n isFollowable: PropTypes.bool,\n approveFollowers: PropTypes.bool,\n badge: PropTypes.string,\n displayName: PropTypes.string,\n displayLocation: PropTypes.string\n })\n ).isRequired\n};\n\nexport default InviteFriendsHeader;\n","import React, { useEffect, useRef } from 'react';\nimport { sortBy } from 'lodash-es';\nimport { useFriendsContext } from '../../state/FriendsContext';\nimport { t } from '../../utils/friendsUtils';\nimport { INVITE_FRIENDS, ONBOARDING } from '../../utils/friendsConstants';\nimport InviteFriendsHeader from './InviteFriendsHeader';\nimport FriendList from '../shared/FriendList';\nimport FriendListItem from '../shared/FriendListItem';\n\n/**\n * display list of friends with CTA to follow them\n *\n * see the readme (app/javascript/components/shared/friends/README.md) for how to use this component\n * */\nconst FacebookFriendList = () => {\n const { state, track } = useFriendsContext();\n const { friends, source } = state;\n const sortedFriends = sortBy(Object.values(friends), 'sortedIndex');\n const friendCount = sortedFriends.length;\n const onboardingFriendCountMessage = (() => {\n switch (friendCount) {\n case 0:\n return t('friend_list.no_fb_matches');\n case 1:\n return t('friend_list.one_friend_to_follow');\n default:\n return t('friend_list.more_friends_to_follow', {\n friend_count: friendCount\n });\n }\n })();\n\n // friends will change as friends get followed, so we\n // want to track the initial screen_enter\n const initialScreenEnter = useRef(true);\n useEffect(() => {\n if (initialScreenEnter.current) {\n const analytics = {\n element: 'facebook_friends_list',\n action: 'screen_enter',\n properties: {\n friends_count: friendCount\n }\n };\n if (source === INVITE_FRIENDS) {\n analytics.properties.current_tab = 'facebook';\n }\n track(analytics);\n initialScreenEnter.current = false;\n }\n }, [friendCount, source, track]);\n\n return (\n <>\n {source === INVITE_FRIENDS && (\n \n )}\n {source === ONBOARDING &&

{onboardingFriendCountMessage}

}\n {source === INVITE_FRIENDS && friendCount === 0 && (\n

{t('friend_list.no_fb_friends_on_strava')}

\n )}\n {friendCount > 0 && (\n \n {sortedFriends.map((friend) => (\n \n ))}\n \n )}\n \n );\n};\n\nexport default FacebookFriendList;\n","// extracted by mini-css-extract-plugin\nexport default {\"fb-panel\":\"FindFacebookFriends--fb-panel--xEyA+\",\"fbPanel\":\"FindFacebookFriends--fb-panel--xEyA+\",\"no-background\":\"FindFacebookFriends--no-background--2gPup\",\"noBackground\":\"FindFacebookFriends--no-background--2gPup\",\"center-spinner\":\"FindFacebookFriends--center-spinner--Wnal7\",\"centerSpinner\":\"FindFacebookFriends--center-spinner--Wnal7\"};","import React, { useEffect, useMemo, useReducer } from 'react';\nimport PropTypes from 'prop-types';\nimport { orderBy } from 'lodash-es';\nimport Spinner from '@strava/ui/Spinner';\nimport useFacebook from 'hooks/externalSocialPartners/useFacebook';\nimport { AuthorizationStatus } from 'hooks/externalSocialPartners/constants/auth-status-constants';\nimport StravaAlert from 'components/StravaAlert';\nimport { INVITE_FRIENDS, ONBOARDING } from '../utils/friendsConstants';\nimport { t } from '../utils/friendsUtils';\nimport FriendsContext from '../state/FriendsContext';\nimport { reducer } from '../state/friendsReducer';\nimport { ADD_ALERT, UPDATE_FRIENDS } from '../state/friendsActions';\nimport LinkFacebookAccount from '../components/LinkFacebookAccount';\nimport FacebookFriendList from '../components/FacebookFriendList';\n\nimport styles from './FindFacebookFriends.scss';\n\nconst FindFacebookFriends = ({\n track,\n currentAthlete,\n isVisible, // InviteFriends modal -> modalTablIndex === 1\n source, // 'invite_friends' or 'onboarding'\n fbApiProps,\n onFollowingFriendsChange\n}) => {\n const [state, dispatch] = useReducer(reducer, {\n currentAthlete,\n source,\n friends: {},\n followedFriends: {},\n alert: null,\n onFollowingFriendsChange\n });\n const { alert } = state;\n\n const providerState = useMemo(() => ({ state, dispatch, track }), [\n state,\n track\n ]);\n\n // don't have requestFriends be called as soon as FB script is ready. let athlete opt-in\n // to connecting FB in onboarding by clicking connect FB button\n const autoSync = source !== ONBOARDING;\n\n const { fbFriends, authorizationStatus, requestFriends } = useFacebook({\n ...fbApiProps,\n autoSync,\n source\n });\n\n useEffect(() => {\n // When component is visible, call requestFriends as soon as FB script is ready.\n // If user is not already logged in to FB, or if user is logged in to FB but\n // doesn't have the right permissions, auth status will be REQUEST_NEW_PERMISSIONS\n // and we show them the LinkFacebookAccount view\n if (\n autoSync &&\n isVisible &&\n authorizationStatus === AuthorizationStatus.READY\n ) {\n requestFriends();\n }\n // requestFriends deliberately left out to prevent multiple calls to this\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [authorizationStatus, isVisible]);\n\n // save friends to the shared state\n useEffect(() => {\n if (fbFriends.length > 0) {\n // INVITE_FRIENDS: list followable friends before friends already being followed\n // and sort alphabetically by name\n // ONBOARDING: list only followable friends\n const processedFriends =\n source === INVITE_FRIENDS\n ? orderBy(fbFriends, ['isFollowable', 'displayName'], ['desc', 'asc'])\n : fbFriends.filter((friend) => friend.isFollowable);\n // map friends array to object with the strava ids as the keys\n // save the index of the friend's position in the sorted array\n const friends = Object.fromEntries(\n processedFriends.map((friend, index) => [\n friend.id,\n { ...friend, sortedIndex: index }\n ])\n );\n dispatch({\n type: UPDATE_FRIENDS,\n payload: { friends }\n });\n }\n }, [dispatch, fbFriends, source]);\n\n useEffect(() => {\n if (authorizationStatus === AuthorizationStatus.ERROR) {\n // show error message to athlete when something goes wrong during authorization\n dispatch({\n type: ADD_ALERT,\n payload: {\n alert: { severity: 'error', message: t('errors.fb_error') }\n }\n });\n } else if (\n source === INVITE_FRIENDS &&\n authorizationStatus === AuthorizationStatus.UNAUTHORIZED\n ) {\n // INVITE_FRIENDS ONLY:\n // show warning message to athlete if they don't authorize FB permissions\n dispatch({\n type: ADD_ALERT,\n payload: {\n alert: {\n severity: 'warning',\n message: t('errors.unauthorized')\n }\n }\n });\n }\n }, [authorizationStatus, dispatch, source]);\n\n return (\n \n
\n {source === INVITE_FRIENDS && alert && (\n {alert.message}\n )}\n {source === ONBOARDING &&

{t('onboarding.message')}

}\n {[\n AuthorizationStatus.REQUEST_PERMISSIONS,\n AuthorizationStatus.REQUEST_NEW_PERMISSIONS,\n AuthorizationStatus.ERROR,\n AuthorizationStatus.UNAUTHORIZED\n ].includes(authorizationStatus) && (\n \n )}\n {source === ONBOARDING && alert && (\n \n {alert.message}\n \n )}\n {authorizationStatus === AuthorizationStatus.DATA_FETCHED && (\n \n )}\n {[\n AuthorizationStatus.INITIATED,\n AuthorizationStatus.READY,\n AuthorizationStatus.AUTHORIZED\n ].includes(authorizationStatus) && (\n
\n \n
\n )}\n
\n
\n );\n};\n\nFindFacebookFriends.defaultProps = {\n isVisible: true,\n onFollowingFriendsChange: () => {}\n};\n\nFindFacebookFriends.propTypes = {\n track: PropTypes.func.isRequired,\n currentAthlete: PropTypes.shape({\n id: PropTypes.number\n }).isRequired,\n fbApiProps: PropTypes.shape({\n appId: PropTypes.number,\n version: PropTypes.string,\n locale: PropTypes.string\n }).isRequired,\n source: PropTypes.oneOf([INVITE_FRIENDS, ONBOARDING]).isRequired,\n isVisible: PropTypes.bool,\n onFollowingFriendsChange: PropTypes.func\n};\n\nexport default FindFacebookFriends;\n","// extracted by mini-css-extract-plugin\nexport default {\"friend-list\":\"FriendList--friend-list--vRDGD\",\"friendList\":\"FriendList--friend-list--vRDGD\",\"scroll-shadow\":\"FriendList--scroll-shadow--0GFRE\",\"scrollShadow\":\"FriendList--scroll-shadow--0GFRE\"};","import React, { useEffect } from 'react';\nimport PropTypes from 'prop-types';\nimport clsx from '@strava/ui/clsx';\nimport { useFriendsContext } from '../../../state/FriendsContext';\n\nimport styles from './FriendList.scss';\n\nconst FriendList = ({ children }) => {\n const { state } = useFriendsContext();\n const { followedFriends, onFollowingFriendsChange } = state;\n\n useEffect(() => {\n onFollowingFriendsChange(followedFriends);\n }, [onFollowingFriendsChange, followedFriends]);\n\n return (\n \n {children}\n \n );\n};\n\nFriendList.propTypes = {\n children: PropTypes.node.isRequired\n};\n\nexport default FriendList;\n","// extracted by mini-css-extract-plugin\nexport default {\"list-row\":\"AthleteInfo--list-row--bM5xg\",\"listRow\":\"AthleteInfo--list-row--bM5xg\",\"athlete-metadata\":\"AthleteInfo--athlete-metadata--qzuP+\",\"athleteMetadata\":\"AthleteInfo--athlete-metadata--qzuP+\",\"name-and-subtitle\":\"AthleteInfo--name-and-subtitle--t+CuJ\",\"nameAndSubtitle\":\"AthleteInfo--name-and-subtitle--t+CuJ\",\"grayed-out\":\"AthleteInfo--grayed-out--ay4VH\",\"grayedOut\":\"AthleteInfo--grayed-out--ay4VH\"};","import React from 'react';\nimport PropTypes from 'prop-types';\nimport Avatar from '@strava/ui/Avatar';\nimport clsx from '@strava/ui/clsx';\nimport { isMobile } from 'utils/generalUtils';\nimport { useFriendsContext } from '../../../state/FriendsContext';\nimport { INVITE_FRIENDS } from '../../../utils/friendsConstants';\n\nimport styles from './AthleteInfo.scss';\n\nconst AthleteInfo = ({ friend, children }) => {\n const { state } = useFriendsContext();\n return (\n
  • \n \n \n
    \n

    {friend.displayName}

    \n

    {friend.subtitle}

    \n
    \n \n {children}\n
  • \n );\n};\n\nAthleteInfo.propTypes = {\n friend: PropTypes.shape({\n isFollowable: PropTypes.bool,\n picture: PropTypes.string,\n badge: PropTypes.string,\n displayName: PropTypes.string,\n subtitle: PropTypes.string\n }).isRequired,\n children: PropTypes.node.isRequired\n};\n\nexport default AthleteInfo;\n","import { useEffect, useState } from 'react';\nimport {\n FOLLOW_ACTIONS,\n FOLLOWING_STATUS\n} from 'constants/follows/following-constants';\n\nexport const useCtaAction = (friend) => {\n const { approveFollowers, followingStatus } = friend;\n const [cta, setCta] = useState(FOLLOW_ACTIONS.follow);\n\n useEffect(() => {\n if (followingStatus === FOLLOWING_STATUS.pending) {\n setCta(FOLLOW_ACTIONS.followRequested);\n } else if (followingStatus === FOLLOWING_STATUS.following) {\n setCta(FOLLOW_ACTIONS.following);\n } else {\n setCta(\n approveFollowers\n ? FOLLOW_ACTIONS.requestToFollow\n : FOLLOW_ACTIONS.follow\n );\n }\n }, [approveFollowers, followingStatus]);\n\n return cta;\n};\n\nexport default useCtaAction;\n","import React, { useState } from 'react';\nimport PropTypes from 'prop-types';\nimport Button from '@strava/ui/Button';\nimport { FOLLOWING_STATUS } from 'constants/follows/following-constants';\nimport { followAthlete, unfollowAthlete } from 'api/athlete';\nimport AthleteInfo from '../AthleteInfo';\nimport { useFriendsContext } from '../../../state/FriendsContext';\nimport {\n ADD_ALERT,\n CLEAR_ALERT,\n ADD_ATHLETE,\n REMOVE_ATHLETE,\n UPDATE_FRIEND_FOLLOWING_STATUS\n} from '../../../state/friendsActions';\nimport { t } from '../../../utils/friendsUtils';\nimport {\n INVITE_FRIENDS,\n SUGGESTED_FRIENDS\n} from '../../../utils/friendsConstants';\nimport useCtaAction from '../../../utils/useCtaAction';\n\nconst FriendListItem = ({ id }) => {\n // retrieve friend from shared state\n const { state, dispatch, track } = useFriendsContext();\n const { friends, currentAthlete, source } = state;\n const friend = friends[id];\n const [isProcessing, setIsProcessing] = useState(false);\n\n const cta = useCtaAction(friend);\n\n const handleFollowAthlete = () => {\n followAthlete({\n followerId: currentAthlete.id,\n followingId: friend.id\n })\n .then((status) => {\n const analytics = {\n element: source === INVITE_FRIENDS ? `${cta}_btn` : cta,\n action: 'click',\n properties: {\n athlete_id: friend.id,\n following_status: status\n }\n };\n if (source === INVITE_FRIENDS) {\n analytics.properties.current_tab = 'facebook';\n }\n track(analytics);\n if (status === FOLLOWING_STATUS.error) {\n dispatch({\n type: ADD_ALERT,\n payload: {\n alert: { severity: 'error', message: t(`errors.generic`) }\n }\n });\n } else {\n dispatch({\n type: UPDATE_FRIEND_FOLLOWING_STATUS,\n payload: {\n id: friend.id,\n isFollowable: false,\n followingStatus: status\n }\n });\n dispatch({\n type: ADD_ATHLETE,\n payload: { friend }\n });\n }\n })\n .finally(() => {\n setIsProcessing(false);\n });\n };\n\n const handleUnfollowAthlete = () => {\n unfollowAthlete({\n followerId: currentAthlete.id,\n followingId: friend.id\n })\n .then((success) => {\n track({\n action: 'click',\n element: 'unfollow',\n properties: {\n athlete_id: friend.id,\n success\n }\n });\n if (success) {\n dispatch({\n type: UPDATE_FRIEND_FOLLOWING_STATUS,\n payload: {\n id: friend.id,\n isFollowable: true,\n followingStatus: friend.approveFollowers\n ? FOLLOWING_STATUS.canRequest\n : FOLLOWING_STATUS.canFollow\n }\n });\n dispatch({\n type: REMOVE_ATHLETE,\n payload: {\n id: friend.id\n }\n });\n } else {\n dispatch({\n type: ADD_ALERT,\n payload: {\n alert: { severity: 'error', message: t(`errors.generic`) }\n }\n });\n }\n })\n .finally(() => {\n setIsProcessing(false);\n });\n };\n\n const handleBtnClick = () => {\n setIsProcessing(true);\n dispatch({ type: CLEAR_ALERT });\n\n if (friend.isFollowable) {\n handleFollowAthlete();\n } else {\n handleUnfollowAthlete();\n }\n };\n\n return (\n \n \n {t(`cta_actions.${cta}`)}\n \n \n );\n};\n\nFriendListItem.propTypes = {\n id: PropTypes.number.isRequired\n};\n\nexport default FriendListItem;\n","import { useContext, createContext } from 'react';\n\nconst FriendsContext = createContext();\nFriendsContext.displayName = 'FriendsContext';\n\nexport const useFriendsContext = () => {\n const context = useContext(FriendsContext);\n\n if (!context) {\n throw new Error(\n 'useFriendsContext must be used within the FriendsContext.Provider'\n );\n }\n\n return context;\n};\n\nexport default FriendsContext;\n","export const ADD_ALERT = 'ADD_ALERT';\nexport const CLEAR_ALERT = 'CLEAR_ALERT';\nexport const ADD_ATHLETE = 'ADD_ATHLETE';\nexport const REMOVE_ATHLETE = 'REMOVE_ATHLETE';\nexport const UPDATE_FRIENDS = 'UPDATE_FRIENDS';\nexport const UPDATE_FRIEND_FOLLOWING_STATUS = 'UPDATE_FRIEND_FOLLOWING_STATUS';\n\nexport default {\n ADD_ALERT,\n CLEAR_ALERT,\n ADD_ATHLETE,\n REMOVE_ATHLETE,\n UPDATE_FRIENDS,\n UPDATE_FRIEND_FOLLOWING_STATUS\n};\n","import {\n ADD_ALERT,\n CLEAR_ALERT,\n ADD_ATHLETE,\n REMOVE_ATHLETE,\n UPDATE_FRIENDS,\n UPDATE_FRIEND_FOLLOWING_STATUS\n} from './friendsActions';\n\nexport const reducer = (state, action) => {\n switch (action.type) {\n case ADD_ALERT: {\n const { alert } = action.payload;\n return {\n ...state,\n alert\n };\n }\n case CLEAR_ALERT: {\n return {\n ...state,\n alert: null\n };\n }\n case ADD_ATHLETE: {\n const { friend } = action.payload;\n return {\n ...state,\n followedFriends: {\n ...state.followedFriends,\n [friend.id]: friend\n }\n };\n }\n case REMOVE_ATHLETE: {\n const { id } = action.payload;\n const { [id]: _, ...rest } = state.followedFriends;\n return {\n ...state,\n followedFriends: { ...rest }\n };\n }\n case UPDATE_FRIENDS: {\n const { friends } = action.payload;\n return {\n ...state,\n friends\n };\n }\n case UPDATE_FRIEND_FOLLOWING_STATUS: {\n const { id, isFollowable, followingStatus } = action.payload;\n const friend = state.friends[id];\n return {\n ...state,\n friends: {\n ...state.friends,\n [id]: { ...friend, isFollowable, followingStatus }\n }\n };\n }\n default:\n throw new Error(`${action.type} not recognized`);\n }\n};\n\nexport default { reducer };\n","// sources where the friend list is mounted\nexport const ONBOARDING = 'onboarding';\nexport const INVITE_FRIENDS = 'invite_friends';\nexport const SUGGESTED_FRIENDS = 'suggested_friends';\n\nexport default { ONBOARDING, INVITE_FRIENDS, SUGGESTED_FRIENDS };\n","import I18n from 'utils/I18n';\n\nexport const t = (key, params) =>\n I18n.t(`components.friends.${key}`, { ...params });\n\nexport default { t };\n","export const FOLLOWING_STATUS = Object.freeze({\n following: 'following',\n pending: 'pending',\n error: 'error',\n canFollow: 'can_follow',\n canRequest: 'can_request'\n});\n\nexport const FOLLOW_ACTIONS = Object.freeze({\n add: 'add',\n followRequested: 'follow_requested',\n following: 'following',\n requestToFollow: 'request_to_follow',\n follow: 'follow'\n});\n","/**\n * AUTHORIZED - the athlete has granted all the necessary permissions and is ready to fetch data\n * DATA_FETCHED - the athlete has granted all the necessary permissions and data has been fetched successfully\n * ERROR - an error occurred while fetching or processing data\n * INITIATED - social hook has been attached to the component\n * READY - external partner JS has been injected or verified to be present on the page\n * REQUEST_PERMISSION - athlete needs to grant permissions for the request to take place\n * REQUEST_NEW_PERMISSION - the athlete needs to grant more permissions for the request to proceed\n * UNAUTHORIZED - the athlete has denied giving permissions after being prompted to do so\n */\nexport const AuthorizationStatus = Object.freeze({\n AUTHORIZED: 'AUTHORIZED',\n DATA_FETCHED: 'DATA_FETCHED',\n ERROR: 'ERROR',\n INITIATED: 'INITIATED',\n READY: 'READY',\n REQUEST_PERMISSIONS: 'REQUEST_PERMISSIONS',\n REQUEST_NEW_PERMISSIONS: 'REQUEST_NEW_PERMISSIONS',\n UNAUTHORIZED: 'UNAUTHORIZED'\n});\n\nexport default { AuthorizationStatus };\n"],"names":["followAthlete","followerId","followingId","Promise","resolve","createNetworkingClient","post","follow","follower_id","following_id","then","response","status","StatusCodes","data","approved","FOLLOWING_STATUS","catch","bulkFollow","followeeIds","followee_ids","success","ids","followed_athlete_ids","followedAthleteIds","e","logError","unfollowAthlete","delete","headers","Accept","getSuggestedFollows","callsite","reject","get","params","error","I18nPrefix","t","key","I18n","InviteFriendsContext","React","useInviteFriendsContext","displayName","ADD_ALERT","CHANGE_TAB","CLEAR_ALERT","CLEAR_EMAILS","CLOSE_MODAL","OPEN_MODAL","UPDATE_EMAILS","UPDATE_FB_FRIENDS","UPDATE_FB_FRIEND_FOLLOWING_STATUS","UPDATE_INVITED_EMAILS_LIST","PEOPLE_BASE_URL","clientId","mocked","useState","contacts","setContacts","undefined","token","setToken","AuthorizationStatus","authorizationStatus","setAuthorizationStatus","handleSignInContactsScope","tokenResponse","access_token","accessToken","requestedScope","window","google","accounts","oauth2","hasGrantedAllScopes","Authorization","url","alt","connections","c","timeout","revoke","useEffect","injectGoogleScript","id","cancel","requestContacts","client","scope","callback","initTokenClient","client_id","initializeGsiTokenClient","requestAccessToken","disconnect","isNil","dispatch","track","className","styles","onClick","element","action","properties","current_tab","type","label","getPrimaryEntry","entries","primary","find","entry","metadata","isEmpty","processContactsForUI","processedContacts","map","index","names","emailAddresses","photos","displayContact","isOnStrava","email","value","name","picture","compact","extractEmailsFromString","emails","split","toLower","trim","contact","FOLLOW_ACTIONS","disabled","config","setConfig","followingStatus","currentFollowingStatus","setCurrentFollowingStatus","isLoading","setIsLoading","state","currentAthlete","invitedEmailsList","approveFollowers","includes","prev","disabledTextStyle","Avatar","src","size","badge","clsx","Button","variant","athlete_id","separator","payload","concat","alert","severity","message","finally","handleBtnClick","ResultsFeed","results","Spinner","length","searchKeyword","setSearchKeyword","filterResults","setFilterResults","initialResults","useRef","current","contacts_count","already_on_strava_count","filter","onChange","keyword","target","toLowerCase","placeholder","safeDispatch","useSafeDispatch","googleClientId","useGoogle","useSafeState","setProcessedContacts","isProcessingContacts","setIsProcessingContacts","isSendingEmails","setIsSendingEmails","emailInputRef","emailMessage","dispatchAlert","useCallback","uniqBy","remove","importedEmails","friendsAlreadyOnStrava","forEach","friend","approve_followers","following_status","display_name","orderBy","focus","alreadyOnStravaMessage","alreadyOnStrava","numOnStrava","email_address","escape","other_email_address","count","isValidEmailList","emailList","EmailValidator","handleFormSubmission","event","preventDefault","email_count","is_valid_email_list","toString","i","to","body","invite_dialog","sent","notSent","not_sent","already_on_strava","noWrap","content","StravaAlert","onSubmit","htmlFor","ref","isModalOpen","modalTabIndex","fbAppId","fbVersion","locale","ModalWithTabs","isOpen","onDismiss","title","selectedTab","FindFacebookFriends","source","INVITE_FRIENDS","fbApiProps","appId","version","isVisible","reducer","fbFriends","isFollowable","Error","InviteFriendsButton","defaultTabIndex","useInView","threshold","intersectionObserverRef","inView","fields","trackV2","page","category","default_tab","useReducer","providerState","useMemo","cta","logo","cx","camelCase","defaultProps","Permissions","Object","freeze","FRIEND_LIST","autoSync","setFbFriends","isInitialRequest","setIsInitialRequest","injectFacebookScript","s","checkPermissions","grantedScopes","requestedScopes","difference","getGrantedScopes","p","permission","requestPermissions","FB","getLoginStatus","authResponse","isDev","module","default","stravaFbProxyPostPermissions","hasPermissions","options","return_scopes","auth_type","login","grantedScopesList","fbGraphApiLogin","requestFriends","stravaFbProxyPostFriends","fbData","facebookUIDs","f","facebook_uids","stravaUsersFromFbIds","stravaData","camelCaseFriends","athlete","subtitle","display_location","LinkFacebookButton","children","fullWidth","LogosFacebookSmall","useFriendsContext","isInviteFriends","analyticsBySource","authorization_status","sortedFriends","isProcessing","setIsProcessing","handleFollowAll","friends","UPDATE_FRIEND_FOLLOWING_STATUS","follow_all_count","follow_all_status","some","sortBy","values","friendCount","onboardingFriendCountMessage","friend_count","initialScreenEnter","analytics","friends_count","ONBOARDING","FriendList","FriendListItem","onFollowingFriendsChange","followedFriends","useFacebook","processedFriends","fromEntries","sortedIndex","UPDATE_FRIENDS","FriendsContext","isMobile","style","flexShrink","setCta","useCtaAction","SUGGESTED_FRIENDS","ADD_ATHLETE","REMOVE_ATHLETE","createContext","context","useContext","rest","following","pending","canFollow","canRequest","add","followRequested","requestToFollow","AUTHORIZED","DATA_FETCHED","ERROR","INITIATED","READY","REQUEST_PERMISSIONS","REQUEST_NEW_PERMISSIONS","UNAUTHORIZED"],"sourceRoot":""}