use js_sys::Reflect;
use wasm_bindgen::JsValue;
use web_sys::window;
use std::sync::OnceLock;
static IS_IOS: OnceLock<bool> = OnceLock::new();
static IS_FIREFOX: OnceLock<bool> = OnceLock::new();
pub fn is_ios() -> bool {
*IS_IOS.get_or_init(|| {
if let Some(window) = window() {
let audio_encoder_exists = is_audio_encoder_available();
if let Ok(ua) = window.navigator().user_agent() {
let ua_lower = ua.to_lowercase();
let likely_ios = ua_lower.contains("iphone") || ua_lower.contains("ipad") || ua_lower.contains("ipod");
let result = likely_ios || !audio_encoder_exists;
log::info!(
"Platform detection: User Agent='{ua}', LikelyiOS={likely_ios}, AudioEncoderAvailable={audio_encoder_exists}, FinalResult={result}"
);
return result;
}
}
log::warn!("Could not determine platform, assuming not iOS.");
false })
}
fn is_audio_encoder_available() -> bool {
if let Some(window) = window() {
let global = JsValue::from(window);
match Reflect::has(&global, &JsValue::from_str("AudioEncoder")) {
Ok(exists) => {
if !exists {
return false;
}
match Reflect::get(&global, &JsValue::from_str("AudioEncoder")) {
Ok(constructor) => {
!constructor.is_undefined() && !constructor.is_null()
}
Err(_) => false,
}
}
Err(_) => false,
}
} else {
false
}
}
pub fn is_firefox() -> bool {
*IS_FIREFOX.get_or_init(|| {
if let Some(window) = window() {
if let Ok(ua) = window.navigator().user_agent() {
let ua_lower = ua.to_lowercase();
let is_ff = ua_lower.contains("firefox") && !ua_lower.contains("seamonkey");
log::info!("Firefox detection: User Agent='{ua}', IsFirefox={is_ff}");
return is_ff;
}
}
log::warn!("Could not determine browser, assuming not Firefox.");
false
})
}