client_capabilities: Add stream_typing_notifications.

This commit is contained in:
Dinesh 2021-04-18 21:42:35 +05:30 committed by Tim Abbott
parent ceb4b239c4
commit 734d935d4a
8 changed files with 19 additions and 0 deletions

View File

@ -1092,6 +1092,7 @@ def do_events_register(
user_avatar_url_field_optional = client_capabilities.get( user_avatar_url_field_optional = client_capabilities.get(
"user_avatar_url_field_optional", False "user_avatar_url_field_optional", False
) )
stream_typing_notifications = client_capabilities.get("stream_typing_notifications", False)
if user_profile.realm.email_address_visibility != Realm.EMAIL_ADDRESS_VISIBILITY_EVERYONE: if user_profile.realm.email_address_visibility != Realm.EMAIL_ADDRESS_VISIBILITY_EVERYONE:
# If real email addresses are not available to the user, their # If real email addresses are not available to the user, their
@ -1111,6 +1112,7 @@ def do_events_register(
all_public_streams, all_public_streams,
narrow=narrow, narrow=narrow,
bulk_message_deletion=bulk_message_deletion, bulk_message_deletion=bulk_message_deletion,
stream_typing_notifications=stream_typing_notifications,
) )
if queue_id is None: if queue_id is None:

View File

@ -162,6 +162,7 @@ def build_page_params_for_home_page_load(
"notification_settings_null": True, "notification_settings_null": True,
"bulk_message_deletion": True, "bulk_message_deletion": True,
"user_avatar_url_field_optional": True, "user_avatar_url_field_optional": True,
"stream_typing_notifications": False, # Set this to True when frontend support is implemented.
} }
if user_profile is not None: if user_profile is not None:

View File

@ -6885,6 +6885,9 @@ paths:
to optimize network performance. This is an important optimization to optimize network performance. This is an important optimization
in organizations with 10,000s of users. in organizations with 10,000s of users.
New in Zulip 3.0 (feature level 18). New in Zulip 3.0 (feature level 18).
* `stream_typing_notifications`: Boolean for whether the client
supports stream typing notifications.
content: content:
application/json: application/json:
schema: schema:

View File

@ -227,6 +227,7 @@ class BaseAction(ZulipTestCase):
include_streams: bool = True, include_streams: bool = True,
num_events: int = 1, num_events: int = 1,
bulk_message_deletion: bool = True, bulk_message_deletion: bool = True,
stream_typing_notifications: bool = True,
) -> List[Dict[str, Any]]: ) -> List[Dict[str, Any]]:
""" """
Make sure we have a clean slate of client descriptors for these tests. Make sure we have a clean slate of client descriptors for these tests.
@ -252,6 +253,7 @@ class BaseAction(ZulipTestCase):
last_connection_time=time.time(), last_connection_time=time.time(),
narrow=[], narrow=[],
bulk_message_deletion=bulk_message_deletion, bulk_message_deletion=bulk_message_deletion,
stream_typing_notifications=stream_typing_notifications,
) )
) )

View File

@ -74,6 +74,7 @@ def request_event_queue(
all_public_streams: bool = False, all_public_streams: bool = False,
narrow: Iterable[Sequence[str]] = [], narrow: Iterable[Sequence[str]] = [],
bulk_message_deletion: bool = False, bulk_message_deletion: bool = False,
stream_typing_notifications: bool = False,
) -> Optional[str]: ) -> Optional[str]:
if not settings.USING_TORNADO: if not settings.USING_TORNADO:
@ -93,6 +94,7 @@ def request_event_queue(
"secret": settings.SHARED_SECRET, "secret": settings.SHARED_SECRET,
"lifespan_secs": queue_lifespan_secs, "lifespan_secs": queue_lifespan_secs,
"bulk_message_deletion": orjson.dumps(bulk_message_deletion), "bulk_message_deletion": orjson.dumps(bulk_message_deletion),
"stream_typing_notifications": orjson.dumps(stream_typing_notifications),
} }
if event_types is not None: if event_types is not None:

