diff --git a/.eslintignore b/.eslintignore index 8c6df956fb..35d4c20993 100644 --- a/.eslintignore +++ b/.eslintignore @@ -725,6 +725,8 @@ packages/app-mobile/components/SearchInput.js packages/app-mobile/components/SelectDateTimeDialog.js packages/app-mobile/components/SideMenu.js packages/app-mobile/components/SideMenuContentNote.js +packages/app-mobile/components/SyncWizard/JoplinCloudIcon.js +packages/app-mobile/components/SyncWizard/SyncWizard.js packages/app-mobile/components/TagEditor.test.js packages/app-mobile/components/TagEditor.js packages/app-mobile/components/TextInput.js @@ -741,6 +743,7 @@ packages/app-mobile/components/base-screen.js packages/app-mobile/components/biometrics/BiometricPopup.js packages/app-mobile/components/biometrics/biometricAuthenticate.js packages/app-mobile/components/biometrics/sensorInfo.js +packages/app-mobile/components/buttons/CardButton.js packages/app-mobile/components/buttons/FloatingActionButton.js packages/app-mobile/components/buttons/LabelledIconButton.js packages/app-mobile/components/buttons/MultiTouchableOpacity.js diff --git a/.gitignore b/.gitignore index b5e041cc54..9530c46304 100644 --- a/.gitignore +++ b/.gitignore @@ -698,6 +698,8 @@ packages/app-mobile/components/SearchInput.js packages/app-mobile/components/SelectDateTimeDialog.js packages/app-mobile/components/SideMenu.js packages/app-mobile/components/SideMenuContentNote.js +packages/app-mobile/components/SyncWizard/JoplinCloudIcon.js +packages/app-mobile/components/SyncWizard/SyncWizard.js packages/app-mobile/components/TagEditor.test.js packages/app-mobile/components/TagEditor.js packages/app-mobile/components/TextInput.js @@ -714,6 +716,7 @@ packages/app-mobile/components/base-screen.js packages/app-mobile/components/biometrics/BiometricPopup.js packages/app-mobile/components/biometrics/biometricAuthenticate.js packages/app-mobile/components/biometrics/sensorInfo.js +packages/app-mobile/components/buttons/CardButton.js packages/app-mobile/components/buttons/FloatingActionButton.js packages/app-mobile/components/buttons/LabelledIconButton.js packages/app-mobile/components/buttons/MultiTouchableOpacity.js diff --git a/packages/app-mobile/components/CameraView/ScannedBarcodes.tsx b/packages/app-mobile/components/CameraView/ScannedBarcodes.tsx index c4f851140b..ea30906c95 100644 --- a/packages/app-mobile/components/CameraView/ScannedBarcodes.tsx +++ b/packages/app-mobile/components/CameraView/ScannedBarcodes.tsx @@ -4,7 +4,7 @@ import { Platform, ScrollView, StyleSheet, View } from 'react-native'; import { BarcodeScanner } from './utils/useBarcodeScanner'; import { LinkButton, PrimaryButton } from '../buttons'; import { _ } from '@joplin/lib/locale'; -import DismissibleDialog, { DialogSize } from '../DismissibleDialog'; +import DismissibleDialog, { DialogVariant } from '../DismissibleDialog'; import { Chip, Text } from 'react-native-paper'; import { isCallbackUrl, parseCallbackUrl } from '@joplin/lib/callbackUrlUtils'; import CommandService from '@joplin/lib/services/CommandService'; @@ -84,7 +84,7 @@ const ScannedBarcodes: React.FC = props => { visible={dialogVisible} onDismiss={onHideDialog} themeId={props.themeId} - size={DialogSize.Small} + size={DialogVariant.Small} > {_('Scanned code')} diff --git a/packages/app-mobile/components/DismissibleDialog.tsx b/packages/app-mobile/components/DismissibleDialog.tsx index 618f9a8083..300741ba06 100644 --- a/packages/app-mobile/components/DismissibleDialog.tsx +++ b/packages/app-mobile/components/DismissibleDialog.tsx @@ -6,7 +6,10 @@ import { themeStyle } from './global-style'; import Modal from './Modal'; import { _ } from '@joplin/lib/locale'; -export enum DialogSize { +export enum DialogVariant { + // Small width, auto-determined height + SmallResize = 'small-resize', + Small = 'small', // Ideal for panels and dialogs that should be fullscreen even on large devices @@ -20,34 +23,58 @@ interface Props { containerStyle?: ViewStyle; children: React.ReactNode; heading?: string; + scrollOverflow?: boolean; - size: DialogSize; + size: DialogVariant; } -const useStyles = (themeId: number, containerStyle: ViewStyle, size: DialogSize) => { +const useStyles = (themeId: number, containerStyle: ViewStyle, size: DialogVariant) => { const windowSize = useWindowDimensions(); return useMemo(() => { const theme = themeStyle(themeId); - const maxWidth = size === DialogSize.Large ? windowSize.width : 500; - const maxHeight = size === DialogSize.Large ? windowSize.height : 700; + const maxWidth = size === DialogVariant.Large ? windowSize.width : 500; + const maxHeight = size === DialogVariant.Large ? windowSize.height : 700; + + const dialogSizing: ViewStyle = { + width: '100%', + + ...(size !== DialogVariant.SmallResize ? { + height: '100%', + } : { }), + }; return StyleSheet.create({ - closeButtonContainer: { + closeButtonRow: { flexDirection: 'row', justifyContent: 'space-between', alignContent: 'center', + marginBottom: 8, + }, + closeButtonRowWithHeading: { + marginBottom: 16, + }, + closeButton: { + margin: 0, + }, + // Ensure that the close button is aligned with the center of the header: + // Make its container smaller and center it. + closeButtonWrapper: { + height: 18, + flexDirection: 'column', + justifyContent: 'center', + alignSelf: 'center', }, heading: { - alignSelf: 'center', + }, + modalBackground: { + justifyContent: 'center', }, dialogContainer: { maxHeight, maxWidth, - width: '100%', - height: '100%', - flexShrink: 1, + ...dialogSizing, // Center marginLeft: 'auto', @@ -58,11 +85,11 @@ const useStyles = (themeId: number, containerStyle: ViewStyle, size: DialogSize) ...containerStyle, }, dialogSurface: { - borderRadius: 12, + borderRadius: 24, backgroundColor: theme.backgroundColor, - padding: 10, - width: '100%', - height: '100%', + paddingHorizontal: 16, + paddingVertical: 24, + ...dialogSizing, }, }); }, [themeId, windowSize.width, windowSize.height, containerStyle, size]); @@ -76,13 +103,16 @@ const DismissibleDialog: React.FC = props => { {props.heading} ) : null; const closeButtonRow = ( - + {heading ?? } - + + + ); @@ -92,9 +122,13 @@ const DismissibleDialog: React.FC = props => { onDismiss={props.onDismiss} onRequestClose={props.onDismiss} containerStyle={styles.dialogContainer} + modalBackgroundStyle={styles.modalBackground} animationType='fade' backgroundColor={theme.backgroundColorTransparent2} transparent={true} + scrollOverflow={props.scrollOverflow} + // Allows the modal background to extend under the statusbar + statusBarTranslucent > {closeButtonRow} diff --git a/packages/app-mobile/components/EditorToolbar/ToolbarEditorDialog.tsx b/packages/app-mobile/components/EditorToolbar/ToolbarEditorDialog.tsx index 00f97e5109..4a26267d96 100644 --- a/packages/app-mobile/components/EditorToolbar/ToolbarEditorDialog.tsx +++ b/packages/app-mobile/components/EditorToolbar/ToolbarEditorDialog.tsx @@ -12,7 +12,7 @@ import { AppState } from '../../utils/types'; import CommandService from '@joplin/lib/services/CommandService'; import allToolbarCommandNamesFromState from './utils/allToolbarCommandNamesFromState'; import Setting from '@joplin/lib/models/Setting'; -import DismissibleDialog, { DialogSize } from '../DismissibleDialog'; +import DismissibleDialog, { DialogVariant } from '../DismissibleDialog'; import selectedCommandNamesFromState from './utils/selectedCommandNamesFromState'; import stateToWhenClauseContext from '../../services/commands/stateToWhenClauseContext'; import { DeleteButton } from '../buttons'; @@ -158,7 +158,7 @@ const ToolbarEditorScreen: React.FC = props => { return ( { const styles = StyleSheet.create({ feedbackContainer: { flexGrow: 1, + flexDirection: 'row', + gap: 16, justifyContent: 'flex-end', + flexWrap: 'wrap', }, paragraph: { paddingBottom: 7, @@ -65,7 +68,7 @@ const WebBetaButton: React.FC = props => { /> = props => { {renderParagraph('Feel free to use it and let us know if have any questions or notice any issues!')} {'Report bug'} - {'Give feedback'} + {'Give feedback'} diff --git a/packages/app-mobile/components/SyncWizard/JoplinCloudIcon.tsx b/packages/app-mobile/components/SyncWizard/JoplinCloudIcon.tsx new file mode 100644 index 0000000000..76d402a7ae --- /dev/null +++ b/packages/app-mobile/components/SyncWizard/JoplinCloudIcon.tsx @@ -0,0 +1,37 @@ +import * as React from 'react'; +import Svg, { SvgProps, G, Path, Defs, LinearGradient, Stop, ClipPath, Rect } from 'react-native-svg'; + +const JoplinCloudIcon: React.FC = props => { + return + + + + + + + + + + + + + + ; +}; + +export default JoplinCloudIcon; diff --git a/packages/app-mobile/components/SyncWizard/SyncWizard.tsx b/packages/app-mobile/components/SyncWizard/SyncWizard.tsx new file mode 100644 index 0000000000..604a11de20 --- /dev/null +++ b/packages/app-mobile/components/SyncWizard/SyncWizard.tsx @@ -0,0 +1,138 @@ +import * as React from 'react'; +import DismissibleDialog, { DialogVariant } from '../DismissibleDialog'; +import { AppState } from '../../utils/types'; +import { connect } from 'react-redux'; +import { Dispatch } from 'redux'; +import { useCallback } from 'react'; +import { Icon, Text } from 'react-native-paper'; +import { _ } from '@joplin/lib/locale'; +import JoplinCloudIcon from './JoplinCloudIcon'; +import NavService from '@joplin/lib/services/NavService'; +import { StyleSheet, View } from 'react-native'; +import CardButton from '../buttons/CardButton'; + +interface Props { + dispatch: Dispatch; + visible: boolean; + themeId: number; +} + +const iconSize = 24; +const styles = StyleSheet.create({ + titleContainer: { + flexDirection: 'row', + gap: 8, + paddingBottom: 6, + alignItems: 'center', + }, + subheading: { + marginBottom: 24, + }, + cardContent: { + padding: 12, + borderRadius: 14, + }, + syncProviderList: { + gap: 8, + }, + featuresList: { + marginTop: 4, + }, + listItem: { + flexDirection: 'row', + gap: 8, + marginVertical: 6, + verticalAlign: 'middle', + }, +}); + +interface SyncProviderProps { + title: string; + icon: ()=> React.ReactNode; + description: string; + onPress: ()=> void; + featuresList: string[]; + disabled: boolean; +} + +const SyncProvider: React.FC = props => { + return + + + {props.icon()} + {props.title}{props.disabled ? ' (Not supported)' : ''} + + {props.description && {props.description}} + + {props.featuresList.map((feature, index) => ( + + {feature} + + ))} + + + ; +}; + +const SyncWizard: React.FC = ({ themeId, visible, dispatch }) => { + const onDismiss = useCallback(() => { + dispatch({ + type: 'SYNC_WIZARD_VISIBLE_CHANGE', + visible: false, + }); + }, [dispatch]); + + const onSelectJoplinCloud = useCallback(async () => { + onDismiss(); + await NavService.go('JoplinCloudLogin'); + }, [onDismiss]); + + const onSelectOtherTarget = useCallback(async () => { + onDismiss(); + await NavService.go('Config', { sectionName: 'sync' }); + }, [onDismiss]); + + return + { + _('Joplin can synchronise your notes using various providers. Select one from the list below.') + } + + } + onPress={onSelectJoplinCloud} + disabled={false} + /> + } + featuresList={[]} + onPress={onSelectOtherTarget} + disabled={false} + /> + + ; +}; + +export default connect((state: AppState) => ({ + visible: state.syncWizardVisible, + themeId: state.settings.theme, +}))(SyncWizard); diff --git a/packages/app-mobile/components/buttons/CardButton.tsx b/packages/app-mobile/components/buttons/CardButton.tsx new file mode 100644 index 0000000000..c000e09927 --- /dev/null +++ b/packages/app-mobile/components/buttons/CardButton.tsx @@ -0,0 +1,72 @@ +import * as React from 'react'; +import { Card, TouchableRipple } from 'react-native-paper'; +import { useMemo } from 'react'; +import { StyleSheet, View, ViewStyle } from 'react-native'; + +export enum InstallState { + NotInstalled, + Installing, + Installed, +} + +interface Props { + onPress: ()=> void; + disabled: boolean; + children: React.ReactNode; + style?: ViewStyle; + testID?: string; +} + +const useStyles = (disabled: boolean) => { + return useMemo(() => { + // For the TouchableRipple to work on Android, the card needs a transparent background. + const baseCard = { backgroundColor: 'transparent' }; + return StyleSheet.create({ + cardOuterWrapper: { + margin: 0, + padding: 0, + borderRadius: 12, + overflow: 'hidden', + }, + cardInnerWrapper: { + width: '100%', + }, + card: disabled ? { + ...baseCard, + opacity: 0.7, + } : baseCard, + content: { + gap: 5, + }, + }); + }, [disabled]); +}; + + +const CardButton: React.FC = props => { + const containerIsButton = !!props.onPress; + const styles = useStyles(props.disabled); + + const CardWrapper = containerIsButton ? TouchableRipple : View; + return ( + + + + {props.children} + + + + ); +}; + +export default CardButton; diff --git a/packages/app-mobile/components/plugins/dialogs/PluginPanelViewer.tsx b/packages/app-mobile/components/plugins/dialogs/PluginPanelViewer.tsx index fdb7d728f6..a6504c45c0 100644 --- a/packages/app-mobile/components/plugins/dialogs/PluginPanelViewer.tsx +++ b/packages/app-mobile/components/plugins/dialogs/PluginPanelViewer.tsx @@ -12,7 +12,7 @@ import PluginUserWebView from './PluginUserWebView'; import { View, StyleSheet, AccessibilityInfo } from 'react-native'; import { _ } from '@joplin/lib/locale'; import Setting from '@joplin/lib/models/Setting'; -import DismissibleDialog, { DialogSize } from '../../../components/DismissibleDialog'; +import DismissibleDialog, { DialogVariant } from '../../../components/DismissibleDialog'; import CommandService from '@joplin/lib/services/CommandService'; interface Props { @@ -164,7 +164,7 @@ const PluginPanelViewer: React.FC = props => { {renderTabContent()} diff --git a/packages/app-mobile/components/screens/ConfigScreen/ConfigScreen.tsx b/packages/app-mobile/components/screens/ConfigScreen/ConfigScreen.tsx index 11914e4c97..d5ee13ad0e 100644 --- a/packages/app-mobile/components/screens/ConfigScreen/ConfigScreen.tsx +++ b/packages/app-mobile/components/screens/ConfigScreen/ConfigScreen.tsx @@ -9,6 +9,7 @@ import { reg } from '@joplin/lib/registry'; import { State } from '@joplin/lib/reducer'; import BackButtonService from '../../../services/BackButtonService'; import { connect } from 'react-redux'; +import { Dispatch } from 'redux'; import ScreenHeader from '../../ScreenHeader'; import { _ } from '@joplin/lib/locale'; import BaseScreenComponent from '../../base-screen'; @@ -60,6 +61,7 @@ interface ConfigScreenProps { themeId: number; // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied navigation: any; + dispatch: Dispatch; } class ConfigScreenComponent extends BaseScreenComponent { @@ -126,6 +128,13 @@ class ConfigScreenComponent extends BaseScreenComponent { + this.props.dispatch({ + type: 'SYNC_WIZARD_VISIBLE_CHANGE', + visible: true, + }); + }; + private saveButton_press = async () => { if (this.state.changedSettingKeys.includes('sync.target') && this.state.settings['sync.target'] === SyncTargetRegistry.nameToId('filesystem')) { if (Platform.OS === 'android') { @@ -545,6 +554,7 @@ class ConfigScreenComponent extends BaseScreenComponent { - return useMemo(() => { - // For the TouchableRipple to work on Android, the card needs a transparent background. - const baseCard = { backgroundColor: 'transparent' }; - return StyleSheet.create({ - cardContainer: { - margin: 0, - marginTop: 8, - padding: 0, - borderRadius: 14, - }, - card: !compatible ? { - ...baseCard, - opacity: 0.7, - } : baseCard, - content: { - gap: 5, - }, - }); - }, [compatible]); -}; - +const styles = StyleSheet.create({ + content: { + gap: 5, + }, + cardContainer: { + marginTop: 8, + }, +}); const PluginBox: React.FC = props => { const manifest = props.item.manifest; @@ -78,46 +65,36 @@ const PluginBox: React.FC = props => { props.onShowPluginInfo?.({ item: props.item }); }, [props.onShowPluginInfo, props.item]); - const styles = useStyles(props.isCompatible); - - const CardWrapper = props.onShowPluginInfo ? TouchableRipple : View; - const containerIsButton = !!props.onShowPluginInfo; return ( - - - - - - - {manifest.description} - - + + + + + {manifest.description} - - - - {props.onAboutPress ? aboutButton : null} - {props.onInstall ? installButton : null} - - - + + + + + + {props.onAboutPress ? aboutButton : null} + {props.onInstall ? installButton : null} + + ); }; diff --git a/packages/app-mobile/components/screens/ConfigScreen/plugins/PluginInfoModal.tsx b/packages/app-mobile/components/screens/ConfigScreen/plugins/PluginInfoModal.tsx index dce8550d20..98fa335d00 100644 --- a/packages/app-mobile/components/screens/ConfigScreen/plugins/PluginInfoModal.tsx +++ b/packages/app-mobile/components/screens/ConfigScreen/plugins/PluginInfoModal.tsx @@ -5,7 +5,7 @@ import { useCallback, useMemo } from 'react'; import { Card, Divider, List, Portal, Switch, Text } from 'react-native-paper'; import getPluginIssueReportUrl from '@joplin/lib/services/plugins/utils/getPluginIssueReportUrl'; import { Linking, ScrollView, StyleSheet, View, ViewStyle } from 'react-native'; -import DismissibleDialog, { DialogSize } from '../../../DismissibleDialog'; +import DismissibleDialog, { DialogVariant } from '../../../DismissibleDialog'; import openWebsiteForPlugin from './utils/openWebsiteForPlugin'; import PluginService, { PluginSettings } from '@joplin/lib/services/plugins/PluginService'; import PluginTitle from './PluginBox/PluginTitle'; @@ -253,7 +253,7 @@ const PluginInfoModal: React.FC = props => { { props.item ? : null } diff --git a/packages/app-mobile/components/screens/ShareNoteDialog.tsx b/packages/app-mobile/components/screens/ShareNoteDialog.tsx index 74d6b5c146..e57a213f7f 100644 --- a/packages/app-mobile/components/screens/ShareNoteDialog.tsx +++ b/packages/app-mobile/components/screens/ShareNoteDialog.tsx @@ -15,7 +15,7 @@ import useEncryptionWarningMessage from '@joplin/lib/components/shared/ShareNote import { SharingStatus } from '@joplin/lib/components/shared/ShareNoteDialog/types'; import { AppState } from '../../utils/types'; import { connect } from 'react-redux'; -import DismissibleDialog, { DialogSize } from '../DismissibleDialog'; +import DismissibleDialog, { DialogVariant } from '../DismissibleDialog'; import { _, _n } from '@joplin/lib/locale'; import { LinkButton, PrimaryButton } from '../buttons'; import { themeStyle } from '../global-style'; @@ -191,7 +191,7 @@ const ShareNoteDialog: React.FC = props => { themeId={props.themeId} visible={props.visible} onDismiss={props.onClose} - size={DialogSize.Small} + size={DialogVariant.Small} heading={_('Publish Note')} > {props.visible ? : null} diff --git a/packages/app-mobile/components/side-menu-content.tsx b/packages/app-mobile/components/side-menu-content.tsx index 6452e8b211..a6da8bc4a5 100644 --- a/packages/app-mobile/components/side-menu-content.tsx +++ b/packages/app-mobile/components/side-menu-content.tsx @@ -502,9 +502,8 @@ const SideMenuContentComponent = (props: Props) => { }); props.dispatch({ - type: 'NAV_GO', - routeName: 'Config', - sectionName: 'sync', + type: 'SYNC_WIZARD_VISIBLE_CHANGE', + visible: true, }); return 'init'; diff --git a/packages/app-mobile/ios/Joplin.xcodeproj/project.pbxproj b/packages/app-mobile/ios/Joplin.xcodeproj/project.pbxproj index 242d64af94..ba22a010c7 100644 --- a/packages/app-mobile/ios/Joplin.xcodeproj/project.pbxproj +++ b/packages/app-mobile/ios/Joplin.xcodeproj/project.pbxproj @@ -341,6 +341,7 @@ "${PODS_CONFIGURATION_BUILD_DIR}/ExpoFileSystem/ExpoFileSystem_privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/RCT-Folly/RCT-Folly_privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/RNDeviceInfo/RNDeviceInfoPrivacyInfo.bundle", + "${PODS_CONFIGURATION_BUILD_DIR}/RNSVG/RNSVGFilters.bundle", "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/AntDesign.ttf", "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Entypo.ttf", "${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/EvilIcons.ttf", @@ -372,6 +373,7 @@ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoFileSystem_privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCT-Folly_privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNDeviceInfoPrivacyInfo.bundle", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNSVGFilters.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AntDesign.ttf", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Entypo.ttf", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EvilIcons.ttf", diff --git a/packages/app-mobile/ios/Podfile.lock b/packages/app-mobile/ios/Podfile.lock index 8032d9d2aa..acf583c0db 100644 --- a/packages/app-mobile/ios/Podfile.lock +++ b/packages/app-mobile/ios/Podfile.lock @@ -1914,6 +1914,8 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga + - RNSVG (15.13.0): + - React-Core - RNVectorIcons (10.2.0): - DoubleConversion - glog @@ -2055,6 +2057,7 @@ DEPENDENCIES: - RNQuickAction (from `../node_modules/react-native-quick-actions`) - RNSecureRandom (from `../node_modules/react-native-securerandom`) - RNShare (from `../node_modules/react-native-share`) + - RNSVG (from `../node_modules/react-native-svg`) - RNVectorIcons (from `../node_modules/react-native-vector-icons`) - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) @@ -2278,6 +2281,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-securerandom" RNShare: :path: "../node_modules/react-native-share" + RNSVG: + :path: "../node_modules/react-native-svg" RNVectorIcons: :path: "../node_modules/react-native-vector-icons" Yoga: @@ -2391,6 +2396,7 @@ SPEC CHECKSUMS: RNQuickAction: c2c8f379e614428be0babe4d53a575739667744d RNSecureRandom: b64d263529492a6897e236a22a2c4249aa1b53dc RNShare: 675e8e4a84f0137baf33057cac8f7334b0bb4b98 + RNSVG: 295a96bc43f2baa5958d64aeec9847a1d8ca7a3d RNVectorIcons: d53917643fddb261b22bd6d889776f336893622b SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748 Yoga: c758bfb934100bb4bf9cbaccb52557cee35e8bdf diff --git a/packages/app-mobile/package.json b/packages/app-mobile/package.json index cd7c0d18ad..53a54f2da9 100644 --- a/packages/app-mobile/package.json +++ b/packages/app-mobile/package.json @@ -70,6 +70,7 @@ "react-native-securerandom": "1.0.1", "react-native-share": "12.0.11", "react-native-sqlite-storage": "6.0.1", + "react-native-svg": "15.13.0", "react-native-url-polyfill": "2.0.0", "react-native-vector-icons": "10.2.0", "react-native-version-info": "1.1.1", diff --git a/packages/app-mobile/root.tsx b/packages/app-mobile/root.tsx index c0ed4b6248..194fd1b2eb 100644 --- a/packages/app-mobile/root.tsx +++ b/packages/app-mobile/root.tsx @@ -107,6 +107,7 @@ import DocumentScanner from './components/screens/DocumentScanner/DocumentScanne import buildStartupTasks from './utils/buildStartupTasks'; import { SafeAreaProvider } from 'react-native-safe-area-context'; import appReducer from './utils/appReducer'; +import SyncWizard from './components/SyncWizard/SyncWizard'; const logger = Logger.create('root'); const perfLogger = PerformanceLogger.create(); @@ -762,6 +763,7 @@ class AppComponent extends React.Component {/* eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied */} (this.dropdownAlert_ = func)} /> + diff --git a/packages/app-mobile/utils/appDefaultState.ts b/packages/app-mobile/utils/appDefaultState.ts index 4ce24fb1c1..c653ef7b38 100644 --- a/packages/app-mobile/utils/appDefaultState.ts +++ b/packages/app-mobile/utils/appDefaultState.ts @@ -17,6 +17,7 @@ const appDefaultState: AppState = { disableSideMenuGestures: false, showPanelsDialog: false, noteEditorVisible: false, + syncWizardVisible: false, ...defaultState, // On mobile, it's possible to select notes that aren't in the selected folder/tag/etc. diff --git a/packages/app-mobile/utils/appReducer.ts b/packages/app-mobile/utils/appReducer.ts index ad03db8139..317af03b5b 100644 --- a/packages/app-mobile/utils/appReducer.ts +++ b/packages/app-mobile/utils/appReducer.ts @@ -195,6 +195,10 @@ const appReducer = (state = appDefaultState, action: any) => { case 'NOTE_EDITOR_VISIBLE_CHANGE': newState = { ...state, noteEditorVisible: action.visible }; break; + + case 'SYNC_WIZARD_VISIBLE_CHANGE': + newState = { ...state, syncWizardVisible: action.visible }; + break; } } catch (error) { error.message = `In reducer: ${error.message} Action: ${JSON.stringify(action)}`; diff --git a/packages/app-mobile/utils/types.ts b/packages/app-mobile/utils/types.ts index 59641cfe83..8c5bfcc209 100644 --- a/packages/app-mobile/utils/types.ts +++ b/packages/app-mobile/utils/types.ts @@ -11,4 +11,5 @@ export interface AppState extends State { noteSideMenuOptions: any; disableSideMenuGestures: boolean; noteEditorVisible: boolean; + syncWizardVisible: boolean; } diff --git a/yarn.lock b/yarn.lock index f9ffebaa00..1894f9dcfa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9615,6 +9615,7 @@ __metadata: react-native-securerandom: "npm:1.0.1" react-native-share: "npm:12.0.11" react-native-sqlite-storage: "npm:6.0.1" + react-native-svg: "npm:15.13.0" react-native-url-polyfill: "npm:2.0.0" react-native-vector-icons: "npm:10.2.0" react-native-version-info: "npm:1.1.1" @@ -42100,6 +42101,20 @@ __metadata: languageName: node linkType: hard +"react-native-svg@npm:15.13.0": + version: 15.13.0 + resolution: "react-native-svg@npm:15.13.0" + dependencies: + css-select: "npm:^5.1.0" + css-tree: "npm:^1.1.3" + warn-once: "npm:0.1.1" + peerDependencies: + react: "*" + react-native: "*" + checksum: 10/03db4516aec2dfcdf406283bf6b0e18ea3f56cdf228c97f92d282128b1e39c3336424d46a1afec894ebc1c3681b16d2c35c03b08a8a5ee2314c124bdea7ae6e3 + languageName: node + linkType: hard + "react-native-url-polyfill@npm:2.0.0": version: 2.0.0 resolution: "react-native-url-polyfill@npm:2.0.0" @@ -50732,6 +50747,13 @@ __metadata: languageName: node linkType: hard +"warn-once@npm:0.1.1": + version: 0.1.1 + resolution: "warn-once@npm:0.1.1" + checksum: 10/e6a5a1f5a8dba7744399743d3cfb571db4c3947897875d4962a7c5b1bf2195ab4518c838cb4cea652e71729f21bba2e98dc75686f5fccde0fabbd894e2ed0c0d + languageName: node + linkType: hard + "wasm-feature-detect@npm:^1.2.11": version: 1.5.1 resolution: "wasm-feature-detect@npm:1.5.1"