Compare commits

..

24 Commits

Author SHA1 Message Date
John Preston
87895466dc Version 2.5.8: Fix dump_syms invocation. 2021-01-30 00:22:40 +04:00
John Preston
72f8d3f485 Version 2.5.8: Fix dump_syms invocation. 2021-01-30 00:05:49 +04:00
John Preston
5092d8fe63 Version 2.5.8: Fix invite link export if absent. 2021-01-29 23:49:20 +04:00
John Preston
01110a29ad Version 2.5.8: Fix PopupMenu min width. 2021-01-29 22:51:11 +04:00
John Preston
e8c3df2abb Version 2.5.8.
- Fix OpenAL device closing in calls and voice chats.
- Fix video chat rotation when calling from iOS.
- Fix scheduling messages without sound.
- Remove redundant Cancel button in ScheduleBox.
2021-01-29 22:10:13 +04:00
John Preston
db89de96a9 Fix loading of voice chats participants. 2021-01-29 22:07:32 +04:00
John Preston
1eacaec66b Fix build. 2021-01-29 21:07:09 +04:00
Ilya Fedin
10f58c2ac7 Add debug logging about media viewer screen 2021-01-29 20:58:35 +04:00
John Preston
e0680fc2a5 Fix voice chat menu for admins editing admins. 2021-01-29 20:56:56 +04:00
23rd
fba7bd7807 Fixed speaker display when participant is muted by me in group calls. 2021-01-29 18:24:52 +03:00
23rd
6c0553f4d6 Returned default icon color for songs without cover art.
Related commit: 9b9531d279.
2021-01-29 18:24:52 +03:00
John Preston
5d4e5ed527 Allow changing my own volume in voice chat. 2021-01-29 19:19:50 +04:00
John Preston
2559c5d6f4 Allow other admins to mute me in voice chats. 2021-01-29 19:19:50 +04:00
John Preston
8d85dd7c19 Fix scheduling messages without sound. 2021-01-29 18:05:13 +04:00
John Preston
8f0e23bb25 Improve editing messages with link previews.
Now preview state can be one of (allowed, cancelled, empty-in-edit).

In case of editing a message without preview we set the state to
empty-in-edit and it changes to allowed if the links in the message
are changed somehow.

That way we don't need to cancel the preview when editing a message
with a cancelled preview and at the same time adding a link to
a message that had no preview in the first place will add a preview.
2021-01-29 15:27:17 +04:00
John Preston
fc4ed2ff91 Fix repainting of non-first file album item. 2021-01-29 14:38:07 +04:00
John Preston
fcdc39c5f9 Add external_xxhash dependency to Telegram project. 2021-01-29 13:56:15 +04:00
John Preston
1ec6b4313d Remove redundant Cancel button in ScheduleBox. 2021-01-29 13:56:15 +04:00
Ilya Fedin
9be65f8812 Fix missing libraries warning in snap 2021-01-29 13:50:29 +04:00
Ilya Fedin
30468746ad Build Qt in snap to get newer version than in Ubuntu 2021-01-29 13:03:29 +04:00
John Preston
7947af665c Skip notifications from imported messages. 2021-01-28 22:19:58 +04:00
Ilya Fedin
160cd975ce Another attempt to implement shadows on Wayland
Works only with patched Qt
2021-01-28 22:19:34 +04:00
John Preston
c13d0e96ef Fix build. 2021-01-28 19:58:35 +04:00
John Preston
fbf4f912c6 Fix OpenAL device closing in calls and voice chats.
Also add 64 bit Windows info in crash platform string.
2021-01-28 19:31:54 +04:00
48 changed files with 586 additions and 213 deletions

View File

@@ -67,6 +67,7 @@ PRIVATE
desktop-app::external_auto_updates
desktop-app::external_openssl
desktop-app::external_openal
desktop-app::external_xxhash
)
if (LINUX)

View File

@@ -9,7 +9,7 @@
<Identity Name="TelegramMessengerLLP.TelegramDesktop"
ProcessorArchitecture="ARCHITECTURE"
Publisher="CN=536BC709-8EE1-4478-AF22-F0F0F26FF64A"
Version="2.5.7.0" />
Version="2.5.8.0" />
<Properties>
<DisplayName>Telegram Desktop</DisplayName>
<PublisherDisplayName>Telegram FZ-LLC</PublisherDisplayName>

View File

@@ -44,8 +44,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico"
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 2,5,7,0
PRODUCTVERSION 2,5,7,0
FILEVERSION 2,5,8,0
PRODUCTVERSION 2,5,8,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.5.7.0"
VALUE "FileVersion", "2.5.8.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2021"
VALUE "ProductName", "Telegram Desktop"
VALUE "ProductVersion", "2.5.7.0"
VALUE "ProductVersion", "2.5.8.0"
END
END
BLOCK "VarFileInfo"

View File

@@ -35,8 +35,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 2,5,7,0
PRODUCTVERSION 2,5,7,0
FILEVERSION 2,5,8,0
PRODUCTVERSION 2,5,8,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.5.7.0"
VALUE "FileVersion", "2.5.8.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2021"
VALUE "ProductName", "Telegram Desktop"
VALUE "ProductVersion", "2.5.7.0"
VALUE "ProductVersion", "2.5.8.0"
END
END
BLOCK "VarFileInfo"

View File

