feat(smart-app): implement complete mobile app MVP

- App.tsx: full navigation (Auth stack + Main tabs with 5 screens)
- Auth: LoginScreen, RegisterScreen, ForgotPasswordScreen
- HomeScreen: dashboard with IoT metrics, weather widget, alerts, quick actions, sensors
- MapScreen: interactive map with layer toggles (6 layers)
- MarketplaceScreen: categories (6), products (5), search
- ChatScreen: AI chat with quick prompts (4), bot responses
- ProfileScreen: user info, stats, menu (9 items), logout
- AlertsScreen: alert list with severity, acknowledge
- SensorsScreen: sensor list with type filters (6 types), search
- ZonesScreen: zone cards with stats
- SettingsScreen: language picker (FR/EN/ES/DE), privacy, about
- Stores: iotStore (sensors, zones, alerts), notificationStore, uiStore + i18n
- Hooks: useSensors, useAlerts, useNotifications, useLocation
- Components: Card, Button, LoadingSpinner, ErrorBoundary, Header
- Services: iotService, notificationService (with axios API client)
- Utils: formatters (temp, AQI, noise, dates), validators (email, password, IBAN)
- Theme: colors.ts with full design system (Blue Ocean palette)
- Ditto: fixed MongoDB connection, new JWT secrets, official gateway image
This commit is contained in:
Eric FELIXINE
2026-06-01 18:00:35 -04:00
parent 08ca495bde
commit e30ae8ed09
35578 changed files with 3703534 additions and 43 deletions

View File

@@ -0,0 +1,22 @@
import { Subscription } from 'expo-modules-core';
import { Localization, Calendar, Locale } from './Localization.types';
export declare function addLocaleListener(listener: (event: any) => void): Subscription;
export declare function addCalendarListener(listener: (event: any) => void): Subscription;
export declare function removeSubscription(subscription: Subscription): void;
declare const _default: {
readonly currency: string | null;
readonly decimalSeparator: string;
readonly digitGroupingSeparator: string;
readonly isRTL: boolean;
readonly isMetric: boolean;
readonly locale: string;
readonly locales: string[];
readonly timezone: string;
readonly isoCurrencyCodes: string[];
readonly region: string | null;
getLocales(): Locale[];
getCalendars(): Calendar[];
getLocalizationAsync(): Promise<Omit<Localization, 'getCalendars' | 'getLocales'>>;
};
export default _default;
//# sourceMappingURL=ExpoLocalization.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ExpoLocalization.d.ts","sourceRoot":"","sources":["../src/ExpoLocalization.ts"],"names":[],"mappings":"AACA,OAAO,EAAY,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAG3D,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAsB,MAAM,sBAAsB,CAAC;AAoC1F,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,CAAC,KAAK,KAAA,KAAK,IAAI,GAAG,YAAY,CAKzE;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,CAAC,KAAK,KAAA,KAAK,IAAI,GAAG,YAAY,CAK3E;AAED,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,YAAY,QAE5D;;;;;;;;;;;;kBAsEe,MAAM,EAAE;oBAgCN,QAAQ,EAAE;4BAcI,QAAQ,KAAK,YAAY,EAAE,cAAc,GAAG,YAAY,CAAC,CAAC;;AAlH1F,wBA4IE"}

View File

