1
0
mirror of https://github.com/fazo96/ipfs-boards synced 2025-01-10 12:24:20 +01:00

WIP add eslint and use material-ui

This commit is contained in:
Enrico Fasoli 2019-03-10 19:50:12 +01:00
parent e90e840a60
commit bc32ede2b5
No known key found for this signature in database
GPG Key ID: 1238873C5F27DB4D
15 changed files with 1419 additions and 578 deletions

10
.eslintrc Normal file
View File

@ -0,0 +1,10 @@
{
"extends": "airbnb",
"env": {
"browser": true
},
"parser": "babel-eslint",
"rules": {
"react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }]
}
}

916
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,8 @@
"homepage": ".",
"private": true,
"dependencies": {
"@material-ui/core": "^3.9.2",
"@material-ui/icons": "^3.0.2",
"connected-react-router": "^6.3.1",
"ipfs": "~0.33.0",
"moment": "^2.24.0",
@ -16,15 +18,19 @@
"react-router-dom": "^4.3.1",
"react-scripts": "2.1.8",
"redux": "^4.0.1",
"redux-saga": "^1.0.2",
"semantic-ui-css": "^2.4.1",
"semantic-ui-react": "^0.85.0"
"redux-saga": "^1.0.2"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build"
"build": "react-scripts build",
"lint": "eslint src"
},
"devDependencies": {
"eslint": "5.12.0",
"eslint-config-airbnb": "^17.1.0",
"eslint-plugin-import": "^2.16.0",
"eslint-plugin-jsx-a11y": "^6.2.1",
"eslint-plugin-react": "^7.12.4",
"redux-immutable-state-invariant": "^2.1.0"
},
"browserslist": [

View File

@ -4,7 +4,6 @@ import Boards from '../containers/Boards'
import OpenBoard from '../containers/OpenBoard'
import WithBoard from '../containers/WithBoard'
import BoardPage from '../components/BoardPage'
import 'semantic-ui-css/semantic.css'
class App extends Component {
render() {

View File

@ -1,108 +1,145 @@
import React from 'react'
import Post from './Post'
import { Divider, Icon, Grid, Header, List, Button, Card } from 'semantic-ui-react'
import { Link } from 'react-router-dom'
import React from 'react';
import {
Grid,
List,
ListItem,
ListItemIcon,
ListItemText,
Card,
CardHeader,
CardContent,
Divider,
Button,
CardActions,
} from '@material-ui/core';
import {
Add,
Link as LinkIcon,
Usb,
NetworkCell,
NetworkCheck,
CloudDownload,
Edit,
Assignment,
Mail,
ArrowLeft,
} from '@material-ui/icons';
import { Link } from 'react-router-dom';
import moment from 'moment';
import { shortenAddress } from '../utils/orbitdb';
import moment from 'moment'
import Post from './Post';
export default function Board({ address, posts, metadata, replicating, stats, replicationInfo, lastReplicated }) {
const { email, website, title, description } = metadata || {}
const peerCount = (stats.peers || []).length
const online = peerCount > 0
const writeable = stats.access ? (stats.access.writeable ? 'Yes' : 'No') : '?'
let replicationMessage = lastReplicated ? ('Last Activity at ' + moment(lastReplicated).format('H:mm')) : 'No Activity'
if (replicating) {
if (replicationInfo && replicationInfo.max !== undefined) {
replicationMessage = 'Progress: ' + (replicationInfo.progress || 0) + '/' + replicationInfo.max
} else {
replicationMessage = 'Initializing Transfer'
}
export default function Board({
address, posts, metadata, replicating, stats, replicationInfo, lastReplicated,
}) {
const {
email, website, title, description,
} = metadata || {};
const peerCount = (stats.peers || []).length;
const online = peerCount > 0;
const writeable = stats.access ? (stats.access.writeable ? 'Yes' : 'No') : '?';
let replicationMessage = lastReplicated ? (`Last Activity at ${moment(lastReplicated).format('H:mm')}`) : 'No Activity';
if (replicating) {
if (replicationInfo && replicationInfo.max !== undefined) {
replicationMessage = `Progress: ${replicationInfo.progress || 0}/${replicationInfo.max}`;
} else {
replicationMessage = 'Initializing Transfer';
}
return <Grid container divided colums={2}>
<Grid.Column width={8}>
<Header size='large' style={{marginTop:'.5em'}}>
<Header.Content>{title || 'Unnamed Board'}</Header.Content>
<Header.Subheader>Board</Header.Subheader>
</Header>
{ description ? <p>{description}</p> : null }
}
return (
<Grid container>
<Grid item xs="12" md="6">
<Card>
<CardHeader
title={title || 'Unnamed Board'}
subheader="Board"
/>
</Card>
<CardContent>
{ description ? <p>{description}</p> : null }
</CardContent>
<CardContent>
<List>
<ListItem>
<ListItemIcon><LinkIcon /></ListItemIcon>
<ListItemText
primary={address}
secondary="Address"
/>
</ListItem>
<ListItem>
<ListItemIcon><Usb /></ListItemIcon>
<ListItemText
primary={`${stats.opLogLength || 0} Entries`}
secondary="Size"
/>
</ListItem>
<ListItem>
<ListItemIcon><NetworkCell /></ListItemIcon>
<ListItemText
primary={online ? `${peerCount} Connections` : 'No Connections'}
secondary={online ? 'Online' : 'Offline'}
/>
</ListItem>
<ListItem>
<ListItemIcon><CloudDownload /></ListItemIcon>
<ListItemText
primary={replicationMessage}
secondary={replicating ? 'Downloading' : 'Download'}
/>
</ListItem>
<ListItem>
<ListItemIcon><Edit /></ListItemIcon>
<ListItemText
primary={writeable}
secondary="Write Access"
/>
</ListItem>
<Divider />
<List relaxed>
<List.Item>
<List.Icon name='linkify' size="large" verticalAlign="middle"/>
<List.Content>
<List.Header>Address</List.Header>
<List.Content>
{address}
</List.Content>
</List.Content>
</List.Item>
<List.Item>
<List.Icon name='disk outline' size="large" verticalAlign="middle"/>
<List.Content>
<List.Header>Size</List.Header>
<List.Content>{stats.opLogLength || 0} Entries</List.Content>
</List.Content>
</List.Item>
<List.Item>
<List.Icon name={online ? 'heart' : 'heartbeat'} size="large" verticalAlign="middle"/>
<List.Content>
<List.Header>{online ? 'Online' : 'Offline'}</List.Header>
<List.Content>{online ? peerCount + ' Connections' : 'No Connections'}</List.Content>
</List.Content>
</List.Item>
<List.Item>
<List.Icon color={replicating ? 'green' : null} name='feed' size="large" verticalAlign="middle"/>
<List.Content>
<List.Header>{replicating ? 'Downloading' : 'Download'}</List.Header>
<List.Content>{replicationMessage}</List.Content>
</List.Content>
</List.Item>
<List.Item>
<List.Icon name='edit' size="large" verticalAlign="middle"/>
<List.Content>
<List.Header>Write Access</List.Header>
<List.Content>{writeable}</List.Content>
</List.Content>
</List.Item>
<Divider/>
<List.Item>
<List.Icon name='file text outline' size="large" verticalAlign="middle"/>
<List.Content>
<List.Header>Posts</List.Header>
<List.Content>{Object.values(posts || {}).length}</List.Content>
</List.Content>
</List.Item>
<List.Item>
<List.Icon name='globe' size="large" verticalAlign="middle"/>
<List.Content>
<List.Header>Website</List.Header>
<List.Content>{website ? <a href={website} target="__blank">{website}</a> : 'N/A'}</List.Content>
</List.Content>
</List.Item>
<List.Item>
<List.Icon name='mail' size="large" verticalAlign="middle"/>
<List.Content>
<List.Header>Mail</List.Header>
<List.Content>{email ? <a href={'mailto:'+email}>{email}</a> : 'N/A'}</List.Content>
</List.Content>
</List.Item>
</List>
<div className='ui three buttons basic'>
<Button as={Link} to={'/'}>
<Icon name='left arrow'/> Boards
</Button>
<Button disabled={!writeable} as={Link} to={shortenAddress(address)+'/edit'}>
<Icon name='pencil'/> Edit
</Button>
<Button disabled={!writeable} as={Link} to={shortenAddress(address)+'/p/new'}>
<Icon name='plus'/> New Post
</Button>
</div>
</Grid.Column>
<Grid.Column width={8}>
<Card.Group className="centered" style={{marginTop:'.5em'}}>
{Object.keys(posts || {}).map(i => <Post key={posts[i].multihash} {...posts[i]}/>)}
</Card.Group>
</Grid.Column>
<ListItem>
<ListItemIcon><Assignment /></ListItemIcon>
<ListItemText
primary={Object.values(posts || {}).length}
secondary="Posts"
/>
</ListItem>
<ListItem>
<ListItemIcon><NetworkCheck /></ListItemIcon>
<ListItemText
primary={website ? <a href={website} target="__blank">{website}</a> : 'N/A'}
secondary="Website"
/>
</ListItem>
<ListItem>
<ListItemIcon><Mail /></ListItemIcon>
<ListItemText
primary={email ? <a href={`mailto:${email}`}>{email}</a> : 'N/A'}
secondary="Email"
/>
</ListItem>
</List>
</CardContent>
<CardActions>
<Button as={Link} to="/">
<ArrowLeft />
{' '}
Boards
</Button>
<Button disabled={!writeable} as={Link} to={`${shortenAddress(address)}/edit`}>
<Edit />
{' '}
Edit
</Button>
<Button disabled={!writeable} as={Link} to={`${shortenAddress(address)}/p/new`}>
<Add />
{' '}
New Post
</Button>
</CardActions>
</Grid>
<Grid xs="12" md="6">
{Object.keys(posts || {}).map(i => <Post key={posts[i].multihash} {...posts[i]} />)}
</Grid>
</Grid>
}
);
}

View File

@ -1,85 +1,81 @@
import React, { Component } from 'react'
import { Icon, Container, Card, Form, Button } from 'semantic-ui-react'
import { Link } from 'react-router-dom'
import React, { Component } from 'react';
import {
Card,
CardContent,
CardHeader,
CardActions,
TextField,
Button,
} from '@material-ui/core';
import {
Save,
ArrowLeft,
} from '@material-ui/icons';
import { Link } from 'react-router-dom';
import { shortenAddress } from '../utils/orbitdb';
export default class BoardEditorForm extends Component {
constructor(props){
super(props)
this.state = {
title: props.title || '',
website: props.website || '',
email: props.email || ''
}
}
constructor(props) {
super(props);
this.state = {
title: props.title || '',
website: props.website || '',
email: props.email || '',
};
}
render() {
const { title, website, email } = this.state
const { address, updateBoardMetadata } = this.props
return <Container>
<Card fluid centered style={{marginTop:'5em',maxWidth:'40em'}}>
<Card.Content>
<Card.Header>Edit Board</Card.Header>
<Card.Meta>
Boards is an experimental peer to peer application.<br/>
All content you publish will be public and may be lost or
changed at any time.<br/>
Please do not use this version of Boards
for anything other than testing purposes
</Card.Meta>
</Card.Content>
<Card.Content>
<Form>
<Form.Field>
<label>Title</label>
<input
value={title}
onChange={this.updateTitle.bind(this)}
/>
</Form.Field>
<Form.Group widths="equal">
<Form.Field>
<label>Website</label>
<input
value={website}
onChange={this.updateWebsite.bind(this)}
/>
</Form.Field>
<Form.Field>
<label>Email</label>
<input
value={email}
type="email"
onChange={this.updateEmail.bind(this)}
/>
</Form.Field>
</Form.Group>
<div className="ui two buttons">
<Button as={Link} to={shortenAddress(address)}>
<Icon name="arrow left"/> Back
</Button>
<Button type="submit" onClick={() => updateBoardMetadata(address, this.state)}>
<Icon name="save"/> Save
</Button>
</div>
</Form>
</Card.Content>
</Card>
</Container>
}
handleChange = name => (event) => {
this.setState({
[name]: event.target.value,
});
}
updateTitle(event) {
const title = event.target.value
this.setState({ title })
}
updateWebsite(event) {
const website = event.target.value
this.setState({ website })
}
updateEmail(event) {
const email = event.target.value
this.setState({ email })
}
}
render() {
const { title, website, email } = this.state;
const { address, updateBoardMetadata } = this.props;
return (
<Card fluid centered style={{ marginTop: '5em', maxWidth: '40em' }}>
<CardHeader>Edit Board</CardHeader>
<CardContent>
Boards is an experimental peer to peer application.
<br />
All content you publish will be public and may be lost or
changed at any time.
<br />
Please do not use this version of Boards
for anything other than testing purposes
</CardContent>
<CardContent>
<TextField
label="Title"
value={title}
onChange={this.handleChange('title')}
/>
<TextField
label="Website"
value={website}
onChange={this.handleChange('website')}
/>
<TextField
label="Email"
value={email}
type="email"
onChange={this.handleChange('email')}
/>
</CardContent>
<CardActions>
<Button as={Link} to={shortenAddress(address)}>
<ArrowLeft />
{' '}
Back
</Button>
<Button type="submit" onClick={() => updateBoardMetadata(address, this.state)}>
<Save />
{' '}
Save
</Button>
</CardActions>
</Card>
);
}
}

View File

@ -1,16 +1,20 @@
import React from 'react'
import { Switch, Route } from 'react-router-dom'
import Board from '../containers/Board'
import BoardEditor from '../containers/BoardEditor'
import PostEditor from '../containers/PostEditor'
import WithStats from '../containers/WithStats'
import React from 'react';
import { Switch, Route } from 'react-router-dom';
import Board from '../containers/Board';
import BoardEditor from '../containers/BoardEditor';
import PostEditor from '../containers/PostEditor';
import WithStats from '../containers/WithStats';
function BoardPage({ match, address, posts, metadata }) {
return <Switch>
<Route path={match.path+'p/new'} component={PostEditor} />
<Route path={match.path+'edit'} component={BoardEditor} />
<Route path={match.path} component={WithStats(Board)} />
function BoardPage({
match, address, posts, metadata,
}) {
return (
<Switch>
<Route path={`${match.path}p/new`} component={PostEditor} />
<Route path={`${match.path}edit`} component={BoardEditor} />
<Route path={match.path} component={WithStats(Board)} />
</Switch>
);
}
export default BoardPage
export default BoardPage;

View File

@ -1,73 +1,105 @@
import React from 'react'
import { List, Icon, Segment, Divider, Grid, Header, Button, Card } from 'semantic-ui-react'
import { Link } from 'react-router-dom'
import BoardsItem from './BoardsItem'
import React from 'react';
import { Link } from 'react-router-dom';
import {
Grid,
Card,
CardHeader,
CardContent,
CardActions,
List,
ListItem,
ListItemIcon,
ListItemText,
Avatar,
Button,
} from '@material-ui/core';
import {
AccountBox,
CastConnected,
Wifi,
Usb,
VerifiedUser,
Lock,
Code,
Add,
Comment,
} from '@material-ui/icons';
import BoardsItem from './BoardsItem';
export default function Boards({ stats, boards, createBoard, closeBoard }) {
return <Grid container divided colums={2}>
<Grid.Column width={8}>
<Header size='large' style={{marginTop:'.5em'}}>
<Icon name="cube" color="blue" circular/>
<Header.Content>
<Header.Content>IPFS Boards</Header.Content>
<Header.Subheader>Experimental Build</Header.Subheader>
</Header.Content>
</Header>
<Divider />
<List relaxed>
<List.Item>
<List.Icon name='leaf' size="large" verticalAlign="middle"/>
<List.Content>
<List.Header>Seeding</List.Header>
<List.Content>{Object.keys(boards).length} Boards</List.Content>
</List.Content>
</List.Item>
<List.Item>
<List.Icon name='signal' size="large" verticalAlign="middle"/>
<List.Content>
<List.Header>Connected Peers</List.Header>
<List.Content>{stats.peers.length}</List.Content>
</List.Content>
</List.Item>
<List.Item>
<List.Icon name='disk outline' size="large" verticalAlign="middle"/>
<List.Content>
<List.Header>Used Space</List.Header>
<List.Content>Not Supported Yet</List.Content>
</List.Content>
</List.Item>
<List.Item>
<List.Icon name='user circle' size="large" verticalAlign="middle"/>
<List.Content>
<List.Header>IPFS ID</List.Header>
<List.Content>{stats.id}</List.Content>
</List.Content>
</List.Item>
<List.Item>
<List.Icon name='key' size="large" verticalAlign="middle"/>
<List.Content>
<List.Header>OrbitDB Public Key</List.Header>
<List.Content style={{wordBreak:'break-all'}}>{stats.pubKey}</List.Content>
</List.Content>
</List.Item>
export default function Boards({
stats, boards, createBoard, closeBoard,
}) {
return (
<Grid>
<Grid item xs="12" md="8">
<Card>
<CardHeader
avatar={<Avatar><AccountBox /></Avatar>}
title="IPFS Boards"
subheader="Experimental Build"
/>
<CardContent>
<List>
<ListItem>
<ListItemIcon><CastConnected /></ListItemIcon>
<ListItemText
primary={Object.keys(boards).length}
secondary="Seeding"
/>
</ListItem>
<ListItem>
<ListItemIcon><Wifi /></ListItemIcon>
<ListItemText
primary={stats.peers.length}
secondary="Connected Peers"
/>
</ListItem>
<ListItem>
<ListItemIcon><Usb /></ListItemIcon>
<ListItemText
primary="Not supported yet"
secondary="Used Space"
/>
</ListItem>
<ListItem>
<ListItemIcon><VerifiedUser /></ListItemIcon>
<ListItemText
primary={stats.id}
secondary="IPFS ID"
/>
</ListItem>
<ListItem>
<ListItemIcon><Lock /></ListItemIcon>
<ListItemText
primary={stats.pubKey}
secondary="OrbitDB Public Key"
/>
</ListItem>
</List>
<div className="ui three buttons">
<Button as='a' href="https://github.com/fazo96/ipfs-boards" target="__blank" >
<Icon name="github"/> GitHub
</Button>
<Button as={Link} to={'/b/new'}>
<Icon name="plus"/> Add Board
</Button>
<Button as='a' href="https://github.com/fazo96/ipfs-boards/issues/new" target="__blank">
<Icon name="comment"/> Leave Feedback
</Button>
</div>
</Grid.Column>
<Grid.Column width={8} style={{paddingTop:'3em'}}>
<Card.Group className="centered">
{Object.values(boards).map(board => <BoardsItem key={board.address} closeBoard={closeBoard} {...board} />)}
{Object.keys(boards).length === 0 ? <Segment>No boards opened</Segment> : null}
</Card.Group>
</Grid.Column>
</CardContent>
<CardActions>
<Button as="a" href="https://github.com/fazo96/ipfs-boards" target="__blank">
<Code />
{' '}
GitHub
</Button>
<Button as={Link} to="/b/new">
<Add />
{' '}
Add Board
</Button>
<Button as="a" href="https://github.com/fazo96/ipfs-boards/issues/new" target="__blank">
<Comment />
{' '}
Leave Feedback
</Button>
</CardActions>
</Card>
</Grid>
<Grid item xs={12} md={6}>
{Object.values(boards).map(board => <BoardsItem key={board.address} closeBoard={closeBoard} {...board} />)}
{Object.keys(boards).length === 0 && 'No boards opened'}
</Grid>
</Grid>
}
);
}

View File

@ -1,43 +1,61 @@
import React from 'react'
import { Icon, List, Button, Card } from 'semantic-ui-react'
import { Link } from 'react-router-dom'
import { shortenAddress } from '../utils/orbitdb'
import React from 'react';
import {
Card,
CardContent,
CardHeader,
CardActions,
List,
ListItem,
ListItemIcon,
ListItemText,
Button,
} from '@material-ui/core';
import {
ArrowLeft,
Assignment,
} from '@material-ui/icons';
import { Link } from 'react-router-dom';
import { shortenAddress } from '../utils/orbitdb';
export default function BoardsItem({ address, metadata, name, closeBoard }) {
return <Card fluid>
<Card.Content>
<Card.Header>
{ metadata.title || 'Unnamed board' }
</Card.Header>
<Card.Meta>Board</Card.Meta>
</Card.Content>
<Card.Content>
<List>
<List.Item>
<List.Icon name="hashtag" verticalAlign="middle"/>
<List.Content>
<List.Header>Name</List.Header>
<List.Content>{name}</List.Content>
</List.Content>
</List.Item>
<List.Item>
<List.Icon name="chain" verticalAlign="middle"/>
<List.Content>
<List.Header>Address</List.Header>
<List.Content>{address}</List.Content>
</List.Content>
</List.Item>
</List>
</Card.Content>
<Card.Content>
<div className="ui two buttons">
<Button onClick={() => closeBoard(address)} basic>
<Icon name="close"/> Close
</Button>
<Button as={Link} to={shortenAddress(address)} basic>
<Icon name="list"/> View
</Button>
</div>
</Card.Content>
export default function BoardsItem({
address, metadata, name, closeBoard,
}) {
return (
<Card fluid>
<CardHeader
title={metadata.title || 'Unnamed board'}
subheader="Board"
/>
<Card.Content>
<List>
<ListItem>
<ListItemIcon name="hashtag" verticalAlign="middle" />
<ListItemText>
<List.Header>Name</List.Header>
<ListItemText>{name}</ListItemText>
</ListItemText>
</ListItem>
<ListItem>
<ListItemIcon name="chain" verticalAlign="middle" />
<ListItemText>
<List.Header>Address</List.Header>
<ListItemText>{address}</ListItemText>
</ListItemText>
</ListItem>
</List>
</Card.Content>
<CardActions>
<Button onClick={() => closeBoard(address)}>
<ArrowLeft />
{' '}
Close
</Button>
<Button as={Link} to={shortenAddress(address)}>
<Assignment />
{' '}
View
</Button>
</CardActions>
</Card>
}
);
}

View File

@ -1,55 +1,71 @@
import React, { Component } from 'react'
import { Icon, Container, Card, Form, Button } from 'semantic-ui-react'
import { Link } from 'react-router-dom'
import React, { Component } from 'react';
import {
Card,
CardHeader,
CardContent,
CardActions,
TextField,
Button,
} from '@material-ui/core';
import {
Add,
ArrowLeft,
} from '@material-ui/icons';
import { Link } from 'react-router-dom';
export default class OpenBoardForm extends Component {
constructor(props){
super(props)
this.state = {
address: props.address || ''
}
}
constructor(props) {
super(props);
this.state = {
address: props.address || '',
};
}
updateAddress(event) {
const address = event.target.value
this.setState({ address })
}
updateAddress = (event) => {
const address = event.target.value;
this.setState({ address });
}
render() {
const { address } = this.state
const { openBoard, opening } = this.props
return <Container>
<Card fluid centered style={{marginTop:'5em',maxWidth:'40em'}}>
<Card.Content>
<Card.Header>Open a Board</Card.Header>
<Card.Meta>
Boards is an experimental peer to peer application.<br/>
All content you publish will be public and may be lost or
changed at any time.<br/>
Please do not use this version of Boards
for anything other than testing purposes
</Card.Meta>
</Card.Content>
<Card.Content>
<Form loading={opening}>
<Form.Field>
<input
placeholder="Paste an existing address or write your new board ID"
value={address}
onChange={this.updateAddress.bind(this)}
/>
</Form.Field>
<div className="ui two buttons">
<Button as={Link} to={'/'}>
<Icon name="arrow left"/> Back
</Button>
<Button type="submit" onClick={() => openBoard({ address, redirect: true })}>
<Icon name="plus"/> Open
</Button>
</div>
</Form>
</Card.Content>
</Card>
</Container>
}
}
render() {
const { address } = this.state;
const { openBoard, opening } = this.props;
return (
<div style={{ display: 'flex' }}>
<Card>
<CardHeader
title="Open a Board"
/>
<CardContent>
Boards is an experimental peer to peer application.
<br />
All content you publish will be public and may be lost or
changed at any time.
<br />
Please do not use this version of Boards
for anything other than testing purposes
</CardContent>
<CardContent>
<TextField
placeholder="Paste an existing address or write your new board ID"
value={address}
onChange={this.updateAddress}
disabled={opening}
/>
</CardContent>
<CardActions>
<Button as={Link} to="/">
<ArrowLeft />
{' '}
Back
</Button>
<Button type="submit" disabled={opening} onClick={() => openBoard({ address, redirect: true })}>
<Add />
{' '}
Open
</Button>
</CardActions>
</Card>
</div>
);
}
}

View File

@ -1,40 +1,47 @@
import React from 'react'
import { List, Card } from 'semantic-ui-react'
import React from 'react';
import {
Card,
CardHeader,
CardContent,
List,
ListItem,
ListItemIcon,
ListItemText,
} from '@material-ui/core';
import { Comment, Link as LinkIcon } from '@material-ui/icons';
export default function Post({ title, multihash, pubKey }) {
return <Card fluid>
<Card.Content>
<Card.Header>
{title}
</Card.Header>
<Card.Meta>Post</Card.Meta>
</Card.Content>
<Card.Content style={{wordBreak:'break-all'}}>
<List>
<List.Item>
<List.Icon name="key" verticalAlign="middle"/>
<List.Content>
<List.Header>Signed By</List.Header>
<List.Content>{pubKey || 'Unknown'}</List.Content>
</List.Content>
</List.Item>
<List.Item>
<List.Icon name="comments" verticalAlign="middle"/>
<List.Content>
<List.Header>Comments</List.Header>
<List.Content>Not Supported Yet</List.Content>
</List.Content>
</List.Item>
<List.Item>
<List.Icon name="chain" verticalAlign="middle"/>
<List.Content>
<List.Header>Content</List.Header>
<List.Content>
<a href={'//ipfs.io/ipfs/'+multihash}>{multihash}</a>
</List.Content>
</List.Content>
</List.Item>
</List>
</Card.Content>
return (
<Card>
<CardHeader
title={title}
subheader="Post"
/>
<CardContent style={{ wordBreak: 'break-all' }}>
<List>
<ListItem>
<ListItemIcon name="key" verticalAlign="middle" />
<ListItemText
primary={pubKey || 'Unknown'}
secondary="Signed By"
/>
</ListItem>
<ListItem>
<ListItemIcon><Comment /></ListItemIcon>
<ListItemText
primary="Not supported yet"
secondary="Comments"
/>
</ListItem>
<ListItem>
<ListItemIcon><LinkIcon /></ListItemIcon>
<ListItemText
primary={<a href={`//ipfs.io/ipfs/${multihash}`}>{multihash}</a>}
secondary="Content"
/>
</ListItem>
</List>
</CardContent>
</Card>
}
);
}

View File

@ -1,71 +1,90 @@
import React, { Component } from 'react'
import { Link } from 'react-router-dom'
import { Card, Container, Form, Icon, Button } from 'semantic-ui-react'
import React, { Component } from 'react';
import {
Card,
CardContent,
CardActions,
CardHeader,
TextField,
Button,
} from '@material-ui/core';
import {
Link as LinkIcon,
Save,
ArrowLeft,
} from '@material-ui/icons';
import { Link } from 'react-router-dom';
import { shortenAddress } from '../utils/orbitdb';
export default class PostForm extends Component {
constructor(props){
super(props)
this.state = {
title: props.title || '',
content: props.content || ''
}
}
constructor(props) {
super(props);
this.state = {
title: props.title || '',
content: props.content || '',
};
}
updateTitle(event) {
this.setState({ title: event.target.value })
}
updateTitle(event) {
this.setState({ title: event.target.value });
}
updateContent(event) {
this.setState({ content: event.target.value })
}
updateContent(event) {
this.setState({ content: event.target.value });
}
render() {
const { title, content } = this.state
const { onSave, board } = this.props
const { address } = board
return <Container>
<Card fluid centered style={{marginTop:'5em',maxWidth:'40em'}}>
<Card.Content>
<Card.Header>New Post</Card.Header>
<Card.Meta>
Boards is an experimental peer to peer application.<br/>
All content you publish will be public and may be lost or
changed at any time.<br/>
Please do not use this version of Boards
for anything other than testing purposes
</Card.Meta>
</Card.Content>
<Card.Content extra>
<Icon name="chain"/> {address}
</Card.Content>
<Card.Content>
<Form>
<Form.Field>
<label>Title</label>
<input
placeholder="What's this about?"
value={title}
onChange={this.updateTitle.bind(this)}
/>
</Form.Field>
<Form.Field>
<label>Content</label>
<input
placeholder='Write your thoughts'
value={content}
onChange={this.updateContent.bind(this)}
/>
</Form.Field>
<Button as={Link} to={shortenAddress(address)}>
<Icon name="chevron left"/> Board
</Button>
<Button type='submit' onClick={() => onSave({ title, text: content })}>
<Icon name="save"/> Submit
</Button>
</Form>
</Card.Content>
</Card>
</Container>
}
}
render() {
const { title, content } = this.state;
const { onSave, board } = this.props;
const { address } = board;
return (
<div style={{ display: 'flex' }}>
<Card fluid centered style={{ marginTop: '5em', maxWidth: '40em' }}>
<CardHeader
title="New Post"
/>
<CardContent>
Boards is an experimental peer to peer application.
<br />
All content you publish will be public and may be lost or
changed at any time.
<br />
Please do not use this version of Boards
for anything other than testing purposes
</CardContent>
<CardContent>
<LinkIcon />
{' '}
{address}
</CardContent>
<CardContent>
<TextField
label="Title"
placeholder="What's this about?"
value={title}
onChange={this.updateTitle}
/>
<TextField
label="Content"
placeholder="Write your thoughts"
value={content}
onChange={this.updateContent}
/>
</CardContent>
<CardActions>
<Button as={Link} to={shortenAddress(address)}>
<ArrowLeft />
{' '}
Board
</Button>
<Button type="submit" onClick={() => onSave({ title, text: content })}>
<Save />
{' '}
Submit
</Button>
</CardActions>
</Card>
</div>
);
}
}

View File

@ -1,6 +1,6 @@
import React from 'react'
import { connect } from 'react-redux'
import { push } from 'react-router-redux'
import { push } from 'connected-react-router'
import BoardsComponent from '../components/Boards'
import WithStats from './WithStats'
import { closeBoard } from '../actions/board'

View File

@ -1,5 +1,4 @@
import React, { Component } from 'react'
import { Dimmer } from 'semantic-ui-react'
import { connect } from 'react-redux'
import { openBoard } from '../actions/board'
import { getBoardAddress } from '../utils/orbitdb'
@ -41,9 +40,7 @@ export default function WithBoard(WrappedComponent) {
if (board) {
return <WrappedComponent {...board} {...this.props} />
} else {
return <Dimmer page active={true}>
Opening this board
</Dimmer>
return "Opening this board"
}
}
}

View File

@ -1,6 +1,6 @@
import { put, call, fork, take } from 'redux-saga/effects'
import { eventChannel } from 'redux-saga'
import { push } from 'react-router-redux'
import { push } from 'connected-react-router'
import { open, connectDb } from '../orbitdb'
import { createdBoard } from '../actions/board'
import { shortenAddress, closeBoard as closeOrbitDBBoard } from '../utils/orbitdb'