|
399 | 399 | searchStatus = 'idle' |
400 | 400 | } |
401 | 401 |
|
| 402 | + /** Stops the background scan but keeps accumulated matches for browsing. */ |
| 403 | + function stopSearch() { |
| 404 | + stopSearchPoll() |
| 405 | + if (!sessionId) return |
| 406 | + viewerSearchCancel(sessionId).catch(() => {}) |
| 407 | + searchStatus = 'cancelled' |
| 408 | + } |
| 409 | +
|
402 | 410 | // Indexing status polling functions |
403 | 411 | function startIndexingPoll() { |
404 | 412 | stopIndexingPoll() |
|
620 | 628 | windowReady, |
621 | 629 | }) |
622 | 630 | if (searchVisible) { |
623 | | - closeSearch() |
| 631 | + if (searchStatus === 'running') { |
| 632 | + stopSearch() |
| 633 | + } else { |
| 634 | + closeSearch() |
| 635 | + } |
624 | 636 | } else { |
625 | 637 | closeWindow() |
626 | 638 | } |
|
853 | 865 | spellcheck="false" |
854 | 866 | /> |
855 | 867 | <span class="match-count" aria-live="polite"> |
856 | | - {#if searchMatches.length > 0} |
| 868 | + {#if searchStatus === 'running'} |
| 869 | + <span class="spinner spinner-sm search-spinner" aria-hidden="true"></span> |
| 870 | + {#if searchMatches.length > 0} |
| 871 | + {currentMatchIndex + 1} of {searchMatches.length}{searchLimitReached ? '+' : ''} |
| 872 | + · {Math.round(searchProgress * 100)}% |
| 873 | + {:else} |
| 874 | + Searching... {Math.round(searchProgress * 100)}% |
| 875 | + {/if} |
| 876 | + {:else if searchMatches.length > 0} |
857 | 877 | {currentMatchIndex + 1} of {searchMatches.length}{searchLimitReached ? '+' : ''} |
858 | | - {#if searchStatus === 'running'} |
859 | | - ({Math.round(searchProgress * 100)}%) |
| 878 | + {#if searchStatus === 'cancelled'} |
| 879 | + (partial) |
860 | 880 | {/if} |
861 | | - {:else if searchStatus === 'running'} |
862 | | - Searching... {Math.round(searchProgress * 100)}% |
863 | | - {:else if searchQuery && searchStatus === 'done'} |
864 | | - No matches |
| 881 | + {:else if searchQuery && (searchStatus === 'done' || searchStatus === 'cancelled')} |
| 882 | + No matches{searchStatus === 'cancelled' ? ' (partial)' : ''} |
865 | 883 | {/if} |
866 | 884 | </span> |
| 885 | + {#if searchStatus === 'running'} |
| 886 | + <button onclick={stopSearch} aria-label="Stop searching" use:tooltip={'Stop scanning and keep results'} |
| 887 | + >■</button |
| 888 | + > |
| 889 | + {/if} |
867 | 890 | <button |
868 | 891 | onclick={findPrev} |
869 | 892 | disabled={searchMatches.length === 0} |
|
879 | 902 | <button onclick={closeSearch} aria-label="Close search" use:tooltip={{ text: 'Close', shortcut: 'Esc' }} |
880 | 903 | >✕</button |
881 | 904 | > |
| 905 | + {#if searchStatus === 'running'} |
| 906 | + <div |
| 907 | + class="search-progress" |
| 908 | + role="progressbar" |
| 909 | + aria-valuenow={Math.round(searchProgress * 100)} |
| 910 | + aria-valuemin={0} |
| 911 | + aria-valuemax={100} |
| 912 | + > |
| 913 | + <div class="search-progress-fill" style="width: {searchProgress * 100}%"></div> |
| 914 | + </div> |
| 915 | + {/if} |
882 | 916 | </div> |
883 | 917 | {/if} |
884 | 918 |
|
|
973 | 1007 | } |
974 | 1008 |
|
975 | 1009 | .search-bar { |
| 1010 | + position: relative; |
976 | 1011 | display: flex; |
977 | 1012 | align-items: center; |
978 | 1013 | gap: var(--spacing-xs); |
|
1003 | 1038 | font-size: var(--font-size-sm); |
1004 | 1039 | color: var(--color-text-secondary); |
1005 | 1040 | min-width: 70px; |
| 1041 | + white-space: nowrap; |
| 1042 | + } |
| 1043 | +
|
| 1044 | + .search-spinner { |
| 1045 | + vertical-align: text-bottom; |
| 1046 | + margin-right: 2px; |
| 1047 | + } |
| 1048 | +
|
| 1049 | + .search-progress { |
| 1050 | + position: absolute; |
| 1051 | + bottom: 0; |
| 1052 | + left: 0; |
| 1053 | + right: 0; |
| 1054 | + height: 2px; |
| 1055 | + background: var(--color-bg-tertiary); |
| 1056 | + overflow: hidden; |
| 1057 | + } |
| 1058 | +
|
| 1059 | + .search-progress-fill { |
| 1060 | + height: 100%; |
| 1061 | + background: var(--color-accent); |
| 1062 | + transition: width var(--transition-base); |
| 1063 | + } |
| 1064 | +
|
| 1065 | + @media (prefers-reduced-motion: reduce) { |
| 1066 | + .search-progress-fill { |
| 1067 | + transition: none; |
| 1068 | + } |
1006 | 1069 | } |
1007 | 1070 |
|
1008 | 1071 | .search-bar button { |
|
0 commit comments