Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions packages/mobile/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { MobileThemeVariables } from '@Root/Style/Themes/styled-components'
import { ApplicationGroupEvent, DeinitMode, DeinitSource } from '@standardnotes/snjs'
import { ThemeService, ThemeServiceContext } from '@Style/ThemeService'
import React, { useCallback, useEffect, useRef, useState } from 'react'
import { StatusBar } from 'react-native'
import { ThemeProvider } from 'styled-components/native'
import { ApplicationContext } from './ApplicationContext'
import { MainStackComponent } from './ModalStack'
Expand Down Expand Up @@ -107,7 +106,6 @@ const AppComponent: React.FC<{
}}
ref={navigationRef}
>
<StatusBar translucent />
{themeService.current && (
<>
<ThemeProvider theme={activeTheme}>
Expand Down
45 changes: 14 additions & 31 deletions packages/mobile/src/AppStack.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,22 @@ import { AlwaysOpenWebAppOnLaunchKey } from '@Lib/constants'
import { useHasEditor, useIsLocked } from '@Lib/SnjsHelperHooks'
import { ScreenStatus } from '@Lib/StatusManager'
import { IsDev } from '@Lib/Utils'
import { CompositeNavigationProp, RouteProp, useNavigation } from '@react-navigation/native'
import { CompositeNavigationProp, RouteProp } from '@react-navigation/native'
import { createStackNavigator, StackNavigationProp } from '@react-navigation/stack'
import { HeaderTitleView } from '@Root/Components/HeaderTitleView'
import { IoniconsHeaderButton } from '@Root/Components/IoniconsHeaderButton'
import { Compose } from '@Root/Screens/Compose/Compose'
import { SCREEN_COMPOSE, SCREEN_NOTES, SCREEN_VIEW_PROTECTED_NOTE, SCREEN_WEB_APP } from '@Root/Screens/screens'
import { SCREEN_COMPOSE, SCREEN_NOTES, SCREEN_VIEW_PROTECTED_NOTE } from '@Root/Screens/screens'
import { MainSideMenu } from '@Root/Screens/SideMenu/MainSideMenu'
import { NoteSideMenu } from '@Root/Screens/SideMenu/NoteSideMenu'
import { ViewProtectedNote } from '@Root/Screens/ViewProtectedNote/ViewProtectedNote'
import { Root } from '@Screens/Root'
import { ApplicationEvent, StorageValueModes, UuidString } from '@standardnotes/snjs'
import { StorageValueModes, UuidString } from '@standardnotes/snjs'
import { ICON_MENU } from '@Style/Icons'
import { ThemeService } from '@Style/ThemeService'
import { getDefaultDrawerWidth } from '@Style/Utils'
import React, { useCallback, useContext, useEffect, useRef, useState } from 'react'
import { Dimensions, Keyboard, ScaledSize } from 'react-native'
import { Dimensions, Keyboard, ScaledSize, StatusBar } from 'react-native'
import DrawerLayout, { DrawerState } from 'react-native-gesture-handler/DrawerLayout'
import { HeaderButtons, Item } from 'react-navigation-header-buttons'
import { ThemeContext } from 'styled-components'
Expand All @@ -27,9 +27,6 @@ import { ApplicationContext } from './ApplicationContext'
import { MobileWebAppContainer } from './MobileWebAppContainer'
import { ModalStackNavigationProp } from './ModalStack'

const IS_DEBUGGING_WEB_APP = false
const DEFAULT_TO_WEB_APP = IsDev && IS_DEBUGGING_WEB_APP

export type AppStackNavigatorParamList = {
[SCREEN_NOTES]: HeaderTitleParams
[SCREEN_COMPOSE]: HeaderTitleParams & {
Expand Down Expand Up @@ -124,28 +121,6 @@ export const AppStackComponent = (props: ModalStackNavigationProp<'AppStack'>) =
[application],
)

const navigation = useNavigation<ModalStackNavigationProp<'AppStack'>['navigation']>()

useEffect(() => {
if (!application) {
return
}

const removeObserver = application.addEventObserver(async (event) => {
if (event === ApplicationEvent.Launched) {
const value = (await application.getValue(AlwaysOpenWebAppOnLaunchKey, StorageValueModes.Nonwrapped)) as
| boolean
| undefined
const shouldAlwaysOpenWebAppOnLaunch = value ?? false
if (shouldAlwaysOpenWebAppOnLaunch) {
navigation.push(SCREEN_WEB_APP)
}
}
})

return removeObserver
}, [application, navigation])

if (IsDev) {
return (
<AppStack.Navigator
Expand All @@ -154,11 +129,17 @@ export const AppStackComponent = (props: ModalStackNavigationProp<'AppStack'>) =
})}
initialRouteName={SCREEN_NOTES}
>
<AppStack.Screen name={SCREEN_NOTES} component={IsDev ? MobileWebAppContainer : Root} />
<AppStack.Screen name={SCREEN_NOTES} component={MobileWebAppContainer} />
</AppStack.Navigator>
)
}

