mirror of
https://github.com/streetwriters/notesnook.git
synced 2026-09-01 11:39:21 +02:00
Compare commits
8 Commits
v2.4.7
...
fix/tag-re
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c1708260b8 | ||
|
|
45ebf0670f | ||
|
|
9cfaa90232 | ||
|
|
edf4a248ed | ||
|
|
14d7ec6b4e | ||
|
|
cd2ca94c3d | ||
|
|
f1609aaa46 | ||
|
|
851364c0bf |
@@ -81,10 +81,20 @@ function getNotebook(item) {
|
||||
return items;
|
||||
}
|
||||
|
||||
function getTags(item) {
|
||||
const noteTags = item.tags?.slice(0, 3) || [];
|
||||
const tags = [];
|
||||
for (const tagName of noteTags) {
|
||||
const tag = db.tags.tag(tagName);
|
||||
if (!tag) continue;
|
||||
tags.push(tag);
|
||||
}
|
||||
return tags;
|
||||
}
|
||||
|
||||
const NoteItem = ({
|
||||
item,
|
||||
isTrash,
|
||||
tags,
|
||||
dateBy = "dateCreated",
|
||||
noOpen = false
|
||||
}) => {
|
||||
@@ -100,6 +110,7 @@ const NoteItem = ({
|
||||
const reminders = db.relations.from(item, "reminder");
|
||||
const reminder = getUpcomingReminder(reminders);
|
||||
const noteColor = COLORS_NOTE[item.color?.toLowerCase()];
|
||||
const tags = getTags(item);
|
||||
return (
|
||||
<>
|
||||
<View
|
||||
|
||||
@@ -100,7 +100,7 @@ export const openNote = async (item, isTrash, setSelectedItem, isSheet) => {
|
||||
};
|
||||
|
||||
export const NoteWrapper = React.memo(
|
||||
function NoteWrapper({ item, index, tags, dateBy, isSheet }) {
|
||||
function NoteWrapper({ item, index, dateBy, isSheet }) {
|
||||
const isTrash = item.type === "trash";
|
||||
const setSelectedItem = useSelectionStore((state) => state.setSelectedItem);
|
||||
|
||||
@@ -113,7 +113,7 @@ export const NoteWrapper = React.memo(
|
||||
isSheet={isSheet}
|
||||
item={item}
|
||||
>
|
||||
<NoteItem item={item} dateBy={dateBy} tags={tags} isTrash={isTrash} />
|
||||
<NoteItem item={item} dateBy={dateBy} isTrash={isTrash} />
|
||||
</SelectionWrapper>
|
||||
);
|
||||
},
|
||||
@@ -125,10 +125,6 @@ export const NoteWrapper = React.memo(
|
||||
return false;
|
||||
}
|
||||
|
||||
if (JSON.stringify(prev.tags) !== JSON.stringify(next.tags)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (prev.item !== next.item) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -57,25 +57,10 @@ const RenderItem = ({ item, index, type, ...restArgs }) => {
|
||||
const dateBy =
|
||||
groupOptions.sortBy !== "title" ? groupOptions.sortBy : "dateEdited";
|
||||
const totalNotes = getTotalNotes(item);
|
||||
const tags =
|
||||
item.tags
|
||||
?.slice(0, 3)
|
||||
?.map((item) => {
|
||||
let tag = db.tags.tag(item);
|
||||
|
||||
if (!tag) return null;
|
||||
return {
|
||||
title: tag.title,
|
||||
id: tag.id,
|
||||
alias: tag.alias
|
||||
};
|
||||
})
|
||||
.filter((t) => t !== null) || [];
|
||||
|
||||
return (
|
||||
<Item
|
||||
item={item}
|
||||
tags={tags}
|
||||
dateBy={dateBy}
|
||||
index={index}
|
||||
type={type}
|
||||
@@ -168,7 +153,6 @@ const List = ({
|
||||
minWidth: 1
|
||||
};
|
||||
|
||||
const _keyExtractor = (item) => item.id || item.title;
|
||||
const ListView = ScrollComponent ? ScrollComponent : FlashList;
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -170,9 +170,17 @@ export const useActions = ({ close = () => null, item }) => {
|
||||
checkNotifPinned();
|
||||
return;
|
||||
}
|
||||
if (item.locked) return;
|
||||
let html = await db.notes.note(item.id).content();
|
||||
let text = await toTXT(item);
|
||||
if (item.locked) {
|
||||
ToastEvent.show({
|
||||
heading: "Note is locked",
|
||||
type: "error",
|
||||
message: "Locked notes cannot be pinned to notifications",
|
||||
context: "local"
|
||||
});
|
||||
return;
|
||||
}
|
||||
let text = await toTXT(item, false);
|
||||
let html = text.replace(/\n/g, "<br />");
|
||||
Notifications.displayNotification({
|
||||
title: item.title,
|
||||
message: item.headline || text,
|
||||
@@ -373,9 +381,11 @@ export const useActions = ({ close = () => null, item }) => {
|
||||
positivePress: async (value) => {
|
||||
if (!value || value === "" || value.trimStart().length == 0) return;
|
||||
await db.tags.rename(item.id, db.tags.sanitize(value));
|
||||
useTagStore.getState().setTags();
|
||||
useMenuStore.getState().setMenuPins();
|
||||
Navigation.queueRoutesForUpdate();
|
||||
setImmediate(() => {
|
||||
useTagStore.getState().setTags();
|
||||
useMenuStore.getState().setMenuPins();
|
||||
Navigation.queueRoutesForUpdate();
|
||||
});
|
||||
},
|
||||
input: true,
|
||||
defaultValue: alias,
|
||||
@@ -418,24 +428,16 @@ export const useActions = ({ close = () => null, item }) => {
|
||||
? "This reminder will be removed"
|
||||
: "This tag will be removed from all notes.",
|
||||
positivePress: async () => {
|
||||
const routes = [];
|
||||
routes.push(
|
||||
"TaggedNotes",
|
||||
"ColoredNotes",
|
||||
"Notes",
|
||||
"NotesPage",
|
||||
"Reminders",
|
||||
"Favorites"
|
||||
);
|
||||
if (item.type === "reminder") {
|
||||
await db.reminders.remove(item.id);
|
||||
} else {
|
||||
await db.tags.remove(item.id);
|
||||
useTagStore.getState().setTags();
|
||||
routes.push("Tags");
|
||||
}
|
||||
Navigation.queueRoutesForUpdate();
|
||||
useRelationStore.getState().update();
|
||||
setImmediate(() => {
|
||||
useTagStore.getState().setTags();
|
||||
Navigation.queueRoutesForUpdate();
|
||||
useRelationStore.getState().update();
|
||||
});
|
||||
},
|
||||
positiveText: "Delete",
|
||||
positiveType: "errorShade"
|
||||
@@ -497,12 +499,14 @@ export const useActions = ({ close = () => null, item }) => {
|
||||
negativeText: "Cancel",
|
||||
positivePress: async () => {
|
||||
await db.trash.delete(item.id);
|
||||
Navigation.queueRoutesForUpdate();
|
||||
useSelectionStore.getState().setSelectionMode(false);
|
||||
ToastEvent.show({
|
||||
heading: "Permanantly deleted items",
|
||||
type: "success",
|
||||
context: "local"
|
||||
setImmediate(() => {
|
||||
Navigation.queueRoutesForUpdate();
|
||||
useSelectionStore.getState().setSelectionMode(false);
|
||||
ToastEvent.show({
|
||||
heading: "Permanantly deleted items",
|
||||
type: "success",
|
||||
context: "local"
|
||||
});
|
||||
});
|
||||
},
|
||||
positiveType: "errorShade"
|
||||
@@ -520,6 +524,15 @@ export const useActions = ({ close = () => null, item }) => {
|
||||
}
|
||||
|
||||
async function exportNote() {
|
||||
if (item.locked) {
|
||||
ToastEvent.show({
|
||||
heading: "Note is locked",
|
||||
type: "error",
|
||||
message: "Locked notes cannot be exported",
|
||||
context: "local"
|
||||
});
|
||||
return;
|
||||
}
|
||||
ExportNotesSheet.present([item]);
|
||||
}
|
||||
|
||||
@@ -623,7 +636,7 @@ export const useActions = ({ close = () => null, item }) => {
|
||||
id: "pin-to-notifications",
|
||||
title:
|
||||
notifPinned !== null
|
||||
? "Unpin from Notifications"
|
||||
? "Unpin from notifications"
|
||||
: "Pin to notifications",
|
||||
icon: "message-badge-outline",
|
||||
on: notifPinned !== null,
|
||||
|
||||
@@ -20,7 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
import { NativeStackScreenProps } from "@react-navigation/native-stack";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { View } from "react-native";
|
||||
import Animated, { FadeInDown, FadeOutDown } from "react-native-reanimated";
|
||||
import Animated, { FadeInDown } from "react-native-reanimated";
|
||||
import DelayLayout from "../../components/delay-layout";
|
||||
import BaseDialog from "../../components/dialog/base-dialog";
|
||||
import { ProgressBarComponent } from "../../components/ui/svg/lazy";
|
||||
@@ -75,57 +75,55 @@ const Home = ({
|
||||
|
||||
return (
|
||||
<DelayLayout delay={300} type="settings">
|
||||
<View>
|
||||
{loading && (
|
||||
//@ts-ignore // Migrate to typescript required.
|
||||
<BaseDialog animated={false} bounce={false} visible={true}>
|
||||
{loading && (
|
||||
//@ts-ignore // Migrate to typescript required.
|
||||
<BaseDialog animated={false} bounce={false} visible={true}>
|
||||
<View
|
||||
style={{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
backgroundColor: colors.bg,
|
||||
justifyContent: "center",
|
||||
alignItems: "center"
|
||||
}}
|
||||
>
|
||||
<Heading color={colors.pri} size={SIZE.lg}>
|
||||
Logging out
|
||||
</Heading>
|
||||
<Paragraph color={colors.icon}>
|
||||
Please wait while we log out and clear app data.
|
||||
</Paragraph>
|
||||
<View
|
||||
style={{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
backgroundColor: colors.bg,
|
||||
justifyContent: "center",
|
||||
alignItems: "center"
|
||||
flexDirection: "row",
|
||||
width: 100,
|
||||
marginTop: 15
|
||||
}}
|
||||
>
|
||||
<Heading color={colors.pri} size={SIZE.lg}>
|
||||
Logging out
|
||||
</Heading>
|
||||
<Paragraph color={colors.icon}>
|
||||
Please wait while we log out and clear app data.
|
||||
</Paragraph>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
width: 100,
|
||||
marginTop: 15
|
||||
}}
|
||||
>
|
||||
<ProgressBarComponent
|
||||
height={5}
|
||||
width={100}
|
||||
animated={true}
|
||||
useNativeDriver
|
||||
indeterminate
|
||||
indeterminateAnimationDuration={2000}
|
||||
unfilledColor={colors.nav}
|
||||
color={colors.accent}
|
||||
borderWidth={0}
|
||||
/>
|
||||
</View>
|
||||
<ProgressBarComponent
|
||||
height={5}
|
||||
width={100}
|
||||
animated={true}
|
||||
useNativeDriver
|
||||
indeterminate
|
||||
indeterminateAnimationDuration={2000}
|
||||
unfilledColor={colors.nav}
|
||||
color={colors.accent}
|
||||
borderWidth={0}
|
||||
/>
|
||||
</View>
|
||||
</BaseDialog>
|
||||
)}
|
||||
</View>
|
||||
</BaseDialog>
|
||||
)}
|
||||
|
||||
<Animated.FlatList
|
||||
entering={FadeInDown}
|
||||
exiting={FadeOutDown}
|
||||
data={settingsGroups}
|
||||
keyExtractor={keyExtractor}
|
||||
ListFooterComponent={<View style={{ height: 200 }} />}
|
||||
renderItem={renderItem}
|
||||
/>
|
||||
</View>
|
||||
<Animated.FlatList
|
||||
entering={FadeInDown}
|
||||
data={settingsGroups}
|
||||
windowSize={1}
|
||||
keyExtractor={keyExtractor}
|
||||
ListFooterComponent={<View style={{ height: 200 }} />}
|
||||
renderItem={renderItem}
|
||||
/>
|
||||
</DelayLayout>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -42,12 +42,12 @@ export const SectionGroup = ({ item }: { item: SettingSection }) => {
|
||||
color={colors.accent}
|
||||
size={SIZE.xs}
|
||||
>
|
||||
{item.name.toUpperCase()}
|
||||
{(item.name as string).toUpperCase()}
|
||||
</Heading>
|
||||
) : null}
|
||||
|
||||
{item.sections?.map((item) => (
|
||||
<SectionItem key={item.name} item={item} />
|
||||
<SectionItem key={item.name as string} item={item} />
|
||||
))}
|
||||
</View>
|
||||
);
|
||||
|
||||
@@ -87,7 +87,7 @@ export const TrashIntervalSelector = () => {
|
||||
>
|
||||
{[-1, 7, 30, 365].map((item) => (
|
||||
<MenuItem
|
||||
key={item.name}
|
||||
key={item.toString()}
|
||||
onPress={async () => {
|
||||
if (item === -1) {
|
||||
await PremiumService.verify(() => {
|
||||
|
||||
@@ -35,6 +35,7 @@ import { eOnNewTopicAdded } from "../utils/events";
|
||||
import { rootNavigatorRef, tabBarRef } from "../utils/global-refs";
|
||||
import { eSendEvent } from "./event-manager";
|
||||
import SettingsService from "./settings";
|
||||
import SearchService from "./search";
|
||||
|
||||
/**
|
||||
* Routes that should be updated on focus
|
||||
@@ -86,7 +87,8 @@ const routeUpdateFunctions: {
|
||||
ColoredNotes: (params) => eSendEvent("ColoredNotes", params),
|
||||
TopicNotes: (params) => eSendEvent("TopicNotes", params),
|
||||
Monographs: (params) => eSendEvent("Monographs", params),
|
||||
Reminders: () => useReminderStore.getState().setReminders()
|
||||
Reminders: () => useReminderStore.getState().setReminders(),
|
||||
Search: () => SearchService.updateAndSearch()
|
||||
};
|
||||
|
||||
function clearRouteFromQueue(routeName: RouteName) {
|
||||
@@ -113,7 +115,7 @@ function queueRoutesForUpdate(...routesToUpdate: RouteName[]) {
|
||||
: (Object.keys(routeNames) as (keyof RouteParams)[]);
|
||||
const currentScreen = useNavigationStore.getState().currentScreen;
|
||||
if (routes.indexOf(currentScreen.name) > -1) {
|
||||
routeUpdateFunctions[currentScreen.name]();
|
||||
routeUpdateFunctions[currentScreen.name]?.();
|
||||
clearRouteFromQueue(currentScreen.name);
|
||||
// Remove focused screen from queue
|
||||
routes.splice(routes.indexOf(currentScreen.name), 1);
|
||||
@@ -129,7 +131,7 @@ function navigate<T extends RouteName>(
|
||||
useNavigationStore.getState().update(screen, !!params?.canGoBack);
|
||||
if (screen.name === "Notebook") routeUpdateFunctions["Notebook"](params);
|
||||
if (screen.name.endsWith("Notes") && screen.name !== "Notes")
|
||||
routeUpdateFunctions[screen.name](params);
|
||||
routeUpdateFunctions[screen.name]?.(params);
|
||||
//@ts-ignore Not sure how to fix this for now ignore it.
|
||||
rootNavigatorRef.current?.navigate<RouteName>(screen.name, params);
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ let searchInformation = {
|
||||
placeholder: "Search in all notes",
|
||||
data: [],
|
||||
type: "notes",
|
||||
get: () => null
|
||||
get: () => []
|
||||
};
|
||||
|
||||
let keyword = null;
|
||||
|
||||
@@ -145,19 +145,12 @@ export function getTotalNotes(item) {
|
||||
return db.notebooks.notebook(item.id)?.totalNotes || 0;
|
||||
}
|
||||
|
||||
export async function toTXT(note, notitle) {
|
||||
export async function toTXT(note, template = true) {
|
||||
let text;
|
||||
if (note.locked) {
|
||||
text = note.content.data;
|
||||
text = await db.notes.note(note.id).export("txt", note.content, template);
|
||||
} else {
|
||||
text = await db.notes.note(note.id).content();
|
||||
}
|
||||
htmlToText = htmlToText || require("html-to-text");
|
||||
text = htmlToText.convert(text, {
|
||||
selectors: [{ selector: "img", format: "skip" }]
|
||||
});
|
||||
if (!notitle) {
|
||||
text = `${note.title}\n \n ${text}`;
|
||||
text = await db.notes.note(note.id).export("txt", undefined, template);
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
@@ -55,12 +55,13 @@ describe("NOTE TESTS", () => {
|
||||
await prepare();
|
||||
let note = await createNote();
|
||||
await tapById(notesnook.listitem.menu);
|
||||
await tapById("icon-Favorite");
|
||||
await tapById("icon-favorite");
|
||||
await visibleById("icon-star");
|
||||
await navigate("Favorites");
|
||||
await visibleByText(note.body);
|
||||
await sleep(500);
|
||||
await tapById(notesnook.listitem.menu);
|
||||
await tapById("icon-Favorite");
|
||||
await tapById("icon-favorite");
|
||||
await expect(element(by.text(note.body))).not.toBeVisible();
|
||||
await navigate("Notes");
|
||||
});
|
||||
@@ -69,11 +70,11 @@ describe("NOTE TESTS", () => {
|
||||
await prepare();
|
||||
await createNote();
|
||||
await tapById(notesnook.listitem.menu);
|
||||
await tapById("icon-Pin");
|
||||
await tapById("icon-pin");
|
||||
await visibleByText("Pinned");
|
||||
await visibleById("icon-pinned");
|
||||
await tapById(notesnook.listitem.menu);
|
||||
await tapById("icon-Pin");
|
||||
await tapById("icon-pin");
|
||||
expect(element(by.id("icon-pinned"))).not.toBeVisible();
|
||||
});
|
||||
|
||||
@@ -81,11 +82,12 @@ describe("NOTE TESTS", () => {
|
||||
await prepare();
|
||||
await createNote();
|
||||
await tapById(notesnook.listitem.menu);
|
||||
await tapById("icon-PinToNotif");
|
||||
await visibleByText("Unpin from Notifications");
|
||||
await tapById("icon-pin-to-notifications");
|
||||
await visibleByText("Unpin from notifications");
|
||||
await sleep(500);
|
||||
await tapById("icon-PinToNotif");
|
||||
await visibleByText("Pin to Notifications");
|
||||
await tapById("icon-pin-to-notifications");
|
||||
await sleep(500);
|
||||
await visibleByText("Pin to notifications");
|
||||
});
|
||||
|
||||
// it("Copy note", async () => {
|
||||
@@ -100,7 +102,7 @@ describe("NOTE TESTS", () => {
|
||||
await prepare();
|
||||
await createNote();
|
||||
await tapById(notesnook.listitem.menu);
|
||||
await tapById("icon-Export");
|
||||
await tapById("icon-export");
|
||||
await visibleByText("PDF");
|
||||
});
|
||||
|
||||
@@ -122,7 +124,7 @@ describe("NOTE TESTS", () => {
|
||||
await prepare();
|
||||
await createNote();
|
||||
await tapById(notesnook.listitem.menu);
|
||||
await tapById("icon-Delete");
|
||||
await tapById("icon-delete");
|
||||
await navigate("Trash");
|
||||
await tapById(notesnook.listitem.menu);
|
||||
await tapByText("Restore note");
|
||||
|
||||
@@ -17,13 +17,15 @@ 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 { notesnook } from "../test.ids";
|
||||
import {
|
||||
tapById,
|
||||
visibleByText,
|
||||
createNote,
|
||||
prepare,
|
||||
elementById,
|
||||
sleep
|
||||
sleep,
|
||||
tapByText
|
||||
} from "./utils";
|
||||
|
||||
describe("Search", () => {
|
||||
@@ -34,6 +36,10 @@ describe("Search", () => {
|
||||
await sleep(300);
|
||||
await elementById("search-input").typeText("n");
|
||||
await sleep(1000);
|
||||
await tapByText(note.body);
|
||||
await sleep(1000);
|
||||
await device.pressBack();
|
||||
await device.pressBack();
|
||||
await visibleByText(note.body);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -164,7 +164,7 @@ android {
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
multiDexEnabled true
|
||||
versionCode 2041
|
||||
versionCode 2042
|
||||
versionName getNpmVersion()
|
||||
testBuildType System.getProperty('testBuildType', 'debug')
|
||||
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
- Added support for sorting topics in topics sheet
|
||||
- Navigation Bar in app now follows app theme
|
||||
- Splashscreen logo quality in dark mode has been improved
|
||||
- Fix topic title goes into multiple lines if long
|
||||
- Fix reminder date picker not allowing to pick a date from past
|
||||
- New and improved share extension with support for organizing notes
|
||||
with tags & notebooks!
|
||||
- Improved UX for topics sheet in Notebooks
|
||||
- Improved editor performance
|
||||
- Many bug fixes and minor improvements
|
||||
|
||||
Thank you for using Notesnook!
|
||||
@@ -993,7 +993,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 2033;
|
||||
CURRENT_PROJECT_VERSION = 2034;
|
||||
DEVELOPMENT_TEAM = 53CWBG3QUC;
|
||||
ENABLE_BITCODE = NO;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
@@ -1067,7 +1067,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 2.4.10;
|
||||
MARKETING_VERSION = 2.4.11;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
@@ -1097,7 +1097,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = Notesnook/Notesnook.entitlements;
|
||||
CODE_SIGN_IDENTITY = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 2033;
|
||||
CURRENT_PROJECT_VERSION = 2034;
|
||||
DEVELOPMENT_TEAM = 53CWBG3QUC;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
||||
@@ -1170,7 +1170,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 2.4.10;
|
||||
MARKETING_VERSION = 2.4.11;
|
||||
ONLY_ACTIVE_ARCH = NO;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
@@ -1328,7 +1328,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 2033;
|
||||
CURRENT_PROJECT_VERSION = 2034;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = 53CWBG3QUC;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
@@ -1340,7 +1340,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 2.4.10;
|
||||
MARKETING_VERSION = 2.4.11;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.notewidget;
|
||||
@@ -1370,7 +1370,7 @@
|
||||
CODE_SIGN_IDENTITY = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 2033;
|
||||
CURRENT_PROJECT_VERSION = 2034;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = 53CWBG3QUC;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
@@ -1382,7 +1382,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 2.4.10;
|
||||
MARKETING_VERSION = 2.4.11;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.notewidget;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
@@ -1411,7 +1411,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = "Make Note/Make Note.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 2033;
|
||||
CURRENT_PROJECT_VERSION = 2034;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = 53CWBG3QUC;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
@@ -1485,7 +1485,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 2.4.10;
|
||||
MARKETING_VERSION = 2.4.11;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.share;
|
||||
@@ -1515,7 +1515,7 @@
|
||||
CODE_SIGN_IDENTITY = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 2033;
|
||||
CURRENT_PROJECT_VERSION = 2034;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = 53CWBG3QUC;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
@@ -1589,7 +1589,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 2.4.10;
|
||||
MARKETING_VERSION = 2.4.11;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.share;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
- Added support for sorting topics in topics sheet
|
||||
- Fixed topics sheet is hard to swipe up from bottom
|
||||
- Fix topic title goes into multiple lines if long
|
||||
- Fix reminder date picker not allowing to pick a date from past
|
||||
- New and improved share extension with support for organizing notes
|
||||
with tags & notebooks!
|
||||
- Improved UX for Topics sheet in Notebooks
|
||||
- Improved editor performance
|
||||
- Many bug fixes and minor improvements
|
||||
|
||||
Thank you for using Notesnook!
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@notesnook/mobile",
|
||||
"version": "2.4.10",
|
||||
"version": "2.4.11",
|
||||
"private": true,
|
||||
"license": "GPL-3.0-or-later",
|
||||
"workspaces": [
|
||||
@@ -34,4 +34,4 @@
|
||||
"@notesnook/editor": "*",
|
||||
"@notesnook/editor-mobile": "*"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -57,7 +57,7 @@ export async function exportNotes(
|
||||
if (format === "pdf") {
|
||||
const note = db.notes?.note(noteIds[0]);
|
||||
if (!note) return false;
|
||||
const html = await note.export("html", null);
|
||||
const html = await note.export("html");
|
||||
if (!html) return false;
|
||||
return await exportToPDF(note.title, html);
|
||||
}
|
||||
@@ -73,7 +73,7 @@ export async function exportNotes(
|
||||
text: `Exporting "${note.title}"...`
|
||||
});
|
||||
|
||||
const content = await note.export(format, null).catch((e: Error) => {
|
||||
const content = await note.export(format).catch((e: Error) => {
|
||||
showToast("error", e.message);
|
||||
});
|
||||
if (!content) continue;
|
||||
|
||||
@@ -162,7 +162,6 @@ function TipTap(props: TipTapProps) {
|
||||
isMobile: isMobile || false,
|
||||
element: editorContainer,
|
||||
editable: !readonly,
|
||||
parseOptions: { preserveWhitespace: "full" },
|
||||
content,
|
||||
autofocus: "start",
|
||||
onFocus,
|
||||
@@ -383,7 +382,7 @@ function toIEditor(editor: Editor): IEditor {
|
||||
tr.setMeta("preventSave", true);
|
||||
return true;
|
||||
})
|
||||
.setContent(content, true, { preserveWhitespace: "full" })
|
||||
.setContent(content, true, { preserveWhitespace: true })
|
||||
.setTextSelection({
|
||||
from,
|
||||
to
|
||||
|
||||
@@ -79,10 +79,12 @@ export default class Note {
|
||||
/**
|
||||
*
|
||||
* @param {"html"|"md"|"txt"} format - Format to export into
|
||||
* @param {string?} rawContent - Use this raw content instead of generating itself
|
||||
* @param {string} [contentItem=undefined]
|
||||
* @param {boolean} [template=true]
|
||||
* @param {string} [rawHTML=undefined] rawHTML - Use this raw content instead of generating itself
|
||||
* @returns {Promise<string | false | undefined>}
|
||||
*/
|
||||
async export(to = "html", rawContent) {
|
||||
async export(to = "html", contentItem, template = true, rawHTML) {
|
||||
if (to !== "txt" && !(await checkIsUserPremium(CHECK_IDS.noteExport)))
|
||||
return false;
|
||||
|
||||
@@ -94,7 +96,8 @@ export default class Note {
|
||||
createdOn: formatDate(this.data.dateCreated),
|
||||
tags: this.tags.join(", ")
|
||||
};
|
||||
const contentItem = await this._db.content.raw(this._note.contentId);
|
||||
contentItem =
|
||||
contentItem || (await this._db.content.raw(this._note.contentId));
|
||||
if (!contentItem) return false;
|
||||
const { data, type } = await this._db.content.downloadMedia(
|
||||
`export-${this.id}`,
|
||||
@@ -105,14 +108,20 @@ export default class Note {
|
||||
|
||||
switch (to) {
|
||||
case "html":
|
||||
templateData.content = rawContent || content.toHTML();
|
||||
return HTMLBuilder.buildHTML(templateData);
|
||||
templateData.content = rawHTML || content.toHTML();
|
||||
return template
|
||||
? HTMLBuilder.buildHTML(templateData)
|
||||
: templateData.content;
|
||||
case "txt":
|
||||
templateData.content = rawContent || content.toTXT();
|
||||
return TextBuilder.buildText(templateData);
|
||||
templateData.content = rawHTML || content.toTXT();
|
||||
return template
|
||||
? TextBuilder.buildText(templateData)
|
||||
: templateData.content;
|
||||
case "md":
|
||||
templateData.content = rawContent || content.toMD();
|
||||
return MarkdownBuilder.buildMarkdown(templateData);
|
||||
templateData.content = rawHTML || content.toMD();
|
||||
return template
|
||||
? MarkdownBuilder.buildMarkdown(templateData)
|
||||
: templateData.content;
|
||||
default:
|
||||
throw new Error("Export format not supported.");
|
||||
}
|
||||
|
||||
@@ -102,7 +102,6 @@ const Tiptap = ({
|
||||
editorProps: {
|
||||
editable: () => !settings.readonly
|
||||
},
|
||||
parseOptions: { preserveWhitespace: "full" },
|
||||
content: global.editorController?.content?.current,
|
||||
isMobile: true,
|
||||
isKeyboardOpen: settings.keyboardShown,
|
||||
|
||||
@@ -118,7 +118,7 @@ export function useEditorController(update: () => void): EditorController {
|
||||
if (!editor) break;
|
||||
const { from, to } = editor.state.selection;
|
||||
editor?.commands.setContent(htmlContentRef.current, false, {
|
||||
preserveWhitespace: "full"
|
||||
preserveWhitespace: true
|
||||
});
|
||||
editor.commands.setTextSelection({
|
||||
from,
|
||||
|
||||
@@ -630,7 +630,7 @@ function indentOnEnter(editor: Editor, $from: ResolvedPos, options: Indent) {
|
||||
return editor
|
||||
.chain()
|
||||
.insertContent(`${newline}${indentation}`, {
|
||||
parseOptions: { preserveWhitespace: "full" }
|
||||
parseOptions: { preserveWhitespace: true }
|
||||
})
|
||||
.focus()
|
||||
.run();
|
||||
|
||||
@@ -57,7 +57,7 @@ test("codeblocks should get highlighted after pasting", async () => {
|
||||
});
|
||||
|
||||
editor.commands.setContent(CODEBLOCKS_HTML, true, {
|
||||
preserveWhitespace: "full"
|
||||
preserveWhitespace: true
|
||||
});
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
|
||||
@@ -241,7 +241,8 @@ const useTiptap = (
|
||||
editor.storage.portalProviderAPI = PortalProviderAPI;
|
||||
if (onBeforeCreate) onBeforeCreate({ editor });
|
||||
},
|
||||
injectCSS: false
|
||||
injectCSS: false,
|
||||
parseOptions: { preserveWhitespace: true }
|
||||
}),
|
||||
[
|
||||
onPreviewAttachment,
|
||||
|
||||
@@ -39,7 +39,6 @@ export function createEditor<TNodes extends string>(
|
||||
const editor = new Editor({
|
||||
element,
|
||||
content: initialContent,
|
||||
parseOptions: { preserveWhitespace: "full" },
|
||||
extensions: [
|
||||
StarterKit.configure({
|
||||
bulletList: false,
|
||||
|
||||
Reference in New Issue
Block a user