The awkward mishap of premature posting

I’m apparently affected by the “premature posting” ailment in various communication, non-chat-focused apps.

Primarily emails (Gmail) and Discourse.

What happens is that I write my message, and I accidentally send it. This inconvenience happens too often for my taste, and it’s probably because of a keyboard shortcut, like Ctrl + Enter, or (perhaps more commonly?) Tab ↹ then Enter.

I can manage it on Gmail: there’s a short window where you can cancel the email sending. Yay! :raising_hands:
To completely avoid sending my post while I’m writing, I don’t fill in the recipient input. I do that last, just before sending the email.

But on Discourse, for non-PMs, it’s not possible. I tried removing the default category from the Category selector, so I would likely face a “category can’t be blank” message when sending my post, but alas, I can’t.

It’s embarrassing to prematurely submit a topic or a reply. I can delete it right away, but the content remains visible to others (they just have to click the edit icon) because this is Discourse’s default behavior. And I can’t complete the content while it’s deleted, to revert the deletion afterward.

In the end, either I keep my post incomplete (usually in the middle of a sentence or a word :woozy_face:) and patiently edit it, which I don’t like because I’m also slow to write, or I delete it and write a new topic/post instead.

Since it often happens on long messages, or those I have to put a lot of thought into, I’d be happy to have a toggleable lock :locked_with_pen: icon that completely prevents message sending.

I’m not particularly suggesting a Discourse feature for this… Unless it happens to many users :smile:

It’s more about sharing this experience, the subsequent embarrassment of premature sending in Discourse, getting other members’ opinions, and sharing ideas to prevent it.

As for me, even a userscript would do the job. Unfortunately, I don’t know how to prevent Discourse’s keyboard shortcut from sending a post, and neither does the AI.
Edit: see The awkward mishap of premature posting - #10 by Canapin

Are you affected by premature posting?

  • Yes
  • No
0 voters

Would you like to be able to “lock” a composer in Discourse?

  • Yes (built-in)
  • Yes (third-party)
  • No—I like to live on the edge
0 voters

Eager to hear your thoughts!

5 Likes

Me too — when using touch screen. Very annoying.

2 Likes

This is super relatable. Happens to me in Chat[1] as well. Sometimes I wish for a confirmation popup or a 10 second window to permanently delete.


  1. That is, chat in Discourse ↩︎

4 Likes

Premature posting doesn’t really happen for me (I’m on desktop 99% of the time) but I can understand the awkwardness. Would it make sense to give the user a short period of time to hide their post for further editing – perhaps only if there have been no replies?

Edit: of course that still wouldn’t hide the edit history… :sweat_smile:

2 Likes

I respect it, but don’t experience it. I much prefer the edit grace period, since I can re-read and proofread as much as I want, and once a big important post is up I will still be finding errors. The edit hides my crimes well.

Different strokes for different misstrokes.

1 Like

I use an external editor to fill any longish website fields, which of course includes discourse posts. In the editor I have all my usual programmer editor keybindings, so it’s better in about every way. Only when I’m satisfied the text is complete I use copy-paste to transfer it to the composer, and then push the Big Button.

Have you considered this workflow?

2 Likes

It’s interesting to see many different experiences. I never post by mistake on smartphone, only on desktop.

Yes, I use it in other contexts. I first write my message on Google Docs, before copy pasting it to the target messaging application.

But on Discourse it’s a bit annoying when I need to add pictures, quotes, or use Discourse-specific features in my post.


I’ve been writing a draft for several days, and it’s always a bit of a stressful experience each time I work on it. I need to constantly be extra careful not to send it by mistake. :lolsob:

1 Like

When I’m writing a longer post, I’m usinn similar solution. But because I’m trying to drop using Google etc. and I work mostly on iPad, my tool is app Ulysses. Mostly because it can markdown. One kind, not totally same syntax what Discourse uses.

I have some mixed feelings about that. On other side I dislike when I need to separate apps (but I use it for WordPress too; creating content there is painful nowadays), but at same time I have little bit more robust and centralized environment.

Is this bigger question for me? No, it is just annoying. When Discourse changed the style how to leave an unmatured work, was more catastrophic and I lost way too many drafts because of muscle memory :zany_face:

1 Like

A solution might be to compose a PM to yourself that acts as a draft. Even accidentally sending does not cause harm as it’s only visible to you :slight_smile:

2 Likes

Here’s a userscript that adds a toggleable lock on the composer.
It also disables keyboard shortcuts, and works on mobile too.

IXlc8u1sm4

https://greasyfork.org/en/scripts/566254-discourse-composer-safety-lock

