aboutsummaryrefslogtreecommitdiff
path: root/src/ui/chats.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/chats.c')
-rw-r--r--src/ui/chats.c189
1 files changed, 189 insertions, 0 deletions
diff --git a/src/ui/chats.c b/src/ui/chats.c
new file mode 100644
index 0000000..991e43b
--- /dev/null
+++ b/src/ui/chats.c
@@ -0,0 +1,189 @@
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/chats.c
23 */
24
25#include "chats.h"
26
27#include "../application.h"
28#include "../util.h"
29
30static int
31_chats_iterate(void *cls,
32 UNUSED struct GNUNET_CHAT_Handle *handle,
33 struct GNUNET_CHAT_Group *group)
34{
35 UI_CHATS_Handle *chats = cls;
36
37 const bool selected = (chats->line_selected == chats->line_index);
38
39 chats->line_index++;
40
41 if (selected)
42 chats->selected = GNUNET_CHAT_group_get_context(group);
43
44 return GNUNET_YES;
45}
46
47static int
48_chats_iterate_messages(void *cls,
49 UNUSED struct GNUNET_CHAT_Context *context,
50 const struct GNUNET_CHAT_Message *message)
51{
52 UI_MESSAGES_Handle *messages = cls;
53
54 messages_add(messages, message);
55
56 return GNUNET_YES;
57}
58
59void
60chats_event(UI_CHATS_Handle *chats,
61 MESSENGER_Application *app,
62 int key)
63{
64 chats->line_index = 0;
65 chats->selected = NULL;
66
67 int count = GNUNET_CHAT_iterate_groups(
68 app->chat.handle,
69 &_chats_iterate,
70 chats
71 );
72
73 switch (key)
74 {
75 case 27:
76 case KEY_EXIT:
77 {
78 GNUNET_CHAT_disconnect(app->chat.handle);
79 break;
80 }
81 case KEY_UP:
82 {
83 chats->line_selected--;
84 break;
85 }
86 case KEY_DOWN:
87 {
88 chats->line_selected++;
89 break;
90 }
91 case '\n':
92 case KEY_ENTER:
93 {
94 if (chats->selected)
95 {
96 messages_clear(&(app->messages));
97
98 GNUNET_CHAT_context_iterate_messages(
99 chats->selected,
100 &_chats_iterate_messages,
101 &(app->messages)
102 );
103
104 GNUNET_CHAT_context_set_user_pointer(
105 chats->selected,
106 &(app->messages)
107 );
108
109 app->chat.context = chats->selected;
110 }
111
112 break;
113 }
114 default:
115 break;
116 }
117
118 if (chats->line_selected < 0)
119 chats->line_selected = 0;
120 else if (chats->line_selected >= count)
121 chats->line_selected = count - 1;
122
123 if (!(chats->window))
124 return;
125
126 const int height = getmaxy(chats->window) - getbegy(chats->window);
127 const int y = chats->line_selected - chats->line_offset;
128
129 if (y < 0)
130 chats->line_offset += y;
131 else if (y + 1 >= height)
132 chats->line_offset += y + 1 - height;
133
134 if (chats->line_offset < 0)
135 chats->line_offset = 0;
136 else if (chats->line_offset >= count)
137 chats->line_offset = count - 1;
138}
139
140int
141_chats_iterate_print(void *cls,
142 UNUSED struct GNUNET_CHAT_Handle *handle,
143 struct GNUNET_CHAT_Group *group)
144{
145 UI_CHATS_Handle *chats = cls;
146
147 const bool selected = (chats->line_selected == chats->line_index);
148 const int y = chats->line_index - chats->line_offset;
149
150 chats->line_index++;
151
152 if (y < 0)
153 return GNUNET_YES;
154
155 const int height = getmaxy(chats->window) - getbegy(chats->window);
156
157 if (y >= height)
158 return GNUNET_NO;
159
160 const char *name = GNUNET_CHAT_group_get_name(group);
161
162 const int attrs_select = A_BOLD;
163
164 if (selected) wattron(chats->window, attrs_select);
165
166 wmove(chats->window, y, 0);
167 wprintw(chats->window, "%s", name);
168
169 if (selected) wattroff(chats->window, attrs_select);
170
171 return GNUNET_YES;
172}
173
174void
175chats_print(UI_CHATS_Handle *chats,
176 MESSENGER_Application *app)
177{
178 if (!(chats->window))
179 return;
180
181 chats->line_index = 0;
182 werase(chats->window);
183
184 GNUNET_CHAT_iterate_groups(
185 app->chat.handle,
186 &_chats_iterate_print,
187 chats
188 );
189}