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:
parent
29a876c193
commit
87988e1f40
@ -1,4 +1,4 @@
|
||||
# Experimental stuff
|
||||
# IPFS Boards
|
||||
|
||||
This is a branch with a brand new implementation of boards. Nothing works yet
|
||||
|
||||
|
@ -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",
|
||||
|
@ -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'
|
@ -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
|
||||
}
|
||||
}
|
@ -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
5
src/components/Board.js
Normal file
@ -0,0 +1,5 @@
|
||||
import React from 'react'
|
||||
|
||||
export default function Board({ id, address }) {
|
||||
return <div>{address}</div>
|
||||
}
|
@ -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>
|
||||
}
|
@ -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>
|
||||
}
|
@ -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)
|
@ -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))
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
6
src/utils/orbitdb.js
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
export function getBoardIdFromAddress(address) {
|
||||
const match = /\/orbitdb\/(.+)\//.exec(address)
|
||||
if (match[1]) return match[1]
|
||||
return undefined
|
||||
}
|
12
yarn.lock
12
yarn.lock
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user