home: Add a modal to replace /try-zulip landing page.

This commit adds a modal which will be displayed when
a spectator visits `/?show_try_zulip_modal`.

When a user visits `/?show_try_zulip_modal` and is a spectator,
we set a new `show_try_zulip_modal` field in `page_params` to
`true` (in all other cases, it's `false`).

Based on the `show_try_zulip_modal` page param, the web client
shows the modal.

Fixes part of #34181.
This commit is contained in:
Prakhar Pratyush
2025-03-31 18:20:36 +05:30
committed by Tim Abbott
parent a7d3d61b41
commit f64d7b6e28
5 changed files with 67 additions and 0 deletions

View File

@@ -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()),

View File

@@ -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({

View File

@@ -0,0 +1,24 @@
<p>
{{t "Explore how hundreds of community participants use Zulip to brainstorm ideas, discuss technical challenges, ask questions, and give feedback:" }}
<ul>
<li>
{{#tr}}
You'll see a list of <b>recent conversations</b>, 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}}
</li>
<li>
{{#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 <b>#design</b>, or see ongoing issue investigations in <b>#issues</b>.
{{/tr}}
</li>
</ul>
{{#tr}}
If you have any questions, please post in the <b>#user questions</b> channel, and we'll be happy to help.
{{/tr}}
</p>

View File

@@ -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

View File

@@ -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")