Release 0.2.2 — browse submitted changelists, People & Roles, AI summaries

- History: GitHub-style split view of submitted changelists; preview file
  contents at their exact revision (code/image/3D/uasset) via `p4 print`
- People & Roles modal: who works on the depot, activity indicators,
  group/role assignment (p4 users / groups / group -i)
- AI commit summaries via OpenRouter (sparkle button); key/model in Settings
- Commit-message draft persists until Submit (not cleared on local commit)
- Resizable History file-list column (pointer-capture drag)
- Fix UI-scale leaving a gap at the bottom (compensate zoom in .win height)
- Author avatars on history rows; bump version to 0.2.2

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Bonchellon
2026-07-07 18:18:07 +03:00
parent 168b6afab3
commit 8e2cac4437
12 changed files with 613 additions and 46 deletions

View File

@ -32,7 +32,9 @@ body{
}
button{font-family:var(--font)}
.win{height:100vh;width:100%;display:flex;flex-direction:column;
/* height divided by the zoom factor: CSS `zoom` shrinks the box but `vh` still
measures the unzoomed viewport, so without this a gap grows below at zoom<1 */
.win{height:calc(100vh / var(--zoom,1));width:100%;display:flex;flex-direction:column;
background:linear-gradient(180deg,var(--win-a),var(--win-b));overflow:hidden}
/* titlebar + inline menu */
@ -556,6 +558,23 @@ body.resizing{cursor:col-resize!important;user-select:none}
/* virtualized changelist-file row (History detail) */
.crow{position:absolute;left:0;right:0;height:52px;display:flex;gap:12px;align-items:center;padding:0 16px;border-bottom:1px solid var(--border-soft)}
.crow:hover{background:var(--hover)}
.crow.click{cursor:pointer}
.crow.click:hover .crow-go{opacity:1;transform:translateX(0)}
.crow.sel{background:rgba(124,110,246,.12);box-shadow:inset 2px 0 0 var(--accent)}
.crow-go{margin-left:auto;flex:0 0 auto;color:var(--faint);font-size:18px;line-height:1;opacity:0;transform:translateX(-4px);transition:opacity .12s,transform .12s;display:flex;align-items:center}
.crow-go svg{width:16px;height:16px}
.gbtn.back{padding:6px 8px}.gbtn.back svg{width:16px;height:16px}
/* History = GitHub-style split: changed-files list beside the file content (no covering) */
.histsplit{display:flex;min-width:0;min-height:0;overflow:hidden}
.histsplit>.right{flex:1 1 auto;min-width:0}
/* explicit width via a state-driven CSS variable */
.histsplit>.histlist{flex:none;width:var(--hist-w,340px);min-width:0;border-right:1px solid var(--border)}
.histsplit.solo>.histlist{flex:1 1 auto;width:auto;border-right:none} /* nothing open → list fills the panel */
/* plain in-flow 8px column between list and preview — only the cursor hints it's draggable.
position MUST override the base .vhandle{position:absolute}, or it falls out of the flex flow */
.histsplit>.histh{position:relative;flex:none;width:8px;align-self:stretch;cursor:col-resize;background:transparent;top:auto;bottom:auto}
.histsplit .histlist .crow-go{opacity:0}
.histsplit .histlist .crow.sel .crow-go{opacity:1;transform:translateX(0)}
.hnum{font-family:var(--mono);font-size:12px;color:var(--accent-2);font-variant-numeric:tabular-nums;flex:0 0 auto;padding-top:1px}
.hbody{display:flex;flex-direction:column;gap:3px;min-width:0}
.hdesc{font-size:13px;color:var(--txt);overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}
@ -638,3 +657,68 @@ body.resizing{cursor:col-resize!important;user-select:none}
animation:toastin .25s ease;white-space:pre-wrap;text-align:center}
.toast.err{border-color:rgba(242,99,126,.4);color:var(--del)}
@keyframes toastin{from{opacity:0;transform:translate(-50%,10px)}to{opacity:1;transform:translate(-50%,0)}}
/* ---------------- avatars ---------------- */
.avatar{position:relative;flex:0 0 auto;border-radius:50%;display:grid;place-items:center;color:#fff;font-weight:700;letter-spacing:.02em;text-transform:uppercase;box-shadow:inset 0 0 0 1px rgba(255,255,255,.14);user-select:none}
.adot{position:absolute;right:-1px;bottom:-1px;width:9px;height:9px;border-radius:50%;border:2px solid var(--elevated);background:var(--faint)}
.adot.active{background:#3ecb8f}.adot.recent{background:#f4c04e}.adot.idle{background:#6b6b7a}
/* ---------------- AI commit summary ---------------- */
.summrow{display:flex;gap:8px;align-items:stretch}
.aibtn{flex:0 0 auto;display:flex;align-items:center;gap:6px;border:1px solid var(--border);border-radius:9px;padding:0 12px;
font-size:12px;font-weight:600;font-family:var(--font);cursor:pointer;color:var(--accent-2);
background:linear-gradient(135deg,rgba(124,110,246,.16),rgba(124,110,246,.06));transition:.15s}
.aibtn:hover:not(:disabled){filter:brightness(1.12);border-color:rgba(124,110,246,.5)}
.aibtn:disabled{opacity:.5;cursor:default}
.aibtn svg{width:15px;height:15px}
.aibtn.busy{color:var(--faint)}
.aibtn.icon{padding:0;width:34px;justify-content:center}
/* AI settings block inside Settings modal */
.ai-set{margin-top:16px;padding-top:14px;border-top:1px solid var(--border-soft)}
.ai-set-h{display:flex;align-items:center;gap:8px;font-size:12.5px;font-weight:700;color:var(--txt);margin-bottom:6px}
.ai-set-h svg{width:16px;height:16px;color:var(--accent-2)}
.keyfield{display:flex;align-items:center;gap:6px;flex:1;max-width:230px}
.kf-in{flex:1;min-width:0;background:var(--panel);border:1px solid var(--border);border-radius:8px;padding:6px 9px;font-size:12px;color:var(--txt);outline:none;font-family:var(--font)}
.kf-in.mono{font-family:var(--mono);font-size:11.5px}
.kf-in:focus{border-color:var(--accent)}
.kf-eye{flex:0 0 auto;width:28px;height:28px;border:1px solid var(--border);background:var(--panel);border-radius:8px;cursor:pointer;font-size:13px;line-height:1}
.ai-hint{font-size:11px;color:var(--faint);line-height:1.5;margin-top:8px}
/* ---------------- People & Roles ---------------- */
.picker.wide{width:720px;max-width:94%;height:560px;max-height:82vh;display:flex;flex-direction:column}
.ph-sub{margin-left:8px;font-size:11.5px;color:var(--faint);font-variant-numeric:tabular-nums}
.picker.wide .ph-sub{margin-right:auto}
.ur-body{flex:1;display:flex;min-height:0}
.ur-list{flex:0 0 300px;display:flex;flex-direction:column;border-right:1px solid var(--border-soft);min-height:0}
.ur-filter{display:flex;align-items:center;gap:8px;padding:10px 12px;border-bottom:1px solid var(--border-soft)}
.ur-filter svg{width:15px;height:15px;color:var(--faint);flex:0 0 auto}
.ur-filter input{flex:1;background:none;border:none;outline:none;color:var(--txt);font-size:12.5px;font-family:var(--font)}
.ur-scroll{flex:1;overflow-y:auto;padding:6px}
.ur-row{display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:10px;cursor:pointer;transition:background .12s}
.ur-row:hover{background:var(--hover)}
.ur-row.on{background:rgba(124,110,246,.13);box-shadow:inset 0 0 0 1px rgba(124,110,246,.28)}
.ur-meta{display:flex;flex-direction:column;gap:1px;min-width:0;flex:1}
.ur-name{font-size:13px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:flex;align-items:center;gap:6px}
.ur-you{font-size:9.5px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--accent-2);background:rgba(124,110,246,.16);border-radius:6px;padding:1px 6px}
.ur-sub{font-size:11px;color:var(--faint);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ur-actd{width:8px;height:8px;border-radius:50%;flex:0 0 auto;background:var(--faint)}
.ur-actd.active{background:#3ecb8f;box-shadow:0 0 0 3px rgba(62,203,143,.18)}
.ur-actd.recent{background:#f4c04e}.ur-actd.idle{background:#4b4b58}
.ur-empty{padding:16px;font-size:12px;color:var(--faint);text-align:center}
.ur-detail{flex:1;display:flex;flex-direction:column;min-width:0;overflow-y:auto}
.ur-dhead{display:flex;align-items:center;gap:14px;padding:18px 20px 14px;border-bottom:1px solid var(--border-soft)}
.ur-dinfo{min-width:0}
.ur-dname{font-size:16px;font-weight:700}
.ur-dsub{font-size:12px;color:var(--faint);margin-top:2px}
.ur-grouphd{display:flex;align-items:center;gap:8px;padding:14px 20px 8px;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:var(--faint)}
.ur-groups{display:flex;flex-wrap:wrap;gap:8px;padding:0 20px}
.ur-chip{display:flex;align-items:center;gap:7px;border:1px solid var(--border);background:var(--panel);color:var(--muted);
border-radius:9px;padding:7px 11px;font-size:12.5px;font-weight:500;font-family:var(--font);cursor:pointer;transition:.14s}
.ur-chip:hover:not(:disabled){border-color:var(--accent);color:var(--txt)}
.ur-chip:disabled{opacity:.6;cursor:default}
.ur-chip.on{border-color:rgba(124,110,246,.5);background:rgba(124,110,246,.13);color:var(--txt)}
.urc-box{width:15px;height:15px;border-radius:5px;border:1.5px solid var(--border);display:grid;place-items:center;flex:0 0 auto;background:var(--panel)}
.ur-chip.on .urc-box{background:var(--accent);border-color:var(--accent);color:#fff}
.urc-box svg{width:11px;height:11px}
.ur-detail .ai-hint{padding:12px 20px 20px}