Prevent spam all issues
This commit is contained in:
parent
f0c275120a
commit
f22944664e
79
Cargo.lock
generated
79
Cargo.lock
generated
@ -858,7 +858,7 @@ dependencies = [
|
||||
"diesel",
|
||||
"dotenv",
|
||||
"futures",
|
||||
"ipnetwork",
|
||||
"ipnetwork 0.16.0",
|
||||
"jirs-config",
|
||||
"jirs-data",
|
||||
"libc",
|
||||
@ -925,7 +925,7 @@ dependencies = [
|
||||
"byteorder",
|
||||
"chrono",
|
||||
"diesel_derives",
|
||||
"ipnetwork",
|
||||
"ipnetwork 0.18.0",
|
||||
"libc",
|
||||
"num-bigint",
|
||||
"num-integer",
|
||||
@ -1345,6 +1345,15 @@ dependencies = [
|
||||
"version_check 0.9.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getopts"
|
||||
version = "0.2.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5"
|
||||
dependencies = [
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.1.16"
|
||||
@ -1352,8 +1361,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"js-sys",
|
||||
"libc",
|
||||
"wasi 0.9.0+wasi-snapshot-preview1",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1662,6 +1673,15 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ipnetwork"
|
||||
version = "0.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4088d739b183546b239688ddbc79891831df421773df95e236daf7867866d355"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.9.0"
|
||||
@ -2412,6 +2432,18 @@ dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pulldown-cmark"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffade02495f22453cd593159ea2f59827aae7f53fa8323f756799b670881dcf8"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"getopts",
|
||||
"memchr",
|
||||
"unicase",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quick-error"
|
||||
version = "1.2.3"
|
||||
@ -2465,7 +2497,7 @@ dependencies = [
|
||||
"rand_isaac",
|
||||
"rand_jitter",
|
||||
"rand_os",
|
||||
"rand_pcg",
|
||||
"rand_pcg 0.1.2",
|
||||
"rand_xorshift",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
@ -2481,6 +2513,7 @@ dependencies = [
|
||||
"rand_chacha 0.2.2",
|
||||
"rand_core 0.5.1",
|
||||
"rand_hc 0.2.0",
|
||||
"rand_pcg 0.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2629,6 +2662,15 @@ dependencies = [
|
||||
"rand_core 0.4.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_pcg"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429"
|
||||
dependencies = [
|
||||
"rand_core 0.5.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_xorshift"
|
||||
version = "0.1.1"
|
||||
@ -2904,21 +2946,22 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "seed"
|
||||
version = "0.8.0"
|
||||
source = "git+https://github.com/seed-rs/seed.git#340d501e51a3988829303d7f6e35cf486768bdcf"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b599be9cc57456f4b7fc99b8abfb154d4819f7b6c147e80be5580663dad4536"
|
||||
dependencies = [
|
||||
"console_error_panic_hook",
|
||||
"cookie",
|
||||
"dbg",
|
||||
"enclose",
|
||||
"futures",
|
||||
"getrandom 0.2.3",
|
||||
"gloo-file",
|
||||
"gloo-timers",
|
||||
"indexmap",
|
||||
"js-sys",
|
||||
"rand 0.8.4",
|
||||
"pulldown-cmark",
|
||||
"rand 0.7.3",
|
||||
"serde",
|
||||
"serde-wasm-bindgen",
|
||||
"serde_json",
|
||||
"uuid 0.8.2",
|
||||
"version_check 0.9.3",
|
||||
"wasm-bindgen",
|
||||
@ -2974,18 +3017,6 @@ dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde-wasm-bindgen"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "618365e8e586c22123d692b72a7d791d5ee697817b65a218cdf12a98870af0f7"
|
||||
dependencies = [
|
||||
"fnv",
|
||||
"js-sys",
|
||||
"serde",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.130"
|
||||
@ -3289,18 +3320,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.29"
|
||||
version = "1.0.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "602eca064b2d83369e2b2f34b09c70b605402801927c65c11071ac911d299b88"
|
||||
checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.29"
|
||||
version = "1.0.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bad553cc2c78e8de258400763a647e80e6d1b31ee237275d756f6836d204494c"
|
||||
checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -3800,6 +3831,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
|
@ -24,7 +24,10 @@ impl AsyncHandler<WsMsgIssue> for WebSocketActor {
|
||||
}
|
||||
WsMsgIssue::IssueCreate(payload) => self.exec(payload).await,
|
||||
WsMsgIssue::IssueDelete(id) => self.exec(DeleteIssue { id }).await,
|
||||
WsMsgIssue::IssueSyncListPosition(sync) => self.exec(SyncIssueListPosition(sync)).await,
|
||||
WsMsgIssue::IssueSyncListPosition(sync) => {
|
||||
self.exec(SyncIssueListPosition(sync)).await?;
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
WsMsgIssue::IssueUpdated(_) => Ok(None),
|
||||
WsMsgIssue::IssueDeleted(_, _) => Ok(None),
|
||||
|
@ -20,7 +20,7 @@ default = []
|
||||
[dependencies]
|
||||
jirs-data = { path = "../shared/jirs-data", features = ["frontend"] }
|
||||
|
||||
seed = { git = "https://github.com/seed-rs/seed.git" }
|
||||
seed = { version = "0.8.0" }
|
||||
|
||||
serde = { version = "*" }
|
||||
serde_json = { version = "*" }
|
||||
|
@ -1,5 +1,4 @@
|
||||
use seed::prelude::*;
|
||||
use seed::*;
|
||||
|
||||
use crate::Msg;
|
||||
|
||||
@ -7,117 +6,5 @@ static LOGO: &str = include_str!("../../static/logo2.svg");
|
||||
|
||||
#[inline(always)]
|
||||
pub fn render() -> Vec<Node<Msg>> {
|
||||
Node::from_html(Some(&Namespace::Svg), LOGO)
|
||||
// svg![
|
||||
// attrs![
|
||||
// "xmlns:xlink" => "http://www.w3.org/1999/xlink",
|
||||
// At::Xmlns => "http://www.w3.org/2000/svg",
|
||||
// At::ViewBox => "0 0 640 640",
|
||||
// At::Width => "28",
|
||||
// At::Height => "28"
|
||||
// ],
|
||||
// defs![
|
||||
// path![attrs![
|
||||
// At::D => "M500 300c0 110.38-89.62 200-200
|
||||
// 200s-200-89.62-200-200c0-110.39 89.62-200 200-200s200 89.61 200 200Z"
|
||||
// At::Id => "a"
|
||||
// ]],
|
||||
// path![attrs![
|
||||
// At::D => "M520 338.18c0 110.38-89.62 200-200
|
||||
// 200s-200-89.62-200-200 89.62-200 200-200 200 89.62 200 200Z",
|
||||
// At::Id => "b"
|
||||
// ]],
|
||||
// path![attrs![
|
||||
// At::D => "M543.03 374.84c0 110.39-89.62 200-200
|
||||
// 200s-200-89.61-200-200c0-110.38 89.62-200 200-200s200 89.62 200 200Z"\
|
||||
// At::Id => "c"
|
||||
// ]],
|
||||
// mask![
|
||||
// attrs![
|
||||
// At::Id => "e",
|
||||
// At::X => "78",
|
||||
// At::Y => "78",
|
||||
// At::Width => "600",
|
||||
// At::Height => "600",
|
||||
// At::MaskUnits => "userSpaceOnUse"
|
||||
// ],
|
||||
// path![attrs![
|
||||
// At::Fill => "#fff",
|
||||
// At::D => "M78 78h444v444H78z"
|
||||
// ]]
|
||||
// seed::r#use![attrs![
|
||||
// "xlink:href" => "#a",
|
||||
// At::Opacity => ".46"
|
||||
// ]]
|
||||
// ],
|
||||
// mask![
|
||||
// attrs![
|
||||
// At::Id => "f",
|
||||
// At::X => "98",
|
||||
// At::Y => "116.18",
|
||||
// At::Width => "444",
|
||||
// At::Height => "444",
|
||||
// At::MaskUnits => "userSpaceOnUse"
|
||||
// ],
|
||||
// path![attrs![
|
||||
// At::Fill => "#fff",
|
||||
// At::D => "M98 116.18h444v444H98z"
|
||||
// ]],
|
||||
// r#use![attrs![
|
||||
// "xlink:href" => "#b",
|
||||
// At::Opacity => ".46"
|
||||
// ]],
|
||||
// ],
|
||||
// mask![
|
||||
// attrs![
|
||||
// At::Id => "g",
|
||||
// At::X => "121.03",
|
||||
// At::Y => "152.84",
|
||||
// At::Width => "444",
|
||||
// At::Height => "444",
|
||||
// At::MaskUnits => "userSpaceOnUse"
|
||||
// ],
|
||||
// path![attrs![
|
||||
// At::Fill => "#fff",
|
||||
// At::D => "M121.03 152.84h444v444h-444z"
|
||||
// ]],
|
||||
// r#use![attrs![
|
||||
// "xlink:href" => "#c",
|
||||
// At::Opacity => ".46"
|
||||
// ]],
|
||||
// ],
|
||||
// filter![
|
||||
// attrs![At::Id => "d"],
|
||||
// feFlood![],
|
||||
// feComposite![attrs![
|
||||
// "in2" => "SourceAlpha",
|
||||
// "operator" => "in"
|
||||
// ]],
|
||||
// feGaussianBlur![attrs!["stdDeviation"=>"1"]],
|
||||
// feOffset![attrs![At::Dx=>"14", At::Dy=>"10",
|
||||
// At::Result=>"afterOffset"]],
|
||||
// feFlood![attrs!["flood-color"=>"#0d0e44", "flood-opacity"=>".5"]],
|
||||
// feComposite![attrs!["in2"=>"afterOffset", "operator"="in"]],
|
||||
// feMorphology![attrs!["operator"=>"dilate", "radius"=>"1"]],
|
||||
// feComposite![attrs!["in2"=>"SourceAlpha",
|
||||
// "operator"=>"out"]], ]
|
||||
// ],
|
||||
// path![attrs![
|
||||
// At::D=>"M500 300c0 110.38-89.62 200-200
|
||||
// 200s-200-89.62-200-200c0-110.39 89.62-200 200-200s200 89.61 200 200Z",
|
||||
// At::Filter=>"url(#d)"
|
||||
// ]],
|
||||
// r#use![attrs!["xlink:href"=>"#a", "opacity"=>".46"
|
||||
// "fill"=>"#fefefe"]], g![attrs!["mask"=>"url(#e)"]],
|
||||
// r#use![attrs![[xlink:href="#a" opacity=".46" fill-opacity="0"
|
||||
// stroke="#06697d" stroke-width="44"/></g><path d="M520 338.18c0
|
||||
// 110.38-89.62 200-200 200s-200-89.62-200-200 89.62-200 200-200 200 89.62
|
||||
// 200 200Z" filter="url(#d)"/><use xlink:href="#b" opacity=".46"
|
||||
// fill="#fefefe"/><g mask="url(#f)"><use xlink:href="#b" opacity=".46"
|
||||
// fill-opacity="0" stroke="#06697d" stroke-width="44"/></g><path d="M543.03
|
||||
// 374.84c0 110.39-89.62 200-200 200s-200-89.61-200-200c0-110.38 89.62-200
|
||||
// 200-200s200 89.62 200 200Z" filter="url(#d)"/><use xlink:href="#c"
|
||||
// opacity=".46" fill="#fefefe"/><g mask="url(#g)"><use xlink:href="#c"
|
||||
// opacity=".46" fill-opacity="0" stroke="#06697d"
|
||||
// stroke-width="44"/></g></svg
|
||||
Node::from_html(LOGO)
|
||||
}
|
||||
|
@ -156,7 +156,6 @@ fn update(msg: Msg, model: &mut model::Model, orders: &mut impl Orders<Msg>) {
|
||||
if model.ws.is_none() {
|
||||
open_socket(model, orders);
|
||||
}
|
||||
let mut msg = msg;
|
||||
|
||||
let msg = match msg {
|
||||
Msg::WebSocketChange(change) => match change {
|
||||
|
@ -134,10 +134,12 @@ fn build_page_content(model: &mut Model) {
|
||||
}
|
||||
|
||||
async fn update_avatar(data: FormData, host_url: String) -> Option<Msg> {
|
||||
use seed::prelude::JsValue;
|
||||
|
||||
let path = format!("{}/avatar/", host_url);
|
||||
let result = Request::new(path)
|
||||
.method(Method::Post)
|
||||
.body(&data)
|
||||
.body(JsValue::from(data))
|
||||
.fetch()
|
||||
.await;
|
||||
let response = match result {
|
||||
|
74
web/src/pages/project_page/events.rs
Normal file
74
web/src/pages/project_page/events.rs
Normal file
@ -0,0 +1,74 @@
|
||||
use seed::prelude::*;
|
||||
|
||||
use crate::model::Page;
|
||||
use crate::{BoardPageChange, Msg, PageChanged};
|
||||
|
||||
pub type EvHandler = seed::EventHandler<Msg>;
|
||||
|
||||
pub fn on_drag_over_move_issue(status_id: i32) -> EvHandler {
|
||||
drag_ev(Ev::DragOver, move |ev| {
|
||||
ev.prevent_default();
|
||||
ev.stop_propagation();
|
||||
Some(Msg::PageChanged(PageChanged::Board(
|
||||
BoardPageChange::IssueDragOverStatus(status_id),
|
||||
)))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn on_drop_issue_drop_zone(status_id: i32) -> EvHandler {
|
||||
drag_ev(Ev::Drop, move |ev| {
|
||||
ev.prevent_default();
|
||||
ev.stop_propagation();
|
||||
Some(Msg::PageChanged(PageChanged::Board(
|
||||
BoardPageChange::IssueDropZone(status_id),
|
||||
)))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn on_drag_started_drag_issue(issue_id: i32) -> EvHandler {
|
||||
drag_ev(Ev::DragStart, move |ev| {
|
||||
ev.stop_propagation();
|
||||
Some(Msg::PageChanged(PageChanged::Board(
|
||||
BoardPageChange::IssueDragStarted(issue_id),
|
||||
)))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn on_drag_stop_issue_drag_stop(issue_id: i32) -> EvHandler {
|
||||
drag_ev(Ev::DragEnd, move |ev| {
|
||||
ev.stop_propagation();
|
||||
Some(Msg::PageChanged(PageChanged::Board(
|
||||
BoardPageChange::IssueDragStopped(issue_id),
|
||||
)))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn on_drag_enter_change_position(issue_id: i32) -> EvHandler {
|
||||
drag_ev(Ev::DragEnter, move |ev| {
|
||||
ev.prevent_default();
|
||||
ev.stop_propagation();
|
||||
Some(Msg::PageChanged(PageChanged::Board(
|
||||
BoardPageChange::ChangePosition(issue_id),
|
||||
)))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn on_drag_leave_issue_drag_leave(issue_id: i32) -> EvHandler {
|
||||
drag_ev(Ev::DragLeave, move |_| {
|
||||
Some(Msg::PageChanged(PageChanged::Board(
|
||||
BoardPageChange::DragLeave(issue_id),
|
||||
)))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn on_click_edit_issue(issue_id: i32) -> EvHandler {
|
||||
ev(Ev::Click, move |ev| {
|
||||
ev.prevent_default();
|
||||
ev.stop_propagation();
|
||||
seed::Url::new()
|
||||
.add_path_part("issues")
|
||||
.add_path_part(format!("{}", issue_id))
|
||||
.go_and_push();
|
||||
Msg::ChangePage(Page::EditIssue(issue_id))
|
||||
})
|
||||
}
|
@ -2,6 +2,7 @@ pub use model::*;
|
||||
pub use update::*;
|
||||
pub use view::*;
|
||||
|
||||
pub mod events;
|
||||
pub mod model;
|
||||
pub mod update;
|
||||
pub mod view;
|
||||
|
@ -6,7 +6,7 @@ use crate::components::styled_avatar::*;
|
||||
use crate::components::styled_button::{ButtonVariant, StyledButton};
|
||||
use crate::components::styled_icon::*;
|
||||
use crate::model::PageContent;
|
||||
use crate::{match_page, BoardPageChange, Model, Msg, Page, PageChanged};
|
||||
use crate::{match_page, Model, Msg, Page};
|
||||
|
||||
#[inline(always)]
|
||||
pub fn project_board_lists(model: &Model) -> Node<Msg> {
|
||||
@ -105,27 +105,8 @@ fn project_issue_list(
|
||||
.iter()
|
||||
.map(|issue| ProjectIssue { model, issue }.render())
|
||||
.collect();
|
||||
let drop_handler = {
|
||||
let send_status = status_id;
|
||||
drag_ev(Ev::Drop, move |ev| {
|
||||
ev.prevent_default();
|
||||
ev.stop_propagation();
|
||||
Some(Msg::PageChanged(PageChanged::Board(
|
||||
BoardPageChange::IssueDropZone(send_status),
|
||||
)))
|
||||
})
|
||||
};
|
||||
|
||||
let drag_over_handler = {
|
||||
let send_status = status_id;
|
||||
drag_ev(Ev::DragOver, move |ev| {
|
||||
ev.prevent_default();
|
||||
ev.stop_propagation();
|
||||
Some(Msg::PageChanged(PageChanged::Board(
|
||||
BoardPageChange::IssueDragOverStatus(send_status),
|
||||
)))
|
||||
})
|
||||
};
|
||||
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);
|
||||
|
||||
div![
|
||||
C!["list"],
|
||||
@ -185,40 +166,13 @@ impl<'l> ProjectIssue<'l> {
|
||||
.render();
|
||||
|
||||
let issue_id = self.issue.id;
|
||||
let drag_started = drag_ev(Ev::DragStart, move |ev| {
|
||||
ev.stop_propagation();
|
||||
Some(Msg::PageChanged(PageChanged::Board(
|
||||
BoardPageChange::IssueDragStarted(issue_id),
|
||||
)))
|
||||
});
|
||||
let drag_stopped = drag_ev(Ev::DragEnd, move |ev| {
|
||||
ev.stop_propagation();
|
||||
Some(Msg::PageChanged(PageChanged::Board(
|
||||
BoardPageChange::IssueDragStopped(issue_id),
|
||||
)))
|
||||
});
|
||||
let drag_over_handler = drag_ev(Ev::DragEnter, move |ev| {
|
||||
ev.prevent_default();
|
||||
ev.stop_propagation();
|
||||
Some(Msg::PageChanged(PageChanged::Board(
|
||||
BoardPageChange::ChangePosition(issue_id),
|
||||
)))
|
||||
});
|
||||
|
||||
let drag_out = drag_ev(Ev::DragLeave, move |_| {
|
||||
Some(Msg::PageChanged(PageChanged::Board(
|
||||
BoardPageChange::DragLeave(issue_id),
|
||||
)))
|
||||
});
|
||||
let on_click = mouse_ev("click", move |ev| {
|
||||
ev.prevent_default();
|
||||
ev.stop_propagation();
|
||||
seed::Url::new()
|
||||
.add_path_part("issues")
|
||||
.add_path_part(format!("{}", issue_id))
|
||||
.go_and_push();
|
||||
Msg::ChangePage(Page::EditIssue(issue_id))
|
||||
});
|
||||
let drag_started = crate::pages::project_page::events::on_drag_started_drag_issue(issue_id);
|
||||
let drag_stopped =
|
||||
crate::pages::project_page::events::on_drag_stop_issue_drag_stop(issue_id);
|
||||
let drag_over_handler =
|
||||
crate::pages::project_page::events::on_drag_enter_change_position(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![
|
||||
drag_started,
|
||||
|
@ -205,10 +205,10 @@ fn issue_list(page: &ReportsPage, project_name: &str, this_month_updated: &[&Iss
|
||||
.render();
|
||||
let priority_icon = StyledIcon::from(Icon::from(*priority))
|
||||
.render();
|
||||
let desc = Node::from_html(None,
|
||||
description
|
||||
.as_deref()
|
||||
.unwrap_or_default(),
|
||||
let desc = Node::from_html(
|
||||
description
|
||||
.as_deref()
|
||||
.unwrap_or_default(),
|
||||
);
|
||||
let link = StyledLink {
|
||||
children: vec![
|
||||
|
Loading…
Reference in New Issue
Block a user