Repository: zulip/zulip

Issue:
Go to newly created stream (with first-time modal)
Even after #29154, users find it hard to navigate to a newly created stream. To address this, we should:

1. Take the user directly to the stream they just created. To avoid a potentially confusing interleaved view, we should go to the most recent topic in the stream (currently "stream events", but might be "general chat" in the future).
2. The first time that a user creates a stream, show an explanatory modal (wording to be finalized when working on the PR):

----

## Stream **#{stream name}** created!

You will now see the stream you created. If you'd like to go back to stream settings, click on the name of the stream at the top of your Zulip window, or use the **back** button in your browser or desktop app.

[Continue]

---

Since we are changing the behavior, it's fine to show this once to existing users.

[CZO thread](https://chat.zulip.org/#narrow/stream/137-feedback/topic/user.20research.3A.20going.20to.20a.20new.20stream/near/1744305)


Discussion:
Hello @zulip/server-onboarding, @zulip/server-streams members, this issue was labeled with the "area: onboarding", "area: stream settings" labels, so you may want to check it out!

<!-- areaLabelAddition -->

@alya Can I work on this issue?
@kuv2707 You can give this a try if you think you'll be able to get a PR up this week.
Sure!

Resolving patch:
diff --git a/zerver/lib/hotspots.py b/zerver/lib/hotspots.py
--- a/zerver/lib/hotspots.py
+++ b/zerver/lib/hotspots.py
@@ -89,6 +89,9 @@ def to_dict(self) -> Dict[str, str]:
     OneTimeNotice(
         name="intro_recent_view_modal",
     ),
+    OneTimeNotice(
+        name="first_stream_created_banner",
+    ),
 ]
 
 # We would most likely implement new hotspots in the future that aren't


Test patch:
diff --git a/web/e2e-tests/stream_create.test.ts b/web/e2e-tests/stream_create.test.ts
--- a/web/e2e-tests/stream_create.test.ts
+++ b/web/e2e-tests/stream_create.test.ts
@@ -81,6 +81,13 @@ async function create_stream(page: Page): Promise<void> {
         stream_description: "Everything Puppeteer",
     });
     await page.click("form#stream_creation_form .finalize_create_stream");
+    // an explanatory modal is shown for the first stream created
+    await common.wait_for_micromodal_to_open(page);
+    await page.click(".dialog_submit_button");
+    await common.wait_for_micromodal_to_close(page);
+    await page.waitForSelector(".message-header-stream-settings-button");
+    await page.click(".message-header-stream-settings-button");
+    await page.waitForSelector(".stream_section");
     await page.waitForSelector(
         `xpath///*[${common.has_class_x("stream-name")} and text()="Puppeteer"]`,
     );
diff --git a/zerver/tests/test_hotspots.py b/zerver/tests/test_hotspots.py
--- a/zerver/tests/test_hotspots.py
+++ b/zerver/tests/test_hotspots.py
@@ -39,11 +39,12 @@ def test_some_done_some_not(self) -> None:
         do_mark_onboarding_step_as_read(self.user, "intro_streams")
         do_mark_onboarding_step_as_read(self.user, "intro_compose")
         onboarding_steps = get_next_onboarding_steps(self.user)
-        self.assert_length(onboarding_steps, 4)
+        self.assert_length(onboarding_steps, 5)
         self.assertEqual(onboarding_steps[0]["name"], "visibility_policy_banner")
         self.assertEqual(onboarding_steps[1]["name"], "intro_inbox_view_modal")
         self.assertEqual(onboarding_steps[2]["name"], "intro_recent_view_modal")
-        self.assertEqual(onboarding_steps[3]["name"], "intro_topics")
+        self.assertEqual(onboarding_steps[3]["name"], "first_stream_created_banner")
+        self.assertEqual(onboarding_steps[4]["name"], "intro_topics")
 
     def test_all_onboarding_steps_done(self) -> None:
         with self.settings(TUTORIAL_ENABLED=True):