Compare commits

...

24 Commits

Author SHA1 Message Date
Ammar Ahmed
8d9df5030c mobile: loading note gets stuck 2026-02-05 11:41:54 +05:00
Ammar Ahmed
af014cf8c1 Merge pull request #9297 from streetwriters/fix-toast-context-color-picker
mobile: fix toast context in color picker
2026-02-03 11:48:33 +05:00
Ammar Ahmed
1ddd7b1e6e mobile: fix toast context in color picker 2026-02-03 11:46:32 +05:00
Ammar Ahmed
9ef0179566 Merge pull request #9296 from streetwriters/fix-notebook-header-error
mobile: fix crash when opening notebook (happens randomly)
2026-02-03 11:11:51 +05:00
Ammar Ahmed
38690d18d4 mobile: fix crash when opening notebook (happens randomly) 2026-02-03 11:10:59 +05:00
Abdullah Atta
c07f5393f6 Merge pull request #9266 from streetwriters/release/v3.3.8
Release vNext
2026-01-28 12:42:38 +05:00
Abdullah Atta
406c63721d web: bump version to 3.3.8 2026-01-27 17:24:36 +05:00
Abdullah Atta
97f3e02f59 core: remove .only from note history tests 2026-01-27 12:25:39 +05:00
Abdullah Atta
5c6564f00b core: fix monograph sync tests 2026-01-27 12:20:54 +05:00
Ammar Ahmed
605e75efb3 mobile: fix and update tests 2026-01-27 12:02:20 +05:00
Ammar Ahmed
496f9ba340 ci: update build tools version 2026-01-27 10:59:49 +05:00
Ammar Ahmed
f98283f2dd mobile: update changelog 2026-01-27 10:08:17 +05:00
Ammar Ahmed
2d32e85a64 mobile: refactor 2026-01-27 09:59:43 +05:00
Ammar Ahmed
1a56a22a33 mobile: fix feature not locked 2026-01-26 13:40:51 +05:00
Ammar Ahmed
c85204d0c1 mobile: bump version to 3.3.13 2026-01-26 13:32:28 +05:00
Abdullah Atta
1d8a958eaf editor: update test snapshots 2026-01-26 13:07:35 +05:00
Abdullah Atta
b52f70d57d core: fix reminders tests 2026-01-26 12:49:50 +05:00
Chloe Oletto
12687dae7b core: Fix reminder sorting. (#9242)
Signed off by: Chloe Oletto <NeedsChloesure@riseup.net>
2026-01-22 09:26:27 +05:00
Chloe Oletto
c53c3167d8 web: Fix reminder dialog subtext formatting. (#9241)
Signed-off by: Chloe Oletto <NeedsChloesure@riseup.net>
2026-01-22 09:25:20 +05:00
01zulfi
60df472d53 editor: fix search scroll not working on switching editors or opening new editor (#8061)
* editor: fix search scroll not working on switching editors or opening new editor
Signed-off-by: 01zulfi <85733202+01zulfi@users.noreply.github.com>

* editor: initialize search right after editor is created
Signed-off-by: 01zulfi <85733202+01zulfi@users.noreply.github.com>
2026-01-19 11:59:48 +05:00
01zulfi
67fe25bc8b common: make command palette keybinding same across web & desktop (#9235)
Signed-off-by: 01zulfi <85733202+01zulfi@users.noreply.github.com>
2026-01-17 21:18:52 +05:00
01zulfi
44a7aed308 intl: fix strings with '<<< HEAD' in pseudo-LOCALE.po (#9236)
Signed-off-by: 01zulfi <85733202+01zulfi@users.noreply.github.com>
2026-01-17 12:32:48 +05:00
Ammar Ahmed
f22937e1eb ci: update build tools version 2026-01-17 10:54:44 +05:00
Ammar Ahmed
c816f8b15b mobile: fix ts errors 2026-01-17 09:39:20 +05:00
37 changed files with 170 additions and 4706 deletions

View File

@@ -113,7 +113,7 @@ jobs:
keyStorePassword: ${{ secrets.KEY_PASSWORD }}
keyPassword: ${{ secrets.KEY_PASSWORD }}
env:
BUILD_TOOLS_VERSION: "33.0.0"
BUILD_TOOLS_VERSION: "36.0.0"
- name: Build apks for Github release
run: yarn release:android
@@ -128,7 +128,7 @@ jobs:
keyStorePassword: ${{ secrets.PUBLIC_KEY_PASSWORD }}
keyPassword: ${{ secrets.PUBLIC_KEY_PASSWORD }}
env:
BUILD_TOOLS_VERSION: "33.0.0"
BUILD_TOOLS_VERSION: "36.0.0"
- name: Rename apk files
run: |

View File

@@ -113,7 +113,7 @@ jobs:
keyStorePassword: ${{ secrets.KEY_PASSWORD }}
keyPassword: ${{ secrets.KEY_PASSWORD }}
env:
BUILD_TOOLS_VERSION: "33.0.0"
BUILD_TOOLS_VERSION: "36.0.0"
- name: Build apks for Github release
run: yarn release:android
@@ -128,7 +128,7 @@ jobs:
keyStorePassword: ${{ secrets.PUBLIC_KEY_PASSWORD }}
keyPassword: ${{ secrets.PUBLIC_KEY_PASSWORD }}
env:
BUILD_TOOLS_VERSION: "33.0.0"
BUILD_TOOLS_VERSION: "36.0.0"
- name: Rename apk files
run: |

View File

@@ -1,12 +1,12 @@
{
"name": "@notesnook/desktop",
"version": "3.3.8-beta.1",
"version": "3.3.8",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@notesnook/desktop",
"version": "3.3.8-beta.1",
"version": "3.3.8",
"hasInstallScript": true,
"license": "GPL-3.0-or-later",
"dependencies": {

View File

@@ -2,7 +2,7 @@
"name": "@notesnook/desktop",
"productName": "Notesnook",
"description": "Your private note taking space",
"version": "3.3.8-beta.1",
"version": "3.3.8",
"appAppleId": "1544027013",
"private": true,
"main": "./dist/cjs/index.js",

View File

@@ -125,7 +125,7 @@ android {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
multiDexEnabled true
versionCode 3090
versionCode 3091
versionName getNpmVersion()
testBuildType System.getProperty('testBuildType', 'debug')
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'

View File

@@ -1,11 +1,13 @@
- Add title and date clipped to web clips
- Add notebooks, tags and colors to Home Screen Shortcuts
- Change day format and use /day in notes
- Add Setting to change default editor line height
- Set a custom title for monographs
- Add webpage title and date clipped to web clips
- Configure Week to start from Sunday or Monday
- Change Note's creation date from properties
- Set expiry date for notes for auto-deletion
- Fix tag and notebook properties cannot be accessed from shortcuts
- Fix editor features remain locked after login
- Temporarily disable password changing and forgot password features
- Note history now includes note title changes
- Other minor bug fixes and improvements
- Change Note's creation date
- Set expiry date on notes
- Temporarily disable password change and recovery options
- Note history now includes note title
- Minor bug fixes
Thank you for using Notesnook!

View File

@@ -167,14 +167,16 @@ const ColorPicker = ({
);
if (!title.current)
return ToastManager.error(
new Error(strings.allFieldsRequired())
new Error(strings.allFieldsRequired()),
"color-picker"
);
const exists = await db.colors.all.find((v) =>
v.and([v(`colorCode`, "==", selectedColor)])
);
if (exists)
return ToastManager.error(
new Error(strings.colorExists(selectedColor))
new Error(strings.colorExists(selectedColor)),
"color-picker"
);
const id = await db.colors.add({
title: title.current,

View File

@@ -56,7 +56,7 @@ export default function NotePreview({
content,
note
}: {
session: HistorySession & { session: string };
session?: HistorySession & { session: string };
content:
| Partial<
NoteContent<boolean> & {
@@ -81,24 +81,26 @@ export default function NotePreview({
eSendEvent(eCloseSheet);
return;
}
await db.noteHistory.restore(session.id);
if (useTabStore.getState().hasTabForNote(session?.noteId)) {
const note = editorController.current.note.current[session?.noteId];
if (note) {
eSendEvent(eOnLoadNote, {
item: note,
forced: true
});
if (session) {
await db.noteHistory.restore(session.id);
if (useTabStore.getState().hasTabForNote(session?.noteId)) {
const note = editorController.current.note.current[session?.noteId];
if (note) {
eSendEvent(eOnLoadNote, {
item: note,
forced: true
});
}
}
}
eSendEvent(eCloseSheet, "note_history");
eSendEvent(eCloseSheet);
Navigation.queueRoutesForUpdate();
eSendEvent(eCloseSheet, "note_history");
eSendEvent(eCloseSheet);
Navigation.queueRoutesForUpdate();
ToastManager.show({
heading: strings.noteRestoredFromHistory(),
type: "success"
});
ToastManager.show({
heading: strings.noteRestoredFromHistory(),
type: "success"
});
}
}
useEffect(() => {
@@ -166,7 +168,7 @@ export default function NotePreview({
currentContent?.data || "<p></p>",
content.data as string
),
id: session?.noteId
id: session?.noteId || note.id
});
}
}

View File

@@ -1169,7 +1169,7 @@ export const useActions = ({
id: "expiry-date",
title: item.expiryDate ? strings.unsetExpiry() : strings.setExpiry(),
icon: item.expiryDate ? "bomb-off" : "bomb",
locked: features?.expiringNotes?.isAllowed,
locked: !features?.expiringNotes?.isAllowed,
onPress: async () => {
if (item.expiryDate) {
await db.notes.setExpiryDate(null, item.id);

View File

@@ -73,15 +73,6 @@ const RecurringModes = {
const WeekDays = [0, 1, 2, 3, 4, 5, 6];
const WeekDaysMon = [1, 2, 3, 4, 5, 6, 0];
const MonthDays = new Array(31).fill(true);
const WeekDayNames = {
0: "Sunday",
1: "Monday",
2: "Tuesday",
3: "Wednesday",
4: "Thursday",
5: "Friday",
6: "Saturday"
};
const ReminderNotificationModes = {
Silent: "silent",
@@ -153,7 +144,8 @@ export default function AddReminder(props: NavigationProps<"AddReminder">) {
const isSecondLast = index === selectedDays.length - 2;
const joinWith = isSecondLast ? " & " : isLast ? "" : ", ";
return recurringMode === RecurringModes.Week
? strings.weekDayNames[day as keyof typeof WeekDayNames]() + joinWith
? strings.weekDayNames[day as keyof typeof strings.weekDayNames]() +
joinWith
: `${day}${nth(day)} ${joinWith}`;
})
.join("");

View File

@@ -25,7 +25,8 @@ import React, {
useEffect,
useImperativeHandle,
useLayoutEffect,
useRef
useRef,
useState
} from "react";
import { Platform, ViewStyle } from "react-native";
import WebView from "react-native-webview";
@@ -109,17 +110,20 @@ const Editor = React.memo(
noToolbar,
noHeader
});
const renderKey = useRef(randId("editor-id") + editorId);
const [renderKey, setRenderKey] = useState(
randId("editor-id") + editorId
);
useImperativeHandle(ref, () => ({
get: () => editor
}));
useLockedNoteHandler();
const onError = useCallback(() => {
renderKey.current = randId("editor-id") + editorId;
setRenderKey(randId("editor-id") + editorId);
editor.state.current.ready = false;
editor.state.current.initialLoadCalled = false;
editor.setLoading(true);
}, [editor, editorId]);
}, [editor]);
useEffect(() => {
const sub = [eSubscribeEvent(eEditorReset, onError)];
@@ -144,7 +148,7 @@ const Editor = React.memo(
<WebView
testID={notesnook.editor.id}
ref={editor.ref}
key={renderKey.current}
key={renderKey}
onRenderProcessGone={onError}
nestedScrollEnabled
onError={onError}

View File

@@ -684,8 +684,6 @@ export const useEditor = (
lastContentChangeTime.current[item.id] = item.dateEdited;
currentNotes.current[item.id] = item;
if (!currentNotes.current[item.id]) return;
editorSessionHistory.newSession(item.id);
await commands.setStatus(
@@ -1104,6 +1102,8 @@ export const useEditor = (
if (noteId) {
const note = await db.notes?.note(noteId);
fluidTabsRef.current?.goToPage("editor");
loadNoteMutex.cancel();
loadNoteMutex.release();
if (note) {
loadNote({
item: note
@@ -1111,6 +1111,8 @@ export const useEditor = (
}
} else {
noteId = useTabStore.getState().getCurrentNoteId() || null;
loadNoteMutex.cancel();
loadNoteMutex.release();
if (!noteId) {
loadNote({ newNote: true });
if (fluidTabsRef.current?.page() === "editor") {

View File

@@ -193,11 +193,13 @@ const NotebookScreen = ({ route, navigation }: NavigationProps<"Notebook">) => {
headerTitle={notebook?.title}
loading={loading}
CustomLisHeader={
<NotebookHeader
breadcrumbs={breadcrumbs}
notebook={notebook!}
totalNotes={notes?.placeholders.length || 0}
/>
notebook ? (
<NotebookHeader
breadcrumbs={breadcrumbs}
notebook={notebook}
totalNotes={notes?.placeholders.length || 0}
/>
) : undefined
}
placeholder={{
title: notebook?.title!,

View File

@@ -929,7 +929,6 @@ export const settingsGroups: SettingSection[] = [
hidden: (current) => (current as VaultStatusType)?.exists,
modifer: () => {
openVault({
item: {},
novault: false,
title: strings.createVault()
});
@@ -943,7 +942,6 @@ export const settingsGroups: SettingSection[] = [
hidden: (current) => !(current as VaultStatusType)?.exists,
modifer: () =>
openVault({
item: {},
changePassword: true,
novault: true,
title: strings.changeVaultPassword()
@@ -957,7 +955,6 @@ export const settingsGroups: SettingSection[] = [
hidden: (current) => !(current as VaultStatusType)?.exists,
modifer: () => {
openVault({
item: {},
clearVault: true,
novault: true,
title: strings.clearVault() + "?"
@@ -972,7 +969,6 @@ export const settingsGroups: SettingSection[] = [
hidden: (current) => !(current as VaultStatusType)?.exists,
modifer: () => {
openVault({
item: {},
deleteVault: true,
novault: true,
title: strings.deleteVault() + "?"
@@ -994,7 +990,6 @@ export const settingsGroups: SettingSection[] = [
modifer: (current) => {
const _current = current as VaultStatusType;
openVault({
item: {},
fingerprintAccess: !_current.biometryEnrolled,
revokeFingerprintAccess: _current.biometryEnrolled,
novault: true,

View File

@@ -134,7 +134,7 @@ describe("NOTE TESTS", () => {
.run();
});
it.only("Assign colors to a note", async () => {
it("Assign colors to a note", async () => {
await TestBuilder.create()
.prepare()
.createNote()

View File

@@ -21,7 +21,7 @@ import { notesnook } from "../test.ids";
import { TestBuilder } from "./utils";
describe("Sort & filter", () => {
it("Sort by date-edited/date-created", async () => {
it.only("Sort by date-edited/date-created", async () => {
await TestBuilder.create()
.prepare()
.createNote("Note 1", "Note 1")
@@ -34,7 +34,7 @@ describe("Sort & filter", () => {
.element(by.web.className("ProseMirror"))
.typeText("Edited ", true);
})
.pressBack(2)
.pressBack(1)
.waitAndTapById("icon-sort")
.wait(500)
.waitAndTapByText("Date created")

View File

@@ -1029,7 +1029,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2170;
CURRENT_PROJECT_VERSION = 2171;
DEVELOPMENT_TEAM = 53CWBG3QUC;
ENABLE_BITCODE = NO;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
@@ -1135,7 +1135,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 2170;
CURRENT_PROJECT_VERSION = 2171;
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 53CWBG3QUC;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
@@ -1367,7 +1367,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2170;
CURRENT_PROJECT_VERSION = 2171;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = 53CWBG3QUC;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
@@ -1410,7 +1410,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 2170;
CURRENT_PROJECT_VERSION = 2171;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 53CWBG3QUC;
@@ -1453,7 +1453,7 @@
CODE_SIGN_ENTITLEMENTS = "Make Note/Make Note.entitlements";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2170;
CURRENT_PROJECT_VERSION = 2171;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = 53CWBG3QUC;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
@@ -1565,7 +1565,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 2170;
CURRENT_PROJECT_VERSION = 2171;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 53CWBG3QUC;

View File

@@ -1,12 +1,12 @@
{
"name": "@notesnook/mobile",
"version": "3.3.13-beta.0",
"version": "3.3.13-beta.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@notesnook/mobile",
"version": "3.3.13-beta.0",
"version": "3.3.13-beta.1",
"hasInstallScript": true,
"license": "GPL-3.0-or-later",
"dependencies": {

View File

@@ -1,6 +1,6 @@
{
"name": "@notesnook/mobile",
"version": "3.3.13-beta.1",
"version": "3.3.13",
"private": true,
"license": "GPL-3.0-or-later",
"scripts": {

View File

@@ -987,7 +987,7 @@
},
"../web": {
"name": "@notesnook/web",
"version": "3.3.8-beta.0",
"version": "3.3.8-beta.1",
"hasInstallScript": true,
"license": "GPL-3.0-or-later",
"dependencies": {

View File

@@ -1,12 +1,12 @@
{
"name": "@notesnook/web",
"version": "3.3.8-beta.1",
"version": "3.3.8",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@notesnook/web",
"version": "3.3.8-beta.1",
"version": "3.3.8",
"hasInstallScript": true,
"license": "GPL-3.0-or-later",
"dependencies": {
@@ -507,7 +507,7 @@
},
"../desktop": {
"name": "@notesnook/desktop",
"version": "3.3.8-beta.0",
"version": "3.3.8-beta.1",
"hasInstallScript": true,
"license": "GPL-3.0-or-later",
"dependencies": {

View File

@@ -1,7 +1,7 @@
{
"name": "@notesnook/web",
"description": "Your private note taking space",
"version": "3.3.8-beta.1",
"version": "3.3.8",
"private": true,
"main": "./src/app.js",
"homepage": "https://notesnook.com/",

View File

@@ -509,7 +509,7 @@ export const AddReminderDialog = DialogManager.register(
</Text>
) : (
<Text variant="subBody" sx={{ mt: 1 }}>
{strings.reminderStarts(date.toString(), date.format(timeFormat()))}
{strings.reminderStarts(date.format(db.settings.getDateFormat()), date.format(timeFormat()))}
</Text>
)}
</Dialog>

View File

@@ -22,8 +22,6 @@ import Dialog from "../components/dialog";
import { getHomeRoute, hardNavigate } from "../navigation";
import { appVersion } from "../utils/version";
import Config from "../utils/config";
import { useEffect } from "react";
import { ArrowRight, Checkmark, Icon, Warn } from "../components/icons";
import { BaseDialogProps, DialogManager } from "../common/dialog-manager";
import { strings } from "@notesnook/intl";
@@ -93,23 +91,34 @@ const features: Record<FeatureKeys, Feature> = {
]
: [
{
title: "Wrapped 2025",
title: "Import/export tables as CSV",
subtitle:
"Notesnook Wrapped 2025 is your personal recap of the year you spent with Notesnook. Available throughout December and accessible from the sidebar, it highlights your activity, stats and how you used Notesnook this year."
"You can now import and export CSV files as tables directly in the editor."
},
{
title: "Monograph analytics",
title: "Customizable monograph title",
subtitle:
"Pro users can now see view count analytics for monographs."
"You can now set a custom title for your monographs different from the note title."
},
{
title: "Twitter/X embed support",
subtitle: "Simply paste the post URL in the Insert Embed dialog."
title: "Expiring notes",
subtitle:
"Set an expiration date for your notes after which they will be automatically moved to trash."
},
{
title: "New keyboard shortcuts",
title: "Change note's created date",
subtitle:
"Use Ctrl/Cmd + Alt/Option + F to open search/replace in the editor. We have also added Ctrl/Cmd + Alt/Option + C for toggling text color."
"You can now change a note's created date from the note properties panel."
},
{
title: "Customizable line height",
subtitle:
"You can now customize the line height in the editor from Settings > Editor."
},
{
title: "Change week starting day",
subtitle:
"You can now change the starting day of the week from Settings > Behaviour."
}
],
cta: {

View File

@@ -22,7 +22,7 @@ The following keyboard shortcuts will help you navigate Notesnook faster.
| --- | --- | --- | --- |
| Next tab | Ctrl Alt → / Ctrl Alt ⇧ → | Ctrl tab | ⌘ tab |
| Previous tab | Ctrl Alt ← / Ctrl Alt ⇧ ← | Ctrl ⇧ tab | ⌘ ⇧ tab |
| Command palette | Ctrl ⇧ P / Ctrl ⇧ : | Ctrl ⇧ P | ⌘ ⇧ P |
| Command palette | Ctrl ⇧ P / Ctrl ⇧ : | Ctrl ⇧ P / Ctrl ⇧ : | ⌘ ⇧ P / ⌘ ⇧ : |
| Quick open | Ctrl P | Ctrl P | ⌘ P |
| New tab | - | Ctrl T | ⌘ T |
| Close active tab | - | Ctrl W | ⌘ W |

View File

@@ -96,10 +96,7 @@ export const hotkeys = {
type: "hotkeys"
},
openCommandPalette: {
keys: normalizeKeys({
desktop: ["ctrl+shift+p"],
web: ["ctrl+shift+p", "ctrl+shift+:"]
}),
keys: normalizeKeys(["ctrl+shift+p", "ctrl+shift+:"]),
description: "Command palette",
category: "Navigation",
type: "hotkeys"

View File

@@ -94,7 +94,7 @@ test(
await login(db);
await db.monographs.refresh();
await db.monographs.publish(id);
await db.monographs.publish(id, "mono");
expect(await db.monographs.all.has(id)).toBeTruthy();
await db.monographs.unpublish(id);

View File

@@ -24,6 +24,7 @@ import { databaseTest, delay } from "../__tests__/utils/index.ts";
import http from "../src/utils/http.ts";
import Constants from "../src/utils/constants.ts";
import { writeFileSync } from "node:fs";
import dayjs from "dayjs";
const TEST_TIMEOUT = 60 * 1000;
const testOptions = { concurrent: true, timeout: TEST_TIMEOUT };
@@ -560,7 +561,10 @@ test(
});
// publish on device A
const monographId = await deviceA.monographs.publish(noteId);
const monographId = await deviceA.monographs.publish(
noteId,
"Monograph note"
);
expect(monographId).toBeTruthy();
// deviceB fetches the monograph
@@ -595,9 +599,13 @@ test(
});
// publish with selfDestruct
const monographId = await deviceA.monographs.publish(noteId, {
selfDestruct: true
});
const monographId = await deviceA.monographs.publish(
noteId,
"Self destruct monograph",
{
selfDestruct: true
}
);
expect(monographId).toBeTruthy();
// ensure all devices know it's published
@@ -649,10 +657,14 @@ test(
});
// publish with password and selfDestruct on device A
const monographId = await deviceA.monographs.publish(noteId, {
password,
selfDestruct: true
});
const monographId = await deviceA.monographs.publish(
noteId,
"Protected monograph",
{
password,
selfDestruct: true
}
);
expect(monographId).toBeTruthy();
// deviceB fetches the monograph

View File

@@ -314,7 +314,7 @@ test("restoring an old session should replace note's content and title", () =>
}
));
test.only("note history item has consistent note and title data between sessions", () =>
test("note history item has consistent note and title data between sessions", () =>
noteTest({
...TEST_NOTE,
title: "Test note",

View File

@@ -28,8 +28,11 @@ import MockDate from "mockdate";
import { describe, afterAll, beforeEach, test, expect } from "vitest";
import { databaseTest } from "./utils/index.ts";
import dayjs from "dayjs";
import utc from "dayjs/plugin/utc.js";
import assert from "assert";
dayjs.extend(utc);
describe("format reminder time", () => {
afterAll(() => {
MockDate.reset();
@@ -371,10 +374,10 @@ async function compareReminder(reminder) {
.sql()
.selectFrom("reminders")
.select([
createUpcomingReminderTimeQuery(dayjs().format("YYYY-MM-DDTHH:mm")).as(
"dueDate"
),
createIsReminderActiveQuery(dayjs().format("YYYY-MM-DDTHH:mm")).as(
createUpcomingReminderTimeQuery(
dayjs().utc().format("YYYY-MM-DDTHH:mm")
).as("dueDate"),
createIsReminderActiveQuery(dayjs.utc().format("YYYY-MM-DDTHH:mm")).as(
"isActive"
),
"id"

View File

@@ -278,9 +278,9 @@ export function isReminderActive(reminder: Reminder) {
export function createUpcomingReminderTimeQuery(unix = "now") {
const time = sql`time(date / 1000, 'unixepoch', 'localtime')`;
const dateNow = sql`date(${unix})`;
const dateNow = sql`date(${unix}, 'localtime')`;
const dateTime = sql`datetime(${dateNow} || ${time})`;
const dateTimeNow = sql`datetime(${unix})`;
const dateTimeNow = sql`datetime(${unix}, 'localtime')`;
const weekDayNow = sql`CAST(strftime('%w', ${dateNow}) AS INTEGER)`;
const monthDayNow = sql`CAST(strftime('%d', ${dateNow}) AS INTEGER)`;
const lastSelectedDay = sql`(SELECT MAX(value) FROM json_each(selectedDays))`;
@@ -326,8 +326,8 @@ export function createIsReminderActiveQuery(now = "now") {
return sql`IIF(
(disabled IS NULL OR disabled = 0)
AND (mode != 'once'
OR datetime(date / 1000, 'unixepoch', 'localtime') > datetime(${now})
OR datetime(date / 1000, 'unixepoch', 'localtime') > datetime(${now}, 'localtime')
OR (snoozeUntil IS NOT NULL
AND datetime(snoozeUntil / 1000, 'unixepoch', 'localtime') > datetime(${now}))
AND datetime(snoozeUntil / 1000, 'unixepoch', 'localtime') > datetime(${now}, 'localtime'))
), 1, 0)`.$castTo<boolean>();
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -294,7 +294,9 @@ export const SearchReplace = Extension.create<SearchOptions, SearchStorage>({
tr.mapping.map(to)
)
);
scrollIntoView();
const domNode = this.editor.view.domAtPos(from).node;
scrollIntoView(domNode);
this.storage.selectedIndex = nextIndex;
tr.setMeta("selectedIndex", nextIndex);
@@ -319,7 +321,9 @@ export const SearchReplace = Extension.create<SearchOptions, SearchStorage>({
tr.mapping.map(to)
)
);
scrollIntoView();
const domNode = this.editor.view.domAtPos(from).node;
scrollIntoView(domNode);
this.storage.selectedIndex = prevIndex;
tr.setMeta("selectedIndex", prevIndex);
@@ -472,14 +476,13 @@ export const SearchReplace = Extension.create<SearchOptions, SearchStorage>({
}
});
function scrollIntoView() {
function scrollIntoView(domNode: Node) {
setTimeout(() => {
const domNode = document.querySelector(".search-result.selected");
if (!(domNode instanceof HTMLElement)) return;
domNode.scrollIntoView({
behavior: "instant",
block: "center"
});
if ("scrollIntoView" in domNode) {
(domNode as Element).scrollIntoView({
behavior: "instant",
block: "center"
});
}
});
}

View File

@@ -22,6 +22,7 @@ import { DependencyList, useEffect, useMemo, useRef, useState } from "react";
import { Editor } from "../types.js";
import { useToolbarStore } from "../toolbar/stores/toolbar-store.js";
import { EditorView } from "@tiptap/pm/view";
import { useEditorSearchStore } from "../toolbar/stores/search-store.js";
function useForceUpdate() {
const [, setValue] = useState(0);
@@ -57,6 +58,13 @@ export const useEditor = (
if (oldIsFocused && !editor.isFocused) editor.commands.focus();
options.onCreate?.({ editor: editor });
const { searchTerm, ...searchOptions } = useEditorSearchStore.getState();
if (!searchOptions.isSearching) {
editor.commands.endSearch();
} else {
editor.commands.search(searchTerm, searchOptions);
}
function onTransaction({ editor }: { editor: TiptapEditor }) {
editorRef.current = editor;
clearTimeout(updateTimeout);

View File

@@ -17,7 +17,6 @@ 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 { useLayoutEffect } from "react";
import { FloatingMenuProps } from "./types.js";
import { SearchReplacePopup } from "../popups/search-replace.js";
import { ResponsivePresenter } from "../../components/responsive/index.js";
@@ -28,12 +27,6 @@ export function SearchReplaceFloatingMenu(props: FloatingMenuProps) {
const { editor } = props;
const isSearching = useEditorSearchStore((store) => store.isSearching);
useLayoutEffect(() => {
const { searchTerm, ...options } = useEditorSearchStore.getState();
if (!options.isSearching) editor.commands.endSearch();
else editor.commands.search(searchTerm, options);
}, []);
return (
<ResponsivePresenter
mobile="sheet"

View File

@@ -749,7 +749,7 @@ msgstr ""
#: src/strings.ts:975
msgid "Add your first notebook"
msgstr "<<<<<<< HEAD"
msgstr ""
#: src/strings.ts:2617
msgid "Adjust the line height of the editor"
@@ -1603,7 +1603,7 @@ msgstr ""
#: src/strings.ts:2392
msgid "Click to reset {title}"
msgstr "<<<<<<< HEAD"
msgstr ""
#: src/strings.ts:2615
msgid "Click to save"
@@ -2591,7 +2591,7 @@ msgstr ""
#: src/strings.ts:120
msgid "Enter the recovery code to continue logging in"
msgstr "<<<<<<< HEAD"
msgstr ""
#: src/strings.ts:2618
msgid "Enter title"
@@ -3556,7 +3556,7 @@ msgstr ""
#: src/strings.ts:2356
msgid "Line {line}, Column {column}"
msgstr "<<<<<<< HEAD"
msgstr ""
#: src/strings.ts:2616
msgid "Line height"
@@ -7488,7 +7488,7 @@ msgstr ""
#: src/strings.ts:1403
msgid "Your free trial is ending soon"
msgstr "<<<<<<< HEAD"
msgstr ""
#: src/strings.ts:2622
msgid "Your free trial is on-going. Your subscription will start on {trialExpiryDate}"