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

Annotation of /lbbs/src/section_list_display.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.45 - (hide annotations)
Sat Oct 4 03:21:59 2025 UTC (5 months, 1 week ago) by sysadm
Branch: MAIN
Changes since 1.44: +39 -0 lines
Content type: text/x-csrc
Locate at next unread article by pressing 'S' in article list

1 sysadm 1.1 /***************************************************************************
2     section_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 sysadm 1.9 #include "article_cache.h"
18 sysadm 1.41 #include "article_op.h"
19 sysadm 1.20 #include "article_post.h"
20 sysadm 1.34 #include "article_view_log.h"
21 sysadm 1.26 #include "article_del.h"
22 sysadm 1.1 #include "common.h"
23     #include "io.h"
24 sysadm 1.34 #include "log.h"
25     #include "login.h"
26 sysadm 1.37 #include "menu.h"
27 sysadm 1.34 #include "section_list_display.h"
28     #include "section_list_loader.h"
29 sysadm 1.1 #include "screen.h"
30 sysadm 1.34 #include "str_process.h"
31 sysadm 1.18 #include "user_priv.h"
32 sysadm 1.29 #include <string.h>
33 sysadm 1.1 #include <time.h>
34 sysadm 1.6 #include <sys/param.h>
35 sysadm 1.1
36 sysadm 1.11 static int section_topic_view_mode = 0;
37 sysadm 1.13 static int section_topic_view_tid = -1;
38 sysadm 1.11
39 sysadm 1.1 enum select_cmd_t
40     {
41     EXIT_SECTION = 0,
42 sysadm 1.41 VIEW_ARTICLE,
43     CHANGE_PAGE,
44     SHOW_HELP,
45     CHANGE_NAME_DISPLAY,
46     POST_ARTICLE,
47     EDIT_ARTICLE,
48     DELETE_ARTICLE,
49     QUERY_ARTICLE,
50     FIRST_TOPIC_ARTICLE,
51     LAST_TOPIC_ARTICLE,
52 sysadm 1.45 SCAN_NEW_ARTICLE,
53 sysadm 1.41 VIEW_EX_DIR,
54 sysadm 1.1 };
55    
56 sysadm 1.36 static int section_list_draw_items(int page_id, ARTICLE *p_articles[], int article_count, int display_nickname, int ontop_start_offset)
57 sysadm 1.1 {
58     char str_time[LINE_BUFFER_LEN];
59     struct tm tm_sub;
60     char title_f[BBS_article_title_max_len + 1];
61     int title_f_len;
62     int eol;
63     int len;
64     int i;
65 sysadm 1.42 size_t j;
66 sysadm 1.3 char article_flag;
67 sysadm 1.17 int is_viewed;
68 sysadm 1.3 time_t tm_now;
69    
70     time(&tm_now);
71 sysadm 1.1
72     clrline(4, 23);
73    
74     for (i = 0; i < article_count; i++)
75     {
76 sysadm 1.18 if (p_articles[i]->uid == BBS_priv.uid)
77 sysadm 1.17 {
78 sysadm 1.18 is_viewed = 1;
79     }
80     else
81     {
82     is_viewed = article_view_log_is_viewed(p_articles[i]->aid, &BBS_article_view_log);
83     if (is_viewed < 0)
84     {
85     log_error("article_view_log_is_viewed(aid=%d) error\n", p_articles[i]->aid);
86     is_viewed = 0;
87     }
88 sysadm 1.17 }
89    
90 sysadm 1.3 if (p_articles[i]->excerption)
91     {
92 sysadm 1.17 article_flag = (is_viewed ? 'm' : 'M');
93 sysadm 1.3 }
94 sysadm 1.17 else if (p_articles[i]->lock && is_viewed)
95 sysadm 1.3 {
96     article_flag = 'x';
97     }
98 sysadm 1.35 else
99     {
100     article_flag = (is_viewed ? ' ' : 'N');
101     }
102 sysadm 1.3
103 sysadm 1.1 localtime_r(&p_articles[i]->sub_dt, &tm_sub);
104 sysadm 1.3 if (tm_now - p_articles[i]->sub_dt < 3600 * 24 * 365)
105     {
106     strftime(str_time, sizeof(str_time), "%b %e ", &tm_sub);
107     }
108     else
109     {
110     strftime(str_time, sizeof(str_time), "%m/%Y", &tm_sub);
111     }
112    
113 sysadm 1.40 strncpy(title_f, (p_articles[i]->tid == 0 ? "● " : ""), sizeof(title_f) - 1);
114 sysadm 1.1 title_f[sizeof(title_f) - 1] = '\0';
115 sysadm 1.40 strncat(title_f, (p_articles[i]->transship ? "[转载]" : ""), sizeof(title_f) - 1 - strnlen(title_f, sizeof(title_f)));
116 sysadm 1.42
117     // Rewrite title with "Re: Re: " prefix into "Re: ... "
118     j = 0;
119     if (p_articles[i]->tid != 0)
120     {
121     while (strncmp(p_articles[i]->title + j, "Re: ", strlen("Re: ")) == 0)
122     {
123     j += strlen("Re: ");
124     }
125     if (j >= strlen("Re: Re: "))
126     {
127     strncat(title_f, "Re: ... ", sizeof(title_f) - 1 - strnlen(title_f, sizeof(title_f)));
128     }
129     else
130     {
131     j = 0;
132     }
133     }
134     strncat(title_f, p_articles[i]->title + j, sizeof(title_f) - 1 - strnlen(title_f, sizeof(title_f)));
135    
136 sysadm 1.27 len = split_line(title_f, 47 - (display_nickname ? 8 : 0), &eol, &title_f_len, 1);
137 sysadm 1.1 if (title_f[len] != '\0')
138     {
139     title_f[len] = '\0';
140     }
141    
142     moveto(4 + i, 1);
143 sysadm 1.36 if (i >= ontop_start_offset)
144     {
145 sysadm 1.40 prints(" \033[1;33m[提示]\033[m %c %s%*s %s %s%s\033[m",
146 sysadm 1.36 article_flag,
147     (display_nickname ? p_articles[i]->nickname : p_articles[i]->username),
148 sysadm 1.43 (display_nickname ? BBS_nickname_max_len / 2 - str_length(p_articles[i]->nickname, 1)
149     : BBS_username_max_len - str_length(p_articles[i]->username, 1)),
150 sysadm 1.36 "",
151     str_time,
152     (p_articles[i]->aid == section_topic_view_tid
153     ? "\033[1;33m"
154     : (p_articles[i]->tid == section_topic_view_tid
155     ? "\033[1;36m"
156     : "")),
157     title_f);
158     }
159     else
160     {
161     prints(" %s%7d\033[m %c %s%*s %s %s%s\033[m",
162     (p_articles[i]->aid == section_topic_view_tid
163     ? "\033[1;33m"
164     : (p_articles[i]->tid == section_topic_view_tid
165     ? "\033[1;36m"
166     : "")),
167     p_articles[i]->aid,
168     article_flag,
169     (display_nickname ? p_articles[i]->nickname : p_articles[i]->username),
170 sysadm 1.43 (display_nickname ? BBS_nickname_max_len / 2 - str_length(p_articles[i]->nickname, 1)
171     : BBS_username_max_len - str_length(p_articles[i]->username, 1)),
172 sysadm 1.36 "",
173     str_time,
174     (p_articles[i]->aid == section_topic_view_tid
175     ? "\033[1;33m"
176     : (p_articles[i]->tid == section_topic_view_tid
177     ? "\033[1;36m"
178     : "")),
179     title_f);
180     }
181 sysadm 1.1 }
182    
183     return 0;
184     }
185    
186 sysadm 1.5 static int section_list_draw_screen(const char *sname, const char *stitle, const char *master_list, int display_nickname)
187 sysadm 1.1 {
188 sysadm 1.40 char str_section_master[LINE_BUFFER_LEN] = "诚征版主中";
189 sysadm 1.1 char str_section_name[LINE_BUFFER_LEN];
190    
191 sysadm 1.5 if (master_list[0] != '\0')
192 sysadm 1.1 {
193 sysadm 1.40 snprintf(str_section_master, sizeof(str_section_master), "版主:%s", master_list);
194 sysadm 1.1 }
195 sysadm 1.40 snprintf(str_section_name, sizeof(str_section_name), "讨论区 [%s]", sname);
196 sysadm 1.1
197     clearscr();
198 sysadm 1.5 show_top(str_section_master, stitle, str_section_name);
199 sysadm 1.1 moveto(2, 0);
200 sysadm 1.40 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] "
201     "阅读[\033[1;32m→\033[0;37m,\033[1;32mENTER\033[0;37m] 发表[\033[1;32mCtrl-P\033[0;37m] "
202     "%s[\033[1;32mn\033[0;37m] 精华区[\033[1;32mx\033[0;37m] 帮助[\033[1;32mh\033[0;37m]\033[m",
203     (display_nickname ? "用户名" : "昵称"));
204 sysadm 1.1 moveto(3, 0);
205 sysadm 1.4 if (display_nickname)
206     {
207 sysadm 1.40 prints("\033[44;37m \033[1;37m 编 号 发布者昵称 日 期 文章标题 \033[m");
208 sysadm 1.4 }
209     else
210     {
211 sysadm 1.40 prints("\033[44;37m \033[1;37m 编 号 发 布 者 日 期 文章标题 \033[m");
212 sysadm 1.4 }
213 sysadm 1.1
214     return 0;
215     }
216    
217     static enum select_cmd_t section_list_select(int total_page, int item_count, int *p_page_id, int *p_selected_index)
218     {
219     int old_page_id = *p_page_id;
220     int old_selected_index = *p_selected_index;
221     int ch;
222 sysadm 1.30 time_t last_refresh_tm = time(NULL);
223 sysadm 1.1
224     if (item_count > 0 && *p_selected_index >= 0)
225     {
226     moveto(4 + *p_selected_index, 1);
227     outc('>');
228     iflush();
229     }
230    
231     while (!SYS_server_exit)
232     {
233     ch = igetch(100);
234    
235     switch (ch)
236     {
237     case KEY_ESC:
238     case KEY_LEFT:
239 sysadm 1.30 BBS_last_access_tm = time(NULL);
240     case KEY_NULL: // broken pipe
241 sysadm 1.1 return EXIT_SECTION; // exit section
242     case KEY_TIMEOUT:
243 sysadm 1.30 if (time(NULL) - BBS_last_access_tm >= MAX_DELAY_TIME)
244 sysadm 1.1 {
245     return EXIT_SECTION; // exit section
246     }
247     continue;
248 sysadm 1.4 case 'n':
249 sysadm 1.30 BBS_last_access_tm = time(NULL);
250 sysadm 1.4 return CHANGE_NAME_DISPLAY;
251 sysadm 1.1 case CR:
252     igetch_reset();
253 sysadm 1.28 case 'r':
254 sysadm 1.1 case KEY_RIGHT:
255     if (item_count > 0)
256     {
257 sysadm 1.30 BBS_last_access_tm = time(NULL);
258 sysadm 1.1 return VIEW_ARTICLE;
259     }
260     break;
261 sysadm 1.20 case Ctrl('P'):
262     return POST_ARTICLE;
263     case 'E':
264 sysadm 1.41 if (item_count > 0)
265     {
266     return EDIT_ARTICLE;
267     }
268     break;
269 sysadm 1.26 case 'd':
270 sysadm 1.41 if (item_count > 0)
271     {
272     return DELETE_ARTICLE;
273     }
274     break;
275     case Ctrl('Q'):
276     if (item_count > 0)
277     {
278     return QUERY_ARTICLE;
279     }
280     break;
281 sysadm 1.1 case KEY_HOME:
282     *p_page_id = 0;
283 sysadm 1.28 case 'P':
284 sysadm 1.1 case KEY_PGUP:
285     *p_selected_index = 0;
286 sysadm 1.28 case 'k':
287 sysadm 1.1 case KEY_UP:
288     if (*p_selected_index <= 0)
289     {
290     if (*p_page_id > 0)
291     {
292     (*p_page_id)--;
293     *p_selected_index = BBS_article_limit_per_page - 1;
294     }
295 sysadm 1.44 else if (ch == KEY_UP || ch == 'k') // Rotate to the tail of section list
296     {
297     if (total_page > 0)
298     {
299     *p_page_id = total_page - 1;
300     }
301     if (item_count > 0)
302     {
303     *p_selected_index = item_count - 1;
304     }
305     }
306 sysadm 1.1 }
307     else
308     {
309     (*p_selected_index)--;
310     }
311     break;
312 sysadm 1.28 case '$':
313 sysadm 1.1 case KEY_END:
314     if (total_page > 0)
315     {
316     *p_page_id = total_page - 1;
317     }
318 sysadm 1.28 case 'N':
319 sysadm 1.1 case KEY_PGDN:
320     if (item_count > 0)
321     {
322     *p_selected_index = item_count - 1;
323     }
324 sysadm 1.28 case 'j':
325 sysadm 1.1 case KEY_DOWN:
326     if (*p_selected_index + 1 >= item_count) // next page
327     {
328     if (*p_page_id + 1 < total_page)
329     {
330     (*p_page_id)++;
331     *p_selected_index = 0;
332     }
333 sysadm 1.44 else if (ch == KEY_DOWN || ch == 'j') // Rotate to the head of section list
334 sysadm 1.25 {
335 sysadm 1.44 *p_page_id = 0;
336     *p_selected_index = 0;
337 sysadm 1.25 }
338 sysadm 1.1 }
339     else
340     {
341     (*p_selected_index)++;
342     }
343     break;
344 sysadm 1.31 case '=':
345 sysadm 1.41 if (item_count > 0)
346     {
347     return FIRST_TOPIC_ARTICLE;
348     }
349     break;
350 sysadm 1.31 case '\\':
351 sysadm 1.41 if (item_count > 0)
352     {
353     return LAST_TOPIC_ARTICLE;
354     }
355     break;
356 sysadm 1.45 case 'S':
357     if (item_count > 0)
358     {
359     return SCAN_NEW_ARTICLE;
360     }
361     break;
362 sysadm 1.28 case 'h':
363     return SHOW_HELP;
364 sysadm 1.37 case 'x':
365     return VIEW_EX_DIR;
366 sysadm 1.1 default:
367     }
368    
369     if (old_page_id != *p_page_id)
370     {
371     return CHANGE_PAGE;
372     }
373    
374     if (item_count > 0 && old_selected_index != *p_selected_index)
375     {
376     if (old_selected_index >= 0)
377     {
378     moveto(4 + old_selected_index, 1);
379     outc(' ');
380     }
381     if (*p_selected_index >= 0)
382     {
383     moveto(4 + *p_selected_index, 1);
384     outc('>');
385     }
386     iflush();
387    
388     old_selected_index = *p_selected_index;
389     }
390    
391 sysadm 1.30 BBS_last_access_tm = time(NULL);
392     if (BBS_last_access_tm - last_refresh_tm >= BBS_section_list_load_interval)
393     {
394     return CHANGE_PAGE; // force section list refresh
395     }
396 sysadm 1.1 }
397    
398     return EXIT_SECTION;
399     }
400    
401 sysadm 1.11 static int display_article_key_handler(int *p_key, DISPLAY_CTX *p_ctx)
402 sysadm 1.10 {
403 sysadm 1.11 switch (*p_key)
404 sysadm 1.10 {
405 sysadm 1.11 case 'p':
406 sysadm 1.28 case Ctrl('X'):
407 sysadm 1.11 section_topic_view_mode = !section_topic_view_mode;
408 sysadm 1.10 case 0: // Set msg
409 sysadm 1.11 if (section_topic_view_mode)
410 sysadm 1.10 {
411 sysadm 1.11 snprintf(p_ctx->msg, sizeof(p_ctx->msg),
412 sysadm 1.40 "| 返回[\033[32m←\033[33m,\033[32mESC\033[33m] "
413     "同主题阅读[\033[32m↑\033[33m/\033[32m↓\033[33m] "
414     "切换[\033[32mp\033[33m] 回复[\033[32mr\033[33m] 帮助[\033[32mh\033[33m] |");
415 sysadm 1.10 }
416     else
417     {
418 sysadm 1.11 snprintf(p_ctx->msg, sizeof(p_ctx->msg),
419 sysadm 1.40 "| 返回[\033[32m←\033[33m,\033[32mESC\033[33m] "
420     "移动[\033[32m↑\033[33m/\033[32m↓\033[33m/\033[32mPgUp\033[33m/\033[32mPgDn\033[33m] "
421     "切换[\033[32mp\033[33m] 回复[\033[32mr\033[33m] 帮助[\033[32mh\033[33m] |");
422 sysadm 1.10 }
423 sysadm 1.11 *p_key = 0;
424 sysadm 1.10 break;
425 sysadm 1.20 case 'r': // Reply article
426     return 1;
427 sysadm 1.31 case '=': // First topic article
428     return 1;
429     case '\\': // Last topic article
430     return 1;
431 sysadm 1.12 case KEY_UP:
432 sysadm 1.16 case KEY_PGUP:
433     case KEY_HOME:
434 sysadm 1.12 if (p_ctx->reach_begin)
435     {
436     if (section_topic_view_mode)
437     {
438     *p_key = KEY_PGUP;
439     }
440 sysadm 1.16 else
441     {
442     *p_key = KEY_UP;
443     }
444 sysadm 1.12 return 1;
445     }
446     break;
447 sysadm 1.28 case 'k':
448     if (section_topic_view_mode)
449     {
450     *p_key = KEY_PGUP;
451     }
452     else
453     {
454     *p_key = KEY_UP;
455     }
456     return 1;
457 sysadm 1.12 case KEY_DOWN:
458 sysadm 1.16 case KEY_PGDN:
459     case KEY_END:
460 sysadm 1.12 if (p_ctx->reach_end)
461     {
462     if (section_topic_view_mode)
463     {
464     *p_key = KEY_PGDN;
465     }
466 sysadm 1.16 else
467     {
468     *p_key = KEY_DOWN;
469     }
470 sysadm 1.12 return 1;
471     }
472     break;
473 sysadm 1.28 case 'j':
474     if (section_topic_view_mode)
475     {
476     *p_key = KEY_PGDN;
477     }
478     else
479     {
480     *p_key = KEY_DOWN;
481     }
482     return 1;
483 sysadm 1.10 }
484    
485     return 0;
486     }
487    
488 sysadm 1.1 int section_list_display(const char *sname)
489     {
490 sysadm 1.4 static int display_nickname = 0;
491    
492 sysadm 1.1 SECTION_LIST *p_section;
493 sysadm 1.5 char stitle[BBS_section_title_max_len + 1];
494     char master_list[(BBS_username_max_len + 1) * 3 + 1];
495 sysadm 1.6 char page_info_str[LINE_BUFFER_LEN];
496 sysadm 1.1 ARTICLE *p_articles[BBS_article_limit_per_page];
497     int article_count;
498 sysadm 1.6 int page_count;
499 sysadm 1.36 int ontop_start_offset;
500 sysadm 1.1 int page_id = 0;
501     int selected_index = 0;
502 sysadm 1.10 ARTICLE_CACHE cache;
503 sysadm 1.1 int ret;
504 sysadm 1.12 int loop;
505     int direction;
506 sysadm 1.24 ARTICLE article_new;
507 sysadm 1.31 int page_id_cur;
508 sysadm 1.45 const ARTICLE *p_article_unread;
509 sysadm 1.1
510     p_section = section_list_find_by_name(sname);
511     if (p_section == NULL)
512     {
513     log_error("Section %s not found\n", sname);
514     return -1;
515     }
516    
517 sysadm 1.5 if ((ret = section_list_rd_lock(p_section)) < 0)
518     {
519     log_error("section_list_rd_lock(sid = 0) error\n");
520     return -2;
521     }
522    
523     strncpy(stitle, p_section->stitle, sizeof(stitle) - 1);
524     stitle[sizeof(stitle) - 1] = '\0';
525     strncpy(master_list, p_section->master_list, sizeof(master_list) - 1);
526     master_list[sizeof(master_list) - 1] = '\0';
527    
528     if ((ret = section_list_rd_unlock(p_section)) < 0)
529     {
530     log_error("section_list_rd_unlock(sid = 0) error\n");
531     return -2;
532     }
533    
534     if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
535 sysadm 1.1 {
536     log_error("section_list_draw_screen() error\n");
537     return -2;
538     }
539    
540 sysadm 1.36 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
541 sysadm 1.5 if (ret < 0)
542 sysadm 1.1 {
543 sysadm 1.5 log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
544     return -3;
545 sysadm 1.1 }
546 sysadm 1.5
547     if (article_count == 0) // empty section
548 sysadm 1.1 {
549     selected_index = 0;
550     }
551    
552     while (!SYS_server_exit)
553     {
554 sysadm 1.36 ret = section_list_draw_items(page_id, p_articles, article_count, display_nickname, ontop_start_offset);
555 sysadm 1.1 if (ret < 0)
556     {
557     log_error("section_list_draw_items(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
558     return -4;
559     }
560 sysadm 1.6
561 sysadm 1.7 snprintf(page_info_str, sizeof(page_info_str),
562 sysadm 1.40 "\033[33m[第\033[36m%d\033[33m/\033[36m%d\033[33m页]",
563 sysadm 1.7 page_id + 1, MAX(page_count, 1));
564 sysadm 1.8
565 sysadm 1.6 show_bottom(page_info_str);
566 sysadm 1.1 iflush();
567    
568 sysadm 1.33 if (user_online_update(sname) < 0)
569     {
570     log_error("user_online_update(%s) error\n", sname);
571     }
572    
573 sysadm 1.6 ret = section_list_select(page_count, article_count, &page_id, &selected_index);
574 sysadm 1.1 switch (ret)
575     {
576     case EXIT_SECTION:
577     return 0;
578     case CHANGE_PAGE:
579 sysadm 1.36 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
580 sysadm 1.5 if (ret < 0)
581 sysadm 1.1 {
582 sysadm 1.5 log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
583     return -3;
584 sysadm 1.1 }
585 sysadm 1.5 if (article_count == 0) // empty section
586 sysadm 1.1 {
587     selected_index = 0;
588     }
589 sysadm 1.5 else if (selected_index >= article_count)
590 sysadm 1.1 {
591     selected_index = article_count - 1;
592     }
593     break;
594     case VIEW_ARTICLE:
595 sysadm 1.12 do
596 sysadm 1.9 {
597 sysadm 1.12 loop = 0;
598 sysadm 1.9
599 sysadm 1.12 if (article_cache_load(&cache, VAR_ARTICLE_CACHE_DIR, p_articles[selected_index]) < 0)
600     {
601     log_error("article_cache_load(aid=%d, cid=%d) error\n", p_articles[selected_index]->aid, p_articles[selected_index]->cid);
602     break;
603     }
604    
605 sysadm 1.33 if (user_online_update("VIEW_ARTICLE") < 0)
606     {
607     log_error("user_online_update(VIEW_ARTICLE) error\n");
608     }
609    
610 sysadm 1.19 ret = display_data(cache.p_data, cache.line_total, cache.line_offsets, 0,
611 sysadm 1.12 display_article_key_handler, DATA_READ_HELP);
612    
613     if (article_cache_unload(&cache) < 0)
614     {
615     log_error("article_cache_unload(aid=%d, cid=%d) error\n", p_articles[selected_index]->aid, p_articles[selected_index]->cid);
616     break;
617     }
618    
619 sysadm 1.17 // Update article_view_log
620     if (article_view_log_set_viewed(p_articles[selected_index]->aid, &BBS_article_view_log) < 0)
621     {
622     log_error("article_view_log_set_viewed(aid=%d) error\n", p_articles[selected_index]->aid);
623     }
624    
625 sysadm 1.12 switch (ret)
626     {
627     case KEY_UP:
628     if (selected_index <= 0)
629     {
630     if (page_id > 0)
631     {
632     page_id--;
633     selected_index = BBS_article_limit_per_page - 1;
634    
635 sysadm 1.36 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
636 sysadm 1.12 if (ret < 0)
637     {
638     log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
639     return -3;
640     }
641    
642     if (article_count != BBS_article_limit_per_page) // page is not full
643     {
644     selected_index = MAX(0, article_count - 1);
645     }
646     else
647     {
648     loop = 1;
649     }
650     }
651     }
652     else
653     {
654     selected_index--;
655     loop = 1;
656     }
657     break;
658     case KEY_DOWN:
659     if (selected_index + 1 >= article_count) // next page
660     {
661     if (page_id + 1 < page_count)
662     {
663     page_id++;
664     selected_index = 0;
665    
666 sysadm 1.36 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
667 sysadm 1.12 if (ret < 0)
668     {
669     log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
670     return -3;
671     }
672    
673     if (article_count == 0) // empty page
674     {
675     selected_index = 0;
676     }
677     else
678     {
679     loop = 1;
680     }
681     }
682     }
683     else
684     {
685     selected_index++;
686     loop = 1;
687     }
688     break;
689     case KEY_PGUP:
690     case KEY_PGDN:
691     direction = (ret == KEY_PGUP ? -1 : 1);
692 sysadm 1.31 ret = locate_article_in_section(p_section, p_articles[selected_index], direction, 1,
693     &page_id, &selected_index, &article_count);
694 sysadm 1.12 if (ret < 0)
695     {
696 sysadm 1.31 log_error("locate_article_in_section(sid=%d, aid=%d, direction=%d, step=1) error\n",
697 sysadm 1.12 p_section->sid, p_articles[selected_index]->aid, direction);
698     return -3;
699     }
700 sysadm 1.31 else if (ret > 0) // found
701 sysadm 1.12 {
702 sysadm 1.36 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
703 sysadm 1.12 if (ret < 0)
704     {
705     log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
706     return -3;
707     }
708     loop = 1;
709     }
710     break;
711 sysadm 1.20 case 'r': // Reply article
712 sysadm 1.33 if (user_online_update("REPLY_ARTICLE") < 0)
713     {
714     log_error("user_online_update(REPLY_ARTICLE) error\n");
715     }
716    
717 sysadm 1.24 if (article_reply(p_section, p_articles[selected_index], &article_new) < 0)
718 sysadm 1.20 {
719 sysadm 1.33 log_error("article_reply(aid=%d) error\n", p_articles[selected_index]->aid);
720 sysadm 1.20 }
721     loop = 1;
722     break;
723 sysadm 1.31 case '=': // First topic article
724     case '\\': // Last topic article
725     page_id_cur = page_id;
726     direction = (ret == '=' ? -1 : 1);
727     ret = locate_article_in_section(p_section, p_articles[selected_index], direction, BBS_article_limit_per_section,
728     &page_id, &selected_index, &article_count);
729     if (ret < 0)
730     {
731     log_error("locate_article_in_section(sid=%d, aid=%d, direction=%d, step=%d) error\n",
732     p_section->sid, p_articles[selected_index]->aid, direction, BBS_article_limit_per_section);
733     return -3;
734     }
735     else if (ret > 0) // found
736     {
737     if (page_id != page_id_cur) // page changed
738     {
739 sysadm 1.36 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
740 sysadm 1.31 if (ret < 0)
741     {
742     log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
743     return -3;
744     }
745     }
746     loop = 1;
747     }
748     break;
749 sysadm 1.12 }
750     } while (loop);
751 sysadm 1.13
752     // Update current topic
753     section_topic_view_tid = (p_articles[selected_index]->tid == 0 ? p_articles[selected_index]->aid : p_articles[selected_index]->tid);
754 sysadm 1.35
755     if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
756     {
757     log_error("section_list_draw_screen() error\n");
758     return -2;
759     }
760     break;
761 sysadm 1.4 case CHANGE_NAME_DISPLAY:
762     display_nickname = !display_nickname;
763 sysadm 1.5 if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
764 sysadm 1.1 {
765     log_error("section_list_draw_screen() error\n");
766     return -2;
767     }
768     break;
769 sysadm 1.20 case POST_ARTICLE:
770 sysadm 1.33 if (user_online_update("POST_ARTICLE") < 0)
771     {
772     log_error("user_online_update(POST_ARTICLE) error\n");
773     }
774    
775 sysadm 1.30 if ((ret = article_post(p_section, &article_new)) < 0)
776 sysadm 1.20 {
777 sysadm 1.26 log_error("article_post(sid=%d) error\n", p_section->sid);
778 sysadm 1.20 }
779 sysadm 1.24 else if (ret > 0) // New article posted
780     {
781 sysadm 1.36 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
782 sysadm 1.24 if (ret < 0)
783     {
784     log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
785     return -3;
786     }
787     }
788 sysadm 1.20 if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
789     {
790     log_error("section_list_draw_screen() error\n");
791     return -2;
792     }
793     break;
794     case EDIT_ARTICLE:
795 sysadm 1.26 if (!checkpriv(&BBS_priv, p_section->sid, S_POST) ||
796     p_articles[selected_index]->uid != BBS_priv.uid)
797 sysadm 1.20 {
798 sysadm 1.26 break; // No permission
799 sysadm 1.20 }
800 sysadm 1.33
801     if (user_online_update("EDIT_ARTICLE") < 0)
802     {
803     log_error("user_online_update() error\n");
804     }
805    
806 sysadm 1.24 if (article_modify(p_section, p_articles[selected_index], &article_new) < 0)
807 sysadm 1.20 {
808 sysadm 1.26 log_error("article_modify(aid=%d) error\n", p_articles[selected_index]->aid);
809     }
810     if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
811     {
812     log_error("section_list_draw_screen() error\n");
813     return -2;
814     }
815     break;
816     case DELETE_ARTICLE:
817     if (!checkpriv(&BBS_priv, p_section->sid, S_POST) ||
818     (!checkpriv(&BBS_priv, p_section->sid, S_MAN_S) && p_articles[selected_index]->uid != BBS_priv.uid))
819     {
820     break; // No permission
821     }
822 sysadm 1.30 if ((ret = article_del(p_section, p_articles[selected_index])) < 0)
823 sysadm 1.26 {
824     log_error("article_del(aid=%d) error\n", p_articles[selected_index]->aid);
825 sysadm 1.20 }
826 sysadm 1.30 else if (ret > 0) // Article deleted
827     {
828 sysadm 1.36 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
829 sysadm 1.30 if (ret < 0)
830     {
831     log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
832     return -3;
833     }
834     }
835 sysadm 1.20 if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
836     {
837     log_error("section_list_draw_screen() error\n");
838     return -2;
839     }
840     break;
841 sysadm 1.41 case QUERY_ARTICLE:
842     if ((ret = display_article_meta(p_articles[selected_index]->aid)) < 0)
843     {
844     log_error("display_article_meta(aid=%d) error\n", p_articles[selected_index]->aid);
845     }
846     if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
847     {
848     log_error("section_list_draw_screen() error\n");
849     return -2;
850     }
851     break;
852 sysadm 1.31 case FIRST_TOPIC_ARTICLE:
853     case LAST_TOPIC_ARTICLE:
854     page_id_cur = page_id;
855     direction = (ret == FIRST_TOPIC_ARTICLE ? -1 : 1);
856     ret = locate_article_in_section(p_section, p_articles[selected_index], direction, BBS_article_limit_per_section,
857     &page_id, &selected_index, &article_count);
858     if (ret < 0)
859     {
860     log_error("locate_article_in_section(sid=%d, aid=%d, direction=%d, step=%d) error\n",
861     p_section->sid, p_articles[selected_index]->aid, direction, BBS_article_limit_per_section);
862     return -3;
863     }
864     else if (ret > 0 && page_id != page_id_cur) // found and page changed
865     {
866 sysadm 1.36 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
867 sysadm 1.31 if (ret < 0)
868     {
869     log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
870     return -3;
871     }
872     }
873     break;
874 sysadm 1.45 case SCAN_NEW_ARTICLE:
875     ret = scan_unread_article_in_section(p_section, p_articles[selected_index], &p_article_unread);
876     if (ret < 0)
877     {
878     log_error("scan_unread_article_in_section(sid=%d, aid=%d) error\n",
879     p_section->sid, p_articles[selected_index]->aid);
880     return -3;
881     }
882     else if (ret == 0) // not found
883     {
884     break;
885     }
886     page_id_cur = page_id;
887     ret = locate_article_in_section(p_section, p_article_unread, 0, 0,
888     &page_id, &selected_index, &article_count);
889     if (ret < 0)
890     {
891     log_error("locate_article_in_section(sid=%d, aid=%d, direction=0, step=0) error\n",
892     p_section->sid, p_article_unread->aid);
893     return -3;
894     }
895     else if (ret > 0 && page_id != page_id_cur) // found and page changed
896     {
897     ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
898     if (ret < 0)
899     {
900     log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
901     return -3;
902     }
903     }
904     break;
905 sysadm 1.28 case SHOW_HELP:
906     // Display help information
907     display_file(DATA_READ_HELP, 1);
908     if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
909     {
910     log_error("section_list_draw_screen() error\n");
911     return -2;
912     }
913     break;
914 sysadm 1.37 case VIEW_EX_DIR:
915     if (section_list_ex_dir_display(p_section) < 0)
916     {
917     log_error("section_list_ex_dir_display(sid=%d) error\n", p_section->sid);
918     }
919     if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
920     {
921     log_error("section_list_draw_screen() error\n");
922     return -2;
923     }
924     break;
925 sysadm 1.1 default:
926     log_error("Unknown command %d\n", ret);
927     }
928     }
929    
930     return 0;
931     }
932 sysadm 1.37
933     int section_list_ex_dir_display(SECTION_LIST *p_section)
934     {
935     MENU_SET ex_menu_set;
936     int ch = 0;
937    
938     if (p_section == NULL)
939     {
940     log_error("NULL pointer error\n");
941     return -1;
942     }
943    
944 sysadm 1.39 if (p_section->ex_menu_tm == 0) // N/A
945     {
946     moveto(2, 1);
947     clrtoeol();
948 sysadm 1.40 prints("该版块精华区未开放");
949 sysadm 1.39 press_any_key();
950     return 0;
951     }
952    
953 sysadm 1.37 if (get_section_ex_menu_set(p_section, &ex_menu_set) < 0)
954     {
955     log_error("get_section_ex_menu_set(sid=%d) error\n", p_section->sid);
956     return -3;
957     }
958     if (get_menu_shm_readonly(&ex_menu_set) < 0)
959     {
960 sysadm 1.39 log_error("get_menu_shm_readonly(sid=%d) error\n", p_section->sid);
961 sysadm 1.37 return -3;
962     }
963    
964     clearscr();
965 sysadm 1.38 show_bottom("");
966 sysadm 1.37
967     if (display_menu(&ex_menu_set) == 0)
968     {
969     while (!SYS_server_exit)
970     {
971     iflush();
972     ch = igetch(100);
973     switch (ch)
974     {
975     case KEY_NULL: // broken pipe
976     return 0;
977     case KEY_TIMEOUT:
978     if (time(NULL) - BBS_last_access_tm >= MAX_DELAY_TIME)
979     {
980     return 0;
981     }
982     continue;
983     case CR:
984     igetch_reset();
985     default:
986     switch (menu_control(&ex_menu_set, ch))
987     {
988     case EXITMENU:
989     ch = EXITMENU;
990     break;
991     case REDRAW:
992     clearscr();
993 sysadm 1.38 show_bottom("");
994 sysadm 1.37 display_menu(&ex_menu_set);
995     break;
996     case NOREDRAW:
997     case UNKNOWN_CMD:
998     default:
999     break;
1000     }
1001     }
1002    
1003     BBS_last_access_tm = time(NULL);
1004    
1005     if (ch == EXITMENU)
1006     {
1007     break;
1008     }
1009     }
1010     }
1011    
1012     detach_menu_shm(&ex_menu_set);
1013    
1014     return 0;
1015     }

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