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

Diff of /lbbs/src/article_favor_display.c

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

Revision 1.4 by sysadm, Sat Oct 18 12:06:10 2025 UTC Revision 1.5 by sysadm, Sat Oct 18 12:49:13 2025 UTC
# Line 1  Line 1 
1  /***************************************************************************  /***************************************************************************
2                      article_favor_display.c  -  description                                          article_favor_display.c  -  description
3                               -------------------                                                           -------------------
4      Copyright            : (C) 2004-2025 by Leaflet          Copyright            : (C) 2004-2025 by Leaflet
5      Email                : leaflet@leafok.com          Email                : leaflet@leafok.com
6   ***************************************************************************/   ***************************************************************************/
7    
8  /***************************************************************************  /***************************************************************************
# Line 30  Line 30 
30    
31  enum select_cmd_t  enum select_cmd_t
32  {  {
33      EXIT_LIST = 0,          EXIT_LIST = 0,
34      LOCATE_ARTICLE,          LOCATE_ARTICLE,
35      CHANGE_PAGE,          CHANGE_PAGE,
36      SHOW_HELP,          SHOW_HELP,
37      SWITCH_NAME,          SWITCH_NAME,
38      UNSET_FAVOR,          UNSET_FAVOR,
39  };  };
40    
41  static int article_favor_draw_screen(int display_sname)  static int article_favor_draw_screen(int display_sname)
42  {  {
43      clearscr();          clearscr();
44      show_top("[主题收藏]", BBS_name, "");          show_top("[主题收藏]", BBS_name, "");
45      moveto(2, 0);          moveto(2, 0);
46      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] "
47             "定位[\033[1;32m→\033[0;37m,\033[1;32mENTER\033[0;37m] 移除[\033[1;32m-\033[0;37m\033[0;37m] "                     "定位[\033[1;32m→\033[0;37m,\033[1;32mENTER\033[0;37m] 移除[\033[1;32m-\033[0;37m\033[0;37m] "
48             "%s[\033[1;32mn\033[0;37m] 帮助[\033[1;32mh\033[0;37m]\033[m",                     "%s[\033[1;32mn\033[0;37m] 帮助[\033[1;32mh\033[0;37m]\033[m",
49             (display_sname ? "用户名" : "版块名称"));                     (display_sname ? "用户名" : "版块名称"));
50      moveto(3, 0);          moveto(3, 0);
51      if (display_sname)          if (display_sname)
52      {          {
53          prints("\033[44;37m  \033[1;37m 编  号   版块名称             日  期  文章标题                               \033[m");                  prints("\033[44;37m  \033[1;37m 编  号   版块名称             日  期  文章标题                               \033[m");
54      }          }
55      else          else
56      {          {
57          prints("\033[44;37m  \033[1;37m 编  号   发 布 者     日  期  文章标题                                       \033[m");                  prints("\033[44;37m  \033[1;37m 编  号   发 布 者     日  期  文章标题                                       \033[m");
58      }          }
59    
60      return 0;          return 0;
61  }  }
62    
63  static int article_favor_draw_items(int page_id, ARTICLE *p_articles[], char p_snames[][BBS_section_name_max_len + 1],  static int article_favor_draw_items(int page_id, ARTICLE *p_articles[], char p_snames[][BBS_section_name_max_len + 1],
64                                      int article_count, int display_sname)                                                                          int article_count, int display_sname)
65  {  {
66      char str_time[LINE_BUFFER_LEN];          char str_time[LINE_BUFFER_LEN];
67      struct tm tm_sub;          struct tm tm_sub;
68      char title_f[BBS_article_title_max_len + 1];          char title_f[BBS_article_title_max_len + 1];
69      int title_f_len;          int title_f_len;
70      int eol;          int eol;
71      int len;          int len;
72      int i;          int i;
73      char article_flag;          char article_flag;
74      int is_viewed;          int is_viewed;
75      time_t tm_now;          time_t tm_now;
76    
77      time(&tm_now);          time(&tm_now);
78    
79      clrline(4, 23);          clrline(4, 23);
80    
81      for (i = 0; i < article_count; i++)          for (i = 0; i < article_count; i++)
82      {          {
83          if (p_articles[i]->uid == BBS_priv.uid)                  if (p_articles[i]->uid == BBS_priv.uid)
84          {                  {
85              is_viewed = 1;                          is_viewed = 1;
86          }                  }
87          else                  else
88          {                  {
89              is_viewed = article_view_log_is_viewed(p_articles[i]->aid, &BBS_article_view_log);                          is_viewed = article_view_log_is_viewed(p_articles[i]->aid, &BBS_article_view_log);
90              if (is_viewed < 0)                          if (is_viewed < 0)
91              {                          {
92                  log_error("article_view_log_is_viewed(aid=%d) error\n", p_articles[i]->aid);                                  log_error("article_view_log_is_viewed(aid=%d) error\n", p_articles[i]->aid);
93                  is_viewed = 0;                                  is_viewed = 0;
94              }                          }
95          }                  }
96    
97          if (p_articles[i]->excerption)                  if (p_articles[i]->excerption)
98          {                  {
99              article_flag = (is_viewed ? 'm' : 'M');                          article_flag = (is_viewed ? 'm' : 'M');
100          }                  }
101          else if (p_articles[i]->lock && is_viewed)                  else if (p_articles[i]->lock && is_viewed)
102          {                  {
103              article_flag = 'x';                          article_flag = 'x';
104          }                  }
105          else                  else
106          {                  {
107              article_flag = (is_viewed ? ' ' : 'N');                          article_flag = (is_viewed ? ' ' : 'N');
108          }                  }
109    
110          localtime_r(&p_articles[i]->sub_dt, &tm_sub);                  localtime_r(&p_articles[i]->sub_dt, &tm_sub);
111          if (tm_now - p_articles[i]->sub_dt < 3600 * 24 * 365)                  if (tm_now - p_articles[i]->sub_dt < 3600 * 24 * 365)
112          {                  {
113              strftime(str_time, sizeof(str_time), "%b %e ", &tm_sub);                          strftime(str_time, sizeof(str_time), "%b %e ", &tm_sub);
114          }                  }
115          else                  else
116          {                  {
117              strftime(str_time, sizeof(str_time), "%m/%Y", &tm_sub);                          strftime(str_time, sizeof(str_time), "%m/%Y", &tm_sub);
118          }                  }
119    
120          strncpy(title_f, (p_articles[i]->tid == 0 ? "● " : ""), sizeof(title_f) - 1);                  strncpy(title_f, (p_articles[i]->tid == 0 ? "● " : ""), sizeof(title_f) - 1);
121          title_f[sizeof(title_f) - 1] = '\0';                  title_f[sizeof(title_f) - 1] = '\0';
122          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)));
123          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)));
124    
125          len = split_line(title_f, 59 - (display_sname ? BBS_section_name_max_len : BBS_username_max_len), &eol, &title_f_len, 1);                  len = split_line(title_f, 59 - (display_sname ? BBS_section_name_max_len : BBS_username_max_len), &eol, &title_f_len, 1);
126          if (title_f[len] != '\0')                  if (title_f[len] != '\0')
127          {                  {
128              title_f[len] = '\0';                          title_f[len] = '\0';
129          }                  }
130    
131          moveto(4 + i, 1);                  moveto(4 + i, 1);
132    
133          prints("  %7d %c %s%*s %s %s",                  prints("  %7d %c %s%*s %s %s",
134                 p_articles[i]->aid,                             p_articles[i]->aid,
135                 article_flag,                             article_flag,
136                 (display_sname ? p_snames[i] : p_articles[i]->username),                             (display_sname ? p_snames[i] : p_articles[i]->username),
137                 (display_sname                             (display_sname
138                      ? BBS_section_name_max_len - str_length(p_snames[i], 1)                                          ? BBS_section_name_max_len - str_length(p_snames[i], 1)
139                      : BBS_username_max_len - str_length(p_articles[i]->username, 1)),                                          : BBS_username_max_len - str_length(p_articles[i]->username, 1)),
140                 "",                             "",
141                 str_time,                             str_time,
142                 title_f);                             title_f);
143      }          }
144    
145      return 0;          return 0;
146  }  }
147    
148  static enum select_cmd_t article_favor_select(int total_page, int item_count, int *p_page_id, int *p_selected_index)  static enum select_cmd_t article_favor_select(int total_page, int item_count, int *p_page_id, int *p_selected_index)
149  {  {
150      int old_page_id = *p_page_id;          int old_page_id = *p_page_id;
151      int old_selected_index = *p_selected_index;          int old_selected_index = *p_selected_index;
152      int ch;          int ch;
153    
154      if (item_count > 0 && *p_selected_index >= 0)          if (item_count > 0 && *p_selected_index >= 0)
155      {          {
156          moveto(4 + *p_selected_index, 1);                  moveto(4 + *p_selected_index, 1);
157          outc('>');                  outc('>');
158          iflush();                  iflush();
159      }          }
160    
161      while (!SYS_server_exit)          while (!SYS_server_exit)
162      {          {
163          ch = igetch(100);                  ch = igetch(100);
164    
165          if (ch != KEY_NULL && ch != KEY_TIMEOUT)                  if (ch != KEY_NULL && ch != KEY_TIMEOUT)
166          {                  {
167              BBS_last_access_tm = time(NULL);                          BBS_last_access_tm = time(NULL);
168          }                  }
169    
170          switch (ch)                  switch (ch)
171          {                  {
172          case KEY_NULL: // broken pipe                  case KEY_NULL: // broken pipe
173              log_error("KEY_NULL\n");                          log_error("KEY_NULL\n");
174          case KEY_ESC:                  case KEY_ESC:
175          case KEY_LEFT:                  case KEY_LEFT:
176              return EXIT_LIST; // exit list                          return EXIT_LIST; // exit list
177          case KEY_TIMEOUT:                  case KEY_TIMEOUT:
178              if (time(NULL) - BBS_last_access_tm >= MAX_DELAY_TIME)                          if (time(NULL) - BBS_last_access_tm >= MAX_DELAY_TIME)
179              {                          {
180                  log_error("User input timeout\n");                                  log_error("User input timeout\n");
181                  return EXIT_LIST; // exit list                                  return EXIT_LIST; // exit list
182              }                          }
183              continue;                          continue;
184          case 'n':                  case 'n':
185              return SWITCH_NAME;                          return SWITCH_NAME;
186          case '-':                  case '-':
187              if (item_count > 0)                          if (item_count > 0)
188              {                          {
189                  return UNSET_FAVOR;                                  return UNSET_FAVOR;
190              }                          }
191              break;                          break;
192          case CR:                  case CR:
193          case KEY_RIGHT:                  case KEY_RIGHT:
194              if (item_count > 0)                          if (item_count > 0)
195              {                          {
196                  return LOCATE_ARTICLE;                                  return LOCATE_ARTICLE;
197              }                          }
198              break;                          break;
199          case KEY_HOME:                  case KEY_HOME:
200              *p_page_id = 0;                          *p_page_id = 0;
201          case 'P':                  case 'P':
202          case KEY_PGUP:                  case KEY_PGUP:
203              *p_selected_index = 0;                          *p_selected_index = 0;
204          case 'k':                  case 'k':
205          case KEY_UP:                  case KEY_UP:
206              if (*p_selected_index <= 0)                          if (*p_selected_index <= 0)
207              {                          {
208                  if (*p_page_id > 0)                                  if (*p_page_id > 0)
209                  {                                  {
210                      (*p_page_id)--;                                          (*p_page_id)--;
211                      *p_selected_index = BBS_article_limit_per_page - 1;                                          *p_selected_index = BBS_article_limit_per_page - 1;
212                  }                                  }
213                  else if (ch == KEY_UP || ch == 'k') // Rotate to the tail of list                                  else if (ch == KEY_UP || ch == 'k') // Rotate to the tail of list
214                  {                                  {
215                      if (total_page > 0)                                          if (total_page > 0)
216                      {                                          {
217                          *p_page_id = total_page - 1;                                                  *p_page_id = total_page - 1;
218                      }                                          }
219                      if (item_count > 0)                                          if (item_count > 0)
220                      {                                          {
221                          *p_selected_index = item_count - 1;                                                  *p_selected_index = item_count - 1;
222                      }                                          }
223                  }                                  }
224              }                          }
225              else                          else
226              {                          {
227                  (*p_selected_index)--;                                  (*p_selected_index)--;
228              }                          }
229              break;                          break;
230          case '$':                  case '$':
231          case KEY_END:                  case KEY_END:
232              if (total_page > 0)                          if (total_page > 0)
233              {                          {
234                  *p_page_id = total_page - 1;                                  *p_page_id = total_page - 1;
235              }                          }
236          case 'N':                  case 'N':
237          case KEY_PGDN:                  case KEY_PGDN:
238              if (item_count > 0)                          if (item_count > 0)
239              {                          {
240                  *p_selected_index = item_count - 1;                                  *p_selected_index = item_count - 1;
241              }                          }
242          case 'j':                  case 'j':
243          case KEY_DOWN:                  case KEY_DOWN:
244              if (*p_selected_index + 1 >= item_count) // next page                          if (*p_selected_index + 1 >= item_count) // next page
245              {                          {
246                  if (*p_page_id + 1 < total_page)                                  if (*p_page_id + 1 < total_page)
247                  {                                  {
248                      (*p_page_id)++;                                          (*p_page_id)++;
249                      *p_selected_index = 0;                                          *p_selected_index = 0;
250                  }                                  }
251                  else if (ch == KEY_DOWN || ch == 'j') // Rotate to the head of list                                  else if (ch == KEY_DOWN || ch == 'j') // Rotate to the head of list
252                  {                                  {
253                      *p_page_id = 0;                                          *p_page_id = 0;
254                      *p_selected_index = 0;                                          *p_selected_index = 0;
255                  }                                  }
256              }                          }
257              else                          else
258              {                          {
259                  (*p_selected_index)++;                                  (*p_selected_index)++;
260              }                          }
261              break;                          break;
262          case 'h':                  case 'h':
263              return SHOW_HELP;                          return SHOW_HELP;
264          default:                  default:
265              break;                          break;
266          }                  }
267    
268          if (old_page_id != *p_page_id)                  if (old_page_id != *p_page_id)
269          {                  {
270              return CHANGE_PAGE;                          return CHANGE_PAGE;
271          }                  }
272    
273          if (item_count > 0 && old_selected_index != *p_selected_index)                  if (item_count > 0 && old_selected_index != *p_selected_index)
274          {                  {
275              if (old_selected_index >= 0)                          if (old_selected_index >= 0)
276              {                          {
277                  moveto(4 + old_selected_index, 1);                                  moveto(4 + old_selected_index, 1);
278                  outc(' ');                                  outc(' ');
279              }                          }
280              if (*p_selected_index >= 0)                          if (*p_selected_index >= 0)
281              {                          {
282                  moveto(4 + *p_selected_index, 1);                                  moveto(4 + *p_selected_index, 1);
283                  outc('>');                                  outc('>');
284              }                          }
285              iflush();                          iflush();
286    
287              old_selected_index = *p_selected_index;                          old_selected_index = *p_selected_index;
288          }                  }
289      }          }
290    
291      return EXIT_LIST;          return EXIT_LIST;
292  }  }
293    
294  int article_favor_display(ARTICLE_FAVOR *p_favor)  int article_favor_display(ARTICLE_FAVOR *p_favor)
295  {  {
296      static int display_sname = 0;          static int display_sname = 0;
297    
298      char page_info_str[LINE_BUFFER_LEN];          char page_info_str[LINE_BUFFER_LEN];
299      char snames[BBS_article_limit_per_page][BBS_section_name_max_len + 1];          char snames[BBS_article_limit_per_page][BBS_section_name_max_len + 1];
300      ARTICLE *p_articles[BBS_article_limit_per_page];          ARTICLE *p_articles[BBS_article_limit_per_page];
301      int article_count;          int article_count;
302      int page_count;          int page_count;
303      int page_id = 0;          int page_id = 0;
304      int selected_index = 0;          int selected_index = 0;
305      int ret;          int ret;
306    
307      if (p_favor == NULL)          if (p_favor == NULL)
308      {          {
309          log_error("NULL pointer error\n");                  log_error("NULL pointer error\n");
310          return -1;                  return -1;
311      }          }
312    
313      article_favor_draw_screen(display_sname);          article_favor_draw_screen(display_sname);
314    
315      ret = query_favor_articles(p_favor, page_id, p_articles, snames, &article_count, &page_count);          ret = query_favor_articles(p_favor, page_id, p_articles, snames, &article_count, &page_count);
316      if (ret < 0)          if (ret < 0)
317      {          {
318          log_error("query_favor_articles(page_id=%d) error\n", page_id);                  log_error("query_favor_articles(page_id=%d) error\n", page_id);
319          return -2;                  return -2;
320      }          }
321    
322      if (article_count == 0) // empty list          if (article_count == 0) // empty list
323      {          {
324          selected_index = 0;                  selected_index = 0;
325      }          }
326    
327      while (!SYS_server_exit)          while (!SYS_server_exit)
328      {          {
329          ret = article_favor_draw_items(page_id, p_articles, snames, article_count, display_sname);                  ret = article_favor_draw_items(page_id, p_articles, snames, article_count, display_sname);
330          if (ret < 0)                  if (ret < 0)
331          {                  {
332              log_error("article_favor_draw_items(page_id=%d) error\n", page_id);                          log_error("article_favor_draw_items(page_id=%d) error\n", page_id);
333              return -3;                          return -3;
334          }                  }
335    
336          snprintf(page_info_str, sizeof(page_info_str),                  snprintf(page_info_str, sizeof(page_info_str),
337                   "\033[33m[第\033[36m%d\033[33m/\033[36m%d\033[33m页]",                                   "\033[33m[第\033[36m%d\033[33m/\033[36m%d\033[33m页]",
338                   page_id + 1, MAX(page_count, 1));                                   page_id + 1, MAX(page_count, 1));
339    
340          show_bottom(page_info_str);                  show_bottom(page_info_str);
341          iflush();                  iflush();
342    
343          if (user_online_update("ARTICLE_FAVOR") < 0)                  if (user_online_update("ARTICLE_FAVOR") < 0)
344          {                  {
345              log_error("user_online_update(ARTICLE_FAVOR) error\n");                          log_error("user_online_update(ARTICLE_FAVOR) error\n");
346          }                  }
347    
348          ret = article_favor_select(page_count, article_count, &page_id, &selected_index);                  ret = article_favor_select(page_count, article_count, &page_id, &selected_index);
349          switch (ret)                  switch (ret)
350          {                  {
351          case EXIT_LIST:                  case EXIT_LIST:
352              return 0;                          return 0;
353          case UNSET_FAVOR:                  case UNSET_FAVOR:
354              if (article_favor_set(p_articles[selected_index]->aid, &BBS_article_favor, 0) != 1)                          if (article_favor_set(p_articles[selected_index]->aid, &BBS_article_favor, 0) != 1)
355              {                          {
356                  log_error("article_favor_set(aid=%d, 0) error\n", p_articles[selected_index]->aid);                                  log_error("article_favor_set(aid=%d, 0) error\n", p_articles[selected_index]->aid);
357                  break;                                  break;
358              }                          }
359              // continue to refresh list                          // continue to refresh list
360          case CHANGE_PAGE:                  case CHANGE_PAGE:
361              ret = query_favor_articles(p_favor, page_id, p_articles, snames, &article_count, &page_count);                          ret = query_favor_articles(p_favor, page_id, p_articles, snames, &article_count, &page_count);
362              if (ret < 0)                          if (ret < 0)
363              {                          {
364                  log_error("query_favor_articles(page_id=%d) error\n", page_id);                                  log_error("query_favor_articles(page_id=%d) error\n", page_id);
365                  return -2;                                  return -2;
366              }                          }
367    
368              if (article_count == 0) // empty list                          if (article_count == 0) // empty list
369              {                          {
370                  selected_index = 0;                                  selected_index = 0;
371              }                          }
372              else if (selected_index >= article_count)                          else if (selected_index >= article_count)
373              {                          {
374                  selected_index = article_count - 1;                                  selected_index = article_count - 1;
375              }                          }
376              break;                          break;
377          case LOCATE_ARTICLE:                  case LOCATE_ARTICLE:
378              if (section_list_display(snames[selected_index], p_articles[selected_index]->aid) < 0)                          if (section_list_display(snames[selected_index], p_articles[selected_index]->aid) < 0)
379              {                          {
380                  log_error("section_list_display(sname=%s, aid=%d) error\n",                                  log_error("section_list_display(sname=%s, aid=%d) error\n",
381                            snames[selected_index], p_articles[selected_index]->aid);                                                    snames[selected_index], p_articles[selected_index]->aid);
382              }                          }
383              break;                          break;
384          case SWITCH_NAME:                  case SWITCH_NAME:
385              display_sname = !display_sname;                          display_sname = !display_sname;
386              article_favor_draw_screen(display_sname);                          article_favor_draw_screen(display_sname);
387              break;                          break;
388          case SHOW_HELP:                  case SHOW_HELP:
389              // Display help information                          // Display help information
390              display_file(DATA_READ_HELP, 1);                          display_file(DATA_READ_HELP, 1);
391              article_favor_draw_screen(display_sname);                          article_favor_draw_screen(display_sname);
392              break;                          break;
393          default:                  default:
394              log_error("Unknown command %d\n", ret);                          log_error("Unknown command %d\n", ret);
395          }                  }
396      }          }
397    
398      return 0;          return 0;
399  }  }


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

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