/[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.1 by sysadm, Wed Oct 15 00:45:21 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;
# Line 94  static int article_favor_draw_items(int Line 94  static int article_favor_draw_items(int
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                  }                  }
# Line 107  static int article_favor_draw_items(int Line 107  static int article_favor_draw_items(int
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          switch (ch)                  if (ch != KEY_NULL && ch != KEY_TIMEOUT)
166          {                  {
167          case KEY_ESC:                          BBS_last_access_tm = time(NULL);
168          case KEY_LEFT:                  }
169              BBS_last_access_tm = time(NULL);  
170          case KEY_NULL:        // broken pipe                  switch (ch)
171              return EXIT_LIST; // exit list                  {
172          case KEY_TIMEOUT:                  case KEY_NULL: // broken pipe
173              if (time(NULL) - BBS_last_access_tm >= MAX_DELAY_TIME)                          log_error("KEY_NULL\n");
174              {                  case KEY_ESC:
175                  return EXIT_LIST; // exit list                  case KEY_LEFT:
176              }                          return EXIT_LIST; // exit list
177              continue;                  case KEY_TIMEOUT:
178          case 'n':                          if (time(NULL) - BBS_last_access_tm >= MAX_DELAY_TIME)
179              BBS_last_access_tm = time(NULL);                          {
180              return SWITCH_NAME;                                  log_error("User input timeout\n");
181          case '-':                                  return EXIT_LIST; // exit list
182              if (item_count > 0)                          }
183              {                          continue;
184                  BBS_last_access_tm = time(NULL);                  case 'n':
185                  return UNSET_FAVOR;                          return SWITCH_NAME;
186              }                  case '-':
187              break;                          if (item_count > 0)
188          case CR:                          {
189              igetch_reset();                                  return UNSET_FAVOR;
190          case KEY_RIGHT:                          }
191              if (item_count > 0)                          break;
192              {                  case CR:
193                  BBS_last_access_tm = time(NULL);                  case KEY_RIGHT:
194                  return LOCATE_ARTICLE;                          if (item_count > 0)
195              }                          {
196              break;                                  return LOCATE_ARTICLE;
197          case KEY_HOME:                          }
198              *p_page_id = 0;                          break;
199          case 'P':                  case KEY_HOME:
200          case KEY_PGUP:                          *p_page_id = 0;
201              *p_selected_index = 0;                  case 'P':
202          case 'k':                  case KEY_PGUP:
203          case KEY_UP:                          *p_selected_index = 0;
204              if (*p_selected_index <= 0)                  case 'k':
205              {                  case KEY_UP:
206                  if (*p_page_id > 0)                          if (*p_selected_index <= 0)
207                  {                          {
208                      (*p_page_id)--;                                  if (*p_page_id > 0)
209                      *p_selected_index = BBS_article_limit_per_page - 1;                                  {
210                  }                                          (*p_page_id)--;
211                  else if (ch == KEY_UP || ch == 'k') // Rotate to the tail of list                                          *p_selected_index = BBS_article_limit_per_page - 1;
212                  {                                  }
213                      if (total_page > 0)                                  else if (ch == KEY_UP || ch == 'k') // Rotate to the tail of list
214                      {                                  {
215                          *p_page_id = total_page - 1;                                          if (total_page > 0)
216                      }                                          {
217                      if (item_count > 0)                                                  *p_page_id = total_page - 1;
218                      {                                          }
219                          *p_selected_index = item_count - 1;                                          if (item_count > 0)
220                      }                                          {
221                  }                                                  *p_selected_index = item_count - 1;
222              }                                          }
223              else                                  }
224              {                          }
225                  (*p_selected_index)--;                          else
226              }                          {
227              break;                                  (*p_selected_index)--;
228          case '$':                          }
229          case KEY_END:                          break;
230              if (total_page > 0)                  case '$':
231              {                  case KEY_END:
232                  *p_page_id = total_page - 1;                          if (total_page > 0)
233              }                          {
234          case 'N':                                  *p_page_id = total_page - 1;
235          case KEY_PGDN:                          }
236              if (item_count > 0)                  case 'N':
237              {                  case KEY_PGDN:
238                  *p_selected_index = item_count - 1;                          if (item_count > 0)
239              }                          {
240          case 'j':                                  *p_selected_index = item_count - 1;
241          case KEY_DOWN:                          }
242              if (*p_selected_index + 1 >= item_count) // next page                  case 'j':
243              {                  case KEY_DOWN:
244                  if (*p_page_id + 1 < total_page)                          if (*p_selected_index + 1 >= item_count) // next page
245                  {                          {
246                      (*p_page_id)++;                                  if (*p_page_id + 1 < total_page)
247                      *p_selected_index = 0;                                  {
248                  }                                          (*p_page_id)++;
249                  else if (ch == KEY_DOWN || ch == 'j') // Rotate to the head of list                                          *p_selected_index = 0;
250                  {                                  }
251                      *p_page_id = 0;                                  else if (ch == KEY_DOWN || ch == 'j') // Rotate to the head of list
252                      *p_selected_index = 0;                                  {
253                  }                                          *p_page_id = 0;
254              }                                          *p_selected_index = 0;
255              else                                  }
256              {                          }
257                  (*p_selected_index)++;                          else
258              }                          {
259              break;                                  (*p_selected_index)++;
260          case 'h':                          }
261              return SHOW_HELP;                          break;
262          default:                  case 'h':
263          }                          return SHOW_HELP;
264                    default:
265          if (old_page_id != *p_page_id)                          break;
266          {                  }
267              return CHANGE_PAGE;  
268          }                  if (old_page_id != *p_page_id)
269                    {
270          if (item_count > 0 && old_selected_index != *p_selected_index)                          return CHANGE_PAGE;
271          {                  }
             if (old_selected_index >= 0)  
             {  
                 moveto(4 + old_selected_index, 1);  
                 outc(' ');  
             }  
             if (*p_selected_index >= 0)  
             {  
                 moveto(4 + *p_selected_index, 1);  
                 outc('>');  
             }  
             iflush();  
272    
273              old_selected_index = *p_selected_index;                  if (item_count > 0 && old_selected_index != *p_selected_index)
274          }                  {
275                            if (old_selected_index >= 0)
276                            {
277                                    moveto(4 + old_selected_index, 1);
278                                    outc(' ');
279                            }
280                            if (*p_selected_index >= 0)
281                            {
282                                    moveto(4 + *p_selected_index, 1);
283                                    outc('>');
284                            }
285                            iflush();
286    
287          BBS_last_access_tm = time(NULL);                          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];
299            char snames[BBS_article_limit_per_page][BBS_section_name_max_len + 1];
300            ARTICLE *p_articles[BBS_article_limit_per_page];
301            int article_count;
302            int page_count;
303            int page_id = 0;
304            int selected_index = 0;
305            int ret;
306    
307            if (p_favor == NULL)
308            {
309                    log_error("NULL pointer error\n");
310                    return -1;
311            }
312    
313            article_favor_draw_screen(display_sname);
314    
315            ret = query_favor_articles(p_favor, page_id, p_articles, snames, &article_count, &page_count);
316            if (ret < 0)
317            {
318                    log_error("query_favor_articles(page_id=%d) error\n", page_id);
319                    return -2;
320            }
321    
322            if (article_count == 0) // empty list
323            {
324                    selected_index = 0;
325            }
326    
327            while (!SYS_server_exit)
328            {
329                    ret = article_favor_draw_items(page_id, p_articles, snames, article_count, display_sname);
330                    if (ret < 0)
331                    {
332                            log_error("article_favor_draw_items(page_id=%d) error\n", page_id);
333                            return -3;
334                    }
335    
336                    snprintf(page_info_str, sizeof(page_info_str),
337                                     "\033[33m[第\033[36m%d\033[33m/\033[36m%d\033[33m页]",
338                                     page_id + 1, MAX(page_count, 1));
339    
340                    show_bottom(page_info_str);
341                    iflush();
342    
343      char page_info_str[LINE_BUFFER_LEN];                  if (user_online_update("ARTICLE_FAVOR") < 0)
344      char snames[BBS_article_limit_per_page][BBS_section_name_max_len + 1];                  {
345      ARTICLE *p_articles[BBS_article_limit_per_page];                          log_error("user_online_update(ARTICLE_FAVOR) error\n");
346      int article_count;                  }
347      int page_count;  
348      int page_id = 0;                  ret = article_favor_select(page_count, article_count, &page_id, &selected_index);
349      int selected_index = 0;                  switch (ret)
350      int ret;                  {
351                    case EXIT_LIST:
352      if (p_favor == NULL)                          return 0;
353      {                  case UNSET_FAVOR:
354          log_error("NULL pointer error\n");                          if (article_favor_set(p_articles[selected_index]->aid, &BBS_article_favor, 0) != 1)
355          return -1;                          {
356      }                                  log_error("article_favor_set(aid=%d, 0) error\n", p_articles[selected_index]->aid);
357                                    break;
358      article_favor_draw_screen(display_sname);                          }
359                            // continue to refresh list
360      ret = query_favor_articles(p_favor, page_id, p_articles, snames, &article_count, &page_count);                  case CHANGE_PAGE:
361      if (ret < 0)                          ret = query_favor_articles(p_favor, page_id, p_articles, snames, &article_count, &page_count);
362      {                          if (ret < 0)
363          log_error("query_favor_articles(page_id=%d) error\n", page_id);                          {
364          return -2;                                  log_error("query_favor_articles(page_id=%d) error\n", page_id);
365      }                                  return -2;
366                            }
367      if (article_count == 0) // empty list  
368      {                          if (article_count == 0) // empty list
369          selected_index = 0;                          {
370      }                                  selected_index = 0;
371                            }
372      while (!SYS_server_exit)                          else if (selected_index >= article_count)
373      {                          {
374          ret = article_favor_draw_items(page_id, p_articles, snames, article_count, display_sname);                                  selected_index = article_count - 1;
375          if (ret < 0)                          }
376          {                          break;
377              log_error("article_favor_draw_items(page_id=%d) error\n", page_id);                  case LOCATE_ARTICLE:
378              return -3;                          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",
381          snprintf(page_info_str, sizeof(page_info_str),                                                    snames[selected_index], p_articles[selected_index]->aid);
382                   "\033[33m[第\033[36m%d\033[33m/\033[36m%d\033[33m页]",                          }
383                   page_id + 1, MAX(page_count, 1));                          break;
384                    case SWITCH_NAME:
385          show_bottom(page_info_str);                          display_sname = !display_sname;
386          iflush();                          article_favor_draw_screen(display_sname);
387                            break;
388          if (user_online_update("ARTICLE_FAVOR") < 0)                  case SHOW_HELP:
389          {                          // Display help information
390              log_error("user_online_update(ARTICLE_FAVOR) error\n");                          display_file(DATA_READ_HELP, 1);
391          }                          article_favor_draw_screen(display_sname);
392                            break;
393          ret = article_favor_select(page_count, article_count, &page_id, &selected_index);                  default:
394          switch (ret)                          log_error("Unknown command %d\n", ret);
395          {                  }
396          case EXIT_LIST:          }
             return 0;  
         case UNSET_FAVOR:  
             if (article_favor_set(p_articles[selected_index]->aid, &BBS_article_favor, 0) != 1)  
             {  
                 log_error("article_favor_set(aid=%d, 0) error\n", p_articles[selected_index]->aid);  
                 break;  
             }  
             // continue to refresh list  
         case CHANGE_PAGE:  
             ret = query_favor_articles(p_favor, page_id, p_articles, snames, &article_count, &page_count);  
             if (ret < 0)  
             {  
                 log_error("query_favor_articles(page_id=%d) error\n", page_id);  
                 return -2;  
             }  
   
             if (article_count == 0) // empty list  
             {  
                 selected_index = 0;  
             }  
             else if (selected_index >= article_count)  
             {  
                 selected_index = article_count - 1;  
             }  
             break;  
         case LOCATE_ARTICLE:  
             if (section_list_display(snames[selected_index], p_articles[selected_index]->aid) < 0)  
             {  
                 log_error("section_list_display(sname=%s, aid=%d) error\n",  
                           snames[selected_index], p_articles[selected_index]->aid);  
             }  
             break;  
         case SWITCH_NAME:  
             display_sname = !display_sname;  
             article_favor_draw_screen(display_sname);  
             break;  
         case SHOW_HELP:  
             // Display help information  
             display_file(DATA_READ_HELP, 1);  
             article_favor_draw_screen(display_sname);  
             break;  
         default:  
             log_error("Unknown command %d\n", ret);  
         }  
     }  
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