mirror of
https://github.com/nimbold/Firelink.git
synced 2026-08-09 18:59:36 +00:00
fix: default logs off, suppress webview context menu, sort queue rows, defer keychain access to user action
- Disable log capture by default in both backend (LOG_PAUSED=true) and frontend (isPaused=true) to avoid unnecessary disk I/O and battery drain. - Add a global contextmenu listener that prevents the webview's default right-click menu (Reload, etc.) so the app behaves like a native macOS window. Custom context menus in DownloadItem, LogsView, and Sidebar still work because their handlers preventDefault() before the document listener fires. - Sort the download table by queuePosition when viewing a specific queue so the move-up/down controls produce a visible reorder instead of a silent position swap with no UI feedback. - Rework the keychain access flow to eliminate the OS credential prompt that appeared before the app's own KeychainPermissionModal after every binary update. hydrate_extension_pairing_token now always skips the keychain; only the explicit Grant Access button (grant_keychain_access) triggers the OS prompt, which is user-initiated and therefore acceptable even when macOS trust resets after a code-signature change.
This commit is contained in:
@@ -182,6 +182,12 @@ export const DownloadTable: React.FC<DownloadTableProps> = ({ filter }) => {
|
||||
default: return d.category === filter;
|
||||
}
|
||||
});
|
||||
|
||||
// Sort by queue position when viewing a specific queue so the visual
|
||||
// order matches the queue order and move-up/down buttons reflect reality.
|
||||
const sortedDownloads = filter.startsWith('queue:')
|
||||
? [...filteredDownloads].sort((left, right) => (left.queuePosition ?? 0) - (right.queuePosition ?? 0))
|
||||
: filteredDownloads;
|
||||
const handleItemClick = (e: React.MouseEvent, item: DownloadItem) => {
|
||||
if (e.metaKey || e.ctrlKey) {
|
||||
const newSelected = new Set(selectedIds);
|
||||
@@ -193,8 +199,8 @@ export const DownloadTable: React.FC<DownloadTableProps> = ({ filter }) => {
|
||||
setSelectedIds(newSelected);
|
||||
setLastSelectedId(item.id);
|
||||
} else if (e.shiftKey && lastSelectedId) {
|
||||
const currentIndex = filteredDownloads.findIndex(d => d.id === item.id);
|
||||
const lastIndex = filteredDownloads.findIndex(d => d.id === lastSelectedId);
|
||||
const currentIndex = sortedDownloads.findIndex(d => d.id === item.id);
|
||||
const lastIndex = sortedDownloads.findIndex(d => d.id === lastSelectedId);
|
||||
|
||||
if (currentIndex !== -1 && lastIndex !== -1) {
|
||||
const start = Math.min(currentIndex, lastIndex);
|
||||
@@ -202,7 +208,7 @@ export const DownloadTable: React.FC<DownloadTableProps> = ({ filter }) => {
|
||||
|
||||
const newSelected = new Set(selectedIds);
|
||||
for (let i = start; i <= end; i++) {
|
||||
newSelected.add(filteredDownloads[i].id);
|
||||
newSelected.add(sortedDownloads[i].id);
|
||||
}
|
||||
setSelectedIds(newSelected);
|
||||
}
|
||||
@@ -290,9 +296,9 @@ export const DownloadTable: React.FC<DownloadTableProps> = ({ filter }) => {
|
||||
|
||||
<button
|
||||
className="main-control-button"
|
||||
disabled={filteredDownloads.length === 0}
|
||||
disabled={sortedDownloads.length === 0}
|
||||
onClick={() => {
|
||||
filteredDownloads
|
||||
sortedDownloads
|
||||
.filter(d => canStartDownload(d.status))
|
||||
.forEach(d => handleResume(d));
|
||||
}}
|
||||
@@ -303,9 +309,9 @@ export const DownloadTable: React.FC<DownloadTableProps> = ({ filter }) => {
|
||||
|
||||
<button
|
||||
className="main-control-button"
|
||||
disabled={filteredDownloads.length === 0}
|
||||
disabled={sortedDownloads.length === 0}
|
||||
onClick={() => {
|
||||
filteredDownloads.filter(d => canPauseDownload(d.status)).forEach(d => handlePause(d.id));
|
||||
sortedDownloads.filter(d => canPauseDownload(d.status)).forEach(d => handlePause(d.id));
|
||||
}}
|
||||
title="Pause All"
|
||||
>
|
||||
@@ -317,12 +323,12 @@ export const DownloadTable: React.FC<DownloadTableProps> = ({ filter }) => {
|
||||
<div className="downloads-content-header">
|
||||
<div className="downloads-title">
|
||||
{getFilterTitle()}
|
||||
<span className="downloads-count">{filteredDownloads.length}</span>
|
||||
<span className="downloads-count">{sortedDownloads.length}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="downloads-table flex-1 flex flex-col">
|
||||
{filteredDownloads.length === 0 ? (
|
||||
{sortedDownloads.length === 0 ? (
|
||||
<div className="downloads-empty-state">
|
||||
<ArrowDownCircle aria-hidden="true" />
|
||||
<div className="downloads-empty-title">No Downloads</div>
|
||||
@@ -357,7 +363,7 @@ export const DownloadTable: React.FC<DownloadTableProps> = ({ filter }) => {
|
||||
|
||||
<div className="download-table-body">
|
||||
<div className="download-table-list">
|
||||
{filteredDownloads.map((d, index) => (
|
||||
{sortedDownloads.map((d, index) => (
|
||||
<DownloadItemComponent
|
||||
key={d.id}
|
||||
downloadId={d.id}
|
||||
|
||||
Reference in New Issue
Block a user