Remove layout styling abstraction (#2982)

This commit is contained in:
Mauro 2024-06-27 18:25:25 +02:00 committed by GitHub
parent 064b1bf224
commit b7345aafca
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 29 additions and 126 deletions

View File

@ -149,7 +149,6 @@ struct RoomScreenViewState: BindableState {
var typingMembers: [String] = [] var typingMembers: [String] = []
var showLoading = false var showLoading = false
var showReadReceipts = false var showReadReceipts = false
let timelineStyle = TimelineStyle.bubbles
var isEncryptedOneToOneRoom = false var isEncryptedOneToOneRoom = false
var timelineViewState: TimelineViewState // check the doc before changing this var timelineViewState: TimelineViewState // check the doc before changing this

View File

@ -87,7 +87,6 @@ struct RoomScreen: View {
TimelineView() TimelineView()
.id(context.viewState.roomID) .id(context.viewState.roomID)
.environmentObject(context) .environmentObject(context)
.environment(\.timelineStyle, context.viewState.timelineStyle)
.environment(\.focussedEventID, context.viewState.timelineViewState.focussedEvent?.eventID) .environment(\.focussedEventID, context.viewState.timelineViewState.focussedEvent?.eventID)
.overlay(alignment: .bottomTrailing) { .overlay(alignment: .bottomTrailing) {
scrollToBottomButton scrollToBottomButton

View File

@ -73,7 +73,7 @@ struct TimelineItemBubbledStylerView<Content: View>: View {
.padding(.leading, bubbleAvatarPadding) .padding(.leading, bubbleAvatarPadding)
} }
} }
.padding(TimelineStyle.bubbles.rowInsets) .padding(EdgeInsets(top: 1, leading: 8, bottom: 1, trailing: 8))
.highlightedTimelineItem(isFocussed) .highlightedTimelineItem(isFocussed)
} }
@ -532,7 +532,6 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview
} }
} }
} }
.environment(\.timelineStyle, .bubbles)
.environmentObject(viewModel.context) .environmentObject(viewModel.context)
} }

View File

