Skip to content

Commit

Permalink
feat: basic feed UI (#2181)
Browse files Browse the repository at this point in the history
* chore: upgrade `zui`

* feat: sidekick margin should be 16px

* chore: create some mock posts

* feat: add WIP UI

* chore: `@ts-ignore` zUI `Name` component

* chore: remove `console.log`

* feat: use `textarea`

* feat: auto-resize `textarea`

* feat: mock submit, avatar

* chore: upgrade `@zero-tech/zui` -> `1.13.1`

* feat: avatar layout
  • Loading branch information
colbr authored Aug 19, 2024
1 parent f34d7de commit 6410aca
Show file tree
Hide file tree
Showing 13 changed files with 325 additions and 16 deletions.
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"@web3-react/network-connector": "^6.1.9",
"@web3-react/walletlink-connector": "^6.2.13",
"@zer0-os/zos-component-library": "0.18.9",
"@zero-tech/zui": "1.11.4",
"@zero-tech/zui": "^1.13.1",
"assert": "^2.1.0",
"buffer": "^6.0.3",
"classnames": "^2.3.1",
Expand Down
75 changes: 75 additions & 0 deletions src/components/messenger/feed/components/create-post/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { useEffect, useRef, useState } from 'react';

import { Avatar, Button, IconButton } from '@zero-tech/zui/components';
import { IconCamera1, IconPlus, IconMicrophone2 } from '@zero-tech/zui/icons';

import styles from './styles.module.scss';

export const CreatePost = () => {
const [value, setValue] = useState('');
const [isLoading, setIsLoading] = useState<boolean>(false);

const handleOnChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
setValue(event.target.value);
};

const handleOnSubmit = () => {
setIsLoading(true);
setTimeout(() => {
setIsLoading(false);
}, 2000);
};

return (
<div className={styles.Container}>
<Avatar size={'regular'} />
<div className={styles.Create}>
<PostInput value={value} onChange={handleOnChange} />
<hr />
<div className={styles.Actions}>
<div className={styles.Media}>
<IconButton Icon={IconPlus} onClick={() => {}} />
<IconButton Icon={IconCamera1} onClick={() => {}} />
<IconButton Icon={IconMicrophone2} onClick={() => {}} />
</div>
<Button isDisabled={!value} isLoading={isLoading} className={styles.Button} onPress={handleOnSubmit}>
Create
</Button>
</div>
</div>
</div>
);
};

interface PostInputProps {
onChange: (event: React.ChangeEvent<HTMLTextAreaElement>) => void;
value: string;
}

