Updated TDesktop sources to 2.1.17 beta

This commit is contained in:
Eric Kotato 2020-07-03 04:39:44 +03:00
commit f633857744
90 changed files with 610 additions and 348 deletions

View file

@ -738,6 +738,8 @@ PRIVATE
media/audio/media_audio_track.h media/audio/media_audio_track.h
media/audio/media_child_ffmpeg_loader.cpp media/audio/media_child_ffmpeg_loader.cpp
media/audio/media_child_ffmpeg_loader.h media/audio/media_child_ffmpeg_loader.h
media/audio/media_openal_functions.cpp
media/audio/media_openal_functions.h
media/clip/media_clip_check_streaming.cpp media/clip/media_clip_check_streaming.cpp
media/clip/media_clip_check_streaming.h media/clip/media_clip_check_streaming.h
media/clip/media_clip_ffmpeg.cpp media/clip/media_clip_ffmpeg.cpp

View file

@ -9,7 +9,7 @@
<Identity Name="TelegramMessengerLLP.TelegramDesktop" <Identity Name="TelegramMessengerLLP.TelegramDesktop"
ProcessorArchitecture="ARCHITECTURE" ProcessorArchitecture="ARCHITECTURE"
Publisher="CN=536BC709-8EE1-4478-AF22-F0F0F26FF64A" Publisher="CN=536BC709-8EE1-4478-AF22-F0F0F26FF64A"
Version="2.1.16.0" /> Version="2.1.17.0" />
<Properties> <Properties>
<DisplayName>Telegram Desktop</DisplayName> <DisplayName>Telegram Desktop</DisplayName>
<PublisherDisplayName>Telegram FZ-LLC</PublisherDisplayName> <PublisherDisplayName>Telegram FZ-LLC</PublisherDisplayName>

View file

@ -44,8 +44,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico"
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 2,1,16,0 FILEVERSION 2,1,17,0
PRODUCTVERSION 2,1,16,0 PRODUCTVERSION 2,1,17,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -62,10 +62,10 @@ BEGIN
BEGIN BEGIN
VALUE "CompanyName", "Telegram FZ-LLC" VALUE "CompanyName", "Telegram FZ-LLC"
VALUE "FileDescription", "Telegram Desktop" VALUE "FileDescription", "Telegram Desktop"
VALUE "FileVersion", "2.1.16.0" VALUE "FileVersion", "2.1.17.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2020" VALUE "LegalCopyright", "Copyright (C) 2014-2020"
VALUE "ProductName", "Telegram Desktop" VALUE "ProductName", "Telegram Desktop"
VALUE "ProductVersion", "2.1.16.0" VALUE "ProductVersion", "2.1.17.0"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View file

@ -35,8 +35,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 2,1,16,0 FILEVERSION 2,1,17,0
PRODUCTVERSION 2,1,16,0 PRODUCTVERSION 2,1,17,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -53,10 +53,10 @@ BEGIN
BEGIN BEGIN
VALUE "CompanyName", "Telegram FZ-LLC" VALUE "CompanyName", "Telegram FZ-LLC"
VALUE "FileDescription", "Telegram Desktop Updater" VALUE "FileDescription", "Telegram Desktop Updater"
VALUE "FileVersion", "2.1.16.0" VALUE "FileVersion", "2.1.17.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2020" VALUE "LegalCopyright", "Copyright (C) 2014-2020"
VALUE "ProductName", "Telegram Desktop" VALUE "ProductName", "Telegram Desktop"
VALUE "ProductVersion", "2.1.16.0" VALUE "ProductVersion", "2.1.17.0"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View file

@ -1364,7 +1364,10 @@ void RevokePublicLinkBox::prepare() {
addButton(tr::lng_cancel(), [=] { closeBox(); }); addButton(tr::lng_cancel(), [=] { closeBox(); });
subscribe(_session->downloaderTaskFinished(), [=] { update(); }); _session->downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
}, lifetime());
_inner->resizeToWidth(st::boxWideWidth); _inner->resizeToWidth(st::boxWideWidth);
setDimensions(st::boxWideWidth, _innerTop + _inner->height()); setDimensions(st::boxWideWidth, _innerTop + _inner->height());

View file

@ -203,7 +203,10 @@ BackgroundBox::Inner::Inner(
} }
requestPapers(); requestPapers();
subscribe(_session->downloaderTaskFinished(), [=] { update(); }); _session->downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
}, lifetime());
using Update = Window::Theme::BackgroundUpdate; using Update = Window::Theme::BackgroundUpdate;
subscribe(Window::Theme::Background(), [=](const Update &update) { subscribe(Window::Theme::Background(), [=](const Update &update) {
if (update.paletteChanged()) { if (update.paletteChanged()) {

View file

@ -419,9 +419,10 @@ BackgroundPreviewBox::BackgroundPreviewBox(
if (_media) { if (_media) {
_media->thumbnailWanted(_paper.fileOrigin()); _media->thumbnailWanted(_paper.fileOrigin());
} }
subscribe(_controller->session().downloaderTaskFinished(), [=] { _controller->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update(); update();
}); }, lifetime());
} }
not_null<HistoryView::ElementDelegate*> BackgroundPreviewBox::delegate() { not_null<HistoryView::ElementDelegate*> BackgroundPreviewBox::delegate() {

View file

@ -891,9 +891,10 @@ ConfirmInviteBox::ConfirmInviteBox(
_photo = photo->createMediaView(); _photo = photo->createMediaView();
_photo->wanted(Data::PhotoSize::Small, Data::FileOrigin()); _photo->wanted(Data::PhotoSize::Small, Data::FileOrigin());
if (!_photo->image(Data::PhotoSize::Small)) { if (!_photo->image(Data::PhotoSize::Small)) {
subscribe(_session->downloaderTaskFinished(), [=] { _session->downloaderTaskFinished(
) | rpl::start_with_next([=] {
update(); update();
}); }, lifetime());
} }
} else { } else {
_photoEmpty = std::make_unique<Ui::EmptyUserpic>( _photoEmpty = std::make_unique<Ui::EmptyUserpic>(

View file

@ -259,9 +259,9 @@ auto AddButtonWithLoader(
) )
); );
*buttonState = localLoaderValues->events_starting_with( *buttonState = localLoaderValues->events_starting_with(
rawGlobalLoaderPtr() ? rawGlobalLoaderPtr() : localLoader->get() rawGlobalLoaderPtr() ? rawGlobalLoaderPtr() : localLoader->get()
) | rpl::map([=](Loader *loader) { ) | rpl::map([=](Loader *loader) {
return (loader && loader->id() == id) return (loader && loader->id() == id)
? loader->state() ? loader->state()
: rpl::single( : rpl::single(

View file

@ -291,7 +291,8 @@ EditCaptionBox::EditCaptionBox(
Assert(_thumbnailImageLoaded || _refreshThumbnail); Assert(_thumbnailImageLoaded || _refreshThumbnail);
if (!_thumbnailImageLoaded) { if (!_thumbnailImageLoaded) {
subscribe(_controller->session().downloaderTaskFinished(), [=] { _controller->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
if (_thumbnailImageLoaded if (_thumbnailImageLoaded
|| (_photoMedia && !_photoMedia->image(PhotoSize::Large)) || (_photoMedia && !_photoMedia->image(PhotoSize::Large))
|| (_documentMedia && !_documentMedia->thumbnail())) { || (_documentMedia && !_documentMedia->thumbnail())) {
@ -299,7 +300,7 @@ EditCaptionBox::EditCaptionBox(
} }
_refreshThumbnail(); _refreshThumbnail();
update(); update();
}); }, lifetime());
} }
_field.create( _field.create(
this, this,

View file

@ -698,9 +698,10 @@ PeerListContent::PeerListContent(
, _st(st) , _st(st)
, _controller(controller) , _controller(controller)
, _rowHeight(_st.item.height) { , _rowHeight(_st.item.height) {
subscribe(_controller->session().downloaderTaskFinished(), [=] { _controller->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update(); update();
}); }, lifetime());
using UpdateFlag = Data::PeerUpdate::Flag; using UpdateFlag = Data::PeerUpdate::Flag;
_controller->session().changes().peerUpdates( _controller->session().changes().peerUpdates(

View file

@ -570,9 +570,10 @@ ShareBox::Inner::Inner(
update.oldFirstLetters); update.oldFirstLetters);
}, lifetime()); }, lifetime());
subscribe(_navigation->session().downloaderTaskFinished(), [=] { _navigation->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update(); update();
}); }, lifetime());
subscribe(Window::Theme::Background(), [this](const Window::Theme::BackgroundUpdate &update) { subscribe(Window::Theme::Background(), [this](const Window::Theme::BackgroundUpdate &update) {
if (update.paletteChanged()) { if (update.paletteChanged()) {

View file

@ -308,7 +308,10 @@ StickerSetBox::Inner::Inner(
_controller->session().api().updateStickers(); _controller->session().api().updateStickers();
subscribe(_controller->session().downloaderTaskFinished(), [this] { update(); }); _controller->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
}, lifetime());
setMouseTracking(true); setMouseTracking(true);
} }

View file

@ -1002,10 +1002,12 @@ Main::Session &StickersBox::Inner::session() const {
} }
void StickersBox::Inner::setup() { void StickersBox::Inner::setup() {
subscribe(session().downloaderTaskFinished(), [this] { session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update(); update();
readVisibleSets(); readVisibleSets();
}); }, lifetime());
setMouseTracking(true); setMouseTracking(true);
} }

View file

@ -446,9 +446,10 @@ void Panel::initLayout() {
}, lifetime()); }, lifetime());
processUserPhoto(); processUserPhoto();
subscribe(_user->session().downloaderTaskFinished(), [=] { _user->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
refreshUserPhoto(); refreshUserPhoto();
}); }, lifetime());
createDefaultCacheImage(); createDefaultCacheImage();
Ui::Platform::InitOnTopPanel(this); Ui::Platform::InitOnTopPanel(this);

View file

@ -161,12 +161,14 @@ bool BotKeyboard::moderateKeyActivate(int key) {
App::activateBotCommand(item, 0, index); App::activateBotCommand(item, 0, index);
return true; return true;
} }
} else if (key == Qt::Key_Q) { } else if (const auto user = item->history()->peer->asUser()) {
if (const auto user = item->history()->peer->asUser()) { if (user->isBot() && item->from() == user) {
if (user->isBot() && item->from() == user) { if (key == Qt::Key_Q) {
App::sendBotCommand(user, user, qsl("/translate")); App::sendBotCommand(user, user, qsl("/translate"));
return true; } else if (key == Qt::Key_W) {
App::sendBotCommand(user, user, qsl("/eng"));
} }
return true;
} }
} }
} }

View file

