mobile: update ui

This commit is contained in:
Ammar Ahmed
2026-07-08 11:29:01 +05:00
parent 7a13ed0f07
commit 952be7c7f3
15 changed files with 570 additions and 355 deletions

View File

@@ -78,7 +78,7 @@ export default function DatePickerComponent(props: {
<Button
title={strings.cancel()}
type="secondary"
type="plain-outline"
style={{
width: "100%"
}}

View File

@@ -166,6 +166,13 @@ export const Header = ({
>
{rightButton ? (
<IconButton {...rightButton} color={colors.primary.icon} />
) : !hasSearch ? (
<View
style={{
width: 20,
height: 20
}}
/>
) : null}
{hasSearch ? (

View File

@@ -17,420 +17,312 @@ 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 { useIsFeatureAvailable } from "@notesnook/common";
import {
ContentBlock,
Note,
VirtualizedGrouping,
createInternalLink
} from "@notesnook/core";
import type { LinkAttributes } from "@notesnook/editor";
import { ContentBlock, Note, createInternalLink } from "@notesnook/core";
import { NativeEvents } from "@notesnook/editor-mobile/src/utils/native-events";
import { strings } from "@notesnook/intl";
import { useThemeColors } from "@notesnook/theme";
import React, { useEffect, useRef, useState } from "react";
import { ActivityIndicator, TextInput, View } from "react-native";
import { FlatList } from "react-native-actions-sheet";
import React, { useEffect, useState } from "react";
import { useWindowDimensions, View } from "react-native";
import { ScrollView } from "react-native-actions-sheet";
import { Radius, Spacing } from "../../../common/design/spacing";
import { db } from "../../../common/database";
import { useDBItem } from "../../../hooks/use-db-item";
import { editorController } from "../../../screens/editor/tiptap/utils";
import { presentSheet } from "../../../services/event-manager";
import { AppFontSize, defaultBorderRadius } from "../../../utils/size";
import { DefaultAppStyles } from "../../../utils/styles";
import { presentSheet, ToastManager } from "../../../services/event-manager";
import { getElevationStyle } from "../../../utils/elevation";
import AppIcon from "../../ui/AppIcon";
import { Button } from "../../ui/button";
import Input from "../../ui/input";
import { Pressable } from "../../ui/pressable";
import Heading from "../../ui/typography/heading";
import Paragraph from "../../ui/typography/paragraph";
import Navigation from "../../../services/navigation";
import { useUserStore } from "../../../stores/use-user-store";
const ListNoteItem = ({
id,
items,
onSelectNote
}: {
id: any;
items: VirtualizedGrouping<Note> | undefined;
onSelectNote: any;
}) => {
const [item] = useDBItem(id, "note", items);
return (
<Pressable
onPress={() => {
if (!item) return;
onSelectNote(item as Note);
}}
type={"transparent"}
style={{
paddingVertical: DefaultAppStyles.GAP_VERTICAL,
flexDirection: "row",
width: "100%",
justifyContent: "flex-start",
height: 50
}}
>
<View
style={{
flexShrink: 1
}}
>
<Paragraph numberOfLines={1}>{item?.title}</Paragraph>
</View>
</Pressable>
);
};
type LinkMode = "note" | "paragraphs";
const ListBlockItem = ({
item,
onSelectBlock
const ParagraphItem = ({
block,
selected,
onSelect
}: {
item: ContentBlock;
onSelectBlock: any;
block: ContentBlock;
selected: boolean;
onSelect: (block: ContentBlock) => void;
}) => {
const { colors } = useThemeColors();
const content =
!block.content || block.content.trim() === ""
? strings.linkNoteEmptyBlock()
: block.content.length > 200
? block.content.slice(0, 200) + "..."
: block.content;
return (
<Pressable
onPress={() => {
onSelectBlock(item);
}}
type={"transparent"}
type={selected ? "selected" : "transparent"}
onPress={() => onSelect(block)}
style={{
flexDirection: "row",
width: "100%",
justifyContent: "flex-start",
minHeight: 45
padding: Spacing.LEVEL_2,
borderRadius: Radius.S,
borderWidth: selected ? 0 : 1,
borderColor: colors.secondary.border,
alignItems: "flex-start"
}}
>
<View
style={{
flexDirection: "row",
width: "100%",
columnGap: 10,
alignItems: "flex-start",
borderBottomWidth: 1,
borderBottomColor: colors.primary.border,
paddingVertical: DefaultAppStyles.GAP_VERTICAL_SMALL,
justifyContent: "space-between"
}}
<Paragraph
fontSize="SM"
numberOfLines={2}
color={selected ? colors.primary.heading : colors.primary.paragraph}
>
<Paragraph
style={{
flexShrink: 1
}}
>
{item?.content.length > 200
? item?.content.slice(0, 200) + "..."
: !item.content || item.content.trim() === ""
? strings.linkNoteEmptyBlock()
: item.content}
</Paragraph>
<View
style={{
borderRadius: defaultBorderRadius,
backgroundColor: colors.secondary.background,
height: 25,
minWidth: 25,
alignItems: "center",
justifyContent: "center"
}}
>
<Paragraph color={colors.secondary.paragraph} size={AppFontSize.xs}>
{item.type.toUpperCase()}
</Paragraph>
</View>
</View>
{content}
</Paragraph>
</Pressable>
);
};
export default function LinkNote(props: {
attributes: LinkAttributes;
note: Note;
resolverId: string;
onLinkCreated: () => void;
close?: (ctx?: string) => void;
}) {
const blockLinking = useIsFeatureAvailable("blockLinking");
const { note, resolverId } = props;
const { colors } = useThemeColors();
const query = useRef<string>(undefined);
const [notes, setNotes] = useState<VirtualizedGrouping<Note>>();
const nodesRef = useRef<ContentBlock[]>([]);
const [nodes, setNodes] = useState<ContentBlock[]>([]);
const inputRef = useRef<TextInput>(null);
const [selectedNote, setSelectedNote] = useState<Note>();
const [selectedNodeId, setSelectedNodeId] = useState<string>();
const [blocksLoading, setBlocksLoading] = useState(false);
const { height } = useWindowDimensions();
const blockLinking = useIsFeatureAvailable("blockLinking");
const [mode, setMode] = useState<LinkMode>("note");
const [blocks, setBlocks] = useState<ContentBlock[]>([]);
const [selectedBlockId, setSelectedBlockId] = useState<string>();
useEffect(() => {
db.notes.all.sorted(db.settings.getGroupOptions("notes")).then((notes) => {
setNotes(notes);
});
}, []);
db.notes.contentBlocks(note.id).then((result) => setBlocks(result));
}, [note.id]);
const onChange = async (value: string) => {
query.current = value;
if (!selectedNote) {
const notes = await db.lookup.notes(value).sorted();
setNotes(notes);
} else {
if (value.startsWith("#")) {
const headingNodes = nodesRef.current.filter((n) =>
n.type.match(/(h1|h2|h3|h4|h5|h6)/g)
);
setNodes(
headingNodes.filter((n) => n.content.includes(value.slice(1)))
);
} else {
setNodes(nodesRef.current.filter((n) => n.content.includes(value)));
}
}
};
const onCreateLink = (blockId?: string) => {
if (!selectedNote) return;
const onAddLink = () => {
const blockId = mode === "paragraphs" ? selectedBlockId : undefined;
const link = createInternalLink(
"note",
selectedNote.id,
blockId
? {
blockId: blockId
}
: undefined
note.id,
blockId ? { blockId } : undefined
);
editorController.current?.postMessage(NativeEvents.resolve, {
data: {
href: link,
title: selectedNote.title
title: note.title
},
resolverId: props.resolverId
resolverId
});
};
const onSelectNote = async (note: Note) => {
setSelectedNote(note);
setBlocksLoading(true);
inputRef.current?.clear();
setTimeout(async () => {
nodesRef.current = await db.notes.contentBlocks(note.id);
setNodes(nodesRef.current);
setBlocksLoading(false);
});
// Fetch and set note's nodes.
};
const onSelectBlock = (block: ContentBlock) => {
onCreateLink(block.id);
props.onLinkCreated();
props.close?.();
props.onLinkCreated();
ToastManager.show({
message: strings.linkAdded(),
type: "success",
context: "global"
});
};
return (
<View
style={{
paddingHorizontal: DefaultAppStyles.GAP,
paddingBottom: DefaultAppStyles.GAP,
minHeight: "100%",
maxHeight: "100%"
width: "100%",
backgroundColor: colors.primary.background,
borderTopLeftRadius: 35,
borderTopRightRadius: 35,
paddingHorizontal: Spacing.LEVEL_3,
paddingTop: Spacing.LEVEL_2,
paddingBottom: Spacing.LEVEL_2,
gap: Spacing.LEVEL_4
}}
>
<View
style={{
flexDirection: "column",
width: "100%",
alignItems: "flex-start",
gap: 10
}}
>
<Input
placeholder={
selectedNote
? strings.searchSectionToLinkPlaceholder()
: strings.searchNoteToLinkPlaceholder()
}
containerStyle={{
width: "100%"
}}
marginBottom={0}
onChangeText={(value) => {
onChange(value);
}}
/>
{selectedNote ? (
<View
style={{
gap: 10
}}
>
<Paragraph color={colors.secondary.paragraph} size={AppFontSize.xs}>
{strings.linkNoteSelectedNote()}
</Paragraph>
<Pressable
onPress={() => {
setSelectedNote(undefined);
setSelectedNodeId(undefined);
setNodes([]);
}}
style={{
flexDirection: "row",
width: "100%",
justifyContent: "flex-start",
height: 45,
borderWidth: 1,
borderColor: colors.primary.accent,
paddingHorizontal: DefaultAppStyles.GAP
}}
type="secondaryAccented"
>
<View
style={{
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
width: "100%"
}}
>
<Paragraph
style={{
flexShrink: 1
}}
numberOfLines={1}
>
{selectedNote?.title}
</Paragraph>
<Paragraph
color={colors.secondary.paragraph}
size={AppFontSize.xs}
>
{strings.tapToDeselect()}
</Paragraph>
</View>
</Pressable>
{nodes?.length > 0 ? (
<Paragraph
style={{
marginBottom: DefaultAppStyles.GAP_VERTICAL
}}
color={colors.secondary.paragraph}
size={AppFontSize.xs}
>
{strings.linkNoteToSection()}
</Paragraph>
) : null}
</View>
) : null}
<View style={{ gap: Spacing.LEVEL_1 }}>
<Heading fontSize="XL" lineHeight="100%">
{strings.linkOptions()}
</Heading>
<Paragraph fontSize="SM" color={colors.secondary.paragraph}>
{strings.linkOptionsDesc()}
</Paragraph>
</View>
{selectedNote ? (
<FlatList
renderItem={({ item, index }) => (
<ListBlockItem item={item} onSelectBlock={onSelectBlock} />
)}
<View style={{ gap: Spacing.LEVEL_2 }}>
<Heading fontSize="LG" lineHeight="100%">
{strings.selectedNoteLabel()}
</Heading>
<View
style={{
marginTop: DefaultAppStyles.GAP_VERTICAL
backgroundColor: colors.secondary.background,
borderRadius: Radius.XS,
paddingHorizontal: Spacing.LEVEL_2,
paddingVertical: Spacing.LEVEL_3
}}
keyboardShouldPersistTaps="handled"
windowSize={3}
keyExtractor={(item) => item.id}
ListEmptyComponent={
!blockLinking || blocksLoading ? (
<ActivityIndicator size={25} color={colors.primary.accent} />
) : !blockLinking.isAllowed ? (
<View
style={{
gap: DefaultAppStyles.GAP_VERTICAL,
backgroundColor: colors.secondary.background,
padding: DefaultAppStyles.GAP,
borderRadius: defaultBorderRadius,
borderWidth: 0.5,
borderColor: colors.secondary.border,
alignItems: "center"
}}
>
<Paragraph color={colors.secondary.paragraph}>
{blockLinking?.error}
</Paragraph>
<Button
title={strings.upgradePlan()}
style={{
width: "100%"
}}
type="accent"
onPress={() => {
Navigation.navigate("PayWall", {
context: useUserStore.getState().user
? "logged-in"
: "logged-out",
canGoBack: true
});
>
<Paragraph
color={colors.primary.heading}
fontFamily="MEDIUM"
fontSize="SM"
>
{note.title}
</Paragraph>
</View>
</View>
props.close?.();
}}
/>
</View>
) : null
}
data={blockLinking?.isAllowed ? nodes : []}
/>
<View
style={{
flexDirection: "row",
gap: Spacing.LEVEL_2,
backgroundColor: colors.secondary.background,
padding: Spacing.LEVEL_1,
borderRadius: Radius.S
}}
>
{(
[
{ key: "note", label: strings.linkEntireNote() },
{ key: "paragraphs", label: strings.specifyParagraphs() }
] as { key: LinkMode; label: string }[]
).map(({ key, label }) => {
const active = mode === key;
return (
<Pressable
key={key}
type="transparent"
onPress={() => setMode(key)}
style={{
flex: 1,
paddingVertical: Spacing.LEVEL_2,
paddingHorizontal: Spacing.LEVEL_1,
borderRadius: Radius.XS,
backgroundColor: active
? colors.primary.background
: "transparent",
...(active ? getElevationStyle(2) : {})
}}
>
<Heading
fontSize="MD"
style={{ textAlign: "center" }}
color={
active ? colors.primary.accent : colors.secondary.paragraph
}
>
{label}
</Heading>
</Pressable>
);
})}
</View>
{mode === "note" ? (
<View style={{ gap: Spacing.LEVEL_1 }}>
<Paragraph fontFamily="MEDIUM" fontSize="SM">
{strings.linkedReferences()}
</Paragraph>
<View
style={{
flexDirection: "row",
alignItems: "center",
gap: Spacing.LEVEL_1,
padding: Spacing.LEVEL_2,
borderRadius: Radius.S,
borderWidth: 1,
borderColor: colors.secondary.border
}}
>
<View
style={{
width: 40,
height: 40,
borderRadius: Radius.XS,
alignItems: "center",
justifyContent: "center",
backgroundColor: colors.secondary.background
}}
>
<AppIcon
name="file-text"
iconFamily="notesnook"
size={20}
color={colors.primary.icon}
/>
</View>
<Heading fontSize="SM" style={{ flexShrink: 1 }}>
{strings.entireNote()}
</Heading>
</View>
</View>
) : (
<FlatList
renderItem={({ item, index }: any) => (
<ListNoteItem
id={index}
items={notes}
onSelectNote={onSelectNote}
/>
<View style={{ gap: Spacing.LEVEL_3 }}>
<Heading fontSize="LG" lineHeight="100%">
{strings.selectParagraphs()}
</Heading>
{blockLinking?.isAllowed ? (
<ScrollView
nestedScrollEnabled
keyboardShouldPersistTaps="handled"
style={{ maxHeight: height * 0.4 }}
contentContainerStyle={{ gap: Spacing.LEVEL_2 }}
>
{blocks.map((block) => (
<ParagraphItem
key={block.id}
block={block}
selected={selectedBlockId === block.id}
onSelect={(b) => setSelectedBlockId(b.id)}
/>
))}
</ScrollView>
) : (
<View
style={{
gap: Spacing.LEVEL_2,
backgroundColor: colors.secondary.background,
padding: Spacing.LEVEL_3,
borderRadius: Radius.S,
borderWidth: 0.5,
borderColor: colors.secondary.border,
alignItems: "center"
}}
>
<Paragraph color={colors.secondary.paragraph}>
{blockLinking?.error}
</Paragraph>
<Button
title={strings.upgradePlan()}
style={{ width: "100%" }}
type="accent"
/>
</View>
)}
keyboardShouldPersistTaps="handled"
style={{
marginTop: DefaultAppStyles.GAP_VERTICAL
}}
windowSize={3}
data={notes?.placeholders}
/>
</View>
)}
{selectedNote ? (
<Button
style={{
marginTop: DefaultAppStyles.GAP_VERTICAL
}}
title={strings.createLink()}
type="accent"
width="100%"
onPress={() => {
onCreateLink();
props.onLinkCreated();
props.close?.();
}}
/>
) : null}
<Button
title={strings.addLink()}
type="accent"
disabled={
mode === "paragraphs" &&
selectedBlockId === undefined &&
blocks.length !== 0
}
width="100%"
onPress={onAddLink}
/>
</View>
);
}
LinkNote.present = (attributes: LinkAttributes, resolverId: string) => {
let didCreateLink = false;
LinkNote.present = (
note: Note,
resolverId: string,
onLinkCreated: () => void
) => {
presentSheet({
component: (ref, close) => (
<LinkNote
attributes={attributes}
note={note}
resolverId={resolverId}
onLinkCreated={() => {
didCreateLink = true;
}}
onLinkCreated={onLinkCreated}
close={close}
/>
),
onClose: () => {
if (!didCreateLink) {
editorController?.current.commands.dismissCreateInternalLinkRequest(
resolverId
);
}
}
)
});
};

View File

@@ -1177,6 +1177,7 @@ export const useActions = ({
title: strings.references(),
icon: "link-alt",
onPress: () => {
close();
Navigation.navigate("References", {
reference: item as ItemReference
});

View File

@@ -307,6 +307,7 @@ let Attachments: any = null;
let References: any = null;
let NoteHistory: any = null;
let NotePreview: any = null;
let AddReference: any = null;
export const RootNavigation = () => {
const introCompleted = useSettingStore(
(state) => state.settings.introCompleted
@@ -536,6 +537,15 @@ export const RootNavigation = () => {
return NotePreview;
}}
/>
<RootStack.Screen
name="AddReference"
getComponent={() => {
AddReference =
AddReference || require("../screens/add-reference").default;
return AddReference;
}}
/>
</RootStack.Navigator>
</NavigationContainer>
);

View File

@@ -0,0 +1,182 @@
/*
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 { LegendList } from "@legendapp/list";
import { Note, VirtualizedGrouping } from "@notesnook/core";
import { strings } from "@notesnook/intl";
import { useThemeColors } from "@notesnook/theme";
import React, { useEffect, useRef, useState } from "react";
import { View } from "react-native";
import { SafeAreaView } from "react-native-safe-area-context";
import { db } from "../../common/database";
import { Radius, Spacing } from "../../common/design/spacing";
import { Header } from "../../components/header";
import LinkNote from "../../components/sheets/link-note";
import Input from "../../components/ui/input";
import { Pressable } from "../../components/ui/pressable";
import LineSeparator from "../../components/ui/seperator/line-separator";
import { TimeSince } from "../../components/ui/time-since";
import Heading from "../../components/ui/typography/heading";
import { useDBItem } from "../../hooks/use-db-item";
import Navigation, { NavigationProps } from "../../services/navigation";
import { AppFontSize } from "../../utils/size";
import { editorController } from "../editor/tiptap/utils";
const NoteReferenceItem = ({
id,
items,
onSelectNote
}: {
id: number;
items?: VirtualizedGrouping<Note>;
onSelectNote: (note: Note) => void;
}) => {
const { colors } = useThemeColors();
const [item] = useDBItem(id, "note", items);
if (!item) {
return <View style={{ height: 72, marginBottom: Spacing.LEVEL_2 }} />;
}
return (
<Pressable
style={{
flexDirection: "row",
alignItems: "center",
gap: Spacing.LEVEL_2,
borderWidth: 1,
borderColor: colors.secondary.border,
borderRadius: Radius.S,
paddingHorizontal: Spacing.LEVEL_3,
paddingVertical: Spacing.LEVEL_3,
marginBottom: Spacing.LEVEL_2
}}
onPress={() => {
onSelectNote(item);
}}
type="plain"
customSelectedColor={colors.primary.shade}
>
<View style={{ flex: 1, gap: Spacing.LEVEL_0 }}>
<Heading fontSize="MD" color={colors.primary.heading}>
{item.title}
</Heading>
<TimeSince
time={item.dateEdited}
updateFrequency={60000}
style={{
fontSize: AppFontSize.xs,
color: colors.secondary.paragraph
}}
/>
</View>
</Pressable>
);
};
const AddReference = (props: NavigationProps<"AddReference">) => {
const { resolverId } = props.route.params;
const { colors } = useThemeColors();
const [notes, setNotes] = useState<VirtualizedGrouping<Note>>();
const didCreateLink = useRef(false);
useEffect(() => {
db.notes.all.sorted(db.settings.getGroupOptions("notes")).then((notes) => {
setNotes(notes);
});
}, []);
useEffect(() => {
return () => {
if (!didCreateLink.current) {
editorController.current?.commands.dismissCreateInternalLinkRequest(
resolverId
);
}
};
}, [resolverId]);
const onSearch = async (value: string) => {
if (!value) {
setNotes(await db.notes.all.sorted(db.settings.getGroupOptions("notes")));
return;
}
setNotes(await db.lookup.notes(value).sorted());
};
const onSelectNote = (note: Note) => {
LinkNote.present(note, resolverId, () => {
didCreateLink.current = true;
Navigation.goBack();
});
};
return (
<SafeAreaView
style={{ flex: 1, backgroundColor: colors.primary.background }}
>
<Header
renderedInRoute="AddReference"
id="AddReference"
title={strings.linkNote()}
style={{ backgroundColor: colors.primary.background }}
canGoBack
/>
<View
style={{
flex: 1,
paddingHorizontal: Spacing.LEVEL_3,
paddingTop: Spacing.LEVEL_3,
gap: Spacing.LEVEL_3
}}
>
<Input
placeholder={strings.searchNoteToLinkPlaceholder()}
containerStyle={{ width: "100%" }}
marginBottom={0}
onChangeText={onSearch}
button={{
icon: "search",
iconFamily: "notesnook",
color: colors.secondary.icon,
onPress: () => {}
}}
/>
<LineSeparator />
<LegendList
data={notes?.placeholders || []}
extraData={notes}
estimatedItemSize={72}
keyboardShouldPersistTaps="handled"
renderItem={({ index }) => (
<NoteReferenceItem
id={index}
items={notes}
onSelectNote={onSelectNote}
/>
)}
/>
</View>
</SafeAreaView>
);
};
export default AddReference;

View File

@@ -29,6 +29,8 @@ import useNavigationStore from "../../stores/use-navigation-store";
import { db } from "../../common/database";
import { strings } from "@notesnook/intl";
import { useArchived } from "../../stores/use-archived-store";
import LineSeparator from "../../components/ui/seperator/line-separator";
import { Spacing } from "../../common/design/spacing";
export const Archive = ({ navigation, route }: NavigationProps<"Archive">) => {
const [archive, loading, refresh] = useArchived();
@@ -53,6 +55,9 @@ export const Archive = ({ navigation, route }: NavigationProps<"Archive">) => {
canGoBack={false}
hasSearch={true}
id={route.name}
style={{
paddingHorizontal: Spacing.LEVEL_2
}}
onSearch={() => {
Navigation.push("Search", {
placeholder: strings.searchInRoute(route.name),
@@ -63,6 +68,7 @@ export const Archive = ({ navigation, route }: NavigationProps<"Archive">) => {
});
}}
/>
<LineSeparator paddingVertical={Spacing.LEVEL_3} />
<DelayLayout wait={loading}>
<List
data={archive}

View File

@@ -44,7 +44,6 @@ import { AuthMode } from "../../../components/auth/common";
import { Properties } from "../../../components/properties";
import EditorTabs from "../../../components/sheets/editor-tabs";
import { Issue } from "../../../components/sheets/github/issue";
import LinkNote from "../../../components/sheets/link-note";
import PaywallSheet from "../../../components/sheets/paywall";
import TableOfContents from "../../../components/sheets/toc";
import { DDS } from "../../../services/device-detection";
@@ -297,7 +296,8 @@ export const useEditorEvents = (
if (
useNavigationStore.getState().currentRoute === "ManageTags" ||
useNavigationStore.getState().currentRoute === "LinkNotebooks" ||
useNavigationStore.getState().currentRoute === "AddReminder"
useNavigationStore.getState().currentRoute === "AddReminder" ||
useNavigationStore.getState().currentRoute === "AddReference"
) {
Navigation.goBack();
} else {
@@ -771,10 +771,9 @@ export const useEditorEvents = (
break;
}
case EditorEvents.createInternalLink: {
LinkNote.present(
editorMessage.value.attributes,
editorMessage.resolverId as string
);
Navigation.navigate("AddReference", {
resolverId: editorMessage.resolverId as string
});
break;
}

View File

@@ -29,6 +29,8 @@ import { useFavorites } from "../../stores/use-favorite-store";
import useNavigationStore from "../../stores/use-navigation-store";
import { db } from "../../common/database";
import { strings } from "@notesnook/intl";
import LineSeparator from "../../components/ui/seperator/line-separator";
import { Spacing } from "../../common/design/spacing";
export const Favorites = ({
navigation,
@@ -56,6 +58,9 @@ export const Favorites = ({
canGoBack={false}
hasSearch={true}
id={route.name}
style={{
paddingHorizontal: Spacing.LEVEL_2
}}
onSearch={() => {
Navigation.push("Search", {
placeholder: strings.searchInRoute(route.name),
@@ -66,6 +71,9 @@ export const Favorites = ({
});
}}
/>
<LineSeparator paddingVertical={Spacing.LEVEL_3} />
<DelayLayout wait={loading}>
<List
data={favorites}

View File

@@ -32,6 +32,8 @@ import { useSelectionStore } from "../../stores/use-selection-store";
import { useTrash, useTrashStore } from "../../stores/use-trash-store";
import SelectionHeader from "../../components/selection-header";
import { strings } from "@notesnook/intl";
import { Spacing } from "../../common/design/spacing";
import LineSeparator from "../../components/ui/seperator/line-separator";
const onPressFloatingButton = () => {
presentDialog({
@@ -85,6 +87,9 @@ export const Trash = ({ navigation, route }: NavigationProps<"Trash">) => {
id={route.name}
canGoBack={false}
hasSearch={true}
style={{
paddingHorizontal: Spacing.LEVEL_2
}}
onSearch={() => {
Navigation.push("Search", {
placeholder: strings.searchInRoute(route.name),
@@ -94,6 +99,7 @@ export const Trash = ({ navigation, route }: NavigationProps<"Trash">) => {
});
}}
/>
<LineSeparator paddingVertical={Spacing.LEVEL_3} />
<DelayLayout wait={loading}>
<List
data={trash}

View File

@@ -77,7 +77,8 @@ const routeNames = {
Attachments: "Attachments",
References: "References",
NoteHistory: "NoteHistory",
NotePreview: "NotePreview"
NotePreview: "NotePreview",
AddReference: "AddReference"
};
export type NavigationProps<T extends RouteName> = NativeStackScreenProps<

View File

@@ -148,6 +148,9 @@ export interface RouteParams extends ParamListBase {
note: TrashOrItem<Note>;
session?: HistorySession & { session: string };
};
AddReference: {
resolverId: string;
};
}
export type RouteName = keyof RouteParams;

View File

@@ -760,6 +760,10 @@ msgstr "Add color"
msgid "Add key"
msgstr "Add key"
#: src/strings.ts:3001
msgid "Add Link"
msgstr "Add Link"
#: src/strings.ts:933
msgid "Add notebook"
msgstr "Add notebook"
@@ -3035,6 +3039,10 @@ msgstr "Enter your recovery code."
msgid "Enter your username"
msgstr "Enter your username"
#: src/strings.ts:2992
msgid "Entire Note"
msgstr "Entire Note"
#: src/strings.ts:2487
msgid "Error"
msgstr "Error"
@@ -4179,10 +4187,22 @@ msgstr "Line spacing changed"
msgid "Link"
msgstr "Link"
#: src/strings.ts:3002
msgid "Link added"
msgstr "Link added"
#: src/strings.ts:949
msgid "Link copied"
msgstr "Link copied"
#: src/strings.ts:2997
msgid "Link entire note"
msgstr "Link entire note"
#: src/strings.ts:2991
msgid "Link note"
msgstr "Link note"
#: src/strings.ts:969
msgid "Link notebooks"
msgstr "Link notebooks"
@@ -4191,6 +4211,10 @@ msgstr "Link notebooks"
msgid "Link notes"
msgstr "Link notes"
#: src/strings.ts:2993
msgid "Link options"
msgstr "Link options"
#: src/strings.ts:2328
msgid "Link settings"
msgstr "Link settings"
@@ -4219,6 +4243,10 @@ msgstr "Linked"
msgid "Linked notes"
msgstr "Linked notes"
#: src/strings.ts:2999
msgid "Linked References"
msgstr "Linked References"
#: src/strings.ts:1647
msgid "Linking to a specific block is not available for locked notes."
msgstr "Linking to a specific block is not available for locked notes."
@@ -6601,6 +6629,10 @@ msgstr "Select notes to link to \"{title}\""
msgid "Select nth day of the month to repeat the reminder."
msgstr "Select nth day of the month to repeat the reminder."
#: src/strings.ts:3000
msgid "Select paragraphs"
msgstr "Select paragraphs"
#: src/strings.ts:2883
msgid "Select Plan"
msgstr "Select Plan"
@@ -6625,6 +6657,10 @@ msgstr "Select the languages the spell checker should check in."
msgid "Select the release track for Notesnook."
msgstr "Select the release track for Notesnook."
#: src/strings.ts:2994
msgid "Selected note"
msgstr "Selected note"
#: src/strings.ts:236
msgid "SELECTED NOTE"
msgstr "SELECTED NOTE"
@@ -6947,6 +6983,10 @@ msgstr "Spaces"
msgid "Special Offer"
msgstr "Special Offer"
#: src/strings.ts:2998
msgid "Specify paragraphs"
msgstr "Specify paragraphs"
#: src/strings.ts:2187
msgid "Spell check"
msgstr "Spell check"
@@ -8353,6 +8393,10 @@ msgstr "You can create shortcuts of frequently accessed notebooks in the side me
msgid "You can import your notes from most other note taking apps."
msgstr "You can import your notes from most other note taking apps."
#: src/strings.ts:2996
msgid "You can link the entire note or specific parts like paragraphs."
msgstr "You can link the entire note or specific parts like paragraphs."
#: src/strings.ts:1482
msgid "You can multi-select notes and move them to a notebook at once"
msgstr "You can multi-select notes and move them to a notebook at once"

View File

@@ -760,6 +760,10 @@ msgstr ""
msgid "Add key"
msgstr ""
#: src/strings.ts:3001
msgid "Add Link"
msgstr ""
#: src/strings.ts:933
msgid "Add notebook"
msgstr ""
@@ -3024,6 +3028,10 @@ msgstr ""
msgid "Enter your username"
msgstr ""
#: src/strings.ts:2992
msgid "Entire Note"
msgstr ""
#: src/strings.ts:2487
msgid "Error"
msgstr ""
@@ -4159,10 +4167,22 @@ msgstr ""
msgid "Link"
msgstr ""
#: src/strings.ts:3002
msgid "Link added"
msgstr ""
#: src/strings.ts:949
msgid "Link copied"
msgstr ""
#: src/strings.ts:2997
msgid "Link entire note"
msgstr ""
#: src/strings.ts:2991
msgid "Link note"
msgstr ""
#: src/strings.ts:969
msgid "Link notebooks"
msgstr ""
@@ -4171,6 +4191,10 @@ msgstr ""
msgid "Link notes"
msgstr ""
#: src/strings.ts:2993
msgid "Link options"
msgstr ""
#: src/strings.ts:2328
msgid "Link settings"
msgstr ""
@@ -4199,6 +4223,10 @@ msgstr ""
msgid "Linked notes"
msgstr ""
#: src/strings.ts:2999
msgid "Linked References"
msgstr ""
#: src/strings.ts:1647
msgid "Linking to a specific block is not available for locked notes."
msgstr ""
@@ -6573,7 +6601,11 @@ msgstr ""
#: src/strings.ts:355
msgid "Select nth day of the month to repeat the reminder."
msgstr "<<<<<<< HEAD<<<<<<< HEAD<<<<<<< HEAD"
msgstr "<<<<<<< HEAD<<<<<<< HEAD<<<<<<< HEAD<<<<<<< HEAD"
#: src/strings.ts:3000
msgid "Select paragraphs"
msgstr ""
#: src/strings.ts:2883
msgid "Select Plan"
@@ -6599,6 +6631,10 @@ msgstr ""
msgid "Select the release track for Notesnook."
msgstr ""
#: src/strings.ts:2994
msgid "Selected note"
msgstr ""
#: src/strings.ts:236
msgid "SELECTED NOTE"
msgstr ""
@@ -6913,6 +6949,10 @@ msgstr ""
msgid "Special Offer"
msgstr ""
#: src/strings.ts:2998
msgid "Specify paragraphs"
msgstr ""
#: src/strings.ts:2187
msgid "Spell check"
msgstr ""
@@ -8303,6 +8343,10 @@ msgstr ""
msgid "You can import your notes from most other note taking apps."
msgstr ""
#: src/strings.ts:2996
msgid "You can link the entire note or specific parts like paragraphs."
msgstr ""
#: src/strings.ts:1482
msgid "You can multi-select notes and move them to a notebook at once"
msgstr ""

View File

@@ -2987,5 +2987,17 @@ Continue without attachments?`,
reminderPlaceholder: () => t`Never miss a task. Set your first reminder now.`,
emptyLinkedNotes: () => t`Links of notes that are references in this note.`,
emptyReferences: () => t`Links of notes where this note is referenced.`,
passwordProtection: () => t`Password protection (optional)`
passwordProtection: () => t`Password protection (optional)`,
linkNote: () => t`Link note`,
entireNote: () => t`Entire Note`,
linkOptions: () => t`Link options`,
selectedNoteLabel: () => t`Selected note`,
linkOptionsDesc: () =>
t`You can link the entire note or specific parts like paragraphs.`,
linkEntireNote: () => t`Link entire note`,
specifyParagraphs: () => t`Specify paragraphs`,
linkedReferences: () => t`Linked References`,
selectParagraphs: () => t`Select paragraphs`,
addLink: () => t`Add Link`,
linkAdded: () => t`Link added`
};