From f0b11b98942b2189d85bf1d1d48919dfcd0cf72d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20Caux?= <git@jscaux.org>
Date: Fri, 3 Feb 2023 00:39:57 +0100
Subject: [PATCH] Improve targeting and refocusing after post creation

---
 scipost_django/forums/models.py | 16 ++++++++++------
 scipost_django/forums/views.py  | 32 ++++++++++++++++++++++----------
 2 files changed, 32 insertions(+), 16 deletions(-)

diff --git a/scipost_django/forums/models.py b/scipost_django/forums/models.py
index e914b91f6..d0c891de0 100644
--- a/scipost_django/forums/models.py
+++ b/scipost_django/forums/models.py
@@ -336,21 +336,25 @@ class Post(models.Model):
         self.cf_latest_followup_in_hierarchy = self.latest_followup_in_hierarchy
         self.save()
 
-    def get_anchor_forum_or_meeting(self):
+    def get_thread_initiator(self):
         """
-        Climb back the hierarchy up to the original Forum.
-        If no Forum is found, return None.
+        Climb back the hierarchy up to the first post in this thread.
         """
-
         type_forum = ContentType.objects.get_by_natural_key("forums", "forum")
         type_meeting = ContentType.objects.get_by_natural_key("forums", "meeting")
         if (
             self.parent_content_type == type_forum
             or self.parent_content_type == type_meeting
         ):
-            return self.parent
+            return self
         else:
-            return self.parent.get_anchor_forum_or_meeting()
+            return self.parent.get_thread_initiator()
+
+    def get_anchor_forum_or_meeting(self):
+        """
+        Climb back the hierarchy up to the original Forum.
+        """
+        return self.get_thread_initiator().parent
 
 
 class Motion(Post):
diff --git a/scipost_django/forums/views.py b/scipost_django/forums/views.py
index ad7fb2916..9127777c7 100644
--- a/scipost_django/forums/views.py
+++ b/scipost_django/forums/views.py
@@ -484,20 +484,32 @@ def _hx_post_form(request, slug, parent_model, parent_id, origin, target, text):
         form = PostForm(request.POST, forum=forum)
         if form.is_valid():
             post = form.save()
-            response_url = reverse(
-                "forums:_hx_thread_from_post",
-                kwargs={
-                    "slug": forum.slug,
-                    "post_id": post.id if parent_model == "forum" else parent_id,
-                },
-            )
+            thread_initiator = post.get_thread_initiator()
             response = render(
                 request,
                 "forums/post_card.html",
-                context={"forum": forum, "post": post,},
+                context={"forum": forum, "post": thread_initiator},
             )
-            response["HX-Trigger"] = f"newPost-{target}"
-            response["HX-Trigger-After-Settle"] = json.dumps({"newPost": target,})
+            # if the parent is a forum, then this is a new Motion or Post,
+            # and we keep the requested target and swap (== beforebegin).
+            # Otherwise, we retarget to the initiator post, and swap outerHTML.
+            # In both cases we refocus the browser after settle.
+            if parent_model in ["forum", "meeting"]:
+                # trigger new post form closure
+                response["HX-Trigger"] = f"newPost-{target}"
+                # refocus browser on new post
+                response["HX-Trigger-After-Settle"] = json.dumps(
+                    {"newPost": f"{target}",}
+                )
+            else:
+                # force rerendering of whole thread from initiator down
+                response["HX-Retarget"] = f"#thread-{thread_initiator.id}"
+                response["HX-Reswap"] = "outerHTML"
+                # refocus browser on initiator
+                response["HX-Trigger-After-Settle"] = json.dumps(
+                    {"newPost": f"thread-{thread_initiator.id}",}
+                )
+            print(f'{response["HX-Trigger-After-Settle"] = }')
             return response
     else:
         subject = ""
-- 
GitLab