mirror of
https://github.com/nimbold/Firelink.git
synced 2026-07-26 12:08:27 +00:00
fix(ui): align download list and live properties
This commit is contained in:
@@ -7,15 +7,16 @@ import { open } from '@tauri-apps/plugin-dialog';
|
||||
type LoginMode = 'matching' | 'custom' | 'none';
|
||||
|
||||
export const PropertiesModal = () => {
|
||||
const {
|
||||
selectedPropertiesDownloadId,
|
||||
setSelectedPropertiesDownloadId,
|
||||
updateDownload
|
||||
} = useDownloadStore();
|
||||
const selectedPropertiesDownloadId = useDownloadStore(state => state.selectedPropertiesDownloadId);
|
||||
const setSelectedPropertiesDownloadId = useDownloadStore(state => state.setSelectedPropertiesDownloadId);
|
||||
const updateDownload = useDownloadStore(state => state.updateDownload);
|
||||
const item = useDownloadStore(state =>
|
||||
selectedPropertiesDownloadId
|
||||
? state.downloads.find(d => d.id === selectedPropertiesDownloadId) ?? null
|
||||
: null
|
||||
);
|
||||
|
||||
const { defaultDownloadPath } = useSettingsStore();
|
||||
|
||||
const [item, setItem] = useState<DownloadItem | null>(null);
|
||||
const { defaultDownloadPath, perServerConnections } = useSettingsStore();
|
||||
|
||||
// Form states
|
||||
const [url, setUrl] = useState('');
|
||||
@@ -44,7 +45,6 @@ export const PropertiesModal = () => {
|
||||
if (selectedPropertiesDownloadId) {
|
||||
const activeItem = useDownloadStore.getState().downloads.find(d => d.id === selectedPropertiesDownloadId);
|
||||
if (activeItem) {
|
||||
setItem(activeItem);
|
||||
setUrl(activeItem.url);
|
||||
setFileName(activeItem.fileName);
|
||||
setSaveLocation(activeItem.destination || defaultDownloadPath || '~/Downloads');
|
||||
@@ -83,12 +83,10 @@ export const PropertiesModal = () => {
|
||||
setMirrors(activeItem.mirrors || '');
|
||||
setErrorMessage('');
|
||||
} else {
|
||||
setItem(null);
|
||||
setSelectedPropertiesDownloadId(null);
|
||||
}
|
||||
} else {
|
||||
setItem(null);
|
||||
}
|
||||
}, [selectedPropertiesDownloadId, defaultDownloadPath]);
|
||||
}, [selectedPropertiesDownloadId, defaultDownloadPath, setSelectedPropertiesDownloadId]);
|
||||
|
||||
if (!selectedPropertiesDownloadId || !item) return null;
|
||||
|
||||
@@ -165,15 +163,15 @@ export const PropertiesModal = () => {
|
||||
<div className={`h-1.5 rounded-full transition-all duration-300 ${item.status === 'completed' ? 'bg-green-500' : item.status === 'paused' ? 'bg-orange-500' : item.status === 'failed' ? 'bg-red-500' : 'bg-blue-500'}`} style={{ width: `${(item.status === 'completed' ? 1 : item.fraction || 0) * 100}%` }}></div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-4 gap-y-2 gap-x-4 text-[11px] leading-tight">
|
||||
<div className="flex gap-1.5"><span className="text-text-muted font-medium w-[90px]">Progress</span><span className="text-text-secondary truncate">{item.status === 'completed' ? '100%' : ((item.fraction || 0) * 100).toFixed(0) + '%'}</span></div>
|
||||
<div className="flex gap-1.5"><span className="text-text-muted font-medium w-[40px]">Size</span><span className="text-text-secondary truncate">-</span></div>
|
||||
<div className="flex gap-1.5"><span className="text-text-muted font-medium w-[40px]">Speed</span><span className="text-text-secondary truncate">{item.status === 'completed' ? '-' : item.speed || '-'}</span></div>
|
||||
<div className="flex gap-1.5"><span className="text-text-muted font-medium w-[30px]">ETA</span><span className="text-text-secondary truncate">{item.status === 'completed' ? '-' : item.eta || '-'}</span></div>
|
||||
|
||||
<div className="flex gap-1.5"><span className="text-text-muted font-medium w-[90px]">Live connections</span><span className="text-text-secondary truncate">-</span></div>
|
||||
<div className="flex gap-1.5"><span className="text-text-muted font-medium w-[60px]">Speed cap</span><span className="text-text-secondary truncate">{item.speedLimit || '-'}</span></div>
|
||||
<div className="flex gap-1.5"><span className="text-text-muted font-medium w-[55px]">Category</span><span className="text-text-secondary truncate">{item.category}</span></div>
|
||||
<div className="grid grid-cols-4 gap-y-2 gap-x-4 text-[11px] leading-tight">
|
||||
<div className="flex gap-1.5 min-w-0"><span className="text-text-muted font-medium w-[90px] shrink-0">Progress</span><span className="text-text-secondary truncate">{item.status === 'completed' ? '100%' : ((item.fraction || 0) * 100).toFixed(0) + '%'}</span></div>
|
||||
<div className="flex gap-1.5 min-w-0"><span className="text-text-muted font-medium w-[40px] shrink-0">Size</span><span className="text-text-secondary truncate">{item.size || '-'}</span></div>
|
||||
<div className="flex gap-1.5 min-w-0"><span className="text-text-muted font-medium w-[40px] shrink-0">Speed</span><span className="text-text-secondary truncate">{item.status === 'completed' ? '-' : item.speed || '-'}</span></div>
|
||||
<div className="flex gap-1.5 min-w-0"><span className="text-text-muted font-medium w-[30px] shrink-0">ETA</span><span className="text-text-secondary truncate">{item.status === 'completed' ? '-' : item.eta || '-'}</span></div>
|
||||
|
||||
<div className="flex gap-1.5 min-w-0"><span className="text-text-muted font-medium w-[90px] shrink-0">Connections</span><span className="text-text-secondary truncate">{item.connections || perServerConnections || '-'}</span></div>
|
||||
<div className="flex gap-1.5 min-w-0"><span className="text-text-muted font-medium w-[60px] shrink-0">Speed cap</span><span className="text-text-secondary truncate">{item.speedLimit || '-'}</span></div>
|
||||
<div className="flex gap-1.5 min-w-0"><span className="text-text-muted font-medium w-[55px] shrink-0">Category</span><span className="text-text-secondary truncate">{item.category}</span></div>
|
||||
<div className="flex gap-1.5"><span className="text-text-muted font-medium w-[50px]">Last try</span><span className="text-text-secondary truncate">-</span></div>
|
||||
|
||||
<div className="flex gap-1.5 col-span-2"><span className="text-text-muted font-medium w-[90px]">Date added</span><span className="text-text-secondary truncate">{new Date(item.dateAdded).toLocaleString(undefined, { dateStyle: 'medium', timeStyle: 'short' })}</span></div>
|
||||
|
||||
+22
-18
@@ -962,10 +962,9 @@
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.download-table-header > div:not(:first-child) {
|
||||
border-left: 1px solid hsl(var(--border-color));
|
||||
padding-left: 12px;
|
||||
}
|
||||
.download-table-header > div:not(:first-child) {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.column-resize-handle {
|
||||
position: absolute;
|
||||
@@ -990,9 +989,9 @@
|
||||
height: 32px;
|
||||
display: grid;
|
||||
align-items: center;
|
||||
width: auto;
|
||||
width: 100%;
|
||||
padding: 0 16px;
|
||||
margin: 2px 12px;
|
||||
margin: 2px 0;
|
||||
border-radius: 6px;
|
||||
color: hsl(var(--text-primary));
|
||||
font-size: 12px;
|
||||
@@ -1069,12 +1068,12 @@
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.download-ghost-row {
|
||||
height: 32px;
|
||||
margin: 2px 12px;
|
||||
border-radius: 6px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.download-ghost-row {
|
||||
height: 32px;
|
||||
margin: 2px 0;
|
||||
border-radius: 6px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.download-ghost-row.striped,
|
||||
.download-row.striped {
|
||||
@@ -1085,7 +1084,6 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding-right: 12px;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
@@ -1093,16 +1091,18 @@
|
||||
.download-status-cell > span {
|
||||
min-width: 0;
|
||||
max-width: 100%;
|
||||
flex: 0 1 auto;
|
||||
flex: 0 0 72px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-size: 10px;
|
||||
line-height: 1.2;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.download-progress-track {
|
||||
width: 100%;
|
||||
flex: 1 1 auto;
|
||||
width: auto;
|
||||
min-width: 0;
|
||||
height: 14px;
|
||||
border-radius: 4px;
|
||||
@@ -1134,9 +1134,13 @@
|
||||
animation: pulse-progress 1.5s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.download-status {
|
||||
font-weight: 500;
|
||||
}
|
||||
.download-status {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.download-status .truncate {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.download-status-paused {
|
||||
color: hsl(var(--status-paused));
|
||||
|
||||
@@ -34,8 +34,13 @@ export async function initDownloadListener() {
|
||||
|
||||
const mainStore = useDownloadStore.getState();
|
||||
const current = mainStore.downloads.find(d => d.id === payload.id);
|
||||
if (current && payload.size && current.size !== payload.size) {
|
||||
mainStore.updateDownload(payload.id, { size: payload.size });
|
||||
if (current) {
|
||||
mainStore.updateDownload(payload.id, {
|
||||
fraction: payload.fraction,
|
||||
speed: payload.speed,
|
||||
eta: payload.eta,
|
||||
...(payload.size ? { size: payload.size } : {}),
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user