Last active
December 22, 2016 15:57
-
-
Save haadcode/b038ce6be019e0ef841258c168b3bd53 to your computer and use it in GitHub Desktop.
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
/* 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} {props.size} ({props.hash}) </Content> | |
} | |
function Directory(props) { | |
return <Content>{props.name} {props.size} ({props.hash}) </Content> | |
} | |
function TextMessage(props) { | |
return <Content>{props.text} ({props.hash}) </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} </span> | |
} | |
function User(props) { | |
return <span style={props.style || styles.message.user}>{props.name} </span> | |
} | |
function Avatar(props) { | |
return <span style={styles.avatar}> {props.avatar} </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') | |
) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Live version: https://codepen.io/anon/pen/PbBryY?editors=0010