Bluesky app fork with some witchin' additions 💫

Add useFormatCurrency hook (#6978)

authored by

Eric Bailey and committed by
GitHub
8c68093d cd4c14e8

+302
+302
src/lib/currency.ts
··· 1 + import React from 'react' 2 + 3 + import {deviceLocales} from '#/locale/deviceLocales' 4 + import {useGeolocation} from '#/state/geolocation' 5 + import {useLanguagePrefs} from '#/state/preferences' 6 + 7 + /** 8 + * From react-native-localize 9 + * 10 + * MIT License 11 + * Copyright (c) 2017-present, Mathieu Acthernoene 12 + * 13 + * @see https://github.com/zoontek/react-native-localize/blob/master/LICENSE 14 + * @see https://github.com/zoontek/react-native-localize/blob/ee5bf25e0bb8f3b8e4f3fd055f67ad46269c81ea/src/constants.ts 15 + */ 16 + export const countryCodeToCurrency: Record<string, string> = { 17 + ad: 'eur', 18 + ae: 'aed', 19 + af: 'afn', 20 + ag: 'xcd', 21 + ai: 'xcd', 22 + al: 'all', 23 + am: 'amd', 24 + an: 'ang', 25 + ao: 'aoa', 26 + ar: 'ars', 27 + as: 'usd', 28 + at: 'eur', 29 + au: 'aud', 30 + aw: 'awg', 31 + ax: 'eur', 32 + az: 'azn', 33 + ba: 'bam', 34 + bb: 'bbd', 35 + bd: 'bdt', 36 + be: 'eur', 37 + bf: 'xof', 38 + bg: 'bgn', 39 + bh: 'bhd', 40 + bi: 'bif', 41 + bj: 'xof', 42 + bl: 'eur', 43 + bm: 'bmd', 44 + bn: 'bnd', 45 + bo: 'bob', 46 + bq: 'usd', 47 + br: 'brl', 48 + bs: 'bsd', 49 + bt: 'btn', 50 + bv: 'nok', 51 + bw: 'bwp', 52 + by: 'byn', 53 + bz: 'bzd', 54 + ca: 'cad', 55 + cc: 'aud', 56 + cd: 'cdf', 57 + cf: 'xaf', 58 + cg: 'xaf', 59 + ch: 'chf', 60 + ci: 'xof', 61 + ck: 'nzd', 62 + cl: 'clp', 63 + cm: 'xaf', 64 + cn: 'cny', 65 + co: 'cop', 66 + cr: 'crc', 67 + cu: 'cup', 68 + cv: 'cve', 69 + cw: 'ang', 70 + cx: 'aud', 71 + cy: 'eur', 72 + cz: 'czk', 73 + de: 'eur', 74 + dj: 'djf', 75 + dk: 'dkk', 76 + dm: 'xcd', 77 + do: 'dop', 78 + dz: 'dzd', 79 + ec: 'usd', 80 + ee: 'eur', 81 + eg: 'egp', 82 + eh: 'mad', 83 + er: 'ern', 84 + es: 'eur', 85 + et: 'etb', 86 + fi: 'eur', 87 + fj: 'fjd', 88 + fk: 'fkp', 89 + fm: 'usd', 90 + fo: 'dkk', 91 + fr: 'eur', 92 + ga: 'xaf', 93 + gb: 'gbp', 94 + gd: 'xcd', 95 + ge: 'gel', 96 + gf: 'eur', 97 + gg: 'gbp', 98 + gh: 'ghs', 99 + gi: 'gip', 100 + gl: 'dkk', 101 + gm: 'gmd', 102 + gn: 'gnf', 103 + gp: 'eur', 104 + gq: 'xaf', 105 + gr: 'eur', 106 + gs: 'gbp', 107 + gt: 'gtq', 108 + gu: 'usd', 109 + gw: 'xof', 110 + gy: 'gyd', 111 + hk: 'hkd', 112 + hm: 'aud', 113 + hn: 'hnl', 114 + hr: 'hrk', 115 + ht: 'htg', 116 + hu: 'huf', 117 + id: 'idr', 118 + ie: 'eur', 119 + il: 'ils', 120 + im: 'gbp', 121 + in: 'inr', 122 + io: 'usd', 123 + iq: 'iqd', 124 + ir: 'irr', 125 + is: 'isk', 126 + it: 'eur', 127 + je: 'gbp', 128 + jm: 'jmd', 129 + jo: 'jod', 130 + jp: 'jpy', 131 + ke: 'kes', 132 + kg: 'kgs', 133 + kh: 'khr', 134 + ki: 'aud', 135 + km: 'kmf', 136 + kn: 'xcd', 137 + kp: 'kpw', 138 + kr: 'krw', 139 + kw: 'kwd', 140 + ky: 'kyd', 141 + kz: 'kzt', 142 + la: 'lak', 143 + lb: 'lbp', 144 + lc: 'xcd', 145 + li: 'chf', 146 + lk: 'lkr', 147 + lr: 'lrd', 148 + ls: 'lsl', 149 + lt: 'eur', 150 + lu: 'eur', 151 + lv: 'eur', 152 + ly: 'lyd', 153 + ma: 'mad', 154 + mc: 'eur', 155 + md: 'mdl', 156 + me: 'eur', 157 + mf: 'eur', 158 + mg: 'mga', 159 + mh: 'usd', 160 + mk: 'mkd', 161 + ml: 'xof', 162 + mm: 'mmk', 163 + mn: 'mnt', 164 + mo: 'mop', 165 + mp: 'usd', 166 + mq: 'eur', 167 + mr: 'mro', 168 + ms: 'xcd', 169 + mt: 'eur', 170 + mu: 'mur', 171 + mv: 'mvr', 172 + mw: 'mwk', 173 + mx: 'mxn', 174 + my: 'myr', 175 + mz: 'mzn', 176 + na: 'nad', 177 + nc: 'xpf', 178 + ne: 'xof', 179 + nf: 'aud', 180 + ng: 'ngn', 181 + ni: 'nio', 182 + nl: 'eur', 183 + no: 'nok', 184 + np: 'npr', 185 + nr: 'aud', 186 + nu: 'nzd', 187 + nz: 'nzd', 188 + om: 'omr', 189 + pa: 'pab', 190 + pe: 'pen', 191 + pf: 'xpf', 192 + pg: 'pgk', 193 + ph: 'php', 194 + pk: 'pkr', 195 + pl: 'pln', 196 + pm: 'eur', 197 + pn: 'nzd', 198 + pr: 'usd', 199 + ps: 'ils', 200 + pt: 'eur', 201 + pw: 'usd', 202 + py: 'pyg', 203 + qa: 'qar', 204 + re: 'eur', 205 + ro: 'ron', 206 + rs: 'rsd', 207 + ru: 'rub', 208 + rw: 'rwf', 209 + sa: 'sar', 210 + sb: 'sbd', 211 + sc: 'scr', 212 + sd: 'sdg', 213 + se: 'sek', 214 + sg: 'sgd', 215 + sh: 'shp', 216 + si: 'eur', 217 + sj: 'nok', 218 + sk: 'eur', 219 + sl: 'sll', 220 + sm: 'eur', 221 + sn: 'xof', 222 + so: 'sos', 223 + sr: 'srd', 224 + ss: 'ssp', 225 + st: 'std', 226 + sv: 'svc', 227 + sx: 'ang', 228 + sy: 'syp', 229 + sz: 'szl', 230 + tc: 'usd', 231 + td: 'xaf', 232 + tf: 'eur', 233 + tg: 'xof', 234 + th: 'thb', 235 + tj: 'tjs', 236 + tk: 'nzd', 237 + tl: 'usd', 238 + tm: 'tmt', 239 + tn: 'tnd', 240 + to: 'top', 241 + tr: 'try', 242 + tt: 'ttd', 243 + tv: 'aud', 244 + tw: 'twd', 245 + tz: 'tzs', 246 + ua: 'uah', 247 + ug: 'ugx', 248 + um: 'usd', 249 + us: 'usd', 250 + uy: 'uyu', 251 + uz: 'uzs', 252 + va: 'eur', 253 + vc: 'xcd', 254 + ve: 'vef', 255 + vg: 'usd', 256 + vi: 'usd', 257 + vn: 'vnd', 258 + vu: 'vuv', 259 + wf: 'xpf', 260 + ws: 'wst', 261 + ye: 'yer', 262 + yt: 'eur', 263 + za: 'zar', 264 + zm: 'zmw', 265 + zw: 'zwl', 266 + } 267 + 268 + /** 269 + * Best-guess currency formatting. 270 + * 271 + * Attempts to use `getLocales` from `expo-localization` if available, 272 + * otherwise falls back to the `persisted.appLanguage` setting, and geolocation 273 + * API for region. 274 + */ 275 + export function useFormatCurrency( 276 + options?: Parameters<typeof Intl.NumberFormat>[1], 277 + ) { 278 + const {geolocation} = useGeolocation() 279 + const {appLanguage} = useLanguagePrefs() 280 + return React.useMemo(() => { 281 + const locale = deviceLocales.at(0) 282 + const languageTag = locale?.languageTag || appLanguage || 'en-US' 283 + const countryCode = ( 284 + locale?.regionCode || 285 + geolocation?.countryCode || 286 + 'us' 287 + ).toLowerCase() 288 + const currency = countryCodeToCurrency[countryCode] || 'usd' 289 + const format = new Intl.NumberFormat(languageTag, { 290 + ...(options || {}), 291 + style: 'currency', 292 + currency: currency, 293 + }).format 294 + 295 + return { 296 + format, 297 + currency, 298 + countryCode, 299 + languageTag, 300 + } 301 + }, [geolocation, appLanguage, options]) 302 + }