mirror of
https://github.com/streetwriters/notesnook.git
synced 2026-08-29 18:19:38 +02:00
Compare commits
55 Commits
fix-input-
...
3.2.8-andr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
475edf6732 | ||
|
|
76ea89b668 | ||
|
|
56b3a8df6b | ||
|
|
e02de0c0f6 | ||
|
|
84bfab2a72 | ||
|
|
a6825a2df2 | ||
|
|
9ba58d1a46 | ||
|
|
29a99d3f97 | ||
|
|
a8b6fe78ba | ||
|
|
4abd69b460 | ||
|
|
5c55b49976 | ||
|
|
c932961dd4 | ||
|
|
47357c3e25 | ||
|
|
3ec5a1cf2c | ||
|
|
13d8a7baf7 | ||
|
|
19b1e74d06 | ||
|
|
82de9b9b94 | ||
|
|
867af58695 | ||
|
|
cdd50f0258 | ||
|
|
8c8b92cc4e | ||
|
|
31dd1619f6 | ||
|
|
afb010e3ae | ||
|
|
ddebdcda43 | ||
|
|
29c69418e9 | ||
|
|
3e565e5195 | ||
|
|
1b352d6162 | ||
|
|
258aa77cdd | ||
|
|
7789bd145c | ||
|
|
c1457cc83f | ||
|
|
8b316d0abf | ||
|
|
def5059ff1 | ||
|
|
e1febfae31 | ||
|
|
82aa506902 | ||
|
|
de1aa40ecf | ||
|
|
53724b437e | ||
|
|
1592620141 | ||
|
|
28ef87a95b | ||
|
|
d4019eea99 | ||
|
|
d13b46cbba | ||
|
|
f1eb215bb9 | ||
|
|
92c7e1a0c1 | ||
|
|
b81cc178b5 | ||
|
|
dd42b82dbf | ||
|
|
ca6b50081a | ||
|
|
4fa27046bb | ||
|
|
8cadc6eaa4 | ||
|
|
ccae629833 | ||
|
|
4a1cbe632c | ||
|
|
579813d93a | ||
|
|
00d00c02ea | ||
|
|
765949cc40 | ||
|
|
87cea6a120 | ||
|
|
83526d4d46 | ||
|
|
fca4faa114 | ||
|
|
171628c7b9 |
60
apps/desktop/package-lock.json
generated
60
apps/desktop/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@notesnook/desktop",
|
||||
"version": "3.2.2",
|
||||
"version": "3.2.3",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@notesnook/desktop",
|
||||
"version": "3.2.2",
|
||||
"version": "3.2.3",
|
||||
"hasInstallScript": true,
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
@@ -20,7 +20,7 @@
|
||||
"electron-updater": "^6.6.2",
|
||||
"icojs": "^0.19.5",
|
||||
"sqlite-better-trigram": "0.0.3",
|
||||
"sqlite3-fts5-html": "^0.0.3",
|
||||
"sqlite3-fts5-html": "^0.0.4",
|
||||
"typed-emitter": "^2.1.0",
|
||||
"yargs": "^17.7.2",
|
||||
"zod": "3.24.3"
|
||||
@@ -6296,23 +6296,23 @@
|
||||
]
|
||||
},
|
||||
"node_modules/sqlite3-fts5-html": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/sqlite3-fts5-html/-/sqlite3-fts5-html-0.0.3.tgz",
|
||||
"integrity": "sha512-omJELqavUID4rikHgSnprzR8KoD+k34Gr//Z6Ju5ZJLI9d2MTv+63gJ/9iCWCmvt5dLODDBL25RzmXsChltjkQ==",
|
||||
"version": "0.0.4",
|
||||
"resolved": "https://registry.npmjs.org/sqlite3-fts5-html/-/sqlite3-fts5-html-0.0.4.tgz",
|
||||
"integrity": "sha512-2d7G3QAgNtndTYRFDXVzzsjlDkjXLo9YB4xxVFIxHIotKnVTNmd0/iSQMMjOMFY5XEpW8yemFkD0EyuN0wFuSQ==",
|
||||
"license": "Public Domain",
|
||||
"optionalDependencies": {
|
||||
"sqlite3-fts5-html-darwin-arm64": "0.0.3",
|
||||
"sqlite3-fts5-html-darwin-x64": "0.0.3",
|
||||
"sqlite3-fts5-html-linux-arm64": "0.0.3",
|
||||
"sqlite3-fts5-html-linux-x64": "0.0.3",
|
||||
"sqlite3-fts5-html-windows-arm64": "0.0.3",
|
||||
"sqlite3-fts5-html-windows-x64": "0.0.3"
|
||||
"sqlite3-fts5-html-darwin-arm64": "0.0.4",
|
||||
"sqlite3-fts5-html-darwin-x64": "0.0.4",
|
||||
"sqlite3-fts5-html-linux-arm64": "0.0.4",
|
||||
"sqlite3-fts5-html-linux-x64": "0.0.4",
|
||||
"sqlite3-fts5-html-windows-arm64": "0.0.4",
|
||||
"sqlite3-fts5-html-windows-x64": "0.0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/sqlite3-fts5-html-darwin-arm64": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/sqlite3-fts5-html-darwin-arm64/-/sqlite3-fts5-html-darwin-arm64-0.0.3.tgz",
|
||||
"integrity": "sha512-jLmBOslggCYG+N8CVbjN/ok6kP9kCkWVYiXVF+ms4NylBPevs6+QBgY4GXNcVuSoRs2T8PT/gxI3yTnjdv/uDg==",
|
||||
"version": "0.0.4",
|
||||
"resolved": "https://registry.npmjs.org/sqlite3-fts5-html-darwin-arm64/-/sqlite3-fts5-html-darwin-arm64-0.0.4.tgz",
|
||||
"integrity": "sha512-zkg+LxOtq7ONz82C4+1mxsmasOIt9tbUReEMlmu29pJosfgDsMftp9k1Jy46FEk3VDFODlg9uDX7f0O0rspayg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -6323,9 +6323,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/sqlite3-fts5-html-darwin-x64": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/sqlite3-fts5-html-darwin-x64/-/sqlite3-fts5-html-darwin-x64-0.0.3.tgz",
|
||||
"integrity": "sha512-zhfkryrXf9UOS/vG9LEUs3sLZTyfgkkX316OAuSVhB0At9oa7rYc3FDiypNh6n3PMr+B3uySC6f9mipBGcsOiQ==",
|
||||
"version": "0.0.4",
|
||||
"resolved": "https://registry.npmjs.org/sqlite3-fts5-html-darwin-x64/-/sqlite3-fts5-html-darwin-x64-0.0.4.tgz",
|
||||
"integrity": "sha512-LtBRTVfB3eNkupKJEobZVOyf4TbmWw4XgdBGvi4wFHHcv96gqhVlHdUGlavul561AOpab+T7DOgaPgph1y5M5A==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -6336,9 +6336,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/sqlite3-fts5-html-linux-arm64": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/sqlite3-fts5-html-linux-arm64/-/sqlite3-fts5-html-linux-arm64-0.0.3.tgz",
|
||||
"integrity": "sha512-FoEwY8I7KHQ0iOtobskKFCqIgFbi+X97h733kDgAN5B9ADK6VHL6/jpLhJLzLtlSVgPedPLTTXnhgP2abQR0eg==",
|
||||
"version": "0.0.4",
|
||||
"resolved": "https://registry.npmjs.org/sqlite3-fts5-html-linux-arm64/-/sqlite3-fts5-html-linux-arm64-0.0.4.tgz",
|
||||
"integrity": "sha512-+xgRPpD7fdXNJPKaggHE5BkSF00aI8rlHHZ+pXZR2GmFyRr++jt34MA5avO4G6oI4mrZ82wUV+sWUqd8FErRBw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -6349,9 +6349,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/sqlite3-fts5-html-linux-x64": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/sqlite3-fts5-html-linux-x64/-/sqlite3-fts5-html-linux-x64-0.0.3.tgz",
|
||||
"integrity": "sha512-wJ2ONYC8Rs/HSWHVI2Y3j7vMh+6QzcA3SYCWAFJEFPM3aCyvf7lFhQgLSHZWkS+OUKduP+9/e/Hc7g3UwHdtig==",
|
||||
"version": "0.0.4",
|
||||
"resolved": "https://registry.npmjs.org/sqlite3-fts5-html-linux-x64/-/sqlite3-fts5-html-linux-x64-0.0.4.tgz",
|
||||
"integrity": "sha512-4ah7IiDUH9kpCPoqT4lW6FcWcNiVF0wtpywW82UVfkawbmgLFPGqSQFqHyChmp1b2dsrkO5X/bhq9E2BR0/xmQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -6362,9 +6362,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/sqlite3-fts5-html-windows-arm64": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/sqlite3-fts5-html-windows-arm64/-/sqlite3-fts5-html-windows-arm64-0.0.3.tgz",
|
||||
"integrity": "sha512-58Qi1NTe/Po+nWz2z24ziSvghQcrMC94/mxmErNeC4SFPZMN7JLx56W2eybJB436CiUUUN9MT4a6BD1bn7RpQg==",
|
||||
"version": "0.0.4",
|
||||
"resolved": "https://registry.npmjs.org/sqlite3-fts5-html-windows-arm64/-/sqlite3-fts5-html-windows-arm64-0.0.4.tgz",
|
||||
"integrity": "sha512-rQKLrX90TKIMgD7zSrOk/U6q0KEBiTaB2nXDONcK4d/CYpnG9g/N/i6Ady98j5+v/PgqymchgtRwvgBHOZzCfw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -6375,9 +6375,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/sqlite3-fts5-html-windows-x64": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/sqlite3-fts5-html-windows-x64/-/sqlite3-fts5-html-windows-x64-0.0.3.tgz",
|
||||
"integrity": "sha512-LYilVGRYXpN0nra3LL7CXlfaLbPmBK78rtaG9Aivufqexqjc2sB+v+xMGT8vxLXOjIAtkBLko2ELuYe8hRLQMw==",
|
||||
"version": "0.0.4",
|
||||
"resolved": "https://registry.npmjs.org/sqlite3-fts5-html-windows-x64/-/sqlite3-fts5-html-windows-x64-0.0.4.tgz",
|
||||
"integrity": "sha512-FxLloBxWtsIGUMxbvOLNY9+FXJYEcku1xVqJarLfGKcXX7zvS3yXMP0dYeld2lQ/evNiLgvLMNLhUFwhEln1vA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "@notesnook/desktop",
|
||||
"productName": "Notesnook",
|
||||
"description": "Your private note taking space",
|
||||
"version": "3.2.2",
|
||||
"version": "3.2.3",
|
||||
"appAppleId": "1544027013",
|
||||
"private": true,
|
||||
"main": "./dist/cjs/index.js",
|
||||
@@ -35,7 +35,7 @@
|
||||
"electron-updater": "^6.6.2",
|
||||
"icojs": "^0.19.5",
|
||||
"sqlite-better-trigram": "0.0.3",
|
||||
"sqlite3-fts5-html": "^0.0.3",
|
||||
"sqlite3-fts5-html": "^0.0.4",
|
||||
"typed-emitter": "^2.1.0",
|
||||
"yargs": "^17.7.2",
|
||||
"zod": "3.24.3"
|
||||
|
||||
@@ -17,26 +17,20 @@ 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 React, { useRef, useState } from "react";
|
||||
import { View } from "react-native";
|
||||
import { db } from "../../common/database";
|
||||
import {
|
||||
eSendEvent,
|
||||
presentSheet,
|
||||
ToastManager
|
||||
} from "../../services/event-manager";
|
||||
import BackupService from "../../services/backup";
|
||||
import { eSendEvent, ToastManager } from "../../services/event-manager";
|
||||
import Navigation from "../../services/navigation";
|
||||
import { useUserStore } from "../../stores/use-user-store";
|
||||
import { eCloseSheet, eOpenRecoveryKeyDialog } from "../../utils/events";
|
||||
import DialogHeader from "../dialog/dialog-header";
|
||||
import { eOpenRecoveryKeyDialog } from "../../utils/events";
|
||||
import { DefaultAppStyles } from "../../utils/styles";
|
||||
import { Dialog } from "../dialog";
|
||||
import { Button } from "../ui/button";
|
||||
import Input from "../ui/input";
|
||||
import { Notice } from "../ui/notice";
|
||||
import Seperator from "../ui/seperator";
|
||||
import { Dialog } from "../dialog";
|
||||
import BackupService from "../../services/backup";
|
||||
import { sleep } from "../../utils/time";
|
||||
import { strings } from "@notesnook/intl";
|
||||
import { DefaultAppStyles } from "../../utils/styles";
|
||||
|
||||
export const ChangePassword = () => {
|
||||
const passwordInputRef = useRef();
|
||||
@@ -85,8 +79,7 @@ export const ChangePassword = () => {
|
||||
context: "global"
|
||||
});
|
||||
setLoading(false);
|
||||
eSendEvent(eCloseSheet);
|
||||
await sleep(300);
|
||||
Navigation.goBack();
|
||||
eSendEvent(eOpenRecoveryKeyDialog);
|
||||
} catch (e) {
|
||||
setLoading(false);
|
||||
@@ -108,9 +101,6 @@ export const ChangePassword = () => {
|
||||
}}
|
||||
>
|
||||
<Dialog context="change-password-dialog" />
|
||||
<DialogHeader title={strings.changePassword()} />
|
||||
<Seperator />
|
||||
|
||||
<Input
|
||||
fwdRef={oldPasswordInputRef}
|
||||
onChangeText={(value) => {
|
||||
@@ -160,9 +150,3 @@ export const ChangePassword = () => {
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
ChangePassword.present = () => {
|
||||
presentSheet({
|
||||
component: <ChangePassword />
|
||||
});
|
||||
};
|
||||
|
||||
@@ -39,6 +39,7 @@ import { hideAuth } from "./common";
|
||||
import { ForgotPassword } from "./forgot-password";
|
||||
import { useLogin } from "./use-login";
|
||||
import { DefaultAppStyles } from "../../utils/styles";
|
||||
import { Dialog } from "../dialog";
|
||||
|
||||
const LoginSteps = {
|
||||
emailAuth: 1,
|
||||
@@ -89,7 +90,7 @@ export const Login = ({ changeMode }) => {
|
||||
return (
|
||||
<>
|
||||
<ForgotPassword />
|
||||
<SheetProvider context="two_factor_verify" />
|
||||
<Dialog context="two_factor_verify" />
|
||||
<View
|
||||
style={{
|
||||
borderRadius: DDS.isTab ? 5 : 0,
|
||||
|
||||
@@ -24,12 +24,8 @@ import { View } from "react-native";
|
||||
import { ScrollView } from "react-native-actions-sheet";
|
||||
import { db } from "../../common/database/index";
|
||||
import useTimer from "../../hooks/use-timer";
|
||||
import {
|
||||
eSendEvent,
|
||||
presentSheet,
|
||||
ToastManager
|
||||
} from "../../services/event-manager";
|
||||
import { eCloseSheet } from "../../utils/events";
|
||||
import { eSendEvent, ToastManager } from "../../services/event-manager";
|
||||
import { eCloseSimpleDialog } from "../../utils/events";
|
||||
import { AppFontSize } from "../../utils/size";
|
||||
import { Button } from "../ui/button";
|
||||
import { IconButton } from "../ui/icon-button";
|
||||
@@ -38,6 +34,7 @@ import { Pressable } from "../ui/pressable";
|
||||
import Heading from "../ui/typography/heading";
|
||||
import Paragraph from "../ui/typography/paragraph";
|
||||
import { DefaultAppStyles } from "../../utils/styles";
|
||||
import { presentDialog } from "../dialog/functions";
|
||||
|
||||
const TwoFactorVerification = ({ onMfaLogin, mfaInfo, onCancel }) => {
|
||||
const { colors } = useThemeColors();
|
||||
@@ -46,7 +43,7 @@ const TwoFactorVerification = ({ onMfaLogin, mfaInfo, onCancel }) => {
|
||||
method: mfaInfo?.primaryMethod,
|
||||
isPrimary: true
|
||||
});
|
||||
const { seconds, start } = useTimer(currentMethod.method);
|
||||
const { seconds, start, reset } = useTimer(currentMethod.method);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const inputRef = useRef();
|
||||
const [sending, setSending] = useState(false);
|
||||
@@ -62,7 +59,7 @@ const TwoFactorVerification = ({ onMfaLogin, mfaInfo, onCancel }) => {
|
||||
},
|
||||
(result) => {
|
||||
if (result) {
|
||||
eSendEvent(eCloseSheet, "two_factor_verify");
|
||||
eSendEvent(eCloseSimpleDialog, "two_factor_verify");
|
||||
}
|
||||
setLoading(false);
|
||||
}
|
||||
@@ -133,6 +130,12 @@ const TwoFactorVerification = ({ onMfaLogin, mfaInfo, onCancel }) => {
|
||||
<ScrollView
|
||||
keyboardShouldPersistTaps="handled"
|
||||
keyboardDismissMode="interactive"
|
||||
style={{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
backgroundColor: colors.primary.background,
|
||||
paddingTop: 60
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
@@ -236,7 +239,10 @@ const TwoFactorVerification = ({ onMfaLogin, mfaInfo, onCancel }) => {
|
||||
<Button
|
||||
title={strings.cancel()}
|
||||
type="secondaryAccented"
|
||||
onPress={onCancel}
|
||||
onPress={() => {
|
||||
reset();
|
||||
onCancel();
|
||||
}}
|
||||
width={250}
|
||||
/>
|
||||
|
||||
@@ -297,7 +303,7 @@ const TwoFactorVerification = ({ onMfaLogin, mfaInfo, onCancel }) => {
|
||||
};
|
||||
|
||||
TwoFactorVerification.present = (onMfaLogin, data, onCancel, context) => {
|
||||
presentSheet({
|
||||
presentDialog({
|
||||
component: () => (
|
||||
<TwoFactorVerification
|
||||
onMfaLogin={onMfaLogin}
|
||||
@@ -306,7 +312,9 @@ TwoFactorVerification.present = (onMfaLogin, data, onCancel, context) => {
|
||||
/>
|
||||
),
|
||||
context: context || "two_factor_verify",
|
||||
disableClosing: true
|
||||
disableClosing: true,
|
||||
transparent: false,
|
||||
statusBarTranslucent: true
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ import { clearMessage } from "../../services/message";
|
||||
import PremiumService from "../../services/premium";
|
||||
import SettingsService from "../../services/settings";
|
||||
import { useUserStore } from "../../stores/use-user-store";
|
||||
import { eCloseSheet } from "../../utils/events";
|
||||
import { eCloseSimpleDialog } from "../../utils/events";
|
||||
import TwoFactorVerification from "./two-factor";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
@@ -92,7 +92,7 @@ export const useLogin = (onFinishLogin, sessionExpired = false) => {
|
||||
} catch (e) {
|
||||
callback && callback(false);
|
||||
if (e.message === "invalid_grant") {
|
||||
eSendEvent(eCloseSheet, "two_factor_verify");
|
||||
eSendEvent(eCloseSimpleDialog, "two_factor_verify");
|
||||
setLoading(false);
|
||||
setStep(LoginSteps.emailAuth);
|
||||
}
|
||||
@@ -100,7 +100,7 @@ export const useLogin = (onFinishLogin, sessionExpired = false) => {
|
||||
},
|
||||
mfaInfo,
|
||||
() => {
|
||||
eSendEvent(eCloseSheet, "two_factor_verify");
|
||||
eSendEvent(eCloseSimpleDialog, "two_factor_verify");
|
||||
setLoading(false);
|
||||
setStep(LoginSteps.emailAuth);
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ import { getElevationStyle } from "../../utils/elevation";
|
||||
import { AppFontSize, normalize } from "../../utils/size";
|
||||
import { DefaultAppStyles } from "../../utils/styles";
|
||||
import { hexToRGBA, RGB_Linear_Shade } from "../../utils/colors";
|
||||
import useKeyboard from "../../hooks/use-keyboard";
|
||||
|
||||
interface FloatingButtonProps {
|
||||
onPress: () => void;
|
||||
|
||||
@@ -21,7 +21,7 @@ import React from "react";
|
||||
import { Text, View, ViewStyle } from "react-native";
|
||||
import { useThemeColors } from "@notesnook/theme";
|
||||
import { AppFontSize } from "../../utils/size";
|
||||
import { Button } from "../ui/button";
|
||||
import { Button, ButtonProps } from "../ui/button";
|
||||
import { PressableProps } from "../ui/pressable";
|
||||
import Heading from "../ui/typography/heading";
|
||||
import Paragraph from "../ui/typography/paragraph";
|
||||
@@ -31,13 +31,7 @@ type DialogHeaderProps = {
|
||||
icon?: string;
|
||||
title?: string;
|
||||
paragraph?: string;
|
||||
button?: {
|
||||
onPress?: () => void;
|
||||
loading?: boolean;
|
||||
title?: string;
|
||||
type?: PressableProps["type"];
|
||||
icon?: string;
|
||||
};
|
||||
button?: ButtonProps;
|
||||
paragraphColor?: string;
|
||||
padding?: number;
|
||||
centered?: boolean;
|
||||
@@ -95,17 +89,14 @@ const DialogHeader = ({
|
||||
|
||||
{button ? (
|
||||
<Button
|
||||
onPress={button.onPress}
|
||||
style={{
|
||||
borderRadius: 100,
|
||||
paddingHorizontal: DefaultAppStyles.GAP
|
||||
}}
|
||||
loading={button.loading}
|
||||
fontSize={13}
|
||||
title={button.title}
|
||||
icon={button.icon}
|
||||
type={button.type || "secondary"}
|
||||
height={30}
|
||||
{...button}
|
||||
/>
|
||||
) : null}
|
||||
</View>
|
||||
|
||||
@@ -27,6 +27,9 @@ export type DialogInfo = {
|
||||
paragraph?: string;
|
||||
positiveText: string;
|
||||
negativeText: string;
|
||||
background?: string;
|
||||
transparent?: boolean;
|
||||
statusBarTranslucent?: boolean;
|
||||
positivePress?: (...args: any[]) => Promise<any>;
|
||||
onClose?: () => void;
|
||||
positiveType?:
|
||||
|
||||
@@ -130,9 +130,17 @@ export const Dialog = ({ context = "global" }: { context?: string }) => {
|
||||
|
||||
return visible && dialogInfo ? (
|
||||
<BaseDialog
|
||||
statusBarTranslucent={false}
|
||||
statusBarTranslucent={
|
||||
dialogInfo.statusBarTranslucent === undefined
|
||||
? false
|
||||
: dialogInfo.statusBarTranslucent
|
||||
}
|
||||
bounce={!dialogInfo.input}
|
||||
closeOnTouch={!dialogInfo.disableBackdropClosing}
|
||||
background={dialogInfo.background}
|
||||
transparent={
|
||||
dialogInfo.transparent === undefined ? true : dialogInfo.transparent
|
||||
}
|
||||
onShow={async () => {
|
||||
if (dialogInfo.input) {
|
||||
inputRef.current?.setNativeProps({
|
||||
|
||||
@@ -17,12 +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 { strings } from "@notesnook/intl";
|
||||
import { useThemeColors } from "@notesnook/theme";
|
||||
import React, { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { Dimensions, TextInput, View } from "react-native";
|
||||
import Orientation from "react-native-orientation-locker";
|
||||
import Pdf from "react-native-pdf";
|
||||
import Animated, { FadeIn, FadeOut } from "react-native-reanimated";
|
||||
import { MMKV } from "../../../common/database/mmkv";
|
||||
import downloadAttachment from "../../../common/filesystem/download-attachment";
|
||||
import { deleteCacheFileByPath, exists } from "../../../common/filesystem/io";
|
||||
import { cacheDir } from "../../../common/filesystem/utils";
|
||||
import { useAttachmentProgress } from "../../../hooks/use-attachment-progress";
|
||||
import useGlobalSafeAreaInsets from "../../../hooks/use-global-safe-area-insets";
|
||||
@@ -30,8 +33,9 @@ import {
|
||||
eSubscribeEvent,
|
||||
eUnSubscribeEvent
|
||||
} from "../../../services/event-manager";
|
||||
import { useThemeColors } from "@notesnook/theme";
|
||||
import { AppFontSize } from "../../../utils/size";
|
||||
import { DefaultAppStyles } from "../../../utils/styles";
|
||||
import { sleep } from "../../../utils/time";
|
||||
import { Dialog } from "../../dialog";
|
||||
import BaseDialog from "../../dialog/base-dialog";
|
||||
import { presentDialog } from "../../dialog/functions";
|
||||
@@ -39,11 +43,6 @@ import SheetProvider from "../../sheet-provider";
|
||||
import { IconButton } from "../../ui/icon-button";
|
||||
import { ProgressBarComponent } from "../../ui/svg/lazy";
|
||||
import Paragraph from "../../ui/typography/paragraph";
|
||||
import { sleep } from "../../../utils/time";
|
||||
import { MMKV } from "../../../common/database/mmkv";
|
||||
import { deleteCacheFileByPath } from "../../../common/filesystem/io";
|
||||
import { strings } from "@notesnook/intl";
|
||||
import { DefaultAppStyles } from "../../../utils/styles";
|
||||
|
||||
const WIN_WIDTH = Dimensions.get("window").width;
|
||||
const WIN_HEIGHT = Dimensions.get("window").height;
|
||||
@@ -105,15 +104,19 @@ const PDFPreview = () => {
|
||||
const open = useCallback(
|
||||
async (attachment) => {
|
||||
setVisible(true);
|
||||
setLoading(true);
|
||||
setTimeout(async () => {
|
||||
setAttachment(attachment);
|
||||
let hash = attachment.hash;
|
||||
if (!hash) return;
|
||||
if (!(await exists(hash))) setLoading(true);
|
||||
const uri = await downloadAttachment(hash, false, {
|
||||
silent: true,
|
||||
cache: true
|
||||
});
|
||||
if (!(await exists(hash))) {
|
||||
setVisible(false);
|
||||
return;
|
||||
}
|
||||
const path = `${cacheDir}/${uri}`;
|
||||
snapshotValue.current = snapshot.current;
|
||||
setPDFSource("file://" + path);
|
||||
@@ -166,8 +169,7 @@ const PDFPreview = () => {
|
||||
}}
|
||||
>
|
||||
{loading ? (
|
||||
<Animated.View
|
||||
exiting={FadeOut}
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
justifyContent: "center",
|
||||
@@ -188,7 +190,7 @@ const PDFPreview = () => {
|
||||
>
|
||||
{strings.loadingWithProgress(progress?.percent)}
|
||||
</Paragraph>
|
||||
</Animated.View>
|
||||
</View>
|
||||
) : (
|
||||
<>
|
||||
<View
|
||||
@@ -270,49 +272,42 @@ const PDFPreview = () => {
|
||||
</View>
|
||||
</View>
|
||||
{pdfSource ? (
|
||||
<Animated.View
|
||||
style={{
|
||||
flex: 1
|
||||
<Pdf
|
||||
source={{
|
||||
uri: pdfSource
|
||||
}}
|
||||
entering={FadeIn}
|
||||
>
|
||||
<Pdf
|
||||
source={{
|
||||
uri: pdfSource
|
||||
}}
|
||||
ref={pdfRef}
|
||||
onLoadComplete={(numberOfPages) => {
|
||||
setNumPages(numberOfPages);
|
||||
}}
|
||||
onPageChanged={(page) => {
|
||||
setCurrentPage(page);
|
||||
inputRef.current?.setNativeProps({
|
||||
text: page + ""
|
||||
});
|
||||
saveSnapshot({
|
||||
currentPage: page,
|
||||
scale: snapshot?.current?.scale
|
||||
});
|
||||
}}
|
||||
// scale={snapshotValue.current?.scale}
|
||||
// onScaleChanged={(scale) => {
|
||||
// saveSnapshot({
|
||||
// currentPage: snapshot?.current?.currentPage,
|
||||
// scale: scale
|
||||
// });
|
||||
// }}
|
||||
page={snapshotValue?.current?.currentPage}
|
||||
password={password}
|
||||
maxScale={6}
|
||||
onError={onError}
|
||||
onPressLink={(uri) => {}}
|
||||
style={{
|
||||
flex: 1,
|
||||
width: width,
|
||||
height: Dimensions.get("window").height
|
||||
}}
|
||||
/>
|
||||
</Animated.View>
|
||||
ref={pdfRef}
|
||||
onLoadComplete={(numberOfPages) => {
|
||||
setNumPages(numberOfPages);
|
||||
}}
|
||||
onPageChanged={(page) => {
|
||||
setCurrentPage(page);
|
||||
inputRef.current?.setNativeProps({
|
||||
text: page + ""
|
||||
});
|
||||
saveSnapshot({
|
||||
currentPage: page,
|
||||
scale: snapshot?.current?.scale
|
||||
});
|
||||
}}
|
||||
// scale={snapshotValue.current?.scale}
|
||||
// onScaleChanged={(scale) => {
|
||||
// saveSnapshot({
|
||||
// currentPage: snapshot?.current?.currentPage,
|
||||
// scale: scale
|
||||
// });
|
||||
// }}
|
||||
page={snapshotValue?.current?.currentPage}
|
||||
password={password}
|
||||
maxScale={6}
|
||||
onError={onError}
|
||||
onPressLink={(uri) => {}}
|
||||
style={{
|
||||
flex: 1,
|
||||
width: width,
|
||||
height: Dimensions.get("window").height
|
||||
}}
|
||||
/>
|
||||
) : null}
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -17,24 +17,26 @@ 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 { Reminder } from "@notesnook/core";
|
||||
import { strings } from "@notesnook/intl";
|
||||
import { useThemeColors } from "@notesnook/theme";
|
||||
import React from "react";
|
||||
import { View } from "react-native";
|
||||
import Icon from "react-native-vector-icons/MaterialCommunityIcons";
|
||||
import { notesnook } from "../../../../e2e/test.ids";
|
||||
import { defaultBorderRadius, AppFontSize } from "../../../utils/size";
|
||||
import useIsSelected from "../../../hooks/use-selected";
|
||||
import AddReminder from "../../../screens/add-reminder";
|
||||
import { eSendEvent } from "../../../services/event-manager";
|
||||
import { useSelectionStore } from "../../../stores/use-selection-store";
|
||||
import { eCloseSheet } from "../../../utils/events";
|
||||
import { AppFontSize, defaultBorderRadius } from "../../../utils/size";
|
||||
import { DefaultAppStyles } from "../../../utils/styles";
|
||||
import { Properties } from "../../properties";
|
||||
import ReminderSheet from "../../sheets/reminder";
|
||||
import AppIcon from "../../ui/AppIcon";
|
||||
import { IconButton } from "../../ui/icon-button";
|
||||
import { ReminderTime } from "../../ui/reminder-time";
|
||||
import Heading from "../../ui/typography/heading";
|
||||
import Paragraph from "../../ui/typography/paragraph";
|
||||
import SelectionWrapper, { selectItem } from "../selection-wrapper";
|
||||
import { strings } from "@notesnook/intl";
|
||||
import { useSelectionStore } from "../../../stores/use-selection-store";
|
||||
import useIsSelected from "../../../hooks/use-selected";
|
||||
import AppIcon from "../../ui/AppIcon";
|
||||
import { DefaultAppStyles } from "../../../utils/styles";
|
||||
|
||||
const ReminderItem = React.memo(
|
||||
({
|
||||
@@ -49,8 +51,10 @@ const ReminderItem = React.memo(
|
||||
const { colors } = useThemeColors();
|
||||
const openReminder = () => {
|
||||
if (selectItem(item)) return;
|
||||
|
||||
ReminderSheet.present(item, undefined, isSheet);
|
||||
AddReminder.present(item, undefined);
|
||||
if (isSheet) {
|
||||
eSendEvent(eCloseSheet);
|
||||
}
|
||||
};
|
||||
const selectionMode = useSelectionStore((state) => state.selectionMode);
|
||||
const [selected] = useIsSelected(item);
|
||||
|
||||
@@ -73,9 +73,6 @@ const ColorItem = ({ item, note }: { item: Color; note: Note }) => {
|
||||
testID={notesnook.ids.dialogs.actionsheet.color(item.colorCode)}
|
||||
key={item.id}
|
||||
onPress={toggleColor}
|
||||
onLongPress={(event) => {
|
||||
NativeTooltip.show(event, item.title, NativeTooltip.POSITIONS.TOP);
|
||||
}}
|
||||
style={{
|
||||
width: 35,
|
||||
height: 35,
|
||||
|
||||
@@ -197,16 +197,6 @@ export const SelectionHeader = React.memo(
|
||||
}
|
||||
]
|
||||
: [
|
||||
{
|
||||
title: strings.move(),
|
||||
onPress: async () => {
|
||||
const ids = selectedItemsList;
|
||||
const notebooks = await db.notebooks.all.items(ids);
|
||||
MoveNotebook.present(notebooks);
|
||||
},
|
||||
visible: renderedInRoute === "Notebooks",
|
||||
icon: "arrow-right-bold-box-outline"
|
||||
},
|
||||
{
|
||||
title: strings.manageTags(),
|
||||
onPress: async () => {
|
||||
|
||||
@@ -34,7 +34,7 @@ import { AppFontSize } from "../../../utils/size";
|
||||
import DialogHeader from "../../dialog/dialog-header";
|
||||
import List from "../../list";
|
||||
import SheetProvider from "../../sheet-provider";
|
||||
import { Button } from "../../ui/button";
|
||||
import { Button, ButtonProps } from "../../ui/button";
|
||||
import { PressableProps } from "../../ui/pressable";
|
||||
import Paragraph from "../../ui/typography/paragraph";
|
||||
import { DefaultAppStyles } from "../../../utils/styles";
|
||||
@@ -47,18 +47,10 @@ type RelationsListProps = {
|
||||
referenceType: string;
|
||||
relationType: "to" | "from";
|
||||
title: string;
|
||||
button?: Button;
|
||||
button?: ButtonProps;
|
||||
onAdd: () => void;
|
||||
};
|
||||
|
||||
type Button = {
|
||||
onPress?: (() => void) | undefined;
|
||||
loading?: boolean | undefined;
|
||||
title?: string | undefined;
|
||||
type?: PressableProps["type"];
|
||||
icon?: string;
|
||||
};
|
||||
|
||||
const IconsByType = {
|
||||
reminder: "bell"
|
||||
};
|
||||
@@ -154,7 +146,7 @@ RelationsList.present = ({
|
||||
referenceType: string;
|
||||
relationType: "to" | "from";
|
||||
title: string;
|
||||
button?: Button;
|
||||
button?: ButtonProps;
|
||||
onAdd: () => void;
|
||||
}) => {
|
||||
presentSheet({
|
||||
|
||||
@@ -1,630 +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 { useThemeColors } from "@notesnook/theme";
|
||||
import React, { RefObject, useRef, useState } from "react";
|
||||
import {
|
||||
Platform,
|
||||
TextInput,
|
||||
View,
|
||||
ScrollView as RNScrollView
|
||||
} from "react-native";
|
||||
import { ActionSheetRef, ScrollView } from "react-native-actions-sheet";
|
||||
import DateTimePickerModal from "react-native-modal-datetime-picker";
|
||||
import {
|
||||
PresentSheetOptions,
|
||||
ToastManager,
|
||||
presentSheet
|
||||
} from "../../../services/event-manager";
|
||||
import { defaultBorderRadius, AppFontSize } from "../../../utils/size";
|
||||
import { Button } from "../../ui/button";
|
||||
import Input from "../../ui/input";
|
||||
|
||||
import dayjs from "dayjs";
|
||||
import DatePicker from "react-native-date-picker";
|
||||
import { db } from "../../../common/database";
|
||||
import { DDS } from "../../../services/device-detection";
|
||||
import Navigation from "../../../services/navigation";
|
||||
import Notifications from "../../../services/notifications";
|
||||
import PremiumService from "../../../services/premium";
|
||||
import SettingsService from "../../../services/settings";
|
||||
import { useRelationStore } from "../../../stores/use-relation-store";
|
||||
import { Dialog } from "../../dialog";
|
||||
import { ReminderTime } from "../../ui/reminder-time";
|
||||
import Heading from "../../ui/typography/heading";
|
||||
import Paragraph from "../../ui/typography/paragraph";
|
||||
import { Note, Reminder } from "@notesnook/core";
|
||||
import { strings } from "@notesnook/intl";
|
||||
import { DefaultAppStyles } from "../../../utils/styles";
|
||||
|
||||
type ReminderSheetProps = {
|
||||
actionSheetRef: RefObject<ActionSheetRef>;
|
||||
close?: (ctx?: string) => void;
|
||||
update?: (options: PresentSheetOptions) => void;
|
||||
reminder?: Reminder;
|
||||
reference?: Note;
|
||||
};
|
||||
|
||||
const ReminderModes =
|
||||
Platform.OS === "ios"
|
||||
? {
|
||||
Once: "once",
|
||||
Repeat: "repeat"
|
||||
}
|
||||
: {
|
||||
Once: "once",
|
||||
Repeat: "repeat",
|
||||
Permanent: "permanent"
|
||||
};
|
||||
|
||||
const RecurringModes = {
|
||||
Daily: "day",
|
||||
Week: "week",
|
||||
Month: "month",
|
||||
Year: "year"
|
||||
};
|
||||
|
||||
const WeekDays = new Array(7).fill(true);
|
||||
const MonthDays = new Array(31).fill(true);
|
||||
const WeekDayNames = {
|
||||
0: "Sunday",
|
||||
1: "Monday",
|
||||
2: "Tuesday",
|
||||
3: "Wednesday",
|
||||
4: "Thursday",
|
||||
5: "Friday",
|
||||
6: "Saturday"
|
||||
};
|
||||
|
||||
const ReminderNotificationModes = {
|
||||
Silent: "silent",
|
||||
Vibrate: "vibrate",
|
||||
Urgent: "urgent"
|
||||
};
|
||||
|
||||
export default function ReminderSheet({
|
||||
actionSheetRef,
|
||||
close,
|
||||
update,
|
||||
reminder,
|
||||
reference
|
||||
}: ReminderSheetProps) {
|
||||
const { colors, isDark } = useThemeColors();
|
||||
const [reminderMode, setReminderMode] = useState<Reminder["mode"]>(
|
||||
reminder?.mode || "once"
|
||||
);
|
||||
const [recurringMode, setRecurringMode] = useState<Reminder["recurringMode"]>(
|
||||
reminder?.recurringMode || "week"
|
||||
);
|
||||
const [selectedDays, setSelectedDays] = useState<number[]>(
|
||||
reminder?.selectedDays || []
|
||||
);
|
||||
const [date, setDate] = useState<Date>(
|
||||
new Date(reminder?.date || Date.now())
|
||||
);
|
||||
const [reminderNotificationMode, setReminderNotificatioMode] = useState<
|
||||
Reminder["priority"]
|
||||
>(reminder?.priority || SettingsService.get().reminderNotificationMode);
|
||||
const [isDatePickerVisible, setDatePickerVisibility] = useState(false);
|
||||
const [repeatFrequency, setRepeatFrequency] = useState(1);
|
||||
const referencedItem = reference ? (reference as Note) : null;
|
||||
|
||||
const title = useRef<string | undefined>(
|
||||
!reminder ? referencedItem?.title : reminder?.title
|
||||
);
|
||||
const details = useRef<string | undefined>(
|
||||
!reminder ? referencedItem?.headline : reminder?.description
|
||||
);
|
||||
const titleRef = useRef<TextInput>(null);
|
||||
const timer = useRef<NodeJS.Timeout>();
|
||||
|
||||
const showDatePicker = () => {
|
||||
setDatePickerVisibility(true);
|
||||
};
|
||||
|
||||
const hideDatePicker = () => {
|
||||
setDatePickerVisibility(false);
|
||||
};
|
||||
|
||||
const handleConfirm = (date: Date) => {
|
||||
timer.current = setTimeout(() => {
|
||||
hideDatePicker();
|
||||
setDate(date);
|
||||
}, 50);
|
||||
};
|
||||
function nth(n: number) {
|
||||
return (
|
||||
["st", "nd", "rd"][(((((n < 0 ? -n : n) + 90) % 100) - 10) % 10) - 1] ||
|
||||
"th"
|
||||
);
|
||||
}
|
||||
|
||||
function getSelectedDaysText(selectedDays: number[]) {
|
||||
const text = selectedDays
|
||||
.sort((a, b) => a - b)
|
||||
.map((day, index) => {
|
||||
const isLast = index === selectedDays.length - 1;
|
||||
const isSecondLast = index === selectedDays.length - 2;
|
||||
const joinWith = isSecondLast ? " & " : isLast ? "" : ", ";
|
||||
return recurringMode === RecurringModes.Week
|
||||
? WeekDayNames[day as keyof typeof WeekDayNames] + joinWith
|
||||
: `${day}${nth(day)} ${joinWith}`;
|
||||
})
|
||||
.join("");
|
||||
return text;
|
||||
}
|
||||
|
||||
async function saveReminder() {
|
||||
try {
|
||||
if (!(await Notifications.checkAndRequestPermissions(true)))
|
||||
throw new Error(strings.noNotificationPermission());
|
||||
if (!date && reminderMode !== ReminderModes.Permanent) return;
|
||||
if (
|
||||
reminderMode === ReminderModes.Repeat &&
|
||||
recurringMode !== "day" &&
|
||||
recurringMode !== "year" &&
|
||||
selectedDays.length === 0
|
||||
)
|
||||
throw new Error(strings.selectDayError());
|
||||
|
||||
if (!title.current) throw new Error(strings.setTitleError());
|
||||
if (date.getTime() < Date.now() && reminderMode === "once") {
|
||||
titleRef?.current?.focus();
|
||||
throw new Error(strings.dateError());
|
||||
}
|
||||
|
||||
date.setSeconds(0, 0);
|
||||
|
||||
const reminderId = await db.reminders?.add({
|
||||
id: reminder?.id,
|
||||
date: date?.getTime(),
|
||||
priority: reminderNotificationMode,
|
||||
title: title.current,
|
||||
description: details.current,
|
||||
recurringMode: recurringMode,
|
||||
selectedDays: selectedDays,
|
||||
mode: reminderMode,
|
||||
localOnly: reminderMode === "permanent",
|
||||
snoozeUntil:
|
||||
date?.getTime() > Date.now() ? undefined : reminder?.snoozeUntil,
|
||||
disabled: false
|
||||
});
|
||||
if (!reminderId) return;
|
||||
const _reminder = await db.reminders?.reminder(reminderId);
|
||||
|
||||
if (reference && _reminder) {
|
||||
await db.relations?.add(reference, {
|
||||
id: _reminder?.id as string,
|
||||
type: _reminder?.type
|
||||
});
|
||||
}
|
||||
Notifications.scheduleNotification(_reminder as Reminder);
|
||||
Navigation.queueRoutesForUpdate();
|
||||
useRelationStore.getState().update();
|
||||
close?.();
|
||||
} catch (e) {
|
||||
ToastManager.error(e as Error, undefined, "local");
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
paddingHorizontal: DefaultAppStyles.GAP,
|
||||
maxHeight: "100%"
|
||||
}}
|
||||
>
|
||||
<Heading size={AppFontSize.lg}>
|
||||
{reminder ? strings.editReminder() : strings.newReminder()}
|
||||
</Heading>
|
||||
|
||||
<Dialog context="local" />
|
||||
<ScrollView
|
||||
bounces={false}
|
||||
style={{
|
||||
marginBottom: DDS.isTab ? 25 : undefined
|
||||
}}
|
||||
>
|
||||
<Input
|
||||
fwdRef={titleRef}
|
||||
defaultValue={reminder?.title || referencedItem?.title}
|
||||
placeholder={strings.remindeMeOf()}
|
||||
onChangeText={(text) => (title.current = text)}
|
||||
wrapperStyle={{
|
||||
marginTop: DefaultAppStyles.GAP_VERTICAL
|
||||
}}
|
||||
/>
|
||||
|
||||
<Input
|
||||
defaultValue={
|
||||
reminder ? reminder?.description : referencedItem?.headline
|
||||
}
|
||||
placeholder={strings.addShortNote()}
|
||||
onChangeText={(text) => (details.current = text)}
|
||||
containerStyle={{
|
||||
maxHeight: 80
|
||||
}}
|
||||
multiline
|
||||
textAlignVertical="top"
|
||||
inputStyle={{
|
||||
minHeight: 80,
|
||||
paddingVertical: DefaultAppStyles.GAP_VERTICAL
|
||||
}}
|
||||
height={80}
|
||||
wrapperStyle={{
|
||||
marginBottom: DefaultAppStyles.GAP_VERTICAL
|
||||
}}
|
||||
/>
|
||||
|
||||
<ScrollView
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
marginBottom: DefaultAppStyles.GAP_VERTICAL,
|
||||
height: 50
|
||||
}}
|
||||
horizontal
|
||||
>
|
||||
{Object.keys(ReminderModes).map((mode) => (
|
||||
<Button
|
||||
key={mode}
|
||||
title={strings.reminderModes(
|
||||
ReminderModes[mode as keyof typeof ReminderModes] as string
|
||||
)}
|
||||
style={{
|
||||
marginRight: 12,
|
||||
borderRadius: 100,
|
||||
minWidth: 70,
|
||||
paddingVertical: DefaultAppStyles.GAP_VERTICAL_SMALL
|
||||
}}
|
||||
proTag={mode === "Repeat"}
|
||||
height={35}
|
||||
type={
|
||||
reminderMode ===
|
||||
ReminderModes[mode as keyof typeof ReminderModes]
|
||||
? "selected"
|
||||
: "plain"
|
||||
}
|
||||
onPress={() => {
|
||||
if (mode === "Repeat" && !PremiumService.get()) return;
|
||||
setReminderMode(
|
||||
ReminderModes[
|
||||
mode as keyof typeof ReminderModes
|
||||
] as Reminder["mode"]
|
||||
);
|
||||
if (mode === "Repeat") {
|
||||
setSelectedDays((days) => {
|
||||
if (days.length > 0) return days;
|
||||
if (days.indexOf(date.getDay()) > -1) {
|
||||
return days;
|
||||
}
|
||||
days.push(date.getDay());
|
||||
return [...days];
|
||||
});
|
||||
}
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</ScrollView>
|
||||
|
||||
{reminderMode === ReminderModes.Repeat ? (
|
||||
<View
|
||||
style={{
|
||||
backgroundColor: colors.secondary.background,
|
||||
padding: DefaultAppStyles.GAP,
|
||||
borderRadius: defaultBorderRadius,
|
||||
marginBottom: DefaultAppStyles.GAP_VERTICAL
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
marginBottom:
|
||||
recurringMode === "day" || recurringMode === "year" ? 0 : 12,
|
||||
alignItems: "center"
|
||||
}}
|
||||
>
|
||||
{Object.keys(RecurringModes).map((mode) => (
|
||||
<Button
|
||||
key={mode}
|
||||
title={strings.recurringModes(
|
||||
RecurringModes[mode as keyof typeof RecurringModes]
|
||||
)}
|
||||
style={{
|
||||
marginRight: 6,
|
||||
borderRadius: 100,
|
||||
paddingVertical: DefaultAppStyles.GAP_VERTICAL_SMALL
|
||||
}}
|
||||
type={
|
||||
recurringMode ===
|
||||
RecurringModes[mode as keyof typeof RecurringModes]
|
||||
? "selected"
|
||||
: "plain"
|
||||
}
|
||||
onPress={() => {
|
||||
setRecurringMode(
|
||||
RecurringModes[
|
||||
mode as keyof typeof RecurringModes
|
||||
] as Reminder["recurringMode"]
|
||||
);
|
||||
setSelectedDays([]);
|
||||
setRepeatFrequency(1);
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</View>
|
||||
|
||||
<RNScrollView showsHorizontalScrollIndicator={false} horizontal>
|
||||
{recurringMode === RecurringModes.Daily ||
|
||||
recurringMode === RecurringModes.Year
|
||||
? null
|
||||
: recurringMode === RecurringModes.Week
|
||||
? WeekDays.map((item, index) => (
|
||||
<Button
|
||||
key={strings.weekDayNamesShort[
|
||||
index as keyof typeof strings.weekDayNamesShort
|
||||
]()}
|
||||
title={strings.weekDayNamesShort[
|
||||
index as keyof typeof strings.weekDayNamesShort
|
||||
]()}
|
||||
type={
|
||||
selectedDays.indexOf(index) > -1 ? "selected" : "plain"
|
||||
}
|
||||
fontSize={AppFontSize.xs}
|
||||
style={{
|
||||
height: 40,
|
||||
borderRadius: 100,
|
||||
marginRight: 10
|
||||
}}
|
||||
onPress={() => {
|
||||
setSelectedDays((days) => {
|
||||
if (days.indexOf(index) > -1) {
|
||||
days.splice(days.indexOf(index), 1);
|
||||
return [...days];
|
||||
}
|
||||
days.push(index);
|
||||
return [...days];
|
||||
});
|
||||
}}
|
||||
/>
|
||||
))
|
||||
: MonthDays.map((item, index) => (
|
||||
<Button
|
||||
key={index + "monthday"}
|
||||
title={index + 1 + ""}
|
||||
type={
|
||||
selectedDays.indexOf(index + 1) > -1
|
||||
? "selected"
|
||||
: "plain"
|
||||
}
|
||||
fontSize={AppFontSize.xs}
|
||||
style={{
|
||||
height: 40,
|
||||
borderRadius: 100,
|
||||
marginRight: 10
|
||||
}}
|
||||
onPress={() => {
|
||||
setSelectedDays((days) => {
|
||||
if (days.indexOf(index + 1) > -1) {
|
||||
days.splice(days.indexOf(index + 1), 1);
|
||||
return [...days];
|
||||
}
|
||||
days.push(index + 1);
|
||||
return [...days];
|
||||
});
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</RNScrollView>
|
||||
</View>
|
||||
) : null}
|
||||
|
||||
{reminderMode === ReminderModes.Permanent ? null : (
|
||||
<View
|
||||
style={{
|
||||
width: "100%",
|
||||
flexDirection: "column",
|
||||
justifyContent: "center",
|
||||
marginBottom: DefaultAppStyles.GAP_VERTICAL,
|
||||
alignItems: "center"
|
||||
}}
|
||||
>
|
||||
<DateTimePickerModal
|
||||
isVisible={isDatePickerVisible}
|
||||
mode="date"
|
||||
onConfirm={handleConfirm}
|
||||
onCancel={hideDatePicker}
|
||||
is24Hour={db.settings.getTimeFormat() === "24-hour"}
|
||||
date={date || new Date(Date.now())}
|
||||
/>
|
||||
|
||||
<DatePicker
|
||||
date={date}
|
||||
maximumDate={dayjs(date).add(3, "months").toDate()}
|
||||
onDateChange={handleConfirm}
|
||||
textColor={isDark ? colors.static.white : colors.static.black}
|
||||
fadeToColor={colors.primary.background}
|
||||
theme={isDark ? "dark" : "light"}
|
||||
androidVariant="nativeAndroid"
|
||||
is24hourSource="locale"
|
||||
locale={
|
||||
db.settings?.getTimeFormat() === "24-hour" ? "en_GB" : "en_US"
|
||||
}
|
||||
mode={
|
||||
reminderMode === ReminderModes.Repeat &&
|
||||
recurringMode !== "year"
|
||||
? "time"
|
||||
: "datetime"
|
||||
}
|
||||
/>
|
||||
|
||||
{reminderMode === ReminderModes.Repeat ? null : (
|
||||
<Button
|
||||
style={{
|
||||
width: "100%"
|
||||
}}
|
||||
title={date ? date.toLocaleDateString() : strings.selectDate()}
|
||||
type={date ? "secondaryAccented" : "secondary"}
|
||||
icon="calendar"
|
||||
fontSize={AppFontSize.sm}
|
||||
onPress={() => {
|
||||
showDatePicker();
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</View>
|
||||
)}
|
||||
|
||||
{reminderMode === ReminderModes.Once ||
|
||||
reminderMode === ReminderModes.Permanent ? null : (
|
||||
<View
|
||||
style={{
|
||||
borderRadius: defaultBorderRadius,
|
||||
flexDirection: "row",
|
||||
paddingVertical: DefaultAppStyles.GAP_VERTICAL_SMALL,
|
||||
alignItems: "center",
|
||||
justifyContent: "flex-start",
|
||||
marginBottom: DefaultAppStyles.GAP_VERTICAL
|
||||
}}
|
||||
>
|
||||
<>
|
||||
<Paragraph
|
||||
size={AppFontSize.xxs}
|
||||
color={colors.secondary.paragraph}
|
||||
>
|
||||
{recurringMode === RecurringModes.Daily
|
||||
? strings.reminderRepeatStrings.day(
|
||||
dayjs(date).format("hh:mm A")
|
||||
)
|
||||
: recurringMode === RecurringModes.Year
|
||||
? strings.reminderRepeatStrings.year(
|
||||
dayjs(date).format("dddd, MMMM D, h:mm A")
|
||||
)
|
||||
: selectedDays.length === 7 &&
|
||||
recurringMode === RecurringModes.Week
|
||||
? strings.reminderRepeatStrings.week.daily(
|
||||
dayjs(date).format("hh:mm A")
|
||||
)
|
||||
: selectedDays.length === 0
|
||||
? strings.reminderRepeatStrings[
|
||||
recurringMode as "week" | "month"
|
||||
].selectDays()
|
||||
: strings.reminderRepeatStrings.repeats(
|
||||
repeatFrequency,
|
||||
recurringMode as string,
|
||||
getSelectedDaysText(selectedDays),
|
||||
dayjs(date).format("hh:mm A")
|
||||
)}
|
||||
</Paragraph>
|
||||
</>
|
||||
</View>
|
||||
)}
|
||||
|
||||
<ReminderTime
|
||||
reminder={reminder}
|
||||
style={{
|
||||
width: "100%",
|
||||
justifyContent: "flex-start",
|
||||
borderWidth: 0,
|
||||
paddingVertical: DefaultAppStyles.GAP_VERTICAL_SMALL,
|
||||
alignSelf: "flex-start"
|
||||
}}
|
||||
/>
|
||||
|
||||
{reminderMode === ReminderModes.Permanent ? null : (
|
||||
<RNScrollView
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
marginTop: DefaultAppStyles.GAP_VERTICAL,
|
||||
height: 50
|
||||
}}
|
||||
horizontal
|
||||
>
|
||||
{Object.keys(ReminderNotificationModes).map((mode) => (
|
||||
<Button
|
||||
key={mode}
|
||||
title={strings.reminderNotificationModes(
|
||||
mode as keyof typeof ReminderNotificationModes
|
||||
)}
|
||||
style={{
|
||||
marginRight: 12,
|
||||
borderRadius: 100,
|
||||
paddingVertical: DefaultAppStyles.GAP_VERTICAL_SMALL
|
||||
}}
|
||||
icon={
|
||||
mode === "Silent"
|
||||
? "minus-circle"
|
||||
: mode === "Vibrate"
|
||||
? "vibrate"
|
||||
: "volume-high"
|
||||
}
|
||||
height={35}
|
||||
type={
|
||||
reminderNotificationMode ===
|
||||
ReminderNotificationModes[
|
||||
mode as keyof typeof ReminderNotificationModes
|
||||
]
|
||||
? "selected"
|
||||
: "plain"
|
||||
}
|
||||
onPress={() => {
|
||||
const _mode = ReminderNotificationModes[
|
||||
mode as keyof typeof ReminderNotificationModes
|
||||
] as Reminder["priority"];
|
||||
SettingsService.set({
|
||||
reminderNotificationMode: _mode
|
||||
});
|
||||
setReminderNotificatioMode(_mode);
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</RNScrollView>
|
||||
)}
|
||||
</ScrollView>
|
||||
|
||||
<Button
|
||||
title={strings.save()}
|
||||
type="accent"
|
||||
style={{
|
||||
paddingHorizontal: DefaultAppStyles.GAP * 2,
|
||||
marginTop: DefaultAppStyles.GAP_VERTICAL,
|
||||
width: "100%"
|
||||
}}
|
||||
onPress={saveReminder}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
ReminderSheet.present = (
|
||||
reminder?: Reminder,
|
||||
reference?: Note,
|
||||
isSheet?: boolean
|
||||
) => {
|
||||
presentSheet({
|
||||
context: isSheet ? "local" : undefined,
|
||||
component: (ref, close, update) => (
|
||||
<ReminderSheet
|
||||
actionSheetRef={ref}
|
||||
close={close}
|
||||
update={update}
|
||||
reminder={reminder}
|
||||
reference={reference}
|
||||
/>
|
||||
)
|
||||
});
|
||||
};
|
||||
@@ -40,6 +40,7 @@ import Sync from "../../../services/sync";
|
||||
|
||||
import Clipboard from "@react-native-clipboard/clipboard";
|
||||
import { logoutUser } from "../../../screens/settings/logout";
|
||||
import { sleep } from "../../../utils/time";
|
||||
export const UserSheet = () => {
|
||||
const ref = useSheetRef();
|
||||
const { colors } = useThemeColors();
|
||||
@@ -310,10 +311,11 @@ export const UserSheet = () => {
|
||||
{
|
||||
icon: "logout",
|
||||
title: strings.logout(),
|
||||
onPress: () => {
|
||||
onPress: async () => {
|
||||
console.log("logout");
|
||||
logoutUser();
|
||||
ref.current?.hide();
|
||||
await sleep(300);
|
||||
logoutUser();
|
||||
},
|
||||
hidden: !user
|
||||
}
|
||||
|
||||
@@ -211,6 +211,14 @@ const TabBar = (
|
||||
const ids = useSideMenuNotebookSelectionStore
|
||||
.getState()
|
||||
.getSelectedItemIds();
|
||||
if (!ids.length) {
|
||||
ToastManager.show({
|
||||
context: "local",
|
||||
type: "error",
|
||||
message: strings.noNotebooksSelectedToMove()
|
||||
});
|
||||
return;
|
||||
}
|
||||
const notebooks = await db.notebooks.all.items(ids);
|
||||
Navigation.navigate("MoveNotebook", {
|
||||
selectedNotebooks: notebooks
|
||||
|
||||
@@ -23,13 +23,11 @@ import { Platform, View } from "react-native";
|
||||
import ActionSheet from "react-native-actions-sheet";
|
||||
import useGlobalSafeAreaInsets from "../../../hooks/use-global-safe-area-insets";
|
||||
import { useSettingStore } from "../../../stores/use-setting-store";
|
||||
import { PremiumToast } from "../../premium/premium-toast";
|
||||
import { Toast } from "../../toast";
|
||||
import { useAppState } from "../../../hooks/use-app-state";
|
||||
import SettingsService from "../../../services/settings";
|
||||
import { useUserStore } from "../../../stores/use-user-store";
|
||||
import { getContainerBorder } from "../../../utils/colors";
|
||||
|
||||
import { PremiumToast } from "../../premium/premium-toast";
|
||||
import { Toast } from "../../toast";
|
||||
import { NotesnookModule } from "../../../utils/notesnook-module";
|
||||
/**
|
||||
*
|
||||
* @param {any} param0
|
||||
@@ -63,6 +61,10 @@ const SheetWrapper = ({
|
||||
const locked = useUserStore((state) => state.appLocked);
|
||||
|
||||
let width = dimensions.width > 600 ? 600 : 500;
|
||||
const isGestureNavigationEnabled =
|
||||
NotesnookModule.isGestureNavigationEnabled();
|
||||
|
||||
console.log(isGestureNavigationEnabled);
|
||||
|
||||
const style = React.useMemo(() => {
|
||||
return {
|
||||
@@ -77,14 +79,18 @@ const SheetWrapper = ({
|
||||
borderBottomRightRadius: 0,
|
||||
borderBottomLeftRadius: 0,
|
||||
...getContainerBorder(colors.primary.border, 0.5),
|
||||
borderBottomWidth: 0
|
||||
borderBottomWidth: 0,
|
||||
paddingBottom: isGestureNavigationEnabled
|
||||
? insets.bottom
|
||||
: insets.bottom || 48
|
||||
};
|
||||
}, [
|
||||
colors.primary.background,
|
||||
colors.primary.border,
|
||||
largeTablet,
|
||||
smallTablet,
|
||||
width
|
||||
width,
|
||||
insets.bottom
|
||||
]);
|
||||
|
||||
const _onOpen = () => {
|
||||
|
||||
@@ -41,7 +41,6 @@ import ExportNotesSheet from "../components/sheets/export-notes";
|
||||
import PublishNoteSheet from "../components/sheets/publish-note";
|
||||
import { ReferencesList } from "../components/sheets/references";
|
||||
import { RelationsList } from "../components/sheets/relations-list/index";
|
||||
import ReminderSheet from "../components/sheets/reminder";
|
||||
import { useSideBarDraggingStore } from "../components/side-menu/dragging-store";
|
||||
import { ButtonProps } from "../components/ui/button";
|
||||
import { useTabStore } from "../screens/editor/tiptap/use-tab-store";
|
||||
@@ -54,19 +53,20 @@ import {
|
||||
} from "../services/event-manager";
|
||||
import Navigation from "../services/navigation";
|
||||
import Notifications from "../services/notifications";
|
||||
import SettingsService from "../services/settings";
|
||||
import { useArchivedStore } from "../stores/use-archived-store";
|
||||
import { useMenuStore } from "../stores/use-menu-store";
|
||||
import useNavigationStore from "../stores/use-navigation-store";
|
||||
import { useRelationStore } from "../stores/use-relation-store";
|
||||
import { useSelectionStore } from "../stores/use-selection-store";
|
||||
import { useSettingStore } from "../stores/use-setting-store";
|
||||
import { useTagStore } from "../stores/use-tag-store";
|
||||
import { useUserStore } from "../stores/use-user-store";
|
||||
import { eUpdateNoteInEditor } from "../utils/events";
|
||||
import { deleteItems } from "../utils/functions";
|
||||
import { convertNoteToText } from "../utils/note-to-text";
|
||||
import { sleep } from "../utils/time";
|
||||
import SettingsService from "../services/settings";
|
||||
import { useSettingStore } from "../stores/use-setting-store";
|
||||
import { useArchivedStore } from "../stores/use-archived-store";
|
||||
import AddReminder from "../screens/add-reminder";
|
||||
|
||||
export type ActionId =
|
||||
| "select"
|
||||
@@ -448,7 +448,8 @@ export const useActions = ({
|
||||
title: strings.editReminder(),
|
||||
icon: "pencil",
|
||||
onPress: async () => {
|
||||
ReminderSheet.present(item);
|
||||
AddReminder.present(item);
|
||||
close();
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -908,12 +909,18 @@ export const useActions = ({
|
||||
referenceType: "reminder",
|
||||
relationType: "from",
|
||||
title: strings.dataTypesPluralCamelCase.reminder(),
|
||||
onAdd: () => ReminderSheet.present(undefined, item, true),
|
||||
onAdd: () => {
|
||||
AddReminder.present(undefined, item);
|
||||
close();
|
||||
},
|
||||
button: {
|
||||
title: strings.add(),
|
||||
type: "accent",
|
||||
onPress: () => ReminderSheet.present(undefined, item, true),
|
||||
icon: "plus"
|
||||
type: "plain",
|
||||
onPress: () => {
|
||||
AddReminder.present(undefined, item);
|
||||
close();
|
||||
},
|
||||
icon: "plus",
|
||||
iconSize: 20
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -957,7 +964,8 @@ export const useActions = ({
|
||||
title: strings.remindMe(),
|
||||
icon: "clock-plus-outline",
|
||||
onPress: () => {
|
||||
ReminderSheet.present(undefined, item);
|
||||
close();
|
||||
AddReminder.present(undefined, item);
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -49,7 +49,6 @@ import { MMKV } from "../common/database/mmkv";
|
||||
import { endProgress, startProgress } from "../components/dialogs/progress";
|
||||
import Migrate from "../components/sheets/migrate";
|
||||
import NewFeature from "../components/sheets/new-feature";
|
||||
import ReminderSheet from "../components/sheets/reminder";
|
||||
import { Walkthrough } from "../components/walkthroughs";
|
||||
import {
|
||||
resetTabStore,
|
||||
@@ -103,6 +102,7 @@ import { getGithubVersion } from "../utils/github-version";
|
||||
import { fluidTabsRef } from "../utils/global-refs";
|
||||
import { NotesnookModule } from "../utils/notesnook-module";
|
||||
import { sleep } from "../utils/time";
|
||||
import AddReminder from "../screens/add-reminder";
|
||||
|
||||
const onCheckSyncStatus = async (type: SyncStatusEvent) => {
|
||||
const { disableSync, disableAutoSync } = SettingsService.get();
|
||||
@@ -182,10 +182,10 @@ const onAppOpenedFromURL = async (event: { url: string }) => {
|
||||
const id = new URL(url).searchParams.get("id");
|
||||
if (id) {
|
||||
const reminder = await db.reminders.reminder(id);
|
||||
if (reminder) ReminderSheet.present(reminder);
|
||||
if (reminder) AddReminder.present(reminder);
|
||||
}
|
||||
} else if (url.startsWith("https://notesnook.com/new_reminder")) {
|
||||
ReminderSheet.present();
|
||||
AddReminder.present();
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
|
||||
@@ -52,7 +52,14 @@ const useTimer = (initialId?: string) => {
|
||||
};
|
||||
}, [seconds, id]);
|
||||
|
||||
return { seconds, setId, start };
|
||||
const reset = () => {
|
||||
if (id) {
|
||||
timers[id] = 0;
|
||||
setSeconds(0);
|
||||
}
|
||||
};
|
||||
|
||||
return { seconds, setId, start, reset };
|
||||
};
|
||||
|
||||
export default useTimer;
|
||||
|
||||
@@ -421,7 +421,6 @@ export const FluidPanelsView = React.memo(
|
||||
height: "100%",
|
||||
width: "100%",
|
||||
backgroundColor: colors.primary.background,
|
||||
paddingBottom: Platform.OS === "android" ? insets?.bottom : 0,
|
||||
marginRight:
|
||||
orientation === "LANDSCAPE-RIGHT" && Platform.OS === "ios"
|
||||
? insets.right
|
||||
@@ -530,17 +529,11 @@ const onChangeTab = async (event: { i: number; from: number }) => {
|
||||
activateKeepAwake();
|
||||
eSendEvent(eOnEnterEditor);
|
||||
|
||||
if (!useTabStore.getState().getCurrentNoteId()) {
|
||||
eSendEvent(eOnLoadNote, {
|
||||
newNote: true
|
||||
});
|
||||
} else {
|
||||
if (
|
||||
useTabStore.getState().getTab(useTabStore.getState().currentTab)
|
||||
?.session?.locked
|
||||
) {
|
||||
eSendEvent(eUnlockNote);
|
||||
}
|
||||
if (
|
||||
useTabStore.getState().getTab(useTabStore.getState().currentTab)?.session
|
||||
?.locked
|
||||
) {
|
||||
eSendEvent(eUnlockNote);
|
||||
}
|
||||
} else {
|
||||
if (event.from === 2) {
|
||||
|
||||
@@ -21,6 +21,7 @@ import { useThemeColors } from "@notesnook/theme";
|
||||
import { NavigationContainer } from "@react-navigation/native";
|
||||
import { createNativeStackNavigator } from "@react-navigation/native-stack";
|
||||
import * as React from "react";
|
||||
import { db } from "../common/database";
|
||||
import { hideAllTooltips } from "../hooks/use-tooltip";
|
||||
import SettingsService from "../services/settings";
|
||||
import useNavigationStore, {
|
||||
@@ -29,7 +30,6 @@ import useNavigationStore, {
|
||||
import { useSelectionStore } from "../stores/use-selection-store";
|
||||
import { useSettingStore } from "../stores/use-setting-store";
|
||||
import { rootNavigatorRef } from "../utils/global-refs";
|
||||
import { db } from "../common/database";
|
||||
|
||||
const RootStack = createNativeStackNavigator();
|
||||
const AppStack = createNativeStackNavigator();
|
||||
@@ -248,6 +248,7 @@ let MoveNotebook: any = null;
|
||||
let MoveNotes: any = null;
|
||||
let Settings: any = null;
|
||||
let ManageTags: any = null;
|
||||
let AddReminder: any = null;
|
||||
|
||||
export const RootNavigation = () => {
|
||||
const introCompleted = useSettingStore(
|
||||
@@ -336,6 +337,15 @@ export const RootNavigation = () => {
|
||||
return ManageTags;
|
||||
}}
|
||||
/>
|
||||
|
||||
<RootStack.Screen
|
||||
name="AddReminder"
|
||||
getComponent={() => {
|
||||
AddReminder =
|
||||
AddReminder || require("../screens/add-reminder").default;
|
||||
return AddReminder;
|
||||
}}
|
||||
/>
|
||||
</RootStack.Navigator>
|
||||
</NavigationContainer>
|
||||
);
|
||||
|
||||
608
apps/mobile/app/screens/add-reminder/index.tsx
Normal file
608
apps/mobile/app/screens/add-reminder/index.tsx
Normal file
@@ -0,0 +1,608 @@
|
||||
/*
|
||||
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 { Note, Reminder } from "@notesnook/core";
|
||||
import { strings } from "@notesnook/intl";
|
||||
import { useThemeColors } from "@notesnook/theme";
|
||||
import dayjs from "dayjs";
|
||||
import React, { useRef, useState } from "react";
|
||||
import {
|
||||
KeyboardAvoidingView,
|
||||
Platform,
|
||||
ScrollView,
|
||||
TextInput,
|
||||
View
|
||||
} from "react-native";
|
||||
import DatePicker from "react-native-date-picker";
|
||||
import DateTimePickerModal from "react-native-modal-datetime-picker";
|
||||
import { SafeAreaView } from "react-native-safe-area-context";
|
||||
import { db } from "../../common/database";
|
||||
import { Dialog } from "../../components/dialog";
|
||||
import { Header } from "../../components/header";
|
||||
import { Button } from "../../components/ui/button";
|
||||
import Input from "../../components/ui/input";
|
||||
import { ReminderTime } from "../../components/ui/reminder-time";
|
||||
import Paragraph from "../../components/ui/typography/paragraph";
|
||||
import { DDS } from "../../services/device-detection";
|
||||
import { ToastManager } from "../../services/event-manager";
|
||||
import Navigation, { NavigationProps } from "../../services/navigation";
|
||||
import Notifications from "../../services/notifications";
|
||||
import PremiumService from "../../services/premium";
|
||||
import SettingsService from "../../services/settings";
|
||||
import { useRelationStore } from "../../stores/use-relation-store";
|
||||
import { AppFontSize, defaultBorderRadius } from "../../utils/size";
|
||||
import { DefaultAppStyles } from "../../utils/styles";
|
||||
|
||||
const ReminderModes =
|
||||
Platform.OS === "ios"
|
||||
? {
|
||||
Once: "once",
|
||||
Repeat: "repeat"
|
||||
}
|
||||
: {
|
||||
Once: "once",
|
||||
Repeat: "repeat",
|
||||
Permanent: "permanent"
|
||||
};
|
||||
|
||||
const RecurringModes = {
|
||||
Daily: "day",
|
||||
Week: "week",
|
||||
Month: "month",
|
||||
Year: "year"
|
||||
};
|
||||
|
||||
const WeekDays = new Array(7).fill(true);
|
||||
const MonthDays = new Array(31).fill(true);
|
||||
const WeekDayNames = {
|
||||
0: "Sunday",
|
||||
1: "Monday",
|
||||
2: "Tuesday",
|
||||
3: "Wednesday",
|
||||
4: "Thursday",
|
||||
5: "Friday",
|
||||
6: "Saturday"
|
||||
};
|
||||
|
||||
const ReminderNotificationModes = {
|
||||
Silent: "silent",
|
||||
Vibrate: "vibrate",
|
||||
Urgent: "urgent"
|
||||
};
|
||||
|
||||
export default function AddReminder(props: NavigationProps<"AddReminder">) {
|
||||
const { reminder, reference } = props.route.params;
|
||||
const { colors, isDark } = useThemeColors();
|
||||
const [reminderMode, setReminderMode] = useState<Reminder["mode"]>(
|
||||
reminder?.mode || "once"
|
||||
);
|
||||
const [recurringMode, setRecurringMode] = useState<Reminder["recurringMode"]>(
|
||||
reminder?.recurringMode || "week"
|
||||
);
|
||||
const [selectedDays, setSelectedDays] = useState<number[]>(
|
||||
reminder?.selectedDays || []
|
||||
);
|
||||
const [date, setDate] = useState<Date>(
|
||||
new Date(reminder?.date || Date.now())
|
||||
);
|
||||
const [reminderNotificationMode, setReminderNotificatioMode] = useState<
|
||||
Reminder["priority"]
|
||||
>(reminder?.priority || SettingsService.get().reminderNotificationMode);
|
||||
const [isDatePickerVisible, setDatePickerVisibility] = useState(false);
|
||||
const [repeatFrequency, setRepeatFrequency] = useState(1);
|
||||
const referencedItem = reference ? (reference as Note) : null;
|
||||
|
||||
const title = useRef<string | undefined>(
|
||||
!reminder ? referencedItem?.title : reminder?.title
|
||||
);
|
||||
const details = useRef<string | undefined>(
|
||||
!reminder ? referencedItem?.headline : reminder?.description
|
||||
);
|
||||
const titleRef = useRef<TextInput>(null);
|
||||
const timer = useRef<NodeJS.Timeout>();
|
||||
|
||||
const showDatePicker = () => {
|
||||
setDatePickerVisibility(true);
|
||||
};
|
||||
|
||||
const hideDatePicker = () => {
|
||||
setDatePickerVisibility(false);
|
||||
};
|
||||
|
||||
const handleConfirm = (date: Date) => {
|
||||
timer.current = setTimeout(() => {
|
||||
hideDatePicker();
|
||||
setDate(date);
|
||||
}, 50);
|
||||
};
|
||||
function nth(n: number) {
|
||||
return (
|
||||
["st", "nd", "rd"][(((((n < 0 ? -n : n) + 90) % 100) - 10) % 10) - 1] ||
|
||||
"th"
|
||||
);
|
||||
}
|
||||
|
||||
function getSelectedDaysText(selectedDays: number[]) {
|
||||
const text = selectedDays
|
||||
.sort((a, b) => a - b)
|
||||
.map((day, index) => {
|
||||
const isLast = index === selectedDays.length - 1;
|
||||
const isSecondLast = index === selectedDays.length - 2;
|
||||
const joinWith = isSecondLast ? " & " : isLast ? "" : ", ";
|
||||
return recurringMode === RecurringModes.Week
|
||||
? WeekDayNames[day as keyof typeof WeekDayNames] + joinWith
|
||||
: `${day}${nth(day)} ${joinWith}`;
|
||||
})
|
||||
.join("");
|
||||
return text;
|
||||
}
|
||||
|
||||
async function saveReminder() {
|
||||
try {
|
||||
if (!(await Notifications.checkAndRequestPermissions(true)))
|
||||
throw new Error(strings.noNotificationPermission());
|
||||
if (!date && reminderMode !== ReminderModes.Permanent) return;
|
||||
if (
|
||||
reminderMode === ReminderModes.Repeat &&
|
||||
recurringMode !== "day" &&
|
||||
recurringMode !== "year" &&
|
||||
selectedDays.length === 0
|
||||
)
|
||||
throw new Error(strings.selectDayError());
|
||||
|
||||
if (!title.current) throw new Error(strings.setTitleError());
|
||||
if (date.getTime() < Date.now() && reminderMode === "once") {
|
||||
titleRef?.current?.focus();
|
||||
throw new Error(strings.dateError());
|
||||
}
|
||||
|
||||
date.setSeconds(0, 0);
|
||||
|
||||
const reminderId = await db.reminders?.add({
|
||||
id: reminder?.id,
|
||||
date: date?.getTime(),
|
||||
priority: reminderNotificationMode,
|
||||
title: title.current,
|
||||
description: details.current,
|
||||
recurringMode: recurringMode,
|
||||
selectedDays: selectedDays,
|
||||
mode: reminderMode,
|
||||
localOnly: reminderMode === "permanent",
|
||||
snoozeUntil:
|
||||
date?.getTime() > Date.now() ? undefined : reminder?.snoozeUntil,
|
||||
disabled: false
|
||||
});
|
||||
if (!reminderId) return;
|
||||
const _reminder = await db.reminders?.reminder(reminderId);
|
||||
|
||||
if (reference && _reminder) {
|
||||
await db.relations?.add(reference, {
|
||||
id: _reminder?.id as string,
|
||||
type: _reminder?.type
|
||||
});
|
||||
}
|
||||
Notifications.scheduleNotification(_reminder as Reminder);
|
||||
Navigation.queueRoutesForUpdate();
|
||||
useRelationStore.getState().update();
|
||||
Navigation.goBack();
|
||||
} catch (e) {
|
||||
ToastManager.error(e as Error, undefined);
|
||||
}
|
||||
}
|
||||
|
||||
const KeyboardViewIOS = Platform.OS === "ios" ? KeyboardAvoidingView : View;
|
||||
|
||||
return (
|
||||
<SafeAreaView
|
||||
style={{
|
||||
backgroundColor: colors.primary.background,
|
||||
flex: 1
|
||||
}}
|
||||
>
|
||||
<KeyboardViewIOS
|
||||
behavior="padding"
|
||||
style={{
|
||||
flex: 1
|
||||
}}
|
||||
>
|
||||
<Header
|
||||
title={reminder ? strings.editReminder() : strings.newReminder()}
|
||||
canGoBack
|
||||
rightButton={{
|
||||
name: "check",
|
||||
onPress: saveReminder
|
||||
}}
|
||||
/>
|
||||
<Dialog context="local" />
|
||||
<ScrollView
|
||||
style={{
|
||||
marginBottom: DDS.isTab ? 25 : undefined,
|
||||
paddingHorizontal: DefaultAppStyles.GAP
|
||||
}}
|
||||
keyboardDismissMode="interactive"
|
||||
keyboardShouldPersistTaps="handled"
|
||||
>
|
||||
<Input
|
||||
fwdRef={titleRef}
|
||||
defaultValue={reminder?.title || referencedItem?.title}
|
||||
placeholder={strings.remindeMeOf()}
|
||||
onChangeText={(text) => (title.current = text)}
|
||||
wrapperStyle={{
|
||||
marginTop: DefaultAppStyles.GAP_VERTICAL
|
||||
}}
|
||||
/>
|
||||
|
||||
<Input
|
||||
defaultValue={
|
||||
reminder ? reminder?.description : referencedItem?.headline
|
||||
}
|
||||
placeholder={strings.addShortNote()}
|
||||
onChangeText={(text) => (details.current = text)}
|
||||
containerStyle={{
|
||||
maxHeight: 80
|
||||
}}
|
||||
multiline
|
||||
textAlignVertical="top"
|
||||
inputStyle={{
|
||||
minHeight: 80,
|
||||
paddingVertical: DefaultAppStyles.GAP_VERTICAL
|
||||
}}
|
||||
height={80}
|
||||
wrapperStyle={{
|
||||
marginBottom: DefaultAppStyles.GAP_VERTICAL
|
||||
}}
|
||||
/>
|
||||
|
||||
<ScrollView
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
marginBottom: DefaultAppStyles.GAP_VERTICAL
|
||||
}}
|
||||
horizontal
|
||||
>
|
||||
{Object.keys(ReminderModes).map((mode) => (
|
||||
<Button
|
||||
key={mode}
|
||||
title={strings.reminderModes(
|
||||
ReminderModes[mode as keyof typeof ReminderModes] as string
|
||||
)}
|
||||
style={{
|
||||
paddingVertical: DefaultAppStyles.GAP_VERTICAL_SMALL,
|
||||
marginRight: DefaultAppStyles.GAP_SMALL
|
||||
}}
|
||||
proTag={mode === "Repeat"}
|
||||
height={35}
|
||||
type={
|
||||
reminderMode ===
|
||||
ReminderModes[mode as keyof typeof ReminderModes]
|
||||
? "selected"
|
||||
: "plain"
|
||||
}
|
||||
onPress={() => {
|
||||
if (mode === "Repeat" && !PremiumService.get()) return;
|
||||
setReminderMode(
|
||||
ReminderModes[
|
||||
mode as keyof typeof ReminderModes
|
||||
] as Reminder["mode"]
|
||||
);
|
||||
if (mode === "Repeat") {
|
||||
setSelectedDays((days) => {
|
||||
if (days.length > 0) return days;
|
||||
if (days.indexOf(date.getDay()) > -1) {
|
||||
return days;
|
||||
}
|
||||
days.push(date.getDay());
|
||||
return [...days];
|
||||
});
|
||||
}
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</ScrollView>
|
||||
|
||||
{reminderMode === ReminderModes.Repeat ? (
|
||||
<View
|
||||
style={{
|
||||
backgroundColor: colors.secondary.background,
|
||||
padding: DefaultAppStyles.GAP,
|
||||
borderRadius: defaultBorderRadius,
|
||||
marginBottom: DefaultAppStyles.GAP_VERTICAL
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
marginBottom:
|
||||
recurringMode === "day" || recurringMode === "year"
|
||||
? 0
|
||||
: 12,
|
||||
alignItems: "center"
|
||||
}}
|
||||
>
|
||||
{Object.keys(RecurringModes).map((mode) => (
|
||||
<Button
|
||||
key={mode}
|
||||
title={strings.recurringModes(
|
||||
RecurringModes[mode as keyof typeof RecurringModes]
|
||||
)}
|
||||
style={{
|
||||
marginRight: 6,
|
||||
borderRadius: 100,
|
||||
paddingVertical: DefaultAppStyles.GAP_VERTICAL_SMALL
|
||||
}}
|
||||
type={
|
||||
recurringMode ===
|
||||
RecurringModes[mode as keyof typeof RecurringModes]
|
||||
? "selected"
|
||||
: "plain"
|
||||
}
|
||||
onPress={() => {
|
||||
setRecurringMode(
|
||||
RecurringModes[
|
||||
mode as keyof typeof RecurringModes
|
||||
] as Reminder["recurringMode"]
|
||||
);
|
||||
setSelectedDays([]);
|
||||
setRepeatFrequency(1);
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</View>
|
||||
|
||||
<ScrollView showsHorizontalScrollIndicator={false} horizontal>
|
||||
{recurringMode === RecurringModes.Daily ||
|
||||
recurringMode === RecurringModes.Year
|
||||
? null
|
||||
: recurringMode === RecurringModes.Week
|
||||
? WeekDays.map((item, index) => (
|
||||
<Button
|
||||
key={strings.weekDayNamesShort[
|
||||
index as keyof typeof strings.weekDayNamesShort
|
||||
]()}
|
||||
title={strings.weekDayNamesShort[
|
||||
index as keyof typeof strings.weekDayNamesShort
|
||||
]()}
|
||||
type={
|
||||
selectedDays.indexOf(index) > -1
|
||||
? "selected"
|
||||
: "plain"
|
||||
}
|
||||
fontSize={AppFontSize.xs}
|
||||
style={{
|
||||
height: 40,
|
||||
borderRadius: 100,
|
||||
marginRight: 10
|
||||
}}
|
||||
onPress={() => {
|
||||
setSelectedDays((days) => {
|
||||
if (days.indexOf(index) > -1) {
|
||||
days.splice(days.indexOf(index), 1);
|
||||
return [...days];
|
||||
}
|
||||
days.push(index);
|
||||
return [...days];
|
||||
});
|
||||
}}
|
||||
/>
|
||||
))
|
||||
: MonthDays.map((item, index) => (
|
||||
<Button
|
||||
key={index + "monthday"}
|
||||
title={index + 1 + ""}
|
||||
type={
|
||||
selectedDays.indexOf(index + 1) > -1
|
||||
? "selected"
|
||||
: "plain"
|
||||
}
|
||||
fontSize={AppFontSize.xs}
|
||||
style={{
|
||||
height: 40,
|
||||
borderRadius: 100,
|
||||
marginRight: 10
|
||||
}}
|
||||
onPress={() => {
|
||||
setSelectedDays((days) => {
|
||||
if (days.indexOf(index + 1) > -1) {
|
||||
days.splice(days.indexOf(index + 1), 1);
|
||||
return [...days];
|
||||
}
|
||||
days.push(index + 1);
|
||||
return [...days];
|
||||
});
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</ScrollView>
|
||||
</View>
|
||||
) : null}
|
||||
|
||||
{reminderMode === ReminderModes.Permanent ? null : (
|
||||
<View
|
||||
style={{
|
||||
width: "100%",
|
||||
flexDirection: "column",
|
||||
justifyContent: "center",
|
||||
marginBottom: DefaultAppStyles.GAP_VERTICAL,
|
||||
alignItems: "center"
|
||||
}}
|
||||
>
|
||||
<DateTimePickerModal
|
||||
isVisible={isDatePickerVisible}
|
||||
mode="date"
|
||||
onConfirm={handleConfirm}
|
||||
onCancel={hideDatePicker}
|
||||
is24Hour={db.settings.getTimeFormat() === "24-hour"}
|
||||
date={date || new Date(Date.now())}
|
||||
/>
|
||||
|
||||
<DatePicker
|
||||
date={date}
|
||||
maximumDate={dayjs(date).add(3, "months").toDate()}
|
||||
onDateChange={handleConfirm}
|
||||
textColor={isDark ? colors.static.white : colors.static.black}
|
||||
fadeToColor={colors.primary.background}
|
||||
theme={isDark ? "dark" : "light"}
|
||||
androidVariant="nativeAndroid"
|
||||
is24hourSource="locale"
|
||||
locale={
|
||||
db.settings?.getTimeFormat() === "24-hour" ? "en_GB" : "en_US"
|
||||
}
|
||||
mode={
|
||||
reminderMode === ReminderModes.Repeat &&
|
||||
recurringMode !== "year"
|
||||
? "time"
|
||||
: "datetime"
|
||||
}
|
||||
/>
|
||||
|
||||
{reminderMode === ReminderModes.Repeat ? null : (
|
||||
<Button
|
||||
style={{
|
||||
width: "100%"
|
||||
}}
|
||||
title={
|
||||
date ? date.toLocaleDateString() : strings.selectDate()
|
||||
}
|
||||
type={date ? "secondaryAccented" : "secondary"}
|
||||
icon="calendar"
|
||||
fontSize={AppFontSize.sm}
|
||||
onPress={() => {
|
||||
showDatePicker();
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</View>
|
||||
)}
|
||||
|
||||
{reminderMode === ReminderModes.Once ||
|
||||
reminderMode === ReminderModes.Permanent ? null : (
|
||||
<View
|
||||
style={{
|
||||
borderRadius: defaultBorderRadius,
|
||||
flexDirection: "row",
|
||||
paddingVertical: DefaultAppStyles.GAP_VERTICAL_SMALL,
|
||||
alignItems: "center",
|
||||
justifyContent: "flex-start",
|
||||
marginBottom: DefaultAppStyles.GAP_VERTICAL
|
||||
}}
|
||||
>
|
||||
<>
|
||||
<Paragraph
|
||||
size={AppFontSize.xxs}
|
||||
color={colors.secondary.paragraph}
|
||||
>
|
||||
{recurringMode === RecurringModes.Daily
|
||||
? strings.reminderRepeatStrings.day(
|
||||
dayjs(date).format("hh:mm A")
|
||||
)
|
||||
: recurringMode === RecurringModes.Year
|
||||
? strings.reminderRepeatStrings.year(
|
||||
dayjs(date).format("dddd, MMMM D, h:mm A")
|
||||
)
|
||||
: selectedDays.length === 7 &&
|
||||
recurringMode === RecurringModes.Week
|
||||
? strings.reminderRepeatStrings.week.daily(
|
||||
dayjs(date).format("hh:mm A")
|
||||
)
|
||||
: selectedDays.length === 0
|
||||
? strings.reminderRepeatStrings[
|
||||
recurringMode as "week" | "month"
|
||||
].selectDays()
|
||||
: strings.reminderRepeatStrings.repeats(
|
||||
repeatFrequency,
|
||||
recurringMode as string,
|
||||
getSelectedDaysText(selectedDays),
|
||||
dayjs(date).format("hh:mm A")
|
||||
)}
|
||||
</Paragraph>
|
||||
</>
|
||||
</View>
|
||||
)}
|
||||
|
||||
<ReminderTime
|
||||
reminder={reminder}
|
||||
style={{
|
||||
width: "100%",
|
||||
justifyContent: "flex-start",
|
||||
borderWidth: 0,
|
||||
paddingVertical: DefaultAppStyles.GAP_VERTICAL_SMALL,
|
||||
alignSelf: "flex-start"
|
||||
}}
|
||||
/>
|
||||
|
||||
{reminderMode === ReminderModes.Permanent ? null : (
|
||||
<ScrollView
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
marginTop: DefaultAppStyles.GAP_VERTICAL,
|
||||
height: 50
|
||||
}}
|
||||
horizontal
|
||||
>
|
||||
{Object.keys(ReminderNotificationModes).map((mode) => (
|
||||
<Button
|
||||
key={mode}
|
||||
title={strings.reminderNotificationModes(
|
||||
mode as keyof typeof ReminderNotificationModes
|
||||
)}
|
||||
style={{
|
||||
marginRight: 12,
|
||||
paddingVertical: DefaultAppStyles.GAP_VERTICAL_SMALL
|
||||
}}
|
||||
icon={
|
||||
mode === "Silent"
|
||||
? "minus-circle"
|
||||
: mode === "Vibrate"
|
||||
? "vibrate"
|
||||
: "volume-high"
|
||||
}
|
||||
fontSize={AppFontSize.xs}
|
||||
height={35}
|
||||
type={
|
||||
reminderNotificationMode ===
|
||||
ReminderNotificationModes[
|
||||
mode as keyof typeof ReminderNotificationModes
|
||||
]
|
||||
? "selected"
|
||||
: "plain"
|
||||
}
|
||||
onPress={() => {
|
||||
const _mode = ReminderNotificationModes[
|
||||
mode as keyof typeof ReminderNotificationModes
|
||||
] as Reminder["priority"];
|
||||
SettingsService.set({
|
||||
reminderNotificationMode: _mode
|
||||
});
|
||||
setReminderNotificatioMode(_mode);
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</ScrollView>
|
||||
)}
|
||||
</ScrollView>
|
||||
</KeyboardViewIOS>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
||||
AddReminder.present = (reminder?: Reminder, reference?: Note) => {
|
||||
Navigation.navigate("AddReminder", {
|
||||
reminder,
|
||||
reference
|
||||
});
|
||||
};
|
||||
@@ -38,11 +38,11 @@ import { WebViewMessageEvent } from "react-native-webview";
|
||||
import { DatabaseLogger, db } from "../../../common/database";
|
||||
import downloadAttachment from "../../../common/filesystem/download-attachment";
|
||||
import { AuthMode } from "../../../components/auth/common";
|
||||
import { Properties } from "../../../components/properties";
|
||||
import EditorTabs from "../../../components/sheets/editor-tabs";
|
||||
import { Issue } from "../../../components/sheets/github/issue";
|
||||
import LinkNote from "../../../components/sheets/link-note";
|
||||
import { RelationsList } from "../../../components/sheets/relations-list";
|
||||
import ReminderSheet from "../../../components/sheets/reminder";
|
||||
import TableOfContents from "../../../components/sheets/toc";
|
||||
import { DDS } from "../../../services/device-detection";
|
||||
import {
|
||||
@@ -73,13 +73,13 @@ import {
|
||||
} from "../../../utils/events";
|
||||
import { openLinkInBrowser } from "../../../utils/functions";
|
||||
import { fluidTabsRef } from "../../../utils/global-refs";
|
||||
import { sleep } from "../../../utils/time";
|
||||
import ManageTags from "../../manage-tags";
|
||||
import { useDragState } from "../../settings/editor/state";
|
||||
import { EditorMessage, EditorProps, useEditorType } from "./types";
|
||||
import { useTabStore } from "./use-tab-store";
|
||||
import { editorState, openInternalLink } from "./utils";
|
||||
import { Properties } from "../../../components/properties";
|
||||
import { sleep } from "../../../utils/time";
|
||||
import ManageTags from "../../manage-tags";
|
||||
import AddReminder from "../../add-reminder";
|
||||
|
||||
const publishNote = async () => {
|
||||
const user = useUserStore.getState().user;
|
||||
@@ -438,7 +438,7 @@ export const useEditorEvents = (
|
||||
referenceType: "reminder",
|
||||
relationType: "from",
|
||||
title: strings.dataTypesPluralCamelCase.reminder(),
|
||||
onAdd: () => ReminderSheet.present(undefined, note, true)
|
||||
onAdd: () => AddReminder.present(undefined, note)
|
||||
});
|
||||
break;
|
||||
case EditorEvents.newtag:
|
||||
|
||||
@@ -755,6 +755,8 @@ export const useEditor = (
|
||||
? (data as ContentItem).noteId
|
||||
: data.id;
|
||||
|
||||
if (!useTabStore.getState().hasTabForNote(noteId)) return;
|
||||
|
||||
const note = data.type === "note" ? data : await db.notes?.note(noteId);
|
||||
lock.current = true;
|
||||
// Handle this case where note was locked on another device and synced.
|
||||
|
||||
@@ -98,7 +98,7 @@ class TabSessionStorage {
|
||||
|
||||
static get(id: string): TabSessionItem | null {
|
||||
if (!id) return null;
|
||||
return TabSessionStorage.storage.getMap(id);
|
||||
return TabSessionStorage.storage.getMap(id) || null;
|
||||
}
|
||||
|
||||
static set(id: string, session: TabSessionItem): void {
|
||||
|
||||
@@ -96,14 +96,16 @@ export const EditorWrapper = ({ widths }: { widths: any }) => {
|
||||
minHeight: "100%",
|
||||
backgroundColor: toolBarColors.primary.background,
|
||||
borderLeftWidth: DDS.isTab ? 1 : 0,
|
||||
borderLeftColor: DDS.isTab ? colors.secondary.background : "transparent"
|
||||
borderLeftColor: DDS.isTab
|
||||
? colors.secondary.background
|
||||
: "transparent",
|
||||
paddingBottom: insets.bottom
|
||||
}}
|
||||
>
|
||||
{loading || !introCompleted ? null : (
|
||||
<KeyboardAvoidingViewIOS
|
||||
behavior="padding"
|
||||
style={{
|
||||
marginBottom: getMarginBottom(),
|
||||
backgroundColor: colors.primary.background,
|
||||
flex: 1
|
||||
}}
|
||||
|
||||
@@ -17,19 +17,19 @@ 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 React from "react";
|
||||
import { FloatingButton } from "../../components/container/floating-button";
|
||||
import DelayLayout from "../../components/delay-layout";
|
||||
import { Header } from "../../components/header";
|
||||
import List from "../../components/list";
|
||||
import SelectionHeader from "../../components/selection-header";
|
||||
import ReminderSheet from "../../components/sheets/reminder";
|
||||
import { useNavigationFocus } from "../../hooks/use-navigation-focus";
|
||||
import Navigation, { NavigationProps } from "../../services/navigation";
|
||||
import SettingsService from "../../services/settings";
|
||||
import useNavigationStore from "../../stores/use-navigation-store";
|
||||
import { useReminders } from "../../stores/use-reminder-store";
|
||||
import { strings } from "@notesnook/intl";
|
||||
import AddReminder from "../add-reminder";
|
||||
|
||||
export const Reminders = ({
|
||||
navigation,
|
||||
@@ -68,7 +68,7 @@ export const Reminders = ({
|
||||
}}
|
||||
id={route.name}
|
||||
onPressDefaultRightButton={() => {
|
||||
ReminderSheet.present();
|
||||
AddReminder.present();
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -84,7 +84,7 @@ export const Reminders = ({
|
||||
paragraph: strings.remindersEmpty(),
|
||||
button: strings.setReminder(),
|
||||
action: () => {
|
||||
ReminderSheet.present();
|
||||
AddReminder.present();
|
||||
},
|
||||
loading: strings.loadingReminders()
|
||||
}}
|
||||
@@ -92,7 +92,7 @@ export const Reminders = ({
|
||||
|
||||
<FloatingButton
|
||||
onPress={() => {
|
||||
ReminderSheet.present();
|
||||
AddReminder.present();
|
||||
}}
|
||||
alwaysVisible
|
||||
/>
|
||||
|
||||
@@ -16,35 +16,22 @@ GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import React, { RefObject, useRef, useState } from "react";
|
||||
import React, { useRef, useState } from "react";
|
||||
import { TextInput, View } from "react-native";
|
||||
import { ActionSheetRef } from "react-native-actions-sheet";
|
||||
import { db } from "../../../common/database";
|
||||
import {
|
||||
eSendEvent,
|
||||
presentSheet,
|
||||
PresentSheetOptions,
|
||||
ToastManager
|
||||
} from "../../../services/event-manager";
|
||||
import DialogHeader from "../../dialog/dialog-header";
|
||||
import { Button } from "../../ui/button";
|
||||
import Input from "../../ui/input";
|
||||
import { eSendEvent, ToastManager } from "../../../services/event-manager";
|
||||
import { eUserLoggedIn } from "../../../utils/events";
|
||||
import { strings } from "@notesnook/intl";
|
||||
import { DefaultAppStyles } from "../../../utils/styles";
|
||||
|
||||
type ChangeEmailProps = {
|
||||
actionSheetRef: RefObject<ActionSheetRef>;
|
||||
close?: () => void;
|
||||
update?: (options: PresentSheetOptions) => void;
|
||||
};
|
||||
import Input from "../../../components/ui/input";
|
||||
import { Button } from "../../../components/ui/button";
|
||||
|
||||
enum EmailChangeSteps {
|
||||
verify,
|
||||
changeEmail
|
||||
}
|
||||
|
||||
export const ChangeEmail = ({ close }: ChangeEmailProps) => {
|
||||
export const ChangeEmail = () => {
|
||||
const [step, setStep] = useState(EmailChangeSteps.verify);
|
||||
const emailChangeData = useRef<{
|
||||
email?: string;
|
||||
@@ -103,10 +90,6 @@ export const ChangeEmail = ({ close }: ChangeEmailProps) => {
|
||||
|
||||
return (
|
||||
<View style={{ paddingHorizontal: DefaultAppStyles.GAP }}>
|
||||
<DialogHeader
|
||||
title={strings.changeEmail()}
|
||||
paragraph={strings.changeEmailDesc()}
|
||||
/>
|
||||
<View
|
||||
style={{
|
||||
marginTop: DefaultAppStyles.GAP_VERTICAL
|
||||
@@ -156,23 +139,12 @@ export const ChangeEmail = ({ close }: ChangeEmailProps) => {
|
||||
: strings.changeEmail()
|
||||
}
|
||||
type="accent"
|
||||
width={250}
|
||||
style={{
|
||||
width: "100%"
|
||||
}}
|
||||
loading={loading}
|
||||
onPress={onSubmit}
|
||||
style={{
|
||||
borderRadius: 100,
|
||||
height: 45,
|
||||
marginTop: 2
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
ChangeEmail.present = () => {
|
||||
presentSheet({
|
||||
component: (ref, close, update) => (
|
||||
<ChangeEmail actionSheetRef={ref} close={close} update={update} />
|
||||
)
|
||||
});
|
||||
};
|
||||
@@ -43,6 +43,8 @@ import ThemeSelector from "./theme-selector";
|
||||
import { TitleFormat } from "./title-format";
|
||||
import { View } from "react-native";
|
||||
import { DefaultAppStyles } from "../../utils/styles";
|
||||
import { ChangePassword } from "../../components/auth/change-password";
|
||||
import { ChangeEmail } from "./change-email";
|
||||
|
||||
export const components: { [name: string]: ReactElement } = {
|
||||
colorpicker: <AccentColorPicker />,
|
||||
@@ -69,5 +71,7 @@ export const components: { [name: string]: ReactElement } = {
|
||||
<AttachmentGroupProgress groupId="offline-mode" />
|
||||
</View>
|
||||
),
|
||||
"sidebar-tab-selector": <SidebarTabPicker />
|
||||
"sidebar-tab-selector": <SidebarTabPicker />,
|
||||
"change-password": <ChangePassword />,
|
||||
"change-email": <ChangeEmail />
|
||||
};
|
||||
|
||||
@@ -32,11 +32,9 @@ import { enabled } from "react-native-privacy-snapshot";
|
||||
import ScreenGuardModule from "react-native-screenguard";
|
||||
import { db } from "../../common/database";
|
||||
import filesystem from "../../common/filesystem";
|
||||
import { ChangePassword } from "../../components/auth/change-password";
|
||||
import { presentDialog } from "../../components/dialog/functions";
|
||||
import { AppLockPassword } from "../../components/dialogs/applock-password";
|
||||
import { endProgress, startProgress } from "../../components/dialogs/progress";
|
||||
import { ChangeEmail } from "../../components/sheets/change-email";
|
||||
import ExportNotesSheet from "../../components/sheets/export-notes";
|
||||
import { Issue } from "../../components/sheets/github/issue";
|
||||
import { Progress } from "../../components/sheets/progress";
|
||||
@@ -243,17 +241,15 @@ export const settingsGroups: SettingSection[] = [
|
||||
{
|
||||
id: "change-password",
|
||||
name: strings.changePassword(),
|
||||
modifer: async () => {
|
||||
ChangePassword.present();
|
||||
},
|
||||
description: strings.changePasswordDesc()
|
||||
type: "screen",
|
||||
description: strings.changePasswordDesc(),
|
||||
component: "change-password"
|
||||
},
|
||||
{
|
||||
id: "change-email",
|
||||
name: strings.changeEmail(),
|
||||
modifer: async () => {
|
||||
ChangeEmail.present();
|
||||
},
|
||||
type: "screen",
|
||||
component: "change-email",
|
||||
description: strings.changeEmailDesc()
|
||||
},
|
||||
{
|
||||
|
||||
@@ -113,7 +113,10 @@ async function onBackgroundSyncStarted() {
|
||||
useUserStore.getState().setSyncing(false);
|
||||
}
|
||||
await Notifications.setupReminders();
|
||||
|
||||
if (SettingsService.get().notifNotes) {
|
||||
Notifications.pinQuickNote(false);
|
||||
}
|
||||
Notifications.restorePinnedNotes();
|
||||
NotePreviewWidget.updateNotes();
|
||||
deleteDCacheFiles();
|
||||
DatabaseLogger.info("BACKGROUND SYNC COMPLETE");
|
||||
@@ -142,6 +145,7 @@ const onBoot = async () => {
|
||||
Notifications.pinQuickNote(false);
|
||||
}
|
||||
Notifications.restorePinnedNotes();
|
||||
NotePreviewWidget.updateNotes();
|
||||
DatabaseLogger.info("BOOT TASK COMPLETE");
|
||||
} catch (e) {
|
||||
DatabaseLogger.error(e as Error);
|
||||
|
||||
@@ -18,12 +18,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { Platform } from "react-native";
|
||||
import { db } from "../common/database";
|
||||
import ReminderSheet from "../components/sheets/reminder";
|
||||
import { setAppState } from "../screens/editor/tiptap/utils";
|
||||
import { eOnLoadNote } from "../utils/events";
|
||||
import { NotesnookModule } from "../utils/notesnook-module";
|
||||
import { eSendEvent } from "./event-manager";
|
||||
import { fluidTabsRef } from "../utils/global-refs";
|
||||
import AddReminder from "../screens/add-reminder";
|
||||
|
||||
const launchIntent = Platform.OS === "ios" ? {} : NotesnookModule.getIntent();
|
||||
let used = false;
|
||||
@@ -65,9 +65,9 @@ export const IntentService = {
|
||||
const reminder = await db.reminders.reminder(
|
||||
intent["com.streetwriters.notesnook.OpenReminderId"]
|
||||
);
|
||||
if (reminder) ReminderSheet.present(reminder);
|
||||
if (reminder) AddReminder.present(reminder);
|
||||
} else if (intent["com.streetwriters.notesnook.NewReminder"]) {
|
||||
ReminderSheet.present();
|
||||
AddReminder.present();
|
||||
}
|
||||
} catch (e) {
|
||||
/* empty */
|
||||
|
||||
@@ -69,7 +69,8 @@ const routeNames = {
|
||||
LinkNotebooks: "LinkNotebooks",
|
||||
MoveNotes: "MoveNotes",
|
||||
Archive: "Archive",
|
||||
ManageTags: "ManageTags"
|
||||
ManageTags: "ManageTags",
|
||||
AddReminder: "AddReminder"
|
||||
};
|
||||
|
||||
export type NavigationProps<T extends RouteName> = NativeStackScreenProps<
|
||||
|
||||
@@ -348,7 +348,7 @@ async function scheduleNotification(
|
||||
title: title,
|
||||
message: description || "",
|
||||
ongoing: true,
|
||||
subtitle: description || "",
|
||||
// subtitle: description || "",
|
||||
actions: [strings.unpin()]
|
||||
});
|
||||
}
|
||||
@@ -396,7 +396,7 @@ async function scheduleNotification(
|
||||
payload: payload || "",
|
||||
dateModified: reminder.dateModified + ""
|
||||
},
|
||||
subtitle: !description ? undefined : description,
|
||||
// subtitle: !description ? undefined : description,
|
||||
android: {
|
||||
channelId: await getChannelId(priority),
|
||||
smallIcon: "ic_stat_name",
|
||||
|
||||
@@ -45,10 +45,10 @@ export function initAfterSync(type: "full" | "send" = "send") {
|
||||
useUserStore.setState({
|
||||
profile: db.settings.getProfile()
|
||||
});
|
||||
eSendEvent(eAfterSync);
|
||||
}
|
||||
Notifications.setupReminders(true);
|
||||
NotePreviewWidget.updateNotes();
|
||||
eSendEvent(eAfterSync);
|
||||
}
|
||||
|
||||
export async function initialize() {}
|
||||
|
||||
@@ -94,6 +94,10 @@ export interface RouteParams extends ParamListBase {
|
||||
ManageTags: {
|
||||
ids?: string[];
|
||||
};
|
||||
AddReminder: {
|
||||
reminder?: Reminder;
|
||||
reference?: Note;
|
||||
};
|
||||
}
|
||||
|
||||
export type RouteName = keyof RouteParams;
|
||||
|
||||
@@ -43,7 +43,7 @@ export function changeSystemBarColors() {
|
||||
const isDark = useThemeStore.getState().colorScheme === "dark";
|
||||
changeNavigationBarColor(
|
||||
currTheme.scopes.base.primary.background,
|
||||
isDark,
|
||||
!isDark,
|
||||
false
|
||||
);
|
||||
StatusBar.setBackgroundColor("transparent" as any);
|
||||
|
||||
@@ -40,6 +40,7 @@ interface NotesnookModuleInterface {
|
||||
hasWidgetNote: (noteId: string) => Promise<boolean>;
|
||||
updateWidgetNote: (noteId: string, data: string) => void;
|
||||
updateReminderWidget: () => void;
|
||||
isGestureNavigationEnabled: () => boolean;
|
||||
}
|
||||
|
||||
export const NotesnookModule: NotesnookModuleInterface = Platform.select({
|
||||
@@ -59,7 +60,8 @@ export const NotesnookModule: NotesnookModuleInterface = Platform.select({
|
||||
getWidgetNotes: () => {},
|
||||
hasWidgetNote: () => {},
|
||||
updateWidgetNote: () => {},
|
||||
updateReminderWidget: () => {}
|
||||
updateReminderWidget: () => {},
|
||||
isGestureNavigationEnabled: () => true
|
||||
},
|
||||
android: NativeModules.NNativeModule
|
||||
});
|
||||
|
||||
@@ -124,7 +124,7 @@ android {
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
multiDexEnabled true
|
||||
versionCode 3058
|
||||
versionCode 3063
|
||||
versionName getNpmVersion()
|
||||
testBuildType System.getProperty('testBuildType', 'debug')
|
||||
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
|
||||
|
||||
@@ -11,57 +11,69 @@
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
<uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:node="remove"/>
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" tools:node="remove"/>
|
||||
<uses-permission android:name="android.permission.CAMERA"/>
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
|
||||
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" tools:node="remove" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
|
||||
<uses-permission
|
||||
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
||||
tools:node="remove" />
|
||||
<uses-permission
|
||||
android:name="android.permission.READ_EXTERNAL_STORAGE"
|
||||
tools:node="remove" />
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" />
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
<uses-permission
|
||||
android:name="android.permission.USE_FULL_SCREEN_INTENT"
|
||||
tools:node="remove" />
|
||||
|
||||
<uses-feature
|
||||
android:name="android.hardware.camera"
|
||||
android:required="false" />
|
||||
|
||||
<queries>
|
||||
<intent>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<!-- If you don't know the MIME type in advance, set "mimeType" to "*/*". -->
|
||||
<data android:mimeType="application/pdf" />
|
||||
</intent>
|
||||
<intent>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<!-- If you don't know the MIME type in advance, set "mimeType" to "*/*". -->
|
||||
<data android:mimeType="text/*" />
|
||||
</intent>
|
||||
<intent>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<!-- If you don't know the MIME type in advance, set "mimeType" to "*/*". -->
|
||||
<data android:mimeType="image/*" />
|
||||
</intent>
|
||||
<intent>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<!-- If you don't know the MIME type in advance, set "mimeType" to "*/*". -->
|
||||
<intent>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<!-- If you don't know the MIME type in advance, set "mimeType" to "*/*". -->
|
||||
<data android:mimeType="application/pdf" />
|
||||
</intent>
|
||||
<intent>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<!-- If you don't know the MIME type in advance, set "mimeType" to "*/*". -->
|
||||
<data android:mimeType="text/*" />
|
||||
</intent>
|
||||
<intent>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<!-- If you don't know the MIME type in advance, set "mimeType" to "*/*". -->
|
||||
<data android:mimeType="image/*" />
|
||||
</intent>
|
||||
<intent>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<!-- If you don't know the MIME type in advance, set "mimeType" to "*/*". -->
|
||||
|
||||
<data android:mimeType="video/*" />
|
||||
</intent>
|
||||
<intent>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<!-- If you don't know the MIME type in advance, set "mimeType" to "*/*". -->
|
||||
<data android:mimeType="audio/*" />
|
||||
</intent>
|
||||
</queries>
|
||||
<data android:mimeType="video/*" />
|
||||
</intent>
|
||||
<intent>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<!-- If you don't know the MIME type in advance, set "mimeType" to "*/*". -->
|
||||
<data android:mimeType="audio/*" />
|
||||
</intent>
|
||||
</queries>
|
||||
|
||||
<application
|
||||
android:name=".MainApplication"
|
||||
android:allowBackup="false"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:requestLegacyExternalStorage="true"
|
||||
android:theme="@style/BootTheme"
|
||||
android:largeHeap="true"
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
android:requestLegacyExternalStorage="true"
|
||||
android:supportsRtl="true"
|
||||
android:networkSecurityConfig="@xml/network_security_config">
|
||||
|
||||
<receiver android:exported="false" android:label="@string/quick_note" android:name=".NoteWidget">
|
||||
android:theme="@style/BootTheme">
|
||||
|
||||
<receiver
|
||||
android:name=".NoteWidget"
|
||||
android:exported="false"
|
||||
android:label="@string/quick_note">
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||
</intent-filter>
|
||||
@@ -71,7 +83,10 @@
|
||||
android:resource="@xml/new_note_widget_info" />
|
||||
</receiver>
|
||||
|
||||
<receiver android:exported="false" android:label="@string/note" android:name=".NotePreviewWidget">
|
||||
<receiver
|
||||
android:name=".NotePreviewWidget"
|
||||
android:exported="false"
|
||||
android:label="@string/note">
|
||||
<intent-filter>"
|
||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||
</intent-filter>
|
||||
@@ -81,7 +96,10 @@
|
||||
android:resource="@xml/note_widget_info" />
|
||||
</receiver>
|
||||
|
||||
<receiver android:exported="false" android:label="@string/reminders_title" android:name=".ReminderWidgetProvider">
|
||||
<receiver
|
||||
android:name=".ReminderWidgetProvider"
|
||||
android:exported="false"
|
||||
android:label="@string/reminders_title">
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||
</intent-filter>
|
||||
@@ -90,33 +108,37 @@
|
||||
android:resource="@xml/widget_reminders_info" />
|
||||
</receiver>
|
||||
|
||||
<activity android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
|
||||
<activity
|
||||
android:name=".NotePreviewConfigureActivity"
|
||||
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
|
||||
android:exported="true"
|
||||
android:label="NotePreviewConfigure"
|
||||
android:launchMode="singleTask"
|
||||
android:exported="true"
|
||||
android:theme="@style/AppTheme"
|
||||
android:windowSoftInputMode="adjustResize" android:name=".NotePreviewConfigureActivity">
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
|
||||
android:exported="true"
|
||||
android:label="@string/app_name"
|
||||
android:launchMode="singleTask"
|
||||
android:resizeableActivity="true"
|
||||
android:exported="true"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<action android:name="android.intent.action.DOWNLOAD_COMPLETE"/>
|
||||
<action android:name="android.intent.action.DOWNLOAD_COMPLETE" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter android:label="Notesnook">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
@@ -127,6 +149,7 @@
|
||||
|
||||
<intent-filter android:label="Notesnook">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
@@ -134,22 +157,25 @@
|
||||
</intent-filter>
|
||||
|
||||
</activity>
|
||||
<activity android:exported="false" android:name="com.facebook.react.devsupport.DevSettingsActivity" />
|
||||
<activity
|
||||
android:name="com.facebook.react.devsupport.DevSettingsActivity"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:name=".ShareActivity"
|
||||
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
|
||||
android:excludeFromRecents="true"
|
||||
android:exported="true"
|
||||
android:label="@string/title_activity_share"
|
||||
android:noHistory="true"
|
||||
android:screenOrientation="unspecified"
|
||||
android:exported="true"
|
||||
android:taskAffinity=""
|
||||
android:excludeFromRecents="true"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:theme="@style/AppThemeB">
|
||||
android:theme="@style/AppThemeB"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
|
||||
<intent-filter android:label="Make Note">
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
|
||||
<data android:mimeType="text/*" />
|
||||
<data android:mimeType="image/*" />
|
||||
<data android:mimeType="video/*" />
|
||||
@@ -160,6 +186,7 @@
|
||||
<intent-filter android:label="Make Note">
|
||||
<action android:name="android.intent.action.SEND_MULTIPLE" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
|
||||
<data android:mimeType="text/*" />
|
||||
<data android:mimeType="image/*" />
|
||||
<data android:mimeType="video/*" />
|
||||
@@ -179,35 +206,41 @@
|
||||
android:enabled="true"
|
||||
android:exported="true"
|
||||
android:stopWithTask="false" />
|
||||
<service android:name="com.asterinet.react.bgactions.RNBackgroundActionsTask" />
|
||||
<service android:name="com.asterinet.react.bgactions.RNBackgroundActionsTask" />
|
||||
|
||||
<service android:name="com.streetwriters.notesnook.BootTaskService" android:foregroundServiceType="dataSync" />
|
||||
<service
|
||||
android:name="com.streetwriters.notesnook.BootTaskService"
|
||||
android:foregroundServiceType="specialUse">
|
||||
<property
|
||||
android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE"
|
||||
android:value="The service is required by the app to restore notifications of pinned notes, restore notification with reply input for creating notes and restore data in note preview widgets on device reboot." />
|
||||
</service>
|
||||
|
||||
<service
|
||||
android:name=".NotesnookTileService"
|
||||
android:exported="true"
|
||||
android:icon="@drawable/add_note"
|
||||
android:label="New note"
|
||||
android:exported="true"
|
||||
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
|
||||
<intent-filter>
|
||||
<action android:name="android.service.quicksettings.action.QS_TILE"/>
|
||||
<action android:name="android.service.quicksettings.action.QS_TILE" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
|
||||
<service
|
||||
android:name=".ReminderViewsService"
|
||||
android:exported="true"
|
||||
android:permission="android.permission.BIND_REMOTEVIEWS" />
|
||||
<service
|
||||
android:name=".ReminderViewsService"
|
||||
android:exported="true"
|
||||
android:permission="android.permission.BIND_REMOTEVIEWS" />
|
||||
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="${applicationId}.provider"
|
||||
android:grantUriPermissions="true"
|
||||
android:exported="false">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/file_viewer_provider_paths" />
|
||||
</provider>
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="${applicationId}.provider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/file_viewer_provider_paths" />
|
||||
</provider>
|
||||
|
||||
<provider
|
||||
android:name="com.vinzscam.reactnativefileviewer.FileProvider"
|
||||
@@ -219,12 +252,14 @@
|
||||
android:resource="@xml/file_viewer_provider_paths" />
|
||||
</provider>
|
||||
|
||||
<receiver android:exported="true" android:name=".BootRecieverService">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver
|
||||
android:name=".BootRecieverService"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
</application>
|
||||
|
||||
|
||||
@@ -39,7 +39,6 @@ public class BootTaskService extends HeadlessJsTaskService {
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
|
||||
NotificationChannel channel = new NotificationChannel("com.streetwriters.notesnook",
|
||||
"Default",
|
||||
@@ -55,7 +54,7 @@ public class BootTaskService extends HeadlessJsTaskService {
|
||||
this.startForeground(
|
||||
1,
|
||||
notification,
|
||||
ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC);
|
||||
ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE);
|
||||
} else {
|
||||
this.startForeground(
|
||||
1,
|
||||
|
||||
@@ -3,8 +3,16 @@ package com.streetwriters.notesnook;
|
||||
import com.facebook.react.ReactActivity;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import androidx.core.graphics.Insets;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.webkit.WebView;
|
||||
|
||||
import androidx.core.view.OnApplyWindowInsetsListener;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.core.view.WindowInsetsCompat;
|
||||
|
||||
import com.facebook.react.ReactActivityDelegate;
|
||||
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
|
||||
import com.facebook.react.defaults.DefaultReactActivityDelegate;
|
||||
@@ -22,6 +30,20 @@ public class MainActivity extends ReactActivity {
|
||||
try {
|
||||
startService(new Intent(getBaseContext(), OnClearFromRecentService.class));
|
||||
} catch (Exception ignored) {}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 35) {
|
||||
final View rootView = findViewById(android.R.id.content);
|
||||
ViewCompat.setOnApplyWindowInsetsListener(rootView, (v, insets) -> {
|
||||
Insets innerPadding = insets.getInsets(WindowInsetsCompat.Type.ime());
|
||||
rootView.setPadding(
|
||||
innerPadding.left,
|
||||
innerPadding.top,
|
||||
innerPadding.right,
|
||||
innerPadding.bottom
|
||||
);
|
||||
return insets;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,7 +7,9 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.Color;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.RemoteViews;
|
||||
@@ -217,4 +219,24 @@ public class RCTNNativeModule extends ReactContextBaseJavaModule {
|
||||
wm.notifyAppWidgetViewDataChanged(id, R.id.widget_list_view);
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public boolean isGestureNavigationEnabled() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
try {
|
||||
String navBarMode = Settings.Secure.getString(
|
||||
mContext.getContentResolver(),
|
||||
"navigation_mode"
|
||||
);
|
||||
return "2".equals(navBarMode);
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
- New and improved search with highlighting
|
||||
- Fixed app crashing on android 16 devices
|
||||
- Many bug fixes and improvements
|
||||
- Fix crash on device boot on android 15 devices
|
||||
- Fix note not opening in editor randomly
|
||||
- Minor bug fixes and improvements
|
||||
|
||||
Thank you for using Notesnook!
|
||||
@@ -124,7 +124,6 @@
|
||||
6529D2B0257B4A2900B49BC3 /* NotesnookDebug.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = NotesnookDebug.entitlements; path = Notesnook/NotesnookDebug.entitlements; sourceTree = "<group>"; };
|
||||
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>"; };
|
||||
6594DDF22CD8BFE8007F5EC2 /* BetterTrigram.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = BetterTrigram.xcframework; 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>"; };
|
||||
65AA857725E6DDEC00772A01 /* NotesWidgetExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = NotesWidgetExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
@@ -256,7 +255,6 @@
|
||||
2D16E6871FA4F8E400B85C8A /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
6594DDF22CD8BFE8007F5EC2 /* BetterTrigram.xcframework */,
|
||||
6515C42E2580AA2F00E83E39 /* StoreKit.framework */,
|
||||
ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
|
||||
ED2971642150620600B7C4FE /* JavaScriptCore.framework */,
|
||||
@@ -1091,7 +1089,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 2136;
|
||||
CURRENT_PROJECT_VERSION = 2142;
|
||||
DEVELOPMENT_TEAM = 53CWBG3QUC;
|
||||
ENABLE_BITCODE = NO;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
@@ -1165,7 +1163,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.2.2;
|
||||
MARKETING_VERSION = 3.2.7;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
@@ -1196,7 +1194,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 2136;
|
||||
CURRENT_PROJECT_VERSION = 2142;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 53CWBG3QUC;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
@@ -1270,7 +1268,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.2.2;
|
||||
MARKETING_VERSION = 3.2.7;
|
||||
ONLY_ACTIVE_ARCH = NO;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
@@ -1429,7 +1427,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 2136;
|
||||
CURRENT_PROJECT_VERSION = 2142;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = 53CWBG3QUC;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
@@ -1441,7 +1439,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.2.2;
|
||||
MARKETING_VERSION = 3.2.7;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.notewidget;
|
||||
@@ -1472,7 +1470,7 @@
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 2136;
|
||||
CURRENT_PROJECT_VERSION = 2142;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = "";
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 53CWBG3QUC;
|
||||
@@ -1485,7 +1483,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.2.2;
|
||||
MARKETING_VERSION = 3.2.7;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.notewidget;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
@@ -1515,10 +1513,16 @@
|
||||
CODE_SIGN_ENTITLEMENTS = "Make Note/Make Note.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 2136;
|
||||
CURRENT_PROJECT_VERSION = 2142;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = 53CWBG3QUC;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"\"${PODS_ROOT}/hermes-engine/destroot/Library/Frameworks/universal\"",
|
||||
"\"${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/Pre-built\"",
|
||||
"\"${PROJECT_DIR}\"",
|
||||
);
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
@@ -1589,7 +1593,8 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.2.2;
|
||||
LIBRARY_SEARCH_PATHS = "$(SDKROOT)/usr/lib/swift$(inherited)";
|
||||
MARKETING_VERSION = 3.2.7;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.share;
|
||||
@@ -1620,11 +1625,17 @@
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 2136;
|
||||
CURRENT_PROJECT_VERSION = 2142;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = "";
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 53CWBG3QUC;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"\"${PODS_ROOT}/hermes-engine/destroot/Library/Frameworks/universal\"",
|
||||
"\"${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/Pre-built\"",
|
||||
"\"${PROJECT_DIR}\"",
|
||||
);
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
@@ -1695,7 +1706,8 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.2.2;
|
||||
LIBRARY_SEARCH_PATHS = "$(SDKROOT)/usr/lib/swift$(inherited)";
|
||||
MARKETING_VERSION = 3.2.7;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.share;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
|
||||
@@ -1325,6 +1325,28 @@ PODS:
|
||||
- react-native-pdf (6.7.7):
|
||||
- React-Core
|
||||
- react-native-quick-sqlite (8.2.7):
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- hermes-engine
|
||||
- RCT-Folly (= 2024.11.18.00)
|
||||
- RCTRequired
|
||||
- RCTTypeSafety
|
||||
- React-Core
|
||||
- React-debug
|
||||
- React-Fabric
|
||||
- React-featureflags
|
||||
- React-graphics
|
||||
- React-ImageManager
|
||||
- react-native-quick-sqlite/lexbor (= 8.2.7)
|
||||
- React-NativeModulesApple
|
||||
- React-RCTFabric
|
||||
- React-rendererdebug
|
||||
- React-utils
|
||||
- ReactCodegen
|
||||
- ReactCommon/turbomodule/bridging
|
||||
- ReactCommon/turbomodule/core
|
||||
- Yoga
|
||||
- react-native-quick-sqlite/lexbor (8.2.7):
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- hermes-engine
|
||||
@@ -1352,7 +1374,7 @@ PODS:
|
||||
- SDWebImage (~> 5.11.1)
|
||||
- react-native-share-extension (2.9.0):
|
||||
- React
|
||||
- react-native-sodium (1.6.3):
|
||||
- react-native-sodium (1.6.4):
|
||||
- React
|
||||
- react-native-theme-switch-animation (0.6.0):
|
||||
- DoubleConversion
|
||||
@@ -2409,11 +2431,11 @@ SPEC CHECKSUMS:
|
||||
react-native-orientation-locker: cc6f357b289a2e0dd2210fea0c52cb8e0727fdaa
|
||||
react-native-pager-view: 5aaf51a9338f7997b8acee0e0febfddd1ade5c0a
|
||||
react-native-pdf: 6a51a22ccefb23eb93298771e4bf090913e86d70
|
||||
react-native-quick-sqlite: 6aebe0e1c264c48450059e271e5d2404013cea93
|
||||
react-native-quick-sqlite: 1bfc7f1e9acbe9a5aa5c4cc81712e9bde3ab7672
|
||||
react-native-safe-area-context: 9d72abf6d8473da73033b597090a80b709c0b2f1
|
||||
react-native-screenguard: 82437eeb0086a90b5e5d7e54130bb04fb406373e
|
||||
react-native-share-extension: bcb7e466390a9e50c742f4b1019d6f181aedd7ad
|
||||
react-native-sodium: aa26d9f46dcfdebd92d3af793b74fbb234a4d75d
|
||||
react-native-sodium: 5b55f74705005612e12838ffd583927229a65e6a
|
||||
react-native-theme-switch-animation: d90fe2de0d9e87a63cd6235d98cba6e7054e9a10
|
||||
react-native-webview: 079eca50edf657503318b66687dadfb903731aa8
|
||||
React-nativeconfig: ecf4dc92c40b97e2b3f0c619938f78bfd6507b08
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@notesnook/mobile",
|
||||
"version": "3.2.2",
|
||||
"version": "3.2.7",
|
||||
"private": true,
|
||||
"license": "GPL-3.0-or-later",
|
||||
"workspaces": [
|
||||
|
||||
12
apps/mobile/patches/react-native-actions-sheet+0.9.7.patch
Normal file
12
apps/mobile/patches/react-native-actions-sheet+0.9.7.patch
Normal file
@@ -0,0 +1,12 @@
|
||||
diff --git a/node_modules/react-native-actions-sheet/dist/src/index.js b/node_modules/react-native-actions-sheet/dist/src/index.js
|
||||
index 0e124da..3703153 100644
|
||||
--- a/node_modules/react-native-actions-sheet/dist/src/index.js
|
||||
+++ b/node_modules/react-native-actions-sheet/dist/src/index.js
|
||||
@@ -1088,6 +1088,7 @@ export default forwardRef(function ActionSheet(_a, ref) {
|
||||
* Always true, it causes issue with keyboard handling.
|
||||
*/
|
||||
statusBarTranslucent: true,
|
||||
+ navigationBarTranslucent: true
|
||||
}
|
||||
: {
|
||||
testID: ((_b = props.testIDs) === null || _b === void 0 ? void 0 : _b.root) || props.testID,
|
||||
@@ -36,3 +36,37 @@ index 3dfe1dc..70ef9da 100644
|
||||
+ implementation 'io.legere:pdfiumandroid:1.0.32'
|
||||
implementation 'com.google.code.gson:gson:2.8.5'
|
||||
}
|
||||
diff --git a/node_modules/react-native-pdf/android/src/main/java/org/wonday/pdf/PdfView.java b/node_modules/react-native-pdf/android/src/main/java/org/wonday/pdf/PdfView.java
|
||||
index 7b7a125..361924b 100644
|
||||
--- a/node_modules/react-native-pdf/android/src/main/java/org/wonday/pdf/PdfView.java
|
||||
+++ b/node_modules/react-native-pdf/android/src/main/java/org/wonday/pdf/PdfView.java
|
||||
@@ -12,6 +12,8 @@ import java.io.File;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
+import android.os.Handler;
|
||||
+import android.os.Looper;
|
||||
import android.util.SizeF;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@@ -105,7 +107,7 @@ public class PdfView extends PDFView implements OnPageChangeListener,OnLoadCompl
|
||||
TopChangeEvent tce = new TopChangeEvent(surfaceId, getId(), event);
|
||||
|
||||
if (dispatcher != null) {
|
||||
- dispatcher.dispatchEvent(tce);
|
||||
+ new Handler(Looper.getMainLooper()).postDelayed(() -> dispatcher.dispatchEvent(tce), 10);
|
||||
}
|
||||
|
||||
// ReactContext reactContext = (ReactContext)this.getContext();
|
||||
diff --git a/node_modules/react-native-pdf/index.js b/node_modules/react-native-pdf/index.js
|
||||
index 56df005..dd14412 100644
|
||||
--- a/node_modules/react-native-pdf/index.js
|
||||
+++ b/node_modules/react-native-pdf/index.js
|
||||
@@ -364,7 +364,6 @@ export default class Pdf extends Component {
|
||||
}
|
||||
|
||||
_onChange = (event) => {
|
||||
-
|
||||
let message = event.nativeEvent.message.split('|');
|
||||
//__DEV__ && console.log("onChange: " + message);
|
||||
if (message.length > 0) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -107,10 +107,12 @@ function generateTableOfContents() {
|
||||
|
||||
export const MonographPage = ({
|
||||
monograph,
|
||||
encodedKey
|
||||
encodedKey,
|
||||
apiHost
|
||||
}: {
|
||||
monograph: Monograph;
|
||||
encodedKey?: string;
|
||||
apiHost: string;
|
||||
}) => {
|
||||
const [reportDialogVisible, setReportDialogVisible] = useState(false);
|
||||
const [tableOfContents, setTableOfContents] = useState<TableOfContent[]>([]);
|
||||
@@ -227,7 +229,7 @@ export const MonographPage = ({
|
||||
)}
|
||||
<Image
|
||||
sx={{ display: "none" }}
|
||||
src={`https://api.notesnook.com/monographs/${monograph.id}/view`}
|
||||
src={`${apiHost}/monographs/${monograph.id}/view`}
|
||||
/>
|
||||
</Flex>
|
||||
</Box>
|
||||
|
||||
@@ -85,7 +85,8 @@ export async function loader({ params }: LoaderFunctionArgs) {
|
||||
const metadata = getMonographMetadata(monograph);
|
||||
return {
|
||||
monograph,
|
||||
metadata
|
||||
metadata,
|
||||
apiHost: API_HOST
|
||||
};
|
||||
} catch (e) {
|
||||
// console.error(e);
|
||||
@@ -96,19 +97,24 @@ export async function loader({ params }: LoaderFunctionArgs) {
|
||||
fullDescription: "This monograph does not exist.",
|
||||
shortDescription: "This monograph does not exist.",
|
||||
datePublished: ""
|
||||
}
|
||||
},
|
||||
apiHost: API_HOST
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export default function MonographPost() {
|
||||
const { monograph } = useLoaderData<typeof loader>();
|
||||
const { monograph, apiHost } = useLoaderData<typeof loader>();
|
||||
const [_, hashParams] = useHashLocation();
|
||||
|
||||
return (
|
||||
<>
|
||||
{monograph ? (
|
||||
<MonographPage monograph={monograph} encodedKey={hashParams.key} />
|
||||
<MonographPage
|
||||
monograph={monograph}
|
||||
encodedKey={hashParams.key}
|
||||
apiHost={apiHost}
|
||||
/>
|
||||
) : (
|
||||
<>
|
||||
<Header />
|
||||
|
||||
40
apps/web/__e2e__/monographs.test.ts
Normal file
40
apps/web/__e2e__/monographs.test.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
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 { test, expect } from "@playwright/test";
|
||||
import { AppModel } from "./models/app.model";
|
||||
import { USER } from "./utils";
|
||||
|
||||
test("don't show monographs list to unauthenticated user", async ({ page }) => {
|
||||
const app = new AppModel(page);
|
||||
await app.goto();
|
||||
|
||||
await expect(
|
||||
async () => await app.navigateTo("Monographs")
|
||||
).rejects.toThrowError();
|
||||
});
|
||||
|
||||
test("show monographs list to authenticated user", async ({ page }) => {
|
||||
const app = new AppModel(page);
|
||||
await app.auth.goto();
|
||||
|
||||
await app.auth.login(USER.CURRENT);
|
||||
|
||||
await app.navigateTo("Monographs");
|
||||
});
|
||||
@@ -28,7 +28,6 @@ function createRoute(key: string, header: string) {
|
||||
const routes = [
|
||||
createRoute("notes", "Notes"),
|
||||
createRoute("favorites", "Favorites"),
|
||||
createRoute("monographs", "Monographs"),
|
||||
createRoute("reminders", "Reminders"),
|
||||
createRoute("trash", "Trash")
|
||||
];
|
||||
|
||||
10
apps/web/package-lock.json
generated
10
apps/web/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@notesnook/web",
|
||||
"version": "3.2.2",
|
||||
"version": "3.2.3",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@notesnook/web",
|
||||
"version": "3.2.2",
|
||||
"version": "3.2.3",
|
||||
"hasInstallScript": true,
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
@@ -278,7 +278,7 @@
|
||||
"refractor": "^4.8.1",
|
||||
"sqlite-better-trigram": "^0.0.3",
|
||||
"sqlite-regex": "^0.2.4-alpha.1",
|
||||
"sqlite3-fts5-html": "^0.0.3",
|
||||
"sqlite3-fts5-html": "^0.0.4",
|
||||
"vitest": "2.1.8",
|
||||
"vitest-fetch-mock": "^0.2.2",
|
||||
"ws": "^8.13.0"
|
||||
@@ -502,7 +502,7 @@
|
||||
},
|
||||
"../desktop": {
|
||||
"name": "@notesnook/desktop",
|
||||
"version": "3.2.1-beta.0",
|
||||
"version": "3.2.2",
|
||||
"hasInstallScript": true,
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
@@ -516,7 +516,7 @@
|
||||
"electron-updater": "^6.6.2",
|
||||
"icojs": "^0.19.5",
|
||||
"sqlite-better-trigram": "0.0.3",
|
||||
"sqlite3-fts5-html": "^0.0.3",
|
||||
"sqlite3-fts5-html": "^0.0.4",
|
||||
"typed-emitter": "^2.1.0",
|
||||
"yargs": "^17.7.2",
|
||||
"zod": "3.24.3"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@notesnook/web",
|
||||
"description": "Your private note taking space",
|
||||
"version": "3.2.2",
|
||||
"version": "3.2.3",
|
||||
"private": true,
|
||||
"main": "./src/app.js",
|
||||
"homepage": "https://notesnook.com/",
|
||||
|
||||
@@ -53,7 +53,8 @@ import { MenuItem } from "@notesnook/ui";
|
||||
export const CREATE_BUTTON_MAP = {
|
||||
notes: {
|
||||
title: strings.addItem("note"),
|
||||
onClick: () => useEditorStore.getState().newSession()
|
||||
onClick: () => useEditorStore.getState().newSession(),
|
||||
onAuxClick: () => useEditorStore.getState().addTab()
|
||||
},
|
||||
notebooks: {
|
||||
title: strings.addItem("notebook"),
|
||||
|
||||
@@ -88,7 +88,7 @@ typeof U||!(H instanceof O))throw H;return H.Pf}},i:function(b,c,d,e,f){try{c=d+
|
||||
c.node.Vf;e.type.Tg?e.type.Tg(e,!1,function(f){f?d(function(){return 29}):d(0)}):d(0)})}catch(d){if("undefined"==typeof U||!(d instanceof O))throw d;return d.Pf}},s:function(b,c,d,e){try{a:{var f=V(b);b=c;for(var g,h=c=0;h<d;h++){var n=E[b>>2],k=E[b+4>>2];b+=8;var l=f,p=n,q=k,r=g,w=A;if(0>q||0>r)throw new O(28);if(null===l.Xf)throw new O(8);if(0===(l.flags&2097155))throw new O(8);if(16384===(l.node.mode&61440))throw new O(31);if(!l.Nf.write)throw new O(28);l.seekable&&l.flags&1024&&Db(l,0,2);var z=
|
||||
"undefined"!=typeof r;if(!z)r=l.position;else if(!l.seekable)throw new O(70);var G=l.Nf.write(l,w,p,q,r,void 0);z||(l.position+=G);var D=G;if(0>D){var J=-1;break a}c+=D;"undefined"!==typeof g&&(g+=D)}J=c}E[e>>2]=J;return 0}catch(H){if("undefined"==typeof U||!(H instanceof O))throw H;return H.Pf}},sa:Vb,_:Wb,x:Xb,P:Yb,ca:Zb,I:$b,ka:ac,m:bc,ra:cc,na:dc,ia:ec,ea:fc,fa:gc,g:hc,h:ic,oa:jc,qa:kc,pa:lc,da:mc,ga:nc,ha:oc,ma:pc,c:qc,ja:rc,la:sc,aa:tc,V:uc,$:vc,ba:wc,S:xc,U:yc,Y:zc,X:Ac,R:Bc,n:Cc,T:Dc,Z:Ec,
|
||||
k:Fc,W:Gc,l:Hc};
|
||||
(function(){function b(g){g=g.exports;g=Kc(g);a.asm=g;ma=a.asm.ua;va();wa=a.asm.Df;ya.unshift(a.asm.va);Ca--;a.monitorRunDependencies&&a.monitorRunDependencies(Ca);0==Ca&&(null!==Da&&(clearInterval(Da),Da=null),Ea&&(g=Ea,Ea=null,g()))}function c(g){b(g.instance)}function d(g){return Ia().then(function(h){return WebAssembly.instantiate(h,e)}).then(function(h){return h}).then(g,function(h){t("failed to asynchronously prepare wasm: "+h);u(h)})}var e={a:ld};Ca++;a.monitorRunDependencies&&a.monitorRunDependencies(Ca);
|
||||
(function(){function b(g){g=g.exports;g=Kc(g);a.asm=g;ma=a.asm.ua;va();wa=a.asm.Cf;ya.unshift(a.asm.va);Ca--;a.monitorRunDependencies&&a.monitorRunDependencies(Ca);0==Ca&&(null!==Da&&(clearInterval(Da),Da=null),Ea&&(g=Ea,Ea=null,g()))}function c(g){b(g.instance)}function d(g){return Ia().then(function(h){return WebAssembly.instantiate(h,e)}).then(function(h){return h}).then(g,function(h){t("failed to asynchronously prepare wasm: "+h);u(h)})}var e={a:ld};Ca++;a.monitorRunDependencies&&a.monitorRunDependencies(Ca);
|
||||
if(a.instantiateWasm)try{var f=a.instantiateWasm(e,b);return f=Kc(f)}catch(g){t("Module.instantiateWasm callback failed with error: "+g),ba(g)}(function(){return la||"function"!=typeof WebAssembly.instantiateStreaming||Fa()||"function"!=typeof fetch?d(c):fetch(F,{credentials:"same-origin"}).then(function(g){return WebAssembly.instantiateStreaming(g,e).then(c,function(h){t("wasm streaming compile failed: "+h);t("falling back to ArrayBuffer instantiation");return d(c)})})})().catch(ba);return{}})();
|
||||
a.___wasm_call_ctors=function(){return(a.___wasm_call_ctors=a.asm.va).apply(null,arguments)};a._sqlite3_status64=function(){return(a._sqlite3_status64=a.asm.wa).apply(null,arguments)};a._sqlite3_status=function(){return(a._sqlite3_status=a.asm.xa).apply(null,arguments)};a._sqlite3_db_status=function(){return(a._sqlite3_db_status=a.asm.ya).apply(null,arguments)};a._sqlite3_msize=function(){return(a._sqlite3_msize=a.asm.za).apply(null,arguments)};
|
||||
a._sqlite3_vfs_find=function(){return(a._sqlite3_vfs_find=a.asm.Aa).apply(null,arguments)};a._sqlite3_vfs_register=function(){return(a._sqlite3_vfs_register=a.asm.Ba).apply(null,arguments)};a._sqlite3_vfs_unregister=function(){return(a._sqlite3_vfs_unregister=a.asm.Ca).apply(null,arguments)};a._sqlite3_release_memory=function(){return(a._sqlite3_release_memory=a.asm.Da).apply(null,arguments)};a._sqlite3_soft_heap_limit64=function(){return(a._sqlite3_soft_heap_limit64=a.asm.Ea).apply(null,arguments)};
|
||||
@@ -148,8 +148,8 @@ a._sqlite3_rekey_v2=function(){return(a._sqlite3_rekey_v2=a.asm.mf).apply(null,a
|
||||
var Rb=a._malloc=function(){return(Rb=a._malloc=a.asm.qf).apply(null,arguments)},$c=a._free=function(){return($c=a._free=a.asm.rf).apply(null,arguments)};a._RegisterExtensionFunctions=function(){return(a._RegisterExtensionFunctions=a.asm.sf).apply(null,arguments)};a._sqlite3Fts5BetterTrigramInit=function(){return(a._sqlite3Fts5BetterTrigramInit=a.asm.tf).apply(null,arguments)};a._sqlite3Fts5HtmlInit=function(){return(a._sqlite3Fts5HtmlInit=a.asm.uf).apply(null,arguments)};
|
||||
a._set_authorizer=function(){return(a._set_authorizer=a.asm.vf).apply(null,arguments)};a._create_function=function(){return(a._create_function=a.asm.wf).apply(null,arguments)};a._create_module=function(){return(a._create_module=a.asm.xf).apply(null,arguments)};a._progress_handler=function(){return(a._progress_handler=a.asm.yf).apply(null,arguments)};a._register_vfs=function(){return(a._register_vfs=a.asm.zf).apply(null,arguments)};
|
||||
a._getSqliteFree=function(){return(a._getSqliteFree=a.asm.Af).apply(null,arguments)};a._main=function(){return(a._main=a.asm.Bf).apply(null,arguments)};
|
||||
var ab=a._emscripten_builtin_memalign=function(){return(ab=a._emscripten_builtin_memalign=a.asm.Cf).apply(null,arguments)},md=a.getTempRet0=function(){return(md=a.getTempRet0=a.asm.Ef).apply(null,arguments)},hd=a.stackSave=function(){return(hd=a.stackSave=a.asm.Ff).apply(null,arguments)},fd=a.stackRestore=function(){return(fd=a.stackRestore=a.asm.Gf).apply(null,arguments)},gd=a.stackAlloc=function(){return(gd=a.stackAlloc=a.asm.Hf).apply(null,arguments)},Yc=a._asyncify_start_unwind=function(){return(Yc=
|
||||
a._asyncify_start_unwind=a.asm.If).apply(null,arguments)},Mc=a._asyncify_stop_unwind=function(){return(Mc=a._asyncify_stop_unwind=a.asm.Jf).apply(null,arguments)},Wc=a._asyncify_start_rewind=function(){return(Wc=a._asyncify_start_rewind=a.asm.Kf).apply(null,arguments)},Zc=a._asyncify_stop_rewind=function(){return(Zc=a._asyncify_stop_rewind=a.asm.Lf).apply(null,arguments)};a._sqlite3_version=3232;a.UTF8ToString=x;a.stringToUTF8=qa;a.lengthBytesUTF8=ra;a.getTempRet0=md;a.ccall=Z;
|
||||
var ab=a._emscripten_builtin_memalign=function(){return(ab=a._emscripten_builtin_memalign=a.asm.Df).apply(null,arguments)},md=a.getTempRet0=function(){return(md=a.getTempRet0=a.asm.Ef).apply(null,arguments)},hd=a.stackSave=function(){return(hd=a.stackSave=a.asm.Ff).apply(null,arguments)},fd=a.stackRestore=function(){return(fd=a.stackRestore=a.asm.Gf).apply(null,arguments)},gd=a.stackAlloc=function(){return(gd=a.stackAlloc=a.asm.Hf).apply(null,arguments)},Yc=a._asyncify_start_unwind=function(){return(Yc=
|
||||
a._asyncify_start_unwind=a.asm.If).apply(null,arguments)},Mc=a._asyncify_stop_unwind=function(){return(Mc=a._asyncify_stop_unwind=a.asm.Jf).apply(null,arguments)},Wc=a._asyncify_start_rewind=function(){return(Wc=a._asyncify_start_rewind=a.asm.Kf).apply(null,arguments)},Zc=a._asyncify_stop_rewind=function(){return(Zc=a._asyncify_stop_rewind=a.asm.Lf).apply(null,arguments)};a._sqlite3_version=60912;a.UTF8ToString=x;a.stringToUTF8=qa;a.lengthBytesUTF8=ra;a.getTempRet0=md;a.ccall=Z;
|
||||
a.cwrap=function(b,c,d,e){d=d||[];var f=d.every(g=>"number"===g||"boolean"===g);return"string"!==c&&f&&!e?a["_"+b]:function(){return Z(b,c,d,arguments,e)}};
|
||||
a.addFunction=function(b,c){if(!cd){cd=new WeakMap;var d=wa.length;if(cd)for(var e=0;e<0+d;e++){var f=wa.get(e);f&&cd.set(f,e)}}if(cd.has(b))return cd.get(b);if(dd.length)d=dd.pop();else{try{wa.grow(1)}catch(n){if(!(n instanceof RangeError))throw n;throw"Unable to grow wasm table. Set ALLOW_TABLE_GROWTH.";}d=wa.length-1}try{wa.set(d,b)}catch(n){if(!(n instanceof TypeError))throw n;if("function"==typeof WebAssembly.Function){e=WebAssembly.Function;f={i:"i32",j:"i32",f:"f32",d:"f64",p:"i32"};for(var g=
|
||||
{parameters:[],results:"v"==c[0]?[]:[f[c[0]]]},h=1;h<c.length;++h)g.parameters.push(f[c[h]]),"j"===c[h]&&g.parameters.push("i32");c=new e(g,b)}else{e=[1];f=c.slice(0,1);c=c.slice(1);g={i:127,p:127,j:126,f:125,d:124};e.push(96);h=c.length;128>h?e.push(h):e.push(h%128|128,h>>7);for(h=0;h<c.length;++h)e.push(g[c[h]]);"v"==f?e.push(0):e.push(1,g[f]);c=[0,97,115,109,1,0,0,0,1];f=e.length;128>f?c.push(f):c.push(f%128|128,f>>7);c.push.apply(c,e);c.push(2,7,1,1,101,1,102,0,0,7,5,1,1,102,0,0);c=new WebAssembly.Module(new Uint8Array(c));
|
||||
|
||||
Binary file not shown.
@@ -83,7 +83,7 @@ h=c=0;h<d;h++){var p=C[b>>2],l=C[b+4>>2];b+=8;var k=f,n=p,q=l,r=g,w=y;if(0>q||0>
|
||||
typeof X||!(H instanceof P))throw H;return H.Lf}},i:function(b,c,d,e,f){try{c=d+2097152>>>0<4194305-!!c?(c>>>0)+4294967296*d:NaN;if(isNaN(c))return 61;var g=Y(b);Bb(g,c,e);L=[g.position>>>0,(K=g.position,1<=+Math.abs(K)?0<K?(Math.min(+Math.floor(K/4294967296),4294967295)|0)>>>0:~~+Math.ceil((K-+(~~K>>>0))/4294967296)>>>0:0)];B[f>>2]=L[0];B[f+4>>2]=L[1];g.lg&&0===c&&0===e&&(g.lg=null);return 0}catch(h){if("undefined"==typeof X||!(h instanceof P))throw h;return h.Lf}},E:function(b){try{var c=Y(b);return c.Jf&&
|
||||
c.Jf.Xf?c.Jf.Xf(c):0}catch(d){if("undefined"==typeof X||!(d instanceof P))throw d;return d.Lf}},s:function(b,c,d,e){try{a:{var f=Y(b);b=c;for(var g,h=c=0;h<d;h++){var p=C[b>>2],l=C[b+4>>2];b+=8;var k=f,n=p,q=l,r=g,w=y;if(0>q||0>r)throw new P(28);if(null===k.Tf)throw new P(8);if(0===(k.flags&2097155))throw new P(8);if(16384===(k.node.mode&61440))throw new P(31);if(!k.Jf.write)throw new P(28);k.seekable&&k.flags&1024&&Bb(k,0,2);var z="undefined"!=typeof r;if(!z)r=k.position;else if(!k.seekable)throw new P(70);
|
||||
var G=k.Jf.write(k,w,n,q,r,void 0);z||(k.position+=G);var D=G;if(0>D){var J=-1;break a}c+=D;"undefined"!==typeof g&&(g+=D)}J=c}C[e>>2]=J;return 0}catch(H){if("undefined"==typeof X||!(H instanceof P))throw H;return H.Lf}},sa:Tb,_:Ub,x:Vb,P:Wb,ca:Xb,I:Yb,ka:Zb,m:$b,ra:ac,na:bc,ia:cc,ea:dc,fa:ec,g:fc,h:gc,oa:hc,qa:ic,pa:jc,da:kc,ga:lc,ha:mc,ma:nc,c:oc,ja:pc,la:qc,aa:rc,V:sc,$:tc,ba:uc,S:vc,U:wc,Y:xc,X:yc,R:zc,n:Ac,T:Bc,Z:Cc,k:Dc,W:Ec,l:Fc};
|
||||
(function(){function b(f){a.asm=f.exports;ma=a.asm.ua;wa();E=a.asm.Df;ya.unshift(a.asm.va);F--;a.monitorRunDependencies&&a.monitorRunDependencies(F);0==F&&(null!==Ca&&(clearInterval(Ca),Ca=null),Da&&(f=Da,Da=null,f()))}function c(f){b(f.instance)}function d(f){return Ha().then(function(g){return WebAssembly.instantiate(g,e)}).then(function(g){return g}).then(f,function(g){t("failed to asynchronously prepare wasm: "+g);u(g)})}var e={a:Oc};F++;a.monitorRunDependencies&&a.monitorRunDependencies(F);if(a.instantiateWasm)try{return a.instantiateWasm(e,
|
||||
(function(){function b(f){a.asm=f.exports;ma=a.asm.ua;wa();E=a.asm.Cf;ya.unshift(a.asm.va);F--;a.monitorRunDependencies&&a.monitorRunDependencies(F);0==F&&(null!==Ca&&(clearInterval(Ca),Ca=null),Da&&(f=Da,Da=null,f()))}function c(f){b(f.instance)}function d(f){return Ha().then(function(g){return WebAssembly.instantiate(g,e)}).then(function(g){return g}).then(f,function(g){t("failed to asynchronously prepare wasm: "+g);u(g)})}var e={a:Oc};F++;a.monitorRunDependencies&&a.monitorRunDependencies(F);if(a.instantiateWasm)try{return a.instantiateWasm(e,
|
||||
b)}catch(f){t("Module.instantiateWasm callback failed with error: "+f),ba(f)}(function(){return la||"function"!=typeof WebAssembly.instantiateStreaming||Ea()||"function"!=typeof fetch?d(c):fetch(I,{credentials:"same-origin"}).then(function(f){return WebAssembly.instantiateStreaming(f,e).then(c,function(g){t("wasm streaming compile failed: "+g);t("falling back to ArrayBuffer instantiation");return d(c)})})})().catch(ba);return{}})();
|
||||
a.___wasm_call_ctors=function(){return(a.___wasm_call_ctors=a.asm.va).apply(null,arguments)};a._sqlite3_status64=function(){return(a._sqlite3_status64=a.asm.wa).apply(null,arguments)};a._sqlite3_status=function(){return(a._sqlite3_status=a.asm.xa).apply(null,arguments)};a._sqlite3_db_status=function(){return(a._sqlite3_db_status=a.asm.ya).apply(null,arguments)};a._sqlite3_msize=function(){return(a._sqlite3_msize=a.asm.za).apply(null,arguments)};
|
||||
a._sqlite3_vfs_find=function(){return(a._sqlite3_vfs_find=a.asm.Aa).apply(null,arguments)};a._sqlite3_vfs_register=function(){return(a._sqlite3_vfs_register=a.asm.Ba).apply(null,arguments)};a._sqlite3_vfs_unregister=function(){return(a._sqlite3_vfs_unregister=a.asm.Ca).apply(null,arguments)};a._sqlite3_release_memory=function(){return(a._sqlite3_release_memory=a.asm.Da).apply(null,arguments)};a._sqlite3_soft_heap_limit64=function(){return(a._sqlite3_soft_heap_limit64=a.asm.Ea).apply(null,arguments)};
|
||||
@@ -142,7 +142,7 @@ a._sqlite3mc_cipher_name=function(){return(a._sqlite3mc_cipher_name=a.asm.gf).ap
|
||||
a._sqlite3_rekey_v2=function(){return(a._sqlite3_rekey_v2=a.asm.mf).apply(null,arguments)};a._sqlite3_rekey=function(){return(a._sqlite3_rekey=a.asm.nf).apply(null,arguments)};a._sqlite3_regexp_init=function(){return(a._sqlite3_regexp_init=a.asm.of).apply(null,arguments)};a._sqlite3mc_register_cipher=function(){return(a._sqlite3mc_register_cipher=a.asm.pf).apply(null,arguments)};var Pb=a._malloc=function(){return(Pb=a._malloc=a.asm.qf).apply(null,arguments)};
|
||||
a._free=function(){return(a._free=a.asm.rf).apply(null,arguments)};a._RegisterExtensionFunctions=function(){return(a._RegisterExtensionFunctions=a.asm.sf).apply(null,arguments)};a._sqlite3Fts5BetterTrigramInit=function(){return(a._sqlite3Fts5BetterTrigramInit=a.asm.tf).apply(null,arguments)};a._sqlite3Fts5HtmlInit=function(){return(a._sqlite3Fts5HtmlInit=a.asm.uf).apply(null,arguments)};a._set_authorizer=function(){return(a._set_authorizer=a.asm.vf).apply(null,arguments)};
|
||||
a._create_function=function(){return(a._create_function=a.asm.wf).apply(null,arguments)};a._create_module=function(){return(a._create_module=a.asm.xf).apply(null,arguments)};a._progress_handler=function(){return(a._progress_handler=a.asm.yf).apply(null,arguments)};a._register_vfs=function(){return(a._register_vfs=a.asm.zf).apply(null,arguments)};a._getSqliteFree=function(){return(a._getSqliteFree=a.asm.Af).apply(null,arguments)};a._main=function(){return(a._main=a.asm.Bf).apply(null,arguments)};
|
||||
var Za=a._emscripten_builtin_memalign=function(){return(Za=a._emscripten_builtin_memalign=a.asm.Cf).apply(null,arguments)},Pc=a.getTempRet0=function(){return(Pc=a.getTempRet0=a.asm.Ef).apply(null,arguments)},Kc=a.stackSave=function(){return(Kc=a.stackSave=a.asm.Ff).apply(null,arguments)},Lc=a.stackRestore=function(){return(Lc=a.stackRestore=a.asm.Gf).apply(null,arguments)},Jc=a.stackAlloc=function(){return(Jc=a.stackAlloc=a.asm.Hf).apply(null,arguments)};a._sqlite3_version=3232;a.UTF8ToString=v;
|
||||
var Za=a._emscripten_builtin_memalign=function(){return(Za=a._emscripten_builtin_memalign=a.asm.Df).apply(null,arguments)},Pc=a.getTempRet0=function(){return(Pc=a.getTempRet0=a.asm.Ef).apply(null,arguments)},Kc=a.stackSave=function(){return(Kc=a.stackSave=a.asm.Ff).apply(null,arguments)},Lc=a.stackRestore=function(){return(Lc=a.stackRestore=a.asm.Gf).apply(null,arguments)},Jc=a.stackAlloc=function(){return(Jc=a.stackAlloc=a.asm.Hf).apply(null,arguments)};a._sqlite3_version=60912;a.UTF8ToString=v;
|
||||
a.stringToUTF8=ra;a.lengthBytesUTF8=sa;a.getTempRet0=Pc;a.ccall=Z;a.cwrap=function(b,c,d,e){d=d||[];var f=d.every(g=>"number"===g||"boolean"===g);return"string"!==c&&f&&!e?a["_"+b]:function(){return Z(b,c,d,arguments,e)}};
|
||||
a.addFunction=function(b,c){if(!Gc){Gc=new WeakMap;var d=E.length;if(Gc)for(var e=0;e<0+d;e++){var f=E.get(e);f&&Gc.set(f,e)}}if(Gc.has(b))return Gc.get(b);if(Hc.length)d=Hc.pop();else{try{E.grow(1)}catch(p){if(!(p instanceof RangeError))throw p;throw"Unable to grow wasm table. Set ALLOW_TABLE_GROWTH.";}d=E.length-1}try{E.set(d,b)}catch(p){if(!(p instanceof TypeError))throw p;if("function"==typeof WebAssembly.Function){e=WebAssembly.Function;f={i:"i32",j:"i32",f:"f32",d:"f64",p:"i32"};for(var g={parameters:[],
|
||||
results:"v"==c[0]?[]:[f[c[0]]]},h=1;h<c.length;++h)g.parameters.push(f[c[h]]),"j"===c[h]&&g.parameters.push("i32");c=new e(g,b)}else{e=[1];f=c.slice(0,1);c=c.slice(1);g={i:127,p:127,j:126,f:125,d:124};e.push(96);h=c.length;128>h?e.push(h):e.push(h%128|128,h>>7);for(h=0;h<c.length;++h)e.push(g[c[h]]);"v"==f?e.push(0):e.push(1,g[f]);c=[0,97,115,109,1,0,0,0,1];f=e.length;128>f?c.push(f):c.push(f%128|128,f>>7);c.push.apply(c,e);c.push(2,7,1,1,101,1,102,0,0,7,5,1,1,102,0,0);c=new WebAssembly.Module(new Uint8Array(c));
|
||||
|
||||
Binary file not shown.
@@ -378,7 +378,7 @@ function TipTap(props: TipTapProps) {
|
||||
<ScrollContainer
|
||||
className="toolbarScroll"
|
||||
suppressScrollY
|
||||
style={{ display: "flex" }}
|
||||
style={{ display: "flex", overscrollBehavior: "contain" }}
|
||||
trackStyle={() => ({
|
||||
backgroundColor: "transparent",
|
||||
"--ms-track-size": "6px"
|
||||
|
||||
@@ -39,9 +39,10 @@ function TitleBox(props: TitleBoxProps) {
|
||||
const inputRef = useRef<HTMLTextAreaElement>(null);
|
||||
const pendingChanges = useRef(false);
|
||||
const sessionType = useEditorStore((store) => store.getSession(id)?.type);
|
||||
const sessionTitle = useEditorStore(
|
||||
(store) => store.getSession(id, ["default"])?.note.title
|
||||
);
|
||||
const sessionTitle = useEditorStore((store) => {
|
||||
const session = store.getSession(id, ["default"]);
|
||||
return session?.note.isGeneratedTitle ? session.note.title : null;
|
||||
});
|
||||
const { editorConfig } = useEditorConfig();
|
||||
const dateFormat = useSettingsStore((store) => store.dateFormat);
|
||||
const timeFormat = useSettingsStore((store) => store.timeFormat);
|
||||
|
||||
@@ -46,7 +46,10 @@ export function ProviderSelector(props: ProviderSelectorProps) {
|
||||
sx={{ mt: 1, color: "paragraph", whiteSpace: "pre-wrap" }}
|
||||
>
|
||||
Can't find your notes app in the list?{" "}
|
||||
<a href="https://github.com/streetwriters/notesnook-importer/issues/new">
|
||||
<a
|
||||
href="https://github.com/streetwriters/notesnook-importer/issues/new"
|
||||
target="_blank"
|
||||
>
|
||||
Send us a request.
|
||||
</a>
|
||||
</Text>
|
||||
|
||||
@@ -113,6 +113,7 @@ type Route = {
|
||||
path: string;
|
||||
icon: Icon;
|
||||
tag?: string;
|
||||
loginRequired?: boolean;
|
||||
};
|
||||
|
||||
const routes: Route[] = [
|
||||
@@ -133,7 +134,8 @@ const routes: Route[] = [
|
||||
id: "monographs",
|
||||
title: strings.routes.Monographs(),
|
||||
path: "/monographs",
|
||||
icon: Monographs
|
||||
icon: Monographs,
|
||||
loginRequired: true
|
||||
},
|
||||
{ id: "trash", title: strings.routes.Trash(), path: "/trash", icon: Trash },
|
||||
{
|
||||
@@ -449,9 +451,12 @@ function Routes({
|
||||
collapse: () => void;
|
||||
}) {
|
||||
const hiddenRoutes = useAppStore((store) => store.hiddenRoutes);
|
||||
const isLoggedIn = useUserStore((store) => store.isLoggedIn);
|
||||
return (
|
||||
<ReorderableList
|
||||
items={routes.filter((r) => !hiddenRoutes.includes(r.id))}
|
||||
items={routes
|
||||
.filter((r) => !hiddenRoutes.includes(r.id))
|
||||
.filter((r) => (r.loginRequired ? isLoggedIn : true))}
|
||||
orderKey={`sidebarOrder:routes`}
|
||||
order={() => db.settings.getSideBarOrder("routes")}
|
||||
onOrderChanged={(order) => db.settings.setSideBarOrder("routes", order)}
|
||||
|
||||
@@ -680,7 +680,8 @@ type ResolvedGroup = {
|
||||
};
|
||||
function getGroup(items: TreeNode[], groupId: string): ResolvedGroup | null {
|
||||
const index = items.findIndex((item) => item.id === groupId);
|
||||
const group = items[index];
|
||||
const group = items.at(index);
|
||||
if (!group) return null;
|
||||
if (!isGroup(group) && !isSubgroup(group)) return null;
|
||||
|
||||
const nextGroupIndex = items.findIndex(
|
||||
|
||||
@@ -31,6 +31,7 @@ import { SpellCheckerLanguages } from "./components/spell-checker-languages";
|
||||
import { CustomizeToolbar } from "./components/customize-toolbar";
|
||||
import { DictionaryWords } from "./components/dictionary-words";
|
||||
import { strings } from "@notesnook/intl";
|
||||
import { isMac } from "../../utils/platform";
|
||||
|
||||
export const EditorSettings: SettingsGroup[] = [
|
||||
{
|
||||
@@ -164,7 +165,7 @@ export const EditorSettings: SettingsGroup[] = [
|
||||
key: "spell-checker-languages",
|
||||
title: strings.languages(),
|
||||
description: strings.spellCheckerLanguagesDescription(),
|
||||
isHidden: () => !useSpellChecker.getState().enabled,
|
||||
isHidden: () => !useSpellChecker.getState().enabled || isMac(),
|
||||
onStateChange: (listener) =>
|
||||
useSpellChecker.subscribe((c) => c.enabled, listener),
|
||||
components: [
|
||||
|
||||
4
fastlane/metadata/android/en-US/changelogs/15299.txt
Normal file
4
fastlane/metadata/android/en-US/changelogs/15299.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
- Fix toolbar hidden behing keyboard on android 15 and 16
|
||||
- Minor bug fixes and improvements
|
||||
|
||||
Thank you for using Notesnook!
|
||||
5
fastlane/metadata/android/en-US/changelogs/15304.txt
Normal file
5
fastlane/metadata/android/en-US/changelogs/15304.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
- Fix toolbar hidden behing keyboard on android 15 and 16
|
||||
- Fix sync performance issues
|
||||
- Minor bug fixes and improvements
|
||||
|
||||
Thank you for using Notesnook!
|
||||
4
fastlane/metadata/android/en-US/changelogs/15309.txt
Normal file
4
fastlane/metadata/android/en-US/changelogs/15309.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
- Fix PDF files get stuck on first page
|
||||
- Minor bug fixes and improvements
|
||||
|
||||
Thank you for using Notesnook!
|
||||
4
fastlane/metadata/android/en-US/changelogs/15314.txt
Normal file
4
fastlane/metadata/android/en-US/changelogs/15314.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
- Fix crash on device boot on android 15 devices
|
||||
- Minor bug fixes and improvements
|
||||
|
||||
Thank you for using Notesnook!
|
||||
5
fastlane/metadata/android/en-US/changelogs/15319.txt
Normal file
5
fastlane/metadata/android/en-US/changelogs/15319.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
- Fix crash on device boot on android 15 devices
|
||||
- Fix note not opening in editor randomly
|
||||
- Minor bug fixes and improvements
|
||||
|
||||
Thank you for using Notesnook!
|
||||
2
packages/common/package-lock.json
generated
2
packages/common/package-lock.json
generated
@@ -85,7 +85,7 @@
|
||||
"refractor": "^4.8.1",
|
||||
"sqlite-better-trigram": "^0.0.3",
|
||||
"sqlite-regex": "^0.2.4-alpha.1",
|
||||
"sqlite3-fts5-html": "^0.0.3",
|
||||
"sqlite3-fts5-html": "^0.0.4",
|
||||
"vitest": "2.1.8",
|
||||
"vitest-fetch-mock": "^0.2.2",
|
||||
"ws": "^8.13.0"
|
||||
|
||||
56
packages/core/package-lock.json
generated
56
packages/core/package-lock.json
generated
@@ -62,7 +62,7 @@
|
||||
"refractor": "^4.8.1",
|
||||
"sqlite-better-trigram": "^0.0.3",
|
||||
"sqlite-regex": "^0.2.4-alpha.1",
|
||||
"sqlite3-fts5-html": "^0.0.3",
|
||||
"sqlite3-fts5-html": "^0.0.4",
|
||||
"vitest": "2.1.8",
|
||||
"vitest-fetch-mock": "^0.2.2",
|
||||
"ws": "^8.13.0"
|
||||
@@ -3445,24 +3445,24 @@
|
||||
]
|
||||
},
|
||||
"node_modules/sqlite3-fts5-html": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/sqlite3-fts5-html/-/sqlite3-fts5-html-0.0.3.tgz",
|
||||
"integrity": "sha512-omJELqavUID4rikHgSnprzR8KoD+k34Gr//Z6Ju5ZJLI9d2MTv+63gJ/9iCWCmvt5dLODDBL25RzmXsChltjkQ==",
|
||||
"version": "0.0.4",
|
||||
"resolved": "https://registry.npmjs.org/sqlite3-fts5-html/-/sqlite3-fts5-html-0.0.4.tgz",
|
||||
"integrity": "sha512-2d7G3QAgNtndTYRFDXVzzsjlDkjXLo9YB4xxVFIxHIotKnVTNmd0/iSQMMjOMFY5XEpW8yemFkD0EyuN0wFuSQ==",
|
||||
"dev": true,
|
||||
"license": "Public Domain",
|
||||
"optionalDependencies": {
|
||||
"sqlite3-fts5-html-darwin-arm64": "0.0.3",
|
||||
"sqlite3-fts5-html-darwin-x64": "0.0.3",
|
||||
"sqlite3-fts5-html-linux-arm64": "0.0.3",
|
||||
"sqlite3-fts5-html-linux-x64": "0.0.3",
|
||||
"sqlite3-fts5-html-windows-arm64": "0.0.3",
|
||||
"sqlite3-fts5-html-windows-x64": "0.0.3"
|
||||
"sqlite3-fts5-html-darwin-arm64": "0.0.4",
|
||||
"sqlite3-fts5-html-darwin-x64": "0.0.4",
|
||||
"sqlite3-fts5-html-linux-arm64": "0.0.4",
|
||||
"sqlite3-fts5-html-linux-x64": "0.0.4",
|
||||
"sqlite3-fts5-html-windows-arm64": "0.0.4",
|
||||
"sqlite3-fts5-html-windows-x64": "0.0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/sqlite3-fts5-html-darwin-arm64": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/sqlite3-fts5-html-darwin-arm64/-/sqlite3-fts5-html-darwin-arm64-0.0.3.tgz",
|
||||
"integrity": "sha512-jLmBOslggCYG+N8CVbjN/ok6kP9kCkWVYiXVF+ms4NylBPevs6+QBgY4GXNcVuSoRs2T8PT/gxI3yTnjdv/uDg==",
|
||||
"version": "0.0.4",
|
||||
"resolved": "https://registry.npmjs.org/sqlite3-fts5-html-darwin-arm64/-/sqlite3-fts5-html-darwin-arm64-0.0.4.tgz",
|
||||
"integrity": "sha512-zkg+LxOtq7ONz82C4+1mxsmasOIt9tbUReEMlmu29pJosfgDsMftp9k1Jy46FEk3VDFODlg9uDX7f0O0rspayg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -3474,9 +3474,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/sqlite3-fts5-html-darwin-x64": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/sqlite3-fts5-html-darwin-x64/-/sqlite3-fts5-html-darwin-x64-0.0.3.tgz",
|
||||
"integrity": "sha512-zhfkryrXf9UOS/vG9LEUs3sLZTyfgkkX316OAuSVhB0At9oa7rYc3FDiypNh6n3PMr+B3uySC6f9mipBGcsOiQ==",
|
||||
"version": "0.0.4",
|
||||
"resolved": "https://registry.npmjs.org/sqlite3-fts5-html-darwin-x64/-/sqlite3-fts5-html-darwin-x64-0.0.4.tgz",
|
||||
"integrity": "sha512-LtBRTVfB3eNkupKJEobZVOyf4TbmWw4XgdBGvi4wFHHcv96gqhVlHdUGlavul561AOpab+T7DOgaPgph1y5M5A==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -3488,9 +3488,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/sqlite3-fts5-html-linux-arm64": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/sqlite3-fts5-html-linux-arm64/-/sqlite3-fts5-html-linux-arm64-0.0.3.tgz",
|
||||
"integrity": "sha512-FoEwY8I7KHQ0iOtobskKFCqIgFbi+X97h733kDgAN5B9ADK6VHL6/jpLhJLzLtlSVgPedPLTTXnhgP2abQR0eg==",
|
||||
"version": "0.0.4",
|
||||
"resolved": "https://registry.npmjs.org/sqlite3-fts5-html-linux-arm64/-/sqlite3-fts5-html-linux-arm64-0.0.4.tgz",
|
||||
"integrity": "sha512-+xgRPpD7fdXNJPKaggHE5BkSF00aI8rlHHZ+pXZR2GmFyRr++jt34MA5avO4G6oI4mrZ82wUV+sWUqd8FErRBw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -3502,9 +3502,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/sqlite3-fts5-html-linux-x64": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/sqlite3-fts5-html-linux-x64/-/sqlite3-fts5-html-linux-x64-0.0.3.tgz",
|
||||
"integrity": "sha512-wJ2ONYC8Rs/HSWHVI2Y3j7vMh+6QzcA3SYCWAFJEFPM3aCyvf7lFhQgLSHZWkS+OUKduP+9/e/Hc7g3UwHdtig==",
|
||||
"version": "0.0.4",
|
||||
"resolved": "https://registry.npmjs.org/sqlite3-fts5-html-linux-x64/-/sqlite3-fts5-html-linux-x64-0.0.4.tgz",
|
||||
"integrity": "sha512-4ah7IiDUH9kpCPoqT4lW6FcWcNiVF0wtpywW82UVfkawbmgLFPGqSQFqHyChmp1b2dsrkO5X/bhq9E2BR0/xmQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -3516,9 +3516,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/sqlite3-fts5-html-windows-arm64": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/sqlite3-fts5-html-windows-arm64/-/sqlite3-fts5-html-windows-arm64-0.0.3.tgz",
|
||||
"integrity": "sha512-58Qi1NTe/Po+nWz2z24ziSvghQcrMC94/mxmErNeC4SFPZMN7JLx56W2eybJB436CiUUUN9MT4a6BD1bn7RpQg==",
|
||||
"version": "0.0.4",
|
||||
"resolved": "https://registry.npmjs.org/sqlite3-fts5-html-windows-arm64/-/sqlite3-fts5-html-windows-arm64-0.0.4.tgz",
|
||||
"integrity": "sha512-rQKLrX90TKIMgD7zSrOk/U6q0KEBiTaB2nXDONcK4d/CYpnG9g/N/i6Ady98j5+v/PgqymchgtRwvgBHOZzCfw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -3530,9 +3530,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/sqlite3-fts5-html-windows-x64": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/sqlite3-fts5-html-windows-x64/-/sqlite3-fts5-html-windows-x64-0.0.3.tgz",
|
||||
"integrity": "sha512-LYilVGRYXpN0nra3LL7CXlfaLbPmBK78rtaG9Aivufqexqjc2sB+v+xMGT8vxLXOjIAtkBLko2ELuYe8hRLQMw==",
|
||||
"version": "0.0.4",
|
||||
"resolved": "https://registry.npmjs.org/sqlite3-fts5-html-windows-x64/-/sqlite3-fts5-html-windows-x64-0.0.4.tgz",
|
||||
"integrity": "sha512-FxLloBxWtsIGUMxbvOLNY9+FXJYEcku1xVqJarLfGKcXX7zvS3yXMP0dYeld2lQ/evNiLgvLMNLhUFwhEln1vA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
"refractor": "^4.8.1",
|
||||
"sqlite-better-trigram": "^0.0.3",
|
||||
"sqlite-regex": "^0.2.4-alpha.1",
|
||||
"sqlite3-fts5-html": "^0.0.3",
|
||||
"sqlite3-fts5-html": "^0.0.4",
|
||||
"vitest": "2.1.8",
|
||||
"vitest-fetch-mock": "^0.2.2",
|
||||
"ws": "^8.13.0"
|
||||
|
||||
@@ -111,13 +111,7 @@ export function ClearFormatting(props: ToolProps) {
|
||||
{...props}
|
||||
toggled={false}
|
||||
onClick={() =>
|
||||
editor
|
||||
?.chain()
|
||||
.focus()
|
||||
.clearNodes()
|
||||
.unsetAllMarks()
|
||||
.unsetMark("link")
|
||||
.run()
|
||||
editor?.chain().focus().unsetAllMarks().unsetMark("link").run()
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -6,6 +6,12 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: @lingui/cli\n"
|
||||
"Language: en\n"
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"Plural-Forms: \n"
|
||||
|
||||
#: src/strings.ts:2410
|
||||
msgid " \"Notebook > Notes\""
|
||||
@@ -3946,6 +3952,10 @@ msgstr "No links found"
|
||||
msgid "No note history available for this device."
|
||||
msgstr "No note history available for this device."
|
||||
|
||||
#: src/strings.ts:2489
|
||||
msgid "No notebooks selected to move"
|
||||
msgstr "No notebooks selected to move"
|
||||
|
||||
#: src/strings.ts:202
|
||||
msgid "No one can view this {type} except you."
|
||||
msgstr "No one can view this {type} except you."
|
||||
|
||||
@@ -6,6 +6,12 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: @lingui/cli\n"
|
||||
"Language: pseudo-LOCALE\n"
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"Plural-Forms: \n"
|
||||
|
||||
#: src/strings.ts:2410
|
||||
msgid " \"Notebook > Notes\""
|
||||
@@ -3926,6 +3932,10 @@ msgstr ""
|
||||
msgid "No note history available for this device."
|
||||
msgstr ""
|
||||
|
||||
#: src/strings.ts:2489
|
||||
msgid "No notebooks selected to move"
|
||||
msgstr ""
|
||||
|
||||
#: src/strings.ts:202
|
||||
msgid "No one can view this {type} except you."
|
||||
msgstr ""
|
||||
|
||||
@@ -2485,5 +2485,6 @@ Use this if changes from other devices are not appearing on this device. This wi
|
||||
yourArchiveIsEmpty: () => t`Your archive is empty`,
|
||||
unarchive: () => t`Unarchive`,
|
||||
moveNotebookDesc: () =>
|
||||
t`Select a notebook to move this notebook into, or unselect to move it to the root level.`
|
||||
t`Select a notebook to move this notebook into, or unselect to move it to the root level.`,
|
||||
noNotebooksSelectedToMove: () => t`No notebooks selected to move`
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user