mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-23 10:18:50 +00:00
Introduce dark/light mode preference (#12224)
This requires Qt 6.8 and only works on Win and Mac.
This commit is contained in:
parent
25cc10a04c
commit
7bf14813d7
@ -7,6 +7,10 @@
|
|||||||
|
|
||||||
!!!The following pref variables were added in 2.5:
|
!!!The following pref variables were added in 2.5:
|
||||||
|
|
||||||
|
- \color_scheme {system,light,dark} allows to override the system-wide
|
||||||
|
color scheme (i.e., dark or light mode). This requires LyX to be built
|
||||||
|
against Qt >= 6.8.0.
|
||||||
|
|
||||||
!!!The following pref variables were changed in 2.5:
|
!!!The following pref variables were changed in 2.5:
|
||||||
|
|
||||||
!!!The following pref variables are obsoleted in 2.5:
|
!!!The following pref variables are obsoleted in 2.5:
|
||||||
|
@ -1982,7 +1982,7 @@ if __name__ == '__main__':
|
|||||||
lyx_check_config = True
|
lyx_check_config = True
|
||||||
lyx_kpsewhich = True
|
lyx_kpsewhich = True
|
||||||
outfile = 'lyxrc.defaults'
|
outfile = 'lyxrc.defaults'
|
||||||
lyxrc_fileformat = 38
|
lyxrc_fileformat = 39
|
||||||
rc_entries = ''
|
rc_entries = ''
|
||||||
lyx_keep_temps = False
|
lyx_keep_temps = False
|
||||||
version_suffix = ''
|
version_suffix = ''
|
||||||
|
@ -170,6 +170,10 @@
|
|||||||
# Add option to configure ui style
|
# Add option to configure ui style
|
||||||
# No conversion necessary.
|
# No conversion necessary.
|
||||||
|
|
||||||
|
# Incremented to format 39, by spitz
|
||||||
|
# Add \color_scheme {system|light|dark}
|
||||||
|
# No conversion necessary.
|
||||||
|
|
||||||
# NOTE: The format should also be updated in LYXRC.cpp and
|
# NOTE: The format should also be updated in LYXRC.cpp and
|
||||||
# in configure.py (search for lyxrc_fileformat).
|
# in configure.py (search for lyxrc_fileformat).
|
||||||
|
|
||||||
@ -558,5 +562,6 @@ conversions = [
|
|||||||
[ 35, [add_dark_color]],
|
[ 35, [add_dark_color]],
|
||||||
[ 36, [add_spellcheck_default]],
|
[ 36, [add_spellcheck_default]],
|
||||||
[ 37, [remove_fullscreen_widthlimit]],
|
[ 37, [remove_fullscreen_widthlimit]],
|
||||||
[ 38, []]
|
[ 38, []],
|
||||||
|
[ 39, []]
|
||||||
]
|
]
|
||||||
|
@ -60,7 +60,7 @@ namespace {
|
|||||||
|
|
||||||
// The format should also be updated in configure.py, and conversion code
|
// The format should also be updated in configure.py, and conversion code
|
||||||
// should be added to prefs2prefs_prefs.py.
|
// should be added to prefs2prefs_prefs.py.
|
||||||
static unsigned int const LYXRC_FILEFORMAT = 38; // chillenb: screen_width and screen_limit
|
static unsigned int const LYXRC_FILEFORMAT = 39; // spitz: \color_scheme {system|light|dark}
|
||||||
// when adding something to this array keep it sorted!
|
// when adding something to this array keep it sorted!
|
||||||
LexerKeyword lyxrcTags[] = {
|
LexerKeyword lyxrcTags[] = {
|
||||||
{ "\\accept_compound", LyXRC::RC_ACCEPT_COMPOUND },
|
{ "\\accept_compound", LyXRC::RC_ACCEPT_COMPOUND },
|
||||||
@ -81,6 +81,7 @@ LexerKeyword lyxrcTags[] = {
|
|||||||
{ "\\citation_search_pattern", LyXRC::RC_CITATION_SEARCH_PATTERN },
|
{ "\\citation_search_pattern", LyXRC::RC_CITATION_SEARCH_PATTERN },
|
||||||
{ "\\citation_search_view", LyXRC::RC_CITATION_SEARCH_VIEW },
|
{ "\\citation_search_view", LyXRC::RC_CITATION_SEARCH_VIEW },
|
||||||
{ "\\close_buffer_with_last_view", LyXRC::RC_CLOSE_BUFFER_WITH_LAST_VIEW },
|
{ "\\close_buffer_with_last_view", LyXRC::RC_CLOSE_BUFFER_WITH_LAST_VIEW },
|
||||||
|
{ "\\color_scheme", LyXRC::RC_COLOR_SCHEME },
|
||||||
{ "\\completion_cursor_text", LyXRC::RC_COMPLETION_CURSOR_TEXT },
|
{ "\\completion_cursor_text", LyXRC::RC_COMPLETION_CURSOR_TEXT },
|
||||||
{ "\\completion_inline_delay", LyXRC::RC_COMPLETION_INLINE_DELAY },
|
{ "\\completion_inline_delay", LyXRC::RC_COMPLETION_INLINE_DELAY },
|
||||||
{ "\\completion_inline_dots", LyXRC::RC_COMPLETION_INLINE_DOTS },
|
{ "\\completion_inline_dots", LyXRC::RC_COMPLETION_INLINE_DOTS },
|
||||||
@ -707,6 +708,11 @@ LyXRC::ReturnValues LyXRC::read(Lexer & lexrc, bool check_format)
|
|||||||
citation_search_view = lexrc.getString();
|
citation_search_view = lexrc.getString();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case RC_COLOR_SCHEME:
|
||||||
|
if (lexrc.next())
|
||||||
|
color_scheme = lexrc.getString();
|
||||||
|
break;
|
||||||
|
|
||||||
case RC_CT_ADDITIONS_UNDERLINED:
|
case RC_CT_ADDITIONS_UNDERLINED:
|
||||||
lexrc >> ct_additions_underlined;
|
lexrc >> ct_additions_underlined;
|
||||||
break;
|
break;
|
||||||
@ -1704,6 +1710,15 @@ void LyXRC::write(ostream & os, bool ignore_system_lyxrc, string const & name) c
|
|||||||
if (tag != RC_LAST)
|
if (tag != RC_LAST)
|
||||||
break;
|
break;
|
||||||
// fall through
|
// fall through
|
||||||
|
case RC_COLOR_SCHEME:
|
||||||
|
if (ignore_system_lyxrc ||
|
||||||
|
color_scheme != system_lyxrc.color_scheme) {
|
||||||
|
os << "# Set color scheme (system|light|dark)\n";
|
||||||
|
os << "\\color_scheme " << color_scheme << '\n';
|
||||||
|
}
|
||||||
|
if (tag != RC_LAST)
|
||||||
|
break;
|
||||||
|
// fall through
|
||||||
case RC_CT_ADDITIONS_UNDERLINED:
|
case RC_CT_ADDITIONS_UNDERLINED:
|
||||||
if (ignore_system_lyxrc ||
|
if (ignore_system_lyxrc ||
|
||||||
ct_additions_underlined
|
ct_additions_underlined
|
||||||
@ -2926,6 +2941,7 @@ void actOnUpdatedPrefs(LyXRC const & lyxrc_orig, LyXRC const & lyxrc_new)
|
|||||||
case LyXRC::RC_CITATION_SEARCH_PATTERN:
|
case LyXRC::RC_CITATION_SEARCH_PATTERN:
|
||||||
case LyXRC::RC_CITATION_SEARCH_VIEW:
|
case LyXRC::RC_CITATION_SEARCH_VIEW:
|
||||||
case LyXRC::RC_CHECKLASTFILES:
|
case LyXRC::RC_CHECKLASTFILES:
|
||||||
|
case LyXRC::RC_COLOR_SCHEME:
|
||||||
case LyXRC::RC_COMPLETION_CURSOR_TEXT:
|
case LyXRC::RC_COMPLETION_CURSOR_TEXT:
|
||||||
case LyXRC::RC_COMPLETION_INLINE_DELAY:
|
case LyXRC::RC_COMPLETION_INLINE_DELAY:
|
||||||
case LyXRC::RC_COMPLETION_INLINE_DOTS:
|
case LyXRC::RC_COMPLETION_INLINE_DOTS:
|
||||||
@ -3210,6 +3226,10 @@ string const LyXRC::getDescription(LyXRCTags tag)
|
|||||||
str = _("Show a small box around a Math Macro with the macro name when the cursor is inside.");
|
str = _("Show a small box around a Math Macro with the macro name when the cursor is inside.");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case LyXRC::RC_COLOR_SCHEME:
|
||||||
|
str = _("Possibility to enforce a particular color scheme (system|dark|light)");
|
||||||
|
break;
|
||||||
|
|
||||||
case RC_DEFFILE:
|
case RC_DEFFILE:
|
||||||
str = _("Command definition file. Can either specify an absolute path, or LyX will look in its global and local commands/ directories.");
|
str = _("Command definition file. Can either specify an absolute path, or LyX will look in its global and local commands/ directories.");
|
||||||
break;
|
break;
|
||||||
|
@ -58,6 +58,7 @@ public:
|
|||||||
RC_CITATION_SEARCH,
|
RC_CITATION_SEARCH,
|
||||||
RC_CITATION_SEARCH_PATTERN,
|
RC_CITATION_SEARCH_PATTERN,
|
||||||
RC_CITATION_SEARCH_VIEW,
|
RC_CITATION_SEARCH_VIEW,
|
||||||
|
RC_COLOR_SCHEME,
|
||||||
RC_COMPLETION_CURSOR_TEXT,
|
RC_COMPLETION_CURSOR_TEXT,
|
||||||
RC_COMPLETION_INLINE_DELAY,
|
RC_COMPLETION_INLINE_DELAY,
|
||||||
RC_COMPLETION_INLINE_MATH,
|
RC_COMPLETION_INLINE_MATH,
|
||||||
@ -550,6 +551,8 @@ public:
|
|||||||
std::string forward_search_dvi;
|
std::string forward_search_dvi;
|
||||||
///
|
///
|
||||||
std::string forward_search_pdf;
|
std::string forward_search_pdf;
|
||||||
|
/// specifiy color scheme (system|dark|light)
|
||||||
|
std::string color_scheme;
|
||||||
///
|
///
|
||||||
int export_overwrite = NO_FILES;
|
int export_overwrite = NO_FILES;
|
||||||
/// Default decimal point when aligning table columns on decimal
|
/// Default decimal point when aligning table columns on decimal
|
||||||
|
@ -116,6 +116,9 @@
|
|||||||
#include <QSortFilterProxyModel>
|
#include <QSortFilterProxyModel>
|
||||||
#include <QStandardItemModel>
|
#include <QStandardItemModel>
|
||||||
#include <QStyle>
|
#include <QStyle>
|
||||||
|
#if (QT_VERSION >= QT_VERSION_CHECK(6, 8, 0))
|
||||||
|
#include <QStyleHints>
|
||||||
|
#endif
|
||||||
#include <QSvgRenderer>
|
#include <QSvgRenderer>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QTranslator>
|
#include <QTranslator>
|
||||||
@ -1256,6 +1259,13 @@ void Application::applyPrefs()
|
|||||||
{
|
{
|
||||||
if (lyxrc.ui_style != "default")
|
if (lyxrc.ui_style != "default")
|
||||||
lyx::frontend::GuiApplication::setStyle(toqstr(lyxrc.ui_style));
|
lyx::frontend::GuiApplication::setStyle(toqstr(lyxrc.ui_style));
|
||||||
|
#if (defined(Q_OS_WIN) || defined(Q_CYGWIN_WIN) || defined(Q_OS_MAC)) && QT_VERSION >= QT_VERSION_CHECK(6, 8, 0)
|
||||||
|
// Set color scheme from prefs
|
||||||
|
if (lyxrc.color_scheme == "dark")
|
||||||
|
guiApp->styleHints()->setColorScheme(Qt::ColorScheme::Dark);
|
||||||
|
else if (lyxrc.color_scheme == "light")
|
||||||
|
guiApp->styleHints()->setColorScheme(Qt::ColorScheme::Light);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
FuncStatus GuiApplication::getStatus(FuncRequest const & cmd) const
|
FuncStatus GuiApplication::getStatus(FuncRequest const & cmd) const
|
||||||
|
@ -64,6 +64,9 @@
|
|||||||
#include <QSpinBox>
|
#include <QSpinBox>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QStyleFactory>
|
#include <QStyleFactory>
|
||||||
|
#if (defined(Q_OS_WIN) || defined(Q_CYGWIN_WIN) || defined(Q_OS_MAC)) && QT_VERSION >= QT_VERSION_CHECK(6, 8, 0)
|
||||||
|
#include <QStyleHints>
|
||||||
|
#endif
|
||||||
#include <QTreeWidget>
|
#include <QTreeWidget>
|
||||||
#include <QTreeWidgetItem>
|
#include <QTreeWidgetItem>
|
||||||
#include <QValidator>
|
#include <QValidator>
|
||||||
@ -2523,6 +2526,10 @@ PrefUserInterface::PrefUserInterface(GuiPreferences * form)
|
|||||||
this, SIGNAL(changed()));
|
this, SIGNAL(changed()));
|
||||||
connect(uiStyleCO, SIGNAL(activated(int)),
|
connect(uiStyleCO, SIGNAL(activated(int)),
|
||||||
this, SIGNAL(changed()));
|
this, SIGNAL(changed()));
|
||||||
|
#if (defined(Q_OS_WIN) || defined(Q_CYGWIN_WIN) || defined(Q_OS_MAC)) && QT_VERSION >= QT_VERSION_CHECK(6, 8, 0)
|
||||||
|
connect(colorSchemeCO, SIGNAL(activated(int)),
|
||||||
|
this, SIGNAL(changed()));
|
||||||
|
#endif
|
||||||
connect(useSystemThemeIconsCB, SIGNAL(clicked()),
|
connect(useSystemThemeIconsCB, SIGNAL(clicked()),
|
||||||
this, SIGNAL(changed()));
|
this, SIGNAL(changed()));
|
||||||
connect(lastfilesSB, SIGNAL(valueChanged(int)),
|
connect(lastfilesSB, SIGNAL(valueChanged(int)),
|
||||||
@ -2545,6 +2552,15 @@ PrefUserInterface::PrefUserInterface(GuiPreferences * form)
|
|||||||
iconSetCO->addItem(qt_("Classic"), "classic");
|
iconSetCO->addItem(qt_("Classic"), "classic");
|
||||||
iconSetCO->addItem(qt_("Oxygen"), "oxygen");
|
iconSetCO->addItem(qt_("Oxygen"), "oxygen");
|
||||||
|
|
||||||
|
#if (defined(Q_OS_WIN) || defined(Q_CYGWIN_WIN) || defined(Q_OS_MAC)) && QT_VERSION >= QT_VERSION_CHECK(6, 8, 0)
|
||||||
|
colorSchemeCO->addItem(qt_("System Default"), "system");
|
||||||
|
colorSchemeCO->addItem(qt_("Light Mode"), "light");
|
||||||
|
colorSchemeCO->addItem(qt_("Dark Mode"), "dark");
|
||||||
|
#else
|
||||||
|
colorSchemeCO->setVisible(false);
|
||||||
|
colorSchemeLA->setVisible(false);
|
||||||
|
#endif
|
||||||
|
|
||||||
uiStyleCO->addItem(qt_("Default"), toqstr("default"));
|
uiStyleCO->addItem(qt_("Default"), toqstr("default"));
|
||||||
for (auto const & style : QStyleFactory::keys())
|
for (auto const & style : QStyleFactory::keys())
|
||||||
uiStyleCO->addItem(style, style.toLower());
|
uiStyleCO->addItem(style, style.toLower());
|
||||||
@ -2575,6 +2591,19 @@ void PrefUserInterface::applyRC(LyXRC & rc) const
|
|||||||
else
|
else
|
||||||
frontend::GuiApplication::setStyle(uistyle);
|
frontend::GuiApplication::setStyle(uistyle);
|
||||||
}
|
}
|
||||||
|
#if (defined(Q_OS_WIN) || defined(Q_CYGWIN_WIN) || defined(Q_OS_MAC)) && QT_VERSION >= QT_VERSION_CHECK(6, 8, 0)
|
||||||
|
QString const color_scheme = colorSchemeCO->itemData(
|
||||||
|
colorSchemeCO->currentIndex()).toString();
|
||||||
|
if (rc.color_scheme != fromqstr(color_scheme)) {
|
||||||
|
if (lyxrc.color_scheme == "dark")
|
||||||
|
guiApp->styleHints()->setColorScheme(Qt::ColorScheme::Dark);
|
||||||
|
else if (lyxrc.color_scheme == "light")
|
||||||
|
guiApp->styleHints()->setColorScheme(Qt::ColorScheme::Light);
|
||||||
|
else
|
||||||
|
guiApp->styleHints()->unsetColorScheme();
|
||||||
|
}
|
||||||
|
rc.color_scheme = fromqstr(color_scheme);
|
||||||
|
#endif
|
||||||
|
|
||||||
rc.ui_file = internal_path(fromqstr(uiFileED->text()));
|
rc.ui_file = internal_path(fromqstr(uiFileED->text()));
|
||||||
rc.use_system_theme_icons = useSystemThemeIconsCB->isChecked();
|
rc.use_system_theme_icons = useSystemThemeIconsCB->isChecked();
|
||||||
@ -2607,6 +2636,12 @@ void PrefUserInterface::updateRC(LyXRC const & rc)
|
|||||||
toggleToolbarsCB->setChecked(rc.full_screen_toolbars);
|
toggleToolbarsCB->setChecked(rc.full_screen_toolbars);
|
||||||
toggleTabbarCB->setChecked(rc.full_screen_tabbar);
|
toggleTabbarCB->setChecked(rc.full_screen_tabbar);
|
||||||
toggleMenubarCB->setChecked(rc.full_screen_menubar);
|
toggleMenubarCB->setChecked(rc.full_screen_menubar);
|
||||||
|
#if (defined(Q_OS_WIN) || defined(Q_CYGWIN_WIN) || defined(Q_OS_MAC)) && QT_VERSION >= QT_VERSION_CHECK(6, 8, 0)
|
||||||
|
int colorscheme = colorSchemeCO->findData(toqstr(rc.color_scheme));
|
||||||
|
if (colorscheme < 0)
|
||||||
|
colorscheme = 0;
|
||||||
|
colorSchemeCO->setCurrentIndex(colorscheme);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1792,10 +1792,12 @@ bool GuiView::event(QEvent * e)
|
|||||||
// dark/light mode runtime switch support
|
// dark/light mode runtime switch support
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0)
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0)
|
||||||
case QEvent::ThemeChange: {
|
case QEvent::ThemeChange: {
|
||||||
guiApp->setPalette(guiApp->style()->standardPalette());
|
if (lyxrc.color_scheme != "dark" && lyxrc.color_scheme != "light") {
|
||||||
// We need to update metrics here to avoid a crash (#12786)
|
guiApp->setPalette(guiApp->style()->standardPalette());
|
||||||
theBufferList().changed(true);
|
// We need to update metrics here to avoid a crash (#12786)
|
||||||
refillToolbars();
|
theBufferList().changed(true);
|
||||||
|
refillToolbars();
|
||||||
|
}
|
||||||
return QMainWindow::event(e);
|
return QMainWindow::event(e);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -42,23 +42,22 @@
|
|||||||
</item>
|
</item>
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<layout class="QGridLayout" name="gridLayout" columnstretch="0,1,0">
|
<layout class="QGridLayout" name="gridLayout" columnstretch="0,1,0">
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QComboBox" name="uiStyleCO">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>You can set a custom style here. Note that only certain styles may support dark mode, e.g. fusion on Windows.</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="2">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2"/>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLineEdit" name="uiFileED"/>
|
||||||
|
</item>
|
||||||
<item row="1" column="2">
|
<item row="1" column="2">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout"/>
|
<layout class="QHBoxLayout" name="horizontalLayout"/>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="2">
|
|
||||||
<widget class="QPushButton" name="uiFilePB">
|
|
||||||
<property name="text">
|
|
||||||
<string>Bro&wse...</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QComboBox" name="iconSetCO">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>The icon set to use. Warning: normal size of icons may be wrong until you save the preferences and restart LyX.</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QLabel" name="iconSetLA">
|
<widget class="QLabel" name="iconSetLA">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@ -79,8 +78,12 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="1">
|
<item row="1" column="1">
|
||||||
<widget class="QLineEdit" name="uiFileED"/>
|
<widget class="QComboBox" name="iconSetCO">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>The icon set to use. Warning: normal size of icons may be wrong until you save the preferences and restart LyX.</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
<item row="2" column="0">
|
||||||
<widget class="QLabel" name="uiStyleLA">
|
<widget class="QLabel" name="uiStyleLA">
|
||||||
@ -92,15 +95,29 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="1">
|
<item row="0" column="2">
|
||||||
<widget class="QComboBox" name="uiStyleCO">
|
<widget class="QPushButton" name="uiFilePB">
|
||||||
<property name="toolTip">
|
<property name="text">
|
||||||
<string>You can set a custom style here. Note that only certain styles may support dark mode, e.g. fusion on Windows.</string>
|
<string>Bro&wse...</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="2">
|
<item row="3" column="1">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2"/>
|
<widget class="QComboBox" name="colorSchemeCO">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>You can override the system's color scheme here if the selected style supports multiple schemes.</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLabel" name="colorSchemeLA">
|
||||||
|
<property name="text">
|
||||||
|
<string>C&olor scheme:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>colorSchemeCO</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
Loading…
Reference in New Issue
Block a user