i18n: localize modal screen chrome

This commit is contained in:
m1ngsama 2026-05-23 18:32:26 +08:00
parent 22ab85acef
commit 4c8ef99880
6 changed files with 63 additions and 6 deletions

View file

@ -14,6 +14,7 @@
with UTF-8-aware title padding for Chinese.
- Common COMMAND-mode outputs now respect the session language, including
`:users` headers and `:mute-joins` state text.
- Command-output and MOTD screen chrome now use the session UI language.
### Changed
- NORMAL mode now opens at the latest visible messages instead of the oldest

View file

@ -12,7 +12,10 @@ typedef enum {
I18N_NORMAL_LATEST,
I18N_NORMAL_NEW_MESSAGES,
I18N_HELP_TITLE,
I18N_HELP_STATUS_FORMAT
I18N_HELP_STATUS_FORMAT,
I18N_COMMAND_OUTPUT_TITLE,
I18N_MOTD_TITLE,
I18N_MOTD_CONTINUE_HINT
} i18n_text_id_t;
bool i18n_try_parse_lang(const char *value, help_lang_t *lang);

View file

@ -89,6 +89,12 @@ const char *i18n_text(help_lang_t lang, i18n_text_id_t id) {
return " 帮助 ";
case I18N_HELP_STATUS_FORMAT:
return "-- 帮助 -- (%d/%d) j/k:滚动 g/G:首尾 e/z:语言 q:关闭";
case I18N_COMMAND_OUTPUT_TITLE:
return " 命令输出 ";
case I18N_MOTD_TITLE:
return " 公告 ";
case I18N_MOTD_CONTINUE_HINT:
return " 按任意键继续 ";
}
}
@ -111,6 +117,12 @@ const char *i18n_text(help_lang_t lang, i18n_text_id_t id) {
return " HELP ";
case I18N_HELP_STATUS_FORMAT:
return "-- HELP -- (%d/%d) j/k:scroll g/G:top/bottom e/z:lang q:close";
case I18N_COMMAND_OUTPUT_TITLE:
return " COMMAND OUTPUT ";
case I18N_MOTD_TITLE:
return " NOTICE ";
case I18N_MOTD_CONTINUE_HINT:
return " Press any key ";
}
return "";

View file

@ -621,7 +621,8 @@ void tui_render_command_output(client_t *client) {
buffer_appendf(buffer, sizeof(buffer), &pos, ANSI_CLEAR ANSI_HOME);
/* Title */
const char *title = " COMMAND OUTPUT ";
const char *title = i18n_text(client->help_lang,
I18N_COMMAND_OUTPUT_TITLE);
char title_display[64];
utf8_ansi_truncate(title, title_display, sizeof(title_display), rw);
int title_width = utf8_ansi_string_width(title_display);
@ -678,8 +679,8 @@ void tui_render_motd(client_t *client) {
size_t pos = 0;
buffer_appendf(buffer, sizeof(buffer), &pos, ANSI_CLEAR ANSI_HOME);
/* Top border: ╭─ 公告 / MOTD ──...──╮ */
const char *title = " 公告 / MOTD ";
/* Top border with a localized title chip. */
const char *title = i18n_text(client->help_lang, I18N_MOTD_TITLE);
int title_w = utf8_string_width(title);
int top_dash_fill = rw - 2 - title_w - 1; /* 2 corners, 1 leading ─ */
if (top_dash_fill < 0) top_dash_fill = 0;
@ -730,8 +731,9 @@ void tui_render_motd(client_t *client) {
/* Bottom breathing-room line */
buffer_appendf(buffer, sizeof(buffer), &pos, "\r\n");
/* Bottom border: ╰─ 按任意键继续 ─...─╯ */
const char *footer = " 按任意键继续 / press any key ";
/* Bottom border with a localized continue hint. */
const char *footer = i18n_text(client->help_lang,
I18N_MOTD_CONTINUE_HINT);
int footer_w = utf8_string_width(footer);
int bot_dash_fill = rw - 2 - footer_w - 1;
if (bot_dash_fill < 0) bot_dash_fill = 0;

View file

@ -216,6 +216,7 @@ expect "NORMAL"
send -- ":"
expect ":"
send -- "mute-joins\r"
expect "命令输出"
expect "加入/离开提示"
expect "已静音"
expect "按任意键"
@ -231,6 +232,7 @@ expect "NORMAL"
send -- ":"
expect ":"
send -- "users\r"
expect "COMMAND OUTPUT"
expect "Online users"
expect "Press any key"
send -- "q"
@ -251,6 +253,35 @@ else
FAIL=$((FAIL + 1))
fi
printf '维护窗口\n' >"$STATE_DIR/motd.txt"
MOTD_SCRIPT="$STATE_DIR/motd.expect"
cat >"$MOTD_SCRIPT" <<EOF
set timeout 10
spawn ssh $SSH_OPTS anonymous@127.0.0.1
sleep 1
send -- "motduser\r"
expect "公告"
expect "维护窗口"
expect "按任意键继续"
send -- "x"
expect "NORMAL"
sleep 0.2
send -- "\003"
sleep 0.2
send -- "\003"
expect eof
EOF
if expect "$MOTD_SCRIPT" >"$STATE_DIR/motd.log" 2>&1; then
echo "✓ MOTD chrome follows session language"
PASS=$((PASS + 1))
else
echo "x localized MOTD chrome failed"
sed -n '1,200p' "$STATE_DIR/motd.log"
sed -n '1,120p' "$STATE_DIR/server.log"
FAIL=$((FAIL + 1))
fi
echo ""
echo "PASSED: $PASS"
echo "FAILED: $FAIL"

View file

@ -66,6 +66,14 @@ TEST(text_lookup_matches_language) {
"HELP") != NULL);
assert(strstr(i18n_text(LANG_ZH, I18N_HELP_STATUS_FORMAT),
"帮助") != NULL);
assert(strstr(i18n_text(LANG_EN, I18N_COMMAND_OUTPUT_TITLE),
"COMMAND") != NULL);
assert(strstr(i18n_text(LANG_ZH, I18N_COMMAND_OUTPUT_TITLE),
"命令输出") != NULL);
assert(strstr(i18n_text(LANG_EN, I18N_MOTD_CONTINUE_HINT),
"Press any key") != NULL);
assert(strstr(i18n_text(LANG_ZH, I18N_MOTD_CONTINUE_HINT),
"按任意键") != NULL);
assert(strcmp(i18n_lang_code(LANG_EN), "en") == 0);
assert(strcmp(i18n_lang_code(LANG_ZH), "zh") == 0);
}