const PostInput = ({ onChange, value }: PostInputProps) => {
const ref = useRef<HTMLTextAreaElement>(null);

useEffect(() => {
if (ref.current) {
ref.current.style.height = 'auto';
ref.current.style.height = `${ref.current.scrollHeight}px`;

// Auto-resize on input
ref.current.addEventListener('input', () => {
ref.current.style.height = 'auto';
ref.current.style.height = `${ref.current.scrollHeight}px`;
});
}
}, []);

return (
<textarea
className={styles.Input}
onChange={onChange}
placeholder='Write a post'
ref={ref}
rows={2}
value={value}
/>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
.Container {
display: flex;
gap: 8px;
padding: 16px 8px;
}

.Create {
align-items: flex-end;
display: flex;
flex: 1;
flex-direction: column;
gap: 8px;

hr {
border: none;
border-bottom: 1px solid rgba(245, 245, 245, 0.12);
outline: none;
width: 100%;
}
}

.Input {
background: none;
border: none;
color: white;
font-size: 16px;
height: auto;
outline: none;
resize: none;
width: 100%;
}

.Actions,
.Media {
display: flex;
width: 100%;
gap: 8px;

svg {
color: var(--color-secondary-11) !important;
}
}

.Button {
border-radius: 8px;
}
55 changes: 55 additions & 0 deletions src/components/messenger/feed/components/post/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { Action, Name, Post as ZUIPost } from '@zero-tech/zui/components/Post';
import { Timestamp } from '@zero-tech/zui/components/Post/components/Timestamp';
import type { Post as PostType } from '../../lib/types';
import { IconMessageSquare2, IconShare7 } from '@zero-tech/zui/icons';
import { Avatar } from '@zero-tech/zui/components';

import styles from './styles.module.scss';

export interface PostProps {
post: PostType;
}

export const Post = ({ post }: PostProps) => {
return (
<div className={styles.Container}>
<div>
<Avatar size='regular' />
</div>
<ZUIPost
className={styles.Post}
body={post.text}
details={
<>
{/* @ts-ignore */}
<Name variant='name'>{post.nickname}</Name>
{/* @ts-ignore */}
<Name variant='username'>{post.author}</Name>
</>
}
options={<Timestamp timestamp={post.timestamp} />}
actions={
<>
<Action>
<IconMessageSquare2 size={16} />
230
</Action>
<Action>
<IconShare7 size={16} />
100
</Action>
<Action>
<svg width='15' height='13' viewBox='0 0 16 14' fill='none' xmlns='http://www.w3.org/2000/svg'>
<path
d='M12.8113 8.32429C11.3858 10.7087 8.45708 10.3566 8.45708 10.3566C8.45708 6.03666 12.2491 6.03666 12.2491 6.03666H13.5226C13.4189 6.99328 13.1604 7.74064 12.8113 8.32429ZM3.18868 8.32429C2.83962 7.74064 2.58113 6.99328 2.47736 6.03666H3.75094C3.75094 6.03666 7.54292 6.03666 7.54292 10.3566C7.54292 10.3566 4.61415 10.7087 3.18868 8.32429ZM14.3193 0.333496L10.2726 3.51273H5.72736L1.68066 0.333496L0.5 7.87682L5.46745 13.3793C5.54906 13.4699 5.64906 13.5425 5.76038 13.5919C5.8717 13.6412 5.99198 13.6668 6.11368 13.6668H9.88632C10.008 13.6668 10.1283 13.6412 10.2396 13.5919C10.3509 13.5425 10.4505 13.4699 10.5325 13.3793L15.5 7.87682L14.3193 0.333496Z'
fill='#01F4CB'
/>
</svg>
100.20
</Action>
</>
}
/>
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.Container {
display: flex;
gap: 8px;
}

.Post {
padding: 0;
}
16 changes: 16 additions & 0 deletions src/components/messenger/feed/components/posts/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Post } from '../post';
import { MOCK_POSTS } from '../../mock';

import styles from './styles.module.scss';

export const Posts = () => {
return (
<ol className={styles.Posts}>
{MOCK_POSTS.map((post) => (
<li key={post.id}>
<Post post={post} />
</li>
))}
</ol>
);
};
11 changes: 11 additions & 0 deletions src/components/messenger/feed/components/posts/styles.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.Posts {
list-style: none;
margin: 0;
padding: 0;

> li {
padding: 16px 8px;

border-top: 1px solid rgba(245, 245, 245, 0.12);
}
}
13 changes: 9 additions & 4 deletions src/components/messenger/feed/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import React from 'react';
import { RootState } from '../../../store/reducer';
import { connectContainer } from '../../../store/redux-container';
import { rawChannelSelector } from '../../../store/channels/saga';
import { Posts } from './components/posts';
import { ScrollbarContainer } from '../../scrollbar-container';
import { CreatePost } from './components/create-post';

import { bemClassName } from '../../../lib/bem';
import './styles.scss';
Expand Down Expand Up @@ -38,10 +41,12 @@ export class Container extends React.Component<Properties> {

return (
<>
<div {...cn('')}>
<>Messenger Feed</>
<div {...cn('feed-view')}>Feed View Component</div>
</div>
<ScrollbarContainer>
<div {...cn('')}>
<CreatePost />
<Posts />
</div>
</ScrollbarContainer>
<div {...cn('divider')} />
</>
);
Expand Down
7 changes: 7 additions & 0 deletions src/components/messenger/feed/lib/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export interface Post {
id: string;
timestamp: number;
author: string;
nickname: string;
text: string;
}
81 changes: 81 additions & 0 deletions src/components/messenger/feed/mock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import type { Post } from './lib/types';

export const MOCK_POSTS: Post[] = [
{
id: '0',
timestamp: 1723791475000,
author: '0://bob',
nickname: 'Bob',
text: "Just finished reading an amazing book! 📚✨ It's called 'The Alchemist' by Paulo Coelho. Highly recommend it to anyone looking for a bit of inspiration and magic in their life. Has anyone else read it? What did you think?",
},
{
id: '1',
timestamp: 1723791575000,
author: '0://alice',
nickname: 'Alice',
text: 'Had a great time hiking today! The view from the top was breathtaking. 🏞️',
},
{
id: '2',
timestamp: 1723791675000,
author: '0://charlie',
nickname: 'Charlie',
text: 'Just baked some cookies and they turned out delicious! 🍪 Who wants some?',
},
{
id: '3',
timestamp: 1723791775000,
author: '0://dave',
nickname: 'Dave',
text: 'Watching the sunset by the beach. Life is good. 🌅',
},
{
id: '4',
timestamp: 1723791875000,
author: '0://eve',
nickname: 'Eve',
text: "Started learning how to play the guitar today. My fingers hurt but it's so much fun! 🎸",
},
{
id: '5',
timestamp: 1723791975000,
author: '0://frank',
nickname: 'Frank',
text: 'Just finished a 5K run. Feeling accomplished and exhausted at the same time. 🏃‍♂️',
},
{
id: '6',
timestamp: 1723792075000,
author: '0://grace',
nickname: 'Grace',
text: 'Made a new friend at the dog park today. Both our dogs got along so well! 🐶',
},
{
id: '7',
timestamp: 1723792175000,
author: '0://heidi',
nickname: 'Heidi',
text: 'Trying out a new recipe tonight. Hope it turns out as good as it looks in the picture! 🍲',
},
{
id: '8',
timestamp: 1723792275000,
author: '0://ivan',
nickname: 'Ivan',
text: 'Just got back from a weekend getaway. Feeling refreshed and ready to tackle the week ahead. 🏖️',
},
{
id: '9',
timestamp: 1723792375000,
author: '0://judy',
nickname: 'Judy',
text: "Spent the afternoon painting. It's so relaxing and therapeutic. 🎨",
},
{
id: '10',
timestamp: 1723792475000,
author: '0://ken',
nickname: 'Ken',
text: 'Just watched an amazing movie. Highly recommend it to everyone! 🎬',
},
];
11 changes: 8 additions & 3 deletions src/components/messenger/feed/styles.scss
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
.messenger-feed {
display: flex;
flex-direction: column;
gap: 32px;
align-items: center;
width: 100%;
margin: auto 0;
padding-top: 16px;

padding: 16px 8px 0 8px;
box-sizing: border-box;

pointer-events: auto;
background: var(--Transparencies-Black-translucent, #0000007a);
backdrop-filter: blur(60px);

&__feed-view {
display: flex;
Expand Down
Loading

0 comments on commit 6410aca

Please sign in to comment.