diff --git a/Telegram/SourceFiles/data/data_media_types.cpp b/Telegram/SourceFiles/data/data_media_types.cpp
index ec3711b52..b25b0266d 100644
--- a/Telegram/SourceFiles/data/data_media_types.cpp
+++ b/Telegram/SourceFiles/data/data_media_types.cpp
@@ -347,63 +347,84 @@ bool MediaPhoto::updateSentMedia(const MTPMessageMedia &media) {
 	if (photo.type() != mtpc_photo) {
 		return false;
 	}
+	struct SizeData {
+		char letter = 0;
+		int width = 0;
+		int height = 0;
+		const MTPFileLocation *location = nullptr;
+		QByteArray bytes;
+	};
 	const auto saveImageToCache = [](
-			const MTPDfileLocation &location,
-			const ImagePtr &image) {
-		const auto key = StorageImageLocation(0, 0, location);
+			const ImagePtr &image,
+			SizeData size) {
+		Expects(size.location != nullptr);
+
+		const auto key = StorageImageLocation(
+			size.width,
+			size.height,
+			size.location->c_fileLocation());
 		if (key.isNull() || image->isNull() || !image->loaded()) {
 			return;
 		}
-		auto bytes = image->bytesForCache();
-		if (bytes.isEmpty() || bytes.size() > Storage::kMaxFileInMemory) {
+		if (size.bytes.isEmpty()) {
+			size.bytes = image->bytesForCache();
+		}
+		const auto length = size.bytes.size();
+		if (!length || length > Storage::kMaxFileInMemory) {
+			LOG(("App Error: Bad photo data for saving to cache."));
 			return;
 		}
 		Auth().data().cache().putIfEmpty(
 			Data::StorageCacheKey(key),
 			Storage::Cache::Database::TaggedValue(
-				std::move(bytes),
+				std::move(size.bytes),
 				Data::kImageCacheTag));
+		image->replaceSource(
+			std::make_unique<Images::StorageSource>(key, length));
 	};
 	auto &sizes = photo.c_photo().vsizes.v;
 	auto max = 0;
-	const MTPDfileLocation *maxLocation = 0;
+	auto maxSize = SizeData();
 	for (const auto &data : sizes) {
-		char size = 0;
-		const MTPFileLocation *loc = 0;
-		switch (data.type()) {
-		case mtpc_photoSize: {
-			const auto &s = data.c_photoSize().vtype.v;
-			loc = &data.c_photoSize().vlocation;
-			if (s.size()) size = s[0];
-		} break;
-
-		case mtpc_photoCachedSize: {
-			const auto &s = data.c_photoCachedSize().vtype.v;
-			loc = &data.c_photoCachedSize().vlocation;
-			if (s.size()) size = s[0];
-		} break;
-		}
-		if (!loc || loc->type() != mtpc_fileLocation) {
+		const auto size = data.match([](const MTPDphotoSize &data) {
+			return SizeData{
+				data.vtype.v.isEmpty() ? char(0) : data.vtype.v[0],
+				data.vw.v,
+				data.vh.v,
+				&data.vlocation,
+				QByteArray()
+			};
+		}, [](const MTPDphotoCachedSize &data) {
+			return SizeData{
+				data.vtype.v.isEmpty() ? char(0) : data.vtype.v[0],
+				data.vw.v,
+				data.vh.v,
+				&data.vlocation,
+				qba(data.vbytes)
+			};
+		}, [](const MTPDphotoSizeEmpty &) {
+			return SizeData();
+		});
+		if (!size.location || size.location->type() != mtpc_fileLocation) {
 			continue;
 		}
-		const auto &location = loc->c_fileLocation();
-		if (size == 's') {
-			saveImageToCache(location, _photo->thumb);
-		} else if (size == 'm') {
-			saveImageToCache(location, _photo->medium);
-		} else if (size == 'x' && max < 1) {
+		if (size.letter == 's') {
+			saveImageToCache(_photo->thumb, size);
+		} else if (size.letter == 'm') {
+			saveImageToCache(_photo->medium, size);
+		} else if (size.letter == 'x' && max < 1) {
 			max = 1;
-			maxLocation = &location;
-		} else if (size == 'y' && max < 2) {
+			maxSize = size;
+		} else if (size.letter == 'y' && max < 2) {
 			max = 2;
-			maxLocation = &location;
-		//} else if (size == 'w' && max < 3) {
+			maxSize = size;
+		//} else if (size.letter == 'w' && max < 3) {
 		//	max = 3;
-		//	maxLocation = &loc->c_fileLocation();
+		//	maxSize = size;
 		}
 	}
-	if (maxLocation) {
-		saveImageToCache(*maxLocation, _photo->full);
+	if (maxSize.location) {
+		saveImageToCache(_photo->full, maxSize);
 	}
 	return true;
 }
diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp
index b587ac220..71fd77eef 100644
--- a/Telegram/SourceFiles/data/data_session.cpp
+++ b/Telegram/SourceFiles/data/data_session.cpp
@@ -880,15 +880,15 @@ PhotoData *Session::photoFromWeb(
 	if (full->isNull()) {
 		return nullptr;
 	}
-	const auto width = full->width();
-	const auto height = full->height();
-	if (thumb->isNull()) {
-		auto thumbsize = shrinkToKeepAspect(width, height, 100, 100);
-		thumb = ImagePtr(thumbsize.width(), thumbsize.height());
-	}
+	//const auto width = full->width();
+	//const auto height = full->height();
+	//if (thumb->isNull()) {
+	//	auto thumbsize = shrinkToKeepAspect(width, height, 100, 100);
+	//	thumb = ImagePtr(thumbsize.width(), thumbsize.height());
+	//}
 
-	auto mediumsize = shrinkToKeepAspect(width, height, 320, 320);
-	auto medium = ImagePtr(mediumsize.width(), mediumsize.height());
+	//auto mediumsize = shrinkToKeepAspect(width, height, 320, 320);
+	//auto medium = ImagePtr(mediumsize.width(), mediumsize.height());
 
 	return photo(
 		rand_value<PhotoId>(),
@@ -896,7 +896,7 @@ PhotoData *Session::photoFromWeb(
 		QByteArray(),
 		unixtime(),
 		thumb,
-		medium,
+		ImagePtr(),
 		full);
 }
 
diff --git a/Telegram/SourceFiles/ui/image.cpp b/Telegram/SourceFiles/ui/image.cpp
index d010d9fe0..73f675043 100644
--- a/Telegram/SourceFiles/ui/image.cpp
+++ b/Telegram/SourceFiles/ui/image.cpp
@@ -778,6 +778,10 @@ Image::Image(std::unique_ptr<Images::Source> &&source)
 : _source(std::move(source)) {
 }
 
+void Image::replaceSource(std::unique_ptr<Images::Source> &&source) {
+	_source = std::move(source);
+}
+
 Image *Image::Blank() {
 	static const auto blankImage = [] {
 		const auto factor = cIntRetinaFactor();
diff --git a/Telegram/SourceFiles/ui/image.h b/Telegram/SourceFiles/ui/image.h
index 5e33a5f94..af943770c 100644
--- a/Telegram/SourceFiles/ui/image.h
+++ b/Telegram/SourceFiles/ui/image.h
@@ -368,6 +368,8 @@ class Image final {
 public:
 	explicit Image(std::unique_ptr<Images::Source> &&source);
 
+	void replaceSource(std::unique_ptr<Images::Source> &&source);
+
 	static Image *Blank();
 
 	const QPixmap &pix(