mirror of
https://oauth2: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@github.com/m1ngsama/TNT.git
synced 2026-06-26 03:24:38 +08:00
Show unread count in private inbox
This commit is contained in:
parent
845657e3c2
commit
d7531f9305
9 changed files with 32 additions and 7 deletions
|
|
@ -116,6 +116,8 @@ shows incoming and sent private messages newest-first; press `r` to refresh it
|
|||
manually, and it refreshes when a new private message arrives while the inbox
|
||||
is open. `:reply text` and `:r text` send to the latest private-message peer.
|
||||
Unread incoming private messages are marked with `*` until `:inbox` renders.
|
||||
The inbox title shows a transient unread count when new private messages are
|
||||
present.
|
||||
`:inbox clear` removes private messages and the reply target for this session.
|
||||
Private messages are per-session only and are not written to `messages.log`.
|
||||
|
||||
|
|
|
|||
|
|
@ -168,8 +168,9 @@ persisted to `messages.log` and are not included in exec `tail`, exec `dump`,
|
|||
Each participant keeps a bounded in-memory `:inbox` for the current session.
|
||||
Recipients see incoming private messages; senders see local sent-message
|
||||
copies. Unread incoming messages are marked with `*` until `:inbox` renders.
|
||||
`:inbox` displays newest messages first, can be refreshed with `r`, and
|
||||
refreshes automatically while open when a new private message arrives.
|
||||
`:inbox` displays newest messages first, shows a transient unread count, can
|
||||
be refreshed with `r`, and refreshes automatically while open when a new
|
||||
private message arrives.
|
||||
`:inbox clear` removes the current session's private messages, unread count,
|
||||
and reply target.
|
||||
|
||||
|
|
|
|||
|
|
@ -38,9 +38,9 @@ The product path should stay short:
|
|||
reconnect.
|
||||
- `:inbox` is live enough for normal chat use: it can be refreshed with `r`
|
||||
and refreshes automatically when a new private message arrives while the
|
||||
inbox is open. Incoming unread messages are marked with `*` until the inbox
|
||||
renders them. `:inbox clear` removes private messages and the reply target
|
||||
for the current session.
|
||||
inbox is open. Incoming unread messages are marked with `*` and counted in
|
||||
the inbox title until the inbox renders them. `:inbox clear` removes private
|
||||
messages and the reply target for the current session.
|
||||
- `:reply` / `:r` keeps the private-message path keyboard-short: it answers
|
||||
the latest private-message peer in the current session without retyping a
|
||||
username.
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ typedef enum {
|
|||
I18N_INBOX_EMPTY,
|
||||
I18N_INBOX_SENT_TO_FORMAT,
|
||||
I18N_INBOX_CLEARED,
|
||||
I18N_INBOX_UNREAD_FORMAT,
|
||||
I18N_NICK_INVALID,
|
||||
I18N_NICK_TAKEN_FORMAT,
|
||||
I18N_NICK_UNCHANGED,
|
||||
|
|
|
|||
|
|
@ -138,9 +138,11 @@ static void append_inbox_output(client_t *client, char *output,
|
|||
size_t buf_size, size_t *pos) {
|
||||
whisper_t snapshot[WHISPER_INBOX_SIZE];
|
||||
int snap_count;
|
||||
int unread_count;
|
||||
|
||||
pthread_mutex_lock(&client->whisper_lock);
|
||||
snap_count = client->whisper_inbox_count;
|
||||
unread_count = client->unread_whispers;
|
||||
memcpy(snapshot, client->whisper_inbox,
|
||||
snap_count * sizeof(whisper_t));
|
||||
for (int i = 0; i < snap_count; i++) {
|
||||
|
|
@ -150,9 +152,18 @@ static void append_inbox_output(client_t *client, char *output,
|
|||
pthread_mutex_unlock(&client->whisper_lock);
|
||||
|
||||
buffer_appendf(output, buf_size, pos,
|
||||
"\033[1;36m%s\033[0m \033[2;37m· %d\033[0m\n",
|
||||
"\033[1;36m%s\033[0m \033[2;37m· %d",
|
||||
i18n_text(client->ui_lang, I18N_INBOX_TITLE),
|
||||
snap_count);
|
||||
if (unread_count > 0) {
|
||||
buffer_appendf(output, buf_size, pos,
|
||||
" · ");
|
||||
buffer_appendf(output, buf_size, pos,
|
||||
i18n_text(client->ui_lang,
|
||||
I18N_INBOX_UNREAD_FORMAT),
|
||||
unread_count);
|
||||
}
|
||||
buffer_appendf(output, buf_size, pos, "\033[0m\n");
|
||||
if (snap_count == 0) {
|
||||
buffer_appendf(output, buf_size, pos,
|
||||
" \033[2;37m%s\033[0m\n",
|
||||
|
|
|
|||
|
|
@ -141,6 +141,10 @@ static const i18n_string_t text_catalog[I18N_TEXT_COUNT] = {
|
|||
"Private messages cleared\n",
|
||||
"私信已清空\n"
|
||||
),
|
||||
[I18N_INBOX_UNREAD_FORMAT] = I18N_STRING(
|
||||
"%d new",
|
||||
"%d 新"
|
||||
),
|
||||
[I18N_NICK_INVALID] = I18N_STRING(
|
||||
"Invalid username\n",
|
||||
"用户名无效\n"
|
||||
|
|
|
|||
|
|
@ -288,7 +288,9 @@ fi
|
|||
BOB_PID=""
|
||||
|
||||
if grep -q '.*alice.*private lifecycle second' "$STATE_DIR/bob.log" &&
|
||||
grep -q '2 新' "$STATE_DIR/bob.log" &&
|
||||
grep -q '\*.*alice.*private lifecycle second' "$STATE_DIR/bob.log" &&
|
||||
grep -q '1 新' "$STATE_DIR/alice.log" &&
|
||||
grep -q '\*.*bob.*private lifecycle reply' "$STATE_DIR/alice.log"; then
|
||||
echo "✓ unread private messages are visibly marked in inbox"
|
||||
PASS=$((PASS + 1))
|
||||
|
|
|
|||
|
|
@ -164,6 +164,10 @@ TEST(text_lookup_matches_language) {
|
|||
"cleared") != NULL);
|
||||
assert(strstr(i18n_text(UI_LANG_ZH, I18N_INBOX_CLEARED),
|
||||
"清空") != NULL);
|
||||
assert(strstr(i18n_text(UI_LANG_EN, I18N_INBOX_UNREAD_FORMAT),
|
||||
"new") != NULL);
|
||||
assert(strstr(i18n_text(UI_LANG_ZH, I18N_INBOX_UNREAD_FORMAT),
|
||||
"新") != NULL);
|
||||
assert(strstr(i18n_text(UI_LANG_EN, I18N_SEARCH_HEADER_FORMAT),
|
||||
"Search") != NULL);
|
||||
assert(strstr(i18n_text(UI_LANG_ZH, I18N_SEARCH_HEADER_FORMAT),
|
||||
|
|
|
|||
2
tnt.1
2
tnt.1
|
|
@ -256,7 +256,7 @@ page shows incoming messages and local sent-message copies for the current
|
|||
session. It refreshes automatically when a new private message arrives while
|
||||
it is open. Incoming unread messages are marked with
|
||||
.B *
|
||||
until the inbox renders them. Use
|
||||
and counted in the inbox title until the inbox renders them. Use
|
||||
.B :reply
|
||||
or
|
||||
.B :r
|
||||
|
|
|
|||
Loading…
Reference in a new issue