aboutsummaryrefslogtreecommitdiff
path: root/src/ui/messages.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/messages.c')
-rw-r--r--src/ui/messages.c209
1 files changed, 192 insertions, 17 deletions
diff --git a/src/ui/messages.c b/src/ui/messages.c
index 780dd45..79a7cab 100644
--- a/src/ui/messages.c
+++ b/src/ui/messages.c
@@ -25,56 +25,231 @@
25#include "messages.h" 25#include "messages.h"
26 26
27#include "../application.h" 27#include "../application.h"
28#include "../util.h"
29
30void
31_messages_iterate(UI_MESSAGES_Handle *messages,
32 const struct GNUNET_CHAT_Message *message)
33{
34 const bool selected = (messages->line_selected == messages->line_index);
35
36 messages->line_index++;
37
38 if (selected)
39 messages->selected = message;
40}
28 41
29void 42void
30messages_event(UI_MESSAGES_Handle *messages, 43messages_event(UI_MESSAGES_Handle *messages,
31 struct MESSENGER_Application *app, 44 MESSENGER_Application *app,
32 int key) 45 int key)
33{ 46{
34 // TODO 47 messages->line_index = 0;
48 messages->selected = NULL;
49
50 int count = 0;
51
52 UI_MESSAGES_List *element = messages->head;
53 while (element)
54 {
55 _messages_iterate(messages, element->message);
56 count++;
57
58 element = element->next;
59 }
60
61 switch (key)
62 {
63 case 27:
64 case KEY_EXIT:
65 {
66 app->chat.context = NULL;
67 break;
68 }
69 case KEY_UP:
70 {
71 messages->line_selected--;
72 break;
73 }
74 case KEY_DOWN:
75 {
76 messages->line_selected++;
77 break;
78 }
79 case '\n':
80 case KEY_ENTER:
81 {
82 if (messages->selected)
83 GNUNET_CHAT_message_delete(
84 messages->selected,
85 GNUNET_TIME_relative_get_zero_()
86 );
87
88 break;
89 }
90 default:
91 break;
92 }
93
94 if (messages->line_selected < 0)
95 messages->line_selected = 0;
96 else if (messages->line_selected >= count)
97 messages->line_selected = count - 1;
98
99 if (!(messages->window))
100 return;
101
102 const int height = getmaxy(messages->window) - getbegy(messages->window);
103 const int y = messages->line_selected - messages->line_offset;
104
105 if (y < 0)
106 messages->line_offset += y;
107 else if (y + 1 >= height)
108 messages->line_offset += y + 1 - height;
109
110 if (messages->line_offset < 0)
111 messages->line_offset = 0;
112 else if (messages->line_offset >= count)
113 messages->line_offset = count - 1;
35} 114}
36 115
37int 116void
38_messages_iterate_print(void *cls, 117_messages_iterate_print(UI_MESSAGES_Handle *messages,
39 struct GNUNET_CHAT_Context *context,
40 const struct GNUNET_CHAT_Message *message) 118 const struct GNUNET_CHAT_Message *message)
41{ 119{
42 UI_MESSAGES_Handle *messages = cls; 120 const bool selected = (messages->line_selected == messages->line_index);
121 const int y = messages->line_index - messages->line_offset;
122
123 messages->line_index++;
124
125 if (y < 0)
126 return;
43 127
44 const int y = messages->line_index++; 128 const int height = getmaxy(messages->window) - getbegy(messages->window);
129
130 if (y >= height)
131 return;
45 132
46 enum GNUNET_CHAT_MessageKind kind = GNUNET_CHAT_message_get_kind(message); 133 enum GNUNET_CHAT_MessageKind kind = GNUNET_CHAT_message_get_kind(message);
134 struct GNUNET_CHAT_Contact *sender = GNUNET_CHAT_message_get_sender(message);
135
136 const char *name = sender? GNUNET_CHAT_contact_get_name(sender) : NULL;
47 const char *text = GNUNET_CHAT_message_get_text(message); 137 const char *text = GNUNET_CHAT_message_get_text(message);
48 138
49 struct GNUNET_TIME_Absolute timestamp = GNUNET_CHAT_message_get_timestamp( 139 struct GNUNET_TIME_Absolute timestamp = GNUNET_CHAT_message_get_timestamp(
50 message 140 message
51 ); 141 );
52 142
143 const int attrs_select = A_BOLD;
144
145 if (selected) wattron(messages->window, attrs_select);
146
53 wmove(messages->window, y, 0); 147 wmove(messages->window, y, 0);
54 wprintw( 148 wprintw(
55 messages->window, 149 messages->window,
56 "%s | [%d]: %s", 150 "%s | [%d] %s: %s",
57 GNUNET_TIME_absolute2s(timestamp), 151 GNUNET_TIME_absolute2s(timestamp),
58 (int) kind, 152 (int) kind,
153 name,
59 text 154 text
60 ); 155 );
61 156
62 return GNUNET_YES; 157 if (selected) wattroff(messages->window, attrs_select);
63} 158}
64 159
65void 160void
66messages_print(UI_MESSAGES_Handle *messages, 161messages_print(UI_MESSAGES_Handle *messages)
67 struct MESSENGER_Application *app)
68{ 162{
69 if (!(messages->window)) 163 if (!(messages->window))
70 return; 164 return;
71 165
72 struct GNUNET_CHAT_Context *context = app->chat.context;
73
74 messages->line_index = 0; 166 messages->line_index = 0;
75 GNUNET_CHAT_context_iterate_messages( 167 werase(messages->window);
76 context, 168
77 _messages_iterate_print, 169 UI_MESSAGES_List *element = messages->head;
78 messages 170 while (element)
171 {
172 _messages_iterate_print(messages, element->message);
173 element = element->next;
174 }
175}
176
177void
178messages_clear(UI_MESSAGES_Handle *messages)
179{
180 UI_MESSAGES_List *element;
181 while (messages->head)
182 {
183 element = messages->head;
184
185 GNUNET_CONTAINER_DLL_remove(
186 messages->head,
187 messages->tail,
188 element
189 );
190
191 GNUNET_free(element);
192 }
193}
194
195static int
196_message_compare_timestamps(UNUSED void *cls,
197 UI_MESSAGES_List *list0,
198 UI_MESSAGES_List *list1)
199{
200 struct GNUNET_TIME_Absolute time0, time1;
201
202 if ((!list0) || (!list1))
203 return 0;
204
205 time0 = GNUNET_CHAT_message_get_timestamp(list0->message);
206 time1 = GNUNET_CHAT_message_get_timestamp(list1->message);
207
208 if (GNUNET_TIME_absolute_cmp(time0, >, time1))
209 return -1;
210 else if (GNUNET_TIME_absolute_cmp(time0, <, time1))
211 return +1;
212 else
213 return 0;
214}
215
216void
217messages_add(UI_MESSAGES_Handle *messages,
218 const struct GNUNET_CHAT_Message *message)
219{
220 if (GNUNET_CHAT_KIND_DELETION == GNUNET_CHAT_message_get_kind(message))
221 return;
222
223 UI_MESSAGES_List *element = GNUNET_new(UI_MESSAGES_List);
224 element->message = message;
225
226 GNUNET_CONTAINER_DLL_insert_sorted(
227 UI_MESSAGES_List,
228 _message_compare_timestamps,
229 NULL,
230 messages->head,
231 messages->tail,
232 element
79 ); 233 );
80} 234}
235
236void
237messages_remove(UI_MESSAGES_Handle *messages,
238 const struct GNUNET_CHAT_Message *message)
239{
240 UI_MESSAGES_List *element = messages->head;
241 while (element)
242 {
243 if (element->message == message)
244 break;
245
246 element = element->next;
247 }
248
249 if (element)
250 GNUNET_CONTAINER_DLL_remove(
251 messages->head,
252 messages->tail,
253 element
254 );
255}