@ -571,16 +571,20 @@ bool FieldAutocomplete::eventFilter(QObject *obj, QEvent *e) {
if (e->type() == QEvent::KeyPress) { if (e->type() == QEvent::KeyPress) {
QKeyEvent *ev = static_cast<QKeyEvent*>(e); QKeyEvent *ev = static_cast<QKeyEvent*>(e);
if (!(ev->modifiers() & (Qt::AltModifier | Qt::ControlModifier | Qt::ShiftModifier | Qt::MetaModifier))) { if (!(ev->modifiers() & (Qt::AltModifier | Qt::ControlModifier | Qt::ShiftModifier | Qt::MetaModifier))) {
const auto key = ev->key();
if (!hidden) { if (!hidden) {
if (ev->key() == Qt::Key_Up || ev->key() == Qt::Key_Down || (!_srows.empty() && (ev->key() == Qt::Key_Left || ev->key() == Qt::Key_Right))) { if (key == Qt::Key_Up || key == Qt::Key_Down || (!_srows.empty() && (key == Qt::Key_Left || key == Qt::Key_Right))) {
return _inner->moveSel(ev->key()); return _inner->moveSel(key);
} else if (ev->key() == Qt::Key_Enter || ev->key() == Qt::Key_Return) { } else if (key == Qt::Key_Enter || key == Qt::Key_Return) {
return _inner->chooseSelected(ChooseMethod::ByEnter); return _inner->chooseSelected(ChooseMethod::ByEnter);
} }
} }
if (moderate && ((ev->key() >= Qt::Key_1 && ev->key() <= Qt::Key_9) || ev->key() == Qt::Key_Q)) { if (moderate
&& ((key >= Qt::Key_1 && key <= Qt::Key_9)
|| key == Qt::Key_Q
|| key == Qt::Key_W)) {
bool handled = false; bool handled = false;
emit moderateKeyActivate(ev->key(), &handled); emit moderateKeyActivate(key, &handled);
return handled; return handled;
} }
} else if (ev->modifiers() & Qt::ControlModifier) { } else if (ev->modifiers() & Qt::ControlModifier) {
@ -608,9 +612,10 @@ FieldAutocompleteInner::FieldAutocompleteInner(
, _brows(brows) , _brows(brows)
, _srows(srows) , _srows(srows)
, _previewTimer([=] { showPreview(); }) { , _previewTimer([=] { showPreview(); }) {
subscribe( controller->session().downloaderTaskFinished(
controller->session().downloaderTaskFinished(), ) | rpl::start_with_next([=] {
[=] { update(); }); update();
}, lifetime());
} }
void FieldAutocompleteInner::paintEvent(QPaintEvent *e) { void FieldAutocompleteInner::paintEvent(QPaintEvent *e) {

View file

@ -153,9 +153,10 @@ GifsListWidget::GifsListWidget(
refreshSavedGifs(); refreshSavedGifs();
}, lifetime()); }, lifetime());
subscribe(controller->session().downloaderTaskFinished(), [this] { controller->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update(); update();
}); }, lifetime());
subscribe(controller->gifPauseLevelChanged(), [=] { subscribe(controller->gifPauseLevelChanged(), [=] {
if (!controller->isGifPausedAtLeastFor( if (!controller->isGifPausedAtLeastFor(

View file

@ -204,7 +204,7 @@ std::shared_ptr<LargeEmojiImage> EmojiPack::image(EmojiPtr emoji) {
if (!strong->image) { if (!strong->image) {
strong->load = nullptr; strong->load = nullptr;
strong->image.emplace(std::move(image)); strong->image.emplace(std::move(image));
_session->downloaderTaskFinished().notify(); _session->notifyDownloaderTaskFinished();
} }
} }
} }

View file

@ -104,9 +104,7 @@ struct StickerIcon {
}; };
class StickersListWidget::Footer class StickersListWidget::Footer : public TabbedSelector::InnerFooter {
: public TabbedSelector::InnerFooter
, private base::Subscriber {
public: public:
explicit Footer(not_null<StickersListWidget*> parent); explicit Footer(not_null<StickersListWidget*> parent);
@ -131,7 +129,7 @@ protected:
void mousePressEvent(QMouseEvent *e) override; void mousePressEvent(QMouseEvent *e) override;
void mouseMoveEvent(QMouseEvent *e) override; void mouseMoveEvent(QMouseEvent *e) override;
void mouseReleaseEvent(QMouseEvent *e) override; void mouseReleaseEvent(QMouseEvent *e) override;
bool event(QEvent *e) override; bool eventHook(QEvent *e) override;
void processHideFinished() override; void processHideFinished() override;
@ -248,9 +246,10 @@ StickersListWidget::Footer::Footer(not_null<StickersListWidget*> parent)
_iconsLeft = _iconsRight = st::emojiCategorySkip + st::stickerIconWidth; _iconsLeft = _iconsRight = st::emojiCategorySkip + st::stickerIconWidth;
subscribe(_pan->session().downloaderTaskFinished(), [=] { _pan->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update(); update();
}); }, lifetime());
} }
void StickersListWidget::Footer::clearHeavyData() { void StickersListWidget::Footer::clearHeavyData() {
@ -599,7 +598,7 @@ void StickersListWidget::Footer::finishDragging() {
updateSelected(); updateSelected();
} }
bool StickersListWidget::Footer::event(QEvent *e) { bool StickersListWidget::Footer::eventHook(QEvent *e) {
if (e->type() == QEvent::TouchBegin) { if (e->type() == QEvent::TouchBegin) {
} else if (e->type() == QEvent::Wheel) { } else if (e->type() == QEvent::Wheel) {
if (!_icons.empty() if (!_icons.empty()
@ -608,7 +607,7 @@ bool StickersListWidget::Footer::event(QEvent *e) {
scrollByWheelEvent(static_cast<QWheelEvent*>(e)); scrollByWheelEvent(static_cast<QWheelEvent*>(e));
} }
} }
return InnerFooter::event(e); return InnerFooter::eventHook(e);
} }
void StickersListWidget::Footer::scrollByWheelEvent( void StickersListWidget::Footer::scrollByWheelEvent(
@ -889,12 +888,13 @@ StickersListWidget::StickersListWidget(
Box<StickersBox>(controller, StickersBox::Section::Installed)); Box<StickersBox>(controller, StickersBox::Section::Installed));
}); });
subscribe(session().downloaderTaskFinished(), [=] { session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
if (isVisible()) { if (isVisible()) {
update(); update();
readVisibleFeatured(getVisibleTop(), getVisibleBottom()); readVisibleFeatured(getVisibleTop(), getVisibleBottom());
} }
}); }, lifetime());
session().changes().peerUpdates( session().changes().peerUpdates(
Data::PeerUpdate::Flag::StickersSet Data::PeerUpdate::Flag::StickersSet

View file

@ -938,7 +938,7 @@ void TabbedSelector::Inner::panelHideFinished() {
} }
TabbedSelector::InnerFooter::InnerFooter(QWidget *parent) TabbedSelector::InnerFooter::InnerFooter(QWidget *parent)
: TWidget(parent) { : RpWidget(parent) {
resize(st::emojiPanWidth, st::emojiFooterHeight); resize(st::emojiPanWidth, st::emojiFooterHeight);
} }

View file

@ -276,7 +276,7 @@ private:
}; };
class TabbedSelector::InnerFooter : public TWidget { class TabbedSelector::InnerFooter : public Ui::RpWidget {
public: public:
InnerFooter(QWidget *parent); InnerFooter(QWidget *parent);

View file

@ -24,36 +24,43 @@ std::map<int, const char*> BetaLogs() {
return { return {
{ {
1009020, 1009020,
"\xE2\x80\xA2 Fix crash in shared links search.\n" "- Fix crash in shared links search.\n"
"\xE2\x80\xA2 Fix blurred thumbnails in albums with video files.\n" "- Fix blurred thumbnails in albums with video files.\n"
"\xE2\x80\xA2 Fix a possible crash in animated stickers rendering." "- Fix a possible crash in animated stickers rendering."
}, },
{ {
1009022, 1009022,
"\xE2\x80\xA2 Organize chats into Chat Folders " "- Organize chats into Chat Folders if you have too many chats.\n"
"if you have too many chats.\n"
}, },
{ {
2000001, 2000001,
"\xE2\x80\xA2 Switch between folders using Ctrl+1, ..., Ctrl+8.\n" "- Switch between folders using Ctrl+1, ..., Ctrl+8.\n"
"\xE2\x80\xA2 Fix crash when a pinned in folder chat " "- Fix crash when a pinned in folder chat was added to archive.\n"
"was added to archive.\n"
"\xE2\x80\xA2 Fix font issues in Linux version." "- Fix font issues in Linux version."
}, },
{ {
2001008, 2001008,
"\xE2\x80\xA2 Add support for full group message history export.\n" "- Add support for full group message history export.\n"
"\xE2\x80\xA2 Allow export of a single chat message history " "- Allow export of a single chat message history in JSON format."
"in JSON format."
}, },
{ {
2001014, 2001014,
"\xE2\x80\xA2 Support for multiple accounts." "- Support for multiple accounts."
},
{
2001017,
"- Fix messages editing in a non-active account.\n"
"- Fix large animated emoji messages editing.\n"
"- Fix high definition GIF animations opening in media viewer.\n"
"- Multiple crash fixes."
} }
}; };
}; };
@ -196,10 +203,18 @@ void Changelogs::addBetaLog(int changeVersion, const char *changes) {
if (_oldVersion >= changeVersion) { if (_oldVersion >= changeVersion) {
return; return;
} }
const auto text = [&] {
static const auto simple = u"\n- "_q;
static const auto separator = QString::fromUtf8("\n\xE2\x80\xA2 ");
auto result = QString::fromUtf8(changes).trimmed();
if (result.startsWith(simple.midRef(1))) {
result = separator.mid(1) + result.mid(simple.size() - 1);
}
return result.replace(simple, separator);
}();
const auto version = FormatVersionDisplay(changeVersion); const auto version = FormatVersionDisplay(changeVersion);
const auto text = qsl("New in version %1:\n\n").arg(version) const auto log = qsl("New in version %1:\n\n").arg(version) + text;
+ QString::fromUtf8(changes).trimmed(); addLocalLog(log);
addLocalLog(text);
} }
} // namespace Core } // namespace Core

View file

