use crate::i18n::js_internal_error;
use lingxia_platform::traits::ui::UIUpdate;
use lxapp::{LxApp, lx};
use rong::{FromJSObj, JSContext, JSFunc, JSResult};
use std::sync::Arc;
#[derive(FromJSObj)]
struct ShowTabBarRedDotOptions {
index: i32,
}
#[derive(FromJSObj)]
struct HideTabBarRedDotOptions {
index: i32,
}
#[derive(FromJSObj)]
struct SetTabBarBadgeOptions {
index: i32,
text: String,
}
#[derive(FromJSObj)]
struct RemoveTabBarBadgeOptions {
index: i32,
}
#[derive(FromJSObj)]
struct SetTabBarStyleOptions {
color: Option<String>,
#[rename = "selectedColor"]
selected_color: Option<String>,
#[rename = "backgroundColor"]
background_color: Option<String>,
#[rename = "borderStyle"]
border_style: Option<String>,
}
#[derive(FromJSObj)]
struct SetTabBarItemOptions {
index: i32,
text: Option<String>,
#[rename = "iconPath"]
icon_path: Option<String>,
#[rename = "selectedIconPath"]
selected_icon_path: Option<String>,
}
fn is_tabbar_visible(lxapp: &Arc<LxApp>) -> bool {
lxapp
.get_tabbar()
.map(|tabbar| tabbar.is_visible)
.unwrap_or(false)
}
fn show_tabbar_red_dot(ctx: JSContext, options: ShowTabBarRedDotOptions) -> JSResult<bool> {
let lxapp = LxApp::from_ctx(&ctx)?;
let updated = lxapp
.with_tabbar_mut(|tabbar| tabbar.set_red_dot(options.index, true))
.unwrap_or(false);
if updated && is_tabbar_visible(&lxapp) {
if let Err(e) = lxapp.runtime.update_tabbar_ui(lxapp.appid.clone()) {
return Err(js_internal_error(format!(
"Failed to update TabBar UI: {}",
e
)));
}
Ok(true)
} else {
Ok(updated)
}
}
fn hide_tabbar_red_dot(ctx: JSContext, options: HideTabBarRedDotOptions) -> JSResult<bool> {
let lxapp = LxApp::from_ctx(&ctx)?;
let updated = lxapp
.with_tabbar_mut(|tabbar| tabbar.set_red_dot(options.index, false))
.unwrap_or(false);
if updated && is_tabbar_visible(&lxapp) {
if let Err(e) = lxapp.runtime.update_tabbar_ui(lxapp.appid.clone()) {
return Err(js_internal_error(format!(
"Failed to update TabBar UI: {}",
e
)));
}
Ok(true)
} else {
Ok(updated)
}
}
fn set_tabbar_badge(ctx: JSContext, options: SetTabBarBadgeOptions) -> JSResult<bool> {
let lxapp = LxApp::from_ctx(&ctx)?;
let updated = lxapp
.with_tabbar_mut(|tabbar| tabbar.set_badge(options.index, &options.text))
.unwrap_or(false);
if updated && is_tabbar_visible(&lxapp) {
if let Err(e) = lxapp.runtime.update_tabbar_ui(lxapp.appid.clone()) {
return Err(js_internal_error(format!(
"Failed to update TabBar UI: {}",
e
)));
}
Ok(true)
} else {
Ok(updated)
}
}
fn remove_tabbar_badge(ctx: JSContext, options: RemoveTabBarBadgeOptions) -> JSResult<bool> {
let lxapp = LxApp::from_ctx(&ctx)?;
let updated = lxapp
.with_tabbar_mut(|tabbar| tabbar.remove_badge(options.index))
.unwrap_or(false);
if updated && is_tabbar_visible(&lxapp) {
if let Err(e) = lxapp.runtime.update_tabbar_ui(lxapp.appid.clone()) {
return Err(js_internal_error(format!(
"Failed to update TabBar UI: {}",
e
)));
}
Ok(true)
} else {
Ok(updated)
}
}
fn show_tabbar(ctx: JSContext) -> JSResult<bool> {
let lxapp = LxApp::from_ctx(&ctx)?;
let updated = lxapp
.with_tabbar_mut(|tabbar| {
tabbar.set_visible(true);
true
})
.unwrap_or(false);
if updated {
if let Err(e) = lxapp.runtime.update_tabbar_ui(lxapp.appid.clone()) {
return Err(js_internal_error(format!(
"Failed to update TabBar UI: {}",
e
)));
}
Ok(true)
} else {
Ok(false)
}
}
fn hide_tabbar(ctx: JSContext) -> JSResult<bool> {
let lxapp = LxApp::from_ctx(&ctx)?;
let updated = lxapp
.with_tabbar_mut(|tabbar| {
tabbar.set_visible(false);
true
})
.unwrap_or(false);
if updated {
if let Err(e) = lxapp.runtime.update_tabbar_ui(lxapp.appid.clone()) {
return Err(js_internal_error(format!(
"Failed to update TabBar UI: {}",
e
)));
}
Ok(true)
} else {
Ok(false)
}
}
fn set_tabbar_style(ctx: JSContext, options: SetTabBarStyleOptions) -> JSResult<bool> {
let lxapp = LxApp::from_ctx(&ctx)?;
let updated = lxapp
.with_tabbar_mut(|tabbar| {
if let Some(color) = options.color {
tabbar.set_color(&color);
}
if let Some(selected_color) = options.selected_color {
tabbar.set_selected_color(&selected_color);
}
if let Some(background_color) = options.background_color {
tabbar.set_background_color(&background_color);
}
if let Some(border_style) = options.border_style {
tabbar.set_border_style(&border_style);
}
true
})
.unwrap_or(false);
if updated && is_tabbar_visible(&lxapp) {
if let Err(e) = lxapp.runtime.update_tabbar_ui(lxapp.appid.clone()) {
return Err(js_internal_error(format!(
"Failed to update TabBar UI: {}",
e
)));
}
Ok(true)
} else {
Ok(updated)
}
}
fn set_tabbar_item(ctx: JSContext, options: SetTabBarItemOptions) -> JSResult<bool> {
let lxapp = LxApp::from_ctx(&ctx)?;
let updated = lxapp
.with_tabbar_mut(|tabbar| {
let mut changed = false;
if let Some(text) = options.text {
tabbar.set_item_text(options.index, &text);
changed = true;
}
if let Some(icon_path) = options.icon_path {
tabbar.set_item_icon(options.index, &icon_path);
changed = true;
}
if let Some(selected_icon_path) = options.selected_icon_path {
tabbar.set_item_selected_icon(options.index, &selected_icon_path);
changed = true;
}
changed
})
.unwrap_or(false);
if updated && is_tabbar_visible(&lxapp) {
if let Err(e) = lxapp.runtime.update_tabbar_ui(lxapp.appid.clone()) {
return Err(js_internal_error(format!(
"Failed to update TabBar UI: {}",
e
)));
}
Ok(true)
} else {
Ok(updated)
}
}
pub(crate) fn init(ctx: &JSContext) -> JSResult<()> {
let show_red_dot_func = JSFunc::new(ctx, show_tabbar_red_dot)?;
lx::register_js_api(ctx, "showTabBarRedDot", show_red_dot_func)?;
let hide_red_dot_func = JSFunc::new(ctx, hide_tabbar_red_dot)?;
lx::register_js_api(ctx, "hideTabBarRedDot", hide_red_dot_func)?;
let set_badge_func = JSFunc::new(ctx, set_tabbar_badge)?;
lx::register_js_api(ctx, "setTabBarBadge", set_badge_func)?;
let remove_badge_func = JSFunc::new(ctx, remove_tabbar_badge)?;
lx::register_js_api(ctx, "removeTabBarBadge", remove_badge_func)?;
let show_tabbar_func = JSFunc::new(ctx, show_tabbar)?;
lx::register_js_api(ctx, "showTabBar", show_tabbar_func)?;
let hide_tabbar_func = JSFunc::new(ctx, hide_tabbar)?;
lx::register_js_api(ctx, "hideTabBar", hide_tabbar_func)?;
let set_style_func = JSFunc::new(ctx, set_tabbar_style)?;
lx::register_js_api(ctx, "setTabBarStyle", set_style_func)?;
let set_item_func = JSFunc::new(ctx, set_tabbar_item)?;
lx::register_js_api(ctx, "setTabBarItem", set_item_func)?;
Ok(())
}