2
0
mirror of https://github.com/kotatogram/kotatogram-desktop synced 2025-08-31 14:45:14 +00:00

First working code for sending albums.

This commit is contained in:
John Preston
2017-12-19 20:57:42 +04:00
parent 711aa51046
commit 3b3a705a67
30 changed files with 1789 additions and 731 deletions

View File

@@ -61,17 +61,18 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "mainwindow.h"
#include "passcodewidget.h"
#include "mainwindow.h"
#include "storage/localimageloader.h"
#include "storage/localstorage.h"
#include "storage/file_upload.h"
#include "storage/storage_media_prepare.h"
#include "media/media_audio.h"
#include "media/media_audio_capture.h"
#include "media/player/media_player_instance.h"
#include "storage/localstorage.h"
#include "apiwrap.h"
#include "history/history_top_bar_widget.h"
#include "observer_peer.h"
#include "base/qthelp_regex.h"
#include "ui/widgets/popup_menu.h"
#include "platform/platform_file_utilities.h"
#include "auth_session.h"
#include "window/themes/window_theme.h"
#include "window/notifications_manager.h"
@@ -104,36 +105,6 @@ ApiWrap::RequestMessageDataCallback replyEditMessageDataCallback() {
};
}
MTPVector<MTPDocumentAttribute> composeDocumentAttributes(DocumentData *document) {
auto filenameAttribute = MTP_documentAttributeFilename(
MTP_string(document->filename()));
auto attributes = QVector<MTPDocumentAttribute>(1, filenameAttribute);
if (document->dimensions.width() > 0 && document->dimensions.height() > 0) {
int32 duration = document->duration();
if (duration >= 0) {
auto flags = MTPDdocumentAttributeVideo::Flags(0);
if (document->isVideoMessage()) {
flags |= MTPDdocumentAttributeVideo::Flag::f_round_message;
}
attributes.push_back(MTP_documentAttributeVideo(MTP_flags(flags), MTP_int(duration), MTP_int(document->dimensions.width()), MTP_int(document->dimensions.height())));
} else {
attributes.push_back(MTP_documentAttributeImageSize(MTP_int(document->dimensions.width()), MTP_int(document->dimensions.height())));
}
}
if (document->type == AnimatedDocument) {
attributes.push_back(MTP_documentAttributeAnimated());
} else if (document->type == StickerDocument && document->sticker()) {
attributes.push_back(MTP_documentAttributeSticker(MTP_flags(0), MTP_string(document->sticker()->alt), document->sticker()->set, MTPMaskCoords()));
} else if (const auto song = document->song()) {
auto flags = MTPDdocumentAttributeAudio::Flag::f_title | MTPDdocumentAttributeAudio::Flag::f_performer;
attributes.push_back(MTP_documentAttributeAudio(MTP_flags(flags), MTP_int(song->duration), MTP_string(song->title), MTP_string(song->performer), MTPstring()));
} else if (const auto voice = document->voice()) {
auto flags = MTPDdocumentAttributeAudio::Flag::f_voice | MTPDdocumentAttributeAudio::Flag::f_waveform;
attributes.push_back(MTP_documentAttributeAudio(MTP_flags(flags), MTP_int(voice->duration), MTPstring(), MTPstring(), MTP_bytes(documentWaveformEncode5bit(voice->waveform))));
}
return MTP_vector<MTPDocumentAttribute>(attributes);
}
} // namespace
ReportSpamPanel::ReportSpamPanel(QWidget *parent) : TWidget(parent),
@@ -448,9 +419,9 @@ HistoryWidget::HistoryWidget(QWidget *parent, not_null<Window::Controller*> cont
, _kbScroll(this, st::botKbScroll)
, _tabbedPanel(this, controller)
, _tabbedSelector(_tabbedPanel->getSelector())
, _attachDragState(DragState::None)
, _attachDragDocument(this)
, _attachDragPhoto(this)
, _fileLoader(this, FileLoaderQueueStopTimeout)
, _sendActionStopTimer([this] { cancelTypingAction(); })
, _topShadow(this) {
setAcceptDrops(true);
@@ -1294,14 +1265,17 @@ void HistoryWidget::onRecordError() {
stopRecording(false);
}
void HistoryWidget::onRecordDone(QByteArray result, VoiceWaveform waveform, qint32 samples) {
void HistoryWidget::onRecordDone(
QByteArray result,
VoiceWaveform waveform,
qint32 samples) {
if (!canWriteMessage() || result.isEmpty()) return;
App::wnd()->activateWindow();
auto duration = samples / Media::Player::kDefaultFrequency;
auto to = FileLoadTo(_peer->id, _peer->notifySilentPosts(), replyToId());
auto caption = QString();
_fileLoader.addTask(std::make_unique<FileLoadTask>(result, duration, waveform, to, caption));
const auto duration = samples / Media::Player::kDefaultFrequency;
auto options = ApiWrap::SendOptions(_history);
options.replyTo = replyToId();
Auth().api().sendVoiceMessage(result, waveform, duration, options);
}
void HistoryWidget::onRecordUpdate(quint16 level, qint32 samples) {
@@ -3129,19 +3103,21 @@ void HistoryWidget::chooseAttach() {
auto animated = false;
auto image = App::readImage(result.remoteContent, nullptr, false, &animated);
if (!image.isNull() && !animated) {
confirmSendingFiles(image, result.remoteContent);
confirmSendingFiles(
image,
result.remoteContent,
CompressConfirm::Auto);
} else {
uploadFile(result.remoteContent, SendMediaType::File);
}
} else {
auto lists = getSendingFilesLists(result.paths);
if (lists.allFilesForCompress) {
confirmSendingFiles(lists);
} else {
validateSendingFiles(lists, [this](const QStringList &files) {
uploadFiles(files, SendMediaType::File);
return true;
});
auto list = Storage::PrepareMediaList(
result.paths,
st::sendMediaPreviewSize);
if (list.allFilesForCompress) {
confirmSendingFiles(std::move(list), CompressConfirm::Auto);
} else if (!showSendingFilesError(list)) {
uploadFiles(std::move(list), SendMediaType::File);
}
}
}));
@@ -3159,25 +3135,25 @@ void HistoryWidget::sendButtonClicked() {
void HistoryWidget::dragEnterEvent(QDragEnterEvent *e) {
if (!_history || !_canSendMessages) return;
_attachDrag = getDragState(e->mimeData());
_attachDragState = Storage::ComputeMimeDataState(e->mimeData());
updateDragAreas();
if (_attachDrag != DragState::None) {
if (_attachDragState != DragState::None) {
e->setDropAction(Qt::IgnoreAction);
e->accept();
}
}
void HistoryWidget::dragLeaveEvent(QDragLeaveEvent *e) {
if (_attachDrag != DragState::None || !_attachDragPhoto->isHidden() || !_attachDragDocument->isHidden()) {
_attachDrag = DragState::None;
if (_attachDragState != DragState::None || !_attachDragPhoto->isHidden() || !_attachDragDocument->isHidden()) {
_attachDragState = DragState::None;
updateDragAreas();
}
}
void HistoryWidget::leaveEventHook(QEvent *e) {
if (_attachDrag != DragState::None || !_attachDragPhoto->isHidden() || !_attachDragDocument->isHidden()) {
_attachDrag = DragState::None;
if (_attachDragState != DragState::None || !_attachDragPhoto->isHidden() || !_attachDragDocument->isHidden()) {
_attachDragState = DragState::None;
updateDragAreas();
}
if (hasMouseTracking()) mouseMoveEvent(0);
@@ -3246,8 +3222,8 @@ void HistoryWidget::mouseReleaseEvent(QMouseEvent *e) {
_replyForwardPressed = false;
update(0, _field->y() - st::historySendPadding - st::historyReplyHeight, width(), st::historyReplyHeight);
}
if (_attachDrag != DragState::None || !_attachDragPhoto->isHidden() || !_attachDragDocument->isHidden()) {
_attachDrag = DragState::None;
if (_attachDragState != DragState::None || !_attachDragPhoto->isHidden() || !_attachDragDocument->isHidden()) {
_attachDragState = DragState::None;
updateDragAreas();
}
if (_recording) {
@@ -3477,60 +3453,11 @@ QRect HistoryWidget::rectForFloatPlayer() const {
return mapToGlobal(_scroll->geometry());
}
DragState HistoryWidget::getDragState(const QMimeData *d) {
if (!d
|| d->hasFormat(qsl("application/x-td-forward-selected"))
|| d->hasFormat(qsl("application/x-td-forward-pressed"))
|| d->hasFormat(qsl("application/x-td-forward-pressed-link"))) return DragState::None;
if (d->hasImage()) return DragState::Image;
QString uriListFormat(qsl("text/uri-list"));
if (!d->hasFormat(uriListFormat)) return DragState::None;
QStringList imgExtensions(cImgExtensions()), files;
const QList<QUrl> &urls(d->urls());
if (urls.isEmpty()) return DragState::None;
bool allAreSmallImages = true;
for (QList<QUrl>::const_iterator i = urls.cbegin(), en = urls.cend(); i != en; ++i) {
if (!i->isLocalFile()) return DragState::None;
auto file = Platform::File::UrlToLocal(*i);
QFileInfo info(file);
if (info.isDir()) return DragState::None;
quint64 s = info.size();
if (s > App::kFileSizeLimit) {
return DragState::None;
}
if (allAreSmallImages) {
if (s > App::kImageSizeLimit) {
allAreSmallImages = false;
} else {
bool foundImageExtension = false;
for (QStringList::const_iterator j = imgExtensions.cbegin(), end = imgExtensions.cend(); j != end; ++j) {
if (file.right(j->size()).toLower() == (*j).toLower()) {
foundImageExtension = true;
break;
}
}
if (!foundImageExtension) {
allAreSmallImages = false;
}
}
}
}
return allAreSmallImages ? DragState::PhotoFiles : DragState::Files;
}
void HistoryWidget::updateDragAreas() {
_field->setAcceptDrops(_attachDrag == DragState::None);
_field->setAcceptDrops(_attachDragState == DragState::None);
updateControlsGeometry();
switch (_attachDrag) {
switch (_attachDragState) {
case DragState::None:
_attachDragDocument->otherLeave();
_attachDragPhoto->otherLeave();
@@ -3670,7 +3597,7 @@ bool HistoryWidget::kbWasHidden() const {
}
void HistoryWidget::dropEvent(QDropEvent *e) {
_attachDrag = DragState::None;
_attachDragState = DragState::None;
updateDragAreas();
e->acceptProposedAction();
}
@@ -4006,11 +3933,20 @@ void HistoryWidget::updateFieldPlaceholder() {
}
template <typename SendCallback>
bool HistoryWidget::showSendFilesBox(object_ptr<SendFilesBox> box, const QString &insertTextOnCancel, const QString *addedComment, SendCallback callback) {
bool HistoryWidget::showSendFilesBox(
object_ptr<SendFilesBox> box,
const QString &insertTextOnCancel,
const QString *addedComment,
SendCallback callback) {
App::wnd()->activateWindow();
auto withComment = (addedComment != nullptr);
box->setConfirmedCallback(base::lambda_guarded(this, [this, withComment, sendCallback = std::move(callback)](const QStringList &files, const QImage &image, std::unique_ptr<FileLoadTask::MediaInformation> information, bool compressed, const QString &caption, bool ctrlShiftEnter) {
const auto confirmedCallback = [=, sendCallback = std::move(callback)](
Storage::PreparedList &&list,
const QImage &image,
bool compressed,
const QString &caption,
bool ctrlShiftEnter) {
if (!canWriteMessage()) return;
const auto replyTo = replyToId();
@@ -4019,13 +3955,14 @@ bool HistoryWidget::showSendFilesBox(object_ptr<SendFilesBox> box, const QString
onSend(ctrlShiftEnter);
}
sendCallback(
files,
std::move(list),
image,
std::move(information),
compressed,
caption,
replyTo);
}));
};
box->setConfirmedCallback(
base::lambda_guarded(this, std::move(confirmedCallback)));
if (withComment) {
auto was = _field->getTextWithTags();
@@ -4043,66 +3980,161 @@ bool HistoryWidget::showSendFilesBox(object_ptr<SendFilesBox> box, const QString
return true;
}
template <typename Callback>
bool HistoryWidget::validateSendingFiles(const SendingFilesLists &lists, Callback callback) {
if (!canWriteMessage()) return false;
bool HistoryWidget::showSendingFilesError(
const Storage::PreparedList &list) const {
App::wnd()->activateWindow();
if (!lists.nonLocalUrls.isEmpty()) {
Ui::show(Box<InformBox>(lng_send_image_empty(lt_name, lists.nonLocalUrls.front().toDisplayString())));
} else if (!lists.emptyFiles.isEmpty()) {
Ui::show(Box<InformBox>(lng_send_image_empty(lt_name, lists.emptyFiles.front())));
} else if (!lists.tooLargeFiles.isEmpty()) {
Ui::show(Box<InformBox>(lng_send_image_too_large(lt_name, lists.tooLargeFiles.front())));
} else if (!lists.filesToSend.isEmpty()) {
return callback(lists.filesToSend);
}
return false;
}
bool HistoryWidget::confirmSendingFiles(const QList<QUrl> &files, CompressConfirm compressed, const QString *addedComment) {
return confirmSendingFiles(getSendingFilesLists(files), compressed, addedComment);
}
bool HistoryWidget::confirmSendingFiles(const QStringList &files, CompressConfirm compressed, const QString *addedComment) {
return confirmSendingFiles(getSendingFilesLists(files), compressed, addedComment);
}
bool HistoryWidget::confirmSendingFiles(const SendingFilesLists &lists, CompressConfirm compressed, const QString *addedComment) {
if (auto megagroup = _peer ? _peer->asMegagroup() : nullptr) {
if (megagroup->restricted(ChannelRestriction::f_send_media)) {
Ui::show(Box<InformBox>(lang(lng_restricted_send_media)));
return false;
const auto text = [&] {
if (const auto megagroup = _peer ? _peer->asMegagroup() : nullptr) {
if (megagroup->restricted(ChannelRestriction::f_send_media)) {
return lang(lng_restricted_send_media);
}
} else if (!canWriteMessage()) {
return lang(lng_forward_send_files_cant);
}
using Error = Storage::PreparedList::Error;
switch (list.error) {
case Error::None: return QString();
case Error::EmptyFile:
case Error::Directory:
case Error::NonLocalUrl: return lng_send_image_empty(
lt_name,
list.errorData);
case Error::TooLargeFile: return lng_send_image_too_large(
lt_name,
list.errorData);
}
return lang(lng_forward_send_files_cant);
}();
if (text.isEmpty()) {
return false;
}
return validateSendingFiles(lists, [this, &lists, compressed, addedComment](const QStringList &files) {
auto insertTextOnCancel = QString();
auto sendCallback = [this](const QStringList &files, const QImage &image, std::unique_ptr<FileLoadTask::MediaInformation> information, bool compressed, const QString &caption, MsgId replyTo) {
auto type = compressed ? SendMediaType::Photo : SendMediaType::File;
uploadFilesAfterConfirmation(files, QByteArray(), image, std::move(information), type, caption);
Ui::show(Box<InformBox>(text));
return true;
}
bool HistoryWidget::confirmSendingFiles(const QStringList &files) {
return confirmSendingFiles(files, CompressConfirm::Auto, nullptr);
}
bool HistoryWidget::confirmSendingFiles(const QMimeData *data) {
return confirmSendingFiles(data, CompressConfirm::Auto, nullptr);
}
bool HistoryWidget::confirmSendingFiles(
const QList<QUrl> &files,
CompressConfirm compressed,
const QString *addedComment) {
return confirmSendingFiles(
Storage::PrepareMediaList(files, st::sendMediaPreviewSize),
compressed,
addedComment);
}
bool HistoryWidget::confirmSendingFiles(
const QStringList &files,
CompressConfirm compressed,
const QString *addedComment) {
return confirmSendingFiles(
Storage::PrepareMediaList(files, st::sendMediaPreviewSize),
compressed,
addedComment);
}
bool HistoryWidget::confirmSendingFiles(
Storage::PreparedList &&list,
CompressConfirm compressed,
const QString *addedComment) {
if (showSendingFilesError(list)) {
return false;
}
if (list.albumIsPossible) {
auto box = Ui::show(Box<SendAlbumBox>(std::move(list)));
const auto confirmedCallback = [=](
Storage::PreparedList &&list,
const QString &caption,
bool ctrlShiftEnter) {
if (!canWriteMessage()) return;
uploadFilesAfterConfirmation(
std::move(list),
QByteArray(),
QImage(),
SendMediaType::Photo,
caption,
replyToId(),
std::make_shared<SendingAlbum>());
};
auto boxCompressConfirm = compressed;
if (files.size() > 1 && !lists.allFilesForCompress) {
boxCompressConfirm = CompressConfirm::None;
}
auto box = Box<SendFilesBox>(files, boxCompressConfirm);
return showSendFilesBox(std::move(box), insertTextOnCancel, addedComment, std::move(sendCallback));
});
box->setConfirmedCallback(
base::lambda_guarded(this, std::move(confirmedCallback)));
return true;
} else {
const auto insertTextOnCancel = QString();
auto sendCallback = [this](
Storage::PreparedList &&list,
const QImage &image,
bool compressed,
const QString &caption,
MsgId replyTo) {
const auto type = compressed
? SendMediaType::Photo
: SendMediaType::File;
uploadFilesAfterConfirmation(
std::move(list),
QByteArray(),
image,
type,
caption,
replyTo);
};
const auto noCompressOption = (list.files.size() > 1)
&& !list.allFilesForCompress;
const auto boxCompressConfirm = noCompressOption
? CompressConfirm::None
: compressed;
return showSendFilesBox(
Box<SendFilesBox>(std::move(list), boxCompressConfirm),
insertTextOnCancel,
addedComment,
std::move(sendCallback));
}
}
bool HistoryWidget::confirmSendingFiles(const QImage &image, const QByteArray &content, CompressConfirm compressed, const QString &insertTextOnCancel) {
bool HistoryWidget::confirmSendingFiles(
const QImage &image,
const QByteArray &content,
CompressConfirm compressed,
const QString &insertTextOnCancel) {
if (!canWriteMessage() || image.isNull()) return false;
App::wnd()->activateWindow();
auto sendCallback = [this, content](const QStringList &files, const QImage &image, std::unique_ptr<FileLoadTask::MediaInformation> information, bool compressed, const QString &caption, MsgId replyTo) {
auto type = compressed ? SendMediaType::Photo : SendMediaType::File;
uploadFilesAfterConfirmation(files, content, image, std::move(information), type, caption);
auto sendCallback = [this, content](
Storage::PreparedList &&list,
const QImage &image,
bool compressed,
const QString &caption,
MsgId replyTo) {
const auto type = compressed
? SendMediaType::Photo
: SendMediaType::File;
uploadFilesAfterConfirmation(
std::move(list),
content,
image,
type,
caption,
replyTo);
};
auto box = Box<SendFilesBox>(image, compressed);
return showSendFilesBox(std::move(box), insertTextOnCancel, nullptr, std::move(sendCallback));
return showSendFilesBox(
Box<SendFilesBox>(image, compressed),
insertTextOnCancel,
nullptr,
std::move(sendCallback));
}
bool HistoryWidget::confirmSendingFiles(const QMimeData *data, CompressConfirm compressed, const QString &insertTextOnCancel) {
bool HistoryWidget::confirmSendingFiles(
const QMimeData *data,
CompressConfirm compressed,
const QString &insertTextOnCancel) {
if (!canWriteMessage()) {
return false;
}
@@ -4119,7 +4151,11 @@ bool HistoryWidget::confirmSendingFiles(const QMimeData *data, CompressConfirm c
if (data->hasImage()) {
auto image = qvariant_cast<QImage>(data->imageData());
if (!image.isNull()) {
confirmSendingFiles(image, QByteArray(), compressed, insertTextOnCancel);
confirmSendingFiles(
image,
QByteArray(),
compressed,
insertTextOnCancel);
return true;
}
}
@@ -4133,11 +4169,9 @@ bool HistoryWidget::confirmShareContact(
const QString *addedComment) {
if (!canWriteMessage()) return false;
auto box = Box<SendFilesBox>(phone, fname, lname);
auto sendCallback = [=](
const QStringList &files,
Storage::PreparedList &&list,
const QImage &image,
std::unique_ptr<FileLoadTask::MediaInformation> information,
bool compressed,
const QString &caption,
MsgId replyTo) {
@@ -4145,113 +4179,79 @@ bool HistoryWidget::confirmShareContact(
options.replyTo = replyTo;
Auth().api().shareContact(phone, fname, lname, options);
};
auto insertTextOnCancel = QString();
const auto insertTextOnCancel = QString();
return showSendFilesBox(
std::move(box),
Box<SendFilesBox>(phone, fname, lname),
insertTextOnCancel,
addedComment,
std::move(sendCallback));
}
HistoryWidget::SendingFilesLists HistoryWidget::getSendingFilesLists(const QList<QUrl> &files) {
auto result = SendingFilesLists();
for_const (auto &url, files) {
if (!url.isLocalFile()) {
result.nonLocalUrls.push_back(url);
} else {
auto filepath = Platform::File::UrlToLocal(url);
getSendingLocalFileInfo(result, filepath);
}
}
return result;
}
HistoryWidget::SendingFilesLists HistoryWidget::getSendingFilesLists(const QStringList &files) {
auto result = SendingFilesLists();
for_const (auto &filepath, files) {
getSendingLocalFileInfo(result, filepath);
}
return result;
}
void HistoryWidget::getSendingLocalFileInfo(SendingFilesLists &result, const QString &filepath) {
auto hasExtensionForCompress = [](const QString &filepath) {
for_const (auto extension, cExtensionsForCompress()) {
if (filepath.right(extension.size()).compare(extension, Qt::CaseInsensitive) == 0) {
return true;
}
}
return false;
};
auto fileinfo = QFileInfo(filepath);
if (fileinfo.isDir()) {
result.directories.push_back(filepath);
} else {
auto filesize = fileinfo.size();
if (filesize <= 0) {
result.emptyFiles.push_back(filepath);
} else if (filesize > App::kFileSizeLimit) {
result.tooLargeFiles.push_back(filepath);
} else {
result.filesToSend.push_back(filepath);
if (result.allFilesForCompress) {
if (filesize > App::kImageSizeLimit || !hasExtensionForCompress(filepath)) {
result.allFilesForCompress = false;
}
}
}
}
}
void HistoryWidget::uploadFiles(const QStringList &files, SendMediaType type) {
void HistoryWidget::uploadFiles(
Storage::PreparedList &&list,
SendMediaType type) {
if (!canWriteMessage()) return;
auto caption = QString();
uploadFilesAfterConfirmation(files, QByteArray(), QImage(), nullptr, type, caption);
uploadFilesAfterConfirmation(
std::move(list),
QByteArray(),
QImage(),
type,
caption,
replyToId());
}
void HistoryWidget::uploadFilesAfterConfirmation(
const QStringList &files,
Storage::PreparedList &&list,
const QByteArray &content,
const QImage &image,
std::unique_ptr<FileLoadTask::MediaInformation> information,
SendMediaType type,
QString caption) {
QString caption,
MsgId replyTo,
std::shared_ptr<SendingAlbum> album) {
Assert(canWriteMessage());
auto to = FileLoadTo(_peer->id, _peer->notifySilentPosts(), replyToId());
if (files.size() > 1 && !caption.isEmpty()) {
auto message = MainWidget::MessageToSend(_history);
message.textWithTags = { caption, TextWithTags::Tags() };
message.replyTo = to.replyTo;
message.clearDraft = false;
App::main()->sendMessage(message);
caption = QString();
}
auto tasks = std::vector<std::unique_ptr<Task>>();
tasks.reserve(files.size());
for_const (auto &filepath, files) {
if (filepath.isEmpty() && (!image.isNull() || !content.isNull())) {
tasks.push_back(std::make_unique<FileLoadTask>(content, image, type, to, caption));
} else {
tasks.push_back(std::make_unique<FileLoadTask>(filepath, std::move(information), type, to, caption));
}
}
_fileLoader.addTasks(std::move(tasks));
auto options = ApiWrap::SendOptions(_history);
options.replyTo = replyTo;
Auth().api().sendFiles(
std::move(list),
content,
image,
type,
caption,
album,
options);
}
void HistoryWidget::uploadFile(const QByteArray &fileContent, SendMediaType type) {
void HistoryWidget::uploadFile(
const QByteArray &fileContent,
SendMediaType type) {
if (!canWriteMessage()) return;
auto to = FileLoadTo(_peer->id, _peer->notifySilentPosts(), replyToId());
auto caption = QString();
_fileLoader.addTask(std::make_unique<FileLoadTask>(fileContent, QImage(), type, to, caption));
auto options = ApiWrap::SendOptions(_history);
options.replyTo = replyToId();
Auth().api().sendFile(fileContent, type, options);
}
void HistoryWidget::sendFileConfirmed(const FileLoadResultPtr &file) {
bool lastKeyboardUsed = lastForceReplyReplied(FullMsgId(peerToChannel(file->to.peer), file->to.replyTo));
void HistoryWidget::sendFileConfirmed(
const std::shared_ptr<FileLoadResult> &file) {
const auto channelId = peerToChannel(file->to.peer);
const auto lastKeyboardUsed = lastForceReplyReplied(FullMsgId(
channelId,
file->to.replyTo));
FullMsgId newId(peerToChannel(file->to.peer), clientMsgId());
const auto newId = FullMsgId(channelId, clientMsgId());
const auto groupId = file->album ? file->album->groupId : uint64(0);
if (file->album) {
const auto proj = [](const SendingAlbum::Item &item) {
return item.taskId;
};
const auto it = ranges::find(file->album->items, file->taskId, proj);
Assert(it != file->album->items.end());
it->msgId = newId;
}
connect(&Auth().uploader(), SIGNAL(photoReady(const FullMsgId&,bool,const MTPInputFile&)), this, SLOT(onPhotoUploaded(const FullMsgId&,bool,const MTPInputFile&)), Qt::UniqueConnection);
connect(&Auth().uploader(), SIGNAL(documentReady(const FullMsgId&,bool,const MTPInputFile&)), this, SLOT(onDocumentUploaded(const FullMsgId&,bool,const MTPInputFile&)), Qt::UniqueConnection);
@@ -4288,6 +4288,9 @@ void HistoryWidget::sendFileConfirmed(const FileLoadResultPtr &file) {
if (silentPost) {
flags |= MTPDmessage::Flag::f_silent;
}
if (groupId) {
flags |= MTPDmessage::Flag::f_grouped_id;
}
auto messageFromId = channelPost ? 0 : Auth().userId();
auto messagePostAuthor = channelPost ? (Auth().user()->firstName + ' ' + Auth().user()->lastName) : QString();
if (file->type == SendMediaType::Photo) {
@@ -4317,7 +4320,7 @@ void HistoryWidget::sendFileConfirmed(const FileLoadResultPtr &file) {
MTP_int(1),
MTPint(),
MTP_string(messagePostAuthor),
MTPlong()),
MTP_long(groupId)),
NewMessageUnread);
} else if (file->type == SendMediaType::File) {
auto documentFlags = MTPDmessageMediaDocument::Flag::f_document | 0;
@@ -4346,7 +4349,7 @@ void HistoryWidget::sendFileConfirmed(const FileLoadResultPtr &file) {
MTP_int(1),
MTPint(),
MTP_string(messagePostAuthor),
MTPlong()),
MTP_long(groupId)),
NewMessageUnread);
} else if (file->type == SendMediaType::Audio) {
if (!peer->isChannel()) {
@@ -4378,7 +4381,7 @@ void HistoryWidget::sendFileConfirmed(const FileLoadResultPtr &file) {
MTP_int(1),
MTPint(),
MTP_string(messagePostAuthor),
MTPlong()),
MTP_long(groupId)),
NewMessageUnread);
}
@@ -4393,90 +4396,14 @@ void HistoryWidget::onPhotoUploaded(
const FullMsgId &newId,
bool silent,
const MTPInputFile &file) {
if (auto item = App::histItemById(newId)) {
uint64 randomId = rand_value<uint64>();
App::historyRegRandom(randomId, newId);
History *hist = item->history();
MsgId replyTo = item->replyToId();
auto sendFlags = MTPmessages_SendMedia::Flags(0);
if (replyTo) {
sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to_msg_id;
}
bool channelPost = hist->peer->isChannel() && !hist->peer->isMegagroup();
bool silentPost = channelPost && silent;
if (silentPost) {
sendFlags |= MTPmessages_SendMedia::Flag::f_silent;
}
auto caption = item->getMedia() ? item->getMedia()->getCaption() : TextWithEntities();
auto media = MTP_inputMediaUploadedPhoto(
MTP_flags(0),
file,
MTP_string(caption.text),
MTPVector<MTPInputDocument>(),
MTP_int(0));
hist->sendRequestId = MTP::send(
MTPmessages_SendMedia(
MTP_flags(sendFlags),
item->history()->peer->input,
MTP_int(replyTo),
media,
MTP_long(randomId),
MTPnullMarkup),
App::main()->rpcDone(&MainWidget::sentUpdatesReceived),
App::main()->rpcFail(&MainWidget::sendMessageFail),
0,
0,
hist->sendRequestId);
}
Auth().api().sendUploadedPhoto(newId, file, silent);
}
void HistoryWidget::onDocumentUploaded(
const FullMsgId &newId,
bool silent,
const MTPInputFile &file) {
if (auto item = dynamic_cast<HistoryMessage*>(App::histItemById(newId))) {
auto media = item->getMedia();
if (auto document = media ? media->getDocument() : nullptr) {
auto randomId = rand_value<uint64>();
App::historyRegRandom(randomId, newId);
auto hist = item->history();
auto replyTo = item->replyToId();
auto sendFlags = MTPmessages_SendMedia::Flags(0);
if (replyTo) {
sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to_msg_id;
}
bool channelPost = hist->peer->isChannel() && !hist->peer->isMegagroup();
bool silentPost = channelPost && silent;
if (silentPost) {
sendFlags |= MTPmessages_SendMedia::Flag::f_silent;
}
auto caption = item->getMedia() ? item->getMedia()->getCaption() : TextWithEntities();
auto media = MTP_inputMediaUploadedDocument(
MTP_flags(0),
file,
MTPInputFile(),
MTP_string(document->mimeString()),
composeDocumentAttributes(document),
MTP_string(caption.text),
MTPVector<MTPInputDocument>(),
MTP_int(0));
hist->sendRequestId = MTP::send(
MTPmessages_SendMedia(
MTP_flags(sendFlags),
item->history()->peer->input,
MTP_int(replyTo),
media,
MTP_long(randomId),
MTPnullMarkup),
App::main()->rpcDone(&MainWidget::sentUpdatesReceived),
App::main()->rpcFail(&MainWidget::sendMessageFail),
0,
0,
hist->sendRequestId);
}
}
Auth().api().sendUploadedDocument(newId, file, base::none, silent);
}
void HistoryWidget::onThumbDocumentUploaded(
@@ -4484,48 +4411,7 @@ void HistoryWidget::onThumbDocumentUploaded(
bool silent,
const MTPInputFile &file,
const MTPInputFile &thumb) {
if (auto item = dynamic_cast<HistoryMessage*>(App::histItemById(newId))) {
auto media = item->getMedia();
if (auto document = media ? media->getDocument() : nullptr) {
auto randomId = rand_value<uint64>();
App::historyRegRandom(randomId, newId);
auto hist = item->history();
auto replyTo = item->replyToId();
auto sendFlags = MTPmessages_SendMedia::Flags(0);
if (replyTo) {
sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to_msg_id;
}
bool channelPost = hist->peer->isChannel() && !hist->peer->isMegagroup();
bool silentPost = channelPost && silent;
if (silentPost) {
sendFlags |= MTPmessages_SendMedia::Flag::f_silent;
}
auto caption = media ? media->getCaption() : TextWithEntities();
auto media = MTP_inputMediaUploadedDocument(
MTP_flags(MTPDinputMediaUploadedDocument::Flag::f_thumb),
file,
thumb,
MTP_string(document->mimeString()),
composeDocumentAttributes(document),
MTP_string(caption.text),
MTPVector<MTPInputDocument>(),
MTP_int(0));
hist->sendRequestId = MTP::send(
MTPmessages_SendMedia(
MTP_flags(sendFlags),
item->history()->peer->input,
MTP_int(replyTo),
media,
MTP_long(randomId),
MTPnullMarkup),
App::main()->rpcDone(&MainWidget::sentUpdatesReceived),
App::main()->rpcFail(&MainWidget::sendMessageFail),
0,
0,
hist->sendRequestId);
}
}
Auth().api().sendUploadedDocument(newId, file, thumb, silent);
}
void HistoryWidget::onPhotoProgress(const FullMsgId &newId) {
@@ -4756,7 +4642,7 @@ void HistoryWidget::updateControlsGeometry() {
_membersDropdown->setMaxHeight(countMembersDropdownHeightMax());
}
switch (_attachDrag) {
switch (_attachDragState) {
case DragState::Files:
_attachDragDocument->resize(width() - st::dragMargin.left() - st::dragMargin.right(), height() - st::dragMargin.top() - st::dragMargin.bottom());
_attachDragDocument->move(st::dragMargin.left(), st::dragMargin.top());