Update the SDK and use media filename and caption internally. (#3375)

Doesn't render captions (other than in fallback places).
This commit is contained in:
Doug
2024-10-08 11:00:58 +01:00
committed by GitHub
parent 794d0eead1
commit 6e51969d27
42 changed files with 581 additions and 358 deletions
@@ -929,8 +929,8 @@ extension ClientProxy: MediaLoaderProtocol {
try await mediaLoader.loadMediaThumbnailForSource(source, width: width, height: height)
}
func loadMediaFileForSource(_ source: MediaSourceProxy, body: String?) async throws -> MediaFileHandleProxy {
try await mediaLoader.loadMediaFileForSource(source, body: body)
func loadMediaFileForSource(_ source: MediaSourceProxy, filename: String?) async throws -> MediaFileHandleProxy {
try await mediaLoader.loadMediaFileForSource(source, filename: filename)
}
}
@@ -34,8 +34,8 @@ actor MediaLoader: MediaLoaderProtocol {
}
}
func loadMediaFileForSource(_ source: MediaSourceProxy, body: String?) async throws -> MediaFileHandleProxy {
let result = try await client.getMediaFile(mediaSource: source.underlyingSource, body: body, mimeType: source.mimeType ?? "application/octet-stream", useCache: true, tempDir: nil)
func loadMediaFileForSource(_ source: MediaSourceProxy, filename: String?) async throws -> MediaFileHandleProxy {
let result = try await client.getMediaFile(mediaSource: source.underlyingSource, body: filename, mimeType: source.mimeType ?? "application/octet-stream", useCache: true, tempDir: nil)
return MediaFileHandleProxy(handle: result)
}
@@ -13,5 +13,5 @@ protocol MediaLoaderProtocol {
func loadMediaThumbnailForSource(_ source: MediaSourceProxy, width: UInt, height: UInt) async throws -> Data
func loadMediaFileForSource(_ source: MediaSourceProxy, body: String?) async throws -> MediaFileHandleProxy
func loadMediaFileForSource(_ source: MediaSourceProxy, filename: String?) async throws -> MediaFileHandleProxy
}
@@ -117,9 +117,9 @@ struct MediaProvider: MediaProviderProtocol {
// MARK: Files
func loadFileFromSource(_ source: MediaSourceProxy, body: String?) async -> Result<MediaFileHandleProxy, MediaProviderError> {
func loadFileFromSource(_ source: MediaSourceProxy, filename: String?) async -> Result<MediaFileHandleProxy, MediaProviderError> {
do {
let file = try await mediaLoader.loadMediaFileForSource(source, body: body)
let file = try await mediaLoader.loadMediaFileForSource(source, filename: filename)
return .success(file)
} catch {
MXLog.error("Failed retrieving file with error: \(error)")
@@ -25,7 +25,7 @@ protocol MediaProviderProtocol {
func loadThumbnailForSource(source: MediaSourceProxy, size: CGSize) async -> Result<Data, MediaProviderError>
func loadFileFromSource(_ source: MediaSourceProxy, body: String?) async -> Result<MediaFileHandleProxy, MediaProviderError>
func loadFileFromSource(_ source: MediaSourceProxy, filename: String?) async -> Result<MediaFileHandleProxy, MediaProviderError>
}
extension MediaProviderProtocol {
@@ -38,6 +38,6 @@ extension MediaProviderProtocol {
}
func loadFileFromSource(_ source: MediaSourceProxy) async -> Result<MediaFileHandleProxy, MediaProviderError> {
await loadFileFromSource(source, body: nil)
await loadFileFromSource(source, filename: nil)
}
}
@@ -257,7 +257,7 @@ enum RoomTimelineItemFixtures {
canBeRepliedTo: true,
isThreaded: false,
sender: .init(id: ""),
content: .init(body: "video",
content: .init(filename: "video.mp4",
duration: 100,
source: .init(url: .picturesDirectory, mimeType: nil),
thumbnailSource: .init(url: .picturesDirectory, mimeType: nil),
@@ -272,7 +272,7 @@ enum RoomTimelineItemFixtures {
canBeRepliedTo: true,
isThreaded: false,
sender: .init(id: ""),
content: .init(body: "image",
content: .init(filename: "image.jpg",
source: .init(url: .picturesDirectory, mimeType: nil),
thumbnailSource: nil,
width: 5120,
@@ -23,7 +23,7 @@ struct AudioRoomTimelineItem: EventBasedMessageTimelineItemProtocol, Equatable {
var properties = RoomTimelineItemProperties()
var body: String {
content.body
content.caption ?? content.filename
}
var contentType: EventBasedMessageTimelineItemContentType {
@@ -9,7 +9,11 @@ import UIKit
import UniformTypeIdentifiers
struct AudioRoomTimelineItemContent: Hashable {
let body: String
let filename: String
var caption: String?
var formattedCaption: AttributedString?
/// The original textual representation of the formatted caption directly from the event (usually HTML code)
var formattedCaptionHTMLString: String?
let duration: TimeInterval
let waveform: EstimatedWaveform?
let source: MediaSourceProxy?
@@ -26,7 +26,7 @@ struct FileRoomTimelineItem: EventBasedMessageTimelineItemProtocol, Equatable {
var properties = RoomTimelineItemProperties()
var body: String {
content.body
content.caption ?? content.filename
}
var contentType: EventBasedMessageTimelineItemContentType {
@@ -9,7 +9,11 @@ import Foundation
import UniformTypeIdentifiers
struct FileRoomTimelineItemContent: Hashable {
let body: String
let filename: String
var caption: String?
var formattedCaption: AttributedString?
/// The original textual representation of the formatted caption directly from the event (usually HTML code)
var formattedCaptionHTMLString: String?
let source: MediaSourceProxy?
let thumbnailSource: MediaSourceProxy?
let contentType: UTType?
@@ -25,7 +25,7 @@ struct ImageRoomTimelineItem: EventBasedMessageTimelineItemProtocol, Equatable {
var properties = RoomTimelineItemProperties()
var body: String {
content.body
content.caption ?? content.filename
}
var contentType: EventBasedMessageTimelineItemContentType {
@@ -9,7 +9,11 @@ import Foundation
import UniformTypeIdentifiers
struct ImageRoomTimelineItemContent: Hashable {
let body: String
let filename: String
var caption: String?
var formattedCaption: AttributedString?
/// The original textual representation of the formatted caption directly from the event (usually HTML code)
var formattedCaptionHTMLString: String?
let source: MediaSourceProxy
let thumbnailSource: MediaSourceProxy?
var width: CGFloat?
@@ -25,7 +25,7 @@ struct VideoRoomTimelineItem: EventBasedMessageTimelineItemProtocol, Equatable {
var properties = RoomTimelineItemProperties()
var body: String {
content.body
content.caption ?? content.filename
}
var contentType: EventBasedMessageTimelineItemContentType {
@@ -9,7 +9,11 @@ import Foundation
import UniformTypeIdentifiers
struct VideoRoomTimelineItemContent: Hashable {
let body: String
let filename: String
var caption: String?
var formattedCaption: AttributedString?
/// The original textual representation of the formatted caption directly from the event (usually HTML code)
var formattedCaptionHTMLString: String?
let duration: TimeInterval
let source: MediaSourceProxy?
let thumbnailSource: MediaSourceProxy?
@@ -23,7 +23,7 @@ struct VoiceMessageRoomTimelineItem: EventBasedMessageTimelineItemProtocol, Equa
var properties = RoomTimelineItemProperties()
var body: String {
content.body
content.caption ?? content.filename
}
var contentType: EventBasedMessageTimelineItemContentType {
@@ -63,7 +63,7 @@ struct VoiceMessageRoomTimelineView_Previews: PreviewProvider, TestablePreview {
canBeRepliedTo: true,
isThreaded: false,
sender: .init(id: "Bob"),
content: .init(body: "audio.ogg",
content: .init(filename: "audio.ogg",
duration: 300,
waveform: EstimatedWaveform.mockWaveform,
source: nil,
@@ -490,12 +490,18 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
}
private func buildAudioTimelineItemContent(_ messageContent: AudioMessageContent) -> AudioRoomTimelineItemContent {
let htmlCaption = messageContent.formattedCaption?.format == .html ? messageContent.formattedCaption?.body : nil
let formattedCaption = htmlCaption != nil ? attributedStringBuilder.fromHTML(htmlCaption) : attributedStringBuilder.fromPlain(messageContent.caption)
var waveform: EstimatedWaveform?
if let audioWaveform = messageContent.audio?.waveform {
waveform = EstimatedWaveform(data: audioWaveform)
}
return AudioRoomTimelineItemContent(body: messageContent.body,
return AudioRoomTimelineItemContent(filename: messageContent.filename,
caption: messageContent.caption,
formattedCaption: formattedCaption,
formattedCaptionHTMLString: htmlCaption,
duration: messageContent.audio?.duration ?? 0,
waveform: waveform,
source: MediaSourceProxy(source: messageContent.source, mimeType: messageContent.info?.mimetype),
@@ -503,6 +509,9 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
}
private func buildImageTimelineItemContent(_ messageContent: ImageMessageContent) -> ImageRoomTimelineItemContent {
let htmlCaption = messageContent.formattedCaption?.format == .html ? messageContent.formattedCaption?.body : nil
let formattedCaption = htmlCaption != nil ? attributedStringBuilder.fromHTML(htmlCaption) : attributedStringBuilder.fromPlain(messageContent.caption)
let thumbnailSource = messageContent.info?.thumbnailSource.map { MediaSourceProxy(source: $0, mimeType: messageContent.info?.thumbnailInfo?.mimetype) }
let width = messageContent.info?.width.map(CGFloat.init)
let height = messageContent.info?.height.map(CGFloat.init)
@@ -512,7 +521,10 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
aspectRatio = width / height
}
return .init(body: messageContent.body,
return .init(filename: messageContent.filename,
caption: messageContent.caption,
formattedCaption: formattedCaption,
formattedCaptionHTMLString: htmlCaption,
source: MediaSourceProxy(source: messageContent.source, mimeType: messageContent.info?.mimetype),
thumbnailSource: thumbnailSource,
width: width,
@@ -523,6 +535,9 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
}
private func buildVideoTimelineItemContent(_ messageContent: VideoMessageContent) -> VideoRoomTimelineItemContent {
let htmlCaption = messageContent.formattedCaption?.format == .html ? messageContent.formattedCaption?.body : nil
let formattedCaption = htmlCaption != nil ? attributedStringBuilder.fromHTML(htmlCaption) : attributedStringBuilder.fromPlain(messageContent.caption)
let thumbnailSource = messageContent.info?.thumbnailSource.map { MediaSourceProxy(source: $0, mimeType: messageContent.info?.thumbnailInfo?.mimetype) }
let width = messageContent.info?.width.map(CGFloat.init)
let height = messageContent.info?.height.map(CGFloat.init)
@@ -532,7 +547,10 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
aspectRatio = width / height
}
return .init(body: messageContent.body,
return .init(filename: messageContent.filename,
caption: messageContent.caption,
formattedCaption: formattedCaption,
formattedCaptionHTMLString: htmlCaption,
duration: messageContent.info?.duration ?? 0,
source: MediaSourceProxy(source: messageContent.source, mimeType: messageContent.info?.mimetype),
thumbnailSource: thumbnailSource,
@@ -550,9 +568,15 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
}
private func buildFileTimelineItemContent(_ messageContent: FileMessageContent) -> FileRoomTimelineItemContent {
let htmlCaption = messageContent.formattedCaption?.format == .html ? messageContent.formattedCaption?.body : nil
let formattedCaption = htmlCaption != nil ? attributedStringBuilder.fromHTML(htmlCaption) : attributedStringBuilder.fromPlain(messageContent.caption)
let thumbnailSource = messageContent.info?.thumbnailSource.map { MediaSourceProxy(source: $0, mimeType: messageContent.info?.thumbnailInfo?.mimetype) }
return .init(body: messageContent.body,
return .init(filename: messageContent.filename,
caption: messageContent.caption,
formattedCaption: formattedCaption,
formattedCaptionHTMLString: htmlCaption,
source: MediaSourceProxy(source: messageContent.source, mimeType: messageContent.info?.mimetype),
thumbnailSource: thumbnailSource,
contentType: UTType(mimeType: messageContent.info?.mimetype, fallbackFilename: messageContent.body))
@@ -51,7 +51,7 @@ class VoiceMessageMediaManager: VoiceMessageMediaManagerProtocol {
}
// Otherwise, load the file from source
guard case .success(let fileHandle) = await mediaProvider.loadFileFromSource(source, body: body) else {
guard case .success(let fileHandle) = await mediaProvider.loadFileFromSource(source, filename: body) else {
throw MediaProviderError.failedRetrievingFile
}