SPACEBROWSER_INTERFACE/interface_081225/extractMap/sources_from_map/App.tsx

437 lines
13 KiB
TypeScript

import 'antd/dist/antd.less'
import { AutoSaveProvider } from 'components/AutoSaveProvider'
import ModulesProvider from 'components/ModulesProvider'
import NotSupportSizeBrowser from 'components/NotSupportSizeBrowser'
import Loading from 'components/Loading'
import { ExchangeRateDefault } from 'constants/exchange-rate'
import 'fonts/SFProDisplay/stylesheet.scss'
import { useNotificationRequest, useWindowSize } from 'hooks'
import { useQuery } from 'hooks/useQuery'
import Cookies from 'js-cookie'
import LogRocket from 'logrocket'
import { getCorrelationId } from '@komi-app/correlation'
import moment from 'moment'
import { updateTalentProfileActions } from 'pages/BecomeATalent/Reducer/action'
import React, { useEffect, useState } from 'react'
import { isMobile } from 'react-device-detect'
import { useDispatch } from 'react-redux'
import { Link, useHistory, useLocation } from 'react-router-dom'
import { useTypedSelector } from 'redux/rootReducer'
import {
detectLocalCurrencyActions,
getExchangeRateActions,
getExchangeRateUSDActions,
getUserProfileActions
} from 'redux/User/actions'
import {
selectIsAdminLogin,
selectIsCheckLocalCurrency,
selectUserData,
selectUserState
} from 'redux/User/selector'
import Routes from 'routes'
import { KOMI_TALENT_CURRENCY } from 'services/UserService'
import { IframeMessage } from 'utils/iframeMessage'
import 'video.js/dist/video-js.css'
import './App.scss'
import '@komi-app/creator-ui/dist/style.css'
import './i18n'
import { webviewMessage } from './utils/webviewMessage'
import '@komi-app/components/dist/index.css'
import { UserAgentProvider } from 'context/user-agent'
import config from 'config'
import { initProfileId, linkRedirectService } from 'services'
import { useLinkRedirect } from 'context/LinkRedirectContext'
import { TALENT_PROFILE_ID } from 'constants/profile'
import {
KOMI_SPOTIFY_ACCESS_TOKEN,
KOMI_SPOTIFY_REFRESH_TOKEN
} from './services/SpotifyService'
import useMobileView from 'hooks/useMobileView'
import { setupLink, ToastContextProvider } from '@komi-app/creator-ui'
import {
FLAGS,
IfFeature,
isReady,
useFeatureIsOn,
useFlags
} from '@komi-app/flags-sdk'
import When from '@komi-app/when'
import {
CreatorTrackingProvider,
CreatorTrackingProps
} from '@komi-app/analytics-sdk'
import { useIntercomMessengerWidget } from './hooks/useIntercomMessengerWidget'
import ErrorBoundary from 'components/ErrorBoundary/ErrorBoundary'
setupLink(Link)
LogRocket.init(config.logRocket.id, {
rootHostname: 'komi.io',
dom: {
privateAttributeBlocklist: ['data-no-track']
}
})
const KOMI_FIRST_SETUP_ONBOARDING = 'KOMI_FIRST_SETUP_ONBOARDING'
function isMobileEnabledPath(path: string | undefined) {
if (!path) {
return false
}
return (
path === '/admin/send-login-link' || path.startsWith('/admin/onboarding')
)
}
const App = () => {
const detectCurrency = useTypedSelector(selectIsCheckLocalCurrency)
const isAdminLogin = useTypedSelector(selectIsAdminLogin)
const user = useTypedSelector(selectUserData)
const userState = useTypedSelector(selectUserState)
const location = useLocation()
const query = useQuery()
//TODO: replace the below accessTokens
const accessToken = query?.get('access_token') // redirect from admin
const token = query?.get('token') // redirect from consumer
const talentProfileId = query?.get('talentProfileId') // redirect from consumer
const router = useHistory()
const [isNotSetup, setIsNotSetup] = useState(false)
const [firstRoute, setFirstRoute] = useState<any>()
const { width } = useWindowSize()
const { setLinkRedirect } = useLinkRedirect()
useFlags(
gb => {
if (user)
gb.setAttributes({
...gb.getAttributes(),
tier: user.tier
})
},
[user]
)
const isLinkRedirectOn = useFeatureIsOn(FLAGS.LINK_REDIRECT)
const isSpotifyFixOn = useFeatureIsOn(FLAGS.FIX_GS46_SPOTIFY_AUTH_FIX)
const mobileView = useMobileView()
const [shouldDisableScreenSizeError, setShouldDisableScreenSizeError] =
useState(false)
const isNotSupport = mobileView ? false : width && width < 1040
const useAnalyticsSDK = useFeatureIsOn(FLAGS.USE_ANALYTICS_SDK_TALENT)
const isAnonIdFixOn = useFeatureIsOn(FLAGS.FIX_SB_1274_ANON_ID_RESET_TALENT)
const shouldRemoveOldAnonIdCookie = useFeatureIsOn(
FLAGS.FIX_SB_1274_ANON_ID_REMOVE_OLD_COOKIE
)
const [tracking, setTracking] = useState<CreatorTrackingProps>()
const ready = isReady()
useIntercomMessengerWidget()
useEffect(() => {
setShouldDisableScreenSizeError(
isMobileEnabledPath(router?.location?.pathname)
)
}, [router.location.pathname])
useEffect(() => {
setFirstRoute(router?.location?.pathname)
if (
firstRoute !== '/collaborator-login' || !isNotSupport
? !user
: !talentProfileId
) {
return
}
const checkSetupStatus = () => {
if (!isNotSupport && user) {
const { talentProfile } = user
const isOnboarding =
talentProfile?.onboardSteps &&
Object.keys(talentProfile?.onboardSteps).every(
(key: string) => !(talentProfile?.onboardSteps as any)[key]
)
if (isOnboarding && talentProfile) {
const result = localStorage.getItem(KOMI_FIRST_SETUP_ONBOARDING)
const data = result ? JSON.parse(result) : {}
if (!data.items?.includes(talentProfile?.id)) {
localStorage.setItem(
KOMI_FIRST_SETUP_ONBOARDING,
JSON.stringify({
items: [...(data.items || []), talentProfile?.id]
})
)
setIsNotSetup(true)
return
}
}
return
}
if (talentProfileId) {
const result = localStorage.getItem(KOMI_FIRST_SETUP_ONBOARDING)
const data = result ? JSON.parse(result) : {}
if (!data.items?.includes(talentProfileId)) {
localStorage.setItem(
KOMI_FIRST_SETUP_ONBOARDING,
JSON.stringify({
items: [...(data.items || []), talentProfileId]
})
)
setIsNotSetup(true)
return
}
}
}
checkSetupStatus()
}, [user, firstRoute, isNotSupport])
useNotificationRequest()
const dispatch = useDispatch()
moment.updateLocale('en-gb', {
weekdaysMin: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
})
useEffect(() => {
if (!ready || isSpotifyFixOn) {
return
}
if (Cookies.get(KOMI_SPOTIFY_ACCESS_TOKEN)) {
Cookies.remove(KOMI_SPOTIFY_ACCESS_TOKEN)
}
if (Cookies.get(KOMI_SPOTIFY_REFRESH_TOKEN)) {
Cookies.remove(KOMI_SPOTIFY_REFRESH_TOKEN)
}
}, [isSpotifyFixOn, ready])
useEffect(() => {
// prevents using talent.*
// or local.komi.ci
const { location } = window
if (
location.hostname.startsWith('talent.') ||
(location.origin === config.service.url && location.pathname === '/')
) {
window.location.href = config.client.url
}
}, [])
useEffect(() => {
if (user) {
const profileId = user.talentProfile?.id
if (profileId) {
initProfileId(profileId)
Cookies.set(TALENT_PROFILE_ID, profileId as string)
}
if (!isAnonIdFixOn) {
;(window as any)?.analytics?.reset()
}
if (shouldRemoveOldAnonIdCookie) {
Cookies.remove('ajs_anonymous_id')
localStorage.removeItem('ajs_anonymous_id')
}
;(window as any)?.analytics?.identify(user.id, {
Id: user.id,
Name: `${user.talentProfile?.firstName} ${user.talentProfile?.lastName}`,
Email: user.email,
Platform: webviewMessage.isWebView()
? 'Webview'
: isMobile
? 'Responsive'
: 'Web'
})
}
}, [user])
useEffect(() => {
const correlationId =
sessionStorage.getItem('correlationId') || getCorrelationId()
sessionStorage.setItem('correlationId', correlationId!)
LogRocket.identify(
correlationId!,
user
? {
name: `${user.talentProfile?.firstName} ${user.talentProfile?.lastName}`,
email: user?.email || ''
}
: undefined
)
}, [user])
useEffect(() => {
if (ready) dispatch(getUserProfileActions.REQUEST())
}, [router, dispatch, accessToken, token, ready])
useEffect(() => {
if (ready && user && useAnalyticsSDK && !tracking) {
const userId = user.id!
const profileId = user.talentProfile?.id!
const profileName =
`${user.talentProfile?.firstName} ${user.talentProfile?.lastName}`.trim()
const userFullname = `${user.firstName} ${user.lastName}`.trim()
const handle = user.talentProfile?.user?.username!
const talentId = user.talentProfile?.user?.id!
setTracking({
handle,
profileId,
profileName,
userFullname,
userId,
talentId
})
}
}, [user, tracking, ready])
// obsolete?
useEffect(() => {
if (detectCurrency) return
if (user && user.localCurrency) {
Cookies.set(KOMI_TALENT_CURRENCY, user.localCurrency, {
expires: 999999
})
dispatch(getExchangeRateActions.REQUEST(user.localCurrency))
dispatch(getExchangeRateUSDActions.REQUEST())
dispatch(detectLocalCurrencyActions.SUCCESS(true))
} else if (user && !user.localCurrency && !isAdminLogin) {
// we will not detect local with expert
if (IframeMessage.inIframe()) return
;(async () => {
const currency = ExchangeRateDefault.localCurrency
Cookies.set(KOMI_TALENT_CURRENCY, currency, { expires: 999999 })
dispatch(
updateTalentProfileActions.REQUEST({
localCurrency: currency,
userState: userState
})
)
dispatch(getExchangeRateActions.REQUEST(currency))
dispatch(getExchangeRateUSDActions.REQUEST())
})()
}
return () => {}
}, [dispatch, user, detectCurrency])
// for Admin (obsolete?)
useEffect(() => {
const query = new URLSearchParams(location.search)
const localCurrency: any = query?.get('localCurrency')
if (!user || !localCurrency || !IframeMessage.inIframe()) return
Cookies.set(KOMI_TALENT_CURRENCY, localCurrency, { expires: 999999 })
dispatch(getExchangeRateActions.REQUEST(localCurrency))
dispatch(getExchangeRateUSDActions.REQUEST())
}, [user])
useEffect(() => {
if (!isLinkRedirectOn) return
const loadExistingRedirect = async () => {
if (user && user.talentProfile) {
const result = await linkRedirectService().getLinkRedirect()
let isExistingRedirectExpired = true
if (
result?.linkRedirect?.scheduled_end_timestamp != undefined &&
result?.linkRedirect?.scheduled_timezone != undefined
) {
const linkRedirectDateTimeNow = moment().tz(
result?.linkRedirect?.scheduled_timezone
)
if (
linkRedirectDateTimeNow.isBefore(
result?.linkRedirect?.scheduled_end_timestamp
)
) {
isExistingRedirectExpired = false
}
}
setLinkRedirect({
link: isExistingRedirectExpired ? '' : result?.linkRedirect?.link,
scheduledTimezone: isExistingRedirectExpired
? ''
: result?.linkRedirect?.scheduled_timezone,
scheduledStartTimestamp: isExistingRedirectExpired
? moment().valueOf()
: moment(result?.linkRedirect?.scheduled_start_timestamp).valueOf(),
scheduledEndTimestamp: isExistingRedirectExpired
? moment().add(1, 'days').valueOf()
: moment(result?.linkRedirect?.scheduled_end_timestamp).valueOf(),
isEnabled: isExistingRedirectExpired
? false
: result?.linkRedirect?.is_enabled
})
}
}
loadExistingRedirect()
}, [setLinkRedirect, user?.talentProfile, isLinkRedirectOn])
return (
<ErrorBoundary>
<CreatorTrackingProvider context={tracking}>
<IfFeature
feature={FLAGS.FEAT_SB_331_COPY_URL_PROMPT}
enabled={
<When
value={ready}
then={
isNotSupport && !shouldDisableScreenSizeError ? (
<NotSupportSizeBrowser isNotSetup={isNotSetup} />
) : (
<UserAgentProvider>
<ToastContextProvider>
<AutoSaveProvider>
<ModulesProvider>
<Routes />
</ModulesProvider>
</AutoSaveProvider>
</ToastContextProvider>
</UserAgentProvider>
)
}
otherwise={<Loading />}
/>
}
disabled={
<When
value={ready}
then={
isNotSupport && !shouldDisableScreenSizeError ? (
<NotSupportSizeBrowser isNotSetup={isNotSetup} />
) : (
<UserAgentProvider>
<AutoSaveProvider>
<ModulesProvider>
<ToastContextProvider>
<Routes />
</ToastContextProvider>
</ModulesProvider>
</AutoSaveProvider>
</UserAgentProvider>
)
}
otherwise={<Loading />}
/>
}
/>
</CreatorTrackingProvider>
</ErrorBoundary>
)
}
export default App