0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-04-15 03:01:37 -05:00

Different looking text boxes and other bits

This commit is contained in:
James Morris 2022-07-06 15:08:10 +02:00
parent 5ce4924624
commit fdc9e5f2e9
8 changed files with 121 additions and 32 deletions

View file

@ -5,6 +5,7 @@ import Avatar from './Avatar';
import Like from './Like';
import Reply from './Reply';
import More from './More';
import EditForm from './EditForm';
class Comment extends React.Component {
static contextType = AppContext;
@ -12,10 +13,12 @@ class Comment extends React.Component {
constructor(props) {
super(props);
this.state = {
isContextMenuOpen: false
isContextMenuOpen: false,
isInEditMode: false
};
this.toggleContextMenu = this.toggleContextMenu.bind(this);
this.toggleEditMode = this.toggleEditMode.bind(this);
}
toggleContextMenu() {
@ -24,6 +27,12 @@ class Comment extends React.Component {
}));
}
toggleEditMode() {
this.setState(state => ({
isInEditMode: !state.isInEditMode
}));
}
/**
* Whether we have at least one action inside the context menu
* (to hide the 'more' icon if we don't have any actions)
@ -40,27 +49,33 @@ class Comment extends React.Component {
html.__html = '<i>This comment has been removed.</i>';
}
return (
<div className="flex mb-8">
<div>
<div className="flex mb-2 space-x-4 justify-start items-center">
<Avatar comment={comment} />
<div>
<h4 className="text-lg font-sans font-bold mb-1 tracking-tight dark:text-neutral-300">{comment.member.name}</h4>
<h6 className="text-xs text-neutral-400 font-sans">{formatRelativeTime(comment.created_at)}</h6>
if (this.state.isInEditMode) {
return (
<EditForm value={html} comment={comment} toggle={this.toggleEditMode} />
);
} else {
return (
<div className="flex mb-8">
<div>
<div className="flex mb-2 space-x-4 justify-start items-center">
<Avatar comment={comment} />
<div>
<h4 className="text-lg font-sans font-bold mb-1 tracking-tight dark:text-neutral-300">{comment.member.name}</h4>
<h6 className="text-xs text-neutral-400 font-sans">{formatRelativeTime(comment.created_at)}</h6>
</div>
</div>
<div className="ml-14 mb-2.5 pr-4 font-sans leading-normal dark:text-neutral-300">
<p dangerouslySetInnerHTML={html} className="whitespace-pre-wrap"></p>
</div>
<div className="ml-14 flex gap-5">
<Like comment={comment} />
<Reply comment={comment} />
<More comment={comment} show={this.hasMoreContextMenu} toggleEdit={this.toggleEditMode} />
</div>
</div>
<div className="ml-14 mb-2.5 pr-4 font-sans leading-normal dark:text-neutral-300">
<p dangerouslySetInnerHTML={html} className="whitespace-pre-wrap"></p>
</div>
<div className="ml-14 flex gap-5">
<Like comment={comment} />
<Reply comment={comment} />
<More comment={comment} show={this.hasMoreContextMenu} />
</div>
</div>
</div>
);
);
}
}
}

View file

@ -0,0 +1,64 @@
import {formatRelativeTime} from '../utils/helpers';
import React from 'react';
import AppContext from '../AppContext';
import Avatar from './Avatar';
class EditForm extends React.Component {
static contextType = AppContext;
constructor(props) {
super(props);
this.state = {
message: props.value.__html
};
this.submitForm = this.submitForm.bind(this);
this.handleChange = this.handleChange.bind(this);
}
getHTML() {
const text = this.state.message;
// Convert newlines to <br> for now (until we add a real editor)
return text.replace('\n', '<br>');
}
async submitForm(event) {
event.preventDefault();
return false;
}
handleChange(event) {
this.setState({message: event.target.value});
}
render() {
const comment = this.props.comment;
return (
<form onSubmit={this.submitForm} className="comment-form mb-6">
<div className="w-full">
<div className="flex mb-2 space-x-4 justify-start items-center">
<Avatar />
<div>
<h4 className="text-lg font-sans font-bold mb-1 tracking-tight dark:text-neutral-300">{comment.member.name}</h4>
<h6 className="text-xs text-neutral-400 font-sans">{formatRelativeTime(comment.created_at)}</h6>
</div>
</div>
<div className="ml-14 pr-3 font-sans leading-normal dark:text-neutral-300">
<div className="relative w-full">
<textarea className="w-full resize-none rounded-md border h-48 p-3 font-sans mb-1 leading-normal focus:outline-0 dark:bg-[rgba(255,255,255,0.08)] dark:border-none dark:text-neutral-300" value={this.state.message} onChange={this.handleChange} />
<div className="flex absolute bottom-5 right-3">
<button className="font-sans text-sm font-medium mr-3 text-neutral-500" onClick={this.props.toggle}>Cancel</button>
<button type="submit" className="w-full rounded-md border p-3 py-3 font-sans text-sm text-center bg-black font-semibold text-white dark:bg-[rgba(255,255,255,0.8)] dark:text-neutral-800">Edit your comment</button>
</div>
</div>
</div>
</div>
</form>
);
}
}
export default EditForm;

View file

@ -53,12 +53,22 @@ class Form extends React.Component {
render() {
return (
<form onSubmit={this.submitForm} className="comment-form">
<div className="flex bg-neutral-50 p-3 space-x-3 rounded-md dark:bg-transparent">
<Avatar size="small" />
<div className="w-full">
<textarea className="w-full resize-none rounded-md border h-24 p-3 font-sans mb-1 leading-normal focus:outline-0 dark:bg-[rgba(255,255,255,0.08)] dark:border-none dark:text-neutral-300" value={this.state.message} onChange={this.handleChange} placeholder="Join the conversation" />
<button type="submit" className="w-full rounded-md border p-3 py-3 font-sans text-sm text-center bg-black font-semibold text-white dark:bg-[rgba(255,255,255,0.8)] dark:text-neutral-800">Add your comment</button>
<form onSubmit={this.submitForm} className="comment-form">
<div className="w-full">
<div className="flex mb-2 space-x-4 justify-start items-center">
<Avatar />
<div>
<h4 className="text-lg font-sans font-bold mb-1 tracking-tight dark:text-neutral-300">{this.context.member.name}</h4>
<h6 className="text-xs text-neutral-400 font-sans">&nbsp;</h6>
</div>
</div>
<div className="-mt-4 ml-14 pr-3 font-sans leading-normal dark:text-neutral-300">
<div className="relative w-full">
<textarea className="w-full resize-none rounded-md border h-36 p-3 font-sans mb-1 leading-normal focus:outline-0 dark:bg-[rgba(255,255,255,0.08)] dark:border-none dark:text-neutral-300" value={this.state.message} onChange={this.handleChange} />
<div className="absolute bottom-5 right-3">
<button type="submit" className="w-full rounded-md border p-3 py-3 font-sans text-sm text-center bg-black font-semibold text-white dark:bg-[rgba(255,255,255,0.8)] dark:text-neutral-800">Add your comment</button>
</div>
</div>
</div>
</div>
</form>

View file

@ -28,7 +28,7 @@ class More extends React.Component {
return (
<div className="relative">
{show ? <button onClick={this.toggleContextMenu}><MoreIcon className='gh-comments-icon gh-comments-icon-more -m-[3px]' /></button> : null}
{this.state.isContextMenuOpen ? <CommentContextMenu comment={comment} close={this.toggleContextMenu} /> : null}
{this.state.isContextMenuOpen ? <CommentContextMenu comment={comment} close={this.toggleContextMenu} toggleEdit={this.props.toggleEdit} /> : null}
</div>
);
}

View file

@ -35,11 +35,11 @@ class AdminContextMenu extends React.Component {
<div className="flex flex-col">
{
this.isHidden ?
<button onClick={this.showComment}>
<button className="text-[14px]" onClick={this.showComment}>
Show comment
</button>
:
<button onClick={this.hideComment}>
<button className="text-[14px]" onClick={this.hideComment}>
Hide comment
</button>
}

View file

@ -23,10 +23,10 @@ class AuthorContextMenu extends React.Component {
render() {
return (
<div className="flex flex-col">
<button className="w-full mb-3 text-left">
<button className="w-full mb-3 text-left text-[14px]" onClick={this.props.toggleEdit}>
Edit
</button>
<button className="w-full text-left" onClick={this.deleteComment}>
<button className="w-full text-left text-[14px]" onClick={this.deleteComment}>
Delete
</button>
</div>

View file

@ -31,7 +31,7 @@ class CommentContextMenu extends React.Component {
return (
<div className="bg-white absolute font-sans rounded py-3 px-4 drop-shadow-xl text-sm whitespace-nowrap">
{this.isAuthor && comment.status === 'published' ? <AuthorContextMenu comment={comment} close={this.close}/> : (this.isAdmin ? <AdminContextMenu comment={comment} close={this.close}/> : <NotAuthorContextMenu comment={comment} close={this.close}/>)}
{this.isAuthor && comment.status === 'published' ? <AuthorContextMenu comment={comment} close={this.close} toggleEdit={this.props.toggleEdit} /> : (this.isAdmin ? <AdminContextMenu comment={comment} close={this.close}/> : <NotAuthorContextMenu comment={comment} close={this.close}/>)}
</div>
);
}

View file

@ -22,7 +22,7 @@ class NotAuthorContextMenu extends React.Component {
render() {
return (
<button onClick={this.reportComment}>
<button className="text-[14px]" onClick={this.reportComment}>
Report comment
</button>
);