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

Annotation of /lbbs/src/article_favor_display.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.6 - (hide annotations)
Tue Nov 4 13:49:50 2025 UTC (4 months, 1 week ago) by sysadm
Branch: MAIN
Changes since 1.5: +7 -15 lines
Content type: text/x-csrc
Update file header information comments

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

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