render.c (3579B)
#include "termbox2.h"
#include "tui.h"
#include "config.h"
#include "utils.h"
#define HORIZ_LINE 0x2500
#define VERT_LINE 0x2502
static void
draw_bars(void)
{
int i;
const int width = tb_width();
const int height = tb_height();
// verticals first
for (i = 2; i < height - 2; i++) {
tb_set_cell(0, i, VERT_LINE, LINE_COLOR, BACK_COLOR);
tb_set_cell(FEED_CAP + 2, i, VERT_LINE, LINE_COLOR, BACK_COLOR); /* separator line */
tb_set_cell(width - 1, i, VERT_LINE, LINE_COLOR, BACK_COLOR);
}
for (i = 0; i < width; i++) {
tb_set_cell(i, 1, HORIZ_LINE, LINE_COLOR, BACK_COLOR);
tb_set_cell(i, height - 2, HORIZ_LINE, LINE_COLOR, BACK_COLOR);
}
tb_print(1, 0, LOGO_COLOR, BACK_COLOR, "readr");
tb_print(width - 6, 0, TEXT_COLOR, BACK_COLOR, VERSION);
tb_print(width - 66,
height - 1,
TEXT_COLOR,
BACK_COLOR,
"[arrows] move [enter] open link [space] open comments [q] quit");
// corners top
tb_set_cell(0, 1, 0x250C, LINE_COLOR, BACK_COLOR);
tb_set_cell(FEED_CAP + 2, 1, 0x252C, LINE_COLOR, BACK_COLOR);
tb_set_cell(width - 1, 1, 0x2510, LINE_COLOR, BACK_COLOR);
// corners bottom
tb_set_cell(0, height - 2, 0x2514, LINE_COLOR, BACK_COLOR);
tb_set_cell(FEED_CAP + 2, height - 2, 0x2534, LINE_COLOR, BACK_COLOR);
tb_set_cell(width - 1, height - 2, 0x2518, LINE_COLOR, BACK_COLOR);
}
static void
draw_background(void)
{
tb_set_clear_attrs(TEXT_COLOR, BACK_COLOR);
tb_clear();
}
void
render(app_t* app)
{
size_t i;
uintattr_t color;
char title[TITLE_CAP] = { 0 };
char domain[DOMAIN_CAP] = { 0 };
db_post_t* post;
feed_t* feed;
feed_t* selected_feed = app->feeds[app->selected_feed];
int buffer_height = tb_height() - 3 - 3;
int width = tb_width();
draw_background();
draw_bars();
for (i = 0; i < app->feeds_len; i++) {
feed = app->feeds[i];
if (app->selected_panel == 0 && i == app->selected_feed)
color = (FEED_COLOR | TB_REVERSE | TB_BRIGHT | TB_BOLD);
else if (i == app->selected_feed)
color = (FEED_COLOR | TB_BOLD);
else
color = (FEED_COLOR | TB_DIM);
tb_print(2, 3 + (int)i, color, BACK_COLOR, feed->title ? feed->title : "N/A");
}
// posts
int visible_len = MIN(buffer_height, selected_feed->posts_len);
char title_suffix[10];
for (int j = 0; j < visible_len; j++) {
post = selected_feed->posts[j];
const char* title_src = post->title ? post->title : "(bad title)";
const char* url_filetype = filetype_from_url(post->link);
if (url_filetype) {
snprintf(title_suffix, 10, "[%s]", url_filetype);
// don't add [video] if the title already ends with [video] etc.
if (!contains(title_src, title_suffix)) {
snprintf(title, TITLE_CAP, "%s %s", title_src, title_suffix);
} else {
snprintf(title, TITLE_CAP, "%s", title_src);
}
} else {
snprintf(title, TITLE_CAP, "%s", title_src);
}
// domain
const char* domain_host = host_from_url(post->link);
snprintf(domain, DOMAIN_CAP, "%s", domain_host ? domain_host : "(bad domain)");
int domain_len = (int)strlen(domain);
// chop title to fit within its column and not overlap the domain
snprintf(title, width - domain_len - FEED_CAP - 6, "%s", title);
if (app->selected_panel == 1 && j == app->selected_post)
if (post->seen)
color = (POST_COLOR | TB_REVERSE | TB_DIM);
else
color = (POST_COLOR | TB_REVERSE | TB_BRIGHT | TB_BOLD);
else if (post->seen)
color = (SEEN_COLOR);
else
color = (POST_COLOR);
tb_print(width - domain_len - 2, 3 + (int)j, DOMAIN_COLOR, BACK_COLOR, domain);
tb_print(FEED_CAP + 4, 3 + (int)j, color, BACK_COLOR, title);
}
tb_present();
}