use mobiler_core::{
ButtonStyle, CardStyle, Cx, ImageRatio, ImageShape, InputValue, MobilerApp, MobilerShell,
Spacing, Tone, Widget, badge, button, caption, card, column, divider, image, row, spacer,
switch, text, text_field, title,
};
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Clone, Debug)]
pub enum Msg {
Increment,
Greet,
}
#[derive(Default)]
pub struct Model {
count: i32,
name: String,
notify: bool,
}
#[derive(Default)]
pub struct {{NAME}}App;
impl MobilerApp for {{NAME}}App {
type Event = Msg;
type Model = Model;
fn update(&self, event: Msg, model: &mut Model, cx: &mut Cx<Msg>) {
match event {
Msg::Increment => model.count += 1,
Msg::Greet => {
let who = if model.name.is_empty() { "there".to_string() } else { model.name.clone() };
cx.notify("toast", "show", format!("Hello, {who}! 👋"));
}
}
}
fn input(&self, id: &str, value: InputValue, model: &mut Model, _cx: &mut Cx<Msg>) {
match (id, value) {
("name", InputValue::Text(v)) => model.name = v,
("notify", InputValue::Bool(v)) => model.notify = v,
_ => {}
}
}
fn view(&self, model: &Model) -> Widget {
let greeting = if model.name.is_empty() {
"Type your name above…".to_string()
} else {
format!("Hello, {}!", model.name)
};
column(vec![
title("Welcome to {{NAME}}"),
caption("Built with Mobiler — your UI is Rust, rendered to native widgets. Edit shared/src/app.rs to make it yours."),
image("https://picsum.photos/seed/{{NAME}}/1200/700", ImageShape::Rounded, ImageRatio::Wide),
divider(),
row(vec![
button("Tap me", ButtonStyle::Filled, Msg::Increment),
badge(format!("count {}", model.count), Tone::Info),
]),
divider(),
card(text("This is a card — cards group related content."), CardStyle::Elevated),
divider(),
text_field("name", "Your name", model.name.clone()),
text(greeting),
switch("notify", "Enable notifications", model.notify),
divider(),
button("Say hello (toast plugin)", ButtonStyle::Outlined, Msg::Greet),
spacer(Spacing::Lg),
])
}
}
pub type App = MobilerShell<{{NAME}}App>;
#[cfg(test)]
mod test {
use super::*;
#[test]
fn increment_counts() {
let app = {{NAME}}App;
let mut model = Model::default();
app.update(Msg::Increment, &mut model, &mut Cx::default());
assert_eq!(model.count, 1);
}
#[test]
fn input_sets_name() {
let app = {{NAME}}App;
let mut model = Model::default();
app.input("name", InputValue::Text("Ada".to_string()), &mut model, &mut Cx::default());
assert_eq!(model.name, "Ada");
}
}