Change web shell to use permanent header
parent
e828f380e7
commit
9bf48ed595
|
@ -1,104 +1,9 @@
|
||||||
import React from 'react'
|
|
||||||
import {observer} from 'mobx-react-lite'
|
import {observer} from 'mobx-react-lite'
|
||||||
import {StyleSheet, TouchableOpacity, View} from 'react-native'
|
|
||||||
import {Text} from './text/Text'
|
|
||||||
import {Link} from './Link'
|
|
||||||
import {usePalette} from 'lib/hooks/usePalette'
|
|
||||||
import {useStores} from 'state/index'
|
|
||||||
import {ComposeIcon, MagnifyingGlassIcon} from 'lib/icons'
|
|
||||||
import {colors} from 'lib/styles'
|
|
||||||
|
|
||||||
export const ViewHeader = observer(function ViewHeader({
|
export const ViewHeader = observer(function ViewHeader(_opts: {
|
||||||
title,
|
|
||||||
}: {
|
|
||||||
title: string
|
title: string
|
||||||
canGoBack?: boolean
|
canGoBack?: boolean
|
||||||
}) {
|
}) {
|
||||||
const store = useStores()
|
// TODO
|
||||||
const pal = usePalette('default')
|
return null
|
||||||
const onPressCompose = () => store.shell.openComposer({})
|
|
||||||
return (
|
|
||||||
<View style={[styles.header, pal.borderDark, pal.view]}>
|
|
||||||
<View style={styles.titleContainer} pointerEvents="none">
|
|
||||||
<Text type="title-2xl" style={[pal.text, styles.title]}>
|
|
||||||
{title}
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
<TouchableOpacity style={[styles.newPostBtn]} onPress={onPressCompose}>
|
|
||||||
<View style={styles.newPostBtnIconWrapper}>
|
|
||||||
<ComposeIcon
|
|
||||||
size={16}
|
|
||||||
strokeWidth={1.5}
|
|
||||||
style={styles.newPostBtnLabel}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
<Text type="md" style={styles.newPostBtnLabel}>
|
|
||||||
New Post
|
|
||||||
</Text>
|
|
||||||
</TouchableOpacity>
|
|
||||||
<Link href="/search" style={[pal.view, pal.borderDark, styles.search]}>
|
|
||||||
<MagnifyingGlassIcon
|
|
||||||
size={18}
|
|
||||||
style={[pal.textLight, styles.searchIconWrapper]}
|
|
||||||
/>
|
|
||||||
<Text type="md-thin" style={pal.textLight}>
|
|
||||||
Search
|
|
||||||
</Text>
|
|
||||||
</Link>
|
|
||||||
</View>
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
|
||||||
header: {
|
|
||||||
flexDirection: 'row',
|
|
||||||
alignItems: 'center',
|
|
||||||
paddingTop: 24,
|
|
||||||
paddingBottom: 18,
|
|
||||||
paddingLeft: 30,
|
|
||||||
paddingRight: 40,
|
|
||||||
marginLeft: 300,
|
|
||||||
borderBottomWidth: 1,
|
|
||||||
},
|
|
||||||
|
|
||||||
titleContainer: {
|
|
||||||
marginRight: 'auto',
|
|
||||||
},
|
|
||||||
title: {
|
|
||||||
fontWeight: 'bold',
|
|
||||||
},
|
|
||||||
|
|
||||||
search: {
|
|
||||||
flexDirection: 'row',
|
|
||||||
alignItems: 'center',
|
|
||||||
width: 300,
|
|
||||||
borderRadius: 20,
|
|
||||||
paddingVertical: 8,
|
|
||||||
paddingHorizontal: 10,
|
|
||||||
borderWidth: 1,
|
|
||||||
},
|
|
||||||
searchIconWrapper: {
|
|
||||||
flexDirection: 'row',
|
|
||||||
width: 30,
|
|
||||||
justifyContent: 'center',
|
|
||||||
marginRight: 2,
|
|
||||||
},
|
|
||||||
|
|
||||||
newPostBtn: {
|
|
||||||
flexDirection: 'row',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
borderRadius: 24,
|
|
||||||
paddingTop: 8,
|
|
||||||
paddingBottom: 9,
|
|
||||||
paddingHorizontal: 18,
|
|
||||||
backgroundColor: colors.blue3,
|
|
||||||
marginRight: 10,
|
|
||||||
},
|
|
||||||
newPostBtnIconWrapper: {
|
|
||||||
marginRight: 8,
|
|
||||||
},
|
|
||||||
newPostBtnLabel: {
|
|
||||||
color: colors.white,
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
import React from 'react'
|
||||||
|
import {observer} from 'mobx-react-lite'
|
||||||
|
import {StyleSheet, TouchableOpacity, View} from 'react-native'
|
||||||
|
import {Text} from 'view/com/util/text/Text'
|
||||||
|
import {Link} from 'view/com/util/Link'
|
||||||
|
import {usePalette} from 'lib/hooks/usePalette'
|
||||||
|
import {useStores} from 'state/index'
|
||||||
|
import {ComposeIcon, MagnifyingGlassIcon} from 'lib/icons'
|
||||||
|
import {colors} from 'lib/styles'
|
||||||
|
|
||||||
|
export const DesktopHeader = observer(function DesktopHeader({}: {
|
||||||
|
canGoBack?: boolean
|
||||||
|
}) {
|
||||||
|
const store = useStores()
|
||||||
|
const pal = usePalette('default')
|
||||||
|
const onPressCompose = () => store.shell.openComposer({})
|
||||||
|
return (
|
||||||
|
<View style={[styles.header, pal.borderDark, pal.view]}>
|
||||||
|
<View style={styles.titleContainer} pointerEvents="none">
|
||||||
|
<Text type="title-2xl" style={[pal.text, styles.title]}>
|
||||||
|
Bluesky
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<TouchableOpacity style={[styles.newPostBtn]} onPress={onPressCompose}>
|
||||||
|
<View style={styles.newPostBtnIconWrapper}>
|
||||||
|
<ComposeIcon
|
||||||
|
size={16}
|
||||||
|
strokeWidth={2}
|
||||||
|
style={styles.newPostBtnLabel}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<Text type="md" style={styles.newPostBtnLabel}>
|
||||||
|
New Post
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Link href="/search" style={[pal.view, pal.borderDark, styles.search]}>
|
||||||
|
<MagnifyingGlassIcon
|
||||||
|
size={18}
|
||||||
|
style={[pal.textLight, styles.searchIconWrapper]}
|
||||||
|
/>
|
||||||
|
<Text type="md-thin" style={pal.textLight}>
|
||||||
|
Search
|
||||||
|
</Text>
|
||||||
|
</Link>
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
header: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
paddingTop: 18,
|
||||||
|
paddingBottom: 18,
|
||||||
|
paddingLeft: 30,
|
||||||
|
paddingRight: 40,
|
||||||
|
borderBottomWidth: 1,
|
||||||
|
},
|
||||||
|
|
||||||
|
titleContainer: {
|
||||||
|
marginRight: 'auto',
|
||||||
|
},
|
||||||
|
title: {},
|
||||||
|
|
||||||
|
search: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
width: 300,
|
||||||
|
borderRadius: 20,
|
||||||
|
paddingVertical: 8,
|
||||||
|
paddingHorizontal: 10,
|
||||||
|
borderWidth: 1,
|
||||||
|
},
|
||||||
|
searchIconWrapper: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
width: 30,
|
||||||
|
justifyContent: 'center',
|
||||||
|
marginRight: 2,
|
||||||
|
},
|
||||||
|
|
||||||
|
newPostBtn: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
borderRadius: 24,
|
||||||
|
paddingTop: 8,
|
||||||
|
paddingBottom: 9,
|
||||||
|
paddingHorizontal: 18,
|
||||||
|
backgroundColor: colors.blue3,
|
||||||
|
marginRight: 10,
|
||||||
|
},
|
||||||
|
newPostBtnIconWrapper: {
|
||||||
|
marginRight: 8,
|
||||||
|
},
|
||||||
|
newPostBtnLabel: {
|
||||||
|
color: colors.white,
|
||||||
|
},
|
||||||
|
})
|
|
@ -1,5 +1,5 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {Pressable, StyleSheet, TouchableOpacity, View} from 'react-native'
|
import {Pressable, StyleSheet, View} from 'react-native'
|
||||||
import {observer} from 'mobx-react-lite'
|
import {observer} from 'mobx-react-lite'
|
||||||
import {Link} from '../../com/util/Link'
|
import {Link} from '../../com/util/Link'
|
||||||
import {Text} from '../../com/util/text/Text'
|
import {Text} from '../../com/util/text/Text'
|
||||||
|
@ -15,7 +15,6 @@ import {
|
||||||
BellIconSolid,
|
BellIconSolid,
|
||||||
MagnifyingGlassIcon,
|
MagnifyingGlassIcon,
|
||||||
CogIcon,
|
CogIcon,
|
||||||
ComposeIcon,
|
|
||||||
} from 'lib/icons'
|
} from 'lib/icons'
|
||||||
|
|
||||||
interface NavItemProps {
|
interface NavItemProps {
|
||||||
|
@ -40,7 +39,7 @@ export const NavItem = observer(
|
||||||
// @ts-ignore Pressable state differs for RNW -prf
|
// @ts-ignore Pressable state differs for RNW -prf
|
||||||
state.hovered && hoverBg,
|
state.hovered && hoverBg,
|
||||||
]}>
|
]}>
|
||||||
<Link style={[styles.navItem, isCurrent && hoverBg]} href={href}>
|
<Link style={[styles.navItem]} href={href}>
|
||||||
<View
|
<View
|
||||||
style={[
|
style={[
|
||||||
styles.navItemIconWrapper,
|
styles.navItemIconWrapper,
|
||||||
|
@ -66,10 +65,6 @@ export const NavItem = observer(
|
||||||
|
|
||||||
export const DesktopLeftColumn = observer(() => {
|
export const DesktopLeftColumn = observer(() => {
|
||||||
const store = useStores()
|
const store = useStores()
|
||||||
const containerBg = useColorSchemeStyle(
|
|
||||||
styles.containerBgLight,
|
|
||||||
styles.containerBgDark,
|
|
||||||
)
|
|
||||||
const pal = usePalette('default')
|
const pal = usePalette('default')
|
||||||
const avi = (
|
const avi = (
|
||||||
<UserAvatar
|
<UserAvatar
|
||||||
|
@ -80,11 +75,8 @@ export const DesktopLeftColumn = observer(() => {
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
return (
|
return (
|
||||||
<View style={[styles.container, containerBg, pal.border]}>
|
<View style={[styles.container]}>
|
||||||
<View style={styles.main}>
|
<View style={styles.main}>
|
||||||
<Link style={styles.logo} href="/">
|
|
||||||
<Text type="title-xl">Bluesky</Text>
|
|
||||||
</Link>
|
|
||||||
<NavItem
|
<NavItem
|
||||||
href="/"
|
href="/"
|
||||||
label="Home"
|
label="Home"
|
||||||
|
@ -110,8 +102,7 @@ export const DesktopLeftColumn = observer(() => {
|
||||||
icon={<CogIcon strokeWidth={2} size={21} />}
|
icon={<CogIcon strokeWidth={2} size={21} />}
|
||||||
iconFilled={<CogIcon strokeWidth={2.5} size={21} />}
|
iconFilled={<CogIcon strokeWidth={2.5} size={21} />}
|
||||||
/>
|
/>
|
||||||
</View>
|
<View style={[styles.separator, pal.borderDark]} />
|
||||||
<View style={[styles.footer, pal.borderDark]}>
|
|
||||||
<NavItem
|
<NavItem
|
||||||
isProfile
|
isProfile
|
||||||
href={`/profile/${store.me.handle}`}
|
href={`/profile/${store.me.handle}`}
|
||||||
|
@ -125,20 +116,11 @@ export const DesktopLeftColumn = observer(() => {
|
||||||
})
|
})
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
containerBgLight: {
|
|
||||||
backgroundColor: '#f9f9fd',
|
|
||||||
},
|
|
||||||
containerBgDark: {
|
|
||||||
backgroundColor: '#f9f9fd', // TODO
|
|
||||||
},
|
|
||||||
|
|
||||||
container: {
|
container: {
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
left: 0,
|
left: 5,
|
||||||
|
top: 100,
|
||||||
width: '300px',
|
width: '300px',
|
||||||
height: '100vh',
|
|
||||||
borderRightWidth: 1,
|
|
||||||
paddingTop: 5,
|
|
||||||
},
|
},
|
||||||
main: {
|
main: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
|
@ -155,11 +137,6 @@ const styles = StyleSheet.create({
|
||||||
marginHorizontal: 8,
|
marginHorizontal: 8,
|
||||||
},
|
},
|
||||||
|
|
||||||
logo: {
|
|
||||||
paddingTop: 8,
|
|
||||||
paddingBottom: 14,
|
|
||||||
},
|
|
||||||
|
|
||||||
navItem: {
|
navItem: {
|
||||||
paddingVertical: 8,
|
paddingVertical: 8,
|
||||||
paddingHorizontal: 6,
|
paddingHorizontal: 6,
|
||||||
|
|
|
@ -5,6 +5,7 @@ import {IconProp} from '@fortawesome/fontawesome-svg-core'
|
||||||
import {useStores} from 'state/index'
|
import {useStores} from 'state/index'
|
||||||
import {NavigationModel} from 'state/models/navigation'
|
import {NavigationModel} from 'state/models/navigation'
|
||||||
import {match, MatchResult} from '../../routes'
|
import {match, MatchResult} from '../../routes'
|
||||||
|
import {DesktopHeader} from './DesktopHeader'
|
||||||
import {DesktopLeftColumn} from './DesktopLeftColumn'
|
import {DesktopLeftColumn} from './DesktopLeftColumn'
|
||||||
import {DesktopRightColumn} from './DesktopRightColumn'
|
import {DesktopRightColumn} from './DesktopRightColumn'
|
||||||
import {Onboard} from '../../screens/Onboard'
|
import {Onboard} from '../../screens/Onboard'
|
||||||
|
@ -14,10 +15,11 @@ import {Lightbox} from '../../com/lightbox/Lightbox'
|
||||||
import {Modal} from '../../com/modals/Modal'
|
import {Modal} from '../../com/modals/Modal'
|
||||||
import {Composer} from './Composer'
|
import {Composer} from './Composer'
|
||||||
import {usePalette} from 'lib/hooks/usePalette'
|
import {usePalette} from 'lib/hooks/usePalette'
|
||||||
import {s} from 'lib/styles'
|
import {useColorSchemeStyle} from 'lib/hooks/useColorSchemeStyle'
|
||||||
|
import {s, colors} from 'lib/styles'
|
||||||
|
|
||||||
export const WebShell: React.FC = observer(() => {
|
export const WebShell: React.FC = observer(() => {
|
||||||
const pal = usePalette('default')
|
const pageBg = useColorSchemeStyle(styles.bgLight, styles.bgDark)
|
||||||
const store = useStores()
|
const store = useStores()
|
||||||
const screenRenderDesc = constructScreenRenderDesc(store.nav)
|
const screenRenderDesc = constructScreenRenderDesc(store.nav)
|
||||||
|
|
||||||
|
@ -40,7 +42,8 @@ export const WebShell: React.FC = observer(() => {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={[styles.outerContainer, pal.view]}>
|
<View style={[styles.outerContainer, pageBg]}>
|
||||||
|
<DesktopHeader />
|
||||||
{screenRenderDesc.screens.map(({Com, navIdx, params, key, current}) => (
|
{screenRenderDesc.screens.map(({Com, navIdx, params, key, current}) => (
|
||||||
<View
|
<View
|
||||||
key={key}
|
key={key}
|
||||||
|
@ -130,6 +133,12 @@ const styles = StyleSheet.create({
|
||||||
outerContainer: {
|
outerContainer: {
|
||||||
height: '100%',
|
height: '100%',
|
||||||
},
|
},
|
||||||
|
bgLight: {
|
||||||
|
backgroundColor: colors.gray1,
|
||||||
|
},
|
||||||
|
bgDark: {
|
||||||
|
backgroundColor: colors.gray1, // TODO
|
||||||
|
},
|
||||||
visible: {
|
visible: {
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue