Send album after cancel of some media uploads.

Also display checks when part of the album medias are uploaded.
This commit is contained in:
John Preston 2017-12-25 17:17:00 +03:00
parent 4e8f5541af
commit 5d18d7c813
19 changed files with 357 additions and 183 deletions

View File

@ -1098,10 +1098,10 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
"lng_send_images_selected#other" = "{count} images selected";
"lng_send_photos#one" = "Send {count} photo";
"lng_send_photos#other" = "Send {count} photos";
"lng_send_photos_videos#one" = "Send {count} photo and video file";
"lng_send_photos_videos#other" = "Send {count} photos and video files";
"lng_send_photos_videos#one" = "Send {count} photo and video";
"lng_send_photos_videos#other" = "Send {count} photos and videos";
"lng_send_separate_photos" = "Send separate photos";
"lng_send_separate_photos_videos" = "Send separate photos and video files";
"lng_send_separate_photos_videos" = "Send separate photos and videos";
"lng_send_files_selected#one" = "{count} file selected";
"lng_send_files_selected#other" = "{count} files selected";
"lng_send_files#one" = "Send {count} file";

View File

@ -2743,6 +2743,9 @@ void ApiWrap::sendFiles(
}
const auto to = FileLoadTaskOptions(options);
if (album) {
album->silent = to.silent;
}
auto tasks = std::vector<std::unique_ptr<Task>>();
tasks.reserve(list.files.size());
for (auto &file : list.files) {
@ -2806,7 +2809,7 @@ void ApiWrap::sendUploadedPhoto(
MTPVector<MTPInputDocument>(),
MTP_int(0));
if (const auto groupId = item->groupId()) {
uploadAlbumMedia(item, groupId, media, silent);
uploadAlbumMedia(item, groupId, media);
} else {
sendMedia(item, media, silent);
}
@ -2840,7 +2843,7 @@ void ApiWrap::sendUploadedDocument(
MTPVector<MTPInputDocument>(),
MTP_int(0));
if (groupId) {
uploadAlbumMedia(item, groupId, media, silent);
uploadAlbumMedia(item, groupId, media);
} else {
sendMedia(item, media, silent);
}
@ -2848,11 +2851,18 @@ void ApiWrap::sendUploadedDocument(
}
}
void ApiWrap::cancelLocalItem(not_null<HistoryItem*> item) {
Expects(!IsServerMsgId(item->id));
if (const auto groupId = item->groupId()) {
sendAlbumWithCancelled(item, groupId);
}
}
void ApiWrap::uploadAlbumMedia(
not_null<HistoryItem*> item,
const MessageGroupId &groupId,
const MTPInputMedia &media,
bool silent) {
const MTPInputMedia &media) {
const auto localId = item->fullId();
const auto failed = [this] {
@ -2865,6 +2875,13 @@ void ApiWrap::uploadAlbumMedia(
if (!item) {
failed();
}
if (const auto media = item->getMedia()) {
if (const auto photo = media->getPhoto()) {
photo->setWaitingForAlbum();
} else if (const auto document = media->getDocument()) {
document->setWaitingForAlbum();
}
}
switch (result.type()) {
case mtpc_messageMediaPhoto: {
@ -2883,7 +2900,7 @@ void ApiWrap::uploadAlbumMedia(
MTP_inputPhoto(photo.vid, photo.vaccess_hash),
data.has_caption() ? data.vcaption : MTP_string(QString()),
data.has_ttl_seconds() ? data.vttl_seconds : MTPint());
trySendAlbum(item, groupId, media, silent);
sendAlbumWithUploaded(item, groupId, media);
} break;
case mtpc_messageMediaDocument: {
@ -2902,7 +2919,7 @@ void ApiWrap::uploadAlbumMedia(
MTP_inputDocument(document.vid, document.vaccess_hash),
data.has_caption() ? data.vcaption : MTP_string(QString()),
data.has_ttl_seconds() ? data.vttl_seconds : MTPint());
trySendAlbum(item, groupId, media, silent);
sendAlbumWithUploaded(item, groupId, media);
} break;
}
}).fail([=](const RPCError &error) {
@ -2910,40 +2927,6 @@ void ApiWrap::uploadAlbumMedia(
}).send();
}
void ApiWrap::trySendAlbum(
not_null<HistoryItem*> item,
const MessageGroupId &groupId,
const MTPInputMedia &media,
bool silent) {
const auto localId = item->fullId();
const auto randomId = rand_value<uint64>();
App::historyRegRandom(randomId, localId);
const auto medias = completeAlbum(localId, groupId, media, randomId);
if (medias.empty()) {
return;
}
const auto history = item->history();
const auto replyTo = item->replyToId();
const auto flags = MTPmessages_SendMultiMedia::Flags(0)
| (replyTo
? MTPmessages_SendMultiMedia::Flag::f_reply_to_msg_id
: MTPmessages_SendMultiMedia::Flag(0))
| (IsSilentPost(item, silent)
? MTPmessages_SendMultiMedia::Flag::f_silent
: MTPmessages_SendMultiMedia::Flag(0));
history->sendRequestId = request(MTPmessages_SendMultiMedia(
MTP_flags(flags),
history->peer->input,
MTP_int(replyTo),
MTP_vector<MTPInputSingleMedia>(medias)
)).done([=](const MTPUpdates &result) { applyUpdates(result);
}).fail([=](const RPCError &error) { sendMessageFail(error);
}).afterRequest(history->sendRequestId
).send();
}
void ApiWrap::sendMedia(
not_null<HistoryItem*> item,
const MTPInputMedia &media,
@ -2951,6 +2934,14 @@ void ApiWrap::sendMedia(
const auto randomId = rand_value<uint64>();
App::historyRegRandom(randomId, item->fullId());
sendMediaWithRandomId(item, media, silent, randomId);
}
void ApiWrap::sendMediaWithRandomId(
not_null<HistoryItem*> item,
const MTPInputMedia &media,
bool silent,
uint64 randomId) {
const auto history = item->history();
const auto replyTo = item->replyToId();
const auto flags = MTPmessages_SendMedia::Flags(0)
@ -2973,11 +2964,14 @@ void ApiWrap::sendMedia(
).send();
}
QVector<MTPInputSingleMedia> ApiWrap::completeAlbum(
FullMsgId localId,
void ApiWrap::sendAlbumWithUploaded(
not_null<HistoryItem*> item,
const MessageGroupId &groupId,
const MTPInputMedia &media,
uint64 randomId) {
const MTPInputMedia &media) {
const auto localId = item->fullId();
const auto randomId = rand_value<uint64>();
App::historyRegRandom(randomId, localId);
const auto albumIt = _sendingAlbums.find(groupId.raw());
Assert(albumIt != _sendingAlbums.end());
const auto &album = albumIt->second;
@ -2990,15 +2984,79 @@ QVector<MTPInputSingleMedia> ApiWrap::completeAlbum(
Assert(!itemIt->media);
itemIt->media = MTP_inputSingleMedia(media, MTP_long(randomId));
auto result = QVector<MTPInputSingleMedia>();
result.reserve(album->items.size());
sendAlbumIfReady(album.get());
}
void ApiWrap::sendAlbumWithCancelled(
not_null<HistoryItem*> item,
const MessageGroupId &groupId) {
const auto localId = item->fullId();
const auto albumIt = _sendingAlbums.find(groupId.raw());
Assert(albumIt != _sendingAlbums.end());
const auto &album = albumIt->second;
const auto proj = [](const SendingAlbum::Item &item) {
return item.msgId;
};
const auto itemIt = ranges::find(album->items, localId, proj);
Assert(itemIt != album->items.end());
album->items.erase(itemIt);
sendAlbumIfReady(album.get());
}
void ApiWrap::sendAlbumIfReady(not_null<SendingAlbum*> album) {
const auto groupId = album->groupId;
if (album->items.empty()) {
_sendingAlbums.remove(groupId);
return;
}
auto sample = (HistoryItem*)nullptr;
auto medias = QVector<MTPInputSingleMedia>();
medias.reserve(album->items.size());
for (const auto &item : album->items) {
if (!item.media) {
return {};
return;
} else if (!sample) {
sample = App::histItemById(item.msgId);
}
result.push_back(*item.media);
medias.push_back(*item.media);
}
return result;
if (!sample) {
_sendingAlbums.remove(groupId);
return;
} else if (medias.size() < 2) {
const auto &single = medias.front().c_inputSingleMedia();
sendMediaWithRandomId(
sample,
single.vmedia,
album->silent,
single.vrandom_id.v);
_sendingAlbums.remove(groupId);
return;
}
const auto history = sample->history();
const auto replyTo = sample->replyToId();
const auto flags = MTPmessages_SendMultiMedia::Flags(0)
| (replyTo
? MTPmessages_SendMultiMedia::Flag::f_reply_to_msg_id
: MTPmessages_SendMultiMedia::Flag(0))
| (IsSilentPost(sample, album->silent)
? MTPmessages_SendMultiMedia::Flag::f_silent
: MTPmessages_SendMultiMedia::Flag(0));
history->sendRequestId = request(MTPmessages_SendMultiMedia(
MTP_flags(flags),
history->peer->input,
MTP_int(replyTo),
MTP_vector<MTPInputSingleMedia>(medias)
)).done([=](const MTPUpdates &result) {
_sendingAlbums.remove(groupId);
applyUpdates(result);
}).fail([=](const RPCError &error) {
_sendingAlbums.remove(groupId);
sendMessageFail(error);
}).afterRequest(history->sendRequestId
).send();
}
void ApiWrap::readServerHistory(not_null<History*> history) {

View File

@ -215,6 +215,7 @@ public:
const MTPInputFile &file,
const base::optional<MTPInputFile> &thumb,
bool silent);
void cancelLocalItem(not_null<HistoryItem*> item);
~ApiWrap();
@ -317,22 +318,24 @@ private:
void uploadAlbumMedia(
not_null<HistoryItem*> item,
const MessageGroupId &groupId,
const MTPInputMedia &media,
bool silent);
void trySendAlbum(
const MTPInputMedia &media);
void sendAlbumWithUploaded(
not_null<HistoryItem*> item,
const MessageGroupId &groupId,
const MTPInputMedia &media,
bool silent);
QVector<MTPInputSingleMedia> completeAlbum(
FullMsgId localId,
const MessageGroupId &groupId,
const MTPInputMedia &media,
uint64 randomId);
const MTPInputMedia &media);
void sendAlbumWithCancelled(
not_null<HistoryItem*> item,
const MessageGroupId &groupId);
void sendAlbumIfReady(not_null<SendingAlbum*> album);
void sendMedia(
not_null<HistoryItem*> item,
const MTPInputMedia &media,
bool silent);
void sendMediaWithRandomId(
not_null<HistoryItem*> item,
const MTPInputMedia &media,
bool silent,
uint64 randomId);
not_null<AuthSession*> _session;
mtpRequestId _changelogSubscription = 0;

View File

@ -1375,17 +1375,24 @@ namespace {
}
PhotoData *photo(const PhotoId &photo) {
PhotosData::const_iterator i = ::photosData.constFind(photo);
auto i = ::photosData.constFind(photo);
if (i == ::photosData.cend()) {
i = ::photosData.insert(photo, new PhotoData(photo));
}
return i.value();
}
PhotoData *photoSet(const PhotoId &photo, PhotoData *convert, const uint64 &access, int32 date, const ImagePtr &thumb, const ImagePtr &medium, const ImagePtr &full) {
PhotoData *photoSet(
const PhotoId &photo,
PhotoData *convert,
const uint64 &access,
int32 date,
const ImagePtr &thumb,
const ImagePtr &medium,
const ImagePtr &full) {
if (convert) {
if (convert->id != photo) {
PhotosData::iterator i = ::photosData.find(convert->id);
const auto i = ::photosData.find(convert->id);
if (i != ::photosData.cend() && i.value() == convert) {
::photosData.erase(i);
}
@ -1400,9 +1407,9 @@ namespace {
updateImage(convert->full, full);
}
}
PhotosData::const_iterator i = ::photosData.constFind(photo);
const auto i = ::photosData.constFind(photo);
PhotoData *result;
LastPhotosMap::iterator inLastIter = lastPhotosMap.end();
auto inLastIter = lastPhotosMap.end();
if (i == ::photosData.cend()) {
if (convert) {
result = convert;
@ -1436,27 +1443,39 @@ namespace {
}
DocumentData *document(const DocumentId &document) {
DocumentsData::const_iterator i = ::documentsData.constFind(document);
auto i = ::documentsData.constFind(document);
if (i == ::documentsData.cend()) {
i = ::documentsData.insert(document, DocumentData::create(document));
}
return i.value();
}
DocumentData *documentSet(const DocumentId &document, DocumentData *convert, const uint64 &access, int32 version, int32 date, const QVector<MTPDocumentAttribute> &attributes, const QString &mime, const ImagePtr &thumb, int32 dc, int32 size, const StorageImageLocation &thumbLocation) {
DocumentData *documentSet(
const DocumentId &document,
DocumentData *convert,
const uint64 &access,
int32 version,
int32 date,
const QVector<MTPDocumentAttribute> &attributes,
const QString &mime,
const ImagePtr &thumb,
int32 dc,
int32 size,
const StorageImageLocation &thumbLocation) {
bool versionChanged = false;
bool sentSticker = false;
if (convert) {
MediaKey oldKey = convert->mediaKey();
bool idChanged = (convert->id != document);
const auto oldKey = convert->mediaKey();
const auto idChanged = (convert->id != document);
if (idChanged) {
DocumentsData::iterator i = ::documentsData.find(convert->id);
const auto i = ::documentsData.find(convert->id);
if (i != ::documentsData.cend() && i.value() == convert) {
::documentsData.erase(i);
}
convert->id = document;
convert->status = FileReady;
convert->uploadingData = nullptr;
sentSticker = (convert->sticker() != 0);
}
if (date) {
@ -1474,7 +1493,7 @@ namespace {
convert->sticker()->loc = thumbLocation;
}
MediaKey newKey = convert->mediaKey();
const auto newKey = convert->mediaKey();
if (idChanged) {
if (convert->isVoiceMessage()) {
Local::copyAudio(oldKey, newKey);
@ -1488,7 +1507,7 @@ namespace {
Local::writeSavedGifs();
}
}
DocumentsData::const_iterator i = ::documentsData.constFind(document);
const auto i = ::documentsData.constFind(document);
DocumentData *result;
if (i == ::documentsData.cend()) {
if (convert) {
@ -1565,10 +1584,23 @@ namespace {
return i.value();
}
WebPageData *webPageSet(const WebPageId &webPage, WebPageData *convert, const QString &type, const QString &url, const QString &displayUrl, const QString &siteName, const QString &title, const TextWithEntities &description, PhotoData *photo, DocumentData *document, int32 duration, const QString &author, int32 pendingTill) {
WebPageData *webPageSet(
const WebPageId &webPage,
WebPageData *convert,
const QString &type,
const QString &url,
const QString &displayUrl,
const QString &siteName,
const QString &title,
const TextWithEntities &description,
PhotoData *photo,
DocumentData *document,
int32 duration,
const QString &author,
int32 pendingTill) {
if (convert) {
if (convert->id != webPage) {
auto i = webPagesData.find(convert->id);
const auto i = webPagesData.find(convert->id);
if (i != webPagesData.cend() && i.value() == convert) {
webPagesData.erase(i);
}
@ -1592,7 +1624,7 @@ namespace {
if (App::main()) App::main()->webPageUpdated(convert);
}
}
auto i = webPagesData.constFind(webPage);
const auto i = webPagesData.constFind(webPage);
WebPageData *result;
if (i == webPagesData.cend()) {
if (convert) {

View File

@ -332,28 +332,15 @@ void DocumentOpenClickHandler::doOpen(
}
void DocumentOpenClickHandler::onClickImpl() const {
const auto item = context()
? App::histItemById(context())
: App::hoveredLinkItem()
? App::hoveredLinkItem()
: App::contextItem()
? App::contextItem()
: nullptr;
const auto action = document()->isVoiceMessage()
const auto data = document();
const auto action = data->isVoiceMessage()
? ActionOnLoadNone
: ActionOnLoadOpen;
doOpen(document(), item, action);
doOpen(data, getActionItem(), action);
}
void GifOpenClickHandler::onClickImpl() const {
const auto item = context()
? App::histItemById(context())
: App::hoveredLinkItem()
? App::hoveredLinkItem()
: App::contextItem()
? App::contextItem()
: nullptr;
doOpen(document(), item, ActionOnLoadPlayInline);
doOpen(document(), getActionItem(), ActionOnLoadPlayInline);
}
void DocumentSaveClickHandler::doSave(
@ -382,17 +369,13 @@ void DocumentSaveClickHandler::onClickImpl() const {
}
void DocumentCancelClickHandler::onClickImpl() const {
auto data = document();
const auto data = document();
if (!data->date) return;
if (data->uploading()) {
if (auto item = App::hoveredLinkItem() ? App::hoveredLinkItem() : (App::contextItem() ? App::contextItem() : nullptr)) {
if (auto media = item->getMedia()) {
if (media->getDocument() == data) {
App::contextItem(item);
App::main()->cancelUploadLayer();
}
}
if (const auto item = App::histItemById(context())) {
App::contextItem(item);
App::main()->cancelUploadLayer();
}
} else {
data->cancel();
@ -685,12 +668,19 @@ QString DocumentData::loadingFilePath() const {
}
bool DocumentData::displayLoading() const {
return loading() ? (!_loader->loadingLocal() || !_loader->autoLoading()) : uploading();
return loading()
? (!_loader->loadingLocal() || !_loader->autoLoading())
: (uploading() && !waitingForAlbum());
}
float64 DocumentData::progress() const {
if (uploading()) {
return snap((size > 0) ? float64(uploadOffset) / size : 0., 0., 1.);
if (uploadingData->size > 0) {
const auto result = float64(uploadingData->offset)
/ uploadingData->size;
return snap(result, 0., 1.);
}
return 0.;
}
return loading() ? _loader->currentProgress() : (loaded() ? 1. : 0.);
}
@ -700,7 +690,17 @@ int32 DocumentData::loadOffset() const {
}
bool DocumentData::uploading() const {
return status == FileUploading;
return (uploadingData != nullptr);
}
void DocumentData::setWaitingForAlbum() {
if (uploading()) {
uploadingData->waitingForAlbum = true;
}
}
bool DocumentData::waitingForAlbum() const {
return uploading() && uploadingData->waitingForAlbum;
}
void DocumentData::save(const QString &toFile, ActionOnLoad action, const FullMsgId &actionMsgId, LoadFromCloudSetting fromCloud, bool autoLoading) {

View File

@ -125,6 +125,9 @@ public:
int32 loadOffset() const;
bool uploading() const;
void setWaitingForAlbum();
bool waitingForAlbum() const;
QByteArray data() const;
const FileLocation &location(bool check = false) const;
void setLocation(const FileLocation &loc);
@ -241,7 +244,8 @@ public:
int32 size = 0;
FileStatus status = FileReady;
int32 uploadOffset = 0;
std::unique_ptr<Data::UploadState> uploadingData;
int32 md5[8];

View File

@ -63,7 +63,9 @@ bool PhotoData::loading() const {
}
bool PhotoData::displayLoading() const {
return full->loading() ? full->displayLoading() : uploading();
return full->loading()
? full->displayLoading()
: (uploading() && !waitingForAlbum());
}
void PhotoData::cancel() {
@ -91,12 +93,22 @@ float64 PhotoData::progress() const {
return full->progress();
}
void PhotoData::setWaitingForAlbum() {
if (uploading()) {
uploadingData->waitingForAlbum = true;
}
}
bool PhotoData::waitingForAlbum() const {
return uploading() && uploadingData->waitingForAlbum;
}
int32 PhotoData::loadOffset() const {
return full->loadOffset();
}
bool PhotoData::uploading() const {
return !!uploadingData;
return (uploadingData != nullptr);
}
void PhotoData::forget() {

View File

@ -44,6 +44,9 @@ public:
int32 loadOffset() const;
bool uploading() const;
void setWaitingForAlbum();
bool waitingForAlbum() const;
void forget();
ImagePtr makeReplyPreview();
@ -57,13 +60,7 @@ public:
PeerData *peer = nullptr; // for chat and channel photos connection
// geo, caption
struct UploadingData {
UploadingData(int size) : size(size) {
}
int offset = 0;
int size = 0;
};
std::unique_ptr<UploadingData> uploadingData;
std::unique_ptr<Data::UploadState> uploadingData;
private:
void notifyLayoutChanged() const;

View File

@ -53,3 +53,13 @@ void MessageCursor::applyTo(QTextEdit *edit) {
scrollbar->setValue(scroll);
}
}
HistoryItem *FileClickHandler::getActionItem() const {
return context()
? App::histItemById(context())
: App::hoveredLinkItem()
? App::hoveredLinkItem()
: App::contextItem()
? App::contextItem()
: nullptr;
}

View File

@ -20,6 +20,18 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/
#pragma once
namespace Data {
struct UploadState {
UploadState(int size) : size(size) {
}
int offset = 0;
int size = 0;
bool waitingForAlbum = false;
};
} // namespace Data
class PeerData;
class UserData;
class ChatData;
@ -241,7 +253,6 @@ enum LocationType {
enum FileStatus {
FileDownloadFailed = -2,
FileUploadFailed = -1,
FileUploading = 0,
FileReady = 1,
};
@ -404,6 +415,9 @@ public:
return _context;
}
protected:
HistoryItem *getActionItem() const;
private:
FullMsgId _context;

View File

@ -123,6 +123,8 @@ historyFileThumbCancel: icon {{ "history_file_cancel", historyFileThumbIconFg }}
historyFileThumbCancelSelected: icon {{ "history_file_cancel", historyFileThumbIconFgSelected }};
historyFileThumbPlay: icon {{ "history_file_play", historyFileThumbIconFg }};
historyFileThumbPlaySelected: icon {{ "history_file_play", historyFileThumbIconFgSelected }};
historyFileThumbWaiting: icon {{ "mediaview_save_check", historyFileThumbIconFg }};
historyFileThumbWaitingSelected: icon {{ "mediaview_save_check", historyFileThumbIconFgSelected }};
historySendStateSpace: 24px;
historySendStatePosition: point(-17px, -19px);

View File

@ -35,6 +35,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "storage/storage_facade.h"
#include "storage/storage_shared_media.h"
#include "auth_session.h"
#include "apiwrap.h"
#include "media/media_audio.h"
#include "messenger.h"
#include "mainwindow.h"
@ -294,18 +295,20 @@ void HistoryItem::destroy() {
// All this must be done for all items manually in History::clear(false)!
eraseFromUnreadMentions();
if (IsServerMsgId(id)) {
if (auto types = sharedMediaTypes()) {
if (const auto types = sharedMediaTypes()) {
Auth().storage().remove(Storage::SharedMediaRemoveOne(
history()->peer->id,
types,
id));
}
} else {
Auth().api().cancelLocalItem(this);
}
auto wasAtBottom = history()->loadedAtBottom();
_history->removeNotification(this);
detach();
if (auto channel = history()->peer->asChannel()) {
if (const auto channel = history()->peer->asChannel()) {
if (channel->pinnedMessageId() == id) {
channel->clearPinnedMessage();
}

View File

@ -442,7 +442,9 @@ void HistoryPhoto::draw(Painter &p, const QRect &r, TextSelection selection, Tim
p.drawPixmap(rthumb.topLeft(), pix);
}
if (radial || (!loaded && !_data->loading())) {
float64 radialOpacity = (radial && loaded && !_data->uploading()) ? _animation->radial.opacity() : 1;
const auto radialOpacity = (radial && loaded && !_data->uploading())
? _animation->radial.opacity() :
1.;
QRect inner(rthumb.x() + (rthumb.width() - st::msgFileSize) / 2, rthumb.y() + (rthumb.height() - st::msgFileSize) / 2, st::msgFileSize, st::msgFileSize);
p.setPen(Qt::NoPen);
if (selected) {
@ -600,7 +602,10 @@ void HistoryPhoto::drawGrouped(
App::complexOverlayRect(p, geometry, roundRadius, corners);
}
if (radial || (!loaded && !_data->loading())) {
const auto displayState = radial
|| (!loaded && !_data->loading())
|| _data->waitingForAlbum();
if (displayState) {
const auto radialOpacity = (radial && loaded && !_data->uploading())
? _animation->radial.opacity()
: 1.;
@ -629,8 +634,10 @@ void HistoryPhoto::drawGrouped(
}
p.setOpacity(radialOpacity);
auto icon = ([radial, this, selected]() -> const style::icon*{
if (radial || _data->loading()) {
auto icon = [&]() -> const style::icon* {
if (_data->waitingForAlbum()) {
return &(selected ? st::historyFileThumbWaitingSelected : st::historyFileThumbWaiting);
} else if (radial || _data->loading()) {
auto delayed = _data->full->toDelayedStorageImage();
if (!delayed || !delayed->location().isNull()) {
return &(selected ? st::historyFileThumbCancelSelected : st::historyFileThumbCancel);
@ -638,7 +645,7 @@ void HistoryPhoto::drawGrouped(
return nullptr;
}
return &(selected ? st::historyFileThumbDownloadSelected : st::historyFileThumbDownload);
})();
}();
if (icon) {
icon->paintInCenter(p, inner);
}
@ -673,6 +680,19 @@ HistoryTextState HistoryPhoto::getStateGrouped(
: _savel);
}
float64 HistoryPhoto::dataProgress() const {
return _data->progress();
}
bool HistoryPhoto::dataFinished() const {
return !_data->loading()
&& (!_data->uploading() || _data->waitingForAlbum());
}
bool HistoryPhoto::dataLoaded() const {
return _data->loaded();
}
void HistoryPhoto::validateGroupedCache(
const QRect &geometry,
RectParts corners,
@ -1158,8 +1178,10 @@ void HistoryVideo::drawGrouped(
}
p.setOpacity(radialOpacity);
auto icon = ([this, radial, selected, loaded]() -> const style::icon * {
if (loaded && !radial) {
auto icon = [&]() -> const style::icon * {
if (_data->waitingForAlbum()) {
return &(selected ? st::historyFileThumbWaitingSelected : st::historyFileThumbWaiting);
} else if (loaded && !radial) {
return &(selected ? st::historyFileThumbPlaySelected : st::historyFileThumbPlay);
} else if (radial || _data->loading()) {
if (_parent->id > 0 || _data->uploading()) {
@ -1168,7 +1190,7 @@ void HistoryVideo::drawGrouped(
return nullptr;
}
return &(selected ? st::historyFileThumbDownloadSelected : st::historyFileThumbDownload);
})();
}();
if (icon) {
icon->paintInCenter(p, inner);
}
@ -1199,6 +1221,19 @@ HistoryTextState HistoryVideo::getStateGrouped(
: _savel);
}
float64 HistoryVideo::dataProgress() const {
return _data->progress();
}
bool HistoryVideo::dataFinished() const {
return !_data->loading()
&& (!_data->uploading() || _data->waitingForAlbum());
}
bool HistoryVideo::dataLoaded() const {
return _data->loaded();
}
void HistoryVideo::validateGroupedCache(
const QRect &geometry,
RectParts corners,
@ -1278,8 +1313,8 @@ void HistoryVideo::updateStatusText() const {
int32 statusSize = 0, realDuration = 0;
if (_data->status == FileDownloadFailed || _data->status == FileUploadFailed) {
statusSize = FileStatusSizeFailed;
} else if (_data->status == FileUploading) {
statusSize = _data->uploadOffset;
} else if (_data->uploading()) {
statusSize = _data->uploadingData->offset;
} else if (_data->loading()) {
statusSize = _data->loadOffset();
} else if (_data->loaded()) {
@ -1374,6 +1409,18 @@ HistoryDocument::HistoryDocument(
}
}
float64 HistoryDocument::dataProgress() const {
return _data->progress();
}
bool HistoryDocument::dataFinished() const {
return !_data->loading() && !_data->uploading();
}
bool HistoryDocument::dataLoaded() const {
return _data->loaded();
}
void HistoryDocument::createComponents(bool caption) {
uint64 mask = 0;
if (_data->isVoiceMessage()) {
@ -1573,7 +1620,9 @@ void HistoryDocument::draw(Painter &p, const QRect &r, TextSelection selection,
}
if (_data->status != FileUploadFailed) {
const ClickHandlerPtr &lnk((_data->loading() || _data->status == FileUploading) ? thumbed->_linkcancell : thumbed->_linksavel);
const auto &lnk = (_data->loading() || _data->uploading())
? thumbed->_linkcancell
: thumbed->_linksavel;
bool over = ClickHandler::showAsActive(lnk);
p.setFont(over ? st::semiboldFont->underline() : st::semiboldFont);
p.setPen(outbg ? (selected ? st::msgFileThumbLinkOutFgSelected : st::msgFileThumbLinkOutFg) : (selected ? st::msgFileThumbLinkInFgSelected : st::msgFileThumbLinkInFg));
@ -1766,7 +1815,9 @@ HistoryTextState HistoryDocument::getState(QPoint point, HistoryStateRequest req
if (_data->status != FileUploadFailed) {
if (rtlrect(nameleft, linktop, thumbed->_linkw, st::semiboldFont->height, _width).contains(point)) {
result.link = (_data->loading() || _data->uploading()) ? thumbed->_linkcancell : thumbed->_linksavel;
result.link = (_data->loading() || _data->uploading())
? thumbed->_linkcancell
: thumbed->_linksavel;
return result;
}
}
@ -1952,8 +2003,8 @@ bool HistoryDocument::updateStatusText() const {
int32 statusSize = 0, realDuration = 0;
if (_data->status == FileDownloadFailed || _data->status == FileUploadFailed) {
statusSize = FileStatusSizeFailed;
} else if (_data->status == FileUploading) {
statusSize = _data->uploadOffset;
} else if (_data->uploading()) {
statusSize = _data->uploadingData->offset;
} else if (_data->loading()) {
statusSize = _data->loadOffset();
} else if (_data->loaded()) {
@ -2769,8 +2820,8 @@ void HistoryGif::updateStatusText() const {
int32 statusSize = 0, realDuration = 0;
if (_data->status == FileDownloadFailed || _data->status == FileUploadFailed) {
statusSize = FileStatusSizeFailed;
} else if (_data->status == FileUploading) {
statusSize = _data->uploadOffset;
} else if (_data->uploading()) {
statusSize = _data->uploadingData->offset;
} else if (_data->loading()) {
statusSize = _data->loadOffset();
} else if (_data->loaded()) {
@ -2924,15 +2975,19 @@ HistoryGif::~HistoryGif() {
}
float64 HistoryGif::dataProgress() const {
return (_data->uploading() || !_parent || _parent->id > 0) ? _data->progress() : 0;
return (_data->uploading() || _parent->id > 0)
? _data->progress()
: 0;
}
bool HistoryGif::dataFinished() const {
return (!_parent || _parent->id > 0) ? (!_data->loading() && !_data->uploading()) : false;
return (_parent->id > 0)
? (!_data->loading() && !_data->uploading())
: false;
}
bool HistoryGif::dataLoaded() const {
return (!_parent || _parent->id > 0) ? _data->loaded() : false;
return (_parent->id > 0) ? _data->loaded() : false;
}
HistorySticker::HistorySticker(

View File

@ -263,15 +263,9 @@ public:
}
protected:
float64 dataProgress() const override {
return _data->progress();
}
bool dataFinished() const override {
return !_data->loading() && !_data->uploading();
}
bool dataLoaded() const override {
return _data->loaded();
}
float64 dataProgress() const override;
bool dataFinished() const override;
bool dataLoaded() const override;
private:
void validateGroupedCache(
@ -383,15 +377,9 @@ public:
}
protected:
float64 dataProgress() const override {
return _data->progress();
}
bool dataFinished() const override {
return !_data->loading() && !_data->uploading();
}
bool dataLoaded() const override {
return _data->loaded();
}
float64 dataProgress() const override;
bool dataFinished() const override;
bool dataLoaded() const override;
private:
void validateGroupedCache(
@ -493,15 +481,9 @@ public:
void clickHandlerPressedChanged(const ClickHandlerPtr &p, bool pressed) override;
protected:
float64 dataProgress() const override {
return _data->progress();
}
bool dataFinished() const override {
return !_data->loading() && !_data->uploading();
}
bool dataLoaded() const override {
return _data->loaded();
}
float64 dataProgress() const override;
bool dataFinished() const override;
bool dataLoaded() const override;
private:
void createComponents(bool caption);

View File

@ -4347,10 +4347,13 @@ void HistoryWidget::onDocumentProgress(const FullMsgId &newId) {
const auto sendAction = (document && document->isVoiceMessage())
? SendAction::Type::UploadVoice
: SendAction::Type::UploadFile;
const auto progress = (document && document->uploading())
? document->uploadingData->offset
: 0;
updateSendAction(
item->history(),
sendAction,
document ? document->uploadOffset : 0);
progress);
Auth().data().requestItemRepaint(item);
}
}

View File

@ -850,8 +850,8 @@ bool File::updateStatusText() const {
DocumentData *document = getShownDocument();
if (document->status == FileDownloadFailed || document->status == FileUploadFailed) {
statusSize = FileStatusSizeFailed;
} else if (document->status == FileUploading) {
statusSize = document->uploadOffset;
} else if (document->uploading()) {
statusSize = document->uploadingData->offset;
} else if (document->loading()) {
statusSize = document->loadOffset();
} else if (document->loaded()) {

View File

@ -524,8 +524,8 @@ void Video::updateStatusText() {
int statusSize = 0;
if (_data->status == FileDownloadFailed || _data->status == FileUploadFailed) {
statusSize = FileStatusSizeFailed;
} else if (_data->status == FileUploading) {
statusSize = _data->uploadOffset;
} else if (_data->uploading()) {
statusSize = _data->uploadingData->offset;
} else if (_data->loading()) {
statusSize = _data->loadOffset();
} else if (_data->loaded()) {
@ -695,7 +695,7 @@ HistoryTextState Voice::getState(
if (inner.contains(point)) {
const auto link = loaded
? _openl
: (_data->loading() || _data->status == FileUploading)
: (_data->loading() || _data->uploading())
? _cancell
: _openl;
return { parent(), link };
@ -1023,7 +1023,7 @@ HistoryTextState Document::getState(
if (inner.contains(point)) {
const auto link = loaded
? _openl
: (_data->loading() || _data->status == FileUploading)
: (_data->loading() || _data->uploading())
? _cancell
: _openl;
return { parent(), link };
@ -1057,7 +1057,7 @@ HistoryTextState Document::getState(
if (rthumb.contains(point)) {
const auto link = loaded
? _openl
: (_data->loading() || _data->status == FileUploading)
: (_data->loading() || _data->uploading())
? _cancell
: _savel;
return { parent(), link };
@ -1133,8 +1133,8 @@ bool Document::updateStatusText() {
int32 statusSize = 0, realDuration = 0;
if (_data->status == FileDownloadFailed || _data->status == FileUploadFailed) {
statusSize = FileStatusSizeFailed;
} else if (_data->status == FileUploading) {
statusSize = _data->uploadOffset;
} else if (_data->uploading()) {
statusSize = _data->uploadingData->offset;
} else if (_data->loading()) {
statusSize = _data->loadOffset();
} else if (_data->loaded()) {

View File

@ -137,7 +137,6 @@ void Uploader::uploadMedia(const FullMsgId &msgId, const SendMediaReady &media)
} else {
document = App::feedDocument(media.document, media.photoThumbs.begin().value());
}
document->status = FileUploading;
if (!media.data.isEmpty()) {
document->setData(media.data);
}
@ -154,10 +153,10 @@ void Uploader::upload(
const std::shared_ptr<FileLoadResult> &file) {
if (file->type == SendMediaType::Photo) {
auto photo = App::feedPhoto(file->photo, file->photoThumbs);
photo->uploadingData = std::make_unique<PhotoData::UploadingData>(file->partssize);
photo->uploadingData = std::make_unique<Data::UploadState>(file->partssize);
} else if (file->type == SendMediaType::File || file->type == SendMediaType::Audio) {
auto document = file->thumb.isNull() ? App::feedDocument(file->document) : App::feedDocument(file->document, file->thumb);
document->status = FileUploading;
document->uploadingData = std::make_unique<Data::UploadState>(document->size);
if (!file->content.isEmpty()) {
document->setData(file->content);
}
@ -176,7 +175,7 @@ void Uploader::currentFailed() {
emit photoFailed(j->first);
} else if (j->second.type() == SendMediaType::File) {
const auto document = App::document(j->second.id());
if (document->status == FileUploading) {
if (document->uploading()) {
document->status = FileUploadFailed;
}
emit documentFailed(j->first);
@ -477,10 +476,9 @@ void Uploader::partLoaded(const MTPBool &result, mtpRequestId requestId) {
if (document->uploading()) {
const auto doneParts = file.docSentParts
- int(docRequestsSent.size());
document->uploadOffset = doneParts * file.docPartSize;
if (document->uploadOffset > document->size) {
document->uploadOffset = document->size;
}
document->uploadingData->offset = std::max(
document->uploadingData->size,
doneParts * file.docPartSize);
}
emit documentProgress(fullId);
}

View File

@ -180,8 +180,9 @@ struct SendingAlbum {
SendingAlbum();
uint64 groupId;
uint64 groupId = 0;
std::vector<Item> items;
bool silent = false;
};