diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index f200221..f6f0561 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -39,6 +39,8 @@
+
+
diff --git a/src/components/firmware/FirmwareListItem.tsx b/src/components/firmware/FirmwareListItem.tsx
index be03485..80d2549 100644
--- a/src/components/firmware/FirmwareListItem.tsx
+++ b/src/components/firmware/FirmwareListItem.tsx
@@ -2,6 +2,7 @@ import type { FC } from 'react';
import { useCallback, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { Badge, Divider, List, Text, useTheme } from 'react-native-paper';
+import Toast from 'react-native-toast-message';
import { Linking, View } from 'react-native';
@@ -18,6 +19,7 @@ import useDtuState from '@/hooks/useDtuState';
import useHasAuthConfigured from '@/hooks/useHasAuthConfigured';
import capitalize from '@/utils/capitalize';
+import { rootLogging } from '@/utils/log';
import { minimumOpenDtuFirmwareVersion, spacing } from '@/constants';
import type { SupportedLanguage } from '@/translations';
@@ -35,6 +37,8 @@ const needsCapitalization: Record = {
de: true,
};
+const log = rootLogging.extend('FirmwareListItem');
+
const FirmwareListItem: FC = ({
release,
selectRelease,
@@ -53,8 +57,14 @@ const FirmwareListItem: FC = ({
if (await Linking.canOpenURL(url)) {
await Linking.openURL(url);
+ } else {
+ log.error(`Cannot open URL: ${url}`);
+ Toast.show({
+ type: 'error',
+ text1: t('cannotOpenUrl'),
+ });
}
- }, [release.html_url]);
+ }, [release.html_url, t]);
const handleInstallFirmware = useCallback(() => {
selectRelease(release);
diff --git a/src/components/modals/ChangeLanguageModal.tsx b/src/components/modals/ChangeLanguageModal.tsx
index 7446975..f12cfde 100644
--- a/src/components/modals/ChangeLanguageModal.tsx
+++ b/src/components/modals/ChangeLanguageModal.tsx
@@ -10,6 +10,7 @@ import {
Text,
useTheme,
} from 'react-native-paper';
+import Toast from 'react-native-toast-message';
import { Linking } from 'react-native';
@@ -53,10 +54,13 @@ const ChangeLanguageModal: FC> = props => {
if (await Linking.canOpenURL(weblateUrl)) {
await Linking.openURL(weblateUrl);
} else {
- // TODO: Better error handling (issue #101)
log.error('Cannot open Weblate URL');
+ Toast.show({
+ type: 'error',
+ text1: t('cannotOpenUrl'),
+ });
}
- }, []);
+ }, [t]);
return (
diff --git a/src/translations b/src/translations
index 730dabd..fe5fb1e 160000
--- a/src/translations
+++ b/src/translations
@@ -1 +1 @@
-Subproject commit 730dabd97144a8616226258cc3309401003c3847
+Subproject commit fe5fb1e82a6f7cc2f861629935174212df81dfa9
diff --git a/src/views/navigation/screens/InformationGroup/LicensesScreen.tsx b/src/views/navigation/screens/InformationGroup/LicensesScreen.tsx
index 31d7b06..1902d4b 100644
--- a/src/views/navigation/screens/InformationGroup/LicensesScreen.tsx
+++ b/src/views/navigation/screens/InformationGroup/LicensesScreen.tsx
@@ -2,17 +2,22 @@ import type { FC } from 'react';
import { useTranslation } from 'react-i18next';
import { Box } from 'react-native-flex-layout';
import { Appbar, List, useTheme } from 'react-native-paper';
+import Toast from 'react-native-toast-message';
import { Linking, ScrollView, View } from 'react-native';
import type { Licenses } from 'npm-license-crawler';
+import { rootLogging } from '@/utils/log';
+
import { spacing } from '@/constants';
import { StyledView } from '@/style';
import type { PropsWithNavigation } from '@/views/navigation/NavigationStack';
import licenses from '@root/licenses.json';
+const log = rootLogging.extend('LicensesScreen');
+
const LicensesScreen: FC = ({ navigation }) => {
const { t } = useTranslation();
const theme = useTheme();
@@ -41,6 +46,12 @@ const LicensesScreen: FC = ({ navigation }) => {
const url = repository || licenseUrl;
if (await Linking.canOpenURL(url)) {
await Linking.openURL(url);
+ } else {
+ log.error(`Cannot open URL: ${url}`);
+ Toast.show({
+ type: 'error',
+ text1: t('cannotOpenUrl'),
+ });
}
}
: undefined
diff --git a/src/views/navigation/screens/InformationGroup/SystemInformationScreen.tsx b/src/views/navigation/screens/InformationGroup/SystemInformationScreen.tsx
index 75b478d..32a983b 100644
--- a/src/views/navigation/screens/InformationGroup/SystemInformationScreen.tsx
+++ b/src/views/navigation/screens/InformationGroup/SystemInformationScreen.tsx
@@ -3,6 +3,7 @@ import { useCallback, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { Box } from 'react-native-flex-layout';
import { Appbar, Badge, List, Switch, useTheme } from 'react-native-paper';
+import Toast from 'react-native-toast-message';
import { Linking, ScrollView, View } from 'react-native';
@@ -20,6 +21,7 @@ import useHasNewOpenDtuVersion from '@/hooks/useHasNewOpenDtuVersion';
import correctTag from '@/utils/correctTag';
import formatBytes from '@/utils/formatBytes';
+import { rootLogging } from '@/utils/log';
import percentage from '@/utils/percentage';
import { colors, spacing } from '@/constants';
@@ -27,6 +29,8 @@ import { useAppDispatch, useAppSelector } from '@/store';
import { StyledView } from '@/style';
import type { PropsWithNavigation } from '@/views/navigation/NavigationStack';
+const log = rootLogging.extend('SystemInformationScreen');
+
const SystemInformationScreen: FC = ({ navigation }) => {
const theme = useTheme();
const { t } = useTranslation();
@@ -62,8 +66,14 @@ const SystemInformationScreen: FC = ({ navigation }) => {
if (await Linking.canOpenURL(url)) {
await Linking.openURL(url);
+ } else {
+ log.error(`Cannot open URL: ${url}`);
+ Toast.show({
+ type: 'error',
+ text1: t('cannotOpenUrl'),
+ });
}
- }, [systemStatus]);
+ }, [systemStatus, t]);
const versionString = useMemo(() => {
if (!latestVersion || !systemStatus?.git_hash)