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

Conversation

matc-pub
Copy link
Collaborator

@matc-pub matc-pub commented Jun 1, 2024

I used this snippet for testing, which selectively replaces the form with an empty object. It also adds a one second delay before the request is made. (Comment and post examples: submit_buttons.webm)

diff --git a/src/shared/services/HttpService.ts b/src/shared/services/HttpService.ts
index 7ff9121b..01a0cef7 100644
--- a/src/shared/services/HttpService.ts
+++ b/src/shared/services/HttpService.ts
@@ -1,3 +1,4 @@
+import { isBrowser } from "@utils/browser";
 import { getHttpBase } from "@utils/env";
 import { LemmyHttp } from "lemmy-js-client";
 
@@ -56,6 +57,24 @@ class WrappedLemmyHttpClient {
       if (key !== "constructor") {
         this[key] = async (...args) => {
           try {
+            if (isBrowser()) {
+              if (
+                [
+                  "createPost",
+                  "editPost",
+                  "createComment",
+                  "editComment",
+                  "createPrivateMessage",
+                  "editPrivateMessage",
+                ].includes(key)
+              ) {
+                if (!confirm("Cancel to fail")) {
+                  args[0] = {};
+                }
+                await new Promise(r => setTimeout(r, 1000));
+              }
+            }
+
             const res = await this.rawClient[key](...args);
 
             return {

Comment and post examples with the above snippet: submit_buttons.webm

Copy link
Member

@dessalines dessalines left a comment

Choose a reason for hiding this comment

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

I tested this out and it works great, thx a ton. So nice to get rid of that finished map, and all those lifecycle events.

I'm not sure why the non-relative import doesn't throw an error, because I've almost always seen that. I'd change it to relative just in case tho.

Lets let @SleeplessOne1917 take a look, then we can merge.

import { CommentNodeI } from "../../interfaces";
import { I18NextService, UserService } from "../../services";
import { Icon } from "../common/icon";
import { MarkdownTextArea } from "../common/markdown-textarea";
import { RequestState } from "shared/services/HttpService";
Copy link
Member

Choose a reason for hiding this comment

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

These need to be relative imports, or it'll fail.

@@ -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.

@@ -973,13 +968,19 @@ export class Home extends Component<HomeRouteProps, HomeState> {
const createCommentRes = await HttpService.client.createComment(form);
this.createAndUpdateComments(createCommentRes);

if (createCommentRes.state === "failed") {
Copy link
Member

Choose a reason for hiding this comment

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

Thx, these are going to be handy.

Copy link
Member

@SleeplessOne1917 SleeplessOne1917 left a comment

Choose a reason for hiding this comment

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

Thanks a lot for helping with this. Most of my efforts on making a nice looking UI have been focused on the UI rewrite, so I really appreciate you improving the UX on the current UI while the new one is under development.

import { CommentNodeI } from "../../interfaces";
import { I18NextService, UserService } from "../../services";
import { Icon } from "../common/icon";
import { MarkdownTextArea } from "../common/markdown-textarea";
import { RequestState } from "shared/services/HttpService";
Copy link
Member

Choose a reason for hiding this comment

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

Use a relative import for this. For some reason, VS Code auto-imports from shared/* sometimes, but doing so causes the build to fail.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The Dockerfile builds and runs fine with absolute import. I added a linter rule to catch these in the future.

Comment on lines 86 to 122
handleCommentSubmit(content: string, language_id?: number) {
async handleCommentSubmit(
content: string,
language_id?: number,
): Promise<boolean> {
const { node, onUpsertComment, edit } = this.props;
if (typeof node === "number") {
const post_id = node;
onUpsertComment({
return onUpsertComment({
content,
post_id,
language_id,
});
}).then(r => r.state !== "failed");
} else {
if (edit) {
const comment_id = node.comment_view.comment.id;
onUpsertComment({
return onUpsertComment({
content,
comment_id,
language_id,
});
}).then(r => r.state !== "failed");
} else {
const post_id = node.comment_view.post.id;
const parent_id = node.comment_view.comment.id;
this.props.onUpsertComment({
return onUpsertComment({
content,
parent_id,
post_id,
language_id,
});
}).then(r => r.state !== "failed");
}
}
Copy link
Member

@SleeplessOne1917 SleeplessOne1917 Jun 1, 2024

Choose a reason for hiding this comment

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

I think this would be cleaner as

  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;
      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 {
        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";
  }

Also, if you do use this code, make sure to run prettier on it since Github makes it hard to format code.

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.

@SleeplessOne1917 SleeplessOne1917 merged commit 02fcfa2 into LemmyNet:main Jun 2, 2024
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants