Skip to content

Commit

Permalink
refactor all code feature comment and add load more, design profile
Browse files Browse the repository at this point in the history
  • Loading branch information
ducga1998 committed Jan 10, 2019
1 parent 31c9f85 commit b1ca6e9
Show file tree
Hide file tree
Showing 16 changed files with 271 additions and 177 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"@types/react-router": "^4.4.1",
"@types/styled-components": "^4.0.3",
"apollo-boost": "^0.1.20",
"apollo-cache-inmemory": "^1.3.12",
"autoprefixer": "7.1.6",
"babel-jest": "20.0.3",
"babel-loader": "7.1.2",
Expand Down
16 changes: 15 additions & 1 deletion src/API/client.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,22 @@
import ApolloClient from "apollo-boost";
import gql from "graphql-tag";
import { convertDataToGraphQL } from "../help/help";
import {InMemoryCache} from 'apollo-cache-inmemory'
const defaultOptions = {
watchQuery: {
fetchPolicy: 'network-only',
errorPolicy: 'ignore',
},
query: {
fetchPolicy: 'network-only',
errorPolicy: 'all',
},
}
const cache = new InMemoryCache();
export const client = new ApolloClient({
uri: "http://localhost:3000/graphql"
uri: "http://localhost:3000/graphql",

// defaultOptions : defaultOptions
})
export function logoutBackend() {
return new Promise(resolve => {
Expand Down
4 changes: 3 additions & 1 deletion src/API/commentAPI.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ export function addComment(input: { idComment : string , idUser: string, idArti
variables: {
input
}
})
},

)

// const { data: { addCommentIntoArticle } } = API
resolve(convertDataToGraphQL(API));
Expand Down
3 changes: 3 additions & 0 deletions src/Components/UI/UIButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ export default function UIButton({ type , to,
>{children}
</ButtonLink>
}
if(isLoading) {
return <Spinner />
}
return <Button
data-active={active || undefined}
data-keyButton={keyButton}
Expand Down
4 changes: 1 addition & 3 deletions src/Components/UI/UIModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,7 @@ export default function UIModal({ trigger, children, title, width, height, c
<$Header><H1>{title ? title : 'Header Modal '}</H1></$Header>
<$Content height={height} width={width}> {children}</$Content>

<$Footer>
<UIButton width="100px" onMouseDown={(e: any) => { e.stopPropagation(); closeMoDal() }}> Close </UIButton>
</$Footer>

</$Modal>
</$Background>
</UIWidget> </>
Expand Down
2 changes: 2 additions & 0 deletions src/Components/styled/base.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@ export const Span = styled.span`
`;
// hoizatal
export const FlexRow = styled.div`
${fontStack};
display: flex;
flex-direction: row;
justify-content: flex-start;
Expand All @@ -293,6 +294,7 @@ export const FlexRow = styled.div`
`;
// vectical
export const FlexCol = styled.div`
${fontStack};
display: flex;
flex-direction: column;
justify-content: flex-start;
Expand Down
2 changes: 1 addition & 1 deletion src/Components/styled/button.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ const baseButton = css`
process.env.NODE_ENV === 'production'
? theme.text.placeholder
: theme.warn.border};
color: ${theme.text.reverse};
/* color: ${theme.text.reverse}; */
transition: ${Transition.hover.on};
}
}
Expand Down
62 changes: 38 additions & 24 deletions src/Views/Article/ReadArticle/FormComment.tsx
Original file line number Diff line number Diff line change
@@ -1,63 +1,77 @@

import UIButton from '../../../Components/UI/UIButton';

import MediumEditer from 'medium-editor'
import * as React from 'react'
import { IMAGE_SOURCE_DEFAULT } from '../../../help/define';
import { Config } from '../../../help/config';
import styled from 'styled-components';

import { toast } from 'react-toastify';
import userContainer from '../../../Container/userContainer';
import { socketNotication } from '../../../socketClient/socket';
import commentAllContainer from '../../../Container/commentContainer';
import { renderElement } from '../../../Core/renderElement';
import { Input, FlexCol, FlexRow } from '../../../Components/styled/base';
import { AvatarImage } from '../../../Components/styled/avatar';
import uuid from 'uuid'
import { addComment } from '../../../API/commentAPI';
interface IFormRely {
context : any ,
idRely ?:string,
onChange ?: (event : any) => any
context: any,
idRely?: string,
onChange: (event: any) => any
}
const FormComment = ({ context , idRely , onChange }: IFormRely ) => {
const FormComment = ({ context, idRely, onChange }: IFormRely) => {
const [content, setContent] = React.useState('')
const { idArticle } = context
const { avatarLink} = userContainer.state.dataUser
const { avatarLink, name } = userContainer.state.dataUser
const handleAddComment = async () => {
if ( content === '') {
if (content === '') {
toast.error('Comment not empty !!!. Please write something ')
return
}
let input = {
content,
idUser: userContainer.state.dataUser.idUser,
idArticle,

} as any
if(idRely && onChange ){
console.log('da co id rely ' ,idRely)
input = {...input , ...{idRely}}
onChange(input)
if (idRely && onChange) {
input = { ...input, ...{ idRely } }

}
const {user : {idUser}} = context
socketNotication({ content,idUser },idRely?'RelyComment':'Comment')

await commentAllContainer.addCommentInArticle(input) // function handle request to backend and add data to commentAllContainer
const { user: { idUser } } = context
// socket notification from backend
socketNotication({ content, idUser }, idRely ? 'RelyComment' : 'Comment')
setContent('')
const idComment = uuid()
let newComment = await addComment({...input , ...{idComment}}) as any
console.log('newComment',newComment)
newComment = {
...newComment ,...{userComment : {avatarLink,name}}
}

onChange(newComment)
}
function handleKeyPress (event) {
if(event.charCode === 13){
function handleKeyPress(event) {
if (event.charCode === 13) {
handleAddComment()
}

}
return <$Aglin >
<FlexRow>
<Avatar className="smallAvatar" src={avatarLink ? avatarLink : IMAGE_SOURCE_DEFAULT} /> <b>{name}</b>
<Avatar
className="smallAvatar"
src={avatarLink ? avatarLink : IMAGE_SOURCE_DEFAULT} /> <b>{name}
</b>
</FlexRow>
<WrapperFromComment>
<$FormComment placeholder="Comment something ....." value={content} onKeyPress={handleKeyPress} onChange={ e => setContent(e.target.value)} />
<UIButton style={{flex : 2}} onMouseDown={handleAddComment} >Comment</UIButton>
<$FormComment placeholder="Comment something ....."
value={content}
onKeyPress={handleKeyPress}
onChange={e => setContent(e.target.value)} />
<UIButton
style={{ flex: 2 }}
onMouseDown={handleAddComment}>Comment
</UIButton>
</WrapperFromComment>
</$Aglin>

Expand Down
109 changes: 63 additions & 46 deletions src/Views/Article/ReadArticle/comment.tsx
Original file line number Diff line number Diff line change
@@ -1,67 +1,86 @@
import * as React from 'react';
import renderHTML from 'react-render-html';
import styled from 'styled-components';
// import { FormComment } from './writeComment';
import { Subscribe } from 'unstated-x';
import commentAllContainer from '../../../Container/commentContainer';
import UILoading from '../../../Components/UI/UILoading';
import { Config } from '../../../help/config';
import MediumEditer from 'medium-editor';
import { IMAGE_SOURCE_DEFAULT } from '../../../help/define';
import FormComment from './FormComment';
import { AvatarImage } from '../../../Components/styled/avatar';
import { H2 } from '../../../Components/styled/base';
import userContainer from '../../../Container/userContainer';
import { getAllCommentinArtcileCurrent } from '../../../API/commentAPI';
import UIButton from '../../../Components/UI/UIButton';
import { StyledTextButton } from '../../../Components/styled/button';
interface IViewComment {
idArticle: string,

}
export default class ViewComment extends React.Component<IViewComment> {

state = {
allComments: [],
offset: 0,
isFetch: true
}
async componentDidMount() {
const first = 5
const { idArticle } = this.props
const allComments = await getAllCommentinArtcileCurrent(idArticle, first, this.state.offset)
this.setState({ allComments })
}
handleComment = (comment) => {
this.setState({
allComments: [
comment,
...this.state.allComments,
]
})
}
handleLoadMore = async () => {
const { idArticle } = this.props
const first = 5
const offset = this.state.offset + first
const newArrComment = await getAllCommentinArtcileCurrent(idArticle, first, offset) as any[]
if (newArrComment.length === 0) {
this.setState({ isFetch: false })
}
this.setState({ allComments: [...this.state.allComments, ...newArrComment], offset })
}
render() {

return <Subscribe to={[commentAllContainer]}>
{
() => {
const { idArticle } = this.props
const data = commentAllContainer.state.registryComment.find(item => item.idArticle === idArticle)
if (!data) {
return <UILoading />
}
const { commentContainer } = data
return <Subscribe to={[commentContainer]}>
{
() => {
const { allComments } = commentContainer.state
return <WrapperComment>
{allComments.length > 0 ? allComments.map((item: any, key) => {
const { idRely } = item
let dataRely
if (!idRely) {
// loop all comment, find idComment === idRely
dataRely = allComments.filter(comment => {
if (comment.idRely) {
return comment.idRely === item.idComment
}
})
}
return <Comment dataUserComment={item} relyComment={dataRely && dataRely.length > 0 ? dataRely : undefined} />
}) :
<H2 style={{ textAlign: 'center', color: 'gray' }}> NO Comment, : ))) cmt vào cho vui đi thằng ngu</H2>
}
</WrapperComment>
const { allComments, isFetch } = this.state
if (allComments.length < 0) {
return <UIButton isLoading />
}
return <>
<FormComment onChange={(comment) => { this.handleComment(comment) }} />
<WrapperComment>
<> {allComments.length > 0 ? allComments.map((item: any, key) => {
const { idRely } = item
let dataRely
if (!idRely) {
// loop all comment, find idComment === idRely
dataRely = allComments.filter((comment: any) => {
if (comment.idRely) {
return comment.idRely === item.idComment
}
}
</Subscribe>
})
}
return <Comment dataUserComment={item} relyComment={dataRely && dataRely.length > 0 ? dataRely : undefined} />
}) :
<H2 style={{ textAlign: 'center', color: 'gray' }}> NO Comment, : ))) cmt vào cho vui đi thằng ngu</H2>
}
}
</Subscribe>

{isFetch ? <LoadMoreButton onMouseDown={this.handleLoadMore}>Load More </LoadMoreButton> : null}
</>
</WrapperComment>
</>

}
}
// comment only comment => we handle data coment a here
const WrapperComment = styled.div`
const WrapperComment = styled.div``
const LoadMoreButton = styled(StyledTextButton)`
display : block;
margin : auto;
`
const Comment = ({ dataUserComment, relyComment }: { dataUserComment: any, relyComment?: any }) => {
const [open, setOpen] = React.useState(false)
Expand All @@ -71,7 +90,6 @@ const Comment = ({ dataUserComment, relyComment }: { dataUserComment: any, relyC
return commentRely.map(comment => {
const { userComment: { avatarLink, name }, createdAt, content, idComment } = comment
return <$Comment data-id={idComment} data-tooltip={`Created At : ${new Date(createdAt)}`}>
<b> ---- </b>
<AvatarImage data-tooltip={name} src={avatarLink ? avatarLink : IMAGE_SOURCE_DEFAULT} />
<$Content >{renderHTML(content)}</$Content>
</$Comment>
Expand All @@ -80,7 +98,6 @@ const Comment = ({ dataUserComment, relyComment }: { dataUserComment: any, relyC
function addCommentRely(rely) {
const { avatarLink, name } = userContainer.state.dataUser
rely = { ...rely, ...{ userComment: { avatarLink, name } } };

dataRely.push(rely); setDataRely(dataRely)
}

Expand Down Expand Up @@ -135,10 +152,10 @@ const $Comment = styled.div`
border-bottom: 1px solid ${props => props.theme.bg.border};
display : flex;
/* margin : 30px 0px 0px; */
padding: 30px;
padding: 30px 0px 30px 60px;
&:hover {
background: ${props => props.theme.bg.wash};
transition: 0.3s;
border-radius: 10px;
}
`
`
Loading

0 comments on commit b1ca6e9

Please sign in to comment.