if (!application) {
return null
}

const shouldOpenWebApp = application.getValue(AlwaysOpenWebAppOnLaunchKey, StorageValueModes.Nonwrapped) as boolean

return (
<DrawerLayout
ref={drawerRef}
Expand All @@ -169,6 +150,7 @@ export const AppStackComponent = (props: ModalStackNavigationProp<'AppStack'>) =
onDrawerStateChanged={handleDrawerStateChange}
renderNavigationView={() => !isLocked && <MainSideMenu drawerRef={drawerRef.current} />}
>
<StatusBar translucent={!shouldOpenWebApp} />
<DrawerLayout
ref={noteDrawerRef}
drawerWidth={getDefaultDrawerWidth(dimensions)}
Expand Down Expand Up @@ -198,6 +180,7 @@ export const AppStackComponent = (props: ModalStackNavigationProp<'AppStack'>) =
name={SCREEN_NOTES}
options={({ route }) => ({
title: 'All notes',
headerShown: !shouldOpenWebApp,
headerTitle: ({ children }) => {
const screenStatus = isInTabletMode ? composeStatus || notesStatus : notesStatus

Expand Down Expand Up @@ -237,7 +220,7 @@ export const AppStackComponent = (props: ModalStackNavigationProp<'AppStack'>) =
</HeaderButtons>
),
})}
component={DEFAULT_TO_WEB_APP ? MobileWebAppContainer : Root}
component={shouldOpenWebApp ? MobileWebAppContainer : Root}
/>
<AppStack.Screen
name={SCREEN_COMPOSE}
Expand Down
40 changes: 14 additions & 26 deletions packages/mobile/src/Screens/Settings/Sections/OptionsSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import { SectionHeader } from '@Root/Components/SectionHeader'
import { TableSection } from '@Root/Components/TableSection'
import { useSafeApplicationContext } from '@Root/Hooks/useSafeApplicationContext'
import { ModalStackNavigationProp } from '@Root/ModalStack'
import { SCREEN_MANAGE_SESSIONS, SCREEN_SETTINGS, SCREEN_WEB_APP } from '@Root/Screens/screens'
import { SCREEN_MANAGE_SESSIONS, SCREEN_SETTINGS } from '@Root/Screens/screens'
import { ButtonType, PrefKey, StorageValueModes } from '@standardnotes/snjs'
import moment from 'moment'
import React, { useCallback, useEffect, useMemo, useState } from 'react'
import React, { useCallback, useMemo, useState } from 'react'
import { Platform } from 'react-native'
import DocumentPicker from 'react-native-document-picker'
import RNFS from 'react-native-fs'
Expand Down Expand Up @@ -183,22 +183,6 @@ export const OptionsSection = ({ title, encryptionAvailable }: Props) => {
)
}, [application.alertService])

const [shouldAlwaysOpenWebAppOnLaunch, setShouldAlwaysOpenWebAppOnLaunch] = useState(false)

useEffect(() => {
const getSetting = async () => {
const value = (await application.getValue(AlwaysOpenWebAppOnLaunchKey, StorageValueModes.Nonwrapped)) as
| boolean
| undefined
setShouldAlwaysOpenWebAppOnLaunch(value ?? false)
}
void getSetting()
}, [application])

const openWebApp = useCallback(() => {
navigation.push(SCREEN_WEB_APP)
}, [navigation])

