mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 16:10:20 +00:00
pr suggestions
This commit is contained in:
@@ -876,7 +876,7 @@
|
|||||||
A6FFC4C5154C446BAD6B40D8 /* TimelineItemProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8520AFD6680CBAD388F6D927 /* TimelineItemProvider.swift */; };
|
A6FFC4C5154C446BAD6B40D8 /* TimelineItemProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8520AFD6680CBAD388F6D927 /* TimelineItemProvider.swift */; };
|
||||||
A722F426FD81FC67706BB1E0 /* CustomLayoutLabelStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42236480CF0431535EBE8387 /* CustomLayoutLabelStyle.swift */; };
|
A722F426FD81FC67706BB1E0 /* CustomLayoutLabelStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42236480CF0431535EBE8387 /* CustomLayoutLabelStyle.swift */; };
|
||||||
A74438ED16F8683A4B793E6A /* AnalyticsSettingsScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BCE3FAF40932AC7C7639AC4 /* AnalyticsSettingsScreenViewModel.swift */; };
|
A74438ED16F8683A4B793E6A /* AnalyticsSettingsScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BCE3FAF40932AC7C7639AC4 /* AnalyticsSettingsScreenViewModel.swift */; };
|
||||||
A7CA45942DEF306400300A02 /* Highlight.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7CA45932DEF306200300A02 /* Highlight.swift */; };
|
A7CA45942DEF306400300A02 /* HorizontalHighlightGradient.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7CA45932DEF306200300A02 /* HorizontalHighlightGradient.swift */; };
|
||||||
A7D48E44D485B143AADDB77D /* Strings+Untranslated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A18F6CE4D694D21E4EA9B25 /* Strings+Untranslated.swift */; };
|
A7D48E44D485B143AADDB77D /* Strings+Untranslated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A18F6CE4D694D21E4EA9B25 /* Strings+Untranslated.swift */; };
|
||||||
A808DC3F72D15C6C5A52317E /* TimelineItemDebugView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCDA016D05107DED3B9495CB /* TimelineItemDebugView.swift */; };
|
A808DC3F72D15C6C5A52317E /* TimelineItemDebugView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCDA016D05107DED3B9495CB /* TimelineItemDebugView.swift */; };
|
||||||
A816F7087C495D85048AC50E /* RoomMemberDetailsScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B6E30BB748F3F480F077969 /* RoomMemberDetailsScreenModels.swift */; };
|
A816F7087C495D85048AC50E /* RoomMemberDetailsScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B6E30BB748F3F480F077969 /* RoomMemberDetailsScreenModels.swift */; };
|
||||||
@@ -2185,7 +2185,7 @@
|
|||||||
A7978C9EFBDD7DE39BD86726 /* RestorationTokenTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RestorationTokenTests.swift; sourceTree = "<group>"; };
|
A7978C9EFBDD7DE39BD86726 /* RestorationTokenTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RestorationTokenTests.swift; sourceTree = "<group>"; };
|
||||||
A7A1B80FE6E3BA72F9C748AD /* AdvancedSettingsScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdvancedSettingsScreenViewModel.swift; sourceTree = "<group>"; };
|
A7A1B80FE6E3BA72F9C748AD /* AdvancedSettingsScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdvancedSettingsScreenViewModel.swift; sourceTree = "<group>"; };
|
||||||
A7C4EA55DA62F9D0F984A2AE /* CollapsibleTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollapsibleTimelineItem.swift; sourceTree = "<group>"; };
|
A7C4EA55DA62F9D0F984A2AE /* CollapsibleTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollapsibleTimelineItem.swift; sourceTree = "<group>"; };
|
||||||
A7CA45932DEF306200300A02 /* Highlight.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Highlight.swift; sourceTree = "<group>"; };
|
A7CA45932DEF306200300A02 /* HorizontalHighlightGradient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HorizontalHighlightGradient.swift; sourceTree = "<group>"; };
|
||||||
A7D452AF7B5F7E3A0A7DB54C /* SessionVerificationScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
A7D452AF7B5F7E3A0A7DB54C /* SessionVerificationScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
A7E37072597F67C4DD8CC2DB /* ComposerDraftServiceProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposerDraftServiceProtocol.swift; sourceTree = "<group>"; };
|
A7E37072597F67C4DD8CC2DB /* ComposerDraftServiceProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposerDraftServiceProtocol.swift; sourceTree = "<group>"; };
|
||||||
A84D413BF49F0E980F010A6B /* LogViewerScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogViewerScreenCoordinator.swift; sourceTree = "<group>"; };
|
A84D413BF49F0E980F010A6B /* LogViewerScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogViewerScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||||
@@ -3329,7 +3329,7 @@
|
|||||||
328DD5DA1281F758B72006C7 /* Views */ = {
|
328DD5DA1281F758B72006C7 /* Views */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
A7CA45932DEF306200300A02 /* Highlight.swift */,
|
A7CA45932DEF306200300A02 /* HorizontalHighlightGradient.swift */,
|
||||||
8F21ED7205048668BEB44A38 /* AppActivityView.swift */,
|
8F21ED7205048668BEB44A38 /* AppActivityView.swift */,
|
||||||
CC743C7A85E3171BCBF0A653 /* AvatarHeaderView.swift */,
|
CC743C7A85E3171BCBF0A653 /* AvatarHeaderView.swift */,
|
||||||
9A028783CFFF861C5E44FFB1 /* BadgeLabel.swift */,
|
9A028783CFFF861C5E44FFB1 /* BadgeLabel.swift */,
|
||||||
@@ -7637,7 +7637,7 @@
|
|||||||
FA71CD334F2D2289BEF0D749 /* SecureBackupRecoveryKeyScreen.swift in Sources */,
|
FA71CD334F2D2289BEF0D749 /* SecureBackupRecoveryKeyScreen.swift in Sources */,
|
||||||
B1387648C6F71F1B98244803 /* SecureBackupRecoveryKeyScreenCoordinator.swift in Sources */,
|
B1387648C6F71F1B98244803 /* SecureBackupRecoveryKeyScreenCoordinator.swift in Sources */,
|
||||||
8AA84EF202F2EFC8453A97BD /* SecureBackupRecoveryKeyScreenModels.swift in Sources */,
|
8AA84EF202F2EFC8453A97BD /* SecureBackupRecoveryKeyScreenModels.swift in Sources */,
|
||||||
A7CA45942DEF306400300A02 /* Highlight.swift in Sources */,
|
A7CA45942DEF306400300A02 /* HorizontalHighlightGradient.swift in Sources */,
|
||||||
27F015B0D5436633B5B3C8C3 /* SecureBackupRecoveryKeyScreenViewModel.swift in Sources */,
|
27F015B0D5436633B5B3C8C3 /* SecureBackupRecoveryKeyScreenViewModel.swift in Sources */,
|
||||||
F0570F1ECD70C4C851FB2052 /* SecureBackupRecoveryKeyScreenViewModelProtocol.swift in Sources */,
|
F0570F1ECD70C4C851FB2052 /* SecureBackupRecoveryKeyScreenViewModelProtocol.swift in Sources */,
|
||||||
E84ADFE9696936C18C2424B5 /* SecureBackupScreen.swift in Sources */,
|
E84ADFE9696936C18C2424B5 /* SecureBackupScreen.swift in Sources */,
|
||||||
|
|||||||
+2
-2
@@ -8,7 +8,7 @@
|
|||||||
import Compound
|
import Compound
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct Highlight: ViewModifier {
|
struct HorizontalHighlightGradient: ViewModifier {
|
||||||
let borderColor: Color
|
let borderColor: Color
|
||||||
let primaryColor: Color
|
let primaryColor: Color
|
||||||
let secondaryColor: Color
|
let secondaryColor: Color
|
||||||
@@ -30,6 +30,6 @@ struct Highlight: ViewModifier {
|
|||||||
|
|
||||||
extension View {
|
extension View {
|
||||||
func highlight(borderColor: Color, primaryColor: Color, secondaryColor: Color) -> some View {
|
func highlight(borderColor: Color, primaryColor: Color, secondaryColor: Color) -> some View {
|
||||||
modifier(Highlight(borderColor: borderColor, primaryColor: primaryColor, secondaryColor: secondaryColor))
|
modifier(HorizontalHighlightGradient(borderColor: borderColor, primaryColor: primaryColor, secondaryColor: secondaryColor))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -199,6 +199,14 @@ struct HomeScreenRoom: Identifiable, Equatable {
|
|||||||
|
|
||||||
let isTombstoned: Bool
|
let isTombstoned: Bool
|
||||||
|
|
||||||
|
var displayedLastMessage: AttributedString? {
|
||||||
|
// If the room is tombstoned, show a specific message, regardless of any last message.
|
||||||
|
guard !isTombstoned else {
|
||||||
|
return AttributedString(L10n.screenRoomlistTombstonedRoomDescription)
|
||||||
|
}
|
||||||
|
return lastMessage
|
||||||
|
}
|
||||||
|
|
||||||
static func placeholder() -> HomeScreenRoom {
|
static func placeholder() -> HomeScreenRoom {
|
||||||
HomeScreenRoom(id: UUID().uuidString,
|
HomeScreenRoom(id: UUID().uuidString,
|
||||||
roomID: nil,
|
roomID: nil,
|
||||||
|
|||||||
@@ -135,12 +135,8 @@ struct HomeScreenRoomCell: View {
|
|||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
private var lastMessage: some View {
|
private var lastMessage: some View {
|
||||||
// If the room is tombstoned, show a specific message, regardless of any last message.
|
if let displayedLastMessage = room.displayedLastMessage {
|
||||||
if room.isTombstoned {
|
Text(displayedLastMessage)
|
||||||
Text(L10n.screenRoomlistTombstonedRoomDescription)
|
|
||||||
.lastMessageFormatting()
|
|
||||||
} else if let lastMessage = room.lastMessage {
|
|
||||||
Text(lastMessage)
|
|
||||||
.lastMessageFormatting()
|
.lastMessageFormatting()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -331,6 +331,7 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
|||||||
|
|
||||||
private func handleRoomInfoUpdate(_ roomInfo: RoomInfoProxy) async {
|
private func handleRoomInfoUpdate(_ roomInfo: RoomInfoProxy) async {
|
||||||
state.hasSuccessor = roomInfo.successor != nil
|
state.hasSuccessor = roomInfo.successor != nil
|
||||||
|
|
||||||
let pinnedEventIDs = roomInfo.pinnedEventIDs
|
let pinnedEventIDs = roomInfo.pinnedEventIDs
|
||||||
// Only update the loading state of the banner
|
// Only update the loading state of the banner
|
||||||
if state.pinnedEventsBannerState.isLoading {
|
if state.pinnedEventsBannerState.isLoading {
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ enum TimelineViewAction {
|
|||||||
case hasScrolled(direction: ScrollDirection)
|
case hasScrolled(direction: ScrollDirection)
|
||||||
case setOpenURLAction(OpenURLAction)
|
case setOpenURLAction(OpenURLAction)
|
||||||
|
|
||||||
case seePredecessorTapped
|
case displayPredecessorRoom
|
||||||
}
|
}
|
||||||
|
|
||||||
enum TimelineComposerAction {
|
enum TimelineComposerAction {
|
||||||
|
|||||||
@@ -212,8 +212,10 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
|||||||
actionsSubject.send(.hasScrolled(direction: direction))
|
actionsSubject.send(.hasScrolled(direction: direction))
|
||||||
case .setOpenURLAction(let action):
|
case .setOpenURLAction(let action):
|
||||||
state.openURL = action
|
state.openURL = action
|
||||||
case .seePredecessorTapped:
|
case .displayPredecessorRoom:
|
||||||
guard let predecessorID = roomProxy.predecessorRoom?.roomId else { return }
|
guard let predecessorID = roomProxy.predecessorRoom?.roomId else {
|
||||||
|
fatalError("Predecessor room should exist if this action is triggered.")
|
||||||
|
}
|
||||||
actionsSubject.send(.displayRoom(roomID: predecessorID))
|
actionsSubject.send(.displayRoom(roomID: predecessorID))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-3
@@ -15,8 +15,9 @@ struct TimelineStartRoomTimelineView: View {
|
|||||||
var body: some View {
|
var body: some View {
|
||||||
VStack(spacing: 14) {
|
VStack(spacing: 14) {
|
||||||
if context?.viewState.hasPredecessor == true {
|
if context?.viewState.hasPredecessor == true {
|
||||||
upgrade
|
upgradeDialogue
|
||||||
}
|
}
|
||||||
|
// We don't display the title for tombstoned DMs
|
||||||
if context?.viewState.isDirectOneToOneRoom != true {
|
if context?.viewState.isDirectOneToOneRoom != true {
|
||||||
Text(title)
|
Text(title)
|
||||||
.font(.compound.bodySM)
|
.font(.compound.bodySM)
|
||||||
@@ -28,13 +29,13 @@ struct TimelineStartRoomTimelineView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private var upgrade: some View {
|
private var upgradeDialogue: some View {
|
||||||
VStack(spacing: 16) {
|
VStack(spacing: 16) {
|
||||||
Text(L10n.screenRoomTimelineUpgradedRoomMessage)
|
Text(L10n.screenRoomTimelineUpgradedRoomMessage)
|
||||||
.font(.compound.bodyMD)
|
.font(.compound.bodyMD)
|
||||||
.foregroundColor(.compound.textPrimary)
|
.foregroundColor(.compound.textPrimary)
|
||||||
Button {
|
Button {
|
||||||
context?.send(viewAction: .seePredecessorTapped)
|
context?.send(viewAction: .displayPredecessorRoom)
|
||||||
} label: {
|
} label: {
|
||||||
Text(L10n.screenRoomTimelineUpgradedRoomAction)
|
Text(L10n.screenRoomTimelineUpgradedRoomAction)
|
||||||
.frame(maxWidth: .infinity)
|
.frame(maxWidth: .infinity)
|
||||||
|
|||||||
@@ -34,7 +34,14 @@ class JoinedRoomProxy: JoinedRoomProxyProtocol {
|
|||||||
|
|
||||||
var ownUserID: String { room.ownUserId() }
|
var ownUserID: String { room.ownUserId() }
|
||||||
|
|
||||||
lazy var predecessorRoom: PredecessorRoom? = room.predecessorRoom()
|
// The predecessor is set on room creation and never changes, so we lazily store it.
|
||||||
|
lazy var predecessorRoom = room.predecessorRoom()
|
||||||
|
|
||||||
|
// The successor may change over time, so we access it dynamically.
|
||||||
|
// It's suggested to observe it through the `infoPublisher`
|
||||||
|
var successorRoom: SuccessorRoom? {
|
||||||
|
room.successorRoom()
|
||||||
|
}
|
||||||
|
|
||||||
let timeline: TimelineProxyProtocol
|
let timeline: TimelineProxyProtocol
|
||||||
|
|
||||||
|
|||||||
@@ -78,6 +78,8 @@ protocol JoinedRoomProxyProtocol: RoomProxyProtocol {
|
|||||||
|
|
||||||
var predecessorRoom: PredecessorRoom? { get }
|
var predecessorRoom: PredecessorRoom? { get }
|
||||||
|
|
||||||
|
var successorRoom: SuccessorRoom? { get }
|
||||||
|
|
||||||
func subscribeForUpdates() async
|
func subscribeForUpdates() async
|
||||||
|
|
||||||
func subscribeToRoomInfoUpdates()
|
func subscribeToRoomInfoUpdates()
|
||||||
|
|||||||
@@ -55,7 +55,6 @@ struct RoomSummary {
|
|||||||
|
|
||||||
let isMarkedUnread: Bool
|
let isMarkedUnread: Bool
|
||||||
let isFavourite: Bool
|
let isFavourite: Bool
|
||||||
|
|
||||||
let isTombstoned: Bool
|
let isTombstoned: Bool
|
||||||
|
|
||||||
var hasUnreadMessages: Bool { unreadMessagesCount > 0 }
|
var hasUnreadMessages: Bool { unreadMessagesCount > 0 }
|
||||||
|
|||||||
@@ -480,11 +480,12 @@ class TimelineController: TimelineControllerProtocol {
|
|||||||
case .readMarker:
|
case .readMarker:
|
||||||
return ReadMarkerRoomTimelineItem(id: .virtual(uniqueID: uniqueID))
|
return ReadMarkerRoomTimelineItem(id: .virtual(uniqueID: uniqueID))
|
||||||
case .timelineStart:
|
case .timelineStart:
|
||||||
if hasPredecessor {
|
// We always display the timeline start item, if there is a predecessor room.
|
||||||
|
guard !hasPredecessor else {
|
||||||
return TimelineStartRoomTimelineItem(name: roomDisplayName)
|
return TimelineStartRoomTimelineItem(name: roomDisplayName)
|
||||||
} else {
|
|
||||||
return isDM ? nil : TimelineStartRoomTimelineItem(name: roomDisplayName)
|
|
||||||
}
|
}
|
||||||
|
// If not we only display the timeline start item if this is not a DM.
|
||||||
|
return isDM ? nil : TimelineStartRoomTimelineItem(name: roomDisplayName)
|
||||||
}
|
}
|
||||||
case .unknown:
|
case .unknown:
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
+1
@@ -8,6 +8,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
struct TimelineStartRoomTimelineItem: DecorationTimelineItemProtocol, Equatable {
|
struct TimelineStartRoomTimelineItem: DecorationTimelineItemProtocol, Equatable {
|
||||||
|
// Using a static identifier makes the animations consistent in SwiftUI
|
||||||
let id: TimelineItemIdentifier = .virtual(uniqueID: .init("TimelineStart"))
|
let id: TimelineItemIdentifier = .virtual(uniqueID: .init("TimelineStart"))
|
||||||
let name: String?
|
let name: String?
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user