Skip to content

Commit

Permalink
Store the preview width in addition to the height
Browse files Browse the repository at this point in the history
Signed-off-by: Marcel Müller <[email protected]>
  • Loading branch information
SystemKeeper committed Dec 15, 2024
1 parent 2fbb789 commit 7c58520
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 33 deletions.
41 changes: 21 additions & 20 deletions NextcloudTalk/BaseChatTableViewCell+File.swift
Original file line number Diff line number Diff line change
Expand Up @@ -123,29 +123,30 @@ extension BaseChatTableViewCell {
return
}

let isVideoFile = NCUtils.isVideo(fileType: message.file().mimetype)
let isMediaFile = isVideoFile || NCUtils.isImage(fileType: message.file().mimetype)

var placeholderImage: UIImage?
var previewImageHeight: CGFloat?
var previewImageWidth: CGFloat?

// In case we can determine the height before requesting the preview, adjust the imageView constraints accordingly
if file.previewImageHeight > 0 {
if file.previewImageHeight > 0 && file.previewImageWidth > 0 {
previewImageHeight = CGFloat(file.previewImageHeight)
previewImageWidth = CGFloat(file.previewImageWidth)
} else {
let estimatedPreviewHeight = BaseChatTableViewCell.getEstimatedPreviewSize(for: message)
let estimatedPreviewSize = BaseChatTableViewCell.getEstimatedPreviewSize(for: message)

if estimatedPreviewHeight > 0 {
previewImageHeight = estimatedPreviewHeight
if estimatedPreviewSize.height > 0 && estimatedPreviewSize.width > 0 {
previewImageHeight = estimatedPreviewSize.height
previewImageWidth = estimatedPreviewSize.width
}
}

if let previewImageHeight {
if let previewImageHeight, let previewImageWidth {
self.filePreviewImageViewHeightConstraint?.constant = previewImageHeight
self.filePreviewImageViewWidthConstraint?.constant = previewImageWidth

if let blurhash = message.file()?.blurhash {
// TODO: Need to determine width as well, we currently only store the height in some cases
placeholderImage = .init(blurHash: blurhash, size: .init(width: 250, height: previewImageHeight))
if !message.isAnimatableGif, let blurhash = message.file()?.blurhash {
let aspectRatio = previewImageHeight / previewImageWidth
placeholderImage = .init(blurHash: blurhash, size: .init(width: 20, height: 20 * aspectRatio))
}
}

Expand All @@ -155,7 +156,7 @@ extension BaseChatTableViewCell {
if message.isAnimatableGif {
self.requestGifPreview(for: message, with: account)
} else {
self.requestDefaultPreview(for: message, with: account)
self.requestDefaultPreview(for: message, withPlaceholderImage: placeholderImage, with: account)
}
}

Expand All @@ -177,7 +178,7 @@ extension BaseChatTableViewCell {
let gifImage = try? UIImage(gifData: data), let baseImage = UIImage(data: data) else {

// No gif, try to request a normal preview
self.requestDefaultPreview(for: message, with: account)
self.requestDefaultPreview(for: message, withPlaceholderImage: nil, with: account)
return
}

Expand All @@ -186,7 +187,7 @@ extension BaseChatTableViewCell {
}
}

func requestDefaultPreview(for message: NCChatMessage, with account: TalkAccount) {
func requestDefaultPreview(for message: NCChatMessage, withPlaceholderImage placeholderImage: UIImage?, with account: TalkAccount) {
guard let file = message.file() else { return }

let requestedHeight = Int(3 * fileMessageCellFileMaxPreviewHeight)
Expand Down Expand Up @@ -233,7 +234,7 @@ extension BaseChatTableViewCell {
self.filePreviewPlayIconImageView?.center = CGPoint(x: previewSize.width / 2.0, y: previewSize.height / 2.0)
}

self.delegate?.cellHasDownloadedImagePreview(withHeight: ceil(previewSize.height), for: message)
self.delegate?.cellHasDownloadedImagePreview(withSize: .init(width: ceil(previewSize.width), height: ceil(previewSize.height)), for: message)
}

func showFallbackIcon(for message: NCChatMessage) {
Expand Down Expand Up @@ -299,22 +300,22 @@ extension BaseChatTableViewCell {
return CGSize(width: width, height: height)
}

static func getEstimatedPreviewSize(for message: NCChatMessage?) -> CGFloat {
guard let message, let fileParameter = message.file() else { return 0 }
static func getEstimatedPreviewSize(for message: NCChatMessage?) -> CGSize {
guard let message, let fileParameter = message.file() else { return .zero }

// We don't have any information about the image to display
if fileParameter.width == 0 && fileParameter.height == 0 {
return 0
return .zero
}

// We can only estimate the height for images and videos
if !NCUtils.isVideo(fileType: fileParameter.mimetype), !NCUtils.isImage(fileType: fileParameter.mimetype) {
return 0
return .zero
}

let imageSize = CGSize(width: CGFloat(fileParameter.width), height: CGFloat(fileParameter.height))
let previewSize = self.getPreviewSize(from: imageSize, true)

return ceil(previewSize.height)
return .init(width: ceil(previewSize.width), height: ceil(previewSize.height))
}
}
2 changes: 1 addition & 1 deletion NextcloudTalk/BaseChatTableViewCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ protocol BaseChatTableViewCellDelegate: AnyObject {
func cellDidSelectedReaction(_ reaction: NCChatReaction!, for message: NCChatMessage)

func cellWants(toDownloadFile fileParameter: NCMessageFileParameter, for message: NCChatMessage)
func cellHasDownloadedImagePreview(withHeight height: CGFloat, for message: NCChatMessage)
func cellHasDownloadedImagePreview(withSize size: CGSize, for message: NCChatMessage)

func cellWants(toOpenLocation geoLocationRichObject: GeoLocationRichObject)

Expand Down
12 changes: 6 additions & 6 deletions NextcloudTalk/BaseChatViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2900,9 +2900,9 @@ import SwiftUI
} else if let file = message.file() {
if file.previewImageHeight > 0 {
height += CGFloat(file.previewImageHeight)
} else if case let estimatedHeight = BaseChatTableViewCell.getEstimatedPreviewSize(for: message), estimatedHeight > 0 {
height += estimatedHeight
message.setPreviewImageHeight(estimatedHeight)
} else if case let estimatedSize = BaseChatTableViewCell.getEstimatedPreviewSize(for: message), estimatedSize.height > 0 {
height += estimatedSize.height
message.setPreviewImageSize(estimatedSize)
} else {
height += fileMessageCellFileMaxPreviewHeight
}
Expand Down Expand Up @@ -3374,14 +3374,14 @@ import SwiftUI
downloader.downloadFile(fromMessage: fileParameter)
}

public func cellHasDownloadedImagePreview(withHeight height: CGFloat, for message: NCChatMessage) {
if message.file().previewImageHeight == Int(height) {
public func cellHasDownloadedImagePreview(withSize size: CGSize, for message: NCChatMessage) {
if message.file().previewImageHeight == Int(size.height) {
return
}

let isAtBottom = self.shouldScrollOnNewMessages()

message.setPreviewImageHeight(height)
message.setPreviewImageSize(size)

CATransaction.begin()
CATransaction.setCompletionBlock {
Expand Down
2 changes: 1 addition & 1 deletion NextcloudTalk/NCChatMessage.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ typedef void (^GetReferenceDataCompletionBlock)(NCChatMessage *message, NSDictio
- (NSArray<NCChatReaction *> * _Nonnull)reactionsArray;
- (BOOL)containsURL;
- (void)getReferenceDataWithCompletionBlock:(GetReferenceDataCompletionBlock _Nullable)block;
- (void)setPreviewImageHeight:(CGFloat)height;
- (void)setPreviewImageSize:(CGSize)size;

// Public for swift extension
- (NSMutableArray * _Nonnull)temporaryReactions;
Expand Down
17 changes: 12 additions & 5 deletions NextcloudTalk/NCChatMessage.m
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ + (instancetype)messageWithDictionary:(NSDictionary *)messageDict andAccountId:(
+ (void)updateChatMessage:(NCChatMessage *)managedChatMessage withChatMessage:(NCChatMessage *)chatMessage isRoomLastMessage:(BOOL)isRoomLastMessage
{
int previewImageHeight = 0;
int previewImageWidth = 0;

// Try to keep our locally saved previewImageHeight when updating this messages with the server message
// This happens when updating the last message of a room for example
Expand All @@ -149,6 +150,10 @@ + (void)updateChatMessage:(NCChatMessage *)managedChatMessage withChatMessage:(N
if (managedChatMessage.file.previewImageHeight > 0 && chatMessage.file.previewImageHeight == 0) {
previewImageHeight = managedChatMessage.file.previewImageHeight;
}

if (managedChatMessage.file.previewImageWidth > 0 && chatMessage.file.previewImageWidth == 0) {
previewImageWidth = managedChatMessage.file.previewImageWidth;
}
}

managedChatMessage.actorDisplayName = chatMessage.actorDisplayName;
Expand Down Expand Up @@ -176,8 +181,8 @@ + (void)updateChatMessage:(NCChatMessage *)managedChatMessage withChatMessage:(N
managedChatMessage.parentId = chatMessage.parentId;
}

if (previewImageHeight > 0) {
[managedChatMessage setPreviewImageHeight:previewImageHeight];
if (previewImageHeight > 0 && previewImageWidth > 0) {
[managedChatMessage setPreviewImageSize:CGSizeMake(previewImageWidth, previewImageHeight)];
}
}

Expand Down Expand Up @@ -623,7 +628,7 @@ - (void)getReferenceDataWithCompletionBlock:(GetReferenceDataCompletionBlock)blo
}
}

- (void)setPreviewImageHeight:(CGFloat)height
- (void)setPreviewImageSize:(CGSize)size
{
// Since the messageParameters property is a non-mutable dictionary, we create a mutable copy
NSMutableDictionary *messageParameterDict = [[NSMutableDictionary alloc] initWithDictionary:self.messageParameters];
Expand All @@ -634,7 +639,8 @@ - (void)setPreviewImageHeight:(CGFloat)height
}

[messageParameterDict setObject:fileParameterDict forKey:@"file"];
[fileParameterDict setObject:@(height) forKey:@"preview-image-height"];
[fileParameterDict setObject:@(size.height) forKey:@"preview-image-height"];
[fileParameterDict setObject:@(size.width) forKey:@"preview-image-width"];

NSData *jsonData = [NSJSONSerialization dataWithJSONObject:messageParameterDict
options:0
Expand All @@ -648,7 +654,8 @@ - (void)setPreviewImageHeight:(CGFloat)height

// Since we previously accessed the 'file' property, it would not be created from the JSON String again
// Manually set it for the lifetime of this message
self.file.previewImageHeight = height;
self.file.previewImageHeight = size.height;
self.file.previewImageWidth = size.width;

// Save our changes to the database
RLMRealm *realm = [RLMRealm defaultRealm];
Expand Down
1 change: 1 addition & 0 deletions NextcloudTalk/NCMessageFileParameter.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, assign) BOOL previewAvailable;
@property (nonatomic, strong, nullable) NCChatFileStatus *fileStatus;
@property (nonatomic, assign) int previewImageHeight;
@property (nonatomic, assign) int previewImageWidth;
@property (nonatomic, assign) int width;
@property (nonatomic, assign) int height;
@property (nonatomic, strong, nullable) NSString *blurhash;
Expand Down
1 change: 1 addition & 0 deletions NextcloudTalk/NCMessageFileParameter.m
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ - (instancetype)initWithDictionary:(NSDictionary *)parameterDict
self.size = [[parameterDict objectForKey:@"size"] integerValue];
self.previewAvailable = [[parameterDict objectForKey:@"preview-available"] boolValue];
self.previewImageHeight = [[parameterDict objectForKey:@"preview-image-height"] intValue];
self.previewImageWidth = [[parameterDict objectForKey:@"preview-image-width"] intValue];
self.width = [[parameterDict objectForKey:@"width"] intValue];
self.height = [[parameterDict objectForKey:@"height"] intValue];
self.blurhash = [parameterDict objectForKey:@"blurhash"];
Expand Down

0 comments on commit 7c58520

Please sign in to comment.