颜色修复
This commit is contained in:
@@ -1209,6 +1209,16 @@ fn target_element(target: web_sys::EventTarget) -> Option<Element> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn event_target_matches_selector(
|
||||||
|
target: Option<web_sys::EventTarget>,
|
||||||
|
selector: &str,
|
||||||
|
) -> bool {
|
||||||
|
target
|
||||||
|
.and_then(target_element)
|
||||||
|
.and_then(|element| element.closest(selector).ok().flatten())
|
||||||
|
.is_some()
|
||||||
|
}
|
||||||
|
|
||||||
fn current_target_html_element(event: &WheelEvent) -> Option<HtmlElement> {
|
fn current_target_html_element(event: &WheelEvent) -> Option<HtmlElement> {
|
||||||
event.current_target()?.dyn_into::<HtmlElement>().ok()
|
event.current_target()?.dyn_into::<HtmlElement>().ok()
|
||||||
}
|
}
|
||||||
@@ -2250,6 +2260,8 @@ fn App() -> impl IntoView {
|
|||||||
let (text_selection_active, set_text_selection_active) = signal(false);
|
let (text_selection_active, set_text_selection_active) = signal(false);
|
||||||
let (floating_toolbar_anchor, set_floating_toolbar_anchor) =
|
let (floating_toolbar_anchor, set_floating_toolbar_anchor) =
|
||||||
signal(None::<FloatingToolbarAnchor>);
|
signal(None::<FloatingToolbarAnchor>);
|
||||||
|
let (locked_toolbar_anchor, set_locked_toolbar_anchor) =
|
||||||
|
signal(None::<FloatingToolbarAnchor>);
|
||||||
let (slash_open, set_slash_open) = signal(false);
|
let (slash_open, set_slash_open) = signal(false);
|
||||||
let (slash_index, set_slash_index) = signal(0_usize);
|
let (slash_index, set_slash_index) = signal(0_usize);
|
||||||
let (turn_into_open, set_turn_into_open) = signal(false);
|
let (turn_into_open, set_turn_into_open) = signal(false);
|
||||||
@@ -2294,6 +2306,18 @@ fn App() -> impl IntoView {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let turn_into_open = turn_into_open;
|
||||||
|
let color_menu_open = color_menu_open;
|
||||||
|
let more_menu_open = more_menu_open;
|
||||||
|
let set_locked_toolbar_anchor = set_locked_toolbar_anchor;
|
||||||
|
Effect::new(move |_| {
|
||||||
|
if !(turn_into_open.get() || color_menu_open.get() || more_menu_open.get()) {
|
||||||
|
set_locked_toolbar_anchor.set(None);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let editor_focused = editor_focused;
|
let editor_focused = editor_focused;
|
||||||
let text_selection_active = text_selection_active;
|
let text_selection_active = text_selection_active;
|
||||||
@@ -2311,8 +2335,7 @@ fn App() -> impl IntoView {
|
|||||||
color_menu_open.get_untracked(),
|
color_menu_open.get_untracked(),
|
||||||
more_menu_open.get_untracked(),
|
more_menu_open.get_untracked(),
|
||||||
);
|
);
|
||||||
if !editor_focused.get()
|
if ((!editor_focused.get() || !text_selection_active.get()) && !toolbar_locked)
|
||||||
|| (!text_selection_active.get() && !toolbar_locked)
|
|
||||||
|| slash_open.get()
|
|| slash_open.get()
|
||||||
|| block_menu_open.get()
|
|| block_menu_open.get()
|
||||||
{
|
{
|
||||||
@@ -2390,7 +2413,7 @@ fn App() -> impl IntoView {
|
|||||||
if let Some(target) = event.target() {
|
if let Some(target) = event.target() {
|
||||||
if let Some(element) = target_element(target) {
|
if let Some(element) = target_element(target) {
|
||||||
if element
|
if element
|
||||||
.closest(HANDLE_SHELL_SELECTOR)
|
.closest(&format!("{HANDLE_SHELL_SELECTOR}, .floating-toolbar"))
|
||||||
.ok()
|
.ok()
|
||||||
.flatten()
|
.flatten()
|
||||||
.is_some()
|
.is_some()
|
||||||
@@ -2808,14 +2831,20 @@ fn App() -> impl IntoView {
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
{move || {
|
{move || {
|
||||||
if let Some(anchor) = floating_toolbar_anchor.get() {
|
let toolbar_locked = toolbar_overlay_locked(
|
||||||
let toolbar_locked = toolbar_overlay_locked(
|
turn_into_open.get(),
|
||||||
turn_into_open.get(),
|
color_menu_open.get(),
|
||||||
color_menu_open.get(),
|
more_menu_open.get(),
|
||||||
more_menu_open.get(),
|
);
|
||||||
);
|
let toolbar_anchor = if toolbar_locked {
|
||||||
if !editor_focused.get()
|
locked_toolbar_anchor
|
||||||
|| (!text_selection_active.get() && !toolbar_locked)
|
.get()
|
||||||
|
.or_else(|| floating_toolbar_anchor.get())
|
||||||
|
} else {
|
||||||
|
floating_toolbar_anchor.get()
|
||||||
|
};
|
||||||
|
if let Some(anchor) = toolbar_anchor {
|
||||||
|
if ((!editor_focused.get() || !text_selection_active.get()) && !toolbar_locked)
|
||||||
|| slash_open.get()
|
|| slash_open.get()
|
||||||
|| block_menu_open.get()
|
|| block_menu_open.get()
|
||||||
|| dragging_block_index.get().is_some()
|
|| dragging_block_index.get().is_some()
|
||||||
@@ -2829,7 +2858,12 @@ fn App() -> impl IntoView {
|
|||||||
style:top=format!("{}px", anchor.top)
|
style:top=format!("{}px", anchor.top)
|
||||||
style:left=format!("{}px", anchor.left)
|
style:left=format!("{}px", anchor.left)
|
||||||
on:mousedown=move |event: MouseEvent| {
|
on:mousedown=move |event: MouseEvent| {
|
||||||
event.prevent_default();
|
if event_target_matches_selector(
|
||||||
|
event.target(),
|
||||||
|
".toolbar-btn, .toolbar-menu-item, .turn-into-item",
|
||||||
|
) {
|
||||||
|
event.prevent_default();
|
||||||
|
}
|
||||||
event.stop_propagation();
|
event.stop_propagation();
|
||||||
}
|
}
|
||||||
on:click=move |event: MouseEvent| {
|
on:click=move |event: MouseEvent| {
|
||||||
@@ -2844,54 +2878,51 @@ fn App() -> impl IntoView {
|
|||||||
data-active=move || turn_into_open.get().to_string()
|
data-active=move || turn_into_open.get().to_string()
|
||||||
data-testid="toolbar-turn-into"
|
data-testid="toolbar-turn-into"
|
||||||
on:click=move |_| {
|
on:click=move |_| {
|
||||||
set_turn_into_open.update(|open| *open = !*open);
|
let next_open = !turn_into_open.get_untracked();
|
||||||
|
if next_open {
|
||||||
|
set_locked_toolbar_anchor
|
||||||
|
.set(floating_toolbar_anchor.get_untracked());
|
||||||
|
}
|
||||||
|
set_turn_into_open.set(next_open);
|
||||||
set_block_menu_open.set(false);
|
set_block_menu_open.set(false);
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
"Text"
|
"Text"
|
||||||
</button>
|
</button>
|
||||||
{move || {
|
<div
|
||||||
if turn_into_open.get() {
|
class="turn-into-panel"
|
||||||
|
data-testid="turn-into-panel"
|
||||||
|
style:display=move || if turn_into_open.get() { "grid" } else { "none" }
|
||||||
|
on:mousedown=move |event: MouseEvent| {
|
||||||
|
event.stop_propagation();
|
||||||
|
}
|
||||||
|
on:click=move |event: MouseEvent| {
|
||||||
|
event.stop_propagation();
|
||||||
|
}
|
||||||
|
on:wheel=move |event: WheelEvent| {
|
||||||
|
trap_scroll_inside_menu(&event);
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{SLASH_ACTIONS.iter().map(|action| {
|
||||||
|
let kind = action.kind;
|
||||||
|
let label = action.label;
|
||||||
|
let description = action.description;
|
||||||
|
let testid = format!("turn-into-{}", action.id);
|
||||||
view! {
|
view! {
|
||||||
<div
|
<button
|
||||||
class="turn-into-panel"
|
class="turn-into-item"
|
||||||
data-testid="turn-into-panel"
|
data-testid=testid
|
||||||
on:mousedown=move |event: MouseEvent| {
|
on:click=move |_| {
|
||||||
event.prevent_default();
|
apply_feedback_result(set_command_feedback, run_slash_action(editor, kind));
|
||||||
event.stop_propagation();
|
set_turn_into_open.set(false);
|
||||||
}
|
|
||||||
on:click=move |event: MouseEvent| {
|
|
||||||
event.stop_propagation();
|
|
||||||
}
|
|
||||||
on:wheel=move |event: WheelEvent| {
|
|
||||||
trap_scroll_inside_menu(&event);
|
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{SLASH_ACTIONS.iter().map(|action| {
|
{label}
|
||||||
let kind = action.kind;
|
<span>{description}</span>
|
||||||
let label = action.label;
|
</button>
|
||||||
let description = action.description;
|
}
|
||||||
let testid = format!("turn-into-{}", action.id);
|
}).collect_view()}
|
||||||
view! {
|
</div>
|
||||||
<button
|
|
||||||
class="turn-into-item"
|
|
||||||
data-testid=testid
|
|
||||||
on:click=move |_| {
|
|
||||||
apply_feedback_result(set_command_feedback, run_slash_action(editor, kind));
|
|
||||||
set_turn_into_open.set(false);
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{label}
|
|
||||||
<span>{description}</span>
|
|
||||||
</button>
|
|
||||||
}
|
|
||||||
}).collect_view()}
|
|
||||||
</div>
|
|
||||||
}.into_any()
|
|
||||||
} else {
|
|
||||||
().into_any()
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -2959,113 +2990,110 @@ fn App() -> impl IntoView {
|
|||||||
|| color_menu_open.get()).to_string()
|
|| color_menu_open.get()).to_string()
|
||||||
data-testid="toolbar-color"
|
data-testid="toolbar-color"
|
||||||
on:click=move |_| {
|
on:click=move |_| {
|
||||||
set_color_menu_open.update(|open| *open = !*open);
|
let next_open = !color_menu_open.get_untracked();
|
||||||
|
if next_open {
|
||||||
|
set_locked_toolbar_anchor
|
||||||
|
.set(floating_toolbar_anchor.get_untracked());
|
||||||
|
}
|
||||||
|
set_color_menu_open.set(next_open);
|
||||||
set_more_menu_open.set(false);
|
set_more_menu_open.set(false);
|
||||||
set_turn_into_open.set(false);
|
set_turn_into_open.set(false);
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
"Color"
|
"Color"
|
||||||
</button>
|
</button>
|
||||||
{move || {
|
<div
|
||||||
if color_menu_open.get() {
|
class="toolbar-popover-panel"
|
||||||
view! {
|
data-testid="toolbar-color-panel"
|
||||||
<div
|
style:display=move || if color_menu_open.get() { "grid" } else { "none" }
|
||||||
class="toolbar-popover-panel"
|
on:mousedown=move |event: MouseEvent| {
|
||||||
data-testid="toolbar-color-panel"
|
event.stop_propagation();
|
||||||
on:mousedown=move |event: MouseEvent| {
|
}
|
||||||
event.prevent_default();
|
on:click=move |event: MouseEvent| {
|
||||||
event.stop_propagation();
|
event.stop_propagation();
|
||||||
}
|
}
|
||||||
on:click=move |event: MouseEvent| {
|
on:wheel=move |event: WheelEvent| {
|
||||||
event.stop_propagation();
|
trap_scroll_inside_menu(&event);
|
||||||
}
|
}
|
||||||
on:wheel=move |event: WheelEvent| {
|
>
|
||||||
trap_scroll_inside_menu(&event);
|
<div class="toolbar-popover-section">
|
||||||
}
|
<div class="toolbar-popover-title">"文字颜色"</div>
|
||||||
>
|
<div class="toolbar-color-grid">
|
||||||
<div class="toolbar-popover-section">
|
{TOOLBAR_TEXT_COLORS.iter().map(|option| {
|
||||||
<div class="toolbar-popover-title">"文字颜色"</div>
|
let value = option.value;
|
||||||
<div class="toolbar-color-grid">
|
let label = option.label;
|
||||||
{TOOLBAR_TEXT_COLORS.iter().map(|option| {
|
let testid = format!("toolbar-text-color-{}", option.id);
|
||||||
let value = option.value;
|
view! {
|
||||||
let label = option.label;
|
|
||||||
let testid = format!("toolbar-text-color-{}", option.id);
|
|
||||||
view! {
|
|
||||||
<button
|
|
||||||
class="toolbar-menu-item toolbar-color-item"
|
|
||||||
data-testid=testid
|
|
||||||
on:click=move |_| {
|
|
||||||
apply_feedback_result(
|
|
||||||
set_command_feedback,
|
|
||||||
apply_text_color(editor, value),
|
|
||||||
);
|
|
||||||
set_color_menu_open.set(false);
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="toolbar-color-chip"
|
|
||||||
style:background=value
|
|
||||||
></span>
|
|
||||||
<strong>{label}</strong>
|
|
||||||
</button>
|
|
||||||
}
|
|
||||||
}).collect_view()}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="toolbar-popover-section">
|
|
||||||
<div class="toolbar-popover-title">"背景颜色"</div>
|
|
||||||
<div class="toolbar-color-grid">
|
|
||||||
{TOOLBAR_HIGHLIGHT_COLORS.iter().map(|option| {
|
|
||||||
let value = option.value;
|
|
||||||
let label = option.label;
|
|
||||||
let testid = format!("toolbar-highlight-color-{}", option.id);
|
|
||||||
view! {
|
|
||||||
<button
|
|
||||||
class="toolbar-menu-item toolbar-color-item"
|
|
||||||
data-testid=testid
|
|
||||||
on:click=move |_| {
|
|
||||||
apply_feedback_result(
|
|
||||||
set_command_feedback,
|
|
||||||
apply_highlight_color(editor, Some(value)),
|
|
||||||
);
|
|
||||||
set_color_menu_open.set(false);
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="toolbar-color-chip"
|
|
||||||
style:background=value
|
|
||||||
></span>
|
|
||||||
<strong>{label}</strong>
|
|
||||||
</button>
|
|
||||||
}
|
|
||||||
}).collect_view()}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="toolbar-popover-section">
|
|
||||||
<button
|
<button
|
||||||
class="toolbar-menu-item"
|
class="toolbar-menu-item toolbar-color-item"
|
||||||
data-testid="toolbar-clear-color"
|
data-testid=testid
|
||||||
on:click=move |_| {
|
on:click=move |_| {
|
||||||
apply_feedback_result(
|
apply_feedback_result(
|
||||||
set_command_feedback,
|
set_command_feedback,
|
||||||
clear_text_color(editor),
|
apply_text_color(editor, value),
|
||||||
);
|
);
|
||||||
let _ = apply_highlight_color(editor, None);
|
|
||||||
set_color_menu_open.set(false);
|
set_color_menu_open.set(false);
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<strong>"清除颜色"</strong>
|
<span
|
||||||
<span>"移除文字色与背景色"</span>
|
class="toolbar-color-chip"
|
||||||
|
style:background=value
|
||||||
|
></span>
|
||||||
|
<strong>{label}</strong>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
}
|
||||||
</div>
|
}).collect_view()}
|
||||||
}.into_any()
|
</div>
|
||||||
} else {
|
</div>
|
||||||
().into_any()
|
|
||||||
}
|
<div class="toolbar-popover-section">
|
||||||
}}
|
<div class="toolbar-popover-title">"背景颜色"</div>
|
||||||
|
<div class="toolbar-color-grid">
|
||||||
|
{TOOLBAR_HIGHLIGHT_COLORS.iter().map(|option| {
|
||||||
|
let value = option.value;
|
||||||
|
let label = option.label;
|
||||||
|
let testid = format!("toolbar-highlight-color-{}", option.id);
|
||||||
|
view! {
|
||||||
|
<button
|
||||||
|
class="toolbar-menu-item toolbar-color-item"
|
||||||
|
data-testid=testid
|
||||||
|
on:click=move |_| {
|
||||||
|
apply_feedback_result(
|
||||||
|
set_command_feedback,
|
||||||
|
apply_highlight_color(editor, Some(value)),
|
||||||
|
);
|
||||||
|
set_color_menu_open.set(false);
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="toolbar-color-chip"
|
||||||
|
style:background=value
|
||||||
|
></span>
|
||||||
|
<strong>{label}</strong>
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
}).collect_view()}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="toolbar-popover-section">
|
||||||
|
<button
|
||||||
|
class="toolbar-menu-item"
|
||||||
|
data-testid="toolbar-clear-color"
|
||||||
|
on:click=move |_| {
|
||||||
|
apply_feedback_result(
|
||||||
|
set_command_feedback,
|
||||||
|
clear_text_color(editor),
|
||||||
|
);
|
||||||
|
let _ = apply_highlight_color(editor, None);
|
||||||
|
set_color_menu_open.set(false);
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<strong>"清除颜色"</strong>
|
||||||
|
<span>"移除文字色与背景色"</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -3082,69 +3110,66 @@ fn App() -> impl IntoView {
|
|||||||
|| more_menu_open.get()).to_string()
|
|| more_menu_open.get()).to_string()
|
||||||
data-testid="toolbar-more"
|
data-testid="toolbar-more"
|
||||||
on:click=move |_| {
|
on:click=move |_| {
|
||||||
set_more_menu_open.update(|open| *open = !*open);
|
let next_open = !more_menu_open.get_untracked();
|
||||||
|
if next_open {
|
||||||
|
set_locked_toolbar_anchor
|
||||||
|
.set(floating_toolbar_anchor.get_untracked());
|
||||||
|
}
|
||||||
|
set_more_menu_open.set(next_open);
|
||||||
set_color_menu_open.set(false);
|
set_color_menu_open.set(false);
|
||||||
set_turn_into_open.set(false);
|
set_turn_into_open.set(false);
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
"More"
|
"More"
|
||||||
</button>
|
</button>
|
||||||
{move || {
|
<div
|
||||||
if more_menu_open.get() {
|
class="toolbar-popover-panel"
|
||||||
view! {
|
data-testid="toolbar-more-panel"
|
||||||
<div
|
style:display=move || if more_menu_open.get() { "grid" } else { "none" }
|
||||||
class="toolbar-popover-panel"
|
on:mousedown=move |event: MouseEvent| {
|
||||||
data-testid="toolbar-more-panel"
|
event.stop_propagation();
|
||||||
on:mousedown=move |event: MouseEvent| {
|
|
||||||
event.prevent_default();
|
|
||||||
event.stop_propagation();
|
|
||||||
}
|
|
||||||
on:click=move |event: MouseEvent| {
|
|
||||||
event.stop_propagation();
|
|
||||||
}
|
|
||||||
on:wheel=move |event: WheelEvent| {
|
|
||||||
trap_scroll_inside_menu(&event);
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<div class="toolbar-popover-section">
|
|
||||||
<div class="toolbar-popover-title">"对齐方式"</div>
|
|
||||||
<div class="toolbar-more-list">
|
|
||||||
{TOOLBAR_ALIGN_OPTIONS.iter().map(|option| {
|
|
||||||
let label = option.label;
|
|
||||||
let alignment = option.alignment;
|
|
||||||
let testid = format!("toolbar-align-{}", option.id);
|
|
||||||
let active = match option.alignment {
|
|
||||||
TiptapTextAlign::Left => selection_state.get().align_left,
|
|
||||||
TiptapTextAlign::Center => selection_state.get().align_center,
|
|
||||||
TiptapTextAlign::Right => selection_state.get().align_right,
|
|
||||||
TiptapTextAlign::Justify => selection_state.get().align_justify,
|
|
||||||
};
|
|
||||||
view! {
|
|
||||||
<button
|
|
||||||
class="toolbar-menu-item toolbar-more-item"
|
|
||||||
data-active=active.to_string()
|
|
||||||
data-testid=testid
|
|
||||||
on:click=move |_| {
|
|
||||||
apply_feedback_result(
|
|
||||||
set_command_feedback,
|
|
||||||
apply_text_align(editor, alignment),
|
|
||||||
);
|
|
||||||
set_more_menu_open.set(false);
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<strong>{label}</strong>
|
|
||||||
<span>"按官方浮动工具条对当前块对齐"</span>
|
|
||||||
</button>
|
|
||||||
}
|
|
||||||
}).collect_view()}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}.into_any()
|
|
||||||
} else {
|
|
||||||
().into_any()
|
|
||||||
}
|
}
|
||||||
}}
|
on:click=move |event: MouseEvent| {
|
||||||
|
event.stop_propagation();
|
||||||
|
}
|
||||||
|
on:wheel=move |event: WheelEvent| {
|
||||||
|
trap_scroll_inside_menu(&event);
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<div class="toolbar-popover-section">
|
||||||
|
<div class="toolbar-popover-title">"对齐方式"</div>
|
||||||
|
<div class="toolbar-more-list">
|
||||||
|
{TOOLBAR_ALIGN_OPTIONS.iter().map(|option| {
|
||||||
|
let label = option.label;
|
||||||
|
let alignment = option.alignment;
|
||||||
|
let testid = format!("toolbar-align-{}", option.id);
|
||||||
|
let active = match option.alignment {
|
||||||
|
TiptapTextAlign::Left => selection_state.get().align_left,
|
||||||
|
TiptapTextAlign::Center => selection_state.get().align_center,
|
||||||
|
TiptapTextAlign::Right => selection_state.get().align_right,
|
||||||
|
TiptapTextAlign::Justify => selection_state.get().align_justify,
|
||||||
|
};
|
||||||
|
view! {
|
||||||
|
<button
|
||||||
|
class="toolbar-menu-item toolbar-more-item"
|
||||||
|
data-active=active.to_string()
|
||||||
|
data-testid=testid
|
||||||
|
on:click=move |_| {
|
||||||
|
apply_feedback_result(
|
||||||
|
set_command_feedback,
|
||||||
|
apply_text_align(editor, alignment),
|
||||||
|
);
|
||||||
|
set_more_menu_open.set(false);
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<strong>{label}</strong>
|
||||||
|
<span>"按官方浮动工具条对当前块对齐"</span>
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
}).collect_view()}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user