Update tier terminology and localization for improved clarity in UI

This commit is contained in:
myhloli
2026-09-14 17:21:20 +08:00
parent 96c54f1254
commit 0acfad6dcd
8 changed files with 39 additions and 14 deletions
+1 -1
View File
@@ -342,7 +342,7 @@ def build_gradio_app(
)
with gr.Group():
tier_label = gr.Markdown(
value=f"解析 tier:{preferred_tier}",
value=MESSAGES["tier_value"][1].format(tier=MESSAGES[f"tier_{preferred_tier}"][1], notice=""),
padding=True,
elem_classes=["mineru-tier-label"],
)
+6 -2
View File
@@ -24,8 +24,12 @@ MESSAGES: dict[str, tuple[str, str]] = {
"homepage": ("Homepage", "主页"),
"download": ("Download", "下载"),
"upload": ("Select a document to parse", "请选择要解析的文件"),
"tier": ("Parsing tier", "解析 tier"),
"tier_value": ("Parsing tier: {tier}{notice}", "解析 tier:{tier}{notice}"),
"tier": ("Parsing tier", "解析等级"),
"tier_value": ("Parsing tier: {tier}{notice}", "解析等级:{tier}{notice}"),
"tier_flash": ("flash", "flash(极速)"),
"tier_basic": ("basic (medium)", "basic(中)"),
"tier_standard": ("standard (high)", "standard(高)"),
"tier_advanced": ("advanced (xhigh)", "advanced(极高)"),
"tier_unavailable_suffix": (" (unavailable on this server)", "(当前服务不可用)"),
"force_ocr": ("Force OCR", "强制 OCR"),
"force_ocr_info": ("Ignore the PDF text layer and perform OCR", "忽略 PDF 文本层并进行 OCR"),
+1 -1
View File
@@ -61,7 +61,7 @@ body.dark .gradio-container {
.mineru-kit-page-range:has([data-range-visible="true"]) { display: flex !important; }
.mineru-page-summary, .mineru-page-summary .html-container { padding: 0 !important; }
.mineru-page-values, .mineru-page-axis { display: flex; justify-content: space-between; align-items: center; gap: 6px; }
.mineru-page-values { font-size: 12px; }
.mineru-page-values { font-size: 12px; justify-content: center; }
.mineru-page-selection { font-weight: 600; color: var(--mineru-accent); }
.mineru-page-axis { position: absolute; bottom: 0; left: 0; right: 0; font-size: 12px; opacity: .7; }
.mineru-page-summary { position: static !important; }
+7 -2
View File
@@ -29,8 +29,13 @@
while ((node = walker.nextNode())) {
const original = node.textContent.trim();
let translated = message(original);
const tier = /^(?:解析 tier:|Parsing tier: )(\w+)$/.exec(original);
if (tier) translated = text("tier_value", { tier: tier[1], notice: "" });
const tier = /^(?:解析等级:|Parsing tier: )(flash|basic|standard|advanced)(?:([^)]*)| \([^)]*\))*$/.exec(original);
if (tier) {
const unavailable = messages.tier_unavailable_suffix.some((suffix) => original.endsWith(suffix));
translated = text("tier_value", {
tier: text(`tier_${tier[1]}`), notice: unavailable ? text("tier_unavailable_suffix") : "",
});
}
if (translated !== original) node.textContent = node.textContent.replace(original, () => translated);
}
});
+2 -3
View File
@@ -68,9 +68,8 @@
const selected = end - start + 1;
const limitText = maxPages === null ? text("page_unlimited") : text("page_limit", { count: maxPages });
const summary = `<div class="mineru-page-values" data-range-visible="${visible}" data-start-handle="${state.start_handle}">`
+ `<span>${text("start_page")} <strong>${start}</strong></span>`
+ `<span class="mineru-page-selection">[${start}-${end}] · ${text("page_count", { count: selected })}</span>`
+ `<span>${text("end_page")} <strong>${end}</strong></span></div>`
+ `</div>`
+ `<div class="mineru-page-axis"><span>1</span><span>${limitText}</span><span>${count}</span></div>`;
const notice = flashUnavailable ? text("flash_unavailable")
: needsRange && !count ? (message(state.error) || text("reading_pages")) : "";
@@ -85,7 +84,7 @@
update({ value: escapeHtml(notice), visible: Boolean(notice) }),
// 同一事件同时更新值、标签和页码,程序赋值无需再触发 tier.input。
update({ value: effectivePosition, interactive: !flashOnly && tiers.length > 1 }),
text("tier_value", { tier: selectedTier, notice: flashUnavailable ? text("tier_unavailable_suffix") : "" }),
text("tier_value", { tier: text(`tier_${selectedTier}`), notice: flashUnavailable ? text("tier_unavailable_suffix") : "" }),
JSON.stringify(tierSelection),
];
}
+7 -1
View File
@@ -1127,7 +1127,13 @@ def test_gradio_tier_slider_uses_available_tiers_and_preserves_selection(
assert (slider.minimum, slider.maximum, slider.step, slider.precision) == (0, maximum, 1, 0)
assert slider.value == default_position
assert slider.interactive is (len(tiers) > 1)
assert label.value == f"解析 tier:{default_tier}"
assert (
label.value
== "解析等级:"
+ {"flash": "flash(极速)", "basic": "basic(中)", "standard": "standard(高)", "advanced": "advanced(极高)"}[
default_tier
]
)
assert not any(block.__class__.__name__ == "Dropdown" for block in demo.blocks.values())
label_events = [event for event in demo.config["dependencies"] if (slider._id, "input") in event["targets"]]
assert len(label_events) == 1
+12 -1
View File
@@ -22,7 +22,18 @@ for (const [languages, language, expected] of [
assert.equal(out[0].label, i18n.text("start_page"));
assert.equal(out[3], "1-10");
assert.ok(out[2].includes(i18n.text("page_limit", { count: 20 })));
assert.equal(out[8], i18n.text("tier_value", { tier: "standard", notice: "" }));
assert.equal(out[8], i18n.text("tier_value", { tier: i18n.text("tier_standard"), notice: "" }));
assert.ok(!out[2].includes("<strong>"));
assert.ok(!out[2].includes(i18n.text("start_page")));
assert.ok(!out[2].includes(i18n.text("end_page")));
for (const [position, tier] of ["flash", "basic", "standard", "advanced"].entries()) {
const labels = expected === "zh"
? ["解析等级:flash(极速)", "解析等级:basic(中)", "解析等级:standard(高)", "解析等级:advanced(极高)"]
: ["Parsing tier: flash", "Parsing tier: basic (medium)", "Parsing tier: standard (high)", "Parsing tier: advanced (xhigh)"];
const result = range(["flash", "basic", "standard", "advanced"], ["csv"], null, null, position,
"{}", "{}", 1, 1, JSON.stringify({ tier, locked: false }));
assert.equal(result[8], labels[position]);
}
const download = vm.runInContext(resource("gradio_download.js"), context);
const formats = [["html", "HTML"]];
download("activate", formats, "", "", "run");
@@ -53,7 +53,7 @@ for (const extension of flashOnlyExtensions.flatMap((extension) => [extension, e
const out = ui.step("file", { file: { path: `/source.${extension}` } });
assert.equal(out[7].value, 0);
assert.equal(out[7].interactive, false);
assert.equal(out[8], "解析 tier:flash");
assert.equal(out[8], "解析等级:flash(极速)");
assert.equal(out[5].interactive, true);
assert.equal(out[3], "");
assert.match(out[2], /data-range-visible="false"/);
@@ -65,7 +65,7 @@ for (const extension of flashOnlyExtensions.flatMap((extension) => [extension, e
const cleared = ui.step("clear");
assert.equal(cleared[7].value, 3);
assert.equal(cleared[7].interactive, true);
assert.equal(cleared[8], "解析 tier:advanced");
assert.equal(cleared[8], "解析等级:advanced(极高)");
assert.equal(cleared[5].interactive, false);
}
@@ -76,7 +76,7 @@ for (const extension of tieredExtensions.flatMap((extension) => [extension, exte
const out = ui.step("file", { file: { path: `/source.${extension}` } });
assert.equal(out[7].value, 2);
assert.equal(out[7].interactive, true);
assert.equal(out[8], "解析 tier:standard");
assert.equal(out[8], "解析等级:standard(高)");
assert.equal(out[5].interactive, extension.toLowerCase() !== "pdf");
assert.deepEqual(ui.state.tierSelection, { tier: "standard", locked: false });
}