1
0
mirror of https://github.com/Tha14/toxic.git synced 2024-11-22 09:03:01 +01:00

Refactor unread message flagging

This fixes an issue where the interface wasn't able to update
when the unread message flag changed. It also cleans up some
ugly code
This commit is contained in:
jfreegman 2021-11-19 22:54:35 -05:00
parent f3f81111c8
commit 1803da85c1
No known key found for this signature in database
GPG Key ID: 3627F3144076AE63
6 changed files with 85 additions and 31 deletions

View File

@ -440,6 +440,10 @@ int line_info_add(ToxWindow *self, bool show_timestamp, const char *name1, const
new_line->noread_flag = false; new_line->noread_flag = false;
new_line->timestamp = get_unix_time(); new_line->timestamp = get_unix_time();
if (type == OUT_MSG || type == OUT_ACTION) {
new_line->noread_flag = self->stb->connection == TOX_CONNECTION_NONE;
}
line_info_init_line(self, new_line); line_info_init_line(self, new_line);
hst->queue[hst->queue_size++] = new_line; hst->queue[hst->queue_size++] = new_line;
@ -475,8 +479,6 @@ static void line_info_check_queue(ToxWindow *self)
flag_interface_refresh(); flag_interface_refresh();
} }
#define NOREAD_FLAG_TIMEOUT 5 /* seconds before a sent message with no read receipt is flagged as unread */
void line_info_print(ToxWindow *self) void line_info_print(ToxWindow *self)
{ {
ChatContext *ctx = self->chatwin; ChatContext *ctx = self->chatwin;
@ -577,12 +579,6 @@ void line_info_print(ToxWindow *self)
wattroff(win, COLOR_PAIR(RED)); wattroff(win, COLOR_PAIR(RED));
} }
if (type == OUT_MSG && !line->read_flag) {
if (timed_out(line->timestamp, NOREAD_FLAG_TIMEOUT)) {
line->noread_flag = true;
}
}
waddch(win, '\n'); waddch(win, '\n');
break; break;
@ -602,12 +598,6 @@ void line_info_print(ToxWindow *self)
print_ret = print_wrap(win, line, max_x, max_y); print_ret = print_wrap(win, line, max_x, max_y);
wattroff(win, COLOR_PAIR(YELLOW)); wattroff(win, COLOR_PAIR(YELLOW));
if (type == OUT_ACTION && !line->read_flag) {
if (timed_out(line->timestamp, NOREAD_FLAG_TIMEOUT)) {
line->noread_flag = true;
}
}
waddch(win, '\n'); waddch(win, '\n');
break; break;
@ -771,6 +761,24 @@ void line_info_set(ToxWindow *self, uint32_t id, char *msg)
} }
} }
/* Return the line_info object associated with `id`.
* Return NULL if id cannot be found
*/
struct line_info *line_info_get(ToxWindow *self, uint32_t id)
{
struct line_info *line = self->chatwin->hst->line_end;
while (line) {
if (line->id == id) {
return line;
}
line = line->prev;
}
return NULL;
}
static void line_info_scroll_up(ToxWindow *self, struct history *hst) static void line_info_scroll_up(ToxWindow *self, struct history *hst)
{ {
if (hst->line_start->prev) { if (hst->line_start->prev) {

View File

@ -96,6 +96,11 @@ void line_info_clear(struct history *hst);
/* puts msg in specified line_info msg buffer */ /* puts msg in specified line_info msg buffer */
void line_info_set(ToxWindow *self, uint32_t id, char *msg); void line_info_set(ToxWindow *self, uint32_t id, char *msg);
/* Return the line_info object associated with `id`.
* Return NULL if id cannot be found
*/
struct line_info *line_info_get(ToxWindow *self, uint32_t id);
/* resets line_start (moves to end of chat history) */ /* resets line_start (moves to end of chat history) */
void line_info_reset_start(ToxWindow *self, struct history *hst); void line_info_reset_start(ToxWindow *self, struct history *hst);

View File

@ -59,6 +59,7 @@ void cqueue_add(struct chat_queue *q, const char *msg, size_t len, uint8_t type,
new_m->type = type; new_m->type = type;
new_m->line_id = line_id; new_m->line_id = line_id;
new_m->last_send_try = 0; new_m->last_send_try = 0;
new_m->time_added = get_unix_time();
new_m->receipt = -1; new_m->receipt = -1;
new_m->next = NULL; new_m->next = NULL;
@ -76,23 +77,19 @@ void cqueue_add(struct chat_queue *q, const char *msg, size_t len, uint8_t type,
/* update line to show receipt was received after queue removal */ /* update line to show receipt was received after queue removal */
static void cqueue_mark_read(ToxWindow *self, struct cqueue_msg *msg) static void cqueue_mark_read(ToxWindow *self, struct cqueue_msg *msg)
{ {
struct line_info *line = self->chatwin->hst->line_end; struct line_info *line = line_info_get(self, msg->line_id);
while (line) {
if (line->id != msg->line_id) {
line = line->prev;
continue;
}
line->type = msg->type == OUT_ACTION ? OUT_ACTION_READ : OUT_MSG_READ;
if (line->noread_flag) {
line->noread_flag = false;
line->read_flag = true;
}
if (line == NULL) {
return; return;
} }
line->type = msg->type == OUT_ACTION ? OUT_ACTION_READ : OUT_MSG_READ;
if (line->noread_flag) {
line->noread_flag = false;
line->read_flag = true;
flag_interface_refresh();
}
} }
/* removes message with matching receipt from queue, writes to log and updates line to show the message was received. */ /* removes message with matching receipt from queue, writes to log and updates line to show the message was received. */
@ -158,6 +155,36 @@ static void cqueue_check_timeouts(struct cqueue_msg *msg)
} }
} }
/*
* Sets the noread flag for messages sent to the peer associated with `self` which have not
* received a receipt after a period of time.
*/
#define NOREAD_TIMEOUT 5
void cqueue_check_unread(ToxWindow *self)
{
struct chat_queue *q = self->chatwin->cqueue;
struct cqueue_msg *msg = q->root;
while (msg) {
if (msg->noread_flag) {
msg = msg->next;
continue;
}
struct line_info *line = line_info_get(self, msg->line_id);
if (line != NULL) {
if (timed_out(msg->time_added, NOREAD_TIMEOUT)) {
line->noread_flag = true;
msg->noread_flag = true;
flag_interface_refresh();
}
}
msg = msg->next;
}
}
/* /*
* Tries to send all messages in the send queue in sequential order. * Tries to send all messages in the send queue in sequential order.
* If a message fails to send the function will immediately return. * If a message fails to send the function will immediately return.

View File

@ -28,8 +28,10 @@ struct cqueue_msg {
size_t len; size_t len;
int line_id; int line_id;
time_t last_send_try; time_t last_send_try;
time_t time_added;
uint8_t type; uint8_t type;
int64_t receipt; int64_t receipt;
bool noread_flag;
struct cqueue_msg *next; struct cqueue_msg *next;
struct cqueue_msg *prev; struct cqueue_msg *prev;
}; };
@ -48,6 +50,12 @@ void cqueue_add(struct chat_queue *q, const char *msg, size_t len, uint8_t type,
*/ */
void cqueue_try_send(ToxWindow *self, Tox *m); void cqueue_try_send(ToxWindow *self, Tox *m);
/*
* Sets the noread flag for messages sent to the peer associated with `self` which have not
* received a receipt after a period of time.
*/
void cqueue_check_unread(ToxWindow *self);
/* removes message with matching receipt from queue, writes to log and updates line to show the message was received. */ /* removes message with matching receipt from queue, writes to log and updates line to show the message was received. */
void cqueue_remove(ToxWindow *self, Tox *m, uint32_t receipt); void cqueue_remove(ToxWindow *self, Tox *m, uint32_t receipt);

View File

@ -1144,9 +1144,12 @@ void *thread_cqueue(void *data)
for (size_t i = 2; i < MAX_WINDOWS_NUM; ++i) { for (size_t i = 2; i < MAX_WINDOWS_NUM; ++i) {
ToxWindow *toxwin = get_window_ptr(i); ToxWindow *toxwin = get_window_ptr(i);
if ((toxwin != NULL) && (toxwin->type == WINDOW_TYPE_CHAT) if ((toxwin != NULL) && (toxwin->type == WINDOW_TYPE_CHAT)) {
&& (get_friend_connection_status(toxwin->num) != TOX_CONNECTION_NONE)) { cqueue_check_unread(toxwin);
cqueue_try_send(toxwin, m);
if (get_friend_connection_status(toxwin->num) != TOX_CONNECTION_NONE) {
cqueue_try_send(toxwin, m);
}
} }
} }

View File

@ -808,15 +808,18 @@ void draw_active_window(Tox *m)
a->onDraw(a, m); a->onDraw(a, m);
wrefresh(a->window); wrefresh(a->window);
} }
#ifdef AUDIO #ifdef AUDIO
else if (a->is_call && timed_out(a->chatwin->infobox.lastupdate, 1)) { else if (a->is_call && timed_out(a->chatwin->infobox.lastupdate, 1)) {
touchwin(a->window); touchwin(a->window);
a->onDraw(a, m); a->onDraw(a, m);
wrefresh(a->window); wrefresh(a->window);
} }
#endif #endif
#ifdef GAMES #ifdef GAMES
if (a->type == WINDOW_TYPE_GAME) { if (a->type == WINDOW_TYPE_GAME) {
if (!flag_refresh) { // we always want to be continously refreshing game windows if (!flag_refresh) { // we always want to be continously refreshing game windows
touchwin(a->window); touchwin(a->window);