@@ -0,0 +1,166 @@
/* eslint-env browser */
import { Platform } from 'expo-modules-core';
import * as rtlDetect from 'rtl-detect';
const getNavigatorLocales = () => {
return Platform.isDOMAvailable ? navigator.languages || [navigator.language] : [];
};
const WEB_LANGUAGE_CHANGE_EVENT = 'languagechange';
// https://wisevoter.com/country-rankings/countries-that-use-fahrenheit/
const USES_FAHRENHEIT = [
'AG',
'BZ',
'VG',
'FM',
'MH',
'MS',
'KN',
'BS',
'CY',
'TC',
'US',
'LR',
'PW',
'KY',
];
export function addLocaleListener(listener) {
addEventListener(WEB_LANGUAGE_CHANGE_EVENT, listener);
return {
remove: () => removeEventListener(WEB_LANGUAGE_CHANGE_EVENT, listener),
};
}
export function addCalendarListener(listener) {
addEventListener(WEB_LANGUAGE_CHANGE_EVENT, listener);
return {
remove: () => removeEventListener(WEB_LANGUAGE_CHANGE_EVENT, listener),
};
}
export function removeSubscription(subscription) {
subscription.remove();
}
export default {
get currency() {
// TODO: Add support
return null;
},
get decimalSeparator() {
return (1.1).toLocaleString().substring(1, 2);
},
get digitGroupingSeparator() {
const value = (1000).toLocaleString();
return value.length === 5 ? value.substring(1, 2) : '';
},
get isRTL() {
return rtlDetect.isRtlLang(this.locale) ?? false;
},
get isMetric() {
const { region } = this;
switch (region) {
case 'US': // USA
case 'LR': // Liberia
case 'MM': // Myanmar
return false;
}
return true;
},
get locale() {
if (!Platform.isDOMAvailable) {
return '';
}
const locale = navigator.language ||
navigator['systemLanguage'] ||
navigator['browserLanguage'] ||
navigator['userLanguage'] ||
this.locales[0];
return locale;
},
get locales() {
if (!Platform.isDOMAvailable) {
return [];
}
const { languages = [] } = navigator;
return Array.from(languages);
},
get timezone() {
const defaultTimeZone = 'Etc/UTC';
if (typeof Intl === 'undefined') {
return defaultTimeZone;
}
return Intl.DateTimeFormat().resolvedOptions().timeZone || defaultTimeZone;
},
get isoCurrencyCodes() {
// TODO(Bacon): Add this - very low priority
return [];
},
get region() {
// There is no way to obtain the current region, as is possible on native.
// Instead, use the country-code from the locale when possible (e.g. "en-US").
const { locale } = this;
const [, ...suffixes] = typeof locale === 'string' ? locale.split('-') : [];
for (const suffix of suffixes) {
if (suffix.length === 2) {
return suffix.toUpperCase();
}
}
return null;
},
getLocales() {
const locales = getNavigatorLocales();
return locales?.map((languageTag) => {
// TextInfo is an experimental API that is not available in all browsers.
// We might want to consider using a locale lookup table instead.
const locale = typeof Intl !== 'undefined'
? new Intl.Locale(languageTag)
: { region: null, textInfo: null, language: null };
const { region, textInfo, language } = locale;
// Properties added only for compatibility with native, use `toLocaleString` instead.
const digitGroupingSeparator = Array.from((10000).toLocaleString(languageTag)).filter((c) => c > '9' || c < '0')[0] ||
null; // using 1e5 instead of 1e4 since for some locales (like pl-PL) 1e4 does not use digit grouping
const decimalSeparator = (1.1).toLocaleString(languageTag).substring(1, 2);
const temperatureUnit = region ? regionToTemperatureUnit(region) : null;
return {
languageTag,
languageCode: language || languageTag.split('-')[0] || 'en',
textDirection: textInfo?.direction || null,
digitGroupingSeparator,
decimalSeparator,
measurementSystem: null,
currencyCode: null,
currencySymbol: null,
regionCode: region || null,
temperatureUnit,
};
});
},
getCalendars() {
const locale = ((typeof Intl !== 'undefined'
? Intl.DateTimeFormat().resolvedOptions()
: null) ?? null);
return [
{
calendar: (locale?.calendar || locale?.calendars?.[0]) || null,
timeZone: locale?.timeZone || locale?.timeZones?.[0] || null,
uses24hourClock: (locale?.hourCycle || locale?.hourCycles?.[0])?.startsWith('h2') ?? null,
firstWeekday: locale?.weekInfo?.firstDay || null,
},
];
},
async getLocalizationAsync() {
const { currency, decimalSeparator, digitGroupingSeparator, isoCurrencyCodes, isMetric, isRTL, locale, locales, region, timezone, } = this;
return {
currency,
decimalSeparator,
digitGroupingSeparator,
isoCurrencyCodes,
isMetric,
isRTL,
locale,
locales,
region,
timezone,
};
},
};
function regionToTemperatureUnit(region) {
return USES_FAHRENHEIT.includes(region) ? 'fahrenheit' : 'celsius';
}
//# sourceMappingURL=ExpoLocalization.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,7 @@
import { Subscription } from 'expo-modules-core';
declare const ExpoLocalizationModule: any;
export declare function addLocaleListener(listener: (event: any) => void): Subscription;
export declare function addCalendarListener(listener: (event: any) => void): Subscription;
export declare function removeSubscription(subscription: Subscription): void;
export default ExpoLocalizationModule;
//# sourceMappingURL=ExpoLocalization.native.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ExpoLocalization.native.d.ts","sourceRoot":"","sources":["../src/ExpoLocalization.native.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,YAAY,EAAuB,MAAM,mBAAmB,CAAC;AAEpF,QAAA,MAAM,sBAAsB,KAA0C,CAAC;AAGvE,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,CAAC,KAAK,KAAA,KAAK,IAAI,GAAG,YAAY,CAEzE;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,CAAC,KAAK,KAAA,KAAK,IAAI,GAAG,YAAY,CAE3E;AAED,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,YAAY,QAE5D;AAED,eAAe,sBAAsB,CAAC"}

View File

