/[LeafOK_CVS]/lbbs/src/user_list_display.c
ViewVC logotype

Contents of /lbbs/src/user_list_display.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.3 - (show annotations)
Wed Oct 22 04:48:53 2025 UTC (4 months, 3 weeks ago) by sysadm
Branch: MAIN
Changes since 1.2: +153 -46 lines
Content type: text/x-csrc
Add user_online_list

1 /***************************************************************************
2 user_list_display.c - description
3 -------------------
4 Copyright : (C) 2004-2025 by Leaflet
5 Email : leaflet@leafok.com
6 ***************************************************************************/
7
8 /***************************************************************************
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 3 of the License, or *
13 * (at your option) any later version. *
14 * *
15 ***************************************************************************/
16
17 #include "common.h"
18 #include "io.h"
19 #include "log.h"
20 #include "login.h"
21 #include "screen.h"
22 #include "str_process.h"
23 #include "user_list.h"
24 #include "user_priv.h"
25 #include "user_list_display.h"
26 #include <string.h>
27 #include <time.h>
28 #include <sys/param.h>
29
30 enum select_cmd_t
31 {
32 EXIT_LIST = 0,
33 VIEW_USER,
34 CHANGE_PAGE,
35 SHOW_HELP,
36 };
37
38 static int user_list_draw_screen(int online_user)
39 {
40 clearscr();
41 show_top((online_user ? "[在线用户]" : "[已注册用户]"), BBS_name, "");
42 moveto(2, 0);
43 prints("返回[\033[1;32m←\033[0;37m,\033[1;32mESC\033[0;37m] 选择[\033[1;32m↑\033[0;37m,\033[1;32m↓\033[0;37m] "
44 "查看[\033[1;32m→\033[0;37m,\033[1;32mENTER\033[0;37m] 帮助[\033[1;32mh\033[0;37m]\033[m");
45 moveto(3, 0);
46
47 if (online_user)
48 {
49 prints("\033[44;37m \033[1;37m 编 号 用户名 昵称 在线时长 空闲 最后活动 \033[m");
50 }
51 else
52 {
53 prints("\033[44;37m \033[1;37m 编 号 用户名 昵称 上次登陆距今 \033[m");
54 }
55
56 return 0;
57 }
58
59 static int user_list_draw_items(int page_id, USER_INFO *p_users, int user_count)
60 {
61 char str_time_login[LINE_BUFFER_LEN];
62 time_t tm_now;
63 time_t tm_duration;
64 struct tm *p_tm;
65 int i;
66
67 clrline(4, 23);
68
69 time(&tm_now);
70
71 for (i = 0; i < user_count; i++)
72 {
73 tm_duration = tm_now - p_users[i].last_login_dt;
74 p_tm = gmtime(&tm_duration);
75 if (p_tm == NULL)
76 {
77 log_error("Invalid time duration\n");
78 str_time_login[0] = '\0';
79 }
80 else if (p_tm->tm_year > 70)
81 {
82 snprintf(str_time_login, sizeof(str_time_login),
83 "%d年", p_tm->tm_year - 70);
84 }
85 else if (p_tm->tm_yday > 0)
86 {
87 snprintf(str_time_login, sizeof(str_time_login),
88 "%d天", p_tm->tm_yday);
89 }
90 else if (p_tm->tm_hour > 0)
91 {
92 snprintf(str_time_login, sizeof(str_time_login),
93 "%d时%d分", p_tm->tm_hour, p_tm->tm_min);
94 }
95 else
96 {
97 snprintf(str_time_login, sizeof(str_time_login),
98 "%d分%d秒", p_tm->tm_min, p_tm->tm_sec);
99 }
100
101 moveto(4 + i, 1);
102
103 prints(" %6d %s%*s %s%*s %s",
104 p_users[i].uid,
105 p_users[i].username,
106 BBS_username_max_len - str_length(p_users[i].username, 1),
107 "",
108 p_users[i].nickname,
109 BBS_nickname_max_len / 2 - str_length(p_users[i].nickname, 1),
110 "",
111 str_time_login);
112 }
113
114 return 0;
115 }
116
117 static int user_online_list_draw_items(int page_id, USER_ONLINE_INFO *p_users, int user_count)
118 {
119 char str_time_login[LINE_BUFFER_LEN];
120 char str_time_idle[LINE_BUFFER_LEN];
121 const char *p_action_title;
122 time_t tm_now;
123 time_t tm_duration;
124 struct tm *p_tm;
125 int i;
126
127 clrline(4, 23);
128
129 time(&tm_now);
130
131 for (i = 0; i < user_count; i++)
132 {
133 tm_duration = tm_now - p_users[i].login_tm;
134 p_tm = gmtime(&tm_duration);
135 if (p_tm == NULL)
136 {
137 log_error("Invalid time duration\n");
138 str_time_login[0] = '\0';
139 }
140 else if (p_tm->tm_yday > 0)
141 {
142 snprintf(str_time_login, sizeof(str_time_login),
143 "%d天%d时", p_tm->tm_yday, p_tm->tm_hour);
144 }
145 else if (p_tm->tm_hour > 0)
146 {
147 snprintf(str_time_login, sizeof(str_time_login),
148 "%d时%d分", p_tm->tm_hour, p_tm->tm_min);
149 }
150 else
151 {
152 snprintf(str_time_login, sizeof(str_time_login),
153 "%d\'%d\"", p_tm->tm_min, p_tm->tm_sec);
154 }
155
156 tm_duration = tm_now - p_users[i].last_tm;
157 p_tm = gmtime(&tm_duration);
158 if (p_tm == NULL)
159 {
160 log_error("Invalid time duration\n");
161 str_time_idle[0] = '\0';
162 }
163 else if (p_tm->tm_min > 0)
164 {
165 snprintf(str_time_idle, sizeof(str_time_idle),
166 "%d\'%d\"", p_tm->tm_min, p_tm->tm_sec);
167 }
168 else
169 {
170 snprintf(str_time_idle, sizeof(str_time_idle),
171 "%d\"", p_tm->tm_sec);
172 }
173
174 p_action_title = (p_users[i].current_action_title != NULL
175 ? p_users[i].current_action_title
176 : p_users[i].current_action);
177
178 moveto(4 + i, 1);
179
180 prints(" %6d %s%*s %s%*s %s%*s %s%*s %s",
181 p_users[i].user_info.uid,
182 p_users[i].user_info.username,
183 BBS_username_max_len - str_length(p_users[i].user_info.username, 1),
184 "",
185 p_users[i].user_info.nickname,
186 BBS_nickname_max_len / 2 - str_length(p_users[i].user_info.nickname, 1),
187 "",
188 str_time_login,
189 8 - str_length(str_time_login, 1),
190 "",
191 str_time_idle,
192 6 - str_length(str_time_idle, 1),
193 "",
194 p_action_title);
195 }
196
197 return 0;
198 }
199
200 static enum select_cmd_t user_list_select(int total_page, int item_count, int *p_page_id, int *p_selected_index)
201 {
202 int old_page_id = *p_page_id;
203 int old_selected_index = *p_selected_index;
204 int ch;
205
206 if (item_count > 0 && *p_selected_index >= 0)
207 {
208 moveto(4 + *p_selected_index, 1);
209 outc('>');
210 iflush();
211 }
212
213 while (!SYS_server_exit)
214 {
215 ch = igetch(100);
216
217 if (ch != KEY_NULL && ch != KEY_TIMEOUT)
218 {
219 BBS_last_access_tm = time(NULL);
220 }
221
222 switch (ch)
223 {
224 case KEY_NULL: // broken pipe
225 log_error("KEY_NULL\n");
226 case KEY_ESC:
227 case KEY_LEFT:
228 return EXIT_LIST; // exit list
229 case KEY_TIMEOUT:
230 if (time(NULL) - BBS_last_access_tm >= MAX_DELAY_TIME)
231 {
232 log_error("User input timeout\n");
233 return EXIT_LIST; // exit list
234 }
235 continue;
236 case CR:
237 case KEY_RIGHT:
238 if (item_count > 0)
239 {
240 return VIEW_USER;
241 }
242 break;
243 case KEY_HOME:
244 *p_page_id = 0;
245 case 'P':
246 case KEY_PGUP:
247 *p_selected_index = 0;
248 case 'k':
249 case KEY_UP:
250 if (*p_selected_index <= 0)
251 {
252 if (*p_page_id > 0)
253 {
254 (*p_page_id)--;
255 *p_selected_index = BBS_user_limit_per_page - 1;
256 }
257 else if (ch == KEY_UP || ch == 'k') // Rotate to the tail of list
258 {
259 if (total_page > 0)
260 {
261 *p_page_id = total_page - 1;
262 }
263 if (item_count > 0)
264 {
265 *p_selected_index = item_count - 1;
266 }
267 }
268 }
269 else
270 {
271 (*p_selected_index)--;
272 }
273 break;
274 case '$':
275 case KEY_END:
276 if (total_page > 0)
277 {
278 *p_page_id = total_page - 1;
279 }
280 case 'N':
281 case KEY_PGDN:
282 if (item_count > 0)
283 {
284 *p_selected_index = item_count - 1;
285 }
286 case 'j':
287 case KEY_DOWN:
288 if (*p_selected_index + 1 >= item_count) // next page
289 {
290 if (*p_page_id + 1 < total_page)
291 {
292 (*p_page_id)++;
293 *p_selected_index = 0;
294 }
295 else if (ch == KEY_DOWN || ch == 'j') // Rotate to the head of list
296 {
297 *p_page_id = 0;
298 *p_selected_index = 0;
299 }
300 }
301 else
302 {
303 (*p_selected_index)++;
304 }
305 break;
306 case 'h':
307 return SHOW_HELP;
308 default:
309 break;
310 }
311
312 if (old_page_id != *p_page_id)
313 {
314 return CHANGE_PAGE;
315 }
316
317 if (item_count > 0 && old_selected_index != *p_selected_index)
318 {
319 if (old_selected_index >= 0)
320 {
321 moveto(4 + old_selected_index, 1);
322 outc(' ');
323 }
324 if (*p_selected_index >= 0)
325 {
326 moveto(4 + *p_selected_index, 1);
327 outc('>');
328 }
329 iflush();
330
331 old_selected_index = *p_selected_index;
332 }
333 }
334
335 return EXIT_LIST;
336 }
337
338 int user_list_display(int online_user)
339 {
340 char page_info_str[LINE_BUFFER_LEN];
341 USER_INFO users[BBS_user_limit_per_page];
342 USER_ONLINE_INFO online_users[BBS_user_limit_per_page];
343 int user_count;
344 int page_count;
345 int page_id = 0;
346 int selected_index = 0;
347 int ret;
348
349 user_list_draw_screen(online_user);
350
351 if (online_user)
352 {
353 ret = query_user_online_list(page_id, online_users, &user_count, &page_count);
354 if (ret < 0)
355 {
356 log_error("query_user_online_list(page_id=%d) error\n", page_id);
357 return -2;
358 }
359 }
360 else
361 {
362 ret = query_user_list(page_id, users, &user_count, &page_count);
363 if (ret < 0)
364 {
365 log_error("query_user_list(page_id=%d) error\n", page_id);
366 return -2;
367 }
368 }
369
370 if (user_count == 0) // empty list
371 {
372 selected_index = 0;
373 }
374
375 while (!SYS_server_exit)
376 {
377 if (online_user)
378 {
379 ret = user_online_list_draw_items(page_id, online_users, user_count);
380 if (ret < 0)
381 {
382 log_error("user_online_list_draw_items(page_id=%d) error\n", page_id);
383 return -3;
384 }
385 }
386 else
387 {
388 ret = user_list_draw_items(page_id, users, user_count);
389 if (ret < 0)
390 {
391 log_error("user_list_draw_items(page_id=%d) error\n", page_id);
392 return -3;
393 }
394 }
395
396 snprintf(page_info_str, sizeof(page_info_str),
397 "\033[33m[第\033[36m%d\033[33m/\033[36m%d\033[33m页]",
398 page_id + 1, MAX(page_count, 1));
399
400 show_bottom(page_info_str);
401 iflush();
402
403 if (user_online_update(online_user ? "USER_ONLINE" : "USER_LIST") < 0)
404 {
405 log_error("user_online_update(%s) error\n",
406 (online_user ? "USER_ONLINE" : "USER_LIST"));
407 }
408
409 ret = user_list_select(page_count, user_count, &page_id, &selected_index);
410 switch (ret)
411 {
412 case EXIT_LIST:
413 return 0;
414 case CHANGE_PAGE:
415 ret = query_user_list(page_id, users, &user_count, &page_count);
416 if (ret < 0)
417 {
418 log_error("query_favor_articles(page_id=%d) error\n", page_id);
419 return -2;
420 }
421
422 if (user_count == 0) // empty list
423 {
424 selected_index = 0;
425 }
426 else if (selected_index >= user_count)
427 {
428 selected_index = user_count - 1;
429 }
430 break;
431 case VIEW_USER:
432 log_error("View user (uid=%d)\n",
433 (online_user ? online_users[selected_index].user_info.uid : users[selected_index].uid));
434 clearscr();
435 press_any_key_ex("功能不可用,按任意键返回", 60);
436 user_list_draw_screen(online_user);
437 break;
438 case SHOW_HELP:
439 // Display help information
440 display_file(DATA_READ_HELP, 1);
441 user_list_draw_screen(online_user);
442 break;
443 default:
444 log_error("Unknown command %d\n", ret);
445 }
446 }
447
448 return 0;
449 }

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1