Skip to content

Commit

Permalink
Fix scrolling state at windows edge
Browse files Browse the repository at this point in the history
The problem: if user scrolled to the edge of the window, the state that
edge is reached, transfers to other windows, rendering user unable to
scroll further up/down in other windows as well.

Make unique states for each window that show that edge of the DB is reached.

Later it might be improved with MAM states as well to decrease load on program
in cases when user keeps scrolling despite reaching the edge.
  • Loading branch information
H3rnand3zzz committed Dec 5, 2023
1 parent bd0aa3e commit 68c9667
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 10 deletions.
7 changes: 7 additions & 0 deletions src/ui/win_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,9 +146,16 @@ typedef enum {
WIN_VCARD
} win_type_t;

typedef enum {
WIN_SCROLL_FREE,
WIN_SCROLL_REACHED_TOP,
WIN_SCROLL_REACHED_BOTTOM
} win_scroll_state_t;

typedef struct prof_win_t
{
win_type_t type;
win_scroll_state_t scroll_state;
ProfLayout* layout;
Autocomplete urls_ac;
Autocomplete quotes_ac;
Expand Down
27 changes: 17 additions & 10 deletions src/ui/window.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,6 @@ static void _win_print_internal(ProfWin* window, const char* show_char, int pad_
int flags, theme_item_t theme_item, const char* const from, const char* const message, DeliveryReceipt* receipt);
static void _win_print_wrapped(WINDOW* win, const char* const message, size_t indent, int pad_indent);

static gboolean _reached_top_of_database = FALSE;
static gboolean _reached_bottom_of_database = FALSE;

int
win_roster_cols(void)
{
Expand Down Expand Up @@ -136,6 +133,7 @@ win_create_console(void)
{
ProfConsoleWin* new_win = malloc(sizeof(ProfConsoleWin));
new_win->window.type = WIN_CONSOLE;
new_win->window.scroll_state = WIN_SCROLL_FREE;
new_win->window.layout = _win_create_split_layout();

return &new_win->window;
Expand All @@ -146,6 +144,7 @@ win_create_chat(const char* const barejid)
{
ProfChatWin* new_win = malloc(sizeof(ProfChatWin));
new_win->window.type = WIN_CHAT;
new_win->window.scroll_state = WIN_SCROLL_FREE;
new_win->window.layout = _win_create_simple_layout();

new_win->barejid = strdup(barejid);
Expand Down Expand Up @@ -177,6 +176,7 @@ win_create_muc(const char* const roomjid)
int cols = getmaxx(stdscr);

new_win->window.type = WIN_MUC;
new_win->window.scroll_state = WIN_SCROLL_FREE;
ProfLayoutSplit* layout = malloc(sizeof(ProfLayoutSplit));
layout->base.type = LAYOUT_SPLIT;

Expand Down Expand Up @@ -231,6 +231,7 @@ win_create_config(const char* const roomjid, DataForm* form, ProfConfWinCallback
{
ProfConfWin* new_win = malloc(sizeof(ProfConfWin));
new_win->window.type = WIN_CONFIG;
new_win->window.scroll_state = WIN_SCROLL_FREE;
new_win->window.layout = _win_create_simple_layout();
new_win->roomjid = strdup(roomjid);
new_win->form = form;
Expand All @@ -248,6 +249,7 @@ win_create_private(const char* const fulljid)
{
ProfPrivateWin* new_win = malloc(sizeof(ProfPrivateWin));
new_win->window.type = WIN_PRIVATE;
new_win->window.scroll_state = WIN_SCROLL_FREE;
new_win->window.layout = _win_create_simple_layout();
new_win->fulljid = strdup(fulljid);
new_win->unread = 0;
Expand All @@ -264,6 +266,7 @@ win_create_xmlconsole(void)
{
ProfXMLWin* new_win = malloc(sizeof(ProfXMLWin));
new_win->window.type = WIN_XML;
new_win->window.scroll_state = WIN_SCROLL_FREE;
new_win->window.layout = _win_create_simple_layout();

new_win->memcheck = PROFXMLWIN_MEMCHECK;
Expand All @@ -276,6 +279,7 @@ win_create_plugin(const char* const plugin_name, const char* const tag)
{
ProfPluginWin* new_win = malloc(sizeof(ProfPluginWin));
new_win->window.type = WIN_PLUGIN;
new_win->window.scroll_state = WIN_SCROLL_FREE;
new_win->window.layout = _win_create_simple_layout();

new_win->tag = strdup(tag);
Expand All @@ -291,6 +295,7 @@ win_create_vcard(vCard* vcard)
{
ProfVcardWin* new_win = malloc(sizeof(ProfVcardWin));
new_win->window.type = WIN_VCARD;
new_win->window.scroll_state = WIN_SCROLL_FREE;
new_win->window.layout = _win_create_simple_layout();

new_win->vcard = vcard;
Expand Down Expand Up @@ -625,14 +630,15 @@ win_free(ProfWin* window)
void
win_page_up(ProfWin* window, int scroll_size)
{
_reached_bottom_of_database = FALSE;
int rows = getmaxy(stdscr);
int total_rows = getcury(window->layout->win);
int page_space = rows - 4;
int* page_start = &(window->layout->y_pos);
int page_start_initial = *page_start;
if (scroll_size == 0)
scroll_size = page_space;
win_scroll_state_t* scroll_state = &window->scroll_state;
*scroll_state = (*scroll_state == WIN_SCROLL_REACHED_BOTTOM) ? WIN_SCROLL_FREE : *scroll_state;

*page_start -= scroll_size;

Expand All @@ -642,11 +648,11 @@ win_page_up(ProfWin* window, int scroll_size)

// Don't do anything if still fetching mam messages
if (first_entry && !(first_entry->theme_item == THEME_ROOMINFO && g_strcmp0(first_entry->message, LOADING_MESSAGE) == 0)) {
if (!_reached_top_of_database) {
_reached_top_of_database = !chatwin_db_history(chatwin, NULL, NULL, TRUE);
if (*scroll_state != WIN_SCROLL_REACHED_TOP) {
*scroll_state = !chatwin_db_history(chatwin, NULL, NULL, TRUE) ? WIN_SCROLL_REACHED_TOP : WIN_SCROLL_FREE;
}

if (_reached_top_of_database && prefs_get_boolean(PREF_MAM)) {
if (*scroll_state == WIN_SCROLL_REACHED_TOP && prefs_get_boolean(PREF_MAM)) {
win_print_loading_history(window);
iq_mam_request_older(chatwin);
}
Expand All @@ -672,14 +678,15 @@ win_page_up(ProfWin* window, int scroll_size)
void
win_page_down(ProfWin* window, int scroll_size)
{
_reached_top_of_database = FALSE;
int rows = getmaxy(stdscr);
int* page_start = &(window->layout->y_pos);
int total_rows = getcury(window->layout->win);
int page_space = rows - 4;
int page_start_initial = *page_start;
if (scroll_size == 0)
scroll_size = page_space;
win_scroll_state_t* scroll_state = &window->scroll_state;
*scroll_state = (*scroll_state == WIN_SCROLL_REACHED_TOP) ? WIN_SCROLL_FREE : *scroll_state;

*page_start += scroll_size;

Expand All @@ -691,8 +698,8 @@ win_page_down(ProfWin* window, int scroll_size)
GDateTime* now = g_date_time_new_now_local();
gchar* end = g_date_time_format_iso8601(now);
// end is free'd inside
if (!_reached_bottom_of_database && !chatwin_db_history((ProfChatWin*)window, start, end, FALSE)) {
_reached_bottom_of_database = TRUE;
if (*scroll_state != WIN_SCROLL_REACHED_BOTTOM && !chatwin_db_history((ProfChatWin*)window, start, end, FALSE)) {
*scroll_state = WIN_SCROLL_REACHED_BOTTOM;
}

g_date_time_unref(now);
Expand Down

0 comments on commit 68c9667

Please sign in to comment.