mirror of https://github.com/zulip/zulip.git
recent senders: Convert module to typescript.
This commit is contained in:
parent
1f2ea95b9f
commit
68f2535ebc
|
@ -2,60 +2,67 @@ import _ from "lodash";
|
|||
|
||||
import {FoldDict} from "./fold_dict";
|
||||
import * as message_store from "./message_store";
|
||||
import type {Message} from "./message_store";
|
||||
import * as people from "./people";
|
||||
import type {User} from "./people";
|
||||
|
||||
// This class is only exported for unit testing purposes.
|
||||
// If we find reuse opportunities, we should just put it into
|
||||
// its own module.
|
||||
export class IdTracker {
|
||||
ids = new Set();
|
||||
ids = new Set<number>();
|
||||
|
||||
// We cache the max message id to make sure that
|
||||
// typeahead code is efficient. We don't eagerly
|
||||
// compute it, since it's plausible a spammy bot
|
||||
// could cause us to process many messages at a time
|
||||
// during fetching.
|
||||
_cached_max_id = undefined;
|
||||
_cached_max_id: number | undefined = undefined;
|
||||
|
||||
add(id) {
|
||||
add(id: number): void {
|
||||
this.ids.add(id);
|
||||
if (this._cached_max_id !== undefined && id > this._cached_max_id) {
|
||||
this._cached_max_id = id;
|
||||
}
|
||||
}
|
||||
|
||||
remove(id) {
|
||||
remove(id: number): void {
|
||||
this.ids.delete(id);
|
||||
this._cached_max_id = undefined;
|
||||
}
|
||||
|
||||
max_id() {
|
||||
max_id(): number {
|
||||
if (this._cached_max_id === undefined) {
|
||||
this._cached_max_id = _.max([...this.ids]);
|
||||
}
|
||||
return this._cached_max_id || -1;
|
||||
return this._cached_max_id ?? -1;
|
||||
}
|
||||
|
||||
empty() {
|
||||
empty(): boolean {
|
||||
return this.ids.size === 0;
|
||||
}
|
||||
}
|
||||
|
||||
// topic_senders[stream_id][sender_id] = IdTracker
|
||||
const stream_senders = new Map();
|
||||
const stream_senders = new Map<number, Map<number, IdTracker>>();
|
||||
|
||||
// topic_senders[stream_id][topic_id][sender_id] = IdTracker
|
||||
const topic_senders = new Map();
|
||||
const topic_senders = new Map<number, FoldDict<Map<number, IdTracker>>>();
|
||||
|
||||
// pm_senders[user_ids_string][user_id] = IdTracker
|
||||
const pm_senders = new Map();
|
||||
const pm_senders = new Map<string, Map<number, IdTracker>>();
|
||||
|
||||
export function clear_for_testing() {
|
||||
export function clear_for_testing(): void {
|
||||
stream_senders.clear();
|
||||
topic_senders.clear();
|
||||
}
|
||||
|
||||
function max_id_for_stream_topic_sender({stream_id, topic, sender_id}) {
|
||||
function max_id_for_stream_topic_sender(opts: {
|
||||
stream_id: number;
|
||||
topic: string;
|
||||
sender_id: number;
|
||||
}): number {
|
||||
const {stream_id, topic, sender_id} = opts;
|
||||
const topic_dict = topic_senders.get(stream_id);
|
||||
if (!topic_dict) {
|
||||
return -1;
|
||||
|
@ -68,7 +75,8 @@ function max_id_for_stream_topic_sender({stream_id, topic, sender_id}) {
|
|||
return id_tracker ? id_tracker.max_id() : -1;
|
||||
}
|
||||
|
||||
function max_id_for_stream_sender({stream_id, sender_id}) {
|
||||
function max_id_for_stream_sender(opts: {stream_id: number; sender_id: number}): number {
|
||||
const {stream_id, sender_id} = opts;
|
||||
const sender_dict = stream_senders.get(stream_id);
|
||||
if (!sender_dict) {
|
||||
return -1;
|
||||
|
@ -77,25 +85,36 @@ function max_id_for_stream_sender({stream_id, sender_id}) {
|
|||
return id_tracker ? id_tracker.max_id() : -1;
|
||||
}
|
||||
|
||||
function add_stream_message({stream_id, sender_id, message_id}) {
|
||||
const sender_dict = stream_senders.get(stream_id) || new Map();
|
||||
const id_tracker = sender_dict.get(sender_id) || new IdTracker();
|
||||
function add_stream_message(opts: {
|
||||
stream_id: number;
|
||||
sender_id: number;
|
||||
message_id: number;
|
||||
}): void {
|
||||
const {stream_id, sender_id, message_id} = opts;
|
||||
const sender_dict = stream_senders.get(stream_id) ?? new Map();
|
||||
const id_tracker = sender_dict.get(sender_id) ?? new IdTracker();
|
||||
stream_senders.set(stream_id, sender_dict);
|
||||
sender_dict.set(sender_id, id_tracker);
|
||||
id_tracker.add(message_id);
|
||||
}
|
||||
|
||||
function add_topic_message({stream_id, topic, sender_id, message_id}) {
|
||||
const topic_dict = topic_senders.get(stream_id) || new FoldDict();
|
||||
const sender_dict = topic_dict.get(topic) || new Map();
|
||||
const id_tracker = sender_dict.get(sender_id) || new IdTracker();
|
||||
function add_topic_message(opts: {
|
||||
stream_id: number;
|
||||
topic: string;
|
||||
sender_id: number;
|
||||
message_id: number;
|
||||
}): void {
|
||||
const {stream_id, topic, sender_id, message_id} = opts;
|
||||
const topic_dict = topic_senders.get(stream_id) ?? new FoldDict();
|
||||
const sender_dict = topic_dict.get(topic) ?? new Map();
|
||||
const id_tracker = sender_dict.get(sender_id) ?? new IdTracker();
|
||||
topic_senders.set(stream_id, topic_dict);
|
||||
topic_dict.set(topic, sender_dict);
|
||||
sender_dict.set(sender_id, id_tracker);
|
||||
id_tracker.add(message_id);
|
||||
}
|
||||
|
||||
export function process_stream_message(message) {
|
||||
export function process_stream_message(message: Message & {type: "stream"}): void {
|
||||
const stream_id = message.stream_id;
|
||||
const topic = message.topic;
|
||||
const sender_id = message.sender_id;
|
||||
|
@ -105,7 +124,13 @@ export function process_stream_message(message) {
|
|||
add_topic_message({stream_id, topic, sender_id, message_id});
|
||||
}
|
||||
|
||||
function remove_topic_message({stream_id, topic, sender_id, message_id}) {
|
||||
function remove_topic_message(opts: {
|
||||
stream_id: number;
|
||||
topic: string;
|
||||
sender_id: number;
|
||||
message_id: number;
|
||||
}): void {
|
||||
const {stream_id, topic, sender_id, message_id} = opts;
|
||||
const topic_dict = topic_senders.get(stream_id);
|
||||
if (!topic_dict) {
|
||||
return;
|
||||
|
@ -133,13 +158,14 @@ function remove_topic_message({stream_id, topic, sender_id, message_id}) {
|
|||
}
|
||||
}
|
||||
|
||||
export function process_topic_edit({
|
||||
message_ids,
|
||||
old_stream_id,
|
||||
old_topic,
|
||||
new_stream_id,
|
||||
new_topic,
|
||||
}) {
|
||||
export function process_topic_edit(opts: {
|
||||
message_ids: number[];
|
||||
old_stream_id: number;
|
||||
old_topic: string;
|
||||
new_stream_id: number;
|
||||
new_topic: string;
|
||||
}): void {
|
||||
const {message_ids, old_stream_id, old_topic, new_stream_id, new_topic} = opts;
|
||||
// Note that we don't delete anything from stream_senders here.
|
||||
// Our view is that it's probably better to not do so; users who
|
||||
// recently posted to a stream are relevant for typeahead even if
|
||||
|
@ -159,10 +185,10 @@ export function process_topic_edit({
|
|||
}
|
||||
}
|
||||
|
||||
export function update_topics_of_deleted_message_ids(message_ids) {
|
||||
export function update_topics_of_deleted_message_ids(message_ids: number[]): void {
|
||||
for (const message_id of message_ids) {
|
||||
const message = message_store.get(message_id);
|
||||
if (!message) {
|
||||
if (!message || message.type !== "stream") {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -174,7 +200,12 @@ export function update_topics_of_deleted_message_ids(message_ids) {
|
|||
}
|
||||
}
|
||||
|
||||
export function compare_by_recency(user_a, user_b, stream_id, topic) {
|
||||
export function compare_by_recency(
|
||||
user_a: User,
|
||||
user_b: User,
|
||||
stream_id: number,
|
||||
topic: string,
|
||||
): number {
|
||||
let a_message_id;
|
||||
let b_message_id;
|
||||
|
||||
|
@ -191,7 +222,7 @@ export function compare_by_recency(user_a, user_b, stream_id, topic) {
|
|||
return b_message_id - a_message_id;
|
||||
}
|
||||
|
||||
export function get_topic_recent_senders(stream_id, topic) {
|
||||
export function get_topic_recent_senders(stream_id: number, topic: string): number[] {
|
||||
const topic_dict = topic_senders.get(stream_id);
|
||||
if (topic_dict === undefined) {
|
||||
return [];
|
||||
|
@ -202,7 +233,7 @@ export function get_topic_recent_senders(stream_id, topic) {
|
|||
return [];
|
||||
}
|
||||
|
||||
function by_max_message_id(item1, item2) {
|
||||
function by_max_message_id(item1: [number, IdTracker], item2: [number, IdTracker]): number {
|
||||
const list1 = item1[1];
|
||||
const list2 = item2[1];
|
||||
return list2.max_id() - list1.max_id();
|
||||
|
@ -216,28 +247,28 @@ export function get_topic_recent_senders(stream_id, topic) {
|
|||
return recent_senders;
|
||||
}
|
||||
|
||||
export function process_private_message({to_user_ids, sender_id, id}) {
|
||||
const sender_dict = pm_senders.get(to_user_ids) || new Map();
|
||||
const id_tracker = sender_dict.get(sender_id) || new IdTracker();
|
||||
export function process_private_message(opts: {
|
||||
to_user_ids: string;
|
||||
sender_id: number;
|
||||
id: number;
|
||||
}): void {
|
||||
const {to_user_ids, sender_id, id} = opts;
|
||||
const sender_dict = pm_senders.get(to_user_ids) ?? new Map();
|
||||
const id_tracker = sender_dict.get(sender_id) ?? new IdTracker();
|
||||
pm_senders.set(to_user_ids, sender_dict);
|
||||
sender_dict.set(sender_id, id_tracker);
|
||||
id_tracker.add(id);
|
||||
}
|
||||
|
||||
export function get_pm_recent_senders(user_ids_string) {
|
||||
type DirectMessageSendersInfo = {participants: number[]; non_participants: number[]};
|
||||
export function get_pm_recent_senders(user_ids_string: string): DirectMessageSendersInfo {
|
||||
const user_ids = [...people.get_participants_from_user_ids_string(user_ids_string)];
|
||||
const sender_dict = pm_senders.get(user_ids_string);
|
||||
const pm_senders_info = {participants: [], non_participants: []};
|
||||
if (!sender_dict) {
|
||||
const pm_senders_info: DirectMessageSendersInfo = {participants: [], non_participants: []};
|
||||
if (sender_dict === undefined) {
|
||||
return pm_senders_info;
|
||||
}
|
||||
|
||||
function compare_pm_user_ids_by_recency(user_id1, user_id2) {
|
||||
const max_id1 = sender_dict.get(user_id1)?.max_id() || -1;
|
||||
const max_id2 = sender_dict.get(user_id2)?.max_id() || -1;
|
||||
return max_id2 - max_id1;
|
||||
}
|
||||
|
||||
for (const user_id of user_ids) {
|
||||
if (sender_dict.get(user_id)) {
|
||||
pm_senders_info.participants.push(user_id);
|
||||
|
@ -245,11 +276,19 @@ export function get_pm_recent_senders(user_ids_string) {
|
|||
pm_senders_info.non_participants.push(user_id);
|
||||
}
|
||||
}
|
||||
pm_senders_info.participants.sort(compare_pm_user_ids_by_recency);
|
||||
pm_senders_info.participants.sort((user_id1: number, user_id2: number) => {
|
||||
const max_id1 = sender_dict.get(user_id1)?.max_id() ?? -1;
|
||||
const max_id2 = sender_dict.get(user_id2)?.max_id() ?? -1;
|
||||
return max_id2 - max_id1;
|
||||
});
|
||||
return pm_senders_info;
|
||||
}
|
||||
|
||||
export function get_topic_message_ids_for_sender(stream_id, topic, sender_id) {
|
||||
export function get_topic_message_ids_for_sender(
|
||||
stream_id: number,
|
||||
topic: string,
|
||||
sender_id: number,
|
||||
): Set<number> {
|
||||
const id_tracker = topic_senders?.get(stream_id)?.get(topic)?.get(sender_id);
|
||||
if (id_tracker === undefined) {
|
||||
return new Set();
|
Loading…
Reference in New Issue