Skip to content

Instantly share code, notes, and snippets.

@haadcode
Last active December 22, 2016 15:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save haadcode/b038ce6be019e0ef841258c168b3bd53 to your computer and use it in GitHub Desktop.
Save haadcode/b038ce6be019e0ef841258c168b3bd53 to your computer and use it in GitHub Desktop.
/* Components for Orbit */
'use strict'
const styles = {
layout: {
flex: {
display: 'flex',
},
row: {
display: 'flex',
flexDirection: 'row',
},
column: {
display: 'flex',
flexDirection: 'column',
},
},
body: {
fontSize: '1.2em',
},
command: {
user: {
backgroundColor: 'rgb(32, 128, 32)',
fontStyle: 'italic',
fontWeight: 700,
},
content: {
backgroundColor: 'rgb(96, 196, 96)',
},
},
message: {
user: {
backgroundColor: 'rgb(32, 128, 32)',
fontStyle: 'bold',
},
content: {
backgroundColor: 'rgb(128, 228, 228)',
},
},
avatar: {
backgroundColor: 'rgb(128, 32, 32)',
alignSelf: 'flex-start',
display: 'flex',
justifyContent: 'center',
minWidth: '2.25em',
minHeight: '2.25em',
},
timestamp: {
backgroundColor: 'rgb(200, 200, 200)',
fontSize: '0.8em',
display: 'flex',
alignItems: 'center',
},
actions: {
container: {
backgroundColor: 'rgb(128, 32, 128)',
},
},
}
function DefaultCommand(props) {
return <span style={styles.command.content}><i>set <b>{props.command.replace('/', '')}</b> with <b>{props.args}</b></i></span>
}
function MeCommand(props) {
return <span style={styles.command.content}><i>{props.args[0]}</i></span>
}
function TopicCommand(props) {
return <span style={styles.command.content}><i>changed channel topic to <b>"{props.args[0]}"</b></i></span>
}
const commandRenderers = (props) => {
return {
'default': <DefaultCommand {...props}/>, // require('command/commands/default-command')
'/me': <MeCommand {...props}/>, // require('command/commands/me-command')
'/topic': <TopicCommand {...props}/>, // require('command/commands/topic-command')
}
}
function Command(props) {
return commandRenderers(props)[props.command] || commandRenderers(props).default
}
/* Message Content Renderers */
function MessageContent(props) {
switch (props.type.toLowerCase()) {
case 'file':
return <File hash={props.hash} name={props.post.name} size={props.post.size} />
case 'directory':
return <Directory hash={props.hash} name={props.post.name} size={props.post.size} />
case 'text':
return <TextMessage hash={props.hash} text={props.post.content} options={props.options} />
default:
return <div>props.post</div>
}
}
function Content(props) {
return <div style={styles.message.content}>{props.children}</div>
}
function File(props) {
return <Content>{props.name}&nbsp;{props.size}&nbsp;({props.hash})&nbsp;</Content>
}
function Directory(props) {
return <Content>{props.name}&nbsp;{props.size}&nbsp;({props.hash})&nbsp;</Content>
}
function TextMessage(props) {
return <Content>{props.text}&nbsp;({props.hash})&nbsp;</Content>
}
/* Actions Renderers */
function MessageActions(props) {
switch (props.type.toLowerCase()) {
case 'file':
return <FileActions hash={props.hash} />
case 'directory':
return <DirectoryActions hash={props.hash} />
case 'text':
default:
return <Actions hash={props.hash} />
}
}
function Actions(props) {
return (
<div style={styles.actions.container}>
{props.children}
<DefaultActions hash={props.hash} />
</div>
)
}
function DefaultActions(props) {
return (
<span>
<CopyHashButton hash={props.hash} />
<PinButton hash={props.hash} />
</span>
)
}
function FileActions(props) {
return (
<Actions>
<OpenButton hash={props.hash} />
<DownloadButton hash={props.hash} />
</Actions>
)
}
function DirectoryActions(props) {
return (
<Actions>
<OpenButton hash={props.hash} />
</Actions>
)
}
/* Button Renderers */
function CopyHashButton(props) {
return <span>Hash</span>
}
function PinButton(props) {
return <span>Pin</span>
}
function OpenButton(props) {
return <span>Open</span>
}
function DownloadButton(props) {
return <span>Download</span>
}
/* Previews */
function MessagePreview(props) {
if (!props.show)
return null
switch (props.type.toLowerCase()) {
case 'file':
return <FilePreview hash={props.hash} />
case 'directory':
return <DirectoryPreview hash={props.hash} />
default:
return <div>No Preview Renderer</div>
}
}
/* Layout */
function Row(props) {
return <div style={styles.layout.row}>{props.children}</div>
}
function Column(props) {
return <div style={styles.layout.column}>{props.children}</div>
}
/* Message Components */
function Timestamp(props) {
return <span style={styles.timestamp}>{props.ts}&nbsp;</span>
}
function User(props) {
return <span style={props.style || styles.message.user}>{props.name}&nbsp;</span>
}
function Avatar(props) {
return <span style={styles.avatar}>&nbsp;{props.avatar}&nbsp;</span>
}
/* Message Layouts */
function SmallMessageLayout(props) {
return <Row>{props.timestamp}{props.user}{props.children}{props.actions}</Row>
}
function LargeMessageLayout(props) {
return (
<Row>
<Avatar avatar={props.avatar} />
<Column>
<Row>{props.user}{props.timestamp}{props.actions}</Row>
<Row>{props.children}</Row>
</Column>
</Row>
)
}
function FeedMessageLayout(props) {
return (
<Column>
<Row>
<Avatar avatar={props.avatar} />
<Column>
{props.user}
{props.timestamp}
</Column>
</Row>
<Row>{props.children}</Row>
<Row>{props.actions}</Row>
</Column>
)
}
/* Messages */
function Message(props) {
if (props.options.feedMessages)
return <FeedMessageLayout {...props}>{props.children}</FeedMessageLayout>
if (props.options.largeMessages)
return <LargeMessageLayout {...props}>{props.children}</LargeMessageLayout>
return <SmallMessageLayout {...props}>{props.children}</SmallMessageLayout>
}
function OrbitMessage(props) {
const { hash, post, options } = props
const { type, from, ts } = post.meta
const { id, name, avatar } = from
let user = <User id={id} name={name} style={styles.message.user}/>
const timestamp = <Timestamp ts={ts} />
const actions = <MessageActions type={type} hash={hash} />
if (type === 'command') {
const { command, args } = post
user = <User id={id} name={name} style={styles.command.user}/>
return (
<Message user={user} timestamp={timestamp} avatar={avatar} actions={actions} options={options} >
<Command hash={hash} command={command} args={args} user={user}/>
</Message>
)
}
return (
<Message user={user} timestamp={timestamp} avatar={avatar} actions={actions} options={options} >
<MessageContent type={type} hash={hash} post={post} />
<MessagePreview type={type} hash={hash} />
</Message>
)
}
function MessageContainer(props) {
const messages = props.messages.map((e) => {
return <OrbitMessage hash={e.hash} post={e.payload} options={props.options} />
})
return <div style={styles.body}>{messages}</div>
}
/* DATA */
const hash1 = 'Qm...Foo1'
const post1 = {
content: 'Hello world',
meta: {
type: 'text',
from: {
id: 'Qm...Id1',
name: 'Haad',
avatar: '[H]',
},
ts: new Date().getTime(),
}
}
const hash2 = 'Qm...Foo2'
const post2 = {
name: 'README.md',
size: 123,
meta: {
type: 'file',
ts: new Date().getTime(),
from: {
id: 'Qm...Id2',
name: 'Frank',
avatar: '[F]',
},
}
}
const hash3 = 'Qm...Foo3'
const post3 = {
command: '/me',
args: ['likes the new structure'],
meta: {
type: 'command',
ts: new Date().getTime(),
from: {
id: 'Qm...Id2',
name: 'Frank',
avatar: '[F]',
},
}
}
const hash4 = 'Qm...Foo4'
const post4 = {
command: '/topic',
args: ['hello friend'],
meta: {
type: 'command',
ts: new Date().getTime(),
from: {
id: 'Qm...Id2',
name: 'Frank',
avatar: '[F]',
},
}
}
const messages = [
{
hash: hash1,
payload: post1,
},
{
hash: hash2,
payload: post2,
},
{
hash: hash3,
payload: post3,
},
{
hash: hash4,
payload: post4,
},
]
const options = {
emojis: true,
largeMessages: true,
feedMessages: true,
}
/* MAIN */
ReactDOM.render(
<MessageContainer messages={messages} options={options} />,
document.getElementById('root')
)
@haadcode
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment