From 4c8ef998803340eb2004a4698738a708648a66fb Mon Sep 17 00:00:00 2001 From: m1ngsama Date: Sat, 23 May 2026 18:32:26 +0800 Subject: [PATCH] i18n: localize modal screen chrome --- docs/CHANGELOG.md | 1 + include/i18n.h | 5 ++++- src/i18n.c | 12 ++++++++++++ src/tui.c | 12 +++++++----- tests/test_interactive_input.sh | 31 +++++++++++++++++++++++++++++++ tests/unit/test_i18n.c | 8 ++++++++ 6 files changed, 63 insertions(+), 6 deletions(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 6934422..937563a 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -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 diff --git a/include/i18n.h b/include/i18n.h index 70020c7..cf072f3 100644 --- a/include/i18n.h +++ b/include/i18n.h @@ -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); diff --git a/src/i18n.c b/src/i18n.c index cee3ee8..e5a1118 100644 --- a/src/i18n.c +++ b/src/i18n.c @@ -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 ""; diff --git a/src/tui.c b/src/tui.c index 0c15135..6d0e3a9 100644 --- a/src/tui.c +++ b/src/tui.c @@ -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; diff --git a/tests/test_interactive_input.sh b/tests/test_interactive_input.sh index fa0472c..55d0f36 100755 --- a/tests/test_interactive_input.sh +++ b/tests/test_interactive_input.sh @@ -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" <"$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" diff --git a/tests/unit/test_i18n.c b/tests/unit/test_i18n.c index 2a0a8e5..4f799b8 100644 --- a/tests/unit/test_i18n.c +++ b/tests/unit/test_i18n.c @@ -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); }