mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-04 05:53:43 +00:00 
			
		
		
		
	This commit adds typing indicators for message editing in stream as well as in dm, if the send typing notification for corresponding is enabled. Based on earlier work in #28585. Co-authored-by: Rohan Gudimetla <rohan.gudimetla07@gmail.com> Fixes #25719.
		
			
				
	
	
		
			266 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			266 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
"use strict";
 | 
						|
 | 
						|
const assert = require("node:assert/strict");
 | 
						|
 | 
						|
const {set_global, zrequire} = require("./lib/namespace.cjs");
 | 
						|
const {run_test} = require("./lib/test.cjs");
 | 
						|
 | 
						|
const muted_users = zrequire("muted_users");
 | 
						|
const typing_data = zrequire("typing_data");
 | 
						|
 | 
						|
function test(label, f) {
 | 
						|
    run_test(label, ({override}) => {
 | 
						|
        typing_data.clear_for_testing();
 | 
						|
        muted_users.set_muted_users([]);
 | 
						|
        f({override});
 | 
						|
    });
 | 
						|
}
 | 
						|
 | 
						|
test("basics", () => {
 | 
						|
    // The typing_data needs to be robust with lists of
 | 
						|
    // user ids being in arbitrary sorting order. So all
 | 
						|
    // the apparent randomness in these tests has a purpose.
 | 
						|
 | 
						|
    const stream_id = 1;
 | 
						|
    const topic = "typing notifications";
 | 
						|
    const topic_typing_key = typing_data.get_topic_key(stream_id, topic);
 | 
						|
    let status;
 | 
						|
 | 
						|
    typing_data.add_typist(typing_data.get_direct_message_conversation_key([5, 10, 15]), 15);
 | 
						|
    assert.deepEqual(typing_data.get_group_typists([15, 10, 5]), [15]);
 | 
						|
 | 
						|
    typing_data.add_typist(topic_typing_key, 12);
 | 
						|
    assert.deepEqual(typing_data.get_topic_typists(stream_id, topic), [12]);
 | 
						|
 | 
						|
    // test that you can add a message_id to messages editing state
 | 
						|
    typing_data.add_edit_message_typing_id(3);
 | 
						|
    assert.deepEqual(typing_data.is_message_editing(3), true);
 | 
						|
 | 
						|
    typing_data.add_edit_message_typing_id(7);
 | 
						|
    assert.deepEqual(typing_data.is_message_editing(7), true);
 | 
						|
 | 
						|
    // test removing a message from editing state
 | 
						|
    status = typing_data.remove_edit_message_typing_id(3);
 | 
						|
    assert.deepEqual(status, true);
 | 
						|
    assert.deepEqual(typing_data.is_message_editing(3), false);
 | 
						|
 | 
						|
    // test removing message_id that doesn't exist from editing
 | 
						|
    assert.deepEqual(typing_data.is_message_editing(3), false);
 | 
						|
    status = typing_data.remove_edit_message_typing_id(3);
 | 
						|
    assert.deepEqual(status, false);
 | 
						|
 | 
						|
    // test that you can add twice
 | 
						|
    typing_data.add_typist(typing_data.get_direct_message_conversation_key([5, 10, 15]), 15);
 | 
						|
 | 
						|
    // add another id to our first group
 | 
						|
    typing_data.add_typist(typing_data.get_direct_message_conversation_key([5, 10, 15]), 10);
 | 
						|
    assert.deepEqual(typing_data.get_group_typists([10, 15, 5]), [10, 15]);
 | 
						|
 | 
						|
    typing_data.add_typist(topic_typing_key, 12);
 | 
						|
 | 
						|
    // add another typist to our stream/topic
 | 
						|
    typing_data.add_typist(topic_typing_key, 13);
 | 
						|
    assert.deepEqual(typing_data.get_topic_typists(stream_id, topic), [12, 13]);
 | 
						|
 | 
						|
    // start adding to a new group
 | 
						|
    typing_data.add_typist(typing_data.get_direct_message_conversation_key([7, 15]), 7);
 | 
						|
    typing_data.add_typist(typing_data.get_direct_message_conversation_key([7, 15]), 15);
 | 
						|
 | 
						|
    // test get_all_direct_message_typists
 | 
						|
    assert.deepEqual(typing_data.get_all_direct_message_typists(), [7, 10, 15]);
 | 
						|
 | 
						|
    // test basic removal
 | 
						|
    assert.ok(
 | 
						|
        typing_data.remove_typist(typing_data.get_direct_message_conversation_key([15, 7]), 7),
 | 
						|
    );
 | 
						|
    assert.deepEqual(typing_data.get_group_typists([7, 15]), [15]);
 | 
						|
    assert.ok(typing_data.remove_typist(topic_typing_key, 12));
 | 
						|
    assert.deepEqual(typing_data.get_topic_typists(stream_id, topic), [13]);
 | 
						|
 | 
						|
    // test removing an id that is not there
 | 
						|
    assert.ok(
 | 
						|
        !typing_data.remove_typist(typing_data.get_direct_message_conversation_key([15, 7]), 7),
 | 
						|
    );
 | 
						|
    assert.deepEqual(typing_data.get_group_typists([7, 15]), [15]);
 | 
						|
    assert.deepEqual(typing_data.get_all_direct_message_typists(), [10, 15]);
 | 
						|
 | 
						|
    // remove user from one group, but "15" will still be among
 | 
						|
    // "all typists"
 | 
						|
    assert.ok(
 | 
						|
        typing_data.remove_typist(typing_data.get_direct_message_conversation_key([15, 7]), 15),
 | 
						|
    );
 | 
						|
    assert.deepEqual(typing_data.get_all_direct_message_typists(), [10, 15]);
 | 
						|
 | 
						|
    // now remove from the other group
 | 
						|
    assert.ok(
 | 
						|
        typing_data.remove_typist(typing_data.get_direct_message_conversation_key([5, 15, 10]), 15),
 | 
						|
    );
 | 
						|
    assert.deepEqual(typing_data.get_all_direct_message_typists(), [10]);
 | 
						|
 | 
						|
    // test duplicate ids in a groups
 | 
						|
    typing_data.add_typist(typing_data.get_direct_message_conversation_key([20, 40, 20]), 20);
 | 
						|
    assert.deepEqual(typing_data.get_group_typists([20, 40]), [20]);
 | 
						|
 | 
						|
    // test clearing out typing data
 | 
						|
    typing_data.clear_typing_data();
 | 
						|
    assert.deepEqual(typing_data.get_group_typists(), []);
 | 
						|
    assert.deepEqual(typing_data.get_all_direct_message_typists(), []);
 | 
						|
    assert.deepEqual(typing_data.get_topic_typists(stream_id, topic), []);
 | 
						|
});
 | 
						|
 | 
						|
