diff --git a/ElementX/Resources/Localizations/en.lproj/Localizable.strings b/ElementX/Resources/Localizations/en.lproj/Localizable.strings index 85fac299a..f81ac7c6d 100644 --- a/ElementX/Resources/Localizations/en.lproj/Localizable.strings +++ b/ElementX/Resources/Localizations/en.lproj/Localizable.strings @@ -36,8 +36,10 @@ "action_confirm_password" = "Confirm password"; "action_continue" = "Continue"; "action_copy" = "Copy"; +"action_copy_caption" = "Copy caption"; "action_copy_link" = "Copy link"; "action_copy_link_to_message" = "Copy link to message"; +"action_copy_text" = "Copy text"; "action_create" = "Create"; "action_create_a_room" = "Create a room"; "action_deactivate" = "Deactivate"; @@ -84,6 +86,7 @@ "action_reject" = "Reject"; "action_remove" = "Remove"; "action_remove_caption" = "Remove caption"; +"action_remove_message" = "Remove message"; "action_reply" = "Reply"; "action_reply_in_thread" = "Reply in thread"; "action_report_bug" = "Report bug"; diff --git a/ElementX/Sources/Generated/Strings.swift b/ElementX/Sources/Generated/Strings.swift index db2328789..36ae30edd 100644 --- a/ElementX/Sources/Generated/Strings.swift +++ b/ElementX/Sources/Generated/Strings.swift @@ -104,10 +104,14 @@ internal enum L10n { internal static var actionContinue: String { return L10n.tr("Localizable", "action_continue") } /// Copy internal static var actionCopy: String { return L10n.tr("Localizable", "action_copy") } + /// Copy caption + internal static var actionCopyCaption: String { return L10n.tr("Localizable", "action_copy_caption") } /// Copy link internal static var actionCopyLink: String { return L10n.tr("Localizable", "action_copy_link") } /// Copy link to message internal static var actionCopyLinkToMessage: String { return L10n.tr("Localizable", "action_copy_link_to_message") } + /// Copy text + internal static var actionCopyText: String { return L10n.tr("Localizable", "action_copy_text") } /// Create internal static var actionCreate: String { return L10n.tr("Localizable", "action_create") } /// Create a room @@ -204,6 +208,8 @@ internal enum L10n { internal static var actionRemove: String { return L10n.tr("Localizable", "action_remove") } /// Remove caption internal static var actionRemoveCaption: String { return L10n.tr("Localizable", "action_remove_caption") } + /// Remove message + internal static var actionRemoveMessage: String { return L10n.tr("Localizable", "action_remove_message") } /// Reply internal static var actionReply: String { return L10n.tr("Localizable", "action_reply") } /// Reply in thread diff --git a/ElementX/Sources/Other/SwiftUI/Layout/MenuSheetLabelStyle.swift b/ElementX/Sources/Other/SwiftUI/Layout/MenuSheetLabelStyle.swift index 0ea17f68e..12f701be9 100644 --- a/ElementX/Sources/Other/SwiftUI/Layout/MenuSheetLabelStyle.swift +++ b/ElementX/Sources/Other/SwiftUI/Layout/MenuSheetLabelStyle.swift @@ -7,14 +7,34 @@ import SwiftUI -extension LabelStyle where Self == MenuSheetLabelStyle { - /// A label style for labels that are within a menu that is being presented as a sheet. - static var menuSheet: Self { MenuSheetLabelStyle() } +extension ButtonStyle where Self == MenuSheetButtonStyle { + /// A button style for buttons that are within a menu that is being presented as a sheet. + static var menuSheet: Self { MenuSheetButtonStyle() } } -/// The style used for labels that are part of a menu that's presented as -/// a sheet as `TimelineItemMenu` and `RoomAttachmentPicker`. -struct MenuSheetLabelStyle: LabelStyle { +/// The style used for buttons that are part of a menu that's presented as +/// a sheet such as `TimelineItemMenu`. +struct MenuSheetButtonStyle: ButtonStyle { + @Environment(\.accessibilityShowButtonShapes) private var accessibilityShowButtonShapes + + func makeBody(configuration: Configuration) -> some View { + configuration.label + .labelStyle(MenuSheetLabelStyle()) + .foregroundStyle(configuration.role == .destructive ? .compound.textCriticalPrimary : .compound.textActionPrimary) + .contentShape(.rect) + .opacity(configuration.isPressed ? 0.3 : 1) + .background { + if accessibilityShowButtonShapes { + RoundedRectangle(cornerRadius: 12) + .fill(Color(uiColor: .secondarySystemFill)) + .opacity(configuration.isPressed ? 0.8 : 1) + .padding(4) + } + } + } +} + +private struct MenuSheetLabelStyle: LabelStyle { var spacing: CGFloat = 16 func makeBody(configuration: Configuration) -> some View { diff --git a/ElementX/Sources/Screens/RoomScreen/ComposerToolbar/View/RoomAttachmentPicker.swift b/ElementX/Sources/Screens/RoomScreen/ComposerToolbar/View/RoomAttachmentPicker.swift index 0732bd15f..b789445a7 100644 --- a/ElementX/Sources/Screens/RoomScreen/ComposerToolbar/View/RoomAttachmentPicker.swift +++ b/ElementX/Sources/Screens/RoomScreen/ComposerToolbar/View/RoomAttachmentPicker.swift @@ -32,7 +32,6 @@ struct RoomAttachmentPicker: View { context.send(viewAction: .enableTextFormatting) } label: { Label(L10n.screenRoomAttachmentTextFormatting, icon: \.textFormatting) - .labelStyle(.menuSheet) } .accessibilityIdentifier(A11yIdentifiers.roomScreen.attachmentPickerTextFormatting) @@ -40,7 +39,6 @@ struct RoomAttachmentPicker: View { context.send(viewAction: .attach(.poll)) } label: { Label(L10n.screenRoomAttachmentSourcePoll, icon: \.polls) - .labelStyle(.menuSheet) } .accessibilityIdentifier(A11yIdentifiers.roomScreen.attachmentPickerPoll) @@ -48,7 +46,6 @@ struct RoomAttachmentPicker: View { context.send(viewAction: .attach(.location)) } label: { Label(L10n.screenRoomAttachmentSourceLocation, icon: \.locationPin) - .labelStyle(.menuSheet) } .accessibilityIdentifier(A11yIdentifiers.roomScreen.attachmentPickerLocation) @@ -56,7 +53,6 @@ struct RoomAttachmentPicker: View { context.send(viewAction: .attach(.file)) } label: { Label(L10n.screenRoomAttachmentSourceFiles, icon: \.attachment) - .labelStyle(.menuSheet) } .accessibilityIdentifier(A11yIdentifiers.roomScreen.attachmentPickerDocuments) @@ -64,7 +60,6 @@ struct RoomAttachmentPicker: View { context.send(viewAction: .attach(.photoLibrary)) } label: { Label(L10n.screenRoomAttachmentSourceGallery, icon: \.image) - .labelStyle(.menuSheet) } .accessibilityIdentifier(A11yIdentifiers.roomScreen.attachmentPickerPhotoLibrary) @@ -72,7 +67,6 @@ struct RoomAttachmentPicker: View { context.send(viewAction: .attach(.camera)) } label: { Label(L10n.screenRoomAttachmentSourceCamera, icon: \.takePhoto) - .labelStyle(.menuSheet) } .accessibilityIdentifier(A11yIdentifiers.roomScreen.attachmentPickerCamera) } diff --git a/ElementX/Sources/Screens/Timeline/TimelineInteractionHandler.swift b/ElementX/Sources/Screens/Timeline/TimelineInteractionHandler.swift index c7d004df1..2e610569c 100644 --- a/ElementX/Sources/Screens/Timeline/TimelineInteractionHandler.swift +++ b/ElementX/Sources/Screens/Timeline/TimelineInteractionHandler.swift @@ -102,7 +102,13 @@ class TimelineInteractionHandler { case .copy: guard let messageTimelineItem = timelineItem as? EventBasedMessageTimelineItemProtocol else { return } UIPasteboard.general.string = messageTimelineItem.body - case .edit: + case .copyCaption: + guard let messageTimelineItem = timelineItem as? EventBasedMessageTimelineItemProtocol, + let caption = messageTimelineItem.mediaCaption else { + return + } + UIPasteboard.general.string = caption + case .edit, .addCaption, .editCaption, .editPoll: switch timelineItem { case let messageTimelineItem as EventBasedMessageTimelineItemProtocol: processEditMessageEvent(messageTimelineItem) @@ -115,13 +121,6 @@ class TimelineInteractionHandler { default: MXLog.error("Cannot edit item with id: \(timelineItem.id)") } - case .addCaption, .editCaption: - switch timelineItem { - case let messageTimelineItem as EventBasedMessageTimelineItemProtocol: - processEditMessageEvent(messageTimelineItem) - default: - MXLog.error("Cannot add/edit caption on item with id: \(timelineItem.id)") - } case .removeCaption: guard case let .event(_, eventOrTransactionID) = timelineItem.id else { MXLog.error("Failed removing caption, missing event ID") diff --git a/ElementX/Sources/Screens/Timeline/View/ItemMenu/TimelineItemMacContextMenu.swift b/ElementX/Sources/Screens/Timeline/View/ItemMenu/TimelineItemMacContextMenu.swift index f97ae8011..8cb4264d4 100644 --- a/ElementX/Sources/Screens/Timeline/View/ItemMenu/TimelineItemMacContextMenu.swift +++ b/ElementX/Sources/Screens/Timeline/View/ItemMenu/TimelineItemMacContextMenu.swift @@ -51,7 +51,7 @@ struct TimelineItemMacContextMenu: View { } Section { - ForEach(menuActions.debugActions) { action in + ForEach(menuActions.secondaryActions) { action in Button(role: action.isDestructive ? .destructive : nil) { send(action) } label: { diff --git a/ElementX/Sources/Screens/Timeline/View/ItemMenu/TimelineItemMenu.swift b/ElementX/Sources/Screens/Timeline/View/ItemMenu/TimelineItemMenu.swift index 43e7144ac..e7448035c 100644 --- a/ElementX/Sources/Screens/Timeline/View/ItemMenu/TimelineItemMenu.swift +++ b/ElementX/Sources/Screens/Timeline/View/ItemMenu/TimelineItemMenu.swift @@ -47,7 +47,7 @@ struct TimelineItemMenu: View { .background(Color.compound.bgSubtlePrimary) } - viewsForActions(actions.debugActions) + viewsForActions(actions.secondaryActions) } } } @@ -179,8 +179,8 @@ struct TimelineItemMenu: View { send(action) } label: { action.label - .labelStyle(.menuSheet) } + .buttonStyle(.menuSheet) } } @@ -261,21 +261,28 @@ private extension View { // MARK: - Previews struct TimelineItemMenu_Previews: PreviewProvider, TestablePreview { + enum ItemType { case incomingText, outgoingMedia, outgoingMediaWithCaption } + static let viewModel = TimelineViewModel.mock - static let (item, actions) = makeItem() - static let (backupItem, _) = makeItem(authenticity: .notGuaranteed(color: .gray)) - static let (unsignedItem, _) = makeItem(authenticity: .unsignedDevice(color: .red)) - static let (unencryptedItem, _) = makeItem(authenticity: .sentInClear(color: .red)) - static let (unknownFailureItem, _) = makeItem(deliveryStatus: .sendingFailed(.unknown)) - static let (identityChangedItem, _) = makeItem(deliveryStatus: .sendingFailed(.verifiedUser(.changedIdentity(users: [ + static let (item, actions) = makeActions() + static let (backupItem, _) = makeActions(authenticity: .notGuaranteed(color: .gray)) + static let (unsignedItem, _) = makeActions(authenticity: .unsignedDevice(color: .red)) + static let (unencryptedItem, _) = makeActions(authenticity: .sentInClear(color: .red)) + static let (unknownFailureItem, _) = makeActions(deliveryStatus: .sendingFailed(.unknown)) + static let (identityChangedItem, _) = makeActions(deliveryStatus: .sendingFailed(.verifiedUser(.changedIdentity(users: [ "@alice:matrix.org" ])))) - static let (unsignedDevicesItem, _) = makeItem(deliveryStatus: .sendingFailed(.verifiedUser(.hasUnsignedDevice(devices: [ + static let (unsignedDevicesItem, _) = makeActions(deliveryStatus: .sendingFailed(.verifiedUser(.hasUnsignedDevice(devices: [ "@alice:matrix.org": ["DEVICE1", "DEVICE2"] ])))) - static let (ownUnsignedDevicesItem, _) = makeItem(deliveryStatus: .sendingFailed(.verifiedUser(.hasUnsignedDevice(devices: [ + static let (ownUnsignedDevicesItem, _) = makeActions(deliveryStatus: .sendingFailed(.verifiedUser(.hasUnsignedDevice(devices: [ RoomMemberProxyMock.mockMe.userID: ["DEVICE1"] ])))) + + // Media + + static let (mediaItem, mediaItemActions) = makeActions(itemType: .outgoingMedia) + static let (mediaItemWithCaption, mediaItemWithCaptionActions) = makeActions(itemType: .outgoingMediaWithCaption) static var previews: some View { TimelineItemMenu(item: item, actions: actions) @@ -314,26 +321,56 @@ struct TimelineItemMenu_Previews: PreviewProvider, TestablePreview { TimelineItemMenu(item: identityChangedItem, actions: actions) .environmentObject(viewModel.context) .previewDisplayName("Identity Changed") + + // Media + + TimelineItemMenu(item: mediaItem, actions: mediaItemActions) + .environmentObject(viewModel.context) + .previewDisplayName("Media") + + TimelineItemMenu(item: mediaItemWithCaption, actions: mediaItemWithCaptionActions) + .environmentObject(viewModel.context) + .previewDisplayName("Media with Caption") } - static func makeItem(authenticity: EncryptionAuthenticity? = nil, - deliveryStatus: TimelineItemDeliveryStatus? = nil) -> (TextRoomTimelineItem, TimelineItemMenuActions)! { - guard var item = RoomTimelineItemFixtures.singleMessageChunk.first as? TextRoomTimelineItem, - let actions = TimelineItemMenuActions(isReactable: true, - actions: [.copy, .edit, .reply(isThread: false), .pin, .redact], - debugActions: [.viewSource], - emojiProvider: EmojiProvider(appSettings: ServiceLocator.shared.settings)) else { - return nil - } + static func makeActions(itemType: ItemType = .incomingText, + authenticity: EncryptionAuthenticity? = nil, + deliveryStatus: TimelineItemDeliveryStatus? = nil) -> (EventBasedTimelineItemProtocol, TimelineItemMenuActions)! { + guard var item = makeItem(itemType: itemType) else { return nil } + let provider = TimelineItemMenuActionProvider(timelineItem: item, + canCurrentUserRedactSelf: true, + canCurrentUserRedactOthers: false, + canCurrentUserPin: true, + pinnedEventIDs: [], + isDM: true, + isViewSourceEnabled: true, + isCreateMediaCaptionsEnabled: true, + isPinnedEventsTimeline: false, + emojiProvider: EmojiProvider(appSettings: ServiceLocator.shared.settings)) + guard let actions = provider.makeActions() else { return nil } - if let authenticity { - item.properties.encryptionAuthenticity = authenticity - } - - if let deliveryStatus { - item.properties.deliveryStatus = deliveryStatus + if var textItem = item as? TextRoomTimelineItem { + if let authenticity { + textItem.properties.encryptionAuthenticity = authenticity + } + + if let deliveryStatus { + textItem.properties.deliveryStatus = deliveryStatus + } + item = textItem } return (item, actions) } + + static func makeItem(itemType: ItemType) -> EventBasedTimelineItemProtocol? { + switch itemType { + case .incomingText: + RoomTimelineItemFixtures.singleMessageChunk.first as? EventBasedTimelineItemProtocol + case .outgoingMedia: + RoomTimelineItemFixtures.mediaChunk[1] as? EventBasedTimelineItemProtocol + case .outgoingMediaWithCaption: + RoomTimelineItemFixtures.mediaChunk[5] as? EventBasedTimelineItemProtocol + } + } } diff --git a/ElementX/Sources/Screens/Timeline/View/ItemMenu/TimelineItemMenuAction.swift b/ElementX/Sources/Screens/Timeline/View/ItemMenu/TimelineItemMenuAction.swift index 38f824622..3a0e88b79 100644 --- a/ElementX/Sources/Screens/Timeline/View/ItemMenu/TimelineItemMenuAction.swift +++ b/ElementX/Sources/Screens/Timeline/View/ItemMenu/TimelineItemMenuAction.swift @@ -13,18 +13,18 @@ import SwiftUI struct TimelineItemMenuActions { let reactions: [TimelineItemMenuReaction] let actions: [TimelineItemMenuAction] - let debugActions: [TimelineItemMenuAction] + let secondaryActions: [TimelineItemMenuAction] init?(isReactable: Bool, actions: [TimelineItemMenuAction], - debugActions: [TimelineItemMenuAction], + secondaryActions: [TimelineItemMenuAction], emojiProvider: EmojiProviderProtocol) { - if !isReactable, actions.isEmpty, debugActions.isEmpty { + if !isReactable, actions.isEmpty, secondaryActions.isEmpty { return nil } self.actions = actions - self.debugActions = debugActions + self.secondaryActions = secondaryActions var frequentlyUsed: OrderedSet = [ .init(key: "👍️", symbol: .handThumbsup), @@ -56,10 +56,12 @@ struct TimelineItemMenuReaction: Hashable { enum TimelineItemMenuAction: Identifiable, Hashable { case copy + case copyCaption case edit case addCaption case editCaption case removeCaption + case editPoll case copyPermalink case redact case reply(isThread: Bool) @@ -79,7 +81,7 @@ enum TimelineItemMenuAction: Identifiable, Hashable { /// Whether the item should cancel a reply/edit occurring in the composer. var switchToDefaultComposer: Bool { switch self { - case .reply, .edit, .addCaption, .editCaption: + case .reply, .edit, .addCaption, .editCaption, .editPoll: return false default: return true @@ -89,7 +91,7 @@ enum TimelineItemMenuAction: Identifiable, Hashable { /// Whether the action should be shown for an item that failed to send. var canAppearInFailedEcho: Bool { switch self { - case .copy, .edit, .redact, .viewSource: + case .copy, .edit, .redact, .viewSource, .editPoll: return true default: return false @@ -130,7 +132,9 @@ enum TimelineItemMenuAction: Identifiable, Hashable { var label: some View { switch self { case .copy: - Label(L10n.actionCopy, icon: \.copy) + Label(L10n.actionCopyText, icon: \.copy) + case .copyCaption: + Label(L10n.actionCopyCaption, icon: \.copy) case .edit: Label(L10n.actionEdit, icon: \.edit) case .addCaption: @@ -138,7 +142,9 @@ enum TimelineItemMenuAction: Identifiable, Hashable { case .editCaption: Label(L10n.actionEditCaption, icon: \.edit) case .removeCaption: - Label(L10n.actionRemoveCaption, icon: \.delete) + Label(L10n.actionRemoveCaption, icon: \.close) + case .editPoll: + Label(L10n.actionEditPoll, icon: \.edit) case .copyPermalink: Label(L10n.actionCopyLinkToMessage, icon: \.link) case .reply(let isThread): @@ -146,7 +152,7 @@ enum TimelineItemMenuAction: Identifiable, Hashable { case .forward: Label(L10n.actionForward, icon: \.forward) case .redact: - Label(L10n.actionRemove, icon: \.delete) + Label(L10n.actionRemoveMessage, icon: \.delete) case .viewSource: Label(L10n.actionViewSource, icon: \.code) case .retryDecryption: diff --git a/ElementX/Sources/Screens/Timeline/View/ItemMenu/TimelineItemMenuActionProvider.swift b/ElementX/Sources/Screens/Timeline/View/ItemMenu/TimelineItemMenuActionProvider.swift index cad18009e..4d624fb3f 100644 --- a/ElementX/Sources/Screens/Timeline/View/ItemMenu/TimelineItemMenuActionProvider.swift +++ b/ElementX/Sources/Screens/Timeline/View/ItemMenu/TimelineItemMenuActionProvider.swift @@ -32,26 +32,12 @@ struct TimelineItemMenuActionProvider { return nil } - var debugActions: [TimelineItemMenuAction] = [] - if isViewSourceEnabled { - debugActions.append(.viewSource) - } - if let encryptedItem = timelineItem as? EncryptedRoomTimelineItem { - switch encryptedItem.encryptionType { - case .megolmV1AesSha2(let sessionID, _): - debugActions.append(.retryDecryption(sessionID: sessionID)) - default: - break - } - - return .init(isReactable: false, - actions: [.copyPermalink], - debugActions: debugActions, - emojiProvider: emojiProvider) + return makeEncryptedItemActions(encryptedItem) } var actions: [TimelineItemMenuAction] = [] + var secondaryActions: [TimelineItemMenuAction] = [] if item.canBeRepliedTo { if let messageItem = item as? EventBasedMessageTimelineItemProtocol { @@ -64,59 +50,95 @@ struct TimelineItemMenuActionProvider { if item.isForwardable { actions.append(.forward(itemID: item.id)) } - - if item.isEditable { - if let messageItem = item as? EventBasedMessageTimelineItemProtocol, messageItem.supportsMediaCaption { - if messageItem.hasMediaCaption { - actions.append(contentsOf: [.editCaption, .removeCaption]) - } else if isCreateMediaCaptionsEnabled { - actions.append(.addCaption) - } - } else if !(item is VoiceMessageRoomTimelineItem) { - actions.append(.edit) - } - } if canCurrentUserPin, let eventID = item.id.eventID { actions.append(pinnedEventIDs.contains(eventID) ? .unpin : .pin) } - - if item.isCopyable { - actions.append(.copy) - } if item.isRemoteMessage { actions.append(.copyPermalink) } + + if item.isEditable { + if item.supportsMediaCaption { + if item.hasMediaCaption { + actions.append(.editCaption) + } else if isCreateMediaCaptionsEnabled { + actions.append(.addCaption) + } + } else if item is PollRoomTimelineItem { + actions.append(.editPoll) + } else if !(item is VoiceMessageRoomTimelineItem) { + actions.append(.edit) + } + } + if item.isCopyable { + actions.append(.copy) + } else if item.hasMediaCaption { + actions.append(.copyCaption) + } + + if item.hasMediaCaption { + actions.append(.removeCaption) + } + if canRedactItem(item), let poll = item.pollIfAvailable, !poll.hasEnded, let eventID = item.id.eventID { actions.append(.endPoll(pollStartID: eventID)) } - if canRedactItem(item) { - actions.append(.redact) + if isViewSourceEnabled { + actions.append(.viewSource) } - + if !item.isOutgoing { - actions.append(.report) + secondaryActions.append(.report) } - - if item.hasFailedToSend { - actions = actions.filter(\.canAppearInFailedEcho) - } - - if item.isRedacted { - actions = actions.filter(\.canAppearInRedacted) + + if canRedactItem(item) { + secondaryActions.append(.redact) } if isPinnedEventsTimeline { actions.insert(.viewInRoomTimeline, at: 0) actions = actions.filter(\.canAppearInPinnedEventsTimeline) + secondaryActions = secondaryActions.filter(\.canAppearInPinnedEventsTimeline) + } + + if item.hasFailedToSend { + actions = actions.filter(\.canAppearInFailedEcho) + secondaryActions = secondaryActions.filter(\.canAppearInFailedEcho) + } + + if item.isRedacted { + actions = actions.filter(\.canAppearInRedacted) + secondaryActions = secondaryActions.filter(\.canAppearInRedacted) } return .init(isReactable: isPinnedEventsTimeline ? false : item.isReactable, actions: actions, - debugActions: debugActions, + secondaryActions: secondaryActions, + emojiProvider: emojiProvider) + } + + private func makeEncryptedItemActions(_ encryptedItem: EncryptedRoomTimelineItem) -> TimelineItemMenuActions? { + var actions: [TimelineItemMenuAction] = [.copyPermalink] + var secondaryActions: [TimelineItemMenuAction] = [] + + if isViewSourceEnabled { + actions.append(.viewSource) + } + + switch encryptedItem.encryptionType { + case .megolmV1AesSha2(let sessionID, _): + secondaryActions.append(.retryDecryption(sessionID: sessionID)) + default: + break + } + + return .init(isReactable: false, + actions: actions, + secondaryActions: secondaryActions, emojiProvider: emojiProvider) } diff --git a/ElementX/Sources/Services/Timeline/Fixtures/RoomTimelineItemFixtures.swift b/ElementX/Sources/Services/Timeline/Fixtures/RoomTimelineItemFixtures.swift index da67a49fc..716849af3 100644 --- a/ElementX/Sources/Services/Timeline/Fixtures/RoomTimelineItemFixtures.swift +++ b/ElementX/Sources/Services/Timeline/Fixtures/RoomTimelineItemFixtures.swift @@ -250,28 +250,16 @@ enum RoomTimelineItemFixtures { static var mediaChunk: [RoomTimelineItemProtocol] { [ - VideoRoomTimelineItem(id: .randomEvent, - timestamp: "10:47 am", - isOutgoing: false, - isEditable: false, - canBeRepliedTo: true, - isThreaded: false, - sender: .init(id: ""), - content: .init(filename: "video.mp4", - videoInfo: .mockVideo, - thumbnailInfo: .mockThumbnail, - blurhash: "KtI~70X5V?yss9oyrYs:t6")), - ImageRoomTimelineItem(id: .randomEvent, - timestamp: "10:47 am", - isOutgoing: false, - isEditable: false, - canBeRepliedTo: true, - isThreaded: false, - sender: .init(id: ""), - content: .init(filename: "image.jpg", - imageInfo: .mockImage, - thumbnailInfo: nil, - blurhash: "KpE4oyayR5|GbHb];3j@of")) + AudioRoomTimelineItem(isOutgoing: false, caption: "Listen to this!"), + AudioRoomTimelineItem(isOutgoing: true), + FileRoomTimelineItem(isOutgoing: false), + FileRoomTimelineItem(isOutgoing: true, caption: "Please check this ASAP!"), + ImageRoomTimelineItem(isOutgoing: false), + ImageRoomTimelineItem(isOutgoing: true, caption: "Isn't this pretty!"), + VideoRoomTimelineItem(isOutgoing: false, caption: "Woah, it was incredible!"), + VideoRoomTimelineItem(isOutgoing: true), + VoiceMessageRoomTimelineItem(isOutgoing: false), + VoiceMessageRoomTimelineItem(isOutgoing: true) ] } } @@ -294,3 +282,92 @@ private extension TextRoomTimelineItem { return newSelf } } + +private extension AudioRoomTimelineItem { + init(isOutgoing: Bool, caption: String? = nil) { + self.init(id: .randomEvent, + timestamp: "10:47 am", + isOutgoing: isOutgoing, + isEditable: isOutgoing, + canBeRepliedTo: true, + isThreaded: false, + sender: .init(id: isOutgoing ? "@alice:matrix.org" : "@bob:matrix.org"), + content: .init(filename: "audio.mp3", + caption: caption, + duration: 60, + waveform: nil, + source: .init(url: .mockMXCAudio, mimeType: nil), + fileSize: nil, + contentType: .mp3)) + } +} + +private extension FileRoomTimelineItem { + init(isOutgoing: Bool, caption: String? = nil) { + self.init(id: .randomEvent, + timestamp: "10:47 am", + isOutgoing: isOutgoing, + isEditable: isOutgoing, + canBeRepliedTo: true, + isThreaded: false, + sender: .init(id: isOutgoing ? "@alice:matrix.org" : "@bob:matrix.org"), + content: .init(filename: "file.pdf", + caption: caption, + source: .init(url: .mockMXCFile, mimeType: nil), + fileSize: nil, + thumbnailSource: nil, + contentType: .pdf)) + } +} + +private extension ImageRoomTimelineItem { + init(isOutgoing: Bool, caption: String? = nil) { + self.init(id: .randomEvent, + timestamp: "10:47 am", + isOutgoing: isOutgoing, + isEditable: isOutgoing, + canBeRepliedTo: true, + isThreaded: false, + sender: .init(id: isOutgoing ? "@alice:matrix.org" : "@bob:matrix.org"), + content: .init(filename: "image.jpg", + caption: caption, + imageInfo: .mockImage, + thumbnailInfo: nil, + blurhash: "KpE4oyayR5|GbHb];3j@of")) + } +} + +private extension VideoRoomTimelineItem { + init(isOutgoing: Bool, caption: String? = nil) { + self.init(id: .randomEvent, + timestamp: "10:47 am", + isOutgoing: isOutgoing, + isEditable: isOutgoing, + canBeRepliedTo: true, + isThreaded: false, + sender: .init(id: isOutgoing ? "@alice:matrix.org" : "@bob:matrix.org"), + content: .init(filename: "video.mp4", + caption: caption, + videoInfo: .mockVideo, + thumbnailInfo: .mockThumbnail, + blurhash: "KtI~70X5V?yss9oyrYs:t6")) + } +} + +private extension VoiceMessageRoomTimelineItem { + init(isOutgoing: Bool) { + self.init(id: .randomEvent, + timestamp: "10:47 am", + isOutgoing: isOutgoing, + isEditable: isOutgoing, + canBeRepliedTo: true, + isThreaded: false, + sender: .init(id: isOutgoing ? "@alice:matrix.org" : "@bob:matrix.org"), + content: .init(filename: "message.ogg", + duration: 10, + waveform: .mockWaveform, + source: .init(url: .mockMXCAudio, mimeType: nil), + fileSize: nil, + contentType: .audio)) + } +} diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/EventBasedMessageTimelineItemProtocol.swift b/ElementX/Sources/Services/Timeline/TimelineItems/EventBasedMessageTimelineItemProtocol.swift index a0832abf5..734037766 100644 --- a/ElementX/Sources/Services/Timeline/TimelineItems/EventBasedMessageTimelineItemProtocol.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItems/EventBasedMessageTimelineItemProtocol.swift @@ -35,18 +35,22 @@ extension EventBasedMessageTimelineItemProtocol { } } - var hasMediaCaption: Bool { + var mediaCaption: String? { switch contentType { case .audio(let content): - content.caption != nil + content.caption case .file(let content): - content.caption != nil + content.caption case .image(let content): - content.caption != nil + content.caption case .video(let content): - content.caption != nil + content.caption case .emote, .notice, .text, .location, .voice: - false + nil } } + + var hasMediaCaption: Bool { + mediaCaption != nil + } } diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/EventBasedTimelineItemProtocol.swift b/ElementX/Sources/Services/Timeline/TimelineItems/EventBasedTimelineItemProtocol.swift index aa99847b7..0150401ff 100644 --- a/ElementX/Sources/Services/Timeline/TimelineItems/EventBasedTimelineItemProtocol.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItems/EventBasedTimelineItemProtocol.swift @@ -99,4 +99,14 @@ extension EventBasedTimelineItemProtocol { return true } } + + var supportsMediaCaption: Bool { + guard let messageBasedItem = self as? EventBasedMessageTimelineItemProtocol else { return false } + return messageBasedItem.supportsMediaCaption + } + + var hasMediaCaption: Bool { + guard let messageBasedItem = self as? EventBasedMessageTimelineItemProtocol else { return false } + return messageBasedItem.hasMediaCaption + } } diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Authenticity.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Authenticity.png index 5614e9125..c93414d20 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Authenticity.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Authenticity.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bcc6fdf7c3f7e40f9beedb8f9779fa74b3c8d7020112398059783ff2820fa4ed -size 135575 +oid sha256:42992a72deec6d6cc0a3268f4619db58fb44ba869b6cca0c9937ee70a0effd7e +size 147883 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Button-shapes.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Button-shapes.png index e6e1c3129..d3a797f89 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Button-shapes.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Button-shapes.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3e337818f2c9ecd0e7abfe35868857394f3b1129e798354266035b65ed9fe9ee -size 142532 +oid sha256:a0868feab75e9ac054da551d7ebcc17d7cb8e2cfb3c4ab540f5d05753a273aea +size 154967 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Identity-Changed.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Identity-Changed.png index db49f1379..c4a29de51 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Identity-Changed.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Identity-Changed.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a7ba26595547bdab86bc57097fcccb0062b73c9afcccc5ee2d9481c24a5ee954 -size 134046 +oid sha256:a57163af2dbcb6af527279ee9959aaf4ac5830424b14deede615891b8da411c4 +size 146496 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Media-with-Caption.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Media-with-Caption.png new file mode 100644 index 000000000..d0b640996 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Media-with-Caption.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8dfdb1408f464b7570b1c587e03dec72be0cc02ad28af2475c7f13eabfecfdea +size 143529 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Media.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Media.png new file mode 100644 index 000000000..b34a3b3ca --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Media.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a8bad202aa9c390b47af7d1e35f3e65c731a3f3ae659c943c7f1ae63581590ec +size 133449 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Normal.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Normal.png index 6dc2b5e65..839ae5df7 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Normal.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Normal.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7f1d6997b3ca132dbf486145371ccc38418ee1ccfbb05ebd670f73f621008c48 -size 124084 +oid sha256:ccec869066425d2bcb107a1dae131d0a87bd2f1c8b345edd8fe77edfe3f779a1 +size 136131 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Own-Unsigned-Devices.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Own-Unsigned-Devices.png index e1bddfabb..5cf9b34ab 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Own-Unsigned-Devices.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Own-Unsigned-Devices.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fbf1b0ba7b26a5bf3040ceffbfcca15cf38445fe4db7a39b81b16826517c6762 -size 134605 +oid sha256:e4448552425a8dde78ee792f3915d76721d548d38daa3b59854e56d692b15286 +size 147056 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Unencrypted.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Unencrypted.png index 214c0a0e7..5df36e364 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Unencrypted.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Unencrypted.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bdcb99ed272db7ee82b09574da7e791ee371b35107ca8104a72acd71e99b1156 -size 129013 +oid sha256:b9845682cd8bc72244d05d872a5212735890703a5e65400667986f1d158a991d +size 141448 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Unknown-failure.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Unknown-failure.png index 6dc2b5e65..839ae5df7 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Unknown-failure.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Unknown-failure.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7f1d6997b3ca132dbf486145371ccc38418ee1ccfbb05ebd670f73f621008c48 -size 124084 +oid sha256:ccec869066425d2bcb107a1dae131d0a87bd2f1c8b345edd8fe77edfe3f779a1 +size 136131 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Unsigned-Devices.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Unsigned-Devices.png index a8350dec8..5c5b13d3c 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Unsigned-Devices.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Unsigned-Devices.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:83ec69d4b69f3a33422b0a472665c65855a365b4f676888edb9eb054ebaf77d4 -size 133818 +oid sha256:b2d5f335b38cdde8f4e5e8c40e7c2c95bee523d353d880e026c7c012c0f86284 +size 146268 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Unsigned.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Unsigned.png index af16a6b6e..98d7bb1f0 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Unsigned.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Unsigned.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e173a969f56bdfad935308070f5dc1958eaf7781fbcf18e01c81b95799ce3ae1 -size 132960 +oid sha256:5bcb1cf3a950c99e05559cb2cf2162e5b96cbccdebbe42e3b09efa2256a5c53c +size 145195 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Authenticity.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Authenticity.png index 73cb694b0..fa99fad4f 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Authenticity.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Authenticity.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c5a5a1d65cd3f0c569f2ca1fb80258e8179870acade4a1d68b3e9e67a52d8d29 -size 142541 +oid sha256:75219b465e5332f12fada6b5c507c9ee6c62c409b06167824310cb7dfbb068f7 +size 156450 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Button-shapes.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Button-shapes.png index 871bdb3e5..50382b602 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Button-shapes.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Button-shapes.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9fbc2bf481aeecb17f3be814b3bcf7147f2d8d757eb82a15b2a0db10a5ec8f40 -size 144452 +oid sha256:e950f852539eccca04f68060e56787413f90a6c2481df251e8ab315cf5b659d1 +size 158242 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Identity-Changed.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Identity-Changed.png index da7e6a2e8..90a3935d1 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Identity-Changed.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Identity-Changed.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1eac1d2d29c71d9c332f26b311b50c7ef601896a6941a1f617d200e23bb88731 -size 141641 +oid sha256:065d14de719ede0234e865a45119a2731da20e7982249db240180db9b7dafe71 +size 155522 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Media-with-Caption.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Media-with-Caption.png new file mode 100644 index 000000000..8cbff9be9 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Media-with-Caption.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5c33873265e2e90314f656d95668da81ab86e7461fea51bfbff083eaea512b52 +size 148202 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Media.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Media.png new file mode 100644 index 000000000..e8f58be7f --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Media.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:001894f533a0619f577647f55a790769d50f5200d4664d027a6b4337e7c8fc25 +size 136972 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Normal.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Normal.png index fbbe196d7..883b6c33a 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Normal.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Normal.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:39c0cc82049d6e4c12416c457a087d99b52169ab266da1beaa22888aa933bca5 -size 125934 +oid sha256:a9bd0e980e02351fdcc69c1e2e71c6c579ee9223b671aedbb8b906d82f0a6da6 +size 139535 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Own-Unsigned-Devices.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Own-Unsigned-Devices.png index 01df243b1..ad09b6c54 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Own-Unsigned-Devices.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Own-Unsigned-Devices.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:eac68c72456505eaafd6c94948857aaa2d54accc4990c3dd3cd1cb31023c89bf -size 140645 +oid sha256:e28d69132bf0d7c6e2380916185df3e5bc0bcf858eda4418cbf561e19b0cfa91 +size 154495 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Unencrypted.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Unencrypted.png index 65f5a2de0..60922e705 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Unencrypted.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Unencrypted.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:150daec2df86269a675887b754f64e067dcdb856dff9d1c8a36e746495745ab8 -size 133199 +oid sha256:b0451dcad4c79972172c171622e32af923db17278bb59d8858ed538ef2e5acb8 +size 146847 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Unknown-failure.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Unknown-failure.png index fbbe196d7..883b6c33a 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Unknown-failure.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Unknown-failure.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:39c0cc82049d6e4c12416c457a087d99b52169ab266da1beaa22888aa933bca5 -size 125934 +oid sha256:a9bd0e980e02351fdcc69c1e2e71c6c579ee9223b671aedbb8b906d82f0a6da6 +size 139535 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Unsigned-Devices.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Unsigned-Devices.png index ebe3d9742..5db052a2f 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Unsigned-Devices.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Unsigned-Devices.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a1d61ad248aa93c90b680e51cdf4a30d8cfd9568a062b03b559d6f9d57fffddf -size 140013 +oid sha256:dc893c5f8cfe7a247818288ec6e551ff9ee4c02971cde61d6bb5502f7af139d5 +size 153853 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Unsigned.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Unsigned.png index 49a10d7bd..2042c2f77 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Unsigned.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Unsigned.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2c30cb638c2eecebb63ca66a5f0107bb85225aa786cbf32ecbca9974b42cd383 -size 139069 +oid sha256:1d8fb938c99c65f5884636f8806bf3fe9a5de5b6877cf0a2899529df29e30679 +size 152908 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Authenticity.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Authenticity.png index b3d2bd460..e2a88dcb5 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Authenticity.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Authenticity.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dd17e2229ac0f1c09ef301589f24de7f879364dbc468460d6e387b2393d6b584 -size 88452 +oid sha256:914c77c473286e62ff5fabd0d62ce7bd0a71c0755a8d2e99ceabb102bdd7f7f0 +size 99760 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Button-shapes.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Button-shapes.png index c5cf3ce85..3ef2032d0 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Button-shapes.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Button-shapes.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2e9f207e4656524273989488b2e8f1d9ee2901d500a76b89dbbf01e831a146c7 -size 91341 +oid sha256:6224e94342cbe0303473eb91f16f97e85e67e43ab74be0d6b68868e3a428d1ea +size 103095 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Identity-Changed.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Identity-Changed.png index acee9f683..8b2139813 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Identity-Changed.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Identity-Changed.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:46f40c81c046bb1593d0ac0d1b396558e75ab4d9a85ce9f460610c623835711a -size 87463 +oid sha256:db0cc945ae881ff0979376ebe01eda05899100557c0778164a0b43f54f8ae6c5 +size 98124 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Media-with-Caption.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Media-with-Caption.png new file mode 100644 index 000000000..494a4efc7 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Media-with-Caption.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:10701f9bcc6d6906d8b1063b145fd754c0af3928e5d5664cb35b1aa4d79aa999 +size 95921 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Media.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Media.png new file mode 100644 index 000000000..50924d695 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Media.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:01dd4d77411e87302bb5b4b152de7e5eb761c7f4b367a84f36a31fc5e141fa9d +size 87399 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Normal.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Normal.png index afc397109..8010c1fc2 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Normal.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Normal.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b1a6d6103056a883e4fa9344b65766867ef28355f359c428c6f8fc7b8a5b1dd4 -size 78383 +oid sha256:841d4f5f4f5a4e3eac938f2fcd4b0bb94561eebd6179c91cb84816f3ae7df8b8 +size 89445 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Own-Unsigned-Devices.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Own-Unsigned-Devices.png index 358918767..26ee5627d 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Own-Unsigned-Devices.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Own-Unsigned-Devices.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:12b9450065c9aa924ac7b833d2c98a8ea011ea3ec470438869f08591590a5576 -size 88346 +oid sha256:6383d2c6351a4833a6ce83a71c6c57c2297d3a8b19c2a818211e21ce61cb7c96 +size 99003 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Unencrypted.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Unencrypted.png index fa0bdd2c3..ee8f8bda2 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Unencrypted.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Unencrypted.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:05ae1dfcf89ec7c5329c570e29b876935d261470a6fc074d961452f75e4ab4e3 -size 81155 +oid sha256:b3068613a53a7634432c201ee51c5bd5e066d93a524019ee7f0b7c6b7199842b +size 92207 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Unknown-failure.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Unknown-failure.png index afc397109..8010c1fc2 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Unknown-failure.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Unknown-failure.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b1a6d6103056a883e4fa9344b65766867ef28355f359c428c6f8fc7b8a5b1dd4 -size 78383 +oid sha256:841d4f5f4f5a4e3eac938f2fcd4b0bb94561eebd6179c91cb84816f3ae7df8b8 +size 89445 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Unsigned-Devices.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Unsigned-Devices.png index b9a00d5ed..2eb251430 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Unsigned-Devices.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Unsigned-Devices.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:100ebc998da4d0625307771a9fda2dc78becccf2fe0e58cb514967cc26b77e46 -size 86917 +oid sha256:a0dac8094cdadc60b5bf9fb5057b910a51d34598ca207acedac4af329ebe61b3 +size 97569 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Unsigned.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Unsigned.png index eeb51c7cf..d84a6afc5 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Unsigned.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Unsigned.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5d2451f6dfdb5d0342c13d9bba95f035610649f5e0c6c026b6b5c02a3f5ea792 -size 84457 +oid sha256:f008b5f6b5015caa5102ee2e3368072b89dc8d369b43d229776b2c4d3a7ec119 +size 95442 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Authenticity.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Authenticity.png index 114f53c75..87fda90f0 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Authenticity.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Authenticity.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a7e0833f33a5372ac34cb1ffc904b3113c292ddfac1798f2ec49263f72487b8b -size 104147 +oid sha256:2214c2b47d33f7e71ebe4b113d8c57461977d0e5558b4851e54be67bfc613bc1 +size 120917 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Button-shapes.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Button-shapes.png index 7e06a52be..964cce30d 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Button-shapes.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Button-shapes.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9dd681b7005cad7f3172e46704ce15f35348741ab4f61c25c7e25dbc976dd47f -size 96872 +oid sha256:c0ca91f7036a9b588ae5cfaa98df46fad4a0c546a815646bcc93b60f5cc04b96 +size 114129 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Identity-Changed.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Identity-Changed.png index 1f8ad9ff3..50d2b28ef 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Identity-Changed.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Identity-Changed.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:66a515af35f86cc79842515e6f200a8ac9e66393bafa3d08dd73c94b55a0e273 -size 102463 +oid sha256:224c0a2a1a180bb0f769690986615b42670eaeba5da36c136a194a9b649392a4 +size 119359 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Media-with-Caption.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Media-with-Caption.png new file mode 100644 index 000000000..e3bf6ea23 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Media-with-Caption.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3ff91b2679413fe8a068f82306eeaa78de5db89edacc910443fd03a9200ac42c +size 111302 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Media.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Media.png new file mode 100644 index 000000000..b87398e00 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Media.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0f083235302db13e888d8c1fdd9cf6746acba7c6b25e6066f225514b78963bc7 +size 99585 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Normal.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Normal.png index cbf97d594..31e7b3339 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Normal.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Normal.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f9f354421510618dc4c3ebdd4ed3f6aeb274236bd4d680948127a21737882a35 -size 83970 +oid sha256:28feeb86b0c09df9a9bc37b3523adbd9145c24372ba3f0d1e46e3b7811d56339 +size 100926 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Own-Unsigned-Devices.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Own-Unsigned-Devices.png index 4d6d50c68..23c68ebfd 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Own-Unsigned-Devices.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Own-Unsigned-Devices.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:20be265e58a5ce19848a1d9c9221587656efbeb1eefa982bf598021ed91b1976 -size 104759 +oid sha256:68ba46257a66431778c6fd648be80e65bd724f451cc4bbd05a92c8dd6eca3ab3 +size 121585 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Unencrypted.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Unencrypted.png index d2ca600aa..28e552dc3 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Unencrypted.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Unencrypted.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bbcb5ce6d51e66aa74d7ebb6cdaf574a80613cf5cbc2a52285f2db5758a260c8 -size 88609 +oid sha256:4a3212f9f5ccb198f4bb9770ea232b700cf635a0a3d37ecb7b8297c0496c12f4 +size 105456 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Unknown-failure.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Unknown-failure.png index cbf97d594..31e7b3339 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Unknown-failure.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Unknown-failure.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f9f354421510618dc4c3ebdd4ed3f6aeb274236bd4d680948127a21737882a35 -size 83970 +oid sha256:28feeb86b0c09df9a9bc37b3523adbd9145c24372ba3f0d1e46e3b7811d56339 +size 100926 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Unsigned-Devices.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Unsigned-Devices.png index 37099ec4f..eb0e27434 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Unsigned-Devices.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Unsigned-Devices.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cb4cba6c55ed6d5a399729817e3bbcf0109e940022009ec2b994d744a0e26b9e -size 100765 +oid sha256:9e084c9628684fe7b383b72a2f5906e47f9d65ba2de12a374b728ece3be37c68 +size 117656 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Unsigned.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Unsigned.png index 5f247f202..80225d3ad 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Unsigned.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Unsigned.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e808c53766810d2cef79e239295f55b151a151cb42a7d7fd24f83ef889964ae1 -size 95987 +oid sha256:ec4a30d3db9d84514c116964209d741a6179b11c0992b0e92e9e98a8d5e050eb +size 112532