@ -17,26 +17,6 @@
import Foundation import Foundation
import SwiftUI import SwiftUI
enum TimelineStyle: String, CaseIterable, Codable {
case bubbles
/// List row insets for a timeline
var rowInsets: EdgeInsets {
switch self {
case .bubbles:
return EdgeInsets(top: 1, leading: 8, bottom: 1, trailing: 8)
}
}
/// Short hand for `self == .bubbles`
var isBubbles: Bool {
switch self {
case .bubbles:
return true
}
}
}
enum TimelineGroupStyle: Hashable { enum TimelineGroupStyle: Hashable {
case single case single
case first case first
@ -55,20 +35,11 @@ enum TimelineGroupStyle: Hashable {
// MARK: - Environment // MARK: - Environment
private struct TimelineStyleKey: EnvironmentKey {
static let defaultValue = TimelineStyle.bubbles
}
private struct TimelineGroupStyleKey: EnvironmentKey { private struct TimelineGroupStyleKey: EnvironmentKey {
static let defaultValue = TimelineGroupStyle.single static let defaultValue = TimelineGroupStyle.single
} }
extension EnvironmentValues { extension EnvironmentValues {
var timelineStyle: TimelineStyle {
get { self[TimelineStyleKey.self] }
set { self[TimelineStyleKey.self] = newValue }
}
var timelineGroupStyle: TimelineGroupStyle { var timelineGroupStyle: TimelineGroupStyle {
get { self[TimelineGroupStyleKey.self] } get { self[TimelineGroupStyleKey.self] }
set { self[TimelineGroupStyleKey.self] = newValue } set { self[TimelineGroupStyleKey.self] = newValue }

View File

@ -20,8 +20,6 @@ import SwiftUI
// MARK: - TimelineStyler // MARK: - TimelineStyler
struct TimelineStyler<Content: View>: View { struct TimelineStyler<Content: View>: View {
@Environment(\.timelineStyle) private var style
let timelineItem: EventBasedTimelineItemProtocol let timelineItem: EventBasedTimelineItemProtocol
@ViewBuilder let content: () -> Content @ViewBuilder let content: () -> Content
@ -59,12 +57,9 @@ struct TimelineStyler<Content: View>: View {
@ViewBuilder @ViewBuilder
var mainContent: some View { var mainContent: some View {
switch style {
case .bubbles:
TimelineItemBubbledStylerView(timelineItem: timelineItem, adjustedDeliveryStatus: adjustedDeliveryStatus, content: content) TimelineItemBubbledStylerView(timelineItem: timelineItem, adjustedDeliveryStatus: adjustedDeliveryStatus, content: content)
} }
} }
}
struct TimelineItemStyler_Previews: PreviewProvider, TestablePreview { struct TimelineItemStyler_Previews: PreviewProvider, TestablePreview {
static let viewModel = RoomScreenViewModel.mock static let viewModel = RoomScreenViewModel.mock
@ -200,17 +195,14 @@ struct TimelineItemStyler_Previews: PreviewProvider, TestablePreview {
static var previews: some View { static var previews: some View {
testView testView
.environmentObject(viewModel.context) .environmentObject(viewModel.context)
.environment(\.timelineStyle, .bubbles)
.previewDisplayName("Bubbles") .previewDisplayName("Bubbles")
languagesTestView languagesTestView
.environmentObject(viewModel.context) .environmentObject(viewModel.context)
.environment(\.timelineStyle, .bubbles)
.previewDisplayName("Bubbles LTR with different layout languages") .previewDisplayName("Bubbles LTR with different layout languages")
languagesTestView languagesTestView
.environmentObject(viewModel.context) .environmentObject(viewModel.context)
.environment(\.timelineStyle, .bubbles)
.environment(\.layoutDirection, .rightToLeft) .environment(\.layoutDirection, .rightToLeft)
.previewDisplayName("Bubbles RTL with different layout languages") .previewDisplayName("Bubbles RTL with different layout languages")
} }

View File

@ -20,7 +20,6 @@ import SwiftUI
struct TimelineItemStatusView: View { struct TimelineItemStatusView: View {
let timelineItem: EventBasedTimelineItemProtocol let timelineItem: EventBasedTimelineItemProtocol
let adjustedDeliveryStatus: TimelineItemDeliveryStatus? let adjustedDeliveryStatus: TimelineItemDeliveryStatus?
@Environment(\.timelineStyle) private var style
@EnvironmentObject private var context: RoomScreenViewModel.Context @EnvironmentObject private var context: RoomScreenViewModel.Context
private var isLastOutgoingMessage: Bool { private var isLastOutgoingMessage: Bool {

View File

@ -18,15 +18,14 @@ import Foundation
import SwiftUI import SwiftUI
struct EmoteRoomTimelineView: View, TextBasedRoomTimelineViewProtocol { struct EmoteRoomTimelineView: View, TextBasedRoomTimelineViewProtocol {
@Environment(\.timelineStyle) var timelineStyle
let timelineItem: EmoteRoomTimelineItem let timelineItem: EmoteRoomTimelineItem
var body: some View { var body: some View {
TimelineStyler(timelineItem: timelineItem) { TimelineStyler(timelineItem: timelineItem) {
if let attributedString = timelineItem.content.formattedBody { if let attributedString = timelineItem.content.formattedBody {
FormattedBodyText(attributedString: attributedString, additionalWhitespacesCount: timelineItem.additionalWhitespaces(timelineStyle: timelineStyle)) FormattedBodyText(attributedString: attributedString, additionalWhitespacesCount: timelineItem.additionalWhitespaces())
} else { } else {
FormattedBodyText(text: timelineItem.content.body, additionalWhitespacesCount: timelineItem.additionalWhitespaces(timelineStyle: timelineStyle)) FormattedBodyText(text: timelineItem.content.body, additionalWhitespacesCount: timelineItem.additionalWhitespaces())
} }
} }
} }

View File

@ -44,8 +44,6 @@ struct EncryptedRoomTimelineView: View {
} }
struct RoomTimelineViewLabelStyle: LabelStyle { struct RoomTimelineViewLabelStyle: LabelStyle {
@Environment(\.timelineStyle) private var timelineStyle
func makeBody(configuration: Configuration) -> some View { func makeBody(configuration: Configuration) -> some View {
HStack(alignment: .center, spacing: 8) { HStack(alignment: .center, spacing: 8) {
configuration.icon configuration.icon
@ -53,7 +51,7 @@ struct RoomTimelineViewLabelStyle: LabelStyle {
configuration.title configuration.title
.foregroundColor(.compound.textPrimary) .foregroundColor(.compound.textPrimary)
} }
.padding(.horizontal, timelineStyle == .bubbles ? 4 : 0) .padding(.horizontal, 4)
} }
} }

View File

@ -17,7 +17,6 @@
import SwiftUI import SwiftUI
struct FormattedBodyText: View { struct FormattedBodyText: View {
@Environment(\.timelineStyle) private var timelineStyle
@Environment(\.layoutDirection) private var layoutDirection @Environment(\.layoutDirection) private var layoutDirection
private let attributedString: AttributedString private let attributedString: AttributedString
@ -81,17 +80,12 @@ struct FormattedBodyText: View {
@ViewBuilder @ViewBuilder
var mainContent: some View { var mainContent: some View {
if timelineStyle == .bubbles { layout
bubbleLayout
.tint(.compound.textLinkExternal) .tint(.compound.textLinkExternal)
} else {
plainLayout
.tint(.compound.textLinkExternal)
}
} }
/// The attributed components laid out for the bubbles timeline style. /// The attributed components laid out for the bubbles timeline style.
var bubbleLayout: some View { var layout: some View {
TimelineBubbleLayout(spacing: 8) { TimelineBubbleLayout(spacing: 8) {
ForEach(attributedComponents) { component in ForEach(attributedComponents) { component in
// Ignore if the string contains only the layout correction // Ignore if the string contains only the layout correction
@ -115,7 +109,7 @@ struct FormattedBodyText: View {
.layoutPriority(TimelineBubbleLayout.Priority.visibleQuote) .layoutPriority(TimelineBubbleLayout.Priority.visibleQuote)
} else { } else {
MessageText(attributedString: component.attributedString) MessageText(attributedString: component.attributedString)
.padding(.horizontal, timelineStyle == .bubbles ? 4 : 0) .padding(.horizontal, 4)
.fixedSize(horizontal: false, vertical: true) .fixedSize(horizontal: false, vertical: true)
.layoutPriority(TimelineBubbleLayout.Priority.regularText) .layoutPriority(TimelineBubbleLayout.Priority.regularText)
} }
@ -135,27 +129,6 @@ struct FormattedBodyText: View {
} }
} }
/// The attributed components laid out for the plain timeline style.
var plainLayout: some View {
VStack(alignment: .leading, spacing: 8.0) {
ForEach(attributedComponents) { component in
if component.isBlockquote {
HStack(spacing: 4.0) {
Rectangle()
.foregroundColor(Color.red)
.frame(width: 4.0)
MessageText(attributedString: component.attributedString)
}
.fixedSize(horizontal: false, vertical: true)
} else {
MessageText(attributedString: component.attributedString)
.padding(.horizontal, timelineStyle == .bubbles ? 4 : 0)
.fixedSize(horizontal: false, vertical: true)
}
}
}
}
private var blockquoteAttributes: AttributeContainer { private var blockquoteAttributes: AttributeContainer {
// The paragraph style removes the block style paragraph that the parser adds by default // The paragraph style removes the block style paragraph that the parser adds by default
// Set directly in the constructor to avoid `Conformance to 'Sendable'` warnings // Set directly in the constructor to avoid `Conformance to 'Sendable'` warnings
@ -246,13 +219,11 @@ struct FormattedBodyText_Previews: PreviewProvider, TestablePreview {
} }
private struct PreviewBubbleModifier: ViewModifier { private struct PreviewBubbleModifier: ViewModifier {
@Environment(\.timelineStyle) private var timelineStyle
func body(content: Content) -> some View { func body(content: Content) -> some View {
content content
.padding(timelineStyle == .bubbles ? 8 : 0) .padding(8)
.background(timelineStyle == .bubbles ? Color.compound._bgBubbleOutgoing : nil) .background(Color.compound._bgBubbleOutgoing)
.cornerRadius(timelineStyle == .bubbles ? 12 : 0) .cornerRadius(12)
.environmentObject(RoomScreenViewModel.mock.context) .environmentObject(RoomScreenViewModel.mock.context)
} }
} }

View File

@ -18,7 +18,6 @@ import SwiftUI
struct LocationRoomTimelineView: View { struct LocationRoomTimelineView: View {
let timelineItem: LocationRoomTimelineItem let timelineItem: LocationRoomTimelineItem
@Environment(\.timelineStyle) var timelineStyle
var body: some View { var body: some View {
TimelineStyler(timelineItem: timelineItem) { TimelineStyler(timelineItem: timelineItem) {
@ -43,7 +42,7 @@ struct LocationRoomTimelineView: View {
.clipped() .clipped()
} }
} else { } else {
FormattedBodyText(text: timelineItem.body, additionalWhitespacesCount: timelineItem.additionalWhitespaces(timelineStyle: timelineStyle)) FormattedBodyText(text: timelineItem.body, additionalWhitespacesCount: timelineItem.additionalWhitespaces())
} }
} }
@ -61,8 +60,7 @@ struct LocationRoomTimelineView: View {
private var descriptionView: some View { private var descriptionView: some View {
if let description = timelineItem.content.description, !description.isEmpty { if let description = timelineItem.content.description, !description.isEmpty {
FormattedBodyText(text: description) FormattedBodyText(text: description)
.padding(.vertical, 8) .padding(8)
.padding(.horizontal, timelineStyle.isBubbles ? 8 : 0)
} }
} }

View File

@ -19,7 +19,6 @@ import SwiftUI
struct NoticeRoomTimelineView: View, TextBasedRoomTimelineViewProtocol { struct NoticeRoomTimelineView: View, TextBasedRoomTimelineViewProtocol {
let timelineItem: NoticeRoomTimelineItem let timelineItem: NoticeRoomTimelineItem
@Environment(\.timelineStyle) var timelineStyle
var body: some View { var body: some View {
TimelineStyler(timelineItem: timelineItem) { TimelineStyler(timelineItem: timelineItem) {
@ -30,9 +29,9 @@ struct NoticeRoomTimelineView: View, TextBasedRoomTimelineViewProtocol {
Label { Label {
if let attributedString = timelineItem.content.formattedBody { if let attributedString = timelineItem.content.formattedBody {
FormattedBodyText(attributedString: attributedString, additionalWhitespacesCount: timelineItem.additionalWhitespaces(timelineStyle: timelineStyle)) FormattedBodyText(attributedString: attributedString, additionalWhitespacesCount: timelineItem.additionalWhitespaces())
} else { } else {
FormattedBodyText(text: timelineItem.content.body, additionalWhitespacesCount: timelineItem.additionalWhitespaces(timelineStyle: timelineStyle)) FormattedBodyText(text: timelineItem.content.body, additionalWhitespacesCount: timelineItem.additionalWhitespaces())
} }
} icon: { } icon: {
CompoundIcon(\.info, size: .small, relativeTo: .compound.bodyLG) CompoundIcon(\.info, size: .small, relativeTo: .compound.bodyLG)

View File

@ -54,32 +54,26 @@ struct PollRoomTimelineView_Previews: PreviewProvider, TestablePreview {
static var previews: some View { static var previews: some View {
PollRoomTimelineView(timelineItem: .mock(poll: .disclosed(), isOutgoing: false)) PollRoomTimelineView(timelineItem: .mock(poll: .disclosed(), isOutgoing: false))
.environment(\.timelineStyle, .bubbles)
.environmentObject(viewModel.context) .environmentObject(viewModel.context)
.previewDisplayName("Disclosed, Bubble") .previewDisplayName("Disclosed, Bubble")
PollRoomTimelineView(timelineItem: .mock(poll: .undisclosed(), isOutgoing: false)) PollRoomTimelineView(timelineItem: .mock(poll: .undisclosed(), isOutgoing: false))
.environment(\.timelineStyle, .bubbles)
.environmentObject(viewModel.context) .environmentObject(viewModel.context)
.previewDisplayName("Undisclosed, Bubble") .previewDisplayName("Undisclosed, Bubble")
PollRoomTimelineView(timelineItem: .mock(poll: .endedDisclosed)) PollRoomTimelineView(timelineItem: .mock(poll: .endedDisclosed))
.environment(\.timelineStyle, .bubbles)
.environmentObject(viewModel.context) .environmentObject(viewModel.context)
.previewDisplayName("Ended, Disclosed, Bubble") .previewDisplayName("Ended, Disclosed, Bubble")
PollRoomTimelineView(timelineItem: .mock(poll: .endedUndisclosed)) PollRoomTimelineView(timelineItem: .mock(poll: .endedUndisclosed))
.environment(\.timelineStyle, .bubbles)
.environmentObject(viewModel.context) .environmentObject(viewModel.context)
.previewDisplayName("Ended, Undisclosed, Bubble") .previewDisplayName("Ended, Undisclosed, Bubble")
PollRoomTimelineView(timelineItem: .mock(poll: .disclosed(createdByAccountOwner: true))) PollRoomTimelineView(timelineItem: .mock(poll: .disclosed(createdByAccountOwner: true)))
.environment(\.timelineStyle, .bubbles)
.environmentObject(viewModel.context) .environmentObject(viewModel.context)
.previewDisplayName("Creator, disclosed, Bubble") .previewDisplayName("Creator, disclosed, Bubble")
PollRoomTimelineView(timelineItem: .mock(poll: .emptyDisclosed, isEditable: true)) PollRoomTimelineView(timelineItem: .mock(poll: .emptyDisclosed, isEditable: true))
.environment(\.timelineStyle, .bubbles)
.environmentObject(viewModel.context) .environmentObject(viewModel.context)
.previewDisplayName("Creator, no votes, Bubble") .previewDisplayName("Creator, no votes, Bubble")
} }

View File

@ -19,5 +19,4 @@ protocol TextBasedRoomTimelineViewProtocol {
associatedtype TimelineItemType: TextBasedRoomTimelineItem associatedtype TimelineItemType: TextBasedRoomTimelineItem
var timelineItem: TimelineItemType { get } var timelineItem: TimelineItemType { get }
var timelineStyle: TimelineStyle { get }
} }

View File

@ -19,17 +19,16 @@ import SwiftUI
struct TextRoomTimelineView: View, TextBasedRoomTimelineViewProtocol { struct TextRoomTimelineView: View, TextBasedRoomTimelineViewProtocol {
let timelineItem: TextRoomTimelineItem let timelineItem: TextRoomTimelineItem
@Environment(\.timelineStyle) var timelineStyle
var body: some View { var body: some View {
TimelineStyler(timelineItem: timelineItem) { TimelineStyler(timelineItem: timelineItem) {
if let attributedString = timelineItem.content.formattedBody { if let attributedString = timelineItem.content.formattedBody {
FormattedBodyText(attributedString: attributedString, FormattedBodyText(attributedString: attributedString,
additionalWhitespacesCount: timelineItem.additionalWhitespaces(timelineStyle: timelineStyle), additionalWhitespacesCount: timelineItem.additionalWhitespaces(),
boostEmojiSize: true) boostEmojiSize: true)
} else { } else {
FormattedBodyText(text: timelineItem.body, FormattedBodyText(text: timelineItem.body,
additionalWhitespacesCount: timelineItem.additionalWhitespaces(timelineStyle: timelineStyle), additionalWhitespacesCount: timelineItem.additionalWhitespaces(),
boostEmojiSize: true) boostEmojiSize: true)
} }
} }

View File

@ -56,7 +56,6 @@ class TimelineTableViewController: UIViewController {
private let coordinator: TimelineView.Coordinator private let coordinator: TimelineView.Coordinator
private let tableView = UITableView(frame: .zero, style: .plain) private let tableView = UITableView(frame: .zero, style: .plain)
var timelineStyle: TimelineStyle
var timelineItemsDictionary = OrderedDictionary<String, RoomTimelineItemViewState>() { var timelineItemsDictionary = OrderedDictionary<String, RoomTimelineItemViewState>() {
didSet { didSet {
guard canApplySnapshot else { guard canApplySnapshot else {
@ -166,11 +165,9 @@ class TimelineTableViewController: UIViewController {
private var hasAppearedOnce = false private var hasAppearedOnce = false
init(coordinator: TimelineView.Coordinator, init(coordinator: TimelineView.Coordinator,
timelineStyle: TimelineStyle,
isScrolledToBottom: Binding<Bool>, isScrolledToBottom: Binding<Bool>,
scrollToBottomPublisher: PassthroughSubject<Void, Never>) { scrollToBottomPublisher: PassthroughSubject<Void, Never>) {
self.coordinator = coordinator self.coordinator = coordinator
self.timelineStyle = timelineStyle
_isScrolledToBottom = isScrolledToBottom _isScrolledToBottom = isScrolledToBottom
super.init(nibName: nil, bundle: nil) super.init(nibName: nil, bundle: nil)

View File

@ -20,18 +20,16 @@ import WysiwygComposer
/// A table view wrapper that displays the timeline of a room. /// A table view wrapper that displays the timeline of a room.
struct TimelineView: UIViewControllerRepresentable { struct TimelineView: UIViewControllerRepresentable {
@EnvironmentObject private var viewModelContext: RoomScreenViewModel.Context @EnvironmentObject private var viewModelContext: RoomScreenViewModel.Context
@Environment(\.timelineStyle) private var timelineStyle
func makeUIViewController(context: Context) -> TimelineTableViewController { func makeUIViewController(context: Context) -> TimelineTableViewController {
let tableViewController = TimelineTableViewController(coordinator: context.coordinator, let tableViewController = TimelineTableViewController(coordinator: context.coordinator,
timelineStyle: timelineStyle,
isScrolledToBottom: $viewModelContext.isScrolledToBottom, isScrolledToBottom: $viewModelContext.isScrolledToBottom,
scrollToBottomPublisher: viewModelContext.viewState.timelineViewState.scrollToBottomPublisher) scrollToBottomPublisher: viewModelContext.viewState.timelineViewState.scrollToBottomPublisher)
return tableViewController return tableViewController
} }
func updateUIViewController(_ uiViewController: TimelineTableViewController, context: Context) { func updateUIViewController(_ uiViewController: TimelineTableViewController, context: Context) {
context.coordinator.update(tableViewController: uiViewController, timelineStyle: timelineStyle) context.coordinator.update(tableViewController: uiViewController)
} }
func makeCoordinator() -> Coordinator { func makeCoordinator() -> Coordinator {
@ -49,14 +47,11 @@ struct TimelineView: UIViewControllerRepresentable {
} }
/// Updates the specified table view's properties from the current view state. /// Updates the specified table view's properties from the current view state.
func update(tableViewController: TimelineTableViewController, timelineStyle: TimelineStyle) { func update(tableViewController: TimelineTableViewController) {
if tableViewController.isSwitchingTimelines != context.viewState.timelineViewState.isSwitchingTimelines { if tableViewController.isSwitchingTimelines != context.viewState.timelineViewState.isSwitchingTimelines {
// Must come before timelineItemsDictionary in order to disable animations. // Must come before timelineItemsDictionary in order to disable animations.
tableViewController.isSwitchingTimelines = context.viewState.timelineViewState.isSwitchingTimelines tableViewController.isSwitchingTimelines = context.viewState.timelineViewState.isSwitchingTimelines
} }
if tableViewController.timelineStyle != timelineStyle {
tableViewController.timelineStyle = timelineStyle
}
if tableViewController.timelineItemsDictionary != context.viewState.timelineViewState.itemsDictionary { if tableViewController.timelineItemsDictionary != context.viewState.timelineViewState.itemsDictionary {
tableViewController.timelineItemsDictionary = context.viewState.timelineViewState.itemsDictionary tableViewController.timelineItemsDictionary = context.viewState.timelineViewState.itemsDictionary
} }

View File

@ -51,8 +51,7 @@ final class SettingsScreenCoordinator: CoordinatorProtocol {
// MARK: - Setup // MARK: - Setup
init(parameters: SettingsScreenCoordinatorParameters) { init(parameters: SettingsScreenCoordinatorParameters) {
viewModel = SettingsScreenViewModel(userSession: parameters.userSession, viewModel = SettingsScreenViewModel(userSession: parameters.userSession)
appSettings: parameters.appSettings)
viewModel.actions viewModel.actions
.sink { [weak self] action in .sink { [weak self] action in

View File

@ -26,7 +26,7 @@ class SettingsScreenViewModel: SettingsScreenViewModelType, SettingsScreenViewMo
actionsSubject.eraseToAnyPublisher() actionsSubject.eraseToAnyPublisher()
} }
init(userSession: UserSessionProtocol, appSettings: AppSettings) { init(userSession: UserSessionProtocol) {
super.init(initialViewState: .init(deviceID: userSession.clientProxy.deviceID, super.init(initialViewState: .init(deviceID: userSession.clientProxy.deviceID,
userID: userSession.clientProxy.userID, userID: userSession.clientProxy.userID,
showDeveloperOptions: AppSettings.isDevelopmentBuild), showDeveloperOptions: AppSettings.isDevelopmentBuild),

View File

@ -227,8 +227,7 @@ struct SettingsScreen_Previews: PreviewProvider, TestablePreview {
static let viewModel = { static let viewModel = {
let userSession = UserSessionMock(.init(clientProxy: ClientProxyMock(.init(userID: "@userid:example.com", let userSession = UserSessionMock(.init(clientProxy: ClientProxyMock(.init(userID: "@userid:example.com",
deviceID: "AAAAAAAAAAA")))) deviceID: "AAAAAAAAAAA"))))
return SettingsScreenViewModel(userSession: userSession, return SettingsScreenViewModel(userSession: userSession)
appSettings: ServiceLocator.shared.settings)
}() }()
static var previews: some View { static var previews: some View {

View File

@ -68,10 +68,7 @@ extension EventBasedTimelineItemProtocol {
} }
} }
func additionalWhitespaces(timelineStyle: TimelineStyle) -> Int { func additionalWhitespaces() -> Int {
guard timelineStyle == .bubbles else {
return 0
}
var whiteSpaces = 1 var whiteSpaces = 1
localizedSendInfo.forEach { _ in localizedSendInfo.forEach { _ in
whiteSpaces += 1 whiteSpaces += 1

View File

@ -28,7 +28,7 @@ class SettingsScreenViewModelTests: XCTestCase {
@MainActor override func setUpWithError() throws { @MainActor override func setUpWithError() throws {
cancellables.removeAll() cancellables.removeAll()
let userSession = UserSessionMock(.init(clientProxy: ClientProxyMock(.init(userID: "")))) let userSession = UserSessionMock(.init(clientProxy: ClientProxyMock(.init(userID: ""))))
viewModel = SettingsScreenViewModel(userSession: userSession, appSettings: ServiceLocator.shared.settings) viewModel = SettingsScreenViewModel(userSession: userSession)
context = viewModel.context context = viewModel.context
} }

View File

@ -28,7 +28,7 @@ final class TextBasedRoomTimelineTests: XCTestCase {
isThreaded: false, isThreaded: false,
sender: .init(id: UUID().uuidString), sender: .init(id: UUID().uuidString),
content: .init(body: "Test")) content: .init(body: "Test"))
XCTAssertEqual(timelineItem.additionalWhitespaces(timelineStyle: .bubbles), timestamp.count + 1) XCTAssertEqual(timelineItem.additionalWhitespaces(), timestamp.count + 1)
} }
func testTextRoomTimelineItemWhitespaceEndLonger() { func testTextRoomTimelineItemWhitespaceEndLonger() {
@ -41,7 +41,7 @@ final class TextBasedRoomTimelineTests: XCTestCase {
isThreaded: false, isThreaded: false,
sender: .init(id: UUID().uuidString), sender: .init(id: UUID().uuidString),
content: .init(body: "Test")) content: .init(body: "Test"))
XCTAssertEqual(timelineItem.additionalWhitespaces(timelineStyle: .bubbles), timestamp.count + 1) XCTAssertEqual(timelineItem.additionalWhitespaces(), timestamp.count + 1)
} }
func testTextRoomTimelineItemWhitespaceEndWithEdit() { func testTextRoomTimelineItemWhitespaceEndWithEdit() {
@ -56,7 +56,7 @@ final class TextBasedRoomTimelineTests: XCTestCase {
content: .init(body: "Test")) content: .init(body: "Test"))
timelineItem.properties.isEdited = true timelineItem.properties.isEdited = true
let editedCount = L10n.commonEditedSuffix.count let editedCount = L10n.commonEditedSuffix.count
XCTAssertEqual(timelineItem.additionalWhitespaces(timelineStyle: .bubbles), timestamp.count + editedCount + 2) XCTAssertEqual(timelineItem.additionalWhitespaces(), timestamp.count + editedCount + 2)
} }
func testTextRoomTimelineItemWhitespaceEndWithEditAndAlert() { func testTextRoomTimelineItemWhitespaceEndWithEditAndAlert() {
@ -72,6 +72,6 @@ final class TextBasedRoomTimelineTests: XCTestCase {
timelineItem.properties.isEdited = true timelineItem.properties.isEdited = true
timelineItem.properties.deliveryStatus = .sendingFailed timelineItem.properties.deliveryStatus = .sendingFailed
let editedCount = L10n.commonEditedSuffix.count let editedCount = L10n.commonEditedSuffix.count
XCTAssertEqual(timelineItem.additionalWhitespaces(timelineStyle: .bubbles), timestamp.count + editedCount + 5) XCTAssertEqual(timelineItem.additionalWhitespaces(), timestamp.count + editedCount + 5)
} }
} }