web: Add parameters to API requests for empty topic name support.

This commit adds `allow_empty_name: true` to the following
endpoints to receive empty strings as topic name when such
topics are available:
* `GET /messages`
* `GET /messages/{message_id}`
* `GET /messages/{message_id}/history`

Also, it adds `empty_topic_name` client capability for spectators.

These changes are part of the broader effort to enable
support for empty string as a topic name.
This commit is contained in:
Prakhar Pratyush
2025-01-08 20:29:19 +05:30
committed by Tim Abbott
parent 593bd5f757
commit fd67e31163
12 changed files with 19 additions and 1 deletions

View File

@@ -321,6 +321,7 @@ export function quote_message(opts: {
void channel.get({ void channel.get({
url: "/json/messages/" + message_id, url: "/json/messages/" + message_id,
data: {allow_empty_topic_name: true},
success(raw_data) { success(raw_data) {
const data = z.object({raw_content: z.string()}).parse(raw_data); const data = z.object({raw_content: z.string()}).parse(raw_data);
replace_content(message, data.raw_content); replace_content(message, data.raw_content);

View File

@@ -669,6 +669,7 @@ export function start($row: JQuery, edit_box_open_callback?: () => void): void {
const msg_list = message_lists.current; const msg_list = message_lists.current;
void channel.get({ void channel.get({
url: "/json/messages/" + message.id, url: "/json/messages/" + message.id,
data: {allow_empty_topic_name: true},
success(data) { success(data) {
const {raw_content} = z.object({raw_content: z.string()}).parse(data); const {raw_content} = z.object({raw_content: z.string()}).parse(data);
if (message_lists.current === msg_list) { if (message_lists.current === msg_list) {
@@ -1582,6 +1583,7 @@ export function with_first_message_id(
{operator: "channel", operand: stream_id}, {operator: "channel", operand: stream_id},
{operator: "topic", operand: topic_name}, {operator: "topic", operand: topic_name},
]), ]),
allow_empty_topic_name: true,
}; };
void channel.get({ void channel.get({
@@ -1617,6 +1619,7 @@ export function is_message_oldest_or_newest(
{operator: "channel", operand: stream_id}, {operator: "channel", operand: stream_id},
{operator: "topic", operand: topic_name}, {operator: "topic", operand: topic_name},
]), ]),
allow_empty_topic_name: true,
}; };
void channel.get({ void channel.get({

View File

@@ -114,7 +114,10 @@ export function fetch_and_render_message_history(message: Message): void {
show_loading_indicator(); show_loading_indicator();
void channel.get({ void channel.get({
url: "/json/messages/" + message.id + "/history", url: "/json/messages/" + message.id + "/history",
data: {message_id: JSON.stringify(message.id)}, data: {
message_id: JSON.stringify(message.id),
allow_empty_topic_name: true,
},
success(raw_data) { success(raw_data) {
const data = server_message_history_schema.parse(raw_data); const data = server_message_history_schema.parse(raw_data);

View File

@@ -192,6 +192,7 @@ export let update_views_filtered_on_message_property = (
data: { data: {
message_ids: JSON.stringify(message_ids), message_ids: JSON.stringify(message_ids),
narrow: JSON.stringify(filter.terms()), narrow: JSON.stringify(filter.terms()),
allow_empty_topic_name: true,
}, },
success(data) { success(data) {
const messages_to_add: Message[] = []; const messages_to_add: Message[] = [];
@@ -216,6 +217,7 @@ export let update_views_filtered_on_message_property = (
url: "/json/messages", url: "/json/messages",
data: { data: {
message_ids: JSON.stringify(messages_to_fetch), message_ids: JSON.stringify(messages_to_fetch),
allow_empty_topic_name: true,
// We don't filter by narrow here since we can // We don't filter by narrow here since we can
// apply the filter locally and the fetched message // apply the filter locally and the fetched message
// can be used to update other message lists and // can be used to update other message lists and

View File

@@ -59,6 +59,7 @@ type MessageFetchAPIParams = {
num_after: number; num_after: number;
client_gravatar: boolean; client_gravatar: boolean;
narrow?: string; narrow?: string;
allow_empty_topic_name: boolean;
}; };
let first_messages_fetch = true; let first_messages_fetch = true;
@@ -329,6 +330,7 @@ function get_parameters_for_message_fetch_api(opts: MessageFetchOptions): Messag
num_before: opts.num_before, num_before: opts.num_before,
num_after: opts.num_after, num_after: opts.num_after,
client_gravatar: true, client_gravatar: true,
allow_empty_topic_name: true,
}; };
const msg_list_data = opts.msg_list_data; const msg_list_data = opts.msg_list_data;

View File

@@ -110,6 +110,7 @@ export function unstar_all_messages_in_topic(stream_id: number, topic: string):
{operator: "topic", operand: topic}, {operator: "topic", operand: topic},
{operator: "is", operand: "starred"}, {operator: "is", operand: "starred"},
]), ]),
allow_empty_topic_name: true,
}; };
void channel.get({ void channel.get({

View File

@@ -555,6 +555,7 @@ export let show = (raw_terms: NarrowTerm[], show_opts: ShowMessageViewOpts): voi
// for it. // for it.
channel.get({ channel.get({
url: `/json/messages/${id_info.target_id}`, url: `/json/messages/${id_info.target_id}`,
data: {allow_empty_topic_name: true},
success(raw_data) { success(raw_data) {
const data = fetch_message_response_schema.parse(raw_data); const data = fetch_message_response_schema.parse(raw_data);
// After the message is fetched, we make the // After the message is fetched, we make the

View File

@@ -334,6 +334,7 @@ export const realm_schema = z.object({
config: z.record(z.string()), config: z.record(z.string()),
}), }),
), ),
realm_empty_topic_display_name: z.string(),
realm_enable_guest_user_indicator: z.boolean(), realm_enable_guest_user_indicator: z.boolean(),
realm_enable_read_receipts: z.boolean(), realm_enable_read_receipts: z.boolean(),
realm_enable_spectator_access: z.boolean(), realm_enable_spectator_access: z.boolean(),

View File

@@ -56,6 +56,7 @@ export function update_topic_last_message_id(
anchor: "newest", anchor: "newest",
num_before: 1, num_before: 1,
num_after: 0, num_after: 0,
allow_empty_topic_name: true,
}, },
success(data) { success(data) {
const {messages} = z const {messages} = z

View File

@@ -709,6 +709,7 @@ $(() => {
// Set this to true when stream typing notifications are implemented. // Set this to true when stream typing notifications are implemented.
stream_typing_notifications: false, stream_typing_notifications: false,
user_settings_object: true, user_settings_object: true,
empty_topic_name: true,
}), }),
client_gravatar: false, client_gravatar: false,
}; };

View File

@@ -143,6 +143,7 @@ run_test("unstar_all_in_topic", ({override}) => {
{operator: "topic", operand: "topic"}, {operator: "topic", operand: "topic"},
{operator: "is", operand: "starred"}, {operator: "is", operand: "starred"},
]), ]),
allow_empty_topic_name: true,
}); });
assert.deepEqual(channel_post_opts.data, { assert.deepEqual(channel_post_opts.data, {

View File

@@ -426,6 +426,7 @@ test("ask_server_for_latest_topic_data", () => {
narrow: '[{"operator":"stream","operand":1080},{"operator":"topic","operand":"Topic1"}]', narrow: '[{"operator":"stream","operand":1080},{"operator":"topic","operand":"Topic1"}]',
num_after: 0, num_after: 0,
num_before: 1, num_before: 1,
allow_empty_topic_name: true,
}); });
success_callback = opts.success; success_callback = opts.success;
}; };