mirror of
https://github.com/wassname/talk.git
synced 2026-07-01 05:08:43 +08:00
Items cleanup
This commit is contained in:
@@ -181,7 +181,6 @@ class Embed extends Component {
|
||||
}
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
items: state.items.toJS(),
|
||||
notification: state.notification.toJS(),
|
||||
auth: state.auth.toJS(),
|
||||
userData: state.user.toJS()
|
||||
|
||||
@@ -1,25 +1,3 @@
|
||||
|
||||
fragment commentView on Comment {
|
||||
id
|
||||
body
|
||||
created_at
|
||||
user {
|
||||
id
|
||||
name: displayName
|
||||
settings {
|
||||
bio
|
||||
}
|
||||
}
|
||||
actions {
|
||||
type: action_type
|
||||
count
|
||||
current: current_user {
|
||||
id
|
||||
created_at
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
query AssetQuery($asset_url: String!) {
|
||||
asset(url: $asset_url) {
|
||||
id
|
||||
|
||||
@@ -3,7 +3,6 @@ import translations from './../translations';
|
||||
const lang = new I18n(translations);
|
||||
import * as actions from '../constants/auth';
|
||||
import coralApi, {base} from '../helpers/response';
|
||||
import {addItem} from './items';
|
||||
|
||||
// Dialog Actions
|
||||
export const showSignInDialog = (offset = 0) => ({type: actions.SHOW_SIGNIN_DIALOG, offset});
|
||||
@@ -30,7 +29,6 @@ export const fetchSignIn = (formData) => (dispatch) => {
|
||||
const isAdmin = !!user.roles.filter(i => i === 'ADMIN').length;
|
||||
dispatch(signInSuccess(user, isAdmin));
|
||||
dispatch(hideSignInDialog());
|
||||
dispatch(addItem(user, 'users'));
|
||||
})
|
||||
.catch(() => dispatch(signInFailure(lang.t('error.emailPasswordError'))));
|
||||
};
|
||||
@@ -59,7 +57,6 @@ export const facebookCallback = (err, data) => dispatch => {
|
||||
const user = JSON.parse(data);
|
||||
dispatch(signInFacebookSuccess(user));
|
||||
dispatch(hideSignInDialog());
|
||||
dispatch(addItem(user, 'users'));
|
||||
} catch (err) {
|
||||
dispatch(signInFacebookFailure(err));
|
||||
return;
|
||||
|
||||
@@ -1,268 +0,0 @@
|
||||
import coralApi from '../helpers/response';
|
||||
import {fromJS} from 'immutable';
|
||||
import {UPDATE_CONFIG} from '../constants/config';
|
||||
|
||||
/**
|
||||
* Action name constants
|
||||
*/
|
||||
|
||||
export const ADD_ITEM = 'ADD_ITEM';
|
||||
export const UPDATE_ITEM = 'UPDATE_ITEM';
|
||||
export const APPEND_ITEM_ARRAY = 'APPEND_ITEM_ARRAY';
|
||||
|
||||
/**
|
||||
* Action creators
|
||||
*/
|
||||
|
||||
/*
|
||||
* Adds an item to the local store without posting it to the server
|
||||
* Useful for optimistic posting, etc.
|
||||
*
|
||||
* @params
|
||||
* item - the item to be posted
|
||||
*
|
||||
*/
|
||||
|
||||
export const addItem = (item, item_type) => {
|
||||
if (!item.id) {
|
||||
console.warn('addItem called without an item id.');
|
||||
}
|
||||
return {
|
||||
type: ADD_ITEM,
|
||||
item,
|
||||
item_type,
|
||||
id: item.id
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
* Updates an item in the local store without posting it to the server
|
||||
* Useful for item-level toggles, etc.
|
||||
*
|
||||
* @params
|
||||
* id - the id of the item to be posted
|
||||
* property - the property to be updated
|
||||
* value - the value that the property should be set to
|
||||
* item_type - the type of the item being updated (users, comments, etc)
|
||||
*
|
||||
*/
|
||||
export const updateItem = (id, property, value, item_type) => {
|
||||
return {
|
||||
type: UPDATE_ITEM,
|
||||
id,
|
||||
property,
|
||||
value,
|
||||
item_type
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
* Appends data to an array in an item in the local store without posting it to the server
|
||||
* Useful for adding a recently posted reply to a comment, etc.
|
||||
*
|
||||
* @params
|
||||
* id - the id of the item to be posted
|
||||
* property - the property to be updated (should be an array)
|
||||
* value - the value that should be added to the array
|
||||
* add_to_front - boolean that defines whether value is added at the beginning (unshift) or end (push)
|
||||
* item_type - the type of the item being updated (users, comments, etc)
|
||||
*
|
||||
*/
|
||||
export const appendItemArray = (id, property, value, add_to_front, item_type) => {
|
||||
return {
|
||||
type: APPEND_ITEM_ARRAY,
|
||||
id,
|
||||
property,
|
||||
value,
|
||||
add_to_front,
|
||||
item_type
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
* Get Items from Query
|
||||
* Gets a set of items from a predefined query
|
||||
*
|
||||
* @params
|
||||
* Query - a predefiend query for retreiving items
|
||||
*
|
||||
* @returns
|
||||
* A promise resolving to a set of items
|
||||
*
|
||||
* @dispatches
|
||||
* A set of items to the item store
|
||||
*/
|
||||
export function getStream (assetUrl) {
|
||||
return (dispatch) => {
|
||||
return coralApi(`/stream?asset_url=${encodeURIComponent(assetUrl)}`)
|
||||
.then((json) => {
|
||||
|
||||
/* Add items to the store */
|
||||
Object.keys(json).forEach(type => {
|
||||
if (type === 'actions') {
|
||||
json[type].forEach(action => {
|
||||
action.id = `${action.action_type}_${action.item_id}`;
|
||||
dispatch(addItem(action, 'actions'));
|
||||
});
|
||||
} else if (type === 'settings') {
|
||||
dispatch({type: UPDATE_CONFIG, config: fromJS(json[type])});
|
||||
} else {
|
||||
json[type].forEach(item => {
|
||||
dispatch(addItem(item, type));
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const assetId = json.assets[0].id;
|
||||
|
||||
/* Sort comments by date*/
|
||||
json.comments.sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());
|
||||
const rels = json.comments.reduce((h, item) => {
|
||||
|
||||
/* Check for root and child comments. */
|
||||
if (
|
||||
item.asset_id === assetId &&
|
||||
!item.parent_id) {
|
||||
h.rootComments.push(item.id);
|
||||
} else if (
|
||||
item.asset_id === assetId
|
||||
) {
|
||||
let children = h.childComments[item.parent_id] || [];
|
||||
h.childComments[item.parent_id] = children.concat(item.id);
|
||||
}
|
||||
return h;
|
||||
}, {rootComments: [], childComments: {}});
|
||||
|
||||
dispatch(updateItem(assetId, 'comments', rels.rootComments, 'assets'));
|
||||
|
||||
Object.keys(rels.childComments).forEach(key => {
|
||||
dispatch(updateItem(key, 'children', rels.childComments[key].reverse(), 'comments'));
|
||||
});
|
||||
|
||||
/* Hydrate actions on comments */
|
||||
json.actions.forEach(action => {
|
||||
dispatch(updateItem(action.item_id, action.action_type, action.id, 'comments'));
|
||||
});
|
||||
|
||||
return (json);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* Get Items Array
|
||||
* Gets a set of items from an array of item ids
|
||||
*
|
||||
* @params
|
||||
* Query - a predefiend query for retreiving items
|
||||
*
|
||||
* @returns
|
||||
* A promise resolving to a set of items
|
||||
*
|
||||
* @dispatches
|
||||
* A set of items to the item store
|
||||
*/
|
||||
|
||||
export function getItemsArray (ids) {
|
||||
return (dispatch) => {
|
||||
return coralApi(`/item/${ids}`)
|
||||
.then((json) => {
|
||||
for (let i = 0; i < json.items.length; i++) {
|
||||
dispatch(addItem(json.items[i]));
|
||||
}
|
||||
return json.items;
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* PutItem
|
||||
* Puts an item
|
||||
*
|
||||
* @params
|
||||
* Item - the item to be put
|
||||
*
|
||||
* @returns
|
||||
* A promise resolving to an item is
|
||||
*
|
||||
* @dispatches
|
||||
* The newly put item to the item store
|
||||
*/
|
||||
|
||||
export function postItem (item, type, id, mutate) {
|
||||
console.log(
|
||||
item,
|
||||
type,
|
||||
id,
|
||||
mutate
|
||||
);
|
||||
mutate({
|
||||
variables: {
|
||||
asset_id: id,
|
||||
body: item,
|
||||
parent_id: null
|
||||
}
|
||||
}).then(({data}) => {
|
||||
console.log('it workt');
|
||||
console.log(data);
|
||||
});
|
||||
|
||||
// return (dispatch) => {
|
||||
// if (id) {
|
||||
// item.id = id;
|
||||
// }
|
||||
// return coralApi(`/${type}`, {method: 'POST', body: item})
|
||||
// .then((json) => {
|
||||
// dispatch(addItem({...item, id:json.id}, type));
|
||||
// return json;
|
||||
// });
|
||||
// };
|
||||
}
|
||||
|
||||
/*
|
||||
* PostAction
|
||||
* Posts an action to an item
|
||||
*
|
||||
* @params
|
||||
* id - the id of the item on which the action is taking place
|
||||
* action - the action object.
|
||||
* Must include an 'action_type' string.
|
||||
* May optionally include a `metadata` object with arbitrary action data.
|
||||
* user - the user performing the action
|
||||
* host - the coral host
|
||||
*
|
||||
* @returns
|
||||
* A promise resolving to null or an error
|
||||
*
|
||||
*/
|
||||
|
||||
export function postAction (item_id, item_type, action) {
|
||||
return (dispatch) => {
|
||||
return coralApi(`/${item_type}/${item_id}/actions`, {method: 'POST', body: action})
|
||||
.then((json) => {
|
||||
dispatch(updateItem(action.item_id, action.action_type, action.id, item_type));
|
||||
return json;
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* DeleteAction
|
||||
* Deletes an action to an item
|
||||
*
|
||||
* @params
|
||||
* id - the id of the item on which the action is taking place
|
||||
* action - the name of the action
|
||||
* user - the user performing the action
|
||||
* host - the coral host
|
||||
*
|
||||
* @returns
|
||||
* A promise resolving to null or an error
|
||||
*
|
||||
*/
|
||||
|
||||
export function deleteAction (action_id) {
|
||||
return () => {
|
||||
return coralApi(`/actions/${action_id}`, {method: 'DELETE'});
|
||||
};
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
import * as actions from '../constants/user';
|
||||
import * as assetActions from '../constants/assets';
|
||||
import {addNotification} from '../actions/notification';
|
||||
import {addItem} from '../actions/items';
|
||||
import coralApi from '../helpers/response';
|
||||
|
||||
import I18n from 'coral-framework/modules/i18n/i18n';
|
||||
@@ -30,27 +29,5 @@ export const saveBio = (user_id, formData) => dispatch => {
|
||||
* @returns Promise
|
||||
*/
|
||||
export const fetchCommentsByUserId = userId => {
|
||||
return (dispatch, getState) => {
|
||||
dispatch({type: actions.COMMENTS_BY_USER_REQUEST});
|
||||
return coralApi(`/comments?user_id=${userId}`)
|
||||
.then(({comments, assets}) => {
|
||||
const state = getState();
|
||||
comments.forEach(comment => dispatch(addItem(comment, 'comments')));
|
||||
assets.forEach(asset => {
|
||||
const prevAsset = state.items.getIn(['assets', asset.id]);
|
||||
|
||||
if (prevAsset) {
|
||||
|
||||
// Include data such as hydrated comments from assets already in the system.
|
||||
dispatch(addItem({...prevAsset.toJS(), ...asset}, 'assets'));
|
||||
} else {
|
||||
dispatch(addItem(asset, 'assets'));
|
||||
}
|
||||
});
|
||||
|
||||
dispatch({type: actions.COMMENTS_BY_USER_SUCCESS, comments: comments.map(comment => comment.id)});
|
||||
dispatch({type: assetActions.MULTIPLE_ASSETS_SUCCESS, assets: assets.map(asset => asset.id)});
|
||||
})
|
||||
.catch(error => dispatch({type: actions.COMMENTS_BY_USER_FAILURE, error}));
|
||||
};
|
||||
// TODO
|
||||
};
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
import Notification from './modules/notification/Notification';
|
||||
import store from './store';
|
||||
import * as itemActions from './actions/items';
|
||||
import pym from './PymConnection';
|
||||
import I18n from './modules/i18n/i18n';
|
||||
import * as notificationActions from './actions/notification';
|
||||
import * as authActions from './actions/auth';
|
||||
import * as assetActions from './actions/asset';
|
||||
import pym from './PymConnection';
|
||||
import * as notificationActions from './actions/notification';
|
||||
import Notification from './modules/notification/Notification';
|
||||
|
||||
export {
|
||||
Notification,
|
||||
store,
|
||||
itemActions,
|
||||
pym,
|
||||
I18n,
|
||||
notificationActions,
|
||||
store,
|
||||
authActions,
|
||||
assetActions,
|
||||
pym
|
||||
Notification,
|
||||
notificationActions
|
||||
};
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
import auth from './auth';
|
||||
import user from './user';
|
||||
import asset from './asset';
|
||||
import items from './items';
|
||||
import notification from './notification';
|
||||
|
||||
export default {
|
||||
auth,
|
||||
user,
|
||||
asset,
|
||||
items,
|
||||
notification
|
||||
};
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
/* Items Reducer */
|
||||
|
||||
import {fromJS} from 'immutable';
|
||||
import * as actions from '../actions/items';
|
||||
|
||||
const initialState = fromJS({
|
||||
comments: {},
|
||||
users: {},
|
||||
assets: {},
|
||||
actions: {}
|
||||
});
|
||||
|
||||
export default (state = initialState, action) => {
|
||||
switch (action.type) {
|
||||
case actions.ADD_ITEM:
|
||||
return state.setIn([action.item_type, action.id], fromJS(action.item));
|
||||
case actions.UPDATE_ITEM:
|
||||
return state.setIn([action.item_type, action.id, action.property], fromJS(action.value));
|
||||
case actions.APPEND_ITEM_ARRAY:
|
||||
return state.updateIn([action.item_type, action.id, action.property], (prop) => {
|
||||
if (action.add_to_front) {
|
||||
return prop ? prop.unshift(fromJS(action.value)) : fromJS([action.value]);
|
||||
} else {
|
||||
return prop ? prop.push(fromJS(action.value)) : fromJS([action.value]);
|
||||
}
|
||||
});
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
@@ -6,7 +6,7 @@ import {saveBio, fetchCommentsByUserId} from 'coral-framework/actions/user';
|
||||
import {link} from 'coral-framework/PymConnection';
|
||||
import BioContainer from './BioContainer';
|
||||
import NotLoggedIn from '../components/NotLoggedIn';
|
||||
import {TabBar, Tab, TabContent} from '../../coral-ui';
|
||||
import {TabBar, Tab, TabContent} from 'coral-ui';
|
||||
import CommentHistory from 'coral-plugin-history/CommentHistory';
|
||||
import SettingsHeader from '../components/SettingsHeader';
|
||||
import RestrictedContent from 'coral-framework/components/RestrictedContent';
|
||||
@@ -26,9 +26,7 @@ class SettingsContainer extends Component {
|
||||
}
|
||||
|
||||
componentWillMount () {
|
||||
|
||||
// Fetch commentHistory
|
||||
this.props.fetchCommentsByUserId(this.props.userData.id);
|
||||
// this.props.fetchCommentsByUserId(this.props.userData.id);
|
||||
}
|
||||
|
||||
handleTabChange(tab) {
|
||||
@@ -41,16 +39,6 @@ class SettingsContainer extends Component {
|
||||
const {loggedIn, userData, showSignInDialog, items, user} = this.props;
|
||||
const {activeTab} = this.state;
|
||||
|
||||
const commentsMostRecentFirst = user
|
||||
.myComments.map(id => items.comments[id])
|
||||
.sort(({created_at:a}, {created_at:b}) => {
|
||||
|
||||
// descending order, created_at
|
||||
// js date strings can be sorted lexigraphically.
|
||||
const aLessThanB = a < b ? 1 : 0;
|
||||
return a > b ? -1 : aLessThanB;
|
||||
});
|
||||
|
||||
return (
|
||||
<RestrictedContent restricted={!loggedIn} restrictedComp={<NotLoggedIn showSignInDialog={showSignInDialog} />}>
|
||||
<SettingsHeader {...this.props} />
|
||||
@@ -59,14 +47,7 @@ class SettingsContainer extends Component {
|
||||
<Tab>Profile Settings</Tab>
|
||||
</TabBar>
|
||||
<TabContent show={activeTab === 0}>
|
||||
{
|
||||
user.myComments.length && user.myAssets.length
|
||||
? <CommentHistory
|
||||
comments={commentsMostRecentFirst}
|
||||
link={link}
|
||||
assets={user.myAssets.map(id => items.assets[id])} />
|
||||
: <p>{lang.t('user-no-comment')}</p>
|
||||
}
|
||||
My comment History
|
||||
</TabContent>
|
||||
<TabContent show={activeTab === 1}>
|
||||
<BioContainer bio={userData.settings.bio} handleSave={this.handleSave} {...this.props} />
|
||||
@@ -77,13 +58,11 @@ class SettingsContainer extends Component {
|
||||
}
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
items: state.items.toJS(),
|
||||
user: state.user.toJS()
|
||||
});
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
saveBio: (user_id, formData) => dispatch(saveBio(user_id, formData)),
|
||||
fetchCommentsByUserId: userId => dispatch(fetchCommentsByUserId(userId))
|
||||
saveBio: (user_id, formData) => dispatch(saveBio(user_id, formData))
|
||||
});
|
||||
|
||||
export default connect(
|
||||
|
||||
Reference in New Issue
Block a user