mirror of
https://github.com/streetwriters/notesnook.git
synced 2025-12-16 19:57:52 +01:00
mobile: migrate app to intl
This commit is contained in:
committed by
Abdullah Atta
parent
f282265fbb
commit
3e5b740ef0
@@ -35,7 +35,8 @@ const SCOPES = [
|
||||
"common",
|
||||
"global",
|
||||
"docs",
|
||||
"themebuilder"
|
||||
"themebuilder",
|
||||
"intl"
|
||||
];
|
||||
|
||||
module.exports = {
|
||||
|
||||
2758
apps/desktop/package-lock.json
generated
2758
apps/desktop/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -16,6 +16,8 @@ GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { i18n } from "@lingui/core";
|
||||
import { I18nProvider } from "@lingui/react";
|
||||
import {
|
||||
THEME_COMPATIBILITY_VERSION,
|
||||
useThemeEngineStore
|
||||
@@ -63,7 +65,9 @@ const App = () => {
|
||||
<View
|
||||
style={{
|
||||
height: "100%",
|
||||
width: "100%"
|
||||
width: "100%",
|
||||
justifyContent: "center",
|
||||
alignItems: "center"
|
||||
}}
|
||||
>
|
||||
<View
|
||||
@@ -138,7 +142,11 @@ export const withTheme = (Element: () => JSX.Element) => {
|
||||
currTheme = nextTheme;
|
||||
}
|
||||
|
||||
return <Element />;
|
||||
return (
|
||||
<I18nProvider i18n={i18n}>
|
||||
<Element />
|
||||
</I18nProvider>
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import Sodium from "@ammarahmed/react-native-sodium";
|
||||
import { getFileNameWithExtension } from "@notesnook/core";
|
||||
import { strings } from "@notesnook/intl";
|
||||
import React from "react";
|
||||
import { Platform } from "react-native";
|
||||
import RNFetchBlob from "react-native-blob-util";
|
||||
@@ -89,7 +90,7 @@ export async function downloadAttachments(attachments) {
|
||||
current: 0,
|
||||
total: 0,
|
||||
success: false,
|
||||
message: "Download cancelled",
|
||||
message: strings.network.dowloadCancelled(),
|
||||
canceled: true
|
||||
});
|
||||
return true;
|
||||
@@ -116,7 +117,7 @@ export async function downloadAttachments(attachments) {
|
||||
|
||||
if (isCancelled()) return;
|
||||
|
||||
if (!uri) throw new Error("Failed to download file");
|
||||
if (!uri) throw new Error(strings.failedToDownloadFile());
|
||||
// Move file to the source folder we will zip eventually and rename the file to it's actual name.
|
||||
const filePath = `${zipSourceFolder}/${attachment.filename}`;
|
||||
await RNFetchBlob.fs.mv(`${cacheDir}/${uri}`, filePath);
|
||||
@@ -139,7 +140,7 @@ export async function downloadAttachments(attachments) {
|
||||
useAttachmentStore.getState().setDownloading({
|
||||
current: 0,
|
||||
total: 1,
|
||||
message: "Saving zip file... Please wait",
|
||||
message: `${strings.savingZipFile()}... ${strings.pleaseWait()}`,
|
||||
groupId
|
||||
});
|
||||
// If all goes well, zip the notesnook-attachments folder in cache.
|
||||
@@ -149,9 +150,9 @@ export async function downloadAttachments(attachments) {
|
||||
groupId,
|
||||
current: progress,
|
||||
total: 1,
|
||||
message: `Saving zip file (${(progress * 100).toFixed(
|
||||
message: `${strings.savingZipFile()} (${(progress * 100).toFixed(
|
||||
1
|
||||
)}%)... Please wait`
|
||||
)}%)... ${strings.pleaseWait()}`
|
||||
});
|
||||
});
|
||||
await zip(zipSourceFolder, zipOutputFile);
|
||||
@@ -273,8 +274,8 @@ export default async function downloadAttachment(
|
||||
|
||||
if (!options.silent) {
|
||||
ToastManager.show({
|
||||
heading: "Download successful",
|
||||
message: filename + " downloaded",
|
||||
heading: strings.network.downloadSuccess(),
|
||||
message: strings.network.fileDownloaded(filename),
|
||||
type: "success"
|
||||
});
|
||||
}
|
||||
@@ -284,12 +285,8 @@ export default async function downloadAttachment(
|
||||
}
|
||||
if (!options.silent) {
|
||||
presentSheet({
|
||||
title: "File downloaded",
|
||||
paragraph: `${filename} saved to ${
|
||||
Platform.OS === "android"
|
||||
? "selected path"
|
||||
: "File Manager/Notesnook/downloads"
|
||||
}`,
|
||||
title: strings.network.fileDownloaded(),
|
||||
paragraph: strings.fileSaved(filename, Platform.OS),
|
||||
icon: "download",
|
||||
context: global ? null : attachment.hash,
|
||||
component: <ShareComponent uri={fileUri} name={filename} padding={12} />
|
||||
|
||||
@@ -17,6 +17,7 @@ You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { strings } from "@notesnook/intl";
|
||||
import NetInfo from "@react-native-community/netinfo";
|
||||
import RNFetchBlob from "react-native-blob-util";
|
||||
import { ToastManager } from "../../services/event-manager";
|
||||
@@ -48,12 +49,12 @@ export async function downloadFile(filename, requestOptions, cancelToken) {
|
||||
const size = await getUploadedFileSize(filename);
|
||||
|
||||
if (size === -1) {
|
||||
const error = `Uploaded file verification failed. (File hash: ${filename})`;
|
||||
const error = `${strings.fileVerificationFailed()} (File hash: ${filename})`;
|
||||
throw new Error(error);
|
||||
}
|
||||
|
||||
if (size === 0) {
|
||||
const error = `File length is 0. Please upload this file again from the attachment manager. (File hash: ${filename})`;
|
||||
const error = `${strings.fileLengthError()} (File hash: ${filename})`;
|
||||
await db.attachments.markAsFailed(attachment.id, error);
|
||||
throw new Error(error);
|
||||
}
|
||||
@@ -62,7 +63,10 @@ export async function downloadFile(filename, requestOptions, cancelToken) {
|
||||
const decryptedLength = size - totalChunks * ABYTES;
|
||||
|
||||
if (attachment && attachment.size !== decryptedLength) {
|
||||
const error = `File length mismatch. Expected ${attachment.size} but got ${decryptedLength} bytes. Please upload this file again from the attachment manager. (File hash: ${filename})`;
|
||||
const error = `${strings.fileLengthMismatch(
|
||||
attachment.size,
|
||||
decryptedLength
|
||||
)} (File hash: ${filename})`;
|
||||
await db.attachments.markAsFailed(attachment.id, error);
|
||||
throw new Error(error);
|
||||
}
|
||||
@@ -76,7 +80,9 @@ export async function downloadFile(filename, requestOptions, cancelToken) {
|
||||
DatabaseLogger.log(
|
||||
`Error downloading file: ${filename}, ${res.status}, ${res.statusText}, reason: Unable to resolve download url`
|
||||
);
|
||||
throw new Error(`${res.status}: Unable to resolve download url`);
|
||||
throw new Error(
|
||||
`${res.status}: ${strings.failedToResolvedDownloadUrl()}`
|
||||
);
|
||||
}
|
||||
|
||||
const downloadUrl = await res.text();
|
||||
@@ -85,7 +91,7 @@ export async function downloadFile(filename, requestOptions, cancelToken) {
|
||||
DatabaseLogger.log(
|
||||
`Error downloading file: ${filename}, reason: Unable to resolve download url`
|
||||
);
|
||||
throw new Error("Unable to resolve download url");
|
||||
throw new Error(strings.failedToResolvedDownloadUrl());
|
||||
}
|
||||
|
||||
DatabaseLogger.log(`Download starting: ${filename}`);
|
||||
@@ -138,18 +144,15 @@ export async function downloadFile(filename, requestOptions, cancelToken) {
|
||||
return status >= 200 && status < 300;
|
||||
} catch (e) {
|
||||
if (e.message !== "canceled" && !e.message.includes("NoSuchKey")) {
|
||||
ToastManager.show({
|
||||
heading: "Error downloading file",
|
||||
const toast = {
|
||||
heading: strings.downloadError(),
|
||||
message: e.message,
|
||||
type: "error",
|
||||
context: "global"
|
||||
});
|
||||
ToastManager.show({
|
||||
heading: "Error downloading file",
|
||||
message: e.message,
|
||||
type: "error",
|
||||
context: "local"
|
||||
});
|
||||
};
|
||||
ToastManager.show(toast);
|
||||
toast.context = "local";
|
||||
ToastManager.show(toast);
|
||||
}
|
||||
|
||||
useAttachmentStore.getState().remove(filename);
|
||||
|
||||
@@ -53,6 +53,7 @@ import Seperator from "../ui/seperator";
|
||||
import Heading from "../ui/typography/heading";
|
||||
import Paragraph from "../ui/typography/paragraph";
|
||||
import { KeyboardAwareScrollView } from "react-native-keyboard-aware-scroll-view";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
const getUser = () => {
|
||||
const user = MMKV.getString("user");
|
||||
@@ -157,7 +158,7 @@ const AppLockedOverlay = () => {
|
||||
password.current = undefined;
|
||||
} else {
|
||||
ToastManager.show({
|
||||
heading: `Invalid ${keyboardType === "numeric" ? "pin" : "password"}`,
|
||||
heading: strings.invalid(keyboardType),
|
||||
type: "error",
|
||||
context: "local"
|
||||
});
|
||||
@@ -250,7 +251,7 @@ const AppLockedOverlay = () => {
|
||||
textAlign: "center"
|
||||
}}
|
||||
>
|
||||
Unlock your notes
|
||||
{strings.unlockNotes()}
|
||||
</Heading>
|
||||
|
||||
<Paragraph
|
||||
@@ -260,7 +261,7 @@ const AppLockedOverlay = () => {
|
||||
maxWidth: "90%"
|
||||
}}
|
||||
>
|
||||
{"Please verify it's you"}
|
||||
{strings.verifyItsYou()}
|
||||
</Paragraph>
|
||||
<Seperator />
|
||||
<View
|
||||
@@ -301,7 +302,7 @@ const AppLockedOverlay = () => {
|
||||
{user || appLockHasPasswordSecurity ? (
|
||||
<>
|
||||
<Button
|
||||
title="Continue"
|
||||
title={strings.continue()}
|
||||
type="accent"
|
||||
onPress={onSubmit}
|
||||
width={250}
|
||||
@@ -317,7 +318,7 @@ const AppLockedOverlay = () => {
|
||||
|
||||
{biometricsAuthEnabled ? (
|
||||
<Button
|
||||
title="Unlock with Biometrics"
|
||||
title={strings.unlockWithBiometrics()}
|
||||
width={250}
|
||||
onPress={onUnlockAppRequested}
|
||||
icon={"fingerprint"}
|
||||
|
||||
@@ -57,6 +57,7 @@ import { Notice } from "../ui/notice";
|
||||
import { Pressable } from "../ui/pressable";
|
||||
import Heading from "../ui/typography/heading";
|
||||
import Paragraph from "../ui/typography/paragraph";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
const Actions = ({
|
||||
attachment,
|
||||
@@ -81,7 +82,7 @@ const Actions = ({
|
||||
|
||||
const actions = [
|
||||
{
|
||||
name: "Download",
|
||||
name: strings.network.download(),
|
||||
onPress: async () => {
|
||||
if (currentProgress) {
|
||||
await db.fs().cancel(attachment.hash);
|
||||
@@ -93,11 +94,11 @@ const Actions = ({
|
||||
icon: "download"
|
||||
},
|
||||
{
|
||||
name: "Reupload",
|
||||
name: strings.network.reupload(),
|
||||
onPress: async () => {
|
||||
if (!PremiumService.get()) {
|
||||
ToastManager.show({
|
||||
heading: "Upgrade to pro",
|
||||
heading: strings.upgradeToPro(),
|
||||
type: "error",
|
||||
context: "local"
|
||||
});
|
||||
@@ -113,10 +114,10 @@ const Actions = ({
|
||||
icon: "upload"
|
||||
},
|
||||
{
|
||||
name: "Run file check",
|
||||
name: strings.fileCheck(),
|
||||
onPress: async () => {
|
||||
setLoading({
|
||||
name: "Run file check"
|
||||
name: strings.fileCheck()
|
||||
});
|
||||
const result = await filesystem.checkAttachment(attachment.hash);
|
||||
if (!result) return;
|
||||
@@ -125,7 +126,7 @@ const Actions = ({
|
||||
db.attachments.markAsFailed(attachment.id, result.failed);
|
||||
setFailed(result.failed);
|
||||
ToastManager.show({
|
||||
heading: "File check failed with error: " + result.failed,
|
||||
heading: strings.fileCheckFailed(result.failed),
|
||||
type: "error",
|
||||
context: "local"
|
||||
});
|
||||
@@ -134,7 +135,7 @@ const Actions = ({
|
||||
db.attachments.markAsFailed(attachment.id);
|
||||
eSendEvent(eDBItemUpdate, attachment.id);
|
||||
ToastManager.show({
|
||||
heading: "File check passed",
|
||||
heading: strings.fileCheckPassed(),
|
||||
type: "success",
|
||||
context: "local"
|
||||
});
|
||||
@@ -148,12 +149,11 @@ const Actions = ({
|
||||
icon: "file-check"
|
||||
},
|
||||
{
|
||||
name: "Rename",
|
||||
onPress: async () => {
|
||||
name: strings.rename(),
|
||||
onPress: () => {
|
||||
presentDialog({
|
||||
input: true,
|
||||
title: "Rename file",
|
||||
paragraph: "Enter a new name for the file",
|
||||
title: strings.renameFile(),
|
||||
defaultValue: attachment.filename,
|
||||
positivePress: async (value) => {
|
||||
if (value && value.length > 0) {
|
||||
@@ -172,7 +172,7 @@ const Actions = ({
|
||||
icon: "form-textbox"
|
||||
},
|
||||
{
|
||||
name: "Delete",
|
||||
name: strings.delete(),
|
||||
onPress: async () => {
|
||||
const relations = await db.relations.to(attachment, "note").get();
|
||||
await db.attachments.remove(attachment.hash, false);
|
||||
@@ -256,8 +256,7 @@ const Actions = ({
|
||||
|
||||
{notes.length ? (
|
||||
<Paragraph size={SIZE.xs} color={colors.secondary.paragraph}>
|
||||
{notes.length} note
|
||||
{notes.length > 1 ? "s" : ""}
|
||||
{strings.notes(notes.length)}
|
||||
</Paragraph>
|
||||
) : null}
|
||||
<Paragraph
|
||||
@@ -265,7 +264,7 @@ const Actions = ({
|
||||
Clipboard.setString(attachment.hash);
|
||||
ToastManager.show({
|
||||
type: "success",
|
||||
heading: "Attachment hash copied",
|
||||
heading: strings.hashCopied(),
|
||||
context: "local"
|
||||
});
|
||||
}}
|
||||
@@ -295,7 +294,7 @@ const Actions = ({
|
||||
}}
|
||||
size={SIZE.sm}
|
||||
>
|
||||
List of notes:
|
||||
{strings.listOf()} {strings.dataTypesPlural.note()}:
|
||||
</Heading>
|
||||
|
||||
{notes.map((item) => (
|
||||
@@ -354,7 +353,7 @@ const Actions = ({
|
||||
{failed ? (
|
||||
<Notice
|
||||
type="alert"
|
||||
text={`File check failed: ${failed} Try reuploading the file to fix the issue.`}
|
||||
text={strings.fileCheckFailed(failed)}
|
||||
size="small"
|
||||
/>
|
||||
) : null}
|
||||
|
||||
@@ -30,6 +30,7 @@ import { IconButton } from "../ui/icon-button";
|
||||
import { ProgressCircleComponent } from "../ui/svg/lazy";
|
||||
import Paragraph from "../ui/typography/paragraph";
|
||||
import Actions from "./actions";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
function getFileExtension(filename: string) {
|
||||
const ext = /^.+\.([^.]+)$/.exec(filename);
|
||||
@@ -136,7 +137,7 @@ export const AttachmentItem = ({
|
||||
|
||||
{!hideWhenNotDownloading ? (
|
||||
<Paragraph color={colors.secondary.paragraph} size={SIZE.xxs}>
|
||||
File size: {formatBytes(attachment.size)}
|
||||
{strings.fileSize()}: {formatBytes(attachment.size)}
|
||||
</Paragraph>
|
||||
) : null}
|
||||
</View>
|
||||
|
||||
@@ -24,6 +24,7 @@ import {
|
||||
SortOptions,
|
||||
VirtualizedGrouping
|
||||
} from "@notesnook/core";
|
||||
import { strings } from "@notesnook/intl";
|
||||
import { useThemeColors } from "@notesnook/theme";
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import { ActivityIndicator, View } from "react-native";
|
||||
@@ -94,31 +95,31 @@ const useRechecker = create<RecheckerState>((set) => ({
|
||||
|
||||
const attachmentTypes = [
|
||||
{
|
||||
title: "All",
|
||||
title: strings.mediaTypes.all(),
|
||||
filterBy: "all"
|
||||
},
|
||||
{
|
||||
title: "Images",
|
||||
title: strings.mediaTypes.image(),
|
||||
filterBy: "images"
|
||||
},
|
||||
{
|
||||
title: "Docs",
|
||||
filterBy: "documents"
|
||||
},
|
||||
{
|
||||
title: "Video",
|
||||
filterBy: "video"
|
||||
},
|
||||
{
|
||||
title: "Audio",
|
||||
title: strings.mediaTypes.audio(),
|
||||
filterBy: "audio"
|
||||
},
|
||||
{
|
||||
title: "Orphaned",
|
||||
title: strings.mediaTypes.video(),
|
||||
filterBy: "video"
|
||||
},
|
||||
{
|
||||
title: strings.mediaTypes.document(),
|
||||
filterBy: "documents"
|
||||
},
|
||||
{
|
||||
title: strings.mediaTypes.orphaned(),
|
||||
filterBy: "orphaned"
|
||||
},
|
||||
{
|
||||
title: "Errors",
|
||||
title: strings.mediaTypes.errors(),
|
||||
filterBy: "errors"
|
||||
}
|
||||
];
|
||||
@@ -358,7 +359,7 @@ export const AttachmentDialog = ({
|
||||
paddingHorizontal: 12
|
||||
}}
|
||||
>
|
||||
<Heading>Attachments</Heading>
|
||||
<Heading>{strings.dataTypesPluralCamelCase.attachment()}</Heading>
|
||||
|
||||
<View
|
||||
style={{
|
||||
|
||||
@@ -36,6 +36,7 @@ import { IconButton } from "../ui/icon-button";
|
||||
import { hideAuth, initialAuthMode } from "./common";
|
||||
import { Login } from "./login";
|
||||
import { Signup } from "./signup";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
export const AuthMode = {
|
||||
login: 0,
|
||||
@@ -153,7 +154,7 @@ const AuthModal = () => {
|
||||
|
||||
{initialAuthMode.current !== AuthMode.welcomeSignup ? null : (
|
||||
<Button
|
||||
title="Skip"
|
||||
title={strings.skip()}
|
||||
onPress={() => {
|
||||
hideAuth();
|
||||
}}
|
||||
|
||||
@@ -35,6 +35,7 @@ import Seperator from "../ui/seperator";
|
||||
import { Dialog } from "../dialog";
|
||||
import BackupService from "../../services/backup";
|
||||
import { sleep } from "../../utils/time";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
export const ChangePassword = () => {
|
||||
const passwordInputRef = useRef();
|
||||
@@ -49,8 +50,8 @@ export const ChangePassword = () => {
|
||||
const changePassword = async () => {
|
||||
if (!user?.isEmailConfirmed) {
|
||||
ToastManager.show({
|
||||
heading: "Email not confirmed",
|
||||
message: "Please confirm your email to change account password",
|
||||
heading: strings.emailNotConfirmed(),
|
||||
message: strings.emailNotConfirmedDesc(),
|
||||
type: "error",
|
||||
context: "local"
|
||||
});
|
||||
@@ -58,8 +59,8 @@ export const ChangePassword = () => {
|
||||
}
|
||||
if (error || !oldPassword.current || !password.current) {
|
||||
ToastManager.show({
|
||||
heading: "All fields required",
|
||||
message: "Fill all the fields and try again.",
|
||||
heading: strings.allFieldsRequired(),
|
||||
message: strings.allFieldsRequiredDesc(),
|
||||
type: "error",
|
||||
context: "local"
|
||||
});
|
||||
@@ -68,13 +69,13 @@ export const ChangePassword = () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const result = await BackupService.run(false, "change-password-dialog");
|
||||
if (result.error)
|
||||
throw new Error(`Failed to create backup: ${result.error}`);
|
||||
if (!result.error)
|
||||
throw new Error(strings.backupFailed() + `: ${result.error}`);
|
||||
|
||||
await db.user.clearSessions();
|
||||
await db.user.changePassword(oldPassword.current, password.current);
|
||||
ToastManager.show({
|
||||
heading: "Account password updated",
|
||||
heading: strings.passwordChangedSuccessfully(),
|
||||
type: "success",
|
||||
context: "global"
|
||||
});
|
||||
@@ -85,7 +86,7 @@ export const ChangePassword = () => {
|
||||
} catch (e) {
|
||||
setLoading(false);
|
||||
ToastManager.show({
|
||||
heading: "Failed to change password",
|
||||
heading: strings.passwordChangeFailed(),
|
||||
message: e.message,
|
||||
type: "error",
|
||||
context: "local"
|
||||
@@ -102,10 +103,7 @@ export const ChangePassword = () => {
|
||||
}}
|
||||
>
|
||||
<Dialog context="change-password-dialog" />
|
||||
<DialogHeader
|
||||
title="Change password"
|
||||
paragraph="Enter your old and new passwords"
|
||||
/>
|
||||
<DialogHeader title={strings.changePassword()} />
|
||||
<Seperator />
|
||||
|
||||
<Input
|
||||
@@ -138,17 +136,11 @@ export const ChangePassword = () => {
|
||||
placeholder="New password"
|
||||
/>
|
||||
|
||||
<Notice
|
||||
text={`Changing password is an irreversible process. You will be logged out from all your devices. Please make sure you do not close the app while your password is changing and have good internet connection.`}
|
||||
type="alert"
|
||||
/>
|
||||
<Notice text={strings.changePasswordNotice()} type="alert" />
|
||||
|
||||
<View style={{ height: 10 }} />
|
||||
|
||||
<Notice
|
||||
text={`Once your password is changed, please make sure to save the new account recovery key.`}
|
||||
type="alert"
|
||||
/>
|
||||
<Notice text={strings.changePasswordNotice2()} type="alert" />
|
||||
|
||||
<Button
|
||||
style={{
|
||||
@@ -158,7 +150,7 @@ export const ChangePassword = () => {
|
||||
loading={loading}
|
||||
onPress={changePassword}
|
||||
type="accent"
|
||||
title={loading ? null : "I understand, change my password"}
|
||||
title={loading ? null : strings.changePasswordConfirm()}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
|
||||
@@ -32,6 +32,7 @@ import Input from "../ui/input";
|
||||
import Seperator from "../ui/seperator";
|
||||
import Heading from "../ui/typography/heading";
|
||||
import Paragraph from "../ui/typography/paragraph";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
export const ForgotPassword = () => {
|
||||
const { colors } = useThemeColors("sheet");
|
||||
@@ -44,7 +45,7 @@ export const ForgotPassword = () => {
|
||||
const sendRecoveryEmail = async () => {
|
||||
if (!email.current || error) {
|
||||
ToastManager.show({
|
||||
heading: "Account email is required.",
|
||||
heading: strings.emailRequired(),
|
||||
type: "error",
|
||||
context: "local"
|
||||
});
|
||||
@@ -64,8 +65,8 @@ export const ForgotPassword = () => {
|
||||
lastRecoveryEmailTime: Date.now()
|
||||
});
|
||||
ToastManager.show({
|
||||
heading: "Check your email to reset password",
|
||||
message: `Recovery email has been sent to ${email.current.toLowerCase()}`,
|
||||
heading: strings.recoveryEmailSent(),
|
||||
message: strings.recoveryEmailSentDesc(),
|
||||
type: "success",
|
||||
context: "local",
|
||||
duration: 7000
|
||||
@@ -75,7 +76,7 @@ export const ForgotPassword = () => {
|
||||
} catch (e) {
|
||||
setLoading(false);
|
||||
ToastManager.show({
|
||||
heading: "Recovery email not sent",
|
||||
heading: strings.recoveryEmailFailed(),
|
||||
message: e.message,
|
||||
type: "error",
|
||||
context: "local"
|
||||
@@ -121,13 +122,13 @@ export const ForgotPassword = () => {
|
||||
name="email"
|
||||
size={50}
|
||||
/>
|
||||
<Heading>Recovery email sent!</Heading>
|
||||
<Heading>{strings.recoveryEmailSent()}</Heading>
|
||||
<Paragraph
|
||||
style={{
|
||||
textAlign: "center"
|
||||
}}
|
||||
>
|
||||
Please follow the link in the email to recover your account.
|
||||
{strings.recoveryEmailSentDesc()}
|
||||
</Paragraph>
|
||||
</View>
|
||||
) : (
|
||||
@@ -140,10 +141,7 @@ export const ForgotPassword = () => {
|
||||
padding: 12
|
||||
}}
|
||||
>
|
||||
<DialogHeader
|
||||
title="Account recovery"
|
||||
paragraph="We will send you an email with steps on how to reset your password."
|
||||
/>
|
||||
<DialogHeader title={strings.accountRecovery()} />
|
||||
<Seperator />
|
||||
|
||||
<Input
|
||||
@@ -172,7 +170,7 @@ export const ForgotPassword = () => {
|
||||
loading={loading}
|
||||
onPress={sendRecoveryEmail}
|
||||
type="accent"
|
||||
title={loading ? null : "Next"}
|
||||
title={loading ? null : strings.next()}
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
|
||||
@@ -38,6 +38,7 @@ import Paragraph from "../ui/typography/paragraph";
|
||||
import { hideAuth } from "./common";
|
||||
import { ForgotPassword } from "./forgot-password";
|
||||
import { useLogin } from "./use-login";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
const LoginSteps = {
|
||||
emailAuth: 1,
|
||||
@@ -147,7 +148,7 @@ export const Login = ({ changeMode }) => {
|
||||
extraBold
|
||||
size={SIZE.xxl}
|
||||
>
|
||||
Login to your {"\n"}account
|
||||
{strings.loginToYourAccount()}
|
||||
</Heading>
|
||||
</View>
|
||||
|
||||
@@ -212,7 +213,7 @@ export const Login = ({ changeMode }) => {
|
||||
onSubmit={() => login()}
|
||||
/>
|
||||
<Button
|
||||
title="Forgot your password?"
|
||||
title={strings.forgotPassword()}
|
||||
style={{
|
||||
alignSelf: "flex-end",
|
||||
height: 30,
|
||||
@@ -249,12 +250,12 @@ export const Login = ({ changeMode }) => {
|
||||
height={50}
|
||||
fontSize={SIZE.md}
|
||||
type="accent"
|
||||
title={!loading ? "Continue" : null}
|
||||
title={!loading ? strings.continue() : null}
|
||||
/>
|
||||
|
||||
{step === LoginSteps.passwordAuth && (
|
||||
<Button
|
||||
title="Cancel logging in"
|
||||
title={strings.cancelLogin()}
|
||||
style={{
|
||||
alignSelf: "center",
|
||||
height: 30,
|
||||
@@ -290,12 +291,12 @@ export const Login = ({ changeMode }) => {
|
||||
size={SIZE.xs + 1}
|
||||
color={colors.secondary.paragraph}
|
||||
>
|
||||
Don't have an account?{" "}
|
||||
{strings.dontHaveAccount()}{" "}
|
||||
<Paragraph
|
||||
size={SIZE.xs + 1}
|
||||
style={{ color: colors.primary.accent }}
|
||||
>
|
||||
Sign up
|
||||
{strings.signUp()}
|
||||
</Paragraph>
|
||||
</Paragraph>
|
||||
</TouchableOpacity>
|
||||
|
||||
@@ -47,6 +47,7 @@ import Input from "../ui/input";
|
||||
import Heading from "../ui/typography/heading";
|
||||
import Paragraph from "../ui/typography/paragraph";
|
||||
import { LoginSteps, useLogin } from "./use-login";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
function getObfuscatedEmail(email) {
|
||||
if (!email) return "";
|
||||
@@ -193,15 +194,14 @@ export const SessionExpired = () => {
|
||||
size={50}
|
||||
/>
|
||||
<Heading size={SIZE.xxxl} color={colors.primary.heading}>
|
||||
Session expired
|
||||
{strings.sessionExpired()}
|
||||
</Heading>
|
||||
<Paragraph
|
||||
style={{
|
||||
textAlign: "center"
|
||||
}}
|
||||
>
|
||||
Your session on this device has expired. Please enter password for{" "}
|
||||
{getObfuscatedEmail(email.current)} to continue.
|
||||
{strings.sessionExpiredDesc(getObfuscatedEmail(email.current))}
|
||||
</Paragraph>
|
||||
</View>
|
||||
|
||||
@@ -231,7 +231,7 @@ export const SessionExpired = () => {
|
||||
loading={loading}
|
||||
onPress={() => login()}
|
||||
type="accent"
|
||||
title={loading ? null : "Login"}
|
||||
title={loading ? null : strings.login()}
|
||||
/>
|
||||
|
||||
<Button
|
||||
@@ -242,16 +242,15 @@ export const SessionExpired = () => {
|
||||
onPress={() => {
|
||||
presentDialog({
|
||||
context: "session_expiry",
|
||||
title: "Logout",
|
||||
paragraph:
|
||||
"Are you sure you want to logout from this device? Any unsynced changes will be lost.",
|
||||
positiveText: "Logout",
|
||||
title: strings.logoutFromDevice(),
|
||||
paragraph: strings.logoutDesc(),
|
||||
positiveText: strings.logout(),
|
||||
positiveType: "errorShade",
|
||||
positivePress: logout
|
||||
});
|
||||
}}
|
||||
type="errorShade"
|
||||
title={loading ? null : "Logout from this device"}
|
||||
title={loading ? null : strings.logoutFromDevice()}
|
||||
/>
|
||||
</View>
|
||||
<Toast context="local" />
|
||||
|
||||
@@ -36,6 +36,7 @@ import Paragraph from "../ui/typography/paragraph";
|
||||
import { hideAuth } from "./common";
|
||||
import { useSettingStore } from "../../stores/use-setting-store";
|
||||
import SettingsService from "../../services/settings";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
export const Signup = ({ changeMode, trial }) => {
|
||||
const { colors } = useThemeColors();
|
||||
@@ -54,8 +55,8 @@ export const Signup = ({ changeMode, trial }) => {
|
||||
const validateInfo = () => {
|
||||
if (!password.current || !email.current || !confirmPassword.current) {
|
||||
ToastManager.show({
|
||||
heading: "All fields required",
|
||||
message: "Fill all the fields and try again",
|
||||
heading: strings.allFieldsRequired(),
|
||||
message: strings.allFieldsRequiredDesc(),
|
||||
type: "error",
|
||||
context: "local"
|
||||
});
|
||||
@@ -88,7 +89,7 @@ export const Signup = ({ changeMode, trial }) => {
|
||||
} catch (e) {
|
||||
setLoading(false);
|
||||
ToastManager.show({
|
||||
heading: "Signup failed",
|
||||
heading: strings.signupFailed(),
|
||||
message: e.message,
|
||||
type: "error",
|
||||
context: "local"
|
||||
@@ -156,7 +157,7 @@ export const Signup = ({ changeMode, trial }) => {
|
||||
}}
|
||||
size={SIZE.xxl}
|
||||
>
|
||||
Create your {"\n"}account
|
||||
{strings.createYourAccount()}
|
||||
</Heading>
|
||||
</View>
|
||||
|
||||
@@ -235,7 +236,7 @@ export const Signup = ({ changeMode, trial }) => {
|
||||
size={SIZE.xs}
|
||||
color={colors.secondary.paragraph}
|
||||
>
|
||||
By signing up, you agree to our{" "}
|
||||
{strings.signupAgreement[0]()}
|
||||
<Paragraph
|
||||
size={SIZE.xs}
|
||||
onPress={() => {
|
||||
@@ -246,9 +247,9 @@ export const Signup = ({ changeMode, trial }) => {
|
||||
}}
|
||||
color={colors.primary.accent}
|
||||
>
|
||||
Terms of Service{" "}
|
||||
{strings.signupAgreement[1]()}
|
||||
</Paragraph>
|
||||
and{" "}
|
||||
{strings.signupAgreement[2]()}
|
||||
<Paragraph
|
||||
size={SIZE.xs}
|
||||
onPress={() => {
|
||||
@@ -259,14 +260,13 @@ export const Signup = ({ changeMode, trial }) => {
|
||||
}}
|
||||
color={colors.primary.accent}
|
||||
>
|
||||
Privacy Policy.
|
||||
</Paragraph>{" "}
|
||||
You also agree to recieve marketing emails from us which you can
|
||||
opt-out of from app settings.
|
||||
{strings.signupAgreement[3]()}
|
||||
</Paragraph>
|
||||
{strings.signupAgreement[4]()}
|
||||
</Paragraph>
|
||||
|
||||
<Button
|
||||
title={!loading ? "Continue" : null}
|
||||
title={!loading ? strings.continue() : null}
|
||||
type="accent"
|
||||
loading={loading}
|
||||
onPress={signup}
|
||||
@@ -291,12 +291,12 @@ export const Signup = ({ changeMode, trial }) => {
|
||||
}}
|
||||
>
|
||||
<Paragraph size={SIZE.xs + 1} color={colors.secondary.paragraph}>
|
||||
Already have an account?{" "}
|
||||
{strings.alreadyHaveAccount()}{" "}
|
||||
<Paragraph
|
||||
size={SIZE.xs + 1}
|
||||
style={{ color: colors.primary.accent }}
|
||||
>
|
||||
Login
|
||||
{strings.login()}
|
||||
</Paragraph>
|
||||
</Paragraph>
|
||||
</TouchableOpacity>
|
||||
|
||||
@@ -38,6 +38,7 @@ import Heading from "../ui/typography/heading";
|
||||
import Paragraph from "../ui/typography/paragraph";
|
||||
import { useCallback } from "react";
|
||||
import { ScrollView } from "react-native-actions-sheet";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
const TwoFactorVerification = ({ onMfaLogin, mfaInfo }) => {
|
||||
const { colors } = useThemeColors();
|
||||
@@ -51,20 +52,6 @@ const TwoFactorVerification = ({ onMfaLogin, mfaInfo }) => {
|
||||
const inputRef = useRef();
|
||||
const [sending, setSending] = useState(false);
|
||||
|
||||
const codeHelpText = {
|
||||
app: "Enter the 6 digit code from your authenticator app to continue logging in",
|
||||
sms: "Enter the 6 digit code sent to your phone number to continue logging in",
|
||||
email: "Enter the 6 digit code sent to your email to continue logging in",
|
||||
recoveryCode: "Enter the recovery code to continue logging in"
|
||||
};
|
||||
|
||||
const secondaryMethodsText = {
|
||||
app: "I don't have access to authenticator app",
|
||||
sms: "I don't have access to my phone",
|
||||
email: "I don't have access to email",
|
||||
recoveryCode: "I don't have recovery codes"
|
||||
};
|
||||
|
||||
const onNext = async () => {
|
||||
if (!code.current || code.current.length < 6) return;
|
||||
setLoading(true);
|
||||
@@ -94,22 +81,22 @@ const TwoFactorVerification = ({ onMfaLogin, mfaInfo }) => {
|
||||
const methods = [
|
||||
{
|
||||
id: "sms",
|
||||
title: "Send code via SMS",
|
||||
title: strings.sendCodeSms(),
|
||||
icon: "message-plus-outline"
|
||||
},
|
||||
{
|
||||
id: "email",
|
||||
title: "Send code via email",
|
||||
title: strings.sendCodeEmail(),
|
||||
icon: "email-outline"
|
||||
},
|
||||
{
|
||||
id: "app",
|
||||
title: "Enter code from authenticator app",
|
||||
title: strings.authAppCode(),
|
||||
icon: "cellphone-key"
|
||||
},
|
||||
{
|
||||
id: "recoveryCode",
|
||||
title: "I have a recovery code",
|
||||
title: strings.recoveryCode(),
|
||||
icon: "key"
|
||||
}
|
||||
];
|
||||
@@ -168,9 +155,7 @@ const TwoFactorVerification = ({ onMfaLogin, mfaInfo }) => {
|
||||
textAlign: "center"
|
||||
}}
|
||||
>
|
||||
{currentMethod.method
|
||||
? "Two factor authentication"
|
||||
: "Select methods for two-factor authentication"}
|
||||
{currentMethod.method ? strings["2fa"]() : strings.select2faMethod()}
|
||||
</Heading>
|
||||
<Paragraph
|
||||
style={{
|
||||
@@ -178,8 +163,8 @@ const TwoFactorVerification = ({ onMfaLogin, mfaInfo }) => {
|
||||
textAlign: "center"
|
||||
}}
|
||||
>
|
||||
{codeHelpText[currentMethod.method] ||
|
||||
"Select how you would like to recieve the code"}
|
||||
{strings["2faCodeHelpText"][currentMethod.method]() ||
|
||||
strings.select2faCodeHelpText()}
|
||||
</Paragraph>
|
||||
|
||||
<Seperator />
|
||||
@@ -191,7 +176,11 @@ const TwoFactorVerification = ({ onMfaLogin, mfaInfo }) => {
|
||||
title={
|
||||
sending
|
||||
? ""
|
||||
: `${seconds ? `Resend code in (${seconds})` : "Send code"}`
|
||||
: `${
|
||||
seconds
|
||||
? strings.resend2faCode(seconds)
|
||||
: strings.sendCode()
|
||||
}`
|
||||
}
|
||||
loading={sending}
|
||||
height={30}
|
||||
@@ -240,7 +229,7 @@ const TwoFactorVerification = ({ onMfaLogin, mfaInfo }) => {
|
||||
/>
|
||||
<Seperator />
|
||||
<Button
|
||||
title={loading ? null : "Next"}
|
||||
title={loading ? null : strings.next()}
|
||||
type="accent"
|
||||
width={250}
|
||||
loading={loading}
|
||||
@@ -252,7 +241,9 @@ const TwoFactorVerification = ({ onMfaLogin, mfaInfo }) => {
|
||||
/>
|
||||
|
||||
<Button
|
||||
title={secondaryMethodsText[currentMethod.method]}
|
||||
title={
|
||||
strings["2faCodeSecondaryMethodText"][currentMethod.method]
|
||||
}
|
||||
type="plain"
|
||||
onPress={onRequestSecondaryMethod}
|
||||
height={30}
|
||||
|
||||
@@ -26,6 +26,7 @@ import SettingsService from "../../services/settings";
|
||||
import { useUserStore } from "../../stores/use-user-store";
|
||||
import { eCloseSheet } from "../../utils/events";
|
||||
import TwoFactorVerification from "./two-factor";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
export const LoginSteps = {
|
||||
emailAuth: 1,
|
||||
@@ -49,8 +50,8 @@ export const useLogin = (onFinishLogin, sessionExpired = false) => {
|
||||
(!email.current && step === LoginSteps.emailAuth)
|
||||
) {
|
||||
ToastManager.show({
|
||||
heading: "All fields required",
|
||||
message: "Fill all the fields and try again",
|
||||
heading: strings.allFieldsRequired(),
|
||||
message: strings.allFieldsRequiredDesc(),
|
||||
type: "error",
|
||||
context: "local"
|
||||
});
|
||||
@@ -122,7 +123,7 @@ export const useLogin = (onFinishLogin, sessionExpired = false) => {
|
||||
if (e.message === "invalid_grant") setStep(LoginSteps.emailAuth);
|
||||
setLoading(false);
|
||||
ToastManager.show({
|
||||
heading: "Login failed",
|
||||
heading: strings.loginFailed(),
|
||||
message: e.message,
|
||||
type: "error",
|
||||
context: "local"
|
||||
@@ -136,8 +137,8 @@ export const useLogin = (onFinishLogin, sessionExpired = false) => {
|
||||
setUser(user);
|
||||
clearMessage();
|
||||
ToastManager.show({
|
||||
heading: "Login successful",
|
||||
message: `Logged in as ${user.email}`,
|
||||
heading: strings.loginSuccess(),
|
||||
message: strings.loginSuccessDesc(),
|
||||
type: "success",
|
||||
context: "global"
|
||||
});
|
||||
|
||||
@@ -26,12 +26,13 @@ import { SIZE } from "../../utils/size";
|
||||
import { Button } from "../ui/button";
|
||||
import Paragraph from "../ui/typography/paragraph";
|
||||
import { getColorLinearShade } from "../../utils/colors";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
const DialogButtons = ({
|
||||
onPressPositive,
|
||||
onPressNegative,
|
||||
positiveTitle,
|
||||
negativeTitle = "Cancel",
|
||||
negativeTitle = strings.cancel(),
|
||||
loading,
|
||||
doneText,
|
||||
positiveType
|
||||
|
||||
@@ -38,6 +38,7 @@ import { useCallback } from "react";
|
||||
import { Button } from "../ui/button";
|
||||
import { getContainerBorder } from "../../utils/colors";
|
||||
import { Notice } from "../ui/notice";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
export const Dialog = ({ context = "global" }) => {
|
||||
const { colors } = useThemeColors();
|
||||
@@ -50,8 +51,8 @@ export const Dialog = ({ context = "global" }) => {
|
||||
const [dialogInfo, setDialogInfo] = useState({
|
||||
title: "",
|
||||
paragraph: "",
|
||||
positiveText: "Done",
|
||||
negativeText: "Cancel",
|
||||
positiveText: strings.done(),
|
||||
negativeText: strings.cancel(),
|
||||
positivePress: () => {},
|
||||
onClose: () => {},
|
||||
positiveType: "transparent",
|
||||
|
||||
@@ -49,6 +49,7 @@ import { Button } from "../../ui/button";
|
||||
import { IconButton } from "../../ui/icon-button";
|
||||
import Input from "../../ui/input";
|
||||
import Seperator from "../../ui/seperator";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
export const AppLockPassword = () => {
|
||||
const { colors } = useThemeColors();
|
||||
@@ -119,22 +120,7 @@ export const AppLockPassword = () => {
|
||||
}}
|
||||
>
|
||||
<DialogHeader
|
||||
title={
|
||||
mode === "change"
|
||||
? `Change app lock ${keyboardType}`
|
||||
: mode === "remove"
|
||||
? `Remove app lock ${keyboardType}`
|
||||
: `Set up app lock ${keyboardType}`
|
||||
}
|
||||
paragraph={
|
||||
mode === "change"
|
||||
? `Change app lock ${keyboardType}`
|
||||
: mode === "remove"
|
||||
? `Enter ${
|
||||
accountPass ? "account password" : `app lock ${keyboardType}`
|
||||
} to remove ${keyboardType}`
|
||||
: `Set up a custom app lock ${keyboardType} to unlock the app`
|
||||
}
|
||||
title={strings.changeAppLockCredentials(mode, keyboardType)}
|
||||
icon="shield"
|
||||
padding={12}
|
||||
/>
|
||||
@@ -253,7 +239,7 @@ export const AppLockPassword = () => {
|
||||
iconColor={
|
||||
accountPass ? colors.primary.accent : colors.primary.icon
|
||||
}
|
||||
title="Use account password instead"
|
||||
title={strings.useAccountPassword()}
|
||||
style={{
|
||||
width: "100%",
|
||||
alignSelf: "flex-start",
|
||||
@@ -272,7 +258,7 @@ export const AppLockPassword = () => {
|
||||
if (mode === "create") {
|
||||
if (!values.current.password || !values.current.confirmPassword) {
|
||||
ToastManager.error(
|
||||
new Error("All inputs are required"),
|
||||
new Error(strings.allFieldsRequired()),
|
||||
undefined,
|
||||
"local"
|
||||
);
|
||||
@@ -281,11 +267,7 @@ export const AppLockPassword = () => {
|
||||
|
||||
if (values.current.password !== values.current.confirmPassword) {
|
||||
ToastManager.error(
|
||||
new Error(
|
||||
`${
|
||||
keyboardType === "pin" ? "Pin" : "Password"
|
||||
} does not match`
|
||||
),
|
||||
new Error(strings.mismatch(keyboardType)),
|
||||
undefined,
|
||||
"local"
|
||||
);
|
||||
@@ -301,7 +283,7 @@ export const AppLockPassword = () => {
|
||||
!values.current.confirmPassword
|
||||
) {
|
||||
ToastManager.error(
|
||||
new Error("All inputs are required"),
|
||||
new Error(strings.allFieldsRequired()),
|
||||
undefined,
|
||||
"local"
|
||||
);
|
||||
@@ -310,11 +292,7 @@ export const AppLockPassword = () => {
|
||||
|
||||
if (values.current.password !== values.current.confirmPassword) {
|
||||
ToastManager.error(
|
||||
new Error(
|
||||
`${
|
||||
keyboardType === "pin" ? "Pin" : "Password"
|
||||
} does not match`
|
||||
),
|
||||
new Error(strings.mismatch(keyboardType)),
|
||||
undefined,
|
||||
"local"
|
||||
);
|
||||
@@ -326,9 +304,7 @@ export const AppLockPassword = () => {
|
||||
|
||||
if (!isCurrentPasswordCorrect) {
|
||||
ToastManager.error(
|
||||
new Error(
|
||||
`${keyboardType === "pin" ? "Pin" : "Password"} incorrect`
|
||||
),
|
||||
new Error(strings.incorrect(keyboardType)),
|
||||
undefined,
|
||||
"local"
|
||||
);
|
||||
@@ -342,7 +318,7 @@ export const AppLockPassword = () => {
|
||||
} else if (mode === "remove") {
|
||||
if (!values.current.password) {
|
||||
ToastManager.error(
|
||||
new Error("All inputs are required"),
|
||||
new Error(strings.allFieldsRequired()),
|
||||
undefined,
|
||||
"local"
|
||||
);
|
||||
@@ -357,10 +333,8 @@ export const AppLockPassword = () => {
|
||||
ToastManager.error(
|
||||
new Error(
|
||||
accountPass
|
||||
? "Account password incorrect"
|
||||
: `${
|
||||
keyboardType === "pin" ? "Pin" : "Password"
|
||||
} incorrect`
|
||||
? strings.passwordIncorrect()
|
||||
: strings.incorrect(keyboardType)
|
||||
),
|
||||
undefined,
|
||||
"local"
|
||||
@@ -377,7 +351,7 @@ export const AppLockPassword = () => {
|
||||
SettingsService.setProperty("appLockEnabled", false);
|
||||
SettingsService.setPrivacyScreen(SettingsService.get());
|
||||
ToastManager.show({
|
||||
message: "App lock disabled",
|
||||
message: strings.applockDisabled(),
|
||||
type: "success"
|
||||
});
|
||||
}
|
||||
@@ -391,9 +365,13 @@ export const AppLockPassword = () => {
|
||||
close();
|
||||
}}
|
||||
positiveTitle={
|
||||
mode === "remove" ? "Remove" : mode === "change" ? "Change" : "Save"
|
||||
mode === "remove"
|
||||
? strings.remove()
|
||||
: mode === "change"
|
||||
? strings.change()
|
||||
: strings.save()
|
||||
}
|
||||
negativeTitle="Cancel"
|
||||
negativeTitle={strings.cancel()}
|
||||
positiveType="transparent"
|
||||
loading={false}
|
||||
doneText=""
|
||||
|
||||
@@ -32,6 +32,7 @@ import { Button } from "../../ui/button";
|
||||
import { IconButton } from "../../ui/icon-button";
|
||||
import { Notice } from "../../ui/notice";
|
||||
import Paragraph from "../../ui/typography/paragraph";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
export default function AttachImage({
|
||||
response,
|
||||
@@ -64,7 +65,7 @@ export default function AttachImage({
|
||||
}}
|
||||
>
|
||||
<Paragraph style={{ color: colors.primary.paragraph, marginBottom: 6 }}>
|
||||
Attaching {response?.length} image(s):
|
||||
{strings.attachImageHeading(response?.length || 1)}
|
||||
</Paragraph>
|
||||
<ScrollView horizontal>
|
||||
{response?.map?.((item) => (
|
||||
@@ -123,14 +124,14 @@ export default function AttachImage({
|
||||
}}
|
||||
size={SIZE.sm}
|
||||
>
|
||||
Compress (recommended)
|
||||
{strings.compress()} ({strings.recommended().toLowerCase()})
|
||||
</Paragraph>
|
||||
</TouchableOpacity>
|
||||
|
||||
{!compress ? (
|
||||
<Notice
|
||||
type="alert"
|
||||
text="Images uploaded without compression are slow to load and take more bandwidth. We recommend compressing images unless you need image in original quality."
|
||||
text={strings.compressionOffNotice()}
|
||||
size="small"
|
||||
style={{
|
||||
width: "100%",
|
||||
@@ -140,7 +141,7 @@ export default function AttachImage({
|
||||
) : (
|
||||
<Notice
|
||||
type="information"
|
||||
text="Compressed images are uploaded in Full HD resolution and usually are good enough for most use cases."
|
||||
text={strings.compressionOnNotice()}
|
||||
size="small"
|
||||
style={{
|
||||
width: "100%",
|
||||
@@ -150,9 +151,7 @@ export default function AttachImage({
|
||||
)}
|
||||
|
||||
<Button
|
||||
title={`${
|
||||
(response?.length || 0) > 1 ? "Attach Images" : "Attach Image"
|
||||
}`}
|
||||
title={strings.attachImageHeading(response?.length || 1)}
|
||||
type="accent"
|
||||
width="100%"
|
||||
onPress={() => {
|
||||
|
||||
@@ -33,6 +33,7 @@ import { Toast } from "../../toast";
|
||||
import { Button } from "../../ui/button";
|
||||
import Input from "../../ui/input";
|
||||
import { Pressable } from "../../ui/pressable";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
const HEX_COLOR_REGEX_ALPHA =
|
||||
/^#(?:(?:[\da-fA-F]{3}){1,2}|(?:[\da-fA-F]{4}){1,2})$/;
|
||||
@@ -152,27 +153,27 @@ const ColorPicker = ({
|
||||
/>
|
||||
|
||||
<Button
|
||||
title="Add color"
|
||||
title={strings.addColor()}
|
||||
style={{
|
||||
marginBottom: 10
|
||||
}}
|
||||
onPress={async () => {
|
||||
if (!selectedColor)
|
||||
return ToastManager.error(
|
||||
new Error("Select a color"),
|
||||
new Error(strings.noColorSelected()),
|
||||
undefined,
|
||||
"color-picker"
|
||||
);
|
||||
if (!title.current)
|
||||
return ToastManager.error(
|
||||
new Error("Enter a title for the color")
|
||||
new Error(strings.allFieldsRequired())
|
||||
);
|
||||
const exists = await db.colors.all.find((v) =>
|
||||
v.and([v(`colorCode`, "==", selectedColor)])
|
||||
);
|
||||
if (exists)
|
||||
return ToastManager.error(
|
||||
new Error(`Color #${selectedColor} already exists`)
|
||||
new Error(strings.colorExists(selectedColor))
|
||||
);
|
||||
const id = await db.colors.add({
|
||||
title: title.current,
|
||||
|
||||
@@ -45,6 +45,7 @@ import Paragraph from "../../ui/typography/paragraph";
|
||||
import { sleep } from "../../../utils/time";
|
||||
import { MMKV } from "../../../common/database/mmkv";
|
||||
import { deleteCacheFileByPath } from "../../../common/filesystem/io";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
const WIN_WIDTH = Dimensions.get("window").width;
|
||||
const WIN_HEIGHT = Dimensions.get("window").height;
|
||||
@@ -137,10 +138,10 @@ const PDFPreview = () => {
|
||||
presentDialog({
|
||||
context: attachment?.hash,
|
||||
input: true,
|
||||
inputPlaceholder: "Enter password",
|
||||
positiveText: "Unlock",
|
||||
title: "Decrypt",
|
||||
paragraph: "Please input password to view pdf.",
|
||||
inputPlaceholder: strings.enterPassword(),
|
||||
positiveText: strings.open(),
|
||||
title: strings.pdfLocked(),
|
||||
paragraph: strings.pdfLockedDesc(),
|
||||
positivePress: (value) => {
|
||||
setTimeout(() => {
|
||||
setPassword(value);
|
||||
@@ -187,8 +188,7 @@ const PDFPreview = () => {
|
||||
}}
|
||||
color={colors.static.white}
|
||||
>
|
||||
Loading {`${progress?.percent ? `(${progress?.percent})` : ""}`}
|
||||
... Please wait
|
||||
{strings.loadingWithProgress(progress.percent)}
|
||||
</Paragraph>
|
||||
</Animated.View>
|
||||
) : (
|
||||
|
||||
@@ -52,6 +52,7 @@ import { Button } from "../../ui/button";
|
||||
import Input from "../../ui/input";
|
||||
import Seperator from "../../ui/seperator";
|
||||
import Paragraph from "../../ui/typography/paragraph";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
export class VaultDialog extends Component {
|
||||
constructor(props) {
|
||||
@@ -76,7 +77,7 @@ export class VaultDialog extends Component {
|
||||
changePassword: false,
|
||||
copyNote: false,
|
||||
revokeFingerprintAccess: false,
|
||||
title: "Unlock Note",
|
||||
title: strings.goToEditor(),
|
||||
description: null,
|
||||
clearVault: false,
|
||||
deleteVault: false,
|
||||
@@ -91,46 +92,25 @@ export class VaultDialog extends Component {
|
||||
this.password = null;
|
||||
this.confirmPassword = null;
|
||||
this.newPassword = null;
|
||||
(this.title = !this.state.novault
|
||||
? "Create Vault"
|
||||
this.title = !this.state.novault
|
||||
? strings.createVault()
|
||||
: this.state.fingerprintAccess
|
||||
? "Vault Fingerprint Unlock"
|
||||
? strings.vaultFingerprintUnlock()
|
||||
: this.state.revokeFingerprintAccess
|
||||
? "Revoke Vault Fingerprint Unlock"
|
||||
? strings.revokeVaultFingerprintUnlock()
|
||||
: this.state.changePassword
|
||||
? "Change Vault Password"
|
||||
? strings.changeVaultPassword()
|
||||
: this.state.noteLocked
|
||||
? this.state.deleteNote
|
||||
? "Delete note"
|
||||
? strings.deleteNote()
|
||||
: this.state.share
|
||||
? "Share note"
|
||||
? strings.shareNote()
|
||||
: this.state.copyNote
|
||||
? "Copy note"
|
||||
? strings.copyNote()
|
||||
: this.state.goToEditor
|
||||
? "Unlock note"
|
||||
: "Unlock note"
|
||||
: "Lock note"),
|
||||
(this.description = !this.state.novault
|
||||
? "Set a password to create vault"
|
||||
: this.state.fingerprintAccess
|
||||
? "Enter vault password to enable fingerprint unlocking."
|
||||
: this.state.revokeFingerprintAccess
|
||||
? "Disable vault fingerprint unlock "
|
||||
: this.state.changePassword
|
||||
? "Setup a new password for the vault."
|
||||
: this.state.permanant
|
||||
? "Enter password to remove note from vault."
|
||||
: this.state.noteLocked
|
||||
? this.state.deleteNote
|
||||
? "Unlock note to delete it. If biometrics are not working, you can enter device pin to unlock vault."
|
||||
: this.state.share
|
||||
? "Unlock note to share it. If biometrics are not working, you can enter device pin to unlock vault."
|
||||
: this.state.copyNote
|
||||
? "Unlock note to copy it. If biometrics are not working, you can enter device pin to unlock vault."
|
||||
: this.state.goToEditor
|
||||
? "Unlock note to open it in editor."
|
||||
: "Enter vault password to unlock note. If biometrics are not working, you can enter device pin to unlock vault."
|
||||
: "Enter vault password to lock note. If biometrics are not working, you can enter device pin to lock note.");
|
||||
? strings.goToEditor()
|
||||
: strings.goToEditor()
|
||||
: strings.lockNote();
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
@@ -708,12 +688,7 @@ export class VaultDialog extends Component {
|
||||
paddingTop: 12
|
||||
}}
|
||||
>
|
||||
<DialogHeader
|
||||
title={this.state.title}
|
||||
paragraph={this.state.description}
|
||||
icon="shield"
|
||||
padding={12}
|
||||
/>
|
||||
<DialogHeader title={this.state.title} icon="shield" padding={12} />
|
||||
<Seperator half />
|
||||
|
||||
<View
|
||||
@@ -761,11 +736,11 @@ export class VaultDialog extends Component {
|
||||
changePassword ? null : (
|
||||
<Button
|
||||
onPress={() =>
|
||||
this._onPressFingerprintAuth("Unlock note", "")
|
||||
this._onPressFingerprintAuth(strings.unlockNote(), "")
|
||||
}
|
||||
icon="fingerprint"
|
||||
width="100%"
|
||||
title={"Biometric unlock"}
|
||||
title={strings.unlockWithBiometrics()}
|
||||
type="transparent"
|
||||
/>
|
||||
)}
|
||||
@@ -788,7 +763,7 @@ export class VaultDialog extends Component {
|
||||
marginTop: 10
|
||||
}}
|
||||
width="100%"
|
||||
title={"Delete all notes"}
|
||||
title={strings.deleteAllNotes()}
|
||||
type="errorShade"
|
||||
/>
|
||||
)}
|
||||
@@ -867,9 +842,7 @@ export class VaultDialog extends Component {
|
||||
{this.state.biometricUnlock &&
|
||||
!this.state.isBiometryEnrolled &&
|
||||
novault ? (
|
||||
<Paragraph>
|
||||
Unlock with password once to enable biometric access.
|
||||
</Paragraph>
|
||||
<Paragraph>{strings.vaultEnableBiometrics()}</Paragraph>
|
||||
) : null}
|
||||
|
||||
{this.state.isBiometryAvailable &&
|
||||
@@ -888,7 +861,7 @@ export class VaultDialog extends Component {
|
||||
}}
|
||||
icon="fingerprint"
|
||||
width="100%"
|
||||
title="Biometric unlocking"
|
||||
title={strings.unlockWithBiometrics()}
|
||||
iconColor={
|
||||
this.state.biometricUnlock
|
||||
? colors.selected.accent
|
||||
@@ -908,26 +881,26 @@ export class VaultDialog extends Component {
|
||||
}
|
||||
positiveTitle={
|
||||
deleteVault
|
||||
? "Delete"
|
||||
? strings.deleteVault()
|
||||
: clearVault
|
||||
? "Clear"
|
||||
? strings.clearVault()
|
||||
: fingerprintAccess
|
||||
? "Enable"
|
||||
? strings.enable()
|
||||
: this.state.revokeFingerprintAccess
|
||||
? "Revoke"
|
||||
? strings.revoke()
|
||||
: changePassword
|
||||
? "Change"
|
||||
? strings.change()
|
||||
: this.state.noteLocked
|
||||
? deleteNote
|
||||
? "Delete"
|
||||
? strings.delete()
|
||||
: share
|
||||
? "Share "
|
||||
? strings.share()
|
||||
: goToEditor
|
||||
? "Open"
|
||||
: "Unlock"
|
||||
? strings.open()
|
||||
: strings.unlock()
|
||||
: !note.id
|
||||
? "Create"
|
||||
: "Lock"
|
||||
? strings.create()
|
||||
: strings.lock()
|
||||
}
|
||||
/>
|
||||
</View>
|
||||
|
||||
@@ -40,6 +40,7 @@ import Navigation from "../../services/navigation";
|
||||
import { eOpenLoginDialog } from "../../utils/events";
|
||||
import { AuthMode } from "../auth";
|
||||
import { eSendEvent } from "../../services/event-manager";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
const Intro = ({ navigation }) => {
|
||||
const { colors } = useThemeColors();
|
||||
@@ -212,7 +213,7 @@ const Intro = ({ navigation }) => {
|
||||
}}
|
||||
fontSize={SIZE.md}
|
||||
type="accent"
|
||||
title="Get started"
|
||||
title={strings.getStarted()}
|
||||
/>
|
||||
</View>
|
||||
</ScrollView>
|
||||
|
||||
@@ -29,6 +29,7 @@ import { IconButton } from "../../ui/icon-button";
|
||||
import Heading from "../../ui/typography/heading";
|
||||
import Paragraph from "../../ui/typography/paragraph";
|
||||
import { getFormattedDate } from "@notesnook/common";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
export const NotebookHeader = ({
|
||||
notebook,
|
||||
@@ -148,11 +149,7 @@ export const NotebookHeader = ({
|
||||
size={SIZE.xs}
|
||||
color={colors.secondary.paragraph}
|
||||
>
|
||||
{notebook && totalNotes > 1
|
||||
? totalNotes + " notes"
|
||||
: totalNotes === 1
|
||||
? totalNotes + " note"
|
||||
: "0 notes"}
|
||||
{strings.notes(totalNotes || 0)}
|
||||
</Paragraph>
|
||||
</View>
|
||||
);
|
||||
|
||||
@@ -32,6 +32,7 @@ import Sort from "../../sheets/sort";
|
||||
import { Button } from "../../ui/button";
|
||||
import { IconButton } from "../../ui/icon-button";
|
||||
import Heading from "../../ui/typography/heading";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
type SectionHeaderProps = {
|
||||
item: GroupHeader;
|
||||
@@ -103,7 +104,7 @@ export const SectionHeader = React.memo<
|
||||
textAlignVertical: "center"
|
||||
}}
|
||||
>
|
||||
{!item.title || item.title === "" ? "Pinned" : item.title}
|
||||
{!item.title || item.title === "" ? strings.pinned() : item.title}
|
||||
</Heading>
|
||||
</TouchableOpacity>
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ import { ReminderTime } from "../../ui/reminder-time";
|
||||
import { TimeSince } from "../../ui/time-since";
|
||||
import Heading from "../../ui/typography/heading";
|
||||
import Paragraph from "../../ui/typography/paragraph";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
type NoteItemProps = {
|
||||
item: Note | BaseTrashItem<Note>;
|
||||
@@ -341,9 +342,10 @@ const NoteItem = ({
|
||||
marginRight: 6
|
||||
}}
|
||||
>
|
||||
Deleted on{" "}
|
||||
{item && item.dateDeleted
|
||||
? new Date(item.dateDeleted).toISOString().slice(0, 10)
|
||||
? strings.deletedOn(
|
||||
new Date(item.dateDeleted).toISOString().slice(0, 10)
|
||||
)
|
||||
: null}
|
||||
</Paragraph>
|
||||
|
||||
@@ -354,8 +356,7 @@ const NoteItem = ({
|
||||
marginRight: 6
|
||||
}}
|
||||
>
|
||||
{(item as TrashItem).itemType[0].toUpperCase() +
|
||||
(item as TrashItem).itemType.slice(1)}
|
||||
{strings.note()}
|
||||
</Paragraph>
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -30,6 +30,7 @@ import { Properties } from "../../properties";
|
||||
import { IconButton } from "../../ui/icon-button";
|
||||
import Heading from "../../ui/typography/heading";
|
||||
import Paragraph from "../../ui/typography/paragraph";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
type NotebookItemProps = {
|
||||
item: Notebook | BaseTrashItem<Notebook>;
|
||||
@@ -112,10 +113,11 @@ export const NotebookItem = ({
|
||||
marginRight: 6
|
||||
}}
|
||||
>
|
||||
{"Deleted on " +
|
||||
{strings.deletedOn(
|
||||
new Date((item as TrashItem).dateDeleted)
|
||||
.toISOString()
|
||||
.slice(0, 10)}
|
||||
.slice(0, 10)
|
||||
)}
|
||||
</Paragraph>
|
||||
<Paragraph
|
||||
color={colors.primary.accent}
|
||||
@@ -147,11 +149,7 @@ export const NotebookItem = ({
|
||||
marginRight: 6
|
||||
}}
|
||||
>
|
||||
{item && totalNotes > 1
|
||||
? totalNotes + " notes"
|
||||
: totalNotes === 1
|
||||
? totalNotes + " note"
|
||||
: "0 notes"}
|
||||
{strings.notes(totalNotes)}
|
||||
</Paragraph>
|
||||
|
||||
{item.pinned ? (
|
||||
@@ -183,11 +181,7 @@ export const NotebookItem = ({
|
||||
marginRight: 6
|
||||
}}
|
||||
>
|
||||
{item && totalNotes > 1
|
||||
? totalNotes + " notes"
|
||||
: totalNotes === 1
|
||||
? totalNotes + " note"
|
||||
: "0 notes"}
|
||||
{strings.notes(totalNotes)}
|
||||
</Paragraph>
|
||||
</>
|
||||
) : null}
|
||||
|
||||
@@ -30,6 +30,7 @@ import { ReminderTime } from "../../ui/reminder-time";
|
||||
import Heading from "../../ui/typography/heading";
|
||||
import Paragraph from "../../ui/typography/paragraph";
|
||||
import SelectionWrapper, { selectItem } from "../selection-wrapper";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
const ReminderItem = React.memo(
|
||||
({
|
||||
@@ -108,7 +109,7 @@ const ReminderItem = React.memo(
|
||||
color={colors.secondary.paragraph}
|
||||
style={{ marginLeft: 5 }}
|
||||
>
|
||||
Disabled
|
||||
{strings.disabled()}
|
||||
</Paragraph>
|
||||
</View>
|
||||
) : null}
|
||||
@@ -137,9 +138,7 @@ const ReminderItem = React.memo(
|
||||
color={colors.secondary.paragraph}
|
||||
style={{ marginLeft: 5 }}
|
||||
>
|
||||
{item.recurringMode.slice(0, 1).toUpperCase() +
|
||||
item.recurringMode.replace("y", "i").slice(1) +
|
||||
"ly"}
|
||||
{strings.reminderRecurringMode[item.recurringMode]()}
|
||||
</Paragraph>
|
||||
</View>
|
||||
) : null}
|
||||
|
||||
@@ -29,6 +29,7 @@ import { IconButton } from "../../ui/icon-button";
|
||||
import Heading from "../../ui/typography/heading";
|
||||
import Paragraph from "../../ui/typography/paragraph";
|
||||
import SelectionWrapper, { selectItem } from "../selection-wrapper";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
const TagItem = React.memo(
|
||||
({
|
||||
@@ -77,11 +78,7 @@ const TagItem = React.memo(
|
||||
marginTop: 5
|
||||
}}
|
||||
>
|
||||
{totalNotes > 1
|
||||
? totalNotes + " notes"
|
||||
: totalNotes === 1
|
||||
? totalNotes + " note"
|
||||
: null}
|
||||
{strings.notes(totalNotes)}
|
||||
</Paragraph>
|
||||
</View>
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ import { IconButton } from "../ui/icon-button";
|
||||
import Seperator from "../ui/seperator";
|
||||
import Paragraph from "../ui/typography/paragraph";
|
||||
import { diff } from "diffblazer";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
const MergeConflicts = () => {
|
||||
const { colors } = useThemeColors();
|
||||
@@ -171,7 +172,11 @@ const MergeConflicts = () => {
|
||||
fontWeight: "bold"
|
||||
}}
|
||||
>
|
||||
{isCurrent ? "(This Device)" : "(Incoming)"}
|
||||
(
|
||||
{isCurrent
|
||||
? strings.mergeConflict.thisDevice()
|
||||
: strings.mergeConflict.otherDevice()}
|
||||
)
|
||||
</Text>
|
||||
{"\n"}
|
||||
{getFormattedDate(contentToKeep?.dateEdited)}
|
||||
@@ -191,7 +196,7 @@ const MergeConflicts = () => {
|
||||
setCopy(contentToKeep);
|
||||
setDialogVisible(true);
|
||||
}}
|
||||
title="Save a copy"
|
||||
title={strings.saveACopy()}
|
||||
type="secondary"
|
||||
height={30}
|
||||
style={{
|
||||
@@ -204,7 +209,7 @@ const MergeConflicts = () => {
|
||||
<View style={{ width: 10 }} />
|
||||
{isDiscarded ? (
|
||||
<Button
|
||||
title="Discard"
|
||||
title={strings.discard()}
|
||||
type="accent"
|
||||
buttonType={{
|
||||
color: colors.static.red,
|
||||
@@ -234,7 +239,9 @@ const MergeConflicts = () => {
|
||||
}}
|
||||
type="accent"
|
||||
fontSize={SIZE.xs}
|
||||
title={keeping && !isDiscarded ? "Undo" : "Keep"}
|
||||
title={
|
||||
keeping && !isDiscarded ? strings.undo() : strings.keep()
|
||||
}
|
||||
onPress={() => {
|
||||
setKeep(keeping && !isDiscarded ? null : contentToKeep);
|
||||
}}
|
||||
@@ -277,11 +284,7 @@ const MergeConflicts = () => {
|
||||
{dialogVisible && (
|
||||
<BaseDialog visible={true}>
|
||||
<DialogContainer>
|
||||
<DialogHeader
|
||||
title="Apply Changes"
|
||||
paragraph="Apply selected changes to note?"
|
||||
padding={12}
|
||||
/>
|
||||
<DialogHeader title={strings.applyChanges()} padding={12} />
|
||||
<Seperator />
|
||||
<DialogButtons
|
||||
positiveTitle="Apply"
|
||||
|
||||
@@ -37,6 +37,7 @@ import { Pressable } from "../ui/pressable";
|
||||
import Seperator from "../ui/seperator";
|
||||
import Paragraph from "../ui/typography/paragraph";
|
||||
import NotePreview from "./preview";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
const HistoryItem = ({
|
||||
index,
|
||||
@@ -141,11 +142,7 @@ export default function NoteHistory({
|
||||
return (
|
||||
<View>
|
||||
<SheetProvider context="note_history" />
|
||||
<DialogHeader
|
||||
title="Note history"
|
||||
paragraph="Revert back to an older version of this note"
|
||||
padding={12}
|
||||
/>
|
||||
<DialogHeader title={strings.noteHistory()} padding={12} />
|
||||
|
||||
<Seperator />
|
||||
|
||||
@@ -180,7 +177,7 @@ export default function NoteHistory({
|
||||
<>
|
||||
<Icon name="history" size={50} color={colors.primary.icon} />
|
||||
<Paragraph color={colors.secondary.paragraph}>
|
||||
No note history found on this device.
|
||||
{strings.noteHistoryPlaceholder()}
|
||||
</Paragraph>
|
||||
</>
|
||||
)}
|
||||
@@ -196,7 +193,7 @@ export default function NoteHistory({
|
||||
alignSelf: "center"
|
||||
}}
|
||||
>
|
||||
Note version history is local only.{" "}
|
||||
{strings.noteHistoryNotice[0]()}{" "}
|
||||
<Text
|
||||
onPress={() => {
|
||||
openLinkInBrowser(
|
||||
@@ -208,7 +205,7 @@ export default function NoteHistory({
|
||||
textDecorationLine: "underline"
|
||||
}}
|
||||
>
|
||||
Learn how this works.
|
||||
{strings.noteHistoryNotice[1]()}
|
||||
</Text>
|
||||
</Paragraph>
|
||||
</View>
|
||||
|
||||
@@ -35,6 +35,7 @@ import { presentDialog } from "../dialog/functions";
|
||||
import { Button } from "../ui/button";
|
||||
import Paragraph from "../ui/typography/paragraph";
|
||||
import { diff } from "diffblazer";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -150,7 +151,7 @@ export default function NotePreview({ session, content, note }) {
|
||||
}}
|
||||
>
|
||||
<Paragraph color={colors.secondary.paragraph}>
|
||||
Preview not available, content is encrypted.
|
||||
{strings.encryptedNoteHistoryNotice()}
|
||||
</Paragraph>
|
||||
</View>
|
||||
)}
|
||||
@@ -160,10 +161,15 @@ export default function NotePreview({ session, content, note }) {
|
||||
paddingHorizontal: 12
|
||||
}}
|
||||
>
|
||||
<Button onPress={restore} title="Restore" type="accent" width="100%" />
|
||||
<Button
|
||||
onPress={restore}
|
||||
title={strings.restore()}
|
||||
type="accent"
|
||||
width="100%"
|
||||
/>
|
||||
<Button
|
||||
onPress={deleteNote}
|
||||
title="Delete permanently"
|
||||
title={strings.deletePermanently()}
|
||||
type="error"
|
||||
width="100%"
|
||||
style={{
|
||||
|
||||
@@ -36,6 +36,7 @@ import ColorPicker from "../dialogs/color-picker";
|
||||
import { Button } from "../ui/button";
|
||||
import NativeTooltip from "../../utils/tooltip";
|
||||
import { Pressable } from "../ui/pressable";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
const ColorItem = ({ item, note }: { item: Color; note: Note }) => {
|
||||
const { colors } = useThemeColors();
|
||||
@@ -145,7 +146,7 @@ export const ColorTags = ({ item }: { item: Note }) => {
|
||||
buttonType={{
|
||||
text: colors.primary.accent
|
||||
}}
|
||||
title="Add color"
|
||||
title={strings.addColor()}
|
||||
type="secondary"
|
||||
icon="plus"
|
||||
iconPosition="right"
|
||||
|
||||
@@ -23,26 +23,10 @@ import { useThemeColors } from "@notesnook/theme";
|
||||
import { SIZE } from "../../utils/size";
|
||||
import Paragraph from "../ui/typography/paragraph";
|
||||
import { getFormattedDate } from "@notesnook/common";
|
||||
import { strings } from "@notesnook/intl";
|
||||
export const DateMeta = ({ item }) => {
|
||||
const { colors } = useThemeColors();
|
||||
|
||||
const getNameFromKey = (key) => {
|
||||
switch (key) {
|
||||
case "dateCreated":
|
||||
return "Created at:";
|
||||
case "dateEdited":
|
||||
return "Last edited at:";
|
||||
case "dateModified":
|
||||
return "Last modified at:";
|
||||
case "dateDeleted":
|
||||
return "Deleted at:";
|
||||
case "dateUploaded":
|
||||
return "Uploaded at:";
|
||||
default:
|
||||
return key;
|
||||
}
|
||||
};
|
||||
|
||||
function getDateMeta() {
|
||||
let keys = Object.keys(item);
|
||||
if (keys.includes("dateEdited"))
|
||||
@@ -64,7 +48,7 @@ export const DateMeta = ({ item }) => {
|
||||
}}
|
||||
>
|
||||
<Paragraph size={SIZE.xs} color={colors.secondary.paragraph}>
|
||||
{getNameFromKey(key)}
|
||||
{strings.dateDescFromKey(key)}
|
||||
</Paragraph>
|
||||
<Paragraph size={SIZE.xs} color={colors.secondary.paragraph}>
|
||||
{getFormattedDate(item[key], "date-time")}
|
||||
|
||||
@@ -39,6 +39,7 @@ import Notebooks from "./notebooks";
|
||||
import { Synced } from "./synced";
|
||||
import { TagStrip, Tags } from "./tags";
|
||||
import { tabBarRef } from "../../utils/global-refs";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
const Line = ({ top = 6, bottom = 6 }) => {
|
||||
const { colors } = useThemeColors();
|
||||
@@ -61,7 +62,7 @@ export const Properties = ({ close = () => {}, item, buttons = [] }) => {
|
||||
if (!item || !item.id) {
|
||||
return (
|
||||
<Paragraph style={{ marginVertical: 10, alignSelf: "center" }}>
|
||||
Start writing to save your note.
|
||||
{strings.noNotePropertiesNotice()}
|
||||
</Paragraph>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import { SIZE } from "../../utils/size";
|
||||
import { Button } from "../ui/button";
|
||||
import Heading from "../ui/typography/heading";
|
||||
import { Pressable } from "../ui/pressable";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
export default function Notebooks({ note, close, full }) {
|
||||
const { colors } = useThemeColors();
|
||||
@@ -102,7 +103,7 @@ export default function Notebooks({ note, close, full }) {
|
||||
|
||||
{noteNotebooks.length > 1 && !full ? (
|
||||
<Button
|
||||
title={`View all linked notebooks`}
|
||||
title={strings.viewAllLinkedNotebooks()}
|
||||
fontSize={SIZE.xs}
|
||||
style={{
|
||||
alignSelf: "flex-end",
|
||||
|
||||
@@ -28,6 +28,7 @@ import { sleep } from "../../utils/time";
|
||||
import { Button } from "../ui/button";
|
||||
import Heading from "../ui/typography/heading";
|
||||
import Paragraph from "../ui/typography/paragraph";
|
||||
import { strings } from "@notesnook/intl";
|
||||
export const Synced = ({ item, close }) => {
|
||||
const { colors } = useThemeColors();
|
||||
const user = useUserStore((state) => state.user);
|
||||
@@ -71,7 +72,7 @@ export const Synced = ({ item, close }) => {
|
||||
flexWrap: "wrap"
|
||||
}}
|
||||
>
|
||||
Encrypted and synced
|
||||
{strings.noteSyncedNoticeHeading()}
|
||||
</Heading>
|
||||
{shouldShrink ? null : (
|
||||
<Paragraph
|
||||
@@ -81,7 +82,7 @@ export const Synced = ({ item, close }) => {
|
||||
size={SIZE.xs}
|
||||
color={colors.primary.paragraph}
|
||||
>
|
||||
No one can view this {item.itemType || item.type} except you.
|
||||
{strings.noteSyncedNoticeDesc(item.itemType || item.type)}
|
||||
</Paragraph>
|
||||
)}
|
||||
</View>
|
||||
@@ -99,7 +100,7 @@ export const Synced = ({ item, close }) => {
|
||||
console.error(e);
|
||||
}
|
||||
}}
|
||||
title="Learn more"
|
||||
title={strings.learnMore()}
|
||||
fontSize={SIZE.xs}
|
||||
height={30}
|
||||
type="secondaryAccented"
|
||||
|
||||
@@ -27,6 +27,7 @@ import { sleep } from "../../utils/time";
|
||||
import ManageTagsSheet from "../sheets/manage-tags";
|
||||
import { Button } from "../ui/button";
|
||||
import { ColorTags } from "./color-tags";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
export const Tags = ({ item, close }) => {
|
||||
const { colors } = useThemeColors();
|
||||
@@ -51,7 +52,7 @@ export const Tags = ({ item, close }) => {
|
||||
buttonType={{
|
||||
text: colors.primary.accent
|
||||
}}
|
||||
title="Add tag"
|
||||
title={strings.addTag()}
|
||||
type="secondary"
|
||||
icon="plus"
|
||||
iconPosition="right"
|
||||
|
||||
@@ -40,6 +40,7 @@ import { MoveNotes } from "../move-notes/movenote";
|
||||
import { eOnNotebookUpdated } from "../../../utils/events";
|
||||
import { getParentNotebookId } from "../../../utils/notebooks";
|
||||
import { useNotebookStore } from "../../../stores/use-notebook-store";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
export const AddNotebookSheet = ({
|
||||
notebook,
|
||||
@@ -119,7 +120,7 @@ export const AddNotebookSheet = ({
|
||||
}}
|
||||
>
|
||||
<Heading size={SIZE.lg}>
|
||||
{notebook ? "Edit Notebook" : "New Notebook"}
|
||||
{notebook ? strings.editNotebook() : strings.newNotebook()}
|
||||
</Heading>
|
||||
|
||||
<Seperator />
|
||||
@@ -157,7 +158,7 @@ export const AddNotebookSheet = ({
|
||||
/>
|
||||
|
||||
<Button
|
||||
title={notebook ? "Save" : "Add"}
|
||||
title={notebook ? strings.save() : strings.add()}
|
||||
type="accent"
|
||||
height={45}
|
||||
fontSize={SIZE.md}
|
||||
|
||||
@@ -55,6 +55,7 @@ import { useNotebookItemSelectionStore } from "./store";
|
||||
import { AddNotebookSheet } from "../add-notebook";
|
||||
import Input from "../../ui/input";
|
||||
import { presentDialog } from "../../dialog/functions";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
async function updateInitialSelectionState(items: string[]) {
|
||||
const relations = await db.relations
|
||||
@@ -200,11 +201,11 @@ const MoveNoteSheet = ({
|
||||
minHeight: 10,
|
||||
flexShrink: 1
|
||||
}}
|
||||
title="Select notebooks"
|
||||
title={strings.selectNotebooks()}
|
||||
paragraph={
|
||||
!multiSelect
|
||||
? "Long press to enable multi-select."
|
||||
: "Select notebooks you want to add note(s) to."
|
||||
? strings.enableMultiSelect()
|
||||
: strings.selectNotebooksDesc()
|
||||
}
|
||||
/>
|
||||
|
||||
@@ -236,7 +237,7 @@ const MoveNoteSheet = ({
|
||||
paddingHorizontal: 24,
|
||||
alignSelf: "flex-start"
|
||||
}}
|
||||
title="Save"
|
||||
title={strings.save()}
|
||||
type={"accent"}
|
||||
onPress={onSave}
|
||||
/>
|
||||
@@ -319,7 +320,7 @@ const MoveNoteSheet = ({
|
||||
/>
|
||||
) : (
|
||||
<Paragraph color={colors.primary.icon}>
|
||||
No notebooks
|
||||
{strings.emptyPlaceholders("notebook")}
|
||||
</Paragraph>
|
||||
)}
|
||||
</View>
|
||||
|
||||
@@ -30,6 +30,7 @@ import DialogHeader from "../../dialog/dialog-header";
|
||||
import { Button } from "../../ui/button";
|
||||
import Input from "../../ui/input";
|
||||
import { eUserLoggedIn } from "../../../utils/events";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
type ChangeEmailProps = {
|
||||
actionSheetRef: RefObject<ActionSheetRef>;
|
||||
@@ -103,8 +104,8 @@ export const ChangeEmail = ({ close }: ChangeEmailProps) => {
|
||||
return (
|
||||
<View style={{ paddingHorizontal: 12 }}>
|
||||
<DialogHeader
|
||||
title="Change email"
|
||||
paragraph="Your account email will be changed without affecting your subscription or any other settings."
|
||||
title={strings.changeEmail()}
|
||||
paragraph={strings.changeEmailDesc()}
|
||||
/>
|
||||
<View
|
||||
style={{
|
||||
@@ -149,8 +150,8 @@ export const ChangeEmail = ({ close }: ChangeEmailProps) => {
|
||||
loading
|
||||
? undefined
|
||||
: step === EmailChangeSteps.verify
|
||||
? "Verify"
|
||||
: "Change email"
|
||||
? strings.verify()
|
||||
: strings.changeEmail()
|
||||
}
|
||||
type="accent"
|
||||
width={250}
|
||||
|
||||
@@ -35,6 +35,7 @@ import { IconButton } from "../../ui/icon-button";
|
||||
import { Pressable } from "../../ui/pressable";
|
||||
import Heading from "../../ui/typography/heading";
|
||||
import Paragraph from "../../ui/typography/paragraph";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
type TabItem = {
|
||||
id: number;
|
||||
@@ -137,7 +138,9 @@ const TabItemComponent = (props: {
|
||||
numberOfLines={1}
|
||||
size={SIZE.md}
|
||||
>
|
||||
{props.tab.noteId ? item?.title || "Untitled note" : "New note"}
|
||||
{props.tab.noteId
|
||||
? item?.title || strings.untitledNote()
|
||||
: strings.newNote()}
|
||||
</Paragraph>
|
||||
</View>
|
||||
|
||||
@@ -229,7 +232,7 @@ export default function EditorTabs({
|
||||
alignItems: "center"
|
||||
}}
|
||||
>
|
||||
<Heading size={SIZE.lg}>Tabs</Heading>
|
||||
<Heading size={SIZE.lg}>{strings.tabs()}</Heading>
|
||||
<Button
|
||||
onPress={() => {
|
||||
useTabStore.getState().newTab();
|
||||
@@ -240,7 +243,7 @@ export default function EditorTabs({
|
||||
}, 500);
|
||||
close?.();
|
||||
}}
|
||||
title="New tab"
|
||||
title={strings.newTab()}
|
||||
icon="plus"
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
|
||||
@@ -52,6 +52,7 @@ import { Pressable } from "../../ui/pressable";
|
||||
import Seperator from "../../ui/seperator";
|
||||
import Heading from "../../ui/typography/heading";
|
||||
import Paragraph from "../../ui/typography/paragraph";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
const ExportNotesSheet = ({
|
||||
ids,
|
||||
@@ -175,14 +176,7 @@ const ExportNotesSheet = ({
|
||||
>
|
||||
<DialogHeader
|
||||
icon="export"
|
||||
title={
|
||||
ids.length > 1 ? `Export ${ids.length} Notes` : "Export Note"
|
||||
}
|
||||
paragraph={`All exports are saved in ${
|
||||
Platform.OS === "android"
|
||||
? "the selected"
|
||||
: "Notesnook/exported"
|
||||
} folder in phone storage`}
|
||||
title={`${strings.export()} ${strings.notes(ids.length)}`}
|
||||
/>
|
||||
</View>
|
||||
|
||||
@@ -263,11 +257,7 @@ const ExportNotesSheet = ({
|
||||
{!complete ? (
|
||||
<>
|
||||
<ActivityIndicator />
|
||||
<Paragraph>
|
||||
{`${
|
||||
status ? `${status})` : `Exporting notes`
|
||||
}... Please wait`}
|
||||
</Paragraph>
|
||||
<Paragraph>{strings.exportingNotes(status)}</Paragraph>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
@@ -287,21 +277,20 @@ const ExportNotesSheet = ({
|
||||
}}
|
||||
color={colors.secondary.heading}
|
||||
>
|
||||
{ids.length > 1
|
||||
? `${ids.length} Notes exported`
|
||||
: "Note exported"}
|
||||
{strings.exportSuccessHeading(ids.length)}
|
||||
</Heading>
|
||||
<Paragraph
|
||||
style={{
|
||||
textAlign: "center"
|
||||
}}
|
||||
>
|
||||
Your {ids.length > 1 ? "notes are" : "note is"} exported
|
||||
successfully as {result?.fileName}
|
||||
{strings.exportSuccessDesc(result?.fileName as string)}
|
||||
</Paragraph>
|
||||
<Button
|
||||
title={
|
||||
Platform.OS === "android" ? "Open file location" : "Open"
|
||||
Platform.OS === "android"
|
||||
? strings.openFileLocation()
|
||||
: strings.open()
|
||||
}
|
||||
type="accent"
|
||||
width={250}
|
||||
@@ -332,7 +321,7 @@ const ExportNotesSheet = ({
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
title="Share"
|
||||
title={strings.share()}
|
||||
type="secondaryAccented"
|
||||
width={250}
|
||||
fontSize={SIZE.md}
|
||||
@@ -356,7 +345,7 @@ const ExportNotesSheet = ({
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
title="Export in another format"
|
||||
title={strings.exportAgain()}
|
||||
type="inverted"
|
||||
width={250}
|
||||
fontSize={SIZE.md}
|
||||
|
||||
@@ -23,6 +23,7 @@ import FileViewer from "react-native-file-viewer";
|
||||
import { ToastManager } from "../../../services/event-manager";
|
||||
import { SIZE } from "../../../utils/size";
|
||||
import { Button } from "../../ui/button";
|
||||
import { strings } from "@notesnook/intl";
|
||||
export const ShareComponent = ({ uri, name, padding }) => {
|
||||
return (
|
||||
<View
|
||||
@@ -31,7 +32,7 @@ export const ShareComponent = ({ uri, name, padding }) => {
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
title="Open"
|
||||
title={strings.open()}
|
||||
type="accent"
|
||||
width="100%"
|
||||
fontSize={SIZE.md}
|
||||
@@ -50,7 +51,7 @@ export const ShareComponent = ({ uri, name, padding }) => {
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
title="Share"
|
||||
title={strings.share()}
|
||||
type="shade"
|
||||
width="100%"
|
||||
fontSize={SIZE.md}
|
||||
|
||||
@@ -34,6 +34,7 @@ import { Button } from "../../ui/button";
|
||||
import Seperator from "../../ui/seperator";
|
||||
import Heading from "../../ui/typography/heading";
|
||||
import Paragraph from "../../ui/typography/paragraph";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
export const Issue = ({ defaultTitle, defaultBody, issueTitle }) => {
|
||||
const { colors } = useThemeColors();
|
||||
@@ -99,14 +100,14 @@ Logged in: ${user ? "yes" : "no"}`,
|
||||
gap: 10
|
||||
}}
|
||||
>
|
||||
<Heading>Issue submitted</Heading>
|
||||
<Heading>{strings.issueCreatedHeading()}</Heading>
|
||||
<Paragraph
|
||||
style={{
|
||||
textAlign: "center"
|
||||
}}
|
||||
selectable={true}
|
||||
>
|
||||
You can track your issue at{" "}
|
||||
{strings.issueCreatedDesc[0]()}
|
||||
<Paragraph
|
||||
style={{
|
||||
textDecorationLine: "underline",
|
||||
@@ -118,12 +119,11 @@ Logged in: ${user ? "yes" : "no"}`,
|
||||
>
|
||||
{issueUrl.current}
|
||||
</Paragraph>
|
||||
. Please note that we will respond to your issue on the given
|
||||
link. We recommend that you save it.
|
||||
. {strings.issueCreatedDesc[1]()}
|
||||
</Paragraph>
|
||||
|
||||
<Button
|
||||
title="Open issue"
|
||||
title={strings.openIssue()}
|
||||
onPress={() => {
|
||||
Linking.openURL(issueUrl.current);
|
||||
}}
|
||||
@@ -135,12 +135,8 @@ Logged in: ${user ? "yes" : "no"}`,
|
||||
) : (
|
||||
<>
|
||||
<DialogHeader
|
||||
title={issueTitle || "Report issue"}
|
||||
paragraph={
|
||||
issueTitle
|
||||
? "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."
|
||||
: "Let us know if you have faced any issue/bug while using Notesnook."
|
||||
}
|
||||
title={issueTitle || strings.issueTitle()}
|
||||
paragraph={issueTitle ? strings.issueDesc() : strings.issueDesc2()}
|
||||
/>
|
||||
|
||||
<Seperator half />
|
||||
@@ -211,7 +207,7 @@ For example:
|
||||
<Seperator />
|
||||
<Button
|
||||
onPress={onPress}
|
||||
title={loading ? null : "Submit"}
|
||||
title={loading ? null : strings.submit()}
|
||||
loading={loading}
|
||||
width="100%"
|
||||
type="accent"
|
||||
@@ -225,7 +221,7 @@ For example:
|
||||
textAlign: "center"
|
||||
}}
|
||||
>
|
||||
The information above will be publically available at{" "}
|
||||
{strings.issueNotice[0]()}{" "}
|
||||
<Text
|
||||
onPress={() => {
|
||||
Linking.openURL("https://github.com/streetwriters/notesnook");
|
||||
@@ -237,8 +233,7 @@ For example:
|
||||
>
|
||||
github.com/streetwriters/notesnook.
|
||||
</Text>{" "}
|
||||
If you want to ask something in general or need some assistance, we
|
||||
would suggest that you{" "}
|
||||
{strings.issueNotice[1]()}{" "}
|
||||
<Text
|
||||
style={{
|
||||
textDecorationLine: "underline",
|
||||
@@ -255,7 +250,7 @@ For example:
|
||||
}
|
||||
}}
|
||||
>
|
||||
join our community on Discord.
|
||||
{strings.issueNotice[2]()}
|
||||
</Text>
|
||||
</Paragraph>
|
||||
</>
|
||||
|
||||
@@ -39,6 +39,7 @@ import {
|
||||
EditorEvents,
|
||||
editorController
|
||||
} from "../../../screens/editor/tiptap/utils";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
const ListNoteItem = ({
|
||||
id,
|
||||
@@ -117,7 +118,7 @@ const ListBlockItem = ({
|
||||
{item?.content.length > 200
|
||||
? item?.content.slice(0, 200) + "..."
|
||||
: !item.content || item.content.trim() === ""
|
||||
? "(Empty block)"
|
||||
? strings.linkNoteEmptyBlock()
|
||||
: item.content}
|
||||
</Paragraph>
|
||||
|
||||
@@ -256,7 +257,7 @@ export default function LinkNote(props: {
|
||||
}}
|
||||
>
|
||||
<Paragraph color={colors.secondary.paragraph} size={SIZE.xs}>
|
||||
SELECTED NOTE
|
||||
{strings.linkNoteSelectedNote()}
|
||||
</Paragraph>
|
||||
<Pressable
|
||||
onPress={() => {
|
||||
@@ -286,7 +287,7 @@ export default function LinkNote(props: {
|
||||
<Paragraph numberOfLines={1}>{selectedNote?.title}</Paragraph>
|
||||
|
||||
<Paragraph color={colors.secondary.paragraph} size={SIZE.xs}>
|
||||
Tap to deselect
|
||||
{strings.tapToDeselect()}
|
||||
</Paragraph>
|
||||
</View>
|
||||
</Pressable>
|
||||
@@ -299,7 +300,7 @@ export default function LinkNote(props: {
|
||||
color={colors.secondary.paragraph}
|
||||
size={SIZE.xs}
|
||||
>
|
||||
LINK TO A SECTION
|
||||
{strings.linkNoteToSection()}
|
||||
</Paragraph>
|
||||
) : null}
|
||||
</View>
|
||||
@@ -342,7 +343,7 @@ export default function LinkNote(props: {
|
||||
style={{
|
||||
marginTop: 10
|
||||
}}
|
||||
title="Create link"
|
||||
title={strings.createLink()}
|
||||
type="accent"
|
||||
width="100%"
|
||||
onPress={() => {
|
||||
|
||||
@@ -48,6 +48,7 @@ import Input from "../../ui/input";
|
||||
import { Pressable } from "../../ui/pressable";
|
||||
import Heading from "../../ui/typography/heading";
|
||||
import Paragraph from "../../ui/typography/paragraph";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
async function updateInitialSelectionState(items: string[]) {
|
||||
const relations = await db.relations
|
||||
@@ -296,7 +297,7 @@ const ManageTagsSheet = (props: {
|
||||
type="selected"
|
||||
>
|
||||
<Heading size={SIZE.sm} color={colors.selected.heading}>
|
||||
Add {'"' + "#" + query + '"'}
|
||||
{strings.add()} {'"' + "#" + query + '"'}
|
||||
</Heading>
|
||||
<Icon name="plus" color={colors.selected.icon} size={SIZE.lg} />
|
||||
</Pressable>
|
||||
@@ -331,7 +332,7 @@ const ManageTagsSheet = (props: {
|
||||
textBreakStrategy="balanced"
|
||||
color={colors.secondary.paragraph}
|
||||
>
|
||||
You do not have any tags.
|
||||
{strings.emptyPlaceholders("tag")}
|
||||
</Paragraph>
|
||||
</View>
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ import Seperator from "../../ui/seperator";
|
||||
import { ProgressBarComponent } from "../../ui/svg/lazy";
|
||||
import Paragraph from "../../ui/typography/paragraph";
|
||||
import { Issue } from "../github/issue";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
export const makeError = (stack: string, component: string) => `
|
||||
|
||||
@@ -133,11 +134,9 @@ export default function Migrate() {
|
||||
>
|
||||
{!loading && !error ? (
|
||||
<DialogHeader
|
||||
title="Save a backup of your notes"
|
||||
title={strings.migrationSaveBackup()}
|
||||
centered
|
||||
paragraph={
|
||||
"Thank you for updating Notesnook! We will be applying some minor changess for a better note taking experience."
|
||||
}
|
||||
paragraph={strings.migrationSaveBackupDesc()}
|
||||
/>
|
||||
) : null}
|
||||
<Seperator />
|
||||
@@ -158,9 +157,7 @@ export default function Migrate() {
|
||||
textAlign: "center"
|
||||
}}
|
||||
>
|
||||
Migrating database{progress ? `(${progress?.collection})` : null}
|
||||
{progress ? `(${progress.current}/${progress.total}) ` : null}
|
||||
... please wait
|
||||
{strings.migrationProgress(progress)}
|
||||
</Paragraph>
|
||||
|
||||
<View
|
||||
@@ -190,9 +187,7 @@ export default function Migrate() {
|
||||
textAlign: "center"
|
||||
}}
|
||||
>
|
||||
An error occurred while migrating your data. You can logout of your
|
||||
account and try to relogin. However this is not recommended as it
|
||||
may result in some data loss if your data was not synced.
|
||||
{strings.migrationError()}
|
||||
</Paragraph>
|
||||
|
||||
{reset ? (
|
||||
@@ -202,11 +197,11 @@ export default function Migrate() {
|
||||
textAlign: "center"
|
||||
}}
|
||||
>
|
||||
App data has been cleared. Kindly relaunch the app to login again.
|
||||
{strings.migrationAppReset()}
|
||||
</Paragraph>
|
||||
) : (
|
||||
<Button
|
||||
title="Logout & clear app data"
|
||||
title={strings.logoutAnClearData()}
|
||||
type="error"
|
||||
width={250}
|
||||
onPress={async () => {
|
||||
@@ -224,7 +219,7 @@ export default function Migrate() {
|
||||
</>
|
||||
) : (
|
||||
<Button
|
||||
title="Save & continue"
|
||||
title={strings.saveAndContinue()}
|
||||
type="accent"
|
||||
width={250}
|
||||
onPress={startMigration}
|
||||
|
||||
@@ -45,6 +45,7 @@ import { Pressable } from "../../ui/pressable";
|
||||
import Seperator from "../../ui/seperator";
|
||||
import Paragraph from "../../ui/typography/paragraph";
|
||||
import { AddNotebookSheet } from "../add-notebook";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
const useNotebookExpandedStore = create<{
|
||||
expanded: {
|
||||
@@ -152,12 +153,10 @@ export const MoveNotebookSheet = ({
|
||||
}}
|
||||
>
|
||||
<DialogHeader
|
||||
title={`Moving ${
|
||||
selectedNotebooks.length > 1
|
||||
? selectedNotebooks.length + " notebooks"
|
||||
: selectedNotebooks[0].title
|
||||
}`}
|
||||
paragraph={"Select the notebook you want to move this notebook to."}
|
||||
title={strings.moveNotebook(
|
||||
selectedNotebooks.length,
|
||||
selectedNotebooks[0].title
|
||||
)}
|
||||
/>
|
||||
</View>
|
||||
<Seperator />
|
||||
@@ -174,7 +173,7 @@ export const MoveNotebookSheet = ({
|
||||
>
|
||||
{moveToTop ? (
|
||||
<Button
|
||||
title="Move to top"
|
||||
title={strings.moveToTop()}
|
||||
style={{
|
||||
alignSelf: "flex-start",
|
||||
width: "100%",
|
||||
|
||||
@@ -39,6 +39,7 @@ import Input from "../../ui/input";
|
||||
import { Pressable } from "../../ui/pressable";
|
||||
import Seperator from "../../ui/seperator";
|
||||
import Paragraph from "../../ui/typography/paragraph";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
const useItemSelectionStore = createItemSelectionStore(true);
|
||||
|
||||
@@ -123,10 +124,7 @@ export const MoveNotes = ({
|
||||
>
|
||||
<Dialog context="local" />
|
||||
|
||||
<DialogHeader
|
||||
title={`Add notes to ${currentNotebook.title}`}
|
||||
paragraph={"Select the notes you want to move to this Notebook."}
|
||||
/>
|
||||
<DialogHeader title={strings.addNotesToNotebook(currentNotebook.title)} />
|
||||
<Seperator />
|
||||
|
||||
<Input
|
||||
@@ -158,7 +156,7 @@ export const MoveNotes = ({
|
||||
<ActivityIndicator size="large" color={colors.primary.accent} />
|
||||
) : (
|
||||
<Paragraph color={colors.secondary.paragraph}>
|
||||
No notes to show
|
||||
{strings.emptyPlaceholders("note")}
|
||||
</Paragraph>
|
||||
)}
|
||||
</View>
|
||||
@@ -185,7 +183,7 @@ export const MoveNotes = ({
|
||||
Navigation.queueRoutesForUpdate();
|
||||
fwdRef?.current?.hide();
|
||||
}}
|
||||
title="Move selected notes"
|
||||
title={strings.moveSelectedNotes()}
|
||||
type="accent"
|
||||
width="100%"
|
||||
/>
|
||||
|
||||
@@ -31,6 +31,7 @@ import { Button } from "../../ui/button";
|
||||
import Seperator from "../../ui/seperator";
|
||||
import Heading from "../../ui/typography/heading";
|
||||
import Paragraph from "../../ui/typography/paragraph";
|
||||
import { strings } from "@notesnook/intl";
|
||||
export type FeatureType = {
|
||||
title: string;
|
||||
body: string;
|
||||
@@ -56,7 +57,7 @@ const NewFeature = ({
|
||||
}}
|
||||
>
|
||||
<Heading color={colors.secondary.heading} size={SIZE.md}>
|
||||
{!version ? "New version " : `v${version} `}Highlights 🎉
|
||||
{!version ? `${strings.newVersion()} ` : `v${version} `}Highlights 🎉
|
||||
</Heading>
|
||||
|
||||
<Seperator />
|
||||
@@ -81,7 +82,7 @@ const NewFeature = ({
|
||||
<Seperator />
|
||||
|
||||
<Button
|
||||
title="Got it"
|
||||
title={strings.gotIt()}
|
||||
type="accent"
|
||||
width={250}
|
||||
style={{
|
||||
|
||||
@@ -51,6 +51,7 @@ import Paragraph from "../../ui/typography/paragraph";
|
||||
import { AddNotebookSheet } from "../add-notebook";
|
||||
import { MoveNotebookSheet } from "../move-notebook";
|
||||
import Sort from "../sort";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
const useItemSelectionStore = createItemSelectionStore(true, false);
|
||||
|
||||
@@ -289,7 +290,7 @@ export const NotebookSheet = () => {
|
||||
}}
|
||||
>
|
||||
<Paragraph size={SIZE.xs} color={colors.primary.icon}>
|
||||
NOTEBOOKS
|
||||
{strings.notebooks()}
|
||||
</Paragraph>
|
||||
<View
|
||||
style={{
|
||||
@@ -433,7 +434,9 @@ export const NotebookSheet = () => {
|
||||
height: 200
|
||||
}}
|
||||
>
|
||||
<Paragraph color={colors.primary.icon}>No notebooks</Paragraph>
|
||||
<Paragraph color={colors.primary.icon}>
|
||||
{strings.emptyPlaceholders("notebook")}
|
||||
</Paragraph>
|
||||
</View>
|
||||
}
|
||||
/>
|
||||
|
||||
@@ -27,6 +27,7 @@ import Seperator from "../../ui/seperator";
|
||||
import { ProgressBarComponent } from "../../ui/svg/lazy";
|
||||
import Heading from "../../ui/typography/heading";
|
||||
import Paragraph from "../../ui/typography/paragraph";
|
||||
import { strings } from "@notesnook/intl";
|
||||
export const Progress = () => {
|
||||
const { colors } = useThemeColors();
|
||||
const { progress } = useSyncProgress();
|
||||
@@ -51,8 +52,8 @@ export const Progress = () => {
|
||||
paddingBottom: 15
|
||||
}}
|
||||
>
|
||||
<Heading size={SIZE.lg}>Syncing your data</Heading>
|
||||
<Paragraph>Please wait while we sync all your data.</Paragraph>
|
||||
<Heading size={SIZE.lg}>{strings.syncingHeading()}</Heading>
|
||||
<Paragraph>{strings.syncingDesc()}</Paragraph>
|
||||
<Seperator />
|
||||
<View
|
||||
style={{
|
||||
@@ -73,8 +74,7 @@ export const Progress = () => {
|
||||
|
||||
{progress ? (
|
||||
<Paragraph color={colors.secondary.paragraph}>
|
||||
{progress.type?.slice(0, 1).toUpperCase() + progress.type?.slice(1)}
|
||||
ing {progress?.current}
|
||||
{strings.networkProgress(progress.type)} {progress?.current}
|
||||
</Paragraph>
|
||||
) : null}
|
||||
</View>
|
||||
|
||||
@@ -37,6 +37,7 @@ import Heading from "../../ui/typography/heading";
|
||||
import Paragraph from "../../ui/typography/paragraph";
|
||||
import { requestInAppReview } from "../../../services/app-review";
|
||||
import { Note } from "@notesnook/core";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
const PublishNoteSheet = ({
|
||||
note: item
|
||||
@@ -120,10 +121,8 @@ const PublishNoteSheet = ({
|
||||
}}
|
||||
>
|
||||
<DialogHeader
|
||||
title={note?.title}
|
||||
paragraph={`Anyone with the link${
|
||||
isLocked ? " and password" : ""
|
||||
} of the published note can view it.`}
|
||||
title={`${strings.publish()} ${strings.note()}`}
|
||||
paragraph={strings.publishDesc()}
|
||||
/>
|
||||
|
||||
{publishing ? (
|
||||
@@ -141,9 +140,9 @@ const PublishNoteSheet = ({
|
||||
textAlign: "center"
|
||||
}}
|
||||
>
|
||||
Please wait...
|
||||
{strings.pleaseWait()}...
|
||||
{downloading && downloading.current && downloading.total
|
||||
? `\nDownloading attachments (${
|
||||
? `\n${strings.downloadingAttachments()} (${
|
||||
downloading?.current / downloading?.total
|
||||
})`
|
||||
: ""}
|
||||
@@ -168,7 +167,7 @@ const PublishNoteSheet = ({
|
||||
flexShrink: 1
|
||||
}}
|
||||
>
|
||||
<Heading size={SIZE.md}>Published at:</Heading>
|
||||
<Heading size={SIZE.md}>{strings.publishedAt()}:</Heading>
|
||||
<Paragraph size={SIZE.sm} numberOfLines={1}>
|
||||
{publishUrl}
|
||||
</Paragraph>
|
||||
@@ -186,8 +185,8 @@ const PublishNoteSheet = ({
|
||||
color: colors.primary.paragraph
|
||||
}}
|
||||
>
|
||||
<Icon color={colors.primary.accent} name="open-in-new" /> Open
|
||||
in browser
|
||||
<Icon color={colors.primary.accent} name="open-in-new" />{" "}
|
||||
{strings.openInBrowser()}
|
||||
</Paragraph>
|
||||
</View>
|
||||
|
||||
@@ -243,10 +242,8 @@ const PublishNoteSheet = ({
|
||||
flexShrink: 1
|
||||
}}
|
||||
>
|
||||
<Heading size={SIZE.md}>Password protection</Heading>
|
||||
<Paragraph>
|
||||
Published note can only be viewed by someone with the password.
|
||||
</Paragraph>
|
||||
<Heading size={SIZE.md}>{strings.monographPassHeading()}</Heading>
|
||||
<Paragraph>{strings.monographPassDesc()}</Paragraph>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
|
||||
@@ -282,11 +279,10 @@ const PublishNoteSheet = ({
|
||||
flexShrink: 1
|
||||
}}
|
||||
>
|
||||
<Heading size={SIZE.md}>Self destruct</Heading>
|
||||
<Paragraph>
|
||||
Published note link will be automatically deleted once it is
|
||||
viewed by someone.
|
||||
</Paragraph>
|
||||
<Heading size={SIZE.md}>
|
||||
{strings.monographSelfDestructHeading()}
|
||||
</Heading>
|
||||
<Paragraph>{strings.monographSelfDestructDesc()}</Paragraph>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
|
||||
@@ -324,7 +320,7 @@ const PublishNoteSheet = ({
|
||||
onPress={deletePublishedNote}
|
||||
fontSize={SIZE.md}
|
||||
type="error"
|
||||
title="Unpublish"
|
||||
title={strings.unpublish()}
|
||||
style={{
|
||||
width: "49%"
|
||||
}}
|
||||
@@ -340,7 +336,7 @@ const PublishNoteSheet = ({
|
||||
borderRadius: isPublished ? 5 : 100
|
||||
}}
|
||||
type="accent"
|
||||
title={isPublished ? "Update" : "Publish"}
|
||||
title={isPublished ? strings.update() : strings.publish()}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
@@ -365,7 +361,7 @@ const PublishNoteSheet = ({
|
||||
}
|
||||
}}
|
||||
>
|
||||
Learn more about Notesnook Monograph
|
||||
{strings.monographLearnMore()}
|
||||
</Paragraph>
|
||||
</View>
|
||||
);
|
||||
|
||||
@@ -33,6 +33,7 @@ import Seperator from "../../ui/seperator";
|
||||
import SheetWrapper from "../../ui/sheet";
|
||||
import Heading from "../../ui/typography/heading";
|
||||
import Paragraph from "../../ui/typography/paragraph";
|
||||
import { strings } from "@notesnook/intl";
|
||||
const RateAppSheet = () => {
|
||||
const [visible, setVisible] = useState(false);
|
||||
const actionSheetRef = useRef();
|
||||
@@ -85,11 +86,8 @@ const RateAppSheet = () => {
|
||||
paddingHorizontal: 12
|
||||
}}
|
||||
>
|
||||
<Heading>Do you enjoy using Notesnook?</Heading>
|
||||
<Paragraph size={SIZE.md}>
|
||||
It took us a year to bring Notesnook to life. Share your experience
|
||||
and suggestions to help us improve it.
|
||||
</Paragraph>
|
||||
<Heading>{strings.rateAppHeading()}</Heading>
|
||||
<Paragraph size={SIZE.md}>{strings.rateAppDesc()}</Paragraph>
|
||||
|
||||
<Seperator half />
|
||||
<Button
|
||||
@@ -97,7 +95,7 @@ const RateAppSheet = () => {
|
||||
fontSize={SIZE.md}
|
||||
width="100%"
|
||||
type="accent"
|
||||
title="Rate now (It takes only a second)"
|
||||
title={strings.rateApp()}
|
||||
/>
|
||||
<View
|
||||
style={{
|
||||
@@ -120,14 +118,14 @@ const RateAppSheet = () => {
|
||||
fontSize={SIZE.md}
|
||||
type="error"
|
||||
width="48%"
|
||||
title="Never"
|
||||
title={strings.never()}
|
||||
/>
|
||||
<Button
|
||||
onPress={onClose}
|
||||
fontSize={SIZE.md}
|
||||
width="48%"
|
||||
type="secondary"
|
||||
title="Later"
|
||||
title={strings.later()}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
@@ -43,6 +43,7 @@ import { QRCode } from "../../ui/svg/lazy";
|
||||
import Paragraph from "../../ui/typography/paragraph";
|
||||
import RNFetchBlob from "react-native-blob-util";
|
||||
import { sanitizeFilename } from "@notesnook/common";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
class RecoveryKeySheet extends React.Component {
|
||||
constructor(props) {
|
||||
@@ -227,9 +228,8 @@ class RecoveryKeySheet extends React.Component {
|
||||
}}
|
||||
>
|
||||
<DialogHeader
|
||||
title="Save account recovery key"
|
||||
paragraph="If you forget your password, you can recover your
|
||||
data and reset your password only using this recovery key."
|
||||
title={strings.saveRecoveryKey()}
|
||||
paragraph={strings.saveRecoveryKeyDesc()}
|
||||
/>
|
||||
|
||||
<View
|
||||
@@ -290,14 +290,14 @@ class RecoveryKeySheet extends React.Component {
|
||||
});
|
||||
}}
|
||||
icon="content-copy"
|
||||
title="Copy to clipboard"
|
||||
title={strings.copyToClipboard()}
|
||||
width="100%"
|
||||
type="secondaryAccented"
|
||||
fontSize={SIZE.md}
|
||||
/>
|
||||
<Seperator />
|
||||
<Button
|
||||
title="Save QR-Code to gallery"
|
||||
title={strings.saveQRCode()}
|
||||
onPress={this.saveQRCODE}
|
||||
width="100%"
|
||||
type="secondaryAccented"
|
||||
@@ -307,7 +307,7 @@ class RecoveryKeySheet extends React.Component {
|
||||
<Seperator />
|
||||
<Button
|
||||
onPress={this.saveToTextFile}
|
||||
title="Save to text file"
|
||||
title={strings.saveAsText()}
|
||||
width="100%"
|
||||
type="secondaryAccented"
|
||||
icon="text"
|
||||
@@ -317,7 +317,7 @@ class RecoveryKeySheet extends React.Component {
|
||||
|
||||
<Button
|
||||
onPress={this.shareFile}
|
||||
title="Share to Cloud"
|
||||
title={strings.shareToCloud()}
|
||||
width="100%"
|
||||
type="secondaryAccented"
|
||||
icon="cloud"
|
||||
@@ -336,10 +336,10 @@ class RecoveryKeySheet extends React.Component {
|
||||
textAlign: "center"
|
||||
}}
|
||||
>
|
||||
Tap twice to confirm you have saved the recovery key.
|
||||
{strings.recoveryKeySavedConfirmation()}
|
||||
</Paragraph>
|
||||
<Button
|
||||
title="I have saved the key."
|
||||
title={strings.done()}
|
||||
width="100%"
|
||||
type="error"
|
||||
fontSize={SIZE.md}
|
||||
|
||||
@@ -41,6 +41,7 @@ import { Button } from "../../ui/button";
|
||||
import { IconButton } from "../../ui/icon-button";
|
||||
import { Pressable } from "../../ui/pressable";
|
||||
import Paragraph from "../../ui/typography/paragraph";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
export const useExpandedStore = create<{
|
||||
expanded: {
|
||||
@@ -99,7 +100,7 @@ const ListBlockItem = ({
|
||||
{item?.content.length > 200
|
||||
? item?.content.slice(0, 200) + "..."
|
||||
: !item.content || item.content.trim() === ""
|
||||
? "(Empty block)"
|
||||
? strings.linkNoteEmptyBlock()
|
||||
: item.content}
|
||||
</Paragraph>
|
||||
|
||||
@@ -360,7 +361,7 @@ const ListNoteItem = ({
|
||||
<>
|
||||
{linkedBlocks.length === 0 ? (
|
||||
<Paragraph color={colors.secondary.paragraph}>
|
||||
No blocks linked
|
||||
{strings.noBlocksLinked()}
|
||||
</Paragraph>
|
||||
) : (
|
||||
linkedBlocks.map(renderBlock)
|
||||
@@ -370,7 +371,7 @@ const ListNoteItem = ({
|
||||
<>
|
||||
{noteInternalLinks.length === 0 ? (
|
||||
<Paragraph color={colors.secondary.paragraph}>
|
||||
No references found of this note
|
||||
{strings.noReferencesFound()}
|
||||
</Paragraph>
|
||||
) : (
|
||||
noteInternalLinks.map(renderInternalLink)
|
||||
@@ -447,7 +448,7 @@ export const ReferencesList = ({ item, close }: ReferencesListProps) => {
|
||||
>
|
||||
<Button
|
||||
type={"plain"}
|
||||
title="Linked notes"
|
||||
title={strings.linkedNotes()}
|
||||
style={{
|
||||
borderRadius: 0,
|
||||
borderWidth: 0,
|
||||
@@ -462,7 +463,7 @@ export const ReferencesList = ({ item, close }: ReferencesListProps) => {
|
||||
/>
|
||||
<Button
|
||||
type={"plain"}
|
||||
title="Referenced in"
|
||||
title={strings.referencedIn()}
|
||||
style={{
|
||||
width: "50%",
|
||||
borderWidth: 0,
|
||||
@@ -486,9 +487,7 @@ export const ReferencesList = ({ item, close }: ReferencesListProps) => {
|
||||
}}
|
||||
>
|
||||
<Paragraph color={colors.secondary.paragraph}>
|
||||
{tab === 1
|
||||
? "This note is not referenced in other notes."
|
||||
: "This note does not link to other notes."}
|
||||
{tab === 1 ? strings.notReferenced() : strings.notLinked()}
|
||||
</Paragraph>
|
||||
</View>
|
||||
) : (
|
||||
|
||||
@@ -37,6 +37,8 @@ import SheetProvider from "../../sheet-provider";
|
||||
import { Button } from "../../ui/button";
|
||||
import { PressableProps } from "../../ui/pressable";
|
||||
import Paragraph from "../../ui/typography/paragraph";
|
||||
import { isStringLiteralOrJsxExpression } from "typescript";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
type RelationsListProps = {
|
||||
actionSheetRef: RefObject<ActionSheetRef>;
|
||||
@@ -114,9 +116,7 @@ export const RelationsList = ({
|
||||
size={60}
|
||||
color={colors.primary.icon}
|
||||
/>
|
||||
<Paragraph>
|
||||
No {referenceType}s linked to this {item.type}.
|
||||
</Paragraph>
|
||||
<Paragraph>{strings.noLinksFound()}</Paragraph>
|
||||
<Button
|
||||
onPress={() => {
|
||||
onAdd?.();
|
||||
@@ -125,7 +125,7 @@ export const RelationsList = ({
|
||||
// width="100%"
|
||||
type="inverted"
|
||||
icon="plus"
|
||||
title={`Add a ${referenceType}`}
|
||||
title={strings.addItem(referenceType)}
|
||||
/>
|
||||
</View>
|
||||
) : (
|
||||
|
||||
@@ -40,6 +40,7 @@ import {
|
||||
VirtualizedGrouping,
|
||||
Note
|
||||
} from "@notesnook/core";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
type ReminderSheetProps = {
|
||||
actionSheetRef: RefObject<ActionSheetRef>;
|
||||
@@ -134,7 +135,7 @@ export default function ReminderNotify({
|
||||
marginTop: 10
|
||||
}}
|
||||
>
|
||||
<Paragraph size={SIZE.xs}>Remind me in:</Paragraph>
|
||||
<Paragraph size={SIZE.xs}>{strings.remindMeIn()}:</Paragraph>
|
||||
{QuickActions.map((item) => {
|
||||
return (
|
||||
<Button
|
||||
@@ -171,7 +172,7 @@ export default function ReminderNotify({
|
||||
marginBottom: 10
|
||||
}}
|
||||
>
|
||||
REFERENCED IN
|
||||
{strings.referencedIn()}
|
||||
</Paragraph>
|
||||
<List
|
||||
data={references}
|
||||
|
||||
@@ -49,6 +49,7 @@ import { ReminderTime } from "../../ui/reminder-time";
|
||||
import Heading from "../../ui/typography/heading";
|
||||
import Paragraph from "../../ui/typography/paragraph";
|
||||
import { ItemReference, Note, Reminder } from "@notesnook/core";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
type ReminderSheetProps = {
|
||||
actionSheetRef: RefObject<ActionSheetRef>;
|
||||
@@ -234,7 +235,7 @@ export default function ReminderSheet({
|
||||
}}
|
||||
>
|
||||
<Heading size={SIZE.lg}>
|
||||
{reminder ? "Edit reminder" : "New reminder"}
|
||||
{reminder ? strings.editReminder() : strings.newReminder()}
|
||||
</Heading>
|
||||
|
||||
<Dialog context="local" />
|
||||
@@ -286,7 +287,9 @@ export default function ReminderSheet({
|
||||
{Object.keys(ReminderModes).map((mode) => (
|
||||
<Button
|
||||
key={mode}
|
||||
title={mode}
|
||||
title={strings.reminderModes[
|
||||
mode as keyof typeof strings.reminderModes
|
||||
]()}
|
||||
style={{
|
||||
marginRight: 12,
|
||||
borderRadius: 100,
|
||||
@@ -342,9 +345,9 @@ export default function ReminderSheet({
|
||||
{Object.keys(RecurringModes).map((mode) => (
|
||||
<Button
|
||||
key={mode}
|
||||
title={
|
||||
!repeatFrequency || repeatFrequency <= 1 ? mode : mode + "s"
|
||||
}
|
||||
title={strings.recurringModes[
|
||||
mode as keyof typeof strings.recurringModes
|
||||
]()}
|
||||
style={{
|
||||
marginRight: 6,
|
||||
borderRadius: 100
|
||||
@@ -376,10 +379,12 @@ export default function ReminderSheet({
|
||||
: recurringMode === RecurringModes.Week
|
||||
? WeekDays.map((item, index) => (
|
||||
<Button
|
||||
key={WeekDayNames[index as keyof typeof WeekDayNames]}
|
||||
title={WeekDayNames[
|
||||
index as keyof typeof WeekDayNames
|
||||
].slice(0, 1)}
|
||||
key={strings.weekDayNamesShort[
|
||||
index as keyof typeof strings.weekDayNamesShort
|
||||
]()}
|
||||
title={strings.weekDayNamesShort[
|
||||
index as keyof typeof strings.weekDayNamesShort
|
||||
]()}
|
||||
type={
|
||||
selectedDays.indexOf(index) > -1 ? "selected" : "plain"
|
||||
}
|
||||
@@ -478,7 +483,7 @@ export default function ReminderSheet({
|
||||
style={{
|
||||
width: "100%"
|
||||
}}
|
||||
title={date ? date.toLocaleDateString() : "Select date"}
|
||||
title={date ? date.toLocaleDateString() : strings.selectDate()}
|
||||
type={date ? "secondaryAccented" : "secondary"}
|
||||
icon="calendar"
|
||||
fontSize={SIZE.md}
|
||||
@@ -507,27 +512,28 @@ export default function ReminderSheet({
|
||||
<>
|
||||
<Paragraph size={SIZE.xs} color={colors.secondary.paragraph}>
|
||||
{recurringMode === RecurringModes.Daily
|
||||
? "Repeats daily " + `at ${dayjs(date).format("hh:mm A")}.`
|
||||
? strings.reminderRepeatStrings.day(
|
||||
dayjs(date).format("hh:mm A")
|
||||
)
|
||||
: recurringMode === RecurringModes.Year
|
||||
? `The reminder will repeat every year on ${dayjs(
|
||||
date
|
||||
).format("dddd, MMMM D, h:mm A")}.`
|
||||
? strings.reminderRepeatStrings.year(
|
||||
dayjs(date).format("dddd, MMMM D, h:mm A")
|
||||
)
|
||||
: selectedDays.length === 7 &&
|
||||
recurringMode === RecurringModes.Week
|
||||
? `The reminder will repeat daily at ${dayjs(date).format(
|
||||
"hh:mm A"
|
||||
)}.`
|
||||
? strings.reminderRepeatStrings.week.daily(
|
||||
dayjs(date).format("hh:mm A")
|
||||
)
|
||||
: selectedDays.length === 0
|
||||
? recurringMode === RecurringModes.Week
|
||||
? "Select day of the week to repeat the reminder."
|
||||
: "Select nth day of the month to repeat the reminder."
|
||||
: `Repeats every${
|
||||
repeatFrequency > 1 ? " " + repeatFrequency : ""
|
||||
} ${
|
||||
repeatFrequency > 1 ? recurringMode + "s" : recurringMode
|
||||
} on ${getSelectedDaysText(selectedDays)} at ${dayjs(
|
||||
date
|
||||
).format("hh:mm A")}.`}
|
||||
? strings.reminderRepeatStrings[
|
||||
recurringMode as "week" | "month"
|
||||
].selectDays()
|
||||
: strings.reminderRepeatStrings.repeats(
|
||||
repeatFrequency,
|
||||
recurringMode as string,
|
||||
getSelectedDaysText(selectedDays),
|
||||
dayjs(date).format("hh:mm A")
|
||||
)}
|
||||
</Paragraph>
|
||||
</>
|
||||
</View>
|
||||
@@ -556,7 +562,9 @@ export default function ReminderSheet({
|
||||
{Object.keys(ReminderNotificationModes).map((mode) => (
|
||||
<Button
|
||||
key={mode}
|
||||
title={mode}
|
||||
title={strings.reminderNotificationModes[
|
||||
mode as keyof typeof strings.reminderNotificationModes
|
||||
]()}
|
||||
style={{
|
||||
marginRight: 12,
|
||||
borderRadius: 100
|
||||
@@ -593,7 +601,7 @@ export default function ReminderSheet({
|
||||
</ScrollView>
|
||||
|
||||
<Button
|
||||
title="Save"
|
||||
title={strings.save()}
|
||||
type="accent"
|
||||
height={45}
|
||||
fontSize={SIZE.md}
|
||||
|
||||
@@ -29,6 +29,7 @@ import { SIZE } from "../../../utils/size";
|
||||
import { Button } from "../../ui/button";
|
||||
import Seperator from "../../ui/seperator";
|
||||
import Heading from "../../ui/typography/heading";
|
||||
import { strings } from "@notesnook/intl";
|
||||
const Sort = ({ type, screen }) => {
|
||||
const isTopicSheet = screen === "TopicSheet";
|
||||
const { colors } = useThemeColors();
|
||||
@@ -80,7 +81,7 @@ const Sort = ({ type, screen }) => {
|
||||
alignSelf: "center"
|
||||
}}
|
||||
>
|
||||
Sort by
|
||||
{strings.sortBy()}
|
||||
</Heading>
|
||||
|
||||
<Button
|
||||
@@ -88,16 +89,16 @@ const Sort = ({ type, screen }) => {
|
||||
groupOptions?.sortDirection === "asc"
|
||||
? groupOptions?.groupBy === "abc" ||
|
||||
groupOptions?.sortBy === "title"
|
||||
? "A - Z"
|
||||
? strings.aToZ()
|
||||
: groupOptions?.sortBy === "dueDate"
|
||||
? "Earliest first"
|
||||
: "Old - New"
|
||||
? strings.earliestFirst()
|
||||
: strings.oldNew()
|
||||
: groupOptions?.groupBy === "abc" ||
|
||||
groupOptions?.sortBy === "title"
|
||||
? "Z - A"
|
||||
? strings.zToA()
|
||||
: groupOptions?.sortBy === "dueDate"
|
||||
? "Latest first"
|
||||
: "New - Old"
|
||||
? strings.latestFirst()
|
||||
: strings.newOld()
|
||||
}
|
||||
icon={
|
||||
groupOptions?.sortDirection === "asc"
|
||||
@@ -137,7 +138,7 @@ const Sort = ({ type, screen }) => {
|
||||
{groupOptions?.groupBy === "abc" ? (
|
||||
<Button
|
||||
type="secondary"
|
||||
title="Title"
|
||||
title={strings.title()}
|
||||
height={40}
|
||||
iconPosition="left"
|
||||
icon={"check"}
|
||||
@@ -155,7 +156,7 @@ const Sort = ({ type, screen }) => {
|
||||
<Button
|
||||
key={item}
|
||||
type={groupOptions?.sortBy === item ? "selected" : "plain"}
|
||||
title={SORT[item]}
|
||||
title={strings.sortByStrings[item]()}
|
||||
height={40}
|
||||
iconPosition="left"
|
||||
icon={groupOptions?.sortBy === item ? "check" : null}
|
||||
@@ -195,7 +196,7 @@ const Sort = ({ type, screen }) => {
|
||||
}}
|
||||
size={SIZE.lg}
|
||||
>
|
||||
Group by
|
||||
{strings.groupBy()}
|
||||
</Heading>
|
||||
|
||||
<Seperator />
|
||||
@@ -236,9 +237,7 @@ const Sort = ({ type, screen }) => {
|
||||
}}
|
||||
height={40}
|
||||
icon={groupOptions?.groupBy === GROUP[item] ? "check" : null}
|
||||
title={
|
||||
item.slice(0, 1).toUpperCase() + item.slice(1, item.length)
|
||||
}
|
||||
title={strings.groupByStrings[item]()}
|
||||
style={{
|
||||
paddingHorizontal: 8,
|
||||
marginBottom: 10,
|
||||
|
||||
@@ -30,6 +30,7 @@ import {
|
||||
editorState
|
||||
} from "../../../screens/editor/tiptap/utils";
|
||||
import { FlatList } from "react-native-actions-sheet";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
type TableOfContentsItem = {
|
||||
level: number;
|
||||
@@ -87,7 +88,7 @@ const TableOfContentsItem: React.FC<{
|
||||
}
|
||||
size={SIZE.md}
|
||||
>
|
||||
{item?.title || "New note"}
|
||||
{item?.title || strings.newNote()}
|
||||
</Paragraph>
|
||||
</View>
|
||||
</Pressable>
|
||||
@@ -111,7 +112,7 @@ const TableOfContents = ({ toc, close }: TableOfContentsProps) => {
|
||||
alignItems: "center"
|
||||
}}
|
||||
>
|
||||
<Heading size={SIZE.lg}>Table of contents</Heading>
|
||||
<Heading size={SIZE.lg}>{strings.toc()}</Heading>
|
||||
</View>
|
||||
|
||||
<FlatList
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -37,6 +37,7 @@ import { useSideBarDraggingStore } from "./dragging-store";
|
||||
import { MenuItem } from "./menu-item";
|
||||
import { PinnedSection } from "./pinned-section";
|
||||
import { UserStatus } from "./user-status";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
export const SideMenu = React.memo(
|
||||
function SideMenu() {
|
||||
@@ -153,7 +154,7 @@ export const SideMenu = React.memo(
|
||||
width: "100%"
|
||||
}}
|
||||
icon="close"
|
||||
title="Tap to stop reordering"
|
||||
title={strings.stopReordering()}
|
||||
onPress={() => {
|
||||
useSideBarDraggingStore.setState({
|
||||
dragging: false
|
||||
|
||||
@@ -29,6 +29,7 @@ import { Button } from "../ui/button";
|
||||
import { Pressable } from "../ui/pressable";
|
||||
import Heading from "../ui/typography/heading";
|
||||
import Paragraph from "../ui/typography/paragraph";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
function _MenuItem({
|
||||
item,
|
||||
@@ -129,7 +130,7 @@ function _MenuItem({
|
||||
}}
|
||||
>
|
||||
<Paragraph color={primaryColors.accentForeground} size={SIZE.xxs}>
|
||||
BETA
|
||||
{strings.beta()}
|
||||
</Paragraph>
|
||||
</View>
|
||||
) : null}
|
||||
|
||||
@@ -38,6 +38,7 @@ import Seperator from "../ui/seperator";
|
||||
import SheetWrapper from "../ui/sheet";
|
||||
import Heading from "../ui/typography/heading";
|
||||
import Paragraph from "../ui/typography/paragraph";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
export const PinnedSection = React.memo(
|
||||
function PinnedSection() {
|
||||
@@ -100,7 +101,7 @@ export const PinnedSection = React.memo(
|
||||
<Notice
|
||||
size="small"
|
||||
type="information"
|
||||
text="Add shortcuts for notebooks and tags here."
|
||||
text={strings.sideMenuNotice()}
|
||||
style={{
|
||||
marginHorizontal: 12
|
||||
}}
|
||||
@@ -152,7 +153,7 @@ export const PinItem = React.memo(
|
||||
>
|
||||
<Seperator />
|
||||
<Button
|
||||
title="Remove Shortcut"
|
||||
title={strings.removeShortcut()}
|
||||
type="error"
|
||||
onPress={async () => {
|
||||
await db.shortcuts.remove(item.id);
|
||||
|
||||
@@ -36,6 +36,7 @@ import { IconButton } from "../ui/icon-button";
|
||||
import { Pressable } from "../ui/pressable";
|
||||
import { TimeSince } from "../ui/time-since";
|
||||
import Paragraph from "../ui/typography/paragraph";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
export const UserStatus = () => {
|
||||
const { colors, isDark } = useThemeColors();
|
||||
@@ -116,7 +117,7 @@ export const UserStatus = () => {
|
||||
color={colors.primary.heading}
|
||||
>
|
||||
{!user || !userProfile?.fullName
|
||||
? "Settings"
|
||||
? strings.settings()
|
||||
: userProfile.fullName}
|
||||
</Paragraph>
|
||||
|
||||
@@ -128,14 +129,16 @@ export const UserStatus = () => {
|
||||
color={colors.secondary.heading}
|
||||
>
|
||||
{!user ? (
|
||||
"Not logged in"
|
||||
strings.notLoggedIn()
|
||||
) : lastSynced && lastSynced !== "Never" ? (
|
||||
<>
|
||||
{syncing
|
||||
? `Syncing ${progress ? `(${progress.current})` : ""}`
|
||||
? `${strings.syncing()} ${
|
||||
progress ? `(${progress.current})` : ""
|
||||
}`
|
||||
: lastSyncStatus === SyncStatus.Failed
|
||||
? "Sync failed"
|
||||
: "Synced"}{" "}
|
||||
? strings.syncFailed()
|
||||
: strings.synced()}{" "}
|
||||
{!syncing ? (
|
||||
<TimeSince
|
||||
style={{
|
||||
@@ -145,10 +148,10 @@ export const UserStatus = () => {
|
||||
time={lastSynced}
|
||||
/>
|
||||
) : null}
|
||||
{isOffline ? " (offline)" : ""}
|
||||
{isOffline ? ` (${strings.offline()})` : ""}
|
||||
</>
|
||||
) : (
|
||||
"never"
|
||||
strings.never()
|
||||
)}{" "}
|
||||
<Icon
|
||||
name="checkbox-blank-circle"
|
||||
|
||||
@@ -28,6 +28,7 @@ import { SIZE } from "../../utils/size";
|
||||
import { Button } from "../ui/button";
|
||||
import Seperator from "../ui/seperator";
|
||||
import Paragraph from "../ui/typography/paragraph";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
export const Tip = ({
|
||||
tip,
|
||||
@@ -67,7 +68,7 @@ export const Tip = ({
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
title="TIP"
|
||||
title={strings.tip()}
|
||||
icon="information"
|
||||
fontSize={SIZE.xs}
|
||||
iconSize={SIZE.xs}
|
||||
@@ -87,7 +88,7 @@ export const Tip = ({
|
||||
|
||||
{neverShowAgain && (
|
||||
<Button
|
||||
title="Never show again"
|
||||
title={strings.neverShowAgain()}
|
||||
type="secondary"
|
||||
icon="close"
|
||||
fontSize={SIZE.xs}
|
||||
|
||||
@@ -29,6 +29,7 @@ import { Button } from "../ui/button";
|
||||
import Heading from "../ui/typography/heading";
|
||||
import Paragraph from "../ui/typography/paragraph";
|
||||
import walkthroughs, { TStep } from "./walkthroughs";
|
||||
import { strings } from "@notesnook/intl";
|
||||
export const Walkthrough = ({
|
||||
steps,
|
||||
canSkip = true
|
||||
@@ -122,7 +123,7 @@ export const Walkthrough = ({
|
||||
eSendEvent(eCloseSheet);
|
||||
}}
|
||||
type="plain"
|
||||
title="Skip introduction"
|
||||
title={strings.skipIntroduction()}
|
||||
/>
|
||||
) : null}
|
||||
</View>
|
||||
|
||||
@@ -41,6 +41,7 @@ import Heading from "../ui/typography/heading";
|
||||
import Paragraph from "../ui/typography/paragraph";
|
||||
import { useThemeColors } from "@notesnook/theme";
|
||||
import { getContainerBorder } from "../../utils/colors";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
export type TStep = {
|
||||
text?: string;
|
||||
@@ -109,7 +110,8 @@ const NotebookWelcome = () => {
|
||||
size={SIZE.xs}
|
||||
color={colors.secondary.paragraph}
|
||||
>
|
||||
Notebook - {data?.count} notes
|
||||
{strings.dataTypesCamelCase.notebook()} - {data?.count}{" "}
|
||||
{strings.dataTypesPlural.note()}
|
||||
</Paragraph>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
@@ -41,7 +41,10 @@
|
||||
"@trpc/react-query": "10.45.2",
|
||||
"@trpc/server": "10.45.2",
|
||||
"@streetwriters/kysely": "^0.27.4",
|
||||
"pathe": "1.1.2"
|
||||
"pathe": "1.1.2",
|
||||
"react-native-format-currency": "0.0.5",
|
||||
"@lingui/react": "4.11.2",
|
||||
"@lingui/core": "4.11.2"
|
||||
},
|
||||
"sideEffects": false
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ import { eClearEditor } from "../../utils/events";
|
||||
import { SIZE } from "../../utils/size";
|
||||
import { useEditor } from "./tiptap/use-editor";
|
||||
import { editorState } from "./tiptap/utils";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
const EditorOverlay = ({
|
||||
editorId = "",
|
||||
@@ -220,7 +221,7 @@ const EditorOverlay = ({
|
||||
}}
|
||||
>
|
||||
<Paragraph color={colors.secondary.paragraph} size={13}>
|
||||
Add a tag
|
||||
{strings.addItem("tag")}
|
||||
</Paragraph>
|
||||
<IconButton
|
||||
size={20}
|
||||
@@ -325,7 +326,7 @@ const EditorOverlay = ({
|
||||
editor.setLoading(true);
|
||||
setTimeout(() => editor.setLoading(false), 10);
|
||||
}}
|
||||
title="Taking too long? Reload editor"
|
||||
title={strings.reloadEditor()}
|
||||
/>
|
||||
<Paragraph
|
||||
textBreakStrategy="balanced"
|
||||
@@ -336,8 +337,7 @@ const EditorOverlay = ({
|
||||
marginTop: 5
|
||||
}}
|
||||
>
|
||||
If the editor fails to load even after reloading. Try restarting
|
||||
the app.
|
||||
{strings.editorFailedToLoad()}
|
||||
</Paragraph>
|
||||
</>
|
||||
) : null}
|
||||
|
||||
@@ -52,6 +52,7 @@ import { eCloseSheet } from "../../utils/events";
|
||||
import { SIZE } from "../../utils/size";
|
||||
import { sleep } from "../../utils/time";
|
||||
import { sanitizeFilename } from "@notesnook/common";
|
||||
import { strings } from "@notesnook/intl";
|
||||
const mfaMethods: MFAMethod[] = [
|
||||
{
|
||||
id: "app",
|
||||
@@ -105,8 +106,8 @@ export const MFAMethodsPickerStep = ({ recovery, onSuccess }: MFAStepProps) => {
|
||||
return (
|
||||
<>
|
||||
<DialogHeader
|
||||
title="Two-factor authentication"
|
||||
paragraph="Protect your notes by enabling 2 factor authentication"
|
||||
title={strings.twoFactorAuth()}
|
||||
paragraph={strings.twoFactorAuthDesc()}
|
||||
padding={12}
|
||||
/>
|
||||
<Seperator />
|
||||
@@ -291,7 +292,9 @@ export const MFASetup = ({
|
||||
height: 50
|
||||
}}
|
||||
/>
|
||||
<Paragraph>Getting information.. please wait</Paragraph>
|
||||
<Paragraph>
|
||||
{strings.gettingInformation()}... {strings.pleaseWait()}
|
||||
</Paragraph>
|
||||
</View>
|
||||
) : (
|
||||
<>
|
||||
@@ -327,11 +330,11 @@ export const MFASetup = ({
|
||||
sending
|
||||
? null
|
||||
: method.id === "app"
|
||||
? "Copy"
|
||||
? strings.copy()
|
||||
: `${
|
||||
seconds
|
||||
? `Resend code in (${seconds})`
|
||||
: "Send code"
|
||||
? strings.resendCode(seconds)
|
||||
: strings.sendCode()
|
||||
}`
|
||||
}
|
||||
/>
|
||||
@@ -339,7 +342,7 @@ export const MFASetup = ({
|
||||
}
|
||||
/>
|
||||
|
||||
<Heading size={SIZE.md}>Enter the 6-digit code</Heading>
|
||||
<Heading size={SIZE.md}>{strings.enterSixDigitCode()}</Heading>
|
||||
<Paragraph>{codeHelpText[method?.id]}</Paragraph>
|
||||
<Seperator />
|
||||
<Input
|
||||
@@ -364,7 +367,7 @@ export const MFASetup = ({
|
||||
/>
|
||||
<Seperator />
|
||||
<Button
|
||||
title={enabling ? null : "Next"}
|
||||
title={enabling ? null : strings.next()}
|
||||
type="accent"
|
||||
width={250}
|
||||
onPress={onNext}
|
||||
@@ -376,7 +379,7 @@ export const MFASetup = ({
|
||||
/>
|
||||
|
||||
<Button
|
||||
title="Select a different 2FA method"
|
||||
title="Change 2FA method"
|
||||
type="plain"
|
||||
height={25}
|
||||
onPress={() => {
|
||||
@@ -423,14 +426,8 @@ export const MFARecoveryCodes = ({
|
||||
<View>
|
||||
<DialogHeader
|
||||
centered={true}
|
||||
title="Save your recovery codes"
|
||||
paragraph={`If you lose access to your ${
|
||||
method?.id === "email"
|
||||
? "email"
|
||||
: method?.id === "sms"
|
||||
? "phone"
|
||||
: "auth app"
|
||||
}, you can login to Notesnook using your recovery codes. Each code can only be used once.`}
|
||||
title={strings.saveRecoveryCodes()}
|
||||
paragraph={strings.saveRecoveryCodesDesc()}
|
||||
padding={12}
|
||||
/>
|
||||
<Seperator />
|
||||
@@ -450,7 +447,9 @@ export const MFARecoveryCodes = ({
|
||||
height: 50
|
||||
}}
|
||||
/>
|
||||
<Paragraph>Getting recovery codes.. please wait</Paragraph>
|
||||
<Paragraph>
|
||||
{strings.gettingRecoveryCodes()}... {strings.pleaseWait()}
|
||||
</Paragraph>
|
||||
</View>
|
||||
) : (
|
||||
<>
|
||||
@@ -483,7 +482,7 @@ export const MFARecoveryCodes = ({
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
title="Copy codes"
|
||||
title={strings.copyCodes()}
|
||||
fontSize={SIZE.md}
|
||||
onPress={() => {
|
||||
const codeString = codes.join("\n");
|
||||
@@ -500,7 +499,7 @@ export const MFARecoveryCodes = ({
|
||||
/>
|
||||
|
||||
<Button
|
||||
title="Save to file"
|
||||
title={strings.saveToFile()}
|
||||
fontSize={SIZE.md}
|
||||
onPress={async () => {
|
||||
try {
|
||||
@@ -542,7 +541,7 @@ export const MFARecoveryCodes = ({
|
||||
</View>
|
||||
|
||||
<Button
|
||||
title={isSetup ? "Next" : "Done"}
|
||||
title={isSetup ? strings.next() : strings.done()}
|
||||
type="accent"
|
||||
width={250}
|
||||
onPress={() => {
|
||||
@@ -593,16 +592,16 @@ const MFASuccess = ({ recovery }: MFAStepProps) => {
|
||||
centered={true}
|
||||
title={
|
||||
recovery
|
||||
? "Fallback method for 2FA enabled"
|
||||
: "Two-factor authentication enabled!"
|
||||
? strings.fallbackMethodEnabled()
|
||||
: strings.twoFactorAuthEnabled()
|
||||
}
|
||||
paragraph="Your account is now 100% secure against unauthorized logins."
|
||||
paragraph={strings.accountIsSecure()}
|
||||
padding={12}
|
||||
/>
|
||||
<Seperator />
|
||||
|
||||
<Button
|
||||
title="Done"
|
||||
title={strings.done()}
|
||||
type="accent"
|
||||
width={250}
|
||||
onPress={() => {
|
||||
@@ -616,7 +615,7 @@ const MFASuccess = ({ recovery }: MFAStepProps) => {
|
||||
|
||||
{!recovery ? (
|
||||
<Button
|
||||
title="Setup secondary 2FA method"
|
||||
title={strings.secondary2faMethod()}
|
||||
type="plain"
|
||||
height={25}
|
||||
onPress={() => {
|
||||
|
||||
@@ -32,6 +32,7 @@ import SettingsService from "../../services/settings";
|
||||
import { useSettingStore } from "../../stores/use-setting-store";
|
||||
import { useUserStore } from "../../stores/use-user-store";
|
||||
import { SIZE } from "../../utils/size";
|
||||
import { strings } from "@notesnook/intl";
|
||||
const AppLock = () => {
|
||||
const { colors } = useThemeColors();
|
||||
const appLockMode = useSettingStore((state) => state.settings.appLockMode);
|
||||
@@ -97,10 +98,8 @@ const AppLock = () => {
|
||||
width: "100%"
|
||||
}}
|
||||
>
|
||||
<Heading>Protect your notes</Heading>
|
||||
<Paragraph size={SIZE.md}>
|
||||
Choose how you want to secure your notes locally.
|
||||
</Paragraph>
|
||||
<Heading>{strings.protectNotes()}</Heading>
|
||||
<Paragraph size={SIZE.md}>{strings.protectNotesDesc()}</Paragraph>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ import { ToastManager } from "../../services/event-manager";
|
||||
import { useThemeColors } from "@notesnook/theme";
|
||||
import { hexToRGBA } from "../../utils/colors";
|
||||
import { sanitizeFilename } from "@notesnook/common";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
export default function DebugLogs() {
|
||||
const { colors } = useThemeColors();
|
||||
@@ -213,10 +214,7 @@ export default function DebugLogs() {
|
||||
padding: 12
|
||||
}}
|
||||
>
|
||||
<Notice
|
||||
text="All logs are local only and are not sent to any server. You can share the logs from here with us if you face an issue to help us find the root cause."
|
||||
type="information"
|
||||
/>
|
||||
<Notice text={strings.debugNotice()} type="information" />
|
||||
</View>
|
||||
|
||||
{currentLog && (
|
||||
|
||||
@@ -29,6 +29,7 @@ import { useThemeColors } from "@notesnook/theme";
|
||||
import { SIZE } from "../../../utils/size";
|
||||
import { Group } from "./group";
|
||||
import { DragState, useDragState } from "./state";
|
||||
import { strings } from "@notesnook/intl";
|
||||
export const ConfigureToolbar = () => {
|
||||
const data = useDragState((state) => state.data);
|
||||
const preset = useDragState((state) => state.preset);
|
||||
@@ -52,10 +53,7 @@ export const ConfigureToolbar = () => {
|
||||
paddingVertical: 12
|
||||
}}
|
||||
>
|
||||
<Notice
|
||||
text="Curate the toolbar that fits your needs and matches your personality."
|
||||
type="information"
|
||||
/>
|
||||
<Notice text={strings.configureToolbarNotice()} type="information" />
|
||||
|
||||
<Paragraph
|
||||
style={{
|
||||
@@ -64,7 +62,7 @@ export const ConfigureToolbar = () => {
|
||||
size={SIZE.xs}
|
||||
color={colors.secondary.paragraph}
|
||||
>
|
||||
PRESETS
|
||||
{strings.presets()}
|
||||
</Paragraph>
|
||||
|
||||
<View
|
||||
@@ -128,7 +126,7 @@ export const ConfigureToolbar = () => {
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
title="Create a group"
|
||||
title={strings.createAGroup()}
|
||||
type="secondaryAccented"
|
||||
icon="plus"
|
||||
style={{
|
||||
|
||||
@@ -34,6 +34,7 @@ import ToolSheet from "./tool-sheet";
|
||||
import Icon from "react-native-vector-icons/MaterialCommunityIcons";
|
||||
import type { ToolId } from "@notesnook/editor";
|
||||
import PremiumService from "../../../services/premium";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
export const Group = ({
|
||||
item,
|
||||
@@ -203,7 +204,7 @@ export const Group = ({
|
||||
color={colors.secondary.paragraph}
|
||||
size={SIZE.xs}
|
||||
>
|
||||
GROUP
|
||||
{strings.group()}
|
||||
</Paragraph>
|
||||
</View>
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ import {
|
||||
getUngroupedTools
|
||||
} from "./toolbar-definition";
|
||||
import { ActionSheetRef, ScrollView } from "react-native-actions-sheet";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
export default function ToolSheet({
|
||||
group,
|
||||
@@ -124,7 +125,7 @@ export default function ToolSheet({
|
||||
}}
|
||||
color={colors.secondary.paragraph}
|
||||
>
|
||||
You have grouped all the tools.
|
||||
{strings.groupedAllTools()}
|
||||
</Paragraph>
|
||||
) : (
|
||||
ungrouped.map(renderTool)
|
||||
|
||||
@@ -36,6 +36,7 @@ import ToolSheet from "./tool-sheet";
|
||||
import Icon from "react-native-vector-icons/MaterialCommunityIcons";
|
||||
import type { ToolId } from "@notesnook/editor";
|
||||
import PremiumService from "../../../services/premium";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
export const Tool = ({
|
||||
item,
|
||||
@@ -221,7 +222,7 @@ export const Tool = ({
|
||||
}
|
||||
size={isSubgroup ? SIZE.xs : SIZE.sm - 1}
|
||||
>
|
||||
{isSubgroup ? "COLLAPSED" : tool?.title}
|
||||
{isSubgroup ? strings.collapsed() : tool?.title}
|
||||
</Paragraph>
|
||||
</View>
|
||||
|
||||
|
||||
@@ -29,6 +29,8 @@ import { SectionGroup } from "./section-group";
|
||||
import { settingsGroups } from "./settings-data";
|
||||
import { RouteParams, SettingSection } from "./types";
|
||||
import SettingsUserSection from "./user-section";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
const keyExtractor = (item: SettingSection) => item.id;
|
||||
|
||||
const Home = ({
|
||||
|
||||
@@ -63,7 +63,7 @@ export const Licenses = () => {
|
||||
</Paragraph>
|
||||
</Pressable>
|
||||
),
|
||||
[colors.secondary.background]
|
||||
[colors.primary.border]
|
||||
);
|
||||
return (
|
||||
<FlatList
|
||||
|
||||
@@ -35,6 +35,7 @@ import {
|
||||
import { eOpenPremiumDialog } from "../../utils/events";
|
||||
import { SIZE } from "../../utils/size";
|
||||
import Config from "react-native-config";
|
||||
import { strings } from "@notesnook/intl";
|
||||
export const Subscription = () => {
|
||||
const user = useUserStore((state) => state.user);
|
||||
const monthlyPlan = usePricing("monthly");
|
||||
@@ -46,7 +47,7 @@ export const Subscription = () => {
|
||||
SUBSCRIPTION_STATUS.PREMIUM_CANCELLED === user?.subscription?.type;
|
||||
|
||||
const subscriptionProviderInfo =
|
||||
SUBSCRIPTION_PROVIDER[user?.subscription?.provider];
|
||||
strings.subscriptionProviderInfo[user?.subscription?.provider];
|
||||
|
||||
const manageSubscription = () => {
|
||||
if (!user?.isEmailConfirmed) {
|
||||
@@ -110,17 +111,17 @@ export const Subscription = () => {
|
||||
onPress={manageSubscription}
|
||||
title={
|
||||
!user?.isEmailConfirmed
|
||||
? "Confirm your email"
|
||||
? strings.confirmEmail()
|
||||
: user.subscription?.provider === 3 && hasCancelledPremium
|
||||
? "Manage subscription from desktop app"
|
||||
? strings.manageSubDesktop()
|
||||
: hasCancelledPremium &&
|
||||
Platform.OS === "android" &&
|
||||
Config.GITHUB_RELEASE !== "true"
|
||||
? "Resubscribe from Google Playstore"
|
||||
? strings.resubFromPlaystore()
|
||||
: user.subscription?.type ===
|
||||
SUBSCRIPTION_STATUS.PREMIUM_EXPIRED || hasCancelledPremium
|
||||
? `Resubscribe to Pro (${getPrice() || "$4.49"} / mo)`
|
||||
: `Get Pro (${getPrice() || "$4.49"} / mo)`
|
||||
? `${strings.resubToPro()} (${getPrice() || "$4.49"} / mo)`
|
||||
: `${strings.getPro()} (${getPrice() || "$4.49"} / mo)`
|
||||
}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
@@ -55,6 +55,7 @@ import { MenuItemsList } from "../../utils/menu-items";
|
||||
import { IconButton } from "../../components/ui/icon-button";
|
||||
import { Pressable } from "../../components/ui/pressable";
|
||||
import { getColorLinearShade } from "../../utils/colors";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
const THEME_SERVER_URL = "https://themes-api.notesnook.com";
|
||||
//@ts-ignore
|
||||
@@ -237,7 +238,7 @@ function ThemeSelector() {
|
||||
color={colors.list.heading}
|
||||
size={7}
|
||||
>
|
||||
Notes
|
||||
{strings.dataTypesPluralCamelCase.note()}
|
||||
</Heading>
|
||||
</View>
|
||||
|
||||
@@ -275,7 +276,9 @@ function ThemeSelector() {
|
||||
) : null}
|
||||
|
||||
<Button
|
||||
title={item.colorScheme === "dark" ? "Dark" : "Light"}
|
||||
title={
|
||||
item.colorScheme === "dark" ? strings.dark() : strings.light()
|
||||
}
|
||||
type="secondaryAccented"
|
||||
height={25}
|
||||
buttonType={{
|
||||
@@ -299,11 +302,8 @@ function ThemeSelector() {
|
||||
<Heading size={SIZE.sm} color={themeColors.primary.heading}>
|
||||
{item.name}
|
||||
</Heading>
|
||||
{/* <Paragraph color={themeColors.primary?.paragraph}>
|
||||
{item.description}
|
||||
</Paragraph> */}
|
||||
<Paragraph size={SIZE.xs} color={themeColors.secondary?.paragraph}>
|
||||
By {item.authors?.[0].name}
|
||||
{strings.by()} {item.authors?.[0].name}
|
||||
</Paragraph>
|
||||
</TouchableOpacity>
|
||||
</>
|
||||
@@ -368,7 +368,7 @@ function ThemeSelector() {
|
||||
type={
|
||||
colorScheme === "" || !colorScheme ? "accent" : "secondary"
|
||||
}
|
||||
title="All"
|
||||
title={strings.all()}
|
||||
fontSize={SIZE.xs}
|
||||
onPress={() => {
|
||||
setColorScheme("");
|
||||
@@ -378,7 +378,7 @@ function ThemeSelector() {
|
||||
style={{ borderRadius: 100, minWidth: 60 }}
|
||||
height={30}
|
||||
type={colorScheme === "dark" ? "accent" : "secondary"}
|
||||
title="Dark"
|
||||
title={strings.dark()}
|
||||
fontSize={SIZE.xs}
|
||||
onPress={() => {
|
||||
setColorScheme("dark");
|
||||
@@ -389,7 +389,7 @@ function ThemeSelector() {
|
||||
height={30}
|
||||
fontSize={SIZE.xs}
|
||||
type={colorScheme === "light" ? "accent" : "secondary"}
|
||||
title="Light"
|
||||
title={strings.light()}
|
||||
onPress={() => {
|
||||
setColorScheme("light");
|
||||
}}
|
||||
@@ -397,7 +397,7 @@ function ThemeSelector() {
|
||||
</View>
|
||||
|
||||
<Button
|
||||
title="Load from file"
|
||||
title={strings.loadFromFile()}
|
||||
style={{ borderRadius: 100, minWidth: 60 }}
|
||||
height={30}
|
||||
type={"secondaryAccented"}
|
||||
@@ -446,10 +446,10 @@ function ThemeSelector() {
|
||||
<ActivityIndicator color={colors.primary.accent} />
|
||||
) : searchQuery ? (
|
||||
<Paragraph color={colors.secondary.paragraph}>
|
||||
No results found for {searchQuery}
|
||||
{strings.noResultsForSearch(searchQuery)}
|
||||
</Paragraph>
|
||||
) : (
|
||||
<Paragraph>No themes found.</Paragraph>
|
||||
<Paragraph>{strings.noThemesFound()}.</Paragraph>
|
||||
)}
|
||||
</View>
|
||||
}
|
||||
@@ -464,7 +464,7 @@ function ThemeSelector() {
|
||||
}}
|
||||
>
|
||||
<Paragraph color={colors.error.paragraph}>
|
||||
Error loading themes. {themes.error.message}.
|
||||
{strings.errorLoadingThemes()}. {themes.error.message}.
|
||||
</Paragraph>
|
||||
</View>
|
||||
) : null
|
||||
@@ -682,7 +682,7 @@ const ThemeSetter = ({
|
||||
color={colors?.list.heading}
|
||||
size={7}
|
||||
>
|
||||
Notes
|
||||
{strings.dataTypesPluralCamelCase.note()}
|
||||
</Heading>
|
||||
</View>
|
||||
|
||||
@@ -703,7 +703,7 @@ const ThemeSetter = ({
|
||||
size={SIZE.xs}
|
||||
color={themeColors.colors.secondary.paragraph}
|
||||
>
|
||||
By {theme.authors?.[0]?.name}
|
||||
{strings.by()} {theme.authors?.[0]?.name}
|
||||
</Paragraph>
|
||||
<View
|
||||
style={{
|
||||
@@ -716,7 +716,7 @@ const ThemeSetter = ({
|
||||
size={SIZE.xs}
|
||||
color={themeColors.colors.secondary.paragraph}
|
||||
>
|
||||
Version {theme.version}
|
||||
${strings.version()} {theme.version}
|
||||
</Paragraph>
|
||||
|
||||
<Paragraph
|
||||
@@ -739,7 +739,7 @@ const ThemeSetter = ({
|
||||
Linking.openURL(theme.homepage as string);
|
||||
}}
|
||||
>
|
||||
Visit homepage
|
||||
{strings.visitHomePage()}
|
||||
</Paragraph>
|
||||
</View>
|
||||
) : null}
|
||||
@@ -756,10 +756,10 @@ const ThemeSetter = ({
|
||||
>
|
||||
<Heading color={colors.accentForeground} size={SIZE.md}>
|
||||
{darkTheme.id === theme.id
|
||||
? "Applied as dark theme"
|
||||
: "Applied as light theme"}
|
||||
? strings.appliedDark()
|
||||
: strings.appliedLight()}
|
||||
</Heading>
|
||||
<Paragraph size={SIZE.xs}>(Tap to apply again)</Paragraph>
|
||||
<Paragraph size={SIZE.xs}>({strings.tapToApplyAgain()})</Paragraph>
|
||||
</Pressable>
|
||||
) : (
|
||||
<Button
|
||||
@@ -770,8 +770,8 @@ const ThemeSetter = ({
|
||||
onPress={applyTheme}
|
||||
title={
|
||||
theme.colorScheme === "dark"
|
||||
? "Set as dark theme"
|
||||
: "Set as light theme"
|
||||
? strings.setAsDarkTheme()
|
||||
: strings.setAsLightTheme()
|
||||
}
|
||||
type="secondaryAccented"
|
||||
/>
|
||||
|
||||
@@ -24,6 +24,7 @@ import { TextInput } from "react-native";
|
||||
import Paragraph from "../../components/ui/typography/paragraph";
|
||||
import { useThemeColors } from "@notesnook/theme";
|
||||
import { SIZE } from "../../utils/size";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
export const TitleFormat = () => {
|
||||
const [titleFormat] = useState(db.settings.getTitleFormat());
|
||||
@@ -53,14 +54,7 @@ export const TitleFormat = () => {
|
||||
color={colors.secondary.paragraph}
|
||||
size={SIZE.xs}
|
||||
>
|
||||
Use the following key to format the title:{"\n"}
|
||||
{"\n"}
|
||||
$date$: Current date.{"\n"}
|
||||
$time$: Current time.{"\n"}
|
||||
$timestamp$: Full date and time without any spaces or other symbols.
|
||||
(e.g 202305261253).{"\n"}
|
||||
$count$: Number of notes + 1.{"\n"}
|
||||
$headline$: Use starting line of the note as title.{"\n"}
|
||||
{strings.titleFormattingGuide()}
|
||||
</Paragraph>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -35,6 +35,7 @@ import { SyncStatus, useUserStore } from "../../stores/use-user-store";
|
||||
import { SUBSCRIPTION_STATUS_STRINGS } from "../../utils/constants";
|
||||
import { SIZE } from "../../utils/size";
|
||||
import { SectionItem } from "./section-item";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
export const getTimeLeft = (t2) => {
|
||||
let daysRemaining = dayjs(t2).diff(dayjs(), "days");
|
||||
@@ -176,7 +177,7 @@ const SettingsUserSection = ({ item }) => {
|
||||
<Heading color={colors.primary.accent} size={SIZE.sm}>
|
||||
{SUBSCRIPTION_STATUS_STRINGS[
|
||||
user.subscription?.type
|
||||
]?.toUpperCase() || "Basic"}
|
||||
]?.toUpperCase() || strings.basic()}
|
||||
</Heading>
|
||||
) : null}
|
||||
|
||||
@@ -208,7 +209,7 @@ const SettingsUserSection = ({ item }) => {
|
||||
>
|
||||
{userProfile?.fullName
|
||||
? userProfile.fullName + " "
|
||||
: "Set your name "}
|
||||
: strings.setYourName() + " "}
|
||||
<AppIcon name="pencil" size={SIZE.lg} />
|
||||
</Paragraph>
|
||||
|
||||
@@ -225,12 +226,12 @@ const SettingsUserSection = ({ item }) => {
|
||||
color={colors.secondary.heading}
|
||||
>
|
||||
{!user ? (
|
||||
"Not logged in"
|
||||
strings.notLoggedIn()
|
||||
) : lastSynced && lastSynced !== "Never" ? (
|
||||
<>
|
||||
{lastSyncStatus === SyncStatus.Failed
|
||||
? "Sync failed"
|
||||
: "Synced"}{" "}
|
||||
? strings.syncFailed()
|
||||
: strings.synced()}{" "}
|
||||
<TimeSince
|
||||
style={{
|
||||
fontSize: SIZE.xs,
|
||||
@@ -238,10 +239,10 @@ const SettingsUserSection = ({ item }) => {
|
||||
}}
|
||||
time={lastSynced}
|
||||
/>
|
||||
{isOffline ? " (offline)" : ""}
|
||||
{isOffline ? ` (${strings.offline()})` : ""}
|
||||
</>
|
||||
) : (
|
||||
"never"
|
||||
strings.never()
|
||||
)}{" "}
|
||||
<Icon
|
||||
name="checkbox-blank-circle"
|
||||
|
||||
@@ -17,6 +17,7 @@ You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { strings } from "@notesnook/intl";
|
||||
import isEmail from "validator/lib/isEmail";
|
||||
|
||||
export function validateEmail(email) {
|
||||
@@ -28,7 +29,7 @@ export function validateEmail(email) {
|
||||
}
|
||||
|
||||
export const ERRORS_LIST = {
|
||||
SHORT_PASS: "Atleast 8 characters"
|
||||
SHORT_PASS: strings.passTooShort()
|
||||
};
|
||||
|
||||
export function validatePass(password) {
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
|
||||
@@ -1,65 +1,40 @@
|
||||
const env = process.env.BABEL_ENV || process.env.NODE_ENV;
|
||||
const configs = {
|
||||
env: {
|
||||
development: {
|
||||
presets: ['module:@react-native/babel-preset'],
|
||||
plugins: [
|
||||
'@babel/plugin-transform-named-capturing-groups-regex',
|
||||
'react-native-reanimated/plugin',
|
||||
"@babel/plugin-transform-export-namespace-from",
|
||||
],
|
||||
overrides: [
|
||||
{
|
||||
test: '../node_modules/kysely',
|
||||
plugins: [
|
||||
["@babel/plugin-transform-private-methods", { "loose": true }]
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
test: {
|
||||
presets: ['module:@react-native/babel-preset'],
|
||||
plugins: [
|
||||
'@babel/plugin-transform-named-capturing-groups-regex',
|
||||
'react-native-reanimated/plugin',
|
||||
],
|
||||
overrides: [
|
||||
{
|
||||
test: '../node_modules/kysely',
|
||||
plugins: [
|
||||
["@babel/plugin-transform-private-methods", { "loose": true }]
|
||||
]
|
||||
},
|
||||
{
|
||||
test: '../node_modules/jest-runner',
|
||||
plugins: [
|
||||
["@babel/plugin-transform-private-methods", { "loose": true }]
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
},
|
||||
production: {
|
||||
presets: ['module:@react-native/babel-preset'],
|
||||
plugins: [
|
||||
'transform-remove-console',
|
||||
'@babel/plugin-transform-named-capturing-groups-regex',
|
||||
'react-native-reanimated/plugin',
|
||||
"@babel/plugin-transform-export-namespace-from",
|
||||
],
|
||||
overrides: [
|
||||
{
|
||||
test: '../node_modules/kysely',
|
||||
plugins: [
|
||||
["@babel/plugin-transform-private-methods", { "loose": true }]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
};
|
||||
let PROCESS_ENV = process.env.BABEL_ENV || process.env.NODE_ENV;
|
||||
/**
|
||||
* @type {import('@babel/core').ConfigFunction}
|
||||
*/
|
||||
module.exports = function (api, opts) {
|
||||
if (!PROCESS_ENV) PROCESS_ENV = 'production';
|
||||
|
||||
const env = {
|
||||
presets: ['module:metro-react-native-babel-preset'],
|
||||
plugins: [
|
||||
'@babel/plugin-transform-named-capturing-groups-regex',
|
||||
'react-native-reanimated/plugin',
|
||||
"@babel/plugin-transform-export-namespace-from",
|
||||
],
|
||||
overrides: [
|
||||
{
|
||||
test: '../node_modules/kysely',
|
||||
plugins: [
|
||||
["@babel/plugin-transform-private-methods", { "loose": true }]
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
if (env === 'production') {
|
||||
env.plugins.push('transform-remove-console');
|
||||
}
|
||||
|
||||
if (env === 'test') {
|
||||
env.overrides.push({
|
||||
test: '../node_modules/jest-runner',
|
||||
plugins: [
|
||||
["@babel/plugin-transform-private-methods", { "loose": true }]
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
api.cache(true);
|
||||
if (!env) env = 'production';
|
||||
return configs.env[env];
|
||||
return env;
|
||||
};
|
||||
|
||||
@@ -1,8 +1,23 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
import "@azure/core-asynciterator-polyfill";
|
||||
import '@formatjs/intl-locale/polyfill'
|
||||
import '@formatjs/intl-pluralrules/polyfill'
|
||||
|
||||
import '@formatjs/intl-pluralrules/locale-data/en'
|
||||
import '@formatjs/intl-pluralrules/locale-data/cs'
|
||||
import '@formatjs/intl-pluralrules/locale-data/fr'
|
||||
|
||||
import 'react-native-url-polyfill/auto';
|
||||
import "./polyfills/console-time.js"
|
||||
global.Buffer = require('buffer').Buffer;
|
||||
import '../app/common/logger/index';
|
||||
import { DOMParser } from './worker.js';
|
||||
global.DOMParser = DOMParser;
|
||||
import { $en, setI18nGlobal } from "@notesnook/intl";
|
||||
import { i18n } from "@lingui/core";
|
||||
|
||||
i18n.load({
|
||||
en: $en,
|
||||
});
|
||||
i18n.activate("en");
|
||||
setI18nGlobal(i18n);
|
||||
|
||||
27
apps/mobile/native/lingui.config.js
Normal file
27
apps/mobile/native/lingui.config.js
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
This file is part of the Notesnook project (https://notesnook.com/)
|
||||
|
||||
Copyright (C) 2023 Streetwriters (Private) Limited
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @type {import('@lingui/conf').LinguiConfig} */
|
||||
|
||||
module.exports = {
|
||||
locales: ["en", "cs", "fr"],
|
||||
sourceLocale: "en",
|
||||
format: "po",
|
||||
compileNamespace: "ts"
|
||||
};
|
||||
@@ -29,7 +29,6 @@ mergedConfig.resolver = {
|
||||
"react-dom": path.join(__dirname, "../node_modules/react-dom"),
|
||||
"@notesnook": path.join(__dirname, "../../../packages"),
|
||||
"@notifee/react-native": path.join(__dirname, "../node_modules/@ammarahmed/notifee-react-native"),
|
||||
|
||||
},
|
||||
resolveRequest: (context, moduleName, platform) => {
|
||||
if (moduleName === "node:crypto") {
|
||||
@@ -60,7 +59,7 @@ mergedConfig.resolver = {
|
||||
};
|
||||
}
|
||||
return context.resolveRequest(context, moduleName, platform);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = mergedConfig;
|
||||
@@ -71,7 +71,9 @@
|
||||
"@ammarahmed/react-native-background-fetch": "^4.2.2",
|
||||
"react-native-image-crop-picker": "^0.40.2",
|
||||
"react-native-url-polyfill": "^2.0.0",
|
||||
"react-native-screenguard": "^1.0.0"
|
||||
"react-native-screenguard": "^1.0.0",
|
||||
"@formatjs/intl-locale": "4.0.0",
|
||||
"@formatjs/intl-pluralrules": "5.2.14"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.20.0",
|
||||
|
||||
@@ -104,6 +104,7 @@ module.exports = (env) => {
|
||||
"@mdi/js": path.join(__dirname, "../node_modules/@mdi/js/mdi.js"),
|
||||
"katex": path.join(__dirname, "../node_modules/katex"),
|
||||
"tinycolor2": path.join(__dirname, "../node_modules/tinycolor2"),
|
||||
"@lingui/core": path.join(__dirname, "../node_modules/@lingui/core"),
|
||||
},
|
||||
fallback: {
|
||||
"crypto": false,
|
||||
@@ -177,7 +178,7 @@ module.exports = (env) => {
|
||||
plugins: [
|
||||
"react-native-reanimated/plugin",
|
||||
"@babel/plugin-transform-named-capturing-groups-regex",
|
||||
["@babel/plugin-transform-private-methods", { "loose": true }]
|
||||
["@babel/plugin-transform-private-methods", { "loose": true }],
|
||||
]
|
||||
},
|
||||
},
|
||||
@@ -222,6 +223,8 @@ module.exports = (env) => {
|
||||
/node_modules(.*[/\\])+react-native-url-polyfill/,
|
||||
/node_modules(.*[/\\])+diffblazer/,
|
||||
/node_modules(.*[/\\])+react-freeze/,
|
||||
/node_modules(.*[/\\])+@messageformat[/\\]parser/,
|
||||
/node_modules(.*[/\\])+@lingui[/\\]core/,
|
||||
],
|
||||
use: {
|
||||
loader: "babel-loader",
|
||||
@@ -236,6 +239,7 @@ module.exports = (env) => {
|
||||
plugins: [
|
||||
"react-native-reanimated/plugin",
|
||||
"@babel/plugin-transform-named-capturing-groups-regex",
|
||||
"macros"
|
||||
]
|
||||
},
|
||||
},
|
||||
@@ -266,11 +270,13 @@ module.exports = (env) => {
|
||||
? [
|
||||
"module:react-refresh/babel",
|
||||
"react-native-reanimated/plugin",
|
||||
"macros"
|
||||
]
|
||||
: [
|
||||
"react-native-reanimated/plugin",
|
||||
`@babel/plugin-transform-named-capturing-groups-regex`,
|
||||
"transform-remove-console",
|
||||
"macros"
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
4932
apps/mobile/package-lock.json
generated
4932
apps/mobile/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -42,6 +42,7 @@
|
||||
"@notesnook/logger": "file:../../packages/logger",
|
||||
"@notesnook/theme": "file:../../packages/theme",
|
||||
"@notesnook/themes-server": "file:../../servers/themes",
|
||||
"@notesnook/intl": "file:../../packages/intl",
|
||||
"diffblazer": "^1.0.1",
|
||||
"react": "18.2.0",
|
||||
"react-native": "0.74.5",
|
||||
|
||||
150
apps/web/package-lock.json
generated
150
apps/web/package-lock.json
generated
@@ -18,6 +18,8 @@
|
||||
"@emotion/react": "11.11.1",
|
||||
"@hazae41/foras": "^2.1.4",
|
||||
"@henrygd/queue": "^1.0.6",
|
||||
"@lingui/core": "4.11.2",
|
||||
"@lingui/react": "4.11.2",
|
||||
"@mdi/js": "^7.2.96",
|
||||
"@mdi/react": "^1.6.1",
|
||||
"@notesnook-importer/core": "^2.1.1",
|
||||
@@ -26,6 +28,7 @@
|
||||
"@notesnook/crypto": "file:../../packages/crypto",
|
||||
"@notesnook/desktop": "file:../desktop",
|
||||
"@notesnook/editor": "file:../../packages/editor",
|
||||
"@notesnook/intl": "file:../../packages/intl",
|
||||
"@notesnook/logger": "file:../../packages/logger",
|
||||
"@notesnook/streamable-fs": "file:../../packages/streamable-fs",
|
||||
"@notesnook/theme": "file:../../packages/theme",
|
||||
@@ -83,6 +86,7 @@
|
||||
"react-virtuoso": "^4.6.2",
|
||||
"timeago.js": "4.0.2",
|
||||
"tinycolor2": "^1.6.0",
|
||||
"vite-plugin-commonjs": "^0.10.1",
|
||||
"w3c-keyname": "^2.2.6",
|
||||
"web-streams-polyfill": "^3.1.1",
|
||||
"wouter": "2.12.1",
|
||||
@@ -33078,6 +33082,27 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"../../packages/intl": {
|
||||
"name": "@notesnook/intl",
|
||||
"version": "1.0.0",
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.24.9",
|
||||
"@babel/preset-env": "^7.20.2",
|
||||
"@lingui/cli": "^4.11.2",
|
||||
"@lingui/macro": "^4.11.2",
|
||||
"@lingui/swc-plugin": "^4.0.7",
|
||||
"@rspack/cli": "^0.6.2",
|
||||
"@rspack/core": "^0.6.2",
|
||||
"@types/react": "^18.2.39",
|
||||
"babel-plugin-macros": "^3.1.0",
|
||||
"react": "18.2.0",
|
||||
"typescript": "5.5.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@lingui/macro": "*",
|
||||
"react": ">=18"
|
||||
}
|
||||
},
|
||||
"../../packages/logger": {
|
||||
"name": "@notesnook/logger",
|
||||
"version": "2.1.3",
|
||||
@@ -42895,6 +42920,46 @@
|
||||
"@jridgewell/sourcemap-codec": "^1.4.14"
|
||||
}
|
||||
},
|
||||
"node_modules/@lingui/core": {
|
||||
"version": "4.11.2",
|
||||
"resolved": "https://registry.npmjs.org/@lingui/core/-/core-4.11.2.tgz",
|
||||
"integrity": "sha512-5wFmpHeDbLXEqaEUwlayS4SoqrCbDI3/bVRlwhmdNCeUcUYWh+7dTDlQnp4tPek1x1dEppABIkdN/0qLDdKcBQ==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.20.13",
|
||||
"@lingui/message-utils": "4.11.2",
|
||||
"unraw": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@lingui/message-utils": {
|
||||
"version": "4.11.2",
|
||||
"resolved": "https://registry.npmjs.org/@lingui/message-utils/-/message-utils-4.11.2.tgz",
|
||||
"integrity": "sha512-3oJk7ZKExk4NVa4d3CM0z0iNqIokaFOWeu7lYVzu0oEX7DP6OxNjlCAtObIhJCB0FdIPz8sXxhDkyDHFj+eIvw==",
|
||||
"dependencies": {
|
||||
"@messageformat/parser": "^5.0.0",
|
||||
"js-sha256": "^0.10.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@lingui/react": {
|
||||
"version": "4.11.2",
|
||||
"resolved": "https://registry.npmjs.org/@lingui/react/-/react-4.11.2.tgz",
|
||||
"integrity": "sha512-OKHCg3yPW2xhYWoY2kOz+eP7qpdkab+4tERUvJ9QJ9bzQ6OnPLCagaRftB3nqdKuWzKoA5F2VG2QLUhF7DjpGA==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.20.13",
|
||||
"@lingui/core": "4.11.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@mapbox/node-pre-gyp": {
|
||||
"version": "1.0.11",
|
||||
"license": "BSD-3-Clause",
|
||||
@@ -42955,6 +43020,14 @@
|
||||
"prop-types": "^15.7.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@messageformat/parser": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@messageformat/parser/-/parser-5.1.0.tgz",
|
||||
"integrity": "sha512-jKlkls3Gewgw6qMjKZ9SFfHUpdzEVdovKFtW1qRhJ3WI4FW5R/NnGDqr8SDGz+krWDO3ki94boMmQvGke1HwUQ==",
|
||||
"dependencies": {
|
||||
"moo": "^0.5.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@microsoft/microsoft-graph-client": {
|
||||
"version": "3.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@microsoft/microsoft-graph-client/-/microsoft-graph-client-3.0.7.tgz",
|
||||
@@ -42983,7 +43056,6 @@
|
||||
},
|
||||
"node_modules/@nodelib/fs.scandir": {
|
||||
"version": "2.1.5",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@nodelib/fs.stat": "2.0.5",
|
||||
@@ -42995,7 +43067,6 @@
|
||||
},
|
||||
"node_modules/@nodelib/fs.stat": {
|
||||
"version": "2.0.5",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
@@ -43003,7 +43074,6 @@
|
||||
},
|
||||
"node_modules/@nodelib/fs.walk": {
|
||||
"version": "1.2.8",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@nodelib/fs.scandir": "2.1.5",
|
||||
@@ -43140,6 +43210,10 @@
|
||||
"resolved": "../../packages/editor",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/@notesnook/intl": {
|
||||
"resolved": "../../packages/intl",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/@notesnook/logger": {
|
||||
"resolved": "../../packages/logger",
|
||||
"link": true
|
||||
@@ -44389,6 +44463,28 @@
|
||||
"@types/ms": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/eslint": {
|
||||
"version": "9.6.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz",
|
||||
"integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@types/estree": "*",
|
||||
"@types/json-schema": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/eslint-scope": {
|
||||
"version": "3.7.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz",
|
||||
"integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@types/eslint": "*",
|
||||
"@types/estree": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/estree": {
|
||||
"version": "1.0.5",
|
||||
"dev": true,
|
||||
@@ -44853,7 +44949,8 @@
|
||||
},
|
||||
"node_modules/acorn": {
|
||||
"version": "8.11.3",
|
||||
"dev": true,
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
|
||||
"integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
@@ -45258,7 +45355,6 @@
|
||||
},
|
||||
"node_modules/braces": {
|
||||
"version": "3.0.2",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fill-range": "^7.0.1"
|
||||
@@ -46568,7 +46664,6 @@
|
||||
},
|
||||
"node_modules/fast-glob": {
|
||||
"version": "3.3.2",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@nodelib/fs.stat": "^2.0.2",
|
||||
@@ -46588,7 +46683,6 @@
|
||||
},
|
||||
"node_modules/fastq": {
|
||||
"version": "1.15.0",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"reusify": "^1.0.4"
|
||||
@@ -46674,7 +46768,6 @@
|
||||
},
|
||||
"node_modules/fill-range": {
|
||||
"version": "7.0.1",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"to-regex-range": "^5.0.1"
|
||||
@@ -46987,7 +47080,6 @@
|
||||
},
|
||||
"node_modules/glob-parent": {
|
||||
"version": "5.1.2",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"is-glob": "^4.0.1"
|
||||
@@ -47667,7 +47759,6 @@
|
||||
},
|
||||
"node_modules/is-extglob": {
|
||||
"version": "2.1.1",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
@@ -47683,7 +47774,6 @@
|
||||
},
|
||||
"node_modules/is-glob": {
|
||||
"version": "4.0.3",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-extglob": "^2.1.1"
|
||||
@@ -47710,7 +47800,6 @@
|
||||
},
|
||||
"node_modules/is-number": {
|
||||
"version": "7.0.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.12.0"
|
||||
@@ -48304,7 +48393,8 @@
|
||||
},
|
||||
"node_modules/magic-string": {
|
||||
"version": "0.30.10",
|
||||
"dev": true,
|
||||
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz",
|
||||
"integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/sourcemap-codec": "^1.4.15"
|
||||
@@ -48614,7 +48704,6 @@
|
||||
},
|
||||
"node_modules/merge2": {
|
||||
"version": "1.4.1",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
@@ -49146,7 +49235,6 @@
|
||||
},
|
||||
"node_modules/micromatch": {
|
||||
"version": "4.0.5",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"braces": "^3.0.2",
|
||||
@@ -49275,6 +49363,11 @@
|
||||
"ufo": "^1.5.3"
|
||||
}
|
||||
},
|
||||
"node_modules/moo": {
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmjs.org/moo/-/moo-0.5.2.tgz",
|
||||
"integrity": "sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q=="
|
||||
},
|
||||
"node_modules/mri": {
|
||||
"version": "1.2.0",
|
||||
"license": "MIT",
|
||||
@@ -49706,7 +49799,6 @@
|
||||
},
|
||||
"node_modules/picomatch": {
|
||||
"version": "2.3.1",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8.6"
|
||||
@@ -49952,7 +50044,6 @@
|
||||
},
|
||||
"node_modules/queue-microtask": {
|
||||
"version": "1.2.3",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
@@ -50451,7 +50542,6 @@
|
||||
},
|
||||
"node_modules/reusify": {
|
||||
"version": "1.0.4",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"iojs": ">=1.0.0",
|
||||
@@ -50566,7 +50656,6 @@
|
||||
},
|
||||
"node_modules/run-parallel": {
|
||||
"version": "1.2.0",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
@@ -51374,7 +51463,6 @@
|
||||
},
|
||||
"node_modules/to-regex-range": {
|
||||
"version": "5.0.1",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-number": "^7.0.0"
|
||||
@@ -51902,6 +51990,28 @@
|
||||
"url": "https://opencollective.com/vitest"
|
||||
}
|
||||
},
|
||||
"node_modules/vite-plugin-commonjs": {
|
||||
"version": "0.10.1",
|
||||
"resolved": "https://registry.npmjs.org/vite-plugin-commonjs/-/vite-plugin-commonjs-0.10.1.tgz",
|
||||
"integrity": "sha512-taP8R9kYGlCW5OzkVR0UIWRCnG6rSxeWWuA7tnU5b9t5MniibOnDY219NhisTeDhJAeGT8cEnrhVWZ9A5yD+vg==",
|
||||
"dependencies": {
|
||||
"acorn": "^8.8.2",
|
||||
"fast-glob": "^3.2.12",
|
||||
"magic-string": "^0.30.1",
|
||||
"vite-plugin-dynamic-import": "^1.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vite-plugin-dynamic-import": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/vite-plugin-dynamic-import/-/vite-plugin-dynamic-import-1.5.0.tgz",
|
||||
"integrity": "sha512-Qp85c+AVJmLa8MLni74U4BDiWpUeFNx7NJqbGZyR2XJOU7mgW0cb7nwlAMucFyM4arEd92Nfxp4j44xPi6Fu7g==",
|
||||
"dependencies": {
|
||||
"acorn": "^8.8.2",
|
||||
"es-module-lexer": "^1.2.1",
|
||||
"fast-glob": "^3.2.12",
|
||||
"magic-string": "^0.30.1"
|
||||
}
|
||||
},
|
||||
"node_modules/vite-plugin-env-compatible": {
|
||||
"version": "2.0.1",
|
||||
"dev": true,
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
"@emotion/react": "11.11.1",
|
||||
"@hazae41/foras": "^2.1.4",
|
||||
"@henrygd/queue": "^1.0.6",
|
||||
"@lingui/core": "4.11.2",
|
||||
"@lingui/react": "4.11.2",
|
||||
"@mdi/js": "^7.2.96",
|
||||
"@mdi/react": "^1.6.1",
|
||||
"@notesnook-importer/core": "^2.1.1",
|
||||
@@ -24,6 +26,7 @@
|
||||
"@notesnook/crypto": "file:../../packages/crypto",
|
||||
"@notesnook/desktop": "file:../desktop",
|
||||
"@notesnook/editor": "file:../../packages/editor",
|
||||
"@notesnook/intl": "file:../../packages/intl",
|
||||
"@notesnook/logger": "file:../../packages/logger",
|
||||
"@notesnook/streamable-fs": "file:../../packages/streamable-fs",
|
||||
"@notesnook/theme": "file:../../packages/theme",
|
||||
@@ -81,6 +84,7 @@
|
||||
"react-virtuoso": "^4.6.2",
|
||||
"timeago.js": "4.0.2",
|
||||
"tinycolor2": "^1.6.0",
|
||||
"vite-plugin-commonjs": "^0.10.1",
|
||||
"w3c-keyname": "^2.2.6",
|
||||
"web-streams-polyfill": "^3.1.1",
|
||||
"wouter": "2.12.1",
|
||||
|
||||
@@ -25,6 +25,13 @@ import { getServiceWorkerVersion } from "./utils/version";
|
||||
import { register as registerStreamSaver } from "./utils/stream-saver/mitm";
|
||||
import { ThemeDark, ThemeLight, themeToCSS } from "@notesnook/theme";
|
||||
import Config from "./utils/config";
|
||||
import Intl from "@notesnook/intl";
|
||||
import { i18n } from "@lingui/core";
|
||||
i18n.load({
|
||||
en: Intl.$en
|
||||
});
|
||||
i18n.activate("en");
|
||||
Intl.setI18nGlobal(i18n);
|
||||
|
||||
const colorScheme = JSON.parse(
|
||||
window.localStorage.getItem("colorScheme") || '"light"'
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user