diff --git a/examples/react.html b/examples/react.html new file mode 100644 index 00000000..e17eab76 --- /dev/null +++ b/examples/react.html @@ -0,0 +1,175 @@ + + + +gun - react examples + + + +
+ + + + + + + diff --git a/examples/react/.babelrc b/examples/react/.babelrc new file mode 100644 index 00000000..29d8a3d5 --- /dev/null +++ b/examples/react/.babelrc @@ -0,0 +1,11 @@ +{ + "presets": [ + "react", + "env", + "stage-0" + ], + "plugins": [ + "transform-decorators-legacy", + "transform-eval" + ] +} diff --git a/examples/react/.gitignore b/examples/react/.gitignore new file mode 100644 index 00000000..34aff0de --- /dev/null +++ b/examples/react/.gitignore @@ -0,0 +1,3 @@ +data.json +node_modules +npm-debug.log diff --git a/examples/react/README.md b/examples/react/README.md new file mode 100644 index 00000000..7947511d --- /dev/null +++ b/examples/react/README.md @@ -0,0 +1,8 @@ +# React Gun Examples + +These are the react examples for gun. They are separate from the other examples, because they require a lot of additional npm modules. + +To run these modules, change to this directory, and run `npm install` and then `npm start` to start the server. Then navigate to `localhost:3000` to view the examples. + + +![examples](https://i.imgur.com/ZXOHWNN.gif) diff --git a/examples/react/app.js b/examples/react/app.js new file mode 100644 index 00000000..a2dac23b --- /dev/null +++ b/examples/react/app.js @@ -0,0 +1,23 @@ +import React, { Component } from 'react' +import { render } from 'react-dom' +import Todos from './todos' +import Chat from './chat' +import Json from './json' + +const App = _ => +
+

React Examples

+

Todo

+ +
+
+

Chat

+ +
+
+

Json

