Finish 3rd refactor step

This commit is contained in:
Adrian Woźniak 2021-04-19 15:09:10 +02:00
parent 1b5ac3c9c3
commit 1117e878a8
22 changed files with 131 additions and 111 deletions

View File

@ -65,14 +65,14 @@ impl actix::Handler<InnerMsg> for WsServer {
room.remove(&user_id);
self.sessions.remove(&user_id);
} else {
let v = self.sessions.entry(user_id).or_insert_with(Vec::new);
let mut old = vec![];
std::mem::swap(&mut old, v);
for r in old {
if r != recipient {
v.push(r);
}
}
let v = self
.sessions
.remove(&user_id)
.unwrap_or_default()
.into_iter()
.filter(|r| r != &recipient)
.collect::<Vec<Recipient<InnerMsg>>>();
self.sessions.insert(user_id, v);
}
}
InnerMsg::SendToUser(user_id, msg) => {

View File

@ -24,6 +24,7 @@ pub enum BoardPageChange {
}
#[derive(Clone, Debug, PartialEq)]
#[repr(C)]
pub enum UsersPageChange {
ResetForm,
}
@ -45,11 +46,13 @@ pub enum ProjectPageChange {
}
#[derive(Clone, Debug, PartialEq)]
#[repr(C)]
pub enum ProfilePageChange {
SubmitForm,
}
#[derive(Clone, Debug, PartialEq)]
#[repr(C)]
pub enum InvitationPageChange {
SubmitForm,
}

View File

@ -14,6 +14,7 @@ pub struct StyledAvatar<'l> {
}
impl<'l> StyledAvatar<'l> {
#[inline(always)]
pub fn render(self) -> Node<Msg> {
let StyledAvatar {
avatar_url,
@ -63,6 +64,7 @@ impl<'l> StyledAvatar<'l> {
}
impl<'l> Default for StyledAvatar<'l> {
#[inline(always)]
fn default() -> Self {
Self {
avatar_url: None,

View File

@ -4,6 +4,7 @@ use seed::*;
use crate::{ButtonId, Msg};
#[allow(dead_code)]
#[repr(C)]
pub enum ButtonVariant {
Primary,
Success,
@ -13,6 +14,7 @@ pub enum ButtonVariant {
}
impl ButtonVariant {
#[inline(always)]
fn to_str(&self) -> &'static str {
match self {
ButtonVariant::Primary => "primary",
@ -44,6 +46,7 @@ pub struct StyledButton<'l> {
}
impl<'l> StyledButton<'l> {
#[inline(always)]
pub fn secondary_with_text_and_icon(text: &'l str, icon: Node<Msg>) -> Self {
Self {
variant: ButtonVariant::Secondary,
@ -61,6 +64,7 @@ impl<'l> StyledButton<'l> {
}
impl<'l> Default for StyledButton<'l> {
#[inline(always)]
fn default() -> Self {
Self {
variant: ButtonVariant::Primary,
@ -71,7 +75,7 @@ impl<'l> Default for StyledButton<'l> {
on_click: None,
children: vec![],
class_list: "",
button_type: "",
button_type: "submit",
button_id: None,
}
}

View File

@ -10,10 +10,12 @@ pub struct StyledCheckboxState {
}
impl StyledCheckboxState {
#[inline(always)]
pub fn new(field_id: FieldId, value: u32) -> Self {
Self { field_id, value }
}
#[inline(always)]
pub fn update(&mut self, msg: &Msg) {
if let Msg::U32InputChanged(field_id, value) = msg {
if field_id != &self.field_id {
@ -35,6 +37,7 @@ pub struct ChildBuilder<'l> {
}
impl<'l> Default for ChildBuilder<'l> {
#[inline(always)]
fn default() -> Self {
Self {
field_id: FieldId::TextFilterBoard,
@ -48,6 +51,7 @@ impl<'l> Default for ChildBuilder<'l> {
}
impl<'l> ChildBuilder<'l> {
#[inline(always)]
pub fn render(self) -> Node<Msg> {
let ChildBuilder {
field_id,
@ -60,7 +64,7 @@ impl<'l> ChildBuilder<'l> {
let id = field_id.to_string();
let handler: EventHandler<Msg> = {
let id = field_id.clone();
let id = field_id;
mouse_ev(Ev::Click, move |_| Msg::U32InputChanged(id, value))
};
@ -93,6 +97,7 @@ impl<'l, Options> Default for StyledCheckbox<'l, Options>
where
Options: Iterator<Item = ChildBuilder<'l>>,
{
#[inline(always)]
fn default() -> Self {
Self {
options: None,
@ -105,6 +110,7 @@ impl<'l, Options> StyledCheckbox<'l, Options>
where
Options: Iterator<Item = ChildBuilder<'l>>,
{
#[inline(always)]
pub fn render(self) -> Node<Msg> {
let StyledCheckbox {
options,

View File

@ -20,6 +20,7 @@ pub struct StyledConfirmModal<'l> {
}
impl<'l> StyledConfirmModal<'l> {
#[inline(always)]
pub fn render(self) -> Node<Msg> {
let StyledConfirmModal {
title,
@ -67,6 +68,7 @@ impl<'l> StyledConfirmModal<'l> {
}
impl<'l> Default for StyledConfirmModal<'l> {
#[inline(always)]
fn default() -> Self {
Self {
title: TITLE,

View File

@ -25,6 +25,7 @@ pub struct StyledDateTimeInputState {
}
impl StyledDateTimeInputState {
#[inline(always)]
pub fn new(field_id: FieldId, timestamp: Option<NaiveDateTime>) -> Self {
Self {
field_id,
@ -33,11 +34,13 @@ impl StyledDateTimeInputState {
}
}
#[inline(always)]
pub fn reset(&mut self) {
self.timestamp = None;
self.popup_visible = false;
}
#[inline(always)]
pub fn update(&mut self, msg: &Msg, _orders: &mut impl Orders<Msg>) {
match msg {
Msg::StyledDateTimeInputChanged(
@ -68,6 +71,22 @@ impl StyledDateTimeInputState {
}
}
struct DateRange(NaiveDateTime, NaiveDateTime);
impl Iterator for DateRange {
type Item = NaiveDateTime;
#[inline(always)]
fn next(&mut self) -> Option<Self::Item> {
if self.0 <= self.1 {
let next = self.0 + Duration::days(1);
Some(std::mem::replace(&mut self.0, next))
} else {
None
}
}
}
pub struct StyledDateTimeInput {
pub field_id: FieldId,
pub timestamp: Option<chrono::NaiveDateTime>,
@ -75,6 +94,7 @@ pub struct StyledDateTimeInput {
}
impl StyledDateTimeInput {
#[inline(always)]
pub fn render(self) -> Node<Msg> {
let timestamp = self
.timestamp
@ -82,21 +102,16 @@ impl StyledDateTimeInput {
let start = timestamp.with_day0(0).unwrap();
let end = (start + Duration::days(32)).with_day0(0).unwrap();
let calendar_start = StyledDateTimeInput::calendar_start(start.clone());
let calendar_end = StyledDateTimeInput::calendar_end(end.clone());
let calendar_start = StyledDateTimeInput::calendar_start(start);
let calendar_end = StyledDateTimeInput::calendar_end(end);
let current_month_range = start..=end;
let mut current = calendar_start;
let current = calendar_start;
let mut weeks = vec![];
let range = calendar_start..=calendar_end;
let mut current_week = vec![];
loop {
if !range.contains(&current) {
break;
}
for current in DateRange(calendar_start, calendar_end) {
if current.weekday() == Weekday::Mon && !current_week.is_empty() {
weeks.push(div![C!["week"], current_week]);
current_week = vec![];
weeks.push(div![C!["week"], std::mem::take(&mut current_week)]);
}
current_week.push(
@ -108,9 +123,8 @@ impl StyledDateTimeInput {
}
.render(),
);
current += Duration::days(1);
}
if !current_week.is_empty() {
weeks.push(div![C!["week"], current_week]);
}
@ -263,6 +277,7 @@ pub struct DayCell<'l> {
}
impl<'l> DayCell<'l> {
#[inline(always)]
pub fn render(self) -> Node<Msg> {
let on_click = {
let field_id = self.field_id.clone();
@ -292,6 +307,7 @@ impl<'l> DayCell<'l> {
]
}
#[inline(always)]
fn is_selected(&self) -> bool {
*self.timestamp == *self.current
}

View File

@ -5,6 +5,7 @@ use crate::components::styled_textarea::StyledTextarea;
use crate::{FieldChange, FieldId, Msg};
#[derive(Debug, Clone, PartialOrd, PartialEq, Hash)]
#[repr(C)]
pub enum Mode {
Editor,
View,
@ -17,6 +18,7 @@ pub struct StyledEditorState {
}
impl StyledEditorState {
#[inline(always)]
pub fn new<S: Into<String>>(mode: Mode, text: S) -> Self {
Self {
mode,
@ -36,6 +38,7 @@ pub struct StyledEditor<'l> {
}
impl<'l> Default for StyledEditor<'l> {
#[inline(always)]
fn default() -> Self {
Self {
id: None,
@ -49,7 +52,7 @@ impl<'l> Default for StyledEditor<'l> {
}
impl<'l> StyledEditor<'l> {
#[inline]
#[inline(always)]
pub fn render(self) -> Node<Msg> {
let StyledEditor {
id,
@ -71,22 +74,16 @@ impl<'l> StyledEditor<'l> {
let text_area = StyledTextarea {
id: Some(id),
height: 40,
max_height: 0,
value: initial_text,
class_list: "",
update_event,
placeholder: "",
disable_auto_resize: false,
..Default::default()
}
.render();
div![
C!["styledEditor"],
label![
C![
"navbar viewTab activeTab",
IF![mode == Mode::View => "activeTab"]
],
C!["navbar viewTab", IF![mode == Mode::View => "activeTab"]],
attrs![At::For => view_id.as_str()],
"View",
on_view_clicked
@ -118,7 +115,7 @@ impl<'l> StyledEditor<'l> {
}
}
#[inline]
#[inline(always)]
fn click_handler(field_id: FieldId, new_mode: Mode) -> EventHandler<Msg> {
mouse_ev(Ev::Click, move |ev| {
ev.stop_propagation();

View File

@ -24,19 +24,12 @@ impl<'l> Default for StyledField<'l> {
impl<'l> StyledField<'l> {
pub fn render(self) -> Node<Msg> {
let StyledField {
label,
tip,
input,
class_list,
} = self;
let tip_node = tip.map_or_else(|| empty![], |s| div![C!["styledTip"], s]);
div![
C!["styledField", class_list],
seed::label![C!["styledLabel"], label],
input,
tip_node,
C!["styledField", self.class_list],
seed::label![C!["styledLabel"], self.label],
self.input,
self.tip
.map_or_else(|| empty![], |s| div![C!["styledTip"], s]),
]
}
}

View File

@ -11,21 +11,16 @@ pub struct StyledForm<'l> {
}
impl<'l> StyledForm<'l> {
#[inline]
#[inline(always)]
pub fn render(self) -> Node<Msg> {
let StyledForm {
heading,
fields,
on_submit,
} = self;
let handlers = match on_submit {
Some(handler) => vec![handler],
_ => vec![],
};
seed::form![
handlers,
self.on_submit,
C!["styledForm"],
div![C!["formElement"], div![C!["formHeading"], heading], fields],
div![
C!["formElement"],
div![C!["formHeading"], self.heading],
self.fields
],
]
}
}

View File

@ -5,6 +5,7 @@ use crate::components::styled_icon::{Icon, StyledIcon};
use crate::{FieldId, Msg};
#[derive(Clone, Debug, PartialOrd, PartialEq)]
#[repr(C)]
pub enum InputVariant {
Normal,
Primary,
@ -20,13 +21,6 @@ impl InputVariant {
}
}
impl ToString for InputVariant {
#[inline]
fn to_string(&self) -> String {
self.to_str().to_string()
}
}
#[derive(Clone, Debug, PartialOrd, PartialEq)]
pub struct StyledInputState {
id: FieldId,
@ -37,7 +31,7 @@ pub struct StyledInputState {
}
impl StyledInputState {
#[inline]
#[inline(always)]
pub fn new<S>(id: FieldId, value: S) -> Self
where
S: Into<String>,
@ -51,34 +45,34 @@ impl StyledInputState {
}
}
#[inline]
#[inline(always)]
pub fn with_min(mut self, min: Option<usize>) -> Self {
self.min = min;
self
}
#[inline]
#[inline(always)]
pub fn with_max(mut self, max: Option<usize>) -> Self {
self.max = max;
self
}
#[inline]
#[inline(always)]
pub fn to_i32(&self) -> Option<i32> {
self.value.parse::<i32>().ok()
}
#[inline]
#[inline(always)]
pub fn to_f64(&self) -> Option<f64> {
self.value.parse::<f64>().ok()
}
#[inline]
#[inline(always)]
pub fn represent_f64_as_i32(&self) -> Option<i32> {
self.to_f64().map(|f| (f * 10.0f64) as i32)
}
#[inline]
#[inline(always)]
pub fn update(&mut self, msg: &Msg) {
match msg {
Msg::StrInputChanged(field_id, s) if field_id == &self.id => {
@ -89,11 +83,12 @@ impl StyledInputState {
}
}
#[inline]
#[inline(always)]
pub fn reset(&mut self) {
self.value.clear();
}
#[inline(always)]
pub fn is_valid(&self) -> bool {
match (
self.touched,
@ -142,7 +137,7 @@ impl<'l, 'm: 'l> Default for StyledInput<'l, 'm> {
}
impl<'l, 'm: 'l> StyledInput<'l, 'm> {
#[inline]
#[inline(always)]
pub fn new_with_id_and_value_and_valid(id: FieldId, value: &'m str, valid: bool) -> Self {
Self {
id: Some(id),
@ -160,6 +155,7 @@ impl<'l, 'm: 'l> StyledInput<'l, 'm> {
}
impl<'l, 'm: 'l> StyledInput<'l, 'm> {
#[inline(always)]
pub fn render(self) -> Node<Msg> {
let StyledInput {
id,

View File

@ -12,6 +12,7 @@ pub struct StyledLink<'l> {
}
impl<'l> StyledLink<'l> {
#[inline(always)]
pub fn render(self) -> Node<Msg> {
let StyledLink {
children,

View File

@ -6,20 +6,23 @@ use crate::Msg;
#[allow(dead_code)]
#[derive(Debug, Copy, Clone, PartialOrd, PartialEq)]
#[repr(C)]
pub enum ModalVariant {
Center,
Aside,
}
impl ModalVariant {
pub fn to_class_name(&self) -> &str {
#[inline(always)]
pub fn to_class_name(self) -> &'static str {
match self {
ModalVariant::Center => "center",
ModalVariant::Aside => "aside",
}
}
pub fn to_icon_class_name(&self) -> &str {
#[inline(always)]
pub fn to_icon_class_name(self) -> &'static str {
match self {
ModalVariant::Center => "modalVariantCenter",
ModalVariant::Aside => "modalVariantAside",
@ -37,6 +40,7 @@ pub struct StyledModal<'l> {
}
impl<'l> Default for StyledModal<'l> {
#[inline(always)]
fn default() -> Self {
Self {
variant: ModalVariant::Center,
@ -49,6 +53,7 @@ impl<'l> Default for StyledModal<'l> {
}
impl<'l> StyledModal<'l> {
#[inline(always)]
pub fn centered_with_width_and_body(width: usize, children: Vec<Node<Msg>>) -> Self {
Self {
variant: ModalVariant::Center,
@ -61,7 +66,7 @@ impl<'l> StyledModal<'l> {
}
impl<'l> StyledModal<'l> {
#[inline]
#[inline(always)]
pub fn render(self) -> Node<Msg> {
let StyledModal {
variant,

View File

@ -16,6 +16,7 @@ pub enum StyledSelectChanged {
}
#[derive(Copy, Clone, Debug, PartialEq)]
#[repr(C)]
pub enum SelectVariant {
Empty,
Normal,
@ -28,7 +29,7 @@ impl Default for SelectVariant {
}
impl SelectVariant {
pub fn to_str<'l>(&self) -> &'l str {
pub fn to_str<'l>(self) -> &'l str {
match self {
SelectVariant::Empty => "empty",
SelectVariant::Normal => "normal",
@ -36,12 +37,6 @@ impl SelectVariant {
}
}
impl std::fmt::Display for SelectVariant {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.to_str())
}
}
#[derive(Debug, Clone, PartialOrd, PartialEq, Hash)]
pub struct StyledSelectState {
pub field_id: FieldId,
@ -68,7 +63,7 @@ impl StyledSelectState {
}
}
pub fn update(&mut self, msg: &Msg, _orders: &mut impl Orders<Msg>) {
pub fn update(&mut self, msg: &Msg, orders: &mut impl Orders<Msg>) {
let field_id = match msg {
Msg::StyledSelectChanged(field_id, ..) => field_id,
_ => return,
@ -84,6 +79,7 @@ impl StyledSelectState {
}
}
Msg::StyledSelectChanged(_, StyledSelectChanged::Text(text)) => {
orders.skip();
self.text_filter = text.clone();
}
Msg::StyledSelectChanged(_, StyledSelectChanged::Changed(Some(v))) => {

View File

@ -75,29 +75,26 @@ impl<'l> StyledSelectOption<'l> {
variant,
} = self;
let icon_node = match icon {
Some(icon) => icon,
_ => empty![],
};
let label_node = match text {
Some(text) => div![
C![
variant.to_str(),
name.as_deref()
.map(|s| format!("{}Label", s))
.unwrap_or_default(),
match display_type {
DisplayType::SelectOption => "optionLabel",
DisplayType::SelectValue | DisplayType::SelectMultiValue =>
"selectItemLabel",
},
class_list
],
text
],
_ => empty![],
};
let label_node = text.map_or_else(
|| Node::Empty,
|text| {
div![
C![
variant.to_str(),
name.as_deref()
.map(|s| format!("{}Label", s))
.unwrap_or_default(),
match display_type {
DisplayType::SelectOption => "optionLabel",
DisplayType::SelectValue | DisplayType::SelectMultiValue =>
"selectItemLabel",
},
class_list
],
text
]
},
);
div![
C![
@ -109,7 +106,7 @@ impl<'l> StyledSelectOption<'l> {
},
class_list
],
icon_node,
icon,
label_node,
IF![display_type == DisplayType::SelectMultiValue => close_icon()]
]

View File

@ -68,7 +68,7 @@ impl<'l> StyledTextarea<'l> {
}
let handler_disable_auto_resize = disable_auto_resize;
let resize_handler = ev(Ev::Change, move |event| {
let resize_handler = ev(Ev::KeyUp, move |event| {
event.stop_propagation();
if handler_disable_auto_resize {
return None as Option<Msg>;

View File

@ -4,6 +4,7 @@ use seed::*;
use crate::Msg;
#[derive(Debug, Copy, Clone)]
#[repr(C)]
pub enum TooltipVariant {
About,
Messages,
@ -19,7 +20,7 @@ impl Default for TooltipVariant {
}
impl TooltipVariant {
pub fn to_str(&self) -> &'static str {
pub fn to_str(self) -> &'static str {
match self {
TooltipVariant::About => "about",
TooltipVariant::Messages => "messages",

View File

@ -17,6 +17,7 @@ pub enum RteField {
}
#[derive(Clone, Debug, PartialOrd, PartialEq, Hash)]
#[repr(C)]
pub enum ButtonId {
JustifyAll,
JustifyCenter,
@ -48,6 +49,7 @@ pub enum ButtonId {
}
impl ButtonId {
#[inline(always)]
pub fn to_str<'l>(&self) -> &'l str {
match self {
ButtonId::JustifyAll => "justifyAll",

View File

@ -35,6 +35,7 @@ mod ws;
// static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
#[derive(Debug)]
#[repr(C)]
pub enum ResourceKind {
Issue,
IssueStatus,
@ -48,6 +49,7 @@ pub enum ResourceKind {
}
#[derive(Debug)]
#[repr(C)]
pub enum OperationKind {
ListLoaded,
SingleLoaded,

View File

@ -97,7 +97,7 @@ pub fn update(msg: &Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
FieldId::EditIssueModal(EditIssueModalSection::Issue(IssueFieldId::Assignees)),
StyledSelectChanged::RemoveMulti(value),
) => {
let old = std::mem::replace(&mut modal.payload.user_ids, vec![]);
let old = std::mem::take(&mut modal.payload.user_ids);
let dropped = *value as i32;
for id in old.into_iter() {
if id != dropped {

View File

@ -87,6 +87,7 @@ pub enum Page {
}
impl Page {
#[inline(always)]
pub fn to_path(self) -> String {
match self {
Page::Project => "/board".to_string(),
@ -122,6 +123,7 @@ pub struct UpdateProjectForm {
}
#[derive(Debug, Clone, Copy, PartialOrd, PartialEq)]
#[repr(C)]
pub enum InvitationFormState {
Initial = 1,
Sent = 2,

View File

@ -78,7 +78,7 @@ pub fn open_socket(model: &mut Model, orders: &mut impl Orders<Msg>) {
error!("Failed to open WebSocket");
None as Option<Msg>
})
.protocols(&["jirs"])
// .protocols(&["jirs"])
.build_and_open()
.ok();
}