commit 2a72f770ecf2f6243fada17c6c31d4dd085eb911
parent 04b106bf09b8ef90418811ed583d1c4ebd5fdaf5
Author: TheJackiMonster <thejackimonster@gmail.com>
Date: Fri, 9 Sep 2022 15:36:34 +0200
Added lines showing dates between chat messages
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
Diffstat:
7 files changed, 160 insertions(+), 95 deletions(-)
diff --git a/src/ui/accounts.h b/src/ui/accounts.h
@@ -40,6 +40,9 @@ typedef struct UI_ACCOUNTS_Handle
{
WINDOW *window;
+ int line_prev;
+ int line_next;
+
int line_index;
int line_offset;
int line_selected;
diff --git a/src/ui/chats.h b/src/ui/chats.h
@@ -42,6 +42,9 @@ typedef struct UI_CHATS_Handle
{
WINDOW *window;
+ int line_prev;
+ int line_next;
+
int line_index;
int line_offset;
int line_selected;
diff --git a/src/ui/list_input.h b/src/ui/list_input.h
@@ -29,80 +29,87 @@
#include <stdlib.h>
#define list_input_reset(list) { \
- (list)->line_index = 0; \
- (list)->selected = 0; \
+ (list)->line_prev = 0; \
+ (list)->line_next = 0; \
+ (list)->line_index = 0; \
+ (list)->selected = 0; \
}
-#define list_input_select(list, line_width, item) { \
- const bool selected = ( \
- ((list)->line_selected >= (list)->line_index) && \
- ((list)->line_selected < (list)->line_index + line_width) \
- ); \
- \
- (list)->line_index += line_width; \
- \
- if (selected) \
- (list)->selected = item; \
+#define list_input_select(list, line_width, item) { \
+ const bool selected = ( \
+ ((list)->line_selected >= (list)->line_index) && \
+ ((list)->line_selected < (list)->line_index + (line_width)) \
+ ); \
+ \
+ if ((!selected) && ((list)->line_selected > (list)->line_index)) \
+ (list)->line_prev = (list)->line_index; \
+ \
+ (list)->line_index += (line_width); \
+ \
+ if (selected) { \
+ (list)->line_next = (list)->line_index; \
+ (list)->selected = item; \
+ } \
}
#define list_input_event(list, key) { \
- int count = (list)->line_index; \
- \
- switch (key) \
- { \
- case KEY_UP: \
- { \
- (list)->line_selected--; \
- break; \
- } \
- case KEY_DOWN: \
- { \
- (list)->line_selected++; \
- break; \
- } \
- default: \
- break; \
- } \
- \
- if ((list)->line_selected < 0) \
- (list)->line_selected = 0; \
- else if ((list)->line_selected >= count) \
- (list)->line_selected = count - 1; \
- \
- if ((list)->window) \
- { \
- const int height = getmaxy((list)->window); \
+ int count = (list)->line_index; \
+ \
+ switch (key) \
+ { \
+ case KEY_UP: \
+ { \
+ (list)->line_selected = (list)->line_prev; \
+ break; \
+ } \
+ case KEY_DOWN: \
+ { \
+ (list)->line_selected = (list)->line_next; \
+ break; \
+ } \
+ default: \
+ break; \
+ } \
+ \
+ if ((list)->line_selected < 0) \
+ (list)->line_selected = 0; \
+ else if ((list)->line_selected >= count) \
+ (list)->line_selected = count - 1; \
+ \
+ if ((list)->window) \
+ { \
+ const int height = getmaxy((list)->window); \
const int y = (list)->line_selected - (list)->line_offset; \
- \
- if (y < 0) \
+ \
+ if (y < 0) \
(list)->line_offset += y; \
- else if (y + 1 >= height) \
+ else if (y + 1 >= height) \
(list)->line_offset += y + 1 - height; \
- \
+ \
if ((list)->line_offset < 0) \
(list)->line_offset = 0; \
else if ((list)->line_offset >= count) \
(list)->line_offset = count - 1; \
- } \
+ } \
}
-#define list_input_print_(list, line_width, yes_res, no_res) \
- const bool selected = ( \
- ((list)->line_selected >= (list)->line_index) && \
- ((list)->line_selected < (list)->line_index + line_width) \
- ); \
- \
- const int y = (list)->line_index - (list)->line_offset; { \
- \
- (list)->line_index += line_width; \
- \
- if (y + line_width < 1) \
- return yes_res; \
- \
- const int height = getmaxy((list)->window); \
- \
- if (y >= height) \
- return no_res; \
+#define list_input_print_(list, line_width, yes_res, no_res) \
+ const bool selected = ( \
+ ((list)->line_selected >= (list)->line_index) && \
+ ((list)->line_selected < (list)->line_index + (line_width)) \
+ ); \
+ \
+ const int y = (list)->line_index - (list)->line_offset; { \
+ \
+ (list)->line_index += (line_width); \
+ \
+ if (y + (line_width) < 1) \
+ return yes_res; \
+ \
+ const int height = getmaxy((list)->window); \
+ \
+ if (y >= height) \
+ return no_res; \
}
#define list_input_print_gnunet(list, line_width) \
diff --git a/src/ui/lobby_create_dialog.h b/src/ui/lobby_create_dialog.h
@@ -39,6 +39,9 @@ typedef struct UI_LOBBY_CREATE_DIALOG_Handle
WINDOW *window;
WINDOW **win;
+ int line_prev;
+ int line_next;
+
int line_index;
int line_offset;
int line_selected;
diff --git a/src/ui/members.h b/src/ui/members.h
@@ -50,6 +50,9 @@ typedef struct UI_MEMBERS_Handle
UI_MEMBERS_List *head;
UI_MEMBERS_List *tail;
+ int line_prev;
+ int line_next;
+
int line_index;
int line_offset;
int line_selected;
diff --git a/src/ui/messages.c b/src/ui/messages.c
@@ -29,6 +29,26 @@
#include "../application.h"
#include "../util.h"
+struct tm*
+_messages_new_day(time_t* current_time,
+ const time_t* timestamp)
+{
+ struct tm* ts = localtime(timestamp);
+
+ ts->tm_sec = 0;
+ ts->tm_min = 0;
+ ts->tm_hour = 0;
+
+ const time_t date_time = timelocal(ts);
+
+ if (date_time <= *current_time) {
+ return NULL;
+ }
+
+ *current_time = date_time;
+ return ts;
+}
+
void
_messages_handle_message(UI_MESSAGES_Handle *messages)
{
@@ -65,11 +85,17 @@ messages_event(UI_MESSAGES_Handle *messages,
int key)
{
list_input_reset(messages);
+ messages->line_time = 0;
UI_MESSAGES_List *element = messages->head;
while (element)
{
- list_input_select(messages, 1, element->message);
+ struct tm *ts = _messages_new_day(
+ &(messages->line_time),
+ &(element->timestamp)
+ );
+
+ list_input_select(messages, ts? 2 : 1, element->message);
element = element->next;
}
@@ -113,12 +139,11 @@ messages_event(UI_MESSAGES_Handle *messages,
void
_messages_iterate_print(UI_MESSAGES_Handle *messages,
+ const time_t* timestamp,
const struct GNUNET_CHAT_Message *message)
{
enum GNUNET_CHAT_MessageKind kind = GNUNET_CHAT_message_get_kind(message);
- list_input_print(messages, 1);
-
struct GNUNET_CHAT_Contact *sender = GNUNET_CHAT_message_get_sender(message);
const char *name = sender? GNUNET_CHAT_contact_get_name(sender) : NULL;
@@ -126,29 +151,35 @@ _messages_iterate_print(UI_MESSAGES_Handle *messages,
const struct GNUNET_CHAT_File *file = GNUNET_CHAT_message_get_file(message);
- struct GNUNET_TIME_Absolute abs_time = GNUNET_CHAT_message_get_timestamp(
- message
- );
+ struct tm* ts = localtime(timestamp);
+ char time_buf [255];
- struct GNUNET_TIME_Timestamp timestamp = GNUNET_TIME_absolute_to_timestamp(
- abs_time
- );
+ strftime(time_buf, sizeof(time_buf), "%H:%M", ts);
- const time_t s_after_epoch = (
- GNUNET_TIME_timestamp_to_s(timestamp)
- );
+ ts = _messages_new_day(&(messages->line_time), timestamp);
- struct tm* ts = localtime(&s_after_epoch);
- char time_buf [255];
+ list_input_print(messages, ts? 2 : 1);
+ wmove(messages->window, y, 0);
- strftime(time_buf, sizeof(time_buf), "%H:%M", ts);
+ if (ts) {
+ char date_buf [255];
+
+ strftime(date_buf, sizeof(date_buf), "%x", ts);
+
+ const int width = getmaxx(messages->window);
+
+ whline(messages->window, '-', width);
+ wmove(messages->window, y, 8);
+
+ wprintw(messages->window, " %s ", date_buf);
+ wmove(messages->window, y+1, 0);
+ }
const int attrs_select = A_BOLD;
if (selected) wattron(messages->window, attrs_select);
- wmove(messages->window, y, 0);
- wprintw(messages->window, "%s | ", time_buf);
+ wprintw(messages->window, " %s | ", time_buf);
switch (kind) {
case GNUNET_CHAT_KIND_JOIN:
@@ -207,7 +238,6 @@ _messages_iterate_print(UI_MESSAGES_Handle *messages,
break;
}
-
if (selected) wattroff(messages->window, attrs_select);
}
@@ -218,12 +248,14 @@ messages_print(UI_MESSAGES_Handle *messages)
return;
list_input_reset(messages);
+ messages->line_time = 0;
+
werase(messages->window);
UI_MESSAGES_List *element = messages->head;
while (element)
{
- _messages_iterate_print(messages, element->message);
+ _messages_iterate_print(messages, &(element->timestamp), element->message);
element = element->next;
}
@@ -278,17 +310,12 @@ _message_compare_timestamps(UNUSED void *cls,
UI_MESSAGES_List *list0,
UI_MESSAGES_List *list1)
{
- struct GNUNET_TIME_Absolute time0, time1;
-
if ((!list0) || (!list1))
return 0;
- time0 = GNUNET_CHAT_message_get_timestamp(list0->message);
- time1 = GNUNET_CHAT_message_get_timestamp(list1->message);
-
- if (GNUNET_TIME_absolute_cmp(time0, >, time1))
+ if (list0->timestamp > list1->timestamp)
return -1;
- else if (GNUNET_TIME_absolute_cmp(time0, <, time1))
+ else if (list0->timestamp < list1->timestamp)
return +1;
else
return 0;
@@ -309,19 +336,33 @@ messages_add(UI_MESSAGES_Handle *messages,
break;
}
- const int height = getmaxy(messages->window);
- const int line_height = height - 2;
-
- int count = 0;
+ list_input_reset(messages);
+ messages->line_time = 0;
UI_MESSAGES_List *element = messages->head;
while (element)
{
- count++;
+ struct tm *ts = _messages_new_day(
+ &(messages->line_time),
+ &(element->timestamp)
+ );
+
+ list_input_select(messages, ts? 2 : 1, element->message);
element = element->next;
}
+ list_input_select(messages, 1, NULL);
+
+ const struct GNUNET_TIME_Absolute abs_time = (
+ GNUNET_CHAT_message_get_timestamp(message)
+ );
+
+ const struct GNUNET_TIME_Timestamp timestamp = (
+ GNUNET_TIME_absolute_to_timestamp(abs_time)
+ );
+
element = GNUNET_new(UI_MESSAGES_List);
+ element->timestamp = GNUNET_TIME_timestamp_to_s(timestamp);
element->message = message;
GNUNET_CONTAINER_DLL_insert_sorted(
@@ -333,11 +374,10 @@ messages_add(UI_MESSAGES_Handle *messages,
element
);
- if (messages->line_selected >= count)
- messages->line_selected = count + 1;
+ list_input_select(messages, 1, NULL);
- if ((line_height > 0) && (messages->line_offset + line_height >= count))
- messages->line_offset = count + 1 - line_height;
+ if (!(messages->selected))
+ list_input_event(messages, KEY_DOWN);
}
void
diff --git a/src/ui/messages.h b/src/ui/messages.h
@@ -36,6 +36,8 @@ struct MESSENGER_Application;
typedef struct UI_MESSAGES_List
{
+ time_t timestamp;
+
const struct GNUNET_CHAT_Message *message;
struct UI_MESSAGES_List *prev;
@@ -51,9 +53,13 @@ typedef struct UI_MESSAGES_Handle
UI_MESSAGES_List *head;
UI_MESSAGES_List *tail;
+ int line_prev;
+ int line_next;
+
int line_index;
int line_offset;
int line_selected;
+ time_t line_time;
const struct GNUNET_CHAT_Message *selected;