+ +
+ +render(, document.getElementById('app')) + diff --git a/examples/react/chat.js b/examples/react/chat.js new file mode 100644 index 00000000..c0b44d53 --- /dev/null +++ b/examples/react/chat.js @@ -0,0 +1,57 @@ +import React, { Component } from 'react' +import Gun from '../../gun' + +const gun = Gun().get('chat') +const formatMsgs = msgs => Object.keys(msgs) + .map(key => ({ key, ...msgs[key] })) + .filter(m => Boolean(m.when) && m.key !== '_') + .sort((a, b) => a.when - b.when) + .map(m => ((m.whenFmt = new Date(m.when).toLocaleString().toLowerCase()), m)) + +export default class Chat extends Component { + constructor() { + super() + this.state = { + newMsg: '', + name: (document.cookie.match(/alias\=(.*?)(\&|$|\;)/i)||[])[1]||'', + msgs: {}, + } + } + componentWillMount() { + const tmpState = {} + gun.map().val((msg, key) => { + tmpState[key] = msg + this.setState({msgs: Object.assign({}, this.state.msgs, tmpState)}) + }) + + } + send = e => { + e.preventDefault() + const who = this.state.name || 'user' + Gun.text.random(6) + this.setState({name: who}) + document.cookie = ('alias=' + who) + const when = Gun.time.is() + const key = `${when}_${Gun.text.random(4)}` + gun.path(key).put({ + who, + when, + what: this.state.newMsg, + }) + this.setState({newMsg: ''}) + } + render() { + const msgs = formatMsgs(this.state.msgs) + return
+ +
+ this.setState({ name: e.target.value})} /> + this.setState({ newMsg: e.target.value})} /> + +
+
+ } +} diff --git a/examples/react/index.html b/examples/react/index.html new file mode 100644 index 00000000..789a18c0 --- /dev/null +++ b/examples/react/index.html @@ -0,0 +1,12 @@ + + + +Gun - React Examples + + + + +
+ + + diff --git a/examples/react/json.js b/examples/react/json.js new file mode 100644 index 00000000..62f6fb00 --- /dev/null +++ b/examples/react/json.js @@ -0,0 +1,45 @@ +import React, { Component } from 'react' +import Gun from '../../gun' + +const gun = Gun().get('json') +const formatJson = json => + Object.keys(json) + .map(key => ({ key, val: json[key]})) + .filter(el => el.key !== '_') + +export default class Json extends Component { + constructor() { + super() + this.state = { newField: '', json: [] } + } + + componentWillMount() { + gun.on(json => this.setState({ json: formatJson(json) })) + } + + edit = key => e => { + e.preventDefault() + gun.path(key).put(e.target.value) + } + + add = e => { + e.preventDefault() + gun.path(this.state.newField).put('value') + this.setState({newField: ''}) + } + + render() { + return
+ +
+ this.setState({ newField: e.target.value})} /> + +
+
+ } +} + diff --git a/examples/react/package.json b/examples/react/package.json new file mode 100644 index 00000000..e83fc128 --- /dev/null +++ b/examples/react/package.json @@ -0,0 +1,38 @@ +{ + "name": "gun-react-examples", + "version": "1.0.0", + "description": "", + "scripts": { + "start": "node start", + "dev": "nodemon --config .nodemon.json start" + }, + "keywords": [], + "author": "", + "license": "ISC", + "devDependencies": { + "babel": "^6.5.2", + "babel-core": "^6.21.0", + "babel-loader": "^6.2.10", + "babel-plugin-transform-decorators-legacy": "^1.3.4", + "babel-plugin-transform-eval": "^6.8.0", + "babel-preset-env": "^1.2.0", + "babel-preset-react": "^6.16.0", + "babel-preset-stage-0": "^6.16.0", + "css-loader": "^0.26.1", + "file-loader": "^0.9.0", + "html-webpack-plugin": "^2.26.0", + "json-loader": "^0.5.4", + "style-loader": "^0.13.1", + "url-loader": "^0.5.7", + "webpack": "^1.14.0" + }, + "dependencies": { + "babel": "^6.5.2", + "babel-polyfill": "^6.20.0", + "express": "^4.14.1", + "lodash": "^4.17.4", + "react": "^15.4.2", + "react-dom": "^15.4.2", + "webpack-dev-middleware": "^1.9.0" + } +} diff --git a/examples/react/server.js b/examples/react/server.js new file mode 100644 index 00000000..b755d568 --- /dev/null +++ b/examples/react/server.js @@ -0,0 +1,19 @@ +import express from 'express' +import Gun from '../..' +import webpack from 'webpack' +import WebpackDevMiddleware from 'webpack-dev-middleware' +import config from './webpack.config' + + +const app = express() +const gun = Gun() + +gun.wsp(app) + +const compiler = webpack(config) + +const devMiddleware = WebpackDevMiddleware(compiler) + +app.use(devMiddleware) + +app.listen(4000) diff --git a/examples/react/start.js b/examples/react/start.js new file mode 100644 index 00000000..c0529ba2 --- /dev/null +++ b/examples/react/start.js @@ -0,0 +1,3 @@ +require('source-map-support').install() +require('babel-register') +require('./server') diff --git a/examples/react/style.css b/examples/react/style.css new file mode 100644 index 00000000..4625ea1f --- /dev/null +++ b/examples/react/style.css @@ -0,0 +1,7 @@ +html, body { font-size: 14pt; padding: 10px 2.5%;} +.hide { display: none; } +form .who { width: 10%; } +form .what { width: 80%; } +ul { list-style: none; padding: 0; } +ul .when {color: #555; font-size: 12pt; float: right; display: none; } +li:hover .when {display: inline;} diff --git a/examples/react/todos.js b/examples/react/todos.js new file mode 100644 index 00000000..53f8c330 --- /dev/null +++ b/examples/react/todos.js @@ -0,0 +1,40 @@ +import './style.css' +import React, { Component } from 'react' +import Gun from '../../gun' + +const gun = Gun().get('todos') +const formatTodos = todos => Object.keys(todos) + .map(key => ({ key, val: todos[key] })) + .filter(t => Boolean(t.val) && t.key !== '_') + +export default class Todos extends Component { + constructor() { + super() + this.state = {newTodo: '', todos: []} + } + componentWillMount() { + gun.on(todos => this.setState({ + todos: formatTodos(todos) + })) + } + add = e => { + e.preventDefault() + gun.path(Gun.text.random()).put(this.state.newTodo) + this.setState({newTodo: ''}) + } + del = key => gun.path(key).put(null) + handleChange = e => this.setState({ newTodo: e.target.value}) + render() { + return
+
+ + +
+
+ +
+ } +} + diff --git a/examples/react/webpack.config.js b/examples/react/webpack.config.js new file mode 100644 index 00000000..c741f22b --- /dev/null +++ b/examples/react/webpack.config.js @@ -0,0 +1,38 @@ +var webpack = require('webpack') +var path = require('path') +var HtmlWebpackPlugin = require('html-webpack-plugin') +module.exports = { + entry: './app.js', + devtool: 'source-map', + output: { + filename: '[name].js?[hash]', + path: path.join(__dirname, 'public'), + }, + module: { + loaders: [ + { + test: /\.css$/, + loader: 'style!css', + }, + { + test: /\.(png|gif|jpg|jpeg|woff)$/, + loader: 'url', + }, + { + test: /\.(eot|ttf|svg|ico)$/, + loader: 'file', + }, + { + test: /\.js$/, + loader: 'babel', + exclude: /node_modules/, + } + ] + }, + plugins: [ + new webpack.HotModuleReplacementPlugin(), + new HtmlWebpackPlugin({ + template: './index.html' + }) + ], +}