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

Diff of /lbbs/src/section_list_display.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

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


Legend:
Removed lines/characters  
Changed lines/characters
  Added lines/characters

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