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-redux": "^5.0.5",
|
||||
"redux": "^3.7.2",
|
||||
"redux-thunk": "^2.2.0",
|
||||
"style-loader": "^0.18.2",
|
||||
"webpack": "^3.1.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 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(
|
||||
<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 subscribe from './subscribe';
|
||||
import filter_subscribe from './filter_subscribe';
|
||||
import torrents from './torrents';
|
||||
|
||||
const root = combineReducers({
|
||||
subscribe,
|
||||
filter_subscribe,
|
||||
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;
|
||||
}
|
|
@ -7,7 +7,7 @@ export default function torrents(state = {}, action) {
|
|||
...state,
|
||||
...action.resources
|
||||
.filter(r => r.type === "torrent")
|
||||
.reduce((s, r) => s[r.id] = r, {})
|
||||
.reduce((s, r) => ({ ...s, [r.id]: r }), {})
|
||||
};
|
||||
}
|
||||
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';
|
||||
|
||||
const _compose =
|
||||
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
|
||||
|| compose;
|
||||
const store = createStore(
|
||||
reducer,
|
||||
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
|
||||
_compose(applyMiddleware(thunk)),
|
||||
);
|
||||
|
||||
export const dispatch = action => store.dispatch(action);
|
||||
|
||||
export default store;
|
||||
|
|
Loading…
Reference in New Issue
Block a user