mirror of
https://github.com/streetwriters/notesnook.git
synced 2026-02-24 04:00:59 +01:00
mobile: redesign onboarding (#2633)
This commit is contained in:
@@ -126,11 +126,11 @@ const AuthModal = () => {
|
||||
|
||||
{initialAuthMode.current !== AuthMode.welcomeSignup ? null : (
|
||||
<Button
|
||||
title="Skip for now"
|
||||
title="Skip"
|
||||
onPress={() => {
|
||||
hideAuth();
|
||||
}}
|
||||
iconSize={20}
|
||||
iconSize={16}
|
||||
type="gray"
|
||||
iconPosition="right"
|
||||
icon="chevron-right"
|
||||
|
||||
@@ -18,9 +18,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { View } from "react-native";
|
||||
import { TouchableOpacity, View } from "react-native";
|
||||
import { SheetManager } from "react-native-actions-sheet";
|
||||
import Animated, { FadeInDown, FadeOutUp } from "react-native-reanimated";
|
||||
import { DDS } from "../../services/device-detection";
|
||||
import { eSendEvent } from "../../services/event-manager";
|
||||
import { useThemeStore } from "../../stores/use-theme-store";
|
||||
@@ -30,13 +29,12 @@ import SheetProvider from "../sheet-provider";
|
||||
import { Progress } from "../sheets/progress";
|
||||
import { Button } from "../ui/button";
|
||||
import Input from "../ui/input";
|
||||
import { SvgView } from "../ui/svg";
|
||||
import Heading from "../ui/typography/heading";
|
||||
import Paragraph from "../ui/typography/paragraph";
|
||||
import { SVG } from "./background";
|
||||
import { hideAuth } from "./common";
|
||||
import { ForgotPassword } from "./forgot-password";
|
||||
import { useLogin } from "./use-login";
|
||||
import { useSettingStore } from "../../stores/use-setting-store";
|
||||
|
||||
const LoginSteps = {
|
||||
emailAuth: 1,
|
||||
@@ -64,6 +62,7 @@ export const Login = ({ changeMode }) => {
|
||||
await sleep(500);
|
||||
Progress.present();
|
||||
});
|
||||
const deviceMode = useSettingStore((state) => state.deviceMode);
|
||||
|
||||
useEffect(() => {
|
||||
async () => {
|
||||
@@ -82,62 +81,70 @@ export const Login = ({ changeMode }) => {
|
||||
<>
|
||||
<ForgotPassword />
|
||||
<SheetProvider context="two_factor_verify" />
|
||||
<Animated.View
|
||||
entering={FadeInDown}
|
||||
exiting={FadeOutUp}
|
||||
<View
|
||||
style={{
|
||||
borderRadius: DDS.isTab ? 5 : 0,
|
||||
backgroundColor: colors.bg,
|
||||
zIndex: 10,
|
||||
width: "100%",
|
||||
alignSelf: "center",
|
||||
height: "100%",
|
||||
minHeight: "100%"
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
height: 250,
|
||||
overflow: "hidden"
|
||||
}}
|
||||
>
|
||||
<SvgView
|
||||
src={SVG(colors.night ? colors.icon : "black")}
|
||||
height={700}
|
||||
/>
|
||||
</View>
|
||||
<View
|
||||
style={{
|
||||
width: "100%",
|
||||
justifyContent: "center",
|
||||
alignSelf: "center",
|
||||
paddingHorizontal: 12,
|
||||
marginBottom: 30,
|
||||
marginTop: 15
|
||||
flex: 0.45,
|
||||
justifyContent: "flex-end",
|
||||
paddingHorizontal: 20,
|
||||
backgroundColor: colors.nav,
|
||||
marginBottom: 20,
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: colors.border,
|
||||
alignSelf: deviceMode !== "mobile" ? "center" : undefined,
|
||||
borderWidth: deviceMode !== "mobile" ? 1 : null,
|
||||
borderColor: deviceMode !== "mobile" ? colors.border : null,
|
||||
borderRadius: deviceMode !== "mobile" ? 20 : null,
|
||||
marginTop: deviceMode !== "mobile" ? 50 : null,
|
||||
width: deviceMode === "mobile" ? null : "50%"
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row"
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
width: 100,
|
||||
height: 5,
|
||||
backgroundColor: colors.accent,
|
||||
borderRadius: 2,
|
||||
marginRight: 7
|
||||
}}
|
||||
/>
|
||||
|
||||
<View
|
||||
style={{
|
||||
width: 20,
|
||||
height: 5,
|
||||
backgroundColor: colors.nav,
|
||||
borderRadius: 2
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
<Heading
|
||||
style={{
|
||||
textAlign: "center"
|
||||
marginBottom: 25,
|
||||
marginTop: 10
|
||||
}}
|
||||
size={30}
|
||||
color={colors.heading}
|
||||
extraBold
|
||||
size={SIZE.xxl}
|
||||
>
|
||||
Welcome back!
|
||||
Login to your {"\n"}account
|
||||
</Heading>
|
||||
<Paragraph
|
||||
style={{
|
||||
textDecorationLine: "underline",
|
||||
textAlign: "center",
|
||||
marginTop: 5
|
||||
}}
|
||||
onPress={() => {
|
||||
if (loading) return;
|
||||
changeMode(1);
|
||||
}}
|
||||
size={SIZE.md}
|
||||
>
|
||||
{"Don't have an account? Sign up"}
|
||||
</Paragraph>
|
||||
</View>
|
||||
|
||||
<View
|
||||
style={{
|
||||
width: DDS.isTab
|
||||
@@ -147,10 +154,9 @@ export const Login = ({ changeMode }) => {
|
||||
: focused
|
||||
? "100%"
|
||||
: "99.9%",
|
||||
padding: 12,
|
||||
backgroundColor: colors.bg,
|
||||
flexGrow: 1,
|
||||
alignSelf: "center"
|
||||
alignSelf: "center",
|
||||
paddingHorizontal: 20
|
||||
}}
|
||||
>
|
||||
<Input
|
||||
@@ -217,28 +223,22 @@ export const Login = ({ changeMode }) => {
|
||||
|
||||
<View
|
||||
style={{
|
||||
marginTop: 25,
|
||||
alignSelf: "center"
|
||||
marginTop: 25
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
style={{
|
||||
width: 250,
|
||||
borderRadius: 100
|
||||
}}
|
||||
loading={loading}
|
||||
onPress={() => {
|
||||
if (loading) return;
|
||||
login();
|
||||
}}
|
||||
style={{
|
||||
width: 250,
|
||||
borderRadius: 100
|
||||
}}
|
||||
fontSize={SIZE.md}
|
||||
type="accent"
|
||||
title={
|
||||
loading
|
||||
? null
|
||||
: step === LoginSteps.emailAuth
|
||||
? "Login"
|
||||
: "Continue"
|
||||
}
|
||||
title={!loading ? "Continue" : null}
|
||||
/>
|
||||
|
||||
{step === LoginSteps.passwordAuth && (
|
||||
@@ -261,9 +261,34 @@ export const Login = ({ changeMode }) => {
|
||||
type="errorShade"
|
||||
/>
|
||||
)}
|
||||
|
||||
{!loading ? (
|
||||
<TouchableOpacity
|
||||
onPress={() => {
|
||||
if (loading) return;
|
||||
changeMode(1);
|
||||
}}
|
||||
activeOpacity={0.8}
|
||||
style={{
|
||||
alignSelf: "center",
|
||||
marginTop: 12,
|
||||
paddingVertical: 12
|
||||
}}
|
||||
>
|
||||
<Paragraph size={SIZE.xs + 1} color={colors.icon}>
|
||||
Don't have an account?{" "}
|
||||
<Paragraph
|
||||
size={SIZE.xs + 1}
|
||||
style={{ color: colors.accent }}
|
||||
>
|
||||
Sign up
|
||||
</Paragraph>
|
||||
</Paragraph>
|
||||
</TouchableOpacity>
|
||||
) : null}
|
||||
</View>
|
||||
</View>
|
||||
</Animated.View>
|
||||
</View>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -18,8 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import React, { useRef, useState } from "react";
|
||||
import { Dimensions, View } from "react-native";
|
||||
import Animated, { FadeInDown, FadeOutUp } from "react-native-reanimated";
|
||||
import { TouchableOpacity, View } from "react-native";
|
||||
import { db } from "../../common/database";
|
||||
import { DDS } from "../../services/device-detection";
|
||||
import { ToastEvent } from "../../services/event-manager";
|
||||
@@ -32,11 +31,10 @@ import { SIZE } from "../../utils/size";
|
||||
import { sleep } from "../../utils/time";
|
||||
import { Button } from "../ui/button";
|
||||
import Input from "../ui/input";
|
||||
import { SvgView } from "../ui/svg";
|
||||
import Heading from "../ui/typography/heading";
|
||||
import Paragraph from "../ui/typography/paragraph";
|
||||
import { SVG } from "./background";
|
||||
import { hideAuth } from "./common";
|
||||
import { useSettingStore } from "../../stores/use-setting-store";
|
||||
|
||||
export const Signup = ({ changeMode, trial }) => {
|
||||
const colors = useThemeStore((state) => state.colors);
|
||||
@@ -50,6 +48,7 @@ export const Signup = ({ changeMode, trial }) => {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const setUser = useUserStore((state) => state.setUser);
|
||||
const setLastSynced = useUserStore((state) => state.setLastSynced);
|
||||
const deviceMode = useSettingStore((state) => state.deviceMode);
|
||||
|
||||
const validateInfo = () => {
|
||||
if (!password.current || !email.current || !confirmPassword.current) {
|
||||
@@ -96,69 +95,77 @@ export const Signup = ({ changeMode, trial }) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Animated.View
|
||||
entering={FadeInDown}
|
||||
exiting={FadeOutUp}
|
||||
<View
|
||||
style={{
|
||||
borderRadius: DDS.isTab ? 5 : 0,
|
||||
backgroundColor: colors.bg,
|
||||
zIndex: 10,
|
||||
width: "100%",
|
||||
alignSelf: "center",
|
||||
height: "100%",
|
||||
minHeight: "100%"
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
height: 250,
|
||||
overflow: "hidden"
|
||||
flex: 0.35,
|
||||
justifyContent: "flex-end",
|
||||
paddingHorizontal: 20,
|
||||
backgroundColor: colors.nav,
|
||||
marginBottom: 20,
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: colors.border,
|
||||
alignSelf: deviceMode !== "mobile" ? "center" : undefined,
|
||||
borderWidth: deviceMode !== "mobile" ? 1 : null,
|
||||
borderColor: deviceMode !== "mobile" ? colors.border : null,
|
||||
borderRadius: deviceMode !== "mobile" ? 20 : null,
|
||||
marginTop: deviceMode !== "mobile" ? 50 : null,
|
||||
width: deviceMode === "mobile" ? null : "50%"
|
||||
}}
|
||||
>
|
||||
<SvgView
|
||||
src={SVG(colors.night ? colors.icon : "black")}
|
||||
height={700}
|
||||
/>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row"
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
width: 100,
|
||||
height: 5,
|
||||
backgroundColor: colors.accent,
|
||||
borderRadius: 2,
|
||||
marginRight: 7
|
||||
}}
|
||||
/>
|
||||
|
||||
<View
|
||||
style={{
|
||||
width: 20,
|
||||
height: 5,
|
||||
backgroundColor: colors.nav,
|
||||
borderRadius: 2
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
<Heading
|
||||
extraBold
|
||||
style={{
|
||||
marginBottom: 25,
|
||||
marginTop: 10
|
||||
}}
|
||||
size={SIZE.xxl}
|
||||
>
|
||||
Create your {"\n"}account
|
||||
</Heading>
|
||||
</View>
|
||||
|
||||
<View
|
||||
style={{
|
||||
width: "100%",
|
||||
justifyContent: "center",
|
||||
alignSelf: "center",
|
||||
paddingHorizontal: 12,
|
||||
marginBottom: 30,
|
||||
marginTop: Dimensions.get("window").height < 700 ? -75 : 15
|
||||
}}
|
||||
>
|
||||
<Heading
|
||||
style={{
|
||||
textAlign: "center"
|
||||
}}
|
||||
size={30}
|
||||
color={colors.heading}
|
||||
>
|
||||
Create your account
|
||||
</Heading>
|
||||
<Paragraph
|
||||
style={{
|
||||
textDecorationLine: "underline",
|
||||
textAlign: "center"
|
||||
}}
|
||||
onPress={() => {
|
||||
if (loading) return;
|
||||
changeMode(0);
|
||||
}}
|
||||
size={SIZE.md}
|
||||
>
|
||||
Already have an account? Log in
|
||||
</Paragraph>
|
||||
</View>
|
||||
<View
|
||||
style={{
|
||||
width: DDS.isTab ? "50%" : "100%",
|
||||
padding: 12,
|
||||
paddingHorizontal: 20,
|
||||
backgroundColor: colors.bg,
|
||||
flexGrow: 1,
|
||||
alignSelf: "center"
|
||||
alignSelf: "center",
|
||||
flex: 0.6
|
||||
}}
|
||||
>
|
||||
<Input
|
||||
@@ -217,37 +224,13 @@ export const Signup = ({ changeMode, trial }) => {
|
||||
validationType="confirmPassword"
|
||||
customValidator={() => password.current}
|
||||
placeholder="Confirm password"
|
||||
marginBottom={5}
|
||||
marginBottom={12}
|
||||
onSubmit={signup}
|
||||
/>
|
||||
<View
|
||||
style={{
|
||||
marginTop: 25,
|
||||
alignSelf: "center"
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
style={{
|
||||
width: 250,
|
||||
borderRadius: 100
|
||||
}}
|
||||
loading={loading}
|
||||
onPress={() => {
|
||||
if (loading) return;
|
||||
signup();
|
||||
}}
|
||||
type="accent"
|
||||
title={loading ? null : "Agree and continue"}
|
||||
/>
|
||||
</View>
|
||||
|
||||
<Paragraph
|
||||
style={{
|
||||
textAlign: "center",
|
||||
position: "absolute",
|
||||
bottom: 0,
|
||||
alignSelf: "center",
|
||||
marginBottom: 20
|
||||
marginBottom: 25
|
||||
}}
|
||||
size={SIZE.xs}
|
||||
color={colors.icon}
|
||||
@@ -263,7 +246,7 @@ export const Signup = ({ changeMode, trial }) => {
|
||||
}}
|
||||
color={colors.accent}
|
||||
>
|
||||
terms of service{" "}
|
||||
Terms of Service{" "}
|
||||
</Paragraph>
|
||||
and{" "}
|
||||
<Paragraph
|
||||
@@ -276,11 +259,46 @@ export const Signup = ({ changeMode, trial }) => {
|
||||
}}
|
||||
color={colors.accent}
|
||||
>
|
||||
privacy policy.
|
||||
</Paragraph>
|
||||
Privacy Policy.
|
||||
</Paragraph>{" "}
|
||||
You also agree to recieve marketing emails from us which you can
|
||||
opt-out of from app settings.
|
||||
</Paragraph>
|
||||
|
||||
<Button
|
||||
title={!loading ? "Continue" : null}
|
||||
type="accent"
|
||||
loading={loading}
|
||||
onPress={signup}
|
||||
fontSize={SIZE.md}
|
||||
style={{
|
||||
marginRight: 12,
|
||||
width: 250,
|
||||
borderRadius: 100
|
||||
}}
|
||||
/>
|
||||
|
||||
<TouchableOpacity
|
||||
onPress={() => {
|
||||
if (loading) return;
|
||||
changeMode(0);
|
||||
}}
|
||||
activeOpacity={0.8}
|
||||
style={{
|
||||
alignSelf: "center",
|
||||
marginTop: 12,
|
||||
paddingVertical: 12
|
||||
}}
|
||||
>
|
||||
<Paragraph size={SIZE.xs + 1} color={colors.icon}>
|
||||
Already have an account?{" "}
|
||||
<Paragraph size={SIZE.xs + 1} style={{ color: colors.accent }}>
|
||||
Login
|
||||
</Paragraph>
|
||||
</Paragraph>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</Animated.View>
|
||||
</View>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -42,7 +42,6 @@ import { eOpenAnnouncementDialog } from "../../utils/events";
|
||||
import { getGithubVersion } from "../../utils/github-version";
|
||||
import { SIZE } from "../../utils/size";
|
||||
import { sleep } from "../../utils/time";
|
||||
import { SVG } from "../auth/background";
|
||||
import Migrate from "../sheets/migrate";
|
||||
import NewFeature from "../sheets/new-feature/index";
|
||||
import { Update } from "../sheets/update";
|
||||
@@ -50,7 +49,6 @@ import { Button } from "../ui/button";
|
||||
import { IconButton } from "../ui/icon-button";
|
||||
import Input from "../ui/input";
|
||||
import Seperator from "../ui/seperator";
|
||||
import { SvgView } from "../ui/svg";
|
||||
import Heading from "../ui/typography/heading";
|
||||
import Paragraph from "../ui/typography/paragraph";
|
||||
import { Walkthrough } from "../walkthroughs";
|
||||
@@ -89,7 +87,7 @@ const Launcher = React.memo(
|
||||
|
||||
const init = useCallback(async () => {
|
||||
if (!db.isInitialized) {
|
||||
await RNBootSplash.hide({ fade: true });
|
||||
RNBootSplash.hide({ fade: true });
|
||||
DatabaseLogger.info("Initializing database");
|
||||
await db.init();
|
||||
}
|
||||
@@ -132,7 +130,6 @@ const Launcher = React.memo(
|
||||
if (NewFeature.present()) return;
|
||||
if (await checkAppUpdateAvailable()) return;
|
||||
if (await checkForRateAppRequest()) return;
|
||||
if (await checkNeedsBackup()) return;
|
||||
if (await PremiumService.getRemainingTrialDaysStatus()) return;
|
||||
|
||||
if (introCompleted) {
|
||||
@@ -175,23 +172,6 @@ const Launcher = React.memo(
|
||||
return false;
|
||||
};
|
||||
|
||||
const checkNeedsBackup = async () => {
|
||||
return false;
|
||||
// let { nextBackupRequestTime, reminder } = SettingsService.get();
|
||||
// if (reminder === 'off' || !reminder) {
|
||||
// if (nextBackupRequestTime < Date.now()) {
|
||||
// presentSheet({
|
||||
// title: 'Backup & restore',
|
||||
// paragraph: 'Please enable automatic backups to keep your data safe',
|
||||
// component: <SettingsBackupAndRestore isSheet={true} />
|
||||
// });
|
||||
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
// return false;
|
||||
};
|
||||
|
||||
const onUnlockBiometrics = useCallback(async () => {
|
||||
if (!(await BiometricService.isBiometryAvailable())) return;
|
||||
if (Platform.OS === "android") {
|
||||
@@ -247,18 +227,10 @@ const Launcher = React.memo(
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
position: "absolute",
|
||||
zIndex: 999
|
||||
zIndex: 999,
|
||||
justifyContent: "center"
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
height: 250,
|
||||
overflow: "hidden"
|
||||
}}
|
||||
>
|
||||
<SvgView src={SVG(colors.night ? "white" : "black")} height={700} />
|
||||
</View>
|
||||
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
@@ -294,14 +266,13 @@ const Launcher = React.memo(
|
||||
textAlign: "center"
|
||||
}}
|
||||
>
|
||||
Unlock to access your notes
|
||||
Unlock your notes
|
||||
</Heading>
|
||||
|
||||
<Paragraph
|
||||
style={{
|
||||
alignSelf: "center",
|
||||
textAlign: "center",
|
||||
fontSize: SIZE.md,
|
||||
maxWidth: "90%"
|
||||
}}
|
||||
>
|
||||
@@ -312,8 +283,7 @@ const Launcher = React.memo(
|
||||
style={{
|
||||
width: "100%",
|
||||
padding: 12,
|
||||
backgroundColor: colors.bg,
|
||||
flexGrow: 1
|
||||
backgroundColor: colors.bg
|
||||
}}
|
||||
>
|
||||
{user ? (
|
||||
@@ -353,14 +323,9 @@ const Launcher = React.memo(
|
||||
<Button
|
||||
title="Unlock with Biometrics"
|
||||
width={250}
|
||||
height={45}
|
||||
style={{
|
||||
borderRadius: 100
|
||||
}}
|
||||
onPress={onUnlockBiometrics}
|
||||
icon={"fingerprint"}
|
||||
type={user ? "grayAccent" : "accent"}
|
||||
fontSize={SIZE.md}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
@@ -18,13 +18,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import { ScrollView } from "react-native";
|
||||
import { FeatureBlock } from "./feature";
|
||||
import { ScrollView } from "react-native-actions-sheet";
|
||||
|
||||
export const CompactFeatures = ({
|
||||
vertical,
|
||||
features = [],
|
||||
maxHeight = 500,
|
||||
maxHeight = 600,
|
||||
scrollRef
|
||||
}) => {
|
||||
let data = vertical
|
||||
@@ -80,14 +80,11 @@ export const CompactFeatures = ({
|
||||
return (
|
||||
<ScrollView
|
||||
horizontal={!vertical}
|
||||
nestedScrollEnabled
|
||||
onMomentumScrollEnd={() => {
|
||||
scrollRef?.current?.handleChildScrollEnd();
|
||||
}}
|
||||
showsHorizontalScrollIndicator={false}
|
||||
style={{
|
||||
width: "100%",
|
||||
maxHeight: maxHeight
|
||||
maxHeight: maxHeight,
|
||||
paddingHorizontal: 12
|
||||
}}
|
||||
>
|
||||
{data.map((item) => (
|
||||
|
||||
@@ -41,18 +41,19 @@ export const FeatureBlock = ({
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
paddingHorizontal: 12,
|
||||
marginBottom: 10
|
||||
marginBottom: 10,
|
||||
backgroundColor: colors.nav,
|
||||
borderRadius: 10,
|
||||
paddingVertical: 12
|
||||
}}
|
||||
>
|
||||
<Icon color={colors.accent} name="check" size={SIZE.lg} />
|
||||
|
||||
<Paragraph
|
||||
style={{
|
||||
flexWrap: "wrap",
|
||||
marginLeft: 5,
|
||||
flexShrink: 1
|
||||
}}
|
||||
size={SIZE.md}
|
||||
size={SIZE.sm}
|
||||
>
|
||||
{content}
|
||||
</Paragraph>
|
||||
|
||||
@@ -232,8 +232,7 @@ export const PricingPlans = ({
|
||||
width={250}
|
||||
style={{
|
||||
paddingHorizontal: 12,
|
||||
marginBottom: 15,
|
||||
borderRadius: 100
|
||||
marginBottom: 15
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
@@ -398,8 +397,7 @@ export const PricingPlans = ({
|
||||
style={{
|
||||
paddingHorizontal: 12,
|
||||
marginTop: 30,
|
||||
marginBottom: 10,
|
||||
borderRadius: 100
|
||||
marginBottom: 10
|
||||
}}
|
||||
/>
|
||||
{Platform.OS !== "ios" &&
|
||||
|
||||
@@ -196,12 +196,11 @@ const SheetProvider = ({ context = "global" }) => {
|
||||
accentColor={data.iconColor || "accent"}
|
||||
accentText="light"
|
||||
type="accent"
|
||||
height={45}
|
||||
height={40}
|
||||
width={250}
|
||||
style={{
|
||||
borderRadius: 100
|
||||
marginBottom: 25
|
||||
}}
|
||||
fontSize={SIZE.md}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
|
||||
@@ -309,7 +309,6 @@ export class AddNotebookSheet extends React.Component {
|
||||
borderRadius: 100,
|
||||
paddingHorizontal: 24
|
||||
}}
|
||||
fontSize={SIZE.md}
|
||||
onPress={this.addNewNotebook}
|
||||
/>
|
||||
</View>
|
||||
|
||||
@@ -243,7 +243,6 @@ export default function ReminderSheet({
|
||||
borderRadius: 100,
|
||||
paddingHorizontal: 24
|
||||
}}
|
||||
fontSize={SIZE.md}
|
||||
onPress={saveReminder}
|
||||
/>
|
||||
</View>
|
||||
|
||||
@@ -65,7 +65,6 @@ import { deleteItems } from "../../../utils/functions";
|
||||
import { presentDialog } from "../../dialog/functions";
|
||||
import { Properties } from "../../properties";
|
||||
import Sort from "../sort";
|
||||
import Heading from "../../ui/typography/heading";
|
||||
|
||||
type ConfigItem = { id: string; type: string };
|
||||
class TopicSheetConfig {
|
||||
|
||||
@@ -302,6 +302,7 @@ export const FluidTabs = forwardRef<TabsRef, TabProps>(function FluidTabs(
|
||||
translateX.value = value;
|
||||
})
|
||||
.onEnd((event) => {
|
||||
if (locked.value || forcedLock.value) return;
|
||||
if (currentTab.value === 2 && Platform.OS === "android") return;
|
||||
const velocityX =
|
||||
event.velocityX < 0 ? event.velocityX * -1 : event.velocityX;
|
||||
|
||||
@@ -119,7 +119,7 @@ const Input = ({
|
||||
? colors.red
|
||||
: focus
|
||||
? customColor || colors.accent
|
||||
: colors.nav;
|
||||
: colors.border;
|
||||
|
||||
const validate = async (value: string) => {
|
||||
if (!validationType) return;
|
||||
|
||||
@@ -105,6 +105,9 @@ const SheetWrapper = ({
|
||||
defaultOverlayOpacity={overlayOpacity}
|
||||
overlayColor={pitchBlack ? "#585858" : "#2b2b2b"}
|
||||
keyboardShouldPersistTaps="always"
|
||||
openAnimationConfig={{
|
||||
friction: 9
|
||||
}}
|
||||
ExtraOverlayComponent={
|
||||
<>
|
||||
{overlay}
|
||||
|
||||
@@ -18,7 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import React, { useMemo } from "react";
|
||||
import { Platform, Text, TextProps } from "react-native";
|
||||
import { Platform, Text, TextProps, ViewStyle } from "react-native";
|
||||
import Animated, {
|
||||
ComplexAnimationBuilder,
|
||||
Layout
|
||||
@@ -30,15 +30,26 @@ interface HeadingProps extends TextProps {
|
||||
size?: number;
|
||||
layout?: ComplexAnimationBuilder;
|
||||
animated?: boolean;
|
||||
extraBold?: boolean;
|
||||
}
|
||||
|
||||
const AnimatedText = Animated.createAnimatedComponent(Text);
|
||||
|
||||
const extraBoldStyle = {
|
||||
fontFamily: Platform.OS === "android" ? "OpenSans-Bold" : undefined,
|
||||
fontWeight: Platform.OS === "ios" ? "800" : undefined
|
||||
};
|
||||
const boldStyle = {
|
||||
fontFamily: Platform.OS === "android" ? "OpenSans-SemiBold" : undefined,
|
||||
fontWeight: Platform.OS === "ios" ? "600" : undefined
|
||||
};
|
||||
|
||||
const Heading = ({
|
||||
color,
|
||||
size = SIZE.xl,
|
||||
style,
|
||||
animated,
|
||||
extraBold,
|
||||
...restProps
|
||||
}: HeadingProps) => {
|
||||
const colors = useThemeStore((state) => state.colors);
|
||||
@@ -53,11 +64,9 @@ const Heading = ({
|
||||
style={[
|
||||
{
|
||||
fontSize: size || SIZE.xl,
|
||||
color: color || colors.heading,
|
||||
fontFamily:
|
||||
Platform.OS === "android" ? "OpenSans-SemiBold" : undefined,
|
||||
fontWeight: Platform.OS === "ios" ? "600" : undefined
|
||||
color: color || colors.heading
|
||||
},
|
||||
extraBold ? (extraBoldStyle as ViewStyle) : (boldStyle as ViewStyle),
|
||||
style
|
||||
]}
|
||||
></Component>
|
||||
|
||||
@@ -50,6 +50,7 @@ import { useSettingStore } from "../stores/use-setting-store";
|
||||
import { useThemeStore } from "../stores/use-theme-store";
|
||||
import { history } from "../utils";
|
||||
import { rootNavigatorRef } from "../utils/global-refs";
|
||||
import Auth from "../components/auth";
|
||||
const NativeStack = createNativeStackNavigator();
|
||||
const IntroStack = createNativeStackNavigator();
|
||||
|
||||
@@ -64,6 +65,7 @@ const IntroStack = createNativeStackNavigator();
|
||||
|
||||
const IntroStackNavigator = () => {
|
||||
const colors = useThemeStore((state) => state.colors);
|
||||
const height = useSettingStore((state) => state.dimensions.height);
|
||||
return (
|
||||
<IntroStack.Navigator
|
||||
screenOptions={{
|
||||
@@ -71,12 +73,14 @@ const IntroStackNavigator = () => {
|
||||
lazy: false,
|
||||
animation: "none",
|
||||
contentStyle: {
|
||||
backgroundColor: colors.bg
|
||||
backgroundColor: colors.bg,
|
||||
minHeight: height
|
||||
}
|
||||
}}
|
||||
initialRouteName={"Intro"}
|
||||
>
|
||||
<NativeStack.Screen name="Intro" component={Intro} />
|
||||
<NativeStack.Screen name="Auth" component={Auth} />
|
||||
<NativeStack.Screen name="AppLock" component={AppLock} />
|
||||
</IntroStack.Navigator>
|
||||
);
|
||||
@@ -120,7 +124,7 @@ const _Tabs = () => {
|
||||
animation: "none",
|
||||
contentStyle: {
|
||||
backgroundColor: colors.bg,
|
||||
height: !introCompleted ? undefined : screenHeight
|
||||
minHeight: !introCompleted ? undefined : screenHeight
|
||||
}
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -271,13 +271,13 @@ const _TabsHolder = () => {
|
||||
setTimeout(() => {
|
||||
switch (current) {
|
||||
case "tablet":
|
||||
introCompleted && tabBarRef.current?.goToIndex(0, false);
|
||||
tabBarRef.current?.goToIndex(0, false);
|
||||
break;
|
||||
case "smallTablet":
|
||||
if (!fullscreen) {
|
||||
introCompleted && tabBarRef.current?.closeDrawer(false);
|
||||
tabBarRef.current?.closeDrawer(false);
|
||||
} else {
|
||||
introCompleted && tabBarRef.current?.openDrawer(false);
|
||||
tabBarRef.current?.openDrawer(false);
|
||||
}
|
||||
break;
|
||||
case "mobile":
|
||||
@@ -416,64 +416,66 @@ const _TabsHolder = () => {
|
||||
backgroundColor="transparent"
|
||||
/>
|
||||
|
||||
{deviceMode && widths[deviceMode] ? (
|
||||
<FluidTabs
|
||||
ref={tabBarRef}
|
||||
dimensions={dimensions}
|
||||
widths={!introCompleted ? widths["mobile"] : widths[deviceMode]}
|
||||
enabled={deviceMode !== "tablet" && !fullscreen}
|
||||
onScroll={onScroll}
|
||||
onChangeTab={onChangeTab}
|
||||
onDrawerStateChange={() => true}
|
||||
>
|
||||
<View
|
||||
key="1"
|
||||
style={{
|
||||
height: "100%",
|
||||
width: fullscreen
|
||||
? 0
|
||||
: widths[!introCompleted ? "mobile" : deviceMode]?.a
|
||||
}}
|
||||
>
|
||||
<SideMenu />
|
||||
</View>
|
||||
|
||||
<View
|
||||
key="2"
|
||||
style={{
|
||||
height: "100%",
|
||||
width: fullscreen
|
||||
? 0
|
||||
: widths[!introCompleted ? "mobile" : deviceMode]?.b
|
||||
}}
|
||||
>
|
||||
{deviceMode === "mobile" ? (
|
||||
<Animated.View
|
||||
onTouchEnd={() => {
|
||||
tabBarRef.current?.closeDrawer();
|
||||
animatedOpacity.value = withTiming(0);
|
||||
animatedTranslateY.value = withTiming(-9999);
|
||||
{!introCompleted ? (
|
||||
<NavigationStack />
|
||||
) : (
|
||||
<>
|
||||
{deviceMode && widths[deviceMode] ? (
|
||||
<FluidTabs
|
||||
ref={tabBarRef}
|
||||
dimensions={dimensions}
|
||||
widths={widths[deviceMode]}
|
||||
enabled={deviceMode !== "tablet" && !fullscreen}
|
||||
onScroll={onScroll}
|
||||
onChangeTab={onChangeTab}
|
||||
onDrawerStateChange={() => true}
|
||||
>
|
||||
<View
|
||||
key="1"
|
||||
style={{
|
||||
height: "100%",
|
||||
width: fullscreen ? 0 : widths[deviceMode]?.a
|
||||
}}
|
||||
style={[
|
||||
{
|
||||
position: "absolute",
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
zIndex: 999,
|
||||
backgroundColor: "rgba(0,0,0,0.2)"
|
||||
},
|
||||
animatedStyle
|
||||
]}
|
||||
ref={overlayRef}
|
||||
/>
|
||||
) : null}
|
||||
>
|
||||
<SideMenu />
|
||||
</View>
|
||||
|
||||
<NavigationStack />
|
||||
</View>
|
||||
<View
|
||||
key="2"
|
||||
style={{
|
||||
height: "100%",
|
||||
width: fullscreen ? 0 : widths[deviceMode]?.b
|
||||
}}
|
||||
>
|
||||
{deviceMode === "mobile" ? (
|
||||
<Animated.View
|
||||
onTouchEnd={() => {
|
||||
tabBarRef.current?.closeDrawer();
|
||||
animatedOpacity.value = withTiming(0);
|
||||
animatedTranslateY.value = withTiming(-9999);
|
||||
}}
|
||||
style={[
|
||||
{
|
||||
position: "absolute",
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
zIndex: 999,
|
||||
backgroundColor: "rgba(0,0,0,0.2)"
|
||||
},
|
||||
animatedStyle
|
||||
]}
|
||||
ref={overlayRef}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
<EditorWrapper key="3" width={widths} dimensions={dimensions} />
|
||||
</FluidTabs>
|
||||
) : null}
|
||||
<NavigationStack />
|
||||
</View>
|
||||
|
||||
<EditorWrapper key="3" width={widths} dimensions={dimensions} />
|
||||
</FluidTabs>
|
||||
) : null}
|
||||
</>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -28,7 +28,8 @@
|
||||
"zustand": "^3.6.0",
|
||||
"fflate": "^0.7.3",
|
||||
"timeago.js": "4.0.2",
|
||||
"react-native-blob-util": "0.17.3"
|
||||
"react-native-blob-util": "0.17.3",
|
||||
"react-native-swiper-flatlist": "3.2.2"
|
||||
},
|
||||
"sideEffects": false
|
||||
}
|
||||
|
||||
@@ -17,34 +17,36 @@ 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, { useState } from "react";
|
||||
import { Dimensions, LayoutAnimation, Platform, View } from "react-native";
|
||||
import React from "react";
|
||||
import { Platform, View } from "react-native";
|
||||
import Animated, { FadeInDown, FadeOutUp } from "react-native-reanimated";
|
||||
import Icon from "react-native-vector-icons/MaterialCommunityIcons";
|
||||
import { SVG_Z } from "../../components/intro";
|
||||
import { WelcomeNotice } from "../../components/intro/welcome";
|
||||
import { AuthMode } from "../../components/auth";
|
||||
import { Button } from "../../components/ui/button";
|
||||
import { PressableButton } from "../../components/ui/pressable";
|
||||
import Seperator from "../../components/ui/seperator";
|
||||
import { SvgView } from "../../components/ui/svg";
|
||||
import { BouncingView } from "../../components/ui/transitions/bouncing-view";
|
||||
import Heading from "../../components/ui/typography/heading";
|
||||
import Paragraph from "../../components/ui/typography/paragraph";
|
||||
import BiometicService from "../../services/biometrics";
|
||||
import { DDS } from "../../services/device-detection";
|
||||
import { presentSheet, ToastEvent } from "../../services/event-manager";
|
||||
import {
|
||||
ToastEvent,
|
||||
eSendEvent,
|
||||
presentSheet
|
||||
} from "../../services/event-manager";
|
||||
import Navigation from "../../services/navigation";
|
||||
import SettingsService from "../../services/settings";
|
||||
import { useSettingStore } from "../../stores/use-setting-store";
|
||||
import { useThemeStore } from "../../stores/use-theme-store";
|
||||
import { useUserStore } from "../../stores/use-user-store";
|
||||
import { getElevation } from "../../utils";
|
||||
import { eOpenLoginDialog } from "../../utils/events";
|
||||
import { SIZE } from "../../utils/size";
|
||||
import { requestInAppReview } from "../../services/app-review";
|
||||
const AppLock = ({ route }) => {
|
||||
const colors = useThemeStore((state) => state.colors);
|
||||
const appLockMode = useSettingStore((state) => state.settings.appLockMode);
|
||||
const [step, setStep] = useState(0);
|
||||
const welcome = route?.params?.welcome;
|
||||
const deviceMode = useSettingStore((state) => state.deviceMode);
|
||||
|
||||
const modes = [
|
||||
{
|
||||
@@ -77,13 +79,12 @@ const AppLock = ({ route }) => {
|
||||
exiting={!welcome ? undefined : FadeOutUp}
|
||||
entering={!welcome ? undefined : FadeInDown}
|
||||
style={{
|
||||
justifyContent: !welcome ? undefined : "center",
|
||||
height: !welcome ? undefined : "100%",
|
||||
width: !welcome ? undefined : "100%"
|
||||
}}
|
||||
>
|
||||
{step === 0 ? (
|
||||
<>
|
||||
<>
|
||||
{!welcome ? (
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
@@ -126,124 +127,164 @@ const AppLock = ({ route }) => {
|
||||
</Paragraph>
|
||||
</View>
|
||||
</View>
|
||||
<Seperator />
|
||||
) : (
|
||||
<View
|
||||
style={{
|
||||
paddingHorizontal: 12,
|
||||
width: DDS.isTab && welcome ? "50%" : "100%",
|
||||
alignSelf: "center"
|
||||
flex: 0.35,
|
||||
justifyContent: "flex-end",
|
||||
paddingHorizontal: 20,
|
||||
backgroundColor: colors.nav,
|
||||
marginBottom: 20,
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: colors.border,
|
||||
alignSelf: deviceMode !== "mobile" ? "center" : undefined,
|
||||
borderWidth: deviceMode !== "mobile" ? 1 : null,
|
||||
borderColor: deviceMode !== "mobile" ? colors.border : null,
|
||||
borderRadius: deviceMode !== "mobile" ? 20 : null,
|
||||
marginTop: deviceMode !== "mobile" ? 50 : null,
|
||||
width: deviceMode === "mobile" ? null : "50%"
|
||||
}}
|
||||
>
|
||||
{modes.map((item) => (
|
||||
<PressableButton
|
||||
key={item.title}
|
||||
type={appLockMode === item.value ? "grayBg" : "transparent"}
|
||||
onPress={async () => {
|
||||
if (
|
||||
!(await BiometicService.isBiometryAvailable()) &&
|
||||
!useUserStore.getState().user
|
||||
) {
|
||||
ToastEvent.show({
|
||||
heading: "Biometrics not enrolled",
|
||||
type: "error",
|
||||
message:
|
||||
"To use app lock, you must enable biometrics such as Fingerprint lock or Face ID on your phone or create an account."
|
||||
});
|
||||
return;
|
||||
}
|
||||
SettingsService.set({ appLockMode: item.value });
|
||||
if (!welcome) {
|
||||
requestInAppReview();
|
||||
}
|
||||
}}
|
||||
customStyle={{
|
||||
justifyContent: "flex-start",
|
||||
alignItems: "flex-start",
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 12,
|
||||
marginTop: 0,
|
||||
marginBottom: 12,
|
||||
borderWidth: 1,
|
||||
borderColor:
|
||||
appLockMode === item.value ? item.activeColor : colors.nav
|
||||
}}
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row"
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
marginBottom: 10
|
||||
width: 100,
|
||||
height: 5,
|
||||
backgroundColor: colors.accent,
|
||||
borderRadius: 2,
|
||||
marginRight: 7
|
||||
}}
|
||||
>
|
||||
<Heading
|
||||
color={
|
||||
appLockMode === item.value ? item.activeColor : colors.pri
|
||||
}
|
||||
style={{ maxWidth: "95%" }}
|
||||
size={SIZE.md}
|
||||
>
|
||||
{item.title}
|
||||
</Heading>
|
||||
<Paragraph
|
||||
color={
|
||||
appLockMode === item.value
|
||||
? item.activeColor
|
||||
: colors.icon
|
||||
}
|
||||
style={{ maxWidth: "95%" }}
|
||||
size={SIZE.sm}
|
||||
>
|
||||
{item.desc}
|
||||
</Paragraph>
|
||||
</PressableButton>
|
||||
))}
|
||||
|
||||
{welcome && (
|
||||
<Button
|
||||
fontSize={SIZE.md}
|
||||
height={45}
|
||||
width={250}
|
||||
onPress={async () => {
|
||||
LayoutAnimation.configureNext({
|
||||
...LayoutAnimation.Presets.linear,
|
||||
delete: {
|
||||
duration: 50,
|
||||
property: "opacity",
|
||||
type: "linear"
|
||||
}
|
||||
});
|
||||
setStep(1);
|
||||
}}
|
||||
style={{
|
||||
paddingHorizontal: 24,
|
||||
alignSelf: "center",
|
||||
borderRadius: 100,
|
||||
...getElevation(5),
|
||||
marginTop: 30
|
||||
}}
|
||||
type="accent"
|
||||
title="Next"
|
||||
/>
|
||||
)}
|
||||
</View>
|
||||
</>
|
||||
) : (
|
||||
<WelcomeNotice />
|
||||
)}
|
||||
|
||||
{welcome && !colors.night ? (
|
||||
<BouncingView
|
||||
<View
|
||||
style={{
|
||||
width: 20,
|
||||
height: 5,
|
||||
backgroundColor: colors.nav,
|
||||
borderRadius: 2
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
<Heading
|
||||
style={{
|
||||
marginTop: 10
|
||||
}}
|
||||
extraBold
|
||||
size={SIZE.xxl}
|
||||
>
|
||||
Protect your notes
|
||||
</Heading>
|
||||
<Paragraph
|
||||
style={{
|
||||
marginBottom: 25
|
||||
}}
|
||||
>
|
||||
Choose how you want to secure your notes locally.
|
||||
</Paragraph>
|
||||
</View>
|
||||
)}
|
||||
|
||||
<Seperator />
|
||||
<View
|
||||
style={{
|
||||
position: "absolute",
|
||||
bottom: DDS.isTab ? -300 : -130,
|
||||
zIndex: -1
|
||||
paddingHorizontal: 12,
|
||||
width: DDS.isTab && welcome ? "50%" : "100%",
|
||||
alignSelf: "center",
|
||||
flex: 0.65
|
||||
}}
|
||||
animated={false}
|
||||
duration={3000}
|
||||
>
|
||||
<SvgView
|
||||
width={Dimensions.get("window").width}
|
||||
height={Dimensions.get("window").width}
|
||||
src={SVG_Z}
|
||||
/>
|
||||
</BouncingView>
|
||||
) : null}
|
||||
{modes.map((item) => (
|
||||
<PressableButton
|
||||
key={item.title}
|
||||
type={appLockMode === item.value ? "grayBg" : "transparent"}
|
||||
onPress={async () => {
|
||||
if (
|
||||
!(await BiometicService.isBiometryAvailable()) &&
|
||||
!useUserStore.getState().user
|
||||
) {
|
||||
ToastEvent.show({
|
||||
heading: "Biometrics not enrolled",
|
||||
type: "error",
|
||||
message:
|
||||
"To use app lock, you must enable biometrics such as Fingerprint lock or Face ID on your phone or create an account."
|
||||
});
|
||||
return;
|
||||
}
|
||||
SettingsService.set({ appLockMode: item.value });
|
||||
}}
|
||||
customStyle={{
|
||||
justifyContent: "flex-start",
|
||||
alignItems: "flex-start",
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 12,
|
||||
marginTop: 0,
|
||||
marginBottom: 12,
|
||||
borderWidth: 1,
|
||||
borderColor:
|
||||
appLockMode === item.value ? item.activeColor : colors.nav
|
||||
}}
|
||||
style={{
|
||||
marginBottom: 10
|
||||
}}
|
||||
>
|
||||
<Heading
|
||||
color={
|
||||
appLockMode === item.value ? item.activeColor : colors.pri
|
||||
}
|
||||
style={{ maxWidth: "95%" }}
|
||||
size={SIZE.md}
|
||||
>
|
||||
{item.title}
|
||||
</Heading>
|
||||
<Paragraph
|
||||
color={
|
||||
appLockMode === item.value ? item.activeColor : colors.icon
|
||||
}
|
||||
style={{ maxWidth: "95%" }}
|
||||
size={SIZE.sm}
|
||||
>
|
||||
{item.desc}
|
||||
</Paragraph>
|
||||
</PressableButton>
|
||||
))}
|
||||
|
||||
{welcome && (
|
||||
<Button
|
||||
fontSize={SIZE.md}
|
||||
width={250}
|
||||
onPress={async () => {
|
||||
eSendEvent(eOpenLoginDialog, AuthMode.welcomeSignup);
|
||||
setTimeout(() => {
|
||||
SettingsService.set({
|
||||
introCompleted: true
|
||||
});
|
||||
Navigation.replace(
|
||||
{
|
||||
name: "Notes"
|
||||
},
|
||||
{
|
||||
canGoBack: false
|
||||
}
|
||||
);
|
||||
}, 1000);
|
||||
}}
|
||||
style={{
|
||||
paddingHorizontal: 24,
|
||||
alignSelf: "center",
|
||||
...getElevation(5),
|
||||
marginTop: 30,
|
||||
borderRadius: 100
|
||||
}}
|
||||
type="accent"
|
||||
title="Next"
|
||||
/>
|
||||
)}
|
||||
</View>
|
||||
</>
|
||||
</Animated.View>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -179,7 +179,6 @@ const onUserStatusCheck = async (type) => {
|
||||
const showVerifyEmailDialog = () => {
|
||||
presentSheet({
|
||||
title: "Confirm your email",
|
||||
icon: "email",
|
||||
paragraph:
|
||||
"We have sent you an email confirmation link. Please check your email inbox. If you cannot find the email, check your spam folder.",
|
||||
action: async () => {
|
||||
@@ -369,7 +368,7 @@ const features_list = [
|
||||
"Rich note editing experience with markdown, tables, checklists and more"
|
||||
},
|
||||
{
|
||||
content: "Export your notes in Pdf, markdown and html formats"
|
||||
content: "Export your notes in PDF, markdown and html formats"
|
||||
}
|
||||
];
|
||||
|
||||
@@ -388,7 +387,7 @@ const sheet = (context, promo, trial) => {
|
||||
<Seperator />
|
||||
<CompactFeatures
|
||||
scrollRef={ref}
|
||||
maxHeight={300}
|
||||
maxHeight={400}
|
||||
features={features_list}
|
||||
vertical
|
||||
/>
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
</dict>
|
||||
<key>UIAppFonts</key>
|
||||
<array>
|
||||
<string>OpenSans-Bold.ttf</string>
|
||||
<string>OpenSans-SemiBold.ttf</string>
|
||||
<string>OpenSans-Regular.ttf</string>
|
||||
<string>MaterialCommunityIcons.ttf</string>
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
6515C42F2580AA3000E83E39 /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6515C42E2580AA2F00E83E39 /* StoreKit.framework */; };
|
||||
6529A13E279BC4C70048D4A8 /* BootSplash.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6529A13D279BC4C70048D4A8 /* BootSplash.storyboard */; };
|
||||
6593E4A3281C345400492C50 /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6593E4A2281C345400492C50 /* AppDelegate.mm */; };
|
||||
659670B22A2754FD00C5D2AF /* OpenSans-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 659670B12A2754FD00C5D2AF /* OpenSans-Bold.ttf */; };
|
||||
659670B32A2754FD00C5D2AF /* OpenSans-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 659670B12A2754FD00C5D2AF /* OpenSans-Bold.ttf */; };
|
||||
659BE46725E11A5100E05671 /* notesnook-text.png in Resources */ = {isa = PBXBuildFile; fileRef = 659BE46625E11A5100E05671 /* notesnook-text.png */; };
|
||||
65AA857925E6DDEC00772A01 /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 65AA857825E6DDEC00772A01 /* WidgetKit.framework */; };
|
||||
65AA857B25E6DDEC00772A01 /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 65AA857A25E6DDEC00772A01 /* SwiftUI.framework */; };
|
||||
@@ -116,6 +118,7 @@
|
||||
6552012E27019F6E00A43C51 /* OpenSans-SemiBold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "OpenSans-SemiBold.ttf"; path = "../android/app/src/main/assets/fonts/OpenSans-SemiBold.ttf"; sourceTree = "<group>"; };
|
||||
6552012F27019F7700A43C51 /* OpenSans-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "OpenSans-Regular.ttf"; path = "../android/app/src/main/assets/fonts/OpenSans-Regular.ttf"; sourceTree = "<group>"; };
|
||||
6593E4A2281C345400492C50 /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = Notesnook/AppDelegate.mm; sourceTree = "<group>"; };
|
||||
659670B12A2754FD00C5D2AF /* OpenSans-Bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "OpenSans-Bold.ttf"; path = "../android/app/src/main/assets/fonts/OpenSans-Bold.ttf"; 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; };
|
||||
@@ -294,6 +297,7 @@
|
||||
6510E6D62877215700DACAA9 /* build.bundle */,
|
||||
65EC5B71272A7EE200FB3748 /* NotesWidgetExtensionDebug.entitlements */,
|
||||
6552012F27019F7700A43C51 /* OpenSans-Regular.ttf */,
|
||||
659670B12A2754FD00C5D2AF /* OpenSans-Bold.ttf */,
|
||||
6552012E27019F6E00A43C51 /* OpenSans-SemiBold.ttf */,
|
||||
65D145C429DC30470056FE7D /* MaterialCommunityIcons.ttf */,
|
||||
13B07FAE1A68108700A75B9A /* Notesnook */,
|
||||
@@ -538,6 +542,7 @@
|
||||
files = (
|
||||
6510626F27042891009661C3 /* OpenSans-Regular.ttf in Resources */,
|
||||
65D145C529DC30470056FE7D /* MaterialCommunityIcons.ttf in Resources */,
|
||||
659670B22A2754FD00C5D2AF /* OpenSans-Bold.ttf in Resources */,
|
||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
|
||||
6529A13E279BC4C70048D4A8 /* BootSplash.storyboard in Resources */,
|
||||
6510E6D72877215700DACAA9 /* build.bundle in Resources */,
|
||||
@@ -575,6 +580,7 @@
|
||||
files = (
|
||||
6510E6D82877215700DACAA9 /* build.bundle in Resources */,
|
||||
65D145C629DC30470056FE7D /* MaterialCommunityIcons.ttf in Resources */,
|
||||
659670B32A2754FD00C5D2AF /* OpenSans-Bold.ttf in Resources */,
|
||||
6510627727042896009661C3 /* OpenSans-SemiBold.ttf in Resources */,
|
||||
6510627527042893009661C3 /* OpenSans-Regular.ttf in Resources */,
|
||||
65B5014725A672B200E2D264 /* MainInterface.storyboard in Resources */,
|
||||
|
||||
@@ -58,11 +58,11 @@
|
||||
"@bam.tech/react-native-image-resizer": "3.0.5",
|
||||
"react-native-navigation-bar-color": "2.0.2",
|
||||
"react-native-actions-shortcuts": "^1.0.1",
|
||||
"react-native-in-app-review": "4.3.3",
|
||||
"react-native-zip-archive": "6.0.9",
|
||||
"react-native-vector-icons": "9.2.0",
|
||||
"react-native-pdf": "6.6.2",
|
||||
"react-native-blob-util": "0.17.3"
|
||||
"react-native-blob-util": "0.17.3",
|
||||
"react-native-in-app-review": "4.3.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.12.9",
|
||||
|
||||
12
apps/mobile/package-lock.json
generated
12
apps/mobile/package-lock.json
generated
@@ -14,7 +14,8 @@
|
||||
],
|
||||
"dependencies": {
|
||||
"react": "18.0.0",
|
||||
"react-native": "0.69.7"
|
||||
"react-native": "0.69.7",
|
||||
"react-native-swiper-flatlist": "3.2.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"otplib": "12.0.1",
|
||||
@@ -48,6 +49,7 @@
|
||||
"react-native-qrcode-svg": "^6.0.6",
|
||||
"react-native-reanimated-material-menu": "github:ammarahm-ed/react-native-reanimated-material-menu",
|
||||
"react-native-reanimated-progress-bar": "1.0.1",
|
||||
"react-native-swiper-flatlist": "3.2.2",
|
||||
"timeago.js": "4.0.2",
|
||||
"toggle-switch-react-native": "3.2.0",
|
||||
"url": "^0.11.0",
|
||||
@@ -18167,6 +18169,14 @@
|
||||
"react-native": ">=0.50.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-swiper-flatlist": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/react-native-swiper-flatlist/-/react-native-swiper-flatlist-3.2.2.tgz",
|
||||
"integrity": "sha512-VVtxJCb2QHGA3ZpLiFqEHv6wyTlnlov5kL0dPKCb9Kc/W1wx8x2ZRFJU2Xja60CKbXDr5zwpxRayBm3bLgFEPg==",
|
||||
"peerDependencies": {
|
||||
"react-native": ">=0.59.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-tooltips": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/react-native-tooltips/-/react-native-tooltips-1.0.3.tgz",
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
"@notesnook/core": "*",
|
||||
"@notesnook/editor": "*",
|
||||
"@notesnook/editor-mobile": "*",
|
||||
"react-native-swiper-flatlist": "3.2.2",
|
||||
"@notesnook/logger": "*"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user