Update web header and search
parent
c5f28376c8
commit
e828f380e7
|
@ -20,6 +20,7 @@ module.exports = {
|
||||||
alias: {
|
alias: {
|
||||||
// This needs to be mirrored in tsconfig.json
|
// This needs to be mirrored in tsconfig.json
|
||||||
lib: './src/lib',
|
lib: './src/lib',
|
||||||
|
platform: './src/platform',
|
||||||
state: './src/state',
|
state: './src/state',
|
||||||
view: './src/view',
|
view: './src/view',
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,69 +1,51 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {observer} from 'mobx-react-lite'
|
import {observer} from 'mobx-react-lite'
|
||||||
import {StyleSheet, TouchableOpacity, View} from 'react-native'
|
import {StyleSheet, TouchableOpacity, View} from 'react-native'
|
||||||
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
|
|
||||||
import {CenteredView} from './Views'
|
|
||||||
import {Text} from './text/Text'
|
import {Text} from './text/Text'
|
||||||
import {useStores} from 'state/index'
|
import {Link} from './Link'
|
||||||
import {usePalette} from 'lib/hooks/usePalette'
|
import {usePalette} from 'lib/hooks/usePalette'
|
||||||
|
import {useStores} from 'state/index'
|
||||||
|
import {ComposeIcon, MagnifyingGlassIcon} from 'lib/icons'
|
||||||
import {colors} from 'lib/styles'
|
import {colors} from 'lib/styles'
|
||||||
|
|
||||||
const BACK_HITSLOP = {left: 10, top: 10, right: 30, bottom: 10}
|
|
||||||
|
|
||||||
export const ViewHeader = observer(function ViewHeader({
|
export const ViewHeader = observer(function ViewHeader({
|
||||||
title,
|
title,
|
||||||
subtitle,
|
|
||||||
canGoBack,
|
|
||||||
}: {
|
}: {
|
||||||
title: string
|
title: string
|
||||||
subtitle?: string
|
|
||||||
canGoBack?: boolean
|
canGoBack?: boolean
|
||||||
}) {
|
}) {
|
||||||
const pal = usePalette('default')
|
|
||||||
const store = useStores()
|
const store = useStores()
|
||||||
const onPressBack = () => {
|
const pal = usePalette('default')
|
||||||
store.nav.tab.goBack()
|
const onPressCompose = () => store.shell.openComposer({})
|
||||||
}
|
|
||||||
if (typeof canGoBack === 'undefined') {
|
|
||||||
canGoBack = store.nav.tab.canGoBack
|
|
||||||
}
|
|
||||||
return (
|
return (
|
||||||
<CenteredView style={[styles.header, pal.view]}>
|
<View style={[styles.header, pal.borderDark, pal.view]}>
|
||||||
{canGoBack ? (
|
|
||||||
<>
|
|
||||||
<TouchableOpacity
|
|
||||||
testID="viewHeaderBackOrMenuBtn"
|
|
||||||
onPress={onPressBack}
|
|
||||||
hitSlop={BACK_HITSLOP}
|
|
||||||
style={styles.backBtn}>
|
|
||||||
<FontAwesomeIcon
|
|
||||||
size={18}
|
|
||||||
icon="angle-left"
|
|
||||||
style={[styles.backIcon, pal.text]}
|
|
||||||
/>
|
|
||||||
</TouchableOpacity>
|
|
||||||
<View style={styles.titleContainer} pointerEvents="none">
|
<View style={styles.titleContainer} pointerEvents="none">
|
||||||
<Text type="title" style={[pal.text, styles.title]}>
|
<Text type="title-2xl" style={[pal.text, styles.title]}>
|
||||||
{title}
|
{title}
|
||||||
</Text>
|
</Text>
|
||||||
{subtitle ? (
|
|
||||||
<Text
|
|
||||||
type="title-sm"
|
|
||||||
style={[styles.subtitle, pal.textLight]}
|
|
||||||
numberOfLines={1}>
|
|
||||||
{subtitle}
|
|
||||||
</Text>
|
|
||||||
) : undefined}
|
|
||||||
</View>
|
</View>
|
||||||
</>
|
<TouchableOpacity style={[styles.newPostBtn]} onPress={onPressCompose}>
|
||||||
) : (
|
<View style={styles.newPostBtnIconWrapper}>
|
||||||
<View style={styles.titleContainer} pointerEvents="none">
|
<ComposeIcon
|
||||||
<Text type="title" style={[pal.text, styles.title]}>
|
size={16}
|
||||||
Home
|
strokeWidth={1.5}
|
||||||
</Text>
|
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>
|
</View>
|
||||||
)}
|
|
||||||
</CenteredView>
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -71,44 +53,52 @@ const styles = StyleSheet.create({
|
||||||
header: {
|
header: {
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
paddingHorizontal: 16,
|
paddingTop: 24,
|
||||||
paddingVertical: 12,
|
paddingBottom: 18,
|
||||||
|
paddingLeft: 30,
|
||||||
|
paddingRight: 40,
|
||||||
|
marginLeft: 300,
|
||||||
|
borderBottomWidth: 1,
|
||||||
},
|
},
|
||||||
|
|
||||||
titleContainer: {
|
titleContainer: {
|
||||||
flexDirection: 'row',
|
|
||||||
alignItems: 'baseline',
|
|
||||||
marginRight: 'auto',
|
marginRight: 'auto',
|
||||||
},
|
},
|
||||||
title: {
|
title: {
|
||||||
fontWeight: 'bold',
|
fontWeight: 'bold',
|
||||||
},
|
},
|
||||||
subtitle: {
|
|
||||||
marginLeft: 4,
|
search: {
|
||||||
maxWidth: 200,
|
flexDirection: 'row',
|
||||||
fontWeight: 'normal',
|
alignItems: 'center',
|
||||||
|
width: 300,
|
||||||
|
borderRadius: 20,
|
||||||
|
paddingVertical: 8,
|
||||||
|
paddingHorizontal: 10,
|
||||||
|
borderWidth: 1,
|
||||||
|
},
|
||||||
|
searchIconWrapper: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
width: 30,
|
||||||
|
justifyContent: 'center',
|
||||||
|
marginRight: 2,
|
||||||
},
|
},
|
||||||
|
|
||||||
backBtn: {
|
newPostBtn: {
|
||||||
width: 30,
|
|
||||||
},
|
|
||||||
backIcon: {
|
|
||||||
position: 'relative',
|
|
||||||
top: -1,
|
|
||||||
},
|
|
||||||
btn: {
|
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
width: 36,
|
borderRadius: 24,
|
||||||
height: 36,
|
paddingTop: 8,
|
||||||
borderRadius: 20,
|
paddingBottom: 9,
|
||||||
marginLeft: 4,
|
paddingHorizontal: 18,
|
||||||
|
backgroundColor: colors.blue3,
|
||||||
|
marginRight: 10,
|
||||||
},
|
},
|
||||||
littleXIcon: {
|
newPostBtnIconWrapper: {
|
||||||
color: colors.red3,
|
marginRight: 8,
|
||||||
position: 'absolute',
|
},
|
||||||
right: 7,
|
newPostBtnLabel: {
|
||||||
bottom: 7,
|
color: colors.white,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
|
@ -22,7 +22,6 @@ import {
|
||||||
View,
|
View,
|
||||||
ViewProps,
|
ViewProps,
|
||||||
} from 'react-native'
|
} from 'react-native'
|
||||||
import {useTheme} from 'lib/ThemeContext'
|
|
||||||
import {addStyle, colors} from 'lib/styles'
|
import {addStyle, colors} from 'lib/styles'
|
||||||
|
|
||||||
export function CenteredView({
|
export function CenteredView({
|
||||||
|
@ -40,15 +39,10 @@ export const FlatList = React.forwardRef(function <ItemT>(
|
||||||
}: React.PropsWithChildren<FlatListProps<ItemT>>,
|
}: React.PropsWithChildren<FlatListProps<ItemT>>,
|
||||||
ref: React.Ref<RNFlatList>,
|
ref: React.Ref<RNFlatList>,
|
||||||
) {
|
) {
|
||||||
const theme = useTheme()
|
|
||||||
contentContainerStyle = addStyle(
|
contentContainerStyle = addStyle(
|
||||||
contentContainerStyle,
|
contentContainerStyle,
|
||||||
styles.containerScroll,
|
styles.containerScroll,
|
||||||
)
|
)
|
||||||
contentContainerStyle = addStyle(
|
|
||||||
contentContainerStyle,
|
|
||||||
theme.colorScheme === 'dark' ? styles.containerDark : styles.containerLight,
|
|
||||||
)
|
|
||||||
return (
|
return (
|
||||||
<RNFlatList
|
<RNFlatList
|
||||||
contentContainerStyle={contentContainerStyle}
|
contentContainerStyle={contentContainerStyle}
|
||||||
|
@ -60,17 +54,12 @@ export const FlatList = React.forwardRef(function <ItemT>(
|
||||||
|
|
||||||
export const ScrollView = React.forwardRef(function (
|
export const ScrollView = React.forwardRef(function (
|
||||||
{contentContainerStyle, ...props}: React.PropsWithChildren<ScrollViewProps>,
|
{contentContainerStyle, ...props}: React.PropsWithChildren<ScrollViewProps>,
|
||||||
ref: React.Ref<RNFlatList>,
|
ref: React.Ref<RNScrollView>,
|
||||||
) {
|
) {
|
||||||
const theme = useTheme()
|
|
||||||
contentContainerStyle = addStyle(
|
contentContainerStyle = addStyle(
|
||||||
contentContainerStyle,
|
contentContainerStyle,
|
||||||
styles.containerScroll,
|
styles.containerScroll,
|
||||||
)
|
)
|
||||||
contentContainerStyle = addStyle(
|
|
||||||
contentContainerStyle,
|
|
||||||
theme.colorScheme === 'dark' ? styles.containerDark : styles.containerLight,
|
|
||||||
)
|
|
||||||
return (
|
return (
|
||||||
<RNScrollView
|
<RNScrollView
|
||||||
contentContainerStyle={contentContainerStyle}
|
contentContainerStyle={contentContainerStyle}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import {ScreenParams} from '../routes'
|
||||||
import {s} from 'lib/styles'
|
import {s} from 'lib/styles'
|
||||||
import {useOnMainScroll} from 'lib/hooks/useOnMainScroll'
|
import {useOnMainScroll} from 'lib/hooks/useOnMainScroll'
|
||||||
import {useAnalytics} from 'lib/analytics'
|
import {useAnalytics} from 'lib/analytics'
|
||||||
|
import {isWeb} from 'platform/detection'
|
||||||
|
|
||||||
const HEADER_HEIGHT = 42
|
const HEADER_HEIGHT = 42
|
||||||
|
|
||||||
|
@ -91,6 +92,7 @@ export const Home = observer(function Home({navIdx, visible}: ScreenParams) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={s.h100pct}>
|
<View style={s.h100pct}>
|
||||||
|
{isWeb && <ViewHeader title="Home Feed" canGoBack={false} />}
|
||||||
<Feed
|
<Feed
|
||||||
testID="homeFeed"
|
testID="homeFeed"
|
||||||
key="default"
|
key="default"
|
||||||
|
@ -102,7 +104,7 @@ export const Home = observer(function Home({navIdx, visible}: ScreenParams) {
|
||||||
onScroll={onMainScroll}
|
onScroll={onMainScroll}
|
||||||
headerOffset={HEADER_HEIGHT}
|
headerOffset={HEADER_HEIGHT}
|
||||||
/>
|
/>
|
||||||
<ViewHeader title="Bluesky" canGoBack={false} hideOnScroll />
|
{!isWeb && <ViewHeader title="Bluesky" canGoBack={false} hideOnScroll />}
|
||||||
{store.me.mainFeed.hasNewLatest && !store.me.mainFeed.isRefreshing && (
|
{store.me.mainFeed.hasNewLatest && !store.me.mainFeed.isRefreshing && (
|
||||||
<LoadLatestBtn onPress={onPressLoadLatest} />
|
<LoadLatestBtn onPress={onPressLoadLatest} />
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -0,0 +1,217 @@
|
||||||
|
import React from 'react'
|
||||||
|
import {
|
||||||
|
Keyboard,
|
||||||
|
StyleSheet,
|
||||||
|
TextInput,
|
||||||
|
TouchableOpacity,
|
||||||
|
View,
|
||||||
|
} from 'react-native'
|
||||||
|
import {ScrollView} from '../com/util/Views'
|
||||||
|
import {observer} from 'mobx-react-lite'
|
||||||
|
import {UserAvatar} from '../com/util/UserAvatar'
|
||||||
|
import {Text} from '../com/util/text/Text'
|
||||||
|
import {ScreenParams} from '../routes'
|
||||||
|
import {useStores} from 'state/index'
|
||||||
|
import {UserAutocompleteViewModel} from 'state/models/user-autocomplete-view'
|
||||||
|
import {s} from 'lib/styles'
|
||||||
|
import {MagnifyingGlassIcon} from 'lib/icons'
|
||||||
|
import {ViewHeader} from '../com/util/ViewHeader'
|
||||||
|
import {WhoToFollow} from '../com/discover/WhoToFollow'
|
||||||
|
import {SuggestedPosts} from '../com/discover/SuggestedPosts'
|
||||||
|
import {ProfileCard} from '../com/profile/ProfileCard'
|
||||||
|
import {usePalette} from 'lib/hooks/usePalette'
|
||||||
|
import {useOnMainScroll} from 'lib/hooks/useOnMainScroll'
|
||||||
|
import {useAnalytics} from 'lib/analytics'
|
||||||
|
|
||||||
|
const MENU_HITSLOP = {left: 10, top: 10, right: 30, bottom: 10}
|
||||||
|
const FIVE_MIN = 5 * 60 * 1e3
|
||||||
|
|
||||||
|
export const Search = observer(({navIdx, visible, params}: ScreenParams) => {
|
||||||
|
const pal = usePalette('default')
|
||||||
|
const store = useStores()
|
||||||
|
const {track} = useAnalytics()
|
||||||
|
const scrollElRef = React.useRef<ScrollView>(null)
|
||||||
|
const onMainScroll = useOnMainScroll(store)
|
||||||
|
const textInput = React.useRef<TextInput>(null)
|
||||||
|
const [lastRenderTime, setRenderTime] = React.useState<number>(Date.now()) // used to trigger reloads
|
||||||
|
const [isInputFocused, setIsInputFocused] = React.useState<boolean>(false)
|
||||||
|
const [query, setQuery] = React.useState<string>('')
|
||||||
|
const autocompleteView = React.useMemo<UserAutocompleteViewModel>(
|
||||||
|
() => new UserAutocompleteViewModel(store),
|
||||||
|
[store],
|
||||||
|
)
|
||||||
|
const {name} = params
|
||||||
|
|
||||||
|
const onSoftReset = () => {
|
||||||
|
scrollElRef.current?.scrollTo({x: 0, y: 0})
|
||||||
|
}
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
const softResetSub = store.onScreenSoftReset(onSoftReset)
|
||||||
|
const cleanup = () => {
|
||||||
|
softResetSub.remove()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (visible) {
|
||||||
|
const now = Date.now()
|
||||||
|
if (now - lastRenderTime > FIVE_MIN) {
|
||||||
|
setRenderTime(Date.now()) // trigger reload of suggestions
|
||||||
|
}
|
||||||
|
store.shell.setMinimalShellMode(false)
|
||||||
|
autocompleteView.setup()
|
||||||
|
store.nav.setTitle(navIdx, 'Search')
|
||||||
|
}
|
||||||
|
return cleanup
|
||||||
|
}, [store, visible, name, navIdx, autocompleteView, lastRenderTime])
|
||||||
|
|
||||||
|
const onPressMenu = () => {
|
||||||
|
track('ViewHeader:MenuButtonClicked')
|
||||||
|
store.shell.setMainMenuOpen(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
const onChangeQuery = (text: string) => {
|
||||||
|
setQuery(text)
|
||||||
|
if (text.length > 0) {
|
||||||
|
autocompleteView.setActive(true)
|
||||||
|
autocompleteView.setPrefix(text)
|
||||||
|
} else {
|
||||||
|
autocompleteView.setActive(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const onPressCancelSearch = () => {
|
||||||
|
setQuery('')
|
||||||
|
autocompleteView.setActive(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={s.h100pct}>
|
||||||
|
<ViewHeader title="Explore" />
|
||||||
|
<ScrollView
|
||||||
|
ref={scrollElRef}
|
||||||
|
testID="searchScrollView"
|
||||||
|
style={[pal.view, styles.container]}
|
||||||
|
onScroll={onMainScroll}
|
||||||
|
scrollEventThrottle={100}>
|
||||||
|
<View style={[pal.view, pal.border, styles.header]}>
|
||||||
|
<TouchableOpacity
|
||||||
|
testID="viewHeaderBackOrMenuBtn"
|
||||||
|
onPress={onPressMenu}
|
||||||
|
hitSlop={MENU_HITSLOP}
|
||||||
|
style={styles.headerMenuBtn}>
|
||||||
|
<UserAvatar
|
||||||
|
size={30}
|
||||||
|
handle={store.me.handle}
|
||||||
|
displayName={store.me.displayName}
|
||||||
|
avatar={store.me.avatar}
|
||||||
|
/>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
{backgroundColor: pal.colors.backgroundLight},
|
||||||
|
styles.headerSearchContainer,
|
||||||
|
]}>
|
||||||
|
<MagnifyingGlassIcon
|
||||||
|
style={[pal.icon, styles.headerSearchIcon]}
|
||||||
|
size={21}
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
testID="searchTextInput"
|
||||||
|
ref={textInput}
|
||||||
|
placeholder="Search"
|
||||||
|
placeholderTextColor={pal.colors.textLight}
|
||||||
|
selectTextOnFocus
|
||||||
|
returnKeyType="search"
|
||||||
|
value={query}
|
||||||
|
style={[pal.text, styles.headerSearchInput]}
|
||||||
|
onFocus={() => setIsInputFocused(true)}
|
||||||
|
onBlur={() => setIsInputFocused(false)}
|
||||||
|
onChangeText={onChangeQuery}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
{query ? (
|
||||||
|
<View style={styles.headerCancelBtn}>
|
||||||
|
<TouchableOpacity onPress={onPressCancelSearch}>
|
||||||
|
<Text>Cancel</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
) : undefined}
|
||||||
|
</View>
|
||||||
|
{query && autocompleteView.searchRes.length ? (
|
||||||
|
<>
|
||||||
|
{autocompleteView.searchRes.map(item => (
|
||||||
|
<ProfileCard
|
||||||
|
key={item.did}
|
||||||
|
handle={item.handle}
|
||||||
|
displayName={item.displayName}
|
||||||
|
avatar={item.avatar}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
) : query && !autocompleteView.searchRes.length ? (
|
||||||
|
<View>
|
||||||
|
<Text style={[pal.textLight, styles.searchPrompt]}>
|
||||||
|
No results found for {autocompleteView.prefix}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
) : isInputFocused ? (
|
||||||
|
<View>
|
||||||
|
<Text style={[pal.textLight, styles.searchPrompt]}>
|
||||||
|
Search for users on the network
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
) : (
|
||||||
|
<ScrollView onScroll={Keyboard.dismiss}>
|
||||||
|
<WhoToFollow key={`wtf-${lastRenderTime}`} />
|
||||||
|
<SuggestedPosts key={`sp-${lastRenderTime}`} />
|
||||||
|
<View style={s.footerSpacer} />
|
||||||
|
</ScrollView>
|
||||||
|
)}
|
||||||
|
<View style={s.footerSpacer} />
|
||||||
|
</ScrollView>
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
},
|
||||||
|
|
||||||
|
header: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
paddingHorizontal: 12,
|
||||||
|
paddingTop: 4,
|
||||||
|
marginBottom: 14,
|
||||||
|
},
|
||||||
|
headerMenuBtn: {
|
||||||
|
width: 40,
|
||||||
|
height: 30,
|
||||||
|
marginLeft: 6,
|
||||||
|
},
|
||||||
|
headerSearchContainer: {
|
||||||
|
flex: 1,
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
borderRadius: 30,
|
||||||
|
paddingHorizontal: 12,
|
||||||
|
paddingVertical: 8,
|
||||||
|
},
|
||||||
|
headerSearchIcon: {
|
||||||
|
marginRight: 6,
|
||||||
|
alignSelf: 'center',
|
||||||
|
},
|
||||||
|
headerSearchInput: {
|
||||||
|
flex: 1,
|
||||||
|
fontSize: 17,
|
||||||
|
},
|
||||||
|
headerCancelBtn: {
|
||||||
|
width: 60,
|
||||||
|
paddingLeft: 10,
|
||||||
|
},
|
||||||
|
|
||||||
|
searchPrompt: {
|
||||||
|
textAlign: 'center',
|
||||||
|
paddingTop: 10,
|
||||||
|
},
|
||||||
|
})
|
|
@ -70,12 +70,7 @@ export const DesktopLeftColumn = observer(() => {
|
||||||
styles.containerBgLight,
|
styles.containerBgLight,
|
||||||
styles.containerBgDark,
|
styles.containerBgDark,
|
||||||
)
|
)
|
||||||
const hoverBg = useColorSchemeStyle(
|
|
||||||
styles.navItemHoverBgLight,
|
|
||||||
styles.navItemHoverBgDark,
|
|
||||||
)
|
|
||||||
const pal = usePalette('default')
|
const pal = usePalette('default')
|
||||||
const onPressCompose = () => store.shell.openComposer({})
|
|
||||||
const avi = (
|
const avi = (
|
||||||
<UserAvatar
|
<UserAvatar
|
||||||
handle={store.me.handle}
|
handle={store.me.handle}
|
||||||
|
@ -90,15 +85,6 @@ export const DesktopLeftColumn = observer(() => {
|
||||||
<Link style={styles.logo} href="/">
|
<Link style={styles.logo} href="/">
|
||||||
<Text type="title-xl">Bluesky</Text>
|
<Text type="title-xl">Bluesky</Text>
|
||||||
</Link>
|
</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>
|
|
||||||
</Link>
|
|
||||||
<NavItem
|
<NavItem
|
||||||
href="/"
|
href="/"
|
||||||
label="Home"
|
label="Home"
|
||||||
|
@ -124,19 +110,6 @@ 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 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>
|
||||||
<View style={[styles.footer, pal.borderDark]}>
|
<View style={[styles.footer, pal.borderDark]}>
|
||||||
<NavItem
|
<NavItem
|
||||||
|
@ -183,24 +156,8 @@ const styles = StyleSheet.create({
|
||||||
},
|
},
|
||||||
|
|
||||||
logo: {
|
logo: {
|
||||||
paddingTop: 6,
|
paddingTop: 8,
|
||||||
paddingBottom: 12,
|
paddingBottom: 14,
|
||||||
},
|
|
||||||
|
|
||||||
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: {
|
navItem: {
|
||||||
|
@ -240,13 +197,4 @@ const styles = StyleSheet.create({
|
||||||
paddingHorizontal: 4,
|
paddingHorizontal: 4,
|
||||||
borderRadius: 6,
|
borderRadius: 6,
|
||||||
},
|
},
|
||||||
composeBtn: {
|
|
||||||
marginTop: 20,
|
|
||||||
marginBottom: 10,
|
|
||||||
marginLeft: 10,
|
|
||||||
marginRight: 20,
|
|
||||||
borderRadius: 30,
|
|
||||||
paddingHorizontal: 20,
|
|
||||||
paddingVertical: 12,
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
|
|
|
@ -3,10 +3,8 @@ import {StyleSheet, View} from 'react-native'
|
||||||
import {Text} from '../../com/util/text/Text'
|
import {Text} from '../../com/util/text/Text'
|
||||||
import {LiteSuggestedFollows} from '../../com/discover/LiteSuggestedFollows'
|
import {LiteSuggestedFollows} from '../../com/discover/LiteSuggestedFollows'
|
||||||
import {s} from 'lib/styles'
|
import {s} from 'lib/styles'
|
||||||
import {useStores} from 'state/index'
|
|
||||||
|
|
||||||
export const DesktopRightColumn: React.FC = () => {
|
export const DesktopRightColumn: React.FC = () => {
|
||||||
const store = useStores()
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<Text type="lg-bold" style={s.mb10}>
|
<Text type="lg-bold" style={s.mb10}>
|
||||||
|
@ -21,6 +19,7 @@ const styles = StyleSheet.create({
|
||||||
container: {
|
container: {
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
right: 0,
|
right: 0,
|
||||||
|
top: 90,
|
||||||
width: '400px',
|
width: '400px',
|
||||||
paddingHorizontal: 16,
|
paddingHorizontal: 16,
|
||||||
paddingRight: 32,
|
paddingRight: 32,
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"paths": {
|
"paths": {
|
||||||
"lib/*": ["./src/lib/*"],
|
"lib/*": ["./src/lib/*"],
|
||||||
|
"platform/*": ["./src/platform/*"],
|
||||||
"state/*": ["./src/state/*"],
|
"state/*": ["./src/state/*"],
|
||||||
"view/*": ["./src/view/*"]
|
"view/*": ["./src/view/*"]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue