diff --git a/web/app/components/comment/__action/_type/_edit/comment__action_type_edit.scss b/web/app/components/comment/__action/_type/_edit/comment__action_type_edit.scss
new file mode 100644
index 00000000..656e430a
--- /dev/null
+++ b/web/app/components/comment/__action/_type/_edit/comment__action_type_edit.scss
@@ -0,0 +1,7 @@
+.comment__action_type_edit {
+ color: #a6a6a6;
+
+ &:hover {
+ color: #31c7c5;
+ }
+}
diff --git a/web/app/components/comment/__vote/comment__vote.scss b/web/app/components/comment/__vote/comment__vote.scss
index cf6dc84c..dd3c9100 100644
--- a/web/app/components/comment/__vote/comment__vote.scss
+++ b/web/app/components/comment/__vote/comment__vote.scss
@@ -8,6 +8,7 @@
background: url('comment__vote.svg') center no-repeat;
background-size: contain;
cursor: pointer;
+ outline: none;
&:hover {
background-image: url('_selected/comment__vote_selected.svg');
diff --git a/web/app/components/comment/_editing/comment_editing.scss b/web/app/components/comment/_editing/comment_editing.scss
new file mode 100644
index 00000000..bb546220
--- /dev/null
+++ b/web/app/components/comment/_editing/comment_editing.scss
@@ -0,0 +1,36 @@
+.comment_editing {
+ .comment__text {
+ display: none;
+ }
+
+ .comment__input {
+ border: 12px solid #eee;
+ }
+
+ .comment__score {
+ top: 4px;
+ right: 0;
+ }
+
+ // it isn't mobile first, but it's fine here
+ @media (-moz-touch-enabled: 1) and (max-width: 768px), (pointer:coarse) and (max-width: 768px) {
+ border: 8px solid #eee;
+ padding-bottom: 0;
+
+ .comment__body {
+ padding: 8px 8px 0;
+ }
+
+ .comment__input {
+ border-left-width: 0;
+ border-right-width: 0;
+ border-bottom-width: 0;
+ border-top-width: 8px;
+ }
+
+ .comment__score {
+ top: 12px;
+ right: 8px;
+ }
+ }
+}
diff --git a/web/app/components/comment/comment.jsx b/web/app/components/comment/comment.jsx
index 49a91b24..8b4cca38 100644
--- a/web/app/components/comment/comment.jsx
+++ b/web/app/components/comment/comment.jsx
@@ -12,7 +12,8 @@ export default class Comment extends Component {
super(props);
this.state = {
- isInputVisible: false,
+ isReplying: false,
+ isEditing: false,
isUserIdVisible: false,
};
@@ -20,7 +21,8 @@ export default class Comment extends Component {
this.decreaseScore = this.decreaseScore.bind(this);
this.increaseScore = this.increaseScore.bind(this);
- this.toggleInputVisibility = this.toggleInputVisibility.bind(this);
+ this.toggleEditing = this.toggleEditing.bind(this);
+ this.toggleReplying = this.toggleReplying.bind(this);
this.toggleCollapse = this.toggleCollapse.bind(this);
this.toggleUserIdVisibility = this.toggleUserIdVisibility.bind(this);
this.scrollToParent = this.scrollToParent.bind(this);
@@ -63,18 +65,33 @@ export default class Comment extends Component {
}
}
- toggleInputVisibility() {
- const { isInputVisible } = this.state;
- const onPrevReplyCb = store.get('onPrevReplyCb');
+ toggleReplying() {
+ const { isReplying } = this.state;
+ const onPrevInputToggleCb = store.get('onPrevInputToggleCb');
- this.setState({ isInputVisible: !isInputVisible });
+ this.setState({ isReplying: !isReplying });
- if (onPrevReplyCb) onPrevReplyCb();
+ if (onPrevInputToggleCb) onPrevInputToggleCb();
- if (!isInputVisible) {
- store.set('onPrevReplyCb', () => this.setState({ isInputVisible: false }));
+ if (!isReplying) {
+ store.set('onPrevInputToggleCb', () => this.setState({ isReplying: false }));
} else {
- store.set('onPrevReplyCb', null);
+ store.set('onPrevInputToggleCb', null);
+ }
+ }
+
+ toggleEditing() {
+ const { isEditing } = this.state;
+ const onPrevInputToggleCb = store.get('onPrevInputToggleCb');
+
+ this.setState({ isEditing: !isEditing });
+
+ if (onPrevInputToggleCb) onPrevInputToggleCb();
+
+ if (!isEditing) {
+ store.set('onPrevInputToggleCb', () => this.setState({ isEditing: false }));
+ } else {
+ store.set('onPrevInputToggleCb', null);
}
}
@@ -180,7 +197,15 @@ export default class Comment extends Component {
this.props.onReply(...rest);
this.setState({
- isInputVisible: false,
+ isReplying: false,
+ });
+ }
+
+ onEdit(...rest) {
+ this.props.onEdit(...rest);
+
+ this.setState({
+ isEditing: false,
});
}
@@ -202,7 +227,7 @@ export default class Comment extends Component {
}
}
- render(props, { guest, isUserIdVisible, userBlocked, pinned, score, scoreIncreased, scoreDecreased, deleted, isInputVisible }) {
+ render(props, { guest, isUserIdVisible, userBlocked, pinned, score, scoreIncreased, scoreDecreased, deleted, isReplying, isEditing }) {
const { data, mods = {} } = props;
const isAdmin = !guest && store.get('user').admin;
const isGuest = guest || !Object.keys(store.get('user')).length;
@@ -240,7 +265,8 @@ export default class Comment extends Component {
useless: userBlocked || deleted || (score <= USELESS_COMMENT_SCORE && !mods.pinned && !mods.disabled),
// TODO: add default view mod or don't?
view: o.user.admin ? 'admin' : null,
- replying: isInputVisible,
+ replying: isReplying,
+ editing: isEditing,
};
if (mods.view === 'preview') {
@@ -344,8 +370,19 @@ export default class Comment extends Component {
className="comment__action"
role="button"
tabIndex="0"
- onClick={this.toggleInputVisibility}
- >{isInputVisible ? 'Cancel' : 'Reply'}
+ onClick={this.toggleReplying}
+ >{isReplying ? 'Cancel' : 'Reply'}
+ )
+ }
+
+ {
+ !deleted && !mods.disabled && !!o.orig && isCurrentUser && (
+ {isEditing ? 'Cancel' : 'Edit'}
)
}
@@ -423,16 +460,30 @@ export default class Comment extends Component {
{
- isInputVisible && (
+ isReplying && (
)
}
+
+ {
+ isEditing && (
+
+ )
+ }
);
}
diff --git a/web/app/components/comment/index.js b/web/app/components/comment/index.js
index 6538f931..68cf4b71 100644
--- a/web/app/components/comment/index.js
+++ b/web/app/components/comment/index.js
@@ -6,6 +6,7 @@ require('./comment.scss');
require('./__action/comment__action.scss');
require('./__action/_type/_collapse/comment__action_type_collapse.scss');
+require('./__action/_type/_edit/comment__action_type_edit.scss');
require('./__avatar/comment__avatar.scss');
require('./__avatar/_default/comment__avatar_default.scss');
@@ -34,6 +35,7 @@ require('./__vote/_type/_down/comment__vote_type_down.scss');
require('./__vote/_type/_up/comment__vote_type_up.scss');
require('./_level/comment_level.scss');
+require('./_editing/comment_editing.scss');
require('./_replying/comment_replying.scss');
require('./_useless/comment_useless.scss');