mirror of
https://github.com/streetwriters/notesnook.git
synced 2026-09-01 11:39:21 +02:00
Compare commits
21 Commits
fix-vault-
...
fix-table-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
14c1567c07 | ||
|
|
fb778f56ed | ||
|
|
ece7b29005 | ||
|
|
8cd8e93487 | ||
|
|
8900a6b080 | ||
|
|
19d90fa221 | ||
|
|
2e5ff859eb | ||
|
|
06747575ee | ||
|
|
98bb8ca186 | ||
|
|
d5f68602b6 | ||
|
|
312999aa5b | ||
|
|
607a4d26f4 | ||
|
|
a88b6615e4 | ||
|
|
f900098201 | ||
|
|
e9a48ae028 | ||
|
|
90a0f619ec | ||
|
|
ed3662a636 | ||
|
|
26eda3b105 | ||
|
|
8f43882e29 | ||
|
|
e239597eb1 | ||
|
|
bf1ef07d3a |
5
.github/workflows/android.e2e.yml
vendored
5
.github/workflows/android.e2e.yml
vendored
@@ -47,6 +47,11 @@ 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
|
||||
|
||||
@@ -73,6 +73,12 @@ 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
|
||||
|
||||
|
||||
6
.github/workflows/android.publish.yml
vendored
6
.github/workflows/android.publish.yml
vendored
@@ -73,6 +73,12 @@ 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
|
||||
|
||||
|
||||
6
.github/workflows/ios.publish.yml
vendored
6
.github/workflows/ios.publish.yml
vendored
@@ -64,6 +64,12 @@ 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
|
||||
|
||||
|
||||
@@ -94,7 +94,9 @@ export async function encryptDatabaseKeyWithPassword(appLockPassword: string) {
|
||||
}
|
||||
|
||||
export async function restoreDatabaseKeyToKeyChain(appLockPassword: string) {
|
||||
const databaseKeyCipher: Cipher = CipherStorage.getMap(DB_KEY_CIPHER);
|
||||
const databaseKeyCipher: Cipher = CipherStorage.getMap(
|
||||
DB_KEY_CIPHER
|
||||
) as Cipher;
|
||||
const databaseKey = (await decrypt(
|
||||
{
|
||||
password: appLockPassword
|
||||
@@ -135,7 +137,9 @@ export async function clearAppLockVerificationCipher() {
|
||||
|
||||
export async function validateAppLockPassword(appLockPassword: string) {
|
||||
try {
|
||||
const appLockCipher: Cipher = CipherStorage.getMap(APPLOCK_CIPHER);
|
||||
const appLockCipher: Cipher = CipherStorage.getMap(
|
||||
APPLOCK_CIPHER
|
||||
) as Cipher;
|
||||
if (!appLockCipher) return true;
|
||||
const key = await Sodium.deriveKey(appLockPassword, appLockCipher.salt);
|
||||
const decrypted = await decrypt(key, appLockCipher);
|
||||
@@ -159,7 +163,9 @@ export function clearDatabaseKey() {
|
||||
export async function getDatabaseKey(appLockPassword?: string) {
|
||||
if (DB_KEY) return DB_KEY;
|
||||
if (appLockPassword) {
|
||||
const databaseKeyCipher: Cipher = CipherStorage.getMap("databaseKeyCipher");
|
||||
const databaseKeyCipher: Cipher = CipherStorage.getMap(
|
||||
"databaseKeyCipher"
|
||||
) as Cipher;
|
||||
const databaseKey = await decrypt(
|
||||
{
|
||||
password: appLockPassword
|
||||
@@ -293,7 +299,7 @@ export async function deriveCryptoKey(data: SerializedKey) {
|
||||
|
||||
export async function getCryptoKey() {
|
||||
try {
|
||||
const keyCipher: Cipher = MMKV.getMap(USER_KEY_CIPHER);
|
||||
const keyCipher: Cipher = MMKV.getMap(USER_KEY_CIPHER) as Cipher;
|
||||
if (!keyCipher) {
|
||||
DatabaseLogger.info("User key cipher is null");
|
||||
return undefined;
|
||||
|
||||
@@ -136,6 +136,12 @@ 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();
|
||||
},
|
||||
|
||||
@@ -39,6 +39,7 @@ 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,
|
||||
|
||||
@@ -99,7 +99,7 @@ export const useLogin = (
|
||||
callback && callback(false);
|
||||
} catch (e) {
|
||||
callback && callback(false);
|
||||
if (e.message === "invalid_grant") {
|
||||
if ((e as Error).message === "invalid_grant") {
|
||||
eSendEvent(eCloseSimpleDialog, "two_factor_verify");
|
||||
setLoading(false);
|
||||
setStep(LoginSteps.emailAuth);
|
||||
|
||||
@@ -35,29 +35,35 @@ 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" />
|
||||
<ResultDialog />
|
||||
<VaultDialog colors={colors} />
|
||||
<RateAppSheet />
|
||||
<ImagePreview />
|
||||
<AnnouncementDialog />
|
||||
<SessionExpired />
|
||||
<PDFPreview />
|
||||
<JumpToSectionDialog />
|
||||
<Dialog context="global" />
|
||||
<Progress />
|
||||
|
||||
{isAppLoading ? null : (
|
||||
<>
|
||||
<MergeConflicts />
|
||||
<RecoveryKeySheet colors={colors} />
|
||||
<ResultDialog />
|
||||
<VaultDialog colors={colors} />
|
||||
<RateAppSheet />
|
||||
<ImagePreview />
|
||||
<AnnouncementDialog />
|
||||
<SessionExpired />
|
||||
<PDFPreview />
|
||||
<JumpToSectionDialog />
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -41,7 +41,7 @@ export const openNotebook = (item: Notebook | BaseTrashItem<Notebook>) => {
|
||||
positiveText: strings.restore(),
|
||||
negativeText: strings.delete(),
|
||||
positivePress: async () => {
|
||||
if ((await db.trash.restore(item.id)) === false) return;
|
||||
await db.trash.restore(item.id);
|
||||
Navigation.queueRoutesForUpdate();
|
||||
useSelectionStore.getState().setSelectionMode(undefined);
|
||||
ToastManager.show({
|
||||
|
||||
@@ -117,7 +117,8 @@ export default function NotePreview({ session, content, note }) {
|
||||
{!session?.locked && !locked ? (
|
||||
<View
|
||||
style={{
|
||||
flex: 1
|
||||
flex: 1,
|
||||
backgroundColor: colors.primary.background
|
||||
}}
|
||||
>
|
||||
<ReadonlyEditor
|
||||
|
||||
@@ -44,6 +44,7 @@ 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,
|
||||
|
||||
@@ -29,6 +29,7 @@ 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";
|
||||
|
||||
@@ -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://notesnook.com/open_note")) {
|
||||
} else if (url.startsWith("https://app.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://notesnook.com/open_reminder")) {
|
||||
} else if (url.startsWith("https://app.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://notesnook.com/new_reminder")) {
|
||||
} else if (url.startsWith("https://app.notesnook.com/new_reminder")) {
|
||||
const reminderFeature = await isFeatureAvailable("activeReminders");
|
||||
if (!reminderFeature.isAllowed) {
|
||||
ToastManager.show({
|
||||
@@ -780,13 +780,11 @@ export const useAppEvents = () => {
|
||||
if (!isAppLoading && !appLocked) {
|
||||
setTimeout(() => {
|
||||
sub = AppState.addEventListener("change", onAppStateChanged);
|
||||
if (
|
||||
refValues.current.initialUrl &&
|
||||
!refValues.current.initialUrl?.includes("open_note")
|
||||
) {
|
||||
if (refValues.current.initialUrl) {
|
||||
onAppOpenedFromURL({
|
||||
url: refValues.current.initialUrl!
|
||||
});
|
||||
refValues.current.initialUrl = undefined;
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
|
||||
@@ -69,36 +69,6 @@ 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;
|
||||
|
||||
@@ -1,67 +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 { 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;
|
||||
};
|
||||
@@ -49,6 +49,7 @@ 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"
|
||||
@@ -89,6 +90,7 @@ 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"
|
||||
|
||||
@@ -82,6 +82,7 @@ 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;
|
||||
@@ -274,7 +275,15 @@ export const useEditorEvents = (
|
||||
|
||||
const onHardwareBackPress = useCallback(() => {
|
||||
if (fluidTabsRef.current?.page() === "editor") {
|
||||
onBackPress();
|
||||
if (
|
||||
useNavigationStore.getState().currentRoute === "ManageTags" ||
|
||||
useNavigationStore.getState().currentRoute === "LinkNotebooks" ||
|
||||
useNavigationStore.getState().currentRoute === "AddReminder"
|
||||
) {
|
||||
Navigation.goBack();
|
||||
} else {
|
||||
onBackPress();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}, [onBackPress]);
|
||||
|
||||
@@ -185,7 +185,7 @@ export default function DebugLogs() {
|
||||
paragraph: strings.clearLogsConfirmation(currentLog.key),
|
||||
negativeText: strings.cancel(),
|
||||
positiveText: strings.clear(),
|
||||
positivePress: () => {
|
||||
positivePress: async () => {
|
||||
const index = logs.findIndex((l) => (l.key = currentLog.key));
|
||||
logManager?.delete(currentLog.key);
|
||||
if (logs.length > 1) {
|
||||
|
||||
@@ -2,7 +2,8 @@ import { CirclePartner, SubscriptionStatus } from "@notesnook/core";
|
||||
import { strings } from "@notesnook/intl";
|
||||
import { useThemeColors } from "@notesnook/theme";
|
||||
import Clipboard from "@react-native-clipboard/clipboard";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useState } from "react";
|
||||
import { useAsync } from "react-async-hook";
|
||||
import {
|
||||
ActivityIndicator,
|
||||
Image,
|
||||
@@ -13,6 +14,7 @@ import {
|
||||
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";
|
||||
@@ -21,8 +23,8 @@ import PremiumService from "../../services/premium";
|
||||
import { useUserStore } from "../../stores/use-user-store";
|
||||
import { AppFontSize, defaultBorderRadius } from "../../utils/size";
|
||||
import { DefaultAppStyles } from "../../utils/styles";
|
||||
import { useAsync } from "react-async-hook";
|
||||
import { Notice } from "../../components/ui/notice";
|
||||
import { openLinkInBrowser } from "../../utils/functions";
|
||||
import { Pressable } from "../../components/ui/pressable";
|
||||
|
||||
export const NotesnookCircle = () => {
|
||||
const user = useUserStore((state) => state.user);
|
||||
@@ -156,32 +158,53 @@ const Partner = ({
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<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}
|
||||
<>
|
||||
<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);
|
||||
}}
|
||||
>
|
||||
{code}
|
||||
</Paragraph>
|
||||
<Paragraph
|
||||
size={AppFontSize.lg}
|
||||
color={colors.secondary.paragraph}
|
||||
>
|
||||
{code}
|
||||
</Paragraph>
|
||||
|
||||
<AppIcon name="content-copy" />
|
||||
</TouchableOpacity>
|
||||
<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}
|
||||
|
||||
@@ -26,18 +26,17 @@ import {
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import { ActivityIndicator, TextInput, View } from "react-native";
|
||||
import Icon from "react-native-vector-icons/MaterialCommunityIcons";
|
||||
//@ts-ignore
|
||||
import { FeatureResult, useIsFeatureAvailable } from "@notesnook/common";
|
||||
import { strings } from "@notesnook/intl";
|
||||
//@ts-ignore
|
||||
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";
|
||||
@@ -45,7 +44,6 @@ 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();
|
||||
|
||||
@@ -32,6 +32,7 @@ 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";
|
||||
|
||||
@@ -580,7 +580,7 @@ function openSettingsDialog(context: string) {
|
||||
positivePress:
|
||||
Platform.OS === "ios"
|
||||
? undefined
|
||||
: () => {
|
||||
: async () => {
|
||||
resolve(true);
|
||||
},
|
||||
onClose: () => {
|
||||
|
||||
@@ -17,8 +17,15 @@ You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { 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,
|
||||
@@ -57,6 +64,28 @@ 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,
|
||||
|
||||
@@ -33,6 +33,7 @@ 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 "";
|
||||
@@ -56,7 +57,7 @@ function confirmDeleteAllNotes(
|
||||
title: strings.doActions.delete.notebook(items.length),
|
||||
positiveText: strings.delete(),
|
||||
negativeText: strings.cancel(),
|
||||
positivePress: (_inputValue, value) => {
|
||||
positivePress: async (_inputValue, value) => {
|
||||
setTimeout(() => {
|
||||
resolve({ delete: true, deleteNotes: value });
|
||||
});
|
||||
@@ -98,6 +99,30 @@ 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({
|
||||
@@ -108,6 +133,7 @@ export const deleteItems = async (
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
await db.notes.moveToTrash(id);
|
||||
|
||||
eSendEvent(
|
||||
@@ -157,7 +183,7 @@ export const deleteItems = async (
|
||||
heading: message,
|
||||
type: "success",
|
||||
func: async () => {
|
||||
if ((await db.trash.restore(...deletedIds)) === false) return;
|
||||
await db.trash.restore(...deletedIds);
|
||||
Navigation.queueRoutesForUpdate();
|
||||
useMenuStore.getState().setMenuPins();
|
||||
useMenuStore.getState().setColorNotes();
|
||||
|
||||
@@ -27,18 +27,20 @@ let unlockPromise: Promise<any> | undefined = undefined;
|
||||
export async function unlockVault({
|
||||
context,
|
||||
title,
|
||||
paragraph
|
||||
paragraph,
|
||||
requirePassword
|
||||
}: {
|
||||
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) return true;
|
||||
if (db.vault.unlocked && !requirePassword) return true;
|
||||
const biometry = await BiometricService.isBiometryAvailable();
|
||||
const fingerprint = await BiometricService.hasInternetCredentials();
|
||||
if (biometry && fingerprint) {
|
||||
|
||||
@@ -124,7 +124,7 @@ android {
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
multiDexEnabled true
|
||||
versionCode 3074
|
||||
versionCode 3075
|
||||
versionName getNpmVersion()
|
||||
testBuildType System.getProperty('testBuildType', 'debug')
|
||||
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
|
||||
|
||||
@@ -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://notesnook.com/open_note?id=" + note.getId()));
|
||||
intent.setData(Uri.parse("https://app.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);
|
||||
|
||||
|
||||
@@ -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://notesnook.com/open_reminder?id=" + reminder.getId()));
|
||||
fillInIntent.setData(Uri.parse("https://app.notesnook.com/open_reminder?id=" + reminder.getId()));
|
||||
fillInIntent.putExtra(RCTNNativeModule.IntentType, "OpenReminder");
|
||||
fillInIntent.putExtras(extras);
|
||||
views.setOnClickFillInIntent(R.id.reminder_item_btn, fillInIntent);
|
||||
|
||||
@@ -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://notesnook.com/new_reminder"));
|
||||
new_reminder_intent.setData(Uri.parse("https://app.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);
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingVertical="10dp"
|
||||
android:id="@+id/reminder_item_btn">
|
||||
|
||||
<TextView
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingVertical="10dp"
|
||||
android:id="@+id/reminder_item_btn">
|
||||
|
||||
<TextView
|
||||
|
||||
@@ -25,9 +25,9 @@
|
||||
android:text="Upcoming Reminders"/>
|
||||
|
||||
<ImageButton
|
||||
android:layout_width="30dp"
|
||||
android:layout_width="35dp"
|
||||
android:id="@+id/add_button"
|
||||
android:layout_height="30dp"
|
||||
android:layout_height="35dp"
|
||||
android:layout_alignParentRight="true"
|
||||
android:background="@drawable/ic_newnote" />
|
||||
</RelativeLayout>
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
- Collapsible Headings
|
||||
- Notesnook Circle
|
||||
- Minor bug fixes and improvements
|
||||
|
||||
Thank you for using Notesnook!
|
||||
@@ -1091,7 +1091,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 2153;
|
||||
CURRENT_PROJECT_VERSION = 2154;
|
||||
DEVELOPMENT_TEAM = 53CWBG3QUC;
|
||||
ENABLE_BITCODE = NO;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
@@ -1165,7 +1165,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.3.5;
|
||||
MARKETING_VERSION = 3.3.6;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
@@ -1196,7 +1196,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 2153;
|
||||
CURRENT_PROJECT_VERSION = 2154;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 53CWBG3QUC;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
@@ -1270,7 +1270,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.3.5;
|
||||
MARKETING_VERSION = 3.3.6;
|
||||
ONLY_ACTIVE_ARCH = NO;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
@@ -1429,7 +1429,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 2153;
|
||||
CURRENT_PROJECT_VERSION = 2154;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = 53CWBG3QUC;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
@@ -1441,7 +1441,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.3.5;
|
||||
MARKETING_VERSION = 3.3.6;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.notewidget;
|
||||
@@ -1472,7 +1472,7 @@
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 2153;
|
||||
CURRENT_PROJECT_VERSION = 2154;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = "";
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 53CWBG3QUC;
|
||||
@@ -1485,7 +1485,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.3.5;
|
||||
MARKETING_VERSION = 3.3.6;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.notewidget;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
@@ -1515,7 +1515,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = "Make Note/Make Note.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 2153;
|
||||
CURRENT_PROJECT_VERSION = 2154;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = 53CWBG3QUC;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
@@ -1596,7 +1596,7 @@
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
LIBRARY_SEARCH_PATHS = "$(SDKROOT)/usr/lib/swift$(inherited)";
|
||||
MARKETING_VERSION = 3.3.5;
|
||||
MARKETING_VERSION = 3.3.6;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.share;
|
||||
@@ -1627,7 +1627,7 @@
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 2153;
|
||||
CURRENT_PROJECT_VERSION = 2154;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = "";
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 53CWBG3QUC;
|
||||
@@ -1709,7 +1709,7 @@
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
LIBRARY_SEARCH_PATHS = "$(SDKROOT)/usr/lib/swift$(inherited)";
|
||||
MARKETING_VERSION = 3.3.5;
|
||||
MARKETING_VERSION = 3.3.6;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.share;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
|
||||
@@ -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"
|
||||
"react-native-orientation-locker": "^1.7.0",
|
||||
"@ammarahmed/react-native-share-extension": "^2.9.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.27.1",
|
||||
|
||||
339
apps/mobile/package-lock.json
generated
339
apps/mobile/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@notesnook/mobile",
|
||||
"version": "3.3.5",
|
||||
"version": "3.3.6",
|
||||
"private": true,
|
||||
"license": "GPL-3.0-or-later",
|
||||
"workspaces": [
|
||||
@@ -56,4 +56,4 @@
|
||||
"react": "18.2.0",
|
||||
"react-native": "0.77.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,11 +68,10 @@ 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) : [],
|
||||
selectedTag: selectedTags ? JSON.parse(selectedTags) : []
|
||||
selectedTags: selectedTags ? JSON.parse(selectedTags) : []
|
||||
});
|
||||
},
|
||||
selectedTags: [],
|
||||
|
||||
@@ -15,10 +15,7 @@
|
||||
"@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
3
fastlane/metadata/android/en-US/changelogs/15379.txt
Normal file
3
fastlane/metadata/android/en-US/changelogs/15379.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
- Minor bug fixes and improvements
|
||||
|
||||
Thank you for using Notesnook!
|
||||
2
packages/editor-mobile/package-lock.json
generated
2
packages/editor-mobile/package-lock.json
generated
@@ -63,7 +63,7 @@
|
||||
"hasInstallScript": true,
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"@notesnook-importer/core": "^2.2.2",
|
||||
"@notesnook-importer/core": "^2.2.5",
|
||||
"@notesnook/common": "file:../common",
|
||||
"@notesnook/intl": "file:../intl",
|
||||
"@notesnook/theme": "file:../theme",
|
||||
|
||||
@@ -34,7 +34,11 @@
|
||||
}
|
||||
|
||||
.ProseMirror > :first-child {
|
||||
margin-top: 0.4em !important;
|
||||
margin-top: 5px !important;
|
||||
}
|
||||
|
||||
.ProseMirror:first-child {
|
||||
margin-top: 0px !important;
|
||||
}
|
||||
|
||||
#root {
|
||||
|
||||
@@ -580,7 +580,8 @@ const Tiptap = ({
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
padding: "0px 16px",
|
||||
paddingBottom: "6px"
|
||||
paddingBottom: "3px",
|
||||
boxSizing: "border-box"
|
||||
}}
|
||||
>
|
||||
<StatusBar
|
||||
|
||||
@@ -77,26 +77,19 @@ function StatusBar({
|
||||
fontSize: 12,
|
||||
color: "var(--nn_secondary_paragraph)",
|
||||
paddingBottom: 0,
|
||||
fontFamily: "Inter",
|
||||
userSelect: "none"
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
height: "25px",
|
||||
alignItems: "center"
|
||||
<p
|
||||
onMouseDown={(e) => {
|
||||
setShowChars(!showChars);
|
||||
}}
|
||||
style={paragraphStyle}
|
||||
>
|
||||
<p
|
||||
onMouseDown={(e) => {
|
||||
setShowChars(!showChars);
|
||||
}}
|
||||
style={paragraphStyle}
|
||||
>
|
||||
{showChars ? strings.charactersCount(chars) : words}
|
||||
</p>
|
||||
</div>
|
||||
{showChars ? strings.charactersCount(chars) : words}
|
||||
</p>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +55,6 @@ function Tags(props: { settings: Settings; loading?: boolean }) {
|
||||
style={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
minHeight: "25px",
|
||||
opacity: props.loading ? 0 : 1,
|
||||
gap: 6
|
||||
}}
|
||||
|
||||
73
packages/editor/package-lock.json
generated
73
packages/editor/package-lock.json
generated
@@ -1535,39 +1535,6 @@
|
||||
"@styled-system/css": "^5.1.5"
|
||||
}
|
||||
},
|
||||
"node_modules/@theme-ui/color-modes": {
|
||||
"version": "0.16.2",
|
||||
"resolved": "https://registry.npmjs.org/@theme-ui/color-modes/-/color-modes-0.16.2.tgz",
|
||||
"integrity": "sha512-jWEWx53lxNgWCT38i/kwLV2rsvJz8lVZgi5oImnVwYba9VejXD23q1ckbNFJHosQ8KKXY87ht0KPC6BQFIiHtQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@theme-ui/core": "^0.16.2",
|
||||
"@theme-ui/css": "^0.16.2",
|
||||
"deepmerge": "^4.2.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@emotion/react": "^11.11.1",
|
||||
"react": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@theme-ui/color-modes/node_modules/@theme-ui/core": {
|
||||
"version": "0.16.2",
|
||||
"resolved": "https://registry.npmjs.org/@theme-ui/core/-/core-0.16.2.tgz",
|
||||
"integrity": "sha512-bBd/ltbwO9vIUjF1jtlOX6XN0IIOdf1vzBp2JCKsSOqdfn84m+XL8OogIe/zOhQ+aM94Nrq4+32tFJc8sFav4Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@theme-ui/css": "^0.16.2",
|
||||
"deepmerge": "^4.2.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@emotion/react": "^11.11.1",
|
||||
"react": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@theme-ui/components": {
|
||||
"version": "0.16.1",
|
||||
"resolved": "https://registry.npmjs.org/@theme-ui/components/-/components-0.16.1.tgz",
|
||||
@@ -1613,39 +1580,6 @@
|
||||
"@emotion/react": "^11.11.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@theme-ui/theme-provider": {
|
||||
"version": "0.16.2",
|
||||
"resolved": "https://registry.npmjs.org/@theme-ui/theme-provider/-/theme-provider-0.16.2.tgz",
|
||||
"integrity": "sha512-LRnVevODcGqO0JyLJ3wht+PV3ZoZcJ7XXLJAJWDoGeII4vZcPQKwVy4Lpz/juHsZppQxKcB3U+sQDGBnP25irQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@theme-ui/color-modes": "^0.16.2",
|
||||
"@theme-ui/core": "^0.16.2",
|
||||
"@theme-ui/css": "^0.16.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@emotion/react": "^11.11.1",
|
||||
"react": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@theme-ui/theme-provider/node_modules/@theme-ui/core": {
|
||||
"version": "0.16.2",
|
||||
"resolved": "https://registry.npmjs.org/@theme-ui/core/-/core-0.16.2.tgz",
|
||||
"integrity": "sha512-bBd/ltbwO9vIUjF1jtlOX6XN0IIOdf1vzBp2JCKsSOqdfn84m+XL8OogIe/zOhQ+aM94Nrq4+32tFJc8sFav4Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@theme-ui/css": "^0.16.2",
|
||||
"deepmerge": "^4.2.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@emotion/react": "^11.11.1",
|
||||
"react": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/core": {
|
||||
"version": "2.6.6",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/core/-/core-2.6.6.tgz",
|
||||
@@ -3556,7 +3490,8 @@
|
||||
"node_modules/js-tokens": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
|
||||
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/js-yaml": {
|
||||
"version": "3.14.1",
|
||||
@@ -3676,6 +3611,7 @@
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
||||
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"js-tokens": "^3.0.0 || ^4.0.0"
|
||||
},
|
||||
@@ -5198,6 +5134,7 @@
|
||||
"version": "18.3.1",
|
||||
"resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
|
||||
"integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.1.0"
|
||||
},
|
||||
@@ -5218,6 +5155,7 @@
|
||||
"version": "18.3.1",
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
|
||||
"integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.1.0",
|
||||
"scheduler": "^0.23.2"
|
||||
@@ -5532,6 +5470,7 @@
|
||||
"version": "0.23.2",
|
||||
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
|
||||
"integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.1.0"
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ import { ReactNodeView, ReactNodeViewProps } from "../react/index.js";
|
||||
import { Node as ProsemirrorNode } from "prosemirror-model";
|
||||
import { Editor } from "../../types.js";
|
||||
import { Editor as TiptapEditor } from "@tiptap/core";
|
||||
import { useEffect, useRef } from "react";
|
||||
import { useCallback, useEffect, useRef } from "react";
|
||||
import { updateColumnsOnResize } from "@tiptap/pm/tables";
|
||||
import { EditorView, NodeView } from "prosemirror-view";
|
||||
import {
|
||||
@@ -32,7 +32,7 @@ import {
|
||||
TableProperties
|
||||
} from "../../toolbar/tools/table.js";
|
||||
import { getToolDefinition } from "../../toolbar/tool-definitions.js";
|
||||
import { getPosition } from "@notesnook/ui";
|
||||
import { getPosition, ScrollContainer } from "@notesnook/ui";
|
||||
import {
|
||||
findSelectedDOMNode,
|
||||
hasSameAttributes
|
||||
@@ -41,12 +41,14 @@ import { DesktopOnly } from "../../components/responsive/index.js";
|
||||
import { TextDirections } from "../text-direction/index.js";
|
||||
import { strings } from "@notesnook/intl";
|
||||
import SimpleBar from "simplebar-react";
|
||||
import { useIsMobile } from "../../toolbar/stores/toolbar-store.js";
|
||||
|
||||
export function TableComponent(props: ReactNodeViewProps) {
|
||||
const { editor, node, forwardRef } = props;
|
||||
const colgroupRef = useRef<HTMLTableColElement>(null);
|
||||
const tableRef = useRef<HTMLTableElement>();
|
||||
const { textDirection } = node.attrs;
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
useEffect(() => {
|
||||
if (!colgroupRef.current || !tableRef.current) return;
|
||||
@@ -54,6 +56,22 @@ export function TableComponent(props: ReactNodeViewProps) {
|
||||
updateColumnsOnResize(node, colgroupRef.current, tableRef.current, 50);
|
||||
}, [node]);
|
||||
|
||||
const renderScrollContent = useCallback(() => {
|
||||
return (
|
||||
<div dir={textDirection}>
|
||||
<table
|
||||
ref={(ref) => {
|
||||
forwardRef?.(ref);
|
||||
tableRef.current = ref || undefined;
|
||||
}}
|
||||
>
|
||||
<colgroup ref={colgroupRef} />
|
||||
{/* <tbody /> */}
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
}, [forwardRef, textDirection]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<DesktopOnly>
|
||||
@@ -68,19 +86,12 @@ export function TableComponent(props: ReactNodeViewProps) {
|
||||
textDirection={textDirection}
|
||||
/>
|
||||
</DesktopOnly>
|
||||
<SimpleBar autoHide>
|
||||
<Box dir={textDirection}>
|
||||
<table
|
||||
ref={(ref) => {
|
||||
forwardRef?.(ref);
|
||||
tableRef.current = ref || undefined;
|
||||
}}
|
||||
>
|
||||
<colgroup ref={colgroupRef} />
|
||||
{/* <tbody /> */}
|
||||
</table>
|
||||
</Box>
|
||||
</SimpleBar>
|
||||
|
||||
{isMobile ? (
|
||||
<ScrollContainer>{renderScrollContent()}</ScrollContainer>
|
||||
) : (
|
||||
<SimpleBar>{renderScrollContent()}</SimpleBar>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -208,6 +219,7 @@ function TableRowToolbar(props: TableToolbarProps) {
|
||||
function TableColumnToolbar(props: TableToolbarProps) {
|
||||
const { editor, table } = props;
|
||||
const columnToolsRef = useRef<HTMLDivElement>(null);
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
useEffect(() => {
|
||||
function onSelectionUpdate() {
|
||||
@@ -234,8 +246,9 @@ function TableColumnToolbar(props: TableToolbarProps) {
|
||||
yOffset: 2
|
||||
});
|
||||
|
||||
const scrollLeft =
|
||||
table.current?.closest(".simplebar-content-wrapper")?.scrollLeft || 0;
|
||||
const scrollLeft = isMobile
|
||||
? table.current.parentElement?.parentElement?.scrollLeft || 0
|
||||
: table.current?.closest(".simplebar-content-wrapper")?.scrollLeft || 0;
|
||||
|
||||
columnToolsRef.current.style.left = `${pos.left - scrollLeft}px`;
|
||||
columnToolsRef.current.style.top = `${pos.top}px`;
|
||||
@@ -245,7 +258,7 @@ function TableColumnToolbar(props: TableToolbarProps) {
|
||||
return () => {
|
||||
editor.off("selectionUpdate", onSelectionUpdate);
|
||||
};
|
||||
}, []);
|
||||
}, [isMobile]);
|
||||
|
||||
return (
|
||||
<Flex
|
||||
|
||||
@@ -1580,6 +1580,10 @@ msgstr ""
|
||||
"\n"
|
||||
"**Only use this for troubleshooting purposes. If you are having persistent issues, it is recommended that you reach out to us via support@streetwriters.co so we can help you resolve it permanently.**"
|
||||
|
||||
#: src/strings.ts:2606
|
||||
msgid "Click here to directly claim the promotion."
|
||||
msgstr "Click here to directly claim the promotion."
|
||||
|
||||
#: src/strings.ts:239
|
||||
msgid "Click to deselect"
|
||||
msgstr "Click to deselect"
|
||||
@@ -2842,7 +2846,7 @@ msgstr "Filter attachments by filename, type or hash"
|
||||
msgid "Filter languages"
|
||||
msgstr "Filter languages"
|
||||
|
||||
#: src/strings.ts:2594
|
||||
#: src/strings.ts:2603
|
||||
msgid "Finish your purchase in the browser."
|
||||
msgstr "Finish your purchase in the browser."
|
||||
|
||||
@@ -3032,7 +3036,7 @@ msgstr "Getting recovery codes"
|
||||
msgid "GNU GENERAL PUBLIC LICENSE Version 3"
|
||||
msgstr "GNU GENERAL PUBLIC LICENSE Version 3"
|
||||
|
||||
#: src/strings.ts:2595
|
||||
#: src/strings.ts:2604
|
||||
msgid "Go back"
|
||||
msgstr "Go back"
|
||||
|
||||
|
||||
@@ -1569,6 +1569,10 @@ msgid ""
|
||||
"**Only use this for troubleshooting purposes. If you are having persistent issues, it is recommended that you reach out to us via support@streetwriters.co so we can help you resolve it permanently.**"
|
||||
msgstr ""
|
||||
|
||||
#: src/strings.ts:2606
|
||||
msgid "Click here to directly claim the promotion."
|
||||
msgstr ""
|
||||
|
||||
#: src/strings.ts:239
|
||||
msgid "Click to deselect"
|
||||
msgstr ""
|
||||
@@ -2831,7 +2835,7 @@ msgstr ""
|
||||
msgid "Filter languages"
|
||||
msgstr ""
|
||||
|
||||
#: src/strings.ts:2594
|
||||
#: src/strings.ts:2603
|
||||
msgid "Finish your purchase in the browser."
|
||||
msgstr ""
|
||||
|
||||
@@ -3014,7 +3018,7 @@ msgstr ""
|
||||
msgid "GNU GENERAL PUBLIC LICENSE Version 3"
|
||||
msgstr ""
|
||||
|
||||
#: src/strings.ts:2595
|
||||
#: src/strings.ts:2604
|
||||
msgid "Go back"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -2601,5 +2601,7 @@ Use this if changes from other devices are not appearing on this device. This wi
|
||||
freeUserCircleNotice: () =>
|
||||
t`The Notesnook Circle is exclusive to subscribers. Please consider subscribing to gain access to Notesnook Circle and enjoy additional benefits.`,
|
||||
finishPurchaseInBrowser: () => t`Finish your purchase in the browser.`,
|
||||
goBack: () => t`Go back`
|
||||
goBack: () => t`Go back`,
|
||||
clickToDirectlyClaimPromo: () =>
|
||||
t`Click here to directly claim the promotion.`
|
||||
};
|
||||
|
||||
@@ -53,6 +53,7 @@ const IGNORED_NATIVE_PACKAGES = [
|
||||
"canvas",
|
||||
// optional dependency only used on Node.js platform
|
||||
"@azure/msal-node-runtime",
|
||||
"react-native-quick-sqlite",
|
||||
// not needed on mobile
|
||||
...(args.scope === "mobile" ? ["esbuild"] : [])
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user