Configure the media preview screen based on the event and presentation. (#3604)

* Configure media previews based on the presenting screen.

* Switch on TimelineKind instead of having an isPinnedEventsTimeline Bool.
This commit is contained in:
Doug
2024-12-11 15:40:31 +00:00
committed by GitHub
parent 9856e3e5b4
commit c827ab9165
35 changed files with 334 additions and 242 deletions
@@ -345,7 +345,7 @@ struct TimelineItemMenu_Previews: PreviewProvider, TestablePreview {
isDM: true,
isViewSourceEnabled: true,
isCreateMediaCaptionsEnabled: true,
isPinnedEventsTimeline: false,
timelineKind: .live,
emojiProvider: EmojiProvider(appSettings: ServiceLocator.shared.settings))
guard let actions = provider.makeActions() else { return nil }
@@ -82,9 +82,9 @@ enum TimelineItemMenuAction: Identifiable, Hashable {
var switchToDefaultComposer: Bool {
switch self {
case .reply, .edit, .addCaption, .editCaption, .editPoll:
return false
false
default:
return true
true
}
}
@@ -92,9 +92,9 @@ enum TimelineItemMenuAction: Identifiable, Hashable {
var canAppearInFailedEcho: Bool {
switch self {
case .copy, .edit, .redact, .viewSource, .editPoll:
return true
true
default:
return false
false
}
}
@@ -102,9 +102,9 @@ enum TimelineItemMenuAction: Identifiable, Hashable {
var canAppearInRedacted: Bool {
switch self {
case .viewSource, .unpin, .viewInRoomTimeline:
return true
true
default:
return false
false
}
}
@@ -112,18 +112,27 @@ enum TimelineItemMenuAction: Identifiable, Hashable {
var isDestructive: Bool {
switch self {
case .redact, .report, .removeCaption:
return true
true
default:
return false
false
}
}
var canAppearInPinnedEventsTimeline: Bool {
switch self {
case .viewInRoomTimeline, .pin, .unpin, .forward:
return true
true
default:
return false
false
}
}
var canAppearInMediaDetails: Bool {
switch self {
case .viewInRoomTimeline, .redact:
true
default:
false
}
}
@@ -17,7 +17,7 @@ struct TimelineItemMenuActionProvider {
let isDM: Bool
let isViewSourceEnabled: Bool
let isCreateMediaCaptionsEnabled: Bool
let isPinnedEventsTimeline: Bool
let timelineKind: TimelineKind
let emojiProvider: EmojiProviderProtocol
// swiftlint:disable:next cyclomatic_complexity
@@ -38,6 +38,10 @@ struct TimelineItemMenuActionProvider {
var actions: [TimelineItemMenuAction] = []
var secondaryActions: [TimelineItemMenuAction] = []
if timelineKind == .pinned || timelineKind == .media(.mediaFilesScreen) {
actions.append(.viewInRoomTimeline)
}
if item.canBeRepliedTo {
if let messageItem = item as? EventBasedMessageTimelineItemProtocol {
@@ -99,10 +103,15 @@ struct TimelineItemMenuActionProvider {
secondaryActions.append(.redact)
}
if isPinnedEventsTimeline {
actions.insert(.viewInRoomTimeline, at: 0)
switch timelineKind {
case .pinned:
actions = actions.filter(\.canAppearInPinnedEventsTimeline)
secondaryActions = secondaryActions.filter(\.canAppearInPinnedEventsTimeline)
case .media:
actions = actions.filter(\.canAppearInMediaDetails)
secondaryActions = secondaryActions.filter(\.canAppearInMediaDetails)
case .live, .detached:
break // viewInRoomTimeline is the only non-room item and was added conditionally.
}
if item.hasFailedToSend {
@@ -114,11 +123,10 @@ struct TimelineItemMenuActionProvider {
actions = actions.filter(\.canAppearInRedacted)
secondaryActions = secondaryActions.filter(\.canAppearInRedacted)
}
let isReactable = timelineKind == .live || timelineKind == .detached ? item.isReactable : false
return .init(isReactable: isPinnedEventsTimeline ? false : item.isReactable,
actions: actions,
secondaryActions: secondaryActions,
emojiProvider: emojiProvider)
return .init(isReactable: isReactable, actions: actions, secondaryActions: secondaryActions, emojiProvider: emojiProvider)
}
private func makeEncryptedItemActions(_ encryptedItem: EncryptedRoomTimelineItem) -> TimelineItemMenuActions? {
@@ -20,7 +20,7 @@ struct TimelineItemBubbledStylerView<Content: View>: View {
private var isEncryptedOneToOneRoom: Bool { context.viewState.isEncryptedOneToOneRoom }
private var isFocussed: Bool { focussedEventID != nil && timelineItem.id.eventID == focussedEventID }
private var isPinned: Bool {
guard !context.viewState.isPinnedEventsTimeline,
guard context.viewState.timelineKind != .pinned,
let eventID = timelineItem.id.eventID else {
return false
}
@@ -110,7 +110,7 @@ struct TimelineItemBubbledStylerView<Content: View>: View {
}
// Do not display reactions in the pinned events timeline
if !context.viewState.isPinnedEventsTimeline,
if context.viewState.timelineKind != .pinned,
!timelineItem.properties.reactions.isEmpty {
TimelineReactionsView(context: context,
itemID: timelineItem.id,
@@ -150,7 +150,7 @@ struct TimelineItemBubbledStylerView<Content: View>: View {
isDM: context.viewState.isEncryptedOneToOneRoom,
isViewSourceEnabled: context.viewState.isViewSourceEnabled,
isCreateMediaCaptionsEnabled: context.viewState.isCreateMediaCaptionsEnabled,
isPinnedEventsTimeline: context.viewState.isPinnedEventsTimeline,
timelineKind: context.viewState.timelineKind,
emojiProvider: context.viewState.emojiProvider)
TimelineItemMacContextMenu(item: timelineItem, actionProvider: provider) { action in
context.send(viewAction: .handleTimelineItemMenuAction(itemID: timelineItem.id, action: action))
@@ -23,7 +23,7 @@ struct TimelineItemStatusView: View {
@ViewBuilder
private var mainContent: some View {
if context.viewState.isPinnedEventsTimeline {
if context.viewState.timelineKind == .pinned {
// Do not display any status when is a pinned events timeline
EmptyView()
} else if context.viewState.showReadReceipts, !timelineItem.properties.orderedReadReceipts.isEmpty {
@@ -12,7 +12,7 @@ struct PollRoomTimelineView: View {
@EnvironmentObject private var context: TimelineViewModel.Context
private var state: PollViewState {
if context.viewState.isPinnedEventsTimeline {
if context.viewState.timelineKind == .pinned {
return .preview
} else {
return .full(isEditable: timelineItem.isEditable)
@@ -51,7 +51,7 @@ struct PollRoomTimelineView: View {
struct PollRoomTimelineView_Previews: PreviewProvider, TestablePreview {
static let viewModel = TimelineViewModel.mock
static let pinnedEventsTimelineViewModel = TimelineViewModel.pinnedEventsTimelineMock
static let pinnedEventsTimelineViewModel = TimelineViewModel.mock(timelineKind: .pinned)
static var previews: some View {
PollRoomTimelineView(timelineItem: .mock(poll: .disclosed(), isOutgoing: false))