return (
<TableSection>
<SectionHeader title={title} />
Expand Down Expand Up @@ -238,15 +222,19 @@ export const OptionsSection = ({ title, encryptionAvailable }: Props) => {
onPress={onExportPress}
/>

<ButtonCell testID="openWebApp" leftAligned title="Open Web App" onPress={() => openWebApp()} />
<SectionedAccessoryTableCell
onPress={() => {
const newValue = !shouldAlwaysOpenWebAppOnLaunch
setShouldAlwaysOpenWebAppOnLaunch(newValue)
void application.setValue(AlwaysOpenWebAppOnLaunchKey, newValue, StorageValueModes.Nonwrapped)
<ButtonCell
onPress={async () => {
const confirmationText =
'This will close the app and fully switch to the web view next time you open it. You will be able to switch back from the settings.'

if (
await application.alertService.confirm(confirmationText, 'Switch To Web View?', 'Switch', ButtonType.Info)
) {
application.setValue(AlwaysOpenWebAppOnLaunchKey, true, StorageValueModes.Nonwrapped)
setTimeout(() => application.deviceInterface.performSoftReset(), 1000)
}
}}
text="Always Open Web App On Launch"
selected={() => shouldAlwaysOpenWebAppOnLaunch}
title="Switch to Web View"
/>

{!signedIn && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,6 @@ const ComponentView: FunctionComponent<IProps> = ({ application, onLoad, compone
{error === ComponentViewerError.MissingUrl && <UrlMissing componentName={component.displayName} />}
{component.uuid && isComponentValid && (
<iframe
className="min-h-[40rem]"
ref={iframeRef}
onLoad={onIframeLoad}
data-component-viewer-id={componentViewer.identifier}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import Dropdown from '@/Components/Dropdown/Dropdown'
import { DropdownItem } from '@/Components/Dropdown/DropdownItem'
import { FeatureIdentifier, PrefKey, ComponentArea, ComponentMutator, SNComponent } from '@standardnotes/snjs'
import {
FeatureIdentifier,
PrefKey,
ComponentArea,
ComponentMutator,
SNComponent,
StorageValueModes,
} from '@standardnotes/snjs'
import { Subtitle, Text, Title } from '@/Components/Preferences/PreferencesComponents/Content'
import { WebApplication } from '@/Application/Application'
import { FunctionComponent, useEffect, useState } from 'react'
Expand All @@ -9,6 +16,7 @@ import Switch from '@/Components/Switch/Switch'
import { PLAIN_EDITOR_NAME } from '@/Constants/Constants'
import PreferencesGroup from '../../PreferencesComponents/PreferencesGroup'
import PreferencesSegment from '../../PreferencesComponents/PreferencesSegment'
import Button from '@/Components/Button/Button'

type Props = {
application: WebApplication
Expand Down Expand Up @@ -43,6 +51,8 @@ const getDefaultEditor = (application: WebApplication) => {
return application.componentManager.componentsForArea(ComponentArea.Editor).filter((e) => e.isDefaultEditor())[0]
}

const AlwaysOpenWebAppOnLaunchKey = 'AlwaysOpenWebAppOnLaunch'

const Defaults: FunctionComponent<Props> = ({ application }) => {
const [editorItems, setEditorItems] = useState<DropdownItem[]>([])
const [defaultEditorValue, setDefaultEditorValue] = useState(
Expand Down Expand Up @@ -102,10 +112,30 @@ const Defaults: FunctionComponent<Props> = ({ application }) => {
}
}

const switchToNativeView = async () => {
application.setValue(AlwaysOpenWebAppOnLaunchKey, false, StorageValueModes.Nonwrapped)
setTimeout(() => {
application.deviceInterface.performSoftReset()
}, 1000)
}

return (
<PreferencesGroup>
<PreferencesSegment>
<Title>Defaults</Title>
{application.isNativeMobileWeb() && (
<>
<div className="flex flex-col">
<Subtitle>Switch to Native View</Subtitle>
<Text>
This will close the app and fully switch to the native view next time you open it. You will be able to
switch back from the settings.
</Text>
<Button className="mt-3 min-w-20" label="Switch" onClick={switchToNativeView} />
</div>
<HorizontalSeparator classes="my-4" />
</>
)}
<div>
<Subtitle>Default Note Type</Subtitle>
<Text>New notes will be created using this type.</Text>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@ interface SecurityProps extends MfaProps {
application: WebApplication
}

const SHOW_MULTITASKING_PRIVACY = false
const SHOW_BIOMETRICS_LOCK = false

const Security: FunctionComponent<SecurityProps> = (props) => {
const isNativeMobileWeb = props.application.isNativeMobileWeb()

Expand All @@ -31,9 +28,9 @@ const Security: FunctionComponent<SecurityProps> = (props) => {
)}
<Protections application={props.application} />
<TwoFactorAuthWrapper mfaProvider={props.mfaProvider} userProvider={props.userProvider} />
{SHOW_MULTITASKING_PRIVACY && isNativeMobileWeb && <MultitaskingPrivacy application={props.application} />}
{isNativeMobileWeb && <MultitaskingPrivacy application={props.application} />}
<PasscodeLock viewControllerManager={props.viewControllerManager} application={props.application} />
{SHOW_BIOMETRICS_LOCK && isNativeMobileWeb && <BiometricsLock application={props.application} />}
{isNativeMobileWeb && <BiometricsLock application={props.application} />}
{props.application.getUser() && <Privacy application={props.application} />}
</PreferencesPane>
)
Expand Down