Refactor/improve state handling from ws
This commit is contained in:
parent
50161bc2a9
commit
13f7d40e92
|
@ -27,6 +27,7 @@
|
||||||
"react-dom": "^15.6.1",
|
"react-dom": "^15.6.1",
|
||||||
"react-redux": "^5.0.5",
|
"react-redux": "^5.0.5",
|
||||||
"redux": "^3.7.2",
|
"redux": "^3.7.2",
|
||||||
|
"redux-thunk": "^2.2.0",
|
||||||
"style-loader": "^0.18.2",
|
"style-loader": "^0.18.2",
|
||||||
"webpack": "^3.1.0",
|
"webpack": "^3.1.0",
|
||||||
"webpack-dev-middleware": "^1.12.0",
|
"webpack-dev-middleware": "^1.12.0",
|
||||||
|
|
18
src/actions/filter_subscribe.js
Normal file
18
src/actions/filter_subscribe.js
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import ws_send from '../socket';
|
||||||
|
|
||||||
|
export const FILTER_SUBSCRIBE = 'FILTER_SUBSCRIBE';
|
||||||
|
export const FILTER_UNSUBSCRIBE = 'FILTER_UNSUBSCRIBE';
|
||||||
|
|
||||||
|
export function filter_subscribe(kind='torrent', criteria=[]) {
|
||||||
|
return dispatch => {
|
||||||
|
const serial = ws_send(FILTER_SUBSCRIBE, { criteria, kind });
|
||||||
|
dispatch({ type: FILTER_SUBSCRIBE, serial });
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function filter_unsubscribe(serial) {
|
||||||
|
return dispatch => {
|
||||||
|
ws_send(FILTER_UNSUBSCRIBE, { serial });
|
||||||
|
dispatch({ type: FILTER_UNSUBSCRIBE, serial });
|
||||||
|
};
|
||||||
|
}
|
25
src/actions/subscribe.js
Normal file
25
src/actions/subscribe.js
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
import ws_send from '../socket';
|
||||||
|
|
||||||
|
export const SUBSCRIBE = 'SUBSCRIBE';
|
||||||
|
export const UNSUBSCRIBE = 'UNSUBSCRIBE';
|
||||||
|
|
||||||
|
export function subscribe(...ids) {
|
||||||
|
return dispatch => {
|
||||||
|
const serial = ws_send(SUBSCRIBE, { ids });
|
||||||
|
dispatch({
|
||||||
|
type: SUBSCRIBE,
|
||||||
|
serial,
|
||||||
|
ids
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function unsubscribe(...ids) {
|
||||||
|
return dispatch => {
|
||||||
|
ws_send(UNSUBSCRIBE, { ids });
|
||||||
|
dispatch({
|
||||||
|
type: UNSUBSCRIBE,
|
||||||
|
ids
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
|
@ -4,6 +4,13 @@ import { Provider } from 'react-redux';
|
||||||
|
|
||||||
import store from './store';
|
import store from './store';
|
||||||
import scss from '../scss/base.scss';
|
import scss from '../scss/base.scss';
|
||||||
|
import { ws_init } from './socket';
|
||||||
|
import { filter_subscribe } from './actions/filter_subscribe';
|
||||||
|
|
||||||
|
ws_init(() => {
|
||||||
|
store.dispatch(filter_subscribe());
|
||||||
|
store.dispatch(filter_subscribe('server'));
|
||||||
|
});
|
||||||
|
|
||||||
render(
|
render(
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
|
|
18
src/reducers/filter_subscribe.js
Normal file
18
src/reducers/filter_subscribe.js
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import {
|
||||||
|
FILTER_SUBSCRIBE,
|
||||||
|
FILTER_UNSUBSCRIBE
|
||||||
|
} from '../actions/filter_subscribe';
|
||||||
|
|
||||||
|
export default function filter_subscribe(state = [], action) {
|
||||||
|
switch (action.type) {
|
||||||
|
case FILTER_SUBSCRIBE: {
|
||||||
|
const { serial } = action;
|
||||||
|
return [...state, serial];
|
||||||
|
}
|
||||||
|
case FILTER_UNSUBSCRIBE: {
|
||||||
|
const { serial } = action;
|
||||||
|
return state.filter(s => s !== serial);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
|
@ -1,7 +1,11 @@
|
||||||
import { combineReducers } from 'redux';
|
import { combineReducers } from 'redux';
|
||||||
|
import subscribe from './subscribe';
|
||||||
|
import filter_subscribe from './filter_subscribe';
|
||||||
import torrents from './torrents';
|
import torrents from './torrents';
|
||||||
|
|
||||||
const root = combineReducers({
|
const root = combineReducers({
|
||||||
|
subscribe,
|
||||||
|
filter_subscribe,
|
||||||
torrents
|
torrents
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
15
src/reducers/subscribe.js
Normal file
15
src/reducers/subscribe.js
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import { SUBSCRIBE, UNSUBSCRIBE } from '../actions/subscribe';
|
||||||
|
|
||||||
|
export default function subscribe(state = [], action) {
|
||||||
|
switch (action.type) {
|
||||||
|
case SUBSCRIBE: {
|
||||||
|
const { ids, serial } = action;
|
||||||
|
return [ ...state, ...ids.map(id => ({ serial, id })) ];
|
||||||
|
}
|
||||||
|
case UNSUBSCRIBE: {
|
||||||
|
const { ids } = action;
|
||||||
|
return state.filter(sub => ids.indexOf(sub.id) === -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
|
@ -2,13 +2,13 @@ import { UPDATE_RESOURCES } from '../actions/resources';
|
||||||
|
|
||||||
export default function torrents(state = {}, action) {
|
export default function torrents(state = {}, action) {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case UPDATE_RESOURCES:
|
case UPDATE_RESOURCES:
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
...action.resources
|
...action.resources
|
||||||
.filter(r => r.type === "torrent")
|
.filter(r => r.type === "torrent")
|
||||||
.reduce((s, r) => s[r.id] = r, {})
|
.reduce((s, r) => ({ ...s, [r.id]: r }), {})
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
41
src/socket.js
Normal file
41
src/socket.js
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
import { dispatch } from './store';
|
||||||
|
import { subscribe } from './actions/subscribe';
|
||||||
|
|
||||||
|
let ws;
|
||||||
|
let serial = 0;
|
||||||
|
let transactions = {};
|
||||||
|
|
||||||
|
export default function ws_send(type, body, callback = null) {
|
||||||
|
const _serial = serial++;
|
||||||
|
if (callback) {
|
||||||
|
transactions[_serial] = callback;
|
||||||
|
}
|
||||||
|
const msg = JSON.stringify({
|
||||||
|
type,
|
||||||
|
serial: _serial,
|
||||||
|
...body
|
||||||
|
});
|
||||||
|
console.log("->", msg);
|
||||||
|
ws.send(msg);
|
||||||
|
return _serial;
|
||||||
|
}
|
||||||
|
|
||||||
|
const handlers = {
|
||||||
|
RESOURCES_EXTANT: msg => dispatch(subscribe(...msg.ids)),
|
||||||
|
UPDATE_RESOURCES: msg => dispatch(msg)
|
||||||
|
};
|
||||||
|
|
||||||
|
function ws_recv(e) {
|
||||||
|
const msg = JSON.parse(e.data);
|
||||||
|
console.log("<-", msg);
|
||||||
|
const cb = transactions[msg.serial];
|
||||||
|
cb && cb(msg);
|
||||||
|
const handler = handlers[msg.type];
|
||||||
|
handler && handler(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ws_init(cb) {
|
||||||
|
ws = new WebSocket("ws://127.0.0.1:8412");
|
||||||
|
ws.addEventListener("open", cb);
|
||||||
|
ws.addEventListener("message", ws_recv);
|
||||||
|
}
|
15
src/store.js
15
src/store.js
|
@ -1,10 +1,19 @@
|
||||||
import { createStore } from 'redux';
|
import {
|
||||||
|
applyMiddleware,
|
||||||
|
createStore,
|
||||||
|
compose
|
||||||
|
} from 'redux';
|
||||||
|
import thunk from 'redux-thunk';
|
||||||
import reducer from './reducers';
|
import reducer from './reducers';
|
||||||
|
|
||||||
|
const _compose =
|
||||||
|
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
|
||||||
|
|| compose;
|
||||||
const store = createStore(
|
const store = createStore(
|
||||||
reducer,
|
reducer,
|
||||||
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
|
_compose(applyMiddleware(thunk)),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const dispatch = action => store.dispatch(action);
|
||||||
|
|
||||||
export default store;
|
export default store;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user