Compare commits

..

21 Commits

Author SHA1 Message Date
John Preston
4b03fd0f23 Version 3.3: Fix build with GCC. 2021-12-08 08:35:03 +04:00
John Preston
9f117cd680 Version 3.3: Update submodules. 2021-12-07 16:29:38 +04:00
John Preston
f6d29991d6 Version 3.3.
- Content creators can restrict the ability to save media
and forward messages from their groups and channels.
- Clear messages in one-on-one chats from a specific day or date range.
- Comment as one of your channels in public groups and channel comments.
- When you request to join a community and its admin
or bot-admin contacts you with a message,
you will see which chat they are from at the top of the chat.
- Bot-admins can now ask users to complete tasks
before they are allowed to join - like accepting community rules,
passing a test, or making a donation to the content creators.
2021-12-07 15:52:33 +04:00
John Preston
1a0d430291 Fix crash in admin log right click.
Fixes #17325.
2021-12-07 15:42:30 +04:00
John Preston
e3b9927faa Reset session on receiving a really old msgId. 2021-12-07 10:05:41 +04:00
John Preston
d199e16a6e Load cloud image without active view only once. 2021-12-07 10:01:56 +04:00
John Preston
01c2be3f01 Add some checks for actions in a locked state. 2021-12-07 10:01:56 +04:00
Ilya Fedin
6db537d1ec Rename telegramdesktop.appdata.xml -> telegramdesktop.metainfo.xml
.appinfo.xml is legacy according to https://freedesktop.org/software/appstream/docs/chap-Metadata.html#spec-component-location
2021-12-06 11:53:28 +04:00
John Preston
e708b2d39c Move some icons, fix verified check scaling. 2021-12-03 15:30:40 +04:00
John Preston
ebd9587821 Fix admin ranks in participants edit. 2021-12-03 15:02:45 +04:00
John Preston
9e5117d336 Respect autodownload settings in reply previews. 2021-12-03 14:59:08 +04:00
John Preston
1c2ea8d84a Fix semi-transparent inline result thumbnails. 2021-12-02 16:03:13 +04:00
John Preston
235484b719 Fix saving group type without changing username. 2021-12-02 15:26:58 +04:00
John Preston
b9ea5718a2 Fix "about request admin panel" box hiding. 2021-12-02 15:00:27 +04:00
John Preston
db0c57a186 Fix reply-to-media timestamps in captions. 2021-12-02 14:42:50 +04:00
John Preston
0fa458737a Fix shared media loading. 2021-12-02 13:54:30 +04:00
John Preston
caaeff32c5 Move global privacy setting down. 2021-12-02 13:36:49 +04:00
John Preston
c4c234f0d3 Pass FilterId to pinnedIndexChanged. 2021-12-02 13:36:49 +04:00
John Preston
894e7c5828 Fix imported messages without a sender name. 2021-12-02 13:36:49 +04:00
John Preston
afcebb136c Don't use MTP for PeerData::isSelf. 2021-12-02 13:36:49 +04:00
Ilya Fedin
8592326a3c Revert "Use kernel accelerated sendfile to copy files on Linux"
This reverts commit 34534a9653.
2021-12-02 09:15:23 +04:00
120 changed files with 371 additions and 322 deletions

View File

