Fix macOS dark-theme rendering and AMS settings icon clipping (#14846)
Fixes a set of Mac only GUI rendering issues: 1. cropped icon 2. wrong color in dark theme ## Screenshots <img width="343" height="370" alt="Screenshot 2026-07-19 at 16 16 39" src="https://github.com/user-attachments/assets/1b89dc01-cd52-43ff-9231-ac31a7e1c18f" /> <img width="701" height="700" alt="Screenshot 2026-07-19 at 13 19 02" src="https://github.com/user-attachments/assets/00fa173f-dea9-4b87-8ac8-ae311dca5c31" /> <img width="425" height="324" alt="Screenshot 2026-07-19 at 02 31 14" src="https://github.com/user-attachments/assets/50740669-d5c0-4309-b0ac-b577a460cc91" /> <img width="1121" height="890" alt="Screenshot 2026-07-19 at 02 24 33" src="https://github.com/user-attachments/assets/9ab380e3-63f6-41a1-9c2c-8d0247bd036f" />
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
#include "uiDeviceUpdateVersion.h"
|
||||
|
||||
#include "slic3r/GUI/I18N.hpp"
|
||||
#include "slic3r/GUI/GUI_App.hpp"
|
||||
#include "slic3r/GUI/wxExtensions.hpp"
|
||||
#include "slic3r/GUI/Widgets/Label.hpp" // Orca: explicit Label include
|
||||
|
||||
@@ -27,6 +28,7 @@ uiDeviceUpdateVersion::uiDeviceUpdateVersion(wxWindow* parent,
|
||||
long style /*= wxTAB_TRAVERSAL*/)
|
||||
: wxPanel(parent, id, pos, size, style)
|
||||
{
|
||||
SetBackgroundColour(*wxWHITE);
|
||||
CreateWidgets();
|
||||
}
|
||||
|
||||
@@ -110,4 +112,6 @@ void uiDeviceUpdateVersion::CreateWidgets()
|
||||
|
||||
SetSizer(main_sizer);
|
||||
Layout();
|
||||
|
||||
wxGetApp().UpdateDarkUIWin(this);
|
||||
}
|
||||
@@ -257,7 +257,9 @@ void wgtDeviceNozzleRackArea::CreateGui()
|
||||
wxSizer* content_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
m_panel_content = new wxPanel(m_simple_book, wxID_ANY);
|
||||
m_panel_content->SetBackgroundColour(*wxWHITE);
|
||||
m_panel_refresh = new wxPanel(m_simple_book, wxID_ANY);
|
||||
m_panel_refresh->SetBackgroundColour(*wxWHITE);
|
||||
|
||||
// Create Hotends ans Rack Position Panel
|
||||
wxSizer* hotends_rack_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
@@ -188,6 +188,7 @@ void wgtDeviceNozzleRackHotendUpdate::CreateGui()
|
||||
|
||||
// Icon
|
||||
wxPanel* imagePanel = new wxPanel(this);
|
||||
imagePanel->SetBackgroundColour(WGT_DEVICE_NOZZLE_RACK_HOTEND_UPDATE_DEFAULT_BG);
|
||||
imagePanel->SetMaxSize(WX_DIP_SIZE(46, -1));
|
||||
imagePanel->SetMinSize(WX_DIP_SIZE(46, -1));
|
||||
imagePanel->SetSize(wxSize(FromDIP(46), FromDIP(-1)));
|
||||
@@ -203,6 +204,7 @@ void wgtDeviceNozzleRackHotendUpdate::CreateGui()
|
||||
|
||||
// Diameter/type (vertical)
|
||||
wxPanel* type_panel = new wxPanel(this);
|
||||
type_panel->SetBackgroundColour(WGT_DEVICE_NOZZLE_RACK_HOTEND_UPDATE_DEFAULT_BG);
|
||||
auto* main_type_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
auto* type_sizer_row_1 = new wxBoxSizer(wxHORIZONTAL);
|
||||
auto* type_sizer_row_2 = new wxBoxSizer(wxHORIZONTAL);
|
||||
@@ -251,6 +253,7 @@ void wgtDeviceNozzleRackHotendUpdate::CreateGui()
|
||||
|
||||
// SN and version (vertical)
|
||||
wxPanel* info_panel = new wxPanel(this);
|
||||
info_panel->SetBackgroundColour(WGT_DEVICE_NOZZLE_RACK_HOTEND_UPDATE_DEFAULT_BG);
|
||||
auto* info_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
m_sn_label = new Label(info_panel);
|
||||
m_sn_label->SetFont(Label::Body_12);
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "wgtDeviceNozzleRack.h"
|
||||
|
||||
#include "slic3r/GUI/I18N.hpp"
|
||||
#include "slic3r/GUI/GUI_App.hpp"
|
||||
#include "slic3r/GUI/DeviceTab/wgtMsgBox.h"
|
||||
#include "slic3r/GUI/Widgets/Label.hpp" // Orca: explicit Label include
|
||||
|
||||
@@ -28,6 +29,7 @@ wgtDeviceNozzleRackSelect::wgtDeviceNozzleRackSelect(wxWindow *parent) : wxPanel
|
||||
static wxPanel* s_create_title(wxWindow *parent, const wxString& text)
|
||||
{
|
||||
wxPanel *panel = new wxPanel(parent, wxID_ANY);
|
||||
panel->SetBackgroundColour(*wxWHITE);
|
||||
|
||||
auto title = new Label(panel, text);
|
||||
title->SetFont(::Label::Body_13);
|
||||
@@ -35,7 +37,7 @@ static wxPanel* s_create_title(wxWindow *parent, const wxString& text)
|
||||
title->SetForegroundColour(0x909090);
|
||||
|
||||
auto split_line = new wxPanel(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
|
||||
split_line->SetBackgroundColour(0xeeeeee);
|
||||
split_line->SetBackgroundColour(wxColour(0xEE, 0xEE, 0xEE));
|
||||
split_line->SetMinSize(wxSize(-1, 1));
|
||||
split_line->SetMaxSize(wxSize(-1, 1));
|
||||
|
||||
@@ -104,6 +106,8 @@ void wgtDeviceNozzleRackSelect::CreateGui()
|
||||
SetSizer(main_sizer);
|
||||
Layout();
|
||||
Fit();
|
||||
|
||||
wxGetApp().UpdateDarkUIWin(this);
|
||||
}
|
||||
|
||||
static void s_update_nozzle_info(wgtDeviceNozzleRackNozzleItem* item,
|
||||
|
||||
@@ -30,6 +30,7 @@ HMSNotifyItem::HMSNotifyItem(const std::string& dev_id, wxWindow *parent, DevHMS
|
||||
auto main_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
m_panel_hms = new wxPanel(this, wxID_ANY, wxDefaultPosition, HMS_NOTIFY_ITEM_SIZE, wxTAB_TRAVERSAL);
|
||||
m_panel_hms->SetBackgroundColour(*wxWHITE);
|
||||
auto m_panel_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
auto m_panel_sizer_inner = new wxBoxSizer(wxHORIZONTAL);
|
||||
@@ -126,6 +127,8 @@ HMSNotifyItem::HMSNotifyItem(const std::string& dev_id, wxWindow *parent, DevHMS
|
||||
if (!m_url.empty()) wxLaunchDefaultBrowser(m_url);
|
||||
});
|
||||
#endif
|
||||
|
||||
wxGetApp().UpdateDarkUIWin(this);
|
||||
}
|
||||
HMSNotifyItem ::~HMSNotifyItem() {
|
||||
;
|
||||
@@ -166,6 +169,7 @@ HMSPanel::HMSPanel(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wx
|
||||
auto m_main_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
m_scrolledWindow = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL);
|
||||
m_scrolledWindow->SetBackgroundColour(*wxWHITE);
|
||||
m_scrolledWindow->SetScrollRate(5, 5);
|
||||
|
||||
m_top_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
@@ -179,6 +183,8 @@ HMSPanel::HMSPanel(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wx
|
||||
this->SetSizerAndFit(m_main_sizer);
|
||||
|
||||
Layout();
|
||||
|
||||
wxGetApp().UpdateDarkUIWin(this);
|
||||
}
|
||||
|
||||
HMSPanel::~HMSPanel() {
|
||||
|
||||
+38
-15
@@ -460,6 +460,17 @@ enum class ActionButtonType : int {
|
||||
abSendGCode
|
||||
};
|
||||
|
||||
// Background for the extruder-group title chip and its edit buttons, matching the StaticGroup
|
||||
// interior. macOS keeps a lighter #F7F7F7 tint in light mode; dark mode uses the mapped colour.
|
||||
static wxColour extruder_group_chip_bg()
|
||||
{
|
||||
#ifdef __WXOSX__
|
||||
if (!wxGetApp().dark_mode())
|
||||
return wxColour("#F7F7F7");
|
||||
#endif
|
||||
return StateColor::darkModeColorFor(*wxWHITE);
|
||||
}
|
||||
|
||||
// Interactive title row for the sidebar extruder cards: "<title> ( <count> ) [edit]". The count shows the
|
||||
// extruder's physical nozzle count on multi-nozzle printers (hidden elsewhere, SetCount(-1)), and the
|
||||
// trailing button opens the manual nozzle-count editor when enabled (a plain dot otherwise).
|
||||
@@ -468,11 +479,7 @@ class HoverLabel : public wxPanel
|
||||
public:
|
||||
HoverLabel(wxWindow *parent, const wxString &label) : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE)
|
||||
{
|
||||
#ifdef __WXOSX__
|
||||
SetBackgroundColour("#F7F7F7");
|
||||
#else
|
||||
SetBackgroundColour(*wxWHITE);
|
||||
#endif
|
||||
SetBackgroundColour(extruder_group_chip_bg());
|
||||
auto sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
m_label = new wxStaticText(this, wxID_ANY, label, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE);
|
||||
@@ -496,11 +503,7 @@ public:
|
||||
|
||||
m_hover_btn = new ScalableButton(this, wxID_ANY, "dot");
|
||||
m_hover_btn->SetMinSize(wxSize(FromDIP(25), -1));
|
||||
#ifdef __WXOSX__
|
||||
m_hover_btn->SetBackgroundColour("#F7F7F7");
|
||||
#else
|
||||
m_hover_btn->SetBackgroundColour(*wxWHITE);
|
||||
#endif
|
||||
m_hover_btn->SetBackgroundColour(extruder_group_chip_bg());
|
||||
m_hover_btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [this](auto &evt) {
|
||||
if (m_enabled && m_hover_on_click)
|
||||
m_hover_on_click();
|
||||
@@ -550,6 +553,17 @@ public:
|
||||
|
||||
void Rescale() { m_hover_btn->msw_rescale(); }
|
||||
|
||||
// Re-apply the chip colours on a live light/dark switch (they are set once at construction).
|
||||
void sys_color_changed()
|
||||
{
|
||||
SetBackgroundColour(extruder_group_chip_bg());
|
||||
m_label->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#6B6B6B")));
|
||||
for (wxStaticText *t : {m_brace_left, m_count, m_brace_right})
|
||||
t->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#262E30")));
|
||||
m_hover_btn->SetBackgroundColour(extruder_group_chip_bg());
|
||||
Refresh();
|
||||
}
|
||||
|
||||
private:
|
||||
// Content changed: the cached best size (ours and, transitively, our ancestors') is stale,
|
||||
// and the parent must re-lay this row or the sizer keeps allocating the old width.
|
||||
@@ -625,6 +639,15 @@ struct ExtruderGroup : StaticGroup
|
||||
for (int i = 0; i < 4; ++i)
|
||||
ams[i]->msw_rescale();
|
||||
}
|
||||
|
||||
void sys_color_changed()
|
||||
{
|
||||
if (hover_label)
|
||||
hover_label->sys_color_changed();
|
||||
if (btn_edit)
|
||||
btn_edit->SetBackgroundColour(extruder_group_chip_bg());
|
||||
Refresh();
|
||||
}
|
||||
};
|
||||
|
||||
struct Sidebar::priv
|
||||
@@ -1275,11 +1298,7 @@ ExtruderGroup::ExtruderGroup(wxWindow * parent, int index, wxString const &title
|
||||
//label_ams->SetMinSize({FromDIP(70), -1});
|
||||
if (index >= 0) {
|
||||
btn_edit = new ScalableButton(this, wxID_ANY, "dot");
|
||||
#ifdef __WXOSX__
|
||||
btn_edit->SetBackgroundColour("#F7F7F7");
|
||||
#else
|
||||
btn_edit->SetBackgroundColour(*wxWHITE);
|
||||
#endif
|
||||
btn_edit->SetBackgroundColour(extruder_group_chip_bg());
|
||||
btn_edit->Hide();
|
||||
btn_edit->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [this, index](auto &evt) {
|
||||
PopupWindow *window = new AMSCountPopupWindow(this, index);
|
||||
@@ -3866,6 +3885,10 @@ void Sidebar::sys_color_changed()
|
||||
p->image_printer->SetSize(FromDIP(PRINTER_THUMBNAIL_SIZE));
|
||||
p->image_printer_bed->SetSize(FromDIP(PRINTER_THUMBNAIL_SIZE));
|
||||
|
||||
for (ExtruderGroup *ext : {p->left_extruder, p->right_extruder, p->single_extruder})
|
||||
if (ext)
|
||||
ext->sys_color_changed();
|
||||
|
||||
// call a kill focus event to ensure new colors applied
|
||||
for (ComboBox* combo : std::vector<ComboBox*>{p->combo_printer, p->combo_nozzle_dia, p->combo_printer_bed}){
|
||||
wxFocusEvent fakeEvent(wxEVT_KILL_FOCUS);
|
||||
|
||||
@@ -559,7 +559,7 @@ SelectMachineDialog::SelectMachineDialog(Plater *plater)
|
||||
sizer_split_options->Add(m_split_options_line, 1, wxALIGN_CENTER, 0);
|
||||
|
||||
m_options_other = new wxPanel(m_scroll_area);
|
||||
|
||||
m_options_other->SetBackgroundColour(*wxWHITE);
|
||||
|
||||
auto option_timelapse = new PrintOption(m_options_other, _L("Timelapse"), wxEmptyString, ops_no_auto, "timelapse");
|
||||
|
||||
@@ -3144,7 +3144,7 @@ void SelectMachineDialog::save_option_vals(MachineObject *obj) {
|
||||
void SelectMachineDialog::Enable_Auto_Refill(bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
m_ams_backup_tip->SetForegroundColour(wxColour("#009688"));
|
||||
m_ams_backup_tip->SetForegroundColour(StateColor::darkModeColorFor("#009688"));
|
||||
}
|
||||
else {
|
||||
m_ams_backup_tip->SetForegroundColour(wxColour(0x90, 0x90, 0x90));
|
||||
@@ -3169,19 +3169,21 @@ void SelectMachineDialog::show_timelapse_folder_popup()
|
||||
return;
|
||||
}
|
||||
|
||||
// build popup with rounded corners + light border
|
||||
// build popup with rounded corners + themed border
|
||||
const wxColour popup_bg = wxGetApp().dark_mode() ? wxColour("#333337") : wxColour(0xF0, 0xF0, 0xF0);
|
||||
const wxColour popup_border = StateColor::darkModeColorFor(wxColour(0xCE, 0xCE, 0xCE));
|
||||
m_timelapse_storage_popup = new PopupWindow(this, wxBORDER_NONE);
|
||||
m_timelapse_storage_popup->SetBackgroundColour(wxColour(0xF0, 0xF0, 0xF0));
|
||||
m_timelapse_storage_popup->Bind(wxEVT_PAINT, [this](wxPaintEvent&) {
|
||||
m_timelapse_storage_popup->SetBackgroundColour(popup_bg);
|
||||
m_timelapse_storage_popup->Bind(wxEVT_PAINT, [this, popup_bg, popup_border](wxPaintEvent&) {
|
||||
wxPaintDC dc(m_timelapse_storage_popup);
|
||||
auto size = m_timelapse_storage_popup->GetSize();
|
||||
dc.SetPen(wxPen(wxColour(0xCE, 0xCE, 0xCE)));
|
||||
dc.SetBrush(wxBrush(wxColour(0xF0, 0xF0, 0xF0)));
|
||||
dc.SetPen(wxPen(popup_border));
|
||||
dc.SetBrush(wxBrush(popup_bg));
|
||||
dc.DrawRoundedRectangle(0, 0, size.x, size.y, FromDIP(8));
|
||||
});
|
||||
|
||||
auto* panel = new wxPanel(m_timelapse_storage_popup, wxID_ANY);
|
||||
panel->SetBackgroundColour(wxColour(0xF0, 0xF0, 0xF0));
|
||||
panel->SetBackgroundColour(popup_bg);
|
||||
|
||||
// horizontal layout: [ Internal] [External]
|
||||
auto* sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
@@ -3202,7 +3204,8 @@ void SelectMachineDialog::show_timelapse_folder_popup()
|
||||
if (enabled) radio->Enable(); else radio->Disable();
|
||||
|
||||
auto* text = new Label(panel, Label::Body_14, label);
|
||||
text->SetForegroundColour(enabled ? wxColour(0x5C, 0x5C, 0x5C) : wxColour(0xAC, 0xAC, 0xAC));
|
||||
text->SetForegroundColour(enabled ? (wxGetApp().dark_mode() ? wxColour("#E5E5E4") : wxColour(0x5C, 0x5C, 0x5C))
|
||||
: StateColor::darkModeColorFor(wxColour(0xAC, 0xAC, 0xAC)));
|
||||
|
||||
if (enabled) {
|
||||
auto on_select = [this, val](wxMouseEvent&) {
|
||||
@@ -3376,7 +3379,7 @@ void SelectMachineDialog::show_timelapse_storage_dialog(MachineObject* obj)
|
||||
create_scaled_bitmap("obj_warning", &dlg, 16), wxDefaultPosition, wxSize(FromDIP(16), FromDIP(16)));
|
||||
auto* msg_label = new Label(&dlg, body_text);
|
||||
msg_label->SetFont(Label::Body_14);
|
||||
msg_label->SetForegroundColour(wxColour(0x33, 0x33, 0x33));
|
||||
msg_label->SetForegroundColour(wxGetApp().dark_mode() ? wxColour("#EFEFF0") : wxColour(0x33, 0x33, 0x33));
|
||||
msg_label->Wrap(FromDIP(340));
|
||||
msg_sizer->Add(warn_bmp, 0, wxALIGN_TOP | wxRIGHT, FromDIP(6));
|
||||
msg_sizer->Add(msg_label, 1, wxEXPAND);
|
||||
@@ -3417,6 +3420,7 @@ void SelectMachineDialog::show_timelapse_storage_dialog(MachineObject* obj)
|
||||
dlg.SetSizer(main_sizer);
|
||||
dlg.Fit();
|
||||
dlg.CenterOnParent();
|
||||
wxGetApp().UpdateDlgDarkUI(&dlg);
|
||||
|
||||
// ShowModal returns after the dialog closes; handle the action outside the modal stack.
|
||||
// wxID_CANCEL is returned when the user clicks X (close button) -> do nothing in that case.
|
||||
@@ -4077,12 +4081,15 @@ void SelectMachineDialog::on_timer(wxTimerEvent &event)
|
||||
if (m_ams_backup_tip->IsShown()) {
|
||||
m_ams_backup_tip->Hide();
|
||||
img_ams_backup->Hide();
|
||||
m_scroll_area->Layout();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!m_ams_backup_tip->IsShown()) {
|
||||
m_ams_backup_tip->Show();
|
||||
img_ams_backup->Show();
|
||||
// first show: position them, they were never laid out while hidden
|
||||
m_scroll_area->Layout();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -538,6 +538,7 @@ void PrintingTaskPanel::create_panel(wxWindow* parent)
|
||||
wxBoxSizer *bSizer_task_name = new wxBoxSizer(wxVERTICAL);
|
||||
wxBoxSizer *bSizer_task_name_hor = new wxBoxSizer(wxHORIZONTAL);
|
||||
wxPanel* task_name_panel = new wxPanel(parent);
|
||||
task_name_panel->SetBackgroundColour(*wxWHITE);
|
||||
|
||||
m_staticText_subtask_value = new wxStaticText(task_name_panel, wxID_ANY, _L("N/A"), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT | wxST_ELLIPSIZE_END);
|
||||
m_staticText_subtask_value->SetMaxSize(wxSize(FromDIP(600), -1));
|
||||
@@ -705,6 +706,7 @@ void PrintingTaskPanel::create_panel(wxWindow* parent)
|
||||
bSizer_text->Add(m_staticText_progress_left, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
|
||||
|
||||
m_printing_stage_panel = new wxPanel(penel_finish_time);
|
||||
m_printing_stage_panel->SetBackgroundColour(*wxWHITE);
|
||||
wxBoxSizer *printingstage_vertical_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
wxBoxSizer *printingstage_horizontal_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
|
||||
@@ -1796,6 +1796,8 @@ bool UpgradePanel::Show(bool show)
|
||||
const wxString &name /*= wxEmptyString*/)
|
||||
: wxPanel(parent,id,pos,size,style)
|
||||
{
|
||||
SetBackgroundColour(*wxWHITE);
|
||||
|
||||
upgrade_green_icon = ScalableBitmap(this, "monitor_upgrade_online", 5);
|
||||
|
||||
auto ams_sizer = new wxFlexGridSizer(0, 2, 0, 0);
|
||||
@@ -1879,6 +1881,7 @@ bool UpgradePanel::Show(bool show)
|
||||
const wxString& name /*= wxEmptyString*/)
|
||||
: wxPanel(parent, id, pos, size, style)
|
||||
{
|
||||
SetBackgroundColour(*wxWHITE);
|
||||
|
||||
upgrade_green_icon = ScalableBitmap(this, "monitor_upgrade_online", 5);
|
||||
|
||||
|
||||
@@ -145,6 +145,8 @@ AMSControl::AMSControl(wxWindow *parent, wxWindowID id, const wxPoint &pos, cons
|
||||
m_button_ams_setting_press = ScalableBitmap(this, "ams_setting_press", 24);
|
||||
|
||||
m_button_ams_setting = new wxStaticBitmap(m_panel_option_left, wxID_ANY, m_button_ams_setting_normal.bmp(), wxDefaultPosition, wxSize(FromDIP(24), FromDIP(24)));
|
||||
m_button_ams_setting->SetMinSize(wxSize(FromDIP(24), FromDIP(24)));
|
||||
m_button_ams_setting->SetMaxSize(wxSize(FromDIP(24), FromDIP(24)));
|
||||
m_sizer_option_left->Add(m_button_auto_refill, 0, wxALIGN_CENTER, 0);
|
||||
m_sizer_option_left->Add(0, 0, 0, wxLEFT, FromDIP(20));
|
||||
m_sizer_option_left->Add(m_button_ams_setting, 0, wxALIGN_CENTER, 0);
|
||||
|
||||
Reference in New Issue
Block a user