mirror of
https://github.com/streetwriters/notesnook.git
synced 2025-12-16 11:47:54 +01:00
mobile: sync with latest core changes
This commit is contained in:
committed by
Abdullah Atta
parent
0fcab638a3
commit
c2d11cdc79
@@ -46,15 +46,15 @@ export const FileDownloadStatus = {
|
||||
* Download all user's attachments
|
||||
* @returns
|
||||
*/
|
||||
export function downloadAllAttachments() {
|
||||
const attachments = db.attachments.all;
|
||||
export async function downloadAllAttachments() {
|
||||
const attachments = await db.attachments.all.ids();
|
||||
return downloadAttachments(attachments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Downloads provided attachments to a .zip file
|
||||
* on user's device.
|
||||
* @param attachments
|
||||
* @param {string[]} attachments
|
||||
* @param onProgress
|
||||
* @returns
|
||||
*/
|
||||
@@ -89,8 +89,8 @@ export async function downloadAttachments(
|
||||
await RNFetchBlob.fs.mkdir(zipSourceFolder);
|
||||
|
||||
for (let i = 0; i < attachments.length; i++) {
|
||||
let attachment = attachments[i];
|
||||
const hash = attachment.metadata.hash;
|
||||
let attachment = await db.attachments.attachment(attachments[i]);
|
||||
const hash = attachment.hash;
|
||||
try {
|
||||
if (canceled.current) {
|
||||
RNFetchBlob.fs.unlink(zipSourceFolder).catch(console.log);
|
||||
@@ -114,15 +114,16 @@ export async function downloadAttachments(
|
||||
}
|
||||
if (!uri) throw new Error("Failed to download file");
|
||||
// Move file to the source folder we will zip eventually and rename the file to it's actual name.
|
||||
const filePath = `${zipSourceFolder}/${attachment.metadata.filename}`;
|
||||
const filePath = `${zipSourceFolder}/${attachment.filename}`;
|
||||
await RNFetchBlob.fs.mv(`${cacheDir}/${uri}`, filePath);
|
||||
result.set(hash, {
|
||||
filename: attachment.metadata.filename,
|
||||
status: FileDownloadStatus.Success
|
||||
filename: attachment.filename,
|
||||
status: FileDownloadStatus.Success,
|
||||
attachment: attachment
|
||||
});
|
||||
} catch (e) {
|
||||
result.set(hash, {
|
||||
filename: attachment.metadata.filename,
|
||||
filename: attachment.filename,
|
||||
status: FileDownloadStatus.Fail,
|
||||
reason: e
|
||||
});
|
||||
@@ -208,14 +209,12 @@ export default async function downloadAttachment(
|
||||
try {
|
||||
console.log(
|
||||
"starting download attachment",
|
||||
attachment.metadata.hash,
|
||||
attachment.hash,
|
||||
options.groupId
|
||||
);
|
||||
await db.fs.downloadFile(
|
||||
options.groupId || attachment.metadata.hash,
|
||||
attachment.metadata.hash
|
||||
);
|
||||
|
||||
await db
|
||||
.fs()
|
||||
.downloadFile(options.groupId || attachment.hash, attachment.hash);
|
||||
if (!(await exists(attachment.metadata.hash))) {
|
||||
return;
|
||||
}
|
||||
@@ -228,19 +227,19 @@ export default async function downloadAttachment(
|
||||
}
|
||||
|
||||
let filename = getFileNameWithExtension(
|
||||
attachment.metadata.filename,
|
||||
attachment.metadata.type
|
||||
attachment.filename,
|
||||
attachment.mimeType
|
||||
);
|
||||
|
||||
let key = await db.attachments.decryptKey(attachment.key);
|
||||
let info = {
|
||||
iv: attachment.iv,
|
||||
salt: attachment.salt,
|
||||
length: attachment.length,
|
||||
length: attachment.size,
|
||||
alg: attachment.alg,
|
||||
hash: attachment.metadata.hash,
|
||||
hashType: attachment.metadata.hashType,
|
||||
mime: attachment.metadata.type,
|
||||
hash: attachment.hash,
|
||||
hashType: attachment.hashType,
|
||||
mime: attachment.mimeType,
|
||||
fileName: options.cache ? undefined : filename,
|
||||
uri: options.cache ? undefined : folder.uri,
|
||||
chunkSize: attachment.chunkSize,
|
||||
@@ -263,11 +262,11 @@ export default async function downloadAttachment(
|
||||
|
||||
if (
|
||||
attachment.dateUploaded &&
|
||||
!isImage(attachment.metadata?.type) &&
|
||||
!isDocument(attachment.metadata?.type)
|
||||
!isImage(attachment.mimeType) &&
|
||||
!isDocument(attachment.mimeType)
|
||||
) {
|
||||
RNFetchBlob.fs
|
||||
.unlink(RNFetchBlob.fs.dirs.CacheDir + `/${attachment.metadata.hash}`)
|
||||
.unlink(RNFetchBlob.fs.dirs.CacheDir + `/${attachment.hash}`)
|
||||
.catch(console.log);
|
||||
}
|
||||
if (Platform.OS === "ios" && !options.cache) {
|
||||
@@ -282,7 +281,7 @@ export default async function downloadAttachment(
|
||||
: "File Manager/Notesnook/downloads"
|
||||
}`,
|
||||
icon: "download",
|
||||
context: global ? null : attachment.metadata.hash,
|
||||
context: global ? null : attachment.hash,
|
||||
component: <ShareComponent uri={fileUri} name={filename} padding={12} />
|
||||
});
|
||||
}
|
||||
@@ -292,10 +291,13 @@ export default async function downloadAttachment(
|
||||
console.log("download attachment error: ", e);
|
||||
if (attachment.dateUploaded) {
|
||||
RNFetchBlob.fs
|
||||
.unlink(RNFetchBlob.fs.dirs.CacheDir + `/${attachment.metadata.hash}`)
|
||||
.unlink(RNFetchBlob.fs.dirs.CacheDir + `/${attachment.hash}`)
|
||||
.catch(console.log);
|
||||
RNFetchBlob.fs
|
||||
.unlink(RNFetchBlob.fs.dirs.CacheDir + `/${attachment.hash}_dcache`)
|
||||
.catch(console.log);
|
||||
}
|
||||
useAttachmentStore.getState().remove(attachment.metadata.hash);
|
||||
useAttachmentStore.getState().remove(attachment.hash);
|
||||
if (options.throwError) {
|
||||
throw e;
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ export async function checkAttachment(hash) {
|
||||
const isInternetReachable =
|
||||
internetState.isConnected && internetState.isInternetReachable;
|
||||
if (!isInternetReachable) return { success: true };
|
||||
const attachment = db.attachments.attachment(hash);
|
||||
const attachment = await db.attachments.attachment(hash);
|
||||
if (!attachment) return { failed: "Attachment not found." };
|
||||
|
||||
try {
|
||||
|
||||
@@ -35,14 +35,10 @@ export async function readEncrypted(filename, key, cipherData) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const attachment = db.attachments.attachment(filename);
|
||||
const isPng = !attachment.metadata.type
|
||||
? false
|
||||
: /(png)/g.test(attachment?.metadata.type);
|
||||
const isJpeg = !attachment.metadata.type
|
||||
? false
|
||||
: /(jpeg|jpg)/g.test(attachment?.metadata.type);
|
||||
|
||||
const attachment = await db.attachments.attachment(filename);
|
||||
const isPng = /(png)/g.test(attachment?.mimeType || "");
|
||||
const isJpeg = /(jpeg|jpg)/g.test(attachment?.mimeType || "");
|
||||
console.log("decrypting....");
|
||||
let output = await Sodium.decryptFile(
|
||||
key,
|
||||
{
|
||||
@@ -194,10 +190,10 @@ export async function exists(filename) {
|
||||
}
|
||||
|
||||
if (exists || existsInAppGroup) {
|
||||
const attachment = db.attachments.attachment(filename);
|
||||
const totalChunks = Math.ceil(attachment.length / attachment.chunkSize);
|
||||
const attachment = await db.attachments.attachment(filename);
|
||||
const totalChunks = Math.ceil(attachment.size / attachment.chunkSize);
|
||||
const totalAbytes = totalChunks * ABYTES;
|
||||
const expectedFileSize = attachment.length + totalAbytes;
|
||||
const expectedFileSize = attachment.size + totalAbytes;
|
||||
|
||||
const stat = await RNFetchBlob.fs.stat(
|
||||
existsInAppGroup ? appGroupPath : path
|
||||
|
||||
@@ -87,12 +87,9 @@ export async function uploadFile(filename, data, cancelToken) {
|
||||
DatabaseLogger.info(
|
||||
`File upload status: ${filename}, ${status}, ${text}`
|
||||
);
|
||||
let attachment = db.attachments.attachment(filename);
|
||||
let attachment = await db.attachments.attachment(filename);
|
||||
if (!attachment) return result;
|
||||
if (
|
||||
!isImage(attachment.metadata.type) &&
|
||||
!isDocument(attachment.metadata?.type)
|
||||
) {
|
||||
if (!isImage(attachment.mimeType) && !isDocument(attachment.mimeType)) {
|
||||
RNFetchBlob.fs.unlink(`${cacheDir}/${filename}`).catch(console.log);
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -63,7 +63,7 @@ const DownloadAttachments = ({
|
||||
canceled.current = false;
|
||||
groupId.current = Date.now().toString();
|
||||
const result = await downloadAttachments(
|
||||
attachments,
|
||||
await attachments.ids(),
|
||||
(progress: number, statusText: string) =>
|
||||
setProgress({ value: progress, statusText }),
|
||||
canceled,
|
||||
@@ -89,29 +89,21 @@ const DownloadAttachments = ({
|
||||
groupId.current = undefined;
|
||||
};
|
||||
|
||||
const successResults = () => {
|
||||
const results = [];
|
||||
for (const [key, value] of result.entries()) {
|
||||
if (value.status === 1) results.push(db.attachments.attachment(key));
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
const failedResults = () => {
|
||||
const results = [];
|
||||
for (const [key, value] of result.entries()) {
|
||||
if (value.status === 0) results.push(db.attachments.attachment(key));
|
||||
for (const value of result.values()) {
|
||||
if (value.status === 0) results.push(value.attachment);
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
function getResultText() {
|
||||
const downloadedAttachmentsCount =
|
||||
attachments?.ids?.length - failedResults().length;
|
||||
attachments?.placeholders?.length - failedResults().length;
|
||||
if (downloadedAttachmentsCount === 0)
|
||||
return "Failed to download all attachments";
|
||||
return `Successfully downloaded ${downloadedAttachmentsCount}/${
|
||||
attachments?.ids.length
|
||||
attachments?.placeholders.length
|
||||
} attachments as a zip file at ${
|
||||
Platform.OS === "android" ? "the selected folder" : "Notesnook/downloads"
|
||||
}`;
|
||||
@@ -174,7 +166,9 @@ const DownloadAttachments = ({
|
||||
animated={true}
|
||||
useNativeDriver
|
||||
progress={
|
||||
progress.value ? progress.value / attachments.ids?.length : 0
|
||||
progress.value
|
||||
? progress.value / attachments.placeholders?.length
|
||||
: 0
|
||||
}
|
||||
unfilledColor={colors.secondary.background}
|
||||
color={colors.primary.accent}
|
||||
@@ -192,7 +186,7 @@ const DownloadAttachments = ({
|
||||
borderRadius: 5,
|
||||
marginVertical: 12
|
||||
}}
|
||||
data={downloading ? attachments.ids : undefined}
|
||||
data={downloading ? attachments.placeholders : undefined}
|
||||
ListEmptyComponent={
|
||||
<View
|
||||
style={{
|
||||
@@ -207,7 +201,7 @@ const DownloadAttachments = ({
|
||||
</Paragraph>
|
||||
</View>
|
||||
}
|
||||
keyExtractor={(item, index) => "attachment" + index}
|
||||
keyExtractor={(index) => "attachment" + index}
|
||||
renderItem={({ index }) => {
|
||||
return (
|
||||
<AttachmentItem
|
||||
|
||||
@@ -92,13 +92,13 @@ export const AttachmentDialog = ({ note }: { note?: Note }) => {
|
||||
}, 300);
|
||||
};
|
||||
|
||||
const renderItem = ({ item }: { item: string | number }) => (
|
||||
const renderItem = ({ index }: { item: boolean; index: number }) => (
|
||||
<AttachmentItem
|
||||
setAttachments={() => {
|
||||
setAttachments(filterAttachments(currentFilter));
|
||||
}}
|
||||
attachments={attachments}
|
||||
id={item}
|
||||
id={index}
|
||||
context="attachments-list"
|
||||
/>
|
||||
);
|
||||
@@ -106,10 +106,10 @@ export const AttachmentDialog = ({ note }: { note?: Note }) => {
|
||||
const onCheck = async () => {
|
||||
if (!attachments) return;
|
||||
setLoading(true);
|
||||
for (const id of attachments.ids) {
|
||||
const attachment = (await attachments.item(id))?.item;
|
||||
if (!attachment) continue;
|
||||
|
||||
for (let i = 0; i < attachments.placeholders.length; i++) {
|
||||
const attachment = (await attachments.item(i))?.item;
|
||||
if (!attachment) continue;
|
||||
const result = await filesystem.checkAttachment(attachment.hash);
|
||||
if (result.failed) {
|
||||
await db.attachments.markAsFailed(attachment.hash, result.failed);
|
||||
@@ -310,7 +310,7 @@ export const AttachmentDialog = ({ note }: { note?: Note }) => {
|
||||
/>
|
||||
}
|
||||
estimatedItemSize={50}
|
||||
data={attachments?.ids}
|
||||
data={attachments?.placeholders}
|
||||
renderItem={renderItem}
|
||||
/>
|
||||
|
||||
|
||||
@@ -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 React, { useEffect, useRef, useState } from "react";
|
||||
import React, { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { Dimensions, TextInput, View } from "react-native";
|
||||
import {
|
||||
addOrientationListener,
|
||||
@@ -85,7 +85,7 @@ const PDFPreview = () => {
|
||||
return () => {
|
||||
eUnSubscribeEvent("PDFPreview", open);
|
||||
};
|
||||
}, []);
|
||||
}, [open]);
|
||||
|
||||
const onOrientationChange = (o) => {
|
||||
if (o.includes("LANDSCAPE")) {
|
||||
@@ -102,23 +102,26 @@ const PDFPreview = () => {
|
||||
};
|
||||
}, []);
|
||||
|
||||
const open = async (attachment) => {
|
||||
setVisible(true);
|
||||
setLoading(true);
|
||||
setTimeout(async () => {
|
||||
setAttachment(attachment);
|
||||
let hash = attachment.metadata.hash;
|
||||
if (!hash) return;
|
||||
const uri = await downloadAttachment(hash, false, {
|
||||
silent: true,
|
||||
cache: true
|
||||
});
|
||||
const path = `${cacheDir}/${uri}`;
|
||||
snapshotValue.current = snapshot.current;
|
||||
setPDFSource("file://" + path);
|
||||
setLoading(false);
|
||||
}, 100);
|
||||
};
|
||||
const open = useCallback(
|
||||
async (attachment) => {
|
||||
setVisible(true);
|
||||
setLoading(true);
|
||||
setTimeout(async () => {
|
||||
setAttachment(attachment);
|
||||
let hash = attachment.hash;
|
||||
if (!hash) return;
|
||||
const uri = await downloadAttachment(hash, false, {
|
||||
silent: true,
|
||||
cache: true
|
||||
});
|
||||
const path = `${cacheDir}/${uri}`;
|
||||
snapshotValue.current = snapshot.current;
|
||||
setPDFSource("file://" + path);
|
||||
setLoading(false);
|
||||
}, 100);
|
||||
},
|
||||
[snapshot]
|
||||
);
|
||||
|
||||
const close = () => {
|
||||
setPDFSource(null);
|
||||
@@ -130,7 +133,7 @@ const PDFPreview = () => {
|
||||
if (error?.message === "Password required or incorrect password.") {
|
||||
await sleep(300);
|
||||
presentDialog({
|
||||
context: attachment?.metadata?.hash,
|
||||
context: attachment?.hash,
|
||||
input: true,
|
||||
inputPlaceholder: "Enter password",
|
||||
positiveText: "Unlock",
|
||||
@@ -151,8 +154,8 @@ const PDFPreview = () => {
|
||||
return (
|
||||
visible && (
|
||||
<BaseDialog animation="fade" visible={true} onRequestClose={close}>
|
||||
<SheetProvider context={attachment?.metadata?.hash} />
|
||||
<Dialog context={attachment?.metadata?.hash} />
|
||||
<SheetProvider context={attachment?.hash} />
|
||||
<Dialog context={attachment?.hash} />
|
||||
|
||||
<View
|
||||
style={{
|
||||
@@ -261,7 +264,7 @@ const PDFPreview = () => {
|
||||
color={colors.static.white}
|
||||
name="download"
|
||||
onPress={() => {
|
||||
downloadAttachment(attachment.metadata.hash, false);
|
||||
downloadAttachment(attachment.hash, false);
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
|
||||
@@ -155,7 +155,7 @@ export default function List(props: ListProps) {
|
||||
style={styles}
|
||||
ref={scrollRef}
|
||||
testID={notesnook.list.id}
|
||||
data={props.data?.ids || []}
|
||||
data={props.data?.placeholders || []}
|
||||
renderItem={renderItem}
|
||||
onScroll={onListScroll}
|
||||
nestedScrollEnabled={true}
|
||||
|
||||
@@ -19,13 +19,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { Item, ItemType, VirtualizedGrouping } from "@notesnook/core";
|
||||
import { useThemeColors } from "@notesnook/theme";
|
||||
import React, { useCallback, useEffect } from "react";
|
||||
import React, { useEffect } from "react";
|
||||
import {
|
||||
BackHandler,
|
||||
NativeEventSubscription,
|
||||
Platform,
|
||||
View
|
||||
} from "react-native";
|
||||
import Animated, { FadeInUp } from "react-native-reanimated";
|
||||
import { db } from "../../common/database";
|
||||
import useGlobalSafeAreaInsets from "../../hooks/use-global-safe-area-insets";
|
||||
import { ToastManager } from "../../services/event-manager";
|
||||
@@ -43,7 +44,6 @@ import ExportNotesSheet from "../sheets/export-notes";
|
||||
import ManageTagsSheet from "../sheets/manage-tags";
|
||||
import { IconButton } from "../ui/icon-button";
|
||||
import Heading from "../ui/typography/heading";
|
||||
import Animated, { FadeInUp } from "react-native-reanimated";
|
||||
|
||||
export const SelectionHeader = React.memo(
|
||||
({
|
||||
@@ -65,8 +65,7 @@ export const SelectionHeader = React.memo(
|
||||
const clearSelection = useSelectionStore((state) => state.clearSelection);
|
||||
const insets = useGlobalSafeAreaInsets();
|
||||
const allSelected =
|
||||
items?.ids?.filter((id) => typeof id === "string").length ===
|
||||
selectedItemsList.length;
|
||||
items?.placeholders?.length === selectedItemsList.length;
|
||||
const focusedRouteId = useNavigationStore((state) => state.focusedRouteId);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -200,15 +199,7 @@ export const SelectionHeader = React.memo(
|
||||
onPress={async () => {
|
||||
useSelectionStore
|
||||
.getState()
|
||||
.setAll(
|
||||
allSelected
|
||||
? []
|
||||
: [
|
||||
...((items?.ids.filter(
|
||||
(id) => typeof id !== "object"
|
||||
) as string[]) || [])
|
||||
]
|
||||
);
|
||||
.setAll(allSelected ? [] : [...((await items?.ids()) || [])]);
|
||||
}}
|
||||
tooltipText="Select all"
|
||||
tooltipPosition={4}
|
||||
|
||||
@@ -31,14 +31,12 @@ import { db } from "../../../common/database";
|
||||
import { presentSheet } from "../../../services/event-manager";
|
||||
import Navigation from "../../../services/navigation";
|
||||
import { ItemSelection } from "../../../stores/item-selection-store";
|
||||
import {
|
||||
useNotebookStore,
|
||||
useNotebooks
|
||||
} from "../../../stores/use-notebook-store";
|
||||
import { useNotebooks } from "../../../stores/use-notebook-store";
|
||||
import { useRelationStore } from "../../../stores/use-relation-store";
|
||||
import { useSelectionStore } from "../../../stores/use-selection-store";
|
||||
import { useSettingStore } from "../../../stores/use-setting-store";
|
||||
import { updateNotebook } from "../../../utils/notebooks";
|
||||
import { SIZE } from "../../../utils/size";
|
||||
import { Dialog } from "../../dialog";
|
||||
import DialogHeader from "../../dialog/dialog-header";
|
||||
import SheetProvider from "../../sheet-provider";
|
||||
@@ -47,7 +45,6 @@ import { IconButton } from "../../ui/icon-button";
|
||||
import Paragraph from "../../ui/typography/paragraph";
|
||||
import { NotebookItem } from "./notebook-item";
|
||||
import { useNotebookItemSelectionStore } from "./store";
|
||||
import { SIZE } from "../../../utils/size";
|
||||
|
||||
async function updateInitialSelectionState(items: string[]) {
|
||||
const relations = await db.relations
|
||||
@@ -144,7 +141,7 @@ const MoveNoteSheet = ({
|
||||
};
|
||||
|
||||
const renderNotebook = useCallback(
|
||||
({ item, index }: { item: string | number; index: number }) => (
|
||||
({ index }: { item: boolean; index: number }) => (
|
||||
<NotebookItem items={notebooks} id={index} index={index} />
|
||||
),
|
||||
[notebooks]
|
||||
@@ -228,7 +225,7 @@ const MoveNoteSheet = ({
|
||||
}}
|
||||
>
|
||||
<FlashList
|
||||
data={notebooks?.ids}
|
||||
data={notebooks?.placeholders}
|
||||
style={{
|
||||
width: "100%"
|
||||
}}
|
||||
|
||||
@@ -146,7 +146,7 @@ export const NotebookItem = ({
|
||||
alignItems: "center"
|
||||
}}
|
||||
>
|
||||
{nestedNotebooks?.ids.length ? (
|
||||
{nestedNotebooks?.placeholders.length ? (
|
||||
<IconButton
|
||||
size={SIZE.xl}
|
||||
color={isSelected ? colors.selected.icon : colors.primary.icon}
|
||||
@@ -240,7 +240,7 @@ export const NotebookItem = ({
|
||||
|
||||
{!expanded
|
||||
? null
|
||||
: nestedNotebooks?.ids.map((id, index) => (
|
||||
: nestedNotebooks?.placeholders.map((id, index) => (
|
||||
<NotebookItem
|
||||
key={item?.id + "_" + index}
|
||||
id={index}
|
||||
|
||||
@@ -115,7 +115,7 @@ const ManageTagsSheet = (props: {
|
||||
});
|
||||
} else {
|
||||
db.tags.all.sorted(db.settings.getGroupOptions("tags")).then((items) => {
|
||||
console.log("items loaded tags", items.ids);
|
||||
console.log("items loaded tags", items.placeholders.length);
|
||||
setTags(items);
|
||||
});
|
||||
}
|
||||
@@ -237,7 +237,7 @@ const ManageTagsSheet = (props: {
|
||||
);
|
||||
|
||||
const renderTag = useCallback(
|
||||
({ item, index }: { item: string | number; index: number }) => (
|
||||
({ index }: { item: boolean; index: number }) => (
|
||||
<TagItem
|
||||
tags={tags as VirtualizedGrouping<Tag>}
|
||||
id={index}
|
||||
@@ -302,7 +302,7 @@ const ManageTagsSheet = (props: {
|
||||
) : null}
|
||||
|
||||
<FlatList
|
||||
data={tags?.ids}
|
||||
data={tags?.placeholders}
|
||||
style={{
|
||||
width: "100%"
|
||||
}}
|
||||
|
||||
@@ -88,7 +88,7 @@ export const MoveNotes = ({
|
||||
);
|
||||
|
||||
const renderItem = React.useCallback(
|
||||
({ index }: { item: string | number; index: number }) => {
|
||||
({ index }: { item: boolean; index: number }) => {
|
||||
return (
|
||||
<SelectableNoteItem
|
||||
id={index}
|
||||
@@ -132,7 +132,7 @@ export const MoveNotes = ({
|
||||
</Paragraph>
|
||||
</View>
|
||||
}
|
||||
data={notes?.ids}
|
||||
data={notes?.placeholders}
|
||||
renderItem={renderItem}
|
||||
/>
|
||||
{selectedNoteIds.length > 0 ? (
|
||||
|
||||
@@ -140,13 +140,7 @@ export const NotebookSheet = () => {
|
||||
loading: "Loading notebook topics"
|
||||
};
|
||||
|
||||
const renderNotebook = ({
|
||||
item,
|
||||
index
|
||||
}: {
|
||||
item: string | number;
|
||||
index: number;
|
||||
}) => (
|
||||
const renderNotebook = ({ index }: { item: boolean; index: number }) => (
|
||||
<NotebookItem
|
||||
items={notebooks}
|
||||
id={index}
|
||||
@@ -403,7 +397,7 @@ export const NotebookSheet = () => {
|
||||
</View>
|
||||
<SelectionContext.Provider value={selectionContext}>
|
||||
<FlashList
|
||||
data={notebooks?.ids}
|
||||
data={notebooks?.placeholders}
|
||||
style={{
|
||||
width: "100%"
|
||||
}}
|
||||
@@ -508,7 +502,7 @@ const NotebookItem = ({
|
||||
alignItems: "center"
|
||||
}}
|
||||
>
|
||||
{nestedNotebooks?.ids.length ? (
|
||||
{nestedNotebooks?.placeholders.length ? (
|
||||
<IconButton
|
||||
size={SIZE.lg}
|
||||
color={isSelected ? colors.selected.icon : colors.primary.icon}
|
||||
@@ -601,7 +595,7 @@ const NotebookItem = ({
|
||||
{!expanded
|
||||
? null
|
||||
: item &&
|
||||
nestedNotebooks?.ids.map((id, index) => (
|
||||
nestedNotebooks?.placeholders.map((id, index) => (
|
||||
<NotebookItem
|
||||
key={item.id + "_" + index}
|
||||
id={index}
|
||||
|
||||
@@ -76,7 +76,7 @@ export const RelationsList = ({
|
||||
|
||||
const [items, setItems] = useState<VirtualizedGrouping<Item>>();
|
||||
|
||||
const hasNoRelations = !items || items?.ids?.length === 0;
|
||||
const hasNoRelations = !items || items?.placeholders?.length === 0;
|
||||
|
||||
useEffect(() => {
|
||||
db.relations?.[relationType]?.(
|
||||
@@ -85,13 +85,12 @@ export const RelationsList = ({
|
||||
)
|
||||
.selector.sorted({
|
||||
sortBy: "dateEdited",
|
||||
sortDirection: "desc",
|
||||
groupBy: "default"
|
||||
sortDirection: "desc"
|
||||
})
|
||||
.then((grouped) => {
|
||||
setItems(grouped);
|
||||
});
|
||||
}, [relationType, referenceType]);
|
||||
}, [relationType, referenceType, item?.id, item?.type]);
|
||||
|
||||
return (
|
||||
<View
|
||||
|
||||
@@ -150,13 +150,13 @@ export default function ReminderNotify({
|
||||
})}
|
||||
</ScrollView>
|
||||
|
||||
{references?.ids && references?.ids?.length > 0 ? (
|
||||
{references?.placeholders && references?.placeholders?.length > 0 ? (
|
||||
<View
|
||||
style={{
|
||||
width: "100%",
|
||||
height:
|
||||
160 * references?.ids?.length < 500
|
||||
? 160 * references?.ids?.length
|
||||
160 * references?.placeholders?.length < 500
|
||||
? 160 * references?.placeholders?.length
|
||||
: 500,
|
||||
borderTopWidth: 1,
|
||||
borderTopColor: colors.secondary.background,
|
||||
|
||||
@@ -235,7 +235,7 @@ const NotebookScreen = ({ route, navigation }: NavigationProps<"Notebook">) => {
|
||||
AddNotebookSheet.present(params.current.item);
|
||||
}}
|
||||
notebook={params.current.item}
|
||||
totalNotes={notes?.ids.length || 0}
|
||||
totalNotes={notes?.placeholders.length || 0}
|
||||
/>
|
||||
}
|
||||
placeholder={{
|
||||
|
||||
@@ -56,8 +56,8 @@ export const Notebooks = ({
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (notebooks?.ids) {
|
||||
if (notebooks?.ids?.length === 0 && !Config.isTesting) {
|
||||
if (notebooks?.placeholders) {
|
||||
if (notebooks?.placeholders?.length === 0 && !Config.isTesting) {
|
||||
Walkthrough.present("notebooks");
|
||||
} else {
|
||||
Walkthrough.update("notebooks");
|
||||
@@ -99,7 +99,9 @@ export const Notebooks = ({
|
||||
headerTitle="Notebooks"
|
||||
/>
|
||||
|
||||
{!notebooks || notebooks.ids.length === 0 || !isFocused ? null : (
|
||||
{!notebooks ||
|
||||
notebooks.placeholders.length === 0 ||
|
||||
!isFocused ? null : (
|
||||
<FloatingButton
|
||||
title="Create a new notebook"
|
||||
onPress={onButtonPress}
|
||||
|
||||
@@ -126,7 +126,7 @@ const NotesPage = ({
|
||||
true
|
||||
)) as VirtualizedGrouping<Note>;
|
||||
|
||||
if (notes.ids.length === 0) setLoadingNotes(false);
|
||||
if (notes.placeholders.length === 0) setLoadingNotes(false);
|
||||
setNotes(notes);
|
||||
await notes.item(0, resolveItems);
|
||||
setLoadingNotes(false);
|
||||
@@ -204,7 +204,8 @@ const NotesPage = ({
|
||||
/>
|
||||
|
||||
{!isMonograph &&
|
||||
((notes?.ids && (notes?.ids?.length || 0) > 0) || isFocused) ? (
|
||||
((notes?.placeholders && (notes?.placeholders?.length || 0) > 0) ||
|
||||
isFocused) ? (
|
||||
<FloatingButton
|
||||
color={accentColor}
|
||||
title="Create a note"
|
||||
|
||||
@@ -65,9 +65,11 @@ export const Search = ({ route, navigation }: NavigationProps<"Search">) => {
|
||||
query,
|
||||
route.params.items as FilteredSelector<Note>
|
||||
).sorted();
|
||||
console.log(`Found ${results.ids?.length} results for ${query}`);
|
||||
console.log(
|
||||
`Found ${results.placeholders?.length} results for ${query}`
|
||||
);
|
||||
setResults(results);
|
||||
if (results.ids?.length === 0) {
|
||||
if (results.placeholders?.length === 0) {
|
||||
setSearchStatus(`No results found for ${query}`);
|
||||
} else {
|
||||
setSearchStatus(undefined);
|
||||
|
||||
@@ -107,7 +107,7 @@ export const Trash = ({ navigation, route }: NavigationProps<"Trash">) => {
|
||||
headerTitle="Trash"
|
||||
/>
|
||||
|
||||
{trash && trash?.ids?.length !== 0 ? (
|
||||
{trash && trash?.placeholders?.length !== 0 ? (
|
||||
<FloatingButton
|
||||
title="Clear all trash"
|
||||
onPress={onPressFloatingButton}
|
||||
|
||||
@@ -173,7 +173,7 @@ const NotebookItem = ({
|
||||
alignItems: "center"
|
||||
}}
|
||||
>
|
||||
{nestedNotebooks?.ids.length ? (
|
||||
{nestedNotebooks?.placeholders.length ? (
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
width: 35,
|
||||
@@ -234,14 +234,14 @@ const NotebookItem = ({
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{nestedNotebooks?.ids?.length && isExpanded ? (
|
||||
{nestedNotebooks?.placeholders?.length && isExpanded ? (
|
||||
<View
|
||||
style={{
|
||||
paddingLeft: level + 1 > 0 && level + 1 < 5 ? 15 : 0,
|
||||
marginTop: 5
|
||||
}}
|
||||
>
|
||||
{nestedNotebooks.ids.map((item, index) => (
|
||||
{nestedNotebooks.placeholders.map((item, index) => (
|
||||
<NotebookItem
|
||||
key={notebook?.id + index}
|
||||
id={index}
|
||||
@@ -396,7 +396,7 @@ export const Search = ({
|
||||
}, [get]);
|
||||
|
||||
const renderItem = React.useCallback(
|
||||
({ index }: { item: string | number; index: number }) =>
|
||||
({ index }: { item: boolean; index: number }) =>
|
||||
mode === "selectNotebooks" ? (
|
||||
<NotebookItem
|
||||
id={index}
|
||||
@@ -509,7 +509,7 @@ export const Search = ({
|
||||
) : null}
|
||||
|
||||
<FlatList
|
||||
data={items?.ids}
|
||||
data={items?.placeholders}
|
||||
keyboardShouldPersistTaps="always"
|
||||
keyboardDismissMode="none"
|
||||
renderItem={renderItem}
|
||||
|
||||
@@ -89,7 +89,7 @@ export async function downloadAttachment<
|
||||
}
|
||||
|
||||
export async function checkAttachment(hash: string) {
|
||||
const attachment = db.attachments.attachment(hash);
|
||||
const attachment = await db.attachments.attachment(hash);
|
||||
if (!attachment) return { failed: "Attachment not found." };
|
||||
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user