feat(gui): support for soundpad:// uri (#123)

* feat(gui): support for soundpad:// uri

* fix: flatpak

* do not open gui when downloading file
This commit is contained in:
Tarasov Aleksandr
2026-05-28 00:58:03 +03:00
committed by GitHub
parent 695c83c9e6
commit 5e47e7d6fb
9 changed files with 1382 additions and 14 deletions
+48 -2
View File
@@ -1,7 +1,9 @@
mod gui;
use anyhow::Result;
use anyhow::{Context, Result};
use pwsp::utils::gui::ensure_pwsp_audio_dir;
use rust_i18n::i18n;
use std::{env, path::PathBuf};
i18n!("locales", fallback = "en");
@@ -10,5 +12,49 @@ async fn main() -> Result<()> {
let locale = sys_locale::get_locale().unwrap_or(String::from("en-US"));
rust_i18n::set_locale(&locale);
gui::run().await
let args = env::args().skip(1).collect::<Vec<String>>();
if let Some(uri) = args.first() {
match download_audio_from_url(uri).await {
Ok(path) => println!("Successfully downloaded to: {:?}", path),
Err(e) => eprintln!("Error downloading file: {}", e),
}
} else {
gui::run().await?;
}
Ok(())
}
async fn download_audio_from_url(uri: &str) -> Result<PathBuf> {
let prefix = "soundpad://sound/url/";
let target_url = uri
.strip_prefix(prefix)
.ok_or_else(|| anyhow::anyhow!("URI does not containt an expected prefix: {}", prefix))?;
let file_name_encoded = target_url
.split('/')
.next_back()
.unwrap_or("downloaded_audio.mp3");
let file_name = percent_encoding::percent_decode_str(file_name_encoded)
.decode_utf8()
.unwrap_or_else(|_| file_name_encoded.into())
.into_owned();
let save_path = ensure_pwsp_audio_dir().join(file_name);
let response = reqwest::get(target_url)
.await?
.error_for_status()
.context("Failed to fetch file")?;
let bytes = response.bytes().await?;
tokio::fs::write(&save_path, bytes)
.await
.context("Failed to save file to disk")?;
Ok(save_path)
}
+5 -2
View File
@@ -1,4 +1,7 @@
use crate::{types::socket::Request, utils::config::get_config_path};
use crate::{
types::socket::Request,
utils::{config::get_config_path, gui::ensure_pwsp_audio_dir},
};
use anyhow::Result;
use serde::{Deserialize, Serialize};
use std::{collections::HashMap, fs, path::PathBuf};
@@ -69,7 +72,7 @@ impl Default for GuiConfig {
save_scale_factor: false,
pause_on_exit: false,
dirs: vec![],
dirs: vec![ensure_pwsp_audio_dir()],
preferred_theme: PreferredTheme::System,
}
+12
View File
@@ -9,6 +9,7 @@ use crate::{
};
use anyhow::{Result, anyhow};
use std::{
path::PathBuf,
sync::{Arc, Mutex},
time::Instant,
};
@@ -36,6 +37,17 @@ pub fn make_request_async(request: Request) {
});
}
pub fn ensure_pwsp_audio_dir() -> PathBuf {
let audio_dir = dirs::audio_dir().unwrap_or("~/Music".into());
let pwsp_audio_dir = audio_dir.join("PWSP");
if !pwsp_audio_dir.exists() {
std::fs::create_dir_all(&pwsp_audio_dir).ok();
}
pwsp_audio_dir
}
pub fn format_time_pair(position: f32, duration: f32) -> String {
fn format_time(seconds: f32) -> String {
let total_seconds = seconds.round() as u32;