mirror of
https://github.com/nimbold/Firelink.git
synced 2026-08-20 08:02:16 +00:00
fix: resolve double-click and redownload issues
- Use `e.detail === 2` for double clicks in `DownloadTable.tsx` - Add `user-select: none` to list items in `index.css` - Delete existing assets before enqueueing in `redownload` action - Remove redundant `onDoubleClick` props from `DownloadItem.tsx`
This commit is contained in:
@@ -13,7 +13,6 @@ interface DownloadItemProps {
|
|||||||
setContextMenu: (menu: { x: number; y: number; id: string }) => void;
|
setContextMenu: (menu: { x: number; y: number; id: string }) => void;
|
||||||
handlePause: (id: string) => void;
|
handlePause: (id: string) => void;
|
||||||
handleResume: (item: DownloadItemType) => void;
|
handleResume: (item: DownloadItemType) => void;
|
||||||
handleDoubleClick: (item: DownloadItemType) => void;
|
|
||||||
getCategoryIcon: (category: string) => React.ReactNode;
|
getCategoryIcon: (category: string) => React.ReactNode;
|
||||||
isSelected: boolean;
|
isSelected: boolean;
|
||||||
onClick: (e: React.MouseEvent, item: DownloadItemType) => void;
|
onClick: (e: React.MouseEvent, item: DownloadItemType) => void;
|
||||||
@@ -26,7 +25,6 @@ export const DownloadItem = React.memo<DownloadItemProps>(({
|
|||||||
setContextMenu,
|
setContextMenu,
|
||||||
handlePause,
|
handlePause,
|
||||||
handleResume,
|
handleResume,
|
||||||
handleDoubleClick,
|
|
||||||
getCategoryIcon,
|
getCategoryIcon,
|
||||||
isSelected,
|
isSelected,
|
||||||
onClick,
|
onClick,
|
||||||
@@ -90,7 +88,6 @@ export const DownloadItem = React.memo<DownloadItemProps>(({
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setContextMenu({ x: e.clientX, y: e.clientY, id: download.id });
|
setContextMenu({ x: e.clientX, y: e.clientY, id: download.id });
|
||||||
}}
|
}}
|
||||||
onDoubleClick={() => handleDoubleClick(download)}
|
|
||||||
>
|
>
|
||||||
<div className="download-file-cell">
|
<div className="download-file-cell">
|
||||||
<span className="shrink-0 text-text-muted">
|
<span className="shrink-0 text-text-muted">
|
||||||
|
|||||||
@@ -189,6 +189,10 @@ export const DownloadTable: React.FC<DownloadTableProps> = ({ filter }) => {
|
|||||||
? [...filteredDownloads].sort((left, right) => (left.queuePosition ?? 0) - (right.queuePosition ?? 0))
|
? [...filteredDownloads].sort((left, right) => (left.queuePosition ?? 0) - (right.queuePosition ?? 0))
|
||||||
: filteredDownloads;
|
: filteredDownloads;
|
||||||
const handleItemClick = (e: React.MouseEvent, item: DownloadItem) => {
|
const handleItemClick = (e: React.MouseEvent, item: DownloadItem) => {
|
||||||
|
if (e.detail === 2) {
|
||||||
|
handleDownloadDoubleClick(item);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (e.metaKey || e.ctrlKey) {
|
if (e.metaKey || e.ctrlKey) {
|
||||||
const newSelected = new Set(selectedIds);
|
const newSelected = new Set(selectedIds);
|
||||||
if (newSelected.has(item.id)) {
|
if (newSelected.has(item.id)) {
|
||||||
@@ -372,7 +376,6 @@ export const DownloadTable: React.FC<DownloadTableProps> = ({ filter }) => {
|
|||||||
setContextMenu={handleContextMenu}
|
setContextMenu={handleContextMenu}
|
||||||
handlePause={handlePause}
|
handlePause={handlePause}
|
||||||
handleResume={handleResume}
|
handleResume={handleResume}
|
||||||
handleDoubleClick={handleDownloadDoubleClick}
|
|
||||||
getCategoryIcon={getCategoryIcon}
|
getCategoryIcon={getCategoryIcon}
|
||||||
isSelected={selectedIds.has(d.id)}
|
isSelected={selectedIds.has(d.id)}
|
||||||
onClick={handleItemClick}
|
onClick={handleItemClick}
|
||||||
|
|||||||
@@ -1497,6 +1497,8 @@
|
|||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
color: hsl(var(--text-primary));
|
color: hsl(var(--text-primary));
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
user-select: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
html[data-list-density="compact"] .download-row,
|
html[data-list-density="compact"] .download-row,
|
||||||
|
|||||||
@@ -470,55 +470,31 @@ export const useDownloadStore = create<DownloadState>((set, get) => ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const url = targetItem.url?.trim();
|
const url = targetItem.url?.trim();
|
||||||
if (!url) {
|
if (!url) throw new Error('Cannot redownload: original URL is missing.');
|
||||||
throw new Error('Cannot redownload: original URL is missing.');
|
|
||||||
|
// Remove from backend to clear its state and delete the existing file so we can overwrite
|
||||||
|
try {
|
||||||
|
await invoke('remove_download', { id, deleteAssets: true });
|
||||||
|
get().unregisterBackendIds([id]);
|
||||||
|
} catch (e) {
|
||||||
|
console.warn("Could not remove old download from backend", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
const filename = targetItem.fileName?.trim();
|
get().updateDownload(id, {
|
||||||
if (!filename) {
|
|
||||||
throw new Error('Cannot redownload: original filename is missing.');
|
|
||||||
}
|
|
||||||
|
|
||||||
const mediaFormatSelector = targetItem.mediaFormatSelector?.trim();
|
|
||||||
|
|
||||||
const settings = useSettingsStore.getState();
|
|
||||||
const destPath = targetItem.destination ||
|
|
||||||
await resolveCategoryDestination(settings, targetItem.category);
|
|
||||||
|
|
||||||
if (!destPath.trim()) {
|
|
||||||
throw new Error('Cannot redownload: destination folder is missing.');
|
|
||||||
}
|
|
||||||
|
|
||||||
const redownloadItem: DownloadItem = {
|
|
||||||
id: crypto.randomUUID(),
|
|
||||||
url,
|
|
||||||
fileName: filename,
|
|
||||||
status: 'queued',
|
status: 'queued',
|
||||||
category: targetItem.category,
|
fraction: 0,
|
||||||
dateAdded: new Date().toISOString(),
|
speed: '-',
|
||||||
connections: targetItem.connections,
|
eta: '-',
|
||||||
speedLimit: targetItem.speedLimit,
|
hasBeenDispatched: false,
|
||||||
username: targetItem.username,
|
dateAdded: Date.now().toString()
|
||||||
password: targetItem.password,
|
});
|
||||||
headers: targetItem.headers,
|
|
||||||
checksum: targetItem.checksum,
|
|
||||||
cookies: targetItem.cookies,
|
|
||||||
mirrors: targetItem.mirrors,
|
|
||||||
destination: destPath,
|
|
||||||
isMedia: targetItem.isMedia,
|
|
||||||
mediaFormatSelector,
|
|
||||||
queueId: targetItem.queueId || MAIN_QUEUE_ID,
|
|
||||||
hasBeenDispatched: false
|
|
||||||
};
|
|
||||||
|
|
||||||
set((state) => ({
|
if (!await dispatchItem(id)) {
|
||||||
downloads: [...state.downloads, redownloadItem]
|
|
||||||
}));
|
|
||||||
|
|
||||||
if (!await dispatchItem(redownloadItem.id)) {
|
|
||||||
console.error("Failed to enqueue redownload");
|
console.error("Failed to enqueue redownload");
|
||||||
|
get().updateDownload(id, { status: 'failed' });
|
||||||
} else {
|
} else {
|
||||||
info(`Download ${id} redownload requested as ${redownloadItem.id} (queued)`);
|
get().updateDownload(id, { hasBeenDispatched: true });
|
||||||
|
info(`Download ${id} redownloaded (queued)`);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
resumeDownload: async (id) => {
|
resumeDownload: async (id) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user