Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7351641034 | ||
|
|
e0669e222d | ||
|
|
4c1f83daca | ||
|
|
ced2652deb | ||
|
|
8d1db85a28 | ||
|
|
97305c8cb5 | ||
|
|
1ef5d81270 | ||
|
|
9ff427afad | ||
|
|
1c5eadcd79 | ||
|
|
bc6c01de7f | ||
|
|
41255cab44 | ||
|
|
ccbc63cd6e | ||
|
|
97446ae783 | ||
|
|
5a75dd2b6f | ||
|
|
6559e83e83 |
@@ -90,6 +90,7 @@ if (LINUX)
|
||||
PRIVATE
|
||||
desktop-app::external_statusnotifieritem
|
||||
desktop-app::external_dbusmenu_qt
|
||||
desktop-app::external_fcitx_qt5
|
||||
desktop-app::external_fcitx5_qt5
|
||||
desktop-app::external_hime_qt
|
||||
)
|
||||
|
||||
@@ -1454,6 +1454,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_context_edit_msg" = "Edit";
|
||||
"lng_context_forward_msg" = "Forward Message";
|
||||
"lng_context_send_now_msg" = "Send now";
|
||||
"lng_context_reschedule" = "Reschedule";
|
||||
"lng_context_delete_msg" = "Delete Message";
|
||||
"lng_context_select_msg" = "Select Message";
|
||||
"lng_context_report_msg" = "Report Message";
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<Identity Name="TelegramMessengerLLP.TelegramDesktop"
|
||||
ProcessorArchitecture="ARCHITECTURE"
|
||||
Publisher="CN=536BC709-8EE1-4478-AF22-F0F0F26FF64A"
|
||||
Version="2.1.6.0" />
|
||||
Version="2.1.7.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,6,0
|
||||
PRODUCTVERSION 2,1,6,0
|
||||
FILEVERSION 2,1,7,0
|
||||
PRODUCTVERSION 2,1,7,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.6.0"
|
||||
VALUE "FileVersion", "2.1.7.0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2014-2020"
|
||||
VALUE "ProductName", "Telegram Desktop"
|
||||
VALUE "ProductVersion", "2.1.6.0"
|
||||
VALUE "ProductVersion", "2.1.7.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
||||
@@ -35,8 +35,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 2,1,6,0
|
||||
PRODUCTVERSION 2,1,6,0
|
||||
FILEVERSION 2,1,7,0
|
||||
PRODUCTVERSION 2,1,7,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.6.0"
|
||||
VALUE "FileVersion", "2.1.7.0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2014-2020"
|
||||
VALUE "ProductName", "Telegram Desktop"
|
||||
VALUE "ProductVersion", "2.1.6.0"
|
||||
VALUE "ProductVersion", "2.1.7.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
||||
@@ -30,6 +30,26 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
namespace Api {
|
||||
namespace {
|
||||
|
||||
void InnerFillMessagePostFlags(
|
||||
const Api::SendOptions &options,
|
||||
not_null<PeerData*> peer,
|
||||
MTPDmessage::Flags &flags) {
|
||||
const auto channelPost = peer->isChannel() && !peer->isMegagroup();
|
||||
if (!channelPost) {
|
||||
flags |= MTPDmessage::Flag::f_from_id;
|
||||
return;
|
||||
}
|
||||
flags |= MTPDmessage::Flag::f_post;
|
||||
// Don't display views and author of a new post when it's scheduled.
|
||||
if (options.scheduled) {
|
||||
return;
|
||||
}
|
||||
flags |= MTPDmessage::Flag::f_views;
|
||||
if (peer->asChannel()->addsSignature()) {
|
||||
flags |= MTPDmessage::Flag::f_post_author;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename MediaData>
|
||||
void SendExistingMedia(
|
||||
Api::MessageToSend &&message,
|
||||
@@ -60,15 +80,7 @@ void SendExistingMedia(
|
||||
const auto channelPost = peer->isChannel() && !peer->isMegagroup();
|
||||
const auto silentPost = message.action.options.silent
|
||||
|| (channelPost && session->data().notifySilentPosts(peer));
|
||||
if (channelPost) {
|
||||
flags |= MTPDmessage::Flag::f_views;
|
||||
flags |= MTPDmessage::Flag::f_post;
|
||||
}
|
||||
if (!channelPost) {
|
||||
flags |= MTPDmessage::Flag::f_from_id;
|
||||
} else if (peer->asChannel()->addsSignature()) {
|
||||
flags |= MTPDmessage::Flag::f_post_author;
|
||||
}
|
||||
InnerFillMessagePostFlags(message.action.options, peer, flags);
|
||||
if (silentPost) {
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_silent;
|
||||
}
|
||||
@@ -246,15 +258,7 @@ bool SendDice(Api::MessageToSend &message) {
|
||||
const auto channelPost = peer->isChannel() && !peer->isMegagroup();
|
||||
const auto silentPost = message.action.options.silent
|
||||
|| (channelPost && session->data().notifySilentPosts(peer));
|
||||
if (channelPost) {
|
||||
flags |= MTPDmessage::Flag::f_views;
|
||||
flags |= MTPDmessage::Flag::f_post;
|
||||
}
|
||||
if (!channelPost) {
|
||||
flags |= MTPDmessage::Flag::f_from_id;
|
||||
} else if (peer->asChannel()->addsSignature()) {
|
||||
flags |= MTPDmessage::Flag::f_post_author;
|
||||
}
|
||||
InnerFillMessagePostFlags(message.action.options, peer, flags);
|
||||
if (silentPost) {
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_silent;
|
||||
}
|
||||
@@ -320,4 +324,11 @@ bool SendDice(Api::MessageToSend &message) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void FillMessagePostFlags(
|
||||
const Api::SendAction &action,
|
||||
not_null<PeerData*> peer,
|
||||
MTPDmessage::Flags &flags) {
|
||||
InnerFillMessagePostFlags(action.options, peer, flags);
|
||||
}
|
||||
|
||||
} // namespace Api
|
||||
|
||||
@@ -25,4 +25,9 @@ void SendExistingPhoto(
|
||||
|
||||
bool SendDice(Api::MessageToSend &message);
|
||||
|
||||
void FillMessagePostFlags(
|
||||
const SendAction &action,
|
||||
not_null<PeerData*> peer,
|
||||
MTPDmessage::Flags &flags);
|
||||
|
||||
} // namespace Api
|
||||
|
||||
@@ -4328,15 +4328,7 @@ void ApiWrap::forwardMessages(
|
||||
auto flags = MTPDmessage::Flags(0);
|
||||
auto clientFlags = MTPDmessage_ClientFlags();
|
||||
auto sendFlags = MTPmessages_ForwardMessages::Flags(0);
|
||||
if (channelPost) {
|
||||
flags |= MTPDmessage::Flag::f_views;
|
||||
flags |= MTPDmessage::Flag::f_post;
|
||||
}
|
||||
if (!channelPost) {
|
||||
flags |= MTPDmessage::Flag::f_from_id;
|
||||
} else if (peer->asChannel()->addsSignature()) {
|
||||
flags |= MTPDmessage::Flag::f_post_author;
|
||||
}
|
||||
FillMessagePostFlags(action, peer, flags);
|
||||
if (silentPost) {
|
||||
sendFlags |= MTPmessages_ForwardMessages::Flag::f_silent;
|
||||
}
|
||||
@@ -4489,15 +4481,7 @@ void ApiWrap::sendSharedContact(
|
||||
if (action.replyTo) {
|
||||
flags |= MTPDmessage::Flag::f_reply_to_msg_id;
|
||||
}
|
||||
if (channelPost) {
|
||||
flags |= MTPDmessage::Flag::f_views;
|
||||
flags |= MTPDmessage::Flag::f_post;
|
||||
if (peer->asChannel()->addsSignature()) {
|
||||
flags |= MTPDmessage::Flag::f_post_author;
|
||||
}
|
||||
} else {
|
||||
flags |= MTPDmessage::Flag::f_from_id;
|
||||
}
|
||||
FillMessagePostFlags(action, peer, flags);
|
||||
if (action.options.scheduled) {
|
||||
flags |= MTPDmessage::Flag::f_from_scheduled;
|
||||
} else {
|
||||
@@ -4874,15 +4858,7 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
|
||||
const auto channelPost = peer->isChannel() && !peer->isMegagroup();
|
||||
const auto silentPost = action.options.silent
|
||||
|| (channelPost && _session->data().notifySilentPosts(peer));
|
||||
if (channelPost) {
|
||||
flags |= MTPDmessage::Flag::f_views;
|
||||
flags |= MTPDmessage::Flag::f_post;
|
||||
}
|
||||
if (!channelPost) {
|
||||
flags |= MTPDmessage::Flag::f_from_id;
|
||||
} else if (peer->asChannel()->addsSignature()) {
|
||||
flags |= MTPDmessage::Flag::f_post_author;
|
||||
}
|
||||
FillMessagePostFlags(action, peer, flags);
|
||||
if (silentPost) {
|
||||
sendFlags |= MTPmessages_SendMessage::Flag::f_silent;
|
||||
}
|
||||
@@ -5019,15 +4995,7 @@ void ApiWrap::sendInlineResult(
|
||||
bool channelPost = peer->isChannel() && !peer->isMegagroup();
|
||||
bool silentPost = action.options.silent
|
||||
|| (channelPost && _session->data().notifySilentPosts(peer));
|
||||
if (channelPost) {
|
||||
flags |= MTPDmessage::Flag::f_views;
|
||||
flags |= MTPDmessage::Flag::f_post;
|
||||
}
|
||||
if (!channelPost) {
|
||||
flags |= MTPDmessage::Flag::f_from_id;
|
||||
} else if (peer->asChannel()->addsSignature()) {
|
||||
flags |= MTPDmessage::Flag::f_post_author;
|
||||
}
|
||||
FillMessagePostFlags(action, peer, flags);
|
||||
if (silentPost) {
|
||||
sendFlags |= MTPmessages_SendInlineBotResult::Flag::f_silent;
|
||||
}
|
||||
@@ -5857,6 +5825,43 @@ void ApiWrap::closePoll(not_null<HistoryItem*> item) {
|
||||
_pollCloseRequestIds.emplace(itemId, requestId);
|
||||
}
|
||||
|
||||
void ApiWrap::rescheduleMessage(
|
||||
not_null<HistoryItem*> item,
|
||||
Api::SendOptions options) {
|
||||
const auto text = item->originalText().text;
|
||||
const auto sentEntities = Api::EntitiesToMTP(
|
||||
item->originalText().entities,
|
||||
Api::ConvertOption::SkipLocal);
|
||||
const auto media = item->media();
|
||||
|
||||
const auto emptyFlag = MTPmessages_EditMessage::Flag(0);
|
||||
const auto flags = MTPmessages_EditMessage::Flag::f_schedule_date
|
||||
| (!text.isEmpty()
|
||||
? MTPmessages_EditMessage::Flag::f_message
|
||||
: emptyFlag)
|
||||
| ((!media || !media->webpage())
|
||||
? MTPmessages_EditMessage::Flag::f_no_webpage
|
||||
: emptyFlag)
|
||||
| (!sentEntities.v.isEmpty()
|
||||
? MTPmessages_EditMessage::Flag::f_entities
|
||||
: emptyFlag);
|
||||
|
||||
const auto id = _session->data().scheduledMessages().lookupId(item);
|
||||
request(MTPmessages_EditMessage(
|
||||
MTP_flags(flags),
|
||||
item->history()->peer->input,
|
||||
MTP_int(id),
|
||||
MTP_string(text),
|
||||
MTPInputMedia(),
|
||||
MTPReplyMarkup(),
|
||||
sentEntities,
|
||||
MTP_int(options.scheduled)
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
applyUpdates(result);
|
||||
}).fail([](const RPCError &error) {
|
||||
}).send();
|
||||
}
|
||||
|
||||
void ApiWrap::reloadPollResults(not_null<HistoryItem*> item) {
|
||||
const auto itemId = item->fullId();
|
||||
if (!IsServerMsgId(item->id)
|
||||
|
||||
@@ -476,6 +476,10 @@ public:
|
||||
void closePoll(not_null<HistoryItem*> item);
|
||||
void reloadPollResults(not_null<HistoryItem*> item);
|
||||
|
||||
void rescheduleMessage(
|
||||
not_null<HistoryItem*> item,
|
||||
Api::SendOptions options);
|
||||
|
||||
private:
|
||||
struct MessageDataRequest {
|
||||
using Callbacks = QList<RequestMessageDataCallback>;
|
||||
|
||||
@@ -599,4 +599,19 @@ void CalendarBox::keyPressEvent(QKeyEvent *e) {
|
||||
}
|
||||
}
|
||||
|
||||
void CalendarBox::wheelEvent(QWheelEvent *e) {
|
||||
// Only a mouse wheel is accepted.
|
||||
constexpr auto step = static_cast<int>(QWheelEvent::DefaultDeltasPerStep);
|
||||
const auto delta = e->angleDelta().y();
|
||||
if (std::abs(delta) != step) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (delta < 0) {
|
||||
goPreviousMonth();
|
||||
} else {
|
||||
goNextMonth();
|
||||
}
|
||||
}
|
||||
|
||||
CalendarBox::~CalendarBox() = default;
|
||||
|
||||
@@ -46,6 +46,7 @@ protected:
|
||||
|
||||
void keyPressEvent(QKeyEvent *e) override;
|
||||
void resizeEvent(QResizeEvent *e) override;
|
||||
void wheelEvent(QWheelEvent *e) override;
|
||||
|
||||
private:
|
||||
void monthChanged(QDate month);
|
||||
|
||||
@@ -551,10 +551,7 @@ void EditCaptionBox::prepare() {
|
||||
} else if (data->hasImage()) {
|
||||
return true;
|
||||
} else if (const auto urls = data->urls(); !urls.empty()) {
|
||||
if (ranges::find_if(
|
||||
urls,
|
||||
[](const QUrl &url) { return !url.isLocalFile(); }
|
||||
) == urls.end()) {
|
||||
if (ranges::all_of(urls, &QUrl::isLocalFile)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 = 2001006;
|
||||
constexpr auto AppVersionStr = "2.1.6";
|
||||
constexpr auto AppVersion = 2001007;
|
||||
constexpr auto AppVersionStr = "2.1.7";
|
||||
constexpr auto AppBetaVersion = false;
|
||||
constexpr auto AppAlphaVersion = TDESKTOP_ALPHA_VERSION;
|
||||
|
||||
@@ -414,6 +414,7 @@ HistoryItem *ScheduledMessages::append(
|
||||
}, data.vmedia());
|
||||
existing->updateReplyMarkup(data.vreply_markup());
|
||||
existing->updateForwardedInfo(data.vfwd_from());
|
||||
existing->updateDate(data.vdate().v);
|
||||
history->owner().requestItemTextRefresh(existing);
|
||||
}, [&](const auto &data) {});
|
||||
return existing;
|
||||
|
||||
@@ -708,6 +708,17 @@ MsgId HistoryItem::idOriginal() const {
|
||||
return id;
|
||||
}
|
||||
|
||||
void HistoryItem::updateDate(TimeId newDate) {
|
||||
if (canUpdateDate() && _date != newDate) {
|
||||
_date = newDate;
|
||||
_history->owner().requestItemViewRefresh(this);
|
||||
}
|
||||
}
|
||||
|
||||
bool HistoryItem::canUpdateDate() const {
|
||||
return isScheduled();
|
||||
}
|
||||
|
||||
void HistoryItem::sendFailed() {
|
||||
Expects(_clientFlags & MTPDmessage_ClientFlag::f_sending);
|
||||
Expects(!(_clientFlags & MTPDmessage_ClientFlag::f_failed));
|
||||
|
||||
@@ -328,6 +328,9 @@ public:
|
||||
[[nodiscard]] virtual std::unique_ptr<HistoryView::Element> createView(
|
||||
not_null<HistoryView::ElementDelegate*> delegate) = 0;
|
||||
|
||||
void updateDate(TimeId newDate);
|
||||
[[nodiscard]] bool canUpdateDate() const;
|
||||
|
||||
virtual ~HistoryItem();
|
||||
|
||||
MsgId id;
|
||||
|
||||
@@ -695,7 +695,7 @@ void HistoryMessage::createComponentsHelper(
|
||||
if (flags & MTPDmessage::Flag::f_reply_to_msg_id) config.replyTo = replyTo;
|
||||
if (flags & MTPDmessage::Flag::f_reply_markup) config.mtpMarkup = &markup;
|
||||
if (flags & MTPDmessage::Flag::f_post_author) config.author = postAuthor;
|
||||
if (isPost()) config.viewsCount = 1;
|
||||
if (flags & MTPDmessage::Flag::f_views) config.viewsCount = 1;
|
||||
|
||||
createComponents(config);
|
||||
}
|
||||
|
||||
@@ -4475,10 +4475,7 @@ bool HistoryWidget::canSendFiles(not_null<const QMimeData*> data) const {
|
||||
} else if (data->hasImage()) {
|
||||
return true;
|
||||
} else if (const auto urls = data->urls(); !urls.empty()) {
|
||||
if (ranges::find_if(
|
||||
urls,
|
||||
[](const QUrl &url) { return !url.isLocalFile(); }
|
||||
) == urls.end()) {
|
||||
if (ranges::all_of(urls, &QUrl::isLocalFile)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -4680,15 +4677,7 @@ void HistoryWidget::sendFileConfirmed(
|
||||
}
|
||||
const auto channelPost = peer->isChannel() && !peer->isMegagroup();
|
||||
const auto silentPost = file->to.options.silent;
|
||||
if (channelPost) {
|
||||
flags |= MTPDmessage::Flag::f_views;
|
||||
flags |= MTPDmessage::Flag::f_post;
|
||||
}
|
||||
if (!channelPost) {
|
||||
flags |= MTPDmessage::Flag::f_from_id;
|
||||
} else if (peer->asChannel()->addsSignature()) {
|
||||
flags |= MTPDmessage::Flag::f_post_author;
|
||||
}
|
||||
Api::FillMessagePostFlags(action, peer, flags);
|
||||
if (silentPost) {
|
||||
flags |= MTPDmessage::Flag::f_silent;
|
||||
}
|
||||
|
||||
@@ -110,6 +110,10 @@ rpl::producer<> ComposeControls::attachRequests() const {
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeControls::setMimeDataHook(MimeDataHook hook) {
|
||||
_field->setMimeDataHook(std::move(hook));
|
||||
}
|
||||
|
||||
rpl::producer<not_null<DocumentData*>> ComposeControls::fileChosen() const {
|
||||
return _fileChosen.events();
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "base/unique_qptr.h"
|
||||
#include "ui/rp_widget.h"
|
||||
#include "ui/effects/animations.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
#include "chat_helpers/tabbed_selector.h"
|
||||
|
||||
class History;
|
||||
@@ -31,7 +32,6 @@ namespace Ui {
|
||||
class SendButton;
|
||||
class IconButton;
|
||||
class EmojiButton;
|
||||
class InputField;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Main {
|
||||
@@ -76,6 +76,11 @@ public:
|
||||
[[nodiscard]] auto inlineResultChosen() const
|
||||
-> rpl::producer<ChatHelpers::TabbedSelector::InlineChosen>;
|
||||
|
||||
using MimeDataHook = Fn<bool(
|
||||
not_null<const QMimeData*> data,
|
||||
Ui::InputField::MimeAction action)>;
|
||||
void setMimeDataHook(MimeDataHook hook);
|
||||
|
||||
bool pushTabbedSelectorToThirdSection(
|
||||
not_null<PeerData*> peer,
|
||||
const Window::SectionShow ¶ms);
|
||||
|
||||
@@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "history/history_item.h"
|
||||
#include "history/history_message.h"
|
||||
#include "history/history_item_text.h"
|
||||
#include "history/view/history_view_schedule_box.h"
|
||||
#include "history/view/media/history_view_media.h"
|
||||
#include "history/view/media/history_view_web_page.h"
|
||||
#include "ui/widgets/popup_menu.h"
|
||||
@@ -29,6 +30,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "data/data_groups.h"
|
||||
#include "data/data_channel.h"
|
||||
#include "data/data_file_origin.h"
|
||||
#include "data/data_scheduled_messages.h"
|
||||
#include "core/file_utilities.h"
|
||||
#include "base/platform/base_platform_info.h"
|
||||
#include "window/window_peer_menu.h"
|
||||
@@ -61,6 +63,14 @@ constexpr auto kExportLocalTimeout = crl::time(1000);
|
||||
// }
|
||||
//}
|
||||
|
||||
MsgId ItemIdAcrossData(not_null<HistoryItem*> item) {
|
||||
if (!item->isScheduled()) {
|
||||
return item->id;
|
||||
}
|
||||
const auto session = &item->history()->session();
|
||||
return session->data().scheduledMessages().lookupId(item);
|
||||
}
|
||||
|
||||
void SavePhotoToFile(not_null<PhotoData*> photo) {
|
||||
if (photo->isNull() || !photo->loaded()) {
|
||||
return;
|
||||
@@ -385,6 +395,49 @@ bool AddSendNowMessageAction(
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AddRescheduleMessageAction(
|
||||
not_null<Ui::PopupMenu*> menu,
|
||||
const ContextMenuRequest &request) {
|
||||
const auto item = request.item;
|
||||
if (!item || item->isSending() || !request.selectedItems.empty()) {
|
||||
return false;
|
||||
}
|
||||
const auto peer = item->history()->peer;
|
||||
if (const auto channel = peer->asChannel()) {
|
||||
if (!channel->canEditMessages()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
const auto owner = &item->history()->owner();
|
||||
const auto itemId = item->fullId();
|
||||
menu->addAction(tr::lng_context_reschedule(tr::now), [=] {
|
||||
const auto item = owner->message(itemId);
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
const auto callback = [=](Api::SendOptions options) {
|
||||
item->history()->session().api().rescheduleMessage(item, options);
|
||||
};
|
||||
|
||||
const auto sendMenuType = !peer
|
||||
? SendMenuType::Disabled
|
||||
: peer->isSelf()
|
||||
? SendMenuType::Reminder
|
||||
: HistoryView::CanScheduleUntilOnline(peer)
|
||||
? SendMenuType::ScheduledToUser
|
||||
: SendMenuType::Scheduled;
|
||||
|
||||
Ui::show(
|
||||
HistoryView::PrepareScheduleBox(
|
||||
&request.navigation->session(),
|
||||
sendMenuType,
|
||||
callback,
|
||||
item->date() + 600),
|
||||
Ui::LayerOption::KeepOther);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
void AddSendNowAction(
|
||||
not_null<Ui::PopupMenu*> menu,
|
||||
const ContextMenuRequest &request,
|
||||
@@ -436,7 +489,8 @@ bool AddDeleteMessageAction(
|
||||
if (asGroup) {
|
||||
if (const auto group = owner->groups().find(item)) {
|
||||
if (ranges::find_if(group->items, [](auto item) {
|
||||
return !IsServerMsgId(item->id) || !item->canDelete();
|
||||
const auto id = ItemIdAcrossData(item);
|
||||
return !IsServerMsgId(id) || !item->canDelete();
|
||||
}) != end(group->items)) {
|
||||
return false;
|
||||
}
|
||||
@@ -495,7 +549,9 @@ bool AddSelectMessageAction(
|
||||
const auto item = request.item;
|
||||
if (request.overSelection && !request.selectedItems.empty()) {
|
||||
return false;
|
||||
} else if (!item || !IsServerMsgId(item->id) || item->serviceMsg()) {
|
||||
} else if (!item
|
||||
|| !IsServerMsgId(ItemIdAcrossData(item))
|
||||
|| item->serviceMsg()) {
|
||||
return false;
|
||||
}
|
||||
const auto owner = &item->history()->owner();
|
||||
@@ -531,6 +587,7 @@ void AddMessageActions(
|
||||
AddSendNowAction(menu, request, list);
|
||||
AddDeleteAction(menu, request, list);
|
||||
AddSelectionAction(menu, request, list);
|
||||
AddRescheduleMessageAction(menu, request);
|
||||
}
|
||||
|
||||
void AddCopyLinkAction(
|
||||
|
||||
@@ -937,6 +937,7 @@ void ListWidget::selectItemAsGroup(not_null<HistoryItem*> item) {
|
||||
item,
|
||||
SelectAction::Select);
|
||||
pushSelectedItems();
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1763,6 +1763,9 @@ void Message::fromNameUpdated(int width) const {
|
||||
}
|
||||
|
||||
TextSelection Message::skipTextSelection(TextSelection selection) const {
|
||||
if (selection.from == 0xFFFF) {
|
||||
return selection;
|
||||
}
|
||||
return HistoryView::UnshiftItemSelection(selection, message()->_text);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,12 +29,13 @@ template <typename Guard, typename Submit>
|
||||
[[nodiscard]] object_ptr<Ui::GenericBox> PrepareScheduleBox(
|
||||
Guard &&guard,
|
||||
SendMenuType type,
|
||||
Submit &&submit) {
|
||||
Submit &&submit,
|
||||
TimeId scheduleTime = DefaultScheduleTime()) {
|
||||
return Box(
|
||||
ScheduleBox,
|
||||
type,
|
||||
crl::guard(std::forward<Guard>(guard), std::forward<Submit>(submit)),
|
||||
DefaultScheduleTime());
|
||||
scheduleTime);
|
||||
}
|
||||
|
||||
} // namespace HistoryView
|
||||
|
||||
@@ -44,6 +44,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "styles/style_info.h"
|
||||
#include "styles/style_boxes.h"
|
||||
|
||||
#include <QtCore/QMimeData>
|
||||
|
||||
namespace HistoryView {
|
||||
namespace {
|
||||
|
||||
@@ -55,6 +57,17 @@ void ShowErrorToast(const QString &text) {
|
||||
});
|
||||
}
|
||||
|
||||
bool CanSendFiles(not_null<const QMimeData*> data) {
|
||||
if (data->hasImage()) {
|
||||
return true;
|
||||
} else if (const auto urls = data->urls(); !urls.empty()) {
|
||||
if (ranges::all_of(urls, &QUrl::isLocalFile)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
object_ptr<Window::SectionWidget> ScheduledMemento::createWidget(
|
||||
@@ -165,6 +178,20 @@ void ScheduledWidget::setupComposeControls() {
|
||||
ChatHelpers::TabbedSelector::InlineChosen chosen) {
|
||||
sendInlineResult(chosen.result, chosen.bot);
|
||||
}, lifetime());
|
||||
|
||||
_composeControls->setMimeDataHook([=](
|
||||
not_null<const QMimeData*> data,
|
||||
Ui::InputField::MimeAction action) {
|
||||
if (action == Ui::InputField::MimeAction::Check) {
|
||||
return CanSendFiles(data);
|
||||
} else if (action == Ui::InputField::MimeAction::Insert) {
|
||||
return confirmSendingFiles(
|
||||
data,
|
||||
CompressConfirm::Auto,
|
||||
data->text());
|
||||
}
|
||||
Unexpected("action in MimeData hook.");
|
||||
});
|
||||
}
|
||||
|
||||
void ScheduledWidget::chooseAttach() {
|
||||
@@ -214,6 +241,43 @@ void ScheduledWidget::chooseAttach() {
|
||||
}), nullptr);
|
||||
}
|
||||
|
||||
bool ScheduledWidget::confirmSendingFiles(
|
||||
not_null<const QMimeData*> data,
|
||||
CompressConfirm compressed,
|
||||
const QString &insertTextOnCancel) {
|
||||
const auto hasImage = data->hasImage();
|
||||
|
||||
if (const auto urls = data->urls(); !urls.empty()) {
|
||||
auto list = Storage::PrepareMediaList(
|
||||
urls,
|
||||
st::sendMediaPreviewSize);
|
||||
if (list.error != Storage::PreparedList::Error::NonLocalUrl) {
|
||||
if (list.error == Storage::PreparedList::Error::None
|
||||
|| !hasImage) {
|
||||
const auto emptyTextOnCancel = QString();
|
||||
confirmSendingFiles(
|
||||
std::move(list),
|
||||
compressed,
|
||||
emptyTextOnCancel);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasImage) {
|
||||
auto image = qvariant_cast<QImage>(data->imageData());
|
||||
if (!image.isNull()) {
|
||||
confirmSendingFiles(
|
||||
std::move(image),
|
||||
QByteArray(),
|
||||
compressed,
|
||||
insertTextOnCancel);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ScheduledWidget::confirmSendingFiles(
|
||||
Storage::PreparedList &&list,
|
||||
CompressConfirm compressed,
|
||||
@@ -834,6 +898,10 @@ void ScheduledWidget::listScrollTo(int top) {
|
||||
}
|
||||
|
||||
void ScheduledWidget::listCancelRequest() {
|
||||
if (_inner && !_inner->getSelectedItems().empty()) {
|
||||
clearSelected();
|
||||
return;
|
||||
}
|
||||
controller()->showBackFromStack();
|
||||
}
|
||||
|
||||
|
||||
@@ -159,6 +159,10 @@ private:
|
||||
Storage::PreparedList &&list,
|
||||
CompressConfirm compressed,
|
||||
const QString &insertTextOnCancel = QString());
|
||||
bool confirmSendingFiles(
|
||||
not_null<const QMimeData*> data,
|
||||
CompressConfirm compressed,
|
||||
const QString &insertTextOnCancel = QString());
|
||||
bool showSendingFilesError(const Storage::PreparedList &list) const;
|
||||
void uploadFilesAfterConfirmation(
|
||||
Storage::PreparedList &&list,
|
||||
|
||||
@@ -86,14 +86,14 @@ void EnumeratePlaybackDevices() {
|
||||
Assert(devices != nullptr);
|
||||
while (*devices != 0) {
|
||||
auto deviceName8Bit = QByteArray(devices);
|
||||
auto deviceName = QString::fromLocal8Bit(deviceName8Bit);
|
||||
auto deviceName = QString::fromUtf8(deviceName8Bit);
|
||||
deviceNames.append(deviceName);
|
||||
devices += deviceName8Bit.size() + 1;
|
||||
}
|
||||
LOG(("Audio Playback Devices: %1").arg(deviceNames.join(';')));
|
||||
|
||||
if (auto device = alcGetString(nullptr, ALC_DEFAULT_ALL_DEVICES_SPECIFIER)) {
|
||||
LOG(("Audio Playback Default Device: %1").arg(QString::fromLocal8Bit(device)));
|
||||
LOG(("Audio Playback Default Device: %1").arg(QString::fromUtf8(device)));
|
||||
} else {
|
||||
LOG(("Audio Playback Default Device: (null)"));
|
||||
}
|
||||
@@ -105,14 +105,14 @@ void EnumerateCaptureDevices() {
|
||||
Assert(devices != nullptr);
|
||||
while (*devices != 0) {
|
||||
auto deviceName8Bit = QByteArray(devices);
|
||||
auto deviceName = QString::fromLocal8Bit(deviceName8Bit);
|
||||
auto deviceName = QString::fromUtf8(deviceName8Bit);
|
||||
deviceNames.append(deviceName);
|
||||
devices += deviceName8Bit.size() + 1;
|
||||
}
|
||||
LOG(("Audio Capture Devices: %1").arg(deviceNames.join(';')));
|
||||
|
||||
if (auto device = alcGetString(nullptr, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER)) {
|
||||
LOG(("Audio Capture Default Device: %1").arg(QString::fromLocal8Bit(device)));
|
||||
LOG(("Audio Capture Default Device: %1").arg(QString::fromUtf8(device)));
|
||||
} else {
|
||||
LOG(("Audio Capture Default Device: (null)"));
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ Instance::Instance() : _inner(new Inner(&_thread)) {
|
||||
void Instance::check() {
|
||||
_available = false;
|
||||
if (auto device = alcGetString(0, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER)) {
|
||||
if (!QString::fromLocal8Bit(device).isEmpty()) {
|
||||
if (!QString::fromUtf8(device).isEmpty()) {
|
||||
_available = true;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -271,6 +271,14 @@ bool IsGtkFileDialogForced() {
|
||||
#endif // !TDESKTOP_FORCE_GTK_FILE_DIALOG
|
||||
}
|
||||
|
||||
bool IsQtPluginsBundled() {
|
||||
#ifdef DESKTOP_APP_USE_PACKAGED_LAZY
|
||||
return true;
|
||||
#else // DESKTOP_APP_USE_PACKAGED_LAZY
|
||||
return false;
|
||||
#endif // !DESKTOP_APP_USE_PACKAGED_LAZY
|
||||
}
|
||||
|
||||
bool IsXDGDesktopPortalPresent() {
|
||||
#ifdef TDESKTOP_DISABLE_DBUS_INTEGRATION
|
||||
static const auto XDGDesktopPortalPresent = false;
|
||||
@@ -633,14 +641,16 @@ void start() {
|
||||
if(IsStaticBinary()
|
||||
|| InAppImage()
|
||||
|| InSandbox()
|
||||
|| InSnap()) {
|
||||
|| InSnap()
|
||||
|| IsQtPluginsBundled()) {
|
||||
qputenv("QT_WAYLAND_DECORATION", "material");
|
||||
}
|
||||
|
||||
if(IsStaticBinary()
|
||||
|| InAppImage()
|
||||
|| InSnap()
|
||||
|| IsGtkFileDialogForced()) {
|
||||
|| IsGtkFileDialogForced()
|
||||
|| IsQtPluginsBundled()) {
|
||||
LOG(("Checking for XDG Desktop Portal..."));
|
||||
// this can give us a chance to use a proper file dialog for current session
|
||||
if (IsXDGDesktopPortalPresent()) {
|
||||
|
||||
@@ -25,6 +25,7 @@ bool InSnap();
|
||||
bool InAppImage();
|
||||
bool IsStaticBinary();
|
||||
bool IsGtkFileDialogForced();
|
||||
bool IsQtPluginsBundled();
|
||||
|
||||
bool IsXDGDesktopPortalPresent();
|
||||
bool UseXDGDesktopPortal();
|
||||
|
||||
@@ -34,7 +34,7 @@ void queryDoNotDisturbState() {
|
||||
|
||||
auto userDefaults = [NSUserDefaults alloc];
|
||||
if ([userDefaults respondsToSelector:@selector(initWithSuiteName:)]) {
|
||||
id userDefaultsValue = [[[NSUserDefaults alloc] initWithSuiteName:@"com.apple.notificationcenterui_test"] objectForKey:@"doNotDisturb"];
|
||||
id userDefaultsValue = [[[NSUserDefaults alloc] initWithSuiteName:@"com.apple.notificationcenterui"] objectForKey:@"doNotDisturb"];
|
||||
DoNotDisturbEnabled = ([userDefaultsValue boolValue] == YES);
|
||||
} else {
|
||||
DoNotDisturbEnabled = false;
|
||||
|
||||
@@ -53,6 +53,7 @@ Q_IMPORT_PLUGIN(QWaylandMaterialDecorationPlugin)
|
||||
Q_IMPORT_PLUGIN(NimfInputContextPlugin)
|
||||
#ifndef TDESKTOP_DISABLE_DBUS_INTEGRATION
|
||||
Q_IMPORT_PLUGIN(QFcitxPlatformInputContextPlugin)
|
||||
Q_IMPORT_PLUGIN(QFcitx5PlatformInputContextPlugin)
|
||||
Q_IMPORT_PLUGIN(QHimePlatformInputContextPlugin)
|
||||
#endif // !TDESKTOP_DISABLE_DBUS_INTEGRATION
|
||||
#endif // !DESKTOP_APP_USE_PACKAGED || DESKTOP_APP_USE_PACKAGED_LAZY
|
||||
|
||||
@@ -37,6 +37,12 @@ namespace {
|
||||
constexpr auto kMinimalAlertDelay = crl::time(500);
|
||||
constexpr auto kWaitingForAllGroupedDelay = crl::time(1000);
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
constexpr auto kSystemAlertDuration = crl::time(1000);
|
||||
#else // !Q_OS_MAC
|
||||
constexpr auto kSystemAlertDuration = crl::time(0);
|
||||
#endif // Q_OS_MAC
|
||||
|
||||
} // namespace
|
||||
|
||||
System::System(not_null<Main::Session*> session)
|
||||
@@ -295,7 +301,7 @@ void System::showNext() {
|
||||
if (Global::FlashBounceNotify() && !Platform::Notifications::SkipFlashBounce()) {
|
||||
if (const auto widget = App::wnd()) {
|
||||
if (const auto window = widget->windowHandle()) {
|
||||
window->alert(0);
|
||||
window->alert(kSystemAlertDuration);
|
||||
// (window, SLOT(_q_clearAlert())); in the future.
|
||||
}
|
||||
}
|
||||
|
||||
2
Telegram/ThirdParty/fcitx5-qt
vendored
2
Telegram/ThirdParty/fcitx5-qt
vendored
Submodule Telegram/ThirdParty/fcitx5-qt updated: 7561f994a7...b7bdd8aec2
@@ -1,7 +1,7 @@
|
||||
AppVersion 2001006
|
||||
AppVersion 2001007
|
||||
AppVersionStrMajor 2.1
|
||||
AppVersionStrSmall 2.1.6
|
||||
AppVersionStr 2.1.6
|
||||
AppVersionStrSmall 2.1.7
|
||||
AppVersionStr 2.1.7
|
||||
BetaChannel 0
|
||||
AlphaVersion 0
|
||||
AppVersionOriginal 2.1.6
|
||||
AppVersionOriginal 2.1.7
|
||||
|
||||
Submodule Telegram/lib_ui updated: 8e2cfbf303...db2a1279d6
@@ -1,3 +1,7 @@
|
||||
2.1.7 (24.05.20)
|
||||
|
||||
- Fix the Fcitx input method plugin.
|
||||
|
||||
2.1.6 (14.05.20)
|
||||
|
||||
- Bug fixes and other minor improvements.
|
||||
|
||||
2
cmake
2
cmake
Submodule cmake updated: 4ea254886e...f4271f2cd4
Reference in New Issue
Block a user