Skip to content

Commit

Permalink
Add timeline day separators and read markers (#383)
Browse files Browse the repository at this point in the history
* Add timeline day separators and read markers
  • Loading branch information
stefanceriu authored Dec 21, 2022
1 parent a9f2e1b commit 131197b
Show file tree
Hide file tree
Showing 10 changed files with 113 additions and 29 deletions.
49 changes: 24 additions & 25 deletions ElementX.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 51;
objectVersion = 54;
objects = {

/* Begin PBXBuildFile section */
Expand Down Expand Up @@ -56,6 +56,8 @@
165A883C29998EC779465068 /* SoftLogoutViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BC38904A9663F7FAFD47457 /* SoftLogoutViewModelProtocol.swift */; };
1702981A8085BE4FB0EC001B /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = D33116993D54FADC0C721C1F /* Application.swift */; };
172E6E9A612ADCF10A62CF13 /* BugReportServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A68BCE6438873D2661D93D0 /* BugReportServiceProtocol.swift */; };
1833A04F2953249E009AA2AE /* ReadMarkerRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1833A04E2953249E009AA2AE /* ReadMarkerRoomTimelineView.swift */; };
1833A051295324B8009AA2AE /* ReadMarkerRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1833A050295324B8009AA2AE /* ReadMarkerRoomTimelineItem.swift */; };
187E18F21EF4DA244E436E58 /* BugReportViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28959C7DB36C7688A01D4045 /* BugReportViewModelProtocol.swift */; };
191161FE9E0DA89704301F37 /* Untranslated.strings in Resources */ = {isa = PBXBuildFile; fileRef = D2F7194F440375338F8E2487 /* Untranslated.strings */; };
1950A80CD198BED283DFC2CE /* ClientProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2958E6D247AE2516BEEE8 /* ClientProxy.swift */; };
Expand Down Expand Up @@ -564,7 +566,6 @@
1215A4FC53D2319E81AE8970 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
1222DB76B917EB8A55365BA5 /* target.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = target.yml; sourceTree = "<group>"; };
124D85E85505B6B81845235F /* fy */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = fy; path = fy.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
12A626D74BBE9F4A60763B45 /* ImageAnonymizer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageAnonymizer.swift; sourceTree = "<group>"; };
130ED565A078F7E0B59D9D25 /* UNTextInputNotificationResponse+Creator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UNTextInputNotificationResponse+Creator.swift"; sourceTree = "<group>"; };
13802897C7AFA360EA74C0B0 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = en.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
1423AB065857FA546444DB15 /* NotificationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationManager.swift; sourceTree = "<group>"; };
Expand All @@ -574,6 +575,8 @@
1715E3D7F53C0748AA50C91C /* PostHogAnalyticsClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostHogAnalyticsClient.swift; sourceTree = "<group>"; };
1734A445A58ED855B977A0A8 /* TracingConfigurationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TracingConfigurationTests.swift; sourceTree = "<group>"; };
179423E34EE846E048E49CBF /* MediaSourceProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaSourceProxy.swift; sourceTree = "<group>"; };
1833A04E2953249E009AA2AE /* ReadMarkerRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadMarkerRoomTimelineView.swift; sourceTree = "<group>"; };
1833A050295324B8009AA2AE /* ReadMarkerRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadMarkerRoomTimelineItem.swift; sourceTree = "<group>"; };
184CF8C196BE143AE226628D /* DecorationTimelineItemProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DecorationTimelineItemProtocol.swift; sourceTree = "<group>"; };
18F2958E6D247AE2516BEEE8 /* ClientProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientProxy.swift; sourceTree = "<group>"; };
18FE0CDF1FFA92EA7EE17B0B /* RoomTimelineControllerFactoryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineControllerFactoryProtocol.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -792,7 +795,7 @@
8D6094DEAAEB388E1AE118C6 /* MockRoomTimelineProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockRoomTimelineProvider.swift; sourceTree = "<group>"; };
8D8169443E5AC5FF71BFB3DB /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/Localizable.strings; sourceTree = "<group>"; };
8DC2C9E0E15C79BBDA80F0A2 /* TimelineStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineStyle.swift; sourceTree = "<group>"; };
8E088F2A1B9EC529D3221931 /* UITests.xctestplan */ = {isa = PBXFileReference; path = UITests.xctestplan; sourceTree = "<group>"; };
8E088F2A1B9EC529D3221931 /* UITests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = UITests.xctestplan; sourceTree = "<group>"; };
8ED2D2F6A137A95EA50413BE /* UserNotificationControllerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserNotificationControllerProtocol.swift; sourceTree = "<group>"; };
8F7D42E66E939B709C1EC390 /* MockRoomSummaryProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockRoomSummaryProvider.swift; sourceTree = "<group>"; };
8FC26871038FB0E4AAE22605 /* apple_emojis_data.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = apple_emojis_data.json; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1002,7 +1005,7 @@
EBE5502760CF6CA2D7201883 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ja; path = ja.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
ED044D00F2176681CC02CD54 /* HomeScreenRoomCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenRoomCell.swift; sourceTree = "<group>"; };
ED1D792EB82506A19A72C8DE /* RoomTimelineItemProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineItemProtocol.swift; sourceTree = "<group>"; };
ED482057AE39D5C6D9C5F3D8 /* message.caf */ = {isa = PBXFileReference; path = message.caf; sourceTree = "<group>"; };
ED482057AE39D5C6D9C5F3D8 /* message.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = message.caf; sourceTree = "<group>"; };
EDAA4472821985BF868CC21C /* ServerSelectionViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerSelectionViewModelTests.swift; sourceTree = "<group>"; };
EDB6E40BAD4504D899FAAC9A /* TemplateViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateViewModel.swift; sourceTree = "<group>"; };
EE8BCD14EFED23459A43FDFF /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/Localizable.strings; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1724,6 +1727,7 @@
A1ED7E89865201EE7D53E6DA /* SeparatorRoomTimelineItem.swift */,
F6A8C632CEF4600107792899 /* TextRoomTimelineItem.swift */,
A4B5B19A10D3F7C2BC5315DF /* VideoRoomTimelineItem.swift */,
1833A050295324B8009AA2AE /* ReadMarkerRoomTimelineItem.swift */,
);
path = Items;
sourceTree = "<group>";
Expand Down Expand Up @@ -1802,6 +1806,18 @@
path = View;
sourceTree = "<group>";
};
7B29CA1D663299262BEADF24 /* RoomDetails */ = {
isa = PBXGroup;
children = (
813B198AE8833FD12E5A9C78 /* RoomDetailsCoordinator.swift */,
DEC031D32CED2CBE122E5038 /* RoomDetailsModels.swift */,
91FB6F5ECCF51ECE98ACFEEC /* RoomDetailsViewModel.swift */,
87B3A76EA6AB67910C11330F /* RoomDetailsViewModelProtocol.swift */,
9A67E5629C207A43043FAF20 /* View */,
);
path = RoomDetails;
sourceTree = "<group>";
};
7DBC911559934065993A5FF4 /* NotificationManager */ = {
isa = PBXGroup;
children = (
Expand All @@ -1815,18 +1831,6 @@
path = NotificationManager;
sourceTree = "<group>";
};
7B29CA1D663299262BEADF24 /* RoomDetails */ = {
isa = PBXGroup;
children = (
813B198AE8833FD12E5A9C78 /* RoomDetailsCoordinator.swift */,
DEC031D32CED2CBE122E5038 /* RoomDetailsModels.swift */,
91FB6F5ECCF51ECE98ACFEEC /* RoomDetailsViewModel.swift */,
87B3A76EA6AB67910C11330F /* RoomDetailsViewModelProtocol.swift */,
9A67E5629C207A43043FAF20 /* View */,
);
path = RoomDetails;
sourceTree = "<group>";
};
8039515BAA53B7C3275AC64A /* Client */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -2134,6 +2138,7 @@
0950733DD4BA83EEE752E259 /* PlaceholderAvatarImage.swift */,
C8F2A7A4E3F5060F52ACFFB0 /* RedactedRoomTimelineView.swift */,
6390A6DC140CA3D6865A66FF /* SeparatorRoomTimelineView.swift */,
1833A04E2953249E009AA2AE /* ReadMarkerRoomTimelineView.swift */,
F9E785D5137510481733A3E8 /* TextRoomTimelineView.swift */,
1941C8817E6B6971BA4415F5 /* VideoRoomTimelineView.swift */,
);
Expand Down Expand Up @@ -2295,7 +2300,6 @@
4009BE2E791C16AC6EE39A7E /* BugReport */,
F5A65D1D3B83593598DC278D /* EmojiPickerScreen */,
B442FCF47E0A6F28D7D50A4D /* FilePreview */,
FC26FB522EDED4965C5325F0 /* Folder */,
B53CA9BECD3F97805E1432D0 /* HomeScreen */,
3F38EAC92E2281990E65DAF2 /* OnboardingScreen */,
A448A3A8F764174C60CD0CA1 /* Other */,
Expand Down Expand Up @@ -2379,13 +2383,6 @@
path = EmojiPickerScreen;
sourceTree = "<group>";
};
FC26FB522EDED4965C5325F0 /* Folder */ = {
isa = PBXGroup;
children = (
);
path = Folder;
sourceTree = "<group>";
};
FCDF06BDB123505F0334B4F9 /* Timeline */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -2934,6 +2931,7 @@
38546A6010A2CF240EC9AF73 /* BindableState.swift in Sources */,
B6DF6B6FA8734B70F9BF261E /* BlurHashDecode.swift in Sources */,
A32517FB1CA0BBCE2BC75249 /* BugReportCoordinator.swift in Sources */,
1833A04F2953249E009AA2AE /* ReadMarkerRoomTimelineView.swift in Sources */,
00F3059B1E0CFCA019710C3E /* BugReportModels.swift in Sources */,
3588F34D05B4D731A73214C6 /* BugReportScreen.swift in Sources */,
3DA57CA0D609A6B37CA1DC2F /* BugReportService.swift in Sources */,
Expand Down Expand Up @@ -3142,6 +3140,7 @@
43FD77998F33C32718C51450 /* TemplateCoordinator.swift in Sources */,
63C9AF0FB8278AF1C0388A0C /* TemplateModels.swift in Sources */,
1555A7643D85187D4851040C /* TemplateScreen.swift in Sources */,
1833A051295324B8009AA2AE /* ReadMarkerRoomTimelineItem.swift in Sources */,
75EA4ABBFAA810AFF289D6F4 /* TemplateViewModel.swift in Sources */,
5F1FDE49DFD0C680386E48F9 /* TemplateViewModelProtocol.swift in Sources */,
D85D4FA590305180B4A41795 /* Tests.swift in Sources */,
Expand Down Expand Up @@ -3884,7 +3883,7 @@
repositoryURL = "https://github.com/matrix-org/matrix-rust-components-swift";
requirement = {
kind = exactVersion;
version = "1.0.22-alpha";
version = "1.0.23-alpha";
};
};
96495DD8554E2F39D3954354 /* XCRemoteSwiftPackageReference "posthog-ios" */ = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/matrix-org/matrix-rust-components-swift",
"state" : {
"revision" : "65d6f8a51367d5c411c1fec39402907f588fcd67",
"version" : "1.0.22-alpha"
"revision" : "f0144bd5faec80c8dbafac7686249893cff2de52",
"version" : "1.0.23-alpha"
}
},
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//
// Copyright 2022 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 Foundation
import SwiftUI

