227 lines
7.9 KiB
Objective-C
227 lines
7.9 KiB
Objective-C
/*
|
|
Copyright 2018-2024 New Vector Ltd.
|
|
Copyright 2017 Vector Creations Ltd
|
|
Copyright 2015 OpenMarket Ltd
|
|
|
|
SPDX-License-Identifier: AGPL-3.0-only
|
|
Please see LICENSE in the repository root for full details.
|
|
*/
|
|
|
|
#import "MXKContactField.h"
|
|
|
|
@import MatrixSDK.MXMediaManager;
|
|
|
|
#import "MXKContactManager.h"
|
|
|
|
@interface MXKContactField()
|
|
{
|
|
// Tell whether we already check the contact avatar definition.
|
|
BOOL shouldCheckAvatarURL;
|
|
// The media manager of the session used to retrieve the contect avatar url
|
|
// This manager is used to download this avatar if need
|
|
MXMediaManager *mediaManager;
|
|
// The current download id
|
|
NSString *downloadId;
|
|
}
|
|
@end
|
|
|
|
@implementation MXKContactField
|
|
|
|
- (void)initFields
|
|
{
|
|
// init members
|
|
_contactID = nil;
|
|
_matrixID = nil;
|
|
|
|
[self resetMatrixAvatar];
|
|
}
|
|
|
|
- (id)initWithContactID:(NSString*)contactID matrixID:(NSString*)matrixID
|
|
{
|
|
self = [super init];
|
|
|
|
if (self)
|
|
{
|
|
[self initFields];
|
|
_contactID = contactID;
|
|
_matrixID = matrixID;
|
|
}
|
|
|
|
return self;
|
|
}
|
|
|
|
- (void)resetMatrixAvatar
|
|
{
|
|
_avatarImage = nil;
|
|
_matrixAvatarURL = nil;
|
|
shouldCheckAvatarURL = YES;
|
|
mediaManager = nil;
|
|
downloadId = nil;
|
|
}
|
|
|
|
- (void)loadAvatarWithSize:(CGSize)avatarSize
|
|
{
|
|
// Check whether the avatar image is already set
|
|
if (_avatarImage)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Sanity check
|
|
if (_matrixID)
|
|
{
|
|
if (shouldCheckAvatarURL)
|
|
{
|
|
// Consider here all sessions reported into contact manager
|
|
NSArray* mxSessions = [MXKContactManager sharedManager].mxSessions;
|
|
|
|
if (mxSessions.count)
|
|
{
|
|
// Check whether a matrix user is already known
|
|
MXUser* user;
|
|
MXSession *mxSession;
|
|
|
|
for (mxSession in mxSessions)
|
|
{
|
|
user = [mxSession userWithUserId:_matrixID];
|
|
if (user)
|
|
{
|
|
_matrixAvatarURL = user.avatarUrl;
|
|
if (_matrixAvatarURL)
|
|
{
|
|
shouldCheckAvatarURL = NO;
|
|
mediaManager = mxSession.mediaManager;
|
|
[self downloadAvatarImage:avatarSize];
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Trigger a server request if this url has not been found.
|
|
if (shouldCheckAvatarURL)
|
|
{
|
|
MXWeakify(self);
|
|
[mxSession.matrixRestClient avatarUrlForUser:_matrixID
|
|
success:^(NSString *mxAvatarUrl) {
|
|
|
|
MXStrongifyAndReturnIfNil(self);
|
|
self.matrixAvatarURL = mxAvatarUrl;
|
|
self->shouldCheckAvatarURL = NO;
|
|
self->mediaManager = mxSession.mediaManager;
|
|
[self downloadAvatarImage:avatarSize];
|
|
|
|
} failure:nil];
|
|
}
|
|
}
|
|
}
|
|
else if (_matrixAvatarURL)
|
|
{
|
|
[self downloadAvatarImage:avatarSize];
|
|
}
|
|
// Do nothing if the avatar url has been checked, and it is null.
|
|
}
|
|
}
|
|
|
|
- (void)downloadAvatarImage:(CGSize)avatarSize
|
|
{
|
|
// the avatar image is already done
|
|
if (_avatarImage)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (_matrixAvatarURL)
|
|
{
|
|
NSString *cacheFilePath = [MXMediaManager thumbnailCachePathForMatrixContentURI:_matrixAvatarURL
|
|
andType:nil
|
|
inFolder:kMXMediaManagerAvatarThumbnailFolder
|
|
toFitViewSize:avatarSize
|
|
withMethod:MXThumbnailingMethodCrop];
|
|
_avatarImage = [MXMediaManager loadPictureFromFilePath:cacheFilePath];
|
|
|
|
// the image is already in the cache
|
|
if (_avatarImage)
|
|
{
|
|
MXWeakify(self);
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
MXStrongifyAndReturnIfNil(self);
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKContactThumbnailUpdateNotification object:self.contactID userInfo:nil];
|
|
});
|
|
}
|
|
else
|
|
{
|
|
NSString *downloadId = [MXMediaManager thumbnailDownloadIdForMatrixContentURI:_matrixAvatarURL inFolder:kMXMediaManagerAvatarThumbnailFolder toFitViewSize:avatarSize withMethod:MXThumbnailingMethodCrop];
|
|
MXMediaLoader* loader = [MXMediaManager existingDownloaderWithIdentifier:downloadId];
|
|
[[NSNotificationCenter defaultCenter] removeObserver:self name:kMXMediaLoaderStateDidChangeNotification object:nil];
|
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMediaDownloadEnd:) name:kMXMediaLoaderStateDidChangeNotification object:loader];
|
|
if (!loader && mediaManager)
|
|
{
|
|
[mediaManager downloadThumbnailFromMatrixContentURI:_matrixAvatarURL
|
|
withType:nil
|
|
inFolder:kMXMediaManagerAvatarThumbnailFolder
|
|
toFitViewSize:avatarSize
|
|
withMethod:MXThumbnailingMethodCrop
|
|
success:nil
|
|
failure:nil];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
- (void)onMediaDownloadEnd:(NSNotification *)notif
|
|
{
|
|
MXMediaLoader *loader = (MXMediaLoader*)notif.object;
|
|
if ([loader.downloadId isEqualToString:downloadId])
|
|
{
|
|
// update the image
|
|
switch (loader.state) {
|
|
case MXMediaLoaderStateDownloadCompleted:
|
|
{
|
|
UIImage *image = [MXMediaManager loadPictureFromFilePath:loader.downloadOutputFilePath];
|
|
if (image)
|
|
{
|
|
_avatarImage = image;
|
|
|
|
MXWeakify(self);
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
MXStrongifyAndReturnIfNil(self);
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKContactThumbnailUpdateNotification object:self.contactID userInfo:nil];
|
|
});
|
|
}
|
|
[[NSNotificationCenter defaultCenter] removeObserver:self name:kMXMediaLoaderStateDidChangeNotification object:nil];
|
|
downloadId = nil;
|
|
break;
|
|
}
|
|
case MXMediaLoaderStateDownloadFailed:
|
|
case MXMediaLoaderStateCancelled:
|
|
[[NSNotificationCenter defaultCenter] removeObserver:self name:kMXMediaLoaderStateDidChangeNotification object:nil];
|
|
downloadId = nil;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
#pragma mark NSCoding
|
|
|
|
- (id)initWithCoder:(NSCoder *)coder
|
|
{
|
|
if (self)
|
|
{
|
|
[self initFields];
|
|
_contactID = [coder decodeObjectForKey:@"contactID"];
|
|
_matrixID = [coder decodeObjectForKey:@"matrixID"];
|
|
}
|
|
|
|
return self;
|
|
}
|
|
|
|
- (void)encodeWithCoder:(NSCoder *)coder
|
|
{
|
|
[coder encodeObject:_contactID forKey:@"contactID"];
|
|
[coder encodeObject:_matrixID forKey:@"matrixID"];
|
|
}
|
|
|
|
@end
|