Reduce memory footprint, fix alloc vec error
This commit is contained in:
parent
d8855bdfec
commit
8478f5d112
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -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",
|
||||||
|
@ -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"]
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
|
@ -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()),
|
||||||
|
18
web/src/modals/issues_edit/events.rs
Normal file
18
web/src/modals/issues_edit/events.rs
Normal 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)))
|
||||||
|
})
|
||||||
|
}
|
@ -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;
|
||||||
|
@ -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(
|
||||||
|
@ -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(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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],
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
@ -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,
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user