262 lines
7.3 KiB
TypeScript
262 lines
7.3 KiB
TypeScript
import { useState, useEffect, ChangeEvent, useCallback } from 'react'
|
|
import { Box, Flex, Label, Select } from 'theme-ui'
|
|
import Page from 'popup/components/Page'
|
|
import Checkbox from 'popup/components/CheckBox'
|
|
import DebouncedInput from 'popup/components/DebouncedInput'
|
|
import detachDebugger from 'utils/detachDebugger'
|
|
import countryLocales from 'utils/countryLocales'
|
|
import configurations from 'utils/configurations'
|
|
import getIp from 'utils/getIp'
|
|
import { ipData } from 'types'
|
|
import { RotateCw } from 'react-feather'
|
|
|
|
interface LocationPageProps {
|
|
tab: string
|
|
}
|
|
|
|
const LocationPage = ({ tab }: LocationPageProps) => {
|
|
const [browserDefault, setBrowserDefault] = useState(true)
|
|
const [ipData, setIpData] = useState<ipData>()
|
|
const [ipInfo, setIpInfo] = useState('loading...')
|
|
const [timezone, setTimezone] = useState('')
|
|
const [locale, setLocale] = useState('')
|
|
const [lat, setLatitude] = useState('')
|
|
const [lon, setLongitude] = useState('')
|
|
const [configuration, setConfiguration] = useState('custom')
|
|
|
|
const reloadIp = useCallback(() => {
|
|
setIpInfo('loading...')
|
|
getIp()
|
|
.then((ipDataRes) => {
|
|
setIpData(ipDataRes)
|
|
setIpInfo(`${getFlagEmoji(ipDataRes.countryCode)} ${ipDataRes.query}`)
|
|
})
|
|
.catch(() => {
|
|
setIpInfo('error')
|
|
})
|
|
}, [])
|
|
|
|
useEffect(() => {
|
|
reloadIp()
|
|
}, [reloadIp])
|
|
|
|
useEffect(() => {
|
|
chrome.storage.local.get(
|
|
[
|
|
'locationBrowserDefault',
|
|
'configuration',
|
|
'timezone',
|
|
'locale',
|
|
'lat',
|
|
'lon',
|
|
],
|
|
(storage) => {
|
|
storage.configuration && setConfiguration(storage.configuration)
|
|
storage.locationBrowserDefault !== undefined &&
|
|
setBrowserDefault(storage.locationBrowserDefault)
|
|
if (storage.configuration === 'matchIp' && ipData) {
|
|
setTimezone(ipData.timezone)
|
|
setLocale(countryLocales[ipData.countryCode].locale)
|
|
setLatitude(`${ipData.lat}`)
|
|
setLongitude(`${ipData.lon}`)
|
|
chrome.storage.local.set({
|
|
timezone: ipData.timezone,
|
|
locale: countryLocales[ipData.countryCode].locale,
|
|
lat: ipData.lat,
|
|
lon: ipData.lon,
|
|
})
|
|
} else {
|
|
storage.timezone && setTimezone(storage.timezone)
|
|
storage.locale && setLocale(storage.locale)
|
|
storage.lat && setLatitude(storage.lat)
|
|
storage.lon && setLongitude(storage.lon)
|
|
}
|
|
}
|
|
)
|
|
}, [ipData])
|
|
|
|
const changeBrowserDefault = () => {
|
|
detachDebugger()
|
|
chrome.storage.local.set({
|
|
locationBrowserDefault: !browserDefault,
|
|
})
|
|
setBrowserDefault(!browserDefault)
|
|
}
|
|
|
|
const changeConfiguration = (e: ChangeEvent<HTMLSelectElement>) => {
|
|
detachDebugger()
|
|
setConfiguration(e.target.value)
|
|
chrome.storage.local.set({
|
|
configuration: e.target.value,
|
|
})
|
|
if (e.target.value === 'matchIp') {
|
|
if (ipData) {
|
|
setTimezone(ipData.timezone)
|
|
setLocale(countryLocales[ipData.countryCode].locale)
|
|
setLatitude(`${ipData.lat}`)
|
|
setLongitude(`${ipData.lon}`)
|
|
chrome.storage.local.set({
|
|
timezone: ipData.timezone,
|
|
locale: countryLocales[ipData.countryCode].locale,
|
|
lat: ipData.lat,
|
|
lon: ipData.lon,
|
|
})
|
|
}
|
|
} else if (e.target.value === 'custom') {
|
|
setTimezone('')
|
|
setLocale('')
|
|
setLatitude('')
|
|
setLongitude('')
|
|
chrome.storage.local.set({
|
|
timezone: '',
|
|
locale: '',
|
|
lat: '',
|
|
lon: '',
|
|
})
|
|
} else {
|
|
setTimezone(configurations[e.target.value].timezone)
|
|
setLocale(configurations[e.target.value].locale)
|
|
setLatitude(configurations[e.target.value].lat)
|
|
setLongitude(configurations[e.target.value].lon)
|
|
chrome.storage.local.set({
|
|
timezone: configurations[e.target.value].timezone,
|
|
locale: configurations[e.target.value].locale,
|
|
lat: configurations[e.target.value].lat,
|
|
lon: configurations[e.target.value].lon,
|
|
})
|
|
}
|
|
}
|
|
|
|
const changeInputText = () => {
|
|
if (configuration !== 'custom') {
|
|
setConfiguration('custom')
|
|
chrome.storage.local.set({
|
|
configuration: 'custom',
|
|
})
|
|
}
|
|
}
|
|
|
|
const getFlagEmoji = (countryCode: string) => {
|
|
const codePoints = countryCode
|
|
.toUpperCase()
|
|
.split('')
|
|
.map((char) => 127397 + char.charCodeAt(0))
|
|
return String.fromCodePoint(...codePoints)
|
|
}
|
|
|
|
return (
|
|
<Page isCurrentTab={tab === 'location'} title={'Location Data'}>
|
|
<Checkbox
|
|
title="Use browser default"
|
|
onChange={changeBrowserDefault}
|
|
checked={browserDefault}
|
|
/>
|
|
<Box
|
|
sx={{
|
|
opacity: browserDefault ? '0.5' : '1',
|
|
pointerEvents: browserDefault ? 'none' : 'auto',
|
|
}}
|
|
>
|
|
<Flex
|
|
sx={{
|
|
border: '1px solid',
|
|
mt: '12px',
|
|
mb: '8px',
|
|
borderRadius: '4px',
|
|
borderColor: 'grey',
|
|
alignItems: 'center',
|
|
p: '4px 8px',
|
|
}}
|
|
>
|
|
<Box sx={{ fontWeight: '700', width: '100px', pr: '8px' }}>
|
|
IP Address
|
|
</Box>
|
|
<Box
|
|
sx={{
|
|
width: '188px',
|
|
whiteSpace: 'nowrap',
|
|
overflow: 'hidden',
|
|
textOverflow: 'ellipsis',
|
|
}}
|
|
title={ipData?.query}
|
|
>
|
|
{ipInfo}
|
|
</Box>
|
|
<RotateCw
|
|
size={20}
|
|
sx={{
|
|
cursor: 'pointer',
|
|
}}
|
|
onClick={() => {
|
|
reloadIp()
|
|
}}
|
|
/>
|
|
</Flex>
|
|
<Label htmlFor="configuration">Configuration</Label>
|
|
<Select
|
|
name="configuration"
|
|
value={configuration}
|
|
onChange={changeConfiguration}
|
|
mb={'8px'}
|
|
>
|
|
<option value="matchIp">Match IP Address</option>
|
|
<option value="custom">Custom</option>
|
|
<optgroup label="Locations">
|
|
{Object.keys(configurations).map((key) => (
|
|
<option value={key} key={key}>
|
|
{configurations[key].name}
|
|
</option>
|
|
))}
|
|
</optgroup>
|
|
</Select>
|
|
<DebouncedInput
|
|
name="timezone"
|
|
title="Timezone"
|
|
value={timezone}
|
|
setValue={setTimezone}
|
|
onChange={changeInputText}
|
|
/>
|
|
<DebouncedInput
|
|
name="locale"
|
|
title="Locale"
|
|
value={locale}
|
|
setValue={setLocale}
|
|
onChange={changeInputText}
|
|
/>
|
|
<Flex sx={{ gap: '12px' }}>
|
|
<DebouncedInput
|
|
name="lat"
|
|
title="Latitude"
|
|
value={lat}
|
|
setValue={setLatitude}
|
|
onChange={changeInputText}
|
|
type="number"
|
|
/>
|
|
<DebouncedInput
|
|
name="lon"
|
|
title="Longitude"
|
|
value={lon}
|
|
setValue={setLongitude}
|
|
onChange={changeInputText}
|
|
mb="12px"
|
|
type="number"
|
|
/>
|
|
</Flex>
|
|
</Box>
|
|
<Box
|
|
sx={{
|
|
color: 'text',
|
|
mb: '8px',
|
|
fontSize: '11px',
|
|
position: 'fixed',
|
|
bottom: '0',
|
|
}}
|
|
>
|
|
Vytal does not change your IP address. To change your IP address you
|
|
will need a VPN or proxy.
|
|
</Box>
|
|
</Page>
|
|
)
|
|
}
|
|
|
|
export default LocationPage
|