summaryrefslogtreecommitdiffstats
path: root/examples/todos
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector@hecrj.dev>2023-11-29 22:28:31 +0100
committerLibravatar Héctor Ramón Jiménez <hector@hecrj.dev>2023-11-29 22:28:31 +0100
commite09b4e24dda51b8212d8ece52431dacaa3922a7b (patch)
tree7005e181528134ebdde5bbbe5909273db9f30174 /examples/todos
parent83c7870c569a2976923ee6243a19813094d44673 (diff)
parent7f8b17604a31e00becc43130ec516c1a53552c88 (diff)
downloadiced-e09b4e24dda51b8212d8ece52431dacaa3922a7b.tar.gz
iced-e09b4e24dda51b8212d8ece52431dacaa3922a7b.tar.bz2
iced-e09b4e24dda51b8212d8ece52431dacaa3922a7b.zip
Merge branch 'master' into feat/multi-window-support
Diffstat (limited to 'examples/todos')
-rw-r--r--examples/todos/Cargo.toml18
-rw-r--r--examples/todos/README.md13
-rw-r--r--examples/todos/src/main.rs62
3 files changed, 50 insertions, 43 deletions
diff --git a/examples/todos/Cargo.toml b/examples/todos/Cargo.toml
index 7ad4d558..3c62bfbc 100644
--- a/examples/todos/Cargo.toml
+++ b/examples/todos/Cargo.toml
@@ -6,18 +6,26 @@ edition = "2021"
publish = false
[dependencies]
-iced = { path = "../..", features = ["async-std", "debug"] }
+iced.workspace = true
+iced.features = ["async-std", "debug"]
+
+once_cell.workspace = true
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
-once_cell = "1.15"
+uuid = { version = "1.0", features = ["v4", "fast-rng", "serde"] }
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
-async-std = "1.0"
+async-std.workspace = true
directories-next = "2.0"
+tracing-subscriber = "0.3"
[target.'cfg(target_arch = "wasm32")'.dependencies]
-web-sys = { version = "0.3", features = ["Window", "Storage"] }
-wasm-timer = "0.2"
+iced.workspace = true
+iced.features = ["debug", "webgl"]
+
+uuid = { version = "1.0", features = ["js"] }
+web-sys = { workspace = true, features = ["Window", "Storage"] }
+wasm-timer.workspace = true
[package.metadata.deb]
assets = [
diff --git a/examples/todos/README.md b/examples/todos/README.md
index 9c2598b9..5e42f166 100644
--- a/examples/todos/README.md
+++ b/examples/todos/README.md
@@ -5,8 +5,8 @@ A todos tracker inspired by [TodoMVC]. It showcases dynamic layout, text input,
All the example code is located in the __[`main`]__ file.
<div align="center">
- <a href="https://gfycat.com/littlesanehalicore">
- <img src="https://thumbs.gfycat.com/LittleSaneHalicore-small.gif" height="400px">
+ <a href="https://iced.rs/examples/todos.mp4">
+ <img src="https://iced.rs/examples/todos.gif">
</a>
</div>
@@ -14,7 +14,14 @@ You can run the native version with `cargo run`:
```
cargo run --package todos
```
-We have not yet implemented a `LocalStorage` version of the auto-save feature. Therefore, it does not work on web _yet_!
+
+The web version can be run with [`trunk`]:
+
+```
+cd examples/todos
+trunk serve
+```
[`main`]: src/main.rs
[TodoMVC]: http://todomvc.com/
+[`trunk`]: https://trunkrs.dev/
diff --git a/examples/todos/src/main.rs b/examples/todos/src/main.rs
index 04c8f618..a7ba69b9 100644
--- a/examples/todos/src/main.rs
+++ b/examples/todos/src/main.rs
@@ -1,12 +1,10 @@
use iced::alignment::{self, Alignment};
-use iced::event::{self, Event};
use iced::font::{self, Font};
-use iced::keyboard::{self, KeyCode, Modifiers};
-use iced::subscription;
+use iced::keyboard;
use iced::theme::{self, Theme};
use iced::widget::{
- self, button, checkbox, column, container, row, scrollable, text,
- text_input, Text,
+ self, button, checkbox, column, container, keyed_column, row, scrollable,
+ text, text_input, Text,
};
use iced::window;
use iced::{Application, Element};
@@ -14,10 +12,14 @@ use iced::{Color, Command, Length, Settings, Subscription};
use once_cell::sync::Lazy;
use serde::{Deserialize, Serialize};
+use uuid::Uuid;
static INPUT_ID: Lazy<text_input::Id> = Lazy::new(text_input::Id::unique);
pub fn main() -> iced::Result {
+ #[cfg(not(target_arch = "wasm32"))]
+ tracing_subscriber::fmt::init();
+
Todos::run(Settings {
window: window::Settings {
size: (500, 800),
@@ -222,17 +224,19 @@ impl Application for Todos {
tasks.iter().filter(|task| filter.matches(task));
let tasks: Element<_> = if filtered_tasks.count() > 0 {
- column(
+ keyed_column(
tasks
.iter()
.enumerate()
.filter(|(_, task)| filter.matches(task))
.map(|(i, task)| {
- task.view(i).map(move |message| {
- Message::TaskMessage(i, message)
- })
- })
- .collect(),
+ (
+ task.id,
+ task.view(i).map(move |message| {
+ Message::TaskMessage(i, message)
+ }),
+ )
+ }),
)
.spacing(10)
.into()
@@ -262,39 +266,27 @@ impl Application for Todos {
}
fn subscription(&self) -> Subscription<Message> {
- subscription::events_with(|event, status| match (event, status) {
- (
- Event::Keyboard(keyboard::Event::KeyPressed {
- key_code: keyboard::KeyCode::Tab,
- modifiers,
- ..
- }),
- event::Status::Ignored,
- ) => Some(Message::TabPressed {
- shift: modifiers.shift(),
- }),
- (
- Event::Keyboard(keyboard::Event::KeyPressed {
- key_code,
- modifiers: Modifiers::SHIFT,
+ keyboard::on_key_press(|key_code, modifiers| {
+ match (key_code, modifiers) {
+ (keyboard::KeyCode::Tab, _) => Some(Message::TabPressed {
+ shift: modifiers.shift(),
}),
- event::Status::Ignored,
- ) => match key_code {
- KeyCode::Up => {
+ (keyboard::KeyCode::Up, keyboard::Modifiers::SHIFT) => {
Some(Message::ToggleFullscreen(window::Mode::Fullscreen))
}
- KeyCode::Down => {
+ (keyboard::KeyCode::Down, keyboard::Modifiers::SHIFT) => {
Some(Message::ToggleFullscreen(window::Mode::Windowed))
}
_ => None,
- },
- _ => None,
+ }
})
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
struct Task {
+ #[serde(default = "Uuid::new_v4")]
+ id: Uuid,
description: String,
completed: bool,
@@ -330,6 +322,7 @@ impl Task {
fn new(description: String) -> Self {
Task {
+ id: Uuid::new_v4(),
description,
completed: false,
state: TaskState::Idle,
@@ -422,8 +415,7 @@ fn view_controls(tasks: &[Task], current_filter: Filter) -> Element<Message> {
row![
text(format!(
- "{} {} left",
- tasks_left,
+ "{tasks_left} {} left",
if tasks_left == 1 { "task" } else { "tasks" }
))
.width(Length::Fill),
@@ -451,7 +443,7 @@ pub enum Filter {
}
impl Filter {
- fn matches(&self, task: &Task) -> bool {
+ fn matches(self, task: &Task) -> bool {
match self {
Filter::All => true,
Filter::Active => !task.completed,