feat(mobile): add setting to always open web view on launch (#1500)
This commit is contained in:
@@ -2,11 +2,12 @@
|
|||||||
class WebProcessDeviceInterface {
|
class WebProcessDeviceInterface {
|
||||||
constructor(messageSender) {
|
constructor(messageSender) {
|
||||||
this.appVersion = '1.2.3'
|
this.appVersion = '1.2.3'
|
||||||
this.environment = 1
|
this.environment = 4
|
||||||
this.databases = []
|
this.databases = []
|
||||||
this.messageSender = messageSender
|
this.messageSender = messageSender
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||||
setApplication() {}
|
setApplication() {}
|
||||||
|
|
||||||
sendMessage(functionName, args) {
|
sendMessage(functionName, args) {
|
||||||
|
|||||||
@@ -1,18 +1,19 @@
|
|||||||
import { AppStateEventType, AppStateType, TabletModeChangeData } from '@Lib/ApplicationState'
|
import { AppStateEventType, AppStateType, TabletModeChangeData } from '@Lib/ApplicationState'
|
||||||
|
import { AlwaysOpenWebAppOnLaunchKey } from '@Lib/constants'
|
||||||
import { useHasEditor, useIsLocked } from '@Lib/SnjsHelperHooks'
|
import { useHasEditor, useIsLocked } from '@Lib/SnjsHelperHooks'
|
||||||
import { ScreenStatus } from '@Lib/StatusManager'
|
import { ScreenStatus } from '@Lib/StatusManager'
|
||||||
import { IsDev } from '@Lib/Utils'
|
import { IsDev } from '@Lib/Utils'
|
||||||
import { CompositeNavigationProp, RouteProp } from '@react-navigation/native'
|
import { CompositeNavigationProp, RouteProp, useNavigation } from '@react-navigation/native'
|
||||||
import { createStackNavigator, StackNavigationProp } from '@react-navigation/stack'
|
import { createStackNavigator, StackNavigationProp } from '@react-navigation/stack'
|
||||||
import { HeaderTitleView } from '@Root/Components/HeaderTitleView'
|
import { HeaderTitleView } from '@Root/Components/HeaderTitleView'
|
||||||
import { IoniconsHeaderButton } from '@Root/Components/IoniconsHeaderButton'
|
import { IoniconsHeaderButton } from '@Root/Components/IoniconsHeaderButton'
|
||||||
import { Compose } from '@Root/Screens/Compose/Compose'
|
import { Compose } from '@Root/Screens/Compose/Compose'
|
||||||
import { SCREEN_COMPOSE, SCREEN_NOTES, SCREEN_VIEW_PROTECTED_NOTE } from '@Root/Screens/screens'
|
import { SCREEN_COMPOSE, SCREEN_NOTES, SCREEN_VIEW_PROTECTED_NOTE, SCREEN_WEB_APP } from '@Root/Screens/screens'
|
||||||
import { MainSideMenu } from '@Root/Screens/SideMenu/MainSideMenu'
|
import { MainSideMenu } from '@Root/Screens/SideMenu/MainSideMenu'
|
||||||
import { NoteSideMenu } from '@Root/Screens/SideMenu/NoteSideMenu'
|
import { NoteSideMenu } from '@Root/Screens/SideMenu/NoteSideMenu'
|
||||||
import { ViewProtectedNote } from '@Root/Screens/ViewProtectedNote/ViewProtectedNote'
|
import { ViewProtectedNote } from '@Root/Screens/ViewProtectedNote/ViewProtectedNote'
|
||||||
import { Root } from '@Screens/Root'
|
import { Root } from '@Screens/Root'
|
||||||
import { UuidString } from '@standardnotes/snjs'
|
import { ApplicationEvent, StorageValueModes, UuidString } from '@standardnotes/snjs'
|
||||||
import { ICON_MENU } from '@Style/Icons'
|
import { ICON_MENU } from '@Style/Icons'
|
||||||
import { ThemeService } from '@Style/ThemeService'
|
import { ThemeService } from '@Style/ThemeService'
|
||||||
import { getDefaultDrawerWidth } from '@Style/Utils'
|
import { getDefaultDrawerWidth } from '@Style/Utils'
|
||||||
@@ -123,6 +124,28 @@ export const AppStackComponent = (props: ModalStackNavigationProp<'AppStack'>) =
|
|||||||
[application],
|
[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])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DrawerLayout
|
<DrawerLayout
|
||||||
ref={drawerRef}
|
ref={drawerRef}
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import { IsDev } from '@Lib/Utils'
|
|
||||||
|
|
||||||
export enum ErrorMessage {
|
export enum ErrorMessage {
|
||||||
GeneralText = 'An error occurred. Please try again later.',
|
GeneralText = 'An error occurred. Please try again later.',
|
||||||
}
|
}
|
||||||
|
|
||||||
export const WebAppOptionEnabled = IsDev
|
export const AlwaysOpenWebAppOnLaunchKey = 'AlwaysOpenWebAppOnLaunch'
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ export const MobileWebAppContainer = () => {
|
|||||||
class WebProcessDeviceInterface {
|
class WebProcessDeviceInterface {
|
||||||
constructor(messageSender) {
|
constructor(messageSender) {
|
||||||
this.appVersion = '1.2.3'
|
this.appVersion = '1.2.3'
|
||||||
this.environment = 1
|
this.environment = 4
|
||||||
this.databases = []
|
this.databases = []
|
||||||
this.messageSender = messageSender
|
this.messageSender = messageSender
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { WebAppOptionEnabled } from '@Lib/constants'
|
import { AlwaysOpenWebAppOnLaunchKey } from '@Lib/constants'
|
||||||
import { useSignedIn } from '@Lib/SnjsHelperHooks'
|
import { useSignedIn } from '@Lib/SnjsHelperHooks'
|
||||||
import { useNavigation } from '@react-navigation/native'
|
import { useNavigation } from '@react-navigation/native'
|
||||||
import { ButtonCell } from '@Root/Components/ButtonCell'
|
import { ButtonCell } from '@Root/Components/ButtonCell'
|
||||||
@@ -9,9 +9,9 @@ import { TableSection } from '@Root/Components/TableSection'
|
|||||||
import { useSafeApplicationContext } from '@Root/Hooks/useSafeApplicationContext'
|
import { useSafeApplicationContext } from '@Root/Hooks/useSafeApplicationContext'
|
||||||
import { ModalStackNavigationProp } from '@Root/ModalStack'
|
import { ModalStackNavigationProp } from '@Root/ModalStack'
|
||||||
import { SCREEN_MANAGE_SESSIONS, SCREEN_SETTINGS, SCREEN_WEB_APP } from '@Root/Screens/screens'
|
import { SCREEN_MANAGE_SESSIONS, SCREEN_SETTINGS, SCREEN_WEB_APP } from '@Root/Screens/screens'
|
||||||
import { ButtonType, PrefKey } from '@standardnotes/snjs'
|
import { ButtonType, PrefKey, StorageValueModes } from '@standardnotes/snjs'
|
||||||
import moment from 'moment'
|
import moment from 'moment'
|
||||||
import React, { useCallback, useMemo, useState } from 'react'
|
import React, { useCallback, useEffect, useMemo, useState } from 'react'
|
||||||
import { Platform } from 'react-native'
|
import { Platform } from 'react-native'
|
||||||
import DocumentPicker from 'react-native-document-picker'
|
import DocumentPicker from 'react-native-document-picker'
|
||||||
import RNFS from 'react-native-fs'
|
import RNFS from 'react-native-fs'
|
||||||
@@ -183,6 +183,18 @@ export const OptionsSection = ({ title, encryptionAvailable }: Props) => {
|
|||||||
)
|
)
|
||||||
}, [application.alertService])
|
}, [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(() => {
|
const openWebApp = useCallback(() => {
|
||||||
navigation.push(SCREEN_WEB_APP)
|
navigation.push(SCREEN_WEB_APP)
|
||||||
}, [navigation])
|
}, [navigation])
|
||||||
@@ -226,9 +238,16 @@ export const OptionsSection = ({ title, encryptionAvailable }: Props) => {
|
|||||||
onPress={onExportPress}
|
onPress={onExportPress}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{WebAppOptionEnabled && (
|
<ButtonCell testID="openWebApp" leftAligned title="Open Web App" onPress={() => openWebApp()} />
|
||||||
<ButtonCell testID="openWebApp" leftAligned title={'Open Web App'} onPress={() => openWebApp()} />
|
<SectionedAccessoryTableCell
|
||||||
)}
|
onPress={() => {
|
||||||
|
const newValue = !shouldAlwaysOpenWebAppOnLaunch
|
||||||
|
setShouldAlwaysOpenWebAppOnLaunch(newValue)
|
||||||
|
void application.setValue(AlwaysOpenWebAppOnLaunchKey, newValue, StorageValueModes.Nonwrapped)
|
||||||
|
}}
|
||||||
|
text="Always Open Web App On Launch"
|
||||||
|
selected={() => shouldAlwaysOpenWebAppOnLaunch}
|
||||||
|
/>
|
||||||
|
|
||||||
{!signedIn && (
|
{!signedIn && (
|
||||||
<SectionedAccessoryTableCell
|
<SectionedAccessoryTableCell
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ export enum Environment {
|
|||||||
Web = 1,
|
Web = 1,
|
||||||
Desktop = 2,
|
Desktop = 2,
|
||||||
Mobile = 3,
|
Mobile = 3,
|
||||||
|
NativeMobileWeb = 4,
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum Platform {
|
export enum Platform {
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ export function environmentFromString(string: string) {
|
|||||||
web: Environment.Web,
|
web: Environment.Web,
|
||||||
desktop: Environment.Desktop,
|
desktop: Environment.Desktop,
|
||||||
mobile: Environment.Mobile,
|
mobile: Environment.Mobile,
|
||||||
|
nativeMobileWeb: Environment.NativeMobileWeb,
|
||||||
}
|
}
|
||||||
return map[string]
|
return map[string]
|
||||||
}
|
}
|
||||||
@@ -42,6 +43,7 @@ export function environmentToString(environment: Environment) {
|
|||||||
[Environment.Web]: 'web',
|
[Environment.Web]: 'web',
|
||||||
[Environment.Desktop]: 'desktop',
|
[Environment.Desktop]: 'desktop',
|
||||||
[Environment.Mobile]: 'mobile',
|
[Environment.Mobile]: 'mobile',
|
||||||
|
[Environment.NativeMobileWeb]: 'native-mobile-web',
|
||||||
}
|
}
|
||||||
return map[environment]
|
return map[environment]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -291,11 +291,15 @@ export class SNComponentManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
const isWeb = this.environment === Environment.Web
|
const isWeb = this.environment === Environment.Web
|
||||||
|
const isMobileWebView = this.environment === Environment.NativeMobileWeb
|
||||||
if (nativeFeature) {
|
if (nativeFeature) {
|
||||||
if (!isWeb) {
|
if (!isWeb && !isMobileWebView) {
|
||||||
throw Error('Mobile must override urlForComponent to handle native paths')
|
throw Error('Mobile must override urlForComponent to handle native paths')
|
||||||
}
|
}
|
||||||
const baseUrlRequiredForThemesInsideEditors = window.location.origin
|
let baseUrlRequiredForThemesInsideEditors = window.location.origin
|
||||||
|
if (isMobileWebView) {
|
||||||
|
baseUrlRequiredForThemesInsideEditors = window.location.href.split('/index.html')[0]
|
||||||
|
}
|
||||||
return `${baseUrlRequiredForThemesInsideEditors}/components/assets/${component.identifier}/${nativeFeature.index_path}`
|
return `${baseUrlRequiredForThemesInsideEditors}/components/assets/${component.identifier}/${nativeFeature.index_path}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user