From a3d2db96457d87b7c9a874d699e51dd5f98750c1 Mon Sep 17 00:00:00 2001 From: Paul Frazee Date: Thu, 26 Jan 2023 12:53:46 -0600 Subject: Get MVP of web app running --- src/App.web.tsx | 7 +- src/view/com/login/CreateAccount.tsx | 6 +- src/view/com/login/Signin.tsx | 10 +- src/view/com/util/forms/DropdownButton.tsx | 6 +- src/view/shell/desktop-web/index.tsx | 35 ------- src/view/shell/desktop-web/left-column.tsx | 57 ----------- src/view/shell/desktop-web/right-column.tsx | 19 ---- src/view/shell/web/index.tsx | 140 ++++++++++++++++++++++++++++ src/view/shell/web/left-column.tsx | 57 +++++++++++ src/view/shell/web/right-column.tsx | 19 ++++ 10 files changed, 234 insertions(+), 122 deletions(-) delete mode 100644 src/view/shell/desktop-web/index.tsx delete mode 100644 src/view/shell/desktop-web/left-column.tsx delete mode 100644 src/view/shell/desktop-web/right-column.tsx create mode 100644 src/view/shell/web/index.tsx create mode 100644 src/view/shell/web/left-column.tsx create mode 100644 src/view/shell/web/right-column.tsx (limited to 'src') diff --git a/src/App.web.tsx b/src/App.web.tsx index 0be05486c..67ef680a5 100644 --- a/src/App.web.tsx +++ b/src/App.web.tsx @@ -1,7 +1,8 @@ import React, {useState, useEffect} from 'react' +import {SafeAreaProvider} from 'react-native-safe-area-context' import * as view from './view/index' import {RootStoreModel, setupState, RootStoreProvider} from './state' -import {DesktopWebShell} from './view/shell/desktop-web' +import {WebShell} from './view/shell/web' // import Toast from 'react-native-root-toast' TODO function App() { @@ -22,7 +23,9 @@ function App() { return ( - + + + ) // TODO diff --git a/src/view/com/login/CreateAccount.tsx b/src/view/com/login/CreateAccount.tsx index be5074eee..dbb3ab52f 100644 --- a/src/view/com/login/CreateAccount.tsx +++ b/src/view/com/login/CreateAccount.tsx @@ -15,7 +15,7 @@ import { } from '@fortawesome/react-native-fontawesome' import {ComAtprotoAccountCreate} from '@atproto/api' import * as EmailValidator from 'email-validator' -import {useAnalytics} from '@segment/analytics-react-native' +// import {useAnalytics} from '@segment/analytics-react-native' TODO import {LogoTextHero} from './Logo' import {Picker} from '../util/Picker' import {TextLink} from '../util/Link' @@ -32,7 +32,7 @@ import {ServerInputModal} from '../../../state/models/shell-ui' import {usePalette} from '../../lib/hooks/usePalette' export const CreateAccount = ({onPressBack}: {onPressBack: () => void}) => { - const {track} = useAnalytics() + // const {track} = useAnalytics() TODO const pal = usePalette('default') const store = useStores() const [isProcessing, setIsProcessing] = useState(false) @@ -109,7 +109,7 @@ export const CreateAccount = ({onPressBack}: {onPressBack: () => void}) => { password, inviteCode, }) - track('Create Account') + // track('Create Account') TODO } catch (e: any) { let errMsg = e.toString() if (e instanceof ComAtprotoAccountCreate.InvalidInviteCodeError) { diff --git a/src/view/com/login/Signin.tsx b/src/view/com/login/Signin.tsx index 1c8a54ad8..8a260a9ba 100644 --- a/src/view/com/login/Signin.tsx +++ b/src/view/com/login/Signin.tsx @@ -14,7 +14,7 @@ import { } from '@fortawesome/react-native-fontawesome' import * as EmailValidator from 'email-validator' import {sessionClient as AtpApi, SessionServiceClient} from '@atproto/api' -import {useAnalytics} from '@segment/analytics-react-native' +// import {useAnalytics} from '@segment/analytics-react-native' TODO import {LogoTextHero} from './Logo' import {Text} from '../util/text/Text' import {UserAvatar} from '../util/UserAvatar' @@ -153,7 +153,7 @@ const ChooseAccountForm = ({ onSelectAccount: (account?: AccountData) => void onPressBack: () => void }) => { - const {track} = useAnalytics() + // const {track} = useAnalytics() TODO const pal = usePalette('default') const [isProcessing, setIsProcessing] = React.useState(false) @@ -161,7 +161,7 @@ const ChooseAccountForm = ({ if (account.accessJwt && account.refreshJwt) { setIsProcessing(true) if (await store.session.resumeSession(account)) { - track('Sign In', {resumedSession: true}) + // track('Sign In', {resumedSession: true}) TODO setIsProcessing(false) return } @@ -261,7 +261,7 @@ const LoginForm = ({ onPressBack: () => void onPressForgotPassword: () => void }) => { - const {track} = useAnalytics() + // const {track} = useAnalytics() TODO const pal = usePalette('default') const [isProcessing, setIsProcessing] = useState(false) const [handle, setHandle] = useState(initialHandle) @@ -302,7 +302,7 @@ const LoginForm = ({ handle: fullHandle, password, }) - track('Sign In', {resumedSession: false}) + // track('Sign In', {resumedSession: false}) TODO } catch (e: any) { const errMsg = e.toString() store.log.warn('Failed to login', e) diff --git a/src/view/com/util/forms/DropdownButton.tsx b/src/view/com/util/forms/DropdownButton.tsx index 1fa03f4c7..f911529d2 100644 --- a/src/view/com/util/forms/DropdownButton.tsx +++ b/src/view/com/util/forms/DropdownButton.tsx @@ -76,7 +76,11 @@ export function DropdownButton({ onPress={onPress} hitSlop={HITSLOP} // Fix an issue where specific references cause runtime error in jest environment - ref={process.env.JEST_WORKER_ID != null ? null : ref}> + ref={ + typeof process !== 'undefined' && process.env.JEST_WORKER_ID != null + ? null + : ref + }> {children} ) diff --git a/src/view/shell/desktop-web/index.tsx b/src/view/shell/desktop-web/index.tsx deleted file mode 100644 index 194954349..000000000 --- a/src/view/shell/desktop-web/index.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import React from 'react' -import {observer} from 'mobx-react-lite' -import {View, StyleSheet} from 'react-native' -import {DesktopLeftColumn} from './left-column' -import {DesktopRightColumn} from './right-column' -import {useStores} from '../../../state' - -export const DesktopWebShell: React.FC = observer(({children}) => { - const store = useStores() - return ( - - {store.session.hasSession ? ( - <> - - {children} - - - ) : ( - {children} - )} - - ) -}) - -const styles = StyleSheet.create({ - outerContainer: { - height: '100%', - }, - innerContainer: { - marginLeft: 'auto', - marginRight: 'auto', - width: '600px', - height: '100%', - }, -}) diff --git a/src/view/shell/desktop-web/left-column.tsx b/src/view/shell/desktop-web/left-column.tsx deleted file mode 100644 index 3ce6c2eca..000000000 --- a/src/view/shell/desktop-web/left-column.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import React from 'react' -import {View} from 'react-native' - -// export const NavItem: React.FC<{label: string; screen: string}> = ({ -// label, -// screen, -// }) => { -// const Link = <> // TODO -// return ( -// -// [ -// // @ts-ignore it does exist! (react-native-web) -prf -// state.hovered && styles.navItemHovered, -// ]}> -// -// {label} -// -// -// -// ) -// } - -export const DesktopLeftColumn: React.FC = () => { - // TODO - return - // return ( - // - // - // - // - // - // ) -} - -// const styles = StyleSheet.create({ -// container: { -// position: 'absolute', -// left: 'calc(50vw - 500px)', -// width: '200px', -// height: '100%', -// }, -// navItemHovered: { -// backgroundColor: 'gray', -// }, -// navItemLink: { -// padding: '1rem', -// }, -// navItemLinkSelected: { -// color: 'blue', -// }, -// }) diff --git a/src/view/shell/desktop-web/right-column.tsx b/src/view/shell/desktop-web/right-column.tsx deleted file mode 100644 index 5fe65cac8..000000000 --- a/src/view/shell/desktop-web/right-column.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import React from 'react' -import {Text, View, StyleSheet} from 'react-native' - -export const DesktopRightColumn: React.FC = () => { - return ( - - Right Column - - ) -} - -const styles = StyleSheet.create({ - container: { - position: 'absolute', - right: 'calc(50vw - 500px)', - width: '200px', - height: '100%', - }, -}) diff --git a/src/view/shell/web/index.tsx b/src/view/shell/web/index.tsx new file mode 100644 index 000000000..9032eb884 --- /dev/null +++ b/src/view/shell/web/index.tsx @@ -0,0 +1,140 @@ +import React from 'react' +import {observer} from 'mobx-react-lite' +import {View, StyleSheet, Text} from 'react-native' +import {useStores} from '../../../state' +import {match, MatchResult} from '../../routes' +// import {DesktopLeftColumn} from './left-column' +// import {DesktopRightColumn} from './right-column' +import {Login} from '../../screens/Login' +import {ErrorBoundary} from '../../com/util/ErrorBoundary' +import {usePalette} from '../../lib/hooks/usePalette' +import {s} from '../../lib/styles' + +export const WebShell: React.FC = observer(() => { + const pal = usePalette('default') + const store = useStores() + const screenRenderDesc = constructScreenRenderDesc(store.nav) + + if (!store.session.hasSession) { + return ( + + + + + + ) + } + + return ( + + + {screenRenderDesc.screens.map(({Com, navIdx, params, key, current}) => ( + + + + + + ))} + + + ) + // TODO + // + // + // store.shell.closeComposer()} + // winHeight={winDim.height} + // replyTo={store.shell.composerOpts?.replyTo} + // imagesOpen={store.shell.composerOpts?.imagesOpen} + // onPost={store.shell.composerOpts?.onPost} + // /> + // return ( + // + // {store.session.hasSession ? ( + // <> + // + // + // Hello, world! (Logged in) + // {children} + // + // + // + // ) : ( + // + // Hello, world! (Logged out) + // {children} + // + // )} + // + // ) +}) + +/** + * This method produces the information needed by the shell to + * render the current screens with screen-caching behaviors. + */ +type ScreenRenderDesc = MatchResult & { + key: string + navIdx: string + current: boolean + previous: boolean + isNewTab: boolean +} +function constructScreenRenderDesc(nav: NavigationModel): { + icon: IconProp + hasNewTab: boolean + screens: ScreenRenderDesc[] +} { + let hasNewTab = false + let icon: IconProp = 'magnifying-glass' + let screens: ScreenRenderDesc[] = [] + for (const tab of nav.tabs) { + const tabScreens = [ + ...tab.getBackList(5), + Object.assign({}, tab.current, {index: tab.index}), + ] + const parsedTabScreens = tabScreens.map(screen => { + const isCurrent = nav.isCurrentScreen(tab.id, screen.index) + const isPrevious = nav.isCurrentScreen(tab.id, screen.index + 1) + const matchRes = match(screen.url) + if (isCurrent) { + icon = matchRes.icon + } + hasNewTab = hasNewTab || tab.isNewTab + return Object.assign(matchRes, { + key: `t${tab.id}-s${screen.index}`, + navIdx: `${tab.id}-${screen.id}`, + current: isCurrent, + previous: isPrevious, + isNewTab: tab.isNewTab, + }) as ScreenRenderDesc + }) + screens = screens.concat(parsedTabScreens) + } + return { + icon, + hasNewTab, + screens, + } +} + +const styles = StyleSheet.create({ + outerContainer: { + height: '100%', + }, + innerContainer: { + marginLeft: 'auto', + marginRight: 'auto', + width: '600px', + height: '100%', + }, + visible: { + display: 'flex', + }, + hidden: { + display: 'none', + }, +}) diff --git a/src/view/shell/web/left-column.tsx b/src/view/shell/web/left-column.tsx new file mode 100644 index 000000000..3ce6c2eca --- /dev/null +++ b/src/view/shell/web/left-column.tsx @@ -0,0 +1,57 @@ +import React from 'react' +import {View} from 'react-native' + +// export const NavItem: React.FC<{label: string; screen: string}> = ({ +// label, +// screen, +// }) => { +// const Link = <> // TODO +// return ( +// +// [ +// // @ts-ignore it does exist! (react-native-web) -prf +// state.hovered && styles.navItemHovered, +// ]}> +// +// {label} +// +// +// +// ) +// } + +export const DesktopLeftColumn: React.FC = () => { + // TODO + return + // return ( + // + // + // + // + // + // ) +} + +// const styles = StyleSheet.create({ +// container: { +// position: 'absolute', +// left: 'calc(50vw - 500px)', +// width: '200px', +// height: '100%', +// }, +// navItemHovered: { +// backgroundColor: 'gray', +// }, +// navItemLink: { +// padding: '1rem', +// }, +// navItemLinkSelected: { +// color: 'blue', +// }, +// }) diff --git a/src/view/shell/web/right-column.tsx b/src/view/shell/web/right-column.tsx new file mode 100644 index 000000000..5fe65cac8 --- /dev/null +++ b/src/view/shell/web/right-column.tsx @@ -0,0 +1,19 @@ +import React from 'react' +import {Text, View, StyleSheet} from 'react-native' + +export const DesktopRightColumn: React.FC = () => { + return ( + + Right Column + + ) +} + +const styles = StyleSheet.create({ + container: { + position: 'absolute', + right: 'calc(50vw - 500px)', + width: '200px', + height: '100%', + }, +}) -- cgit 1.4.1