/[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.5 - (hide annotations)
Sat Oct 18 12:49:13 2025 UTC (4 months, 4 weeks ago) by sysadm
Branch: MAIN
Changes since 1.4: +349 -349 lines
Content type: text/x-csrc
Convert space to tab

1 sysadm 1.1 /***************************************************************************
2 sysadm 1.5 article_favor_display.c - description
3     -------------------
4     Copyright : (C) 2004-2025 by Leaflet
5     Email : leaflet@leafok.com
6 sysadm 1.1 ***************************************************************************/
7    
8     /***************************************************************************
9     * *
10     * This program is free software; you can redistribute it and/or modify *
11     * it under the terms of the GNU General Public License as published by *
12     * the Free Software Foundation; either version 3 of the License, or *
13     * (at your option) any later version. *
14     * *
15     ***************************************************************************/
16    
17     #include "article_favor_display.h"
18     #include "article_view_log.h"
19     #include "io.h"
20     #include "log.h"
21     #include "login.h"
22     #include "screen.h"
23     #include "str_process.h"
24     #include "section_list.h"
25     #include "section_list_display.h"
26     #include "user_priv.h"
27     #include <string.h>
28     #include <time.h>
29     #include <sys/param.h>
30    
31     enum select_cmd_t
32     {
33 sysadm 1.5 EXIT_LIST = 0,
34     LOCATE_ARTICLE,
35     CHANGE_PAGE,
36     SHOW_HELP,
37     SWITCH_NAME,
38     UNSET_FAVOR,
39 sysadm 1.1 };
40    
41     static int article_favor_draw_screen(int display_sname)
42     {
43 sysadm 1.5 clearscr();
44     show_top("[主题收藏]", BBS_name, "");
45     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] "
47     "定位[\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",
49     (display_sname ? "用户名" : "版块名称"));
50     moveto(3, 0);
51     if (display_sname)
52     {
53     prints("\033[44;37m \033[1;37m 编 号 版块名称 日 期 文章标题 \033[m");
54     }
55     else
56     {
57     prints("\033[44;37m \033[1;37m 编 号 发 布 者 日 期 文章标题 \033[m");
58     }
59 sysadm 1.1
60 sysadm 1.5 return 0;
61 sysadm 1.1 }
62    
63     static int article_favor_draw_items(int page_id, ARTICLE *p_articles[], char p_snames[][BBS_section_name_max_len + 1],
64 sysadm 1.5 int article_count, int display_sname)
65 sysadm 1.1 {
66 sysadm 1.5 char str_time[LINE_BUFFER_LEN];
67     struct tm tm_sub;
68     char title_f[BBS_article_title_max_len + 1];
69     int title_f_len;
70     int eol;
71     int len;
72     int i;
73     char article_flag;
74     int is_viewed;
75     time_t tm_now;
76    
77     time(&tm_now);
78    
79     clrline(4, 23);
80    
81     for (i = 0; i < article_count; i++)
82     {
83     if (p_articles[i]->uid == BBS_priv.uid)
84     {
85     is_viewed = 1;
86     }
87     else
88     {
89     is_viewed = article_view_log_is_viewed(p_articles[i]->aid, &BBS_article_view_log);
90     if (is_viewed < 0)
91     {
92     log_error("article_view_log_is_viewed(aid=%d) error\n", p_articles[i]->aid);
93     is_viewed = 0;
94     }
95     }
96    
97     if (p_articles[i]->excerption)
98     {
99     article_flag = (is_viewed ? 'm' : 'M');
100     }
101     else if (p_articles[i]->lock && is_viewed)
102     {
103     article_flag = 'x';
104     }
105     else
106     {
107     article_flag = (is_viewed ? ' ' : 'N');
108     }
109    
110     localtime_r(&p_articles[i]->sub_dt, &tm_sub);
111     if (tm_now - p_articles[i]->sub_dt < 3600 * 24 * 365)
112     {
113     strftime(str_time, sizeof(str_time), "%b %e ", &tm_sub);
114     }
115     else
116     {
117     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);
121     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)));
123     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);
126     if (title_f[len] != '\0')
127     {
128     title_f[len] = '\0';
129     }
130    
131     moveto(4 + i, 1);
132    
133     prints(" %7d %c %s%*s %s %s",
134     p_articles[i]->aid,
135     article_flag,
136     (display_sname ? p_snames[i] : p_articles[i]->username),
137     (display_sname
138     ? BBS_section_name_max_len - str_length(p_snames[i], 1)
139     : BBS_username_max_len - str_length(p_articles[i]->username, 1)),
140     "",
141     str_time,
142     title_f);
143     }
144 sysadm 1.1
145 sysadm 1.5 return 0;
146 sysadm 1.1 }
147    
148     static enum select_cmd_t article_favor_select(int total_page, int item_count, int *p_page_id, int *p_selected_index)
149     {
150 sysadm 1.5 int old_page_id = *p_page_id;
151     int old_selected_index = *p_selected_index;
152     int ch;
153    
154     if (item_count > 0 && *p_selected_index >= 0)
155     {
156     moveto(4 + *p_selected_index, 1);
157     outc('>');
158     iflush();
159     }
160    
161     while (!SYS_server_exit)
162     {
163     ch = igetch(100);
164    
165     if (ch != KEY_NULL && ch != KEY_TIMEOUT)
166     {
167     BBS_last_access_tm = time(NULL);
168     }
169    
170     switch (ch)
171     {
172     case KEY_NULL: // broken pipe
173     log_error("KEY_NULL\n");
174     case KEY_ESC:
175     case KEY_LEFT:
176     return EXIT_LIST; // exit list
177     case KEY_TIMEOUT:
178     if (time(NULL) - BBS_last_access_tm >= MAX_DELAY_TIME)
179     {
180     log_error("User input timeout\n");
181     return EXIT_LIST; // exit list
182     }
183     continue;
184     case 'n':
185     return SWITCH_NAME;
186     case '-':
187     if (item_count > 0)
188     {
189     return UNSET_FAVOR;
190     }
191     break;
192     case CR:
193     case KEY_RIGHT:
194     if (item_count > 0)
195     {
196     return LOCATE_ARTICLE;
197     }
198     break;
199     case KEY_HOME:
200     *p_page_id = 0;
201     case 'P':
202     case KEY_PGUP:
203     *p_selected_index = 0;
204     case 'k':
205     case KEY_UP:
206     if (*p_selected_index <= 0)
207     {
208     if (*p_page_id > 0)
209     {
210     (*p_page_id)--;
211     *p_selected_index = BBS_article_limit_per_page - 1;
212     }
213     else if (ch == KEY_UP || ch == 'k') // Rotate to the tail of list
214     {
215     if (total_page > 0)
216     {
217     *p_page_id = total_page - 1;
218     }
219     if (item_count > 0)
220     {
221     *p_selected_index = item_count - 1;
222     }
223     }
224     }
225     else
226     {
227     (*p_selected_index)--;
228     }
229     break;
230     case '$':
231     case KEY_END:
232     if (total_page > 0)
233     {
234     *p_page_id = total_page - 1;
235     }
236     case 'N':
237     case KEY_PGDN:
238     if (item_count > 0)
239     {
240     *p_selected_index = item_count - 1;
241     }
242     case 'j':
243     case KEY_DOWN:
244     if (*p_selected_index + 1 >= item_count) // next page
245     {
246     if (*p_page_id + 1 < total_page)
247     {
248     (*p_page_id)++;
249     *p_selected_index = 0;
250     }
251     else if (ch == KEY_DOWN || ch == 'j') // Rotate to the head of list
252     {
253     *p_page_id = 0;
254     *p_selected_index = 0;
255     }
256     }
257     else
258     {
259     (*p_selected_index)++;
260     }
261     break;
262     case 'h':
263     return SHOW_HELP;
264     default:
265     break;
266     }
267    
268     if (old_page_id != *p_page_id)
269     {
270     return CHANGE_PAGE;
271     }
272    
273     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     old_selected_index = *p_selected_index;
288     }
289     }
290 sysadm 1.1
291 sysadm 1.5 return EXIT_LIST;
292 sysadm 1.1 }
293    
294     int article_favor_display(ARTICLE_FAVOR *p_favor)
295     {
296 sysadm 1.5 static int display_sname = 0;
297 sysadm 1.1
298 sysadm 1.5 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     if (user_online_update("ARTICLE_FAVOR") < 0)
344     {
345     log_error("user_online_update(ARTICLE_FAVOR) error\n");
346     }
347    
348     ret = article_favor_select(page_count, article_count, &page_id, &selected_index);
349     switch (ret)
350     {
351     case EXIT_LIST:
352     return 0;
353     case UNSET_FAVOR:
354     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);
357     break;
358     }
359     // continue to refresh list
360     case CHANGE_PAGE:
361     ret = query_favor_articles(p_favor, page_id, p_articles, snames, &article_count, &page_count);
362     if (ret < 0)
363     {
364     log_error("query_favor_articles(page_id=%d) error\n", page_id);
365     return -2;
366     }
367    
368     if (article_count == 0) // empty list
369     {
370     selected_index = 0;
371     }
372     else if (selected_index >= article_count)
373     {
374     selected_index = article_count - 1;
375     }
376     break;
377     case LOCATE_ARTICLE:
378     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     snames[selected_index], p_articles[selected_index]->aid);
382     }
383     break;
384     case SWITCH_NAME:
385     display_sname = !display_sname;
386     article_favor_draw_screen(display_sname);
387     break;
388     case SHOW_HELP:
389     // Display help information
390     display_file(DATA_READ_HELP, 1);
391     article_favor_draw_screen(display_sname);
392     break;
393     default:
394     log_error("Unknown command %d\n", ret);
395     }
396     }
397 sysadm 1.1
398 sysadm 1.5 return 0;
399 sysadm 1.1 }

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