|
137 | 137 | scrollToIndex(cursorIndex) |
138 | 138 | } |
139 | 139 |
|
| 140 | + /** Refresh all shares (used by ⌘R shortcut). */ |
| 141 | + export function refresh() { |
| 142 | + handleRefreshClick() |
| 143 | + } |
| 144 | +
|
140 | 145 | /** Find a host by name, returns its index or -1. */ |
141 | 146 | // noinspection JSUnusedGlobalSymbols -- used dynamically |
142 | 147 | export function findItemIndex(name: string): number { |
143 | 148 | return hosts.findIndex((h) => h.name.toLowerCase() === name.toLowerCase()) |
144 | 149 | } |
145 | 150 |
|
| 151 | + /** Check for ⌘R refresh shortcut */ |
| 152 | + function isRefreshShortcut(e: KeyboardEvent): boolean { |
| 153 | + return e.key === 'r' && e.metaKey && !e.shiftKey && !e.altKey && !e.ctrlKey |
| 154 | + } |
| 155 | +
|
146 | 156 | // Handle keyboard navigation |
147 | 157 | // noinspection JSUnusedGlobalSymbols -- used dynamically |
148 | 158 | export function handleKeyDown(e: KeyboardEvent): boolean { |
| 159 | + // ⌘R to refresh — works regardless of host count |
| 160 | + if (isRefreshShortcut(e)) { |
| 161 | + e.preventDefault() |
| 162 | + handleRefreshClick() |
| 163 | + return true |
| 164 | + } |
| 165 | +
|
149 | 166 | if (hosts.length === 0) return false |
150 | 167 |
|
151 | 168 | // Try centralized navigation shortcuts first (PageUp, PageDown, Home, End, Option+arrows) |
|
408 | 425 | </div> |
409 | 426 |
|
410 | 427 | {#if hosts.length > 0} |
411 | | - <div class="refresh-section"> |
412 | | - <Button variant="secondary" onclick={handleRefreshClick}>🔄 Refresh</Button> |
413 | | - </div> |
| 428 | + <button class="network-status-bar" onclick={handleRefreshClick} aria-label="Refresh network hosts"> |
| 429 | + <span class="status-text">{hosts.length} {hosts.length === 1 ? 'host' : 'hosts'}</span> |
| 430 | + <span class="refresh-hint">Press ⌘R or click here to refresh</span> |
| 431 | + </button> |
414 | 432 | {/if} |
415 | 433 | </div> |
416 | 434 |
|
|
549 | 567 | cursor: help; |
550 | 568 | } |
551 | 569 |
|
552 | | - .refresh-section { |
| 570 | + .network-status-bar { |
553 | 571 | display: flex; |
554 | | - justify-content: center; |
555 | | - padding: var(--spacing-lg) var(--spacing-sm); |
556 | | - border-top: 1px solid var(--color-border-subtle); |
| 572 | + align-items: center; |
| 573 | + gap: 8px; |
| 574 | + width: 100%; |
| 575 | + padding: var(--spacing-xs) var(--spacing-sm); |
| 576 | + font-family: var(--font-system), sans-serif; |
| 577 | + font-size: calc(var(--font-size-sm) * 0.95); |
| 578 | + color: var(--color-text-secondary); |
| 579 | + background-color: var(--color-bg-secondary); |
| 580 | + border: none; |
| 581 | + border-top: 1px solid var(--color-border-strong); |
| 582 | + min-height: 1.5em; |
| 583 | + text-align: left; |
| 584 | + } |
| 585 | +
|
| 586 | + .status-text { |
| 587 | + flex: 1 1 0; |
| 588 | + min-width: 0; |
| 589 | + white-space: nowrap; |
| 590 | + overflow: hidden; |
| 591 | + text-overflow: ellipsis; |
| 592 | + } |
| 593 | +
|
| 594 | + .refresh-hint { |
| 595 | + flex-shrink: 0; |
| 596 | + margin-left: auto; |
| 597 | + padding-left: var(--spacing-md); |
| 598 | + color: var(--color-text-tertiary); |
| 599 | + white-space: nowrap; |
557 | 600 | } |
558 | 601 | </style> |
0 commit comments