@@ -0,0 +1,14 @@
import { EventEmitter, requireNativeModule } from 'expo-modules-core';
const ExpoLocalizationModule = requireNativeModule('ExpoLocalization');
const emitter = new EventEmitter(ExpoLocalizationModule);
export function addLocaleListener(listener) {
return emitter.addListener('onLocaleSettingsChanged', listener);
}
export function addCalendarListener(listener) {
return emitter.addListener('onCalendarSettingsChanged', listener);
}
export function removeSubscription(subscription) {
return emitter.removeSubscription(subscription);
}
export default ExpoLocalizationModule;
//# sourceMappingURL=ExpoLocalization.native.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ExpoLocalization.native.js","sourceRoot":"","sources":["../src/ExpoLocalization.native.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAgB,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAEpF,MAAM,sBAAsB,GAAG,mBAAmB,CAAC,kBAAkB,CAAC,CAAC;AACvE,MAAM,OAAO,GAAG,IAAI,YAAY,CAAC,sBAAsB,CAAC,CAAC;AAEzD,MAAM,UAAU,iBAAiB,CAAC,QAAyB;IACzD,OAAO,OAAO,CAAC,WAAW,CAAC,yBAAyB,EAAE,QAAQ,CAAC,CAAC;AAClE,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,QAAyB;IAC3D,OAAO,OAAO,CAAC,WAAW,CAAC,2BAA2B,EAAE,QAAQ,CAAC,CAAC;AACpE,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,YAA0B;IAC3D,OAAO,OAAO,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC;AAClD,CAAC;AAED,eAAe,sBAAsB,CAAC","sourcesContent":["import { EventEmitter, Subscription, requireNativeModule } from 'expo-modules-core';\n\nconst ExpoLocalizationModule = requireNativeModule('ExpoLocalization');\nconst emitter = new EventEmitter(ExpoLocalizationModule);\n\nexport function addLocaleListener(listener: (event) => void): Subscription {\n return emitter.addListener('onLocaleSettingsChanged', listener);\n}\n\nexport function addCalendarListener(listener: (event) => void): Subscription {\n return emitter.addListener('onCalendarSettingsChanged', listener);\n}\n\nexport function removeSubscription(subscription: Subscription) {\n return emitter.removeSubscription(subscription);\n}\n\nexport default ExpoLocalizationModule;\n"]}

View File

@@ -0,0 +1,188 @@
import { Localization } from './Localization.types';
export * from './Localization.types';
/**
* @hidden
* @deprecated Use Localization.getLocales() instead.
* Three-character ISO 4217 currency code. Returns `null` on web.
*
* @example
* `'USD'`, `'EUR'`, `'CNY'`, `null`
*/
export declare const currency: string | null;
/**
* @hidden
* @deprecated Use Localization.getLocales() instead.
* Decimal separator used for formatting numbers.
*
* @example
* `','`, `'.'`
*/
export declare const decimalSeparator: string;
/**
* @hidden
* @deprecated Use Localization.getLocales() instead.
* Digit grouping separator used when formatting numbers larger than 1000.
*
* @example
* `'.'`, `''`, `','`
*/
export declare const digitGroupingSeparator: string;
/**
* @hidden
* @deprecated Use Localization.getLocales() instead.
* A list of all the supported language ISO codes.
*/
export declare const isoCurrencyCodes: string[];
/**
* @hidden
* @deprecated Use Localization.getLocales() instead.
* Boolean value that indicates whether the system uses the metric system.
* On Android and web, this is inferred from the current region.
*/
export declare const isMetric: boolean;
/**
* @hidden
* @deprecated Use Localization.getLocales() instead.
* Returns if the system's language is written from Right-to-Left.
* This can be used to build features like [bidirectional icons](https://material.io/design/usability/bidirectionality.html).
*
* Returns `false` in Server Side Rendering (SSR) environments.
*/
export declare const isRTL: boolean;
/**
* @deprecated Use [`Localization.getLocales()`](#localizationgetlocales) instead.
* An [IETF BCP 47 language tag](https://en.wikipedia.org/wiki/IETF_language_tag),
* consisting of a two-character language code and optional script, region and variant codes.
*
* @example
* `'en'`, `'en-US'`, `'zh-Hans'`, `'zh-Hans-CN'`, `'en-emodeng'`
*/
export declare const locale: string;
/**
* @hidden
* @deprecated Use Localization.getLocales() instead.
* List of all the native languages provided by the user settings.
* These are returned in the order the user defines in their device settings.
*
* @example
* `['en', 'en-US', 'zh-Hans', 'zh-Hans-CN', 'en-emodeng']`
*/
export declare const locales: string[];
/**
* @hidden
* @deprecated Use Localization.getCalendars() instead.
* The current time zone in display format.
* On Web time zone is calculated with Intl.DateTimeFormat().resolvedOptions().timeZone. For a
* better estimation you could use the moment-timezone package but it will add significant bloat to
* your website's bundle size.
*
* @example
* `'America/Los_Angeles'`
*/
export declare const timezone: string;
/**
* @hidden
* @deprecated Use Localization.getLocales() instead.
* The region code for your device that comes from the Region setting under Language & Region on iOS.
* This value is always available on iOS, but might return `null` on Android or web.
*
* @example
* `'US'`, `'NZ'`, `null`
*/
export declare const region: string | null;
/**
* List of user's locales, returned as an array of objects of type `Locale`.
* Guaranteed to contain at least 1 element.
* These are returned in the order the user defines in their device settings.
* On the web currency and measurements systems are not provided, instead returned as null.
* If needed, you can infer them from the current region using a lookup table.
* @example
* ```js
* [{
* "languageTag": "pl-PL",
* "languageCode": "pl",
* "textDirection": "ltr",
* "digitGroupingSeparator": " ",
* "decimalSeparator": ",",
* "measurementSystem": "metric",
* "currencyCode": "PLN",
* "currencySymbol": "zł",
* "regionCode": "PL",
* "temperatureUnit": "celsius"
* }]
* ```
*/
export declare const getLocales: () => import("./Localization.types").Locale[];
/**
* List of user's preferred calendars, returned as an array of objects of type `Calendar`.
* Guaranteed to contain at least 1 element.
* For now always returns a single element, but it's likely to return a user preference list on some platforms in the future.
* @example
* ```js
* [{
* "calendar": "gregory",
* "timeZone": "Europe/Warsaw",
* "uses24hourClock": true,
* "firstWeekday": 1
* }]
* ```
*/
export declare const getCalendars: () => import("./Localization.types").Calendar[];
/**
* A hook providing a list of user's locales, returned as an array of objects of type `Locale`.
* Guaranteed to contain at least 1 element.
* These are returned in the order the user defines in their device settings.
* On the web currency and measurements systems are not provided, instead returned as null.
* If needed, you can infer them from the current region using a lookup table.
* If the OS settings change, the hook will rerender with a new list of locales.
* @example
* ```js
* [{
* "languageTag": "pl-PL",
* "languageCode": "pl",
* "textDirection": "ltr",
* "digitGroupingSeparator": " ",
* "decimalSeparator": ",",
* "measurementSystem": "metric",
* "currencyCode": "PLN",
* "currencySymbol": "zł",
* "regionCode": "PL",
* "temperatureUnit": "celsius"
* }]
* ```
*/
export declare function useLocales(): import("./Localization.types").Locale[];
/**
* A hook providing a list of user's preferred calendars, returned as an array of objects of type `Calendar`.
* Guaranteed to contain at least 1 element.
* For now always returns a single element, but it's likely to return a user preference list on some platforms in the future.
* If the OS settings change, the hook will rerender with a new list of calendars.
* @example
* ```js
* [{
* "calendar": "gregory",
* "timeZone": "Europe/Warsaw",
* "uses24hourClock": true,
* "firstWeekday": 1
* }]
* ```
*/
export declare function useCalendars(): import("./Localization.types").Calendar[];
/**
* @hidden
* Get the latest native values from the device. Locale can be changed on some Android devices
* without resetting the app.
* > On iOS, changing the locale will cause the device to reset meaning the constants will always be
* correct.
*
* @example
* ```ts
* // When the app returns from the background on Android...
*
* const { locale } = await Localization.getLocalizationAsync();
* ```
* @deprecated
* Use Localization.getLocales() or Localization.getCalendars() instead.
*/
export declare function getLocalizationAsync(): Promise<Localization>;
//# sourceMappingURL=Localization.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"Localization.d.ts","sourceRoot":"","sources":["../src/Localization.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,cAAc,sBAAsB,CAAC;AAGrC;;;;;;;GAOG;AACH,eAAO,MAAM,QAAQ,eAA4B,CAAC;AAGlD;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,QAAoC,CAAC;AAGlE;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,QAA0C,CAAC;AAG9E;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,UAAoC,CAAC;AAGlE;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,SAA4B,CAAC;AAGlD;;;;;;;GAOG;AACH,eAAO,MAAM,KAAK,SAAyB,CAAC;AAG5C;;;;;;;GAOG;AACH,eAAO,MAAM,MAAM,QAA0B,CAAC;AAG9C;;;;;;;;GAQG;AACH,eAAO,MAAM,OAAO,UAA2B,CAAC;AAGhD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,QAAQ,QAA4B,CAAC;AAGlD;;;;;;;;GAQG;AACH,eAAO,MAAM,MAAM,eAA0B,CAAC;AAE9C;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,UAAU,+CAA8B,CAAC;AAEtD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,YAAY,iDAAgC,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,UAAU,4CAUzB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,8CAU3B;AAGD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,YAAY,CAAC,CAElE"}

