/* 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 . */ import { formatBytes } from "@notesnook/common"; import { SubscriptionPlan, SubscriptionProvider } from "@notesnook/core"; import { strings } from "@notesnook/intl"; import { useThemeColors } from "@notesnook/theme"; import { useNetInfo } from "@react-native-community/netinfo"; import dayjs from "dayjs"; import React from "react"; import { Image, Platform, TouchableOpacity, View } from "react-native"; import ImagePicker from "react-native-image-crop-picker"; import Icon from "react-native-vector-icons/MaterialCommunityIcons"; import { db } from "../../common/database"; import { presentDialog } from "../../components/dialog/functions"; import { createFormRef, validators } from "../../components/ui/input/form-input"; import { PlanLimits } from "../../components/sheets/plan-limits"; import AppIcon from "../../components/ui/AppIcon"; import { Button } from "../../components/ui/button"; import { TimeSince } from "../../components/ui/time-since"; import Paragraph from "../../components/ui/typography/paragraph"; import { presentSheet, ToastManager } from "../../services/event-manager"; import Navigation from "../../services/navigation"; import PremiumService from "../../services/premium"; import { useThemeStore } from "../../stores/use-theme-store"; import { SyncStatus, useUserStore } from "../../stores/use-user-store"; import { planToDisplayName } from "../../utils/constants"; import { AppFontSize } from "../../utils/size"; import { DefaultAppStyles } from "../../utils/styles"; import { SectionItem } from "./section-item"; import SettingsService from "../../services/settings"; export const getTimeLeft = (t2) => { let daysRemaining = dayjs(t2).diff(dayjs(), "days"); return { time: dayjs(t2).diff(dayjs(), daysRemaining === 0 ? "hours" : "days"), isHour: daysRemaining === 0 }; }; const ProfilePicPlaceholder = (props) => { const { colors } = useThemeColors(); return ( ); }; const onChangePicture = () => { useUserStore.setState({ disableAppLockRequests: true }); const theme = useThemeStore.getState().colorScheme === "dark" ? useThemeStore.getState().darkTheme : useThemeStore.getState().lightTheme; ImagePicker.openPicker({ compressImageMaxWidth: 256, compressImageMaxHeight: 256, compressImageQuality: 0.8, avoidEmptySpaceAroundImage: true, cropping: true, cropperCircleOverlay: true, mediaType: "photo", forceJpg: true, includeBase64: true, writeTempFile: false, cropperToolbarColor: theme.scopes.base.primary.background, cropperToolbarTitle: strings.editProfilePicture(), cropperActiveWidgetColor: theme.scopes.base.primary.accent, cropperToolbarWidgetColor: theme.scopes.base.primary.icon }) .then(async (image) => { if (!image.data) return; await db.settings.setProfile({ profilePicture: "data:image/jpeg;base64," + image.data }); useUserStore.setState({ profile: db.settings.getProfile() }); }) .finally(() => { setTimeout(() => { useUserStore.setState({ disableAppLockRequests: false }); }, 1000); }); }; const SettingsUserSection = ({ item }) => { const { colors } = useThemeColors(); const [user] = useUserStore((state) => [state.user]); const lastSynced = useUserStore((state) => state.lastSynced); const lastSyncStatus = useUserStore((state) => state.lastSyncStatus); const { isInternetReachable } = useNetInfo(); const isOffline = !isInternetReachable; const userProfile = useUserStore((state) => state.profile); const used = user?.storageUsed || 0; const total = user?.totalStorage || 0; const isCurrentPlatform = (user?.subscription?.provider === SubscriptionProvider.APPLE && Platform.OS === "ios") || (user?.subscription?.provider === SubscriptionProvider.GOOGLE && Platform.OS === "android"); return ( <> {user ? ( <> {userProfile?.profilePicture ? ( ) : ( )} { presentDialog({ title: strings.setFullName(), paragraph: strings.setFullNameDesc(), positiveText: strings.save(), form: { formRef: createFormRef({ fullName: userProfile?.fullName || "" }), items: [ { name: "fullName", placeholder: strings.enterFullName(), defaultValue: userProfile?.fullName, validators: [ validators.required(strings.nameIsRequired()) ] } ], onFormSubmit: async (form) => { try { await db.settings.setProfile({ fullName: form.getValue("fullName") }); useUserStore.setState({ profile: db.settings.getProfile() }); return true; } catch (e) { form.setError("fullName", e.message); return false; } } } }); }} color={colors.primary.heading} size={AppFontSize.md} > {userProfile?.fullName ? userProfile.fullName + " " : strings.setYourName() + " "} {user?.email} {!user ? ( strings.notLoggedIn() ) : lastSynced && lastSynced !== "Never" ? ( <> {lastSyncStatus === SyncStatus.Failed ? strings.syncFailed() : strings.synced()}{" "} {" "} ago {isOffline ? ` (${strings.offline()})` : ""} ) : ( strings.never() )} {strings.storage()} {formatBytes(used)}/ {total === -1 ? "Unlimited" : formatBytes(total) + " " + strings.used()} { presentSheet({ component: }); }} > {planToDisplayName(user.subscription?.plan)} {strings.viewAllLimits()}{" "} {((user.subscription?.provider === SubscriptionProvider.PADDLE || user.subscription?.provider === SubscriptionProvider.STREETWRITERS || !isCurrentPlatform) && PremiumService.get()) || SettingsService.getProperty("serverUrls") ? null : (