/[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.22 by sysadm, Fri Jun 13 12:17:21 2025 UTC Revision 1.41 by sysadm, Tue Sep 30 04:56:16 2025 UTC
# Line 14  Line 14 
14   *                                                                         *   *                                                                         *
15   ***************************************************************************/   ***************************************************************************/
16    
 #include "section_list_display.h"  
 #include "section_list_loader.h"  
17  #include "article_cache.h"  #include "article_cache.h"
18    #include "article_op.h"
19  #include "article_post.h"  #include "article_post.h"
20    #include "article_view_log.h"
21    #include "article_del.h"
22  #include "common.h"  #include "common.h"
23  #include "io.h"  #include "io.h"
 #include "screen.h"  
24  #include "log.h"  #include "log.h"
25  #include "user_priv.h"  #include "login.h"
26  #include "article_view_log.h"  #include "menu.h"
27    #include "section_list_display.h"
28    #include "section_list_loader.h"
29    #include "screen.h"
30  #include "str_process.h"  #include "str_process.h"
31    #include "user_priv.h"
32    #include <string.h>
33  #include <time.h>  #include <time.h>
34  #include <sys/param.h>  #include <sys/param.h>
 #define _POSIX_C_SOURCE 200809L  
 #include <string.h>  
35    
36  static int section_topic_view_mode = 0;  static int section_topic_view_mode = 0;
37  static int section_topic_view_tid = -1;  static int section_topic_view_tid = -1;
# Line 36  static int section_topic_view_tid = -1; Line 39  static int section_topic_view_tid = -1;
39  enum select_cmd_t  enum select_cmd_t
40  {  {
41          EXIT_SECTION = 0,          EXIT_SECTION = 0,
42          VIEW_ARTICLE = 1,          VIEW_ARTICLE,
43          CHANGE_PAGE = 2,          CHANGE_PAGE,
44          REFRESH_SCREEN = 3,          SHOW_HELP,
45          CHANGE_NAME_DISPLAY = 4,          CHANGE_NAME_DISPLAY,
46          POST_ARTICLE = 5,          POST_ARTICLE,
47          EDIT_ARTICLE = 6,          EDIT_ARTICLE,
48            DELETE_ARTICLE,
49            QUERY_ARTICLE,
50            FIRST_TOPIC_ARTICLE,
51            LAST_TOPIC_ARTICLE,
52            VIEW_EX_DIR,
53  };  };
54    
55  static int section_list_draw_items(int page_id, ARTICLE *p_articles[], int article_count, int display_nickname)  static int section_list_draw_items(int page_id, ARTICLE *p_articles[], int article_count, int display_nickname, int ontop_start_offset)
56  {  {
57          char str_time[LINE_BUFFER_LEN];          char str_time[LINE_BUFFER_LEN];
58          struct tm tm_sub;          struct tm tm_sub;
# Line 77  static int section_list_draw_items(int p Line 85  static int section_list_draw_items(int p
85                          }                          }
86                  }                  }
87    
                 article_flag = (is_viewed ? ' ' : 'N');  
   
