diff options
-rw-r--r-- | src/view/shell/web/DesktopHeader.tsx | 166 | ||||
-rw-r--r-- | src/view/shell/web/DesktopLeftColumn.tsx | 177 | ||||
-rw-r--r-- | src/view/shell/web/index.tsx | 1 |
3 files changed, 154 insertions, 190 deletions
diff --git a/src/view/shell/web/DesktopHeader.tsx b/src/view/shell/web/DesktopHeader.tsx index 75acb8da9..acef3d9ba 100644 --- a/src/view/shell/web/DesktopHeader.tsx +++ b/src/view/shell/web/DesktopHeader.tsx @@ -1,12 +1,88 @@ import React from 'react' import {observer} from 'mobx-react-lite' -import {StyleSheet, TouchableOpacity, View} from 'react-native' +import {Pressable, StyleSheet, TouchableOpacity, View} from 'react-native' import {Text} from 'view/com/util/text/Text' import {Link} from 'view/com/util/Link' +import {UserAvatar} from 'view/com/util/UserAvatar' import {usePalette} from 'lib/hooks/usePalette' +import {useColorSchemeStyle} from 'lib/hooks/useColorSchemeStyle' import {useStores} from 'state/index' -import {ComposeIcon, MagnifyingGlassIcon} from 'lib/icons' import {colors} from 'lib/styles' +import { + ComposeIcon, + HomeIcon, + HomeIconSolid, + BellIcon, + BellIconSolid, + MagnifyingGlassIcon, + CogIcon, +} from 'lib/icons' + +interface NavItemProps { + count?: number + href: string + icon: JSX.Element + iconFilled: JSX.Element + isProfile?: boolean +} +export const NavItem = observer( + ({count, href, icon, iconFilled}: NavItemProps) => { + const store = useStores() + const hoverBg = useColorSchemeStyle( + styles.navItemHoverBgLight, + styles.navItemHoverBgDark, + ) + const isCurrent = store.nav.tab.current.url === href + const onPress = () => store.nav.navigate(href) + return ( + <Pressable + style={state => [ + styles.navItem, + // @ts-ignore Pressable state differs for RNW -prf + (state.hovered || isCurrent) && hoverBg, + ]} + onPress={onPress}> + <View style={[styles.navItemIconWrapper]}> + {isCurrent ? iconFilled : icon} + {typeof count === 'number' && count > 0 && ( + <Text type="button" style={styles.navItemCount}> + {count} + </Text> + )} + </View> + </Pressable> + ) + }, +) + +export const ProfileItem = observer(() => { + const store = useStores() + const hoverBg = useColorSchemeStyle( + styles.navItemHoverBgLight, + styles.navItemHoverBgDark, + ) + const href = `/profile/${store.me.handle}` + const isCurrent = store.nav.tab.current.url === href + const onPress = () => store.nav.navigate(href) + return ( + <Pressable + style={state => [ + styles.navItem, + // @ts-ignore Pressable state differs for RNW -prf + (state.hovered || isCurrent) && hoverBg, + ]} + onPress={onPress}> + <View style={[styles.navItemIconWrapper]}> + <UserAvatar + handle={store.me.handle} + displayName={store.me.displayName} + avatar={store.me.avatar} + size={28} + /> + </View> + </Pressable> + ) +}) export const DesktopHeader = observer(function DesktopHeader({}: { canGoBack?: boolean @@ -16,11 +92,29 @@ export const DesktopHeader = observer(function DesktopHeader({}: { 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> + <Text type="title-2xl" style={[pal.text, styles.title]}> + Bluesky + </Text> + <View style={styles.space30} /> + <NavItem + href="/" + icon={<HomeIcon size={28} />} + iconFilled={<HomeIconSolid size={28} />} + /> + <View style={styles.space15} /> + <NavItem + href="/search" + icon={<MagnifyingGlassIcon size={28} />} + iconFilled={<MagnifyingGlassIcon strokeWidth={3} size={28} />} + /> + <View style={styles.space15} /> + <NavItem + href="/notifications" + count={store.me.notifications.unreadCount} + icon={<BellIcon size={28} />} + iconFilled={<BellIconSolid size={28} />} + /> + <View style={styles.spaceFlex} /> <TouchableOpacity style={[styles.newPostBtn]} onPress={onPressCompose}> <View style={styles.newPostBtnIconWrapper}> <ComposeIcon @@ -33,6 +127,7 @@ export const DesktopHeader = observer(function DesktopHeader({}: { New Post </Text> </TouchableOpacity> + <View style={styles.space20} /> <Link href="/search" style={[pal.view, pal.borderDark, styles.search]}> <MagnifyingGlassIcon size={18} @@ -42,6 +137,13 @@ export const DesktopHeader = observer(function DesktopHeader({}: { Search </Text> </Link> + <View style={styles.space15} /> + <ProfileItem /> + <NavItem + href="/settings" + icon={<CogIcon strokeWidth={2} size={28} />} + iconFilled={<CogIcon strokeWidth={2.5} size={28} />} + /> </View> ) }) @@ -50,18 +152,59 @@ const styles = StyleSheet.create({ header: { flexDirection: 'row', alignItems: 'center', - paddingTop: 18, - paddingBottom: 18, + // paddingTop: 18, + // paddingBottom: 18, paddingLeft: 30, paddingRight: 40, borderBottomWidth: 1, }, - titleContainer: { - marginRight: 'auto', + spaceFlex: { + flex: 1, + }, + space15: { + width: 15, }, + space20: { + width: 20, + }, + space30: { + width: 30, + }, + title: {}, + navItem: { + paddingTop: 14, + paddingBottom: 10, + paddingHorizontal: 10, + alignItems: 'center', + borderBottomWidth: 2, + borderBottomColor: 'transparent', + }, + navItemHoverBgLight: { + borderBottomWidth: 2, + borderBottomColor: colors.blue3, + }, + navItemHoverBgDark: { + borderBottomWidth: 2, + backgroundColor: colors.blue3, + }, + navItemIconWrapper: { + marginBottom: 2, + }, + navItemCount: { + position: 'absolute', + top: -5, + left: 15, + backgroundColor: colors.red3, + color: colors.white, + fontSize: 12, + fontWeight: 'bold', + paddingHorizontal: 4, + borderRadius: 6, + }, + search: { flexDirection: 'row', alignItems: 'center', @@ -87,7 +230,6 @@ const styles = StyleSheet.create({ paddingBottom: 9, paddingHorizontal: 18, backgroundColor: colors.blue3, - marginRight: 10, }, newPostBtnIconWrapper: { marginRight: 8, diff --git a/src/view/shell/web/DesktopLeftColumn.tsx b/src/view/shell/web/DesktopLeftColumn.tsx deleted file mode 100644 index 28c867582..000000000 --- a/src/view/shell/web/DesktopLeftColumn.tsx +++ /dev/null @@ -1,177 +0,0 @@ -import React from 'react' -import {Pressable, StyleSheet, View} from 'react-native' -import {observer} from 'mobx-react-lite' -import {Link} from '../../com/util/Link' -import {Text} from '../../com/util/text/Text' -import {UserAvatar} from '../../com/util/UserAvatar' -import {colors} from 'lib/styles' -import {useStores} from 'state/index' -import {usePalette} from 'lib/hooks/usePalette' -import {useColorSchemeStyle} from 'lib/hooks/useColorSchemeStyle' -import { - HomeIcon, - HomeIconSolid, - BellIcon, - BellIconSolid, - MagnifyingGlassIcon, - CogIcon, -} from 'lib/icons' - -interface NavItemProps { - label: string - count?: number - href: string - icon: JSX.Element - iconFilled: JSX.Element - isProfile?: boolean -} -export const NavItem = observer( - ({label, count, href, icon, iconFilled, isProfile}: NavItemProps) => { - const store = useStores() - const hoverBg = useColorSchemeStyle( - styles.navItemHoverBgLight, - styles.navItemHoverBgDark, - ) - const isCurrent = store.nav.tab.current.url === href - return ( - <Pressable - style={state => [ - // @ts-ignore Pressable state differs for RNW -prf - state.hovered && hoverBg, - ]}> - <Link style={[styles.navItem]} href={href}> - <View - style={[ - styles.navItemIconWrapper, - isProfile && styles.navItemProfile, - ]}> - {isCurrent ? iconFilled : icon} - {typeof count === 'number' && count > 0 && ( - <Text type="button" style={styles.navItemCount}> - {count} - </Text> - )} - </View> - <Text - type={isCurrent || isProfile ? 'xl' : 'xl-thin'} - numberOfLines={1}> - {label} - </Text> - </Link> - </Pressable> - ) - }, -) - -export const DesktopLeftColumn = observer(() => { - const store = useStores() - const pal = usePalette('default') - const avi = ( - <UserAvatar - handle={store.me.handle} - displayName={store.me.displayName} - avatar={store.me.avatar} - size={30} - /> - ) - return ( - <View style={[styles.container]}> - <View style={styles.main}> - <NavItem - href="/" - label="Home" - icon={<HomeIcon size={21} />} - iconFilled={<HomeIconSolid size={21} />} - /> - <NavItem - href="/search" - label="Explore" - icon={<MagnifyingGlassIcon size={21} />} - iconFilled={<MagnifyingGlassIcon strokeWidth={3} size={21} />} - /> - <NavItem - href="/notifications" - label="Notifications" - count={store.me.notifications.unreadCount} - icon={<BellIcon size={21} />} - iconFilled={<BellIconSolid size={21} />} - /> - <NavItem - href="/settings" - label="Settings" - icon={<CogIcon strokeWidth={2} size={21} />} - iconFilled={<CogIcon strokeWidth={2.5} size={21} />} - /> - <View style={[styles.separator, pal.borderDark]} /> - <NavItem - isProfile - href={`/profile/${store.me.handle}`} - label={store.me.displayName || store.me.handle} - icon={avi} - iconFilled={avi} - /> - </View> - </View> - ) -}) - -const styles = StyleSheet.create({ - container: { - position: 'absolute', - left: 5, - top: 100, - width: '300px', - }, - main: { - flex: 1, - paddingHorizontal: 16, - }, - footer: { - borderTopWidth: 1, - paddingHorizontal: 16, - paddingVertical: 8, - }, - separator: { - borderTopWidth: 1, - marginVertical: 12, - marginHorizontal: 8, - }, - - navItem: { - paddingVertical: 8, - paddingHorizontal: 6, - marginBottom: 2, - flexDirection: 'row', - alignItems: 'center', - borderRadius: 6, - }, - navItemHoverBgLight: { - backgroundColor: '#ebebf0', - borderRadius: 6, - }, - navItemHoverBgDark: { - backgroundColor: colors.gray2, // TODO - borderRadius: 6, - }, - navItemIconWrapper: { - flexDirection: 'row', - width: 30, - justifyContent: 'center', - marginRight: 8, - }, - navItemProfile: { - width: 30, - marginRight: 10, - }, - navItemCount: { - position: 'absolute', - top: -5, - left: 15, - backgroundColor: colors.red3, - color: colors.white, - fontSize: 12, - fontWeight: 'bold', - paddingHorizontal: 4, - borderRadius: 6, - }, -}) diff --git a/src/view/shell/web/index.tsx b/src/view/shell/web/index.tsx index 44f958be8..4a4bde817 100644 --- a/src/view/shell/web/index.tsx +++ b/src/view/shell/web/index.tsx @@ -53,7 +53,6 @@ export const WebShell: React.FC = observer(() => { </ErrorBoundary> </View> ))} - <DesktopLeftColumn /> <DesktopRightColumn /> <Composer active={store.shell.isComposerActive} |