test("muted_typists_excluded", () => {
 | 
						|
    const stream_id = 1;
 | 
						|
    const topic = "typing notifications";
 | 
						|
    const topic_typing_key = typing_data.get_topic_key(stream_id, topic);
 | 
						|
 | 
						|
    typing_data.add_typist(typing_data.get_direct_message_conversation_key([5, 10, 15]), 5);
 | 
						|
    typing_data.add_typist(typing_data.get_direct_message_conversation_key([5, 10, 15]), 10);
 | 
						|
    typing_data.add_typist(topic_typing_key, 7);
 | 
						|
    typing_data.add_typist(topic_typing_key, 12);
 | 
						|
 | 
						|
    // Nobody is muted.
 | 
						|
    assert.deepEqual(typing_data.get_group_typists([5, 10, 15]), [5, 10]);
 | 
						|
    assert.deepEqual(typing_data.get_all_direct_message_typists(), [5, 10]);
 | 
						|
    assert.deepEqual(typing_data.get_topic_typists(stream_id, topic), [7, 12]);
 | 
						|
 | 
						|
    // Mute a user, and test that the get_* functions exclude that user.
 | 
						|
    muted_users.add_muted_user(10);
 | 
						|
    muted_users.add_muted_user(7);
 | 
						|
    assert.deepEqual(typing_data.get_group_typists([5, 10, 15]), [5]);
 | 
						|
    assert.deepEqual(typing_data.get_all_direct_message_typists(), [5]);
 | 
						|
    assert.deepEqual(typing_data.get_topic_typists(stream_id, topic), [12]);
 | 
						|
});
 | 
						|
 | 
						|
