Compare commits
24 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
87895466dc | ||
|
|
72f8d3f485 | ||
|
|
5092d8fe63 | ||
|
|
01110a29ad | ||
|
|
e8c3df2abb | ||
|
|
db89de96a9 | ||
|
|
1eacaec66b | ||
|
|
10f58c2ac7 | ||
|
|
e0680fc2a5 | ||
|
|
fba7bd7807 | ||
|
|
6c0553f4d6 | ||
|
|
5d4e5ed527 | ||
|
|
2559c5d6f4 | ||
|
|
8d85dd7c19 | ||
|
|
8f0e23bb25 | ||
|
|
fc4ed2ff91 | ||
|
|
fcdc39c5f9 | ||
|
|
1ec6b4313d | ||
|
|
9be65f8812 | ||
|
|
30468746ad | ||
|
|
7947af665c | ||
|
|
160cd975ce | ||
|
|
c13d0e96ef | ||
|
|
fbf4f912c6 |
@@ -67,6 +67,7 @@ PRIVATE
|
||||
desktop-app::external_auto_updates
|
||||
desktop-app::external_openssl
|
||||
desktop-app::external_openal
|
||||
desktop-app::external_xxhash
|
||||
)
|
||||
|
||||
if (LINUX)
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
}
|
||||
|
||||
|
||||
@@ -51,10 +51,6 @@ public:
|
||||
private:
|
||||
using ListWidget = PeerListContent;
|
||||
|
||||
void visibleTopBottomUpdated(
|
||||
int visibleTop,
|
||||
int visibleBottom) override;
|
||||
|
||||
void resizeEvent(QResizeEvent *e) override;
|
||||
|
||||
// PeerListContentDelegate interface.
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -155,7 +155,7 @@ Data::Draft OccupiedDraft(const QString &normalizedName) {
|
||||
+ normalizedName },
|
||||
MsgId(0),
|
||||
MessageCursor(),
|
||||
false
|
||||
Data::PreviewState::Allowed
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 :(
|
||||
|
||||
@@ -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
|
||||
|
||||
Submodule Telegram/lib_base updated: f770025cc1...2bf29ab1a5
Submodule Telegram/lib_ui updated: f03209c1f9...d94cb34219
Submodule Telegram/lib_webrtc updated: de46d688f0...af7269454c
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user