forked from
jollywhoppers.com/witchsky.app
Bluesky app fork with some witchin' additions 馃挮
1import {type LocationGeocodedAddress} from 'expo-location'
2
3import {logger} from '#/geolocation/logger'
4import {type Geolocation} from '#/geolocation/types'
5
6/**
7 * Maps full US region names to their short codes.
8 *
9 * Context: in some cases, like on Android, we get the full region name instead
10 * of the short code. We may need to expand this in the future to other
11 * countries, hence the prefix.
12 */
13export const USRegionNameToRegionCode: {
14 [regionName: string]: string
15} = {
16 Alabama: 'AL',
17 Alaska: 'AK',
18 Arizona: 'AZ',
19 Arkansas: 'AR',
20 California: 'CA',
21 Colorado: 'CO',
22 Connecticut: 'CT',
23 Delaware: 'DE',
24 Florida: 'FL',
25 Georgia: 'GA',
26 Hawaii: 'HI',
27 Idaho: 'ID',
28 Illinois: 'IL',
29 Indiana: 'IN',
30 Iowa: 'IA',
31 Kansas: 'KS',
32 Kentucky: 'KY',
33 Louisiana: 'LA',
34 Maine: 'ME',
35 Maryland: 'MD',
36 Massachusetts: 'MA',
37 Michigan: 'MI',
38 Minnesota: 'MN',
39 Mississippi: 'MS',
40 Missouri: 'MO',
41 Montana: 'MT',
42 Nebraska: 'NE',
43 Nevada: 'NV',
44 ['New Hampshire']: 'NH',
45 ['New Jersey']: 'NJ',
46 ['New Mexico']: 'NM',
47 ['New York']: 'NY',
48 ['North Carolina']: 'NC',
49 ['North Dakota']: 'ND',
50 Ohio: 'OH',
51 Oklahoma: 'OK',
52 Oregon: 'OR',
53 Pennsylvania: 'PA',
54 ['Rhode Island']: 'RI',
55 ['South Carolina']: 'SC',
56 ['South Dakota']: 'SD',
57 Tennessee: 'TN',
58 Texas: 'TX',
59 Utah: 'UT',
60 Vermont: 'VT',
61 Virginia: 'VA',
62 Washington: 'WA',
63 ['West Virginia']: 'WV',
64 Wisconsin: 'WI',
65 Wyoming: 'WY',
66}
67
68/**
69 * Normalizes a `LocationGeocodedAddress` into a `Geolocation`.
70 *
71 * We don't want or care about the full location data, so we trim it down and
72 * normalize certain fields, like region, into the format we need.
73 */
74export function normalizeDeviceLocation(
75 location: LocationGeocodedAddress,
76): Geolocation {
77 let {isoCountryCode, region} = location
78
79 if (region) {
80 if (isoCountryCode === 'US') {
81 region = USRegionNameToRegionCode[region] ?? region
82 }
83 }
84
85 return {
86 countryCode: isoCountryCode ?? undefined,
87 regionCode: region ?? undefined,
88 }
89}
90
91/**
92 * Combines precise location data with the geolocation config fetched from the
93 * IP service, with preference to the precise data.
94 */
95export function mergeGeolocations(
96 device?: Geolocation,
97 geolocationService?: Geolocation,
98): Geolocation {
99 let geolocation: Geolocation = {
100 countryCode: geolocationService?.countryCode ?? undefined,
101 regionCode: geolocationService?.regionCode ?? undefined,
102 }
103 // prefer GPS
104 if (device?.countryCode) {
105 geolocation = device
106 }
107 logger.debug('merged geolocation data', {
108 device,
109 service: geolocationService,
110 merged: geolocation,
111 })
112 return geolocation
113}