From 8e7117fa2283f0a7081e4d373d3b51f00b71ef36 Mon Sep 17 00:00:00 2001
From: John Preston <johnprestonmail@gmail.com>
Date: Tue, 23 Oct 2018 16:57:43 +0400
Subject: [PATCH] Don't unload all media on switching between chats.

---
 .../chat_helpers/gifs_list_widget.cpp         | 22 +++++++++----------
 Telegram/SourceFiles/data/data_document.cpp   |  7 ++++--
 Telegram/SourceFiles/data/data_document.h     |  2 +-
 Telegram/SourceFiles/data/data_game.h         |  5 -----
 Telegram/SourceFiles/data/data_photo.cpp      |  9 ++++----
 Telegram/SourceFiles/data/data_photo.h        |  2 +-
 Telegram/SourceFiles/data/data_session.cpp    | 12 ----------
 Telegram/SourceFiles/data/data_session.h      |  2 --
 Telegram/SourceFiles/data/data_web_page.h     |  5 -----
 .../history/history_media_types.cpp           |  2 +-
 .../SourceFiles/history/history_widget.cpp    |  1 -
 .../inline_bot_layout_internal.cpp            |  8 +++----
 .../inline_bots/inline_bot_result.cpp         |  7 +++---
 .../inline_bots/inline_bot_result.h           |  2 +-
 .../inline_bots/inline_results_widget.cpp     | 18 +++++++--------
 Telegram/SourceFiles/mediaview.cpp            |  4 ++--
 .../SourceFiles/overview/overview_layout.cpp  |  4 ++--
 Telegram/SourceFiles/ui/image/image.cpp       |  8 +++----
 Telegram/SourceFiles/ui/image/image.h         |  4 ++--
 .../SourceFiles/ui/image/image_source.cpp     | 14 ++++++------
 Telegram/SourceFiles/ui/image/image_source.h  |  6 ++---
 21 files changed, 61 insertions(+), 83 deletions(-)

