mirror of
https://github.com/streetwriters/notesnook.git
synced 2025-12-23 15:09:33 +01:00
web: fix all type errors
This commit is contained in:
@@ -31,9 +31,15 @@ import { pluralize } from "@notesnook/common";
|
||||
async function moveNotesToTrash(ids: string[], confirm = true) {
|
||||
if (confirm && !(await showMultiDeleteConfirmation(ids.length))) return;
|
||||
|
||||
const lockedIds = await db.notes.locked.ids();
|
||||
if (ids.some((id) => lockedIds.includes(id)) && !(await Vault.unlockVault()))
|
||||
return;
|
||||
const vault = await db.vaults.default();
|
||||
if (vault) {
|
||||
const lockedIds = await db.relations.from(vault, "note").get();
|
||||
if (
|
||||
ids.some((id) => lockedIds.findIndex((s) => s.toId === id) > -1) &&
|
||||
!(await Vault.unlockVault())
|
||||
)
|
||||
return;
|
||||
}
|
||||
|
||||
const items = ids.filter((id) => !db.monographs.isPublished(id));
|
||||
|
||||
|
||||
@@ -288,7 +288,7 @@ const AttachmentMenuItems: (
|
||||
onClick: async () => {
|
||||
const isDownloading = status?.type === "download";
|
||||
if (isDownloading) {
|
||||
await db.fs().cancel(attachment.hash, "download");
|
||||
await db.fs().cancel(attachment.hash);
|
||||
} else await saveAttachment(attachment.hash);
|
||||
}
|
||||
},
|
||||
@@ -300,7 +300,7 @@ const AttachmentMenuItems: (
|
||||
onClick: async () => {
|
||||
const isDownloading = status?.type === "upload";
|
||||
if (isDownloading) {
|
||||
await db.fs().cancel(attachment.hash, "upload");
|
||||
await db.fs().cancel(attachment.hash);
|
||||
} else await reuploadAttachment(attachment.type, attachment.hash);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -61,7 +61,6 @@ import {
|
||||
MaybeDeletedItem,
|
||||
isDeleted
|
||||
} from "@notesnook/core/dist/types";
|
||||
import { isEncryptedContent } from "@notesnook/core/dist/collections/content";
|
||||
import { PreviewSession } from "./types";
|
||||
|
||||
const PDFPreview = React.lazy(() => import("../pdf-preview"));
|
||||
@@ -89,7 +88,7 @@ export default function EditorManager({
|
||||
noteId,
|
||||
nonce
|
||||
}: {
|
||||
noteId?: string;
|
||||
noteId?: string | number;
|
||||
nonce?: string;
|
||||
}) {
|
||||
const isNewSession = !!nonce && !noteId;
|
||||
@@ -136,7 +135,7 @@ export default function EditorManager({
|
||||
|
||||
if (id && isContent && editorInstance.current) {
|
||||
let content: string | null = null;
|
||||
if (locked && isEncryptedContent(item)) {
|
||||
if (locked && item.locked) {
|
||||
const result = await db.vault
|
||||
.decryptContent(item, item.noteId)
|
||||
.catch(() => undefined);
|
||||
@@ -181,7 +180,7 @@ export default function EditorManager({
|
||||
}, [isNewSession, nonce]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isOldSession) return;
|
||||
if (!isOldSession || typeof noteId === "number") return;
|
||||
|
||||
openSession(noteId);
|
||||
}, [noteId]);
|
||||
@@ -210,7 +209,9 @@ export default function EditorManager({
|
||||
{previewSession.current && noteId && (
|
||||
<PreviewModeNotice
|
||||
{...previewSession.current}
|
||||
onDiscard={() => openSession(noteId)}
|
||||
onDiscard={() =>
|
||||
typeof noteId === "string" && openSession(noteId)
|
||||
}
|
||||
/>
|
||||
)}
|
||||
<Editor
|
||||
@@ -330,7 +331,7 @@ type EditorOptions = {
|
||||
onRequestFocus?: () => void;
|
||||
};
|
||||
type EditorProps = {
|
||||
id: string | number;
|
||||
id?: string | number;
|
||||
content: () => string | undefined;
|
||||
nonce?: number;
|
||||
options?: EditorOptions;
|
||||
@@ -393,7 +394,7 @@ export function Editor(props: EditorProps) {
|
||||
const dataurl = await downloadAttachment(
|
||||
hash,
|
||||
"base64",
|
||||
id.toString()
|
||||
id?.toString()
|
||||
);
|
||||
if (!dataurl)
|
||||
return showToast("error", "This image cannot be previewed.");
|
||||
@@ -411,7 +412,7 @@ export function Editor(props: EditorProps) {
|
||||
);
|
||||
} else if (attachment && onPreviewDocument) {
|
||||
onPreviewDocument({ hash });
|
||||
const blob = await downloadAttachment(hash, "blob", id.toString());
|
||||
const blob = await downloadAttachment(hash, "blob", id?.toString());
|
||||
if (!blob) return;
|
||||
onPreviewDocument({ url: URL.createObjectURL(blob), hash });
|
||||
}
|
||||
@@ -427,7 +428,7 @@ export function Editor(props: EditorProps) {
|
||||
return downloadAttachment(
|
||||
attachment.hash,
|
||||
attachment.type === "web-clip" ? "text" : "base64",
|
||||
id.toString()
|
||||
id?.toString()
|
||||
);
|
||||
}}
|
||||
onAttachFile={async (file) => {
|
||||
|
||||
@@ -190,8 +190,8 @@ async function addAttachment(
|
||||
metadata: {
|
||||
hash,
|
||||
hashType,
|
||||
filename: exists?.metadata.filename || file.name,
|
||||
type: exists?.metadata.type || file.type
|
||||
filename: exists?.filename || file.name,
|
||||
type: exists?.type || file.type
|
||||
},
|
||||
key
|
||||
});
|
||||
|
||||
@@ -25,21 +25,20 @@ import { VirtualizedList, VirtualizedListProps } from "../virtualized-list";
|
||||
|
||||
type FilteredListProps<T> = {
|
||||
placeholders: { filter: string; empty: string };
|
||||
filter: (query: string) => Promise<T[]>;
|
||||
filter: (query: string) => Promise<void>;
|
||||
onCreateNewItem: (title: string) => Promise<void>;
|
||||
} & VirtualizedListProps<T, unknown>;
|
||||
|
||||
export function FilteredList<T>(props: FilteredListProps<T>) {
|
||||
const { items, filter, onCreateNewItem, placeholders, ...listProps } = props;
|
||||
|
||||
const [filteredItems, setFilteredItems] = useState<T[]>([]);
|
||||
const [query, setQuery] = useState<string>();
|
||||
const noItemsFound = filteredItems.length <= 0 && query && query.length > 0;
|
||||
const noItemsFound = items.length <= 0 && query && query.length > 0;
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
const _filter = useCallback(
|
||||
async (query = "") => {
|
||||
setFilteredItems(query ? await filter(query) : []);
|
||||
await filter(query);
|
||||
setQuery(query);
|
||||
},
|
||||
[filter]
|
||||
@@ -61,7 +60,7 @@ export function FilteredList<T>(props: FilteredListProps<T>) {
|
||||
data-test-id={"filter-input"}
|
||||
autoFocus
|
||||
placeholder={
|
||||
filteredItems.length <= 0 ? placeholders.empty : placeholders.filter
|
||||
items.length <= 0 ? placeholders.empty : placeholders.filter
|
||||
}
|
||||
onChange={(e) => _filter((e.target as HTMLInputElement).value)}
|
||||
onKeyUp={async (e) => {
|
||||
@@ -70,7 +69,7 @@ export function FilteredList<T>(props: FilteredListProps<T>) {
|
||||
}
|
||||
}}
|
||||
action={
|
||||
filteredItems.length <= 0 && !!query
|
||||
items.length <= 0 && !!query
|
||||
? {
|
||||
icon: Plus,
|
||||
onClick: async () => await _createNewItem(query)
|
||||
@@ -95,7 +94,7 @@ export function FilteredList<T>(props: FilteredListProps<T>) {
|
||||
<Plus size={16} color="accent" />
|
||||
</Button>
|
||||
) : (
|
||||
<VirtualizedList {...listProps} items={query ? filteredItems : items} />
|
||||
<VirtualizedList {...listProps} items={items} />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -69,7 +69,6 @@ export function SessionItem(props: SessionItemProps) {
|
||||
try {
|
||||
const decryptedContent = await db.vault.decryptContent(
|
||||
content,
|
||||
noteId,
|
||||
password
|
||||
);
|
||||
onOpenPreviewSession({
|
||||
|
||||
@@ -17,7 +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 { useEffect } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { Flex, Text } from "@theme-ui/components";
|
||||
import {
|
||||
CheckCircleOutline,
|
||||
@@ -34,6 +34,7 @@ import { FilteredList } from "../components/filtered-list";
|
||||
import { ItemReference, Tag } from "@notesnook/core/dist/types";
|
||||
import { ResolvedItem } from "../components/list-container/resolved-item";
|
||||
import { create } from "zustand";
|
||||
import { VirtualizedGrouping } from "@notesnook/core";
|
||||
|
||||
type SelectedReference = {
|
||||
id: string;
|
||||
@@ -58,14 +59,18 @@ export type AddTagsDialogProps = {
|
||||
function AddTagsDialog(props: AddTagsDialogProps) {
|
||||
const { onClose, noteIds } = props;
|
||||
|
||||
const tags = useStore((store) => store.tags);
|
||||
const [tags, setTags] = useState<VirtualizedGrouping<Tag> | undefined>(
|
||||
() => useStore.getState().tags
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
(async function () {
|
||||
if (!tags) {
|
||||
await useStore.getState().refresh();
|
||||
setTags(useStore.getState().tags);
|
||||
return;
|
||||
}
|
||||
|
||||
const selected: SelectedReference[] = [];
|
||||
const selectedTags = await db.relations
|
||||
.to({ type: "note", ids: noteIds }, "tag")
|
||||
@@ -76,7 +81,7 @@ function AddTagsDialog(props: AddTagsDialogProps) {
|
||||
});
|
||||
useSelectionStore.getState().setSelected(selected);
|
||||
})();
|
||||
}, [tags, noteIds]);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
@@ -119,7 +124,13 @@ function AddTagsDialog(props: AddTagsDialogProps) {
|
||||
empty: "Add a new tag",
|
||||
filter: "Search or add a new tag"
|
||||
}}
|
||||
filter={(query) => db.lookup.tags(query).ids()}
|
||||
filter={async (query) => {
|
||||
setTags(
|
||||
query
|
||||
? await db.lookup.tags(query).sorted()
|
||||
: useStore.getState().tags
|
||||
);
|
||||
}}
|
||||
onCreateNewItem={async (title) => {
|
||||
const tagId = await db.tags.add({ title });
|
||||
if (!tagId) return;
|
||||
@@ -202,7 +213,3 @@ function SelectedCheck({ id, size = 20 }: { id: string; size?: number }) {
|
||||
<CircleEmpty size={size} sx={{ mr: 1, opacity: 0.4 }} />
|
||||
);
|
||||
}
|
||||
|
||||
function tagHasNotes(tagId: string, noteIds: string[]) {
|
||||
return db.relations.from({ type: "tag", id: tagId }, "note").has(...noteIds);
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ class EditorStore extends BaseStore<EditorStore> {
|
||||
openSession = async (noteId: string, force = false) => {
|
||||
const session = this.get().session;
|
||||
|
||||
if (session.id) await db.fs().cancel(session.id, "download");
|
||||
if (session.id) await db.fs().cancel(session.id);
|
||||
if (session.id === noteId && !force) return;
|
||||
|
||||
if (session.state === SESSION_STATES.unlocked) {
|
||||
@@ -285,7 +285,7 @@ class EditorStore extends BaseStore<EditorStore> {
|
||||
newSession = async (nonce?: string) => {
|
||||
const context = noteStore.get().context;
|
||||
const session = this.get().session;
|
||||
if (session.id) await db.fs().cancel(session.id, "download");
|
||||
if (session.id) await db.fs().cancel(session.id);
|
||||
|
||||
this.set((state) => {
|
||||
state.session = {
|
||||
@@ -302,7 +302,7 @@ class EditorStore extends BaseStore<EditorStore> {
|
||||
|
||||
clearSession = async (shouldNavigate = true) => {
|
||||
const session = this.get().session;
|
||||
if (session.id) await db.fs().cancel(session.id, "download");
|
||||
if (session.id) await db.fs().cancel(session.id);
|
||||
|
||||
this.set((state) => {
|
||||
state.session = {
|
||||
|
||||
@@ -36,7 +36,7 @@ export class AttachmentStream extends ReadableStream<ZipFile> {
|
||||
const counters: Record<string, number> = {};
|
||||
if (signal)
|
||||
signal.onabort = async () => {
|
||||
await db.fs().cancel(GROUP_ID, "download");
|
||||
await db.fs().cancel(GROUP_ID);
|
||||
};
|
||||
|
||||
super({
|
||||
|
||||
@@ -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 { db } from "../../common/db";
|
||||
import { exportNote } from "../../common/export";
|
||||
import { makeUniqueFilename } from "./utils";
|
||||
import { ZipFile } from "./zip-stream";
|
||||
@@ -44,41 +45,18 @@ export class ExportStream extends TransformStream<Note, ZipFile> {
|
||||
|
||||
const { filename, content } = result;
|
||||
|
||||
const notebooks = [
|
||||
...(
|
||||
db.relations
|
||||
?.to({ id: note.id, type: "note" }, "notebook")
|
||||
.resolved() || []
|
||||
).map((n) => ({ title: n.title, topics: [] })),
|
||||
...(note.notebooks || []).map(
|
||||
(ref: { id: string; topics: string[] }) => {
|
||||
const notebook = db.notebooks?.notebook(ref.id);
|
||||
const topics: any[] = notebook?.topics.all || [];
|
||||
const notebooks = await db.relations
|
||||
.to({ id: note.id, type: "note" }, "notebook")
|
||||
.get();
|
||||
|
||||
return {
|
||||
title: notebook?.title,
|
||||
topics: ref.topics
|
||||
.map((topicId: string) =>
|
||||
topics.find((topic) => topic.id === topicId)
|
||||
)
|
||||
.filter(Boolean)
|
||||
};
|
||||
}
|
||||
)
|
||||
];
|
||||
|
||||
const filePaths: Array<string> =
|
||||
notebooks.length > 0
|
||||
? notebooks
|
||||
.map((notebook) => {
|
||||
if (notebook.topics.length > 0)
|
||||
return notebook.topics.map((topic: { title: string }) =>
|
||||
[notebook.title, topic.title, filename].join("/")
|
||||
);
|
||||
return [notebook.title, filename].join("/");
|
||||
})
|
||||
.flat()
|
||||
: [filename];
|
||||
const filePaths: string[] = [];
|
||||
for (const { fromId: notebookId } of notebooks) {
|
||||
const crumbs = (await db.notebooks.breadcrumbs(notebookId)).map(
|
||||
(n) => n.title
|
||||
);
|
||||
filePaths.push([...crumbs, filename].join("/"));
|
||||
}
|
||||
if (filePaths.length <= 0) filePaths.push(filename);
|
||||
|
||||
filePaths.forEach((filePath) => {
|
||||
controller.enqueue({
|
||||
|
||||
Reference in New Issue
Block a user