Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e5132e3fe8 | ||
|
|
3b6870396c | ||
|
|
f6b849e4f7 | ||
|
|
48e3802565 | ||
|
|
26ba7e57ce | ||
|
|
2605e754ff | ||
|
|
9e85b1aa23 | ||
|
|
88cd886ec8 | ||
|
|
adc536b81d |
@@ -1053,6 +1053,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_proxy_sponsor" = "Proxy sponsor";
|
||||
"lng_proxy_sponsor_about" = "This channel is shown by your proxy server.\nTo remove this channel from your chats list,\ndisable the proxy in Telegram Settings.";
|
||||
"lng_proxy_sponsor_warning" = "This proxy may display a sponsored channel in your chat list. This doesn't reveal any of your Telegram traffic.";
|
||||
"lng_proxy_add_from_clipboard" = "Add proxy from clipboard";
|
||||
"lng_proxy_add_from_clipboard_good_toast" = "Proxy was added from clipboard.";
|
||||
"lng_proxy_add_from_clipboard_failed_toast" = "This is not a proxy link.";
|
||||
"lng_proxy_add_from_clipboard_existing_toast" = "This proxy is already in the list.";
|
||||
"lng_badge_psa_default" = "PSA";
|
||||
"lng_about_psa_default" = "This message provides you with a public service announcement. To remove it from your chats list, right click it and select **Hide**.";
|
||||
"lng_tooltip_psa_default" = "This message provides you with a public service announcement.";
|
||||
@@ -1522,8 +1526,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_manage_peer_link_invite" = "Invite link";
|
||||
"lng_manage_peer_link_expired" = "Expired link";
|
||||
"lng_manage_private_group_title" = "Private";
|
||||
"lng_manage_private_group_noforwards_title" = "Private restricted";
|
||||
"lng_manage_public_group_title" = "Public";
|
||||
"lng_manage_private_peer_title" = "Private";
|
||||
"lng_manage_private_peer_noforwards_title" = "Private restricted";
|
||||
"lng_manage_public_peer_title" = "Public";
|
||||
"lng_manage_peer_send_title" = "Who can send new messages?";
|
||||
"lng_manage_peer_send_only_members" = "Only members";
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<Identity Name="TelegramMessengerLLP.TelegramDesktop"
|
||||
ProcessorArchitecture="ARCHITECTURE"
|
||||
Publisher="CN=536BC709-8EE1-4478-AF22-F0F0F26FF64A"
|
||||
Version="5.0.3.0" />
|
||||
Version="5.0.4.0" />
|
||||
<Properties>
|
||||
<DisplayName>Telegram Desktop</DisplayName>
|
||||
<PublisherDisplayName>Telegram Messenger LLP</PublisherDisplayName>
|
||||
|
||||
@@ -44,8 +44,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico"
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 5,0,3,0
|
||||
PRODUCTVERSION 5,0,3,0
|
||||
FILEVERSION 5,0,4,0
|
||||
PRODUCTVERSION 5,0,4,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -62,10 +62,10 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Telegram FZ-LLC"
|
||||
VALUE "FileDescription", "Telegram Desktop"
|
||||
VALUE "FileVersion", "5.0.3.0"
|
||||
VALUE "FileVersion", "5.0.4.0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2014-2024"
|
||||
VALUE "ProductName", "Telegram Desktop"
|
||||
VALUE "ProductVersion", "5.0.3.0"
|
||||
VALUE "ProductVersion", "5.0.4.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
||||
@@ -35,8 +35,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 5,0,3,0
|
||||
PRODUCTVERSION 5,0,3,0
|
||||
FILEVERSION 5,0,4,0
|
||||
PRODUCTVERSION 5,0,4,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", "5.0.3.0"
|
||||
VALUE "FileVersion", "5.0.4.0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2014-2024"
|
||||
VALUE "ProductName", "Telegram Desktop"
|
||||
VALUE "ProductVersion", "5.0.3.0"
|
||||
VALUE "ProductVersion", "5.0.4.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
||||
@@ -7,31 +7,35 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "boxes/connection_box.h"
|
||||
|
||||
#include "ui/boxes/confirm_box.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "storage/localstorage.h"
|
||||
#include "base/qthelp_url.h"
|
||||
#include "base/call_delayed.h"
|
||||
#include "base/qthelp_regex.h"
|
||||
#include "base/qthelp_url.h"
|
||||
#include "core/application.h"
|
||||
#include "core/click_handler_types.h"
|
||||
#include "core/core_settings.h"
|
||||
#include "core/local_url_handlers.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "main/main_account.h"
|
||||
#include "mtproto/facade.h"
|
||||
#include "ui/widgets/checkbox.h"
|
||||
#include "storage/localstorage.h"
|
||||
#include "ui/basic_click_handlers.h"
|
||||
#include "ui/boxes/confirm_box.h"
|
||||
#include "ui/effects/animations.h"
|
||||
#include "ui/effects/radial_animation.h"
|
||||
#include "ui/painter.h"
|
||||
#include "ui/text/text_options.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "ui/toast/toast.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/checkbox.h"
|
||||
#include "ui/widgets/dropdown_menu.h"
|
||||
#include "ui/widgets/fields/input_field.h"
|
||||
#include "ui/widgets/fields/number_input.h"
|
||||
#include "ui/widgets/fields/password_input.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "ui/widgets/dropdown_menu.h"
|
||||
#include "ui/widgets/popup_menu.h"
|
||||
#include "ui/wrap/slide_wrap.h"
|
||||
#include "ui/wrap/vertical_layout.h"
|
||||
#include "ui/toast/toast.h"
|
||||
#include "ui/effects/animations.h"
|
||||
#include "ui/effects/radial_animation.h"
|
||||
#include "ui/text/text_options.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "ui/basic_click_handlers.h"
|
||||
#include "ui/painter.h"
|
||||
#include "boxes/abstract_box.h" // Ui::show().
|
||||
#include "styles/style_layers.h"
|
||||
#include "styles/style_boxes.h"
|
||||
@@ -48,6 +52,22 @@ constexpr auto kSaveSettingsDelayedTimeout = crl::time(1000);
|
||||
|
||||
using ProxyData = MTP::ProxyData;
|
||||
|
||||
[[nodiscard]] ProxyData ProxyDataFromFields(
|
||||
ProxyData::Type type,
|
||||
const QMap<QString, QString> &fields) {
|
||||
auto proxy = ProxyData();
|
||||
proxy.type = type;
|
||||
proxy.host = fields.value(u"server"_q);
|
||||
proxy.port = fields.value(u"port"_q).toUInt();
|
||||
if (type == ProxyData::Type::Socks5) {
|
||||
proxy.user = fields.value(u"user"_q);
|
||||
proxy.password = fields.value(u"pass"_q);
|
||||
} else if (type == ProxyData::Type::Mtproto) {
|
||||
proxy.password = fields.value(u"secret"_q);
|
||||
}
|
||||
return proxy;
|
||||
};
|
||||
|
||||
class HostInput : public Ui::MaskedInputField {
|
||||
public:
|
||||
HostInput(
|
||||
@@ -203,6 +223,7 @@ protected:
|
||||
|
||||
private:
|
||||
void setupContent();
|
||||
void setupTopButton();
|
||||
void createNoRowsLabel();
|
||||
void addNewProxy();
|
||||
void applyView(View &&view);
|
||||
@@ -600,9 +621,80 @@ void ProxiesBox::prepare() {
|
||||
addButton(tr::lng_proxy_add(), [=] { addNewProxy(); });
|
||||
addButton(tr::lng_close(), [=] { closeBox(); });
|
||||
|
||||
setupTopButton();
|
||||
setupContent();
|
||||
}
|
||||
|
||||
void ProxiesBox::setupTopButton() {
|
||||
const auto top = addTopButton(st::infoTopBarMenu);
|
||||
const auto menu
|
||||
= top->lifetime().make_state<base::unique_qptr<Ui::PopupMenu>>();
|
||||
const auto callback = [=] {
|
||||
const auto maybeUrl = QGuiApplication::clipboard()->text();
|
||||
const auto local = Core::TryConvertUrlToLocal(maybeUrl);
|
||||
|
||||
const auto proxyString = u"proxy"_q;
|
||||
const auto socksString = u"socks"_q;
|
||||
const auto protocol = u"tg://"_q;
|
||||
const auto command = base::StringViewMid(
|
||||
local,
|
||||
protocol.size(),
|
||||
8192);
|
||||
|
||||
if (local.startsWith(protocol + proxyString)
|
||||
|| local.startsWith(protocol + socksString)) {
|
||||
|
||||
using namespace qthelp;
|
||||
const auto options = RegExOption::CaseInsensitive;
|
||||
for (const auto &[expression, _] : Core::LocalUrlHandlers()) {
|
||||
const auto midExpression = base::StringViewMid(
|
||||
expression,
|
||||
1);
|
||||
const auto isSocks = midExpression.startsWith(
|
||||
socksString);
|
||||
if (!midExpression.startsWith(proxyString)
|
||||
&& !isSocks) {
|
||||
continue;
|
||||
}
|
||||
const auto match = regex_match(
|
||||
expression,
|
||||
command,
|
||||
options);
|
||||
if (!match) {
|
||||
continue;
|
||||
}
|
||||
const auto type = isSocks
|
||||
? ProxyData::Type::Socks5
|
||||
: ProxyData::Type::Mtproto;
|
||||
const auto fields = url_parse_params(
|
||||
match->captured(1),
|
||||
qthelp::UrlParamNameTransform::ToLower);
|
||||
const auto proxy = ProxyDataFromFields(type, fields);
|
||||
const auto contains = _controller->contains(proxy);
|
||||
const auto toast = (contains
|
||||
? tr::lng_proxy_add_from_clipboard_existing_toast
|
||||
: tr::lng_proxy_add_from_clipboard_good_toast)(tr::now);
|
||||
uiShow()->showToast(toast);
|
||||
if (!contains) {
|
||||
_controller->addNewItem(proxy);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
uiShow()->showToast(
|
||||
tr::lng_proxy_add_from_clipboard_failed_toast(tr::now));
|
||||
}
|
||||
};
|
||||
top->setClickedCallback([=] {
|
||||
*menu = base::make_unique_q<Ui::PopupMenu>(top, st::defaultPopupMenu);
|
||||
(*menu)->addAction(
|
||||
tr::lng_proxy_add_from_clipboard(tr::now),
|
||||
callback);
|
||||
(*menu)->popup(QCursor::pos());
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
void ProxiesBox::setupContent() {
|
||||
const auto inner = setInnerWidget(object_ptr<Ui::VerticalLayout>(this));
|
||||
|
||||
@@ -1096,24 +1188,13 @@ ProxiesBoxController::ProxiesBoxController(not_null<Main::Account*> account)
|
||||
void ProxiesBoxController::ShowApplyConfirmation(
|
||||
Type type,
|
||||
const QMap<QString, QString> &fields) {
|
||||
const auto server = fields.value(u"server"_q);
|
||||
const auto port = fields.value(u"port"_q).toUInt();
|
||||
auto proxy = ProxyData();
|
||||
proxy.type = type;
|
||||
proxy.host = server;
|
||||
proxy.port = port;
|
||||
if (type == Type::Socks5) {
|
||||
proxy.user = fields.value(u"user"_q);
|
||||
proxy.password = fields.value(u"pass"_q);
|
||||
} else if (type == Type::Mtproto) {
|
||||
proxy.password = fields.value(u"secret"_q);
|
||||
}
|
||||
const auto proxy = ProxyDataFromFields(type, fields);
|
||||
if (proxy) {
|
||||
static const auto UrlStartRegExp = QRegularExpression(
|
||||
"^https://",
|
||||
QRegularExpression::CaseInsensitiveOption);
|
||||
static const auto UrlEndRegExp = QRegularExpression("/$");
|
||||
const auto displayed = "https://" + server + "/";
|
||||
const auto displayed = "https://" + proxy.host + "/";
|
||||
const auto parsed = QUrl::fromUserInput(displayed);
|
||||
const auto displayUrl = !UrlClickHandler::IsSuspicious(displayed)
|
||||
? displayed
|
||||
@@ -1131,7 +1212,7 @@ void ProxiesBoxController::ShowApplyConfirmation(
|
||||
lt_server,
|
||||
displayServer,
|
||||
lt_port,
|
||||
QString::number(port))
|
||||
QString::number(proxy.port))
|
||||
+ (proxy.type == Type::Mtproto
|
||||
? "\n\n" + tr::lng_proxy_sponsor_warning(tr::now)
|
||||
: QString());
|
||||
@@ -1448,6 +1529,14 @@ object_ptr<Ui::BoxContent> ProxiesBoxController::addNewItemBox() {
|
||||
});
|
||||
}
|
||||
|
||||
bool ProxiesBoxController::contains(const ProxyData &proxy) const {
|
||||
const auto j = ranges::find(
|
||||
_list,
|
||||
proxy,
|
||||
[](const Item &item) { return item.data; });
|
||||
return (j != end(_list));
|
||||
}
|
||||
|
||||
void ProxiesBoxController::addNewItem(const ProxyData &proxy) {
|
||||
auto &proxies = _settings.list();
|
||||
proxies.push_back(proxy);
|
||||
|
||||
@@ -77,6 +77,9 @@ public:
|
||||
void setTryIPv6(bool enabled);
|
||||
rpl::producer<ProxyData::Settings> proxySettingsValue() const;
|
||||
|
||||
[[nodiscard]] bool contains(const ProxyData &proxy) const;
|
||||
void addNewItem(const ProxyData &proxy);
|
||||
|
||||
rpl::producer<ItemView> views() const;
|
||||
|
||||
~ProxiesBoxController();
|
||||
@@ -109,7 +112,6 @@ private:
|
||||
void replaceItemValue(
|
||||
std::vector<Item>::iterator which,
|
||||
const ProxyData &proxy);
|
||||
void addNewItem(const ProxyData &proxy);
|
||||
|
||||
const not_null<Main::Account*> _account;
|
||||
Core::SettingsProxy &_settings;
|
||||
|
||||
@@ -415,7 +415,12 @@ private:
|
||||
std::deque<FnMut<void()>> _saveStagesQueue;
|
||||
Saving _savingData;
|
||||
|
||||
const rpl::event_stream<Privacy> _privacyTypeUpdates;
|
||||
struct PrivacyAndForwards {
|
||||
Privacy privacy;
|
||||
bool noForwards = false;
|
||||
};
|
||||
|
||||
const rpl::event_stream<PrivacyAndForwards> _privacyTypeUpdates;
|
||||
const rpl::event_stream<ChannelData*> _linkedChatUpdates;
|
||||
mtpRequestId _linkedChatsRequestId = 0;
|
||||
|
||||
@@ -761,7 +766,7 @@ void Controller::refreshHistoryVisibility() {
|
||||
void Controller::showEditPeerTypeBox(
|
||||
std::optional<rpl::producer<QString>> error) {
|
||||
const auto boxCallback = crl::guard(this, [=](EditPeerTypeData data) {
|
||||
_privacyTypeUpdates.fire_copy(data.privacy);
|
||||
_privacyTypeUpdates.fire({ data.privacy, data.noForwards });
|
||||
_typeDataSavedValue = data;
|
||||
refreshHistoryVisibility();
|
||||
});
|
||||
@@ -882,7 +887,8 @@ void Controller::fillPrivacyTypeButton() {
|
||||
? tr::lng_manage_peer_group_type
|
||||
: tr::lng_manage_peer_channel_type)(),
|
||||
_privacyTypeUpdates.events(
|
||||
) | rpl::map([=](Privacy flag) {
|
||||
) | rpl::map([=](PrivacyAndForwards data) {
|
||||
const auto flag = data.privacy;
|
||||
if (flag == Privacy::HasUsername) {
|
||||
_peer->session().api().usernames().requestToCache(_peer);
|
||||
}
|
||||
@@ -894,14 +900,21 @@ void Controller::fillPrivacyTypeButton() {
|
||||
: tr::lng_manage_public_peer_title)()
|
||||
: (hasLocation
|
||||
? tr::lng_manage_peer_link_invite
|
||||
: isGroup
|
||||
: ((!data.noForwards) && isGroup)
|
||||
? tr::lng_manage_private_group_title
|
||||
: tr::lng_manage_private_peer_title)();
|
||||
: ((!data.noForwards) && !isGroup)
|
||||
? tr::lng_manage_private_peer_title
|
||||
: isGroup
|
||||
? tr::lng_manage_private_group_noforwards_title
|
||||
: tr::lng_manage_private_peer_noforwards_title)();
|
||||
}) | rpl::flatten_latest(),
|
||||
[=] { showEditPeerTypeBox(); },
|
||||
{ &st::menuIconCustomize });
|
||||
|
||||
_privacyTypeUpdates.fire_copy(_typeDataSavedValue->privacy);
|
||||
_privacyTypeUpdates.fire_copy({
|
||||
_typeDataSavedValue->privacy,
|
||||
_typeDataSavedValue->noForwards,
|
||||
});
|
||||
}
|
||||
|
||||
void Controller::fillLinkedChatButton() {
|
||||
|
||||
@@ -22,7 +22,7 @@ constexpr auto AppId = "{53F49750-6209-4FBF-9CA8-7A333C87D1ED}"_cs;
|
||||
constexpr auto AppNameOld = "Telegram Win (Unofficial)"_cs;
|
||||
constexpr auto AppName = "Telegram Desktop"_cs;
|
||||
constexpr auto AppFile = "Telegram"_cs;
|
||||
constexpr auto AppVersion = 5000003;
|
||||
constexpr auto AppVersionStr = "5.0.3";
|
||||
constexpr auto AppVersion = 5000004;
|
||||
constexpr auto AppVersionStr = "5.0.4";
|
||||
constexpr auto AppBetaVersion = false;
|
||||
constexpr auto AppAlphaVersion = TDESKTOP_ALPHA_VERSION;
|
||||
|
||||
@@ -161,7 +161,13 @@ void FillSponsoredMessagesMenu(
|
||||
menu->addSeparator(&st::expandedMenuSeparator);
|
||||
}
|
||||
menu->addAction(tr::lng_sponsored_hide_ads(tr::now), [=] {
|
||||
ShowPremiumPreviewBox(controller, PremiumFeature::NoAds);
|
||||
if (controller->session().premium()) {
|
||||
using Result = Data::SponsoredReportResult;
|
||||
controller->session().sponsoredMessages().createReportCallback(
|
||||
itemId)(Result::Id("-1"), [](const auto &) {});
|
||||
} else {
|
||||
ShowPremiumPreviewBox(controller, PremiumFeature::NoAds);
|
||||
}
|
||||
}, &st::menuIconCancel);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "api/api_text_entities.h"
|
||||
#include "boxes/premium_preview_box.h"
|
||||
#include "calls/calls_instance.h"
|
||||
#include "data/components/sponsored_messages.h"
|
||||
#include "data/stickers/data_custom_emoji.h"
|
||||
#include "data/notify/data_notify_settings.h"
|
||||
#include "data/data_channel.h"
|
||||
@@ -363,7 +364,14 @@ ClickHandlerPtr HideSponsoredClickHandler() {
|
||||
return std::make_shared<LambdaClickHandler>([=](ClickContext context) {
|
||||
const auto my = context.other.value<ClickHandlerContext>();
|
||||
if (const auto controller = my.sessionWindow.get()) {
|
||||
ShowPremiumPreviewBox(controller, PremiumFeature::NoAds);
|
||||
const auto &session = controller->session();
|
||||
if (session.premium()) {
|
||||
using Result = Data::SponsoredReportResult;
|
||||
session.sponsoredMessages().createReportCallback(
|
||||
my.itemId)(Result::Id("-1"), [](const auto &) {});
|
||||
} else {
|
||||
ShowPremiumPreviewBox(controller, PremiumFeature::NoAds);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ void MediaEditSpoilerManager::showMenu(
|
||||
const auto media = item->media();
|
||||
const auto hasPreview = media && media->hasReplyPreview();
|
||||
const auto preview = hasPreview ? media->replyPreview() : nullptr;
|
||||
if (!preview) {
|
||||
if (!preview || (media && media->webpage())) {
|
||||
return;
|
||||
}
|
||||
const auto spoilered = _spoilerOverride
|
||||
|
||||
@@ -16,6 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "api/api_transcribes.h"
|
||||
#include "api/api_who_reacted.h"
|
||||
#include "api/api_toggling_media.h" // Api::ToggleFavedSticker
|
||||
#include "base/qt/qt_key_modifiers.h"
|
||||
#include "base/unixtime.h"
|
||||
#include "history/view/history_view_list_widget.h"
|
||||
#include "history/view/history_view_cursor_state.h"
|
||||
@@ -636,7 +637,7 @@ bool AddReplyToMessageAction(
|
||||
.messageId = itemId,
|
||||
.quote = quote.text,
|
||||
.quoteOffset = quote.offset,
|
||||
});
|
||||
}, base::IsCtrlPressed());
|
||||
}, &st::menuIconReply);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -3904,12 +3904,15 @@ bool ListWidget::lastMessageEditRequestNotify() const {
|
||||
}
|
||||
}
|
||||
|
||||
rpl::producer<FullReplyTo> ListWidget::replyToMessageRequested() const {
|
||||
auto ListWidget::replyToMessageRequested() const
|
||||
-> rpl::producer<ReplyToMessageRequest> {
|
||||
return _requestedToReplyToMessage.events();
|
||||
}
|
||||
|
||||
void ListWidget::replyToMessageRequestNotify(FullReplyTo id) {
|
||||
_requestedToReplyToMessage.fire(std::move(id));
|
||||
void ListWidget::replyToMessageRequestNotify(
|
||||
FullReplyTo to,
|
||||
bool forceAnotherChat) {
|
||||
_requestedToReplyToMessage.fire({ std::move(to), forceAnotherChat });
|
||||
}
|
||||
|
||||
rpl::producer<FullMsgId> ListWidget::readMessageRequested() const {
|
||||
|
||||
@@ -286,11 +286,18 @@ public:
|
||||
QPoint tooltipPos() const override;
|
||||
bool tooltipWindowActive() const override;
|
||||
|
||||
struct ReplyToMessageRequest {
|
||||
FullReplyTo to;
|
||||
bool forceAnotherChat = false;
|
||||
};
|
||||
[[nodiscard]] rpl::producer<FullMsgId> editMessageRequested() const;
|
||||
void editMessageRequestNotify(FullMsgId item) const;
|
||||
[[nodiscard]] bool lastMessageEditRequestNotify() const;
|
||||
[[nodiscard]] rpl::producer<FullReplyTo> replyToMessageRequested() const;
|
||||
void replyToMessageRequestNotify(FullReplyTo id);
|
||||
[[nodiscard]] auto replyToMessageRequested() const
|
||||
-> rpl::producer<ReplyToMessageRequest>;
|
||||
void replyToMessageRequestNotify(
|
||||
FullReplyTo to,
|
||||
bool forceAnotherChat = false);
|
||||
[[nodiscard]] rpl::producer<FullMsgId> readMessageRequested() const;
|
||||
[[nodiscard]] rpl::producer<FullMsgId> showMessageRequested() const;
|
||||
void replyNextMessage(FullMsgId fullId, bool next = true);
|
||||
@@ -760,7 +767,7 @@ private:
|
||||
base::Timer _touchScrollTimer;
|
||||
|
||||
rpl::event_stream<FullMsgId> _requestedToEditMessage;
|
||||
rpl::event_stream<FullReplyTo> _requestedToReplyToMessage;
|
||||
rpl::event_stream<ReplyToMessageRequest> _requestedToReplyToMessage;
|
||||
rpl::event_stream<FullMsgId> _requestedToReadMessage;
|
||||
rpl::event_stream<FullMsgId> _requestedToShowMessage;
|
||||
|
||||
|
||||
@@ -323,14 +323,15 @@ RepliesWidget::RepliesWidget(
|
||||
}, _inner->lifetime());
|
||||
|
||||
_inner->replyToMessageRequested(
|
||||
) | rpl::start_with_next([=](auto fullId) {
|
||||
) | rpl::start_with_next([=](ListWidget::ReplyToMessageRequest request) {
|
||||
const auto canSendReply = _topic
|
||||
? Data::CanSendAnything(_topic)
|
||||
: Data::CanSendAnything(_history->peer);
|
||||
if (_joinGroup || !canSendReply || base::IsCtrlPressed()) {
|
||||
Controls::ShowReplyToChatBox(controller->uiShow(), { fullId });
|
||||
const auto &to = request.to;
|
||||
if (_joinGroup || !canSendReply || request.forceAnotherChat) {
|
||||
Controls::ShowReplyToChatBox(controller->uiShow(), { to });
|
||||
} else {
|
||||
replyToMessage(fullId);
|
||||
replyToMessage(to);
|
||||
_composeControls->focus();
|
||||
}
|
||||
}, _inner->lifetime());
|
||||
|
||||
@@ -35,6 +35,10 @@ public:
|
||||
void submit() override;
|
||||
rpl::producer<QString> nextButtonText() const override;
|
||||
|
||||
bool hasBack() const override {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *e) override;
|
||||
|
||||
|
||||
@@ -849,7 +849,7 @@ void Widget::backRequested() {
|
||||
Core::App().domain().activate(parent);
|
||||
} else {
|
||||
moveToStep(
|
||||
new StartWidget(this, _account, getData()),
|
||||
Ui::CreateChild<StartWidget>(this, _account, getData()),
|
||||
StackAction::Replace,
|
||||
Animate::Back);
|
||||
}
|
||||
|
||||
@@ -1398,7 +1398,9 @@ void Document::drawCornerDownload(QPainter &p, bool selected, const PaintContext
|
||||
icon->paintInCenter(p, inner);
|
||||
if (_radial && _radial->animating()) {
|
||||
const auto rinner = inner.marginsRemoved(QMargins(st::historyAudioRadialLine, st::historyAudioRadialLine, st::historyAudioRadialLine, st::historyAudioRadialLine));
|
||||
auto fg = selected ? st::historyFileThumbRadialFgSelected : st::historyFileThumbRadialFg;
|
||||
const auto &fg = selected
|
||||
? st::historyFileInIconFgSelected
|
||||
: st::historyFileInIconFg;
|
||||
_radial->draw(p, rinner, st::historyAudioRadialLine, fg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
AppVersion 5000003
|
||||
AppVersion 5000004
|
||||
AppVersionStrMajor 5.0
|
||||
AppVersionStrSmall 5.0.3
|
||||
AppVersionStr 5.0.3
|
||||
AppVersionStrSmall 5.0.4
|
||||
AppVersionStr 5.0.4
|
||||
BetaChannel 0
|
||||
AlphaVersion 0
|
||||
AppVersionOriginal 5.0.3
|
||||
AppVersionOriginal 5.0.4
|
||||
|
||||
Submodule Telegram/lib_webview updated: 064ff7cafe...115530c7aa
@@ -1,3 +1,8 @@
|
||||
5.0.4 (28.05.24)
|
||||
|
||||
- Fix reply to last message by Ctrl+Up in topics.
|
||||
- Some other bug fixes.
|
||||
|
||||
5.0.3 (28.05.24)
|
||||
|
||||
- Ctrl+Click on Reply in menu to Reply in another chat.
|
||||
|
||||
Reference in New Issue
Block a user