mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 16:10:20 +00:00
SwiftUI timeline refactor + TimelineViewState decoupling (#1392)
* swiftUI conversion + scroll to bottom * remove unused * back pagination implemented, however when a lot of elements are in the scroll the perfomance diminishes not sure what may be causing it * scroll adapter solution * way better * works but height animation in cells are broken * code improvement * everything implemented * rebase fix * fix * doc * fix test compilation * code improvement and animation improvement * code improvement * code improvements * tests updated. * pr comments * better identifiers * fix * some PR comments * pr comments
This commit is contained in:
@@ -16,17 +16,27 @@
|
||||
import SwiftUI
|
||||
|
||||
struct RoomTimelineItemView: View {
|
||||
@ObservedObject var viewModel: RoomTimelineItemViewModel
|
||||
@EnvironmentObject private var context: RoomScreenViewModel.Context
|
||||
let viewState: RoomTimelineItemViewState
|
||||
|
||||
var body: some View {
|
||||
timelineView
|
||||
.environment(\.timelineGroupStyle, viewModel.groupStyle)
|
||||
.animation(.elementDefault, value: viewModel.type)
|
||||
.animation(.elementDefault, value: viewModel.groupStyle)
|
||||
.environmentObject(context)
|
||||
.environment(\.timelineGroupStyle, viewState.groupStyle)
|
||||
.onAppear {
|
||||
context.send(viewAction: .itemAppeared(itemID: viewState.identifier))
|
||||
}
|
||||
.onDisappear {
|
||||
context.send(viewAction: .itemDisappeared(itemID: viewState.identifier))
|
||||
}
|
||||
.environment(\.openURL, OpenURLAction { url in
|
||||
context.send(viewAction: .linkClicked(url: url))
|
||||
return .systemAction
|
||||
})
|
||||
}
|
||||
|
||||
@ViewBuilder private var timelineView: some View {
|
||||
switch viewModel.type {
|
||||
switch viewState.type {
|
||||
case .text(let item):
|
||||
TextRoomTimelineView(timelineItem: item)
|
||||
case .separator(let item):
|
||||
@@ -69,6 +79,6 @@ struct RoomTimelineItemView: View {
|
||||
}
|
||||
|
||||
var timelineGroupStyle: TimelineGroupStyle {
|
||||
viewModel.groupStyle
|
||||
viewState.groupStyle
|
||||
}
|
||||
}
|
||||
|
||||
+14
-15
@@ -16,25 +16,18 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
final class RoomTimelineItemViewModel: Identifiable, Equatable, ObservableObject {
|
||||
static func == (lhs: RoomTimelineItemViewModel, rhs: RoomTimelineItemViewModel) -> Bool {
|
||||
lhs.type == rhs.type && lhs.groupStyle == rhs.groupStyle
|
||||
}
|
||||
struct RoomTimelineItemViewState: Identifiable, Equatable {
|
||||
let type: RoomTimelineItemType
|
||||
let groupStyle: TimelineGroupStyle
|
||||
|
||||
@Published var type: RoomTimelineItemType
|
||||
@Published var groupStyle: TimelineGroupStyle
|
||||
|
||||
var id: TimelineItemIdentifier {
|
||||
/// Contains all the identification info of the item, `timelineID`, `eventID` and `transactionID`
|
||||
var identifier: TimelineItemIdentifier {
|
||||
type.id
|
||||
}
|
||||
|
||||
convenience init(item: RoomTimelineItemProtocol, groupStyle: TimelineGroupStyle) {
|
||||
self.init(type: .init(item: item), groupStyle: groupStyle)
|
||||
}
|
||||
|
||||
init(type: RoomTimelineItemType, groupStyle: TimelineGroupStyle) {
|
||||
self.type = type
|
||||
self.groupStyle = groupStyle
|
||||
/// The `timelineID` of the item, used for the timeline view level identification, do not use for any business logic use `identifier` instead
|
||||
var id: String {
|
||||
identifier.timelineID
|
||||
}
|
||||
|
||||
var isReactable: Bool {
|
||||
@@ -42,6 +35,12 @@ final class RoomTimelineItemViewModel: Identifiable, Equatable, ObservableObject
|
||||
}
|
||||
}
|
||||
|
||||
extension RoomTimelineItemViewState {
|
||||
init(item: RoomTimelineItemProtocol, groupStyle: TimelineGroupStyle) {
|
||||
self.init(type: .init(item: item), groupStyle: groupStyle)
|
||||
}
|
||||
}
|
||||
|
||||
enum RoomTimelineItemType: Equatable {
|
||||
case text(TextRoomTimelineItem)
|
||||
case separator(SeparatorRoomTimelineItem)
|
||||
Reference in New Issue
Block a user