Restructure the shell folder and fix the header positioning
This commit is contained in:
+2
-2
@@ -9,7 +9,7 @@ import {observer} from 'mobx-react-lite'
|
|||||||
import {ThemeProvider} from 'lib/ThemeContext'
|
import {ThemeProvider} from 'lib/ThemeContext'
|
||||||
import * as view from './view/index'
|
import * as view from './view/index'
|
||||||
import {RootStoreModel, setupState, RootStoreProvider} from './state'
|
import {RootStoreModel, setupState, RootStoreProvider} from './state'
|
||||||
import {MobileShell} from './view/shell/mobile'
|
import {Shell} from './view/shell'
|
||||||
import {s} from 'lib/styles'
|
import {s} from 'lib/styles'
|
||||||
import * as notifee from 'lib/notifee'
|
import * as notifee from 'lib/notifee'
|
||||||
import * as analytics from 'lib/analytics'
|
import * as analytics from 'lib/analytics'
|
||||||
@@ -54,7 +54,7 @@ const App = observer(() => {
|
|||||||
<analytics.Provider>
|
<analytics.Provider>
|
||||||
<RootStoreProvider value={rootStore}>
|
<RootStoreProvider value={rootStore}>
|
||||||
<SafeAreaProvider>
|
<SafeAreaProvider>
|
||||||
<MobileShell />
|
<Shell />
|
||||||
</SafeAreaProvider>
|
</SafeAreaProvider>
|
||||||
</RootStoreProvider>
|
</RootStoreProvider>
|
||||||
</analytics.Provider>
|
</analytics.Provider>
|
||||||
|
|||||||
+2
-2
@@ -3,7 +3,7 @@ import {SafeAreaProvider} from 'react-native-safe-area-context'
|
|||||||
import {getInitialURL} from 'platform/urls'
|
import {getInitialURL} from 'platform/urls'
|
||||||
import * as view from './view/index'
|
import * as view from './view/index'
|
||||||
import {RootStoreModel, setupState, RootStoreProvider} from './state'
|
import {RootStoreModel, setupState, RootStoreProvider} from './state'
|
||||||
import {WebShell} from './view/shell/web'
|
import {Shell} from './view/shell/index'
|
||||||
import {ToastContainer} from './view/com/util/Toast.web'
|
import {ToastContainer} from './view/com/util/Toast.web'
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
@@ -33,7 +33,7 @@ function App() {
|
|||||||
return (
|
return (
|
||||||
<RootStoreProvider value={rootStore}>
|
<RootStoreProvider value={rootStore}>
|
||||||
<SafeAreaProvider>
|
<SafeAreaProvider>
|
||||||
<WebShell />
|
<Shell />
|
||||||
</SafeAreaProvider>
|
</SafeAreaProvider>
|
||||||
<ToastContainer />
|
<ToastContainer />
|
||||||
</RootStoreProvider>
|
</RootStoreProvider>
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "xyz.blueskyweb.app",
|
|
||||||
"displayName": "Bluesky"
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
/**
|
|
||||||
* @format
|
|
||||||
*/
|
|
||||||
|
|
||||||
import {AppRegistry} from 'react-native'
|
|
||||||
import App from './App'
|
|
||||||
|
|
||||||
AppRegistry.registerComponent('App', () => App)
|
|
||||||
|
|
||||||
AppRegistry.runApplication('App', {
|
|
||||||
rootTag: document.getElementById('root'),
|
|
||||||
})
|
|
||||||
+77
-76
@@ -1,19 +1,20 @@
|
|||||||
import {LikelyType, LinkMeta} from './link-meta'
|
import {LikelyType, LinkMeta} from './link-meta'
|
||||||
import {match as matchRoute} from 'view/routes'
|
// import {match as matchRoute} from 'view/routes'
|
||||||
import {convertBskyAppUrlIfNeeded, makeRecordUri} from '../strings/url-helpers'
|
import {convertBskyAppUrlIfNeeded, makeRecordUri} from '../strings/url-helpers'
|
||||||
import {RootStoreModel} from 'state/index'
|
import {RootStoreModel} from 'state/index'
|
||||||
import {PostThreadViewModel} from 'state/models/post-thread-view'
|
import {PostThreadViewModel} from 'state/models/post-thread-view'
|
||||||
import {ComposerOptsQuote} from 'state/models/shell-ui'
|
import {ComposerOptsQuote} from 'state/models/shell-ui'
|
||||||
|
|
||||||
import {Home} from 'view/screens/Home'
|
// TODO
|
||||||
import {Search} from 'view/screens/Search'
|
// import {Home} from 'view/screens/Home'
|
||||||
import {Notifications} from 'view/screens/Notifications'
|
// import {Search} from 'view/screens/Search'
|
||||||
import {PostThread} from 'view/screens/PostThread'
|
// import {Notifications} from 'view/screens/Notifications'
|
||||||
import {PostUpvotedBy} from 'view/screens/PostUpvotedBy'
|
// import {PostThread} from 'view/screens/PostThread'
|
||||||
import {PostRepostedBy} from 'view/screens/PostRepostedBy'
|
// import {PostUpvotedBy} from 'view/screens/PostUpvotedBy'
|
||||||
import {Profile} from 'view/screens/Profile'
|
// import {PostRepostedBy} from 'view/screens/PostRepostedBy'
|
||||||
import {ProfileFollowers} from 'view/screens/ProfileFollowers'
|
// import {Profile} from 'view/screens/Profile'
|
||||||
import {ProfileFollows} from 'view/screens/ProfileFollows'
|
// import {ProfileFollowers} from 'view/screens/ProfileFollowers'
|
||||||
|
// import {ProfileFollows} from 'view/screens/ProfileFollows'
|
||||||
|
|
||||||
// NOTE
|
// NOTE
|
||||||
// this is a hack around the lack of hosted social metadata
|
// this is a hack around the lack of hosted social metadata
|
||||||
@@ -24,77 +25,77 @@ export async function extractBskyMeta(
|
|||||||
url: string,
|
url: string,
|
||||||
): Promise<LinkMeta> {
|
): Promise<LinkMeta> {
|
||||||
url = convertBskyAppUrlIfNeeded(url)
|
url = convertBskyAppUrlIfNeeded(url)
|
||||||
const route = matchRoute(url)
|
// const route = matchRoute(url)
|
||||||
let meta: LinkMeta = {
|
let meta: LinkMeta = {
|
||||||
likelyType: LikelyType.AtpData,
|
likelyType: LikelyType.AtpData,
|
||||||
url,
|
url,
|
||||||
title: route.defaultTitle,
|
// title: route.defaultTitle,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (route.Com === Home) {
|
// if (route.Com === Home) {
|
||||||
meta = {
|
// meta = {
|
||||||
...meta,
|
// ...meta,
|
||||||
title: 'Bluesky',
|
// title: 'Bluesky',
|
||||||
description: 'A new kind of social network',
|
// description: 'A new kind of social network',
|
||||||
}
|
// }
|
||||||
} else if (route.Com === Search) {
|
// } else if (route.Com === Search) {
|
||||||
meta = {
|
// meta = {
|
||||||
...meta,
|
// ...meta,
|
||||||
title: 'Search - Bluesky',
|
// title: 'Search - Bluesky',
|
||||||
description: 'A new kind of social network',
|
// description: 'A new kind of social network',
|
||||||
}
|
// }
|
||||||
} else if (route.Com === Notifications) {
|
// } else if (route.Com === Notifications) {
|
||||||
meta = {
|
// meta = {
|
||||||
...meta,
|
// ...meta,
|
||||||
title: 'Notifications - Bluesky',
|
// title: 'Notifications - Bluesky',
|
||||||
description: 'A new kind of social network',
|
// description: 'A new kind of social network',
|
||||||
}
|
// }
|
||||||
} else if (
|
// } else if (
|
||||||
route.Com === PostThread ||
|
// route.Com === PostThread ||
|
||||||
route.Com === PostUpvotedBy ||
|
// route.Com === PostUpvotedBy ||
|
||||||
route.Com === PostRepostedBy
|
// route.Com === PostRepostedBy
|
||||||
) {
|
// ) {
|
||||||
// post and post-related screens
|
// // post and post-related screens
|
||||||
const threadUri = makeRecordUri(
|
// const threadUri = makeRecordUri(
|
||||||
route.params.name,
|
// route.params.name,
|
||||||
'app.bsky.feed.post',
|
// 'app.bsky.feed.post',
|
||||||
route.params.rkey,
|
// route.params.rkey,
|
||||||
)
|
// )
|
||||||
const threadView = new PostThreadViewModel(store, {
|
// const threadView = new PostThreadViewModel(store, {
|
||||||
uri: threadUri,
|
// uri: threadUri,
|
||||||
depth: 0,
|
// depth: 0,
|
||||||
})
|
// })
|
||||||
await threadView.setup().catch(_err => undefined)
|
// await threadView.setup().catch(_err => undefined)
|
||||||
const title = [
|
// const title = [
|
||||||
route.Com === PostUpvotedBy
|
// route.Com === PostUpvotedBy
|
||||||
? 'Likes on a post by'
|
// ? 'Likes on a post by'
|
||||||
: route.Com === PostRepostedBy
|
// : route.Com === PostRepostedBy
|
||||||
? 'Reposts of a post by'
|
// ? 'Reposts of a post by'
|
||||||
: 'Post by',
|
// : 'Post by',
|
||||||
threadView.thread?.post.author.displayName ||
|
// threadView.thread?.post.author.displayName ||
|
||||||
threadView.thread?.post.author.handle ||
|
// threadView.thread?.post.author.handle ||
|
||||||
'a bluesky user',
|
// 'a bluesky user',
|
||||||
].join(' ')
|
// ].join(' ')
|
||||||
meta = {
|
// meta = {
|
||||||
...meta,
|
// ...meta,
|
||||||
title,
|
// title,
|
||||||
description: threadView.thread?.postRecord?.text,
|
// description: threadView.thread?.postRecord?.text,
|
||||||
}
|
// }
|
||||||
} else if (
|
// } else if (
|
||||||
route.Com === Profile ||
|
// route.Com === Profile ||
|
||||||
route.Com === ProfileFollowers ||
|
// route.Com === ProfileFollowers ||
|
||||||
route.Com === ProfileFollows
|
// route.Com === ProfileFollows
|
||||||
) {
|
// ) {
|
||||||
// profile and profile-related screens
|
// // profile and profile-related screens
|
||||||
const profile = await store.profiles.getProfile(route.params.name)
|
// const profile = await store.profiles.getProfile(route.params.name)
|
||||||
if (profile?.data) {
|
// if (profile?.data) {
|
||||||
meta = {
|
// meta = {
|
||||||
...meta,
|
// ...meta,
|
||||||
title: profile.data.displayName || profile.data.handle,
|
// title: profile.data.displayName || profile.data.handle,
|
||||||
description: profile.data.description,
|
// description: profile.data.description,
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
return meta
|
return meta
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,21 +11,21 @@ import {
|
|||||||
State,
|
State,
|
||||||
} from 'lib/routes/types'
|
} from 'lib/routes/types'
|
||||||
|
|
||||||
import {Drawer} from './shell/Drawer'
|
import {Drawer} from './view/shell/Drawer'
|
||||||
import {BottomBar} from './shell/BottomBar'
|
import {BottomBar} from './view/shell/BottomBar'
|
||||||
|
|
||||||
import {HomeScreen} from './screens/Home'
|
import {HomeScreen} from './view/screens/Home'
|
||||||
import {SearchScreen} from './screens/Search'
|
import {SearchScreen} from './view/screens/Search'
|
||||||
import {NotificationsScreen} from './screens/Notifications'
|
import {NotificationsScreen} from './view/screens/Notifications'
|
||||||
import {SettingsScreen} from './screens/Settings'
|
import {SettingsScreen} from './view/screens/Settings'
|
||||||
import {ProfileScreen} from './screens/Profile'
|
import {ProfileScreen} from './view/screens/Profile'
|
||||||
import {ProfileFollowersScreen} from './screens/ProfileFollowers'
|
import {ProfileFollowersScreen} from './view/screens/ProfileFollowers'
|
||||||
import {ProfileFollowsScreen} from './screens/ProfileFollows'
|
import {ProfileFollowsScreen} from './view/screens/ProfileFollows'
|
||||||
import {PostThreadScreen} from './screens/PostThread'
|
import {PostThreadScreen} from './view/screens/PostThread'
|
||||||
import {PostUpvotedByScreen} from './screens/PostUpvotedBy'
|
import {PostUpvotedByScreen} from './view/screens/PostUpvotedBy'
|
||||||
import {PostRepostedByScreen} from './screens/PostRepostedBy'
|
import {PostRepostedByScreen} from './view/screens/PostRepostedBy'
|
||||||
import {DebugScreen} from './screens/Debug'
|
import {DebugScreen} from './view/screens/Debug'
|
||||||
import {LogScreen} from './screens/Log'
|
import {LogScreen} from './view/screens/Log'
|
||||||
|
|
||||||
const HomeDrawer = createDrawerNavigator()
|
const HomeDrawer = createDrawerNavigator()
|
||||||
const HomeTab = createNativeStackNavigator<HomeTabNavigatorParams>()
|
const HomeTab = createNativeStackNavigator<HomeTabNavigatorParams>()
|
||||||
@@ -52,7 +52,7 @@ function r(pattern: string): Route {
|
|||||||
match(path: string) {
|
match(path: string) {
|
||||||
const res = matcherRe.exec(path)
|
const res = matcherRe.exec(path)
|
||||||
if (res) {
|
if (res) {
|
||||||
return {params: res.groups}
|
return {params: res.groups || {}}
|
||||||
}
|
}
|
||||||
return undefined
|
return undefined
|
||||||
},
|
},
|
||||||
@@ -101,7 +101,7 @@ export const LINKING = {
|
|||||||
|
|
||||||
getPathFromState(state: State) {
|
getPathFromState(state: State) {
|
||||||
// find the current node in the navigation tree
|
// find the current node in the navigation tree
|
||||||
let node = state.routes[state.index]
|
let node = state.routes[state.index || 0]
|
||||||
while (node.state?.routes && typeof node.state?.index === 'number') {
|
while (node.state?.routes && typeof node.state?.index === 'number') {
|
||||||
node = node.state?.routes[node.state?.index]
|
node = node.state?.routes[node.state?.index]
|
||||||
}
|
}
|
||||||
@@ -239,7 +239,7 @@ function SearchTabNavigator() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function TabsNavigator() {
|
export function TabsNavigator() {
|
||||||
const tabBar = React.useCallback(props => <BottomBar {...props} />, [])
|
const tabBar = React.useCallback(props => <BottomBar {...props} />, [])
|
||||||
return (
|
return (
|
||||||
<Tab.Navigator
|
<Tab.Navigator
|
||||||
@@ -257,10 +257,6 @@ function TabsNavigator() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Screens() {
|
export function RoutesContainer({children}: React.PropsWithChildren<{}>) {
|
||||||
return (
|
return <NavigationContainer linking={LINKING}>{children}</NavigationContainer>
|
||||||
<NavigationContainer linking={LINKING}>
|
|
||||||
<TabsNavigator />
|
|
||||||
</NavigationContainer>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
@@ -15,7 +15,7 @@ import {useLinkProps, useNavigation} from '@react-navigation/native'
|
|||||||
import {Text} from './text/Text'
|
import {Text} from './text/Text'
|
||||||
import {TypographyVariant} from 'lib/ThemeContext'
|
import {TypographyVariant} from 'lib/ThemeContext'
|
||||||
import {NavigationProp} from 'lib/routes/types'
|
import {NavigationProp} from 'lib/routes/types'
|
||||||
import {matchPath} from 'view/screens'
|
import {matchPath} from '../../../Routes'
|
||||||
import {useStores, RootStoreModel} from 'state/index'
|
import {useStores, RootStoreModel} from 'state/index'
|
||||||
import {convertBskyAppUrlIfNeeded} from 'lib/strings/url-helpers'
|
import {convertBskyAppUrlIfNeeded} from 'lib/strings/url-helpers'
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ export const Link = observer(function Link({
|
|||||||
children?: React.ReactNode
|
children?: React.ReactNode
|
||||||
noFeedback?: boolean
|
noFeedback?: boolean
|
||||||
}) {
|
}) {
|
||||||
let {...props} = useLinkProps({to: href})
|
let {...props} = useLinkProps({to: href || ''})
|
||||||
const store = useStores()
|
const store = useStores()
|
||||||
const navigation = useNavigation<NavigationProp>()
|
const navigation = useNavigation<NavigationProp>()
|
||||||
|
|
||||||
|
|||||||
@@ -1,82 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
import {IconProp} from '@fortawesome/fontawesome-svg-core'
|
|
||||||
import {Home} from './screens/Home'
|
|
||||||
import {Search} from './screens/Search'
|
|
||||||
import {Notifications} from './screens/Notifications'
|
|
||||||
import {NotFound} from './screens/NotFound'
|
|
||||||
import {PostThread} from './screens/PostThread'
|
|
||||||
import {PostUpvotedBy} from './screens/PostUpvotedBy'
|
|
||||||
import {PostRepostedBy} from './screens/PostRepostedBy'
|
|
||||||
import {Profile} from './screens/Profile'
|
|
||||||
import {ProfileFollowers} from './screens/ProfileFollowers'
|
|
||||||
import {ProfileFollows} from './screens/ProfileFollows'
|
|
||||||
import {Settings} from './screens/Settings'
|
|
||||||
import {Debug} from './screens/Debug'
|
|
||||||
import {Log} from './screens/Log'
|
|
||||||
|
|
||||||
export type ScreenParams = {
|
|
||||||
navIdx: string
|
|
||||||
params: Record<string, any>
|
|
||||||
visible: boolean
|
|
||||||
}
|
|
||||||
export type Route = [React.FC<ScreenParams>, string, IconProp, RegExp]
|
|
||||||
export type MatchResult = {
|
|
||||||
Com: React.FC<ScreenParams>
|
|
||||||
defaultTitle: string
|
|
||||||
icon: IconProp
|
|
||||||
params: Record<string, any>
|
|
||||||
isNotFound?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
const r = (pattern: string) => new RegExp('^' + pattern + '([?]|$)', 'i')
|
|
||||||
export const routes: Route[] = [
|
|
||||||
[Home, 'Home', 'house', r('/')],
|
|
||||||
[Search, 'Search', 'magnifying-glass', r('/search')],
|
|
||||||
[Notifications, 'Notifications', 'bell', r('/notifications')],
|
|
||||||
[Settings, 'Settings', 'bell', r('/settings')],
|
|
||||||
[Profile, 'User', ['far', 'user'], r('/profile/(?<name>[^/]+)')],
|
|
||||||
[
|
|
||||||
ProfileFollowers,
|
|
||||||
'Followers',
|
|
||||||
'users',
|
|
||||||
r('/profile/(?<name>[^/]+)/followers'),
|
|
||||||
],
|
|
||||||
[ProfileFollows, 'Follows', 'users', r('/profile/(?<name>[^/]+)/follows')],
|
|
||||||
[
|
|
||||||
PostThread,
|
|
||||||
'Post',
|
|
||||||
['far', 'message'],
|
|
||||||
r('/profile/(?<name>[^/]+)/post/(?<rkey>[^/]+)'),
|
|
||||||
],
|
|
||||||
[
|
|
||||||
PostUpvotedBy,
|
|
||||||
'Liked by',
|
|
||||||
'heart',
|
|
||||||
r('/profile/(?<name>[^/]+)/post/(?<rkey>[^/]+)/upvoted-by'),
|
|
||||||
],
|
|
||||||
[
|
|
||||||
PostRepostedBy,
|
|
||||||
'Reposted by',
|
|
||||||
'retweet',
|
|
||||||
r('/profile/(?<name>[^/]+)/post/(?<rkey>[^/]+)/reposted-by'),
|
|
||||||
],
|
|
||||||
[Debug, 'Debug', 'house', r('/sys/debug')],
|
|
||||||
[Log, 'Log', 'house', r('/sys/log')],
|
|
||||||
]
|
|
||||||
|
|
||||||
export function match(url: string): MatchResult {
|
|
||||||
for (const [Com, defaultTitle, icon, pattern] of routes) {
|
|
||||||
const res = pattern.exec(url)
|
|
||||||
if (res) {
|
|
||||||
// TODO: query params
|
|
||||||
return {Com, defaultTitle, icon, params: res.groups || {}}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
Com: NotFound,
|
|
||||||
defaultTitle: 'Not found',
|
|
||||||
icon: 'magnifying-glass',
|
|
||||||
params: {},
|
|
||||||
isNotFound: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -18,7 +18,7 @@ import {ComposeIcon2} from 'lib/icons'
|
|||||||
const HEADER_HEIGHT = 42
|
const HEADER_HEIGHT = 42
|
||||||
|
|
||||||
type Props = NativeStackScreenProps<HomeTabNavigatorParams, 'Home'>
|
type Props = NativeStackScreenProps<HomeTabNavigatorParams, 'Home'>
|
||||||
export const HomeScreen = observer(function Home({}: Props) {
|
export const HomeScreen = observer(function Home(_opts: Props) {
|
||||||
const store = useStores()
|
const store = useStores()
|
||||||
const onMainScroll = useOnMainScroll(store)
|
const onMainScroll = useOnMainScroll(store)
|
||||||
const {screen, track} = useAnalytics()
|
const {screen, track} = useAnalytics()
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React, {useEffect} from 'react'
|
import React, {useEffect} from 'react'
|
||||||
import {observer} from 'mobx-react-lite'
|
import {observer} from 'mobx-react-lite'
|
||||||
import {Animated, Easing, Platform, StyleSheet, View} from 'react-native'
|
import {Animated, Easing, Platform, StyleSheet, View} from 'react-native'
|
||||||
import {ComposePost} from '../../com/composer/ComposePost'
|
import {ComposePost} from '../com/composer/ComposePost'
|
||||||
import {ComposerOpts} from 'state/models/shell-ui'
|
import {ComposerOpts} from 'state/models/shell-ui'
|
||||||
import {useAnimatedValue} from 'lib/hooks/useAnimatedValue'
|
import {useAnimatedValue} from 'lib/hooks/useAnimatedValue'
|
||||||
import {usePalette} from 'lib/hooks/usePalette'
|
import {usePalette} from 'lib/hooks/usePalette'
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {observer} from 'mobx-react-lite'
|
import {observer} from 'mobx-react-lite'
|
||||||
import {StyleSheet, View} from 'react-native'
|
import {StyleSheet, View} from 'react-native'
|
||||||
import {ComposePost} from '../../com/composer/ComposePost'
|
import {ComposePost} from '../com/composer/ComposePost'
|
||||||
import {ComposerOpts} from 'state/models/shell-ui'
|
import {ComposerOpts} from 'state/models/shell-ui'
|
||||||
import {usePalette} from 'lib/hooks/usePalette'
|
import {usePalette} from 'lib/hooks/usePalette'
|
||||||
|
|
||||||
@@ -318,7 +318,7 @@ const styles = StyleSheet.create({
|
|||||||
flex: 1,
|
flex: 1,
|
||||||
paddingTop: 20,
|
paddingTop: 20,
|
||||||
paddingBottom: 50,
|
paddingBottom: 50,
|
||||||
paddingLeft: 30,
|
paddingLeft: 20,
|
||||||
},
|
},
|
||||||
viewDarkMode: {
|
viewDarkMode: {
|
||||||
backgroundColor: '#1B1919',
|
backgroundColor: '#1B1919',
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import {
|
|||||||
MagnifyingGlassIcon,
|
MagnifyingGlassIcon,
|
||||||
CogIcon,
|
CogIcon,
|
||||||
} from 'lib/icons'
|
} from 'lib/icons'
|
||||||
import {DesktopSearch} from './DesktopSearch'
|
import {DesktopSearch} from './Search'
|
||||||
|
|
||||||
interface NavItemProps {
|
interface NavItemProps {
|
||||||
count?: number
|
count?: number
|
||||||
@@ -5,7 +5,7 @@ import {observer} from 'mobx-react-lite'
|
|||||||
import {useStores} from 'state/index'
|
import {useStores} from 'state/index'
|
||||||
import {usePalette} from 'lib/hooks/usePalette'
|
import {usePalette} from 'lib/hooks/usePalette'
|
||||||
import {MagnifyingGlassIcon} from 'lib/icons'
|
import {MagnifyingGlassIcon} from 'lib/icons'
|
||||||
import {ProfileCard} from '../../com/profile/ProfileCard'
|
import {ProfileCard} from '../com/profile/ProfileCard'
|
||||||
|
|
||||||
export const DesktopSearch = observer(function DesktopSearch() {
|
export const DesktopSearch = observer(function DesktopSearch() {
|
||||||
const store = useStores()
|
const store = useStores()
|
||||||
@@ -1,23 +1,28 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {observer} from 'mobx-react-lite'
|
import {observer} from 'mobx-react-lite'
|
||||||
import {StatusBar, StyleSheet, useWindowDimensions, View} from 'react-native'
|
import {StatusBar, StyleSheet, useWindowDimensions, View} from 'react-native'
|
||||||
|
import {useSafeAreaInsets} from 'react-native-safe-area-context'
|
||||||
import {useStores} from 'state/index'
|
import {useStores} from 'state/index'
|
||||||
import {Login} from '../../screens/Login'
|
import {Login} from '../screens/Login'
|
||||||
import {ModalsContainer} from '../../com/modals/Modal'
|
import {ModalsContainer} from '../com/modals/Modal'
|
||||||
import {Lightbox} from '../../com/lightbox/Lightbox'
|
import {Lightbox} from '../com/lightbox/Lightbox'
|
||||||
import {Text} from '../../com/util/text/Text'
|
import {Text} from '../com/util/text/Text'
|
||||||
import {Composer} from './Composer'
|
import {Composer} from './Composer'
|
||||||
import {s} from 'lib/styles'
|
import {s} from 'lib/styles'
|
||||||
import {useTheme} from 'lib/ThemeContext'
|
import {useTheme} from 'lib/ThemeContext'
|
||||||
import {usePalette} from 'lib/hooks/usePalette'
|
import {usePalette} from 'lib/hooks/usePalette'
|
||||||
|
import {RoutesContainer, TabsNavigator} from '../../Routes'
|
||||||
|
|
||||||
import {Screens} from '../../screens'
|
export const Shell: React.FC = observer(() => {
|
||||||
|
|
||||||
export const MobileShell: React.FC = observer(() => {
|
|
||||||
const theme = useTheme()
|
const theme = useTheme()
|
||||||
const pal = usePalette('default')
|
const pal = usePalette('default')
|
||||||
const store = useStores()
|
const store = useStores()
|
||||||
const winDim = useWindowDimensions()
|
const winDim = useWindowDimensions()
|
||||||
|
const safeAreaInsets = useSafeAreaInsets()
|
||||||
|
const containerPadding = React.useMemo(
|
||||||
|
() => ({height: '100%', paddingTop: safeAreaInsets.top}),
|
||||||
|
[safeAreaInsets],
|
||||||
|
)
|
||||||
|
|
||||||
if (store.hackUpgradeNeeded) {
|
if (store.hackUpgradeNeeded) {
|
||||||
return (
|
return (
|
||||||
@@ -73,18 +78,22 @@ export const MobileShell: React.FC = observer(() => {
|
|||||||
theme.colorScheme === 'dark' ? 'light-content' : 'dark-content'
|
theme.colorScheme === 'dark' ? 'light-content' : 'dark-content'
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Screens />
|
<RoutesContainer>
|
||||||
<ModalsContainer />
|
<View style={containerPadding}>
|
||||||
<Lightbox />
|
<TabsNavigator />
|
||||||
<Composer
|
</View>
|
||||||
active={store.shell.isComposerActive}
|
<ModalsContainer />
|
||||||
onClose={() => store.shell.closeComposer()}
|
<Lightbox />
|
||||||
winHeight={winDim.height}
|
<Composer
|
||||||
replyTo={store.shell.composerOpts?.replyTo}
|
active={store.shell.isComposerActive}
|
||||||
imagesOpen={store.shell.composerOpts?.imagesOpen}
|
onClose={() => store.shell.closeComposer()}
|
||||||
onPost={store.shell.composerOpts?.onPost}
|
winHeight={winDim.height}
|
||||||
quote={store.shell.composerOpts?.quote}
|
replyTo={store.shell.composerOpts?.replyTo}
|
||||||
/>
|
imagesOpen={store.shell.composerOpts?.imagesOpen}
|
||||||
|
onPost={store.shell.composerOpts?.onPost}
|
||||||
|
quote={store.shell.composerOpts?.quote}
|
||||||
|
/>
|
||||||
|
</RoutesContainer>
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@@ -3,23 +3,22 @@ import {observer} from 'mobx-react-lite'
|
|||||||
import {View, StyleSheet} from 'react-native'
|
import {View, StyleSheet} from 'react-native'
|
||||||
import {IconProp} from '@fortawesome/fontawesome-svg-core'
|
import {IconProp} from '@fortawesome/fontawesome-svg-core'
|
||||||
import {useStores} from 'state/index'
|
import {useStores} from 'state/index'
|
||||||
import {NavigationModel} from 'state/models/navigation'
|
import {match, MatchResult} from '../routes'
|
||||||
import {match, MatchResult} from '../../routes'
|
import {DesktopHeader} from './desktop/Header'
|
||||||
import {DesktopHeader} from './DesktopHeader'
|
import {Login} from '../screens/Login'
|
||||||
import {Login} from '../../screens/Login'
|
import {ErrorBoundary} from '../com/util/ErrorBoundary'
|
||||||
import {ErrorBoundary} from '../../com/util/ErrorBoundary'
|
import {Lightbox} from '../com/lightbox/Lightbox'
|
||||||
import {Lightbox} from '../../com/lightbox/Lightbox'
|
import {ModalsContainer} from '../com/modals/Modal'
|
||||||
import {ModalsContainer} from '../../com/modals/Modal'
|
|
||||||
import {Text} from 'view/com/util/text/Text'
|
import {Text} from 'view/com/util/text/Text'
|
||||||
import {Composer} from './Composer'
|
import {Composer} from './Composer.web'
|
||||||
import {usePalette} from 'lib/hooks/usePalette'
|
import {usePalette} from 'lib/hooks/usePalette'
|
||||||
import {useColorSchemeStyle} from 'lib/hooks/useColorSchemeStyle'
|
import {useColorSchemeStyle} from 'lib/hooks/useColorSchemeStyle'
|
||||||
import {s, colors} from 'lib/styles'
|
import {s, colors} from 'lib/styles'
|
||||||
import {isMobileWeb} from 'platform/detection'
|
import {isMobileWeb} from 'platform/detection'
|
||||||
|
|
||||||
import {Screens} from '../../screens'
|
import {RoutesContainer} from '../../Routes'
|
||||||
|
|
||||||
export const WebShell: React.FC = observer(() => {
|
export const Shell: React.FC = observer(() => {
|
||||||
const pageBg = useColorSchemeStyle(styles.bgLight, styles.bgDark)
|
const pageBg = useColorSchemeStyle(styles.bgLight, styles.bgDark)
|
||||||
const store = useStores()
|
const store = useStores()
|
||||||
const screenRenderDesc = constructScreenRenderDesc(store.nav)
|
const screenRenderDesc = constructScreenRenderDesc(store.nav)
|
||||||
@@ -28,7 +27,7 @@ export const WebShell: React.FC = observer(() => {
|
|||||||
return <NoMobileWeb />
|
return <NoMobileWeb />
|
||||||
}
|
}
|
||||||
|
|
||||||
return <Screens />
|
return <RoutesContainer />
|
||||||
|
|
||||||
if (!store.session.hasSession) {
|
if (!store.session.hasSession) {
|
||||||
return (
|
return (
|
||||||
Reference in New Issue
Block a user