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
index bf97ef2..1cd5774 100644
index 9d8f8e9..8c8e44a 100644
--- a/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();
althrd_setname(althrd_current(), MIXER_THREAD_NAME);
- 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)
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);
- 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)
continue;

View File

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

View File

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

View File

@ -1069,8 +1069,8 @@ void AppClass::checkMapVersion() {
if (Local::oldMapVersion() < AppVersion) {
if (Local::oldMapVersion()) {
QString versionFeatures;
if ((cAlphaVersion() || cBetaVersion()) && Local::oldMapVersion() < 10021) {
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.");
if ((cAlphaVersion() || cBetaVersion()) && Local::oldMapVersion() < 10026) {
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) {
versionFeatures = langNewVersionText();
} else {

View File

@ -1173,7 +1173,7 @@ void RevokePublicLinkBox::mouseReleaseEvent(QMouseEvent *e) {
setCursor((_selected || _pressed) ? style::cur_pointer : style::cur_default);
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 = 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);
_weakRevokeConfirmBox = Ui::show(Box<ConfirmBox>(text, confirmText, base::lambda_guarded(this, [this, pressed]() {
if (_revokeRequestId) return;
@ -1233,7 +1233,7 @@ void RevokePublicLinkBox::getPublicDone(const MTPmessages_Chats &result) {
ChatRow row;
row.peer = peer;
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));
}
}

View File

@ -45,7 +45,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "apiwrap.h"
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) {
return lng_cant_invite_not_contact(lt_more_info, link);
}

View File

@ -870,7 +870,7 @@ void shareGameScoreFromItem(HistoryItem *item) {
if (media->type() == MediaTypeGame) {
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;
toast.text = lang(lng_share_game_link_copied);

View File

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

View File

@ -86,7 +86,7 @@ void UsernameBox::paintEvent(QPaintEvent *e) {
if (_link->isHidden()) {
p.drawTextLeft(st::usernamePadding.left(), linky, width(), lang(lng_username_link_willbe));
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 {
p.drawTextLeft(st::usernamePadding.left(), linky, width(), lang(lng_username_link));
}
@ -160,7 +160,7 @@ void UsernameBox::onChanged() {
}
void UsernameBox::onLinkClick() {
Application::clipboard()->setText(qsl("https://telegram.me/") + getName());
Application::clipboard()->setText(CreateInternalLinkHttps(getName()));
Ui::Toast::Config toast;
toast.text = lang(lng_username_copied);
@ -234,7 +234,7 @@ QString UsernameBox::getName() const {
void UsernameBox::updateLinkText() {
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 (!_link->isHidden()) {
_link->hide();

View File

@ -322,6 +322,16 @@ inline QString cApiAppVersion() {
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;
inline const QString &cDataFile() {
if (!gKeyFile.isEmpty()) return gKeyFile;

View File

@ -40,12 +40,9 @@ QString tryConvertUrlToLocal(QString url) {
using namespace qthelp;
auto matchOptions = RegExOption::CaseInsensitive;
auto telegramMeMatch = regex_match(qsl("https?://(www\\.)?telegram\\.me/(.+)$"), url, matchOptions);
if (!telegramMeMatch) {
telegramMeMatch = regex_match(qsl("https?://(www\\.)?t\\.me/(.+)$"), url, matchOptions);
}
auto telegramMeMatch = regex_match(qsl("https?://(www\\.)?(telegram|t)\\.me/(.+)$"), url, matchOptions);
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)) {
return qsl("tg://join?invite=") + url_encode(joinChatMatch->captured(1));
} 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)
constexpr int AppVersion = 10025;
constexpr str_const AppVersionStr = "0.10.25";
constexpr int AppVersion = 10026;
constexpr str_const AppVersionStr = "0.10.26";
constexpr bool AppAlphaVersion = true;
constexpr uint64 AppBetaVersion = BETA_VERSION_MACRO;

View File

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

View File

@ -41,7 +41,7 @@ public:
using Map = QHash<PeerId, History*>;
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);
@ -53,9 +53,6 @@ public:
void clear();
void remove(const PeerId &peer);
~Histories() {
_unreadFull = _unreadMuted = 0;
}
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();
}
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;

View File

@ -6389,7 +6389,7 @@ void HistoryWidget::moveFieldControls() {
_silent->moveToRight(right, buttonsBottom);
_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());
_botStart->setGeometry(fullWidthButtonRect);
@ -7098,7 +7098,8 @@ void HistoryWidget::updateControlsGeometry() {
updateHistoryDownPosition();
_emojiPan->setMaxHeight(height() - _attachEmoji->height());
_emojiPan->setMinTop(0);
_emojiPan->setMinBottom(_attachEmoji->height());
if (_membersDropdown) {
_membersDropdown->setMaxHeight(countMembersDropdownHeightMax());
}

View File

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

View File

@ -266,6 +266,10 @@ void finish() {
class Manager::Impl {
public:
using Type = Window::Notifications::CachedUserpics::Type;
Impl(Type type) : _cachedUserpics(type) {
}
bool init();
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();
}
Manager::Manager() : _impl(std_::make_unique<Impl>()) {
Manager::Manager() : _impl(std_::make_unique<Impl>(Impl::Type::Rounded)) {
}
bool Manager::init() {

View File

@ -338,6 +338,11 @@ void finish() {
class Manager::Impl {
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);
void clearAll();
void clearFromHistory(History *history);
@ -506,7 +511,7 @@ bool Manager::Impl::showNotification(PeerData *peer, MsgId msgId, const QString
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) {

View File

@ -192,10 +192,10 @@ void InfoWidget::refreshChannelLink() {
TextWithEntities channelLinkTextShort;
if (auto channel = peer()->asChannel()) {
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()));
channelLinkTextShort.text = qsl("telegram.me/") + channel->username;
channelLinkTextShort.entities.push_back(EntityInText(EntityInTextCustomUrl, 0, channelLinkTextShort.text.size(), qsl("https://telegram.me/") + channel->username));
channelLinkTextShort.text = CreateInternalLink(channel->username);
channelLinkTextShort.entities.push_back(EntityInText(EntityInTextCustomUrl, 0, channelLinkTextShort.text.size(), CreateInternalLinkHttps(channel->username)));
}
}
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) {
if (e->key() == Qt::Key_Escape) {
emit cancelled();
}
}
void InnerWidget::updateSelected(QPoint localPos) {

View File

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

View File

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

View File

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

View File

@ -95,8 +95,13 @@ public:
}
void paint(Painter &p, int x, int y, int size);
void paintRounded(Painter &p, int x, int y, int size);
StorageKey uniqueKey() const;
private:
template <typename PaintBackground>
void paint(Painter &p, int x, int y, int size, PaintBackground paintBackground);
void fillString(const QString &name);
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 font = st::historyPeerUserpicFont->f;
font.setPixelSize(fontsize);
@ -112,7 +118,7 @@ void EmptyUserpic::Impl::paint(Painter &p, int x, int y, int size) {
PainterHighQualityEnabler hq(p);
p.setBrush(_color);
p.setPen(Qt::NoPen);
p.drawEllipse(x, y, size, size);
paintBackground();
p.setFont(font);
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));
}
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) {
QList<QString> letters;
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);
}
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) {
auto result = QImage(QSize(size, size) * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied);
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 {
if (photoLoc.isNull() || !_userpic || !_userpic->loaded()) {
return StorageKey(0, (isUser() ? 0x1000 : ((isChat() || isMegagroup()) ? 0x2000 : 0x3000)) | colorIndex);
return _userpicEmpty.uniqueKey();
}
return storageKey(photoLoc);
}
@ -310,7 +353,25 @@ void PeerData::saveUserpic(const QString &path, int size) const {
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 {
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()) {
return userpic->pixRounded(size, size, ImageRoundRadius::Small);
}
@ -319,7 +380,7 @@ QPixmap PeerData::genUserpic(int size) const {
result.fill(Qt::transparent);
{
Painter p(&result);
paintUserpic(p, 0, 0, size);
paintUserpicRounded(p, 0, 0, size);
}
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 paintRounded(Painter &p, int x, int y, int outerWidth, int size) const;
QPixmap generate(int size);
StorageKey uniqueKey() const;
~EmptyUserpic();
@ -317,6 +319,7 @@ public:
void paintUserpicLeft(Painter &p, int x, int y, int w, int size) const {
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) {
_userpic->load(loadFirst, prior);
}
@ -325,7 +328,9 @@ public:
}
StorageKey userpicUniqueKey() const;
void saveUserpic(const QString &path, int size) const;
void saveUserpicRounded(const QString &path, int size) const;
QPixmap genUserpic(int size) const;
QPixmap genUserpicRounded(int size) const;
PhotoId photoId = UnknownPeerPhotoId;
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),
_linkPlaceholder(isLink ? qsl("telegram.me/") : QString()) {
_linkPlaceholder(isLink ? CreateInternalLink(QString()) : QString()) {
if (!_linkPlaceholder.isEmpty()) {
setTextMargins(style::margins(_st.textMargins.left() + _st.font->width(_linkPlaceholder), _st.textMargins.top(), _st.textMargins.right(), _st.textMargins.bottom()));
setPlaceholderHidden(true);

View File

@ -34,7 +34,7 @@ constexpr int kNotifyDeletePhotoAfterMs = 60000;
} // namespace
CachedUserpics::CachedUserpics() {
CachedUserpics::CachedUserpics(Type type) : _type(type) {
connect(&_clearTimer, SIGNAL(timeout()), this, SLOT(onClear()));
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");
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 {
App::wnd()->iconLarge().save(v.path, "PNG");
}

View File

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

View File

@ -192,10 +192,24 @@ void TopBarWidget::paintUnreadCounter(Painter &p, int outerWidth) {
if (!Adaptive::OneColumn()) {
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);
Dialogs::Layout::UnreadBadgeStyle unreadSt;
unreadSt.muted = App::histories().unreadOnlyMuted();
unreadSt.muted = (mutedCount >= fullCounter);
auto unreadRight = st::titleUnreadCounterRight;
if (rtl()) unreadRight = outerWidth - st::titleUnreadCounterRight;
auto unreadTop = st::titleUnreadCounterTop;
@ -303,13 +317,14 @@ void TopBarWidget::showAll() {
void TopBarWidget::updateMembersShowArea() {
auto membersShowAreaNeeded = [this]() {
if ((_selectedCount > 0) || App::main()->overviewPeer() || !_selectedInPeer) {
auto peer = App::main()->peer();
if ((_selectedCount > 0) || !peer || App::main()->overviewPeer()) {
return false;
}
if (auto chat = _selectedInPeer->asChat()) {
if (auto chat = peer->asChat()) {
return chat->amIn();
}
if (auto megagroup = _selectedInPeer->asMegagroup()) {
if (auto megagroup = peer->asMegagroup()) {
return megagroup->canViewMembers() && (megagroup->membersCount() < Global::ChatSizeMax());
}
return false;
@ -338,7 +353,6 @@ void TopBarWidget::showSelected(int selectedCount, bool canDelete) {
}
auto wasSelected = (_selectedCount > 0);
_selectedInPeer = App::main()->overviewPeer() ? App::main()->overviewPeer() : App::main()->peer();
_selectedCount = selectedCount;
if (_selectedCount > 0) {
_forward->setNumbersText(_selectedCount);

View File

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

View File

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

View File

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