#reactjs #spring #recursion #animation #css-transitions
Вопрос:
Мне не удалось применить переход к divs в разделе комментариев, над которым я работаю. Раздел комментариев отображается рекурсивно, и в каждом из них есть экземпляр useTransition. При нажатии кнопки «Ответить» на любой из комментариев должна появиться форма ответа. То же самое, когда нажимается кнопка показать/скрыть комментарии, все ее дочерние элементы должны перейти, однако эффекты перехода применяются ко всем разделам. я сделал кодовую строку, чтобы проиллюстрировать проблему. пожалуйста, укажите мне правильное направление. Спасибо.
import React, { useState, useEffect } from "https://cdn.skypack.dev/react@17.0.1";
import * as ReactDOM from "https://cdn.skypack.dev/react-dom@17.0.1";
import styled from "https://cdn.skypack.dev/styled-components@5.3.0";
import { useSpring, useTransition, animated } from "https://cdn.skypack.dev/react-spring@9.2.4";
///////// Styled Components ///////////////////////////////
const CommentDisplay = styled(animated.div)`
max-height: 100%;
margin: 10px 0px 0px 25px;
position: relative;
img {
width: 25px;
height: 25px;
margin: 1px 10px 0px 0px;
border-radius: 50%;
border: 1px solid gray;
}
`;
const TopBarWrapper = styled.div`
display: flex;
position: relative;
z-index: -1;
`;
const BorderDiv = styled.div`
position: absolute;
border-left: 1px solid gray;
height: calc(100% - 25px);
width: 100%;
margin-left: 12px;
bottom: 0px;
pointer-events: none;
`;
const CommentBody = styled.p`
overflow-wrap: break-word;
word-wrap: break-word;
-ms-word-break: break-all;
word-break: break-word;
padding-left: 35px;
`;
const BottomBarWrapper = styled.div`
grid-area: bottomBar;
display: flex;
flex-direction: row;
padding-left: 35px;
`;
const Reply = styled.div`
color: rgba(7, 7, 7, 0.65);
cursor: pointer;
padding: 8px 8px 8px 0px;
font-size: 14px;
amp;:hover{
color: black;
}
`;
const VoteUp = styled.div`
cursor: pointer;
padding: 8px;
amp;:hover{
background-color: #e5f4fb;
}
svg{
width: 16px;
height: 15px;
margin-right: 4px;
}
span{
font-size: 13px;
}
`;
const VoteDown = styled.div`
cursor: pointer;
padding: 8px;
amp;:hover{
background-color: #e5f4fb;
}
svg{
width: 16px;
height: 15px;
margin-right: 4px;
}
span{
font-size: 13px;
}
`;
const Form = styled.form`
display: grid;
//grid-template-columns: 90%;
grid-gap: 1.5rem;
grid-area: main_comment_body;
`;
const FormWrapper = styled.div`
display: ${props => props.rows[props.commentid] == "true" ? "grid" : "grid"};
grid-template-columns: minmax(min-content, max-content) 1fr;
grid-template-rows: minmax(50px, 1fr) minmax(min-content, max-content);
grid-template-areas:
"main_comment_img main_comment_body "
"main_comment_img main_comment_buttons";
margin: 0px 50px 0px 85px;
z-index: ${props => props.rows[props.commentid] == "true" ? "1" : "-1"};
opacity: ${props => props.rows[props.commentid] == "true" ? "1" : "0"};
height: ${props => props.rows[props.commentid] == "true" ? "initial" : "0px"};
min-height: ${props => props.rows[props.commentid] == "true" ? "100px" : "0px"};
position: relative;
top: ${props => props.rows[props.commentid] == "true" ? "7px" : "-100px"};
left: 0;
background-color: F4F4F4;
transition: all .05s ease 0s;
img {
width: 25px;
height: 25px;
grid-area: avatar;
margin: 1px 10px 0px 0px;
border-radius: 50%;
border: 1px solid gray;
grid-Area: main_comment_img;
}
`;
const CommentSection = () => {
//in the useEffect hook, an ajax call gets all the comments from the rails server (in this case, it's a hard coded //"allComments" object below) and recursivley gets the id of every comment, reply, reply of reply etc.. and builds an //object in the format of {"comment id" : " false"}.
//
// example showMore initial state
// {"207":"false",
// "208":"false",
// "209":"false",
// "210":"false",
// "211":"false",
// "212":"false",
// "213":"false",
// "214":"false"}
//
// when the "show/hide" comments button is clicked, it sets the id of all its children to "true" in the showMore state //variable, causing the css to //toggle it out of view.
const [showMore, setShowMore] = useState({});
const [rows, setRows] = useState({});
// "rows" is identical to "showMore" but is used when the "reply" button in clicked, causing the reply form appear.
//response from server containing all the comments and its nested replies etc..
const allComments = [
{
"id": 295,
"body": "This is a First level comment to the main Story blah blah...",
"created_at": "2021-07-16T17:17:10.410Z",
"updated_at": "2021-07-16T17:17:10.410Z",
"original_comment_author": null,
"parent_id": null,
"ancestry": null,
"date": "less than a minute",
"comment_number": 256,
"reply": false,
"user_id": 1,
"commentable_type": "Story",
"commentable_id": 1,
"edit_history": "",
"author_avatar": "undefined",
"author_nick": "Jimmy",
"comments": [
{
"id": 296,
"body": "this is the first reply to the main comment ",
"created_at": "2021-07-16T17:17:49.585Z",
"updated_at": "2021-07-16T17:17:49.585Z",
"original_comment_author": "undefined",
"parent_id": 295,
"ancestry": "295",
"date": "less than a minute",
"comment_number": 257,
"reply": true,
"user_id": 1,
"commentable_type": "Comment",
"commentable_id": 295,
"edit_history": "",
"author_avatar": "undefined",
"author_nick": "izzy",
"comments": [
{
"id": 298,
"body": "Reply to the reply (3rd level)",
"created_at": "2021-07-16T17:22:46.088Z",
"updated_at": "2021-07-16T17:22:46.088Z",
"original_comment_author": "undefined",
"parent_id": 296,
"ancestry": "295/296",
"date": "less than a minute",
"comment_number": 259,
"reply": true,
"user_id": 1,
"commentable_type": "Comment",
"commentable_id": 296,
"edit_history": "",
"author_avatar": "undefined",
"author_nick": "Noel",
"comments": [
{
"id": 299,
"body": "another reply to a reply (4th level) etc...",
"created_at": "2021-07-16T17:23:10.561Z",
"updated_at": "2021-07-16T17:23:10.561Z",
"original_comment_author": "undefined",
"parent_id": 298,
"ancestry": "295/296/298",
"date": "less than a minute",
"comment_number": 260,
"reply": true,
"user_id": 1,
"commentable_type": "Comment",
"commentable_id": 298,
"edit_history": "",
"author_avatar": "undefined",
"author_nick": "Mitch",
"comments": []
}
]
}
]
},
{
"id": 297,
"body": "this is a second reply to the main comment .... ",
"created_at": "2021-07-16T17:18:59.249Z",
"updated_at": "2021-07-16T17:18:59.249Z",
"original_comment_author": "undefined",
"parent_id": 295,
"ancestry": "295",
"date": "less than a minute",
"comment_number": 258,
"reply": true,
"user_id": 1,
"commentable_type": "Comment",
"commentable_id": 295,
"edit_history": "",
"author_avatar": "undefined",
"author_nick": "mike",
"comments": []
}
]
},
{
"id": 294,
"body": "This is another First Level comment to the main story ... ",
"created_at": "2021-07-16T17:16:19.314Z",
"updated_at": "2021-07-16T17:16:19.314Z",
"original_comment_author": null,
"parent_id": null,
"ancestry": null,
"date": "less than a minute",
"comment_number": 255,
"reply": false,
"user_id": 1,
"commentable_type": "Story",
"commentable_id": 1,
"edit_history": "",
"author_avatar": "undefined",
"author_nick": "Natalie",
"comments": []
}
]
;
useEffect( () => {
addAllCommentsToStateForReplyButtonToWork(allComments)
addAllCommentsToStateForShowMoreButtonToWork(allComments)
},[]);
const getReplyArray = (childrenCommentArray) => {
let tempArray = []
childrenCommentArray.map( (x, i) => {
x.id
tempArray.push(x.id ", ")
});
return tempArray.length > 0 ? tempArray : "blank"
};
function addAllCommentsToStateForReplyButtonToWork(c) {
let newArray = [];
let newState = {};
function getAllId(arr, key) {
arr.forEach(function(item) {
for (let keys in item) {
if (keys === key) {
newArray.push(item[key])
} else if (Array.isArray(item[keys])) {
getAllId(item[keys], key);
}
}
});
}
getAllId(c, 'id');
newArray.forEach(function(item) {
newState[item] = "false";
})
setRows(newState);
}
function addAllCommentsToStateForShowMoreButtonToWork(c) {
let newArray = [];
let newState = {};
function getAllId(arr, key) {
arr.forEach(function(item) {
for (let keys in item) {
if (keys === key) {
newArray.push(item[key])
} else if (Array.isArray(item[keys])) {
getAllId(item[keys], key)
}
}
})
}
getAllId(c, 'id')
newArray.forEach(function(item) {
newState[item] = "false"
})
setShowMore(newState);
}
const handleSubmitClick = (e) => {
e.preventDefault()
}
const hideCommentsOrShowComments = (childrenCommentArray) => {
let tempArray = []
let numOfTrue = 0
let numOfFalse = 0
let tempShowMore = {}
childrenCommentArray.map( (x, i) => {
tempArray.push(x.id)
})
tempArray.forEach (x => {
if (showMore[x] == "true"){
numOfTrue = numOfTrue 1
}else{
numOfFalse = numOfFalse 1
}
})
if (numOfTrue > 0){
return "show replies"
}else{
return "hide replies"
}
}
const handleShowMoreButton = (childrenCommentArray) => {
//console.log("handleShowMoreButtonfrom article.jsx------------------------")
let tempArray = []
let tempShowMore = {}
childrenCommentArray.map( (x, i) => {
tempArray.push(x.id)
})
tempArray.forEach (x => {
//console.log("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx idididid" x)
if (showMore[x] == "true"){
//console.log("in if and x is = " x " and was true, changing it!")
tempShowMore[x] = "false"
}else{
//console.log("in else and x is = " x " and was false, changing it!")
tempShowMore[x] = "true"
}
} )
setShowMore({...showMore, ...tempShowMore})
}
const handleReplyButton = (id) => {
if (rows[id] == "true"){
setRows({...rows, [id]: "false"})
}else{
setRows({...rows,[id]: "true"})
}
}
const handleChange = () => {
//
}
////////////// Comment Function, Called recursively ///////////////
function Comment({ item, rows, showMore, handleShowMoreButton, handleReplyButton }){
const transition = useTransition(showMore[item.id], {
from: {opacity: 0},
enter: {y: 0, opacity: 1},
leave: {opacity: 0},
delay: 100
});
const nestedComments = (item.comments || []).map(com => {
return <Comment style={{border: "2px solid blue"}} key={com.id} item={com} type="child" rows={rows}
showMore={showMore} handleShowMoreButton={handleShowMoreButton}
handleReplyButton={handleReplyButton}/>
});
return (
<>
{transition((style,val) => val == "true" ? '' :
<CommentDisplay
style={style}
key={item.id "commentDisplay"}
showMore={showMore}
item={item}
id={item.id} >
<BorderDiv/>
<TopBarWrapper>
<img src={item.author_avatar}/>
<h3 style={{alignSelf: "center", fontSize: ".6em", gridArea: "nick", marginRight: "8px"}}> {item.author_nick}
</h3>
<span style={{alignSelf: "center", gridArea: "date", fontSize: ".6em", color: "gray"}}></span>
</TopBarWrapper>
<CommentBody style={{gridArea: "body", fontSize: "15px"}}>
{item.body} (...the ID for this comment => {item.id}, and its children id's => {getReplyArray(item.comments)}) </CommentBody>
<BottomBarWrapper>
<Reply onClick={() => handleReplyButton(item.id)}>reply</Reply>
<VoteUp>
<svg viewBox="0 0 22 20" xmlns="http://www.w3.org/2000/svg"><path key={item.id "path1"} data-id={ item.id "path1"} d="M10.74.04a2.013 2.013 0 00-1.58 1.88c-.11 2.795-.485 4.45-2.283 6.946a1.272 1.272 0 00-1.065-.58h-4.55C.573 8.287 0 8.84 0 9.507v8.773c0 .667.572 1.218 1.263 1.218h4.55c.435 0 .821-.22 1.049-.548.263.204.506.387.758.533.417.24.887.384 1.532.45 1.29.128 3.403.032 8.283.052a.53.53 0 00.317-.113c1.224-.667 4.255-5.775 4.248-10.534-.026-1.138-.542-1.78-1.532-1.78H13.96c.388-2.47.131-4.738-.735-6.208C12.76.555 12.078.111 11.403.018a2.035 2.035 0 00-.663.022m2.154 7.912c-.055.28.201.58.498.58h6.934c.356.035.67.091.67.913 0 1.047-.168 2.886-1.031 5.057-.865 2.172-2.155 4.531-2.603 4.455-1.215.08-7.014.109-8.108 0-.556-.056-.818-.135-1.113-.306-.266-.152-.59-.423-1.066-.791v-7.6c2.349-2.88 2.979-5.302 3.096-8.3.338-1.495 1.702-1.082 2.179-.13.697 2.402.879 4.442.544 6.122M1.263 9.262h4.55c.148 0 .251.1.251.244v8.773c0 .144-.103.243-.252.243h-4.55c-.148 0-.251-.099-.251-.243V9.506c0-.144.103-.244.252-.244"></path>
</svg>
<span></span>
</VoteUp>
<VoteDown>
<svg viewBox="0 0 22 20" xmlns="http://www.w3.org/2000/svg"><path key={item.id "path2"} data-id={ item.id "path2"} d="M11.26 19.96a2.013 2.013 0 001.58-1.881c.11-2.794.484-4.45 2.282-6.945.224.345.618.58 1.066.58h4.548c.692 0 1.264-.553 1.264-1.22V1.722c0-.668-.572-1.22-1.264-1.22h-4.548c-.436 0-.823.22-1.05.55a6.898 6.898 0 00-.759-.534c-.416-.24-.887-.384-1.531-.45C11.558-.06 9.445.037 4.564.017a.521.521 0 00-.316.114C3.023.796-.007 5.904 0 10.663c.025 1.138.541 1.78 1.532 1.78H8.04c-.39 2.47-.131 4.738.735 6.208.467.794 1.148 1.238 1.823 1.331a2.034 2.034 0 00.663-.022m-2.155-7.913c.056-.28-.202-.579-.497-.579H1.674c-.356-.035-.67-.091-.67-.913 0-1.047.166-2.886 1.031-5.057C2.9 3.326 4.19.967 4.638 1.044c1.214-.081 7.014-.109 8.108 0 .556.055.818.134 1.113.305.265.152.59.423 1.066.791v7.6c-2.349 2.88-2.979 5.302-3.096 8.3-.338 1.495-1.702 1.083-2.179.13-.697-2.402-.88-4.442-.545-6.123m11.631-1.309h-4.548c-.149 0-.252-.1-.252-.244V1.722c0-.144.103-.244.252-.244h4.548c.15 0 .253.1.253.244v8.772c0 .144-.103.244-.253.244"></path> </svg>
<span></span>
</VoteDown>
<span style={{cursor: "pointer", marginLeft: "10px", fontSize: "10px", lineHeight: "40px"}}
onClick={() => handleShowMoreButton(item.comments)}>
{item.comments === undefined || item.comments.length == 0 ? "" : hideCommentsOrShowComments(item.comments)}
</span>
</BottomBarWrapper>
<FormWrapper rows={rows} commentid={item.id}>
<img src={item.author_avatar}></img>
<Form
id={item.id.toString() "form"}
className="form-inline"
onSubmit={handleSubmitClick}
enctype="multipart/form-data" >
<div style={{width: "100%", height: "100%"}} className="field" >
<textarea
style={{width: "100%"}}
onChange={handleChange}
index={1}
placeholder={"...reply to " }
name="comment"
onKeyPress={e => {
if(e.key === 'Enter')
e.preventDefault()
}}
value={"enter a reply..."}/>
</div>
</Form>
<button
form={item.id.toString() "form"}
style={{marginTop: "3px", gridArea: "main_comment_buttons"}}
type="submit">
reply now
</button>
</FormWrapper>
{nestedComments}
</CommentDisplay>
)}
</>
)
}
return (
<div style={{margin: "0 auto 90px auto"}}>
<div style={{background: "#d3f7b9"}}>
<ul style={{padding: "18px", margin: "0px 15px 0px 15px", width: "80vw"}}>
<li> <h2>Animation using React-spring useTransition not working as expected. All the divs get animated instead of only the respective divs when the "show/hide comments" button or the "reply" buttons are clicked. </h2></li>
<ul style={{margin: "10px 30px"}}>
<li>Each top level comment is mapped into the Comment function (Line 715) </li><br/>
<li>The Comment function (Line 548) recursively loops thru each top level comment's nested replies, replies of replies, replies of replies of replies etc.... adds useTansition to each and renders them. </li><br/>
<li> When the show/hide button is clicked, it changes the boolean state for all its children to true causing the children to collapse out of view. This is the part i want to animate. Same thing when the reply button is clicked, the reply form should be animated.</li><br/>
</ul>
</ul>
</div>
<div style={{position: "relative"}}>
{allComments.map( (c) => {
return (
<Comment
key={c.id}
item={c}
rows={rows}
showMore={showMore}
handleShowMoreButton={handleShowMoreButton}
handleReplyButton={handleReplyButton}/>
)
})}
</div>
</div>
)
}
class App extends React.Component {
render() {
return (
<CommentSection/>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Ответ №1:
В итоге я использовал массив ссылок для анимации формы ответа и кнопки «Показать/скрыть». Это были все заданные состояния, которые у меня были, которые вызывали многие рендеры и не позволяли анимации перехода CSS работать.
function CommentSection(props){
//all the comments from server, usually in useeffect hook but hardcoded here instead
const artDataComments = [
{
"id": 295,
"body": "This is a First level comment to the main Story blah blah...",
"created_at": "2021-07-16T17:17:10.410Z",
"updated_at": "2021-07-16T17:17:10.410Z",
"original_comment_author": null,
"parent_id": null,
"ancestry": null,
"date": "less than a minute",
"comment_number": 256,
"reply": false,
"user_id": 1,
"commentable_type": "Story",
"commentable_id": 1,
"edit_history": "",
"author_avatar": "undefined",
"author_nick": "Jimmy",
"comments": [
{
"id": 296,
"body": "this is the first reply to the main comment ",
"created_at": "2021-07-16T17:17:49.585Z",
"updated_at": "2021-07-16T17:17:49.585Z",
"original_comment_author": "undefined",
"parent_id": 295,
"ancestry": "295",
"date": "less than a minute",
"comment_number": 257,
"reply": true,
"user_id": 1,
"commentable_type": "Comment",
"commentable_id": 295,
"edit_history": "",
"author_avatar": "undefined",
"author_nick": "izzy",
"comments": [
{
"id": 298,
"body": "Reply to the reply (3rd level)",
"created_at": "2021-07-16T17:22:46.088Z",
"updated_at": "2021-07-16T17:22:46.088Z",
"original_comment_author": "undefined",
"parent_id": 296,
"ancestry": "295/296",
"date": "less than a minute",
"comment_number": 259,
"reply": true,
"user_id": 1,
"commentable_type": "Comment",
"commentable_id": 296,
"edit_history": "",
"author_avatar": "undefined",
"author_nick": "Noel",
"comments": [
{
"id": 299,
"body": "another reply to a reply (4th level) etc...",
"created_at": "2021-07-16T17:23:10.561Z",
"updated_at": "2021-07-16T17:23:10.561Z",
"original_comment_author": "undefined",
"parent_id": 298,
"ancestry": "295/296/298",
"date": "less than a minute",
"comment_number": 260,
"reply": true,
"user_id": 1,
"commentable_type": "Comment",
"commentable_id": 298,
"edit_history": "",
"author_avatar": "undefined",
"author_nick": "Mitch",
"comments": []
}
]
}
]
},
{
"id": 297,
"body": "this is a second reply to the main comment .... ",
"created_at": "2021-07-16T17:18:59.249Z",
"updated_at": "2021-07-16T17:18:59.249Z",
"original_comment_author": "undefined",
"parent_id": 295,
"ancestry": "295",
"date": "less than a minute",
"comment_number": 258,
"reply": true,
"user_id": 1,
"commentable_type": "Comment",
"commentable_id": 295,
"edit_history": "",
"author_avatar": "undefined",
"author_nick": "mike",
"comments": []
}
]
},
{
"id": 294,
"body": "This is another First Level comment to the main story ... ",
"created_at": "2021-07-16T17:16:19.314Z",
"updated_at": "2021-07-16T17:16:19.314Z",
"original_comment_author": null,
"parent_id": null,
"ancestry": null,
"date": "less than a minute",
"comment_number": 255,
"reply": false,
"user_id": 1,
"commentable_type": "Story",
"commentable_id": 1,
"edit_history": "",
"author_avatar": "undefined",
"author_nick": "Natalie",
"comments": []
}
]
;
const allShowMoreRefs = useRef([]);
allShowMoreRefs.current = []
const allReplyRefs = useRef([]);
allReplyRefs.current = []
const getReplyArray = (childrenCommentArray) => {
let tempArray = []
childrenCommentArray.map( (x, i) => {
x.id
tempArray.push(x.id ", ")
})
return tempArray.length > 0 ? tempArray : "blank"
}
const handleReplyButton = (childrenCommentArray, e, itemID) => {
allReplyRefs.current.map ( (current, i) => {
if (itemID == current.id.substr(0, current.id.indexOf('-'))){
if (current.classList.contains("replyForm")){
current.classList.remove("replyForm")
}else{
current.classList.add("replyForm")
}
}
})
}
const handleShowMoreButton = (childrenCommentArray, e, itemID) => {
//set the label
if (e.target.innerText == "hide replies"){
e.target.innerText = "show replies"
}else{
e.target.innerText = "hide replies"
}
//get the ref(s) and change the css
childrenCommentArray.map(item => {
allShowMoreRefs.current.map ( (current, i) => {
if (item.id == current.id){
if (current.classList.contains("shrink")){
current.classList.remove("shrink")
}else{
current.classList.add("shrink")
}
}
})
})
}
//function called recursivley depended on how many nested comments get returned from server
const Comment = ({ item, userState, storyID, setArtDataComments, handleShowMoreButton, handleReplyButton}) => {
const addToShowMoreRefs = (el) => {
if (el amp;amp; !allShowMoreRefs.current.includes(el)){
allShowMoreRefs.current.push(el)
}
}
const addToReplyRefs = (el) => {
//console.log("size b4 going in addToReplyeRefs is ", allReplyRefs.current.length )
console.log("in================= addTo_Reply_Refs")
if (el amp;amp; !allReplyRefs.current.includes(el)){
//console.log("inside================= addToReplyeRefs")
//console.log(el)
allReplyRefs.current.push(el)
console.log("size after adding one is ", allReplyRefs.current.length )
}
}
const nestedComments = (item.comments || []).map(com => {
return (
<div key={item.id}>
<Comment style={{border: "2px solid blue"}}
item={com} type="child"
userState={userState}
storyID={storyID}
setArtDataComments={setArtDataComments}
handleShowMoreButton={handleShowMoreButton}
handleReplyButton={handleReplyButton} />
</div>
)
});
return (
<CommentDisplay
ref={addToShowMoreRefs}
className={"replies"}
key={item.id "commentDisplay"}
item={item} id={item.id} >
<BorderDiv/>
<TopBarWrapper>
<img src="defaultAvatar"/>
<h3 style={{alignSelf: "center", fontSize: ".6em", gridArea: "nick", marginRight: "8px"}}>
{item.author_nick}
</h3>
<span style={{alignSelf: "center", gridArea: "date", fontSize: ".6em", color: "gray"}}></span>
</TopBarWrapper>
<CommentBody style={{gridArea: "body", fontSize: "15px"}}>
{item.body} this comment ID is {item.id} and its children array is {getReplyArray(item.comments)}
</CommentBody>
<BottomBarWrapper>
<Reply onClick={(e) => handleReplyButton(item.comments, e, item.id)}>reply</Reply>
<VoteUp onClick={(e)=>{handleVoteUp(e, item.id)}}>
<svg viewBox="0 0 22 20" xmlns="http://www.w3.org/2000/svg"><path key={item.id "path1"} data-id={ item.id "path1"}
d="M10.74.04a2.013 2.013 0 00-1.58 1.88c-.11 2.795-.485 4.45-2.283
6.946a1.272 1.272 0 00-1.065-.58h-4.55C.573 8.287 0 8.84 0 9.507v8.773c0 .667.572 1.218 1.263 1.218h4.55c.435 0 .821-.22 1.049-.548.263.204.506.387.758.533.417.24.887.384 1.532.45 1.29.128 3.403.032 8.283.052a.53.53 0 00.317-.113c1.224-.667 4.255-5.775 4.248-10.534-.026-1.138-.542-1.78-1.532-1.78H13.96c.388-2.47.131-4.738-.735-6.208C12.76.555 12.078.111 11.403.018a2.035 2.035 0 00-.663.022m2.154 7.912c-.055.28.201.58.498.58h6.934c.356.035.67.091.67.913 0 1.047-.168 2.886-1.031 5.057-.865 2.172-2.155 4.531-2.603 4.455-1.215.08-7.014.109-8.108 0-.556-.056-.818-.135-1.113-.306-.266-.152-.59-.423-1.066-.791v-7.6c2.349-2.88 2.979-5.302 3.096-8.3.338-1.495 1.702-1.082 2.179-.13.697 2.402.879 4.442.544 6.122M1.263 9.262h4.55c.148 0 .251.1.251.244v8.773c0 .144-.103.243-.252.243h-4.55c-.148 0-.251-.099-.251-.243V9.506c0-.144.103-.244.252-.244"></path></svg>
<span commentid={item.id}>{item.total_upvotes}</span>
</VoteUp>
<VoteDown onClick={(e)=>{handleVoteDown(e, item.id)}}>
<svg viewBox="0 0 22 20" xmlns="http://www.w3.org/2000/svg"><path key={item.id "path2"} data-id={ item.id "path2"} d="M11.26 19.96a2.013 2.013 0 001.58-1.881c.11-2.794.484-4.45 2.282-6.945.224.345.618.58 1.066.58h4.548c.692 0 1.264-.553 1.264-1.22V1.722c0-.668-.572-1.22-1.264-1.22h-4.548c-.436 0-.823.22-1.05.55a6.898 6.898 0 00-.759-.534c-.416-.24-.887-.384-1.531-.45C11.558-.06 9.445.037 4.564.017a.521.521 0 00-.316.114C3.023.796-.007 5.904 0 10.663c.025 1.138.541 1.78 1.532 1.78H8.04c-.39 2.47-.131 4.738.735 6.208.467.794 1.148 1.238 1.823 1.331a2.034 2.034 0 00.663-.022m-2.155-7.913c.056-.28-.202-.579-.497-.579H1.674c-.356-.035-.67-.091-.67-.913 0-1.047.166-2.886 1.031-5.057C2.9 3.326 4.19.967 4.638 1.044c1.214-.081 7.014-.109 8.108 0 .556.055.818.134 1.113.305.265.152.59.423 1.066.791v7.6c-2.349 2.88-2.979 5.302-3.096 8.3-.338 1.495-1.702 1.083-2.179.13-.697-2.402-.88-4.442-.545-6.123m11.631-1.309h-4.548c-.149 0-.252-.1-.252-.244V1.722c0-.144.103-.244.252-.244h4.548c.15 0 .253.1.253.244v8.772c0 .144-.103.244-.253.244"></path></svg>
<span commentid={item.id}>{item.total_downvotes}</span>
</VoteDown>
<span
style={{cursor: "pointer", marginLeft: "10px", fontSize: "10px", lineHeight: "40px"}}
onClick={(e) => handleShowMoreButton(item.comments, e, item.id)}>
{item.comments === undefined || item.comments.length == 0 ? "" : "hide replies"}
</span>
</BottomBarWrapper>
<div
id={item.id "-replyform"}
className={"replyFormHidden"}
ref={props.addToReplyRefs}
commentid={props.commentid}
ref={addToReplyRefs}
originalcommentAuthor={item.author_nick}
userState={userState}
storyID={storyID}
commentid={item.id}
setArtDataComments={setArtDataComments}
handleReplyButton={handleReplyButton}>
<img src="defaultManIcon"></img>
<Form
id={item.id "form"}
className="form-inline"
onSubmit="handleAdd"
enctype="multipart/form-data" >
<div style={{width: "100%", height: "100%"}} className="field" >
<Textarea
type="textarea"
className="form-control"
index={1}
placeholder={"...reply to " props.commentAuthor}
name="comment"
onKeyPress={e => {
if(e.key === 'Enter')
e.preventDefault()
}}/>
</div>
</Form>
<button
form={item.id "form"}
style={{marginTop: "3px", gridArea: "main_comment_buttons"}}
type="submit" >
reply now
</button>
</div>
{nestedComments}
</CommentDisplay>
)
}
return (
<Comments>
<div>
<div style={{position: "relative"}}>
{
artDataComments.map( (c, i) => {
return (
<div key={c.id}>
<Comment
item={c}
userState={props.userState}
handleShowMoreButton={handleShowMoreButton}
handleReplyButton={handleReplyButton} />
</div>
)
})
}
</div>
</div>
</Comments>
);
}