Skip to content

update terminology from 'stream' to 'channel' #1574

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Zulip-terminal Changelog



### Changes in the terminology from 'Stream' to 'channel'
- **Terminology Update**: The term "Stream" has been replaced with "Channel" in the UI for servers supporting the updated terminology. Older servers will continue to display "Stream" to maintain consistency with the server's terminology.

### User Documentation Updates
- Updated all references to "Stream" in the documentation to "Channel."
- Added a FAQ entry to explain the terminology change and its behavior with older servers.

## 0.7.0 - 20 May 2022

This long-awaited release includes contributions from our four 2021
Expand Down
7 changes: 7 additions & 0 deletions docs/FAQ.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
- [Hotkeys don't work as described](#hotkeys-dont-work-as-described)
- [Zulip-term crashed!](#zulip-term-crashed)
- [Something looks wrong! Where's this feature? There's a bug!](#something-looks-wrong-wheres-this-feature-theres-a-bug)
- [Why does the UI show "Channel" instead of "Stream"?](#why-does-the-ui-show-channel-instead-of-stream)

## What Python implementations are supported?

Expand Down Expand Up @@ -497,3 +498,9 @@ Come meet us on the
[#zulip-terminal](https://chat.zulip.org/#narrow/stream/206-zulip-terminal)
stream on *chat.zulip.org*.

## Why does the UI show "Channel" instead of "Stream"?

Starting from a specific Zulip feature level, the term "Stream" has been renamed to "Channel" to align with modern terminology. If you are using an older Zulip server, the UI will still display "Stream" to match the server's terminology. This ensures consistency between the Zulip Terminal and the web or mobile apps.

If you encounter any issues or confusion, feel free to reach out on the [#zulip-terminal](https://chat.zulip.org/#narrow/stream/206-zulip-terminal) stream on *chat.zulip.org*.

24 changes: 12 additions & 12 deletions docs/hotkeys.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
## Switching Messages View
|Command|Key Combination|
| :--- | :---: |
|View the stream of the current message|<kbd>s</kbd>|
|View the of the current message|<kbd>s</kbd>|
|View the topic of the current message|<kbd>S</kbd>|
|Zoom in/out the message's conversation context|<kbd>z</kbd>|
|Switch message view to the compose box target|<kbd>Meta</kbd> + <kbd>.</kbd>|
Expand All @@ -46,8 +46,8 @@
| :--- | :---: |
|Search users|<kbd>w</kbd>|
|Search messages|<kbd>/</kbd>|
|Search streams|<kbd>q</kbd>|
|Search topics in a stream|<kbd>q</kbd>|
|Search s|<kbd>q</kbd>|
|Search topics in a |<kbd>q</kbd>|
|Search emojis from emoji picker|<kbd>p</kbd>|
|Submit search and browse results|<kbd>Enter</kbd>|
|Clear search in current panel|<kbd>Esc</kbd>|
Expand All @@ -63,12 +63,12 @@
|Show/hide message information|<kbd>i</kbd>|
|Show/hide message sender information|<kbd>u</kbd>|

## Stream list actions
## list actions
|Command|Key Combination|
| :--- | :---: |
|Toggle topics in a stream|<kbd>t</kbd>|
|Mute/unmute streams|<kbd>m</kbd>|
|Show/hide stream information & modify settings|<kbd>i</kbd>|
|Toggle topics in a |<kbd>t</kbd>|
|Mute/unmute s|<kbd>m</kbd>|
|Show/hide information & modify settings|<kbd>i</kbd>|

## User list actions
|Command|Key Combination|
Expand All @@ -84,7 +84,7 @@
|Reply mentioning the sender of the current message|<kbd>@</kbd>|
|Reply quoting the current message text|<kbd>></kbd>|
|Reply directly to the sender of the current message|<kbd>R</kbd>|
|New message to a stream|<kbd>c</kbd>|
|New message to a |<kbd>c</kbd>|
|New message to a person or group of people|<kbd>x</kbd>|

## Writing a message
Expand All @@ -93,7 +93,7 @@
|Cycle through recipient and content boxes|<kbd>Tab</kbd>|
|Send a message|<kbd>Ctrl</kbd> + <kbd>d</kbd> / <kbd>Meta</kbd> + <kbd>Enter</kbd>|
|Save current message as a draft|<kbd>Meta</kbd> + <kbd>s</kbd>|
|Autocomplete @mentions, #stream_names, :emoji: and topics|<kbd>Ctrl</kbd> + <kbd>f</kbd>|
|Autocomplete @mentions, #_names, :emoji: and topics|<kbd>Ctrl</kbd> + <kbd>f</kbd>|
|Cycle through autocomplete suggestions in reverse|<kbd>Ctrl</kbd> + <kbd>r</kbd>|
|Exit message compose box|<kbd>Esc</kbd>|
|Insert new line|<kbd>Enter</kbd>|
Expand Down Expand Up @@ -123,11 +123,11 @@
|Delete previous character|<kbd>Ctrl</kbd> + <kbd>h</kbd>|
|Swap with previous character|<kbd>Ctrl</kbd> + <kbd>t</kbd>|

## Stream information (press i to view info of a stream)
## information (press i to view info of a )
|Command|Key Combination|
| :--- | :---: |
|Show/hide stream members|<kbd>m</kbd>|
|Copy stream email to clipboard|<kbd>c</kbd>|
|Show/hide members|<kbd>m</kbd>|
|Copy email to clipboard|<kbd>c</kbd>|

## Message information (press i to view info of a message)
|Command|Key Combination|
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -206,3 +206,4 @@ select = [
# N803: Allow upper-case in test function argument names, eg. ZFL, API
# N806: Allow upper-case in test function variables
"tests/*" = ["N802", "N803", "N806"]

61 changes: 34 additions & 27 deletions tests/config/test_keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@
from zulipterminal.config import keys


AVAILABLE_COMMANDS = list(keys.KEY_BINDINGS.keys())
AVAILABLE_COMMANDS = list(keys.key_config.KEY_BINDINGS.keys())

USED_KEYS = {key for values in keys.KEY_BINDINGS.values() for key in values["keys"]}
USED_KEYS = {
key for values in keys.key_config.KEY_BINDINGS.values() for key in values["keys"]
}


@pytest.fixture(params=keys.KEY_BINDINGS.keys())
@pytest.fixture(params=keys.key_config.KEY_BINDINGS.keys())
def valid_command(request: Any) -> str:
return request.param

Expand All @@ -22,20 +24,20 @@ def invalid_command(request: Any) -> str:


def test_keys_for_command(valid_command: str) -> None:
assert keys.KEY_BINDINGS[valid_command]["keys"] == keys.keys_for_command(
valid_command
)
assert keys.key_config.KEY_BINDINGS[valid_command][
"keys"
] == keys.key_config.keys_for_command(valid_command)


def test_primary_key_for_command(valid_command: str) -> None:
assert keys.KEY_BINDINGS[valid_command]["keys"][0] == keys.primary_key_for_command(
valid_command
)
assert keys.key_config.KEY_BINDINGS[valid_command]["keys"][
0
] == keys.key_config.primary_key_for_command(valid_command)


def test_keys_for_command_invalid_command(invalid_command: str) -> None:
with pytest.raises(keys.InvalidCommand):
keys.keys_for_command(invalid_command)
keys.key_config.keys_for_command(invalid_command)


def test_keys_for_command_identity(valid_command: str) -> None:
Expand All @@ -44,30 +46,33 @@ def test_keys_for_command_identity(valid_command: str) -> None:
new list which validates that the original keys don't get altered
elsewhere unintentionally.
"""
assert id(keys.KEY_BINDINGS[valid_command]["keys"]) != id(
keys.keys_for_command(valid_command)
assert id(keys.key_config.KEY_BINDINGS[valid_command]["keys"]) != id(
keys.key_config.keys_for_command(valid_command)
)


def test_is_command_key_matching_keys(valid_command: str) -> None:
for key in keys.keys_for_command(valid_command):
assert keys.is_command_key(valid_command, key)
for key in keys.key_config.keys_for_command(valid_command):
assert keys.key_config.is_command_key(valid_command, key)


def test_is_command_key_nonmatching_keys(valid_command: str) -> None:
keys_to_test = USED_KEYS - set(keys.keys_for_command(valid_command))
keys_to_test = USED_KEYS - set(keys.key_config.keys_for_command(valid_command))
for key in keys_to_test:
assert not keys.is_command_key(valid_command, key)
assert not keys.key_config.is_command_key(valid_command, key)


def test_is_command_key_invalid_command(invalid_command: str) -> None:
with pytest.raises(keys.InvalidCommand):
keys.is_command_key(invalid_command, "esc") # key doesn't matter
keys.key_config.is_command_key(invalid_command, "esc") # key doesn't matter


def test_HELP_is_not_allowed_as_tip() -> None:
assert keys.KEY_BINDINGS["HELP"]["excluded_from_random_tips"] is True
assert keys.KEY_BINDINGS["HELP"] not in keys.commands_for_random_tips()
assert keys.key_config.KEY_BINDINGS["HELP"]["excluded_from_random_tips"] is True
assert (
keys.key_config.KEY_BINDINGS["HELP"]
not in keys.key_config.commands_for_random_tips()
)


def test_commands_for_random_tips(mocker: MockerFixture) -> None:
Expand Down Expand Up @@ -96,20 +101,22 @@ def test_commands_for_random_tips(mocker: MockerFixture) -> None:
"excluded_from_random_tips": True,
},
}
mocker.patch.dict(keys.KEY_BINDINGS, new_key_bindings, clear=True)
result = keys.commands_for_random_tips()
mocker.patch.dict(keys.key_config.KEY_BINDINGS, new_key_bindings, clear=True)
result = keys.key_config.commands_for_random_tips()
assert len(result) == 2
assert new_key_bindings["BETA"] in result
assert new_key_bindings["GAMMA"] in result


def test_updated_urwid_command_map() -> None:
urwid_to_zt_mapping = {v: k for k, v in keys.ZT_TO_URWID_CMD_MAPPING.items()}
urwid_to_zt_mapping = {
v: k for k, v in keys.key_config.ZT_TO_URWID_CMD_MAPPING.items()
}
# Check if keys in command map are actually the ones in KEY_BINDINGS
for key, urwid_cmd in keys.command_map._command.items():
try:
zt_cmd = urwid_to_zt_mapping[urwid_cmd]
assert key in keys.keys_for_command(zt_cmd)
assert key in keys.key_config.keys_for_command(zt_cmd)
except KeyError:
pass

Expand Down Expand Up @@ -138,7 +145,7 @@ def test_updated_urwid_command_map() -> None:
],
)
def test_display_key_for_urwid_key(urwid_key: str, display_key: str) -> None:
assert keys.display_key_for_urwid_key(urwid_key) == display_key
assert keys.key_config.display_key_for_urwid_key(urwid_key) == display_key


COMMAND_TO_DISPLAY_KEYS = [
Expand All @@ -150,14 +157,14 @@ def test_display_key_for_urwid_key(urwid_key: str, display_key: str) -> None:

@pytest.mark.parametrize("command, display_keys", COMMAND_TO_DISPLAY_KEYS)
def test_display_keys_for_command(command: str, display_keys: List[str]) -> None:
assert keys.display_keys_for_command(command) == display_keys
assert keys.key_config.display_keys_for_command(command) == display_keys


@pytest.mark.parametrize("command, display_keys", COMMAND_TO_DISPLAY_KEYS)
def test_primary_display_key_for_command(command: str, display_keys: List[str]) -> None:
assert keys.primary_display_key_for_command(command) == display_keys[0]
assert keys.key_config.primary_display_key_for_command(command) == display_keys[0]


def test_display_keys_for_command_invalid_command(invalid_command: str) -> None:
with pytest.raises(keys.InvalidCommand):
keys.display_keys_for_command(invalid_command)
keys.key_config.display_keys_for_command(invalid_command)
16 changes: 8 additions & 8 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,7 @@
Message,
MessageType,
)
from zulipterminal.config.keys import (
ZT_TO_URWID_CMD_MAPPING,
keys_for_command,
primary_key_for_command,
)
from zulipterminal.config.keys import key_config
from zulipterminal.helper import (
CustomProfileData,
Index,
Expand Down Expand Up @@ -1495,8 +1491,8 @@ def compose_box_is_open(request: Any) -> bool:

@pytest.fixture(
params=[
("mouse press", 4, primary_key_for_command("GO_UP")),
("mouse press", 5, primary_key_for_command("GO_DOWN")),
("mouse press", 4, key_config.primary_key_for_command("GO_UP")),
("mouse press", 5, key_config.primary_key_for_command("GO_DOWN")),
],
ids=[
"mouse_scroll_up",
Expand All @@ -1511,7 +1507,11 @@ def mouse_scroll_event(request: Any) -> Tuple[Any]:


@pytest.fixture(
params=[key for cmd in ZT_TO_URWID_CMD_MAPPING for key in keys_for_command(cmd)],
params=[
key
for cmd in key_config.ZT_TO_URWID_CMD_MAPPING
for key in key_config.keys_for_command(cmd)
],
ids=lambda param: "nav-key:{}".format(*param),
)
def navigation_key(request: Any) -> str:
Expand Down
4 changes: 2 additions & 2 deletions tests/helper/test_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from pytest_mock import MockerFixture

from zulipterminal.api_types import Composition
from zulipterminal.config.keys import primary_display_key_for_command
from zulipterminal.config.keys import key_config
from zulipterminal.helper import (
Index,
canonicalize_color,
Expand Down Expand Up @@ -469,7 +469,7 @@ def test_notify_if_message_sent_outside_narrow(
notify_if_message_sent_outside_narrow(req, controller)

if footer_updated:
key = primary_display_key_for_command("NARROW_MESSAGE_RECIPIENT")
key = key_config.primary_display_key_for_command("NARROW_MESSAGE_RECIPIENT")
report_success.assert_called_once_with(
[
"Message is sent outside of current narrow."
Expand Down
16 changes: 8 additions & 8 deletions tests/ui/test_ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from urwid import Widget

from zulipterminal.api_types import Composition
from zulipterminal.config.keys import keys_for_command
from zulipterminal.config.keys import key_config
from zulipterminal.ui import LEFT_WIDTH, RIGHT_WIDTH, TAB_WIDTH, View
from zulipterminal.urwid_types import urwid_Box

Expand Down Expand Up @@ -299,7 +299,7 @@ def test_keypress_normal_mode_navigation(

super_keypress.assert_called_once_with(size, navigation_key)

@pytest.mark.parametrize("key", keys_for_command("ALL_MENTIONS"))
@pytest.mark.parametrize("key", key_config.keys_for_command("ALL_MENTIONS"))
def test_keypress_ALL_MENTIONS(
self,
view: View,
Expand All @@ -316,7 +316,7 @@ def test_keypress_ALL_MENTIONS(

view.mentioned_button.activate.assert_called_once_with(key)

@pytest.mark.parametrize("key", keys_for_command("STREAM_MESSAGE"))
@pytest.mark.parametrize("key", key_config.keys_for_command("STREAM_MESSAGE"))
@pytest.mark.parametrize("autohide", [True, False], ids=["autohide", "no_autohide"])
def test_keypress_STREAM_MESSAGE(
self,
Expand All @@ -341,7 +341,7 @@ def test_keypress_STREAM_MESSAGE(
assert returned_key == key
assert view.body.focus_col == 1

@pytest.mark.parametrize("key", keys_for_command("NEW_HINT"))
@pytest.mark.parametrize("key", key_config.keys_for_command("NEW_HINT"))
def test_keypress_NEW_HINT(
self,
view: View,
Expand All @@ -358,7 +358,7 @@ def test_keypress_NEW_HINT(
set_footer_text.assert_called_once_with()
assert returned_key == key

@pytest.mark.parametrize("key", keys_for_command("SEARCH_PEOPLE"))
@pytest.mark.parametrize("key", key_config.keys_for_command("SEARCH_PEOPLE"))
@pytest.mark.parametrize("autohide", [True, False], ids=["autohide", "no_autohide"])
def test_keypress_autohide_users(
self,
Expand All @@ -383,7 +383,7 @@ def test_keypress_autohide_users(
mocked_users_view.keypress.assert_called_once_with(size, key)
assert view.body.focus_position == 2

@pytest.mark.parametrize("key", keys_for_command("SEARCH_STREAMS"))
@pytest.mark.parametrize("key", key_config.keys_for_command("SEARCH_STREAMS"))
@pytest.mark.parametrize("autohide", [True, False], ids=["autohide", "no_autohide"])
def test_keypress_autohide_streams(
self,
Expand Down Expand Up @@ -430,7 +430,7 @@ def test_keypress_autohide_streams(
"no_draft_composition",
],
)
@pytest.mark.parametrize("key", keys_for_command("OPEN_DRAFT"))
@pytest.mark.parametrize("key", key_config.keys_for_command("OPEN_DRAFT"))
@pytest.mark.parametrize("autohide", [True, False], ids=["autohide", "no_autohide"])
def test_keypress_OPEN_DRAFT(
self,
Expand Down Expand Up @@ -479,7 +479,7 @@ def test_keypress_OPEN_DRAFT(
["No draft message was saved in this session."]
)

@pytest.mark.parametrize("key", keys_for_command("SEARCH_PEOPLE"))
@pytest.mark.parametrize("key", key_config.keys_for_command("SEARCH_PEOPLE"))
def test_keypress_edit_mode(
self,
view: View,
Expand Down
Loading
Loading