diff --git a/.github/workflows/snap.yml b/.github/workflows/snap.yml
index 9769045bf..fe44d49e9 100644
--- a/.github/workflows/snap.yml
+++ b/.github/workflows/snap.yml
@@ -67,7 +67,7 @@ jobs:
- name: CMake build.
if: steps.cache-cmake.outputs.cache-hit != 'true'
- run: snapcraft build --destructive-mode cmake
+ run: sudo snapcraft build --destructive-mode cmake
- name: FFmpeg cache.
id: cache-ffmpeg
@@ -78,11 +78,11 @@ jobs:
- name: FFmpeg build.
if: steps.cache-ffmpeg.outputs.cache-hit != 'true'
- run: snapcraft build --destructive-mode ffmpeg
+ run: sudo snapcraft build --destructive-mode ffmpeg
- name: Kotatogram Desktop snap build.
if: env.ONLY_CACHE == 'false'
- run: snapcraft --destructive-mode
+ run: sudo snapcraft --destructive-mode
- name: Move artifact.
if: env.UPLOAD_ARTIFACT == 'true'
@@ -102,5 +102,5 @@ jobs:
- name: Remove unneeded directories for cache.
run: |
- rm -rf parts/{cmake,ffmpeg}/{build,src,ubuntu}
- rm -rf parts/{cmake,ffmpeg}/state/{stage,prime}
+ sudo rm -rf parts/{cmake,ffmpeg}/{build,src,ubuntu}
+ sudo rm -rf parts/{cmake,ffmpeg}/state/{stage,prime}
diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings
index 11b92f6a1..f9e79443c 100644
--- a/Telegram/Resources/langs/lang.strings
+++ b/Telegram/Resources/langs/lang.strings
@@ -1329,6 +1329,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_dialogs_skip_archive_in_search" = "Skip results from archive";
"lng_dialogs_show_archive_in_search" = "With results from archive";
+"lng_about_dice" = "Send a 🎲 emoji to any chat to get a random number from Telegram.";
+
"lng_open_this_link" = "Open this link?";
"lng_open_link" = "Open";
"lng_allow_bot_pass" = "Allow {bot_name} to pass your Telegram name and ID to the web pages you open via this bot?";
diff --git a/Telegram/Resources/uwp/AppX/AppxManifest.xml b/Telegram/Resources/uwp/AppX/AppxManifest.xml
index 5db8923b4..9feaa42a4 100644
--- a/Telegram/Resources/uwp/AppX/AppxManifest.xml
+++ b/Telegram/Resources/uwp/AppX/AppxManifest.xml
@@ -9,7 +9,7 @@
+ Version="2.0.0.0" />
Telegram Desktop
Telegram FZ-LLC
diff --git a/Telegram/SourceFiles/boxes/connection_box.cpp b/Telegram/SourceFiles/boxes/connection_box.cpp
index a96648e17..3428c478e 100644
--- a/Telegram/SourceFiles/boxes/connection_box.cpp
+++ b/Telegram/SourceFiles/boxes/connection_box.cpp
@@ -691,7 +691,10 @@ void ProxiesBox::applyView(View &&view) {
wrap,
std::move(view))));
setupButtons(id, i->second.get());
- _noRows.reset();
+ if (_noRows) {
+ _noRows.reset();
+ wrap->resizeToWidth(width());
+ }
} else if (view.host.isEmpty()) {
_rows.erase(i);
} else {
diff --git a/Telegram/SourceFiles/boxes/filters/edit_filter_box.cpp b/Telegram/SourceFiles/boxes/filters/edit_filter_box.cpp
index 0955fd11d..47d9c7a88 100644
--- a/Telegram/SourceFiles/boxes/filters/edit_filter_box.cpp
+++ b/Telegram/SourceFiles/boxes/filters/edit_filter_box.cpp
@@ -314,6 +314,7 @@ void EditExceptions(
include ? rules.always() : rules.never());
const auto rawController = controller.get();
auto initBox = [=](not_null box) {
+ box->setCloseByOutsideClick(false);
box->addButton(tr::lng_settings_save(), crl::guard(context, [=] {
const auto peers = box->peerListCollectSelectedRows();
const auto rules = data->current();
@@ -469,6 +470,10 @@ void CreateIconSelector(
return QString();
}
+[[nodiscard]] QString TrimDefaultTitle(const QString &title) {
+ return (title.size() <= kMaxFilterTitleLength) ? title : QString();
+}
+
} // namespace
void EditFilterBox(
@@ -512,7 +517,7 @@ void EditFilterBox(
if (nameEditing->custom) {
return;
}
- const auto title = DefaultTitle(filter);
+ const auto title = TrimDefaultTitle(DefaultTitle(filter));
if (nameEditing->field->getLastText() != title) {
nameEditing->settingDefault = true;
nameEditing->field->setText(title);
@@ -559,6 +564,11 @@ void EditFilterBox(
AddSkip(content);
AddSubsectionTitle(content, tr::lng_filters_include());
+ const auto includeAdd = AddButton(
+ content,
+ tr::lng_filters_add_chats() | Ui::Text::ToUpper(),
+ st::settingsUpdate);
+
const auto include = SetupChatsPreview(
content,
data,
@@ -566,11 +576,6 @@ void EditFilterBox(
kTypes,
&Data::ChatFilter::always);
- const auto includeAdd = AddButton(
- content,
- tr::lng_filters_add_chats() | Ui::Text::ToUpper(),
- st::settingsUpdate);
-
AddSkip(content);
content->add(
object_ptr(
@@ -583,6 +588,11 @@ void EditFilterBox(
AddSubsectionTitle(content, tr::lng_filters_exclude());
+ const auto excludeAdd = AddButton(
+ content,
+ tr::lng_filters_remove_chats() | Ui::Text::ToUpper(),
+ st::settingsUpdate);
+
const auto exclude = SetupChatsPreview(
content,
data,
@@ -590,11 +600,6 @@ void EditFilterBox(
kExcludeTypes,
&Data::ChatFilter::never);
- const auto excludeAdd = AddButton(
- content,
- tr::lng_filters_remove_chats() | Ui::Text::ToUpper(),
- st::settingsUpdate);
-
AddSkip(content);
content->add(
object_ptr(
diff --git a/Telegram/SourceFiles/core/application.h b/Telegram/SourceFiles/core/application.h
index 1c3350cc6..6ce06b829 100644
--- a/Telegram/SourceFiles/core/application.h
+++ b/Telegram/SourceFiles/core/application.h
@@ -144,7 +144,7 @@ public:
void saveSettingsDelayed(crl::time delay = kDefaultSaveDelay);
// Dc options and proxy.
- MTP::DcOptions *dcOptions() {
+ not_null dcOptions() {
return _dcOptions.get();
}
struct ProxyChange {
diff --git a/Telegram/SourceFiles/core/shortcuts.cpp b/Telegram/SourceFiles/core/shortcuts.cpp
index fa9860ffb..7cfcf02d4 100644
--- a/Telegram/SourceFiles/core/shortcuts.cpp
+++ b/Telegram/SourceFiles/core/shortcuts.cpp
@@ -299,6 +299,8 @@ bool Manager::readCustomFile() {
}
void Manager::fillDefaults() {
+ const auto ctrl = Platform::IsMac() ? qsl("meta") : qsl("ctrl");
+
set(qsl("ctrl+w"), Command::Close);
set(qsl("ctrl+f4"), Command::Close);
set(qsl("ctrl+l"), Command::Lock);
@@ -320,15 +322,11 @@ void Manager::fillDefaults() {
set(qsl("alt+down"), Command::ChatNext);
set(qsl("ctrl+pgup"), Command::ChatPrevious);
set(qsl("alt+up"), Command::ChatPrevious);
- if (Platform::IsMac()) {
- set(qsl("meta+tab"), Command::ChatNext);
- set(qsl("meta+shift+tab"), Command::ChatPrevious);
- set(qsl("meta+backtab"), Command::ChatPrevious);
- } else {
- set(qsl("ctrl+tab"), Command::ChatNext);
- set(qsl("ctrl+shift+tab"), Command::ChatPrevious);
- set(qsl("ctrl+backtab"), Command::ChatPrevious);
- }
+
+ set(qsl("%1+tab").arg(ctrl), Command::ChatNext);
+ set(qsl("%1+shift+tab").arg(ctrl), Command::ChatPrevious);
+ set(qsl("%1+backtab").arg(ctrl), Command::ChatPrevious);
+
set(qsl("ctrl+alt+home"), Command::ChatFirst);
set(qsl("ctrl+alt+end"), Command::ChatLast);
@@ -344,6 +342,17 @@ void Manager::fillDefaults() {
set(qsl("ctrl+4"), Command::ChatPinned4);
set(qsl("ctrl+5"), Command::ChatPinned5);
+ auto &&folders = ranges::view::zip(
+ kShowFolder,
+ ranges::view::ints(1, ranges::unreachable));
+
+ for (const auto [command, index] : folders) {
+ set(qsl("%1+shift+%2").arg(ctrl).arg(index > 9 ? 0 : index), command);
+ }
+
+ set(qsl("%1+shift+down").arg(ctrl), Command::FolderNext);
+ set(qsl("%1+shift+up").arg(ctrl), Command::FolderPrevious);
+
set(qsl("ctrl+0"), Command::ChatSelf);
set(qsl("ctrl+9"), Command::ShowArchive);
diff --git a/Telegram/SourceFiles/core/shortcuts.h b/Telegram/SourceFiles/core/shortcuts.h
index 9238aeb9e..5929e22b5 100644
--- a/Telegram/SourceFiles/core/shortcuts.h
+++ b/Telegram/SourceFiles/core/shortcuts.h
@@ -35,6 +35,20 @@ enum class Command {
ChatPinned4,
ChatPinned5,
+ ShowFolder1,
+ ShowFolder2,
+ ShowFolder3,
+ ShowFolder4,
+ ShowFolder5,
+ ShowFolder6,
+ ShowFolder7,
+ ShowFolder8,
+ ShowFolder9,
+ ShowFolder10,
+
+ FolderNext,
+ FolderPrevious,
+
ShowArchive,
JustSendMessage,
@@ -50,6 +64,19 @@ enum class Command {
SaveDraft,
};
+constexpr auto kShowFolder = {
+ Command::ShowFolder1,
+ Command::ShowFolder2,
+ Command::ShowFolder3,
+ Command::ShowFolder4,
+ Command::ShowFolder5,
+ Command::ShowFolder6,
+ Command::ShowFolder7,
+ Command::ShowFolder8,
+ Command::ShowFolder9,
+ Command::ShowFolder10,
+};
+
[[nodiscard]] FnMut RequestHandler(Command command);
class Request {
diff --git a/Telegram/SourceFiles/core/ui_integration.cpp b/Telegram/SourceFiles/core/ui_integration.cpp
index ccc76aa66..9e4161b17 100644
--- a/Telegram/SourceFiles/core/ui_integration.cpp
+++ b/Telegram/SourceFiles/core/ui_integration.cpp
@@ -52,6 +52,14 @@ void UiIntegration::activationFromTopPanel() {
Platform::IgnoreApplicationActivationRightNow();
}
+void UiIntegration::startFontsBegin() {
+ Platform::FallbackFontConfigCheckBegin();
+}
+
+void UiIntegration::startFontsEnd() {
+ Platform::FallbackFontConfigCheckEnd();
+}
+
std::shared_ptr UiIntegration::createLinkHandler(
EntityType type,
const QString &text,
diff --git a/Telegram/SourceFiles/core/ui_integration.h b/Telegram/SourceFiles/core/ui_integration.h
index b53c76aa7..3cb3e191c 100644
--- a/Telegram/SourceFiles/core/ui_integration.h
+++ b/Telegram/SourceFiles/core/ui_integration.h
@@ -23,6 +23,9 @@ public:
void textActionsUpdated() override;
void activationFromTopPanel() override;
+ void startFontsBegin() override;
+ void startFontsEnd() override;
+
std::shared_ptr createLinkHandler(
EntityType type,
const QString &text,
diff --git a/Telegram/SourceFiles/core/version.h b/Telegram/SourceFiles/core/version.h
index 856ca8458..5cd8868dc 100644
--- a/Telegram/SourceFiles/core/version.h
+++ b/Telegram/SourceFiles/core/version.h
@@ -22,9 +22,9 @@ 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 = 1009022;
-constexpr auto AppVersionStr = "1.9.22";
-constexpr auto AppBetaVersion = true;
+constexpr auto AppVersion = 2000000;
+constexpr auto AppVersionStr = "2.0";
+constexpr auto AppBetaVersion = false;
constexpr auto AppAlphaVersion = TDESKTOP_ALPHA_VERSION;
constexpr auto AppKotatoVersion = 1002000;
constexpr auto AppKotatoVersionStr = "1.2";
diff --git a/Telegram/SourceFiles/dialogs/dialogs_entry.cpp b/Telegram/SourceFiles/dialogs/dialogs_entry.cpp
index fa0919e67..f707b9928 100644
--- a/Telegram/SourceFiles/dialogs/dialogs_entry.cpp
+++ b/Telegram/SourceFiles/dialogs/dialogs_entry.cpp
@@ -230,6 +230,10 @@ not_null Entry::addToChatList(
void Entry::removeFromChatList(
FilterId filterId,
not_null list) {
+ if (isPinnedDialog(filterId)) {
+ owner().setChatPinned(_key, filterId, false);
+ }
+
const auto i = _chatListLinks.find(filterId);
if (i == end(_chatListLinks)) {
return;
diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp
index 15ac44be0..349184b99 100644
--- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp
+++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp
@@ -1278,7 +1278,8 @@ bool InnerWidget::updateReorderPinned(QPoint localPosition) {
const auto delta = [&] {
if (localPosition.y() < _visibleTop) {
return localPosition.y() - _visibleTop;
- } else if (_openedFolder && localPosition.y() > _visibleBottom) {
+ } else if ((_openedFolder || _filterId)
+ && localPosition.y() > _visibleBottom) {
return localPosition.y() - _visibleBottom;
}
return 0;
@@ -3074,6 +3075,54 @@ void InnerWidget::setupShortcuts() {
return jumpToDialogRow({ row->key(), FullMsgId() });
});
}
+
+ auto &&folders = ranges::view::zip(
+ Shortcuts::kShowFolder,
+ ranges::view::ints(0, ranges::unreachable));
+
+ for (const auto [command, index] : folders) {
+ request->check(command) && request->handle([=, index = index] {
+ const auto list = &session().data().chatsFilters().list();
+ if (index >= list->size()) {
+ return false;
+ }
+ const auto filterId = list->at(index).id();
+ _controller->setActiveChatsFilter((filterId == _filterId)
+ ? 0
+ : filterId);
+ return true;
+ });
+ }
+
+ const auto nearFolder = [=](bool isNext) {
+ const auto id = _controller->activeChatsFilterCurrent();
+ const auto list = &session().data().chatsFilters().list();
+ const auto it = (id == 0)
+ ? begin(*list) - 1
+ : ranges::find(*list, id, &Data::ChatFilter::id);
+ if (it == end(*list) && id != 0) {
+ return false;
+ }
+ const auto i = isNext ? 1 : -1;
+ const auto index = it - begin(*list) + i;
+ if (index >= (int)list->size() || index < -1) {
+ return false;
+ }
+ const auto filterId = (index == -1)
+ ? 0
+ : list->at(index).id();
+ _controller->setActiveChatsFilter(filterId);
+ return true;
+ };
+
+ request->check(Command::FolderNext) && request->handle([=] {
+ return nearFolder(true);
+ });
+
+ request->check(Command::FolderPrevious) && request->handle([=] {
+ return nearFolder(false);
+ });
+
if (session().supportMode() && row.key.history()) {
request->check(
Command::SupportScrollToCurrent
diff --git a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp
index a5997befe..89f08591e 100644
--- a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp
+++ b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp
@@ -745,7 +745,9 @@ void Widget::onDraggingScrollDelta(int delta) {
}
void Widget::onDraggingScrollTimer() {
- auto delta = (_draggingScrollDelta > 0) ? qMin(_draggingScrollDelta * 3 / 20 + 1, int32(Ui::kMaxScrollSpeed)) : qMax(_draggingScrollDelta * 3 / 20 - 1, -int32(Ui::kMaxScrollSpeed));
+ const auto delta = (_draggingScrollDelta > 0)
+ ? qMin(_draggingScrollDelta * 3 / 20 + 1, Ui::kMaxScrollSpeed)
+ : qMax(_draggingScrollDelta * 3 / 20 - 1, -Ui::kMaxScrollSpeed);
_scroll->scrollToY(_scroll->scrollTop() + delta);
}
diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp
index 939a5a75e..3b337dc23 100644
--- a/Telegram/SourceFiles/history/history_widget.cpp
+++ b/Telegram/SourceFiles/history/history_widget.cpp
@@ -1826,6 +1826,7 @@ void HistoryWidget::showHistory(
_showAtMsgId = showAtMsgId;
_historyInited = false;
+ _contactStatus = nullptr;
// Unload lottie animations.
Auth().data().unloadHeavyViewParts(HistoryInner::ElementDelegate());
@@ -1843,8 +1844,6 @@ void HistoryWidget::showHistory(
}, _contactStatus->lifetime());
orderWidgets();
controller()->tabbedSelector()->setCurrentPeer(_peer);
- } else {
- _contactStatus = nullptr;
}
refreshTabbedPanel();
diff --git a/Telegram/SourceFiles/history/view/media/history_view_dice.cpp b/Telegram/SourceFiles/history/view/media/history_view_dice.cpp
index f753d434a..587b0e929 100644
--- a/Telegram/SourceFiles/history/view/media/history_view_dice.cpp
+++ b/Telegram/SourceFiles/history/view/media/history_view_dice.cpp
@@ -13,6 +13,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history_item.h"
#include "history/history_item_components.h"
#include "history/view/history_view_element.h"
+#include "ui/toast/toast.h"
+#include "lang/lang_keys.h"
#include "main/main_session.h"
namespace HistoryView {
@@ -30,10 +32,9 @@ Dice::Dice(not_null parent, not_null dice)
, _dice(dice)
, _start(parent, Lookup(parent, 0)) {
_showLastFrame = _parent->data()->Has();
+ _start.setDiceIndex(0);
if (_showLastFrame) {
_drawingEnd = true;
- } else {
- _start.setDiceIndex(0);
}
}
@@ -43,6 +44,20 @@ QSize Dice::size() {
return _start.size();
}
+ClickHandlerPtr Dice::link() {
+ if (_parent->data()->Has()) {
+ return nullptr;
+ }
+ static auto kHandler = std::make_shared([] {
+ auto config = Ui::Toast::Config();
+ config.multiline = true;
+ config.minWidth = st::msgMinWidth;
+ config.text = tr::lng_about_dice(tr::now);
+ Ui::Toast::Show(config);
+ });
+ return kHandler;
+}
+
void Dice::draw(Painter &p, const QRect &r, bool selected) {
if (const auto value = _end ? 0 : _dice->diceValue()) {
if (const auto document = Lookup(_parent, value)) {
diff --git a/Telegram/SourceFiles/history/view/media/history_view_dice.h b/Telegram/SourceFiles/history/view/media/history_view_dice.h
index d8967412f..113c94dba 100644
--- a/Telegram/SourceFiles/history/view/media/history_view_dice.h
+++ b/Telegram/SourceFiles/history/view/media/history_view_dice.h
@@ -24,6 +24,8 @@ public:
QSize size() override;
void draw(Painter &p, const QRect &r, bool selected) override;
+ ClickHandlerPtr link() override;
+
void clearStickerLoopPlayed() override {
}
void unloadHeavyPart() override {
diff --git a/Telegram/SourceFiles/history/view/media/history_view_sticker.cpp b/Telegram/SourceFiles/history/view/media/history_view_sticker.cpp
index e88d2d020..f0cbebd0a 100644
--- a/Telegram/SourceFiles/history/view/media/history_view_sticker.cpp
+++ b/Telegram/SourceFiles/history/view/media/history_view_sticker.cpp
@@ -31,12 +31,22 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace HistoryView {
namespace {
-double GetEmojiStickerZoom(not_null session) {
+[[nodiscard]] double GetEmojiStickerZoom(not_null session) {
return session->account().appConfig().get(
"emojies_animated_zoom",
0.625);
}
+[[nodiscard]] QImage CacheDiceImage(int index, const QImage &image) {
+ static auto Cache = base::flat_map();
+ const auto i = Cache.find(index);
+ if (i != end(Cache) && i->second.size() == image.size()) {
+ return i->second;
+ }
+ Cache[index] = image;
+ return image;
+}
+
} // namespace
Sticker::Sticker(
@@ -117,7 +127,7 @@ void Sticker::paintLottie(Painter &p, const QRect &r, bool selected) {
: Lottie::Animation::FrameInfo();
if (_nextLastDiceFrame) {
_nextLastDiceFrame = false;
- _lastDiceFrame = frame.image;
+ _lastDiceFrame = CacheDiceImage(_diceIndex, frame.image);
}
const auto &image = _lastDiceFrame.isNull()
? frame.image
@@ -255,6 +265,10 @@ void Sticker::unloadLottie() {
if (!_lottie) {
return;
}
+ if (_diceIndex > 0 && _lastDiceFrame.isNull()) {
+ _nextLastDiceFrame = false;
+ _lottieOncePlayed = false;
+ }
_lottie = nullptr;
_parent->data()->history()->owner().unregisterHeavyViewPart(_parent);
}
diff --git a/Telegram/SourceFiles/intro/intro_widget.cpp b/Telegram/SourceFiles/intro/intro_widget.cpp
index 80ad033a0..87e048d83 100644
--- a/Telegram/SourceFiles/intro/intro_widget.cpp
+++ b/Telegram/SourceFiles/intro/intro_widget.cpp
@@ -23,9 +23,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/labels.h"
#include "ui/wrap/fade_wrap.h"
#include "core/update_checker.h"
+#include "core/application.h"
+#include "mtproto/dc_options.h"
#include "window/window_slide_animation.h"
#include "window/window_connecting_widget.h"
#include "base/platform/base_platform_info.h"
+#include "api/api_text_entities.h"
#include "facades.h"
#include "app.h"
#include "styles/style_layers.h"
@@ -72,6 +75,11 @@ Widget::Widget(QWidget *parent, not_null account)
createLanguageLink();
});
+ _account->mtpUpdates(
+ ) | rpl::start_with_next([=](const MTPUpdates &updates) {
+ handleUpdates(updates);
+ }, lifetime());
+
_back->entity()->setClickedCallback([=] {
historyMove(Direction::Back);
});
@@ -116,6 +124,34 @@ void Widget::refreshLang() {
InvokeQueued(this, [this] { updateControlsGeometry(); });
}
+void Widget::handleUpdates(const MTPUpdates &updates) {
+ updates.match([&](const MTPDupdateShort &data) {
+ handleUpdate(data.vupdate());
+ }, [&](const MTPDupdates &data) {
+ for (const auto &update : data.vupdates().v) {
+ handleUpdate(update);
+ }
+ }, [&](const MTPDupdatesCombined &data) {
+ for (const auto &update : data.vupdates().v) {
+ handleUpdate(update);
+ }
+ }, [](const auto &) {});
+}
+
+void Widget::handleUpdate(const MTPUpdate &update) {
+ update.match([&](const MTPDupdateDcOptions &data) {
+ Core::App().dcOptions()->addFromList(data.vdc_options());
+ }, [&](const MTPDupdateConfig &data) {
+ _account->mtp()->requestConfig();
+ }, [&](const MTPDupdateServiceNotification &data) {
+ const auto text = TextWithEntities{
+ qs(data.vmessage()),
+ Api::EntitiesFromMTP(data.ventities().v)
+ };
+ Ui::show(Box(text));
+ }, [](const auto &) {});
+}
+
void Widget::createLanguageLink() {
if (_changeLanguage) {
return;
@@ -651,7 +687,6 @@ void Widget::updateControlsGeometry() {
}
}
-
void Widget::keyPressEvent(QKeyEvent *e) {
if (_a_show.animating() || getStep()->animating()) return;
diff --git a/Telegram/SourceFiles/intro/intro_widget.h b/Telegram/SourceFiles/intro/intro_widget.h
index b26e1f452..978bfc812 100644
--- a/Telegram/SourceFiles/intro/intro_widget.h
+++ b/Telegram/SourceFiles/intro/intro_widget.h
@@ -93,6 +93,8 @@ private:
void createLanguageLink();
void checkUpdateStatus();
void setupNextButton();
+ void handleUpdates(const MTPUpdates &updates);
+ void handleUpdate(const MTPUpdate &update);
void updateControlsGeometry();
[[nodiscard]] not_null getData() {
diff --git a/Telegram/SourceFiles/media/clip/media_clip_ffmpeg.cpp b/Telegram/SourceFiles/media/clip/media_clip_ffmpeg.cpp
index b6bd69426..263ff877e 100644
--- a/Telegram/SourceFiles/media/clip/media_clip_ffmpeg.cpp
+++ b/Telegram/SourceFiles/media/clip/media_clip_ffmpeg.cpp
@@ -18,6 +18,7 @@ namespace {
constexpr auto kSkipInvalidDataPackets = 10;
constexpr auto kMaxInlineArea = 1280 * 720;
+constexpr auto kMaxSendingArea = 3840 * 2160; // usual 4K
// See https://github.com/telegramdesktop/tdesktop/issues/7225
constexpr auto kAlignImageBy = 64;
@@ -60,7 +61,10 @@ ReaderImplementation::ReadResult FFMpegReaderImplementation::readNextFrame() {
do {
int res = avcodec_receive_frame(_codecContext, _frame.get());
if (res >= 0) {
- if (_frame->width * _frame->height > kMaxInlineArea) {
+ const auto limit = (_mode == Mode::Inspecting)
+ ? kMaxSendingArea
+ : kMaxInlineArea;
+ if (_frame->width * _frame->height > limit) {
return ReadResult::Error;
}
processReadFrame();
diff --git a/Telegram/SourceFiles/platform/linux/main_window_linux.cpp b/Telegram/SourceFiles/platform/linux/main_window_linux.cpp
index 989137be8..867c7ee45 100644
--- a/Telegram/SourceFiles/platform/linux/main_window_linux.cpp
+++ b/Telegram/SourceFiles/platform/linux/main_window_linux.cpp
@@ -313,6 +313,14 @@ std::unique_ptr TrayIconFile(
return ret;
}
+
+bool UseUnityCounter() {
+ static const auto UnityCounter = QDBusInterface(
+ "com.canonical.Unity",
+ "/").isValid();
+
+ return UnityCounter;
+}
#endif // !TDESKTOP_DISABLE_DBUS_INTEGRATION
bool IsSNIAvailable() {
@@ -341,18 +349,6 @@ bool IsSNIAvailable() {
return false;
}
-bool UseUnityCounter() {
-#ifdef TDESKTOP_DISABLE_DBUS_INTEGRATION
- static const auto UnityCounter = false;
-#else // TDESKTOP_DISABLE_DBUS_INTEGRATION
- static const auto UnityCounter = QDBusInterface(
- "com.canonical.Unity",
- "/").isValid();
-#endif // !TDESKTOP_DISABLE_DBUS_INTEGRATION
-
- return UnityCounter;
-}
-
quint32 djbStringHash(QString string) {
quint32 hash = 5381;
QByteArray chars = string.toLatin1();
@@ -460,13 +456,19 @@ void MainWindow::initHook() {
&QWindow::visibleChanged,
this,
&MainWindow::onVisibleChanged);
-#endif // !TDESKTOP_DISABLE_DBUS_INTEGRATION
+
+ if (AppMenuSupported()) {
+ LOG(("Using D-Bus global menu."));
+ } else {
+ LOG(("Not using D-Bus global menu."));
+ }
if (UseUnityCounter()) {
LOG(("Using Unity launcher counter."));
} else {
LOG(("Not using Unity launcher counter."));
}
+#endif // !TDESKTOP_DISABLE_DBUS_INTEGRATION
}
bool MainWindow::hasTrayIcon() const {
diff --git a/Telegram/SourceFiles/platform/linux/specific_linux.cpp b/Telegram/SourceFiles/platform/linux/specific_linux.cpp
index 24146981c..c21a893ba 100644
--- a/Telegram/SourceFiles/platform/linux/specific_linux.cpp
+++ b/Telegram/SourceFiles/platform/linux/specific_linux.cpp
@@ -44,6 +44,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
using namespace Platform;
using Platform::File::internal::EscapeShell;
+namespace Platform {
namespace {
constexpr auto kDesktopFile = ":/misc/kotatogramdesktop.desktop"_cs;
@@ -95,23 +96,27 @@ bool RunShellCommand(const QByteArray &command) {
return true;
}
-void FallbackFontConfig() {
-#ifdef TDESKTOP_USE_FONT_CONFIG_FALLBACK
- const auto custom = cWorkingDir() + "tdata/fc-custom-1.conf";
- const auto finish = gsl::finally([&] {
- if (QFile(custom).exists()) {
- LOG(("Custom FONTCONFIG_FILE: ") + custom);
- qputenv("FONTCONFIG_FILE", QFile::encodeName(custom));
- }
- });
+[[nodiscard]] bool CheckFontConfigCrash() {
+ return InSnap();
+}
+[[nodiscard]] QString FallbackFontConfigCheckPath() {
+ return cWorkingDir() + "tdata/fc-check";
+}
+
+#ifdef TDESKTOP_USE_FONTCONFIG_FALLBACK
+
+[[nodiscard]] bool BadFontConfigVersion() {
+ if (CheckFontConfigCrash()) {
+ return QFile(FallbackFontConfigCheckPath()).exists();
+ }
QProcess process;
process.setProcessChannelMode(QProcess::MergedChannels);
process.start("fc-list", QStringList() << "--version");
process.waitForFinished();
if (process.exitCode() > 0) {
LOG(("App Error: Could not start fc-list. Process exited with code: %1.").arg(process.exitCode()));
- return;
+ return false;
}
QString result(process.readAllStandardOutput());
@@ -120,20 +125,31 @@ void FallbackFontConfig() {
QVersionNumber version = QVersionNumber::fromString(result.split("version ").last());
if (version.isNull()) {
LOG(("App Error: Could not get version from fc-list output."));
- return;
+ return false;
}
LOG(("Fontconfig version: %1.").arg(version.toString()));
if (version < QVersionNumber::fromString("2.13")) {
if (qgetenv("TDESKTOP_FORCE_CUSTOM_FONTCONFIG").isEmpty()) {
- return;
+ return false;
}
}
-
- QFile(":/fc/fc-custom.conf").copy(custom);
-#endif // TDESKTOP_USE_FONT_CONFIG_FALLBACK
+ return true;
}
+void FallbackFontConfig() {
+ if (BadFontConfigVersion()) {
+ const auto custom = cWorkingDir() + "tdata/fc-custom-1.conf";
+ QFile(":/fc/fc-custom.conf").copy(custom);
+ if (QFile(custom).exists()) {
+ LOG(("Custom FONTCONFIG_FILE: ") + custom);
+ qputenv("FONTCONFIG_FILE", QFile::encodeName(custom));
+ }
+ }
+}
+
+#endif // TDESKTOP_USE_FONTCONFIG_FALLBACK
+
bool GenerateDesktopFile(
const QString &targetPath,
const QString &args,
@@ -208,8 +224,6 @@ bool GenerateDesktopFile(
} // namespace
-namespace Platform {
-
void SetApplicationIcon(const QIcon &icon) {
QApplication::setWindowIcon(icon);
}
@@ -404,6 +418,23 @@ std::optional LastUserInputTime() {
return std::nullopt;
}
+void FallbackFontConfigCheckBegin() {
+ if (!CheckFontConfigCrash()) {
+ return;
+ }
+ auto file = QFile(FallbackFontConfigCheckPath());
+ if (file.open(QIODevice::WriteOnly)) {
+ file.write("1", 1);
+ }
+}
+
+void FallbackFontConfigCheckEnd() {
+ if (!CheckFontConfigCrash()) {
+ return;
+ }
+ QFile(FallbackFontConfigCheckPath()).remove();
+}
+
} // namespace Platform
namespace {
@@ -521,7 +552,10 @@ namespace Platform {
void start() {
LOG(("Launcher filename: %1").arg(GetLauncherFilename()));
+
+#ifdef TDESKTOP_USE_FONTCONFIG_FALLBACK
FallbackFontConfig();
+#endif // TDESKTOP_USE_FONTCONFIG_FALLBACK
qputenv("PULSE_PROP_application.name", AppName.utf8());
qputenv("PULSE_PROP_application.icon_name", GetIconName().toLatin1());
@@ -529,9 +563,9 @@ void start() {
#ifdef TDESKTOP_FORCE_GTK_FILE_DIALOG
LOG(("Checking for XDG Desktop Portal..."));
// this can give us a chance to use a proper file dialog for current session
- if(IsXDGDesktopPortalPresent()) {
+ if (IsXDGDesktopPortalPresent()) {
LOG(("XDG Desktop Portal is present!"));
- if(UseXDGDesktopPortal()) {
+ if (UseXDGDesktopPortal()) {
LOG(("Usage of XDG Desktop Portal is enabled."));
qputenv("QT_QPA_PLATFORMTHEME", "xdgdesktopportal");
} else {
diff --git a/Telegram/SourceFiles/platform/linux/specific_linux.h b/Telegram/SourceFiles/platform/linux/specific_linux.h
index 7f18032cb..28e3ef386 100644
--- a/Telegram/SourceFiles/platform/linux/specific_linux.h
+++ b/Telegram/SourceFiles/platform/linux/specific_linux.h
@@ -40,6 +40,9 @@ QString GetIconName();
inline void IgnoreApplicationActivationRightNow() {
}
+void FallbackFontConfigCheckBegin();
+void FallbackFontConfigCheckEnd();
+
} // namespace Platform
inline void psCheckLocalSocket(const QString &serverName) {
diff --git a/Telegram/SourceFiles/platform/mac/specific_mac.h b/Telegram/SourceFiles/platform/mac/specific_mac.h
index 0d4c4896f..09de68ff9 100644
--- a/Telegram/SourceFiles/platform/mac/specific_mac.h
+++ b/Telegram/SourceFiles/platform/mac/specific_mac.h
@@ -22,6 +22,12 @@ QString SingleInstanceLocalServerName(const QString &hash);
void RemoveQuarantine(const QString &path);
+inline void FallbackFontConfigCheckBegin() {
+}
+
+inline void FallbackFontConfigCheckEnd() {
+}
+
namespace ThirdParty {
inline void start() {
diff --git a/Telegram/SourceFiles/platform/win/specific_win.h b/Telegram/SourceFiles/platform/win/specific_win.h
index 330cae4b7..17092a1c4 100644
--- a/Telegram/SourceFiles/platform/win/specific_win.h
+++ b/Telegram/SourceFiles/platform/win/specific_win.h
@@ -26,6 +26,12 @@ QString SingleInstanceLocalServerName(const QString &hash);
inline void IgnoreApplicationActivationRightNow() {
}
+inline void FallbackFontConfigCheckBegin() {
+}
+
+inline void FallbackFontConfigCheckEnd() {
+}
+
namespace ThirdParty {
void start();
diff --git a/Telegram/SourceFiles/storage/localstorage.cpp b/Telegram/SourceFiles/storage/localstorage.cpp
index 69728e6ba..9709842d6 100644
--- a/Telegram/SourceFiles/storage/localstorage.cpp
+++ b/Telegram/SourceFiles/storage/localstorage.cpp
@@ -15,6 +15,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_drafts.h"
#include "data/data_user.h"
#include "boxes/send_files_box.h"
+#include "base/flags.h"
+#include "base/platform/base_platform_file_utilities.h"
#include "base/platform/base_platform_info.h"
#include "ui/widgets/input_fields.h"
#include "ui/emoji_config.h"
@@ -35,7 +37,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "main/main_session.h"
#include "window/themes/window_theme.h"
#include "window/window_session_controller.h"
-#include "base/flags.h"
#include "data/data_session.h"
#include "history/history.h"
#include "facades.h"
@@ -251,97 +252,24 @@ struct EncryptedDescriptor {
};
struct FileWriteDescriptor {
- FileWriteDescriptor(const FileKey &key, FileOptions options = FileOption::User | FileOption::Safe)
- : file((options & FileOption::Safe) ? (QFileDevice&)saveFile : plainFile) {
- init(toFilePart(key), options);
- }
- FileWriteDescriptor(const QString &name, FileOptions options = FileOption::User | FileOption::Safe)
- : file((options & FileOption::Safe) ? (QFileDevice&)saveFile : plainFile) {
- init(name, options);
- }
- void init(const QString &name, FileOptions options) {
- if (options & FileOption::User) {
- if (!_userWorking()) return;
- } else {
- if (!_working()) return;
- }
+ FileWriteDescriptor(
+ const FileKey &key,
+ FileOptions options = FileOption::User | FileOption::Safe);
+ FileWriteDescriptor(
+ const QString &name,
+ FileOptions options = FileOption::User | FileOption::Safe);
+ ~FileWriteDescriptor();
- const auto base = ((options & FileOption::User) ? _userBasePath : _basePath) + name;
- if (options & FileOption::Safe) {
- toDelete = base;
- saveFile.setFileName(base + 's');
- } else {
- plainFile.setFileName(base + '0');
- }
- if (file.open(QIODevice::WriteOnly)) {
- file.write(tdfMagic, tdfMagicLen);
- qint32 version = AppVersion;
- file.write((const char*)&version, sizeof(version));
+ void init(const QString &name, FileOptions options);
+ bool writeData(const QByteArray &data);
+ bool writeEncrypted(
+ EncryptedDescriptor &data,
+ const MTP::AuthKeyPtr &key = LocalKey);
+ void finish();
- stream.setDevice(&file);
- stream.setVersion(QDataStream::Qt_5_1);
- }
- }
- bool writeData(const QByteArray &data) {
- if (!file.isOpen()) return false;
-
- stream << data;
- quint32 len = data.isNull() ? 0xffffffff : data.size();
- if (QSysInfo::ByteOrder != QSysInfo::BigEndian) {
- len = qbswap(len);
- }
- md5.feed(&len, sizeof(len));
- md5.feed(data.constData(), data.size());
- dataSize += sizeof(len) + data.size();
-
- return true;
- }
- static QByteArray prepareEncrypted(EncryptedDescriptor &data, const MTP::AuthKeyPtr &key = LocalKey) {
- data.finish();
- QByteArray &toEncrypt(data.data);
-
- // prepare for encryption
- uint32 size = toEncrypt.size(), fullSize = size;
- if (fullSize & 0x0F) {
- fullSize += 0x10 - (fullSize & 0x0F);
- toEncrypt.resize(fullSize);
- memset_rand(toEncrypt.data() + size, fullSize - size);
- }
- *(uint32*)toEncrypt.data() = size;
- QByteArray encrypted(0x10 + fullSize, Qt::Uninitialized); // 128bit of sha1 - key128, sizeof(data), data
- hashSha1(toEncrypt.constData(), toEncrypt.size(), encrypted.data());
- MTP::aesEncryptLocal(toEncrypt.constData(), encrypted.data() + 0x10, fullSize, key, encrypted.constData());
-
- return encrypted;
- }
- bool writeEncrypted(EncryptedDescriptor &data, const MTP::AuthKeyPtr &key = LocalKey) {
- return writeData(prepareEncrypted(data, key));
- }
- void finish() {
- if (!file.isOpen()) return;
-
- stream.setDevice(nullptr);
-
- md5.feed(&dataSize, sizeof(dataSize));
- qint32 version = AppVersion;
- md5.feed(&version, sizeof(version));
- md5.feed(tdfMagic, tdfMagicLen);
- file.write((const char*)md5.result(), 0x10);
-
- if (saveFile.isOpen()) {
- saveFile.commit();
- } else {
- plainFile.close();
- }
-
- if (!toDelete.isEmpty()) {
- QFile::remove(toDelete + '0');
- QFile::remove(toDelete + '1');
- }
- }
QFile plainFile;
QSaveFile saveFile;
- QFileDevice &file;
+ not_null file;
QDataStream stream;
QString toDelete;
@@ -349,11 +277,141 @@ struct FileWriteDescriptor {
HashMd5 md5;
int32 dataSize = 0;
- ~FileWriteDescriptor() {
- finish();
- }
};
+[[nodiscard]] QByteArray PrepareEncrypted(
+ EncryptedDescriptor &data,
+ const MTP::AuthKeyPtr &key = LocalKey) {
+ data.finish();
+ QByteArray &toEncrypt(data.data);
+
+ // prepare for encryption
+ uint32 size = toEncrypt.size(), fullSize = size;
+ if (fullSize & 0x0F) {
+ fullSize += 0x10 - (fullSize & 0x0F);
+ toEncrypt.resize(fullSize);
+ memset_rand(toEncrypt.data() + size, fullSize - size);
+ }
+ *(uint32*)toEncrypt.data() = size;
+ QByteArray encrypted(0x10 + fullSize, Qt::Uninitialized); // 128bit of sha1 - key128, sizeof(data), data
+ hashSha1(toEncrypt.constData(), toEncrypt.size(), encrypted.data());
+ MTP::aesEncryptLocal(toEncrypt.constData(), encrypted.data() + 0x10, fullSize, key, encrypted.constData());
+
+ return encrypted;
+}
+
+FileWriteDescriptor::FileWriteDescriptor(
+ const FileKey &key,
+ FileOptions options)
+: file((options & FileOption::Safe) ? (QFileDevice*)&saveFile : &plainFile) {
+ init(toFilePart(key), options);
+}
+
+FileWriteDescriptor::FileWriteDescriptor(
+ const QString &name,
+ FileOptions options)
+: file((options & FileOption::Safe) ? (QFileDevice*)&saveFile : &plainFile) {
+ init(name, options);
+}
+
+FileWriteDescriptor::~FileWriteDescriptor() {
+ finish();
+}
+
+void FileWriteDescriptor::init(const QString &name, FileOptions options) {
+ if (options & FileOption::User) {
+ if (!_userWorking()) return;
+ } else {
+ if (!_working()) return;
+ }
+
+ const auto base = ((options & FileOption::User) ? _userBasePath : _basePath) + name;
+ saveFile.setFileName(base + 's');
+ plainFile.setFileName(base + '0');
+ if (options & FileOption::Safe) {
+ toDelete = base;
+ }
+ if (!file->open(QIODevice::WriteOnly)) {
+ LOG(("Storage Error: Could not open '%1' for writing.").arg(file->fileName()));
+ if (!(options & FileOption::Safe)) {
+ return;
+ }
+ file = &plainFile;
+ LOG(("Storage Info: Trying to fallback to '%1'.").arg(file->fileName()));
+ if (!file->open(QIODevice::WriteOnly)) {
+ LOG(("Storage Error: Could not open '%1' for safe writing.").arg(file->fileName()));
+ return;
+ }
+ }
+ file->write(tdfMagic, tdfMagicLen);
+ qint32 version = AppVersion;
+ file->write((const char*)&version, sizeof(version));
+
+ stream.setDevice(file);
+ stream.setVersion(QDataStream::Qt_5_1);
+}
+
+bool FileWriteDescriptor::writeData(const QByteArray &data) {
+ if (!file->isOpen()) {
+ return false;
+ }
+
+ stream << data;
+ quint32 len = data.isNull() ? 0xffffffff : data.size();
+ if (QSysInfo::ByteOrder != QSysInfo::BigEndian) {
+ len = qbswap(len);
+ }
+ md5.feed(&len, sizeof(len));
+ md5.feed(data.constData(), data.size());
+ dataSize += sizeof(len) + data.size();
+
+ return true;
+}
+
+bool FileWriteDescriptor::writeEncrypted(
+ EncryptedDescriptor &data,
+ const MTP::AuthKeyPtr &key) {
+ return writeData(PrepareEncrypted(data, key));
+}
+
+void FileWriteDescriptor::finish() {
+ if (!file->isOpen()) {
+ return;
+ }
+
+ stream.setDevice(nullptr);
+
+ md5.feed(&dataSize, sizeof(dataSize));
+ qint32 version = AppVersion;
+ md5.feed(&version, sizeof(version));
+ md5.feed(tdfMagic, tdfMagicLen);
+ file->write((const char*)md5.result(), 0x10);
+
+ if (saveFile.isOpen()) {
+ if (!saveFile.commit()) {
+ LOG(("Storage Error: Could not commit safe writing in '%1'."
+ ).arg(saveFile.fileName()));
+ }
+ } else {
+ plainFile.close();
+ if (!toDelete.isEmpty()) {
+ QFile::remove(toDelete + '1');
+ if (!base::Platform::RenameWithOverwrite(
+ plainFile.fileName(),
+ saveFile.fileName())) {
+ LOG(("Storage Error: Could not rename '%1' to '%2'"
+ ).arg(plainFile.fileName()
+ ).arg(saveFile.fileName()));
+ }
+ }
+ }
+
+ if (!toDelete.isEmpty()) {
+ QFile::remove(toDelete + '0');
+ QFile::remove(toDelete + '1');
+ }
+}
+
bool readFile(FileReadDescriptor &result, const QString &name, FileOptions options = FileOption::User | FileOption::Safe) {
if (options & FileOption::User) {
if (!_userWorking()) return false;
@@ -2484,7 +2542,7 @@ void _writeMap(WriteMapWhen when) {
EncryptedDescriptor passKeyData(kLocalKeySize);
LocalKey->write(passKeyData.stream);
- _passKeyEncrypted = FileWriteDescriptor::prepareEncrypted(passKeyData, PassKey);
+ _passKeyEncrypted = PrepareEncrypted(passKeyData, PassKey);
}
map.writeData(_passKeySalt);
map.writeData(_passKeyEncrypted);
@@ -2873,7 +2931,7 @@ void setPasscode(const QByteArray &passcode) {
EncryptedDescriptor passKeyData(kLocalKeySize);
LocalKey->write(passKeyData.stream);
- _passKeyEncrypted = FileWriteDescriptor::prepareEncrypted(passKeyData, PassKey);
+ _passKeyEncrypted = PrepareEncrypted(passKeyData, PassKey);
_mapChanged = true;
_writeMap(WriteMapWhen::Now);
diff --git a/Telegram/SourceFiles/window/window_filters_menu.cpp b/Telegram/SourceFiles/window/window_filters_menu.cpp
index 06693879b..0fbddcc60 100644
--- a/Telegram/SourceFiles/window/window_filters_menu.cpp
+++ b/Telegram/SourceFiles/window/window_filters_menu.cpp
@@ -123,9 +123,12 @@ void FiltersMenu::setup() {
const auto j = _filters.find(_activeFilterId);
if (j != end(_filters)) {
j->second->setActive(true);
+ scrollToButton(j->second);
} else if (!_activeFilterId) {
_all->setActive(true);
+ scrollToButton(_all);
}
+ _reorder->finishReordering();
}, _outer.lifetime());
_menu.setClickedCallback([=] {
@@ -133,6 +136,32 @@ void FiltersMenu::setup() {
});
}
+void FiltersMenu::scrollToButton(not_null widget) {
+ const auto globalPosition = widget->mapToGlobal(QPoint(0, 0));
+ const auto localTop = _scroll.mapFromGlobal(globalPosition).y();
+ const auto localBottom = localTop + widget->height() - _scroll.height();
+ const auto isTopEdge = (localTop < 0);
+ const auto isBottomEdge = (localBottom > 0);
+ if (!isTopEdge && !isBottomEdge) {
+ return;
+ }
+
+ _scrollToAnimation.stop();
+ const auto scrollTop = _scroll.scrollTop();
+ const auto scrollTo = scrollTop + (isBottomEdge ? localBottom : localTop);
+
+ auto scroll = [=] {
+ _scroll.scrollToY(qRound(_scrollToAnimation.value(scrollTo)));
+ };
+
+ _scrollToAnimation.start(
+ std::move(scroll),
+ scrollTop,
+ scrollTo,
+ st::slideDuration,
+ anim::sineInOut);
+}
+
void FiltersMenu::refresh(bool firstLoad) {
const auto filters = &_session->session().data().chatsFilters();
if (filters->list().empty() || _ignoreRefresh) {
@@ -177,7 +206,7 @@ void FiltersMenu::setupList() {
tr::lng_filters_setup(tr::now),
Ui::FilterIcon::Setup);
}
- _reorder = std::make_unique(_list);
+ _reorder = std::make_unique(_list, &_scroll);
_reorder->updates(
) | rpl::start_with_next([=](Ui::VerticalLayoutReorder::Single data) {
diff --git a/Telegram/SourceFiles/window/window_filters_menu.h b/Telegram/SourceFiles/window/window_filters_menu.h
index 6266a0d4f..116def012 100644
--- a/Telegram/SourceFiles/window/window_filters_menu.h
+++ b/Telegram/SourceFiles/window/window_filters_menu.h
@@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
+#include "ui/effects/animations.h"
#include "ui/widgets/side_bar_button.h"
#include "ui/widgets/scroll_area.h"
#include "ui/wrap/vertical_layout.h"
@@ -51,6 +52,7 @@ private:
void showEditBox(FilterId id);
void showRemoveBox(FilterId id);
void remove(FilterId id);
+ void scrollToButton(not_null widget);
const not_null _session;
const not_null _parent;
@@ -70,6 +72,8 @@ private:
base::unique_qptr _popupMenu;
+ Ui::Animations::Simple _scrollToAnimation;
+
};
} // namespace Window
diff --git a/Telegram/build/version b/Telegram/build/version
index a1f24723d..b6e9151e0 100644
--- a/Telegram/build/version
+++ b/Telegram/build/version
@@ -1,7 +1,7 @@
-AppVersion 1009022
-AppVersionStrMajor 1.9
-AppVersionStrSmall 1.9.22
-AppVersionStr 1.9.22
-BetaChannel 1
+AppVersion 2000000
+AppVersionStrMajor 2.0
+AppVersionStrSmall 2.0
+AppVersionStr 2.0.0
+BetaChannel 0
AlphaVersion 0
-AppVersionOriginal 1.9.22.beta
+AppVersionOriginal 2.0
diff --git a/Telegram/cmake/telegram_options.cmake b/Telegram/cmake/telegram_options.cmake
index c2d34c18a..8f482ef86 100644
--- a/Telegram/cmake/telegram_options.cmake
+++ b/Telegram/cmake/telegram_options.cmake
@@ -4,6 +4,7 @@
# For license and copyright information please follow this link:
# https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
+option(TDESKTOP_USE_FONTCONFIG_FALLBACK "Use custom fonts.conf (Linux only)." OFF)
option(TDESKTOP_FORCE_GTK_FILE_DIALOG "Force using GTK file dialog (Linux only)." OFF)
option(TDESKTOP_DISABLE_REGISTER_CUSTOM_SCHEME "Disable automatic 'tg://' URL scheme handler registration." ${DESKTOP_APP_USE_PACKAGED})
option(TDESKTOP_DISABLE_NETWORK_PROXY "Disable all code for working through Socks5 or MTProxy." OFF)
@@ -63,6 +64,10 @@ if (DESKTOP_APP_SPECIAL_TARGET)
target_compile_definitions(Telegram PRIVATE TDESKTOP_ALLOW_CLOSED_ALPHA)
endif()
+if (TDESKTOP_USE_FONTCONFIG_FALLBACK)
+ target_compile_definitions(Telegram PRIVATE TDESKTOP_USE_FONTCONFIG_FALLBACK)
+endif()
+
if (TDESKTOP_FORCE_GTK_FILE_DIALOG)
target_compile_definitions(Telegram PRIVATE TDESKTOP_FORCE_GTK_FILE_DIALOG)
endif()
diff --git a/Telegram/lib_base b/Telegram/lib_base
index 7de25679d..05b4e4e2a 160000
--- a/Telegram/lib_base
+++ b/Telegram/lib_base
@@ -1 +1 @@
-Subproject commit 7de25679dd68f3fb7d2faee77ff5311f4d9587d6
+Subproject commit 05b4e4e2a813b2888858acde80f67c4eafffdbce
diff --git a/changelog.txt b/changelog.txt
index 258870949..5d85a0ba8 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -1,3 +1,12 @@
+2.0 (30.03.20)
+
+- Organize chats into Chat Folders if you have too many chats.
+- Create custom folders with flexible settings, or use default recommendations.
+- Pin an unlimited number of chats in each folder.
+- Switch between folders in the new side bar to easily access all of your chats.
+- Send :dice: to any chat to try your luck and get a random number from the animated dice.
+- Send :virus:, :face_with_thermometer:, :mask:, :face_with_head_bandage:, :sneeze:, :sick:, :soap: or :ambulance: to try out the new animated emoji.
+
1.9.22 beta (27.03.20)
- Organize chats into Chat Folders if you have too many chats.
diff --git a/cmake b/cmake
index d48723593..b4ea62dfd 160000
--- a/cmake
+++ b/cmake
@@ -1 +1 @@
-Subproject commit d48723593fa05c57814c74221e6b39c4c1fb2297
+Subproject commit b4ea62dfda376354aaae1482441a21ee06348580
diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml
index c15241153..75d4ae35c 100644
--- a/snap/snapcraft.yaml
+++ b/snap/snapcraft.yaml
@@ -102,6 +102,7 @@ parts:
- -DDESKTOP_APP_USE_PACKAGED_EXPECTED=OFF
- -DDESKTOP_APP_USE_PACKAGED_RLOTTIE=OFF
- -DTDESKTOP_USE_PACKAGED_TGVOIP=OFF
+ - -DTDESKTOP_USE_FONTCONFIG_FALLBACK=ON
override-pull: |
snapcraftctl pull
@@ -109,10 +110,6 @@ parts:
snapcraftctl set-version "$version"
sed -i 's|^Icon=.*|Icon=/share/icons/hicolor/512x512/apps/kotatogram.png|g' lib/xdg/kotatogramdesktop.desktop
- override-build: |
- snapcraftctl build
- mkdir -p "$SNAPCRAFT_PART_INSTALL/etc/fonts"
- cp "$SNAPCRAFT_PART_SRC/Telegram/lib_ui/qt_conf/fc-custom.conf" "$SNAPCRAFT_PART_INSTALL/etc/fonts/fonts.conf"
after:
- cmake
- desktop-qt5
@@ -150,13 +147,11 @@ parts:
- locales-all
- xdg-user-dirs
- fcitx-frontend-qt5
- stage: [-etc/fonts/fonts.conf]
qt5-gtk-platform:
plugin: nil
stage-packages:
- qt5-gtk-platformtheme
- stage: [-etc/fonts/fonts.conf]
cmake:
source: "https://gitlab.kitware.com/cmake/cmake.git"
@@ -182,13 +177,35 @@ parts:
- libtinfo5
prime: [-./*]
+ nasm:
+ source: https://repo.or.cz/nasm.git
+ source-depth: 1
+ source-tag: nasm-2.14.02
+ plugin: autotools
+ override-build: |
+ ./autogen.sh
+ ./configure --prefix=
+ make
+ install -d "$SNAPCRAFT_PART_INSTALL/bin"
+ install nasm "$SNAPCRAFT_PART_INSTALL/bin/nasm"
+ install ndisasm "$SNAPCRAFT_PART_INSTALL/bin/ndisasm"
+ prime: [-./*]
+
+ dav1d:
+ source: https://github.com/videolan/dav1d.git
+ source-depth: 1
+ source-tag: 0.6.0
+ plugin: meson
+ meson-parameters: [--prefix=/usr]
+ after:
+ - nasm
+
ffmpeg:
source: https://github.com/FFmpeg/FFmpeg.git
source-depth: 1
source-branch: release/4.2
plugin: autotools
build-packages:
- - yasm
- libasound2-dev
- libopus-dev
- libva-dev
@@ -210,6 +227,7 @@ parts:
- --disable-iconv
- --enable-gpl
- --enable-version3
+ - --enable-libdav1d
- --enable-libopus
- --enable-vaapi
- --enable-vdpau
@@ -219,6 +237,7 @@ parts:
- --enable-decoder=flac
- --enable-decoder=gif
- --enable-decoder=h264
+ - --enable-decoder=libdav1d
- --enable-decoder=mp1
- --enable-decoder=mp1float
- --enable-decoder=mp2
@@ -268,6 +287,8 @@ parts:
patch -p1 < "$SNAPCRAFT_STAGE/ffmpeg.diff"
after:
- patches
+ - nasm
+ - dav1d
openal:
source: https://github.com/kcat/openal-soft.git