|
309 | 309 | let container: HTMLDivElement | undefined = $state(); |
310 | 310 | let scrollTop = $state(0); |
311 | 311 | let viewportHeight = $state(600); |
| 312 | + let viewportWidth = $state(800); |
| 313 | +
|
| 314 | + // Right-side columns (author + sha + date) and the minimum width we always |
| 315 | + // reserve for the commit message. These mirror the fixed column widths in the |
| 316 | + // CSS below. |
| 317 | + const RIGHT_COLS_WIDTH = 120 + 75 + 160; |
| 318 | + const MIN_MESSAGE_WIDTH = 120; |
| 319 | +
|
| 320 | + // In huge repos (e.g. nixpkgs) hundreds of concurrent branches make the graph |
| 321 | + // grow wider than the whole viewport, which would push the commit message off |
| 322 | + // screen and break column alignment. Cap the graph at whatever space is left |
| 323 | + // after the message + right columns; lanes beyond the cap are clipped. |
| 324 | + let maxGraphWidth = $derived( |
| 325 | + Math.max(120, viewportWidth - RIGHT_COLS_WIDTH - MIN_MESSAGE_WIDTH) |
| 326 | + ); |
312 | 327 |
|
313 | 328 | // Scroll to search result when navigating |
314 | 329 | $effect(() => { |
|
331 | 346 | if (displayLeftMargin.length > 0) { |
332 | 347 | let maxMargin = 0; |
333 | 348 | for (const m of displayLeftMargin) if (m > maxMargin) maxMargin = m; |
334 | | - return Math.ceil(maxMargin * X_SCALE) + 4; |
| 349 | + return Math.min(Math.ceil(maxMargin * X_SCALE) + 4, maxGraphWidth); |
335 | 350 | } |
336 | 351 | return 30; |
337 | 352 | }); |
|
404 | 419 | function handleResize() { |
405 | 420 | if (container) { |
406 | 421 | viewportHeight = container.clientHeight; |
| 422 | + viewportWidth = container.clientWidth; |
407 | 423 | } |
408 | 424 | } |
409 | 425 |
|
|
785 | 801 | $effect(() => { |
786 | 802 | if (container) { |
787 | 803 | viewportHeight = container.clientHeight; |
| 804 | + viewportWidth = container.clientWidth; |
788 | 805 | } |
789 | 806 | }); |
790 | 807 | </script> |
|
821 | 838 | <svg |
822 | 839 | class="graph-lines" |
823 | 840 | width={graphWidth} |
824 | | - style="position: absolute; top: 0; height: {totalHeight}px; overflow: visible;" |
| 841 | + style="position: absolute; top: 0; height: {totalHeight}px; overflow: hidden;" |
825 | 842 | > |
826 | 843 | <!-- Paths: continuous branch lines --> |
827 | 844 | {#each visiblePaths as path} |
|
958 | 975 | } |
959 | 976 | }} |
960 | 977 | > |
961 | | - <div class="col-message" style="padding-left: {(displayLeftMargin[index] ?? graphWidth) * X_SCALE + 4}px;"> |
| 978 | + <div class="col-message" style="padding-left: {Math.min((displayLeftMargin[index] ?? graphWidth) * X_SCALE + 4, maxGraphWidth)}px;"> |
962 | 979 | {#if currentBranchLocalOnly.has(commit.hash)} |
963 | 980 | <span class="local-dot" use:tooltip={t('graph.notPushed')}></span> |
964 | 981 | {:else if currentBranchRemoteAhead.has(commit.hash)} |
|
1087 | 1104 | <span class="commit-subject truncate" use:tooltip={commit.subject}>{commit.subject}</span> |
1088 | 1105 | {/if} |
1089 | 1106 | </div> |
1090 | | - <div class="col-author truncate" use:tooltip={commit.author.name}> |
| 1107 | + <div class="col-author" use:tooltip={commit.author.name}> |
1091 | 1108 | {#if commit.hash !== 'UNCOMMITTED'} |
1092 | 1109 | <img class="avatar-sm" src={getGravatarUrl(commit.author.email, 20)} alt="" loading="lazy" /> |
1093 | | - {commit.author.name} |
| 1110 | + <span class="author-name truncate">{commit.author.name}</span> |
1094 | 1111 | {/if} |
1095 | 1112 | </div> |
1096 | 1113 | <div class="col-hash" use:tooltip={commit.hash !== 'UNCOMMITTED' ? commit.hash : ''}>{commit.hash !== 'UNCOMMITTED' ? commit.abbreviatedHash : ''}</div> |
|
1462 | 1479 | flex-shrink: 0; |
1463 | 1480 | } |
1464 | 1481 |
|
| 1482 | + /* Flex item must allow shrinking below content size for ellipsis to engage. */ |
| 1483 | + .author-name { |
| 1484 | + min-width: 0; |
| 1485 | + } |
| 1486 | +
|
1465 | 1487 | .commit-row.selected .col-author, |
1466 | 1488 | .commit-row.selected .col-date, |
1467 | 1489 | .commit-row.selected .col-hash { |
|
1475 | 1497 | padding: 0 10px; |
1476 | 1498 | color: var(--text-secondary); |
1477 | 1499 | white-space: nowrap; |
1478 | | - text-align: right; |
| 1500 | + text-align: left; |
1479 | 1501 | } |
1480 | 1502 |
|
1481 | 1503 | .col-hash { |
|
1484 | 1506 | padding: 0 10px; |
1485 | 1507 | font-family: var(--vscode-editor-font-family, monospace); |
1486 | 1508 | color: var(--text-secondary); |
| 1509 | + /* Large repos abbreviate hashes to 10-12 chars; clip so they never spill |
| 1510 | + into the date column. */ |
| 1511 | + overflow: hidden; |
| 1512 | + text-overflow: ellipsis; |
| 1513 | + white-space: nowrap; |
1487 | 1514 | } |
1488 | 1515 |
|
1489 | 1516 | .commit-subject { |
|
0 commit comments