Spaces:
Running
Running
Fix glossary row addition on Space
Browse files- hachimimt-local.zip +2 -2
- src/app.py +70 -5
hachimimt-local.zip
CHANGED
|
@@ -1,3 +1,3 @@
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:
|
| 3 |
-
size
|
|
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:a3511d1f3a5a8e0e44de5cbd24daedc7e9226c3bd9bf0efb0d7688972b48a0d9
|
| 3 |
+
size 136689
|
src/app.py
CHANGED
|
@@ -200,10 +200,32 @@ def render_gpu_hint_html() -> str:
|
|
| 200 |
# theme vì Gradio bỏ qua nó ở đây và CSS đã đủ.
|
| 201 |
|
| 202 |
# Preload font trong <head> để giảm nhấp nháy khi tải.
|
| 203 |
-
HEAD_HTML = """
|
| 204 |
-
<link rel="preconnect" href="https://fonts.googleapis.com">
|
| 205 |
-
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
| 206 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 207 |
|
| 208 |
CUSTOM_CSS = """
|
| 209 |
@import url('https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,400;0,9..144,600;0,9..144,700;1,9..144,500&family=Literata:ital,opsz,wght@0,7..72,400;0,7..72,500;0,7..72,600;1,7..72,400&family=Noto+Serif+SC:wght@400;600&display=swap');
|
|
@@ -1328,6 +1350,28 @@ def export_translation_ui(
|
|
| 1328 |
return export_translation(full_text, "hachimimt", request)
|
| 1329 |
|
| 1330 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1331 |
def import_glossary_ui(file_obj) -> tuple[list[list[object]], str]:
|
| 1332 |
if file_obj is None:
|
| 1333 |
raise gr.Error("Chọn file glossary .tsv hoặc .json.")
|
|
@@ -2129,6 +2173,15 @@ def build_ui() -> gr.Blocks:
|
|
| 2129 |
label="Glossary của phiên hiện tại",
|
| 2130 |
elem_id="glossary-table",
|
| 2131 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2132 |
with gr.Row():
|
| 2133 |
glossary_file = gr.File(
|
| 2134 |
label="Nhập glossary (.tsv / .json)",
|
|
@@ -2219,8 +2272,20 @@ mục `hachimimt`, chạy `setup.bat` (cài thư viện + tải model mặc đ
|
|
| 2219 |
on_backend_change,
|
| 2220 |
inputs=[backend_select, model_select],
|
| 2221 |
outputs=[engine_hint, model_badge],
|
| 2222 |
-
)
|
| 2223 |
auto_batch.change(on_auto_batch_toggle, inputs=[auto_batch], outputs=[manual_batch])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2224 |
glossary_import_btn.click(
|
| 2225 |
import_glossary_ui,
|
| 2226 |
inputs=[glossary_file],
|
|
|
|
| 200 |
# theme vì Gradio bỏ qua nó ở đây và CSS đã đủ.
|
| 201 |
|
| 202 |
# Preload font trong <head> để giảm nhấp nháy khi tải.
|
| 203 |
+
HEAD_HTML = """
|
| 204 |
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
| 205 |
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
| 206 |
+
<script>
|
| 207 |
+
window.__hachimimtRefreshGlossaryTable = () => {
|
| 208 |
+
window.dispatchEvent(new Event("resize"));
|
| 209 |
+
document
|
| 210 |
+
.querySelector("#glossary-table .virtual-table-viewport")
|
| 211 |
+
?.dispatchEvent(new Event("scroll"));
|
| 212 |
+
};
|
| 213 |
+
|
| 214 |
+
document.addEventListener("click", (event) => {
|
| 215 |
+
const target = event.target instanceof Element
|
| 216 |
+
? event.target.closest(
|
| 217 |
+
'[role="menuitem"][aria-label="Add row above"], ' +
|
| 218 |
+
'[role="menuitem"][aria-label="Add row below"]'
|
| 219 |
+
)
|
| 220 |
+
: null;
|
| 221 |
+
if (!target) return;
|
| 222 |
+
requestAnimationFrame(() => {
|
| 223 |
+
window.__hachimimtRefreshGlossaryTable();
|
| 224 |
+
requestAnimationFrame(window.__hachimimtRefreshGlossaryTable);
|
| 225 |
+
});
|
| 226 |
+
});
|
| 227 |
+
</script>
|
| 228 |
+
"""
|
| 229 |
|
| 230 |
CUSTOM_CSS = """
|
| 231 |
@import url('https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,400;0,9..144,600;0,9..144,700;1,9..144,500&family=Literata:ital,opsz,wght@0,7..72,400;0,7..72,500;0,7..72,600;1,7..72,400&family=Noto+Serif+SC:wght@400;600&display=swap');
|
|
|
|
| 1350 |
return export_translation(full_text, "hachimimt", request)
|
| 1351 |
|
| 1352 |
|
| 1353 |
+
def add_glossary_row_ui(rows) -> list[list[object]]:
|
| 1354 |
+
"""Append one editable glossary row without relying on Gradio's cell menu."""
|
| 1355 |
+
if isinstance(rows, dict):
|
| 1356 |
+
rows = rows.get("data", [])
|
| 1357 |
+
elif hasattr(rows, "tolist"):
|
| 1358 |
+
rows = rows.tolist()
|
| 1359 |
+
|
| 1360 |
+
blank_row: list[object] = ["", "", "", "", True]
|
| 1361 |
+
table_rows: list[list[object]] = []
|
| 1362 |
+
if isinstance(rows, (list, tuple)):
|
| 1363 |
+
for row in rows:
|
| 1364 |
+
if not isinstance(row, (list, tuple)):
|
| 1365 |
+
continue
|
| 1366 |
+
normalized = blank_row.copy()
|
| 1367 |
+
for index, value in enumerate(row[: len(blank_row)]):
|
| 1368 |
+
normalized[index] = value
|
| 1369 |
+
table_rows.append(normalized)
|
| 1370 |
+
|
| 1371 |
+
table_rows.append(blank_row.copy())
|
| 1372 |
+
return table_rows
|
| 1373 |
+
|
| 1374 |
+
|
| 1375 |
def import_glossary_ui(file_obj) -> tuple[list[list[object]], str]:
|
| 1376 |
if file_obj is None:
|
| 1377 |
raise gr.Error("Chọn file glossary .tsv hoặc .json.")
|
|
|
|
| 2173 |
label="Glossary của phiên hiện tại",
|
| 2174 |
elem_id="glossary-table",
|
| 2175 |
)
|
| 2176 |
+
with gr.Row():
|
| 2177 |
+
glossary_add_row_btn = gr.Button(
|
| 2178 |
+
"+ Thêm hàng",
|
| 2179 |
+
variant="secondary",
|
| 2180 |
+
size="sm",
|
| 2181 |
+
scale=0,
|
| 2182 |
+
min_width=140,
|
| 2183 |
+
elem_id="glossary-add-row",
|
| 2184 |
+
)
|
| 2185 |
with gr.Row():
|
| 2186 |
glossary_file = gr.File(
|
| 2187 |
label="Nhập glossary (.tsv / .json)",
|
|
|
|
| 2272 |
on_backend_change,
|
| 2273 |
inputs=[backend_select, model_select],
|
| 2274 |
outputs=[engine_hint, model_badge],
|
| 2275 |
+
)
|
| 2276 |
auto_batch.change(on_auto_batch_toggle, inputs=[auto_batch], outputs=[manual_batch])
|
| 2277 |
+
glossary_add_row_event = glossary_add_row_btn.click(
|
| 2278 |
+
add_glossary_row_ui,
|
| 2279 |
+
inputs=[glossary_table],
|
| 2280 |
+
outputs=[glossary_table],
|
| 2281 |
+
queue=False,
|
| 2282 |
+
)
|
| 2283 |
+
glossary_add_row_event.then(
|
| 2284 |
+
fn=None,
|
| 2285 |
+
js="() => window.__hachimimtRefreshGlossaryTable?.()",
|
| 2286 |
+
queue=False,
|
| 2287 |
+
api_name=False,
|
| 2288 |
+
)
|
| 2289 |
glossary_import_btn.click(
|
| 2290 |
import_glossary_ui,
|
| 2291 |
inputs=[glossary_file],
|