Compare commits

...

69 Commits

Author SHA1 Message Date
Ammar Ahmed
9bde6ce190 mobile: bump version 2024-08-17 17:51:32 +05:00
Ammar Ahmed
d94474de79 mobile: fix android crash api 34 2024-08-10 16:29:05 +05:00
Ammar Ahmed
fcf0e0c531 mobile: update Podfile.lock 2024-08-10 12:35:34 +05:00
Ammar Ahmed
24048ebfbe mobile: remove USE_FULL_SCREEN_INTENT 2024-08-10 11:57:57 +05:00
Ammar Ahmed
5ae8cdd5b9 mobile: fix build errors 2024-08-10 11:31:37 +05:00
Ammar Ahmed
74187b335f ci: set java 17
Signed-off-by: Ammar Ahmed <40239442+ammarahm-ed@users.noreply.github.com>
2024-08-09 15:26:12 +05:00
Ammar Ahmed
16fc689299 mobile: release v3.0.13 2024-08-09 15:01:19 +05:00
Ammar Ahmed
578a9de680 mobile: fix ios build 2024-08-09 12:25:59 +05:00
Ammar Ahmed
62d475b2ef mobile: upgrade to react native 0.74.4 2024-08-09 12:25:59 +05:00
Ammar Ahmed
69c902c6c1 mobile: fix title input changes not detected 2024-08-09 12:25:14 +05:00
Abdullah Atta
c8c1028cbc core: fix least relevant results shown on top 2024-08-09 11:52:55 +05:00
Abdullah Atta
313807c384 web: remove Report an issue button from status bar 2024-08-09 11:47:56 +05:00
Abdullah Atta
5dc0e15094 web: fix last change in editor not getting saved 2024-08-09 10:35:53 +05:00
Ammar Ahmed
12c5b6d227 mobile: release v3.0.12 2024-07-29 10:06:21 +05:00
Ammar Ahmed
364ae51e36 mobile: fix backup share button not working 2024-07-29 09:53:20 +05:00
Ammar Ahmed
18947e0c93 mobile: fix missing fonts in share sheet 2024-07-29 09:43:37 +05:00
François Martin
3880db4339 global: clarify explanations for force push and force pull (#6255)
Signed-off-by: François Martin <f.martin@fastmail.com>
2024-07-29 09:38:30 +05:00
Ammar Ahmed
ae5b0b6fcc mobile: fix share sheet not loading on ios 2024-07-29 09:25:46 +05:00
Abdullah Atta
2c729f90cc global: update lockfiles 2024-07-27 13:30:25 +05:00
Ammar Ahmed
800514d769 mobile: fix position of password input 2024-07-27 12:49:57 +05:00
Ammar Ahmed
b03b9482dc mobile: app stuck after unlock 2024-07-27 12:49:57 +05:00
Abdullah Atta
9019490dbd web: bump version to v3.0.13 2024-07-27 11:16:42 +05:00
Abdullah Atta
4a3e23c288 web: fix reminder can't be set in january 2024-07-27 11:16:09 +05:00
Ammar Ahmed
1800ebea2d mobile: fix keyboard blocks continue button on applock 2024-07-27 11:12:09 +05:00
Ammar Ahmed
a708c9e9eb mobile: fix home shortcut not working 2024-07-27 10:56:09 +05:00
Abdullah Atta
2aeb875fec web: fix crash on moving temporary tab 2024-07-27 10:08:38 +05:00
Abdullah Atta
a8164e9f6c web: enter in title should focus editor 2024-07-27 09:46:37 +05:00
Abdullah Atta
0ee8e738e5 web: fix attachments ui in properties 2024-07-27 09:46:23 +05:00
Abdullah Atta
8fdef2ac7d web: fix attachments flicker in editor note properties 2024-07-27 09:46:23 +05:00
Abdullah Atta
920b1d91f3 web: bump version to 3.0.12 2024-07-22 15:42:18 +05:00
Abdullah Atta
0ad382aced web: fix incorrect attachment upload progress 2024-07-22 15:30:38 +05:00
Abdullah Atta
c8aa8e37cf web: add support for clearing attachments cache 2024-07-22 15:30:21 +05:00
Abdullah Atta
9a37f7c506 web: fix image picker dialog shown for non-image attachments 2024-07-22 13:08:49 +05:00
Abdullah Atta
717750d5d4 web: subscribe to user related events before fetching user 2024-07-22 13:08:36 +05:00
Abdullah Atta
1274ecc3b5 core: refresh token on user subscription change 2024-07-22 13:08:12 +05:00
Abdullah Atta
4c2ad4567c setup: use listr2 2024-07-20 10:34:40 +05:00
Abdullah Atta
ebc01af34a global: publish packages 2024-07-20 10:34:28 +05:00
Abdullah Atta
e66d8eee13 ui: add support for ss 2024-07-20 01:16:46 +05:00
Abdullah Atta
55e6a4b65a editor: do not throw during ssr 2024-07-20 00:42:54 +05:00
Abdullah Atta
0aa1db584d editor: do not keep last line in view for readonly editor 2024-07-19 23:50:20 +05:00
Abdullah Atta
a0e6266d28 ui: fix Cannot access 'mouseMoveListenerAttached' before initialization 2024-07-19 23:26:35 +05:00
Abdullah Atta
bd0aaed863 ui: add support for ssr 2024-07-19 23:22:47 +05:00
Abdullah Atta
9410c42f29 web: fix search icon overlapping route header text 2024-07-19 12:42:18 +05:00
Abdullah Atta
80186c1812 web: fix type errors 2024-07-19 11:11:51 +05:00
Abdullah Atta
37dfda5c54 desktop: set updaterCacheDirName in app-update.yml 2024-07-19 10:52:59 +05:00
Abdullah Atta
ec83517dc5 desktop: fix update check gives no feedback in ui 2024-07-19 10:51:10 +05:00
Abdullah Atta
2eb4911592 web: bump version to 3.0.11 2024-07-18 17:41:26 +05:00
Abdullah Atta
cd0a6a8fcb editor: fix editing link adds a new link right beside it 2024-07-18 17:38:18 +05:00
Abdullah Atta
b15f192244 desktop: update esbuild 2024-07-18 16:47:08 +05:00
Abdullah Atta
406cb663c9 editor: pasting list item with single spaced paragraphs shouldn't break formatting 2024-07-18 12:02:39 +05:00
Abdullah Atta
301a30a50a editor: copying a link from a list item shouldn't add spaces at the end 2024-07-18 12:02:39 +05:00
Abdullah Atta
81e3432143 editor: fix copying multiple lists only copied the first one 2024-07-18 12:02:39 +05:00
Abdullah Atta
c43c2936ac web: use resizeobserver to wait for scroll container to resize 2024-07-18 11:56:48 +05:00
Abdullah Atta
fdea1807d2 web: fix editor scroll bar hiding sometimes on startup 2024-07-18 11:56:48 +05:00
Abdullah Atta
5439578fcf server(theme): add health endpoint 2024-07-17 15:25:52 +05:00
Abdullah Atta
e05e52f870 web: fix crash on sync 2024-07-16 17:18:25 +05:00
Abdullah Atta
1c6243d12e web: fix error on resetting database on crash 2024-07-16 17:18:25 +05:00
Abdullah Atta
a51dfb5b6e web: remove all traces of immer 2024-07-16 17:18:25 +05:00
Abdullah Atta
c98bddd35b web: use sqlite for storing editor session data 2024-07-16 17:18:25 +05:00
Abdullah Atta
1eb80ccc88 web: get rid of dialog controller
dialog controller was redundant and created unnecessary overhead.
It also coupled all the dialogs together so you couldn't import a dialog
independently. This new change isolates each dialog to its own module
while keeping the behaviour mostly the same.
2024-07-16 17:18:25 +05:00
Abdullah Atta
5a346aa7de web: fix tags & colors not updating/loading on opening a note 2024-07-16 17:18:25 +05:00
Abdullah Atta
910095a769 web: replace immer with mutative for perf reasons 2024-07-16 17:18:25 +05:00
Abdullah Atta
119059befa core: update tag on rename instead of upserting 2024-07-16 17:18:25 +05:00
Abdullah Atta
a8f5dea315 core: fix type definition 2024-07-16 17:18:25 +05:00
Abdullah Atta
ca0a4cb02c core: add localStorage like ConfigStorage based on SQLite 2024-07-16 17:18:25 +05:00
Abdullah Atta
a04cd6b8dc core: send event when directly unlinking a relation 2024-07-16 17:18:25 +05:00
Abdullah Atta
3e4ab0f6df setup: update typescript to 5.5 2024-07-16 17:18:25 +05:00
Abdullah Atta
a7fe1aca44 global: update lockfiles 2024-07-16 17:18:25 +05:00
Abdullah Atta
ff0188f602 web: fix app lock verification always succeeds 2024-07-12 14:30:37 +05:00
214 changed files with 10851 additions and 59565 deletions

View File

@@ -22,7 +22,7 @@ jobs:
- name: Use specific Java version for the builds
uses: joschi/setup-jdk@v2
with:
java-version: "11"
java-version: "17"
architecture: "x64"
- name: Install node modules

View File

@@ -1,3 +1,4 @@
owner: streetwriters
repo: notesnook
provider: github
updaterCacheDirName: Notesnook

File diff suppressed because it is too large Load Diff

View File

@@ -2,7 +2,7 @@
"name": "@notesnook/desktop",
"productName": "Notesnook",
"description": "Your private note taking space",
"version": "3.0.10",
"version": "3.0.13",
"appAppleId": "1544027013",
"private": true,
"main": "./dist/index.js",
@@ -16,7 +16,7 @@
"@trpc/server": "10.38.3",
"better-sqlite3-multiple-ciphers": "^9.5.0",
"electron-trpc": "0.5.2",
"electron-updater": "6.1.4",
"electron-updater": "^6.2.1",
"icojs": "^0.17.1",
"sodium-native": "^4.1.1",
"typed-emitter": "^2.1.0",
@@ -28,8 +28,8 @@
"@types/yargs": "^17.0.24",
"chokidar": "^3.5.3",
"electron": "^29.3.1",
"electron-builder": "^25.0.0-alpha.11",
"esbuild": "^0.20.0",
"electron-builder": "^24.13.3",
"esbuild": "^0.23.0",
"kysely": "^0.27.3",
"node-gyp-build": "^4.8.0",
"prebuildify": "^6.0.1",

View File

@@ -46,11 +46,11 @@ if (args.rebuild || !existsSync(path.join(webAppPath, "build"))) {
// temporary until there's support for prebuilt binaries for linux ARM
if (os.platform() === "linux") await patchBetterSQLite3();
if (os.platform() === "win32")
await exec(
`npx prebuildify --arch=arm64 --strip -t electron@${packageJson.devDependencies.electron}`,
path.join(__dirname, "..", "node_modules", "sodium-native")
);
// if (os.platform() === "win32")
// await exec(
// `npx prebuildify --arch=arm64 --strip -t electron@${packageJson.devDependencies.electron}`,
// path.join(__dirname, "..", "node_modules", "sodium-native")
// );
await fs.cp(path.join(webAppPath, "build"), "build", {
recursive: true,

View File

@@ -61,7 +61,18 @@ export const updaterRouter = t.router({
"update-not-available"
),
onAvailable: createSubscription<"update-available", UpdateInfo>(
"update-available"
"update-available",
() => {
if (!config.automaticUpdates) return false;
autoUpdater.emit("download-progress", {
bytesPerSecond: 0,
delta: 0,
percent: 0,
total: 100,
transferred: 0
});
return true;
}
),
onError: createSubscription("error")
});
@@ -69,10 +80,11 @@ export const updaterRouter = t.router({
function createSubscription<
TName extends keyof AppUpdaterEvents,
TReturnType = Parameters<AppUpdaterEvents[TName]>[0]
>(eventName: TName) {
>(eventName: TName, handler?: (args: TReturnType) => boolean) {
return t.procedure.subscription(() => {
return observable<TReturnType>((emit) => {
const listener: AppUpdaterEvents[TName] = (...args: any[]) => {
if (handler?.(args[0])) return;
emit.next(args[0]);
};
autoUpdater.removeAllListeners(eventName);

View File

@@ -35,6 +35,7 @@ async function configureAutoUpdater() {
autoUpdater.allowDowngrade = false;
autoUpdater.allowPrerelease = false;
autoUpdater.autoInstallOnAppQuit = true;
autoUpdater.disableWebInstaller = true;
}
export { configureAutoUpdater };

View File

@@ -38,7 +38,7 @@ DerivedData
*.ipa
*.xcuserstate
*.hprof
ios/.xcode.env.local
**/.xcode.env.local
# Android/IntelliJ
#
rn-build-deps/

View File

@@ -25,7 +25,6 @@ import { I18nManager, View } from "react-native";
import "react-native-gesture-handler";
import { GestureHandlerRootView } from "react-native-gesture-handler";
import { SafeAreaProvider } from "react-native-safe-area-context";
import { initializeLogger } from "./common/database/logger";
import AppLockedOverlay from "./components/app-lock-overlay";
import { withErrorBoundry } from "./components/exception-handler";
import GlobalSafeAreaProvider from "./components/globalsafearea";
@@ -41,33 +40,24 @@ import { useUserStore } from "./stores/use-user-store";
I18nManager.allowRTL(false);
I18nManager.forceRTL(false);
I18nManager.swapLeftAndRightInRTL(false);
const { appLockEnabled, appLockMode } = SettingsService.get();
if (appLockEnabled || appLockMode !== "none") {
useUserStore.getState().lockApp(true);
}
const App = () => {
const init = useAppEvents();
useAppEvents();
//@ts-ignore
globalThis["IS_MAIN_APP_RUNNING"] = true;
useEffect(() => {
initializeLogger()
.catch((e) => {
console.log(e);
})
.finally(() => {
const { appLockEnabled, appLockMode } = SettingsService.get();
if (appLockEnabled || appLockMode !== "none") {
useUserStore.getState().lockApp(true);
}
//@ts-ignore
globalThis["IS_MAIN_APP_RUNNING"] = true;
init();
setTimeout(async () => {
SettingsService.onFirstLaunch();
await Notifications.get();
if (SettingsService.get().notifNotes) {
Notifications.pinQuickNote(true);
}
TipManager.init();
}, 100);
});
// eslint-disable-next-line react-hooks/exhaustive-deps
SettingsService.onFirstLaunch();
setTimeout(async () => {
await Notifications.get();
if (SettingsService.get().notifNotes) {
Notifications.pinQuickNote(true);
}
TipManager.init();
}, 100);
}, []);
return (
<View

View File

@@ -23,7 +23,9 @@ import { Platform } from "react-native";
import { setLogger } from ".";
import { RNSqliteDriver } from "./sqlite.kysely";
let loggerLoaded = false;
const initializeLogger = async () => {
if (loggerLoaded) return;
await initialize({
dialect: (name) => ({
createDriver: () => {
@@ -37,6 +39,7 @@ const initializeLogger = async () => {
journalMode: Platform.OS === "ios" ? "DELETE" : "WAL"
});
setLogger();
loggerLoaded = true;
};
export { initializeLogger };

View File

@@ -18,7 +18,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import React, { useCallback, useEffect, useRef } from "react";
import { AppStateStatus, Platform, TextInput, View } from "react-native";
import {
AppStateStatus,
Platform,
TextInput,
useWindowDimensions,
View
} from "react-native";
//@ts-ignore
import { useThemeColors } from "@notesnook/theme";
import { DatabaseLogger } from "../../common/database";
@@ -46,6 +52,7 @@ import Input from "../ui/input";
import Seperator from "../ui/seperator";
import Heading from "../ui/typography/heading";
import Paragraph from "../ui/typography/paragraph";
import { KeyboardAwareScrollView } from "react-native-keyboard-aware-scroll-view";
const getUser = () => {
const user = MMKV.getString("user");
@@ -86,6 +93,7 @@ const AppLockedOverlay = () => {
const appState = useAppState();
const lastAppState = useRef<AppStateStatus>(appState);
const biometricUnlockAwaitingUserInput = useRef(false);
const { height } = useWindowDimensions();
const keyboardType = useSettingStore(
(state) => state.settings.applockKeyboardType
);
@@ -191,15 +199,20 @@ const AppLockedOverlay = () => {
}, [appState, onUnlockAppRequested, appLocked]);
return appLocked ? (
<View
<KeyboardAwareScrollView
style={{
backgroundColor: colors.primary.background,
width: "100%",
height: "100%",
position: "absolute",
zIndex: 999,
justifyContent: "center"
zIndex: 999
}}
contentContainerStyle={{
justifyContent: "center",
minHeight: height
}}
keyboardDismissMode="interactive"
keyboardShouldPersistTaps="handled"
>
<Toast context="local" />
<View
@@ -314,7 +327,7 @@ const AppLockedOverlay = () => {
</View>
</View>
</View>
</View>
</KeyboardAwareScrollView>
) : null;
};

View File

@@ -97,6 +97,7 @@ import {
import { getGithubVersion } from "../utils/github-version";
import { tabBarRef } from "../utils/global-refs";
import { sleep } from "../utils/time";
import { initializeLogger } from "../common/database/logger";
const onCheckSyncStatus = async (type: SyncStatusEvent) => {
const { disableSync, disableAutoSync } = SettingsService.get();
@@ -280,8 +281,108 @@ const onSubscriptionError = async (error: RNIap.PurchaseError) => {
const SodiumEventEmitter = new NativeEventEmitter(NativeModules.Sodium);
const doAppLoadActions = async () => {
if (SettingsService.get().sessionExpired) {
eSendEvent(eLoginSessionExpired);
return;
}
notifee.setBadgeCount(0);
if (!(await db.user.getUser())) {
setLoginMessage();
return;
}
await useMessageStore.getState().setAnnouncement();
if (NewFeature.present()) return;
if (await checkAppUpdateAvailable()) return;
if (await checkForRateAppRequest()) return;
if (await PremiumService.getRemainingTrialDaysStatus()) return;
if (SettingsService.get().introCompleted) {
useMessageStore.subscribe((state) => {
const dialogs = state.dialogs;
if (dialogs.length > 0) {
eSendEvent(eOpenAnnouncementDialog, dialogs[0]);
}
});
}
};
const checkAppUpdateAvailable = async () => {
if (__DEV__ || Config.isTesting === "true" || Config.FDROID_BUILD || BETA)
return;
try {
const version =
Config.GITHUB_RELEASE === "true"
? await getGithubVersion()
: await checkVersion();
if (!version || !version?.needsUpdate) return false;
setUpdateAvailableMessage(version);
return true;
} catch (e) {
return false;
}
};
const checkForRateAppRequest = async () => {
const rateApp = SettingsService.get().rateApp as number;
if (
rateApp &&
rateApp < Date.now() &&
!useMessageStore.getState().message?.visible
) {
setRateAppMessage();
return false;
}
return false;
};
const IsDatabaseMigrationRequired = () => {
if (!db.migrations.required() || useUserStore.getState().appLocked)
return false;
presentSheet({
component: <Migrate />,
onClose: () => {
if (!db.migrations.required()) {
initializeDatabase();
}
},
disableClosing: true
});
return true;
};
const initializeDatabase = async (password?: string) => {
if (useUserStore.getState().appLocked) return;
if (!db.isInitialized) {
RNBootSplash.hide({ fade: true });
DatabaseLogger.info("Initializing database");
try {
await setupDatabase(password);
await db.init();
} catch (e) {
DatabaseLogger.error(e as Error);
ToastManager.error(e as Error, "Error initializing database", "global");
}
}
if (IsDatabaseMigrationRequired()) return;
if (db.isInitialized) {
Notifications.setupReminders(true);
if (SettingsService.get().notifNotes) {
Notifications.pinQuickNote(false);
}
useSettingStore.getState().setAppLoading(false);
DatabaseLogger.info("Database initialized");
}
Walkthrough.init();
};
export const useAppEvents = () => {
const loading = useSettingStore((state) => state.isAppLoading);
const isAppLoading = useSettingStore((state) => state.isAppLoading);
const [setLastSynced, setUser, appLocked, syncing] = useUserStore((state) => [
state.setLastSynced,
state.setUser,
@@ -312,7 +413,7 @@ export const useAppEvents = () => {
}, [setLastSynced]);
useEffect(() => {
if (loading) return;
if (isAppLoading) return;
let subscriptions: EventManagerSubscription[] = [];
const eventManager = db.eventManager;
@@ -327,7 +428,7 @@ export const useAppEvents = () => {
return () => {
subscriptions.forEach((sub) => sub?.unsubscribe?.());
};
}, [loading, onSyncComplete]);
}, [isAppLoading, onSyncComplete]);
const subscribeToPurchaseListeners = useCallback(async () => {
if (Platform.OS === "android") {
@@ -572,7 +673,7 @@ export const useAppEvents = () => {
});
}
let sub: NativeEventSubscription;
if (!loading && !appLocked) {
if (!isAppLoading && !appLocked) {
setTimeout(() => {
sub = AppState.addEventListener("change", onAppStateChanged);
if (
@@ -594,7 +695,7 @@ export const useAppEvents = () => {
sub?.remove();
unsubscribePurchaseListeners();
};
}, [loading, appLocked, checkAutoBackup]);
}, [isAppLoading, appLocked, checkAutoBackup]);
useEffect(() => {
if (!appLocked && !syncing && refValues.current.backupDidWait) {
@@ -643,127 +744,22 @@ export const useAppEvents = () => {
}
useEffect(() => {
if (!loading) {
if (!isAppLoading) {
onUserUpdated();
doAppLoadActions();
}
}, [loading, onUserUpdated]);
const initializeDatabase = useCallback(async (password?: string) => {
const IsDatabaseMigrationRequired = () => {
if (!db.migrations.required() || useUserStore.getState().appLocked)
return false;
presentSheet({
component: <Migrate />,
onClose: () => {
if (!db.migrations.required()) {
initializeDatabase();
}
},
disableClosing: true
});
return true;
};
if (useUserStore.getState().appLocked) return;
if (!db.isInitialized) {
RNBootSplash.hide({ fade: true });
DatabaseLogger.info("Initializing database");
try {
await setupDatabase(password);
await db.init();
} catch (e) {
DatabaseLogger.error(e as Error);
ToastManager.error(e as Error, "Error initializing database", "global");
}
}
if (IsDatabaseMigrationRequired()) return;
if (db.isInitialized) {
Notifications.setupReminders(true);
if (SettingsService.get().notifNotes) {
Notifications.pinQuickNote(false);
}
useSettingStore.getState().setAppLoading(false);
DatabaseLogger.info("Database initialized");
}
Walkthrough.init();
}, []);
}, [isAppLoading, onUserUpdated]);
useEffect(() => {
let sub: () => void;
if (appLocked) {
const sub = useUserStore.subscribe((state) => {
if (!state.appLocked && useSettingStore.getState().isAppLoading) {
console.log("DB initialized");
if (!appLocked && isAppLoading) {
initializeLogger()
.catch((e) => {
console.log(e);
})
.finally(() => {
//@ts-ignore
initializeDatabase();
sub();
}
});
});
}
return () => {
sub?.();
};
}, [appLocked, initializeDatabase]);
return initializeDatabase;
};
const doAppLoadActions = async () => {
if (SettingsService.get().sessionExpired) {
eSendEvent(eLoginSessionExpired);
return;
}
notifee.setBadgeCount(0);
if (!(await db.user.getUser())) {
setLoginMessage();
return;
}
await useMessageStore.getState().setAnnouncement();
if (NewFeature.present()) return;
if (await checkAppUpdateAvailable()) return;
if (await checkForRateAppRequest()) return;
if (await PremiumService.getRemainingTrialDaysStatus()) return;
if (SettingsService.get().introCompleted) {
useMessageStore.subscribe((state) => {
const dialogs = state.dialogs;
if (dialogs.length > 0) {
eSendEvent(eOpenAnnouncementDialog, dialogs[0]);
}
});
}
};
const checkAppUpdateAvailable = async () => {
if (__DEV__ || Config.isTesting === "true" || Config.FDROID_BUILD || BETA)
return;
try {
const version =
Config.GITHUB_RELEASE === "true"
? await getGithubVersion()
: await checkVersion();
if (!version || !version?.needsUpdate) return false;
setUpdateAvailableMessage(version);
return true;
} catch (e) {
return false;
}
};
const checkForRateAppRequest = async () => {
const rateApp = SettingsService.get().rateApp as number;
if (
rateApp &&
rateApp < Date.now() &&
!useMessageStore.getState().message?.visible
) {
setRateAppMessage();
return false;
}
return false;
}, [appLocked, isAppLoading]);
};

View File

@@ -62,7 +62,6 @@ import {
} from "../services/event-manager";
import { useSettingStore } from "../stores/use-setting-store";
import {
eClearEditor,
eCloseFullscreenEditor,
eOnEnterEditor,
eOnExitEditor,
@@ -286,9 +285,10 @@ const _TabsHolder = () => {
break;
case "mobile":
if (
state &&
!state?.movedAway &&
useTabStore.getState().getCurrentNoteId()
(state &&
!state?.movedAway &&
useTabStore.getState().getCurrentNoteId()) ||
editorState().movedAway === false
) {
tabBarRef.current?.goToIndex(2, false);
} else {

View File

@@ -16,7 +16,7 @@
"html-to-text": "9.0.5",
"phone": "^3.1.14",
"qclone": "^1.2.0",
"react-native-actions-sheet": "0.9.6",
"react-native-actions-sheet": "0.9.7",
"react-native-check-version": "https://github.com/flexible-agency/react-native-check-version",
"react-native-drax": "^0.10.2",
"react-native-image-zoom-viewer": "^3.0.1",

View File

@@ -475,7 +475,7 @@ export const settingsGroups: SettingSection[] = [
{
id: "pull-sync",
name: "Force pull changes",
description: `Use this if some changes are not appearing on this device from other devices. This will pull everything from the server and overwrite with whatever is one this device.\n\nThese must only be used for troubleshooting. Using them regularly for sync is not recommended and will lead to unexpected data loss and other issues. If you are having persistent issues with sync, please report them to us at support@streetwriters.co.`,
description: `Use this if changes from other devices are not appearing on this device. This will overwrite the data on this device with the latest data from the server.\n\nThis must only be used for troubleshooting. Using it regularly for sync is not recommended and will lead to unexpected data loss and other issues. If you are having persistent issues with sync, please report them to us at support@streetwriters.co.`,
modifer: () => {
presentDialog({
title: "Force Pull changes",
@@ -497,7 +497,7 @@ export const settingsGroups: SettingSection[] = [
{
id: "push-sync",
name: "Force push changes",
description: `Use this if some changes are not appearing on this device from other devices. This will pull everything from the server and overwrite with whatever is one this device.`,
description: `Use this if changes made on this device are not appearing on other devices. This will overwrite the data on the server with the data from this device.\n\nThis must only be used for troubleshooting. Using it regularly for sync is not recommended and will lead to unexpected data loss and other issues. If you are having persistent issues with sync, please report them to us at support@streetwriters.co.`,
modifer: () => {
presentDialog({
title: "Force Push changes",

View File

@@ -141,7 +141,6 @@ const onBoot = async () => {
}
await Notifications.setupReminders();
SettingsService.init();
if (SettingsService.get().notifNotes) {
Notifications.pinQuickNote(false);
}

View File

@@ -171,7 +171,6 @@ async function run(progress = false, context) {
}
let path;
let backupFilePath;
let backupFileName = "notesnook_backup_" + Date.now();
if (Platform.OS === "ios") {
@@ -236,7 +235,7 @@ async function run(progress = false, context) {
await sleep(300);
if (showBackupCompleteSheet) {
presentBackupCompleteSheet(backupFilePath);
presentBackupCompleteSheet(path);
} else {
progress && eSendEvent(eCloseSheet);
}

View File

@@ -17,7 +17,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { Platform } from "react-native";
import { NativeModules, Platform } from "react-native";
import { enabled } from "react-native-privacy-snapshot";
import { MMKV } from "../common/database/mmkv";
import {
@@ -118,14 +118,18 @@ function setPrivacyScreen(settings: SettingStore["settings"]) {
NotesnookModule.setSecureMode(true);
} else {
enabled(true);
ScreenGuardModule.register({ backgroundColor: "#000000" });
if (NativeModules.ScreenGuard) {
ScreenGuardModule.register({ backgroundColor: "#000000" });
}
}
} else {
if (Platform.OS === "android") {
NotesnookModule.setSecureMode(false);
} else {
enabled(false);
ScreenGuardModule.unregister();
if (NativeModules.ScreenGuard) {
ScreenGuardModule.unregister();
}
}
}
}

View File

@@ -17,8 +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 { Profile } from "@notesnook/core";
import { User } from "@notesnook/core";
import { Profile, User } from "@notesnook/core";
import create, { State } from "zustand";
export enum SyncStatus {
@@ -56,7 +55,9 @@ export const useUserStore = create<UserStore>((set) => ({
set({ syncing: syncing, lastSyncStatus: status });
},
setLastSynced: (lastSynced) => set({ lastSynced: lastSynced }),
lockApp: (appLocked) => set({ appLocked }),
lockApp: (appLocked) => {
set({ appLocked });
},
lastSyncStatus: SyncStatus.Never,
disableAppLockRequests: false,
setDisableAppLockRequests: (disableAppLockRequests) => {

View File

@@ -1,4 +1,7 @@
source 'https://rubygems.org'
# You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
ruby ">= 2.6.10"
gem 'cocoapods', '~> 1.12'
# Cocoapods 1.15 introduced a bug which break the build. We will remove the upper
# bound in the template on Cocoapods with next React Native release.
gem 'cocoapods', '>= 1.13', '< 1.15'
gem 'activesupport', '>= 6.1.7.5', '< 7.1.0'

View File

@@ -1,5 +1,7 @@
apply plugin: "com.android.application"
apply plugin: "org.jetbrains.kotlin.android"
apply plugin: "com.facebook.react"
apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.gradle"
import com.android.build.OutputFile
@@ -96,10 +98,14 @@ def getNpmVersion() {
return jsonPackage["version"]
}
def isBuildingAAB = gradle.startParameter.getTaskNames().any { it.contains("bundleRelease") }
android {
compileSdkVersion rootProject.ext.compileSdkVersion
ndkVersion rootProject.ext.ndkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
compileSdk rootProject.ext.compileSdkVersion
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
@@ -111,7 +117,7 @@ android {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
multiDexEnabled true
versionCode 3019
versionCode 3024
versionName getNpmVersion()
testBuildType System.getProperty('testBuildType', 'debug')
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
@@ -178,9 +184,15 @@ android {
defaultConfig.versionCode * 5 + versionCodes.get(abi)
println("Fdroid Version code: ${output.versionCodeOverride} for abi ${versionCodes.get(abi)}");
} else {
println("Version code: ${output.versionCodeOverride} for abi ${versionCodes.get(abi)}");
output.versionCodeOverride =
if (isBuildingAAB) {
output.versionCodeOverride = 4 * 1048576 + defaultConfig.versionCode
println("AAB version code: ${output.versionCodeOverride}");
} else {
output.versionCodeOverride =
versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
println("Version code: ${output.versionCodeOverride} for abi ${versionCodes.get(abi)}");
}
}
}
@@ -203,13 +215,7 @@ dependencies {
androidTestImplementation('com.wix:detox:+')
implementation 'androidx.appcompat:appcompat:1.1.0'
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}")
debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
exclude group:'com.squareup.okhttp3', module:'okhttp'
}
debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}")
if (hermesEnabled.toBoolean()) {
implementation("com.facebook.react:hermes-android")
} else {

View File

@@ -2,12 +2,9 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<application
android:usesCleartextTraffic="true"
tools:targetApi="28"
tools:ignore="GoogleAppIndexingWarning">
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" android:exported="false" />
</application>
</manifest>

View File

@@ -1,71 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* <p>This source code is licensed under the MIT license found in the LICENSE file in the root
* directory of this source tree.
*/
package com.streetwriters.notesnook;
import android.content.Context;
import com.facebook.flipper.android.AndroidFlipperClient;
import com.facebook.flipper.android.utils.FlipperUtils;
import com.facebook.flipper.core.FlipperClient;
import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin;
import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin;
import com.facebook.flipper.plugins.fresco.FrescoFlipperPlugin;
import com.facebook.flipper.plugins.inspector.DescriptorMapping;
import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin;
import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor;
import com.facebook.flipper.plugins.network.NetworkFlipperPlugin;
import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin;
import com.facebook.react.ReactInstanceEventListener;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.modules.network.NetworkingModule;
import okhttp3.OkHttpClient;
public class ReactNativeFlipper {
public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
if (FlipperUtils.shouldEnableFlipper(context)) {
final FlipperClient client = AndroidFlipperClient.getInstance(context);
client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults()));
client.addPlugin(new DatabasesFlipperPlugin(context));
client.addPlugin(new SharedPreferencesFlipperPlugin(context));
client.addPlugin(CrashReporterPlugin.getInstance());
NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin();
NetworkingModule.setCustomClientBuilder(
new NetworkingModule.CustomClientBuilder() {
@Override
public void apply(OkHttpClient.Builder builder) {
builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin));
}
});
client.addPlugin(networkFlipperPlugin);
client.start();
// Fresco Plugin needs to ensure that ImagePipelineFactory is initialized
// Hence we run if after all native modules have been initialized
ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
if (reactContext == null) {
reactInstanceManager.addReactInstanceEventListener(
new ReactInstanceEventListener() {
@Override
public void onReactContextInitialized(ReactContext reactContext) {
reactInstanceManager.removeReactInstanceEventListener(this);
reactContext.runOnNativeModulesQueueThread(
new Runnable() {
@Override
public void run() {
client.addPlugin(new FrescoFlipperPlugin());
}
});
}
});
} else {
client.addPlugin(new FrescoFlipperPlugin());
}
}
}
}

View File

@@ -18,6 +18,7 @@
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" tools:node="remove" />
<queries>
<intent>

View File

@@ -1,65 +0,0 @@
package com.streetwriters.notesnook;
import com.facebook.react.PackageList;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.soloader.SoLoader;
import java.util.List;
import androidx.multidex.MultiDexApplication;
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
import com.facebook.react.defaults.DefaultReactNativeHost;
public class MainApplication extends MultiDexApplication implements ReactApplication {
private final ReactNativeHost mReactNativeHost =
new DefaultReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
@SuppressWarnings("UnnecessaryLocalVariable")
List<ReactPackage> packages = new PackageList(this).getPackages();
packages.add(new NNativeModulePackage());
return packages;
}
@Override
protected String getJSMainModuleName() {
return "index";
}
@Override
protected boolean isNewArchEnabled() {
return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
}
@Override
protected Boolean isHermesEnabled() {
return BuildConfig.IS_HERMES_ENABLED;
}
};
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
@Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
// If you opted-in for the New Architecture, we load the native entry point for this app.
DefaultNewArchitectureEntryPoint.load();
}
com.streetwriters.notesnook.ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
}
}

View File

@@ -0,0 +1,44 @@
package com.streetwriters.notesnook
import android.app.Application
import com.facebook.react.PackageList
import com.facebook.react.ReactApplication
import com.facebook.react.ReactHost
import com.facebook.react.ReactNativeHost
import com.facebook.react.ReactPackage
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
import com.facebook.react.defaults.DefaultReactNativeHost
import com.facebook.soloader.SoLoader
class MainApplication : Application(), ReactApplication {
override val reactNativeHost: ReactNativeHost =
object : DefaultReactNativeHost(this) {
override fun getPackages(): List<ReactPackage> =
PackageList(this).packages.apply {
// Packages that cannot be autolinked yet can be added manually here, for example:
// add(MyReactNativePackage())
add(NNativeModulePackage());
}
override fun getJSMainModuleName(): String = "index"
override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG
override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
}
override val reactHost: ReactHost
get() = getDefaultReactHost(applicationContext, reactNativeHost)
override fun onCreate() {
super.onCreate()
SoLoader.init(this, false)
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
// If you opted-in for the New Architecture, we load the native entry point for this app.
load()
}
}
}

View File

@@ -67,7 +67,6 @@ public class ShareApplication extends MultiDexApplication implements ReactApplic
@Override
public void onCreate() {
super.onCreate();
ReactFeatureFlags.useTurboModules = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
SoLoader.init(this, /* native exopackage */ false);
}

View File

@@ -3,11 +3,11 @@ import org.apache.tools.ant.taskdefs.condition.Os
buildscript {
ext {
buildToolsVersion = "33.0.0"
minSdkVersion = 21
compileSdkVersion = 33
targetSdkVersion = 33
ext.kotlinVersion = '1.8.0'
buildToolsVersion = "34.0.0"
minSdkVersion = 23
compileSdkVersion = 34
targetSdkVersion = 34
kotlinVersion = '1.9.22'
androidXAnnotation = "1.1.0"
androidXCoreVersion = "1.7.0"
androidXCore = "1.7.0"
@@ -23,10 +23,11 @@ buildscript {
dependencies {
classpath("com.android.tools.build:gradle")
classpath("com.facebook.react:react-native-gradle-plugin")
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin")
}
}
apply plugin: "com.facebook.react.rootproject"
allprojects {
repositories {
@@ -38,9 +39,9 @@ allprojects {
maven { url 'https://www.jitpack.io' }
}
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
kotlinOptions {
jvmTarget = "11"
}
}
// tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
// kotlinOptions {
// jvmTarget = "11"
// }
// }
}

View File

@@ -24,9 +24,6 @@ android.useAndroidX=true
# Automatically convert third-party libraries to use AndroidX
android.enableJetifier=true
# Version of flipper SDK to use with React Native
FLIPPER_VERSION=0.182.0
# Use this property to specify which architecture you want to build.
# You can also override it from the CLI using
# ./gradlew <task> -PreactNativeArchitectures=x86_64

View File

@@ -1,5 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-all.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@@ -83,10 +83,8 @@ done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
@@ -133,10 +131,13 @@ location of your Java installation."
fi
else
JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
@@ -144,7 +145,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
@@ -152,7 +153,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
@@ -197,11 +198,15 @@ if "$cygwin" || "$msys" ; then
done
fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \

View File

@@ -43,11 +43,11 @@ set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
@@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail

View File

@@ -1,5 +1,3 @@
- Fixed realtime sync issues
- Fixed color popups not opening from main toolbar
- Bug fixes and performance improvements
Thank you for using Notesnook!

View File

@@ -2,7 +2,7 @@ const env = process.env.BABEL_ENV || process.env.NODE_ENV;
const configs = {
env: {
development: {
presets: ['module:metro-react-native-babel-preset'],
presets: ['module:@react-native/babel-preset'],
plugins: [
'@babel/plugin-transform-named-capturing-groups-regex',
'react-native-reanimated/plugin',
@@ -18,7 +18,7 @@ const configs = {
]
},
test: {
presets: ['module:metro-react-native-babel-preset'],
presets: ['module:@react-native/babel-preset'],
plugins: [
'@babel/plugin-transform-named-capturing-groups-regex',
'react-native-reanimated/plugin',
@@ -40,7 +40,7 @@ const configs = {
},
production: {
presets: ['module:metro-react-native-babel-preset'],
presets: ['module:@react-native/babel-preset'],
plugins: [
'transform-remove-console',
'@babel/plugin-transform-named-capturing-groups-regex',

View File

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyCollectedDataTypes</key>
<array>
</array>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>C617.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>CA92.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategorySystemBootTime</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>35F9.1</string>
</array>
</dict>
</array>
<key>NSPrivacyTracking</key>
<false/>
</dict>
</plist>

View File

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyCollectedDataTypes</key>
<array>
</array>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>C617.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>CA92.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategorySystemBootTime</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>35F9.1</string>
</array>
</dict>
</array>
<key>NSPrivacyTracking</key>
<false/>
</dict>
</plist>

View File

@@ -14,6 +14,7 @@
2D02E4BD1E0B4A84006451C7 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
2D02E4BF1E0B4AB3006451C7 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
2DCD954D1E0B4F2C00145EB5 /* NotesnookTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* NotesnookTests.m */; };
2E4BF736C2EB268ED3FD9C29 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = B5216B66C0B4A91C0A69128B /* PrivacyInfo.xcprivacy */; };
6510E6D72877215700DACAA9 /* build.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 6510E6D62877215700DACAA9 /* build.bundle */; };
6515C42F2580AA3000E83E39 /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6515C42E2580AA2F00E83E39 /* StoreKit.framework */; };
6517B7C12B6838EB0079FF37 /* OpenSans-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 6517B7BE2B6838EB0079FF37 /* OpenSans-Regular.ttf */; };
@@ -21,9 +22,9 @@
6517B7C32B6838EB0079FF37 /* OpenSans-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 6517B7C02B6838EB0079FF37 /* OpenSans-Bold.ttf */; };
6529A13E279BC4C70048D4A8 /* BootSplash.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6529A13D279BC4C70048D4A8 /* BootSplash.storyboard */; };
656835812BB29A9800144BAB /* OpenSans-Italic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 656835802BB29A8300144BAB /* OpenSans-Italic.ttf */; };
656DD2AB2B1891DF00A362EA /* BuildFile in Resources */ = {isa = PBXBuildFile; };
656DD2AC2B1891DF00A362EA /* BuildFile in Resources */ = {isa = PBXBuildFile; };
656DD2AD2B1891DF00A362EA /* BuildFile in Resources */ = {isa = PBXBuildFile; };
6569927F2C5754F10041CD41 /* OpenSans-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 6517B7C02B6838EB0079FF37 /* OpenSans-Bold.ttf */; };
656992802C5754F10041CD41 /* OpenSans-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 6517B7BE2B6838EB0079FF37 /* OpenSans-Regular.ttf */; };
656992812C5754F10041CD41 /* OpenSans-SemiBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 6517B7BF2B6838EB0079FF37 /* OpenSans-SemiBold.ttf */; };
6593E4A3281C345400492C50 /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6593E4A2281C345400492C50 /* AppDelegate.mm */; };
659BE46725E11A5100E05671 /* notesnook-text.png in Resources */ = {isa = PBXBuildFile; fileRef = 659BE46625E11A5100E05671 /* notesnook-text.png */; };
65AA857925E6DDEC00772A01 /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 65AA857825E6DDEC00772A01 /* WidgetKit.framework */; };
@@ -42,6 +43,7 @@
87CE5B71DC72F3D95B7B1AA5 /* libPods-Notesnook-tvOSTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A03E3F5851D27269540E147C /* libPods-Notesnook-tvOSTests.a */; };
A79A93DC9D0CAE8703462151 /* libPods-Notesnook-NotesnookTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 068FA9BDFA207A50B0A9E597 /* libPods-Notesnook-NotesnookTests.a */; };
C619D096A9DE2070DBEAC70F /* libPods-Make Note.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C4AF691C324D95337F2FB0A /* libPods-Make Note.a */; };
E7F9D56665C2F19F4A97BF49 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 4B679E87FDFB1312CAD6CF45 /* PrivacyInfo.xcprivacy */; };
F50BF8BC21F8B58EB2B5A31A /* libPods-Notesnook-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 16C0296DE7A2B4102817F5C1 /* libPods-Notesnook-tvOS.a */; };
/* End PBXBuildFile section */
@@ -110,6 +112,7 @@
2D02E4901E0B4A5D006451C7 /* Notesnook-tvOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Notesnook-tvOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
41D57E9831C724F59F18FBAE /* libPods-Notesnook-Add to Notes.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Notesnook-Add to Notes.a"; sourceTree = BUILT_PRODUCTS_DIR; };
47AE097A087A651BD60CAD7B /* Pods-Notesnook-Make Note.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Notesnook-Make Note.release.xcconfig"; path = "Target Support Files/Pods-Notesnook-Make Note/Pods-Notesnook-Make Note.release.xcconfig"; sourceTree = "<group>"; };
4B679E87FDFB1312CAD6CF45 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = Notesnook/PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
4BD34AE0C0FD2416E48803B8 /* libPods-Notesnook.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Notesnook.a"; sourceTree = BUILT_PRODUCTS_DIR; };
4C4AF691C324D95337F2FB0A /* libPods-Make Note.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Make Note.a"; sourceTree = BUILT_PRODUCTS_DIR; };
6510E6D62877215700DACAA9 /* build.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = build.bundle; path = "../../../../packages/editor-mobile/build.bundle"; sourceTree = "<group>"; };
@@ -149,6 +152,7 @@
88211800FA8BF60638327ADE /* Pods-Make Note.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Make Note.debug.xcconfig"; path = "Target Support Files/Pods-Make Note/Pods-Make Note.debug.xcconfig"; sourceTree = "<group>"; };
A03E3F5851D27269540E147C /* libPods-Notesnook-tvOSTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Notesnook-tvOSTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
A84F3F0D50641D1CD4569B0E /* Pods-Make Note.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Make Note.release.xcconfig"; path = "Target Support Files/Pods-Make Note/Pods-Make Note.release.xcconfig"; sourceTree = "<group>"; };
B5216B66C0B4A91C0A69128B /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = Notesnook/PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
B9989E5C777BB11343A62D09 /* Pods-Notesnook-NotesnookTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Notesnook-NotesnookTests.debug.xcconfig"; path = "Target Support Files/Pods-Notesnook-NotesnookTests/Pods-Notesnook-NotesnookTests.debug.xcconfig"; sourceTree = "<group>"; };
D1710CA05FED221CC56D2BE1 /* Pods-Notesnook-tvOSTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Notesnook-tvOSTests.release.xcconfig"; path = "Target Support Files/Pods-Notesnook-tvOSTests/Pods-Notesnook-tvOSTests.release.xcconfig"; sourceTree = "<group>"; };
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
@@ -243,6 +247,7 @@
13B07FB71A68108700A75B9A /* main.m */,
65E0340A257B9FF100793428 /* File.swift */,
65E03409257B9FF100793428 /* Notesnook-Bridging-Header.h */,
4B679E87FDFB1312CAD6CF45 /* PrivacyInfo.xcprivacy */,
);
name = Notesnook;
sourceTree = "<group>";
@@ -315,6 +320,7 @@
83CBBA001A601CBA00E9B192 /* Products */,
2D16E6871FA4F8E400B85C8A /* Frameworks */,
DA84645424CFBF19A44D64B3 /* Pods */,
B5216B66C0B4A91C0A69128B /* PrivacyInfo.xcprivacy */,
);
indentWidth = 2;
sourceTree = "<group>";
@@ -367,6 +373,7 @@
00E356EB1AD99517003FC87E /* Frameworks */,
00E356EC1AD99517003FC87E /* Resources */,
819D480147D052141ACC55A9 /* [CP] Copy Pods Resources */,
310C868ED8D8299D75460154 /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
@@ -390,6 +397,7 @@
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
240525450DF9ABA0F332B52E /* [CP] Copy Pods Resources */,
65A7F34B255687E600699170 /* Embed App Extensions */,
48C834D962D612F18A0388B3 /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
@@ -556,6 +564,7 @@
6510E6D72877215700DACAA9 /* build.bundle in Resources */,
6517B7C12B6838EB0079FF37 /* OpenSans-Regular.ttf in Resources */,
659BE46725E11A5100E05671 /* notesnook-text.png in Resources */,
E7F9D56665C2F19F4A97BF49 /* PrivacyInfo.xcprivacy in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -564,6 +573,7 @@
buildActionMask = 2147483647;
files = (
2D02E4BD1E0B4A84006451C7 /* Images.xcassets in Resources */,
2E4BF736C2EB268ED3FD9C29 /* PrivacyInfo.xcprivacy in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -586,9 +596,9 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
656DD2AB2B1891DF00A362EA /* BuildFile in Resources */,
656DD2AC2B1891DF00A362EA /* BuildFile in Resources */,
656DD2AD2B1891DF00A362EA /* BuildFile in Resources */,
6569927F2C5754F10041CD41 /* OpenSans-Bold.ttf in Resources */,
656992802C5754F10041CD41 /* OpenSans-Regular.ttf in Resources */,
656992812C5754F10041CD41 /* OpenSans-SemiBold.ttf in Resources */,
65C400DF2A80B6B600AA3DF5 /* MaterialCommunityIcons.ttf in Resources */,
65C149872A61151B005C40F1 /* extension.bundle in Resources */,
65B5014725A672B200E2D264 /* MainInterface.storyboard in Resources */,
@@ -642,13 +652,13 @@
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Notesnook/Pods-Notesnook-resources.sh",
"${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/QBImagePicker.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/RCTI18nStrings.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/TOCropViewController/TOCropViewControllerBundle.bundle",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/QBImagePicker.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCTI18nStrings.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/TOCropViewControllerBundle.bundle",
);
runOnlyForDeploymentPostprocessing = 0;
@@ -692,6 +702,42 @@
shellPath = /bin/sh;
shellScript = "export SENTRY_PROPERTIES=sentry.properties\nexport EXTRA_PACKAGER_ARGS=\"--sourcemap-output $DERIVED_FILE_DIR/main.jsbundle.map\"\nexport NODE_BINARY=node\n../node_modules/@sentry/cli/bin/sentry-cli react-native xcode ../node_modules/react-native/scripts/react-native-xcode.sh";
};
310C868ED8D8299D75460154 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Notesnook-NotesnookTests/Pods-Notesnook-NotesnookTests-frameworks.sh",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/Pre-built/hermes.framework/hermes",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Notesnook-NotesnookTests/Pods-Notesnook-NotesnookTests-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
48C834D962D612F18A0388B3 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Notesnook/Pods-Notesnook-frameworks.sh",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/Pre-built/hermes.framework/hermes",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Notesnook/Pods-Notesnook-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
52B9E42E0FD77D180139A8C7 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@@ -763,13 +809,13 @@
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Notesnook-NotesnookTests/Pods-Notesnook-NotesnookTests-resources.sh",
"${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/QBImagePicker.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/RCTI18nStrings.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/TOCropViewController/TOCropViewControllerBundle.bundle",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/QBImagePicker.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCTI18nStrings.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/TOCropViewControllerBundle.bundle",
);
runOnlyForDeploymentPostprocessing = 0;
@@ -806,11 +852,11 @@
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Make Note/Pods-Make Note-resources.sh",
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/RCTI18nStrings.bundle",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCTI18nStrings.bundle",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
@@ -1015,7 +1061,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2108;
CURRENT_PROJECT_VERSION = 2111;
DEVELOPMENT_TEAM = 53CWBG3QUC;
ENABLE_BITCODE = NO;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
@@ -1089,7 +1135,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 3.0.11;
MARKETING_VERSION = 3.0.14;
OTHER_LDFLAGS = (
"$(inherited)",
"-ObjC",
@@ -1120,7 +1166,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 2108;
CURRENT_PROJECT_VERSION = 2111;
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 53CWBG3QUC;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
@@ -1194,7 +1240,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 3.0.11;
MARKETING_VERSION = 3.0.14;
ONLY_ACTIVE_ARCH = NO;
OTHER_LDFLAGS = (
"$(inherited)",
@@ -1353,7 +1399,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2108;
CURRENT_PROJECT_VERSION = 2111;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = 53CWBG3QUC;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
@@ -1365,7 +1411,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 3.0.11;
MARKETING_VERSION = 3.0.14;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.notewidget;
@@ -1396,7 +1442,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 2108;
CURRENT_PROJECT_VERSION = 2111;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 53CWBG3QUC;
@@ -1409,7 +1455,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 3.0.11;
MARKETING_VERSION = 3.0.14;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.notewidget;
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -1439,7 +1485,7 @@
CODE_SIGN_ENTITLEMENTS = "Make Note/Make Note.entitlements";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2108;
CURRENT_PROJECT_VERSION = 2111;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = 53CWBG3QUC;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
@@ -1513,7 +1559,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 3.0.11;
MARKETING_VERSION = 3.0.14;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.share;
@@ -1544,7 +1590,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 2108;
CURRENT_PROJECT_VERSION = 2111;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 53CWBG3QUC;
@@ -1619,7 +1665,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 3.0.11;
MARKETING_VERSION = 3.0.14;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.share;
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -1638,7 +1684,7 @@
ALWAYS_SEARCH_USER_PATHS = NO;
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
CLANG_CXX_LANGUAGE_STANDARD = "c++20";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
@@ -1696,8 +1742,13 @@
ONLY_ACTIVE_ARCH = YES;
OTHER_CFLAGS = "$(inherited)";
OTHER_CPLUSPLUSFLAGS = "$(inherited)";
OTHER_LDFLAGS = (
"$(inherited)",
" ",
);
REACT_NATIVE_PATH = "${PODS_ROOT}/../../../node_modules/react-native";
SDKROOT = iphoneos;
USE_HERMES = true;
};
name = Debug;
};
@@ -1707,7 +1758,7 @@
ALWAYS_SEARCH_USER_PATHS = NO;
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
CLANG_CXX_LANGUAGE_STANDARD = "c++20";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
@@ -1758,8 +1809,13 @@
ONLY_ACTIVE_ARCH = NO;
OTHER_CFLAGS = "$(inherited)";
OTHER_CPLUSPLUSFLAGS = "$(inherited)";
OTHER_LDFLAGS = (
"$(inherited)",
" ",
);
REACT_NATIVE_PATH = "${PODS_ROOT}/../../../node_modules/react-native";
SDKROOT = iphoneos;
USE_HERMES = true;
VALIDATE_PRODUCT = YES;
};
name = Release;

View File

@@ -19,9 +19,16 @@
}
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
return [self bundleURL];
}
- (NSURL *)bundleURL
{
#if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
#else
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];

View File

@@ -71,14 +71,11 @@
<true/>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>localhost</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
<!-- Do not change NSAllowsArbitraryLoads to true, or you will risk app rejection! -->
<key>NSAllowsArbitraryLoads</key>
<false/>
<key>NSAllowsLocalNetworking</key>
<true/>
</dict>
<key>NSCameraUsageDescription</key>
<string>Take a picture and add it to your note.</string>
@@ -115,7 +112,7 @@
<string>BootSplash</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
<string>arm64</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>

View File

@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>C617.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>CA92.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategorySystemBootTime</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>35F9.1</string>
</array>
</dict>
</array>
<key>NSPrivacyCollectedDataTypes</key>
<array/>
<key>NSPrivacyTracking</key>
<false/>
</dict>
</plist>

View File

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyCollectedDataTypes</key>
<array>
</array>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>C617.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>CA92.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategorySystemBootTime</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>35F9.1</string>
</array>
</dict>
</array>
<key>NSPrivacyTracking</key>
<false/>
</dict>
</plist>

View File

@@ -14,16 +14,7 @@ require Pod::Executable.execute_command('node', ['-p',
platform :ios, min_ios_version_supported
prepare_react_native_project!
# If you are using a `react-native-flipper` your iOS build will fail when `NO_FLIPPER=1` is set.
# because `react-native-flipper` depends on (FlipperKit,...) that will be excluded
#
# To fix this you can also exclude `react-native-flipper` using a `react-native.config.js`
# ```js
# module.exports = {
# dependencies: {
# ...(process.env.NO_FLIPPER ? { 'react-native-flipper': { platforms: { ios: null } } } : {}),
# ```
flipper_config = ENV['NO_FLIPPER'] == "1" ? FlipperConfiguration.disabled : FlipperConfiguration.enabled
linkage = ENV['USE_FRAMEWORKS']
if linkage != nil
Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green
@@ -38,22 +29,14 @@ pod 'MMKV'
target 'Notesnook' do
config = use_native_modules!
# Flags change depending on the env values.
flags = get_default_flags()
use_react_native!(
:path => config[:reactNativePath],
# Hermes is now enabled by default. Disable by setting this flag to false.
# Upcoming versions of React Native may rely on get_default_flags(), but
# we make it explicit here to aid in the React Native upgrade process.
:hermes_enabled => false,
:fabric_enabled => flags[:fabric_enabled],
# Enables Flipper.
#
# Note that if you have use_frameworks! enabled, Flipper will not work and
# you should disable the next line.
# :flipper_configuration => flipper_config,
# An absolute path to your application root.
:hermes_enabled => true,
:fabric_enabled => false,
:app_path => "#{Pod::Config.instance.installation_root}/.."
)
@@ -71,7 +54,7 @@ target 'Make Note' do
# Hermes is now enabled by default. Disable by setting this flag to false.
# Upcoming versions of React Native may rely on get_default_flags(), but
# we make it explicit here to aid in the React Native upgrade process.
:hermes_enabled => false,
:hermes_enabled => true,
:fabric_enabled => false,
# Enables Flipper.
#
@@ -118,9 +101,9 @@ post_install do |installer|
react_native_path = "../../node_modules/react-native",
# Set `mac_catalyst_enabled` to `true` in order to apply patches
# necessary for Mac Catalyst builds
:mac_catalyst_enabled => false
:mac_catalyst_enabled => false,
# :ccache_enabled => true
)
__apply_Xcode_12_5_M1_post_install_workaround(installer)
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['APPLICATION_EXTENSION_API_ONLY'] = 'NO'
@@ -130,7 +113,7 @@ post_install do |installer|
installer.pods_project.targets.each do |target|
if target.name == "react-native-quick-sqlite" then
target.build_configurations.each do |config|
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] << 'SQLITE_ENABLE_FTS5=1 SQLITE3MC_OMIT_AES_HARDWARE_SUPPORT=1 HAVE_CIPHER_AES_128_CBC=0 HAVE_CIPHER_AES_256_CBC=0 HAVE_CIPHER_SQLCIPHER=0 HAVE_CIPHER_RC4=0 HAVE_CIPHER_CHACHA20=1 SQLITE_OMIT_PROGRESS_CALLBACK=1 SQLITE_MAX_EXPR_DEPTH=0 SQLITE_OMIT_DEPRECATED=1 SQLITE_LIKE_DOESNT_MATCH_BLOBS=1 SQLITE_DQS=0 SQLITE_DEFAULT_MEMSTATUS=0 SQLITE_USE_ALLOCA=1'
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = 'SQLITE_ENABLE_FTS5=1 SQLITE3MC_OMIT_AES_HARDWARE_SUPPORT=1 HAVE_CIPHER_AES_128_CBC=0 HAVE_CIPHER_AES_256_CBC=0 HAVE_CIPHER_SQLCIPHER=0 HAVE_CIPHER_RC4=0 HAVE_CIPHER_CHACHA20=1 SQLITE_OMIT_PROGRESS_CALLBACK=1 SQLITE_MAX_EXPR_DEPTH=0 SQLITE_OMIT_DEPRECATED=1 SQLITE_LIKE_DOESNT_MATCH_BLOBS=1 SQLITE_DQS=0 SQLITE_DEFAULT_MEMSTATUS=0 SQLITE_USE_ALLOCA=1'
end
end
end

File diff suppressed because it is too large Load Diff

View File

@@ -4,12 +4,16 @@
"version": "1.0.0",
"main": "index.js",
"license": "GPL-3.0-or-later",
"overrides": {
"react-native": "0.74.5",
"react": "18.2.0"
},
"dependencies": {
"@ammarahmed/notifee-react-native": "7.4.7",
"@ammarahmed/react-native-share-extension": "^3.0.0",
"@ammarahmed/react-native-sodium": "1.5.4",
"@bam.tech/react-native-image-resizer": "3.0.5",
"@callstack/repack": "^3.2.0",
"@callstack/repack": "^4.1.1",
"@react-native-clipboard/clipboard": "^1.9.0",
"@react-native-community/checkbox": "^0.5.8",
"@react-native-community/datetimepicker": "6.6.0",
@@ -20,9 +24,8 @@
"@react-navigation/native": "^6.0.10",
"@react-navigation/native-stack": "6.6.2",
"@sayem314/react-native-keep-awake": "^1.0.4",
"@shopify/flash-list": "1.4.0",
"react": "18.2.0",
"react-native": "0.72.0",
"react-native": "0.74.5",
"react-native-actions-shortcuts": "^1.0.1",
"react-native-background-actions": "^2.6.6",
"react-native-begin-background-task": "https://github.com/blockfirm/react-native-begin-background-task.git",
@@ -36,31 +39,32 @@
"react-native-exit-app": "https://github.com/ammarahm-ed/react-native-exit-app.git",
"react-native-file-viewer": "^2.1.1",
"react-native-fingerprint-scanner": "https://github.com/ammarahm-ed/react-native-fingerprint-scanner.git",
"react-native-gesture-handler": "^2.12.0",
"react-native-gesture-handler": "^2.18.0",
"react-native-reanimated": "3.14.0",
"react-native-safe-area-context": "^4.10.8",
"react-native-screens": "^3.33.0",
"react-native-webview": "^13.10.0",
"@shopify/flash-list": "1.7.0",
"react-native-vector-icons": "9.2.0",
"react-native-get-random-values": "^1.7.0",
"react-native-gzip": "1.1.0",
"react-native-html-to-pdf-lite": "^0.9.1",
"react-native-iap": "12.11.0",
"react-native-iap": "12.15.1",
"react-native-in-app-review": "4.3.3",
"react-native-keychain": "4.0.5",
"react-native-mmkv-storage": "^0.10.0-alpha.12",
"react-native-mmkv-storage": "^0.10.2",
"react-native-modal-datetime-picker": "14.0.0",
"react-native-navigation-bar-color": "2.0.2",
"react-native-notification-sounds": "0.5.5",
"react-native-orientation": "https://github.com/yamill/react-native-orientation.git",
"react-native-pdf": "6.6.2",
"react-native-privacy-snapshot": "https://github.com/standardnotes/react-native-privacy-snapshot.git",
"react-native-reanimated": "3.3.0",
"react-native-safe-area-context": "^4.3.1",
"react-native-scoped-storage": "^1.9.5",
"react-native-screens": "^3.13.1",
"react-native-securerandom": "^1.0.1",
"react-native-share": "^7.2.0",
"react-native-svg": "^12.3.0",
"react-native-swiper-flatlist": "3.2.2",
"react-native-tooltips": "^1.0.3",
"react-native-vector-icons": "9.2.0",
"react-native-webview": "^13.10.0",
"react-native-zip-archive": "6.0.9",
"react-native-quick-sqlite": "^8.0.6",
"react-native-theme-switch-animation": "^0.6.0",
@@ -76,19 +80,19 @@
"@babel/plugin-transform-private-methods": "^7.22.5",
"@babel/preset-env": "^7.20.0",
"@babel/runtime": "^7.20.0",
"@react-native/eslint-config": "^0.72.2",
"@react-native/metro-config": "^0.72.6",
"@react-native/eslint-config": "0.74.86",
"@react-native/metro-config": "0.74.86",
"@tsconfig/react-native": "^3.0.2",
"@types/html-to-text": "^8.0.1",
"@types/jest": "^29.2.1",
"@types/metro-config": "^0.76.3",
"@types/react": "^18.0.24",
"@types/react": "^18.2.6",
"@types/react-native": "^0.69.1",
"@types/react-native-vector-icons": "^6.4.10",
"@types/react-test-renderer": "^18.0.0",
"@typescript-eslint/eslint-plugin": "^5.14.0",
"@typescript-eslint/parser": "^5.14.0",
"babel-jest": "^29.6.2",
"babel-jest": "^29.6.3",
"babel-loader": "^8.2.5",
"babel-plugin-module-resolver": "^4.1.0",
"babel-plugin-transform-remove-console": "6.9.4",
@@ -100,12 +104,12 @@
"eslint-plugin-react-native": "^4.0.0",
"eslint-plugin-unused-imports": "^2.0.0",
"expect": "^29.6.2",
"jest": "^29.6.2",
"jest": "^29.6.3",
"jest-circus": "^29.6.2",
"jest-image-snapshot": "^6.2.0",
"metro-react-native-babel-preset": "0.76.5",
"@react-native/babel-preset": "0.74.86",
"pixelmatch": "^5.3.0",
"prettier": "^2.4.1",
"prettier": "2.8.8",
"react-native-actions-shortcuts": "^1.0.1",
"react-native-bundle-visualizer": "^3.1.1",
"react-native-cli-bump-version": "^1.3.0",

View File

@@ -36,4 +36,10 @@ if (isGithubRelease) {
}
}
const repackCommands = require('@callstack/repack/commands');
config.commands = repackCommands.filter((command) =>
command.name.startsWith('webpack')
),
module.exports = config;

View File

@@ -26,7 +26,7 @@ module.exports = (env) => {
mode = "development",
context = __dirname,
entry = "./index.js",
platform,
platform = process.env.PLATFORM,
minimize = mode === "production",
devServer = undefined,
bundleFilename = undefined,
@@ -118,7 +118,8 @@ module.exports = (env) => {
*/
output: {
clean: true,
path: path.join(__dirname, "build/generated", platform),
hashFunction: 'xxhash64',
path: path.join(__dirname, 'build/generated', platform),
filename: "index.bundle",
chunkFilename: "[name].chunk.bundle",
publicPath: Repack.getPublicPath({ platform, devServer }),
@@ -172,7 +173,7 @@ module.exports = (env) => {
"node_modules/.webpack-cache"
),
babelrc: false,
presets: ["module:metro-react-native-babel-preset"],
presets: ["module:@react-native/babel-preset"],
plugins: [
"react-native-reanimated/plugin",
"@babel/plugin-transform-named-capturing-groups-regex",
@@ -184,7 +185,7 @@ module.exports = (env) => {
{
test: /\.mjs$|cjs$|js$|jsx$|ts$|tsx$/,
include: [
/node_modules(.*[/\\])+react/,
/node_modules(.*[/\\])+react-native/,
/node_modules(.*[/\\])+@react-native/,
/node_modules(.*[/\\])+@react-navigation/,
/node_modules(.*[/\\])+@react-native-community/,
@@ -220,6 +221,7 @@ module.exports = (env) => {
/node_modules(.*[/\\])+whatwg-url/,
/node_modules(.*[/\\])+react-native-url-polyfill/,
/node_modules(.*[/\\])+diffblazer/,
/node_modules(.*[/\\])+react-freeze/,
],
use: {
loader: "babel-loader",
@@ -230,7 +232,7 @@ module.exports = (env) => {
"node_modules/.webpack-cache"
),
babelrc: false,
presets: ["module:metro-react-native-babel-preset"],
presets: ["module:@react-native/babel-preset"],
plugins: [
"react-native-reanimated/plugin",
"@babel/plugin-transform-named-capturing-groups-regex",
@@ -258,7 +260,7 @@ module.exports = (env) => {
"node_modules/.webpack-cache"
),
babelrc: false,
presets: [["module:metro-react-native-babel-preset"]],
presets: [["module:@react-native/babel-preset"]],
plugins:
devServer && devServer.hmr
? [

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "@notesnook/mobile",
"version": "3.0.11",
"version": "3.0.14",
"private": true,
"license": "GPL-3.0-or-later",
"workspaces": [
@@ -25,10 +25,15 @@
},
"devDependencies": {
"fonteditor-core": "^2.1.11",
"listr": "^0.14.3",
"otplib": "12.0.1",
"patch-package": "7.0.0",
"react-refresh": "0.14.0"
},
"overrides": {
"react-native": "0.74.5",
"react": "18.2.0"
},
"dependencies": {
"@notesnook/common": "file:../../packages/common",
"@notesnook/core": "file:../../packages/core",
@@ -39,6 +44,8 @@
"@notesnook/themes-server": "file:../../servers/themes",
"diffblazer": "^1.0.1",
"react": "18.2.0",
"react-native": "0.72.0"
"react-native": "0.74.5",
"react-native-mmkv-storage": "^0.10.2",
"react-native-actions-sheet": "^0.9.7"
}
}

View File

@@ -1,13 +0,0 @@
diff --git a/node_modules/@callstack/repack/android/build.gradle b/node_modules/@callstack/repack/android/build.gradle
index e41f2f3..b04735e 100644
--- a/node_modules/@callstack/repack/android/build.gradle
+++ b/node_modules/@callstack/repack/android/build.gradle
@@ -29,7 +29,7 @@ android {
compileSdkVersion getExtOrIntegerDefault('compileSdkVersion')
buildToolsVersion getExtOrDefault('buildToolsVersion')
defaultConfig {
- minSdkVersion 16
+ minSdkVersion 21
targetSdkVersion getExtOrIntegerDefault('targetSdkVersion')
versionCode 1
versionName "1.0"

View File

@@ -0,0 +1,11 @@
diff --git a/node_modules/@react-native/community-cli-plugin/dist/utils/loadMetroConfig.js b/node_modules/@react-native/community-cli-plugin/dist/utils/loadMetroConfig.js
index 636c0d8..87f4ee6 100644
--- a/node_modules/@react-native/community-cli-plugin/dist/utils/loadMetroConfig.js
+++ b/node_modules/@react-native/community-cli-plugin/dist/utils/loadMetroConfig.js
@@ -105,5 +105,6 @@ This warning will be removed in future (https://github.com/facebook/metro/issues
...options,
});
const overrideConfig = getOverrideConfig(ctx, config);
+ if (!overrideConfig.resolver.resolveRequest) delete overrideConfig.resolver.resolveRequest;
return (0, _metroConfig.mergeConfig)(config, overrideConfig);
}

View File

@@ -1,24 +0,0 @@
diff --git a/node_modules/@react-native-community/cli-plugin-metro/build/tools/loadMetroConfig.d.ts b/node_modules/@react-native-community/cli-plugin-metro/build/tools/loadMetroConfig.d.ts
index 6cbcc22..62d5422 100644
--- a/node_modules/@react-native-community/cli-plugin-metro/build/tools/loadMetroConfig.d.ts
+++ b/node_modules/@react-native-community/cli-plugin-metro/build/tools/loadMetroConfig.d.ts
@@ -12,6 +12,7 @@ export interface ConfigOptionsT {
reporter?: any;
config?: string;
}
+
/**
* Load Metro config.
*
diff --git a/node_modules/@react-native-community/cli-plugin-metro/build/tools/loadMetroConfig.js b/node_modules/@react-native-community/cli-plugin-metro/build/tools/loadMetroConfig.js
index f26ef52..233a7c9 100644
--- a/node_modules/@react-native-community/cli-plugin-metro/build/tools/loadMetroConfig.js
+++ b/node_modules/@react-native-community/cli-plugin-metro/build/tools/loadMetroConfig.js
@@ -82,6 +82,7 @@ async function loadMetroConfig(ctx, options = {}) {
(0, _getDefaultMetroConfig.default)(ctx));
return (0, _metroConfig().mergeConfig)(loadedConfig, overrideConfig);
}
+ if (!overrideConfig.resolver.resolveRequest) delete overrideConfig.resolver.resolveRequest;
return (0, _metroConfig().mergeConfig)(await (0, _metroConfig().loadConfig)({
cwd: ctx.root,
...options

View File

@@ -1,70 +0,0 @@
diff --git a/node_modules/react-native/ReactCommon/jsc/JSCRuntime.cpp b/node_modules/react-native/ReactCommon/jsc/JSCRuntime.cpp
index 7958519..25f58b1 100644
--- a/node_modules/react-native/ReactCommon/jsc/JSCRuntime.cpp
+++ b/node_modules/react-native/ReactCommon/jsc/JSCRuntime.cpp
@@ -409,12 +409,12 @@ JSCRuntime::~JSCRuntime() {
// has started.
ctxInvalid_ = true;
JSGlobalContextRelease(ctx_);
-#ifndef NDEBUG
- assert(
- objectCounter_ == 0 && "JSCRuntime destroyed with a dangling API object");
- assert(
- stringCounter_ == 0 && "JSCRuntime destroyed with a dangling API string");
-#endif
+//#ifndef NDEBUG
+// assert(
+// objectCounter_ == 0 && "JSCRuntime destroyed with a dangling API object");
+// assert(
+// stringCounter_ == 0 && "JSCRuntime destroyed with a dangling API string");
+//#endif
}
std::shared_ptr<const jsi::PreparedJavaScript> JSCRuntime::prepareJavaScript(
diff --git a/node_modules/react-native/scripts/.packager.env b/node_modules/react-native/scripts/.packager.env
new file mode 100644
index 0000000..361f5fb
--- /dev/null
+++ b/node_modules/react-native/scripts/.packager.env
@@ -0,0 +1 @@
+export RCT_METRO_PORT=8081
diff --git a/node_modules/react-native/scripts/launchPackager.command b/node_modules/react-native/scripts/launchPackager.command
index efd1f2e..c2fbbb3 100755
--- a/node_modules/react-native/scripts/launchPackager.command
+++ b/node_modules/react-native/scripts/launchPackager.command
@@ -10,7 +10,7 @@ clear
THIS_DIR=$(cd -P "$(dirname "$(readlink "${BASH_SOURCE[0]}" || echo "${BASH_SOURCE[0]}")")" && pwd)
-export PODS_ROOT="$THIS_DIR/../../../ios/Pods"
+export PODS_ROOT="$THIS_DIR/../../../native/ios/Pods"
WITH_ENVIRONMENT="$THIS_DIR/xcode/with-environment.sh"
source $WITH_ENVIRONMENT
diff --git a/node_modules/react-native/scripts/packager.sh b/node_modules/react-native/scripts/packager.sh
index cb8b101..519070a 100755
--- a/node_modules/react-native/scripts/packager.sh
+++ b/node_modules/react-native/scripts/packager.sh
@@ -8,17 +8,16 @@
THIS_DIR=$(cd -P "$(dirname "$(readlink "${BASH_SOURCE[0]}" || echo "${BASH_SOURCE[0]}")")" && pwd)
REACT_NATIVE_ROOT="$THIS_DIR/.."
# Application root directory - General use case: react-native is a dependency
-PROJECT_ROOT=${PROJECT_ROOT:-"$THIS_DIR/../../.."}
-
+PROJECT_ROOT=${PROJECT_ROOT:-"$THIS_DIR/../../../native"}
# check and assign NODE_BINARY env
# shellcheck disable=SC1090
source "${THIS_DIR}/node-binary.sh"
# When running react-native tests, react-native doesn't live in node_modules but in the PROJECT_ROOT
-if [ ! -d "$THIS_DIR/../../../node_modules/react-native" ];
-then
- PROJECT_ROOT="$THIS_DIR/../../.."
-fi
+# if [ ! -d "$THIS_DIR/../../../node_modules/react-native" ];
+# then
+# PROJECT_ROOT="$THIS_DIR/../../.."
+# fi
# Start packager from PROJECT_ROOT
cd "$PROJECT_ROOT" || exit
"$NODE_BINARY" "$REACT_NATIVE_ROOT/cli.js" start --custom-log-reporter-path "$THIS_DIR/packager-reporter.js" "$@"

View File

@@ -0,0 +1,13 @@
diff --git a/node_modules/react-native/scripts/packager.sh b/node_modules/react-native/scripts/packager.sh
index 00d6ebc..6846832 100755
--- a/node_modules/react-native/scripts/packager.sh
+++ b/node_modules/react-native/scripts/packager.sh
@@ -8,7 +8,7 @@
THIS_DIR=$(cd -P "$(dirname "$(readlink "${BASH_SOURCE[0]}" || echo "${BASH_SOURCE[0]}")")" && pwd)
REACT_NATIVE_ROOT="$THIS_DIR/.."
# Application root directory - General use case: react-native is a dependency
-PROJECT_ROOT=${PROJECT_ROOT:-"$THIS_DIR/../../.."}
+PROJECT_ROOT=${PROJECT_ROOT:-"$THIS_DIR/../../../native"}
# check and assign NODE_BINARY env
# shellcheck disable=SC1090

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +1,88 @@
diff --git a/node_modules/react-native-quick-sqlite/.DS_Store b/node_modules/react-native-quick-sqlite/.DS_Store
new file mode 100644
index 0000000..02a6bbf
Binary files /dev/null and b/node_modules/react-native-quick-sqlite/.DS_Store differ
index 0000000..e69de29
diff --git a/node_modules/react-native-quick-sqlite/android/.cxx/Debug/3u4yy1v4/arm64-v8a/metadata_generation_command.txt b/node_modules/react-native-quick-sqlite/android/.cxx/Debug/3u4yy1v4/arm64-v8a/metadata_generation_command.txt
new file mode 100644
index 0000000..16ba95f
--- /dev/null
+++ b/node_modules/react-native-quick-sqlite/android/.cxx/Debug/3u4yy1v4/arm64-v8a/metadata_generation_command.txt
@@ -0,0 +1,23 @@
+ -H/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android
+-DCMAKE_SYSTEM_NAME=Android
+-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
+-DCMAKE_SYSTEM_VERSION=21
+-DANDROID_PLATFORM=android-21
+-DANDROID_ABI=arm64-v8a
+-DCMAKE_ANDROID_ARCH_ABI=arm64-v8a
+-DANDROID_NDK=/Volumes/DataDrive/Android/sdk/ndk/23.1.7779620
+-DCMAKE_ANDROID_NDK=/Volumes/DataDrive/Android/sdk/ndk/23.1.7779620
+-DCMAKE_TOOLCHAIN_FILE=/Volumes/DataDrive/Android/sdk/ndk/23.1.7779620/build/cmake/android.toolchain.cmake
+-DCMAKE_MAKE_PROGRAM=/Volumes/DataDrive/Android/sdk/cmake/3.22.1/bin/ninja
+-DCMAKE_CXX_FLAGS=-O2 -fexceptions -frtti -std=c++1y -DONANDROID
+-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/obj/arm64-v8a
+-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/obj/arm64-v8a
+-DCMAKE_BUILD_TYPE=Debug
+-DCMAKE_FIND_ROOT_PATH=/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/.cxx/Debug/3u4yy1v4/prefab/arm64-v8a/prefab
+-B/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/.cxx/Debug/3u4yy1v4/arm64-v8a
+-GNinja
+-DANDROID_STL=c++_shared
+-DSQLITE_FLAGS='-DSQLITE3MC_OMIT_AES_HARDWARE_SUPPORT -DHAVE_CIPHER_AES_128_CBC=0 -DHAVE_CIPHER_AES_256_CBC=0 -DHAVE_CIPHER_SQLCIPHER=0 -DHAVE_CIPHER_RC4=0 -DHAVE_CIPHER_CHACHA20=1 -DSQLITE_ENABLE_FTS5 -DSQLITE_OMIT_PROGRESS_CALLBACK=1 -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_OMIT_DEPRECATED=1 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS=1 -DSQLITE_DQS=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_USE_ALLOCA=1'
+-DUSE_HERMES=true
+ Build command args: []
+ Version: 2
\ No newline at end of file
diff --git a/node_modules/react-native-quick-sqlite/android/.cxx/Debug/3u4yy1v4/arm64-v8a/prefab_config.json b/node_modules/react-native-quick-sqlite/android/.cxx/Debug/3u4yy1v4/arm64-v8a/prefab_config.json
new file mode 100644
index 0000000..1d61ce4
--- /dev/null
+++ b/node_modules/react-native-quick-sqlite/android/.cxx/Debug/3u4yy1v4/arm64-v8a/prefab_config.json
@@ -0,0 +1,8 @@
+{
+ "enabled": true,
+ "prefabPath": "/Users/ammarahmed/.gradle/caches/modules-2/files-2.1/com.google.prefab/cli/2.0.0/f2702b5ca13df54e3ca92f29d6b403fb6285d8df/cli-2.0.0-all.jar",
+ "packages": [
+ "/Users/ammarahmed/.gradle/caches/transforms-4/af547bd0d6b859d6b490959996fda082/transformed/jetified-react-android-0.74.4-debug/prefab",
+ "/Users/ammarahmed/.gradle/caches/transforms-4/c7e26f7d3c2fc1a6636ff1467fc77795/transformed/jetified-fbjni-0.6.0/prefab"
+ ]
+}
\ No newline at end of file
diff --git a/node_modules/react-native-quick-sqlite/android/.cxx/Debug/3u4yy1v4/hash_key.txt b/node_modules/react-native-quick-sqlite/android/.cxx/Debug/3u4yy1v4/hash_key.txt
new file mode 100644
index 0000000..a453b76
--- /dev/null
+++ b/node_modules/react-native-quick-sqlite/android/.cxx/Debug/3u4yy1v4/hash_key.txt
@@ -0,0 +1,30 @@
+# Values used to calculate the hash in this folder name.
+# Should not depend on the absolute path of the project itself.
+# - AGP: 8.2.1.
+# - $NDK is the path to NDK 23.1.7779620.
+# - $PROJECT is the path to the parent folder of the root Gradle build file.
+# - $ABI is the ABI to be built with. The specific value doesn't contribute to the value of the hash.
+# - $HASH is the hash value computed from this text.
+# - $CMAKE is the path to CMake 3.22.1.
+# - $NINJA is the path to Ninja.
+-H/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android
+-DCMAKE_SYSTEM_NAME=Android
+-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
+-DCMAKE_SYSTEM_VERSION=21
+-DANDROID_PLATFORM=android-21
+-DANDROID_ABI=$ABI
+-DCMAKE_ANDROID_ARCH_ABI=$ABI
+-DANDROID_NDK=$NDK
+-DCMAKE_ANDROID_NDK=$NDK
+-DCMAKE_TOOLCHAIN_FILE=$NDK/build/cmake/android.toolchain.cmake
+-DCMAKE_MAKE_PROGRAM=$NINJA
+-DCMAKE_CXX_FLAGS=-O2 -fexceptions -frtti -std=c++1y -DONANDROID
+-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/$HASH/obj/$ABI
+-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/$HASH/obj/$ABI
+-DCMAKE_BUILD_TYPE=Debug
+-DCMAKE_FIND_ROOT_PATH=/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/.cxx/Debug/$HASH/prefab/$ABI/prefab
+-B/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/.cxx/Debug/$HASH/$ABI
+-GNinja
+-DANDROID_STL=c++_shared
+-DSQLITE_FLAGS='-DSQLITE3MC_OMIT_AES_HARDWARE_SUPPORT -DHAVE_CIPHER_AES_128_CBC=0 -DHAVE_CIPHER_AES_256_CBC=0 -DHAVE_CIPHER_SQLCIPHER=0 -DHAVE_CIPHER_RC4=0 -DHAVE_CIPHER_CHACHA20=1 -DSQLITE_ENABLE_FTS5 -DSQLITE_OMIT_PROGRESS_CALLBACK=1 -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_OMIT_DEPRECATED=1 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS=1 -DSQLITE_DQS=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_USE_ALLOCA=1'
+-DUSE_HERMES=true
\ No newline at end of file
diff --git a/node_modules/react-native-quick-sqlite/android/.settings/org.eclipse.buildship.core.prefs b/node_modules/react-native-quick-sqlite/android/.settings/org.eclipse.buildship.core.prefs
deleted file mode 100644
index 8c253d6..0000000
@@ -21,12 +102,765 @@ index 8c253d6..0000000
-override.workspace.settings=true
-show.console.view=true
-show.executions.view=true
diff --git a/node_modules/react-native-quick-sqlite/android/build.gradle b/node_modules/react-native-quick-sqlite/android/build.gradle
index 96d2a74..c26e678 100644
--- a/node_modules/react-native-quick-sqlite/android/build.gradle
+++ b/node_modules/react-native-quick-sqlite/android/build.gradle
@@ -63,7 +63,7 @@ android {
}
defaultConfig {
- minSdkVersion 21
+ minSdkVersion safeExtGet("minSdkVersion", 23)
targetSdkVersion safeExtGet('targetSdkVersion', 28)
versionCode 1
versionName "1.0"
diff --git a/node_modules/react-native-quick-sqlite/android/build/.transforms/a5d230bd7410c4a394e68198eafb820e/results.bin b/node_modules/react-native-quick-sqlite/android/build/.transforms/a5d230bd7410c4a394e68198eafb820e/results.bin
new file mode 100644
index 0000000..0d259dd
--- /dev/null
+++ b/node_modules/react-native-quick-sqlite/android/build/.transforms/a5d230bd7410c4a394e68198eafb820e/results.bin
@@ -0,0 +1 @@
+o/classes
diff --git a/node_modules/react-native-quick-sqlite/android/build/.transforms/a5d230bd7410c4a394e68198eafb820e/transformed/classes/classes_dex/classes.dex b/node_modules/react-native-quick-sqlite/android/build/.transforms/a5d230bd7410c4a394e68198eafb820e/transformed/classes/classes_dex/classes.dex
new file mode 100644
index 0000000..220a44f
Binary files /dev/null and b/node_modules/react-native-quick-sqlite/android/build/.transforms/a5d230bd7410c4a394e68198eafb820e/transformed/classes/classes_dex/classes.dex differ
diff --git a/node_modules/react-native-quick-sqlite/android/build/generated/source/buildConfig/debug/com/reactnativequicksqlite/BuildConfig.java b/node_modules/react-native-quick-sqlite/android/build/generated/source/buildConfig/debug/com/reactnativequicksqlite/BuildConfig.java
new file mode 100644
index 0000000..bb02d55
--- /dev/null
+++ b/node_modules/react-native-quick-sqlite/android/build/generated/source/buildConfig/debug/com/reactnativequicksqlite/BuildConfig.java
@@ -0,0 +1,10 @@
+/**
+ * Automatically generated file. DO NOT MODIFY
+ */
+package com.reactnativequicksqlite;
+
+public final class BuildConfig {
+ public static final boolean DEBUG = Boolean.parseBoolean("true");
+ public static final String LIBRARY_PACKAGE_NAME = "com.reactnativequicksqlite";
+ public static final String BUILD_TYPE = "debug";
+}
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/AndroidManifest.xml b/node_modules/react-native-quick-sqlite/android/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/AndroidManifest.xml
new file mode 100644
index 0000000..65ada26
--- /dev/null
+++ b/node_modules/react-native-quick-sqlite/android/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/AndroidManifest.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.reactnativequicksqlite" >
+
+ <uses-sdk android:minSdkVersion="21" />
+
+</manifest>
\ No newline at end of file
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/output-metadata.json b/node_modules/react-native-quick-sqlite/android/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/output-metadata.json
new file mode 100644
index 0000000..c903659
--- /dev/null
+++ b/node_modules/react-native-quick-sqlite/android/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/output-metadata.json
@@ -0,0 +1,18 @@
+{
+ "version": 3,
+ "artifactType": {
+ "type": "AAPT_FRIENDLY_MERGED_MANIFESTS",
+ "kind": "Directory"
+ },
+ "applicationId": "com.reactnativequicksqlite",
+ "variantName": "debug",
+ "elements": [
+ {
+ "type": "SINGLE",
+ "filters": [],
+ "attributes": [],
+ "outputFile": "AndroidManifest.xml"
+ }
+ ],
+ "elementType": "File"
+}
\ No newline at end of file
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/aar_metadata/debug/aar-metadata.properties b/node_modules/react-native-quick-sqlite/android/build/intermediates/aar_metadata/debug/aar-metadata.properties
new file mode 100644
index 0000000..1211b1e
--- /dev/null
+++ b/node_modules/react-native-quick-sqlite/android/build/intermediates/aar_metadata/debug/aar-metadata.properties
@@ -0,0 +1,6 @@
+aarFormatVersion=1.0
+aarMetadataVersion=1.0
+minCompileSdk=1
+minCompileSdkExtension=0
+minAndroidGradlePluginVersion=1.0.0
+coreLibraryDesugaringEnabled=false
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/annotation_processor_list/debug/annotationProcessors.json b/node_modules/react-native-quick-sqlite/android/build/intermediates/annotation_processor_list/debug/annotationProcessors.json
new file mode 100644
index 0000000..9e26dfe
--- /dev/null
+++ b/node_modules/react-native-quick-sqlite/android/build/intermediates/annotation_processor_list/debug/annotationProcessors.json
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/compile_library_classes_jar/debug/classes.jar b/node_modules/react-native-quick-sqlite/android/build/intermediates/compile_library_classes_jar/debug/classes.jar
new file mode 100644
index 0000000..d7046e6
Binary files /dev/null and b/node_modules/react-native-quick-sqlite/android/build/intermediates/compile_library_classes_jar/debug/classes.jar differ
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/compile_r_class_jar/debug/R.jar b/node_modules/react-native-quick-sqlite/android/build/intermediates/compile_r_class_jar/debug/R.jar
new file mode 100644
index 0000000..1fff931
Binary files /dev/null and b/node_modules/react-native-quick-sqlite/android/build/intermediates/compile_r_class_jar/debug/R.jar differ
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/compile_symbol_list/debug/R.txt b/node_modules/react-native-quick-sqlite/android/build/intermediates/compile_symbol_list/debug/R.txt
new file mode 100644
index 0000000..e69de29
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/logs/arm64-v8a/build_model.json b/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/logs/arm64-v8a/build_model.json
new file mode 100644
index 0000000..b6ba478
--- /dev/null
+++ b/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/logs/arm64-v8a/build_model.json
@@ -0,0 +1,201 @@
+{
+ "info": {
+ "name": "arm64-v8a",
+ "bitness": 64,
+ "isDefault": true,
+ "isDeprecated": false,
+ "architecture": "arm64",
+ "triple": "aarch64-linux-android",
+ "llvmTriple": "aarch64-none-linux-android"
+ },
+ "cxxBuildFolder": "/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/.cxx/Debug/3u4yy1v4/arm64-v8a",
+ "soFolder": "/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/obj/arm64-v8a",
+ "soRepublishFolder": "/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/build/intermediates/cmake/debug/obj/arm64-v8a",
+ "abiPlatformVersion": 21,
+ "cmake": {
+ "effectiveConfiguration": {
+ "inheritEnvironments": [],
+ "variables": []
+ }
+ },
+ "variant": {
+ "buildSystemArgumentList": [
+ "-DANDROID_STL\u003dc++_shared",
+ "-DSQLITE_FLAGS\u003d\u0027-DSQLITE3MC_OMIT_AES_HARDWARE_SUPPORT -DHAVE_CIPHER_AES_128_CBC\u003d0 -DHAVE_CIPHER_AES_256_CBC\u003d0 -DHAVE_CIPHER_SQLCIPHER\u003d0 -DHAVE_CIPHER_RC4\u003d0 -DHAVE_CIPHER_CHACHA20\u003d1 -DSQLITE_ENABLE_FTS5 -DSQLITE_OMIT_PROGRESS_CALLBACK\u003d1 -DSQLITE_MAX_EXPR_DEPTH\u003d0 -DSQLITE_OMIT_DEPRECATED\u003d1 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS\u003d1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS\u003d1 -DSQLITE_DQS\u003d0 -DSQLITE_DEFAULT_MEMSTATUS\u003d0 -DSQLITE_USE_ALLOCA\u003d1\u0027",
+ "-DUSE_HERMES\u003dtrue"
+ ],
+ "cFlagsList": [],
+ "cppFlagsList": [
+ "-O2",
+ "-fexceptions",
+ "-frtti",
+ "-std\u003dc++1y",
+ "-DONANDROID"
+ ],
+ "variantName": "debug",
+ "isDebuggableEnabled": true,
+ "validAbiList": [
+ "armeabi-v7a",
+ "arm64-v8a",
+ "x86",
+ "x86_64"
+ ],
+ "buildTargetSet": [],
+ "implicitBuildTargetSet": [],
+ "cmakeSettingsConfiguration": "android-gradle-plugin-predetermined-name",
+ "module": {
+ "cxxFolder": "/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/.cxx",
+ "intermediatesBaseFolder": "/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/build/intermediates",
+ "intermediatesFolder": "/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx",
+ "gradleModulePathName": ":react-native-quick-sqlite",
+ "moduleRootFolder": "/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android",
+ "moduleBuildFile": "/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/build.gradle",
+ "makeFile": "/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/CMakeLists.txt",
+ "buildSystem": "CMAKE",
+ "ndkFolder": "/Volumes/DataDrive/Android/sdk/ndk/23.1.7779620",
+ "ndkFolderBeforeSymLinking": "/Volumes/DataDrive/Android/sdk/ndk/23.1.7779620",
+ "ndkVersion": "23.1.7779620",
+ "ndkSupportedAbiList": [
+ "armeabi-v7a",
+ "arm64-v8a",
+ "x86",
+ "x86_64"
+ ],
+ "ndkDefaultAbiList": [
+ "armeabi-v7a",
+ "arm64-v8a",
+ "x86",
+ "x86_64"
+ ],
+ "ndkDefaultStl": "LIBCXX_STATIC",
+ "ndkMetaPlatforms": {
+ "min": 16,
+ "max": 31,
+ "aliases": {
+ "20": 19,
+ "25": 24,
+ "J": 16,
+ "J-MR1": 17,
+ "J-MR2": 18,
+ "K": 19,
+ "L": 21,
+ "L-MR1": 22,
+ "M": 23,
+ "N": 24,
+ "N-MR1": 24,
+ "O": 26,
+ "O-MR1": 27,
+ "P": 28,
+ "Q": 29,
+ "R": 30,
+ "S": 31
+ }
+ },
+ "ndkMetaAbiList": [
+ {
+ "name": "armeabi-v7a",
+ "bitness": 32,
+ "isDefault": true,
+ "isDeprecated": false,
+ "architecture": "arm",
+ "triple": "arm-linux-androideabi",
+ "llvmTriple": "armv7-none-linux-androideabi"
+ },
+ {
+ "name": "arm64-v8a",
+ "bitness": 64,
+ "isDefault": true,
+ "isDeprecated": false,
+ "architecture": "arm64",
+ "triple": "aarch64-linux-android",
+ "llvmTriple": "aarch64-none-linux-android"
+ },
+ {
+ "name": "x86",
+ "bitness": 32,
+ "isDefault": true,
+ "isDeprecated": false,
+ "architecture": "x86",
+ "triple": "i686-linux-android",
+ "llvmTriple": "i686-none-linux-android"
+ },
+ {
+ "name": "x86_64",
+ "bitness": 64,
+ "isDefault": true,
+ "isDeprecated": false,
+ "architecture": "x86_64",
+ "triple": "x86_64-linux-android",
+ "llvmTriple": "x86_64-none-linux-android"
+ }
+ ],
+ "cmakeToolchainFile": "/Volumes/DataDrive/Android/sdk/ndk/23.1.7779620/build/cmake/android.toolchain.cmake",
+ "cmake": {
+ "cmakeExe": "/Volumes/DataDrive/Android/sdk/cmake/3.22.1/bin/cmake"
+ },
+ "stlSharedObjectMap": {
+ "LIBCXX_SHARED": {
+ "armeabi-v7a": "/Volumes/DataDrive/Android/sdk/ndk/23.1.7779620/toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr/lib/arm-linux-androideabi/libc++_shared.so",
+ "arm64-v8a": "/Volumes/DataDrive/Android/sdk/ndk/23.1.7779620/toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr/lib/aarch64-linux-android/libc++_shared.so",
+ "x86": "/Volumes/DataDrive/Android/sdk/ndk/23.1.7779620/toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr/lib/i686-linux-android/libc++_shared.so",
+ "x86_64": "/Volumes/DataDrive/Android/sdk/ndk/23.1.7779620/toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr/lib/x86_64-linux-android/libc++_shared.so"
+ },
+ "LIBCXX_STATIC": {},
+ "NONE": {},
+ "SYSTEM": {}
+ },
+ "project": {
+ "rootBuildGradleFolder": "/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/native/android",
+ "sdkFolder": "/Volumes/DataDrive/Android/sdk",
+ "isBuildOnlyTargetAbiEnabled": true,
+ "isCmakeBuildCohabitationEnabled": false,
+ "isPrefabEnabled": true
+ },
+ "outputOptions": [],
+ "ninjaExe": "/Volumes/DataDrive/Android/sdk/cmake/3.22.1/bin/ninja",
+ "hasBuildTimeInformation": true
+ },
+ "prefabClassPaths": [
+ "/Users/ammarahmed/.gradle/caches/modules-2/files-2.1/com.google.prefab/cli/2.0.0/f2702b5ca13df54e3ca92f29d6b403fb6285d8df/cli-2.0.0-all.jar"
+ ],
+ "prefabPackages": [
+ "/Users/ammarahmed/.gradle/caches/transforms-4/af547bd0d6b859d6b490959996fda082/transformed/jetified-react-android-0.74.4-debug/prefab",
+ "/Users/ammarahmed/.gradle/caches/transforms-4/c7e26f7d3c2fc1a6636ff1467fc77795/transformed/jetified-fbjni-0.6.0/prefab"
+ ],
+ "prefabPackageConfigurations": [],
+ "stlType": "c++_shared",
+ "optimizationTag": "Debug"
+ },
+ "buildSettings": {
+ "environmentVariables": []
+ },
+ "prefabFolder": "/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/.cxx/Debug/3u4yy1v4/prefab/arm64-v8a",
+ "isActiveAbi": true,
+ "fullConfigurationHash": "3u4yy1v4n5m1m3r6x453b2w4u42s4h63w1d2iu6l6v2q6n2d4154135b3h34",
+ "fullConfigurationHashKey": "# Values used to calculate the hash in this folder name.\n# Should not depend on the absolute path of the project itself.\n# - AGP: 8.2.1.\n# - $NDK is the path to NDK 23.1.7779620.\n# - $PROJECT is the path to the parent folder of the root Gradle build file.\n# - $ABI is the ABI to be built with. The specific value doesn\u0027t contribute to the value of the hash.\n# - $HASH is the hash value computed from this text.\n# - $CMAKE is the path to CMake 3.22.1.\n# - $NINJA is the path to Ninja.\n-H/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android\n-DCMAKE_SYSTEM_NAME\u003dAndroid\n-DCMAKE_EXPORT_COMPILE_COMMANDS\u003dON\n-DCMAKE_SYSTEM_VERSION\u003d21\n-DANDROID_PLATFORM\u003dandroid-21\n-DANDROID_ABI\u003d$ABI\n-DCMAKE_ANDROID_ARCH_ABI\u003d$ABI\n-DANDROID_NDK\u003d$NDK\n-DCMAKE_ANDROID_NDK\u003d$NDK\n-DCMAKE_TOOLCHAIN_FILE\u003d$NDK/build/cmake/android.toolchain.cmake\n-DCMAKE_MAKE_PROGRAM\u003d$NINJA\n-DCMAKE_CXX_FLAGS\u003d-O2 -fexceptions -frtti -std\u003dc++1y -DONANDROID\n-DCMAKE_LIBRARY_OUTPUT_DIRECTORY\u003d/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/$HASH/obj/$ABI\n-DCMAKE_RUNTIME_OUTPUT_DIRECTORY\u003d/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/$HASH/obj/$ABI\n-DCMAKE_BUILD_TYPE\u003dDebug\n-DCMAKE_FIND_ROOT_PATH\u003d/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/.cxx/Debug/$HASH/prefab/$ABI/prefab\n-B/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/.cxx/Debug/$HASH/$ABI\n-GNinja\n-DANDROID_STL\u003dc++_shared\n-DSQLITE_FLAGS\u003d\u0027-DSQLITE3MC_OMIT_AES_HARDWARE_SUPPORT -DHAVE_CIPHER_AES_128_CBC\u003d0 -DHAVE_CIPHER_AES_256_CBC\u003d0 -DHAVE_CIPHER_SQLCIPHER\u003d0 -DHAVE_CIPHER_RC4\u003d0 -DHAVE_CIPHER_CHACHA20\u003d1 -DSQLITE_ENABLE_FTS5 -DSQLITE_OMIT_PROGRESS_CALLBACK\u003d1 -DSQLITE_MAX_EXPR_DEPTH\u003d0 -DSQLITE_OMIT_DEPRECATED\u003d1 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS\u003d1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS\u003d1 -DSQLITE_DQS\u003d0 -DSQLITE_DEFAULT_MEMSTATUS\u003d0 -DSQLITE_USE_ALLOCA\u003d1\u0027\n-DUSE_HERMES\u003dtrue",
+ "configurationArguments": [
+ "-H/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android",
+ "-DCMAKE_SYSTEM_NAME\u003dAndroid",
+ "-DCMAKE_EXPORT_COMPILE_COMMANDS\u003dON",
+ "-DCMAKE_SYSTEM_VERSION\u003d21",
+ "-DANDROID_PLATFORM\u003dandroid-21",
+ "-DANDROID_ABI\u003darm64-v8a",
+ "-DCMAKE_ANDROID_ARCH_ABI\u003darm64-v8a",
+ "-DANDROID_NDK\u003d/Volumes/DataDrive/Android/sdk/ndk/23.1.7779620",
+ "-DCMAKE_ANDROID_NDK\u003d/Volumes/DataDrive/Android/sdk/ndk/23.1.7779620",
+ "-DCMAKE_TOOLCHAIN_FILE\u003d/Volumes/DataDrive/Android/sdk/ndk/23.1.7779620/build/cmake/android.toolchain.cmake",
+ "-DCMAKE_MAKE_PROGRAM\u003d/Volumes/DataDrive/Android/sdk/cmake/3.22.1/bin/ninja",
+ "-DCMAKE_CXX_FLAGS\u003d-O2 -fexceptions -frtti -std\u003dc++1y -DONANDROID",
+ "-DCMAKE_LIBRARY_OUTPUT_DIRECTORY\u003d/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/obj/arm64-v8a",
+ "-DCMAKE_RUNTIME_OUTPUT_DIRECTORY\u003d/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/obj/arm64-v8a",
+ "-DCMAKE_BUILD_TYPE\u003dDebug",
+ "-DCMAKE_FIND_ROOT_PATH\u003d/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/.cxx/Debug/3u4yy1v4/prefab/arm64-v8a/prefab",
+ "-B/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/.cxx/Debug/3u4yy1v4/arm64-v8a",
+ "-GNinja",
+ "-DANDROID_STL\u003dc++_shared",
+ "-DSQLITE_FLAGS\u003d\u0027-DSQLITE3MC_OMIT_AES_HARDWARE_SUPPORT -DHAVE_CIPHER_AES_128_CBC\u003d0 -DHAVE_CIPHER_AES_256_CBC\u003d0 -DHAVE_CIPHER_SQLCIPHER\u003d0 -DHAVE_CIPHER_RC4\u003d0 -DHAVE_CIPHER_CHACHA20\u003d1 -DSQLITE_ENABLE_FTS5 -DSQLITE_OMIT_PROGRESS_CALLBACK\u003d1 -DSQLITE_MAX_EXPR_DEPTH\u003d0 -DSQLITE_OMIT_DEPRECATED\u003d1 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS\u003d1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS\u003d1 -DSQLITE_DQS\u003d0 -DSQLITE_DEFAULT_MEMSTATUS\u003d0 -DSQLITE_USE_ALLOCA\u003d1\u0027",
+ "-DUSE_HERMES\u003dtrue"
+ ],
+ "stlLibraryFile": "/Volumes/DataDrive/Android/sdk/ndk/23.1.7779620/toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr/lib/aarch64-linux-android/libc++_shared.so",
+ "intermediatesParentFolder": "/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4"
+}
\ No newline at end of file
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/logs/arm64-v8a/generate_cxx_metadata_696_timing.txt b/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/logs/arm64-v8a/generate_cxx_metadata_696_timing.txt
new file mode 100644
index 0000000..34dc50a
--- /dev/null
+++ b/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/logs/arm64-v8a/generate_cxx_metadata_696_timing.txt
@@ -0,0 +1,7 @@
+# C/C++ build system timings
+generate_cxx_metadata
+ generate-prefab-packages
+ exec-prefab 363ms
+ generate-prefab-packages completed in 367ms
+generate_cxx_metadata completed in 372ms
+
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/logs/arm64-v8a/metadata_generation_record.json b/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/logs/arm64-v8a/metadata_generation_record.json
new file mode 100644
index 0000000..2030622
--- /dev/null
+++ b/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/logs/arm64-v8a/metadata_generation_record.json
@@ -0,0 +1,80 @@
+[
+ {
+ "level_": 0,
+ "message_": "Start JSON generation. Platform version: 21 min SDK version: arm64-v8a",
+ "file_": "/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/CMakeLists.txt",
+ "tag_": "debug|arm64-v8a",
+ "diagnosticCode_": 0,
+ "memoizedIsInitialized": 1,
+ "unknownFields": {
+ "fields": {}
+ },
+ "memoizedSize": -1,
+ "memoizedHashCode": 0
+ },
+ {
+ "level_": 0,
+ "message_": "rebuilding JSON /Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/.cxx/Debug/3u4yy1v4/arm64-v8a/android_gradle_build.json due to:",
+ "file_": "/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/CMakeLists.txt",
+ "tag_": "debug|arm64-v8a",
+ "diagnosticCode_": 0,
+ "memoizedIsInitialized": 1,
+ "unknownFields": {
+ "fields": {}
+ },
+ "memoizedSize": -1,
+ "memoizedHashCode": 0
+ },
+ {
+ "level_": 0,
+ "message_": "- no fingerprint file, will remove stale configuration folder",
+ "file_": "/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/CMakeLists.txt",
+ "tag_": "debug|arm64-v8a",
+ "diagnosticCode_": 0,
+ "memoizedIsInitialized": 1,
+ "unknownFields": {
+ "fields": {}
+ },
+ "memoizedSize": -1,
+ "memoizedHashCode": 0
+ },
+ {
+ "level_": 0,
+ "message_": "/Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home/bin/java \\\n --class-path \\\n /Users/ammarahmed/.gradle/caches/modules-2/files-2.1/com.google.prefab/cli/2.0.0/f2702b5ca13df54e3ca92f29d6b403fb6285d8df/cli-2.0.0-all.jar \\\n com.google.prefab.cli.AppKt \\\n --build-system \\\n cmake \\\n --platform \\\n android \\\n --abi \\\n arm64-v8a \\\n --os-version \\\n 21 \\\n --stl \\\n c++_shared \\\n --ndk-version \\\n 23 \\\n --output \\\n /var/folders/8n/7d231mbx74v_dqslxq126wm40000gn/T/agp-prefab-staging14064479766908916482/staged-cli-output \\\n /Users/ammarahmed/.gradle/caches/transforms-4/af547bd0d6b859d6b490959996fda082/transformed/jetified-react-android-0.74.4-debug/prefab \\\n /Users/ammarahmed/.gradle/caches/transforms-4/c7e26f7d3c2fc1a6636ff1467fc77795/transformed/jetified-fbjni-0.6.0/prefab\n",
+ "file_": "/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/CMakeLists.txt",
+ "tag_": "debug|arm64-v8a",
+ "diagnosticCode_": 0,
+ "memoizedIsInitialized": 1,
+ "unknownFields": {
+ "fields": {}
+ },
+ "memoizedSize": -1,
+ "memoizedHashCode": 0
+ },
+ {
+ "level_": 0,
+ "message_": "Received process result: 0",
+ "file_": "/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/CMakeLists.txt",
+ "tag_": "debug|arm64-v8a",
+ "diagnosticCode_": 0,
+ "memoizedIsInitialized": 1,
+ "unknownFields": {
+ "fields": {}
+ },
+ "memoizedSize": -1,
+ "memoizedHashCode": 0
+ },
+ {
+ "level_": 1,
+ "message_": "com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/fabricjni. Rejected the following libraries:",
+ "file_": "/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/CMakeLists.txt",
+ "tag_": "debug|arm64-v8a",
+ "diagnosticCode_": 0,
+ "memoizedIsInitialized": 1,
+ "unknownFields": {
+ "fields": {}
+ },
+ "memoizedSize": -1,
+ "memoizedHashCode": 0
+ }
+]
\ No newline at end of file
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/logs/arm64-v8a/prefab_command b/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/logs/arm64-v8a/prefab_command
new file mode 100755
index 0000000..76cf03e
--- /dev/null
+++ b/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/logs/arm64-v8a/prefab_command
@@ -0,0 +1,20 @@
+/Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home/bin/java \
+ --class-path \
+ /Users/ammarahmed/.gradle/caches/modules-2/files-2.1/com.google.prefab/cli/2.0.0/f2702b5ca13df54e3ca92f29d6b403fb6285d8df/cli-2.0.0-all.jar \
+ com.google.prefab.cli.AppKt \
+ --build-system \
+ cmake \
+ --platform \
+ android \
+ --abi \
+ arm64-v8a \
+ --os-version \
+ 21 \
+ --stl \
+ c++_shared \
+ --ndk-version \
+ 23 \
+ --output \
+ /var/folders/8n/7d231mbx74v_dqslxq126wm40000gn/T/agp-prefab-staging14064479766908916482/staged-cli-output \
+ /Users/ammarahmed/.gradle/caches/transforms-4/af547bd0d6b859d6b490959996fda082/transformed/jetified-react-android-0.74.4-debug/prefab \
+ /Users/ammarahmed/.gradle/caches/transforms-4/c7e26f7d3c2fc1a6636ff1467fc77795/transformed/jetified-fbjni-0.6.0/prefab
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/logs/arm64-v8a/prefab_stderr.txt b/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/logs/arm64-v8a/prefab_stderr.txt
new file mode 100644
index 0000000..f0ba97d
--- /dev/null
+++ b/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/logs/arm64-v8a/prefab_stderr.txt
@@ -0,0 +1,170 @@
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/fabricjni. Rejected the following libraries:
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
+android.x86: User is targeting arm64-v8a but library is for x86
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/folly_runtime. Rejected the following libraries:
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
+android.x86: User is targeting arm64-v8a but library is for x86
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/glog. Rejected the following libraries:
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
+android.x86: User is targeting arm64-v8a but library is for x86
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/hermes_executor. Rejected the following libraries:
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
+android.x86: User is targeting arm64-v8a but library is for x86
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/jscexecutor. Rejected the following libraries:
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
+android.x86: User is targeting arm64-v8a but library is for x86
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/jsi. Rejected the following libraries:
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
+android.x86: User is targeting arm64-v8a but library is for x86
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/jsinspector. Rejected the following libraries:
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
+android.x86: User is targeting arm64-v8a but library is for x86
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/react_codegen_rncore. Rejected the following libraries:
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
+android.x86: User is targeting arm64-v8a but library is for x86
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/react_cxxreactpackage. Rejected the following libraries:
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
+android.x86: User is targeting arm64-v8a but library is for x86
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/react_debug. Rejected the following libraries:
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
+android.x86: User is targeting arm64-v8a but library is for x86
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/react_nativemodule_core. Rejected the following libraries:
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
+android.x86: User is targeting arm64-v8a but library is for x86
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/react_newarchdefaults. Rejected the following libraries:
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
+android.x86: User is targeting arm64-v8a but library is for x86
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/react_render_animations. Rejected the following libraries:
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
+android.x86: User is targeting arm64-v8a but library is for x86
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/react_render_componentregistry. Rejected the following libraries:
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
+android.x86: User is targeting arm64-v8a but library is for x86
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/react_render_core. Rejected the following libraries:
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
+android.x86: User is targeting arm64-v8a but library is for x86
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/react_render_debug. Rejected the following libraries:
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
+android.x86: User is targeting arm64-v8a but library is for x86
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/react_render_graphics. Rejected the following libraries:
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
+android.x86: User is targeting arm64-v8a but library is for x86
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/react_render_imagemanager. Rejected the following libraries:
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
+android.x86: User is targeting arm64-v8a but library is for x86
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/react_render_mapbuffer. Rejected the following libraries:
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
+android.x86: User is targeting arm64-v8a but library is for x86
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/react_render_mounting. Rejected the following libraries:
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
+android.x86: User is targeting arm64-v8a but library is for x86
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/react_render_scheduler. Rejected the following libraries:
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
+android.x86: User is targeting arm64-v8a but library is for x86
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/react_render_textlayoutmanager. Rejected the following libraries:
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
+android.x86: User is targeting arm64-v8a but library is for x86
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/react_render_uimanager. Rejected the following libraries:
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
+android.x86: User is targeting arm64-v8a but library is for x86
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/react_utils. Rejected the following libraries:
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
+android.x86: User is targeting arm64-v8a but library is for x86
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/reactnativejni. Rejected the following libraries:
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
+android.x86: User is targeting arm64-v8a but library is for x86
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/rrc_image. Rejected the following libraries:
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
+android.x86: User is targeting arm64-v8a but library is for x86
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/rrc_legacyviewmanagerinterop. Rejected the following libraries:
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
+android.x86: User is targeting arm64-v8a but library is for x86
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/rrc_root. Rejected the following libraries:
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
+android.x86: User is targeting arm64-v8a but library is for x86
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/rrc_text. Rejected the following libraries:
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
+android.x86: User is targeting arm64-v8a but library is for x86
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/rrc_textinput. Rejected the following libraries:
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
+android.x86: User is targeting arm64-v8a but library is for x86
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/rrc_view. Rejected the following libraries:
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
+android.x86: User is targeting arm64-v8a but library is for x86
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/runtimeexecutor. Rejected the following libraries:
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
+android.x86: User is targeting arm64-v8a but library is for x86
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/turbomodulejsijni. Rejected the following libraries:
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
+android.x86: User is targeting arm64-v8a but library is for x86
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/yoga. Rejected the following libraries:
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
+android.x86: User is targeting arm64-v8a but library is for x86
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/logs/arm64-v8a/prefab_stdout.txt b/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/logs/arm64-v8a/prefab_stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties b/node_modules/react-native-quick-sqlite/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties
new file mode 100644
index 0000000..dbce266
--- /dev/null
+++ b/node_modules/react-native-quick-sqlite/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties
@@ -0,0 +1 @@
+#Thu Aug 01 12:36:04 PKT 2024
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/incremental/debug/packageDebugResources/merger.xml b/node_modules/react-native-quick-sqlite/android/build/intermediates/incremental/debug/packageDebugResources/merger.xml
new file mode 100644
index 0000000..af54be8
--- /dev/null
+++ b/node_modules/react-native-quick-sqlite/android/build/intermediates/incremental/debug/packageDebugResources/merger.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<merger version="3"><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="main$Generated" generated="true" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/src/main/res"/></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="main" generated-set="main$Generated" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/src/main/res"/></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="debug$Generated" generated="true" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/src/debug/res"/></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="debug" generated-set="debug$Generated" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/src/debug/res"/></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="generated$Generated" generated="true" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/build/generated/res/resValues/debug"/></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="generated" generated-set="generated$Generated" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/build/generated/res/resValues/debug"/></dataSet><mergedItems/></merger>
\ No newline at end of file
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/incremental/mergeDebugShaders/merger.xml b/node_modules/react-native-quick-sqlite/android/build/intermediates/incremental/mergeDebugShaders/merger.xml
new file mode 100644
index 0000000..a8ab2fe
--- /dev/null
+++ b/node_modules/react-native-quick-sqlite/android/build/intermediates/incremental/mergeDebugShaders/merger.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<merger version="3"><dataSet config="main" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/src/main/shaders"/></dataSet><dataSet config="debug" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/src/debug/shaders"/></dataSet></merger>
\ No newline at end of file
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/incremental/packageDebugAssets/merger.xml b/node_modules/react-native-quick-sqlite/android/build/intermediates/incremental/packageDebugAssets/merger.xml
new file mode 100644
index 0000000..e9d427d
--- /dev/null
+++ b/node_modules/react-native-quick-sqlite/android/build/intermediates/incremental/packageDebugAssets/merger.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<merger version="3"><dataSet config="main" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/src/main/assets"/></dataSet><dataSet config="debug" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/src/debug/assets"/></dataSet><dataSet config="generated" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/build/intermediates/shader_assets/debug/out"/></dataSet></merger>
\ No newline at end of file
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/javac/debug/classes/com/reactnativequicksqlite/BuildConfig.class b/node_modules/react-native-quick-sqlite/android/build/intermediates/javac/debug/classes/com/reactnativequicksqlite/BuildConfig.class
new file mode 100644
index 0000000..0e69a3b
Binary files /dev/null and b/node_modules/react-native-quick-sqlite/android/build/intermediates/javac/debug/classes/com/reactnativequicksqlite/BuildConfig.class differ
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/javac/debug/classes/com/reactnativequicksqlite/QuickSQLiteBridge.class b/node_modules/react-native-quick-sqlite/android/build/intermediates/javac/debug/classes/com/reactnativequicksqlite/QuickSQLiteBridge.class
new file mode 100644
index 0000000..08396d0
Binary files /dev/null and b/node_modules/react-native-quick-sqlite/android/build/intermediates/javac/debug/classes/com/reactnativequicksqlite/QuickSQLiteBridge.class differ
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/javac/debug/classes/com/reactnativequicksqlite/SequelModule.class b/node_modules/react-native-quick-sqlite/android/build/intermediates/javac/debug/classes/com/reactnativequicksqlite/SequelModule.class
new file mode 100644
index 0000000..2c123a9
Binary files /dev/null and b/node_modules/react-native-quick-sqlite/android/build/intermediates/javac/debug/classes/com/reactnativequicksqlite/SequelModule.class differ
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/javac/debug/classes/com/reactnativequicksqlite/SequelPackage.class b/node_modules/react-native-quick-sqlite/android/build/intermediates/javac/debug/classes/com/reactnativequicksqlite/SequelPackage.class
new file mode 100644
index 0000000..d78a2bf
Binary files /dev/null and b/node_modules/react-native-quick-sqlite/android/build/intermediates/javac/debug/classes/com/reactnativequicksqlite/SequelPackage.class differ
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/local_only_symbol_list/debug/R-def.txt b/node_modules/react-native-quick-sqlite/android/build/intermediates/local_only_symbol_list/debug/R-def.txt
new file mode 100644
index 0000000..78ac5b8
--- /dev/null
+++ b/node_modules/react-native-quick-sqlite/android/build/intermediates/local_only_symbol_list/debug/R-def.txt
@@ -0,0 +1,2 @@
+R_DEF: Internal format may change without notice
+local
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/manifest_merge_blame_file/debug/manifest-merger-blame-debug-report.txt b/node_modules/react-native-quick-sqlite/android/build/intermediates/manifest_merge_blame_file/debug/manifest-merger-blame-debug-report.txt
new file mode 100644
index 0000000..a67baa4
--- /dev/null
+++ b/node_modules/react-native-quick-sqlite/android/build/intermediates/manifest_merge_blame_file/debug/manifest-merger-blame-debug-report.txt
@@ -0,0 +1,7 @@
+1<?xml version="1.0" encoding="utf-8"?>
+2<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+3 package="com.reactnativequicksqlite" >
+4
+5 <uses-sdk android:minSdkVersion="21" />
+6
+7</manifest>
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/merged_manifest/debug/AndroidManifest.xml b/node_modules/react-native-quick-sqlite/android/build/intermediates/merged_manifest/debug/AndroidManifest.xml
new file mode 100644
index 0000000..65ada26
--- /dev/null
+++ b/node_modules/react-native-quick-sqlite/android/build/intermediates/merged_manifest/debug/AndroidManifest.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.reactnativequicksqlite" >
+
+ <uses-sdk android:minSdkVersion="21" />
+
+</manifest>
\ No newline at end of file
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/navigation_json/debug/navigation.json b/node_modules/react-native-quick-sqlite/android/build/intermediates/navigation_json/debug/navigation.json
new file mode 100644
index 0000000..0637a08
--- /dev/null
+++ b/node_modules/react-native-quick-sqlite/android/build/intermediates/navigation_json/debug/navigation.json
@@ -0,0 +1 @@
+[]
\ No newline at end of file
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/runtime_library_classes_jar/debug/classes.jar b/node_modules/react-native-quick-sqlite/android/build/intermediates/runtime_library_classes_jar/debug/classes.jar
new file mode 100644
index 0000000..9fb3961
Binary files /dev/null and b/node_modules/react-native-quick-sqlite/android/build/intermediates/runtime_library_classes_jar/debug/classes.jar differ
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/symbol_list_with_package_name/debug/package-aware-r.txt b/node_modules/react-native-quick-sqlite/android/build/intermediates/symbol_list_with_package_name/debug/package-aware-r.txt
new file mode 100644
index 0000000..1ab64fc
--- /dev/null
+++ b/node_modules/react-native-quick-sqlite/android/build/intermediates/symbol_list_with_package_name/debug/package-aware-r.txt
@@ -0,0 +1 @@
+com.reactnativequicksqlite
diff --git a/node_modules/react-native-quick-sqlite/android/build/outputs/logs/manifest-merger-debug-report.txt b/node_modules/react-native-quick-sqlite/android/build/outputs/logs/manifest-merger-debug-report.txt
new file mode 100644
index 0000000..50600fe
--- /dev/null
+++ b/node_modules/react-native-quick-sqlite/android/build/outputs/logs/manifest-merger-debug-report.txt
@@ -0,0 +1,17 @@
+-- Merging decision tree log ---
+manifest
+ADDED from /Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/src/main/AndroidManifest.xml:1:1-4:12
+INJECTED from /Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/src/main/AndroidManifest.xml:1:1-4:12
+ package
+ ADDED from /Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/src/main/AndroidManifest.xml:2:11-47
+ INJECTED from /Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/src/main/AndroidManifest.xml
+ xmlns:android
+ ADDED from /Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/src/main/AndroidManifest.xml:1:11-69
+uses-sdk
+INJECTED from /Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/src/main/AndroidManifest.xml reason: use-sdk injection requested
+INJECTED from /Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/src/main/AndroidManifest.xml
+INJECTED from /Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/src/main/AndroidManifest.xml
+ android:targetSdkVersion
+ INJECTED from /Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/src/main/AndroidManifest.xml
+ android:minSdkVersion
+ INJECTED from /Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/src/main/AndroidManifest.xml
diff --git a/node_modules/react-native-quick-sqlite/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin b/node_modules/react-native-quick-sqlite/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin
new file mode 100644
index 0000000..ef93f2f
Binary files /dev/null and b/node_modules/react-native-quick-sqlite/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin differ
diff --git a/node_modules/react-native-quick-sqlite/cpp/.DS_Store b/node_modules/react-native-quick-sqlite/cpp/.DS_Store
new file mode 100644
index 0000000..5008ddf
Binary files /dev/null and b/node_modules/react-native-quick-sqlite/cpp/.DS_Store differ
index 0000000..e69de29
diff --git a/node_modules/react-native-quick-sqlite/cpp/sqlite3.c b/node_modules/react-native-quick-sqlite/cpp/sqlite3.c
index 51d5dbd..895536b 100644
index 51d5dbd..f1295eb 100644
--- a/node_modules/react-native-quick-sqlite/cpp/sqlite3.c
+++ b/node_modules/react-native-quick-sqlite/cpp/sqlite3.c
@@ -1,6 +1,139 @@
@@ -1681,7 +2515,7 @@ index 51d5dbd..895536b 100644
} /* End of the 'extern "C"' block */
#endif
#endif /* SQLITE3_H */
+/* Function prototypes of SQLite3 Multiple Ciphers */
+SQLITE_PRIVATE int sqlite3mcCheckVfs(const char*);
+SQLITE_PRIVATE int sqlite3mcFileControlPragma(sqlite3*, const char*, int, void*);
@@ -104785,7 +105619,7 @@ index 51d5dbd..895536b 100644
+
+#endif
diff --git a/node_modules/react-native-quick-sqlite/cpp/sqlite3.h b/node_modules/react-native-quick-sqlite/cpp/sqlite3.h
index 9b284d2..a12c6ab 100644
index 9b284d2..bda794a 100644
--- a/node_modules/react-native-quick-sqlite/cpp/sqlite3.h
+++ b/node_modules/react-native-quick-sqlite/cpp/sqlite3.h
@@ -1,4 +1,50 @@

View File

@@ -134,15 +134,15 @@
},
"../../packages/common": {
"name": "@notesnook/common",
"version": "1.0.0",
"version": "2.0.7",
"license": "GPL-3.0-or-later",
"dependencies": {
"@notesnook/core": "file:../core",
"@notesnook/core": "^8.0.0",
"pathe": "^1.1.2",
"timeago.js": "4.0.2"
},
"devDependencies": {
"@notesnook/core": "file:../core",
"@notesnook/core": "^8.0.0",
"@types/react": "^18.2.39",
"react": "18.2.0",
"vitest": "^1.4.0"
@@ -330,7 +330,7 @@
},
"../../packages/theme": {
"name": "@notesnook/theme",
"version": "1.2.0",
"version": "2.0.7",
"license": "GPL-3.0-or-later",
"devDependencies": {
"@emotion/react": "11.11.1",
@@ -979,7 +979,7 @@
},
"../web": {
"name": "@notesnook/web",
"version": "3.0.6",
"version": "3.0.13",
"hasInstallScript": true,
"license": "GPL-3.0-or-later",
"dependencies": {
@@ -1029,12 +1029,12 @@
"framer-motion": "^10.16.8",
"hash-wasm": "^4.9.0",
"hotkeys-js": "^3.8.3",
"immer": "^10.0.3",
"katex": "0.16.2",
"kysely": "^0.26.3",
"libsodium-wrappers": "^0.7.13",
"mac-scrollbar": "^0.13.5",
"marked": "^4.1.0",
"mutative": "^1.0.6",
"pdfjs-dist": "3.6.172",
"phone": "^3.1.14",
"platform": "^1.3.6",
@@ -1059,12 +1059,14 @@
"w3c-keyname": "^2.2.6",
"web-streams-polyfill": "^3.1.1",
"wouter": "2.12.1",
"zustand": "4.4.7"
"zustand": "4.4.7",
"zustand-mutative": "^1.0.1"
},
"devDependencies": {
"@babel/core": "^7.22.5",
"@playwright/test": "^1.43.1",
"@swc/core": "1.3.61",
"@swc/core": "^1.5.24",
"@swc/plugin-react-remove-properties": "^2.0.4",
"@trpc/server": "10.38.3",
"@types/babel__core": "^7.20.1",
"@types/event-source-polyfill": "^1.0.1",
@@ -1079,8 +1081,8 @@
"@types/react-scroll-sync": "^0.9.0",
"@types/tinycolor2": "^1.4.3",
"@types/wicg-file-system-access": "^2020.9.6",
"@vitejs/plugin-react-swc": "3.3.2",
"autoprefixer": "^10.4.14",
"@vitejs/plugin-react-swc": "^3.7.0",
"autoprefixer": "^10.4.19",
"better-sqlite3-multiple-ciphers": "^9.4.0",
"buffer": "^6.0.3",
"chalk": "^4.1.0",
@@ -1091,14 +1093,13 @@
"ip": "^1.1.8",
"lorem-ipsum": "^2.0.4",
"otplib": "^12.0.1",
"rollup": "^3.29.4",
"rollup-plugin-visualizer": "^5.9.2",
"swc-plugin-react-remove-properties": "^0.1.4",
"vite": "^4.5.0",
"vite-plugin-env-compatible": "^1.1.1",
"vite-plugin-pwa": "^0.16.3",
"vite-plugin-svgr": "^3.2.0",
"vitest": "^0.34.6",
"rollup": "^4.18.0",
"rollup-plugin-visualizer": "^5.12.0",
"vite": "^5.2.12",
"vite-plugin-env-compatible": "^2.0.1",
"vite-plugin-pwa": "^0.20.0",
"vite-plugin-svgr": "^4.2.0",
"vitest": "^1.6.0",
"workbox-core": "^7.0.0",
"workbox-expiration": "^7.0.0",
"workbox-precaching": "^7.0.0",
@@ -2027,15 +2028,6 @@
"@trpc/server": "10.38.3"
}
},
"node_modules/@trpc/server": {
"version": "10.38.3",
"resolved": "https://registry.npmjs.org/@trpc/server/-/server-10.38.3.tgz",
"integrity": "sha512-9s8/kwo2IDB5hwB2SKZZrfevRhdb1f9fdXtIYd3lbQuf2jQaC/LyQuHaIQjDQoUx9updBfsHXcFFPiCP1DL6pg==",
"funding": [
"https://trpc.io/sponsor"
],
"peer": true
},
"node_modules/@types/babel__core": {
"version": "7.20.1",
"dev": true,

View File

@@ -33,7 +33,7 @@
},
"../../packages/crypto": {
"name": "@notesnook/crypto",
"version": "1.1.1",
"version": "2.0.7",
"license": "GPL-3.0-or-later",
"dependencies": {
"@notesnook/sodium": "file:../sodium"

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
{
"name": "@notesnook/web",
"description": "Your private note taking space",
"version": "3.0.10",
"version": "3.0.13",
"private": true,
"main": "./src/app.js",
"homepage": "https://notesnook.com/",
@@ -54,12 +54,12 @@
"framer-motion": "^10.16.8",
"hash-wasm": "^4.9.0",
"hotkeys-js": "^3.8.3",
"immer": "^10.0.3",
"katex": "0.16.2",
"kysely": "^0.26.3",
"libsodium-wrappers": "^0.7.13",
"mac-scrollbar": "^0.13.5",
"marked": "^4.1.0",
"mutative": "^1.0.6",
"pdfjs-dist": "3.6.172",
"phone": "^3.1.14",
"platform": "^1.3.6",
@@ -84,7 +84,8 @@
"w3c-keyname": "^2.2.6",
"web-streams-polyfill": "^3.1.1",
"wouter": "2.12.1",
"zustand": "4.4.7"
"zustand": "4.4.7",
"zustand-mutative": "^1.0.1"
},
"devDependencies": {
"@babel/core": "^7.22.5",

View File

@@ -20,7 +20,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { useEffect } from "react";
import { useStore } from "./stores/app-store";
import { useStore as useUserStore } from "./stores/user-store";
import { useStore as useAttachmentStore } from "./stores/attachment-store";
import { useEditorStore } from "./stores/editor-store";
import { useStore as useAnnouncementStore } from "./stores/announcement-store";
import { resetNotices, scheduleBackups } from "./common/notices";
@@ -30,17 +29,17 @@ import { db } from "./common/db";
import { EV, EVENTS } from "@notesnook/core/dist/common";
import { registerKeyMap } from "./common/key-map";
import { isUserPremium } from "./hooks/use-is-user-premium";
import {
showAnnouncementDialog,
showBuyDialog,
showFeatureDialog,
showOnboardingDialog
} from "./common/dialog-controller";
import { updateStatus, removeStatus, getStatus } from "./hooks/use-status";
import { showToast } from "./utils/toast";
import { interruptedOnboarding } from "./dialogs/onboarding-dialog";
import {
interruptedOnboarding,
OnboardingDialog
} from "./dialogs/onboarding-dialog";
import { hashNavigate } from "./navigation";
import { desktop } from "./common/desktop-bridge";
import { BuyDialog } from "./dialogs/buy-dialog";
import { FeatureDialog } from "./dialogs/feature-dialog";
import { AnnouncementDialog } from "./dialogs/announcement-dialog";
type AppEffectsProps = {
setShow: (show: boolean) => void;
@@ -51,7 +50,6 @@ export default function AppEffects({ setShow }: AppEffectsProps) {
const isFocusMode = useStore((store) => store.isFocusMode);
const initUser = useUserStore((store) => store.init);
const initStore = useStore((store) => store.init);
const initAttachments = useAttachmentStore((store) => store.init);
const setIsVaultCreated = useStore((store) => store.setIsVaultCreated);
const initEditorStore = useEditorStore((store) => store.init);
const dialogAnnouncements = useAnnouncementStore(
@@ -69,7 +67,7 @@ export default function AppEffects({ setShow }: AppEffectsProps) {
showToast(
"error",
"Please upgrade your account to Pro to use this feature.",
[{ text: "Upgrade now", onClick: () => showBuyDialog() }]
[{ text: "Upgrade now", onClick: () => BuyDialog.show({}) }]
);
return { type, result: false };
}
@@ -77,7 +75,6 @@ export default function AppEffects({ setShow }: AppEffectsProps) {
);
initStore();
initAttachments();
initEditorStore();
(async function () {
@@ -89,8 +86,9 @@ export default function AppEffects({ setShow }: AppEffectsProps) {
await resetNotices();
setIsVaultCreated(await db.vault.exists());
await showOnboardingDialog(interruptedOnboarding());
await showFeatureDialog("highlights");
const onboardingKey = interruptedOnboarding();
if (onboardingKey) await OnboardingDialog.show({ type: onboardingKey });
await FeatureDialog.show({ featureName: "highlights" });
await scheduleBackups();
})();
@@ -101,7 +99,6 @@ export default function AppEffects({ setShow }: AppEffectsProps) {
[
initEditorStore,
initStore,
initAttachments,
updateLastSynced,
refreshNavItems,
initUser,
@@ -224,7 +221,7 @@ export default function AppEffects({ setShow }: AppEffectsProps) {
useEffect(() => {
if (!dialogAnnouncements.length || IS_TESTING) return;
(async () => {
await showAnnouncementDialog(dialogAnnouncements[0]);
await AnnouncementDialog.show({ announcement: dialogAnnouncements[0] });
})();
}, [dialogAnnouncements]);

View File

@@ -20,7 +20,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import { EventSourcePolyfill as EventSource } from "event-source-polyfill";
import { DatabasePersistence, NNStorage } from "../interfaces/storage";
import { logger } from "../utils/logger";
import { showMigrationDialog } from "./dialog-controller";
import { database } from "@notesnook/common";
import { createDialect } from "./sqlite";
import { isFeatureSupported } from "../utils/feature-check";
@@ -119,7 +118,9 @@ async function initializeDatabase(persistence: DatabasePersistence) {
logger.measure("Database initialization");
if (db.migrations?.required()) {
await showMigrationDialog();
await import("../dialogs/migration-dialog").then(({ MigrationDialog }) =>
MigrationDialog.show({})
);
}
return db;

View File

@@ -28,7 +28,10 @@ export const desktop = createTRPCProxyClient<AppRouter>({
links: [ipcLink()]
});
document.addEventListener("readystatechange", async () => {
attachListeners();
function attachListeners() {
console.log("attaching listeners");
desktop.updater.onChecking.subscribe(
undefined,
attachListener(AppEvents.checkingForUpdate)
@@ -62,7 +65,7 @@ document.addEventListener("readystatechange", async () => {
TaskScheduler.register("updateCheck", "0 0 */12 * * * *", () => {
checkForUpdate();
});
});
}
function attachListener(event: string) {
return {

View File

@@ -1,577 +0,0 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { Dialogs } from "../dialogs";
import { store as tagStore } from "../stores/tag-store";
import { store as appStore } from "../stores/app-store";
import { useEditorStore } from "../stores/editor-store";
import { store as noteStore } from "../stores/note-store";
import { db } from "./db";
import { showToast } from "../utils/toast";
import Config from "../utils/config";
import { AppVersion, getChangelog } from "../utils/version";
import { Period } from "../dialogs/buy-dialog/types";
import { FeatureKeys } from "../dialogs/feature-dialog";
import { Suspense } from "react";
import { ConfirmDialogProps } from "../dialogs/confirm";
import { getFormattedDate } from "@notesnook/common";
import { downloadUpdate } from "../utils/updater";
import { ThemeMetadata } from "@notesnook/themes-server";
import {
Color,
Profile,
Reminder,
Tag,
AuthenticatorType
} from "@notesnook/core";
import { createRoot } from "react-dom/client";
import { PasswordDialogProps } from "../dialogs/password-dialog";
import { LinkAttributes } from "@notesnook/editor/dist/extensions/link";
type DialogTypes = typeof Dialogs;
type DialogIds = keyof DialogTypes;
export type Perform<T = boolean> = (result: T) => void;
type RenderDialog<TId extends DialogIds, TReturnType> = (
dialog: DialogTypes[TId],
perform: (result: TReturnType) => void
) => JSX.Element;
let openDialogs: Partial<Record<DialogIds, boolean>> = {};
function showDialog<TId extends DialogIds, TReturnType>(
id: TId,
render: RenderDialog<TId, TReturnType>
): Promise<TReturnType> {
return new Promise((resolve) => {
if (openDialogs[id]) return false;
const container = document.createElement("div");
container.id = id;
const root = createRoot(container);
const perform = (result: TReturnType) => {
openDialogs[id] = false;
root.unmount();
container.remove();
resolve(result);
};
const PropDialog = () => render(Dialogs[id], perform);
root.render(
<Suspense fallback={<div />}>
<PropDialog />
</Suspense>
);
openDialogs[id] = true;
});
}
export function closeOpenedDialog() {
openDialogs = {};
const dialogs = document.querySelectorAll(
".ReactModalPortal,[data-react-modal-body-trap]"
);
dialogs.forEach((elem) => elem.remove());
}
export function showAddTagsDialog(noteIds: string[]) {
return showDialog("AddTagsDialog", (Dialog, perform) => (
<Dialog onClose={(res: any) => perform(res)} noteIds={noteIds} />
));
}
export function showCreateColorDialog() {
return showDialog<"CreateColorDialog", string | undefined>(
"CreateColorDialog",
(Dialog, perform) => (
<Dialog onClose={() => perform(undefined)} onDone={(id) => perform(id)} />
)
);
}
export function showAddNotebookDialog(parentId?: string) {
return showDialog("AddNotebookDialog", (Dialog, perform) => (
<Dialog
parentId={parentId}
onClose={() => {
perform(false);
}}
/>
));
}
export function showNoteLinkingDialog(attr?: LinkAttributes) {
return showDialog<"NoteLinkingDialog", LinkAttributes | undefined>(
"NoteLinkingDialog",
(Dialog, perform) => (
<Dialog
attributes={attr}
onDone={(link) => perform(link)}
onClose={() => perform(undefined)}
/>
)
);
}
export async function showEditNotebookDialog(notebookId: string) {
const notebook = await db.notebooks.notebook(notebookId);
if (!notebook) return;
return await showDialog("AddNotebookDialog", (Dialog, perform) => (
<Dialog
notebook={notebook}
edit={true}
onClose={() => {
perform(false);
}}
/>
));
}
export function showBuyDialog(plan?: Period, couponCode?: string) {
return showDialog("BuyDialog", (Dialog, perform) => (
<Dialog
plan={plan}
couponCode={couponCode}
onClose={() => perform(false)}
/>
));
}
export function confirm<TCheckId extends string>(
props: Omit<ConfirmDialogProps<TCheckId>, "onClose">
) {
return showDialog<"Confirm", false | Record<TCheckId, boolean>>(
"Confirm",
(Dialog, perform) => (
<Dialog {...props} onClose={(result) => perform(result)} />
)
);
}
export function showPromptDialog(props: {
title: string;
description?: string;
defaultValue?: string;
}) {
return showDialog<"Prompt", string | null>("Prompt", (Dialog, perform) => (
<Dialog
{...props}
onClose={() => perform(null)}
onSave={(text) => {
perform(text);
}}
/>
));
}
export function showEmailChangeDialog() {
return showDialog("EmailChangeDialog", (Dialog, perform) => (
<Dialog onClose={() => perform(null)} />
));
}
export function showError(title: string, message: string) {
return confirm({ title, message, positiveButtonText: "Okay" });
}
export function showMultiDeleteConfirmation(length: number) {
return confirm({
title: `Delete ${length} items?`,
message: `These items will be **kept in your Trash for ${
db.settings.getTrashCleanupInterval() || 7
} days** after which they will be permanently deleted.`,
positiveButtonText: "Yes",
negativeButtonText: "No"
});
}
export function showMultiPermanentDeleteConfirmation(length: number) {
return confirm({
title: `Permanently delete ${length} items?`,
message:
"These items will be **permanently deleted**. This is IRREVERSIBLE.",
positiveButtonText: "Yes",
negativeButtonText: "No"
});
}
export function showLogoutConfirmation() {
return confirm({
title: `Logout?`,
message:
"Logging out will clear all data stored on THIS DEVICE. Make sure you have synced all your changes before logging out.",
positiveButtonText: "Yes",
negativeButtonText: "No"
});
}
export function showClearSessionsConfirmation() {
return confirm({
title: `Logout from other devices?`,
message:
"All other logged-in devices will be forced to logout stopping sync. Use with care lest you lose important notes.",
positiveButtonText: "Yes",
negativeButtonText: "No"
});
}
export function showAccountLoggedOutNotice(reason?: string) {
return confirm({
title: "You were logged out",
message: reason,
negativeButtonText: "Okay"
});
}
export function showAppUpdatedNotice(
version: AppVersion & { changelog?: string }
) {
return confirm({
title: `Welcome to v${version.formatted}`,
message: `## Changelog:
\`\`\`
${version.changelog || "No change log."}
\`\`\`
`,
positiveButtonText: `Continue`
});
}
export function showEmailVerificationDialog() {
return showDialog("EmailVerificationDialog", (Dialog, perform) => (
<Dialog onCancel={() => perform(false)} />
));
}
export function showMigrationDialog() {
return showDialog("MigrationDialog", (Dialog, perform) => (
<Dialog onClose={() => perform(false)} />
));
}
type LoadingDialogProps<T> = {
title: string;
message?: string;
subtitle: string;
action: () => T | Promise<T>;
};
export function showLoadingDialog<T>(dialogData: LoadingDialogProps<T>) {
const { title, message, subtitle, action } = dialogData;
return showDialog<"LoadingDialog", T | boolean>(
"LoadingDialog",
(Dialog, perform) => (
<Dialog
title={title}
description={subtitle}
message={message}
action={action}
onClose={(e) => perform(e as T | boolean)}
/>
)
);
}
type ProgressDialogProps = {
title: string;
subtitle: string;
action: (...args: never[]) => void;
};
export function showProgressDialog<T>(dialogData: ProgressDialogProps) {
const { title, subtitle, action } = dialogData;
return showDialog<"ProgressDialog", T>(
"ProgressDialog",
(Dialog, perform) => (
<Dialog
title={title}
subtitle={subtitle}
action={action}
onDone={(e: T) => perform(e)}
/>
)
);
}
export function showThemeDetails(theme: ThemeMetadata) {
return showDialog("ThemeDetailsDialog", (Dialog, perform) => (
<Dialog theme={theme} onClose={(res: boolean) => perform(res)} />
));
}
export function showMoveNoteDialog(noteIds: string[]) {
return showDialog("MoveDialog", (Dialog, perform) => (
<Dialog noteIds={noteIds} onClose={(res: boolean) => perform(res)} />
));
}
export function showPasswordDialog<
TInputId extends string,
TCheckId extends string
>(props: Omit<PasswordDialogProps<TInputId, TCheckId>, "onClose">) {
return showDialog<
"PasswordDialog",
string extends TCheckId ? boolean : false | Record<TCheckId, boolean>
>("PasswordDialog", (Dialog, perform) => (
<Dialog
{...props}
onClose={(result) =>
perform(
result as string extends TCheckId
? boolean
: false | Record<TCheckId, boolean>
)
}
/>
));
}
export function showBackupPasswordDialog(
validate: (outputs: {
password?: string;
key?: string;
}) => boolean | Promise<boolean>
) {
return showDialog("BackupPasswordDialog", (Dialog, perform) => (
<Dialog onClose={() => perform(false)} validate={validate} />
));
}
export function showRecoveryKeyDialog() {
return showDialog("RecoveryKeyDialog", (Dialog, perform) => (
<Dialog onDone={() => perform(true)} />
));
}
export function showCreateTagDialog() {
return showDialog("ItemDialog", (Dialog, perform) => (
<Dialog
title={"Create tag"}
subtitle={"You can create as many tags as you want."}
onClose={() => {
perform(false);
}}
onAction={async (title: string) => {
await db.tags.add({ title });
showToast("success", "Tag created!");
tagStore.refresh();
perform(true);
}}
/>
));
}
export function showEditTagDialog(tag: Tag) {
return showDialog("ItemDialog", (Dialog, perform) => (
<Dialog
title={"Edit tag"}
subtitle={`You are editing #${tag.title}.`}
defaultValue={tag.title}
onClose={() => perform(false)}
onAction={async (title: string) => {
await db.tags.add({ id: tag.id, title });
showToast("success", "Tag edited!");
await tagStore.refresh();
await useEditorStore.getState().refreshTags();
await noteStore.refresh();
await appStore.refreshNavItems();
perform(true);
}}
/>
));
}
export function showRenameColorDialog(color: Color) {
return showDialog("ItemDialog", (Dialog, perform) => (
<Dialog
title={"Rename color"}
subtitle={`You are renaming color ${color.title}.`}
defaultValue={color.title}
onClose={() => perform(false)}
onAction={async (title: string) => {
if (!title) return;
await db.colors.add({ id: color.id, title });
showToast("success", "Color renamed!");
appStore.refreshNavItems();
perform(true);
}}
/>
));
}
export function showFeatureDialog(featureName: FeatureKeys) {
return showDialog("FeatureDialog", (Dialog, perform) => (
<Dialog featureName={featureName} onClose={(res) => perform(res)} />
));
}
export function showReminderDialog(reminderKey: string) {
if (Config.get(reminderKey, false)) return;
return showDialog("ReminderDialog", (Dialog, perform) => (
<Dialog
reminderKey={reminderKey}
onClose={(res: boolean) => {
Config.set(reminderKey, true);
perform(res);
}}
/>
));
}
export function showReminderPreviewDialog(reminder: Reminder) {
return showDialog("ReminderPreviewDialog", (Dialog, perform) => (
<Dialog reminder={reminder} onClose={perform} />
));
}
export async function showAddReminderDialog(noteId?: string) {
const note = noteId ? await db.notes.note(noteId) : undefined;
return showDialog("AddReminderDialog", (Dialog, perform) => (
<Dialog onClose={(res: boolean) => perform(res)} note={note} />
));
}
export async function showEditReminderDialog(reminderId: string) {
const reminder = await db.reminders.reminder(reminderId);
if (!reminder) return null;
return showDialog("AddReminderDialog", (Dialog, perform) => (
<Dialog onClose={(res: boolean) => perform(res)} reminder={reminder} />
));
}
export function showAnnouncementDialog(announcement: any) {
return showDialog("AnnouncementDialog", (Dialog, perform) => (
<Dialog
announcement={announcement}
onClose={(res: boolean) => perform(res)}
/>
));
}
export function showIssueDialog() {
return showDialog("IssueDialog", (Dialog, perform) => (
<Dialog
onClose={(res: boolean) => {
perform(res);
}}
/>
));
}
export function showMultifactorDialog(primaryMethod?: AuthenticatorType) {
return showDialog("MultifactorDialog", (Dialog, perform) => (
<Dialog onClose={(res) => perform(res)} primaryMethod={primaryMethod} />
));
}
export function show2FARecoveryCodesDialog(primaryMethod: AuthenticatorType) {
return showDialog("RecoveryCodesDialog", (Dialog, perform) => (
<Dialog onClose={(res) => perform(res)} primaryMethod={primaryMethod} />
));
}
export function showAttachmentsDialog() {
return showDialog("AttachmentsDialog", (Dialog, perform) => (
<Dialog onClose={(res: boolean) => perform(res)} />
));
}
export function showEditProfilePictureDialog(profile?: Profile) {
return showDialog("EditProfilePictureDialog", (Dialog, perform) => (
<Dialog onClose={(res: boolean) => perform(res)} profile={profile} />
));
}
export function showImagePickerDialog(images: File[]): Promise<false | File[]> {
if (images.length <= 0) return Promise.resolve(false);
return showDialog("ImagePickerDialog", (Dialog, perform) => (
<Dialog onClose={(res) => perform(res)} images={images} />
));
}
export function showSettings() {
return showDialog("SettingsDialog", (Dialog, perform) => (
<Dialog onClose={(res: boolean) => perform(res)} />
));
}
export function showOnboardingDialog(type?: string) {
if (!type) return;
return showDialog("OnboardingDialog", (Dialog, perform) => (
<Dialog type={type} onClose={(res: boolean) => perform(res)} />
));
}
export async function showInvalidSystemTimeDialog({
serverTime,
localTime
}: {
serverTime: number;
localTime: number;
}) {
const result = await confirm({
title: "Your system clock is out of sync",
subtitle:
"Please correct your system date & time and reload the app to avoid syncing issues.",
message: `Server time: ${getFormattedDate(serverTime)}
Local time: ${getFormattedDate(localTime)}
Please sync your system time with [https://time.is](https://time.is).`,
positiveButtonText: "Reload app"
});
if (result) window.location.reload();
}
export async function showUpdateAvailableNotice({
version
}: {
version: string;
}) {
const changelog = await getChangelog(version);
return showUpdateDialog({
title: `New version available`,
subtitle: `v${version} is available for download`,
changelog,
action: { text: `Update now`, onClick: () => downloadUpdate() }
});
}
type UpdateDialogProps = {
title: string;
subtitle: string;
changelog: string;
action: {
text: string;
onClick: () => void;
};
};
async function showUpdateDialog({
title,
subtitle,
changelog,
action
}: UpdateDialogProps) {
const result = await confirm({
title,
subtitle,
message: changelog,
width: 500,
positiveButtonText: action.text
});
if (result && action.onClick) action.onClick();
}

View File

@@ -0,0 +1,88 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import React from "react";
import { createRoot } from "react-dom/client";
export interface BaseDialogProps<T = unknown> {
onClose: (result: T) => void;
}
class _DialogManager {
private openedDialogs: Set<React.JSXElementConstructor<any>> = new Set();
open<
Props extends BaseDialogProps<any>,
Result extends Props extends BaseDialogProps<infer T> ? T : unknown
>(
component: React.ComponentType<Props>,
props: Omit<Props, "onClose">
): Promise<Result | false> {
if (this.openedDialogs.has(component)) return Promise.resolve(false);
const container = document.createElement("div");
const root = createRoot(container);
const close = () => {
this.openedDialogs.delete(component);
root.unmount();
container.remove();
};
const Dialog = component as React.FunctionComponent<
Omit<Props, "onClose"> & {
onClose: (result: any) => void;
}
>;
this.openedDialogs.add(component);
return new Promise<Result>((resolve, reject) =>
root.render(
<Dialog
{...props}
onClose={(result: Result) => {
try {
close();
resolve(result);
} catch (e) {
reject(e);
}
}}
/>
)
);
}
closeAll() {
this.openedDialogs.clear();
const dialogs = document.querySelectorAll(
".ReactModalPortal,[data-react-modal-body-trap]"
);
dialogs.forEach((elem) => elem.remove());
}
register<Props extends BaseDialogProps<any>>(
component: React.ComponentType<Props>
) {
return {
show: (props: Omit<Props, "onClose">) => this.open(component, props)
};
}
}
export const DialogManager = new _DialogManager();

View File

@@ -32,7 +32,7 @@ import {
import Vault from "./vault";
import { ExportStream } from "../utils/streams/export-stream";
import { showToast } from "../utils/toast";
import { confirm } from "./dialog-controller";
import { ConfirmDialog } from "../dialogs/confirm";
export async function exportToPDF(
title: string,
@@ -101,14 +101,14 @@ export async function exportNotes(
}
});
if (result instanceof Error) {
confirm({
ConfirmDialog.show({
title: `Export failed`,
message: result.stack || result.message,
positiveButtonText: "Okay"
});
return false;
} else {
confirm({
ConfirmDialog.show({
title: `Exported ${result.count} notes`,
message:
result.errors.length > 0

View File

@@ -17,12 +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 {
showBackupPasswordDialog,
showFeatureDialog,
showPasswordDialog,
showReminderDialog
} from "./dialog-controller";
import Config from "../utils/config";
import { hashNavigate, getCurrentHash } from "../navigation";
import { db } from "./db";
@@ -38,12 +32,15 @@ import { TaskManager } from "./task-manager";
import { EVENTS } from "@notesnook/core/dist/common";
import { createWritableStream } from "./desktop-bridge";
import { createZipStream } from "../utils/streams/zip-stream";
import { FeatureKeys } from "../dialogs/feature-dialog";
import { FeatureDialog, FeatureKeys } from "../dialogs/feature-dialog";
import { ZipEntry, createUnzipIterator } from "../utils/streams/unzip-stream";
import { User } from "@notesnook/core";
import { LegacyBackupFile } from "@notesnook/core";
import { useEditorStore } from "../stores/editor-store";
import { formatDate } from "@notesnook/core/dist/utils/date";
import { showPasswordDialog } from "../dialogs/password-dialog";
import { BackupPasswordDialog } from "../dialogs/backup-password-dialog";
import { ReminderDialog } from "../dialogs/reminder-dialog";
export const CREATE_BUTTON_MAP = {
notes: {
@@ -70,7 +67,7 @@ export async function introduceFeatures() {
const features: FeatureKeys[] = [];
for (const feature of features) {
if (!Config.get(`feature:${feature}`)) {
await showFeatureDialog(feature);
await FeatureDialog.show({ featureName: feature });
}
}
}
@@ -173,10 +170,12 @@ export async function restoreBackupFile(backupFile: File) {
const backup = JSON.parse(await readFile(backupFile));
if (backup.data.iv && backup.data.salt) {
await showBackupPasswordDialog(async ({ password, key }) => {
if (!password && !key) return false;
const error = await restoreWithProgress(backup, password, key);
return !error;
await BackupPasswordDialog.show({
validate: async ({ password, key }) => {
if (!password && !key) return false;
const error = await restoreWithProgress(backup, password, key);
return !error;
}
});
} else {
await restoreWithProgress(backup);
@@ -212,15 +211,15 @@ export async function restoreBackupFile(backupFile: File) {
const backup = JSON.parse(await entry.text());
if (backup.encrypted) {
if (!cachedPassword && !cachedKey) {
const result = await showBackupPasswordDialog(
async ({ password, key }) => {
const result = await BackupPasswordDialog.show({
validate: async ({ password, key }) => {
if (!password && !key) return false;
await db.backup?.import(backup, password, key);
cachedPassword = password;
cachedKey = key;
return true;
}
);
});
if (!result) break;
} else await db.backup?.import(backup, cachedPassword, cachedKey);
} else {
@@ -318,9 +317,9 @@ export async function showUpgradeReminderDialogs() {
const isTrial = user.subscription?.type === SUBSCRIPTION_STATUS.TRIAL;
const isBasic = user.subscription?.type === SUBSCRIPTION_STATUS.BASIC;
if (isBasic && consumed >= 100) {
await showReminderDialog("trialexpired");
await ReminderDialog.show({ reminderKey: "trialexpired" });
} else if (isTrial && consumed >= 75) {
await showReminderDialog("trialexpiring");
await ReminderDialog.show({ reminderKey: "trialexpiring" });
}
}

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 { confirm, showMultiDeleteConfirmation } from "./dialog-controller";
import { store as noteStore } from "../stores/note-store";
import { store as notebookStore } from "../stores/notebook-store";
import { store as attachmentStore } from "../stores/attachment-store";
@@ -27,6 +26,7 @@ import { showToast } from "../utils/toast";
import Vault from "./vault";
import { TaskManager } from "./task-manager";
import { pluralize } from "@notesnook/common";
import { ConfirmDialog, showMultiDeleteConfirmation } from "../dialogs/confirm";
async function moveNotesToTrash(ids: string[], confirm = true) {
if (confirm && !(await showMultiDeleteConfirmation(ids.length))) return;
@@ -79,7 +79,7 @@ async function moveNotebooksToTrash(ids: string[]) {
async function deleteAttachments(ids: string[]) {
if (
!(await confirm({
!(await ConfirmDialog.show({
title: "Are you sure?",
message:
"Are you sure you want to permanently delete these attachments? This action is IRREVERSIBLE.",

View File

@@ -23,12 +23,12 @@ import { db } from "./db";
import { store as appStore } from "../stores/app-store";
import { Backup, User, Email, Warn, Icon } from "../components/icons";
import dayjs from "dayjs";
import { showBuyDialog, showRecoveryKeyDialog } from "./dialog-controller";
import { hardNavigate, hashNavigate } from "../navigation";
import { isUserPremium } from "../hooks/use-is-user-premium";
import { showToast } from "../utils/toast";
import { TaskScheduler } from "../utils/task-scheduler";
import { BuyDialog } from "../dialogs/buy-dialog";
import { RecoveryKeyDialog } from "../dialogs/recovery-key-dialog";
export type NoticeType = "autoBackupsOff" | "login" | "email" | "recoverykey";
@@ -119,7 +119,7 @@ export const NoticesData: Record<NoticeType, NoticeData> = {
key: "autoBackupsOff",
title: "Automatic backups disabled",
subtitle: "Please upgrade to Pro to enable automatic backups.",
action: () => showBuyDialog(),
action: () => BuyDialog.show({}),
dismissable: true,
icon: Backup
},
@@ -143,7 +143,7 @@ export const NoticesData: Record<NoticeType, NoticeData> = {
subtitle: "Keep your recovery key safe",
dismissable: true,
action: async () => {
if (await verifyAccount()) await showRecoveryKeyDialog();
if (await verifyAccount()) await RecoveryKeyDialog.show({});
},
icon: Warn
}

View File

@@ -16,30 +16,37 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { immerable, setAutoFreeze } from "immer";
import { create } from "zustand";
import {
subscribeWithSelector,
persist,
PersistOptions
} from "zustand/middleware";
import { immer } from "zustand/middleware/immer";
import { GetState, IStore, SetState } from "../stores";
setAutoFreeze(false);
import { mutative } from "zustand-mutative";
export function createStore<T>(
getStore: (set: SetState<T>, get: GetState<T>) => T
) {
const store = create<
T,
[["zustand/subscribeWithSelector", never], ["zustand/immer", never]]
[["zustand/subscribeWithSelector", never], ["zustand/mutative", never]]
>(
subscribeWithSelector(
immer((set, get) => {
const store = getStore(set, get);
(store as any)[immerable] = true;
return store;
})
mutative(
(set, get) => {
const store = getStore(set, get);
return store;
},
{
strict: import.meta.env.DEV,
mark: (target, { mutable, immutable }) => {
if (!target || typeof target !== "object") return mutable;
return immutable;
}
}
)
)
);
return [store, store.getState()] as const;
@@ -54,16 +61,24 @@ export function createPersistedStore<T extends object>(
[
["zustand/persist", Partial<T>],
["zustand/subscribeWithSelector", never],
["zustand/immer", never]
["zustand/mutative", never]
]
>(
persist(
subscribeWithSelector(
immer((set, get) => {
const store = new Store(set, get);
(store as any)[immerable] = true;
return store;
})
mutative(
(set, get) => {
const store = new Store(set, get);
return store;
},
{
strict: import.meta.env.DEV,
mark: (target, { mutable, immutable }) => {
if (!target || typeof target !== "object") return mutable;
return immutable;
}
}
)
),
options
)

View File

@@ -17,8 +17,8 @@ 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 { ProgressDialog } from "../dialogs/progress-dialog";
import { removeStatus, updateStatus } from "../hooks/use-status";
import { showProgressDialog } from "./dialog-controller";
type TaskType = "status" | "modal";
type TaskAction<T> = (report: ProgressReportCallback) => T | Promise<T>;
@@ -74,11 +74,11 @@ export class TaskManager {
return result;
}
case "modal": {
return await showProgressDialog<T | Error>({
return (await ProgressDialog.show({
title: task.title,
subtitle: task.subtitle,
action: task.action
});
})) as T;
}
}
}

View File

@@ -18,7 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { db } from "./db";
import { showPasswordDialog } from "./dialog-controller";
import { showPasswordDialog } from "../dialogs/password-dialog";
import { showToast } from "../utils/toast";
import { VAULT_ERRORS } from "@notesnook/core/dist/api/vault";

View File

@@ -24,10 +24,6 @@ import {
Image as RebassImage,
Text as RebassText
} from "@theme-ui/components";
import {
closeOpenedDialog,
showBuyDialog
} from "../../common/dialog-controller";
import { ANALYTICS_EVENTS, trackEvent } from "../../utils/analytics";
import {
Sync,
@@ -43,6 +39,8 @@ import { store as appStore } from "../../stores/app-store";
import { createBackup } from "../../common";
import { allowedPlatforms } from "../../stores/announcement-store";
import { alpha } from "@theme-ui/color";
import { BuyDialog } from "../../dialogs/buy-dialog/buy-dialog";
import { DialogManager } from "../../common/dialog-manager";
var margins = [0, 2];
var HORIZONTAL_MARGIN = 3;
@@ -285,7 +283,7 @@ function CalltoAction({ action, variant, sx, dismissAnnouncement }) {
sx={sx}
onClick={async () => {
if (dismissAnnouncement) dismissAnnouncement();
closeOpenedDialog();
DialogManager.closeAll();
trackEvent(ANALYTICS_EVENTS.announcementCta, action);
switch (action.type) {
case "link": {
@@ -299,7 +297,7 @@ function CalltoAction({ action, variant, sx, dismissAnnouncement }) {
}
case "promo": {
const [coupon, plan] = action.data.split(":");
await showBuyDialog(plan, coupon);
await BuyDialog.show({ plan, coupon });
break;
}
case "force-sync": {

View File

@@ -38,10 +38,6 @@ import {
Reupload,
Uploading
} from "../icons";
import {
closeOpenedDialog,
showPromptDialog
} from "../../common/dialog-controller";
import { store, useStore } from "../../stores/attachment-store";
import { db } from "../../common/db";
import { saveAttachment } from "../../common/attachments";
@@ -59,6 +55,8 @@ import { getFormattedDate } from "@notesnook/common";
import { MenuItem } from "@notesnook/ui";
import { Attachment as AttachmentType } from "@notesnook/core";
import { useEditorStore } from "../../stores/editor-store";
import { PromptDialog } from "../../dialogs/prompt";
import { DialogManager } from "../../common/dialog-manager";
const FILE_ICONS: Record<string, Icon> = {
"image/": FileImage,
@@ -158,8 +156,7 @@ export function Attachment({
<td>
<Flex
sx={{
alignItems: "center",
maxWidth: compact ? 180 : "95%"
alignItems: "center"
}}
>
{status ? (
@@ -211,7 +208,12 @@ export function Attachment({
<Text
as="td"
variant="body"
sx={{ color: status ? "accent" : "paragraph" }}
sx={{
color: status ? "accent" : "paragraph",
whiteSpace: "nowrap",
overflow: "hidden",
textOverflow: "ellipsis"
}}
>
{status ? (
<>
@@ -259,7 +261,7 @@ const AttachmentMenuItems: (
title: note.title,
onClick: () => {
useEditorStore.getState().openSession(note.id);
closeOpenedDialog();
DialogManager.closeAll();
}
});
}
@@ -291,7 +293,7 @@ const AttachmentMenuItems: (
title: "Rename",
icon: Rename.path,
onClick: async () => {
const newName = await showPromptDialog({
const newName = await PromptDialog.show({
title: "Rename attachment",
description: attachment.filename,
defaultValue: attachment.filename

View File

@@ -281,21 +281,21 @@ function TabStrip() {
items={sessions}
moveItem={(from, to) => {
if (from === to) return;
useEditorStore.setState((state) => {
const isToPinned = state.sessions[to].pinned;
const [fromTab] = state.sessions.splice(from, 1);
const sessions = useEditorStore.getState().sessions.slice();
const isToPinned = sessions[to].pinned;
const [fromTab] = sessions.splice(from, 1);
// if the tab where this tab is being dropped is pinned,
// let's pin our tab too.
if (isToPinned) {
fromTab.pinned = true;
fromTab.preview = false;
}
// unpin the tab if it is moved.
else if (fromTab.pinned) fromTab.pinned = false;
// if the tab where this tab is being dropped is pinned,
// let's pin our tab too.
if (isToPinned) {
fromTab.pinned = true;
fromTab.preview = false;
}
// unpin the tab if it is moved.
else if (fromTab.pinned) fromTab.pinned = false;
state.sessions.splice(to, 0, fromTab);
});
sessions.splice(to, 0, fromTab);
useEditorStore.setState({ sessions });
}}
renderItem={({ item: session, index: i }) => (
<Tab

View File

@@ -34,36 +34,28 @@ import { Tag } from "@notesnook/core";
type HeaderProps = { readonly: boolean; id: string };
function Header(props: HeaderProps) {
const { readonly, id } = props;
const session = useEditorStore((store) =>
store.getActiveSession(["default", "readonly"])
const tags = useEditorStore(
(store) => store.getActiveSession(["default", "readonly"])?.tags
);
const tags = session?.tags || [];
const refreshTags = useEditorStore((store) => store.refreshTags);
useEffect(() => {
refreshTags();
}, [id, refreshTags, session?.type]);
const setTag = useCallback(
async function (noteId: string, tags: Tag[], value: string) {
const oldTag = tags.find((t) => t.title === value);
if (oldTag) {
await db.relations.unlink(oldTag, { type: "note", id: noteId });
} else {
const id =
(await db.tags.find(value))?.id ??
(await db.tags.add({ title: value }));
await db.relations.add(
{ id, type: "tag" },
{ type: "note", id: noteId }
);
await useTagStore.getState().refresh();
}
await refreshTags();
await useNoteStore.getState().refresh();
},
[refreshTags]
);
const setTag = useCallback(async function (
noteId: string,
tags: Tag[],
value: string
) {
const oldTag = tags.find((t) => t.title === value);
if (oldTag) {
await db.relations.unlink(oldTag, { type: "note", id: noteId });
} else {
const id =
(await db.tags.find(value))?.id ??
(await db.tags.add({ title: value }));
await db.relations.add({ id, type: "tag" }, { type: "note", id: noteId });
await useTagStore.getState().refresh();
}
await useNoteStore.getState().refresh();
},
[]);
return (
<>
@@ -82,7 +74,7 @@ function Header(props: HeaderProps) {
styles={{ container: { mr: 1 }, text: { fontSize: "body" } }}
/>
))}
{!!session && !readonly && tags ? (
{!readonly && tags ? (
<Autosuggest
sessionId={id}
filter={(query) => db.lookup.tags(query).items(10)}

View File

@@ -64,12 +64,12 @@ import { Freeze } from "react-freeze";
import { UnlockView } from "../unlock";
import DiffViewer from "../diff-viewer";
import TableOfContents from "./table-of-contents";
import { showNoteLinkingDialog } from "../../common/dialog-controller";
import { scrollIntoViewById } from "@notesnook/editor";
import { IEditor } from "./types";
import { EditorActionBar } from "./action-bar";
import { logger } from "../../utils/logger";
import { PanelGroup, Panel, PanelResizeHandle } from "react-resizable-panels";
import { NoteLinkingDialog } from "../../dialogs/note-linking-dialog";
const PDFPreview = React.lazy(() => import("../pdf-preview"));
@@ -545,8 +545,8 @@ export function Editor(props: EditorProps) {
result.forEach((attachment) => editor?.attachFile(attachment));
}}
onInsertInternalLink={async (attributes) => {
const link = await showNoteLinkingDialog(attributes);
return link;
const link = await NoteLinkingDialog.show({ attributes });
return link || undefined;
}}
>
{headless ? null : (
@@ -763,13 +763,23 @@ function restoreScrollPosition(session: EditorSession) {
const scrollContainer = document.getElementById(`editorScroll_${session.id}`);
const scrollPosition = Config.get(`${session.id}:scroll-position`, 0);
if (scrollContainer) {
setTimeout(() => {
requestAnimationFrame(() => {
if (scrollContainer.scrollHeight < scrollPosition)
scrollContainer.style.minHeight = `${scrollPosition + 100}px`;
scrollContainer.scrollTop = scrollPosition;
if (scrollContainer.scrollHeight < scrollPosition) {
const observer = new ResizeObserver(() => {
if (scrollContainer.scrollHeight >= scrollPosition) {
observer.disconnect();
requestAnimationFrame(
() => (scrollContainer.scrollTop = scrollPosition)
);
clearTimeout(timeout);
}
});
});
observer.observe(scrollContainer);
// eslint-disable-next-line no-var
var timeout = setTimeout(() => {
observer.disconnect();
}, 30 * 1000);
} else
requestAnimationFrame(() => (scrollContainer.scrollTop = scrollPosition));
}
}

View File

@@ -20,22 +20,20 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import { SerializedKey } from "@notesnook/crypto/dist/src/types";
import { AppEventManager, AppEvents } from "../../common/app-events";
import { db } from "../../common/db";
import {
showBuyDialog,
showImagePickerDialog
} from "../../common/dialog-controller";
import { TaskManager } from "../../common/task-manager";
import { isUserPremium } from "../../hooks/use-is-user-premium";
import { showToast } from "../../utils/toast";
import { showFilePicker } from "../../utils/file-picker";
import { Attachment } from "@notesnook/editor";
import { ImagePickerDialog } from "../../dialogs/image-picker-dialog";
import { BuyDialog } from "../../dialogs/buy-dialog";
const FILE_SIZE_LIMIT = 500 * 1024 * 1024;
const IMAGE_SIZE_LIMIT = 50 * 1024 * 1024;
export async function insertAttachments(type = "*/*") {
if (!isUserPremium()) {
await showBuyDialog();
await BuyDialog.show({});
return;
}
@@ -49,14 +47,17 @@ export async function insertAttachments(type = "*/*") {
export async function attachFiles(files: File[]) {
if (!isUserPremium()) {
await showBuyDialog();
await BuyDialog.show({});
return;
}
const images =
(await showImagePickerDialog(
files.filter((f) => f.type.startsWith("image/"))
)) || [];
let images = files.filter((f) => f.type.startsWith("image/"));
images =
images.length > 0
? (await ImagePickerDialog.show({
images
})) || []
: [];
const documents = files.filter((f) => !f.type.startsWith("image/"));
const attachments: Attachment[] = [];
for (const file of [...images, ...documents]) {

View File

@@ -48,7 +48,6 @@ import {
import { IEditor, MAX_AUTO_SAVEABLE_WORDS } from "./types";
import { useEditorConfig, useToolbarConfig, useEditorManager } from "./manager";
import { useIsUserPremium } from "../../hooks/use-is-user-premium";
import { showBuyDialog } from "../../common/dialog-controller";
import { useStore as useSettingsStore } from "../../stores/setting-store";
import { debounce } from "@notesnook/common";
import { ScopedThemeProvider } from "../theme-provider";
@@ -62,6 +61,7 @@ import Skeleton from "react-loading-skeleton";
import useMobile from "../../hooks/use-mobile";
import useTablet from "../../hooks/use-tablet";
import { TimeFormat } from "@notesnook/core/dist/utils/date";
import { BuyDialog } from "../../dialogs/buy-dialog";
export type OnChangeHandler = (
content: () => string,
@@ -155,7 +155,7 @@ function TipTap(props: TipTapProps) {
premium: isUserPremium
},
onPermissionDenied: (claim) => {
if (claim === "premium") showBuyDialog();
if (claim === "premium") BuyDialog.show({});
}
});

View File

@@ -23,7 +23,7 @@ import { useEditorStore } from "../../stores/editor-store";
import { debounceWithId } from "@notesnook/common";
import useMobile from "../../hooks/use-mobile";
import useTablet from "../../hooks/use-tablet";
import { useEditorConfig } from "./manager";
import { useEditorConfig, useEditorManager } from "./manager";
import { getFontById } from "@notesnook/editor";
import { replaceDateTime } from "@notesnook/editor/dist/extensions/date-time";
import { useStore as useSettingsStore } from "../../stores/setting-store";
@@ -131,6 +131,13 @@ function TitleBox(props: TitleBoxProps) {
color: "placeholder"
}
}}
onKeyUp={(e) => {
if (e.key === "Enter") {
const context = useEditorManager.getState().getEditor(id);
if (!context) return;
context.editor?.focus({ scrollIntoView: true });
}
}}
onChange={(e) => {
pendingChanges.current = true;
e.target.value = replaceDateTime(

View File

@@ -27,6 +27,7 @@ import {
useErrorBoundary
} from "react-error-boundary";
import { useKeyStore } from "../../interfaces/key-store";
import { isFeatureSupported } from "../../utils/feature-check";
export function GlobalErrorHandler(props: PropsWithChildren) {
const { showBoundary } = useErrorBoundary();
@@ -199,11 +200,7 @@ function getErrorHelp(props: FallbackProps) {
action:
"This error can only be fixed by wiping & reseting the database. Beware that this will wipe all your data inside the database with no way to recover it later on. This WILL NOT change/affect/delete/wipe your data on the server but ONLY on this device.",
fix: async () => {
const { createDialect } = await import("../../common/sqlite");
await useKeyStore.getState().clear();
const dialect = createDialect("notesnook", true);
const driver = dialect.createDriver();
await driver.delete();
await resetDatabase();
resetErrorBoundary();
}
};
@@ -213,11 +210,7 @@ function getErrorHelp(props: FallbackProps) {
action:
"This error can only be fixed by wiping & reseting the Key Store and the database. This WILL NOT change/affect/delete/wipe your data on the server but ONLY on this device.",
fix: async () => {
const { createDialect } = await import("../../common/sqlite");
await useKeyStore.getState().clear();
const dialect = createDialect("notesnook", true);
const driver = dialect.createDriver();
await driver.delete();
await resetDatabase();
resetErrorBoundary();
}
};
@@ -242,3 +235,17 @@ function errorToString(error: unknown) {
? error
: JSON.stringify(error);
}
async function resetDatabase() {
const { createDialect } = await import("../../common/sqlite");
const multiTab = !!globalThis.SharedWorker && isFeatureSupported("opfs");
await useKeyStore.getState().clear();
const dialect = createDialect({
name: "notesnook",
encrypted: true,
async: !isFeatureSupported("opfs"),
multiTab
});
const driver = dialect.createDriver();
await driver.delete();
}

View File

@@ -213,7 +213,8 @@ import {
mdiFormatListBulleted,
mdiLink,
mdiWindowClose,
mdiFileMusicOutline
mdiFileMusicOutline,
mdiBroom
} from "@mdi/js";
import { useTheme } from "@emotion/react";
import { Theme } from "@notesnook/theme";
@@ -548,3 +549,4 @@ export const WindowRestore = createIcon(
"M8 16V4h12v12Zm2-2h8V6h-8Zm-6 6V8.525h2V18h9.475v2Zm6-6V6v8Z"
);
export const WindowClose = createIcon(mdiWindowClose);
export const ClearCache = createIcon(mdiBroom);

View File

@@ -43,7 +43,6 @@ import NavigationItem, { SortableNavigationItem } from "./navigation-item";
import { hardNavigate, hashNavigate, navigate } from "../../navigation";
import { db } from "../../common/db";
import useMobile from "../../hooks/use-mobile";
import { showRenameColorDialog } from "../../common/dialog-controller";
import { useStore as useAppStore } from "../../stores/app-store";
import { useStore as useUserStore } from "../../stores/user-store";
import { useStore as useThemeStore } from "../../stores/theme-store";
@@ -72,6 +71,7 @@ import { MenuItem } from "@notesnook/ui";
import { Notebook, Tag } from "@notesnook/core";
import { handleDrop } from "../../common/drop-handler";
import { Menu } from "../../hooks/use-menu";
import { RenameColorDialog } from "../../dialogs/item-dialog";
type Route = {
id: string;
@@ -368,7 +368,7 @@ function NavigationMenu(props: NavigationMenuProps) {
type: "button",
key: "rename-color",
title: "Rename color",
onClick: () => showRenameColorDialog(color)
onClick: () => RenameColorDialog.show(color)
},
{
type: "button",

View File

@@ -54,13 +54,6 @@ import {
} from "../icons";
import TimeAgo from "../time-ago";
import ListItem from "../list-item";
import {
confirm,
showAddReminderDialog,
showAddTagsDialog,
showCreateColorDialog,
showMoveNoteDialog
} from "../../common/dialog-controller";
import { store } from "../../stores/note-store";
import { store as userstore } from "../../stores/user-store";
import { useEditorStore } from "../../stores/editor-store";
@@ -97,12 +90,16 @@ import { SchemeColors } from "@notesnook/theme";
import { writeToClipboard } from "../../utils/clipboard";
import Vault from "../../common/vault";
import { isUserPremium } from "../../hooks/use-is-user-premium";
import { AddTagsDialog } from "../../dialogs/add-tags-dialog";
import { CreateColorDialog } from "../../dialogs/create-color-dialog";
import { ConfirmDialog } from "../../dialogs/confirm";
import { MoveNoteDialog } from "../../dialogs/move-note-dialog";
import { AddReminderDialog } from "../../dialogs/add-reminder-dialog";
type NoteProps = NoteResolvedData & {
item: NoteType;
context?: Context;
date: number;
simplified?: boolean;
compact?: boolean;
};
@@ -116,7 +113,6 @@ function Note(props: NoteProps) {
item,
date,
reminder,
simplified,
compact,
context
} = props;
@@ -130,7 +126,6 @@ function Note(props: NoteProps) {
draggable={true}
isFocused={isOpened}
isCompact={compact}
isSimple={simplified}
item={note}
title={note.title}
body={note.headline as string}
@@ -391,7 +386,7 @@ const menuItems: (
title: "Remind me",
icon: AddReminder.path,
onClick: async () => {
await showAddReminderDialog(note.id);
await AddReminderDialog.show({ note });
}
},
{ key: "sep1", type: "separator" },
@@ -541,7 +536,7 @@ const menuItems: (
onClick: async () => {
if (
note.localOnly ||
(await confirm({
(await ConfirmDialog.show({
title: `Prevent ${pluralize(ids.length, "note")} from syncing?`,
message: `${pluralize(
ids.length,
@@ -580,7 +575,7 @@ function colorsToMenuItems(
title: "Add new color",
icon: Plus.path,
onClick: async () => {
const id = await showCreateColorDialog();
const id = await CreateColorDialog.show({});
if (!id) return;
await store.get().setColor(id, noteColor?.id === id, ...ids);
}
@@ -620,7 +615,7 @@ function notebooksMenuItems(ids: string[]): MenuItem[] {
key: "link-notebooks",
title: "Link to...",
icon: AddToNotebook.path,
onClick: () => showMoveNoteDialog(ids)
onClick: () => MoveNoteDialog.show({ noteIds: ids })
},
{
type: "lazy-loader",
@@ -700,7 +695,7 @@ function tagsMenuItems(ids: string[]): MenuItem[] {
key: "assign-tags",
title: "Assign to...",
icon: Plus.path,
onClick: () => showAddTagsDialog(ids)
onClick: () => AddTagsDialog.show({ noteIds: ids })
},
{
type: "lazy-loader",
@@ -732,7 +727,6 @@ function tagsMenuItems(ids: string[]): MenuItem[] {
await db.relations.to({ id, type: "note" }, "tag").unlink();
}
tagStore.get().refresh();
await useEditorStore.getState().refreshTags();
await store.get().refresh();
}
},
@@ -753,7 +747,6 @@ function tagsMenuItems(ids: string[]): MenuItem[] {
await db.relations.add(tag, { id, type: "note" });
}
await tagStore.get().refresh();
await useEditorStore.getState().refreshTags();
await store.get().refresh();
}
});
@@ -774,7 +767,6 @@ function tagsMenuItems(ids: string[]): MenuItem[] {
await db.relations.unlink(tag, { id, type: "note" });
}
await tagStore.get().refresh();
await useEditorStore.getState().refreshTags();
await store.get().refresh();
}
});

View File

@@ -38,12 +38,12 @@ import { hashNavigate, navigate } from "../../navigation";
import IconTag from "../icon-tag";
import { Multiselect } from "../../common/multi-select";
import { pluralize } from "@notesnook/common";
import { confirm } from "../../common/dialog-controller";
import { getFormattedDate } from "@notesnook/common";
import { MenuItem } from "@notesnook/ui";
import { Notebook as NotebookType } from "@notesnook/core";
import { handleDrop } from "../../common/drop-handler";
import { useDragHandler } from "../../hooks/use-drag-handler";
import { ConfirmDialog } from "../../dialogs/confirm";
type NotebookProps = {
item: NotebookType;
@@ -202,7 +202,7 @@ export const notebookMenuItems: (
variant: "dangerous",
icon: Trash.path,
onClick: async () => {
const result = await confirm({
const result = await ConfirmDialog.show({
title: `Delete ${pluralize(ids.length, "notebook")}?`,
positiveButtonText: `Yes`,
negativeButtonText: "No",

View File

@@ -606,7 +606,7 @@ function Notebooks({ noteId }: { noteId: string }) {
renderItem={({ index }) => (
<ResolvedItem index={index} items={result.value} type="notebook">
{({ item, data }) => (
<ListItemWrapper item={item} data={data} simplified />
<ListItemWrapper item={item} data={data} compact />
)}
</ResolvedItem>
)}
@@ -635,7 +635,7 @@ function Reminders({ noteId }: { noteId: string }) {
renderItem={({ index }) => (
<ResolvedItem index={index} items={result.value} type="reminder">
{({ item, data }) => (
<ListItemWrapper item={item} data={data} simplified />
<ListItemWrapper item={item} data={data} compact />
)}
</ResolvedItem>
)}
@@ -659,6 +659,7 @@ function Attachments({ noteId }: { noteId: string }) {
estimatedSize={30}
getItemKey={(index) => result.value.key(index)}
items={result.value.placeholders}
style={{ tableLayout: "fixed", width: "100%" }}
header={
<tr>
<th style={{ width: "75%" }} />
@@ -666,7 +667,6 @@ function Attachments({ noteId }: { noteId: string }) {
<th style={{ width: "20%" }} />
</tr>
}
headerSize={0}
renderRow={({ index }) => (
<ResolvedItem index={index} type="attachment" items={result.value}>
{({ item }) => <ListItemWrapper item={item} compact />}

View File

@@ -37,14 +37,12 @@ import { hashNavigate } from "../../navigation";
import { Multiselect } from "../../common/multi-select";
import { store } from "../../stores/reminder-store";
import { db } from "../../common/db";
import {
confirm,
showEditReminderDialog
} from "../../common/dialog-controller";
import { pluralize } from "@notesnook/common";
import { getFormattedReminderTime } from "@notesnook/common";
import { MenuItem } from "@notesnook/ui";
import { Reminder as ReminderType } from "@notesnook/core/dist/types";
import { ConfirmDialog } from "../../dialogs/confirm";
import { EditReminderDialog } from "../../dialogs/add-reminder-dialog";
const RECURRING_MODE_MAP = {
week: "Weekly",
@@ -75,7 +73,7 @@ function Reminder(props: ReminderProps) {
body={reminder.description}
isDisabled={reminder.disabled}
isCompact={compact}
onClick={() => showEditReminderDialog(reminder.id)}
onClick={() => EditReminderDialog.show({ reminderId: reminder.id })}
footer={
<Flex
sx={{
@@ -145,7 +143,7 @@ const menuItems: (reminder: ReminderType, items?: string[]) => MenuItem[] = (
variant: "dangerous",
icon: Trash.path,
onClick: async () => {
confirm({
ConfirmDialog.show({
title: `Delete ${pluralize(items.length, "reminder")}`,
message: `Are you sure you want to proceed? **This action is IRREVERSIBLE**.`,
positiveButtonText: "Yes",

View File

@@ -117,7 +117,14 @@ function Header(props: RouteContainerProps) {
height: 42.8
}}
>
<Flex py={1} sx={{ alignItems: "center", justifyContent: "center" }}>
<Flex
py={1}
sx={{
alignItems: "center",
justifyContent: "center",
overflow: "hidden"
}}
>
{buttons?.back ? (
<ArrowLeft
size={24}

View File

@@ -34,15 +34,13 @@ import { useStore as useUserStore } from "../../stores/user-store";
import { useStore as useAppStore } from "../../stores/app-store";
import { hardNavigate, hashNavigate } from "../../navigation";
import { useAutoUpdater, UpdateStatus } from "../../hooks/use-auto-updater";
import {
showIssueDialog,
showUpdateAvailableNotice
} from "../../common/dialog-controller";
import useStatus, { statusToString } from "../../hooks/use-status";
import { ScopedThemeProvider } from "../theme-provider";
import { checkForUpdate, installUpdate } from "../../utils/updater";
import { getTimeAgo, toTitleCase } from "@notesnook/common";
import { User } from "@notesnook/core";
import { showUpdateAvailableNotice } from "../../dialogs/confirm";
import { IssueDialog } from "../../dialogs/issue-dialog";
function StatusBar() {
const user = useUserStore((state) => state.user);
@@ -112,21 +110,6 @@ function StatusBar() {
</Text>
</Button>
) : null}
<Button
variant="statusitem"
onClick={() => showIssueDialog()}
sx={{
alignItems: "center",
justifyContent: "center",
display: "flex"
}}
title="Facing an issue? Click here to create a bug report."
>
<Issue size={12} />
<Text variant="subBody" ml={1} sx={{ color: "paragraph" }}>
Report an issue
</Text>
</Button>
{statuses?.map((status) => {
const { key, icon: Icon } = status;
return (

View File

@@ -24,11 +24,11 @@ import { Notebook } from "@notesnook/core";
import { notebookMenuItems } from "../notebook";
import { ChevronDown, ChevronRight, Plus } from "../icons";
import { MenuItem } from "@notesnook/ui";
import { showAddNotebookDialog } from "../../common/dialog-controller";
import { navigate } from "../../navigation";
import { useCallback, useRef } from "react";
import { handleDrop } from "../../common/drop-handler";
import { useDragHandler } from "../../hooks/use-drag-handler";
import { AddNotebookDialog } from "../../dialogs/add-notebook-dialog";
type SubNotebookProps = {
item: Notebook;
@@ -173,7 +173,6 @@ const subNotebookMenuItems: (
context?: { refresh?: () => void }
) => MenuItem[] = (notebook, ids = [], context) => {
const menuItems = notebookMenuItems(notebook, ids);
console.log("ITEMS", context);
return [
{
type: "button",
@@ -181,7 +180,9 @@ const subNotebookMenuItems: (
title: "New notebook",
icon: Plus.path,
onClick: () =>
showAddNotebookDialog(notebook.id).then(() => context?.refresh?.())
AddNotebookDialog.show({ parentId: notebook.id }).then((res) =>
res ? context?.refresh?.() : null
)
},
{ type: "separator", key: "sepep2" },
...menuItems

View File

@@ -23,15 +23,14 @@ import { Text } from "@theme-ui/components";
import { store as appStore } from "../../stores/app-store";
import { store as tagStore } from "../../stores/tag-store";
import { store as noteStore } from "../../stores/note-store";
import { useEditorStore } from "../../stores/editor-store";
import { db } from "../../common/db";
import { Edit, Shortcut, DeleteForver } from "../icons";
import { showToast } from "../../utils/toast";
import { pluralize } from "@notesnook/common";
import { MenuItem } from "@notesnook/ui";
import { Tag as TagType } from "@notesnook/core";
import { showEditTagDialog } from "../../common/dialog-controller";
import { handleDrop } from "../../common/drop-handler";
import { EditTagDialog } from "../../dialogs/item-dialog";
type TagProps = { item: TagType; totalNotes: number };
function Tag(props: TagProps) {
@@ -78,9 +77,7 @@ const menuItems: (tag: TagType, ids?: string[]) => MenuItem[] = (
key: "edit",
title: "Rename tag",
icon: Edit.path,
onClick: () => {
showEditTagDialog(tag);
}
onClick: () => EditTagDialog.show(tag)
},
{
type: "button",
@@ -102,7 +99,6 @@ const menuItems: (tag: TagType, ids?: string[]) => MenuItem[] = (
await db.tags.remove(...ids);
showToast("success", `${pluralize(ids.length, "tag")} deleted`);
await appStore.refreshNavItems();
await useEditorStore.getState().refreshTags();
await tagStore.refresh();
await noteStore.refresh();
},

View File

@@ -18,11 +18,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { useCallback, useState } from "react";
import { showBuyDialog } from "../../common/dialog-controller";
import Tip from "../tip";
import { isUserPremium } from "../../hooks/use-is-user-premium";
import { Flex, Switch } from "@theme-ui/components";
import { Loading } from "../icons";
import { BuyDialog } from "../../dialogs/buy-dialog/buy-dialog";
function Toggle(props) {
const {
@@ -46,7 +46,7 @@ function Toggle(props) {
setIsLoading(false);
}
} else {
await showBuyDialog();
await BuyDialog.show({});
}
}, [onToggled, premium, isToggled]);

View File

@@ -18,7 +18,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import ListItem from "../list-item";
import { showMultiPermanentDeleteConfirmation } from "../../common/dialog-controller";
import { Restore, DeleteForver } from "../icons";
import { store } from "../../stores/trash-store";
import { Flex, Text } from "@theme-ui/components";
@@ -28,6 +27,7 @@ import { showToast } from "../../utils/toast";
import { MenuItem } from "@notesnook/ui";
import { TrashItem as TrashItemType } from "@notesnook/core/dist/types";
import { useEditorStore } from "../../stores/editor-store";
import { showMultiPermanentDeleteConfirmation } from "../../dialogs/confirm";
type TrashItemProps = { item: TrashItemType; date: number };
function TrashItem(props: TrashItemProps) {

View File

@@ -17,9 +17,10 @@ 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 { Virtualizer, useVirtualizer } from "@tanstack/react-virtual";
import { Box } from "@theme-ui/components";
import { Virtualizer } from "@tanstack/react-virtual";
import { Flex } from "@theme-ui/components";
import React, { useRef } from "react";
import { TableVirtuoso } from "react-virtuoso";
export type VirtualizedTableRowProps<T, C> = {
item: T;
@@ -36,12 +37,10 @@ type VirtualizedTableProps<T, C> = {
mode?: "fixed" | "dynamic";
items: T[];
estimatedSize: number;
headerSize: number;
getItemKey: (index: number) => string;
scrollElement?: Element | null;
scrollElement?: HTMLElement | null;
context?: C;
renderRow: (props: VirtualizedTableRowProps<T, C>) => JSX.Element | null;
scrollMargin?: number;
header: React.ReactNode;
style?: React.CSSProperties;
};
@@ -50,59 +49,95 @@ export function VirtualizedTable<T, C>(props: VirtualizedTableProps<T, C>) {
items,
getItemKey,
scrollElement,
scrollMargin,
headerSize,
renderRow: Row,
estimatedSize,
mode,
virtualizerRef,
header,
style,
context
context,
style
} = props;
const containerRef = useRef<HTMLDivElement>(null);
const virtualizer = useVirtualizer({
count: items.length,
estimateSize: () => estimatedSize,
getItemKey,
getScrollElement: () =>
scrollElement || containerRef.current?.closest(".ms-container") || null,
scrollMargin: scrollMargin || containerRef.current?.offsetTop || 0
});
if (virtualizerRef) virtualizerRef.current = virtualizer;
const virtualItems = virtualizer.getVirtualItems();
return (
<Box
<Flex
ref={containerRef}
sx={{
height: virtualizer.getTotalSize() + headerSize
}}
variant="columnFill"
sx={{ height: estimatedSize * items.length }}
>
<table style={style}>
<thead>{header}</thead>
<tbody>
{virtualItems.map((row, index) => (
<Row
key={row.key}
item={items[row.index]}
index={row.index}
rowRef={mode === "dynamic" ? virtualizer.measureElement : null}
context={context}
style={{
height: mode === "dynamic" ? "unset" : `${row.size}px`,
transform: `translateY(${
row.start -
index * row.size -
virtualizer.options.scrollMargin
}px)`
}}
/>
))}
</tbody>
</table>
</Box>
<TableVirtuoso
data={items}
context={context}
customScrollParent={
scrollElement ||
containerRef.current?.closest(".ms-container") ||
undefined
}
computeItemKey={(index) => getItemKey(index)}
defaultItemHeight={estimatedSize}
fixedHeaderContent={() => <>{header}</>}
fixedItemHeight={mode === "fixed" ? estimatedSize : undefined}
components={{
Table: (props) => (
<table {...props} style={{ ...style, ...props.style }} />
),
TableRow: (props) => {
return (
<Row
index={props["data-item-index"]}
item={props.item}
style={props.style || {}}
context={props.context}
/>
);
}
}}
/>
</Flex>
);
//
// const virtualizer = useVirtualizer({
// count: items.length,
// estimateSize: () => estimatedSize,
// getItemKey,
// getScrollElement: () =>
// scrollElement || containerRef.current?.closest(".ms-container") || null,
// scrollMargin: scrollMargin || containerRef.current?.offsetTop || 0
// });
// if (virtualizerRef) virtualizerRef.current = virtualizer;
// const virtualItems = virtualizer.getVirtualItems();
// return (
// <Box
// ref={containerRef}
// sx={{
// height: virtualizer.getTotalSize() + headerSize
// }}
// >
// <table style={style}>
// <thead>{header}</thead>
// <tbody>
// {virtualItems.map((row, index) => (
// <Row
// key={row.key}
// item={items[row.index]}
// index={row.index}
// rowRef={mode === "dynamic" ? virtualizer.measureElement : null}
// context={context}
// style={{
// height: mode === "dynamic" ? "unset" : `${row.size}px`,
// transform: `translateY(${
// row.start -
// index * row.size -
// virtualizer.options.scrollMargin
// }px)`
// }}
// />
// ))}
// </tbody>
// </table>
// </Box>
// );
}

View File

@@ -22,96 +22,104 @@ import Dialog from "../components/dialog";
import Field from "../components/field";
import { showToast } from "../utils/toast";
import { Notebook } from "@notesnook/core";
import { Perform } from "../common/dialog-controller";
import { store as noteStore } from "../stores/note-store";
import { store as notebookStore } from "../stores/notebook-store";
import { store as appStore } from "../stores/app-store";
import { db } from "../common/db";
import { BaseDialogProps, DialogManager } from "../common/dialog-manager";
type AddNotebookDialogProps = {
type AddNotebookDialogProps = BaseDialogProps<boolean> & {
parentId?: string;
edit?: boolean;
notebook?: Notebook;
onClose: Perform;
};
function AddNotebookDialog(props: AddNotebookDialogProps) {
const { notebook, onClose, parentId } = props;
const title = useRef<string>(notebook?.title || "");
const description = useRef<string>(notebook?.description || "");
export const AddNotebookDialog = DialogManager.register(
function AddNotebookDialog(props: AddNotebookDialogProps) {
const { notebook, onClose, parentId } = props;
const title = useRef<string>(notebook?.title || "");
const description = useRef<string>(notebook?.description || "");
const onSubmit = useCallback(async () => {
if (!title.current.trim())
return showToast("error", "Notebook title cannot be empty.");
const onSubmit = useCallback(async () => {
if (!title.current.trim())
return showToast("error", "Notebook title cannot be empty.");
const id = await db.notebooks.add({
id: props.notebook?.id,
title: title.current,
description: description.current
});
if (parentId) {
await db.relations.add(
{ type: "notebook", id: parentId },
{ type: "notebook", id }
);
}
await notebookStore.refresh();
await noteStore.refresh();
await appStore.refreshNavItems();
showToast(
"success",
props.edit
? "Notebook edited successfully!"
: "Notebook created successfully"
);
onClose(true);
}, [props.notebook?.id, props.edit, onClose, parentId]);
return (
<Dialog
testId="add-notebook-dialog"
isOpen={true}
title={props.edit ? "Edit Notebook" : "Create a Notebook"}
description={
props.edit
? `You are editing "${notebook?.title}".`
: "Notebooks are the best way to organize your notes."
const id = await db.notebooks.add({
id: props.notebook?.id,
title: title.current,
description: description.current
});
if (parentId) {
await db.relations.add(
{ type: "notebook", id: parentId },
{ type: "notebook", id }
);
}
onClose={() => onClose(false)}
positiveButton={{
text: props.edit ? "Save" : "Create",
onClick: onSubmit
}}
negativeButton={{ text: "Cancel", onClick: () => onClose(false) }}
>
<Field
defaultValue={title.current}
data-test-id="title-input"
autoFocus
required
label="Title"
name="title"
id="title"
onChange={(e) => (title.current = e.target.value)}
onKeyUp={async (e) => {
if (e.key === "Enter") {
await onSubmit();
}
}}
/>
<Field
data-test-id="description-input"
label="Description"
name="description"
id="description"
onChange={(e) => (description.current = e.target.value)}
defaultValue={description.current}
helpText="Optional"
sx={{ mt: 1 }}
/>
</Dialog>
);
}
export default AddNotebookDialog;
await notebookStore.refresh();
await noteStore.refresh();
await appStore.refreshNavItems();
showToast(
"success",
props.edit
? "Notebook edited successfully!"
: "Notebook created successfully"
);
onClose(true);
}, [props.notebook?.id, props.edit, onClose, parentId]);
return (
<Dialog
testId="add-notebook-dialog"
isOpen={true}
title={props.edit ? "Edit Notebook" : "Create a Notebook"}
description={
props.edit
? `You are editing "${notebook?.title}".`
: "Notebooks are the best way to organize your notes."
}
onClose={() => onClose(false)}
positiveButton={{
text: props.edit ? "Save" : "Create",
onClick: onSubmit
}}
negativeButton={{ text: "Cancel", onClick: () => onClose(false) }}
>
<Field
defaultValue={title.current}
data-test-id="title-input"
autoFocus
required
label="Title"
name="title"
id="title"
onChange={(e) => (title.current = e.target.value)}
onKeyUp={async (e) => {
if (e.key === "Enter") {
await onSubmit();
}
}}
/>
<Field
data-test-id="description-input"
label="Description"
name="description"
id="description"
onChange={(e) => (description.current = e.target.value)}
defaultValue={description.current}
helpText="Optional"
sx={{ mt: 1 }}
/>
</Dialog>
);
}
);
type EditNotebookDialogProps = { notebookId: string };
export const EditNotebookDialog = {
show: async (props: EditNotebookDialogProps) => {
const notebook = await db.notebooks.notebook(props.notebookId);
if (!notebook) return;
return AddNotebookDialog.show({ edit: true, notebook });
}
};

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 { Perform } from "../common/dialog-controller";
import Dialog from "../components/dialog";
import Field from "../components/field";
import { Box, Button, Flex, Label, Radio, Text } from "@theme-ui/components";
@@ -37,11 +36,11 @@ import { useStore as useThemeStore } from "../stores/theme-store";
import { getFormattedDate } from "@notesnook/common";
import { MONTHS_FULL, getTimeFormat } from "@notesnook/core/dist/utils/date";
import { Note, Reminder } from "@notesnook/core";
import { BaseDialogProps, DialogManager } from "../common/dialog-manager";
dayjs.extend(customParseFormat);
export type AddReminderDialogProps = {
onClose: Perform;
export type AddReminderDialogProps = BaseDialogProps<boolean> & {
reminder?: Reminder;
note?: Note;
};
@@ -116,419 +115,425 @@ const recurringModes = [
}
];
export default function AddReminderDialog(props: AddReminderDialogProps) {
const { reminder, note } = props;
export const AddReminderDialog = DialogManager.register(
function AddReminderDialog(props: AddReminderDialogProps) {
const { reminder, note } = props;
const [selectedDays, setSelectedDays] = useState<number[]>(
reminder?.selectedDays ?? []
);
const [recurringMode, setRecurringMode] = useState<
ValueOf<typeof RecurringModes>
>(reminder?.recurringMode ?? RecurringModes.DAY);
const [mode, setMode] = useState<ValueOf<typeof Modes>>(
reminder?.mode ?? Modes.ONCE
);
const [priority, setPriority] = usePersistentState<
ValueOf<typeof Priorities>
>("reminders:default_priority", reminder?.priority ?? Priorities.VIBRATE);
const [date, setDate] = useState(dayjs(reminder?.date));
const [title, setTitle] = useState<string>(
note?.title ?? reminder?.title ?? ""
);
const [description, setDescription] = useState<string>(
note?.headline ?? reminder?.description ?? ""
);
const [showCalendar, setShowCalendar] = useState(false);
const refresh = useStore((state) => state.refresh);
const isUserPremium = useIsUserPremium();
const theme = useThemeStore((store) => store.colorScheme);
const dateInputRef = useRef<HTMLInputElement>(null);
const [selectedDays, setSelectedDays] = useState<number[]>(
reminder?.selectedDays ?? []
);
const [recurringMode, setRecurringMode] = useState<
ValueOf<typeof RecurringModes>
>(reminder?.recurringMode ?? RecurringModes.DAY);
const [mode, setMode] = useState<ValueOf<typeof Modes>>(
reminder?.mode ?? Modes.ONCE
);
const [priority, setPriority] = usePersistentState<
ValueOf<typeof Priorities>
>("reminders:default_priority", reminder?.priority ?? Priorities.VIBRATE);
const [date, setDate] = useState(dayjs(reminder?.date));
const [title, setTitle] = useState<string>(
note?.title ?? reminder?.title ?? ""
);
const [description, setDescription] = useState<string>(
note?.headline ?? reminder?.description ?? ""
);
const [showCalendar, setShowCalendar] = useState(false);
const refresh = useStore((state) => state.refresh);
const isUserPremium = useIsUserPremium();
const theme = useThemeStore((store) => store.colorScheme);
const dateInputRef = useRef<HTMLInputElement>(null);
const repeatsDaily =
(selectedDays.length === 7 && recurringMode === RecurringModes.WEEK) ||
(selectedDays.length === 31 && recurringMode === RecurringModes.MONTH) ||
recurringMode === RecurringModes.DAY;
const repeatsDaily =
(selectedDays.length === 7 && recurringMode === RecurringModes.WEEK) ||
(selectedDays.length === 31 && recurringMode === RecurringModes.MONTH) ||
recurringMode === RecurringModes.DAY;
return (
<Dialog
isOpen={true}
title={reminder ? "Edit reminder" : "Add a reminder"}
testId="add-reminder-dialog"
onClose={() => props.onClose(false)}
sx={{ fontFamily: "body" }}
positiveButton={{
text: reminder ? "Save" : "Add",
disabled:
!title ||
(mode !== Modes.ONCE &&
recurringMode !== RecurringModes.DAY &&
recurringMode !== RecurringModes.YEAR &&
!selectedDays.length),
onClick: async () => {
if (!("Notification" in window))
showToast(
"warn",
"Reminders will not be active on this device as it does not support notifications."
);
return (
<Dialog
isOpen={true}
title={reminder ? "Edit reminder" : "Add a reminder"}
testId="add-reminder-dialog"
onClose={() => props.onClose(false)}
sx={{ fontFamily: "body" }}
positiveButton={{
text: reminder ? "Save" : "Add",
disabled:
!title ||
(mode !== Modes.ONCE &&
recurringMode !== RecurringModes.DAY &&
recurringMode !== RecurringModes.YEAR &&
!selectedDays.length),
onClick: async () => {
if (!("Notification" in window))
showToast(
"warn",
"Reminders will not be active on this device as it does not support notifications."
);
const permissionResult = await Notification.requestPermission();
if (!IS_TESTING && permissionResult !== "granted") {
showToast(
"error",
"Please grant notifications permission to add new reminders."
);
return;
}
const permissionResult = await Notification.requestPermission();
if (!IS_TESTING && permissionResult !== "granted") {
showToast(
"error",
"Please grant notifications permission to add new reminders."
);
return;
}
if (mode !== Modes.REPEAT && date.isBefore(dayjs())) {
showToast(
"error",
"Reminder time cannot be earlier than the current time."
);
return;
}
if (mode !== Modes.REPEAT && date.isBefore(dayjs())) {
showToast(
"error",
"Reminder time cannot be earlier than the current time."
);
return;
}
const id = await db.reminders.add({
id: reminder?.id,
recurringMode,
mode,
priority,
selectedDays,
date: date.valueOf(),
title,
description,
disabled: false,
...(date.isAfter(dayjs()) ? { snoozeUntil: 0 } : {})
});
const id = await db.reminders.add({
id: reminder?.id,
recurringMode,
mode,
priority,
selectedDays,
date: date.valueOf(),
title,
description,
disabled: false,
...(date.isAfter(dayjs()) ? { snoozeUntil: 0 } : {})
});
if (id && note) {
await db.relations.add(note, { id, type: "reminder" });
}
if (id && note) {
await db.relations.add(note, { id, type: "reminder" });
}
refresh();
props.onClose(true);
}
}}
negativeButton={{ text: "Cancel", onClick: () => props.onClose(false) }}
>
<Field
id="title"
label="Title"
required
value={title}
data-test-id="title-input"
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
setTitle(e.target.value)
}
/>
<Field
as="textarea"
id="description"
label="Description"
data-test-id="description-input"
helpText="Optional"
value={description}
styles={{
input: {
height: 100
refresh();
props.onClose(true);
}
}}
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
setDescription(e.target.value)
}
/>
<Flex sx={{ gap: 2, mt: 2 }}>
{modes.map((m) => (
<Label
key={m.id}
variant="text.body"
data-test-id={`mode-${m.id}`}
sx={{
width: "auto",
justifyContent: "center",
alignItems: "center"
}}
>
<Radio
id="mode"
name="mode"
defaultChecked={m.id === Modes.ONCE}
checked={m.id === mode}
disabled={m.premium && !isUserPremium}
sx={{ color: m.id === mode ? "accent" : "icon" }}
onChange={() => {
if (m.premium && !isUserPremium) return;
setMode(m.id);
setRecurringMode(RecurringModes.DAY);
setSelectedDays([]);
}}
/>
{m.title}
{m.premium && !isUserPremium && (
<Pro size={18} color="accent" sx={{ ml: 1 }} />
)}
</Label>
))}
</Flex>
{mode === Modes.REPEAT ? (
<Flex
sx={{
mt: 2,
bg: "var(--background-secondary)",
borderRadius: "default",
p: 1,
flexDirection: "column"
negativeButton={{ text: "Cancel", onClick: () => props.onClose(false) }}
>
<Field
id="title"
label="Title"
required
value={title}
data-test-id="title-input"
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
setTitle(e.target.value)
}
/>
<Field
as="textarea"
id="description"
label="Description"
data-test-id="description-input"
helpText="Optional"
value={description}
styles={{
input: {
height: 100
}
}}
>
<Flex sx={{ alignItems: "center", gap: 1 }}>
{recurringModes.map((mode) => (
<Button
key={mode.id}
variant="secondary"
data-test-id={`recurring-mode-${mode.id}`}
onClick={() => {
setRecurringMode(mode.id);
setSelectedDays([]);
}}
sx={{
borderRadius: 100,
py: 1,
px: 2,
flexShrink: 0,
bg:
mode.id === recurringMode
? "background-selected"
: "transparent",
color:
mode.id === recurringMode
? "paragraph-selected"
: "paragraph"
}}
>
{mode.title}
</Button>
))}
</Flex>
{recurringModes.map((mode) =>
mode.id === recurringMode ? (
<Box
key={mode.id}
sx={{
display: "grid",
gridTemplateColumns:
mode.id === RecurringModes.WEEK
? "1fr 1fr 1fr 1fr 1fr 1fr 1fr"
: "1fr 1fr 1fr 1fr 1fr 1fr 1fr",
mt: mode.options.length > 0 ? 1 : 0,
maxHeight: 150,
overflowY: "auto",
gap: 1
}}
>
{mode.options.map((day, i) => (
<Button
key={day}
variant="secondary"
data-test-id={`day-${day}`}
onClick={() => {
setSelectedDays((days) => {
const clone = days.slice();
if (clone.indexOf(day) > -1)
clone.splice(clone.indexOf(day), 1);
else clone.push(day);
return clone;
});
}}
sx={{
borderRadius: "default",
py: 1,
px: 2,
flexShrink: 0,
textAlign: "left",
bg: selectedDays.includes(day)
? "background-selected"
: "transparent",
color: selectedDays.includes(day)
? "paragraph-selected"
: "paragraph"
}}
>
{mode.id === "week" ? WEEK_DAYS[i] : day}
</Button>
))}
</Box>
) : null
)}
</Flex>
) : null}
<Flex sx={{ gap: 2, overflowX: "auto", mt: 2 }}>
{mode === Modes.ONCE ? (
<>
<Field
id="date"
label="Date"
required
inputRef={dateInputRef}
data-test-id="date-input"
helpText={`${db.settings.getDateFormat()}`}
action={{
icon: Calendar,
onClick() {
setShowCalendar(true);
}
}}
validate={(t) =>
dayjs(t, db.settings.getDateFormat(), true).isValid()
}
defaultValue={date.format(db.settings.getDateFormat())}
onChange={(e) => setDate((d) => setDateOnly(e.target.value, d))}
/>
<PopupPresenter
isOpen={showCalendar}
onClose={() => setShowCalendar(false)}
position={{
isTargetAbsolute: true,
target: dateInputRef.current,
location: "top"
}}
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
setDescription(e.target.value)
}
/>
<Flex sx={{ gap: 2, mt: 2 }}>
{modes.map((m) => (
<Label
key={m.id}
variant="text.body"
data-test-id={`mode-${m.id}`}
sx={{
".rdp": {
bg: "background",
p: 1,
boxShadow: `0px 0px 25px 5px ${
theme === "dark" ? "#000000aa" : "#0000004e"
}`,
borderRadius: "dialog",
fontFamily: "body",
"--rdp-accent-color": "var(--accent)",
"--rdp-background-color": "var(--background)",
"--rdp-background-color-dark": "var(--background)",
"--rdp-selected-color": "var(--paragraph-selected)",
color: "paragraph"
},
".rdp-caption_label": { fontWeight: "heading" }
width: "auto",
justifyContent: "center",
alignItems: "center"
}}
>
<DayPicker
mode="single"
captionLayout="dropdown-buttons"
fromYear={new Date().getFullYear()}
toYear={new Date().getFullYear() + 99}
modifiers={{
disabled: { before: new Date() }
}}
selected={dayjs(date).toDate()}
onSelect={(day) => {
if (!day) return;
const date = getFormattedDate(day, "date");
setDate((d) => setDateOnly(date, d));
if (dateInputRef.current) dateInputRef.current.value = date;
}}
styles={{
day: {
fontFamily: "inherit",
fontSize: 14
}
<Radio
id="mode"
name="mode"
defaultChecked={m.id === Modes.ONCE}
checked={m.id === mode}
disabled={m.premium && !isUserPremium}
sx={{ color: m.id === mode ? "accent" : "icon" }}
onChange={() => {
if (m.premium && !isUserPremium) return;
setMode(m.id);
setRecurringMode(RecurringModes.DAY);
setSelectedDays([]);
}}
/>
</PopupPresenter>
</>
) : recurringMode === RecurringModes.YEAR ? (
<>
<LabeledSelect
id="month"
label="Month"
value={`${dayjs(date).month()}`}
options={MONTHS_FULL.map((month, index) => ({
value: `${index}`,
title: month
}))}
onSelectionChanged={(month) => {
setDate((d) => d.month(parseInt(month)));
}}
/>
<LabeledSelect
id="day"
label="Day"
value={`${dayjs(date).date()}`}
options={new Array(dayjs(date).daysInMonth())
.fill("0")
.map((_, day) => ({
value: `${day + 1}`,
title: `${day + 1}`
}))}
onSelectionChanged={(day) => {
setDate((d) => d.date(parseInt(day)));
}}
/>
</>
) : null}
<Field
id="time"
label="Time"
required
data-test-id="time-input"
helpText={`${
db.settings.getTimeFormat() === "12-hour" ? "hh:mm AM/PM" : "hh:mm"
}`}
validate={(t) => {
const format =
db.settings.getTimeFormat() === "12-hour" ? "hh:mm a" : "HH:mm";
return dayjs(t.toLowerCase(), format, true).isValid();
}}
defaultValue={date.format(getTimeFormat(db.settings.getTimeFormat()))}
onChange={(e) => setDate((d) => setTimeOnly(e.target.value, d))}
/>
</Flex>
<Flex sx={{ gap: 2, mt: 2 }}>
{priorities.map((p) => (
<Label
key={p.id}
variant="text.body"
data-test-id={`priority-${p.id}`}
{m.title}
{m.premium && !isUserPremium && (
<Pro size={18} color="accent" sx={{ ml: 1 }} />
)}
</Label>
))}
</Flex>
{mode === Modes.REPEAT ? (
<Flex
sx={{
width: "auto",
justifyContent: "center",
alignItems: "center"
mt: 2,
bg: "var(--background-secondary)",
borderRadius: "default",
p: 1,
flexDirection: "column"
}}
>
<Radio
id="priority"
name="priority"
sx={{ color: p.id === priority ? "accent" : "icon" }}
defaultChecked={p.id === Priorities.VIBRATE}
checked={p.id === priority}
onChange={() => setPriority(p.id)}
/>
{p.title}
</Label>
))}
</Flex>
<Flex sx={{ alignItems: "center", gap: 1 }}>
{recurringModes.map((mode) => (
<Button
key={mode.id}
variant="secondary"
data-test-id={`recurring-mode-${mode.id}`}
onClick={() => {
setRecurringMode(mode.id);
setSelectedDays([]);
}}
sx={{
borderRadius: 100,
py: 1,
px: 2,
flexShrink: 0,
bg:
mode.id === recurringMode
? "background-selected"
: "transparent",
color:
mode.id === recurringMode
? "paragraph-selected"
: "paragraph"
}}
>
{mode.title}
</Button>
))}
</Flex>
{recurringModes.map((mode) =>
mode.id === recurringMode ? (
<Box
key={mode.id}
sx={{
display: "grid",
gridTemplateColumns:
mode.id === RecurringModes.WEEK
? "1fr 1fr 1fr 1fr 1fr 1fr 1fr"
: "1fr 1fr 1fr 1fr 1fr 1fr 1fr",
mt: mode.options.length > 0 ? 1 : 0,
maxHeight: 150,
overflowY: "auto",
gap: 1
}}
>
{mode.options.map((day, i) => (
<Button
key={day}
variant="secondary"
data-test-id={`day-${day}`}
onClick={() => {
setSelectedDays((days) => {
const clone = days.slice();
if (clone.indexOf(day) > -1)
clone.splice(clone.indexOf(day), 1);
else clone.push(day);
return clone;
});
}}
sx={{
borderRadius: "default",
py: 1,
px: 2,
flexShrink: 0,
textAlign: "left",
bg: selectedDays.includes(day)
? "background-selected"
: "transparent",
color: selectedDays.includes(day)
? "paragraph-selected"
: "paragraph"
}}
>
{mode.id === "week" ? WEEK_DAYS[i] : day}
</Button>
))}
</Box>
) : null
)}
</Flex>
) : null}
{mode === Modes.REPEAT ? (
<Text variant="subBody" sx={{ mt: 1 }}>
{selectedDays.length === 0 && recurringMode !== RecurringModes.DAY
? recurringMode === RecurringModes.WEEK
? "Select day of the week to repeat the reminder."
: "Select nth day(s) of the month to repeat the reminder."
: repeatsDaily
? `Repeats daily at ${date.format(timeFormat())}.`
: `Repeats every ${recurringMode} on ${getSelectedDaysText(
selectedDays,
recurringMode
)} at ${date.format(timeFormat())}.`}
</Text>
) : (
<Text variant="subBody" sx={{ mt: 1 }}>
{`The reminder will start on ${date} at ${date.format(
timeFormat()
)}.`}
</Text>
)}
</Dialog>
);
}
<Flex sx={{ gap: 2, overflowX: "auto", mt: 2 }}>
{mode === Modes.ONCE ? (
<>
<Field
id="date"
label="Date"
required
inputRef={dateInputRef}
data-test-id="date-input"
helpText={`${db.settings.getDateFormat()}`}
action={{
icon: Calendar,
onClick() {
setShowCalendar(true);
}
}}
validate={(t) =>
dayjs(t, db.settings.getDateFormat(), true).isValid()
}
defaultValue={date.format(db.settings.getDateFormat())}
onChange={(e) => setDate((d) => setDateOnly(e.target.value, d))}
/>
<PopupPresenter
isOpen={showCalendar}
onClose={() => setShowCalendar(false)}
position={{
isTargetAbsolute: true,
target: dateInputRef.current,
location: "top"
}}
sx={{
".rdp": {
bg: "background",
p: 1,
boxShadow: `0px 0px 25px 5px ${
theme === "dark" ? "#000000aa" : "#0000004e"
}`,
borderRadius: "dialog",
fontFamily: "body",
"--rdp-accent-color": "var(--accent)",
"--rdp-background-color": "var(--background)",
"--rdp-background-color-dark": "var(--background)",
"--rdp-selected-color": "var(--paragraph-selected)",
color: "paragraph"
},
".rdp-caption_label": { fontWeight: "heading" }
}}
>
<DayPicker
mode="single"
captionLayout="dropdown-buttons"
fromYear={new Date().getFullYear()}
toYear={new Date().getFullYear() + 99}
modifiers={{
disabled: { before: new Date() }
}}
selected={dayjs(date).toDate()}
onSelect={(day) => {
if (!day) return;
const date = getFormattedDate(day, "date");
setDate((d) => setDateOnly(date, d));
if (dateInputRef.current) dateInputRef.current.value = date;
}}
styles={{
day: {
fontFamily: "inherit",
fontSize: 14
}
}}
/>
</PopupPresenter>
</>
) : recurringMode === RecurringModes.YEAR ? (
<>
<LabeledSelect
id="month"
label="Month"
value={`${dayjs(date).month()}`}
options={MONTHS_FULL.map((month, index) => ({
value: `${index}`,
title: month
}))}
onSelectionChanged={(month) => {
setDate((d) => d.month(parseInt(month)));
}}
/>
<LabeledSelect
id="day"
label="Day"
value={`${dayjs(date).date()}`}
options={new Array(dayjs(date).daysInMonth())
.fill("0")
.map((_, day) => ({
value: `${day + 1}`,
title: `${day + 1}`
}))}
onSelectionChanged={(day) => {
setDate((d) => d.date(parseInt(day)));
}}
/>
</>
) : null}
<Field
id="time"
label="Time"
required
data-test-id="time-input"
helpText={`${
db.settings.getTimeFormat() === "12-hour"
? "hh:mm AM/PM"
: "hh:mm"
}`}
validate={(t) => {
const format =
db.settings.getTimeFormat() === "12-hour" ? "hh:mm a" : "HH:mm";
return dayjs(t.toLowerCase(), format, true).isValid();
}}
defaultValue={date.format(
getTimeFormat(db.settings.getTimeFormat())
)}
onChange={(e) => setDate((d) => setTimeOnly(e.target.value, d))}
/>
</Flex>
<Flex sx={{ gap: 2, mt: 2 }}>
{priorities.map((p) => (
<Label
key={p.id}
variant="text.body"
data-test-id={`priority-${p.id}`}
sx={{
width: "auto",
justifyContent: "center",
alignItems: "center"
}}
>
<Radio
id="priority"
name="priority"
sx={{ color: p.id === priority ? "accent" : "icon" }}
defaultChecked={p.id === Priorities.VIBRATE}
checked={p.id === priority}
onChange={() => setPriority(p.id)}
/>
{p.title}
</Label>
))}
</Flex>
{mode === Modes.REPEAT ? (
<Text variant="subBody" sx={{ mt: 1 }}>
{selectedDays.length === 0 && recurringMode !== RecurringModes.DAY
? recurringMode === RecurringModes.WEEK
? "Select day of the week to repeat the reminder."
: "Select nth day(s) of the month to repeat the reminder."
: repeatsDaily
? `Repeats daily at ${date.format(timeFormat())}.`
: `Repeats every ${recurringMode} on ${getSelectedDaysText(
selectedDays,
recurringMode
)} at ${date.format(timeFormat())}.`}
</Text>
) : (
<Text variant="subBody" sx={{ mt: 1 }}>
{`The reminder will start on ${date} at ${date.format(
timeFormat()
)}.`}
</Text>
)}
</Dialog>
);
}
);
function setTimeOnly(str: string, date: dayjs.Dayjs) {
const value = dayjs(str, timeFormat(), true);
@@ -619,3 +624,12 @@ function LabeledSelect(props: LabeledSelectProps) {
</Label>
);
}
type EditReminderDialogProps = { reminderId: string };
export const EditReminderDialog = {
show: async (props: EditReminderDialogProps) => {
const reminder = await db.reminders.reminder(props.reminderId);
if (!reminder) return;
return AddReminderDialog.show({ reminder });
}
};

View File

@@ -29,12 +29,12 @@ import Dialog from "../components/dialog";
import { useStore, store } from "../stores/tag-store";
import { store as notestore } from "../stores/note-store";
import { useEditorStore } from "../stores/editor-store";
import { Perform } from "../common/dialog-controller";
import { FilteredList } from "../components/filtered-list";
import { ItemReference, Tag } from "@notesnook/core/dist/types";
import { create } from "zustand";
import { VirtualizedGrouping } from "@notesnook/core";
import { ResolvedItem } from "@notesnook/common";
import { BaseDialogProps, DialogManager } from "../common/dialog-manager";
type SelectedReference = {
id: string;
@@ -51,12 +51,10 @@ export const useSelectionStore = create<ISelectionStore>((set) => ({
setSelected: (selected) => set({ selected: selected.slice() })
}));
export type AddTagsDialogProps = {
onClose: Perform;
noteIds: string[];
};
function AddTagsDialog(props: AddTagsDialogProps) {
type AddTagsDialogProps = BaseDialogProps<boolean> & { noteIds: string[] };
export const AddTagsDialog = DialogManager.register(function AddTagsDialog(
props: AddTagsDialogProps
) {
const { onClose, noteIds } = props;
const [tags, setTags] = useState<VirtualizedGrouping<Tag> | undefined>(
@@ -101,7 +99,6 @@ function AddTagsDialog(props: AddTagsDialogProps) {
else await db.relations.unlink(tagRef, noteRef);
}
}
await useEditorStore.getState().refreshTags();
await store.get().refresh();
await notestore.get().refresh();
onClose(true);
@@ -150,7 +147,7 @@ function AddTagsDialog(props: AddTagsDialogProps) {
)}
</Dialog>
);
}
});
function TagItem(props: { tag: Tag }) {
const { tag } = props;
@@ -201,8 +198,6 @@ function TagItem(props: { tag: Tag }) {
);
}
export default AddTagsDialog;
function SelectedCheck({ id, size = 20 }: { id: string; size?: number }) {
const selected = useSelectionStore((store) => store.selected);
const selectedTag = selected.find((item) => item.id === id);

View File

@@ -22,31 +22,36 @@ import AnnouncementBody from "../components/announcements/body";
import { store as announcementStore } from "../stores/announcement-store";
import { useCallback } from "react";
import BaseDialog from "../components/dialog";
import { BaseDialogProps, DialogManager } from "../common/dialog-manager";
function AnnouncementDialog(props) {
const { announcement, onClose } = props;
type AnnouncementDialogProps = BaseDialogProps<boolean> & {
announcement: any;
};
export const AnnouncementDialog = DialogManager.register(
function AnnouncementDialog(props: AnnouncementDialogProps) {
const { announcement, onClose } = props;
const dismiss = useCallback(() => {
announcementStore.get().dismiss(announcement.id);
onClose(true);
}, [announcement, onClose]);
const dismiss = useCallback(() => {
announcementStore.get().dismiss(announcement.id);
onClose(true);
}, [announcement, onClose]);
return (
<BaseDialog isOpen onClose={props.onClose} width={"30%"}>
<Flex
bg="background"
sx={{
position: "relative",
flexDirection: "column"
}}
>
<AnnouncementBody
dismiss={dismiss}
components={announcement.body}
type="dialog"
/>
</Flex>
</BaseDialog>
);
}
export default AnnouncementDialog;
return (
<BaseDialog isOpen onClose={() => onClose(false)} width={"30%"}>
<Flex
bg="background"
sx={{
position: "relative",
flexDirection: "column"
}}
>
<AnnouncementBody
dismiss={dismiss}
components={announcement.body}
type="dialog"
/>
</Flex>
</BaseDialog>
);
}
);

View File

@@ -17,7 +17,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { useEffect, useState, memo, useRef } from "react";
import { useEffect, useState, memo, useRef, startTransition } from "react";
import {
Box,
Button,
@@ -29,11 +29,12 @@ import {
Text
} from "@theme-ui/components";
import { store, useStore } from "../stores/attachment-store";
import { ResolvedItem, formatBytes, usePromise } from "@notesnook/common";
import { formatBytes, usePromise, useResolvedItem } from "@notesnook/common";
import Dialog from "../components/dialog";
import {
ChevronDown,
ChevronUp,
ClearCache,
Close,
DoubleCheckmark,
Download,
@@ -50,7 +51,6 @@ import {
import NavigationItem from "../components/navigation-menu/navigation-item";
import { pluralize } from "@notesnook/common";
import { db } from "../common/db";
import { Perform } from "../common/dialog-controller";
import { Attachment } from "../components/attachment";
import { ScopedThemeProvider } from "../components/theme-provider";
import {
@@ -63,6 +63,10 @@ import {
VirtualizedTableRowProps
} from "../components/virtualized-table";
import { FlexScrollContainer } from "../components/scroll-container";
import { BaseDialogProps, DialogManager } from "../common/dialog-manager";
import { ConfirmDialog } from "./confirm";
import { showToast } from "../utils/toast";
import { Loader } from "../components/loader";
type ToolbarAction = {
title: string;
@@ -101,122 +105,114 @@ type SortOptions = {
id: "filename" | "size" | "dateUploaded";
direction: "asc" | "desc";
};
type AttachmentsDialogProps = { onClose: Perform };
function AttachmentsDialog({ onClose }: AttachmentsDialogProps) {
const allAttachments = useStore((store) => store.attachments);
const [attachments, setAttachments] =
useState<VirtualizedGrouping<AttachmentType>>();
const [counts, setCounts] = useState<Record<Route, number>>({
all: 0,
documents: 0,
images: 0,
orphaned: 0,
uploads: 0,
videos: 0,
audio: 0
});
const [selected, setSelected] = useState<string[]>([]);
const [sortBy, setSortBy] = useState<SortOptions>({
id: "filename",
direction: "asc"
});
const currentRoute = useRef<Route>("all");
const refresh = useStore((store) => store.refresh);
const download = useStore((store) => store.download);
type AttachmentsDialogProps = BaseDialogProps<false>;
export const AttachmentsDialog = DialogManager.register(
function AttachmentsDialog({ onClose }: AttachmentsDialogProps) {
const nonce = useStore((store) => store.nonce);
const [attachments, setAttachments] =
useState<VirtualizedGrouping<AttachmentType>>();
const [counts, setCounts] = useState<Record<Route, number>>({
all: 0,
documents: 0,
images: 0,
orphaned: 0,
uploads: 0,
videos: 0,
audio: 0
});
const [selected, setSelected] = useState<string[]>([]);
const [sortBy, setSortBy] = useState<SortOptions>({
id: "filename",
direction: "asc"
});
const currentRoute = useRef<Route>("all");
const download = useStore((store) => store.download);
useEffect(() => {
refresh();
}, [refresh]);
useEffect(() => {
(async function () {
setAttachments(
await filterAttachments(currentRoute.current).sorted({
useEffect(() => {
filterAttachments(currentRoute.current)
.sorted({
sortBy: sortBy.id,
sortDirection: sortBy.direction
})
);
})();
}, [sortBy, allAttachments]);
.then((value) => startTransition(() => setAttachments(value)));
}, [sortBy, nonce]);
useEffect(() => {
(async function () {
setCounts(await getCounts());
})();
}, [allAttachments]);
useEffect(() => {
getCounts().then((counts) => startTransition(() => setCounts(counts)));
}, [nonce]);
return (
<Dialog
isOpen={true}
width={"70%"}
onClose={() => onClose(false)}
noScroll
sx={{ bg: "transparent" }}
>
<Flex
sx={{
height: "80vw",
overflow: "hidden"
}}
return (
<Dialog
isOpen={true}
width={"70%"}
onClose={() => onClose(false)}
noScroll
sx={{ bg: "transparent" }}
>
<Sidebar
onDownloadAll={async () =>
download(
await db.attachments.all.ids({
sortBy: "dateCreated",
sortDirection: "desc"
})
)
}
filter={async (query) => {
setAttachments(await db.lookup.attachments(query).sorted());
}}
counts={counts}
onRouteChange={async (route) => {
currentRoute.current = route;
setSelected([]);
setAttachments(
await filterAttachments(currentRoute.current).sorted({
sortBy: sortBy.id,
sortDirection: sortBy.direction
})
);
}}
/>
<Flex
variant="columnFill"
sx={{
bg: "background",
flexDirection: "column",
pl: 4,
pt: 2,
height: "80vw",
overflow: "hidden"
}}
>
<FlexScrollContainer>
<Flex sx={{ justifyContent: "space-between" }}>
<Flex sx={{ gap: 1 }}>
{TOOLBAR_ACTIONS.map((tool) => (
<Button
variant="secondary"
key={tool.title}
title={tool.title}
onClick={() =>
tool.onClick({
selected
// : attachments.filter(
// (a) => selected.indexOf(a.id) > -1
// )
})
}
disabled={!selected.length}
sx={{ bg: "transparent", p: 1 }}
>
<tool.icon size={18} />
</Button>
))}
</Flex>
{/* <Button
<Sidebar
onDownloadAll={async () =>
download(
await db.attachments.all.ids({
sortBy: "dateCreated",
sortDirection: "desc"
})
)
}
filter={async (query) => {
setAttachments(await db.lookup.attachments(query).sorted());
}}
counts={counts}
onRouteChange={async (route) => {
currentRoute.current = route;
setSelected([]);
setAttachments(
await filterAttachments(currentRoute.current).sorted({
sortBy: sortBy.id,
sortDirection: sortBy.direction
})
);
}}
/>
<Flex
variant="columnFill"
sx={{
bg: "background",
flexDirection: "column",
pl: 4,
pt: 2,
overflow: "hidden"
}}
>
<FlexScrollContainer>
<Flex sx={{ justifyContent: "space-between" }}>
<Flex sx={{ gap: 1 }}>
{TOOLBAR_ACTIONS.map((tool) => (
<Button
variant="secondary"
key={tool.title}
title={tool.title}
onClick={() =>
tool.onClick({
selected
// : attachments.filter(
// (a) => selected.indexOf(a.id) > -1
// )
})
}
disabled={!selected.length}
sx={{ bg: "transparent", p: 1 }}
>
<tool.icon size={18} />
</Button>
))}
</Flex>
{/* <Button
variant="tool"
sx={{ p: 1, display: "flex" }}
onClick={async () => {
@@ -229,123 +225,127 @@ function AttachmentsDialog({ onClose }: AttachmentsDialogProps) {
Upload
</Text>
</Button> */}
</Flex>
{attachments && (
<VirtualizedTable
style={{ tableLayout: "fixed", borderCollapse: "collapse" }}
header={
<Box
as="tr"
sx={{
height: 40,
th: { borderBottom: "1px solid var(--separator)" },
bg: "background"
}}
>
<Text
as="th"
variant="body"
</Flex>
{attachments ? (
<VirtualizedTable
style={{
tableLayout: "fixed",
width: "100%",
borderCollapse: "collapse"
}}
header={
<Box
as="tr"
sx={{
width: 24,
textAlign: "left",
fontWeight: "normal",
mb: 2
height: 40,
th: { borderBottom: "1px solid var(--separator)" },
bg: "background"
}}
>
<Label>
<Checkbox
sx={{ width: 18, height: 18 }}
onChange={async (e) => {
setSelected(
e.currentTarget.checked
? await filterAttachments(
currentRoute.current
).ids()
: []
);
}}
/>
</Label>
</Text>
{COLUMNS.map((column) =>
!column.title ? (
<th key={column.id} />
) : (
<Box
as="th"
key={column.id}
sx={{
width: column.width,
cursor: "pointer",
px: 1,
mb: 2,
":hover": { bg: "hover" }
}}
onClick={() => {
setSortBy((sortBy) => ({
direction:
sortBy.id === column.id &&
sortBy.direction === "asc"
? "desc"
: "asc",
id: column.id
}));
}}
>
<Flex
<Text
as="th"
variant="body"
sx={{
width: 24,
textAlign: "left",
fontWeight: "normal",
mb: 2
}}
>
<Label>
<Checkbox
sx={{ width: 18, height: 18 }}
onChange={async (e) => {
setSelected(
e.currentTarget.checked
? await filterAttachments(
currentRoute.current
).ids()
: []
);
}}
/>
</Label>
</Text>
{COLUMNS.map((column) =>
!column.title ? (
<th key={column.id} />
) : (
<Box
as="th"
key={column.id}
sx={{
alignItems: "center",
justifyContent: "space-between"
width: column.width,
cursor: "pointer",
px: 1,
mb: 2,
":hover": { bg: "hover" }
}}
onClick={() => {
setSortBy((sortBy) => ({
direction:
sortBy.id === column.id &&
sortBy.direction === "asc"
? "desc"
: "asc",
id: column.id
}));
}}
>
<Text
variant="body"
sx={{ textAlign: "left", fontWeight: "normal" }}
<Flex
sx={{
alignItems: "center",
justifyContent: "space-between"
}}
>
{column.title}
</Text>
{sortBy.id === column.id ? (
sortBy.direction === "asc" ? (
<ChevronUp size={16} />
) : (
<ChevronDown size={16} />
)
) : null}
</Flex>
</Box>
)
)}
</Box>
}
mode="fixed"
estimatedSize={30}
headerSize={40}
getItemKey={(index) => attachments.key(index)}
items={attachments.placeholders}
context={{
isSelected: (id: string) => selected.indexOf(id) > -1,
select: (id: string) => {
setSelected((s) => {
const copy = s.slice();
const index = copy.indexOf(id);
if (index > -1) copy.splice(index, 1);
else copy.push(id);
return copy;
});
},
attachments
}}
renderRow={AttachmentRow}
/>
)}
</FlexScrollContainer>
<Text
variant="body"
sx={{ textAlign: "left", fontWeight: "normal" }}
>
{column.title}
</Text>
{sortBy.id === column.id ? (
sortBy.direction === "asc" ? (
<ChevronUp size={16} />
) : (
<ChevronDown size={16} />
)
) : null}
</Flex>
</Box>
)
)}
</Box>
}
mode="fixed"
estimatedSize={30}
getItemKey={(index) => attachments.key(index)}
items={attachments.placeholders}
context={{
isSelected: (id: string) => selected.indexOf(id) > -1,
select: (id: string) => {
setSelected((s) => {
const copy = s.slice();
const index = copy.indexOf(id);
if (index > -1) copy.splice(index, 1);
else copy.push(id);
return copy;
});
},
attachments
}}
renderRow={AttachmentRow}
/>
) : (
<Loader title="Loading attachments..." />
)}
</FlexScrollContainer>
</Flex>
</Flex>
</Flex>
</Dialog>
);
}
export default AttachmentsDialog;
</Dialog>
);
}
);
function AttachmentRow(
props: VirtualizedTableRowProps<
@@ -357,23 +357,21 @@ function AttachmentRow(
}
>
) {
if (!props.context) return null;
const item = useResolvedItem({
index: props.index,
items: props.context!.attachments,
type: "attachment"
});
if (!item) return null;
return (
<ResolvedItem
index={props.index}
items={props.context.attachments}
type="attachment"
>
{({ item }) => (
<Attachment
rowRef={props.rowRef}
style={props.style}
item={item}
isSelected={props.context?.isSelected(item.id)}
onSelected={() => props.context?.select(item.id)}
/>
)}
</ResolvedItem>
<Attachment
key={item.item.id}
rowRef={props.rowRef}
style={props.style}
item={item?.item}
isSelected={props.context?.isSelected(item.item.id)}
onSelected={() => props.context?.select(item.item.id)}
/>
);
}
@@ -443,6 +441,7 @@ const Sidebar = memo(
<Flex
className="theme-scope-navigationMenu"
sx={{
flexShrink: 0,
flexDirection: "column",
justifyContent: "space-between",
width: 240,
@@ -484,40 +483,83 @@ const Sidebar = memo(
</Text>
)}
</Flex>
<Button
variant="secondary"
sx={{
bg: "transparent",
borderRadius: 100,
position: "relative",
width: 38,
height: 38
}}
title="Download all attachments"
onClick={async () => {
if (downloadStatus) {
await cancelDownload();
} else {
onDownloadAll();
}
}}
>
{downloadStatus ? <Close size={18} /> : <Download size={18} />}
{downloadStatus ? (
<Donut
value={
(downloadStatus.current / downloadStatus.total) * 100
<Flex>
<Button
variant="secondary"
sx={{
bg: "transparent",
borderRadius: 100,
position: "relative",
width: 38,
height: 38
}}
disabled={!!downloadStatus}
title="Clear cache"
onClick={async () => {
if (
await ConfirmDialog.show({
title: "Clear attachments cache?",
message: `Clearing attachments cache will perform the following actions:
- Downloaded images & files: **cleared**
- Pending uploads: **cleared**
- Uploaded images & files: _unaffected_
All attachments will be downloaded & cached again on access.
---
**Only use this for troubleshooting purposes. If you are having persistent issues, it is recommended that you reach out to us via support@streetwriters.co so we can help you resolve it permanently.**`,
negativeButtonText: "No",
positiveButtonText: "Yes"
})
) {
await db.fs().clear();
showToast("success", "Attachments cache cleared!");
}
max={100}
size={38}
sx={{
position: "absolute",
top: 0,
left: 0
}}
/>
) : null}
</Button>
}}
>
<ClearCache />
</Button>
<Button
variant="secondary"
sx={{
bg: "transparent",
borderRadius: 100,
position: "relative",
width: 38,
height: 38
}}
title="Download all attachments"
onClick={async () => {
if (downloadStatus) {
await cancelDownload();
} else {
onDownloadAll();
}
}}
>
{downloadStatus ? (
<Close size={18} />
) : (
<Download size={18} />
)}
{downloadStatus ? (
<Donut
value={
(downloadStatus.current / downloadStatus.total) * 100
}
max={100}
size={38}
sx={{
position: "absolute",
top: 0,
left: 0
}}
/>
) : null}
</Button>
</Flex>
</Flex>
</Flex>
</Flex>

View File

@@ -18,105 +18,106 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { useState } from "react";
import { Perform } from "../common/dialog-controller";
import Field from "../components/field";
import Dialog from "../components/dialog";
import { Box, Button, Text } from "@theme-ui/components";
import { BaseDialogProps, DialogManager } from "../common/dialog-manager";
export type PromptDialogProps = {
onClose: Perform;
export type BackupPasswordDialogProps = BaseDialogProps<boolean> & {
validate: (outputs: {
password?: string;
key?: string;
}) => boolean | Promise<boolean>;
};
export default function BackupPasswordDialog(props: PromptDialogProps) {
const { onClose, validate } = props;
export const BackupPasswordDialog = DialogManager.register(
function BackupPasswordDialog(props: BackupPasswordDialogProps) {
const { onClose, validate } = props;
const [error, setError] = useState<string>();
const [isLoading, setIsLoading] = useState(false);
const [isEncryptionKey, setIsEncryptionKey] = useState(false);
const [error, setError] = useState<string>();
const [isLoading, setIsLoading] = useState(false);
const [isEncryptionKey, setIsEncryptionKey] = useState(false);
return (
<Dialog
isOpen={true}
testId="password-dialog"
title={"Encrypted backup"}
description={
"Please enter the password to decrypt and restore this backup."
}
onClose={() => onClose(false)}
positiveButton={{
form: "backupPasswordForm",
type: "submit",
loading: isLoading,
disabled: isLoading,
text: "Restore"
}}
negativeButton={{ text: "Cancel", onClick: () => onClose(false) }}
>
<Box
id="backupPasswordForm"
as="form"
onSubmit={async (e) => {
e.preventDefault();
const formData = new FormData(e.target as HTMLFormElement);
try {
setIsLoading(true);
setError(undefined);
const key = formData.get("key") as string;
const password = formData.get("password") as string;
if (!key && !password) return;
if (await validate({ key, password })) {
onClose(true);
} else {
setError("Wrong password.");
}
} catch (e) {
setError((e as Error).message);
} finally {
setIsLoading(false);
}
return (
<Dialog
isOpen={true}
testId="password-dialog"
title={"Encrypted backup"}
description={
"Please enter the password to decrypt and restore this backup."
}
onClose={() => onClose(false)}
positiveButton={{
form: "backupPasswordForm",
type: "submit",
loading: isLoading,
disabled: isLoading,
text: "Restore"
}}
negativeButton={{ text: "Cancel", onClick: () => onClose(false) }}
>
{isEncryptionKey ? (
<Field
required
autoFocus
data-test-id="encryption-key"
label="Encryption key"
type="password"
id="key"
name="key"
/>
) : (
<Field
required
autoFocus
data-test-id="password"
label="Password"
type="password"
autoComplete="current-password"
id="password"
name="password"
/>
)}
</Box>
<Button variant="anchor" onClick={() => setIsEncryptionKey((s) => !s)}>
{isEncryptionKey
? "Don't have encryption key? Use password."
: "Forgot password? Use encryption key."}
</Button>
<Box
id="backupPasswordForm"
as="form"
onSubmit={async (e) => {
e.preventDefault();
const formData = new FormData(e.target as HTMLFormElement);
{error && (
<Text as="div" mt={1} variant={"error"}>
{error}
</Text>
)}
</Dialog>
);
}
try {
setIsLoading(true);
setError(undefined);
const key = formData.get("key") as string;
const password = formData.get("password") as string;
if (!key && !password) return;
if (await validate({ key, password })) {
onClose(true);
} else {
setError("Wrong password.");
}
} catch (e) {
setError((e as Error).message);
} finally {
setIsLoading(false);
}
}}
>
{isEncryptionKey ? (
<Field
required
autoFocus
data-test-id="encryption-key"
label="Encryption key"
type="password"
id="key"
name="key"
/>
) : (
<Field
required
autoFocus
data-test-id="password"
label="Password"
type="password"
autoComplete="current-password"
id="password"
name="password"
/>
)}
</Box>
<Button variant="anchor" onClick={() => setIsEncryptionKey((s) => !s)}>
{isEncryptionKey
? "Don't have encryption key? Use password."
: "Forgot password? Use encryption key."}
</Button>
{error && (
<Text as="div" mt={1} variant={"error"}>
{error}
</Text>
)}
</Dialog>
);
}
);

Some files were not shown because too many files have changed in this diff Show More