Compare commits

...

9 Commits

Author SHA1 Message Date
John Preston
e5132e3fe8 Version 5.0.4
- Fix reply to last message by Ctrl+Up in topics.
- Some other bug fixes.
2024-05-28 20:32:48 +04:00
23rd
3b6870396c Added ability to hide every sponsored message to premium users. 2024-05-28 20:30:40 +04:00
23rd
f6b849e4f7 Added ability to add proxy from clipboard. 2024-05-28 20:30:40 +04:00
23rd
48e3802565 Improved labels for channel and group types with restricted content. 2024-05-28 20:30:40 +04:00
23rd
26ba7e57ce Fixed color of radial animation in audio files from shared media. 2024-05-28 20:30:40 +04:00
23rd
2605e754ff Added back button to cloud password step in intro. 2024-05-28 20:30:40 +04:00
23rd
9e85b1aa23 Fixed fake ability to hide webpage media with spoiler. 2024-05-28 20:30:40 +04:00
Ilya Fedin
88cd886ec8 Update lib_webview 2024-05-28 17:50:39 +04:00
John Preston
adc536b81d Fix Ctrl+Up reply in topics / comments. 2024-05-28 15:01:01 +04:00
21 changed files with 213 additions and 66 deletions

View File

@@ -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";

View File

@@ -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>

View File

@@ -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"

View File

@@ -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"

View File

@@ -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);

View File

@@ -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;

View File

@@ -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() {

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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);
}
}
});
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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 {

View File

@@ -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;

View File

@@ -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());

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -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.