Add or remove @match lines to enable it on forums you use.

// ==UserScript==
// @name         Discourse Composer Safety Lock
// @namespace    https://meta.discourse.org
// @version      2.0
// @description  Togglable padlock on the composer to prevent accidental post submission
// @author       Canapin & AI
// @match        https://meta.discourse.org/*
// @grant        none
// @license MIT
// ==/UserScript==
(function () {
  "use strict";
 
  let locked = false;
 
  // Capture-phase listener on #reply-control to block Ctrl/Cmd/Alt+Enter
  function attachBlocker(replyControl) {
    if (replyControl._safetyLockAttached) return;
    replyControl._safetyLockAttached = true;
 
    replyControl.addEventListener(
      "keydown",
      function (e) {
        if (!locked) return;
        if (e.key === "Enter" && (e.ctrlKey || e.metaKey || e.altKey)) {
          e.stopImmediatePropagation();
          e.stopPropagation();
          e.preventDefault();
        }
      },
      true
    );
  }
 
  function updateButtons() {
    const rc = document.getElementById("reply-control");
    if (!rc) return;
    rc.querySelectorAll(".save-or-cancel .btn-primary").forEach((btn) => {
      if (locked) {
        btn.style.pointerEvents = "none";
        btn.style.filter = "grayscale(1) opacity(0.4)";
        btn.setAttribute("tabindex", "-1");
      } else {
        btn.style.pointerEvents = "";
        btn.style.filter = "";
        btn.removeAttribute("tabindex");
      }
    });
  }
 
  // Capture-phase click blocker on save button
  document.addEventListener(
    "click",
    function (e) {
      if (!locked) return;
      if (e.target.closest(".save-or-cancel .btn-primary")) {
        e.stopImmediatePropagation();
        e.stopPropagation();
        e.preventDefault();
      }
    },
    true
  );
 
  // Capture-phase keydown blocker for Enter on focused save button
  document.addEventListener(
    "keydown",
    function (e) {
      if (!locked) return;
      if (
        e.key === "Enter" &&
        e.target.closest(".save-or-cancel .btn-primary")
      ) {
        e.stopImmediatePropagation();
        e.stopPropagation();
        e.preventDefault();
      }
    },
    true
  );
 
  function injectPadlock() {
    if (document.getElementById("composer-lock-btn")) return;
    const title = document.querySelector(".composer-action-title");
    if (!title) return;
 
    const btn = document.createElement("span");
    btn.id = "composer-lock-btn";
    btn.textContent = locked ? "\u{1F512}" : "\u{1F513}";
    btn.style.cssText =
      "cursor:pointer;margin-left:10px;font-size:1.1em;user-select:none;opacity:" +
      (locked ? "1" : "0.5");
 
    btn.addEventListener("click", (e) => {
      e.preventDefault();
      e.stopPropagation();
      locked = !locked;
      btn.textContent = locked ? "\u{1F512}" : "\u{1F513}";
      btn.style.opacity = locked ? "1" : "0.5";
      updateButtons();
    });
 
    title.appendChild(btn);
    updateButtons();
  }
 
  const observer = new MutationObserver(() => {
    const rc = document.getElementById("reply-control");
    if (rc && rc.classList.contains("open")) {
      attachBlocker(rc);
      injectPadlock();
      updateButtons();
    }
  });
 
  observer.observe(document.body, {
    childList: true,
    subtree: true,
    attributes: true,
    attributeFilter: ["class"],
  });
 
  const rc = document.getElementById("reply-control");
  if (rc && rc.classList.contains("open")) {
    attachBlocker(rc);
    injectPadlock();
    updateButtons();
  }
})();
5 Likes

This not a problem I usually have. Not sure why! It has, however, happened to me that I send an email by mistake — more often, I have to say, I have a doubt just after sending the email (wrong recipient? Missing info?) that I’m very happy to be able to lay to rest with the « undo send » link that gmail offers for a few seconds. It doesn’t happen often, though.

So, maybe something similar when posting would make sense. A few seconds to hit the « whoopsie, that shouldn’t have gone out like that » button after posting.

I do this a lot due to shift-enter ctrl-enter shortcuts.

Not a big problem, I just edit the post.

For sensitive stuff, I compose in a separate editor first and paste into the application before sending.

I’ve used the userscript I posted on meta and it truly eases my mind when I write!

Now I wish (I mean more thab before) there would be such a built-in feature :face_with_tongue:

But I see the designer has spoken!

image

:laughing:

1 Like

I put together a simple TC that does this, with a lock/unlock button in the composer.

Will post the Meta topic shortly.

EDIT: Here it is: Lock Composer