mirror of
https://oauth2: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@github.com/m1ngsama/TNT.git
synced 2026-05-10 19:00:57 +08:00
feat: improve TUI visual experience with colors and indicators
- Color-code usernames using hash-based ANSI color assignment (6 colors) - Style system messages (join/leave/rename) in gray with --> prefix - Style /me action messages in italic cyan - Show "↓ N new" indicator in yellow when scrolled up in NORMAL mode - Compact timestamps from full date to HH:MM for more message space Closes #44
This commit is contained in:
parent
6dfcfe0487
commit
ee3f89f10a
1 changed files with 98 additions and 4 deletions
98
src/tui.c
98
src/tui.c
|
|
@ -5,6 +5,93 @@
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
static const char *username_color(const char *name) {
|
||||||
|
static const char *colors[] = {
|
||||||
|
"\033[31m", "\033[32m", "\033[33m",
|
||||||
|
"\033[34m", "\033[35m", "\033[36m",
|
||||||
|
};
|
||||||
|
unsigned int h = 5381;
|
||||||
|
for (const char *p = name; *p; p++)
|
||||||
|
h = h * 33 + (unsigned char)*p;
|
||||||
|
return colors[h % 6];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void format_message_colored(const message_t *msg, char *buffer,
|
||||||
|
size_t buf_size, int width) {
|
||||||
|
struct tm tm_info;
|
||||||
|
localtime_r(&msg->timestamp, &tm_info);
|
||||||
|
char time_str[32];
|
||||||
|
strftime(time_str, sizeof(time_str), "%H:%M", &tm_info);
|
||||||
|
|
||||||
|
if (strcmp(msg->username, "系统") == 0) {
|
||||||
|
snprintf(buffer, buf_size,
|
||||||
|
"\033[90m--> %s\033[0m", msg->content);
|
||||||
|
} else if (strcmp(msg->username, "*") == 0) {
|
||||||
|
snprintf(buffer, buf_size,
|
||||||
|
"\033[90m%s\033[0m \033[3;36m* %s\033[0m",
|
||||||
|
time_str, msg->content);
|
||||||
|
} else {
|
||||||
|
snprintf(buffer, buf_size,
|
||||||
|
"\033[90m%s\033[0m %s%s\033[0m: %s",
|
||||||
|
time_str, username_color(msg->username),
|
||||||
|
msg->username, msg->content);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Plain-text version for width calculation */
|
||||||
|
char plain[MAX_MESSAGE_LEN + 128];
|
||||||
|
if (strcmp(msg->username, "系统") == 0) {
|
||||||
|
snprintf(plain, sizeof(plain), "--> %s", msg->content);
|
||||||
|
} else if (strcmp(msg->username, "*") == 0) {
|
||||||
|
snprintf(plain, sizeof(plain), "%s * %s", time_str, msg->content);
|
||||||
|
} else {
|
||||||
|
snprintf(plain, sizeof(plain), "%s %s: %s",
|
||||||
|
time_str, msg->username, msg->content);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (utf8_string_width(plain) > width) {
|
||||||
|
/* Rebuild with truncated content */
|
||||||
|
int prefix_width;
|
||||||
|
char prefix_plain[256];
|
||||||
|
if (strcmp(msg->username, "系统") == 0) {
|
||||||
|
snprintf(prefix_plain, sizeof(prefix_plain), "--> ");
|
||||||
|
} else if (strcmp(msg->username, "*") == 0) {
|
||||||
|
snprintf(prefix_plain, sizeof(prefix_plain), "%s * ", time_str);
|
||||||
|
} else {
|
||||||
|
snprintf(prefix_plain, sizeof(prefix_plain), "%s %s: ",
|
||||||
|
time_str, msg->username);
|
||||||
|
}
|
||||||
|
prefix_width = utf8_string_width(prefix_plain);
|
||||||
|
int content_width = width - prefix_width;
|
||||||
|
if (content_width < 4) content_width = 4;
|
||||||
|
|
||||||
|
char truncated_content[MAX_MESSAGE_LEN];
|
||||||
|
if (strcmp(msg->username, "系统") == 0) {
|
||||||
|
strncpy(truncated_content, msg->content, sizeof(truncated_content) - 1);
|
||||||
|
truncated_content[sizeof(truncated_content) - 1] = '\0';
|
||||||
|
} else if (strcmp(msg->username, "*") == 0) {
|
||||||
|
snprintf(truncated_content, sizeof(truncated_content), "* %s", msg->content);
|
||||||
|
} else {
|
||||||
|
strncpy(truncated_content, msg->content, sizeof(truncated_content) - 1);
|
||||||
|
truncated_content[sizeof(truncated_content) - 1] = '\0';
|
||||||
|
}
|
||||||
|
utf8_truncate(truncated_content, content_width);
|
||||||
|
|
||||||
|
if (strcmp(msg->username, "系统") == 0) {
|
||||||
|
snprintf(buffer, buf_size,
|
||||||
|
"\033[90m--> %s\033[0m", truncated_content);
|
||||||
|
} else if (strcmp(msg->username, "*") == 0) {
|
||||||
|
snprintf(buffer, buf_size,
|
||||||
|
"\033[90m%s\033[0m \033[3;36m%s\033[0m",
|
||||||
|
time_str, truncated_content);
|
||||||
|
} else {
|
||||||
|
snprintf(buffer, buf_size,
|
||||||
|
"\033[90m%s\033[0m %s%s\033[0m: %s",
|
||||||
|
time_str, username_color(msg->username),
|
||||||
|
msg->username, truncated_content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void buffer_append_bytes(char *buffer, size_t buf_size, size_t *pos,
|
static void buffer_append_bytes(char *buffer, size_t buf_size, size_t *pos,
|
||||||
const char *data, size_t len) {
|
const char *data, size_t len) {
|
||||||
size_t available;
|
size_t available;
|
||||||
|
|
@ -148,8 +235,8 @@ void tui_render_screen(client_t *client) {
|
||||||
/* Render messages from snapshot */
|
/* Render messages from snapshot */
|
||||||
if (msg_snapshot) {
|
if (msg_snapshot) {
|
||||||
for (int i = 0; i < snapshot_count; i++) {
|
for (int i = 0; i < snapshot_count; i++) {
|
||||||
char msg_line[1024];
|
char msg_line[2048];
|
||||||
message_format(&msg_snapshot[i], msg_line, sizeof(msg_line), render_width);
|
format_message_colored(&msg_snapshot[i], msg_line, sizeof(msg_line), render_width);
|
||||||
buffer_appendf(buffer, buf_size, &pos, "%s\033[K\r\n", msg_line);
|
buffer_appendf(buffer, buf_size, &pos, "%s\033[K\r\n", msg_line);
|
||||||
}
|
}
|
||||||
free(msg_snapshot);
|
free(msg_snapshot);
|
||||||
|
|
@ -173,8 +260,15 @@ void tui_render_screen(client_t *client) {
|
||||||
int total = msg_count;
|
int total = msg_count;
|
||||||
int scroll_pos = client->scroll_pos + 1;
|
int scroll_pos = client->scroll_pos + 1;
|
||||||
if (total == 0) scroll_pos = 0;
|
if (total == 0) scroll_pos = 0;
|
||||||
|
int unseen = msg_count - end;
|
||||||
|
if (unseen > 0) {
|
||||||
|
buffer_appendf(buffer, buf_size, &pos,
|
||||||
|
"-- NORMAL -- (%d/%d) \033[33m↓ %d new\033[0m\033[K",
|
||||||
|
scroll_pos, total, unseen);
|
||||||
|
} else {
|
||||||
buffer_appendf(buffer, buf_size, &pos,
|
buffer_appendf(buffer, buf_size, &pos,
|
||||||
"-- NORMAL -- (%d/%d)\033[K", scroll_pos, total);
|
"-- NORMAL -- (%d/%d)\033[K", scroll_pos, total);
|
||||||
|
}
|
||||||
} else if (client->mode == MODE_COMMAND) {
|
} else if (client->mode == MODE_COMMAND) {
|
||||||
buffer_appendf(buffer, buf_size, &pos, ":%s\033[K", client->command_input);
|
buffer_appendf(buffer, buf_size, &pos, ":%s\033[K", client->command_input);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue