Rework web shell ui
parent
9bfffadd88
commit
c5f28376c8
|
@ -0,0 +1,6 @@
|
|||
import {useColorScheme} from 'react-native'
|
||||
|
||||
export function useColorSchemeStyle(lightStyle: any, darkStyle: any) {
|
||||
const colorScheme = useColorScheme()
|
||||
return colorScheme === 'dark' ? darkStyle : lightStyle
|
||||
}
|
|
@ -527,3 +527,29 @@ export function RectTallIcon({
|
|||
</Svg>
|
||||
)
|
||||
}
|
||||
export function ComposeIcon({
|
||||
style,
|
||||
size,
|
||||
strokeWidth = 1.5,
|
||||
}: {
|
||||
style?: StyleProp<TextStyle>
|
||||
size?: string | number
|
||||
strokeWidth?: number
|
||||
}) {
|
||||
return (
|
||||
<Svg
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
strokeWidth={strokeWidth}
|
||||
stroke="currentColor"
|
||||
width={size || 24}
|
||||
height={size || 24}
|
||||
style={style}>
|
||||
<Path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
d="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L10.582 16.07a4.5 4.5 0 01-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 011.13-1.897l8.932-8.931zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0115.75 21H5.25A2.25 2.25 0 013 18.75V8.25A2.25 2.25 0 015.25 6H10"
|
||||
/>
|
||||
</Svg>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import {
|
|||
TouchableOpacity,
|
||||
View,
|
||||
} from 'react-native'
|
||||
import LinearGradient from 'react-native-linear-gradient'
|
||||
import {observer} from 'mobx-react-lite'
|
||||
import _omit from 'lodash.omit'
|
||||
import {Link} from '../util/Link'
|
||||
|
@ -99,6 +98,7 @@ const User = ({
|
|||
onPressUnfollow: (item: SuggestedActor) => void
|
||||
}) => {
|
||||
const pal = usePalette('default')
|
||||
const palInverted = usePalette('inverted')
|
||||
return (
|
||||
<View style={[styles.actor]}>
|
||||
<View style={styles.actorMeta}>
|
||||
|
@ -121,23 +121,19 @@ const User = ({
|
|||
<View style={styles.actorBtn}>
|
||||
{follow ? (
|
||||
<TouchableOpacity onPress={() => onPressUnfollow(item)}>
|
||||
<View style={[styles.btn, styles.secondaryBtn, pal.btn]}>
|
||||
<View style={[styles.btn, pal.btn]}>
|
||||
<Text type="button" style={pal.text}>
|
||||
Unfollow
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
) : (
|
||||
<TouchableOpacity onPress={() => onPressFollow(item)}>
|
||||
<LinearGradient
|
||||
colors={[gradients.blueLight.start, gradients.blueLight.end]}
|
||||
start={{x: 0, y: 0}}
|
||||
end={{x: 1, y: 1}}
|
||||
style={[styles.btn, styles.gradientBtn]}>
|
||||
<Text type="sm-medium" style={s.white}>
|
||||
Follow
|
||||
</Text>
|
||||
</LinearGradient>
|
||||
<TouchableOpacity
|
||||
onPress={() => onPressFollow(item)}
|
||||
style={[styles.btn, palInverted.view]}>
|
||||
<Text type="sm-medium" style={palInverted.text}>
|
||||
Follow
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
</View>
|
||||
|
@ -187,6 +183,7 @@ const styles = StyleSheet.create({
|
|||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
paddingVertical: 7,
|
||||
paddingHorizontal: 14,
|
||||
borderRadius: 50,
|
||||
marginLeft: 6,
|
||||
},
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import React from 'react'
|
||||
import {Pressable, StyleSheet, TouchableOpacity, View} from 'react-native'
|
||||
import {observer} from 'mobx-react-lite'
|
||||
import LinearGradient from 'react-native-linear-gradient'
|
||||
import {Link} from '../../com/util/Link'
|
||||
import {Text} from '../../com/util/text/Text'
|
||||
import {UserAvatar} from '../../com/util/UserAvatar'
|
||||
import {s, colors, gradients} from 'lib/styles'
|
||||
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,
|
||||
|
@ -15,6 +15,7 @@ import {
|
|||
BellIconSolid,
|
||||
MagnifyingGlassIcon,
|
||||
CogIcon,
|
||||
ComposeIcon,
|
||||
} from 'lib/icons'
|
||||
|
||||
interface NavItemProps {
|
||||
|
@ -28,15 +29,18 @@ interface NavItemProps {
|
|||
export const NavItem = observer(
|
||||
({label, count, href, icon, iconFilled, isProfile}: NavItemProps) => {
|
||||
const store = useStores()
|
||||
const pal = usePalette('default')
|
||||
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 && {backgroundColor: pal.colors.backgroundLight},
|
||||
state.hovered && hoverBg,
|
||||
]}>
|
||||
<Link style={styles.navItem} href={href}>
|
||||
<Link style={[styles.navItem, isCurrent && hoverBg]} href={href}>
|
||||
<View
|
||||
style={[
|
||||
styles.navItemIconWrapper,
|
||||
|
@ -50,8 +54,7 @@ export const NavItem = observer(
|
|||
)}
|
||||
</View>
|
||||
<Text
|
||||
type={isCurrent ? 'xl-bold' : 'xl'}
|
||||
style={styles.navItemLabel}
|
||||
type={isCurrent || isProfile ? 'xl' : 'xl-thin'}
|
||||
numberOfLines={1}>
|
||||
{label}
|
||||
</Text>
|
||||
|
@ -63,6 +66,14 @@ export const NavItem = observer(
|
|||
|
||||
export const DesktopLeftColumn = observer(() => {
|
||||
const store = useStores()
|
||||
const containerBg = useColorSchemeStyle(
|
||||
styles.containerBgLight,
|
||||
styles.containerBgDark,
|
||||
)
|
||||
const hoverBg = useColorSchemeStyle(
|
||||
styles.navItemHoverBgLight,
|
||||
styles.navItemHoverBgDark,
|
||||
)
|
||||
const pal = usePalette('default')
|
||||
const onPressCompose = () => store.shell.openComposer({})
|
||||
const avi = (
|
||||
|
@ -70,81 +81,152 @@ export const DesktopLeftColumn = observer(() => {
|
|||
handle={store.me.handle}
|
||||
displayName={store.me.displayName}
|
||||
avatar={store.me.avatar}
|
||||
size={40}
|
||||
size={30}
|
||||
/>
|
||||
)
|
||||
return (
|
||||
<View style={[styles.container, pal.border]}>
|
||||
<NavItem
|
||||
isProfile
|
||||
href={`/profile/${store.me.handle}`}
|
||||
label={store.me.displayName || store.me.handle}
|
||||
icon={avi}
|
||||
iconFilled={avi}
|
||||
/>
|
||||
<NavItem
|
||||
href="/"
|
||||
label="Home"
|
||||
icon={<HomeIcon />}
|
||||
iconFilled={<HomeIconSolid />}
|
||||
/>
|
||||
<NavItem
|
||||
href="/search"
|
||||
label="Search"
|
||||
icon={<MagnifyingGlassIcon />}
|
||||
iconFilled={<MagnifyingGlassIcon strokeWidth={4} />}
|
||||
/>
|
||||
<NavItem
|
||||
href="/notifications"
|
||||
label="Notifications"
|
||||
count={store.me.notifications.unreadCount}
|
||||
icon={<BellIcon />}
|
||||
iconFilled={<BellIconSolid />}
|
||||
/>
|
||||
<NavItem
|
||||
href="/settings"
|
||||
label="Settings"
|
||||
icon={<CogIcon strokeWidth={1.5} />}
|
||||
iconFilled={<CogIcon strokeWidth={2} />}
|
||||
/>
|
||||
<TouchableOpacity onPress={onPressCompose}>
|
||||
<LinearGradient
|
||||
colors={[gradients.blueLight.start, gradients.blueLight.end]}
|
||||
start={{x: 0, y: 0}}
|
||||
end={{x: 1, y: 1}}
|
||||
style={styles.composeBtn}>
|
||||
<Text type="xl-medium" style={[s.white, s.textCenter]}>
|
||||
New Post
|
||||
<View style={[styles.container, containerBg, pal.border]}>
|
||||
<View style={styles.main}>
|
||||
<Link style={styles.logo} href="/">
|
||||
<Text type="title-xl">Bluesky</Text>
|
||||
</Link>
|
||||
<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>
|
||||
</LinearGradient>
|
||||
</TouchableOpacity>
|
||||
</Link>
|
||||
<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={[pal.border, styles.separator]} />
|
||||
<Pressable
|
||||
style={state => [
|
||||
// @ts-ignore Pressable state differs for RNW -prf
|
||||
state.hovered && hoverBg,
|
||||
]}>
|
||||
<TouchableOpacity style={styles.navItem} onPress={onPressCompose}>
|
||||
<View style={styles.navItemIconWrapper}>
|
||||
<ComposeIcon size={21} />
|
||||
</View>
|
||||
<Text type="xl-thin">New Post</Text>
|
||||
</TouchableOpacity>
|
||||
</Pressable>
|
||||
</View>
|
||||
<View style={[styles.footer, 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({
|
||||
containerBgLight: {
|
||||
backgroundColor: '#f9f9fd',
|
||||
},
|
||||
containerBgDark: {
|
||||
backgroundColor: '#f9f9fd', // TODO
|
||||
},
|
||||
|
||||
container: {
|
||||
position: 'absolute',
|
||||
left: 'calc(50vw - 530px)',
|
||||
width: '230px',
|
||||
height: '100%',
|
||||
left: 0,
|
||||
width: '300px',
|
||||
height: '100vh',
|
||||
borderRightWidth: 1,
|
||||
paddingTop: 5,
|
||||
},
|
||||
navItem: {
|
||||
paddingVertical: 10,
|
||||
paddingHorizontal: 10,
|
||||
main: {
|
||||
flex: 1,
|
||||
paddingHorizontal: 16,
|
||||
},
|
||||
footer: {
|
||||
borderTopWidth: 1,
|
||||
paddingHorizontal: 16,
|
||||
paddingVertical: 8,
|
||||
},
|
||||
separator: {
|
||||
borderTopWidth: 1,
|
||||
marginVertical: 12,
|
||||
marginHorizontal: 8,
|
||||
},
|
||||
|
||||
logo: {
|
||||
paddingTop: 6,
|
||||
paddingBottom: 12,
|
||||
},
|
||||
|
||||
search: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
borderRadius: 8,
|
||||
paddingVertical: 8,
|
||||
paddingHorizontal: 6,
|
||||
marginBottom: 10,
|
||||
borderWidth: 1,
|
||||
},
|
||||
searchIconWrapper: {
|
||||
flexDirection: 'row',
|
||||
width: 30,
|
||||
justifyContent: 'center',
|
||||
marginRight: 6,
|
||||
},
|
||||
|
||||
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: 5,
|
||||
marginRight: 8,
|
||||
},
|
||||
navItemProfile: {
|
||||
width: 40,
|
||||
width: 30,
|
||||
marginRight: 10,
|
||||
},
|
||||
navItemCount: {
|
||||
|
@ -158,9 +240,6 @@ const styles = StyleSheet.create({
|
|||
paddingHorizontal: 4,
|
||||
borderRadius: 6,
|
||||
},
|
||||
navItemLabel: {
|
||||
fontSize: 19,
|
||||
},
|
||||
composeBtn: {
|
||||
marginTop: 20,
|
||||
marginBottom: 10,
|
||||
|
|
|
@ -1,25 +1,15 @@
|
|||
import React from 'react'
|
||||
import {View, StyleSheet} from 'react-native'
|
||||
import {Link} from '../../com/util/Link'
|
||||
import {StyleSheet, View} from 'react-native'
|
||||
import {Text} from '../../com/util/text/Text'
|
||||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
import {MagnifyingGlassIcon} from 'lib/icons'
|
||||
import {LiteSuggestedFollows} from '../../com/discover/LiteSuggestedFollows'
|
||||
import {s} from 'lib/styles'
|
||||
import {useStores} from 'state/index'
|
||||
|
||||
export const DesktopRightColumn: React.FC = () => {
|
||||
const pal = usePalette('default')
|
||||
const store = useStores()
|
||||
return (
|
||||
<View style={[styles.container, pal.border]}>
|
||||
<Link href="/search" style={[pal.btn, styles.searchContainer]}>
|
||||
<View style={styles.searchIcon}>
|
||||
<MagnifyingGlassIcon style={pal.textLight} />
|
||||
</View>
|
||||
<Text type="lg" style={pal.textLight}>
|
||||
Search
|
||||
</Text>
|
||||
</Link>
|
||||
<Text type="xl-bold" style={s.mb10}>
|
||||
<View style={styles.container}>
|
||||
<Text type="lg-bold" style={s.mb10}>
|
||||
Suggested Follows
|
||||
</Text>
|
||||
<LiteSuggestedFollows />
|
||||
|
@ -30,23 +20,10 @@ export const DesktopRightColumn: React.FC = () => {
|
|||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
position: 'absolute',
|
||||
right: 'calc(50vw - 650px)',
|
||||
width: '350px',
|
||||
height: '100%',
|
||||
borderLeftWidth: 1,
|
||||
overscrollBehavior: 'auto',
|
||||
paddingLeft: 30,
|
||||
paddingTop: 10,
|
||||
},
|
||||
searchContainer: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
paddingHorizontal: 14,
|
||||
paddingVertical: 10,
|
||||
borderRadius: 20,
|
||||
marginBottom: 20,
|
||||
},
|
||||
searchIcon: {
|
||||
marginRight: 5,
|
||||
right: 0,
|
||||
width: '400px',
|
||||
paddingHorizontal: 16,
|
||||
paddingRight: 32,
|
||||
paddingTop: 20,
|
||||
},
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue