diff options
Diffstat (limited to 'src/ui')
-rw-r--r-- | src/ui/chat.h | 37 | ||||
-rw-r--r-- | src/ui/chats.c | 19 | ||||
-rw-r--r-- | src/ui/members.c | 217 | ||||
-rw-r--r-- | src/ui/members.h | 78 | ||||
-rw-r--r-- | src/ui/messages.c | 19 | ||||
-rw-r--r-- | src/ui/messages.h | 2 |
6 files changed, 346 insertions, 26 deletions
diff --git a/src/ui/chat.h b/src/ui/chat.h new file mode 100644 index 0000000..b8febf4 --- /dev/null +++ b/src/ui/chat.h | |||
@@ -0,0 +1,37 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2022 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | /* | ||
21 | * @author Tobias Frisch | ||
22 | * @file ui/chat.h | ||
23 | */ | ||
24 | |||
25 | #ifndef UI_CHAT_H_ | ||
26 | #define UI_CHAT_H_ | ||
27 | |||
28 | #include "members.h" | ||
29 | #include "messages.h" | ||
30 | |||
31 | typedef struct UI_CHAT_Handle | ||
32 | { | ||
33 | UI_MEMBERS_Handle members; | ||
34 | UI_MESSAGES_Handle messages; | ||
35 | } UI_CHAT_Handle; | ||
36 | |||
37 | #endif /* UI_CHAT_H_ */ | ||
diff --git a/src/ui/chats.c b/src/ui/chats.c index dbffc26..fc7056c 100644 --- a/src/ui/chats.c +++ b/src/ui/chats.c | |||
@@ -49,10 +49,8 @@ _chats_iterate_messages(void *cls, | |||
49 | struct GNUNET_CHAT_Context *context, | 49 | struct GNUNET_CHAT_Context *context, |
50 | const struct GNUNET_CHAT_Message *message) | 50 | const struct GNUNET_CHAT_Message *message) |
51 | { | 51 | { |
52 | UI_MESSAGES_Handle *messages = cls; | 52 | MESSENGER_Chat *chat = cls; |
53 | 53 | chat_process_message(chat, context, message); | |
54 | messages_add(messages, context, message); | ||
55 | |||
56 | return GNUNET_YES; | 54 | return GNUNET_YES; |
57 | } | 55 | } |
58 | 56 | ||
@@ -101,17 +99,18 @@ chats_event(UI_CHATS_Handle *chats, | |||
101 | { | 99 | { |
102 | struct GNUNET_CHAT_Context *context = GNUNET_CHAT_group_get_context(chats->selected); | 100 | struct GNUNET_CHAT_Context *context = GNUNET_CHAT_group_get_context(chats->selected); |
103 | 101 | ||
104 | messages_clear(&(app->messages)); | 102 | members_clear(&(app->current.members)); |
103 | messages_clear(&(app->current.messages)); | ||
105 | 104 | ||
106 | GNUNET_CHAT_context_iterate_messages( | 105 | GNUNET_CHAT_context_set_user_pointer( |
107 | context, | 106 | context, |
108 | &_chats_iterate_messages, | 107 | &(app->current) |
109 | &(app->messages) | ||
110 | ); | 108 | ); |
111 | 109 | ||
112 | GNUNET_CHAT_context_set_user_pointer( | 110 | GNUNET_CHAT_context_iterate_messages( |
113 | context, | 111 | context, |
114 | &(app->messages) | 112 | &_chats_iterate_messages, |
113 | &(app->chat) | ||
115 | ); | 114 | ); |
116 | 115 | ||
117 | app->chat.context = context; | 116 | app->chat.context = context; |
diff --git a/src/ui/members.c b/src/ui/members.c new file mode 100644 index 0000000..c500d58 --- /dev/null +++ b/src/ui/members.c | |||
@@ -0,0 +1,217 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2022 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | /* | ||
21 | * @author Tobias Frisch | ||
22 | * @file ui/members.c | ||
23 | */ | ||
24 | |||
25 | #include "members.h" | ||
26 | |||
27 | #include "../application.h" | ||
28 | #include "../util.h" | ||
29 | |||
30 | void | ||
31 | members_event(UI_MEMBERS_Handle *members, | ||
32 | struct MESSENGER_Application *app, | ||
33 | int key) | ||
34 | { | ||
35 | members->line_index = 0; | ||
36 | members->selected = NULL; | ||
37 | |||
38 | int count = 0; | ||
39 | |||
40 | UI_MEMBERS_List *element = members->head; | ||
41 | while (element) | ||
42 | { | ||
43 | count++; | ||
44 | |||
45 | element = element->next; | ||
46 | } | ||
47 | |||
48 | switch (key) | ||
49 | { | ||
50 | case 27: | ||
51 | case KEY_EXIT: | ||
52 | case '\t': | ||
53 | { | ||
54 | app->chat.show_members = FALSE; | ||
55 | break; | ||
56 | } | ||
57 | case KEY_UP: | ||
58 | { | ||
59 | members->line_selected--; | ||
60 | break; | ||
61 | } | ||
62 | case KEY_DOWN: | ||
63 | { | ||
64 | members->line_selected++; | ||
65 | break; | ||
66 | } | ||
67 | case '\n': | ||
68 | case KEY_ENTER: | ||
69 | { | ||
70 | if (members->selected) | ||
71 | { | ||
72 | // TODO | ||
73 | } | ||
74 | |||
75 | break; | ||
76 | } | ||
77 | default: | ||
78 | break; | ||
79 | } | ||
80 | |||
81 | if (members->line_selected < 0) | ||
82 | members->line_selected = 0; | ||
83 | else if (members->line_selected >= count) | ||
84 | members->line_selected = count - 1; | ||
85 | |||
86 | if (!(members->window)) | ||
87 | return; | ||
88 | |||
89 | const int height = getmaxy(members->window) - getbegy(members->window); | ||
90 | const int y = members->line_selected - members->line_offset; | ||
91 | |||
92 | if (y < 0) | ||
93 | members->line_offset += y; | ||
94 | else if (y + 1 >= height) | ||
95 | members->line_offset += y + 1 - height; | ||
96 | |||
97 | if (members->line_offset < 0) | ||
98 | members->line_offset = 0; | ||
99 | else if (members->line_offset >= count) | ||
100 | members->line_offset = count - 1; | ||
101 | } | ||
102 | |||
103 | static void | ||
104 | _members_iterate_print(UI_MEMBERS_Handle *members, | ||
105 | const struct GNUNET_CHAT_Contact *contact) | ||
106 | { | ||
107 | const bool selected = (members->line_selected == members->line_index); | ||
108 | const int y = members->line_index - members->line_offset; | ||
109 | |||
110 | members->line_index++; | ||
111 | |||
112 | if (y < 0) | ||
113 | return; | ||
114 | |||
115 | const int height = getmaxy(members->window) - getbegy(members->window); | ||
116 | |||
117 | if (y >= height) | ||
118 | return; | ||
119 | |||
120 | const int attrs_select = A_BOLD; | ||
121 | |||
122 | if (selected) wattron(members->window, attrs_select); | ||
123 | |||
124 | wmove(members->window, y, 0); | ||
125 | |||
126 | const char *name = GNUNET_CHAT_contact_get_name(contact); | ||
127 | wprintw(members->window, "%s", name); | ||
128 | |||
129 | if (selected) wattroff(members->window, attrs_select); | ||
130 | } | ||
131 | |||
132 | void | ||
133 | members_print(UI_MEMBERS_Handle *members) | ||
134 | { | ||
135 | if (!(members->window)) | ||
136 | return; | ||
137 | |||
138 | members->line_index = 0; | ||
139 | werase(members->window); | ||
140 | |||
141 | UI_MEMBERS_List *element = members->head; | ||
142 | while (element) | ||
143 | { | ||
144 | _members_iterate_print(members, element->contact); | ||
145 | |||
146 | element = element->next; | ||
147 | } | ||
148 | } | ||
149 | |||
150 | void | ||
151 | members_clear(UI_MEMBERS_Handle *members) | ||
152 | { | ||
153 | UI_MEMBERS_List *element; | ||
154 | while (members->head) | ||
155 | { | ||
156 | element = members->head; | ||
157 | |||
158 | GNUNET_CONTAINER_DLL_remove( | ||
159 | members->head, | ||
160 | members->tail, | ||
161 | element | ||
162 | ); | ||
163 | |||
164 | GNUNET_free(element); | ||
165 | } | ||
166 | |||
167 | members->line_selected = 0; | ||
168 | } | ||
169 | |||
170 | bool | ||
171 | members_add(UI_MEMBERS_Handle *members, | ||
172 | const struct GNUNET_CHAT_Contact *contact) | ||
173 | { | ||
174 | UI_MEMBERS_List *element = members->head; | ||
175 | while (element) | ||
176 | { | ||
177 | if (element->contact == contact) | ||
178 | break; | ||
179 | |||
180 | element = element->next; | ||
181 | } | ||
182 | |||
183 | if (element) | ||
184 | return FALSE; | ||
185 | |||
186 | element = GNUNET_new(UI_MEMBERS_List); | ||
187 | element->contact = contact; | ||
188 | |||
189 | GNUNET_CONTAINER_DLL_insert_tail( | ||
190 | members->head, | ||
191 | members->tail, | ||
192 | element | ||
193 | ); | ||
194 | |||
195 | return TRUE; | ||
196 | } | ||
197 | |||
198 | void | ||
199 | members_remove(UI_MEMBERS_Handle *members, | ||
200 | const struct GNUNET_CHAT_Contact *contact) | ||
201 | { | ||
202 | UI_MEMBERS_List *element = members->head; | ||
203 | while (element) | ||
204 | { | ||
205 | if (element->contact == contact) | ||
206 | break; | ||
207 | |||
208 | element = element->next; | ||
209 | } | ||
210 | |||
211 | if (element) | ||
212 | GNUNET_CONTAINER_DLL_remove( | ||
213 | members->head, | ||
214 | members->tail, | ||
215 | element | ||
216 | ); | ||
217 | } | ||
diff --git a/src/ui/members.h b/src/ui/members.h new file mode 100644 index 0000000..4f7c50d --- /dev/null +++ b/src/ui/members.h | |||
@@ -0,0 +1,78 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2022 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | /* | ||
21 | * @author Tobias Frisch | ||
22 | * @file ui/members.h | ||
23 | */ | ||
24 | |||
25 | #ifndef UI_MEMBERS_H_ | ||
26 | #define UI_MEMBERS_H_ | ||
27 | |||
28 | #include <stdlib.h> | ||
29 | #include <curses.h> | ||
30 | |||
31 | #include <gnunet/platform.h> | ||
32 | #include <gnunet/gnunet_chat_lib.h> | ||
33 | #include <gnunet/gnunet_util_lib.h> | ||
34 | |||
35 | struct MESSENGER_Application; | ||
36 | |||
37 | typedef struct UI_MEMBERS_List | ||
38 | { | ||
39 | const struct GNUNET_CHAT_Contact *contact; | ||
40 | |||
41 | struct UI_MEMBERS_List *prev; | ||
42 | struct UI_MEMBERS_List *next; | ||
43 | } UI_MEMBERS_List; | ||
44 | |||
45 | typedef struct UI_MEMBERS_Handle | ||
46 | { | ||
47 | WINDOW *window; | ||
48 | |||
49 | UI_MEMBERS_List *head; | ||
50 | UI_MEMBERS_List *tail; | ||
51 | |||
52 | int line_index; | ||
53 | int line_offset; | ||
54 | int line_selected; | ||
55 | |||
56 | const struct GNUNET_CHAT_Contact *selected; | ||
57 | } UI_MEMBERS_Handle; | ||
58 | |||
59 | void | ||
60 | members_event(UI_MEMBERS_Handle *members, | ||
61 | struct MESSENGER_Application *app, | ||
62 | int key); | ||
63 | |||
64 | void | ||
65 | members_print(UI_MEMBERS_Handle *members); | ||
66 | |||
67 | void | ||
68 | members_clear(UI_MEMBERS_Handle *members); | ||
69 | |||
70 | bool | ||
71 | members_add(UI_MEMBERS_Handle *members, | ||
72 | const struct GNUNET_CHAT_Contact *contact); | ||
73 | |||
74 | void | ||
75 | members_remove(UI_MEMBERS_Handle *members, | ||
76 | const struct GNUNET_CHAT_Contact *contact); | ||
77 | |||
78 | #endif /* UI_MEMBERS_H_ */ | ||
diff --git a/src/ui/messages.c b/src/ui/messages.c index 70d64df..9b0a692 100644 --- a/src/ui/messages.c +++ b/src/ui/messages.c | |||
@@ -86,6 +86,11 @@ messages_event(UI_MESSAGES_Handle *messages, | |||
86 | messages->line_selected++; | 86 | messages->line_selected++; |
87 | break; | 87 | break; |
88 | } | 88 | } |
89 | case '\t': | ||
90 | { | ||
91 | app->chat.show_members = TRUE; | ||
92 | break; | ||
93 | } | ||
89 | case '\n': | 94 | case '\n': |
90 | case KEY_ENTER: | 95 | case KEY_ENTER: |
91 | { | 96 | { |
@@ -337,7 +342,6 @@ _message_compare_timestamps(UNUSED void *cls, | |||
337 | 342 | ||
338 | void | 343 | void |
339 | messages_add(UI_MESSAGES_Handle *messages, | 344 | messages_add(UI_MESSAGES_Handle *messages, |
340 | struct GNUNET_CHAT_Context *context, | ||
341 | const struct GNUNET_CHAT_Message *message) | 345 | const struct GNUNET_CHAT_Message *message) |
342 | { | 346 | { |
343 | enum GNUNET_CHAT_MessageKind kind = GNUNET_CHAT_message_get_kind(message); | 347 | enum GNUNET_CHAT_MessageKind kind = GNUNET_CHAT_message_get_kind(message); |
@@ -351,15 +355,6 @@ messages_add(UI_MESSAGES_Handle *messages, | |||
351 | break; | 355 | break; |
352 | } | 356 | } |
353 | 357 | ||
354 | struct GNUNET_CHAT_Contact *sender = GNUNET_CHAT_message_get_sender(message); | ||
355 | struct GNUNET_CHAT_Group *group = GNUNET_CHAT_context_get_group(context); | ||
356 | |||
357 | if ((GNUNET_CHAT_KIND_JOIN == kind) && | ||
358 | (GNUNET_CHAT_member_get_user_pointer(group, sender))) | ||
359 | { | ||
360 | return; | ||
361 | } | ||
362 | |||
363 | const int height = getmaxy(messages->window) - getbegy(messages->window); | 358 | const int height = getmaxy(messages->window) - getbegy(messages->window); |
364 | const int line_height = height - 2; | 359 | const int line_height = height - 2; |
365 | 360 | ||
@@ -384,9 +379,6 @@ messages_add(UI_MESSAGES_Handle *messages, | |||
384 | element | 379 | element |
385 | ); | 380 | ); |
386 | 381 | ||
387 | if (GNUNET_CHAT_KIND_JOIN == kind) | ||
388 | GNUNET_CHAT_member_set_user_pointer(group, sender, element); | ||
389 | |||
390 | if (messages->line_selected >= count) | 382 | if (messages->line_selected >= count) |
391 | messages->line_selected = count + 1; | 383 | messages->line_selected = count + 1; |
392 | 384 | ||
@@ -396,7 +388,6 @@ messages_add(UI_MESSAGES_Handle *messages, | |||
396 | 388 | ||
397 | void | 389 | void |
398 | messages_remove(UI_MESSAGES_Handle *messages, | 390 | messages_remove(UI_MESSAGES_Handle *messages, |
399 | UNUSED struct GNUNET_CHAT_Context *context, | ||
400 | const struct GNUNET_CHAT_Message *message) | 391 | const struct GNUNET_CHAT_Message *message) |
401 | { | 392 | { |
402 | UI_MESSAGES_List *element = messages->head; | 393 | UI_MESSAGES_List *element = messages->head; |
diff --git a/src/ui/messages.h b/src/ui/messages.h index d969782..06de97f 100644 --- a/src/ui/messages.h +++ b/src/ui/messages.h | |||
@@ -75,12 +75,10 @@ messages_clear(UI_MESSAGES_Handle *messages); | |||
75 | 75 | ||
76 | void | 76 | void |
77 | messages_add(UI_MESSAGES_Handle *messages, | 77 | messages_add(UI_MESSAGES_Handle *messages, |
78 | struct GNUNET_CHAT_Context *context, | ||
79 | const struct GNUNET_CHAT_Message *message); | 78 | const struct GNUNET_CHAT_Message *message); |
80 | 79 | ||
81 | void | 80 | void |
82 | messages_remove(UI_MESSAGES_Handle *messages, | 81 | messages_remove(UI_MESSAGES_Handle *messages, |
83 | struct GNUNET_CHAT_Context *context, | ||
84 | const struct GNUNET_CHAT_Message *message); | 82 | const struct GNUNET_CHAT_Message *message); |
85 | 83 | ||
86 | #endif /* UI_MESSAGES_H_ */ | 84 | #endif /* UI_MESSAGES_H_ */ |