Skip to content

Commit 0299ea2

Browse files
committed
Layout fixes on native app
1 parent d5ee333 commit 0299ea2

9 files changed

Lines changed: 170 additions & 115 deletions

File tree

apps/polycentric/app.config.ts

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import type { ExpoConfig, ConfigContext } from 'expo/config';
2+
3+
const IS_DEV = process.env.APP_VARIANT === 'dev';
4+
5+
const NAME = IS_DEV ? 'Polycentric Dev' : 'Polycentric';
6+
const ID = IS_DEV ? 'org.futo.polycentric.dev' : 'org.futo.polycentric';
7+
8+
export default ({ config }: ConfigContext): ExpoConfig => ({
9+
...config,
10+
name: NAME,
11+
slug: 'polycentric',
12+
version: '0.0.1',
13+
orientation: 'portrait',
14+
icon: './src/common/assets/images/AppIcon.png',
15+
scheme: 'polycentric',
16+
web: {
17+
output: 'server',
18+
},
19+
userInterfaceStyle: 'automatic',
20+
ios: {
21+
supportsTablet: true,
22+
bundleIdentifier: ID,
23+
infoPlist: {
24+
NSCameraUsageDescription: '$(PRODUCT_NAME) needs access to your Camera.',
25+
},
26+
},
27+
android: {
28+
adaptiveIcon: {
29+
foregroundImage: './src/common/assets/images/AppIcon.png',
30+
backgroundColor: '#ffffff',
31+
},
32+
edgeToEdgeEnabled: true,
33+
package: ID,
34+
permissions: ['android.permission.CAMERA'],
35+
},
36+
plugins: [
37+
'expo-router',
38+
[
39+
'expo-splash-screen',
40+
{
41+
image: './src/common/assets/images/AppIcon.png',
42+
imageWidth: 200,
43+
resizeMode: 'contain',
44+
backgroundColor: '#F2F5F9',
45+
},
46+
],
47+
'expo-font',
48+
'expo-web-browser',
49+
[
50+
'react-native-vision-camera',
51+
{
52+
cameraPermissionText: '$(PRODUCT_NAME) needs access to your Camera.',
53+
enableLocation: false,
54+
},
55+
],
56+
[
57+
'expo-dev-client',
58+
{
59+
launchMode: 'most-recent',
60+
},
61+
],
62+
[
63+
'expo-build-properties',
64+
{
65+
android: {
66+
buildArchs: ['arm64-v8a'],
67+
},
68+
},
69+
],
70+
'expo-image',
71+
],
72+
experiments: {
73+
typedRoutes: true,
74+
},
75+
extra: {
76+
router: {},
77+
eas: {
78+
projectId: '4db035ec-2de9-448a-a6cf-07347d6ae8b9',
79+
},
80+
},
81+
owner: 'futo-org',
82+
});

apps/polycentric/app.json

Lines changed: 0 additions & 76 deletions
This file was deleted.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { Atoms } from '@/src/common/theme';
2+
import { Slot } from 'expo-router';
3+
import { View } from 'react-native';
4+
import { useSafeAreaInsets } from 'react-native-safe-area-context';
5+
6+
export default function OnboardingLayout() {
7+
const insets = useSafeAreaInsets();
8+
return (
9+
<View style={[Atoms.flex_1, { paddingBottom: insets.bottom }]}>
10+
<Slot />
11+
</View>
12+
);
13+
}

apps/polycentric/app/(tabs)/_layout.tsx

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,32 @@
1+
import { useTheme } from '@/src/common/theme';
12
import { isWeb } from '@/src/common/util/platform';
2-
import { WideShell } from '@/src/features/wideshell';
3+
34
import { Slot } from 'expo-router';
45
import { NativeTabs } from 'expo-router/unstable-native-tabs';
56

