mirror of
https://github.com/streetwriters/notesnook.git
synced 2026-08-29 10:09:26 +02:00
Compare commits
20 Commits
fix_releas
...
3.0.29-and
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
275b285a8b | ||
|
|
96310a46e9 | ||
|
|
42f9bf1593 | ||
|
|
25aab6913a | ||
|
|
3bd7da68be | ||
|
|
a218738eff | ||
|
|
8bf283b3bc | ||
|
|
cb09430ff4 | ||
|
|
66d75492bb | ||
|
|
d772d38dc7 | ||
|
|
46a74f9512 | ||
|
|
7df1037e3f | ||
|
|
5c3136d07d | ||
|
|
6a9ddb770e | ||
|
|
f4c54fd27f | ||
|
|
05b12df7d7 | ||
|
|
dcf053eede | ||
|
|
5430966b02 | ||
|
|
7271140627 | ||
|
|
eb5ae0773b |
2
.github/workflows/core.tests.yml
vendored
2
.github/workflows/core.tests.yml
vendored
@@ -18,7 +18,7 @@ on:
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
2
.github/workflows/desktop.publish.yml
vendored
2
.github/workflows/desktop.publish.yml
vendored
@@ -37,7 +37,7 @@ on:
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
4
.github/workflows/desktop.tests.yml
vendored
4
.github/workflows/desktop.tests.yml
vendored
@@ -14,7 +14,7 @@ on:
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
@@ -133,7 +133,7 @@ jobs:
|
||||
test-linux:
|
||||
name: Test for Linux
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
steps:
|
||||
- name: Check out Git repository
|
||||
|
||||
2
.github/workflows/editor.tests.yml
vendored
2
.github/workflows/editor.tests.yml
vendored
@@ -19,7 +19,7 @@ on:
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
2
.github/workflows/help.publish.yml
vendored
2
.github/workflows/help.publish.yml
vendored
@@ -11,7 +11,7 @@ on:
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
2
.github/workflows/monograph.publish.yml
vendored
2
.github/workflows/monograph.publish.yml
vendored
@@ -14,7 +14,7 @@ on: workflow_dispatch
|
||||
jobs:
|
||||
push_to_registry:
|
||||
name: Push Docker image to Docker Hub
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04
|
||||
permissions:
|
||||
packages: write
|
||||
contents: read
|
||||
|
||||
2
.github/workflows/theme-builder.publish.yml
vendored
2
.github/workflows/theme-builder.publish.yml
vendored
@@ -5,7 +5,7 @@ on: workflow_dispatch
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
2
.github/workflows/vericrypt.publish.yml
vendored
2
.github/workflows/vericrypt.publish.yml
vendored
@@ -5,7 +5,7 @@ on: workflow_dispatch
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
2
.github/workflows/web.benchmarks.yml
vendored
2
.github/workflows/web.benchmarks.yml
vendored
@@ -14,7 +14,7 @@ on:
|
||||
jobs:
|
||||
bench:
|
||||
name: Bench
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
2
.github/workflows/web.publish.yml
vendored
2
.github/workflows/web.publish.yml
vendored
@@ -5,7 +5,7 @@ on: workflow_dispatch
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
2
.github/workflows/web.tests.yml
vendored
2
.github/workflows/web.tests.yml
vendored
@@ -19,7 +19,7 @@ on:
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -11,3 +11,4 @@ nx-cloud.env
|
||||
site
|
||||
node_modules.backup
|
||||
.nx
|
||||
*.patch
|
||||
|
||||
4
apps/desktop/package-lock.json
generated
4
apps/desktop/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@notesnook/desktop",
|
||||
"version": "3.0.24",
|
||||
"version": "3.0.25",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@notesnook/desktop",
|
||||
"version": "3.0.24",
|
||||
"version": "3.0.25",
|
||||
"hasInstallScript": true,
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "@notesnook/desktop",
|
||||
"productName": "Notesnook",
|
||||
"description": "Your private note taking space",
|
||||
"version": "3.0.24",
|
||||
"version": "3.0.25",
|
||||
"appAppleId": "1544027013",
|
||||
"private": true,
|
||||
"main": "./dist/cjs/index.js",
|
||||
|
||||
@@ -39,7 +39,6 @@ import SettingsService from "./services/settings";
|
||||
import { TipManager } from "./services/tip-manager";
|
||||
import { useThemeStore } from "./stores/use-theme-store";
|
||||
import { useUserStore } from "./stores/use-user-store";
|
||||
import { IntentService } from "./services/intent";
|
||||
|
||||
I18nManager.allowRTL(false);
|
||||
I18nManager.forceRTL(false);
|
||||
@@ -49,7 +48,6 @@ if (appLockEnabled || appLockMode !== "none") {
|
||||
useUserStore.getState().lockApp(true);
|
||||
}
|
||||
|
||||
IntentService.onLaunch();
|
||||
const App = (props: { configureMode: "note-preview" }) => {
|
||||
useAppEvents();
|
||||
//@ts-ignore
|
||||
|
||||
@@ -112,14 +112,19 @@ const AppLockedOverlay = () => {
|
||||
if (
|
||||
!biometricsAuthEnabled ||
|
||||
!(await BiometricService.isBiometryAvailable())
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
biometricUnlockAwaitingUserInput.current = true;
|
||||
|
||||
if (Platform.OS === "android") {
|
||||
const activityName = await NotesnookModule.getActivityName();
|
||||
if (activityName !== "MainActivity") return;
|
||||
if (
|
||||
activityName !== "MainActivity" &&
|
||||
activityName !== "NotePreviewConfigureActivity"
|
||||
)
|
||||
return;
|
||||
}
|
||||
useSettingStore.getState().setRequestBiometrics(true);
|
||||
|
||||
@@ -180,7 +185,6 @@ const AppLockedOverlay = () => {
|
||||
DatabaseLogger.info("Locking app on entering foreground");
|
||||
useUserStore.getState().lockApp(true);
|
||||
}
|
||||
|
||||
if (
|
||||
!(
|
||||
biometricUnlockAwaitingUserInput.current ||
|
||||
|
||||
@@ -110,6 +110,7 @@ export const Dialog = ({ context = "global" }) => {
|
||||
setChecked(false);
|
||||
values.current.inputValue = undefined;
|
||||
setVisible(false);
|
||||
dialogInfo.onClose();
|
||||
};
|
||||
|
||||
const onNegativePress = async () => {
|
||||
|
||||
@@ -43,7 +43,7 @@ export const Update = ({ version: appVersion, fwdRef }) => {
|
||||
let notes = version?.notes
|
||||
? version.notes.replace("Thank you for using Notesnook!", "").split("- ")
|
||||
: ["Bug fixes and performance improvements"];
|
||||
notes = notes?.map((n) => n.replace(/\n/g, ""));
|
||||
notes = notes?.map((n) => n.replace(/\n|<br>/g, ""));
|
||||
const isGithubRelease = Config.GITHUB_RELEASE === "true";
|
||||
|
||||
const getSupportedAbi = () => {
|
||||
@@ -178,18 +178,20 @@ export const Update = ({ version: appVersion, fwdRef }) => {
|
||||
{version.body}
|
||||
</Paragraph>
|
||||
) : null}
|
||||
{notes.map((item) => (
|
||||
<Paragraph
|
||||
key={item}
|
||||
color={colors.secondary.paragraph}
|
||||
style={{
|
||||
marginBottom: 5
|
||||
}}
|
||||
selectable
|
||||
>
|
||||
• {item}
|
||||
</Paragraph>
|
||||
))}
|
||||
{notes.map((item) =>
|
||||
item && item !== "" ? (
|
||||
<Paragraph
|
||||
key={item}
|
||||
color={colors.secondary.paragraph}
|
||||
style={{
|
||||
marginBottom: 5
|
||||
}}
|
||||
selectable
|
||||
>
|
||||
• {item}
|
||||
</Paragraph>
|
||||
) : null
|
||||
)}
|
||||
</ScrollView>
|
||||
<Seperator />
|
||||
<Button
|
||||
|
||||
@@ -50,6 +50,7 @@ import { MMKV } from "../common/database/mmkv";
|
||||
import { endProgress, startProgress } from "../components/dialogs/progress";
|
||||
import Migrate from "../components/sheets/migrate";
|
||||
import NewFeature from "../components/sheets/new-feature";
|
||||
import ReminderSheet from "../components/sheets/reminder";
|
||||
import { Walkthrough } from "../components/walkthroughs";
|
||||
import {
|
||||
resetTabStore,
|
||||
@@ -58,7 +59,8 @@ import {
|
||||
import {
|
||||
clearAppState,
|
||||
editorController,
|
||||
editorState
|
||||
editorState,
|
||||
setAppState
|
||||
} from "../screens/editor/tiptap/utils";
|
||||
import { useDragState } from "../screens/settings/editor/state";
|
||||
import BackupService from "../services/backup";
|
||||
@@ -69,7 +71,6 @@ import {
|
||||
eSubscribeEvent,
|
||||
presentSheet
|
||||
} from "../services/event-manager";
|
||||
import { IntentService } from "../services/intent";
|
||||
import {
|
||||
clearMessage,
|
||||
setEmailVerifyMessage,
|
||||
@@ -98,7 +99,6 @@ import {
|
||||
eLoginSessionExpired,
|
||||
eOnLoadNote,
|
||||
eOpenAnnouncementDialog,
|
||||
eUnlockNote,
|
||||
eUserLoggedIn,
|
||||
refreshNotesPage
|
||||
} from "../utils/events";
|
||||
@@ -106,7 +106,6 @@ import { getGithubVersion } from "../utils/github-version";
|
||||
import { tabBarRef } from "../utils/global-refs";
|
||||
import { NotesnookModule } from "../utils/notesnook-module";
|
||||
import { sleep } from "../utils/time";
|
||||
import ReminderSheet from "../components/sheets/reminder";
|
||||
|
||||
const onCheckSyncStatus = async (type: SyncStatusEvent) => {
|
||||
const { disableSync, disableAutoSync } = SettingsService.get();
|
||||
@@ -162,7 +161,6 @@ const onUserSessionExpired = async () => {
|
||||
const onAppOpenedFromURL = async (event: { url: string }) => {
|
||||
const url = event.url;
|
||||
|
||||
console.log("URL", url);
|
||||
try {
|
||||
if (url.startsWith("https://app.notesnook.com/account/verified")) {
|
||||
await onUserEmailVerified();
|
||||
@@ -751,13 +749,15 @@ export const useAppEvents = () => {
|
||||
setTimeout(() => {
|
||||
sub = AppState.addEventListener("change", onAppStateChanged);
|
||||
if (
|
||||
refValues.current.initialUrl?.startsWith(
|
||||
"https://app.notesnook.com/account/verified"
|
||||
)
|
||||
refValues.current.initialUrl &&
|
||||
!refValues.current.initialUrl?.includes("open_note")
|
||||
) {
|
||||
onUserEmailVerified();
|
||||
onAppOpenedFromURL({
|
||||
url: refValues.current.initialUrl!
|
||||
});
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
refValues.current.removeInternetStateListener = NetInfo.addEventListener(
|
||||
onInternetStateChanged
|
||||
);
|
||||
|
||||
@@ -17,6 +17,7 @@ You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { strings } from "@notesnook/intl";
|
||||
import { useThemeColors } from "@notesnook/theme";
|
||||
import { NavigationContainer } from "@react-navigation/native";
|
||||
import { createNativeStackNavigator } from "@react-navigation/native-stack";
|
||||
@@ -44,10 +45,6 @@ import useNavigationStore from "../stores/use-navigation-store";
|
||||
import { useSelectionStore } from "../stores/use-selection-store";
|
||||
import { useSettingStore } from "../stores/use-setting-store";
|
||||
import { rootNavigatorRef } from "../utils/global-refs";
|
||||
import { strings } from "@notesnook/intl";
|
||||
import { IntentService } from "../services/intent";
|
||||
import ReminderSheet from "../components/sheets/reminder";
|
||||
import { db } from "../common/database";
|
||||
|
||||
const NativeStack = createNativeStackNavigator();
|
||||
const IntroStack = createNativeStackNavigator();
|
||||
@@ -86,17 +83,6 @@ const _Tabs = () => {
|
||||
React.useEffect(() => {
|
||||
setTimeout(async () => {
|
||||
useNavigationStore.getState().update(homepage);
|
||||
const intent = IntentService.getLaunchIntent();
|
||||
if (intent && intent["com.streetwriters.notesnook.OpenReminderId"]) {
|
||||
const reminder = await db.reminders.reminder(
|
||||
intent["com.streetwriters.notesnook.OpenReminderId"]
|
||||
);
|
||||
if (reminder) {
|
||||
ReminderSheet.present(reminder);
|
||||
}
|
||||
} else if (intent["com.streetwriters.notesnook.NewReminder"]) {
|
||||
ReminderSheet.present();
|
||||
}
|
||||
}, 1000);
|
||||
}, [homepage]);
|
||||
|
||||
|
||||
@@ -613,7 +613,7 @@ export const useEditorEvents = (
|
||||
}
|
||||
case EditorEvents.tabFocused: {
|
||||
eSendEvent(eEditorTabFocused, editorMessage.tabId);
|
||||
|
||||
if (!editor.state.current.initialLoadCalled) break;
|
||||
if (editorMessage.noteId) {
|
||||
if (!useSettingStore.getState().isAppLoading) {
|
||||
const note = await db.notes.note(editorMessage.noteId);
|
||||
|
||||
@@ -77,6 +77,7 @@ import {
|
||||
isEditorLoaded,
|
||||
post
|
||||
} from "./utils";
|
||||
import { Linking } from "react-native";
|
||||
|
||||
const loadNoteMutex = new Mutex();
|
||||
|
||||
@@ -738,35 +739,37 @@ export const useEditor = (
|
||||
lock.current = true;
|
||||
|
||||
// Handle this case where note was locked on another device and synced.
|
||||
const locked = note
|
||||
let locked = note
|
||||
? await db.vaults.itemExists(note as ItemReference)
|
||||
: false;
|
||||
|
||||
if (data.type === "tiptap") {
|
||||
locked = data.locked;
|
||||
}
|
||||
|
||||
useTabStore.getState().forEachNoteTab(noteId, async (tab) => {
|
||||
const tabId = tab.id;
|
||||
|
||||
let didUnlock = false;
|
||||
|
||||
if (note) {
|
||||
if (!locked && tab?.session?.noteLocked) {
|
||||
// Note lock removed.
|
||||
if (tab.session?.locked) {
|
||||
if (useTabStore.getState().currentTab === tabId) {
|
||||
eSendEvent(eOnLoadNote, {
|
||||
item: note
|
||||
});
|
||||
} else {
|
||||
useTabStore.getState().updateTab(tabId, {
|
||||
session: {
|
||||
locked: false,
|
||||
noteLocked: false
|
||||
}
|
||||
});
|
||||
if (tab?.session?.noteLocked || tab?.session?.locked) {
|
||||
if (useTabStore.getState().currentTab !== tabId) {
|
||||
localTabState.current?.set(tabId, {
|
||||
editedAt: 0
|
||||
});
|
||||
}
|
||||
|
||||
didUnlock = true;
|
||||
useTabStore.getState().updateTab(tabId, {
|
||||
session: {
|
||||
locked: false,
|
||||
noteLocked: false
|
||||
}
|
||||
});
|
||||
}
|
||||
} else if (!tab?.session?.noteLocked && locked) {
|
||||
// Note lock added.
|
||||
useTabStore.getState().updateTab(tabId, {
|
||||
session: {
|
||||
locked: true,
|
||||
@@ -782,18 +785,24 @@ export const useEditor = (
|
||||
});
|
||||
}
|
||||
|
||||
if (currentNotes.current[noteId]?.title !== note.title) {
|
||||
if (
|
||||
currentNotes.current[noteId]?.title !== note.title ||
|
||||
didUnlock
|
||||
) {
|
||||
postMessage(NativeEvents.title, note.title, tabId);
|
||||
}
|
||||
commands.setTags(note);
|
||||
if (currentNotes.current[noteId]?.dateEdited !== note.dateEdited) {
|
||||
if (
|
||||
currentNotes.current[noteId]?.dateEdited !== note.dateEdited ||
|
||||
didUnlock
|
||||
) {
|
||||
commands.setStatus(
|
||||
getFormattedDate(note.dateEdited, "date-time"),
|
||||
strings.saved(),
|
||||
tabId as string
|
||||
);
|
||||
}
|
||||
if (tab.session?.readonly !== note.readonly) {
|
||||
if (tab.session?.readonly !== note.readonly || didUnlock) {
|
||||
useTabStore.getState().updateTab(tabId, {
|
||||
session: {
|
||||
readonly: note.readonly
|
||||
@@ -803,7 +812,10 @@ export const useEditor = (
|
||||
}
|
||||
|
||||
if (data.type === "tiptap" && note && !isLocal) {
|
||||
if (lastContentChangeTime.current[noteId] >= data.dateModified) {
|
||||
if (
|
||||
lastContentChangeTime.current[noteId] >= data.dateModified &&
|
||||
!didUnlock
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -823,18 +835,35 @@ export const useEditor = (
|
||||
} else {
|
||||
await postMessage(
|
||||
NativeEvents.updatehtml,
|
||||
decryptedContent.data,
|
||||
{
|
||||
data: decryptedContent.data,
|
||||
selection: tab.session?.selection,
|
||||
scrollTop: tab.session?.scrollTop
|
||||
},
|
||||
tabId
|
||||
);
|
||||
currentContents.current[note.id] = decryptedContent;
|
||||
}
|
||||
} else {
|
||||
const _nextContent = data.data;
|
||||
if (_nextContent === currentContents.current[note.id]?.data) {
|
||||
if (
|
||||
_nextContent === currentContents.current[note.id]?.data &&
|
||||
!didUnlock
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
lastContentChangeTime.current[note.id] = note.dateEdited;
|
||||
await postMessage(NativeEvents.updatehtml, _nextContent, tabId);
|
||||
console.log(tab.session?.selection);
|
||||
await postMessage(
|
||||
NativeEvents.updatehtml,
|
||||
{
|
||||
data: _nextContent,
|
||||
selection: tab.session?.selection,
|
||||
scrollTop: tab.session?.scrollTop
|
||||
},
|
||||
tabId
|
||||
);
|
||||
if (!isEncryptedContent(data)) {
|
||||
currentContents.current[note.id] =
|
||||
data as UnencryptedContentItem;
|
||||
@@ -1027,30 +1056,33 @@ export const useEditor = (
|
||||
state.current.ready = true;
|
||||
}
|
||||
|
||||
const appState = getAppState();
|
||||
if (appState?.noteId) {
|
||||
const note = await db.notes?.note(appState.noteId);
|
||||
if (note) {
|
||||
loadNote({
|
||||
item: note
|
||||
});
|
||||
}
|
||||
} else {
|
||||
const noteId = useTabStore.getState().getCurrentNoteId();
|
||||
if (!noteId) {
|
||||
loadNote({ newNote: true });
|
||||
if (tabBarRef.current?.page() === 1) {
|
||||
state.current.currentlyEditing = false;
|
||||
}
|
||||
} else if (state.current?.initialLoadCalled) {
|
||||
const note = currentNotes.current[noteId];
|
||||
if (!state.current?.initialLoadCalled) {
|
||||
const url = await Linking.getInitialURL();
|
||||
let noteId = url && new URL(url).searchParams.get("id");
|
||||
if (noteId) {
|
||||
const note = await db.notes?.note(noteId);
|
||||
if (note) {
|
||||
loadNote({
|
||||
item: note
|
||||
});
|
||||
}
|
||||
}
|
||||
if (!state.current?.initialLoadCalled) {
|
||||
tabBarRef.current?.goToPage(1);
|
||||
} else {
|
||||
noteId = useTabStore.getState().getCurrentNoteId() || null;
|
||||
if (!noteId) {
|
||||
loadNote({ newNote: true });
|
||||
if (tabBarRef.current?.page() === 1) {
|
||||
state.current.currentlyEditing = false;
|
||||
}
|
||||
} else {
|
||||
const note = await db.notes.note(noteId);
|
||||
if (note) {
|
||||
loadNote({
|
||||
item: note
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
state.current.initialLoadCalled = true;
|
||||
}
|
||||
overlay(false);
|
||||
|
||||
@@ -105,11 +105,14 @@ class TabSessionStorage {
|
||||
}
|
||||
|
||||
static update(id: string, session: Partial<TabSessionItem>) {
|
||||
if (!id) throw new Error("Session ID is required");
|
||||
const currentSession = TabSessionStorage.get(id);
|
||||
const newSession = {
|
||||
...currentSession,
|
||||
...session
|
||||
...session,
|
||||
id: currentSession?.id || session.id || id
|
||||
};
|
||||
|
||||
TabSessionStorage.set(id, newSession as TabSessionItem);
|
||||
return newSession;
|
||||
}
|
||||
@@ -164,7 +167,7 @@ const history = new TabHistory();
|
||||
|
||||
export type TabStore = {
|
||||
tabs: TabItem[];
|
||||
currentTab?: string;
|
||||
currentTab: string;
|
||||
updateTab: (id: string, options: Omit<Partial<TabItem>, "id">) => void;
|
||||
focusPreviewTab: (
|
||||
noteId: string,
|
||||
@@ -289,6 +292,7 @@ export const useTabStore = create<TabStore>(
|
||||
const tabs = [...get().tabs];
|
||||
const sessionId =
|
||||
options.session?.id || (tabs[index].session?.id as string);
|
||||
|
||||
const updatedSession = !options.session
|
||||
? tabs[index].session
|
||||
: TabSessionStorage.update(sessionId, options.session);
|
||||
@@ -474,7 +478,7 @@ export const useTabStore = create<TabStore>(
|
||||
}
|
||||
}),
|
||||
{
|
||||
name: "tabs-storage-v3",
|
||||
name: "tabs-storage-v5",
|
||||
getStorage: () => MMKV as unknown as StateStorage,
|
||||
onRehydrateStorage: () => {
|
||||
return (state) => {
|
||||
|
||||
@@ -148,7 +148,7 @@ const restoreBackup = async (options: {
|
||||
|
||||
let count = 0;
|
||||
await db.transaction(async () => {
|
||||
let passwordOrKey: PasswordOrKey;
|
||||
let passwordOrKey: PasswordOrKey | undefined = undefined;
|
||||
for (const path of extractedBackupFiles) {
|
||||
if (path === ".nnbackup" || path === "attachments") continue;
|
||||
|
||||
@@ -166,7 +166,7 @@ const restoreBackup = async (options: {
|
||||
|
||||
passwordOrKey = !isEncryptedBackup
|
||||
? ({} as PasswordOrKey)
|
||||
: await withPassword();
|
||||
: passwordOrKey || (await withPassword());
|
||||
|
||||
if (
|
||||
isEncryptedBackup &&
|
||||
|
||||
@@ -30,12 +30,15 @@ import { DatabaseLogger, db } from "../common/database";
|
||||
import filesystem, { FileStorage } from "../common/filesystem";
|
||||
import { cacheDir, copyFileAsync } from "../common/filesystem/utils";
|
||||
import { presentDialog } from "../components/dialog/functions";
|
||||
import { endProgress, updateProgress } from "../components/dialogs/progress";
|
||||
import {
|
||||
endProgress,
|
||||
startProgress,
|
||||
updateProgress
|
||||
} from "../components/dialogs/progress";
|
||||
import { eCloseSheet } from "../utils/events";
|
||||
import { sleep } from "../utils/time";
|
||||
import { ToastManager, eSendEvent, presentSheet } from "./event-manager";
|
||||
import SettingsService from "./settings";
|
||||
import { e } from "@lingui/react/dist/shared/react.b2b749a9";
|
||||
|
||||
const MS_DAY = 86400000;
|
||||
const MS_WEEK = MS_DAY * 7;
|
||||
@@ -156,6 +159,7 @@ async function updateNextBackupTime(type: "full" | "partial") {
|
||||
[type === "full" ? "lastFullBackupDate" : "lastBackupDate"]: Date.now()
|
||||
});
|
||||
}
|
||||
let backupRunning = false;
|
||||
/**
|
||||
* @param {boolean=} progress
|
||||
* @param {string=} context
|
||||
@@ -166,6 +170,18 @@ async function run(
|
||||
context?: string,
|
||||
backupType: "full" | "partial" = "partial"
|
||||
) {
|
||||
if (backupRunning) {
|
||||
if (progress) {
|
||||
startProgress({
|
||||
title: strings.backingUpData(backupType),
|
||||
paragraph: strings.backupDataDesc(),
|
||||
progress: "Backup in progress...",
|
||||
canHideProgress: true
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
backupRunning = true;
|
||||
const androidBackupDirectory = (await checkBackupDirExists(
|
||||
false,
|
||||
context
|
||||
@@ -193,10 +209,11 @@ async function run(
|
||||
);
|
||||
|
||||
if (progress) {
|
||||
presentSheet({
|
||||
startProgress({
|
||||
title: strings.backingUpData(backupType),
|
||||
paragraph: strings.backupDataDesc(),
|
||||
progress: true
|
||||
progress: "Preparing backup...",
|
||||
canHideProgress: true
|
||||
});
|
||||
}
|
||||
|
||||
@@ -274,14 +291,7 @@ async function run(
|
||||
path = zipOutputFile;
|
||||
}
|
||||
|
||||
RNFetchBlob.fs.unlink(zipSourceFolder).catch(() => {
|
||||
/* empty */
|
||||
});
|
||||
if (Platform.OS === "android") {
|
||||
RNFetchBlob.fs.unlink(zipOutputFile).catch(() => {
|
||||
/* empty */
|
||||
});
|
||||
}
|
||||
cleanupAfterBackup(zipSourceFolder, zipOutputFile);
|
||||
|
||||
updateNextBackupTime(backupType || "partial");
|
||||
|
||||
@@ -292,6 +302,8 @@ async function run(
|
||||
const canShowCompletionStatus =
|
||||
progress && SettingsService.get().showBackupCompleteSheet;
|
||||
|
||||
backupRunning = false;
|
||||
|
||||
if (context) {
|
||||
return {
|
||||
path: path
|
||||
@@ -302,8 +314,6 @@ async function run(
|
||||
|
||||
if (canShowCompletionStatus) {
|
||||
presentBackupCompleteSheet(path);
|
||||
} else {
|
||||
eSendEvent(eCloseSheet);
|
||||
}
|
||||
|
||||
ToastManager.show({
|
||||
@@ -311,11 +321,11 @@ async function run(
|
||||
type: "success",
|
||||
context: "global"
|
||||
});
|
||||
|
||||
return {
|
||||
path: path
|
||||
};
|
||||
} catch (e) {
|
||||
backupRunning = false;
|
||||
ToastManager.error(e as Error, strings.backupFailed(), context || "global");
|
||||
|
||||
if (
|
||||
@@ -326,17 +336,9 @@ async function run(
|
||||
return run(progress, context, backupType);
|
||||
}
|
||||
|
||||
RNFetchBlob.fs.unlink(zipSourceFolder).catch(() => {
|
||||
/* empty */
|
||||
});
|
||||
if (Platform.OS === "android") {
|
||||
RNFetchBlob.fs.unlink(zipOutputFile).catch(() => {
|
||||
/* empty */
|
||||
});
|
||||
}
|
||||
cleanupAfterBackup(zipSourceFolder, zipOutputFile);
|
||||
|
||||
DatabaseLogger.error(e);
|
||||
await sleep(300);
|
||||
if (progress) {
|
||||
endProgress();
|
||||
}
|
||||
@@ -347,6 +349,17 @@ async function run(
|
||||
}
|
||||
}
|
||||
|
||||
function cleanupAfterBackup(zipSourceFolder: string, zipOutputFile: string) {
|
||||
RNFetchBlob.fs.unlink(zipSourceFolder).catch(() => {
|
||||
/* empty */
|
||||
});
|
||||
if (Platform.OS === "android") {
|
||||
RNFetchBlob.fs.unlink(zipOutputFile).catch(() => {
|
||||
/* empty */
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function checkBackupRequired(
|
||||
type: "daily" | "off" | "useroff" | "weekly" | "monthly" | "never",
|
||||
lastBackupDateType: "lastBackupDate" | "lastFullBackupDate" = "lastBackupDate"
|
||||
|
||||
@@ -116,7 +116,7 @@ android {
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
multiDexEnabled true
|
||||
versionCode 3037
|
||||
versionCode 3039
|
||||
versionName getNpmVersion()
|
||||
testBuildType System.getProperty('testBuildType', 'debug')
|
||||
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
android:theme="@style/BootTheme"
|
||||
android:largeHeap="true"
|
||||
android:supportsRtl="false"
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
tools:replace="android:supportsRtl">
|
||||
|
||||
<receiver android:exported="false" android:label="@string/reminders_title" android:name=".ReminderWidgetProvider">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
- Added a widget to add a note to home screen for quick access
|
||||
- Added a widget that shows upcoming reminders on home screen
|
||||
- Now you can share an image with other apps from image viewer
|
||||
- New and improved editor tabs with history
|
||||
- Fixed a crash on app launch faced by some users
|
||||
- Fixed homescreen note widget does not open correct note
|
||||
- Many small bug fixes and improvements
|
||||
|
||||
Thank you for using Notesnook!
|
||||
@@ -1063,7 +1063,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 2124;
|
||||
CURRENT_PROJECT_VERSION = 2126;
|
||||
DEVELOPMENT_TEAM = 53CWBG3QUC;
|
||||
ENABLE_BITCODE = NO;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
@@ -1137,7 +1137,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.0.27;
|
||||
MARKETING_VERSION = 3.0.29;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
@@ -1168,7 +1168,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 2124;
|
||||
CURRENT_PROJECT_VERSION = 2126;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 53CWBG3QUC;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
@@ -1242,7 +1242,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.0.27;
|
||||
MARKETING_VERSION = 3.0.29;
|
||||
ONLY_ACTIVE_ARCH = NO;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
@@ -1401,7 +1401,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 2124;
|
||||
CURRENT_PROJECT_VERSION = 2126;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = 53CWBG3QUC;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
@@ -1413,7 +1413,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.0.27;
|
||||
MARKETING_VERSION = 3.0.29;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.notewidget;
|
||||
@@ -1444,7 +1444,7 @@
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 2124;
|
||||
CURRENT_PROJECT_VERSION = 2126;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = "";
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 53CWBG3QUC;
|
||||
@@ -1457,7 +1457,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.0.27;
|
||||
MARKETING_VERSION = 3.0.29;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.notewidget;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
@@ -1487,7 +1487,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = "Make Note/Make Note.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 2124;
|
||||
CURRENT_PROJECT_VERSION = 2126;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = 53CWBG3QUC;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
@@ -1561,7 +1561,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.0.27;
|
||||
MARKETING_VERSION = 3.0.29;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.share;
|
||||
@@ -1592,7 +1592,7 @@
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 2124;
|
||||
CURRENT_PROJECT_VERSION = 2126;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = "";
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 53CWBG3QUC;
|
||||
@@ -1667,7 +1667,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.0.27;
|
||||
MARKETING_VERSION = 3.0.29;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.share;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
|
||||
@@ -1820,7 +1820,7 @@ SPEC CHECKSUMS:
|
||||
Base64: cecfb41a004124895a7bcee567a89bae5a89d49b
|
||||
BEMCheckBox: 5ba6e37ade3d3657b36caecc35c8b75c6c2b1a4e
|
||||
boost: d3f49c53809116a5d38da093a8aa78bf551aed09
|
||||
callstack-repack: 2db7cbeced7cd5da360d01965e0b983f6dacfd54
|
||||
callstack-repack: 721b034d0662f47388719bf26c00f838da6880d5
|
||||
DoubleConversion: 76ab83afb40bddeeee456813d9c04f67f78771b5
|
||||
FBLazyVector: ac12dc084d1c8ec4cc4d7b3cf1b0ebda6dab85af
|
||||
fmt: 4c2741a687cc09f0634a2e2c72a838b99f1ff120
|
||||
@@ -1837,103 +1837,103 @@ SPEC CHECKSUMS:
|
||||
RCTTypeSafety: f5ecbc86c5c5fa163c05acb7a1c5012e15b5f994
|
||||
React: fc9fa7258eff606f44d58c5b233a82dc9cf09018
|
||||
React-callinvoker: e3fab14d69607fb7e8e3a57e5a415aed863d3599
|
||||
React-Codegen: 49efb5917c904b5b01ef708311a2f1773f4fe73e
|
||||
React-Core: 3a5fd9e781cecf87803e5b091496a606a3df774a
|
||||
React-CoreModules: cbf4707dafab8f9f826ac0c63a07d0bf5d01e256
|
||||
React-cxxreact: 7b188556271e3c7fdf22a04819f6a6225045b9dd
|
||||
React-Codegen: ff6c425afab9288a1573337111741d30363bf962
|
||||
React-Core: c3f589f104983dec3c3eeec5e70d61aa811bc236
|
||||
React-CoreModules: 864932ddae3ead5af5bfb05f9bbc2cedcb958b39
|
||||
React-cxxreact: bd9146108c44e6dbb99bba4568ce7af0304a2419
|
||||
React-debug: d30893c49ae1bce4037ea5cd8bb2511d2a38d057
|
||||
React-Fabric: 826729dd2304fda9b89ff0a579f60ba2a470bc26
|
||||
React-FabricImage: 2ad1fb8ffa5778eda9ed204a7b3cdd70bc333ce7
|
||||
React-Fabric: a171830e52baf8ec2b175c6a3791e01bbb92f1fb
|
||||
React-FabricImage: ad154af0067f4b5dc5a41f607e48ee343641e903
|
||||
React-featureflags: 4ae83e72d9a92452793601ac9ac7d2280e486089
|
||||
React-graphics: 61a026e1c1e7e20d20ac9fec6f6de631732b233d
|
||||
React-hermes: a7054fbcbda3957e3c5eaad06ef9bf79998d535a
|
||||
React-ImageManager: 2bbd6eb2e696bc680f76f84563e4b87d241614e1
|
||||
React-jserrorhandler: 56fa04d49bfbe54ddfece7916673a73ebfea286b
|
||||
React-jsi: f3ce1dd2e950b6ad12b65ea3ef89168f1b94c584
|
||||
React-jsiexecutor: b4df3a27973d82f9abf3c4bd0f88e042cda25f16
|
||||
React-jsinspector: 97ea746c023687de7313ee289817d6991d596c7d
|
||||
React-jsitracing: 3b6060bbf5317663667e1dd93560c7943ab86ccc
|
||||
React-logger: 257858bd55f3a4e1bc0cf07ddc8fb9faba6f8c7c
|
||||
React-Mapbuffer: 6c1cacdbf40b531f549eba249e531a7d0bfd8e7f
|
||||
react-native-actions-shortcuts: 5d9cf0c9c308333dfcc1e05c3f9afa8c428e2533
|
||||
react-native-background-actions: 2c251c986f23347f9c1722f05fd296938f60edb1
|
||||
react-native-begin-background-task: 3b889e07458afc5822a7277cf9cbc7cd077e39ee
|
||||
react-native-blob-util: 2d36383bb52c15c5451be81cb7ddf22bc34a12a6
|
||||
react-native-config: 86038147314e2e6d10ea9972022aa171e6b1d4d8
|
||||
react-native-date-picker: 93e43b3084cea595b4d68b1405d6d99849663bd6
|
||||
react-native-document-picker: ec07866a30707f23660c0f3ae591d669d3e89096
|
||||
react-native-fingerprint-scanner: be63e626b31fb951780a5fac5328b065a61a3d6e
|
||||
react-native-get-random-values: dee677497c6a740b71e5612e8dbd83e7539ed5bb
|
||||
react-native-gzip: c5e87ee9e359f02350e3a2ee52eb35eddc398868
|
||||
react-native-html-to-pdf-lite: 21bfb169bf4cbcd7bec9f736975ee1b3f5292d4a
|
||||
react-native-image-resizer: 00ceb0e05586c7aadf061eea676957a6c2ec60fa
|
||||
react-native-in-app-review: db8bb167a5f238e7ceca5c242d6b36ce8c4404a4
|
||||
react-native-keep-awake: caee3ff89eaa21dfe29010f0d143566874a04441
|
||||
react-native-mmkv-storage: 3892853c11ab8a0c3a3f9ef3b0657aa9a5f616c9
|
||||
react-native-netinfo: ccbe1085dffd16592791d550189772e13bf479e2
|
||||
react-native-notification-sounds: da78c828fe1bcbb92d8b505d5261890ed315ff39
|
||||
react-native-orientation: f1caf84d65f1a4fd4511a18f2b924e634ad7a628
|
||||
react-native-pdf: 33c622cbdf776a649929e8b9d1ce2d313347c4fa
|
||||
react-native-quick-sqlite: 18e1367c34faac90e37f6eb3e78c196e9b674b5d
|
||||
react-native-safe-area-context: b7daa1a8df36095a032dff095a1ea8963cb48371
|
||||
react-native-screenguard: 8b36a3df84c76cd2b82c477f71c26fa1c8cc14a0
|
||||
react-native-share-extension: 01b25fc15faf2510cc2529e98ca444f64e46238d
|
||||
react-native-sodium: 4cb76086943a7f60c42b40ebca866695b360a196
|
||||
react-native-theme-switch-animation: d3eb50365a3829ce5572628888fa514752703f61
|
||||
react-native-webview: 553abd09f58e340fdc7746c9e2ae096839e99911
|
||||
React-graphics: ed7d57965140168de86835946e8f1210c72c65dc
|
||||
React-hermes: 177b1efdf3b8f10f4ca12b624b83fb4d4ccb2884
|
||||
React-ImageManager: 3a50d0ee0bf81b1a6f23a0c5b30388293bcd6004
|
||||
React-jserrorhandler: dcd62f5ca1c724c19637595ef7f45b78018e758f
|
||||
React-jsi: 0abe1b0881b67caf8d8df6a57778dd0d3bb9d9a5
|
||||
React-jsiexecutor: f6ca8c04f19f6a3acaa9610f7fb728f39d6e3248
|
||||
React-jsinspector: db98771eae84e6f86f0ca5d9dcc572baadbfefc0
|
||||
React-jsitracing: f8367edacc50bb3f9f056a5aeafb8cee5849fafb
|
||||
React-logger: 780b9ee9cec7d44eabc4093de90107c379078cb6
|
||||
React-Mapbuffer: f544f00b98dbdd8cbae96dd2bdb8b47f719976e0
|
||||
react-native-actions-shortcuts: 65fb9cb4a58c71af7382663c1822dda061dbf1b0
|
||||
react-native-background-actions: 40e09df6ea8c7d2753f6c1d75f6f1eee4a9bc35f
|
||||
react-native-begin-background-task: 2191f2a84b0328932a3d44db4361e666fee781bb
|
||||
react-native-blob-util: 4be49d669870f01645b63d33342718e95d0d48b1
|
||||
react-native-config: 136f9755ccc991cc6438053a44363259ad4c7813
|
||||
react-native-date-picker: bbf77c50dce9da2beb11e2f67f3300195ba27d81
|
||||
react-native-document-picker: f4ccd6f6f369da1409e609788181eac66cc1a2d8
|
||||
react-native-fingerprint-scanner: 562585260768cad51ae48e4b505d28c8731aecfa
|
||||
react-native-get-random-values: 419569b6ed3d15bfb9b6781b2f2e058f8e8d2698
|
||||
react-native-gzip: 8d602277c2564591f04dd1cec4043acc8350dcc3
|
||||
react-native-html-to-pdf-lite: d606d3b72d9696c7a6d1e5f5b7536783faacef14
|
||||
react-native-image-resizer: ff3c9ab0ce235c4c00f49d0a373043cb4b8781be
|
||||
react-native-in-app-review: b3d1eed3d1596ebf6539804778272c4c65e4a400
|
||||
react-native-keep-awake: bda639e941ce138506c18f1b999dcbf16d4c77b8
|
||||
react-native-mmkv-storage: 8dddc9d16248bc9a4d9566ac5c97c318692d299c
|
||||
react-native-netinfo: 66c9ac0d0ae92a57a9ed99ab8a75429740700c73
|
||||
react-native-notification-sounds: ce106d58df0dd384bccbd2e84fb53accab7cc068
|
||||
react-native-orientation: db2655b95b4123f17e75dcb04ee8b8b1294ce7ee
|
||||
react-native-pdf: da10473ae54555c373c62af671da8fe0eef846e2
|
||||
react-native-quick-sqlite: 80b5b3405bfc92e97b6041d2c2a446800bea6ad7
|
||||
react-native-safe-area-context: b72c4611af2e86d80a59ac76279043d8f75f454c
|
||||
react-native-screenguard: 82437eeb0086a90b5e5d7e54130bb04fb406373e
|
||||
react-native-share-extension: 7528322fe621b683e6b48ab3418207ed45a70983
|
||||
react-native-sodium: ed020d5f50ab1886f7bf23e32732d0d10e9373ac
|
||||
react-native-theme-switch-animation: 64f2688c2e3489ababc7b35f436fd3b5ed7c0a98
|
||||
react-native-webview: a71525b1ab760230fbf37303d8371fbe72051c7d
|
||||
React-nativeconfig: ba9a2e54e2f0882cf7882698825052793ed4c851
|
||||
React-NativeModulesApple: 8d11ff8955181540585c944cf48e9e7236952697
|
||||
React-NativeModulesApple: 84aaad2b0e546d7b839837ca537f6e72804a4cad
|
||||
React-perflogger: ed4e0c65781521e0424f2e5e40b40cc7879d737e
|
||||
React-RCTActionSheet: 49d53ff03bb5688ca4606c55859053a0cd129ea5
|
||||
React-RCTAnimation: 07b4923885c52c397c4ec103924bf6e53b42c73e
|
||||
React-RCTAppDelegate: 316e295076734baf9bdf1bfac7d92ab647aed930
|
||||
React-RCTBlob: 85c57b0d5e667ff8a472163ba3af0628171a64bb
|
||||
React-RCTFabric: 97c1465ded4dc92841f5376a39e43e1b2c455f40
|
||||
React-RCTImage: b965c85bec820e2a9c154b1fb00a2ecdd59a9c92
|
||||
React-RCTLinking: 75f04a5f27c26c4e73a39c50df470820d219df79
|
||||
React-RCTNetwork: c1a9143f4d5778efc92da40d83969d03912ccc24
|
||||
React-RCTSettings: c6800f91c0ecd48868cd5db754b0b0a7f5ffe039
|
||||
React-RCTText: b923e24f9b7250bc4f7ab154c4168ad9f8d8fc9d
|
||||
React-RCTVibration: 08c4f0c917c435b3619386c25a94ee5d64c250f0
|
||||
React-rendererdebug: 3cda04217d9df67b94397ee0ead8ef3d8b7e427b
|
||||
React-RCTAnimation: 3075449f26cb98a52bcbf51cccd0c7954e2a71db
|
||||
React-RCTAppDelegate: 9a419c4dda9dd039ad851411546dd297b930c454
|
||||
React-RCTBlob: e81ab773a8fc1e9dceed953e889f936a7b7b3aa6
|
||||
React-RCTFabric: 47a87a3e3fa751674f7e64d0bcd58976b8c57db9
|
||||
React-RCTImage: d570531201c6dce7b5b63878fa8ecec0cc311c4c
|
||||
React-RCTLinking: af888972b925d2811633d47853c479e88c35eb4d
|
||||
React-RCTNetwork: 5728a06ff595003eca628f43f112a804f4a9a970
|
||||
React-RCTSettings: ba3665b0569714a8aaceee5c7d23b943e333fa55
|
||||
React-RCTText: b733fa984f0336b072e47512898ba91214f66ddb
|
||||
React-RCTVibration: 0cbcbbd8781b6f6123671bae9ee5dd20d621af6c
|
||||
React-rendererdebug: 9fc8f7d0bd19f2a3fe3791982af550b5e1535ff7
|
||||
React-rncore: 4013508a2f3fcf46c961919bbbd4bfdda198977e
|
||||
React-RuntimeApple: 447844a2bdb0a03ffd24e5b4a4b96cfc50325b88
|
||||
React-RuntimeCore: 9b5bffdaccee9b707b1c2694c9044e13ff0bb087
|
||||
React-RuntimeApple: a852a6e06ab20711658873f39cb10b0033bea19d
|
||||
React-RuntimeCore: 12e5e176c0cb09926f3e6f37403a84d2e0f203a7
|
||||
React-runtimeexecutor: 0e688aefc14c6bc8601f4968d8d01c3fb6446844
|
||||
React-RuntimeHermes: 4d6ef6bb0f2b0b40d59143317f6b99c82764c959
|
||||
React-runtimescheduler: cfbe85c3510c541ec6dc815c7729b41304b67961
|
||||
React-utils: f242eb7e7889419d979ca0e1c02ccc0ea6e43b29
|
||||
ReactCommon: f7da14a8827b72704169a48c929bcde802698361
|
||||
RNBackgroundFetch: 35c7183f6eeff69396d42c4b206e1ae2a21e9327
|
||||
RNBootSplash: de2c568373a9c79a66e9918b8929eb6c9a35246f
|
||||
RNCCheckbox: 43bcc6493611468af0e19f19f029dab3da8561c4
|
||||
RNCClipboard: 3f0451a8100393908bea5c5c5b16f96d45f30bfc
|
||||
RNCMaskedView: 949696f25ec596bfc697fc88e6f95cf0c79669b6
|
||||
RNDateTimePicker: 40ffda97d071a98a10fdca4fa97e3977102ccd14
|
||||
RNDeviceInfo: aad3c663b25752a52bf8fce93f2354001dd185aa
|
||||
RNExitApp: c4e052df2568b43bec8a37c7cd61194d4cfee2c3
|
||||
RNFileViewer: ce7ca3ac370e18554d35d6355cffd7c30437c592
|
||||
RNFlashList: e9b57a5553639f9b528cc50ab53f25831722ed62
|
||||
RNGestureHandler: 4fd316f1bdb8d7f6a54efc58da5923cb83014b19
|
||||
RNIap: 17583f958d35788a87948e94072ff6edd3580497
|
||||
RNImageCropPicker: d9616a0cb9b72e8551ff94a7a5021fbd29050aa5
|
||||
RNKeychain: 840f8e6f13be0576202aefcdffd26a4f54bfe7b5
|
||||
RNNotifee: 1448fd16c2a6f3e8abbc219801bf5be2435183e5
|
||||
RNPrivacySnapshot: 8eaf571478a353f2e5184f5c803164f22428b023
|
||||
RNReanimated: 7212582b487bceed64b2dbc6c15777b97922be21
|
||||
RNScreens: d2a12528d1abe4922e7ee5c9a00dd40c827c2ab5
|
||||
RNSecureRandom: 07efbdf2cd99efe13497433668e54acd7df49fef
|
||||
RNShare: 22717e910836a66cb7255b3b8c4ab06cbe346e27
|
||||
RNSVG: d7d7bc8229af3842c9cfc3a723c815a52cdd1105
|
||||
RNTooltips: 5424d4bf0b3d441104127943b1115cc7f0616b1f
|
||||
RNZipArchive: 9d90367b1573903b5561a8c0b911e5cc12626e74
|
||||
React-RuntimeHermes: 80c03a5215520c9733764ba11cbe535053c9746d
|
||||
React-runtimescheduler: 2cbd0f3625b30bba08e8768776107f6f0203159b
|
||||
React-utils: 9fa4e5d0b5e6c6c85c958f19d6ef854337886417
|
||||
ReactCommon: 9f285823dbe955099978d9bff65a7653ca029256
|
||||
RNBackgroundFetch: 0c49d5892a0e2f9c139e24ba498985cf0bf070c6
|
||||
RNBootSplash: 3bc12ecb62f69c5af6e6ddf0e6bef88f572ccdb5
|
||||
RNCCheckbox: df88c1c78a17869da84bb031c9d8185d417398a6
|
||||
RNCClipboard: efe1b27ad1ea378c60c8c8aabfd130961bbeb474
|
||||
RNCMaskedView: 4b5b12efdee55966f1d68f32d4b3401c2acf05c2
|
||||
RNDateTimePicker: 818460dc31b0dc5ec58289003e27dd8d022fb79c
|
||||
RNDeviceInfo: d3e91ffb33ee97a7982108476edb68cb3672efa6
|
||||
RNExitApp: 890cce29b4e01372c84b3b775f9a63f90d77de19
|
||||
RNFileViewer: 4b5d83358214347e4ab2d4ca8d5c1c90d869e251
|
||||
RNFlashList: fe872a2d1b4c859c64a7d7421628a1308ebb9e4f
|
||||
RNGestureHandler: 61302deb50c92cba160f5a11f00f69da48116724
|
||||
RNIap: aa38c2cc8a2a75ba8112d161ca084a0b611955df
|
||||
RNImageCropPicker: 30d770b383d84e1067d82ea7b5ed4fff851bbbb2
|
||||
RNKeychain: ffd0513e676445c637410b47249460cbf56bc9cb
|
||||
RNNotifee: b98fb71f678f6644fa48ec6d515ec6fcfc5214ba
|
||||
RNPrivacySnapshot: ccad3a548338c2f526bb7b1789af3fb0618b7d1d
|
||||
RNReanimated: bee9626cf4920f2910bf7c4f8a3dc569161a9475
|
||||
RNScreens: d0db5e9f28afd284a5193474d6be949f4cba888e
|
||||
RNSecureRandom: b64d263529492a6897e236a22a2c4249aa1b53dc
|
||||
RNShare: 5d7762ded21e1fff97dda6d41e963e22dce2d025
|
||||
RNSVG: d7cb8bd34550cf4c4fc7edd7ac627905e2b71f3f
|
||||
RNTooltips: 50ff94bd2bff84ef74279c9532d008f5fdcddb95
|
||||
RNZipArchive: 71befbdc20e7fbd4b64552a0b324ad0e8d0efefb
|
||||
SDWebImage: a7f831e1a65eb5e285e3fb046a23fcfbf08e696d
|
||||
SexyTooltip: 5c9b4dec52bfb317938cb0488efd9da3717bb6fd
|
||||
SocketRocket: abac6f5de4d4d62d24e11868d7a2f427e0ef940d
|
||||
SSZipArchive: fe6a26b2a54d5a0890f2567b5cc6de5caa600aef
|
||||
SwiftyRSA: 8c6dd1ea7db1b8dc4fb517a202f88bb1354bc2c6
|
||||
TOCropViewController: 80b8985ad794298fb69d3341de183f33d1853654
|
||||
toolbar-android: 2a73856e98b750d7e71ce4644d3f41cc98211719
|
||||
toolbar-android: c426ed5bd3dcccfed20fd79533efc0d1ae0ef018
|
||||
Yoga: 950bbfd7e6f04790fdb51149ed51df41f329fcc8
|
||||
|
||||
PODFILE CHECKSUM: aa07aca16c1d92394d8ce12f2c5fcaa8a3ae4997
|
||||
|
||||
4
apps/mobile/package-lock.json
generated
4
apps/mobile/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@notesnook/mobile",
|
||||
"version": "3.0.27",
|
||||
"version": "3.0.28",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@notesnook/mobile",
|
||||
"version": "3.0.27",
|
||||
"version": "3.0.28",
|
||||
"hasInstallScript": true,
|
||||
"license": "GPL-3.0-or-later",
|
||||
"workspaces": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@notesnook/mobile",
|
||||
"version": "3.0.27",
|
||||
"version": "3.0.29",
|
||||
"private": true,
|
||||
"license": "GPL-3.0-or-later",
|
||||
"workspaces": [
|
||||
@@ -54,4 +54,4 @@
|
||||
"react": "18.2.0",
|
||||
"react-native": "0.74.5"
|
||||
}
|
||||
}
|
||||
}
|
||||
1320
apps/web/package-lock.json
generated
1320
apps/web/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@notesnook/web",
|
||||
"description": "Your private note taking space",
|
||||
"version": "3.0.24",
|
||||
"version": "3.0.25",
|
||||
"private": true,
|
||||
"main": "./src/app.js",
|
||||
"homepage": "https://notesnook.com/",
|
||||
|
||||
@@ -64,8 +64,8 @@ function App() {
|
||||
{isFocused ? null : (
|
||||
<Global
|
||||
styles={`
|
||||
body {
|
||||
filter: brightness(0.95) grayscale(1);
|
||||
.nav-pane {
|
||||
opacity: 0.7;
|
||||
}
|
||||
.titlebar {
|
||||
background: var(--background-secondary) !important;
|
||||
@@ -150,23 +150,9 @@ function DesktopAppContents({ show, setShow }: DesktopAppContentsProps) {
|
||||
|
||||
useEffect(() => {
|
||||
if (isTablet) navPane.current?.collapse(0);
|
||||
else navPane.current?.expand(0);
|
||||
else if (navPane.current?.isCollapsed(0)) navPane.current?.expand(0);
|
||||
}, [isTablet]);
|
||||
|
||||
// useEffect(() => {
|
||||
// if (show) middlePane.current?.expand();
|
||||
// else middlePane.current?.collapse();
|
||||
// }, [show]);
|
||||
|
||||
// useEffect(() => {
|
||||
// if (isFocusMode) {
|
||||
// const middlePaneSize = middlePane.current?.getSize() || 20;
|
||||
// navPane.current?.collapse();
|
||||
// // the middle pane has to be resized because collapsing the nav
|
||||
// // pane increases the middle pane's size every time.
|
||||
// middlePane.current?.resize(middlePaneSize);
|
||||
// } else navPane.current?.expand();
|
||||
// }, [isFocusMode]);
|
||||
return (
|
||||
<>
|
||||
<Flex
|
||||
|
||||
@@ -573,14 +573,11 @@ function Tab(props: TabProps) {
|
||||
onAuxClick={(e) => {
|
||||
if (e.button == 1) onClose();
|
||||
}}
|
||||
onClick={() => onFocus()}
|
||||
{...listeners}
|
||||
{...attributes}
|
||||
>
|
||||
<Flex
|
||||
onMouseUp={(e) => {
|
||||
if (e.button == 0) onFocus();
|
||||
}}
|
||||
>
|
||||
<Flex>
|
||||
<Icon
|
||||
data-test-id={`tab-icon${isUnsaved ? "-unsaved" : ""}`}
|
||||
size={14}
|
||||
|
||||
@@ -59,6 +59,7 @@ type PaneOptions = {
|
||||
export type SplitPaneImperativeHandle = {
|
||||
collapse: (index: number) => void;
|
||||
expand: (index: number) => void;
|
||||
isCollapsed: (index: number) => boolean;
|
||||
};
|
||||
export const SplitPane = React.forwardRef<
|
||||
SplitPaneImperativeHandle,
|
||||
@@ -165,7 +166,7 @@ export const SplitPane = React.forwardRef<
|
||||
|
||||
if (wrapSize.current === 0) return;
|
||||
updatePaneLimitSizes(children);
|
||||
setSizes(paneSizes.current, wrapSize.current, false);
|
||||
setSizes(paneSizes.current, wrapSize.current, true);
|
||||
}, [children, childrenLength]);
|
||||
|
||||
const setSizes = useCallback(
|
||||
@@ -266,6 +267,9 @@ export const SplitPane = React.forwardRef<
|
||||
? lastCollapsedPaneSize.current
|
||||
: paneSizes.current[index].initialSize;
|
||||
setSizes(paneSizes.current, wrapSize.current);
|
||||
},
|
||||
isCollapsed: (index: number) => {
|
||||
return paneSizes.current[index].collapsed;
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
@@ -93,14 +93,9 @@ const features: Record<FeatureKeys, Feature> = {
|
||||
]
|
||||
: [
|
||||
{
|
||||
title: "Notesnook Gift Cards",
|
||||
title: "Better tabs",
|
||||
subtitle:
|
||||
"You can now gift Notesnook Pro to your friends and family. Gift cards are available in 1, 3, and 5-year plans at https://notesnook.com/giftcards."
|
||||
},
|
||||
{
|
||||
title: "Sorted search results",
|
||||
subtitle:
|
||||
"Search results are now sorted by date created by default."
|
||||
"Tabs have been overhauled to be more predictable and easier to use. Give it a try! We are sure you'll love it."
|
||||
}
|
||||
],
|
||||
cta: {
|
||||
|
||||
@@ -68,7 +68,7 @@ async function resetReminders(reminders: FilteredSelector<Reminder>) {
|
||||
)
|
||||
return;
|
||||
|
||||
for await (const reminder of reminders) {
|
||||
for await (const reminder of reminders.iterate()) {
|
||||
if (reminder.disabled) continue;
|
||||
|
||||
// set a one time reminder at the snoozed date
|
||||
|
||||
@@ -148,7 +148,10 @@ function SubNotebooks({ rootId, isCollapsed, onClick }: SubNotebooksProps) {
|
||||
const toggleSelection = useSelectionStore(
|
||||
(store) => store.toggleSelectionMode
|
||||
);
|
||||
const rootNotebook = usePromise(() => db.notebooks.notebook(rootId));
|
||||
const rootNotebook = usePromise(
|
||||
() => db.notebooks.notebook(rootId),
|
||||
[rootId]
|
||||
);
|
||||
const notebooks = useNotebookStore((store) => store.notebooks);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
5
fastlane/metadata/android/en-US/changelogs/15179.txt
Normal file
5
fastlane/metadata/android/en-US/changelogs/15179.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
- New and improved editor tabs with history
|
||||
- Fixed homescreen widget bugs
|
||||
- Many small bug fixes and improvements
|
||||
|
||||
Thank you for using Notesnook!
|
||||
6
fastlane/metadata/android/en-US/changelogs/15184.txt
Normal file
6
fastlane/metadata/android/en-US/changelogs/15184.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
- New and improved editor tabs with history
|
||||
- Fixed a crash on app launch faced by some users
|
||||
- Fixed homescreen note widget does not open correct note
|
||||
- Many small bug fixes and improvements
|
||||
|
||||
Thank you for using Notesnook!
|
||||
@@ -71,5 +71,6 @@
|
||||
"license": "GPL-3.0-or-later",
|
||||
"volta": {
|
||||
"node": "20.12.0"
|
||||
}
|
||||
},
|
||||
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
|
||||
}
|
||||
|
||||
@@ -205,9 +205,18 @@ const Tiptap = ({
|
||||
if (tabRef.current.session?.noteId) {
|
||||
clearTimeout(noteStateUpdateTimer.current);
|
||||
noteStateUpdateTimer.current = setTimeout(() => {
|
||||
const { to, from } =
|
||||
editors[tabRef.current?.id]?.state.selection || {};
|
||||
}, 500);
|
||||
post(
|
||||
EditorEvents.saveScroll,
|
||||
{
|
||||
selection: {
|
||||
to: editors[tabRef.current.id]?.state.selection.to,
|
||||
from: editors[tabRef.current.id]?.state.selection.from
|
||||
}
|
||||
},
|
||||
tabRef.current.id,
|
||||
tabRef.current.session?.noteId
|
||||
);
|
||||
}, 300);
|
||||
}
|
||||
},
|
||||
onCreate() {
|
||||
@@ -547,7 +556,7 @@ const Tiptap = ({
|
||||
</>
|
||||
)}
|
||||
|
||||
{controller.loading || tab.session?.locked ? (
|
||||
{controller.loading || tab.session?.noteLocked ? (
|
||||
<div
|
||||
style={{
|
||||
width: "100%",
|
||||
@@ -559,13 +568,15 @@ const Tiptap = ({
|
||||
paddingLeft: 12,
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: tab.session?.locked ? "center" : "flex-start",
|
||||
justifyContent: tab.session?.locked ? "center" : "flex-start",
|
||||
alignItems: tab.session?.noteLocked ? "center" : "flex-start",
|
||||
justifyContent: tab.session?.noteLocked
|
||||
? "center"
|
||||
: "flex-start",
|
||||
boxSizing: "border-box",
|
||||
rowGap: 10
|
||||
}}
|
||||
>
|
||||
{tab.session?.locked ? (
|
||||
{tab.session?.noteLocked ? (
|
||||
<>
|
||||
<p
|
||||
style={{
|
||||
@@ -605,7 +616,9 @@ const Tiptap = ({
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
rowGap: 10
|
||||
rowGap: 10,
|
||||
justifyContent: "center",
|
||||
alignItems: "center"
|
||||
}}
|
||||
>
|
||||
<input
|
||||
|
||||
@@ -71,7 +71,7 @@ export const useTabStore = create(
|
||||
}
|
||||
}),
|
||||
{
|
||||
name: "tab-storage-v3",
|
||||
name: "tab-storage-v5",
|
||||
storage: createJSONStorage(() => localStorage)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -57,7 +57,8 @@ export const TaskListNode = TaskList.extend({
|
||||
rendered: false,
|
||||
parseHTML: (element) => {
|
||||
// do not update stats for nested task lists
|
||||
if (!!element.closest("ul")) return { checked: 0, total: 0 };
|
||||
if (element.parentElement?.closest("ul"))
|
||||
return { checked: 0, total: 0 };
|
||||
const total = element.querySelectorAll("li.checklist--item").length;
|
||||
const checked = element.querySelectorAll(
|
||||
"li.checklist--item.checked"
|
||||
|
||||
@@ -284,7 +284,7 @@ function PaletteButton(props: PaletteButtonProps) {
|
||||
ml: [2, 2, 1],
|
||||
bg,
|
||||
":hover:not(:disabled):not(:active)": {
|
||||
bg: bg?.startsWith("#") ? colord(bg).darken(5).toRgbString() : "hover"
|
||||
bg: bg?.startsWith("#") ? colord(bg).darken().toRgbString() : "hover"
|
||||
},
|
||||
...sx
|
||||
}}
|
||||
|
||||
@@ -137,7 +137,7 @@ export function ColorTool(props: ColorToolProps) {
|
||||
mr: 0,
|
||||
bg: activeColor || "transparent",
|
||||
":hover:not(:disabled):not(:active)": {
|
||||
bg: tColor ? tColor.darken(5).toRgbString() : "transparent"
|
||||
bg: tColor ? tColor.darken().toRgbString() : "transparent"
|
||||
}
|
||||
}}
|
||||
onOpen={toggle}
|
||||
|
||||
Reference in New Issue
Block a user