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

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