Compare commits

..

1 Commits

Author SHA1 Message Date
Abdullah Atta
caf217907c docs: add docs for self hosting 2025-10-09 13:23:10 +05:00
232 changed files with 5137 additions and 5258 deletions

View File

@@ -47,11 +47,6 @@ jobs:
- name: Install Detox CLI
run: npm install detox-cli --global
- name: Check for typescript errors
run: |
cd apps/mobile
npx tsc --noEmit
- name: Detox build
run: |
yarn build:android

View File

@@ -73,12 +73,6 @@ jobs:
- name: CCache Stats Before Build
run: ccache -sv
- name: Check for typescript errors
run: |
npm run tx mobile:build
cd apps/mobile
npx tsc --noEmit
- name: Build unsigned app bundle
run: yarn release:android:bundle

View File

@@ -73,12 +73,6 @@ jobs:
- name: CCache Stats Before Build
run: ccache -sv
- name: Check for typescript errors
run: |
npm run tx mobile:build
cd apps/mobile
npx tsc --noEmit
- name: Build unsigned app bundle
run: yarn release:android:bundle

View File

@@ -268,6 +268,7 @@ jobs:
- name: Build Electron wrapper
run: npm run tx @notesnook/desktop:release
working-directory: ./apps/desktop
- name: Build snap
if: inputs.publish-snap
@@ -335,6 +336,7 @@ jobs:
- name: Build Electron wrapper
run: npm run tx @notesnook/desktop:release
working-directory: ./apps/desktop
# - name: Build snap
# if: inputs.publish-snap

View File

@@ -67,6 +67,7 @@ jobs:
- name: Build Electron wrapper
run: npm run tx @notesnook/desktop:release
working-directory: ./apps/desktop
- name: Build app
run: |
@@ -110,6 +111,7 @@ jobs:
- name: Build Electron wrapper
run: npm run tx @notesnook/desktop:release
working-directory: ./apps/desktop
- name: Build app
run: |
@@ -159,6 +161,7 @@ jobs:
- name: Build Electron wrapper
run: npm run tx @notesnook/desktop:release
working-directory: ./apps/desktop
- name: Build app
run: |

View File

@@ -64,12 +64,6 @@ jobs:
bundle install
RCT_NEW_ARCH_ENABLED=0 bundle exec pod install
- name: Check for typescript errors
run: |
npm run tx mobile:build
cd apps/mobile
npx tsc --noEmit
- name: CCache Stats Before Build
run: ccache -sv

View File

