/[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.51 - (hide annotations)
Tue Oct 14 04:01:40 2025 UTC (5 months ago) by sysadm
Branch: MAIN
Changes since 1.50: +2 -2 lines
Content type: text/x-csrc
Refine

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

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