View File

@ -86,6 +86,7 @@ class ClientDescriptor:
lifespan_secs: int = 0, lifespan_secs: int = 0,
narrow: Iterable[Sequence[str]] = [], narrow: Iterable[Sequence[str]] = [],
bulk_message_deletion: bool = False, bulk_message_deletion: bool = False,
stream_typing_notifications: bool = False,
) -> None: ) -> None:
# These objects are serialized on shutdown and restored on restart. # These objects are serialized on shutdown and restored on restart.
# If fields are added or semantics are changed, temporary code must be # If fields are added or semantics are changed, temporary code must be
@ -107,6 +108,7 @@ class ClientDescriptor:
self.narrow = narrow self.narrow = narrow
self.narrow_filter = build_narrow_filter(narrow) self.narrow_filter = build_narrow_filter(narrow)
self.bulk_message_deletion = bulk_message_deletion self.bulk_message_deletion = bulk_message_deletion
self.stream_typing_notifications = stream_typing_notifications
# Default for lifespan_secs is DEFAULT_EVENT_QUEUE_TIMEOUT_SECS; # Default for lifespan_secs is DEFAULT_EVENT_QUEUE_TIMEOUT_SECS;
# but users can set it as high as MAX_QUEUE_TIMEOUT_SECS. # but users can set it as high as MAX_QUEUE_TIMEOUT_SECS.
@ -132,6 +134,7 @@ class ClientDescriptor:
narrow=self.narrow, narrow=self.narrow,
client_type_name=self.client_type_name, client_type_name=self.client_type_name,
bulk_message_deletion=self.bulk_message_deletion, bulk_message_deletion=self.bulk_message_deletion,
stream_typing_notifications=self.stream_typing_notifications,
) )
def __repr__(self) -> str: def __repr__(self) -> str:
@ -162,6 +165,7 @@ class ClientDescriptor:
d["queue_timeout"], d["queue_timeout"],
d.get("narrow", []), d.get("narrow", []),
d.get("bulk_message_deletion", False), d.get("bulk_message_deletion", False),
d.get("stream_typing_notifications", False),
) )
ret.last_connection_time = d["last_connection_time"] ret.last_connection_time = d["last_connection_time"]
return ret return ret

View File

@ -97,6 +97,9 @@ def get_events_backend(
bulk_message_deletion: bool = REQ( bulk_message_deletion: bool = REQ(
default=False, json_validator=check_bool, intentionally_undocumented=True default=False, json_validator=check_bool, intentionally_undocumented=True
), ),
stream_typing_notifications: bool = REQ(
default=False, json_validator=check_bool, intentionally_undocumented=True
),
) -> HttpResponse: ) -> HttpResponse:
if all_public_streams and not user_profile.can_access_public_streams(): if all_public_streams and not user_profile.can_access_public_streams():
return json_error(_("User not authorized for this query")) return json_error(_("User not authorized for this query"))
@ -136,6 +139,7 @@ def get_events_backend(
last_connection_time=time.time(), last_connection_time=time.time(),
narrow=narrow, narrow=narrow,
bulk_message_deletion=bulk_message_deletion, bulk_message_deletion=bulk_message_deletion,
stream_typing_notifications=stream_typing_notifications,
) )
result = fetch_events(events_query) result = fetch_events(events_query)

View File

@ -52,6 +52,7 @@ def events_register_backend(
# Any new fields of `client_capabilities` should be optional. Add them here. # Any new fields of `client_capabilities` should be optional. Add them here.
("bulk_message_deletion", check_bool), ("bulk_message_deletion", check_bool),
("user_avatar_url_field_optional", check_bool), ("user_avatar_url_field_optional", check_bool),
("stream_typing_notifications", check_bool),
], ],
value_validator=check_bool, value_validator=check_bool,
), ),