完成弹窗
This commit is contained in:
parent
fdcb8bd065
commit
291b8d9060
@ -16,3 +16,7 @@ html.light{
|
|||||||
background-color:white;
|
background-color:white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
html {
|
||||||
|
overflow-x:hidden;
|
||||||
|
}
|
||||||
|
@ -618,6 +618,38 @@ video {
|
|||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes slide-in {
|
||||||
|
0% {
|
||||||
|
transform: translateX(100%);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: translateX(0);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-slide-in {
|
||||||
|
animation: slide-in 0.3s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slide-out {
|
||||||
|
0% {
|
||||||
|
transform: translateX(0);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: translateX(100%);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-slide-out {
|
||||||
|
animation: slide-out 0.3s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
.items-center {
|
.items-center {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
@ -652,18 +684,19 @@ video {
|
|||||||
border-style: solid;
|
border-style: solid;
|
||||||
}
|
}
|
||||||
|
|
||||||
.border-none {
|
.border-blue-200 {
|
||||||
border-style: none;
|
--tw-border-opacity: 1;
|
||||||
|
border-color: rgb(191 219 254 / var(--tw-border-opacity, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
.border-blue-500 {
|
.border-green-200 {
|
||||||
--tw-border-opacity: 1;
|
--tw-border-opacity: 1;
|
||||||
border-color: rgb(59 130 246 / var(--tw-border-opacity, 1));
|
border-color: rgb(187 247 208 / var(--tw-border-opacity, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
.border-green-500 {
|
.border-red-200 {
|
||||||
--tw-border-opacity: 1;
|
--tw-border-opacity: 1;
|
||||||
border-color: rgb(34 197 94 / var(--tw-border-opacity, 1));
|
border-color: rgb(254 202 202 / var(--tw-border-opacity, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
.border-red-500 {
|
.border-red-500 {
|
||||||
@ -671,34 +704,38 @@ video {
|
|||||||
border-color: rgb(239 68 68 / var(--tw-border-opacity, 1));
|
border-color: rgb(239 68 68 / var(--tw-border-opacity, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-blue-200 {
|
.border-transparent {
|
||||||
--tw-bg-opacity: 1;
|
border-color: transparent;
|
||||||
background-color: rgb(191 219 254 / var(--tw-bg-opacity, 1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-blue-500 {
|
.bg-blue-400 {
|
||||||
--tw-bg-opacity: 1;
|
--tw-bg-opacity: 1;
|
||||||
background-color: rgb(59 130 246 / var(--tw-bg-opacity, 1));
|
background-color: rgb(96 165 250 / var(--tw-bg-opacity, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-green-200 {
|
.bg-blue-50 {
|
||||||
--tw-bg-opacity: 1;
|
--tw-bg-opacity: 1;
|
||||||
background-color: rgb(187 247 208 / var(--tw-bg-opacity, 1));
|
background-color: rgb(239 246 255 / var(--tw-bg-opacity, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-green-500 {
|
.bg-green-400 {
|
||||||
--tw-bg-opacity: 1;
|
--tw-bg-opacity: 1;
|
||||||
background-color: rgb(34 197 94 / var(--tw-bg-opacity, 1));
|
background-color: rgb(74 222 128 / var(--tw-bg-opacity, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-red-200 {
|
.bg-green-50 {
|
||||||
--tw-bg-opacity: 1;
|
--tw-bg-opacity: 1;
|
||||||
background-color: rgb(254 202 202 / var(--tw-bg-opacity, 1));
|
background-color: rgb(240 253 244 / var(--tw-bg-opacity, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-red-500 {
|
.bg-red-400 {
|
||||||
--tw-bg-opacity: 1;
|
--tw-bg-opacity: 1;
|
||||||
background-color: rgb(239 68 68 / var(--tw-bg-opacity, 1));
|
background-color: rgb(248 113 113 / var(--tw-bg-opacity, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-red-50 {
|
||||||
|
--tw-bg-opacity: 1;
|
||||||
|
background-color: rgb(254 242 242 / var(--tw-bg-opacity, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
.px-3 {
|
.px-3 {
|
||||||
@ -721,9 +758,9 @@ video {
|
|||||||
line-height: 1.25rem;
|
line-height: 1.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-blue-800 {
|
.text-blue-600 {
|
||||||
--tw-text-opacity: 1;
|
--tw-text-opacity: 1;
|
||||||
color: rgb(30 64 175 / var(--tw-text-opacity, 1));
|
color: rgb(37 99 235 / var(--tw-text-opacity, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-gray-800 {
|
.text-gray-800 {
|
||||||
@ -731,14 +768,18 @@ video {
|
|||||||
color: rgb(31 41 55 / var(--tw-text-opacity, 1));
|
color: rgb(31 41 55 / var(--tw-text-opacity, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-green-800 {
|
.text-green-600 {
|
||||||
--tw-text-opacity: 1;
|
--tw-text-opacity: 1;
|
||||||
color: rgb(22 101 52 / var(--tw-text-opacity, 1));
|
color: rgb(22 163 74 / var(--tw-text-opacity, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-red-800 {
|
.text-red-600 {
|
||||||
--tw-text-opacity: 1;
|
--tw-text-opacity: 1;
|
||||||
color: rgb(153 27 27 / var(--tw-text-opacity, 1));
|
color: rgb(220 38 38 / var(--tw-text-opacity, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
.opacity-60 {
|
||||||
|
opacity: 0.6;
|
||||||
}
|
}
|
||||||
|
|
||||||
.transition-all {
|
.transition-all {
|
||||||
@ -747,10 +788,64 @@ video {
|
|||||||
transition-duration: 150ms;
|
transition-duration: 150ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.transition-opacity {
|
||||||
|
transition-property: opacity;
|
||||||
|
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
transition-duration: 150ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
.duration-200 {
|
||||||
|
transition-duration: 200ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ease-in-out {
|
||||||
|
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
}
|
||||||
|
|
||||||
.ease-linear {
|
.ease-linear {
|
||||||
transition-timing-function: linear;
|
transition-timing-function: linear;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hover\:scale-\[1\.02\]:hover {
|
||||||
|
--tw-scale-x: 1.02;
|
||||||
|
--tw-scale-y: 1.02;
|
||||||
|
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
||||||
|
}
|
||||||
|
|
||||||
|
.hover\:border-blue-400:hover {
|
||||||
|
--tw-border-opacity: 1;
|
||||||
|
border-color: rgb(96 165 250 / var(--tw-border-opacity, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
.hover\:border-green-400:hover {
|
||||||
|
--tw-border-opacity: 1;
|
||||||
|
border-color: rgb(74 222 128 / var(--tw-border-opacity, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
.hover\:border-red-400:hover {
|
||||||
|
--tw-border-opacity: 1;
|
||||||
|
border-color: rgb(248 113 113 / var(--tw-border-opacity, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
.hover\:text-blue-400:hover {
|
||||||
|
--tw-text-opacity: 1;
|
||||||
|
color: rgb(96 165 250 / var(--tw-text-opacity, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
.hover\:text-green-400:hover {
|
||||||
|
--tw-text-opacity: 1;
|
||||||
|
color: rgb(74 222 128 / var(--tw-text-opacity, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
.hover\:text-red-400:hover {
|
||||||
|
--tw-text-opacity: 1;
|
||||||
|
color: rgb(248 113 113 / var(--tw-text-opacity, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
.hover\:opacity-100:hover {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
.dark\:text-gray-200:is(.dark *) {
|
.dark\:text-gray-200:is(.dark *) {
|
||||||
--tw-text-opacity: 1;
|
--tw-text-opacity: 1;
|
||||||
color: rgb(229 231 235 / var(--tw-text-opacity, 1));
|
color: rgb(229 231 235 / var(--tw-text-opacity, 1));
|
||||||
|
@ -1 +0,0 @@
|
|||||||
pub fn set_interval(time: u32, callback: fn()) {}
|
|
@ -1,4 +1,3 @@
|
|||||||
pub mod dom;
|
pub mod dom;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod helps;
|
pub mod helps;
|
||||||
pub mod hooks;
|
|
||||||
|
@ -1,17 +1,16 @@
|
|||||||
use std::format;
|
use std::format;
|
||||||
|
|
||||||
use crate::common::error::{CustomErrorInto, CustomResult};
|
use crate::common::dom::add_element_class;
|
||||||
use crate::common::helps::generate_random_string;
|
use crate::common::helps::generate_random_string;
|
||||||
use crate::Route;
|
use crate::Route;
|
||||||
use dioxus::{logger::tracing, prelude::*};
|
use dioxus::{logger::tracing, prelude::*};
|
||||||
use dioxus_free_icons::icons::bs_icons::{BsCheckCircle, BsInfoCircle, BsXCircle, BsXLg};
|
use dioxus_free_icons::icons::bs_icons::{BsCheckCircle, BsInfoCircle, BsXCircle, BsXLg};
|
||||||
use dioxus_free_icons::Icon;
|
use dioxus_free_icons::Icon;
|
||||||
use wasm_bindgen::prelude::*;
|
|
||||||
use web_sys::window;
|
use web_sys::window;
|
||||||
|
|
||||||
#[derive(PartialEq, Clone)]
|
#[derive(PartialEq, Clone)]
|
||||||
pub struct NotificationProvider {
|
pub struct NotificationProvider {
|
||||||
pub notifications: Vec<NotificationProps>,
|
notifications: Vec<NotificationProps>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for NotificationProvider {
|
impl Default for NotificationProvider {
|
||||||
@ -57,6 +56,8 @@ struct NoticationColorMatching {
|
|||||||
border_color: &'static str,
|
border_color: &'static str,
|
||||||
text_color: &'static str,
|
text_color: &'static str,
|
||||||
progress_color: &'static str,
|
progress_color: &'static str,
|
||||||
|
hover_border_color: &'static str,
|
||||||
|
hover_text_color: &'static str,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_color_matching(notification_type: &NotificationType) -> NoticationColorMatching {
|
fn get_color_matching(notification_type: &NotificationType) -> NoticationColorMatching {
|
||||||
@ -69,10 +70,12 @@ fn get_color_matching(notification_type: &NotificationType) -> NoticationColorMa
|
|||||||
height:18,
|
height:18,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
bg_color: "bg-blue-200",
|
bg_color: "bg-blue-50",
|
||||||
border_color: "border-blue-500",
|
border_color: "border-blue-200",
|
||||||
text_color: "text-blue-800",
|
text_color: "text-blue-600",
|
||||||
progress_color: "bg-blue-500",
|
progress_color: "bg-blue-400",
|
||||||
|
hover_border_color: "hover:border-blue-400",
|
||||||
|
hover_text_color: "hover:text-blue-400",
|
||||||
},
|
},
|
||||||
NotificationType::Error => NoticationColorMatching {
|
NotificationType::Error => NoticationColorMatching {
|
||||||
icon: rsx! {
|
icon: rsx! {
|
||||||
@ -82,10 +85,12 @@ fn get_color_matching(notification_type: &NotificationType) -> NoticationColorMa
|
|||||||
height:18,
|
height:18,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
bg_color: "bg-red-200",
|
bg_color: "bg-red-50",
|
||||||
border_color: "border-red-500",
|
border_color: "border-red-200",
|
||||||
text_color: "text-red-800",
|
text_color: "text-red-600",
|
||||||
progress_color: "bg-red-500",
|
progress_color: "bg-red-400",
|
||||||
|
hover_border_color: "hover:border-red-400",
|
||||||
|
hover_text_color: "hover:text-red-400",
|
||||||
},
|
},
|
||||||
NotificationType::Success => NoticationColorMatching {
|
NotificationType::Success => NoticationColorMatching {
|
||||||
icon: rsx! {
|
icon: rsx! {
|
||||||
@ -95,28 +100,22 @@ fn get_color_matching(notification_type: &NotificationType) -> NoticationColorMa
|
|||||||
height:18,
|
height:18,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
bg_color: "bg-green-200",
|
bg_color: "bg-green-50",
|
||||||
border_color: "border-green-500",
|
border_color: "border-green-200",
|
||||||
text_color: "text-green-800",
|
text_color: "text-green-600",
|
||||||
progress_color: "bg-green-500",
|
progress_color: "bg-green-400",
|
||||||
|
hover_border_color: "hover:border-green-400",
|
||||||
|
hover_text_color: "hover:text-green-400",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_notification(id: String) {
|
pub fn remove_notification(id: String) {
|
||||||
let mut notifications_context = use_context::<Signal<NotificationProvider>>();
|
let mut notifications_context = use_context::<Signal<NotificationProvider>>();
|
||||||
tracing::info!("开始删除通知,ID: {}", id);
|
|
||||||
tracing::info!(
|
|
||||||
"当前通知列表长度: {}",
|
|
||||||
notifications_context().notifications.len()
|
|
||||||
);
|
|
||||||
notifications_context.with_mut(|state| {
|
notifications_context.with_mut(|state| {
|
||||||
let before_len = state.notifications.len();
|
|
||||||
state
|
state
|
||||||
.notifications
|
.notifications
|
||||||
.retain(|notification| notification.id != id);
|
.retain(|notification| notification.id != id);
|
||||||
let after_len = state.notifications.len();
|
|
||||||
tracing::info!("删除通知后,列表长度从 {} 变为 {}", before_len, after_len);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,25 +123,21 @@ pub fn remove_notification(id: String) {
|
|||||||
pub fn NotificationCard(props: NotificationProps) -> Element {
|
pub fn NotificationCard(props: NotificationProps) -> Element {
|
||||||
let color_matching = get_color_matching(&props.r#type);
|
let color_matching = get_color_matching(&props.r#type);
|
||||||
let mut progress = use_signal(|| 0);
|
let mut progress = use_signal(|| 0);
|
||||||
let mut hover = use_signal(|| false);
|
let mut is_hover = use_signal(|| false);
|
||||||
let id_for_future = props.id.clone();
|
let id_for_future = props.id.clone();
|
||||||
|
|
||||||
use_future(move || {
|
use_future(move || {
|
||||||
let id = id_for_future.clone();
|
let id = id_for_future.clone();
|
||||||
let progress_time = (props.time * 10) as i32;
|
let progress_time = (props.time * 10) as i32;
|
||||||
async move {
|
async move {
|
||||||
loop {
|
loop {
|
||||||
if progress() >= 100 {
|
if is_hover() {
|
||||||
let promise = js_sys::Promise::new(&mut |resolve, _| {
|
progress.set(0);
|
||||||
window()
|
} else {
|
||||||
.unwrap()
|
|
||||||
.set_timeout_with_callback_and_timeout_and_arguments_0(&resolve, 150)
|
|
||||||
.unwrap();
|
|
||||||
});
|
|
||||||
wasm_bindgen_futures::JsFuture::from(promise).await.unwrap();
|
|
||||||
remove_notification(id.clone());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
progress.set(progress() + 1);
|
progress.set(progress() + 1);
|
||||||
|
}
|
||||||
|
let current_progress = progress();
|
||||||
|
|
||||||
let promise = js_sys::Promise::new(&mut |resolve, _| {
|
let promise = js_sys::Promise::new(&mut |resolve, _| {
|
||||||
window()
|
window()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@ -153,16 +148,37 @@ pub fn NotificationCard(props: NotificationProps) -> Element {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
});
|
});
|
||||||
wasm_bindgen_futures::JsFuture::from(promise).await.unwrap();
|
wasm_bindgen_futures::JsFuture::from(promise).await.unwrap();
|
||||||
|
|
||||||
|
if current_progress >= 100 && !is_hover() {
|
||||||
|
let _ = add_element_class(&format!("#{}", id), "animate-slide-out");
|
||||||
|
let promise = js_sys::Promise::new(&mut |resolve, _| {
|
||||||
|
window()
|
||||||
|
.unwrap()
|
||||||
|
.set_timeout_with_callback_and_timeout_and_arguments_0(&resolve, 300)
|
||||||
|
.unwrap();
|
||||||
|
});
|
||||||
|
wasm_bindgen_futures::JsFuture::from(promise).await.unwrap();
|
||||||
|
remove_notification(id.clone());
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
rsx! {
|
rsx! {
|
||||||
div {
|
div {
|
||||||
|
key: "{props.id}",
|
||||||
id: props.id.clone(),
|
id: props.id.clone(),
|
||||||
class:format!("rounded px-3 py-3 m-2 border-none text-gray-800 dark:text-gray-200 {} hover:{} border-2 text-base",color_matching.bg_color,color_matching.border_color),
|
class: "rounded px-3 py-3 m-2 border-2 border-transparent text-gray-800 {color_matching.bg_color} text-base animate-slide-in dark:text-gray-200 {color_matching.hover_border_color} transition-all duration-200 ease-in-out hover:scale-[1.02]",
|
||||||
|
onmouseenter:move |_|{
|
||||||
|
is_hover.set(true)
|
||||||
|
},
|
||||||
|
onmouseleave: move |_| {
|
||||||
|
is_hover.set(false)
|
||||||
|
},
|
||||||
div {
|
div {
|
||||||
div {
|
div {
|
||||||
class:format!("flex items-center justify-between {}",color_matching.text_color),
|
class:"flex items-center justify-between {color_matching.text_color}",
|
||||||
div {
|
div {
|
||||||
class:"mr-2 relative top-[0.06rem]",
|
class:"mr-2 relative top-[0.06rem]",
|
||||||
{color_matching.icon},
|
{color_matching.icon},
|
||||||
@ -176,7 +192,7 @@ pub fn NotificationCard(props: NotificationProps) -> Element {
|
|||||||
e.prevent_default();
|
e.prevent_default();
|
||||||
remove_notification(props.id.clone());
|
remove_notification(props.id.clone());
|
||||||
},
|
},
|
||||||
class:"ml-1 flex-shrink-0",
|
class:"ml-1 flex-shrink-0 opacity-60 hover:opacity-100 transition-opacity duration-200 {color_matching.text_color}",
|
||||||
Icon{
|
Icon{
|
||||||
icon:BsXLg,
|
icon:BsXLg,
|
||||||
height:18,
|
height:18,
|
||||||
@ -185,19 +201,17 @@ pub fn NotificationCard(props: NotificationProps) -> Element {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
div {
|
div {
|
||||||
class:format!("text-sm {}",color_matching.text_color),
|
class:"text-sm {color_matching.text_color}",
|
||||||
{props.content.clone()}
|
{props.content.clone()}
|
||||||
}
|
}
|
||||||
div {
|
div {
|
||||||
class:format!("mt-2 border border-solid rounded-md {}",color_matching.border_color),
|
class:"mt-2 border border-solid rounded-md {color_matching.border_color}",
|
||||||
div {
|
div {
|
||||||
class:format!("w-full h-1 transition-all ease-linear {}",color_matching.progress_color),
|
class:"w-full h-1 transition-all ease-linear {color_matching.progress_color}",
|
||||||
style:format!("width:{}%",progress()),
|
style:"width:{progress()}%",
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -213,6 +227,7 @@ pub fn Notification() -> Element {
|
|||||||
{notifications.notifications.iter().map(move |item| {
|
{notifications.notifications.iter().map(move |item| {
|
||||||
rsx! {
|
rsx! {
|
||||||
NotificationCard {
|
NotificationCard {
|
||||||
|
key: "{item.id}",
|
||||||
..item.clone()
|
..item.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,20 @@ module.exports = {
|
|||||||
colors: {
|
colors: {
|
||||||
accent: 'var(--accent-color)',
|
accent: 'var(--accent-color)',
|
||||||
},
|
},
|
||||||
|
animation: {
|
||||||
|
'slide-in': 'slide-in 0.3s ease-out',
|
||||||
|
'slide-out': 'slide-out 0.3s ease-out',
|
||||||
|
},
|
||||||
|
keyframes: {
|
||||||
|
'slide-in': {
|
||||||
|
'0%': { transform: 'translateX(100%)', opacity: '0' },
|
||||||
|
'100%': { transform: 'translateX(0)', opacity: '1' },
|
||||||
|
},
|
||||||
|
'slide-out': {
|
||||||
|
'0%': { transform: 'translateX(0)', opacity: '1' },
|
||||||
|
'100%': { transform: 'translateX(100%)', opacity: '0' },
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
plugins: [],
|
plugins: [],
|
||||||
|
Loading…
Reference in New Issue
Block a user