Compare commits

...

5 Commits

Author SHA1 Message Date
Pratik Chanda
ffa9c1e6a3 widget: Hide widgets from muted users like normal messages.
Earlier, messages from muted users were hidden with a hidden dialog
but widgets were still visible.

This commit corrects this behaviour by hiding it if the message
container is supposed to be hidden.

Fixes part of zulip#34886.
2025-10-21 12:27:18 -07:00
Alex Vandiver
a8f0cb2cf9 restart-server: All realm Tornado ports need a restart when they change. 2025-10-21 11:38:03 -07:00
Alex Vandiver
21f08265de restart-server: --tornado-reshard implies --skip-client-reloads.
The flags are marked mutually exclusive, so don't pass both; have the
former imply the latter.
2025-10-21 11:38:03 -07:00
Alex Vandiver
b61b495112 puppet: Update dependencies. 2025-10-21 08:28:18 -07:00
Aman Agrawal
aa17bc20cd message_list_view: Fix failing test.
It was throwing error when running test for
message_list_view without failing the entire test suite.
2025-10-21 08:27:39 -07:00
7 changed files with 81 additions and 42 deletions

View File

@@ -26,7 +26,7 @@ class kandra::aws_tools {
$helper_version = $zulip::common::versions['aws_signing_helper']['version'] $helper_version = $zulip::common::versions['aws_signing_helper']['version']
zulip::external_dep { 'aws_signing_helper': zulip::external_dep { 'aws_signing_helper':
version => $helper_version, version => $helper_version,
url => "https://rolesanywhere.amazonaws.com/releases/${helper_version}/${archname}/Linux/aws_signing_helper", url => "https://rolesanywhere.amazonaws.com/releases/${helper_version}/${archname}/Linux/Amzn2023/aws_signing_helper",
before => File['/root/.aws/config'], before => File['/root/.aws/config'],
} }
file { '/srv/zulip-aws-tools/bin/aws_signing_helper': file { '/srv/zulip-aws-tools/bin/aws_signing_helper':

View File

@@ -53,28 +53,28 @@ class zulip::common {
$versions = { $versions = {
# https://github.com/cactus/go-camo/releases # https://github.com/cactus/go-camo/releases
'go-camo' => { 'go-camo' => {
'version' => '2.6.3', 'version' => '2.7.1',
'goversion' => '1242', 'goversion' => '1252',
'sha256' => { 'sha256' => {
'amd64' => '8ac2122a822366ba4c628fcd99d53e73ac0292456a4cf53548a711ca5500b6d3', 'amd64' => 'dd90f226d9305fcea4a91e90710615ed20b44339e3c4f4425356c80c3203ed8a',
'aarch64' => 'a391d1686c604f7f930ac8d31fb3265a6f1841aab8b7ee426391f1bbf1617b15', 'aarch64' => 'a7f380eca870e0eb26774592271df9d8f2d325f8c45fec5cb989b5c3ef23135a',
}, },
}, },
# https://go.dev/dl/ # https://go.dev/dl/
'golang' => { 'golang' => {
'version' => '1.24.4', 'version' => '1.25.3',
'sha256' => { 'sha256' => {
'amd64' => '77e5da33bb72aeaef1ba4418b6fe511bc4d041873cbf82e5aa6318740df98717', 'amd64' => '0335f314b6e7bfe08c3d0cfaa7c19db961b7b99fb20be62b0a826c992ad14e0f',
'aarch64' => 'd5501ee5aca0f258d5fe9bfaed401958445014495dc115f202d43d5210b45241', 'aarch64' => '1d42ebc84999b5e2069f5e31b67d6fc5d67308adad3e178d5a2ee2c9ff2001f5',
}, },
}, },
# https://github.com/stripe/smokescreen/tags # https://github.com/stripe/smokescreen/tags
'smokescreen-src' => { 'smokescreen-src' => {
'version' => '1b618edf4d3dda409ab7a00cdf3f202e143b5289', 'version' => '3ec99c08f3a42840e6a5c9a47d0f85c6d591f52c',
# Source code, so arch-invariant sha256 # Source code, so arch-invariant sha256
'sha256' => '19ffe07eaab321b3ce33b64d893a09ffc9cb520c8672458b761d0a76147079e3', 'sha256' => '32e18f5bb04001079a05996088ea33600bedd25b6abd0caf636049677a9e94a5',
}, },
# https://github.com/tus/tusd/releases # https://github.com/tus/tusd/releases
@@ -100,28 +100,28 @@ class zulip::common {
# https://docs.aws.amazon.com/rolesanywhere/latest/userguide/credential-helper.html # https://docs.aws.amazon.com/rolesanywhere/latest/userguide/credential-helper.html
'aws_signing_helper' => { 'aws_signing_helper' => {
'version' => '1.7.0', 'version' => '1.7.1',
'sha256' => { 'sha256' => {
'amd64' => 'e932f029b73f97523c1dea2e78e9543d9e2753c387c4c46e77be8c1d9424db0f', 'amd64' => '807f911124a7192bba23c6e8f37f6cb41e9defe4722fbeaf471e2c5951c6229c',
'aarch64' => '800fc208b74cdb64b8c7270c41aa0c9d2f9bf5bba498539513acb30f8eb8f164', 'aarch64' => '5413ea1c86c1747254fc14450f44013ccec32901fb2b70f9105f5679dd6eaa5d',
}, },
}, },
# https://release-registry.services.sentry.io/apps/sentry-cli/latest # https://release-registry.services.sentry.io/apps/sentry-cli/latest
'sentry-cli' => { 'sentry-cli' => {
'version' => '2.46.0', 'version' => '2.56.1',
'sha256' => { 'sha256' => {
'amd64' => 'a55b96a0d5391c5206c2bc028e52dd9797dc3646556291cca09d00a19707f85e', 'amd64' => 'be0bcbf4740c95330cf2d735769f31640d69fd297a2b74ad0cd9ed383814cafa',
'aarch64' => '00b292f4edc9c13b079123b574abe73c012b7357426d34bbbf0bd0a5ab59a491', 'aarch64' => 'cc58bca49593cd6fcda4d934e1bf68f3bed9194156ba122cdb2e4cfd79a23878',
}, },
}, },
# https://grafana.com/grafana/download?edition=oss # https://grafana.com/grafana/download?edition=oss
'grafana' => { 'grafana' => {
'version' => '12.0.2', 'version' => '12.2.0',
'sha256' => { 'sha256' => {
'amd64' => 'c1755b4da918edfd298d5c8d5f1ffce35982ad10e1640ec356570cfb8c34b3e8', 'amd64' => 'c4f53551ed4887c792caeb9d02fa0c1a36e3db9ee8bdda32b1ced810cb135a93',
'aarch64' => 'bc0b186458cc91e2f96a06ecff2b3b4033b1a6ffd2449817e2a430a0b4ae4f12', 'aarch64' => 'ef84a75b6888e4674e3d2a21ae586cda61999ec202298e855c5de71fd242eb35',
}, },
}, },
@@ -145,17 +145,17 @@ class zulip::common {
# https://github.com/prometheus-community/postgres_exporter/tags # https://github.com/prometheus-community/postgres_exporter/tags
'postgres_exporter' => { 'postgres_exporter' => {
'version' => '0.17.1', 'version' => '0.18.1',
'sha256' => { 'sha256' => {
'amd64' => '6da7d2edafd69ecceb08addec876786fa609849f6d5f903987c0d61c3fc89506', 'amd64' => '1630965540d49a4907ad181cef5696306d7a481f87f43978538997e85d357272',
'aarch64' => '405af4e838a3d094d575e5aaeac43bd0a1818aaf2c840a3c8fc2c6fcc77218dc', 'aarch64' => '81c22dc2b6dcc58e9e2b5c0e557301dbf0ca0812ee3113d31984c1a37811d1cc',
}, },
}, },
# https://github.com/prometheus-community/postgres_exporter/pull/843 # https://github.com/prometheus-community/postgres_exporter/pull/843
'postgres_exporter-src' => { 'postgres_exporter-src' => {
'version' => 'a90028d313e914d0736c94bb896c06818afcefb1', 'version' => '8067b51a82bba267497d64b8708e141aa493450c',
'sha256' => 'b52909bda1fc60bcdde1dd800e4d088a7a5027ecafa152e034d30e82329dba41', 'sha256' => '9b74d48019a46fafb88948c8209fa713ccd8d1c34a0d935593ddb301656f0871',
}, },
# https://github.com/ncabatoff/process-exporter/releases # https://github.com/ncabatoff/process-exporter/releases
@@ -169,19 +169,19 @@ class zulip::common {
# https://prometheus.io/download/#prometheus # https://prometheus.io/download/#prometheus
'prometheus' => { 'prometheus' => {
'version' => '3.4.1', 'version' => '3.7.1',
'sha256' => { 'sha256' => {
'amd64' => '09203151c132f36b004615de1a3dea22117ad17e6d7a59962e34f3abf328f312', 'amd64' => 'a2e8a89c09b14b2277e6151e87fc8ed18858486cbf89372656d71fcd666b51da',
'aarch64' => '2a85be1dff46238c0d799674e856c8629c8526168dd26c3de2cecfbfc6f9a0a2', 'aarch64' => '7ede3f3f0541b9bfd2ccca9cef57af80554f131b8e7af8900896c6e49ed2d4ef',
}, },
}, },
# https://github.com/oliver006/redis_exporter/releases # https://github.com/oliver006/redis_exporter/releases
'redis_exporter' => { 'redis_exporter' => {
'version' => '1.74.0', 'version' => '1.79.0',
'sha256' => { 'sha256' => {
'amd64' => '481830d1a238cadfb84dacef9381012c7b2aa1d400baa9bc551995b8839f55a3', 'amd64' => 'cd584b0ec12dfb539c5df0c9cac9ca277f4383022576182e9ecb1df8c45642f0',
'aarch64' => 'a864fed00d83c4f43257738abd0cd09343b075591eae2ee43a573e0c9693c36c', 'aarch64' => '278becb6e7343577846d76d7250a6c84bd18efb9fe893cf4f3d5ee9534b39496',
}, },
}, },
@@ -196,10 +196,10 @@ class zulip::common {
# https://vector.dev/download/ # https://vector.dev/download/
'vector' => { 'vector' => {
'version' => '0.47.0', 'version' => '0.50.0',
'sha256' => { 'sha256' => {
'amd64' => '478c1c85a0279e9f05a4253b518c8e93b6e2154e36e8cb3d8d77c2e496316682', 'amd64' => '951ceb14f2382c1438696552745221c5584d6895f9aa2b0e12ff0e30271d4b0e',
'aarch64' => '614ff0481a901ece8634e734c94c318bf63fca34d00d0605e456dbfa3b5f80b8', 'aarch64' => 'ed73245a88638962093b9b5eb92ba3e17681a7b641e26eac674d07b137a605b8',
}, },
}, },
} }

View File

@@ -25,5 +25,5 @@ fi
# clients getting into reload loops ending in crashing on 500 response # clients getting into reload loops ending in crashing on 500 response
# while Django is restarting. For this reason it's important to # while Django is restarting. For this reason it's important to
# reload nginx only after Django and Tornado. # reload nginx only after Django and Tornado.
"$(dirname "$0")/restart-server" --skip-client-reloads --tornado-reshard "$(dirname "$0")/restart-server" --tornado-reshard
service nginx reload service nginx reload

View File

@@ -195,7 +195,12 @@ def update_tornado_sharding() -> list[int]:
for realm in set().union(old_sharding["shard_map"], new_sharding["shard_map"]): for realm in set().union(old_sharding["shard_map"], new_sharding["shard_map"]):
old_ports = ports_as_set(old_sharding["shard_map"].get(realm, [])) old_ports = ports_as_set(old_sharding["shard_map"].get(realm, []))
new_ports = ports_as_set(new_sharding["shard_map"].get(realm, [])) new_ports = ports_as_set(new_sharding["shard_map"].get(realm, []))
affected_tornados |= old_ports ^ new_ports if old_ports != new_ports:
# A realm sharded across multiple ports gets requests at
# random from nginx, and each does an X-Accel-Redirect to
# the user's right Tornado instance. So all ports in the
# set need a restart when we add or remove ports.
affected_tornados |= old_ports | new_ports
old_regex_set = { old_regex_set = {
(regex, ports_as_set(ports)) for (regex, ports) in old_sharding["shard_regexes"] (regex, ports_as_set(ports)) for (regex, ports) in old_sharding["shard_regexes"]
} }
@@ -303,7 +308,12 @@ if (action == "start" or args.less_graceful) and not args.only_django:
logging.info("Starting workers") logging.info("Starting workers")
subprocess.check_call(["supervisorctl", "start", *workers]) subprocess.check_call(["supervisorctl", "start", *workers])
if has_application_server() and not args.skip_client_reloads and not args.only_django: if (
has_application_server()
and not args.skip_client_reloads
and not args.only_django
and not args.tornado_reshard
):
# All of the servers have been (re)started; now enqueue events in # All of the servers have been (re)started; now enqueue events in
# the Tornado servers to tell clients to reload. # the Tornado servers to tell clients to reload.
logging.info("Sending reload events to clients in the background") logging.info("Sending reload events to clients in the background")

View File

@@ -7,12 +7,14 @@ import type {
QuestionOutboundData, QuestionOutboundData,
VoteOutboundData, VoteOutboundData,
} from "../shared/src/poll_data.ts"; } from "../shared/src/poll_data.ts";
import render_message_hidden_dialog from "../templates/message_hidden_dialog.hbs";
import render_widgets_poll_widget from "../templates/widgets/poll_widget.hbs"; import render_widgets_poll_widget from "../templates/widgets/poll_widget.hbs";
import render_widgets_poll_widget_results from "../templates/widgets/poll_widget_results.hbs"; import render_widgets_poll_widget_results from "../templates/widgets/poll_widget_results.hbs";
import * as blueslip from "./blueslip.ts"; import * as blueslip from "./blueslip.ts";
import {$t} from "./i18n.ts"; import {$t} from "./i18n.ts";
import * as keydown_util from "./keydown_util.ts"; import * as keydown_util from "./keydown_util.ts";
import * as message_lists from "./message_lists.ts";
import type {Message} from "./message_store.ts"; import type {Message} from "./message_store.ts";
import * as people from "./people.ts"; import * as people from "./people.ts";
@@ -49,6 +51,7 @@ export function activate({
comma_separated_names: people.get_full_names_for_poll_option, comma_separated_names: people.get_full_names_for_poll_option,
report_error_function: blueslip.warn, report_error_function: blueslip.warn,
}); });
const message_container = message_lists.current?.view.message_containers.get(message.id);
function update_edit_controls(): void { function update_edit_controls(): void {
const has_question = const has_question =
@@ -230,6 +233,12 @@ export function activate({
} }
const handle_events = function (events: Event[]): void { const handle_events = function (events: Event[]): void {
// We don't have to handle events now since we go through
// handle_event loop again when we unmute the message.
if (message_container?.is_hidden) {
return;
}
for (const event of events) { for (const event of events) {
poll_data.handle_event(event.sender_id, event.data); poll_data.handle_event(event.sender_id, event.data);
} }
@@ -238,9 +247,14 @@ export function activate({
render_results(); render_results();
}; };
build_widget(); if (message_container?.is_hidden) {
render_question(); const html = render_message_hidden_dialog();
render_results(); $elem.html(html);
} else {
build_widget();
render_question();
render_results();
}
return handle_events; return handle_events;
} }

View File

@@ -3,11 +3,13 @@ import _ from "lodash";
import assert from "minimalistic-assert"; import assert from "minimalistic-assert";
import * as z from "zod/mini"; import * as z from "zod/mini";
import render_message_hidden_dialog from "../templates/message_hidden_dialog.hbs";
import render_widgets_todo_widget from "../templates/widgets/todo_widget.hbs"; import render_widgets_todo_widget from "../templates/widgets/todo_widget.hbs";
import render_widgets_todo_widget_tasks from "../templates/widgets/todo_widget_tasks.hbs"; import render_widgets_todo_widget_tasks from "../templates/widgets/todo_widget_tasks.hbs";
import * as blueslip from "./blueslip.ts"; import * as blueslip from "./blueslip.ts";
import {$t} from "./i18n.ts"; import {$t} from "./i18n.ts";
import * as message_lists from "./message_lists.ts";
import type {Message} from "./message_store.ts"; import type {Message} from "./message_store.ts";
import {page_params} from "./page_params.ts"; import {page_params} from "./page_params.ts";
import * as people from "./people.ts"; import * as people from "./people.ts";
@@ -342,6 +344,7 @@ export function activate({
tasks, tasks,
report_error_function: blueslip.warn, report_error_function: blueslip.warn,
}); });
const message_container = message_lists.current?.view.message_containers.get(message.id);
function update_edit_controls(): void { function update_edit_controls(): void {
const has_title = const has_title =
@@ -521,6 +524,12 @@ export function activate({
} }
const handle_events = function (events: Event[]): void { const handle_events = function (events: Event[]): void {
// We don't have to handle events now since we go through
// handle_event loop again when we unmute the message.
if (message_container?.is_hidden) {
return;
}
for (const event of events) { for (const event of events) {
task_data.handle_event(event.sender_id, event.data); task_data.handle_event(event.sender_id, event.data);
} }
@@ -529,9 +538,14 @@ export function activate({
render_results(); render_results();
}; };
build_widget(); if (message_container?.is_hidden) {
render_task_list_title(); const html = render_message_hidden_dialog();
render_results(); $elem.html(html);
} else {
build_widget();
render_task_list_title();
render_results();
}
return handle_events; return handle_events;
} }

View File

@@ -367,6 +367,7 @@ test("muted_message_vars", () => {
test("merge_message_groups", ({mock_template}) => { test("merge_message_groups", ({mock_template}) => {
mock_template("message_list.hbs", false, () => "<message-list-stub>"); mock_template("message_list.hbs", false, () => "<message-list-stub>");
mock_template("bookend.hbs", false, () => "<bookend-stub>");
// MessageListView has lots of DOM code, so we are going to test the message // MessageListView has lots of DOM code, so we are going to test the message
// group merging logic on its own. // group merging logic on its own.