diff --git a/web/src/base_page_params.ts b/web/src/base_page_params.ts
index ade0bb021a..f4de13654c 100644
--- a/web/src/base_page_params.ts
+++ b/web/src/base_page_params.ts
@@ -43,6 +43,7 @@ const home_params_schema = default_params_schema
// it isn't displayed for logged-in users and requires markdown
// processor time to compute.
realm_rendered_description: z.optional(z.string()),
+ show_try_zulip_modal: z.boolean(),
show_webathena: z.boolean(),
state_data: state_data_schema.nullable(),
translation_data: z.record(z.string()),
diff --git a/web/src/ui_init.js b/web/src/ui_init.js
index 6eb49afbc4..2bc42d6e3c 100644
--- a/web/src/ui_init.js
+++ b/web/src/ui_init.js
@@ -8,6 +8,7 @@ import render_compose from "../templates/compose.hbs";
import render_message_feed_bottom_whitespace from "../templates/message_feed_bottom_whitespace.hbs";
import render_message_feed_errors from "../templates/message_feed_errors.hbs";
import render_navbar from "../templates/navbar.hbs";
+import render_try_zulip_modal from "../templates/try_zulip_modal.hbs";
import * as about_zulip from "./about_zulip.ts";
import * as activity from "./activity.ts";
@@ -40,6 +41,7 @@ import * as condense from "./condense.ts";
import * as copy_messages from "./copy_messages.ts";
import * as desktop_integration from "./desktop_integration.ts";
import * as desktop_notifications from "./desktop_notifications.ts";
+import * as dialog_widget from "./dialog_widget.ts";
import * as drafts from "./drafts.ts";
import * as drafts_overlay_ui from "./drafts_overlay_ui.ts";
import * as echo from "./echo.ts";
@@ -719,8 +721,33 @@ export function initialize_everything(state_data) {
$("#app-loading").addClass("loaded");
}
+function show_try_zulip_modal() {
+ const html_body = render_try_zulip_modal();
+ dialog_widget.launch({
+ text_heading: i18n.$t({defaultMessage: "Welcome to the Zulip development community!"}),
+ html_body,
+ html_submit_button: i18n.$t({defaultMessage: "Let's go!"}),
+ on_click() {
+ // Do nothing
+ },
+ single_footer_button: true,
+ focus_submit_on_open: true,
+ close_on_submit: true,
+ });
+}
+
$(() => {
+ // Remove '?show_try_zulip_modal', if present.
+ const url = new URL(window.location.href);
+ if (url.searchParams.has("show_try_zulip_modal")) {
+ url.searchParams.delete("show_try_zulip_modal");
+ window.history.replaceState(window.history.state, "", url.toString());
+ }
+
if (page_params.is_spectator) {
+ if (page_params.show_try_zulip_modal) {
+ show_try_zulip_modal();
+ }
const data = {
apply_markdown: true,
client_capabilities: JSON.stringify({
diff --git a/web/templates/try_zulip_modal.hbs b/web/templates/try_zulip_modal.hbs
new file mode 100644
index 0000000000..ebaf297f7f
--- /dev/null
+++ b/web/templates/try_zulip_modal.hbs
@@ -0,0 +1,24 @@
+
+ {{t "Explore how hundreds of community participants use Zulip to brainstorm ideas, discuss technical challenges, ask questions, and give feedback:" }}
+
+
+ -
+ {{#tr}}
+ You'll see a list of recent conversations, where each conversation is
+ labeled with a topic by the person who started it. Click on a conversation to
+ view it. You can always get back to recent conversations from the left sidebar.
+ {{/tr}}
+
+ -
+ {{#tr}}
+ Click the name of a channel in the left sidebar, and click on any topic underneath
+ to view one conversation at a time. You can explore discussions of changes to the
+ design of the Zulip app in #design, or see ongoing issue investigations in #issues.
+ {{/tr}}
+
+
+
+ {{#tr}}
+ If you have any questions, please post in the #user questions channel, and we'll be happy to help.
+ {{/tr}}
+
diff --git a/zerver/lib/home.py b/zerver/lib/home.py
index a20a65953c..aabcec6783 100644
--- a/zerver/lib/home.py
+++ b/zerver/lib/home.py
@@ -2,6 +2,7 @@ import calendar
import os
import time
from dataclasses import dataclass
+from urllib.parse import urlsplit
from django.conf import settings
from django.http import HttpRequest
@@ -135,12 +136,17 @@ def build_page_params_for_home_page_load(
if user_profile is None:
request_language = request.COOKIES.get(settings.LANGUAGE_COOKIE_NAME, default_language)
+ split_url = urlsplit(request.build_absolute_uri())
+ show_try_zulip_modal = (
+ settings.DEVELOPMENT or split_url.hostname == "chat.zulip.org"
+ ) and split_url.query == "show_try_zulip_modal"
else:
request_language = get_and_set_request_language(
request,
default_language,
translation.get_language_from_path(request.path_info),
)
+ show_try_zulip_modal = False
furthest_read_time = get_furthest_read_time(user_profile)
two_fa_enabled = settings.TWO_FACTOR_AUTHENTICATION_ENABLED and user_profile is not None
@@ -175,6 +181,7 @@ def build_page_params_for_home_page_load(
# There is no event queue for spectators since
# events support for spectators is not implemented yet.
no_event_queue=user_profile is None,
+ show_try_zulip_modal=show_try_zulip_modal,
)
page_params["state_data"] = state_data
diff --git a/zerver/tests/test_home.py b/zerver/tests/test_home.py
index ceea5a9bf4..4553abaed6 100644
--- a/zerver/tests/test_home.py
+++ b/zerver/tests/test_home.py
@@ -57,6 +57,7 @@ class HomeTest(ZulipTestCase):
"presence_history_limit_days_for_web_app",
"promote_sponsoring_zulip",
"request_language",
+ "show_try_zulip_modal",
"show_webathena",
"state_data",
"test_suite",
@@ -375,6 +376,7 @@ class HomeTest(ZulipTestCase):
"promote_sponsoring_zulip",
"realm_rendered_description",
"request_language",
+ "show_try_zulip_modal",
"show_webathena",
"state_data",
"test_suite",
@@ -386,6 +388,12 @@ class HomeTest(ZulipTestCase):
self.assertCountEqual(page_params, expected_keys)
self.assertIsNone(page_params["state_data"])
+ with self.settings(DEVELOPMENT=True):
+ result = self.client_get("/?show_try_zulip_modal")
+ self.assertEqual(result.status_code, 200)
+ page_params = self._get_page_params(result)
+ self.assertEqual(page_params["show_try_zulip_modal"], True)
+
def test_realm_authentication_methods(self) -> None:
realm = get_realm("zulip")
self.login("desdemona")