@@ -1526,8 +1526,8 @@ endif()
if (LINUX AND DESKTOP_APP_USE_PACKAGED)
include(GNUInstallDirs)
configure_file("../lib/xdg/telegramdesktop.appdata.xml.in" "${CMAKE_CURRENT_BINARY_DIR}/telegramdesktop.appdata.xml" @ONLY)
generate_appdata_changelog(Telegram "${CMAKE_SOURCE_DIR}/changelog.txt" "${CMAKE_CURRENT_BINARY_DIR}/telegramdesktop.appdata.xml")
configure_file("../lib/xdg/telegramdesktop.metainfo.xml.in" "${CMAKE_CURRENT_BINARY_DIR}/telegramdesktop.metainfo.xml" @ONLY)
generate_appdata_changelog(Telegram "${CMAKE_SOURCE_DIR}/changelog.txt" "${CMAKE_CURRENT_BINARY_DIR}/telegramdesktop.metainfo.xml")
install(TARGETS Telegram RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" BUNDLE DESTINATION "${CMAKE_INSTALL_BINDIR}")
install(FILES "Resources/art/icon16.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/16x16/apps" RENAME "telegram.png")
install(FILES "Resources/art/icon32.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/32x32/apps" RENAME "telegram.png")
@@ -1537,5 +1537,5 @@ if (LINUX AND DESKTOP_APP_USE_PACKAGED)
install(FILES "Resources/art/icon256.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/256x256/apps" RENAME "telegram.png")
install(FILES "Resources/art/icon512.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/512x512/apps" RENAME "telegram.png")
install(FILES "../lib/xdg/telegramdesktop.desktop" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications" RENAME "${TDESKTOP_LAUNCHER_BASENAME}.desktop")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/telegramdesktop.appdata.xml" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/metainfo" RENAME "${TDESKTOP_LAUNCHER_BASENAME}.appdata.xml")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/telegramdesktop.metainfo.xml" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/metainfo" RENAME "${TDESKTOP_LAUNCHER_BASENAME}.metainfo.xml")
endif()

View File

Before

Width:  |  Height:  |  Size: 277 B

After

Width:  |  Height:  |  Size: 277 B

View File

Before

Width:  |  Height:  |  Size: 482 B

After

Width:  |  Height:  |  Size: 482 B

View File

Before

Width:  |  Height:  |  Size: 715 B

After

Width:  |  Height:  |  Size: 715 B

View File

Before

Width:  |  Height:  |  Size: 173 B

After

Width:  |  Height:  |  Size: 173 B

View File

Before

Width:  |  Height:  |  Size: 255 B

After

Width:  |  Height:  |  Size: 255 B

View File

Before

Width:  |  Height:  |  Size: 344 B

After

Width:  |  Height:  |  Size: 344 B

View File

Before

Width:  |  Height:  |  Size: 197 B

After

Width:  |  Height:  |  Size: 197 B

View File

Before

Width:  |  Height:  |  Size: 273 B

After

Width:  |  Height:  |  Size: 273 B

View File

Before

Width:  |  Height:  |  Size: 393 B

After

Width:  |  Height:  |  Size: 393 B

View File

Before

Width:  |  Height:  |  Size: 253 B

After

Width:  |  Height:  |  Size: 253 B

View File

Before

Width:  |  Height:  |  Size: 433 B

After

Width:  |  Height:  |  Size: 433 B

View File

Before

Width:  |  Height:  |  Size: 494 B

After

Width:  |  Height:  |  Size: 494 B

View File

Before

Width:  |  Height:  |  Size: 265 B

After

Width:  |  Height:  |  Size: 265 B

View File

Before

Width:  |  Height:  |  Size: 490 B

After

Width:  |  Height:  |  Size: 490 B

View File

Before

Width:  |  Height:  |  Size: 578 B

After

Width:  |  Height:  |  Size: 578 B

View File

Before

Width:  |  Height:  |  Size: 285 B

After

Width:  |  Height:  |  Size: 285 B

View File

Before

Width:  |  Height:  |  Size: 444 B

After

Width:  |  Height:  |  Size: 444 B

View File

Before

Width:  |  Height:  |  Size: 598 B

After

Width:  |  Height:  |  Size: 598 B

View File

Before

Width:  |  Height:  |  Size: 128 B

After

Width:  |  Height:  |  Size: 128 B

View File

Before

Width:  |  Height:  |  Size: 247 B

After

Width:  |  Height:  |  Size: 247 B

View File

Before

Width:  |  Height:  |  Size: 350 B

After

Width:  |  Height:  |  Size: 350 B

View File

Before

Width:  |  Height:  |  Size: 146 B

After

Width:  |  Height:  |  Size: 146 B

View File

Before

Width:  |  Height:  |  Size: 289 B

After

Width:  |  Height:  |  Size: 289 B

View File

Before

Width:  |  Height:  |  Size: 386 B

After

Width:  |  Height:  |  Size: 386 B

View File

Before

Width:  |  Height:  |  Size: 170 B

After

Width:  |  Height:  |  Size: 170 B

View File

Before

Width:  |  Height:  |  Size: 362 B

After

Width:  |  Height:  |  Size: 362 B

View File

Before

Width:  |  Height:  |  Size: 488 B

After

Width:  |  Height:  |  Size: 488 B

View File

Before

Width:  |  Height:  |  Size: 387 B

After

Width:  |  Height:  |  Size: 387 B

View File

Before

Width:  |  Height:  |  Size: 638 B

After

Width:  |  Height:  |  Size: 638 B

View File

Before

Width:  |  Height:  |  Size: 907 B

After

Width:  |  Height:  |  Size: 907 B

View File

Before

Width:  |  Height:  |  Size: 158 B

After

Width:  |  Height:  |  Size: 158 B

View File

Before

Width:  |  Height:  |  Size: 309 B

After

Width:  |  Height:  |  Size: 309 B

View File

Before

Width:  |  Height:  |  Size: 321 B

After

Width:  |  Height:  |  Size: 321 B

View File

Before

Width:  |  Height:  |  Size: 367 B

After

Width:  |  Height:  |  Size: 367 B

View File

Before

Width:  |  Height:  |  Size: 1013 B

After

Width:  |  Height:  |  Size: 1013 B

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 223 B

After

Width:  |  Height:  |  Size: 223 B

View File

Before

Width:  |  Height:  |  Size: 432 B

After

Width:  |  Height:  |  Size: 432 B

View File

Before

Width:  |  Height:  |  Size: 512 B

After

Width:  |  Height:  |  Size: 512 B

View File

Before

Width:  |  Height:  |  Size: 145 B

After

Width:  |  Height:  |  Size: 145 B

View File

Before

Width:  |  Height:  |  Size: 261 B

After

Width:  |  Height:  |  Size: 261 B

View File

Before

Width:  |  Height:  |  Size: 272 B

After

Width:  |  Height:  |  Size: 272 B

View File

Before

Width:  |  Height:  |  Size: 287 B

After

Width:  |  Height:  |  Size: 287 B

View File

Before

Width:  |  Height:  |  Size: 450 B

After

Width:  |  Height:  |  Size: 450 B

View File

Before

Width:  |  Height:  |  Size: 578 B

After

Width:  |  Height:  |  Size: 578 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 365 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 425 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 371 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 714 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 803 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 180 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 281 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 404 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 342 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 660 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 694 B

View File

@@ -10,7 +10,7 @@
<Identity Name="TelegramMessengerLLP.TelegramDesktop"
ProcessorArchitecture="ARCHITECTURE"
Publisher="CN=536BC709-8EE1-4478-AF22-F0F0F26FF64A"
Version="3.2.8.0" />
Version="3.3.0.0" />
<Properties>
<DisplayName>Telegram Desktop</DisplayName>
<PublisherDisplayName>Telegram Messenger LLP</PublisherDisplayName>

View File

@@ -44,8 +44,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico"
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 3,2,8,0
PRODUCTVERSION 3,2,8,0
FILEVERSION 3,3,0,0
PRODUCTVERSION 3,3,0,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -62,10 +62,10 @@ BEGIN
BEGIN
VALUE "CompanyName", "Telegram FZ-LLC"
VALUE "FileDescription", "Telegram Desktop"
VALUE "FileVersion", "3.2.8.0"
VALUE "FileVersion", "3.3.0.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2021"
VALUE "ProductName", "Telegram Desktop"
VALUE "ProductVersion", "3.2.8.0"
VALUE "ProductVersion", "3.3.0.0"
END
END
BLOCK "VarFileInfo"

View File

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

View File

@@ -8,7 +8,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <cstdio>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/sendfile.h>
#include <cstdlib>
#include <unistd.h>
#include <dirent.h>
@@ -98,6 +97,11 @@ bool copyFile(const char *from, const char *to, bool writeprotected) {
fclose(ffrom);
return false;
}
static const int BufSize = 65536;
char buf[BufSize];
while (size_t size = fread(buf, 1, BufSize, ffrom)) {
fwrite(buf, 1, size, fto);
}
struct stat fst; // from http://stackoverflow.com/questions/5486774/keeping-fileowner-and-permissions-after-copying-file-in-c
//let's say this wont fail since you already worked OK on that fp
@@ -106,33 +110,6 @@ bool copyFile(const char *from, const char *to, bool writeprotected) {
fclose(fto);
return false;
}
ssize_t copied = sendfile(
fileno(fto),
fileno(ffrom),
nullptr,
fst.st_size);
if (copied == -1) {
writeLog(
"Copy by sendfile '%s' to '%s' failed, error: %d, fallback now.",
from,
to,
int(errno));
static const int BufSize = 65536;
char buf[BufSize];
while (size_t size = fread(buf, 1, BufSize, ffrom)) {
fwrite(buf, 1, size, fto);
}
} else {
writeLog(
"Copy by sendfile '%s' to '%s' done, size: %d, result: %d.",
from,
to,
int(fst.st_size),
int(copied));
}
//update to the same uid/gid
if (!writeprotected && fchown(fileno(fto), fst.st_uid, fst.st_gid) != 0) {
fclose(ffrom);

View File

@@ -662,7 +662,7 @@ UserData *ParticipantsAdditionalData::applyCreator(
} else {
_adminCanEdit.erase(user);
}
if (data.rank().isEmpty()) {
if (!data.rank().isEmpty()) {
_adminRanks[user] = data.rank();
} else {
_adminRanks.remove(user);
@@ -693,7 +693,7 @@ UserData *ParticipantsAdditionalData::applyAdmin(
} else {
_adminCanEdit.erase(user);
}
if (data.rank().isEmpty()) {
if (!data.rank().isEmpty()) {
_adminRanks[user] = data.rank();
} else {
_adminRanks.remove(user);

View File

@@ -78,8 +78,8 @@ public:
: tr::lng_manage_peer_channel_type();
}
[[nodiscard]] bool isAllowSave() {
return _isAllowSave;
[[nodiscard]] bool goodUsername() const {
return _goodUsername;
}
[[nodiscard]] Privacy getPrivacy() const {
@@ -144,7 +144,7 @@ private:
bool _useLocationPhrases = false;
bool _isGroup = false;
bool _isAllowSave = false;
bool _goodUsername = false;
base::unique_qptr<Ui::VerticalLayout> _wrap;
base::Timer _checkUsernameTimer;
@@ -171,7 +171,8 @@ Controller::Controller(
, _noForwardsSavedValue(noForwardsSavedValue)
, _useLocationPhrases(useLocationPhrases)
, _isGroup(_peer->isChat() || _peer->isMegagroup())
, _isAllowSave(!_usernameSavedValue.value_or(QString()).isEmpty())
, _goodUsername(!_usernameSavedValue.value_or(
_peer->isChannel() ? _peer->asChannel()->username : QString()).isEmpty())
, _wrap(container)
, _checkUsernameTimer([=] { checkUsernameAvailability(); }) {
_peer->updateFull();
@@ -236,7 +237,8 @@ void Controller::createContent() {
if (_controls.privacy->value() == Privacy::NoUsername) {
checkUsernameAvailability();
}
const auto forShowing = _privacySavedValue.value_or(Privacy::NoUsername);
const auto forShowing = _privacySavedValue.value_or(
Privacy::NoUsername);
_controls.inviteLinkWrap->toggle(
(forShowing != Privacy::HasUsername),
anim::type::instant);
@@ -333,8 +335,8 @@ object_ptr<Ui::RpWidget> Controller::createUsernameEdit() {
Expects(_wrap != nullptr);
const auto channel = _peer->asChannel();
const auto username =
_usernameSavedValue.value_or(channel ? channel->username : QString());
const auto username = _usernameSavedValue.value_or(
channel ? channel->username : QString());
auto result = object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
_wrap,
@@ -505,7 +507,7 @@ void Controller::askUsernameRevoke() {
}
void Controller::usernameChanged() {
_isAllowSave = false;
_goodUsername = false;
const auto username = getUsernameInput();
if (username.isEmpty()) {
_controls.usernameResult = nullptr;
@@ -529,12 +531,12 @@ void Controller::usernameChanged() {
}
void Controller::showUsernameError(rpl::producer<QString> &&error) {
_isAllowSave = false;
_goodUsername = false;
showUsernameResult(std::move(error), &st::editPeerUsernameError);
}
void Controller::showUsernameGood() {
_isAllowSave = true;
_goodUsername = true;
showUsernameResult(
tr::lng_create_channel_link_available(),
&st::editPeerUsernameGood);
@@ -655,7 +657,7 @@ void EditPeerTypeBox::prepare() {
if (_savedCallback.has_value()) {
addButton(tr::lng_settings_save(), [=] {
const auto v = controller->getPrivacy();
if (!controller->isAllowSave() && (v == Privacy::HasUsername)) {
if ((v == Privacy::HasUsername) && !controller->goodUsername()) {
controller->setFocusUsername();
return;
}

View File

@@ -550,11 +550,6 @@ QRect Row::elementGeometry(int element, int outerWidth) const {
const auto size = QSize(
st::sessionTerminate.width,
st::sessionTerminate.height);
const auto margins = QMargins(
0,
(st::sessionListItem.height - size.height()) / 2,
st::sessionListThreeDotsSkip,
0);
const auto right = st::sessionTerminateSkip;
const auto top = st::sessionTerminateTop;
const auto left = outerWidth - right - size.width();

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 = 3002008;
constexpr auto AppVersionStr = "3.2.8";
constexpr auto AppBetaVersion = true;
constexpr auto AppVersion = 3003000;
constexpr auto AppVersionStr = "3.3";
constexpr auto AppBetaVersion = false;
constexpr auto AppAlphaVersion = TDESKTOP_ALPHA_VERSION;

View File

@@ -99,13 +99,19 @@ bool CloudImage::failed() const {
return (_file.flags & CloudFile::Flag::Failed);
}
bool CloudImage::loadedOnce() const {
return (_file.flags & CloudFile::Flag::Loaded);
}
void CloudImage::load(not_null<Main::Session*> session, FileOrigin origin) {
const auto autoLoading = false;
const auto finalCheck = [=] {
if (const auto active = activeView()) {
return !active->image();
} else if (_file.flags & CloudFile::Flag::Loaded) {
return false;
}
return true;
return !(_file.flags & CloudFile::Flag::Loaded);
};
const auto done = [=](QImage result) {
if (const auto active = activeView()) {
@@ -247,6 +253,7 @@ void LoadCloudFile(
if (!file.loader || file.loader->cancelled()) {
file.flags |= CloudFile::Flag::Cancelled;
} else {
file.flags |= CloudFile::Flag::Loaded;
done(file);
}
// NB! file.loader may be in ~FileLoader() already.

View File

@@ -31,6 +31,7 @@ struct CloudFile final {
enum class Flag : uchar {
Cancelled = 0x01,
Failed = 0x02,
Loaded = 0x04,
};
friend inline constexpr bool is_flag_type(Flag) { return true; };
@@ -73,6 +74,7 @@ public:
[[nodiscard]] bool empty() const;
[[nodiscard]] bool loading() const;
[[nodiscard]] bool failed() const;
[[nodiscard]] bool loadedOnce() const;
void load(not_null<Main::Session*> session, FileOrigin origin);
[[nodiscard]] const ImageLocation &location() const;
[[nodiscard]] int byteSize() const;

View File

@@ -1084,13 +1084,19 @@ bool DocumentData::isStickerSetInstalled() const {
}
}
Image *DocumentData::getReplyPreview(Data::FileOrigin origin) {
Image *DocumentData::getReplyPreview(
Data::FileOrigin origin,
not_null<PeerData*> context) {
if (!hasThumbnail()) {
return nullptr;
} else if (!_replyPreview) {
_replyPreview = std::make_unique<Data::ReplyPreview>(this);
}
return _replyPreview->image(origin);
return _replyPreview->image(origin, context);
}
Image *DocumentData::getReplyPreview(not_null<HistoryItem*> item) {
return getReplyPreview(item->fullId(), item->history()->peer);
}
bool DocumentData::replyPreviewLoaded() const {

View File

@@ -115,7 +115,8 @@ public:
void setWaitingForAlbum();
[[nodiscard]] bool waitingForAlbum() const;
[[nodiscard]] const Core::FileLocation &location(bool check = false) const;
[[nodiscard]] const Core::FileLocation &location(
bool check = false) const;
void setLocation(const Core::FileLocation &loc);
bool saveFromData();
@@ -124,7 +125,10 @@ public:
[[nodiscard]] bool saveToCache() const;
[[nodiscard]] Image *getReplyPreview(Data::FileOrigin origin);
[[nodiscard]] Image *getReplyPreview(
Data::FileOrigin origin,
not_null<PeerData*> context);
[[nodiscard]] Image *getReplyPreview(not_null<HistoryItem*> item);
[[nodiscard]] bool replyPreviewLoaded() const;
[[nodiscard]] StickerData *sticker() const;

View File

@@ -164,18 +164,8 @@ using ItemPreviewImage = HistoryView::ItemPreviewImage;
} else if (const auto large = media->image(PhotoSize::Large)) {
return { PreparePreviewImage(large, radius), readyCacheKey };
}
const auto allowedToDownload = [&] {
const auto photo = media->owner();
if (media->loaded() || photo->cancelled()) {
return false;
}
return photo->hasExact(PhotoSize::Small)
|| photo->hasExact(PhotoSize::Thumbnail)
|| AutoDownload::Should(
photo->session().settings().autoDownload(),
item->history()->peer,
photo);
}();
const auto allowedToDownload = media->autoLoadThumbnailAllowed(
item->history()->peer);
const auto cacheKey = allowedToDownload ? 0 : readyCacheKey;
if (allowedToDownload) {
media->owner()->load(PhotoSize::Small, item->fullId());
@@ -533,7 +523,7 @@ bool MediaPhoto::hasReplyPreview() const {
}
Image *MediaPhoto::replyPreview() const {
return _photo->getReplyPreview(parent()->fullId());
return _photo->getReplyPreview(parent());
}
bool MediaPhoto::replyPreviewLoaded() const {
@@ -738,7 +728,7 @@ bool MediaFile::hasReplyPreview() const {
}
Image *MediaFile::replyPreview() const {
return _document->getReplyPreview(parent()->fullId());
return _document->getReplyPreview(parent());
}
bool MediaFile::replyPreviewLoaded() const {
@@ -1295,9 +1285,9 @@ bool MediaWebPage::hasReplyPreview() const {
Image *MediaWebPage::replyPreview() const {
if (const auto document = MediaWebPage::document()) {
return document->getReplyPreview(parent()->fullId());
return document->getReplyPreview(parent());
} else if (const auto photo = MediaWebPage::photo()) {
return photo->getReplyPreview(parent()->fullId());
return photo->getReplyPreview(parent());
}
return nullptr;
}
@@ -1368,9 +1358,9 @@ bool MediaGame::hasReplyPreview() const {
Image *MediaGame::replyPreview() const {
if (const auto document = _game->document) {
return document->getReplyPreview(parent()->fullId());
return document->getReplyPreview(parent());
} else if (const auto photo = _game->photo) {
return photo->getReplyPreview(parent()->fullId());
return photo->getReplyPreview(parent());
}
return nullptr;
}
@@ -1478,7 +1468,7 @@ bool MediaInvoice::hasReplyPreview() const {
Image *MediaInvoice::replyPreview() const {
if (const auto photo = _invoice.photo) {
return photo->getReplyPreview(parent()->fullId());
return photo->getReplyPreview(parent());
}
return nullptr;
}

View File

@@ -795,6 +795,13 @@ QString PeerData::userName() const {
return QString();
}
bool PeerData::isSelf() const {
if (const auto user = asUser()) {
return (user->flags() & UserDataFlag::Self);
}
return false;
}
bool PeerData::isVerified() const {
if (const auto user = asUser()) {
return user->isVerified();

View File

@@ -164,9 +164,7 @@ public:
[[nodiscard]] bool isChannel() const {
return peerIsChannel(id);
}
[[nodiscard]] bool isSelf() const {
return (input.type() == mtpc_inputPeerSelf);
}
[[nodiscard]] bool isSelf() const;
[[nodiscard]] bool isVerified() const;
[[nodiscard]] bool isScam() const;
[[nodiscard]] bool isFake() const;

View File

@@ -13,6 +13,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_photo_media.h"
#include "ui/image/image.h"
#include "main/main_session.h"
#include "history/history.h"
#include "history/history_item.h"
#include "media/streaming/media_streaming_loader_local.h"
#include "media/streaming/media_streaming_loader_mtproto.h"
#include "mainwidget.h"
@@ -206,11 +208,17 @@ bool PhotoData::uploading() const {
return (uploadingData != nullptr);
}
Image *PhotoData::getReplyPreview(Data::FileOrigin origin) {
Image *PhotoData::getReplyPreview(
Data::FileOrigin origin,
not_null<PeerData*> context) {
if (!_replyPreview) {
_replyPreview = std::make_unique<Data::ReplyPreview>(this);
}
return _replyPreview->image(origin);
return _replyPreview->image(origin, context);
}
Image *PhotoData::getReplyPreview(not_null<HistoryItem*> item) {
return getReplyPreview(item->fullId(), item->history()->peer);
}
bool PhotoData::replyPreviewLoaded() const {

View File

@@ -64,7 +64,10 @@ public:
void setWaitingForAlbum();
[[nodiscard]] bool waitingForAlbum() const;
[[nodiscard]] Image *getReplyPreview(Data::FileOrigin origin);
[[nodiscard]] Image *getReplyPreview(
Data::FileOrigin origin,
not_null<PeerData*> context);
[[nodiscard]] Image *getReplyPreview(not_null<HistoryItem*> item);
[[nodiscard]] bool replyPreviewLoaded() const;
void setRemoteLocation(

View File

@@ -128,6 +128,18 @@ float64 PhotoMedia::progress() const {
: (loaded() ? 1. : 0.);
}
bool PhotoMedia::autoLoadThumbnailAllowed(not_null<PeerData*> peer) const {
if (loaded() || _owner->cancelled()) {
return false;
}
return _owner->hasExact(PhotoSize::Small)
|| _owner->hasExact(PhotoSize::Thumbnail)
|| AutoDownload::Should(
_owner->session().settings().autoDownload(),
peer,
_owner);
}
void PhotoMedia::automaticLoad(
Data::FileOrigin origin,
const HistoryItem *item) {

View File

@@ -36,6 +36,8 @@ public:
[[nodiscard]] bool loaded() const;
[[nodiscard]] float64 progress() const;
[[nodiscard]] bool autoLoadThumbnailAllowed(
not_null<PeerData*> peer) const;
void automaticLoad(Data::FileOrigin origin, const HistoryItem *item);
void collectLocalData(not_null<PhotoMedia*> local);

View File

@@ -55,7 +55,9 @@ void ReplyPreview::prepare(not_null<Image*> image, Images::Options options) {
_good = ((options & Images::Option::Blurred) == 0);
}
Image *ReplyPreview::image(Data::FileOrigin origin) {
Image *ReplyPreview::image(
Data::FileOrigin origin,
not_null<PeerData*> context) {
if (_checked) {
return _image.get();
}
@@ -84,8 +86,13 @@ Image *ReplyPreview::image(Data::FileOrigin origin) {
} else {
Assert(_photo != nullptr);
if (!_image || !_good) {
const auto inlineThumbnailBytes = _photo->inlineThumbnailBytes();
if (!_photoMedia) {
_photoMedia = _photo->createMediaView();
}
const auto loadThumbnail = inlineThumbnailBytes.isEmpty()
|| _photoMedia->autoLoadThumbnailAllowed(context);
if (loadThumbnail) {
_photoMedia->wanted(PhotoSize::Small, origin);
}
if (const auto small = _photoMedia->image(PhotoSize::Small)) {

View File

@@ -23,7 +23,9 @@ public:
explicit ReplyPreview(not_null<PhotoData*> photo);
~ReplyPreview();
[[nodiscard]] Image *image(Data::FileOrigin origin);
[[nodiscard]] Image *image(
Data::FileOrigin origin,
not_null<PeerData*> context);
[[nodiscard]] bool loaded() const;
private:

View File

@@ -85,6 +85,10 @@ std::optional<MTPmessages_Search> PrepareSearchRequest(
}();
const auto hash = uint64(0);
const auto mtpOffsetId = int(std::clamp(
offsetId.bare,
int64(0),
int64(0x3FFFFFFF)));
return MTPmessages_Search(
MTP_flags(0),
peer->input,
@@ -94,7 +98,7 @@ std::optional<MTPmessages_Search> PrepareSearchRequest(
filter,
MTP_int(0), // min_date
MTP_int(0), // max_date
MTP_int(offsetId),
MTP_int(mtpOffsetId),
MTP_int(addOffset),
MTP_int(limit),
MTP_int(maxId),

View File

@@ -782,10 +782,6 @@ private:
PhotoData *photo,
DocumentData *document);
void folderApplyFields(
not_null<Folder*> folder,
const MTPDfolder &data);
void setPinnedFromDialog(const Dialogs::Key &key, bool pinned);
NotifySettings &defaultNotifySettings(not_null<const PeerData*> peer);

View File

@@ -25,7 +25,8 @@ using UpdateFlag = Data::PeerUpdate::Flag;
} // namespace
UserData::UserData(not_null<Data::Session*> owner, PeerId id)
: PeerData(owner, id) {
: PeerData(owner, id)
, _flags((id == owner->session().userPeerId()) ? Flag::Self : Flag(0)) {
}
bool UserData::canShareThisContact() const {
@@ -173,6 +174,19 @@ void UserData::setAccessHash(uint64 accessHash) {
}
}
void UserData::setFlags(UserDataFlags which) {
_flags.set((flags() & UserDataFlag::Self)
| (which & ~UserDataFlag::Self));
}
void UserData::addFlags(UserDataFlags which) {
_flags.add(which & ~UserDataFlag::Self);
}
void UserData::removeFlags(UserDataFlags which) {
_flags.remove(which & ~UserDataFlag::Self);
}
void UserData::setCallsStatus(CallsStatus callsStatus) {
if (callsStatus != _callsStatus) {
_callsStatus = callsStatus;

View File

@@ -37,6 +37,7 @@ enum class UserDataFlag {
Support = (1 << 10),
CanPinMessages = (1 << 11),
DiscardMinPhoto = (1 << 12),
Self = (1 << 13),
};
inline constexpr bool is_flag_type(UserDataFlag) { return true; };
using UserDataFlags = base::flags<UserDataFlag>;
@@ -68,21 +69,15 @@ public:
}
void setAccessHash(uint64 accessHash);
void setFlags(UserDataFlags which) {
_flags.set(which);
}
void addFlags(UserDataFlags which) {
_flags.add(which);
}
void removeFlags(UserDataFlags which) {
_flags.remove(which);
}
auto flags() const {
return _flags.current();
}
auto flagsValue() const {
return _flags.value();
}
void setFlags(UserDataFlags which);
void addFlags(UserDataFlags which);
void removeFlags(UserDataFlags which);
[[nodiscard]] bool isVerified() const {
return flags() & UserDataFlag::Verified;

View File

@@ -101,8 +101,8 @@ dialogsMenuToggle: IconButton {
width: 40px;
height: 40px;
icon: icon {{ "dialogs_menu", dialogsMenuIconFg }};
iconOver: icon {{ "dialogs_menu", dialogsMenuIconFgOver }};
icon: icon {{ "dialogs/dialogs_menu", dialogsMenuIconFg }};
iconOver: icon {{ "dialogs/dialogs_menu", dialogsMenuIconFgOver }};
iconPosition: point(-1px, -1px);
rippleAreaPosition: point(0px, 0px);
@@ -112,32 +112,32 @@ dialogsMenuToggle: IconButton {
}
}
dialogsMenuToggleUnread: icon {
{ "dialogs_menu_unread", dialogsMenuIconFg },
{ "dialogs_menu_unread_dot", dialogsUnreadBg },
{ "dialogs/dialogs_menu_unread", dialogsMenuIconFg },
{ "dialogs/dialogs_menu_unread_dot", dialogsUnreadBg },
};
dialogsMenuToggleUnreadMuted: icon {
{ "dialogs_menu_unread", dialogsMenuIconFg },
{ "dialogs_menu_unread_dot", dialogsMenuIconFg },
{ "dialogs/dialogs_menu_unread", dialogsMenuIconFg },
{ "dialogs/dialogs_menu_unread_dot", dialogsMenuIconFg },
};
dialogsLock: IconButton(dialogsMenuToggle) {
icon: icon {{ "dialogs_lock", dialogsMenuIconFg }};
iconOver: icon {{ "dialogs_lock", dialogsMenuIconFgOver }};
icon: icon {{ "dialogs/dialogs_lock", dialogsMenuIconFg }};
iconOver: icon {{ "dialogs/dialogs_lock", dialogsMenuIconFgOver }};
}
dialogsUnlockIcon: icon {{ "dialogs_unlock", dialogsMenuIconFg }};
dialogsUnlockIconOver: icon {{ "dialogs_unlock", dialogsMenuIconFgOver }};
dialogsUnlockIcon: icon {{ "dialogs/dialogs_unlock", dialogsMenuIconFg }};
dialogsUnlockIconOver: icon {{ "dialogs/dialogs_unlock", dialogsMenuIconFgOver }};
dialogsCalendar: IconButton {
width: 29px;
height: 32px;
icon: icon {{ "dialogs_calendar", dialogsMenuIconFg }};
iconOver: icon {{ "dialogs_calendar", dialogsMenuIconFgOver }};
icon: icon {{ "dialogs/dialogs_calendar", dialogsMenuIconFg }};
iconOver: icon {{ "dialogs/dialogs_calendar", dialogsMenuIconFgOver }};
iconPosition: point(0px, 5px);
}
dialogsSearchFrom: IconButton(dialogsCalendar) {
width: 26px;
icon: icon {{ "dialogs_search_from", dialogsMenuIconFg }};
iconOver: icon {{ "dialogs_search_from", dialogsMenuIconFgOver }};
icon: icon {{ "dialogs/dialogs_search_from", dialogsMenuIconFg }};
iconOver: icon {{ "dialogs/dialogs_search_from", dialogsMenuIconFgOver }};
}
dialogsSearchForNarrowFilters: IconButton(dialogsMenuToggle) {
icon: icon {{ "top_bar_search", menuIconFg }};
@@ -154,8 +154,8 @@ dialogsFilter: FlatInput(defaultFlatInput) {
textMrg: margins(12px, 3px, 30px, 3px);
}
dialogsCancelSearchInPeer: IconButton(dialogsMenuToggle) {
icon: icon {{ "dialogs_cancel_search", dialogsMenuIconFg }};
iconOver: icon {{ "dialogs_cancel_search", dialogsMenuIconFgOver }};
icon: icon {{ "dialogs/dialogs_cancel_search", dialogsMenuIconFg }};
iconOver: icon {{ "dialogs/dialogs_cancel_search", dialogsMenuIconFgOver }};
iconPosition: point(11px, 11px);
rippleAreaPosition: point(3px, 3px);
rippleAreaSize: 34px;
@@ -180,49 +180,49 @@ dialogsCancelSearch: CrossButton {
}
dialogsChatTypeSkip: 22px;
dialogsChatIcon: icon {{ "dialogs_chat", dialogsChatIconFg, point(1px, 4px) }};
dialogsChatIconOver: icon {{ "dialogs_chat", dialogsChatIconFgOver, point(1px, 4px) }};
dialogsChatIconActive: icon {{ "dialogs_chat", dialogsChatIconFgActive, point(1px, 4px) }};
dialogsChannelIcon: icon {{ "dialogs_channel", dialogsChatIconFg, point(3px, 4px) }};
dialogsChannelIconOver: icon {{ "dialogs_channel", dialogsChatIconFgOver, point(3px, 4px) }};
dialogsChannelIconActive: icon {{ "dialogs_channel", dialogsChatIconFgActive, point(3px, 4px) }};
dialogsBotIcon: icon {{ "dialogs_bot", dialogsChatIconFg, point(1px, 3px) }};
dialogsBotIconOver: icon {{ "dialogs_bot", dialogsChatIconFgOver, point(1px, 3px) }};
dialogsBotIconActive: icon {{ "dialogs_bot", dialogsChatIconFgActive, point(1px, 3px) }};
dialogsChatIcon: icon {{ "dialogs/dialogs_chat", dialogsChatIconFg, point(1px, 4px) }};
dialogsChatIconOver: icon {{ "dialogs/dialogs_chat", dialogsChatIconFgOver, point(1px, 4px) }};
dialogsChatIconActive: icon {{ "dialogs/dialogs_chat", dialogsChatIconFgActive, point(1px, 4px) }};
dialogsChannelIcon: icon {{ "dialogs/dialogs_channel", dialogsChatIconFg, point(3px, 4px) }};
dialogsChannelIconOver: icon {{ "dialogs/dialogs_channel", dialogsChatIconFgOver, point(3px, 4px) }};
dialogsChannelIconActive: icon {{ "dialogs/dialogs_channel", dialogsChatIconFgActive, point(3px, 4px) }};
dialogsBotIcon: icon {{ "dialogs/dialogs_bot", dialogsChatIconFg, point(1px, 3px) }};
dialogsBotIconOver: icon {{ "dialogs/dialogs_bot", dialogsChatIconFgOver, point(1px, 3px) }};
dialogsBotIconActive: icon {{ "dialogs/dialogs_bot", dialogsChatIconFgActive, point(1px, 3px) }};
dialogsArchiveUserpic: icon {{ "archive_userpic", historyPeerUserpicFg }};
dialogsRepliesUserpic: icon {{ "replies_userpic", historyPeerUserpicFg }};
dialogsSendStateSkip: 20px;
dialogsSendingIcon: icon {{ "dialogs_sending", dialogsSendingIconFg, point(8px, 4px) }};
dialogsSendingIconOver: icon {{ "dialogs_sending", dialogsSendingIconFgOver, point(8px, 4px) }};
dialogsSendingIconActive: icon {{ "dialogs_sending", dialogsSendingIconFgActive, point(8px, 4px) }};
dialogsSentIcon: icon {{ "dialogs_sent", dialogsSentIconFg, point(10px, 4px) }};
dialogsSentIconOver: icon {{ "dialogs_sent", dialogsSentIconFgOver, point(10px, 4px) }};
dialogsSentIconActive: icon {{ "dialogs_sent", dialogsSentIconFgActive, point(10px, 4px) }};
dialogsReceivedIcon: icon {{ "dialogs_received", dialogsSentIconFg, point(5px, 4px) }};
dialogsReceivedIconOver: icon {{ "dialogs_received", dialogsSentIconFgOver, point(5px, 4px) }};
dialogsReceivedIconActive: icon {{ "dialogs_received", dialogsSentIconFgActive, point(5px, 4px) }};
dialogsPinnedIcon: icon {{ "dialogs_pinned", dialogsUnreadBgMuted }};
dialogsPinnedIconOver: icon {{ "dialogs_pinned", dialogsUnreadBgMutedOver }};
dialogsPinnedIconActive: icon {{ "dialogs_pinned", dialogsUnreadBgMutedActive }};
dialogsSendingIcon: icon {{ "dialogs/dialogs_sending", dialogsSendingIconFg, point(8px, 4px) }};
dialogsSendingIconOver: icon {{ "dialogs/dialogs_sending", dialogsSendingIconFgOver, point(8px, 4px) }};
dialogsSendingIconActive: icon {{ "dialogs/dialogs_sending", dialogsSendingIconFgActive, point(8px, 4px) }};
dialogsSentIcon: icon {{ "dialogs/dialogs_sent", dialogsSentIconFg, point(10px, 4px) }};
dialogsSentIconOver: icon {{ "dialogs/dialogs_sent", dialogsSentIconFgOver, point(10px, 4px) }};
dialogsSentIconActive: icon {{ "dialogs/dialogs_sent", dialogsSentIconFgActive, point(10px, 4px) }};
dialogsReceivedIcon: icon {{ "dialogs/dialogs_received", dialogsSentIconFg, point(5px, 4px) }};
dialogsReceivedIconOver: icon {{ "dialogs/dialogs_received", dialogsSentIconFgOver, point(5px, 4px) }};
dialogsReceivedIconActive: icon {{ "dialogs/dialogs_received", dialogsSentIconFgActive, point(5px, 4px) }};
dialogsPinnedIcon: icon {{ "dialogs/dialogs_pinned", dialogsUnreadBgMuted }};
dialogsPinnedIconOver: icon {{ "dialogs/dialogs_pinned", dialogsUnreadBgMutedOver }};
dialogsPinnedIconActive: icon {{ "dialogs/dialogs_pinned", dialogsUnreadBgMutedActive }};
dialogsVerifiedIcon: icon {
{ "dialogs_verified_star", dialogsVerifiedIconBg, point(4px, 2px) },
{ "dialogs_verified_check", dialogsVerifiedIconFg, point(7px, 7px) },
{ "dialogs/dialogs_verified_star", dialogsVerifiedIconBg },
{ "dialogs/dialogs_verified_check", dialogsVerifiedIconFg },
};
dialogsVerifiedIconOver: icon {
{ "dialogs_verified_star", dialogsVerifiedIconBgOver, point(4px, 2px) },
{ "dialogs_verified_check", dialogsVerifiedIconFgOver, point(7px, 7px) },
{ "dialogs/dialogs_verified_star", dialogsVerifiedIconBgOver },
{ "dialogs/dialogs_verified_check", dialogsVerifiedIconFgOver },
};
dialogsVerifiedIconActive: icon {
{ "dialogs_verified_star", dialogsVerifiedIconBgActive, point(4px, 2px) },
{ "dialogs_verified_check", dialogsVerifiedIconFgActive, point(7px, 7px) },
{ "dialogs/dialogs_verified_star", dialogsVerifiedIconBgActive },
{ "dialogs/dialogs_verified_check", dialogsVerifiedIconFgActive },
};
historySendingIcon: icon {{ "dialogs_sending", historySendingOutIconFg, point(5px, 5px) }};
historySendingInvertedIcon: icon {{ "dialogs_sending", historySendingInvertedIconFg, point(5px, 5px) }};
historyViewsSendingIcon: icon {{ "dialogs_sending", historySendingInIconFg, point(3px, 0px) }};
historyViewsSendingInvertedIcon: icon {{ "dialogs_sending", historySendingInvertedIconFg, point(3px, 0px) }};
historySendingIcon: icon {{ "dialogs/dialogs_sending", historySendingOutIconFg, point(5px, 5px) }};
historySendingInvertedIcon: icon {{ "dialogs/dialogs_sending", historySendingInvertedIconFg, point(5px, 5px) }};
historyViewsSendingIcon: icon {{ "dialogs/dialogs_sending", historySendingInIconFg, point(3px, 0px) }};
historyViewsSendingInvertedIcon: icon {{ "dialogs/dialogs_sending", historySendingInvertedIconFg, point(3px, 0px) }};
dialogsUpdateButton: FlatButton {
color: activeButtonFg;

View File

@@ -63,8 +63,8 @@ Data::Folder *Entry::asFolder() {
return _isFolder ? static_cast<Data::Folder*>(this) : nullptr;
}
void Entry::pinnedIndexChanged(int was, int now) {
if (session().supportMode()) {
void Entry::pinnedIndexChanged(FilterId filterId, int was, int now) {
if (!filterId && session().supportMode()) {
// Force reorder in support mode.
_sortKeyInChatList = 0;
}
@@ -83,15 +83,12 @@ void Entry::cachePinnedIndex(FilterId filterId, int index) {
}
if (!index) {
_pinnedIndex.erase(i);
pinnedIndexChanged(was, index);
} else if (!was) {
_pinnedIndex.emplace(filterId, index);
} else {
if (!was) {
_pinnedIndex.emplace(filterId, index);
} else {
i->second = index;
}
pinnedIndexChanged(was, index);
i->second = index;
}
pinnedIndexChanged(filterId, was, index);
}
void Entry::cacheTopPromoted(bool promoted) {

View File

@@ -205,7 +205,7 @@ protected:
private:
virtual void changedChatListPinHook();
void pinnedIndexChanged(int was, int now);
void pinnedIndexChanged(FilterId filterId, int was, int now);
[[nodiscard]] uint64 computeSortPosition(FilterId filterId) const;
void setChatListExistence(bool exists);

View File

@@ -42,6 +42,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "main/main_session.h"
#include "main/main_session_settings.h"
#include "window/notifications_manager.h"
#include "window/window_controller.h"
#include "window/window_session_controller.h"
#include "window/window_peer_menu.h"
#include "ui/widgets/multi_select.h"
@@ -3011,7 +3012,9 @@ void InnerWidget::updateRowCornerStatusShown(
void InnerWidget::setupShortcuts() {
Shortcuts::Requests(
) | rpl::filter([=] {
return isActiveWindow() && !Ui::isLayerShown();
return isActiveWindow()
&& !Ui::isLayerShown()
&& !_controller->window().locked();
}) | rpl::start_with_next([=](not_null<Shortcuts::Request*> request) {
using Command = Shortcuts::Command;

View File

@@ -1160,8 +1160,9 @@ void InnerWidget::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
auto lnkIsVideo = lnkDocument ? lnkDocument->document()->isVideoFile() : false;
auto lnkIsVoice = lnkDocument ? lnkDocument->document()->isVoiceMessage() : false;
auto lnkIsAudio = lnkDocument ? lnkDocument->document()->isAudioFile() : false;
const auto fromId = PeerId(
link->property(kPeerLinkPeerIdProperty).toULongLong());
const auto fromId = PeerId(link
? link->property(kPeerLinkPeerIdProperty).toULongLong()
: 0);
if (lnkPhoto || lnkDocument) {
if (isUponSelected > 0) {
_menu->addAction(tr::lng_context_copy_selected(tr::now), [=] {

View File

@@ -343,6 +343,10 @@ public:
[[nodiscard]] virtual TextWithEntities originalText() const {
return TextWithEntities();
}
[[nodiscard]] virtual auto originalTextWithLocalEntities() const
-> TextWithEntities {
return TextWithEntities();
}
[[nodiscard]] virtual TextForMimeData clipboardText() const {
return TextForMimeData();
}

View File

@@ -135,6 +135,8 @@ HiddenSenderInfo::HiddenSenderInfo(const QString &name, bool external)
(external
? Ui::EmptyUserpic::ExternalName()
: name)) {
Expects(!name.isEmpty());
nameText.setText(st::msgNameStyle, name, Ui::NameTextOptions());
const auto parts = name.trimmed().split(' ', Qt::SkipEmptyParts);
firstName = parts[0];

View File

@@ -1176,8 +1176,13 @@ void HistoryMessage::setupForwardedComponent(const CreateConfig &config) {
return;
}
forwarded->originalDate = config.originalDate;
forwarded->originalSender = config.senderOriginal
? history()->owner().peer(config.senderOriginal).get()
const auto originalSender = config.senderOriginal
? config.senderOriginal
: !config.senderNameOriginal.isEmpty()
? PeerId()
: from()->id;
forwarded->originalSender = originalSender
? history()->owner().peer(originalSender).get()
: nullptr;
if (!forwarded->originalSender) {
forwarded->hiddenSenderInfo = std::make_unique<HiddenSenderInfo>(
@@ -1531,19 +1536,31 @@ Storage::SharedMediaTypesMask HistoryMessage::sharedMediaTypes() const {
}
bool HistoryMessage::generateLocalEntitiesByReply() const {
using namespace HistoryView;
if (!_media) {
return true;
} else if (const auto document = _media->document()) {
return !DurationForTimestampLinks(document);
} else if (const auto webpage = _media->webpage()) {
return !webpage->document && webpage->type != WebPageType::Video;
return (webpage->type != WebPageType::Video)
&& !DurationForTimestampLinks(webpage);
}
return false;
return true;
}
TextWithEntities HistoryMessage::withLocalEntities(
const TextWithEntities &textWithEntities) const {
using namespace HistoryView;
if (!generateLocalEntitiesByReply()) {
if (const auto webpage = _media ? _media->webpage() : nullptr) {
if (!_media) {
} else if (const auto document = _media->document()) {
if (const auto duration = DurationForTimestampLinks(document)) {
return AddTimestampLinks(
textWithEntities,
duration,
TimestampLinkBase(document, fullId()));
}
} else if (const auto webpage = _media->webpage()) {
if (const auto duration = DurationForTimestampLinks(webpage)) {
return AddTimestampLinks(
textWithEntities,
@@ -1707,6 +1724,10 @@ TextWithEntities HistoryMessage::originalText() const {
return _text.toTextWithEntities();
}
TextWithEntities HistoryMessage::originalTextWithLocalEntities() const {
return withLocalEntities(originalText());
}
TextForMimeData HistoryMessage::clipboardText() const {
if (emptyText()) {
return TextForMimeData();

View File

@@ -173,6 +173,8 @@ public:
void setText(const TextWithEntities &textWithEntities) override;
[[nodiscard]] Ui::Text::IsolatedEmoji isolatedEmoji() const override;
[[nodiscard]] TextWithEntities originalText() const override;
[[nodiscard]] auto originalTextWithLocalEntities() const
-> TextWithEntities override;
[[nodiscard]] TextForMimeData clipboardText() const override;
[[nodiscard]] bool textHasLinks() const override;

View File

@@ -7162,7 +7162,7 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) {
textTop,
st::msgReplyBarSize.height(),
st::msgReplyBarSize.height());
if (HistoryView::DrawWebPageDataPreview(p, _previewData, to)) {
if (HistoryView::DrawWebPageDataPreview(p, _previewData, _peer, to)) {
previewLeft += st::msgReplyBarSize.height()
+ st::msgReplyBarSkip
- st::msgReplyBarSize.width()

View File

@@ -105,6 +105,7 @@ class FieldHeader final : public Ui::RpWidget {
public:
FieldHeader(QWidget *parent, not_null<Data::Session*> data);
void setHistory(const SetHistoryArgs &args);
void init();
void editMessage(FullMsgId id);
@@ -142,7 +143,7 @@ private:
void resolveMessageData();
void updateShownMessageText();
void paintWebPage(Painter &p);
void paintWebPage(Painter &p, not_null<PeerData*> peer);
void paintEditOrReplyToMessage(Painter &p);
struct Preview {
@@ -152,6 +153,7 @@ private:
bool cancelled = false;
};
History *_history = nullptr;
rpl::variable<QString> _title;
rpl::variable<QString> _description;
@@ -188,6 +190,10 @@ FieldHeader::FieldHeader(QWidget *parent, not_null<Data::Session*> data)
init();
}
void FieldHeader::setHistory(const SetHistoryArgs &args) {
_history = *args.history;
}
void FieldHeader::init() {
sizeValue(
) | rpl::start_with_next([=](QSize size) {
@@ -209,7 +215,9 @@ void FieldHeader::init() {
(!ShowWebPagePreview(_preview.data) || *leftIconPressed)
? paintEditOrReplyToMessage(p)
: paintWebPage(p);
: paintWebPage(
p,
_history ? _history->peer : _data->session().user());
}, lifetime());
_editMsgId.value(
@@ -415,7 +423,7 @@ void FieldHeader::previewRequested(
}
void FieldHeader::paintWebPage(Painter &p) {
void FieldHeader::paintWebPage(Painter &p, not_null<PeerData*> context) {
Expects(ShowWebPagePreview(_preview.data));
const auto textTop = st::msgReplyPadding.top();
@@ -432,7 +440,7 @@ void FieldHeader::paintWebPage(Painter &p) {
textTop,
st::msgReplyBarSize.height(),
st::msgReplyBarSize.height());
if (HistoryView::DrawWebPageDataPreview(p, _preview.data, to)) {
if (HistoryView::DrawWebPageDataPreview(p, _preview.data, context, to)) {
previewLeft += st::msgReplyBarSize.height()
+ st::msgReplyBarSkip
- st::msgReplyBarSize.width()
@@ -655,6 +663,7 @@ void ComposeControls::setHistory(SetHistoryArgs &&args) {
//}
unregisterDraftSources();
_history = history;
_header->setHistory(args);
registerDraftSource();
_window->tabbedSelector()->setCurrentPeer(
history ? history->peer.get() : nullptr);

View File

@@ -564,6 +564,7 @@ void ContactStatus::setupRequestInfoHandler(not_null<PeerData*> peer) {
*request = peer->session().api().request(
MTPmessages_HidePeerSettingsBar(peer->input)
).send();
box->closeBox();
});
}));
}, _bar.lifetime());

View File

@@ -56,9 +56,13 @@ WebPageText TitleAndDescriptionFromWebPage(not_null<WebPageData*> d) {
return { resultTitle, resultDescription };
}
bool DrawWebPageDataPreview(Painter &p, not_null<WebPageData*> d, QRect to) {
const auto document = d->document;
const auto photo = d->photo;
bool DrawWebPageDataPreview(
Painter &p,
not_null<WebPageData*> webpage,
not_null<PeerData*> context,
QRect to) {
const auto document = webpage->document;
const auto photo = webpage->photo;
if ((!photo || photo->isNull())
&& (!document
|| !document->hasThumbnail()
@@ -67,8 +71,8 @@ bool DrawWebPageDataPreview(Painter &p, not_null<WebPageData*> d, QRect to) {
}
const auto preview = photo
? photo->getReplyPreview(Data::FileOrigin())
: document->getReplyPreview(Data::FileOrigin());
? photo->getReplyPreview(Data::FileOrigin(), context)
: document->getReplyPreview(Data::FileOrigin(), context);
if (preview) {
const auto w = preview->width();
const auto h = preview->height();

View File

@@ -15,6 +15,10 @@ struct WebPageText {
};
WebPageText TitleAndDescriptionFromWebPage(not_null<WebPageData*> d);
bool DrawWebPageDataPreview(Painter &p, not_null<WebPageData*> d, QRect to);
bool DrawWebPageDataPreview(
Painter &p,
not_null<WebPageData*> webpage,
not_null<PeerData*> context,
QRect to);
} // namespace HistoryView

View File

@@ -1084,14 +1084,7 @@ TextWithEntities Document::getCaption() const {
}
Ui::Text::String Document::createCaption() {
const auto timestampLinksDuration = DurationForTimestampLinks(_data);
const auto timestampLinkBase = timestampLinksDuration
? TimestampLinkBase(_data, _realParent->fullId())
: QString();
return File::createCaption(
_realParent,
timestampLinksDuration,
timestampLinkBase);
return File::createCaption(_realParent);
}
bool DrawThumbnailAsSongCover(

View File

@@ -1322,14 +1322,7 @@ void Gif::refreshParentId(not_null<HistoryItem*> realParent) {
}
void Gif::refreshCaption() {
const auto timestampLinksDuration = DurationForTimestampLinks(_data);
const auto timestampLinkBase = timestampLinksDuration
? TimestampLinkBase(_data, _realParent->fullId())
: QString();
_caption = createCaption(
_parent->data(),
timestampLinksDuration,
timestampLinkBase);
_caption = createCaption(_parent->data());
}
int Gif::additionalWidth(const HistoryMessageVia *via, const HistoryMessageReply *reply, const HistoryMessageForwarded *forwarded) const {

View File

@@ -64,7 +64,7 @@ QString TimestampLinkBase(
TimeId DurationForTimestampLinks(not_null<WebPageData*> webpage) {
if (!webpage->collage.items.empty()) {
return false;
return 0;
} else if (const auto document = webpage->document) {
return DurationForTimestampLinks(document);
} else if (webpage->type != WebPageType::Video
@@ -185,12 +185,7 @@ QSize Media::countCurrentSize(int newWidth) {
return QSize(qMin(newWidth, maxWidth()), minHeight());
}
Ui::Text::String Media::createCaption(
not_null<HistoryItem*> item,
TimeId timestampLinksDuration,
const QString &timestampLinkBase) const {
Expects(timestampLinksDuration >= 0);
Ui::Text::String Media::createCaption(not_null<HistoryItem*> item) const {
if (item->emptyText()) {
return {};
}
@@ -203,12 +198,7 @@ Ui::Text::String Media::createCaption(
};
result.setMarkedText(
st::messageTextStyle,
(timestampLinksDuration
? AddTimestampLinks(
item->originalText(),
timestampLinksDuration,
timestampLinkBase)
: item->originalText()),
item->originalTextWithLocalEntities(),
Ui::ItemTextOptions(item),
context);
if (const auto width = _parent->skipBlockWidth()) {

Some files were not shown because too many files have changed in this diff Show More