mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-04 05:53:43 +00:00 
			
		
		
		
	input pill: Move user pill rendering code to user_pill.
This is part of a larger effort to refactor input_pill to remove custom logic and move it into relevant modules.
This commit is contained in:
		@@ -1,17 +1,16 @@
 | 
				
			|||||||
import $ from "jquery";
 | 
					import $ from "jquery";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import type {InputPillConfig} from "./input_pill";
 | 
					import type {InputPillConfig, InputPillItem} from "./input_pill";
 | 
				
			||||||
import * as input_pill from "./input_pill";
 | 
					import * as input_pill from "./input_pill";
 | 
				
			||||||
import type {User} from "./people";
 | 
					import type {User} from "./people";
 | 
				
			||||||
import * as people from "./people";
 | 
					import * as people from "./people";
 | 
				
			||||||
import type {UserPillWidget} from "./user_pill";
 | 
					import type {UserPill, UserPillWidget} from "./user_pill";
 | 
				
			||||||
import * as user_pill from "./user_pill";
 | 
					import * as user_pill from "./user_pill";
 | 
				
			||||||
import * as util from "./util";
 | 
					import * as util from "./util";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export let widget: UserPillWidget;
 | 
					export let widget: UserPillWidget;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const pill_config: InputPillConfig = {
 | 
					const pill_config: InputPillConfig = {
 | 
				
			||||||
    show_user_status_emoji: true,
 | 
					 | 
				
			||||||
    exclude_inaccessible_users: true,
 | 
					    exclude_inaccessible_users: true,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -23,6 +22,8 @@ export function initialize_pill(): UserPillWidget {
 | 
				
			|||||||
        pill_config,
 | 
					        pill_config,
 | 
				
			||||||
        create_item_from_text: user_pill.create_item_from_email,
 | 
					        create_item_from_text: user_pill.create_item_from_email,
 | 
				
			||||||
        get_text_from_item: user_pill.get_email_from_item,
 | 
					        get_text_from_item: user_pill.get_email_from_item,
 | 
				
			||||||
 | 
					        generate_pill_html: (item: InputPillItem<UserPill>) =>
 | 
				
			||||||
 | 
					            user_pill.generate_pill_html(item, true),
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return pill;
 | 
					    return pill;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,7 +29,6 @@ export type InputPillItem<ItemType> = {
 | 
				
			|||||||
} & ItemType;
 | 
					} & ItemType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type InputPillConfig = {
 | 
					export type InputPillConfig = {
 | 
				
			||||||
    show_user_status_emoji?: boolean;
 | 
					 | 
				
			||||||
    exclude_inaccessible_users?: boolean;
 | 
					    exclude_inaccessible_users?: boolean;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -70,13 +69,6 @@ type InputPillStore<ItemType> = {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
type InputPillRenderingDetails = {
 | 
					type InputPillRenderingDetails = {
 | 
				
			||||||
    display_value: string;
 | 
					    display_value: string;
 | 
				
			||||||
    has_image: boolean;
 | 
					 | 
				
			||||||
    img_src?: string | undefined;
 | 
					 | 
				
			||||||
    deactivated: boolean | undefined;
 | 
					 | 
				
			||||||
    has_status?: boolean;
 | 
					 | 
				
			||||||
    status_emoji_info?: (EmojiRenderingDetails & {emoji_alt_code?: boolean}) | undefined;
 | 
					 | 
				
			||||||
    should_add_guest_user_indicator: boolean | undefined;
 | 
					 | 
				
			||||||
    user_id?: number | undefined;
 | 
					 | 
				
			||||||
    group_id?: number | undefined;
 | 
					    group_id?: number | undefined;
 | 
				
			||||||
    has_stream?: boolean;
 | 
					    has_stream?: boolean;
 | 
				
			||||||
    stream?: StreamSubscription;
 | 
					    stream?: StreamSubscription;
 | 
				
			||||||
@@ -178,38 +170,18 @@ export function create<ItemType>(
 | 
				
			|||||||
            if (store.generate_pill_html !== undefined) {
 | 
					            if (store.generate_pill_html !== undefined) {
 | 
				
			||||||
                pill_html = store.generate_pill_html(item);
 | 
					                pill_html = store.generate_pill_html(item);
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                const has_image = item.img_src !== undefined;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                const opts: InputPillRenderingDetails = {
 | 
					                const opts: InputPillRenderingDetails = {
 | 
				
			||||||
                    display_value: item.display_value,
 | 
					                    display_value: item.display_value,
 | 
				
			||||||
                    has_image,
 | 
					 | 
				
			||||||
                    deactivated: item.deactivated,
 | 
					 | 
				
			||||||
                    should_add_guest_user_indicator: item.should_add_guest_user_indicator,
 | 
					 | 
				
			||||||
                };
 | 
					                };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (item.user_id) {
 | 
					 | 
				
			||||||
                    opts.user_id = item.user_id;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                if (item.group_id) {
 | 
					                if (item.group_id) {
 | 
				
			||||||
                    opts.group_id = item.group_id;
 | 
					                    opts.group_id = item.group_id;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (has_image) {
 | 
					 | 
				
			||||||
                    opts.img_src = item.img_src;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if (item.type === "stream" && item.stream) {
 | 
					                if (item.type === "stream" && item.stream) {
 | 
				
			||||||
                    opts.has_stream = true;
 | 
					                    opts.has_stream = true;
 | 
				
			||||||
                    opts.stream = item.stream;
 | 
					                    opts.stream = item.stream;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					 | 
				
			||||||
                if (store.pill_config?.show_user_status_emoji === true) {
 | 
					 | 
				
			||||||
                    const has_status = item.status_emoji_info !== undefined;
 | 
					 | 
				
			||||||
                    if (has_status) {
 | 
					 | 
				
			||||||
                        opts.status_emoji_info = item.status_emoji_info;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    opts.has_status = has_status;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                pill_html = render_input_pill(opts);
 | 
					                pill_html = render_input_pill(opts);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            const payload: InputPill<ItemType> = {
 | 
					            const payload: InputPill<ItemType> = {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,5 @@
 | 
				
			|||||||
 | 
					import render_input_pill from "../templates/input_pill.hbs";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import * as blueslip from "./blueslip";
 | 
					import * as blueslip from "./blueslip";
 | 
				
			||||||
import type {InputPillConfig, InputPillContainer, InputPillItem} from "./input_pill";
 | 
					import type {InputPillConfig, InputPillContainer, InputPillItem} from "./input_pill";
 | 
				
			||||||
import * as input_pill from "./input_pill";
 | 
					import * as input_pill from "./input_pill";
 | 
				
			||||||
@@ -159,6 +161,30 @@ export function append_user(user: User, pills: UserPillWidget | CombinedPillCont
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function generate_pill_html(
 | 
				
			||||||
 | 
					    item: InputPillItem<UserPill>,
 | 
				
			||||||
 | 
					    show_user_status_emoji = false,
 | 
				
			||||||
 | 
					): string {
 | 
				
			||||||
 | 
					    let status_emoji_info;
 | 
				
			||||||
 | 
					    let has_status;
 | 
				
			||||||
 | 
					    if (show_user_status_emoji) {
 | 
				
			||||||
 | 
					        has_status = item.status_emoji_info !== undefined;
 | 
				
			||||||
 | 
					        if (has_status) {
 | 
				
			||||||
 | 
					            status_emoji_info = item.status_emoji_info;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return render_input_pill({
 | 
				
			||||||
 | 
					        display_value: item.display_value,
 | 
				
			||||||
 | 
					        has_image: item.img_src !== undefined,
 | 
				
			||||||
 | 
					        deactivated: item.deactivated,
 | 
				
			||||||
 | 
					        should_add_guest_user_indicator: item.should_add_guest_user_indicator,
 | 
				
			||||||
 | 
					        user_id: item.user_id,
 | 
				
			||||||
 | 
					        img_src: item.img_src,
 | 
				
			||||||
 | 
					        has_status,
 | 
				
			||||||
 | 
					        status_emoji_info,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function create_pills(
 | 
					export function create_pills(
 | 
				
			||||||
    $pill_container: JQuery,
 | 
					    $pill_container: JQuery,
 | 
				
			||||||
    pill_config?: InputPillConfig | undefined,
 | 
					    pill_config?: InputPillConfig | undefined,
 | 
				
			||||||
@@ -168,6 +194,7 @@ export function create_pills(
 | 
				
			|||||||
        pill_config,
 | 
					        pill_config,
 | 
				
			||||||
        create_item_from_text: create_item_from_email,
 | 
					        create_item_from_text: create_item_from_email,
 | 
				
			||||||
        get_text_from_item: get_email_from_item,
 | 
					        get_text_from_item: get_email_from_item,
 | 
				
			||||||
 | 
					        generate_pill_html,
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    return pills;
 | 
					    return pills;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,8 +11,6 @@ set_global("document", {});
 | 
				
			|||||||
class ClipboardEvent {}
 | 
					class ClipboardEvent {}
 | 
				
			||||||
set_global("ClipboardEvent", ClipboardEvent);
 | 
					set_global("ClipboardEvent", ClipboardEvent);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const example_img_link = "http://example.com/example.png";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
mock_esm("../src/ui_util", {
 | 
					mock_esm("../src/ui_util", {
 | 
				
			||||||
    place_caret_at_end: noop,
 | 
					    place_caret_at_end: noop,
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
@@ -23,24 +21,10 @@ set_global("getSelection", () => ({
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const input_pill = zrequire("input_pill");
 | 
					const input_pill = zrequire("input_pill");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function pill_html(value, img_src, status_emoji_info) {
 | 
					function pill_html(value) {
 | 
				
			||||||
    const has_image = img_src !== undefined;
 | 
					 | 
				
			||||||
    const has_status = status_emoji_info !== undefined;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const opts = {
 | 
					    const opts = {
 | 
				
			||||||
        display_value: value,
 | 
					        display_value: value,
 | 
				
			||||||
        has_image,
 | 
					 | 
				
			||||||
        has_status,
 | 
					 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (has_image) {
 | 
					 | 
				
			||||||
        opts.img_src = img_src;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (has_status) {
 | 
					 | 
				
			||||||
        opts.status_emoji_info = status_emoji_info;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return require("../templates/input_pill.hbs")(opts);
 | 
					    return require("../templates/input_pill.hbs")(opts);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -58,24 +42,17 @@ run_test("basics", ({mock_template}) => {
 | 
				
			|||||||
        $container,
 | 
					        $container,
 | 
				
			||||||
        create_item_from_text: noop,
 | 
					        create_item_from_text: noop,
 | 
				
			||||||
        get_text_from_item: noop,
 | 
					        get_text_from_item: noop,
 | 
				
			||||||
        pill_config: {
 | 
					 | 
				
			||||||
            show_user_status_emoji: true,
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    const status_emoji_info = {emoji_code: "5"};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // type for a pill can be any string but it needs to be
 | 
					    // type for a pill can be any string but it needs to be
 | 
				
			||||||
    // defined while creating any pill.
 | 
					    // defined while creating any pill.
 | 
				
			||||||
    const item = {
 | 
					    const item = {
 | 
				
			||||||
        display_value: "JavaScript",
 | 
					        display_value: "JavaScript",
 | 
				
			||||||
        language: "js",
 | 
					 | 
				
			||||||
        type: "language",
 | 
					        type: "language",
 | 
				
			||||||
        img_src: example_img_link,
 | 
					 | 
				
			||||||
        status_emoji_info,
 | 
					 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let inserted_before;
 | 
					    let inserted_before;
 | 
				
			||||||
    const expected_html = pill_html("JavaScript", example_img_link, status_emoji_info);
 | 
					    const expected_html = pill_html("JavaScript");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $pill_input.before = ($elem) => {
 | 
					    $pill_input.before = ($elem) => {
 | 
				
			||||||
        inserted_before = true;
 | 
					        inserted_before = true;
 | 
				
			||||||
@@ -94,7 +71,6 @@ function set_up() {
 | 
				
			|||||||
            display_value: "BLUE",
 | 
					            display_value: "BLUE",
 | 
				
			||||||
            description: "color of the sky",
 | 
					            description: "color of the sky",
 | 
				
			||||||
            type: "color",
 | 
					            type: "color",
 | 
				
			||||||
            img_src: example_img_link,
 | 
					 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        red: {
 | 
					        red: {
 | 
				
			||||||
@@ -172,10 +148,7 @@ run_test("copy from pill", ({mock_template}) => {
 | 
				
			|||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
run_test("paste to input", ({mock_template}) => {
 | 
					run_test("paste to input", ({mock_template}) => {
 | 
				
			||||||
    mock_template("input_pill.hbs", true, (data, html) => {
 | 
					    mock_template("input_pill.hbs", true, (_data, html) => html);
 | 
				
			||||||
        assert.equal(typeof data.has_image, "boolean");
 | 
					 | 
				
			||||||
        return html;
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const info = set_up();
 | 
					    const info = set_up();
 | 
				
			||||||
    const config = info.config;
 | 
					    const config = info.config;
 | 
				
			||||||
@@ -219,10 +192,7 @@ run_test("paste to input", ({mock_template}) => {
 | 
				
			|||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
run_test("arrows on pills", ({mock_template}) => {
 | 
					run_test("arrows on pills", ({mock_template}) => {
 | 
				
			||||||
    mock_template("input_pill.hbs", true, (data, html) => {
 | 
					    mock_template("input_pill.hbs", true, (_data, html) => html);
 | 
				
			||||||
        assert.equal(typeof data.has_image, "boolean");
 | 
					 | 
				
			||||||
        return html;
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const info = set_up();
 | 
					    const info = set_up();
 | 
				
			||||||
    const config = info.config;
 | 
					    const config = info.config;
 | 
				
			||||||
@@ -413,11 +383,7 @@ run_test("insert_remove", ({mock_template}) => {
 | 
				
			|||||||
    assert.ok(created);
 | 
					    assert.ok(created);
 | 
				
			||||||
    assert.ok(!removed);
 | 
					    assert.ok(!removed);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    assert.deepEqual(inserted_html, [
 | 
					    assert.deepEqual(inserted_html, [pill_html("BLUE"), pill_html("RED"), pill_html("YELLOW")]);
 | 
				
			||||||
        pill_html("BLUE", example_img_link),
 | 
					 | 
				
			||||||
        pill_html("RED"),
 | 
					 | 
				
			||||||
        pill_html("YELLOW"),
 | 
					 | 
				
			||||||
    ]);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    assert.deepEqual(widget.items(), [items.blue, items.red, items.yellow]);
 | 
					    assert.deepEqual(widget.items(), [items.blue, items.red, items.yellow]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -568,7 +534,6 @@ run_test("misc things", () => {
 | 
				
			|||||||
    widget.appendValidatedData({
 | 
					    widget.appendValidatedData({
 | 
				
			||||||
        display_value: "This item has no type.",
 | 
					        display_value: "This item has no type.",
 | 
				
			||||||
        language: "js",
 | 
					        language: "js",
 | 
				
			||||||
        img_src: example_img_link,
 | 
					 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // click on container
 | 
					    // click on container
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -139,7 +139,6 @@ run_test("set_up_user", ({mock_template, override, override_rewire}) => {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
    mock_template("input_pill.hbs", true, (data, html) => {
 | 
					    mock_template("input_pill.hbs", true, (data, html) => {
 | 
				
			||||||
        assert.equal(typeof data.display_value, "string");
 | 
					        assert.equal(typeof data.display_value, "string");
 | 
				
			||||||
        assert.equal(typeof data.has_image, "boolean");
 | 
					 | 
				
			||||||
        return html;
 | 
					        return html;
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    let input_pill_typeahead_called = false;
 | 
					    let input_pill_typeahead_called = false;
 | 
				
			||||||
@@ -231,7 +230,6 @@ run_test("set_up_stream", ({mock_template, override, override_rewire}) => {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
    mock_template("input_pill.hbs", true, (data, html) => {
 | 
					    mock_template("input_pill.hbs", true, (data, html) => {
 | 
				
			||||||
        assert.equal(typeof data.display_value, "string");
 | 
					        assert.equal(typeof data.display_value, "string");
 | 
				
			||||||
        assert.equal(typeof data.has_image, "boolean");
 | 
					 | 
				
			||||||
        return html;
 | 
					        return html;
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    let input_pill_typeahead_called = false;
 | 
					    let input_pill_typeahead_called = false;
 | 
				
			||||||
@@ -319,7 +317,6 @@ run_test("set_up_combined", ({mock_template, override, override_rewire}) => {
 | 
				
			|||||||
    override_typeahead_helper(override_rewire);
 | 
					    override_typeahead_helper(override_rewire);
 | 
				
			||||||
    mock_template("input_pill.hbs", true, (data, html) => {
 | 
					    mock_template("input_pill.hbs", true, (data, html) => {
 | 
				
			||||||
        assert.equal(typeof data.display_value, "string");
 | 
					        assert.equal(typeof data.display_value, "string");
 | 
				
			||||||
        assert.equal(typeof data.has_image, "boolean");
 | 
					 | 
				
			||||||
        return html;
 | 
					        return html;
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    let input_pill_typeahead_called = false;
 | 
					    let input_pill_typeahead_called = false;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user