View File

@@ -0,0 +1,222 @@
import { useEffect, useReducer, useMemo } from 'react';
import ExpoLocalization, { addCalendarListener, addLocaleListener, removeSubscription, } from './ExpoLocalization';
export * from './Localization.types';
// @needsAudit
/**
* @hidden
* @deprecated Use Localization.getLocales() instead.
* Three-character ISO 4217 currency code. Returns `null` on web.
*
* @example
* `'USD'`, `'EUR'`, `'CNY'`, `null`
*/
export const currency = ExpoLocalization.currency;
// @needsAudit
/**
* @hidden
* @deprecated Use Localization.getLocales() instead.
* Decimal separator used for formatting numbers.
*
* @example
* `','`, `'.'`
*/
export const decimalSeparator = ExpoLocalization.decimalSeparator;
// @needsAudit
/**
* @hidden
* @deprecated Use Localization.getLocales() instead.
* Digit grouping separator used when formatting numbers larger than 1000.
*
* @example
* `'.'`, `''`, `','`
*/
export const digitGroupingSeparator = ExpoLocalization.digitGroupingSeparator;
// @needsAudit
/**
* @hidden
* @deprecated Use Localization.getLocales() instead.
* A list of all the supported language ISO codes.
*/
export const isoCurrencyCodes = ExpoLocalization.isoCurrencyCodes;
// @needsAudit
/**
* @hidden
* @deprecated Use Localization.getLocales() instead.
* Boolean value that indicates whether the system uses the metric system.
* On Android and web, this is inferred from the current region.
*/
export const isMetric = ExpoLocalization.isMetric;
// @needsAudit
/**
* @hidden
* @deprecated Use Localization.getLocales() instead.
* Returns if the system's language is written from Right-to-Left.
* This can be used to build features like [bidirectional icons](https://material.io/design/usability/bidirectionality.html).
*
* Returns `false` in Server Side Rendering (SSR) environments.
*/
export const isRTL = ExpoLocalization.isRTL;
// @needsAudit
/**
* @deprecated Use [`Localization.getLocales()`](#localizationgetlocales) instead.
* An [IETF BCP 47 language tag](https://en.wikipedia.org/wiki/IETF_language_tag),
* consisting of a two-character language code and optional script, region and variant codes.
*
* @example
* `'en'`, `'en-US'`, `'zh-Hans'`, `'zh-Hans-CN'`, `'en-emodeng'`
*/
export const locale = ExpoLocalization.locale;
// @needsAudit
/**
* @hidden
* @deprecated Use Localization.getLocales() instead.
* List of all the native languages provided by the user settings.
* These are returned in the order the user defines in their device settings.
*
* @example
* `['en', 'en-US', 'zh-Hans', 'zh-Hans-CN', 'en-emodeng']`
*/
export const locales = ExpoLocalization.locales;
// @needsAudit
/**
* @hidden
* @deprecated Use Localization.getCalendars() instead.
* The current time zone in display format.
* On Web time zone is calculated with Intl.DateTimeFormat().resolvedOptions().timeZone. For a
* better estimation you could use the moment-timezone package but it will add significant bloat to
* your website's bundle size.
*
* @example
* `'America/Los_Angeles'`
*/
export const timezone = ExpoLocalization.timezone;
// @needsAudit
/**
* @hidden
* @deprecated Use Localization.getLocales() instead.
* The region code for your device that comes from the Region setting under Language & Region on iOS.
* This value is always available on iOS, but might return `null` on Android or web.
*
* @example
* `'US'`, `'NZ'`, `null`
*/
export const region = ExpoLocalization.region;
/**
* List of user's locales, returned as an array of objects of type `Locale`.
* Guaranteed to contain at least 1 element.
* These are returned in the order the user defines in their device settings.
* On the web currency and measurements systems are not provided, instead returned as null.
* If needed, you can infer them from the current region using a lookup table.
* @example
* ```js
* [{
* "languageTag": "pl-PL",
* "languageCode": "pl",
* "textDirection": "ltr",
* "digitGroupingSeparator": " ",
* "decimalSeparator": ",",
* "measurementSystem": "metric",
* "currencyCode": "PLN",
* "currencySymbol": "zł",
* "regionCode": "PL",
* "temperatureUnit": "celsius"
* }]
* ```
*/
export const getLocales = ExpoLocalization.getLocales;
/**
* List of user's preferred calendars, returned as an array of objects of type `Calendar`.
* Guaranteed to contain at least 1 element.
* For now always returns a single element, but it's likely to return a user preference list on some platforms in the future.
* @example
* ```js
* [{
* "calendar": "gregory",
* "timeZone": "Europe/Warsaw",
* "uses24hourClock": true,
* "firstWeekday": 1
* }]
* ```
*/
export const getCalendars = ExpoLocalization.getCalendars;
/**
* A hook providing a list of user's locales, returned as an array of objects of type `Locale`.
* Guaranteed to contain at least 1 element.
* These are returned in the order the user defines in their device settings.
* On the web currency and measurements systems are not provided, instead returned as null.
* If needed, you can infer them from the current region using a lookup table.
* If the OS settings change, the hook will rerender with a new list of locales.
* @example
* ```js
* [{
* "languageTag": "pl-PL",
* "languageCode": "pl",
* "textDirection": "ltr",
* "digitGroupingSeparator": " ",
* "decimalSeparator": ",",
* "measurementSystem": "metric",
* "currencyCode": "PLN",
* "currencySymbol": "zł",
* "regionCode": "PL",
* "temperatureUnit": "celsius"
* }]
* ```
*/
export function useLocales() {
const [key, invalidate] = useReducer((k) => k + 1, 0);
const locales = useMemo(() => getLocales(), [key]);
useEffect(() => {
const subscription = addLocaleListener(invalidate);
return () => {
removeSubscription(subscription);
};
}, []);
return locales;
}
/**
* A hook providing a list of user's preferred calendars, returned as an array of objects of type `Calendar`.
* Guaranteed to contain at least 1 element.
* For now always returns a single element, but it's likely to return a user preference list on some platforms in the future.
* If the OS settings change, the hook will rerender with a new list of calendars.
* @example
* ```js
* [{
* "calendar": "gregory",
* "timeZone": "Europe/Warsaw",
* "uses24hourClock": true,
* "firstWeekday": 1
* }]
* ```
*/
export function useCalendars() {
const [key, invalidate] = useReducer((k) => k + 1, 0);
const calendars = useMemo(() => getCalendars(), [key]);
useEffect(() => {
const subscription = addCalendarListener(invalidate);
return () => {
removeSubscription(subscription);
};
}, []);
return calendars;
}
// @needsAudit
/**
* @hidden
* Get the latest native values from the device. Locale can be changed on some Android devices
* without resetting the app.
* > On iOS, changing the locale will cause the device to reset meaning the constants will always be
* correct.
*
* @example
* ```ts
* // When the app returns from the background on Android...
*
* const { locale } = await Localization.getLocalizationAsync();
* ```
* @deprecated
* Use Localization.getLocales() or Localization.getCalendars() instead.
*/
export async function getLocalizationAsync() {
return await ExpoLocalization.getLocalizationAsync();
}
//# sourceMappingURL=Localization.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,210 @@
export type Localization = {
/**
* Three-character ISO 4217 currency code. Returns `null` on web.
* @example
* `'USD'`, `'EUR'`, `'CNY'`, `null`
*/
currency: string | null;
/**
* Decimal separator used for formatting numbers.
* @example
* `','`, `'.'`
*/
decimalSeparator: string;
/**
* Digit grouping separator used when formatting numbers larger than 1000.
* @example
* `'.'`, `''`, `','`
*/
digitGroupingSeparator: string;
/**
* A list of all the supported language ISO codes.
*/
isoCurrencyCodes: string[];
/**
* Boolean value that indicates whether the system uses the metric system.
* On Android and web, this is inferred from the current region.
*/
isMetric: boolean;
/**
* Returns if the system's language is written from Right-to-Left.
* This can be used to build features like [bidirectional icons](https://material.io/design/usability/bidirectionality.html).
*
* Returns `false` in Server Side Rendering (SSR) environments.
*/
isRTL: boolean;
/**
* An [IETF BCP 47 language tag](https://en.wikipedia.org/wiki/IETF_language_tag),
* consisting of a two-character language code and optional script, region and variant codes.
* @example
* `'en'`, `'en-US'`, `'zh-Hans'`, `'zh-Hans-CN'`, `'en-emodeng'`
*/
locale: string;
/**
* List of all the native languages provided by the user settings.
* These are returned in the order that the user defined in the device settings.
* @example
* `['en', 'en-US', 'zh-Hans', 'zh-Hans-CN', 'en-emodeng']`
*/
locales: string[];
/**
* The region code for your device that comes from the Region setting under Language & Region on iOS.
* This value is always available on iOS, but might return `null` on Android or web.
* @example
* `'US'`, `'NZ'`, `null`
*/
region: string | null;
/**
* The current time zone in display format.
* On Web time zone is calculated with Intl.DateTimeFormat().resolvedOptions().timeZone. For a
* better estimation you could use the moment-timezone package but it will add significant bloat to
* your website's bundle size.
* @example
* `'America/Los_Angeles'`
*/
timezone: string;
};
export type Locale = {
/**
* An [IETF BCP 47 language tag](https://en.wikipedia.org/wiki/IETF_language_tag) with a region code.
* @example
* `'en-US'`, `'es-419'`, `'pl-PL'`.
*/
languageTag: string;
/**
* An [IETF BCP 47 language tag](https://en.wikipedia.org/wiki/IETF_language_tag) without the region code.
* @example
* `'en'`, `'es'`, `'pl'`.
*/
languageCode: string | null;
/**
* The region code for your device that comes from the Region setting under Language & Region on iOS, Region settings on Android and is parsed from locale on Web (can be `null` on Web).
*/
regionCode: string | null;
/**
* Currency code for the locale.
* Is `null` on Web, use a table lookup based on region instead.
* @example
* `'USD'`, `'EUR'`, `'PLN'`.
*/
currencyCode: string | null;
/**
* Currency symbol for the locale.
* Is `null` on Web, use a table lookup based on region (if available) instead.
* @example
* `'$'`, `'€'`, `'zł'`.
*/
currencySymbol: string | null;
/**
* Decimal separator used for formatting numbers with fractional parts.
* @example
* `'.'`, `','`.
*/
decimalSeparator: string | null;
/**
* Digit grouping separator used for formatting large numbers.
* @example
* `'.'`, `','`.
*/
digitGroupingSeparator: string | null;
/**
* Text direction for the locale. One of: `'ltr'`, `'rtl'`, but can also be `null` on some browsers without support for the [textInfo](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale/textInfo) property in [Intl](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl) API.
*/
textDirection: 'ltr' | 'rtl' | null;
/**
* The measurement system used in the locale.
* Is `null` on Web, as user chosen measurement system is not exposed on the web and using locale to determine measurement systems is unreliable.
* Ask for user preferences if possible.
*/
measurementSystem: `metric` | `us` | `uk` | null;
/**
* The temperature unit used in the locale.
* Returns `null` if the region code is unknown.
*/
temperatureUnit: 'celsius' | 'fahrenheit' | null;
};
/**
* An enum mapping days of the week in Gregorian calendar to their index as returned by the `firstWeekday` property.
*/
export declare enum Weekday {
SUNDAY = 1,
MONDAY = 2,
TUESDAY = 3,
WEDNESDAY = 4,
THURSDAY = 5,
FRIDAY = 6,
SATURDAY = 7
}
/**
* The calendar identifier, one of [Unicode calendar types](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale/calendar).
* Gregorian calendar is aliased and can be referred to as both `CalendarIdentifier.GREGORIAN` and `CalendarIdentifier.GREGORY`.
*/
export declare enum CalendarIdentifier {
/** Thai Buddhist calendar */
BUDDHIST = "buddhist",
/** Traditional Chinese calendar */
CHINESE = "chinese",
/** Coptic calendar */
COPTIC = "coptic",
/** Traditional Korean calendar */
DANGI = "dangi",
/** Ethiopic calendar, Amete Alem (epoch approx. 5493 B.C.E) */
ETHIOAA = "ethioaa",
/** Ethiopic calendar, Amete Mihret (epoch approx, 8 C.E.) */
ETHIOPIC = "ethiopic",
/** Gregorian calendar */
GREGORY = "gregory",
/** Gregorian calendar (alias) */
GREGORIAN = "gregory",
/** Traditional Hebrew calendar */
HEBREW = "hebrew",
/** Indian calendar */
INDIAN = "indian",
/** Islamic calendar */
ISLAMIC = "islamic",
/** Islamic calendar, tabular (intercalary years [2,5,7,10,13,16,18,21,24,26,29] - civil epoch) */
ISLAMIC_CIVIL = "islamic-civil",
/** Islamic calendar, Saudi Arabia sighting */
ISLAMIC_RGSA = "islamic-rgsa",
/**Islamic calendar, tabular (intercalary years [2,5,7,10,13,16,18,21,24,26,29] - astronomical epoch) */
ISLAMIC_TBLA = "islamic-tbla",
/** Islamic calendar, Umm al-Qura */
ISLAMIC_UMALQURA = "islamic-umalqura",
/** ISO calendar (Gregorian calendar using the ISO 8601 calendar week rules) */
ISO8601 = "iso8601",
/** Japanese imperial calendar */
JAPANESE = "japanese",
/** Persian calendar */
PERSIAN = "persian",
/** Civil (algorithmic) Arabic calendar */
ROC = "roc"
}
export type Calendar = {
/**
* The calendar identifier, one of [Unicode calendar types](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale/calendar).
*
* On Android is limited to one of device's [available calendar types](https://developer.android.com/reference/java/util/Calendar#getAvailableCalendarTypes()).
*
* On iOS uses [calendar identifiers](https://developer.apple.com/documentation/foundation/calendar/identifier), but maps them to the corresponding Unicode types, will also never contain `'dangi'` or `'islamic-rgsa'` due to it not being implemented on iOS.
*/
calendar: CalendarIdentifier | null;
/**
* True when current device settings use 24-hour time format.
* Can be null on some browsers that don't support the [hourCycle](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale/hourCycle) property in [Intl](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl) API.
*/
uses24hourClock: boolean | null;
/**
* The first day of the week. For most calendars Sunday is numbered `1`, with Saturday being number `7`.
* Can be null on some browsers that don't support the [weekInfo](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale/weekInfo) property in [Intl](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl) API.
* @example
* `1`, `7`.
*/
firstWeekday: Weekday | null;
/**
* Time zone for the calendar. Can be `null` on Web.
* @example
* `'America/Los_Angeles'`, `'Europe/Warsaw'`, `'GMT+1'`.
*/
timeZone: string | null;
};
//# sourceMappingURL=Localization.types.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"Localization.types.d.ts","sourceRoot":"","sources":["../src/Localization.types.ts"],"names":[],"mappings":"AACA,MAAM,MAAM,YAAY,GAAG;IACzB;;;;OAIG;IACH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB;;;;OAIG;IACH,gBAAgB,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,sBAAsB,EAAE,MAAM,CAAC;IAC/B;;OAEG;IACH,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B;;;OAGG;IACH,QAAQ,EAAE,OAAO,CAAC;IAClB;;;;;OAKG;IACH,KAAK,EAAE,OAAO,CAAC;IACf;;;;;OAKG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB;;;;;OAKG;IACH,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB;;;;;;;OAOG;IACH,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG;IACnB;;;;OAIG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B;;OAEG;IACH,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B;;;;;OAKG;IACH,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B;;;;;OAKG;IACH,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B;;;;OAIG;IACH,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC;;;;OAIG;IACH,sBAAsB,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC;;OAEG;IACH,aAAa,EAAE,KAAK,GAAG,KAAK,GAAG,IAAI,CAAC;IACpC;;;;OAIG;IACH,iBAAiB,EAAE,QAAQ,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IACjD;;;OAGG;IACH,eAAe,EAAE,SAAS,GAAG,YAAY,GAAG,IAAI,CAAC;CAClD,CAAC;AAEF;;GAEG;AACH,oBAAY,OAAO;IACjB,MAAM,IAAI;IACV,MAAM,IAAI;IACV,OAAO,IAAI;IACX,SAAS,IAAI;IACb,QAAQ,IAAI;IACZ,MAAM,IAAI;IACV,QAAQ,IAAI;CACb;AAED;;;GAGG;AACH,oBAAY,kBAAkB;IAC5B,6BAA6B;IAC7B,QAAQ,aAAa;IACrB,mCAAmC;IACnC,OAAO,YAAY;IACnB,sBAAsB;IACtB,MAAM,WAAW;IACjB,kCAAkC;IAClC,KAAK,UAAU;IACf,+DAA+D;IAC/D,OAAO,YAAY;IACnB,6DAA6D;IAC7D,QAAQ,aAAa;IACrB,yBAAyB;IACzB,OAAO,YAAY;IACnB,iCAAiC;IACjC,SAAS,YAAY;IACrB,kCAAkC;IAClC,MAAM,WAAW;IACjB,sBAAsB;IACtB,MAAM,WAAW;IACjB,uBAAuB;IACvB,OAAO,YAAY;IACnB,kGAAkG;IAClG,aAAa,kBAAkB;IAC/B,8CAA8C;IAC9C,YAAY,iBAAiB;IAC7B,wGAAwG;IACxG,YAAY,iBAAiB;IAC7B,oCAAoC;IACpC,gBAAgB,qBAAqB;IACrC,+EAA+E;IAC/E,OAAO,YAAY;IACnB,iCAAiC;IACjC,QAAQ,aAAa;IACrB,uBAAuB;IACvB,OAAO,YAAY;IACnB,0CAA0C;IAC1C,GAAG,QAAQ;CACZ;AAED,MAAM,MAAM,QAAQ,GAAG;IACrB;;;;;;OAMG;IACH,QAAQ,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACpC;;;OAGG;IACH,eAAe,EAAE,OAAO,GAAG,IAAI,CAAC;IAChC;;;;;OAKG;IACH,YAAY,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7B;;;;OAIG;IACH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,CAAC"}

