Reduce memory footprint, fix alloc vec error

This commit is contained in:
Adrian Woźniak 2021-10-11 16:56:15 +02:00
parent d8855bdfec
commit 8478f5d112
No known key found for this signature in database
GPG Key ID: DE43476F72AD3F6C
11 changed files with 77 additions and 75 deletions

1
Cargo.lock generated
View File

@ -1765,6 +1765,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"bincode", "bincode",
"chrono", "chrono",
"console_error_panic_hook",
"derive_enum_iter", "derive_enum_iter",
"derive_enum_primitive", "derive_enum_primitive",
"dotenv", "dotenv",

View File

@ -34,6 +34,8 @@ dotenv = { version = "*" }
wasm-logger = { version = "*" } wasm-logger = { version = "*" }
log = "*" log = "*"
console_error_panic_hook = { version = "*" }
[dependencies.wee_alloc] [dependencies.wee_alloc]
version = "*" version = "*"
features = ["static_array_backend"] features = ["static_array_backend"]

View File

@ -52,11 +52,9 @@ impl<'l> StyledImageInput<'l> {
let v = input let v = input
.files() .files()
.map(|list| { .map(|list| {
let mut v = vec![]; (0..list.length())
for i in 0..list.length() { .filter_map(|i| list.get(i))
v.push(list.get(i).unwrap()); .collect::<Vec<File>>()
}
v
}) })
.unwrap_or_default(); .unwrap_or_default();
Msg::FileInputChanged(field_id, v) Msg::FileInputChanged(field_id, v)

View File

@ -34,8 +34,8 @@ mod shared;
pub mod validations; pub mod validations;
mod ws; mod ws;
#[global_allocator] // #[global_allocator]
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT; // static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
#[derive(Debug)] #[derive(Debug)]
#[repr(C)] #[repr(C)]
@ -179,7 +179,7 @@ fn update(msg: Msg, model: &mut model::Model, orders: &mut impl Orders<Msg>) {
WebSocketChanged::WsMsg(mut ws_msg) => { WebSocketChanged::WsMsg(mut ws_msg) => {
ws::update(&mut ws_msg, model, orders); ws::update(&mut ws_msg, model, orders);
orders.skip(); orders.skip();
Msg::WebSocketChange(WebSocketChanged::WsMsg(ws_msg)) return;
} }
WebSocketChanged::WebSocketMessageLoaded(v) => { WebSocketChanged::WebSocketMessageLoaded(v) => {
match bincode::deserialize(v.as_slice()) { match bincode::deserialize(v.as_slice()) {
@ -325,6 +325,8 @@ fn resolve_page(url: Url) -> Option<Page> {
#[wasm_bindgen] #[wasm_bindgen]
pub fn render() { pub fn render() {
console_error_panic_hook::set_once();
let app = seed::App::start("app", init, update, view); let app = seed::App::start("app", init, update, view);
wasm_logger::init(wasm_logger::Config::default()); wasm_logger::init(wasm_logger::Config::default());
@ -402,18 +404,18 @@ fn init(url: Url, orders: &mut impl Orders<Msg>) -> Model {
}); });
{ {
// let sender_clone = sender.clone(); let sender_clone = sender.clone();
// let id = FieldId::ProjectSettings(ProjectFieldId::Description); let id = FieldId::ProjectSettings(ProjectFieldId::Description);
// model model
// .distinct_key_up .distinct_key_up
// .keyup_wih_reset(id.to_str(), 20, move |ev| { .keyup_wih_reset(id.to_str(), 20, move |ev| {
// let sender = sender_clone.clone(); let sender = sender_clone.clone();
// let key_ev = seed::to_keyboard_event(&ev); let key_ev = seed::to_keyboard_event(&ev);
// let target = key_ev.target().unwrap(); let target = key_ev.target().unwrap();
// let el = seed::to_html_el(&target); let el = seed::to_html_el(&target);
// let value = el.inner_html(); let value = el.inner_html();
// sender.clone()(Some(Msg::StrInputChanged(id.clone(), sender.clone()(Some(Msg::StrInputChanged(id.clone(), value)));
// value))); }); });
} }
open_socket(&mut model, orders); open_socket(&mut model, orders);

View File

@ -42,7 +42,7 @@ where
) )
} }
fn epic_select_option<'l>(epic: &'l Epic) -> StyledSelectOption<'l> { fn epic_select_option(epic: &Epic) -> StyledSelectOption<'_> {
StyledSelectOption { StyledSelectOption {
value: epic.id as u32, value: epic.id as u32,
text: Some(epic.name.as_str()), text: Some(epic.name.as_str()),

View File

@ -0,0 +1,18 @@
use jirs_data::IssueId;
use seed::prelude::*;
pub type EvHandler = seed::EventHandler<crate::Msg>;
pub fn on_click_close_modal() -> EvHandler {
mouse_ev(Ev::Click, |ev| {
ev.prevent_default();
ev.stop_propagation();
crate::Msg::ModalDropped
})
}
pub fn on_click_open_delete_confirm(issue_id: IssueId) -> EvHandler {
mouse_ev(Ev::Click, move |_| {
crate::Msg::ModalOpened(crate::ModalType::DeleteIssueConfirm(Some(issue_id)))
})
}

View File

@ -2,6 +2,7 @@ pub use model::*;
pub use update::*; pub use update::*;
pub use view::*; pub use view::*;
mod events;
mod model; mod model;
mod update; mod update;
mod view; mod view;

View File

@ -19,7 +19,7 @@ use crate::components::styled_tip::styled_tip;
use crate::modals::epic_field; use crate::modals::epic_field;
use crate::modals::issues_edit::Model as EditIssueModal; use crate::modals::issues_edit::Model as EditIssueModal;
use crate::modals::time_tracking::time_tracking_field; use crate::modals::time_tracking::time_tracking_field;
use crate::model::{ModalType, Model}; use crate::model::Model;
use crate::shared::tracking_widget::tracking_link; use crate::shared::tracking_widget::tracking_link;
use crate::{BuildMsg, EditIssueModalSection, FieldChange, FieldId, Msg}; use crate::{BuildMsg, EditIssueModalSection, FieldChange, FieldId, Msg};
@ -95,14 +95,8 @@ fn modal_header(_model: &Model, modal: &EditIssueModal) -> Node<Msg> {
true, true,
))) )))
}); });
let close_handler = mouse_ev(Ev::Click, |ev| { let close_handler = super::events::on_click_close_modal();
ev.prevent_default(); let delete_confirmation_handler = super::events::on_click_open_delete_confirm(issue_id);
ev.stop_propagation();
Msg::ModalDropped
});
let delete_confirmation_handler = mouse_ev(Ev::Click, move |_| {
Msg::ModalOpened(ModalType::DeleteIssueConfirm(Some(issue_id)))
});
let copy_button = StyledButton { let copy_button = StyledButton {
variant: ButtonVariant::Empty, variant: ButtonVariant::Empty,
@ -181,7 +175,7 @@ fn modal_header(_model: &Model, modal: &EditIssueModal) -> Node<Msg> {
} }
#[inline(always)] #[inline(always)]
fn type_select_option<'l>(t: IssueType, text: &'l str) -> StyledSelectOption<'l> { fn type_select_option(t: IssueType, text: &str) -> StyledSelectOption<'_> {
let name = t.to_label(); let name = t.to_label();
StyledSelectOption { StyledSelectOption {
class_list: name, class_list: name,
@ -220,7 +214,7 @@ fn left_modal_column(model: &Model, modal: &EditIssueModal) -> Node<Msg> {
} }
.render(); .render();
let description = render_styled_editor(&description_state); let description = render_styled_editor(description_state);
let description_field = StyledField { let description_field = StyledField {
input: description, input: description,
..Default::default() ..Default::default()
@ -478,7 +472,7 @@ fn reporters_select(
} }
#[inline(always)] #[inline(always)]
fn reporter_select_option<'l>(user: &'l User) -> StyledSelectOption<'l> { fn reporter_select_option(user: &User) -> StyledSelectOption<'_> {
StyledSelectOption { StyledSelectOption {
value: user.id as u32, value: user.id as u32,
icon: Some( icon: Some(
@ -535,7 +529,7 @@ fn assignees_select(
} }
#[inline(always)] #[inline(always)]
fn assignee_select_option<'l>(user: &'l User) -> StyledSelectOption<'l> { fn assignee_select_option(user: &User) -> StyledSelectOption<'_> {
StyledSelectOption { StyledSelectOption {
value: user.id as u32, value: user.id as u32,
icon: Some( icon: Some(

View File

@ -265,7 +265,7 @@ pub struct Model {
pub epics_by_id: HashMap<EpicId, Epic>, pub epics_by_id: HashMap<EpicId, Epic>,
pub key_triggers: std::rc::Rc<std::cell::RefCell<HashMap<char, Box<dyn BuildMsg>>>>, pub key_triggers: std::rc::Rc<std::cell::RefCell<HashMap<char, Box<dyn BuildMsg>>>>,
// pub distinct_key_up: crate::shared::on_event::Distinct, pub distinct_key_up: crate::shared::on_event::Distinct,
pub show_extras: bool, pub show_extras: bool,
} }
@ -307,7 +307,7 @@ impl Model {
modals_stack: vec![], modals_stack: vec![],
modals: Modals::default(), modals: Modals::default(),
key_triggers: std::rc::Rc::new(std::cell::RefCell::new(HashMap::with_capacity(20))), key_triggers: std::rc::Rc::new(std::cell::RefCell::new(HashMap::with_capacity(20))),
// distinct_key_up: crate::shared::on_event::distinct(), distinct_key_up: crate::shared::on_event::distinct(),
} }
} }

View File

@ -6,6 +6,7 @@ use crate::components::styled_avatar::*;
use crate::components::styled_button::{ButtonVariant, StyledButton}; use crate::components::styled_button::{ButtonVariant, StyledButton};
use crate::components::styled_icon::*; use crate::components::styled_icon::*;
use crate::model::PageContent; use crate::model::PageContent;
use crate::pages::project_page::{events, StatusIssueIds};
use crate::{match_page, Model, Msg, Page}; use crate::{match_page, Model, Msg, Page};
#[inline(always)] #[inline(always)]
@ -14,23 +15,11 @@ pub fn project_board_lists(model: &Model) -> Node<Msg> {
let now = chrono::Utc::now().naive_utc(); let now = chrono::Utc::now().naive_utc();
let rows = project_page.visible_issues.iter().map(|per_epic| { let rows = project_page.visible_issues.iter().map(|per_epic| {
let columns: Vec<Node<Msg>> = per_epic let columns = per_epic
.per_status_issues .per_status_issues
.iter() .iter()
.map(|per_status| { .map(|per_status| project_issue_list(model, per_status));
let issues: Vec<&Issue> = per_status
.issue_ids
.iter()
.filter_map(|id| model.issues_by_id.get(id))
.collect();
project_issue_list(
model,
per_status.status_id,
&per_status.status_name,
issues.as_slice(),
)
})
.collect();
let epic_name = match per_epic.epic_ref.as_ref() { let epic_name = match per_epic.epic_ref.as_ref() {
Some((id, name, starts_at, ends_at)) => { Some((id, name, starts_at, ends_at)) => {
let id = *id; let id = *id;
@ -95,18 +84,18 @@ pub fn project_board_lists(model: &Model) -> Node<Msg> {
} }
#[inline(always)] #[inline(always)]
fn project_issue_list( fn project_issue_list(model: &Model, per_status: &StatusIssueIds) -> Node<Msg> {
model: &Model, let status_id = per_status.status_id;
status_id: IssueStatusId, let status_name = per_status.status_name.as_str();
status_name: &str,
issues: &[&Issue], let issues = per_status
) -> Node<Msg> { .issue_ids
let issues: Vec<Node<Msg>> = issues
.iter() .iter()
.map(|issue| ProjectIssue { model, issue }.render()) .filter_map(|id| model.issues_by_id.get(id))
.collect(); .map(|issue| ProjectIssue { model, issue }.render());
let drop_handler = crate::pages::project_page::events::on_drop_issue_drop_zone(status_id);
let drag_over_handler = crate::pages::project_page::events::on_drag_over_move_issue(status_id); let drop_handler = events::on_drop_issue_drop_zone(status_id);
let drag_over_handler = events::on_drag_over_move_issue(status_id);
div![ div![
C!["list"], C!["list"],
@ -133,7 +122,7 @@ impl<'l> ProjectIssue<'l> {
PageContent::Project(project_page) => project_page.issue_drag.is_dragging(), PageContent::Project(project_page) => project_page.issue_drag.is_dragging(),
_ => false, _ => false,
}; };
let avatars: Vec<Node<Msg>> = self let avatars = self
.issue .issue
.user_ids .user_ids
.iter() .iter()
@ -146,8 +135,7 @@ impl<'l> ProjectIssue<'l> {
..StyledAvatar::default() ..StyledAvatar::default()
} }
.render() .render()
}) });
.collect();
let issue_type_icon = StyledIcon { let issue_type_icon = StyledIcon {
icon: self.issue.issue_type.into(), icon: self.issue.issue_type.into(),
@ -166,13 +154,11 @@ impl<'l> ProjectIssue<'l> {
.render(); .render();
let issue_id = self.issue.id; let issue_id = self.issue.id;
let drag_started = crate::pages::project_page::events::on_drag_started_drag_issue(issue_id); let drag_started = events::on_drag_started_drag_issue(self.issue.id);
let drag_stopped = let drag_stopped = events::on_drag_stop_issue_drag_stop(self.issue.id);
crate::pages::project_page::events::on_drag_stop_issue_drag_stop(issue_id); let drag_over_handler = events::on_drag_enter_change_position(self.issue.id);
let drag_over_handler = let drag_out = events::on_drag_leave_issue_drag_leave(self.issue.id);
crate::pages::project_page::events::on_drag_enter_change_position(issue_id); let on_click = events::on_click_edit_issue(self.issue.id);
let drag_out = crate::pages::project_page::events::on_drag_leave_issue_drag_leave(issue_id);
let on_click = crate::pages::project_page::events::on_click_edit_issue(issue_id);
a![ a![
drag_started, drag_started,
@ -192,7 +178,7 @@ impl<'l> ProjectIssue<'l> {
div![C!["issueTypeIcon"], issue_type_icon], div![C!["issueTypeIcon"], issue_type_icon],
div![C!["issuePriorityIcon"], priority_icon] div![C!["issuePriorityIcon"], priority_icon]
], ],
div![C!["assignees"], avatars,], div![C!["assignees"], avatars],
] ]
] ]
] ]

View File

@ -6,14 +6,14 @@ pub fn is_email(s: &str) -> bool {
for c in s.chars() { for c in s.chars() {
match c { match c {
'\n' | ' ' | '\t' | '\r' => return false,
'@' if !has_at => { '@' if !has_at => {
has_at = true; has_at = true;
} }
'@' if has_at => return false,
'.' if has_at => { '.' if has_at => {
has_dot = true; has_dot = true;
} }
'\n' | ' ' | '\t' | '\r' => return false,
'@' if has_at => return false,
_ if has_dot => return true, _ if has_dot => return true,
_ => (), _ => (),
} }