summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.c94
1 files changed, 61 insertions, 33 deletions
diff --git a/main.c b/main.c
index 69eda35..cc00c83 100644
--- a/main.c
+++ b/main.c
@@ -46,6 +46,8 @@
#define GFX_TEXT_MARGIN_X 1
#define GFX_TEXT_MARGIN_Y 0
#define GFX_POST_SPACING 1
+#define GFX_PRONOUNS_MARGIN 1
+#define GFX_PRONOUNS_FMT "<%S>"
#define PFP_LINES 3
#define PFP_COLS 7
@@ -55,16 +57,17 @@
#define CPAIR_INIT_X(cp, fg, bg) init_pair(cp, fg, bg);
#define CPAIR_ENUM_X(cp, fg, bg) cp,
#define CPAIR_LIST(X)\
- X(CPAIR_TEXT , COLOR_WHITE , COLOR_BLACK)\
- X(CPAIR_MENTION , COLOR_BLACK , COLOR_WHITE)\
- X(CPAIR_USER , COLOR_YELLOW , COLOR_BLACK)\
- X(CPAIR_TIME , COLOR_BLUE , COLOR_BLACK)\
- X(CPAIR_PFP , COLOR_BLUE , COLOR_BLACK)\
- X(CPAIR_PFP_SELF , COLOR_YELLOW , COLOR_BLACK)\
- X(CPAIR_BORDER , COLOR_BLUE , COLOR_BLACK)\
- X(CPAIR_TAGLINE_OK , COLOR_GREEN , COLOR_BLACK)\
- X(CPAIR_TAGLINE_WARN , COLOR_YELLOW , COLOR_BLACK)\
- X(CPAIR_TAGLINE_ERR , COLOR_RED , COLOR_BLACK)
+ X(CPAIR_TEXT , COLOR_WHITE , COLOR_BLACK)\
+ X(CPAIR_MENTION , COLOR_BLACK , COLOR_WHITE)\
+ X(CPAIR_USER , COLOR_YELLOW , COLOR_BLACK)\
+ X(CPAIR_PRONOUNS , COLOR_CYAN , COLOR_BLACK)\
+ X(CPAIR_TIME , COLOR_BLUE , COLOR_BLACK)\
+ X(CPAIR_PFP , COLOR_BLUE , COLOR_BLACK)\
+ X(CPAIR_PFP_SELF , COLOR_YELLOW , COLOR_BLACK)\
+ X(CPAIR_BORDER , COLOR_BLUE , COLOR_BLACK)\
+ X(CPAIR_TAGLINE_OK , COLOR_GREEN , COLOR_BLACK)\
+ X(CPAIR_TAGLINE_WARN , COLOR_YELLOW , COLOR_BLACK)\
+ X(CPAIR_TAGLINE_ERR , COLOR_RED , COLOR_BLACK)
typedef enum {
CPAIR_LIST(CPAIR_ENUM_X)
@@ -95,10 +98,25 @@ typedef enum {
(da)->len += n;\
} while(0)
+/* utf8 */
+
+int fast_utf8_width(Str s) {
+ int n = 0;
+ for (int i = 0; i < s.n; i++) {
+ if (s.s[i] & 0x80) {
+ i += stdc_leading_ones((unsigned)i) - 1;
+ }
+ n++;
+ }
+ return n;
+}
+
/* options */
typedef struct {
- int pfp_vis;
+ struct {
+ int pfp, pronouns;
+ } see;
struct {
int left, right, top, bottom;
} margin;
@@ -108,7 +126,10 @@ typedef struct {
regex_t re_mention;
Options opt = {
- .pfp_vis = 1,
+ .see = {
+ .pfp = 1,
+ .pronouns = 1
+ },
.margin = {
.left = 0,
.right = 0
@@ -189,20 +210,10 @@ typedef struct {
typedef struct {
Str name;
+ Str pronouns;
Pfp pfp;
} User;
-int fast_utf8_width(Str s) {
- int n = 0;
- for (int i = 0; i < s.n; i++) {
- if (s.s[i] & 0x80) {
- i += stdc_leading_ones((unsigned)i) - 1;
- }
- n++;
- }
- return n;
-}
-
void pfp_load(Pfp *pfp, Str src, Arena *a) {
int lines = 0, cols = 0;
for (Str s = src, l = {0}; next_line(&s, &l);) {
@@ -226,6 +237,7 @@ User *user_load(Str name, Str homedir, Str binkdir, Arena *a) {
(void)binkdir;
User *u = new(a, User);
u->name = str_dup(name, a);
+
FILE *f = fopen(cstr_fmt(a, "%S/.binkpfp", homedir), "r/o");
Str pfp_src = {0};
if (f) {
@@ -239,6 +251,16 @@ User *user_load(Str name, Str homedir, Str binkdir, Arena *a) {
);
}
pfp_load(&u->pfp, pfp_src, a);
+
+ f = fopen(cstr_fmt(a, "%S/.pronouns", homedir), "r/o");
+ if (f) {
+ Str buf = { 0 };
+ read_all(f, &buf, a);
+ fclose(f);
+ buf = str_trim(buf);
+ next_line(&buf, &u->pronouns);
+ }
+
return u;
}
@@ -417,7 +439,7 @@ typedef struct {
int post_left_margin(Post *post) {
int lm = opt.margin.left;
- if (opt.pfp_vis && post->user->pfp.cols >= lm) lm = post->user->pfp.cols + 1;
+ if (opt.see.pfp && post->user->pfp.cols >= lm) lm = post->user->pfp.cols + 1;
return lm;
}
@@ -460,11 +482,11 @@ void gfx_predraw_post(GfxPost *post) {
int gfx_post_height(GfxPost *post) {
int n = 0;
- if (opt.pfp_vis && post->src->user->pfp.lines > post->lines + 2) n = post->src->user->pfp.lines - post->lines - 2;
+ if (opt.see.pfp && post->src->user->pfp.lines > post->lines + 2) n = post->src->user->pfp.lines - post->lines - 2;
return post->lines + 2 + GFX_TEXT_MARGIN_Y * 2 + n;
}
-void gfx_draw_post(GfxPost *post, int y, int x, int width) {
+void gfx_draw_post(GfxPost *post, int y, int x, int width, Arena *scratch) {
int height = gfx_post_height(post);
if (!post->drawn) {
@@ -475,6 +497,7 @@ void gfx_draw_post(GfxPost *post, int y, int x, int width) {
int left = x + post_left_margin(post->src), top = y + opt.margin.top;
int right = left + width - 1, bottom = top + height - 1;
int self = is_post_mine(post->src);
+ User *u = post->src->user;
color_set(CPAIR_BORDER, 0);
gfx_hline(top, left, right - left, ACS_HLINE);
@@ -491,9 +514,9 @@ void gfx_draw_post(GfxPost *post, int y, int x, int width) {
Str s = str_trim(str_from_cstr(ctime(&(time_t){post->src->timestamp.tv_sec})));
mvaddnstr(y, right - s.n, s.s, s.n);
- if (opt.pfp_vis) {
+ if (opt.see.pfp) {
color_set(self ? CPAIR_PFP_SELF : CPAIR_PFP, 0);
- Pfp *pfp = &post->src->user->pfp;
+ Pfp *pfp = &u->pfp;
int pfptop = top + GFX_TEXT_MARGIN_Y;
if (height > pfp->lines) pfptop += (height - pfp->lines) >> 1;
int pfpleft = left - pfp->cols - GFX_TEXT_MARGIN_X;
@@ -503,7 +526,12 @@ void gfx_draw_post(GfxPost *post, int y, int x, int width) {
}
color_set(CPAIR_USER, 0);
- mvaddnstr(y, left + 2, post->src->user->name.s, post->src->user->name.n);
+ mvaddnstr(y, left + 2, u->name.s, u->name.n);
+
+ if (opt.see.pronouns && u->pronouns.n) {
+ color_set(CPAIR_PRONOUNS, 0);
+ mvaddstr(y, left + 2 + fast_utf8_width(u->name) + GFX_PRONOUNS_MARGIN, cstr_fmt(scratch, GFX_PRONOUNS_FMT, u->pronouns));
+ }
color_set(post->has_mention ? CPAIR_MENTION : CPAIR_TEXT, 0);
@@ -515,10 +543,10 @@ void gfx_draw_post(GfxPost *post, int y, int x, int width) {
}
}
-void gfx_draw(Gfx *gfx, int cur) {
+void gfx_draw(Gfx *gfx, int cur, Arena *scratch) {
erase();
for (int i = cur, y = GFX_MARGIN_Y; i < gfx->len && y < getmaxy(stdscr) - GFX_MARGIN_Y; i++) {
- gfx_draw_post(&gfx->posts[i], y, GFX_MARGIN_X, gfx_post_width(gfx->posts[i].src));
+ gfx_draw_post(&gfx->posts[i], y, GFX_MARGIN_X, gfx_post_width(gfx->posts[i].src), scratch);
y += gfx_post_height(&gfx->posts[i]) + GFX_POST_SPACING;
}
}
@@ -669,7 +697,7 @@ int main(void) {
if (cur < 0) cur = 0;
arena_reset(&temp_arena);
- gfx_draw(&gfx, cur);
+ gfx_draw(&gfx, cur, &temp_arena);
switch (tagline_status) {
case TAGLINE_OK: color_set(CPAIR_TAGLINE_OK, 0); break;
case TAGLINE_WARN: color_set(CPAIR_TAGLINE_WARN, 0); break;
@@ -738,7 +766,7 @@ refresh:
post_stats.gather_ns / 1000000);
goto resize;
case '\t':
- opt.pfp_vis = !opt.pfp_vis;
+ opt.see.pfp = !opt.see.pfp;
/* fallthrough */
case KEY_RESIZE: