mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-02 12:07:55 +00:00
Enable encryption and add support for loading encrypted images.
This commit is contained in:
@@ -65,7 +65,7 @@ struct ImageRoomTimelineView_Previews: PreviewProvider {
|
||||
timestamp: "Now",
|
||||
shouldShowSenderDetails: false,
|
||||
senderId: "Bob",
|
||||
url: nil,
|
||||
source: nil,
|
||||
image: UIImage(systemName: "photo"))
|
||||
ImageRoomTimelineView(timelineItem: timelineItem)
|
||||
|
||||
@@ -74,7 +74,7 @@ struct ImageRoomTimelineView_Previews: PreviewProvider {
|
||||
timestamp: "Now",
|
||||
shouldShowSenderDetails: false,
|
||||
senderId: "Bob",
|
||||
url: nil,
|
||||
source: nil,
|
||||
image: nil)
|
||||
ImageRoomTimelineView(timelineItem: timelineItem)
|
||||
|
||||
@@ -83,7 +83,7 @@ struct ImageRoomTimelineView_Previews: PreviewProvider {
|
||||
timestamp: "Now",
|
||||
shouldShowSenderDetails: false,
|
||||
senderId: "Bob",
|
||||
url: nil,
|
||||
source: nil,
|
||||
image: nil,
|
||||
aspectRatio: 0.7,
|
||||
blurhash: "L%KUc%kqS$RP?Ks,WEf8OlrqaekW")
|
||||
|
||||
@@ -21,21 +21,21 @@ struct MediaProvider: MediaProviderProtocol {
|
||||
self.processingQueue = DispatchQueue(label: "MediaProviderProcessingQueue", attributes: .concurrent)
|
||||
}
|
||||
|
||||
func imageForURL(_ url: String?) -> UIImage? {
|
||||
guard let url = url else {
|
||||
func imageFromSource(_ source: MediaSource?) -> UIImage? {
|
||||
guard let source = source else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return imageCache.retrieveImageInMemoryCache(forKey: url, options: nil)
|
||||
|
||||
return imageCache.retrieveImageInMemoryCache(forKey: source.underlyingSource.url(), options: nil)
|
||||
}
|
||||
|
||||
func loadImageFromURL(_ url: String, _ completion: @escaping (Result<UIImage, MediaProviderError>) -> Void) {
|
||||
if let image = imageForURL(url) {
|
||||
func loadImageFromSource(_ source: MediaSource, _ completion: @escaping (Result<UIImage, MediaProviderError>) -> Void) {
|
||||
if let image = imageFromSource(source) {
|
||||
completion(.success(image))
|
||||
return
|
||||
}
|
||||
|
||||
imageCache.retrieveImage(forKey: url) { result in
|
||||
imageCache.retrieveImage(forKey: source.underlyingSource.url()) { result in
|
||||
if case let .success(cacheResult) = result,
|
||||
let image = cacheResult.image {
|
||||
completion(.success(image))
|
||||
@@ -44,7 +44,7 @@ struct MediaProvider: MediaProviderProtocol {
|
||||
|
||||
processingQueue.async {
|
||||
do {
|
||||
let imageData = try client.loadImage(url: url)
|
||||
let imageData = try client.loadImage(source: source.underlyingSource)
|
||||
|
||||
guard let image = UIImage(data: Data(bytes: imageData, count: imageData.count)) else {
|
||||
MXLog.error("Invalid image data")
|
||||
@@ -54,7 +54,7 @@ struct MediaProvider: MediaProviderProtocol {
|
||||
return
|
||||
}
|
||||
|
||||
imageCache.store(image, forKey: url)
|
||||
imageCache.store(image, forKey: source.underlyingSource.url())
|
||||
|
||||
DispatchQueue.main.async {
|
||||
completion(.success(image))
|
||||
@@ -68,4 +68,16 @@ struct MediaProvider: MediaProviderProtocol {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func imageFromURL(_ url: String?) -> UIImage? {
|
||||
guard let url = url else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return imageFromSource(MediaSource(source: mediaSourceFromUrl(url: url)))
|
||||
}
|
||||
|
||||
func loadImageFromURL(_ url: String, _ completion: @escaping (Result<UIImage, MediaProviderError>) -> Void) {
|
||||
return loadImageFromSource(MediaSource(source: mediaSourceFromUrl(url: url)), completion)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,11 @@ enum MediaProviderError: Error {
|
||||
}
|
||||
|
||||
protocol MediaProviderProtocol {
|
||||
func imageForURL(_ url: String?) -> UIImage?
|
||||
func imageFromSource(_ source: MediaSource?) -> UIImage?
|
||||
|
||||
func loadImageFromSource(_ source: MediaSource, _ completion: @escaping (Result<UIImage, MediaProviderError>) -> Void)
|
||||
|
||||
func imageFromURL(_ url: String?) -> UIImage?
|
||||
|
||||
func loadImageFromURL(_ url: String, _ completion: @escaping (Result<UIImage, MediaProviderError>) -> Void)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// MediaSource.swift
|
||||
// ElementX
|
||||
//
|
||||
// Created by Stefan Ceriu on 06/04/2022.
|
||||
// Copyright © 2022 Element. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import MatrixRustSDK
|
||||
|
||||
struct MediaSource: Equatable {
|
||||
let underlyingSource: MatrixRustSDK.MediaSource
|
||||
|
||||
init(source: MatrixRustSDK.MediaSource) {
|
||||
self.underlyingSource = source
|
||||
}
|
||||
|
||||
init(urlString: String) {
|
||||
self.underlyingSource = mediaSourceFromUrl(url: urlString)
|
||||
}
|
||||
|
||||
// MARK: - Equatable
|
||||
|
||||
static func == (lhs: MediaSource, rhs: MediaSource) -> Bool {
|
||||
return lhs.underlyingSource.url() == rhs.underlyingSource.url()
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,15 @@ struct MockMediaProvider: MediaProviderProtocol {
|
||||
|
||||
}
|
||||
|
||||
func imageForURL(_ url: String?) -> UIImage? {
|
||||
func imageFromSource(_ source: MediaSource?) -> UIImage? {
|
||||
return nil
|
||||
}
|
||||
|
||||
func loadImageFromSource(_ source: MediaSource, _ completion: @escaping (Result<UIImage, MediaProviderError>) -> Void) {
|
||||
|
||||
}
|
||||
|
||||
func imageFromURL(_ url: String?) -> UIImage? {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -32,8 +32,8 @@ struct ImageRoomMessage: RoomMessageProtocol {
|
||||
Date(timeIntervalSince1970: TimeInterval(message.baseMessage().originServerTs()))
|
||||
}
|
||||
|
||||
var url: String? {
|
||||
message.url()
|
||||
var source: MediaSource? {
|
||||
MediaSource(source: message.source())
|
||||
}
|
||||
|
||||
var width: CGFloat? {
|
||||
|
||||
@@ -125,11 +125,11 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
|
||||
return
|
||||
}
|
||||
|
||||
guard let url = timelineItem.url else {
|
||||
guard let source = timelineItem.source else {
|
||||
return
|
||||
}
|
||||
|
||||
mediaProvider.loadImageFromURL(url) { [weak self] result in
|
||||
mediaProvider.loadImageFromSource(source) { [weak self] result in
|
||||
guard let self = self else {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ struct ImageRoomTimelineItem: EventBasedTimelineItemProtocol, Identifiable, Equa
|
||||
var senderDisplayName: String?
|
||||
var senderAvatar: UIImage?
|
||||
|
||||
let url: String?
|
||||
let source: MediaSource?
|
||||
var image: UIImage?
|
||||
|
||||
var width: CGFloat?
|
||||
|
||||
@@ -25,7 +25,7 @@ struct RoomTimelineItemFactory {
|
||||
func buildTimelineItemFor(_ roomMessage: RoomMessageProtocol, showSenderDetails: Bool) -> RoomTimelineItemProtocol {
|
||||
let displayName = memberDetailProvider.displayNameForUserId(roomMessage.sender)
|
||||
let avatarURL = memberDetailProvider.avatarURLForUserId(roomMessage.sender)
|
||||
let avatarImage = mediaProvider.imageForURL(avatarURL)
|
||||
let avatarImage = mediaProvider.imageFromURL(avatarURL)
|
||||
|
||||
switch roomMessage {
|
||||
case let message as TextRoomMessage:
|
||||
@@ -77,8 +77,8 @@ struct RoomTimelineItemFactory {
|
||||
senderId: message.sender,
|
||||
senderDisplayName: displayName,
|
||||
senderAvatar: avatarImage,
|
||||
url: message.url,
|
||||
image: mediaProvider.imageForURL(message.url),
|
||||
source: message.source,
|
||||
image: mediaProvider.imageFromSource(message.source),
|
||||
width: message.width,
|
||||
height: message.height,
|
||||
aspectRatio: aspectRatio,
|
||||
|
||||
Reference in New Issue
Block a user