67
export default function TabsLayout() {
8+
const { theme } = useTheme();
79
if (isWeb) {
810
return <Slot />;
911
}
1012

1113
return (
12-
<NativeTabs>
14+
<NativeTabs
15+
minimizeBehavior="onScrollDown"
16+
backgroundColor={theme.palette.neutral_0}
17+
iconColor={theme.palette.neutral_900}
18+
tintColor={theme.palette.neutral_900}
19+
indicatorColor={theme.palette.neutral_25}
20+
rippleColor={theme.palette.neutral_50}
21+
badgeBackgroundColor={theme.palette.primary_200}
22+
>
1323
<NativeTabs.Trigger name="feed">
1424
<NativeTabs.Trigger.Label>Feed</NativeTabs.Trigger.Label>
1525
<NativeTabs.Trigger.Icon sf="house.fill" md="home" />
1626
</NativeTabs.Trigger>
1727

18-
<NativeTabs.Trigger name="search">
19-
<NativeTabs.Trigger.Label>Search</NativeTabs.Trigger.Label>
28+
<NativeTabs.Trigger name="explore">
29+
<NativeTabs.Trigger.Label>Explore</NativeTabs.Trigger.Label>
2030
<NativeTabs.Trigger.Icon sf="magnifyingglass" md="search" />
2131
</NativeTabs.Trigger>
2232

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import FeedTabScreen from '@/src/features/feed/FeedScreen';
1+
import ExploreScreen from '@/src/features/feed/ExploreScreen';
22

33
export default function FeedIndexRoute() {
4-
return <FeedTabScreen />;
4+
return <ExploreScreen />;
55
}

apps/polycentric/package.json

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@
44
"version": "0.0.1",
55
"private": true,
66
"scripts": {
7-
"dev": "expo start",
8-
"android": "expo run:android",
9-
"ios": "expo run:ios",
7+
"dev": "APP_VARIANT=dev expo start",
8+
"android": "APP_VARIANT=dev expo run:android",
9+
"ios": "APP_VARIANT=dev expo run:ios",
10+
"android:prod": "expo run:android",
11+
"ios:prod": "expo run:ios",
1012
"web": "expo start --web",
1113
"build:web": "expo export --platform web",
1214
"lint": "expo lint",
13-
"prebuild": "expo prebuild --clean"
15+
"prebuild": "APP_VARIANT=dev expo prebuild --clean"
1416
},
1517
"dependencies": {
1618
"@expo/metro-runtime": "~55.0.9",

apps/polycentric/src/common/components/layout/Layout.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ function PrimaryColumn({ children }: PrimaryColumnProps) {
8585
testID="primaryColumn"
8686
style={[
8787
Atoms.flex_1,
88-
Atoms.pb_lg,
88+
isWeb && Atoms.pb_lg,
8989
{
9090
maxWidth: 600,
9191
borderLeftColor: theme.palette.neutral_25,
@@ -137,7 +137,7 @@ function Screen({
137137
return (
138138
<View
139139
testID="layout-screen"
140-
style={[Atoms.flex_row, Atoms.flex_1]}
140+
style={[Atoms.flex_row, Atoms.flex_1, { paddingTop: insets.top }]}
141141
dir="ltr"
142142
>
143143
{showLeftSidebar && <LeftSidebar />}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { Ionicons } from '@expo/vector-icons';
2+
import { Screen } from '@/src/common/components/layout';
3+
import { Fab } from '@/src/common/components';
4+
import { FeedViewer, type FeedType } from '@/src/features/post';
5+
import { useExploreFeed } from './hooks/useExploreFeed';
6+
import { openCompose } from '@/src/common/constants';
7+
import { isWeb } from '@/src/common/util/platform';
8+
9+
export default function ExploreScreen() {
10+
const showComposeFab = !isWeb;
11+
12+
const feed = useExploreFeed({
13+
enabled: true,
14+
});
15+
16+
const handleFabPress = () => {
17+
openCompose();
18+
};
19+
20+
return (
21+
<Screen>
22+
<Screen.PrimaryColumn>
23+
<FeedViewer
24+
items={feed.items}
25+
isLoading={feed.isLoading}
26+
error={feed.error}
27+
onRefresh={feed.refresh}
28+
onEndReached={feed.loadMore}
29+
hasMore={feed.hasMore}
30+
bottomPadding={0}
31+
/>
32+
{showComposeFab ? (
33+
<Fab
34+
title="New Post"
35+
onPress={handleFabPress}
36+
icon={() => <Ionicons name="add-circle" size={22} color="white" />}
37+
/>
38+
) : null}
39+
</Screen.PrimaryColumn>
40+
</Screen>
41+
);
42+
}

apps/polycentric/src/features/feed/FeedScreen.tsx

Lines changed: 9 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,33 +3,16 @@ import { Screen } from '@/src/common/components/layout';
33
import { Fab } from '@/src/common/components';
44
import { FeedViewer, type FeedType } from '@/src/features/post';
55
import { ComposerInput } from '@/src/features/composer';
6-
import { useExploreFeed } from './hooks/useExploreFeed';
76
import { useFollowingFeed } from './hooks/useFollowingFeed';
87
import { openCompose } from '@/src/common/constants';
98
import { isWeb } from '@/src/common/util/platform';
10-
import { usePathname } from 'expo-router';
11-
12-
function feedTypeFromPath(pathname: string): FeedType {
13-
// The /feed route shows the following feed; /explore is the public feed.
14-
// Default to explore so any unrelated caller gets a sensible view.
15-
return pathname.startsWith('/feed') ? 'following' : 'explore';
16-
}
179

1810
export default function FeedScreen() {
1911
const showComposeFab = !isWeb;
2012

21-
const pathname = usePathname();
22-
const selectedFeed = feedTypeFromPath(pathname);
23-
24-
const exploreFeed = useExploreFeed({
25-
enabled: selectedFeed === 'explore',
13+
const feed = useFollowingFeed({
14+
enabled: true,
2615
});
27-
const followingFeed = useFollowingFeed({
28-
enabled: selectedFeed === 'following',
29-
});
30-
31-
const currentFeed =
32-
selectedFeed === 'following' ? followingFeed : exploreFeed;
3316

3417
const handleFabPress = () => {
3518
openCompose();
@@ -38,15 +21,14 @@ export default function FeedScreen() {
3821
return (
3922
<Screen>
4023
<Screen.PrimaryColumn>
41-
{selectedFeed === 'following' ? <ComposerInput /> : null}
24+
<ComposerInput />
4225
<FeedViewer
43-
key={selectedFeed}
44-
items={currentFeed.items}
45-
isLoading={currentFeed.isLoading}
46-
error={currentFeed.error}
47-
onRefresh={currentFeed.refresh}
48-
onEndReached={currentFeed.loadMore}
49-
hasMore={currentFeed.hasMore}
26+
items={feed.items}
27+
isLoading={feed.isLoading}
28+
error={feed.error}
29+
onRefresh={feed.refresh}
30+
onEndReached={feed.loadMore}
31+
hasMore={feed.hasMore}
5032
bottomPadding={0}
5133
/>
5234
{showComposeFab ? (

0 commit comments

Comments
 (0)