zulip/static/js/list_cursor.js

142 lines
3.8 KiB
JavaScript

const list_cursor = function (opts) {
const self = {};
const config_ok =
opts.highlight_class &&
opts.list &&
opts.list.scroll_container_sel &&
opts.list.find_li &&
opts.list.first_key &&
opts.list.prev_key &&
opts.list.next_key;
if (!config_ok) {
blueslip.error("Programming error");
return;
}
self.clear = function () {
if (self.curr_key === undefined) {
return;
}
const row = self.get_row(self.curr_key);
if (row) {
row.clear();
}
self.curr_key = undefined;
};
self.get_key = function () {
return self.curr_key;
};
self.get_row = function (key) {
// TODO: The list class should probably do more of the work
// here, so we're not so coupled to jQuery, and
// so we instead just get back a widget we can say
// something like widget.trigger("select") on. This will
// be especially important if we do lazy rendering.
// It would also give the caller more flexibility on
// the actual styling.
if (key === undefined) {
return;
}
const li = opts.list.find_li({
key,
force_render: true,
});
if (!li || li.length === 0) {
return;
}
return {
highlight() {
li.addClass(opts.highlight_class);
self.adjust_scroll(li);
},
clear() {
li.removeClass(opts.highlight_class);
},
};
};
self.adjust_scroll = function (li) {
const scroll_container = $(opts.list.scroll_container_sel);
scroll_util.scroll_element_into_container(li, scroll_container);
};
self.redraw = function () {
// We should only call this for situations like the buddy
// list where we redraw the whole list without necessarily
// changing it, so we just want to re-highlight the current
// row in the new DOM. If you are filtering, for now you
// should call the 'reset()' method.
const row = self.get_row(self.curr_key);
if (row === undefined) {
return;
}
row.highlight();
};
self.go_to = function (key) {
if (key === undefined) {
blueslip.error("Caller is not checking keys for list_cursor.go_to");
return;
}
if (key === self.curr_key) {
return;
}
self.clear();
const row = self.get_row(key);
if (row === undefined) {
blueslip.error("Cannot highlight key for list_cursor: " + key);
return;
}
self.curr_key = key;
row.highlight();
};
self.reset = function () {
self.clear();
const key = opts.list.first_key();
if (key === undefined) {
self.curr_key = undefined;
return;
}
self.go_to(key);
};
self.prev = function () {
if (self.curr_key === undefined) {
return;
}
const key = opts.list.prev_key(self.curr_key);
if (key === undefined) {
// leave the current key
return;
}
self.go_to(key);
};
self.next = function () {
if (self.curr_key === undefined) {
// This is sort of a special case where we went from
// an empty filter to having data.
self.reset();
return;
}
const key = opts.list.next_key(self.curr_key);
if (key === undefined) {
// leave the current key
return;
}
self.go_to(key);
};
return self;
};
module.exports = list_cursor;
window.list_cursor = list_cursor;