mirror of https://github.com/zulip/zulip.git
stream_pill: Add channel privacy icons in input_pill.
Modify stream pills to add channel privacy decorations inside input pills for areas eg: the UI for adding members to a channel. Partly fixes: #25257.
This commit is contained in:
parent
9e096382cd
commit
6f4d14ddde
|
@ -10,6 +10,7 @@ import * as blueslip from "./blueslip";
|
|||
import type {EmojiRenderingDetails} from "./emoji";
|
||||
import * as keydown_util from "./keydown_util";
|
||||
import type {SearchUserPill} from "./search_pill";
|
||||
import type {StreamSubscription} from "./sub_store";
|
||||
import * as ui_util from "./ui_util";
|
||||
|
||||
// See https://zulip.readthedocs.io/en/latest/subsystems/input-pills.html
|
||||
|
@ -25,6 +26,7 @@ export type InputPillItem<T> = {
|
|||
group_id?: number;
|
||||
// Used for search pills
|
||||
operator?: string;
|
||||
stream?: StreamSubscription;
|
||||
} & T;
|
||||
|
||||
export type InputPillConfig = {
|
||||
|
@ -75,6 +77,8 @@ type InputPillRenderingDetails = {
|
|||
should_add_guest_user_indicator: boolean | undefined;
|
||||
user_id?: number | undefined;
|
||||
group_id?: number | undefined;
|
||||
has_stream?: boolean;
|
||||
stream?: StreamSubscription;
|
||||
};
|
||||
|
||||
// These are the functions that are exposed to other modules.
|
||||
|
@ -203,6 +207,11 @@ export function create<T>(opts: InputPillCreateOptions<T>): InputPillContainer<T
|
|||
opts.img_src = item.img_src;
|
||||
}
|
||||
|
||||
if (item.type === "stream" && item.stream) {
|
||||
opts.has_stream = true;
|
||||
opts.stream = item.stream;
|
||||
}
|
||||
|
||||
if (store.pill_config?.show_user_status_emoji === true) {
|
||||
const has_status = item.status_emoji_info !== undefined;
|
||||
if (has_status) {
|
||||
|
|
|
@ -7,8 +7,7 @@ import type {CombinedPillContainer, CombinedPillItem} from "./typeahead_helper";
|
|||
|
||||
export type StreamPill = {
|
||||
type: "stream";
|
||||
stream_id: number;
|
||||
stream_name: string;
|
||||
stream: StreamSubscription;
|
||||
};
|
||||
|
||||
export type StreamPillWidget = InputPillContainer<StreamPill>;
|
||||
|
@ -18,7 +17,7 @@ export type StreamPillData = StreamSubscription & {type: "stream"};
|
|||
function format_stream_name_and_subscriber_count(sub: StreamSubscription): string {
|
||||
const sub_count = peer_data.get_subscriber_count(sub.stream_id);
|
||||
return $t(
|
||||
{defaultMessage: "#{stream_name}: {sub_count} users"},
|
||||
{defaultMessage: "{stream_name}: {sub_count} users"},
|
||||
{stream_name: sub.name, sub_count},
|
||||
);
|
||||
}
|
||||
|
@ -48,11 +47,15 @@ export function create_item_from_stream_name(
|
|||
return undefined;
|
||||
}
|
||||
|
||||
if (current_items.some((item) => item.type === "stream" && item.stream_id === sub.stream_id)) {
|
||||
if (
|
||||
current_items.some(
|
||||
(item) => item.type === "stream" && item.stream.stream_id === sub.stream_id,
|
||||
)
|
||||
) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let display_value = "#" + sub.name;
|
||||
let display_value = sub.name;
|
||||
if (show_subscriber_count) {
|
||||
display_value = format_stream_name_and_subscriber_count(sub);
|
||||
}
|
||||
|
@ -60,20 +63,19 @@ export function create_item_from_stream_name(
|
|||
return {
|
||||
type: "stream",
|
||||
display_value,
|
||||
stream_id: sub.stream_id,
|
||||
stream_name: sub.name,
|
||||
stream: sub,
|
||||
};
|
||||
}
|
||||
|
||||
export function get_stream_name_from_item(item: InputPillItem<StreamPill>): string {
|
||||
return item.stream_name;
|
||||
return item.stream.name;
|
||||
}
|
||||
|
||||
export function get_user_ids(pill_widget: StreamPillWidget | CombinedPillContainer): number[] {
|
||||
let user_ids = pill_widget
|
||||
.items()
|
||||
.flatMap((item) =>
|
||||
item.type === "stream" ? peer_data.get_subscribers(item.stream_id) : [],
|
||||
item.type === "stream" ? peer_data.get_subscribers(item.stream.stream_id) : [],
|
||||
);
|
||||
user_ids = [...new Set(user_ids)];
|
||||
user_ids.sort((a, b) => a - b);
|
||||
|
@ -85,22 +87,21 @@ export function append_stream(
|
|||
pill_widget: StreamPillWidget | CombinedPillContainer,
|
||||
show_subscriber_count = true,
|
||||
): void {
|
||||
let display_value = "#" + stream.name;
|
||||
let display_value = stream.name;
|
||||
if (show_subscriber_count) {
|
||||
display_value = format_stream_name_and_subscriber_count(stream);
|
||||
}
|
||||
pill_widget.appendValidatedData({
|
||||
type: "stream",
|
||||
display_value,
|
||||
stream_id: stream.stream_id,
|
||||
stream_name: stream.name,
|
||||
stream,
|
||||
});
|
||||
pill_widget.clear_text();
|
||||
}
|
||||
|
||||
export function get_stream_ids(pill_widget: StreamPillWidget | CombinedPillContainer): number[] {
|
||||
const items = pill_widget.items();
|
||||
return items.flatMap((item) => (item.type === "stream" ? item.stream_id : []));
|
||||
return items.flatMap((item) => (item.type === "stream" ? item.stream.stream_id : []));
|
||||
}
|
||||
|
||||
export function filter_taken_streams(
|
||||
|
|
|
@ -39,6 +39,10 @@
|
|||
border-radius: 4px 0 0 4px;
|
||||
}
|
||||
|
||||
.zulip-icon {
|
||||
padding-right: 2px;
|
||||
}
|
||||
|
||||
.pill-label {
|
||||
/* Treat as flex container to better position status
|
||||
emoji and control ellipsis on the pill value. */
|
||||
|
|
|
@ -3,7 +3,18 @@
|
|||
<img class="pill-image" src="{{img_src}}" />
|
||||
{{/if}}
|
||||
<span class="pill-label">
|
||||
<span class="pill-value">{{ display_value }}</span>
|
||||
<span class="pill-value">
|
||||
{{#if has_stream}}
|
||||
{{~#if stream.invite_only ~}}
|
||||
<i class="zulip-icon zulip-icon-lock stream-privacy-type-icon" aria-hidden="true"></i>
|
||||
{{~ else if stream.is_web_public ~}}
|
||||
<i class="zulip-icon zulip-icon-globe stream-privacy-type-icon" aria-hidden="true"></i>
|
||||
{{~ else ~}}
|
||||
<i class="zulip-icon zulip-icon-hashtag stream-privacy-type-icon" aria-hidden="true"></i>
|
||||
{{~/if~}}
|
||||
{{/if}}
|
||||
{{ display_value }}
|
||||
</span>
|
||||
{{~#if should_add_guest_user_indicator}} <i>({{t 'guest'}})</i>{{~/if~}}
|
||||
{{~#if deactivated}} ({{t 'deactivated'}}){{~/if~}}
|
||||
{{~#if has_status~}}
|
||||
|
|
|
@ -200,13 +200,13 @@ run_test("initialize", ({override, override_rewire, mock_template}) => {
|
|||
let expected_value = `<div class="search_list_item">\n <span>Search for zo</span>\n</div>\n`;
|
||||
assert.equal(opts.highlighter_html(source[0]), expected_value);
|
||||
|
||||
expected_value = `<div class="search_list_item">\n <span>sent by</span>\n <span class="pill-container">\n <div class='pill ' tabindex=0>\n <img class="pill-image" src="https://secure.gravatar.com/avatar/0f030c97ab51312c7bbffd3966198ced?d=identicon&version=1&s=50" />\n <span class="pill-label">\n <span class="pill-value"><strong>Zo</strong>e</span></span>\n <div class="exit">\n <a role="button" class="zulip-icon zulip-icon-close pill-close-button"></a>\n </div>\n</div>\n </span>\n</div>\n`;
|
||||
expected_value = `<div class="search_list_item">\n <span>sent by</span>\n <span class="pill-container">\n <div class='pill ' tabindex=0>\n <img class="pill-image" src="https://secure.gravatar.com/avatar/0f030c97ab51312c7bbffd3966198ced?d=identicon&version=1&s=50" />\n <span class="pill-label">\n <span class="pill-value">\n <strong>Zo</strong>e\n </span></span>\n <div class="exit">\n <a role="button" class="zulip-icon zulip-icon-close pill-close-button"></a>\n </div>\n</div>\n </span>\n</div>\n`;
|
||||
assert.equal(opts.highlighter_html(source[1]), expected_value);
|
||||
|
||||
expected_value = `<div class="search_list_item">\n <span>direct messages with</span>\n <span class="pill-container">\n <div class='pill ' tabindex=0>\n <img class="pill-image" src="https://secure.gravatar.com/avatar/0f030c97ab51312c7bbffd3966198ced?d=identicon&version=1&s=50" />\n <span class="pill-label">\n <span class="pill-value"><strong>Zo</strong>e</span></span>\n <div class="exit">\n <a role="button" class="zulip-icon zulip-icon-close pill-close-button"></a>\n </div>\n</div>\n </span>\n</div>\n`;
|
||||
expected_value = `<div class="search_list_item">\n <span>direct messages with</span>\n <span class="pill-container">\n <div class='pill ' tabindex=0>\n <img class="pill-image" src="https://secure.gravatar.com/avatar/0f030c97ab51312c7bbffd3966198ced?d=identicon&version=1&s=50" />\n <span class="pill-label">\n <span class="pill-value">\n <strong>Zo</strong>e\n </span></span>\n <div class="exit">\n <a role="button" class="zulip-icon zulip-icon-close pill-close-button"></a>\n </div>\n</div>\n </span>\n</div>\n`;
|
||||
assert.equal(opts.highlighter_html(source[2]), expected_value);
|
||||
|
||||
expected_value = `<div class="search_list_item">\n <span>group direct messages including</span>\n <span class="pill-container">\n <div class='pill ' tabindex=0>\n <img class="pill-image" src="https://secure.gravatar.com/avatar/0f030c97ab51312c7bbffd3966198ced?d=identicon&version=1&s=50" />\n <span class="pill-label">\n <span class="pill-value"><strong>Zo</strong>e</span></span>\n <div class="exit">\n <a role="button" class="zulip-icon zulip-icon-close pill-close-button"></a>\n </div>\n</div>\n </span>\n</div>\n`;
|
||||
expected_value = `<div class="search_list_item">\n <span>group direct messages including</span>\n <span class="pill-container">\n <div class='pill ' tabindex=0>\n <img class="pill-image" src="https://secure.gravatar.com/avatar/0f030c97ab51312c7bbffd3966198ced?d=identicon&version=1&s=50" />\n <span class="pill-label">\n <span class="pill-value">\n <strong>Zo</strong>e\n </span></span>\n <div class="exit">\n <a role="button" class="zulip-icon zulip-icon-close pill-close-button"></a>\n </div>\n</div>\n </span>\n</div>\n`;
|
||||
assert.equal(opts.highlighter_html(source[3]), expected_value);
|
||||
|
||||
/* Test sorter */
|
||||
|
|
|
@ -32,16 +32,14 @@ peer_data.set_subscribers(denmark.stream_id, [1, 2, 3, 77]);
|
|||
peer_data.set_subscribers(sweden.stream_id, [1, 2, 3, 4, 5]);
|
||||
|
||||
const denmark_pill = {
|
||||
stream_name: denmark.name,
|
||||
stream_id: denmark.stream_id,
|
||||
type: "stream",
|
||||
display_value: "#Denmark: 3 users",
|
||||
display_value: "Denmark: 3 users",
|
||||
stream: denmark,
|
||||
};
|
||||
const sweden_pill = {
|
||||
stream_name: sweden.name,
|
||||
stream_id: sweden.stream_id,
|
||||
type: "stream",
|
||||
display_value: "translated: #Sweden: 5 users",
|
||||
display_value: "translated: Sweden: 5 users",
|
||||
stream: sweden,
|
||||
};
|
||||
|
||||
const subs = [denmark, sweden, germany];
|
||||
|
|
Loading…
Reference in New Issue