web: update importer to 2.6.0

This commit is contained in:
Abdullah Atta
2026-08-19 13:29:54 +05:00
parent bcfdb5caf9
commit 54a9c131fa
11 changed files with 471 additions and 2195 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -18,7 +18,7 @@
"@lingui/react": "5.1.2",
"@mdi/js": "7.4.47",
"@mdi/react": "1.6.1",
"@notesnook-importer/core": "^2.4.5",
"@notesnook-importer/core": "2.6.0",
"@notesnook/common": "file:../../packages/common",
"@notesnook/core": "file:../../packages/core",
"@notesnook/crypto": "file:../../packages/crypto",

View File

@@ -0,0 +1,121 @@
/*
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/>.
*/
import { wrap } from "comlink";
import type { Remote } from "comlink";
import type {
SqlDatabase,
SqliteAdapter,
SqliteDatabaseFiles,
SqlParams,
SqlRow
} from "@notesnook-importer/core";
import SQLiteWorker from "./sqlite.worker?worker";
import { IDBBatchAtomicVFS } from "./IDBBatchAtomicVFS";
import SQLiteAsyncURI from "./wa-sqlite-async.wasm?url";
type ImporterWorkerAPI = {
open(
name: string,
options: { async: boolean; url?: string; encrypted: boolean; skipExtensions?: boolean }
): Promise<void>;
run(
mode: "query" | "exec" | "raw",
sql: string,
parameters?: unknown[]
): Promise<{ rows: SqlRow[] }>;
close(): Promise<void>;
};
function toParams(params?: SqlParams): unknown[] | undefined {
return Array.isArray(params) ? params : params ? Object.values(params) : undefined;
}
class WorkerSqlDatabase implements SqlDatabase {
constructor(
private readonly worker: InstanceType<typeof SQLiteWorker>,
private readonly api: Remote<ImporterWorkerAPI>,
private readonly idbName: string
) {}
async all<T = SqlRow>(sql: string, params?: SqlParams): Promise<T[]> {
const result = await this.api.run("query", sql, toParams(params));
return result.rows as T[];
}
async get<T = SqlRow>(sql: string, params?: SqlParams): Promise<T | undefined> {
const result = await this.api.run("query", sql, toParams(params));
return result.rows[0] as T | undefined;
}
close() {
void this.api
.close()
.catch(() => {})
.finally(() => {
this.worker.terminate();
try {
indexedDB.deleteDatabase(this.idbName);
} catch {
// ignore
}
});
}
}
/**
* An SQLite adapter for Apple Notes / Apple Journal. Database files are
* streamed into IndexedDB (via the `IDBBatchAtomicVFS` block format) on the
* main thread — so large imports never load the files fully into memory — and
* the existing `sqlite.worker.ts` is reused to open the database and run
* queries. WAL data is replayed with exclusive locking, so no manual
* checkpointing is needed.
*/
export class ImporterSqliteAdapter implements SqliteAdapter {
async open(files: SqliteDatabaseFiles): Promise<SqlDatabase> {
const name = `importer-${crypto.randomUUID()}`;
const path = `/${name}`;
const vfs = new IDBBatchAtomicVFS(name, { durability: "strict" });
try {
await vfs.importFile(path, files.main);
if (files.wal) await vfs.importFile(`${path}-wal`, files.wal);
// The -shm file is intentionally skipped: it is only a cache of the WAL
// index and its import breaks the Asyncify build. Exclusive locking makes
// SQLite rebuild it in memory.
} finally {
await vfs.close();
}
const worker = new SQLiteWorker();
const api = wrap<ImporterWorkerAPI>(worker);
await api.open(name, {
async: true,
encrypted: false,
url: SQLiteAsyncURI,
skipExtensions: true
});
// WAL + exclusive locking (the same combination the Notesnook database
// uses) replays the imported -wal file without needing a shared -shm.
await api.run("exec", "PRAGMA locking_mode=EXCLUSIVE");
return new WorkerSqlDatabase(worker, api, name);
}
}

View File