View File

@@ -0,0 +1,59 @@
/**
* An enum mapping days of the week in Gregorian calendar to their index as returned by the `firstWeekday` property.
*/
export var Weekday;
(function (Weekday) {
Weekday[Weekday["SUNDAY"] = 1] = "SUNDAY";
Weekday[Weekday["MONDAY"] = 2] = "MONDAY";
Weekday[Weekday["TUESDAY"] = 3] = "TUESDAY";
Weekday[Weekday["WEDNESDAY"] = 4] = "WEDNESDAY";
Weekday[Weekday["THURSDAY"] = 5] = "THURSDAY";
Weekday[Weekday["FRIDAY"] = 6] = "FRIDAY";
Weekday[Weekday["SATURDAY"] = 7] = "SATURDAY";
})(Weekday || (Weekday = {}));
/**
* The calendar identifier, one of [Unicode calendar types](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale/calendar).
* Gregorian calendar is aliased and can be referred to as both `CalendarIdentifier.GREGORIAN` and `CalendarIdentifier.GREGORY`.
*/
export var CalendarIdentifier;
(function (CalendarIdentifier) {
/** Thai Buddhist calendar */
CalendarIdentifier["BUDDHIST"] = "buddhist";
/** Traditional Chinese calendar */
CalendarIdentifier["CHINESE"] = "chinese";
/** Coptic calendar */
CalendarIdentifier["COPTIC"] = "coptic";
/** Traditional Korean calendar */
CalendarIdentifier["DANGI"] = "dangi";
/** Ethiopic calendar, Amete Alem (epoch approx. 5493 B.C.E) */
CalendarIdentifier["ETHIOAA"] = "ethioaa";
/** Ethiopic calendar, Amete Mihret (epoch approx, 8 C.E.) */
CalendarIdentifier["ETHIOPIC"] = "ethiopic";
/** Gregorian calendar */
CalendarIdentifier["GREGORY"] = "gregory";
/** Gregorian calendar (alias) */
CalendarIdentifier["GREGORIAN"] = "gregory";
/** Traditional Hebrew calendar */
CalendarIdentifier["HEBREW"] = "hebrew";
/** Indian calendar */
CalendarIdentifier["INDIAN"] = "indian";
/** Islamic calendar */
CalendarIdentifier["ISLAMIC"] = "islamic";
/** Islamic calendar, tabular (intercalary years [2,5,7,10,13,16,18,21,24,26,29] - civil epoch) */
CalendarIdentifier["ISLAMIC_CIVIL"] = "islamic-civil";
/** Islamic calendar, Saudi Arabia sighting */
CalendarIdentifier["ISLAMIC_RGSA"] = "islamic-rgsa";
/**Islamic calendar, tabular (intercalary years [2,5,7,10,13,16,18,21,24,26,29] - astronomical epoch) */
CalendarIdentifier["ISLAMIC_TBLA"] = "islamic-tbla";
/** Islamic calendar, Umm al-Qura */
CalendarIdentifier["ISLAMIC_UMALQURA"] = "islamic-umalqura";
/** ISO calendar (Gregorian calendar using the ISO 8601 calendar week rules) */
CalendarIdentifier["ISO8601"] = "iso8601";
/** Japanese imperial calendar */
CalendarIdentifier["JAPANESE"] = "japanese";
/** Persian calendar */
CalendarIdentifier["PERSIAN"] = "persian";
/** Civil (algorithmic) Arabic calendar */
CalendarIdentifier["ROC"] = "roc";
})(CalendarIdentifier || (CalendarIdentifier = {}));
//# sourceMappingURL=Localization.types.js.map

File diff suppressed because one or more lines are too long