@ -458,7 +458,7 @@ void Settings::resetOnLastLogout() {
//_videoPipGeometry = QByteArray(); //_videoPipGeometry = QByteArray();
_dictionariesEnabled = std::vector<int>(); _dictionariesEnabled = std::vector<int>();
_autoDownloadDictionaries = true; _autoDownloadDictionaries = true;
_mainMenuAccountsShown = false; _mainMenuAccountsShown = true;
_tabbedSelectorSectionEnabled = false; // per-window _tabbedSelectorSectionEnabled = false; // per-window
_floatPlayerColumn = Window::Column::Second; // per-window _floatPlayerColumn = Window::Column::Second; // per-window
_floatPlayerCorner = RectPart::TopRight; // per-window _floatPlayerCorner = RectPart::TopRight; // per-window

View file

@ -464,7 +464,7 @@ private:
QByteArray _videoPipGeometry; QByteArray _videoPipGeometry;
rpl::variable<std::vector<int>> _dictionariesEnabled; rpl::variable<std::vector<int>> _dictionariesEnabled;
rpl::variable<bool> _autoDownloadDictionaries = true; rpl::variable<bool> _autoDownloadDictionaries = true;
rpl::variable<bool> _mainMenuAccountsShown = false; rpl::variable<bool> _mainMenuAccountsShown = true;
bool _tabbedSelectorSectionEnabled = false; // per-window bool _tabbedSelectorSectionEnabled = false; // per-window
Window::Column _floatPlayerColumn; // per-window Window::Column _floatPlayerColumn; // per-window
RectPart _floatPlayerCorner; // per-window RectPart _floatPlayerCorner; // per-window

View file

@ -282,6 +282,19 @@ void Launcher::init() {
prepareSettings(); prepareSettings();
static QtMessageHandler originalMessageHandler = nullptr;
originalMessageHandler = qInstallMessageHandler([](
QtMsgType type,
const QMessageLogContext &context,
const QString &msg) {
if (originalMessageHandler) {
originalMessageHandler(type, context, msg);
}
if (Logs::DebugEnabled() || !Logs::started()) {
LOG((msg));
}
});
QApplication::setApplicationName(qsl("KotatogramDesktop")); QApplication::setApplicationName(qsl("KotatogramDesktop"));
#if defined Q_OS_UNIX && !defined Q_OS_MAC && QT_VERSION >= QT_VERSION_CHECK(5, 7, 0) #if defined Q_OS_UNIX && !defined Q_OS_MAC && QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)

View file

@ -74,11 +74,11 @@ const auto CommandByName = base::flat_map<QString, Command>{
{ qsl("first_chat") , Command::ChatFirst }, { qsl("first_chat") , Command::ChatFirst },
{ qsl("last_chat") , Command::ChatLast }, { qsl("last_chat") , Command::ChatLast },
{ qsl("self_chat") , Command::ChatSelf }, { qsl("self_chat") , Command::ChatSelf },
{ qsl("previous_folder") , Command::FolderPrevious }, { qsl("previous_folder") , Command::FolderPrevious },
{ qsl("next_folder") , Command::FolderNext }, { qsl("next_folder") , Command::FolderNext },
{ qsl("all_chats") , Command::ShowAllChats }, { qsl("all_chats") , Command::ShowAllChats },
{ qsl("folder1") , Command::ShowFolder1 }, { qsl("folder1") , Command::ShowFolder1 },
{ qsl("folder2") , Command::ShowFolder2 }, { qsl("folder2") , Command::ShowFolder2 },
{ qsl("folder3") , Command::ShowFolder3 }, { qsl("folder3") , Command::ShowFolder3 },
@ -137,11 +137,11 @@ const auto CommandNames = base::flat_map<Command, QString>{
{ Command::ChatFirst , qsl("first_chat") }, { Command::ChatFirst , qsl("first_chat") },
{ Command::ChatLast , qsl("last_chat") }, { Command::ChatLast , qsl("last_chat") },
{ Command::ChatSelf , qsl("self_chat") }, { Command::ChatSelf , qsl("self_chat") },
{ Command::FolderPrevious , qsl("previous_folder") }, { Command::FolderPrevious , qsl("previous_folder") },
{ Command::FolderNext , qsl("next_folder") }, { Command::FolderNext , qsl("next_folder") },
{ Command::ShowAllChats , qsl("all_chats") }, { Command::ShowAllChats , qsl("all_chats") },
{ Command::ShowFolder1 , qsl("folder1") }, { Command::ShowFolder1 , qsl("folder1") },
{ Command::ShowFolder2 , qsl("folder2") }, { Command::ShowFolder2 , qsl("folder2") },
{ Command::ShowFolder3 , qsl("folder3") }, { Command::ShowFolder3 , qsl("folder3") },

View file

@ -10,7 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/const_string.h" #include "base/const_string.h"
#include "kotato/version.h" #include "kotato/version.h"
#define TDESKTOP_REQUESTED_ALPHA_VERSION (2001007004ULL) #define TDESKTOP_REQUESTED_ALPHA_VERSION (0ULL)
#ifdef TDESKTOP_ALLOW_CLOSED_ALPHA #ifdef TDESKTOP_ALLOW_CLOSED_ALPHA
#define TDESKTOP_ALPHA_VERSION TDESKTOP_REQUESTED_ALPHA_VERSION #define TDESKTOP_ALPHA_VERSION TDESKTOP_REQUESTED_ALPHA_VERSION
@ -23,7 +23,7 @@ constexpr auto AppId = "{C4A4AE8F-B9F7-4CC7-8A6C-BF7EEE87ACA5}"_cs;
constexpr auto AppNameOld = "Telegram Win (Unofficial)"_cs; constexpr auto AppNameOld = "Telegram Win (Unofficial)"_cs;
constexpr auto AppName = "Kotatogram Desktop"_cs; constexpr auto AppName = "Kotatogram Desktop"_cs;
constexpr auto AppFile = "Kotatogram"_cs; constexpr auto AppFile = "Kotatogram"_cs;
constexpr auto AppVersion = 2001016; constexpr auto AppVersion = 2001017;
constexpr auto AppVersionStr = "2.1.16"; constexpr auto AppVersionStr = "2.1.17";
constexpr auto AppBetaVersion = true; constexpr auto AppBetaVersion = true;
constexpr auto AppAlphaVersion = TDESKTOP_ALPHA_VERSION; constexpr auto AppAlphaVersion = TDESKTOP_ALPHA_VERSION;

View file

@ -26,7 +26,7 @@ void CloudImageView::set(
not_null<Main::Session*> session, not_null<Main::Session*> session,
QImage image) { QImage image) {
_image.emplace(std::move(image)); _image.emplace(std::move(image));
session->downloaderTaskFinished().notify(); session->notifyDownloaderTaskFinished();
} }
CloudImage::CloudImage() = default; CloudImage::CloudImage() = default;

View file

@ -222,8 +222,7 @@ void CloudThemes::loadDocumentAndInvoke(
return; return;
} }
if (!alreadyWaiting) { if (!alreadyWaiting) {
base::ObservableViewer( _session->downloaderTaskFinished(
_session->downloaderTaskFinished()
) | rpl::filter([=, &value] { ) | rpl::filter([=, &value] {
return value.documentMedia->loaded(); return value.documentMedia->loaded();
}) | rpl::start_with_next([=, &value] { }) | rpl::start_with_next([=, &value] {

View file

@ -31,6 +31,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "platform/platform_specific.h" #include "platform/platform_specific.h"
#include "history/history.h" #include "history/history.h"
#include "history/history_item.h" #include "history/history_item.h"
#include "history/view/media/history_view_gif.h"
#include "window/window_session_controller.h" #include "window/window_session_controller.h"
#include "storage/cache/storage_cache_database.h" #include "storage/cache/storage_cache_database.h"
#include "boxes/confirm_box.h" #include "boxes/confirm_box.h"
@ -340,7 +341,9 @@ void DocumentOpenClickHandler::Open(
|| data->isVideoMessage()) { || data->isVideoMessage()) {
const auto msgId = context ? context->fullId() : FullMsgId(); const auto msgId = context ? context->fullId() : FullMsgId();
Media::Player::instance()->playPause({ data, msgId }); Media::Player::instance()->playPause({ data, msgId });
} else if (context && data->isAnimation()) { } else if (context
&& data->isAnimation()
&& HistoryView::Gif::CanPlayInline(data)) {
data->owner().requestAnimationPlayInline(context); data->owner().requestAnimationPlayInline(context);
} else { } else {
Core::App().showDocument(data, context); Core::App().showDocument(data, context);

View file

@ -169,7 +169,7 @@ void DocumentMedia::setGoodThumbnail(QImage thumbnail) {
return; return;
} }
_goodThumbnail = std::make_unique<Image>(std::move(thumbnail)); _goodThumbnail = std::make_unique<Image>(std::move(thumbnail));
_owner->session().downloaderTaskFinished().notify(); _owner->session().notifyDownloaderTaskFinished();
} }
Image *DocumentMedia::thumbnailInline() const { Image *DocumentMedia::thumbnailInline() const {
@ -207,7 +207,7 @@ QSize DocumentMedia::thumbnailSize() const {
void DocumentMedia::setThumbnail(QImage thumbnail) { void DocumentMedia::setThumbnail(QImage thumbnail) {
_thumbnail = std::make_unique<Image>(std::move(thumbnail)); _thumbnail = std::make_unique<Image>(std::move(thumbnail));
_owner->session().downloaderTaskFinished().notify(); _owner->session().notifyDownloaderTaskFinished();
} }
QByteArray DocumentMedia::videoThumbnailContent() const { QByteArray DocumentMedia::videoThumbnailContent() const {

View file

@ -82,7 +82,7 @@ void PhotoMedia::set(PhotoSize size, QImage image) {
Qt::SmoothTransformation); Qt::SmoothTransformation);
} }
_images[index] = std::make_unique<Image>(std::move(image)); _images[index] = std::make_unique<Image>(std::move(image));
_owner->session().downloaderTaskFinished().notify(); _owner->session().notifyDownloaderTaskFinished();
} }
bool PhotoMedia::loaded() const { bool PhotoMedia::loaded() const {

View file

@ -1279,7 +1279,8 @@ rpl::producer<not_null<ViewElement*>> Session::viewResizeRequest() const {
void Session::requestItemViewRefresh(not_null<HistoryItem*> item) { void Session::requestItemViewRefresh(not_null<HistoryItem*> item) {
if (const auto view = item->mainView()) { if (const auto view = item->mainView()) {
view->setPendingResize(); notifyHistoryChangeDelayed(item->history());
view->refreshInBlock();
} }
_itemViewRefreshRequest.fire_copy(item); _itemViewRefreshRequest.fire_copy(item);
} }

View file

@ -34,7 +34,7 @@ void StickersSetThumbnailView::set(
} else { } else {
_image = std::make_unique<Image>(std::move(image)); _image = std::make_unique<Image>(std::move(image));
} }
session->downloaderTaskFinished().notify(); session->notifyDownloaderTaskFinished();
} }
Image *StickersSetThumbnailView::image() const { Image *StickersSetThumbnailView::image() const {

View file

@ -140,7 +140,10 @@ InnerWidget::InnerWidget(
}); });
_cancelSearchFromUser->hide(); _cancelSearchFromUser->hide();
subscribe(session().downloaderTaskFinished(), [=] { update(); }); session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
}, lifetime());
subscribe(Core::App().notifications().settingsChanged(), [=]( subscribe(Core::App().notifications().settingsChanged(), [=](
Window::Notifications::ChangeType change) { Window::Notifications::ChangeType change) {

View file

@ -161,7 +161,8 @@ void Widget::BottomButton::paintEvent(QPaintEvent *e) {
Widget::Widget( Widget::Widget(
QWidget *parent, QWidget *parent,
not_null<Window::SessionController*> controller) not_null<Window::SessionController*> controller)
: Window::AbstractSectionWidget(parent, controller) : Window::AbstractSectionWidget(parent, controller)
, _api(&controller->session().mtp())
, _searchControls(this) , _searchControls(this)
, _mainMenuToggle(_searchControls, st::dialogsMenuToggle) , _mainMenuToggle(_searchControls, st::dialogsMenuToggle)
, _searchForNarrowFilters(_searchControls, st::dialogsSearchForNarrowFilters) , _searchForNarrowFilters(_searchControls, st::dialogsSearchForNarrowFilters)
@ -435,7 +436,9 @@ void Widget::fullSearchRefreshOn(rpl::producer<> events) {
_searchTimer.stop(); _searchTimer.stop();
_searchCache.clear(); _searchCache.clear();
_singleMessageSearch.clear(); _singleMessageSearch.clear();
_searchQueries.clear(); for (const auto &[requestId, query] : base::take(_searchQueries)) {
session().api().request(requestId).cancel();
}
_searchQuery = QString(); _searchQuery = QString();
_scroll->scrollToY(0); _scroll->scrollToY(0);
cancelSearchRequest(); cancelSearchRequest();
@ -771,7 +774,7 @@ bool Widget::onSearchMessages(bool searchCache) {
auto q = _filter->getLastText().trimmed(); auto q = _filter->getLastText().trimmed();
if (q.isEmpty() && !_searchFromUser) { if (q.isEmpty() && !_searchFromUser) {
cancelSearchRequest(); cancelSearchRequest();
session().api().request(base::take(_peerSearchRequest)).cancel(); _api.request(base::take(_peerSearchRequest)).cancel();
return true; return true;
} }
if (searchCache) { if (searchCache) {
@ -781,8 +784,8 @@ bool Widget::onSearchMessages(bool searchCache) {
if (!success) { if (!success) {
return false; return false;
} }
const auto i = _searchCache.constFind(q); const auto i = _searchCache.find(q);
if (i != _searchCache.cend()) { if (i != _searchCache.end()) {
_searchQuery = q; _searchQuery = q;
_searchQueryFrom = _searchFromUser; _searchQueryFrom = _searchFromUser;
_searchNextRate = 0; _searchNextRate = 0;
@ -792,7 +795,7 @@ bool Widget::onSearchMessages(bool searchCache) {
_searchInChat _searchInChat
? SearchRequestType::PeerFromStart ? SearchRequestType::PeerFromStart
: SearchRequestType::FromStart, : SearchRequestType::FromStart,
i.value(), i->second,
0); 0);
result = true; result = true;
} }
@ -836,7 +839,7 @@ bool Widget::onSearchMessages(bool searchCache) {
_searchInHistoryRequest = 0; _searchInHistoryRequest = 0;
finish(); finish();
}).send(); }).send();
_searchQueries.insert(_searchRequest, _searchQuery); _searchQueries.emplace(_searchRequest, _searchQuery);
return _searchRequest; return _searchRequest;
}); });
//} else if (const auto feed = _searchInChat.feed()) { // #feed //} else if (const auto feed = _searchInChat.feed()) { // #feed
@ -853,7 +856,7 @@ bool Widget::onSearchMessages(bool searchCache) {
// }).fail([=](const RPCError &error) { // }).fail([=](const RPCError &error) {
// searchFailed(type, error, _searchRequest); // searchFailed(type, error, _searchRequest);
// }).send(); // }).send();
// _searchQueries.insert(_searchRequest, _searchQuery); // _searchQueries.emplace(_searchRequest, _searchQuery);
} else { } else {
const auto type = SearchRequestType::FromStart; const auto type = SearchRequestType::FromStart;
const auto flags = session().settings().skipArchiveInSearch() const auto flags = session().settings().skipArchiveInSearch()
@ -873,23 +876,23 @@ bool Widget::onSearchMessages(bool searchCache) {
}).fail([=](const RPCError &error) { }).fail([=](const RPCError &error) {
searchFailed(type, error, _searchRequest); searchFailed(type, error, _searchRequest);
}).send(); }).send();
_searchQueries.insert(_searchRequest, _searchQuery); _searchQueries.emplace(_searchRequest, _searchQuery);
} }
} }
const auto query = Api::ConvertPeerSearchQuery(q); const auto query = Api::ConvertPeerSearchQuery(q);
if (searchForPeersRequired(query)) { if (searchForPeersRequired(query)) {
if (searchCache) { if (searchCache) {
auto i = _peerSearchCache.constFind(query); auto i = _peerSearchCache.find(query);
if (i != _peerSearchCache.cend()) { if (i != _peerSearchCache.end()) {
_peerSearchQuery = query; _peerSearchQuery = query;
_peerSearchRequest = 0; _peerSearchRequest = 0;
peerSearchReceived(i.value(), 0); peerSearchReceived(i->second, 0);
result = true; result = true;
} }
} else if (_peerSearchQuery != query) { } else if (_peerSearchQuery != query) {
_peerSearchQuery = query; _peerSearchQuery = query;
_peerSearchFull = false; _peerSearchFull = false;
_peerSearchRequest = session().api().request(MTPcontacts_Search( _peerSearchRequest = _api.request(MTPcontacts_Search(
MTP_string(_peerSearchQuery), MTP_string(_peerSearchQuery),
MTP_int(SearchPeopleLimit) MTP_int(SearchPeopleLimit)
)).done([=](const MTPcontacts_Found &result, mtpRequestId requestId) { )).done([=](const MTPcontacts_Found &result, mtpRequestId requestId) {
@ -897,7 +900,7 @@ bool Widget::onSearchMessages(bool searchCache) {
}).fail([=](const RPCError &error, mtpRequestId requestId) { }).fail([=](const RPCError &error, mtpRequestId requestId) {
peopleFailed(error, requestId); peopleFailed(error, requestId);
}).send(); }).send();
_peerSearchQueries.insert(_peerSearchRequest, _peerSearchQuery); _peerSearchQueries.emplace(_peerSearchRequest, _peerSearchQuery);
} }
} else { } else {
_peerSearchQuery = query; _peerSearchQuery = query;
@ -1013,7 +1016,7 @@ void Widget::onSearchMore() {
finish(); finish();
}).send(); }).send();
if (!offsetId) { if (!offsetId) {
_searchQueries.insert(_searchRequest, _searchQuery); _searchQueries.emplace(_searchRequest, _searchQuery);
} }
return _searchRequest; return _searchRequest;
}); });
@ -1036,7 +1039,7 @@ void Widget::onSearchMore() {
// searchFailed(type, error, _searchRequest); // searchFailed(type, error, _searchRequest);
// }).send(); // }).send();
// if (!offsetId) { // if (!offsetId) {
// _searchQueries.insert(_searchRequest, _searchQuery); // _searchQueries.emplace(_searchRequest, _searchQuery);
// } // }
} else { } else {
const auto type = offsetId const auto type = offsetId
@ -1062,7 +1065,7 @@ void Widget::onSearchMore() {
searchFailed(type, error, _searchRequest); searchFailed(type, error, _searchRequest);
}).send(); }).send();
if (!offsetId) { if (!offsetId) {
_searchQueries.insert(_searchRequest, _searchQuery); _searchQueries.emplace(_searchRequest, _searchQuery);
} }
} }
} else if (_searchInMigrated && !_searchFullMigrated) { } else if (_searchInMigrated && !_searchFullMigrated) {
@ -1115,8 +1118,8 @@ void Widget::searchReceived(
if (state == WidgetState::Filtered) { if (state == WidgetState::Filtered) {
if (type == SearchRequestType::FromStart || type == SearchRequestType::PeerFromStart) { if (type == SearchRequestType::FromStart || type == SearchRequestType::PeerFromStart) {
auto i = _searchQueries.find(requestId); auto i = _searchQueries.find(requestId);
if (i != _searchQueries.cend()) { if (i != _searchQueries.end()) {
_searchCache[i.value()] = result; _searchCache[i->second] = result;
_searchQueries.erase(i); _searchQueries.erase(i);
} }
} }
@ -1224,9 +1227,8 @@ void Widget::peerSearchReceived(
auto q = _peerSearchQuery; auto q = _peerSearchQuery;
if (state == WidgetState::Filtered) { if (state == WidgetState::Filtered) {
auto i = _peerSearchQueries.find(requestId); auto i = _peerSearchQueries.find(requestId);
if (i != _peerSearchQueries.cend()) { if (i != _peerSearchQueries.end()) {
q = i.value(); _peerSearchCache[i->second] = result;
_peerSearchCache[q] = result;
_peerSearchQueries.erase(i); _peerSearchQueries.erase(i);
} }
} }
@ -1368,7 +1370,9 @@ void Widget::applyFilterUpdate(bool force) {
if (filterText.isEmpty()) { if (filterText.isEmpty()) {
_peerSearchCache.clear(); _peerSearchCache.clear();
_peerSearchQueries.clear(); for (const auto &[requestId, query] : base::take(_peerSearchQueries)) {
_api.request(requestId).cancel();
}
_peerSearchQuery = QString(); _peerSearchQuery = QString();
} }
@ -1425,7 +1429,9 @@ void Widget::setSearchInChat(Key chat, UserData *from) {
void Widget::clearSearchCache() { void Widget::clearSearchCache() {
_searchCache.clear(); _searchCache.clear();
_singleMessageSearch.clear(); _singleMessageSearch.clear();
_searchQueries.clear(); for (const auto &[requestId, query] : base::take(_searchQueries)) {
session().api().request(requestId).cancel();
}
_searchQuery = QString(); _searchQuery = QString();
_searchQueryFrom = nullptr; _searchQueryFrom = nullptr;
cancelSearchRequest(); cancelSearchRequest();
@ -1729,10 +1735,8 @@ void Widget::scrollToEntry(const RowDescriptor &entry) {
void Widget::cancelSearchRequest() { void Widget::cancelSearchRequest() {
session().api().request(base::take(_searchRequest)).cancel(); session().api().request(base::take(_searchRequest)).cancel();
if (_searchInHistoryRequest) { session().data().histories().cancelRequest(
session().data().histories().cancelRequest(_searchInHistoryRequest); base::take(_searchInHistoryRequest));
_searchInHistoryRequest = 0;
}
} }
bool Widget::onCancelSearch() { bool Widget::onCancelSearch() {

View file

@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/effects/animations.h" #include "ui/effects/animations.h"
#include "ui/widgets/scroll_area.h" #include "ui/widgets/scroll_area.h"
#include "ui/special_buttons.h" #include "ui/special_buttons.h"
#include "mtproto/sender.h"
#include "api/api_single_message_search.h" #include "api/api_single_message_search.h"
class RPCError; class RPCError;
@ -174,6 +175,8 @@ private:
void startScrollUpButtonAnimation(bool shown); void startScrollUpButtonAnimation(bool shown);
void updateScrollUpPosition(); void updateScrollUpPosition();
MTP::Sender _api;
bool _dragInScroll = false; bool _dragInScroll = false;
bool _dragForward = false; bool _dragForward = false;
QTimer _chooseByDragTimer; QTimer _chooseByDragTimer;
@ -225,11 +228,11 @@ private:
int _searchInHistoryRequest = 0; // Not real mtpRequestId. int _searchInHistoryRequest = 0; // Not real mtpRequestId.
mtpRequestId _searchRequest = 0; mtpRequestId _searchRequest = 0;
QMap<QString, MTPmessages_Messages> _searchCache; base::flat_map<QString, MTPmessages_Messages> _searchCache;
Api::SingleMessageSearch _singleMessageSearch; Api::SingleMessageSearch _singleMessageSearch;
QMap<mtpRequestId, QString> _searchQueries; base::flat_map<mtpRequestId, QString> _searchQueries;
QMap<QString, MTPcontacts_Found> _peerSearchCache; base::flat_map<QString, MTPcontacts_Found> _peerSearchCache;
QMap<mtpRequestId, QString> _peerSearchQueries; base::flat_map<mtpRequestId, QString> _peerSearchQueries;
QPixmap _widthAnimationCache; QPixmap _widthAnimationCache;

View file

@ -230,6 +230,7 @@ void showPeerProfile(not_null<PeerData*> peer) {
if (const auto controller = window->sessionController()) { if (const auto controller = window->sessionController()) {
if (&controller->session() == &peer->session()) { if (&controller->session() == &peer->session()) {
controller->showPeerInfo(peer); controller->showPeerInfo(peer);
return;
} }
} }
if (&Core::App().domain().active() != &peer->session().account()) { if (&Core::App().domain().active() != &peer->session().account()) {

View file

@ -178,10 +178,6 @@ HistoryInner::HistoryInner(
) | rpl::start_with_next( ) | rpl::start_with_next(
[this](auto view) { viewRemoved(view); }, [this](auto view) { viewRemoved(view); },
lifetime()); lifetime());
session().data().itemViewRefreshRequest(
) | rpl::start_with_next(
[this](auto item) { refreshView(item); },
lifetime());
rpl::merge( rpl::merge(
session().data().historyUnloaded(), session().data().historyUnloaded(),
session().data().historyCleared() session().data().historyCleared()
@ -1316,32 +1312,15 @@ void HistoryInner::itemRemoved(not_null<const HistoryItem*> item) {
} }
void HistoryInner::viewRemoved(not_null<const Element*> view) { void HistoryInner::viewRemoved(not_null<const Element*> view) {
if (_dragSelFrom == view) { const auto refresh = [&](auto &saved) {
_dragSelFrom = nullptr; if (saved == view) {
} const auto now = view->data()->mainView();
if (_dragSelTo == view) { saved = (now && now != view) ? now : nullptr;
_dragSelTo = nullptr; }
} };
if (_scrollDateLastItem == view) { refresh(_dragSelFrom);
_scrollDateLastItem = nullptr; refresh(_dragSelTo);
} refresh(_scrollDateLastItem);
}
void HistoryInner::refreshView(not_null<HistoryItem*> item) {
const auto dragSelFrom = (_dragSelFrom && _dragSelFrom->data() == item);
const auto dragSelTo = (_dragSelTo && _dragSelTo->data() == item);
const auto scrollDateLastItem = (_scrollDateLastItem
&& _scrollDateLastItem->data() == item);
item->refreshMainView();
if (dragSelFrom) {
_dragSelFrom = item->mainView();
}
if (dragSelTo) {
_dragSelTo = item->mainView();
}
if (scrollDateLastItem) {
_scrollDateLastItem = item->mainView();
}
} }
void HistoryInner::mouseActionFinish( void HistoryInner::mouseActionFinish(

View file

@ -239,7 +239,6 @@ private:
void itemRemoved(not_null<const HistoryItem*> item); void itemRemoved(not_null<const HistoryItem*> item);
void viewRemoved(not_null<const Element*> view); void viewRemoved(not_null<const Element*> view);
void refreshView(not_null<HistoryItem*> item);
void touchResetSpeed(); void touchResetSpeed();
void touchUpdateSpeed(); void touchUpdateSpeed();

View file

@ -307,7 +307,11 @@ HistoryWidget::HistoryWidget(
, _topShadow(this) { , _topShadow(this) {
setAcceptDrops(true); setAcceptDrops(true);
subscribe(session().downloaderTaskFinished(), [=] { update(); }); session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
}, lifetime());
connect(_scroll, SIGNAL(scrolled()), this, SLOT(onScroll())); connect(_scroll, SIGNAL(scrolled()), this, SLOT(onScroll()));
_historyDown->addClickHandler([=] { historyDownClicked(); }); _historyDown->addClickHandler([=] { historyDownClicked(); });
_unreadMentions->addClickHandler([=] { showNextUnreadMention(); }); _unreadMentions->addClickHandler([=] { showNextUnreadMention(); });
@ -500,15 +504,6 @@ HistoryWidget::HistoryWidget(
} }
}, lifetime()); }, lifetime());
session().data().itemViewRefreshRequest(
) | rpl::start_with_next([=](not_null<HistoryItem*> item) {
// While HistoryInner doesn't own item views we must refresh them
// even if the list is not yet created / was destroyed.
if (!_list) {
item->refreshMainView();
}
}, lifetime());
Core::App().settings().largeEmojiChanges( Core::App().settings().largeEmojiChanges(
) | rpl::start_with_next([=] { ) | rpl::start_with_next([=] {
crl::on_main(this, [=] { crl::on_main(this, [=] {

View file

@ -577,6 +577,9 @@ void TopBarWidget::updateSearchVisibility() {
} }
void TopBarWidget::updateControlsGeometry() { void TopBarWidget::updateControlsGeometry() {
if (!_activeChat) {
return;
}
auto hasSelected = (_selectedCount > 0); auto hasSelected = (_selectedCount > 0);
auto selectedButtonsTop = countSelectedButtonsTop(_selectedShown.value(hasSelected ? 1. : 0.)); auto selectedButtonsTop = countSelectedButtonsTop(_selectedShown.value(hasSelected ? 1. : 0.));
auto otherButtonsTop = selectedButtonsTop + st::topBarHeight; auto otherButtonsTop = selectedButtonsTop + st::topBarHeight;
@ -663,7 +666,9 @@ void TopBarWidget::setAnimatingMode(bool enabled) {
} }
void TopBarWidget::updateControlsVisibility() { void TopBarWidget::updateControlsVisibility() {
if (_animatingMode) { if (!_activeChat) {
return;
} else if (_animatingMode) {
hideChildren(); hideChildren();
return; return;
} }
@ -708,14 +713,12 @@ void TopBarWidget::updateControlsVisibility() {
void TopBarWidget::updateMembersShowArea() { void TopBarWidget::updateMembersShowArea() {
const auto membersShowAreaNeeded = [&] { const auto membersShowAreaNeeded = [&] {
auto peer = _controller->content()->peer(); const auto peer = _activeChat.peer();
if ((_selectedCount > 0) || !peer) { if ((_selectedCount > 0) || !peer) {
return false; return false;
} } else if (const auto chat = peer->asChat()) {
if (auto chat = peer->asChat()) {
return chat->amIn(); return chat->amIn();
} } else if (const auto megagroup = peer->asMegagroup()) {
if (auto megagroup = peer->asMegagroup()) {
return megagroup->canViewMembers() return megagroup->canViewMembers()
&& (megagroup->membersCount() && (megagroup->membersCount()
< megagroup->session().serverConfig().chatSizeMax); < megagroup->session().serverConfig().chatSizeMax);

View file

@ -51,11 +51,6 @@ int gifMaxStatusWidth(DocumentData *document) {
return result; return result;
} }
[[nodiscard]] bool CanPlayInline(not_null<DocumentData*> document) {
const auto dimensions = document->dimensions;
return dimensions.width() * dimensions.height() <= kMaxInlineArea;
}
} // namespace } // namespace
struct Gif::Streamed { struct Gif::Streamed {
@ -110,6 +105,11 @@ Gif::~Gif() {
} }
} }
bool Gif::CanPlayInline(not_null<DocumentData*> document) {
const auto dimensions = document->dimensions;
return dimensions.width() * dimensions.height() <= kMaxInlineArea;
}
QSize Gif::sizeForAspectRatio() const { QSize Gif::sizeForAspectRatio() const {
// We use size only for aspect ratio and we want to have it // We use size only for aspect ratio and we want to have it
// as close to the thumbnail as possible. // as close to the thumbnail as possible.

View file

@ -110,6 +110,8 @@ public:
void refreshParentId(not_null<HistoryItem*> realParent) override; void refreshParentId(not_null<HistoryItem*> realParent) override;
[[nodiscard]] static bool CanPlayInline(not_null<DocumentData*> document);
private: private:
struct Streamed; struct Streamed;

View file

@ -172,7 +172,9 @@ PointState Media::pointState(QPoint point) const {
: PointState::Outside; : PointState::Outside;
} }
std::unique_ptr<Lottie::SinglePlayer> Media::stickerTakeLottie() { std::unique_ptr<Lottie::SinglePlayer> Media::stickerTakeLottie(
not_null<DocumentData*> data,
const Lottie::ColorReplacements *replacements) {
return nullptr; return nullptr;
} }

View file

@ -26,6 +26,7 @@ using SharedMediaTypesMask = base::enum_mask<SharedMediaType>;
namespace Lottie { namespace Lottie {
class SinglePlayer; class SinglePlayer;
struct ColorReplacements;
} // namespace Lottie } // namespace Lottie
namespace HistoryView { namespace HistoryView {
@ -145,7 +146,9 @@ public:
} }
virtual void stickerClearLoopPlayed() { virtual void stickerClearLoopPlayed() {
} }
virtual std::unique_ptr<Lottie::SinglePlayer> stickerTakeLottie(); virtual std::unique_ptr<Lottie::SinglePlayer> stickerTakeLottie(
not_null<DocumentData*> data,
const Lottie::ColorReplacements *replacements);
virtual void checkAnimation() { virtual void checkAnimation() {
} }

View file

@ -28,7 +28,9 @@ constexpr auto kMaxForwardedBarLines = 4;
} // namespace } // namespace
auto UnwrappedMedia::Content::stickerTakeLottie() auto UnwrappedMedia::Content::stickerTakeLottie(
not_null<DocumentData*> data,
const Lottie::ColorReplacements *replacements)
-> std::unique_ptr<Lottie::SinglePlayer> { -> std::unique_ptr<Lottie::SinglePlayer> {
return nullptr; return nullptr;
} }
@ -394,8 +396,10 @@ TextState UnwrappedMedia::textState(QPoint point, StateRequest request) const {
return result; return result;
} }
std::unique_ptr<Lottie::SinglePlayer> UnwrappedMedia::stickerTakeLottie() { std::unique_ptr<Lottie::SinglePlayer> UnwrappedMedia::stickerTakeLottie(
return _content->stickerTakeLottie(); not_null<DocumentData*> data,
const Lottie::ColorReplacements *replacements) {
return _content->stickerTakeLottie(data, replacements);
} }
int UnwrappedMedia::calculateFullRight(const QRect &inner) const { int UnwrappedMedia::calculateFullRight(const QRect &inner) const {

View file

@ -34,7 +34,9 @@ public:
} }
virtual void stickerClearLoopPlayed() { virtual void stickerClearLoopPlayed() {
} }
virtual std::unique_ptr<Lottie::SinglePlayer> stickerTakeLottie(); virtual std::unique_ptr<Lottie::SinglePlayer> stickerTakeLottie(
not_null<DocumentData*> data,
const Lottie::ColorReplacements *replacements);
virtual bool hasHeavyPart() const { virtual bool hasHeavyPart() const {
return false; return false;
} }
@ -85,7 +87,9 @@ public:
void stickerClearLoopPlayed() override { void stickerClearLoopPlayed() override {
_content->stickerClearLoopPlayed(); _content->stickerClearLoopPlayed();
} }
std::unique_ptr<Lottie::SinglePlayer> stickerTakeLottie() override; std::unique_ptr<Lottie::SinglePlayer> stickerTakeLottie(
not_null<DocumentData*> data,
const Lottie::ColorReplacements *replacements) override;
bool hasHeavyPart() const override { bool hasHeavyPart() const override {
return _content->hasHeavyPart(); return _content->hasHeavyPart();

View file

@ -71,7 +71,7 @@ Sticker::Sticker(
_data->loadThumbnail(parent->data()->fullId()); _data->loadThumbnail(parent->data()->fullId());
} }
if (const auto media = replacing ? replacing->media() : nullptr) { if (const auto media = replacing ? replacing->media() : nullptr) {
_lottie = media->stickerTakeLottie(); _lottie = media->stickerTakeLottie(_data, _replacements);
if (_lottie) { if (_lottie) {
lottieCreated(); lottieCreated();
} }
@ -344,8 +344,12 @@ void Sticker::unloadLottie() {
_parent->checkHeavyPart(); _parent->checkHeavyPart();
} }
std::unique_ptr< Lottie::SinglePlayer> Sticker::stickerTakeLottie() { std::unique_ptr<Lottie::SinglePlayer> Sticker::stickerTakeLottie(
return std::move(_lottie); not_null<DocumentData*> data,
const Lottie::ColorReplacements *replacements) {
return (data == _data && replacements == _replacements)
? std::move(_lottie)
: nullptr;
} }
} // namespace HistoryView } // namespace HistoryView

View file

@ -50,7 +50,9 @@ public:
void stickerClearLoopPlayed() override { void stickerClearLoopPlayed() override {
_lottieOncePlayed = false; _lottieOncePlayed = false;
} }
std::unique_ptr<Lottie::SinglePlayer> stickerTakeLottie() override; std::unique_ptr<Lottie::SinglePlayer> stickerTakeLottie(
not_null<DocumentData*> data,
const Lottie::ColorReplacements *replacements) override;
bool hasHeavyPart() const override; bool hasHeavyPart() const override;
void unloadHeavyPart() override; void unloadHeavyPart() override;

View file

@ -590,21 +590,27 @@ void ListWidget::start() {
invalidatePaletteCache(); invalidatePaletteCache();
} }
}, lifetime()); }, lifetime());
ObservableViewer(
session().downloaderTaskFinished() session().downloaderTaskFinished(
) | rpl::start_with_next([this] { update(); }, lifetime()); ) | rpl::start_with_next([=] {
update();
}, lifetime());
session().data().itemLayoutChanged( session().data().itemLayoutChanged(
) | rpl::start_with_next([this](auto item) { ) | rpl::start_with_next([this](auto item) {
itemLayoutChanged(item); itemLayoutChanged(item);
}, lifetime()); }, lifetime());
session().data().itemRemoved( session().data().itemRemoved(
) | rpl::start_with_next([this](auto item) { ) | rpl::start_with_next([this](auto item) {
itemRemoved(item); itemRemoved(item);
}, lifetime()); }, lifetime());
session().data().itemRepaintRequest( session().data().itemRepaintRequest(
) | rpl::start_with_next([this](auto item) { ) | rpl::start_with_next([this](auto item) {
repaintItem(item); repaintItem(item);
}, lifetime()); }, lifetime());
_controller->mediaSourceQueryValue( _controller->mediaSourceQueryValue(
) | rpl::start_with_next([this]{ ) | rpl::start_with_next([this]{
restart(); restart();

View file

@ -681,7 +681,7 @@ void ActionsFiller::addClearHistoryAction(not_null<UserData*> user) {
_wrap, _wrap,
tr::lng_profile_clear_history(), tr::lng_profile_clear_history(),
rpl::single(true), rpl::single(true),
Window::ClearHistoryHandler(user)); Window::ClearHistoryHandler(user));
} }
void ActionsFiller::addDeleteConversationAction( void ActionsFiller::addDeleteConversationAction(

View file

@ -58,9 +58,11 @@ Inner::Inner(
setMouseTracking(true); setMouseTracking(true);
setAttribute(Qt::WA_OpaquePaintEvent); setAttribute(Qt::WA_OpaquePaintEvent);
subscribe(_controller->session().downloaderTaskFinished(), [this] { _controller->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update(); update();
}); }, lifetime());
subscribe(controller->gifPauseLevelChanged(), [this] { subscribe(controller->gifPauseLevelChanged(), [this] {
if (!_controller->isGifPausedAtLeastFor(Window::GifPauseReason::InlineResults)) { if (!_controller->isGifPausedAtLeastFor(Window::GifPauseReason::InlineResults)) {
update(); update();

View file

@ -187,16 +187,18 @@ void PasswordCheckWidget::requestPasswordData() {
).done([=](const MTPaccount_Password &result) { ).done([=](const MTPaccount_Password &result) {
_sentRequest = 0; _sentRequest = 0;
result.match([&](const MTPDaccount_password &data) { result.match([&](const MTPDaccount_password &data) {
_request = Core::ParseCloudPasswordCheckRequest(data); auto request = Core::ParseCloudPasswordCheckRequest(data);
if (request && request.id) {
_request = std::move(request);
} else {
// Maybe the password was removed? Just submit it once again.
}
passwordChecked(); passwordChecked();
}); });
}).send(); }).send();
} }
void PasswordCheckWidget::passwordChecked() { void PasswordCheckWidget::passwordChecked() {
if (!_request || !_request.id) {
return serverError();
}
const auto check = Core::ComputeCloudPasswordCheck( const auto check = Core::ComputeCloudPasswordCheck(
_request, _request,
_passwordHash); _passwordHash);

View file

@ -725,6 +725,9 @@ void Widget::paintEvent(QPaintEvent *e) {
} }
void Widget::resizeEvent(QResizeEvent *e) { void Widget::resizeEvent(QResizeEvent *e) {
if (_stepHistory.empty()) {
return;
}
for (const auto step : _stepHistory) { for (const auto step : _stepHistory) {
step->setGeometry(rect()); step->setGeometry(rect());
} }

View file

@ -542,7 +542,7 @@ void CloudManager::performSwitchToCustom() {
}; };
const auto text = tr::lng_sure_save_language(tr::now) const auto text = tr::lng_sure_save_language(tr::now)
+ "\n\n" + "\n\n"
+ getValue(tr::lng_sure_save_language.base); + getValue(tr::lng_sure_save_language.base);
const auto change = [=] { const auto change = [=] {
_langpack.switchToCustomFile(filePath); _langpack.switchToCustomFile(filePath);
App::restart(); App::restart();

View file

@ -270,6 +270,13 @@ not_null<Main::Account*> Domain::add(MTP::Environment environment) {
_local->startAdded(account, std::move(config)); _local->startAdded(account, std::move(config));
watchSession(account); watchSession(account);
_accountsChanges.fire({}); _accountsChanges.fire({});
auto &settings = Core::App().settings();
if (_accounts.size() == 2 && !settings.mainMenuAccountsShown()) {
settings.setMainMenuAccountsShown(true);
Core::App().saveSettingsDelayed();
}
return account; return account;
} }

View file

@ -181,7 +181,11 @@ Storage::Domain &Session::domainLocal() const {
return _account->domainLocal(); return _account->domainLocal();
} }
base::Observable<void> &Session::downloaderTaskFinished() { void Session::notifyDownloaderTaskFinished() {
downloader().notifyTaskFinished();
}
rpl::producer<> Session::downloaderTaskFinished() const {
return downloader().taskFinished(); return downloader().taskFinished();
} }

View file

@ -121,7 +121,8 @@ public:
-> const base::flat_set<not_null<Window::SessionController*>> &; -> const base::flat_set<not_null<Window::SessionController*>> &;
// Shortcuts. // Shortcuts.
[[nodiscard]] base::Observable<void> &downloaderTaskFinished(); void notifyDownloaderTaskFinished();
[[nodiscard]] rpl::producer<> downloaderTaskFinished() const;
[[nodiscard]] MTP::DcId mainDcId() const; [[nodiscard]] MTP::DcId mainDcId() const;
[[nodiscard]] MTP::Instance &mtp() const; [[nodiscard]] MTP::Instance &mtp() const;
[[nodiscard]] const MTP::ConfigFields &serverConfig() const; [[nodiscard]] const MTP::ConfigFields &serverConfig() const;

View file

@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "media/audio/media_child_ffmpeg_loader.h" #include "media/audio/media_child_ffmpeg_loader.h"
#include "media/audio/media_audio_loaders.h" #include "media/audio/media_audio_loaders.h"
#include "media/audio/media_audio_track.h" #include "media/audio/media_audio_track.h"
#include "media/audio/media_openal_functions.h"
#include "media/streaming/media_streaming_utility.h" #include "media/streaming/media_streaming_utility.h"
#include "data/data_document.h" #include "data/data_document.h"
#include "data/data_file_origin.h" #include "data/data_file_origin.h"
@ -22,9 +23,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <al.h> #include <al.h>
#include <alc.h> #include <alc.h>
#ifndef TDESKTOP_DISABLE_OPENAL_EFFECTS
#include <alext.h>
#endif // !TDESKTOP_DISABLE_OPENAL_EFFECTS
#include <numeric> #include <numeric>
@ -205,6 +203,7 @@ void Start(not_null<Instance*> instance) {
auto loglevel = getenv("ALSOFT_LOGLEVEL"); auto loglevel = getenv("ALSOFT_LOGLEVEL");
LOG(("OpenAL Logging Level: %1").arg(loglevel ? loglevel : "(not set)")); LOG(("OpenAL Logging Level: %1").arg(loglevel ? loglevel : "(not set)"));
OpenAL::LoadEFXExtension();
EnumeratePlaybackDevices(); EnumeratePlaybackDevices();
EnumerateCaptureDevices(); EnumerateCaptureDevices();
@ -281,11 +280,7 @@ void StopDetachIfNotUsedSafe() {
} }
bool SupportsSpeedControl() { bool SupportsSpeedControl() {
#ifndef TDESKTOP_DISABLE_OPENAL_EFFECTS return OpenAL::HasEFXExtension();
return true;
#else // TDESKTOP_DISABLE_OPENAL_EFFECTS
return false;
#endif // TDESKTOP_DISABLE_OPENAL_EFFECTS
} }
} // namespace Audio } // namespace Audio
@ -331,40 +326,44 @@ void Mixer::Track::createStream(AudioMsgId::Type type) {
alSourcei(stream.source, AL_SOURCE_RELATIVE, 1); alSourcei(stream.source, AL_SOURCE_RELATIVE, 1);
alSourcei(stream.source, AL_ROLLOFF_FACTOR, 0); alSourcei(stream.source, AL_ROLLOFF_FACTOR, 0);
alGenBuffers(3, stream.buffers); alGenBuffers(3, stream.buffers);
#ifndef TDESKTOP_DISABLE_OPENAL_EFFECTS
if (speedEffect) { if (speedEffect) {
applySourceSpeedEffect(); applySourceSpeedEffect();
} else { } else {
removeSourceSpeedEffect(); removeSourceSpeedEffect();
} }
#endif // TDESKTOP_DISABLE_OPENAL_EFFECTS
} }
#ifndef TDESKTOP_DISABLE_OPENAL_EFFECTS
void Mixer::Track::removeSourceSpeedEffect() { void Mixer::Track::removeSourceSpeedEffect() {
alSource3i(stream.source, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, 0); if (!Audio::SupportsSpeedControl()) {
alSourcei(stream.source, AL_DIRECT_FILTER, AL_FILTER_NULL); return;
}
alSource3i(stream.source, alGetEnumValue("AL_AUXILIARY_SEND_FILTER"), alGetEnumValue("AL_EFFECTSLOT_NULL"), 0, 0);
alSourcei(stream.source, alGetEnumValue("AL_DIRECT_FILTER"), alGetEnumValue("AL_FILTER_NULL"));
alSourcef(stream.source, AL_PITCH, 1.f); alSourcef(stream.source, AL_PITCH, 1.f);
} }
void Mixer::Track::applySourceSpeedEffect() { void Mixer::Track::applySourceSpeedEffect() {
if (!Audio::SupportsSpeedControl()) {
return;
}
Expects(speedEffect != nullptr); Expects(speedEffect != nullptr);
if (!speedEffect->effect || !alIsEffect(speedEffect->effect)) { if (!speedEffect->effect || !OpenAL::alIsEffect(speedEffect->effect)) {
alGenAuxiliaryEffectSlots(1, &speedEffect->effectSlot); OpenAL::alGenAuxiliaryEffectSlots(1, &speedEffect->effectSlot);
alGenEffects(1, &speedEffect->effect); OpenAL::alGenEffects(1, &speedEffect->effect);
alGenFilters(1, &speedEffect->filter); OpenAL::alGenFilters(1, &speedEffect->filter);
alEffecti(speedEffect->effect, AL_EFFECT_TYPE, AL_EFFECT_PITCH_SHIFTER); OpenAL::alEffecti(speedEffect->effect, alGetEnumValue("AL_EFFECT_TYPE"), alGetEnumValue("AL_EFFECT_PITCH_SHIFTER"));
alFilteri(speedEffect->filter, AL_FILTER_TYPE, AL_FILTER_LOWPASS); OpenAL::alFilteri(speedEffect->filter, alGetEnumValue("AL_FILTER_TYPE"), alGetEnumValue("AL_FILTER_LOWPASS"));
alFilterf(speedEffect->filter, AL_LOWPASS_GAIN, 0.f); OpenAL::alFilterf(speedEffect->filter, alGetEnumValue("AL_LOWPASS_GAIN"), 0.f);
} }
alEffecti(speedEffect->effect, AL_PITCH_SHIFTER_COARSE_TUNE, speedEffect->coarseTune); OpenAL::alEffecti(speedEffect->effect, alGetEnumValue("AL_PITCH_SHIFTER_COARSE_TUNE"), speedEffect->coarseTune);
alAuxiliaryEffectSloti(speedEffect->effectSlot, AL_EFFECTSLOT_EFFECT, speedEffect->effect); OpenAL::alAuxiliaryEffectSloti(speedEffect->effectSlot, alGetEnumValue("AL_EFFECTSLOT_EFFECT"), speedEffect->effect);
alSourcef(stream.source, AL_PITCH, speedEffect->speed); alSourcef(stream.source, AL_PITCH, speedEffect->speed);
alSource3i(stream.source, AL_AUXILIARY_SEND_FILTER, speedEffect->effectSlot, 0, 0); alSource3i(stream.source, alGetEnumValue("AL_AUXILIARY_SEND_FILTER"), speedEffect->effectSlot, 0, 0);
alSourcei(stream.source, AL_DIRECT_FILTER, speedEffect->filter); alSourcei(stream.source, alGetEnumValue("AL_DIRECT_FILTER"), speedEffect->filter);
} }
#endif // TDESKTOP_DISABLE_OPENAL_EFFECTS
void Mixer::Track::destroyStream() { void Mixer::Track::destroyStream() {
if (isStreamCreated()) { if (isStreamCreated()) {
@ -375,26 +374,26 @@ void Mixer::Track::destroyStream() {
for (auto i = 0; i != 3; ++i) { for (auto i = 0; i != 3; ++i) {
stream.buffers[i] = 0; stream.buffers[i] = 0;
} }
#ifndef TDESKTOP_DISABLE_OPENAL_EFFECTS
resetSpeedEffect(); resetSpeedEffect();
#endif // TDESKTOP_DISABLE_OPENAL_EFFECTS
} }
#ifndef TDESKTOP_DISABLE_OPENAL_EFFECTS
void Mixer::Track::resetSpeedEffect() { void Mixer::Track::resetSpeedEffect() {
if (!Audio::SupportsSpeedControl()) {
return;
}
if (!speedEffect) { if (!speedEffect) {
return; return;
} else if (speedEffect->effect && alIsEffect(speedEffect->effect)) { } else if (speedEffect->effect && OpenAL::alIsEffect(speedEffect->effect)) {
if (isStreamCreated()) { if (isStreamCreated()) {
removeSourceSpeedEffect(); removeSourceSpeedEffect();
} }
alDeleteEffects(1, &speedEffect->effect); OpenAL::alDeleteEffects(1, &speedEffect->effect);
alDeleteAuxiliaryEffectSlots(1, &speedEffect->effectSlot); OpenAL::alDeleteAuxiliaryEffectSlots(1, &speedEffect->effectSlot);
alDeleteFilters(1, &speedEffect->filter); OpenAL::alDeleteFilters(1, &speedEffect->filter);
} }
speedEffect->effect = speedEffect->effectSlot = speedEffect->filter = 0; speedEffect->effect = speedEffect->effectSlot = speedEffect->filter = 0;
} }
#endif // TDESKTOP_DISABLE_OPENAL_EFFECTS
void Mixer::Track::reattach(AudioMsgId::Type type) { void Mixer::Track::reattach(AudioMsgId::Type type) {
if (isStreamCreated() if (isStreamCreated()
@ -531,14 +530,15 @@ int Mixer::Track::getNotQueuedBufferIndex() {
void Mixer::Track::setExternalData( void Mixer::Track::setExternalData(
std::unique_ptr<ExternalSoundData> data) { std::unique_ptr<ExternalSoundData> data) {
#ifndef TDESKTOP_DISABLE_OPENAL_EFFECTS
changeSpeedEffect(data ? data->speed : 1.); changeSpeedEffect(data ? data->speed : 1.);
#endif // TDESKTOP_DISABLE_OPENAL_EFFECTS
externalData = std::move(data); externalData = std::move(data);
} }
#ifndef TDESKTOP_DISABLE_OPENAL_EFFECTS
void Mixer::Track::changeSpeedEffect(float64 speed) { void Mixer::Track::changeSpeedEffect(float64 speed) {
if (!Audio::SupportsSpeedControl()) {
return;
}
if (speed != 1.) { if (speed != 1.) {
if (!speedEffect) { if (!speedEffect) {
speedEffect = std::make_unique<SpeedEffect>(); speedEffect = std::make_unique<SpeedEffect>();
@ -553,7 +553,6 @@ void Mixer::Track::changeSpeedEffect(float64 speed) {
speedEffect = nullptr; speedEffect = nullptr;
} }
} }
#endif // TDESKTOP_DISABLE_OPENAL_EFFECTS
void Mixer::Track::resetStream() { void Mixer::Track::resetStream() {
if (isStreamCreated()) { if (isStreamCreated()) {
@ -830,13 +829,11 @@ void Mixer::forceToBufferExternal(const AudioMsgId &audioId) {
} }
void Mixer::setSpeedFromExternal(const AudioMsgId &audioId, float64 speed) { void Mixer::setSpeedFromExternal(const AudioMsgId &audioId, float64 speed) {
#ifndef TDESKTOP_DISABLE_OPENAL_EFFECTS
QMutexLocker lock(&AudioMutex); QMutexLocker lock(&AudioMutex);
const auto track = trackForType(audioId.type()); const auto track = trackForType(audioId.type());
if (track->state.id == audioId) { if (track->state.id == audioId) {
track->changeSpeedEffect(speed); track->changeSpeedEffect(speed);
} }
#endif // TDESKTOP_DISABLE_OPENAL_EFFECTS
} }
Streaming::TimePoint Mixer::getExternalSyncTimePoint( Streaming::TimePoint Mixer::getExternalSyncTimePoint(

View file

@ -215,9 +215,7 @@ private:
int getNotQueuedBufferIndex(); int getNotQueuedBufferIndex();
void setExternalData(std::unique_ptr<ExternalSoundData> data); void setExternalData(std::unique_ptr<ExternalSoundData> data);
#ifndef TDESKTOP_DISABLE_OPENAL_EFFECTS
void changeSpeedEffect(float64 speed); void changeSpeedEffect(float64 speed);
#endif // TDESKTOP_DISABLE_OPENAL_EFFECTS
~Track(); ~Track();
@ -243,7 +241,6 @@ private:
Stream stream; Stream stream;
std::unique_ptr<ExternalSoundData> externalData; std::unique_ptr<ExternalSoundData> externalData;
#ifndef TDESKTOP_DISABLE_OPENAL_EFFECTS
struct SpeedEffect { struct SpeedEffect {
uint32 effect = 0; uint32 effect = 0;
uint32 effectSlot = 0; uint32 effectSlot = 0;
@ -252,7 +249,6 @@ private:
float64 speed = 1.; float64 speed = 1.;
}; };
std::unique_ptr<SpeedEffect> speedEffect; std::unique_ptr<SpeedEffect> speedEffect;
#endif // TDESKTOP_DISABLE_OPENAL_EFFECTS
crl::time lastUpdateWhen = 0; crl::time lastUpdateWhen = 0;
crl::time lastUpdatePosition = 0; crl::time lastUpdatePosition = 0;
@ -260,11 +256,9 @@ private:
void createStream(AudioMsgId::Type type); void createStream(AudioMsgId::Type type);
void destroyStream(); void destroyStream();
void resetStream(); void resetStream();
#ifndef TDESKTOP_DISABLE_OPENAL_EFFECTS
void resetSpeedEffect(); void resetSpeedEffect();
void applySourceSpeedEffect(); void applySourceSpeedEffect();
void removeSourceSpeedEffect(); void removeSourceSpeedEffect();
#endif // TDESKTOP_DISABLE_OPENAL_EFFECTS
}; };

View file

@ -0,0 +1,90 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "media/audio/media_openal_functions.h"
#include <al.h>
namespace OpenAL {
void LoadEFXExtension() {
#define LOAD_PROC(x) ((x) = reinterpret_cast<decltype(x)>(alGetProcAddress(#x)))
LOAD_PROC(alGenEffects);
LOAD_PROC(alDeleteEffects);
LOAD_PROC(alIsEffect);
LOAD_PROC(alEffecti);
LOAD_PROC(alEffectiv);
LOAD_PROC(alEffectf);
LOAD_PROC(alEffectfv);
LOAD_PROC(alGetEffecti);
LOAD_PROC(alGetEffectiv);
LOAD_PROC(alGetEffectf);
LOAD_PROC(alGetEffectfv);
LOAD_PROC(alGenFilters);
LOAD_PROC(alDeleteFilters);
LOAD_PROC(alIsFilter);
LOAD_PROC(alFilteri);
LOAD_PROC(alFilteriv);
LOAD_PROC(alFilterf);
LOAD_PROC(alFilterfv);
LOAD_PROC(alGetFilteri);
LOAD_PROC(alGetFilteriv);
LOAD_PROC(alGetFilterf);
LOAD_PROC(alGetFilterfv);
LOAD_PROC(alGenAuxiliaryEffectSlots);
LOAD_PROC(alDeleteAuxiliaryEffectSlots);
LOAD_PROC(alIsAuxiliaryEffectSlot);
LOAD_PROC(alAuxiliaryEffectSloti);
LOAD_PROC(alAuxiliaryEffectSlotiv);
LOAD_PROC(alAuxiliaryEffectSlotf);
LOAD_PROC(alAuxiliaryEffectSlotfv);
LOAD_PROC(alGetAuxiliaryEffectSloti);
LOAD_PROC(alGetAuxiliaryEffectSlotiv);
LOAD_PROC(alGetAuxiliaryEffectSlotf);
LOAD_PROC(alGetAuxiliaryEffectSlotfv);
#undef LOAD_PROC
}
bool HasEFXExtension() {
return (alGenEffects != nullptr)
&& (alDeleteEffects != nullptr)
&& (alIsEffect != nullptr)
&& (alEffecti != nullptr)
&& (alEffectiv != nullptr)
&& (alEffectf != nullptr)
&& (alEffectfv != nullptr)
&& (alGetEffecti != nullptr)
&& (alGetEffectiv != nullptr)
&& (alGetEffectf != nullptr)
&& (alGetEffectfv != nullptr)
&& (alGenFilters != nullptr)
&& (alDeleteFilters != nullptr)
&& (alIsFilter != nullptr)
&& (alFilteri != nullptr)
&& (alFilteriv != nullptr)
&& (alFilterf != nullptr)
&& (alFilterfv != nullptr)
&& (alGetFilteri != nullptr)
&& (alGetFilteriv != nullptr)
&& (alGetFilterf != nullptr)
&& (alGetFilterfv != nullptr)
&& (alGenAuxiliaryEffectSlots != nullptr)
&& (alDeleteAuxiliaryEffectSlots != nullptr)
&& (alIsAuxiliaryEffectSlot != nullptr)
&& (alAuxiliaryEffectSloti != nullptr)
&& (alAuxiliaryEffectSlotiv != nullptr)
&& (alAuxiliaryEffectSlotf != nullptr)
&& (alAuxiliaryEffectSlotfv != nullptr)
&& (alGetAuxiliaryEffectSloti != nullptr)
&& (alGetAuxiliaryEffectSlotiv != nullptr)
&& (alGetAuxiliaryEffectSlotf != nullptr)
&& (alGetAuxiliaryEffectSlotfv != nullptr);
}
} // namespace OpenAL

View file

@ -0,0 +1,56 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include <alext.h>
namespace OpenAL {
/* Effect object functions */
inline LPALGENEFFECTS alGenEffects;
inline LPALDELETEEFFECTS alDeleteEffects;
inline LPALISEFFECT alIsEffect;
inline LPALEFFECTI alEffecti;
inline LPALEFFECTIV alEffectiv;
inline LPALEFFECTF alEffectf;
inline LPALEFFECTFV alEffectfv;
inline LPALGETEFFECTI alGetEffecti;
inline LPALGETEFFECTIV alGetEffectiv;
inline LPALGETEFFECTF alGetEffectf;
inline LPALGETEFFECTFV alGetEffectfv;
/* Filter object functions */
inline LPALGENFILTERS alGenFilters;
inline LPALDELETEFILTERS alDeleteFilters;
inline LPALISFILTER alIsFilter;
inline LPALFILTERI alFilteri;
inline LPALFILTERIV alFilteriv;
inline LPALFILTERF alFilterf;
inline LPALFILTERFV alFilterfv;
inline LPALGETFILTERI alGetFilteri;
inline LPALGETFILTERIV alGetFilteriv;
inline LPALGETFILTERF alGetFilterf;
inline LPALGETFILTERFV alGetFilterfv;
/* Auxiliary Effect Slot object functions */
inline LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots;
inline LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots;
inline LPALISAUXILIARYEFFECTSLOT alIsAuxiliaryEffectSlot;
inline LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti;
inline LPALAUXILIARYEFFECTSLOTIV alAuxiliaryEffectSlotiv;
inline LPALAUXILIARYEFFECTSLOTF alAuxiliaryEffectSlotf;
inline LPALAUXILIARYEFFECTSLOTFV alAuxiliaryEffectSlotfv;
inline LPALGETAUXILIARYEFFECTSLOTI alGetAuxiliaryEffectSloti;
inline LPALGETAUXILIARYEFFECTSLOTIV alGetAuxiliaryEffectSlotiv;
inline LPALGETAUXILIARYEFFECTSLOTF alGetAuxiliaryEffectSlotf;
inline LPALGETAUXILIARYEFFECTSLOTFV alGetAuxiliaryEffectSlotfv;
void LoadEFXExtension();
bool HasEFXExtension();
} // namespace OpenAL

View file

@ -3534,8 +3534,7 @@ void OverlayWidget::setSession(not_null<Main::Session*> session) {
_session = session; _session = session;
setWindowIcon(Window::CreateIcon(session)); setWindowIcon(Window::CreateIcon(session));
base::ObservableViewer( session->downloaderTaskFinished(
session->downloaderTaskFinished()
) | rpl::start_with_next([=] { ) | rpl::start_with_next([=] {
if (!isHidden()) { if (!isHidden()) {
updateControls(); updateControls();

View file

@ -20,7 +20,7 @@ int __clock_gettime_glibc_old(clockid_t clk_id, struct timespec *tp);
__asm__(".symver __clock_gettime_glibc_old,clock_gettime@GLIBC_" GETTIME_GLIBC_VERSION); __asm__(".symver __clock_gettime_glibc_old,clock_gettime@GLIBC_" GETTIME_GLIBC_VERSION);
int __wrap_clock_gettime(clockid_t clk_id, struct timespec *tp) { int __wrap_clock_gettime(clockid_t clk_id, struct timespec *tp) {
return __clock_gettime_glibc_old(clk_id, tp); return __clock_gettime_glibc_old(clk_id, tp);
} }
uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *rem_p); uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *rem_p);

View file

@ -20,6 +20,6 @@ __asm__(".symver __clock_gettime_glibc_old,clock_gettime@GLIBC_" GETTIME_GLIBC_V
int __wrap_clock_gettime(clockid_t clk_id, struct timespec *tp) { int __wrap_clock_gettime(clockid_t clk_id, struct timespec *tp) {
return __clock_gettime_glibc_old(clk_id, tp); return __clock_gettime_glibc_old(clk_id, tp);
} }

View file

@ -810,8 +810,7 @@ void AppendEmojiPacks(
[self setNeedsDisplayInRect:PeerRectByIndex(userpicIndex)]; [self setNeedsDisplayInRect:PeerRectByIndex(userpicIndex)];
}; };
const auto listenToDownloaderFinished = [=] { const auto listenToDownloaderFinished = [=] {
base::ObservableViewer( _session->downloaderTaskFinished(
_session->downloaderTaskFinished()
) | rpl::start_with_next([=] { ) | rpl::start_with_next([=] {
const auto all = ranges::all_of(_pins, [=](const auto &pin) { const auto all = ranges::all_of(_pins, [=](const auto &pin) {
return (!pin->peer->hasUserpic()) return (!pin->peer->hasUserpic())
@ -1191,8 +1190,7 @@ void AppendEmojiPacks(
[self updateImage]; [self updateImage];
return; return;
} }
base::ObservableViewer( document->session().downloaderTaskFinished(
document->session().downloaderTaskFinished()
) | rpl::start_with_next([=] { ) | rpl::start_with_next([=] {
_image = _media->getStickerSmall(); _image = _media->getStickerSmall();
if (_image) { if (_image) {

View file

@ -301,6 +301,8 @@ void Manager::Private::clearingThreadLoop() {
_clearingTasks.clear(); _clearingTasks.clear();
} }
@autoreleasepool {
auto clearBySpecial = [&](NSDictionary *notificationUserInfo) { auto clearBySpecial = [&](NSDictionary *notificationUserInfo) {
NSNumber *sessionObject = [notificationUserInfo objectForKey:@"session"]; NSNumber *sessionObject = [notificationUserInfo objectForKey:@"session"];
const auto notificationSessionId = sessionObject ? [sessionObject unsignedLongLongValue] : 0; const auto notificationSessionId = sessionObject ? [sessionObject unsignedLongLongValue] : 0;
@ -332,6 +334,8 @@ void Manager::Private::clearingThreadLoop() {
} }
} }
} }
}
} }
} }

View file

@ -7,26 +7,43 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/ */
#include "platform/win/windows_dlls.h" #include "platform/win/windows_dlls.h"
#include "base/platform/win/base_windows_safe_library.h"
#include <VersionHelpers.h> #include <VersionHelpers.h>
#include <QtCore/QSysInfo> #include <QtCore/QSysInfo>
namespace Platform { namespace Platform {
namespace Dlls { namespace Dlls {
f_SetDllDirectory SetDllDirectory; using base::Platform::SafeLoadLibrary;
using base::Platform::LoadMethod;
HINSTANCE LibKernel32;
void init() { void init() {
static bool inited = false; static bool inited = false;
if (inited) return; if (inited) return;
inited = true; inited = true;
LibKernel32 = LoadLibrary(L"KERNEL32.DLL"); // Remove the current directory from the DLL search order.
load(LibKernel32, "SetDllDirectoryW", SetDllDirectory); ::SetDllDirectory(L"");
if (SetDllDirectory) {
// Remove the current directory from the DLL search order. const auto list = {
SetDllDirectory(L""); u"dbghelp.dll"_q,
u"dbgcore.dll"_q,
u"propsys.dll"_q,
u"winsta.dll"_q,
u"textinputframework.dll"_q,
u"uxtheme.dll"_q,
u"igdumdim32.dll"_q,
u"amdhdl32.dll"_q,
u"wtsapi32.dll"_q,
u"propsys.dll"_q,
u"combase.dll"_q,
u"dwmapi.dll"_q,
u"rstrtmgr.dll"_q,
u"psapi.dll"_q,
};
for (const auto &lib : list) {
SafeLoadLibrary(lib);
} }
} }
@ -53,59 +70,50 @@ f_RmShutdown RmShutdown;
f_RmEndSession RmEndSession; f_RmEndSession RmEndSession;
f_GetProcessMemoryInfo GetProcessMemoryInfo; f_GetProcessMemoryInfo GetProcessMemoryInfo;
HINSTANCE LibUxTheme;
HINSTANCE LibShell32;
HINSTANCE LibWtsApi32;
HINSTANCE LibPropSys;
HINSTANCE LibComBase;
HINSTANCE LibDwmApi;
HINSTANCE LibRstrtMgr;
HINSTANCE LibPsApi;
void start() { void start() {
init(); init();
LibShell32 = LoadLibrary(L"SHELL32.DLL"); const auto LibShell32 = SafeLoadLibrary(u"shell32.dll"_q);
load(LibShell32, "SHAssocEnumHandlers", SHAssocEnumHandlers); LoadMethod(LibShell32, "SHAssocEnumHandlers", SHAssocEnumHandlers);
load(LibShell32, "SHCreateItemFromParsingName", SHCreateItemFromParsingName); LoadMethod(LibShell32, "SHCreateItemFromParsingName", SHCreateItemFromParsingName);
load(LibShell32, "SHOpenWithDialog", SHOpenWithDialog); LoadMethod(LibShell32, "SHOpenWithDialog", SHOpenWithDialog);
load(LibShell32, "OpenAs_RunDLLW", OpenAs_RunDLL); LoadMethod(LibShell32, "OpenAs_RunDLLW", OpenAs_RunDLL);
load(LibShell32, "SHQueryUserNotificationState", SHQueryUserNotificationState); LoadMethod(LibShell32, "SHQueryUserNotificationState", SHQueryUserNotificationState);
load(LibShell32, "SHChangeNotify", SHChangeNotify); LoadMethod(LibShell32, "SHChangeNotify", SHChangeNotify);
load(LibShell32, "SetCurrentProcessExplicitAppUserModelID", SetCurrentProcessExplicitAppUserModelID); LoadMethod(LibShell32, "SetCurrentProcessExplicitAppUserModelID", SetCurrentProcessExplicitAppUserModelID);
LibUxTheme = LoadLibrary(L"UXTHEME.DLL"); const auto LibUxTheme = SafeLoadLibrary(u"uxtheme.dll"_q);
load(LibUxTheme, "SetWindowTheme", SetWindowTheme); LoadMethod(LibUxTheme, "SetWindowTheme", SetWindowTheme);
if (IsWindowsVistaOrGreater()) { if (IsWindowsVistaOrGreater()) {
LibWtsApi32 = LoadLibrary(L"WTSAPI32.DLL"); const auto LibWtsApi32 = SafeLoadLibrary(u"wtsapi32.dll"_q);
load(LibWtsApi32, "WTSRegisterSessionNotification", WTSRegisterSessionNotification); LoadMethod(LibWtsApi32, "WTSRegisterSessionNotification", WTSRegisterSessionNotification);
load(LibWtsApi32, "WTSUnRegisterSessionNotification", WTSUnRegisterSessionNotification); LoadMethod(LibWtsApi32, "WTSUnRegisterSessionNotification", WTSUnRegisterSessionNotification);
LibPropSys = LoadLibrary(L"PROPSYS.DLL"); const auto LibPropSys = SafeLoadLibrary(u"propsys.dll"_q);
load(LibPropSys, "PropVariantToString", PropVariantToString); LoadMethod(LibPropSys, "PropVariantToString", PropVariantToString);
load(LibPropSys, "PSStringFromPropertyKey", PSStringFromPropertyKey); LoadMethod(LibPropSys, "PSStringFromPropertyKey", PSStringFromPropertyKey);
if (IsWindows8OrGreater()) { if (IsWindows8OrGreater()) {
LibComBase = LoadLibrary(L"COMBASE.DLL"); const auto LibComBase = SafeLoadLibrary(u"combase.dll"_q);
load(LibComBase, "RoGetActivationFactory", RoGetActivationFactory); LoadMethod(LibComBase, "RoGetActivationFactory", RoGetActivationFactory);
load(LibComBase, "WindowsCreateStringReference", WindowsCreateStringReference); LoadMethod(LibComBase, "WindowsCreateStringReference", WindowsCreateStringReference);
load(LibComBase, "WindowsDeleteString", WindowsDeleteString); LoadMethod(LibComBase, "WindowsDeleteString", WindowsDeleteString);
} }
LibDwmApi = LoadLibrary(L"DWMAPI.DLL"); const auto LibDwmApi = SafeLoadLibrary(u"dwmapi.dll"_q);
load(LibDwmApi, "DwmIsCompositionEnabled", DwmIsCompositionEnabled); LoadMethod(LibDwmApi, "DwmIsCompositionEnabled", DwmIsCompositionEnabled);
LibRstrtMgr = LoadLibrary(L"RSTRTMGR.DLL"); const auto LibRstrtMgr = SafeLoadLibrary(u"rstrtmgr.dll"_q);
load(LibRstrtMgr, "RmStartSession", RmStartSession); LoadMethod(LibRstrtMgr, "RmStartSession", RmStartSession);
load(LibRstrtMgr, "RmRegisterResources", RmRegisterResources); LoadMethod(LibRstrtMgr, "RmRegisterResources", RmRegisterResources);
load(LibRstrtMgr, "RmGetList", RmGetList); LoadMethod(LibRstrtMgr, "RmGetList", RmGetList);
load(LibRstrtMgr, "RmShutdown", RmShutdown); LoadMethod(LibRstrtMgr, "RmShutdown", RmShutdown);
load(LibRstrtMgr, "RmEndSession", RmEndSession); LoadMethod(LibRstrtMgr, "RmEndSession", RmEndSession);
} }
LibPsApi = LoadLibrary(L"PSAPI.DLL"); const auto LibPsApi = SafeLoadLibrary(u"psapi.dll"_q);
load(LibPsApi, "GetProcessMemoryInfo", GetProcessMemoryInfo); LoadMethod(LibPsApi, "GetProcessMemoryInfo", GetProcessMemoryInfo);
} }
} // namespace Dlls } // namespace Dlls

View file

@ -30,14 +30,6 @@ extern f_SetDllDirectory SetDllDirectory;
void start(); void start();
template <typename Function>
bool load(HINSTANCE library, LPCSTR name, Function &func) {
if (!library) return false;
func = reinterpret_cast<Function>(GetProcAddress(library, name));
return (func != nullptr);
}
// UXTHEME.DLL // UXTHEME.DLL
using f_SetWindowTheme = HRESULT(FAR STDAPICALLTYPE*)( using f_SetWindowTheme = HRESULT(FAR STDAPICALLTYPE*)(
HWND hWnd, HWND hWnd,

View file

@ -26,8 +26,8 @@ class GroupMembersWidget : public PeerListWidget {
public: public:
GroupMembersWidget( GroupMembersWidget(
QWidget *parent, QWidget *parent,
not_null<PeerData*> peer, not_null<PeerData*> peer,
const style::PeerListItem &st); const style::PeerListItem &st);
int onlineCount() const { int onlineCount() const {

View file

@ -33,7 +33,11 @@ PeerListWidget::PeerListWidget(
, _removeText(removeText) , _removeText(removeText)
, _removeWidth(st::normalFont->width(_removeText)) { , _removeWidth(st::normalFont->width(_removeText)) {
setMouseTracking(true); setMouseTracking(true);
subscribe(peer->session().downloaderTaskFinished(), [=] { update(); });
peer->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
}, lifetime());
} }
int PeerListWidget::resizeGetHeight(int newWidth) { int PeerListWidget::resizeGetHeight(int newWidth) {

View file

@ -577,6 +577,7 @@ void SetupMultiAccountNotifications(
AddSkip(container); AddSkip(container);
AddDividerText(container, tr::lng_settings_notify_all_about()); AddDividerText(container, tr::lng_settings_notify_all_about());
AddSkip(container);
} }
void SetupNotificationsContent( void SetupNotificationsContent(

View file

@ -38,8 +38,11 @@ public:
void enqueue(not_null<Task*> task, int priority); void enqueue(not_null<Task*> task, int priority);
void remove(not_null<Task*> task); void remove(not_null<Task*> task);
[[nodiscard]] base::Observable<void> &taskFinished() { void notifyTaskFinished() {
return _taskFinishedObservable; _taskFinished.fire({});
}
[[nodiscard]] rpl::producer<> taskFinished() const {
return _taskFinished.events();
} }
int changeRequestedAmount(MTP::DcId dcId, int index, int delta); int changeRequestedAmount(MTP::DcId dcId, int index, int delta);
@ -101,7 +104,7 @@ private:
const not_null<ApiWrap*> _api; const not_null<ApiWrap*> _api;
base::Observable<void> _taskFinishedObservable; rpl::event_stream<> _taskFinished;
base::flat_map<MTP::DcId, DcBalanceData> _balanceData; base::flat_map<MTP::DcId, DcBalanceData> _balanceData;
base::Timer _resetGenerationTimer; base::Timer _resetGenerationTimer;

View file

@ -140,7 +140,7 @@ void FileLoader::finishWithBytes(const QByteArray &data) {
Platform::File::PostprocessDownloaded( Platform::File::PostprocessDownloaded(
QFileInfo(_file).absoluteFilePath()); QFileInfo(_file).absoluteFilePath());
} }
_session->downloaderTaskFinished().notify(); _session->notifyDownloaderTaskFinished();
_updates.fire_done(); _updates.fire_done();
} }
@ -440,7 +440,7 @@ bool FileLoader::finalizeResult() {
_cacheTag)); _cacheTag));
} }
} }
_session->downloaderTaskFinished().notify(); _session->notifyDownloaderTaskFinished();
_updates.fire_done(); _updates.fire_done();
return true; return true;
} }

View file

@ -388,7 +388,7 @@ void start() {
EncryptedDescriptor settings; EncryptedDescriptor settings;
if (!DecryptLocal(settings, settingsEncrypted, SettingsKey)) { if (!DecryptLocal(settings, settingsEncrypted, SettingsKey)) {
LOG(("App Error: could not decrypt settings from settings file, maybe bad passcode...")); LOG(("App Error: could not decrypt settings from settings file..."));
return writeSettings(); return writeSettings();
} }
@ -426,7 +426,12 @@ void start() {
void writeSettings() { void writeSettings() {
if (!_settingsWriteAllowed) { if (!_settingsWriteAllowed) {
_settingsRewriteNeeded = true; _settingsRewriteNeeded = true;
return;
// We need to generate SettingsKey anyway,
// for the moveLegacyBackground to work.
if (SettingsKey) {
return;
}
} }
if (_basePath.isEmpty()) { if (_basePath.isEmpty()) {
LOG(("App Error: _basePath is empty in writeSettings()")); LOG(("App Error: _basePath is empty in writeSettings()"));
@ -446,6 +451,11 @@ void writeSettings() {
} }
settings.writeData(_settingsSalt); settings.writeData(_settingsSalt);
if (!_settingsWriteAllowed) {
EncryptedDescriptor data(0);
settings.writeEncrypted(data, SettingsKey);
return;
}
const auto configSerialized = LookupFallbackConfig().serialize(); const auto configSerialized = LookupFallbackConfig().serialize();
const auto applicationSettings = Core::App().settings().serialize(); const auto applicationSettings = Core::App().settings().serialize();

View file

@ -639,8 +639,7 @@ void UserpicButton::setupPeerViewers() {
update(); update();
}, lifetime()); }, lifetime());
base::ObservableViewer( _peer->session().downloaderTaskFinished(
_peer->session().downloaderTaskFinished()
) | rpl::filter([=] { ) | rpl::filter([=] {
return _waiting; return _waiting;
}) | rpl::start_with_next([=] { }) | rpl::start_with_next([=] {

View file

@ -21,6 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "window/themes/window_theme.h" #include "window/themes/window_theme.h"
#include "storage/file_download.h" #include "storage/file_download.h"
#include "main/main_session.h" #include "main/main_session.h"
#include "main/main_account.h"
#include "history/history.h" #include "history/history.h"
#include "history/history_item.h" #include "history/history_item.h"
#include "platform/platform_specific.h" #include "platform/platform_specific.h"
@ -229,14 +230,16 @@ void Manager::showNextFromQueue() {
void Manager::subscribeToSession(not_null<Main::Session*> session) { void Manager::subscribeToSession(not_null<Main::Session*> session) {
auto i = _subscriptions.find(session); auto i = _subscriptions.find(session);
if (i == _subscriptions.end()) { if (i == _subscriptions.end()) {
i = _subscriptions.emplace(session, base::Subscription()).first; i = _subscriptions.emplace(session).first;
session->lifetime().add([=] { session->account().sessionChanges(
) | rpl::start_with_next([=] {
_subscriptions.remove(session); _subscriptions.remove(session);
}); }, i->second.lifetime);
} else if (i->second) { } else if (i->second.subscription) {
return; return;
} }
i->second = session->downloaderTaskFinished().add_subscription([=] { session->downloaderTaskFinished(
) | rpl::start_with_next([=] {
auto found = false; auto found = false;
for (const auto &notification : _notifications) { for (const auto &notification : _notifications) {
if (const auto history = notification->maybeHistory()) { if (const auto history = notification->maybeHistory()) {
@ -247,9 +250,9 @@ void Manager::subscribeToSession(not_null<Main::Session*> session) {
} }
} }
if (!found) { if (!found) {
_subscriptions[session].destroy(); _subscriptions[session].subscription.destroy();
} }
}); }, i->second.subscription);
} }
void Manager::moveWidgets() { void Manager::moveWidgets() {

View file

@ -56,6 +56,10 @@ private:
friend class internal::Widget; friend class internal::Widget;
using Notification = internal::Notification; using Notification = internal::Notification;
using HideAllButton = internal::HideAllButton; using HideAllButton = internal::HideAllButton;
struct SessionSubscription {
rpl::lifetime subscription;
rpl::lifetime lifetime;
};
[[nodiscard]] QPixmap hiddenUserpicPlaceholder() const; [[nodiscard]] QPixmap hiddenUserpicPlaceholder() const;
@ -91,7 +95,7 @@ private:
std::vector<std::unique_ptr<Notification>> _notifications; std::vector<std::unique_ptr<Notification>> _notifications;
base::flat_map< base::flat_map<
not_null<Main::Session*>, not_null<Main::Session*>,
base::Subscription> _subscriptions; SessionSubscription> _subscriptions;
std::unique_ptr<HideAllButton> _hideAll; std::unique_ptr<HideAllButton> _hideAll;

View file

@ -666,8 +666,7 @@ void CloudList::subscribeToDownloadFinished() {
if (_downloadFinishedLifetime) { if (_downloadFinishedLifetime) {
return; return;
} }
base::ObservableViewer( _window->session().downloaderTaskFinished(
_window->session().downloaderTaskFinished()
) | rpl::start_with_next([=] { ) | rpl::start_with_next([=] {
auto &&waiting = _elements | ranges::view::filter(&Element::waiting); auto &&waiting = _elements | ranges::view::filter(&Element::waiting);
const auto still = ranges::count_if(waiting, [&](Element &element) { const auto still = ranges::count_if(waiting, [&](Element &element) {

View file

@ -578,7 +578,10 @@ MainMenu::MainMenu(
_version->setRichText(textcmdLink(1, currentVersionText())); _version->setRichText(textcmdLink(1, currentVersionText()));
_version->setLink(1, std::make_shared<UrlClickHandler>(qsl("https://github.com/kotatogram/kotatogram-desktop"))); _version->setLink(1, std::make_shared<UrlClickHandler>(qsl("https://github.com/kotatogram/kotatogram-desktop")));
subscribe(_controller->session().downloaderTaskFinished(), [=] { update(); }); _controller->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
}, lifetime());
_controller->session().changes().peerUpdates( _controller->session().changes().peerUpdates(
_controller->session().user(), _controller->session().user(),

View file

@ -36,9 +36,10 @@ MediaPreviewWidget::MediaPreviewWidget(
, _controller(controller) , _controller(controller)
, _emojiSize(Ui::Emoji::GetSizeLarge() / cIntRetinaFactor()) { , _emojiSize(Ui::Emoji::GetSizeLarge() / cIntRetinaFactor()) {
setAttribute(Qt::WA_TransparentForMouseEvents); setAttribute(Qt::WA_TransparentForMouseEvents);
subscribe(_controller->session().downloaderTaskFinished(), [=] { _controller->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update(); update();
}); }, lifetime());
} }
QRect MediaPreviewWidget::updateArea() const { QRect MediaPreviewWidget::updateArea() const {

View file

@ -105,15 +105,16 @@ bool TitleWidgetQt::eventFilter(QObject *obj, QEvent *e) {
|| e->type() == QEvent::MouseButtonPress) { || e->type() == QEvent::MouseButtonPress) {
if(window()->isAncestorOf(static_cast<QWidget*>(obj))) { if(window()->isAncestorOf(static_cast<QWidget*>(obj))) {
const auto mouseEvent = static_cast<QMouseEvent*>(e); const auto mouseEvent = static_cast<QMouseEvent*>(e);
const auto edges = edgesFromPos(mouseEvent->windowPos().toPoint());
if (e->type() == QEvent::MouseMove) { if (e->type() == QEvent::MouseMove) {
updateCursor(mouseEvent->windowPos().toPoint()); updateCursor(edges);
} }
if(e->type() == QEvent::MouseButtonPress if(e->type() == QEvent::MouseButtonPress
&& mouseEvent->button() == Qt::LeftButton && mouseEvent->button() == Qt::LeftButton
&& window()->windowState() != Qt::WindowMaximized) { && window()->windowState() != Qt::WindowMaximized) {
return startResize(mouseEvent->windowPos().toPoint()); return startResize(edges);
} }
} }
} else if (e->type() == QEvent::Leave) { } else if (e->type() == QEvent::Leave) {
@ -195,9 +196,7 @@ Qt::Edges TitleWidgetQt::edgesFromPos(const QPoint &pos) {
} }
} }
void TitleWidgetQt::updateCursor(const QPoint &pos) { void TitleWidgetQt::updateCursor(Qt::Edges edges) {
const auto edges = edgesFromPos(pos);
if (!edges || window()->windowState() == Qt::WindowMaximized) { if (!edges || window()->windowState() == Qt::WindowMaximized) {
while (QGuiApplication::overrideCursor()) { while (QGuiApplication::overrideCursor()) {
QGuiApplication::restoreOverrideCursor(); QGuiApplication::restoreOverrideCursor();
@ -221,9 +220,9 @@ void TitleWidgetQt::updateCursor(const QPoint &pos) {
} }
} }
bool TitleWidgetQt::startResize(const QPoint &pos) { bool TitleWidgetQt::startResize(Qt::Edges edges) {
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) || defined DESKTOP_APP_QT_PATCHED #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) || defined DESKTOP_APP_QT_PATCHED
if (const auto edges = edgesFromPos(pos)) { if (edges) {
return window()->windowHandle()->startSystemResize(edges); return window()->windowHandle()->startSystemResize(edges);
} }
#endif // Qt >= 5.15 || DESKTOP_APP_QT_PATCHED #endif // Qt >= 5.15 || DESKTOP_APP_QT_PATCHED

View file

@ -41,8 +41,8 @@ private:
void updateControlsPosition(); void updateControlsPosition();
Qt::Edges edgesFromPos(const QPoint &pos); Qt::Edges edgesFromPos(const QPoint &pos);
void updateCursor(const QPoint &pos); void updateCursor(Qt::Edges edges);
bool startResize(const QPoint &pos); bool startResize(Qt::Edges edges);
const style::WindowTitle &_st; const style::WindowTitle &_st;
object_ptr<Ui::IconButton> _minimize; object_ptr<Ui::IconButton> _minimize;

View file

@ -1,7 +1,7 @@
AppVersion 2001016 AppVersion 2001017
AppVersionStrMajor 2.1 AppVersionStrMajor 2.1
AppVersionStrSmall 2.1.16 AppVersionStrSmall 2.1.17
AppVersionStr 2.1.16 AppVersionStr 2.1.17
BetaChannel 1 BetaChannel 1
AlphaVersion 0 AlphaVersion 0
AppVersionOriginal 2.1.16.beta AppVersionOriginal 2.1.17.beta

@ -1 +1 @@
Subproject commit 3017da83c15e5e27244ab66526fea8cc3bddb7cf Subproject commit 01ca681ab3aecda8c372b1bb77999f3b7b7a52c6

@ -1 +1 @@
Subproject commit 2a063957da89554214ed52e2d7b94f1fa08668ce Subproject commit 11a39d9d941e4cd1c60a0c97352cbf89700f42fc

View file

@ -1,3 +1,10 @@
2.1.17 beta (02.07.20)
- Fix messages editing in a non-active account.
- Fix large animated emoji messages editing.
- Fix high definition GIF animations opening in media viewer.
- Multiple crash fixes.
2.1.16 beta (01.07.20) 2.1.16 beta (01.07.20)
- Crash fix. - Crash fix.

2
cmake

@ -1 +1 @@
Subproject commit 6b36a649dc0061138cf60bac65d9a40a5c9faea3 Subproject commit 9346d5f89510c4f9e340a0e26a1f8c2244e7de29