1
0
mirror of https://github.com/fazo96/ipfs-boards synced 2025-01-24 14:44:19 +01:00

can now kinda open boards

This commit is contained in:
Enrico Fasoli 2018-02-04 19:08:21 +01:00
parent 29a876c193
commit 87988e1f40
No known key found for this signature in database
GPG Key ID: 1238873C5F27DB4D
15 changed files with 127 additions and 20 deletions

View File

@ -1,4 +1,4 @@
# Experimental stuff # IPFS Boards
This is a branch with a brand new implementation of boards. Nothing works yet This is a branch with a brand new implementation of boards. Nothing works yet

View File

@ -5,6 +5,7 @@
"dependencies": { "dependencies": {
"ipfs": "^0.27.7", "ipfs": "^0.27.7",
"orbit-db": "^0.19.4", "orbit-db": "^0.19.4",
"orbit-db-discussion-board": "https://github.com/fazo96/orbit-db-discussion-board.git",
"react": "^16.2.0", "react": "^16.2.0",
"react-dom": "^16.2.0", "react-dom": "^16.2.0",
"react-hot-loader": "^3.1.3", "react-hot-loader": "^3.1.3",

View File

@ -2,4 +2,5 @@
export const ADD_POST = 'ADD_POST' export const ADD_POST = 'ADD_POST'
export const CREATE_BOARD = 'CREATE_BOARD' export const CREATE_BOARD = 'CREATE_BOARD'
export const CREATING_BOARD = 'CREATING_BOARD' export const CREATING_BOARD = 'CREATING_BOARD'
export const CREATED_BOARD = 'CREATED_BOARD' export const CREATED_BOARD = 'CREATED_BOARD'
export const BOARD_ERROR = 'BOARD_ERROR'

View File

@ -1,7 +1,8 @@
import { import {
CREATE_BOARD, CREATE_BOARD,
CREATING_BOARD, CREATING_BOARD,
CREATED_BOARD CREATED_BOARD,
BOARD_ERROR
} from './actionTypes' } from './actionTypes'
export function createBoard(board) { export function createBoard(board) {
@ -23,4 +24,11 @@ export function createdBoard(board) {
type: CREATED_BOARD, type: CREATED_BOARD,
board board
} }
}
export function boardError(error) {
return {
type: BOARD_ERROR,
error
}
} }

View File

@ -1,19 +1,21 @@
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 PostEditor from '../containers/PostEditor'
import BoardEditor from '../containers/BoardEditor' import BoardEditor from '../containers/BoardEditor'
import Board from '../containers/Board'
import 'semantic-ui-css/semantic.css' import 'semantic-ui-css/semantic.css'
class App extends Component { class App extends Component {
render() { render() {
return ( return (
<Switch> <Switch>
<Route path='/p/new' component={PostEditor} />
<Route path='/b/new' component={BoardEditor} /> <Route path='/b/new' component={BoardEditor} />
<Route path='/b/:boardId/p/new' component={PostEditor} />
<Route path='/b/:boardId' component={Board} />
<Route path='/' component={Boards} /> <Route path='/' component={Boards} />
</Switch> </Switch>
); )
} }
} }

5
src/components/Board.js Normal file
View File

@ -0,0 +1,5 @@
import React from 'react'
export default function Board({ id, address }) {
return <div>{address}</div>
}

View File

@ -5,7 +5,7 @@ import { Button } from 'semantic-ui-react'
export default function Boards({ boards, createBoard }) { export default function Boards({ boards, createBoard }) {
return <List divided relaxed> return <List divided relaxed>
{boards.map(board => <BoardsItem {...board} />)} {Object.values(boards).map(board => <BoardsItem {...board} />)}
<Button onClick={createBoard}>New Board</Button> <Button onClick={createBoard}>New Board</Button>
</List> </List>
} }

View File

@ -1,5 +1,14 @@
import React from 'react' import React from 'react'
import { PostEditor } from '../containers/PostEditor'
import { Section } from 'react-semantic-ui'
export default function Feed({ posts }) { export default function Board({ posts }) {
return <ul>{(posts || []).map(p => <li>{p}</li>)}</ul> return <div>
<Section>
<PostEditor />
</Section>
<Section>
<ul>{(posts || []).map(p => <li>{p}</li>)}</ul>
</Section>
</div>
} }

View File

@ -0,0 +1,43 @@
import React, { Component } from 'react'
import { connect } from 'react-redux'
import { push } from 'react-router-redux'
import BoardComponent from '../components/Board'
import { createBoard } from '../actions/board'
class Board extends Component {
componentDidMount() {
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){
return {
boards: state.boards.boards
}
}
function mapDispatchToProps(dispatch){
return {
openBoard: id => dispatch(createBoard(id))
}
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(Board)

View File

@ -1,6 +1,16 @@
import BoardStore from 'orbit-db-discussion-board' import BoardStore from 'orbit-db-discussion-board'
import multihashes from 'multihashes'
export async function open(address, metadata, options = {}) { export function isValidID(id) {
try {
if (typeof id === 'string' && multihashes.fromB58String(id)) return true
} catch (error) {
return false
}
return false
}
export async function open(id, metadata, options = {}) {
if (!window.ipfs) { if (!window.ipfs) {
const IPFS = await import('ipfs') const IPFS = await import('ipfs')
window.ipfs = new IPFS({ window.ipfs = new IPFS({
@ -28,12 +38,13 @@ export async function open(address, metadata, options = {}) {
window.orbitDb = new OrbitDB(window.ipfs) window.orbitDb = new OrbitDB(window.ipfs)
} }
const defaultOptions = { const defaultOptions = {
create: address === undefined, create: id === undefined,
type: BoardStore.type type: BoardStore.type
} }
if (!address) { let address
if (!id) {
address = 'board-v0' address = 'board-v0'
} else if (!address.indexOf('/orbitdb/') < 0 || address.indexOf('/board-v0') < 0) { } else if (!isValidID(id)) {
throw new Error('invalid address') throw new Error('invalid address')
} }
const db = await window.orbitDb.open(address, Object.assign(defaultOptions, options)) const db = await window.orbitDb.open(address, Object.assign(defaultOptions, options))

View File

@ -1,4 +1,5 @@
import { CREATED_BOARD } from '../actions/actionTypes' import { CREATED_BOARD } from '../actions/actionTypes'
import { getBoardIdFromAddress } from '../utils/orbitdb'
function getInitialState() { function getInitialState() {
return { return {
@ -9,7 +10,9 @@ function getInitialState() {
export default function BoardsReducer(state = getInitialState(), action) { export default function BoardsReducer(state = getInitialState(), action) {
switch (action.type) { switch (action.type) {
case CREATED_BOARD: case CREATED_BOARD:
return Object.assign({}, state, { boards: state.boards.concat(action.board) }) const id = getBoardIdFromAddress(action.board.address)
const newBoards = Object.assign({}, state.boards.boards, { [id]: action.board })
return Object.assign({}, state, { boards: newBoards })
default: default:
return state; return state;
} }

View File

@ -1,9 +1,11 @@
import { combineReducers } from 'redux' import { combineReducers } from 'redux'
import { routerReducer } from 'react-router-redux'
import postReducer from './post' import postReducer from './post'
import boardsReducer from './boards' import boardsReducer from './boards'
import boardEditorReducer from './boardEditor' import boardEditorReducer from './boardEditor'
export default combineReducers({ export default combineReducers({
router: routerReducer,
postEditor: postReducer, postEditor: postReducer,
boards: boardsReducer, boards: boardsReducer,
boardEditor: boardEditorReducer boardEditor: boardEditorReducer

View File

@ -1,13 +1,23 @@
import { put, call } from 'redux-saga/effects' import { put, call } from 'redux-saga/effects'
import { push } from 'react-router-redux'
import { open } from '../orbitdb' import { open } from '../orbitdb'
import { creatingBoard, createdBoard } from '../actions/board' import { creatingBoard, createdBoard, boardError } from '../actions/board'
import { getBoardIdFromAddress } from '../utils/orbitdb'
export function* createBoard({ board }) { export function* createBoard({ board }) {
yield put(creatingBoard(board)) yield put(creatingBoard(board))
const db = yield call(open, board.address) let db
try {
db = yield call(open, board.id)
} catch (error) {
yield put(boardError, error)
}
const address = db.address.toString()
const dbInfo = { const dbInfo = {
address: db.address.toString() id: getBoardIdFromAddress(address),
address
} }
// TODO watch db status // TODO watch db status
yield put(createdBoard(Object.assign({}, board, dbInfo))) yield put(createdBoard(Object.assign({}, board, dbInfo)))
yield put(push('/b/' + dbInfo.id + '/'))
} }

6
src/utils/orbitdb.js Normal file
View File

@ -0,0 +1,6 @@
export function getBoardIdFromAddress(address) {
const match = /\/orbitdb\/(.+)\//.exec(address)
if (match[1]) return match[1]
return undefined
}

View File

@ -5040,7 +5040,7 @@ level-js@^2.2.4, level-js@~2.2.4:
typedarray-to-buffer "~1.0.0" typedarray-to-buffer "~1.0.0"
xtend "~2.1.2" xtend "~2.1.2"
"level-js@github:timkuijsten/level.js#idbunwrapper": level-js@timkuijsten/level.js#idbunwrapper:
version "2.2.3" version "2.2.3"
resolved "https://codeload.github.com/timkuijsten/level.js/tar.gz/18e03adab34c49523be7d3d58fafb0c632f61303" resolved "https://codeload.github.com/timkuijsten/level.js/tar.gz/18e03adab34c49523be7d3d58fafb0c632f61303"
dependencies: dependencies:
@ -5922,7 +5922,7 @@ multihashing-async@~0.4.6, multihashing-async@~0.4.7:
murmurhash3js "^3.0.1" murmurhash3js "^3.0.1"
nodeify "^1.0.1" nodeify "^1.0.1"
"multiplex@github:dignifiedquire/multiplex": multiplex@dignifiedquire/multiplex:
version "6.7.0" version "6.7.0"
resolved "https://codeload.github.com/dignifiedquire/multiplex/tar.gz/b5d5edd30454e2c978ee8c52df86f5f4840d2eab" resolved "https://codeload.github.com/dignifiedquire/multiplex/tar.gz/b5d5edd30454e2c978ee8c52df86f5f4840d2eab"
dependencies: dependencies:
@ -6273,6 +6273,12 @@ orbit-db-counterstore@~1.2.0:
crdts "~0.1.2" crdts "~0.1.2"
orbit-db-store "~2.2.0" orbit-db-store "~2.2.0"
"orbit-db-discussion-board@https://github.com/fazo96/orbit-db-discussion-board.git":
version "0.1.0"
resolved "https://github.com/fazo96/orbit-db-discussion-board.git#b71b93f2415a867f8ed29cc76fe7af0e9fb570ce"
dependencies:
orbit-db-store "^2.2.1"
orbit-db-docstore@~1.2.0: orbit-db-docstore@~1.2.0:
version "1.2.0" version "1.2.0"
resolved "https://registry.yarnpkg.com/orbit-db-docstore/-/orbit-db-docstore-1.2.0.tgz#c5d7fe291de148db4e1adebdf3bad12422dc44c6" resolved "https://registry.yarnpkg.com/orbit-db-docstore/-/orbit-db-docstore-1.2.0.tgz#c5d7fe291de148db4e1adebdf3bad12422dc44c6"
@ -6313,7 +6319,7 @@ orbit-db-pubsub@~0.3.8:
ipfs-pubsub-room "github:haadcode/ipfs-pubsub-room#orbitdb" ipfs-pubsub-room "github:haadcode/ipfs-pubsub-room#orbitdb"
logplease "~1.2.14" logplease "~1.2.14"
orbit-db-store@~2.2.0: orbit-db-store@^2.2.1, orbit-db-store@~2.2.0:
version "2.2.1" version "2.2.1"
resolved "https://registry.yarnpkg.com/orbit-db-store/-/orbit-db-store-2.2.1.tgz#49ac9c054ae157e3a0052a9a178a73e2e8b7f914" resolved "https://registry.yarnpkg.com/orbit-db-store/-/orbit-db-store-2.2.1.tgz#49ac9c054ae157e3a0052a9a178a73e2e8b7f914"
dependencies: dependencies: