mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-01-14 03:01:15 +00:00
Load and use Segoe UI [Semibold] if no Open Sans.
Sometimes Open Sans Semibold fails to load properly on the latest Windows Creators Update. In that case try to load Segoe UI instead. An attempt to fix #3276.
This commit is contained in:
parent
6418c9c718
commit
297856db32
@ -1043,7 +1043,7 @@ MainWindow::~MainWindow() {
|
|||||||
PreLaunchWindow *PreLaunchWindowInstance = 0;
|
PreLaunchWindow *PreLaunchWindowInstance = 0;
|
||||||
|
|
||||||
PreLaunchWindow::PreLaunchWindow(QString title) : TWidget(0) {
|
PreLaunchWindow::PreLaunchWindow(QString title) : TWidget(0) {
|
||||||
Fonts::start();
|
Fonts::Start();
|
||||||
|
|
||||||
QIcon icon(App::pixmapFromImageInPlace(QImage(cPlatform() == dbipMac ? qsl(":/gui/art/iconbig256.png") : qsl(":/gui/art/icon256.png"))));
|
QIcon icon(App::pixmapFromImageInPlace(QImage(cPlatform() == dbipMac ? qsl(":/gui/art/iconbig256.png") : qsl(":/gui/art/icon256.png"))));
|
||||||
if (cPlatform() == dbipLinux32 || cPlatform() == dbipLinux64) {
|
if (cPlatform() == dbipLinux32 || cPlatform() == dbipLinux64) {
|
||||||
@ -1090,7 +1090,7 @@ PreLaunchWindow::~PreLaunchWindow() {
|
|||||||
|
|
||||||
PreLaunchLabel::PreLaunchLabel(QWidget *parent) : QLabel(parent) {
|
PreLaunchLabel::PreLaunchLabel(QWidget *parent) : QLabel(parent) {
|
||||||
QFont labelFont(font());
|
QFont labelFont(font());
|
||||||
labelFont.setFamily(qsl("Open Sans Semibold"));
|
labelFont.setFamily(Fonts::GetOverride(qsl("Open Sans Semibold")));
|
||||||
labelFont.setPixelSize(static_cast<PreLaunchWindow*>(parent)->basicSize());
|
labelFont.setPixelSize(static_cast<PreLaunchWindow*>(parent)->basicSize());
|
||||||
setFont(labelFont);
|
setFont(labelFont);
|
||||||
|
|
||||||
@ -1108,7 +1108,7 @@ void PreLaunchLabel::setText(const QString &text) {
|
|||||||
|
|
||||||
PreLaunchInput::PreLaunchInput(QWidget *parent, bool password) : QLineEdit(parent) {
|
PreLaunchInput::PreLaunchInput(QWidget *parent, bool password) : QLineEdit(parent) {
|
||||||
QFont logFont(font());
|
QFont logFont(font());
|
||||||
logFont.setFamily(qsl("Open Sans"));
|
logFont.setFamily(Fonts::GetOverride(qsl("Open Sans")));
|
||||||
logFont.setPixelSize(static_cast<PreLaunchWindow*>(parent)->basicSize());
|
logFont.setPixelSize(static_cast<PreLaunchWindow*>(parent)->basicSize());
|
||||||
setFont(logFont);
|
setFont(logFont);
|
||||||
|
|
||||||
@ -1126,7 +1126,7 @@ PreLaunchInput::PreLaunchInput(QWidget *parent, bool password) : QLineEdit(paren
|
|||||||
|
|
||||||
PreLaunchLog::PreLaunchLog(QWidget *parent) : QTextEdit(parent) {
|
PreLaunchLog::PreLaunchLog(QWidget *parent) : QTextEdit(parent) {
|
||||||
QFont logFont(font());
|
QFont logFont(font());
|
||||||
logFont.setFamily(qsl("Open Sans"));
|
logFont.setFamily(Fonts::GetOverride(qsl("Open Sans")));
|
||||||
logFont.setPixelSize(static_cast<PreLaunchWindow*>(parent)->basicSize());
|
logFont.setPixelSize(static_cast<PreLaunchWindow*>(parent)->basicSize());
|
||||||
setFont(logFont);
|
setFont(logFont);
|
||||||
|
|
||||||
@ -1148,7 +1148,7 @@ PreLaunchButton::PreLaunchButton(QWidget *parent, bool confirm) : QPushButton(pa
|
|||||||
setObjectName(confirm ? "confirm" : "cancel");
|
setObjectName(confirm ? "confirm" : "cancel");
|
||||||
|
|
||||||
QFont closeFont(font());
|
QFont closeFont(font());
|
||||||
closeFont.setFamily(qsl("Open Sans Semibold"));
|
closeFont.setFamily(Fonts::GetOverride(qsl("Open Sans Semibold")));
|
||||||
closeFont.setPixelSize(static_cast<PreLaunchWindow*>(parent)->basicSize());
|
closeFont.setPixelSize(static_cast<PreLaunchWindow*>(parent)->basicSize());
|
||||||
setFont(closeFont);
|
setFont(closeFont);
|
||||||
|
|
||||||
@ -1167,7 +1167,7 @@ PreLaunchCheckbox::PreLaunchCheckbox(QWidget *parent) : QCheckBox(parent) {
|
|||||||
setCheckState(Qt::Checked);
|
setCheckState(Qt::Checked);
|
||||||
|
|
||||||
QFont closeFont(font());
|
QFont closeFont(font());
|
||||||
closeFont.setFamily(qsl("Open Sans Semibold"));
|
closeFont.setFamily(Fonts::GetOverride(qsl("Open Sans Semibold")));
|
||||||
closeFont.setPixelSize(static_cast<PreLaunchWindow*>(parent)->basicSize());
|
closeFont.setPixelSize(static_cast<PreLaunchWindow*>(parent)->basicSize());
|
||||||
setFont(closeFont);
|
setFont(closeFont);
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ Messenger::Messenger() : QObject()
|
|||||||
t_assert(SingleInstance == nullptr);
|
t_assert(SingleInstance == nullptr);
|
||||||
SingleInstance = this;
|
SingleInstance = this;
|
||||||
|
|
||||||
Fonts::start();
|
Fonts::Start();
|
||||||
|
|
||||||
ThirdParty::start();
|
ThirdParty::start();
|
||||||
Global::start();
|
Global::start();
|
||||||
|
@ -56,7 +56,12 @@ int registerFontFamily(const QString &family) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
FontData::FontData(int size, uint32 flags, int family, Font *other) : f(fontFamilies[family]), m(f), _size(size), _flags(flags), _family(family) {
|
FontData::FontData(int size, uint32 flags, int family, Font *other)
|
||||||
|
: f(Fonts::GetOverride(fontFamilies[family]))
|
||||||
|
, m(f)
|
||||||
|
, _size(size)
|
||||||
|
, _flags(flags)
|
||||||
|
, _family(family) {
|
||||||
if (other) {
|
if (other) {
|
||||||
memcpy(modified, other, sizeof(modified));
|
memcpy(modified, other, sizeof(modified));
|
||||||
} else {
|
} else {
|
||||||
|
@ -567,7 +567,7 @@ public:
|
|||||||
|
|
||||||
ch = emojiLookback = 0;
|
ch = emojiLookback = 0;
|
||||||
lastSkipped = false;
|
lastSkipped = false;
|
||||||
checkTilde = !cRetina() && _t->_st->font->size() == 13 && _t->_st->font->flags() == 0; // tilde Open Sans fix
|
checkTilde = !cRetina() && (_t->_st->font->size() == 13) && (_t->_st->font->flags() == 0) && (_t->_st->font->f.family() == qstr("Open Sans")); // tilde Open Sans fix
|
||||||
for (; ptr <= end; ++ptr) {
|
for (; ptr <= end; ++ptr) {
|
||||||
while (checkEntities() || (rich && checkCommand())) {
|
while (checkEntities() || (rich && checkCommand())) {
|
||||||
}
|
}
|
||||||
|
@ -22,16 +22,96 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
|
|
||||||
namespace Fonts {
|
namespace Fonts {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
bool ValidateFont(const QString &familyName, int flags = 0) {
|
||||||
|
QFont checkFont(familyName);
|
||||||
|
checkFont.setPixelSize(13);
|
||||||
|
checkFont.setBold(flags & style::internal::FontBold);
|
||||||
|
checkFont.setItalic(flags & style::internal::FontItalic);
|
||||||
|
checkFont.setUnderline(flags & style::internal::FontUnderline);
|
||||||
|
checkFont.setStyleStrategy(QFont::PreferQuality);
|
||||||
|
auto realFamily = QFontInfo(checkFont).family();
|
||||||
|
if (realFamily.trimmed().compare(familyName, Qt::CaseInsensitive)) {
|
||||||
|
LOG(("Font Error: could not resolve '%1' font, got '%2' after feeding '%3'.").arg(familyName).arg(realFamily));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto metrics = QFontMetrics(checkFont);
|
||||||
|
if (!metrics.height()) {
|
||||||
|
LOG(("Font Error: got a zero height in '%1'.").arg(familyName));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LoadCustomFont(const QString &filePath, const QString &familyName, int flags = 0) {
|
||||||
|
auto regularId = QFontDatabase::addApplicationFont(filePath);
|
||||||
|
if (regularId < 0) {
|
||||||
|
LOG(("Font Error: could not add '%1'.").arg(filePath));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto found = [&familyName, regularId] {
|
||||||
|
for (auto &family : QFontDatabase::applicationFontFamilies(regularId)) {
|
||||||
|
if (!family.trimmed().compare(familyName, Qt::CaseInsensitive)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
if (!found()) {
|
||||||
|
LOG(("Font Error: could not locate '%1' font in '%2'.").arg(familyName).arg(filePath));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ValidateFont(familyName, flags);
|
||||||
|
}
|
||||||
|
|
||||||
bool Started = false;
|
bool Started = false;
|
||||||
void start() {
|
QString OpenSansOverride;
|
||||||
if (!Started) {
|
QString OpenSansSemiboldOverride;
|
||||||
Started = true;
|
|
||||||
|
|
||||||
QFontDatabase::addApplicationFont(qsl(":/gui/fonts/OpenSans-Regular.ttf"));
|
} // namespace
|
||||||
QFontDatabase::addApplicationFont(qsl(":/gui/fonts/OpenSans-Bold.ttf"));
|
|
||||||
QFontDatabase::addApplicationFont(qsl(":/gui/fonts/OpenSans-Semibold.ttf"));
|
void Start() {
|
||||||
|
if (Started) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
Started = true;
|
||||||
|
|
||||||
|
auto regular = LoadCustomFont(qsl(":/gui/fonts/OpenSans-Regular.ttf"), qsl("Open Sans"));
|
||||||
|
auto bold = LoadCustomFont(qsl(":/gui/fonts/OpenSans-Bold.ttf"), qsl("Open Sans"), style::internal::FontBold);
|
||||||
|
auto semibold = LoadCustomFont(qsl(":/gui/fonts/OpenSans-Semibold.ttf"), qsl("Open Sans Semibold"));
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
// Attempt to workaround a strange font bug with Open Sans Semibold not loading.
|
||||||
|
// See https://github.com/telegramdesktop/tdesktop/issues/3276 for details.
|
||||||
|
// Crash happens on "options.maxh / _t->_st->font->height" with "division by zero".
|
||||||
|
// In that place "_t->_st->font" is "semiboldFont" is "font(13 "Open Sans Semibold").
|
||||||
|
if (QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS10) {
|
||||||
|
if (!regular || !bold) {
|
||||||
|
if (ValidateFont(qsl("Segoe UI")) && ValidateFont(qsl("Segoe UI"), style::internal::FontBold)) {
|
||||||
|
OpenSansOverride = qsl("Segoe UI");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!semibold) {
|
||||||
|
if (ValidateFont(qsl("Segoe UI Semibold"))) {
|
||||||
|
OpenSansSemiboldOverride = qsl("Segoe UI Semibold");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // Q_OS_WIN
|
||||||
|
}
|
||||||
|
|
||||||
|
QString GetOverride(const QString &familyName) {
|
||||||
|
if (familyName == qstr("Open Sans")) {
|
||||||
|
return OpenSansOverride.isEmpty() ? familyName : OpenSansOverride;
|
||||||
|
} else if (familyName == qstr("Open Sans Semibold")) {
|
||||||
|
return OpenSansSemiboldOverride.isEmpty() ? familyName : OpenSansSemiboldOverride;
|
||||||
|
}
|
||||||
|
return familyName;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // Fonts
|
} // Fonts
|
||||||
|
@ -21,8 +21,11 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
namespace Fonts {
|
namespace Fonts {
|
||||||
void start();
|
|
||||||
}
|
void Start();
|
||||||
|
QString GetOverride(const QString &familyName);
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
class Painter : public QPainter {
|
class Painter : public QPainter {
|
||||||
public:
|
public:
|
||||||
|
@ -1079,9 +1079,10 @@ struct FormattingAction {
|
|||||||
|
|
||||||
void FlatTextarea::processFormatting(int insertPosition, int insertEnd) {
|
void FlatTextarea::processFormatting(int insertPosition, int insertEnd) {
|
||||||
// Tilde formatting.
|
// Tilde formatting.
|
||||||
auto regularFont = qsl("Open Sans"), semiboldFont = qsl("Open Sans Semibold");
|
auto tildeFormatting = !cRetina() && (font().pixelSize() == 13) && (font().family() == qstr("Open Sans"));
|
||||||
bool tildeFormatting = !cRetina() && (font().pixelSize() == 13) && (font().family() == regularFont);
|
auto isTildeFragment = false;
|
||||||
bool isTildeFragment = false;
|
auto tildeRegularFont = tildeFormatting ? qsl("Open Sans") : QString();
|
||||||
|
auto tildeFixedFont = tildeFormatting ? Fonts::GetOverride(qsl("Open Sans Semibold")) : QString();
|
||||||
|
|
||||||
// First tag handling (the one we inserted text to).
|
// First tag handling (the one we inserted text to).
|
||||||
bool startTagFound = false;
|
bool startTagFound = false;
|
||||||
@ -1118,7 +1119,7 @@ void FlatTextarea::processFormatting(int insertPosition, int insertEnd) {
|
|||||||
|
|
||||||
auto charFormat = fragment.charFormat();
|
auto charFormat = fragment.charFormat();
|
||||||
if (tildeFormatting) {
|
if (tildeFormatting) {
|
||||||
isTildeFragment = (charFormat.fontFamily() == semiboldFont);
|
isTildeFragment = (charFormat.fontFamily() == tildeFixedFont);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto fragmentText = fragment.text();
|
auto fragmentText = fragment.text();
|
||||||
@ -1202,7 +1203,7 @@ void FlatTextarea::processFormatting(int insertPosition, int insertEnd) {
|
|||||||
c.mergeCharFormat(format);
|
c.mergeCharFormat(format);
|
||||||
} else if (action.type == ActionType::TildeFont) {
|
} else if (action.type == ActionType::TildeFont) {
|
||||||
QTextCharFormat format;
|
QTextCharFormat format;
|
||||||
format.setFontFamily(action.isTilde ? semiboldFont : regularFont);
|
format.setFontFamily(action.isTilde ? tildeFixedFont : tildeRegularFont);
|
||||||
c.mergeCharFormat(format);
|
c.mergeCharFormat(format);
|
||||||
insertPosition = action.intervalEnd;
|
insertPosition = action.intervalEnd;
|
||||||
}
|
}
|
||||||
@ -2126,9 +2127,11 @@ void InputArea::processDocumentContentsChange(int position, int charsAdded) {
|
|||||||
int32 replacePosition = -1, replaceLen = 0;
|
int32 replacePosition = -1, replaceLen = 0;
|
||||||
EmojiPtr emoji = nullptr;
|
EmojiPtr emoji = nullptr;
|
||||||
|
|
||||||
static QString regular = qsl("Open Sans"), semibold = qsl("Open Sans Semibold");
|
// Tilde formatting.
|
||||||
bool checkTilde = !cRetina() && (_inner->font().pixelSize() == 13) && (_inner->font().family() == regular);
|
auto tildeFormatting = !cRetina() && (font().pixelSize() == 13) && (font().family() == qstr("Open Sans"));
|
||||||
bool wasTildeFragment = false;
|
auto isTildeFragment = false;
|
||||||
|
auto tildeRegularFont = tildeFormatting ? qsl("Open Sans") : QString();
|
||||||
|
auto tildeFixedFont = tildeFormatting ? Fonts::GetOverride(qsl("Open Sans Semibold")) : QString();
|
||||||
|
|
||||||
QTextDocument *doc(_inner->document());
|
QTextDocument *doc(_inner->document());
|
||||||
QTextCursor c(_inner->textCursor());
|
QTextCursor c(_inner->textCursor());
|
||||||
@ -2148,8 +2151,8 @@ void InputArea::processDocumentContentsChange(int position, int charsAdded) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (checkTilde) {
|
if (tildeFormatting) {
|
||||||
wasTildeFragment = (fragment.charFormat().fontFamily() == semibold);
|
isTildeFragment = (fragment.charFormat().fontFamily() == tildeFixedFont);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString t(fragment.text());
|
QString t(fragment.text());
|
||||||
@ -2167,9 +2170,9 @@ void InputArea::processDocumentContentsChange(int position, int charsAdded) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (checkTilde && fp >= position) { // tilde fix in OpenSans
|
if (tildeFormatting && fp >= position) { // tilde fix in OpenSans
|
||||||
bool tilde = (ch->unicode() == '~');
|
bool tilde = (ch->unicode() == '~');
|
||||||
if ((tilde && !wasTildeFragment) || (!tilde && wasTildeFragment)) {
|
if ((tilde && !isTildeFragment) || (!tilde && isTildeFragment)) {
|
||||||
if (replacePosition < 0) {
|
if (replacePosition < 0) {
|
||||||
replacePosition = fp;
|
replacePosition = fp;
|
||||||
replaceLen = 1;
|
replaceLen = 1;
|
||||||
@ -2201,7 +2204,7 @@ void InputArea::processDocumentContentsChange(int position, int charsAdded) {
|
|||||||
insertEmoji(emoji, c);
|
insertEmoji(emoji, c);
|
||||||
} else {
|
} else {
|
||||||
QTextCharFormat format;
|
QTextCharFormat format;
|
||||||
format.setFontFamily(wasTildeFragment ? regular : semibold);
|
format.setFontFamily(isTildeFragment ? tildeRegularFont : tildeFixedFont);
|
||||||
c.mergeCharFormat(format);
|
c.mergeCharFormat(format);
|
||||||
}
|
}
|
||||||
charsAdded -= replacePosition + replaceLen - position;
|
charsAdded -= replacePosition + replaceLen - position;
|
||||||
@ -2857,9 +2860,11 @@ void InputField::processDocumentContentsChange(int position, int charsAdded) {
|
|||||||
EmojiPtr emoji = nullptr;
|
EmojiPtr emoji = nullptr;
|
||||||
bool newlineFound = false;
|
bool newlineFound = false;
|
||||||
|
|
||||||
static QString regular = qsl("Open Sans"), semibold = qsl("Open Sans Semibold"), space(' ');
|
// Tilde formatting.
|
||||||
bool checkTilde = !cRetina() && (_inner->font().pixelSize() == 13) && (_inner->font().family() == regular);
|
auto tildeFormatting = !cRetina() && (font().pixelSize() == 13) && (font().family() == qstr("Open Sans"));
|
||||||
bool wasTildeFragment = false;
|
auto isTildeFragment = false;
|
||||||
|
auto tildeRegularFont = tildeFormatting ? qsl("Open Sans") : QString();
|
||||||
|
auto tildeFixedFont = tildeFormatting ? Fonts::GetOverride(qsl("Open Sans Semibold")) : QString();
|
||||||
|
|
||||||
QTextDocument *doc(_inner->document());
|
QTextDocument *doc(_inner->document());
|
||||||
QTextCursor c(_inner->textCursor());
|
QTextCursor c(_inner->textCursor());
|
||||||
@ -2879,8 +2884,8 @@ void InputField::processDocumentContentsChange(int position, int charsAdded) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (checkTilde) {
|
if (tildeFormatting) {
|
||||||
wasTildeFragment = (fragment.charFormat().fontFamily() == semibold);
|
isTildeFragment = (fragment.charFormat().fontFamily() == tildeFixedFont);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString t(fragment.text());
|
QString t(fragment.text());
|
||||||
@ -2910,9 +2915,9 @@ void InputField::processDocumentContentsChange(int position, int charsAdded) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (checkTilde && fp >= position) { // tilde fix in OpenSans
|
if (tildeFormatting && fp >= position) { // tilde fix in OpenSans
|
||||||
bool tilde = (ch->unicode() == '~');
|
bool tilde = (ch->unicode() == '~');
|
||||||
if ((tilde && !wasTildeFragment) || (!tilde && wasTildeFragment)) {
|
if ((tilde && !isTildeFragment) || (!tilde && isTildeFragment)) {
|
||||||
if (replacePosition < 0) {
|
if (replacePosition < 0) {
|
||||||
replacePosition = fp;
|
replacePosition = fp;
|
||||||
replaceLen = 1;
|
replaceLen = 1;
|
||||||
@ -2948,14 +2953,14 @@ void InputField::processDocumentContentsChange(int position, int charsAdded) {
|
|||||||
c.setPosition(replacePosition + replaceLen, QTextCursor::KeepAnchor);
|
c.setPosition(replacePosition + replaceLen, QTextCursor::KeepAnchor);
|
||||||
if (newlineFound) {
|
if (newlineFound) {
|
||||||
QTextCharFormat format;
|
QTextCharFormat format;
|
||||||
format.setFontFamily(regular);
|
format.setFontFamily(font().family());
|
||||||
c.mergeCharFormat(format);
|
c.mergeCharFormat(format);
|
||||||
c.insertText(space);
|
c.insertText(" ");
|
||||||
} else if (emoji) {
|
} else if (emoji) {
|
||||||
insertEmoji(emoji, c);
|
insertEmoji(emoji, c);
|
||||||
} else {
|
} else {
|
||||||
QTextCharFormat format;
|
QTextCharFormat format;
|
||||||
format.setFontFamily(wasTildeFragment ? regular : semibold);
|
format.setFontFamily(isTildeFragment ? tildeRegularFont : tildeFixedFont);
|
||||||
c.mergeCharFormat(format);
|
c.mergeCharFormat(format);
|
||||||
}
|
}
|
||||||
charsAdded -= replacePosition + replaceLen - position;
|
charsAdded -= replacePosition + replaceLen - position;
|
||||||
|
Loading…
Reference in New Issue
Block a user