88                  if (p_articles[i]->excerption)                  if (p_articles[i]->excerption)
89                  {                  {
90                          article_flag = (is_viewed ? 'm' : 'M');                          article_flag = (is_viewed ? 'm' : 'M');
# Line 87  static int section_list_draw_items(int p Line 93  static int section_list_draw_items(int p
93                  {                  {
94                          article_flag = 'x';                          article_flag = 'x';
95                  }                  }
96                    else
97                    {
98                            article_flag = (is_viewed ? ' ' : 'N');
99                    }
100    
101                  localtime_r(&p_articles[i]->sub_dt, &tm_sub);                  localtime_r(&p_articles[i]->sub_dt, &tm_sub);
102                  if (tm_now - p_articles[i]->sub_dt < 3600 * 24 * 365)                  if (tm_now - p_articles[i]->sub_dt < 3600 * 24 * 365)
# Line 98  static int section_list_draw_items(int p Line 108  static int section_list_draw_items(int p
108                          strftime(str_time, sizeof(str_time), "%m/%Y", &tm_sub);                          strftime(str_time, sizeof(str_time), "%m/%Y", &tm_sub);
109                  }                  }
110    
111                  strncpy(title_f, (p_articles[i]->tid == 0 ? " " : ""), sizeof(title_f) - 1);                  strncpy(title_f, (p_articles[i]->tid == 0 ? "● " : ""), sizeof(title_f) - 1);
112                  title_f[sizeof(title_f) - 1] = '\0';                  title_f[sizeof(title_f) - 1] = '\0';
113                  strncat(title_f, (p_articles[i]->transship ? "[ת]" : ""), sizeof(title_f) - 1 - strnlen(title_f, sizeof(title_f)));                  strncat(title_f, (p_articles[i]->transship ? "[转载]" : ""), sizeof(title_f) - 1 - strnlen(title_f, sizeof(title_f)));
114                  strncat(title_f, p_articles[i]->title, sizeof(title_f) - 1 - strnlen(title_f, sizeof(title_f)));                  strncat(title_f, p_articles[i]->title, sizeof(title_f) - 1 - strnlen(title_f, sizeof(title_f)));
115                  len = split_line(title_f, 47 - (display_nickname ? 8 : 0), &eol, &title_f_len);                  len = split_line(title_f, 47 - (display_nickname ? 8 : 0), &eol, &title_f_len, 1);
116                  if (title_f[len] != '\0')                  if (title_f[len] != '\0')
117                  {                  {
118                          title_f[len] = '\0';                          title_f[len] = '\0';
119                  }                  }
120    
121                  moveto(4 + i, 1);                  moveto(4 + i, 1);
122                  prints("  %s%7d\033[m %c %s%*s %s %s%s\033[m",                  if (i >= ontop_start_offset)
123                             (p_articles[i]->aid == section_topic_view_tid ? "\033[1;33m" : (p_articles[i]->tid == section_topic_view_tid ? "\033[1;36m" : "")),                  {
124                             p_articles[i]->aid,                          prints("   \033[1;33m[提示]\033[m %c %s%*s %s %s%s\033[m",
125                             article_flag,                                     article_flag,
126                             (display_nickname ? p_articles[i]->nickname : p_articles[i]->username),                                     (display_nickname ? p_articles[i]->nickname : p_articles[i]->username),
127                             (display_nickname ? BBS_nickname_max_len - (int)strnlen(p_articles[i]->nickname, sizeof(p_articles[i]->nickname))                                     (display_nickname ? BBS_nickname_max_len - (int)strnlen(p_articles[i]->nickname, sizeof(p_articles[i]->nickname))
128                                                                   : BBS_username_max_len - (int)strnlen(p_articles[i]->username, sizeof(p_articles[i]->username))),                                                                           : BBS_username_max_len - (int)strnlen(p_articles[i]->username, sizeof(p_articles[i]->username))),
129                             "",                                     "",
130                             str_time,                                     str_time,
131                             (p_articles[i]->aid == section_topic_view_tid ? "\033[1;33m" : (p_articles[i]->tid == section_topic_view_tid ? "\033[1;36m" : "")),                                     (p_articles[i]->aid == section_topic_view_tid
132                             title_f);                                                  ? "\033[1;33m"
133                                                    : (p_articles[i]->tid == section_topic_view_tid
134                                                               ? "\033[1;36m"
135                                                               : "")),
136                                       title_f);
137                    }
138                    else
139                    {
140                            prints("  %s%7d\033[m %c %s%*s %s %s%s\033[m",
141                                       (p_articles[i]->aid == section_topic_view_tid
142                                                    ? "\033[1;33m"
143                                                    : (p_articles[i]->tid == section_topic_view_tid
144                                                               ? "\033[1;36m"
145                                                               : "")),
146                                       p_articles[i]->aid,
147                                       article_flag,
148                                       (display_nickname ? p_articles[i]->nickname : p_articles[i]->username),
149                                       (display_nickname ? BBS_nickname_max_len - (int)strnlen(p_articles[i]->nickname, sizeof(p_articles[i]->nickname))
150                                                                             : BBS_username_max_len - (int)strnlen(p_articles[i]->username, sizeof(p_articles[i]->username))),
151                                       "",
152                                       str_time,
153                                       (p_articles[i]->aid == section_topic_view_tid
154                                                    ? "\033[1;33m"
155                                                    : (p_articles[i]->tid == section_topic_view_tid
156                                                               ? "\033[1;36m"
157                                                               : "")),
158                                       title_f);
159                    }
160          }          }
161    
162          return 0;          return 0;
# Line 127  static int section_list_draw_items(int p Line 164  static int section_list_draw_items(int p
164    
165  static int section_list_draw_screen(const char *sname, const char *stitle, const char *master_list, int display_nickname)  static int section_list_draw_screen(const char *sname, const char *stitle, const char *master_list, int display_nickname)
166  {  {
167          char str_section_master[LINE_BUFFER_LEN] = "";          char str_section_master[LINE_BUFFER_LEN] = "诚征版主中";
168          char str_section_name[LINE_BUFFER_LEN];          char str_section_name[LINE_BUFFER_LEN];
169    
170          if (master_list[0] != '\0')          if (master_list[0] != '\0')
171          {          {
172                  snprintf(str_section_master, sizeof(str_section_master), "%s", master_list);                  snprintf(str_section_master, sizeof(str_section_master), "版主:%s", master_list);
173          }          }
174          snprintf(str_section_name, sizeof(str_section_name), " [%s]", sname);          snprintf(str_section_name, sizeof(str_section_name), "讨论区 [%s]", sname);
175    
176          clearscr();          clearscr();
177          show_top(str_section_master, stitle, str_section_name);          show_top(str_section_master, stitle, str_section_name);
178          moveto(2, 0);          moveto(2, 0);
179          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] "          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] "
180                     "Ķ[\033[1;32m\033[0;37m,\033[1;32mENTER\033[0;37m] [\033[1;32mCtrl-P\033[0;37m] %s[\033[1;32mn\033[0;37m]\033[m",                     "阅读[\033[1;32m→\033[0;37m,\033[1;32mENTER\033[0;37m] 发表[\033[1;32mCtrl-P\033[0;37m] "
181                     (display_nickname ? "ʾû" : "ʾdz"));                     "%s[\033[1;32mn\033[0;37m] 精华区[\033[1;32mx\033[0;37m] 帮助[\033[1;32mh\033[0;37m]\033[m",
182                       (display_nickname ? "用户名" : "昵称"));
183          moveto(3, 0);          moveto(3, 0);
184          if (display_nickname)          if (display_nickname)
185          {          {
186                  prints("\033[44;37m  \033[1;37m     dz              ±                               \033[m");                  prints("\033[44;37m  \033[1;37m 编  号   发布者昵称           日  期  文章标题                               \033[m");
187          }          }
188          else          else
189          {          {
190                  prints("\033[44;37m  \033[1;37m            ±                                       \033[m");                  prints("\033[44;37m  \033[1;37m 编  号   发 布 者     日  期  文章标题                                       \033[m");
191          }          }
192    
193          return 0;          return 0;
# Line 160  static enum select_cmd_t section_list_se Line 198  static enum select_cmd_t section_list_se
198          int old_page_id = *p_page_id;          int old_page_id = *p_page_id;
199          int old_selected_index = *p_selected_index;          int old_selected_index = *p_selected_index;
200          int ch;          int ch;
201            time_t last_refresh_tm = time(NULL);
         BBS_last_access_tm = time(0);  
