Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix some submit button issues #2487

Merged
merged 13 commits into from
Jun 2, 2024
Merged
11 changes: 11 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,17 @@ export default [
"unicorn/filename-case": 0,
"jsx-a11y/media-has-caption": 0,
"jsx-a11y/label-has-associated-control": 0,
"no-restricted-imports": [
"error",
{
patterns: [
{
group: ["assets/*", "client/*", "server/*", "shared/*"],
message: "Use relative import instead.",
},
],
},
],
},
},
];
57 changes: 34 additions & 23 deletions src/shared/components/comment/comment-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,33 @@ import { capitalizeFirstLetter } from "@utils/helpers";
import { Component } from "inferno";
import { T } from "inferno-i18next-dess";
import { Link } from "inferno-router";
import { CreateComment, EditComment, Language } from "lemmy-js-client";
import {
CommentResponse,
CreateComment,
EditComment,
Language,
} from "lemmy-js-client";
import { CommentNodeI } from "../../interfaces";
import { I18NextService, UserService } from "../../services";
import { Icon } from "../common/icon";
import { MarkdownTextArea } from "../common/markdown-textarea";
import { RequestState } from "../../services/HttpService";

interface CommentFormProps {
/**
* Can either be the parent, or the editable comment. The right side is a postId.
*/
node: CommentNodeI | number;
finished?: boolean;
edit?: boolean;
disabled?: boolean;
focus?: boolean;
onReplyCancel?(): void;
allLanguages: Language[];
siteLanguages: number[];
containerClass?: string;
onUpsertComment(form: EditComment | CreateComment): void;
onUpsertComment(
form: EditComment | CreateComment,
): Promise<RequestState<CommentResponse>>;
}