@@ -2449,7 +2449,7 @@ void ApiWrap::saveDraftsToCloud() {
auto flags = MTPmessages_SaveDraft::Flags(0);
auto &textWithTags = cloudDraft->textWithTags;
if (cloudDraft->previewCancelled) {
if (cloudDraft->previewState != Data::PreviewState::Allowed) {
flags |= MTPmessages_SaveDraft::Flag::f_no_webpage;
}
if (cloudDraft->msgId) {

View File

@@ -88,8 +88,10 @@ void AboutBox::resizeEvent(QResizeEvent *e) {
void AboutBox::showVersionHistory() {
if (cRealAlphaVersion()) {
auto url = qsl("https://tdesktop.com/");
if (Platform::IsWindows()) {
if (Platform::IsWindows32Bit()) {
url += qsl("win/%1.zip");
} else if (Platform::IsWindows64Bit()) {
url += qsl("win64/%1.zip");
} else if (Platform::IsOSXBuild()) {
url += qsl("osx/%1.zip");
} else if (Platform::IsMac()) {
@@ -143,5 +145,8 @@ QString currentVersionText() {
} else if (AppBetaVersion) {
result += " beta";
}
if (Platform::IsWindows64Bit()) {
result += " x64";
}
return result;
}

View File

@@ -963,7 +963,7 @@ void EditCaptionBox::paintEvent(QPaintEvent *e) {
}
const auto icon = &(_isAudio
? st::historyFileSongPlay
? (_thumbw ? st::historyFileSongPlay : st::historyFileInPlay)
: _isImage
? st::historyFileInImage
: st::historyFileInDocument);

View File

@@ -120,7 +120,7 @@ private:
void fillPrivaciesButtons(
not_null<Ui::VerticalLayout*> parent,
std::optional<Privacy> savedValue = std::nullopt);
Privacy savedValue);
void addRoundButton(
not_null<Ui::VerticalLayout*> container,
Privacy value,
@@ -195,6 +195,12 @@ void Controller::createContent() {
if (_controls.privacy->value() == Privacy::NoUsername) {
checkUsernameAvailability();
}
_controls.inviteLinkWrap->toggle(
(_privacySavedValue != Privacy::HasUsername),
anim::type::instant);
_controls.usernameWrap->toggle(
(_privacySavedValue == Privacy::HasUsername),
anim::type::instant);
}
void Controller::addRoundButton(
@@ -222,7 +228,7 @@ void Controller::addRoundButton(
void Controller::fillPrivaciesButtons(
not_null<Ui::VerticalLayout*> parent,
std::optional<Privacy> savedValue) {
Privacy savedValue) {
const auto canEditUsername = [&] {
if (const auto chat = _peer->asChat()) {
return chat->canEditUsername();
@@ -245,8 +251,7 @@ void Controller::fillPrivaciesButtons(
const auto isPublic = _peer->isChannel()
&& _peer->asChannel()->hasUsername();
_controls.privacy = std::make_shared<Ui::RadioenumGroup<Privacy>>(
savedValue.value_or(
isPublic ? Privacy::HasUsername : Privacy::NoUsername));
savedValue);
addRoundButton(
container,
@@ -543,7 +548,8 @@ object_ptr<Ui::RpWidget> Controller::createInviteLinkBlock() {
using namespace Settings;
AddSkip(container);
AddSubsectionTitle(container, tr::lng_create_permanent_link_title());
AddSubsectionTitle(container, tr::lng_create_invite_link_title());
// tr::lng_create_permanent_link_title()); // #TODO links
AddPermanentLinkBlock(container, _peer);
AddSkip(container);
@@ -554,6 +560,16 @@ object_ptr<Ui::RpWidget> Controller::createInviteLinkBlock() {
? tr::lng_group_invite_about_permanent_group()
: tr::lng_group_invite_about_permanent_channel()));
if (_peer->wasFullUpdated()) {
const auto link = _peer->isChat()
? _peer->asChat()->inviteLink()
: _peer->asChannel()->inviteLink();
if (link.isEmpty()) {
// #TODO links remove this auto-export link.
_peer->session().api().inviteLinks().revokePermanent(_peer);
}
}
return result;
}

View File

@@ -409,11 +409,11 @@ void GroupCall::applyParticipantLocally(
const auto mutedCount = 0/*participant->mutedCount*/;
using Flag = MTPDgroupCallParticipant::Flag;
const auto flags = (canSelfUnmute ? Flag::f_can_self_unmute : Flag(0))
| (volume.has_value() ? Flag::f_volume : Flag(0))
| Flag::f_volume // Without flag the volume is reset to 100%.
| (participant->lastActive ? Flag::f_active_date : Flag(0))
| (!mute
? Flag(0)
: user->canManageGroupCall()
: _peer->canManageGroupCall()
? Flag::f_muted
: Flag::f_muted_by_you);
_peer->groupCall()->applyUpdateChecked(
@@ -631,6 +631,8 @@ void GroupCall::handleUpdate(const MTPDupdateGroupCallParticipants &data) {
setMuted(MuteState::ForceMuted);
} else if (muted() == MuteState::ForceMuted) {
setMuted(MuteState::Muted);
} else if (data.is_muted() && muted() != MuteState::Muted) {
setMuted(MuteState::Muted);
}
});
}

View File

@@ -295,6 +295,7 @@ private:
void addMuteActionsToContextMenu(
not_null<Ui::PopupMenu*> menu,
not_null<UserData*> user,
bool userIsCallAdmin,
not_null<Row*> row);
void setupListChangeViewers(not_null<GroupCall*> call);
void subscribeToChanges(not_null<Data::GroupCall*> real);
@@ -660,13 +661,13 @@ void Row::paintStatusText(
int availableWidth,
int outerWidth,
bool selected) {
p.save();
const auto &font = st::normalFont;
paintStatusIcon(p, st, font, selected);
const auto translatedWidth = statusIconWidth();
p.translate(translatedWidth, 0);
const auto guard = gsl::finally([&] { p.restore(); });
if (_state != State::Invited && _state != State::MutedByMe) {
p.save();
paintStatusIcon(p, st, font, selected);
const auto translatedWidth = statusIconWidth();
p.translate(translatedWidth, 0);
const auto guard = gsl::finally([&] { p.restore(); });
PeerListRow::paintStatusText(
p,
st,
@@ -1275,10 +1276,11 @@ base::unique_qptr<Ui::PopupMenu> MembersController::createRowContextMenu(
not_null<PeerListRow*> row) {
Expects(row->peer()->isUser());
if (row->peer()->isSelf()) {
const auto real = static_cast<Row*>(row.get());
if (row->peer()->isSelf()
&& (!_peer->canManageGroupCall() || !real->ssrc())) {
return nullptr;
}
const auto real = static_cast<Row*>(row.get());
const auto user = row->peer()->asUser();
auto result = base::make_unique_q<Ui::PopupMenu>(
parent,
@@ -1355,30 +1357,32 @@ base::unique_qptr<Ui::PopupMenu> MembersController::createRowContextMenu(
});
if (real->ssrc() != 0) {
addMuteActionsToContextMenu(result, user, real);
addMuteActionsToContextMenu(result, user, admin, real);
}
result->addAction(
tr::lng_context_view_profile(tr::now),
showProfile);
result->addAction(
tr::lng_context_send_message(tr::now),
showHistory);
const auto canKick = [&] {
if (static_cast<Row*>(row.get())->state() == Row::State::Invited) {
return false;
} else if (const auto chat = _peer->asChat()) {
return chat->amCreator()
|| (chat->canBanMembers() && !chat->admins.contains(user));
} else if (const auto group = _peer->asMegagroup()) {
return group->canRestrictUser(user);
}
return false;
}();
if (canKick) {
if (!user->isSelf()) {
result->addAction(
tr::lng_context_remove_from_group(tr::now),
removeFromGroup);
tr::lng_context_view_profile(tr::now),
showProfile);
result->addAction(
tr::lng_context_send_message(tr::now),
showHistory);
const auto canKick = [&] {
if (static_cast<Row*>(row.get())->state() == Row::State::Invited) {
return false;
} else if (const auto chat = _peer->asChat()) {
return chat->amCreator()
|| (chat->canBanMembers() && !chat->admins.contains(user));
} else if (const auto group = _peer->asMegagroup()) {
return group->canRestrictUser(user);
}
return false;
}();
if (canKick) {
result->addAction(
tr::lng_context_remove_from_group(tr::now),
removeFromGroup);
}
}
return result;
}
@@ -1386,6 +1390,7 @@ base::unique_qptr<Ui::PopupMenu> MembersController::createRowContextMenu(
void MembersController::addMuteActionsToContextMenu(
not_null<Ui::PopupMenu*> menu,
not_null<UserData*> user,
bool userIsCallAdmin,
not_null<Row*> row) {
const auto muteString = [=] {
return (_peer->canManageGroupCall()
@@ -1422,7 +1427,7 @@ void MembersController::addMuteActionsToContextMenu(
auto mutesFromVolume = rpl::never<bool>() | rpl::type_erased();
if (!isMuted) {
if (!isMuted || user->isSelf()) {
const auto call = _call.get();
auto otherParticipantStateValue = call
? call->otherParticipantStateValue(
@@ -1443,12 +1448,21 @@ void MembersController::addMuteActionsToContextMenu(
volumeItem->toggleMuteRequests(
) | rpl::start_with_next([=](bool muted) {
if (muted) {
// Slider value is changed after the callback is called.
// To capture good state inside the slider frame we postpone.
crl::on_main(menu, [=] {
menu->hideMenu();
});
}
toggleMute(muted, false);
}, volumeItem->lifetime());
volumeItem->toggleMuteLocallyRequests(
) | rpl::start_with_next([=](bool muted) {
toggleMute(muted, true);
if (!user->isSelf()) {
toggleMute(muted, true);
}
}, volumeItem->lifetime());
volumeItem->changeVolumeRequests(
@@ -1458,14 +1472,20 @@ void MembersController::addMuteActionsToContextMenu(
volumeItem->changeVolumeLocallyRequests(
) | rpl::start_with_next([=](int volume) {
changeVolume(volume, true);
if (!user->isSelf()) {
changeVolume(volume, true);
}
}, volumeItem->lifetime());
menu->addAction(std::move(volumeItem));
};
const auto muteAction = [&]() -> QAction* {
if (muteState == Row::State::Invited) {
if (muteState == Row::State::Invited
|| user->isSelf()
|| (muteState == Row::State::Muted
&& userIsCallAdmin
&& _peer->canManageGroupCall())) {
return nullptr;
}
auto callback = [=] {
@@ -1635,6 +1655,13 @@ void GroupMembers::setupList() {
resizeToList();
}, _list->lifetime());
rpl::combine(
_scroll->scrollTopValue(),
_scroll->heightValue()
) | rpl::start_with_next([=](int scrollTop, int scrollHeight) {
_list->setVisibleTopBottom(scrollTop, scrollTop + scrollHeight);
}, _scroll->lifetime());
updateControlsGeometry();
}
@@ -1736,12 +1763,6 @@ void GroupMembers::setupFakeRoundCorners() {
}, lifetime());
}
void GroupMembers::visibleTopBottomUpdated(
int visibleTop,
int visibleBottom) {
setChildVisibleTopBottom(_list, visibleTop, visibleBottom);
}
void GroupMembers::peerListSetTitle(rpl::producer<QString> title) {
}

View File

@@ -51,10 +51,6 @@ public:
private:
using ListWidget = PeerListContent;
void visibleTopBottomUpdated(
int visibleTop,
int visibleBottom) override;
void resizeEvent(QResizeEvent *e) override;
// PeerListContentDelegate interface.

View File

@@ -501,6 +501,11 @@ MessageLinksParser::MessageLinksParser(not_null<Ui::InputField*> field)
_field->installEventFilter(this);
}
void MessageLinksParser::parseNow() {
_timer.cancel();
parse();
}
bool MessageLinksParser::eventFilter(QObject *object, QEvent *event) {
if (object == _field) {
if (event->type() == QEvent::KeyPress) {

View File

@@ -71,7 +71,9 @@ class MessageLinksParser : private QObject {
public:
MessageLinksParser(not_null<Ui::InputField*> field);
const rpl::variable<QStringList> &list() const;
void parseNow();
[[nodiscard]] const rpl::variable<QStringList> &list() const;
protected:
bool eventFilter(QObject *object, QEvent *event) override;

View File

@@ -321,9 +321,13 @@ bool DumpCallback(const google_breakpad::MinidumpDescriptor &md, void *context,
QString PlatformString() {
if (Platform::IsWindowsStoreBuild()) {
return qsl("WinStore");
} else if (Platform::IsWindows()) {
return qsl("Windows");
return Platform::IsWindows64Bit()
? qsl("WinStore64Bit")
: qsl("WinStore32Bit");
} else if (Platform::IsWindows32Bit()) {
return qsl("Windows32Bit");
} else if (Platform::IsWindows64Bit()) {
return qsl("Windows64Bit");
} else if (Platform::IsMacStoreBuild()) {
return qsl("MacAppStore");
} else if (Platform::IsOSXBuild()) {

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 = 2005007;
constexpr auto AppVersionStr = "2.5.7";
constexpr auto AppVersion = 2005008;
constexpr auto AppVersionStr = "2.5.8";
constexpr auto AppBetaVersion = false;
constexpr auto AppAlphaVersion = TDESKTOP_ALPHA_VERSION;

View File

@@ -18,32 +18,29 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "storage/localstorage.h"
namespace Data {
namespace {
} // namespace
Draft::Draft(
const TextWithTags &textWithTags,
MsgId msgId,
const MessageCursor &cursor,
bool previewCancelled,
PreviewState previewState,
mtpRequestId saveRequestId)
: textWithTags(textWithTags)
, msgId(msgId)
, cursor(cursor)
, previewCancelled(previewCancelled)
, previewState(previewState)
, saveRequestId(saveRequestId) {
}
Draft::Draft(
not_null<const Ui::InputField*> field,
MsgId msgId,
bool previewCancelled,
PreviewState previewState,
mtpRequestId saveRequestId)
: textWithTags(field->getTextWithTags())
, msgId(msgId)
, cursor(field)
, previewCancelled(previewCancelled) {
, previewState(previewState) {
}
void ApplyPeerCloudDraft(
@@ -66,7 +63,9 @@ void ApplyPeerCloudDraft(
textWithTags,
replyTo,
MessageCursor(QFIXED_MAX, QFIXED_MAX, QFIXED_MAX),
draft.is_no_webpage());
(draft.is_no_webpage()
? Data::PreviewState::Cancelled
: Data::PreviewState::Allowed));
cloudDraft->date = draft.vdate().v;
history->setCloudDraft(std::move(cloudDraft));

View File

@@ -26,25 +26,31 @@ void ClearPeerCloudDraft(
PeerId peerId,
TimeId date);
enum class PreviewState : char {
Allowed,
Cancelled,
EmptyOnEdit,
};
struct Draft {
Draft() = default;
Draft(
const TextWithTags &textWithTags,
MsgId msgId,
const MessageCursor &cursor,
bool previewCancelled,
PreviewState previewState,
mtpRequestId saveRequestId = 0);
Draft(
not_null<const Ui::InputField*> field,
MsgId msgId,
bool previewCancelled,
PreviewState previewState,
mtpRequestId saveRequestId = 0);
TimeId date = 0;
TextWithTags textWithTags;
MsgId msgId = 0; // replyToId for message draft, editMsgId for edit draft
MessageCursor cursor;
bool previewCancelled = false;
PreviewState previewState = PreviewState::Allowed;
mtpRequestId saveRequestId = 0;
};
@@ -144,7 +150,7 @@ inline bool draftsAreEqual(const Draft *a, const Draft *b) {
return (a->textWithTags == b->textWithTags)
&& (a->msgId == b->msgId)
&& (a->previewCancelled == b->previewCancelled);
&& (a->previewState == b->previewState);
}
} // namespace Data

View File

@@ -21,7 +21,7 @@ constexpr auto kMaxItemsInGroup = 10;
Groups::Groups(not_null<Session*> data) : _data(data) {
}
bool Groups::isGrouped(not_null<HistoryItem*> item) const {
bool Groups::isGrouped(not_null<const HistoryItem*> item) const {
if (!item->groupId()) {
return false;
}
@@ -124,7 +124,7 @@ HistoryItemsList::const_iterator Groups::findPositionForItem(
return last;
}
const Group *Groups::find(not_null<HistoryItem*> item) const {
const Group *Groups::find(not_null<const HistoryItem*> item) const {
const auto groupId = item->groupId();
if (!groupId) {
return nullptr;

View File

@@ -22,14 +22,14 @@ class Groups {
public:
Groups(not_null<Session*> data);
bool isGrouped(not_null<HistoryItem*> item) const;
[[nodiscard]] bool isGrouped(not_null<const HistoryItem*> item) const;
void registerMessage(not_null<HistoryItem*> item);
void unregisterMessage(not_null<const HistoryItem*> item);
void refreshMessage(
not_null<HistoryItem*> item,
bool justRefreshViews = false);
const Group *find(not_null<HistoryItem*> item) const;
[[nodiscard]] const Group *find(not_null<const HistoryItem*> item) const;
not_null<HistoryItem*> findItemToEdit(not_null<HistoryItem*> item) const;

View File

@@ -1417,9 +1417,23 @@ rpl::producer<Session::IdChange> Session::itemIdChanged() const {
void Session::requestItemRepaint(not_null<const HistoryItem*> item) {
_itemRepaintRequest.fire_copy(item);
enumerateItemViews(item, [&](not_null<const ViewElement*> view) {
requestViewRepaint(view);
});
auto repaintGroupLeader = false;
auto repaintView = [&](not_null<const ViewElement*> view) {
if (view->isHiddenByGroup()) {
repaintGroupLeader = true;
} else {
requestViewRepaint(view);
}
};
enumerateItemViews(item, repaintView);
if (repaintGroupLeader) {
if (const auto group = groups().find(item)) {
const auto leader = group->items.front();
if (leader != item) {
enumerateItemViews(leader, repaintView);
}
}
}
}
rpl::producer<not_null<const HistoryItem*>> Session::itemRepaintRequest() const {

View File

@@ -215,13 +215,13 @@ void History::createLocalDraftFromCloud() {
draft->textWithTags,
draft->msgId,
draft->cursor,
draft->previewCancelled));
draft->previewState));
existing = localDraft();
} else if (existing != draft) {
existing->textWithTags = draft->textWithTags;
existing->msgId = draft->msgId;
existing->cursor = draft->cursor;
existing->previewCancelled = draft->previewCancelled;
existing->previewState = draft->previewState;
}
existing->date = draft->date;
}
@@ -280,7 +280,7 @@ Data::Draft *History::createCloudDraft(const Data::Draft *fromDraft) {
TextWithTags(),
0,
MessageCursor(),
false));
Data::PreviewState::Allowed));
cloudDraft()->date = TimeId(0);
} else {
auto existing = cloudDraft();
@@ -289,13 +289,13 @@ Data::Draft *History::createCloudDraft(const Data::Draft *fromDraft) {
fromDraft->textWithTags,
fromDraft->msgId,
fromDraft->cursor,
fromDraft->previewCancelled));
fromDraft->previewState));
existing = cloudDraft();
} else if (existing != fromDraft) {
existing->textWithTags = fromDraft->textWithTags;
existing->msgId = fromDraft->msgId;
existing->cursor = fromDraft->cursor;
existing->previewCancelled = fromDraft->previewCancelled;
existing->previewState = fromDraft->previewState;
}
existing->date = base::unixtime::now();
}

View File

@@ -174,6 +174,7 @@ HistoryWidget::HistoryWidget(
, _updateEditTimeLeftDisplay([=] { updateField(); })
, _fieldBarCancel(this, st::historyReplyCancel)
, _previewTimer([=] { requestPreview(); })
, _previewState(Data::PreviewState::Allowed)
, _topBar(this, controller)
, _scroll(this, st::historyScroll, false)
, _updateHistoryItems([=] { updateHistoryItemsByTimer(); })
@@ -335,6 +336,10 @@ HistoryWidget::HistoryWidget(
_fieldLinksParser = std::make_unique<MessageLinksParser>(_field);
_fieldLinksParser->list().changes(
) | rpl::start_with_next([=](QStringList &&parsed) {
if (_previewState == Data::PreviewState::EmptyOnEdit
&& _parsedLinks != parsed) {
_previewState = Data::PreviewState::Allowed;
}
_parsedLinks = std::move(parsed);
checkPreview();
}, lifetime());
@@ -1328,7 +1333,7 @@ void HistoryWidget::fieldChanged() {
updateSendButtonType();
if (!HasSendText(_field)) {
_previewCancelled = false;
_previewState = Data::PreviewState::Allowed;
}
if (updateCmdStartShown()) {
updateControlsVisibility();
@@ -1377,10 +1382,17 @@ void HistoryWidget::saveFieldToHistoryLocalDraft() {
if (!_history) return;
if (_editMsgId) {
_history->setLocalEditDraft(std::make_unique<Data::Draft>(_field, _editMsgId, _previewCancelled, _saveEditMsgRequestId));
_history->setLocalEditDraft(std::make_unique<Data::Draft>(
_field,
_editMsgId,
_previewState,
_saveEditMsgRequestId));
} else {
if (_replyToId || !_field->empty()) {
_history->setLocalDraft(std::make_unique<Data::Draft>(_field, _replyToId, _previewCancelled));
_history->setLocalDraft(std::make_unique<Data::Draft>(
_field,
_replyToId,
_previewState));
} else {
_history->clearLocalDraft();
}
@@ -1401,7 +1413,7 @@ void HistoryWidget::writeDraftTexts() {
Storage::MessageDraft{
_editMsgId ? _editMsgId : _replyToId,
_field->getTextWithTags(),
_previewCancelled,
_previewState,
});
if (_migrated) {
_migrated->clearDrafts();
@@ -1476,7 +1488,11 @@ bool HistoryWidget::notify_switchInlineBotButtonReceived(const QString &query, U
if (_history) {
TextWithTags textWithTags = { '@' + samePeerBot->username + ' ' + query, TextWithTags::Tags() };
MessageCursor cursor = { textWithTags.text.size(), textWithTags.text.size(), QFIXED_MAX };
_history->setLocalDraft(std::make_unique<Data::Draft>(textWithTags, 0, cursor, false));
_history->setLocalDraft(std::make_unique<Data::Draft>(
textWithTags,
0,
cursor,
Data::PreviewState::Allowed));
applyDraft();
return true;
}
@@ -1497,7 +1513,7 @@ bool HistoryWidget::notify_switchInlineBotButtonReceived(const QString &query, U
textWithTags,
to.currentReplyToId,
cursor,
false);
Data::PreviewState::Allowed);
if (to.section == Section::Replies) {
history->setDraft(
@@ -1653,8 +1669,15 @@ void HistoryWidget::applyDraft(FieldHistoryAction fieldHistoryAction) {
setFieldText(draft->textWithTags, 0, fieldHistoryAction);
_field->setFocus();
draft->cursor.applyTo(_field);
_textUpdateEvents = TextUpdateEvent::SaveDraft | TextUpdateEvent::SendTyping;
_previewCancelled = draft->previewCancelled;
_textUpdateEvents = TextUpdateEvent::SaveDraft
| TextUpdateEvent::SendTyping;
// Save links from _field to _parsedLinks without generating preview.
_previewState = Data::PreviewState::Cancelled;
_fieldLinksParser->parseNow();
_parsedLinks = _fieldLinksParser->list().current();
_previewState = draft->previewState;
_replyEditMsg = nullptr;
if (const auto editDraft = _history->localEditDraft()) {
_editMsgId = editDraft->msgId;
@@ -2986,7 +3009,7 @@ void HistoryWidget::saveEditMsg() {
cancelEdit();
return;
}
const auto webPageId = _previewCancelled
const auto webPageId = (_previewState != Data::PreviewState::Allowed)
? CancelledWebPageId
: ((_previewData && _previewData->pendingTill >= 0)
? _previewData->id
@@ -3106,7 +3129,7 @@ void HistoryWidget::send(Api::SendOptions options) {
return;
}
const auto webPageId = _previewCancelled
const auto webPageId = (_previewState != Data::PreviewState::Allowed)
? CancelledWebPageId
: ((_previewData && _previewData->pendingTill >= 0)
? _previewData->id
@@ -5580,7 +5603,7 @@ void HistoryWidget::setFieldText(
| TextUpdateEvent::SendTyping;
previewCancel();
_previewCancelled = false;
_previewState = Data::PreviewState::Allowed;
}
void HistoryWidget::clearFieldText(
@@ -5623,7 +5646,7 @@ void HistoryWidget::replyToMessage(not_null<HistoryItem*> item) {
TextWithTags(),
item->id,
MessageCursor(),
false));
Data::PreviewState::Allowed));
}
} else {
_replyEditMsg = item;
@@ -5670,7 +5693,7 @@ void HistoryWidget::editMessage(not_null<HistoryItem*> item) {
_history->setLocalDraft(std::make_unique<Data::Draft>(
_field,
_replyToId,
_previewCancelled));
_previewState));
} else {
_history->clearLocalDraft();
}
@@ -5688,12 +5711,14 @@ void HistoryWidget::editMessage(not_null<HistoryItem*> item) {
}
return nullptr;
}();
const auto previewCancelled = !previewPage;
const auto previewState = previewPage
? Data::PreviewState::Allowed
: Data::PreviewState::EmptyOnEdit;
_history->setLocalEditDraft(std::make_unique<Data::Draft>(
editData,
item->id,
cursor,
previewCancelled));
previewState));
applyDraft();
_previewData = previewPage;
@@ -5853,7 +5878,7 @@ void HistoryWidget::cancelFieldAreaState() {
Ui::hideLayer();
_replyForwardPressed = false;
if (_previewData && _previewData->pendingTill >= 0) {
_previewCancelled = true;
_previewState = Data::PreviewState::Cancelled;
previewCancel();
_saveDraftText = true;
@@ -5881,7 +5906,7 @@ void HistoryWidget::checkPreview() {
const auto previewRestricted = [&] {
return _peer && _peer->amRestricted(ChatRestriction::f_embed_links);
}();
if (_previewCancelled || previewRestricted) {
if (_previewState != Data::PreviewState::Allowed || previewRestricted) {
previewCancel();
return;
}
@@ -5929,7 +5954,10 @@ void HistoryWidget::requestPreview() {
}).send();
}
void HistoryWidget::gotPreview(QString links, const MTPMessageMedia &result, mtpRequestId req) {
void HistoryWidget::gotPreview(
QString links,
const MTPMessageMedia &result,
mtpRequestId req) {
if (req == _previewRequest) {
_previewRequest = 0;
}
@@ -5937,10 +5965,12 @@ void HistoryWidget::gotPreview(QString links, const MTPMessageMedia &result, mtp
const auto &data = result.c_messageMediaWebPage().vwebpage();
const auto page = session().data().processWebpage(data);
_previewCache.insert(links, page->id);
if (page->pendingTill > 0 && page->pendingTill <= base::unixtime::now()) {
if (page->pendingTill > 0
&& page->pendingTill <= base::unixtime::now()) {
page->pendingTill = -1;
}
if (links == _previewLinks && !_previewCancelled) {
if (links == _previewLinks
&& _previewState == Data::PreviewState::Allowed) {
_previewData = (page->id && page->pendingTill >= 0)
? page.get()
: nullptr;
@@ -5949,7 +5979,8 @@ void HistoryWidget::gotPreview(QString links, const MTPMessageMedia &result, mtp
session().data().sendWebPageGamePollNotifications();
} else if (result.type() == mtpc_messageMediaEmpty) {
_previewCache.insert(links, 0);
if (links == _previewLinks && !_previewCancelled) {
if (links == _previewLinks
&& _previewState == Data::PreviewState::Allowed) {
_previewData = nullptr;
updatePreview();
}

View File

@@ -25,6 +25,10 @@ struct SendingAlbum;
enum class SendMediaType;
class MessageLinksParser;
namespace Data {
enum class PreviewState : char;
} // namespace Data
namespace SendMenu {
enum class Type;
} // namespace SendMenu
@@ -617,7 +621,7 @@ private:
Ui::Text::String _previewTitle;
Ui::Text::String _previewDescription;
base::Timer _previewTimer;
bool _previewCancelled = false;
Data::PreviewState _previewState = Data::PreviewState();
bool _replyForwardPressed = false;

View File

@@ -612,7 +612,8 @@ ComposeControls::ComposeControls(
_send,
st::historySendSize.height()))
, _sendMenuType(sendMenuType)
, _saveDraftTimer([=] { saveDraft(); }) {
, _saveDraftTimer([=] { saveDraft(); })
, _previewState(Data::PreviewState::Allowed) {
init();
}
@@ -865,7 +866,7 @@ void ComposeControls::setFieldText(
| TextUpdateEvent::SendTyping;
_previewCancel();
_previewCancelled = false;
_previewState = Data::PreviewState::Allowed;
}
void ComposeControls::saveFieldToHistoryLocalDraft() {
@@ -880,7 +881,7 @@ void ComposeControls::saveFieldToHistoryLocalDraft() {
std::make_unique<Data::Draft>(
_field,
_header->getDraftMessageId(),
_previewCancelled));
_previewState));
} else {
_history->clearDraft(draftKeyCurrent());
}
@@ -964,7 +965,7 @@ void ComposeControls::init() {
_header->previewCancelled(
) | rpl::start_with_next([=] {
_previewCancelled = true;
_previewState = Data::PreviewState::Cancelled;
_saveDraftText = true;
_saveDraftStart = crl::now();
saveDraft();
@@ -1224,7 +1225,7 @@ void ComposeControls::fieldChanged() {
}
updateSendButtonType();
if (!HasSendText(_field)) {
_previewCancelled = false;
_previewState = Data::PreviewState::Allowed;
}
if (updateBotCommandShown()) {
updateControlsVisibility();
@@ -1294,7 +1295,7 @@ void ComposeControls::writeDraftTexts() {
Storage::MessageDraft{
_header->getDraftMessageId(),
_field->getTextWithTags(),
_previewCancelled,
_previewState,
});
}
@@ -1353,7 +1354,8 @@ void ComposeControls::applyDraft(FieldHistoryAction fieldHistoryAction) {
_field->setFocus();
draft->cursor.applyTo(_field);
_textUpdateEvents = TextUpdateEvent::SaveDraft | TextUpdateEvent::SendTyping;
_previewCancelled = draft->previewCancelled;
_previewSetState(draft->previewState);
if (draft == editDraft) {
_header->editMessage({ _history->channelId(), draft->msgId });
_header->replyToMessage({});
@@ -1837,14 +1839,16 @@ void ComposeControls::editMessage(not_null<HistoryItem*> item) {
}
return nullptr;
}();
const auto previewCancelled = !previewPage;
const auto previewState = previewPage
? Data::PreviewState::Allowed
: Data::PreviewState::EmptyOnEdit;
_history->setDraft(
draftKey(DraftType::Edit),
std::make_unique<Data::Draft>(
editData,
item->id,
cursor,
previewCancelled));
previewState));
applyDraft();
if (_autocomplete) {
@@ -1883,7 +1887,7 @@ void ComposeControls::replyToMessage(FullMsgId id) {
TextWithTags(),
id.msg,
MessageCursor(),
false));
Data::PreviewState::Allowed));
}
} else {
_header->replyToMessage(id);
@@ -1995,7 +1999,8 @@ void ComposeControls::initWebpageProcess() {
if (till > 0 && till <= base::unixtime::now()) {
till = -1;
}
if (links == *previewLinks && !_previewCancelled) {
if (links == *previewLinks
&& _previewState == Data::PreviewState::Allowed) {
*previewData = (page->id && page->pendingTill >= 0)
? page.get()
: nullptr;
@@ -2003,7 +2008,8 @@ void ComposeControls::initWebpageProcess() {
}
}, [=](const MTPDmessageMediaEmpty &d) {
previewCache->insert({ links, 0 });
if (links == *previewLinks && !_previewCancelled) {
if (links == *previewLinks
&& _previewState == Data::PreviewState::Allowed) {
*previewData = nullptr;
updatePreview();
}
@@ -2032,7 +2038,8 @@ void ComposeControls::initWebpageProcess() {
const auto checkPreview = crl::guard(_wrap.get(), [=] {
const auto previewRestricted = peer
&& peer->amRestricted(ChatRestriction::f_embed_links);
if (_previewCancelled || previewRestricted) {
if (_previewState != Data::PreviewState::Allowed
|| previewRestricted) {
_previewCancel();
return;
}
@@ -2105,8 +2112,20 @@ void ComposeControls::initWebpageProcess() {
const auto fieldLinksParser =
lifetime.make_state<MessageLinksParser>(_field);
_previewSetState = [=](Data::PreviewState state) {
// Save links from _field to _parsedLinks without generating preview.
_previewState = Data::PreviewState::Cancelled;
fieldLinksParser->parseNow();
*parsedLinks = fieldLinksParser->list().current();
_previewState = state;
};
fieldLinksParser->list().changes(
) | rpl::start_with_next([=](QStringList &&parsed) {
if (_previewState == Data::PreviewState::EmptyOnEdit
&& *parsedLinks != parsed) {
_previewState = Data::PreviewState::Allowed;
}
*parsedLinks = std::move(parsed);
checkPreview();

View File

@@ -34,6 +34,7 @@ namespace Data {
struct MessagePosition;
struct Draft;
class DraftKey;
enum class PreviewState : char;
} // namespace Data
namespace InlineBots {
@@ -307,7 +308,8 @@ private:
bool _botCommandShown = false;
Fn<void()> _previewCancel;
bool _previewCancelled = false;
Fn<void(Data::PreviewState)> _previewSetState;
Data::PreviewState _previewState = Data::PreviewState();
rpl::lifetime _uploaderSubscriptions;

View File

@@ -902,11 +902,7 @@ void RepliesWidget::send(Api::SendOptions options) {
return;
}
const auto webPageId = _composeControls->webPageId();/* _previewCancelled
? CancelledWebPageId
: ((_previewData && _previewData->pendingTill >= 0)
? _previewData->id
: WebPageId(0));*/
const auto webPageId = _composeControls->webPageId();
auto message = ApiWrap::MessageToSend(_history);
message.textWithTags = _composeControls->getTextWithAppliedMarkdown();

View File

@@ -90,7 +90,6 @@ void ScheduleBox(
[=] { return SendMenu::Type::SilentOnly; },
[=] { save(true, descriptor.collect()); },
nullptr);
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
if (type == SendMenu::Type::ScheduledToUser) {
const auto sendUntilOnline = box->addTopButton(st::infoTopBarMenu);

View File

@@ -523,11 +523,7 @@ void ScheduledWidget::send() {
}
void ScheduledWidget::send(Api::SendOptions options) {
const auto webPageId = _composeControls->webPageId();/* _previewCancelled
? CancelledWebPageId
: ((_previewData && _previewData->pendingTill >= 0)
? _previewData->id
: WebPageId(0));*/
const auto webPageId = _composeControls->webPageId();
auto message = ApiWrap::MessageToSend(_history);
message.textWithTags = _composeControls->getTextWithAppliedMarkdown();

View File

@@ -456,21 +456,21 @@ void Document::draw(
const auto icon = [&] {
if (_data->waitingForAlbum()) {
if (_data->isSong()) {
if (_data->isSongWithCover()) {
return &(selected
? st::historyFileSongWaitingSelected
: st::historyFileSongWaiting);
}
return &(outbg ? (selected ? st::historyFileOutWaitingSelected : st::historyFileOutWaiting) : (selected ? st::historyFileInWaitingSelected : st::historyFileInWaiting));
} else if (!cornerDownload && (_data->loading() || _data->uploading())) {
if (_data->isSong()) {
if (_data->isSongWithCover()) {
return &(selected
? st::historyFileSongCancelSelected
: st::historyFileSongCancel);
}
return &(outbg ? (selected ? st::historyFileOutCancelSelected : st::historyFileOutCancel) : (selected ? st::historyFileInCancelSelected : st::historyFileInCancel));
} else if (showPause) {
if (_data->isSong()) {
if (_data->isSongWithCover()) {
return &(selected
? st::historyFileSongPauseSelected
: st::historyFileSongPause);
@@ -478,7 +478,7 @@ void Document::draw(
return &(outbg ? (selected ? st::historyFileOutPauseSelected : st::historyFileOutPause) : (selected ? st::historyFileInPauseSelected : st::historyFileInPause));
} else if (loaded || _dataMedia->canBePlayed()) {
if (_dataMedia->canBePlayed()) {
if (_data->isSong()) {
if (_data->isSongWithCover()) {
return &(selected
? st::historyFileSongPlaySelected
: st::historyFileSongPlay);
@@ -489,7 +489,7 @@ void Document::draw(
}
return &(outbg ? (selected ? st::historyFileOutDocumentSelected : st::historyFileOutDocument) : (selected ? st::historyFileInDocumentSelected : st::historyFileInDocument));
}
if (_data->isSong()) {
if (_data->isSongWithCover()) {
return &(selected
? st::historyFileSongDownloadSelected
: st::historyFileSongDownload);

View File

@@ -896,7 +896,7 @@ void File::paint(Painter &p, const QRect &clip, const PaintContext *context) con
return &st::historyFileInPause;
} else if (_document->isImage()) {
return &st::historyFileInImage;
} else if (_document->isSong()) {
} else if (_document->isSongWithCover()) {
return &st::historyFileSongPlay;
} else if (_document->isVoiceMessage()
|| _document->isAudioFile()) {

View File

@@ -548,8 +548,11 @@ bool MainWidget::shareUrl(
QFIXED_MAX
};
auto history = peer->owner().history(peer);
history->setLocalDraft(
std::make_unique<Data::Draft>(textWithTags, 0, cursor, false));
history->setLocalDraft(std::make_unique<Data::Draft>(
textWithTags,
0,
cursor,
Data::PreviewState::Allowed));
history->clearLocalEditDraft();
history->session().changes().historyUpdated(
history,
@@ -576,7 +579,11 @@ bool MainWidget::inlineSwitchChosen(PeerId peerId, const QString &botAndQuery) {
const auto h = peer->owner().history(peer);
TextWithTags textWithTags = { botAndQuery, TextWithTags::Tags() };
MessageCursor cursor = { botAndQuery.size(), botAndQuery.size(), QFIXED_MAX };
h->setLocalDraft(std::make_unique<Data::Draft>(textWithTags, 0, cursor, false));
h->setLocalDraft(std::make_unique<Data::Draft>(
textWithTags,
0,
cursor,
Data::PreviewState::Allowed));
h->clearLocalEditDraft();
h->session().changes().historyUpdated(
h,

View File

@@ -444,7 +444,15 @@ void OverlayWidget::moveToScreen() {
const auto activeWindowScreen = widgetScreen(window);
const auto myScreen = widgetScreen(this);
if (activeWindowScreen && myScreen != activeWindowScreen) {
const auto screenList = QGuiApplication::screens();
DEBUG_LOG(("Viewer Pos: Currently on screen %1, moving to screen %2")
.arg(screenList.indexOf(myScreen))
.arg(screenList.indexOf(activeWindowScreen)));
windowHandle()->setScreen(activeWindowScreen);
DEBUG_LOG(("Viewer Pos: New actual screen: %1")
.arg(windowHandle()
? screenList.indexOf(windowHandle()->screen())
: -2));
}
updateGeometry();
}
@@ -1313,14 +1321,26 @@ void OverlayWidget::onScreenResized(int screen) {
void OverlayWidget::handleVisibleChanged(bool visible) {
if (visible) {
const auto screenList = QGuiApplication::screens();
DEBUG_LOG(("Viewer Pos: Shown, screen number: %1")
.arg(windowHandle()
? screenList.indexOf(windowHandle()->screen())
: -2));
moveToScreen();
}
}
void OverlayWidget::handleScreenChanged(QScreen *screen) {
if (isVisible()) {
moveToScreen();
if (!isVisible()) {
return;
}
const auto screenList = QGuiApplication::screens();
DEBUG_LOG(("Viewer Pos: Screen changed to: %1")
.arg(screenList.indexOf(screen)));
moveToScreen();
}
void OverlayWidget::onToMessage() {

View File

@@ -1037,6 +1037,24 @@ void Document::paint(Painter &p, const QRect &clip, TextSelection selection, con
}
const auto icon = [&] {
if (!coverDrawn) {
if (isLoading) {
return &(selected
? _st.voiceCancelSelected
: _st.voiceCancel);
} else if (showPause) {
return &(selected
? _st.voicePauseSelected
: _st.voicePause);
} else if (loaded || _dataMedia->canBePlayed()) {
return &(selected
? _st.voicePlaySelected
: _st.voicePlay);
}
return &(selected
? _st.voiceDownloadSelected
: _st.voiceDownload);
}
if (isLoading) {
return &(selected ? _st.songCancelSelected : _st.songCancel);
} else if (showPause) {

View File

@@ -65,6 +65,8 @@ using namespace Platform;
using Platform::internal::WaylandIntegration;
using Platform::internal::GtkIntegration;
Q_DECLARE_METATYPE(QMargins);
namespace Platform {
namespace {
@@ -796,24 +798,45 @@ bool ShowWindowMenu(QWindow *window) {
}
bool SetWindowExtents(QWindow *window, const QMargins &extents) {
if (!IsWayland()) {
if (IsWayland()) {
#ifdef DESKTOP_APP_QT_PATCHED
window->setProperty("WaylandCustomMargins", QVariant::fromValue<QMargins>(extents));
return true;
#else // DESKTOP_APP_QT_PATCHED
return false;
#endif // !DESKTOP_APP_QT_PATCHED
} else {
return SetXCBFrameExtents(window, extents);
}
return false;
}
bool UnsetWindowExtents(QWindow *window) {
if (!IsWayland()) {
if (IsWayland()) {
#ifdef DESKTOP_APP_QT_PATCHED
window->setProperty("WaylandCustomMargins", QVariant());
return true;
#else // DESKTOP_APP_QT_PATCHED
return false;
#endif // !DESKTOP_APP_QT_PATCHED
} else {
return UnsetXCBFrameExtents(window);
}
return false;
}
bool WindowsNeedShadow() {
return !IsWayland()
&& base::Platform::XCB::IsSupportedByWM(kXCBFrameExtentsAtomName.utf16());
#ifdef DESKTOP_APP_QT_PATCHED
if (IsWayland()) {
return true;
}
#endif // DESKTOP_APP_QT_PATCHED
namespace XCB = base::Platform::XCB;
if (!IsWayland()
&& XCB::IsSupportedByWM(kXCBFrameExtentsAtomName.utf16())) {
return true;
}
return false;
}
Window::ControlsLayout WindowControlsLayout() {

View File

@@ -958,7 +958,7 @@ void EnumerateDrafts(
key,
draft->msgId,
draft->textWithTags,
draft->previewCancelled,
draft->previewState,
draft->cursor);
}
if (replaceKey
@@ -969,7 +969,7 @@ void EnumerateDrafts(
replaceKey,
replaceDraft.msgId,
replaceDraft.textWithTags,
replaceDraft.previewCancelled,
replaceDraft.previewState,
replaceCursor);
}
}
@@ -1017,12 +1017,12 @@ void Account::writeDrafts(
auto&&, // key
MsgId, // msgId
const TextWithTags &text,
bool, // previewCancelled
Data::PreviewState,
auto&&) { // cursor
size += sizeof(qint32) // key
+ Serialize::stringSize(text.text)
+ sizeof(quint32) + TextUtilities::SerializeTagsSize(text.tags)
+ 2 * sizeof(qint32); // msgId, previewCancelled
+ 2 * sizeof(qint32); // msgId, previewState
};
EnumerateDrafts(
map,
@@ -1043,14 +1043,14 @@ void Account::writeDrafts(
const Data::DraftKey &key,
MsgId msgId,
const TextWithTags &text,
bool previewCancelled,
Data::PreviewState previewState,
auto&&) { // cursor
data.stream
<< key.serialize()
<< text.text
<< TextUtilities::SerializeTags(text.tags)
<< qint32(msgId)
<< qint32(previewCancelled ? 1 : 0);
<< qint32(previewState);
};
EnumerateDrafts(
map,
@@ -1109,7 +1109,7 @@ void Account::writeDraftCursors(
auto&&, // key
MsgId, // msgId
auto&&, // text
bool, // previewCancelled
Data::PreviewState,
const MessageCursor &cursor) { // cursor
data.stream
<< qint32(cursor.position)
@@ -1249,23 +1249,29 @@ void Account::readDraftsWithCursors(not_null<History*> history) {
for (auto i = 0; i != count; ++i) {
TextWithTags data;
QByteArray tagsSerialized;
qint32 keyValue = 0, messageId = 0, previewCancelled = 0;
qint32 keyValue = 0, messageId = 0, uncheckedPreviewState = 0;
draft.stream
>> keyValue
>> data.text
>> tagsSerialized
>> messageId
>> previewCancelled;
>> uncheckedPreviewState;
data.tags = TextUtilities::DeserializeTags(
tagsSerialized,
data.text.size());
auto previewState = Data::PreviewState::Allowed;
switch (static_cast<Data::PreviewState>(uncheckedPreviewState)) {
case Data::PreviewState::Cancelled:
case Data::PreviewState::EmptyOnEdit:
previewState = Data::PreviewState(uncheckedPreviewState);
}
const auto key = Data::DraftKey::FromSerialized(keyValue);
if (key && key != Data::DraftKey::Cloud()) {
map.emplace(key, std::make_unique<Data::Draft>(
data,
messageId,
MessageCursor(),
previewCancelled));
previewState));
}
}
if (draft.stream.status() != QDataStream::Ok) {
@@ -1326,14 +1332,18 @@ void Account::readDraftsWithCursorsLegacy(
msgData,
msgReplyTo,
MessageCursor(),
msgPreviewCancelled));
(msgPreviewCancelled
? Data::PreviewState::Cancelled
: Data::PreviewState::Allowed)));
}
if (editMsgId) {
map.emplace(Data::DraftKey::LocalEdit(), std::make_unique<Data::Draft>(
editData,
editMsgId,
MessageCursor(),
editPreviewCancelled));
(editPreviewCancelled
? Data::PreviewState::Cancelled
: Data::PreviewState::Allowed)));
}
readDraftCursors(peerId, map);
history->setDraftsMap(std::move(map));

View File

@@ -52,7 +52,7 @@ enum class StartResult : uchar;
struct MessageDraft {
MsgId msgId = 0;
TextWithTags textWithTags;
bool previewCancelled = false;
Data::PreviewState previewState = Data::PreviewState::Allowed;
};
class Account final {

View File

@@ -155,7 +155,7 @@ Data::Draft OccupiedDraft(const QString &normalizedName) {
+ normalizedName },
MsgId(0),
MessageCursor(),
false
Data::PreviewState::Allowed
};
}

View File

@@ -694,6 +694,7 @@ ChooseDateTimeBoxDescriptor ChooseDateTimeBox(
auto result = ChooseDateTimeBoxDescriptor();
box->setFocusCallback([=] { timeInput->setFocusFast(); });
result.submit = box->addButton(std::move(submit), save);
result.collect = collect;
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
return result;

View File

@@ -168,7 +168,9 @@ void SingleFilePreview::paintEvent(QPaintEvent *e) {
}
auto &icon = _fileIsAudio
? st::historyFileSongPlay
? (_fileThumb.isNull()
? st::historyFileInPlay
: st::historyFileSongPlay)
: _fileIsImage
? st::historyFileInImage
: st::historyFileInDocument;

View File

@@ -106,6 +106,12 @@ System::SkipState System::skipNotification(
}
const auto scheduled = item->out() && item->isFromScheduled();
if (const auto forwarded = item->Get<HistoryMessageForwarded>()) {
if (forwarded->imported) {
return { SkipState::Skip };
}
}
history->owner().requestNotifySettings(history->peer);
if (notifyBy) {
history->owner().requestNotifySettings(notifyBy);

View File

@@ -95,10 +95,12 @@ if %Build64% neq 0 (
set "UpdateFile=tx64upd%AppVersion%"
set "SetupFile=tsetup-x64.%AppVersionStrFull%.exe"
set "PortableFile=tportable-x64.%AppVersionStrFull%.zip"
set "DumpSymsPath=%SolutionPath%\..\..\Libraries\win64\breakpad\src\tools\windows\dump_syms\Release\dump_syms.exe"
) else (
set "UpdateFile=tupdate%AppVersion%"
set "SetupFile=tsetup.%AppVersionStrFull%.exe"
set "PortableFile=tportable.%AppVersionStrFull%.zip"
set "DumpSymsPath=%SolutionPath%\..\..\Libraries\breakpad\src\tools\windows\dump_syms\Release\dump_syms.exe"
)
set "ReleasePath=%SolutionPath%\Release"
set "DeployPath=%ReleasePath%\deploy\%AppVersionStrMajor%\%AppVersionStrFull%"
@@ -164,13 +166,13 @@ echo.
echo Version %AppVersionStrFull% build successfull. Preparing..
echo.
if not exist "%SolutionPath%\..\..\Libraries\win64\breakpad\src\tools\windows\dump_syms\Release\dump_syms.exe" (
if not exist "%DumpSymsPath%" (
echo Utility dump_syms not found!
exit /b 1
)
echo Dumping debug symbols..
call "%SolutionPath%\..\..\Libraries\win64\breakpad\src\tools\windows\dump_syms\Release\dump_syms.exe" "%ReleasePath%\%BinaryName%.pdb" > "%ReleasePath%\%BinaryName%.sym"
call "%DumpSymsPath%" "%ReleasePath%\%BinaryName%.pdb" > "%ReleasePath%\%BinaryName%.sym"
echo Done!
set "PATH=%PATH%;C:\Program Files\7-Zip;C:\Program Files (x86)\Inno Setup 5"

View File

@@ -479,6 +479,8 @@ RUN git submodule update qtbase qtwayland qtimageformats qtsvg
WORKDIR qtbase
RUN find ../../patches/qtbase_${QT} -type f -print0 | sort -z | xargs -r0 git apply
WORKDIR ../qtwayland
RUN find ../../patches/qtwayland_${QT} -type f -print0 | sort -z | xargs -r0 git apply
WORKDIR ..
# I couldn't make it work with direct ./configure call :(

View File

@@ -1,7 +1,7 @@
AppVersion 2005007
AppVersion 2005008
AppVersionStrMajor 2.5
AppVersionStrSmall 2.5.7
AppVersionStr 2.5.7
AppVersionStrSmall 2.5.8
AppVersionStr 2.5.8
BetaChannel 0
AlphaVersion 0
AppVersionOriginal 2.5.7
AppVersionOriginal 2.5.8

View File

@@ -1,3 +1,10 @@
2.5.8 (29.01.21)
- Fix OpenAL device closing in calls and voice chats.
- Fix video chat rotation when calling from iOS.
- Fix scheduling messages without sound.
- Remove redundant Cancel button in ScheduleBox.
2.5.7 (28.01.21)
- Delete not only messages, but also groups you created and call history for all sides, without a trace.

View File

@@ -68,17 +68,16 @@ parts:
source: .
source-type: git
parse-info: [usr/share/metainfo/telegram-desktop_telegram-desktop.appdata.xml]
build-environment:
- LD_LIBRARY_PATH: $SNAPCRAFT_STAGE/usr/lib/$SNAPCRAFT_ARCH_TRIPLET:$LD_LIBRARY_PATH
build-packages:
- python
- qtbase5-private-dev
- libasound2-dev
- libglib2.0-dev
- libgtk-3-dev
- libkf5wayland-dev
- liblzma-dev
- libopus-dev
- libpulse-dev
- libqt5waylandclient5-dev
- libssl-dev
- libxcb1-dev
- libxcb-keysyms1-dev
@@ -86,16 +85,12 @@ parts:
- libxcb-screensaver0-dev
- zlib1g-dev
stage-packages:
- qt5-image-formats-plugins
- qtwayland5
- libasound2
- libglib2.0-0
- libgtk-3-0
- libkf5waylandclient5
- liblzma5
- libopus0
- libpulse0
- libqt5waylandclient5
- libssl1.1
- libxcb1
- libxcb-keysyms1
@@ -108,7 +103,7 @@ parts:
- -DTDESKTOP_API_ID=611335
- -DTDESKTOP_API_HASH=d524b414d21f4d37f08684c1df41ac9c
- -DDESKTOP_APP_USE_PACKAGED_LAZY=ON
- -DDESKTOP_APP_QTWAYLANDCLIENT_PRIVATE_HEADERS=$SNAPCRAFT_STAGE/usr/include/$SNAPCRAFT_ARCH_TRIPLET/qt5/QtWaylandClient/5.12.8
- -DDESKTOP_APP_USE_PACKAGED_LAZY_PLATFORMTHEMES=OFF
- -DTDESKTOP_LAUNCHER_BASENAME=telegram-desktop_telegram-desktop
override-pull: |
snapcraftctl pull
@@ -134,11 +129,19 @@ parts:
after:
- desktop-qt5
- ffmpeg
- kwayland
- mozjpeg
- openal
- qtwayland
- webrtc
patches:
source: https://github.com/desktop-app/patches.git
source-depth: 1
plugin: dump
organize:
"*": patches/
prime: [-./*]
desktop-qt5:
source: https://github.com/ubuntu/snapcraft-desktop-helpers.git
source-subdir: qt
@@ -146,7 +149,6 @@ parts:
make-parameters: ["FLAVOR=qt5"]
build-packages:
- build-essential
- qtbase5-dev
- dpkg-dev
stage-packages:
- libxkbcommon0
@@ -156,26 +158,25 @@ parts:
- adwaita-icon-theme
- gnome-themes-standard
- shared-mime-info
- libqt5gui5
- libgdk-pixbuf2.0-0
- libqt5svg5 # for loading icon themes which are svg
- try: [appmenu-qt5] # not available on core18
- locales-all
- xdg-user-dirs
- fcitx-frontend-qt5
stage:
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/libjpeg.so.8.2.2
after:
- mozjpeg
- qt5
qt5-xdgdesktopportal-platform:
plugin: nil
stage-packages:
- qt5-xdgdesktopportal-platformtheme
stage:
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/libjpeg.so.8.2.2
after:
- mozjpeg
extra-cmake-modules:
source: https://github.com/KDE/extra-cmake-modules.git
source-depth: 1
source-tag: v5.77.0
plugin: cmake
cmake-parameters:
- -DCMAKE_BUILD_TYPE=Release
- -DCMAKE_INSTALL_PREFIX=/usr
- -DBUILD_TESTING=OFF
prime: [-./*]
ffmpeg:
plugin: nil
@@ -196,6 +197,32 @@ parts:
after:
- mozjpeg
kwayland:
source: https://github.com/KDE/kwayland.git
source-depth: 1
source-tag: v5.77.0
plugin: cmake
build-packages:
- libwayland-dev
- wayland-protocols
stage-packages:
- libwayland-client0
- libwayland-server0
cmake-parameters:
- -DCMAKE_BUILD_TYPE=Release
- -DCMAKE_INSTALL_PREFIX=/usr
- -DBUILD_TESTING=OFF
prime:
- -./usr/include
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/libexec
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/pkgconfig
- -./usr/mkspecs
- -./usr/share
after:
- extra-cmake-modules
- desktop-qt5
- plasma-wayland-protocols
mozjpeg:
source: https://github.com/mozilla/mozjpeg.git
source-depth: 1
@@ -236,19 +263,149 @@ parts:
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/cmake
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/pkgconfig
qtwayland:
source: https://github.com/qt/qtwayland.git
plasma-wayland-protocols:
source: https://github.com/KDE/plasma-wayland-protocols.git
source-depth: 1
source-tag: v5.12.8
plugin: dump
override-build: |
qmake
make -j$(nproc)
make INSTALL_ROOT="$SNAPCRAFT_PART_INSTALL" install
stage: [-./usr/lib]
source-tag: v1.1.1
plugin: cmake
cmake-parameters:
- -DCMAKE_BUILD_TYPE=Release
- -DCMAKE_INSTALL_PREFIX=/usr
prime: [-./*]
after:
- desktop-qt5
- extra-cmake-modules
qt5:
plugin: nil
build-packages:
- libdbus-1-dev
- libegl-dev
- libfontconfig1-dev
- libfreetype-dev
- libgl-dev
- libglib2.0-dev
- libharfbuzz-dev
- libicu-dev
- libpcre2-dev
- libpng-dev
- libssl-dev
- libwayland-dev
- libx11-dev
- libx11-xcb-dev
- libxcb1-dev
- libxcb-glx0-dev
- libxcb-icccm4-dev
- libxcb-image0-dev
- libxcb-keysyms1-dev
- libxcb-randr0-dev
- libxcb-render0-dev
- libxcb-render-util0-dev
- libxcb-shape0-dev
- libxcb-shm0-dev
- libxcb-sync-dev
- libxcb-util-dev
- libxcb-xfixes0-dev
- libxcb-xinerama0-dev
- libxcb-xinput-dev
- libxcb-xkb-dev
- libxcursor-dev
- libxkbcommon-dev
- libxkbcommon-x11-dev
- zlib1g-dev
stage-packages:
- libdbus-1-3
- libegl1
- libfontconfig1
- libfreetype6
- libgl1
- libglib2.0-0
- libharfbuzz0b
- libicu66
- libpcre2-16-0
- libpng16-16
- libssl1.1
- libwayland-client0
- libwayland-cursor0
- libwayland-egl1
- libx11-6
- libx11-xcb1
- libxcb1
- libxcb-glx0
- libxcb-icccm4
- libxcb-image0
- libxcb-keysyms1
- libxcb-randr0
- libxcb-render0
- libxcb-render-util0
- libxcb-shape0
- libxcb-shm0
- libxcb-sync1
- libxcb-util1
- libxcb-xfixes0
- libxcb-xinerama0
- libxcb-xinput0
- libxcb-xkb1
- libxcursor1
- libxkbcommon0
- libxkbcommon-x11-0
- zlib1g
override-pull: |
QT=5_15_2
git clone -b v5.15.2 --depth=1 git://code.qt.io/qt/qt5.git .
perl init-repository --module-subset=qtbase,qtwayland,qtimageformats,qtsvg
git submodule update qtbase qtwayland qtimageformats qtsvg
cd qtbase
find $SNAPCRAFT_STAGE/patches/qtbase_${QT} -type f -print0 | sort -z | xargs -r0 git apply
cd ../qtwayland
find $SNAPCRAFT_STAGE/patches/qtwayland_${QT} -type f -print0 | sort -z | xargs -r0 git apply
cd ..
override-build: |
./configure \
-prefix /usr \
-bindir /usr/lib/qt5/bin \
-libdir /usr/lib/$SNAPCRAFT_ARCH_TRIPLET \
-docdir /usr/share/qt5/doc \
-headerdir /usr/include/$SNAPCRAFT_ARCH_TRIPLET/qt5 \
-datadir /usr/share/qt5 \
-archdatadir /usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5 \
-plugindir /usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/plugins \
-importdir /usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/imports \
-translationdir /usr/share/qt5/translations \
-hostdatadir /usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5 \
-sysconfdir /etc/xdg \
-examplesdir /usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/examples \
-release \
-opensource \
-confirm-license \
-no-gtk \
-no-feature-xcb-sm \
-no-feature-xcomposite-egl \
-no-feature-xcomposite-glx \
-no-feature-wayland-server \
-openssl-linked \
-nomake examples \
-nomake tests \
-I $SNAPCRAFT_STAGE/usr/include \
-L $SNAPCRAFT_STAGE/usr/lib/$SNAPCRAFT_ARCH_TRIPLET
make -j$(nproc)
make INSTALL_ROOT="$SNAPCRAFT_PART_INSTALL" install
stage:
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/libjpeg.so.8.2.2
prime:
- -./usr/include
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/cmake
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/pkgconfig
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/bin
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/mkspecs
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/examples
- -./usr/lib/qt5
- -./usr/share
after:
- mozjpeg
- patches
webrtc:
source: https://github.com/desktop-app/tg_owt.git