Skip to content

Commit

Permalink
refactor(front): error handling and reporting using toaster;
Browse files Browse the repository at this point in the history
  • Loading branch information
TheBestTvarynka committed Jan 4, 2025
1 parent b25a3d9 commit 9b53a3d
Show file tree
Hide file tree
Showing 8 changed files with 74 additions and 44 deletions.
42 changes: 22 additions & 20 deletions dataans/src/app_info/app_info_window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ use crate::backend::{open_config_file, open_config_file_folder, open_theme_file}

#[component]
pub fn AppInfoWindow(#[prop(into)] close: Callback<(), ()>) -> impl IntoView {
let toaster = leptoaster::expect_toaster();

use_hotkeys!(("Escape") => move |_| close.call(()));

let global_config = expect_context::<RwSignal<Config>>();
Expand All @@ -19,29 +21,29 @@ pub fn AppInfoWindow(#[prop(into)] close: Callback<(), ()>) -> impl IntoView {

let (is_autostart_enabled, set_autostart) = create_signal(false);

let enable_autostart = move |_| {
let t = toaster.clone();
let enable_autostart = Callback::new(move |_| {
let t = t.clone();
spawn_local(async move {
match crate::backend::autostart::enable().await {
Ok(flag) => set_autostart.set(flag),
Err(err) => {
error!("{:?}", err);
// TODO: toastr.
}
}
set_autostart.set(try_exec!(
crate::backend::autostart::enable().await,
"Failed to enable autostart",
t
));
})
};
});

let disable_autostart = move |_| {
let t = toaster.clone();
let disable_autostart = Callback::new(move |_| {
let t = t.clone();
spawn_local(async move {
match crate::backend::autostart::disable().await {
Ok(flag) => set_autostart.set(flag),
Err(err) => {
error!("{:?}", err);
// TODO: toastr.
}
}
set_autostart.set(try_exec!(
crate::backend::autostart::disable().await,
"Failed to disable autostart",
t
));
})
};
});

view! {
<div class="app-into-window">
Expand All @@ -66,9 +68,9 @@ pub fn AppInfoWindow(#[prop(into)] close: Callback<(), ()>) -> impl IntoView {
<img alt="edit note" src="/public/icons/folder-light.png" />
</button>
{move || if is_autostart_enabled.get() {view! {
<button class="button_ok" on:click=disable_autostart title="Disable autostart">"Disable autostart"</button>
<button class="button_ok" on:click=move |ev| disable_autostart.call(ev) title="Disable autostart">"Disable autostart"</button>
}} else {view! {
<button class="button_ok" on:click=enable_autostart title="Enable autostart">"Enable autostart"</button>
<button class="button_ok" on:click=move |ev| enable_autostart.call(ev) title="Enable autostart">"Enable autostart"</button>
}}}
</div>
{move || {
Expand Down
12 changes: 8 additions & 4 deletions dataans/src/app_info/export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,20 @@ use crate::backend::file::open;

#[component]
pub fn Export() -> impl IntoView {
let toaster = leptoaster::expect_toaster();

let (export_config, set_export_config) = create_signal(DataExportConfig::default());
let (backup_dir, set_backup_dir) = create_signal(None);

let export_data_action = Action::new(move |export_config: &DataExportConfig| {
let toaster = toaster.clone();
let export_config = export_config.clone();
async move {
match export_data(export_config).await {
Ok(backup_dir) => set_backup_dir.set(Some(backup_dir)),
Err(err) => error!("{:?}", err),
}
set_backup_dir.set(Some(try_exec!(
export_data(export_config).await,
"Failed to export the data",
toaster
)));
}
});

Expand Down
13 changes: 3 additions & 10 deletions dataans/src/common/attachment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,9 @@ pub fn Attachment(
let toaster = toaster.clone();

spawn_local(async move {
match files.await {
Ok(files) => {
attached_files.extend_from_slice(&files);
set_files.call(attached_files);
}
Err(err) => {
error!("{:?}", err);
toaster.error(&format!("Files uploading failed: {:?}", err));
}
}
let files = try_exec!(files.await, "Failed to upload files", toaster);
attached_files.extend_from_slice(&files);
set_files.call(attached_files);
});
};
};
Expand Down
12 changes: 10 additions & 2 deletions dataans/src/common/textarea.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ pub fn TextArea(
#[prop(into)] set_text: Callback<String, ()>,
key_down: impl Fn(KeyboardEvent) + 'static,
) -> impl IntoView {
let toaster = leptoaster::expect_toaster();

let (disabled, set_disabled) = create_signal(false);
let ref_input = create_node_ref::<html::Textarea>();

Expand Down Expand Up @@ -39,12 +41,18 @@ pub fn TextArea(
.expect("MIME type JsValue should be string");
ty.to_ascii_lowercase().contains("files")
}) {
let toaster = toaster.clone();

ev.prevent_default();
let mut text = text.get();
let id = elem_id.clone();
spawn_local(async move {
let image = load_clipboard_image().await.expect("TODO: handle err");
let image_path = image.path.to_str().expect("TODO: handle none");
let image = try_exec!(load_clipboard_image().await, "Failed to load clipboard image", toaster);
let image_path = try_exec!(
image.path.to_str().ok_or("use UTF-8 valid paths"),
"Image path is not valid UTF-8 string",
toaster
);

let text_area = document().get_element_by_id(&id).expect("Dom element should present");
let text_area = text_area
Expand Down
12 changes: 12 additions & 0 deletions dataans/src/macros.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
macro_rules! try_exec {
($data:expr, $msg:expr, $toaster:expr) => {
match $data {
Ok(data) => data,
Err(err) => {
error!("{:?}", err);
$toaster.error(&format!("{}: {:?}", $msg, err));
return;
}
}
};
}
3 changes: 3 additions & 0 deletions dataans/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
#[macro_use]
extern crate log;

#[macro_use]
pub mod macros;

mod app;
mod app_info;
mod backend;
Expand Down
11 changes: 8 additions & 3 deletions dataans/src/notes/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ use crate::common::{Attachment, Files, TextArea};

#[component]
pub fn Editor(space_id: SpaceId, #[prop(into)] create_note: Callback<Note<'static>, ()>) -> impl IntoView {
let toaster = leptoaster::expect_toaster();

let (draft_note, set_draft_note) =
if let Ok(draft_note) = LocalStorage::get::<DraftNote>(space_id.inner().to_string()) {
create_signal(draft_note)
Expand Down Expand Up @@ -59,16 +61,19 @@ pub fn Editor(space_id: SpaceId, #[prop(into)] create_note: Callback<Note<'stati
}
};

let remove_file = move |File { id, name: _, path: _ }| {
let toaster = toaster.clone();
let remove_file = Callback::new(move |File { id, name: _, path: _ }| {
let toaster = toaster.clone();

let DraftNote { text, mut files } = draft_note.get();

spawn_local(async move {
remove_file(id).await.expect("TODO: handle err");
try_exec!(remove_file(id).await, "File removing failed", toaster);

files.retain(|file| file.id != id);
set_draft_note(DraftNote { text, files });
});
};
});

let handle_files = move |files| {
if let Some(DraftNote { text, files: _ }) = draft_note.try_get_untracked() {
Expand Down
13 changes: 8 additions & 5 deletions dataans/src/spaces/space_form.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ pub fn SpaceForm(
set_selected_space: Callback<OwnedSpace, ()>,
config: Config,
) -> impl IntoView {
let toaster = leptoaster::expect_toaster();

let (space_name, set_space_name) = create_signal(space.as_ref().map(|s| s.name.to_string()).unwrap_or_default());
let (avatar, set_avatar) = create_signal(
space
Expand All @@ -39,11 +41,12 @@ pub fn SpaceForm(
}
});

let generate_avatar = move || {
let generate_avatar = Callback::new(move |_| {
let toaster = toaster.clone();
spawn_local(async move {
set_avatar.set(gen_avatar().await.expect("TODO: handle err").into());
set_avatar.set(try_exec!(gen_avatar().await, "Failed to generate a new avatar:", toaster).into());
});
};
});

let id = space.as_ref().map(|s| s.id);
let create_space = move || {
Expand Down Expand Up @@ -93,7 +96,7 @@ pub fn SpaceForm(
use_hotkeys!(("Escape") => move |_| on_cancel.call(()));
use_hotkeys!(("Enter") => move |_| create_space());
let regenerate_space_avatar = config.key_bindings.regenerate_space_avatar.clone();
use_hotkeys!((regenerate_space_avatar) => move |_| generate_avatar());
use_hotkeys!((regenerate_space_avatar) => move |_| generate_avatar.call(()));

view! {
<div class="create-space-window" on:load=move |_| info!("on_load")>
Expand All @@ -105,7 +108,7 @@ pub fn SpaceForm(
<div class="create-space-avatar">
<img class="create-space-avatar-img" src=move || convert_file_src(avatar.get().path()) />
<div style="align-self: center">
<button class="tool" title="Regenerate avatar" on:click=move |_| generate_avatar()>
<button class="tool" title="Regenerate avatar" on:click=move |_| generate_avatar.call(())>
<img alt="regenerate-avatar" src="/public/icons/refresh.svg" />
</button>
</div>
Expand Down

0 comments on commit 9b53a3d

Please sign in to comment.