Skip to content

Commit 0da3de8

Browse files
Merge upstream develop
2 parents a0e4fb4 + c7682a3 commit 0da3de8

44 files changed

Lines changed: 1436 additions & 641 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitlab/ci/build_app.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ app-web-image:
5959
- pnpm config set @polycentric:registry https://${CI_SERVER_HOST}/api/v4/projects/${CI_PROJECT_ID}/packages/npm/
6060
- pnpm install
6161
- apt-get update && apt-get install -y --no-install-recommends git
62+
# Tag builds use the tag version; others use the latest release + a patch.
63+
- export APP_VERSION=$(node "$CI_PROJECT_DIR/tools/expo/resolve-version.js")
64+
- echo "Building app version ${APP_VERSION}"
6265
- cd ./apps/polycentric
6366

6467
# EAS builds run: manual on merge requests, automatic on the default branch and

apps/polycentric/app.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export default ({ config }: ConfigContext): ExpoConfig => ({
99
...config,
1010
name: NAME,
1111
slug: 'polycentric',
12-
version: '0.0.1',
12+
version: process.env.APP_VERSION ?? '0.0.1',
1313
orientation: 'portrait',
1414
icon: './src/common/assets/images/app-icons/android-icon-foreground.png',
1515
scheme: 'polycentric',

apps/polycentric/app/_layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ function RootStack() {
4242
name="feed"
4343
options={{
4444
presentation: 'transparentModal',
45-
animation: 'none',
45+
animation: isWeb ? 'fade' : 'default',
4646
contentStyle: { backgroundColor: 'transparent' },
4747
}}
4848
/>

apps/polycentric/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
"@rn-primitives/hover-card": "^1.4.0",
3131
"@rn-primitives/popover": "^1.4.0",
3232
"@rn-primitives/portal": "^1.4.0",
33+
"@rn-primitives/radio-group": "^1.4.0",
34+
"@rn-primitives/toast": "^1.4.0",
3335
"@shopify/flash-list": "^2.3.1",
3436
"@types/react-native-web": "^0.19.2",
3537
"better-sqlite3": "^12.6.2",

apps/polycentric/src/common/components/Icon.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ function defineIcon<G extends string>(
2121
* Map of icon names to their icon set definitions
2222
*/
2323
export const IconsMap = {
24-
add: defineIcon(Ionicons, 'add-circle'),
24+
add: defineIcon(Ionicons, 'add'),
2525
addOutline: defineIcon(Ionicons, 'add-circle-outline'),
2626
arrowBack: defineIcon(Ionicons, 'arrow-back'),
2727
ban: defineIcon(Ionicons, 'ban'),
@@ -68,7 +68,7 @@ export type IconName = keyof typeof IconsMap;
6868
/** A palette token (resolved against the theme) or any raw color string. */
6969
type IconColor = PaletteColorToken | (string & {});
7070

71-
type IconProps = Omit<
71+
export type IconProps = Omit<
7272
ComponentProps<typeof Ionicons>,
7373
'name' | 'color' | 'size'
7474
> & {
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import * as RadioGroupPrimitive from '@rn-primitives/radio-group';
2+
import { useState } from 'react';
3+
import {
4+
StyleSheet,
5+
View,
6+
type GestureResponderEvent,
7+
type MouseEvent,
8+
type PressableStateCallbackType,
9+
} from 'react-native';
10+
import { Atoms, Spacing, useTheme } from '../../theme';
11+
12+
function RadioGroup({ ...props }: RadioGroupPrimitive.RootProps) {
13+
return <RadioGroupPrimitive.Root {...props} />;
14+
}
15+
16+
function RadioItem({
17+
style,
18+
onHoverIn,
19+
onHoverOut,
20+
onPressIn,
21+
onPressOut,
22+
...props
23+
}: RadioGroupPrimitive.ItemProps) {
24+
const [hovered, setHovered] = useState(false);
25+
const [pressed, setPressed] = useState(false);
26+
27+
const resolved =
28+
typeof style === 'function'
29+
? style({
30+
hovered,
31+
pressed,
32+
focused: false,
33+
} as PressableStateCallbackType)
34+
: style;
35+
36+
return (
37+
<RadioGroupPrimitive.Item
38+
{...props}
39+
onHoverIn={(e: MouseEvent) => {
40+
setHovered(true);
41+
onHoverIn?.(e);
42+
}}
43+
onHoverOut={(e: MouseEvent) => {
44+
setHovered(false);
45+
onHoverOut?.(e);
46+
}}
47+
onPressIn={(e: GestureResponderEvent) => {
48+
setPressed(true);
49+
onPressIn?.(e);
50+
}}
51+
onPressOut={(e: GestureResponderEvent) => {
52+
setPressed(false);
53+
onPressOut?.(e);
54+
}}
55+
style={StyleSheet.flatten(resolved)}
56+
/>
57+
);
58+
}
59+
60+
function RadioIndicator() {
61+
const { theme } = useTheme();
62+
return (
63+
<View
64+
style={[
65+
Atoms.items_center,
66+
Atoms.justify_center,
67+
{
68+
width: Spacing['xl'],
69+
height: Spacing['xl'],
70+
borderRadius: Spacing['md'],
71+
borderWidth: Spacing['2xs'],
72+
borderColor: theme.palette.neutral_500,
73+
},
74+
]}
75+
>
76+
<RadioGroupPrimitive.Indicator>
77+
<View
78+
style={{
79+
width: Spacing['md'],
80+
height: Spacing['md'],
81+
borderRadius: Spacing['sm'],
82+
backgroundColor: theme.palette.primary_500,
83+
}}
84+
/>
85+
</RadioGroupPrimitive.Indicator>
86+
</View>
87+
);
88+
}
89+
90+
RadioGroup.Item = RadioItem;
91+
RadioGroup.Indicator = RadioIndicator;
92+
93+
export default RadioGroup;

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

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
1+
import Icon from '@/src/common/components/Icon';
2+
import { Image } from 'expo-image';
13
import { Link, router, useSegments } from 'expo-router';
4+
import { memo, type ReactNode } from 'react';
25
import { Pressable, View } from 'react-native';
3-
import { Atoms, Spacing, useTheme, withHexOpacity } from '../../theme';
4-
import { Image } from 'expo-image';
5-
import Icon from '@/src/common/components/Icon';
66
import BLUE_LOGO from '../../assets/images/polycentric-logo-blue-256.png';
77
import WHITE_LOGO from '../../assets/images/polycentric-logo-white-256.png';
8-
import { ProfileAvatar, Text } from '../primitives';
98
import { useCurrentIdentity } from '../../lib/polycentric-hooks';
10-
import { memo, type ReactNode } from 'react';
9+
import { Atoms, Spacing, useTheme, withHexOpacity } from '../../theme';
10+
import { ProfileAvatar, Text } from '../primitives';
1111

1212
const SIDE_WIDTH = 32;
1313

1414
type TopbarProps = {
1515
title?: string;
16+
left?: ReactNode;
1617
/**
1718
* Replaces the default centred title/logo. Use this when the centre
1819
* slot needs a non-navigational element (e.g. a search bar).
@@ -22,7 +23,7 @@ type TopbarProps = {
2223
right?: ReactNode;
2324
};
2425

25-
function Topbar({ title, center, right }: TopbarProps) {
26+
function Topbar({ title, left, center, right }: TopbarProps) {
2627
const { identity: currentIdentity } = useCurrentIdentity();
2728
const { theme } = useTheme();
2829

@@ -56,32 +57,33 @@ function Topbar({ title, center, right }: TopbarProps) {
5657
Atoms.items_start,
5758
]}
5859
>
59-
{canGoBack ? (
60-
<Pressable
61-
accessibilityRole="button"
62-
accessibilityLabel="Go back"
63-
onPress={() => router.back()}
64-
hitSlop={Spacing['lg']}
65-
style={({ pressed }) => [pressed && { opacity: 0.5 }]}
66-
>
67-
<Icon name="chevronBack" size={24} color="neutral_900" />
68-
</Pressable>
69-
) : (
70-
<ProfileAvatar
71-
identityKey={identityKey ?? ''}
72-
size="sm"
73-
containerProps={{ hitSlop: Spacing['lg'] }}
74-
onPress={
75-
identityKey
76-
? () =>
77-
router.push({
78-
pathname: '/profile/[identityId]',
79-
params: { identityId: identityKey },
80-
})
81-
: undefined
82-
}
83-
/>
84-
)}
60+
{left ??
61+
(canGoBack ? (
62+
<Pressable
63+
accessibilityRole="button"
64+
accessibilityLabel="Go back"
65+
onPress={() => router.back()}
66+
hitSlop={Spacing['lg']}
67+
style={({ pressed }) => [pressed && { opacity: 0.5 }]}
68+
>
69+
<Icon name="chevronBack" size={24} color="neutral_900" />
70+
</Pressable>
71+
) : (
72+
<ProfileAvatar
73+
identityKey={identityKey ?? ''}
74+
size="sm"
75+
containerProps={{ hitSlop: Spacing['lg'] }}
76+
onPress={
77+
identityKey
78+
? () =>
79+
router.push({
80+
pathname: '/profile/[identityId]',
81+
params: { identityId: identityKey },
82+
})
83+
: undefined
84+
}
85+
/>
86+
))}
8587
</View>
8688
<View
8789
style={[

apps/polycentric/src/common/components/primitives/Button.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ const SIZE_CONFIG: Record<
5555
> = {
5656
sm: {
5757
paddingV: 4,
58-
paddingH: Spacing['lg'],
58+
paddingH: Spacing['md'],
5959
iconSize: 16,
6060
borderRadius: 'full',
6161
},
@@ -184,7 +184,7 @@ function getVariantStyle(theme: Theme, variant: ButtonVariant) {
184184
case 'primary':
185185
return {
186186
backgroundColor: theme.palette.primary_500,
187-
borderColor: theme.palette.primary_600,
187+
borderColor: theme.palette.primary_500,
188188
shadowColor: theme.palette.primary_900,
189189
shadowOpacity: 0.22,
190190
shadowRadius: 10,

0 commit comments

Comments
 (0)