mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-04-09 03:01:36 +00:00
Use Main::Session in download/upload.
This commit is contained in:
parent
3878a1b212
commit
4b354b0928
@ -28,7 +28,11 @@ void UrlAuthBox::Activate(
|
||||
int row,
|
||||
int column) {
|
||||
const auto itemId = message->fullId();
|
||||
const auto button = HistoryMessageMarkupButton::Get(itemId, row, column);
|
||||
const auto button = HistoryMessageMarkupButton::Get(
|
||||
&message->history()->owner(),
|
||||
itemId,
|
||||
row,
|
||||
column);
|
||||
if (button->requestId || !IsServerMsgId(itemId.msg)) {
|
||||
return;
|
||||
}
|
||||
@ -43,10 +47,13 @@ void UrlAuthBox::Activate(
|
||||
MTP_int(buttonId)
|
||||
)).done([=](const MTPUrlAuthResult &result) {
|
||||
const auto button = HistoryMessageMarkupButton::Get(
|
||||
&session->data(),
|
||||
itemId,
|
||||
row,
|
||||
column);
|
||||
if (!button) return;
|
||||
if (!button) {
|
||||
return;
|
||||
}
|
||||
|
||||
button->requestId = 0;
|
||||
result.match([&](const MTPDurlAuthResultAccepted &data) {
|
||||
@ -58,6 +65,7 @@ void UrlAuthBox::Activate(
|
||||
});
|
||||
}).fail([=](const RPCError &error) {
|
||||
const auto button = HistoryMessageMarkupButton::Get(
|
||||
&session->data(),
|
||||
itemId,
|
||||
row,
|
||||
column);
|
||||
@ -74,7 +82,11 @@ void UrlAuthBox::Request(
|
||||
int row,
|
||||
int column) {
|
||||
const auto itemId = message->fullId();
|
||||
const auto button = HistoryMessageMarkupButton::Get(itemId, row, column);
|
||||
const auto button = HistoryMessageMarkupButton::Get(
|
||||
&message->history()->owner(),
|
||||
itemId,
|
||||
row,
|
||||
column);
|
||||
if (button->requestId || !IsServerMsgId(itemId.msg)) {
|
||||
return;
|
||||
}
|
||||
|
@ -108,21 +108,27 @@ bool Set::thumbnailFailed() const {
|
||||
}
|
||||
|
||||
void Set::loadThumbnail() {
|
||||
auto &file = _thumbnail;
|
||||
const auto origin = Data::FileOriginStickerSet(id, access);
|
||||
const auto fromCloud = LoadFromCloudOrLocal;
|
||||
const auto cacheTag = Data::kImageCacheTag;
|
||||
const auto autoLoading = false;
|
||||
Data::LoadCloudFile(file, origin, fromCloud, autoLoading, cacheTag, [=] {
|
||||
const auto finalCheck = [=] {
|
||||
if (const auto active = activeThumbnailView()) {
|
||||
return !active->image() && active->content().isEmpty();
|
||||
}
|
||||
return true;
|
||||
}, [=](QByteArray result) {
|
||||
};
|
||||
const auto done = [=](QByteArray result) {
|
||||
if (const auto active = activeThumbnailView()) {
|
||||
active->set(&_owner->session(), std::move(result));
|
||||
}
|
||||
});
|
||||
};
|
||||
Data::LoadCloudFile(
|
||||
&_owner->session(),
|
||||
_thumbnail,
|
||||
Data::FileOriginStickerSet(id, access),
|
||||
LoadFromCloudOrLocal,
|
||||
autoLoading,
|
||||
Data::kImageCacheTag,
|
||||
finalCheck,
|
||||
done);
|
||||
}
|
||||
|
||||
const ImageLocation &Set::thumbnailLocation() const {
|
||||
|
@ -157,13 +157,15 @@ void ShowInFolder(const QString &filepath) {
|
||||
});
|
||||
}
|
||||
|
||||
QString DefaultDownloadPath() {
|
||||
QString DefaultDownloadPathFolder(not_null<Main::Session*> session) {
|
||||
return session->supportMode() ? u"Tsupport Desktop"_q : AppName.utf16();
|
||||
}
|
||||
|
||||
QString DefaultDownloadPath(not_null<Main::Session*> session) {
|
||||
return QStandardPaths::writableLocation(
|
||||
QStandardPaths::DownloadLocation)
|
||||
+ '/'
|
||||
+ (Main::Session::Exists() && Auth().supportMode()
|
||||
? "Tsupport Desktop"_cs
|
||||
: AppName).utf16()
|
||||
+ DefaultDownloadPathFolder(session)
|
||||
+ '/';
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
#include "base/observer.h"
|
||||
|
||||
namespace Main {
|
||||
class Session;
|
||||
} // namespace Main
|
||||
|
||||
// legacy
|
||||
bool filedialogGetSaveFile(
|
||||
QString &file,
|
||||
@ -36,7 +40,9 @@ void OpenWith(const QString &filepath, QPoint menuPosition);
|
||||
void Launch(const QString &filepath);
|
||||
void ShowInFolder(const QString &filepath);
|
||||
|
||||
[[nodiscard]] QString DefaultDownloadPath();
|
||||
[[nodiscard]] QString DefaultDownloadPathFolder(
|
||||
not_null<Main::Session*> session);
|
||||
[[nodiscard]] QString DefaultDownloadPath(not_null<Main::Session*> session);
|
||||
|
||||
namespace internal {
|
||||
|
||||
|
@ -45,7 +45,8 @@ void MegagroupInfo::setLocation(const ChannelLocation &location) {
|
||||
|
||||
ChannelData::ChannelData(not_null<Data::Session*> owner, PeerId id)
|
||||
: PeerData(owner, id)
|
||||
, inputChannel(MTP_inputChannel(MTP_int(bareId()), MTP_long(0))) {
|
||||
, inputChannel(MTP_inputChannel(MTP_int(bareId()), MTP_long(0)))
|
||||
, _ptsWaiter(&owner->session()) {
|
||||
Data::PeerFlagValue(
|
||||
this,
|
||||
MTPDchannel::Flag::f_megagroup
|
||||
|
@ -103,16 +103,26 @@ void CloudImage::load(not_null<Main::Session*> session, FileOrigin origin) {
|
||||
const auto fromCloud = LoadFromCloudOrLocal;
|
||||
const auto cacheTag = kImageCacheTag;
|
||||
const auto autoLoading = false;
|
||||
LoadCloudFile(_file, origin, fromCloud, autoLoading, cacheTag, [=] {
|
||||
const auto finalCheck = [=] {
|
||||
if (const auto active = activeView()) {
|
||||
return !active->image();
|
||||
}
|
||||
return true;
|
||||
}, [=](QImage result) {
|
||||
};
|
||||
const auto done = [=](QImage result) {
|
||||
if (const auto active = activeView()) {
|
||||
active->set(session, std::move(result));
|
||||
}
|
||||
});
|
||||
};
|
||||
LoadCloudFile(
|
||||
session,
|
||||
_file,
|
||||
origin,
|
||||
LoadFromCloudOrLocal,
|
||||
autoLoading,
|
||||
kImageCacheTag,
|
||||
finalCheck,
|
||||
done);
|
||||
}
|
||||
|
||||
const ImageLocation &CloudImage::location() const {
|
||||
@ -191,6 +201,7 @@ void UpdateCloudFile(
|
||||
}
|
||||
|
||||
void LoadCloudFile(
|
||||
not_null<Main::Session*> session,
|
||||
CloudFile &file,
|
||||
FileOrigin origin,
|
||||
LoadFromCloudSetting fromCloud,
|
||||
@ -212,6 +223,7 @@ void LoadCloudFile(
|
||||
}
|
||||
file.flags &= ~CloudFile::Flag::Cancelled;
|
||||
file.loader = CreateFileLoader(
|
||||
session,
|
||||
file.location.file(),
|
||||
origin,
|
||||
QString(),
|
||||
@ -256,6 +268,7 @@ void LoadCloudFile(
|
||||
}
|
||||
|
||||
void LoadCloudFile(
|
||||
not_null<Main::Session*> session,
|
||||
CloudFile &file,
|
||||
FileOrigin origin,
|
||||
LoadFromCloudSetting fromCloud,
|
||||
@ -276,6 +289,7 @@ void LoadCloudFile(
|
||||
}
|
||||
};
|
||||
LoadCloudFile(
|
||||
session,
|
||||
file,
|
||||
origin,
|
||||
fromCloud,
|
||||
@ -288,6 +302,7 @@ void LoadCloudFile(
|
||||
}
|
||||
|
||||
void LoadCloudFile(
|
||||
not_null<Main::Session*> session,
|
||||
CloudFile &file,
|
||||
FileOrigin origin,
|
||||
LoadFromCloudSetting fromCloud,
|
||||
@ -308,6 +323,7 @@ void LoadCloudFile(
|
||||
}
|
||||
};
|
||||
LoadCloudFile(
|
||||
session,
|
||||
file,
|
||||
origin,
|
||||
fromCloud,
|
||||
|
@ -96,6 +96,7 @@ void UpdateCloudFile(
|
||||
Fn<void(QImage)> usePreloaded = nullptr);
|
||||
|
||||
void LoadCloudFile(
|
||||
not_null<Main::Session*> session,
|
||||
CloudFile &file,
|
||||
FileOrigin origin,
|
||||
LoadFromCloudSetting fromCloud,
|
||||
@ -107,6 +108,7 @@ void LoadCloudFile(
|
||||
Fn<void()> progress = nullptr);
|
||||
|
||||
void LoadCloudFile(
|
||||
not_null<Main::Session*> session,
|
||||
CloudFile &file,
|
||||
FileOrigin origin,
|
||||
LoadFromCloudSetting fromCloud,
|
||||
|
@ -123,6 +123,7 @@ bool fileIsImage(const QString &name, const QString &mime) {
|
||||
}
|
||||
|
||||
QString FileNameUnsafe(
|
||||
not_null<Main::Session*> session,
|
||||
const QString &title,
|
||||
const QString &filter,
|
||||
const QString &prefix,
|
||||
@ -176,7 +177,7 @@ QString FileNameUnsafe(
|
||||
|
||||
QString path;
|
||||
if (Global::DownloadPath().isEmpty()) {
|
||||
path = File::DefaultDownloadPath();
|
||||
path = File::DefaultDownloadPath(session);
|
||||
} else if (Global::DownloadPath() == qsl("tmp")) {
|
||||
path = cTempDir();
|
||||
} else {
|
||||
@ -210,6 +211,7 @@ QString FileNameUnsafe(
|
||||
}
|
||||
|
||||
QString FileNameForSave(
|
||||
not_null<Main::Session*> session,
|
||||
const QString &title,
|
||||
const QString &filter,
|
||||
const QString &prefix,
|
||||
@ -217,6 +219,7 @@ QString FileNameForSave(
|
||||
bool savingAs,
|
||||
const QDir &dir) {
|
||||
const auto result = FileNameUnsafe(
|
||||
session,
|
||||
title,
|
||||
filter,
|
||||
prefix,
|
||||
@ -285,7 +288,14 @@ QString DocumentFileNameForSave(
|
||||
prefix = qsl("doc");
|
||||
}
|
||||
|
||||
return FileNameForSave(caption, filter, prefix, name, forceSavingAs, dir);
|
||||
return FileNameForSave(
|
||||
&data->session(),
|
||||
caption,
|
||||
filter,
|
||||
prefix,
|
||||
name,
|
||||
forceSavingAs,
|
||||
dir);
|
||||
}
|
||||
|
||||
DocumentClickHandler::DocumentClickHandler(
|
||||
@ -655,20 +665,27 @@ bool DocumentData::thumbnailFailed() const {
|
||||
}
|
||||
|
||||
void DocumentData::loadThumbnail(Data::FileOrigin origin) {
|
||||
auto &file = _thumbnail;
|
||||
const auto fromCloud = LoadFromCloudOrLocal;
|
||||
const auto cacheTag = Data::kImageCacheTag;
|
||||
const auto autoLoading = false;
|
||||
Data::LoadCloudFile(file, origin, fromCloud, autoLoading, cacheTag, [=] {
|
||||
const auto finalCheck = [=] {
|
||||
if (const auto active = activeMediaView()) {
|
||||
return !active->thumbnail();
|
||||
}
|
||||
return true;
|
||||
}, [=](QImage result) {
|
||||
};
|
||||
const auto done = [=](QImage result) {
|
||||
if (const auto active = activeMediaView()) {
|
||||
active->setThumbnail(std::move(result));
|
||||
}
|
||||
});
|
||||
};
|
||||
Data::LoadCloudFile(
|
||||
&session(),
|
||||
_thumbnail,
|
||||
origin,
|
||||
LoadFromCloudOrLocal,
|
||||
autoLoading,
|
||||
Data::kImageCacheTag,
|
||||
finalCheck,
|
||||
done);
|
||||
}
|
||||
|
||||
const ImageLocation &DocumentData::thumbnailLocation() const {
|
||||
@ -692,20 +709,27 @@ bool DocumentData::videoThumbnailFailed() const {
|
||||
}
|
||||
|
||||
void DocumentData::loadVideoThumbnail(Data::FileOrigin origin) {
|
||||
auto &file = _videoThumbnail;
|
||||
const auto fromCloud = LoadFromCloudOrLocal;
|
||||
const auto cacheTag = Data::kAnimationCacheTag;
|
||||
const auto autoLoading = false;
|
||||
Data::LoadCloudFile(file, origin, fromCloud, autoLoading, cacheTag, [=] {
|
||||
const auto finalCheck = [=] {
|
||||
if (const auto active = activeMediaView()) {
|
||||
return active->videoThumbnailContent().isEmpty();
|
||||
}
|
||||
return true;
|
||||
}, [=](QByteArray result) {
|
||||
};
|
||||
const auto done = [=](QByteArray result) {
|
||||
if (const auto active = activeMediaView()) {
|
||||
active->setVideoThumbnail(std::move(result));
|
||||
}
|
||||
});
|
||||
};
|
||||
Data::LoadCloudFile(
|
||||
&session(),
|
||||
_videoThumbnail,
|
||||
origin,
|
||||
LoadFromCloudOrLocal,
|
||||
autoLoading,
|
||||
Data::kAnimationCacheTag,
|
||||
finalCheck,
|
||||
done);
|
||||
}
|
||||
|
||||
const ImageLocation &DocumentData::videoThumbnailLocation() const {
|
||||
@ -957,6 +981,7 @@ void DocumentData::save(
|
||||
auto reader = owner().streaming().sharedReader(this, origin, true);
|
||||
if (reader) {
|
||||
_loader = std::make_unique<Storage::StreamedFileDownloader>(
|
||||
&session(),
|
||||
id,
|
||||
_dc,
|
||||
origin,
|
||||
@ -972,6 +997,7 @@ void DocumentData::save(
|
||||
cacheTag());
|
||||
} else if (hasWebLocation()) {
|
||||
_loader = std::make_unique<mtpFileLoader>(
|
||||
&session(),
|
||||
_urlLocation,
|
||||
size,
|
||||
fromCloud,
|
||||
@ -979,6 +1005,7 @@ void DocumentData::save(
|
||||
cacheTag());
|
||||
} else if (!_access && !_url.isEmpty()) {
|
||||
_loader = std::make_unique<webFileLoader>(
|
||||
&session(),
|
||||
_url,
|
||||
toFile,
|
||||
fromCloud,
|
||||
@ -986,6 +1013,7 @@ void DocumentData::save(
|
||||
cacheTag());
|
||||
} else {
|
||||
_loader = std::make_unique<mtpFileLoader>(
|
||||
&session(),
|
||||
StorageFileLocation(
|
||||
_dc,
|
||||
session().userId(),
|
||||
|
@ -432,6 +432,7 @@ private:
|
||||
};
|
||||
|
||||
QString FileNameForSave(
|
||||
not_null<Main::Session*> session,
|
||||
const QString &title,
|
||||
const QString &filter,
|
||||
const QString &prefix,
|
||||
|
@ -233,32 +233,44 @@ void PhotoData::load(
|
||||
LoadFromCloudSetting fromCloud,
|
||||
bool autoLoading) {
|
||||
const auto index = validSizeIndex(size);
|
||||
auto &image = _images[index];
|
||||
|
||||
// Could've changed, if the requested size didn't have a location.
|
||||
const auto loadingSize = static_cast<PhotoSize>(index);
|
||||
const auto cacheTag = Data::kImageCacheTag;
|
||||
Data::LoadCloudFile(image, origin, fromCloud, autoLoading, cacheTag, [=] {
|
||||
const auto finalCheck = [=] {
|
||||
if (const auto active = activeMediaView()) {
|
||||
return !active->image(size);
|
||||
}
|
||||
return true;
|
||||
}, [=](QImage result) {
|
||||
};
|
||||
const auto done = [=](QImage result) {
|
||||
if (const auto active = activeMediaView()) {
|
||||
active->set(loadingSize, std::move(result));
|
||||
}
|
||||
if (loadingSize == PhotoSize::Large) {
|
||||
_owner->photoLoadDone(this);
|
||||
}
|
||||
}, [=](bool started) {
|
||||
};
|
||||
const auto fail = [=](bool started) {
|
||||
if (loadingSize == PhotoSize::Large) {
|
||||
_owner->photoLoadFail(this, started);
|
||||
}
|
||||
}, [=] {
|
||||
};
|
||||
const auto progress = [=] {
|
||||
if (loadingSize == PhotoSize::Large) {
|
||||
_owner->photoLoadProgress(this);
|
||||
}
|
||||
});
|
||||
};
|
||||
Data::LoadCloudFile(
|
||||
&session(),
|
||||
_images[index],
|
||||
origin,
|
||||
fromCloud,
|
||||
autoLoading,
|
||||
Data::kImageCacheTag,
|
||||
finalCheck,
|
||||
done,
|
||||
fail,
|
||||
progress);
|
||||
|
||||
if (size == PhotoSize::Large) {
|
||||
_owner->notifyPhotoLayoutChanged(this);
|
||||
|
@ -12,8 +12,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "apiwrap.h"
|
||||
#include "app.h"
|
||||
|
||||
PtsWaiter::PtsWaiter(not_null<Main::Session*> session) : _session(session) {
|
||||
}
|
||||
|
||||
uint64 PtsWaiter::ptsKey(PtsSkippedQueue queue, int32 pts) {
|
||||
return _queue.insert(uint64(uint32(pts)) << 32 | (++_skippedKey), queue).key();
|
||||
return _queue.emplace(
|
||||
uint64(uint32(pts)) << 32 | (++_skippedKey),
|
||||
queue
|
||||
).first->first;
|
||||
}
|
||||
|
||||
void PtsWaiter::setWaitingForSkipped(ChannelData *channel, int32 ms) {
|
||||
@ -47,17 +53,25 @@ void PtsWaiter::checkForWaiting(ChannelData *channel) {
|
||||
}
|
||||
|
||||
void PtsWaiter::applySkippedUpdates(ChannelData *channel) {
|
||||
if (!_waitingForSkipped) return;
|
||||
if (!_waitingForSkipped) {
|
||||
return;
|
||||
}
|
||||
|
||||
setWaitingForSkipped(channel, -1);
|
||||
|
||||
if (_queue.isEmpty()) return;
|
||||
if (_queue.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
++_applySkippedLevel;
|
||||
for (auto i = _queue.cbegin(), e = _queue.cend(); i != e; ++i) {
|
||||
switch (i.value()) {
|
||||
case SkippedUpdate: Auth().api().applyUpdateNoPtsCheck(_updateQueue.value(i.key())); break;
|
||||
case SkippedUpdates: Auth().api().applyUpdatesNoPtsCheck(_updatesQueue.value(i.key())); break;
|
||||
switch (i->second) {
|
||||
case SkippedUpdate: {
|
||||
_session->api().applyUpdateNoPtsCheck(_updateQueue[i->first]);
|
||||
} break;
|
||||
case SkippedUpdates: {
|
||||
_session->api().applyUpdatesNoPtsCheck(_updatesQueue[i->first]);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
--_applySkippedLevel;
|
||||
@ -71,7 +85,11 @@ void PtsWaiter::clearSkippedUpdates() {
|
||||
_applySkippedLevel = 0;
|
||||
}
|
||||
|
||||
bool PtsWaiter::updated(ChannelData *channel, int32 pts, int32 count, const MTPUpdates &updates) {
|
||||
bool PtsWaiter::updated(
|
||||
ChannelData *channel,
|
||||
int32 pts,
|
||||
int32 count,
|
||||
const MTPUpdates &updates) {
|
||||
if (_requesting || _applySkippedLevel) {
|
||||
return true;
|
||||
} else if (pts <= _good && count > 0) {
|
||||
@ -79,11 +97,15 @@ bool PtsWaiter::updated(ChannelData *channel, int32 pts, int32 count, const MTPU
|
||||
} else if (check(channel, pts, count)) {
|
||||
return true;
|
||||
}
|
||||
_updatesQueue.insert(ptsKey(SkippedUpdates, pts), updates);
|
||||
_updatesQueue.emplace(ptsKey(SkippedUpdates, pts), updates);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PtsWaiter::updated(ChannelData *channel, int32 pts, int32 count, const MTPUpdate &update) {
|
||||
bool PtsWaiter::updated(
|
||||
ChannelData *channel,
|
||||
int32 pts,
|
||||
int32 count,
|
||||
const MTPUpdate &update) {
|
||||
if (_requesting || _applySkippedLevel) {
|
||||
return true;
|
||||
} else if (pts <= _good && count > 0) {
|
||||
@ -91,7 +113,7 @@ bool PtsWaiter::updated(ChannelData *channel, int32 pts, int32 count, const MTPU
|
||||
} else if (check(channel, pts, count)) {
|
||||
return true;
|
||||
}
|
||||
_updateQueue.insert(ptsKey(SkippedUpdate, pts), update);
|
||||
_updateQueue.emplace(ptsKey(SkippedUpdate, pts), update);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -104,35 +126,46 @@ bool PtsWaiter::updated(ChannelData *channel, int32 pts, int32 count) {
|
||||
return check(channel, pts, count);
|
||||
}
|
||||
|
||||
bool PtsWaiter::updateAndApply(ChannelData *channel, int32 pts, int32 count, const MTPUpdates &updates) {
|
||||
bool PtsWaiter::updateAndApply(
|
||||
ChannelData *channel,
|
||||
int32 pts,
|
||||
int32 count,
|
||||
const MTPUpdates &updates) {
|
||||
if (!updated(channel, pts, count, updates)) {
|
||||
return false;
|
||||
}
|
||||
if (!_waitingForSkipped || _queue.isEmpty()) {
|
||||
if (!_waitingForSkipped || _queue.empty()) {
|
||||
// Optimization - no need to put in queue and back.
|
||||
Auth().api().applyUpdatesNoPtsCheck(updates);
|
||||
_session->api().applyUpdatesNoPtsCheck(updates);
|
||||
} else {
|
||||
_updatesQueue.insert(ptsKey(SkippedUpdates, pts), updates);
|
||||
_updatesQueue.emplace(ptsKey(SkippedUpdates, pts), updates);
|
||||
applySkippedUpdates(channel);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PtsWaiter::updateAndApply(ChannelData *channel, int32 pts, int32 count, const MTPUpdate &update) {
|
||||
bool PtsWaiter::updateAndApply(
|
||||
ChannelData *channel,
|
||||
int32 pts,
|
||||
int32 count,
|
||||
const MTPUpdate &update) {
|
||||
if (!updated(channel, pts, count, update)) {
|
||||
return false;
|
||||
}
|
||||
if (!_waitingForSkipped || _queue.isEmpty()) {
|
||||
if (!_waitingForSkipped || _queue.empty()) {
|
||||
// Optimization - no need to put in queue and back.
|
||||
Auth().api().applyUpdateNoPtsCheck(update);
|
||||
_session->api().applyUpdateNoPtsCheck(update);
|
||||
} else {
|
||||
_updateQueue.insert(ptsKey(SkippedUpdate, pts), update);
|
||||
_updateQueue.emplace(ptsKey(SkippedUpdate, pts), update);
|
||||
applySkippedUpdates(channel);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PtsWaiter::updateAndApply(ChannelData *channel, int32 pts, int32 count) {
|
||||
bool PtsWaiter::updateAndApply(
|
||||
ChannelData *channel,
|
||||
int32 pts,
|
||||
int32 count) {
|
||||
if (!updated(channel, pts, count)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -7,6 +7,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace Main {
|
||||
class Session;
|
||||
} // namespace Main
|
||||
|
||||
enum PtsSkippedQueue {
|
||||
SkippedUpdate,
|
||||
SkippedUpdates,
|
||||
@ -14,7 +18,7 @@ enum PtsSkippedQueue {
|
||||
|
||||
class PtsWaiter {
|
||||
public:
|
||||
PtsWaiter() = default;
|
||||
explicit PtsWaiter(not_null<Main::Session*> session);
|
||||
|
||||
// 1s wait for skipped seq or pts in updates.
|
||||
static constexpr auto kWaitForSkippedTimeout = 1000;
|
||||
@ -84,9 +88,10 @@ private:
|
||||
uint64 ptsKey(PtsSkippedQueue queue, int32 pts);
|
||||
void checkForWaiting(ChannelData *channel);
|
||||
|
||||
QMap<uint64, PtsSkippedQueue> _queue;
|
||||
QMap<uint64, MTPUpdate> _updateQueue;
|
||||
QMap<uint64, MTPUpdates> _updatesQueue;
|
||||
const not_null<Main::Session*> _session;
|
||||
base::flat_map<uint64, PtsSkippedQueue> _queue;
|
||||
base::flat_map<uint64, MTPUpdate> _updateQueue;
|
||||
base::flat_map<uint64, MTPUpdates> _updatesQueue;
|
||||
int32 _good = 0;
|
||||
int32 _last = 0;
|
||||
int32 _count = 0;
|
||||
|
@ -906,6 +906,7 @@ void Session::startExport(const MTPInputPeer &singlePeer) {
|
||||
}
|
||||
_export = std::make_unique<Export::Controller>(singlePeer);
|
||||
_exportPanel = std::make_unique<Export::View::PanelController>(
|
||||
&session(),
|
||||
_export.get());
|
||||
|
||||
_exportViewChanges.fire(_exportPanel.get());
|
||||
@ -944,9 +945,9 @@ void Session::suggestStartExport() {
|
||||
_session,
|
||||
[=] { suggestStartExport(); });
|
||||
} else if (_export) {
|
||||
Export::View::ClearSuggestStart();
|
||||
Export::View::ClearSuggestStart(&session());
|
||||
} else {
|
||||
_exportSuggestion = Export::View::SuggestStart();
|
||||
_exportSuggestion = Export::View::SuggestStart(&session());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -170,23 +170,28 @@ rpl::producer<SparseIdsMergedSlice> SharedMediaMergedViewer(
|
||||
std::move(createSimpleViewer));
|
||||
}
|
||||
|
||||
SharedMediaWithLastSlice::SharedMediaWithLastSlice(Key key)
|
||||
SharedMediaWithLastSlice::SharedMediaWithLastSlice(
|
||||
not_null<Main::Session*> session,
|
||||
Key key)
|
||||
: SharedMediaWithLastSlice(
|
||||
session,
|
||||
key,
|
||||
SparseIdsMergedSlice(ViewerKey(key)),
|
||||
EndingSlice(key)) {
|
||||
}
|
||||
|
||||
SharedMediaWithLastSlice::SharedMediaWithLastSlice(
|
||||
not_null<Main::Session*> session,
|
||||
Key key,
|
||||
SparseIdsMergedSlice slice,
|
||||
std::optional<SparseIdsMergedSlice> ending)
|
||||
: _key(key)
|
||||
: _session(session)
|
||||
, _key(key)
|
||||
, _slice(std::move(slice))
|
||||
, _ending(std::move(ending))
|
||||
, _lastPhotoId(LastPeerPhotoId(key.peerId))
|
||||
, _lastPhotoId(LastPeerPhotoId(session, key.peerId))
|
||||
, _isolatedLastPhoto(_key.type == Type::ChatPhoto
|
||||
? IsLastIsolated(_slice, _ending, _lastPhotoId)
|
||||
? IsLastIsolated(session, _slice, _ending, _lastPhotoId)
|
||||
: false) {
|
||||
}
|
||||
|
||||
@ -296,7 +301,7 @@ SharedMediaWithLastSlice::Value SharedMediaWithLastSlice::operator[](int index)
|
||||
}
|
||||
return (index < _slice.size())
|
||||
? Value(_slice[index])
|
||||
: Value(Auth().data().photo(*_lastPhotoId));
|
||||
: Value(_session->data().photo(*_lastPhotoId));
|
||||
}
|
||||
|
||||
std::optional<int> SharedMediaWithLastSlice::distance(
|
||||
@ -315,8 +320,9 @@ void SharedMediaWithLastSlice::reverse() {
|
||||
}
|
||||
|
||||
std::optional<PhotoId> SharedMediaWithLastSlice::LastPeerPhotoId(
|
||||
not_null<Main::Session*> session,
|
||||
PeerId peerId) {
|
||||
if (const auto peer = Auth().data().peerLoaded(peerId)) {
|
||||
if (const auto peer = session->data().peerLoaded(peerId)) {
|
||||
return peer->userpicPhotoUnknown()
|
||||
? std::nullopt
|
||||
: base::make_optional(peer->userpicPhotoId());
|
||||
@ -325,6 +331,7 @@ std::optional<PhotoId> SharedMediaWithLastSlice::LastPeerPhotoId(
|
||||
}
|
||||
|
||||
std::optional<bool> SharedMediaWithLastSlice::IsLastIsolated(
|
||||
not_null<Main::Session*> session,
|
||||
const SparseIdsMergedSlice &slice,
|
||||
const std::optional<SparseIdsMergedSlice> &ending,
|
||||
std::optional<PhotoId> lastPeerPhotoId) {
|
||||
@ -334,7 +341,7 @@ std::optional<bool> SharedMediaWithLastSlice::IsLastIsolated(
|
||||
return false;
|
||||
}
|
||||
return LastFullMsgId(ending ? *ending : slice)
|
||||
| [](FullMsgId msgId) { return Auth().data().message(msgId); }
|
||||
| [&](FullMsgId msgId) { return session->data().message(msgId); }
|
||||
| [](HistoryItem *item) { return item ? item->media() : nullptr; }
|
||||
| [](Data::Media *media) { return media ? media->photo() : nullptr; }
|
||||
| [](PhotoData *photo) { return photo ? photo->id : 0; }
|
||||
@ -367,6 +374,7 @@ rpl::producer<SharedMediaWithLastSlice> SharedMediaWithLastViewer(
|
||||
limitAfter
|
||||
) | rpl::start_with_next([=](SparseIdsMergedSlice &&update) {
|
||||
consumer.put_next(SharedMediaWithLastSlice(
|
||||
session,
|
||||
key,
|
||||
std::move(update),
|
||||
std::nullopt));
|
||||
@ -391,6 +399,7 @@ rpl::producer<SharedMediaWithLastSlice> SharedMediaWithLastViewer(
|
||||
SparseIdsMergedSlice &&viewer,
|
||||
SparseIdsMergedSlice &&ending) {
|
||||
consumer.put_next(SharedMediaWithLastSlice(
|
||||
session,
|
||||
key,
|
||||
std::move(viewer),
|
||||
std::move(ending)));
|
||||
|
@ -97,8 +97,11 @@ public:
|
||||
|
||||
};
|
||||
|
||||
SharedMediaWithLastSlice(Key key);
|
||||
SharedMediaWithLastSlice(
|
||||
not_null<Main::Session*> session,
|
||||
Key key);
|
||||
SharedMediaWithLastSlice(
|
||||
not_null<Main::Session*> session,
|
||||
Key key,
|
||||
SparseIdsMergedSlice slice,
|
||||
std::optional<SparseIdsMergedSlice> ending);
|
||||
@ -137,8 +140,11 @@ private:
|
||||
: std::nullopt;
|
||||
}
|
||||
|
||||
static std::optional<PhotoId> LastPeerPhotoId(PeerId peerId);
|
||||
static std::optional<PhotoId> LastPeerPhotoId(
|
||||
not_null<Main::Session*> session,
|
||||
PeerId peerId);
|
||||
static std::optional<bool> IsLastIsolated(
|
||||
not_null<Main::Session*> session,
|
||||
const SparseIdsMergedSlice &slice,
|
||||
const std::optional<SparseIdsMergedSlice> &ending,
|
||||
std::optional<PhotoId> lastPeerPhotoId);
|
||||
@ -175,6 +181,7 @@ private:
|
||||
std::optional<int> skippedAfterImpl() const;
|
||||
std::optional<int> indexOfImpl(Value fullId) const;
|
||||
|
||||
not_null<Main::Session*> _session;
|
||||
Key _key;
|
||||
SparseIdsMergedSlice _slice;
|
||||
std::optional<SparseIdsMergedSlice> _ending;
|
||||
|
@ -32,14 +32,18 @@ constexpr auto kSaveSettingsTimeout = crl::time(1000);
|
||||
|
||||
class SuggestBox : public Ui::BoxContent {
|
||||
public:
|
||||
SuggestBox(QWidget*);
|
||||
SuggestBox(QWidget*, not_null<Main::Session*> session);
|
||||
|
||||
protected:
|
||||
void prepare() override;
|
||||
|
||||
private:
|
||||
const not_null<Main::Session*> _session;
|
||||
|
||||
};
|
||||
|
||||
SuggestBox::SuggestBox(QWidget*) {
|
||||
SuggestBox::SuggestBox(QWidget*, not_null<Main::Session*> session)
|
||||
: _session(session) {
|
||||
}
|
||||
|
||||
void SuggestBox::prepare() {
|
||||
@ -47,7 +51,7 @@ void SuggestBox::prepare() {
|
||||
|
||||
addButton(tr::lng_box_ok(), [=] {
|
||||
closeBox();
|
||||
Auth().data().startExport(Local::ReadExportSettings().singlePeer);
|
||||
_session->data().startExport(Local::ReadExportSettings().singlePeer);
|
||||
});
|
||||
addButton(tr::lng_export_suggest_cancel(), [=] { closeBox(); });
|
||||
setCloseByOutsideClick(false);
|
||||
@ -85,13 +89,15 @@ Environment PrepareEnvironment() {
|
||||
return result;
|
||||
}
|
||||
|
||||
QPointer<Ui::BoxContent> SuggestStart() {
|
||||
ClearSuggestStart();
|
||||
return Ui::show(Box<SuggestBox>(), Ui::LayerOption::KeepOther).data();
|
||||
QPointer<Ui::BoxContent> SuggestStart(not_null<Main::Session*> session) {
|
||||
ClearSuggestStart(session);
|
||||
return Ui::show(
|
||||
Box<SuggestBox>(session),
|
||||
Ui::LayerOption::KeepOther).data();
|
||||
}
|
||||
|
||||
void ClearSuggestStart() {
|
||||
Auth().data().clearExportSuggestion();
|
||||
void ClearSuggestStart(not_null<Main::Session*> session) {
|
||||
session->data().clearExportSuggestion();
|
||||
|
||||
auto settings = Local::ReadExportSettings();
|
||||
if (settings.availableAt) {
|
||||
@ -100,33 +106,36 @@ void ClearSuggestStart() {
|
||||
}
|
||||
}
|
||||
|
||||
bool IsDefaultPath(const QString &path) {
|
||||
bool IsDefaultPath(not_null<Main::Session*> session, const QString &path) {
|
||||
const auto check = [](const QString &value) {
|
||||
const auto result = value.endsWith('/')
|
||||
? value.mid(0, value.size() - 1)
|
||||
: value;
|
||||
return Platform::IsWindows() ? result.toLower() : result;
|
||||
};
|
||||
return (check(path) == check(File::DefaultDownloadPath()));
|
||||
return (check(path) == check(File::DefaultDownloadPath(session)));
|
||||
}
|
||||
|
||||
void ResolveSettings(Settings &settings) {
|
||||
void ResolveSettings(not_null<Main::Session*> session, Settings &settings) {
|
||||
if (settings.path.isEmpty()) {
|
||||
settings.path = File::DefaultDownloadPath();
|
||||
settings.path = File::DefaultDownloadPath(session);
|
||||
settings.forceSubPath = true;
|
||||
} else {
|
||||
settings.forceSubPath = IsDefaultPath(settings.path);
|
||||
settings.forceSubPath = IsDefaultPath(session, settings.path);
|
||||
}
|
||||
if (!settings.onlySinglePeer()) {
|
||||
settings.singlePeerFrom = settings.singlePeerTill = 0;
|
||||
}
|
||||
}
|
||||
|
||||
PanelController::PanelController(not_null<Controller*> process)
|
||||
: _process(process)
|
||||
PanelController::PanelController(
|
||||
not_null<Main::Session*> session,
|
||||
not_null<Controller*> process)
|
||||
: _session(session)
|
||||
, _process(process)
|
||||
, _settings(std::make_unique<Settings>(Local::ReadExportSettings()))
|
||||
, _saveSettingsTimer([=] { saveSettings(); }) {
|
||||
ResolveSettings(*_settings);
|
||||
ResolveSettings(session, *_settings);
|
||||
|
||||
_process->state(
|
||||
) | rpl::start_with_next([=](State &&state) {
|
||||
@ -165,6 +174,7 @@ void PanelController::createPanel() {
|
||||
void PanelController::showSettings() {
|
||||
auto settings = base::make_unique_q<SettingsWidget>(
|
||||
_panel,
|
||||
_session,
|
||||
*_settings);
|
||||
settings->setShowBoxCallback([=](object_ptr<Ui::BoxContent> box) {
|
||||
_panel->showBox(
|
||||
@ -220,7 +230,7 @@ void PanelController::showError(const ApiErrorState &error) {
|
||||
_settings->availableAt = base::unixtime::now() + seconds;
|
||||
_saveSettingsTimer.callOnce(kSaveSettingsTimeout);
|
||||
|
||||
Auth().data().suggestStartExport(_settings->availableAt);
|
||||
_session->data().suggestStartExport(_settings->availableAt);
|
||||
} else {
|
||||
showCriticalError("API Error happened :(\n"
|
||||
+ QString::number(error.data.code()) + ": " + error.data.type()
|
||||
@ -273,7 +283,7 @@ void PanelController::showError(const QString &text) {
|
||||
|
||||
void PanelController::showProgress() {
|
||||
_settings->availableAt = 0;
|
||||
ClearSuggestStart();
|
||||
ClearSuggestStart(_session);
|
||||
|
||||
_panel->setTitle(tr::lng_export_progress_title());
|
||||
|
||||
@ -388,7 +398,7 @@ void PanelController::saveSettings() const {
|
||||
return Platform::IsWindows() ? result.toLower() : result;
|
||||
};
|
||||
auto settings = *_settings;
|
||||
if (check(settings.path) == check(File::DefaultDownloadPath())) {
|
||||
if (check(settings.path) == check(File::DefaultDownloadPath(_session))) {
|
||||
settings.path = QString();
|
||||
}
|
||||
Local::WriteExportSettings(settings);
|
||||
|
@ -17,6 +17,10 @@ class SeparatePanel;
|
||||
class BoxContent;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Main {
|
||||
class Session;
|
||||
} // namespace Main
|
||||
|
||||
namespace Export {
|
||||
|
||||
struct Environment;
|
||||
@ -24,16 +28,18 @@ struct Environment;
|
||||
namespace View {
|
||||
|
||||
Environment PrepareEnvironment();
|
||||
QPointer<Ui::BoxContent> SuggestStart();
|
||||
void ClearSuggestStart();
|
||||
bool IsDefaultPath(const QString &path);
|
||||
void ResolveSettings(Settings &settings);
|
||||
QPointer<Ui::BoxContent> SuggestStart(not_null<Main::Session*> session);
|
||||
void ClearSuggestStart(not_null<Main::Session*> session);
|
||||
bool IsDefaultPath(not_null<Main::Session*> session, const QString &path);
|
||||
void ResolveSettings(not_null<Main::Session*> session, Settings &settings);
|
||||
|
||||
class Panel;
|
||||
|
||||
class PanelController {
|
||||
public:
|
||||
PanelController(not_null<Controller*> process);
|
||||
PanelController(
|
||||
not_null<Main::Session*> session,
|
||||
not_null<Controller*> process);
|
||||
~PanelController();
|
||||
|
||||
void activatePanel();
|
||||
@ -63,7 +69,8 @@ private:
|
||||
|
||||
void saveSettings() const;
|
||||
|
||||
not_null<Controller*> _process;
|
||||
const not_null<Main::Session*> _session;
|
||||
const not_null<Controller*> _process;
|
||||
std::unique_ptr<Settings> _settings;
|
||||
base::Timer _saveSettingsTimer;
|
||||
|
||||
|
@ -36,7 +36,9 @@ namespace {
|
||||
|
||||
constexpr auto kMegabyte = 1024 * 1024;
|
||||
|
||||
[[nodiscard]] PeerId ReadPeerId(const MTPInputPeer &data) {
|
||||
[[nodiscard]] PeerId ReadPeerId(
|
||||
not_null<Main::Session*> session,
|
||||
const MTPInputPeer &data) {
|
||||
return data.match([](const MTPDinputPeerUser &data) {
|
||||
return peerFromUser(data.vuser_id().v);
|
||||
}, [](const MTPDinputPeerUserFromMessage &data) {
|
||||
@ -47,8 +49,8 @@ constexpr auto kMegabyte = 1024 * 1024;
|
||||
return peerFromChannel(data.vchannel_id().v);
|
||||
}, [](const MTPDinputPeerChannelFromMessage &data) {
|
||||
return peerFromChannel(data.vchannel_id().v);
|
||||
}, [](const MTPDinputPeerSelf &data) {
|
||||
return Auth().userPeerId();
|
||||
}, [&](const MTPDinputPeerSelf &data) {
|
||||
return session->userPeerId();
|
||||
}, [](const MTPDinputPeerEmpty &data) {
|
||||
return PeerId(0);
|
||||
});
|
||||
@ -106,11 +108,15 @@ int SizeLimitByIndex(int index) {
|
||||
return megabytes * kMegabyte;
|
||||
}
|
||||
|
||||
SettingsWidget::SettingsWidget(QWidget *parent, Settings data)
|
||||
SettingsWidget::SettingsWidget(
|
||||
QWidget *parent,
|
||||
not_null<Main::Session*> session,
|
||||
Settings data)
|
||||
: RpWidget(parent)
|
||||
, _singlePeerId(ReadPeerId(data.singlePeer))
|
||||
, _session(session)
|
||||
, _singlePeerId(ReadPeerId(session, data.singlePeer))
|
||||
, _internal_data(std::move(data)) {
|
||||
ResolveSettings(_internal_data);
|
||||
ResolveSettings(session, _internal_data);
|
||||
setupContent();
|
||||
}
|
||||
|
||||
@ -278,9 +284,9 @@ void SettingsWidget::addLocationLabel(
|
||||
auto pathLink = value() | rpl::map([](const Settings &data) {
|
||||
return data.path;
|
||||
}) | rpl::distinct_until_changed(
|
||||
) | rpl::map([](const QString &path) {
|
||||
const auto text = IsDefaultPath(path)
|
||||
? QString("Downloads/Telegram Desktop")
|
||||
) | rpl::map([=](const QString &path) {
|
||||
const auto text = IsDefaultPath(_session, path)
|
||||
? u"Downloads/"_q + File::DefaultDownloadPathFolder(_session)
|
||||
: path;
|
||||
return Ui::Text::Link(
|
||||
QDir::toNativeSeparators(text),
|
||||
@ -326,9 +332,9 @@ void SettingsWidget::addFormatAndLocationLabel(
|
||||
auto pathLink = value() | rpl::map([](const Settings &data) {
|
||||
return data.path;
|
||||
}) | rpl::distinct_until_changed(
|
||||
) | rpl::map([](const QString &path) {
|
||||
const auto text = IsDefaultPath(path)
|
||||
? u"Downloads/Telegram Desktop"_q
|
||||
) | rpl::map([=](const QString &path) {
|
||||
const auto text = IsDefaultPath(_session, path)
|
||||
? u"Downloads/"_q + File::DefaultDownloadPathFolder(_session)
|
||||
: path;
|
||||
return Ui::Text::Link(
|
||||
QDir::toNativeSeparators(text),
|
||||
@ -774,7 +780,7 @@ void SettingsWidget::chooseFolder() {
|
||||
const auto callback = [=](QString &&result) {
|
||||
changeData([&](Settings &data) {
|
||||
data.path = std::move(result);
|
||||
data.forceSubPath = IsDefaultPath(data.path);
|
||||
data.forceSubPath = IsDefaultPath(_session, data.path);
|
||||
});
|
||||
};
|
||||
FileDialog::GetFolder(
|
||||
|
@ -18,6 +18,10 @@ class ScrollArea;
|
||||
class BoxContent;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Main {
|
||||
class Session;
|
||||
} // namespace Main
|
||||
|
||||
namespace Export {
|
||||
namespace View {
|
||||
|
||||
@ -26,7 +30,10 @@ int SizeLimitByIndex(int index);
|
||||
|
||||
class SettingsWidget : public Ui::RpWidget {
|
||||
public:
|
||||
SettingsWidget(QWidget *parent, Settings data);
|
||||
SettingsWidget(
|
||||
QWidget *parent,
|
||||
not_null<Main::Session*> session,
|
||||
Settings data);
|
||||
|
||||
rpl::producer<Settings> value() const;
|
||||
rpl::producer<Settings> changes() const;
|
||||
@ -98,6 +105,7 @@ private:
|
||||
template <typename Callback>
|
||||
void changeData(Callback &&callback);
|
||||
|
||||
const not_null<Main::Session*> _session;
|
||||
PeerId _singlePeerId = 0;
|
||||
Fn<void(object_ptr<Ui::BoxContent>)> _showBoxCallback;
|
||||
|
||||
|
@ -58,8 +58,14 @@ void activateBotCommand(
|
||||
not_null<const HistoryItem*> msg,
|
||||
int row,
|
||||
int column) {
|
||||
const auto button = HistoryMessageMarkupButton::Get(msg->fullId(), row, column);
|
||||
if (!button) return;
|
||||
const auto button = HistoryMessageMarkupButton::Get(
|
||||
&msg->history()->owner(),
|
||||
msg->fullId(),
|
||||
row,
|
||||
column);
|
||||
if (!button) {
|
||||
return;
|
||||
}
|
||||
|
||||
using ButtonType = HistoryMessageMarkupButton::Type;
|
||||
switch (button->type) {
|
||||
@ -67,7 +73,11 @@ void activateBotCommand(
|
||||
// Copy string before passing it to the sending method
|
||||
// because the original button can be destroyed inside.
|
||||
MsgId replyTo = (msg->id > 0) ? msg->id : 0;
|
||||
sendBotCommand(msg->history()->peer, msg->fromOriginal()->asUser(), QString(button->text), replyTo);
|
||||
sendBotCommand(
|
||||
msg->history()->peer,
|
||||
msg->fromOriginal()->asUser(),
|
||||
QString(button->text),
|
||||
replyTo);
|
||||
} break;
|
||||
|
||||
case ButtonType::Callback:
|
||||
@ -98,7 +108,8 @@ void activateBotCommand(
|
||||
|
||||
case ButtonType::RequestLocation: {
|
||||
hideSingleUseKeyboard(msg);
|
||||
Ui::show(Box<InformBox>(tr::lng_bot_share_location_unavailable(tr::now)));
|
||||
Ui::show(Box<InformBox>(
|
||||
tr::lng_bot_share_location_unavailable(tr::now)));
|
||||
} break;
|
||||
|
||||
case ButtonType::RequestPhone: {
|
||||
|
@ -243,9 +243,11 @@ TextWithEntities GenerateBannedChangeText(
|
||||
return result;
|
||||
}
|
||||
|
||||
auto GenerateUserString(MTPint userId) {
|
||||
auto GenerateUserString(
|
||||
not_null<Main::Session*> session,
|
||||
MTPint userId) {
|
||||
// User name in "User name (@username)" format with entities.
|
||||
auto user = Auth().data().user(userId.v);
|
||||
auto user = session->data().user(userId.v);
|
||||
auto name = TextWithEntities { user->name };
|
||||
auto entityData = QString::number(user->id)
|
||||
+ '.'
|
||||
@ -283,10 +285,10 @@ auto GenerateParticipantChangeTextInner(
|
||||
return tr::lng_admin_log_transferred(
|
||||
tr::now,
|
||||
lt_user,
|
||||
GenerateUserString(data.vuser_id()),
|
||||
GenerateUserString(&channel->session(), data.vuser_id()),
|
||||
Ui::Text::WithEntities);
|
||||
}, [&](const MTPDchannelParticipantAdmin &data) {
|
||||
auto user = GenerateUserString(data.vuser_id());
|
||||
auto user = GenerateUserString(&channel->session(), data.vuser_id());
|
||||
return GenerateAdminChangeText(
|
||||
channel,
|
||||
user,
|
||||
@ -295,7 +297,7 @@ auto GenerateParticipantChangeTextInner(
|
||||
? &oldParticipant->c_channelParticipantAdmin().vadmin_rights()
|
||||
: nullptr);
|
||||
}, [&](const MTPDchannelParticipantBanned &data) {
|
||||
auto user = GenerateUserString(data.vuser_id());
|
||||
auto user = GenerateUserString(&channel->session(), data.vuser_id());
|
||||
return GenerateBannedChangeText(
|
||||
user,
|
||||
&data.vbanned_rights(),
|
||||
@ -303,7 +305,7 @@ auto GenerateParticipantChangeTextInner(
|
||||
? &oldParticipant->c_channelParticipantBanned().vbanned_rights()
|
||||
: nullptr);
|
||||
}, [&](const auto &data) {
|
||||
auto user = GenerateUserString(data.vuser_id());
|
||||
auto user = GenerateUserString(&channel->session(), data.vuser_id());
|
||||
if (oldType == mtpc_channelParticipantAdmin) {
|
||||
return GenerateAdminChangeText(
|
||||
channel,
|
||||
@ -380,7 +382,7 @@ void GenerateItems(
|
||||
|
||||
const auto session = &history->session();
|
||||
const auto id = event.vid().v;
|
||||
const auto from = Auth().data().user(event.vuser_id().v);
|
||||
const auto from = history->owner().user(event.vuser_id().v);
|
||||
const auto channel = history->peer->asChannel();
|
||||
const auto &action = event.vaction();
|
||||
const auto date = event.vdate().v;
|
||||
@ -490,7 +492,7 @@ void GenerateItems(
|
||||
|
||||
auto createChangePhoto = [&](const MTPDchannelAdminLogEventActionChangePhoto &action) {
|
||||
action.vnew_photo().match([&](const MTPDphoto &data) {
|
||||
auto photo = Auth().data().processPhoto(data);
|
||||
auto photo = history->owner().processPhoto(data);
|
||||
auto text = (channel->isMegagroup()
|
||||
? tr::lng_admin_log_changed_photo_group
|
||||
: tr::lng_admin_log_changed_photo_channel)(
|
||||
|
@ -38,8 +38,10 @@ const auto kPsaForwardedPrefix = "cloud_lng_forwarded_psa_";
|
||||
|
||||
} // namespace
|
||||
|
||||
void HistoryMessageVia::create(UserId userId) {
|
||||
bot = Auth().data().user(userId);
|
||||
void HistoryMessageVia::create(
|
||||
not_null<Data::Session*> owner,
|
||||
UserId userId) {
|
||||
bot = owner->user(userId);
|
||||
maxWidth = st::msgServiceNameFont->width(
|
||||
tr::lng_inline_bot_via(tr::now, lt_inline_bot, '@' + bot->username));
|
||||
link = std::make_shared<LambdaClickHandler>([bot = this->bot] {
|
||||
@ -229,7 +231,9 @@ bool HistoryMessageReply::updateData(
|
||||
if (!replyToMsg->Has<HistoryMessageForwarded>()) {
|
||||
if (auto bot = replyToMsg->viaBot()) {
|
||||
replyToVia = std::make_unique<HistoryMessageVia>();
|
||||
replyToVia->create(peerToUser(bot->id));
|
||||
replyToVia->create(
|
||||
&holder->history()->owner(),
|
||||
peerToUser(bot->id));
|
||||
}
|
||||
}
|
||||
} else if (force) {
|
||||
@ -419,7 +423,11 @@ QString ReplyMarkupClickHandler::copyToClipboardContextItemText() const {
|
||||
// Note: it is possible that we will point to the different button
|
||||
// than the one was used when constructing the handler, but not a big deal.
|
||||
const HistoryMessageMarkupButton *ReplyMarkupClickHandler::getButton() const {
|
||||
return HistoryMessageMarkupButton::Get(_itemId, _row, _column);
|
||||
return HistoryMessageMarkupButton::Get(
|
||||
&Auth().data(),
|
||||
_itemId,
|
||||
_row,
|
||||
_column);
|
||||
}
|
||||
|
||||
void ReplyMarkupClickHandler::onClickImpl() const {
|
||||
@ -788,10 +796,11 @@ HistoryMessageMarkupButton::HistoryMessageMarkupButton(
|
||||
}
|
||||
|
||||
HistoryMessageMarkupButton *HistoryMessageMarkupButton::Get(
|
||||
not_null<Data::Session*> owner,
|
||||
FullMsgId itemId,
|
||||
int row,
|
||||
int column) {
|
||||
if (const auto item = Auth().data().message(itemId)) {
|
||||
if (const auto item = owner->message(itemId)) {
|
||||
if (const auto markup = item->Get<HistoryMessageReplyMarkup>()) {
|
||||
if (row < markup->rows.size()) {
|
||||
auto &buttons = markup->rows[row];
|
||||
|
@ -13,13 +13,17 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
struct WebPageData;
|
||||
|
||||
namespace Data {
|
||||
class Session;
|
||||
} // namespace Data
|
||||
|
||||
namespace HistoryView {
|
||||
class Element;
|
||||
class Document;
|
||||
} // namespace HistoryView
|
||||
|
||||
struct HistoryMessageVia : public RuntimeComponent<HistoryMessageVia, HistoryItem> {
|
||||
void create(UserId userId);
|
||||
void create(not_null<Data::Session*> owner, UserId userId);
|
||||
void resize(int32 availw) const;
|
||||
|
||||
UserData *bot = nullptr;
|
||||
@ -181,6 +185,7 @@ struct HistoryMessageMarkupButton {
|
||||
int32 buttonId = 0);
|
||||
|
||||
static HistoryMessageMarkupButton *Get(
|
||||
not_null<Data::Session*> owner,
|
||||
FullMsgId itemId,
|
||||
int row,
|
||||
int column);
|
||||
|
@ -836,7 +836,7 @@ void HistoryMessage::createComponents(const CreateConfig &config) {
|
||||
}
|
||||
}
|
||||
if (const auto via = Get<HistoryMessageVia>()) {
|
||||
via->create(config.viaBotId);
|
||||
via->create(&history()->owner(), config.viaBotId);
|
||||
}
|
||||
if (const auto views = Get<HistoryMessageViews>()) {
|
||||
views->_views = config.viewsCount;
|
||||
|
@ -3644,11 +3644,14 @@ void HistoryWidget::botCallbackDone(
|
||||
const MTPmessages_BotCallbackAnswer &answer,
|
||||
mtpRequestId req) {
|
||||
const auto item = session().data().message(info.msgId);
|
||||
if (const auto button = HistoryMessageMarkupButton::Get(info.msgId, info.row, info.col)) {
|
||||
if (button->requestId == req) {
|
||||
button->requestId = 0;
|
||||
session().data().requestItemRepaint(item);
|
||||
}
|
||||
const auto button = HistoryMessageMarkupButton::Get(
|
||||
&session().data(),
|
||||
info.msgId,
|
||||
info.row,
|
||||
info.col);
|
||||
if (button && button->requestId == req) {
|
||||
button->requestId = 0;
|
||||
session().data().requestItemRepaint(item);
|
||||
}
|
||||
answer.match([&](const MTPDmessages_botCallbackAnswer &data) {
|
||||
if (const auto message = data.vmessage()) {
|
||||
@ -3677,11 +3680,14 @@ bool HistoryWidget::botCallbackFail(
|
||||
const RPCError &error,
|
||||
mtpRequestId req) {
|
||||
// show error?
|
||||
if (const auto button = HistoryMessageMarkupButton::Get(info.msgId, info.row, info.col)) {
|
||||
if (button->requestId == req) {
|
||||
button->requestId = 0;
|
||||
session().data().requestItemRepaint(session().data().message(info.msgId));
|
||||
}
|
||||
const auto button = HistoryMessageMarkupButton::Get(
|
||||
&session().data(),
|
||||
info.msgId,
|
||||
info.row,
|
||||
info.col);
|
||||
if (button && button->requestId == req) {
|
||||
button->requestId = 0;
|
||||
session().data().requestItemRepaint(session().data().message(info.msgId));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -386,6 +386,7 @@ MainWidget::MainWidget(
|
||||
, _history(this, _controller)
|
||||
, _playerPlaylist(this, _controller)
|
||||
, _noUpdatesTimer([=] { sendPing(); })
|
||||
, _ptsWaiter(&controller->session())
|
||||
, _byPtsTimer([=] { getDifferenceByPts(); })
|
||||
, _bySeqTimer([=] { getDifference(); })
|
||||
, _byMinChannelTimer([=] { getDifference(); })
|
||||
@ -1095,8 +1096,8 @@ void MainWidget::createPlayer() {
|
||||
) | rpl::start_with_next(
|
||||
[this] { playerHeightUpdated(); },
|
||||
_player->lifetime());
|
||||
_player->entity()->setCloseCallback([this] { closeBothPlayers(); });
|
||||
_playerVolume.create(this);
|
||||
_player->entity()->setCloseCallback([=] { closeBothPlayers(); });
|
||||
_playerVolume.create(this, _controller);
|
||||
_player->entity()->volumeWidgetCreated(_playerVolume);
|
||||
orderWidgets();
|
||||
if (_a_show.animating()) {
|
||||
|
@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "base/object_ptr.h"
|
||||
#include "mainwindow.h"
|
||||
#include "main/main_session.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "facades.h"
|
||||
#include "app.h"
|
||||
#include "styles/style_media_player.h"
|
||||
@ -23,7 +24,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
namespace Media {
|
||||
namespace Player {
|
||||
|
||||
VolumeController::VolumeController(QWidget *parent)
|
||||
VolumeController::VolumeController(
|
||||
QWidget *parent,
|
||||
not_null<Window::SessionController*> controller)
|
||||
: TWidget(parent)
|
||||
, _slider(this, st::mediaPlayerPanelPlayback) {
|
||||
_slider->setMoveByWheel(true);
|
||||
@ -35,7 +38,7 @@ VolumeController::VolumeController(QWidget *parent)
|
||||
Global::SetRememberedSongVolume(volume);
|
||||
}
|
||||
applyVolumeChange(volume);
|
||||
Auth().saveSettingsDelayed();
|
||||
controller->session().saveSettingsDelayed();
|
||||
});
|
||||
subscribe(Global::RefSongVolumeChanged(), [this] {
|
||||
if (!_slider->isChanging()) {
|
||||
@ -73,9 +76,11 @@ void VolumeController::applyVolumeChange(float64 volume) {
|
||||
}
|
||||
}
|
||||
|
||||
VolumeWidget::VolumeWidget(QWidget *parent)
|
||||
VolumeWidget::VolumeWidget(
|
||||
QWidget *parent,
|
||||
not_null<Window::SessionController*> controller)
|
||||
: RpWidget(parent)
|
||||
, _controller(this) {
|
||||
, _controller(this, controller) {
|
||||
hide();
|
||||
_controller->setIsVertical(true);
|
||||
|
||||
|
@ -18,12 +18,18 @@ class IconButton;
|
||||
class MediaSlider;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Window {
|
||||
class SessionController;
|
||||
} // namespace Window
|
||||
|
||||
namespace Media {
|
||||
namespace Player {
|
||||
|
||||
class VolumeController : public TWidget, private base::Subscriber {
|
||||
public:
|
||||
VolumeController(QWidget *parent);
|
||||
VolumeController(
|
||||
QWidget *parent,
|
||||
not_null<Window::SessionController*> controller);
|
||||
|
||||
void setIsVertical(bool vertical);
|
||||
|
||||
@ -42,7 +48,9 @@ class VolumeWidget : public Ui::RpWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
VolumeWidget(QWidget *parent);
|
||||
VolumeWidget(
|
||||
QWidget *parent,
|
||||
not_null<Window::SessionController*> controller);
|
||||
|
||||
bool overlaps(const QRect &globalRect);
|
||||
|
||||
|
@ -57,7 +57,10 @@ Data::FileOrigin ComputeFileOrigin(const Key &key, const Context &context) {
|
||||
});
|
||||
}
|
||||
|
||||
Context ComputeContext(const SharedMediaWithLastSlice &slice, int index) {
|
||||
Context ComputeContext(
|
||||
not_null<Main::Session*> session,
|
||||
const SharedMediaWithLastSlice &slice,
|
||||
int index) {
|
||||
Expects(index >= 0 && index < slice.size());
|
||||
|
||||
const auto value = slice[index];
|
||||
@ -67,7 +70,7 @@ Context ComputeContext(const SharedMediaWithLastSlice &slice, int index) {
|
||||
}
|
||||
return std::nullopt;
|
||||
} else if (const auto msgId = base::get_if<FullMsgId>(&value)) {
|
||||
if (const auto item = Auth().data().message(*msgId)) {
|
||||
if (const auto item = session->data().message(*msgId)) {
|
||||
if (!item->toHistoryMessage()) {
|
||||
return item->history()->peer->id;
|
||||
} else if (const auto groupId = item->groupId()) {
|
||||
@ -79,11 +82,17 @@ Context ComputeContext(const SharedMediaWithLastSlice &slice, int index) {
|
||||
Unexpected("Variant in ComputeContext(SharedMediaWithLastSlice::Value)");
|
||||
}
|
||||
|
||||
Context ComputeContext(const UserPhotosSlice &slice, int index) {
|
||||
Context ComputeContext(
|
||||
not_null<Main::Session*> session,
|
||||
const UserPhotosSlice &slice,
|
||||
int index) {
|
||||
return peerFromUser(slice.key().userId);
|
||||
}
|
||||
|
||||
Context ComputeContext(const GroupThumbs::CollageSlice &slice, int index) {
|
||||
Context ComputeContext(
|
||||
not_null<Main::Session*> session,
|
||||
const GroupThumbs::CollageSlice &slice,
|
||||
int index) {
|
||||
return slice.context;
|
||||
}
|
||||
|
||||
@ -96,7 +105,7 @@ Key ComputeKey(const SharedMediaWithLastSlice &slice, int index) {
|
||||
} else if (const auto msgId = base::get_if<FullMsgId>(&value)) {
|
||||
return *msgId;
|
||||
}
|
||||
Unexpected("Variant in ComputeContext(SharedMediaWithLastSlice::Value)");
|
||||
Unexpected("Variant in ComputeKey(SharedMediaWithLastSlice::Value)");
|
||||
}
|
||||
|
||||
Key ComputeKey(const UserPhotosSlice &slice, int index) {
|
||||
@ -410,8 +419,9 @@ int GroupThumbs::CollageSlice::size() const {
|
||||
return data->items.size();
|
||||
}
|
||||
|
||||
GroupThumbs::GroupThumbs(Context context)
|
||||
: _context(context) {
|
||||
GroupThumbs::GroupThumbs(not_null<Main::Session*> session, Context context)
|
||||
: _session(session)
|
||||
, _context(context) {
|
||||
}
|
||||
|
||||
void GroupThumbs::updateContext(Context context) {
|
||||
@ -423,11 +433,12 @@ void GroupThumbs::updateContext(Context context) {
|
||||
|
||||
template <typename Slice>
|
||||
void GroupThumbs::RefreshFromSlice(
|
||||
not_null<Main::Session*> session,
|
||||
std::unique_ptr<GroupThumbs> &instance,
|
||||
const Slice &slice,
|
||||
int index,
|
||||
int availableWidth) {
|
||||
const auto context = ComputeContext(slice, index);
|
||||
const auto context = ComputeContext(session, slice, index);
|
||||
if (instance) {
|
||||
instance->updateContext(context);
|
||||
}
|
||||
@ -441,7 +452,7 @@ void GroupThumbs::RefreshFromSlice(
|
||||
const auto from = [&] {
|
||||
const auto edge = std::max(index - limit, 0);
|
||||
for (auto result = index; result != edge; --result) {
|
||||
if (ComputeContext(slice, result - 1) != context) {
|
||||
if (ComputeContext(session, slice, result - 1) != context) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@ -450,7 +461,7 @@ void GroupThumbs::RefreshFromSlice(
|
||||
const auto till = [&] {
|
||||
const auto edge = std::min(index + limit + 1, slice.size());
|
||||
for (auto result = index + 1; result != edge; ++result) {
|
||||
if (ComputeContext(slice, result) != context) {
|
||||
if (ComputeContext(session, slice, result) != context) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@ -458,7 +469,7 @@ void GroupThumbs::RefreshFromSlice(
|
||||
}();
|
||||
if (from + 1 < till) {
|
||||
if (!instance) {
|
||||
instance = std::make_unique<GroupThumbs>(context);
|
||||
instance = std::make_unique<GroupThumbs>(session, context);
|
||||
}
|
||||
instance->fillItems(slice, from, index, till);
|
||||
instance->resizeToWidth(availableWidth);
|
||||
@ -554,10 +565,10 @@ void GroupThumbs::animatePreviouslyAlive(
|
||||
auto GroupThumbs::createThumb(Key key)
|
||||
-> std::unique_ptr<Thumb> {
|
||||
if (const auto photoId = base::get_if<PhotoId>(&key)) {
|
||||
const auto photo = Auth().data().photo(*photoId);
|
||||
const auto photo = _session->data().photo(*photoId);
|
||||
return createThumb(key, photo);
|
||||
} else if (const auto msgId = base::get_if<FullMsgId>(&key)) {
|
||||
if (const auto item = Auth().data().message(*msgId)) {
|
||||
if (const auto item = _session->data().message(*msgId)) {
|
||||
if (const auto media = item->media()) {
|
||||
if (const auto photo = media->photo()) {
|
||||
return createThumb(key, photo);
|
||||
@ -569,7 +580,7 @@ auto GroupThumbs::createThumb(Key key)
|
||||
return createThumb(key, nullptr);
|
||||
} else if (const auto collageKey = base::get_if<CollageKey>(&key)) {
|
||||
if (const auto itemId = base::get_if<FullMsgId>(&_context)) {
|
||||
if (const auto item = Auth().data().message(*itemId)) {
|
||||
if (const auto item = _session->data().message(*itemId)) {
|
||||
if (const auto media = item->media()) {
|
||||
if (const auto page = media->webpage()) {
|
||||
return createThumb(
|
||||
@ -651,27 +662,30 @@ void GroupThumbs::markCacheStale() {
|
||||
}
|
||||
|
||||
void GroupThumbs::Refresh(
|
||||
not_null<Main::Session*> session,
|
||||
std::unique_ptr<GroupThumbs> &instance,
|
||||
const SharedMediaWithLastSlice &slice,
|
||||
int index,
|
||||
int availableWidth) {
|
||||
RefreshFromSlice(instance, slice, index, availableWidth);
|
||||
RefreshFromSlice(session, instance, slice, index, availableWidth);
|
||||
}
|
||||
|
||||
void GroupThumbs::Refresh(
|
||||
not_null<Main::Session*> session,
|
||||
std::unique_ptr<GroupThumbs> &instance,
|
||||
const UserPhotosSlice &slice,
|
||||
int index,
|
||||
int availableWidth) {
|
||||
RefreshFromSlice(instance, slice, index, availableWidth);
|
||||
RefreshFromSlice(session, instance, slice, index, availableWidth);
|
||||
}
|
||||
|
||||
void GroupThumbs::Refresh(
|
||||
not_null<Main::Session*> session,
|
||||
std::unique_ptr<GroupThumbs> &instance,
|
||||
const CollageSlice &slice,
|
||||
int index,
|
||||
int availableWidth) {
|
||||
RefreshFromSlice(instance, slice, index, availableWidth);
|
||||
RefreshFromSlice(session, instance, slice, index, availableWidth);
|
||||
}
|
||||
|
||||
void GroupThumbs::clear() {
|
||||
|
@ -15,6 +15,10 @@ class SharedMediaWithLastSlice;
|
||||
class UserPhotosSlice;
|
||||
struct WebPageCollage;
|
||||
|
||||
namespace Main {
|
||||
class Session;
|
||||
} // namespace Main
|
||||
|
||||
namespace Media {
|
||||
namespace View {
|
||||
|
||||
@ -36,16 +40,19 @@ public:
|
||||
using Key = base::variant<PhotoId, FullMsgId, CollageKey>;
|
||||
|
||||
static void Refresh(
|
||||
not_null<Main::Session*> session,
|
||||
std::unique_ptr<GroupThumbs> &instance,
|
||||
const SharedMediaWithLastSlice &slice,
|
||||
int index,
|
||||
int availableWidth);
|
||||
static void Refresh(
|
||||
not_null<Main::Session*> session,
|
||||
std::unique_ptr<GroupThumbs> &instance,
|
||||
const UserPhotosSlice &slice,
|
||||
int index,
|
||||
int availableWidth);
|
||||
static void Refresh(
|
||||
not_null<Main::Session*> session,
|
||||
std::unique_ptr<GroupThumbs> &instance,
|
||||
const CollageSlice &slice,
|
||||
int index,
|
||||
@ -78,7 +85,7 @@ public:
|
||||
MessageGroupId,
|
||||
FullMsgId>;
|
||||
|
||||
GroupThumbs(Context context);
|
||||
GroupThumbs(not_null<Main::Session*> session, Context context);
|
||||
~GroupThumbs();
|
||||
|
||||
private:
|
||||
@ -86,6 +93,7 @@ private:
|
||||
|
||||
template <typename Slice>
|
||||
static void RefreshFromSlice(
|
||||
not_null<Main::Session*> session,
|
||||
std::unique_ptr<GroupThumbs> &instance,
|
||||
const Slice &slice,
|
||||
int index,
|
||||
@ -115,6 +123,7 @@ private:
|
||||
void animatePreviouslyAlive(const std::vector<not_null<Thumb*>> &old);
|
||||
void startDelayedAnimation();
|
||||
|
||||
const not_null<Main::Session*> _session;
|
||||
Context _context;
|
||||
bool _waitingForAnimationStart = true;
|
||||
Ui::Animations::Simple _animation;
|
||||
|
@ -554,7 +554,9 @@ void OverlayWidget::changingMsgId(not_null<HistoryItem*> row, MsgId newId) {
|
||||
}
|
||||
|
||||
void OverlayWidget::updateDocSize() {
|
||||
if (!_document || !documentBubbleShown()) return;
|
||||
if (!_document || !documentBubbleShown()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_document->loading()) {
|
||||
quint64 ready = _document->loadOffset(), total = _document->size;
|
||||
@ -646,7 +648,9 @@ void OverlayWidget::updateControls() {
|
||||
|
||||
const auto dNow = QDateTime::currentDateTime();
|
||||
const auto d = [&] {
|
||||
if (const auto item = Auth().data().message(_msgid)) {
|
||||
if (!_session) {
|
||||
return dNow;
|
||||
} else if (const auto item = _session->data().message(_msgid)) {
|
||||
return ItemDateTime(item);
|
||||
} else if (_photo) {
|
||||
return base::unixtime::parse(_photo->date);
|
||||
@ -752,10 +756,13 @@ void OverlayWidget::updateActions() {
|
||||
if (_canForwardItem) {
|
||||
_actions.push_back({ tr::lng_mediaview_forward(tr::now), SLOT(onForward()) });
|
||||
}
|
||||
auto canDelete = [&] {
|
||||
const auto canDelete = [&] {
|
||||
if (_canDeleteItem) {
|
||||
return true;
|
||||
} else if (!_msgid && _photo && _user && _user == Auth().user()) {
|
||||
} else if (!_msgid
|
||||
&& _photo
|
||||
&& _user
|
||||
&& _user == _user->session().user()) {
|
||||
return _userPhotosData && _fullIndex && _fullCount;
|
||||
} else if (_photo && _photo->peer && _photo->peer->userpicPhotoId() == _photo->id) {
|
||||
if (auto chat = _photo->peer->asChat()) {
|
||||
@ -1096,6 +1103,7 @@ void OverlayWidget::clearData() {
|
||||
_pip = nullptr;
|
||||
_fullScreenVideo = false;
|
||||
_caption.clear();
|
||||
_session = nullptr;
|
||||
}
|
||||
|
||||
OverlayWidget::~OverlayWidget() {
|
||||
@ -1224,7 +1232,10 @@ void OverlayWidget::onScreenResized(int screen) {
|
||||
}
|
||||
|
||||
void OverlayWidget::onToMessage() {
|
||||
if (const auto item = Auth().data().message(_msgid)) {
|
||||
if (!_session) {
|
||||
return;
|
||||
}
|
||||
if (const auto item = _session->data().message(_msgid)) {
|
||||
close();
|
||||
Ui::showPeerHistoryAtItem(item);
|
||||
}
|
||||
@ -1263,7 +1274,14 @@ void OverlayWidget::onSaveAs() {
|
||||
filter = mimeType.filterString() + qsl(";;") + FileDialog::AllFilesFilter();
|
||||
}
|
||||
|
||||
file = FileNameForSave(tr::lng_save_file(tr::now), filter, qsl("doc"), name, true, alreadyDir);
|
||||
file = FileNameForSave(
|
||||
_session,
|
||||
tr::lng_save_file(tr::now),
|
||||
filter,
|
||||
qsl("doc"),
|
||||
name,
|
||||
true,
|
||||
alreadyDir);
|
||||
if (!file.isEmpty() && file != location.name()) {
|
||||
if (bytes.isEmpty()) {
|
||||
QFile(file).remove();
|
||||
@ -1319,7 +1337,7 @@ void OverlayWidget::onDocClick() {
|
||||
DocumentOpenClickHandler::Open(
|
||||
fileOrigin(),
|
||||
_document,
|
||||
Auth().data().message(_msgid));
|
||||
_document->owner().message(_msgid));
|
||||
if (_document->loading() && !_radial.animating()) {
|
||||
_radial.start(_documentMedia->progress());
|
||||
}
|
||||
@ -1331,13 +1349,17 @@ PeerData *OverlayWidget::ui_getPeerForMouseAction() {
|
||||
}
|
||||
|
||||
void OverlayWidget::onDownload() {
|
||||
if (!_photo && !_document) {
|
||||
return;
|
||||
}
|
||||
if (Global::AskDownloadPath()) {
|
||||
return onSaveAs();
|
||||
}
|
||||
|
||||
QString path;
|
||||
const auto session = _photo ? &_photo->session() : &_document->session();
|
||||
if (Global::DownloadPath().isEmpty()) {
|
||||
path = File::DefaultDownloadPath();
|
||||
path = File::DefaultDownloadPath(session);
|
||||
} else if (Global::DownloadPath() == qsl("tmp")) {
|
||||
path = cTempDir();
|
||||
} else {
|
||||
@ -1418,7 +1440,10 @@ void OverlayWidget::onShowInFolder() {
|
||||
}
|
||||
|
||||
void OverlayWidget::onForward() {
|
||||
auto item = Auth().data().message(_msgid);
|
||||
if (!_session) {
|
||||
return;
|
||||
}
|
||||
const auto item = _session->data().message(_msgid);
|
||||
if (!item || !IsServerMsgId(item->id) || item->serviceMsg()) {
|
||||
return;
|
||||
}
|
||||
@ -1430,6 +1455,11 @@ void OverlayWidget::onForward() {
|
||||
}
|
||||
|
||||
void OverlayWidget::onDelete() {
|
||||
const auto session = _session;
|
||||
if (!session) {
|
||||
return;
|
||||
}
|
||||
|
||||
close();
|
||||
const auto deletingPeerPhoto = [this] {
|
||||
if (!_msgid) {
|
||||
@ -1445,7 +1475,7 @@ void OverlayWidget::onDelete() {
|
||||
|
||||
if (deletingPeerPhoto()) {
|
||||
App::main()->deletePhotoLayer(_photo);
|
||||
} else if (const auto item = Auth().data().message(_msgid)) {
|
||||
} else if (const auto item = session->data().message(_msgid)) {
|
||||
const auto suggestModerateActions = true;
|
||||
Ui::show(Box<DeleteMessagesBox>(item, suggestModerateActions));
|
||||
}
|
||||
@ -1474,13 +1504,20 @@ void OverlayWidget::onCopy() {
|
||||
}
|
||||
|
||||
void OverlayWidget::onAttachedStickers() {
|
||||
const auto session = _session;
|
||||
if (!session) {
|
||||
return;
|
||||
}
|
||||
close();
|
||||
Auth().api().requestAttachedStickerSets(_photo);
|
||||
session->api().requestAttachedStickerSets(_photo);
|
||||
}
|
||||
|
||||
std::optional<OverlayWidget::SharedMediaType> OverlayWidget::sharedMediaType() const {
|
||||
auto OverlayWidget::sharedMediaType() const
|
||||
-> std::optional<SharedMediaType> {
|
||||
using Type = SharedMediaType;
|
||||
if (const auto item = Auth().data().message(_msgid)) {
|
||||
if (!_session) {
|
||||
return std::nullopt;
|
||||
} else if (const auto item = _session->data().message(_msgid)) {
|
||||
if (const auto media = item->media()) {
|
||||
if (media->webpage()) {
|
||||
return std::nullopt;
|
||||
@ -1503,8 +1540,12 @@ std::optional<OverlayWidget::SharedMediaType> OverlayWidget::sharedMediaType() c
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<OverlayWidget::SharedMediaKey> OverlayWidget::sharedMediaKey() const {
|
||||
if (!_msgid && _peer && !_user && _photo && _peer->userpicPhotoId() == _photo->id) {
|
||||
auto OverlayWidget::sharedMediaKey() const -> std::optional<SharedMediaKey> {
|
||||
if (!_msgid
|
||||
&& _peer
|
||||
&& !_user
|
||||
&& _photo
|
||||
&& _peer->userpicPhotoId() == _photo->id) {
|
||||
return SharedMediaKey {
|
||||
_history->peer->id,
|
||||
_migrated ? _migrated->peer->id : 0,
|
||||
@ -1689,7 +1730,9 @@ void OverlayWidget::handleUserPhotosUpdate(UserPhotosSlice &&update) {
|
||||
}
|
||||
|
||||
std::optional<OverlayWidget::CollageKey> OverlayWidget::collageKey() const {
|
||||
if (const auto item = Auth().data().message(_msgid)) {
|
||||
if (!_session) {
|
||||
return std::nullopt;
|
||||
} else if (const auto item = _session->data().message(_msgid)) {
|
||||
if (const auto media = item->media()) {
|
||||
if (const auto page = media->webpage()) {
|
||||
for (const auto &item : page->collage.items) {
|
||||
@ -1735,7 +1778,7 @@ void OverlayWidget::validateCollage() {
|
||||
if (const auto key = collageKey()) {
|
||||
_collage = std::make_unique<Collage>(*key);
|
||||
_collageData = WebPageCollage();
|
||||
if (const auto item = Auth().data().message(_msgid)) {
|
||||
if (const auto item = _session->data().message(_msgid)) {
|
||||
if (const auto media = item->media()) {
|
||||
if (const auto page = media->webpage()) {
|
||||
_collageData = page->collage;
|
||||
@ -1816,18 +1859,21 @@ void OverlayWidget::refreshGroupThumbs() {
|
||||
const auto existed = (_groupThumbs != nullptr);
|
||||
if (_index && _sharedMediaData) {
|
||||
View::GroupThumbs::Refresh(
|
||||
_session,
|
||||
_groupThumbs,
|
||||
*_sharedMediaData,
|
||||
*_index,
|
||||
_groupThumbsAvailableWidth);
|
||||
} else if (_index && _userPhotosData) {
|
||||
View::GroupThumbs::Refresh(
|
||||
_session,
|
||||
_groupThumbs,
|
||||
*_userPhotosData,
|
||||
*_index,
|
||||
_groupThumbsAvailableWidth);
|
||||
} else if (_index && _collageData) {
|
||||
View::GroupThumbs::Refresh(
|
||||
_session,
|
||||
_groupThumbs,
|
||||
{ _msgid, &*_collageData },
|
||||
*_index,
|
||||
@ -1859,7 +1905,7 @@ void OverlayWidget::initGroupThumbs() {
|
||||
) | rpl::start_with_next([this](View::GroupThumbs::Key key) {
|
||||
using CollageKey = View::GroupThumbs::CollageKey;
|
||||
if (const auto photoId = base::get_if<PhotoId>(&key)) {
|
||||
const auto photo = Auth().data().photo(*photoId);
|
||||
const auto photo = _session->data().photo(*photoId);
|
||||
moveToEntity({ photo, nullptr });
|
||||
} else if (const auto itemId = base::get_if<FullMsgId>(&key)) {
|
||||
moveToEntity(entityForItemId(*itemId));
|
||||
@ -1894,6 +1940,8 @@ void OverlayWidget::clearControlsState() {
|
||||
}
|
||||
|
||||
void OverlayWidget::showPhoto(not_null<PhotoData*> photo, HistoryItem *context) {
|
||||
_session = &photo->session();
|
||||
|
||||
if (context) {
|
||||
setContext(context);
|
||||
} else {
|
||||
@ -1910,6 +1958,8 @@ void OverlayWidget::showPhoto(not_null<PhotoData*> photo, HistoryItem *context)
|
||||
}
|
||||
|
||||
void OverlayWidget::showPhoto(not_null<PhotoData*> photo, not_null<PeerData*> context) {
|
||||
_session = &photo->session();
|
||||
|
||||
setContext(context);
|
||||
|
||||
clearControlsState();
|
||||
@ -1938,6 +1988,8 @@ void OverlayWidget::showDocument(
|
||||
HistoryItem *context,
|
||||
const Data::CloudTheme &cloud,
|
||||
bool continueStreaming) {
|
||||
_session = &document->session();
|
||||
|
||||
if (context) {
|
||||
setContext(context);
|
||||
} else {
|
||||
@ -1997,10 +2049,10 @@ void OverlayWidget::destroyThemePreview() {
|
||||
}
|
||||
|
||||
void OverlayWidget::redisplayContent() {
|
||||
if (isHidden()) {
|
||||
if (isHidden() || !_session) {
|
||||
return;
|
||||
}
|
||||
const auto item = Auth().data().message(_msgid);
|
||||
const auto item = _session->data().message(_msgid);
|
||||
if (_photo) {
|
||||
displayPhoto(_photo, item);
|
||||
} else {
|
||||
@ -3367,11 +3419,13 @@ void OverlayWidget::setZoomLevel(int newZoom, bool force) {
|
||||
|
||||
OverlayWidget::Entity OverlayWidget::entityForUserPhotos(int index) const {
|
||||
Expects(_userPhotosData.has_value());
|
||||
Expects(_session != nullptr);
|
||||
|
||||
if (index < 0 || index >= _userPhotosData->size()) {
|
||||
return { std::nullopt, nullptr };
|
||||
}
|
||||
if (auto photo = Auth().data().photo((*_userPhotosData)[index])) {
|
||||
const auto id = (*_userPhotosData)[index];
|
||||
if (const auto photo = _session->data().photo(id)) {
|
||||
return { photo, nullptr };
|
||||
}
|
||||
return { std::nullopt, nullptr };
|
||||
@ -3395,8 +3449,9 @@ OverlayWidget::Entity OverlayWidget::entityForSharedMedia(int index) const {
|
||||
|
||||
OverlayWidget::Entity OverlayWidget::entityForCollage(int index) const {
|
||||
Expects(_collageData.has_value());
|
||||
Expects(_session != nullptr);
|
||||
|
||||
const auto item = Auth().data().message(_msgid);
|
||||
const auto item = _session->data().message(_msgid);
|
||||
const auto &items = _collageData->items;
|
||||
if (!item || index < 0 || index >= items.size()) {
|
||||
return { std::nullopt, nullptr };
|
||||
@ -3410,7 +3465,9 @@ OverlayWidget::Entity OverlayWidget::entityForCollage(int index) const {
|
||||
}
|
||||
|
||||
OverlayWidget::Entity OverlayWidget::entityForItemId(const FullMsgId &itemId) const {
|
||||
if (const auto item = Auth().data().message(itemId)) {
|
||||
Expects(_session != nullptr);
|
||||
|
||||
if (const auto item = _session->data().message(itemId)) {
|
||||
if (const auto media = item->media()) {
|
||||
if (const auto photo = media->photo()) {
|
||||
return { photo, item };
|
||||
|
@ -355,6 +355,7 @@ private:
|
||||
|
||||
QBrush _transparentBrush;
|
||||
|
||||
Main::Session *_session = nullptr;
|
||||
PhotoData *_photo = nullptr;
|
||||
DocumentData *_document = nullptr;
|
||||
std::shared_ptr<Data::PhotoMedia> _photoMedia;
|
||||
|
@ -1740,6 +1740,7 @@ void FormController::loadFile(File &file) {
|
||||
const auto [j, ok] = _fileLoaders.emplace(
|
||||
key,
|
||||
std::make_unique<mtpFileLoader>(
|
||||
&_controller->session(),
|
||||
StorageFileLocation(
|
||||
file.dcId,
|
||||
session().userId(),
|
||||
|
@ -381,7 +381,7 @@ void CountryRow::chooseCountry() {
|
||||
const auto top = _value.current();
|
||||
const auto name = Data::CountryNameByISO2(top);
|
||||
const auto isoByPhone = Data::CountryISO2ByPhone(
|
||||
Auth().user()->phone());
|
||||
_controller->bot()->session().user()->phone());
|
||||
const auto box = _controller->show(Box<CountrySelectBox>(!name.isEmpty()
|
||||
? top
|
||||
: !isoByPhone.isEmpty()
|
||||
|
@ -71,7 +71,7 @@ GroupMembersWidget::GroupMembersWidget(
|
||||
}
|
||||
|
||||
void GroupMembersWidget::removePeer(PeerData *selectedPeer) {
|
||||
auto user = selectedPeer->asUser();
|
||||
const auto user = selectedPeer->asUser();
|
||||
Assert(user != nullptr);
|
||||
|
||||
auto text = tr::lng_profile_sure_kick(tr::now, lt_user, user->firstName);
|
||||
@ -84,18 +84,24 @@ void GroupMembersWidget::removePeer(PeerData *selectedPeer) {
|
||||
}
|
||||
return MTP_chatBannedRights(MTP_flags(0), MTP_int(0));
|
||||
}();
|
||||
Ui::show(Box<ConfirmBox>(text, tr::lng_box_remove(tr::now), [user, currentRestrictedRights, peer = peer()] {
|
||||
|
||||
const auto peer = this->peer();
|
||||
const auto callback = [=] {
|
||||
Ui::hideLayer();
|
||||
if (const auto chat = peer->asChat()) {
|
||||
Auth().api().kickParticipant(chat, user);
|
||||
chat->session().api().kickParticipant(chat, user);
|
||||
Ui::showPeerHistory(chat->id, ShowAtTheEndMsgId);
|
||||
} else if (const auto channel = peer->asChannel()) {
|
||||
Auth().api().kickParticipant(
|
||||
channel->session().api().kickParticipant(
|
||||
channel,
|
||||
user,
|
||||
currentRestrictedRights);
|
||||
}
|
||||
}));
|
||||
};
|
||||
Ui::show(Box<ConfirmBox>(
|
||||
text,
|
||||
tr::lng_box_remove(tr::now),
|
||||
crl::guard(&peer->session(), callback)));
|
||||
}
|
||||
|
||||
void GroupMembersWidget::notifyPeerUpdated(const Notify::PeerUpdate &update) {
|
||||
@ -152,7 +158,7 @@ void GroupMembersWidget::preloadMore() {
|
||||
//if (auto megagroup = peer()->asMegagroup()) {
|
||||
// auto &megagroupInfo = megagroup->mgInfo;
|
||||
// if (!megagroupInfo->lastParticipants.isEmpty() && megagroupInfo->lastParticipants.size() < megagroup->membersCount()) {
|
||||
// Auth().api().requestLastParticipants(megagroup, false);
|
||||
// peer()->session().api().requestLastParticipants(megagroup, false);
|
||||
// }
|
||||
//}
|
||||
}
|
||||
@ -187,13 +193,13 @@ void GroupMembersWidget::refreshMembers() {
|
||||
if (const auto chat = peer()->asChat()) {
|
||||
checkSelfAdmin(chat);
|
||||
if (chat->noParticipantInfo()) {
|
||||
Auth().api().requestFullPeer(chat);
|
||||
chat->session().api().requestFullPeer(chat);
|
||||
}
|
||||
fillChatMembers(chat);
|
||||
} else if (const auto megagroup = peer()->asMegagroup()) {
|
||||
auto &megagroupInfo = megagroup->mgInfo;
|
||||
if (megagroup->lastParticipantsRequestNeeded()) {
|
||||
Auth().api().requestLastParticipants(megagroup);
|
||||
megagroup->session().api().requestLastParticipants(megagroup);
|
||||
}
|
||||
fillMegagroupMembers(megagroup);
|
||||
}
|
||||
|
@ -22,13 +22,18 @@ PeerListWidget::Item::Item(not_null<PeerData*> peer) : peer(peer) {
|
||||
|
||||
PeerListWidget::Item::~Item() = default;
|
||||
|
||||
PeerListWidget::PeerListWidget(QWidget *parent, PeerData *peer, const QString &title, const style::PeerListItem &st, const QString &removeText)
|
||||
PeerListWidget::PeerListWidget(
|
||||
QWidget *parent,
|
||||
PeerData *peer,
|
||||
const QString &title,
|
||||
const style::PeerListItem &st,
|
||||
const QString &removeText)
|
||||
: BlockWidget(parent, peer, title)
|
||||
, _st(st)
|
||||
, _removeText(removeText)
|
||||
, _removeWidth(st::normalFont->width(_removeText)) {
|
||||
setMouseTracking(true);
|
||||
subscribe(Auth().downloaderTaskFinished(), [this] { update(); });
|
||||
subscribe(peer->session().downloaderTaskFinished(), [=] { update(); });
|
||||
}
|
||||
|
||||
int PeerListWidget::resizeGetHeight(int newWidth) {
|
||||
|
@ -30,6 +30,7 @@ namespace {
|
||||
class FromMemoryLoader final : public FileLoader {
|
||||
public:
|
||||
FromMemoryLoader(
|
||||
not_null<Main::Session*> session,
|
||||
const QByteArray &data,
|
||||
const QString &toFile,
|
||||
int32 size,
|
||||
@ -50,6 +51,7 @@ private:
|
||||
};
|
||||
|
||||
FromMemoryLoader::FromMemoryLoader(
|
||||
not_null<Main::Session*> session,
|
||||
const QByteArray &data,
|
||||
const QString &toFile,
|
||||
int32 size,
|
||||
@ -59,6 +61,7 @@ FromMemoryLoader::FromMemoryLoader(
|
||||
bool autoLoading,
|
||||
uint8 cacheTag
|
||||
) : FileLoader(
|
||||
session,
|
||||
toFile,
|
||||
size,
|
||||
locationType,
|
||||
@ -87,6 +90,7 @@ void FromMemoryLoader::startLoading() {
|
||||
} // namespace
|
||||
|
||||
FileLoader::FileLoader(
|
||||
not_null<Main::Session*> session,
|
||||
const QString &toFile,
|
||||
int32 size,
|
||||
LocationType locationType,
|
||||
@ -94,7 +98,7 @@ FileLoader::FileLoader(
|
||||
LoadFromCloudSetting fromCloud,
|
||||
bool autoLoading,
|
||||
uint8 cacheTag)
|
||||
: _session(&Auth())
|
||||
: _session(session)
|
||||
, _autoLoading(autoLoading)
|
||||
, _cacheTag(cacheTag)
|
||||
, _filename(toFile)
|
||||
@ -441,6 +445,7 @@ bool FileLoader::finalizeResult() {
|
||||
}
|
||||
|
||||
std::unique_ptr<FileLoader> CreateFileLoader(
|
||||
not_null<Main::Session*> session,
|
||||
const DownloadLocation &location,
|
||||
Data::FileOrigin origin,
|
||||
const QString &toFile,
|
||||
@ -453,6 +458,7 @@ std::unique_ptr<FileLoader> CreateFileLoader(
|
||||
auto result = std::unique_ptr<FileLoader>();
|
||||
location.data.match([&](const StorageFileLocation &data) {
|
||||
result = std::make_unique<mtpFileLoader>(
|
||||
session,
|
||||
data,
|
||||
origin,
|
||||
locationType,
|
||||
@ -464,6 +470,7 @@ std::unique_ptr<FileLoader> CreateFileLoader(
|
||||
cacheTag);
|
||||
}, [&](const WebFileLocation &data) {
|
||||
result = std::make_unique<mtpFileLoader>(
|
||||
session,
|
||||
data,
|
||||
size,
|
||||
fromCloud,
|
||||
@ -471,6 +478,7 @@ std::unique_ptr<FileLoader> CreateFileLoader(
|
||||
cacheTag);
|
||||
}, [&](const GeoPointLocation &data) {
|
||||
result = std::make_unique<mtpFileLoader>(
|
||||
session,
|
||||
data,
|
||||
size,
|
||||
fromCloud,
|
||||
@ -478,6 +486,7 @@ std::unique_ptr<FileLoader> CreateFileLoader(
|
||||
cacheTag);
|
||||
}, [&](const PlainUrlLocation &data) {
|
||||
result = std::make_unique<webFileLoader>(
|
||||
session,
|
||||
data.url,
|
||||
toFile,
|
||||
fromCloud,
|
||||
@ -485,6 +494,7 @@ std::unique_ptr<FileLoader> CreateFileLoader(
|
||||
cacheTag);
|
||||
}, [&](const InMemoryLocation &data) {
|
||||
result = std::make_unique<FromMemoryLoader>(
|
||||
session,
|
||||
data.bytes,
|
||||
toFile,
|
||||
size,
|
||||
|
@ -55,6 +55,7 @@ struct StorageImageSaved {
|
||||
class FileLoader : public base::has_weak_ptr {
|
||||
public:
|
||||
FileLoader(
|
||||
not_null<Main::Session*> session,
|
||||
const QString &toFile,
|
||||
int32 size,
|
||||
LocationType locationType,
|
||||
@ -173,6 +174,7 @@ protected:
|
||||
};
|
||||
|
||||
[[nodiscard]] std::unique_ptr<FileLoader> CreateFileLoader(
|
||||
not_null<Main::Session*> session,
|
||||
const DownloadLocation &location,
|
||||
Data::FileOrigin origin,
|
||||
const QString &toFile,
|
||||
|
@ -18,6 +18,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "facades.h"
|
||||
|
||||
mtpFileLoader::mtpFileLoader(
|
||||
not_null<Main::Session*> session,
|
||||
const StorageFileLocation &location,
|
||||
Data::FileOrigin origin,
|
||||
LocationType type,
|
||||
@ -28,6 +29,7 @@ mtpFileLoader::mtpFileLoader(
|
||||
bool autoLoading,
|
||||
uint8 cacheTag)
|
||||
: FileLoader(
|
||||
session,
|
||||
to,
|
||||
size,
|
||||
type,
|
||||
@ -35,16 +37,18 @@ mtpFileLoader::mtpFileLoader(
|
||||
fromCloud,
|
||||
autoLoading,
|
||||
cacheTag)
|
||||
, DownloadMtprotoTask(&session().downloader(), location, origin) {
|
||||
, DownloadMtprotoTask(&session->downloader(), location, origin) {
|
||||
}
|
||||
|
||||
mtpFileLoader::mtpFileLoader(
|
||||
not_null<Main::Session*> session,
|
||||
const WebFileLocation &location,
|
||||
int32 size,
|
||||
LoadFromCloudSetting fromCloud,
|
||||
bool autoLoading,
|
||||
uint8 cacheTag)
|
||||
: FileLoader(
|
||||
session,
|
||||
QString(),
|
||||
size,
|
||||
UnknownFileLocation,
|
||||
@ -53,18 +57,20 @@ mtpFileLoader::mtpFileLoader(
|
||||
autoLoading,
|
||||
cacheTag)
|
||||
, DownloadMtprotoTask(
|
||||
&session().downloader(),
|
||||
&session->downloader(),
|
||||
Global::WebFileDcId(),
|
||||
{ location }) {
|
||||
}
|
||||
|
||||
mtpFileLoader::mtpFileLoader(
|
||||
not_null<Main::Session*> session,
|
||||
const GeoPointLocation &location,
|
||||
int32 size,
|
||||
LoadFromCloudSetting fromCloud,
|
||||
bool autoLoading,
|
||||
uint8 cacheTag)
|
||||
: FileLoader(
|
||||
session,
|
||||
QString(),
|
||||
size,
|
||||
UnknownFileLocation,
|
||||
@ -73,7 +79,7 @@ mtpFileLoader::mtpFileLoader(
|
||||
autoLoading,
|
||||
cacheTag)
|
||||
, DownloadMtprotoTask(
|
||||
&session().downloader(),
|
||||
&session->downloader(),
|
||||
Global::WebFileDcId(),
|
||||
{ location }) {
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ class mtpFileLoader final
|
||||
, private Storage::DownloadMtprotoTask {
|
||||
public:
|
||||
mtpFileLoader(
|
||||
not_null<Main::Session*> session,
|
||||
const StorageFileLocation &location,
|
||||
Data::FileOrigin origin,
|
||||
LocationType type,
|
||||
@ -25,12 +26,14 @@ public:
|
||||
bool autoLoading,
|
||||
uint8 cacheTag);
|
||||
mtpFileLoader(
|
||||
not_null<Main::Session*> session,
|
||||
const WebFileLocation &location,
|
||||
int32 size,
|
||||
LoadFromCloudSetting fromCloud,
|
||||
bool autoLoading,
|
||||
uint8 cacheTag);
|
||||
mtpFileLoader(
|
||||
not_null<Main::Session*> session,
|
||||
const GeoPointLocation &location,
|
||||
int32 size,
|
||||
LoadFromCloudSetting fromCloud,
|
||||
|
@ -436,12 +436,14 @@ void WebLoadManager::sendUpdate(int id, Update &&data) {
|
||||
}
|
||||
|
||||
webFileLoader::webFileLoader(
|
||||
not_null<Main::Session*> session,
|
||||
const QString &url,
|
||||
const QString &to,
|
||||
LoadFromCloudSetting fromCloud,
|
||||
bool autoLoading,
|
||||
uint8 cacheTag)
|
||||
: FileLoader(
|
||||
session,
|
||||
QString(),
|
||||
0,
|
||||
UnknownFileLocation,
|
||||
|
@ -14,6 +14,7 @@ class WebLoadManager;
|
||||
class webFileLoader final : public FileLoader {
|
||||
public:
|
||||
webFileLoader(
|
||||
not_null<Main::Session*> session,
|
||||
const QString &url,
|
||||
const QString &to,
|
||||
LoadFromCloudSetting fromCloud,
|
||||
|
@ -16,6 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "ui/image/image_location_factory.h"
|
||||
#include "core/mime_type.h"
|
||||
#include "main/main_session.h"
|
||||
#include "apiwrap.h"
|
||||
|
||||
namespace Storage {
|
||||
namespace {
|
||||
@ -154,17 +155,25 @@ Uploader::Uploader(not_null<ApiWrap*> api)
|
||||
connect(&stopSessionsTimer, SIGNAL(timeout()), this, SLOT(stopSessions()));
|
||||
}
|
||||
|
||||
Uploader::~Uploader() {
|
||||
clear();
|
||||
}
|
||||
|
||||
Main::Session &Uploader::session() const {
|
||||
return _api->session();
|
||||
}
|
||||
|
||||
void Uploader::uploadMedia(
|
||||
const FullMsgId &msgId,
|
||||
const SendMediaReady &media) {
|
||||
if (media.type == SendMediaType::Photo) {
|
||||
Auth().data().processPhoto(media.photo, media.photoThumbs);
|
||||
session().data().processPhoto(media.photo, media.photoThumbs);
|
||||
} else if (media.type == SendMediaType::File
|
||||
|| media.type == SendMediaType::ThemeFile
|
||||
|| media.type == SendMediaType::Audio) {
|
||||
const auto document = media.photoThumbs.empty()
|
||||
? Auth().data().processDocument(media.document)
|
||||
: Auth().data().processDocument(
|
||||
? session().data().processDocument(media.document)
|
||||
: session().data().processDocument(
|
||||
media.document,
|
||||
Images::FromImageInMemory(
|
||||
media.photoThumbs.front().second,
|
||||
@ -187,7 +196,7 @@ void Uploader::upload(
|
||||
const FullMsgId &msgId,
|
||||
const std::shared_ptr<FileLoadResult> &file) {
|
||||
if (file->type == SendMediaType::Photo) {
|
||||
const auto photo = Auth().data().processPhoto(
|
||||
const auto photo = session().data().processPhoto(
|
||||
file->photo,
|
||||
file->photoThumbs);
|
||||
photo->uploadingData = std::make_unique<Data::UploadState>(
|
||||
@ -196,8 +205,8 @@ void Uploader::upload(
|
||||
|| file->type == SendMediaType::ThemeFile
|
||||
|| file->type == SendMediaType::Audio) {
|
||||
const auto document = file->thumb.isNull()
|
||||
? Auth().data().processDocument(file->document)
|
||||
: Auth().data().processDocument(
|
||||
? session().data().processDocument(file->document)
|
||||
: session().data().processDocument(
|
||||
file->document,
|
||||
Images::FromImageInMemory(
|
||||
file->thumb,
|
||||
@ -241,7 +250,7 @@ void Uploader::currentFailed() {
|
||||
} else if (j->second.type() == SendMediaType::File
|
||||
|| j->second.type() == SendMediaType::ThemeFile
|
||||
|| j->second.type() == SendMediaType::Audio) {
|
||||
const auto document = Auth().data().document(j->second.id());
|
||||
const auto document = session().data().document(j->second.id());
|
||||
if (document->uploading()) {
|
||||
document->status = FileUploadFailed;
|
||||
}
|
||||
@ -552,7 +561,7 @@ void Uploader::partLoaded(const MTPBool &result, mtpRequestId requestId) {
|
||||
sentSizes[dc] -= sentPartSize;
|
||||
if (file.type() == SendMediaType::Photo) {
|
||||
file.fileSentSize += sentPartSize;
|
||||
const auto photo = Auth().data().photo(file.id());
|
||||
const auto photo = session().data().photo(file.id());
|
||||
if (photo->uploading() && file.file) {
|
||||
photo->uploadingData->size = file.file->partssize;
|
||||
photo->uploadingData->offset = file.fileSentSize;
|
||||
@ -561,7 +570,7 @@ void Uploader::partLoaded(const MTPBool &result, mtpRequestId requestId) {
|
||||
} else if (file.type() == SendMediaType::File
|
||||
|| file.type() == SendMediaType::ThemeFile
|
||||
|| file.type() == SendMediaType::Audio) {
|
||||
const auto document = Auth().data().document(file.id());
|
||||
const auto document = session().data().document(file.id());
|
||||
if (document->uploading()) {
|
||||
const auto doneParts = file.docSentParts
|
||||
- int(docRequestsSent.size());
|
||||
@ -595,8 +604,4 @@ bool Uploader::partFailed(const RPCError &error, mtpRequestId requestId) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Uploader::~Uploader() {
|
||||
clear();
|
||||
}
|
||||
|
||||
} // namespace Storage
|
||||
|
@ -16,6 +16,10 @@ class ApiWrap;
|
||||
struct FileLoadResult;
|
||||
struct SendMediaReady;
|
||||
|
||||
namespace Main {
|
||||
class Session;
|
||||
} // namespace Main
|
||||
|
||||
namespace Storage {
|
||||
|
||||
// MTP big files methods used for files greater than 10mb.
|
||||
@ -62,6 +66,8 @@ public:
|
||||
explicit Uploader(not_null<ApiWrap*> api);
|
||||
~Uploader();
|
||||
|
||||
[[nodiscard]] Main::Session &session() const;
|
||||
|
||||
void uploadMedia(const FullMsgId &msgId, const SendMediaReady &image);
|
||||
void upload(
|
||||
const FullMsgId &msgId,
|
||||
|
@ -428,7 +428,7 @@ void SendingAlbum::removeItem(not_null<HistoryItem*> item) {
|
||||
if (moveCaption) {
|
||||
const auto caption = item->originalText();
|
||||
const auto firstId = items.front().msgId;
|
||||
if (const auto first = Auth().data().message(firstId)) {
|
||||
if (const auto first = item->history()->owner().message(firstId)) {
|
||||
// We don't need to finishEdition() here, because the whole
|
||||
// album will be rebuilt after one item was removed from it.
|
||||
first->setText(caption);
|
||||
|
@ -21,6 +21,8 @@ constexpr auto kRequestPartsCount = 8;
|
||||
} // namespace
|
||||
|
||||
StreamedFileDownloader::StreamedFileDownloader(
|
||||
not_null<Main::Session*> session,
|
||||
|
||||
uint64 objectId,
|
||||
MTP::DcId dcId,
|
||||
Data::FileOrigin origin,
|
||||
@ -37,6 +39,7 @@ StreamedFileDownloader::StreamedFileDownloader(
|
||||
bool autoLoading,
|
||||
uint8 cacheTag)
|
||||
: FileLoader(
|
||||
session,
|
||||
toFile,
|
||||
size,
|
||||
locationType,
|
||||
|
@ -23,6 +23,8 @@ namespace Storage {
|
||||
class StreamedFileDownloader final : public FileLoader {
|
||||
public:
|
||||
StreamedFileDownloader(
|
||||
not_null<Main::Session*> session,
|
||||
|
||||
uint64 objectId,
|
||||
MTP::DcId dcId,
|
||||
Data::FileOrigin origin,
|
||||
|
Loading…
Reference in New Issue
Block a user