From 72f1ca3954b8a5c7916f448599cbe7d2c1214691 Mon Sep 17 00:00:00 2001 From: Paul Frazee Date: Thu, 26 Jan 2023 21:03:50 -0600 Subject: [PATCH] Update login/create-account and onboard for web --- public/index.html | 5 + src/view/com/onboard/FeatureExplainer.web.tsx | 203 ++++++++++++++++++ src/view/com/onboard/Follows.web.tsx | 47 ++++ src/view/screens/Login.web.tsx | 163 ++++++++++++++ src/view/shell/web/index.tsx | 16 +- 5 files changed, 428 insertions(+), 6 deletions(-) create mode 100644 src/view/com/onboard/FeatureExplainer.web.tsx create mode 100644 src/view/com/onboard/Follows.web.tsx create mode 100644 src/view/screens/Login.web.tsx diff --git a/public/index.html b/public/index.html index c01f68c303..50a27bfafe 100644 --- a/public/index.html +++ b/public/index.html @@ -12,6 +12,11 @@ /* These styles make the root element full-height */ #app-root { display:flex; height:100%; } + /* Remove focus state on inputs */ + input:focus { + outline: 0; + } + /* These styles are for src/view/com/modals/WebModal */ div[data-modal-overlay] { position: fixed; diff --git a/src/view/com/onboard/FeatureExplainer.web.tsx b/src/view/com/onboard/FeatureExplainer.web.tsx new file mode 100644 index 0000000000..83d460808f --- /dev/null +++ b/src/view/com/onboard/FeatureExplainer.web.tsx @@ -0,0 +1,203 @@ +import React, {useState} from 'react' +import { + Animated, + Image, + SafeAreaView, + StyleSheet, + TouchableOpacity, + useWindowDimensions, + View, +} from 'react-native' +import {TabView, SceneMap, Route, TabBarProps} from 'react-native-tab-view' +import { + FontAwesomeIcon, + FontAwesomeIconStyle, +} from '@fortawesome/react-native-fontawesome' +import {CenteredView} from '../util/Views.web' +import {Text} from '../util/text/Text' +import {useStores} from '../../../state' +import {s, colors} from '../../lib/styles' +import {TABS_EXPLAINER} from '../../lib/assets' +import {TABS_ENABLED} from '../../../build-flags' + +const ROUTES = TABS_ENABLED + ? [ + {key: 'intro', title: 'Intro'}, + {key: 'tabs', title: 'Tabs'}, + ] + : [{key: 'intro', title: 'Intro'}] + +const Intro = () => ( + + + Welcome to{' '} + + Bluesky + + + + This is an early beta. Your feedback is appreciated! + + +) + +const Tabs = () => ( + + + + + + + Tabs + + Never lose your place! Long-press to open posts and profiles in a new tab. + + + + + +) + +const SCENE_MAP = { + intro: Intro, + tabs: Tabs, +} +const renderScene = SceneMap(SCENE_MAP) + +export const FeatureExplainer = () => { + const layout = useWindowDimensions() + const store = useStores() + const [index, setIndex] = useState(0) + + const onPressSkip = () => store.onboard.next() + const onPressNext = () => { + if (index >= ROUTES.length - 1) { + store.onboard.next() + } else { + setIndex(index + 1) + } + } + + const renderTabBar = (props: TabBarProps) => { + const inputRange = props.navigationState.routes.map((x, i) => i) + return ( + + + {props.navigationState.routes.map((route, i) => { + const opacity = props.position.interpolate({ + inputRange, + outputRange: inputRange.map(inputIndex => + inputIndex === i ? 1 : 0.5, + ), + }) + + return ( + setIndex(i)}> + ° + + ) + })} + + + ) + } + + const FirstExplainer = SCENE_MAP[ROUTES[0]?.key as keyof typeof SCENE_MAP] + return ( + + {ROUTES.length > 1 ? ( + + ) : FirstExplainer ? ( + + ) : ( + + )} + + + Skip + + + Next + + + + ) +} + +const styles = StyleSheet.create({ + container: { + height: '100%', + justifyContent: 'center', + paddingBottom: '10%', + }, + + tabBar: { + flexDirection: 'row', + }, + tabItem: { + alignItems: 'center', + padding: 16, + }, + + explainer: { + paddingHorizontal: 16, + }, + explainerIcon: { + flexDirection: 'row', + }, + explainerHeading: { + fontSize: 42, + fontWeight: 'bold', + textAlign: 'center', + marginBottom: 16, + }, + explainerHeadingIntro: { + lineHeight: 40, + }, + explainerHeadingBrand: {fontSize: 56}, + explainerDesc: { + fontSize: 18, + textAlign: 'center', + marginBottom: 16, + color: colors.gray5, + }, + explainerDescIntro: {fontSize: 24}, + explainerImg: { + resizeMode: 'contain', + maxWidth: '100%', + maxHeight: 330, + }, + + footer: { + flexDirection: 'row', + justifyContent: 'center', + paddingTop: 24, + }, + footerBtn: { + color: colors.blue3, + fontSize: 19, + paddingHorizontal: 36, + paddingVertical: 8, + }, + footerBtnNext: { + marginLeft: 10, + borderWidth: 1, + borderColor: colors.blue3, + borderRadius: 6, + }, +}) diff --git a/src/view/com/onboard/Follows.web.tsx b/src/view/com/onboard/Follows.web.tsx new file mode 100644 index 0000000000..50e119e49c --- /dev/null +++ b/src/view/com/onboard/Follows.web.tsx @@ -0,0 +1,47 @@ +import React from 'react' +import {SafeAreaView, StyleSheet, TouchableOpacity, View} from 'react-native' +import {observer} from 'mobx-react-lite' +import {SuggestedFollows} from '../discover/SuggestedFollows' +import {CenteredView} from '../util/Views.web' +import {Text} from '../util/text/Text' +import {useStores} from '../../../state' +import {s, colors} from '../../lib/styles' + +export const Follows = observer(() => { + const store = useStores() + + const onNoSuggestions = () => { + // no suggestions, bounce from this view + store.onboard.next() + } + const onPressNext = () => store.onboard.next() + + return ( + + + + Follow these people to see their posts in your feed + + + Next » + + + + + ) +}) + +const styles = StyleSheet.create({ + container: { + flex: 1, + }, + title: { + fontSize: 24, + fontWeight: 'bold', + }, + + header: { + paddingTop: 30, + paddingBottom: 40, + }, +}) diff --git a/src/view/screens/Login.web.tsx b/src/view/screens/Login.web.tsx new file mode 100644 index 0000000000..77149090cb --- /dev/null +++ b/src/view/screens/Login.web.tsx @@ -0,0 +1,163 @@ +import React, {useState} from 'react' +import { + Image, + SafeAreaView, + StyleSheet, + TouchableOpacity, + View, +} from 'react-native' +import {observer} from 'mobx-react-lite' +import {CenteredView} from '../com/util/Views' +import {Signin} from '../com/login/Signin' +import {CreateAccount} from '../com/login/CreateAccount' +import {Text} from '../com/util/text/Text' +import {ErrorBoundary} from '../com/util/ErrorBoundary' +import {colors} from '../lib/styles' +import {usePalette} from '../lib/hooks/usePalette' +import {CLOUD_SPLASH} from '../lib/assets' + +enum ScreenState { + S_SigninOrCreateAccount, + S_Signin, + S_CreateAccount, +} + +const SigninOrCreateAccount = ({ + onPressSignin, + onPressCreateAccount, +}: { + onPressSignin: () => void + onPressCreateAccount: () => void +}) => { + const pal = usePalette('default') + return ( + <> + + + Bluesky + [ private beta ] + + + + + New account + + + Sign in + + + + ) +} + +export const Login = observer(() => { + const pal = usePalette('default') + const [screenState, setScreenState] = useState( + ScreenState.S_SigninOrCreateAccount, + ) + + if (screenState === ScreenState.S_SigninOrCreateAccount) { + return ( + + + setScreenState(ScreenState.S_Signin)} + onPressCreateAccount={() => + setScreenState(ScreenState.S_CreateAccount) + } + /> + + + ) + } + + return ( + + + + {screenState === ScreenState.S_Signin ? ( + + setScreenState(ScreenState.S_SigninOrCreateAccount) + } + /> + ) : undefined} + {screenState === ScreenState.S_CreateAccount ? ( + + setScreenState(ScreenState.S_SigninOrCreateAccount) + } + /> + ) : undefined} + + + + ) +}) + +const styles = StyleSheet.create({ + container: { + height: '100%', + }, + containerBorder: { + borderLeftWidth: 1, + borderRightWidth: 1, + }, + vertCenter: { + justifyContent: 'center', + }, + bgImg: { + position: 'absolute', + top: 0, + left: 0, + width: '100%', + height: '100%', + }, + heroText: { + backgroundColor: colors.white, + paddingTop: 10, + paddingBottom: 20, + }, + btns: { + flexDirection: 'row', + paddingTop: 40, + }, + title: { + textAlign: 'center', + color: colors.blue3, + fontSize: 68, + fontWeight: 'bold', + }, + subtitle: { + textAlign: 'center', + color: colors.blue3, + fontSize: 18, + }, + btn: { + flex: 1, + borderRadius: 4, + paddingVertical: 16, + marginBottom: 20, + marginHorizontal: 20, + borderWidth: 1, + borderColor: colors.blue3, + }, + btnLabel: { + textAlign: 'center', + fontSize: 21, + fontWeight: '500', + color: colors.blue3, + }, +}) diff --git a/src/view/shell/web/index.tsx b/src/view/shell/web/index.tsx index fedc9c3d6b..1059aa280d 100644 --- a/src/view/shell/web/index.tsx +++ b/src/view/shell/web/index.tsx @@ -5,6 +5,7 @@ import {useStores} from '../../../state' import {match, MatchResult} from '../../routes' import {DesktopLeftColumn} from './left-column' import {DesktopRightColumn} from './right-column' +import {Onboard} from '../../screens/Onboard' import {Login} from '../../screens/Login' import {ErrorBoundary} from '../../com/util/ErrorBoundary' import {usePalette} from '../../lib/hooks/usePalette' @@ -22,6 +23,15 @@ export const WebShell: React.FC = observer(() => { ) } + if (store.onboard.isOnboarding) { + return ( + + + + + + ) + } return ( @@ -104,12 +114,6 @@ const styles = StyleSheet.create({ outerContainer: { height: '100%', }, - innerContainer: { - marginLeft: 'auto', - marginRight: 'auto', - width: '600px', - height: '100%', - }, visible: { display: 'flex', },