1//! The controller handles UI events, translates them into updates on the model,
2//! and schedules re-renders.
4use crate::todo::{Todo, TodoActions};
5use crate::todos::{Todos, TodosActions};
6use crate::visibility::Visibility;
7use dodrio::{RootRender, VdomWeak};
8use serde::{Deserialize, Serialize};
9use std::ops::{Deref, DerefMut};
11/// The controller for the TodoMVC app.
13/// This `Controller` struct is never actually instantiated. It is only used for
14/// its `*Actions` trait implementations, none of which take a `self` parameter.
16/// One could imagine alternative controller implementations with `*Actions`
17/// trait implementations for (e.g.) testing that will assert various expected
18/// action methods are called after rendering todo items and sending DOM events.
19#[derive(Default, Deserialize, Serialize)]
22impl TodosActions for Controller {
23 fn toggle_all(root: &mut dyn RootRender, vdom: VdomWeak) {
24 let mut todos = AutoCommitTodos::new(root, vdom);
25 let all_complete = todos.todos().iter().all(|t| t.is_complete());
26 for t in todos.todos_mut() {
27 t.set_complete(!all_complete);
31 fn update_draft(root: &mut dyn RootRender, vdom: VdomWeak, draft: String) {
32 let mut todos = AutoCommitTodos::new(root, vdom);
33 todos.set_draft(draft);
36 fn finish_draft(root: &mut dyn RootRender, vdom: VdomWeak) {
37 let mut todos = AutoCommitTodos::new(root, vdom);
38 let title = todos.take_draft();
39 let title = title.trim();
40 if !title.is_empty() {
41 let id = todos.todos().len();
42 let new = Todo::new(id, title);
47 fn change_visibility(root: &mut dyn RootRender, vdom: VdomWeak, vis: Visibility) {
48 let mut todos = AutoCommitTodos::new(root, vdom);
49 todos.set_visibility(vis);
52 fn delete_completed(root: &mut dyn RootRender, vdom: VdomWeak) {
53 let mut todos = AutoCommitTodos::new(root, vdom);
54 todos.delete_completed();
58impl TodoActions for Controller {
59 fn toggle_completed(root: &mut dyn RootRender, vdom: VdomWeak, id: usize) {
60 let mut todos = AutoCommitTodos::new(root, vdom);
61 let t = &mut todos.todos_mut()[id];
62 let completed = t.is_complete();
63 t.set_complete(!completed);
66 fn delete(root: &mut dyn RootRender, vdom: VdomWeak, id: usize) {
67 let mut todos = AutoCommitTodos::new(root, vdom);
68 todos.delete_todo(id);
71 fn begin_editing(root: &mut dyn RootRender, vdom: VdomWeak, id: usize) {
72 let mut todos = AutoCommitTodos::new(root, vdom);
73 let t = &mut todos.todos_mut()[id];
74 let desc = t.title().to_string();
75 t.set_edits(Some(desc));
78 fn update_edits(root: &mut dyn RootRender, vdom: VdomWeak, id: usize, edits: String) {
79 let mut todos = AutoCommitTodos::new(root, vdom);
80 let t = &mut todos.todos_mut()[id];
81 t.set_edits(Some(edits));
84 fn finish_edits(root: &mut dyn RootRender, vdom: VdomWeak, id: usize) {
85 let mut todos = AutoCommitTodos::new(root, vdom);
86 let t = &mut todos.todos_mut()[id];
87 if let Some(edits) = t.take_edits() {
88 let edits = edits.trim();
90 todos.delete_todo(id);
97 fn cancel_edits(root: &mut dyn RootRender, vdom: VdomWeak, id: usize) {
98 let mut todos = AutoCommitTodos::new(root, vdom);
99 let t = &mut todos.todos_mut()[id];
100 let _ = t.take_edits();
104/// An RAII type that dereferences to a `Todos` and once it is dropped, saves
105/// the (presumably just modified) todos to local storage, and schedules a new
107pub struct AutoCommitTodos<'a> {
108 todos: &'a mut Todos,
112impl AutoCommitTodos<'_> {
113 /// Construct a new `AutoCommitTodos` from the root rendering component and
115 pub fn new(root: &mut dyn RootRender, vdom: VdomWeak) -> AutoCommitTodos {
116 let todos = root.unwrap_mut::<Todos>();
117 AutoCommitTodos { todos, vdom }
121impl Drop for AutoCommitTodos<'_> {
123 self.todos.save_to_local_storage();
124 self.vdom.schedule_render();
128impl Deref for AutoCommitTodos<'_> {
131 fn deref(&self) -> &Todos {
136impl DerefMut for AutoCommitTodos<'_> {
137 fn deref_mut(&mut self) -> &mut Todos {
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list