mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 06:55:59 +00:00
Introduced the RoomTimelineViewProvider with different timeline items/views. Added timeline date separators (currently breaks back pagination)
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
//
|
||||
// ImageRoomTimelineItem.swift
|
||||
// ElementX
|
||||
//
|
||||
// Created by Stefan Ceriu on 11/03/2022.
|
||||
// Copyright © 2022 Element. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct ImageRoomTimelineItem: Identifiable, Equatable {
|
||||
let id: String
|
||||
let text: String
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// ImageRoomTimelineView.swift
|
||||
// ElementX
|
||||
//
|
||||
// Created by Stefan Ceriu on 11/03/2022.
|
||||
// Copyright © 2022 Element. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
|
||||
struct ImageRoomTimelineView: View {
|
||||
let timelineItem: ImageRoomTimelineItem
|
||||
var loadedImage: UIImage?
|
||||
|
||||
var body: some View {
|
||||
if let loadedImage = loadedImage {
|
||||
Image(uiImage: loadedImage)
|
||||
} else {
|
||||
ProgressView()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
//
|
||||
// TextRoomTimelineItem.swift
|
||||
// ElementX
|
||||
//
|
||||
// Created by Stefan Ceriu on 04.03.2022.
|
||||
// Copyright © 2022 Element. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
|
||||
private var dateFormatter: DateFormatter = {
|
||||
let dateFormatter = DateFormatter()
|
||||
dateFormatter.dateStyle = .none
|
||||
dateFormatter.timeStyle = .short
|
||||
return dateFormatter
|
||||
}()
|
||||
|
||||
enum RoomTimelineItem: Identifiable, Equatable {
|
||||
case text(id: String, senderDisplayName: String, text: String, originServerTs: Date, shouldShowSenderDetails: Bool)
|
||||
case sectionTitle(id: String, text: String)
|
||||
|
||||
var id: String {
|
||||
switch self {
|
||||
case .text(let id, _, _, _, _):
|
||||
return id
|
||||
case .sectionTitle(let id, _):
|
||||
return id
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension RoomTimelineItem: View {
|
||||
var body: some View {
|
||||
switch self {
|
||||
case .text(let id, let senderDisplayName, let text, let originServerTs, let shouldShowSenderDetails):
|
||||
VStack(alignment: .leading) {
|
||||
if shouldShowSenderDetails {
|
||||
HStack {
|
||||
Text(senderDisplayName)
|
||||
.font(.footnote)
|
||||
.bold()
|
||||
Spacer()
|
||||
Text(dateFormatter.string(from: originServerTs))
|
||||
.font(.footnote)
|
||||
}
|
||||
Divider()
|
||||
Spacer()
|
||||
}
|
||||
Text(text)
|
||||
}
|
||||
.listRowSeparator(.hidden)
|
||||
.id(id)
|
||||
case .sectionTitle(let id, let text):
|
||||
LabelledDivider(label: text)
|
||||
.id(id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct LabelledDivider: View {
|
||||
|
||||
let label: String
|
||||
let color: Color
|
||||
|
||||
init(label: String, color: Color = .gray) {
|
||||
self.label = label
|
||||
self.color = color
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
HStack {
|
||||
line
|
||||
Text(label)
|
||||
.foregroundColor(color)
|
||||
.fixedSize()
|
||||
line
|
||||
}
|
||||
}
|
||||
|
||||
var line: some View {
|
||||
VStack { Divider().background(color) }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
//
|
||||
// TextRoomTimelineItem.swift
|
||||
// ElementX
|
||||
//
|
||||
// Created by Stefan Ceriu on 04.03.2022.
|
||||
// Copyright © 2022 Element. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
|
||||
enum RoomTimelineViewProvider: Identifiable, Equatable {
|
||||
case text(TextRoomTimelineItem)
|
||||
case separator(SeparatorRoomTimelineItem)
|
||||
case image(ImageRoomTimelineItem)
|
||||
|
||||
var id: String {
|
||||
switch self {
|
||||
case .text(let item):
|
||||
return item.id
|
||||
case .separator(let item):
|
||||
return item.id
|
||||
case .image(let item):
|
||||
return item.id
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension RoomTimelineViewProvider: View {
|
||||
@ViewBuilder var body: some View {
|
||||
switch self {
|
||||
case .text(let item):
|
||||
TextRoomTimelineView(timelineItem: item)
|
||||
case .separator(let item):
|
||||
SeparatorRoomTimelineView(timelineItem: item)
|
||||
case .image(let item):
|
||||
ImageRoomTimelineView(timelineItem: item)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
//
|
||||
// SectionSeparatorTimelineItem.swift
|
||||
// ElementX
|
||||
//
|
||||
// Created by Stefan Ceriu on 11/03/2022.
|
||||
// Copyright © 2022 Element. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct SeparatorRoomTimelineItem: Identifiable, Equatable {
|
||||
let id: String
|
||||
let text: String
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
//
|
||||
// SeparatorRoomTimelineView.swift
|
||||
// ElementX
|
||||
//
|
||||
// Created by Stefan Ceriu on 11/03/2022.
|
||||
// Copyright © 2022 Element. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
|
||||
struct SeparatorRoomTimelineView: View {
|
||||
let timelineItem: SeparatorRoomTimelineItem
|
||||
|
||||
var body: some View {
|
||||
LabelledDivider(label: timelineItem.text)
|
||||
.id(timelineItem.id)
|
||||
}
|
||||
}
|
||||
|
||||
struct LabelledDivider: View {
|
||||
let label: String
|
||||
let color: Color
|
||||
|
||||
init(label: String, color: Color = .gray) {
|
||||
self.label = label
|
||||
self.color = color
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
HStack {
|
||||
line
|
||||
Text(label)
|
||||
.foregroundColor(color)
|
||||
.fixedSize()
|
||||
line
|
||||
}
|
||||
}
|
||||
|
||||
var line: some View {
|
||||
VStack { Divider().background(color) }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
//
|
||||
// TextRoomTimelineItem.swift
|
||||
// ElementX
|
||||
//
|
||||
// Created by Stefan Ceriu on 11/03/2022.
|
||||
// Copyright © 2022 Element. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct TextRoomTimelineItem: Identifiable, Equatable {
|
||||
let id: String
|
||||
let senderDisplayName: String
|
||||
let text: String
|
||||
let timestamp: String
|
||||
let shouldShowSenderDetails: Bool
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
//
|
||||
// TextRoomTimelineView.swift
|
||||
// ElementX
|
||||
//
|
||||
// Created by Stefan Ceriu on 11/03/2022.
|
||||
// Copyright © 2022 Element. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
|
||||
struct TextRoomTimelineView: View {
|
||||
let timelineItem: TextRoomTimelineItem
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading) {
|
||||
if timelineItem.shouldShowSenderDetails {
|
||||
HStack {
|
||||
Text(timelineItem.senderDisplayName)
|
||||
.font(.footnote)
|
||||
.bold()
|
||||
Spacer()
|
||||
Text(timelineItem.timestamp)
|
||||
.font(.footnote)
|
||||
}
|
||||
Divider()
|
||||
Spacer()
|
||||
}
|
||||
Text(timelineItem.text)
|
||||
}
|
||||
.id(timelineItem.id)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user