export class CommentForm extends Component<CommentFormProps, any> {
Expand Down Expand Up @@ -50,7 +57,6 @@ export class CommentForm extends Component<CommentFormProps, any> {
initialContent={initialContent}
showLanguage
buttonTitle={this.buttonTitle}
finished={this.props.finished}
replyType={typeof this.props.node !== "number"}
focus={this.props.focus}
disabled={this.props.disabled}
Expand Down Expand Up @@ -83,33 +89,38 @@ export class CommentForm extends Component<CommentFormProps, any> {
: capitalizeFirstLetter(I18NextService.i18n.t("reply"));
}

handleCommentSubmit(content: string, language_id?: number) {
async handleCommentSubmit(
content: string,
language_id?: number,
): Promise<boolean> {
const { node, onUpsertComment, edit } = this.props;
let response: RequestState<CommentResponse>;

if (typeof node === "number") {
const post_id = node;
onUpsertComment({
response = await onUpsertComment({
content,
post_id,
language_id,
});
} else if (edit) {
const comment_id = node.comment_view.comment.id;
response = await onUpsertComment({
content,
comment_id,
language_id,
});
} else {
if (edit) {
const comment_id = node.comment_view.comment.id;
onUpsertComment({
content,
comment_id,
language_id,
});
} else {
const post_id = node.comment_view.post.id;
const parent_id = node.comment_view.comment.id;
this.props.onUpsertComment({
content,
parent_id,
post_id,
language_id,
});
}
const post_id = node.comment_view.post.id;
const parent_id = node.comment_view.comment.id;
response = await onUpsertComment({
content,
parent_id,
post_id,
language_id,
});
}

return response.state !== "failed";
}
}
49 changes: 25 additions & 24 deletions src/shared/components/comment/comment-node.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { colorList, getCommentParentId } from "@utils/app";
import { futureDaysToUnixTime, numToSI } from "@utils/helpers";
import classNames from "classnames";
import { isBefore, parseISO, subMinutes } from "date-fns";
import { Component, InfernoNode, linkEvent } from "inferno";
import { Component, linkEvent } from "inferno";
import { Link } from "inferno-router";
import {
AddAdmin,
Expand Down Expand Up @@ -33,7 +33,6 @@ import {
SaveComment,
TransferCommunity,
} from "lemmy-js-client";
import deepEqual from "lodash.isequal";
import { commentTreeMaxDepth } from "../../config";
import {
CommentNodeI,
Expand Down Expand Up @@ -87,7 +86,6 @@ interface CommentNodeProps {
allLanguages: Language[];
siteLanguages: number[];
hideImages?: boolean;
finished: Map<CommentId, boolean | undefined>;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good, its nice to get rid of these.

onSaveComment(form: SaveComment): Promise<void>;
onCommentReplyRead(form: MarkCommentReplyAsRead): void;
onPersonMentionRead(form: MarkPersonMentionAsRead): void;
Expand Down Expand Up @@ -139,6 +137,8 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
super(props, context);

this.handleReplyCancel = this.handleReplyCancel.bind(this);
this.handleCreateComment = this.handleCreateComment.bind(this);
this.handleEditComment = this.handleEditComment.bind(this);
this.handleReportComment = this.handleReportComment.bind(this);
this.handleRemoveComment = this.handleRemoveComment.bind(this);
this.handleReplyClick = this.handleReplyClick.bind(this);
Expand All @@ -164,22 +164,6 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
return this.commentView.comment.id;
}

componentWillReceiveProps(
nextProps: Readonly<{ children?: InfernoNode } & CommentNodeProps>,
): void {
if (!deepEqual(this.props, nextProps)) {
this.setState({
showEdit: false,
showAdvanced: false,
createOrEditCommentLoading: false,
upvoteLoading: false,
downvoteLoading: false,
readLoading: false,
fetchChildrenLoading: false,
});
}
}

render() {
const node = this.props.node;
const cv = this.commentView;
Expand Down Expand Up @@ -283,12 +267,11 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
edit
onReplyCancel={this.handleReplyCancel}
disabled={this.props.locked}
finished={this.props.finished.get(id)}
focus
allLanguages={this.props.allLanguages}
siteLanguages={this.props.siteLanguages}
containerClass="comment-comment-container"
onUpsertComment={this.props.onEditComment}
onUpsertComment={this.handleEditComment}
/>
)}
{!this.state.showEdit && !this.state.collapsed && (
Expand Down Expand Up @@ -425,12 +408,11 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
node={node}
onReplyCancel={this.handleReplyCancel}
disabled={this.props.locked}
finished={this.props.finished.get(id)}
focus
allLanguages={this.props.allLanguages}
siteLanguages={this.props.siteLanguages}
containerClass="comment-comment-container"
onUpsertComment={this.props.onCreateComment}
onUpsertComment={this.handleCreateComment}
/>
)}
{!this.state.collapsed && node.children.length > 0 && (
Expand All @@ -447,7 +429,6 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
hideImages={this.props.hideImages}
isChild={!this.props.isTopLevel}
depth={this.props.node.depth + 1}
finished={this.props.finished}
onCommentReplyRead={this.props.onCommentReplyRead}
onPersonMentionRead={this.props.onPersonMentionRead}
onCreateComment={this.props.onCreateComment}
Expand Down Expand Up @@ -559,6 +540,26 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
this.setState({ showReply: false, showEdit: false });
}

async handleCreateComment(
form: CreateComment,
): Promise<RequestState<CommentResponse>> {
const res = await this.props.onCreateComment(form);
if (res.state !== "failed") {
this.setState({ showReply: false, showEdit: false });
}
return res;
}

async handleEditComment(
form: EditComment,
): Promise<RequestState<CommentResponse>> {
const res = await this.props.onEditComment(form);
if (res.state !== "failed") {
this.setState({ showReply: false, showEdit: false });
}
return res;
}

isPersonMentionType(item: CommentNodeView): item is PersonMentionView {
return item.person_mention?.id !== undefined;
}
Expand Down
3 changes: 0 additions & 3 deletions src/shared/components/comment/comment-nodes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
BanFromCommunity,
BanPerson,
BlockPerson,
CommentId,
CommentResponse,
CommunityModeratorView,
CreateComment,
Expand Down Expand Up @@ -52,7 +51,6 @@ interface CommentNodesProps {
hideImages?: boolean;
isChild?: boolean;
depth?: number;
finished: Map<CommentId, boolean | undefined>;
onSaveComment(form: SaveComment): Promise<void>;
onCommentReplyRead(form: MarkCommentReplyAsRead): void;
onPersonMentionRead(form: MarkPersonMentionAsRead): void;
Expand Down Expand Up @@ -124,7 +122,6 @@ export class CommentNodes extends Component<CommentNodesProps, any> {
hideImages={this.props.hideImages}
onCommentReplyRead={this.props.onCommentReplyRead}
onPersonMentionRead={this.props.onPersonMentionRead}
finished={this.props.finished}
onCreateComment={this.props.onCreateComment}
onEditComment={this.props.onEditComment}
onCommentVote={this.props.onCommentVote}
Expand Down
1 change: 0 additions & 1 deletion src/shared/components/comment/comment-report.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ export class CommentReport extends Component<
siteLanguages={[]}
hideImages
// All of these are unused, since its viewonly
finished={new Map()}
onSaveComment={async () => {}}
onBlockPerson={async () => {}}
onDeleteComment={async () => {}}
Expand Down
38 changes: 10 additions & 28 deletions src/shared/components/common/markdown-textarea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { numToSI, randomStr } from "@utils/helpers";
import autosize from "autosize";
import classNames from "classnames";
import { NoOptionI18nKeys } from "i18next";
import { Component, InfernoNode, linkEvent } from "inferno";
import { Component, linkEvent } from "inferno";
import { Prompt } from "inferno-router";
import { Language } from "lemmy-js-client";
import {
Expand Down Expand Up @@ -41,15 +41,14 @@ interface MarkdownTextAreaProps {
replyType?: boolean;
focus?: boolean;
disabled?: boolean;
finished?: boolean;
/**
* Whether to show the language selector
*/
showLanguage?: boolean;
hideNavigationWarnings?: boolean;
onContentChange?(val: string): void;
onReplyCancel?(): void;
onSubmit?(content: string, languageId?: number): void;
onSubmit?(content: string, languageId?: number): Promise<boolean>;
allLanguages: Language[]; // TODO should probably be nullable
siteLanguages: number[]; // TODO same
}
Expand Down Expand Up @@ -115,27 +114,6 @@ export class MarkdownTextArea extends Component<
}
}

componentWillReceiveProps(
nextProps: MarkdownTextAreaProps & { children?: InfernoNode },
) {
if (nextProps.finished) {
this.setState({
previewMode: false,
imageUploadStatus: undefined,
loading: false,
content: undefined,
});
if (this.props.replyType) {
this.props.onReplyCancel?.();
}

const textarea: any = document.getElementById(this.id);
const form: any = document.getElementById(this.formId);
form.reset();
setTimeout(() => autosize.update(textarea), 10);
}
}

render() {
const languageId = this.state.languageId;

Expand All @@ -149,8 +127,8 @@ export class MarkdownTextArea extends Component<
message={I18NextService.i18n.t("block_leaving")}
when={
!this.props.hideNavigationWarnings &&
!!this.state.content &&
!this.state.submitted
((!!this.state.content && !this.state.submitted) ||
this.state.loading)
}
/>
<div className="mb-3 row">
Expand Down Expand Up @@ -575,11 +553,15 @@ export class MarkdownTextArea extends Component<
this.setState({ languageId: val[0] });
}

handleSubmit(i: MarkdownTextArea, event: any) {
async handleSubmit(i: MarkdownTextArea, event: any) {
event.preventDefault();
if (i.state.content) {
i.setState({ loading: true, submitted: true });
i.props.onSubmit?.(i.state.content, i.state.languageId);
const success = await i.props.onSubmit?.(
i.state.content,
i.state.languageId,
);
i.setState({ loading: false, submitted: success ?? true });
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't onSubmit always return a boolean, making the coalesce for success unnecessary?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

onSubmit is optional, which makes success of type boolean | undefined.

}
}

Expand Down
Loading