kopuz 0.8.0

A modern, lightweight music player built with Rust and Dioxus.
#[cfg(all(not(target_arch = "wasm32"), not(target_os = "android")))]
pub fn build_window_icon() -> Option<dioxus::desktop::tao::window::Icon> {
    let image = image::load_from_memory(include_bytes!("../assets/logo-512.png")).ok()?;
    let image = image.into_rgba8();
    let (width, height) = image.dimensions();
    dioxus::desktop::tao::window::Icon::from_rgba(image.into_raw(), width, height).ok()
}

#[cfg(all(not(target_arch = "wasm32"), not(target_os = "android")))]
pub fn build_tray_icon() -> Option<dioxus::desktop::trayicon::Icon> {
    let image = image::load_from_memory(include_bytes!("../assets/logo-512.png")).ok()?;
    let image = image.into_rgba8();
    let (width, height) = image.dimensions();
    dioxus::desktop::trayicon::Icon::from_rgba(image.into_raw(), width, height).ok()
}

#[cfg(target_os = "linux")]
pub fn tray_backend_available() -> bool {
    const CANDIDATES: &[&str] = &[
        "libayatana-appindicator3.so.1",
        "libappindicator3.so.1",
        "libayatana-appindicator3.so",
        "libappindicator3.so",
    ];
    CANDIDATES
        .iter()
        .any(|name| unsafe { libloading::Library::new(name) }.is_ok())
}

#[cfg(all(
    not(target_arch = "wasm32"),
    not(target_os = "android"),
    not(target_os = "linux")
))]
pub fn tray_backend_available() -> bool {
    true
}

#[cfg(all(not(target_arch = "wasm32"), not(target_os = "android")))]
pub fn show_tray_missing_popup() {
    let msg = "System tray unavailable: appindicator library not found. \
               Install libayatana-appindicator (Debian/Ubuntu/Arch) or \
               libappindicator-gtk3 (Fedora). Closing the window will quit \
               the app instead of minimizing to tray.";
    let escaped = serde_json::to_string(msg).unwrap_or_else(|_| "\"\"".to_string());
    let js = format!(
        r#"(function(m){{
            let t = document.getElementById('kopuz-tray-popup');
            if (!t) {{
                t = document.createElement('div');
                t.id = 'kopuz-tray-popup';
                t.style.cssText = 'position:fixed;right:16px;top:16px;max-width:360px;background:rgba(28,28,30,0.97);color:#fff;padding:14px 16px;border-radius:10px;font:13px/1.45 system-ui,sans-serif;z-index:99999;box-shadow:0 8px 28px rgba(0,0,0,0.5);border:1px solid rgba(255,170,60,0.45);opacity:0;transition:opacity 200ms;';
                t.onclick = () => {{ t.style.opacity = '0'; }};
                document.body.appendChild(t);
            }}
            t.innerHTML = '<div style="font-weight:600;margin-bottom:4px;color:#ffb347;">Tray icon unavailable</div>' + m;
            requestAnimationFrame(() => {{ t.style.opacity = '1'; }});
            clearTimeout(t._h);
            t._h = setTimeout(() => {{ t.style.opacity = '0'; }}, 8000);
        }})({escaped});"#
    );
    let _ = dioxus::document::eval(&js);
}

#[cfg(any(target_os = "linux", target_os = "windows"))]
pub fn read_titlebar_mode_from_disk() -> config::TitlebarMode {
    db::peek_config(&db::default_db_path())
        .map(|c| c.titlebar_mode)
        .unwrap_or_default()
}