diff --git a/Telegram/SourceFiles/chat_helpers/gifs_list_widget.cpp b/Telegram/SourceFiles/chat_helpers/gifs_list_widget.cpp
index 5f7e1c10d..6bf7ed7e4 100644
--- a/Telegram/SourceFiles/chat_helpers/gifs_list_widget.cpp
+++ b/Telegram/SourceFiles/chat_helpers/gifs_list_widget.cpp
@@ -405,24 +405,24 @@ void GifsListWidget::processHideFinished() {
 }
 
 void GifsListWidget::processPanelHideFinished() {
-	auto itemForget = [](auto &item) {
-		if (auto document = item->getDocument()) {
-			document->forget();
+	const auto itemForget = [](const auto &item) {
+		if (const auto document = item->getDocument()) {
+			document->unload();
 		}
-		if (auto photo = item->getPhoto()) {
-			photo->forget();
+		if (const auto photo = item->getPhoto()) {
+			photo->unload();
 		}
-		if (auto result = item->getResult()) {
-			result->forget();
+		if (const auto result = item->getResult()) {
+			result->unload();
 		}
 	};
 	// Preserve panel state through visibility toggles.
 	//clearInlineRows(false);
-	for_const (auto &item, _gifLayouts) {
-		itemForget(item.second);
+	for (const auto &[document, layout] : _gifLayouts) {
+		itemForget(layout);
 	}
-	for_const (auto &item, _inlineLayouts) {
-		itemForget(item.second);
+	for (const auto &[document, layout] : _inlineLayouts) {
+		itemForget(layout);
 	}
 }
 
diff --git a/Telegram/SourceFiles/data/data_document.cpp b/Telegram/SourceFiles/data/data_document.cpp
index a276afb55..7418cfef3 100644
--- a/Telegram/SourceFiles/data/data_document.cpp
+++ b/Telegram/SourceFiles/data/data_document.cpp
@@ -34,7 +34,7 @@ constexpr auto kMemoryForCache = 32 * 1024 * 1024;
 Core::MediaActiveCache<DocumentData> &ActiveCache() {
 	static auto Instance = Core::MediaActiveCache<DocumentData>(
 		kMemoryForCache,
-		[](DocumentData *document) { document->forget(); });
+		[](DocumentData *document) { document->unload(); });
 	return Instance;
 }
 
@@ -536,7 +536,9 @@ bool DocumentData::saveToCache() const {
 		|| (isVoiceMessage() && size < Storage::kMaxVoiceInMemory);
 }
 
-void DocumentData::forget() {
+void DocumentData::unload() {
+	// Forget thumb only when image cache limit exceeds.
+	//thumb->unload();
 	if (sticker()) {
 		if (!sticker()->img->isNull()) {
 			ActiveCache().decrement(ComputeUsage(sticker()));
@@ -551,6 +553,7 @@ void DocumentData::forget() {
 		delete replyPreview.get();
 		replyPreview = ImagePtr();
 	}
+
 	ActiveCache().decrement(_data.size());
 	_data.clear();
 }
diff --git a/Telegram/SourceFiles/data/data_document.h b/Telegram/SourceFiles/data/data_document.h
index 79e6a57ba..bc508518a 100644
--- a/Telegram/SourceFiles/data/data_document.h
+++ b/Telegram/SourceFiles/data/data_document.h
@@ -121,7 +121,7 @@ public:
 
 	void performActionOnLoad();
 
-	void forget();
+	void unload();
 	ImagePtr makeReplyPreview(Data::FileOrigin origin);
 
 	StickerData *sticker() const;
diff --git a/Telegram/SourceFiles/data/data_game.h b/Telegram/SourceFiles/data/data_game.h
index 8613b5727..b74771fc9 100644
--- a/Telegram/SourceFiles/data/data_game.h
+++ b/Telegram/SourceFiles/data/data_game.h
@@ -30,11 +30,6 @@ struct GameData {
 	, document(document) {
 	}
 
-	void forget() {
-		if (document) document->forget();
-		if (photo) photo->forget();
-	}
-
 	GameId id = 0;
 	uint64 accessHash = 0;
 	QString shortName;
diff --git a/Telegram/SourceFiles/data/data_photo.cpp b/Telegram/SourceFiles/data/data_photo.cpp
index 6acde7535..ff3b6ac09 100644
--- a/Telegram/SourceFiles/data/data_photo.cpp
+++ b/Telegram/SourceFiles/data/data_photo.cpp
@@ -103,15 +103,16 @@ bool PhotoData::uploading() const {
 	return (uploadingData != nullptr);
 }
 
-void PhotoData::forget() {
-	thumb->forget();
+void PhotoData::unload() {
+	// Forget thumb only when image cache limit exceeds.
+	//thumb->unload();
+	medium->unload();
+	full->unload();
 	if (!replyPreview->isNull()) {
 		// Should be std::unique_ptr<Image>.
 		delete replyPreview.get();
 		replyPreview = ImagePtr();
 	}
-	medium->forget();
-	full->forget();
 }
 
 ImagePtr PhotoData::makeReplyPreview(Data::FileOrigin origin) {
diff --git a/Telegram/SourceFiles/data/data_photo.h b/Telegram/SourceFiles/data/data_photo.h
index 64dcafd19..9dd2a1c71 100644
--- a/Telegram/SourceFiles/data/data_photo.h
+++ b/Telegram/SourceFiles/data/data_photo.h
@@ -38,7 +38,7 @@ public:
 	void setWaitingForAlbum();
 	bool waitingForAlbum() const;
 
-	void forget();
+	void unload();
 	ImagePtr makeReplyPreview(Data::FileOrigin origin);
 
 	MTPInputPhoto mtpInput() const;
diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp
index 0ee126c2f..7ef6ece7b 100644
--- a/Telegram/SourceFiles/data/data_session.cpp
+++ b/Telegram/SourceFiles/data/data_session.cpp
@@ -2008,18 +2008,6 @@ void Session::insertCheckedServiceNotification(
 	sendHistoryChangeNotifications();
 }
 
-void Session::forgetMedia() {
-	for (const auto &[id, photo] : _photos) {
-		photo->forget();
-	}
-	for (const auto &[id, document] : _documents) {
-		document->forget();
-	}
-	for (const auto &[coords, location] : _locations) {
-		location->thumb->forget();
-	}
-}
-
 void Session::setMimeForwardIds(MessageIdsList &&list) {
 	_mimeForwardIds = std::move(list);
 }
diff --git a/Telegram/SourceFiles/data/data_session.h b/Telegram/SourceFiles/data/data_session.h
index a3c3aa888..4f11fc91c 100644
--- a/Telegram/SourceFiles/data/data_session.h
+++ b/Telegram/SourceFiles/data/data_session.h
@@ -420,8 +420,6 @@ public:
 		const TextWithEntities &message,
 		const MTPMessageMedia &media = MTP_messageMediaEmpty());
 
-	void forgetMedia();
-
 	void setMimeForwardIds(MessageIdsList &&list);
 	MessageIdsList takeMimeForwardIds();
 
diff --git a/Telegram/SourceFiles/data/data_web_page.h b/Telegram/SourceFiles/data/data_web_page.h
index d73a479fb..164dbc20f 100644
--- a/Telegram/SourceFiles/data/data_web_page.h
+++ b/Telegram/SourceFiles/data/data_web_page.h
@@ -54,11 +54,6 @@ struct WebPageData {
 	, pendingTill(pendingTill) {
 	}
 
-	void forget() {
-		if (document) document->forget();
-		if (photo) photo->forget();
-	}
-
 	bool applyChanges(
 		const QString &newType,
 		const QString &newUrl,
diff --git a/Telegram/SourceFiles/history/history_media_types.cpp b/Telegram/SourceFiles/history/history_media_types.cpp
index 1b0a71000..4b74336d9 100644
--- a/Telegram/SourceFiles/history/history_media_types.cpp
+++ b/Telegram/SourceFiles/history/history_media_types.cpp
@@ -2758,7 +2758,7 @@ void HistoryGif::stopAnimation() {
 	if (_gif) {
 		clearClipReader();
 		Auth().data().requestViewResize(_parent);
-		_data->forget();
+		_data->unload();
 	}
 }
 
diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp
index 16ca44166..c0e3a8f90 100644
--- a/Telegram/SourceFiles/history/history_widget.cpp
+++ b/Telegram/SourceFiles/history/history_widget.cpp
@@ -1922,7 +1922,6 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
 	_nonEmptySelection = false;
 
 	if (_peer) {
-		Auth().data().forgetMedia();
 		Auth().downloader().clearPriorities();
 
 		_history = App::history(_peer);
diff --git a/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.cpp b/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.cpp
index 7475de4dd..8842aa2dd 100644
--- a/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.cpp
+++ b/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.cpp
@@ -353,14 +353,14 @@ void Gif::clipCallback(Media::Clip::Notification notification) {
 		if (_gif) {
 			if (_gif->state() == State::Error) {
 				_gif.setBad();
-				getShownDocument()->forget();
+				getShownDocument()->unload();
 			} else if (_gif->ready() && !_gif->started()) {
 				auto height = st::inlineMediaHeight;
 				auto frame = countFrameSize();
 				_gif->start(frame.width(), frame.height(), _width, height, ImageRoundRadius::None, RectPart::None);
 			} else if (_gif->autoPausedGif() && !context()->inlineItemVisible(this)) {
 				_gif.reset();
-				getShownDocument()->forget();
+				getShownDocument()->unload();
 			}
 		}
 
@@ -1373,12 +1373,12 @@ void Game::clipCallback(Media::Clip::Notification notification) {
 		if (_gif) {
 			if (_gif->state() == State::Error) {
 				_gif.setBad();
-				getResultDocument()->forget();
+				getResultDocument()->unload();
 			} else if (_gif->ready() && !_gif->started()) {
 				_gif->start(_frameSize.width(), _frameSize.height(), st::inlineThumbSize, st::inlineThumbSize, ImageRoundRadius::None, RectPart::None);
 			} else if (_gif->autoPausedGif() && !context()->inlineItemVisible(this)) {
 				_gif.reset();
-				getResultDocument()->forget();
+				getResultDocument()->unload();
 			}
 		}
 
diff --git a/Telegram/SourceFiles/inline_bots/inline_bot_result.cpp b/Telegram/SourceFiles/inline_bots/inline_bot_result.cpp
index 65418a3eb..0d33f3ec0 100644
--- a/Telegram/SourceFiles/inline_bots/inline_bot_result.cpp
+++ b/Telegram/SourceFiles/inline_bots/inline_bot_result.cpp
@@ -279,13 +279,12 @@ bool Result::onChoose(Layout::ItemBase *layout) {
 	return true;
 }
 
-void Result::forget() {
-	_thumb->forget();
+void Result::unload() {
 	if (_document) {
-		_document->forget();
+		_document->unload();
 	}
 	if (_photo) {
-		_photo->forget();
+		_photo->unload();
 	}
 }
 
diff --git a/Telegram/SourceFiles/inline_bots/inline_bot_result.h b/Telegram/SourceFiles/inline_bots/inline_bot_result.h
index b0d992c22..f047eb39a 100644
--- a/Telegram/SourceFiles/inline_bots/inline_bot_result.h
+++ b/Telegram/SourceFiles/inline_bots/inline_bot_result.h
@@ -45,7 +45,7 @@ public:
 	// inline bot result. If it returns true you need to send this result.
 	bool onChoose(Layout::ItemBase *layout);
 
-	void forget();
+	void unload();
 	void openFile();
 	void cancelFile();
 
diff --git a/Telegram/SourceFiles/inline_bots/inline_results_widget.cpp b/Telegram/SourceFiles/inline_bots/inline_results_widget.cpp
index 88414dab7..23f7d3026 100644
--- a/Telegram/SourceFiles/inline_bots/inline_results_widget.cpp
+++ b/Telegram/SourceFiles/inline_bots/inline_results_widget.cpp
@@ -267,20 +267,20 @@ void Inner::clearSelection() {
 
 void Inner::hideFinish(bool completely) {
 	if (completely) {
-		auto itemForget = [](auto &item) {
-			if (auto document = item->getDocument()) {
-				document->forget();
+		const auto unload = [](const auto &item) {
+			if (const auto document = item->getDocument()) {
+				document->unload();
 			}
-			if (auto photo = item->getPhoto()) {
-				photo->forget();
+			if (const auto photo = item->getPhoto()) {
+				photo->unload();
 			}
-			if (auto result = item->getResult()) {
-				result->forget();
+			if (const auto result = item->getResult()) {
+				result->unload();
 			}
 		};
 		clearInlineRows(false);
-		for_const (auto &item, _inlineLayouts) {
-			itemForget(item.second);
+		for (const auto &[result, layout] : _inlineLayouts) {
+			unload(layout);
 		}
 	}
 }
diff --git a/Telegram/SourceFiles/mediaview.cpp b/Telegram/SourceFiles/mediaview.cpp
index efe902e28..8c53b898f 100644
--- a/Telegram/SourceFiles/mediaview.cpp
+++ b/Telegram/SourceFiles/mediaview.cpp
@@ -2589,9 +2589,9 @@ void MediaView::preloadData(int delta) {
 		auto forgetIndex = *_index - delta * 2;
 		auto entity = entityByIndex(forgetIndex);
 		if (auto photo = base::get_if<not_null<PhotoData*>>(&entity.data)) {
-			(*photo)->forget();
+			(*photo)->unload();
 		} else if (auto document = base::get_if<not_null<DocumentData*>>(&entity.data)) {
-			(*document)->forget();
+			(*document)->unload();
 		}
 	}
 
diff --git a/Telegram/SourceFiles/overview/overview_layout.cpp b/Telegram/SourceFiles/overview/overview_layout.cpp
index 3f3882f0a..7e8d8bc43 100644
--- a/Telegram/SourceFiles/overview/overview_layout.cpp
+++ b/Telegram/SourceFiles/overview/overview_layout.cpp
@@ -342,7 +342,7 @@ void Photo::paint(Painter &p, const QRect &clip, TextSelection selection, const
 				img = img.copy(0, (img.height() - img.width()) / 2, img.width(), img.width()).scaled(size, size, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);
 			}
 			img.setDevicePixelRatio(cRetinaFactor());
-			_data->forget();
+			_data->unload();
 
 			_pix = App::pixmapFromImageInPlace(std::move(img));
 		} else if (!_pix.isNull()) {
@@ -426,7 +426,7 @@ void Video::paint(Painter &p, const QRect &clip, TextSelection selection, const
 				img = img.copy(0, (img.height() - img.width()) / 2, img.width(), img.width()).scaled(size, size, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);
 			}
 			img.setDevicePixelRatio(cRetinaFactor());
-			_data->forget();
+			_data->unload();
 
 			_pix = App::pixmapFromImageInPlace(std::move(img));
 		} else if (!_pix.isNull()) {
diff --git a/Telegram/SourceFiles/ui/image/image.cpp b/Telegram/SourceFiles/ui/image/image.cpp
index 8124f4e30..092dd3d78 100644
--- a/Telegram/SourceFiles/ui/image/image.cpp
+++ b/Telegram/SourceFiles/ui/image/image.cpp
@@ -42,7 +42,7 @@ int64 ComputeUsage(const QImage &image) {
 Core::MediaActiveCache<const Image> &ActiveCache() {
 	static auto Instance = Core::MediaActiveCache<const Image>(
 		kMemoryForCache,
-		[](const Image *image) { image->forget(); });
+		[](const Image *image) { image->unload(); });
 	return Instance;
 }
 
@@ -769,9 +769,9 @@ void Image::checkSource() const {
 	ActiveCache().up(this);
 }
 
-void Image::forget() const {
+void Image::unload() const {
 	_source->takeLoaded();
-	_source->forget();
+	_source->unload();
 	invalidateSizeCache();
 	ActiveCache().decrement(ComputeUsage(_data));
 	_data = QImage();
@@ -800,6 +800,6 @@ void Image::invalidateSizeCache() const {
 }
 
 Image::~Image() {
-	forget();
+	unload();
 	ActiveCache().remove(this);
 }
diff --git a/Telegram/SourceFiles/ui/image/image.h b/Telegram/SourceFiles/ui/image/image.h
index f86082691..5ef58aaff 100644
--- a/Telegram/SourceFiles/ui/image/image.h
+++ b/Telegram/SourceFiles/ui/image/image.h
@@ -54,7 +54,7 @@ public:
 		bool loadFirst,
 		bool prior) = 0;
 	virtual QImage takeLoaded() = 0;
-	virtual void forget() = 0;
+	virtual void unload() = 0;
 
 	virtual void automaticLoad(
 		Data::FileOrigin origin,
@@ -229,7 +229,7 @@ public:
 
 	bool loaded() const;
 	bool isNull() const;
-	void forget() const;
+	void unload() const;
 	void setDelayedStorageLocation(
 		Data::FileOrigin origin,
 		const StorageImageLocation &location);
diff --git a/Telegram/SourceFiles/ui/image/image_source.cpp b/Telegram/SourceFiles/ui/image/image_source.cpp
index ebb53633d..79df7b107 100644
--- a/Telegram/SourceFiles/ui/image/image_source.cpp
+++ b/Telegram/SourceFiles/ui/image/image_source.cpp
@@ -37,7 +37,7 @@ QImage ImageSource::takeLoaded() {
 	return _data;
 }
 
-void ImageSource::forget() {
+void ImageSource::unload() {
 }
 
 void ImageSource::automaticLoad(
@@ -161,7 +161,7 @@ QImage LocalFileSource::takeLoaded() {
 	return std::move(_data);
 }
 
-void LocalFileSource::forget() {
+void LocalFileSource::unload() {
 	_data = QImage();
 }
 
@@ -361,10 +361,6 @@ void RemoteSource::loadEvenCancelled(
 	return load(origin, loadFirst, prior);
 }
 
-RemoteSource::~RemoteSource() {
-	forget();
-}
-
 bool RemoteSource::displayLoading() {
 	return loaderValid()
 		&& (!_loader->loadingLocal() || !_loader->autoLoading());
@@ -380,7 +376,7 @@ void RemoteSource::cancel() {
 		std::unique_ptr<FileLoader>(loader));
 }
 
-void RemoteSource::forget() {
+void RemoteSource::unload() {
 	if (loaderValid()) {
 		destroyLoaderDelayed();
 	}
@@ -394,6 +390,10 @@ int RemoteSource::loadOffset() {
 	return loaderValid() ? _loader->currentOffset() : 0;
 }
 
+RemoteSource::~RemoteSource() {
+	unload();
+}
+
 const StorageImageLocation &RemoteSource::location() {
 	return StorageImageLocation::Null;
 }
diff --git a/Telegram/SourceFiles/ui/image/image_source.h b/Telegram/SourceFiles/ui/image/image_source.h
index 42a7bdcc4..7fa02445e 100644
--- a/Telegram/SourceFiles/ui/image/image_source.h
+++ b/Telegram/SourceFiles/ui/image/image_source.h
@@ -24,7 +24,7 @@ public:
 		bool loadFirst,
 		bool prior) override;
 	QImage takeLoaded() override;
-	void forget() override;
+	void unload() override;
 
 	void automaticLoad(
 		Data::FileOrigin origin,
@@ -75,7 +75,7 @@ public:
 		bool loadFirst,
 		bool prior) override;
 	QImage takeLoaded() override;
-	void forget() override;
+	void unload() override;
 
 	void automaticLoad(
 		Data::FileOrigin origin,
@@ -126,7 +126,7 @@ public:
 		bool loadFirst,
 		bool prior) override;
 	QImage takeLoaded() override;
-	void forget() override;
+	void unload() override;
 
 	void automaticLoad(
 		Data::FileOrigin origin,