Skip to content

Commit

Permalink
remove thumbnail cache (#2033)
Browse files Browse the repository at this point in the history
* remove thumbnail cache

* simplify code

* simplify code

* remove unused 'protocol' abstraction

* move webxdc-description out of image-reading

* move play-button out of image-reading

* make enlarging GIF work; this lacks animantion similar to webp and others, that can be fixed on another PR

* reuse already calculated image from grip; this already fixes the non-animated GIF

* format
  • Loading branch information
r10s authored Jan 5, 2024
1 parent 5a7d03d commit 3c5c375
Show file tree
Hide file tree
Showing 11 changed files with 46 additions and 147 deletions.
4 changes: 0 additions & 4 deletions deltachat-ios.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,6 @@
AE57C0802552BBD0003CFE70 /* GalleryItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE57C07F2552BBD0003CFE70 /* GalleryItem.swift */; };
AE57C084255310BB003CFE70 /* ContextMenuController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE57C083255310BB003CFE70 /* ContextMenuController.swift */; };
AE6EC5242497663200A400E4 /* UIImageView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE6EC5232497663200A400E4 /* UIImageView+Extensions.swift */; };
AE6EC5282497B9B200A400E4 /* ThumbnailCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE6EC5272497B9B200A400E4 /* ThumbnailCache.swift */; };
AE728F15229D5C390047565B /* PhotoPickerAlertAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE728F14229D5C390047565B /* PhotoPickerAlertAction.swift */; };
AE76E5EE242BF2EA003CF461 /* WelcomeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE76E5ED242BF2EA003CF461 /* WelcomeViewController.swift */; };
AE77838D23E32ED20093EABD /* ContactDetailViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE77838C23E32ED20093EABD /* ContactDetailViewModel.swift */; };
Expand Down Expand Up @@ -447,7 +446,6 @@
AE57C07F2552BBD0003CFE70 /* GalleryItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GalleryItem.swift; sourceTree = "<group>"; };
AE57C083255310BB003CFE70 /* ContextMenuController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContextMenuController.swift; sourceTree = "<group>"; };
AE6EC5232497663200A400E4 /* UIImageView+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImageView+Extensions.swift"; sourceTree = "<group>"; };
AE6EC5272497B9B200A400E4 /* ThumbnailCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThumbnailCache.swift; sourceTree = "<group>"; };
AE728F14229D5C390047565B /* PhotoPickerAlertAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoPickerAlertAction.swift; sourceTree = "<group>"; };
AE76E5ED242BF2EA003CF461 /* WelcomeViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WelcomeViewController.swift; sourceTree = "<group>"; };
AE77838C23E32ED20093EABD /* ContactDetailViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactDetailViewModel.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -966,7 +964,6 @@
AE1988A423EB2FBA00B4CD5F /* Errors.swift */,
307D822D241669C7006D2490 /* LocationManager.swift */,
AE0AA9552478191900D42A7F /* GridCollectionViewFlowLayout.swift */,
AE6EC5272497B9B200A400E4 /* ThumbnailCache.swift */,
21D6C9392606190600D0755A /* NotificationManager.swift */,
3011E8042787365D00214221 /* KeychainManager.swift */,
30E83EFC289BF32C0035614C /* ShortcutManager.swift */,
Expand Down Expand Up @@ -1394,7 +1391,6 @@
3080A022277DE09900E74565 /* InputTextView.swift in Sources */,
30734326249A280B00BF9AD1 /* MediaQualityViewController.swift in Sources */,
3080A01C277DDB8A00E74565 /* InputBarAccessoryViewDelegate.swift in Sources */,
AE6EC5282497B9B200A400E4 /* ThumbnailCache.swift in Sources */,
30FDB70524D1C1000066C48D /* ChatViewController.swift in Sources */,
3080A013277DDABA00E74565 /* KeyboardNotification.swift in Sources */,
AE52EA20229EB9F000C586C9 /* EditGroupViewController.swift in Sources */,
Expand Down
32 changes: 10 additions & 22 deletions deltachat-ios/Chat/Views/Cells/ImageTextCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,32 +70,20 @@ class ImageTextCell: BaseMessageCell {
} else if msg.type == DC_MSG_VIDEO, let url = msg.fileURL {
playButtonView.isHidden = false
accessibilityLabel = String.localized("video")
if let image = ThumbnailCache.shared.restoreImage(key: url.absoluteString) {
contentImageView.image = image
contentImageIsPlaceholder = false
setAspectRatioFor(message: msg, with: image, isPlaceholder: false)
} else {
// no image in cache
let placeholderImage = UIImage(color: UIColor.init(alpha: 0,
red: 255,
green: 255,
blue: 255),
size: CGSize(width: 250, height: 250))
contentImageView.image = placeholderImage
DispatchQueue.global(qos: .userInteractive).async {
let thumbnailImage = DcUtils.generateThumbnailFromVideo(url: url)
if let thumbnailImage = thumbnailImage {
DispatchQueue.main.async { [weak self] in
if msg.id == self?.tag {
self?.contentImageView.image = thumbnailImage
self?.contentImageIsPlaceholder = false
ThumbnailCache.shared.storeImage(image: thumbnailImage, key: url.absoluteString)
}
let placeholderImage = UIImage(color: UIColor.init(alpha: 0, red: 255, green: 255, blue: 255), size: CGSize(width: 250, height: 250))
contentImageView.image = placeholderImage
DispatchQueue.global(qos: .userInteractive).async {
let thumbnailImage = DcUtils.generateThumbnailFromVideo(url: url)
if let thumbnailImage = thumbnailImage {
DispatchQueue.main.async { [weak self] in
if msg.id == self?.tag {
self?.contentImageView.image = thumbnailImage
self?.contentImageIsPlaceholder = false
}
}
}
setAspectRatioFor(message: msg, with: placeholderImage, isPlaceholder: true)
}
setAspectRatioFor(message: msg, with: placeholderImage, isPlaceholder: true)
}
super.update(dcContext: dcContext,
msg: msg,
Expand Down
6 changes: 1 addition & 5 deletions deltachat-ios/Chat/Views/FileView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -161,13 +161,9 @@ public class FileView: UIView {
}

private func generateThumbnailFor(url: URL, placeholder: UIImage?) {
if let thumbnail = ThumbnailCache.shared.restoreImage(key: url.absoluteString) {
fileImageView.image = thumbnail
horizontalLayout = allowLayoutChange ? false : horizontalLayout
} else if let pdfThumbnail = DcUtils.thumbnailFromPdf(withUrl: url) {
if let pdfThumbnail = DcUtils.thumbnailFromPdf(withUrl: url) {
fileImageView.image = pdfThumbnail
horizontalLayout = allowLayoutChange ? false : horizontalLayout
ThumbnailCache.shared.storeImage(image: pdfThumbnail, key: url.absoluteString)
} else {
let controller = UIDocumentInteractionController(url: url)
fileImageView.image = controller.icons.first ?? placeholder
Expand Down
24 changes: 8 additions & 16 deletions deltachat-ios/Chat/Views/MediaPreview.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,21 +50,14 @@ class MediaPreview: DraftPreview {
})
isHidden = false
} else if draft.viewType == DC_MSG_VIDEO, let path = draft.attachment {
if let image = ThumbnailCache.shared.restoreImage(key: path) {
self.contentImageView.image = image
self.setAspectRatio(image: image)
self.delegate?.onAttachmentAdded()
} else {
DispatchQueue.global(qos: .userInteractive).async {
let thumbnailImage = DcUtils.generateThumbnailFromVideo(url: URL(fileURLWithPath: path, isDirectory: false))
if let thumbnailImage = thumbnailImage {
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
self.contentImageView.image = thumbnailImage
self.setAspectRatio(image: thumbnailImage)
ThumbnailCache.shared.storeImage(image: thumbnailImage, key: path)
self.delegate?.onAttachmentAdded()
}
DispatchQueue.global(qos: .userInteractive).async {
let thumbnailImage = DcUtils.generateThumbnailFromVideo(url: URL(fileURLWithPath: path, isDirectory: false))
if let thumbnailImage = thumbnailImage {
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
self.contentImageView.image = thumbnailImage
self.setAspectRatio(image: thumbnailImage)
self.delegate?.onAttachmentAdded()
}
}
}
Expand Down Expand Up @@ -103,7 +96,6 @@ class MediaPreview: DraftPreview {
self?.configure(draft: draft)
})
} else if draft.viewType == DC_MSG_VIDEO {
ThumbnailCache.shared.deleteImage(key: attachment)
self.configure(draft: draft)
}
}
Expand Down
36 changes: 14 additions & 22 deletions deltachat-ios/Controller/ContextMenuController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,15 @@ import AVFoundation
import SDWebImage
import DcCore


protocol ContextMenuItem {
var msg: DcMsg { get set }
var thumbnailImage: UIImage? { get set }
}

// MARK: - ContextMenuController
class ContextMenuController: UIViewController {

let item: ContextMenuItem

var msg: DcMsg {
return item.msg
}
let msg: DcMsg
let image: UIImage?

init(item: ContextMenuItem) {
self.item = item
init(msg: DcMsg, image: UIImage?) {
self.msg = msg
self.image = image
super.init(nibName: nil, bundle: nil)
}

Expand All @@ -35,11 +27,11 @@ class ContextMenuController: UIViewController {
var thumbnailView: UIView?
switch viewType {
case .image:
thumbnailView = makeImageView(image: msg.image)
thumbnailView = makeImageView()
case .video:
thumbnailView = makeVideoView(videoUrl: msg.fileURL)
thumbnailView = makeVideoView()
case .gif:
thumbnailView = makeGifView(gifImage: item.thumbnailImage)
thumbnailView = makeGifView()
default:
return
}
Expand All @@ -60,19 +52,19 @@ class ContextMenuController: UIViewController {
}

// MARK: - thumbnailView creation
private func makeGifView(gifImage: UIImage?) -> UIView? {
private func makeGifView() -> UIView? {
let view = SDAnimatedImageView()
view.contentMode = .scaleAspectFill
view.clipsToBounds = true
view.backgroundColor = DcColors.defaultBackgroundColor
if let image = gifImage {
if let image = image {
setPreferredContentSize(for: image)
}
view.image = gifImage
view.image = image
return view
}

private func makeImageView(image: UIImage?) -> UIView? {
private func makeImageView() -> UIView? {
guard let image = image else {
return nil
}
Expand All @@ -85,8 +77,8 @@ class ContextMenuController: UIViewController {
return imageView
}

private func makeVideoView(videoUrl: URL?) -> UIView? {
guard let videoUrl = videoUrl, let videoSize = item.thumbnailImage?.size else { return nil }
private func makeVideoView() -> UIView? {
guard let videoUrl = msg.fileURL, let videoSize = image?.size else { return nil }
let player = AVPlayer(url: videoUrl)
let playerController = AVPlayerViewController()
addChild(playerController)
Expand Down
4 changes: 2 additions & 2 deletions deltachat-ios/Controller/GalleryViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -309,14 +309,14 @@ extension GalleryViewController: UICollectionViewDataSource, UICollectionViewDel
_ collectionView: UICollectionView,
contextMenuConfigurationForItemAt indexPath: IndexPath,
point: CGPoint) -> UIContextMenuConfiguration? {
guard let galleryCell = collectionView.cellForItem(at: indexPath) as? GalleryCell, let item = galleryCell.item else {
guard let galleryCell = collectionView.cellForItem(at: indexPath) as? GalleryCell, let item = galleryCell.item else {
return nil
}

return UIContextMenuConfiguration(
identifier: nil,
previewProvider: {
let contextMenuController = ContextMenuController(item: item)
let contextMenuController = ContextMenuController(msg: item.msg, image: galleryCell.imageView.image)
return contextMenuController
},
actionProvider: { [weak self] _ in
Expand Down
25 changes: 0 additions & 25 deletions deltachat-ios/Helper/ThumbnailCache.swift

This file was deleted.

51 changes: 7 additions & 44 deletions deltachat-ios/Model/GalleryItem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,67 +2,30 @@ import UIKit
import DcCore
import SDWebImage

class GalleryItem: ContextMenuItem {
class GalleryItem {

var onImageLoaded: ((UIImage?) -> Void)?

var msg: DcMsg

var fileUrl: URL? {
return msg.fileURL
}

var description: String?
let msg: DcMsg

var thumbnailImage: UIImage? {
get {
if let fileUrl = self.fileUrl {
if let image = ThumbnailCache.shared.restoreImage(key: fileUrl.absoluteString) {
return image
} else {
loadThumbnail()
}
}
loadThumbnail()
return nil
}
set {
if let fileUrl = self.fileUrl {
if let image = newValue {
ThumbnailCache.shared.storeImage(image: image, key: fileUrl.absoluteString)
onImageLoaded?(newValue)
} else {
ThumbnailCache.shared.deleteImage(key: fileUrl.absoluteString)
}
}
}
}

var showPlayButton: Bool {
switch msg.viewtype {
case .video:
return true
default:
return false
onImageLoaded?(newValue)
}
}

init(msg: DcMsg) {
self.msg = msg
if let key = msg.fileURL?.absoluteString, let image = ThumbnailCache.shared.restoreImage(key: key) {
self.thumbnailImage = image
} else {
loadThumbnail()
}
if msg.viewtype == .webxdc {
description = msg.getWebxdcInfoDict()["name"] as? String ?? "ErrName"
}
loadThumbnail()
}

private func loadThumbnail() {
guard let viewtype = msg.viewtype, let url = msg.fileURL else {
return
}
switch viewtype {
guard let url = msg.fileURL else { return }
switch msg.viewtype {
case .image, .gif:
loadImageThumbnail(from: url)
case .video:
Expand Down
5 changes: 1 addition & 4 deletions deltachat-ios/View/Cell/DocumentGalleryFileCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,8 @@ class DocumentGalleryFileCell: UITableViewCell {
}

private func generateThumbnailFor(url: URL, placeholder: UIImage?) {
if let thumbnail = ThumbnailCache.shared.restoreImage(key: url.absoluteString) {
fileImageView.image = thumbnail
} else if let pdfThumbnail = DcUtils.thumbnailFromPdf(withUrl: url) {
if let pdfThumbnail = DcUtils.thumbnailFromPdf(withUrl: url) {
fileImageView.image = pdfThumbnail
ThumbnailCache.shared.storeImage(image: pdfThumbnail, key: url.absoluteString)
} else {
let controller = UIDocumentInteractionController(url: url)
fileImageView.image = controller.icons.first ?? placeholder
Expand Down
4 changes: 2 additions & 2 deletions deltachat-ios/View/Cell/GalleryCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,11 @@ class GalleryCell: UICollectionViewCell {
item.onImageLoaded = { [weak self] image in
self?.imageView.image = image
}
playButtonView.isHidden = !item.showPlayButton
playButtonView.isHidden = item.msg.viewtype != .video
imageView.image = item.thumbnailImage

contentView.isAccessibilityElement = true
contentView.accessibilityHint = String.localized(item.showPlayButton ? "video" : "image")
contentView.accessibilityHint = String.localized(playButtonView.isHidden ? "image" : "video")
+ ", " + DateUtils.getBriefRelativeTimeSpanString(timeStamp: Double(item.msg.timestamp))
}

Expand Down
2 changes: 1 addition & 1 deletion deltachat-ios/View/Cell/WebxdcGridCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class WebxdcGridCell: UICollectionViewCell {
self?.imageView.image = image
}
imageView.image = item.thumbnailImage
descriptionLabel.text = item.description
descriptionLabel.text = item.msg.getWebxdcInfoDict()["name"] as? String ?? "ErrName"
}

override var isSelected: Bool {
Expand Down

0 comments on commit 3c5c375

Please sign in to comment.