EAS integration & Improvements & fixes (#334)

* fix: issues with build after debugging expo app

* feat: updates icons app and increases build version

* fix: react-native-svg resolution

* feat: multiple fixes and top bar implementation

* fix: sidebar members animation

Co-authored-by: marcelines <marcio@significa.co>
This commit is contained in:
marcelines 2023-01-24 13:41:25 +00:00 committed by GitHub
parent 16b2c13a47
commit 9e613244e0
No known key found for this signature in database
GPG Key ID: 0EB8D75C775AB6F1
27 changed files with 346 additions and 184 deletions

View File

@ -4,11 +4,14 @@ import 'expo-dev-client'
import { useMemo, useState } from 'react' import { useMemo, useState } from 'react'
import { useNavigation, useRoute } from '@react-navigation/native'
import { createNativeStackNavigator } from '@react-navigation/native-stack' import { createNativeStackNavigator } from '@react-navigation/native-stack'
import { Heading } from '@status-im/components' import { Heading, IconButton, Paragraph } from '@status-im/components'
import { Avatar } from '@status-im/components/src/avatar' import { Avatar } from '@status-im/components/src/avatar'
import { ArrowLeftIcon, MembersIcon } from '@status-im/icons/20'
import { Stack as View, TamaguiProvider } from '@tamagui/core' import { Stack as View, TamaguiProvider } from '@tamagui/core'
import { useFonts } from 'expo-font' import { useFonts } from 'expo-font'
import { Platform } from 'react-native'
import { SafeAreaProvider } from 'react-native-safe-area-context' import { SafeAreaProvider } from 'react-native-safe-area-context'
import { AnimatePresence } from 'tamagui' import { AnimatePresence } from 'tamagui'
@ -17,7 +20,34 @@ import { ChannelScreen } from './screens/channel'
import { HomeScreen } from './screens/home' import { HomeScreen } from './screens/home'
import tamaguiConfig from './tamagui.config' import tamaguiConfig from './tamagui.config'
const Stack = createNativeStackNavigator() import type { RouteProp } from '@react-navigation/native'
import type { HeaderBackButtonProps } from '@react-navigation/native-stack/lib/typescript/src/types'
export type RootStackParamList = {
Home: undefined
Channel: { channelId: string }
}
const Stack = createNativeStackNavigator<RootStackParamList>()
const CustomHeaderLeft = (props: HeaderBackButtonProps) => {
const navigation = useNavigation()
const route = useRoute<RouteProp<RootStackParamList, 'Channel'>>()
return (
<>
<IconButton
icon={<ArrowLeftIcon />}
onPress={() => {
props.canGoBack && navigation.goBack()
}}
/>
<Paragraph weight="semibold" marginLeft={12}>
# {route.params.channelId || 'channel'}
</Paragraph>
</>
)
}
export default function App() { export default function App() {
const [position, setPosition] = useState(0) const [position, setPosition] = useState(0)
@ -49,13 +79,16 @@ export default function App() {
<TamaguiProvider config={tamaguiConfig} defaultTheme="light"> <TamaguiProvider config={tamaguiConfig} defaultTheme="light">
<NavigationProvider> <NavigationProvider>
<SafeAreaProvider> <SafeAreaProvider>
<Stack.Navigator> <Stack.Navigator
screenOptions={{
animation: 'slide_from_right',
}}
>
<Stack.Screen <Stack.Screen
name="Home" name="Home"
options={{ options={{
headerBlurEffect: 'systemUltraThinMaterialLight',
headerTransparent: true, headerTransparent: true,
headerShadowVisible: true, headerShadowVisible: false,
header: () => ( header: () => (
<View <View
height={100} height={100}
@ -113,7 +146,31 @@ export default function App() {
<Stack.Screen <Stack.Screen
name="Channel" name="Channel"
component={ChannelScreen} component={ChannelScreen}
options={{ title: 'Messages' }} options={{
headerBlurEffect: 'systemUltraThinMaterialLight',
headerStyle: {
backgroundColor: Platform.select({
ios: 'transparent',
default: 'white',
}),
},
headerTransparent: true,
headerShadowVisible: false,
headerTitle: '',
headerLeft(props) {
return <CustomHeaderLeft {...props} />
},
headerRight() {
return (
<IconButton
icon={<MembersIcon />}
onPress={() => {
// noop
}}
/>
)
},
}}
/> />
</Stack.Navigator> </Stack.Navigator>
</SafeAreaProvider> </SafeAreaProvider>

View File

@ -1,8 +1,8 @@
{ {
"expo": { "expo": {
"name": "mobile", "name": "mobile",
"slug": "mobile", "slug": "status-poc",
"version": "1.0.0", "version": "1.0.2",
"orientation": "portrait", "orientation": "portrait",
"icon": "./assets/icon.png", "icon": "./assets/icon.png",
"userInterfaceStyle": "light", "userInterfaceStyle": "light",
@ -16,16 +16,24 @@
}, },
"assetBundlePatterns": ["**/*"], "assetBundlePatterns": ["**/*"],
"ios": { "ios": {
"supportsTablet": true "supportsTablet": true,
"bundleIdentifier": "com.marcelines.statuspoc"
}, },
"android": { "android": {
"adaptiveIcon": { "adaptiveIcon": {
"foregroundImage": "./assets/adaptive-icon.png", "foregroundImage": "./assets/adaptive-icon.png",
"backgroundColor": "#FFFFFF" "backgroundColor": "#FFFFFF"
} },
"package": "com.marcelines.statuspoc"
}, },
"web": { "web": {
"favicon": "./assets/favicon.png" "favicon": "./assets/favicon.png"
} },
"extra": {
"eas": {
"projectId": "e214cc8a-4e7e-4850-8a41-e280ca3a4469"
}
},
"owner": "marcelines"
} }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 24 KiB

23
apps/mobile/eas.json Normal file
View File

@ -0,0 +1,23 @@
{
"cli": {
"version": ">= 3.3.2"
},
"build": {
"development": {
"developmentClient": true,
"distribution": "internal"
},
"preview": {
"distribution": "internal"
},
"production": {},
"simulator": {
"ios": {
"simulator": true
}
}
},
"submit": {
"production": {}
}
}

View File

@ -6,18 +6,19 @@
"scripts": { "scripts": {
"dev": "expo start -c", "dev": "expo start -c",
"ios": "TAMAGUI_TARGET=native yarn expo run:ios", "ios": "TAMAGUI_TARGET=native yarn expo run:ios",
"android": "TAMAGUI_TARGET=native yarn expo run:android" "android": "TAMAGUI_TARGET=native yarn expo run:android",
"start": "expo start --dev-client"
}, },
"dependencies": { "dependencies": {
"@babel/runtime": "^7.18.9", "@babel/runtime": "^7.18.9",
"@react-navigation/native": "^6.1.2", "@react-navigation/native": "^6.1.2",
"@react-navigation/native-stack": "^6.9.8", "@react-navigation/native-stack": "^6.9.8",
"@status-im/components": "*", "@status-im/components": "*",
"expo": "^47.0.12", "expo": "~47.0.12",
"expo-constants": "^14.0.2", "expo-constants": "^14.0.2",
"expo-dev-client": "^2.0.1", "expo-dev-client": "^2.0.1",
"expo-linear-gradient": "^12.0.1", "expo-linear-gradient": "^12.0.1",
"expo-splash-screen": "^0.17.5", "expo-splash-screen": "~0.17.5",
"expo-status-bar": "^1.4.2", "expo-status-bar": "^1.4.2",
"expo-updates": "^0.15.6", "expo-updates": "^0.15.6",
"react": "18.1.0", "react": "18.1.0",
@ -25,6 +26,7 @@
"react-native": "0.70.5", "react-native": "0.70.5",
"react-native-safe-area-context": "4.4.1", "react-native-safe-area-context": "4.4.1",
"react-native-screens": "~3.18.0", "react-native-screens": "~3.18.0",
"react-native-svg": "^13.7.0",
"react-native-web": "~0.18.7" "react-native-web": "~0.18.7"
}, },
"devDependencies": { "devDependencies": {

View File

@ -1,7 +1,11 @@
// eslint-disable-next-line eslint-comments/disable-enable-pair // eslint-disable-next-line eslint-comments/disable-enable-pair
/* eslint-disable import/namespace */ /* eslint-disable import/namespace */
import { useRef } from 'react'
import { Composer, Messages } from '@status-im/components' import { Composer, Messages } from '@status-im/components'
import { Stack, useTheme } from '@tamagui/core' import { Stack, useTheme } from '@tamagui/core'
import { StatusBar } from 'expo-status-bar'
import { import {
Keyboard, Keyboard,
KeyboardAvoidingView, KeyboardAvoidingView,
@ -11,22 +15,41 @@ import {
import { useSafeAreaInsets } from 'react-native-safe-area-context' import { useSafeAreaInsets } from 'react-native-safe-area-context'
import { ScrollView } from 'tamagui' import { ScrollView } from 'tamagui'
export const ChannelScreen = () => { import type { RootStackParamList } from '../App'
import type { NativeStackScreenProps } from '@react-navigation/native-stack'
type ChannelScreenProps = NativeStackScreenProps<RootStackParamList, 'Channel'>
export const ChannelScreen = ({ route }: ChannelScreenProps) => {
const insets = useSafeAreaInsets() const insets = useSafeAreaInsets()
const theme = useTheme() const theme = useTheme()
// We need to get the channel name from the route params
const channelName = route.params.channelId
const scrollRef = useRef(null)
return ( return (
<KeyboardAvoidingView <KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : 'height'} behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
keyboardVerticalOffset={Platform.select({ ios: 60 })}
style={{ height: '100%', flex: 1, backgroundColor: theme.background.val }} style={{ height: '100%', flex: 1, backgroundColor: theme.background.val }}
> >
<ScrollView paddingHorizontal={12} width="100%"> <StatusBar style={'dark'} animated />
<Messages py={20} /> <ScrollView
ref={scrollRef}
paddingHorizontal={12}
width="100%"
onContentSizeChange={() => scrollRef.current?.scrollToEnd()}
>
<Stack pt={insets.top + 60} pb={insets.bottom}>
<Messages />
</Stack>
</ScrollView> </ScrollView>
<TouchableWithoutFeedback onPress={Keyboard.dismiss}> <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<Stack pb={insets.bottom}> <Stack>
<Composer /> <Composer
pb={insets.bottom + Platform.select({ android: 12, ios: 0 })}
/>
</Stack> </Stack>
</TouchableWithoutFeedback> </TouchableWithoutFeedback>
</KeyboardAvoidingView> </KeyboardAvoidingView>

View File

@ -1,18 +1,27 @@
// eslint-disable-next-line eslint-comments/disable-enable-pair // eslint-disable-next-line eslint-comments/disable-enable-pair
/* eslint-disable import/namespace */ /* eslint-disable import/namespace */
import { useState } from 'react'
import { Sidebar } from '@status-im/components' import { Sidebar } from '@status-im/components'
import { Stack } from '@tamagui/core' import { Stack } from '@tamagui/core'
import { StatusBar } from 'expo-status-bar' import { StatusBar } from 'expo-status-bar'
import { ScrollView } from 'tamagui' import { ScrollView } from 'tamagui'
export const HomeScreen = ({ navigation, onScroll, isMinimized }) => { import type { RootStackParamList } from '../App'
const [selectedChannel, setSelectedChannel] = useState<string>('welcome') import type { NativeStackScreenProps } from '@react-navigation/native-stack'
import type { NativeScrollEvent, NativeSyntheticEvent } from 'react-native'
type HomeScreenProps = NativeStackScreenProps<RootStackParamList, 'Home'> & {
onScroll: (event: NativeSyntheticEvent<NativeScrollEvent>) => void
isMinimized?: boolean
}
export const HomeScreen = ({
navigation,
onScroll,
isMinimized,
}: HomeScreenProps) => {
const onChannelPress = (id: string) => { const onChannelPress = (id: string) => {
setSelectedChannel(id) navigation.navigate('Channel', { channelId: id })
navigation.navigate('Channel')
} }
return ( return (
@ -25,7 +34,6 @@ export const HomeScreen = ({ navigation, onScroll, isMinimized }) => {
description="Multichain community-centric NFT marketplace. Create, buy and sell your NFTs." description="Multichain community-centric NFT marketplace. Create, buy and sell your NFTs."
membersCount={123} membersCount={123}
onChannelPress={onChannelPress} onChannelPress={onChannelPress}
selectedChannel={selectedChannel}
/> />
</Stack> </Stack>
</ScrollView> </ScrollView>

View File

@ -1,41 +1,35 @@
import { useState } from 'react' import { useState } from 'react'
import { import {
Button,
Code,
Composer, Composer,
Heading,
Label,
Messages, Messages,
Paragraph,
Shape,
Sidebar, Sidebar,
SidebarMembers, SidebarMembers,
Topbar,
} from '@status-im/components' } from '@status-im/components'
import { Stack, styled, TamaguiProvider } from '@tamagui/core' import { Stack, styled, TamaguiProvider } from '@tamagui/core'
import { AnimatePresence } from 'tamagui'
// import { AnimatePresence } from 'tamagui'
import tamaguiConfig from '../tamagui.config' import tamaguiConfig from '../tamagui.config'
import { Topbar } from './components/topbar'
type ThemeVars = 'light' | 'dark' type ThemeVars = 'light' | 'dark'
// const AnimatableDrawer = styled(Stack, { const AnimatableDrawer = styled(Stack, {
// variants: { variants: {
// fromRight: { fromRight: {
// true: { true: {
// x: 500, x: 500,
// width: 0, width: 0,
// }, },
// }, },
// fromLeft: { fromLeft: {
// true: { true: {
// x: 500, x: 500,
// width: 250, width: 250,
// }, },
// }, },
// }, },
// }) })
function App() { function App() {
const [theme, setTheme] = useState<ThemeVars>('light') const [theme, setTheme] = useState<ThemeVars>('light')
@ -61,6 +55,8 @@ function App() {
</div> </div>
<main id="main"> <main id="main">
<Topbar <Topbar
title={`#${selectedChannel}`}
description="Share random funny stuff with the community. Play nice."
membersVisisble={showMembers} membersVisisble={showMembers}
onMembersPress={() => setShowMembers(show => !show)} onMembersPress={() => setShowMembers(show => !show)}
/> />
@ -69,12 +65,27 @@ function App() {
</div> </div>
<Composer /> <Composer />
</main> </main>
<AnimatePresence enterVariant="fromRight" exitVariant="fromLeft">
{showMembers && ( {showMembers && (
<div id="members"> <AnimatableDrawer
<SidebarMembers /> id="members"
</div> key="members"
)} animation={[
'fast',
{
opacity: {
overshootClamping: true,
},
},
]}
enterStyle={{ opacity: 0 }}
exitStyle={{ opacity: 0 }}
opacity={1}
>
<SidebarMembers />
</AnimatableDrawer>
)}
</AnimatePresence>
</div> </div>
</TamaguiProvider> </TamaguiProvider>
) )

View File

@ -1,44 +0,0 @@
import { Divider, IconButton, Paragraph } from '@status-im/components'
import { LockedIcon, MembersIcon, OptionsIcon } from '@status-im/icons/20'
import { Stack } from '@tamagui/core'
type Props = {
membersVisisble: boolean
onMembersPress: () => void
}
export const Topbar = (props: Props) => {
const { membersVisisble, onMembersPress } = props
return (
<Stack
flexDirection="row"
height={56}
alignItems="center"
justifyContent="space-between"
padding={16}
borderBottomWidth={1}
borderColor="$neutral-10"
>
<Stack flexDirection="row" alignItems="center">
<Paragraph weight="semibold" marginRight={4}>
# random
</Paragraph>
<LockedIcon color="rgba(27, 39, 61, 0.4)" size={16} />
<Divider height={16} />
<Paragraph weight="medium" color="$neutral-80-opa-50" variant="smaller">
Share random funny stuff with the community. Play nice.
</Paragraph>
</Stack>
<Stack space={12} flexDirection="row">
<IconButton
icon={<MembersIcon />}
selected={membersVisisble}
onPress={onMembersPress}
/>
<IconButton icon={<OptionsIcon />} />
</Stack>
</Stack>
)
}

View File

@ -22,7 +22,8 @@
}, },
"resolutions": { "resolutions": {
"react": "18.1.0", "react": "18.1.0",
"react-dom": "18.1.0" "react-dom": "18.1.0",
"react-native-svg": "13.4.0"
}, },
"devDependencies": { "devDependencies": {
"@changesets/cli": "^2.23.0", "@changesets/cli": "^2.23.0",

View File

@ -1,4 +1,4 @@
import React from 'react' import React, { useState } from 'react'
import { ChevronRightIcon } from '@status-im/icons/20' import { ChevronRightIcon } from '@status-im/icons/20'
import { Stack } from '@tamagui/core' import { Stack } from '@tamagui/core'
@ -12,21 +12,18 @@ type BaseProps = GetProps<typeof Stack>
type Props = { type Props = {
children: React.ReactElement[] | React.ReactElement children: React.ReactElement[] | React.ReactElement
isExpanded: boolean initialExpanded: boolean
onToggle?: () => void
title: string title: string
numberOfNewMessages?: number numberOfNewMessages?: number
showNotifications?: boolean
} & BaseProps } & BaseProps
const Accordion = ({ const Accordion = ({
children, children,
isExpanded, initialExpanded,
onToggle,
title, title,
numberOfNewMessages, numberOfNewMessages,
showNotifications,
}: Props) => { }: Props) => {
const [isExpanded, setIsExpanded] = useState(initialExpanded)
return ( return (
<Stack <Stack
width="100%" width="100%"
@ -41,7 +38,7 @@ const Accordion = ({
width="100%" width="100%"
flexDirection="row" flexDirection="row"
justifyContent={'space-between'} justifyContent={'space-between'}
onPress={onToggle} onPress={() => setIsExpanded(prev => !prev)}
cursor="pointer" cursor="pointer"
py={8} py={8}
> >
@ -70,7 +67,7 @@ const Accordion = ({
</Paragraph> </Paragraph>
</Stack> </Stack>
<AnimatePresence> <AnimatePresence>
{showNotifications && numberOfNewMessages && ( {!isExpanded && numberOfNewMessages && (
<Stack <Stack
key={`notifications-${title}}`} key={`notifications-${title}}`}
width={20} width={20}

View File

@ -15,7 +15,7 @@ import type { GetProps } from '@tamagui/core'
const Base = styled(Stack, { const Base = styled(Stack, {
name: 'Avatar', name: 'Avatar',
display: 'inline-flex', display: 'flex',
position: 'relative', position: 'relative',
backgroundColor: '$white-100', backgroundColor: '$white-100',
justifyContent: 'center', justifyContent: 'center',
@ -78,20 +78,20 @@ const Indicator = styled(Stack, {
right: 2, right: 2,
zIndex: 2, zIndex: 2,
borderWidth: '2px', borderWidth: 2,
borderColor: '$white-100', borderColor: '$white-100',
variants: { variants: {
size: { size: {
80: { 80: {
width: 12, width: 10,
height: 12, height: 10,
borderRadius: '50%', borderRadius: 10 / 2,
}, },
56: { 56: {
width: 12, width: 10,
height: 12, height: 10,
borderRadius: 12 / 2, borderRadius: 10 / 2,
}, },
// FIXME: use catch all variant // FIXME: use catch all variant
52: { 52: {

View File

@ -10,8 +10,12 @@ const Base = styled(Stack, {
accessibilityRole: 'button', accessibilityRole: 'button',
borderRadius: 12, borderRadius: 12,
display: 'flex',
paddingHorizontal: 16,
paddingTop: 7,
paddingBottom: 9,
cursor: 'pointer', cursor: 'pointer',
display: 'inline-flex',
alignItems: 'center', alignItems: 'center',
animation: 'fast', animation: 'fast',
userSelect: 'none', userSelect: 'none',
@ -65,7 +69,7 @@ const Base = styled(Stack, {
const ButtonText = styled(Paragraph, { const ButtonText = styled(Paragraph, {
textAlign: 'center', textAlign: 'center',
weight: 'medium', weight: 'medium',
display: 'inline-flex', display: 'flex',
alignItems: 'center', alignItems: 'center',
space: 4, space: 4,

View File

@ -22,21 +22,15 @@ const Composer = (props: BaseProps) => {
shadowRadius={20} shadowRadius={20}
borderTopLeftRadius={20} borderTopLeftRadius={20}
borderTopRightRadius={20} borderTopRightRadius={20}
elevation={0}
px={16} px={16}
pt={8} pt={8}
pb={12}
width="100%" width="100%"
style={{
elevation: 10,
}}
{...props} {...props}
> >
<YStack> <Input placeholder="Type something..." borderWidth={0} px={0} />
<Input
elevation={10}
placeholder="Type something..."
borderWidth={0}
px={0}
/>
</YStack>
<XStack alignItems="center" justifyContent="space-between" pt={8}> <XStack alignItems="center" justifyContent="space-between" pt={8}>
<Stack space={12} flexDirection="row"> <Stack space={12} flexDirection="row">
<IconButton icon={<ImageIcon />} transparent /> <IconButton icon={<ImageIcon />} transparent />

View File

@ -8,6 +8,7 @@ export const Divider = styled(Stack, {
flex: 1, flex: 1,
height: '100%', height: '100%',
// maxHeight: 0, // maxHeight: 0,
maxWidth: 1,
width: 1, width: 1,
marginHorizontal: 12, marginHorizontal: 12,
// y: -0.5, // y: -0.5,

View File

@ -12,7 +12,7 @@ export function themed(Component: React.ElementType) {
<Stack <Stack
width={sizeBackground} width={sizeBackground}
height={sizeBackground} height={sizeBackground}
borderRadius="50%" borderRadius={sizeBackground / 2}
backgroundColor="$turquoise-50-opa-10" backgroundColor="$turquoise-50-opa-10"
justifyContent="center" justifyContent="center"
alignItems="center" alignItems="center"

View File

@ -2,7 +2,6 @@ import { cloneElement } from 'react'
import { Stack, styled, Text } from '@tamagui/core' import { Stack, styled, Text } from '@tamagui/core'
// import { Pressable } from 'react-native'
import type React from 'react' import type React from 'react'
const Base = styled(Stack, { const Base = styled(Stack, {
@ -12,6 +11,9 @@ const Base = styled(Stack, {
cursor: 'pointer', cursor: 'pointer',
userSelect: 'none', userSelect: 'none',
borderRadius: 10, borderRadius: 10,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
animation: 'fast', animation: 'fast',
width: 30, width: 30,

View File

@ -8,6 +8,7 @@ export * from './input'
export * from './messages' export * from './messages'
export * from './sidebar' export * from './sidebar'
export * from './sidebar-members' export * from './sidebar-members'
export * from './topbar'
export * from './typography' export * from './typography'
export * from './user-list' export * from './user-list'

View File

@ -25,7 +25,7 @@ const ReactButton = styled(Stack, {
cursor: 'pointer', cursor: 'pointer',
userSelect: 'none', userSelect: 'none',
borderRadius: 8, borderRadius: 8,
display: 'inline-flex', display: 'flex',
flexDirection: 'row', flexDirection: 'row',
space: 4, space: 4,
alignItems: 'center', alignItems: 'center',
@ -82,7 +82,7 @@ export const Reactions = (props: Props) => {
console.log(reactions) console.log(reactions)
return ( return (
<XStack space={8}> <XStack space={8} flexWrap="wrap">
<ReactionButton count={1} icon={<LoveIcon />} selected /> <ReactionButton count={1} icon={<LoveIcon />} selected />
<ReactionButton count={10} icon={<ThumbsUpIcon />} /> <ReactionButton count={10} icon={<ThumbsUpIcon />} />
<ReactionButton count={99} icon={<ThumbsDownIcon />} /> <ReactionButton count={99} icon={<ThumbsDownIcon />} />

View File

@ -1,5 +1,3 @@
import { useState } from 'react'
import { GroupIcon } from '@status-im/icons/16' import { GroupIcon } from '@status-im/icons/16'
import { Stack } from '@tamagui/core' import { Stack } from '@tamagui/core'
@ -35,26 +33,6 @@ const Sidebar = (props: Props) => {
onChannelPress, onChannelPress,
} = props } = props
const communitiesExpandControl = communities.reduce(
(o, key) => ({ ...o, [key.id]: false }),
{} as Record<string, boolean>[]
)
const [isExpanded, setIsExpanded] = useState({
...communitiesExpandControl,
welcome: true,
community: true,
design: true,
})
const handleToggle = (id: string) => {
setIsExpanded(prev => ({
...prev,
[id]: !prev[id as keyof typeof isExpanded],
}))
}
return ( return (
<Stack <Stack
backgroundColor="$background" backgroundColor="$background"
@ -96,13 +74,10 @@ const Sidebar = (props: Props) => {
{communities.map(community => ( {communities.map(community => (
<Accordion <Accordion
key={community.id} key={community.id}
isExpanded={!!isExpanded[community.id as keyof typeof isExpanded]} // This is just for the demo
onToggle={() => handleToggle(community.id)} initialExpanded={community.id === 'welcome'}
title={community.title} title={community.title}
numberOfNewMessages={community.numberOfNewMessages} numberOfNewMessages={community.numberOfNewMessages}
showNotifications={
!isExpanded[community.id as keyof typeof isExpanded]
}
> >
{community.channels.map((channel, index) => { {community.channels.map((channel, index) => {
const isLastChannelOfTheList = const isLastChannelOfTheList =

View File

@ -0,0 +1 @@
export { Topbar } from './topbar'

View File

@ -0,0 +1,71 @@
import { Divider, IconButton, Paragraph } from '@status-im/components'
import {
ArrowLeftIcon,
LockedIcon,
MembersIcon,
OptionsIcon,
} from '@status-im/icons/20'
import { Stack } from '@tamagui/core'
type Props = {
membersVisisble: boolean
onMembersPress: () => void
goBack?: () => void
title?: string
description?: string
}
const Topbar = (props: Props) => {
const { membersVisisble, onMembersPress, goBack, title, description } = props
return (
<Stack
flexDirection="row"
height={56}
alignItems="center"
justifyContent="space-between"
padding={16}
borderBottomWidth={1}
borderColor="$neutral-10"
width="100%"
>
<Stack flexDirection="row" alignItems="center" flexWrap="wrap">
<Stack mr={12} $gtSm={{ display: 'none' }}>
<IconButton icon={<ArrowLeftIcon />} onPress={() => goBack?.()} />
</Stack>
{title && (
<Paragraph weight="semibold" marginRight={4}>
{title}
</Paragraph>
)}
<LockedIcon color="$neutral-80-opa-40" />
<Divider height={16} $sm={{ display: 'none' }} />
{description && (
<Paragraph
weight="medium"
color="$neutral-80-opa-50"
variant="smaller"
$sm={{ display: 'none' }}
>
{description}
</Paragraph>
)}
</Stack>
<Stack space={12} flexDirection="row">
<Stack $sm={{ display: 'none' }}>
<IconButton
icon={<MembersIcon />}
selected={membersVisisble}
onPress={onMembersPress}
/>
</Stack>
<IconButton icon={<OptionsIcon />} />
</Stack>
</Stack>
)
}
export { Topbar }

View File

@ -11,12 +11,12 @@ export const Heading = styled(SizableText, {
h1: { h1: {
fontSize: 27, fontSize: 27,
lineHeight: 32, lineHeight: 32,
letterSpacing: '-0.021em', letterSpacing: -0.021,
}, },
h2: { h2: {
fontSize: 19, fontSize: 19,
lineHeight: 26, lineHeight: 26,
letterSpacing: '-0.016em', letterSpacing: -0.016,
}, },
}, },
uppercase: { uppercase: {
@ -53,17 +53,17 @@ export const Paragraph = styled(SizableText, {
normal: { normal: {
fontSize: 15, fontSize: 15,
lineHeight: 22, lineHeight: 22,
letterSpacing: '-0.009em', letterSpacing: -0.009,
}, },
smaller: { smaller: {
fontSize: 13, fontSize: 13,
lineHeight: 18, lineHeight: 18,
letterSpacing: '-0.003em', letterSpacing: -0.003,
}, },
11: { 11: {
fontSize: 11, fontSize: 11,
lineHeight: 18, lineHeight: 18,
letterSpacing: '-0.003em', letterSpacing: -0.003,
}, },
}, },
uppercase: { uppercase: {
@ -98,7 +98,7 @@ export const Label = styled(SizableText, {
fontSize: 11, fontSize: 11,
lineHeight: 16, lineHeight: 16,
letterSpacing: '-0.005em', letterSpacing: -0.005,
variants: { variants: {
uppercase: { uppercase: {
@ -132,18 +132,18 @@ export const Code = styled(SizableText, {
fontSize: 11, fontSize: 11,
lineHeight: 16, lineHeight: 16,
letterSpacing: '-0.005em', letterSpacing: -0.005,
variants: { variants: {
normal: { normal: {
fontSize: 15, fontSize: 15,
lineHeight: 22, lineHeight: 22,
letterSpacing: '-0.009em', letterSpacing: -0.009,
}, },
smaller: { smaller: {
fontSize: 13, fontSize: 13,
lineHeight: 18, lineHeight: 18,
letterSpacing: '-0.003em', letterSpacing: -0.003,
}, },
uppercase: { uppercase: {
true: { true: {

View File

@ -0,0 +1,27 @@
import { memo } from 'react'
import { themed } from '@status-im/icons/src/themed'
import { Path, Svg } from 'react-native-svg'
import type { IconProps } from './types'
function Icon(props: IconProps) {
const { color, size = 20, ...otherProps } = props
return (
<Svg
width={size}
height={size}
viewBox={`0 0 ${size} ${size}`}
fill="none"
{...otherProps}
>
<Path
d="m5.569 9.35 3.89-3.89-.919-.92-5 5-.46.46.46.46 5 5 .92-.92-3.891-3.89h10.43v-1.3H5.57Z"
fill={`${color}`}
/>
</Svg>
)
}
export const ArrowIcon = memo<IconProps>(themed(Icon))

View File

@ -10682,10 +10682,10 @@ expo-manifests@~0.4.0:
dependencies: dependencies:
expo-json-utils "~0.4.0" expo-json-utils "~0.4.0"
expo-modules-autolinking@1.0.1: expo-modules-autolinking@1.0.2:
version "1.0.1" version "1.0.2"
resolved "https://registry.yarnpkg.com/expo-modules-autolinking/-/expo-modules-autolinking-1.0.1.tgz#a82eaef2decd1d518458d64cb542c64fc23eacde" resolved "https://registry.yarnpkg.com/expo-modules-autolinking/-/expo-modules-autolinking-1.0.2.tgz#f072f342ab797e43b16ddcdef251fcd4db851e1a"
integrity sha512-Ch0K/Vb2W7zSPlPKKFr6dwgwge6sSCpl7XPW8jrc7hUy+M72dvcfsBsaphvGNlKIZM6TtpCt0xbUlL48wI2y1A== integrity sha512-skAUXERKw1gtSw8xsvft9DE0KVhBvw4dujAtgCZoG2l513fN7ds+B5+30ZVgZATMC+EjtlmjKXzhp5QS44DCFA==
dependencies: dependencies:
chalk "^4.1.0" chalk "^4.1.0"
commander "^7.2.0" commander "^7.2.0"
@ -10701,7 +10701,7 @@ expo-modules-core@1.1.1:
compare-versions "^3.4.0" compare-versions "^3.4.0"
invariant "^2.2.4" invariant "^2.2.4"
expo-splash-screen@^0.17.5: expo-splash-screen@~0.17.5:
version "0.17.5" version "0.17.5"
resolved "https://registry.yarnpkg.com/expo-splash-screen/-/expo-splash-screen-0.17.5.tgz#a18dc59c1cc28ebbedbf0a7529a419d18ab0b311" resolved "https://registry.yarnpkg.com/expo-splash-screen/-/expo-splash-screen-0.17.5.tgz#a18dc59c1cc28ebbedbf0a7529a419d18ab0b311"
integrity sha512-ejSO78hwHXz8T9u8kh8t4r6CR4h70iBvA65gX8GK+dYxZl6/IANPbIb2VnUpND9vqfW+JnkDw+ZFst+gDnkpcQ== integrity sha512-ejSO78hwHXz8T9u8kh8t4r6CR4h70iBvA65gX8GK+dYxZl6/IANPbIb2VnUpND9vqfW+JnkDw+ZFst+gDnkpcQ==
@ -10742,10 +10742,10 @@ expo-updates@^0.15.6:
resolve-from "^5.0.0" resolve-from "^5.0.0"
uuid "^3.4.0" uuid "^3.4.0"
expo@^47.0.12: expo@~47.0.12:
version "47.0.12" version "47.0.13"
resolved "https://registry.yarnpkg.com/expo/-/expo-47.0.12.tgz#2a8b41217e1cb630f84ea3723031d07354289ae7" resolved "https://registry.yarnpkg.com/expo/-/expo-47.0.13.tgz#f53f82e7f9e209f8a8b25f2493f58439958368cb"
integrity sha512-LqECuBpV6arTncksQzOGGQmxOdeQmzm15VqwIJ/c3SWoxiVh5hKf+taUv2oaLmfx2z04TSm1oo56pRSrsL5iIA== integrity sha512-9VjjGdViCJ9NfWbUE7brkwFBDvKuA35V345vMtHFYNKoGJjXib36yitmawreMDQFv0kMTqTnzc7T2191Pod7Ng==
dependencies: dependencies:
"@babel/runtime" "^7.14.0" "@babel/runtime" "^7.14.0"
"@expo/cli" "0.4.11" "@expo/cli" "0.4.11"
@ -10760,7 +10760,7 @@ expo@^47.0.12:
expo-file-system "~15.1.1" expo-file-system "~15.1.1"
expo-font "~11.0.1" expo-font "~11.0.1"
expo-keep-awake "~11.0.1" expo-keep-awake "~11.0.1"
expo-modules-autolinking "1.0.1" expo-modules-autolinking "1.0.2"
expo-modules-core "1.1.1" expo-modules-core "1.1.1"
fbemitter "^3.0.0" fbemitter "^3.0.0"
getenv "^1.0.0" getenv "^1.0.0"
@ -15755,10 +15755,10 @@ react-native-screens@~3.18.0:
react-freeze "^1.0.0" react-freeze "^1.0.0"
warn-once "^0.1.0" warn-once "^0.1.0"
react-native-svg@^13.7.0: react-native-svg@13.4.0, react-native-svg@^13.7.0:
version "13.7.0" version "13.4.0"
resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-13.7.0.tgz#be2ffb935e996762543dd7376bdc910722f7a43c" resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-13.4.0.tgz#82399ba0956c454144618aa581e2d748dd3f010a"
integrity sha512-WR5CIURvee5cAfvMhmdoeOjh1SC8KdLq5u5eFsz4pbYzCtIFClGSkLnNgkMSDMVV5LV0qQa4jeIk75ieIBzaDA== integrity sha512-B3TwK+H0+JuRhYPzF21AgqMt4fjhCwDZ9QUtwNstT5XcslJBXC0FoTkdZo8IEb1Sv4suSqhZwlAY6lwOv3tHag==
dependencies: dependencies:
css-select "^5.1.0" css-select "^5.1.0"
css-tree "^1.1.3" css-tree "^1.1.3"