Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b29968d014 | ||
|
|
a07556b87d | ||
|
|
5b551af25a | ||
|
|
69f6ca2635 |
1
CODEOWNERS
Normal file
1
CODEOWNERS
Normal file
@ -0,0 +1 @@
|
|||||||
|
* @uniswap/web-admins
|
||||||
@ -3,27 +3,27 @@
|
|||||||
"relation": ["delegate_permission/common.handle_all_urls"],
|
"relation": ["delegate_permission/common.handle_all_urls"],
|
||||||
"target": {
|
"target": {
|
||||||
"namespace": "android_app",
|
"namespace": "android_app",
|
||||||
"package_name": "com.uniswap",
|
"package_name": "com.uniswap.mobile",
|
||||||
"sha256_cert_fingerprints":
|
"sha256_cert_fingerprints":
|
||||||
["97:A5:81:51:DA:AF:8F:6E:65:3A:90:1E:82:12:6C:FB:61:2D:36:C7:CF:20:61:6B:A3:4C:52:CA:BC:58:43:8E", "F9:E9:E3:F0:04:28:66:62:81:44:50:7E:D6:A9:5F:B9:65:39:02:70:1D:13:74:15:D3:E1:A3:1B:D4:38:3A:1F"]
|
["49:D9:3D:5D:FB:AA:64:A4:64:80:85:0F:39:A8:C1:D9:25:D3:D4:BC:8E:6B:1F:45:0C:EA:AF:B1:0C:27:DF:B8", "F9:E9:E3:F0:04:28:66:62:81:44:50:7E:D6:A9:5F:B9:65:39:02:70:1D:13:74:15:D3:E1:A3:1B:D4:38:3A:1F"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"relation": ["delegate_permission/common.handle_all_urls"],
|
"relation": ["delegate_permission/common.handle_all_urls"],
|
||||||
"target": {
|
"target": {
|
||||||
"namespace": "android_app",
|
"namespace": "android_app",
|
||||||
"package_name": "com.uniswap.beta",
|
"package_name": "com.uniswap.mobile.beta",
|
||||||
"sha256_cert_fingerprints":
|
"sha256_cert_fingerprints":
|
||||||
["E5:39:87:DC:4D:FD:4C:1B:A6:74:36:7D:3A:3B:6B:ED:9E:B3:66:89:92:8A:1B:B8:FC:1B:22:56:56:B4:46:A3", "54:4B:62:33:17:9B:5F:A8:E6:5D:D3:A6:E5:9D:80:5F:A5:02:7F:E2:14:B8:C1:7A:AC:4B:8D:E0:65:49:87:41"]
|
["75:41:9C:2D:01:4A:88:4E:8D:C6:EF:E5:51:54:28:6B:99:05:31:43:AD:84:B4:EB:39:28:B8:C3:C4:CE:48:E3", "54:4B:62:33:17:9B:5F:A8:E6:5D:D3:A6:E5:9D:80:5F:A5:02:7F:E2:14:B8:C1:7A:AC:4B:8D:E0:65:49:87:41"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"relation": ["delegate_permission/common.handle_all_urls"],
|
"relation": ["delegate_permission/common.handle_all_urls"],
|
||||||
"target": {
|
"target": {
|
||||||
"namespace": "android_app",
|
"namespace": "android_app",
|
||||||
"package_name": "com.uniswap.dev",
|
"package_name": "com.uniswap.mobile.dev",
|
||||||
"sha256_cert_fingerprints":
|
"sha256_cert_fingerprints":
|
||||||
["5A:6D:23:50:2F:1E:0D:01:DC:96:65:F3:3A:18:4C:4C:8C:67:E0:09:99:9B:B1:9B:BF:44:99:D0:D1:D0:FC:5E", "02:E6:1C:76:8C:75:C3:78:C8:8C:FE:7B:2E:8F:4B:E1:FA:47:F2:F6:1A:DB:57:69:4A:41:99:C6:71:2C:AB:E3", "FA:C6:17:45:DC:09:03:78:6F:B9:ED:E6:2A:96:2B:39:9F:73:48:F0:BB:6F:89:9B:83:32:66:75:91:03:3B:9C"]
|
["45:F8:15:02:C5:4F:AD:82:E7:51:F0:9C:D1:CA:77:C8:C9:BF:06:A6:D9:5A:55:4F:9E:B8:5F:81:33:2B:D0:DB", "02:E6:1C:76:8C:75:C3:78:C8:8C:FE:7B:2E:8F:4B:E1:FA:47:F2:F6:1A:DB:57:69:4A:41:99:C6:71:2C:AB:E3", "FA:C6:17:45:DC:09:03:78:6F:B9:ED:E6:2A:96:2B:39:9F:73:48:F0:BB:6F:89:9B:83:32:66:75:91:03:3B:9C"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
3710
src/locales/af-ZA.po
Normal file
3710
src/locales/af-ZA.po
Normal file
File diff suppressed because it is too large
Load Diff
3710
src/locales/ar-SA.po
Normal file
3710
src/locales/ar-SA.po
Normal file
File diff suppressed because it is too large
Load Diff
3710
src/locales/ca-ES.po
Normal file
3710
src/locales/ca-ES.po
Normal file
File diff suppressed because it is too large
Load Diff
3710
src/locales/cs-CZ.po
Normal file
3710
src/locales/cs-CZ.po
Normal file
File diff suppressed because it is too large
Load Diff
3710
src/locales/da-DK.po
Normal file
3710
src/locales/da-DK.po
Normal file
File diff suppressed because it is too large
Load Diff
3710
src/locales/de-DE.po
Normal file
3710
src/locales/de-DE.po
Normal file
File diff suppressed because it is too large
Load Diff
3710
src/locales/el-GR.po
Normal file
3710
src/locales/el-GR.po
Normal file
File diff suppressed because it is too large
Load Diff
3710
src/locales/es-ES.po
Normal file
3710
src/locales/es-ES.po
Normal file
File diff suppressed because it is too large
Load Diff
3710
src/locales/fi-FI.po
Normal file
3710
src/locales/fi-FI.po
Normal file
File diff suppressed because it is too large
Load Diff
3710
src/locales/fr-FR.po
Normal file
3710
src/locales/fr-FR.po
Normal file
File diff suppressed because it is too large
Load Diff
3710
src/locales/he-IL.po
Normal file
3710
src/locales/he-IL.po
Normal file
File diff suppressed because it is too large
Load Diff
3711
src/locales/hu-HU.po
Normal file
3711
src/locales/hu-HU.po
Normal file
File diff suppressed because it is too large
Load Diff
3710
src/locales/id-ID.po
Normal file
3710
src/locales/id-ID.po
Normal file
File diff suppressed because it is too large
Load Diff
3710
src/locales/it-IT.po
Normal file
3710
src/locales/it-IT.po
Normal file
File diff suppressed because it is too large
Load Diff
3710
src/locales/ja-JP.po
Normal file
3710
src/locales/ja-JP.po
Normal file
File diff suppressed because it is too large
Load Diff
3710
src/locales/ko-KR.po
Normal file
3710
src/locales/ko-KR.po
Normal file
File diff suppressed because it is too large
Load Diff
3710
src/locales/nl-NL.po
Normal file
3710
src/locales/nl-NL.po
Normal file
File diff suppressed because it is too large
Load Diff
3710
src/locales/no-NO.po
Normal file
3710
src/locales/no-NO.po
Normal file
File diff suppressed because it is too large
Load Diff
3710
src/locales/pl-PL.po
Normal file
3710
src/locales/pl-PL.po
Normal file
File diff suppressed because it is too large
Load Diff
3710
src/locales/pt-BR.po
Normal file
3710
src/locales/pt-BR.po
Normal file
File diff suppressed because it is too large
Load Diff
3710
src/locales/pt-PT.po
Normal file
3710
src/locales/pt-PT.po
Normal file
File diff suppressed because it is too large
Load Diff
3710
src/locales/ro-RO.po
Normal file
3710
src/locales/ro-RO.po
Normal file
File diff suppressed because it is too large
Load Diff
3710
src/locales/ru-RU.po
Normal file
3710
src/locales/ru-RU.po
Normal file
File diff suppressed because it is too large
Load Diff
3710
src/locales/sl-SI.po
Normal file
3710
src/locales/sl-SI.po
Normal file
File diff suppressed because it is too large
Load Diff
3710
src/locales/sr-SP.po
Normal file
3710
src/locales/sr-SP.po
Normal file
File diff suppressed because it is too large
Load Diff
3710
src/locales/sv-SE.po
Normal file
3710
src/locales/sv-SE.po
Normal file
File diff suppressed because it is too large
Load Diff
3710
src/locales/sw-TZ.po
Normal file
3710
src/locales/sw-TZ.po
Normal file
File diff suppressed because it is too large
Load Diff
3710
src/locales/th-TH.po
Normal file
3710
src/locales/th-TH.po
Normal file
File diff suppressed because it is too large
Load Diff
3710
src/locales/tr-TR.po
Normal file
3710
src/locales/tr-TR.po
Normal file
File diff suppressed because it is too large
Load Diff
3710
src/locales/uk-UA.po
Normal file
3710
src/locales/uk-UA.po
Normal file
File diff suppressed because it is too large
Load Diff
3710
src/locales/vi-VN.po
Normal file
3710
src/locales/vi-VN.po
Normal file
File diff suppressed because it is too large
Load Diff
3710
src/locales/zh-CN.po
Normal file
3710
src/locales/zh-CN.po
Normal file
File diff suppressed because it is too large
Load Diff
3710
src/locales/zh-TW.po
Normal file
3710
src/locales/zh-TW.po
Normal file
File diff suppressed because it is too large
Load Diff
@ -5,7 +5,7 @@ import ErrorBoundary from 'components/ErrorBoundary'
|
|||||||
import Loader from 'components/Icons/LoadingSpinner'
|
import Loader from 'components/Icons/LoadingSpinner'
|
||||||
import NavBar, { PageTabs } from 'components/NavBar'
|
import NavBar, { PageTabs } from 'components/NavBar'
|
||||||
import { UK_BANNER_HEIGHT, UK_BANNER_HEIGHT_MD, UK_BANNER_HEIGHT_SM, UkBanner } from 'components/NavBar/UkBanner'
|
import { UK_BANNER_HEIGHT, UK_BANNER_HEIGHT_MD, UK_BANNER_HEIGHT_SM, UkBanner } from 'components/NavBar/UkBanner'
|
||||||
import { useFeatureFlagsIsLoaded } from 'featureFlags'
|
import { FeatureFlag, useFeatureFlagsIsLoaded } from 'featureFlags'
|
||||||
import { useUniswapXDefaultEnabled } from 'featureFlags/flags/uniswapXDefault'
|
import { useUniswapXDefaultEnabled } from 'featureFlags/flags/uniswapXDefault'
|
||||||
import { useAtom } from 'jotai'
|
import { useAtom } from 'jotai'
|
||||||
import { useBag } from 'nft/hooks/useBag'
|
import { useBag } from 'nft/hooks/useBag'
|
||||||
@ -16,7 +16,7 @@ import { useAppSelector } from 'state/hooks'
|
|||||||
import { AppState } from 'state/reducer'
|
import { AppState } from 'state/reducer'
|
||||||
import { RouterPreference } from 'state/routing/types'
|
import { RouterPreference } from 'state/routing/types'
|
||||||
import { useRouterPreference, useUserOptedOutOfUniswapX } from 'state/user/hooks'
|
import { useRouterPreference, useUserOptedOutOfUniswapX } from 'state/user/hooks'
|
||||||
import { StatsigProvider, StatsigUser } from 'statsig-react'
|
import { StatsigProvider, StatsigUser, useGate } from 'statsig-react'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
import DarkModeQueryParamReader from 'theme/components/DarkModeQueryParamReader'
|
import DarkModeQueryParamReader from 'theme/components/DarkModeQueryParamReader'
|
||||||
import { useIsDarkMode } from 'theme/components/ThemeToggle'
|
import { useIsDarkMode } from 'theme/components/ThemeToggle'
|
||||||
@ -97,12 +97,8 @@ export default function App() {
|
|||||||
const location = useLocation()
|
const location = useLocation()
|
||||||
const { pathname } = location
|
const { pathname } = location
|
||||||
const currentPage = getCurrentPageFromLocation(pathname)
|
const currentPage = getCurrentPageFromLocation(pathname)
|
||||||
const isDarkMode = useIsDarkMode()
|
|
||||||
const [routerPreference] = useRouterPreference()
|
|
||||||
const [scrollY, setScrollY] = useState(0)
|
const [scrollY, setScrollY] = useState(0)
|
||||||
const scrolledState = scrollY > 0
|
const scrolledState = scrollY > 0
|
||||||
const isUniswapXDefaultEnabled = useUniswapXDefaultEnabled()
|
|
||||||
const userOptedOutOfUniswapX = useUserOptedOutOfUniswapX()
|
|
||||||
const routerConfig = useRouterConfig()
|
const routerConfig = useRouterConfig()
|
||||||
|
|
||||||
const originCountry = useAppSelector((state: AppState) => state.user.originCountry)
|
const originCountry = useAppSelector((state: AppState) => state.user.originCountry)
|
||||||
@ -122,53 +118,6 @@ export default function App() {
|
|||||||
}
|
}
|
||||||
}, [searchParams, setShouldDisableNFTRoutes])
|
}, [searchParams, setShouldDisableNFTRoutes])
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
// User properties *must* be set before sending corresponding event properties,
|
|
||||||
// so that the event contains the correct and up-to-date user properties.
|
|
||||||
user.set(CustomUserProperties.USER_AGENT, navigator.userAgent)
|
|
||||||
user.set(CustomUserProperties.BROWSER, getBrowser())
|
|
||||||
user.set(CustomUserProperties.SCREEN_RESOLUTION_HEIGHT, window.screen.height)
|
|
||||||
user.set(CustomUserProperties.SCREEN_RESOLUTION_WIDTH, window.screen.width)
|
|
||||||
user.set(CustomUserProperties.GIT_COMMIT_HASH, process.env.REACT_APP_GIT_COMMIT_HASH ?? 'unknown')
|
|
||||||
|
|
||||||
// Service Worker analytics
|
|
||||||
const isServiceWorkerInstalled = Boolean(window.navigator.serviceWorker?.controller)
|
|
||||||
const isServiceWorkerHit = Boolean((window as any).__isDocumentCached)
|
|
||||||
const serviceWorkerProperty = isServiceWorkerInstalled ? (isServiceWorkerHit ? 'hit' : 'miss') : 'uninstalled'
|
|
||||||
|
|
||||||
const pageLoadProperties = { service_worker: serviceWorkerProperty }
|
|
||||||
sendInitializationEvent(SharedEventName.APP_LOADED, pageLoadProperties)
|
|
||||||
const sendWebVital =
|
|
||||||
(metric: string) =>
|
|
||||||
({ delta }: Metric) =>
|
|
||||||
sendAnalyticsEvent(SharedEventName.WEB_VITALS, { ...pageLoadProperties, [metric]: delta })
|
|
||||||
getCLS(sendWebVital('cumulative_layout_shift'))
|
|
||||||
getFCP(sendWebVital('first_contentful_paint_ms'))
|
|
||||||
getFID(sendWebVital('first_input_delay_ms'))
|
|
||||||
getLCP(sendWebVital('largest_contentful_paint_ms'))
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
user.set(CustomUserProperties.DARK_MODE, isDarkMode)
|
|
||||||
}, [isDarkMode])
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
// If we're not in the transition period to UniswapX opt-out, set the router preference to whatever is specified.
|
|
||||||
if (!isUniswapXDefaultEnabled) {
|
|
||||||
user.set(CustomUserProperties.ROUTER_PREFERENCE, routerPreference)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// In the transition period, override the stored API preference to UniswapX if the user hasn't opted out.
|
|
||||||
if (routerPreference === RouterPreference.API && !userOptedOutOfUniswapX) {
|
|
||||||
user.set(CustomUserProperties.ROUTER_PREFERENCE, RouterPreference.X)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, the user has opted out or their preference is UniswapX/client, so set the preference to whatever is specified.
|
|
||||||
user.set(CustomUserProperties.ROUTER_PREFERENCE, routerPreference)
|
|
||||||
}, [routerPreference, isUniswapXDefaultEnabled, userOptedOutOfUniswapX])
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const scrollListener = () => {
|
const scrollListener = () => {
|
||||||
setScrollY(window.scrollY)
|
setScrollY(window.scrollY)
|
||||||
@ -221,6 +170,7 @@ export default function App() {
|
|||||||
api: process.env.REACT_APP_STATSIG_PROXY_URL,
|
api: process.env.REACT_APP_STATSIG_PROXY_URL,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
<UserPropertyUpdater />
|
||||||
{renderUkBannner && <UkBanner />}
|
{renderUkBannner && <UkBanner />}
|
||||||
<HeaderWrapper transparent={isHeaderTransparent} bannerIsVisible={renderUkBannner} scrollY={scrollY}>
|
<HeaderWrapper transparent={isHeaderTransparent} bannerIsVisible={renderUkBannner} scrollY={scrollY}>
|
||||||
<NavBar blur={isHeaderTransparent} />
|
<NavBar blur={isHeaderTransparent} />
|
||||||
@ -255,3 +205,63 @@ export default function App() {
|
|||||||
</ErrorBoundary>
|
</ErrorBoundary>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function UserPropertyUpdater() {
|
||||||
|
const isDarkMode = useIsDarkMode()
|
||||||
|
|
||||||
|
const [routerPreference] = useRouterPreference()
|
||||||
|
const userOptedOutOfUniswapX = useUserOptedOutOfUniswapX()
|
||||||
|
const isUniswapXDefaultEnabled = useUniswapXDefaultEnabled()
|
||||||
|
const { isLoading: isUniswapXDefaultLoading } = useGate(FeatureFlag.uniswapXDefaultEnabled)
|
||||||
|
const rehydrated = useAppSelector((state) => state._persist.rehydrated)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// User properties *must* be set before sending corresponding event properties,
|
||||||
|
// so that the event contains the correct and up-to-date user properties.
|
||||||
|
user.set(CustomUserProperties.USER_AGENT, navigator.userAgent)
|
||||||
|
user.set(CustomUserProperties.BROWSER, getBrowser())
|
||||||
|
user.set(CustomUserProperties.SCREEN_RESOLUTION_HEIGHT, window.screen.height)
|
||||||
|
user.set(CustomUserProperties.SCREEN_RESOLUTION_WIDTH, window.screen.width)
|
||||||
|
user.set(CustomUserProperties.GIT_COMMIT_HASH, process.env.REACT_APP_GIT_COMMIT_HASH ?? 'unknown')
|
||||||
|
|
||||||
|
// Service Worker analytics
|
||||||
|
const isServiceWorkerInstalled = Boolean(window.navigator.serviceWorker?.controller)
|
||||||
|
const isServiceWorkerHit = Boolean((window as any).__isDocumentCached)
|
||||||
|
const serviceWorkerProperty = isServiceWorkerInstalled ? (isServiceWorkerHit ? 'hit' : 'miss') : 'uninstalled'
|
||||||
|
|
||||||
|
const pageLoadProperties = { service_worker: serviceWorkerProperty }
|
||||||
|
sendInitializationEvent(SharedEventName.APP_LOADED, pageLoadProperties)
|
||||||
|
const sendWebVital =
|
||||||
|
(metric: string) =>
|
||||||
|
({ delta }: Metric) =>
|
||||||
|
sendAnalyticsEvent(SharedEventName.WEB_VITALS, { ...pageLoadProperties, [metric]: delta })
|
||||||
|
getCLS(sendWebVital('cumulative_layout_shift'))
|
||||||
|
getFCP(sendWebVital('first_contentful_paint_ms'))
|
||||||
|
getFID(sendWebVital('first_input_delay_ms'))
|
||||||
|
getLCP(sendWebVital('largest_contentful_paint_ms'))
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
user.set(CustomUserProperties.DARK_MODE, isDarkMode)
|
||||||
|
}, [isDarkMode])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (isUniswapXDefaultLoading || !rehydrated) return
|
||||||
|
|
||||||
|
// If we're not in the transition period to UniswapX opt-out, set the router preference to whatever is specified.
|
||||||
|
if (!isUniswapXDefaultEnabled) {
|
||||||
|
user.set(CustomUserProperties.ROUTER_PREFERENCE, routerPreference)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// In the transition period, override the stored API preference to UniswapX if the user hasn't opted out.
|
||||||
|
if (routerPreference === RouterPreference.API && !userOptedOutOfUniswapX) {
|
||||||
|
user.set(CustomUserProperties.ROUTER_PREFERENCE, RouterPreference.X)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, the user has opted out or their preference is UniswapX/client, so set the preference to whatever is specified.
|
||||||
|
user.set(CustomUserProperties.ROUTER_PREFERENCE, routerPreference)
|
||||||
|
}, [routerPreference, isUniswapXDefaultEnabled, userOptedOutOfUniswapX, isUniswapXDefaultLoading, rehydrated])
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user