Add cross-platform sidebar (#331)
* feat: add icon example and solve some types * fix: add accordion and emojis * fix: fixes animation issues and adds overall minor improvements * fix: more fixes and new emoji * fix: id from channel
This commit is contained in:
parent
cdeeafafae
commit
f197ae31cf
|
@ -15,7 +15,7 @@ import {
|
||||||
} from '@status-im/components'
|
} from '@status-im/components'
|
||||||
import { Stack, TamaguiProvider } from '@tamagui/core'
|
import { Stack, TamaguiProvider } from '@tamagui/core'
|
||||||
import { useFonts } from 'expo-font'
|
import { useFonts } from 'expo-font'
|
||||||
import { SafeAreaView, TouchableOpacity } from 'react-native'
|
import { SafeAreaView, ScrollView, TouchableOpacity } from 'react-native'
|
||||||
|
|
||||||
import tamaguiConfig from './tamagui.config'
|
import tamaguiConfig from './tamagui.config'
|
||||||
|
|
||||||
|
@ -37,51 +37,51 @@ export default function App() {
|
||||||
return (
|
return (
|
||||||
<TamaguiProvider config={tamaguiConfig} defaultTheme={theme}>
|
<TamaguiProvider config={tamaguiConfig} defaultTheme={theme}>
|
||||||
<SafeAreaView>
|
<SafeAreaView>
|
||||||
<Image
|
<ScrollView>
|
||||||
source={{
|
<Image
|
||||||
uri: 'https://images.unsplash.com/photo-1673537074513-e66435b69012?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=687&q=80',
|
source={{
|
||||||
height: 200,
|
uri: 'https://images.unsplash.com/photo-1673537074513-e66435b69012?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=687&q=80',
|
||||||
width: '100%',
|
height: 200,
|
||||||
}}
|
width: '100%',
|
||||||
/>
|
}}
|
||||||
<Sidebar
|
/>
|
||||||
name="Rarible"
|
<Sidebar
|
||||||
description="Multichain community-centric NFT marketplace. Create, buy and sell your NFTs."
|
name="Rarible"
|
||||||
membersCount={123}
|
description="Multichain community-centric NFT marketplace. Create, buy and sell your NFTs."
|
||||||
/>
|
membersCount={123}
|
||||||
<Stack
|
/>
|
||||||
flexDirection="column"
|
<Stack
|
||||||
justifyContent="center"
|
flexDirection="column"
|
||||||
alignItems="center"
|
justifyContent="center"
|
||||||
marginTop={20}
|
alignItems="center"
|
||||||
height="100%"
|
paddingTop={20}
|
||||||
width="100%"
|
width="100%"
|
||||||
backgroundColor="$background"
|
backgroundColor="$background"
|
||||||
>
|
|
||||||
<Heading weight="semibold" marginBottom={12}>
|
|
||||||
Communities
|
|
||||||
</Heading>
|
|
||||||
<Heading heading="h2" marginBottom={12}>
|
|
||||||
This is an Heading 2
|
|
||||||
</Heading>
|
|
||||||
<Paragraph weight="semibold" marginBottom={12} uppercase>
|
|
||||||
Paragraph uppercased and bolded
|
|
||||||
</Paragraph>
|
|
||||||
<Paragraph marginBottom={12} uppercase>
|
|
||||||
This is a paragraph
|
|
||||||
</Paragraph>
|
|
||||||
<Label marginBottom={12}>This is a label</Label>
|
|
||||||
<Code marginBottom={12}>This is a code line</Code>
|
|
||||||
<Paragraph fontWeight="400">0x213abc190 ... 121ah4a9e</Paragraph>
|
|
||||||
<Shape marginVertical={20} />
|
|
||||||
|
|
||||||
<Paragraph>Theme selected - {theme}</Paragraph>
|
|
||||||
<TouchableOpacity
|
|
||||||
onPress={() => setTheme(theme === 'dark' ? 'light' : 'dark')}
|
|
||||||
>
|
>
|
||||||
<Paragraph>Toogle theme</Paragraph>
|
<Heading weight="semibold" marginBottom={12}>
|
||||||
</TouchableOpacity>
|
Communities
|
||||||
</Stack>
|
</Heading>
|
||||||
|
<Heading heading="h2" marginBottom={12}>
|
||||||
|
This is an Heading 2
|
||||||
|
</Heading>
|
||||||
|
<Paragraph weight="semibold" marginBottom={12} uppercase>
|
||||||
|
Paragraph uppercased and bolded
|
||||||
|
</Paragraph>
|
||||||
|
<Paragraph marginBottom={12} uppercase>
|
||||||
|
This is a paragraph
|
||||||
|
</Paragraph>
|
||||||
|
<Label marginBottom={12}>This is a label</Label>
|
||||||
|
<Code marginBottom={12}>This is a code line</Code>
|
||||||
|
<Paragraph fontWeight="400">0x213abc190 ... 121ah4a9e</Paragraph>
|
||||||
|
<Shape marginVertical={20} />
|
||||||
|
<Paragraph>Theme selected - {theme}</Paragraph>
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={() => setTheme(theme === 'dark' ? 'light' : 'dark')}
|
||||||
|
>
|
||||||
|
<Paragraph>Toogle theme</Paragraph>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</Stack>
|
||||||
|
</ScrollView>
|
||||||
</SafeAreaView>
|
</SafeAreaView>
|
||||||
</TamaguiProvider>
|
</TamaguiProvider>
|
||||||
)
|
)
|
||||||
|
|
|
@ -16,8 +16,12 @@ body,
|
||||||
grid-template-rows: 56px 1fr 100px;
|
grid-template-rows: 56px 1fr 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#sidebar,
|
|
||||||
#main,
|
#main,
|
||||||
#main > div {
|
#main > div {
|
||||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#sidebar {
|
||||||
|
overflow: auto;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
"@tamagui/vite-plugin": "1.0.15",
|
"@tamagui/vite-plugin": "1.0.15",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
|
"react-native-svg": "^13.7.0",
|
||||||
"react-native-web": "^0.18.0",
|
"react-native-web": "^0.18.0",
|
||||||
"storybook": "^7.0.0-beta.21",
|
"storybook": "^7.0.0-beta.21",
|
||||||
"storybook-addon-designs": "^7.0.0-beta.2",
|
"storybook-addon-designs": "^7.0.0-beta.2",
|
||||||
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
import { Stack } from '@tamagui/core'
|
||||||
|
import { AnimatePresence } from 'tamagui'
|
||||||
|
|
||||||
|
import { Chevron } from '../icon'
|
||||||
|
import { Label, Paragraph } from '../typography'
|
||||||
|
|
||||||
|
import type { GetProps } from '@tamagui/core'
|
||||||
|
|
||||||
|
type BaseProps = GetProps<typeof Stack>
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
children: React.ReactElement[] | React.ReactElement
|
||||||
|
isExpanded: boolean
|
||||||
|
onToggle?: () => void
|
||||||
|
title: string
|
||||||
|
numberOfNewMessages?: number
|
||||||
|
showNotifications?: boolean
|
||||||
|
} & BaseProps
|
||||||
|
|
||||||
|
const Accordion = ({
|
||||||
|
children,
|
||||||
|
isExpanded,
|
||||||
|
onToggle,
|
||||||
|
title,
|
||||||
|
numberOfNewMessages,
|
||||||
|
showNotifications,
|
||||||
|
}: Props) => {
|
||||||
|
return (
|
||||||
|
<Stack
|
||||||
|
width="100%"
|
||||||
|
borderRadius="$0"
|
||||||
|
borderTopWidth={1}
|
||||||
|
borderTopColor="$neutral-10"
|
||||||
|
paddingHorizontal={8}
|
||||||
|
>
|
||||||
|
<Stack justifyContent="flex-start">
|
||||||
|
<Stack width="100%">
|
||||||
|
<Stack
|
||||||
|
width="100%"
|
||||||
|
flexDirection="row"
|
||||||
|
justifyContent={'space-between'}
|
||||||
|
onPress={onToggle}
|
||||||
|
cursor="pointer"
|
||||||
|
py={8}
|
||||||
|
>
|
||||||
|
<Stack flexDirection="row" alignItems="center">
|
||||||
|
<Stack
|
||||||
|
animation="fast"
|
||||||
|
transform={[{ rotateZ: isExpanded ? '90deg' : '0deg' }]}
|
||||||
|
>
|
||||||
|
<Chevron color="$neutral-50" size={16} />
|
||||||
|
</Stack>
|
||||||
|
<Paragraph
|
||||||
|
marginLeft={4}
|
||||||
|
color="$neutral-50"
|
||||||
|
weight="medium"
|
||||||
|
variant="smaller"
|
||||||
|
>
|
||||||
|
{title}
|
||||||
|
</Paragraph>
|
||||||
|
</Stack>
|
||||||
|
<AnimatePresence>
|
||||||
|
{showNotifications && numberOfNewMessages && (
|
||||||
|
<Stack
|
||||||
|
key={`notifications-${title}}`}
|
||||||
|
width={20}
|
||||||
|
justifyContent="center"
|
||||||
|
alignItems="center"
|
||||||
|
mr={8}
|
||||||
|
animation={[
|
||||||
|
'fast',
|
||||||
|
{
|
||||||
|
opacity: {
|
||||||
|
overshootClamping: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
enterStyle={{ opacity: 0 }}
|
||||||
|
exitStyle={{ opacity: 0 }}
|
||||||
|
opacity={1}
|
||||||
|
>
|
||||||
|
<Stack
|
||||||
|
backgroundColor="$turquoise-50"
|
||||||
|
borderRadius="$4"
|
||||||
|
width={16}
|
||||||
|
height={16}
|
||||||
|
justifyContent="center"
|
||||||
|
alignItems="center"
|
||||||
|
>
|
||||||
|
<Label color="$white-100" weight="medium">
|
||||||
|
{numberOfNewMessages}
|
||||||
|
</Label>
|
||||||
|
</Stack>
|
||||||
|
</Stack>
|
||||||
|
)}
|
||||||
|
</AnimatePresence>
|
||||||
|
</Stack>
|
||||||
|
<AnimatePresence>
|
||||||
|
{isExpanded && (
|
||||||
|
<React.Fragment key={title}>{children}</React.Fragment>
|
||||||
|
)}
|
||||||
|
</AnimatePresence>
|
||||||
|
</Stack>
|
||||||
|
</Stack>
|
||||||
|
</Stack>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export { Accordion }
|
|
@ -0,0 +1,115 @@
|
||||||
|
import { Stack } from '@tamagui/core'
|
||||||
|
|
||||||
|
import { Muted } from '../icon'
|
||||||
|
import { Label, Paragraph } from '../typography'
|
||||||
|
|
||||||
|
import type { GetProps } from '@tamagui/core'
|
||||||
|
|
||||||
|
type BaseProps = GetProps<typeof Stack>
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
isSelected?: boolean
|
||||||
|
onToggle?: () => void
|
||||||
|
title: string
|
||||||
|
channelStatus?: 'muted' | 'normal' | 'withMessages' | 'withMentions'
|
||||||
|
icon?: React.ReactNode
|
||||||
|
numberOfMessages?: number
|
||||||
|
} & BaseProps
|
||||||
|
|
||||||
|
const textColor = {
|
||||||
|
muted: '$neutral-40',
|
||||||
|
normal: '$neutral-50',
|
||||||
|
withMessages: '$neutral-100',
|
||||||
|
withMentions: '$neutral-100',
|
||||||
|
}
|
||||||
|
|
||||||
|
const AccordionItem = ({
|
||||||
|
icon,
|
||||||
|
isSelected,
|
||||||
|
title,
|
||||||
|
channelStatus = 'normal',
|
||||||
|
numberOfMessages,
|
||||||
|
...rest
|
||||||
|
}: Props) => {
|
||||||
|
return (
|
||||||
|
<Stack
|
||||||
|
{...rest}
|
||||||
|
animation={[
|
||||||
|
'fast',
|
||||||
|
{
|
||||||
|
opacity: {
|
||||||
|
overshootClamping: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
backgroundColor={isSelected ? '$turquoise-50-opa-10' : 'transparent'}
|
||||||
|
borderRadius="$4"
|
||||||
|
padding={8}
|
||||||
|
width="100%"
|
||||||
|
enterStyle={{ opacity: 0 }}
|
||||||
|
exitStyle={{ opacity: 0 }}
|
||||||
|
opacity={1}
|
||||||
|
justifyContent={
|
||||||
|
channelStatus === 'normal' ? 'flex-start' : 'space-between'
|
||||||
|
}
|
||||||
|
alignItems="center"
|
||||||
|
flexDirection="row"
|
||||||
|
cursor="pointer"
|
||||||
|
>
|
||||||
|
<Stack
|
||||||
|
justifyContent="flex-start"
|
||||||
|
alignItems="center"
|
||||||
|
flexDirection="row"
|
||||||
|
>
|
||||||
|
{icon && <>{icon}</>}
|
||||||
|
<Paragraph
|
||||||
|
color={textColor[channelStatus]}
|
||||||
|
weight="medium"
|
||||||
|
marginLeft={icon ? 8 : 0}
|
||||||
|
>
|
||||||
|
{title}
|
||||||
|
</Paragraph>
|
||||||
|
</Stack>
|
||||||
|
{channelStatus !== 'normal' && (
|
||||||
|
<Stack>
|
||||||
|
{channelStatus === 'withMentions' && (
|
||||||
|
<Stack width={20} justifyContent="center" alignItems="center">
|
||||||
|
<Stack
|
||||||
|
backgroundColor="$turquoise-50"
|
||||||
|
borderRadius="$4"
|
||||||
|
width={16}
|
||||||
|
height={16}
|
||||||
|
justifyContent="center"
|
||||||
|
alignItems="center"
|
||||||
|
>
|
||||||
|
<Label color="$white-100" weight="medium">
|
||||||
|
{numberOfMessages}
|
||||||
|
</Label>
|
||||||
|
</Stack>
|
||||||
|
</Stack>
|
||||||
|
)}
|
||||||
|
{channelStatus === 'withMessages' && (
|
||||||
|
<Stack
|
||||||
|
width={20}
|
||||||
|
height={20}
|
||||||
|
justifyContent="center"
|
||||||
|
alignItems="center"
|
||||||
|
>
|
||||||
|
<Stack
|
||||||
|
backgroundColor="$neutral-40"
|
||||||
|
borderRadius="$4"
|
||||||
|
width={8}
|
||||||
|
height={8}
|
||||||
|
justifyContent="center"
|
||||||
|
alignItems="center"
|
||||||
|
/>
|
||||||
|
</Stack>
|
||||||
|
)}
|
||||||
|
{channelStatus === 'muted' && <Muted size={20} color="$neutral-40" />}
|
||||||
|
</Stack>
|
||||||
|
)}
|
||||||
|
</Stack>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export { AccordionItem }
|
|
@ -0,0 +1,18 @@
|
||||||
|
import { createAnimations } from '@tamagui/animations-react-native'
|
||||||
|
|
||||||
|
export const animations = createAnimations({
|
||||||
|
fast: {
|
||||||
|
damping: 20,
|
||||||
|
mass: 1.2,
|
||||||
|
stiffness: 250,
|
||||||
|
},
|
||||||
|
medium: {
|
||||||
|
damping: 10,
|
||||||
|
mass: 0.9,
|
||||||
|
stiffness: 100,
|
||||||
|
},
|
||||||
|
slow: {
|
||||||
|
damping: 20,
|
||||||
|
stiffness: 60,
|
||||||
|
},
|
||||||
|
})
|
|
@ -1,27 +1,6 @@
|
||||||
import { createAnimations as createAnimationsCSS } from '@tamagui/animations-css'
|
import { createAnimations } from '@tamagui/animations-css'
|
||||||
import { createAnimations } from '@tamagui/animations-react-native'
|
|
||||||
|
|
||||||
export const animations = createAnimations({
|
export const animations = createAnimations({
|
||||||
bouncy: {
|
|
||||||
type: 'spring',
|
|
||||||
damping: 10,
|
|
||||||
mass: 0.9,
|
|
||||||
stiffness: 100,
|
|
||||||
},
|
|
||||||
lazy: {
|
|
||||||
type: 'spring',
|
|
||||||
damping: 20,
|
|
||||||
stiffness: 60,
|
|
||||||
},
|
|
||||||
quick: {
|
|
||||||
type: 'spring',
|
|
||||||
damping: 20,
|
|
||||||
mass: 1.2,
|
|
||||||
stiffness: 250,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
export const animationsCSS = createAnimationsCSS({
|
|
||||||
fast: 'ease-in 150ms',
|
fast: 'ease-in 150ms',
|
||||||
medium: 'ease-in 300ms',
|
medium: 'ease-in 300ms',
|
||||||
slow: 'ease-in 450ms',
|
slow: 'ease-in 450ms',
|
||||||
|
|
|
@ -18,7 +18,9 @@ const Base = styled(Stack, {
|
||||||
display: 'inline-flex',
|
display: 'inline-flex',
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
backgroundColor: 'rgb(255,255,255)',
|
backgroundColor: '$white-100',
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
|
||||||
variants: {
|
variants: {
|
||||||
size: {
|
size: {
|
||||||
|
@ -55,6 +57,12 @@ const Base = styled(Stack, {
|
||||||
borderRadius: 16,
|
borderRadius: 16,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
withOutline: {
|
||||||
|
true: {
|
||||||
|
borderWidth: 2,
|
||||||
|
borderColor: '$white-100',
|
||||||
|
},
|
||||||
|
},
|
||||||
} as const,
|
} as const,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -69,12 +77,13 @@ interface Props {
|
||||||
size: NonNullable<BaseProps['size']>
|
size: NonNullable<BaseProps['size']>
|
||||||
indicator?: 'online' | 'offline'
|
indicator?: 'online' | 'offline'
|
||||||
shape?: 'circle' | 'rounded'
|
shape?: 'circle' | 'rounded'
|
||||||
|
withOutline?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
type ImageLoadingStatus = 'idle' | 'loading' | 'loaded' | 'error'
|
type ImageLoadingStatus = 'idle' | 'loading' | 'loaded' | 'error'
|
||||||
|
|
||||||
const Avatar = (props: Props) => {
|
const Avatar = (props: Props) => {
|
||||||
const { src, size, shape = 'circle' } = props
|
const { src, size, shape = 'circle', withOutline } = props
|
||||||
|
|
||||||
const [status, setStatus] = useState<ImageLoadingStatus>('idle')
|
const [status, setStatus] = useState<ImageLoadingStatus>('idle')
|
||||||
|
|
||||||
|
@ -83,7 +92,7 @@ const Avatar = (props: Props) => {
|
||||||
}, [JSON.stringify(src)])
|
}, [JSON.stringify(src)])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Base size={size} shape={shape}>
|
<Base size={size} shape={shape} withOutline={withOutline}>
|
||||||
<Image
|
<Image
|
||||||
src={src}
|
src={src}
|
||||||
width={size}
|
width={size}
|
||||||
|
@ -91,15 +100,17 @@ const Avatar = (props: Props) => {
|
||||||
onLoad={() => setStatus('loaded')}
|
onLoad={() => setStatus('loaded')}
|
||||||
onError={() => setStatus('error')}
|
onError={() => setStatus('error')}
|
||||||
/>
|
/>
|
||||||
<Fallback
|
{status === 'error' && (
|
||||||
width={size}
|
<Fallback
|
||||||
height={size}
|
width={size}
|
||||||
display="flex"
|
height={size}
|
||||||
alignItems="center"
|
display="flex"
|
||||||
justifyContent="center"
|
alignItems="center"
|
||||||
>
|
justifyContent="center"
|
||||||
PP
|
>
|
||||||
</Fallback>
|
PP
|
||||||
|
</Fallback>
|
||||||
|
)}
|
||||||
</Base>
|
</Base>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
import { styled, Text } from '@tamagui/core'
|
import { Stack, styled, Text } from '@tamagui/core'
|
||||||
import { ButtonFrame } from 'tamagui'
|
|
||||||
|
|
||||||
import type { GetProps } from '@tamagui/core'
|
import type { GetProps } from '@tamagui/core'
|
||||||
|
|
||||||
const Base = styled(ButtonFrame, {
|
const Base = styled(Stack, {
|
||||||
// tag: 'button',
|
// tag: 'button',
|
||||||
|
|
||||||
cursor: 'pointer',
|
cursor: 'pointer',
|
||||||
|
@ -31,24 +30,22 @@ const Base = styled(ButtonFrame, {
|
||||||
const ButtonText = styled(Text, {
|
const ButtonText = styled(Text, {
|
||||||
fontFamily: '$inter',
|
fontFamily: '$inter',
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
color: '$white',
|
color: '$white-100',
|
||||||
})
|
})
|
||||||
|
|
||||||
type BaseProps = GetProps<typeof Base>
|
type BaseProps = GetProps<typeof Base>
|
||||||
|
|
||||||
interface Props {
|
type Props = {
|
||||||
type?: BaseProps['type']
|
type?: BaseProps['type']
|
||||||
children: string
|
children: string
|
||||||
onPress?: () => void
|
onPress?: () => void
|
||||||
}
|
} & Omit<BaseProps, 'type'>
|
||||||
|
|
||||||
const Button = (props: Props) => {
|
const Button = (props: Props) => {
|
||||||
const { type = 'primary', children, onPress } = props
|
const { type = 'primary', children, onPress, ...rest } = props
|
||||||
console.log(onPress)
|
|
||||||
|
|
||||||
console.log('Button', type)
|
|
||||||
return (
|
return (
|
||||||
<Base type={type} onPress={onPress}>
|
<Base {...rest} type={type} onPress={onPress}>
|
||||||
<ButtonText>{children}</ButtonText>
|
<ButtonText>{children}</ButtonText>
|
||||||
</Base>
|
</Base>
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
import type { SizeTokens, StyleObject } from '@tamagui/core'
|
||||||
|
import type { SvgProps } from 'react-native-svg'
|
||||||
|
|
||||||
|
export type EmojiProps = SvgProps & {
|
||||||
|
size?: number | SizeTokens
|
||||||
|
style?: StyleObject
|
||||||
|
sizeBackground?: number
|
||||||
|
hasBackground?: boolean
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
import { memo } from 'react'
|
||||||
|
|
||||||
|
import { Defs, Image, Path, Pattern, Svg, Use } from 'react-native-svg'
|
||||||
|
|
||||||
|
import { themed } from '../themed'
|
||||||
|
|
||||||
|
import type { EmojiProps } from '../EmojiProps'
|
||||||
|
|
||||||
|
const Emoji = (props: EmojiProps) => {
|
||||||
|
const { size = 16, ...otherProps } = props
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Svg
|
||||||
|
width={size}
|
||||||
|
height={size}
|
||||||
|
viewBox={`0 0 ${size} ${size}`}
|
||||||
|
fill="none"
|
||||||
|
{...otherProps}
|
||||||
|
>
|
||||||
|
<Path fill="url(#basketball-a)" d="M1.333 1.333h13.333v13.333H1.333z" />
|
||||||
|
|
||||||
|
<Defs>
|
||||||
|
<Pattern
|
||||||
|
id="basketball-a"
|
||||||
|
patternContentUnits="objectBoundingBox"
|
||||||
|
width="1"
|
||||||
|
height="1"
|
||||||
|
>
|
||||||
|
<Use xlinkHref="#basketball-b" transform="scale(.01389)" />
|
||||||
|
</Pattern>
|
||||||
|
<Image
|
||||||
|
id="basketball-b"
|
||||||
|
width="72"
|
||||||
|
height="72"
|
||||||
|
xlinkHref="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAMAAABiM0N1AAAAY1BMVEVHcEz0kAz0kAz0kAz0kAz0kAz0kAwjHyD0kAz0kAz0kAz0kAz0kAz0kAz0kAzKeRAjHyCMWBZKNBzniQ0jHyDagg9kQhqmZhQwJh9xSRnNexCzbRI9LR5+UBeZXxXAdBFXOxt8YctEAAAAFXRSTlMAIGCPv9///1Cf70CvgM+fn////4DoPY5GAAAB20lEQVR4AdzSh46yQBQFYGlnYMACSBGxvP9T/t6JhuDxv4wbkk32pAP5uG2jJAijOAHMI0ASR2Gw+UHSLIHkBbkkWfqdEkQWAEESG/nXlRcACJpS5H7VZIAOAZlHVVuLZQh2u1TODliGJDu1qNTCF4JNlbYABaL8t709voOw/+wcTPkdVJrDZ8eYqvaH6sqYT9LRGJIUSBzJkfbVtCwRRE7bvO0usEDXy6uTH3SSp30H2Pk9uTscnHT2gc7OGdxl8gGhk9djvQzVozzs6JykMZeLvC+XoVKeXSCZNZfN/tTXS1DdzyrPXk4OydRcp0P8Vf6ECkyRkqolqJKCMKV4Toi6b3SooUkGDoroo6sOXelnkYMsld3qUEvtW3FS3myvQz3fSOp2P8vNPDJo0CAPbphFLiABL6nToI7XiMTtjHdbalDJFyJ7CwHQKFsNog8koSyfp33XoDvPWg4gBkBXMmrQSJcGIHaz5rVpEC/NTRvrQFgPMivlL0O391x/eWvrHeS/VuygAAAABkFgEPv39GUCL8QcwE5EHa2bETZsbGrR+Mt3RB4ke9kMIhTWMNBS6OdhdHicA48BsDOFUFKjNEuJn1RRL8de111AcEnDRRaYfVyIAmkMxDqQDwumcHXpGt5TKwAAAABJRU5ErkJggg=="
|
||||||
|
/>
|
||||||
|
</Defs>
|
||||||
|
</Svg>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Emoji.displayName = 'Basketball'
|
||||||
|
|
||||||
|
export const Basketball = memo<EmojiProps>(themed(Emoji))
|
|
@ -0,0 +1,42 @@
|
||||||
|
import { memo } from 'react'
|
||||||
|
|
||||||
|
import { Path, Svg } from 'react-native-svg'
|
||||||
|
|
||||||
|
import { themed } from '../themed'
|
||||||
|
|
||||||
|
import type { EmojiProps } from '../EmojiProps'
|
||||||
|
|
||||||
|
const Emoji = (props: EmojiProps) => {
|
||||||
|
const { size = 16, ...otherProps } = props
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Svg
|
||||||
|
width={size}
|
||||||
|
height={size}
|
||||||
|
viewBox={`0 0 ${size} ${size}`}
|
||||||
|
fill="none"
|
||||||
|
{...otherProps}
|
||||||
|
>
|
||||||
|
<Path
|
||||||
|
d="M7.145 13.135a1.054 1.054 0 0 0 1.493-.27.383.383 0 0 0-.091-.527l-.859-.925 1.96 1.402a.689.689 0 0 0 .52.118.688.688 0 0 0 .45-.293.72.72 0 0 0-.172-.991L8.777 10.08l2.495 1.785a.687.687 0 0 0 1.08-.429.724.724 0 0 0-.282-.737L9.858 8.768l2.722 1.947a.689.689 0 0 0 .774.018.703.703 0 0 0 .305-.447.726.726 0 0 0-.28-.736L1.716 4.059.107 6.677a.7.7 0 0 0 .129.897l3.614 3.164c.164.144.336.28.514.408l2.781 1.99Z"
|
||||||
|
fill="#EF9645"
|
||||||
|
/>
|
||||||
|
<Path
|
||||||
|
d="M13.353 9.066 8.107 5.2l-.027-.038.024-.037.025-.026.396.223c.445.294 1.46.728 2.23.728.528 0 .843-.201.938-.596a.68.68 0 0 0-.112-.497.652.652 0 0 0-.423-.272 3.111 3.111 0 0 1-1.3-.518L9.6 3.99c-.29-.2-.618-.425-.86-.572a1.85 1.85 0 0 0-1.004-.277c-.555 0-1.119.2-1.664.394l-.588.206c-.253.088-.52.131-.787.129-.716 0-1.418-.278-2.096-.546l-.068-.028a.632.632 0 0 0-.435-.01.647.647 0 0 0-.342.276l-1.61 2.62a.655.655 0 0 0 .12.834l3.613 3.165c.164.143.335.279.51.404l2.862 2.047a.919.919 0 0 0 .694.157.917.917 0 0 0 .6-.39.388.388 0 0 0-.091-.529l-.851-.608a.2.2 0 0 1-.082-.138.206.206 0 0 1 .044-.155.193.193 0 0 1 .263-.036l1.847 1.321a.639.639 0 0 0 .905-.163.676.676 0 0 0-.16-.925L8.692 9.93a.2.2 0 0 1-.082-.138.205.205 0 0 1 .044-.155.195.195 0 0 1 .263-.036l2.382 1.704a.644.644 0 0 0 .722.017.658.658 0 0 0 .285-.417.678.678 0 0 0-.262-.688l-2.26-1.615a.197.197 0 0 1-.082-.138.203.203 0 0 1 .045-.156.172.172 0 0 1 .235-.031l2.625 1.878a.645.645 0 0 0 .486.11.642.642 0 0 0 .42-.274.673.673 0 0 0-.16-.925Z"
|
||||||
|
fill="#FFDC5D"
|
||||||
|
/>
|
||||||
|
<Path
|
||||||
|
d="M7.195 11.996a.716.716 0 0 1-.18.323l-.466.472a.69.69 0 0 1-.668.188.693.693 0 0 1-.314-.182.715.715 0 0 1-.183-.689.715.715 0 0 1 .18-.32l.466-.473a.69.69 0 0 1 .667-.187.7.7 0 0 1 .425.329c.093.162.12.356.073.54ZM2.301 9.662l.698-.71a.714.714 0 0 0 .192-.631.719.719 0 0 0-.398-.521.68.68 0 0 0-.778.147l-.697.71a.714.714 0 0 0-.193.631.719.719 0 0 0 .4.521.68.68 0 0 0 .776-.147Zm2.415.025a.711.711 0 0 0 .221-.508.725.725 0 0 0-.204-.516.695.695 0 0 0-.505-.208.684.684 0 0 0-.496.227l-1.394 1.422a.711.711 0 0 0-.22.508.725.725 0 0 0 .203.516.695.695 0 0 0 .505.207.684.684 0 0 0 .497-.226l1.393-1.422Zm1.045 1.423a.716.716 0 0 0 .16-.75.71.71 0 0 0-.233-.32.687.687 0 0 0-.66-.1.69.69 0 0 0-.25.167l-.93.946a.716.716 0 0 0-.162.75.71.71 0 0 0 .234.32.683.683 0 0 0 .91-.067l.93-.946Zm7.684-1.963.291-.257-3.209-5.146-5.695.942a.69.69 0 0 0-.454.29.722.722 0 0 0-.12.534c.306 1.278 2.787.328 3.879-.285l5.308 3.922Z"
|
||||||
|
fill="#EF9645"
|
||||||
|
/>
|
||||||
|
<Path
|
||||||
|
d="M7.195 11.522a.716.716 0 0 1-.18.323l-.466.472a.69.69 0 0 1-.668.188.692.692 0 0 1-.314-.183.715.715 0 0 1-.183-.688.716.716 0 0 1 .18-.32l.466-.473a.69.69 0 0 1 .667-.188.7.7 0 0 1 .425.33c.093.162.12.356.073.539ZM2.301 9.188l.698-.71a.714.714 0 0 0 .192-.632.719.719 0 0 0-.398-.52.681.681 0 0 0-.778.147l-.697.71a.715.715 0 0 0-.193.631.719.719 0 0 0 .4.52.68.68 0 0 0 .776-.146Zm2.415.024a.711.711 0 0 0 .221-.508.725.725 0 0 0-.204-.515.695.695 0 0 0-.505-.208.684.684 0 0 0-.496.227L2.338 9.63a.711.711 0 0 0-.22.508.725.725 0 0 0 .203.515.695.695 0 0 0 .505.208.682.682 0 0 0 .497-.227l1.393-1.422Zm1.045 1.423a.716.716 0 0 0 .16-.75.71.71 0 0 0-.233-.32.688.688 0 0 0-.66-.099.69.69 0 0 0-.25.166l-.93.946a.716.716 0 0 0-.162.75.71.71 0 0 0 .234.321.683.683 0 0 0 .91-.067l.93-.947ZM15.767 7.1a.7.7 0 0 0 .125-.894l-.002-.002-1.609-3.093a.693.693 0 0 0-.366-.295.677.677 0 0 0-.467.01c-.924.366-1.937.786-2.92.444l-.51-.178c-.904-.32-1.887-.696-2.785-.14-.322.194-.807.538-1.119.75a3.15 3.15 0 0 1-1.282.51.688.688 0 0 0-.454.29.72.72 0 0 0-.12.534c.285 1.191 2.46.43 3.639-.175a.441.441 0 0 1 .465.038l5.377 3.992 2.028-1.791Z"
|
||||||
|
fill="#FFCC4D"
|
||||||
|
/>
|
||||||
|
</Svg>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Emoji.displayName = 'Collaboration'
|
||||||
|
|
||||||
|
export const Collaboration = memo<EmojiProps>(themed(Emoji))
|
|
@ -0,0 +1,43 @@
|
||||||
|
import { memo } from 'react'
|
||||||
|
|
||||||
|
import { Defs, Image, Path, Pattern, Svg, Use } from 'react-native-svg'
|
||||||
|
|
||||||
|
import { themed } from '../themed'
|
||||||
|
|
||||||
|
import type { EmojiProps } from '../EmojiProps'
|
||||||
|
|
||||||
|
const Emoji = (props: EmojiProps) => {
|
||||||
|
const { size = 16, ...otherProps } = props
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Svg
|
||||||
|
width={size}
|
||||||
|
height={size}
|
||||||
|
viewBox={`0 0 ${size} ${size}`}
|
||||||
|
fill="none"
|
||||||
|
{...otherProps}
|
||||||
|
>
|
||||||
|
<Path fill="url(#fire-a)" d="M1.333 1.333h13.333v13.333H1.333z" />
|
||||||
|
<Defs>
|
||||||
|
<Pattern
|
||||||
|
id="fire-a"
|
||||||
|
patternContentUnits="objectBoundingBox"
|
||||||
|
width="1"
|
||||||
|
height="1"
|
||||||
|
>
|
||||||
|
<Use xlinkHref="#fire-b" transform="scale(.01389)" />
|
||||||
|
</Pattern>
|
||||||
|
<Image
|
||||||
|
id="fire-b"
|
||||||
|
width="72"
|
||||||
|
height="72"
|
||||||
|
xlinkHref="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAMAAABiM0N1AAAAh1BMVEVHcEz0kAz0kAz0kAz0kAz0kAz0kAz0kAz0kAz0kAz0kAz0kAz0kAz0kAz0kAz0kAz/zE3/zE3/zE3/zE3/zE3/zE3/zE3/zE39wkL/zE3/zE3/zE3/zE30kAz/zE36ri33nxz+yEn+xUX5qij8vT32mxj9wUH3oyD1mBT6sjH1lBD7tjX8uTmQeifTAAAAHXRSTlMAMEBQv++PEM+A359gryBwzxDvv4CPUK9gIN9gMOUtXcUAAAKrSURBVHjarZfZkoIwEEWDLEkAcXfWDpu78//fN4OMqdAkJFCeJy3LI919OwJxJAtm5DUkENGXiGYAof8SUwwAERkPxV+K4I+AjvawoFdbAxtrYpAQBDiacB1c06SG+RiPBxpRAC2cuDMHgMQkgszZkz2a0W/bP4GzaAENuKsg8dwra0hJBx8kiXuIG2K8bJLQVaQbjwcKM3cRLo7KVlsTEGX9ti56Hnso/Vg3H5bSRsNDkFgCkIUJEklXwAATm0UBcPWNDaMn7UwimiyicUfkTxZxtIoxaLEnMkQ/YqstMHUIb6I/UcRw7Gegw7q1nkyxq2jR/b7X6UjiXBpeWj9SK4OQujcbzZz9h6i30jSEQRg+B2mnjtBzXZE5Pgd9mcbW1JbuMbDA8aw4/n3GOceao21oi2euLBdwqvLb4NDiZ9NgmFqIMscinDkX0VH8cToaSwtcRVA2pvJs2JCFDFYGFg7iQXtNOLteKEUULNxbUXlBlyQ9rqXlouWgFkcf18ABJohEAQoB5/MQpokOYEQfSJS/H/HkMrzFAW5uAR0qKaqHj14OHa7ijAIp+RneYh9UzkLkaPqSExjwSS9IlxI19SgUwMB/QBnu7E1p/Ela0Aeo1+iELkRDjj2aJBXK6+iZc+NeFYoHieqD5i6XqRfUUNa3pu93gcjV4Rb9/4JUM6GqFH2uarrumlvNUB49w1Sdc1Nza8JlZRZqNRRF/z+FxnI9nUy10rGYEoVUzsxGlefXSj0NUs0zVCVGUelulbKm32IkTaczgvCniXzSI5oiioiG+XjR3PCoP1ZkenSny3GeJSUGVm9jPG8rYmbn7tmRQfZrN816Tyx8bFw8mw9i5/3Tpvl8J06stuvBqraUOPO1NM78i4zje7fUWHbfZAKr/XazlI7Ndj8UnF+YwEpCshNBaAAAAABJRU5ErkJggg=="
|
||||||
|
/>
|
||||||
|
</Defs>
|
||||||
|
</Svg>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Emoji.displayName = 'Fire'
|
||||||
|
|
||||||
|
export const Fire = memo<EmojiProps>(themed(Emoji))
|
|
@ -0,0 +1,57 @@
|
||||||
|
import { memo } from 'react'
|
||||||
|
|
||||||
|
import {
|
||||||
|
ClipPath,
|
||||||
|
Defs,
|
||||||
|
G,
|
||||||
|
Image,
|
||||||
|
Path,
|
||||||
|
Pattern,
|
||||||
|
Svg,
|
||||||
|
Use,
|
||||||
|
} from 'react-native-svg'
|
||||||
|
|
||||||
|
import { themed } from '../themed'
|
||||||
|
|
||||||
|
import type { EmojiProps } from '../EmojiProps'
|
||||||
|
|
||||||
|
const Emoji = (props: EmojiProps) => {
|
||||||
|
const { size = 16, ...otherProps } = props
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Svg
|
||||||
|
width={size}
|
||||||
|
height={size}
|
||||||
|
viewBox={`0 0 ${size} ${size}`}
|
||||||
|
fill="none"
|
||||||
|
{...otherProps}
|
||||||
|
>
|
||||||
|
<G clipPath="url(#peach-a)">
|
||||||
|
<Path fill="url(#peach-b)" d="M.667.667h14.667v14.667H.667z" />
|
||||||
|
</G>
|
||||||
|
<Defs>
|
||||||
|
<ClipPath id="peach-a">
|
||||||
|
<Path fill="#fff" d="M0 0h16v16H0z" />
|
||||||
|
</ClipPath>
|
||||||
|
<Pattern
|
||||||
|
id="peach-b"
|
||||||
|
patternContentUnits="objectBoundingBox"
|
||||||
|
width="1"
|
||||||
|
height="1"
|
||||||
|
>
|
||||||
|
<Use xlinkHref="#peach-c" transform="scale(.01389)" />
|
||||||
|
</Pattern>
|
||||||
|
<Image
|
||||||
|
id="peach-c"
|
||||||
|
width="72"
|
||||||
|
height="72"
|
||||||
|
xlinkHref="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAMAAABiM0N1AAAAwFBMVEVHcExlnER3slV3slV3slV3slVvqU53slV3slV3slV3slVnnkV3slVup0xckTtckTtckTtckTtckTtckTt3slVckTtyrFBwkEGPjkqyjVXYimDpjmf/iGyZjk2Ar1aujVT/iGz/iGz/iGyhpVyOq1nvXFndLkTsVVb/iGz/iGz/iGz3i2vCm2KipVzqTVL/iGzRl2TyZl3/iGz/iGzfNEf7e2biO0r/iGz9gmr/iGz/iGz3cmLmRU7/iGz/iGz/iGyyzkZtAAAAQHRSTlMAQIC/n2YwUK//3xDvIIi//8+vY8/t////+///////QJ8wEM//////71Bg/////4D//3DP////3/8gj///r0C/62GdZgAAAmhJREFUeAGc0FWChTAMBdDg1Ghwt/0vcnyeNEXPd/QC4bjeDz8I4b4oZi+4K+CWgDODdOFJJRq/pFke7l/DmUXx3yQyfCpzARuUx+zk76SwxDdlDlaBZGxvkirRpBUQImY7pALQSJUOGELOdnngoJXxXiTZgSBDK/0eDzvEkaJ5++xQVTdt23VdPwxD33XtWCNiIsCgjkZN/WDq2hkoOorOoZb1s9uysLIbiKHo9BEteD6bmaH/rmItw9P3KJy9BdwzAssPq7QeVlmo2t1Cz549h+PxBEznCxD5FIT7z54ooJXjSkyABHiYNPpQVkgPHEXTPfIw/KxXDT+HOR2Z07bJO9Mr38LodrVEKWueOByZjAC5eUNBIm/fVFYE8F49CW0Ts6kmQGPNE/ZM27Q1mw5XR5eQC1XJxbVonbon0ZmcOIg70JsHLuTIQ3Go32drmHtyZBC75CsqY0buEgEm9njkTCZuJdeWkzul1O5ZbJG836W0SgsxinYPQpPOpKAU5lasItIwSk3Sini7R1mkXAAssqRh+AMi80VF51XU/ArRwp+IXoRvZK8X4cuW/4qF7OBh038iherUMicsylXHnxlxlrCvSUTxRzqgRKKsrcUXsnsS3eumX4kRqVMNrRR+/cy9/tLipNVpWnSAO/REotjrSiyMKZwrq1F+eMUjByoQbXuQs91iZCWEY8XkQP4vrHEyAdGAPTrTgWcPPMCkYgIeRcdBnwFeQ67k5iq2JyfOs9lidnnUYo0D+Zk2SIwbNrn6qsIz7vgFCZwTo8Pr4bOmzqgBrmI2P0jn378W2fjm55jzZFk2NN8BIrOmWnrNWn4AAAAASUVORK5CYII="
|
||||||
|
/>
|
||||||
|
</Defs>
|
||||||
|
</Svg>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Emoji.displayName = 'Peach'
|
||||||
|
|
||||||
|
export const Peach = memo<EmojiProps>(themed(Emoji))
|
|
@ -0,0 +1,46 @@
|
||||||
|
import { memo } from 'react'
|
||||||
|
|
||||||
|
import { Path, Svg } from 'react-native-svg'
|
||||||
|
|
||||||
|
import { themed } from '../themed'
|
||||||
|
|
||||||
|
import type { EmojiProps } from '../EmojiProps'
|
||||||
|
|
||||||
|
const Emoji = (props: EmojiProps) => {
|
||||||
|
const { size = 16, ...otherProps } = props
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Svg
|
||||||
|
width={size}
|
||||||
|
height={size}
|
||||||
|
viewBox={`0 0 ${size} ${size}`}
|
||||||
|
fill="none"
|
||||||
|
{...otherProps}
|
||||||
|
>
|
||||||
|
<Path
|
||||||
|
d="M1.667 4.91v.061c0-.019.004-.037.006-.056l-.006-.005Zm5.88 4.99a.875.875 0 0 1-.186-.11L1.922 5.468a.637.637 0 0 1-.255-.497v5.484c0 .915.494 1.113.494 1.113l5.236 4.077c.093.072.17.116.239.143a.487.487 0 0 1-.089-.271V9.9Zm-3.968.163c-.45 0-.92-.451-1.05-1.008-.13-.557.13-1.008.58-1.008.45 0 .92.451 1.049 1.008.13.557-.13 1.008-.58 1.008Zm2.525 3.36c-.45 0-.92-.451-1.049-1.008-.13-.557.13-1.008.58-1.008.45 0 .92.451 1.049 1.008.13.557-.13 1.009-.58 1.009Z"
|
||||||
|
fill="#A0041E"
|
||||||
|
/>
|
||||||
|
<Path
|
||||||
|
d="M14.078 5.43 8.602 9.79a.852.852 0 0 1-.15.095v5.632a.492.492 0 0 1-.09.275.945.945 0 0 0 .248-.147l5.242-4.077s.481-.198.481-1.113V4.934c0 .18-.085.36-.255.496Zm-3.374 7.497c-.11.51-.506.922-.886.922-.379 0-.598-.413-.488-.922.11-.51.506-.922.885-.922.38 0 .598.412.49.922Zm1.6-2.362c-.114.525-.532.95-.932.95s-.63-.425-.515-.95c.116-.525.534-.95.933-.95.4 0 .63.425.515.95Zm1.386-2.287c-.113.5-.526.903-.92.903-.395 0-.622-.404-.508-.903.113-.5.525-.904.92-.904s.622.405.508.904Zm.64-3.366c.001.007.003.014.003.022V4.91l-.002.002Z"
|
||||||
|
fill="#DD2E44"
|
||||||
|
/>
|
||||||
|
<Path
|
||||||
|
d="M14.078 4.437 8.583.205c-.34-.273-.9-.273-1.24 0l-5.42 4.27a.644.644 0 0 0-.25.44c-.002.02-.006.037-.006.056 0 .18.085.36.255.497l5.44 4.322c.056.045.119.08.185.11v5.617a.49.49 0 0 0 .088.27c.082.126.211.213.365.213.152 0 .28-.085.362-.208a.49.49 0 0 0 .09-.275V9.885a.852.852 0 0 0 .15-.095l5.476-4.36a.637.637 0 0 0 .255-.496l-.002-.022a.638.638 0 0 0-.253-.475Zm-5.852-.572c.728 0 1.32.467 1.32 1.045 0 .577-.592 1.045-1.32 1.045-.729 0-1.32-.468-1.32-1.045 0-.578.591-1.045 1.32-1.045Z"
|
||||||
|
fill="#EA596E"
|
||||||
|
/>
|
||||||
|
<Path
|
||||||
|
d="M8.226 5.955c.728 0 1.319-.468 1.319-1.045s-.59-1.045-1.32-1.045c-.728 0-1.318.468-1.318 1.045s.59 1.045 1.319 1.045ZM13.181 7.374c-.394 0-.806.405-.92.904-.114.5.114.904.508.904.395 0 .807-.405.92-.904.115-.499-.113-.904-.508-.904Zm-1.391 2.24c-.4 0-.818.426-.933.951-.115.525.116.95.515.95.4 0 .818-.425.933-.95.115-.525-.116-.95-.515-.95Zm-1.576 2.39c-.38 0-.776.414-.885.923-.11.51.11.922.489.922.38 0 .776-.412.885-.922.11-.51-.11-.922-.489-.922Z"
|
||||||
|
fill="#fff"
|
||||||
|
/>
|
||||||
|
<Path
|
||||||
|
d="M3.109 8.047c-.45 0-.71.451-.58 1.008.13.557.6 1.008 1.05 1.008.45 0 .709-.451.579-1.008-.13-.557-.6-1.008-1.05-1.008Zm2.525 3.36c-.45 0-.709.451-.58 1.008.13.557.6 1.008 1.05 1.008.45 0 .71-.451.58-1.008-.13-.557-.6-1.008-1.05-1.008Z"
|
||||||
|
fill="#E1E8ED"
|
||||||
|
/>
|
||||||
|
</Svg>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Emoji.displayName = 'Play'
|
||||||
|
|
||||||
|
export const Play = memo<EmojiProps>(themed(Emoji))
|
|
@ -0,0 +1,57 @@
|
||||||
|
import { memo } from 'react'
|
||||||
|
|
||||||
|
import {
|
||||||
|
ClipPath,
|
||||||
|
Defs,
|
||||||
|
G,
|
||||||
|
Image,
|
||||||
|
Path,
|
||||||
|
Pattern,
|
||||||
|
Svg,
|
||||||
|
Use,
|
||||||
|
} from 'react-native-svg'
|
||||||
|
|
||||||
|
import { themed } from '../themed'
|
||||||
|
|
||||||
|
import type { EmojiProps } from '../EmojiProps'
|
||||||
|
|
||||||
|
const Emoji = (props: EmojiProps) => {
|
||||||
|
const { size = 16, ...otherProps } = props
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Svg
|
||||||
|
width={size}
|
||||||
|
height={size}
|
||||||
|
viewBox={`0 0 ${size} ${size}`}
|
||||||
|
fill="none"
|
||||||
|
{...otherProps}
|
||||||
|
>
|
||||||
|
<G clipPath="url(#unicorn-a)">
|
||||||
|
<Path fill="url(#unicorn-b)" d="M.667.667h14.667v14.667H.667z" />
|
||||||
|
</G>
|
||||||
|
<Defs>
|
||||||
|
<ClipPath id="unicorn-a">
|
||||||
|
<Path fill="#fff" d="M0 0h16v16H0z" />
|
||||||
|
</ClipPath>
|
||||||
|
<Pattern
|
||||||
|
id="unicorn-b"
|
||||||
|
patternContentUnits="objectBoundingBox"
|
||||||
|
width="1"
|
||||||
|
height="1"
|
||||||
|
>
|
||||||
|
<Use xlinkHref="#unicorn-c" transform="scale(.01389)" />
|
||||||
|
</Pattern>
|
||||||
|
<Image
|
||||||
|
id="unicorn-c"
|
||||||
|
width="72"
|
||||||
|
height="72"
|
||||||
|
xlinkHref="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAMAAABiM0N1AAAAwFBMVEVHcEx6QYTBzdXBzdXBzdVgN5pgN5rBzdW2n6fENRJgN5rBzdVgN5rBzdXBzdVgN5rBzdXufA7seA5gN5rBzdXBzdXBzdXBzdXufA7MQhHaWhDteQ5gN5rWUxDHOhF1V6fufA7XVhDNgFzBzdW8xs9gN5rufA6prMSyvMbncRCImKORgrhTYmyCbK9pRaDIPBOfmMF2iJYqMDSaqLFga3N0VqbboGV6g4nbYBTlhi6ESHc8Q0ewXkvMuaPHsKSuipHrwtT2AAAAI3RSTlMAIO8wfdN9QBD+W983v1zvn2bpqq+PIM+WpzDDj0DP36/Pz9/s0Q4AAAK6SURBVHhe7ZbXUuMwFIblFsuOU0ghlLCweyTXkkpnd9//rVbGFMtYsgwZrvYbbpjJfHP+o19K0MnVEToIR74/OYzqxD+U6spn/Lz4ugif+37kOKfaIdKtnJU/OcFfNp06zl2xqmo+Qzd4geb2SlxNYmIexqqSz4b+q8nrWdZS8+gb7D9xCxh3jlNUwThGDAMAxjZC7pQyRnTkjmiFqSYyTfyo2JR/fjaAebEtgBBgcEnf4ER05AlMZxPmiXzGLwL63EAzstkRgISKcEWmH6XHX63+AMBiAMEmZqa12CQpVLmp6IbAOicQM5NkJpbOW2LRdYlWRRXu/1KasJE2MQAEzyRZXjdZGFmW1nx40eumnmgespE2AbwTJDXXEk0FW79wWDC/jPiQQViMxLHmVVqPJcTNK2eekigECOMd1OCmmnpFQvHKS26gkeC6YvLKhDU09teznlpEQLJKBUod4umVwR9e0v0GEcl7NkqbwlkvpntJMkalpVZzN3FpyggzsVIK4VvauG93ao0uCbST8SbURB9UuG4VDUEJkreJBqDGukWEgUNxTdJkZL/dE2k4qWgMr9xut9tbxXDSM+NF8pOTrih83D6GICOQiGyosGstk1hkQhcCZZHqSII6qrMWihbQCZKLRNCRTCA6ho4EApENXcmbRSZ0JWkWzaArYbNIBw7lKnV4HfvSKnVIZkurpH74fXFVs4+iMQgZI1NWJfU22siQVUm5RHPZ911SE2FdEowxk1RJ7ez1YcvAGVV5imbD1nu45kUAQUzqNRwqPTE5f/HDNN3zpgVW+3WR8KI4TdMdNw9WfIbJR1FcXbKhXA++juE+TcOKyFS/0vzktZ/VOlZ/PqWfM5G6SHZndfxpEV4INt1VhPBc5lEXMexZqRlj1F3Eg20GL1AXyTm8yPw+0X/R+FCiwTdE+weFN6s3Jd7QlgAAAABJRU5ErkJggg=="
|
||||||
|
/>
|
||||||
|
</Defs>
|
||||||
|
</Svg>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Emoji.displayName = 'Unicorn'
|
||||||
|
|
||||||
|
export const Unicorn = memo<EmojiProps>(themed(Emoji))
|
|
@ -0,0 +1,6 @@
|
||||||
|
export { Basketball } from './emojis/basketball'
|
||||||
|
export { Collaboration } from './emojis/collaboration'
|
||||||
|
export { Fire } from './emojis/fire'
|
||||||
|
export { Peach } from './emojis/peach'
|
||||||
|
export { Play } from './emojis/play'
|
||||||
|
export { Unicorn } from './emojis/unicorn'
|
|
@ -0,0 +1,27 @@
|
||||||
|
import { Stack } from '@tamagui/core'
|
||||||
|
|
||||||
|
import type { EmojiProps } from './EmojiProps'
|
||||||
|
import type React from 'react'
|
||||||
|
|
||||||
|
export function themed(Component: React.ElementType) {
|
||||||
|
const useWrapped = (props: EmojiProps) => {
|
||||||
|
const { size, hasBackground, sizeBackground = 24, ...rest } = props
|
||||||
|
|
||||||
|
if (hasBackground) {
|
||||||
|
return (
|
||||||
|
<Stack
|
||||||
|
width={sizeBackground}
|
||||||
|
height={sizeBackground}
|
||||||
|
borderRadius="50%"
|
||||||
|
backgroundColor="$turquoise-50-opa-10"
|
||||||
|
justifyContent="center"
|
||||||
|
alignItems="center"
|
||||||
|
>
|
||||||
|
<Component {...rest} size={size} />
|
||||||
|
</Stack>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return <Component {...rest} size={size} />
|
||||||
|
}
|
||||||
|
return useWrapped
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
import type {
|
||||||
|
SizeTokens,
|
||||||
|
StyleObject,
|
||||||
|
ThemeParsed,
|
||||||
|
Tokens,
|
||||||
|
} from '@tamagui/core'
|
||||||
|
import type { SvgProps } from 'react-native-svg'
|
||||||
|
|
||||||
|
type GetTokenString<A> = A extends string ? `$${A}` : `$${string}`
|
||||||
|
export type ColorTokens =
|
||||||
|
| GetTokenString<keyof Tokens['color']>
|
||||||
|
| GetTokenString<keyof ThemeParsed>
|
||||||
|
|
||||||
|
export type IconProps = SvgProps & {
|
||||||
|
size?: number | SizeTokens
|
||||||
|
color?: ColorTokens
|
||||||
|
style?: StyleObject
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
import { memo } from 'react'
|
||||||
|
|
||||||
|
import { Path, Svg } from 'react-native-svg'
|
||||||
|
|
||||||
|
import { themed } from '../themed'
|
||||||
|
|
||||||
|
import type { IconProps } from '../IconProps'
|
||||||
|
|
||||||
|
const Icon = (props: IconProps) => {
|
||||||
|
const { color, size = 16, ...otherProps } = props
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Svg
|
||||||
|
width={size}
|
||||||
|
height={size}
|
||||||
|
viewBox={`0 0 ${size} ${size}`}
|
||||||
|
fill="none"
|
||||||
|
{...otherProps}
|
||||||
|
>
|
||||||
|
<Path d="M8 14L12 10L8 6" stroke={`${color}`} strokeWidth="1.3" />
|
||||||
|
</Svg>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Icon.displayName = 'Chevron'
|
||||||
|
|
||||||
|
export const Chevron = memo<IconProps>(themed(Icon))
|
|
@ -0,0 +1,39 @@
|
||||||
|
import { memo } from 'react'
|
||||||
|
|
||||||
|
import { Path, Svg } from 'react-native-svg'
|
||||||
|
|
||||||
|
import { themed } from '../themed'
|
||||||
|
|
||||||
|
import type { IconProps } from '../IconProps'
|
||||||
|
|
||||||
|
const Icon = (props: IconProps) => {
|
||||||
|
const { color, size = 16, ...otherProps } = props
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Svg
|
||||||
|
width={size}
|
||||||
|
height={size}
|
||||||
|
viewBox={`0 0 ${size} ${size}`}
|
||||||
|
fill="none"
|
||||||
|
strokeWidth="2"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
{...otherProps}
|
||||||
|
>
|
||||||
|
<Path
|
||||||
|
fillRule="evenodd"
|
||||||
|
clipRule="evenodd"
|
||||||
|
d="M4.6 5a1.9 1.9 0 1 1 3.8 0 1.9 1.9 0 0 1-3.8 0Zm1.9-3.1a3.1 3.1 0 1 0 0 6.2 3.1 3.1 0 0 0 0-6.2ZM5 8.9a3.6 3.6 0 0 0-3.6 3.6A1.6 1.6 0 0 0 3 14.1h6a1.6 1.6 0 0 0 1.6-1.6A3.6 3.6 0 0 0 7 8.9H5Zm-2.4 3.6A2.4 2.4 0 0 1 5 10.1h2a2.4 2.4 0 0 1 2.4 2.4.4.4 0 0 1-.4.4H3a.4.4 0 0 1-.4-.4Z"
|
||||||
|
fill={`${color}`}
|
||||||
|
/>
|
||||||
|
<Path
|
||||||
|
d="M10 3.1a1.9 1.9 0 0 1 0 3.8v1.2a3.1 3.1 0 0 0 0-6.2v1.2ZM11 10.1h.5a2.4 2.4 0 0 1 2.4 2.4.4.4 0 0 1-.4.4h-2v1.2h2a1.6 1.6 0 0 0 1.6-1.6 3.6 3.6 0 0 0-3.6-3.6H11v1.2Z"
|
||||||
|
fill={`${color}`}
|
||||||
|
/>
|
||||||
|
</Svg>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Icon.displayName = 'Group'
|
||||||
|
|
||||||
|
export const Group = memo<IconProps>(themed(Icon))
|
|
@ -0,0 +1,32 @@
|
||||||
|
import { memo } from 'react'
|
||||||
|
|
||||||
|
import { Path, Svg } from 'react-native-svg'
|
||||||
|
|
||||||
|
import { themed } from '../themed'
|
||||||
|
|
||||||
|
import type { IconProps } from '../IconProps'
|
||||||
|
|
||||||
|
const Icon = (props: IconProps) => {
|
||||||
|
const { color, size = 16, ...otherProps } = props
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Svg
|
||||||
|
width={size}
|
||||||
|
height={size}
|
||||||
|
viewBox={`0 0 ${size} ${size}`}
|
||||||
|
fill="none"
|
||||||
|
{...otherProps}
|
||||||
|
>
|
||||||
|
<Path
|
||||||
|
d="M5.655 4.735A5.15 5.15 0 0 1 15.15 7.5v.75a3.1 3.1 0 0 0 .62 1.86l.45.6a2.15 2.15 0 0 1-1.212 3.38l2.523 2.523-.92.919-3.38-3.382H5.5a2.15 2.15 0 0 1-1.72-3.44l.45-.6a3.1 3.1 0 0 0 .62-1.86V7.5c0-.524.079-1.03.224-1.507L2.471 3.39l.919-.92 2.265 2.265Zm.517 2.356a3.894 3.894 0 0 0-.022.409v.75a4.4 4.4 0 0 1-.88 2.64l-.45.6a.85.85 0 0 0 .68 1.36h6.431l-5.76-5.76Zm7.598 5.759L6.604 5.685A3.85 3.85 0 0 1 13.85 7.5v.75a4.4 4.4 0 0 0 .88 2.64l.45.6a.85.85 0 0 1-.68 1.36h-.73Zm-2.373 4.522a3.649 3.649 0 0 1-3.978-.791l.92-.92a2.35 2.35 0 0 0 3.323 0l.919.92a3.65 3.65 0 0 1-1.184.791Z"
|
||||||
|
fill={`${color}`}
|
||||||
|
fillRule="evenodd"
|
||||||
|
clipRule="evenodd"
|
||||||
|
/>
|
||||||
|
</Svg>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Icon.displayName = 'Muted'
|
||||||
|
|
||||||
|
export const Muted = memo<IconProps>(themed(Icon))
|
|
@ -0,0 +1,3 @@
|
||||||
|
export { Chevron } from './icons/chevron'
|
||||||
|
export { Group } from './icons/group'
|
||||||
|
export { Muted } from './icons/muted'
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { useCurrentColor } from 'tamagui'
|
||||||
|
|
||||||
|
import type { IconProps } from './IconProps'
|
||||||
|
import type React from 'react'
|
||||||
|
|
||||||
|
export function themed(Component: React.ElementType) {
|
||||||
|
const useWrapped = (props: IconProps) => {
|
||||||
|
const { size, color: colorToken = '$neutral-100', ...rest } = props
|
||||||
|
|
||||||
|
const color = useCurrentColor(colorToken)
|
||||||
|
|
||||||
|
return <Component {...rest} color={color} size={size} />
|
||||||
|
}
|
||||||
|
return useWrapped
|
||||||
|
}
|
|
@ -1,4 +1,6 @@
|
||||||
import { setupReactNative, Stack, styled } from '@tamagui/core'
|
// eslint-disable-next-line eslint-comments/disable-enable-pair
|
||||||
|
/* eslint-disable import/namespace */
|
||||||
|
import { setupReactNative, styled } from '@tamagui/core'
|
||||||
// import { focusableInputHOC } from '@tamagui/focusable'
|
// import { focusableInputHOC } from '@tamagui/focusable'
|
||||||
import { TextInput } from 'react-native'
|
import { TextInput } from 'react-native'
|
||||||
|
|
||||||
|
@ -43,7 +45,7 @@ export const InputFrame = styled(
|
||||||
// },/
|
// },/
|
||||||
|
|
||||||
// focusStyle: {
|
// focusStyle: {
|
||||||
// // borderColor: '$borderColorFocus',
|
|
||||||
// borderWidth: 2,
|
// borderWidth: 2,
|
||||||
// marginHorizontal: -1,
|
// marginHorizontal: -1,
|
||||||
// },
|
// },
|
||||||
|
|
|
@ -1,7 +1,13 @@
|
||||||
|
import { useState } from 'react'
|
||||||
|
|
||||||
import { Stack } from '@tamagui/core'
|
import { Stack } from '@tamagui/core'
|
||||||
|
|
||||||
|
import { Accordion } from '../accordion/accordion'
|
||||||
|
import { AccordionItem } from '../accordion/accordionItem'
|
||||||
import { Avatar } from '../avatar'
|
import { Avatar } from '../avatar'
|
||||||
import { Button } from '../button'
|
// import { Button } from '../button'
|
||||||
|
import { Basketball, Collaboration, Fire, Peach, Play, Unicorn } from '../emoji'
|
||||||
|
import { Group } from '../icon'
|
||||||
import { Image } from '../image'
|
import { Image } from '../image'
|
||||||
import { Heading, Paragraph } from '../typography'
|
import { Heading, Paragraph } from '../typography'
|
||||||
|
|
||||||
|
@ -11,35 +17,259 @@ interface Props {
|
||||||
membersCount: number
|
membersCount: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface Channels {
|
||||||
|
id: string
|
||||||
|
title: string
|
||||||
|
icon?: React.ReactNode
|
||||||
|
channelStatus?: 'muted' | 'normal' | 'withMessages' | 'withMentions'
|
||||||
|
numberOfMessages?: number
|
||||||
|
}
|
||||||
|
interface CommunitiesProps {
|
||||||
|
id: string
|
||||||
|
title: string
|
||||||
|
numberOfNewMessages?: number
|
||||||
|
channels: Channels[]
|
||||||
|
}
|
||||||
|
|
||||||
|
// MOCK DATA
|
||||||
|
const COMMUNITIES: CommunitiesProps[] = [
|
||||||
|
{
|
||||||
|
id: 'welcome',
|
||||||
|
title: 'Welcome',
|
||||||
|
numberOfNewMessages: 3,
|
||||||
|
channels: [
|
||||||
|
{
|
||||||
|
id: 'welcome',
|
||||||
|
title: '# welcome',
|
||||||
|
icon: <Collaboration hasBackground />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'general-welcome',
|
||||||
|
title: '# general',
|
||||||
|
icon: <Play hasBackground />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'random',
|
||||||
|
title: '# random',
|
||||||
|
icon: <Fire hasBackground />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'onboarding',
|
||||||
|
title: '# onboarding',
|
||||||
|
icon: <Unicorn hasBackground />,
|
||||||
|
channelStatus: 'withMentions',
|
||||||
|
numberOfMessages: 3,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'community',
|
||||||
|
title: 'Community',
|
||||||
|
numberOfNewMessages: 5,
|
||||||
|
channels: [
|
||||||
|
{
|
||||||
|
id: 'announcements',
|
||||||
|
title: '# announcements',
|
||||||
|
icon: <Peach hasBackground />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'jobs',
|
||||||
|
title: '# jobs',
|
||||||
|
channelStatus: 'withMentions',
|
||||||
|
numberOfMessages: 3,
|
||||||
|
icon: <Play hasBackground />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'events',
|
||||||
|
title: '# events',
|
||||||
|
channelStatus: 'withMentions',
|
||||||
|
numberOfMessages: 2,
|
||||||
|
icon: <Fire hasBackground />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'meetups',
|
||||||
|
title: '# meetups',
|
||||||
|
icon: <Unicorn hasBackground />,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'Design',
|
||||||
|
title: 'Design',
|
||||||
|
channels: [
|
||||||
|
{
|
||||||
|
id: 'design',
|
||||||
|
title: '# design',
|
||||||
|
icon: <Collaboration hasBackground />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'ux',
|
||||||
|
title: '# ux',
|
||||||
|
icon: <Play hasBackground />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'ui',
|
||||||
|
title: '# ui',
|
||||||
|
icon: <Fire hasBackground />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'figma',
|
||||||
|
title: '# figma',
|
||||||
|
icon: <Unicorn hasBackground />,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'General',
|
||||||
|
title: 'General',
|
||||||
|
channels: [
|
||||||
|
{
|
||||||
|
id: 'general',
|
||||||
|
title: '# general',
|
||||||
|
icon: <Collaboration hasBackground />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'people-ops',
|
||||||
|
title: '# people-ops',
|
||||||
|
icon: <Basketball hasBackground />,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'Frontend',
|
||||||
|
title: 'Frontend',
|
||||||
|
channels: [
|
||||||
|
{
|
||||||
|
id: 'react',
|
||||||
|
title: '# react',
|
||||||
|
icon: <Collaboration hasBackground />,
|
||||||
|
channelStatus: 'withMessages',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'vue',
|
||||||
|
title: '# vue',
|
||||||
|
icon: <Play hasBackground />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'angular',
|
||||||
|
title: '# angular',
|
||||||
|
channelStatus: 'muted',
|
||||||
|
icon: <Fire hasBackground />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'svelte',
|
||||||
|
title: '# svelte',
|
||||||
|
icon: <Unicorn hasBackground />,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'Backend',
|
||||||
|
title: 'Backend',
|
||||||
|
channels: [
|
||||||
|
{
|
||||||
|
id: 'node',
|
||||||
|
title: '# node',
|
||||||
|
icon: <Collaboration hasBackground />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'python',
|
||||||
|
title: '# python',
|
||||||
|
icon: <Play hasBackground />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'ruby',
|
||||||
|
title: '# ruby',
|
||||||
|
icon: <Fire hasBackground />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'php',
|
||||||
|
title: '# php',
|
||||||
|
channelStatus: 'muted',
|
||||||
|
icon: <Unicorn hasBackground />,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
const COMMUNITIES_EXPAND_CONTROL = COMMUNITIES.reduce(
|
||||||
|
(o, key) => ({ ...o, [key.id]: false }),
|
||||||
|
|
||||||
|
{} as Record<string, boolean>[]
|
||||||
|
)
|
||||||
|
|
||||||
const _Sidebar = (props: Props) => {
|
const _Sidebar = (props: Props) => {
|
||||||
const { name, description, membersCount } = props
|
const { name, description, membersCount } = props
|
||||||
|
const [isExpanded, setIsExpanded] = useState({
|
||||||
|
...COMMUNITIES_EXPAND_CONTROL,
|
||||||
|
welcome: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
const [selectedChannel, setSelectedChannel] = useState('welcome')
|
||||||
|
|
||||||
|
const handleToggle = (id: string) => {
|
||||||
|
setIsExpanded(prev => ({
|
||||||
|
...prev,
|
||||||
|
[id]: !prev[id as keyof typeof isExpanded],
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack backgroundColor="$background" minHeight={'calc(100vh - 2px)'}>
|
<Stack backgroundColor="$background">
|
||||||
<Image
|
<Image
|
||||||
src="https://images.unsplash.com/photo-1584475784921-d9dbfd9d17ca?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1740&q=80"
|
src="https://images.unsplash.com/photo-1584475784921-d9dbfd9d17ca?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1740&q=80"
|
||||||
width={350}
|
width={352}
|
||||||
height={136}
|
height={136}
|
||||||
/>
|
/>
|
||||||
<Stack
|
<Stack
|
||||||
paddingHorizontal={16}
|
|
||||||
paddingBottom={16}
|
paddingBottom={16}
|
||||||
marginTop={-16}
|
marginTop={-16}
|
||||||
backgroundColor="$background"
|
backgroundColor="$background"
|
||||||
borderTopLeftRadius={16}
|
borderTopLeftRadius={20}
|
||||||
borderTopRightRadius={16}
|
borderTopRightRadius={20}
|
||||||
zIndex={10}
|
zIndex={10}
|
||||||
>
|
>
|
||||||
<Stack marginTop={-32} marginBottom={12}>
|
<Stack paddingHorizontal={16}>
|
||||||
<Avatar
|
<Stack marginTop={-32} marginBottom={12}>
|
||||||
src="https://images.unsplash.com/photo-1553835973-dec43bfddbeb?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1740&q=80"
|
<Avatar
|
||||||
size={56}
|
withOutline
|
||||||
/>
|
src="https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fi.seadn.io%2Fgae%2FFG0QJ00fN3c_FWuPeUr9-T__iQl63j9hn5d6svW8UqOmia5zp3lKHPkJuHcvhZ0f_Pd6P2COo9tt9zVUvdPxG_9BBw%3Fw%3D500%26auto%3Dformat&f=1&nofb=1&ipt=c177cd71d8d0114080cfc6efd3f9e098ddaeb1b347919bd3089bf0aacb003b3e&ipo=images"
|
||||||
|
size={56}
|
||||||
|
/>
|
||||||
|
</Stack>
|
||||||
|
<Heading marginBottom={16}>{name}</Heading>
|
||||||
|
<Paragraph marginBottom={12}>{description}</Paragraph>
|
||||||
|
<Stack flexDirection="row" alignItems="center" mb={12}>
|
||||||
|
<Group color="$neutral-100" size={16} />
|
||||||
|
<Paragraph ml={8}>{membersCount}</Paragraph>
|
||||||
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Heading marginBottom={16}>{name}</Heading>
|
{COMMUNITIES.map(community => (
|
||||||
<Paragraph marginBottom={12}>{description}</Paragraph>
|
<Accordion
|
||||||
<Paragraph marginBottom={12}>{membersCount}</Paragraph>
|
key={community.id}
|
||||||
<Button>Request to join community</Button>
|
isExpanded={!!isExpanded[community.id as keyof typeof isExpanded]}
|
||||||
|
onToggle={() => handleToggle(community.id)}
|
||||||
|
title={community.title}
|
||||||
|
numberOfNewMessages={community.numberOfNewMessages}
|
||||||
|
showNotifications={
|
||||||
|
!isExpanded[community.id as keyof typeof isExpanded]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{community.channels.map(channel => (
|
||||||
|
<AccordionItem
|
||||||
|
key={channel.id}
|
||||||
|
icon={channel.icon}
|
||||||
|
title={channel.title}
|
||||||
|
channelStatus={channel.channelStatus}
|
||||||
|
numberOfMessages={channel.numberOfMessages}
|
||||||
|
isSelected={selectedChannel === channel.id}
|
||||||
|
onPress={() => setSelectedChannel(channel.id)}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</Accordion>
|
||||||
|
))}
|
||||||
|
<Stack borderBottomColor="$neutral-10" borderBottomWidth={1} />
|
||||||
|
{/* <Button mt={20}>Request to join community</Button> */}
|
||||||
</Stack>
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
)
|
)
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { createInterFont } from '@tamagui/font-inter'
|
||||||
import { createMedia } from '@tamagui/react-native-media-driver'
|
import { createMedia } from '@tamagui/react-native-media-driver'
|
||||||
import { shorthands } from '@tamagui/shorthands'
|
import { shorthands } from '@tamagui/shorthands'
|
||||||
|
|
||||||
import { animations, animationsCSS } from './animations'
|
import { animations } from './animations'
|
||||||
import { themes } from './themes'
|
import { themes } from './themes'
|
||||||
import { tokens } from './tokens'
|
import { tokens } from './tokens'
|
||||||
|
|
||||||
|
@ -106,8 +106,5 @@ export const config = createTamagui({
|
||||||
pointerCoarse: { pointer: 'coarse' },
|
pointerCoarse: { pointer: 'coarse' },
|
||||||
}),
|
}),
|
||||||
shorthands,
|
shorthands,
|
||||||
animations: {
|
animations,
|
||||||
...animations,
|
|
||||||
...animationsCSS,
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
|
|
|
@ -35,7 +35,10 @@ const light = createTheme({
|
||||||
beigeHover: tokens.color['beige-60'],
|
beigeHover: tokens.color['beige-60'],
|
||||||
})
|
})
|
||||||
|
|
||||||
const dark = createTheme({
|
// note: we set up a single consistent base type to validate the rest:
|
||||||
|
type BaseTheme = typeof light
|
||||||
|
|
||||||
|
const dark: BaseTheme = createTheme({
|
||||||
background: tokens.color['neutral-95'],
|
background: tokens.color['neutral-95'],
|
||||||
textPrimary: tokens.color['white-100'],
|
textPrimary: tokens.color['white-100'],
|
||||||
primary: tokens.color['primary-60'],
|
primary: tokens.color['primary-60'],
|
||||||
|
@ -68,7 +71,15 @@ const dark = createTheme({
|
||||||
beigeHover: tokens.color['beige-50'],
|
beigeHover: tokens.color['beige-50'],
|
||||||
})
|
})
|
||||||
|
|
||||||
export const themes = {
|
const allThemes = {
|
||||||
light,
|
light,
|
||||||
dark,
|
dark,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ThemeName = keyof typeof allThemes
|
||||||
|
|
||||||
|
type Themes = {
|
||||||
|
[key in ThemeName]: BaseTheme
|
||||||
|
}
|
||||||
|
|
||||||
|
export const themes: Themes = allThemes
|
||||||
|
|
67
yarn.lock
67
yarn.lock
|
@ -8488,7 +8488,26 @@ css-select@^4.1.3, css-select@^4.2.0:
|
||||||
domutils "^2.8.0"
|
domutils "^2.8.0"
|
||||||
nth-check "^2.0.1"
|
nth-check "^2.0.1"
|
||||||
|
|
||||||
css-what@^6.0.1:
|
css-select@^5.1.0:
|
||||||
|
version "5.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/css-select/-/css-select-5.1.0.tgz#b8ebd6554c3637ccc76688804ad3f6a6fdaea8a6"
|
||||||
|
integrity sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==
|
||||||
|
dependencies:
|
||||||
|
boolbase "^1.0.0"
|
||||||
|
css-what "^6.1.0"
|
||||||
|
domhandler "^5.0.2"
|
||||||
|
domutils "^3.0.1"
|
||||||
|
nth-check "^2.0.1"
|
||||||
|
|
||||||
|
css-tree@^1.1.3:
|
||||||
|
version "1.1.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d"
|
||||||
|
integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==
|
||||||
|
dependencies:
|
||||||
|
mdn-data "2.0.14"
|
||||||
|
source-map "^0.6.1"
|
||||||
|
|
||||||
|
css-what@^6.0.1, css-what@^6.1.0:
|
||||||
version "6.1.0"
|
version "6.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4"
|
resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4"
|
||||||
integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==
|
integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==
|
||||||
|
@ -8880,12 +8899,21 @@ dom-serializer@^1.0.1:
|
||||||
domhandler "^4.2.0"
|
domhandler "^4.2.0"
|
||||||
entities "^2.0.0"
|
entities "^2.0.0"
|
||||||
|
|
||||||
|
dom-serializer@^2.0.0:
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53"
|
||||||
|
integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==
|
||||||
|
dependencies:
|
||||||
|
domelementtype "^2.3.0"
|
||||||
|
domhandler "^5.0.2"
|
||||||
|
entities "^4.2.0"
|
||||||
|
|
||||||
dom-walk@^0.1.0:
|
dom-walk@^0.1.0:
|
||||||
version "0.1.2"
|
version "0.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84"
|
resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84"
|
||||||
integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==
|
integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==
|
||||||
|
|
||||||
domelementtype@^2.0.1, domelementtype@^2.2.0:
|
domelementtype@^2.0.1, domelementtype@^2.2.0, domelementtype@^2.3.0:
|
||||||
version "2.3.0"
|
version "2.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d"
|
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d"
|
||||||
integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==
|
integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==
|
||||||
|
@ -8897,6 +8925,13 @@ domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
domelementtype "^2.2.0"
|
domelementtype "^2.2.0"
|
||||||
|
|
||||||
|
domhandler@^5.0.1, domhandler@^5.0.2:
|
||||||
|
version "5.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31"
|
||||||
|
integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==
|
||||||
|
dependencies:
|
||||||
|
domelementtype "^2.3.0"
|
||||||
|
|
||||||
domutils@^2.5.2, domutils@^2.8.0:
|
domutils@^2.5.2, domutils@^2.8.0:
|
||||||
version "2.8.0"
|
version "2.8.0"
|
||||||
resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135"
|
resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135"
|
||||||
|
@ -8906,6 +8941,15 @@ domutils@^2.5.2, domutils@^2.8.0:
|
||||||
domelementtype "^2.2.0"
|
domelementtype "^2.2.0"
|
||||||
domhandler "^4.2.0"
|
domhandler "^4.2.0"
|
||||||
|
|
||||||
|
domutils@^3.0.1:
|
||||||
|
version "3.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.0.1.tgz#696b3875238338cb186b6c0612bd4901c89a4f1c"
|
||||||
|
integrity sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==
|
||||||
|
dependencies:
|
||||||
|
dom-serializer "^2.0.0"
|
||||||
|
domelementtype "^2.3.0"
|
||||||
|
domhandler "^5.0.1"
|
||||||
|
|
||||||
dot-case@^3.0.4:
|
dot-case@^3.0.4:
|
||||||
version "3.0.4"
|
version "3.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751"
|
resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751"
|
||||||
|
@ -9001,6 +9045,11 @@ entities@^2.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55"
|
resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55"
|
||||||
integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==
|
integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==
|
||||||
|
|
||||||
|
entities@^4.2.0:
|
||||||
|
version "4.4.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/entities/-/entities-4.4.0.tgz#97bdaba170339446495e653cfd2db78962900174"
|
||||||
|
integrity sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==
|
||||||
|
|
||||||
env-editor@^0.4.1:
|
env-editor@^0.4.1:
|
||||||
version "0.4.2"
|
version "0.4.2"
|
||||||
resolved "https://registry.yarnpkg.com/env-editor/-/env-editor-0.4.2.tgz#4e76568d0bd8f5c2b6d314a9412c8fe9aa3ae861"
|
resolved "https://registry.yarnpkg.com/env-editor/-/env-editor-0.4.2.tgz#4e76568d0bd8f5c2b6d314a9412c8fe9aa3ae861"
|
||||||
|
@ -13300,6 +13349,11 @@ mdast-util-to-string@^1.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz#27055500103f51637bd07d01da01eb1967a43527"
|
resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz#27055500103f51637bd07d01da01eb1967a43527"
|
||||||
integrity sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A==
|
integrity sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A==
|
||||||
|
|
||||||
|
mdn-data@2.0.14:
|
||||||
|
version "2.0.14"
|
||||||
|
resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50"
|
||||||
|
integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==
|
||||||
|
|
||||||
media-typer@0.3.0:
|
media-typer@0.3.0:
|
||||||
version "0.3.0"
|
version "0.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
|
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
|
||||||
|
@ -14079,7 +14133,6 @@ node-fetch-native@^1.0.1:
|
||||||
|
|
||||||
node-fetch@2.6.7, node-fetch@^2.2.0, node-fetch@^2.6.0, node-fetch@^2.6.1, node-fetch@^2.6.7, node-fetch@^2.x.x:
|
node-fetch@2.6.7, node-fetch@^2.2.0, node-fetch@^2.6.0, node-fetch@^2.6.1, node-fetch@^2.6.7, node-fetch@^2.x.x:
|
||||||
version "2.6.7"
|
version "2.6.7"
|
||||||
uid "1b5d62978f2ed07b99444f64f0df39f960a6d34d"
|
|
||||||
resolved "https://registry.npmjs.org/@achingbrain/node-fetch/-/node-fetch-2.6.7.tgz#1b5d62978f2ed07b99444f64f0df39f960a6d34d"
|
resolved "https://registry.npmjs.org/@achingbrain/node-fetch/-/node-fetch-2.6.7.tgz#1b5d62978f2ed07b99444f64f0df39f960a6d34d"
|
||||||
|
|
||||||
node-forge@^1.1.0, node-forge@^1.2.1, node-forge@^1.3.1:
|
node-forge@^1.1.0, node-forge@^1.2.1, node-forge@^1.3.1:
|
||||||
|
@ -15374,6 +15427,14 @@ react-native-gradle-plugin@^0.70.3:
|
||||||
resolved "https://registry.yarnpkg.com/react-native-gradle-plugin/-/react-native-gradle-plugin-0.70.3.tgz#cbcf0619cbfbddaa9128701aa2d7b4145f9c4fc8"
|
resolved "https://registry.yarnpkg.com/react-native-gradle-plugin/-/react-native-gradle-plugin-0.70.3.tgz#cbcf0619cbfbddaa9128701aa2d7b4145f9c4fc8"
|
||||||
integrity sha512-oOanj84fJEXUg9FoEAQomA8ISG+DVIrTZ3qF7m69VQUJyOGYyDZmPqKcjvRku4KXlEH6hWO9i4ACLzNBh8gC0A==
|
integrity sha512-oOanj84fJEXUg9FoEAQomA8ISG+DVIrTZ3qF7m69VQUJyOGYyDZmPqKcjvRku4KXlEH6hWO9i4ACLzNBh8gC0A==
|
||||||
|
|
||||||
|
react-native-svg@^13.7.0:
|
||||||
|
version "13.7.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-13.7.0.tgz#be2ffb935e996762543dd7376bdc910722f7a43c"
|
||||||
|
integrity sha512-WR5CIURvee5cAfvMhmdoeOjh1SC8KdLq5u5eFsz4pbYzCtIFClGSkLnNgkMSDMVV5LV0qQa4jeIk75ieIBzaDA==
|
||||||
|
dependencies:
|
||||||
|
css-select "^5.1.0"
|
||||||
|
css-tree "^1.1.3"
|
||||||
|
|
||||||
react-native-web-internals@^1.0.15:
|
react-native-web-internals@^1.0.15:
|
||||||
version "1.0.15"
|
version "1.0.15"
|
||||||
resolved "https://registry.yarnpkg.com/react-native-web-internals/-/react-native-web-internals-1.0.15.tgz#8c4367e2461edf5bab4abab71471b351a08cb19f"
|
resolved "https://registry.yarnpkg.com/react-native-web-internals/-/react-native-web-internals-1.0.15.tgz#8c4367e2461edf5bab4abab71471b351a08cb19f"
|
||||||
|
|
Loading…
Reference in New Issue