@@ -1,12 +1,12 @@
{
"name": "@notesnook/desktop",
"version": "3.3.5",
"version": "3.3.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@notesnook/desktop",
"version": "3.3.5",
"version": "3.3.0",
"hasInstallScript": true,
"license": "GPL-3.0-or-later",
"dependencies": {
@@ -30,7 +30,7 @@
"@types/node": "22.15.3",
"@types/yargs": "^17.0.33",
"chokidar": "^4.0.3",
"electron": "^37.0.0",
"electron": "^36.0.0",
"electron-builder": "^26.0.12",
"esbuild": "0.21.5",
"node-abi": "^4.5.0",
@@ -3412,9 +3412,9 @@
}
},
"node_modules/electron": {
"version": "37.6.1",
"resolved": "https://registry.npmjs.org/electron/-/electron-37.6.1.tgz",
"integrity": "sha512-aHtJVNjqf0lk7dlPoc1X+fMBpZtLn+XGvP6IYc3gooTwsD1D/Ic2SBRC9SnIk6LkWTsDaSF9jgH1d9Q7eABy/Q==",
"version": "36.9.3",
"resolved": "https://registry.npmjs.org/electron/-/electron-36.9.3.tgz",
"integrity": "sha512-eR5yswsA55zVTPDEIA/PSdVNBLOp0q0Wsavgx0S3BmJYOqKoH1gqzS+hggf0/aY5OvUjVNSHiJJA1VsB5aJUug==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",

View File

@@ -2,7 +2,7 @@
"name": "@notesnook/desktop",
"productName": "Notesnook",
"description": "Your private note taking space",
"version": "3.3.5",
"version": "3.3.0",
"appAppleId": "1544027013",
"private": true,
"main": "./dist/cjs/index.js",
@@ -47,7 +47,7 @@
"@types/node": "22.15.3",
"@types/yargs": "^17.0.33",
"chokidar": "^4.0.3",
"electron": "^37.0.0",
"electron": "^36.0.0",
"electron-builder": "^26.0.12",
"esbuild": "0.21.5",
"node-abi": "^4.5.0",

View File

@@ -18,7 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import "./overrides";
import { app, BrowserWindow, nativeTheme, shell, dialog } from "electron";
import { app, BrowserWindow, nativeTheme, shell } from "electron";
import { isDevelopment } from "./utils";
import { registerProtocol, PROTOCOL_URL } from "./utils/protocol";
import { configureAutoUpdater } from "./utils/autoupdater";
@@ -182,17 +182,6 @@ async function createWindow() {
app.once("ready", async () => {
console.info("App ready. Opening window.");
if (app.runningUnderARM64Translation) {
console.log("App is running under ARM64 translation");
dialog.showMessageBoxSync({
message:
"Notesnook detected that it is running under ARM64 translation. For the best performance, please download the ARM64 build of Notesnook from our website.",
type: "warning",
buttons: ["Okay"],
title: "Degraded Performance Warning"
});
}
if (config.customDns) enableCustomDns();
else disableCustomDns();

View File

@@ -94,9 +94,7 @@ export async function encryptDatabaseKeyWithPassword(appLockPassword: string) {
}
export async function restoreDatabaseKeyToKeyChain(appLockPassword: string) {
const databaseKeyCipher: Cipher = CipherStorage.getMap(
DB_KEY_CIPHER
) as Cipher;
const databaseKeyCipher: Cipher = CipherStorage.getMap(DB_KEY_CIPHER);
const databaseKey = (await decrypt(
{
password: appLockPassword
@@ -137,9 +135,7 @@ export async function clearAppLockVerificationCipher() {
export async function validateAppLockPassword(appLockPassword: string) {
try {
const appLockCipher: Cipher = CipherStorage.getMap(
APPLOCK_CIPHER
) as Cipher;
const appLockCipher: Cipher = CipherStorage.getMap(APPLOCK_CIPHER);
if (!appLockCipher) return true;
const key = await Sodium.deriveKey(appLockPassword, appLockCipher.salt);
const decrypted = await decrypt(key, appLockCipher);
@@ -163,9 +159,7 @@ export function clearDatabaseKey() {
export async function getDatabaseKey(appLockPassword?: string) {
if (DB_KEY) return DB_KEY;
if (appLockPassword) {
const databaseKeyCipher: Cipher = CipherStorage.getMap(
"databaseKeyCipher"
) as Cipher;
const databaseKeyCipher: Cipher = CipherStorage.getMap("databaseKeyCipher");
const databaseKey = await decrypt(
{
password: appLockPassword
@@ -299,7 +293,7 @@ export async function deriveCryptoKey(data: SerializedKey) {
export async function getCryptoKey() {
try {
const keyCipher: Cipher = MMKV.getMap(USER_KEY_CIPHER) as Cipher;
const keyCipher: Cipher = MMKV.getMap(USER_KEY_CIPHER);
if (!keyCipher) {
DatabaseLogger.info("User key cipher is null");
return undefined;

View File

@@ -39,7 +39,7 @@ export async function setupDatabase(password?: string) {
const key = await getDatabaseKey(password);
if (!key) throw new Error(strings.databaseSetupFailed());
// const base = `http://192.168.100.92`;
// const base = `http://192.168.100.88`;
// database.host({
// API_HOST: `${base}:5264`,

View File

@@ -136,12 +136,6 @@ export const Storage: IStorage = {
clear(): Promise<void> {
return DefaultStorage.clear();
},
generateCryptoKeyPair() {
throw new Error("Not implemented");
},
decryptAsymmetric() {
throw new Error("Not implemented");
},
getAllKeys(): Promise<string[]> {
return DefaultStorage.getAllKeys();
},

View File

@@ -38,6 +38,9 @@ export function hideAuth(context) {
context === "intro"
) {
Navigation.replace("FluidPanelsView");
setTimeout(() => {
Navigation.resetRootState();
}, 1000);
} else {
Navigation.goBack();
}

View File

@@ -39,7 +39,6 @@ import Heading from "../ui/typography/heading";
import Paragraph from "../ui/typography/paragraph";
import { AuthHeader } from "./header";
import { SignupContext } from "./signup-context";
import SettingsService from "../../services/settings";
const SignupSteps = {
signup: 0,

View File

@@ -99,7 +99,7 @@ export const useLogin = (
callback && callback(false);
} catch (e) {
callback && callback(false);
if ((e as Error).message === "invalid_grant") {
if (e.message === "invalid_grant") {
eSendEvent(eCloseSimpleDialog, "two_factor_verify");
setLoading(false);
setStep(LoginSteps.emailAuth);

View File

@@ -35,35 +35,29 @@ import SheetProvider from "../sheet-provider";
import RateAppSheet from "../sheets/rate-app";
import RecoveryKeySheet from "../sheets/recovery-key";
import Progress from "../dialogs/progress";
import { useSettingStore } from "../../stores/use-setting-store";
const DialogProvider = () => {
const { colors } = useThemeColors();
const isAppLoading = useSettingStore((state) => state.isAppLoading);
return (
<>
<AppLockPassword />
<LoadingDialog />
<Dialog context="global" />
<AuthModal colors={colors} />
<MergeConflicts />
<RecoveryKeySheet colors={colors} />
<SheetProvider />
<SheetProvider context="sync_progress" />
<Dialog context="global" />
<ResultDialog />
<VaultDialog colors={colors} />
<RateAppSheet />
<ImagePreview />
<AnnouncementDialog />
<SessionExpired />
<PDFPreview />
<JumpToSectionDialog />
<Progress />
{isAppLoading ? null : (
<>
<MergeConflicts />
<RecoveryKeySheet colors={colors} />
<ResultDialog />
<VaultDialog colors={colors} />
<RateAppSheet />
<ImagePreview />
<AnnouncementDialog />
<SessionExpired />
<PDFPreview />
<JumpToSectionDialog />
</>
)}
</>
);
};

View File

@@ -244,7 +244,7 @@ const PDFPreview = () => {
textAlign: "center",
marginRight: 4,
borderRadius: 3,
fontFamily: "Inter-Regular"
fontFamily: "OpenSans-Regular"
}}
selectTextOnFocus
keyboardType="decimal-pad"

View File

@@ -41,7 +41,7 @@ export const openNotebook = (item: Notebook | BaseTrashItem<Notebook>) => {
positiveText: strings.restore(),
negativeText: strings.delete(),
positivePress: async () => {
await db.trash.restore(item.id);
if ((await db.trash.restore(item.id)) === false) return;
Navigation.queueRoutesForUpdate();
useSelectionStore.getState().setSelectionMode(undefined);
ToastManager.show({

View File

@@ -117,8 +117,7 @@ export default function NotePreview({ session, content, note }) {
{!session?.locked && !locked ? (
<View
style={{
flex: 1,
backgroundColor: colors.primary.background
flex: 1
}}
>
<ReadonlyEditor

View File

@@ -44,7 +44,6 @@ import Config from "react-native-config";
import * as RNIap from "react-native-iap";
import { SafeAreaView } from "react-native-safe-area-context";
import Icon from "react-native-vector-icons/MaterialCommunityIcons";
//@ts-ignore
import ToggleSwitch from "toggle-switch-react-native";
import {
ANDROID_POLICE_SVG,
@@ -920,6 +919,7 @@ const ReviewItem = (props: {
</View>
);
};
const PricingPlanCard = ({
plan,
pricingPlans,
@@ -932,6 +932,7 @@ const PricingPlanCard = ({
setStep: (step: number) => void;
}) => {
const { colors } = useThemeColors();
const isFreePlan = plan.id === "free";
const [regionalDiscount, setRegionaDiscount] = useState<SKUResponse>();
const { width } = useWindowDimensions();
const isTablet = width > 600;
@@ -941,22 +942,19 @@ const PricingPlanCard = ({
regionalDiscount?.sku ||
`notesnook.${plan.id}.${annualBilling ? "yearly" : "monthly"}`
];
const price = pricingPlans?.getPrice(
product as RNIap.Subscription,
pricingPlans.hasTrialOffer(plan.id, product?.productId) ? 1 : 0,
annualBilling
);
const WebPlan = pricingPlans?.getWebPlan(
plan.id,
annualBilling ? "yearly" : "monthly"
);
const price = pricingPlans?.getPrice(
pricingPlans.isGithubRelease && WebPlan
? WebPlan
: (product as RNIap.Subscription),
pricingPlans.hasTrialOffer(plan.id, product?.productId) ? 1 : 0,
annualBilling
);
useEffect(() => {
if (pricingPlans?.isGithubRelease || !annualBilling) return;
if (pricingPlans?.isGithubRelease) return;
pricingPlans
?.getRegionalDiscount(
plan.id,
@@ -967,13 +965,7 @@ const PricingPlanCard = ({
.then((value) => {
setRegionaDiscount(value);
});
}, [annualBilling]);
useEffect(() => {
if (!annualBilling) {
setRegionaDiscount(undefined);
}
}, [annualBilling]);
}, []);
const isSubscribed =
product?.productId &&
@@ -1118,21 +1110,24 @@ const PricingPlanCard = ({
) : (
<View>
<Paragraph size={AppFontSize.lg}>
{price || `${WebPlan?.price?.currency} ${WebPlan?.price?.gross}`}{" "}
{isFreePlan
? "0.00"
: price ||
`${WebPlan?.price?.currency} ${WebPlan?.price?.gross}`}{" "}
<Paragraph>/{strings.month()}</Paragraph>
</Paragraph>
{!product && !WebPlan ? null : (
{isFreePlan || !product ? null : (
<Paragraph color={colors.secondary.paragraph} size={AppFontSize.xs}>
{annualBilling
? strings.billedAnnually(
pricingPlans?.getStandardPrice(
(product || WebPlan) as any
product as RNIap.Subscription
) as string
)
: strings.billedMonthly(
pricingPlans?.getStandardPrice(
(product || WebPlan) as any
product as RNIap.Subscription
) as string
)}
</Paragraph>

View File

@@ -21,13 +21,7 @@ import { strings } from "@notesnook/intl";
import { useThemeColors } from "@notesnook/theme";
import dayjs from "dayjs";
import React, { useEffect, useState } from "react";
import {
Linking,
ScrollView,
Text,
TouchableOpacity,
View
} from "react-native";
import { ScrollView, Text, TouchableOpacity, View } from "react-native";
import Config from "react-native-config";
import * as RNIap from "react-native-iap";
import Icon from "react-native-vector-icons/MaterialCommunityIcons";
@@ -66,24 +60,27 @@ export const BuyPlan = (props: {
return checkoutUrl ? (
<View
style={{
flex: 1,
justifyContent: "center",
alignItems: "center",
gap: DefaultAppStyles.GAP_VERTICAL
flex: 1
}}
>
<Paragraph>{strings.finishPurchaseInBrowser()}</Paragraph>
<Button
title={strings.next()}
type="accent"
onPress={() => {
pricingPlans.finish();
<WebView
source={{
uri: checkoutUrl
}}
/>
<Button
title={strings.goBack()}
onPress={() => {
setCheckoutUrl(undefined);
onMessage={(message) => {
try {
const data = JSON.parse(message.nativeEvent.data);
if (data.success) {
pricingPlans.finish();
}
} catch (e) {}
}}
domStorageEnabled
javaScriptEnabled
cacheEnabled
enabled
style={{
flex: 1
}}
/>
</View>
@@ -248,14 +245,12 @@ export const BuyPlan = (props: {
}
onPress={async () => {
if (isGithubRelease) {
const url = await db.subscriptions.checkoutUrl(
(pricingPlans.selectedProduct as Plan).plan,
(pricingPlans.selectedProduct as Plan).period
setCheckoutUrl(
await db.subscriptions.checkoutUrl(
(pricingPlans.selectedProduct as Plan).plan,
(pricingPlans.selectedProduct as Plan).period
)
);
if (url) {
setCheckoutUrl(url);
Linking.openURL(url);
}
return;
}

View File

@@ -39,7 +39,9 @@ import {
presentSheet
} from "../../../services/event-manager";
import Exporter from "../../../services/exporter";
import PremiumService from "../../../services/premium";
import { useSettingStore } from "../../../stores/use-setting-store";
import { useUserStore } from "../../../stores/use-user-store";
import { getElevationStyle } from "../../../utils/elevation";
import { AppFontSize, defaultBorderRadius } from "../../../utils/size";
import { DefaultAppStyles } from "../../../utils/styles";
@@ -81,6 +83,7 @@ const ExportNotesSheet = ({
type: "pdf" | "txt" | "md" | "html" | "md-frontmatter"
) => {
if (exporting) return;
if (!PremiumService.get() && type !== "txt") return;
setExporting(true);
update?.({ disableClosing: true } as PresentSheetOptions);
setComplete(false);
@@ -142,7 +145,8 @@ const ExportNotesSheet = ({
await exportNoteAs("txt");
},
icon: "card-text",
id: notesnook.ids.dialogs.export.text
id: notesnook.ids.dialogs.export.text,
pro: true
},
{
title: "HTML",
@@ -190,7 +194,8 @@ const ExportNotesSheet = ({
paddingVertical: DefaultAppStyles.GAP_VERTICAL,
justifyContent: "flex-start",
borderRadius: 0,
paddingHorizontal: DefaultAppStyles.GAP
paddingHorizontal: DefaultAppStyles.GAP,
opacity: item.pro ? 1 : 0.5
}}
>
<View

View File

@@ -36,7 +36,6 @@ import Heading from "../../ui/typography/heading";
import Paragraph from "../../ui/typography/paragraph";
import { strings } from "@notesnook/intl";
import { DefaultAppStyles } from "../../../utils/styles";
import Config from "react-native-config";
export const Issue = ({ defaultTitle, defaultBody, issueTitle }) => {
const { colors } = useThemeColors();
@@ -68,8 +67,7 @@ App version: ${getVersion()}
Platform: ${Platform.OS}
Device: ${getBrand() || ""}-${getModel() || ""}-${getSystemVersion() || ""}
Pro: ${PremiumService.get()}
Logged in: ${user ? "yes" : "no"}
Github Release: ${Config.GITHUB_RELEASE === "true" ? "Yes" : "No"}`,
Logged in: ${user ? "yes" : "no"}`,
userId: user?.id
});
if (!issueUrl.current) {
@@ -161,7 +159,7 @@ Github Release: ${Config.GITHUB_RELEASE === "true" ? "Yes" : "No"}`,
borderColor: colors.primary.border,
borderRadius: defaultBorderRadius,
padding: DefaultAppStyles.GAP,
fontFamily: "Inter-Regular",
fontFamily: "OpenSans-Regular",
marginBottom: DefaultAppStyles.GAP_VERTICAL,
fontSize: AppFontSize.md,
color: colors.primary.heading
@@ -194,7 +192,7 @@ Github Release: ${Config.GITHUB_RELEASE === "true" ? "Yes" : "No"}`,
borderColor: colors.primary.border,
borderRadius: defaultBorderRadius,
padding: DefaultAppStyles.GAP,
fontFamily: "Inter-Regular",
fontFamily: "OpenSans-Regular",
maxHeight: 200,
fontSize: AppFontSize.sm,
marginBottom: 2.5,

View File

@@ -29,7 +29,6 @@ import {
View
} from "react-native";
import Icon from "react-native-vector-icons/MaterialCommunityIcons";
//@ts-ignore
import ToggleSwitch from "toggle-switch-react-native";
import { db } from "../../../common/database";
import { requestInAppReview } from "../../../services/app-review";

View File

@@ -239,7 +239,7 @@ const Input = ({
flexShrink: 1,
paddingBottom: DefaultAppStyles.GAP_VERTICAL - 4,
paddingTop: DefaultAppStyles.GAP_VERTICAL - 4,
fontFamily: "Inter-Regular",
fontFamily: "OpenSans-Regular",
...(inputStyle as ViewStyle)
};

View File

@@ -132,10 +132,7 @@ const SheetWrapper = ({
width: 100,
backgroundColor: colors.secondary.background
}}
safeAreaInsets={{
...insets,
bottom: Platform.OS === "android" ? 0 : insets.bottom
}}
safeAreaInsets={insets}
statusBarTranslucent
drawUnderStatusBar={true}
containerStyle={style}

View File

@@ -171,7 +171,7 @@ const onAppOpenedFromURL = async (event: { url: string }) => {
eSendEvent(eOnLoadNote, { newNote: true });
fluidTabsRef.current?.goToPage("editor", false);
return;
} else if (url.startsWith("https://app.notesnook.com/open_note")) {
} else if (url.startsWith("https://notesnook.com/open_note")) {
const id = new URL(url).searchParams.get("id");
if (id) {
const note = await db.notes.note(id);
@@ -182,13 +182,13 @@ const onAppOpenedFromURL = async (event: { url: string }) => {
fluidTabsRef.current?.goToPage("editor", false);
}
}
} else if (url.startsWith("https://app.notesnook.com/open_reminder")) {
} else if (url.startsWith("https://notesnook.com/open_reminder")) {
const id = new URL(url).searchParams.get("id");
if (id) {
const reminder = await db.reminders.reminder(id);
if (reminder) AddReminder.present(reminder);
}
} else if (url.startsWith("https://app.notesnook.com/new_reminder")) {
} else if (url.startsWith("https://notesnook.com/new_reminder")) {
const reminderFeature = await isFeatureAvailable("activeReminders");
if (!reminderFeature.isAllowed) {
ToastManager.show({
@@ -780,11 +780,13 @@ export const useAppEvents = () => {
if (!isAppLoading && !appLocked) {
setTimeout(() => {
sub = AppState.addEventListener("change", onAppStateChanged);
if (refValues.current.initialUrl) {
if (
refValues.current.initialUrl &&
!refValues.current.initialUrl?.includes("open_note")
) {
onAppOpenedFromURL({
url: refValues.current.initialUrl!
});
refValues.current.initialUrl = undefined;
}
}, 1000);

View File

@@ -69,6 +69,36 @@ export default function useFeatureManager() {
db.settings.setDefaultTag(undefined);
}
}
const isAppLocked = useUserStore.getState().appLocked;
let unsub: () => void;
if (isAppLocked) {
unsub = useUserStore.subscribe((state) => {
if (!state.appLocked && !features?.appLock?.isAllowed) {
unsub();
SettingsService.setProperty("appLockEnabled", false);
setTimeout(() => {
presentDialog({
title: "App Lock Disabled",
paragraph: features?.appLock?.error,
positiveText: strings.upgrade(),
negativeText: strings.cancel(),
positivePress: async () => {
eSendEvent(eCloseSimpleDialog);
if (SettingsService.getProperty("serverUrls")) return;
Navigation.navigate("PayWall", {
context: "logged-in"
});
}
});
}, 1000);
}
});
}
return () => {
unsub?.();
};
}, [features, plan]);
return true;

View File

@@ -270,13 +270,11 @@ const usePricingPlans = (options?: PricingPlansOptions) => {
if (Platform.OS === "android") {
if (isGithubRelease) {
if (!(product as Plan)?.price) return null;
return `${
(product as Plan).currencySymbol || (product as Plan).currency
} ${
return `${(product as Plan).price.currency} ${
(product as Plan).period === "yearly"
? (product as Plan).price.gross
? ((product as Plan).price.gross / 12).toFixed(2)
: (product as Plan).period === "5-year"
? (product as Plan).price.gross
? ((product as Plan).price.gross / (12 * 5)).toFixed(2)
: (product as Plan).price.gross
}`;
}
@@ -601,9 +599,7 @@ const usePricingPlans = (options?: PricingPlansOptions) => {
if (isGithubRelease) {
if (!(product as Plan)?.price) return null;
return `${
(product as Plan).currencySymbol || (product as Plan).currency
} ${
return `${(product as Plan).price.currency} ${
(product as Plan).period === "yearly"
? ((product as Plan).price.gross / 12).toFixed(2)
: (product as Plan).period === "5-year"

View File

@@ -0,0 +1,67 @@
/*
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 { useEffect, useState } from "react";
import { Platform } from "react-native";
import { Subscription } from "react-native-iap";
import PremiumService from "../services/premium";
import { db } from "../common/database";
import { Product } from "@notesnook/core";
const skuInfos: { [name: string]: Product | undefined } = {};
export const usePricing = (period: "monthly" | "yearly") => {
const [current, setCurrent] = useState<{
period: string;
info?: Product;
product?: Subscription;
}>();
const getDefaultSku = (period: "monthly" | "yearly") => {
return period === "monthly"
? "com.streetwriters.notesnook.sub.mo"
: "com.streetwriters.notesnook.sub.yr";
};
useEffect(() => {
(async () => {
const skuInfo =
skuInfos[period] ||
(await db.pricing?.sku(
Platform.OS === "android" ? "android" : "ios",
period
));
skuInfos[period] = skuInfo;
const products = (await (
await PremiumService.loadProductsAndSubs()
).subs) as Subscription[];
let product = products.find((p) => p.productId === skuInfo?.sku);
if (!product)
product = products.find((p) => p.productId === getDefaultSku(period));
setCurrent({
info: skuInfo,
period,
product
});
})();
}, [period]);
return current;
};

View File

@@ -21,7 +21,6 @@ import React, { useCallback, useEffect } from "react";
import { db } from "../common/database";
import BiometricService from "../services/biometrics";
import { eSubscribeEvent, eUnSubscribeEvent } from "../services/event-manager";
import { useSettingStore } from "../stores/use-setting-store";
const VaultStatusDefaults = {
exists: false,
@@ -37,7 +36,6 @@ export type VaultStatusType = {
export const useVaultStatus = () => {
const [vaultStatus, setVaultStatus] = React.useState(VaultStatusDefaults);
const isAppLoading = useSettingStore((state) => state.isAppLoading);
const checkVaultStatus = useCallback(() => {
db.vault?.exists().then(async (exists) => {
@@ -52,13 +50,12 @@ export const useVaultStatus = () => {
}, []);
useEffect(() => {
if (isAppLoading) return;
checkVaultStatus();
eSubscribeEvent("vaultUpdated", () => checkVaultStatus());
return () => {
eUnSubscribeEvent("vaultUpdated", () => checkVaultStatus());
};
}, [checkVaultStatus, isAppLoading]);
}, [checkVaultStatus]);
return vaultStatus;
};

View File

@@ -258,14 +258,12 @@ export const RootNavigation = () => {
(state) => state.settings.introCompleted
);
const clearSelection = useSelectionStore((state) => state.clearSelection);
const resetTimer = React.useRef<NodeJS.Timeout>(undefined);
const onStateChange = React.useCallback(
(state: any) => {
if (useSelectionStore.getState().selectionMode) {
clearSelection();
}
clearTimeout(resetTimer.current);
resetTimer.current = setTimeout(() => {
setTimeout(() => {
Navigation.resetRootState(state);
}, 1000);
hideAllTooltips();

View File

@@ -44,8 +44,7 @@
"@trpc/react-query": "^10.45.2",
"@trpc/server": "^10.45.2",
"@tanstack/react-query": "^4.36.1",
"async-mutex": "0.5.0",
"react-async-hook": "^4.0.0"
"async-mutex": "0.5.0"
},
"sideEffects": false
}

View File

@@ -49,7 +49,6 @@ import { AppFontSize, defaultBorderRadius } from "../../utils/size";
import { DefaultAppStyles } from "../../utils/styles";
import { getFormattedDate, useIsFeatureAvailable } from "@notesnook/common";
import PaywallSheet from "../../components/sheets/paywall";
import { useNavigationFocus } from "../../hooks/use-navigation-focus";
const ReminderModes =
Platform.OS === "ios"
@@ -90,7 +89,6 @@ const ReminderNotificationModes = {
export default function AddReminder(props: NavigationProps<"AddReminder">) {
const { reminder, reference } = props.route.params;
useNavigationFocus(props.navigation, { focusOnInit: true });
const { colors, isDark } = useThemeColors();
const [reminderMode, setReminderMode] = useState<Reminder["mode"]>(
reminder?.mode || "once"

View File

@@ -61,7 +61,6 @@ import {
import { fluidTabsRef } from "../../utils/global-refs";
import { strings } from "@notesnook/intl";
import { i18n } from "@lingui/core";
import { useVaultStatus } from "../../hooks/use-vault-status";
const style: ViewStyle = {
height: "100%",
@@ -198,7 +197,6 @@ const Editor = React.memo(
export default Editor;
const useLockedNoteHandler = () => {
const vaultStatus = useVaultStatus();
const tab = useTabStore((state) => state.getTab(state.currentTab));
const tabRef = useRef(tab);
tabRef.current = tab;
@@ -219,13 +217,15 @@ const useLockedNoteHandler = () => {
useEffect(() => {
(async () => {
const biometry = await BiometricService.isBiometryAvailable();
const fingerprint = await BiometricService.hasInternetCredentials();
useTabStore.setState({
biometryAvailable: !!vaultStatus.isBiometryAvailable,
biometryEnrolled: !!vaultStatus.biometryEnrolled
biometryAvailable: !!biometry,
biometryEnrolled: !!fingerprint
});
syncTabs("biometry");
})();
}, [tab?.id, vaultStatus.biometryEnrolled, vaultStatus.isBiometryAvailable]);
}, [tab?.id]);
useEffect(() => {
const unlockWithBiometrics = async () => {

View File

@@ -59,7 +59,6 @@ export type Settings = {
fontScale: number;
markdownShortcuts: boolean;
features: Record<any, any>;
loggedIn: boolean;
};
export type EditorProps = {

View File

@@ -82,7 +82,6 @@ import { editorState, openInternalLink } from "./utils";
import AddReminder from "../../add-reminder";
import { isFeatureAvailable, useAreFeaturesAvailable } from "@notesnook/common";
import PaywallSheet from "../../../components/sheets/paywall";
import useNavigationStore from "../../../stores/use-navigation-store";
const publishNote = async () => {
const user = useUserStore.getState().user;
@@ -165,7 +164,6 @@ export const useEditorEvents = (
state.timeFormat
]);
const handleBack = useRef<NativeEventSubscription>();
const loggedIn = useUserStore((state) => !!state.user);
const { fontScale } = useWindowDimensions();
const doubleSpacedLines = useSettingStore(
@@ -225,8 +223,7 @@ export const useEditorEvents = (
timeFormat: db.settings?.getTimeFormat(),
fontScale,
markdownShortcuts,
features,
loggedIn
features
});
}, [
fullscreen,
@@ -244,8 +241,7 @@ export const useEditorEvents = (
timeFormat,
loading,
fontScale,
markdownShortcuts,
loggedIn
markdownShortcuts
]);
const onBackPress = useCallback(async () => {
@@ -278,15 +274,7 @@ export const useEditorEvents = (
const onHardwareBackPress = useCallback(() => {
if (fluidTabsRef.current?.page() === "editor") {
if (
useNavigationStore.getState().currentRoute === "ManageTags" ||
useNavigationStore.getState().currentRoute === "LinkNotebooks" ||
useNavigationStore.getState().currentRoute === "AddReminder"
) {
Navigation.goBack();
} else {
onBackPress();
}
onBackPress();
return true;
}
}, [onBackPress]);
@@ -559,17 +547,9 @@ export const useEditorEvents = (
if (editor.state.current?.isFocused) {
editor.state.current.isFocused = true;
}
if (editorMessage.value.feature === "insertAttachment") {
ToastManager.show({
type: "info",
message: strings.loginRequired()
});
} else {
PaywallSheet.present(
await isFeatureAvailable(editorMessage.value.feature)
);
}
PaywallSheet.present(
await isFeatureAvailable(editorMessage.value.feature)
);
break;
case EditorEvents.monograph:
publishNote();

View File

@@ -19,7 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import { strings } from "@notesnook/intl";
import { useThemeColors } from "@notesnook/theme";
import React, { useRef, useState } from "react";
import React, { useRef } from "react";
import { View } from "react-native";
import { TextInput } from "react-native-gesture-handler";
import { IconButton } from "../../components/ui/icon-button";
@@ -36,7 +36,6 @@ export const SearchBar = ({
onChangeText: (value: string) => void;
loading?: boolean;
}) => {
const [clearButton, setClearButton] = useState(false);
const selectionMode = useSelectionStore((state) => state.selectionMode);
const isFocused = useNavigationStore(
(state) => state.focusedRouteId === "Search"
@@ -46,7 +45,6 @@ export const SearchBar = ({
const inputRef = useRef<TextInput>(null);
const _onChangeText = (value: string) => {
onChangeText(value);
setClearButton(!!value);
};
return selectionMode && isFocused ? null : (
@@ -86,7 +84,7 @@ export const SearchBar = ({
testID="search-input"
style={{
fontSize: AppFontSize.sm,
fontFamily: "Inter-Regular",
fontFamily: "OpenSans-Regular",
flexGrow: 1,
color: colors.primary.paragraph,
paddingTop: 0,
@@ -102,23 +100,6 @@ export const SearchBar = ({
autoCorrect={false}
placeholderTextColor={colors.primary.placeholder}
/>
{clearButton ? (
<IconButton
name="close"
size={AppFontSize.xxl}
top={10}
testID="clear-search"
bottom={10}
onPress={() => {
inputRef.current?.clear();
onChangeText("");
setClearButton(false);
}}
color={colors.primary.paragraph}
type="plain"
/>
) : null}
</View>
</View>
);

View File

@@ -43,7 +43,6 @@ import { ServersConfiguration } from "./server-config";
import SoundPicker from "./sound-picker";
import ThemeSelector from "./theme-selector";
import { TitleFormat } from "./title-format";
import { NotesnookCircle } from "./notesnook-circle";
export const components: { [name: string]: ReactElement } = {
homeselector: <HomePicker />,
@@ -70,6 +69,5 @@ export const components: { [name: string]: ReactElement } = {
),
"sidebar-tab-selector": <SidebarTabPicker />,
"change-password": <ChangePassword />,
"change-email": <ChangeEmail />,
"notesnook-circle": <NotesnookCircle />
"change-email": <ChangeEmail />
};

View File

@@ -185,7 +185,7 @@ export default function DebugLogs() {
paragraph: strings.clearLogsConfirmation(currentLog.key),
negativeText: strings.cancel(),
positiveText: strings.clear(),
positivePress: async () => {
positivePress: () => {
const index = logs.findIndex((l) => (l.key = currentLog.key));
logManager?.delete(currentLog.key);
if (logs.length > 1) {

View File

@@ -1,213 +0,0 @@
import { CirclePartner, SubscriptionStatus } from "@notesnook/core";
import { strings } from "@notesnook/intl";
import { useThemeColors } from "@notesnook/theme";
import Clipboard from "@react-native-clipboard/clipboard";
import { useState } from "react";
import { useAsync } from "react-async-hook";
import {
ActivityIndicator,
Image,
ScrollView,
TouchableOpacity,
View
} from "react-native";
import { db } from "../../common/database";
import AppIcon from "../../components/ui/AppIcon";
import { Button } from "../../components/ui/button";
import { Notice } from "../../components/ui/notice";
import Heading from "../../components/ui/typography/heading";
import Paragraph from "../../components/ui/typography/paragraph";
import { ToastManager } from "../../services/event-manager";
import Navigation from "../../services/navigation";
import PremiumService from "../../services/premium";
import { useUserStore } from "../../stores/use-user-store";
import { AppFontSize, defaultBorderRadius } from "../../utils/size";
import { DefaultAppStyles } from "../../utils/styles";
import { openLinkInBrowser } from "../../utils/functions";
import { Pressable } from "../../components/ui/pressable";
export const NotesnookCircle = () => {
const user = useUserStore((state) => state.user);
const isOnTrial =
PremiumService.get() &&
user?.subscription?.status === SubscriptionStatus.TRIAL;
const isFree = !PremiumService.get();
const partners = useAsync(db.circle.partners, []);
return (
<ScrollView
contentContainerStyle={{
gap: DefaultAppStyles.GAP_VERTICAL,
paddingHorizontal: DefaultAppStyles.GAP,
paddingTop: DefaultAppStyles.GAP_VERTICAL
}}
>
{!isFree && !isOnTrial ? null : (
<View>
<Paragraph>
{isFree
? strings.freeUserCircleNotice()
: strings.trialUserCircleNotice()}
</Paragraph>
{!isOnTrial ? null : (
<Button
title={strings.upgradePlan()}
onPress={() => {
Navigation.navigate("PayWall", {
canGoBack: true,
context: useUserStore.getState().user
? "logged-in"
: "logged-out"
});
}}
style={{
alignSelf: "flex-start",
paddingHorizontal: 0
}}
/>
)}
</View>
)}
{partners.loading ? <ActivityIndicator /> : null}
{partners.error ? (
<Notice type="alert" text={partners.error.message} />
) : null}
{partners.result?.map((item) => (
<Partner item={item} available={!isFree && !isOnTrial} />
))}
</ScrollView>
);
};
const Partner = ({
item,
available
}: {
item: CirclePartner;
available: boolean;
}) => {
const { colors } = useThemeColors();
const [code, setCode] = useState<string>();
return (
<View
style={{
borderRadius: defaultBorderRadius,
borderWidth: 1,
borderColor: colors.primary.border,
padding: DefaultAppStyles.GAP,
gap: DefaultAppStyles.GAP_VERTICAL
}}
>
<View
style={{
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center"
}}
>
<Heading>{item.name}</Heading>
<Image
src={item.logoBase64}
style={{
width: 40,
height: 40
}}
/>
</View>
<Paragraph style={{ textAlign: "justify" }}>
{item.longDescription.trim()}
</Paragraph>
<Paragraph
style={{
alignSelf: "center"
}}
color={colors.primary.accent}
>
{item.offerDescription}
</Paragraph>
{available ? (
<>
{!code ? (
<Button
type="accent"
title={strings.redeemCode()}
width="100%"
onPress={() => {
if (!PremiumService.get()) {
Navigation.navigate("PayWall", {
canGoBack: true,
context: useUserStore.getState().user
? "logged-in"
: "logged-out"
});
return;
}
db.circle
.redeem(item.id)
.then((result) => setCode(result?.code))
.catch((e) => ToastManager.error(e));
}}
/>
) : (
<>
<TouchableOpacity
style={{
backgroundColor: colors.secondary.background,
borderRadius: defaultBorderRadius,
alignItems: "center",
justifyContent: "center",
padding: DefaultAppStyles.GAP_SMALL,
borderWidth: 0.5,
borderColor: colors.secondary.border,
flexDirection: "row",
gap: DefaultAppStyles.GAP_SMALL
}}
activeOpacity={0.9}
onPress={() => {
Clipboard.setString(code);
}}
>
<Paragraph
size={AppFontSize.lg}
color={colors.secondary.paragraph}
>
{code}
</Paragraph>
<AppIcon name="content-copy" />
</TouchableOpacity>
{item.codeRedeemUrl ? (
<Pressable
onPress={() => {
if (item.codeRedeemUrl) {
openLinkInBrowser(
item.codeRedeemUrl.replace("{{code}}", code)
);
}
}}
>
<Paragraph
color={colors.secondary.paragraph}
size={AppFontSize.xxs}
>
{strings.clickToDirectlyClaimPromo()}
</Paragraph>
</Pressable>
) : null}
</>
)}
</>
) : null}
</View>
);
};

View File

@@ -322,7 +322,6 @@ export const RestoreBackup = () => {
});
setFiles(files);
setLoading(false);
BACKUP_FILES_CACHE.splice(0, BACKUP_FILES_CACHE.length, ...files);
} catch (e) {
e;
@@ -520,11 +519,7 @@ const BackupItem = ({
paddingVertical: DefaultAppStyles.GAP_VERTICAL
}}
>
<View
style={{
flexShrink: 1
}}
>
<View>
<Paragraph size={AppFontSize.sm}>{itemName}</Paragraph>
<Paragraph
size={AppFontSize.xs}

View File

@@ -26,17 +26,18 @@ import {
import React, { useEffect, useRef, useState } from "react";
import { ActivityIndicator, TextInput, View } from "react-native";
import Icon from "react-native-vector-icons/MaterialCommunityIcons";
import { FeatureResult, useIsFeatureAvailable } from "@notesnook/common";
//@ts-ignore
import { FeatureResult, useIsFeatureAvailable } from "@notesnook/common";
import { strings } from "@notesnook/intl";
import ToggleSwitch from "toggle-switch-react-native";
import PaywallSheet from "../../components/sheets/paywall";
import AppIcon from "../../components/ui/AppIcon";
import { IconButton } from "../../components/ui/icon-button";
import Input from "../../components/ui/input";
import { Pressable } from "../../components/ui/pressable";
import Seperator from "../../components/ui/seperator";
import Heading from "../../components/ui/typography/heading";
import Paragraph from "../../components/ui/typography/paragraph";
import { ToastManager } from "../../services/event-manager";
import SettingsService from "../../services/settings";
import useNavigationStore from "../../stores/use-navigation-store";
import { SettingStore, useSettingStore } from "../../stores/use-setting-store";
@@ -44,6 +45,7 @@ import { AppFontSize } from "../../utils/size";
import { DefaultAppStyles } from "../../utils/styles";
import { components } from "./components";
import { RouteParams, SettingSection } from "./types";
import AppIcon from "../../components/ui/AppIcon";
const _SectionItem = ({ item }: { item: SettingSection }) => {
const { colors } = useThemeColors();

View File

@@ -32,7 +32,6 @@ import React from "react";
import { Appearance, Linking, Platform } from "react-native";
import { getVersion } from "react-native-device-info";
import * as RNIap from "react-native-iap";
//@ts-ignore
import { enabled } from "react-native-privacy-snapshot";
import ScreenGuardModule from "react-native-screenguard";
import { DatabaseLogger, db } from "../../common/database";
@@ -82,22 +81,15 @@ export const settingsGroups: SettingSection[] = [
{
id: "subscription-status",
useHook: () => useUserStore((state) => state.user),
hidden: (current) => {
const user = current as User;
return (
!user ||
!user.subscription ||
user.subscription.provider === undefined ||
!strings.subscriptionProviderInfo[user?.subscription?.provider] ||
user.subscription?.plan === SubscriptionPlan.FREE
);
},
hidden: (current) =>
!current ||
(current as User).subscription?.plan === SubscriptionPlan.FREE,
name: (current) => {
const user = (current as User) || useUserStore.getState().user;
return (
strings.subscriptionProviderInfo[
user?.subscription?.provider
]?.title() || `Unknown provider id: ${user?.subscription?.provider}`
].title() || "Unknown provider"
);
},
icon: "credit-card",
@@ -107,8 +99,6 @@ export const settingsGroups: SettingSection[] = [
const subscriptionProviderInfo =
strings.subscriptionProviderInfo[user?.subscription?.provider];
if (!subscriptionProviderInfo) return;
const isCurrentPlatform =
(user.subscription?.provider === SubscriptionProvider.APPLE &&
Platform.OS === "ios") ||
@@ -625,14 +615,6 @@ export const settingsGroups: SettingSection[] = [
}
}
]
},
{
id: "notesnook-circle",
name: strings.notesnookCircle(),
icon: "circle-outline",
type: "screen",
description: strings.notesnookCircleDesc(),
component: "notesnook-circle"
}
]
},
@@ -1436,7 +1418,7 @@ export const settingsGroups: SettingSection[] = [
id: "docs-link",
name: strings.documentation(),
modifer: async () => {
Linking.openURL("https://help.notesnook.com/");
Linking.openURL("https://docs.notesnook.com");
},
description: strings.documentationDesc(),
icon: "file-document"

View File

@@ -580,7 +580,7 @@ function openSettingsDialog(context: string) {
positivePress:
Platform.OS === "ios"
? undefined
: async () => {
: () => {
resolve(true);
},
onClose: () => {

View File

@@ -58,7 +58,6 @@ async function setPremiumStatus() {
async function loadProductsAndSubs() {
try {
if (Config.GITHUB_RELEASE === "true") throw new Error("Github release");
if (!subs || subs.length === 0) {
subs = await RNIap.getSubscriptions({
skus: itemSkus

View File

@@ -17,15 +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 { isFeatureAvailable } from "@notesnook/common";
import { Profile, User } from "@notesnook/core";
import create, { State } from "zustand";
import SettingsService from "../services/settings";
import { presentDialog } from "../components/dialog/functions";
import { strings } from "@notesnook/intl";
import { eSendEvent } from "../services/event-manager";
import { eCloseSimpleDialog } from "../utils/events";
import Navigation from "../services/navigation";
export enum SyncStatus {
Passed,
@@ -64,28 +57,6 @@ export const useUserStore = create<UserStore>((set) => ({
setLastSynced: (lastSynced) => set({ lastSynced: lastSynced }),
lockApp: (appLocked) => {
set({ appLocked });
if (!appLocked) {
isFeatureAvailable("appLock").then((feature) => {
if (!feature.isAllowed) {
SettingsService.setProperty("appLockEnabled", false);
setTimeout(() => {
presentDialog({
title: "App Lock Disabled",
paragraph: feature?.error,
positiveText: strings.upgrade(),
negativeText: strings.cancel(),
positivePress: async () => {
eSendEvent(eCloseSimpleDialog);
if (SettingsService.getProperty("serverUrls")) return;
Navigation.navigate("PayWall", {
context: "logged-in"
});
}
});
}, 1000);
}
});
}
},
lastSyncStatus: SyncStatus.Never,
disableAppLockRequests: false,

View File

@@ -33,7 +33,6 @@ import { useNotebookStore } from "../stores/use-notebook-store";
import { useRelationStore } from "../stores/use-relation-store";
import { useTagStore } from "../stores/use-tag-store";
import { eUpdateNoteInEditor } from "./events";
import { unlockVault } from "./unlock-vault";
export function getObfuscatedEmail(email: string) {
if (!email) return "";
@@ -57,7 +56,7 @@ function confirmDeleteAllNotes(
title: strings.doActions.delete.notebook(items.length),
positiveText: strings.delete(),
negativeText: strings.cancel(),
positivePress: async (_inputValue, value) => {
positivePress: (_inputValue, value) => {
setTimeout(() => {
resolve({ delete: true, deleteNotes: value });
});
@@ -99,30 +98,6 @@ export const deleteItems = async (
await db.reminders.remove(...itemIds);
useRelationStore.getState().update();
} else if (type === "note") {
let someNotesLocked = false;
for (const id of itemIds) {
if (
await db.vaults.itemExists({
id: id,
type: "note"
})
) {
someNotesLocked = true;
break;
}
}
if (someNotesLocked) {
const unlocked = await unlockVault({
title: strings.unlockVault(),
paragraph: strings.unlockVaultDesc(),
context: "global",
requirePassword: true
});
if (!unlocked) return;
}
for (const id of itemIds) {
if (db.monographs.isPublished(id)) {
ToastManager.show({
@@ -133,7 +108,6 @@ export const deleteItems = async (
});
continue;
}
await db.notes.moveToTrash(id);
eSendEvent(
@@ -183,7 +157,7 @@ export const deleteItems = async (
heading: message,
type: "success",
func: async () => {
await db.trash.restore(...deletedIds);
if ((await db.trash.restore(...deletedIds)) === false) return;
Navigation.queueRoutesForUpdate();
useMenuStore.getState().setMenuPins();
useMenuStore.getState().setColorNotes();

View File

@@ -27,20 +27,18 @@ let unlockPromise: Promise<any> | undefined = undefined;
export async function unlockVault({
context,
title,
paragraph,
requirePassword
paragraph
}: {
context?: string;
title: string;
paragraph: string;
requirePassword?: boolean;
}) {
if (unlockPromise) {
return unlockPromise;
}
unlockPromise = new Promise(async (resolve) => {
const result = await (async () => {
if (db.vault.unlocked && !requirePassword) return true;
if (db.vault.unlocked) return true;
const biometry = await BiometricService.isBiometryAvailable();
const fingerprint = await BiometricService.hasInternetCredentials();
if (biometry && fingerprint) {

View File

@@ -1,5 +1,5 @@
import { execSync } from "child_process";
//@ts-ignore
import { pathExists, ensureDir } from "fs-extra";
import { resolveConfig } from "detox/internals";

View File

@@ -1,3 +1,22 @@
/*
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 { notesnook } from "../test.ids";
import { TestBuilder } from "./utils";

View File

@@ -28,9 +28,6 @@ describe("Search", () => {
.typeTextById("search-input", "Test")
.wait(1000)
.isVisibleByText("1")
.waitAndTapById("clear-search")
.wait(2000)
.isNotVisibleByText("1")
.run();
});
});

View File

@@ -20,7 +20,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import { expect as jestExpect } from "@jest/globals";
import { device as _device, expect } from "detox";
import { readFileSync } from "fs";
//@ts-ignore
import { toMatchImageSnapshot } from "jest-image-snapshot";
import type { RouteName } from "../../app/stores/use-navigation-store";
import { notesnook } from "../test.ids";

View File

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

View File

@@ -152,7 +152,7 @@
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="notesnook" />
<data android:scheme="com.streetwriters.notesnook" />
</intent-filter>
</activity>

View File

@@ -33,7 +33,7 @@ public class NotePreviewWidget extends AppWidgetProvider {
intent.putExtra(OpenNoteId, note.getId());
intent.setAction(Intent.ACTION_VIEW);
intent.putExtra(RCTNNativeModule.IntentType, "OpenNote");
intent.setData(Uri.parse("https://app.notesnook.com/open_note?id=" + note.getId()));
intent.setData(Uri.parse("https://notesnook.com/open_note?id=" + note.getId()));
PendingIntent pendingIntent = PendingIntent.getActivity(context, appWidgetId, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE, getActivityOptionsBundle());
views.setOnClickPendingIntent(R.id.open_note, pendingIntent);

View File

@@ -75,7 +75,7 @@ class ReminderRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactor
final Intent fillInIntent = new Intent();
final Bundle extras = new Bundle();
extras.putString(ReminderViewsService.OpenReminderId, reminder.getId());
fillInIntent.setData(Uri.parse("https://app.notesnook.com/open_reminder?id=" + reminder.getId()));
fillInIntent.setData(Uri.parse("https://notesnook.com/open_reminder?id=" + reminder.getId()));
fillInIntent.putExtra(RCTNNativeModule.IntentType, "OpenReminder");
fillInIntent.putExtras(extras);
views.setOnClickFillInIntent(R.id.reminder_item_btn, fillInIntent);

View File

@@ -43,7 +43,7 @@ public class ReminderWidgetProvider extends AppWidgetProvider {
new_reminder_intent.putExtra(NewReminder, NewReminder);
new_reminder_intent.setAction(Intent.ACTION_VIEW);
new_reminder_intent.putExtra(RCTNNativeModule.IntentType, "NewReminder");
new_reminder_intent.setData(Uri.parse("https://app.notesnook.com/new_reminder"));
new_reminder_intent.setData(Uri.parse("https://notesnook.com/new_reminder"));
PendingIntent pendingIntent2 = PendingIntent.getActivity(context, appWidgetId, new_reminder_intent, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE, getActivityOptionsBundle());
views.setOnClickPendingIntent(R.id.add_button, pendingIntent2);

View File

@@ -2,7 +2,6 @@
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingVertical="10dp"
android:id="@+id/reminder_item_btn">
<TextView

View File

@@ -2,7 +2,6 @@
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingVertical="10dp"
android:id="@+id/reminder_item_btn">
<TextView

View File

@@ -25,9 +25,9 @@
android:text="Upcoming Reminders"/>
<ImageButton
android:layout_width="35dp"
android:layout_width="30dp"
android:id="@+id/add_button"
android:layout_height="35dp"
android:layout_height="30dp"
android:layout_alignParentRight="true"
android:background="@drawable/ic_newnote" />
</RelativeLayout>

View File

@@ -1,3 +1,5 @@
- Bug fixes and minor improvements
- We have launches new pricing plans, Essential, Pro and Believer
- Free users can now upload attachments and create private vault
- Minor bug fixes and improvements
Thank you for using Notesnook!

View File

@@ -56,10 +56,9 @@
<string>group.org.streetwriters.notesnook</string>
<key>UIAppFonts</key>
<array>
<string>Inter-Bold.ttf</string>
<string>Inter-SemiBold.ttf</string>
<string>Inter-Regular.ttf</string>
<string>Inter-Italic.ttf</string>
<string>OpenSans-Bold.ttf</string>
<string>OpenSans-SemiBold.ttf</string>
<string>OpenSans-Regular.ttf</string>
<string>MaterialCommunityIcons.ttf</string>
</array>
<key>UISupportedInterfaceOrientations</key>

View File

@@ -17,15 +17,14 @@
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 */; };
6517B7C22B6838EB0079FF37 /* OpenSans-SemiBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 6517B7BF2B6838EB0079FF37 /* OpenSans-SemiBold.ttf */; };
6517B7C32B6838EB0079FF37 /* OpenSans-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 6517B7C02B6838EB0079FF37 /* OpenSans-Bold.ttf */; };
6529A13E279BC4C70048D4A8 /* BootSplash.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6529A13D279BC4C70048D4A8 /* BootSplash.storyboard */; };
653F4E082EA3887C009A42A2 /* Inter-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 653F4E042EA3887C009A42A2 /* Inter-Bold.ttf */; };
653F4E092EA3887C009A42A2 /* Inter-Italic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 653F4E052EA3887C009A42A2 /* Inter-Italic.ttf */; };
653F4E0A2EA3887C009A42A2 /* Inter-SemiBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 653F4E072EA3887C009A42A2 /* Inter-SemiBold.ttf */; };
653F4E0B2EA3887C009A42A2 /* Inter-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 653F4E062EA3887C009A42A2 /* Inter-Regular.ttf */; };
653F4E0C2EA3887C009A42A2 /* Inter-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 653F4E042EA3887C009A42A2 /* Inter-Bold.ttf */; };
653F4E0D2EA3887C009A42A2 /* Inter-Italic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 653F4E052EA3887C009A42A2 /* Inter-Italic.ttf */; };
653F4E0E2EA3887C009A42A2 /* Inter-SemiBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 653F4E072EA3887C009A42A2 /* Inter-SemiBold.ttf */; };
653F4E0F2EA3887C009A42A2 /* Inter-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 653F4E062EA3887C009A42A2 /* Inter-Regular.ttf */; };
656835812BB29A9800144BAB /* OpenSans-Italic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 656835802BB29A8300144BAB /* OpenSans-Italic.ttf */; };
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 */; };
@@ -118,12 +117,12 @@
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>"; };
6515C42E2580AA2F00E83E39 /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = System/Library/Frameworks/StoreKit.framework; sourceTree = SDKROOT; };
6517B7BE2B6838EB0079FF37 /* OpenSans-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "OpenSans-Regular.ttf"; path = "../../../../packages/editor-mobile/public/fonts/OpenSans-Regular.ttf"; sourceTree = "<group>"; };
6517B7BF2B6838EB0079FF37 /* OpenSans-SemiBold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "OpenSans-SemiBold.ttf"; path = "../../../../packages/editor-mobile/public/fonts/OpenSans-SemiBold.ttf"; sourceTree = "<group>"; };
6517B7C02B6838EB0079FF37 /* OpenSans-Bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "OpenSans-Bold.ttf"; path = "../../../../packages/editor-mobile/public/fonts/OpenSans-Bold.ttf"; sourceTree = "<group>"; };
6529A13D279BC4C70048D4A8 /* BootSplash.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = BootSplash.storyboard; path = Notesnook/BootSplash.storyboard; sourceTree = "<group>"; };
6529D2B0257B4A2900B49BC3 /* NotesnookDebug.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = NotesnookDebug.entitlements; path = Notesnook/NotesnookDebug.entitlements; sourceTree = "<group>"; };
653F4E042EA3887C009A42A2 /* Inter-Bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "Inter-Bold.ttf"; path = "../../../../packages/editor-mobile/public/fonts/Inter-Bold.ttf"; sourceTree = SOURCE_ROOT; };
653F4E052EA3887C009A42A2 /* Inter-Italic.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "Inter-Italic.ttf"; path = "../../../../packages/editor-mobile/public/fonts/Inter-Italic.ttf"; sourceTree = SOURCE_ROOT; };
653F4E062EA3887C009A42A2 /* Inter-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "Inter-Regular.ttf"; path = "../../../../packages/editor-mobile/public/fonts/Inter-Regular.ttf"; sourceTree = SOURCE_ROOT; };
653F4E072EA3887C009A42A2 /* Inter-SemiBold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "Inter-SemiBold.ttf"; path = "../../../../packages/editor-mobile/public/fonts/Inter-SemiBold.ttf"; sourceTree = SOURCE_ROOT; };
656835802BB29A8300144BAB /* OpenSans-Italic.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "OpenSans-Italic.ttf"; path = "../../../../packages/editor-mobile/public/fonts/OpenSans-Italic.ttf"; sourceTree = "<group>"; };
6593E4A2281C345400492C50 /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = Notesnook/AppDelegate.mm; sourceTree = "<group>"; };
659BE46625E11A5100E05671 /* notesnook-text.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "notesnook-text.png"; path = "Notesnook/Images.xcassets/notesnook-text.png"; sourceTree = "<group>"; };
65A7F34F255689AD00699170 /* Notesnook.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = Notesnook.entitlements; path = Notesnook/Notesnook.entitlements; sourceTree = "<group>"; };
@@ -304,10 +303,10 @@
83CBB9F61A601CBA00E9B192 = {
isa = PBXGroup;
children = (
653F4E042EA3887C009A42A2 /* Inter-Bold.ttf */,
653F4E052EA3887C009A42A2 /* Inter-Italic.ttf */,
653F4E062EA3887C009A42A2 /* Inter-Regular.ttf */,
653F4E072EA3887C009A42A2 /* Inter-SemiBold.ttf */,
656835802BB29A8300144BAB /* OpenSans-Italic.ttf */,
6517B7C02B6838EB0079FF37 /* OpenSans-Bold.ttf */,
6517B7BE2B6838EB0079FF37 /* OpenSans-Regular.ttf */,
6517B7BF2B6838EB0079FF37 /* OpenSans-SemiBold.ttf */,
65C400DD2A80B68D00AA3DF5 /* MaterialCommunityIcons.ttf */,
65C149862A61151B005C40F1 /* extension.bundle */,
6510E6D62877215700DACAA9 /* build.bundle */,
@@ -556,15 +555,15 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
656835812BB29A9800144BAB /* OpenSans-Italic.ttf in Resources */,
65C400DE2A80B68D00AA3DF5 /* MaterialCommunityIcons.ttf in Resources */,
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
6517B7C32B6838EB0079FF37 /* OpenSans-Bold.ttf in Resources */,
6517B7C22B6838EB0079FF37 /* OpenSans-SemiBold.ttf in Resources */,
6529A13E279BC4C70048D4A8 /* BootSplash.storyboard in Resources */,
6510E6D72877215700DACAA9 /* build.bundle in Resources */,
6517B7C12B6838EB0079FF37 /* OpenSans-Regular.ttf in Resources */,
659BE46725E11A5100E05671 /* notesnook-text.png in Resources */,
653F4E0C2EA3887C009A42A2 /* Inter-Bold.ttf in Resources */,
653F4E0D2EA3887C009A42A2 /* Inter-Italic.ttf in Resources */,
653F4E0E2EA3887C009A42A2 /* Inter-SemiBold.ttf in Resources */,
653F4E0F2EA3887C009A42A2 /* Inter-Regular.ttf in Resources */,
E7F9D56665C2F19F4A97BF49 /* PrivacyInfo.xcprivacy in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -597,11 +596,10 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
6569927F2C5754F10041CD41 /* OpenSans-Bold.ttf in Resources */,
656992802C5754F10041CD41 /* OpenSans-Regular.ttf in Resources */,
656992812C5754F10041CD41 /* OpenSans-SemiBold.ttf in Resources */,
65C400DF2A80B6B600AA3DF5 /* MaterialCommunityIcons.ttf in Resources */,
653F4E082EA3887C009A42A2 /* Inter-Bold.ttf in Resources */,
653F4E092EA3887C009A42A2 /* Inter-Italic.ttf in Resources */,
653F4E0A2EA3887C009A42A2 /* Inter-SemiBold.ttf in Resources */,
653F4E0B2EA3887C009A42A2 /* Inter-Regular.ttf in Resources */,
65C149872A61151B005C40F1 /* extension.bundle in Resources */,
65B5014725A672B200E2D264 /* MainInterface.storyboard in Resources */,
);
@@ -654,7 +652,6 @@
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Notesnook/Pods-Notesnook-resources.sh",
"${PODS_CONFIGURATION_BUILD_DIR}/RCT-Folly/RCT-Folly_privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/RNImageCropPickerPrivacyInfo.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/QBImagePicker.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/RNSVG/RNSVGFilters.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/React-Core_privacy.bundle",
@@ -666,7 +663,6 @@
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCT-Folly_privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNImageCropPickerPrivacyInfo.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/QBImagePicker.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNSVGFilters.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/React-Core_privacy.bundle",
@@ -823,7 +819,6 @@
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Notesnook-NotesnookTests/Pods-Notesnook-NotesnookTests-resources.sh",
"${PODS_CONFIGURATION_BUILD_DIR}/RCT-Folly/RCT-Folly_privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/RNImageCropPickerPrivacyInfo.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/QBImagePicker.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/RNSVG/RNSVGFilters.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/React-Core_privacy.bundle",
@@ -835,7 +830,6 @@
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCT-Folly_privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNImageCropPickerPrivacyInfo.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/QBImagePicker.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNSVGFilters.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/React-Core_privacy.bundle",
@@ -1095,7 +1089,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2157;
CURRENT_PROJECT_VERSION = 2150;
DEVELOPMENT_TEAM = 53CWBG3QUC;
ENABLE_BITCODE = NO;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
@@ -1169,7 +1163,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 3.3.9;
MARKETING_VERSION = 3.3.2;
OTHER_LDFLAGS = (
"$(inherited)",
"-ObjC",
@@ -1200,7 +1194,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 2157;
CURRENT_PROJECT_VERSION = 2150;
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 53CWBG3QUC;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
@@ -1274,7 +1268,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 3.3.9;
MARKETING_VERSION = 3.3.2;
ONLY_ACTIVE_ARCH = NO;
OTHER_LDFLAGS = (
"$(inherited)",
@@ -1433,7 +1427,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2157;
CURRENT_PROJECT_VERSION = 2150;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = 53CWBG3QUC;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
@@ -1445,7 +1439,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 3.3.9;
MARKETING_VERSION = 3.3.2;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.notewidget;
@@ -1476,7 +1470,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 2157;
CURRENT_PROJECT_VERSION = 2150;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 53CWBG3QUC;
@@ -1489,7 +1483,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 3.3.9;
MARKETING_VERSION = 3.3.2;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.notewidget;
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -1519,7 +1513,7 @@
CODE_SIGN_ENTITLEMENTS = "Make Note/Make Note.entitlements";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2157;
CURRENT_PROJECT_VERSION = 2150;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = 53CWBG3QUC;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
@@ -1593,14 +1587,14 @@
"\"$(PODS_ROOT)/Headers/Private/React-Core\"",
);
INFOPLIST_FILE = "Make Note/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 12.4;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
LIBRARY_SEARCH_PATHS = "$(SDKROOT)/usr/lib/swift$(inherited)";
MARKETING_VERSION = 3.3.9;
MARKETING_VERSION = 3.3.2;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.share;
@@ -1631,7 +1625,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 2157;
CURRENT_PROJECT_VERSION = 2150;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 53CWBG3QUC;
@@ -1706,14 +1700,14 @@
"\"$(PODS_ROOT)/Headers/Private/React-Core\"",
);
INFOPLIST_FILE = "Make Note/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 12.4;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
LIBRARY_SEARCH_PATHS = "$(SDKROOT)/usr/lib/swift$(inherited)";
MARKETING_VERSION = 3.3.9;
MARKETING_VERSION = 3.3.2;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.share;
PRODUCT_NAME = "$(TARGET_NAME)";

View File

@@ -74,7 +74,7 @@
<RemoteRunnable
runnableDebuggingMode = "1"
BundleIdentifier = "com.apple.mobilesafari"
RemotePath = "/Library/Developer/CoreSimulator/Volumes/iOS_22G86/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.6.simruntime/Contents/Resources/RuntimeRoot/Applications/MobileSafari.app">
RemotePath = "/Applications/MobileSafari.app">
</RemoteRunnable>
<MacroExpansion>
<BuildableReference
@@ -92,7 +92,6 @@
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES"
askForAppToLaunch = "Yes"
launchAutomaticallySubstyle = "2">
<BuildableProductRunnable
runnableDebuggingMode = "0">

View File

@@ -71,6 +71,7 @@
<true/>
<key>NSAppTransportSecurity</key>
<dict>
<!-- Do not change NSAllowsArbitraryLoads to true, or you will risk app rejection! -->
<key>NSAllowsArbitraryLoads</key>
<false/>
<key>NSAllowsLocalNetworking</key>
@@ -88,10 +89,9 @@
<string>group.org.streetwriters.notesnook</string>
<key>UIAppFonts</key>
<array>
<string>Inter-Italic.ttf</string>
<string>Inter-SemiBold.ttf</string>
<string>Inter-Regular.ttf</string>
<string>Inter-Bold.ttf</string>
<string>OpenSans-Italic.ttf</string>
<string>OpenSans-SemiBold.ttf</string>
<string>OpenSans-Regular.ttf</string>
<string>MaterialCommunityIcons.ttf</string>
</array>
<key>UIApplicationSceneManifest</key>

View File

@@ -9,7 +9,6 @@
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>3B52.1</string>
<string>C617.1</string>
</array>
</dict>

View File

@@ -1273,11 +1273,11 @@ PODS:
- React-Core
- react-native-keep-awake (1.3.1):
- React-Core
- react-native-mmkv-storage (12.0.0):
- react-native-mmkv-storage (0.11.2):
- DoubleConversion
- glog
- hermes-engine
- MMKV (~> 1.3.14)
- MMKV (~> 1.3.9)
- RCT-Folly (= 2024.11.18.00)
- RCTRequired
- RCTTypeSafety
@@ -1372,7 +1372,7 @@ PODS:
- react-native-screenguard (1.0.0):
- React-Core
- SDWebImage (~> 5.11.1)
- react-native-share-extension (2.9.5):
- react-native-share-extension (2.9.0):
- React
- react-native-sodium (1.6.5):
- React
@@ -1770,53 +1770,15 @@ PODS:
- Yoga
- RNIap (12.16.2):
- React-Core
- RNImageCropPicker (0.51.1):
- DoubleConversion
- glog
- hermes-engine
- RCT-Folly (= 2024.11.18.00)
- RCTRequired
- RCTTypeSafety
- RNImageCropPicker (0.40.2):
- React-Core
- React-debug
- React-Fabric
- React-featureflags
- React-graphics
- React-ImageManager
- React-NativeModulesApple
- React-RCTFabric
- React-RCTImage
- React-rendererdebug
- React-utils
- ReactCodegen
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- RNImageCropPicker/QBImagePickerController (= 0.51.1)
- TOCropViewController (~> 2.8.0)
- Yoga
- RNImageCropPicker/QBImagePickerController (0.51.1):
- DoubleConversion
- glog
- hermes-engine
- RCT-Folly (= 2024.11.18.00)
- RCTRequired
- RCTTypeSafety
- RNImageCropPicker/QBImagePickerController (= 0.40.2)
- TOCropViewController
- RNImageCropPicker/QBImagePickerController (0.40.2):
- React-Core
- React-debug
- React-Fabric
- React-featureflags
- React-graphics
- React-ImageManager
- React-NativeModulesApple
- React-RCTFabric
- React-RCTImage
- React-rendererdebug
- React-utils
- ReactCodegen
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- TOCropViewController (~> 2.8.0)
- Yoga
- TOCropViewController
- RNKeychain (4.0.5):
- React
- RNNotifee (7.4.9):
@@ -2013,7 +1975,7 @@ PODS:
- SwiftyRSA (1.7.0):
- SwiftyRSA/ObjC (= 1.7.0)
- SwiftyRSA/ObjC (1.7.0)
- TOCropViewController (2.8.0)
- TOCropViewController (2.7.4)
- toolbar-android (0.2.1):
- React
- Yoga (0.0.0)
@@ -2463,7 +2425,7 @@ SPEC CHECKSUMS:
react-native-image-resizer: 24c5d06fae2176dc0caed4b6396e02befb44064a
react-native-in-app-review: b3d1eed3d1596ebf6539804778272c4c65e4a400
react-native-keep-awake: 03b74eebe4f2bb5e8478fc8f420651a92463b6f8
react-native-mmkv-storage: 935d661dc3913a41be70d041aa3ff860d6aa4873
react-native-mmkv-storage: 51c33c6f6678d67061059cce8189a57c3e47192e
react-native-netinfo: 66c9ac0d0ae92a57a9ed99ab8a75429740700c73
react-native-notification-sounds: ce106d58df0dd384bccbd2e84fb53accab7cc068
react-native-orientation-locker: cc6f357b289a2e0dd2210fea0c52cb8e0727fdaa
@@ -2472,7 +2434,7 @@ SPEC CHECKSUMS:
react-native-quick-sqlite: 1bfc7f1e9acbe9a5aa5c4cc81712e9bde3ab7672
react-native-safe-area-context: 9d72abf6d8473da73033b597090a80b709c0b2f1
react-native-screenguard: 82437eeb0086a90b5e5d7e54130bb04fb406373e
react-native-share-extension: fdc6aaab51591a2d445df239c446aaa3a99658ec
react-native-share-extension: bcb7e466390a9e50c742f4b1019d6f181aedd7ad
react-native-sodium: 285eec063e4232cb67347ef6a434b85e588d38cb
react-native-theme-switch-animation: d90fe2de0d9e87a63cd6235d98cba6e7054e9a10
react-native-webview: 079eca50edf657503318b66687dadfb903731aa8
@@ -2517,7 +2479,7 @@ SPEC CHECKSUMS:
RNFlashList: ff5a0b3113c4cda0eaf4b94df8572ccad3c40fd5
RNGestureHandler: 92e89a04cd0d1c77f383a55d14c15e7f423f4c00
RNIap: f94647b3a3dbd5fa08ad7ed847eb588aa5fe95fe
RNImageCropPicker: aa81bda9f887e20542b569938cde5ce50a4ec404
RNImageCropPicker: 30d770b383d84e1067d82ea7b5ed4fff851bbbb2
RNKeychain: ffd0513e676445c637410b47249460cbf56bc9cb
RNNotifee: dabf3cdd7bfd9340bb84358cc78f635af4bc80e2
RNPrivacySnapshot: ccad3a548338c2f526bb7b1789af3fb0618b7d1d
@@ -2533,7 +2495,7 @@ SPEC CHECKSUMS:
SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
SSZipArchive: fe6a26b2a54d5a0890f2567b5cc6de5caa600aef
SwiftyRSA: 8c6dd1ea7db1b8dc4fb517a202f88bb1354bc2c6
TOCropViewController: 797deaf39c90e6e9ddd848d88817f6b9a8a09888
TOCropViewController: 80b8985ad794298fb69d3341de183f33d1853654
toolbar-android: c426ed5bd3dcccfed20fd79533efc0d1ae0ef018
Yoga: 31a098f74c16780569aebd614a0f37a907de0189

File diff suppressed because one or more lines are too long

View File

@@ -21,7 +21,6 @@
"@react-navigation/native": "^6.0.10",
"@react-navigation/native-stack": "6.6.2",
"@sayem314/react-native-keep-awake": "^1.3.1",
"react-native-image-crop-picker": "^0.51.1",
"react": "18.2.0",
"react-native": "0.77.2",
"react-native-actions-shortcuts": "^1.0.1",
@@ -49,7 +48,7 @@
"react-native-navigation-bar-color": "2.0.2",
"react-native-notification-sounds": "0.5.5",
"@shopify/flash-list": "^1.8.0",
"react-native-mmkv-storage": "^12.0.0",
"react-native-mmkv-storage": "^0.11.2",
"react-native-quick-sqlite": "^8.2.7",
"react-native-svg": "^15.12.0",
"react-native-webview": "^13.13.5",
@@ -62,6 +61,7 @@
"react-native-zip-archive": "6.0.9",
"react-native-theme-switch-animation": "^0.6.0",
"@ammarahmed/react-native-background-fetch": "^4.2.2",
"react-native-image-crop-picker": "^0.40.2",
"react-native-url-polyfill": "^2.0.0",
"react-native-screenguard": "^1.0.0",
"@formatjs/intl-locale": "4.0.0",
@@ -72,10 +72,10 @@
"react-native-begin-background-task": "github:blockfirm/react-native-begin-background-task",
"react-native-privacy-snapshot": "github:standardnotes/react-native-privacy-snapshot",
"@ammarahmed/react-native-fingerprint-scanner": "^5.0.0",
"@ammarahmed/react-native-share-extension": "^2.9.0",
"react-native-pager-view": "^6.5.1",
"react-native-tab-view": "^4.0.2",
"react-native-orientation-locker": "^1.7.0",
"@ammarahmed/react-native-share-extension": "^2.9.5"
"react-native-orientation-locker": "^1.7.0"
},
"devDependencies": {
"@babel/core": "^7.27.1",

View File

@@ -1,12 +1,12 @@
{
"name": "@notesnook/mobile",
"version": "3.3.7",
"version": "3.2.12",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@notesnook/mobile",
"version": "3.3.7",
"version": "3.2.12",
"hasInstallScript": true,
"license": "GPL-3.0-or-later",
"workspaces": [
@@ -3730,7 +3730,7 @@
"hasInstallScript": true,
"license": "GPL-3.0-or-later",
"dependencies": {
"@notesnook-importer/core": "^2.2.5",
"@notesnook-importer/core": "^2.2.2",
"@notesnook/common": "file:../common",
"@notesnook/intl": "file:../intl",
"@notesnook/theme": "file:../theme",
@@ -3797,7 +3797,6 @@
"happy-dom": "16.0.1",
"isomorphic-fetch": "^3.0.0",
"nodemon": "^3.1.7",
"prismjs": "^1.30.0",
"prosemirror-test-builder": "^1.1.1",
"react": "18.3.1",
"react-dom": "18.3.1",
@@ -28297,7 +28296,6 @@
"pathe": "1.1.2",
"phone": "^3.1.14",
"qclone": "^1.2.0",
"react-async-hook": "^4.0.0",
"react-native-actions-sheet": "0.9.7",
"react-native-check-version": "^1.3.0",
"react-native-drax": "^0.10.2",
@@ -28326,7 +28324,7 @@
"@ammarahmed/react-native-background-fetch": "^4.2.2",
"@ammarahmed/react-native-eventsource": "1.1.0",
"@ammarahmed/react-native-fingerprint-scanner": "^5.0.0",
"@ammarahmed/react-native-share-extension": "^2.9.5",
"@ammarahmed/react-native-share-extension": "^2.9.0",
"@ammarahmed/react-native-sodium": "^1.6.5",
"@bam.tech/react-native-image-resizer": "3.0.11",
"@callstack/repack": "~5.1.2",
@@ -28361,10 +28359,10 @@
"react-native-gzip": "1.1.0",
"react-native-html-to-pdf-lite": "^0.9.1",
"react-native-iap": "12.16.2",
"react-native-image-crop-picker": "^0.51.1",
"react-native-image-crop-picker": "^0.40.2",
"react-native-in-app-review": "4.3.3",
"react-native-keychain": "4.0.5",
"react-native-mmkv-storage": "^12.0.0",
"react-native-mmkv-storage": "^0.11.2",
"react-native-modal-datetime-picker": "14.0.0",
"react-native-navigation-bar-color": "2.0.2",
"react-native-notification-sounds": "0.5.5",
@@ -28472,9 +28470,9 @@
}
},
"node_modules/@ammarahmed/react-native-share-extension": {
"version": "2.9.5",
"resolved": "https://registry.npmjs.org/@ammarahmed/react-native-share-extension/-/react-native-share-extension-2.9.5.tgz",
"integrity": "sha512-UTE8TSxkx+RFNgSJCCfD5FSdQ5IuMOsZzuuy0BVy46emRrpPw1fedJTtDbqyKrU8fwtKEIbzJWeQtjjRZlHxjQ==",
"version": "2.9.0",
"resolved": "https://registry.npmjs.org/@ammarahmed/react-native-share-extension/-/react-native-share-extension-2.9.0.tgz",
"integrity": "sha512-iEkpJQFZL5/WDPh7iRCLZREANgaaAHthDsPaAYT6sI4wieQcHZMBAnfRMwBEnC0BZ0WVxbQZdzJYez+dmwpr2g==",
"license": "MIT",
"dependencies": {
"react-native": "^0.63.1"
@@ -44135,19 +44133,6 @@
"node": ">=0.10.0"
}
},
"node_modules/react-async-hook": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/react-async-hook/-/react-async-hook-4.0.0.tgz",
"integrity": "sha512-97lgjFkOcHCTYSrsKBpsXg3iVWM0LnzedB749iP76sb3/8Ouu4nHIkCLEOrQWHVYqrYxjF05NN6GHoXWFkB3Kw==",
"license": "MIT",
"engines": {
"node": ">=8",
"npm": ">=5"
},
"peerDependencies": {
"react": ">=16.8"
}
},
"node_modules/react-devtools-core": {
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-6.1.2.tgz",
@@ -44519,13 +44504,10 @@
}
},
"node_modules/react-native-image-crop-picker": {
"version": "0.51.1",
"resolved": "https://registry.npmjs.org/react-native-image-crop-picker/-/react-native-image-crop-picker-0.51.1.tgz",
"integrity": "sha512-GIFRyXJgv1dPceKd/hraK9q9V38v45rSg2ONR6RiSePcOJemkHpc/PMU86pq6lWPilDYHSxbZmea2pNMk85ayw==",
"version": "0.40.2",
"license": "MIT",
"peerDependencies": {
"react": "*",
"react-native": "*"
"react-native": ">=0.40.0"
}
},
"node_modules/react-native-image-pan-zoom": {
@@ -44593,9 +44575,9 @@
}
},
"node_modules/react-native-mmkv-storage": {
"version": "12.0.0",
"resolved": "https://registry.npmjs.org/react-native-mmkv-storage/-/react-native-mmkv-storage-12.0.0.tgz",
"integrity": "sha512-sssZInILQBquytDDfjosjEdvevwMPk3fqQQjdjfnH362IcsBsApvtT8yJS406Mz9aJ6VhqVsZw/awltsUuPSYg==",
"version": "0.11.2",
"resolved": "https://registry.npmjs.org/react-native-mmkv-storage/-/react-native-mmkv-storage-0.11.2.tgz",
"integrity": "sha512-/jbYNOUrwgVU09WyXDK6lFGXqBs+23oR9X37z3N68rwHNiXF5WDyXnT38dU2tF07ZlvmsobNHgdxgTu4kGQUKQ==",
"license": "MIT",
"bin": {
"mmkv-link": "autolink/postlink/run.js"

View File

@@ -1,6 +1,6 @@
{
"name": "@notesnook/mobile",
"version": "3.3.9",
"version": "3.3.2",
"private": true,
"license": "GPL-3.0-or-later",
"workspaces": [
@@ -56,4 +56,4 @@
"react": "18.2.0",
"react-native": "0.77.2"
}
}
}

View File

@@ -1,27 +1,27 @@
diff --git a/node_modules/react-native-image-crop-picker/android/src/main/java/com/reactnative/ivpusic/imagepicker/ImageCropPicker.java b/node_modules/react-native-image-crop-picker/android/src/main/java/com/reactnative/ivpusic/imagepicker/ImageCropPicker.java
index b9c494e..34ef800 100644
--- a/node_modules/react-native-image-crop-picker/android/src/main/java/com/reactnative/ivpusic/imagepicker/ImageCropPicker.java
+++ b/node_modules/react-native-image-crop-picker/android/src/main/java/com/reactnative/ivpusic/imagepicker/ImageCropPicker.java
@@ -679,6 +679,7 @@ class ImageCropPicker implements ActivityEventListener {
diff --git a/node_modules/react-native-image-crop-picker/android/src/main/java/com/reactnative/ivpusic/imagepicker/PickerModule.java b/node_modules/react-native-image-crop-picker/android/src/main/java/com/reactnative/ivpusic/imagepicker/PickerModule.java
index 5de0845..1b158d8 100644
--- a/node_modules/react-native-image-crop-picker/android/src/main/java/com/reactnative/ivpusic/imagepicker/PickerModule.java
+++ b/node_modules/react-native-image-crop-picker/android/src/main/java/com/reactnative/ivpusic/imagepicker/PickerModule.java
@@ -692,6 +692,7 @@ class PickerModule extends ReactContextBaseJavaModule implements ActivityEventLi
image.putString("mime", options.outMimeType);
image.putInt("size", (int) new File(compressedImagePath).length());
image.putString("modificationDate", String.valueOf(modificationDate));
image.putString("filename", new File(path).getName());
+ image.putString("sourceURL", path);
if (includeBase64) {
image.putString("data", getBase64StringFromFile(compressedImagePath));
diff --git a/node_modules/react-native-image-crop-picker/ios/src/ImageCropPicker.mm b/node_modules/react-native-image-crop-picker/ios/src/ImageCropPicker.mm
index 354ad09..622f779 100644
--- a/node_modules/react-native-image-crop-picker/ios/src/ImageCropPicker.mm
+++ b/node_modules/react-native-image-crop-picker/ios/src/ImageCropPicker.mm
@@ -603,7 +603,10 @@ - (void)qb_imagePickerController:(QBImagePickerController *)imagePickerControlle
diff --git a/node_modules/react-native-image-crop-picker/ios/src/ImageCropPicker.m b/node_modules/react-native-image-crop-picker/ios/src/ImageCropPicker.m
index 9f20973..5e14da8 100644
--- a/node_modules/react-native-image-crop-picker/ios/src/ImageCropPicker.m
+++ b/node_modules/react-native-image-crop-picker/ios/src/ImageCropPicker.m
@@ -595,8 +595,10 @@ - (void)qb_imagePickerController:
NSString *mimeType = [self determineMimeTypeFromImageData:imageData];
Boolean isKnownMimeType = [mimeType length] > 0;
+ Boolean isHeicOrHeif = [mimeType isEqualToString:@"image/heic"] || [mimeType isEqualToString:@"image/heif"];
+
ImageResult *imageResult = [[ImageResult alloc] init];
- if (isLossless && useOriginalWidth && useOriginalHeight && isKnownMimeType && !forceJpg) {
+
+ Boolean isHeicOrHeif = [mimeType isEqualToString:@"image/heic"] || [mimeType isEqualToString:@"image/heif"];
+
+ if (isLossless && useOriginalWidth && useOriginalHeight && isKnownMimeType && !forceJpg && !isHeicOrHeif) {
// Use original, unmodified image
imageResult.data = imageData;

View File

@@ -1,169 +0,0 @@
diff --git a/node_modules/react-native-keychain/android/build.gradle b/node_modules/react-native-keychain/android/build.gradle
index bd2fe04..53ce4b1 100755
--- a/node_modules/react-native-keychain/android/build.gradle
+++ b/node_modules/react-native-keychain/android/build.gradle
@@ -51,5 +51,4 @@ dependencies {
//noinspection GradleDynamicVersion
implementation 'com.facebook.react:react-native:+' // From node_modules
implementation 'androidx.annotation:annotation:1.1.0'
- implementation 'com.facebook.conceal:conceal:1.1.3@aar'
}
diff --git a/node_modules/react-native-keychain/android/src/main/java/com/oblador/keychain/KeychainModule.java b/node_modules/react-native-keychain/android/src/main/java/com/oblador/keychain/KeychainModule.java
index 61d061e..be49f8a 100644
--- a/node_modules/react-native-keychain/android/src/main/java/com/oblador/keychain/KeychainModule.java
+++ b/node_modules/react-native-keychain/android/src/main/java/com/oblador/keychain/KeychainModule.java
@@ -15,7 +15,6 @@ import com.oblador.keychain.PrefsStorage.ResultSet;
import com.oblador.keychain.cipherStorage.CipherStorage;
import com.oblador.keychain.cipherStorage.CipherStorage.DecryptionResult;
import com.oblador.keychain.cipherStorage.CipherStorage.EncryptionResult;
-import com.oblador.keychain.cipherStorage.CipherStorageFacebookConceal;
import com.oblador.keychain.cipherStorage.CipherStorageKeystoreAESCBC;
import com.oblador.keychain.exceptions.CryptoFailedException;
import com.oblador.keychain.exceptions.EmptyParameterException;
@@ -48,7 +47,6 @@ public class KeychainModule extends ReactContextBaseJavaModule {
super(reactContext);
prefsStorage = new PrefsStorage(reactContext);
- addCipherStorageToMap(new CipherStorageFacebookConceal(reactContext));
addCipherStorageToMap(new CipherStorageKeystoreAESCBC());
}
diff --git a/node_modules/react-native-keychain/android/src/main/java/com/oblador/keychain/PrefsStorage.java b/node_modules/react-native-keychain/android/src/main/java/com/oblador/keychain/PrefsStorage.java
index 99448b1..792c24c 100644
--- a/node_modules/react-native-keychain/android/src/main/java/com/oblador/keychain/PrefsStorage.java
+++ b/node_modules/react-native-keychain/android/src/main/java/com/oblador/keychain/PrefsStorage.java
@@ -7,7 +7,6 @@ import android.util.Base64;
import com.facebook.react.bridge.ReactApplicationContext;
import com.oblador.keychain.cipherStorage.CipherStorage.EncryptionResult;
-import com.oblador.keychain.cipherStorage.CipherStorageFacebookConceal;
public class PrefsStorage {
public static final String KEYCHAIN_DATA = "RN_KEYCHAIN";
@@ -35,10 +34,6 @@ public class PrefsStorage {
byte[] bytesForPassword = getBytesForPassword(service);
String cipherStorageName = getCipherStorageName(service);
if (bytesForUsername != null && bytesForPassword != null) {
- if (cipherStorageName == null) {
- // If the CipherStorage name is not found, we assume it is because the entry was written by an older version of this library. The older version used Facebook Conceal, so we default to that.
- cipherStorageName = CipherStorageFacebookConceal.CIPHER_STORAGE_NAME;
- }
return new ResultSet(cipherStorageName, bytesForUsername, bytesForPassword);
}
return null;
diff --git a/node_modules/react-native-keychain/android/src/main/java/com/oblador/keychain/cipherStorage/CipherStorageFacebookConceal.java b/node_modules/react-native-keychain/android/src/main/java/com/oblador/keychain/cipherStorage/CipherStorageFacebookConceal.java
deleted file mode 100644
index 3162f99..0000000
--- a/node_modules/react-native-keychain/android/src/main/java/com/oblador/keychain/cipherStorage/CipherStorageFacebookConceal.java
+++ /dev/null
@@ -1,110 +0,0 @@
-package com.oblador.keychain.cipherStorage;
-
-import android.os.Build;
-import androidx.annotation.NonNull;
-
-import com.facebook.android.crypto.keychain.AndroidConceal;
-import com.facebook.android.crypto.keychain.SharedPrefsBackedKeyChain;
-import com.facebook.crypto.Crypto;
-import com.facebook.crypto.CryptoConfig;
-import com.facebook.crypto.Entity;
-import com.facebook.crypto.keychain.KeyChain;
-import com.facebook.react.bridge.ReactApplicationContext;
-import com.oblador.keychain.SecurityLevel;
-import com.oblador.keychain.exceptions.CryptoFailedException;
-
-import java.nio.charset.Charset;
-
-public class CipherStorageFacebookConceal implements CipherStorage {
- public static final String CIPHER_STORAGE_NAME = "FacebookConceal";
- public static final String KEYCHAIN_DATA = "RN_KEYCHAIN";
- private final Crypto crypto;
-
- public CipherStorageFacebookConceal(ReactApplicationContext reactContext) {
- KeyChain keyChain = new SharedPrefsBackedKeyChain(reactContext, CryptoConfig.KEY_256);
- this.crypto = AndroidConceal.get().createDefaultCrypto(keyChain);
- }
-
- @Override
- public String getCipherStorageName() {
- return CIPHER_STORAGE_NAME;
- }
-
- @Override
- public int getMinSupportedApiLevel() {
- return Build.VERSION_CODES.JELLY_BEAN;
- }
-
- @Override
- public SecurityLevel securityLevel() {
- return SecurityLevel.ANY;
- }
-
- @Override
- public boolean supportsSecureHardware() {
- return false;
- }
-
- @Override
- public EncryptionResult encrypt(@NonNull String service, @NonNull String username, @NonNull String password, SecurityLevel level) throws CryptoFailedException {
-
- if (!this.securityLevel().satisfiesSafetyThreshold(level)) {
- throw new CryptoFailedException(String.format("Insufficient security level (wants %s; got %s)", level, this.securityLevel()));
- }
-
- if (!crypto.isAvailable()) {
- throw new CryptoFailedException("Crypto is missing");
- }
- Entity usernameEntity = createUsernameEntity(service);
- Entity passwordEntity = createPasswordEntity(service);
-
- try {
- byte[] encryptedUsername = crypto.encrypt(username.getBytes(Charset.forName("UTF-8")), usernameEntity);
- byte[] encryptedPassword = crypto.encrypt(password.getBytes(Charset.forName("UTF-8")), passwordEntity);
-
- return new EncryptionResult(encryptedUsername, encryptedPassword, this);
- } catch (Exception e) {
- throw new CryptoFailedException("Encryption failed for service " + service, e);
- }
- }
-
- @Override
- public DecryptionResult decrypt(@NonNull String service, @NonNull byte[] username, @NonNull byte[] password) throws CryptoFailedException {
- if (!crypto.isAvailable()) {
- throw new CryptoFailedException("Crypto is missing");
- }
- Entity usernameEntity = createUsernameEntity(service);
- Entity passwordEntity = createPasswordEntity(service);
-
- try {
- byte[] decryptedUsername = crypto.decrypt(username, usernameEntity);
- byte[] decryptedPassword = crypto.decrypt(password, passwordEntity);
-
- return new DecryptionResult(
- new String(decryptedUsername, Charset.forName("UTF-8")),
- new String(decryptedPassword, Charset.forName("UTF-8")),
- SecurityLevel.ANY);
- } catch (Exception e) {
- throw new CryptoFailedException("Decryption failed for service " + service, e);
- }
- }
-
- @Override
- public void removeKey(@NonNull String service) {
- // Facebook Conceal stores only one key across all services, so we cannot delete the key (otherwise decryption will fail for encrypted data of other services).
- }
-
- private Entity createUsernameEntity(String service) {
- String prefix = getEntityPrefix(service);
- return Entity.create(prefix + "user");
- }
-
- private Entity createPasswordEntity(String service) {
- String prefix = getEntityPrefix(service);
- return Entity.create(prefix + "pass");
- }
-
- private String getEntityPrefix(String service) {
- return KEYCHAIN_DATA + ":" + service;
- }
-}

View File

@@ -0,0 +1,14 @@
diff --git a/node_modules/react-native-mmkv-storage/android/build.gradle b/node_modules/react-native-mmkv-storage/android/build.gradle
index abb696e..ba35baa 100644
--- a/node_modules/react-native-mmkv-storage/android/build.gradle
+++ b/node_modules/react-native-mmkv-storage/android/build.gradle
@@ -98,7 +98,8 @@ android {
cmake {
cppFlags "-O3 -frtti -fexceptions -Wall -fstack-protector-all"
arguments "-DANDROID_STL=c++_shared",
- "-DREACT_NATIVE_MINOR_VERSION=${REACT_NATIVE_MINOR_VERSION}"
+ "-DREACT_NATIVE_MINOR_VERSION=${REACT_NATIVE_MINOR_VERSION}",
+ "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON"
abiFilters (*reactNativeArchitectures())
}
}

View File

@@ -70,7 +70,6 @@ const EXTRA_ICON_NAMES = [
"chevron-down",
"calendar",
"minus-circle-outline",
"circle-outline",
"close-circle-outline",
"qrcode",
"text",

View File

@@ -28,6 +28,7 @@ import RNFetchBlob from "react-native-blob-util";
import WebView from "react-native-webview";
import { Config } from "./store";
import { db } from "../app/common/database";
import { SUBSCRIPTION_STATUS } from "../app/utils/constants";
export const fetchHandle = createRef();
export const HtmlLoadingWebViewAgent = React.memo(
@@ -39,7 +40,6 @@ export const HtmlLoadingWebViewAgent = React.memo(
const webview = useRef();
const premium = useRef(false);
const corsProxy = Config.corsProxy;
const [isLoggedIn, setIsLoggedIn] = useState();
useImperativeHandle(
fetchHandle,
@@ -72,8 +72,11 @@ export const HtmlLoadingWebViewAgent = React.memo(
useEffect(() => {
(async () => {
const user = await db.user.getUser();
setIsLoggedIn(!!user);
console.log("USER", !!user);
const subscriptionStatus =
user?.subscription?.type || SUBSCRIPTION_STATUS.BASIC;
premium.current =
user && subscriptionStatus !== SUBSCRIPTION_STATUS.BASIC;
const clipperPath =
Platform.OS === "ios"
? RNFetchBlob.fs.dirs.MainBundleDir +
@@ -88,7 +91,6 @@ export const HtmlLoadingWebViewAgent = React.memo(
.catch((e) => console.log(e));
})();
}, []);
console.log(isLoggedIn);
return !source || !clipper ? null : (
<WebView
@@ -101,8 +103,7 @@ export const HtmlLoadingWebViewAgent = React.memo(
height: 100,
position: "absolute",
opacity: 0,
zIndex: -1,
pointerEvents: "none"
zIndex: -1
}}
useSharedProcessPool={false}
pointerEvents="none"
@@ -122,11 +123,7 @@ export const HtmlLoadingWebViewAgent = React.memo(
console.log("Error handling webview message", e);
}
}}
injectedJavaScriptBeforeContentLoaded={script(
clipper,
corsProxy,
isLoggedIn
)}
injectedJavaScriptBeforeContentLoaded={script(clipper, premium.current)}
onError={() => {
console.log("Error loading page");
loadHandler.current?.();
@@ -140,11 +137,9 @@ export const HtmlLoadingWebViewAgent = React.memo(
() => true
);
const script = (clipper, corsProxy, loggedIn) => `
globalThis.module = {};
const script = (clipper, pro) => `
${clipper}
function postMessage(type, value) {
if (window.ReactNativeWebView) {
window.ReactNativeWebView.postMessage(
@@ -163,10 +158,10 @@ function postMessage(type, value) {
postMessage("error", globalThis.Clipper.clipPage);
} else {
globalThis.Clipper.clipPage(document,false, {
images: ${loggedIn ? "true" : "false"},
images: ${pro},
inlineImages: false,
styles: false,
corsProxy: ${corsProxy ? `"${corsProxy}"` : "undefined"}
corsProxy: undefined
}).then(result => {
postMessage("html", result);
}).catch(e => {

View File

@@ -19,11 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import ShareExtension from "@ammarahmed/react-native-share-extension";
import { getPreviewData } from "@flyerhq/react-native-link-preview";
import {
formatBytes,
isFeatureAvailable,
useIsFeatureAvailable
} from "@notesnook/common";
import { formatBytes } from "@notesnook/common";
import { isImage } from "@notesnook/core";
import { useThemeColors } from "@notesnook/theme";
import React, { useCallback, useEffect, useRef, useState } from "react";
@@ -123,7 +119,6 @@ const ShareView = () => {
const noteTitle = useRef("");
const [loading, setLoading] = useState(false);
const [loadingExtension, setLoadingExtension] = useState(true);
const fullQualityImages = useIsFeatureAvailable("fullQualityImages");
const [rawData, setRawData] = useState({
type: null,
value: null
@@ -166,12 +161,6 @@ const ShareView = () => {
};
}, []);
useEffect(() => {
if (!fullQualityImages?.isAllowed) {
setCompress(true);
}
}, [fullQualityImages]);
const showLinkPreview = async (note, link) => {
let _note = note;
_note.content.data = makeHtmlFromUrl(link);
@@ -234,14 +223,14 @@ const ShareView = () => {
}
} else {
const user = await db.user.getUser();
if (user) {
const feature = await isFeatureAvailable(
"fileSize",
item.size || 0
);
if (!feature.isAllowed) {
if (user && user.subscription.type !== 0) {
if (
(isImage(item.type) && item.size > IMAGE_SIZE_LIMIT) ||
(!isImage(item.type) && item.size > FILE_SIZE_LIMIT)
) {
continue;
}
setRawFiles((files) => {
const index = files.findIndex(
(file) => file.name === item.name
@@ -267,6 +256,7 @@ const ShareView = () => {
);
const onLoad = useCallback(() => {
console.log(noteContent.current, "current...");
eSendEvent(eOnLoadNote + "shareEditor", {
id: null,
content: {
@@ -501,7 +491,7 @@ const ShareView = () => {
style={{
flexShrink: 1,
flexGrow: 1,
fontFamily: "Inter-SemiBold",
fontFamily: "OpenSans-SemiBold",
fontSize: AppFontSize.lg,
paddingBottom: 0,
paddingTop: 0
@@ -516,7 +506,7 @@ const ShareView = () => {
style={{
flexShrink: 1,
flexGrow: 1,
fontFamily: "Inter-SemiBold",
fontFamily: "OpenSans-SemiBold",
fontSize: AppFontSize.lg,
paddingBottom: 0,
paddingTop: 0,
@@ -642,9 +632,7 @@ const ShareView = () => {
marginTop: 6
}}
onPress={() => {
if (fullQualityImages?.isAllowed) {
setCompress(!compress);
}
setCompress(!compress);
}}
>
<Icon
@@ -655,7 +643,7 @@ const ShareView = () => {
: "checkbox-blank-outline"
}
color={
compress && fullQualityImages?.isAllowed
compress
? colors.primary.accent
: colors.primary.icon
}
@@ -746,7 +734,7 @@ const ShareView = () => {
</Paragraph>
{rawData.value && isURL(rawData.value) ? (
<Button
type={mode === 2 ? "inverted" : "plain"}
type={mode === 2 ? "inverted" : "transparent"}
icon={mode === 2 ? "radiobox-marked" : "radiobox-blank"}
onPress={() => changeMode(2)}
title={modes[2].title}
@@ -757,9 +745,9 @@ const ShareView = () => {
/>
) : null}
<Button
type={mode === 1 ? "inverted" : "plain"}
type={mode === 1 ? "inverted" : "transparent"}
icon={mode === 1 ? "radiobox-marked" : "radiobox-blank"}
onPress={() => changeMode(1)}
onPress={() => changeMode(2)}
title={modes[1].title}
height={30}
style={{

View File

@@ -68,10 +68,11 @@ export const useShareStore = create((set) => ({
let appendNote = MMKV.getString(StorageKeys.appendNote);
let selectedNotebooks = MMKV.getString(StorageKeys.selectedNotebooks);
let selectedTags = MMKV.getString(StorageKeys.selectedTag);
appendNote = JSON.parse(appendNote);
set({
appendNote: appendNote,
selectedNotebooks: selectedNotebooks ? JSON.parse(selectedNotebooks) : [],
selectedTags: selectedTags ? JSON.parse(selectedTags) : []
selectedTag: selectedTags ? JSON.parse(selectedTags) : []
});
},
selectedTags: [],

View File

@@ -15,7 +15,10 @@
"@notesnook/theme": ["../../packages/theme"],
"@types/react": ["./node_modules/@types/react"],
"react": ["./node_modules/react"]
}
},
"incremental": true,
"maxNodeModuleJsDepth": 5,
"downlevelIteration": true
},
"exclude": ["native", "e2e"]
}

File diff suppressed because one or more lines are too long

View File

@@ -141,7 +141,7 @@
"hasInstallScript": true,
"license": "GPL-3.0-or-later",
"dependencies": {
"@notesnook-importer/core": "^2.2.5",
"@notesnook-importer/core": "^2.2.2",
"@notesnook/common": "file:../common",
"@notesnook/intl": "file:../intl",
"@notesnook/theme": "file:../theme",
@@ -208,7 +208,6 @@
"happy-dom": "16.0.1",
"isomorphic-fetch": "^3.0.0",
"nodemon": "^3.1.7",
"prismjs": "^1.30.0",
"prosemirror-test-builder": "^1.1.1",
"react": "18.3.1",
"react-dom": "18.3.1",

View File

@@ -987,7 +987,7 @@
},
"../web": {
"name": "@notesnook/web",
"version": "3.3.4",
"version": "3.3.0-beta.1",
"hasInstallScript": true,
"license": "GPL-3.0-or-later",
"dependencies": {
@@ -1001,7 +1001,7 @@
"@lingui/react": "5.1.2",
"@mdi/js": "7.4.47",
"@mdi/react": "1.6.1",
"@notesnook-importer/core": "^2.2.5",
"@notesnook-importer/core": "^2.2.2",
"@notesnook/common": "file:../../packages/common",
"@notesnook/core": "file:../../packages/core",
"@notesnook/crypto": "file:../../packages/crypto",

View File

@@ -1,12 +1,12 @@
{
"name": "@notesnook/web",
"version": "3.3.5",
"version": "3.3.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@notesnook/web",
"version": "3.3.5",
"version": "3.3.0",
"hasInstallScript": true,
"license": "GPL-3.0-or-later",
"dependencies": {
@@ -20,7 +20,7 @@
"@lingui/react": "5.1.2",
"@mdi/js": "7.4.47",
"@mdi/react": "1.6.1",
"@notesnook-importer/core": "^2.2.5",
"@notesnook-importer/core": "^2.2.2",
"@notesnook/common": "file:../../packages/common",
"@notesnook/core": "file:../../packages/core",
"@notesnook/crypto": "file:../../packages/crypto",
@@ -131,7 +131,7 @@
},
"../../extensions/web-clipper": {
"name": "@notesnook/web-clipper",
"version": "0.4.0",
"version": "0.3.4",
"license": "GPL-3.0-or-later",
"dependencies": {
"@emotion/react": "11.11.1",
@@ -192,7 +192,7 @@
"style-loader": "^3.3.1",
"terser-webpack-plugin": "^5.3.1",
"ts-loader": "^9.2.6",
"web-ext": "^7.12.0",
"web-ext": "^7.6.2",
"webpack": "5.88.2",
"webpack-cli": "5.1.4",
"webpack-dev-server": "^4.7.4"
@@ -299,7 +299,7 @@
"hasInstallScript": true,
"license": "GPL-3.0-or-later",
"dependencies": {
"@notesnook-importer/core": "^2.2.5",
"@notesnook-importer/core": "^2.2.2",
"@notesnook/common": "file:../common",
"@notesnook/intl": "file:../intl",
"@notesnook/theme": "file:../theme",
@@ -366,7 +366,6 @@
"happy-dom": "16.0.1",
"isomorphic-fetch": "^3.0.0",
"nodemon": "^3.1.7",
"prismjs": "^1.30.0",
"prosemirror-test-builder": "^1.1.1",
"react": "18.3.1",
"react-dom": "18.3.1",
@@ -504,7 +503,7 @@
},
"../desktop": {
"name": "@notesnook/desktop",
"version": "3.3.4",
"version": "3.3.0-beta.1",
"hasInstallScript": true,
"license": "GPL-3.0-or-later",
"dependencies": {
@@ -513,7 +512,7 @@
"@notesnook/ui": "file:../../packages/ui",
"@trpc/client": "10.45.2",
"@trpc/server": "10.45.2",
"better-sqlite3-multiple-ciphers": "^12.4.1",
"better-sqlite3-multiple-ciphers": "^11.10.0",
"electron-trpc": "0.7.1",
"electron-updater": "^6.6.2",
"icojs": "^0.19.5",
@@ -528,7 +527,7 @@
"@types/node": "22.15.3",
"@types/yargs": "^17.0.33",
"chokidar": "^4.0.3",
"electron": "^37.0.0",
"electron": "^34.0.0",
"electron-builder": "^26.0.12",
"esbuild": "0.21.5",
"node-abi": "^4.5.0",
@@ -558,6 +557,78 @@
"node": ">=6.0.0"
}
},
"node_modules/@azure/msal-browser": {
"version": "3.28.1",
"resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-3.28.1.tgz",
"integrity": "sha512-OHHEWMB5+Zrix8yKvLVzU3rKDFvh7SOzAzXfICD7YgUXLxfHpTPX2pzOotrri1kskwhHqIj4a5LvhZlIqE7C7g==",
"license": "MIT",
"optional": true,
"dependencies": {
"@azure/msal-common": "14.16.0"
},
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/@azure/msal-common": {
"version": "14.16.0",
"resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-14.16.0.tgz",
"integrity": "sha512-1KOZj9IpcDSwpNiQNjt0jDYZpQvNZay7QAEi/5DLubay40iGYtLzya/jbjRPLyOTZhEKyL1MzPuw2HqBCjceYA==",
"license": "MIT",
"optional": true,
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/@azure/msal-node": {
"version": "2.16.2",
"resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-2.16.2.tgz",
"integrity": "sha512-An7l1hEr0w1HMMh1LU+rtDtqL7/jw74ORlc9Wnh06v7TU/xpG39/Zdr1ZJu3QpjUfKJ+E0/OXMW8DRSWTlh7qQ==",
"license": "MIT",
"optional": true,
"dependencies": {
"@azure/msal-common": "14.16.0",
"jsonwebtoken": "^9.0.0",
"uuid": "^8.3.0"
},
"engines": {
"node": ">=16"
}
},
"node_modules/@azure/msal-node-extensions": {
"version": "1.5.14",
"resolved": "https://registry.npmjs.org/@azure/msal-node-extensions/-/msal-node-extensions-1.5.14.tgz",
"integrity": "sha512-vsXUY1SEVAOlMP5guzrDUmsKJsl5O+zOTb5bxtvCPFAc+ayE9UY9KAespvXIKnPe9MCH8lIP5UJ7DTR7Y5xb8Q==",
"hasInstallScript": true,
"license": "MIT",
"optional": true,
"dependencies": {
"@azure/msal-common": "15.7.0",
"@azure/msal-node-runtime": "^0.18.1",
"keytar": "^7.8.0"
},
"engines": {
"node": ">=16"
}
},
"node_modules/@azure/msal-node-extensions/node_modules/@azure/msal-common": {
"version": "15.7.0",
"resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-15.7.0.tgz",
"integrity": "sha512-m9M5hoFoxhe/HlXNVa4qBHekrX60CVPkWzsjhKQGuzw/OPOmurosKRPDIMn8fug/E1hHI5v33DvT1LVJfItjcg==",
"license": "MIT",
"optional": true,
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/@azure/msal-node-runtime": {
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@azure/msal-node-runtime/-/msal-node-runtime-0.18.2.tgz",
"integrity": "sha512-v45fyBQp80BrjZAeGJXl+qggHcbylQiFBihr0ijO2eniDCW9tz5TZBKYsqzH06VuiRaVG/Sa0Hcn4pjhJqFSTw==",
"hasInstallScript": true,
"license": "MIT",
"optional": true
},
"node_modules/@babel/code-frame": {
"version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
@@ -2854,16 +2925,47 @@
"moo": "^0.5.1"
}
},
"node_modules/@microsoft/microsoft-graph-client": {
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/@microsoft/microsoft-graph-client/-/microsoft-graph-client-3.0.7.tgz",
"integrity": "sha512-/AazAV/F+HK4LIywF9C+NYHcJo038zEnWkteilcxC1FM/uK/4NVGDKGrxx7nNq1ybspAroRKT4I1FHfxQzxkUw==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.12.5",
"tslib": "^2.2.0"
},
"engines": {
"node": ">=12.0.0"
},
"peerDependenciesMeta": {
"@azure/identity": {
"optional": true
},
"@azure/msal-browser": {
"optional": true
},
"buffer": {
"optional": true
},
"stream-browserify": {
"optional": true
}
}
},
"node_modules/@notesnook-importer/core": {
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/@notesnook-importer/core/-/core-2.2.5.tgz",
"integrity": "sha512-S2ie0kgNG/PGdmCF81auvVX0+cvUekjBRzqyT7AYwYi6/z1JN+yGY9S8b1UVscOpm33T7/q6w9FphepEsDXNAA==",
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/@notesnook-importer/core/-/core-2.2.2.tgz",
"integrity": "sha512-ouPirC378m/fJNDOWS1BPN3tS6hj2cyxP13z9dXt45XyyNyK0g9j1u6O212LJEKSqb1JvCelHuimAOzsuXVWtw==",
"hasInstallScript": true,
"license": "GPL-3.0-or-later",
"dependencies": {
"@notesnook-importer/enex": "file:../enex",
"@notesnook-importer/storage": "file:../storage",
"@notesnook-importer/znel": "file:../znel",
"@notesnook-importer/enex": "^2.2.2",
"@notesnook-importer/onenote": "^2.2.2",
"@notesnook-importer/storage": "^2.2.2",
"@notesnook-importer/znel": "^2.2.2",
"@stablelib/chacha20poly1305": "^1.0.1",
"@standardnotes/features": "1.58.0",
"@standardnotes/models": "1.42.0",
"@streamparser/json": "^0.0.10",
"@zip.js/zip.js": "^2.7.32",
"css-select": "^5.1.0",
@@ -2897,7 +2999,9 @@
"license": "MIT"
},
"node_modules/@notesnook-importer/enex": {
"version": "2.2.3",
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/@notesnook-importer/enex/-/enex-2.2.2.tgz",
"integrity": "sha512-SA0X0UqRwNGdGagXGqLu279WRRBkGIDrjjduqY18QNA1WHMULgZa+lbipJDCT/0Omcqs0sI8DXlTEJhZbtJtug==",
"license": "GPL-3.0-or-later",
"dependencies": {
"base64-js": "^1.5.1",
@@ -2909,12 +3013,36 @@
"spark-md5": "^3.0.2"
}
},
"node_modules/@notesnook-importer/onenote": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/@notesnook-importer/onenote/-/onenote-2.2.2.tgz",
"integrity": "sha512-T8UzDIGhjysEZAeA0uux4ZjkyYuMJDTiyRgwxjI4rio2SZzJjIzhhhGSHBWP0VYTKVBFPhwxy7V6J8dL6Z8x6Q==",
"license": "GPL-3.0-or-later",
"dependencies": {
"@microsoft/microsoft-graph-client": "^3.0.7",
"css-select": "^5.1.0",
"dom-serializer": "^2.0.0",
"domhandler": "^5.0.3",
"domutils": "^3.0.1",
"dotenv": "^16.0.0",
"htmlparser2": "^8.0.1"
},
"optionalDependencies": {
"@azure/msal-browser": "^3.6.0",
"@azure/msal-node": "^2.6.0",
"@azure/msal-node-extensions": "^1.0.8"
}
},
"node_modules/@notesnook-importer/storage": {
"version": "2.2.3",
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/@notesnook-importer/storage/-/storage-2.2.2.tgz",
"integrity": "sha512-snEkk6Rb3eKQTkjOUncBPVe8D3Q6sIuxRfK8Y/EBSAzGcLcD3uatS/KQhbZLELN0Xjahhy6l7z87Q1qy9OaJWg==",
"license": "GPL-3.0-or-later"
},
"node_modules/@notesnook-importer/znel": {
"version": "2.2.3",
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/@notesnook-importer/znel/-/znel-2.2.2.tgz",
"integrity": "sha512-lqaKtM0UofkQ9iojUe8MGbClbTrK5HkG/+iB9BbUzAmq0fyk0AaI7go34QJ0CL3zu7p4gFjjc6lllJqdQzV0jA==",
"license": "GPL-3.0-or-later",
"dependencies": {
"base64-js": "^1.5.1",
@@ -3677,6 +3805,111 @@
"integrity": "sha512-WfqfX/eXGiAd3RJe4VU2snh/ZPwtSjLG4ynQ/vYzvghTh7dHFcI1wl+nrkWG6lGhukOxOsUHfv8dUXr58D0ayg==",
"license": "MIT"
},
"node_modules/@standardnotes/auth": {
"version": "3.19.4",
"resolved": "https://registry.npmjs.org/@standardnotes/auth/-/auth-3.19.4.tgz",
"integrity": "sha512-JwD8zBupTp8dP7gLehvPlLTRZfukb19JE64SB/dpHri3tnrBnli5v4DpOYoV/ukDXEarCTt+bwZwBMJFLpU1+A==",
"license": "AGPL-3.0-or-later",
"dependencies": {
"@standardnotes/common": "^1.23.1",
"jsonwebtoken": "^8.5.1"
},
"engines": {
"node": ">=14.0.0 <17.0.0"
}
},
"node_modules/@standardnotes/auth/node_modules/jsonwebtoken": {
"version": "8.5.1",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
"integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
"license": "MIT",
"dependencies": {
"jws": "^3.2.2",
"lodash.includes": "^4.3.0",
"lodash.isboolean": "^3.0.3",
"lodash.isinteger": "^4.0.4",
"lodash.isnumber": "^3.0.3",
"lodash.isplainobject": "^4.0.6",
"lodash.isstring": "^4.0.1",
"lodash.once": "^4.0.0",
"ms": "^2.1.1",
"semver": "^5.6.0"
},
"engines": {
"node": ">=4",
"npm": ">=1.4.28"
}
},
"node_modules/@standardnotes/auth/node_modules/semver": {
"version": "5.7.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
"license": "ISC",
"bin": {
"semver": "bin/semver"
}
},
"node_modules/@standardnotes/common": {
"version": "1.52.4",
"resolved": "https://registry.npmjs.org/@standardnotes/common/-/common-1.52.4.tgz",
"integrity": "sha512-+Iu8D+FIYMXW0kngJLuD5H6xZ1MzzzDViYkM3bRbnWLUwpzmjQybG+MX55PgzxYrwErOShE/pdy498Qxu1qWbw==",
"license": "AGPL-3.0-or-later",
"dependencies": {
"reflect-metadata": "^0.2.1"
},
"engines": {
"node": ">=18.0.0 <21.0.0"
}
},
"node_modules/@standardnotes/common/node_modules/reflect-metadata": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz",
"integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==",
"license": "Apache-2.0"
},
"node_modules/@standardnotes/features": {
"version": "1.58.0",
"resolved": "https://registry.npmjs.org/@standardnotes/features/-/features-1.58.0.tgz",
"integrity": "sha512-JO7tBb3O6xRnRb4+1dXqu9U1l7eZbW4KgbsSdIdRx8Ag2gKzu+2vcRLfpbTQXuxv/zIckaGxPGAmH6t9jm+7Cw==",
"license": "AGPL-3.0-or-later",
"dependencies": {
"@standardnotes/auth": "^3.19.4",
"@standardnotes/common": "^1.45.0",
"@standardnotes/security": "^1.7.0",
"reflect-metadata": "^0.1.13"
},
"engines": {
"node": ">=16.0.0 <17.0.0"
}
},
"node_modules/@standardnotes/models": {
"version": "1.42.0",
"resolved": "https://registry.npmjs.org/@standardnotes/models/-/models-1.42.0.tgz",
"integrity": "sha512-ZGMYD9NgeUxexLTbmtDAe03gh6nvTeoVobJlnrcthSKcibjIDLlBbjG9TB6Bq2Jwbp+qEdhGjZd1fVzwUyf6pw==",
"license": "AGPL-3.0-or-later",
"engines": {
"node": ">=16.0.0 <17.0.0"
}
},
"node_modules/@standardnotes/security": {
"version": "1.17.4",
"resolved": "https://registry.npmjs.org/@standardnotes/security/-/security-1.17.4.tgz",
"integrity": "sha512-Wd9KK5EInqHS5MBATRGeTn2qPqPxPPJviS2Kk13Sypugm4NJOBzbvDNuVutyv2ujgh9EWhlPVc2DugJHYzQqgg==",
"license": "AGPL-3.0-or-later",
"dependencies": {
"jsonwebtoken": "^9.0.0",
"reflect-metadata": "^0.2.1"
},
"engines": {
"node": ">=18.0.0 <21.0.0"
}
},
"node_modules/@standardnotes/security/node_modules/reflect-metadata": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz",
"integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==",
"license": "Apache-2.0"
},
"node_modules/@streamparser/json": {
"version": "0.0.10",
"resolved": "https://registry.npmjs.org/@streamparser/json/-/json-0.0.10.tgz",
@@ -5316,15 +5549,6 @@
],
"license": "MIT"
},
"node_modules/baseline-browser-mapping": {
"version": "2.8.18",
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.18.tgz",
"integrity": "sha512-UYmTpOBwgPScZpS4A+YbapwWuBwasxvO/2IOHArSsAhL/+ZdmATBXTex3t+l2hXwLVYK382ibr/nKoY9GKe86w==",
"license": "Apache-2.0",
"bin": {
"baseline-browser-mapping": "dist/cli.js"
}
},
"node_modules/better-sqlite3-multiple-ciphers": {
"version": "11.5.0",
"resolved": "https://registry.npmjs.org/better-sqlite3-multiple-ciphers/-/better-sqlite3-multiple-ciphers-11.5.0.tgz",
@@ -5361,7 +5585,7 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
"integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
"dev": true,
"devOptional": true,
"license": "MIT",
"dependencies": {
"buffer": "^5.5.0",
@@ -5373,7 +5597,7 @@
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
"dev": true,
"devOptional": true,
"funding": [
{
"type": "github",
@@ -5412,9 +5636,9 @@
}
},
"node_modules/browserslist": {
"version": "4.26.3",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.26.3.tgz",
"integrity": "sha512-lAUU+02RFBuCKQPj/P6NgjlbCnLBMp4UtgTx7vNHd3XSIJF87s9a5rA3aH2yw3GS9DqZAUbOtZdCCiZeVRqt0w==",
"version": "4.25.0",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.0.tgz",
"integrity": "sha512-PJ8gYKeS5e/whHBh8xrwYK+dAvEj7JXtz6uTucnMRB8OiGTsKccFekoRrjajPBHV8oOY+2tI4uxeceSimKwMFA==",
"funding": [
{
"type": "opencollective",
@@ -5431,10 +5655,9 @@
],
"license": "MIT",
"dependencies": {
"baseline-browser-mapping": "^2.8.9",
"caniuse-lite": "^1.0.30001746",
"electron-to-chromium": "^1.5.227",
"node-releases": "^2.0.21",
"caniuse-lite": "^1.0.30001718",
"electron-to-chromium": "^1.5.160",
"node-releases": "^2.0.19",
"update-browserslist-db": "^1.1.3"
},
"bin": {
@@ -5469,6 +5692,12 @@
"ieee754": "^1.2.1"
}
},
"node_modules/buffer-equal-constant-time": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
"integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==",
"license": "BSD-3-Clause"
},
"node_modules/buffer-from": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
@@ -5558,9 +5787,9 @@
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001751",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001751.tgz",
"integrity": "sha512-A0QJhug0Ly64Ii3eIqHu5X51ebln3k4yTUkY1j8drqpWHVreg/VLijN48cZ1bYPiqOQuqpkIKnzr/Ul8V+p6Cw==",
"version": "1.0.30001723",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001723.tgz",
"integrity": "sha512-1R/elMjtehrFejxwmexeXAtae5UO9iSyFn6G/I806CYC/BLyyBk1EPhrKBkWhy6wM6Xnm47dSJQec+tLJ39WHw==",
"funding": [
{
"type": "opencollective",
@@ -5855,9 +6084,9 @@
}
},
"node_modules/css-select": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz",
"integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==",
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
"integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
"license": "BSD-2-Clause",
"dependencies": {
"boolbase": "^1.0.0",
@@ -5871,9 +6100,9 @@
}
},
"node_modules/css-what": {
"version": "6.2.2",
"resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz",
"integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==",
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
"integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
"license": "BSD-2-Clause",
"engines": {
"node": ">= 6"
@@ -5982,7 +6211,7 @@
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
"integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
"dev": true,
"devOptional": true,
"license": "MIT",
"dependencies": {
"mimic-response": "^3.1.0"
@@ -5998,7 +6227,7 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
"integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
"dev": true,
"devOptional": true,
"license": "MIT",
"engines": {
"node": ">=10"
@@ -6021,7 +6250,7 @@
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
"integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
"dev": true,
"devOptional": true,
"license": "MIT",
"engines": {
"node": ">=4.0.0"
@@ -6224,7 +6453,6 @@
"version": "16.4.7",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz",
"integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==",
"dev": true,
"license": "BSD-2-Clause",
"engines": {
"node": ">=12"
@@ -6254,6 +6482,15 @@
"node": ">= 0.4"
}
},
"node_modules/ecdsa-sig-formatter": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
"integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
"license": "Apache-2.0",
"dependencies": {
"safe-buffer": "^5.0.1"
}
},
"node_modules/ejs": {
"version": "3.1.10",
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
@@ -6271,9 +6508,9 @@
}
},
"node_modules/electron-to-chromium": {
"version": "1.5.237",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.237.tgz",
"integrity": "sha512-icUt1NvfhGLar5lSWH3tHNzablaA5js3HVHacQimfP8ViEBOQv+L7DKEuHdbTZ0SKCO1ogTJTIL1Gwk9S6Qvcg==",
"version": "1.5.168",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.168.tgz",
"integrity": "sha512-RUNQmFLNIWVW6+z32EJQ5+qx8ci6RGvdtDC0Ls+F89wz6I2AthpXF0w0DIrn2jpLX0/PU9ZCo+Qp7bg/EckJmA==",
"license": "ISC"
},
"node_modules/electron-trpc": {
@@ -6311,7 +6548,7 @@
"version": "1.4.5",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz",
"integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==",
"dev": true,
"devOptional": true,
"license": "MIT",
"dependencies": {
"once": "^1.4.0"
@@ -6583,7 +6820,7 @@
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
"integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
"dev": true,
"devOptional": true,
"license": "(MIT OR WTFPL)",
"engines": {
"node": ">=6"
@@ -6839,7 +7076,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
"integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
"dev": true,
"devOptional": true,
"license": "MIT"
},
"node_modules/fs-minipass": {
@@ -7045,7 +7282,7 @@
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
"integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==",
"dev": true,
"devOptional": true,
"license": "MIT"
},
"node_modules/glob": {
@@ -7481,7 +7718,7 @@
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
"dev": true,
"devOptional": true,
"funding": [
{
"type": "github",
@@ -7537,7 +7774,7 @@
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
"dev": true,
"devOptional": true,
"license": "ISC"
},
"node_modules/internal-slot": {
@@ -8154,6 +8391,61 @@
"node": ">=0.10.0"
}
},
"node_modules/jsonwebtoken": {
"version": "9.0.2",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz",
"integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==",
"license": "MIT",
"dependencies": {
"jws": "^3.2.2",
"lodash.includes": "^4.3.0",
"lodash.isboolean": "^3.0.3",
"lodash.isinteger": "^4.0.4",
"lodash.isnumber": "^3.0.3",
"lodash.isplainobject": "^4.0.6",
"lodash.isstring": "^4.0.1",
"lodash.once": "^4.0.0",
"ms": "^2.1.1",
"semver": "^7.5.4"
},
"engines": {
"node": ">=12",
"npm": ">=6"
}
},
"node_modules/jsonwebtoken/node_modules/semver": {
"version": "7.7.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
"integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/jwa": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.2.tgz",
"integrity": "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==",
"license": "MIT",
"dependencies": {
"buffer-equal-constant-time": "^1.0.1",
"ecdsa-sig-formatter": "1.0.11",
"safe-buffer": "^5.0.1"
}
},
"node_modules/jws": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
"integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
"license": "MIT",
"dependencies": {
"jwa": "^1.4.1",
"safe-buffer": "^5.0.1"
}
},
"node_modules/katex": {
"version": "0.16.11",
"resolved": "https://registry.npmjs.org/katex/-/katex-0.16.11.tgz",
@@ -8179,6 +8471,18 @@
"node": ">= 12"
}
},
"node_modules/keytar": {
"version": "7.9.0",
"resolved": "https://registry.npmjs.org/keytar/-/keytar-7.9.0.tgz",
"integrity": "sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ==",
"hasInstallScript": true,
"license": "MIT",
"optional": true,
"dependencies": {
"node-addon-api": "^4.3.0",
"prebuild-install": "^7.0.1"
}
},
"node_modules/kind-of": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
@@ -8241,6 +8545,18 @@
"integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==",
"license": "MIT"
},
"node_modules/lodash.includes": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
"integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==",
"license": "MIT"
},
"node_modules/lodash.isboolean": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
"integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==",
"license": "MIT"
},
"node_modules/lodash.isequal": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
@@ -8248,6 +8564,36 @@
"deprecated": "This package is deprecated. Use require('node:util').isDeepStrictEqual instead.",
"license": "MIT"
},
"node_modules/lodash.isinteger": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
"integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==",
"license": "MIT"
},
"node_modules/lodash.isnumber": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
"integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==",
"license": "MIT"
},
"node_modules/lodash.isplainobject": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
"integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
"license": "MIT"
},
"node_modules/lodash.isstring": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
"integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==",
"license": "MIT"
},
"node_modules/lodash.once": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
"integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==",
"license": "MIT"
},
"node_modules/lodash.sortby": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
@@ -9322,7 +9668,7 @@
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
"dev": true,
"devOptional": true,
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -9389,7 +9735,7 @@
"version": "0.5.3",
"resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
"integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
"dev": true,
"devOptional": true,
"license": "MIT"
},
"node_modules/moo": {
@@ -9452,7 +9798,7 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz",
"integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==",
"dev": true,
"devOptional": true,
"license": "MIT"
},
"node_modules/no-case": {
@@ -9470,7 +9816,7 @@
"version": "3.75.0",
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.75.0.tgz",
"integrity": "sha512-OhYaY5sDsIka7H7AtijtI9jwGYLyl29eQn/W623DiN/MIv5sUqc4g7BIDThX+gb7di9f6xK02nkp8sdfFWZLTg==",
"dev": true,
"devOptional": true,
"license": "MIT",
"dependencies": {
"semver": "^7.3.5"
@@ -9483,7 +9829,7 @@
"version": "7.7.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
"integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
"dev": true,
"devOptional": true,
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
@@ -9492,6 +9838,13 @@
"node": ">=10"
}
},
"node_modules/node-addon-api": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz",
"integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==",
"license": "MIT",
"optional": true
},
"node_modules/node-fetch": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
@@ -9514,9 +9867,9 @@
}
},
"node_modules/node-releases": {
"version": "2.0.25",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.25.tgz",
"integrity": "sha512-4auku8B/vw5psvTiiN9j1dAOsXvMoGqJuKJcR+dTdqiXEK20mMTk1UEo3HS16LeGQsVG6+qKTPM9u/qQ2LqATA==",
"version": "2.0.19",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
"integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==",
"license": "MIT"
},
"node_modules/nopt": {
@@ -9913,7 +10266,7 @@
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz",
"integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==",
"dev": true,
"devOptional": true,
"license": "MIT",
"dependencies": {
"detect-libc": "^2.0.0",
@@ -9940,7 +10293,7 @@
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz",
"integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==",
"dev": true,
"devOptional": true,
"funding": [
{
"type": "github",
@@ -10006,7 +10359,7 @@
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz",
"integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==",
"dev": true,
"devOptional": true,
"license": "MIT",
"dependencies": {
"end-of-stream": "^1.1.0",
@@ -10049,7 +10402,7 @@
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
"integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
"dev": true,
"devOptional": true,
"license": "(BSD-2-Clause OR MIT OR Apache-2.0)",
"dependencies": {
"deep-extend": "^0.6.0",
@@ -10248,6 +10601,12 @@
"node": ">= 6"
}
},
"node_modules/reflect-metadata": {
"version": "0.1.14",
"resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.14.tgz",
"integrity": "sha512-ZhYeb6nRaXCfhnndflDK8qI6ZQ/YcWZCISRAWICW9XYqMUwjZM9Z0DveWX/ABN01oxSHwVxKQmxeYZSsm0jh5A==",
"license": "Apache-2.0"
},
"node_modules/reflect.getprototypeof": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
@@ -10685,7 +11044,6 @@
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
"devOptional": true,
"funding": [
{
"type": "github",
@@ -11301,7 +11659,7 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
"integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
"dev": true,
"devOptional": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@@ -11388,7 +11746,7 @@
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.3.tgz",
"integrity": "sha512-090nwYJDmlhwFwEW3QQl+vaNnxsO2yVsd45eTKRBzSzu+hlb1w2K9inVq5b0ngXuLVqQ4ApvsUHHnu/zQNkWAg==",
"dev": true,
"devOptional": true,
"license": "MIT",
"dependencies": {
"chownr": "^1.1.1",
@@ -11401,14 +11759,14 @@
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
"integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
"dev": true,
"devOptional": true,
"license": "ISC"
},
"node_modules/tar-stream": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
"integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
"dev": true,
"devOptional": true,
"license": "MIT",
"dependencies": {
"bl": "^4.0.3",
@@ -11609,7 +11967,7 @@
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
"integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
"dev": true,
"devOptional": true,
"license": "Apache-2.0",
"dependencies": {
"safe-buffer": "^5.0.1"
@@ -11982,6 +12340,16 @@
"devOptional": true,
"license": "MIT"
},
"node_modules/uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
"license": "MIT",
"optional": true,
"bin": {
"uuid": "dist/bin/uuid"
}
},
"node_modules/uvu": {
"version": "0.5.6",
"resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz",

View File

@@ -1,7 +1,7 @@
{
"name": "@notesnook/web",
"description": "Your private note taking space",
"version": "3.3.5",
"version": "3.3.0",
"private": true,
"main": "./src/app.js",
"homepage": "https://notesnook.com/",
@@ -18,7 +18,7 @@
"@lingui/react": "5.1.2",
"@mdi/js": "7.4.47",
"@mdi/react": "1.6.1",
"@notesnook-importer/core": "^2.2.5",
"@notesnook-importer/core": "^2.2.2",
"@notesnook/common": "file:../../packages/common",
"@notesnook/core": "file:../../packages/core",
"@notesnook/crypto": "file:../../packages/crypto",

View File

@@ -23,7 +23,11 @@ import { useStore as useUserStore } from "./stores/user-store";
import { useEditorStore } from "./stores/editor-store";
import { useStore as useAnnouncementStore } from "./stores/announcement-store";
import { useStore as useSettingStore } from "./stores/setting-store";
import { scheduleBackups, scheduleFullBackups } from "./common/notices";
import {
resetNotices,
scheduleBackups,
scheduleFullBackups
} from "./common/notices";
import { introduceFeatures, resetFeatures } from "./common";
import { AppEventManager, AppEvents } from "./common/app-events";
import { db } from "./common/db";
@@ -59,7 +63,7 @@ export default function AppEffects() {
await refreshNavItems();
await updateLastSynced();
await initUser();
// await resetNotices();
await resetNotices();
setIsVaultCreated(await db.vault.exists());
await FeatureDialog.show({ featureName: "highlights" });

View File

@@ -53,8 +53,8 @@ async function initializeDatabase(persistence: DatabasePersistence) {
AUTH_HOST: "https://auth.streetwriters.co",
SSE_HOST: "https://events.streetwriters.co",
ISSUES_HOST: "https://issues.streetwriters.co",
SUBSCRIPTIONS_HOST: "https://subscriptions.streetwriters.co",
MONOGRAPH_HOST: "https://monogr.ph",
SUBSCRIPTIONS_HOST: "https://subscriptions.streetwriters.co",
NOTESNOOK_HOST: "https://notesnook.com",
...Config.get("serverUrls", {})
});

View File

@@ -89,6 +89,9 @@ export async function scheduleFullBackups() {
export async function shouldAddAutoBackupsDisabledNotice() {
if (isIgnored("autoBackupsOff")) return false;
const user = await db.user.getUser();
if (!user) return false;
const backupInterval = Config.get("backupReminderOffset", 0);
return backupInterval === 0;
}
@@ -198,11 +201,9 @@ function isIgnored(key: keyof typeof NoticesData) {
let openedToast: { hide: () => void } | null = null;
async function saveBackup(mode: "full" | "partial" = "partial") {
if (IS_TESTING) return;
if (IS_DESKTOP_APP) {
await createBackup({ noVerify: true, mode, background: true });
} else {
} else if (!IS_TESTING) {
if (openedToast !== null) return;
openedToast = showToast(
"success",

View File

@@ -44,7 +44,6 @@ import {
useStore as useAppStore,
store as appstore
} from "../../stores/app-store";
import { useStore as useUserStore } from "../../stores/user-store";
import { useStore as useSearchStore } from "../../stores/search-store";
import { AppEventManager, AppEvents } from "../../common/app-events";
import { FlexScrollContainer } from "../scroll-container";
@@ -78,7 +77,6 @@ import { Pane, SplitPane } from "../split-pane";
import { TITLE_BAR_HEIGHT } from "../title-bar";
import { isMobile } from "../../hooks/use-mobile";
import { isTablet } from "../../hooks/use-tablet";
import { ConfirmDialog } from "../../dialogs/confirm";
const PDFPreview = React.lazy(() => import("../pdf-preview"));
@@ -606,15 +604,6 @@ export function Editor(props: EditorProps) {
}
}}
onInsertAttachment={async (type) => {
if (!useUserStore.getState().isLoggedIn) {
ConfirmDialog.show({
title: strings.notLoggedIn(),
message: strings.loginToUploadAttachments(),
positiveButtonText: strings.okay()
});
return;
}
const mime = type === "file" ? "*/*" : "image/*";
const attachments = await insertAttachments(mime);
const editor = useEditorManager.getState().getEditor(id)?.editor;
@@ -715,10 +704,8 @@ function EditorChrome(props: PropsWithChildren<EditorProps>) {
);
requestAnimationFrame(() => {
if (!isMobile() && !isTablet()) {
editor.style.marginLeft = `-${negativeSpace}px`;
editor.style.marginRight = `-${negativeSpace}px`;
}
editor.style.marginLeft = `-${negativeSpace}px`;
editor.style.marginRight = `-${negativeSpace}px`;
editor.style.paddingLeft = `${negativeSpace}px`;
editor.style.paddingRight = `${negativeSpace}px`;
});

View File

@@ -51,7 +51,6 @@ import {
import { IEditor, MAX_AUTO_SAVEABLE_WORDS } from "./types";
import { useEditorConfig, useToolbarConfig, useEditorManager } from "./manager";
import { useStore as useSettingsStore } from "../../stores/setting-store";
import { useStore as useUserStore } from "../../stores/user-store";
import { debounce, useAreFeaturesAvailable } from "@notesnook/common";
import { ScopedThemeProvider } from "../theme-provider";
import { useStore as useThemeStore } from "../../stores/theme-store";
@@ -66,8 +65,6 @@ import { EDITOR_ZOOM } from "./common";
import { ScrollContainer } from "@notesnook/ui";
import { showFeatureNotAllowedToast } from "../../common/toasts";
import { UpgradeDialog } from "../../dialogs/buy-dialog/upgrade-dialog";
import { ConfirmDialog } from "../../dialogs/confirm";
import { strings } from "@notesnook/intl";
export type OnChangeHandler = (
content: () => string,
@@ -188,6 +185,7 @@ function TipTap(props: TipTapProps) {
const autoSave = useRef(true);
const { toolbarConfig } = useToolbarConfig();
const features = useAreFeaturesAvailable([
"callout",
"outlineList",
@@ -198,19 +196,9 @@ function TipTap(props: TipTapProps) {
claims: {
callout: !!features?.callout?.isAllowed,
outlineList: !!features?.outlineList?.isAllowed,
taskList: !!features?.taskList?.isAllowed,
insertAttachment: !!useUserStore.getState().isLoggedIn
taskList: !!features?.taskList?.isAllowed
},
onPermissionDenied: (claim, silent) => {
if (claim === "insertAttachment") {
ConfirmDialog.show({
title: strings.notLoggedIn(),
message: strings.loginToUploadAttachments(),
positiveButtonText: strings.okay()
});
return;
}
if (silent) {
console.log(features, features?.[claim]);
if (features?.[claim]) showFeatureNotAllowedToast(features[claim]);

View File

@@ -19,6 +19,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import {
INetworkProvider,
OneNote,
OneNoteSettings,
ProviderSettings,
transform
} from "@notesnook-importer/core";
@@ -44,7 +46,17 @@ function getProviderSettings(
provider: INetworkProvider<ProviderSettings>,
settings: ProviderSettings
) {
return settings;
if (provider instanceof OneNote) {
return {
...settings,
cache: false,
clientId: "6c32bdbd-c6c6-4cda-bcf0-0c8ec17e5804",
redirectUri:
process.env.NODE_ENV === "development"
? "http://localhost:3000"
: "https://app.notesnook.com"
} as OneNoteSettings;
}
}
export function NetworkProviderHandler(props: NetworkProviderHandlerProps) {

View File

@@ -50,6 +50,7 @@ const TRIAL_PERIODS: Record<Period, number> = {
};
export function toPricingInfo(plan: Plan, user: User | undefined): PricingInfo {
console.log("TO PRICING INFO", plan);
return {
country: plan.country,
period: plan.period,
@@ -57,9 +58,9 @@ export function toPricingInfo(plan: Plan, user: User | undefined): PricingInfo {
currency: plan.currency,
id: plan.id,
period: plan.period,
subtotal: formatPrice(plan.price.net, plan.currency),
subtotal: formatPrice(plan.price.gross, plan.currency),
tax: formatPrice(plan.price.tax, plan.currency),
total: formatPrice(plan.price.gross, plan.currency),
total: formatPrice(plan.price.net, plan.currency),
trial_period: isTrialAvailableForPlan(plan.plan, user)
? {
frequency: TRIAL_PERIODS[plan.period]
@@ -73,9 +74,9 @@ export function toPricingInfo(plan: Plan, user: User | undefined): PricingInfo {
currency: plan.currency,
id: plan.id,
period: plan.period,
subtotal: formatPrice(plan.price.net, plan.currency),
subtotal: formatPrice(plan.price.gross, plan.currency),
tax: formatPrice(plan.price.tax, plan.currency),
total: formatPrice(plan.price.gross, plan.currency)
total: formatPrice(plan.price.net, plan.currency)
}
: undefined
};

View File

@@ -245,7 +245,7 @@ function getPricingInfo(
id: price.price_id,
period: options.period,
subtotal: formatPrice(
data.recurring_totals.subtotal - data.recurring_totals.discount,
data.recurring_totals.subtotal,
data.currency_code
),
total: formatPrice(data.recurring_totals.total, data.currency_code),
@@ -256,10 +256,7 @@ function getPricingInfo(
currency: data.currency_code,
id: price.price_id,
period: options.period,
subtotal: formatPrice(
totals.subtotal - totals.discount,
data.currency_code
),
subtotal: formatPrice(totals.subtotal, data.currency_code),
total: formatPrice(totals.total, data.currency_code),
tax: formatPrice(totals.tax, data.currency_code),
trial_period: price.trial_period

View File

@@ -93,14 +93,14 @@ const features: Record<FeatureKeys, Feature> = {
]
: [
{
title: "Notesnook Circle",
title: "New pricing plans",
subtitle:
"Notesnook Circle brings together trusted partners who share our commitment to privacy, transparency, and user freedom. As a member you get exclusive discounts and offers from our partners. Check it out in Settings > Notesnook Circle."
"We are changing our pricing to make more sense and be more flexible."
},
{
title: "Collapsible headings",
title: "Filters in search",
subtitle:
"You can now collapse and expand headings in your notes. This makes it easier to manage large notes and focus on specific sections."
"Search now has some basic filters like content:, title:, tag:, color: etc. For the whole list of filters, read our docs."
}
],
cta: {

View File

@@ -1,173 +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 { useState } from "react";
import { Copy, Loading } from "../../../components/icons";
import { Button, Link, Flex, Text, Grid } from "@theme-ui/components";
import { usePromise } from "@notesnook/common";
import { db } from "../../../common/db";
import { writeToClipboard } from "../../../utils/clipboard";
import { showToast } from "../../../utils/toast";
import { ErrorText } from "../../../components/error-text";
import { useStore as useUserStore } from "../../../stores/user-store";
import { SubscriptionPlan, SubscriptionStatus } from "@notesnook/core";
import { BuyDialog } from "../../buy-dialog";
import { strings } from "@notesnook/intl";
export function CirclePartners() {
const partners = usePromise(() => db.circle.partners(), []);
const [redeemedCode, setRedeemedCode] = useState<{
partnerId: string;
code: string;
}>();
const subscription = useUserStore((store) => store.user?.subscription);
const isFree =
!subscription ||
subscription?.plan === SubscriptionPlan.FREE ||
subscription?.status === SubscriptionStatus.EXPIRED;
const isTrial = subscription?.status === SubscriptionStatus.TRIAL;
const canRedeem = !isFree && !isTrial;
return (
<>
{partners.status === "pending" ? (
<Loading sx={{ mt: 2 }} />
) : partners.status === "rejected" ? (
<ErrorText error={partners.reason} />
) : (
<Grid columns={2} sx={{ mt: 2 }}>
{partners.value?.map((partner) => (
<Flex
key={partner.id}
sx={{
flexDirection: "column",
border: "1px solid var(--border)",
borderRadius: "dialog",
padding: 2,
gap: 1
}}
>
<Flex
sx={{ justifyContent: "space-between", alignItems: "center" }}
>
<Text variant="title">{partner.name}</Text>
<img
src={partner.logoBase64}
alt={partner.name}
style={{ width: 30, height: "auto", borderRadius: 8 }}
/>
</Flex>
<Text variant="body" sx={{ whiteSpace: "pre-wrap" }}>
{partner.shortDescription}
</Text>
<Text
variant="subBody"
sx={{
fontStyle: "italic",
color: "accent",
textAlign: "center"
}}
>
{partner.offerDescription}
</Text>
{redeemedCode?.partnerId === partner.id ? (
<>
<Flex
sx={{
bg: "background-secondary",
border: "1px solid var(--border)",
borderRadius: "default",
alignSelf: "center",
alignItems: "center",
gap: 1,
p: "small"
}}
>
<Text
variant="body"
className="selectable"
sx={{
fontFamily: "monospace",
fontSize: 14
}}
>
{redeemedCode.code}
</Text>
<Button
variant="icon"
onClick={() =>
writeToClipboard({ "text/plain": redeemedCode.code })
}
>
<Copy size={12} />
</Button>
</Flex>
{partner.codeRedeemUrl ? (
<Text variant="subBody" sx={{ textAlign: "center" }}>
<Link
target="_blank"
href={partner.codeRedeemUrl.replace(
"{{code}}",
redeemedCode.code
)}
>
Click here
</Link>{" "}
to directly claim the promotion.
</Text>
) : null}
</>
) : (
<Button
variant="accent"
sx={{ mt: 1 }}
onClick={async () => {
if (isFree) return BuyDialog.show({});
if (isTrial) {
return showToast(
"error",
strings.trialUserCircleNotice()
);
}
if (!canRedeem) return;
const result = await db.circle
.redeem(partner.id)
.catch((e) => {
showToast("error", e.message);
});
if (result?.code) {
setRedeemedCode({
partnerId: partner.id,
code: result.code
});
showToast("success", "Code redeemed successfully");
}
}}
>
{isFree ? strings.upgradeToRedeem() : strings.redeemCode()}
</Button>
)}
</Flex>
))}
</Grid>
)}
</>
);
}

View File

@@ -39,8 +39,7 @@ import {
Servers,
ShieldLock,
Sync,
Inbox,
CircleEmpty
Inbox
} from "../../components/icons";
import NavigationItem from "../../components/navigation-menu/navigation-item";
import { FlexScrollContainer } from "../../components/scroll-container";
@@ -81,8 +80,6 @@ import { strings } from "@notesnook/intl";
import { mdToHtml } from "../../utils/md";
import { InboxSettings } from "./inbox-settings";
import { withFeatureCheck } from "../../common";
import { NotesnookCircleSettings } from "./notesnook-circle-settings";
import { hashNavigate } from "../../navigation";
type SettingsDialogProps = BaseDialogProps<false> & {
activeSection?: SectionKeys;
@@ -112,12 +109,6 @@ const sectionGroups: SectionGroup[] = [
icon: Sync,
isHidden: () => !useUserStore.getState().isLoggedIn
},
{
key: "circle",
title: "Notesnook Circle",
icon: CircleEmpty,
isHidden: () => !useUserStore.getState().isLoggedIn
},
{
key: "inbox",
title: "Inbox",
@@ -194,8 +185,7 @@ const SettingsGroups = [
...AboutSettings,
...SubscriptionSettings,
...ServersSettings,
...InboxSettings,
...NotesnookCircleSettings
...InboxSettings
];
// Thoughts:
@@ -272,12 +262,6 @@ function SettingsSideBar(props: SettingsSideBarProps) {
const [route, setRoute] = useState<SectionKeys>(activeSection || "profile");
useUserStore((store) => store.isLoggedIn);
useEffect(() => {
hashNavigate(`/settings/${route}`, {
notify: false
});
}, [route, activeSection]);
return (
<FlexScrollContainer
id="settings-side-menu"

View File

@@ -1,43 +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 { strings } from "@notesnook/intl";
import { CirclePartners } from "./components/circle-partners";
import { SettingsGroup } from "./types";
export const NotesnookCircleSettings: SettingsGroup[] = [
{
header: strings.notesnookCircle(),
key: "notesnook-circle",
section: "circle",
settings: [
{
key: "partners",
title: "",
description: strings.notesnookCircleDesc(),
components: [
{
type: "custom",
component: CirclePartners
}
]
}
]
}
];

View File

@@ -20,32 +20,28 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import { FeatureId } from "@notesnook/common";
import { Icon } from "../../components/icons";
const SectionKeys = [
"profile",
"auth",
"subscription",
"sync",
"appearance",
"behaviour",
"desktop",
"notifications",
"servers",
"editor",
"backup-export",
"export",
"importer",
"vault",
"app-lock",
"privacy",
"support",
"legal",
"developer",
"about",
"inbox",
"circle"
] as const;
export type SectionKeys = (typeof SectionKeys)[number];
export type SectionKeys =
| "profile"
| "auth"
| "subscription"
| "sync"
| "appearance"
| "behaviour"
| "desktop"
| "notifications"
| "servers"
| "editor"
| "backup-export"
| "export"
| "importer"
| "vault"
| "app-lock"
| "privacy"
| "support"
| "legal"
| "developer"
| "about"
| "inbox";
export type SectionGroupKeys =
| "account"
@@ -156,7 +152,3 @@ export type TextInputSettingComponent = BaseSettingComponent<"input"> & {
export type CustomSettingComponent = BaseSettingComponent<"custom"> & {
component: () => JSX.Element | null;
};
export function isSectionKey(key: string): key is SectionKeys {
return SectionKeys.includes(key as SectionKeys);
}

View File

@@ -25,12 +25,7 @@ import {
IKVStore
} from "./key-value";
import { NNCrypto } from "./nncrypto";
import type {
AsymmetricCipher,
Cipher,
SerializedKey,
SerializedKeyPair
} from "@notesnook/crypto";
import type { Cipher, SerializedKey } from "@notesnook/crypto";
import { isFeatureSupported } from "../utils/feature-check";
import { IKeyStore } from "./key-store";
import { User } from "@notesnook/core";
@@ -165,14 +160,6 @@ export class NNStorage implements IStorage {
return NNCrypto.decryptMulti(key, items, "text");
}
decryptAsymmetric(
keyPair: SerializedKeyPair,
cipherData: AsymmetricCipher<"base64">
): Promise<string> {
cipherData.format = "base64";
return NNCrypto.decryptAsymmetric(keyPair, cipherData, "base64");
}
/**
* @deprecated
*/

View File

@@ -33,7 +33,6 @@ import {
import { FeatureDialog } from "../dialogs/feature-dialog";
import { CreateTagDialog } from "../dialogs/item-dialog";
import { OnboardingDialog } from "../dialogs/onboarding-dialog";
import { isSectionKey, SectionKeys } from "../dialogs/settings/types";
const hashroutes = defineHashRoutes({
"/": () => {},
@@ -69,11 +68,6 @@ const hashroutes = defineHashRoutes({
},
"/settings": () => {
SettingsDialog.show({}).then(afterAction);
},
"/settings/:section": ({ section }) => {
SettingsDialog.show(
isSectionKey(section) ? { activeSection: section as SectionKeys } : {}
).then(afterAction);
}
});

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