test("timers", () => {
 | 
						|
    const events = {};
 | 
						|
 | 
						|
    const stub_timer_id = "timer_id_stub";
 | 
						|
    const stub_group = [5, 10, 15];
 | 
						|
    const stub_delay = 99;
 | 
						|
    const stub_f = "function";
 | 
						|
    const stub_stream_id = 1;
 | 
						|
    const stub_topic = "typing notifications";
 | 
						|
    const topic_typing_key = typing_data.get_topic_key(stub_stream_id, stub_topic);
 | 
						|
 | 
						|
    function set_timeout(f, delay) {
 | 
						|
        assert.equal(delay, stub_delay);
 | 
						|
        events.f = f;
 | 
						|
        events.timer_set = true;
 | 
						|
        return stub_timer_id;
 | 
						|
    }
 | 
						|
 | 
						|
    function clear_timeout(timer) {
 | 
						|
        assert.equal(timer, stub_timer_id);
 | 
						|
        events.timer_cleared = true;
 | 
						|
    }
 | 
						|
 | 
						|
    function reset_events() {
 | 
						|
        events.f = undefined;
 | 
						|
        events.timer_cleared = false;
 | 
						|
        events.timer_set = false;
 | 
						|
    }
 | 
						|
 | 
						|
    function kickstart() {
 | 
						|
        reset_events();
 | 
						|
        typing_data.kickstart_inbound_timer(
 | 
						|
            typing_data.get_direct_message_conversation_key(stub_group),
 | 
						|
            stub_delay,
 | 
						|
            stub_f,
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    function clear() {
 | 
						|
        reset_events();
 | 
						|
        typing_data.clear_inbound_timer(
 | 
						|
            typing_data.get_direct_message_conversation_key(stub_group),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    function streams_kickstart() {
 | 
						|
        reset_events();
 | 
						|
        typing_data.kickstart_inbound_timer(topic_typing_key, stub_delay, stub_f);
 | 
						|
    }
 | 
						|
 | 
						|
    function streams_clear() {
 | 
						|
        reset_events();
 | 
						|
        typing_data.clear_inbound_timer(topic_typing_key);
 | 
						|
    }
 | 
						|
 | 
						|
    set_global("setTimeout", set_timeout);
 | 
						|
    set_global("clearTimeout", clear_timeout);
 | 
						|
 | 
						|
    // first time, we set
 | 
						|
    kickstart();
 | 
						|
    assert.deepEqual(events, {
 | 
						|
        f: stub_f,
 | 
						|
        timer_cleared: false,
 | 
						|
        timer_set: true,
 | 
						|
    });
 | 
						|
 | 
						|
    // second time we clear and set
 | 
						|
    kickstart();
 | 
						|
    assert.deepEqual(events, {
 | 
						|
        f: stub_f,
 | 
						|
        timer_cleared: true,
 | 
						|
        timer_set: true,
 | 
						|
    });
 | 
						|
 | 
						|
    // clearing out typing data
 | 
						|
    kickstart();
 | 
						|
    typing_data.clear_typing_data();
 | 
						|
    assert.deepEqual(events, {
 | 
						|
        f: stub_f,
 | 
						|
        timer_cleared: true,
 | 
						|
        timer_set: true,
 | 
						|
    });
 | 
						|
 | 
						|
    kickstart();
 | 
						|
    // first time clearing, we clear
 | 
						|
    clear();
 | 
						|
    assert.deepEqual(events, {
 | 
						|
        f: undefined,
 | 
						|
        timer_cleared: true,
 | 
						|
        timer_set: false,
 | 
						|
    });
 | 
						|
 | 
						|
    // second time clearing, we noop
 | 
						|
    clear();
 | 
						|
    assert.deepEqual(events, {
 | 
						|
        f: undefined,
 | 
						|
        timer_cleared: false,
 | 
						|
        timer_set: false,
 | 
						|
    });
 | 
						|
 | 
						|
    // first time, we set
 | 
						|
    streams_kickstart();
 | 
						|
    assert.deepEqual(events, {
 | 
						|
        f: stub_f,
 | 
						|
        timer_cleared: false,
 | 
						|
        timer_set: true,
 | 
						|
    });
 | 
						|
 | 
						|
    // second time we clear and set
 | 
						|
    streams_kickstart();
 | 
						|
    assert.deepEqual(events, {
 | 
						|
        f: stub_f,
 | 
						|
        timer_cleared: true,
 | 
						|
        timer_set: true,
 | 
						|
    });
 | 
						|
 | 
						|
    // first time clearing, we clear
 | 
						|
    streams_clear();
 | 
						|
    assert.deepEqual(events, {
 | 
						|
        f: undefined,
 | 
						|
        timer_cleared: true,
 | 
						|
        timer_set: false,
 | 
						|
    });
 | 
						|
 | 
						|
    // second time clearing, we noop
 | 
						|
    streams_clear();
 | 
						|
    assert.deepEqual(events, {
 | 
						|
        f: undefined,
 | 
						|
        timer_cleared: false,
 | 
						|
        timer_set: false,
 | 
						|
    });
 | 
						|
});
 |