Skip to content
This repository was archived by the owner on Mar 3, 2020. It is now read-only.

Commit c5bc150

Browse files
committed
Show basic info in user history item
1 parent 427865f commit c5bc150

File tree

6 files changed

+116
-49
lines changed

6 files changed

+116
-49
lines changed

velog-backend/src/router/users/users.ctrl.js

+4-9
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
} from 'database/models';
1313
import { pick } from 'lodash';
1414
import { getUserHistory } from 'database/rawQuery/users';
15-
import { normalize } from 'lib/common';
15+
import { normalize, formatShortDescription } from 'lib/common';
1616

1717
const { Op } = Sequelize;
1818

@@ -84,7 +84,6 @@ export const getHistory: KoaRouter$Middleware = async (ctx) => {
8484
include: [
8585
{
8686
model: Post,
87-
attributes: ['title', 'fk_user_id', 'url_slug', 'thumbnail'],
8887
include: [
8988
{
9089
model: User,
@@ -104,13 +103,6 @@ export const getHistory: KoaRouter$Middleware = async (ctx) => {
104103
include: [
105104
{
106105
model: Post,
107-
attributes: [
108-
'title',
109-
'fk_user_id',
110-
'url_slug',
111-
'thumbnail',
112-
'created_at',
113-
],
114106
include: [
115107
{
116108
model: User,
@@ -131,6 +123,9 @@ export const getHistory: KoaRouter$Middleware = async (ctx) => {
131123
...pick(row, ['id', 'text']),
132124
post: {
133125
...pick(row.post, ['title', 'url_slug', 'thumbnail', 'created_at']),
126+
short_description:
127+
row.post.meta.short_description ||
128+
formatShortDescription(row.post.body),
134129
user: {
135130
username: row.post.user.username,
136131
...pick(row.post.user.user_profile, ['display_name', 'thumbnail']),

velog-frontend/src/components/user/UserHistory/UserHistory.js

+40-33
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,66 @@
11
// @flow
2-
import React, { Component } from 'react';
2+
import React, { Component, Fragment } from 'react';
33
import CommentIcon from 'react-icons/lib/fa/comment';
44
import HeartIcon from 'react-icons/lib/fa/heart';
5+
import { type UserHistoryItem } from 'store/modules/profile';
56
import './UserHistory.scss';
67

78
type HistoryItemProps = {
8-
type: 'comment' | 'like',
9+
item: UserHistoryItem,
910
};
1011

11-
const HistoryItem = ({ type }: HistoryItemProps) => {
12+
const HistoryItem = ({ item }: HistoryItemProps) => {
13+
const { type } = item;
1214
return (
1315
<div className="HistoryItem">
14-
<div className="message">
15-
<CommentIcon className="comment" />@velopert님이 댓글을 남기셨습니다.
16-
</div>
17-
<div className="mini-postcard">
18-
<div className="thumbnail">
19-
<img
20-
src="https://thumb.velog.io/resize?url=https://images.velog.io/post-images/clarekang/75978a70-c53e-11e8-a8ba-eb98e52ccb66/cucumber.jpg&width=512"
21-
alt="thumbnail"
22-
/>
16+
{type === 'comment' ? (
17+
<div className="message">
18+
<CommentIcon className="comment" />@velopert님이 댓글을 남기셨습니다.
2319
</div>
24-
<div className="separator" />
20+
) : (
21+
<div className="message">
22+
<HeartIcon className="heart" />
23+
@velopert님이 이 포스트를 좋아합니다.
24+
</div>
25+
)}
26+
<div className="mini-postcard">
27+
{item.post.thumbnail && (
28+
<Fragment>
29+
<div className="thumbnail">
30+
<img src={item.post.thumbnail} alt="thumbnail" />
31+
</div>
32+
<div className="separator" />
33+
</Fragment>
34+
)}
2535
<div className="post-info">
26-
<h4>제목이라능</h4>
36+
<h4>{item.post.title}</h4>
2737
<p>
28-
쇼트 디스립션은 한 100자정도만 보여줄꺼지롱 나는 아무거나 쓸건데 이걸 쓰는 동안에는
29-
오타를 엄청나게 많이 낼 것이다. 왜냐하면 나는 아무 생각없이 쓰고 있기때문이고 지금 사실
30-
눈을 감고있다. 지금 드는 감정에 대해서 묘사를 하자면 음파음파 꼬르르이다.
38+
{item.post.short_description.slice(0, 150)}
39+
{item.post.short_description.length >= 150 && '...'}
3140
</p>
3241
</div>
3342
</div>
34-
<div className="comment-block">
35-
<div className="mark"></div>
36-
<div className="comment-text">
37-
제 생각엔 제가 댓글을 달았는데 그게 진짜 댓글이 아니더라구요.. ㄷ 근데 문제는 그게
38-
무슨소리인지 모르겠다는거에요.
43+
{type === 'comment' && (
44+
<div className="comment-block">
45+
<div className="mark"></div>
46+
<div className="comment-text">{item.text}</div>
3947
</div>
40-
</div>
48+
)}
4149
</div>
4250
);
4351
};
4452

45-
type Props = {};
53+
type Props = {
54+
username: string,
55+
data: UserHistoryItem[],
56+
};
4657
class UserHistory extends Component<Props> {
58+
renderList() {
59+
const { username, data } = this.props;
60+
return data.map(item => <HistoryItem username={username} item={item} key={item.id} />);
61+
}
4762
render() {
48-
return (
49-
<div className="UserHistory">
50-
<HistoryItem type="comment" />
51-
<HistoryItem type="comment" />
52-
<HistoryItem type="comment" />
53-
<HistoryItem type="comment" />
54-
<HistoryItem type="like" />
55-
</div>
56-
);
63+
return <div className="UserHistory">{this.renderList()}</div>;
5764
}
5865
}
5966

velog-frontend/src/components/user/UserHistory/UserHistory.scss

+6-3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
.HistoryItem {
66
padding-top: 2rem;
77
padding-bottom: 2rem;
8+
& + .HistoryItem {
9+
border-top: 1px solid $oc-gray-2;
10+
}
811
.message {
912
display: flex;
1013
align-items: center;
@@ -72,9 +75,9 @@
7275
}
7376
.comment-text {
7477
font-family: "Noto Serif KR", sans-serif;
75-
padding-top: 1rem;
76-
padding-left: 2rem;
78+
padding-top: 0.5rem;
79+
padding-left: 1.5rem;
7780
}
7881
}
7982
}
80-
}
83+
}
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,50 @@
11
// @flow
22
import React, { Component } from 'react';
3+
import { connect } from 'react-redux';
34
import { ProfileActions } from 'store/actionCreators';
45
import UserHistory from 'components/user/UserHistory/UserHistory';
6+
import { withRouter, type ContextRouter } from 'react-router-dom';
7+
import { compose } from 'redux';
8+
import { type State } from 'store';
9+
import { type UserHistoryItem } from 'store/modules/profile';
510

6-
type Props = {};
11+
type Props = {
12+
userHistory: ?(UserHistoryItem[]),
13+
} & ContextRouter;
714
class UserHistoryContainer extends Component<Props> {
15+
initialize = async () => {
16+
const { match } = this.props;
17+
const { username } = match.params;
18+
try {
19+
if (!username) return;
20+
await ProfileActions.getUserHistory(username);
21+
} catch (e) {
22+
console.log(e);
23+
}
24+
};
825
componentDidMount() {
9-
console.log('helloworld');
1026
ProfileActions.setSideVisibility(false);
27+
this.initialize();
1128
}
1229
componentWillUnmount() {
1330
ProfileActions.setSideVisibility(true);
1431
}
1532

1633
render() {
17-
return <UserHistory />;
34+
const { userHistory, match } = this.props;
35+
if (!userHistory) return null;
36+
return <UserHistory data={userHistory} username={match.params.username || ''} />;
1837
}
1938
}
2039

21-
export default UserHistoryContainer;
40+
const enhance = compose(
41+
withRouter,
42+
connect(
43+
({ profile }: State) => ({
44+
userHistory: profile.userHistory,
45+
}),
46+
() => ({}),
47+
),
48+
);
49+
50+
export default enhance(UserHistoryContainer);

velog-frontend/src/lib/api/users.js

+1
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ import axios from 'lib/defaultClient';
33

44
export const listUserTags = (username: string) => axios.get(`/users/@${username}/tags`);
55
export const getProfile = (username: string) => axios.get(`/users/@${username}`);
6+
export const getHistory = (username: string) => axios.get(`/users/@${username}/history`);

velog-frontend/src/store/modules/profile.js

+32
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const SET_RAW_TAG_NAME = 'profile/SET_RAW_TAG_NAME';
1111
const GET_TAG_INFO = 'profile/GET_TAG_INFO';
1212
const INITIALIZE = 'profile/INITIALIZE';
1313
const SET_SIDE_VISIBILITY = 'profile/SET_SIDE_VISIBILITY';
14+
const GET_USER_HISTORY = 'profile/GET_USER_HISTORY';
1415

1516
export const actionCreators = {
1617
initialize: createAction(INITIALIZE),
@@ -19,6 +20,7 @@ export const actionCreators = {
1920
setRawTagName: createAction(SET_RAW_TAG_NAME, (tagName: string) => tagName),
2021
getTagInfo: createAction(GET_TAG_INFO, CommonAPI.getTagInfo),
2122
setSideVisibility: createAction(SET_SIDE_VISIBILITY, (visible: boolean) => visible),
23+
getUserHistory: createAction(GET_USER_HISTORY, UsersAPI.getHistory),
2224
};
2325

2426
export type TagCountInfo = {
@@ -53,13 +55,33 @@ type ProfileResponseAction = {
5355
},
5456
};
5557

58+
export type UserHistoryItem = {
59+
id: string,
60+
created: string,
61+
type: 'comment' | 'like',
62+
text: ?string,
63+
post: {
64+
title: string,
65+
url_slug: string,
66+
thumbnail: string,
67+
short_description: string,
68+
user: {
69+
username: string,
70+
display_name: string,
71+
thumbnail: string,
72+
},
73+
},
74+
};
75+
5676
type SetRawTagNameAction = ActionType<typeof actionCreators.setRawTagName>;
5777
type GetTagInfoResponseAction = GenericResponseAction<TagData, string>;
5878
type SetSideVisibilityAction = ActionType<typeof actionCreators.setSideVisibility>;
79+
type GetUserHistoryResponseAction = GenericResponseAction<UserHistoryItem[], any>;
5980

6081
export type ProfileState = {
6182
tagCounts: ?(TagCountInfo[]),
6283
profile: ?Profile,
84+
userHistory: ?(UserHistoryItem[]),
6385
rawTagName: ?string,
6486
side: boolean,
6587
};
@@ -68,6 +90,7 @@ const initialState = {
6890
tagCounts: null,
6991
profile: null,
7092
rawTagName: null,
93+
userHistory: null,
7194
side: true,
7295
};
7396

@@ -124,4 +147,13 @@ export default applyPenders(reducer, [
124147
};
125148
},
126149
},
150+
{
151+
type: GET_USER_HISTORY,
152+
onSuccess: (state: ProfileState, { payload }: GetUserHistoryResponseAction) => {
153+
return {
154+
...state,
155+
userHistory: payload.data,
156+
};
157+
},
158+
},
127159
]);

0 commit comments

Comments
 (0)