mirror of
https://github.com/fazo96/ipfs-boards
synced 2025-01-10 12:24:20 +01:00
WIP prototype
This commit is contained in:
parent
7483c683a4
commit
502244dbe1
@ -1,9 +1,8 @@
|
|||||||
|
|
||||||
export const ADD_POST = 'ADD_POST'
|
export const ADD_POST = 'ADD_POST'
|
||||||
|
|
||||||
export const CREATE_BOARD = 'CREATE_BOARD'
|
export const OPEN_BOARD = 'OPEN_BOARD'
|
||||||
export const CREATING_BOARD = 'CREATING_BOARD'
|
export const OPENED_BOARD = 'OPENED_BOARD'
|
||||||
export const CREATED_BOARD = 'CREATED_BOARD'
|
|
||||||
|
|
||||||
export const UPDATE_BOARD = 'UPDATE_BOARD'
|
export const UPDATE_BOARD = 'UPDATE_BOARD'
|
||||||
|
|
||||||
|
@ -1,27 +1,19 @@
|
|||||||
import {
|
import {
|
||||||
CREATE_BOARD,
|
OPEN_BOARD,
|
||||||
CREATING_BOARD,
|
OPENED_BOARD,
|
||||||
CREATED_BOARD,
|
|
||||||
BOARD_ERROR
|
BOARD_ERROR
|
||||||
} from './actionTypes'
|
} from './actionTypes'
|
||||||
|
|
||||||
export function createBoard(board) {
|
export function openBoard(board) {
|
||||||
return {
|
return {
|
||||||
type: CREATE_BOARD,
|
type: OPEN_BOARD,
|
||||||
board
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function creatingBoard(board) {
|
|
||||||
return {
|
|
||||||
type: CREATING_BOARD,
|
|
||||||
board
|
board
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createdBoard(board) {
|
export function createdBoard(board) {
|
||||||
return {
|
return {
|
||||||
type: CREATED_BOARD,
|
type: OPENED_BOARD,
|
||||||
board
|
board
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { ADD_POST } from './actionTypes'
|
import { ADD_POST } from './actionTypes'
|
||||||
|
|
||||||
export function addPost(boardId, post) {
|
export function addPost(address, post) {
|
||||||
return {
|
return {
|
||||||
type: ADD_POST,
|
type: ADD_POST,
|
||||||
post,
|
post,
|
||||||
boardId
|
address
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,9 +1,9 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { Switch, Route, withRouter } from 'react-router-dom'
|
import { Switch, Route, withRouter } from 'react-router-dom'
|
||||||
import Boards from '../containers/Boards'
|
import Boards from '../containers/Boards'
|
||||||
import PostEditor from '../containers/PostEditor'
|
|
||||||
import BoardEditor from '../containers/BoardEditor'
|
import BoardEditor from '../containers/BoardEditor'
|
||||||
import Board from '../containers/Board'
|
import WithBoard from '../containers/WithBoard'
|
||||||
|
import BoardPage from '../components/BoardPage'
|
||||||
import 'semantic-ui-css/semantic.css'
|
import 'semantic-ui-css/semantic.css'
|
||||||
|
|
||||||
class App extends Component {
|
class App extends Component {
|
||||||
@ -11,8 +11,7 @@ class App extends Component {
|
|||||||
return (
|
return (
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route path='/b/new' component={BoardEditor} />
|
<Route path='/b/new' component={BoardEditor} />
|
||||||
<Route path='/b/:boardId/p/new' component={PostEditor} />
|
<Route path='/b/:hash/:name/' component={withRouter(WithBoard(BoardPage))} />
|
||||||
<Route path='/b/:boardId' component={Board} />
|
|
||||||
<Route path='/' component={Boards} />
|
<Route path='/' component={Boards} />
|
||||||
</Switch>
|
</Switch>
|
||||||
)
|
)
|
||||||
|
@ -2,13 +2,14 @@ import React from 'react'
|
|||||||
import Post from './Post'
|
import Post from './Post'
|
||||||
import { Segment, Button } from 'semantic-ui-react'
|
import { Segment, Button } from 'semantic-ui-react'
|
||||||
import { Link } from 'react-router-dom'
|
import { Link } from 'react-router-dom'
|
||||||
|
import { shortenAddress } from '../utils/orbitdb';
|
||||||
|
|
||||||
export default function Board({ id, posts }) {
|
export default function Board({ address, posts }) {
|
||||||
return <div>
|
return <div>
|
||||||
<Segment>{id}</Segment>
|
<Segment>{address}</Segment>
|
||||||
<Segment><Button as={Link} to={'p/new'}>New Post</Button></Segment>
|
<Segment><Button as={Link} to={shortenAddress(address)+'/p/new'}>New Post</Button></Segment>
|
||||||
<Segment>
|
<Segment>
|
||||||
<ul>{Object.keys(posts).map(i => <Post key={posts[i].multihash} {...posts[i]}/>)}</ul>
|
<ul>{Object.keys(posts || {}).map(i => <Post key={posts[i].multihash} {...posts[i]}/>)}</ul>
|
||||||
</Segment>
|
</Segment>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
@ -5,29 +5,30 @@ export default class BoardForm extends Component {
|
|||||||
constructor(props){
|
constructor(props){
|
||||||
super(props)
|
super(props)
|
||||||
this.state = {
|
this.state = {
|
||||||
title: props.title || ''
|
address: props.address || ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateTitle(event) {
|
updateAddress(event) {
|
||||||
this.setState({ title: event.target.value })
|
const address = event.target.value
|
||||||
|
this.setState({ address })
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { title, content } = this.state
|
const { address } = this.state
|
||||||
const { onSave, creating } = this.props
|
const { onSave, creating } = this.props
|
||||||
return <Form>
|
return <Form>
|
||||||
<Form.Field>
|
<Form.Field>
|
||||||
<label>Title</label>
|
<label>Address</label>
|
||||||
<input
|
<input
|
||||||
placeholder="What's this board about?"
|
placeholder="Paste an existing address or write your new board ID"
|
||||||
value={title}
|
value={address}
|
||||||
onChange={this.updateTitle.bind(this)}
|
onChange={this.updateAddress.bind(this)}
|
||||||
/>
|
/>
|
||||||
</Form.Field>
|
</Form.Field>
|
||||||
<Button
|
<Button
|
||||||
type='submit'
|
type='submit'
|
||||||
onClick={() => onSave({ title, content })}
|
onClick={() => onSave({ address })}
|
||||||
disabled={creating}
|
disabled={creating}
|
||||||
>Create</Button>
|
>Create</Button>
|
||||||
{creating ? 'Creating the board...' : ''}
|
{creating ? 'Creating the board...' : ''}
|
||||||
|
13
src/components/BoardPage.js
Normal file
13
src/components/BoardPage.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { Switch, Route } from 'react-router-dom'
|
||||||
|
import Board from '../containers/Board'
|
||||||
|
import PostEditor from '../containers/PostEditor'
|
||||||
|
|
||||||
|
function BoardPage({ match, address, posts, metadata }) {
|
||||||
|
return <Switch>
|
||||||
|
<Route path={match.path+'p/new'} component={PostEditor} />
|
||||||
|
<Route path={match.path} component={Board} />
|
||||||
|
</Switch>
|
||||||
|
}
|
||||||
|
|
||||||
|
export default BoardPage
|
@ -1,11 +1,12 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { List } from 'semantic-ui-react'
|
import { Button, Card } from 'semantic-ui-react'
|
||||||
import BoardsItem from './BoardsItem'
|
import BoardsItem from './BoardsItem'
|
||||||
import { Button } from 'semantic-ui-react'
|
|
||||||
|
|
||||||
export default function Boards({ boards, createBoard }) {
|
export default function Boards({ boards, createBoard }) {
|
||||||
return <List divided relaxed>
|
return <div>
|
||||||
{Object.values(boards).map(board => <BoardsItem key={board.id} {...board} />)}
|
<Card.Group>
|
||||||
|
{Object.values(boards).map(board => <BoardsItem key={board.address} {...board} />)}
|
||||||
|
</Card.Group>
|
||||||
<Button onClick={createBoard}>New Board</Button>
|
<Button onClick={createBoard}>New Board</Button>
|
||||||
</List>
|
</div>
|
||||||
}
|
}
|
@ -1,13 +1,23 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { List } from 'semantic-ui-react'
|
import { Button, Card } from 'semantic-ui-react'
|
||||||
import { Link } from 'react-router-dom'
|
import { Link } from 'react-router-dom'
|
||||||
|
import { shortenAddress } from '../utils/orbitdb'
|
||||||
|
|
||||||
export default function BoardsItem({ id, title }) {
|
export default function BoardsItem({ address, title }) {
|
||||||
return <List.Item as={Link} to={'/b/'+id+'/'}>
|
return <Card>
|
||||||
<List.Icon name='comments' size='large' verticalAlign='middle' />
|
<Card.Content>
|
||||||
<List.Content>
|
<Card.Header>
|
||||||
<List.Header>{title}</List.Header>
|
{ title || 'Untitled board' }
|
||||||
<List.Description>Experimental</List.Description>
|
</Card.Header>
|
||||||
</List.Content>
|
<Card.Meta>
|
||||||
</List.Item>
|
Board
|
||||||
|
</Card.Meta>
|
||||||
|
<Card.Description style={{wordBreak:'break-all'}}>
|
||||||
|
{address}
|
||||||
|
</Card.Description>
|
||||||
|
</Card.Content>
|
||||||
|
<Card.Content extra>
|
||||||
|
<Button as={Link} to={shortenAddress(address)} basic fluid>View</Button>
|
||||||
|
</Card.Content>
|
||||||
|
</Card>
|
||||||
}
|
}
|
@ -1,28 +1,11 @@
|
|||||||
import React, { Component } from 'react'
|
import React from 'react'
|
||||||
import { connect } from 'react-redux'
|
import { connect } from 'react-redux'
|
||||||
import { push } from 'react-router-redux'
|
|
||||||
import BoardComponent from '../components/Board'
|
import BoardComponent from '../components/Board'
|
||||||
import { createBoard } from '../actions/board'
|
import { getBoardAddress } from '../utils/orbitdb'
|
||||||
|
|
||||||
class Board extends Component {
|
function Board({ location, match, boards }) {
|
||||||
|
const { hash, name } = match.params
|
||||||
componentDidMount() {
|
return <BoardComponent {...boards[getBoardAddress(hash, name)]} />
|
||||||
const { boards, match } = this.props
|
|
||||||
if (!boards[match.params.boardId]) {
|
|
||||||
this.props.openBoard(match.params.boardId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { boards, match } = this.props
|
|
||||||
const id = match.params.boardId
|
|
||||||
const board = boards[id]
|
|
||||||
if (board) {
|
|
||||||
return <BoardComponent {...board} />
|
|
||||||
} else {
|
|
||||||
return <div>Opening this board...</div>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapStateToProps(state){
|
function mapStateToProps(state){
|
||||||
@ -31,13 +14,6 @@ function mapStateToProps(state){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapDispatchToProps(dispatch){
|
|
||||||
return {
|
|
||||||
openBoard: id => dispatch(createBoard(id))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default connect(
|
export default connect(
|
||||||
mapStateToProps,
|
mapStateToProps
|
||||||
mapDispatchToProps
|
|
||||||
)(Board)
|
)(Board)
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { connect } from 'react-redux'
|
import { connect } from 'react-redux'
|
||||||
import BoardForm from '../components/BoardForm'
|
import BoardForm from '../components/BoardForm'
|
||||||
import { createBoard } from '../actions/board'
|
import { openBoard } from '../actions/board'
|
||||||
|
|
||||||
function BoardEditor({ board, createBoard }) {
|
function BoardEditor({ board, openBoard }) {
|
||||||
return <BoardForm board={board} onSave={createBoard} />
|
return <BoardForm board={board} onSave={openBoard} />
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapStateToProps(state){
|
function mapStateToProps(state){
|
||||||
@ -15,7 +15,7 @@ function mapStateToProps(state){
|
|||||||
|
|
||||||
function mapDispatchToProps(dispatch) {
|
function mapDispatchToProps(dispatch) {
|
||||||
return {
|
return {
|
||||||
createBoard: board => dispatch(createBoard(board))
|
openBoard: board => dispatch(openBoard(board))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,12 +2,13 @@ import React, { Component } from 'react'
|
|||||||
import { connect } from 'react-redux'
|
import { connect } from 'react-redux'
|
||||||
import PostForm from '../components/PostForm'
|
import PostForm from '../components/PostForm'
|
||||||
import { addPost } from '../actions/post'
|
import { addPost } from '../actions/post'
|
||||||
|
import { getBoardAddress } from '../utils/orbitdb';
|
||||||
|
|
||||||
class PostEditor extends Component {
|
class PostEditor extends Component {
|
||||||
render() {
|
render() {
|
||||||
const { post, addPost, match } = this.props
|
const { post, addPost, match } = this.props
|
||||||
const { boardId } = match.params
|
const address = getBoardAddress(match.params.hash, match.params.name)
|
||||||
return <PostForm post={post} onSave={p => addPost(boardId, p)} />
|
return <PostForm post={post} onSave={p => addPost(address, p)} />
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -19,7 +20,7 @@ function mapStateToProps(state){
|
|||||||
|
|
||||||
function mapDispatchToProps(dispatch) {
|
function mapDispatchToProps(dispatch) {
|
||||||
return {
|
return {
|
||||||
addPost: (boardId, post) => dispatch(addPost(boardId, post))
|
addPost: (address, post) => dispatch(addPost(address, post))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
53
src/containers/WithBoard.js
Normal file
53
src/containers/WithBoard.js
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import React, { Component } from 'react'
|
||||||
|
import { connect } from 'react-redux'
|
||||||
|
import { openBoard } from '../actions/board'
|
||||||
|
import { getBoardAddress } from '../utils/orbitdb'
|
||||||
|
|
||||||
|
function mapStateToProps(state){
|
||||||
|
return {
|
||||||
|
boards: state.boards.boards
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapDispatchToProps(dispatch){
|
||||||
|
return {
|
||||||
|
openBoard: address => dispatch(openBoard({ address }))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function WithBoard(WrappedComponent) {
|
||||||
|
class ToExport extends Component {
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
const { boards, match } = this.props
|
||||||
|
const address = getBoardAddress(match.params.hash, match.params.name)
|
||||||
|
if (!boards[address]) {
|
||||||
|
this.props.openBoard(address)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillReceiveProps({ match, boards }) {
|
||||||
|
const address = getBoardAddress(match.params.hash, match.params.name)
|
||||||
|
if (!boards[address]) {
|
||||||
|
this.props.openBoard(address)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { boards, match } = this.props
|
||||||
|
const address = getBoardAddress(match.params.hash, match.params.name)
|
||||||
|
const board = boards[address]
|
||||||
|
if (board) {
|
||||||
|
return <WrappedComponent {...board} {...this.props} />
|
||||||
|
} else {
|
||||||
|
return <div>Opening this board...</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)(ToExport)
|
||||||
|
|
||||||
|
}
|
@ -11,7 +11,7 @@ export function isValidID(id) {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function open(id, metadata, options = {}) {
|
export async function open(address, metadata) {
|
||||||
if (!window.ipfs) {
|
if (!window.ipfs) {
|
||||||
const IPFS = await import('ipfs')
|
const IPFS = await import('ipfs')
|
||||||
window.ipfs = new IPFS({
|
window.ipfs = new IPFS({
|
||||||
@ -38,24 +38,18 @@ export async function open(id, metadata, options = {}) {
|
|||||||
OrbitDB.addDatabaseType(BoardStore.type, BoardStore)
|
OrbitDB.addDatabaseType(BoardStore.type, BoardStore)
|
||||||
window.orbitDb = new OrbitDB(window.ipfs)
|
window.orbitDb = new OrbitDB(window.ipfs)
|
||||||
}
|
}
|
||||||
const defaultOptions = {
|
const options = {
|
||||||
create: id === undefined,
|
type: BoardStore.type,
|
||||||
type: BoardStore.type
|
create: true
|
||||||
}
|
|
||||||
let address
|
|
||||||
if (!id) {
|
|
||||||
address = 'board-v0'
|
|
||||||
} else if (!isValidID(id)) {
|
|
||||||
throw new Error('invalid address')
|
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const db = await window.orbitDb.open(address, Object.assign(defaultOptions, options))
|
const db = await window.orbitDb.open(address, options)
|
||||||
await db.load()
|
await db.load()
|
||||||
if (metadata && defaultOptions.create) {
|
if (metadata) {
|
||||||
await db.updateMetadata(metadata)
|
await db.updateMetadata(metadata)
|
||||||
}
|
}
|
||||||
if (!window.dbs) window.dbs = {}
|
if (!window.dbs) window.dbs = {}
|
||||||
window.dbs[getBoardIdFromAddress(db.address.toString())] = db
|
window.dbs[db.address.toString()] = db
|
||||||
return db
|
return db
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error)
|
console.log(error)
|
||||||
@ -66,7 +60,7 @@ export function connectDb(db, dispatch) {
|
|||||||
db.events.on('write', (dbname, hash, entry) => {
|
db.events.on('write', (dbname, hash, entry) => {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: 'ORBITDB_WRITE',
|
type: 'ORBITDB_WRITE',
|
||||||
id: getBoardIdFromAddress(db.address.toString()),
|
address: db.address.toString(),
|
||||||
hash,
|
hash,
|
||||||
entry
|
entry
|
||||||
})
|
})
|
||||||
@ -74,13 +68,13 @@ export function connectDb(db, dispatch) {
|
|||||||
db.events.on('replicated', address => {
|
db.events.on('replicated', address => {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: 'ORBITDB_REPLICATED',
|
type: 'ORBITDB_REPLICATED',
|
||||||
id: getBoardIdFromAddress(db.address.toString())
|
address: db.address.toString()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
db.events.on('replicate.progress', (address, hash, entry, progress, have) => {
|
db.events.on('replicate.progress', (address, hash, entry, progress, have) => {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: 'ORBITDB_REPLICATE_PROGRESS',
|
type: 'ORBITDB_REPLICATE_PROGRESS',
|
||||||
id: getBoardIdFromAddress(db.address.toString()),
|
address: db.address.toString(),
|
||||||
hash,
|
hash,
|
||||||
entry,
|
entry,
|
||||||
progress,
|
progress,
|
||||||
@ -90,25 +84,25 @@ export function connectDb(db, dispatch) {
|
|||||||
db.events.on('replicate', address => {
|
db.events.on('replicate', address => {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: 'ORBITDB_REPLICATE',
|
type: 'ORBITDB_REPLICATE',
|
||||||
id: getBoardIdFromAddress(db.address.toString())
|
address: db.address.toString()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
db.events.on('close', address => {
|
db.events.on('close', address => {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: 'ORBITDB_CLOSE',
|
type: 'ORBITDB_CLOSE',
|
||||||
id: getBoardIdFromAddress(db.address.toString())
|
address: db.address.toString()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
db.events.on('load', address => {
|
db.events.on('load', address => {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: 'ORBITDB_LOAD',
|
type: 'ORBITDB_LOAD',
|
||||||
id: getBoardIdFromAddress(db.address.toString())
|
address: db.address.toString()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
db.events.on('load.progress', (address, hash, entry, progress, total) => {
|
db.events.on('load.progress', (address, hash, entry, progress, total) => {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: 'ORBITDB_LOAD_PROGRESS',
|
type: 'ORBITDB_LOAD_PROGRESS',
|
||||||
id: getBoardIdFromAddress(db.address.toString()),
|
address: db.address.toString(),
|
||||||
hash,
|
hash,
|
||||||
entry,
|
entry,
|
||||||
progress,
|
progress,
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
import {
|
import {
|
||||||
CREATE_BOARD,
|
OPEN_BOARD,
|
||||||
CREATING_BOARD,
|
OPENED_BOARD
|
||||||
CREATED_BOARD
|
|
||||||
} from '../actions/actionTypes'
|
} from '../actions/actionTypes'
|
||||||
|
|
||||||
function getInitialState() {
|
function getInitialState() {
|
||||||
return {
|
return {
|
||||||
board: {
|
board: {
|
||||||
title: ''
|
name: ''
|
||||||
},
|
},
|
||||||
creating: false
|
creating: false
|
||||||
}
|
}
|
||||||
@ -15,12 +14,10 @@ function getInitialState() {
|
|||||||
|
|
||||||
export default function BoardEditorReducer(state = getInitialState(), action) {
|
export default function BoardEditorReducer(state = getInitialState(), action) {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case CREATE_BOARD:
|
case OPEN_BOARD:
|
||||||
return Object.assign({}, state, { board: action.board, creating: false })
|
return Object.assign({}, state, { board: action.board, opening: true })
|
||||||
case CREATING_BOARD:
|
case OPENED_BOARD:
|
||||||
return Object.assign({}, state, { creating: true })
|
return Object.assign({}, state, { opening: false, board: action.board })
|
||||||
case CREATED_BOARD:
|
|
||||||
return Object.assign({}, state, { creating: false })
|
|
||||||
default:
|
default:
|
||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { CREATED_BOARD, UPDATE_BOARD } from '../actions/actionTypes'
|
import { OPENED_BOARD, UPDATE_BOARD } from '../actions/actionTypes'
|
||||||
import { getBoardIdFromAddress } from '../utils/orbitdb'
|
import { getBoardIdFromAddress } from '../utils/orbitdb'
|
||||||
|
|
||||||
function getInitialState() {
|
function getInitialState() {
|
||||||
@ -8,22 +8,17 @@ function getInitialState() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function BoardsReducer(state = getInitialState(), action) {
|
export default function BoardsReducer(state = getInitialState(), action) {
|
||||||
let id, newBoards
|
let address, newBoards
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case CREATED_BOARD:
|
case OPENED_BOARD:
|
||||||
id = getBoardIdFromAddress(action.board.address)
|
address = action.board.address
|
||||||
const board = {
|
newBoards = Object.assign({}, state.boards, { [address]: action.board })
|
||||||
id,
|
|
||||||
posts: {}
|
|
||||||
}
|
|
||||||
newBoards = Object.assign({}, state.boards, { [id]: board })
|
|
||||||
return Object.assign({}, state, { boards: newBoards })
|
return Object.assign({}, state, { boards: newBoards })
|
||||||
case UPDATE_BOARD:
|
case UPDATE_BOARD:
|
||||||
id = action.boardId
|
address = action.address
|
||||||
let { posts } = action
|
let { posts, metadata } = action
|
||||||
console.log(state, action)
|
|
||||||
newBoards = Object.assign({}, state.boards, {
|
newBoards = Object.assign({}, state.boards, {
|
||||||
[id]: Object.assign({}, state.boards[id], { posts })
|
[address]: Object.assign({}, state.boards[address], { posts, metadata })
|
||||||
})
|
})
|
||||||
return Object.assign({}, state, { boards: newBoards })
|
return Object.assign({}, state, { boards: newBoards })
|
||||||
default:
|
default:
|
||||||
|
@ -6,36 +6,32 @@ import { creatingBoard, createdBoard, boardError } from '../actions/board'
|
|||||||
import { getBoardIdFromAddress } from '../utils/orbitdb'
|
import { getBoardIdFromAddress } from '../utils/orbitdb'
|
||||||
import { UPDATE_BOARD } from '../actions/actionTypes'
|
import { UPDATE_BOARD } from '../actions/actionTypes'
|
||||||
|
|
||||||
export function* updateBoard({ id }){
|
export function* updateBoard({ address }){
|
||||||
const db = window.dbs[id]
|
const db = window.dbs[address]
|
||||||
yield put({
|
yield put({
|
||||||
type: UPDATE_BOARD,
|
type: UPDATE_BOARD,
|
||||||
boardId: id,
|
address,
|
||||||
posts: db.posts,
|
posts: db.posts,
|
||||||
metadata: db.metadata
|
metadata: db.metadata
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function* createBoard({ board }) {
|
export function* openBoard({ board }) {
|
||||||
yield put(creatingBoard(board))
|
|
||||||
let db
|
let db
|
||||||
try {
|
try {
|
||||||
db = yield call(open, board.id, {
|
const metadata = board.title ? { title: board.title } : null
|
||||||
title: board.title
|
db = yield call(open, board.address, metadata)
|
||||||
})
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
yield put(boardError(error))
|
yield put(boardError(error))
|
||||||
}
|
}
|
||||||
if (db) {
|
if (db) {
|
||||||
const address = db.address.toString()
|
const address = db.address.toString()
|
||||||
const dbInfo = {
|
const dbInfo = { address }
|
||||||
id: getBoardIdFromAddress(address),
|
dbInfo.posts = db.posts
|
||||||
address
|
dbInfo.metadata = db.metadata
|
||||||
}
|
|
||||||
const channel = yield call(createDbEventChannel, db)
|
const channel = yield call(createDbEventChannel, db)
|
||||||
yield fork(watchDb, channel)
|
yield fork(watchDb, channel)
|
||||||
yield put(createdBoard(Object.assign({}, board, dbInfo)))
|
yield put(createdBoard(Object.assign({}, board, dbInfo)))
|
||||||
yield put(push('/b/' + dbInfo.id + '/'))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { takeEvery } from 'redux-saga/effects'
|
import { takeEvery } from 'redux-saga/effects'
|
||||||
import { CREATE_BOARD, ADD_POST, ORBITDB_REPLICATED, ORBITDB_WRITE } from '../actions/actionTypes'
|
import { OPEN_BOARD, ADD_POST, ORBITDB_REPLICATED, ORBITDB_WRITE } from '../actions/actionTypes'
|
||||||
import { createBoard, updateBoard } from './boards'
|
import { openBoard, updateBoard } from './boards'
|
||||||
import { addPost } from './posts'
|
import { addPost } from './posts'
|
||||||
|
|
||||||
export default function* saga(){
|
export default function* saga(){
|
||||||
yield takeEvery(CREATE_BOARD, createBoard)
|
yield takeEvery(OPEN_BOARD, openBoard)
|
||||||
yield takeEvery(ADD_POST, addPost)
|
yield takeEvery(ADD_POST, addPost)
|
||||||
yield takeEvery(ORBITDB_WRITE, updateBoard)
|
yield takeEvery(ORBITDB_WRITE, updateBoard)
|
||||||
yield takeEvery(ORBITDB_REPLICATED, updateBoard)
|
yield takeEvery(ORBITDB_REPLICATED, updateBoard)
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { put, apply, call } from 'redux-saga/effects'
|
import { apply, call } from 'redux-saga/effects'
|
||||||
import { ipfsPut } from '../utils/ipfs'
|
import { ipfsPut } from '../utils/ipfs'
|
||||||
|
|
||||||
export function* addPost({ boardId, post }) {
|
export function* addPost({ address, post }) {
|
||||||
const db = window.dbs[boardId]
|
const db = window.dbs[address]
|
||||||
const { title, content } = post
|
const { title, content } = post
|
||||||
const multihash = yield call(ipfsPut, content)
|
const multihash = yield call(ipfsPut, content)
|
||||||
yield apply(db, db.addPost, [title, multihash])
|
yield apply(db, db.addPost, [title, multihash])
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
|
|
||||||
export function getBoardIdFromAddress(address) {
|
export function getBoardAddress(hash, name) {
|
||||||
const match = /\/orbitdb\/(.+)\//.exec(address)
|
return '/orbitdb/' + hash + '/' + name
|
||||||
if (match[1]) return match[1]
|
}
|
||||||
return undefined
|
|
||||||
|
export function shortenAddress(address) {
|
||||||
|
return address.replace(/^\/orbitdb/, '/b')
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user