diff --git a/apps/mobile/app/common/filesystem/utils.ts b/apps/mobile/app/common/filesystem/utils.ts index 6998fd68f..e5f87a39e 100644 --- a/apps/mobile/app/common/filesystem/utils.ts +++ b/apps/mobile/app/common/filesystem/utils.ts @@ -192,7 +192,8 @@ export async function checkAndCreateDir(path: string) { } export const santizeUri = (uri: string) => { - return Platform.OS === "ios" ? decodeURI(uri).replace("file:///", "/") : uri; + const decoded = decodeURI(uri); + return Platform.OS === "ios" ? decoded.replace("file:///", "/") : decoded; }; export function isSuccessStatusCode(statusCode: number) { diff --git a/apps/mobile/app/screens/settings/theme-selector.tsx b/apps/mobile/app/screens/settings/theme-selector.tsx index 073adbd02..8193b40c6 100644 --- a/apps/mobile/app/screens/settings/theme-selector.tsx +++ b/apps/mobile/app/screens/settings/theme-selector.tsx @@ -63,6 +63,8 @@ import { getElevationStyle } from "../../utils/elevation"; import { MenuItemsList } from "../../utils/menu-items"; import { AppFontSize, defaultBorderRadius } from "../../utils/size"; import { DefaultAppStyles } from "../../utils/styles"; +import { openLinkInBrowser } from "../../utils/functions"; +import Clipboard from "@react-native-clipboard/clipboard"; const THEME_SERVER_URL = "https://themes-api.notesnook.com"; //@ts-ignore @@ -441,14 +443,55 @@ function ThemeSelector() { ReactNativeBlobUtil.fs .unlink(themeJsonCopiedPath) .catch(() => {}); - const json = JSON.parse(themeJson); + let json; + try { + json = JSON.parse(themeJson); + } catch (e) { + ToastManager.show({ + heading: strings.invalidThemeFileFormat(), + type: "error", + context: "global", + actionText: strings.learnMore(), + func: () => { + openLinkInBrowser( + "https://help.notesnook.com/custom-themes/introduction" + ); + } + }); + return; + } const result = validateTheme(json); + if (result.error) { - ToastManager.error(new Error(result.error)); + if ( + typeof result.error === "string" && + result.error.includes("missing from the theme") + ) { + ToastManager.show({ + heading: strings.themeMissingRequiredFields(), + type: "error", + context: "global", + actionText: strings.copyLogs(), + func: () => { + Clipboard.setString(result.error || ""); + ToastManager.show({ + heading: strings.logsCopied(), + type: "success", + context: "global" + }); + } + }); + } else { + ToastManager.error(new Error(result.error)); + } + return; } select(json, true); } catch (e) { + if ((e as Error).message.includes("Code=3072")) { + return; + } ToastManager.error(e as Error); } }} diff --git a/packages/intl/locale/en.po b/packages/intl/locale/en.po index 842f61e8a..33aac399f 100644 --- a/packages/intl/locale/en.po +++ b/packages/intl/locale/en.po @@ -1868,6 +1868,10 @@ msgstr "Copy link" msgid "Copy link text" msgstr "Copy link text" +#: src/strings.ts:2694 +msgid "Copy logs" +msgstr "Copy logs" + #: src/strings.ts:454 msgid "Copy note" msgstr "Copy note" @@ -7273,6 +7277,14 @@ msgstr "We are creating a backup of your data. Please wait..." msgid "We are sorry, it seems that the app crashed due to an error. You can submit a bug report below so we can fix this asap." msgstr "We are sorry, it seems that the app crashed due to an error. You can submit a bug report below so we can fix this asap." +#: src/strings.ts:2700 +msgid "We couldn't load this theme. Please make sure the file is a valid JSON theme file." +msgstr "We couldn't load this theme. Please make sure the file is a valid JSON theme file." + +#: src/strings.ts:2693 +msgid "We couldn't load this theme. The file appears to be incomplete or missing required theme properties." +msgstr "We couldn't load this theme. The file appears to be incomplete or missing required theme properties." + #: src/strings.ts:1390 msgid "We have sent you an email confirmation link. Please check your email inbox. If you cannot find the email, check your spam folder." msgstr "We have sent you an email confirmation link. Please check your email inbox. If you cannot find the email, check your spam folder." diff --git a/packages/intl/locale/pseudo-LOCALE.po b/packages/intl/locale/pseudo-LOCALE.po index 103ffefb4..20a8dae61 100644 --- a/packages/intl/locale/pseudo-LOCALE.po +++ b/packages/intl/locale/pseudo-LOCALE.po @@ -1857,6 +1857,10 @@ msgstr "" msgid "Copy link text" msgstr "" +#: src/strings.ts:2694 +msgid "Copy logs" +msgstr "" + #: src/strings.ts:454 msgid "Copy note" msgstr "" @@ -7221,6 +7225,14 @@ msgstr "" #: src/strings.ts:474 msgid "We are sorry, it seems that the app crashed due to an error. You can submit a bug report below so we can fix this asap." +msgstr "<<<<<<< HEAD" + +#: src/strings.ts:2700 +msgid "We couldn't load this theme. Please make sure the file is a valid JSON theme file." +msgstr "" + +#: src/strings.ts:2693 +msgid "We couldn't load this theme. The file appears to be incomplete or missing required theme properties." msgstr "" #: src/strings.ts:1390 diff --git a/packages/intl/src/strings.ts b/packages/intl/src/strings.ts index 79024af1b..aeb5e97f1 100644 --- a/packages/intl/src/strings.ts +++ b/packages/intl/src/strings.ts @@ -2695,5 +2695,10 @@ Continue without attachments?`, t`Creation date cannot be after last edited date`, noteDuplicated: () => t`Note duplicated`, maximumReminderDate: (maxDate: string) => - t`Maximum reminder date is ${maxDate}` + t`Maximum reminder date is ${maxDate}`, + invalidThemeFileFormat: () => + t`We couldn't load this theme. Please make sure the file is a valid JSON theme file.`, + themeMissingRequiredFields: () => + t`We couldn't load this theme. The file appears to be incomplete or missing required theme properties.`, + copyLogs: () => t`Copy logs` };