Rework the presentation of the media browser quick look view to use SwiftUI. (#3619)
* Embed the media preview quick look inside a full screen cover With a zoom transition on iOS 18. * Use a the representable coordinator properly. * Fix a bug with the toolbar appearance. * Format * Try prevent the zoom transition being upside down. * Fix the snapshot test configuration.
This commit is contained in:
@@ -11,6 +11,8 @@ import SwiftUI
|
||||
struct MediaEventsTimelineScreen: View {
|
||||
@ObservedObject var context: MediaEventsTimelineScreenViewModel.Context
|
||||
|
||||
@Namespace private var zoomTransition
|
||||
|
||||
var body: some View {
|
||||
mainContent
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
@@ -30,7 +32,6 @@ struct MediaEventsTimelineScreen: View {
|
||||
.pickerStyle(.segmented)
|
||||
}
|
||||
}
|
||||
.timelineMediaQuickLook(viewModel: $context.mediaPreviewViewModel)
|
||||
.environmentObject(context.viewState.activeTimelineContextProvider())
|
||||
.environment(\.timelineContext, context.viewState.activeTimelineContextProvider())
|
||||
}
|
||||
@@ -39,7 +40,7 @@ struct MediaEventsTimelineScreen: View {
|
||||
// * flip the scrollView vertically to keep the items
|
||||
// at the bottom and have pagination working properly
|
||||
// * flip the grid vertically to counteract the scroll view
|
||||
// but also horizontally to preserve the corect item order
|
||||
// but also horizontally to preserve the correct item order
|
||||
// * flip the items on both axes have them render correctly
|
||||
@ViewBuilder
|
||||
private var mainContent: some View {
|
||||
@@ -73,7 +74,7 @@ struct MediaEventsTimelineScreen: View {
|
||||
Section {
|
||||
ForEach(group.items) { item in
|
||||
Button {
|
||||
context.send(viewAction: .tappedItem(item))
|
||||
tappedItem(item)
|
||||
} label: {
|
||||
Color.clear // Let the image aspect fill in place
|
||||
.aspectRatio(1, contentMode: .fill)
|
||||
@@ -81,8 +82,9 @@ struct MediaEventsTimelineScreen: View {
|
||||
viewForTimelineItem(item)
|
||||
}
|
||||
.clipped()
|
||||
.scaleEffect(.init(width: -1, height: -1))
|
||||
.scaleEffect(scale(for: item, isGridLayout: true))
|
||||
}
|
||||
.zoomTransitionSource(id: item.identifier, in: zoomTransition)
|
||||
}
|
||||
} footer: {
|
||||
// Use a footer as the header because the scrollView is flipped
|
||||
@@ -104,11 +106,12 @@ struct MediaEventsTimelineScreen: View {
|
||||
Divider()
|
||||
|
||||
Button {
|
||||
context.send(viewAction: .tappedItem(item))
|
||||
tappedItem(item)
|
||||
} label: {
|
||||
viewForTimelineItem(item)
|
||||
.scaleEffect(.init(width: 1, height: -1))
|
||||
.scaleEffect(scale(for: item, isGridLayout: false))
|
||||
}
|
||||
.zoomTransitionSource(id: item.identifier, in: zoomTransition)
|
||||
}
|
||||
.padding(.horizontal, 16)
|
||||
}
|
||||
@@ -207,6 +210,19 @@ struct MediaEventsTimelineScreen: View {
|
||||
.multilineTextAlignment(.center)
|
||||
}
|
||||
}
|
||||
|
||||
func tappedItem(_ item: RoomTimelineItemViewState) {
|
||||
context.send(viewAction: .tappedItem(item: item, namespace: zoomTransition))
|
||||
}
|
||||
|
||||
func scale(for item: RoomTimelineItemViewState, isGridLayout: Bool) -> CGSize {
|
||||
guard item.identifier != context.viewState.currentPreviewItemID else {
|
||||
// Remove the flip when presenting a preview so that the zoom transition is the right way up 🙃
|
||||
return CGSize(width: 1, height: 1)
|
||||
}
|
||||
|
||||
return CGSize(width: isGridLayout ? -1 : 1, height: -1)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Previews
|
||||
|
||||
Reference in New Issue
Block a user