refactor: new mobile experience opt in flow (#1616)
* refactor: new mobile experience opt in flow * chore: lint
This commit is contained in:
@@ -13,6 +13,7 @@ import {
|
|||||||
platformFromString,
|
platformFromString,
|
||||||
SNApplication,
|
SNApplication,
|
||||||
SNComponentManager,
|
SNComponentManager,
|
||||||
|
StorageValueModes,
|
||||||
} from '@standardnotes/snjs'
|
} from '@standardnotes/snjs'
|
||||||
import { Platform } from 'react-native'
|
import { Platform } from 'react-native'
|
||||||
|
|
||||||
@@ -21,6 +22,7 @@ import { MobileAlertService } from './AlertService'
|
|||||||
import { ApplicationState } from './ApplicationState'
|
import { ApplicationState } from './ApplicationState'
|
||||||
import { BackupsService } from './BackupsService'
|
import { BackupsService } from './BackupsService'
|
||||||
import { ComponentManager } from './ComponentManager'
|
import { ComponentManager } from './ComponentManager'
|
||||||
|
import { AlwaysOpenWebAppOnLaunchKey } from './constants'
|
||||||
import { FilesService } from './FilesService'
|
import { FilesService } from './FilesService'
|
||||||
import { InstallationService } from './InstallationService'
|
import { InstallationService } from './InstallationService'
|
||||||
import { MobileDevice } from './Interface'
|
import { MobileDevice } from './Interface'
|
||||||
@@ -135,7 +137,8 @@ export class MobileApplication extends SNApplication {
|
|||||||
}
|
}
|
||||||
|
|
||||||
promptForChallenge(challenge: Challenge) {
|
promptForChallenge(challenge: Challenge) {
|
||||||
if (IsMobileWeb) {
|
const optedIntoWebPreview = this.getValue(AlwaysOpenWebAppOnLaunchKey, StorageValueModes.Nonwrapped) as boolean
|
||||||
|
if (IsMobileWeb || optedIntoWebPreview) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
import { AlwaysOpenWebAppOnLaunchKey } from '@Lib/constants'
|
||||||
|
import { ApplicationContext } from '@Root/ApplicationContext'
|
||||||
|
import { ButtonCell } from '@Root/Components/ButtonCell'
|
||||||
|
import { SectionHeader } from '@Root/Components/SectionHeader'
|
||||||
|
import { TableSection } from '@Root/Components/TableSection'
|
||||||
|
import { ButtonType, StorageValueModes } from '@standardnotes/snjs'
|
||||||
|
import React, { useContext } from 'react'
|
||||||
|
import styled from 'styled-components/native'
|
||||||
|
import { Label } from './CompanySection.styled'
|
||||||
|
import { BaseView, StyledSectionedTableCell } from './EncryptionSection.styled'
|
||||||
|
|
||||||
|
const Title = styled.Text`
|
||||||
|
color: ${({ theme }) => theme.stylekitForegroundColor};
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: bold;
|
||||||
|
`
|
||||||
|
|
||||||
|
export const NewMobileSection = () => {
|
||||||
|
const application = useContext(ApplicationContext)
|
||||||
|
|
||||||
|
if (!application) {
|
||||||
|
return <></>
|
||||||
|
}
|
||||||
|
|
||||||
|
const optIn = async () => {
|
||||||
|
const confirmationText =
|
||||||
|
'This will close the app and switch to the new mobile experience next time you open it. You will be able to switch back to the soon-to-be removed classic experience from the settings.'
|
||||||
|
|
||||||
|
if (
|
||||||
|
await application.alertService.confirm(
|
||||||
|
confirmationText,
|
||||||
|
'Switch To New Mobile Experience?',
|
||||||
|
'Switch',
|
||||||
|
ButtonType.Info,
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
application.setValue(AlwaysOpenWebAppOnLaunchKey, true, StorageValueModes.Nonwrapped)
|
||||||
|
setTimeout(() => application.deviceInterface.performSoftReset(), 1000)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TableSection>
|
||||||
|
<SectionHeader title={'New Mobile Experience'} />
|
||||||
|
|
||||||
|
<StyledSectionedTableCell last={true} first={true}>
|
||||||
|
<BaseView>
|
||||||
|
<Title>🎉 New Mobile Experience Preview</Title>
|
||||||
|
<Label>
|
||||||
|
The new mobile experience (MX) brings the desktop experience you've come to love right here on your mobile
|
||||||
|
device. This mode will replace the existing classic mobile experience soon. You can opt in below to begin
|
||||||
|
using the new MX now.
|
||||||
|
</Label>
|
||||||
|
</BaseView>
|
||||||
|
</StyledSectionedTableCell>
|
||||||
|
|
||||||
|
<ButtonCell leftAligned={true} title="Opt In to New Mobile Experience" onPress={optIn}></ButtonCell>
|
||||||
|
<ButtonCell
|
||||||
|
leftAligned={true}
|
||||||
|
title="Read Blog Post"
|
||||||
|
onPress={() => {
|
||||||
|
application?.deviceInterface!.openUrl(
|
||||||
|
'https://blog.standardnotes.com/38384/our-new-mobile-experience-is-launching-soon',
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
></ButtonCell>
|
||||||
|
</TableSection>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
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,7 +8,7 @@ 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 } from '@Root/Screens/screens'
|
import { SCREEN_MANAGE_SESSIONS, SCREEN_SETTINGS } from '@Root/Screens/screens'
|
||||||
import { ButtonType, PrefKey, StorageValueModes } from '@standardnotes/snjs'
|
import { ButtonType, PrefKey } from '@standardnotes/snjs'
|
||||||
import moment from 'moment'
|
import moment from 'moment'
|
||||||
import React, { useCallback, useMemo, useState } from 'react'
|
import React, { useCallback, useMemo, useState } from 'react'
|
||||||
import { Platform } from 'react-native'
|
import { Platform } from 'react-native'
|
||||||
@@ -222,21 +221,6 @@ export const OptionsSection = ({ title, encryptionAvailable }: Props) => {
|
|||||||
onPress={onExportPress}
|
onPress={onExportPress}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<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)
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
title="Switch to Web View"
|
|
||||||
/>
|
|
||||||
|
|
||||||
{!signedIn && (
|
{!signedIn && (
|
||||||
<SectionedAccessoryTableCell
|
<SectionedAccessoryTableCell
|
||||||
testID="lastExportDate"
|
testID="lastExportDate"
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import React, { useCallback, useEffect, useState } from 'react'
|
|||||||
import { AuthSection } from './Sections/AuthSection'
|
import { AuthSection } from './Sections/AuthSection'
|
||||||
import { CompanySection } from './Sections/CompanySection'
|
import { CompanySection } from './Sections/CompanySection'
|
||||||
import { EncryptionSection } from './Sections/EncryptionSection'
|
import { EncryptionSection } from './Sections/EncryptionSection'
|
||||||
|
import { NewMobileSection } from './Sections/NewMobilePreview'
|
||||||
import { OptionsSection } from './Sections/OptionsSection'
|
import { OptionsSection } from './Sections/OptionsSection'
|
||||||
import { PreferencesSection } from './Sections/PreferencesSection'
|
import { PreferencesSection } from './Sections/PreferencesSection'
|
||||||
import { ProtectionsSection } from './Sections/ProtectionsSection'
|
import { ProtectionsSection } from './Sections/ProtectionsSection'
|
||||||
@@ -54,6 +55,7 @@ export const Settings = (props: Props) => {
|
|||||||
<Container keyboardShouldPersistTaps={'always'} keyboardDismissMode={'interactive'}>
|
<Container keyboardShouldPersistTaps={'always'} keyboardDismissMode={'interactive'}>
|
||||||
<AuthSection title="Account" signedIn={signedIn} />
|
<AuthSection title="Account" signedIn={signedIn} />
|
||||||
<OptionsSection encryptionAvailable={!!encryptionAvailable} title="Options" />
|
<OptionsSection encryptionAvailable={!!encryptionAvailable} title="Options" />
|
||||||
|
<NewMobileSection />
|
||||||
<WorkspacesSection />
|
<WorkspacesSection />
|
||||||
<PreferencesSection />
|
<PreferencesSection />
|
||||||
{application.hasAccount() && isEntitledToFiles && <FilesSection />}
|
{application.hasAccount() && isEntitledToFiles && <FilesSection />}
|
||||||
|
|||||||
@@ -126,10 +126,10 @@ const Defaults: FunctionComponent<Props> = ({ application }) => {
|
|||||||
{application.isNativeMobileWeb() && (
|
{application.isNativeMobileWeb() && (
|
||||||
<>
|
<>
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<Subtitle>Switch to Native View</Subtitle>
|
<Subtitle>Switch to Classic Mobile Experience</Subtitle>
|
||||||
<Text>
|
<Text>
|
||||||
This will close the app and fully switch to the native view next time you open it. You will be able to
|
This will close the app and switch back to the soon-to-be removed classic mobile experience. You can opt
|
||||||
switch back from the settings.
|
back in to new experience from the app settings.
|
||||||
</Text>
|
</Text>
|
||||||
<Button className="mt-3 min-w-20" label="Switch" onClick={switchToNativeView} />
|
<Button className="mt-3 min-w-20" label="Switch" onClick={switchToNativeView} />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user