Spaces:
Sleeping
Sleeping
deploy rater (Docker/FastAPI): registration + completeness gate + /api/submit → dataset
Browse files- static/mobile.html +51 -0
static/mobile.html
CHANGED
|
@@ -294,6 +294,7 @@
|
|
| 294 |
<header class="top" id="topBar">
|
| 295 |
<button class="icon" id="drawerBtn" title="Cases">☰</button>
|
| 296 |
<span class="title" id="topTitle">Video user study</span>
|
|
|
|
| 297 |
<span class="pill" id="syncPill" data-state="idle">●</span>
|
| 298 |
<select id="langSelect" title="Language"></select>
|
| 299 |
</header>
|
|
@@ -333,6 +334,20 @@
|
|
| 333 |
</div>
|
| 334 |
</aside>
|
| 335 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 336 |
<!-- Registration overlay -->
|
| 337 |
<div id="loginOverlay" class="overlay" role="dialog" aria-modal="true">
|
| 338 |
<div class="reg-card">
|
|
@@ -455,6 +470,9 @@ const STRINGS = {
|
|
| 455 |
reg_email:"Email", reg_email_ph:"e.g. alex@example.com",
|
| 456 |
reg_note:"Affiliation / notes (optional)", reg_note_ph:"e.g. INSAIT, internal pilot, etc.",
|
| 457 |
reg_continue:"Continue →",
|
|
|
|
|
|
|
|
|
|
| 458 |
reg_foot:"Submissions are written to the <code>dehezhang2/Frameworker_User_Study</code> dataset on Hugging Face.",
|
| 459 |
reg_err_name:"Please enter your name.",
|
| 460 |
reg_err_email:"Please enter a valid email address.",
|
|
@@ -494,6 +512,9 @@ const STRINGS = {
|
|
| 494 |
reg_email:"邮箱", reg_email_ph:"例如:xiaoming@example.com",
|
| 495 |
reg_note:"所属单位 / 备注(可选)", reg_note_ph:"例如:INSAIT、内部预测试 等",
|
| 496 |
reg_continue:"继续 →",
|
|
|
|
|
|
|
|
|
|
| 497 |
reg_foot:"提交将写入 Hugging Face 上的 <code>dehezhang2/Frameworker_User_Study</code> 数据集。",
|
| 498 |
reg_err_name:"请输入您的姓名。",
|
| 499 |
reg_err_email:"请输入有效的邮箱地址。",
|
|
@@ -533,6 +554,9 @@ const STRINGS = {
|
|
| 533 |
reg_email:"Имейл", reg_email_ph:"напр. alex@example.com",
|
| 534 |
reg_note:"Принадлежност / бележки (по избор)", reg_note_ph:"напр. INSAIT, вътрешен пилот",
|
| 535 |
reg_continue:"Продължи →",
|
|
|
|
|
|
|
|
|
|
| 536 |
reg_foot:"Изпращанията се записват в <code>dehezhang2/Frameworker_User_Study</code> на Hugging Face.",
|
| 537 |
reg_err_name:"Моля, въведете името си.",
|
| 538 |
reg_err_email:"Моля, въведете валиден имейл адрес.",
|
|
@@ -1292,6 +1316,25 @@ function openRegister(){
|
|
| 1292 |
applyRegistrationI18n();
|
| 1293 |
}
|
| 1294 |
function closeRegister(){ document.getElementById("loginOverlay").classList.add("hidden"); }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1295 |
function applyRegistrationI18n(){
|
| 1296 |
document.getElementById("regHeader").textContent = t("reg_title");
|
| 1297 |
document.getElementById("regLead").textContent = t("reg_lead");
|
|
@@ -1398,6 +1441,9 @@ function hideSubmittedOverlay(){ document.getElementById("submittedOverlay").cla
|
|
| 1398 |
|
| 1399 |
// wire DOM events
|
| 1400 |
document.getElementById("drawerBtn").onclick = openDrawer;
|
|
|
|
|
|
|
|
|
|
| 1401 |
document.getElementById("drawerCloseBtn").onclick = closeDrawer;
|
| 1402 |
document.getElementById("drawerBackdrop").onclick = closeDrawer;
|
| 1403 |
document.getElementById("prevBtn").onclick = () => step(-1);
|
|
@@ -1431,6 +1477,11 @@ function hideSubmittedOverlay(){ document.getElementById("submittedOverlay").cla
|
|
| 1431 |
renderShell();
|
| 1432 |
closeRegister();
|
| 1433 |
probeSync();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1434 |
}
|
| 1435 |
// Always fetch admin-curated highlights; available even before registration
|
| 1436 |
// gate clears so the prompt shows highlights as soon as the rater enters.
|
|
|
|
| 294 |
<header class="top" id="topBar">
|
| 295 |
<button class="icon" id="drawerBtn" title="Cases">☰</button>
|
| 296 |
<span class="title" id="topTitle">Video user study</span>
|
| 297 |
+
<button class="icon" id="helpBtn" title="How to rate" style="font-size:18px">?</button>
|
| 298 |
<span class="pill" id="syncPill" data-state="idle">●</span>
|
| 299 |
<select id="langSelect" title="Language"></select>
|
| 300 |
</header>
|
|
|
|
| 334 |
</div>
|
| 335 |
</aside>
|
| 336 |
|
| 337 |
+
<!-- Rating instructions overlay (mobile) — toggled via the "?" header button.
|
| 338 |
+
Auto-opened on first launch; user can close + reopen any time. -->
|
| 339 |
+
<div id="helpOverlay" class="overlay hidden" role="dialog" aria-modal="true">
|
| 340 |
+
<div class="reg-card" style="max-width:520px">
|
| 341 |
+
<div class="top-row">
|
| 342 |
+
<h2 id="helpHeader">How to rate</h2>
|
| 343 |
+
<button class="btn" id="helpCloseBtn"
|
| 344 |
+
style="background:transparent;border:none;color:var(--fg);font-size:22px;cursor:pointer">✕</button>
|
| 345 |
+
</div>
|
| 346 |
+
<div id="helpBody" style="font-size:13px;line-height:1.6;color:var(--fg);max-height:60vh;overflow-y:auto"></div>
|
| 347 |
+
<button class="go-btn" id="helpDismissBtn" style="margin-top:14px"><span id="helpDismissText">Got it</span></button>
|
| 348 |
+
</div>
|
| 349 |
+
</div>
|
| 350 |
+
|
| 351 |
<!-- Registration overlay -->
|
| 352 |
<div id="loginOverlay" class="overlay" role="dialog" aria-modal="true">
|
| 353 |
<div class="reg-card">
|
|
|
|
| 470 |
reg_email:"Email", reg_email_ph:"e.g. alex@example.com",
|
| 471 |
reg_note:"Affiliation / notes (optional)", reg_note_ph:"e.g. INSAIT, internal pilot, etc.",
|
| 472 |
reg_continue:"Continue →",
|
| 473 |
+
help_title:"How to rate",
|
| 474 |
+
help_dismiss:"Got it",
|
| 475 |
+
help_body_html:"<p>For each case watch all videos via the <b>A / B / C</b> tabs at the top, then rate each one on every sub-question below. Slot order is shuffled per rater but stable within a case.</p><h4 style='color:var(--accent);margin-top:14px;font-size:13px'>Likert (1 = worst, 5 = best)</h4><p>1 Very poor · 2 Poor · 3 Fair · 4 Good · 5 Excellent</p><h4 style='color:var(--accent);margin-top:14px;font-size:13px'>3 dimensions × 9 sub-questions</h4><ul style='padding-left:18px;margin:6px 0'><li><b>Instruction following</b> — re-read the prompt, especially the red-highlighted phrases.</li><li><b>Temporal consistency</b> — focus on how characters, objects, and environment change across frames.</li><li><b>Realism</b> — notice obvious out-of-place / unnatural moments.</li></ul><h4 style='color:var(--accent);margin-top:14px;font-size:13px'>Tips</h4><ul style='padding-left:18px;margin:6px 0'><li><b>Click 💾 to save progress at any time.</b> Click <b>Submit study</b> once everything is rated — otherwise your scores don't count.</li><li>For BGM / subtitle / sound questions, unmute the video first.</li><li>Score motion logic / camera low if the video has little to no movement.</li></ul>",
|
| 476 |
reg_foot:"Submissions are written to the <code>dehezhang2/Frameworker_User_Study</code> dataset on Hugging Face.",
|
| 477 |
reg_err_name:"Please enter your name.",
|
| 478 |
reg_err_email:"Please enter a valid email address.",
|
|
|
|
| 512 |
reg_email:"邮箱", reg_email_ph:"例如:xiaoming@example.com",
|
| 513 |
reg_note:"所属单位 / 备注(可选)", reg_note_ph:"例如:INSAIT、内部预测试 等",
|
| 514 |
reg_continue:"继续 →",
|
| 515 |
+
help_title:"评分说明",
|
| 516 |
+
help_dismiss:"知道了",
|
| 517 |
+
help_body_html:"<p>每个案例,先在顶部的 <b>A / B / C</b> 视频标签切换观看每个视频,然后在下方对每个视频的每个子问题打分。视频顺序按评分人随机分配,但同一案例内保持一致。</p><h4 style='color:var(--accent);margin-top:14px;font-size:13px'>李克特量表(1 = 最差,5 = 最佳)</h4><p>1 很差 · 2 差 · 3 一般 · 4 好 · 5 极佳</p><h4 style='color:var(--accent);margin-top:14px;font-size:13px'>3 个维度 × 9 个子问题</h4><ul style='padding-left:18px;margin:6px 0'><li><b>指令遵循</b> — 请先看清提示词,尤其是标红的部分。</li><li><b>时间一致性</b> — 关注人物、物品和环境在帧间的变化。</li><li><b>真实感</b> — 留意视频中不和谐或有明显问题的地方。</li></ul><h4 style='color:var(--accent);margin-top:14px;font-size:13px'>操作提示</h4><ul style='padding-left:18px;margin:6px 0'><li><b>随时点击 💾 保存进度;</b>全部完成后必须点击「提交研究」,否则评分不会被计入。</li><li>BGM / 字幕 / 配乐 等问题请先打开视频声音聆听。</li><li>运动逻辑 / 相机运动 若几乎没有运动,请打低分。</li></ul>",
|
| 518 |
reg_foot:"提交将写入 Hugging Face 上的 <code>dehezhang2/Frameworker_User_Study</code> 数据集。",
|
| 519 |
reg_err_name:"请输入您的姓名。",
|
| 520 |
reg_err_email:"请输入有效的邮箱地址。",
|
|
|
|
| 554 |
reg_email:"Имейл", reg_email_ph:"напр. alex@example.com",
|
| 555 |
reg_note:"Принадлежност / бележки (по избор)", reg_note_ph:"напр. INSAIT, вътрешен пилот",
|
| 556 |
reg_continue:"Продължи →",
|
| 557 |
+
help_title:"Как се оценява",
|
| 558 |
+
help_dismiss:"Разбрах",
|
| 559 |
+
help_body_html:"<p>За всеки случай гледайте всички видеа чрез табовете <b>A / B / C</b> отгоре, след това оценете всяко по всеки под-въпрос отдолу.</p><h4 style='color:var(--accent);margin-top:14px;font-size:13px'>Ликерт (1 = най-лошо, 5 = най-добро)</h4><p>1 Много слабо · 2 Слабо · 3 Средно · 4 Добро · 5 Отлично</p><h4 style='color:var(--accent);margin-top:14px;font-size:13px'>3 измерения × 9 под-въпроса</h4><ul style='padding-left:18px;margin:6px 0'><li><b>Следване на инструкции</b> — прочетете подканата, особено маркираните в червено фрази.</li><li><b>Времева съгласуваност</b> — съсредоточете се върху промените на хора, обекти и среда между кадрите.</li><li><b>Реализъм</b> — забележете неестествени моменти.</li></ul><h4 style='color:var(--accent);margin-top:14px;font-size:13px'>Съвети</h4><ul style='padding-left:18px;margin:6px 0'><li><b>Щракнете 💾, за да запазите прогрес по всяко време;</b> щракнете <b>Изпрати проучването</b> накрая — иначе оценките не се броят.</li><li>За въпроси относно BGM / субтитри / звук включете звука първо.</li><li>Дайте нисък резултат за логика на движението / камера, ако има малко движение.</li></ul>",
|
| 560 |
reg_foot:"Изпращанията се записват в <code>dehezhang2/Frameworker_User_Study</code> на Hugging Face.",
|
| 561 |
reg_err_name:"Моля, въведете името си.",
|
| 562 |
reg_err_email:"Моля, въведете валиден имейл адрес.",
|
|
|
|
| 1316 |
applyRegistrationI18n();
|
| 1317 |
}
|
| 1318 |
function closeRegister(){ document.getElementById("loginOverlay").classList.add("hidden"); }
|
| 1319 |
+
|
| 1320 |
+
/* ----- help / 评分说明 overlay (mobile only) ----- */
|
| 1321 |
+
const HELP_SEEN_KEY = "user_study_help_seen_v1";
|
| 1322 |
+
function openHelp(){
|
| 1323 |
+
applyHelpI18n();
|
| 1324 |
+
document.getElementById("helpOverlay").classList.remove("hidden");
|
| 1325 |
+
}
|
| 1326 |
+
function closeHelp(){
|
| 1327 |
+
document.getElementById("helpOverlay").classList.add("hidden");
|
| 1328 |
+
try { localStorage.setItem(HELP_SEEN_KEY, "1"); } catch(e){}
|
| 1329 |
+
}
|
| 1330 |
+
function applyHelpI18n(){
|
| 1331 |
+
const h = document.getElementById("helpHeader");
|
| 1332 |
+
if (h) h.textContent = t("help_title");
|
| 1333 |
+
const body = document.getElementById("helpBody");
|
| 1334 |
+
if (body) body.innerHTML = t("help_body_html");
|
| 1335 |
+
const btn = document.getElementById("helpDismissText");
|
| 1336 |
+
if (btn) btn.textContent = t("help_dismiss");
|
| 1337 |
+
}
|
| 1338 |
function applyRegistrationI18n(){
|
| 1339 |
document.getElementById("regHeader").textContent = t("reg_title");
|
| 1340 |
document.getElementById("regLead").textContent = t("reg_lead");
|
|
|
|
| 1441 |
|
| 1442 |
// wire DOM events
|
| 1443 |
document.getElementById("drawerBtn").onclick = openDrawer;
|
| 1444 |
+
document.getElementById("helpBtn").onclick = openHelp;
|
| 1445 |
+
document.getElementById("helpCloseBtn").onclick = closeHelp;
|
| 1446 |
+
document.getElementById("helpDismissBtn").onclick = closeHelp;
|
| 1447 |
document.getElementById("drawerCloseBtn").onclick = closeDrawer;
|
| 1448 |
document.getElementById("drawerBackdrop").onclick = closeDrawer;
|
| 1449 |
document.getElementById("prevBtn").onclick = () => step(-1);
|
|
|
|
| 1477 |
renderShell();
|
| 1478 |
closeRegister();
|
| 1479 |
probeSync();
|
| 1480 |
+
// Auto-open the rubric popup once per device. The user can manually
|
| 1481 |
+
// reopen it any time via the "?" header button.
|
| 1482 |
+
try {
|
| 1483 |
+
if (localStorage.getItem(HELP_SEEN_KEY) !== "1") openHelp();
|
| 1484 |
+
} catch (e) {}
|
| 1485 |
}
|
| 1486 |
// Always fetch admin-curated highlights; available even before registration
|
| 1487 |
// gate clears so the prompt shows highlights as soon as the rater enters.
|