mirror of
https://github.com/fazo96/ipfs-boards
synced 2025-01-09 12:19:49 +01:00
WIP making posts
This commit is contained in:
parent
c9218d94e6
commit
7483c683a4
@ -1,6 +1,13 @@
|
||||
|
||||
export const ADD_POST = 'ADD_POST'
|
||||
|
||||
export const CREATE_BOARD = 'CREATE_BOARD'
|
||||
export const CREATING_BOARD = 'CREATING_BOARD'
|
||||
export const CREATED_BOARD = 'CREATED_BOARD'
|
||||
export const BOARD_ERROR = 'BOARD_ERROR'
|
||||
|
||||
export const UPDATE_BOARD = 'UPDATE_BOARD'
|
||||
|
||||
export const BOARD_ERROR = 'BOARD_ERROR'
|
||||
|
||||
export const ORBITDB_WRITE = 'ORBITDB_WRITE'
|
||||
export const ORBITDB_REPLICATED = 'ORBITDB_REPLICATED'
|
@ -1,8 +1,9 @@
|
||||
import { ADD_POST } from './actionTypes'
|
||||
|
||||
export function addPost(post) {
|
||||
export function addPost(boardId, post) {
|
||||
return {
|
||||
type: ADD_POST,
|
||||
post
|
||||
post,
|
||||
boardId
|
||||
}
|
||||
}
|
@ -1,16 +1,14 @@
|
||||
import React from 'react'
|
||||
import PostEditor from '../containers/PostEditor'
|
||||
import Post from './Post'
|
||||
import { Segment } from 'semantic-ui-react'
|
||||
import { Segment, Button } from 'semantic-ui-react'
|
||||
import { Link } from 'react-router-dom'
|
||||
|
||||
export default function Board({ id, posts }) {
|
||||
return <div>
|
||||
<Segment>{id}</Segment>
|
||||
<Segment><Button as={Link} to={'p/new'}>New Post</Button></Segment>
|
||||
<Segment>
|
||||
<PostEditor />
|
||||
</Segment>
|
||||
<Segment>
|
||||
<ul>{Object.keys(posts).map(i => <Post key={posts[i]} {...posts[i]}/>)}</ul>
|
||||
<ul>{Object.keys(posts).map(i => <Post key={posts[i].multihash} {...posts[i]}/>)}</ul>
|
||||
</Segment>
|
||||
</div>
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import React from 'react'
|
||||
|
||||
export default function Post({ title, content }) {
|
||||
return <li>{title}: {content}</li>
|
||||
export default function Post({ title, multihash}) {
|
||||
return <li>{title}: {multihash}</li>
|
||||
}
|
@ -1,10 +1,14 @@
|
||||
import React from 'react'
|
||||
import React, { Component } from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
import PostForm from '../components/PostForm'
|
||||
import { addPost } from '../actions/post'
|
||||
|
||||
function PostEditor({ post, addPost }) {
|
||||
return <PostForm post={post} onSave={addPost} />
|
||||
class PostEditor extends Component {
|
||||
render() {
|
||||
const { post, addPost, match } = this.props
|
||||
const { boardId } = match.params
|
||||
return <PostForm post={post} onSave={p => addPost(boardId, p)} />
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps(state){
|
||||
@ -15,7 +19,7 @@ function mapStateToProps(state){
|
||||
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return {
|
||||
addPost: post => dispatch(addPost(post))
|
||||
addPost: (boardId, post) => dispatch(addPost(boardId, post))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,14 +48,18 @@ export async function open(id, metadata, options = {}) {
|
||||
} else if (!isValidID(id)) {
|
||||
throw new Error('invalid address')
|
||||
}
|
||||
const db = await window.orbitDb.open(address, Object.assign(defaultOptions, options))
|
||||
await db.load()
|
||||
if (metadata && defaultOptions.create) {
|
||||
await db.updateMetadata(metadata)
|
||||
try {
|
||||
const db = await window.orbitDb.open(address, Object.assign(defaultOptions, options))
|
||||
await db.load()
|
||||
if (metadata && defaultOptions.create) {
|
||||
await db.updateMetadata(metadata)
|
||||
}
|
||||
if (!window.dbs) window.dbs = {}
|
||||
window.dbs[getBoardIdFromAddress(db.address.toString())] = db
|
||||
return db
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
if (!window.dbs) window.dbs = {}
|
||||
window.dbs[db.address.toString()] = db
|
||||
return db
|
||||
}
|
||||
|
||||
export function connectDb(db, dispatch) {
|
||||
|
@ -1,26 +1,30 @@
|
||||
import { CREATED_BOARD } from '../actions/actionTypes'
|
||||
import { CREATED_BOARD, UPDATE_BOARD } from '../actions/actionTypes'
|
||||
import { getBoardIdFromAddress } from '../utils/orbitdb'
|
||||
|
||||
function getInitialState() {
|
||||
return {
|
||||
boards: []
|
||||
boards: {}
|
||||
}
|
||||
}
|
||||
|
||||
export default function BoardsReducer(state = getInitialState(), action) {
|
||||
let id, newBoards
|
||||
switch (action.type) {
|
||||
case CREATED_BOARD:
|
||||
const id = getBoardIdFromAddress(action.board.address)
|
||||
id = getBoardIdFromAddress(action.board.address)
|
||||
const board = {
|
||||
id,
|
||||
posts: {
|
||||
1: {
|
||||
title: 'Example Post',
|
||||
content: 'no, this is not real'
|
||||
}
|
||||
}
|
||||
posts: {}
|
||||
}
|
||||
const newBoards = Object.assign({}, state.boards.boards, { [id]: board })
|
||||
newBoards = Object.assign({}, state.boards, { [id]: board })
|
||||
return Object.assign({}, state, { boards: newBoards })
|
||||
case UPDATE_BOARD:
|
||||
id = action.boardId
|
||||
let { posts } = action
|
||||
console.log(state, action)
|
||||
newBoards = Object.assign({}, state.boards, {
|
||||
[id]: Object.assign({}, state.boards[id], { posts })
|
||||
})
|
||||
return Object.assign({}, state, { boards: newBoards })
|
||||
default:
|
||||
return state;
|
||||
|
@ -1,8 +1,20 @@
|
||||
import { put, call } from 'redux-saga/effects'
|
||||
import { put, call, fork, take } from 'redux-saga/effects'
|
||||
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 { UPDATE_BOARD } from '../actions/actionTypes'
|
||||
|
||||
export function* updateBoard({ id }){
|
||||
const db = window.dbs[id]
|
||||
yield put({
|
||||
type: UPDATE_BOARD,
|
||||
boardId: id,
|
||||
posts: db.posts,
|
||||
metadata: db.metadata
|
||||
})
|
||||
}
|
||||
|
||||
export function* createBoard({ board }) {
|
||||
yield put(creatingBoard(board))
|
||||
@ -12,15 +24,33 @@ export function* createBoard({ board }) {
|
||||
title: board.title
|
||||
})
|
||||
} catch (error) {
|
||||
yield put(boardError, error)
|
||||
yield put(boardError(error))
|
||||
}
|
||||
const address = db.address.toString()
|
||||
const dbInfo = {
|
||||
id: getBoardIdFromAddress(address),
|
||||
address
|
||||
if (db) {
|
||||
const address = db.address.toString()
|
||||
const dbInfo = {
|
||||
id: getBoardIdFromAddress(address),
|
||||
address
|
||||
}
|
||||
const channel = yield call(createDbEventChannel, db)
|
||||
yield fork(watchDb, channel)
|
||||
yield put(createdBoard(Object.assign({}, board, dbInfo)))
|
||||
yield put(push('/b/' + dbInfo.id + '/'))
|
||||
}
|
||||
// TODO: use https://redux-saga.js.org/docs/advanced/Channels.html to handle orbitdb events
|
||||
// yield call(connectDb(db, dispatch))
|
||||
yield put(createdBoard(Object.assign({}, board, dbInfo)))
|
||||
yield put(push('/b/' + dbInfo.id + '/'))
|
||||
}
|
||||
|
||||
function* watchDb(channel) {
|
||||
// Dispatches action coming from the channel, terminates when ORBITDB_CLOSE arrives
|
||||
let action
|
||||
while(!action || action.type !== 'ORBITDB_CLOSE') {
|
||||
action = yield take(channel)
|
||||
yield put(action)
|
||||
}
|
||||
}
|
||||
|
||||
function createDbEventChannel(db) {
|
||||
return eventChannel(emitter => {
|
||||
connectDb(db, emitter)
|
||||
return () => db.close()
|
||||
})
|
||||
}
|
@ -1,7 +1,11 @@
|
||||
import { takeEvery } from 'redux-saga/effects'
|
||||
import { CREATE_BOARD } from '../actions/actionTypes'
|
||||
import { createBoard } from './boards'
|
||||
import { CREATE_BOARD, ADD_POST, ORBITDB_REPLICATED, ORBITDB_WRITE } from '../actions/actionTypes'
|
||||
import { createBoard, updateBoard } from './boards'
|
||||
import { addPost } from './posts'
|
||||
|
||||
export default function* saga(){
|
||||
yield takeEvery(CREATE_BOARD, createBoard)
|
||||
yield takeEvery(ADD_POST, addPost)
|
||||
yield takeEvery(ORBITDB_WRITE, updateBoard)
|
||||
yield takeEvery(ORBITDB_REPLICATED, updateBoard)
|
||||
}
|
9
src/sagas/posts.js
Normal file
9
src/sagas/posts.js
Normal file
@ -0,0 +1,9 @@
|
||||
import { put, apply, call } from 'redux-saga/effects'
|
||||
import { ipfsPut } from '../utils/ipfs'
|
||||
|
||||
export function* addPost({ boardId, post }) {
|
||||
const db = window.dbs[boardId]
|
||||
const { title, content } = post
|
||||
const multihash = yield call(ipfsPut, content)
|
||||
yield apply(db, db.addPost, [title, multihash])
|
||||
}
|
6
src/utils/ipfs.js
Normal file
6
src/utils/ipfs.js
Normal file
@ -0,0 +1,6 @@
|
||||
import multihashes from 'multihashes'
|
||||
|
||||
export async function ipfsPut(content) {
|
||||
const dagNode = await window.ipfs.object.put(Buffer.from(content))
|
||||
return multihashes.toB58String(dagNode.multihash)
|
||||
}
|
Loading…
Reference in New Issue
Block a user