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}} + 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")