@@ -18,23 +18,23 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import {
IFile,
IFileProvider,
ProviderSettings,
transform
} from "@notesnook-importer/core";
import { formatBytes, getFormattedDate } from "@notesnook/common";
import { ScrollContainer } from "@notesnook/ui";
import { Button, Flex, Input, Text } from "@theme-ui/components";
import { Button, Flex, Text } from "@theme-ui/components";
import { xxhash64 } from "hash-wasm";
import { useCallback, useEffect, useRef, useState } from "react";
import { useDropzone } from "react-dropzone";
import { useEffect, useRef, useState } from "react";
import { importNote } from "../../../utils/importer";
import { PromptDialog } from "../../../dialogs/prompt";
import { ImporterSqliteAdapter } from "../../../common/sqlite/importer-sqlite-adapter";
import Accordion from "../../accordion";
import { TransformResult } from "../types";
import { useStore as useAppStore } from "../../../stores/app-store";
import { strings } from "@notesnook/intl";
import { showFilePicker } from "../../../utils/file-picker";
type FileProviderHandlerProps = {
provider: IFileProvider;
@@ -63,20 +63,6 @@ export function FileProviderHandler(props: FileProviderHandlerProps) {
const [_, setCounter] = useState<number>(0);
const logs = useRef<LogMessage[]>([]);
const onDrop = useCallback((acceptedFiles: File[]) => {
setFiles((files) => {
const newFiles = [...acceptedFiles, ...files];
return newFiles;
});
}, []);
const { getRootProps, getInputProps, isDragActive } = useDropzone({
onDrop,
accept: {
file: provider?.supportedExtensions?.concat([".zip"])
}
});
useEffect(() => {
setFiles([]);
}, [provider]);
@@ -122,14 +108,15 @@ export function FileProviderHandler(props: FileProviderHandlerProps) {
setTotalNoteCount(++totalNotes);
},
options: {
onenote: {
getPassword
},
colornote: {
getPassword: async (filename: string) => {
const password = await PromptDialog.show({
title: strings.colorNotePasswordFor(filename),
description: strings.colorNotPasswordForDesc()
});
return password || undefined;
}
getPassword
},
applenotes: {
adapter: new ImporterSqliteAdapter(),
getPassword
}
}
};
@@ -140,20 +127,24 @@ export function FileProviderHandler(props: FileProviderHandlerProps) {
done: 0
});
for (const file of files) {
setFilesProgress((p) => ({
...p,
done: p.done + 1
}));
errors.push(
...(await transform(
provider,
files.map((f) => ({
name: f.name,
modifiedAt: f.lastModified,
size: f.size,
data: f
})),
settings
))
);
setFilesProgress({
total: files.length,
done: files.length
});
const providerFile: IFile = {
name: file.name,
modifiedAt: file.lastModified,
size: file.size,
data: file
};
errors.push(...(await transform(provider, [providerFile], settings)));
}
await useAppStore.getState().refresh();
onTransformFinished({
totalNotes,
@@ -226,42 +217,53 @@ export function FileProviderHandler(props: FileProviderHandlerProps) {
how to import from {provider?.name}.
</a>
</Text>
<Flex
{...getRootProps()}
sx={{
justifyContent: "center",
alignItems: "center",
height: 100,
border: "2px dashed var(--border)",
borderRadius: "default",
mt: 2,
cursor: "pointer",
":hover": {
bg: "background-secondary"
<Flex sx={{ mt: 1, gap: 1 }}>
<Button
variant="secondary"
onClick={() =>
showFilePicker({
multiple: true,
acceptedFileTypes: provider?.supportedExtensions
?.concat([".zip"])
.join(",")
}).then((newFiles) => {
setFiles((files) => {
const _files = [...files, ...newFiles];
return _files;
});
})
}
}}
>
<Input {...getInputProps()} />
<Text variant="body" sx={{ textAlign: "center" }}>
{isDragActive
? "Drop the files here"
: "Drag & drop files here, or click to select files"}
<br />
<Text variant="subBody">
Only {provider?.supportedExtensions.join(", ")} files are supported.{" "}
{provider?.supportedExtensions.includes(".zip") ? null : (
<>
You can also select .zip files containing{" "}
{provider?.supportedExtensions.join(", ")} files.
</>
)}
<br />
{provider.examples ? (
<>For example, {provider.examples.join(", ")}</>
) : null}
</Text>
</Text>
>
{strings.selectFiles()}
</Button>
<Button
variant="secondary"
onClick={() => {
showFilePicker({
directory: true
}).then((newFiles) => {
setFiles((files) => {
const _files = [...files, ...newFiles];
return _files;
});
});
}}
>
{strings.selectFolder()}
</Button>
</Flex>
<Text variant="subBody" sx={{ mt: 1 }}>
Only {provider?.supportedExtensions.join(", ")} files are supported.{" "}
{provider?.supportedExtensions.includes(".zip") ? null : (
<>
You can also select .zip files containing{" "}
{provider?.supportedExtensions.join(", ")} files.
</>
)}
{provider.examples ? (
<> For example, {provider.examples.join(", ")}</>
) : null}
</Text>
{files.length > 0 ? (
<Accordion
@@ -352,3 +354,11 @@ export function FileProviderHandler(props: FileProviderHandlerProps) {
</Flex>
);
}
async function getPassword(filename: string) {
const password = await PromptDialog.show({
title: strings.passwordFor(filename),
type: "password"
});
return password || undefined;
}

View File

@@ -27,6 +27,7 @@ export type PromptDialogProps = BaseDialogProps<undefined | string> & {
title: string;
description?: string;
defaultValue?: string;
type?: "text" | "password" | "email" | "number";
};
export const PromptDialog = DialogManager.register(function PromptDialog(
@@ -51,6 +52,7 @@ export const PromptDialog = DialogManager.register(function PromptDialog(
<Field
inputRef={inputRef}
defaultValue={props.defaultValue}
type={props.type}
autoFocus
onKeyUp={(e) => {
if (e.key == "Enter") props.onClose(inputRef.current?.value || "");

View File

@@ -21,17 +21,26 @@ import { PAGE_VISIBILITY_CHANGE } from "./page-visibility";
import { strings } from "@notesnook/intl";
import { TaskManager } from "../common/task-manager";
type FilePickerOptions = { acceptedFileTypes: string; multiple?: boolean };
type FilePickerOptions = {
acceptedFileTypes?: string;
multiple?: boolean;
directory?: boolean;
};
export async function showFilePicker({
acceptedFileTypes,
multiple
multiple,
directory
}: FilePickerOptions): Promise<File[]> {
PAGE_VISIBILITY_CHANGE.ignore = true;
const input = document.createElement("input");
input.setAttribute("type", "file");
input.setAttribute("multiple", `${multiple || false}`);
input.setAttribute("accept", acceptedFileTypes);
if (acceptedFileTypes) input.setAttribute("accept", acceptedFileTypes);
if (directory) {
input.setAttribute("webkitdirectory", "true");
input.setAttribute("directory", "true");
}
input.dispatchEvent(new MouseEvent("click"));
const result = await TaskManager.startTask<File[]>({
type: "modal",

View File

@@ -10,7 +10,7 @@
"hasInstallScript": true,
"license": "GPL-3.0-or-later",
"dependencies": {
"@notesnook-importer/core": "^2.4.5",
"@notesnook-importer/core": "^2.6.0",
"@notesnook/common": "file:../common",
"@notesnook/intl": "file:../intl",
"@notesnook/theme": "file:../theme",
@@ -105,6 +105,7 @@
"version": "2.1.3",
"license": "GPL-3.0-or-later",
"dependencies": {
"@notesnook/common": "^2.1.3",
"@notesnook/core": "file:../core",
"@readme/data-urls": "^3.0.0",
"dayjs": "1.11.13",
@@ -982,15 +983,43 @@
"integrity": "sha512-KPnNOtm5i2pMabqZxpUz7iQf+mfrYZyKCZ8QNz85czgEt7cuHcGorWfdzUMWYA0SD+a6Hn4FmJ+YhzzzjkTZrQ==",
"dev": true
},
"node_modules/@notesnook-importer/core": {
"version": "2.4.5",
"resolved": "https://registry.npmjs.org/@notesnook-importer/core/-/core-2.4.5.tgz",
"integrity": "sha512-7Oqkw07CykwC/xzGrC6St4C/87QmXqK8UtmSxwE05fpz8DWoKEviJSWFa5fKY52umTphGvmtY23252dZ9J9EJg==",
"node_modules/@notesnook-importer/applenotes": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@notesnook-importer/applenotes/-/applenotes-1.1.0.tgz",
"integrity": "sha512-6mV6QtYqNqomyHJsWA926I1X8BsoM/6R3X8cdF7d4sg5cfkjENt2hoayBiW1ONK92MM9rU6mbJlqDSDEDinXPg==",
"license": "GPL-3.0-or-later",
"dependencies": {
"@notesnook-importer/enex": "^2.3.5",
"@notesnook-importer/storage": "^2.3.5",
"@notesnook-importer/znel": "^2.3.5",
"@notesnook-importer/types": "^1.1.0",
"entities": "^4.4.0",
"fflate": "^0.7.4",
"protobufjs": "^8.7.2"
}
},
"node_modules/@notesnook-importer/applenotes/node_modules/entities": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"license": "BSD-2-Clause",
"engines": {
"node": ">=0.12"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/@notesnook-importer/core": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/@notesnook-importer/core/-/core-2.6.0.tgz",
"integrity": "sha512-HjVvNgH6hFDMM/m3i+7GNDLMfcqAvNessDMS+JBWp70k8w8m1KltkVL2E6bng/zRRG6hisJJMSQzFOwpTBS2Ag==",
"license": "GPL-3.0-or-later",
"dependencies": {
"@notesnook-importer/applenotes": "^1.1.0",
"@notesnook-importer/enex": "^2.5.0",
"@notesnook-importer/onenote": "^1.1.0",
"@notesnook-importer/samsung-notes": "^1.1.0",
"@notesnook-importer/storage": "^2.5.0",
"@notesnook-importer/types": "^1.1.0",
"@notesnook-importer/znel": "^2.5.0",
"@stablelib/chacha20poly1305": "^1.0.1",
"@streamparser/json": "^0.0.10",
"@zip.js/zip.js": "^2.7.32",
@@ -1004,6 +1033,7 @@
"hast-util-is-element": "^2.1.3",
"htmlparser2": "^8.0.1",
"magic-bytes.js": "^1.8.0",
"plist": "^5.0.0",
"rehype-stringify": "^9.0.3",
"remark": "^14.0.3",
"remark-comments": "^1.2.9",
@@ -1012,6 +1042,7 @@
"remark-rehype": "^10.1.0",
"remark-supersub": "^1.0.0",
"spark-md5": "^3.0.2",
"sql.js": "^1.14.2",
"unified": "^10.1.2",
"unist-util-visit": "^5.0.0",
"varint": "^6.0.0",
@@ -1031,9 +1062,9 @@
}
},
"node_modules/@notesnook-importer/enex": {
"version": "2.3.5",
"resolved": "https://registry.npmjs.org/@notesnook-importer/enex/-/enex-2.3.5.tgz",
"integrity": "sha512-0+08XVhsQQFoEUrar3k07DuTluNho/FHxJ25n/DT+ug8kVraHHVqI40a2P9h8bW8iWxYs02Zq1n+N2uTv5qb+g==",
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@notesnook-importer/enex/-/enex-2.5.0.tgz",
"integrity": "sha512-oqlg0SCqwTDmqGdi/p6m5FpcaKspIhDG08g/2fm2xIAYH95WJlyS4nb4pygyJGsywrq1USgIQ/Bup9hZ4jJKeA==",
"license": "GPL-3.0-or-later",
"dependencies": {
"base64-js": "^1.5.1",
@@ -1045,16 +1076,40 @@
"spark-md5": "^3.0.2"
}
},
"node_modules/@notesnook-importer/onenote": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@notesnook-importer/onenote/-/onenote-1.1.0.tgz",
"integrity": "sha512-V0cFx4QsC873wJsh5ONNG/pTAdTN+9LBYIAEIi+U6ZubTfm8Y2zIn/eBabVpFO62OvdD551EcFIbto5CTGJOrg==",
"license": "GPL-3.0-or-later",
"dependencies": {
"fflate": "^0.7.4"
}
},
"node_modules/@notesnook-importer/samsung-notes": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@notesnook-importer/samsung-notes/-/samsung-notes-1.1.0.tgz",
"integrity": "sha512-2/2WbDqBBYQ46qkpPf4M5mdgHgSsjBlyTxWQsr0jv5l2j9TedxKE6NwmMxlrRJFkLxNBnNw3Yj1E437h7AJpqA==",
"license": "GPL-3.0-or-later",
"dependencies": {
"fflate": "^0.7.4"
}
},
"node_modules/@notesnook-importer/storage": {
"version": "2.3.5",
"resolved": "https://registry.npmjs.org/@notesnook-importer/storage/-/storage-2.3.5.tgz",
"integrity": "sha512-orvSK0XIcqlmiWmjQ3RzS3qZp7viBdCpAloX557Ml200LMSMGDsOtofYNv5IYllBETnqApERLPQaUzBSuviuvA==",
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@notesnook-importer/storage/-/storage-2.5.0.tgz",
"integrity": "sha512-7HpvJkafCs3Ba0DdzZA8QecLfdN7D7V3g4773/iwTsRxa07YTRcavmV2jBGY6DuMaTkJio/Q/M/kSI0m5yiU6A==",
"license": "GPL-3.0-or-later"
},
"node_modules/@notesnook-importer/types": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@notesnook-importer/types/-/types-1.1.0.tgz",
"integrity": "sha512-hoS4jHoaXiFnbUTElxYdIY85BOqf1wke0B+Oe5ExbHuFdUDOI0AtZWyCwArG9t0vfUlYmhJ1v27QHOfeE1kxQQ==",
"license": "GPL-3.0-or-later"
},
"node_modules/@notesnook-importer/znel": {
"version": "2.3.5",
"resolved": "https://registry.npmjs.org/@notesnook-importer/znel/-/znel-2.3.5.tgz",
"integrity": "sha512-s1kTA3EQ5OswBc0RvWnWgIm6/mIWvnh3iWmcOJcApIqhDwQziEkYiS+UMfuY9nOUyIWtepMe/WJ0Odk15uah9w==",
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@notesnook-importer/znel/-/znel-2.5.0.tgz",
"integrity": "sha512-8Tx+fcAPJQeyjJpk9+mrak4c+v186IExgpy16I25fRJwl35k5B77NS0gWNOCFX80levInoX8FoXNp8IanVb8Rg==",
"license": "GPL-3.0-or-later",
"dependencies": {
"base64-js": "^1.5.1",
@@ -2299,6 +2354,15 @@
"url": "https://opencollective.com/vitest"
}
},
"node_modules/@xmldom/xmldom": {
"version": "0.9.11",
"resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.9.11.tgz",
"integrity": "sha512-tW8bcK3hsG0/uqSnNz6TK4BkcuZSezoU7DlnYssILmZDktPnSHHuDJJFM0AJv+13gz2r0iGdrj6qqKeUnxXEDg==",
"license": "MIT",
"engines": {
"node": ">=14.6"
}
},
"node_modules/@zip.js/zip.js": {
"version": "2.7.57",
"resolved": "https://registry.npmjs.org/@zip.js/zip.js/-/zip.js-2.7.57.tgz",
@@ -3528,6 +3592,12 @@
"resolved": "https://registry.npmjs.org/linkifyjs/-/linkifyjs-4.1.3.tgz",
"integrity": "sha512-auMesunaJ8yfkHvK4gfg1K0SaKX/6Wn9g2Aac/NwX+l5VdmFZzo/hdPGxEOETj+ryRa4/fiOPjeeKURSAJx1sg=="
},
"node_modules/long": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz",
"integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==",
"license": "Apache-2.0"
},
"node_modules/longest-streak": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz",
@@ -4764,6 +4834,19 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/plist": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/plist/-/plist-5.0.0.tgz",
"integrity": "sha512-20N+g1DvMm/DFRbsvER7tT4wDryq0WunK7VMkDaiJcKNapAnUMkTsAnacFYf8n420F4Hf6/hefgmJRkMb1M0fg==",
"license": "MIT",
"dependencies": {
"@xmldom/xmldom": "^0.9.10",
"xmlbuilder": "^15.1.1"
},
"engines": {
"node": ">=18"
}
},
"node_modules/postcss": {
"version": "8.5.1",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.1.tgz",
@@ -5047,6 +5130,18 @@
"prosemirror-transform": "^1.1.0"
}
},
"node_modules/protobufjs": {
"version": "8.7.2",
"resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-8.7.2.tgz",
"integrity": "sha512-oTVHV+oelUBtiu5iTuTNNZ0eLYsXSMxry4cgr30mayNkgIZL6qZ0IOQVPuSWGcyAaXKl/XgqwWHIC3a0khYVBA==",
"license": "BSD-3-Clause",
"dependencies": {
"long": "^5.3.2"
},
"engines": {
"node": ">=12.0.0"
}
},
"node_modules/pstree.remy": {
"version": "1.1.8",
"resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
@@ -5500,6 +5595,12 @@
"integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
"license": "BSD-3-Clause"
},
"node_modules/sql.js": {
"version": "1.14.2",
"resolved": "https://registry.npmjs.org/sql.js/-/sql.js-1.14.2.tgz",
"integrity": "sha512-3ZGPovObMFrdw79zrUHbfdE/DLIsy8jdNdssmMSQuRAymedU6q84asPt0kgiqrdMYlPegDItiIMfmIXzZnYFcw==",
"license": "MIT"
},
"node_modules/stackback": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz",
@@ -6208,6 +6309,15 @@
"node": ">=8"
}
},
"node_modules/xmlbuilder": {
"version": "15.1.1",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz",
"integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==",
"license": "MIT",
"engines": {
"node": ">=8.0"
}
},
"node_modules/yaml": {
"version": "1.10.2",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",

View File

@@ -30,7 +30,7 @@
},
"license": "GPL-3.0-or-later",
"dependencies": {
"@notesnook-importer/core": "^2.4.5",
"@notesnook-importer/core": "^2.6.0",
"@notesnook/common": "file:../common",
"@notesnook/intl": "file:../intl",
"@notesnook/theme": "file:../theme",

View File

@@ -812,7 +812,7 @@ msgstr "Align left"
msgid "Align right"
msgstr "Align right"
#: src/strings.ts:2813
#: src/strings.ts:2809
msgid "Alignment"
msgstr "Alignment"
@@ -1358,6 +1358,10 @@ msgstr "Boost your productivity with Notebooks and organize your notes."
msgid "Browse"
msgstr "Browse"
#: src/strings.ts:2811
msgid "Browser storage quota reached. Please delete some attachments from the attachment manager or clear some local data to free up space."
msgstr "Browser storage quota reached. Please delete some attachments from the attachment manager or clear some local data to free up space."
#: src/strings.ts:2286
msgid "Bullet list"
msgstr "Bullet list"
@@ -1662,7 +1666,7 @@ msgstr "Clear data & reset account"
msgid "Clear default notebook"
msgstr "Clear default notebook"
#: src/strings.ts:2803
#: src/strings.ts:2799
msgid "Clear history"
msgstr "Clear history"
@@ -1821,10 +1825,6 @@ msgstr "Color scheme"
msgid "Color title"
msgstr "Color title"
#: src/strings.ts:2796
msgid "Colornote password for {filename}"
msgstr "Colornote password for {filename}"
#: src/strings.ts:309
msgid "colors"
msgstr "colors"
@@ -2314,7 +2314,7 @@ msgstr "Delete account"
msgid "Delete all"
msgstr "Delete all"
#: src/strings.ts:2805
#: src/strings.ts:2801
msgid "Delete all version history for this note?"
msgstr "Delete all version history for this note?"
@@ -2338,7 +2338,7 @@ msgstr "Delete data"
msgid "Delete group"
msgstr "Delete group"
#: src/strings.ts:2799
#: src/strings.ts:2795
msgid "Delete item"
msgstr "Delete item"
@@ -2809,6 +2809,10 @@ msgstr "Enter notebook title"
msgid "Enter password"
msgstr "Enter password"
#: src/strings.ts:2812
msgid "Enter password for {filename}"
msgstr "Enter password for {filename}"
#: src/strings.ts:2100
msgid "Enter pin or password to enable app lock."
msgstr "Enter pin or password to enable app lock."
@@ -3844,7 +3848,7 @@ msgstr "Keep"
msgid "Keep open"
msgstr "Keep open"
#: src/strings.ts:2800
#: src/strings.ts:2796
msgid "Keep screen on"
msgstr "Keep screen on"
@@ -4737,7 +4741,7 @@ msgstr "Off"
msgid "Offline"
msgstr "Offline"
#: src/strings.ts:2810
#: src/strings.ts:2806
msgid "Offline mode"
msgstr "Offline mode"
@@ -5223,7 +5227,7 @@ msgstr "Pressing \"X\" will hide the app in your system tray."
msgid "Prevent note title from appearing in tab/window title."
msgstr "Prevent note title from appearing in tab/window title."
#: src/strings.ts:2802
#: src/strings.ts:2798
msgid "Prevent the screen from turning off while the editor is focused."
msgstr "Prevent the screen from turning off while the editor is focused."
@@ -6152,8 +6156,12 @@ msgid "Select day of the week to repeat the reminder."
msgstr "Select day of the week to repeat the reminder."
#: src/strings.ts:1765
msgid "Select files to import"
msgstr "Select files to import"
msgid "Select files"
msgstr "Select files"
#: src/strings.ts:2813
msgid "Select folder"
msgstr "Select folder"
#: src/strings.ts:1608
msgid "Select folder where Notesnook backup files are stored to view and restore them from the app"
@@ -6924,10 +6932,6 @@ msgstr "The information above will be publically available at"
msgid "The Notesnook Circle is exclusive to subscribers. Please consider subscribing to gain access to Notesnook Circle and enjoy additional benefits."
msgstr "The Notesnook Circle is exclusive to subscribers. Please consider subscribing to gain access to Notesnook Circle and enjoy additional benefits."
#: src/strings.ts:2798
msgid "The password for decrypting the Colornote backup file."
msgstr "The password for decrypting the Colornote backup file."
#: src/strings.ts:2094
msgid "The password/pin for unlocking the app."
msgstr "The password/pin for unlocking the app."
@@ -7493,7 +7497,7 @@ msgstr "User verification failed"
msgid "Using {instance} (v{version})"
msgstr "Using {instance} (v{version})"
#: src/strings.ts:2812
#: src/strings.ts:2808
msgid "Using Notesnook without an account will **NOT** sync your notes across devices and could result in data loss if you lose access to your device or uninstall the app. Make sure to backup your notes regularly."
msgstr "Using Notesnook without an account will **NOT** sync your notes across devices and could result in data loss if you lose access to your device or uninstall the app. Make sure to backup your notes regularly."
@@ -7565,7 +7569,7 @@ msgstr "Verifying your email"
msgid "Version"
msgstr "Version"
#: src/strings.ts:2804
#: src/strings.ts:2800
msgid "Version history cleared"
msgstr "Version history cleared"

View File

@@ -812,7 +812,7 @@ msgstr ""
msgid "Align right"
msgstr ""
#: src/strings.ts:2813
#: src/strings.ts:2809
msgid "Alignment"
msgstr ""
@@ -1358,6 +1358,10 @@ msgstr ""
msgid "Browse"
msgstr ""
#: src/strings.ts:2811
msgid "Browser storage quota reached. Please delete some attachments from the attachment manager or clear some local data to free up space."
msgstr ""
#: src/strings.ts:2286
msgid "Bullet list"
msgstr ""
@@ -1662,7 +1666,7 @@ msgstr ""
msgid "Clear default notebook"
msgstr ""
#: src/strings.ts:2803
#: src/strings.ts:2799
msgid "Clear history"
msgstr ""
@@ -1810,10 +1814,6 @@ msgstr ""
msgid "Color title"
msgstr ""
#: src/strings.ts:2796
msgid "Colornote password for {filename}"
msgstr ""
#: src/strings.ts:309
msgid "colors"
msgstr ""
@@ -2303,7 +2303,7 @@ msgstr ""
msgid "Delete all"
msgstr ""
#: src/strings.ts:2805
#: src/strings.ts:2801
msgid "Delete all version history for this note?"
msgstr ""
@@ -2327,7 +2327,7 @@ msgstr ""
msgid "Delete group"
msgstr ""
#: src/strings.ts:2799
#: src/strings.ts:2795
msgid "Delete item"
msgstr ""
@@ -2798,6 +2798,10 @@ msgstr ""
msgid "Enter password"
msgstr ""
#: src/strings.ts:2812
msgid "Enter password for {filename}"
msgstr ""
#: src/strings.ts:2100
msgid "Enter pin or password to enable app lock."
msgstr ""
@@ -3824,7 +3828,7 @@ msgstr ""
msgid "Keep open"
msgstr ""
#: src/strings.ts:2800
#: src/strings.ts:2796
msgid "Keep screen on"
msgstr ""
@@ -4711,7 +4715,7 @@ msgstr ""
msgid "Offline"
msgstr ""
#: src/strings.ts:2810
#: src/strings.ts:2806
msgid "Offline mode"
msgstr ""
@@ -5197,7 +5201,7 @@ msgstr ""
msgid "Prevent note title from appearing in tab/window title."
msgstr ""
#: src/strings.ts:2802
#: src/strings.ts:2798
msgid "Prevent the screen from turning off while the editor is focused."
msgstr ""
@@ -6126,7 +6130,11 @@ msgid "Select day of the week to repeat the reminder."
msgstr ""
#: src/strings.ts:1765
msgid "Select files to import"
msgid "Select files"
msgstr ""
#: src/strings.ts:2813
msgid "Select folder"
msgstr ""
#: src/strings.ts:1608
@@ -6883,10 +6891,6 @@ msgstr ""
msgid "The Notesnook Circle is exclusive to subscribers. Please consider subscribing to gain access to Notesnook Circle and enjoy additional benefits."
msgstr "<<<<<<< HEAD"
#: src/strings.ts:2798
msgid "The password for decrypting the Colornote backup file."
msgstr ""
#: src/strings.ts:2094
msgid "The password/pin for unlocking the app."
msgstr ""
@@ -7443,7 +7447,7 @@ msgstr ""
msgid "Using {instance} (v{version})"
msgstr ""
#: src/strings.ts:2812
#: src/strings.ts:2808
msgid "Using Notesnook without an account will **NOT** sync your notes across devices and could result in data loss if you lose access to your device or uninstall the app. Make sure to backup your notes regularly."
msgstr ""
@@ -7515,7 +7519,7 @@ msgstr ""
msgid "Version"
msgstr ""
#: src/strings.ts:2804
#: src/strings.ts:2800
msgid "Version history cleared"
msgstr ""

View File

@@ -1762,7 +1762,7 @@ For example:
one: "# file ready for import",
other: "# files ready for import"
}),
selectFilesToImport: () => t`Select files to import`,
selectFiles: () => t`Select files`,
importerHelpText: () => [
t`Please refer to the`,
t`import guide`,
@@ -2792,10 +2792,6 @@ Continue without attachments?`,
enterPgpPublicKey: () => t`Enter your PGP public key`,
enterPgpPrivateKey: () => t`Enter your PGP private key`,
expiryDateRemoved: () => t`Expiry date removed`,
colorNotePasswordFor: (filename: string) =>
t`Colornote password for ${filename}`,
colorNotPasswordForDesc: () =>
t`The password for decrypting the Colornote backup file.`,
deleteItem: () => t`Delete item`,
keepScreenOn: () => t`Keep screen on`,
keepScreenOnDesc: () =>
@@ -2810,5 +2806,9 @@ Continue without attachments?`,
offlineMode: () => t`Offline mode`,
offlineModeDesc: () =>
t`Using Notesnook without an account will **NOT** sync your notes across devices and could result in data loss if you lose access to your device or uninstall the app. Make sure to backup your notes regularly.`,
alignment: () => t`Alignment`
alignment: () => t`Alignment`,
browserStorageQuotaReached: () =>
t`Browser storage quota reached. Please delete some attachments from the attachment manager or clear some local data to free up space.`,
passwordFor: (filename: string) => t`Enter password for ${filename}`,
selectFolder: () => t`Select folder`
};