1
0
mirror of https://github.com/fazo96/ipfs-boards synced 2025-01-09 12:19:49 +01:00

UI Improvements

This commit is contained in:
Enrico Fasoli 2018-02-07 23:00:50 +01:00
parent 1a91c3e679
commit 443cef55a5
No known key found for this signature in database
GPG Key ID: 1238873C5F27DB4D
11 changed files with 149 additions and 55 deletions

View File

@ -9,4 +9,5 @@ export const UPDATE_BOARD = 'UPDATE_BOARD'
export const BOARD_ERROR = 'BOARD_ERROR'
export const ORBITDB_WRITE = 'ORBITDB_WRITE'
export const ORBITDB_REPLICATE = 'ORBITDB_REPLICATE'
export const ORBITDB_REPLICATED = 'ORBITDB_REPLICATED'

View File

@ -4,7 +4,7 @@ import { Divider, Icon, Grid, Segment, Header, List, Button, Card } from 'semant
import { Link } from 'react-router-dom'
import { shortenAddress } from '../utils/orbitdb';
export default function Board({ address, posts, metadata }) {
export default function Board({ address, posts, metadata, replicating }) {
const { email, website, title } = metadata || {}
const url = window.location.href
return <Grid container divided colums={2}>
@ -39,10 +39,10 @@ export default function Board({ address, posts, metadata }) {
</List.Content>
</List.Item>
<List.Item>
<List.Icon name='wifi' size="large" verticalAlign="middle"/>
<List.Icon color={replicating ? 'green' : null} name='wifi' size="large" verticalAlign="middle"/>
<List.Content>
<List.Header>Replication Status</List.Header>
<List.Content>Idle</List.Content>
<List.Header>Replication</List.Header>
<List.Content>{replicating ? 'Receiving Content...' : 'Idle'}</List.Content>
</List.Content>
</List.Item>
<List.Item>
@ -60,9 +60,16 @@ export default function Board({ address, posts, metadata }) {
</List.Content>
</List.Item>
</List>
<div className='ui two buttons'>
<Button>Edit</Button>
<Button as={Link} to={shortenAddress(address)+'/p/new'}>New Post</Button>
<div className='ui three buttons basic'>
<Button>
<Icon name='left arrow'/> Boards
</Button>
<Button>
<Icon name='pencil'/> Edit
</Button>
<Button as={Link} to={shortenAddress(address)+'/p/new'}>
<Icon name='plus'/> New Post
</Button>
</div>
</Grid.Column>
<Grid.Column width={8}>

View File

@ -1,5 +1,7 @@
import React, { Component } from 'react'
import { Form, Button } from 'semantic-ui-react'
import { Redirect } from 'react-router-dom'
import { Container, Card, Form, Button } from 'semantic-ui-react'
import { shortenAddress } from '../utils/orbitdb'
export default class BoardForm extends Component {
constructor(props){
@ -16,22 +18,32 @@ export default class BoardForm extends Component {
render() {
const { address } = this.state
const { onSave, creating } = this.props
return <Form>
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>
<label>Address</label>
<input
placeholder="Paste an existing address or write your new board ID"
value={address}
onChange={this.updateAddress.bind(this)}
/>
</Form.Field>
<Button
type='submit'
onClick={() => onSave({ address })}
disabled={creating}
>Create</Button>
{creating ? 'Creating the board...' : ''}
<Button fluid onClick={() => openBoard({ address })}>Open</Button>
</Form>
</Card.Content>
</Card>
</Container>
}
}

View File

@ -1,12 +1,67 @@
import React from 'react'
import { Button, Card } from 'semantic-ui-react'
import { List, Icon, Segment, Divider, Grid, Header, Button, Card } from 'semantic-ui-react'
import { Link } from 'react-router-dom'
import BoardsItem from './BoardsItem'
export default function Boards({ boards, createBoard }) {
return <div>
<Card.Group>
{Object.values(boards).map(board => <BoardsItem key={board.address} {...board} />)}
</Card.Group>
<Button onClick={createBoard}>New Board</Button>
return <Grid container divided colums={2}>
<Grid.Column width={8}>
<Header size='large' style={{marginTop:'.5em'}}>
<Header.Content>IPFS Boards</Header.Content>
<Header.Subheader>Experimental Build</Header.Subheader>
</Header>
<Divider />
<List relaxed>
<List.Item>
<List.Icon name='file text outline' size="large" verticalAlign="middle"/>
<List.Content>
<List.Header>Boards</List.Header>
<List.Content>{Object.keys(boards).length}</List.Content>
</List.Content>
</List.Item>
<List.Item>
<List.Icon name='wifi' size="large" verticalAlign="middle"/>
<List.Content>
<List.Header>Connected Peers</List.Header>
<List.Content>?</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>?</List.Content>
</List.Content>
</List.Item>
<List.Item>
<List.Icon name='user' size="large" verticalAlign="middle"/>
<List.Content>
<List.Header>IPFS ID</List.Header>
<List.Content>?</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>?</List.Content>
</List.Content>
</List.Item>
</List>
<div className="ui two buttons">
<Button as='a' href="https://github.com/fazo96/ipfs-boards">
<Icon name="github"/> GitHub
</Button>
<Button as={Link} to={'/b/new'}>
Open or Create Board
</Button>
</div>
</Grid.Column>
<Grid.Column width={8} style={{paddingTop:'3em'}}>
<Card.Group className="centered">
{Object.values(boards).map(board => <BoardsItem key={board.address} {...board} />)}
{Object.keys(boards).length === 0 ? <Segment>No boards opened</Segment> : null}
</Card.Group>
</Grid.Column>
</Grid>
}

View File

@ -4,14 +4,16 @@ import { Link } from 'react-router-dom'
import { shortenAddress } from '../utils/orbitdb'
export default function BoardsItem({ address, title }) {
return <Card>
return <Card fluid>
<Card.Content>
<Card.Header>
{ title || 'Untitled board' }
{ title || 'Unnamed board' }
</Card.Header>
<Card.Meta>
Board
</Card.Meta>
</Card.Content>
<Card.Content>
<Card.Description style={{wordBreak:'break-all'}}>
{address}
</Card.Description>

View File

@ -4,7 +4,10 @@ import { Card, Icon } from 'semantic-ui-react'
export default function Post({ title, multihash}) {
return <Card fluid>
<Card.Content>
<Icon name="file text outline"/> {title}
<Card.Header>
{title}
</Card.Header>
<Card.Meta>Post</Card.Meta>
</Card.Content>
<Card.Content style={{wordBreak:'break-all'}}>
<Icon name="chain"/> <a href={'//ipfs.io/ipfs/'+multihash}>View</a>

View File

@ -3,13 +3,13 @@ import { connect } from 'react-redux'
import BoardForm from '../components/BoardForm'
import { openBoard } from '../actions/board'
function BoardEditor({ board, openBoard }) {
return <BoardForm board={board} onSave={openBoard} />
function BoardEditor(props) {
return <BoardForm {...props} />
}
function mapStateToProps(state){
return {
board: state.boardEditor.board
opening: state.boardEditor.opening
}
}

View File

@ -5,19 +5,16 @@ import {
function getInitialState() {
return {
board: {
name: ''
},
creating: false
opening: false
}
}
export default function BoardEditorReducer(state = getInitialState(), action) {
switch (action.type) {
case OPEN_BOARD:
return Object.assign({}, state, { board: action.board, opening: true })
return Object.assign({}, state, { opening: true })
case OPENED_BOARD:
return Object.assign({}, state, { opening: false, board: action.board })
return Object.assign({}, state, { opening: false })
default:
return state
}

View File

@ -1,4 +1,4 @@
import { OPENED_BOARD, UPDATE_BOARD } from '../actions/actionTypes'
import { OPENED_BOARD, UPDATE_BOARD, ORBITDB_REPLICATED, ORBITDB_REPLICATE } from '../actions/actionTypes'
import { getBoardIdFromAddress } from '../utils/orbitdb'
function getInitialState() {
@ -7,20 +7,32 @@ function getInitialState() {
}
}
function updateBoard(existingBoards, address, value) {
return Object.assign({}, existingBoards, {
[address]: Object.assign({}, existingBoards[address] || {}, value)
})
}
export default function BoardsReducer(state = getInitialState(), action) {
let address, newBoards
let address
switch (action.type) {
case OPENED_BOARD:
address = action.board.address
newBoards = Object.assign({}, state.boards, { [address]: action.board })
return Object.assign({}, state, { boards: newBoards })
return Object.assign({}, state, { boards: updateBoard(state.boards, address, action.board) })
case UPDATE_BOARD:
address = action.address
let { posts, metadata } = action
newBoards = Object.assign({}, state.boards, {
[address]: Object.assign({}, state.boards[address], { posts, metadata })
})
return Object.assign({}, state, { boards: newBoards })
return Object.assign({}, state, { boards: updateBoard(state.boards, address, { posts, metadata })})
case ORBITDB_REPLICATE:
address = action.address
return Object.assign({}, state, { boards: updateBoard(state.boards, address, {
replicating: true
})})
case ORBITDB_REPLICATED:
address = action.address
return Object.assign({}, state, { boards: updateBoard(state.boards, address, {
replicating: false
})})
default:
return state;
}

View File

@ -3,9 +3,13 @@ import { eventChannel } from 'redux-saga'
import { push } from 'react-router-redux'
import { open, connectDb } from '../orbitdb'
import { creatingBoard, createdBoard, boardError } from '../actions/board'
import { getBoardIdFromAddress } from '../utils/orbitdb'
import { getBoardIdFromAddress, shortenAddress } from '../utils/orbitdb'
import { UPDATE_BOARD } from '../actions/actionTypes'
export function* goToBoard({ board }){
yield put(push(shortenAddress(board.address)))
}
export function* updateBoard({ address }){
const db = window.dbs[address]
yield put({

View File

@ -1,10 +1,11 @@
import { takeEvery } from 'redux-saga/effects'
import { OPEN_BOARD, ADD_POST, ORBITDB_REPLICATED, ORBITDB_WRITE } from '../actions/actionTypes'
import { openBoard, updateBoard } from './boards'
import { OPEN_BOARD, OPENED_BOARD, ADD_POST, ORBITDB_REPLICATED, ORBITDB_WRITE } from '../actions/actionTypes'
import { openBoard, updateBoard, goToBoard } from './boards'
import { addPost } from './posts'
export default function* saga(){
yield takeEvery(OPEN_BOARD, openBoard)
yield takeEvery(OPENED_BOARD, goToBoard)
yield takeEvery(ADD_POST, addPost)
yield takeEvery(ORBITDB_WRITE, updateBoard)
yield takeEvery(ORBITDB_REPLICATED, updateBoard)