Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Redux branch #67

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions client/configs/context.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import * as Collections from '/lib/collections';
import {Meteor} from 'meteor/meteor';
import {FlowRouter} from 'meteor/kadira:flow-router';
import {ReactiveDict} from 'meteor/reactive-dict';
import {Tracker} from 'meteor/tracker';
import {createStore} from 'redux';

export default function () {
export default function ({reducer}) {
return {
Meteor,
FlowRouter,
Collections,
LocalState: new ReactiveDict(),
Tracker
Tracker,
Store: createStore(reducer)
};
}
12 changes: 10 additions & 2 deletions client/main.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
import {createApp} from 'mantra-core';
import {combineReducers} from 'redux';
import initContext from './configs/context';

// modules
import coreModule from './modules/core';
import commentsModule from './modules/comments';

const coreReducers = coreModule.reducers;
const commentsReducers = commentsModule.reducers;
const reducer = combineReducers({
...coreReducers,
...commentsReducers
});

// init context
const context = initContext();
const context = initContext({reducer});

// create app
const app = createApp(context);
app.loadModule(coreModule);
app.loadModule(commentsModule);
app.init();
app.init();
27 changes: 20 additions & 7 deletions client/modules/comments/actions/comments.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,37 @@
export default {
create({Meteor, LocalState}, postId, text) {
create({Meteor, Store}, postId, text) {
if (!text) {
return LocalState.set('CREATE_COMMENT_ERROR', 'Comment text is required.');
return Store.dispatch({
type: 'SET_CREATE_COMMENT_ERROR',
error: 'Comment text is required.'
});
}

if (!postId) {
return LocalState.set('CREATE_COMMENT_ERROR', 'postId is required.');
return Store.dispatch({
type: 'SET_CREATE_COMMENT_ERROR',
error: 'postId is required.'
});
}

LocalState.set('CREATE_COMMENT_ERROR', null);
Store.dispatch({
type: 'CLEAR_CREATE_COMMENT_ERROR'
});

const id = Meteor.uuid();
Meteor.call('posts.createComment', id, postId, text, (err) => {
if (err) {
return LocalState.set('CREATE_COMMENT_ERROR', err.message);
return Store.dispatch({
type: 'SET_CREATE_COMMENT_ERROR',
error: err.message
});
}
});
},

clearErrors({LocalState}) {
return LocalState.set('CREATE_COMMENT_ERROR', null);
clearErrors({Store}) {
return Store.dispatch({
type: 'CLEAR_CREATE_COMMENT_ERROR'
});
}
};
19 changes: 19 additions & 0 deletions client/modules/comments/configs/reducers/comments.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const defaultState = { CREATE_COMMENT_ERROR: null};
const commentsReducer = (state = defaultState, action) => {
switch(action.type) {
case 'SET_CREATE_COMMENT_ERROR':
return {
...state,
CREATE_COMMENT_ERROR: action.error
};
case 'CLEAR_CREATE_COMMENT_ERROR':
return {
...state,
CREATE_COMMENT_ERROR: null
};
default:
return state;
}
};

export default commentsReducer;
5 changes: 5 additions & 0 deletions client/modules/comments/configs/reducers/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import comments from './comments';

export default {
comments
}
27 changes: 22 additions & 5 deletions client/modules/comments/containers/create_comment.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,31 @@
import {
useDeps, composeWithTracker, composeAll
useDeps, compose, composeAll
} from 'mantra-core';
import Component from '../components/create_comment.jsx';

export const composer = ({context, clearErrors}, onData) => {
const {LocalState} = context();
const error = LocalState.get('CREATE_COMMENT_ERROR');
const {Store} = context();

// subscribe to state updates
// and keep handle to unsubscribe
const unsubscribe = Store.subscribe(() => {
const error = Store.getState().comments.CREATE_COMMENT_ERROR;
onData(null, {error})
});

// get initial state
const error = Store.getState().comments.CREATE_COMMENT_ERROR;
onData(null, {error});

return clearErrors;
// function to unsubscribe from Store
// and clearing error
const cleanup = () => {
unsubscribe();
clearErrors();
};

// running cleanup when unmounting the component
return cleanup;
};

export const depsMapper = (context, actions) => ({
Expand All @@ -18,6 +35,6 @@ export const depsMapper = (context, actions) => ({
});

export default composeAll(
composeWithTracker(composer),
compose(composer),
useDeps(depsMapper)
)(Component);
2 changes: 2 additions & 0 deletions client/modules/comments/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import methodStubs from './configs/method_stubs';
import actions from './actions';
import reducers from './configs/reducers';

export default {
actions,
reducers,
load(context) {
methodStubs(context);
}
Expand Down
22 changes: 16 additions & 6 deletions client/modules/core/actions/posts.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,33 @@
export default {
create({Meteor, LocalState, FlowRouter}, title, content) {
create({Meteor, Store, FlowRouter}, title, content) {
if (!title || !content) {
return LocalState.set('SAVING_ERROR', 'Title & Content are required!');
return Store.dispatch({
type: 'SET_SAVING_POST_ERROR',
error: 'Title & Content are required!'
});
}

LocalState.set('SAVING_ERROR', null);
Store.dispatch({
type: 'CLEAR_SAVING_POST_ERROR'
});

const id = Meteor.uuid();
// There is a method stub for this in the config/method_stubs
// That's how we are doing latency compensation
Meteor.call('posts.create', id, title, content, (err) => {
if (err) {
return LocalState.set('SAVING_ERROR', err.message);
return Store.dispatch({
type: 'SET_SAVING_POST_ERROR',
error: err.message
});
}
});
FlowRouter.go(`/post/${id}`);
},

clearErrors({LocalState}) {
return LocalState.set('SAVING_ERROR', null);
clearErrors({Store}) {
return Store.dispatch({
type: 'CLEAR_SAVING_POST_ERROR'
});
}
};
5 changes: 5 additions & 0 deletions client/modules/core/configs/reducers/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import posts from './posts';

export default {
posts
}
19 changes: 19 additions & 0 deletions client/modules/core/configs/reducers/posts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const defaultState = { SAVING_POST_ERROR: null};
const postsReducer = (state = defaultState, action) => {
switch(action.type) {
case 'SET_SAVING_POST_ERROR':
return {
...state,
SAVING_POST_ERROR: action.error
};
case 'CLEAR_SAVING_POST_ERROR':
return {
...state,
SAVING_POST_ERROR: null
};
default:
return state;
}
};

export default postsReducer;
28 changes: 22 additions & 6 deletions client/modules/core/containers/newpost.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,29 @@
import NewPost from '../components/newpost.jsx';
import {useDeps, composeWithTracker, composeAll} from 'mantra-core';
import {useDeps, compose, composeAll} from 'mantra-core';

export const composer = ({context, clearErrors}, onData) => {
const {LocalState} = context();
const error = LocalState.get('SAVING_ERROR');
const {Store} = context();

// subscribe to state updates
// and keep handle to unsubscribe
const unsubscribe = Store.subscribe(() => {
const error = Store.getState().posts.SAVING_POST_ERROR;
onData(null, {error})
});

// get initial state
const error = Store.getState().posts.SAVING_POST_ERROR;
onData(null, {error});

// clearErrors when unmounting the component
return clearErrors;
// function to unsubscribe from Store
// and clearing error
const cleanup = () => {
unsubscribe();
clearErrors();
};

// running cleanup when unmounting the component
return cleanup;
};

export const depsMapper = (context, actions) => ({
Expand All @@ -17,6 +33,6 @@ export const depsMapper = (context, actions) => ({
});

export default composeAll(
composeWithTracker(composer),
compose(composer),
useDeps(depsMapper)
)(NewPost);
2 changes: 2 additions & 0 deletions client/modules/core/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import methodStubs from './configs/method_stubs';
import actions from './actions';
import routes from './routes.jsx';
import reducers from './configs/reducers';

export default {
routes,
actions,
reducers,
load(context) {
methodStubs(context);
}
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@
"mantra-core": "^1.2.0",
"react": "^0.14.6",
"react-dom": "^0.14.6",
"react-mounter": "^1.0.0"
"react-mounter": "^1.0.0",
"redux": "^3.3.1"
},
"private": true
}