Start display messages
This commit is contained in:
parent
92e129115a
commit
2d55c5f143
@ -1,8 +1,9 @@
|
||||
use crate::FieldId;
|
||||
use jirs_data::{IssueId, IssueStatusId};
|
||||
use seed::prelude::WebSocketMessage;
|
||||
|
||||
use jirs_data::{IssueId, IssueStatusId, WsMsg};
|
||||
|
||||
use crate::shared::styled_editor::Mode as TabMode;
|
||||
use seed::prelude::WebSocketMessage;
|
||||
use crate::FieldId;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum FieldChange {
|
||||
@ -59,10 +60,11 @@ pub enum PageChanged {
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum WebSocketChanged {
|
||||
WsMsg(jirs_data::WsMsg),
|
||||
WsMsg(WsMsg),
|
||||
WebSocketMessage(WebSocketMessage),
|
||||
WebSocketMessageLoaded(Vec<u8>),
|
||||
WebSocketOpened,
|
||||
WebSocketClosed,
|
||||
SendPing,
|
||||
Bounced(WsMsg),
|
||||
}
|
||||
|
@ -7,8 +7,9 @@ use jirs_data::*;
|
||||
|
||||
use crate::model::{ModalType, Model, Page};
|
||||
use crate::shared::styled_select::StyledSelectChange;
|
||||
use crate::shared::{go_to_board, go_to_login};
|
||||
use crate::ws::{open_socket, read_incoming, send_ws_msg};
|
||||
use crate::shared::styled_tooltip::Variant as StyledTooltip;
|
||||
use crate::shared::{go_to_board, go_to_login, styled_tooltip};
|
||||
use crate::ws::{flush_queue, open_socket, read_incoming, send_ws_msg};
|
||||
|
||||
mod changes;
|
||||
mod fields;
|
||||
@ -40,7 +41,7 @@ pub enum Msg {
|
||||
|
||||
StyledSelectChanged(FieldId, StyledSelectChange),
|
||||
InternalFailure(String),
|
||||
ToggleAboutTooltip,
|
||||
ToggleTooltip(StyledTooltip),
|
||||
|
||||
// Auth Token
|
||||
AuthTokenStored,
|
||||
@ -100,12 +101,13 @@ fn update(msg: Msg, model: &mut model::Model, orders: &mut impl Orders<Msg>) {
|
||||
Msg::WebSocketChange(change) => {
|
||||
match change {
|
||||
WebSocketChanged::WebSocketOpened => {
|
||||
authorize_or_redirect(model);
|
||||
send_ws_msg(WsMsg::Ping, model.ws.as_ref());
|
||||
flush_queue(model, orders);
|
||||
send_ws_msg(WsMsg::Ping, model.ws.as_ref(), orders);
|
||||
authorize_or_redirect(model, orders);
|
||||
return;
|
||||
}
|
||||
WebSocketChanged::SendPing => {
|
||||
send_ws_msg(WsMsg::Ping, model.ws.as_ref());
|
||||
send_ws_msg(WsMsg::Ping, model.ws.as_ref(), orders);
|
||||
return;
|
||||
}
|
||||
WebSocketChanged::WebSocketMessage(incoming) => {
|
||||
@ -135,6 +137,11 @@ fn update(msg: Msg, model: &mut model::Model, orders: &mut impl Orders<Msg>) {
|
||||
WebSocketChanged::WebSocketClosed => {
|
||||
open_socket(model, orders);
|
||||
}
|
||||
WebSocketChanged::Bounced(ws_msg) => {
|
||||
model.ws_queue.push(ws_msg);
|
||||
open_socket(model, orders);
|
||||
return;
|
||||
}
|
||||
};
|
||||
Msg::WebSocketChange(change)
|
||||
}
|
||||
@ -147,23 +154,24 @@ fn update(msg: Msg, model: &mut model::Model, orders: &mut impl Orders<Msg>) {
|
||||
|
||||
match &msg {
|
||||
Msg::AuthTokenStored => {
|
||||
go_to_board();
|
||||
orders.skip().send_msg(Msg::ChangePage(Page::Project));
|
||||
authorize_or_redirect(model);
|
||||
go_to_board(orders);
|
||||
return;
|
||||
}
|
||||
Msg::AuthTokenErased => {
|
||||
go_to_login();
|
||||
orders.skip().send_msg(Msg::ChangePage(Page::SignIn));
|
||||
authorize_or_redirect(model);
|
||||
go_to_login(orders);
|
||||
return;
|
||||
}
|
||||
Msg::ChangePage(page) => {
|
||||
model.page = *page;
|
||||
}
|
||||
Msg::ToggleAboutTooltip => {
|
||||
Msg::ToggleTooltip(variant) => match variant {
|
||||
styled_tooltip::Variant::About => {
|
||||
model.about_tooltip_visible = !model.about_tooltip_visible;
|
||||
}
|
||||
styled_tooltip::Variant::Messages => {
|
||||
model.messages_tooltip_visible = !model.messages_tooltip_visible;
|
||||
}
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
crate::modal::update(&msg, model, orders);
|
||||
@ -250,7 +258,6 @@ fn after_mount(url: Url, orders: &mut impl Orders<Msg>) -> AfterMount<Model> {
|
||||
WS_URL = "".to_string();
|
||||
}
|
||||
model.page = resolve_page(url).unwrap_or_else(|| Page::Project);
|
||||
log!(model);
|
||||
open_socket(&mut model, orders);
|
||||
AfterMount::new(model).url_handling(UrlHandling::PassToRoutes)
|
||||
}
|
||||
@ -279,17 +286,17 @@ fn window_events(_model: &Model) -> Vec<EventHandler<Msg>> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn authorize_or_redirect(model: &Model) {
|
||||
fn authorize_or_redirect(model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
let pathname = seed::document().location().unwrap().pathname().unwrap();
|
||||
match crate::shared::read_auth_token() {
|
||||
Ok(token) => {
|
||||
send_ws_msg(WsMsg::AuthorizeRequest(token), model.ws.as_ref());
|
||||
send_ws_msg(WsMsg::AuthorizeRequest(token), model.ws.as_ref(), orders);
|
||||
}
|
||||
Err(..) => {
|
||||
let pathname = seed::document().location().unwrap().pathname().unwrap();
|
||||
match pathname.as_str() {
|
||||
"/login" | "/register" | "/invite" => {}
|
||||
_ => {
|
||||
go_to_login();
|
||||
go_to_login(orders);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -53,6 +53,7 @@ pub fn update(msg: &Msg, model: &mut crate::model::Model, orders: &mut impl Orde
|
||||
send_ws_msg(
|
||||
jirs_data::WsMsg::IssueCreateRequest(payload),
|
||||
model.ws.as_ref(),
|
||||
orders,
|
||||
);
|
||||
}
|
||||
Msg::WebSocketChange(WebSocketChanged::WsMsg(WsMsg::IssueCreated(issue))) => {
|
||||
|
@ -22,6 +22,7 @@ pub fn update(msg: &Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
crate::ws::send_ws_msg(
|
||||
WsMsg::IssueStatusDelete(*issue_status_id),
|
||||
model.ws.as_ref(),
|
||||
orders,
|
||||
);
|
||||
}
|
||||
Msg::WebSocketChange(WebSocketChanged::WsMsg(WsMsg::IssueStatusDeleted(_))) => {
|
||||
|
@ -50,6 +50,7 @@ pub fn update(msg: &Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
PayloadVariant::IssueType(modal.payload.issue_type),
|
||||
),
|
||||
model.ws.as_ref(),
|
||||
orders,
|
||||
);
|
||||
}
|
||||
Msg::StyledSelectChanged(
|
||||
@ -64,6 +65,7 @@ pub fn update(msg: &Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
PayloadVariant::I32(modal.payload.issue_status_id),
|
||||
),
|
||||
model.ws.as_ref(),
|
||||
orders,
|
||||
);
|
||||
}
|
||||
Msg::StyledSelectChanged(
|
||||
@ -78,6 +80,7 @@ pub fn update(msg: &Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
PayloadVariant::I32(modal.payload.reporter_id),
|
||||
),
|
||||
model.ws.as_ref(),
|
||||
orders,
|
||||
);
|
||||
}
|
||||
Msg::StyledSelectChanged(
|
||||
@ -92,6 +95,7 @@ pub fn update(msg: &Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
PayloadVariant::VecI32(modal.payload.user_ids.clone()),
|
||||
),
|
||||
model.ws.as_ref(),
|
||||
orders,
|
||||
);
|
||||
}
|
||||
Msg::StyledSelectChanged(
|
||||
@ -113,6 +117,7 @@ pub fn update(msg: &Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
PayloadVariant::VecI32(modal.payload.user_ids.clone()),
|
||||
),
|
||||
model.ws.as_ref(),
|
||||
orders,
|
||||
);
|
||||
}
|
||||
Msg::StyledSelectChanged(
|
||||
@ -127,6 +132,7 @@ pub fn update(msg: &Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
PayloadVariant::IssuePriority(modal.payload.priority),
|
||||
),
|
||||
model.ws.as_ref(),
|
||||
orders,
|
||||
);
|
||||
}
|
||||
Msg::StrInputChanged(
|
||||
@ -141,6 +147,7 @@ pub fn update(msg: &Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
PayloadVariant::String(modal.payload.title.clone()),
|
||||
),
|
||||
model.ws.as_ref(),
|
||||
orders,
|
||||
);
|
||||
}
|
||||
Msg::StrInputChanged(
|
||||
@ -163,6 +170,7 @@ pub fn update(msg: &Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
),
|
||||
),
|
||||
model.ws.as_ref(),
|
||||
orders,
|
||||
);
|
||||
}
|
||||
// TimeSpent
|
||||
@ -178,6 +186,7 @@ pub fn update(msg: &Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
PayloadVariant::OptionI32(modal.payload.time_spent),
|
||||
),
|
||||
model.ws.as_ref(),
|
||||
orders,
|
||||
);
|
||||
}
|
||||
Msg::StyledSelectChanged(
|
||||
@ -192,6 +201,7 @@ pub fn update(msg: &Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
PayloadVariant::OptionI32(modal.payload.time_spent),
|
||||
),
|
||||
model.ws.as_ref(),
|
||||
orders,
|
||||
);
|
||||
}
|
||||
// Time Remaining
|
||||
@ -207,6 +217,7 @@ pub fn update(msg: &Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
PayloadVariant::OptionI32(modal.payload.time_remaining),
|
||||
),
|
||||
model.ws.as_ref(),
|
||||
orders,
|
||||
);
|
||||
}
|
||||
Msg::StyledSelectChanged(
|
||||
@ -222,6 +233,7 @@ pub fn update(msg: &Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
PayloadVariant::OptionI32(modal.payload.time_remaining),
|
||||
),
|
||||
model.ws.as_ref(),
|
||||
orders,
|
||||
);
|
||||
}
|
||||
// Estimate
|
||||
@ -237,6 +249,7 @@ pub fn update(msg: &Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
PayloadVariant::OptionI32(modal.payload.estimate),
|
||||
),
|
||||
model.ws.as_ref(),
|
||||
orders,
|
||||
);
|
||||
}
|
||||
Msg::StyledSelectChanged(
|
||||
@ -251,6 +264,7 @@ pub fn update(msg: &Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
PayloadVariant::OptionI32(modal.payload.estimate),
|
||||
),
|
||||
model.ws.as_ref(),
|
||||
orders,
|
||||
);
|
||||
}
|
||||
Msg::ModalChanged(FieldChange::TabChanged(
|
||||
@ -290,7 +304,7 @@ pub fn update(msg: &Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
issue_id: modal.id,
|
||||
}),
|
||||
};
|
||||
send_ws_msg(msg, model.ws.as_ref());
|
||||
send_ws_msg(msg, model.ws.as_ref(), orders);
|
||||
orders
|
||||
.skip()
|
||||
.send_msg(Msg::ModalChanged(FieldChange::ToggleCommentForm(
|
||||
@ -314,7 +328,11 @@ pub fn update(msg: &Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
modal.comment_form.creating = true;
|
||||
}
|
||||
Msg::DeleteComment(comment_id) => {
|
||||
send_ws_msg(WsMsg::CommentDeleteRequest(*comment_id), model.ws.as_ref());
|
||||
send_ws_msg(
|
||||
WsMsg::CommentDeleteRequest(*comment_id),
|
||||
model.ws.as_ref(),
|
||||
orders,
|
||||
);
|
||||
orders.skip().send_msg(Msg::ModalDropped);
|
||||
}
|
||||
|
||||
|
@ -19,8 +19,7 @@ pub fn update(msg: &Msg, model: &mut model::Model, orders: &mut impl Orders<Msg>
|
||||
match msg {
|
||||
Msg::ModalDropped => match model.modals.pop() {
|
||||
Some(ModalType::EditIssue(..)) | Some(ModalType::AddIssue(..)) => {
|
||||
go_to_board();
|
||||
orders.send_msg(Msg::ChangePage(Page::Project));
|
||||
go_to_board(orders);
|
||||
}
|
||||
_ => (),
|
||||
},
|
||||
@ -40,14 +39,14 @@ pub fn update(msg: &Msg, model: &mut model::Model, orders: &mut impl Orders<Msg>
|
||||
Msg::WebSocketChange(WebSocketChanged::WsMsg(WsMsg::ProjectIssuesLoaded(_issues))) => {
|
||||
match model.page {
|
||||
Page::EditIssue(issue_id) if model.modals.is_empty() => {
|
||||
push_edit_modal(issue_id, model)
|
||||
push_edit_modal(issue_id, model, orders)
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
Msg::ChangePage(Page::EditIssue(issue_id)) => {
|
||||
push_edit_modal(*issue_id, model);
|
||||
push_edit_modal(*issue_id, model, orders);
|
||||
}
|
||||
|
||||
Msg::ChangePage(Page::AddIssue) => {
|
||||
@ -102,7 +101,7 @@ pub fn view(model: &model::Model) -> Node<Msg> {
|
||||
section![id!["modals"], modals]
|
||||
}
|
||||
|
||||
fn push_edit_modal(issue_id: i32, model: &mut Model) {
|
||||
fn push_edit_modal(issue_id: i32, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
let time_tracking_type = model
|
||||
.project
|
||||
.as_ref()
|
||||
@ -118,6 +117,10 @@ fn push_edit_modal(issue_id: i32, model: &mut Model) {
|
||||
Box::new(EditIssueModal::new(issue, time_tracking_type)),
|
||||
)
|
||||
};
|
||||
send_ws_msg(WsMsg::IssueCommentsRequest(issue_id), model.ws.as_ref());
|
||||
send_ws_msg(
|
||||
WsMsg::IssueCommentsRequest(issue_id),
|
||||
model.ws.as_ref(),
|
||||
orders,
|
||||
);
|
||||
model.modals.push(modal);
|
||||
}
|
||||
|
@ -434,10 +434,12 @@ pub enum PageContent {
|
||||
#[derive(Debug)]
|
||||
pub struct Model {
|
||||
pub ws: Option<WebSocket>,
|
||||
pub ws_queue: Vec<WsMsg>,
|
||||
pub host_url: String,
|
||||
pub ws_url: String,
|
||||
pub access_token: Option<Uuid>,
|
||||
pub about_tooltip_visible: bool,
|
||||
pub messages_tooltip_visible: bool,
|
||||
|
||||
// mapped
|
||||
pub comments_by_project_id: HashMap<ProjectId, Vec<Comment>>,
|
||||
@ -467,6 +469,7 @@ impl Model {
|
||||
pub fn new(host_url: String, ws_url: String) -> Self {
|
||||
Self {
|
||||
ws: None,
|
||||
ws_queue: vec![],
|
||||
access_token: None,
|
||||
user: None,
|
||||
issue_form: None,
|
||||
@ -483,6 +486,7 @@ impl Model {
|
||||
project: None,
|
||||
comments: vec![],
|
||||
about_tooltip_visible: false,
|
||||
messages_tooltip_visible: false,
|
||||
issue_statuses: vec![],
|
||||
messages: vec![Message {
|
||||
id: 0,
|
||||
|
@ -14,15 +14,14 @@ use crate::ws::send_ws_msg;
|
||||
use crate::{FieldId, Msg, PageChanged, ProfilePageChange, WebSocketChanged};
|
||||
|
||||
pub fn update(msg: Msg, model: &mut crate::model::Model, orders: &mut impl Orders<Msg>) {
|
||||
match msg {
|
||||
Msg::WebSocketChange(WebSocketChanged::WsMsg(WsMsg::AuthorizeLoaded(..)))
|
||||
| Msg::ChangePage(Page::Profile) => {
|
||||
send_ws_msg(WsMsg::ProjectRequest, model.ws.as_ref(), orders);
|
||||
let user = match model.user {
|
||||
Some(ref user) => user,
|
||||
_ => return,
|
||||
};
|
||||
|
||||
match msg {
|
||||
Msg::WebSocketChange(WebSocketChanged::WsMsg(WsMsg::AuthorizeLoaded(..)))
|
||||
| Msg::ChangePage(Page::Profile) => {
|
||||
send_ws_msg(WsMsg::ProjectRequest, model.ws.as_ref());
|
||||
model.page_content = PageContent::Profile(Box::new(ProfilePage::new(user)));
|
||||
}
|
||||
_ => (),
|
||||
@ -71,6 +70,7 @@ pub fn update(msg: Msg, model: &mut crate::model::Model, orders: &mut impl Order
|
||||
profile_page.name.value.clone(),
|
||||
),
|
||||
model.ws.as_ref(),
|
||||
orders,
|
||||
);
|
||||
}
|
||||
_ => (),
|
||||
|
@ -10,7 +10,7 @@ use crate::shared::styled_icon::{Icon, StyledIcon};
|
||||
use crate::shared::styled_input::StyledInput;
|
||||
use crate::shared::styled_select::StyledSelectChange;
|
||||
use crate::shared::{inner_layout, ToNode};
|
||||
use crate::ws::send_ws_msg;
|
||||
use crate::ws::{enqueue_ws_msg, send_ws_msg};
|
||||
use crate::{BoardPageChange, EditIssueModalSection, FieldId, Msg, PageChanged, WebSocketChanged};
|
||||
|
||||
pub fn update(msg: Msg, model: &mut crate::model::Model, orders: &mut impl Orders<Msg>) {
|
||||
@ -37,10 +37,16 @@ pub fn update(msg: Msg, model: &mut crate::model::Model, orders: &mut impl Order
|
||||
| Msg::ChangePage(Page::Project)
|
||||
| Msg::ChangePage(Page::AddIssue)
|
||||
| Msg::ChangePage(Page::EditIssue(..)) => {
|
||||
send_ws_msg(jirs_data::WsMsg::ProjectRequest, model.ws.as_ref());
|
||||
send_ws_msg(jirs_data::WsMsg::ProjectIssuesRequest, model.ws.as_ref());
|
||||
send_ws_msg(jirs_data::WsMsg::ProjectUsersRequest, model.ws.as_ref());
|
||||
send_ws_msg(jirs_data::WsMsg::IssueStatusesRequest, model.ws.as_ref());
|
||||
enqueue_ws_msg(
|
||||
vec![
|
||||
jirs_data::WsMsg::ProjectRequest,
|
||||
jirs_data::WsMsg::ProjectIssuesRequest,
|
||||
jirs_data::WsMsg::ProjectUsersRequest,
|
||||
jirs_data::WsMsg::IssueStatusesRequest,
|
||||
],
|
||||
model.ws.as_ref(),
|
||||
orders,
|
||||
);
|
||||
}
|
||||
Msg::WebSocketChange(WebSocketChanged::WsMsg(WsMsg::IssueUpdated(issue))) => {
|
||||
let mut old: Vec<Issue> = vec![];
|
||||
@ -108,7 +114,7 @@ pub fn update(msg: Msg, model: &mut crate::model::Model, orders: &mut impl Order
|
||||
crate::ws::issue::drag_started(issue_id, model)
|
||||
}
|
||||
Msg::PageChanged(PageChanged::Board(BoardPageChange::IssueDragStopped(_))) => {
|
||||
crate::ws::issue::sync(model);
|
||||
crate::ws::issue::sync(model, orders);
|
||||
}
|
||||
Msg::PageChanged(PageChanged::Board(BoardPageChange::ExchangePosition(
|
||||
issue_bellow_id,
|
||||
@ -117,7 +123,7 @@ pub fn update(msg: Msg, model: &mut crate::model::Model, orders: &mut impl Order
|
||||
crate::ws::issue::change_status(status, model)
|
||||
}
|
||||
Msg::PageChanged(PageChanged::Board(BoardPageChange::IssueDropZone(_status))) => {
|
||||
crate::ws::issue::sync(model)
|
||||
crate::ws::issue::sync(model, orders)
|
||||
}
|
||||
Msg::PageChanged(PageChanged::Board(BoardPageChange::DragLeave(_id))) => {
|
||||
project_page.issue_drag.clear_last();
|
||||
@ -126,6 +132,7 @@ pub fn update(msg: Msg, model: &mut crate::model::Model, orders: &mut impl Order
|
||||
send_ws_msg(
|
||||
jirs_data::WsMsg::IssueDeleteRequest(issue_id),
|
||||
model.ws.as_ref(),
|
||||
orders,
|
||||
);
|
||||
}
|
||||
_ => (),
|
||||
|
@ -1,3 +1,5 @@
|
||||
use std::collections::HashSet;
|
||||
|
||||
use seed::{prelude::*, *};
|
||||
use wasm_bindgen::__rt::std::collections::HashMap;
|
||||
|
||||
@ -18,7 +20,7 @@ use crate::shared::styled_input::StyledInput;
|
||||
use crate::shared::styled_select::{StyledSelect, StyledSelectChange};
|
||||
use crate::shared::styled_textarea::StyledTextarea;
|
||||
use crate::shared::{inner_layout, ToChild, ToNode};
|
||||
use crate::ws::send_ws_msg;
|
||||
use crate::ws::{enqueue_ws_msg, send_ws_msg};
|
||||
use crate::FieldChange::TabChanged;
|
||||
use crate::{
|
||||
model, FieldId, Msg, PageChanged, ProjectFieldId, ProjectPageChange, WebSocketChanged,
|
||||
@ -389,9 +391,15 @@ pub fn update(msg: Msg, model: &mut model::Model, orders: &mut impl Orders<Msg>)
|
||||
match msg {
|
||||
Msg::WebSocketChange(ref change) => match change {
|
||||
WebSocketChanged::WsMsg(WsMsg::AuthorizeLoaded(..)) => {
|
||||
send_ws_msg(WsMsg::ProjectRequest, model.ws.as_ref());
|
||||
send_ws_msg(WsMsg::IssueStatusesRequest, model.ws.as_ref());
|
||||
send_ws_msg(WsMsg::ProjectIssuesRequest, model.ws.as_ref());
|
||||
enqueue_ws_msg(
|
||||
vec![
|
||||
WsMsg::ProjectRequest,
|
||||
WsMsg::IssueStatusesRequest,
|
||||
WsMsg::ProjectIssuesRequest,
|
||||
],
|
||||
model.ws.as_ref(),
|
||||
orders,
|
||||
);
|
||||
}
|
||||
WebSocketChanged::WsMsg(WsMsg::ProjectLoaded(..)) => {
|
||||
build_page_content(model);
|
||||
@ -409,9 +417,15 @@ pub fn update(msg: Msg, model: &mut model::Model, orders: &mut impl Orders<Msg>)
|
||||
Msg::ChangePage(Page::ProjectSettings) => {
|
||||
build_page_content(model);
|
||||
if model.user.is_some() {
|
||||
send_ws_msg(WsMsg::ProjectRequest, model.ws.as_ref());
|
||||
send_ws_msg(WsMsg::IssueStatusesRequest, model.ws.as_ref());
|
||||
send_ws_msg(WsMsg::ProjectIssuesRequest, model.ws.as_ref());
|
||||
enqueue_ws_msg(
|
||||
vec![
|
||||
WsMsg::ProjectRequest,
|
||||
WsMsg::IssueStatusesRequest,
|
||||
WsMsg::ProjectIssuesRequest,
|
||||
],
|
||||
model.ws.as_ref(),
|
||||
orders,
|
||||
);
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
@ -465,6 +479,7 @@ pub fn update(msg: Msg, model: &mut model::Model, orders: &mut impl Orders<Msg>)
|
||||
time_tracking: Some(page.time_tracking.value.into()),
|
||||
}),
|
||||
model.ws.as_ref(),
|
||||
orders,
|
||||
);
|
||||
}
|
||||
Msg::PageChanged(PageChanged::ProjectSettings(ProjectPageChange::ColumnDragStarted(
|
||||
@ -475,7 +490,7 @@ pub fn update(msg: Msg, model: &mut model::Model, orders: &mut impl Orders<Msg>)
|
||||
Msg::PageChanged(PageChanged::ProjectSettings(ProjectPageChange::ColumnDragStopped(
|
||||
_issue_status_id,
|
||||
))) => {
|
||||
sync(model);
|
||||
sync(model, orders);
|
||||
}
|
||||
Msg::PageChanged(PageChanged::ProjectSettings(ProjectPageChange::ColumnDragLeave(
|
||||
_issue_status_id,
|
||||
@ -486,7 +501,7 @@ pub fn update(msg: Msg, model: &mut model::Model, orders: &mut impl Orders<Msg>)
|
||||
Msg::PageChanged(PageChanged::ProjectSettings(ProjectPageChange::ColumnDropZone(
|
||||
_issue_status_id,
|
||||
))) => {
|
||||
sync(model);
|
||||
sync(model, orders);
|
||||
}
|
||||
Msg::PageChanged(PageChanged::ProjectSettings(ProjectPageChange::EditIssueStatusName(
|
||||
id,
|
||||
@ -503,6 +518,7 @@ pub fn update(msg: Msg, model: &mut model::Model, orders: &mut impl Orders<Msg>)
|
||||
send_ws_msg(
|
||||
WsMsg::IssueStatusUpdate(id, name.to_string(), pos),
|
||||
model.ws.as_ref(),
|
||||
orders,
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -525,7 +541,7 @@ pub fn update(msg: Msg, model: &mut model::Model, orders: &mut impl Orders<Msg>)
|
||||
let name = page.name.value.clone();
|
||||
let position = model.issue_statuses.len();
|
||||
let ws_msg = WsMsg::IssueStatusCreate(name, position as i32);
|
||||
send_ws_msg(ws_msg, model.ws.as_ref());
|
||||
send_ws_msg(ws_msg, model.ws.as_ref(), orders);
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
@ -581,20 +597,25 @@ fn exchange_position(bellow_id: IssueStatusId, model: &mut Model) {
|
||||
page.column_drag.last_id = Some(bellow_id);
|
||||
}
|
||||
|
||||
fn sync(model: &mut Model) {
|
||||
let page = match &mut model.page_content {
|
||||
PageContent::ProjectSettings(page) => page,
|
||||
fn sync(model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
let dirty = match &mut model.page_content {
|
||||
PageContent::ProjectSettings(page) => {
|
||||
let mut old = HashSet::new();
|
||||
std::mem::swap(&mut old, &mut page.column_drag.dirty);
|
||||
old
|
||||
}
|
||||
_ => return error!("bad content type"),
|
||||
};
|
||||
for id in page.column_drag.dirty.iter() {
|
||||
for id in dirty {
|
||||
let IssueStatus { name, position, .. } =
|
||||
match model.issue_statuses.iter().find(|is| is.id == *id) {
|
||||
match model.issue_statuses.iter().find(|is| is.id == id) {
|
||||
Some(is) => is,
|
||||
_ => continue,
|
||||
};
|
||||
send_ws_msg(
|
||||
WsMsg::IssueStatusUpdate(*id, name.clone(), *position),
|
||||
WsMsg::IssueStatusUpdate(id, name.clone(), *position),
|
||||
model.ws.as_ref(),
|
||||
orders,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
use seed::{prelude::*, *};
|
||||
use std::str::FromStr;
|
||||
|
||||
use seed::{prelude::*, *};
|
||||
|
||||
use jirs_data::*;
|
||||
|
||||
use crate::model::Model;
|
||||
use crate::model::Page;
|
||||
use crate::Msg;
|
||||
|
||||
pub mod aside;
|
||||
@ -33,12 +35,14 @@ pub trait ToChild {
|
||||
fn to_child(&self) -> Self::Builder;
|
||||
}
|
||||
|
||||
pub fn go_to_board() {
|
||||
pub fn go_to_board(orders: &mut impl Orders<Msg>) {
|
||||
go_to("/board");
|
||||
orders.skip().send_msg(Msg::ChangePage(Page::Project));
|
||||
}
|
||||
|
||||
pub fn go_to_login() {
|
||||
pub fn go_to_login(orders: &mut impl Orders<Msg>) {
|
||||
go_to("/login");
|
||||
orders.skip().send_msg(Msg::ChangePage(Page::SignIn));
|
||||
}
|
||||
|
||||
pub fn go_to(url: &str) {
|
||||
|
@ -1,5 +1,7 @@
|
||||
use seed::{prelude::*, *};
|
||||
|
||||
use jirs_data::Message;
|
||||
|
||||
use crate::model::Model;
|
||||
use crate::shared::styled_avatar::StyledAvatar;
|
||||
use crate::shared::styled_button::StyledButton;
|
||||
@ -42,49 +44,102 @@ pub fn render(model: &Model) -> Vec<Node<Msg>> {
|
||||
let messages = if model.messages.is_empty() {
|
||||
empty![]
|
||||
} else {
|
||||
navbar_left_item("Messages", Icon::Message, None)
|
||||
navbar_left_item(
|
||||
"Messages",
|
||||
Icon::Message,
|
||||
None,
|
||||
Some(mouse_ev(Ev::Click, |ev| {
|
||||
ev.prevent_default();
|
||||
Msg::ToggleTooltip(styled_tooltip::Variant::Messages)
|
||||
})),
|
||||
)
|
||||
};
|
||||
|
||||
vec![
|
||||
about_tooltip_popup(model),
|
||||
messages_tooltip_popup(model),
|
||||
aside![
|
||||
id!["navbar-left"],
|
||||
a![
|
||||
attrs![At::Class => "logoLink", At::Href => "/"],
|
||||
div![attrs![At::Class => "styledLogo"], logo_svg]
|
||||
class!["logoLink"],
|
||||
attrs![At::Href => "/"],
|
||||
div![class!["styledLogo"], logo_svg]
|
||||
],
|
||||
navbar_left_item("Search issues", Icon::Search, None),
|
||||
navbar_left_item("Create Issue", Icon::Plus, Some("/add-issue")),
|
||||
navbar_left_item("Search issues", Icon::Search, None, None),
|
||||
navbar_left_item("Create Issue", Icon::Plus, Some("/add-issue"), None),
|
||||
div![
|
||||
class!["bottom"],
|
||||
navbar_left_item("Profile", user_icon, Some("/profile")),
|
||||
navbar_left_item("Profile", user_icon, Some("/profile"), None),
|
||||
messages,
|
||||
about_tooltip(model, navbar_left_item("About", Icon::Help, None)),
|
||||
about_tooltip(model, navbar_left_item("About", Icon::Help, None, None)),
|
||||
],
|
||||
],
|
||||
]
|
||||
}
|
||||
|
||||
fn navbar_left_item<I>(text: &str, icon: I, href: Option<&str>) -> Node<Msg>
|
||||
fn navbar_left_item<I>(
|
||||
text: &str,
|
||||
icon: I,
|
||||
href: Option<&str>,
|
||||
on_click: Option<EventHandler<Msg>>,
|
||||
) -> Node<Msg>
|
||||
where
|
||||
I: IntoNavItemIcon,
|
||||
{
|
||||
let styled_icon = icon.into_nav_item_icon();
|
||||
let href = href.unwrap_or_else(|| "#");
|
||||
|
||||
a![
|
||||
class!["item"],
|
||||
attrs![At::Href => href],
|
||||
styled_icon,
|
||||
span![class!["itemText"], text]
|
||||
span![class!["itemText"], text],
|
||||
on_click,
|
||||
]
|
||||
}
|
||||
|
||||
pub fn about_tooltip(_model: &Model, children: Node<Msg>) -> Node<Msg> {
|
||||
let on_click: EventHandler<Msg> = ev(Ev::Click, move |_| {
|
||||
Some(Msg::ToggleTooltip(styled_tooltip::Variant::About))
|
||||
});
|
||||
div![class!["aboutTooltip"], on_click, children]
|
||||
}
|
||||
|
||||
fn messages_tooltip_popup(model: &Model) -> Node<Msg> {
|
||||
let on_click: EventHandler<Msg> = ev(Ev::Click, move |_| {
|
||||
Some(Msg::ToggleTooltip(styled_tooltip::Variant::Messages))
|
||||
});
|
||||
let messages: Vec<Node<Msg>> = model
|
||||
.messages
|
||||
.iter()
|
||||
.map(|message| {
|
||||
let Message {
|
||||
id: _,
|
||||
receiver_id: _,
|
||||
sender_id: _,
|
||||
summary,
|
||||
description,
|
||||
message_type,
|
||||
hyper_link,
|
||||
created_at: _,
|
||||
updated_at: _,
|
||||
} = message;
|
||||
div![
|
||||
attrs![At::Class => "aboutTooltip"],
|
||||
ev(Ev::Click, |_| Msg::ToggleAboutTooltip),
|
||||
children
|
||||
class!["message"],
|
||||
class![message_type.as_str()],
|
||||
div![class!["summary"], summary],
|
||||
div![class!["description"], description],
|
||||
div![class!["hyperlink"], hyper_link],
|
||||
]
|
||||
})
|
||||
.collect();
|
||||
let body = div![on_click, class!["messagesList"], messages];
|
||||
styled_tooltip::StyledTooltip::build()
|
||||
.visible(model.messages_tooltip_visible)
|
||||
.messages_tooltip()
|
||||
.add_child(body)
|
||||
.build()
|
||||
.into_node()
|
||||
}
|
||||
|
||||
fn about_tooltip_popup(model: &Model) -> Node<Msg> {
|
||||
@ -100,23 +155,23 @@ fn about_tooltip_popup(model: &Model) -> Node<Msg> {
|
||||
.build()
|
||||
.into_node();
|
||||
|
||||
styled_tooltip::StyledTooltip {
|
||||
visible: model.about_tooltip_visible,
|
||||
class_name: "aboutTooltipPopup".to_string(),
|
||||
children: div![
|
||||
ev(Ev::Click, |_| Msg::ToggleAboutTooltip),
|
||||
attrs![At::Class => "feedbackDropdown"],
|
||||
let on_click = mouse_ev(Ev::Click, |_| {
|
||||
Msg::ToggleTooltip(styled_tooltip::Variant::About)
|
||||
});
|
||||
let body = div![
|
||||
on_click,
|
||||
class!["feedbackDropdown"],
|
||||
div![
|
||||
attrs![At::Class => "feedbackImageCont"],
|
||||
class!["feedbackImageCont"],
|
||||
img![attrs![At::Src => "/feedback.png"]],
|
||||
class!["feedbackImage"],
|
||||
],
|
||||
div![
|
||||
attrs![At::Class => "feedbackParagraph"],
|
||||
class!["feedbackParagraph"],
|
||||
"This simplified Jira clone is built with Seed.rs on the front-end and Actix-Web on the back-end."
|
||||
],
|
||||
div![
|
||||
attrs![At::Class => "feedbackParagraph"],
|
||||
class!["feedbackParagraph"],
|
||||
"Read more on my website or reach out via ",
|
||||
a![
|
||||
attrs![At::Href => "mailto:adrian.wozniak@ita-prog.pl"],
|
||||
@ -140,6 +195,13 @@ fn about_tooltip_popup(model: &Model) -> Node<Msg> {
|
||||
],
|
||||
github_repo
|
||||
]
|
||||
],
|
||||
}.into_node()
|
||||
];
|
||||
|
||||
styled_tooltip::StyledTooltip::build()
|
||||
.visible(model.about_tooltip_visible)
|
||||
.about_tooltip()
|
||||
.add_class("aboutTooltipPopup")
|
||||
.add_child(body)
|
||||
.build()
|
||||
.into_node()
|
||||
}
|
||||
|
@ -3,10 +3,32 @@ use seed::{prelude::*, *};
|
||||
use crate::shared::ToNode;
|
||||
use crate::Msg;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum Variant {
|
||||
About,
|
||||
Messages,
|
||||
}
|
||||
|
||||
impl Default for Variant {
|
||||
fn default() -> Self {
|
||||
Variant::Messages
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Variant {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Variant::About => f.write_str("about"),
|
||||
Variant::Messages => f.write_str("messages"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct StyledTooltip {
|
||||
pub visible: bool,
|
||||
pub class_name: String,
|
||||
pub children: Node<Msg>,
|
||||
visible: bool,
|
||||
class_name: String,
|
||||
children: Vec<Node<Msg>>,
|
||||
variant: Variant,
|
||||
}
|
||||
|
||||
impl ToNode for StyledTooltip {
|
||||
@ -15,15 +37,69 @@ impl ToNode for StyledTooltip {
|
||||
}
|
||||
}
|
||||
|
||||
impl StyledTooltip {
|
||||
pub fn build() -> StyledTooltipBuilder {
|
||||
StyledTooltipBuilder::default()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct StyledTooltipBuilder {
|
||||
visible: bool,
|
||||
class_list: Vec<String>,
|
||||
children: Vec<Node<Msg>>,
|
||||
variant: Variant,
|
||||
}
|
||||
|
||||
impl StyledTooltipBuilder {
|
||||
pub fn visible(mut self, b: bool) -> Self {
|
||||
self.visible = b;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn add_class<S>(mut self, name: S) -> Self
|
||||
where
|
||||
S: Into<String>,
|
||||
{
|
||||
self.class_list.push(name.into());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn add_child(mut self, child: Node<Msg>) -> Self {
|
||||
self.children.push(child);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn about_tooltip(mut self) -> Self {
|
||||
self.variant = Variant::About;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn messages_tooltip(mut self) -> Self {
|
||||
self.variant = Variant::Messages;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> StyledTooltip {
|
||||
StyledTooltip {
|
||||
visible: self.visible,
|
||||
class_name: self.class_list.join(" "),
|
||||
children: self.children,
|
||||
variant: self.variant,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn render(values: StyledTooltip) -> Node<Msg> {
|
||||
let StyledTooltip {
|
||||
visible,
|
||||
class_name,
|
||||
children,
|
||||
variant,
|
||||
} = values;
|
||||
if visible {
|
||||
div![
|
||||
attrs![At::Class => format!("styledTooltip {}", class_name)],
|
||||
attrs![At::Class => format!("styledTooltip {} {}", class_name, variant)],
|
||||
children
|
||||
]
|
||||
} else {
|
||||
|
@ -52,6 +52,7 @@ pub fn update(msg: Msg, model: &mut model::Model, orders: &mut impl Orders<Msg>)
|
||||
send_ws_msg(
|
||||
WsMsg::AuthenticateRequest(page.email.clone(), page.username.clone()),
|
||||
model.ws.as_ref(),
|
||||
orders,
|
||||
);
|
||||
}
|
||||
Msg::BindClientRequest => {
|
||||
@ -62,7 +63,7 @@ pub fn update(msg: Msg, model: &mut model::Model, orders: &mut impl Orders<Msg>)
|
||||
return;
|
||||
}
|
||||
};
|
||||
send_ws_msg(WsMsg::BindTokenCheck(bind_token), model.ws.as_ref());
|
||||
send_ws_msg(WsMsg::BindTokenCheck(bind_token), model.ws.as_ref(), orders);
|
||||
}
|
||||
Msg::WebSocketChange(change) => match change {
|
||||
WebSocketChanged::WsMsg(WsMsg::AuthenticateSuccess) => {
|
||||
|
@ -14,7 +14,7 @@ use crate::validations::is_email;
|
||||
use crate::ws::send_ws_msg;
|
||||
use crate::{model, FieldId, Msg, WebSocketChanged};
|
||||
|
||||
pub fn update(msg: Msg, model: &mut model::Model, _orders: &mut impl Orders<Msg>) {
|
||||
pub fn update(msg: Msg, model: &mut model::Model, orders: &mut impl Orders<Msg>) {
|
||||
if model.page != Page::SignUp {
|
||||
return;
|
||||
}
|
||||
@ -45,6 +45,7 @@ pub fn update(msg: Msg, model: &mut model::Model, _orders: &mut impl Orders<Msg>
|
||||
send_ws_msg(
|
||||
WsMsg::SignUpRequest(page.email.clone(), page.username.clone()),
|
||||
model.ws.as_ref(),
|
||||
orders,
|
||||
);
|
||||
}
|
||||
Msg::WebSocketChange(change) => match change {
|
||||
|
@ -10,7 +10,7 @@ use crate::shared::styled_input::StyledInput;
|
||||
use crate::shared::styled_select::*;
|
||||
use crate::shared::{inner_layout, ToChild, ToNode};
|
||||
use crate::validations::is_email;
|
||||
use crate::ws::send_ws_msg;
|
||||
use crate::ws::{enqueue_ws_msg, send_ws_msg};
|
||||
use crate::{FieldId, Msg, PageChanged, UsersPageChange, WebSocketChanged};
|
||||
|
||||
pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
@ -28,13 +28,19 @@ pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
|
||||
match msg {
|
||||
Msg::ChangePage(Page::Users) if model.user.is_some() => {
|
||||
send_ws_msg(WsMsg::InvitationListRequest, model.ws.as_ref());
|
||||
send_ws_msg(WsMsg::InvitedUsersRequest, model.ws.as_ref());
|
||||
enqueue_ws_msg(
|
||||
vec![WsMsg::InvitationListRequest, WsMsg::InvitedUsersRequest],
|
||||
model.ws.as_ref(),
|
||||
orders,
|
||||
);
|
||||
}
|
||||
Msg::WebSocketChange(change) => match change {
|
||||
WebSocketChanged::WsMsg(WsMsg::AuthorizeLoaded(Ok(_))) if model.user.is_some() => {
|
||||
send_ws_msg(WsMsg::InvitationListRequest, model.ws.as_ref());
|
||||
send_ws_msg(WsMsg::InvitedUsersRequest, model.ws.as_ref());
|
||||
enqueue_ws_msg(
|
||||
vec![WsMsg::InvitationListRequest, WsMsg::InvitedUsersRequest],
|
||||
model.ws.as_ref(),
|
||||
orders,
|
||||
);
|
||||
}
|
||||
WebSocketChanged::WsMsg(WsMsg::InvitedUsersLoaded(users)) => {
|
||||
page.invited_users = users;
|
||||
@ -51,7 +57,7 @@ pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
}
|
||||
page.invitations.push(invitation);
|
||||
}
|
||||
send_ws_msg(WsMsg::InvitationListRequest, model.ws.as_ref());
|
||||
send_ws_msg(WsMsg::InvitationListRequest, model.ws.as_ref(), orders);
|
||||
}
|
||||
WebSocketChanged::WsMsg(WsMsg::InvitedUserRemoveSuccess(email)) => {
|
||||
let mut old = vec![];
|
||||
@ -63,7 +69,7 @@ pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
}
|
||||
}
|
||||
WebSocketChanged::WsMsg(WsMsg::InvitationSendSuccess) => {
|
||||
send_ws_msg(WsMsg::InvitationListRequest, model.ws.as_ref());
|
||||
send_ws_msg(WsMsg::InvitationListRequest, model.ws.as_ref(), orders);
|
||||
page.form_state = InvitationFormState::Succeed;
|
||||
}
|
||||
WebSocketChanged::WsMsg(WsMsg::InvitationSendFailure) => {
|
||||
@ -102,16 +108,22 @@ pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
email: page.email.clone(),
|
||||
},
|
||||
model.ws.as_ref(),
|
||||
orders,
|
||||
);
|
||||
}
|
||||
Msg::InviteRevokeRequest(invitation_id) => {
|
||||
send_ws_msg(
|
||||
WsMsg::InvitationRevokeRequest(invitation_id),
|
||||
model.ws.as_ref(),
|
||||
orders,
|
||||
);
|
||||
}
|
||||
Msg::InvitedUserRemove(email) => {
|
||||
send_ws_msg(WsMsg::InvitedUserRemoveRequest(email), model.ws.as_ref());
|
||||
send_ws_msg(
|
||||
WsMsg::InvitedUserRemoveRequest(email),
|
||||
model.ws.as_ref(),
|
||||
orders,
|
||||
);
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
use seed::prelude::Orders;
|
||||
use seed::*;
|
||||
|
||||
use jirs_data::*;
|
||||
|
||||
use crate::model::{Model, PageContent};
|
||||
use crate::ws::send_ws_msg;
|
||||
use crate::Msg;
|
||||
|
||||
pub fn drag_started(issue_id: IssueId, model: &mut Model) {
|
||||
let project_page = match &mut model.page_content {
|
||||
@ -76,7 +78,7 @@ pub fn exchange_position(issue_bellow_id: IssueId, model: &mut Model) {
|
||||
project_page.issue_drag.last_id = Some(issue_bellow_id);
|
||||
}
|
||||
|
||||
pub fn sync(model: &mut Model) {
|
||||
pub fn sync(model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
// log!("------------------------------------------------------------------");
|
||||
// log!("| SYNC |");
|
||||
// log!("------------------------------------------------------------------");
|
||||
@ -97,6 +99,7 @@ pub fn sync(model: &mut Model) {
|
||||
PayloadVariant::I32(issue.issue_status_id),
|
||||
),
|
||||
model.ws.as_ref(),
|
||||
orders,
|
||||
);
|
||||
send_ws_msg(
|
||||
WsMsg::IssueUpdateRequest(
|
||||
@ -105,6 +108,7 @@ pub fn sync(model: &mut Model) {
|
||||
PayloadVariant::I32(issue.list_position),
|
||||
),
|
||||
model.ws.as_ref(),
|
||||
orders,
|
||||
);
|
||||
}
|
||||
project_page.issue_drag.clear();
|
||||
|
@ -3,15 +3,41 @@ use seed::prelude::*;
|
||||
use jirs_data::WsMsg;
|
||||
|
||||
use crate::model::*;
|
||||
use crate::shared::write_auth_token;
|
||||
use crate::shared::{go_to_board, write_auth_token};
|
||||
use crate::{Msg, WebSocketChanged};
|
||||
|
||||
pub mod issue;
|
||||
|
||||
pub fn send_ws_msg(msg: WsMsg, ws: Option<&WebSocket>) {
|
||||
pub fn flush_queue(model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
use seed::browser::web_socket::State;
|
||||
match model.ws.as_ref() {
|
||||
Some(ws) if ws.state() != State::Open => return,
|
||||
None => return,
|
||||
_ => (),
|
||||
};
|
||||
let mut old = vec![];
|
||||
std::mem::swap(&mut model.ws_queue, &mut old);
|
||||
for msg in old {
|
||||
send_ws_msg(msg, model.ws.as_ref(), orders);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn enqueue_ws_msg(v: Vec<WsMsg>, ws: Option<&WebSocket>, orders: &mut impl Orders<Msg>) {
|
||||
for msg in v {
|
||||
send_ws_msg(msg, ws.clone(), orders);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn send_ws_msg(msg: WsMsg, ws: Option<&WebSocket>, orders: &mut impl Orders<Msg>) {
|
||||
use seed::browser::web_socket::State;
|
||||
let ws = match ws {
|
||||
Some(ws) => ws,
|
||||
_ => return,
|
||||
Some(ws) if ws.state() == State::Open => ws,
|
||||
_ => {
|
||||
orders
|
||||
.skip()
|
||||
.send_msg(Msg::WebSocketChange(WebSocketChanged::Bounced(msg)));
|
||||
return;
|
||||
}
|
||||
};
|
||||
let binary = bincode::serialize(&msg).unwrap();
|
||||
ws.send_bytes(binary.as_slice())
|
||||
@ -19,6 +45,16 @@ pub fn send_ws_msg(msg: WsMsg, ws: Option<&WebSocket>) {
|
||||
}
|
||||
|
||||
pub fn open_socket(model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
use seed::browser::web_socket::State;
|
||||
use seed::{prelude::*, *};
|
||||
log!(model.ws.as_ref().map(|ws| ws.state()));
|
||||
|
||||
match model.ws.as_ref() {
|
||||
Some(ws) if ws.state() != State::Closed => {
|
||||
return;
|
||||
}
|
||||
_ => (),
|
||||
};
|
||||
if model.host_url.is_empty() {
|
||||
return;
|
||||
}
|
||||
@ -43,6 +79,7 @@ pub fn update(msg: &WsMsg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
// auth
|
||||
WsMsg::AuthorizeLoaded(Ok(user)) => {
|
||||
model.user = Some(user.clone());
|
||||
go_to_board(orders);
|
||||
}
|
||||
WsMsg::AuthorizeExpired => {
|
||||
if let Ok(msg) = write_auth_token(None) {
|
||||
|
@ -736,4 +736,8 @@ pub enum WsMsg {
|
||||
|
||||
// messages
|
||||
Message(Message),
|
||||
MessagesRequest,
|
||||
MessagesResponse(Vec<Message>),
|
||||
MessageMarkSeen(MessageId),
|
||||
MessageMarkedSeen(MessageId),
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user