This repository was archived by the owner on Mar 4, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 51
docs(chat-pane): chat-pane prototype #235
Merged
Merged
Changes from all commits
Commits
Show all changes
37 commits
Select commit
Hold shift + click to select a range
6b683a9
docs(chat-pane): add chat-pane prototype
bmdalex aa4ac4f
feat(chat): add author and timestamp props
bmdalex f9bbdb0
Merge branch 'master' into feat/chat-author-and-timestamp
ab2935e
-addressing comments on the PR
8f463c4
-adding more variables to the chat and chat message components
7210744
-removed timestamp right margin style
85a9998
Merge branch 'feat/chat-author-and-timestamp' into docs/chat-pane-pro…
3d6e6c4
Merge branch 'master' into docs/chat-pane-prototype
9d512f7
-updated styles in the chat pane according to the new usages without …
47be3b9
-added author and timestamp to the chat pane messages example
6e0db1a
-added menu in the chat pane header
6f12ee8
-adjusting the header according to the styling guides
5570706
Merge branch 'master' of https://github.com/stardust-ui/react into do…
bmdalex deb76e0
Merge branch 'master' of https://github.com/stardust-ui/react into do…
bmdalex 92edc79
code update
bmdalex 9c4fc3e
Merge branch 'master' of https://github.com/stardust-ui/react into do…
bmdalex 644826e
fixed type errors
bmdalex a6f7285
Merge branch 'master' of https://github.com/stardust-ui/react into do…
bmdalex 305db49
fixed conflicts
bmdalex ffe0cd8
Merge branch 'master' of https://github.com/stardust-ui/react into do…
bmdalex 9f0bf6c
fixed build issue
bmdalex 12e8ff4
Merge branch 'master' into docs/chat-pane-prototype
4a04fca
fixed styling
bmdalex 2ca8708
Merge branch 'master' into docs/chat-pane-prototype
f2234ba
Merge branch 'master' into docs/chat-pane-prototype
a514df4
Merge branch 'master' of https://github.com/stardust-ui/react into do…
bmdalex 75278a4
Merge branch 'master' into docs/chat-pane-prototype
327ab32
-updating with the latest changes from master
9dc7bd0
Merge branch 'master' of https://github.com/stardust-ui/react into do…
bmdalex cc4d9e9
Merge branch 'master' of https://github.com/stardust-ui/react into do…
bmdalex af641d4
updates:
bmdalex 3c33a3b
Merge branch 'master' of https://github.com/stardust-ui/react into do…
bmdalex 8d5449e
Merge branch 'master' of https://github.com/stardust-ui/react into do…
bmdalex 1ebf826
addressed comments
bmdalex b44e07a
Merge branch 'master' of https://github.com/stardust-ui/react into do…
bmdalex 3cf76e3
Merge branch 'master' of https://github.com/stardust-ui/react into do…
bmdalex 35cdb3f
synced descriptions with the previous changelog
bmdalex File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| import * as React from 'react' | ||
| import * as _ from 'lodash' | ||
| import Scrollbars from 'react-custom-scrollbars' | ||
| import { Chat, Divider } from '@stardust-ui/react' | ||
|
|
||
| import { IChat, ChatItemType, generateChatProps } from './services' | ||
|
|
||
| export interface IChatPaneContainerProps { | ||
| chat: IChat | ||
| } | ||
|
|
||
| class ChatPaneContainer extends React.PureComponent<IChatPaneContainerProps> { | ||
| public render() { | ||
| const items = this.generateChatItems(this.props.chat) | ||
|
|
||
| return ( | ||
| items.length > 0 && ( | ||
| <Scrollbars ref={this.handleScrollRef}> | ||
| <Chat items={items} styles={{ padding: '0 32px' }} /> | ||
| </Scrollbars> | ||
| ) | ||
| ) | ||
| } | ||
|
|
||
| private generateChatItems(chat: IChat): JSX.Element[] { | ||
| return generateChatProps(chat).map(({ itemType, ...props }, index) => { | ||
| const ElementType = this.getElementType(itemType) | ||
| return ( | ||
bmdalex marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| <Chat.Item key={`chat-item-${index}`}> | ||
| <ElementType {...props} /> | ||
| </Chat.Item> | ||
| ) | ||
| }) | ||
| } | ||
|
|
||
| private getElementType = (itemType: ChatItemType) => { | ||
| switch (itemType) { | ||
bmdalex marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| case ChatItemType.message: | ||
| return Chat.Message | ||
| case ChatItemType.divider: | ||
| return Divider | ||
| } | ||
| } | ||
|
|
||
| private handleScrollRef(scrollRef: Scrollbars) { | ||
| if (scrollRef) { | ||
| scrollRef.scrollToBottom() | ||
| } | ||
| } | ||
| } | ||
|
|
||
| export default ChatPaneContainer | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,100 @@ | ||
| import * as React from 'react' | ||
| import { Avatar, Button, Divider, Icon, Layout, Segment, Text } from '@stardust-ui/react' | ||
|
|
||
| import { pxToRem } from 'src/lib' | ||
| import { IChat } from './services' | ||
| import { Sizes } from 'src/lib/enums' | ||
|
|
||
| export interface IChatPaneHeaderProps { | ||
| chat?: IChat | ||
| } | ||
|
|
||
| class ChatPaneHeader extends React.PureComponent<IChatPaneHeaderProps> { | ||
| public render() { | ||
| return ( | ||
| <Layout | ||
| vertical | ||
| start={this.renderBanner()} | ||
| main={this.renderMainArea()} | ||
| end={<Divider size={2} styles={{ padding: '0 32px' }} />} | ||
| /> | ||
| ) | ||
| } | ||
|
|
||
| private renderBanner(): React.ReactNode { | ||
| return ( | ||
| <Segment | ||
| content={ | ||
| <Icon | ||
| size="big" | ||
| name="team-create" | ||
| variables={siteVars => ({ color: siteVars.white, margin: 'auto 8px' })} | ||
| /> | ||
| } | ||
| styles={({ variables: v }) => ({ | ||
| backgroundColor: v.backgroundColor, | ||
| borderRadius: 0, | ||
| display: 'flex', | ||
| height: '40px', | ||
| padding: 0, | ||
| })} | ||
| variables={siteVars => ({ backgroundColor: siteVars.brand })} | ||
| /> | ||
| ) | ||
| } | ||
|
|
||
| private renderMainArea(): React.ReactNode { | ||
| const { chat } = this.props | ||
|
|
||
| return ( | ||
| <Layout | ||
| start={<Avatar name={chat.title} />} | ||
| main={ | ||
| <Text | ||
| size={Sizes.Large} | ||
| content={chat.title} | ||
| styles={{ marginLeft: '12px', fontWeight: 600 }} | ||
| /> | ||
| } | ||
| end={this.renderHeaderButtons()} | ||
| alignItems="center" | ||
| styles={{ padding: '16px 32px' }} | ||
| /> | ||
| ) | ||
| } | ||
|
|
||
| private renderHeaderButtons(): React.ReactNode { | ||
bmdalex marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| return ( | ||
| <div style={{ display: 'inline-flex' }}> | ||
| <Button.Group | ||
| circular | ||
| buttons={['call-video', 'call'].map((name, index) => ({ | ||
| key: `${index}-${name}`, | ||
| icon: { | ||
| name, | ||
| size: 'big', | ||
| variables: siteVars => ({ color: siteVars.white, margin: 'auto 8px' }), | ||
| }, | ||
| type: 'primary', | ||
| }))} | ||
| styles={{ marginRight: '20px' }} | ||
| /> | ||
| {['user plus', 'ellipsis horizontal'].map((name, index) => ( | ||
| <Icon | ||
| key={`${index}-${name}`} | ||
| name={name} | ||
| tabIndex={0} | ||
| styles={{ | ||
| fontWeight: 100, | ||
| ...(!index && { marginRight: '1.6rem' }), | ||
| marginTop: pxToRem(8), | ||
| }} | ||
| variables={siteVars => ({ color: siteVars.gray04 })} | ||
| /> | ||
| ))} | ||
| </div> | ||
| ) | ||
| } | ||
| } | ||
|
|
||
| export default ChatPaneHeader | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| import * as React from 'react' | ||
| import { Layout } from '@stardust-ui/react' | ||
| import { IChat } from './services' | ||
|
|
||
| import ChatPaneHeader from './chatPaneHeader' | ||
| import ChatPaneContainer from './chatPaneContent' | ||
| import ComposeMessage from './composeMessage' | ||
|
|
||
| export interface IChatPaneLayoutProps { | ||
| chat: IChat | ||
| } | ||
|
|
||
| const ChatPaneLayout: React.SFC<IChatPaneLayoutProps> = ({ chat }: IChatPaneLayoutProps) => ( | ||
| <Layout | ||
| vertical | ||
| start={<ChatPaneHeader chat={chat} />} | ||
| main={<ChatPaneContainer chat={chat} />} | ||
| end={<ComposeMessage />} | ||
| styles={{ | ||
| backgroundColor: '#f3f2f1', | ||
| left: 0, | ||
| paddingLeft: '250px', | ||
| width: '100%', | ||
| height: '100%', | ||
| position: 'fixed', | ||
| }} | ||
| /> | ||
| ) | ||
|
|
||
| export default ChatPaneLayout |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,72 @@ | ||
| import * as React from 'react' | ||
| import { Layout, Input, ToolbarButtonBehavior, ToolbarBehavior, Menu } from '@stardust-ui/react' | ||
| import { IMenuItemProps } from 'src/components/Menu/MenuItem' | ||
|
|
||
| type ToolbarProps = IMenuItemProps & { key: string; 'aria-label'?: string } | ||
|
|
||
| class ComposeMessage extends React.Component { | ||
| public render() { | ||
| return ( | ||
| <Layout | ||
| vertical | ||
| start={this.renderInput()} | ||
| main={this.renderToolbar()} | ||
| styles={{ padding: '16px 32px' }} | ||
| /> | ||
| ) | ||
| } | ||
|
|
||
| private renderInput(): React.ReactNode { | ||
| return ( | ||
| <Input | ||
| fluid | ||
| placeholder="Type a message" | ||
| variables={siteVars => ({ backgroundColor: siteVars.white })} | ||
| /> | ||
| ) | ||
| } | ||
|
|
||
| private renderToolbar(): React.ReactNode { | ||
| const items: (ToolbarProps | JSX.Element)[] = [ | ||
| 'compose', | ||
| 'attach', | ||
| 'smile', | ||
| 'picture', | ||
| 'smile outline', | ||
| 'calendar alternate', | ||
| 'ellipsis horizontal', | ||
| 'send', | ||
| ].map((icon, index) => this.getMenuItem(icon, index)) | ||
|
|
||
| items.splice(-1, 0, { key: 'separator', styles: { flex: 1 } }) | ||
|
|
||
| return ( | ||
| <Menu | ||
| defaultActiveIndex={0} | ||
| items={items} | ||
| iconOnly | ||
| accessibility={ToolbarBehavior} | ||
| aria-label="Compose Editor" | ||
| styles={{ marginTop: '10px' }} | ||
| /> | ||
| ) | ||
| } | ||
|
|
||
| private getMenuItem( | ||
| name: string, | ||
| index: number, | ||
| ): IMenuItemProps & { key: string; 'aria-label': string } { | ||
| return { | ||
| key: `${index}-${name}`, | ||
| icon: { | ||
| name, | ||
| xSpacing: 'both', | ||
| variables: siteVars => ({ color: siteVars.gray02 }), | ||
| }, | ||
| accessibility: ToolbarButtonBehavior, | ||
| 'aria-label': `${name} tool`, | ||
| } | ||
| } | ||
| } | ||
|
|
||
| export default ComposeMessage |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| import * as React from 'react' | ||
| import { Provider } from '@stardust-ui/react' | ||
|
|
||
| import ChatPaneLayout from './chatPaneLayout' | ||
| import { getChatMock } from './services' | ||
|
|
||
| const chatMock = getChatMock({ msgCount: 40, userCount: 6 }) | ||
|
|
||
| export default () => ( | ||
| <Provider | ||
| theme={{ | ||
| componentStyles: { | ||
| Layout: { | ||
| start: { display: 'block' }, | ||
| end: { display: 'block' }, | ||
| }, | ||
| }, | ||
| }} | ||
| > | ||
| <ChatPaneLayout chat={chatMock.chat} /> | ||
| </Provider> | ||
| ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,89 @@ | ||
| import * as _ from 'lodash' | ||
| import { lorem, random, name, internet } from 'faker' | ||
| import { IMessage, IUser, IChat, UserStatus, getTimestamp, getRandomDates } from '.' | ||
|
|
||
| export interface ChatOptions { | ||
| userCount?: number | ||
| msgCount?: number | ||
| } | ||
|
|
||
| const userStatuses: UserStatus[] = ['Available', 'Away', 'DoNotDisturb', 'Offline'] | ||
|
|
||
| class ChatMock { | ||
| private static readonly minUserCount = 2 | ||
| private static readonly defaultCount = 10 | ||
| private static readonly daysAgo = 40 | ||
| private static readonly defaultChatTitle = 'Test Chat' | ||
|
|
||
| private userIds: string[] = [] | ||
| private usersMap: Map<string, IUser> = new Map() | ||
| private chatMessages: IMessage[] = [] | ||
| public chat: IChat | ||
|
|
||
| constructor( | ||
| private options: ChatOptions = { | ||
| userCount: ChatMock.defaultCount, | ||
| msgCount: ChatMock.defaultCount, | ||
| }, | ||
| ) { | ||
| if (this.options.userCount < ChatMock.minUserCount) { | ||
| throw `[ChatMock]: A chat has a minimum of ${ChatMock.minUserCount} users` | ||
| } | ||
|
|
||
| this.userIds = _.times(this.options.userCount, random.uuid) | ||
|
|
||
| this.userIds.forEach(id => { | ||
| const firstName = name.firstName() | ||
| const lastName = name.lastName() | ||
| const user: IUser = { | ||
| id, | ||
| firstName, | ||
| lastName, | ||
| avatar: internet.avatar(), | ||
| displayName: internet.userName(firstName, lastName), | ||
| email: internet.email(firstName, lastName), | ||
| status: userStatuses[_.random(userStatuses.length - 1)], | ||
| } | ||
|
|
||
| this.usersMap.set(id, user) | ||
| }) | ||
|
|
||
| const currentUser = this.usersMap.get(this.userIds[0]) | ||
| const dates = getRandomDates(this.options.msgCount, ChatMock.daysAgo) | ||
|
|
||
| this.chatMessages = _.times(this.options.msgCount, id => { | ||
| const mine = random.boolean() | ||
| const from = (mine ? currentUser : this.getRandomUser()).id | ||
| const date = dates[id] | ||
| const timestamp = getTimestamp(date) | ||
|
|
||
| const message: IMessage = { | ||
| id, | ||
| from, | ||
| mine, | ||
| date, | ||
| content: lorem.sentences(_.random(1, 5, false)), | ||
| timestamp: timestamp.short, | ||
| timestampLong: timestamp.long, | ||
| isImportant: random.boolean(), | ||
| } | ||
|
|
||
| return message | ||
| }).sort((a, b) => a.date - b.date) | ||
|
|
||
| this.chat = { | ||
| id: random.uuid(), | ||
| currentUser, | ||
| isOneOnOne: this.usersMap.size === ChatMock.minUserCount, | ||
| messages: this.chatMessages, | ||
| members: this.usersMap, | ||
| title: ChatMock.defaultChatTitle, | ||
| } | ||
| } | ||
|
|
||
| private getRandomUser(max: number = this.usersMap.size - 1): IUser { | ||
| return this.usersMap.get(this.userIds[random.number({ max, precision: 1 })]) | ||
| } | ||
| } | ||
|
|
||
| export const getChatMock = (options?: ChatOptions) => new ChatMock(options) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.