RoomScreenViewModel is now TimelineViewModel (#3157)

Co-authored-by: Stefan Ceriu <stefanc@matrix.org>
This commit is contained in:
Mauro
2024-08-13 13:36:40 +02:00
committed by GitHub
parent 4519275559
commit 1ad361a6e8
88 changed files with 2266 additions and 1973 deletions
@@ -0,0 +1,87 @@
//
// Copyright 2023 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import SwiftUI
struct ReadReceiptCell: View {
let readReceipt: ReadReceipt
let memberState: RoomMemberState?
let imageProvider: ImageProviderProtocol?
private var title: String {
memberState?.displayName ?? readReceipt.userID
}
private var subtitle: String {
guard title != readReceipt.userID else {
return ""
}
return readReceipt.userID
}
var body: some View {
HStack(spacing: 12) {
LoadableAvatarImage(url: memberState?.avatarURL,
name: memberState?.displayName,
contentID: readReceipt.userID,
avatarSize: .user(on: .readReceiptSheet),
imageProvider: imageProvider)
VStack(alignment: .leading, spacing: 0) {
HStack(spacing: 12) {
Text(title)
.font(.compound.bodyMDSemibold)
.foregroundColor(.compound.textPrimary)
.lineLimit(1)
.frame(maxWidth: .infinity, alignment: .leading)
if let formattedTimestamp = readReceipt.formattedTimestamp {
Text(formattedTimestamp)
.font(.compound.bodyXS)
.foregroundColor(.compound.textSecondary)
.lineLimit(1)
}
}
Text(subtitle)
.font(.compound.bodySM)
.foregroundColor(.compound.textSecondary)
.lineLimit(1)
}
}
.padding(.vertical, 8)
.padding(.horizontal, 16)
}
}
struct ReadReceiptCell_Previews: PreviewProvider, TestablePreview {
static var previews: some View {
ReadReceiptCell(readReceipt: .init(userID: "@test:matrix.org",
formattedTimestamp: "10:00"),
memberState: .init(displayName: "Test",
avatarURL: nil),
imageProvider: MockMediaProvider())
.previewDisplayName("No Image")
ReadReceiptCell(readReceipt: .init(userID: "@test:matrix.org",
formattedTimestamp: "10:00"),
memberState: .init(displayName: "Test",
avatarURL: URL.documentsDirectory),
imageProvider: MockMediaProvider())
.previewDisplayName("With Image")
ReadReceiptCell(readReceipt: .init(userID: "@test:matrix.org",
formattedTimestamp: "10:00"),
memberState: nil,
imageProvider: MockMediaProvider())
.previewDisplayName("Loading Member")
}
}
@@ -0,0 +1,79 @@
//
// Copyright 2023 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import SwiftUI
struct ReadReceiptsSummaryView: View {
let orderedReadReceipts: [ReadReceipt]
@EnvironmentObject private var context: TimelineViewModel.Context
var body: some View {
VStack(alignment: .leading, spacing: 16) {
Text(L10n.commonSeenBy)
.font(.compound.bodyLGSemibold)
.foregroundColor(.compound.textPrimary)
.padding(.horizontal, 16)
ScrollView {
LazyVStack(spacing: 0) {
ForEach(orderedReadReceipts) { receipt in
ReadReceiptCell(readReceipt: receipt,
memberState: context.viewState.members[receipt.userID],
imageProvider: context.imageProvider)
}
}
}
}
.padding(.top, 24)
.presentationDetents([.medium, .large])
.presentationBackground(Color.compound.bgCanvasDefault)
.presentationDragIndicator(.visible)
}
}
struct ReadReceiptsSummaryView_Previews: PreviewProvider, TestablePreview {
static let viewModel = {
let members: [RoomMemberProxyMock] = [
.mockAlice,
.mockBob,
.mockCharlie,
.mockDan
]
let roomProxyMock = RoomProxyMock(.init(name: "Room", members: members))
let mock = TimelineViewModel(roomProxy: roomProxyMock,
timelineController: MockRoomTimelineController(),
mediaProvider: MockMediaProvider(),
mediaPlayerProvider: MediaPlayerProviderMock(),
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
userIndicatorController: UserIndicatorControllerMock(),
appMediator: AppMediatorMock.default,
appSettings: ServiceLocator.shared.settings,
analyticsService: ServiceLocator.shared.analytics)
return mock
}()
static let orderedReadReceipts: [ReadReceipt] = [
.init(userID: "@alice:matrix.org", formattedTimestamp: "10:00"),
.init(userID: "@bob:matrix.org", formattedTimestamp: "9:30"),
.init(userID: "@charlie:matrix.org", formattedTimestamp: "9:00"),
.init(userID: "@dan:matrix.org", formattedTimestamp: "8:30"),
.init(userID: "@loading:matrix.org", formattedTimestamp: "Long time ago")
]
static var previews: some View {
ReadReceiptsSummaryView(orderedReadReceipts: orderedReadReceipts)
.environmentObject(viewModel.context)
}
}