From 7e654cf5e5a493ff902891ab95b6376b7f76a28b Mon Sep 17 00:00:00 2001 From: CommanderRedYT Date: Sat, 9 Dec 2023 18:34:52 +0100 Subject: [PATCH] Implemented information screens --- README.md | 8 +- babel.config.js | 1 + licenses.json | 8 +- package.json | 2 +- src/App.tsx | 17 +- src/api/ApiHandler.tsx | 51 ++- src/api/opendtuapi.ts | 108 ++++-- src/components/Charts/UnifiedLineChart.tsx | 66 +++- src/components/devices/MDNSScan.tsx | 33 +- src/components/devices/MDNSScanItem.tsx | 5 + src/components/modals/AddDatabaseModal.tsx | 4 - src/components/styled/SettingsSurface.tsx | 10 + src/database/index.tsx | 5 +- src/database/prometheus.ts | 13 +- src/slices/opendtu.ts | 21 + src/translations/en.json | 72 +++- src/types/opendtu/state.ts | 23 +- src/types/opendtu/status.ts | 60 +++ src/views/navigation/NavigationStack.tsx | 18 + .../navigation/screens/AboutOpenDTUScreen.tsx | 358 +++++++++++------- .../screens/MqttInformationScreen.tsx | 277 ++++++++++++++ .../screens/NetworkInformationScreen.tsx | 180 +++++++++ .../screens/NtpInformationScreen.tsx | 135 +++++++ .../screens/SetupAddOpenDTUScreen.tsx | 6 +- src/views/navigation/tabs/LivedataTab.tsx | 27 +- src/views/navigation/tabs/MainSettingsTab.tsx | 36 ++ yarn.lock | 187 ++++++--- 27 files changed, 1434 insertions(+), 297 deletions(-) create mode 100644 src/components/styled/SettingsSurface.tsx create mode 100644 src/views/navigation/screens/MqttInformationScreen.tsx create mode 100644 src/views/navigation/screens/NetworkInformationScreen.tsx create mode 100644 src/views/navigation/screens/NtpInformationScreen.tsx diff --git a/README.md b/README.md index b4f203a..e3df50c 100644 --- a/README.md +++ b/README.md @@ -19,10 +19,10 @@ I am a OpenDTU user, but I am not affiliated with the original project. However, - [ ] Firmware Upgrade with Firmware Browser - [ ] Device Reboot - [ ] Information - - [ ] System Information - - [ ] Network Information - - [ ] NTP Information - - [ ] MQTT Information + - [x] System Information + - [x] Network Information + - [x] NTP Information + - [x] MQTT Information - [ ] tbd if also console - [ ] Livedata - [x] Today's Yield diff --git a/babel.config.js b/babel.config.js index 751fdaa..856c182 100644 --- a/babel.config.js +++ b/babel.config.js @@ -18,6 +18,7 @@ module.exports = { shippedProposals: true, }, ], + //['@babel/plugin-transform-private-property-in-object', { loose: true }], 'react-native-reanimated/plugin', [ 'module-resolver', diff --git a/licenses.json b/licenses.json index c682b06..f588b89 100644 --- a/licenses.json +++ b/licenses.json @@ -5,7 +5,7 @@ "licenseUrl": "git@gitlab.com:os-team/libs/utils", "parents": "opendtu-react-native" }, - "@react-native-async-storage/async-storage@1.19.5": { + "@react-native-async-storage/async-storage@1.19.8": { "licenses": "MIT", "repository": "https://github.com/react-native-async-storage/async-storage", "licenseUrl": "https://github.com/react-native-async-storage/async-storage/raw/master/LICENSE", @@ -106,7 +106,7 @@ "licenseUrl": "https://github.com/ds300/postinstall-postinstall/raw/master/LICENSE", "parents": "opendtu-react-native" }, - "prometheus-query@3.3.2": { + "prometheus-query@3.3.3": { "licenses": "MIT", "repository": "https://github.com/samber/prometheus-query-js", "licenseUrl": "https://github.com/samber/prometheus-query-js/raw/master/LICENSE", @@ -136,7 +136,7 @@ "licenseUrl": "https://github.com/yamankatby/react-native-flex-layout/raw/master/LICENSE", "parents": "opendtu-react-native" }, - "react-native-get-random-values@1.9.0": { + "react-native-get-random-values@1.10.0": { "licenses": "MIT", "repository": "https://github.com/LinusU/react-native-get-random-values", "licenseUrl": "https://github.com/LinusU/react-native-get-random-values/raw/master/LICENSE", @@ -166,7 +166,7 @@ "licenseUrl": "https://github.com/web-ridge/react-native-paper-dates/raw/master/LICENSE", "parents": "opendtu-react-native" }, - "react-native-paper@5.11.1": { + "react-native-paper@5.11.2": { "licenses": "MIT", "repository": "https://github.com/callstack/react-native-paper", "licenseUrl": "https://github.com/callstack/react-native-paper/raw/master/LICENSE.md", diff --git a/package.json b/package.json index 979a5da..77df0b1 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "react-native-linear-gradient": "^2.8.3", "react-native-logs": "^5.0.1", "react-native-markdown-display": "^7.0.0-alpha.2", - "react-native-paper": "^5.11.0", + "react-native-paper": "^5.11.2", "react-native-paper-dates": "^0.20.4", "react-native-reanimated": "^3.5.4", "react-native-safe-area-context": "^4.7.2", diff --git a/src/App.tsx b/src/App.tsx index 9107590..2fb9925 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -54,7 +54,7 @@ const App = () => { const LightTheme: MD3Theme = { ...MD3LightTheme, - colors: { + /*colors: { primary: 'rgb(0, 95, 175)', onPrimary: 'rgb(255, 255, 255)', primaryContainer: 'rgb(212, 227, 255)', @@ -95,12 +95,12 @@ const LightTheme: MD3Theme = { surfaceDisabled: 'rgba(26, 28, 30, 0.12)', onSurfaceDisabled: 'rgba(26, 28, 30, 0.38)', backdrop: 'rgba(45, 49, 56, 0.4)', - }, + },*/ }; const DarkTheme: MD3Theme = { ...MD3DarkTheme, - colors: { + /*colors: { primary: 'rgb(165, 200, 255)', onPrimary: 'rgb(0, 49, 95)', primaryContainer: 'rgb(0, 71, 134)', @@ -141,7 +141,7 @@ const DarkTheme: MD3Theme = { surfaceDisabled: 'rgba(227, 226, 230, 0.12)', onSurfaceDisabled: 'rgba(227, 226, 230, 0.38)', backdrop: 'rgba(45, 49, 56, 0.4)', - }, + },*/ }; const _App: FC = () => { @@ -153,14 +153,21 @@ const _App: FC = () => { const darkMode = useMemo(() => { if (appTheme === 'system') { + console.log('systemModeWantsDark', systemModeWantsDark); return systemModeWantsDark; } + console.log('appTheme === dark', appTheme === 'dark'); return appTheme === 'dark'; }, [appTheme, systemModeWantsDark]); const theme = useMemo(() => { - if (darkMode) return DarkTheme; + if (darkMode) { + console.log('darkMode'); + return DarkTheme; + } + + console.log('lightMode'); return LightTheme; }, [darkMode]); diff --git a/src/api/ApiHandler.tsx b/src/api/ApiHandler.tsx index ab53d89..2255247 100644 --- a/src/api/ApiHandler.tsx +++ b/src/api/ApiHandler.tsx @@ -7,6 +7,9 @@ import { setDeviceState, setIsConnected, setLiveData, + setMqttStatus, + setNetworkStatus, + setNtpStatus, setSystemStatus, setTriedToConnect, } from '@/slices/opendtu'; @@ -81,21 +84,39 @@ export const ApiProvider: FC> = ({ children }) => { dispatch(setDeviceState({ deviceState: DeviceState.Connected, index })); }); - api.registerSystemStatusHandler((data, index) => { - if (data.systemStatus) { - dispatch(setSystemStatus({ data: data.systemStatus })); - dispatch( - updateDtuHostname({ hostname: data.systemStatus.hostname, index }), - ); - dispatch( - updateDtuCustomNameIfEmpty({ - customName: data.systemStatus.hostname, - index, - }), - ); - } - setDeviceState({ deviceState: DeviceState.Connected, index }); - }); + api.registerHttpStatusHandler( + ({ systemStatus, networkStatus, ntpStatus, mqttStatus }, index) => { + if (systemStatus) { + dispatch(setSystemStatus({ data: systemStatus })); + dispatch( + updateDtuHostname({ + hostname: systemStatus.hostname, + index, + }), + ); + dispatch( + updateDtuCustomNameIfEmpty({ + customName: systemStatus.hostname, + index, + }), + ); + } + + if (networkStatus) { + dispatch(setNetworkStatus({ data: networkStatus })); + } + + if (ntpStatus) { + dispatch(setNtpStatus({ data: ntpStatus })); + } + + if (mqttStatus) { + dispatch(setMqttStatus({ data: mqttStatus })); + } + + setDeviceState({ deviceState: DeviceState.Connected, index }); + }, + ); console.log('Connecting API Handler'); diff --git a/src/api/opendtuapi.ts b/src/api/opendtuapi.ts index 251c756..eef038a 100644 --- a/src/api/opendtuapi.ts +++ b/src/api/opendtuapi.ts @@ -3,7 +3,13 @@ import { logger } from 'react-native-logs'; import type { OpenDTUAuthenticateResponse } from '@/types/opendtu/authenticate'; import { DeviceState } from '@/types/opendtu/state'; -import type { LiveData, SystemStatus } from '@/types/opendtu/status'; +import type { + LiveData, + MqttStatus, + NetworkStatus, + NtpStatus, + SystemStatus, +} from '@/types/opendtu/status'; import type { Index, OpenDTUConfig } from '@/types/settings'; const log = logger.createLogger(); @@ -19,10 +25,15 @@ export interface GetSystemStatusReturn { deviceState: DeviceState; } -export type SystemStatusHandler = ( - data: GetSystemStatusReturn, - index: Index, -) => void; +export interface HttpStatusData { + systemStatus?: SystemStatus; + deviceState: DeviceState; + networkStatus: NetworkStatus | null; + ntpStatus: NtpStatus | null; + mqttStatus: MqttStatus | null; +} + +export type HttpStatusHandler = (data: HttpStatusData, index: Index) => void; class OpenDtuApi { // variables for communication @@ -32,7 +43,7 @@ class OpenDtuApi { // handlers private liveDataHandler: LiveDataHandler | null = null; - private systemStatusHandler: SystemStatusHandler | null = null; + private httpStatusHandler: HttpStatusHandler | null = null; private onConnectedHandler: ((index: Index) => void) | null = null; private onDisconnectedHandler: (() => void) | null = null; @@ -107,12 +118,12 @@ class OpenDtuApi { this.liveDataHandler = null; } - public registerSystemStatusHandler(handler: SystemStatusHandler): void { - this.systemStatusHandler = handler; + public registerHttpStatusHandler(handler: HttpStatusHandler): void { + this.httpStatusHandler = handler; } - public unregisterSystemStatusHandler(): void { - this.systemStatusHandler = null; + public unregisterHttpStatusHandler(): void { + this.httpStatusHandler = null; } public registerOnConnectedHandler(handler: (index: Index) => void): void { @@ -431,20 +442,28 @@ class OpenDtuApi { public async updateHttpState(): Promise { log.info('OpenDtuApi.updateHttpState()'); - if (this.systemStatusHandler && this.index !== null) { - const systemStatus = await this.getSystemStatus(); + if (this.index === null) { + log.warn('OpenDtuApi.updateHttpState() index is null'); + return; + } - if ( - systemStatus.systemStatus && - 'git_hash' in systemStatus.systemStatus - ) { - this.systemStatusHandler(systemStatus, this.index); - } else { - console.log('OpenDtuApi.updateHttpState() systemStatus is invalid'); - } - } else { - console.log('OpenDtuApi.updateHttpState() systemStatusHandler is null'); + if (!this.httpStatusHandler) { + log.warn('OpenDtuApi.updateHttpState() httpStatusHandler is null'); + return; } + + const systemStatus = await this.getSystemStatus(); + + this.httpStatusHandler( + { + systemStatus: systemStatus.systemStatus, + deviceState: systemStatus.deviceState, + networkStatus: await this.getNetworkStatus(), + ntpStatus: await this.getNtpStatus(), + mqttStatus: await this.getMqttStatus(), + }, + this.index, + ); } private getAuthString(): string { @@ -463,6 +482,51 @@ class OpenDtuApi { return ''; } + public async getNetworkStatus(): Promise { + if (!this.baseUrl) { + return null; + } + + const res = await this.makeAuthenticatedRequest( + '/api/network/status', + 'GET', + ); + + if (res.status === 200) { + return await res.json(); + } + + return null; + } + + public async getNtpStatus(): Promise { + if (!this.baseUrl) { + return null; + } + + const res = await this.makeAuthenticatedRequest('/api/ntp/status', 'GET'); + + if (res.status === 200) { + return await res.json(); + } + + return null; + } + + public async getMqttStatus(): Promise { + if (!this.baseUrl) { + return null; + } + + const res = await this.makeAuthenticatedRequest('/api/mqtt/status', 'GET'); + + if (res.status === 200) { + return await res.json(); + } + + return null; + } + public async makeAuthenticatedRequest( route: string, method: string, diff --git a/src/components/Charts/UnifiedLineChart.tsx b/src/components/Charts/UnifiedLineChart.tsx index f32d33e..8ea82c8 100644 --- a/src/components/Charts/UnifiedLineChart.tsx +++ b/src/components/Charts/UnifiedLineChart.tsx @@ -7,7 +7,7 @@ import { Platform, processColor, TouchableOpacity, View } from 'react-native'; import type { LineChartProps } from 'react-native-charts-wrapper'; import { LineChart } from 'react-native-charts-wrapper'; import { Box } from 'react-native-flex-layout'; -import { Text, useTheme } from 'react-native-paper'; +import { Icon, Text, useTheme } from 'react-native-paper'; import SkeletonPlaceholder from 'react-native-skeleton-placeholder'; import StyledSurface from '@/components/styled/StyledSurface'; @@ -15,6 +15,7 @@ import StyledSurface from '@/components/styled/StyledSurface'; import useOrientation from '@/hooks/useOrientation'; import { GrafanaColors, GrafanaTextColors } from '@/database'; +import { useAppSelector } from '@/store'; export interface ChartData { data?: LineChartProps['data']; @@ -57,6 +58,12 @@ const UnifiedLineChart: FC = props => { const chartRef = useRef(null); + const isRelativeTime = useAppSelector( + state => + state.database.timeRange.end === 'now' && + typeof state.database.timeRange.start === 'object', + ); + useEffect(() => { // remove 100px for top and bottom padding setHeight(Math.min(screenHeight - 200, HEIGHT)); @@ -168,6 +175,33 @@ const UnifiedLineChart: FC = props => { setAvgValuePerDataSet(avgValues); }, [data]); + const timeRangeText = useMemo(() => { + if (!isRelativeTime) { + return `${moment(from).format('L HH:mm:ss')} - ${moment(to).format( + 'L HH:mm:ss', + )}`; + } + + // last N {seconds, minutes, hours, days, weeks, months, years} + const diff = moment(to).diff(moment(from), 'seconds'); + + if (diff < 60) { + return t('charts.lastNSeconds', { n: diff }); + } + + if (diff < 60 * 60) { + return t('charts.lastNMinutes', { n: Math.round(diff / 60) }); + } + + if (diff < 60 * 60 * 24) { + return t('charts.lastNHours', { n: Math.round(diff / 60 / 60) }); + } + + if (diff < 60 * 60 * 24 * 7) { + return t('charts.lastNDays', { n: Math.round(diff / 60 / 60 / 24) }); + } + }, [from, isRelativeTime, t, to]); + if (error) { return ( @@ -184,6 +218,12 @@ const UnifiedLineChart: FC = props => { > {title}: {error} + + {t('charts.checkDatabase')} + ); @@ -212,7 +252,7 @@ const UnifiedLineChart: FC = props => { alignItems: 'center', justifyContent: 'space-between', marginTop: 10, - marginLeft: 4, + marginHorizontal: 4, }} > = props => { > {title} - - {moment(from).format('L HH:mm:ss')} -{' '} - {moment(to).format('L HH:mm:ss')} - + + + + {timeRangeText} + + = props => { labelRotationAngle: 45, valueFormatter: 'date', timeUnit: 'MILLISECONDS', - valueFormatterPattern: 'd.M.Y HH:mm', + valueFormatterPattern: 'HH:mm', since: Platform.OS === 'android' ? UNIX_TS_FIRST_SECOND_OF_2000 diff --git a/src/components/devices/MDNSScan.tsx b/src/components/devices/MDNSScan.tsx index 93e5fca..8ffc109 100644 --- a/src/components/devices/MDNSScan.tsx +++ b/src/components/devices/MDNSScan.tsx @@ -1,5 +1,5 @@ import type { FC } from 'react'; -import React, { useEffect, useMemo } from 'react'; +import React, { useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { FlatList } from 'react-native'; import { Box } from 'react-native-flex-layout'; @@ -12,16 +12,18 @@ import MDNSScanItem from '@/components/devices/MDNSScanItem'; export interface MDNSScanProps { setError: (error: string) => void; setLoading: (loading: boolean) => void; + loading: boolean; } -const MDNSScan: FC = ({ setError, setLoading }) => { +const MDNSScan: FC = ({ setError, setLoading, loading }) => { const { t } = useTranslation(); - const zeroconf = useMemo(() => new Zeroconf(), []); - const [discovering, setDiscovering] = React.useState(false); - const [services, setServices] = React.useState([]); + const [discovering, setDiscovering] = useState(false); + const [services, setServices] = useState([]); useEffect(() => { + const zeroconf = new Zeroconf(); + zeroconf.on('start', () => { setDiscovering(true); }); @@ -62,26 +64,34 @@ const MDNSScan: FC = ({ setError, setLoading }) => { setDiscovering(false); setServices([]); }; - }, [zeroconf]); + }, []); + + console.log('services', services); if (discovering && services.length === 0) { return ( - {t('mdns.scanning')} - + {t('mdns.scanning')} + ); } if (!discovering && services.length === 0) { - return {t('mdns.noDevicesFound')}; + return ( + + {t('mdns.noDevicesFound')} + + ); } return ( @@ -92,6 +102,7 @@ const MDNSScan: FC = ({ setError, setLoading }) => { service={item} setError={setError} setLoading={setLoading} + loading={loading} /> )} keyExtractor={item => item.name} diff --git a/src/components/devices/MDNSScanItem.tsx b/src/components/devices/MDNSScanItem.tsx index d47b388..fa37e7c 100644 --- a/src/components/devices/MDNSScanItem.tsx +++ b/src/components/devices/MDNSScanItem.tsx @@ -17,12 +17,14 @@ export interface MDNSScanItemProps { service: Service; setError: (error: string) => void; setLoading: (loading: boolean) => void; + loading: boolean; } const MDNSScanItem: FC = ({ service, setError, setLoading, + loading, }) => { const openDtuApi = useApi(); const dispatch = useAppDispatch(); @@ -34,6 +36,7 @@ const MDNSScanItem: FC = ({ ); const handlePress = useCallback(async () => { + setLoading(true); const url = new URL(`http://${service.host}:${service.port}`); try { @@ -78,6 +81,7 @@ const MDNSScanItem: FC = ({ dispatch(setSetupBaseUrl({ baseUrl })); navigation.navigate('SetupAuthenticateOpenDTUInstanceScreen'); + setLoading(false); }, [ baseUrls, dispatch, @@ -95,6 +99,7 @@ const MDNSScanItem: FC = ({ description={service.txt?.model} left={props => } onPress={handlePress} + disabled={loading} /> ); }; diff --git a/src/components/modals/AddDatabaseModal.tsx b/src/components/modals/AddDatabaseModal.tsx index bf1fbf5..64aec2f 100644 --- a/src/components/modals/AddDatabaseModal.tsx +++ b/src/components/modals/AddDatabaseModal.tsx @@ -76,7 +76,6 @@ const AddDatabaseModal: FC = props => { @@ -85,7 +84,6 @@ const AddDatabaseModal: FC = props => { = props => { @@ -104,7 +101,6 @@ const AddDatabaseModal: FC = props => { > = ({ children }) => { ); const refreshFunc = useCallback(async () => { - if (typeof database === 'undefined' || inverters === null) return; + if (typeof database === 'undefined' || inverters === null) { + setIsFetching(false); + return; + } setIsFetching(true); diff --git a/src/database/prometheus.ts b/src/database/prometheus.ts index 6933ccb..e5929b8 100644 --- a/src/database/prometheus.ts +++ b/src/database/prometheus.ts @@ -68,7 +68,7 @@ class PrometheusDatabase implements Database { const { inverters } = args; if (!this.statusSuccess) { - return { message: 'Could not fetch status', success: false }; + return { message: 'Could not fetch database status', success: false }; } const serialList = inverters.map(inverter => inverter.serial).join('|'); @@ -82,7 +82,7 @@ class PrometheusDatabase implements Database { const { inverters } = args; if (!this.statusSuccess) { - return { message: 'Could not fetch status', success: false }; + return { message: 'Could not fetch database status', success: false }; } const serialList = inverters.map(inverter => inverter.serial).join('|'); @@ -96,7 +96,7 @@ class PrometheusDatabase implements Database { const { inverters } = args; if (!this.statusSuccess) { - return { message: 'Could not fetch status', success: false }; + return { message: 'Could not fetch database status', success: false }; } const serialList = inverters.map(inverter => inverter.serial).join('|'); @@ -110,7 +110,7 @@ class PrometheusDatabase implements Database { const { inverters } = args; if (!this.statusSuccess) { - return { message: 'Could not fetch status', success: false }; + return { message: 'Could not fetch database status', success: false }; } const serialList = inverters.map(inverter => inverter.serial).join('|'); @@ -188,7 +188,10 @@ class PrometheusDatabase implements Database { const e = error as Error; console.log('try catch', e.message); - return { message: e.message ?? 'Unknown error', success: false }; + return { + message: e.message ?? `Unknown error (${e.name})`, + success: false, + }; } } diff --git a/src/slices/opendtu.ts b/src/slices/opendtu.ts index 78c0c68..98bee95 100644 --- a/src/slices/opendtu.ts +++ b/src/slices/opendtu.ts @@ -9,11 +9,17 @@ import type { SetIsConnectedAction, SetDeviceStateAction, SetTriedToConnectAction, + SetNetworkStatusAction, + SetNtpStatusAction, + SetMqttStatusAction, } from '@/types/opendtu/state'; const initialState: OpenDTUState = { liveData: null, systemStatus: null, + networkStatus: null, + ntpStatus: null, + mqttStatus: null, setup: { userString: null, baseUrl: null, @@ -83,6 +89,18 @@ const opendtuSlice = createSlice({ clearOpenDtuState: state => { state.liveData = null; state.systemStatus = null; + state.networkStatus = null; + state.ntpStatus = null; + state.mqttStatus = null; + }, + setNetworkStatus: (state, action: SetNetworkStatusAction) => { + state.networkStatus = action.payload.data; + }, + setNtpStatus: (state, action: SetNtpStatusAction) => { + state.ntpStatus = action.payload.data; + }, + setMqttStatus: (state, action: SetMqttStatusAction) => { + state.mqttStatus = action.payload.data; }, }, }); @@ -99,6 +117,9 @@ export const { clearDeviceState, setTriedToConnect, clearOpenDtuState, + setNetworkStatus, + setNtpStatus, + setMqttStatus, } = opendtuSlice.actions; export const { reducer: OpenDTUReducer } = opendtuSlice; diff --git a/src/translations/en.json b/src/translations/en.json index b0c612a..d514dc9 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -45,7 +45,12 @@ "acCurrent": "AC Current", "minMaxAvg": "min: {{min}} {{unit}} max: {{max}} {{unit}} avg: {{avg}} {{unit}}", "noDatabaseConfigured": "No database configured", - "noDatabaseConfiguredDescription": "To see charts, configure and assign a database to your DTU." + "noDatabaseConfiguredDescription": "To see charts, configure and assign a database to your DTU.", + "lastNSeconds": "Last {{n}} seconds", + "lastNMinutes": "Last {{n}} minutes", + "lastNHours": "Last {{n}} hours", + "lastNDays": "Last {{n}} days", + "checkDatabase": "Check if the database is running and reachable." }, "setup": { "setupComplete": "Setup complete! \uD83C\uDF89", @@ -187,10 +192,73 @@ "nrf24ChipType": "nRF24 Chip Type", "cmt2300aStatus": "CMT2300A Status", "cmt2300aChipStatus": "CMT2300A Chip Status" + }, + "networkInformation": "Network Information", + "networkInformationDescription": "WiFi \u2022 Ethernet \u2022 mDNS", + "networkInformationScreen": { + "wifiStation": "WiFi Station", + "wifiAccessPoint": "WiFi Access Point", + "wifiStationInterface": "WiFi Station Interface", + "wifiAccessPointInterface": "WiFi Access Point Interface", + "status": "Status", + "ssid": "SSID", + "bssid": "BSSID", + "quality": "Quality", + "rssi": "Signal Strength", + "numberOfStations": "Number of Stations", + "hostname": "Hostname", + "ipAddress": "IP Address", + "subnetMask": "Subnet Mask", + "gateway": "Gateway", + "dns1": "DNS 1", + "dns2": "DNS 2", + "macAddress": "MAC Address" + }, + "ntpInformation": "NTP Information", + "ntpInformationDescription": "NTP Configuration \u2022 NTP Status", + "ntpInformationScreen": { + "configurationSummary": "Configuration Summary", + "ntpServer": "NTP Server", + "ntpTimezone": "NTP Timezone", + "ntpTimezoneDescription": "NTP Timezone Description", + "status": "Status", + "currentTime": "Current Time", + "localTime": "Local Time", + "sunrise": "Sunrise", + "sunset": "Sunset", + "mode": "Mode", + "day": "Day", + "night": "Night" + }, + "mqttInformation": "MQTT Information", + "mqttInformationDescription": "MQTT Configuration \u2022 MQTT Status", + "mqttInformationScreen": { + "configurationSummary": "Configuration Summary", + "status": "Status", + "server": "Server", + "username": "Username", + "port": "Port", + "baseTopic": "Base Topic", + "publishInterval": "Publish Interval", + "cleansessionFlag": "CleanSession Flag", + "retain": "Retain", + "tls": "TLS", + "loginWithTlsCertificate": "Login with TLS Certificate", + "homeAssistantAutoDiscovery": "Home Assistant Auto Discovery", + "expire": "Expire", + "individualPanels": "Individual Panels", + "runtimeSummary": "Runtime Summary", + "connectionStatus": "Connection Status" } }, "connected": "Connected", "notConnected": "Not connected", "configured": "Configured", - "notConfigured": "Not configured" + "notConfigured": "Not configured", + "enabled": "Enabled", + "disabled": "Disabled", + "unavailable": "Unavailable", + "synced": "Synced", + "notSynced": "Not synced", + "n_seconds": "{{n}} seconds" } diff --git a/src/types/opendtu/state.ts b/src/types/opendtu/state.ts index a3d7b1c..b969f66 100644 --- a/src/types/opendtu/state.ts +++ b/src/types/opendtu/state.ts @@ -1,6 +1,12 @@ import type { PayloadAction } from '@reduxjs/toolkit'; -import type { LiveData, SystemStatus } from '@/types/opendtu/status'; +import type { + LiveData, + MqttStatus, + NetworkStatus, + NtpStatus, + SystemStatus, +} from '@/types/opendtu/status'; import type { Index } from '@/types/settings'; export enum DeviceState { @@ -44,6 +50,18 @@ export type SetTriedToConnectAction = PayloadAction<{ triedToConnect: boolean; }>; +export type SetNetworkStatusAction = PayloadAction<{ + data: NetworkStatus; +}>; + +export type SetNtpStatusAction = PayloadAction<{ + data: NtpStatus; +}>; + +export type SetMqttStatusAction = PayloadAction<{ + data: MqttStatus; +}>; + export interface OpenDTUSetup { baseUrl: string | null; userString: string | null; @@ -52,6 +70,9 @@ export interface OpenDTUSetup { export interface OpenDTUState { liveData: LiveData | null; systemStatus: SystemStatus | null; + networkStatus: NetworkStatus | null; + ntpStatus: NtpStatus | null; + mqttStatus: MqttStatus | null; setup: OpenDTUSetup; isConnected: boolean; deviceState: Record; diff --git a/src/types/opendtu/status.ts b/src/types/opendtu/status.ts index adda3e5..63f0895 100644 --- a/src/types/opendtu/status.ts +++ b/src/types/opendtu/status.ts @@ -92,3 +92,63 @@ export interface SystemStatus { cmt_configured: boolean; cmt_connected: boolean; } + +export interface NetworkStatus { + // WifiStationInfo + sta_status: boolean; + sta_ssid: string; + sta_bssid: string; + sta_rssi: number; + + // WifiApInfo + ap_status: boolean; + ap_ssid: string; + ap_stationnum: number; + + // InterfaceNetworkInfo + network_hostname: string; + network_ip: string; + network_netmask: string; + network_gateway: string; + network_dns1: string; + network_dns2: string; + network_mac: string; + network_mode: string; + + // InterfaceApInfo + ap_ip: string; + ap_mac: string; +} + +export interface MqttStatus { + mqtt_enabled: boolean; + mqtt_hostname: string; + mqtt_port: number; + mqtt_username: string; + mqtt_topic: string; + mqtt_publish_interval: number; + mqtt_clean_session: boolean; + mqtt_retain: boolean; + mqtt_tls: boolean; + mqtt_root_ca_cert_info: string; + mqtt_tls_cert_login: boolean; + mqtt_client_cert_info: string; + mqtt_connected: boolean; + mqtt_hass_enabled: boolean; + mqtt_hass_expire: boolean; + mqtt_hass_retain: boolean; + mqtt_hass_topic: string; + mqtt_hass_individualpanels: boolean; +} + +export interface NtpStatus { + ntp_server: string; + ntp_timezone: string; + ntp_timezone_descr: string; + ntp_status: boolean; + ntp_localtime: string; + sun_risetime: string; + sun_settime: string; + sun_isDayPeriod: boolean; + sun_isSunsetAvailable: boolean; +} diff --git a/src/views/navigation/NavigationStack.tsx b/src/views/navigation/NavigationStack.tsx index 6d30a5f..661a8ce 100644 --- a/src/views/navigation/NavigationStack.tsx +++ b/src/views/navigation/NavigationStack.tsx @@ -15,6 +15,9 @@ import DeviceListScreen from '@/views/navigation/screens/DeviceListScreen'; import DeviceSettingsScreen from '@/views/navigation/screens/DeviceSettingsScreen'; import MainScreen from '@/views/navigation/screens/MainScreen'; import ManageDatabasesScreen from '@/views/navigation/screens/ManageDatabasesScreen'; +import MqttInformationScreen from '@/views/navigation/screens/MqttInformationScreen'; +import NetworkInformationScreen from '@/views/navigation/screens/NetworkInformationScreen'; +import NtpInformationScreen from '@/views/navigation/screens/NtpInformationScreen'; import SelectDatabaseScreen from '@/views/navigation/screens/SelectDatabaseScreen'; import SetupAddOpenDTUScreen from '@/views/navigation/screens/SetupAddOpenDTUScreen'; import SetupAuthenticateOpenDTUInstanceScreen from '@/views/navigation/screens/SetupAuthenticateOpenDTUInstanceScreen'; @@ -95,6 +98,21 @@ const NavigationStack: FC = () => { component={AboutOpenDTUScreen} options={{ headerShown: false }} /> + + + ); }; diff --git a/src/views/navigation/screens/AboutOpenDTUScreen.tsx b/src/views/navigation/screens/AboutOpenDTUScreen.tsx index c5c83d4..e382ad4 100644 --- a/src/views/navigation/screens/AboutOpenDTUScreen.tsx +++ b/src/views/navigation/screens/AboutOpenDTUScreen.tsx @@ -10,6 +10,8 @@ import { Linking, ScrollView } from 'react-native'; import { Box } from 'react-native-flex-layout'; import { Appbar, List, useTheme } from 'react-native-paper'; +import SettingsSurface from '@/components/styled/SettingsSurface'; + import formatBytes from '@/utils/formatBytes'; import percentage from '@/utils/percentage'; @@ -75,151 +77,217 @@ const AboutOpenDTUScreen: FC = () => { - - - {t('opendtu.systemInformationScreen.firmwareInformation')} - - - - - } - onPress={openGitHub} - /> - - - - - - - - - {t('opendtu.systemInformationScreen.hardwareInformation')} - - - - - - - - - {t('opendtu.systemInformationScreen.memoryInformation')} - - - - - - - - {t('opendtu.systemInformationScreen.radioInformation')} - - - - - - - + + + + + + } + onPress={openGitHub} + /> + + + + + + + + + + + + + + + + + + + + + + + + + ( + + )} + /> + ( + + )} + /> + ( + + )} + /> + ( + + )} + /> + ( + + )} + /> + + diff --git a/src/views/navigation/screens/MqttInformationScreen.tsx b/src/views/navigation/screens/MqttInformationScreen.tsx new file mode 100644 index 0000000..72e053f --- /dev/null +++ b/src/views/navigation/screens/MqttInformationScreen.tsx @@ -0,0 +1,277 @@ +import type { NavigationProp, ParamListBase } from '@react-navigation/native'; +import { useNavigation } from '@react-navigation/native'; + +import type { FC } from 'react'; +import { useCallback } from 'react'; +import { useTranslation } from 'react-i18next'; +import { ScrollView } from 'react-native'; +import { Box } from 'react-native-flex-layout'; +import { Appbar, List, useTheme } from 'react-native-paper'; + +import SettingsSurface from '@/components/styled/SettingsSurface'; + +import { useAppSelector } from '@/store'; +import { StyledSafeAreaView } from '@/style'; + +const MqttInformationScreen: FC = () => { + const theme = useTheme(); + const { t } = useTranslation(); + + const navigation = useNavigation() as NavigationProp; + + const handleBack = useCallback(() => { + navigation.goBack(); + }, [navigation]); + + const mqttStatus = useAppSelector(state => state.opendtu.mqttStatus); + + return ( + <> + + + + + + + + + + ( + + )} + /> + + + + + + ( + + )} + /> + ( + + )} + /> + ( + + )} + /> + ( + + )} + /> + + + + + ( + + )} + /> + + ( + + )} + /> + ( + + )} + /> + ( + + )} + /> + + + + + ( + + )} + /> + + + + + + + ); +}; + +export default MqttInformationScreen; diff --git a/src/views/navigation/screens/NetworkInformationScreen.tsx b/src/views/navigation/screens/NetworkInformationScreen.tsx new file mode 100644 index 0000000..2e9a9e8 --- /dev/null +++ b/src/views/navigation/screens/NetworkInformationScreen.tsx @@ -0,0 +1,180 @@ +import type { NavigationProp, ParamListBase } from '@react-navigation/native'; +import { useNavigation } from '@react-navigation/native'; + +import type { FC } from 'react'; +import { useCallback, useMemo } from 'react'; +import { useTranslation } from 'react-i18next'; +import { ScrollView } from 'react-native'; +import { Box } from 'react-native-flex-layout'; +import { Appbar, List, useTheme } from 'react-native-paper'; + +import SettingsSurface from '@/components/styled/SettingsSurface'; + +import { useAppSelector } from '@/store'; +import { StyledSafeAreaView } from '@/style'; + +const NetworkInformationScreen: FC = () => { + const theme = useTheme(); + const { t } = useTranslation(); + + const navigation = useNavigation() as NavigationProp; + + const handleBack = useCallback(() => { + navigation.goBack(); + }, [navigation]); + + const networkStatus = useAppSelector(state => state.opendtu.networkStatus); + + const wifiQuality = useMemo(() => { + let quality = 0; + + const rssi = networkStatus?.sta_rssi; + + if (typeof rssi !== 'number') return '0%'; + + if (rssi <= -100) { + quality = 0; + } else if (rssi >= -50) { + quality = 100; + } else { + quality = 2 * (rssi + 100); + } + + return `${quality}%`; + }, [networkStatus?.sta_rssi]); + + return ( + <> + + + + + + + + + + ( + + )} + /> + + + + + + + + + ( + + )} + /> + + + + {t('opendtu.networkInformationScreen.wifiStationInterface')} + + + + + + + + + + + + + + + + + + + + + ); +}; + +export default NetworkInformationScreen; diff --git a/src/views/navigation/screens/NtpInformationScreen.tsx b/src/views/navigation/screens/NtpInformationScreen.tsx new file mode 100644 index 0000000..6200d99 --- /dev/null +++ b/src/views/navigation/screens/NtpInformationScreen.tsx @@ -0,0 +1,135 @@ +import type { NavigationProp, ParamListBase } from '@react-navigation/native'; +import { useNavigation } from '@react-navigation/native'; + +import type { FC } from 'react'; +import { useCallback } from 'react'; +import { useTranslation } from 'react-i18next'; +import { ScrollView } from 'react-native'; +import { Box } from 'react-native-flex-layout'; +import { Appbar, List, useTheme } from 'react-native-paper'; + +import SettingsSurface from '@/components/styled/SettingsSurface'; + +import { useAppSelector } from '@/store'; +import { StyledSafeAreaView } from '@/style'; + +const NtpInformationScreen: FC = () => { + const theme = useTheme(); + const { t } = useTranslation(); + + const navigation = useNavigation() as NavigationProp; + + const handleBack = useCallback(() => { + navigation.goBack(); + }, [navigation]); + + const ntpStatus = useAppSelector(state => state.opendtu.ntpStatus); + + return ( + <> + + + + + + + + + + + + + + + + + ( + + )} + /> + + + + ( + + )} + /> + + + + + + + ); +}; + +export default NtpInformationScreen; diff --git a/src/views/navigation/screens/SetupAddOpenDTUScreen.tsx b/src/views/navigation/screens/SetupAddOpenDTUScreen.tsx index 878646e..11d5c87 100644 --- a/src/views/navigation/screens/SetupAddOpenDTUScreen.tsx +++ b/src/views/navigation/screens/SetupAddOpenDTUScreen.tsx @@ -141,7 +141,11 @@ const SetupAddOpenDTUScreen: FC = ({ navigation }) => { {t('setup.instancesInYourNetwork')} - + diff --git a/src/views/navigation/tabs/LivedataTab.tsx b/src/views/navigation/tabs/LivedataTab.tsx index caec247..7e75a0f 100644 --- a/src/views/navigation/tabs/LivedataTab.tsx +++ b/src/views/navigation/tabs/LivedataTab.tsx @@ -7,7 +7,11 @@ import DeviceOfflineWrapper from '@/components/DeviceOfflineWrapper'; import DeviceStatus from '@/components/DeviceStatus'; import ImportantStatusValues from '@/components/ImportantStatusValues'; -import { useDatabaseIsFetching, useRefreshDatabase } from '@/database'; +import { + useDatabase, + useDatabaseIsFetching, + useRefreshDatabase, +} from '@/database'; import { StyledSafeAreaView, StyledScrollView } from '@/style'; const LivedataTab = () => { @@ -17,11 +21,14 @@ const LivedataTab = () => { const refreshing = useDatabaseIsFetching(); const triggerRefresh = useRefreshDatabase(); + const database = useDatabase(); const handleRefresh = useCallback(() => { + if (!database) return; + triggerRefresh?.(); setIsRefreshing(true); - }, [triggerRefresh]); + }, [database, triggerRefresh]); useEffect(() => { if (!refreshing) { @@ -35,13 +42,15 @@ const LivedataTab = () => { + database ? ( + + ) : undefined } > diff --git a/src/views/navigation/tabs/MainSettingsTab.tsx b/src/views/navigation/tabs/MainSettingsTab.tsx index 4d31dcc..5dba1dc 100644 --- a/src/views/navigation/tabs/MainSettingsTab.tsx +++ b/src/views/navigation/tabs/MainSettingsTab.tsx @@ -43,6 +43,18 @@ const MainSettingsTab: FC = () => { navigation.navigate('AboutOpenDTUScreen'); }, [navigation]); + const handleNetworkInformation = useCallback(() => { + navigation.navigate('NetworkInformationScreen'); + }, [navigation]); + + const handleNtpInformation = useCallback(() => { + navigation.navigate('NtpInformationScreen'); + }, [navigation]); + + const handleMqttInformation = useCallback(() => { + navigation.navigate('MqttInformationScreen'); + }, [navigation]); + return ( @@ -78,6 +90,30 @@ const MainSettingsTab: FC = () => { disabled={!websocketConnected} style={{ opacity: websocketConnected ? 1 : 0.5 }} /> + } + onPress={handleNetworkInformation} + disabled={!websocketConnected} + style={{ opacity: websocketConnected ? 1 : 0.5 }} + /> + } + onPress={handleNtpInformation} + disabled={!websocketConnected} + style={{ opacity: websocketConnected ? 1 : 0.5 }} + /> + } + onPress={handleMqttInformation} + disabled={!websocketConnected} + style={{ opacity: websocketConnected ? 1 : 0.5 }} + /> diff --git a/yarn.lock b/yarn.lock index 2a72549..a13cbad 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15,7 +15,7 @@ "@jridgewell/gen-mapping" "^0.3.0" "@jridgewell/trace-mapping" "^0.3.9" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.22.13": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13": version "7.22.13" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.13.tgz#e3c1c099402598483b7a8c46a721d1038803755e" integrity sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w== @@ -23,6 +23,14 @@ "@babel/highlight" "^7.22.13" chalk "^2.4.2" +"@babel/code-frame@^7.22.13": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.23.4.tgz#03ae5af150be94392cb5c7ccd97db5a19a5da6aa" + integrity sha512-r1IONyb6Ia+jYR2vvIDhdWdlTGhqbBoFqLTQidzZ4kepUFH15ejXvFHxCVbtl7BOXIudsIubf4E81xeA3h3IXA== + dependencies: + "@babel/highlight" "^7.23.4" + chalk "^2.4.2" + "@babel/compat-data@^7.20.5": version "7.23.2" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.23.2.tgz#6a12ced93455827037bfb5ed8492820d60fc32cc" @@ -269,10 +277,10 @@ dependencies: "@babel/types" "^7.22.5" -"@babel/helper-string-parser@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" - integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== +"@babel/helper-string-parser@^7.22.5", "@babel/helper-string-parser@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz#9478c707febcbbe1ddb38a3d91a2e054ae622d83" + integrity sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ== "@babel/helper-validator-identifier@^7.16.7", "@babel/helper-validator-identifier@^7.22.20": version "7.22.20" @@ -302,10 +310,10 @@ "@babel/traverse" "^7.23.2" "@babel/types" "^7.23.0" -"@babel/highlight@^7.22.13": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.20.tgz#4ca92b71d80554b01427815e06f2df965b9c1f54" - integrity sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg== +"@babel/highlight@^7.22.13", "@babel/highlight@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.23.4.tgz#edaadf4d8232e1a961432db785091207ead0621b" + integrity sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A== dependencies: "@babel/helper-validator-identifier" "^7.22.20" chalk "^2.4.2" @@ -316,11 +324,16 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.0.tgz#da950e622420bf96ca0d0f2909cdddac3acd8719" integrity sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw== -"@babel/parser@^7.20.5", "@babel/parser@^7.22.15", "@babel/parser@^7.23.0", "@babel/parser@^7.23.3": +"@babel/parser@^7.20.5", "@babel/parser@^7.23.0", "@babel/parser@^7.23.3": version "7.23.3" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.3.tgz#0ce0be31a4ca4f1884b5786057cadcb6c3be58f9" integrity sha512-uVsWNvlVsIninV2prNz/3lHCb+5CJ+e+IUBfbjToAHODtfGYLfCFuY4AU7TskI+dAKk+njsPiBjq1gKTvZOBaw== +"@babel/parser@^7.22.15": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.4.tgz#409fbe690c333bb70187e2de4021e1e47a026661" + integrity sha512-vf3Xna6UEprW+7t6EtOmFpHNAuxw3xqPZghy+brsnusscJRW5BMUzzHZc5ICjULee81WeUV2jjakG09MDglJXQ== + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.23.3": version "7.23.3" resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.23.3.tgz#5cd1c87ba9380d0afb78469292c954fee5d2411a" @@ -661,9 +674,9 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-class-static-block@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.23.3.tgz#56f2371c7e5bf6ff964d84c5dc4d4db5536b5159" - integrity sha512-PENDVxdr7ZxKPyi5Ffc0LjXdnJyrJxyqF5T5YjlVg4a0VFfQHW0r8iAtRiDXkfHlu1wwcvdtnndGYIeJLSuRMQ== + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.23.4.tgz#2a202c8787a8964dd11dfcedf994d36bfc844ab5" + integrity sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ== dependencies: "@babel/helper-create-class-features-plugin" "^7.22.15" "@babel/helper-plugin-utils" "^7.22.5" @@ -1328,13 +1341,20 @@ resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310" integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== -"@babel/runtime@^7.0.0", "@babel/runtime@^7.12.1", "@babel/runtime@^7.20.0", "@babel/runtime@^7.22.5", "@babel/runtime@^7.23.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": +"@babel/runtime@^7.0.0", "@babel/runtime@^7.12.1", "@babel/runtime@^7.22.5", "@babel/runtime@^7.23.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": version "7.23.2" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.2.tgz#062b0ac103261d68a966c4c7baf2ae3e62ec3885" integrity sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg== dependencies: regenerator-runtime "^0.14.0" +"@babel/runtime@^7.20.0": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.4.tgz#36fa1d2b36db873d25ec631dcc4923fdc1cf2e2e" + integrity sha512-2Yv65nlWnWlSpe3fXEyX5i7fx5kIKo4Qbcj+hMO0odwaneFjfXw5fdum+4yL20O0QiaHpia0cYQ9xpNMqrBwHg== + dependencies: + regenerator-runtime "^0.14.0" + "@babel/template@^7.0.0", "@babel/template@^7.22.15", "@babel/template@^7.22.5", "@babel/template@^7.3.3": version "7.22.15" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.15.tgz#09576efc3830f0430f4548ef971dde1350ef2f38" @@ -1393,7 +1413,7 @@ "@babel/helper-validator-identifier" "^7.22.20" to-fast-properties "^2.0.0" -"@babel/types@^7.17.0", "@babel/types@^7.22.15", "@babel/types@^7.22.19", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.23.3", "@babel/types@^7.4.4": +"@babel/types@^7.17.0", "@babel/types@^7.22.19", "@babel/types@^7.23.3", "@babel/types@^7.4.4": version "7.23.3" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.3.tgz#d5ea892c07f2ec371ac704420f4dcdb07b5f9598" integrity sha512-OZnvoH2l8PK5eUvEcUyCt/sXgr/h+UWpVuBbOljwcrAgUl6lpchoQ++PHGyQy1AtYnVA6CEq3y5xeEI10brpXw== @@ -1402,6 +1422,15 @@ "@babel/helper-validator-identifier" "^7.22.20" to-fast-properties "^2.0.0" +"@babel/types@^7.22.15", "@babel/types@^7.22.5", "@babel/types@^7.23.0": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.4.tgz#7206a1810fc512a7f7f7d4dace4cb4c1c9dbfb8e" + integrity sha512-7uIFwVYpoplT5jp/kVv6EF93VaJ8H+Yn5IczYiaAi98ajzjfoZfslet/e0sLh+wVBjb2qqIut1b0S26VSafsSQ== + dependencies: + "@babel/helper-string-parser" "^7.23.4" + "@babel/helper-validator-identifier" "^7.22.20" + to-fast-properties "^2.0.0" + "@bcoe/v8-coverage@^0.2.3": version "0.2.3" resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" @@ -1464,10 +1493,10 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@eslint/js@8.53.0": - version "8.53.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.53.0.tgz#bea56f2ed2b5baea164348ff4d5a879f6f81f20d" - integrity sha512-Kn7K8dx/5U6+cT1yEhpX1w4PCSg0M+XyRILPgvwcEBjerFWCwQj5sbr3/VmxqV0JGHCBCzyd6LxypEuehypY1w== +"@eslint/js@8.54.0": + version "8.54.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.54.0.tgz#4fab9a2ff7860082c304f750e94acd644cf984cf" + integrity sha512-ut5V+D+fOoWPgGGNj83GGjnntO39xDy6DWxO0wb7Jp3DcMX0TfIqdzHF85VTQkerdyGmuuMD9AKAo5KiNlf/AQ== "@hapi/hoek@^9.0.0": version "9.3.0" @@ -2066,9 +2095,9 @@ integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== "@react-native-async-storage/async-storage@^1.19.3": - version "1.19.5" - resolved "https://registry.yarnpkg.com/@react-native-async-storage/async-storage/-/async-storage-1.19.5.tgz#d59dd493b2b25346412085dd48896cabca011eed" - integrity sha512-zLT7oNPXpW8BxJyHyq8AJbXtlHE/eonFWuJt44y0WeCGnp4KOJ8mfqD8mtAIKLyrYHHE1uadFe/s4C+diYAi8g== + version "1.19.8" + resolved "https://registry.yarnpkg.com/@react-native-async-storage/async-storage/-/async-storage-1.19.8.tgz#a29fc4f4aa5c85805f8b3edea84e19f797c59fdd" + integrity sha512-O25eaSbmH+LEmOobkpwf43bAGIkqE9YGzfWcirTszI90xk4ItaDWpgJsQx9LeAbeAKzVkn1h+Nq5Bo6I6q2oFA== dependencies: merge-options "^3.0.4" @@ -2556,9 +2585,9 @@ integrity sha512-yj7cmccUiAeHp6E6DMt+rprzVoBA+be60dEZEi9tyFLZsutNyKG6K7jgGmPO+gV0pT/aMjeklEP0p/XgExJANA== "@types/prop-types@*": - version "15.7.10" - resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.10.tgz#892afc9332c4d62a5ea7e897fe48ed2085bbb08a" - integrity sha512-mxSnDQxPqsZxmeShFH+uwQ4kO4gcJcGahjjMFeLbKE95IAZiiZyiEepGZjtXJ7hN/yfu0bu9xN2ajcU0JcxX6A== + version "15.7.11" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.11.tgz#2596fb352ee96a1379c657734d4b913a613ad563" + integrity sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng== "@types/react-native-charts-wrapper@^0.5.9": version "0.5.9" @@ -2584,25 +2613,25 @@ "@types/react" "*" "@types/react-test-renderer@^18.0.0": - version "18.0.6" - resolved "https://registry.yarnpkg.com/@types/react-test-renderer/-/react-test-renderer-18.0.6.tgz#1db32c09d3931a7f4ed7f31612f6cccb2910d28f" - integrity sha512-O2JT1J3/v/NaYHYmPf2DXBSqUGmp6iwhFPicES6Pc1Y90B9Qgu99mmaBGqfZFpVuXLzF/pNJB4K9ySL3iqFeXA== + version "18.0.7" + resolved "https://registry.yarnpkg.com/@types/react-test-renderer/-/react-test-renderer-18.0.7.tgz#2cfe657adb3688cdf543995eceb2e062b5a68728" + integrity sha512-1+ANPOWc6rB3IkSnElhjv6VLlKg2dSv/OWClUyZimbLsQyBn8Js9Vtdsi3UICJ2rIQ3k2la06dkB+C92QfhKmg== dependencies: "@types/react" "*" "@types/react@*", "@types/react@^18.0.24": - version "18.2.37" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.37.tgz#0f03af69e463c0f19a356c2660dbca5d19c44cae" - integrity sha512-RGAYMi2bhRgEXT3f4B92WTohopH6bIXw05FuGlmJEnv/omEn190+QYEIYxIAuIBdKgboYYdVved2p1AxZVQnaw== + version "18.2.38" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.38.tgz#3605ca41d3daff2c434e0b98d79a2469d4c2dd52" + integrity sha512-cBBXHzuPtQK6wNthuVMV6IjHAFkdl/FOPFIlkd81/Cd1+IqkHu/A+w4g43kaQQoYHik/ruaQBDL72HyCy1vuMw== dependencies: "@types/prop-types" "*" "@types/scheduler" "*" csstype "^3.0.2" "@types/scheduler@*": - version "0.16.6" - resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.6.tgz#eb26db6780c513de59bee0b869ef289ad3068711" - integrity sha512-Vlktnchmkylvc9SnwwwozTv04L/e1NykF5vgoQ0XTmI8DD+wxfjQuHuvHS3p0r2jz2x2ghPs2h1FVeDirIteWA== + version "0.16.8" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.8.tgz#ce5ace04cfeabe7ef87c0091e50752e36707deff" + integrity sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A== "@types/semver@^7.3.12": version "7.5.3" @@ -2615,9 +2644,9 @@ integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== "@types/styled-components@^5.1.28": - version "5.1.30" - resolved "https://registry.yarnpkg.com/@types/styled-components/-/styled-components-5.1.30.tgz#7f2b2c01245e3274083091517c7205c9ce9dd420" - integrity sha512-xxJqw0s1myRTgrzHgG5tKHS9hK+KNhjbKMXDWlHRo9eDNVVUqf147QUGYUqwyCDkFyGr2pi1qJKFMEy0ACZb0A== + version "5.1.32" + resolved "https://registry.yarnpkg.com/@types/styled-components/-/styled-components-5.1.32.tgz#58718971519c4562229ba85face98e8530d21bfd" + integrity sha512-DqVpl8R0vbhVSop4120UHtGrFmHuPeoDwF4hDT0kPJTY8ty0SI38RV3VhCMsWigMUXG+kCXu7vMRqMFNy6eQgA== dependencies: "@types/hoist-non-react-statics" "*" "@types/react" "*" @@ -3030,6 +3059,11 @@ asynciterator.prototype@^1.0.0: dependencies: has-symbols "^1.0.3" +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + at-least-node@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" @@ -3040,12 +3074,14 @@ available-typed-arrays@^1.0.5: resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== -axios@^0.26.1: - version "0.26.1" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.26.1.tgz#1ede41c51fcf51bbbd6fd43669caaa4f0495aaa9" - integrity sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA== +axios@^1.6.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.2.tgz#de67d42c755b571d3e698df1b6504cde9b0ee9f2" + integrity sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A== dependencies: - follow-redirects "^1.14.8" + follow-redirects "^1.15.0" + form-data "^4.0.0" + proxy-from-env "^1.1.0" babel-core@^7.0.0-bridge.0: version "7.0.0-bridge.0" @@ -3534,6 +3570,13 @@ colorette@^1.0.7: resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.4.0.tgz#5190fbb87276259a86ad700bff2c6d6faa3fca40" integrity sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g== +combined-stream@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + command-exists@^1.2.8: version "1.2.9" resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.9.tgz#c50725af3808c8ab0260fd60b01fbfa25b954f69" @@ -3793,6 +3836,11 @@ define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0, de has-property-descriptors "^1.0.0" object-keys "^1.1.1" +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + denodeify@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/denodeify/-/denodeify-1.2.1.tgz#3a36287f5034e699e7577901052c2e6c94251631" @@ -4220,14 +4268,14 @@ eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4 integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== eslint@^8.19.0: - version "8.53.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.53.0.tgz#14f2c8244298fcae1f46945459577413ba2697ce" - integrity sha512-N4VuiPjXDUa4xVeV/GC/RV3hQW9Nw+Y463lkWaKKXKYMvmRiRDAtfpuPFLN+E1/6ZhyR8J2ig+eVREnYgUsiag== + version "8.54.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.54.0.tgz#588e0dd4388af91a2e8fa37ea64924074c783537" + integrity sha512-NY0DfAkM8BIZDVl6PgSa1ttZbx3xHgJzSNJKYcQglem6CppHyMhRIQkBVSSMaSRnLhig3jsDbEzOjwCVt4AmmA== dependencies: "@eslint-community/eslint-utils" "^4.2.0" "@eslint-community/regexpp" "^4.6.1" "@eslint/eslintrc" "^2.1.3" - "@eslint/js" "8.53.0" + "@eslint/js" "8.54.0" "@humanwhocodes/config-array" "^0.11.13" "@humanwhocodes/module-importer" "^1.0.1" "@nodelib/fs.walk" "^1.2.8" @@ -4517,7 +4565,7 @@ flow-parser@^0.206.0: resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.206.0.tgz#f4f794f8026535278393308e01ea72f31000bfef" integrity sha512-HVzoK3r6Vsg+lKvlIZzaWNBVai+FXTX1wdYhz/wVlH13tb/gOdLXmlTqy6odmTBhT5UoWUbq0k8263Qhr9d88w== -follow-redirects@^1.14.8: +follow-redirects@^1.15.0: version "1.15.3" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.3.tgz#fe2f3ef2690afce7e82ed0b44db08165b207123a" integrity sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q== @@ -4537,6 +4585,15 @@ foreground-child@^3.1.0: cross-spawn "^7.0.0" signal-exit "^4.0.1" +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + fresh@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" @@ -4877,11 +4934,16 @@ ieee754@^1.1.13: resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== -ignore@^5.0.5, ignore@^5.2.0: +ignore@^5.0.5: version "5.2.4" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== +ignore@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.0.tgz#67418ae40d34d6999c95ff56016759c718c82f78" + integrity sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg== + image-size@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/image-size/-/image-size-1.0.2.tgz#d778b6d0ab75b2737c1556dd631652eb963bc486" @@ -6451,7 +6513,7 @@ mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -mime-types@^2.1.27, mime-types@~2.1.34: +mime-types@^2.1.12, mime-types@^2.1.27, mime-types@~2.1.34: version "2.1.35" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== @@ -7110,11 +7172,11 @@ process-nextick-args@~2.0.0: integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== prometheus-query@^3.3.2: - version "3.3.2" - resolved "https://registry.yarnpkg.com/prometheus-query/-/prometheus-query-3.3.2.tgz#b1f605fad7d771b8992d77c61087bd6fbbf180cc" - integrity sha512-xNgDjDdueiTkA3sY9CJPLa4OgGGoH1ug+TPq3aYY6hnhN7nq1ykP9UmciWnMTYCc178eQ3yesG4HFsRg72CgOg== + version "3.3.3" + resolved "https://registry.yarnpkg.com/prometheus-query/-/prometheus-query-3.3.3.tgz#5c4212c11cc606d45cc61aaa3ceaeed84e47c529" + integrity sha512-BL76MllxFdgaXUw1tOtg1osvgaDpHdq0PjUVvWTMXRr/txRxdY4TvQ4k6il9xxUL+L52qOWr4XZKXGWF3n7GZw== dependencies: - axios "^0.26.1" + axios "^1.6.0" promise@^8.3.0: version "8.3.0" @@ -7145,6 +7207,11 @@ proto-list@~1.2.1: resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" integrity sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA== +proxy-from-env@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + punycode@^2.1.0: version "2.3.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" @@ -7250,9 +7317,9 @@ react-native-flex-layout@^0.1.5: integrity sha512-DrLir5Wl0RhgJXHeDBSaa1Y1LdpNuoz0PEe5E1T1+xVWt2DAz/r+1N8bnhtVkTKJE6WrH6jIH2hoe8kogR0X+w== react-native-get-random-values@^1.9.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/react-native-get-random-values/-/react-native-get-random-values-1.9.0.tgz#6cb30511c406922e75fe73833dc1812a85bfb37e" - integrity sha512-+29IR2oxzxNVeaRwCqGZ9ABadzMI8SLTBidrIDXPOkKnm5+kEmLt34QKM4JV+d2usPErvKyS85le0OmGTHnyWQ== + version "1.10.0" + resolved "https://registry.yarnpkg.com/react-native-get-random-values/-/react-native-get-random-values-1.10.0.tgz#c2c5f12a4ef8b1175145347b4a4b9f9a40d9ffc8" + integrity sha512-gZ1zbXhbb8+Jy9qYTV8c4Nf45/VB4g1jmXuavY5rPfUn7x3ok9Vl3FTl0dnE92Z4FFtfbUNNwtSfcmomdtWg+A== dependencies: fast-base64-decode "^1.0.0" @@ -7283,10 +7350,10 @@ react-native-paper-dates@^0.20.4: dependencies: color "^3.2.1" -react-native-paper@^5.11.0: - version "5.11.1" - resolved "https://registry.yarnpkg.com/react-native-paper/-/react-native-paper-5.11.1.tgz#34f612d6fb28099334db08a1bd109086ea91dcac" - integrity sha512-axqRTagGL8LtuYh172cx2Q2THOVJ3PTpPjCKhL5ECRdpJs2ceiboVecSiOIBuO3H7dVpaneptBA0vJr9HeVHwg== +react-native-paper@^5.11.2: + version "5.11.2" + resolved "https://registry.yarnpkg.com/react-native-paper/-/react-native-paper-5.11.2.tgz#447b7cae8eaf578e6133ca8f56131b78f4c3cfa1" + integrity sha512-UbMkoGtOzU2T54b1uUnqc6YA0kz5mCUxoA4VLcePHDAi/Nvk54gm/TkZnP6nImUMjpcSBI4Fj0GI1cx9Cp169w== dependencies: "@callstack/react-theme-provider" "^3.0.9" color "^3.1.2"