Alpha 0.10.26: t.me links, latest OpenAL code used.

Also inline results should be displayed above the message field.
This commit is contained in:
John Preston 2017-01-07 15:55:05 +04:00
parent 1a16df4037
commit 143181095f
34 changed files with 250 additions and 113 deletions

View File

@ -1,22 +1,22 @@
diff --git a/Alc/backends/winmm.c b/Alc/backends/winmm.c diff --git a/Alc/backends/winmm.c b/Alc/backends/winmm.c
index bf97ef2..1cd5774 100644 index 9d8f8e9..8c8e44a 100644
--- a/Alc/backends/winmm.c --- a/Alc/backends/winmm.c
+++ b/Alc/backends/winmm.c +++ b/Alc/backends/winmm.c
@@ -221,7 +221,7 @@ FORCE_ALIGN static int ALCwinmmPlayback_mixerProc(void *arg) @@ -219,7 +219,7 @@ FORCE_ALIGN static int ALCwinmmPlayback_mixerProc(void *arg)
SetRTPriority(); SetRTPriority();
althrd_setname(althrd_current(), MIXER_THREAD_NAME); althrd_setname(althrd_current(), MIXER_THREAD_NAME);
- while(GetMessage(&msg, NULL, 0, 0)) - while(GetMessage(&msg, NULL, 0, 0))
+ if (!self->killNow) while(GetMessage(&msg, NULL, 0, 0)) + if (!self->killNow) while(GetMessage(&msg, NULL, 0, 0))
{ {
if(msg.message != WOM_DONE) if(msg.message != WOM_DONE)
continue; continue;
@@ -506,7 +506,7 @@ static int ALCwinmmCapture_captureProc(void *arg) @@ -504,7 +504,7 @@ static int ALCwinmmCapture_captureProc(void *arg)
althrd_setname(althrd_current(), RECORD_THREAD_NAME); althrd_setname(althrd_current(), RECORD_THREAD_NAME);
- while(GetMessage(&msg, NULL, 0, 0)) - while(GetMessage(&msg, NULL, 0, 0))
+ if (!self->killNow) while(GetMessage(&msg, NULL, 0, 0)) + if (!self->killNow) while(GetMessage(&msg, NULL, 0, 0))
{ {
if(msg.message != WIM_DATA) if(msg.message != WIM_DATA)
continue; continue;

View File

@ -34,8 +34,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico"
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,10,25,0 FILEVERSION 0,10,26,0
PRODUCTVERSION 0,10,25,0 PRODUCTVERSION 0,10,26,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -51,10 +51,10 @@ BEGIN
BLOCK "040904b0" BLOCK "040904b0"
BEGIN BEGIN
VALUE "CompanyName", "Telegram Messenger LLP" VALUE "CompanyName", "Telegram Messenger LLP"
VALUE "FileVersion", "0.10.25.0" VALUE "FileVersion", "0.10.26.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2016" VALUE "LegalCopyright", "Copyright (C) 2014-2016"
VALUE "ProductName", "Telegram Desktop" VALUE "ProductName", "Telegram Desktop"
VALUE "ProductVersion", "0.10.25.0" VALUE "ProductVersion", "0.10.26.0"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View File

@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,10,25,0 FILEVERSION 0,10,26,0
PRODUCTVERSION 0,10,25,0 PRODUCTVERSION 0,10,26,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -43,10 +43,10 @@ BEGIN
BEGIN BEGIN
VALUE "CompanyName", "Telegram Messenger LLP" VALUE "CompanyName", "Telegram Messenger LLP"
VALUE "FileDescription", "Telegram Updater" VALUE "FileDescription", "Telegram Updater"
VALUE "FileVersion", "0.10.25.0" VALUE "FileVersion", "0.10.26.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2016" VALUE "LegalCopyright", "Copyright (C) 2014-2016"
VALUE "ProductName", "Telegram Desktop" VALUE "ProductName", "Telegram Desktop"
VALUE "ProductVersion", "0.10.25.0" VALUE "ProductVersion", "0.10.26.0"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View File

@ -1069,8 +1069,8 @@ void AppClass::checkMapVersion() {
if (Local::oldMapVersion() < AppVersion) { if (Local::oldMapVersion() < AppVersion) {
if (Local::oldMapVersion()) { if (Local::oldMapVersion()) {
QString versionFeatures; QString versionFeatures;
if ((cAlphaVersion() || cBetaVersion()) && Local::oldMapVersion() < 10021) { if ((cAlphaVersion() || cBetaVersion()) && Local::oldMapVersion() < 10026) {
versionFeatures = QString::fromUtf8("\xe2\x80\x94 Fabulous new material-style design and animations.\n\xe2\x80\x94 This version already supports custom themes that are coming soon.\n\xe2\x80\x94 Pin important chats to the top of the list so that you never miss a new message (right click on a chat, then choose 'Pin to top').\n\xe2\x80\x94 Groups in common. A new option in your contacts' profiles that shows a list of all groups you share with that person."); versionFeatures = QString::fromUtf8("\xe2\x80\x94 You can use t.me instead of telegram.me\n\xe2\x80\x94 OpenAL updated to the latest version\n\xe2\x80\x94 Bug fixes and other minor improvements");
} else if (!(cAlphaVersion() || cBetaVersion()) && Local::oldMapVersion() < 10018) { } else if (!(cAlphaVersion() || cBetaVersion()) && Local::oldMapVersion() < 10018) {
versionFeatures = langNewVersionText(); versionFeatures = langNewVersionText();
} else { } else {

View File

@ -1173,7 +1173,7 @@ void RevokePublicLinkBox::mouseReleaseEvent(QMouseEvent *e) {
setCursor((_selected || _pressed) ? style::cur_pointer : style::cur_default); setCursor((_selected || _pressed) ? style::cur_pointer : style::cur_default);
if (pressed && pressed == _selected) { if (pressed && pressed == _selected) {
auto text_method = pressed->isMegagroup() ? lng_channels_too_much_public_revoke_confirm_group : lng_channels_too_much_public_revoke_confirm_channel; auto text_method = pressed->isMegagroup() ? lng_channels_too_much_public_revoke_confirm_group : lng_channels_too_much_public_revoke_confirm_channel;
auto text = text_method(lt_link, qsl("telegram.me/") + pressed->userName(), lt_group, pressed->name); auto text = text_method(lt_link, CreateInternalLink(pressed->userName()), lt_group, pressed->name);
auto confirmText = lang(lng_channels_too_much_public_revoke); auto confirmText = lang(lng_channels_too_much_public_revoke);
_weakRevokeConfirmBox = Ui::show(Box<ConfirmBox>(text, confirmText, base::lambda_guarded(this, [this, pressed]() { _weakRevokeConfirmBox = Ui::show(Box<ConfirmBox>(text, confirmText, base::lambda_guarded(this, [this, pressed]() {
if (_revokeRequestId) return; if (_revokeRequestId) return;
@ -1233,7 +1233,7 @@ void RevokePublicLinkBox::getPublicDone(const MTPmessages_Chats &result) {
ChatRow row; ChatRow row;
row.peer = peer; row.peer = peer;
row.name.setText(st::contactsNameStyle, peer->name, _textNameOptions); row.name.setText(st::contactsNameStyle, peer->name, _textNameOptions);
row.status.setText(st::defaultTextStyle, qsl("telegram.me/") + textcmdLink(1, peer->userName()), _textDlgOptions); row.status.setText(st::defaultTextStyle, CreateInternalLink(textcmdLink(1, peer->userName())), _textDlgOptions);
_rows.push_back(std_::move(row)); _rows.push_back(std_::move(row));
} }
} }

View File

@ -45,7 +45,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "apiwrap.h" #include "apiwrap.h"
QString PeerFloodErrorText(PeerFloodType type) { QString PeerFloodErrorText(PeerFloodType type) {
auto link = textcmdLink(qsl("https://telegram.me/spambot"), lang(lng_cant_more_info)); auto link = textcmdLink(CreateInternalLinkHttps(qsl("spambot")), lang(lng_cant_more_info));
if (type == PeerFloodType::InviteGroup) { if (type == PeerFloodType::InviteGroup) {
return lng_cant_invite_not_contact(lt_more_info, link); return lng_cant_invite_not_contact(lt_more_info, link);
} }

View File

@ -870,7 +870,7 @@ void shareGameScoreFromItem(HistoryItem *item) {
if (media->type() == MediaTypeGame) { if (media->type() == MediaTypeGame) {
auto shortName = static_cast<HistoryGame*>(media)->game()->shortName; auto shortName = static_cast<HistoryGame*>(media)->game()->shortName;
QApplication::clipboard()->setText(qsl("https://telegram.me/") + bot->username + qsl("?game=") + shortName); QApplication::clipboard()->setText(CreateInternalLinkHttps(bot->username + qsl("?game=") + shortName));
Ui::Toast::Config toast; Ui::Toast::Config toast;
toast.text = lang(lng_share_game_link_copied); toast.text = lang(lng_share_game_link_copied);

View File

@ -68,7 +68,7 @@ void StickerSetBox::onAddStickers() {
} }
void StickerSetBox::onShareStickers() { void StickerSetBox::onShareStickers() {
QString url = qsl("https://telegram.me/addstickers/") + _inner->shortName(); auto url = CreateInternalLinkHttps(qsl("addstickers/") + _inner->shortName());
QApplication::clipboard()->setText(url); QApplication::clipboard()->setText(url);
Ui::show(Box<InformBox>(lang(lng_stickers_copied))); Ui::show(Box<InformBox>(lang(lng_stickers_copied)));
} }

View File

@ -86,7 +86,7 @@ void UsernameBox::paintEvent(QPaintEvent *e) {
if (_link->isHidden()) { if (_link->isHidden()) {
p.drawTextLeft(st::usernamePadding.left(), linky, width(), lang(lng_username_link_willbe)); p.drawTextLeft(st::usernamePadding.left(), linky, width(), lang(lng_username_link_willbe));
p.setPen(st::usernameDefaultFg); p.setPen(st::usernameDefaultFg);
p.drawTextLeft(st::usernamePadding.left(), linky + st::usernameTextStyle.lineHeight + ((st::usernameTextStyle.lineHeight - st::boxTextFont->height) / 2), width(), qsl("https://telegram.me/username")); p.drawTextLeft(st::usernamePadding.left(), linky + st::usernameTextStyle.lineHeight + ((st::usernameTextStyle.lineHeight - st::boxTextFont->height) / 2), width(), CreateInternalLinkHttps(qsl("username")));
} else { } else {
p.drawTextLeft(st::usernamePadding.left(), linky, width(), lang(lng_username_link)); p.drawTextLeft(st::usernamePadding.left(), linky, width(), lang(lng_username_link));
} }
@ -160,7 +160,7 @@ void UsernameBox::onChanged() {
} }
void UsernameBox::onLinkClick() { void UsernameBox::onLinkClick() {
Application::clipboard()->setText(qsl("https://telegram.me/") + getName()); Application::clipboard()->setText(CreateInternalLinkHttps(getName()));
Ui::Toast::Config toast; Ui::Toast::Config toast;
toast.text = lang(lng_username_copied); toast.text = lang(lng_username_copied);
@ -234,7 +234,7 @@ QString UsernameBox::getName() const {
void UsernameBox::updateLinkText() { void UsernameBox::updateLinkText() {
QString uname = getName(); QString uname = getName();
_link->setText(st::boxTextFont->elided(qsl("https://telegram.me/") + uname, st::boxWidth - st::usernamePadding.left() - st::usernamePadding.right())); _link->setText(st::boxTextFont->elided(CreateInternalLinkHttps(uname), st::boxWidth - st::usernamePadding.left() - st::usernamePadding.right()));
if (uname.isEmpty()) { if (uname.isEmpty()) {
if (!_link->isHidden()) { if (!_link->isHidden()) {
_link->hide(); _link->hide();

View File

@ -322,6 +322,16 @@ inline QString cApiAppVersion() {
return QString::number(AppVersion); return QString::number(AppVersion);
} }
constexpr str_const AppLinksDomain = "t.me";
inline QString CreateInternalLink(const QString &query) {
return str_const_toString(AppLinksDomain) + '/' + query;
}
inline QString CreateInternalLinkHttps(const QString &query) {
return qsl("https://") + CreateInternalLink(query);
}
extern QString gKeyFile; extern QString gKeyFile;
inline const QString &cDataFile() { inline const QString &cDataFile() {
if (!gKeyFile.isEmpty()) return gKeyFile; if (!gKeyFile.isEmpty()) return gKeyFile;

View File

@ -40,12 +40,9 @@ QString tryConvertUrlToLocal(QString url) {
using namespace qthelp; using namespace qthelp;
auto matchOptions = RegExOption::CaseInsensitive; auto matchOptions = RegExOption::CaseInsensitive;
auto telegramMeMatch = regex_match(qsl("https?://(www\\.)?telegram\\.me/(.+)$"), url, matchOptions); auto telegramMeMatch = regex_match(qsl("https?://(www\\.)?(telegram|t)\\.me/(.+)$"), url, matchOptions);
if (!telegramMeMatch) {
telegramMeMatch = regex_match(qsl("https?://(www\\.)?t\\.me/(.+)$"), url, matchOptions);
}
if (telegramMeMatch) { if (telegramMeMatch) {
auto query = telegramMeMatch->capturedRef(2); auto query = telegramMeMatch->capturedRef(3);
if (auto joinChatMatch = regex_match(qsl("^joinchat/([a-zA-Z0-9\\.\\_\\-]+)(\\?|$)"), query, matchOptions)) { if (auto joinChatMatch = regex_match(qsl("^joinchat/([a-zA-Z0-9\\.\\_\\-]+)(\\?|$)"), query, matchOptions)) {
return qsl("tg://join?invite=") + url_encode(joinChatMatch->captured(1)); return qsl("tg://join?invite=") + url_encode(joinChatMatch->captured(1));
} else if (auto stickerSetMatch = regex_match(qsl("^addstickers/([a-zA-Z0-9\\.\\_]+)(\\?|$)"), query, matchOptions)) { } else if (auto stickerSetMatch = regex_match(qsl("^addstickers/([a-zA-Z0-9\\.\\_]+)(\\?|$)"), query, matchOptions)) {

View File

@ -24,7 +24,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#define BETA_VERSION_MACRO (0ULL) #define BETA_VERSION_MACRO (0ULL)
constexpr int AppVersion = 10025; constexpr int AppVersion = 10026;
constexpr str_const AppVersionStr = "0.10.25"; constexpr str_const AppVersionStr = "0.10.26";
constexpr bool AppAlphaVersion = true; constexpr bool AppAlphaVersion = true;
constexpr uint64 AppBetaVersion = BETA_VERSION_MACRO; constexpr uint64 AppBetaVersion = BETA_VERSION_MACRO;

View File

@ -192,9 +192,9 @@ void activateClickHandler(ClickHandlerPtr handler, Qt::MouseButton button) {
} }
void logOutDelayed() { void logOutDelayed() {
if (auto w = App::wnd()) { App::CallDelayed(1, App::app(), [] {
QMetaObject::invokeMethod(w, "onLogoutSure", Qt::QueuedConnection); App::logOut();
} });
} }
} // namespace App } // namespace App

View File

@ -41,7 +41,7 @@ public:
using Map = QHash<PeerId, History*>; using Map = QHash<PeerId, History*>;
Map map; Map map;
Histories() : _a_typings(animation(this, &Histories::step_typings)), _unreadFull(0), _unreadMuted(0) { Histories() : _a_typings(animation(this, &Histories::step_typings)) {
} }
void regSendAction(History *history, UserData *user, const MTPSendMessageAction &action, TimeId when); void regSendAction(History *history, UserData *user, const MTPSendMessageAction &action, TimeId when);
@ -53,9 +53,6 @@ public:
void clear(); void clear();
void remove(const PeerId &peer); void remove(const PeerId &peer);
~Histories() {
_unreadFull = _unreadMuted = 0;
}
HistoryItem *addNewMessage(const MTPMessage &msg, NewMessageType type); HistoryItem *addNewMessage(const MTPMessage &msg, NewMessageType type);

View File

@ -716,7 +716,7 @@ public:
return id > 0 && _history->peer->isChannel() && _history->peer->asChannel()->isPublic() && !_history->peer->isMegagroup(); return id > 0 && _history->peer->isChannel() && _history->peer->asChannel()->isPublic() && !_history->peer->isMegagroup();
} }
QString directLink() const { QString directLink() const {
return hasDirectLink() ? qsl("https://telegram.me/") + _history->peer->asChannel()->username + '/' + QString::number(id) : QString(); return hasDirectLink() ? CreateInternalLinkHttps(_history->peer->asChannel()->username + '/' + QString::number(id)) : QString();
} }
int32 y; int32 y;

View File

@ -6389,7 +6389,7 @@ void HistoryWidget::moveFieldControls() {
_silent->moveToRight(right, buttonsBottom); _silent->moveToRight(right, buttonsBottom);
_fieldBarCancel->moveToRight(0, _field->y() - st::historySendPadding - _fieldBarCancel->height()); _fieldBarCancel->moveToRight(0, _field->y() - st::historySendPadding - _fieldBarCancel->height());
_emojiPan->moveBottom(_attachEmoji->y()); _emojiPan->moveBottom(_field->y() - st::historySendPadding);
auto fullWidthButtonRect = QRect(0, bottom - _botStart->height(), width(), _botStart->height()); auto fullWidthButtonRect = QRect(0, bottom - _botStart->height(), width(), _botStart->height());
_botStart->setGeometry(fullWidthButtonRect); _botStart->setGeometry(fullWidthButtonRect);
@ -7098,7 +7098,8 @@ void HistoryWidget::updateControlsGeometry() {
updateHistoryDownPosition(); updateHistoryDownPosition();
_emojiPan->setMaxHeight(height() - _attachEmoji->height()); _emojiPan->setMinTop(0);
_emojiPan->setMinBottom(_attachEmoji->height());
if (_membersDropdown) { if (_membersDropdown) {
_membersDropdown->setMaxHeight(countMembersDropdownHeightMax()); _membersDropdown->setMaxHeight(countMembersDropdownHeightMax());
} }

View File

@ -2548,13 +2548,14 @@ void MainWidget::showWideSectionAnimated(const Window::SectionMemento *memento,
_wideSection = std_::move(newWideSection); _wideSection = std_::move(newWideSection);
_topBar->hide(); _topBar->hide();
resizeEvent(0); resizeEvent(0);
auto direction = back ? Window::SlideDirection::FromLeft : Window::SlideDirection::FromRight;
_wideSection->showAnimated(direction, animationParams);
_history->finishAnimation(); _history->finishAnimation();
_history->showHistory(0, 0); _history->showHistory(0, 0);
_history->hide(); _history->hide();
if (Adaptive::OneColumn()) _dialogs->hide(); if (Adaptive::OneColumn()) _dialogs->hide();
auto direction = back ? Window::SlideDirection::FromLeft : Window::SlideDirection::FromRight;
_wideSection->showAnimated(direction, animationParams);
orderWidgets(); orderWidgets();
} }

View File

@ -266,6 +266,10 @@ void finish() {
class Manager::Impl { class Manager::Impl {
public: public:
using Type = Window::Notifications::CachedUserpics::Type;
Impl(Type type) : _cachedUserpics(type) {
}
bool init(); bool init();
void showNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, const QString &msg, bool hideNameAndPhoto, bool hideReplyButton); void showNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, const QString &msg, bool hideNameAndPhoto, bool hideReplyButton);
@ -480,7 +484,7 @@ void Manager::Impl::clearNotification(PeerId peerId, MsgId msgId) {
showNextNotification(); showNextNotification();
} }
Manager::Manager() : _impl(std_::make_unique<Impl>()) { Manager::Manager() : _impl(std_::make_unique<Impl>(Impl::Type::Rounded)) {
} }
bool Manager::init() { bool Manager::init() {

View File

@ -338,6 +338,11 @@ void finish() {
class Manager::Impl { class Manager::Impl {
public: public:
using Type = Window::Notifications::CachedUserpics::Type;
Impl(Type type) : _cachedUserpics(type) {
}
bool showNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, const QString &msg, bool hideNameAndPhoto, bool hideReplyButton); bool showNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, const QString &msg, bool hideNameAndPhoto, bool hideReplyButton);
void clearAll(); void clearAll();
void clearFromHistory(History *history); void clearFromHistory(History *history);
@ -506,7 +511,7 @@ bool Manager::Impl::showNotification(PeerData *peer, MsgId msgId, const QString
return true; return true;
} }
Manager::Manager() : _impl(std_::make_unique<Impl>()) { Manager::Manager() : _impl(std_::make_unique<Impl>(Impl::Type::Rounded)) {
} }
void Manager::clearNotification(PeerId peerId, MsgId msgId) { void Manager::clearNotification(PeerId peerId, MsgId msgId) {

View File

@ -192,10 +192,10 @@ void InfoWidget::refreshChannelLink() {
TextWithEntities channelLinkTextShort; TextWithEntities channelLinkTextShort;
if (auto channel = peer()->asChannel()) { if (auto channel = peer()->asChannel()) {
if (!channel->username.isEmpty()) { if (!channel->username.isEmpty()) {
channelLinkText.text = qsl("https://telegram.me/") + channel->username; channelLinkText.text = CreateInternalLinkHttps(channel->username);
channelLinkText.entities.push_back(EntityInText(EntityInTextUrl, 0, channelLinkText.text.size())); channelLinkText.entities.push_back(EntityInText(EntityInTextUrl, 0, channelLinkText.text.size()));
channelLinkTextShort.text = qsl("telegram.me/") + channel->username; channelLinkTextShort.text = CreateInternalLink(channel->username);
channelLinkTextShort.entities.push_back(EntityInText(EntityInTextCustomUrl, 0, channelLinkTextShort.text.size(), qsl("https://telegram.me/") + channel->username)); channelLinkTextShort.entities.push_back(EntityInText(EntityInTextCustomUrl, 0, channelLinkTextShort.text.size(), CreateInternalLinkHttps(channel->username)));
} }
} }
setLabeledText(nullptr, lang(lng_profile_link), &_channelLink, channelLinkText, QString()); setLabeledText(nullptr, lang(lng_profile_link), &_channelLink, channelLinkText, QString());

View File

@ -249,7 +249,9 @@ void InnerWidget::paintRow(Painter &p, int index, TimeMs ms) {
} }
void InnerWidget::keyPressEvent(QKeyEvent *e) { void InnerWidget::keyPressEvent(QKeyEvent *e) {
if (e->key() == Qt::Key_Escape) {
emit cancelled();
}
} }
void InnerWidget::updateSelected(QPoint localPos) { void InnerWidget::updateSelected(QPoint localPos) {

View File

@ -80,7 +80,7 @@ void InfoWidget::refreshUsername() {
usernameText.text = '@' + self()->username; usernameText.text = '@' + self()->username;
copyText = lang(lng_context_copy_mention); copyText = lang(lng_context_copy_mention);
} }
usernameText.entities.push_back(EntityInText(EntityInTextCustomUrl, 0, usernameText.text.size(), qsl("https://telegram.me/") + self()->username)); usernameText.entities.push_back(EntityInText(EntityInTextCustomUrl, 0, usernameText.text.size(), CreateInternalLinkHttps(self()->username)));
setLabeledText(_username, lang(lng_profile_username), usernameText, TextWithEntities(), copyText); setLabeledText(_username, lang(lng_profile_username), usernameText, TextWithEntities(), copyText);
if (auto text = _username->entity()->textLabel()) { if (auto text = _username->entity()->textLabel()) {
text->setClickHandlerHook([](const ClickHandlerPtr &handler, Qt::MouseButton button) { text->setClickHandlerHook([](const ClickHandlerPtr &handler, Qt::MouseButton button) {
@ -94,10 +94,10 @@ void InfoWidget::refreshLink() {
TextWithEntities linkText; TextWithEntities linkText;
TextWithEntities linkTextShort; TextWithEntities linkTextShort;
if (!self()->username.isEmpty()) { if (!self()->username.isEmpty()) {
linkText.text = qsl("https://telegram.me/") + self()->username; linkText.text = CreateInternalLinkHttps(self()->username);
linkText.entities.push_back(EntityInText(EntityInTextUrl, 0, linkText.text.size())); linkText.entities.push_back(EntityInText(EntityInTextUrl, 0, linkText.text.size()));
linkTextShort.text = qsl("telegram.me/") + self()->username; linkTextShort.text = CreateInternalLink(self()->username);
linkTextShort.entities.push_back(EntityInText(EntityInTextCustomUrl, 0, linkTextShort.text.size(), qsl("https://telegram.me/") + self()->username)); linkTextShort.entities.push_back(EntityInText(EntityInTextCustomUrl, 0, linkTextShort.text.size(), CreateInternalLinkHttps(self()->username)));
} }
setLabeledText(_link, lang(lng_profile_link), linkText, linkTextShort, QString()); setLabeledText(_link, lang(lng_profile_link), linkText, linkTextShort, QString());
if (auto text = _link->entity()->textLabel()) { if (auto text = _link->entity()->textLabel()) {

View File

@ -247,7 +247,7 @@ void EmojiColorPicker::drawVariant(Painter &p, int variant) {
} }
EmojiPanInner::EmojiPanInner(QWidget *parent) : TWidget(parent) EmojiPanInner::EmojiPanInner(QWidget *parent) : TWidget(parent)
, _maxHeight(int(st::emojiPanMaxHeight) - st::emojiCategory.height) , _maxHeight(st::emojiPanMaxHeight - st::emojiCategory.height)
, _picker(this) { , _picker(this) {
resize(st::emojiPanWidth - st::emojiScroll.width - st::buttonRadius, countHeight()); resize(st::emojiPanWidth - st::emojiScroll.width - st::buttonRadius, countHeight());
@ -774,7 +774,8 @@ int StickerPanInner::featuredRowHeight() const {
} }
int StickerPanInner::countHeight(bool plain) { int StickerPanInner::countHeight(bool plain) {
int result = 0, minLastH = plain ? 0 : (_maxHeight - st::stickerPanPadding); auto result = 0;
auto minLastH = plain ? 0 : (_maxHeight - st::stickerPanPadding);
if (showingInlineItems()) { if (showingInlineItems()) {
result = st::emojiPanHeader; result = st::emojiPanHeader;
if (_switchPmButton) { if (_switchPmButton) {
@ -787,10 +788,13 @@ int StickerPanInner::countHeight(bool plain) {
result = st::emojiPanHeader + shownSets().size() * featuredRowHeight(); result = st::emojiPanHeader + shownSets().size() * featuredRowHeight();
} else { } else {
auto &sets = shownSets(); auto &sets = shownSets();
for (int i = 0; i < sets.size(); ++i) { for (auto i = 0; i != sets.size(); ++i) {
int cnt = sets[i].pack.size(), rows = (cnt / StickerPanPerRow) + ((cnt % StickerPanPerRow) ? 1 : 0); auto cnt = sets[i].pack.size();
int h = st::emojiPanHeader + rows * st::stickerPanSize.height(); auto rows = (cnt / StickerPanPerRow) + ((cnt % StickerPanPerRow) ? 1 : 0);
if (i == sets.size() - 1 && h < minLastH) h = minLastH; auto h = st::emojiPanHeader + rows * st::stickerPanSize.height();
if (i == sets.size() - 1 && h < minLastH) {
h = minLastH;
}
result += h; result += h;
} }
} }
@ -861,7 +865,7 @@ void StickerPanInner::paintEvent(QPaintEvent *e) {
} }
void StickerPanInner::paintInlineItems(Painter &p, const QRect &r) { void StickerPanInner::paintInlineItems(Painter &p, const QRect &r) {
if (_inlineRows.isEmpty()) { if (_inlineRows.isEmpty() && !_switchPmButton) {
p.setFont(st::normalFont); p.setFont(st::normalFont);
p.setPen(st::noContactsColor); p.setPen(st::noContactsColor);
p.drawText(QRect(0, 0, width(), (height() / 3) * 2 + st::normalFont->height), lang(lng_inline_bot_no_results), style::al_center); p.drawText(QRect(0, 0, width(), (height() / 3) * 2 + st::normalFont->height), lang(lng_inline_bot_no_results), style::al_center);
@ -870,23 +874,24 @@ void StickerPanInner::paintInlineItems(Painter &p, const QRect &r) {
auto gifPaused = Ui::isLayerShown() || Ui::isMediaViewShown() || _previewShown || !App::wnd()->isActive(); auto gifPaused = Ui::isLayerShown() || Ui::isMediaViewShown() || _previewShown || !App::wnd()->isActive();
InlineBots::Layout::PaintContext context(getms(), false, gifPaused, false); InlineBots::Layout::PaintContext context(getms(), false, gifPaused, false);
int top = st::emojiPanHeader; auto top = st::emojiPanHeader;
if (_switchPmButton) { if (_switchPmButton) {
top += _switchPmButton->height() + st::inlineResultsSkip; top += _switchPmButton->height() + st::inlineResultsSkip;
} }
int fromx = rtl() ? (width() - r.x() - r.width()) : r.x(), tox = rtl() ? (width() - r.x()) : (r.x() + r.width()); auto fromx = rtl() ? (width() - r.x() - r.width()) : r.x();
for (int row = 0, rows = _inlineRows.size(); row < rows; ++row) { auto tox = rtl() ? (width() - r.x()) : (r.x() + r.width());
for (auto row = 0, rows = _inlineRows.size(); row != rows; ++row) {
auto &inlineRow = _inlineRows[row]; auto &inlineRow = _inlineRows[row];
if (top >= r.top() + r.height()) break; if (top >= r.top() + r.height()) break;
if (top + inlineRow.height > r.top()) { if (top + inlineRow.height > r.top()) {
int left = st::inlineResultsLeft - st::buttonRadius; auto left = st::inlineResultsLeft - st::buttonRadius;
if (row == rows - 1) context.lastRow = true; if (row == rows - 1) context.lastRow = true;
for (int col = 0, cols = inlineRow.items.size(); col < cols; ++col) { for (int col = 0, cols = inlineRow.items.size(); col < cols; ++col) {
if (left >= tox) break; if (left >= tox) break;
const InlineItem *item = inlineRow.items.at(col); auto item = inlineRow.items.at(col);
int w = item->width(); auto w = item->width();
if (left + w > fromx) { if (left + w > fromx) {
p.translate(left, top); p.translate(left, top);
item->paint(p, r.translated(-left, -top), &context); item->paint(p, r.translated(-left, -top), &context);
@ -1622,12 +1627,13 @@ void StickerPanInner::refreshSwitchPmButton(const InlineCacheEntry *entry) {
if (!_switchPmButton) { if (!_switchPmButton) {
_switchPmButton.create(this, QString(), st::switchPmButton); _switchPmButton.create(this, QString(), st::switchPmButton);
_switchPmButton->show(); _switchPmButton->show();
_switchPmButton->move(st::inlineResultsLeft - st::buttonRadius, st::emojiPanHeader);
_switchPmButton->setTextTransform(Ui::RoundButton::TextTransform::NoTransform); _switchPmButton->setTextTransform(Ui::RoundButton::TextTransform::NoTransform);
connect(_switchPmButton, SIGNAL(clicked()), this, SLOT(onSwitchPm())); connect(_switchPmButton, SIGNAL(clicked()), this, SLOT(onSwitchPm()));
} }
_switchPmButton->setText(entry->switchPmText); // doesn't perform text.toUpper() _switchPmButton->setText(entry->switchPmText); // doesn't perform text.toUpper()
_switchPmStartToken = entry->switchPmStartToken; _switchPmStartToken = entry->switchPmStartToken;
auto buttonTop = entry->results.isEmpty() ? (2 * st::emojiPanHeader) : st::emojiPanHeader;
_switchPmButton->move(st::inlineResultsLeft - st::buttonRadius, buttonTop);
} }
update(); update();
} }
@ -2643,7 +2649,6 @@ void EmojiPan::SlideAnimation::paintFrame(QPainter &p, float64 dt, float64 opaci
} }
EmojiPan::EmojiPan(QWidget *parent) : TWidget(parent) EmojiPan::EmojiPan(QWidget *parent) : TWidget(parent)
, _maxHeight(st::emojiPanMaxHeight)
, _contentMaxHeight(st::emojiPanMaxHeight) , _contentMaxHeight(st::emojiPanMaxHeight)
, _contentHeight(_contentMaxHeight) , _contentHeight(_contentMaxHeight)
, _contentHeightEmoji(_contentHeight - st::emojiCategory.height) , _contentHeightEmoji(_contentHeight - st::emojiCategory.height)
@ -2664,7 +2669,6 @@ EmojiPan::EmojiPan(QWidget *parent) : TWidget(parent)
resize(QRect(0, 0, st::emojiPanWidth, _contentHeight).marginsAdded(innerPadding()).size()); resize(QRect(0, 0, st::emojiPanWidth, _contentHeight).marginsAdded(innerPadding()).size());
_width = width(); _width = width();
_height = height(); _height = height();
_bottom = 0;
e_scroll->resize(st::emojiPanWidth - st::buttonRadius, _contentHeightEmoji); e_scroll->resize(st::emojiPanWidth - st::buttonRadius, _contentHeightEmoji);
s_scroll->resize(st::emojiPanWidth - st::buttonRadius, _contentHeightStickers); s_scroll->resize(st::emojiPanWidth - st::buttonRadius, _contentHeightStickers);
@ -2741,25 +2745,45 @@ EmojiPan::EmojiPan(QWidget *parent) : TWidget(parent)
setAttribute(Qt::WA_OpaquePaintEvent, false); setAttribute(Qt::WA_OpaquePaintEvent, false);
} }
void EmojiPan::setMaxHeight(int maxHeight) { void EmojiPan::setMinTop(int minTop) {
_maxHeight = maxHeight - st::emojiPanMargins.top() - st::emojiPanMargins.bottom(); _minTop = minTop;
updateContentHeight();
}
void EmojiPan::setMinBottom(int minBottom) {
_minBottom = minBottom;
updateContentHeight();
}
void EmojiPan::moveBottom(int bottom) {
_bottom = bottom;
updateContentHeight(); updateContentHeight();
} }
void EmojiPan::updateContentHeight() { void EmojiPan::updateContentHeight() {
int32 h = qMin(_contentMaxHeight, _maxHeight); auto wantedBottom = countBottom();
int32 he = h - st::emojiCategory.height; auto maxContentHeight = wantedBottom - st::emojiPanMargins.top() - st::emojiPanMargins.bottom();
int32 hs = h - (s_inner->showSectionIcons() ? st::emojiCategory.height : 0); auto contentHeight = qMin(_contentMaxHeight, maxContentHeight);
if (h == _contentHeight && he == _contentHeightEmoji && hs == _contentHeightStickers) return; accumulate_max(contentHeight, st::emojiPanMinHeight);
auto resultTop = wantedBottom - st::emojiPanMargins.bottom() - contentHeight - st::emojiPanMargins.top();
accumulate_max(resultTop, _minTop);
auto he = contentHeight - st::emojiCategory.height;
auto hs = contentHeight - (s_inner->showSectionIcons() ? st::emojiCategory.height : 0);
if (contentHeight == _contentHeight && he == _contentHeightEmoji && hs == _contentHeightStickers) {
move(x(), resultTop);
return;
}
int32 was = _contentHeight, wase = _contentHeightEmoji, wass = _contentHeightStickers; auto was = _contentHeight;
_contentHeight = h; auto wase = _contentHeightEmoji;
auto wass = _contentHeightStickers;
_contentHeight = contentHeight;
_contentHeightEmoji = he; _contentHeightEmoji = he;
_contentHeightStickers = hs; _contentHeightStickers = hs;
resize(QRect(0, 0, innerRect().width(), _contentHeight).marginsAdded(innerPadding()).size()); resize(QRect(0, 0, innerRect().width(), _contentHeight).marginsAdded(innerPadding()).size());
_height = height(); _height = height();
move(x(), _bottom - _height); move(x(), resultTop);
if (was > _contentHeight || (was == _contentHeight && wass > _contentHeightStickers)) { if (was > _contentHeight || (was == _contentHeight && wass > _contentHeightStickers)) {
e_scroll->resize(e_scroll->width(), _contentHeightEmoji); e_scroll->resize(e_scroll->width(), _contentHeightEmoji);
@ -2948,18 +2972,21 @@ void EmojiPan::paintContent(Painter &p) {
} }
} }
void EmojiPan::moveBottom(int bottom, bool force) { bool EmojiPan::inlineResultsShown() const {
_bottom = bottom; return !_emojiShown && s_inner->inlineResultsShown();
if (isHidden() && !force) { }
move(x(), _bottom - height());
return; int EmojiPan::countBottom() const {
} return (_origin == Ui::PanelAnimation::Origin::BottomLeft) ? _bottom : (parentWidget()->height() - _minBottom);
if (!_emojiShown && s_inner->inlineResultsShown()) { }
void EmojiPan::moveByBottom() {
if (inlineResultsShown()) {
setOrigin(Ui::PanelAnimation::Origin::BottomLeft); setOrigin(Ui::PanelAnimation::Origin::BottomLeft);
moveToLeft(0, _bottom - height()); moveToLeft(0, countBottom() - height());
} else { } else {
setOrigin(Ui::PanelAnimation::Origin::BottomRight); setOrigin(Ui::PanelAnimation::Origin::BottomRight);
moveToRight(0, _bottom - height()); moveToRight(0, countBottom() - height());
} }
} }
@ -3353,7 +3380,7 @@ void EmojiPan::showStarted() {
s_inner->preloadImages(); s_inner->preloadImages();
_a_slide.finish(); _a_slide.finish();
_slideAnimation.reset(); _slideAnimation.reset();
moveBottom(y() + height(), true); moveByBottom();
show(); show();
startShowAnimation(); startShowAnimation();
} else if (_hiding) { } else if (_hiding) {
@ -3391,7 +3418,7 @@ bool EmojiPan::eventFilter(QObject *obj, QEvent *e) {
void EmojiPan::stickersInstalled(uint64 setId) { void EmojiPan::stickersInstalled(uint64 setId) {
_emojiShown = false; _emojiShown = false;
if (isHidden()) { if (isHidden()) {
moveBottom(y() + height(), true); moveByBottom();
startShowAnimation(); startShowAnimation();
show(); show();
} }
@ -3736,7 +3763,7 @@ bool EmojiPan::overlaps(const QRect &globalRect) const {
} }
bool EmojiPan::hideOnNoInlineResults() { bool EmojiPan::hideOnNoInlineResults() {
return _inlineBot && !_emojiShown && s_inner->inlineResultsShown() && (_shownFromInlineQuery || _inlineBot->username != cInlineGifBotUsername()); return _inlineBot && inlineResultsShown() && (_shownFromInlineQuery || _inlineBot->username != cInlineGifBotUsername());
} }
void EmojiPan::inlineBotChanged() { void EmojiPan::inlineBotChanged() {
@ -3920,7 +3947,7 @@ int32 EmojiPan::showInlineRows(bool newResults) {
void EmojiPan::recountContentMaxHeight() { void EmojiPan::recountContentMaxHeight() {
if (_shownFromInlineQuery) { if (_shownFromInlineQuery) {
_contentMaxHeight = qMin(s_inner->countHeight(true), int(st::emojiPanMaxHeight)); _contentMaxHeight = qMin(s_inner->countHeight(true), st::emojiPanMaxHeight);
} else { } else {
_contentMaxHeight = st::emojiPanMaxHeight; _contentMaxHeight = st::emojiPanMaxHeight;
} }

View File

@ -473,9 +473,9 @@ class EmojiPan : public TWidget, public RPCSender {
public: public:
EmojiPan(QWidget *parent); EmojiPan(QWidget *parent);
void setMaxHeight(int maxHeight); void setMinTop(int minTop);
void setMinBottom(int minBottom);
void moveBottom(int bottom, bool force = false); void moveBottom(int bottom);
void hideFast(); void hideFast();
bool hiding() const { bool hiding() const {
@ -554,6 +554,9 @@ signals:
void updateStickers(); void updateStickers();
private: private:
bool inlineResultsShown() const;
int countBottom() const;
void moveByBottom();
void paintContent(Painter &p); void paintContent(Painter &p);
void performSwitch(); void performSwitch();
@ -607,7 +610,8 @@ private:
void showAll(); void showAll();
void hideAll(); void hideAll();
int _maxHeight = 0; int _minTop = 0;
int _minBottom = 0;
int _contentMaxHeight = 0; int _contentMaxHeight = 0;
int _contentHeight = 0; int _contentHeight = 0;
int _contentHeightEmoji = 0; int _contentHeightEmoji = 0;

View File

@ -152,6 +152,7 @@ emojiPanAnimation: PanelAnimation(defaultPanelAnimation) {
emojiPanPadding: 12px; emojiPanPadding: 12px;
emojiPanSize: size(45px, 41px); emojiPanSize: size(45px, 41px);
emojiPanWidth: 345px; emojiPanWidth: 345px;
emojiPanMinHeight: 206px;
emojiPanMaxHeight: 366px; emojiPanMaxHeight: 366px;
emojiPanShowDuration: 200; emojiPanShowDuration: 200;
emojiPanDuration: 200; emojiPanDuration: 200;

View File

@ -95,8 +95,13 @@ public:
} }
void paint(Painter &p, int x, int y, int size); void paint(Painter &p, int x, int y, int size);
void paintRounded(Painter &p, int x, int y, int size);
StorageKey uniqueKey() const;
private: private:
template <typename PaintBackground>
void paint(Painter &p, int x, int y, int size, PaintBackground paintBackground);
void fillString(const QString &name); void fillString(const QString &name);
style::color _color; style::color _color;
@ -104,7 +109,8 @@ private:
}; };
void EmptyUserpic::Impl::paint(Painter &p, int x, int y, int size) { template <typename PaintBackground>
void EmptyUserpic::Impl::paint(Painter &p, int x, int y, int size, PaintBackground paintBackground) {
auto fontsize = (size * 13) / 33; auto fontsize = (size * 13) / 33;
auto font = st::historyPeerUserpicFont->f; auto font = st::historyPeerUserpicFont->f;
font.setPixelSize(fontsize); font.setPixelSize(fontsize);
@ -112,7 +118,7 @@ void EmptyUserpic::Impl::paint(Painter &p, int x, int y, int size) {
PainterHighQualityEnabler hq(p); PainterHighQualityEnabler hq(p);
p.setBrush(_color); p.setBrush(_color);
p.setPen(Qt::NoPen); p.setPen(Qt::NoPen);
p.drawEllipse(x, y, size, size); paintBackground();
p.setFont(font); p.setFont(font);
p.setBrush(Qt::NoBrush); p.setBrush(Qt::NoBrush);
@ -120,6 +126,25 @@ void EmptyUserpic::Impl::paint(Painter &p, int x, int y, int size) {
p.drawText(QRect(x, y, size, size), _string, QTextOption(style::al_center)); p.drawText(QRect(x, y, size, size), _string, QTextOption(style::al_center));
} }
void EmptyUserpic::Impl::paint(Painter &p, int x, int y, int size) {
paint(p, x, y, size, [&p, x, y, size] {
p.drawEllipse(x, y, size, size);
});
}
void EmptyUserpic::Impl::paintRounded(Painter &p, int x, int y, int size) {
paint(p, x, y, size, [&p, x, y, size] {
p.drawRoundedRect(x, y, size, size, st::buttonRadius, st::buttonRadius);
});
}
StorageKey EmptyUserpic::Impl::uniqueKey() const {
auto first = 0xFFFFFFFF00000000ULL | anim::getPremultiplied(_color->c);
auto second = uint64(0);
memcpy(&second, _string.constData(), qMin(sizeof(second), _string.size() * sizeof(QChar)));
return StorageKey(first, second);
}
void EmptyUserpic::Impl::fillString(const QString &name) { void EmptyUserpic::Impl::fillString(const QString &name) {
QList<QString> letters; QList<QString> letters;
QList<int> levels; QList<int> levels;
@ -195,6 +220,16 @@ void EmptyUserpic::paint(Painter &p, int x, int y, int outerWidth, int size) con
_impl->paint(p, rtl() ? (outerWidth - x - size) : x, y, size); _impl->paint(p, rtl() ? (outerWidth - x - size) : x, y, size);
} }
void EmptyUserpic::paintRounded(Painter &p, int x, int y, int outerWidth, int size) const {
t_assert(_impl != nullptr);
_impl->paintRounded(p, rtl() ? (outerWidth - x - size) : x, y, size);
}
StorageKey EmptyUserpic::uniqueKey() const {
t_assert(_impl != nullptr);
return _impl->uniqueKey();
}
QPixmap EmptyUserpic::generate(int size) { QPixmap EmptyUserpic::generate(int size) {
auto result = QImage(QSize(size, size) * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied); auto result = QImage(QSize(size, size) * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied);
result.setDevicePixelRatio(cRetinaFactor()); result.setDevicePixelRatio(cRetinaFactor());
@ -299,9 +334,17 @@ void PeerData::paintUserpic(Painter &p, int x, int y, int size) const {
} }
} }
void PeerData::paintUserpicRounded(Painter &p, int x, int y, int size) const {
if (auto userpic = currentUserpic()) {
p.drawPixmap(x, y, userpic->pixRounded(size, size, ImageRoundRadius::Small));
} else {
_userpicEmpty.paintRounded(p, x, y, x + size + x, size);
}
}
StorageKey PeerData::userpicUniqueKey() const { StorageKey PeerData::userpicUniqueKey() const {
if (photoLoc.isNull() || !_userpic || !_userpic->loaded()) { if (photoLoc.isNull() || !_userpic || !_userpic->loaded()) {
return StorageKey(0, (isUser() ? 0x1000 : ((isChat() || isMegagroup()) ? 0x2000 : 0x3000)) | colorIndex); return _userpicEmpty.uniqueKey();
} }
return storageKey(photoLoc); return storageKey(photoLoc);
} }
@ -310,7 +353,25 @@ void PeerData::saveUserpic(const QString &path, int size) const {
genUserpic(size).save(path, "PNG"); genUserpic(size).save(path, "PNG");
} }
void PeerData::saveUserpicRounded(const QString &path, int size) const {
genUserpicRounded(size).save(path, "PNG");
}
QPixmap PeerData::genUserpic(int size) const { QPixmap PeerData::genUserpic(int size) const {
if (auto userpic = currentUserpic()) {
return userpic->pixCircled(size, size);
}
auto result = QImage(QSize(size, size) * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied);
result.setDevicePixelRatio(cRetinaFactor());
result.fill(Qt::transparent);
{
Painter p(&result);
paintUserpic(p, 0, 0, size);
}
return App::pixmapFromImageInPlace(std_::move(result));
}
QPixmap PeerData::genUserpicRounded(int size) const {
if (auto userpic = currentUserpic()) { if (auto userpic = currentUserpic()) {
return userpic->pixRounded(size, size, ImageRoundRadius::Small); return userpic->pixRounded(size, size, ImageRoundRadius::Small);
} }
@ -319,7 +380,7 @@ QPixmap PeerData::genUserpic(int size) const {
result.fill(Qt::transparent); result.fill(Qt::transparent);
{ {
Painter p(&result); Painter p(&result);
paintUserpic(p, 0, 0, size); paintUserpicRounded(p, 0, 0, size);
} }
return App::pixmapFromImageInPlace(std_::move(result)); return App::pixmapFromImageInPlace(std_::move(result));
} }

View File

@ -218,7 +218,9 @@ public:
} }
void paint(Painter &p, int x, int y, int outerWidth, int size) const; void paint(Painter &p, int x, int y, int outerWidth, int size) const;
void paintRounded(Painter &p, int x, int y, int outerWidth, int size) const;
QPixmap generate(int size); QPixmap generate(int size);
StorageKey uniqueKey() const;
~EmptyUserpic(); ~EmptyUserpic();
@ -317,6 +319,7 @@ public:
void paintUserpicLeft(Painter &p, int x, int y, int w, int size) const { void paintUserpicLeft(Painter &p, int x, int y, int w, int size) const {
paintUserpic(p, rtl() ? (w - x - size) : x, y, size); paintUserpic(p, rtl() ? (w - x - size) : x, y, size);
} }
void paintUserpicRounded(Painter &p, int x, int y, int size) const;
void loadUserpic(bool loadFirst = false, bool prior = true) { void loadUserpic(bool loadFirst = false, bool prior = true) {
_userpic->load(loadFirst, prior); _userpic->load(loadFirst, prior);
} }
@ -325,7 +328,9 @@ public:
} }
StorageKey userpicUniqueKey() const; StorageKey userpicUniqueKey() const;
void saveUserpic(const QString &path, int size) const; void saveUserpic(const QString &path, int size) const;
void saveUserpicRounded(const QString &path, int size) const;
QPixmap genUserpic(int size) const; QPixmap genUserpic(int size) const;
QPixmap genUserpicRounded(int size) const;
PhotoId photoId = UnknownPeerPhotoId; PhotoId photoId = UnknownPeerPhotoId;
StorageImageLocation photoLoc; StorageImageLocation photoLoc;

View File

@ -3826,7 +3826,7 @@ void PortInput::correctValue(const QString &was, int32 wasCursor, QString &now,
} }
UsernameInput::UsernameInput(QWidget *parent, const style::InputField &st, const QString &ph, const QString &val, bool isLink) : MaskedInputField(parent, st, ph, val), UsernameInput::UsernameInput(QWidget *parent, const style::InputField &st, const QString &ph, const QString &val, bool isLink) : MaskedInputField(parent, st, ph, val),
_linkPlaceholder(isLink ? qsl("telegram.me/") : QString()) { _linkPlaceholder(isLink ? CreateInternalLink(QString()) : QString()) {
if (!_linkPlaceholder.isEmpty()) { if (!_linkPlaceholder.isEmpty()) {
setTextMargins(style::margins(_st.textMargins.left() + _st.font->width(_linkPlaceholder), _st.textMargins.top(), _st.textMargins.right(), _st.textMargins.bottom())); setTextMargins(style::margins(_st.textMargins.left() + _st.font->width(_linkPlaceholder), _st.textMargins.top(), _st.textMargins.right(), _st.textMargins.bottom()));
setPlaceholderHidden(true); setPlaceholderHidden(true);

View File

@ -34,7 +34,7 @@ constexpr int kNotifyDeletePhotoAfterMs = 60000;
} // namespace } // namespace
CachedUserpics::CachedUserpics() { CachedUserpics::CachedUserpics(Type type) : _type(type) {
connect(&_clearTimer, SIGNAL(timeout()), this, SLOT(onClear())); connect(&_clearTimer, SIGNAL(timeout()), this, SLOT(onClear()));
QDir().mkpath(cWorkingDir() + qsl("tdata/temp")); QDir().mkpath(cWorkingDir() + qsl("tdata/temp"));
} }
@ -57,7 +57,11 @@ QString CachedUserpics::get(const StorageKey &key, PeerData *peer) {
} }
v.path = cWorkingDir() + qsl("tdata/temp/") + QString::number(rand_value<uint64>(), 16) + qsl(".png"); v.path = cWorkingDir() + qsl("tdata/temp/") + QString::number(rand_value<uint64>(), 16) + qsl(".png");
if (key.first || key.second) { if (key.first || key.second) {
peer->saveUserpic(v.path, st::notifyMacPhotoSize); if (_type == Type::Rounded) {
peer->saveUserpicRounded(v.path, st::notifyMacPhotoSize);
} else {
peer->saveUserpic(v.path, st::notifyMacPhotoSize);
}
} else { } else {
App::wnd()->iconLarge().save(v.path, "PNG"); App::wnd()->iconLarge().save(v.path, "PNG");
} }

View File

@ -30,7 +30,11 @@ class CachedUserpics : public QObject {
Q_OBJECT Q_OBJECT
public: public:
CachedUserpics(); enum class Type {
Rounded,
Circled,
};
CachedUserpics(Type type);
QString get(const StorageKey &key, PeerData *peer); QString get(const StorageKey &key, PeerData *peer);
@ -43,6 +47,7 @@ private:
void clearInMs(int ms); void clearInMs(int ms);
TimeMs clear(TimeMs ms); TimeMs clear(TimeMs ms);
Type _type = Type::Rounded;
struct Image { struct Image {
TimeMs until; TimeMs until;
QString path; QString path;

View File

@ -192,10 +192,24 @@ void TopBarWidget::paintUnreadCounter(Painter &p, int outerWidth) {
if (!Adaptive::OneColumn()) { if (!Adaptive::OneColumn()) {
return; return;
} }
if (auto counter = App::histories().unreadBadge()) { auto mutedCount = App::histories().unreadMutedCount();
auto fullCounter = App::histories().unreadBadge() + (Global::IncludeMuted() ? 0 : mutedCount);
// Do not include currently shown chat in the top bar unread counter.
if (auto historyShown = App::historyLoaded(App::main()->historyPeer())) {
auto shownUnreadCount = historyShown->unreadCount();
if (!historyShown->mute() || Global::IncludeMuted()) {
fullCounter -= shownUnreadCount;
}
if (historyShown->mute()) {
mutedCount -= shownUnreadCount;
}
}
if (auto counter = (fullCounter - (Global::IncludeMuted() ? 0 : mutedCount))) {
auto counterText = (counter > 99) ? qsl("..%1").arg(counter % 100) : QString::number(counter); auto counterText = (counter > 99) ? qsl("..%1").arg(counter % 100) : QString::number(counter);
Dialogs::Layout::UnreadBadgeStyle unreadSt; Dialogs::Layout::UnreadBadgeStyle unreadSt;
unreadSt.muted = App::histories().unreadOnlyMuted(); unreadSt.muted = (mutedCount >= fullCounter);
auto unreadRight = st::titleUnreadCounterRight; auto unreadRight = st::titleUnreadCounterRight;
if (rtl()) unreadRight = outerWidth - st::titleUnreadCounterRight; if (rtl()) unreadRight = outerWidth - st::titleUnreadCounterRight;
auto unreadTop = st::titleUnreadCounterTop; auto unreadTop = st::titleUnreadCounterTop;
@ -303,13 +317,14 @@ void TopBarWidget::showAll() {
void TopBarWidget::updateMembersShowArea() { void TopBarWidget::updateMembersShowArea() {
auto membersShowAreaNeeded = [this]() { auto membersShowAreaNeeded = [this]() {
if ((_selectedCount > 0) || App::main()->overviewPeer() || !_selectedInPeer) { auto peer = App::main()->peer();
if ((_selectedCount > 0) || !peer || App::main()->overviewPeer()) {
return false; return false;
} }
if (auto chat = _selectedInPeer->asChat()) { if (auto chat = peer->asChat()) {
return chat->amIn(); return chat->amIn();
} }
if (auto megagroup = _selectedInPeer->asMegagroup()) { if (auto megagroup = peer->asMegagroup()) {
return megagroup->canViewMembers() && (megagroup->membersCount() < Global::ChatSizeMax()); return megagroup->canViewMembers() && (megagroup->membersCount() < Global::ChatSizeMax());
} }
return false; return false;
@ -338,7 +353,6 @@ void TopBarWidget::showSelected(int selectedCount, bool canDelete) {
} }
auto wasSelected = (_selectedCount > 0); auto wasSelected = (_selectedCount > 0);
_selectedInPeer = App::main()->overviewPeer() ? App::main()->overviewPeer() : App::main()->peer();
_selectedCount = selectedCount; _selectedCount = selectedCount;
if (_selectedCount > 0) { if (_selectedCount > 0) {
_forward->setNumbersText(_selectedCount); _forward->setNumbersText(_selectedCount);

View File

@ -74,7 +74,6 @@ private:
MainWidget *main(); MainWidget *main();
PeerData *_searchInPeer = nullptr; PeerData *_searchInPeer = nullptr;
PeerData *_selectedInPeer = nullptr;
int _selectedCount = 0; int _selectedCount = 0;
bool _canDelete = false; bool _canDelete = false;

View File

@ -1,6 +1,6 @@
AppVersion 10025 AppVersion 10026
AppVersionStrMajor 0.10 AppVersionStrMajor 0.10
AppVersionStrSmall 0.10.25 AppVersionStrSmall 0.10.26
AppVersionStr 0.10.25 AppVersionStr 0.10.26
AlphaChannel 1 AlphaChannel 1
BetaVersion 0 BetaVersion 0

View File

@ -119,7 +119,7 @@ Go to **D:\\TBuild\\Libraries** and run
git clone git://repo.or.cz/openal-soft.git git clone git://repo.or.cz/openal-soft.git
cd openal-soft cd openal-soft
git checkout 90349b38 git checkout 18bb46163af
git apply ./../../tdesktop/Telegram/Patches/openal.diff git apply ./../../tdesktop/Telegram/Patches/openal.diff
#### Building library #### Building library