Files
standardnotes-app-web/packages/mobile/src/Screens/Root.tsx
2022-06-21 06:42:43 -05:00

128 lines
5.1 KiB
TypeScript

import { AppStateEventType, AppStateType, TabletModeChangeData } from '@Lib/ApplicationState'
import { useIsLocked } from '@Lib/SnjsHelperHooks'
import { ApplicationContext } from '@Root/ApplicationContext'
import { NoteViewController } from '@standardnotes/snjs'
import { ThemeService } from '@Style/ThemeService'
import { hexToRGBA } from '@Style/Utils'
import React, { useContext, useEffect, useMemo, useState } from 'react'
import { LayoutChangeEvent } from 'react-native'
import Icon from 'react-native-vector-icons/Ionicons'
import { ThemeContext } from 'styled-components'
import { Compose } from './Compose/Compose'
import { Notes } from './Notes/Notes'
import { ComposeContainer, Container, ExpandTouchable, iconNames, NotesContainer } from './Root.styled'
export const Root = () => {
const application = useContext(ApplicationContext)
const theme = useContext(ThemeContext)
const [isLocked] = useIsLocked()
const [, setWidth] = useState<number | undefined>(undefined)
const [height, setHeight] = useState<number | undefined>(undefined)
const [, setX] = useState<number | undefined>(undefined)
const [noteListCollapsed, setNoteListCollapsed] = useState<boolean>(false)
const [activeNoteView, setActiveNoteView] = useState<NoteViewController | undefined>()
const [isInTabletMode, setIsInTabletMode] = useState<boolean | undefined>(application?.getAppState().isInTabletMode)
const [keyboardHeight, setKeyboardHeight] = useState<number | undefined>(undefined)
useEffect(() => {
const removeStateObserver = application?.getAppState().addStateChangeObserver((state) => {
if (state === AppStateType.GainingFocus) {
void application.sync.sync()
}
})
const removeApplicationStateEventHandler = application
?.getAppState()
.addStateEventObserver((event: AppStateEventType, data: TabletModeChangeData | undefined) => {
if (event === AppStateEventType.TabletModeChange) {
const eventData = data as TabletModeChangeData
if (eventData.new_isInTabletMode && !eventData.old_isInTabletMode) {
setIsInTabletMode(true)
} else if (!eventData.new_isInTabletMode && eventData.old_isInTabletMode) {
setIsInTabletMode(false)
}
}
if (event === AppStateEventType.KeyboardChangeEvent) {
// need to refresh the height of the keyboard when it opens so that we can change the position
// of the sidebar collapse icon
if (application?.getAppState().isInTabletMode) {
setKeyboardHeight(application?.getAppState().getKeyboardHeight())
}
}
})
const removeNoteObserver = application?.editorGroup.addActiveControllerChangeObserver((activeController) => {
if (activeController instanceof NoteViewController) {
setActiveNoteView(activeController)
} else {
setActiveNoteView(undefined)
}
})
return () => {
if (removeApplicationStateEventHandler) {
removeApplicationStateEventHandler()
}
if (removeStateObserver) {
removeStateObserver()
}
if (removeNoteObserver) {
removeNoteObserver()
}
}
}, [application])
const collapseIconName = useMemo(() => {
const collapseIconPrefix = ThemeService.platformIconPrefix()
return collapseIconPrefix + '-' + iconNames[collapseIconPrefix][noteListCollapsed ? 0 : 1]
}, [noteListCollapsed])
const onLayout = (e: LayoutChangeEvent) => {
const tempWidth = e.nativeEvent.layout.width
/**
If you're in tablet mode, but on an iPad where this app is running side by
side by another app, we only want to show the Compose window and not the
list, because there isn't enough space.
*/
const MinWidthToSplit = 450
if (application?.getAppState().isTabletDevice) {
if (tempWidth < MinWidthToSplit) {
application?.getAppState().setTabletModeEnabled(false)
} else {
application?.getAppState().setTabletModeEnabled(true)
}
}
setWidth(tempWidth)
setHeight(e.nativeEvent.layout.height)
setX(e.nativeEvent.layout.x)
setIsInTabletMode(application?.getAppState().isInTabletMode)
setKeyboardHeight(application?.getAppState().getKeyboardHeight())
}
const toggleNoteList = () => {
setNoteListCollapsed((value) => !value)
}
const collapseIconBottomPosition = (keyboardHeight ?? 0) > (height ?? 0) / 2 ? (keyboardHeight ?? 0) + 40 : '50%'
if (isLocked) {
return null
}
return (
<Container testID="rootView" onLayout={onLayout}>
<NotesContainer notesListCollapsed={noteListCollapsed} isInTabletMode={isInTabletMode}>
<Notes keyboardHeight={keyboardHeight} isInTabletMode={isInTabletMode} />
</NotesContainer>
{activeNoteView && !activeNoteView.dealloced && isInTabletMode && (
<ComposeContainer>
<Compose noteUuid={activeNoteView.item.uuid} />
<ExpandTouchable style={{ bottom: collapseIconBottomPosition }} onPress={toggleNoteList}>
<Icon name={collapseIconName} size={24} color={hexToRGBA(theme.stylekitInfoColor, 0.85)} />
</ExpandTouchable>
</ComposeContainer>
)}
</Container>
)
}