fix: resolve UI hangs and contrast issues, improve concurrency

- Prevent UI hang by processing aria2 unpause actions asynchronously
- Bypass internal aria2 limits to honor Firelink's max concurrent setting
- Improve visibility of the 'Recheck engines' button in Settings
- Refactor Speed Limiter checkbox into a toggle and fix text selection
- Update Add window font and placeholder to match modern design standards
This commit is contained in:
NimBold
2026-06-24 14:31:40 +03:30
parent d05f4fb251
commit d720308f30
4 changed files with 53 additions and 28 deletions
+38 -22
View File
@@ -2396,30 +2396,45 @@ async fn resume_download(
let status = aria2_download_status(state.aria2_port, &state.aria2_secret, &gid).await?;
match status.as_str() {
"paused" => {
let acquired = state.queue_manager.ensure_aria2_permit(&id).await;
let result = match rpc_call(
state.aria2_port,
&state.aria2_secret,
"aria2.unpause",
serde_json::json!([gid]),
)
.await
{
Ok(result) => result,
Err(error) => {
if acquired {
state.queue_manager.release_permit(&id).await;
use tauri::Emitter;
let _ = state.emit(
"download-state",
crate::ipc::DownloadStateEvent::new(&id, crate::ipc::DownloadStatus::Queued),
);
let app_state = state.inner().clone();
let id_clone = id.clone();
let gid_clone = gid.clone();
tauri::async_runtime::spawn(async move {
let acquired = app_state.queue_manager.ensure_aria2_permit(&id_clone).await;
let result = match rpc_call(
app_state.aria2_port,
&app_state.aria2_secret,
"aria2.unpause",
serde_json::json!([gid_clone]),
)
.await
{
Ok(result) => result,
Err(error) => {
if acquired {
app_state.queue_manager.release_permit(&id_clone).await;
}
log::error!("failed to resume aria2 gid {}: {}", gid_clone, error);
return;
}
return Err(format!("failed to resume aria2 gid {gid}: {error}"));
};
if let Err(error) = ensure_aria2_gid_result("unpause", &gid_clone, &result) {
if acquired {
app_state.queue_manager.release_permit(&id_clone).await;
}
log::error!("failed to resume aria2 gid {}: {}", gid_clone, error);
return;
}
};
if let Err(error) = ensure_aria2_gid_result("unpause", &gid, &result) {
if acquired {
state.queue_manager.release_permit(&id).await;
}
return Err(error);
}
log::info!("aria2 resume [{}]: unpaused gid {}", id, gid);
log::info!("aria2 resume [{}]: unpaused gid {}", id_clone, gid_clone);
});
return Ok(true);
}
"active" | "waiting" => {
state.queue_manager.ensure_aria2_permit(&id).await;
@@ -3960,6 +3975,7 @@ pub fn run() {
.arg("--summary-interval=1")
.arg("--console-log-level=warn")
.arg("--download-result=hide")
.arg("--max-concurrent-downloads=9999")
.arg("--check-certificate=true");
if let Some(global_speed_limit) = normalize_speed_limit_for_aria2(&global_speed_limit) {
+2 -2
View File
@@ -734,8 +734,8 @@ export const AddDownloadsModal = () => {
</div>
</div>
<textarea
className="add-download-control add-download-links-input w-full h-32 p-3 text-[13px] resize-none font-mono"
placeholder="Paste HTTP, HTTPS, FTP, or SFTP URLs here..."
className="add-download-control add-download-links-input w-full h-32 p-3 text-[13px] resize-none"
placeholder={"Paste HTTP, HTTPS, FTP, or SFTP URLs here...\n\nFor media downloads, paste links from Youtube, X, TikTok, Instagram, Reddit, etc."}
value={urls}
onChange={(e) => setUrls(e.target.value)}
/>
+1 -1
View File
@@ -971,7 +971,7 @@ runEngineChecks(false);
type="button"
onClick={() => runEngineChecks(true)}
disabled={isRecheckingEngines}
className="flex items-center gap-1.5 px-3 py-1.5 rounded-md bg-bg-modal hover:bg-item-hover disabled:opacity-60 text-[12px] text-text-primary"
className="app-button px-3 py-1.5 text-[12px] flex items-center gap-1.5 disabled:opacity-60"
>
<RefreshCw size={13} className={isRecheckingEngines ? 'animate-spin' : ''} />
{isRecheckingEngines ? 'Checking' : 'Recheck engines'}
+12 -3
View File
@@ -58,10 +58,19 @@ export default function SpeedLimiterView() {
<WindowDragRegion />
<div className="flex items-center gap-3 border-b border-border-color px-6 pb-4">
<label className="flex items-center gap-3 text-[17px] font-semibold tracking-tight text-text-primary">
<input type="checkbox" checked={enabled} onChange={event => setEnabled(event.target.checked)} className="h-4 w-4 accent-accent" />
<div className="flex items-center gap-3 text-[17px] font-semibold tracking-tight text-text-primary select-none">
<button
onClick={() => setEnabled(!enabled)}
className={`relative inline-flex h-5 w-9 cursor-pointer items-center rounded-full transition-colors duration-200 ease-in-out focus:outline-none ${enabled ? 'bg-accent' : 'bg-item-hover'}`}
aria-checked={enabled}
role="switch"
>
<span
className={`inline-block h-4 w-4 transform rounded-full bg-white transition duration-200 ease-in-out ${enabled ? 'translate-x-4' : 'translate-x-1'}`}
/>
</button>
Speed Limiter
</label>
</div>
<span className={`rounded-full px-2.5 py-1 text-[11px] font-semibold ${
enabled ? 'bg-accent/15 text-accent' : 'bg-item-hover text-text-muted'
}`}>