struct ReadMarkerRoomTimelineView: View {
let timelineItem: ReadMarkerRoomTimelineItem

var body: some View {
VStack {
Spacer(minLength: 4.0)
Divider()
.id(timelineItem.id)
.frame(maxWidth: .infinity)
.overlay(Color.element.accent)
}
}
}

struct ReadMarkerRoomTimelineView_Previews: PreviewProvider {
static var previews: some View {
let item = ReadMarkerRoomTimelineItem(id: UUID().uuidString)
ReadMarkerRoomTimelineView(timelineItem: item)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ struct SeparatorRoomTimelineView: View {
.font(.element.footnote)
.foregroundColor(.element.secondaryContent)
.id(timelineItem.id)
.padding(.vertical, 8)
.padding(.vertical, 24)
.frame(maxWidth: .infinity)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,22 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
case .event(let eventItem):
newTimelineItems.append(timelineItemFactory.buildTimelineItemFor(eventItemProxy: eventItem,
inGroupState: inGroupState))
case .virtual(let virtualItem):
switch virtualItem {
case .dayDivider(let year, let month, let day):
// These components will be replaced by a timestamp in upcoming releases
let dateComponents = DateComponents(calendar: .current, year: Int(year), month: Int(month), day: Int(day))
if let dateString = dateComponents.date?.formatted(date: .complete, time: .omitted) {
newTimelineItems.append(SeparatorRoomTimelineItem(id: UUID().uuidString, text: dateString))
} else {
MXLog.error("Failed formatting separator date")
}
case .readMarker:
// Don't show the read marker if it's the last item in the timeline
if index != timelineProvider.itemsPublisher.value.indices.last {
newTimelineItems.append(ReadMarkerRoomTimelineItem(id: UUID().uuidString))
}
}
default:
break
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//
// Copyright 2022 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 Foundation

struct ReadMarkerRoomTimelineItem: DecorationTimelineItemProtocol, Identifiable, Hashable {
let id: String
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import Foundation

struct RoomTimelineViewFactory: RoomTimelineViewFactoryProtocol {
// swiftlint:disable:next cyclomatic_complexity
func buildTimelineViewFor(timelineItem: RoomTimelineItemProtocol) -> RoomTimelineViewProvider {
switch timelineItem {
case let item as TextRoomTimelineItem:
Expand All @@ -37,6 +38,8 @@ struct RoomTimelineViewFactory: RoomTimelineViewFactoryProtocol {
return .redacted(item)
case let item as EncryptedRoomTimelineItem:
return .encrypted(item)
case let item as ReadMarkerRoomTimelineItem:
return .readMarker(item)
default:
fatalError("Unknown timeline item")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ enum RoomTimelineViewProvider: Identifiable, Hashable {
case notice(NoticeRoomTimelineItem)
case redacted(RedactedRoomTimelineItem)
case encrypted(EncryptedRoomTimelineItem)
case readMarker(ReadMarkerRoomTimelineItem)
case backPaginationIndicator(Bool)

var id: String {
Expand All @@ -49,6 +50,8 @@ enum RoomTimelineViewProvider: Identifiable, Hashable {
return item.id
case .encrypted(let item):
return item.id
case .readMarker(let item):
return item.id
case .backPaginationIndicator:
return "BackpaginationLoadingIndicator"
}
Expand Down Expand Up @@ -76,6 +79,8 @@ extension RoomTimelineViewProvider: View {
RedactedRoomTimelineView(timelineItem: item)
case .encrypted(let item):
EncryptedRoomTimelineView(timelineItem: item)
case .readMarker(let item):
ReadMarkerRoomTimelineView(timelineItem: item)
case .backPaginationIndicator(let isBackPaginating):
ProgressView()
.frame(maxWidth: .infinity)
Expand Down
1 change: 1 addition & 0 deletions changelog.d/pr-383.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added timeline day separators and read markers
2 changes: 1 addition & 1 deletion project.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ include:
packages:
MatrixRustSDK:
url: https://github.com/matrix-org/matrix-rust-components-swift
exactVersion: 1.0.22-alpha
exactVersion: 1.0.23-alpha
# path: ../matrix-rust-sdk
DesignKit:
path: ./
Expand Down

0 comments on commit 131197b

Please sign in to comment.