202    
203          if (item_count > 0 && *p_selected_index >= 0)          if (item_count > 0 && *p_selected_index >= 0)
204          {          {
# Line 176  static enum select_cmd_t section_list_se Line 213  static enum select_cmd_t section_list_se
213    
214                  switch (ch)                  switch (ch)
215                  {                  {
                 case KEY_NULL: // broken pipe  
216                  case KEY_ESC:                  case KEY_ESC:
217                  case KEY_LEFT:                  case KEY_LEFT:
218                            BBS_last_access_tm = time(NULL);
219                    case KEY_NULL:                   // broken pipe
220                          return EXIT_SECTION; // exit section                          return EXIT_SECTION; // exit section
221                  case KEY_TIMEOUT:                  case KEY_TIMEOUT:
222                          if (time(0) - BBS_last_access_tm >= MAX_DELAY_TIME)                          if (time(NULL) - BBS_last_access_tm >= MAX_DELAY_TIME)
223                          {                          {
224                                  return EXIT_SECTION; // exit section                                  return EXIT_SECTION; // exit section
225                          }                          }
226                          continue;                          continue;
227                  case 'n':                  case 'n':
228                            BBS_last_access_tm = time(NULL);
229                          return CHANGE_NAME_DISPLAY;                          return CHANGE_NAME_DISPLAY;
230                  case CR:                  case CR:
231                          igetch_reset();                          igetch_reset();
232                    case 'r':
233                  case KEY_RIGHT:                  case KEY_RIGHT:
234                          if (item_count > 0)                          if (item_count > 0)
235                          {                          {
236                                    BBS_last_access_tm = time(NULL);
237                                  return VIEW_ARTICLE;                                  return VIEW_ARTICLE;
238                          }                          }
239                          break;                          break;
240                  case Ctrl('P'):                  case Ctrl('P'):
241                          return POST_ARTICLE;                          return POST_ARTICLE;
242                  case 'E':                  case 'E':
243                          return EDIT_ARTICLE;                          if (item_count > 0)
244                            {
245                                    return EDIT_ARTICLE;
246                            }
247                            break;
248                    case 'd':
249                            if (item_count > 0)
250                            {
251                                    return DELETE_ARTICLE;
252                            }
253                            break;
254                    case Ctrl('Q'):
255                            if (item_count > 0)
256                            {
257                                    return QUERY_ARTICLE;
258                            }
259                            break;
260                  case KEY_HOME:                  case KEY_HOME:
261                          *p_page_id = 0;                          *p_page_id = 0;
262                    case 'P':
263                  case KEY_PGUP:                  case KEY_PGUP:
264                          *p_selected_index = 0;                          *p_selected_index = 0;
265                    case 'k':
266                  case KEY_UP:                  case KEY_UP:
267                          if (*p_selected_index <= 0)                          if (*p_selected_index <= 0)
268                          {                          {
# Line 218  static enum select_cmd_t section_list_se Line 277  static enum select_cmd_t section_list_se
277                                  (*p_selected_index)--;                                  (*p_selected_index)--;
278                          }                          }
279                          break;                          break;
280                    case '$':
281                  case KEY_END:                  case KEY_END:
282                          if (total_page > 0)                          if (total_page > 0)
283                          {                          {
284                                  *p_page_id = total_page - 1;                                  *p_page_id = total_page - 1;
285                          }                          }
286                    case 'N':
287                  case KEY_PGDN:                  case KEY_PGDN:
288                          if (item_count > 0)                          if (item_count > 0)
289                          {                          {
290                                  *p_selected_index = item_count - 1;                                  *p_selected_index = item_count - 1;
291                          }                          }
292                    case 'j':
293                  case KEY_DOWN:                  case KEY_DOWN:
294                          if (*p_selected_index + 1 >= item_count) // next page                          if (*p_selected_index + 1 >= item_count) // next page
295                          {                          {
# Line 236  static enum select_cmd_t section_list_se Line 298  static enum select_cmd_t section_list_se
298                                          (*p_page_id)++;                                          (*p_page_id)++;
299                                          *p_selected_index = 0;                                          *p_selected_index = 0;
300                                  }                                  }
301                                    else // end of last page
302                                    {
303                                            return CHANGE_PAGE; // force refresh pages
304                                    }
305                          }                          }
306                          else                          else
307                          {                          {
308                                  (*p_selected_index)++;                                  (*p_selected_index)++;
309                          }                          }
310                          break;                          break;
311                    case '=':
312                            if (item_count > 0)
313                            {
314                                    return FIRST_TOPIC_ARTICLE;
315                            }
316                            break;
317                    case '\\':
318                            if (item_count > 0)
319                            {
320                                    return LAST_TOPIC_ARTICLE;
321                            }
322                            break;
323                    case 'h':
324                            return SHOW_HELP;
325                    case 'x':
326                            return VIEW_EX_DIR;
327                  default:                  default:
328                  }                  }
329    
# Line 267  static enum select_cmd_t section_list_se Line 349  static enum select_cmd_t section_list_se
349                          old_selected_index = *p_selected_index;                          old_selected_index = *p_selected_index;
350                  }                  }
351    
352                  BBS_last_access_tm = time(0);                  BBS_last_access_tm = time(NULL);
353                    if (BBS_last_access_tm - last_refresh_tm >= BBS_section_list_load_interval)
354                    {
355                            return CHANGE_PAGE; // force section list refresh
356                    }
357          }          }
358    
359          return EXIT_SECTION;          return EXIT_SECTION;
# Line 278  static int display_article_key_handler(i Line 364  static int display_article_key_handler(i
364          switch (*p_key)          switch (*p_key)
365          {          {
366          case 'p':          case 'p':
367            case Ctrl('X'):
368                  section_topic_view_mode = !section_topic_view_mode;                  section_topic_view_mode = !section_topic_view_mode;
369          case 0: // Set msg          case 0: // Set msg
370                  if (section_topic_view_mode)                  if (section_topic_view_mode)
371                  {                  {
372                          snprintf(p_ctx->msg, sizeof(p_ctx->msg),                          snprintf(p_ctx->msg, sizeof(p_ctx->msg),
373                                           "| [\033[32m\033[33m,\033[32mESC\033[33m] | "                                           "| 返回[\033[32m←\033[33m,\033[32mESC\033[33m] "
374                                           "ͬĶ[\033[32m\033[33m/\033[32m\033[33m] | "                                           "同主题阅读[\033[32m↑\033[33m/\033[32m↓\033[33m] "
375                                           "ģʽ[\033[32mp\033[33m] | [\033[32mh\033[33m] |");                                           "切换[\033[32mp\033[33m] 回复[\033[32mr\033[33m] 帮助[\033[32mh\033[33m] |");
376                  }                  }
377                  else                  else
378                  {                  {
379                          snprintf(p_ctx->msg, sizeof(p_ctx->msg),                          snprintf(p_ctx->msg, sizeof(p_ctx->msg),
380                                           "| [\033[32m\033[33m,\033[32mESC\033[33m] | "                                           "| 返回[\033[32m←\033[33m,\033[32mESC\033[33m] "
381                                           "ƶ[\033[32m\033[33m/\033[32m\033[33m/\033[32mPgUp\033[33m/\033[32mPgDn\033[33m] | "                                           "移动[\033[32m↑\033[33m/\033[32m↓\033[33m/\033[32mPgUp\033[33m/\033[32mPgDn\033[33m] "
382                                           "ģʽ[\033[32mp\033[33m] | [\033[32mh\033[33m] |");                                           "切换[\033[32mp\033[33m] 回复[\033[32mr\033[33m] 帮助[\033[32mh\033[33m] |");
383                  }                  }
384                  *p_key = 0;                  *p_key = 0;
385                  break;                  break;
386          case 'r': // Reply article          case 'r': // Reply article
387                  return 1;                  return 1;
388            case '=': // First topic article
389                    return 1;
390            case '\\': // Last topic article
391                    return 1;
392          case KEY_UP:          case KEY_UP:
393          case KEY_PGUP:          case KEY_PGUP:
394          case KEY_HOME:          case KEY_HOME:
# Line 314  static int display_article_key_handler(i Line 405  static int display_article_key_handler(i
405                          return 1;                          return 1;
406                  }                  }
407                  break;                  break;
408            case 'k':
409                    if (section_topic_view_mode)
410                    {
411                            *p_key = KEY_PGUP;
412                    }
413                    else
414                    {
415                            *p_key = KEY_UP;
416                    }
417                    return 1;
418          case KEY_DOWN:          case KEY_DOWN:
419          case KEY_PGDN:          case KEY_PGDN:
420          case KEY_END:          case KEY_END:
# Line 330  static int display_article_key_handler(i Line 431  static int display_article_key_handler(i
431                          return 1;                          return 1;
432                  }                  }
433                  break;                  break;
434            case 'j':
435                    if (section_topic_view_mode)
436                    {
437                            *p_key = KEY_PGDN;
438                    }
439                    else
440                    {
441                            *p_key = KEY_DOWN;
442                    }
443                    return 1;
444          }          }
445    
446          return 0;          return 0;
# Line 346  int section_list_display(const char *sna Line 457  int section_list_display(const char *sna
457          ARTICLE *p_articles[BBS_article_limit_per_page];          ARTICLE *p_articles[BBS_article_limit_per_page];
458          int article_count;          int article_count;
459          int page_count;          int page_count;
460            int ontop_start_offset;
461          int page_id = 0;          int page_id = 0;
462          int selected_index = 0;          int selected_index = 0;
463          ARTICLE_CACHE cache;          ARTICLE_CACHE cache;
464          int ret;          int ret;
465          int loop;          int loop;
466          int direction;          int direction;
467            ARTICLE article_new;
468            int page_id_cur;
469    
470          p_section = section_list_find_by_name(sname);          p_section = section_list_find_by_name(sname);
471          if (p_section == NULL)          if (p_section == NULL)
# Line 383  int section_list_display(const char *sna Line 497  int section_list_display(const char *sna
497                  return -2;                  return -2;
498          }          }
499    
500          ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count);          ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
501          if (ret < 0)          if (ret < 0)
502          {          {
503                  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);
# Line 397  int section_list_display(const char *sna Line 511  int section_list_display(const char *sna
511    
512          while (!SYS_server_exit)          while (!SYS_server_exit)
513          {          {
514                  ret = section_list_draw_items(page_id, p_articles, article_count, display_nickname);                  ret = section_list_draw_items(page_id, p_articles, article_count, display_nickname, ontop_start_offset);
515                  if (ret < 0)                  if (ret < 0)
516                  {                  {
517                          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);
# Line 405  int section_list_display(const char *sna Line 519  int section_list_display(const char *sna
519                  }                  }
520    
521                  snprintf(page_info_str, sizeof(page_info_str),                  snprintf(page_info_str, sizeof(page_info_str),
522                                   "\033[33m[\033[36m%d\033[33m/\033[36m%d\033[33mҳ]",                                   "\033[33m[第\033[36m%d\033[33m/\033[36m%d\033[33m页]",
523                                   page_id + 1, MAX(page_count, 1));                                   page_id + 1, MAX(page_count, 1));
524    
525                  show_bottom(page_info_str);                  show_bottom(page_info_str);
526                  iflush();                  iflush();
527    
528                    if (user_online_update(sname) < 0)
529                    {
530                            log_error("user_online_update(%s) error\n", sname);
531                    }
532    
533                  ret = section_list_select(page_count, article_count, &page_id, &selected_index);                  ret = section_list_select(page_count, article_count, &page_id, &selected_index);
534                  switch (ret)                  switch (ret)
535                  {                  {
536                  case EXIT_SECTION:                  case EXIT_SECTION:
537                          return 0;                          return 0;
538                  case CHANGE_PAGE:                  case CHANGE_PAGE:
539                          ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count);                          ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
540                          if (ret < 0)                          if (ret < 0)
541                          {                          {
542                                  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);
# Line 443  int section_list_display(const char *sna Line 562  int section_list_display(const char *sna
562                                          break;                                          break;
563                                  }                                  }
564    
565                                    if (user_online_update("VIEW_ARTICLE") < 0)
566                                    {
567                                            log_error("user_online_update(VIEW_ARTICLE) error\n");
568                                    }
569    
570                                  ret = display_data(cache.p_data, cache.line_total, cache.line_offsets, 0,                                  ret = display_data(cache.p_data, cache.line_total, cache.line_offsets, 0,
571                                                                     display_article_key_handler, DATA_READ_HELP);                                                                     display_article_key_handler, DATA_READ_HELP);
572    
# Line 468  int section_list_display(const char *sna Line 592  int section_list_display(const char *sna
592                                                          page_id--;                                                          page_id--;
593                                                          selected_index = BBS_article_limit_per_page - 1;                                                          selected_index = BBS_article_limit_per_page - 1;
594    
595                                                          ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count);                                                          ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
596                                                          if (ret < 0)                                                          if (ret < 0)
597                                                          {                                                          {
598                                                                  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);
# Line 499  int section_list_display(const char *sna Line 623  int section_list_display(const char *sna
623                                                          page_id++;                                                          page_id++;
624                                                          selected_index = 0;                                                          selected_index = 0;
625    
626                                                          ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count);                                                          ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
627                                                          if (ret < 0)                                                          if (ret < 0)
628                                                          {                                                          {
629                                                                  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);
# Line 525  int section_list_display(const char *sna Line 649  int section_list_display(const char *sna
649                                  case KEY_PGUP:                                  case KEY_PGUP:
650                                  case KEY_PGDN:                                  case KEY_PGDN:
651                                          direction = (ret == KEY_PGUP ? -1 : 1);                                          direction = (ret == KEY_PGUP ? -1 : 1);
652                                          ret = locate_article_in_section(p_section, p_articles[selected_index], direction, &page_id, &selected_index, &page_count);                                          ret = locate_article_in_section(p_section, p_articles[selected_index], direction, 1,
653                                                                                                            &page_id, &selected_index, &article_count);
654                                          if (ret < 0)                                          if (ret < 0)
655                                          {                                          {
656                                                  log_error("locate_article_in_section(sid=%d, aid=%d, direction=%d) error\n",                                                  log_error("locate_article_in_section(sid=%d, aid=%d, direction=%d, step=1) error\n",
657                                                                    p_section->sid, p_articles[selected_index]->aid, direction);                                                                    p_section->sid, p_articles[selected_index]->aid, direction);
658                                                  return -3;                                                  return -3;
659                                          }                                          }
660                                          else if (ret > 0)                                          else if (ret > 0) // found
661                                          {                                          {
662                                                  ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count);                                                  ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
663                                                  if (ret < 0)                                                  if (ret < 0)
664                                                  {                                                  {
665                                                          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);
# Line 544  int section_list_display(const char *sna Line 669  int section_list_display(const char *sna
669                                          }                                          }
670                                          break;                                          break;
671                                  case 'r': // Reply article                                  case 'r': // Reply article
672                                          if (article_reply(p_section, p_articles[selected_index]) < 0)                                          if (user_online_update("REPLY_ARTICLE") < 0)
673                                            {
674                                                    log_error("user_online_update(REPLY_ARTICLE) error\n");
675                                            }
676    
677                                            if (article_reply(p_section, p_articles[selected_index], &article_new) < 0)
678                                          {                                          {
679                                                  log_error("article_post(aid=%d, REPLY) error\n", p_articles[selected_index]->aid);                                                  log_error("article_reply(aid=%d) error\n", p_articles[selected_index]->aid);
680                                          }                                          }
681                                          loop = 1;                                          loop = 1;
682                                          break;                                          break;
683                                    case '=':  // First topic article
684                                    case '\\': // Last topic article
685                                            page_id_cur = page_id;
686                                            direction = (ret == '=' ? -1 : 1);
687                                            ret = locate_article_in_section(p_section, p_articles[selected_index], direction, BBS_article_limit_per_section,
688                                                                                                            &page_id, &selected_index, &article_count);
689                                            if (ret < 0)
690                                            {
691                                                    log_error("locate_article_in_section(sid=%d, aid=%d, direction=%d, step=%d) error\n",
692                                                                      p_section->sid, p_articles[selected_index]->aid, direction, BBS_article_limit_per_section);
693                                                    return -3;
694                                            }
695                                            else if (ret > 0) // found
696                                            {
697                                                    if (page_id != page_id_cur) // page changed
698                                                    {
699                                                            ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
700                                                            if (ret < 0)
701                                                            {
702                                                                    log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
703                                                                    return -3;
704                                                            }
705                                                    }
706                                                    loop = 1;
707                                            }
708                                            break;
709                                  }                                  }
710                          } while (loop);                          } while (loop);
711    
712                          // Update current topic                          // Update current topic
713                          section_topic_view_tid = (p_articles[selected_index]->tid == 0 ? p_articles[selected_index]->aid : p_articles[selected_index]->tid);                          section_topic_view_tid = (p_articles[selected_index]->tid == 0 ? p_articles[selected_index]->aid : p_articles[selected_index]->tid);
714                  case REFRESH_SCREEN:  
715                          if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)                          if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
716                          {                          {
717                                  log_error("section_list_draw_screen() error\n");                                  log_error("section_list_draw_screen() error\n");
# Line 571  int section_list_display(const char *sna Line 727  int section_list_display(const char *sna
727                          }                          }
728                          break;                          break;
729                  case POST_ARTICLE:                  case POST_ARTICLE:
730                          if (article_post(p_section) < 0)                          if (user_online_update("POST_ARTICLE") < 0)
731                          {                          {
732                                  log_error("article_post(sid=%d, NEW) error\n", p_section->sid);                                  log_error("user_online_update(POST_ARTICLE) error\n");
733                            }
734    
735                            if ((ret = article_post(p_section, &article_new)) < 0)
736                            {
737                                    log_error("article_post(sid=%d) error\n", p_section->sid);
738                            }
739                            else if (ret > 0) // New article posted
740                            {
741                                    ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
742                                    if (ret < 0)
743                                    {
744                                            log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
745                                            return -3;
746                                    }
747                          }                          }
748                          if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)                          if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
749                          {                          {
# Line 582  int section_list_display(const char *sna Line 752  int section_list_display(const char *sna
752                          }                          }
753                          break;                          break;
754                  case EDIT_ARTICLE:                  case EDIT_ARTICLE:
755                          if (p_articles[selected_index]->uid != BBS_priv.uid)                          if (!checkpriv(&BBS_priv, p_section->sid, S_POST) ||
756                                    p_articles[selected_index]->uid != BBS_priv.uid)
757                          {                          {
758                                  break;                                  break; // No permission
759                            }
760    
761                            if (user_online_update("EDIT_ARTICLE") < 0)
762                            {
763                                    log_error("user_online_update() error\n");
764                            }
765    
766                            if (article_modify(p_section, p_articles[selected_index], &article_new) < 0)
767                            {
768                                    log_error("article_modify(aid=%d) error\n", p_articles[selected_index]->aid);
769                            }
770                            if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
771                            {
772                                    log_error("section_list_draw_screen() error\n");
773                                    return -2;
774                          }                          }
775                          if (article_modify(p_section, p_articles[selected_index]) < 0)                          break;
776                    case DELETE_ARTICLE:
777                            if (!checkpriv(&BBS_priv, p_section->sid, S_POST) ||
778                                    (!checkpriv(&BBS_priv, p_section->sid, S_MAN_S) && p_articles[selected_index]->uid != BBS_priv.uid))
779                            {
780                                    break; // No permission
781                            }
782                            if ((ret = article_del(p_section, p_articles[selected_index])) < 0)
783                          {                          {
784                                  log_error("article_post(aid=%d, EDIT) error\n", p_articles[selected_index]->aid);                                  log_error("article_del(aid=%d) error\n", p_articles[selected_index]->aid);
785                            }
786                            else if (ret > 0) // Article deleted
787                            {
788                                    ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
789                                    if (ret < 0)
790                                    {
791                                            log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
792                                            return -3;
793                                    }
794                            }
795                            if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
796                            {
797                                    log_error("section_list_draw_screen() error\n");
798                                    return -2;
799                            }
800                            break;
801                    case QUERY_ARTICLE:
802                            if ((ret = display_article_meta(p_articles[selected_index]->aid)) < 0)
803                            {
804                                    log_error("display_article_meta(aid=%d) error\n", p_articles[selected_index]->aid);
805                            }
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                    case FIRST_TOPIC_ARTICLE:
813                    case LAST_TOPIC_ARTICLE:
814                            page_id_cur = page_id;
815                            direction = (ret == FIRST_TOPIC_ARTICLE ? -1 : 1);
816                            ret = locate_article_in_section(p_section, p_articles[selected_index], direction, BBS_article_limit_per_section,
817                                                                                            &page_id, &selected_index, &article_count);
818                            if (ret < 0)
819                            {
820                                    log_error("locate_article_in_section(sid=%d, aid=%d, direction=%d, step=%d) error\n",
821                                                      p_section->sid, p_articles[selected_index]->aid, direction, BBS_article_limit_per_section);
822                                    return -3;
823                            }
824                            else if (ret > 0 && page_id != page_id_cur) // found and page changed
825                            {
826                                    ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
827                                    if (ret < 0)
828                                    {
829                                            log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
830                                            return -3;
831                                    }
832                            }
833                            break;
834                    case SHOW_HELP:
835                            // Display help information
836                            display_file(DATA_READ_HELP, 1);
837                            if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
838                            {
839                                    log_error("section_list_draw_screen() error\n");
840                                    return -2;
841                            }
842                            break;
843                    case VIEW_EX_DIR:
844                            if (section_list_ex_dir_display(p_section) < 0)
845                            {
846                                    log_error("section_list_ex_dir_display(sid=%d) error\n", p_section->sid);
847                          }                          }
848                          if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)                          if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
849                          {                          {
# Line 603  int section_list_display(const char *sna Line 858  int section_list_display(const char *sna
858    
859          return 0;          return 0;
860  }  }
861    
862    int section_list_ex_dir_display(SECTION_LIST *p_section)
863    {
864            MENU_SET ex_menu_set;
865            int ch = 0;
866    
867            if (p_section == NULL)
868            {
869                    log_error("NULL pointer error\n");
870                    return -1;
871            }
872    
873            if (p_section->ex_menu_tm == 0) // N/A
874            {
875                    moveto(2, 1);
876                    clrtoeol();
877                    prints("该版块精华区未开放");
878                    press_any_key();
879                    return 0;
880            }
881    
882            if (get_section_ex_menu_set(p_section, &ex_menu_set) < 0)
883            {
884                    log_error("get_section_ex_menu_set(sid=%d) error\n", p_section->sid);
885                    return -3;
886            }
887            if (get_menu_shm_readonly(&ex_menu_set) < 0)
888            {
889                    log_error("get_menu_shm_readonly(sid=%d) error\n", p_section->sid);
890                    return -3;
891            }
892    
893            clearscr();
894            show_bottom("");
895    
896            if (display_menu(&ex_menu_set) == 0)
897            {
898                    while (!SYS_server_exit)
899                    {
900                            iflush();
901                            ch = igetch(100);
902                            switch (ch)
903                            {
904                            case KEY_NULL: // broken pipe
905                                    return 0;
906                            case KEY_TIMEOUT:
907                                    if (time(NULL) - BBS_last_access_tm >= MAX_DELAY_TIME)
908                                    {
909                                            return 0;
910                                    }
911                                    continue;
912                            case CR:
913                                    igetch_reset();
914                            default:
915                                    switch (menu_control(&ex_menu_set, ch))
916                                    {
917                                    case EXITMENU:
918                                            ch = EXITMENU;
919                                            break;
920                                    case REDRAW:
921                                            clearscr();
922                                            show_bottom("");
923                                            display_menu(&ex_menu_set);
924                                            break;
925                                    case NOREDRAW:
926                                    case UNKNOWN_CMD:
927                                    default:
928                                            break;
929                                    }
930                            }
931    
932                            BBS_last_access_tm = time(NULL);
933    
934                            if (ch == EXITMENU)
935                            {
936                                    break;
937                            }
938                    }
939            }
940    
941            detach_menu_shm(&ex_menu_set);
942    
943            return 0;
944    }


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

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