Fix the media gallery's empty state showing up at wrong times.
This commit is contained in:
committed by
Stefan Ceriu
parent
ee24764b08
commit
ffad834cd3
@@ -29,4 +29,9 @@ extension View {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
func mediaGalleryTimelineAspectRatio(imageInfo: ImageInfoProxy?) -> some View {
|
||||
aspectRatio(imageInfo?.aspectRatio, contentMode: .fill)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ struct MediaEventsTimelineGroup: Identifiable {
|
||||
}
|
||||
|
||||
struct MediaEventsTimelineScreenViewState: BindableState {
|
||||
var hasReachedTimelineStart = false
|
||||
var isBackPaginating = false
|
||||
var groups = [MediaEventsTimelineGroup]()
|
||||
|
||||
@@ -31,6 +32,10 @@ struct MediaEventsTimelineScreenViewState: BindableState {
|
||||
var bindings: MediaEventsTimelineScreenViewStateBindings
|
||||
|
||||
var currentPreviewItemID: TimelineItemIdentifier?
|
||||
|
||||
var shouldShowEmptyState: Bool {
|
||||
groups.isEmpty && hasReachedTimelineStart
|
||||
}
|
||||
}
|
||||
|
||||
struct MediaEventsTimelineScreenViewStateBindings {
|
||||
|
||||
@@ -36,13 +36,13 @@ class MediaEventsTimelineScreenViewModel: MediaEventsTimelineScreenViewModelType
|
||||
init(mediaTimelineViewModel: TimelineViewModelProtocol,
|
||||
filesTimelineViewModel: TimelineViewModelProtocol,
|
||||
mediaProvider: MediaProviderProtocol,
|
||||
screenMode: MediaEventsTimelineScreenMode = .media,
|
||||
initialViewState: MediaEventsTimelineScreenViewState = .init(bindings: .init(screenMode: .media)),
|
||||
userIndicatorController: UserIndicatorControllerProtocol) {
|
||||
self.mediaTimelineViewModel = mediaTimelineViewModel
|
||||
self.filesTimelineViewModel = filesTimelineViewModel
|
||||
self.userIndicatorController = userIndicatorController
|
||||
|
||||
super.init(initialViewState: .init(bindings: .init(screenMode: screenMode)), mediaProvider: mediaProvider)
|
||||
super.init(initialViewState: initialViewState, mediaProvider: mediaProvider)
|
||||
|
||||
state.activeTimelineContextProvider = { [weak self] in
|
||||
guard let self else { fatalError() }
|
||||
@@ -131,6 +131,7 @@ class MediaEventsTimelineScreenViewModel: MediaEventsTimelineScreenViewModelType
|
||||
state.groups = newGroups
|
||||
|
||||
state.isBackPaginating = (timelineViewState.timelineState.paginationState.backward == .paginating)
|
||||
// state.hasReachedTimelineStart = (timelineViewState.timelineState.paginationState.backward == .timelineEndReached)
|
||||
backPaginateIfNecessary(paginationStatus: timelineViewState.timelineState.paginationState.backward)
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,9 @@ struct MediaEventsTimelineScreen: View {
|
||||
}
|
||||
.environmentObject(context.viewState.activeTimelineContextProvider())
|
||||
.environment(\.timelineContext, context.viewState.activeTimelineContextProvider())
|
||||
.onChange(of: context.screenMode) { _, _ in
|
||||
context.send(viewAction: .changedScreenMode)
|
||||
}
|
||||
}
|
||||
|
||||
// The scale effects do the following:
|
||||
@@ -44,7 +47,7 @@ struct MediaEventsTimelineScreen: View {
|
||||
// * flip the items on both axes have them render correctly
|
||||
@ViewBuilder
|
||||
private var mainContent: some View {
|
||||
if context.viewState.groups.isEmpty, !context.viewState.isBackPaginating {
|
||||
if context.viewState.shouldShowEmptyState {
|
||||
emptyState
|
||||
} else {
|
||||
ScrollView {
|
||||
@@ -60,9 +63,6 @@ struct MediaEventsTimelineScreen: View {
|
||||
}
|
||||
}
|
||||
.scaleEffect(.init(width: 1, height: -1))
|
||||
.onChange(of: context.screenMode) { _, _ in
|
||||
context.send(viewAction: .changedScreenMode)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,12 +76,7 @@ struct MediaEventsTimelineScreen: View {
|
||||
Button {
|
||||
tappedItem(item)
|
||||
} label: {
|
||||
Color.clear // Let the image aspect fill in place
|
||||
.aspectRatio(1, contentMode: .fill)
|
||||
.overlay {
|
||||
viewForTimelineItem(item)
|
||||
}
|
||||
.clipped()
|
||||
viewForTimelineItem(item)
|
||||
.scaleEffect(scale(for: item, isGridLayout: true))
|
||||
}
|
||||
.zoomTransitionSource(id: item.identifier, in: zoomTransition)
|
||||
@@ -260,7 +255,8 @@ struct MediaEventsTimelineScreen_Previews: PreviewProvider, TestablePreview {
|
||||
MediaEventsTimelineScreenViewModel(mediaTimelineViewModel: makeTimelineViewModel(timelineKind: timelineKind),
|
||||
filesTimelineViewModel: makeTimelineViewModel(timelineKind: timelineKind),
|
||||
mediaProvider: MediaProviderMock(configuration: .init()),
|
||||
screenMode: screenMode,
|
||||
initialViewState: .init(hasReachedTimelineStart: true,
|
||||
bindings: .init(screenMode: screenMode)),
|
||||
userIndicatorController: UserIndicatorControllerMock())
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,12 @@ struct ImageMediaEventsTimelineView: View {
|
||||
let timelineItem: ImageRoomTimelineItem
|
||||
|
||||
var body: some View {
|
||||
loadableImage
|
||||
Color.clear // Let the image aspect fill in place
|
||||
.aspectRatio(1, contentMode: .fill)
|
||||
.overlay {
|
||||
loadableImage
|
||||
}
|
||||
.clipped()
|
||||
.accessibilityElement(children: .ignore)
|
||||
.accessibilityLabel(L10n.commonImage)
|
||||
}
|
||||
@@ -48,13 +53,6 @@ struct ImageMediaEventsTimelineView: View {
|
||||
}
|
||||
}
|
||||
|
||||
private extension View {
|
||||
@ViewBuilder
|
||||
func mediaGalleryTimelineAspectRatio(imageInfo: ImageInfoProxy?) -> some View {
|
||||
aspectRatio(imageInfo?.aspectRatio, contentMode: .fill)
|
||||
}
|
||||
}
|
||||
|
||||
struct ImageMediaEventsTimelineView_Previews: PreviewProvider, TestablePreview {
|
||||
static let viewModel = TimelineViewModel.mock
|
||||
|
||||
|
||||
@@ -13,7 +13,13 @@ struct VideoMediaEventsTimelineView: View {
|
||||
let timelineItem: VideoRoomTimelineItem
|
||||
|
||||
var body: some View {
|
||||
thumbnail
|
||||
Color.clear // Let the image aspect fill in place
|
||||
.aspectRatio(1, contentMode: .fill)
|
||||
.overlay {
|
||||
thumbnail
|
||||
}
|
||||
.clipped()
|
||||
.overlay(alignment: .bottom) { overlay }
|
||||
.accessibilityElement(children: .ignore)
|
||||
.accessibilityLabel(L10n.commonVideo)
|
||||
}
|
||||
@@ -25,23 +31,30 @@ struct VideoMediaEventsTimelineView: View {
|
||||
mediaType: .timelineItem(uniqueID: timelineItem.id.uniqueID.id),
|
||||
blurhash: timelineItem.content.blurhash,
|
||||
size: timelineItem.content.thumbnailInfo?.size,
|
||||
mediaProvider: context?.mediaProvider) { imageView in
|
||||
imageView
|
||||
.overlay { playIcon }
|
||||
} placeholder: {
|
||||
mediaProvider: context?.mediaProvider) {
|
||||
placeholder
|
||||
}
|
||||
.mediaGalleryTimelineAspectRatio(imageInfo: timelineItem.content.thumbnailInfo)
|
||||
} else {
|
||||
playIcon
|
||||
overlay
|
||||
}
|
||||
}
|
||||
|
||||
var playIcon: some View {
|
||||
Image(systemName: "play.circle.fill")
|
||||
.resizable()
|
||||
.frame(width: 50, height: 50)
|
||||
.background(.ultraThinMaterial, in: Circle())
|
||||
.foregroundColor(.white)
|
||||
var overlay: some View {
|
||||
HStack(spacing: 0) {
|
||||
CompoundIcon(\.videoCallSolid)
|
||||
Spacer()
|
||||
Text(Date(timeIntervalSince1970: timelineItem.content.videoInfo.duration).formattedTime())
|
||||
}
|
||||
.padding(8)
|
||||
.background {
|
||||
LinearGradient(stops: [.init(color: .clear, location: 0.0),
|
||||
.init(color: .compound.bgCanvasDefault, location: 1.0)],
|
||||
startPoint: .top,
|
||||
endPoint: .bottom)
|
||||
}
|
||||
.font(.compound.bodyXSSemibold)
|
||||
.foregroundStyle(.compound.textPrimary)
|
||||
}
|
||||
|
||||
var placeholder: some View {
|
||||
|
||||
@@ -36,18 +36,20 @@ class MockRoomTimelineController: RoomTimelineControllerProtocol {
|
||||
|
||||
init(timelineKind: TimelineKind = .live, listenForSignals: Bool = false) {
|
||||
self.timelineKind = timelineKind
|
||||
paginationState = PaginationState(backward: .idle, forward: .timelineEndReached)
|
||||
callbacks.send(.isLive(true))
|
||||
|
||||
switch timelineKind {
|
||||
case .media:
|
||||
paginationState = PaginationState(backward: .timelineEndReached, forward: .timelineEndReached)
|
||||
timelineItems = (0..<5).reduce([]) { partialResult, _ in
|
||||
partialResult + [RoomTimelineItemFixtures.separator] + RoomTimelineItemFixtures.mediaChunk
|
||||
}
|
||||
default:
|
||||
break
|
||||
paginationState = PaginationState(backward: .idle, forward: .timelineEndReached)
|
||||
}
|
||||
|
||||
callbacks.send(.paginationState(paginationState))
|
||||
callbacks.send(.isLive(true))
|
||||
|
||||
guard listenForSignals else { return }
|
||||
|
||||
do {
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:3e66d65ca577aa31e708a19e92ee3686b73a2fc9179c9dbad65c67c3a41a9ede
|
||||
size 113146
|
||||
oid sha256:cdee3d600b60fdbd1a4ee024a32fcb96aa1acede48816ac44fea31dd6f98b2e0
|
||||
size 95367
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:3e66d65ca577aa31e708a19e92ee3686b73a2fc9179c9dbad65c67c3a41a9ede
|
||||
size 113146
|
||||
oid sha256:cdee3d600b60fdbd1a4ee024a32fcb96aa1acede48816ac44fea31dd6f98b2e0
|
||||
size 95367
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:64e70e20286ebc6bbf25f0d93e4043b7113284a41ce96ab701c61a83b249ac18
|
||||
size 98920
|
||||
oid sha256:cc9a10f0defb81ffc49b373264d7a427a4586d00d2953474ed52d4750d0cced2
|
||||
size 83265
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:64e70e20286ebc6bbf25f0d93e4043b7113284a41ce96ab701c61a83b249ac18
|
||||
size 98920
|
||||
oid sha256:cc9a10f0defb81ffc49b373264d7a427a4586d00d2953474ed52d4750d0cced2
|
||||
size 83265
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:22b56f65c9574b55043aa8a7593065a075b253268bfb6e1cf4d5588375efcf98
|
||||
size 723194
|
||||
oid sha256:812ec06c83ea2c361241ea77163a23156a22ee4535ed50ab86e1f5aec130e342
|
||||
size 779101
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:fc265e69d1938da9a7550fa049e4456d06c88aec5bf007613b2c2b896186d993
|
||||
size 730597
|
||||
oid sha256:47e5e4eb18390da554bb8a6ce643eb7ee9d677d4b98235874de95e1ac484b19b
|
||||
size 781617
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:86b5bf6112dde6e9de73e5e2b9268346f023bd959f4a07fde51ccaaf4ea6f31e
|
||||
size 803264
|
||||
oid sha256:5f0a4d5ae4dc218dc9a24f0cf7f73c71f99fc9cc2c62e20b7d1bba7d949a273c
|
||||
size 857546
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:b26928f0fb0f4e536909ecac7166a0e1cc6606dfeddb0e6b373a0fdd8ba94fac
|
||||
size 809016
|
||||
oid sha256:177b94dea4f1fc4eead6438dfc9dcf94ad5b1f1c209660691aa587e8c6a2dd11
|
||||
size 862850
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:463ae69de9a5919702d8d4561ad18f87d5cf32461b5e8fbd015f38710dc9cbfa
|
||||
size 110192
|
||||
oid sha256:ed840d795c1c117436307a02af3668cfd0091d9831572b5d0724acf34290a962
|
||||
size 119624
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:463ae69de9a5919702d8d4561ad18f87d5cf32461b5e8fbd015f38710dc9cbfa
|
||||
size 110192
|
||||
oid sha256:9a44591168a07d0e590384b128045159dbf9707b89c9e3cac462857770ba215b
|
||||
size 119534
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e8327696e387d06deb4a44651894a5ffee31a024093e1dfbebb99f704601991e
|
||||
size 100670
|
||||
oid sha256:8a1a9ad985d1fdbb5bcbfda1f1a0987cdea236759b5905cdc63abc45a4ec35f3
|
||||
size 109469
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e8327696e387d06deb4a44651894a5ffee31a024093e1dfbebb99f704601991e
|
||||
size 100670
|
||||
oid sha256:1001b44cee3b02729073c1ee91a41872b5eca901dd09a414e2e05ed63b412cf0
|
||||
size 109394
|
||||
|
||||
Reference in New Issue
Block a user