mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 06:55:59 +00:00
Enable encryption and add support for loading encrypted images.
This commit is contained in:
@@ -7,6 +7,7 @@
|
|||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
|
1803C82027FDE17B00795848 /* MediaSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1803C81F27FDE17B00795848 /* MediaSource.swift */; };
|
||||||
181A317727F703E300B8305B /* RoomSummaryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 181A317427F703E300B8305B /* RoomSummaryProtocol.swift */; };
|
181A317727F703E300B8305B /* RoomSummaryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 181A317427F703E300B8305B /* RoomSummaryProtocol.swift */; };
|
||||||
181A317827F703E300B8305B /* RoomSummary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 181A317527F703E300B8305B /* RoomSummary.swift */; };
|
181A317827F703E300B8305B /* RoomSummary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 181A317527F703E300B8305B /* RoomSummary.swift */; };
|
||||||
181A317927F703E300B8305B /* MockRoomSummary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 181A317627F703E300B8305B /* MockRoomSummary.swift */; };
|
181A317927F703E300B8305B /* MockRoomSummary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 181A317627F703E300B8305B /* MockRoomSummary.swift */; };
|
||||||
@@ -150,6 +151,7 @@
|
|||||||
/* End PBXContainerItemProxy section */
|
/* End PBXContainerItemProxy section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
|
1803C81F27FDE17B00795848 /* MediaSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaSource.swift; sourceTree = "<group>"; };
|
||||||
181A317427F703E300B8305B /* RoomSummaryProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoomSummaryProtocol.swift; sourceTree = "<group>"; };
|
181A317427F703E300B8305B /* RoomSummaryProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoomSummaryProtocol.swift; sourceTree = "<group>"; };
|
||||||
181A317527F703E300B8305B /* RoomSummary.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoomSummary.swift; sourceTree = "<group>"; };
|
181A317527F703E300B8305B /* RoomSummary.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoomSummary.swift; sourceTree = "<group>"; };
|
||||||
181A317627F703E300B8305B /* MockRoomSummary.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockRoomSummary.swift; sourceTree = "<group>"; };
|
181A317627F703E300B8305B /* MockRoomSummary.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockRoomSummary.swift; sourceTree = "<group>"; };
|
||||||
@@ -189,7 +191,6 @@
|
|||||||
18ADC80427EB1ED100A8C953 /* UIFont+AttributedStringBuilder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIFont+AttributedStringBuilder.m"; sourceTree = "<group>"; };
|
18ADC80427EB1ED100A8C953 /* UIFont+AttributedStringBuilder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIFont+AttributedStringBuilder.m"; sourceTree = "<group>"; };
|
||||||
18ADC80527EB1ED100A8C953 /* UIFont+AttributedStringBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIFont+AttributedStringBuilder.h"; sourceTree = "<group>"; };
|
18ADC80527EB1ED100A8C953 /* UIFont+AttributedStringBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIFont+AttributedStringBuilder.h"; sourceTree = "<group>"; };
|
||||||
18ADC80727EB1EE200A8C953 /* ElementX-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ElementX-Bridging-Header.h"; sourceTree = "<group>"; };
|
18ADC80727EB1EE200A8C953 /* ElementX-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ElementX-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||||
18BB170627FB74B30074CBD6 /* matrix-rust-components-swift */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = "matrix-rust-components-swift"; path = "../matrix-rust-components-swift"; sourceTree = "<group>"; };
|
|
||||||
18BB170927FC20D20074CBD6 /* BlurHashDecode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BlurHashDecode.swift; sourceTree = "<group>"; };
|
18BB170927FC20D20074CBD6 /* BlurHashDecode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BlurHashDecode.swift; sourceTree = "<group>"; };
|
||||||
18C5744827E1D84000D70937 /* RoomProxyProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoomProxyProtocol.swift; sourceTree = "<group>"; };
|
18C5744827E1D84000D70937 /* RoomProxyProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoomProxyProtocol.swift; sourceTree = "<group>"; };
|
||||||
18C5744A27E1D84000D70937 /* RoomProxy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoomProxy.swift; sourceTree = "<group>"; };
|
18C5744A27E1D84000D70937 /* RoomProxy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoomProxy.swift; sourceTree = "<group>"; };
|
||||||
@@ -323,7 +324,6 @@
|
|||||||
1850251B27B6918C002E6B18 = {
|
1850251B27B6918C002E6B18 = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
18BB170627FB74B30074CBD6 /* matrix-rust-components-swift */,
|
|
||||||
1850252627B6918C002E6B18 /* ElementX */,
|
1850252627B6918C002E6B18 /* ElementX */,
|
||||||
1850253D27B6918D002E6B18 /* ElementXTests */,
|
1850253D27B6918D002E6B18 /* ElementXTests */,
|
||||||
1850254727B6918D002E6B18 /* ElementXUITests */,
|
1850254727B6918D002E6B18 /* ElementXUITests */,
|
||||||
@@ -460,6 +460,7 @@
|
|||||||
18DF7C3027E3608100291672 /* MediaProviderProtocol.swift */,
|
18DF7C3027E3608100291672 /* MediaProviderProtocol.swift */,
|
||||||
18DF7C2E27E264FC00291672 /* MediaProvider.swift */,
|
18DF7C2E27E264FC00291672 /* MediaProvider.swift */,
|
||||||
18DF7C3227E3608800291672 /* MockMediaProvider.swift */,
|
18DF7C3227E3608800291672 /* MockMediaProvider.swift */,
|
||||||
|
1803C81F27FDE17B00795848 /* MediaSource.swift */,
|
||||||
);
|
);
|
||||||
path = Media;
|
path = Media;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -1044,6 +1045,7 @@
|
|||||||
18F2BAFB27D25B4000DD1988 /* HomeScreenCoordinator.swift in Sources */,
|
18F2BAFB27D25B4000DD1988 /* HomeScreenCoordinator.swift in Sources */,
|
||||||
18F2BB0C27D25B4000DD1988 /* RoomScreenCoordinator.swift in Sources */,
|
18F2BB0C27D25B4000DD1988 /* RoomScreenCoordinator.swift in Sources */,
|
||||||
18DDB72127EB9D57000F1ABF /* ElementXAttributeScope.swift in Sources */,
|
18DDB72127EB9D57000F1ABF /* ElementXAttributeScope.swift in Sources */,
|
||||||
|
1803C82027FDE17B00795848 /* MediaSource.swift in Sources */,
|
||||||
18DF7C4527E4670600291672 /* SeparatorRoomTimelineItem.swift in Sources */,
|
18DF7C4527E4670600291672 /* SeparatorRoomTimelineItem.swift in Sources */,
|
||||||
18DF7C4227E4670600291672 /* RoomTimelineItemFactory.swift in Sources */,
|
18DF7C4227E4670600291672 /* RoomTimelineItemFactory.swift in Sources */,
|
||||||
18F2BB0E27D25B4000DD1988 /* RoomScreenViewModelProtocol.swift in Sources */,
|
18F2BB0E27D25B4000DD1988 /* RoomScreenViewModelProtocol.swift in Sources */,
|
||||||
|
|||||||
@@ -42,7 +42,7 @@
|
|||||||
"repositoryURL": "https://github.com/matrix-org/matrix-rust-components-swift.git",
|
"repositoryURL": "https://github.com/matrix-org/matrix-rust-components-swift.git",
|
||||||
"state": {
|
"state": {
|
||||||
"branch": "main",
|
"branch": "main",
|
||||||
"revision": "a69956b5724cc969ea47acf5eabbacdfecc712b7",
|
"revision": "f6682cf02eec087f921c53526895996cba169378",
|
||||||
"version": null
|
"version": null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ struct ImageRoomTimelineView_Previews: PreviewProvider {
|
|||||||
timestamp: "Now",
|
timestamp: "Now",
|
||||||
shouldShowSenderDetails: false,
|
shouldShowSenderDetails: false,
|
||||||
senderId: "Bob",
|
senderId: "Bob",
|
||||||
url: nil,
|
source: nil,
|
||||||
image: UIImage(systemName: "photo"))
|
image: UIImage(systemName: "photo"))
|
||||||
ImageRoomTimelineView(timelineItem: timelineItem)
|
ImageRoomTimelineView(timelineItem: timelineItem)
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ struct ImageRoomTimelineView_Previews: PreviewProvider {
|
|||||||
timestamp: "Now",
|
timestamp: "Now",
|
||||||
shouldShowSenderDetails: false,
|
shouldShowSenderDetails: false,
|
||||||
senderId: "Bob",
|
senderId: "Bob",
|
||||||
url: nil,
|
source: nil,
|
||||||
image: nil)
|
image: nil)
|
||||||
ImageRoomTimelineView(timelineItem: timelineItem)
|
ImageRoomTimelineView(timelineItem: timelineItem)
|
||||||
|
|
||||||
@@ -83,7 +83,7 @@ struct ImageRoomTimelineView_Previews: PreviewProvider {
|
|||||||
timestamp: "Now",
|
timestamp: "Now",
|
||||||
shouldShowSenderDetails: false,
|
shouldShowSenderDetails: false,
|
||||||
senderId: "Bob",
|
senderId: "Bob",
|
||||||
url: nil,
|
source: nil,
|
||||||
image: nil,
|
image: nil,
|
||||||
aspectRatio: 0.7,
|
aspectRatio: 0.7,
|
||||||
blurhash: "L%KUc%kqS$RP?Ks,WEf8OlrqaekW")
|
blurhash: "L%KUc%kqS$RP?Ks,WEf8OlrqaekW")
|
||||||
|
|||||||
@@ -21,21 +21,21 @@ struct MediaProvider: MediaProviderProtocol {
|
|||||||
self.processingQueue = DispatchQueue(label: "MediaProviderProcessingQueue", attributes: .concurrent)
|
self.processingQueue = DispatchQueue(label: "MediaProviderProcessingQueue", attributes: .concurrent)
|
||||||
}
|
}
|
||||||
|
|
||||||
func imageForURL(_ url: String?) -> UIImage? {
|
func imageFromSource(_ source: MediaSource?) -> UIImage? {
|
||||||
guard let url = url else {
|
guard let source = source else {
|
||||||
return nil
|
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) {
|
func loadImageFromSource(_ source: MediaSource, _ completion: @escaping (Result<UIImage, MediaProviderError>) -> Void) {
|
||||||
if let image = imageForURL(url) {
|
if let image = imageFromSource(source) {
|
||||||
completion(.success(image))
|
completion(.success(image))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
imageCache.retrieveImage(forKey: url) { result in
|
imageCache.retrieveImage(forKey: source.underlyingSource.url()) { result in
|
||||||
if case let .success(cacheResult) = result,
|
if case let .success(cacheResult) = result,
|
||||||
let image = cacheResult.image {
|
let image = cacheResult.image {
|
||||||
completion(.success(image))
|
completion(.success(image))
|
||||||
@@ -44,7 +44,7 @@ struct MediaProvider: MediaProviderProtocol {
|
|||||||
|
|
||||||
processingQueue.async {
|
processingQueue.async {
|
||||||
do {
|
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 {
|
guard let image = UIImage(data: Data(bytes: imageData, count: imageData.count)) else {
|
||||||
MXLog.error("Invalid image data")
|
MXLog.error("Invalid image data")
|
||||||
@@ -54,7 +54,7 @@ struct MediaProvider: MediaProviderProtocol {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
imageCache.store(image, forKey: url)
|
imageCache.store(image, forKey: source.underlyingSource.url())
|
||||||
|
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
completion(.success(image))
|
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 {
|
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)
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,8 +32,8 @@ struct ImageRoomMessage: RoomMessageProtocol {
|
|||||||
Date(timeIntervalSince1970: TimeInterval(message.baseMessage().originServerTs()))
|
Date(timeIntervalSince1970: TimeInterval(message.baseMessage().originServerTs()))
|
||||||
}
|
}
|
||||||
|
|
||||||
var url: String? {
|
var source: MediaSource? {
|
||||||
message.url()
|
MediaSource(source: message.source())
|
||||||
}
|
}
|
||||||
|
|
||||||
var width: CGFloat? {
|
var width: CGFloat? {
|
||||||
|
|||||||
@@ -125,11 +125,11 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let url = timelineItem.url else {
|
guard let source = timelineItem.source else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
mediaProvider.loadImageFromURL(url) { [weak self] result in
|
mediaProvider.loadImageFromSource(source) { [weak self] result in
|
||||||
guard let self = self else {
|
guard let self = self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ struct ImageRoomTimelineItem: EventBasedTimelineItemProtocol, Identifiable, Equa
|
|||||||
var senderDisplayName: String?
|
var senderDisplayName: String?
|
||||||
var senderAvatar: UIImage?
|
var senderAvatar: UIImage?
|
||||||
|
|
||||||
let url: String?
|
let source: MediaSource?
|
||||||
var image: UIImage?
|
var image: UIImage?
|
||||||
|
|
||||||
var width: CGFloat?
|
var width: CGFloat?
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ struct RoomTimelineItemFactory {
|
|||||||
func buildTimelineItemFor(_ roomMessage: RoomMessageProtocol, showSenderDetails: Bool) -> RoomTimelineItemProtocol {
|
func buildTimelineItemFor(_ roomMessage: RoomMessageProtocol, showSenderDetails: Bool) -> RoomTimelineItemProtocol {
|
||||||
let displayName = memberDetailProvider.displayNameForUserId(roomMessage.sender)
|
let displayName = memberDetailProvider.displayNameForUserId(roomMessage.sender)
|
||||||
let avatarURL = memberDetailProvider.avatarURLForUserId(roomMessage.sender)
|
let avatarURL = memberDetailProvider.avatarURLForUserId(roomMessage.sender)
|
||||||
let avatarImage = mediaProvider.imageForURL(avatarURL)
|
let avatarImage = mediaProvider.imageFromURL(avatarURL)
|
||||||
|
|
||||||
switch roomMessage {
|
switch roomMessage {
|
||||||
case let message as TextRoomMessage:
|
case let message as TextRoomMessage:
|
||||||
@@ -77,8 +77,8 @@ struct RoomTimelineItemFactory {
|
|||||||
senderId: message.sender,
|
senderId: message.sender,
|
||||||
senderDisplayName: displayName,
|
senderDisplayName: displayName,
|
||||||
senderAvatar: avatarImage,
|
senderAvatar: avatarImage,
|
||||||
url: message.url,
|
source: message.source,
|
||||||
image: mediaProvider.imageForURL(message.url),
|
image: mediaProvider.imageFromSource(message.source),
|
||||||
width: message.width,
|
width: message.width,
|
||||||
height: message.height,
|
height: message.height,
|
||||||
aspectRatio: aspectRatio,
|
aspectRatio: aspectRatio,
|
||||||
|
|||||||
Reference in New Issue
Block a user