Updated TDesktop sources to 2.1.17 beta
This commit is contained in:
commit
f633857744
90 changed files with 610 additions and 348 deletions
|
|
@ -738,6 +738,8 @@ PRIVATE
|
|||
media/audio/media_audio_track.h
|
||||
media/audio/media_child_ffmpeg_loader.cpp
|
||||
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.h
|
||||
media/clip/media_clip_ffmpeg.cpp
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
<Identity Name="TelegramMessengerLLP.TelegramDesktop"
|
||||
ProcessorArchitecture="ARCHITECTURE"
|
||||
Publisher="CN=536BC709-8EE1-4478-AF22-F0F0F26FF64A"
|
||||
Version="2.1.16.0" />
|
||||
Version="2.1.17.0" />
|
||||
<Properties>
|
||||
<DisplayName>Telegram Desktop</DisplayName>
|
||||
<PublisherDisplayName>Telegram FZ-LLC</PublisherDisplayName>
|
||||
|
|
|
|||
|
|
@ -44,8 +44,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico"
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 2,1,16,0
|
||||
PRODUCTVERSION 2,1,16,0
|
||||
FILEVERSION 2,1,17,0
|
||||
PRODUCTVERSION 2,1,17,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
|
@ -62,10 +62,10 @@ BEGIN
|
|||
BEGIN
|
||||
VALUE "CompanyName", "Telegram FZ-LLC"
|
||||
VALUE "FileDescription", "Telegram Desktop"
|
||||
VALUE "FileVersion", "2.1.16.0"
|
||||
VALUE "FileVersion", "2.1.17.0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2014-2020"
|
||||
VALUE "ProductName", "Telegram Desktop"
|
||||
VALUE "ProductVersion", "2.1.16.0"
|
||||
VALUE "ProductVersion", "2.1.17.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
|
|||
|
|
@ -35,8 +35,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 2,1,16,0
|
||||
PRODUCTVERSION 2,1,16,0
|
||||
FILEVERSION 2,1,17,0
|
||||
PRODUCTVERSION 2,1,17,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
|
@ -53,10 +53,10 @@ BEGIN
|
|||
BEGIN
|
||||
VALUE "CompanyName", "Telegram FZ-LLC"
|
||||
VALUE "FileDescription", "Telegram Desktop Updater"
|
||||
VALUE "FileVersion", "2.1.16.0"
|
||||
VALUE "FileVersion", "2.1.17.0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2014-2020"
|
||||
VALUE "ProductName", "Telegram Desktop"
|
||||
VALUE "ProductVersion", "2.1.16.0"
|
||||
VALUE "ProductVersion", "2.1.17.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
|
|||
|
|
@ -1364,7 +1364,10 @@ void RevokePublicLinkBox::prepare() {
|
|||
|
||||
addButton(tr::lng_cancel(), [=] { closeBox(); });
|
||||
|
||||
subscribe(_session->downloaderTaskFinished(), [=] { update(); });
|
||||
_session->downloaderTaskFinished(
|
||||
) | rpl::start_with_next([=] {
|
||||
update();
|
||||
}, lifetime());
|
||||
|
||||
_inner->resizeToWidth(st::boxWideWidth);
|
||||
setDimensions(st::boxWideWidth, _innerTop + _inner->height());
|
||||
|
|
|
|||
|
|
@ -203,7 +203,10 @@ BackgroundBox::Inner::Inner(
|
|||
}
|
||||
requestPapers();
|
||||
|
||||
subscribe(_session->downloaderTaskFinished(), [=] { update(); });
|
||||
_session->downloaderTaskFinished(
|
||||
) | rpl::start_with_next([=] {
|
||||
update();
|
||||
}, lifetime());
|
||||
using Update = Window::Theme::BackgroundUpdate;
|
||||
subscribe(Window::Theme::Background(), [=](const Update &update) {
|
||||
if (update.paletteChanged()) {
|
||||
|
|
|
|||
|
|
@ -419,9 +419,10 @@ BackgroundPreviewBox::BackgroundPreviewBox(
|
|||
if (_media) {
|
||||
_media->thumbnailWanted(_paper.fileOrigin());
|
||||
}
|
||||
subscribe(_controller->session().downloaderTaskFinished(), [=] {
|
||||
_controller->session().downloaderTaskFinished(
|
||||
) | rpl::start_with_next([=] {
|
||||
update();
|
||||
});
|
||||
}, lifetime());
|
||||
}
|
||||
|
||||
not_null<HistoryView::ElementDelegate*> BackgroundPreviewBox::delegate() {
|
||||
|
|
|
|||
|
|
@ -891,9 +891,10 @@ ConfirmInviteBox::ConfirmInviteBox(
|
|||
_photo = photo->createMediaView();
|
||||
_photo->wanted(Data::PhotoSize::Small, Data::FileOrigin());
|
||||
if (!_photo->image(Data::PhotoSize::Small)) {
|
||||
subscribe(_session->downloaderTaskFinished(), [=] {
|
||||
_session->downloaderTaskFinished(
|
||||
) | rpl::start_with_next([=] {
|
||||
update();
|
||||
});
|
||||
}, lifetime());
|
||||
}
|
||||
} else {
|
||||
_photoEmpty = std::make_unique<Ui::EmptyUserpic>(
|
||||
|
|
|
|||
|
|
@ -259,9 +259,9 @@ auto AddButtonWithLoader(
|
|||
)
|
||||
);
|
||||
|
||||
*buttonState = localLoaderValues->events_starting_with(
|
||||
rawGlobalLoaderPtr() ? rawGlobalLoaderPtr() : localLoader->get()
|
||||
) | rpl::map([=](Loader *loader) {
|
||||
*buttonState = localLoaderValues->events_starting_with(
|
||||
rawGlobalLoaderPtr() ? rawGlobalLoaderPtr() : localLoader->get()
|
||||
) | rpl::map([=](Loader *loader) {
|
||||
return (loader && loader->id() == id)
|
||||
? loader->state()
|
||||
: rpl::single(
|
||||
|
|
|
|||
|
|
@ -291,7 +291,8 @@ EditCaptionBox::EditCaptionBox(
|
|||
Assert(_thumbnailImageLoaded || _refreshThumbnail);
|
||||
|
||||
if (!_thumbnailImageLoaded) {
|
||||
subscribe(_controller->session().downloaderTaskFinished(), [=] {
|
||||
_controller->session().downloaderTaskFinished(
|
||||
) | rpl::start_with_next([=] {
|
||||
if (_thumbnailImageLoaded
|
||||
|| (_photoMedia && !_photoMedia->image(PhotoSize::Large))
|
||||
|| (_documentMedia && !_documentMedia->thumbnail())) {
|
||||
|
|
@ -299,7 +300,7 @@ EditCaptionBox::EditCaptionBox(
|
|||
}
|
||||
_refreshThumbnail();
|
||||
update();
|
||||
});
|
||||
}, lifetime());
|
||||
}
|
||||
_field.create(
|
||||
this,
|
||||
|
|
|
|||
|
|
@ -698,9 +698,10 @@ PeerListContent::PeerListContent(
|
|||
, _st(st)
|
||||
, _controller(controller)
|
||||
, _rowHeight(_st.item.height) {
|
||||
subscribe(_controller->session().downloaderTaskFinished(), [=] {
|
||||
_controller->session().downloaderTaskFinished(
|
||||
) | rpl::start_with_next([=] {
|
||||
update();
|
||||
});
|
||||
}, lifetime());
|
||||
|
||||
using UpdateFlag = Data::PeerUpdate::Flag;
|
||||
_controller->session().changes().peerUpdates(
|
||||
|
|
|
|||
|
|
@ -570,9 +570,10 @@ ShareBox::Inner::Inner(
|
|||
update.oldFirstLetters);
|
||||
}, lifetime());
|
||||
|
||||
subscribe(_navigation->session().downloaderTaskFinished(), [=] {
|
||||
_navigation->session().downloaderTaskFinished(
|
||||
) | rpl::start_with_next([=] {
|
||||
update();
|
||||
});
|
||||
}, lifetime());
|
||||
|
||||
subscribe(Window::Theme::Background(), [this](const Window::Theme::BackgroundUpdate &update) {
|
||||
if (update.paletteChanged()) {
|
||||
|
|
|
|||
|
|
@ -308,7 +308,10 @@ StickerSetBox::Inner::Inner(
|
|||
|
||||
_controller->session().api().updateStickers();
|
||||
|
||||
subscribe(_controller->session().downloaderTaskFinished(), [this] { update(); });
|
||||
_controller->session().downloaderTaskFinished(
|
||||
) | rpl::start_with_next([=] {
|
||||
update();
|
||||
}, lifetime());
|
||||
|
||||
setMouseTracking(true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1002,10 +1002,12 @@ Main::Session &StickersBox::Inner::session() const {
|
|||
}
|
||||
|
||||
void StickersBox::Inner::setup() {
|
||||
subscribe(session().downloaderTaskFinished(), [this] {
|
||||
session().downloaderTaskFinished(
|
||||
) | rpl::start_with_next([=] {
|
||||
update();
|
||||
readVisibleSets();
|
||||
});
|
||||
}, lifetime());
|
||||
|
||||
setMouseTracking(true);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -446,9 +446,10 @@ void Panel::initLayout() {
|
|||
}, lifetime());
|
||||
processUserPhoto();
|
||||
|
||||
subscribe(_user->session().downloaderTaskFinished(), [=] {
|
||||
_user->session().downloaderTaskFinished(
|
||||
) | rpl::start_with_next([=] {
|
||||
refreshUserPhoto();
|
||||
});
|
||||
}, lifetime());
|
||||
createDefaultCacheImage();
|
||||
|
||||
Ui::Platform::InitOnTopPanel(this);
|
||||
|
|
|
|||
|
|
@ -161,12 +161,14 @@ bool BotKeyboard::moderateKeyActivate(int key) {
|
|||
App::activateBotCommand(item, 0, index);
|
||||
return true;
|
||||
}
|
||||
} else if (key == Qt::Key_Q) {
|
||||
if (const auto user = item->history()->peer->asUser()) {
|
||||
if (user->isBot() && item->from() == user) {
|
||||
} else if (const auto user = item->history()->peer->asUser()) {
|
||||
if (user->isBot() && item->from() == user) {
|
||||
if (key == Qt::Key_Q) {
|
||||
App::sendBotCommand(user, user, qsl("/translate"));
|
||||
return true;
|
||||
} else if (key == Qt::Key_W) {
|
||||
App::sendBotCommand(user, user, qsl("/eng"));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -571,16 +571,20 @@ bool FieldAutocomplete::eventFilter(QObject *obj, QEvent *e) {
|
|||
if (e->type() == QEvent::KeyPress) {
|
||||
QKeyEvent *ev = static_cast<QKeyEvent*>(e);
|
||||
if (!(ev->modifiers() & (Qt::AltModifier | Qt::ControlModifier | Qt::ShiftModifier | Qt::MetaModifier))) {
|
||||
const auto key = ev->key();
|
||||
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))) {
|
||||
return _inner->moveSel(ev->key());
|
||||
} else if (ev->key() == Qt::Key_Enter || ev->key() == Qt::Key_Return) {
|
||||
if (key == Qt::Key_Up || key == Qt::Key_Down || (!_srows.empty() && (key == Qt::Key_Left || key == Qt::Key_Right))) {
|
||||
return _inner->moveSel(key);
|
||||
} else if (key == Qt::Key_Enter || key == Qt::Key_Return) {
|
||||
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;
|
||||
emit moderateKeyActivate(ev->key(), &handled);
|
||||
emit moderateKeyActivate(key, &handled);
|
||||
return handled;
|
||||
}
|
||||
} else if (ev->modifiers() & Qt::ControlModifier) {
|
||||
|
|
@ -608,9 +612,10 @@ FieldAutocompleteInner::FieldAutocompleteInner(
|
|||
, _brows(brows)
|
||||
, _srows(srows)
|
||||
, _previewTimer([=] { showPreview(); }) {
|
||||
subscribe(
|
||||
controller->session().downloaderTaskFinished(),
|
||||
[=] { update(); });
|
||||
controller->session().downloaderTaskFinished(
|
||||
) | rpl::start_with_next([=] {
|
||||
update();
|
||||
}, lifetime());
|
||||
}
|
||||
|
||||
void FieldAutocompleteInner::paintEvent(QPaintEvent *e) {
|
||||
|
|
|
|||
|
|
@ -153,9 +153,10 @@ GifsListWidget::GifsListWidget(
|
|||
refreshSavedGifs();
|
||||
}, lifetime());
|
||||
|
||||
subscribe(controller->session().downloaderTaskFinished(), [this] {
|
||||
controller->session().downloaderTaskFinished(
|
||||
) | rpl::start_with_next([=] {
|
||||
update();
|
||||
});
|
||||
}, lifetime());
|
||||
|
||||
subscribe(controller->gifPauseLevelChanged(), [=] {
|
||||
if (!controller->isGifPausedAtLeastFor(
|
||||
|
|
|
|||
|
|
@ -204,7 +204,7 @@ std::shared_ptr<LargeEmojiImage> EmojiPack::image(EmojiPtr emoji) {
|
|||
if (!strong->image) {
|
||||
strong->load = nullptr;
|
||||
strong->image.emplace(std::move(image));
|
||||
_session->downloaderTaskFinished().notify();
|
||||
_session->notifyDownloaderTaskFinished();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,9 +104,7 @@ struct StickerIcon {
|
|||
|
||||
};
|
||||
|
||||
class StickersListWidget::Footer
|
||||
: public TabbedSelector::InnerFooter
|
||||
, private base::Subscriber {
|
||||
class StickersListWidget::Footer : public TabbedSelector::InnerFooter {
|
||||
public:
|
||||
explicit Footer(not_null<StickersListWidget*> parent);
|
||||
|
||||
|
|
@ -131,7 +129,7 @@ protected:
|
|||
void mousePressEvent(QMouseEvent *e) override;
|
||||
void mouseMoveEvent(QMouseEvent *e) override;
|
||||
void mouseReleaseEvent(QMouseEvent *e) override;
|
||||
bool event(QEvent *e) override;
|
||||
bool eventHook(QEvent *e) override;
|
||||
|
||||
void processHideFinished() override;
|
||||
|
||||
|
|
@ -248,9 +246,10 @@ StickersListWidget::Footer::Footer(not_null<StickersListWidget*> parent)
|
|||
|
||||
_iconsLeft = _iconsRight = st::emojiCategorySkip + st::stickerIconWidth;
|
||||
|
||||
subscribe(_pan->session().downloaderTaskFinished(), [=] {
|
||||
_pan->session().downloaderTaskFinished(
|
||||
) | rpl::start_with_next([=] {
|
||||
update();
|
||||
});
|
||||
}, lifetime());
|
||||
}
|
||||
|
||||
void StickersListWidget::Footer::clearHeavyData() {
|
||||
|
|
@ -599,7 +598,7 @@ void StickersListWidget::Footer::finishDragging() {
|
|||
updateSelected();
|
||||
}
|
||||
|
||||
bool StickersListWidget::Footer::event(QEvent *e) {
|
||||
bool StickersListWidget::Footer::eventHook(QEvent *e) {
|
||||
if (e->type() == QEvent::TouchBegin) {
|
||||
} else if (e->type() == QEvent::Wheel) {
|
||||
if (!_icons.empty()
|
||||
|
|
@ -608,7 +607,7 @@ bool StickersListWidget::Footer::event(QEvent *e) {
|
|||
scrollByWheelEvent(static_cast<QWheelEvent*>(e));
|
||||
}
|
||||
}
|
||||
return InnerFooter::event(e);
|
||||
return InnerFooter::eventHook(e);
|
||||
}
|
||||
|
||||
void StickersListWidget::Footer::scrollByWheelEvent(
|
||||
|
|
@ -889,12 +888,13 @@ StickersListWidget::StickersListWidget(
|
|||
Box<StickersBox>(controller, StickersBox::Section::Installed));
|
||||
});
|
||||
|
||||
subscribe(session().downloaderTaskFinished(), [=] {
|
||||
session().downloaderTaskFinished(
|
||||
) | rpl::start_with_next([=] {
|
||||
if (isVisible()) {
|
||||
update();
|
||||
readVisibleFeatured(getVisibleTop(), getVisibleBottom());
|
||||
}
|
||||
});
|
||||
}, lifetime());
|
||||
|
||||
session().changes().peerUpdates(
|
||||
Data::PeerUpdate::Flag::StickersSet
|
||||
|
|
|
|||
|
|
@ -938,7 +938,7 @@ void TabbedSelector::Inner::panelHideFinished() {
|
|||
}
|
||||
|
||||
TabbedSelector::InnerFooter::InnerFooter(QWidget *parent)
|
||||
: TWidget(parent) {
|
||||
: RpWidget(parent) {
|
||||
resize(st::emojiPanWidth, st::emojiFooterHeight);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -276,7 +276,7 @@ private:
|
|||
|
||||
};
|
||||
|
||||
class TabbedSelector::InnerFooter : public TWidget {
|
||||
class TabbedSelector::InnerFooter : public Ui::RpWidget {
|
||||
public:
|
||||
InnerFooter(QWidget *parent);
|
||||
|
||||
|
|
|
|||
|
|
@ -24,36 +24,43 @@ std::map<int, const char*> BetaLogs() {
|
|||
return {
|
||||
{
|
||||
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,
|
||||
"\xE2\x80\xA2 Organize chats into Chat Folders "
|
||||
"if you have too many chats.\n"
|
||||
"- Organize chats into Chat Folders if you have too many chats.\n"
|
||||
},
|
||||
{
|
||||
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 "
|
||||
"was added to archive.\n"
|
||||
"- Fix crash when a pinned in folder chat was added to archive.\n"
|
||||
|
||||
"\xE2\x80\xA2 Fix font issues in Linux version."
|
||||
"- Fix font issues in Linux version."
|
||||
},
|
||||
{
|
||||
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 "
|
||||
"in JSON format."
|
||||
"- Allow export of a single chat message history in JSON format."
|
||||
},
|
||||
{
|
||||
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) {
|
||||
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 text = qsl("New in version %1:\n\n").arg(version)
|
||||
+ QString::fromUtf8(changes).trimmed();
|
||||
addLocalLog(text);
|
||||
const auto log = qsl("New in version %1:\n\n").arg(version) + text;
|
||||
addLocalLog(log);
|
||||
}
|
||||
|
||||
} // namespace Core
|
||||
|
|
|
|||
|
|
@ -458,7 +458,7 @@ void Settings::resetOnLastLogout() {
|
|||
//_videoPipGeometry = QByteArray();
|
||||
_dictionariesEnabled = std::vector<int>();
|
||||
_autoDownloadDictionaries = true;
|
||||
_mainMenuAccountsShown = false;
|
||||
_mainMenuAccountsShown = true;
|
||||
_tabbedSelectorSectionEnabled = false; // per-window
|
||||
_floatPlayerColumn = Window::Column::Second; // per-window
|
||||
_floatPlayerCorner = RectPart::TopRight; // per-window
|
||||
|
|
|
|||
|
|
@ -464,7 +464,7 @@ private:
|
|||
QByteArray _videoPipGeometry;
|
||||
rpl::variable<std::vector<int>> _dictionariesEnabled;
|
||||
rpl::variable<bool> _autoDownloadDictionaries = true;
|
||||
rpl::variable<bool> _mainMenuAccountsShown = false;
|
||||
rpl::variable<bool> _mainMenuAccountsShown = true;
|
||||
bool _tabbedSelectorSectionEnabled = false; // per-window
|
||||
Window::Column _floatPlayerColumn; // per-window
|
||||
RectPart _floatPlayerCorner; // per-window
|
||||
|
|
|
|||
|
|
@ -282,6 +282,19 @@ void Launcher::init() {
|
|||
|
||||
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"));
|
||||
|
||||
#if defined Q_OS_UNIX && !defined Q_OS_MAC && QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
|
||||
|
|
|
|||
|
|
@ -74,11 +74,11 @@ const auto CommandByName = base::flat_map<QString, Command>{
|
|||
{ qsl("first_chat") , Command::ChatFirst },
|
||||
{ qsl("last_chat") , Command::ChatLast },
|
||||
{ qsl("self_chat") , Command::ChatSelf },
|
||||
|
||||
|
||||
{ qsl("previous_folder") , Command::FolderPrevious },
|
||||
{ qsl("next_folder") , Command::FolderNext },
|
||||
{ qsl("all_chats") , Command::ShowAllChats },
|
||||
|
||||
|
||||
{ qsl("folder1") , Command::ShowFolder1 },
|
||||
{ qsl("folder2") , Command::ShowFolder2 },
|
||||
{ qsl("folder3") , Command::ShowFolder3 },
|
||||
|
|
@ -137,11 +137,11 @@ const auto CommandNames = base::flat_map<Command, QString>{
|
|||
{ Command::ChatFirst , qsl("first_chat") },
|
||||
{ Command::ChatLast , qsl("last_chat") },
|
||||
{ Command::ChatSelf , qsl("self_chat") },
|
||||
|
||||
|
||||
{ Command::FolderPrevious , qsl("previous_folder") },
|
||||
{ Command::FolderNext , qsl("next_folder") },
|
||||
{ Command::ShowAllChats , qsl("all_chats") },
|
||||
|
||||
|
||||
{ Command::ShowFolder1 , qsl("folder1") },
|
||||
{ Command::ShowFolder2 , qsl("folder2") },
|
||||
{ Command::ShowFolder3 , qsl("folder3") },
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "base/const_string.h"
|
||||
#include "kotato/version.h"
|
||||
|
||||
#define TDESKTOP_REQUESTED_ALPHA_VERSION (2001007004ULL)
|
||||
#define TDESKTOP_REQUESTED_ALPHA_VERSION (0ULL)
|
||||
|
||||
#ifdef TDESKTOP_ALLOW_CLOSED_ALPHA
|
||||
#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 AppName = "Kotatogram Desktop"_cs;
|
||||
constexpr auto AppFile = "Kotatogram"_cs;
|
||||
constexpr auto AppVersion = 2001016;
|
||||
constexpr auto AppVersionStr = "2.1.16";
|
||||
constexpr auto AppVersion = 2001017;
|
||||
constexpr auto AppVersionStr = "2.1.17";
|
||||
constexpr auto AppBetaVersion = true;
|
||||
constexpr auto AppAlphaVersion = TDESKTOP_ALPHA_VERSION;
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ void CloudImageView::set(
|
|||
not_null<Main::Session*> session,
|
||||
QImage image) {
|
||||
_image.emplace(std::move(image));
|
||||
session->downloaderTaskFinished().notify();
|
||||
session->notifyDownloaderTaskFinished();
|
||||
}
|
||||
|
||||
CloudImage::CloudImage() = default;
|
||||
|
|
|
|||
|
|
@ -222,8 +222,7 @@ void CloudThemes::loadDocumentAndInvoke(
|
|||
return;
|
||||
}
|
||||
if (!alreadyWaiting) {
|
||||
base::ObservableViewer(
|
||||
_session->downloaderTaskFinished()
|
||||
_session->downloaderTaskFinished(
|
||||
) | rpl::filter([=, &value] {
|
||||
return value.documentMedia->loaded();
|
||||
}) | rpl::start_with_next([=, &value] {
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "platform/platform_specific.h"
|
||||
#include "history/history.h"
|
||||
#include "history/history_item.h"
|
||||
#include "history/view/media/history_view_gif.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "storage/cache/storage_cache_database.h"
|
||||
#include "boxes/confirm_box.h"
|
||||
|
|
@ -340,7 +341,9 @@ void DocumentOpenClickHandler::Open(
|
|||
|| data->isVideoMessage()) {
|
||||
const auto msgId = context ? context->fullId() : FullMsgId();
|
||||
Media::Player::instance()->playPause({ data, msgId });
|
||||
} else if (context && data->isAnimation()) {
|
||||
} else if (context
|
||||
&& data->isAnimation()
|
||||
&& HistoryView::Gif::CanPlayInline(data)) {
|
||||
data->owner().requestAnimationPlayInline(context);
|
||||
} else {
|
||||
Core::App().showDocument(data, context);
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@ void DocumentMedia::setGoodThumbnail(QImage thumbnail) {
|
|||
return;
|
||||
}
|
||||
_goodThumbnail = std::make_unique<Image>(std::move(thumbnail));
|
||||
_owner->session().downloaderTaskFinished().notify();
|
||||
_owner->session().notifyDownloaderTaskFinished();
|
||||
}
|
||||
|
||||
Image *DocumentMedia::thumbnailInline() const {
|
||||
|
|
@ -207,7 +207,7 @@ QSize DocumentMedia::thumbnailSize() const {
|
|||
|
||||
void DocumentMedia::setThumbnail(QImage thumbnail) {
|
||||
_thumbnail = std::make_unique<Image>(std::move(thumbnail));
|
||||
_owner->session().downloaderTaskFinished().notify();
|
||||
_owner->session().notifyDownloaderTaskFinished();
|
||||
}
|
||||
|
||||
QByteArray DocumentMedia::videoThumbnailContent() const {
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ void PhotoMedia::set(PhotoSize size, QImage image) {
|
|||
Qt::SmoothTransformation);
|
||||
}
|
||||
_images[index] = std::make_unique<Image>(std::move(image));
|
||||
_owner->session().downloaderTaskFinished().notify();
|
||||
_owner->session().notifyDownloaderTaskFinished();
|
||||
}
|
||||
|
||||
bool PhotoMedia::loaded() const {
|
||||
|
|
|
|||
|
|
@ -1279,7 +1279,8 @@ rpl::producer<not_null<ViewElement*>> Session::viewResizeRequest() const {
|
|||
|
||||
void Session::requestItemViewRefresh(not_null<HistoryItem*> item) {
|
||||
if (const auto view = item->mainView()) {
|
||||
view->setPendingResize();
|
||||
notifyHistoryChangeDelayed(item->history());
|
||||
view->refreshInBlock();
|
||||
}
|
||||
_itemViewRefreshRequest.fire_copy(item);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ void StickersSetThumbnailView::set(
|
|||
} else {
|
||||
_image = std::make_unique<Image>(std::move(image));
|
||||
}
|
||||
session->downloaderTaskFinished().notify();
|
||||
session->notifyDownloaderTaskFinished();
|
||||
}
|
||||
|
||||
Image *StickersSetThumbnailView::image() const {
|
||||
|
|
|
|||
|
|
@ -140,7 +140,10 @@ InnerWidget::InnerWidget(
|
|||
});
|
||||
_cancelSearchFromUser->hide();
|
||||
|
||||
subscribe(session().downloaderTaskFinished(), [=] { update(); });
|
||||
session().downloaderTaskFinished(
|
||||
) | rpl::start_with_next([=] {
|
||||
update();
|
||||
}, lifetime());
|
||||
|
||||
subscribe(Core::App().notifications().settingsChanged(), [=](
|
||||
Window::Notifications::ChangeType change) {
|
||||
|
|
|
|||
|
|
@ -161,7 +161,8 @@ void Widget::BottomButton::paintEvent(QPaintEvent *e) {
|
|||
Widget::Widget(
|
||||
QWidget *parent,
|
||||
not_null<Window::SessionController*> controller)
|
||||
: Window::AbstractSectionWidget(parent, controller)
|
||||
: Window::AbstractSectionWidget(parent, controller)
|
||||
, _api(&controller->session().mtp())
|
||||
, _searchControls(this)
|
||||
, _mainMenuToggle(_searchControls, st::dialogsMenuToggle)
|
||||
, _searchForNarrowFilters(_searchControls, st::dialogsSearchForNarrowFilters)
|
||||
|
|
@ -435,7 +436,9 @@ void Widget::fullSearchRefreshOn(rpl::producer<> events) {
|
|||
_searchTimer.stop();
|
||||
_searchCache.clear();
|
||||
_singleMessageSearch.clear();
|
||||
_searchQueries.clear();
|
||||
for (const auto &[requestId, query] : base::take(_searchQueries)) {
|
||||
session().api().request(requestId).cancel();
|
||||
}
|
||||
_searchQuery = QString();
|
||||
_scroll->scrollToY(0);
|
||||
cancelSearchRequest();
|
||||
|
|
@ -771,7 +774,7 @@ bool Widget::onSearchMessages(bool searchCache) {
|
|||
auto q = _filter->getLastText().trimmed();
|
||||
if (q.isEmpty() && !_searchFromUser) {
|
||||
cancelSearchRequest();
|
||||
session().api().request(base::take(_peerSearchRequest)).cancel();
|
||||
_api.request(base::take(_peerSearchRequest)).cancel();
|
||||
return true;
|
||||
}
|
||||
if (searchCache) {
|
||||
|
|
@ -781,8 +784,8 @@ bool Widget::onSearchMessages(bool searchCache) {
|
|||
if (!success) {
|
||||
return false;
|
||||
}
|
||||
const auto i = _searchCache.constFind(q);
|
||||
if (i != _searchCache.cend()) {
|
||||
const auto i = _searchCache.find(q);
|
||||
if (i != _searchCache.end()) {
|
||||
_searchQuery = q;
|
||||
_searchQueryFrom = _searchFromUser;
|
||||
_searchNextRate = 0;
|
||||
|
|
@ -792,7 +795,7 @@ bool Widget::onSearchMessages(bool searchCache) {
|
|||
_searchInChat
|
||||
? SearchRequestType::PeerFromStart
|
||||
: SearchRequestType::FromStart,
|
||||
i.value(),
|
||||
i->second,
|
||||
0);
|
||||
result = true;
|
||||
}
|
||||
|
|
@ -836,7 +839,7 @@ bool Widget::onSearchMessages(bool searchCache) {
|
|||
_searchInHistoryRequest = 0;
|
||||
finish();
|
||||
}).send();
|
||||
_searchQueries.insert(_searchRequest, _searchQuery);
|
||||
_searchQueries.emplace(_searchRequest, _searchQuery);
|
||||
return _searchRequest;
|
||||
});
|
||||
//} else if (const auto feed = _searchInChat.feed()) { // #feed
|
||||
|
|
@ -853,7 +856,7 @@ bool Widget::onSearchMessages(bool searchCache) {
|
|||
// }).fail([=](const RPCError &error) {
|
||||
// searchFailed(type, error, _searchRequest);
|
||||
// }).send();
|
||||
// _searchQueries.insert(_searchRequest, _searchQuery);
|
||||
// _searchQueries.emplace(_searchRequest, _searchQuery);
|
||||
} else {
|
||||
const auto type = SearchRequestType::FromStart;
|
||||
const auto flags = session().settings().skipArchiveInSearch()
|
||||
|
|
@ -873,23 +876,23 @@ bool Widget::onSearchMessages(bool searchCache) {
|
|||
}).fail([=](const RPCError &error) {
|
||||
searchFailed(type, error, _searchRequest);
|
||||
}).send();
|
||||
_searchQueries.insert(_searchRequest, _searchQuery);
|
||||
_searchQueries.emplace(_searchRequest, _searchQuery);
|
||||
}
|
||||
}
|
||||
const auto query = Api::ConvertPeerSearchQuery(q);
|
||||
if (searchForPeersRequired(query)) {
|
||||
if (searchCache) {
|
||||
auto i = _peerSearchCache.constFind(query);
|
||||
if (i != _peerSearchCache.cend()) {
|
||||
auto i = _peerSearchCache.find(query);
|
||||
if (i != _peerSearchCache.end()) {
|
||||
_peerSearchQuery = query;
|
||||
_peerSearchRequest = 0;
|
||||
peerSearchReceived(i.value(), 0);
|
||||
peerSearchReceived(i->second, 0);
|
||||
result = true;
|
||||
}
|
||||
} else if (_peerSearchQuery != query) {
|
||||
_peerSearchQuery = query;
|
||||
_peerSearchFull = false;
|
||||
_peerSearchRequest = session().api().request(MTPcontacts_Search(
|
||||
_peerSearchRequest = _api.request(MTPcontacts_Search(
|
||||
MTP_string(_peerSearchQuery),
|
||||
MTP_int(SearchPeopleLimit)
|
||||
)).done([=](const MTPcontacts_Found &result, mtpRequestId requestId) {
|
||||
|
|
@ -897,7 +900,7 @@ bool Widget::onSearchMessages(bool searchCache) {
|
|||
}).fail([=](const RPCError &error, mtpRequestId requestId) {
|
||||
peopleFailed(error, requestId);
|
||||
}).send();
|
||||
_peerSearchQueries.insert(_peerSearchRequest, _peerSearchQuery);
|
||||
_peerSearchQueries.emplace(_peerSearchRequest, _peerSearchQuery);
|
||||
}
|
||||
} else {
|
||||
_peerSearchQuery = query;
|
||||
|
|
@ -1013,7 +1016,7 @@ void Widget::onSearchMore() {
|
|||
finish();
|
||||
}).send();
|
||||
if (!offsetId) {
|
||||
_searchQueries.insert(_searchRequest, _searchQuery);
|
||||
_searchQueries.emplace(_searchRequest, _searchQuery);
|
||||
}
|
||||
return _searchRequest;
|
||||
});
|
||||
|
|
@ -1036,7 +1039,7 @@ void Widget::onSearchMore() {
|
|||
// searchFailed(type, error, _searchRequest);
|
||||
// }).send();
|
||||
// if (!offsetId) {
|
||||
// _searchQueries.insert(_searchRequest, _searchQuery);
|
||||
// _searchQueries.emplace(_searchRequest, _searchQuery);
|
||||
// }
|
||||
} else {
|
||||
const auto type = offsetId
|
||||
|
|
@ -1062,7 +1065,7 @@ void Widget::onSearchMore() {
|
|||
searchFailed(type, error, _searchRequest);
|
||||
}).send();
|
||||
if (!offsetId) {
|
||||
_searchQueries.insert(_searchRequest, _searchQuery);
|
||||
_searchQueries.emplace(_searchRequest, _searchQuery);
|
||||
}
|
||||
}
|
||||
} else if (_searchInMigrated && !_searchFullMigrated) {
|
||||
|
|
@ -1115,8 +1118,8 @@ void Widget::searchReceived(
|
|||
if (state == WidgetState::Filtered) {
|
||||
if (type == SearchRequestType::FromStart || type == SearchRequestType::PeerFromStart) {
|
||||
auto i = _searchQueries.find(requestId);
|
||||
if (i != _searchQueries.cend()) {
|
||||
_searchCache[i.value()] = result;
|
||||
if (i != _searchQueries.end()) {
|
||||
_searchCache[i->second] = result;
|
||||
_searchQueries.erase(i);
|
||||
}
|
||||
}
|
||||
|
|
@ -1224,9 +1227,8 @@ void Widget::peerSearchReceived(
|
|||
auto q = _peerSearchQuery;
|
||||
if (state == WidgetState::Filtered) {
|
||||
auto i = _peerSearchQueries.find(requestId);
|
||||
if (i != _peerSearchQueries.cend()) {
|
||||
q = i.value();
|
||||
_peerSearchCache[q] = result;
|
||||
if (i != _peerSearchQueries.end()) {
|
||||
_peerSearchCache[i->second] = result;
|
||||
_peerSearchQueries.erase(i);
|
||||
}
|
||||
}
|
||||
|
|
@ -1368,7 +1370,9 @@ void Widget::applyFilterUpdate(bool force) {
|
|||
|
||||
if (filterText.isEmpty()) {
|
||||
_peerSearchCache.clear();
|
||||
_peerSearchQueries.clear();
|
||||
for (const auto &[requestId, query] : base::take(_peerSearchQueries)) {
|
||||
_api.request(requestId).cancel();
|
||||
}
|
||||
_peerSearchQuery = QString();
|
||||
}
|
||||
|
||||
|
|
@ -1425,7 +1429,9 @@ void Widget::setSearchInChat(Key chat, UserData *from) {
|
|||
void Widget::clearSearchCache() {
|
||||
_searchCache.clear();
|
||||
_singleMessageSearch.clear();
|
||||
_searchQueries.clear();
|
||||
for (const auto &[requestId, query] : base::take(_searchQueries)) {
|
||||
session().api().request(requestId).cancel();
|
||||
}
|
||||
_searchQuery = QString();
|
||||
_searchQueryFrom = nullptr;
|
||||
cancelSearchRequest();
|
||||
|
|
@ -1729,10 +1735,8 @@ void Widget::scrollToEntry(const RowDescriptor &entry) {
|
|||
|
||||
void Widget::cancelSearchRequest() {
|
||||
session().api().request(base::take(_searchRequest)).cancel();
|
||||
if (_searchInHistoryRequest) {
|
||||
session().data().histories().cancelRequest(_searchInHistoryRequest);
|
||||
_searchInHistoryRequest = 0;
|
||||
}
|
||||
session().data().histories().cancelRequest(
|
||||
base::take(_searchInHistoryRequest));
|
||||
}
|
||||
|
||||
bool Widget::onCancelSearch() {
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/effects/animations.h"
|
||||
#include "ui/widgets/scroll_area.h"
|
||||
#include "ui/special_buttons.h"
|
||||
#include "mtproto/sender.h"
|
||||
#include "api/api_single_message_search.h"
|
||||
|
||||
class RPCError;
|
||||
|
|
@ -174,6 +175,8 @@ private:
|
|||
void startScrollUpButtonAnimation(bool shown);
|
||||
void updateScrollUpPosition();
|
||||
|
||||
MTP::Sender _api;
|
||||
|
||||
bool _dragInScroll = false;
|
||||
bool _dragForward = false;
|
||||
QTimer _chooseByDragTimer;
|
||||
|
|
@ -225,11 +228,11 @@ private:
|
|||
int _searchInHistoryRequest = 0; // Not real mtpRequestId.
|
||||
mtpRequestId _searchRequest = 0;
|
||||
|
||||
QMap<QString, MTPmessages_Messages> _searchCache;
|
||||
base::flat_map<QString, MTPmessages_Messages> _searchCache;
|
||||
Api::SingleMessageSearch _singleMessageSearch;
|
||||
QMap<mtpRequestId, QString> _searchQueries;
|
||||
QMap<QString, MTPcontacts_Found> _peerSearchCache;
|
||||
QMap<mtpRequestId, QString> _peerSearchQueries;
|
||||
base::flat_map<mtpRequestId, QString> _searchQueries;
|
||||
base::flat_map<QString, MTPcontacts_Found> _peerSearchCache;
|
||||
base::flat_map<mtpRequestId, QString> _peerSearchQueries;
|
||||
|
||||
QPixmap _widthAnimationCache;
|
||||
|
||||
|
|
|
|||
|
|
@ -230,6 +230,7 @@ void showPeerProfile(not_null<PeerData*> peer) {
|
|||
if (const auto controller = window->sessionController()) {
|
||||
if (&controller->session() == &peer->session()) {
|
||||
controller->showPeerInfo(peer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (&Core::App().domain().active() != &peer->session().account()) {
|
||||
|
|
|
|||
|
|
@ -178,10 +178,6 @@ HistoryInner::HistoryInner(
|
|||
) | rpl::start_with_next(
|
||||
[this](auto view) { viewRemoved(view); },
|
||||
lifetime());
|
||||
session().data().itemViewRefreshRequest(
|
||||
) | rpl::start_with_next(
|
||||
[this](auto item) { refreshView(item); },
|
||||
lifetime());
|
||||
rpl::merge(
|
||||
session().data().historyUnloaded(),
|
||||
session().data().historyCleared()
|
||||
|
|
@ -1316,32 +1312,15 @@ void HistoryInner::itemRemoved(not_null<const HistoryItem*> item) {
|
|||
}
|
||||
|
||||
void HistoryInner::viewRemoved(not_null<const Element*> view) {
|
||||
if (_dragSelFrom == view) {
|
||||
_dragSelFrom = nullptr;
|
||||
}
|
||||
if (_dragSelTo == view) {
|
||||
_dragSelTo = nullptr;
|
||||
}
|
||||
if (_scrollDateLastItem == view) {
|
||||
_scrollDateLastItem = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
const auto refresh = [&](auto &saved) {
|
||||
if (saved == view) {
|
||||
const auto now = view->data()->mainView();
|
||||
saved = (now && now != view) ? now : nullptr;
|
||||
}
|
||||
};
|
||||
refresh(_dragSelFrom);
|
||||
refresh(_dragSelTo);
|
||||
refresh(_scrollDateLastItem);
|
||||
}
|
||||
|
||||
void HistoryInner::mouseActionFinish(
|
||||
|
|
|
|||
|
|
@ -239,7 +239,6 @@ private:
|
|||
|
||||
void itemRemoved(not_null<const HistoryItem*> item);
|
||||
void viewRemoved(not_null<const Element*> view);
|
||||
void refreshView(not_null<HistoryItem*> item);
|
||||
|
||||
void touchResetSpeed();
|
||||
void touchUpdateSpeed();
|
||||
|
|
|
|||
|
|
@ -307,7 +307,11 @@ HistoryWidget::HistoryWidget(
|
|||
, _topShadow(this) {
|
||||
setAcceptDrops(true);
|
||||
|
||||
subscribe(session().downloaderTaskFinished(), [=] { update(); });
|
||||
session().downloaderTaskFinished(
|
||||
) | rpl::start_with_next([=] {
|
||||
update();
|
||||
}, lifetime());
|
||||
|
||||
connect(_scroll, SIGNAL(scrolled()), this, SLOT(onScroll()));
|
||||
_historyDown->addClickHandler([=] { historyDownClicked(); });
|
||||
_unreadMentions->addClickHandler([=] { showNextUnreadMention(); });
|
||||
|
|
@ -500,15 +504,6 @@ HistoryWidget::HistoryWidget(
|
|||
}
|
||||
}, 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(
|
||||
) | rpl::start_with_next([=] {
|
||||
crl::on_main(this, [=] {
|
||||
|
|
|
|||
|
|
@ -577,6 +577,9 @@ void TopBarWidget::updateSearchVisibility() {
|
|||
}
|
||||
|
||||
void TopBarWidget::updateControlsGeometry() {
|
||||
if (!_activeChat) {
|
||||
return;
|
||||
}
|
||||
auto hasSelected = (_selectedCount > 0);
|
||||
auto selectedButtonsTop = countSelectedButtonsTop(_selectedShown.value(hasSelected ? 1. : 0.));
|
||||
auto otherButtonsTop = selectedButtonsTop + st::topBarHeight;
|
||||
|
|
@ -663,7 +666,9 @@ void TopBarWidget::setAnimatingMode(bool enabled) {
|
|||
}
|
||||
|
||||
void TopBarWidget::updateControlsVisibility() {
|
||||
if (_animatingMode) {
|
||||
if (!_activeChat) {
|
||||
return;
|
||||
} else if (_animatingMode) {
|
||||
hideChildren();
|
||||
return;
|
||||
}
|
||||
|
|
@ -708,14 +713,12 @@ void TopBarWidget::updateControlsVisibility() {
|
|||
|
||||
void TopBarWidget::updateMembersShowArea() {
|
||||
const auto membersShowAreaNeeded = [&] {
|
||||
auto peer = _controller->content()->peer();
|
||||
const auto peer = _activeChat.peer();
|
||||
if ((_selectedCount > 0) || !peer) {
|
||||
return false;
|
||||
}
|
||||
if (auto chat = peer->asChat()) {
|
||||
} else if (const auto chat = peer->asChat()) {
|
||||
return chat->amIn();
|
||||
}
|
||||
if (auto megagroup = peer->asMegagroup()) {
|
||||
} else if (const auto megagroup = peer->asMegagroup()) {
|
||||
return megagroup->canViewMembers()
|
||||
&& (megagroup->membersCount()
|
||||
< megagroup->session().serverConfig().chatSizeMax);
|
||||
|
|
|
|||
|
|
@ -51,11 +51,6 @@ int gifMaxStatusWidth(DocumentData *document) {
|
|||
return result;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool CanPlayInline(not_null<DocumentData*> document) {
|
||||
const auto dimensions = document->dimensions;
|
||||
return dimensions.width() * dimensions.height() <= kMaxInlineArea;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
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 {
|
||||
// We use size only for aspect ratio and we want to have it
|
||||
// as close to the thumbnail as possible.
|
||||
|
|
|
|||
|
|
@ -110,6 +110,8 @@ public:
|
|||
|
||||
void refreshParentId(not_null<HistoryItem*> realParent) override;
|
||||
|
||||
[[nodiscard]] static bool CanPlayInline(not_null<DocumentData*> document);
|
||||
|
||||
private:
|
||||
struct Streamed;
|
||||
|
||||
|
|
|
|||
|
|
@ -172,7 +172,9 @@ PointState Media::pointState(QPoint point) const {
|
|||
: 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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ using SharedMediaTypesMask = base::enum_mask<SharedMediaType>;
|
|||
|
||||
namespace Lottie {
|
||||
class SinglePlayer;
|
||||
struct ColorReplacements;
|
||||
} // namespace Lottie
|
||||
|
||||
namespace HistoryView {
|
||||
|
|
@ -145,7 +146,9 @@ public:
|
|||
}
|
||||
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() {
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,9 @@ constexpr auto kMaxForwardedBarLines = 4;
|
|||
|
||||
} // namespace
|
||||
|
||||
auto UnwrappedMedia::Content::stickerTakeLottie()
|
||||
auto UnwrappedMedia::Content::stickerTakeLottie(
|
||||
not_null<DocumentData*> data,
|
||||
const Lottie::ColorReplacements *replacements)
|
||||
-> std::unique_ptr<Lottie::SinglePlayer> {
|
||||
return nullptr;
|
||||
}
|
||||
|
|
@ -394,8 +396,10 @@ TextState UnwrappedMedia::textState(QPoint point, StateRequest request) const {
|
|||
return result;
|
||||
}
|
||||
|
||||
std::unique_ptr<Lottie::SinglePlayer> UnwrappedMedia::stickerTakeLottie() {
|
||||
return _content->stickerTakeLottie();
|
||||
std::unique_ptr<Lottie::SinglePlayer> UnwrappedMedia::stickerTakeLottie(
|
||||
not_null<DocumentData*> data,
|
||||
const Lottie::ColorReplacements *replacements) {
|
||||
return _content->stickerTakeLottie(data, replacements);
|
||||
}
|
||||
|
||||
int UnwrappedMedia::calculateFullRight(const QRect &inner) const {
|
||||
|
|
|
|||
|
|
@ -34,7 +34,9 @@ public:
|
|||
}
|
||||
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 {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -85,7 +87,9 @@ public:
|
|||
void stickerClearLoopPlayed() override {
|
||||
_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 {
|
||||
return _content->hasHeavyPart();
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ Sticker::Sticker(
|
|||
_data->loadThumbnail(parent->data()->fullId());
|
||||
}
|
||||
if (const auto media = replacing ? replacing->media() : nullptr) {
|
||||
_lottie = media->stickerTakeLottie();
|
||||
_lottie = media->stickerTakeLottie(_data, _replacements);
|
||||
if (_lottie) {
|
||||
lottieCreated();
|
||||
}
|
||||
|
|
@ -344,8 +344,12 @@ void Sticker::unloadLottie() {
|
|||
_parent->checkHeavyPart();
|
||||
}
|
||||
|
||||
std::unique_ptr< Lottie::SinglePlayer> Sticker::stickerTakeLottie() {
|
||||
return std::move(_lottie);
|
||||
std::unique_ptr<Lottie::SinglePlayer> Sticker::stickerTakeLottie(
|
||||
not_null<DocumentData*> data,
|
||||
const Lottie::ColorReplacements *replacements) {
|
||||
return (data == _data && replacements == _replacements)
|
||||
? std::move(_lottie)
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
} // namespace HistoryView
|
||||
|
|
|
|||
|
|
@ -50,7 +50,9 @@ public:
|
|||
void stickerClearLoopPlayed() override {
|
||||
_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;
|
||||
void unloadHeavyPart() override;
|
||||
|
|
|
|||
|
|
@ -590,21 +590,27 @@ void ListWidget::start() {
|
|||
invalidatePaletteCache();
|
||||
}
|
||||
}, lifetime());
|
||||
ObservableViewer(
|
||||
session().downloaderTaskFinished()
|
||||
) | rpl::start_with_next([this] { update(); }, lifetime());
|
||||
|
||||
session().downloaderTaskFinished(
|
||||
) | rpl::start_with_next([=] {
|
||||
update();
|
||||
}, lifetime());
|
||||
|
||||
session().data().itemLayoutChanged(
|
||||
) | rpl::start_with_next([this](auto item) {
|
||||
itemLayoutChanged(item);
|
||||
}, lifetime());
|
||||
|
||||
session().data().itemRemoved(
|
||||
) | rpl::start_with_next([this](auto item) {
|
||||
itemRemoved(item);
|
||||
}, lifetime());
|
||||
|
||||
session().data().itemRepaintRequest(
|
||||
) | rpl::start_with_next([this](auto item) {
|
||||
repaintItem(item);
|
||||
}, lifetime());
|
||||
|
||||
_controller->mediaSourceQueryValue(
|
||||
) | rpl::start_with_next([this]{
|
||||
restart();
|
||||
|
|
|
|||
|
|
@ -681,7 +681,7 @@ void ActionsFiller::addClearHistoryAction(not_null<UserData*> user) {
|
|||
_wrap,
|
||||
tr::lng_profile_clear_history(),
|
||||
rpl::single(true),
|
||||
Window::ClearHistoryHandler(user));
|
||||
Window::ClearHistoryHandler(user));
|
||||
}
|
||||
|
||||
void ActionsFiller::addDeleteConversationAction(
|
||||
|
|
|
|||
|
|
@ -58,9 +58,11 @@ Inner::Inner(
|
|||
setMouseTracking(true);
|
||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||
|
||||
subscribe(_controller->session().downloaderTaskFinished(), [this] {
|
||||
_controller->session().downloaderTaskFinished(
|
||||
) | rpl::start_with_next([=] {
|
||||
update();
|
||||
});
|
||||
}, lifetime());
|
||||
|
||||
subscribe(controller->gifPauseLevelChanged(), [this] {
|
||||
if (!_controller->isGifPausedAtLeastFor(Window::GifPauseReason::InlineResults)) {
|
||||
update();
|
||||
|
|
|
|||
|
|
@ -187,16 +187,18 @@ void PasswordCheckWidget::requestPasswordData() {
|
|||
).done([=](const MTPaccount_Password &result) {
|
||||
_sentRequest = 0;
|
||||
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();
|
||||
});
|
||||
}).send();
|
||||
}
|
||||
|
||||
void PasswordCheckWidget::passwordChecked() {
|
||||
if (!_request || !_request.id) {
|
||||
return serverError();
|
||||
}
|
||||
const auto check = Core::ComputeCloudPasswordCheck(
|
||||
_request,
|
||||
_passwordHash);
|
||||
|
|
|
|||
|
|
@ -725,6 +725,9 @@ void Widget::paintEvent(QPaintEvent *e) {
|
|||
}
|
||||
|
||||
void Widget::resizeEvent(QResizeEvent *e) {
|
||||
if (_stepHistory.empty()) {
|
||||
return;
|
||||
}
|
||||
for (const auto step : _stepHistory) {
|
||||
step->setGeometry(rect());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -542,7 +542,7 @@ void CloudManager::performSwitchToCustom() {
|
|||
};
|
||||
const auto text = tr::lng_sure_save_language(tr::now)
|
||||
+ "\n\n"
|
||||
+ getValue(tr::lng_sure_save_language.base);
|
||||
+ getValue(tr::lng_sure_save_language.base);
|
||||
const auto change = [=] {
|
||||
_langpack.switchToCustomFile(filePath);
|
||||
App::restart();
|
||||
|
|
|
|||
|
|
@ -270,6 +270,13 @@ not_null<Main::Account*> Domain::add(MTP::Environment environment) {
|
|||
_local->startAdded(account, std::move(config));
|
||||
watchSession(account);
|
||||
_accountsChanges.fire({});
|
||||
|
||||
auto &settings = Core::App().settings();
|
||||
if (_accounts.size() == 2 && !settings.mainMenuAccountsShown()) {
|
||||
settings.setMainMenuAccountsShown(true);
|
||||
Core::App().saveSettingsDelayed();
|
||||
}
|
||||
|
||||
return account;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -181,7 +181,11 @@ Storage::Domain &Session::domainLocal() const {
|
|||
return _account->domainLocal();
|
||||
}
|
||||
|
||||
base::Observable<void> &Session::downloaderTaskFinished() {
|
||||
void Session::notifyDownloaderTaskFinished() {
|
||||
downloader().notifyTaskFinished();
|
||||
}
|
||||
|
||||
rpl::producer<> Session::downloaderTaskFinished() const {
|
||||
return downloader().taskFinished();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -121,7 +121,8 @@ public:
|
|||
-> const base::flat_set<not_null<Window::SessionController*>> &;
|
||||
|
||||
// Shortcuts.
|
||||
[[nodiscard]] base::Observable<void> &downloaderTaskFinished();
|
||||
void notifyDownloaderTaskFinished();
|
||||
[[nodiscard]] rpl::producer<> downloaderTaskFinished() const;
|
||||
[[nodiscard]] MTP::DcId mainDcId() const;
|
||||
[[nodiscard]] MTP::Instance &mtp() const;
|
||||
[[nodiscard]] const MTP::ConfigFields &serverConfig() const;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "media/audio/media_child_ffmpeg_loader.h"
|
||||
#include "media/audio/media_audio_loaders.h"
|
||||
#include "media/audio/media_audio_track.h"
|
||||
#include "media/audio/media_openal_functions.h"
|
||||
#include "media/streaming/media_streaming_utility.h"
|
||||
#include "data/data_document.h"
|
||||
#include "data/data_file_origin.h"
|
||||
|
|
@ -22,9 +23,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
|
||||
#include <al.h>
|
||||
#include <alc.h>
|
||||
#ifndef TDESKTOP_DISABLE_OPENAL_EFFECTS
|
||||
#include <alext.h>
|
||||
#endif // !TDESKTOP_DISABLE_OPENAL_EFFECTS
|
||||
|
||||
#include <numeric>
|
||||
|
||||
|
|
@ -205,6 +203,7 @@ void Start(not_null<Instance*> instance) {
|
|||
auto loglevel = getenv("ALSOFT_LOGLEVEL");
|
||||
LOG(("OpenAL Logging Level: %1").arg(loglevel ? loglevel : "(not set)"));
|
||||
|
||||
OpenAL::LoadEFXExtension();
|
||||
EnumeratePlaybackDevices();
|
||||
EnumerateCaptureDevices();
|
||||
|
||||
|
|
@ -281,11 +280,7 @@ void StopDetachIfNotUsedSafe() {
|
|||
}
|
||||
|
||||
bool SupportsSpeedControl() {
|
||||
#ifndef TDESKTOP_DISABLE_OPENAL_EFFECTS
|
||||
return true;
|
||||
#else // TDESKTOP_DISABLE_OPENAL_EFFECTS
|
||||
return false;
|
||||
#endif // TDESKTOP_DISABLE_OPENAL_EFFECTS
|
||||
return OpenAL::HasEFXExtension();
|
||||
}
|
||||
|
||||
} // namespace Audio
|
||||
|
|
@ -331,40 +326,44 @@ void Mixer::Track::createStream(AudioMsgId::Type type) {
|
|||
alSourcei(stream.source, AL_SOURCE_RELATIVE, 1);
|
||||
alSourcei(stream.source, AL_ROLLOFF_FACTOR, 0);
|
||||
alGenBuffers(3, stream.buffers);
|
||||
#ifndef TDESKTOP_DISABLE_OPENAL_EFFECTS
|
||||
if (speedEffect) {
|
||||
applySourceSpeedEffect();
|
||||
} else {
|
||||
removeSourceSpeedEffect();
|
||||
}
|
||||
#endif // TDESKTOP_DISABLE_OPENAL_EFFECTS
|
||||
}
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_OPENAL_EFFECTS
|
||||
void Mixer::Track::removeSourceSpeedEffect() {
|
||||
alSource3i(stream.source, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, 0);
|
||||
alSourcei(stream.source, AL_DIRECT_FILTER, AL_FILTER_NULL);
|
||||
if (!Audio::SupportsSpeedControl()) {
|
||||
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);
|
||||
}
|
||||
|
||||
void Mixer::Track::applySourceSpeedEffect() {
|
||||
if (!Audio::SupportsSpeedControl()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Expects(speedEffect != nullptr);
|
||||
|
||||
if (!speedEffect->effect || !alIsEffect(speedEffect->effect)) {
|
||||
alGenAuxiliaryEffectSlots(1, &speedEffect->effectSlot);
|
||||
alGenEffects(1, &speedEffect->effect);
|
||||
alGenFilters(1, &speedEffect->filter);
|
||||
alEffecti(speedEffect->effect, AL_EFFECT_TYPE, AL_EFFECT_PITCH_SHIFTER);
|
||||
alFilteri(speedEffect->filter, AL_FILTER_TYPE, AL_FILTER_LOWPASS);
|
||||
alFilterf(speedEffect->filter, AL_LOWPASS_GAIN, 0.f);
|
||||
if (!speedEffect->effect || !OpenAL::alIsEffect(speedEffect->effect)) {
|
||||
OpenAL::alGenAuxiliaryEffectSlots(1, &speedEffect->effectSlot);
|
||||
OpenAL::alGenEffects(1, &speedEffect->effect);
|
||||
OpenAL::alGenFilters(1, &speedEffect->filter);
|
||||
OpenAL::alEffecti(speedEffect->effect, alGetEnumValue("AL_EFFECT_TYPE"), alGetEnumValue("AL_EFFECT_PITCH_SHIFTER"));
|
||||
OpenAL::alFilteri(speedEffect->filter, alGetEnumValue("AL_FILTER_TYPE"), alGetEnumValue("AL_FILTER_LOWPASS"));
|
||||
OpenAL::alFilterf(speedEffect->filter, alGetEnumValue("AL_LOWPASS_GAIN"), 0.f);
|
||||
}
|
||||
alEffecti(speedEffect->effect, AL_PITCH_SHIFTER_COARSE_TUNE, speedEffect->coarseTune);
|
||||
alAuxiliaryEffectSloti(speedEffect->effectSlot, AL_EFFECTSLOT_EFFECT, speedEffect->effect);
|
||||
OpenAL::alEffecti(speedEffect->effect, alGetEnumValue("AL_PITCH_SHIFTER_COARSE_TUNE"), speedEffect->coarseTune);
|
||||
OpenAL::alAuxiliaryEffectSloti(speedEffect->effectSlot, alGetEnumValue("AL_EFFECTSLOT_EFFECT"), speedEffect->effect);
|
||||
alSourcef(stream.source, AL_PITCH, speedEffect->speed);
|
||||
alSource3i(stream.source, AL_AUXILIARY_SEND_FILTER, speedEffect->effectSlot, 0, 0);
|
||||
alSourcei(stream.source, AL_DIRECT_FILTER, speedEffect->filter);
|
||||
alSource3i(stream.source, alGetEnumValue("AL_AUXILIARY_SEND_FILTER"), speedEffect->effectSlot, 0, 0);
|
||||
alSourcei(stream.source, alGetEnumValue("AL_DIRECT_FILTER"), speedEffect->filter);
|
||||
}
|
||||
#endif // TDESKTOP_DISABLE_OPENAL_EFFECTS
|
||||
|
||||
void Mixer::Track::destroyStream() {
|
||||
if (isStreamCreated()) {
|
||||
|
|
@ -375,26 +374,26 @@ void Mixer::Track::destroyStream() {
|
|||
for (auto i = 0; i != 3; ++i) {
|
||||
stream.buffers[i] = 0;
|
||||
}
|
||||
#ifndef TDESKTOP_DISABLE_OPENAL_EFFECTS
|
||||
resetSpeedEffect();
|
||||
#endif // TDESKTOP_DISABLE_OPENAL_EFFECTS
|
||||
}
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_OPENAL_EFFECTS
|
||||
void Mixer::Track::resetSpeedEffect() {
|
||||
if (!Audio::SupportsSpeedControl()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!speedEffect) {
|
||||
return;
|
||||
} else if (speedEffect->effect && alIsEffect(speedEffect->effect)) {
|
||||
} else if (speedEffect->effect && OpenAL::alIsEffect(speedEffect->effect)) {
|
||||
if (isStreamCreated()) {
|
||||
removeSourceSpeedEffect();
|
||||
}
|
||||
alDeleteEffects(1, &speedEffect->effect);
|
||||
alDeleteAuxiliaryEffectSlots(1, &speedEffect->effectSlot);
|
||||
alDeleteFilters(1, &speedEffect->filter);
|
||||
OpenAL::alDeleteEffects(1, &speedEffect->effect);
|
||||
OpenAL::alDeleteAuxiliaryEffectSlots(1, &speedEffect->effectSlot);
|
||||
OpenAL::alDeleteFilters(1, &speedEffect->filter);
|
||||
}
|
||||
speedEffect->effect = speedEffect->effectSlot = speedEffect->filter = 0;
|
||||
}
|
||||
#endif // TDESKTOP_DISABLE_OPENAL_EFFECTS
|
||||
|
||||
void Mixer::Track::reattach(AudioMsgId::Type type) {
|
||||
if (isStreamCreated()
|
||||
|
|
@ -531,14 +530,15 @@ int Mixer::Track::getNotQueuedBufferIndex() {
|
|||
|
||||
void Mixer::Track::setExternalData(
|
||||
std::unique_ptr<ExternalSoundData> data) {
|
||||
#ifndef TDESKTOP_DISABLE_OPENAL_EFFECTS
|
||||
changeSpeedEffect(data ? data->speed : 1.);
|
||||
#endif // TDESKTOP_DISABLE_OPENAL_EFFECTS
|
||||
externalData = std::move(data);
|
||||
}
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_OPENAL_EFFECTS
|
||||
void Mixer::Track::changeSpeedEffect(float64 speed) {
|
||||
if (!Audio::SupportsSpeedControl()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (speed != 1.) {
|
||||
if (!speedEffect) {
|
||||
speedEffect = std::make_unique<SpeedEffect>();
|
||||
|
|
@ -553,7 +553,6 @@ void Mixer::Track::changeSpeedEffect(float64 speed) {
|
|||
speedEffect = nullptr;
|
||||
}
|
||||
}
|
||||
#endif // TDESKTOP_DISABLE_OPENAL_EFFECTS
|
||||
|
||||
void Mixer::Track::resetStream() {
|
||||
if (isStreamCreated()) {
|
||||
|
|
@ -830,13 +829,11 @@ void Mixer::forceToBufferExternal(const AudioMsgId &audioId) {
|
|||
}
|
||||
|
||||
void Mixer::setSpeedFromExternal(const AudioMsgId &audioId, float64 speed) {
|
||||
#ifndef TDESKTOP_DISABLE_OPENAL_EFFECTS
|
||||
QMutexLocker lock(&AudioMutex);
|
||||
const auto track = trackForType(audioId.type());
|
||||
if (track->state.id == audioId) {
|
||||
track->changeSpeedEffect(speed);
|
||||
}
|
||||
#endif // TDESKTOP_DISABLE_OPENAL_EFFECTS
|
||||
}
|
||||
|
||||
Streaming::TimePoint Mixer::getExternalSyncTimePoint(
|
||||
|
|
|
|||
|
|
@ -215,9 +215,7 @@ private:
|
|||
int getNotQueuedBufferIndex();
|
||||
|
||||
void setExternalData(std::unique_ptr<ExternalSoundData> data);
|
||||
#ifndef TDESKTOP_DISABLE_OPENAL_EFFECTS
|
||||
void changeSpeedEffect(float64 speed);
|
||||
#endif // TDESKTOP_DISABLE_OPENAL_EFFECTS
|
||||
|
||||
~Track();
|
||||
|
||||
|
|
@ -243,7 +241,6 @@ private:
|
|||
Stream stream;
|
||||
std::unique_ptr<ExternalSoundData> externalData;
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_OPENAL_EFFECTS
|
||||
struct SpeedEffect {
|
||||
uint32 effect = 0;
|
||||
uint32 effectSlot = 0;
|
||||
|
|
@ -252,7 +249,6 @@ private:
|
|||
float64 speed = 1.;
|
||||
};
|
||||
std::unique_ptr<SpeedEffect> speedEffect;
|
||||
#endif // TDESKTOP_DISABLE_OPENAL_EFFECTS
|
||||
crl::time lastUpdateWhen = 0;
|
||||
crl::time lastUpdatePosition = 0;
|
||||
|
||||
|
|
@ -260,11 +256,9 @@ private:
|
|||
void createStream(AudioMsgId::Type type);
|
||||
void destroyStream();
|
||||
void resetStream();
|
||||
#ifndef TDESKTOP_DISABLE_OPENAL_EFFECTS
|
||||
void resetSpeedEffect();
|
||||
void applySourceSpeedEffect();
|
||||
void removeSourceSpeedEffect();
|
||||
#endif // TDESKTOP_DISABLE_OPENAL_EFFECTS
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
90
Telegram/SourceFiles/media/audio/media_openal_functions.cpp
Normal file
90
Telegram/SourceFiles/media/audio/media_openal_functions.cpp
Normal 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
|
||||
56
Telegram/SourceFiles/media/audio/media_openal_functions.h
Normal file
56
Telegram/SourceFiles/media/audio/media_openal_functions.h
Normal 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
|
||||
|
|
@ -3534,8 +3534,7 @@ void OverlayWidget::setSession(not_null<Main::Session*> session) {
|
|||
_session = session;
|
||||
setWindowIcon(Window::CreateIcon(session));
|
||||
|
||||
base::ObservableViewer(
|
||||
session->downloaderTaskFinished()
|
||||
session->downloaderTaskFinished(
|
||||
) | rpl::start_with_next([=] {
|
||||
if (!isHidden()) {
|
||||
updateControls();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
return __clock_gettime_glibc_old(clk_id, tp);
|
||||
return __clock_gettime_glibc_old(clk_id, tp);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -810,8 +810,7 @@ void AppendEmojiPacks(
|
|||
[self setNeedsDisplayInRect:PeerRectByIndex(userpicIndex)];
|
||||
};
|
||||
const auto listenToDownloaderFinished = [=] {
|
||||
base::ObservableViewer(
|
||||
_session->downloaderTaskFinished()
|
||||
_session->downloaderTaskFinished(
|
||||
) | rpl::start_with_next([=] {
|
||||
const auto all = ranges::all_of(_pins, [=](const auto &pin) {
|
||||
return (!pin->peer->hasUserpic())
|
||||
|
|
@ -1191,8 +1190,7 @@ void AppendEmojiPacks(
|
|||
[self updateImage];
|
||||
return;
|
||||
}
|
||||
base::ObservableViewer(
|
||||
document->session().downloaderTaskFinished()
|
||||
document->session().downloaderTaskFinished(
|
||||
) | rpl::start_with_next([=] {
|
||||
_image = _media->getStickerSmall();
|
||||
if (_image) {
|
||||
|
|
|
|||
|
|
@ -301,6 +301,8 @@ void Manager::Private::clearingThreadLoop() {
|
|||
_clearingTasks.clear();
|
||||
}
|
||||
|
||||
@autoreleasepool {
|
||||
|
||||
auto clearBySpecial = [&](NSDictionary *notificationUserInfo) {
|
||||
NSNumber *sessionObject = [notificationUserInfo objectForKey:@"session"];
|
||||
const auto notificationSessionId = sessionObject ? [sessionObject unsignedLongLongValue] : 0;
|
||||
|
|
@ -332,6 +334,8 @@ void Manager::Private::clearingThreadLoop() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,26 +7,43 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
*/
|
||||
#include "platform/win/windows_dlls.h"
|
||||
|
||||
#include "base/platform/win/base_windows_safe_library.h"
|
||||
|
||||
#include <VersionHelpers.h>
|
||||
#include <QtCore/QSysInfo>
|
||||
|
||||
namespace Platform {
|
||||
namespace Dlls {
|
||||
|
||||
f_SetDllDirectory SetDllDirectory;
|
||||
|
||||
HINSTANCE LibKernel32;
|
||||
using base::Platform::SafeLoadLibrary;
|
||||
using base::Platform::LoadMethod;
|
||||
|
||||
void init() {
|
||||
static bool inited = false;
|
||||
if (inited) return;
|
||||
inited = true;
|
||||
|
||||
LibKernel32 = LoadLibrary(L"KERNEL32.DLL");
|
||||
load(LibKernel32, "SetDllDirectoryW", SetDllDirectory);
|
||||
if (SetDllDirectory) {
|
||||
// Remove the current directory from the DLL search order.
|
||||
SetDllDirectory(L"");
|
||||
// Remove the current directory from the DLL search order.
|
||||
::SetDllDirectory(L"");
|
||||
|
||||
const auto list = {
|
||||
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_GetProcessMemoryInfo GetProcessMemoryInfo;
|
||||
|
||||
HINSTANCE LibUxTheme;
|
||||
HINSTANCE LibShell32;
|
||||
HINSTANCE LibWtsApi32;
|
||||
HINSTANCE LibPropSys;
|
||||
HINSTANCE LibComBase;
|
||||
HINSTANCE LibDwmApi;
|
||||
HINSTANCE LibRstrtMgr;
|
||||
HINSTANCE LibPsApi;
|
||||
|
||||
void start() {
|
||||
init();
|
||||
|
||||
LibShell32 = LoadLibrary(L"SHELL32.DLL");
|
||||
load(LibShell32, "SHAssocEnumHandlers", SHAssocEnumHandlers);
|
||||
load(LibShell32, "SHCreateItemFromParsingName", SHCreateItemFromParsingName);
|
||||
load(LibShell32, "SHOpenWithDialog", SHOpenWithDialog);
|
||||
load(LibShell32, "OpenAs_RunDLLW", OpenAs_RunDLL);
|
||||
load(LibShell32, "SHQueryUserNotificationState", SHQueryUserNotificationState);
|
||||
load(LibShell32, "SHChangeNotify", SHChangeNotify);
|
||||
load(LibShell32, "SetCurrentProcessExplicitAppUserModelID", SetCurrentProcessExplicitAppUserModelID);
|
||||
const auto LibShell32 = SafeLoadLibrary(u"shell32.dll"_q);
|
||||
LoadMethod(LibShell32, "SHAssocEnumHandlers", SHAssocEnumHandlers);
|
||||
LoadMethod(LibShell32, "SHCreateItemFromParsingName", SHCreateItemFromParsingName);
|
||||
LoadMethod(LibShell32, "SHOpenWithDialog", SHOpenWithDialog);
|
||||
LoadMethod(LibShell32, "OpenAs_RunDLLW", OpenAs_RunDLL);
|
||||
LoadMethod(LibShell32, "SHQueryUserNotificationState", SHQueryUserNotificationState);
|
||||
LoadMethod(LibShell32, "SHChangeNotify", SHChangeNotify);
|
||||
LoadMethod(LibShell32, "SetCurrentProcessExplicitAppUserModelID", SetCurrentProcessExplicitAppUserModelID);
|
||||
|
||||
LibUxTheme = LoadLibrary(L"UXTHEME.DLL");
|
||||
load(LibUxTheme, "SetWindowTheme", SetWindowTheme);
|
||||
const auto LibUxTheme = SafeLoadLibrary(u"uxtheme.dll"_q);
|
||||
LoadMethod(LibUxTheme, "SetWindowTheme", SetWindowTheme);
|
||||
|
||||
if (IsWindowsVistaOrGreater()) {
|
||||
LibWtsApi32 = LoadLibrary(L"WTSAPI32.DLL");
|
||||
load(LibWtsApi32, "WTSRegisterSessionNotification", WTSRegisterSessionNotification);
|
||||
load(LibWtsApi32, "WTSUnRegisterSessionNotification", WTSUnRegisterSessionNotification);
|
||||
const auto LibWtsApi32 = SafeLoadLibrary(u"wtsapi32.dll"_q);
|
||||
LoadMethod(LibWtsApi32, "WTSRegisterSessionNotification", WTSRegisterSessionNotification);
|
||||
LoadMethod(LibWtsApi32, "WTSUnRegisterSessionNotification", WTSUnRegisterSessionNotification);
|
||||
|
||||
LibPropSys = LoadLibrary(L"PROPSYS.DLL");
|
||||
load(LibPropSys, "PropVariantToString", PropVariantToString);
|
||||
load(LibPropSys, "PSStringFromPropertyKey", PSStringFromPropertyKey);
|
||||
const auto LibPropSys = SafeLoadLibrary(u"propsys.dll"_q);
|
||||
LoadMethod(LibPropSys, "PropVariantToString", PropVariantToString);
|
||||
LoadMethod(LibPropSys, "PSStringFromPropertyKey", PSStringFromPropertyKey);
|
||||
|
||||
if (IsWindows8OrGreater()) {
|
||||
LibComBase = LoadLibrary(L"COMBASE.DLL");
|
||||
load(LibComBase, "RoGetActivationFactory", RoGetActivationFactory);
|
||||
load(LibComBase, "WindowsCreateStringReference", WindowsCreateStringReference);
|
||||
load(LibComBase, "WindowsDeleteString", WindowsDeleteString);
|
||||
const auto LibComBase = SafeLoadLibrary(u"combase.dll"_q);
|
||||
LoadMethod(LibComBase, "RoGetActivationFactory", RoGetActivationFactory);
|
||||
LoadMethod(LibComBase, "WindowsCreateStringReference", WindowsCreateStringReference);
|
||||
LoadMethod(LibComBase, "WindowsDeleteString", WindowsDeleteString);
|
||||
}
|
||||
|
||||
LibDwmApi = LoadLibrary(L"DWMAPI.DLL");
|
||||
load(LibDwmApi, "DwmIsCompositionEnabled", DwmIsCompositionEnabled);
|
||||
const auto LibDwmApi = SafeLoadLibrary(u"dwmapi.dll"_q);
|
||||
LoadMethod(LibDwmApi, "DwmIsCompositionEnabled", DwmIsCompositionEnabled);
|
||||
|
||||
LibRstrtMgr = LoadLibrary(L"RSTRTMGR.DLL");
|
||||
load(LibRstrtMgr, "RmStartSession", RmStartSession);
|
||||
load(LibRstrtMgr, "RmRegisterResources", RmRegisterResources);
|
||||
load(LibRstrtMgr, "RmGetList", RmGetList);
|
||||
load(LibRstrtMgr, "RmShutdown", RmShutdown);
|
||||
load(LibRstrtMgr, "RmEndSession", RmEndSession);
|
||||
const auto LibRstrtMgr = SafeLoadLibrary(u"rstrtmgr.dll"_q);
|
||||
LoadMethod(LibRstrtMgr, "RmStartSession", RmStartSession);
|
||||
LoadMethod(LibRstrtMgr, "RmRegisterResources", RmRegisterResources);
|
||||
LoadMethod(LibRstrtMgr, "RmGetList", RmGetList);
|
||||
LoadMethod(LibRstrtMgr, "RmShutdown", RmShutdown);
|
||||
LoadMethod(LibRstrtMgr, "RmEndSession", RmEndSession);
|
||||
}
|
||||
|
||||
LibPsApi = LoadLibrary(L"PSAPI.DLL");
|
||||
load(LibPsApi, "GetProcessMemoryInfo", GetProcessMemoryInfo);
|
||||
const auto LibPsApi = SafeLoadLibrary(u"psapi.dll"_q);
|
||||
LoadMethod(LibPsApi, "GetProcessMemoryInfo", GetProcessMemoryInfo);
|
||||
}
|
||||
|
||||
} // namespace Dlls
|
||||
|
|
|
|||
|
|
@ -30,14 +30,6 @@ extern f_SetDllDirectory SetDllDirectory;
|
|||
|
||||
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
|
||||
using f_SetWindowTheme = HRESULT(FAR STDAPICALLTYPE*)(
|
||||
HWND hWnd,
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@ class GroupMembersWidget : public PeerListWidget {
|
|||
|
||||
public:
|
||||
GroupMembersWidget(
|
||||
QWidget *parent,
|
||||
not_null<PeerData*> peer,
|
||||
QWidget *parent,
|
||||
not_null<PeerData*> peer,
|
||||
const style::PeerListItem &st);
|
||||
|
||||
int onlineCount() const {
|
||||
|
|
|
|||
|
|
@ -33,7 +33,11 @@ PeerListWidget::PeerListWidget(
|
|||
, _removeText(removeText)
|
||||
, _removeWidth(st::normalFont->width(_removeText)) {
|
||||
setMouseTracking(true);
|
||||
subscribe(peer->session().downloaderTaskFinished(), [=] { update(); });
|
||||
|
||||
peer->session().downloaderTaskFinished(
|
||||
) | rpl::start_with_next([=] {
|
||||
update();
|
||||
}, lifetime());
|
||||
}
|
||||
|
||||
int PeerListWidget::resizeGetHeight(int newWidth) {
|
||||
|
|
|
|||
|
|
@ -577,6 +577,7 @@ void SetupMultiAccountNotifications(
|
|||
|
||||
AddSkip(container);
|
||||
AddDividerText(container, tr::lng_settings_notify_all_about());
|
||||
AddSkip(container);
|
||||
}
|
||||
|
||||
void SetupNotificationsContent(
|
||||
|
|
|
|||
|
|
@ -38,8 +38,11 @@ public:
|
|||
void enqueue(not_null<Task*> task, int priority);
|
||||
void remove(not_null<Task*> task);
|
||||
|
||||
[[nodiscard]] base::Observable<void> &taskFinished() {
|
||||
return _taskFinishedObservable;
|
||||
void notifyTaskFinished() {
|
||||
_taskFinished.fire({});
|
||||
}
|
||||
[[nodiscard]] rpl::producer<> taskFinished() const {
|
||||
return _taskFinished.events();
|
||||
}
|
||||
|
||||
int changeRequestedAmount(MTP::DcId dcId, int index, int delta);
|
||||
|
|
@ -101,7 +104,7 @@ private:
|
|||
|
||||
const not_null<ApiWrap*> _api;
|
||||
|
||||
base::Observable<void> _taskFinishedObservable;
|
||||
rpl::event_stream<> _taskFinished;
|
||||
|
||||
base::flat_map<MTP::DcId, DcBalanceData> _balanceData;
|
||||
base::Timer _resetGenerationTimer;
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ void FileLoader::finishWithBytes(const QByteArray &data) {
|
|||
Platform::File::PostprocessDownloaded(
|
||||
QFileInfo(_file).absoluteFilePath());
|
||||
}
|
||||
_session->downloaderTaskFinished().notify();
|
||||
_session->notifyDownloaderTaskFinished();
|
||||
_updates.fire_done();
|
||||
}
|
||||
|
||||
|
|
@ -440,7 +440,7 @@ bool FileLoader::finalizeResult() {
|
|||
_cacheTag));
|
||||
}
|
||||
}
|
||||
_session->downloaderTaskFinished().notify();
|
||||
_session->notifyDownloaderTaskFinished();
|
||||
_updates.fire_done();
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -388,7 +388,7 @@ void start() {
|
|||
|
||||
EncryptedDescriptor settings;
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
@ -426,7 +426,12 @@ void start() {
|
|||
void writeSettings() {
|
||||
if (!_settingsWriteAllowed) {
|
||||
_settingsRewriteNeeded = true;
|
||||
return;
|
||||
|
||||
// We need to generate SettingsKey anyway,
|
||||
// for the moveLegacyBackground to work.
|
||||
if (SettingsKey) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (_basePath.isEmpty()) {
|
||||
LOG(("App Error: _basePath is empty in writeSettings()"));
|
||||
|
|
@ -446,6 +451,11 @@ void writeSettings() {
|
|||
}
|
||||
settings.writeData(_settingsSalt);
|
||||
|
||||
if (!_settingsWriteAllowed) {
|
||||
EncryptedDescriptor data(0);
|
||||
settings.writeEncrypted(data, SettingsKey);
|
||||
return;
|
||||
}
|
||||
const auto configSerialized = LookupFallbackConfig().serialize();
|
||||
const auto applicationSettings = Core::App().settings().serialize();
|
||||
|
||||
|
|
|
|||
|
|
@ -639,8 +639,7 @@ void UserpicButton::setupPeerViewers() {
|
|||
update();
|
||||
}, lifetime());
|
||||
|
||||
base::ObservableViewer(
|
||||
_peer->session().downloaderTaskFinished()
|
||||
_peer->session().downloaderTaskFinished(
|
||||
) | rpl::filter([=] {
|
||||
return _waiting;
|
||||
}) | rpl::start_with_next([=] {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "window/themes/window_theme.h"
|
||||
#include "storage/file_download.h"
|
||||
#include "main/main_session.h"
|
||||
#include "main/main_account.h"
|
||||
#include "history/history.h"
|
||||
#include "history/history_item.h"
|
||||
#include "platform/platform_specific.h"
|
||||
|
|
@ -229,14 +230,16 @@ void Manager::showNextFromQueue() {
|
|||
void Manager::subscribeToSession(not_null<Main::Session*> session) {
|
||||
auto i = _subscriptions.find(session);
|
||||
if (i == _subscriptions.end()) {
|
||||
i = _subscriptions.emplace(session, base::Subscription()).first;
|
||||
session->lifetime().add([=] {
|
||||
i = _subscriptions.emplace(session).first;
|
||||
session->account().sessionChanges(
|
||||
) | rpl::start_with_next([=] {
|
||||
_subscriptions.remove(session);
|
||||
});
|
||||
} else if (i->second) {
|
||||
}, i->second.lifetime);
|
||||
} else if (i->second.subscription) {
|
||||
return;
|
||||
}
|
||||
i->second = session->downloaderTaskFinished().add_subscription([=] {
|
||||
session->downloaderTaskFinished(
|
||||
) | rpl::start_with_next([=] {
|
||||
auto found = false;
|
||||
for (const auto ¬ification : _notifications) {
|
||||
if (const auto history = notification->maybeHistory()) {
|
||||
|
|
@ -247,9 +250,9 @@ void Manager::subscribeToSession(not_null<Main::Session*> session) {
|
|||
}
|
||||
}
|
||||
if (!found) {
|
||||
_subscriptions[session].destroy();
|
||||
_subscriptions[session].subscription.destroy();
|
||||
}
|
||||
});
|
||||
}, i->second.subscription);
|
||||
}
|
||||
|
||||
void Manager::moveWidgets() {
|
||||
|
|
|
|||
|
|
@ -56,6 +56,10 @@ private:
|
|||
friend class internal::Widget;
|
||||
using Notification = internal::Notification;
|
||||
using HideAllButton = internal::HideAllButton;
|
||||
struct SessionSubscription {
|
||||
rpl::lifetime subscription;
|
||||
rpl::lifetime lifetime;
|
||||
};
|
||||
|
||||
[[nodiscard]] QPixmap hiddenUserpicPlaceholder() const;
|
||||
|
||||
|
|
@ -91,7 +95,7 @@ private:
|
|||
std::vector<std::unique_ptr<Notification>> _notifications;
|
||||
base::flat_map<
|
||||
not_null<Main::Session*>,
|
||||
base::Subscription> _subscriptions;
|
||||
SessionSubscription> _subscriptions;
|
||||
|
||||
std::unique_ptr<HideAllButton> _hideAll;
|
||||
|
||||
|
|
|
|||
|
|
@ -666,8 +666,7 @@ void CloudList::subscribeToDownloadFinished() {
|
|||
if (_downloadFinishedLifetime) {
|
||||
return;
|
||||
}
|
||||
base::ObservableViewer(
|
||||
_window->session().downloaderTaskFinished()
|
||||
_window->session().downloaderTaskFinished(
|
||||
) | rpl::start_with_next([=] {
|
||||
auto &&waiting = _elements | ranges::view::filter(&Element::waiting);
|
||||
const auto still = ranges::count_if(waiting, [&](Element &element) {
|
||||
|
|
|
|||
|
|
@ -578,7 +578,10 @@ MainMenu::MainMenu(
|
|||
_version->setRichText(textcmdLink(1, currentVersionText()));
|
||||
_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().user(),
|
||||
|
|
|
|||
|
|
@ -36,9 +36,10 @@ MediaPreviewWidget::MediaPreviewWidget(
|
|||
, _controller(controller)
|
||||
, _emojiSize(Ui::Emoji::GetSizeLarge() / cIntRetinaFactor()) {
|
||||
setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
subscribe(_controller->session().downloaderTaskFinished(), [=] {
|
||||
_controller->session().downloaderTaskFinished(
|
||||
) | rpl::start_with_next([=] {
|
||||
update();
|
||||
});
|
||||
}, lifetime());
|
||||
}
|
||||
|
||||
QRect MediaPreviewWidget::updateArea() const {
|
||||
|
|
|
|||
|
|
@ -105,15 +105,16 @@ bool TitleWidgetQt::eventFilter(QObject *obj, QEvent *e) {
|
|||
|| e->type() == QEvent::MouseButtonPress) {
|
||||
if(window()->isAncestorOf(static_cast<QWidget*>(obj))) {
|
||||
const auto mouseEvent = static_cast<QMouseEvent*>(e);
|
||||
const auto edges = edgesFromPos(mouseEvent->windowPos().toPoint());
|
||||
|
||||
if (e->type() == QEvent::MouseMove) {
|
||||
updateCursor(mouseEvent->windowPos().toPoint());
|
||||
updateCursor(edges);
|
||||
}
|
||||
|
||||
if(e->type() == QEvent::MouseButtonPress
|
||||
&& mouseEvent->button() == Qt::LeftButton
|
||||
&& window()->windowState() != Qt::WindowMaximized) {
|
||||
return startResize(mouseEvent->windowPos().toPoint());
|
||||
return startResize(edges);
|
||||
}
|
||||
}
|
||||
} else if (e->type() == QEvent::Leave) {
|
||||
|
|
@ -195,9 +196,7 @@ Qt::Edges TitleWidgetQt::edgesFromPos(const QPoint &pos) {
|
|||
}
|
||||
}
|
||||
|
||||
void TitleWidgetQt::updateCursor(const QPoint &pos) {
|
||||
const auto edges = edgesFromPos(pos);
|
||||
|
||||
void TitleWidgetQt::updateCursor(Qt::Edges edges) {
|
||||
if (!edges || window()->windowState() == Qt::WindowMaximized) {
|
||||
while (QGuiApplication::overrideCursor()) {
|
||||
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 (const auto edges = edgesFromPos(pos)) {
|
||||
if (edges) {
|
||||
return window()->windowHandle()->startSystemResize(edges);
|
||||
}
|
||||
#endif // Qt >= 5.15 || DESKTOP_APP_QT_PATCHED
|
||||
|
|
|
|||
|
|
@ -41,8 +41,8 @@ private:
|
|||
void updateControlsPosition();
|
||||
|
||||
Qt::Edges edgesFromPos(const QPoint &pos);
|
||||
void updateCursor(const QPoint &pos);
|
||||
bool startResize(const QPoint &pos);
|
||||
void updateCursor(Qt::Edges edges);
|
||||
bool startResize(Qt::Edges edges);
|
||||
|
||||
const style::WindowTitle &_st;
|
||||
object_ptr<Ui::IconButton> _minimize;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
AppVersion 2001016
|
||||
AppVersion 2001017
|
||||
AppVersionStrMajor 2.1
|
||||
AppVersionStrSmall 2.1.16
|
||||
AppVersionStr 2.1.16
|
||||
AppVersionStrSmall 2.1.17
|
||||
AppVersionStr 2.1.17
|
||||
BetaChannel 1
|
||||
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
|
||||
|
|
@ -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)
|
||||
|
||||
- Crash fix.
|
||||
|
|
|
|||
2
cmake
2
cmake
|
|
@ -1 +1 @@
|
|||
Subproject commit 6b36a649dc0061138cf60bac65d9a40a5c9faea3
|
||||
Subproject commit 9346d5f89510c4f9e340a0e26a1f8c2244e7de29
|
||||
Loading…
Add table
Reference in a new issue