1
0
mirror of https://github.com/fazo96/ipfs-boards synced 2025-01-09 12:19:49 +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

View File

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

View File

@ -2,4 +2,5 @@
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 CREATED_BOARD = 'CREATED_BOARD'
export const BOARD_ERROR = 'BOARD_ERROR'

View File

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

View File

@ -1,19 +1,21 @@
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 PostEditor from '../containers/PostEditor'
import BoardEditor from '../containers/BoardEditor'
import Board from '../containers/Board'
import 'semantic-ui-css/semantic.css'
class App extends Component {
render() {
return (
<Switch>
<Route path='/p/new' component={PostEditor} />
<Route path='/b/new' component={BoardEditor} />
<Route path='/b/:boardId/p/new' component={PostEditor} />
<Route path='/b/:boardId' component={Board} />
<Route path='/' component={Boards} />
</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 }) {
return <List divided relaxed>
{boards.map(board => <BoardsItem {...board} />)}
{Object.values(boards).map(board => <BoardsItem {...board} />)}
<Button onClick={createBoard}>New Board</Button>
</List>
}

View File

@ -1,5 +1,14 @@
import React from 'react'
import { PostEditor } from '../containers/PostEditor'
import { Section } from 'react-semantic-ui'
export default function Feed({ posts }) {
return <ul>{(posts || []).map(p => <li>{p}</li>)}</ul>
export default function Board({ posts }) {
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 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) {
const IPFS = await import('ipfs')
window.ipfs = new IPFS({
@ -28,12 +38,13 @@ export async function open(address, metadata, options = {}) {
window.orbitDb = new OrbitDB(window.ipfs)
}
const defaultOptions = {
create: address === undefined,
create: id === undefined,
type: BoardStore.type
}
if (!address) {
let address
if (!id) {
address = 'board-v0'
} else if (!address.indexOf('/orbitdb/') < 0 || address.indexOf('/board-v0') < 0) {
} else if (!isValidID(id)) {
throw new Error('invalid address')
}
const db = await window.orbitDb.open(address, Object.assign(defaultOptions, options))

View File

@ -1,4 +1,5 @@
import { CREATED_BOARD } from '../actions/actionTypes'
import { getBoardIdFromAddress } from '../utils/orbitdb'
function getInitialState() {
return {
@ -9,7 +10,9 @@ function getInitialState() {
export default function BoardsReducer(state = getInitialState(), action) {
switch (action.type) {
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:
return state;
}

View File

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

View File

@ -1,13 +1,23 @@
import { put, call } from 'redux-saga/effects'
import { push } from 'react-router-redux'
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 }) {
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 = {
address: db.address.toString()
id: getBoardIdFromAddress(address),
address
}
// TODO watch db status
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"
xtend "~2.1.2"
"level-js@github:timkuijsten/level.js#idbunwrapper":
level-js@timkuijsten/level.js#idbunwrapper:
version "2.2.3"
resolved "https://codeload.github.com/timkuijsten/level.js/tar.gz/18e03adab34c49523be7d3d58fafb0c632f61303"
dependencies:
@ -5922,7 +5922,7 @@ multihashing-async@~0.4.6, multihashing-async@~0.4.7:
murmurhash3js "^3.0.1"
nodeify "^1.0.1"
"multiplex@github:dignifiedquire/multiplex":
multiplex@dignifiedquire/multiplex:
version "6.7.0"
resolved "https://codeload.github.com/dignifiedquire/multiplex/tar.gz/b5d5edd30454e2c978ee8c52df86f5f4840d2eab"
dependencies:
@ -6273,6 +6273,12 @@ orbit-db-counterstore@~1.2.0:
crdts "~0.1.2"
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:
version "1.2.0"
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"
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"
resolved "https://registry.yarnpkg.com/orbit-db-store/-/orbit-db-store-2.2.1.tgz#49ac9c054ae157e3a0052a9a178a73e2e8b7f914"
dependencies: