mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 16:10:20 +00:00
Group image and video metadata in specialised structs (#3518)
This commit is contained in:
@@ -553,11 +553,11 @@ class TimelineInteractionHandler {
|
||||
|
||||
switch timelineItem {
|
||||
case let item as ImageRoomTimelineItem:
|
||||
source = item.content.source
|
||||
source = item.content.imageInfo.source
|
||||
filename = item.content.filename
|
||||
caption = item.content.caption
|
||||
case let item as VideoRoomTimelineItem:
|
||||
source = item.content.source
|
||||
source = item.content.videoInfo.source
|
||||
filename = item.content.filename
|
||||
caption = item.content.caption
|
||||
case let item as FileRoomTimelineItem:
|
||||
|
||||
@@ -42,7 +42,7 @@ struct TimelineReplyView: View {
|
||||
ReplyView(sender: sender,
|
||||
plainBody: content.caption ?? content.filename,
|
||||
formattedBody: content.formattedCaption,
|
||||
icon: .init(kind: .mediaSource(content.thumbnailSource ?? content.source), cornerRadii: iconCornerRadii))
|
||||
icon: .init(kind: .mediaSource(content.thumbnailInfo?.source ?? content.imageInfo.source), cornerRadii: iconCornerRadii))
|
||||
case .notice(let content):
|
||||
ReplyView(sender: sender,
|
||||
plainBody: content.body,
|
||||
@@ -55,7 +55,7 @@ struct TimelineReplyView: View {
|
||||
ReplyView(sender: sender,
|
||||
plainBody: content.caption ?? content.filename,
|
||||
formattedBody: content.formattedCaption,
|
||||
icon: content.thumbnailSource.map { .init(kind: .mediaSource($0), cornerRadii: iconCornerRadii) })
|
||||
icon: content.thumbnailInfo.map { .init(kind: .mediaSource($0.source), cornerRadii: iconCornerRadii) })
|
||||
case .voice:
|
||||
ReplyView(sender: sender,
|
||||
plainBody: L10n.commonVoiceMessage,
|
||||
@@ -222,9 +222,7 @@ struct TimelineReplyView_Previews: PreviewProvider, TestablePreview {
|
||||
}()
|
||||
|
||||
static var previewItems: [TimelineReplyView] {
|
||||
let imageSource = MediaSourceProxy(url: "https://mock.com", mimeType: "image/png")
|
||||
|
||||
return [
|
||||
[
|
||||
TimelineReplyView(placement: .timeline, timelineItemReplyDetails: .notLoaded(eventID: "")),
|
||||
|
||||
TimelineReplyView(placement: .timeline, timelineItemReplyDetails: .loading(eventID: "")),
|
||||
@@ -268,17 +266,16 @@ struct TimelineReplyView_Previews: PreviewProvider, TestablePreview {
|
||||
eventID: "123",
|
||||
eventContent: .message(.image(.init(filename: "image.jpg",
|
||||
caption: "Some image",
|
||||
source: imageSource,
|
||||
thumbnailSource: imageSource))))),
|
||||
imageInfo: .mockImage,
|
||||
thumbnailInfo: .mockThumbnail))))),
|
||||
|
||||
TimelineReplyView(placement: .timeline,
|
||||
timelineItemReplyDetails: .loaded(sender: .init(id: "", displayName: "Alice"),
|
||||
eventID: "123",
|
||||
eventContent: .message(.video(.init(filename: "video.mp4",
|
||||
caption: "Some video",
|
||||
duration: 0,
|
||||
source: nil,
|
||||
thumbnailSource: imageSource))))),
|
||||
videoInfo: .mockVideo,
|
||||
thumbnailInfo: .mockThumbnail))))),
|
||||
TimelineReplyView(placement: .timeline,
|
||||
timelineItemReplyDetails: .loaded(sender: .init(id: "", displayName: "Alice"),
|
||||
eventID: "123",
|
||||
@@ -321,7 +318,7 @@ struct TimelineReplyView_Previews: PreviewProvider, TestablePreview {
|
||||
}
|
||||
.padding()
|
||||
.environmentObject(viewModel.context)
|
||||
// Allow member names to load. Reduce precission as the `imageSource` randomly renders slightly differently
|
||||
// Allow member names to load. Reduce precission as the `mockThumbnail` randomly renders slightly differently
|
||||
.snapshotPreferences(delay: 0.2, precision: 0.98)
|
||||
.previewLayout(.sizeThatFits)
|
||||
}
|
||||
|
||||
@@ -498,8 +498,8 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview
|
||||
isThreaded: false,
|
||||
sender: .init(id: "Bob"),
|
||||
content: .init(filename: "other.png",
|
||||
source: MediaSourceProxy(url: .picturesDirectory, mimeType: "image/png"),
|
||||
thumbnailSource: nil),
|
||||
imageInfo: .mockImage,
|
||||
thumbnailInfo: nil),
|
||||
|
||||
properties: RoomTimelineItemProperties(encryptionAuthenticity: .notGuaranteed(color: .gray))))
|
||||
|
||||
@@ -577,8 +577,8 @@ private struct MockTimelineContent: View {
|
||||
isThreaded: isThreaded,
|
||||
sender: .init(id: ""),
|
||||
content: .init(filename: "image.jpg",
|
||||
source: MediaSourceProxy(url: .picturesDirectory, mimeType: "image/png"),
|
||||
thumbnailSource: nil),
|
||||
imageInfo: .mockImage,
|
||||
thumbnailInfo: nil),
|
||||
replyDetails: replyDetails))
|
||||
|
||||
LocationRoomTimelineView(timelineItem: .init(id: makeItemIdentifier(),
|
||||
|
||||
+14
-19
@@ -40,25 +40,23 @@ struct ImageRoomTimelineView: View {
|
||||
@ViewBuilder
|
||||
private var loadableImage: some View {
|
||||
if timelineItem.content.contentType == .gif {
|
||||
LoadableImage(mediaSource: timelineItem.content.source,
|
||||
LoadableImage(mediaSource: timelineItem.content.imageInfo.source,
|
||||
mediaType: .timelineItem,
|
||||
blurhash: timelineItem.content.blurhash,
|
||||
size: timelineItem.content.size,
|
||||
size: timelineItem.content.imageInfo.size,
|
||||
mediaProvider: context.mediaProvider) {
|
||||
placeholder
|
||||
}
|
||||
.timelineMediaFrame(height: timelineItem.content.thumbnailSize?.height,
|
||||
aspectRatio: timelineItem.content.aspectRatio)
|
||||
.timelineMediaFrame(imageInfo: timelineItem.content.imageInfo)
|
||||
} else {
|
||||
LoadableImage(mediaSource: timelineItem.content.thumbnailSource ?? timelineItem.content.source,
|
||||
LoadableImage(mediaSource: timelineItem.content.thumbnailInfo?.source ?? timelineItem.content.imageInfo.source,
|
||||
mediaType: .timelineItem,
|
||||
blurhash: timelineItem.content.blurhash,
|
||||
size: timelineItem.content.thumbnailSize ?? timelineItem.content.size,
|
||||
size: timelineItem.content.thumbnailInfo?.size ?? timelineItem.content.imageInfo.size,
|
||||
mediaProvider: context.mediaProvider) {
|
||||
placeholder
|
||||
}
|
||||
.timelineMediaFrame(height: timelineItem.content.thumbnailSize?.height ?? timelineItem.content.size?.height,
|
||||
aspectRatio: timelineItem.content.thumbnailAspectRatio ?? timelineItem.content.aspectRatio)
|
||||
.timelineMediaFrame(imageInfo: timelineItem.content.thumbnailInfo ?? timelineItem.content.imageInfo)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,8 +85,8 @@ struct ImageRoomTimelineView_Previews: PreviewProvider, TestablePreview {
|
||||
isThreaded: false,
|
||||
sender: .init(id: "Bob"),
|
||||
content: .init(filename: "image.jpg",
|
||||
source: MediaSourceProxy(url: .picturesDirectory, mimeType: "image/jpg"),
|
||||
thumbnailSource: nil)))
|
||||
imageInfo: .mockImage,
|
||||
thumbnailInfo: nil)))
|
||||
|
||||
ImageRoomTimelineView(timelineItem: ImageRoomTimelineItem(id: .randomEvent,
|
||||
timestamp: "Now",
|
||||
@@ -98,8 +96,8 @@ struct ImageRoomTimelineView_Previews: PreviewProvider, TestablePreview {
|
||||
isThreaded: false,
|
||||
sender: .init(id: "Bob"),
|
||||
content: .init(filename: "other.png",
|
||||
source: MediaSourceProxy(url: .picturesDirectory, mimeType: "image/png"),
|
||||
thumbnailSource: nil)))
|
||||
imageInfo: .mockImage,
|
||||
thumbnailInfo: nil)))
|
||||
|
||||
ImageRoomTimelineView(timelineItem: ImageRoomTimelineItem(id: .randomEvent,
|
||||
timestamp: "Now",
|
||||
@@ -109,9 +107,8 @@ struct ImageRoomTimelineView_Previews: PreviewProvider, TestablePreview {
|
||||
isThreaded: false,
|
||||
sender: .init(id: "Bob"),
|
||||
content: .init(filename: "Blurhashed.jpg",
|
||||
source: MediaSourceProxy(url: .picturesDirectory, mimeType: "image/gif"),
|
||||
aspectRatio: 0.7,
|
||||
thumbnailSource: nil,
|
||||
imageInfo: .mockImage,
|
||||
thumbnailInfo: nil,
|
||||
blurhash: "L%KUc%kqS$RP?Ks,WEf8OlrqaekW",
|
||||
contentType: .gif)))
|
||||
|
||||
@@ -124,10 +121,8 @@ struct ImageRoomTimelineView_Previews: PreviewProvider, TestablePreview {
|
||||
sender: .init(id: "Bob"),
|
||||
content: .init(filename: "Blurhashed.jpg",
|
||||
caption: "This is a great image 😎",
|
||||
source: MediaSourceProxy(url: .picturesDirectory, mimeType: "image/png"),
|
||||
size: .init(width: 50, height: 50),
|
||||
aspectRatio: 1,
|
||||
thumbnailSource: nil,
|
||||
imageInfo: .mockImage,
|
||||
thumbnailInfo: .mockThumbnail,
|
||||
blurhash: "L%KUc%kqS$RP?Ks,WEf8OlrqaekW",
|
||||
contentType: .gif)))
|
||||
}
|
||||
|
||||
+6
-8
@@ -14,15 +14,14 @@ struct StickerRoomTimelineView: View {
|
||||
|
||||
var body: some View {
|
||||
TimelineStyler(timelineItem: timelineItem) {
|
||||
LoadableImage(url: timelineItem.imageURL,
|
||||
LoadableImage(mediaSource: timelineItem.imageInfo.source,
|
||||
mediaType: .timelineItem,
|
||||
blurhash: timelineItem.blurhash,
|
||||
size: timelineItem.size,
|
||||
size: timelineItem.imageInfo.size,
|
||||
mediaProvider: context.mediaProvider) {
|
||||
placeholder
|
||||
}
|
||||
.timelineMediaFrame(height: timelineItem.size?.height,
|
||||
aspectRatio: timelineItem.aspectRatio)
|
||||
.timelineMediaFrame(imageInfo: timelineItem.imageInfo)
|
||||
.accessibilityElement(children: .ignore)
|
||||
.accessibilityLabel("\(L10n.commonSticker), \(timelineItem.body)")
|
||||
}
|
||||
@@ -51,7 +50,7 @@ struct StickerRoomTimelineView_Previews: PreviewProvider, TestablePreview {
|
||||
isEditable: false,
|
||||
canBeRepliedTo: true,
|
||||
sender: .init(id: "Bob"),
|
||||
imageURL: URL.picturesDirectory))
|
||||
imageInfo: .mockImage))
|
||||
|
||||
StickerRoomTimelineView(timelineItem: StickerRoomTimelineItem(id: .randomEvent,
|
||||
body: "Some other image",
|
||||
@@ -60,7 +59,7 @@ struct StickerRoomTimelineView_Previews: PreviewProvider, TestablePreview {
|
||||
isEditable: false,
|
||||
canBeRepliedTo: true,
|
||||
sender: .init(id: "Bob"),
|
||||
imageURL: URL.picturesDirectory))
|
||||
imageInfo: .mockImage))
|
||||
|
||||
StickerRoomTimelineView(timelineItem: StickerRoomTimelineItem(id: .randomEvent,
|
||||
body: "Blurhashed image",
|
||||
@@ -69,8 +68,7 @@ struct StickerRoomTimelineView_Previews: PreviewProvider, TestablePreview {
|
||||
isEditable: false,
|
||||
canBeRepliedTo: true,
|
||||
sender: .init(id: "Bob"),
|
||||
imageURL: URL.picturesDirectory,
|
||||
aspectRatio: 0.7,
|
||||
imageInfo: .mockImage,
|
||||
blurhash: "L%KUc%kqS$RP?Ks,WEf8OlrqaekW"))
|
||||
}
|
||||
}
|
||||
|
||||
+11
-17
@@ -18,8 +18,7 @@ struct VideoRoomTimelineView: View {
|
||||
TimelineStyler(timelineItem: timelineItem) {
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
thumbnail
|
||||
.timelineMediaFrame(height: timelineItem.content.thumbnailSize?.height,
|
||||
aspectRatio: timelineItem.content.aspectRatio)
|
||||
.timelineMediaFrame(imageInfo: timelineItem.content.thumbnailInfo)
|
||||
.accessibilityElement(children: .ignore)
|
||||
.accessibilityLabel(L10n.commonVideo)
|
||||
// This clip shape is distinct from the one in the styler as that one
|
||||
@@ -41,11 +40,11 @@ struct VideoRoomTimelineView: View {
|
||||
|
||||
@ViewBuilder
|
||||
var thumbnail: some View {
|
||||
if let thumbnailSource = timelineItem.content.thumbnailSource {
|
||||
if let thumbnailSource = timelineItem.content.thumbnailInfo?.source {
|
||||
LoadableImage(mediaSource: thumbnailSource,
|
||||
mediaType: .timelineItem,
|
||||
blurhash: timelineItem.content.blurhash,
|
||||
size: timelineItem.content.thumbnailSize,
|
||||
size: timelineItem.content.thumbnailInfo?.size,
|
||||
mediaProvider: context.mediaProvider) { imageView in
|
||||
imageView
|
||||
.overlay { playIcon }
|
||||
@@ -89,9 +88,8 @@ struct VideoRoomTimelineView_Previews: PreviewProvider, TestablePreview {
|
||||
isThreaded: false,
|
||||
sender: .init(id: "Bob"),
|
||||
content: .init(filename: "video.mp4",
|
||||
duration: 21,
|
||||
source: nil,
|
||||
thumbnailSource: nil)))
|
||||
videoInfo: .mockVideo,
|
||||
thumbnailInfo: nil)))
|
||||
|
||||
VideoRoomTimelineView(timelineItem: VideoRoomTimelineItem(id: .randomEvent,
|
||||
timestamp: "Now",
|
||||
@@ -101,9 +99,8 @@ struct VideoRoomTimelineView_Previews: PreviewProvider, TestablePreview {
|
||||
isThreaded: false,
|
||||
sender: .init(id: "Bob"),
|
||||
content: .init(filename: "other.mp4",
|
||||
duration: 22,
|
||||
source: nil,
|
||||
thumbnailSource: nil)))
|
||||
videoInfo: .mockVideo,
|
||||
thumbnailInfo: nil)))
|
||||
|
||||
VideoRoomTimelineView(timelineItem: VideoRoomTimelineItem(id: .randomEvent,
|
||||
timestamp: "Now",
|
||||
@@ -113,10 +110,8 @@ struct VideoRoomTimelineView_Previews: PreviewProvider, TestablePreview {
|
||||
isThreaded: false,
|
||||
sender: .init(id: "Bob"),
|
||||
content: .init(filename: "Blurhashed.mp4",
|
||||
duration: 23,
|
||||
source: nil,
|
||||
aspectRatio: 0.7,
|
||||
thumbnailSource: nil,
|
||||
videoInfo: .mockVideo,
|
||||
thumbnailInfo: nil,
|
||||
blurhash: "L%KUc%kqS$RP?Ks,WEf8OlrqaekW")))
|
||||
|
||||
VideoRoomTimelineView(timelineItem: VideoRoomTimelineItem(id: .randomEvent,
|
||||
@@ -128,9 +123,8 @@ struct VideoRoomTimelineView_Previews: PreviewProvider, TestablePreview {
|
||||
sender: .init(id: "Bob"),
|
||||
content: .init(filename: "video.mp4",
|
||||
caption: "This is a caption",
|
||||
duration: 21,
|
||||
source: nil,
|
||||
thumbnailSource: nil)))
|
||||
videoInfo: .mockVideo,
|
||||
thumbnailInfo: nil)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user