Removing dead code part 3 (#2264)

This commit is contained in:
Mauro 2023-12-19 12:12:16 +01:00 committed by GitHub
parent 334d55aeaf
commit 09fb5461e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
77 changed files with 48 additions and 462 deletions

View File

@ -604,7 +604,6 @@
9BD3A773186291560DF92B62 /* RoomTimelineProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66F2402D738694F98729A441 /* RoomTimelineProvider.swift */; }; 9BD3A773186291560DF92B62 /* RoomTimelineProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66F2402D738694F98729A441 /* RoomTimelineProvider.swift */; };
9BEA56957B3AF954E7321658 /* ComposerToolbarViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = E44928D844E16EE48A311FCA /* ComposerToolbarViewModelProtocol.swift */; }; 9BEA56957B3AF954E7321658 /* ComposerToolbarViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = E44928D844E16EE48A311FCA /* ComposerToolbarViewModelProtocol.swift */; };
9C5A07E7C33F3F40287D7861 /* SettingsScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EC57A32ABC80D774CC663DB /* SettingsScreenUITests.swift */; }; 9C5A07E7C33F3F40287D7861 /* SettingsScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EC57A32ABC80D774CC663DB /* SettingsScreenUITests.swift */; };
9CCC77C31CB399661A034739 /* UserProperties+Element.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A6C4BE591FE5C38CE9C7EF3 /* UserProperties+Element.swift */; };
9D2E03DB175A6AB14589076D /* AnalyticsEvents in Frameworks */ = {isa = PBXBuildFile; productRef = 2A3F7BCCB18C15B30CCA39A9 /* AnalyticsEvents */; }; 9D2E03DB175A6AB14589076D /* AnalyticsEvents in Frameworks */ = {isa = PBXBuildFile; productRef = 2A3F7BCCB18C15B30CCA39A9 /* AnalyticsEvents */; };
9D79B94493FB32249F7E472F /* PlaceholderAvatarImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C705E605EF57C19DBE86FFA1 /* PlaceholderAvatarImage.swift */; }; 9D79B94493FB32249F7E472F /* PlaceholderAvatarImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C705E605EF57C19DBE86FFA1 /* PlaceholderAvatarImage.swift */; };
9D9690D2FD4CD26FF670620F /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C75EF87651B00A176AB08E97 /* AppDelegate.swift */; }; 9D9690D2FD4CD26FF670620F /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C75EF87651B00A176AB08E97 /* AppDelegate.swift */; };
@ -1428,7 +1427,6 @@
69D42EE0102D2857933625DD /* CreateRoomViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateRoomViewModelTests.swift; sourceTree = "<group>"; }; 69D42EE0102D2857933625DD /* CreateRoomViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateRoomViewModelTests.swift; sourceTree = "<group>"; };
6A4C9547BBFEEF30AA11329B /* TimelineItemStatusView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineItemStatusView.swift; sourceTree = "<group>"; }; 6A4C9547BBFEEF30AA11329B /* TimelineItemStatusView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineItemStatusView.swift; sourceTree = "<group>"; };
6A580295A56B55A856CC4084 /* InfoPlistReader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfoPlistReader.swift; sourceTree = "<group>"; }; 6A580295A56B55A856CC4084 /* InfoPlistReader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfoPlistReader.swift; sourceTree = "<group>"; };
6A6C4BE591FE5C38CE9C7EF3 /* UserProperties+Element.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UserProperties+Element.swift"; sourceTree = "<group>"; };
6A8E19C4645D3F5F9FB02355 /* UnitTestsAppCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnitTestsAppCoordinator.swift; sourceTree = "<group>"; }; 6A8E19C4645D3F5F9FB02355 /* UnitTestsAppCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnitTestsAppCoordinator.swift; sourceTree = "<group>"; };
6AB54B4F94686CCF0289B72F /* UserIndicatorPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserIndicatorPresenter.swift; sourceTree = "<group>"; }; 6AB54B4F94686CCF0289B72F /* UserIndicatorPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserIndicatorPresenter.swift; sourceTree = "<group>"; };
6AD1A853D605C2146B0DC028 /* MatrixEntityRegex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatrixEntityRegex.swift; sourceTree = "<group>"; }; 6AD1A853D605C2146B0DC028 /* MatrixEntityRegex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatrixEntityRegex.swift; sourceTree = "<group>"; };
@ -2608,7 +2606,6 @@
children = ( children = (
B4CFE236419E830E8946639C /* Analytics+SwiftUI.swift */, B4CFE236419E830E8946639C /* Analytics+SwiftUI.swift */,
CBF9AEA706926DD0DA2B954C /* JoinedRoomSize+MemberCount.swift */, CBF9AEA706926DD0DA2B954C /* JoinedRoomSize+MemberCount.swift */,
6A6C4BE591FE5C38CE9C7EF3 /* UserProperties+Element.swift */,
); );
path = Helpers; path = Helpers;
sourceTree = "<group>"; sourceTree = "<group>";
@ -5931,7 +5928,6 @@
80DEA2A4B20F9E279EAE6B2B /* UserProfile+Mock.swift in Sources */, 80DEA2A4B20F9E279EAE6B2B /* UserProfile+Mock.swift in Sources */,
ED90A59F068FD0CA27E602ED /* UserProfileListRow.swift in Sources */, ED90A59F068FD0CA27E602ED /* UserProfileListRow.swift in Sources */,
E21FE4C5B614F311C0955859 /* UserProfileProxy.swift in Sources */, E21FE4C5B614F311C0955859 /* UserProfileProxy.swift in Sources */,
9CCC77C31CB399661A034739 /* UserProperties+Element.swift in Sources */,
8AB8ED1051216546CB35FA0E /* UserSession.swift in Sources */, 8AB8ED1051216546CB35FA0E /* UserSession.swift in Sources */,
4A618590DEB72C4F186BFED4 /* UserSessionFlowCoordinator.swift in Sources */, 4A618590DEB72C4F186BFED4 /* UserSessionFlowCoordinator.swift in Sources */,
3113065AABBC14CEAE6843FA /* UserSessionFlowCoordinatorStateMachine.swift in Sources */, 3113065AABBC14CEAE6843FA /* UserSessionFlowCoordinatorStateMachine.swift in Sources */,

View File

@ -40,6 +40,7 @@ class WindowManager {
[mainWindow, overlayWindow, alternateWindow] [mainWindow, overlayWindow, alternateWindow]
} }
// periphery:ignore - auto cancels when reassigned
/// The task used to switch windows, so that we don't get stuck in the wrong state with a quick switch. /// The task used to switch windows, so that we don't get stuck in the wrong state with a quick switch.
@CancellableTask private var switchTask: Task<Void, Error>? @CancellableTask private var switchTask: Task<Void, Error>?
/// A duration that allows window switching to wait a couple of frames to avoid a transition through black. /// A duration that allows window switching to wait a couple of frames to avoid a transition through black.

View File

@ -408,11 +408,9 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
let userID = userSession.clientProxy.userID let userID = userSession.clientProxy.userID
let timelineItemFactory = RoomTimelineItemFactory(userID: userID, let timelineItemFactory = RoomTimelineItemFactory(userID: userID,
mediaProvider: userSession.mediaProvider,
attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: appSettings.permalinkBaseURL, attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: appSettings.permalinkBaseURL,
mentionBuilder: MentionBuilder()), mentionBuilder: MentionBuilder()),
stateEventStringBuilder: RoomStateEventStringBuilder(userID: userID), stateEventStringBuilder: RoomStateEventStringBuilder(userID: userID))
appSettings: appSettings)
let timelineController = roomTimelineControllerFactory.buildRoomTimelineController(roomProxy: roomProxy, let timelineController = roomTimelineControllerFactory.buildRoomTimelineController(roomProxy: roomProxy,
timelineItemFactory: timelineItemFactory, timelineItemFactory: timelineItemFactory,
@ -889,11 +887,9 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
let userID = userSession.clientProxy.userID let userID = userSession.clientProxy.userID
let timelineItemFactory = RoomTimelineItemFactory(userID: userID, let timelineItemFactory = RoomTimelineItemFactory(userID: userID,
mediaProvider: userSession.mediaProvider,
attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: appSettings.permalinkBaseURL, attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: appSettings.permalinkBaseURL,
mentionBuilder: MentionBuilder()), mentionBuilder: MentionBuilder()),
stateEventStringBuilder: RoomStateEventStringBuilder(userID: userID), stateEventStringBuilder: RoomStateEventStringBuilder(userID: userID))
appSettings: appSettings)
let roomTimelineController = roomTimelineControllerFactory.buildRoomTimelineController(roomProxy: roomProxy, let roomTimelineController = roomTimelineControllerFactory.buildRoomTimelineController(roomProxy: roomProxy,
timelineItemFactory: timelineItemFactory, timelineItemFactory: timelineItemFactory,

View File

@ -27,11 +27,8 @@ enum UserSessionFlowCoordinatorAction {
class UserSessionFlowCoordinator: FlowCoordinatorProtocol { class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
private let userSession: UserSessionProtocol private let userSession: UserSessionProtocol
private let navigationSplitCoordinator: NavigationSplitCoordinator private let navigationSplitCoordinator: NavigationSplitCoordinator
private let appLockService: AppLockServiceProtocol
private let bugReportService: BugReportServiceProtocol private let bugReportService: BugReportServiceProtocol
private let roomTimelineControllerFactory: RoomTimelineControllerFactoryProtocol
private let appSettings: AppSettings private let appSettings: AppSettings
private let analytics: AnalyticsService
private let actionsSubject: PassthroughSubject<UserSessionFlowCoordinatorAction, Never> = .init() private let actionsSubject: PassthroughSubject<UserSessionFlowCoordinatorAction, Never> = .init()
private let stateMachine: UserSessionFlowCoordinatorStateMachine private let stateMachine: UserSessionFlowCoordinatorStateMachine
@ -60,11 +57,8 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
stateMachine = UserSessionFlowCoordinatorStateMachine() stateMachine = UserSessionFlowCoordinatorStateMachine()
self.userSession = userSession self.userSession = userSession
self.navigationSplitCoordinator = navigationSplitCoordinator self.navigationSplitCoordinator = navigationSplitCoordinator
self.appLockService = appLockService
self.bugReportService = bugReportService self.bugReportService = bugReportService
self.roomTimelineControllerFactory = roomTimelineControllerFactory
self.appSettings = appSettings self.appSettings = appSettings
self.analytics = analytics
sidebarNavigationStackCoordinator = NavigationStackCoordinator(navigationSplitCoordinator: navigationSplitCoordinator) sidebarNavigationStackCoordinator = NavigationStackCoordinator(navigationSplitCoordinator: navigationSplitCoordinator)
detailNavigationStackCoordinator = NavigationStackCoordinator(navigationSplitCoordinator: navigationSplitCoordinator) detailNavigationStackCoordinator = NavigationStackCoordinator(navigationSplitCoordinator: navigationSplitCoordinator)

View File

@ -2194,11 +2194,11 @@ class RoomProxyMock: RoomProxyProtocol {
} }
} }
class RoomTimelineProviderMock: RoomTimelineProviderProtocol { class RoomTimelineProviderMock: RoomTimelineProviderProtocol {
var updatePublisher: AnyPublisher<TimelineProviderUpdate, Never> { var updatePublisher: AnyPublisher<Void, Never> {
get { return underlyingUpdatePublisher } get { return underlyingUpdatePublisher }
set(value) { underlyingUpdatePublisher = value } set(value) { underlyingUpdatePublisher = value }
} }
var underlyingUpdatePublisher: AnyPublisher<TimelineProviderUpdate, Never>! var underlyingUpdatePublisher: AnyPublisher<Void, Never>!
var itemProxies: [TimelineItemProxy] = [] var itemProxies: [TimelineItemProxy] = []
var backPaginationState: BackPaginationStatus { var backPaginationState: BackPaginationStatus {
get { return underlyingBackPaginationState } get { return underlyingBackPaginationState }
@ -3225,11 +3225,6 @@ class VoiceMessageMediaManagerMock: VoiceMessageMediaManagerProtocol {
} }
} }
class VoiceMessageRecorderMock: VoiceMessageRecorderProtocol { class VoiceMessageRecorderMock: VoiceMessageRecorderProtocol {
var audioRecorder: AudioRecorderProtocol {
get { return underlyingAudioRecorder }
set(value) { underlyingAudioRecorder = value }
}
var underlyingAudioRecorder: AudioRecorderProtocol!
var previewAudioPlayerState: AudioPlayerState? var previewAudioPlayerState: AudioPlayerState?
var isRecording: Bool { var isRecording: Bool {
get { return underlyingIsRecording } get { return underlyingIsRecording }
@ -3237,11 +3232,6 @@ class VoiceMessageRecorderMock: VoiceMessageRecorderProtocol {
} }
var underlyingIsRecording: Bool! var underlyingIsRecording: Bool!
var recordingURL: URL? var recordingURL: URL?
var recordingDuration: TimeInterval {
get { return underlyingRecordingDuration }
set(value) { underlyingRecordingDuration = value }
}
var underlyingRecordingDuration: TimeInterval!
var actions: AnyPublisher<VoiceMessageRecorderAction, Never> { var actions: AnyPublisher<VoiceMessageRecorderAction, Never> {
get { return underlyingActions } get { return underlyingActions }
set(value) { underlyingActions = value } set(value) { underlyingActions = value }
@ -3353,23 +3343,6 @@ class VoiceMessageRecorderMock: VoiceMessageRecorderProtocol {
deleteRecordingCallsCount += 1 deleteRecordingCallsCount += 1
await deleteRecordingClosure?() await deleteRecordingClosure?()
} }
//MARK: - buildRecordingWaveform
var buildRecordingWaveformCallsCount = 0
var buildRecordingWaveformCalled: Bool {
return buildRecordingWaveformCallsCount > 0
}
var buildRecordingWaveformReturnValue: Result<[UInt16], VoiceMessageRecorderError>!
var buildRecordingWaveformClosure: (() async -> Result<[UInt16], VoiceMessageRecorderError>)?
func buildRecordingWaveform() async -> Result<[UInt16], VoiceMessageRecorderError> {
buildRecordingWaveformCallsCount += 1
if let buildRecordingWaveformClosure = buildRecordingWaveformClosure {
return await buildRecordingWaveformClosure()
} else {
return buildRecordingWaveformReturnValue
}
}
//MARK: - sendVoiceMessage //MARK: - sendVoiceMessage
var sendVoiceMessageInRoomAudioConverterCallsCount = 0 var sendVoiceMessageInRoomAudioConverterCallsCount = 0

View File

@ -29,7 +29,6 @@ struct RoomProxyMockConfiguration {
var isEncrypted = true var isEncrypted = true
var hasOngoingCall = false var hasOngoingCall = false
var canonicalAlias: String? var canonicalAlias: String?
var alternativeAliases: [String] = []
var hasUnreadNotifications = Bool.random() var hasUnreadNotifications = Bool.random()
var timeline = { var timeline = {
@ -46,7 +45,6 @@ struct RoomProxyMockConfiguration {
var canUserTriggerRoomNotification = false var canUserTriggerRoomNotification = false
var canUserJoinCall = false var canUserJoinCall = false
var invitedMembersCount = 100
var joinedMembersCount = 50 var joinedMembersCount = 50
var activeMembersCount = 25 var activeMembersCount = 25
} }

View File

@ -31,18 +31,6 @@ extension String {
return string return string
} }
/// Calculates a numeric hash same as Element Web
/// See original function here https://github.com/matrix-org/matrix-react-sdk/blob/321dd49db4fbe360fc2ff109ac117305c955b061/src/utils/FormattingUtils.js#L47
var hashCode: Int32 {
var hash: Int32 = 0
for character in self {
let shiftedHash = hash << 5
hash = shiftedHash.subtractingReportingOverflow(hash).partialValue + Int32(character.unicodeScalars[character.unicodeScalars.startIndex].value)
}
return abs(hash)
}
var isASCII: Bool { var isASCII: Bool {
allSatisfy(\.isASCII) allSatisfy(\.isASCII)

View File

@ -44,10 +44,6 @@ extension UNNotificationContent {
@objc var roomID: String? { @objc var roomID: String? {
userInfo[NotificationConstants.UserInfoKey.roomIdentifier] as? String userInfo[NotificationConstants.UserInfoKey.roomIdentifier] as? String
} }
@objc var eventID: String? {
userInfo[NotificationConstants.UserInfoKey.eventIdentifier] as? String
}
} }
extension UNMutableNotificationContent { extension UNMutableNotificationContent {
@ -69,15 +65,6 @@ extension UNMutableNotificationContent {
} }
} }
override var eventID: String? {
get {
userInfo[NotificationConstants.UserInfoKey.eventIdentifier] as? String
}
set {
userInfo[NotificationConstants.UserInfoKey.eventIdentifier] = newValue
}
}
func addMediaAttachment(using mediaProvider: MediaProviderProtocol?, func addMediaAttachment(using mediaProvider: MediaProviderProtocol?,
mediaSource: MediaSourceProxy) async -> UNMutableNotificationContent { mediaSource: MediaSourceProxy) async -> UNMutableNotificationContent {
guard let mediaProvider else { guard let mediaProvider else {

View File

@ -47,17 +47,6 @@ extension URL: ExpressibleByStringLiteral {
return applicationSupportSessionsURL return applicationSupportSessionsURL
} }
/// The base directory where all cache is stored.
static var cacheBaseDirectory: URL {
let url = appGroupContainerDirectory
.appendingPathComponent("Library", isDirectory: true)
.appendingPathComponent("Caches", isDirectory: true)
try? FileManager.default.createDirectoryIfNeeded(at: url)
return url
}
/// The base directory where all application support data is stored. /// The base directory where all application support data is stored.
static var applicationSupportBaseDirectory: URL { static var applicationSupportBaseDirectory: URL {

View File

@ -18,11 +18,6 @@ import Combine
import UIKit import UIKit
class ScrollViewAdapter: NSObject, UIScrollViewDelegate { class ScrollViewAdapter: NSObject, UIScrollViewDelegate {
enum ScrollDirection {
case up
case down
}
var scrollView: UIScrollView? { var scrollView: UIScrollView? {
didSet { didSet {
oldValue?.delegate = nil oldValue?.delegate = nil
@ -42,13 +37,6 @@ class ScrollViewAdapter: NSObject, UIScrollViewDelegate {
.init(isScrollingSubject) .init(isScrollingSubject)
} }
private let scrollDirectionSubject: PassthroughSubject<ScrollDirection, Never> = .init()
var scrollDirection: AnyPublisher<ScrollDirection, Never> {
scrollDirectionSubject
.removeDuplicates()
.eraseToAnyPublisher()
}
private let isAtTopEdgeSubject: CurrentValueSubject<Bool, Never> = .init(false) private let isAtTopEdgeSubject: CurrentValueSubject<Bool, Never> = .init(false)
var isAtTopEdge: CurrentValuePublisher<Bool, Never> { var isAtTopEdge: CurrentValuePublisher<Bool, Never> {
isAtTopEdgeSubject isAtTopEdgeSubject
@ -59,7 +47,6 @@ class ScrollViewAdapter: NSObject, UIScrollViewDelegate {
func scrollViewDidScroll(_ scrollView: UIScrollView) { func scrollViewDidScroll(_ scrollView: UIScrollView) {
didScrollSubject.send(()) didScrollSubject.send(())
updateScrollDirection(scrollView)
let insetContentOffset = scrollView.contentOffset.y + scrollView.contentInset.top let insetContentOffset = scrollView.contentOffset.y + scrollView.contentInset.top
isAtTopEdgeSubject.send(insetContentOffset >= 3) isAtTopEdgeSubject.send(insetContentOffset >= 3)
} }
@ -97,18 +84,4 @@ class ScrollViewAdapter: NSObject, UIScrollViewDelegate {
private func updateDidScroll(_ scrollView: UIScrollView) { private func updateDidScroll(_ scrollView: UIScrollView) {
isScrollingSubject.send(scrollView.isDragging || scrollView.isDecelerating) isScrollingSubject.send(scrollView.isDragging || scrollView.isDecelerating)
} }
private func updateScrollDirection(_ scrollView: UIScrollView) {
let velocity = scrollView.panGestureRecognizer.velocity(in: nil)
if velocity.y > Constant.scrollDirectionThreshold {
scrollDirectionSubject.send(.up)
} else if velocity.y < -Constant.scrollDirectionThreshold {
scrollDirectionSubject.send(.down)
}
}
private enum Constant {
static let scrollDirectionThreshold: CGFloat = 200
}
} }

View File

@ -43,10 +43,6 @@ final class ShareToMapsAppActivity: UIActivity {
type.activityTitle type.activityTitle
} }
var activityCategory: UIActivity.Category {
.action
}
override var activityType: UIActivity.ActivityType { override var activityType: UIActivity.ActivityType {
.shareToMapsApp .shareToMapsApp
} }

View File

@ -75,19 +75,6 @@ extension UserPreference {
convenience init<R: RawRepresentable>(key: R, defaultValue: T, storageType: StorageType) where R.RawValue == String { convenience init<R: RawRepresentable>(key: R, defaultValue: T, storageType: StorageType) where R.RawValue == String {
self.init(key: key.rawValue, defaultValue: defaultValue, storageType: storageType) self.init(key: key.rawValue, defaultValue: defaultValue, storageType: storageType)
} }
/// Convenience initializer that also immediatelly stores the provided initialValue.
/// The initial value is stored every time the app is launched.
/// And will override any existing values.
///
/// - Parameters:
/// - key: the raw representable key used to store the value, needs conform also to String
/// - initialValue: the initial value that will be stored when the app is launched, the initialValue is also used as defaultValue
/// - storageType: the storage type where the wrappedValue will be stored.
convenience init<R: RawRepresentable>(key: R, initialValue: T, storageType: StorageType) where R.RawValue == String {
self.init(key: key, defaultValue: initialValue, storageType: storageType)
wrappedValue = initialValue
}
convenience init(key: String, storageType: StorageType) where T: ExpressibleByNilLiteral { convenience init(key: String, storageType: StorageType) where T: ExpressibleByNilLiteral {
self.init(key: key, defaultValue: nil, storageType: storageType) self.init(key: key, defaultValue: nil, storageType: storageType)

View File

@ -28,7 +28,6 @@ enum ServerConfirmationScreenCoordinatorAction {
} }
final class ServerConfirmationScreenCoordinator: CoordinatorProtocol { final class ServerConfirmationScreenCoordinator: CoordinatorProtocol {
private let parameters: ServerConfirmationScreenCoordinatorParameters
private var viewModel: ServerConfirmationScreenViewModelProtocol private var viewModel: ServerConfirmationScreenViewModelProtocol
private let actionsSubject: PassthroughSubject<ServerConfirmationScreenCoordinatorAction, Never> = .init() private let actionsSubject: PassthroughSubject<ServerConfirmationScreenCoordinatorAction, Never> = .init()
private var cancellables = Set<AnyCancellable>() private var cancellables = Set<AnyCancellable>()
@ -38,8 +37,6 @@ final class ServerConfirmationScreenCoordinator: CoordinatorProtocol {
} }
init(parameters: ServerConfirmationScreenCoordinatorParameters) { init(parameters: ServerConfirmationScreenCoordinatorParameters) {
self.parameters = parameters
viewModel = ServerConfirmationScreenViewModel(authenticationService: parameters.authenticationService, viewModel = ServerConfirmationScreenViewModel(authenticationService: parameters.authenticationService,
authenticationFlow: parameters.authenticationFlow) authenticationFlow: parameters.authenticationFlow)
} }

View File

@ -161,11 +161,6 @@ struct SoftLogoutScreen: View {
context.send(viewAction: .login) context.send(viewAction: .login)
} }
/// Sends the `forgotPassword` view action.
func forgotPassword() {
context.send(viewAction: .forgotPassword)
}
/// Sends the `clearAllData` view action. /// Sends the `clearAllData` view action.
func clearData() { func clearData() {
context.send(viewAction: .clearAllData) context.send(viewAction: .clearAllData)

View File

@ -43,14 +43,6 @@ struct WaitlistScreenViewState: BindableState {
/// Whether or not the user is still waiting in the queue. /// Whether or not the user is still waiting in the queue.
var isWaiting: Bool { userSession == nil } var isWaiting: Bool { userSession == nil }
var iconSymbolName: String {
if isWaiting {
return "stopwatch"
} else {
return "sparkles"
}
}
var title: String { var title: String {
if isWaiting { if isWaiting {
return L10n.screenWaitlistTitle return L10n.screenWaitlistTitle

View File

@ -162,19 +162,6 @@ class CallScreenViewModel: CallScreenViewModelType, CallScreenViewModelProtocol
""" """
} }
private func evaluateJavaScript(_ script: String) async -> String? {
guard let evaluator = state.bindings.javaScriptEvaluator else {
fatalError("Invalid javaScriptEvaluator")
}
do {
return try await evaluator(script) as? String
} catch {
MXLog.error("Failed evaluating javaScript with error: \(error)")
return nil
}
}
private func setupVoIPSession(callID: UUID) async throws { private func setupVoIPSession(callID: UUID) async throws {
try AVAudioSession.sharedInstance().setCategory(.playAndRecord, mode: .videoChat, options: []) try AVAudioSession.sharedInstance().setCategory(.playAndRecord, mode: .videoChat, options: [])
try AVAudioSession.sharedInstance().setActive(true, options: .notifyOthersOnDeactivation) try AVAudioSession.sharedInstance().setActive(true, options: .notifyOthersOnDeactivation)

View File

@ -24,7 +24,6 @@ struct VoiceMessagePreviewComposer: View {
let waveform: WaveformSource let waveform: WaveformSource
@ScaledMetric private var waveformLineWidth = 2.0 @ScaledMetric private var waveformLineWidth = 2.0
@ScaledMetric private var waveformLinePadding = 2.0 @ScaledMetric private var waveformLinePadding = 2.0
@State private var resumePlaybackAfterScrubbing = false
@GestureState var isDragging = false @GestureState var isDragging = false
let onPlay: () -> Void let onPlay: () -> Void
@ -95,20 +94,6 @@ struct VoiceMessagePreviewComposer: View {
onPlay() onPlay()
} }
} }
private func onScrubbing(_ scrubbing: Bool) {
if scrubbing {
if playerState.playbackState == .playing {
resumePlaybackAfterScrubbing = true
onPause()
}
} else {
if resumePlaybackAfterScrubbing {
onPlay()
resumePlaybackAfterScrubbing = false
}
}
}
} }
private extension DateFormatter { private extension DateFormatter {

View File

@ -33,12 +33,6 @@ struct VoiceMessageRecordingComposer: View {
} }
} }
} }
private func onPlaybackPlayPause() { }
private func onPlaybackSeek(_ progress: Double) { }
private func onPlaybackScrubbing(_ dragging: Bool) { }
} }
struct VoiceMessageRecordingComposer_Previews: PreviewProvider, TestablePreview { struct VoiceMessageRecordingComposer_Previews: PreviewProvider, TestablePreview {

View File

@ -27,7 +27,6 @@ enum StaticLocationScreenCoordinatorAction {
} }
final class StaticLocationScreenCoordinator: CoordinatorProtocol { final class StaticLocationScreenCoordinator: CoordinatorProtocol {
let parameters: StaticLocationScreenCoordinatorParameters
let viewModel: StaticLocationScreenViewModelProtocol let viewModel: StaticLocationScreenViewModelProtocol
private let actionsSubject: PassthroughSubject<StaticLocationScreenCoordinatorAction, Never> = .init() private let actionsSubject: PassthroughSubject<StaticLocationScreenCoordinatorAction, Never> = .init()
@ -38,8 +37,6 @@ final class StaticLocationScreenCoordinator: CoordinatorProtocol {
} }
init(parameters: StaticLocationScreenCoordinatorParameters) { init(parameters: StaticLocationScreenCoordinatorParameters) {
self.parameters = parameters
viewModel = StaticLocationScreenViewModel(interactionMode: parameters.interactionMode) viewModel = StaticLocationScreenViewModel(interactionMode: parameters.interactionMode)
} }

View File

@ -37,8 +37,7 @@ final class RoomPollsHistoryScreenCoordinator: CoordinatorProtocol {
} }
init(parameters: RoomPollsHistoryScreenCoordinatorParameters) { init(parameters: RoomPollsHistoryScreenCoordinatorParameters) {
viewModel = RoomPollsHistoryScreenViewModel(roomProxy: parameters.roomProxy, viewModel = RoomPollsHistoryScreenViewModel(pollInteractionHandler: parameters.pollInteractionHandler,
pollInteractionHandler: parameters.pollInteractionHandler,
roomTimelineController: parameters.roomTimelineController, roomTimelineController: parameters.roomTimelineController,
userIndicatorController: ServiceLocator.shared.userIndicatorController) userIndicatorController: ServiceLocator.shared.userIndicatorController)
} }

View File

@ -26,7 +26,6 @@ class RoomPollsHistoryScreenViewModel: RoomPollsHistoryScreenViewModelType, Room
static let backPaginationEventLimit: UInt = 250 static let backPaginationEventLimit: UInt = 250
} }
private let roomProxy: RoomProxyProtocol
private let pollInteractionHandler: PollInteractionHandlerProtocol private let pollInteractionHandler: PollInteractionHandlerProtocol
private let roomTimelineController: RoomTimelineControllerProtocol private let roomTimelineController: RoomTimelineControllerProtocol
private let userIndicatorController: UserIndicatorControllerProtocol private let userIndicatorController: UserIndicatorControllerProtocol
@ -40,11 +39,9 @@ class RoomPollsHistoryScreenViewModel: RoomPollsHistoryScreenViewModelType, Room
actionsSubject.eraseToAnyPublisher() actionsSubject.eraseToAnyPublisher()
} }
init(roomProxy: RoomProxyProtocol, init(pollInteractionHandler: PollInteractionHandlerProtocol,
pollInteractionHandler: PollInteractionHandlerProtocol,
roomTimelineController: RoomTimelineControllerProtocol, roomTimelineController: RoomTimelineControllerProtocol,
userIndicatorController: UserIndicatorControllerProtocol) { userIndicatorController: UserIndicatorControllerProtocol) {
self.roomProxy = roomProxy
self.pollInteractionHandler = pollInteractionHandler self.pollInteractionHandler = pollInteractionHandler
self.roomTimelineController = roomTimelineController self.roomTimelineController = roomTimelineController
self.userIndicatorController = userIndicatorController self.userIndicatorController = userIndicatorController
@ -189,12 +186,3 @@ class RoomPollsHistoryScreenViewModel: RoomPollsHistoryScreenViewModelType, Room
} }
} }
} }
// MARK: - Mocks
extension RoomPollsHistoryScreenViewModel {
static let mock = RoomPollsHistoryScreenViewModel(roomProxy: RoomProxyMock(),
pollInteractionHandler: PollInteractionHandlerMock(),
roomTimelineController: MockRoomTimelineController(),
userIndicatorController: UserIndicatorControllerMock())
}

View File

@ -126,8 +126,7 @@ struct RoomPollsHistoryScreen_Previews: PreviewProvider, TestablePreview {
roomTimelineController.timelineItems = [] roomTimelineController.timelineItems = []
let roomProxyMockConfiguration = RoomProxyMockConfiguration(displayName: "Polls") let roomProxyMockConfiguration = RoomProxyMockConfiguration(displayName: "Polls")
roomProxyMockConfiguration.timeline.timelineStartReached = false roomProxyMockConfiguration.timeline.timelineStartReached = false
let viewModel = RoomPollsHistoryScreenViewModel(roomProxy: RoomProxyMock(with: roomProxyMockConfiguration), let viewModel = RoomPollsHistoryScreenViewModel(pollInteractionHandler: PollInteractionHandlerMock(),
pollInteractionHandler: PollInteractionHandlerMock(),
roomTimelineController: roomTimelineController, roomTimelineController: roomTimelineController,
userIndicatorController: UserIndicatorControllerMock()) userIndicatorController: UserIndicatorControllerMock())
return viewModel return viewModel
@ -150,8 +149,7 @@ struct RoomPollsHistoryScreen_Previews: PreviewProvider, TestablePreview {
let roomProxyMockConfiguration = RoomProxyMockConfiguration(displayName: "Polls") let roomProxyMockConfiguration = RoomProxyMockConfiguration(displayName: "Polls")
roomProxyMockConfiguration.timeline.timelineStartReached = true roomProxyMockConfiguration.timeline.timelineStartReached = true
let viewModel = RoomPollsHistoryScreenViewModel(roomProxy: RoomProxyMock(with: roomProxyMockConfiguration), let viewModel = RoomPollsHistoryScreenViewModel(pollInteractionHandler: PollInteractionHandlerMock(),
pollInteractionHandler: PollInteractionHandlerMock(),
roomTimelineController: roomTimelineController, roomTimelineController: roomTimelineController,
userIndicatorController: UserIndicatorControllerMock()) userIndicatorController: UserIndicatorControllerMock())

View File

@ -26,8 +26,6 @@ struct TimelineItemBubbledStylerView<Content: View>: View {
let timelineItem: EventBasedTimelineItemProtocol let timelineItem: EventBasedTimelineItemProtocol
let adjustedDeliveryStatus: TimelineItemDeliveryStatus? let adjustedDeliveryStatus: TimelineItemDeliveryStatus?
@ViewBuilder let content: () -> Content @ViewBuilder let content: () -> Content
@State private var showItemActionMenu = false
private var isEncryptedOneToOneRoom: Bool { context.viewState.isEncryptedOneToOneRoom } private var isEncryptedOneToOneRoom: Bool { context.viewState.isEncryptedOneToOneRoom }

View File

@ -24,8 +24,6 @@ struct TimelineItemPlainStylerView<Content: View>: View {
let timelineItem: EventBasedTimelineItemProtocol let timelineItem: EventBasedTimelineItemProtocol
let adjustedDeliveryStatus: TimelineItemDeliveryStatus? let adjustedDeliveryStatus: TimelineItemDeliveryStatus?
@ViewBuilder let content: () -> Content @ViewBuilder let content: () -> Content
@State private var showItemActionMenu = false
var body: some View { var body: some View {
VStack(alignment: .trailing, spacing: 0) { VStack(alignment: .trailing, spacing: 0) {

View File

@ -68,10 +68,6 @@ private struct TimelineGroupStyleKey: EnvironmentKey {
static let defaultValue = TimelineGroupStyle.single static let defaultValue = TimelineGroupStyle.single
} }
private struct ReadReceiptsEnabledKey: EnvironmentKey {
static let defaultValue = false
}
extension EnvironmentValues { extension EnvironmentValues {
var timelineStyle: TimelineStyle { var timelineStyle: TimelineStyle {
get { self[TimelineStyleKey.self] } get { self[TimelineStyleKey.self] }

View File

@ -18,8 +18,6 @@ import SwiftUI
@MainActor @MainActor
struct TimelineReactionsView: View { struct TimelineReactionsView: View {
private static let horizontalSpacing: CGFloat = 4
private static let verticalSpacing: CGFloat = 4
private let feedbackGenerator = UIImpactFeedbackGenerator(style: .heavy) private let feedbackGenerator = UIImpactFeedbackGenerator(style: .heavy)
@Environment(\.layoutDirection) private var layoutDirection: LayoutDirection @Environment(\.layoutDirection) private var layoutDirection: LayoutDirection

View File

@ -20,8 +20,6 @@ struct PollRoomTimelineView: View {
let timelineItem: PollRoomTimelineItem let timelineItem: PollRoomTimelineItem
@EnvironmentObject private var context: RoomScreenViewModel.Context @EnvironmentObject private var context: RoomScreenViewModel.Context
private let feedbackGenerator = UIImpactFeedbackGenerator(style: .heavy)
var body: some View { var body: some View {
TimelineStyler(timelineItem: timelineItem) { TimelineStyler(timelineItem: timelineItem) {
PollView(poll: poll, editable: timelineItem.isEditable) { action in PollView(poll: poll, editable: timelineItem.isEditable) { action in

View File

@ -24,6 +24,7 @@ import OrderedCollections
class TimelineItemCell: UITableViewCell { class TimelineItemCell: UITableViewCell {
static let reuseIdentifier = "TimelineItemCell" static let reuseIdentifier = "TimelineItemCell"
// periphery:ignore - retaining purpose
var item: RoomTimelineItemViewState? var item: RoomTimelineItemViewState?
override func prepareForReuse() { override func prepareForReuse() {
@ -63,8 +64,6 @@ class TimelineTableViewController: UIViewController {
paginateBackwardsPublisher.send(()) paginateBackwardsPublisher.send(())
} }
} }
var contextMenuActionProvider: (@MainActor (_ itemID: TimelineItemIdentifier) -> TimelineItemMenuActions?)?
@Binding private var isScrolledToBottom: Bool @Binding private var isScrolledToBottom: Bool

View File

@ -66,9 +66,6 @@ struct UITimelineView: UIViewControllerRepresentable {
if tableViewController.isBackPaginating != context.viewState.timelineViewState.isBackPaginating { if tableViewController.isBackPaginating != context.viewState.timelineViewState.isBackPaginating {
tableViewController.isBackPaginating = context.viewState.timelineViewState.isBackPaginating tableViewController.isBackPaginating = context.viewState.timelineViewState.isBackPaginating
} }
// Doesn't have an equatable conformance :(
tableViewController.contextMenuActionProvider = context.viewState.timelineItemMenuActionProvider
} }
func send(viewAction: RoomScreenViewAction) { func send(viewAction: RoomScreenViewAction) {

View File

@ -133,7 +133,7 @@ extension RoomTimelineItemProtocol {
} }
} }
public struct TimelineItemMenu: View { struct TimelineItemMenu: View {
@EnvironmentObject private var context: RoomScreenViewModel.Context @EnvironmentObject private var context: RoomScreenViewModel.Context
@Environment(\.dismiss) private var dismiss @Environment(\.dismiss) private var dismiss
@ -141,7 +141,7 @@ public struct TimelineItemMenu: View {
let actions: TimelineItemMenuActions let actions: TimelineItemMenuActions
private let feedbackGenerator = UIImpactFeedbackGenerator(style: .heavy) private let feedbackGenerator = UIImpactFeedbackGenerator(style: .heavy)
public var body: some View { var body: some View {
VStack(spacing: 8) { VStack(spacing: 8) {
header header
.frame(idealWidth: 300.0) .frame(idealWidth: 300.0)

View File

@ -27,7 +27,6 @@ enum SecureBackupKeyBackupScreenCoordinatorAction {
} }
final class SecureBackupKeyBackupScreenCoordinator: CoordinatorProtocol { final class SecureBackupKeyBackupScreenCoordinator: CoordinatorProtocol {
private let parameters: SecureBackupKeyBackupScreenCoordinatorParameters
private var viewModel: SecureBackupKeyBackupScreenViewModelProtocol private var viewModel: SecureBackupKeyBackupScreenViewModelProtocol
private let actionsSubject: PassthroughSubject<SecureBackupKeyBackupScreenCoordinatorAction, Never> = .init() private let actionsSubject: PassthroughSubject<SecureBackupKeyBackupScreenCoordinatorAction, Never> = .init()
private var cancellables = Set<AnyCancellable>() private var cancellables = Set<AnyCancellable>()
@ -37,8 +36,6 @@ final class SecureBackupKeyBackupScreenCoordinator: CoordinatorProtocol {
} }
init(parameters: SecureBackupKeyBackupScreenCoordinatorParameters) { init(parameters: SecureBackupKeyBackupScreenCoordinatorParameters) {
self.parameters = parameters
viewModel = SecureBackupKeyBackupScreenViewModel(secureBackupController: parameters.secureBackupController, viewModel = SecureBackupKeyBackupScreenViewModel(secureBackupController: parameters.secureBackupController,
userIndicatorController: parameters.userIndicatorController) userIndicatorController: parameters.userIndicatorController)
} }

View File

@ -33,8 +33,6 @@ struct SecureBackupKeyBackupScreenViewStateBindings {
var alertInfo: AlertInfo<UUID>? var alertInfo: AlertInfo<UUID>?
} }
var alertInfo: AlertInfo<UUID>?
enum SecureBackupKeyBackupScreenViewAction { enum SecureBackupKeyBackupScreenViewAction {
case cancel case cancel
case toggleBackup case toggleBackup

View File

@ -29,7 +29,6 @@ enum SecureBackupLogoutConfirmationScreenCoordinatorAction {
} }
final class SecureBackupLogoutConfirmationScreenCoordinator: CoordinatorProtocol { final class SecureBackupLogoutConfirmationScreenCoordinator: CoordinatorProtocol {
private let parameters: SecureBackupLogoutConfirmationScreenCoordinatorParameters
private var viewModel: SecureBackupLogoutConfirmationScreenViewModelProtocol private var viewModel: SecureBackupLogoutConfirmationScreenViewModelProtocol
private let actionsSubject: PassthroughSubject<SecureBackupLogoutConfirmationScreenCoordinatorAction, Never> = .init() private let actionsSubject: PassthroughSubject<SecureBackupLogoutConfirmationScreenCoordinatorAction, Never> = .init()
private var cancellables = Set<AnyCancellable>() private var cancellables = Set<AnyCancellable>()
@ -39,8 +38,6 @@ final class SecureBackupLogoutConfirmationScreenCoordinator: CoordinatorProtocol
} }
init(parameters: SecureBackupLogoutConfirmationScreenCoordinatorParameters) { init(parameters: SecureBackupLogoutConfirmationScreenCoordinatorParameters) {
self.parameters = parameters
viewModel = SecureBackupLogoutConfirmationScreenViewModel(secureBackupController: parameters.secureBackupController, viewModel = SecureBackupLogoutConfirmationScreenViewModel(secureBackupController: parameters.secureBackupController,
networkMonitor: parameters.networkMonitor) networkMonitor: parameters.networkMonitor)
} }

View File

@ -23,6 +23,7 @@ class SecureBackupLogoutConfirmationScreenViewModel: SecureBackupLogoutConfirmat
private let secureBackupController: SecureBackupControllerProtocol private let secureBackupController: SecureBackupControllerProtocol
private let networkMonitor: NetworkMonitorProtocol private let networkMonitor: NetworkMonitorProtocol
// periphery:ignore - auto cancels when reassigned
@CancellableTask @CancellableTask
private var keyUploadWaitingTask: Task<Void, Never>? private var keyUploadWaitingTask: Task<Void, Never>?

View File

@ -30,7 +30,6 @@ enum SecureBackupRecoveryKeyScreenCoordinatorAction {
} }
final class SecureBackupRecoveryKeyScreenCoordinator: CoordinatorProtocol { final class SecureBackupRecoveryKeyScreenCoordinator: CoordinatorProtocol {
private let parameters: SecureBackupRecoveryKeyScreenCoordinatorParameters
private var viewModel: SecureBackupRecoveryKeyScreenViewModelProtocol private var viewModel: SecureBackupRecoveryKeyScreenViewModelProtocol
private let actionsSubject: PassthroughSubject<SecureBackupRecoveryKeyScreenCoordinatorAction, Never> = .init() private let actionsSubject: PassthroughSubject<SecureBackupRecoveryKeyScreenCoordinatorAction, Never> = .init()
private var cancellables = Set<AnyCancellable>() private var cancellables = Set<AnyCancellable>()
@ -40,8 +39,6 @@ final class SecureBackupRecoveryKeyScreenCoordinator: CoordinatorProtocol {
} }
init(parameters: SecureBackupRecoveryKeyScreenCoordinatorParameters) { init(parameters: SecureBackupRecoveryKeyScreenCoordinatorParameters) {
self.parameters = parameters
viewModel = SecureBackupRecoveryKeyScreenViewModel(secureBackupController: parameters.secureBackupController, viewModel = SecureBackupRecoveryKeyScreenViewModel(secureBackupController: parameters.secureBackupController,
userIndicatorController: parameters.userIndicatorController) userIndicatorController: parameters.userIndicatorController)
} }

View File

@ -24,18 +24,11 @@ struct SecureBackupScreenCoordinatorParameters {
let userIndicatorController: UserIndicatorControllerProtocol let userIndicatorController: UserIndicatorControllerProtocol
} }
enum SecureBackupScreenCoordinatorAction { }
final class SecureBackupScreenCoordinator: CoordinatorProtocol { final class SecureBackupScreenCoordinator: CoordinatorProtocol {
private let parameters: SecureBackupScreenCoordinatorParameters private let parameters: SecureBackupScreenCoordinatorParameters
private var viewModel: SecureBackupScreenViewModelProtocol private var viewModel: SecureBackupScreenViewModelProtocol
private let actionsSubject: PassthroughSubject<SecureBackupScreenCoordinatorAction, Never> = .init()
private var cancellables = Set<AnyCancellable>() private var cancellables = Set<AnyCancellable>()
var actions: AnyPublisher<SecureBackupScreenCoordinatorAction, Never> {
actionsSubject.eraseToAnyPublisher()
}
init(parameters: SecureBackupScreenCoordinatorParameters) { init(parameters: SecureBackupScreenCoordinatorParameters) {
self.parameters = parameters self.parameters = parameters

View File

@ -26,7 +26,6 @@ struct SessionVerificationScreenCoordinatorParameters {
} }
final class SessionVerificationScreenCoordinator: CoordinatorProtocol { final class SessionVerificationScreenCoordinator: CoordinatorProtocol {
private let parameters: SessionVerificationScreenCoordinatorParameters
private var viewModel: SessionVerificationScreenViewModelProtocol private var viewModel: SessionVerificationScreenViewModelProtocol
private let actionsSubject: PassthroughSubject<SessionVerificationScreenCoordinatorAction, Never> = .init() private let actionsSubject: PassthroughSubject<SessionVerificationScreenCoordinatorAction, Never> = .init()
@ -37,8 +36,6 @@ final class SessionVerificationScreenCoordinator: CoordinatorProtocol {
} }
init(parameters: SessionVerificationScreenCoordinatorParameters) { init(parameters: SessionVerificationScreenCoordinatorParameters) {
self.parameters = parameters
viewModel = SessionVerificationScreenViewModel(sessionVerificationControllerProxy: parameters.sessionVerificationControllerProxy) viewModel = SessionVerificationScreenViewModel(sessionVerificationControllerProxy: parameters.sessionVerificationControllerProxy)
} }

View File

@ -211,19 +211,6 @@ struct SessionVerificationScreen: View {
.padding(8.0) .padding(8.0)
} }
} }
struct StateIcon: View {
let systemName: String
var body: some View {
Image(systemName: systemName)
.resizable()
.font(.compound.bodyLG.weight(.light))
.scaledToFit()
.foregroundColor(.compound.iconPrimary)
.frame(width: 100, height: 100)
}
}
} }
// MARK: - Previews // MARK: - Previews

View File

@ -41,6 +41,7 @@ final class SettingsScreenCoordinator: CoordinatorProtocol {
private let parameters: SettingsScreenCoordinatorParameters private let parameters: SettingsScreenCoordinatorParameters
private var viewModel: SettingsScreenViewModelProtocol private var viewModel: SettingsScreenViewModelProtocol
// periphery:ignore - retaining purpose
private var appLockSetupFlowCoordinator: AppLockSetupFlowCoordinator? private var appLockSetupFlowCoordinator: AppLockSetupFlowCoordinator?
private let actionsSubject: PassthroughSubject<SettingsScreenCoordinatorAction, Never> = .init() private let actionsSubject: PassthroughSubject<SettingsScreenCoordinatorAction, Never> = .init()

View File

@ -20,9 +20,6 @@ import SwiftUI
typealias SettingsScreenViewModelType = StateStoreViewModel<SettingsScreenViewState, SettingsScreenViewAction> typealias SettingsScreenViewModelType = StateStoreViewModel<SettingsScreenViewState, SettingsScreenViewAction>
class SettingsScreenViewModel: SettingsScreenViewModelType, SettingsScreenViewModelProtocol { class SettingsScreenViewModel: SettingsScreenViewModelType, SettingsScreenViewModelProtocol {
private let userSession: UserSessionProtocol
private let appSettings: AppSettings
private var actionsSubject: PassthroughSubject<SettingsScreenViewModelAction, Never> = .init() private var actionsSubject: PassthroughSubject<SettingsScreenViewModelAction, Never> = .init()
var actions: AnyPublisher<SettingsScreenViewModelAction, Never> { var actions: AnyPublisher<SettingsScreenViewModelAction, Never> {
@ -30,9 +27,6 @@ class SettingsScreenViewModel: SettingsScreenViewModelType, SettingsScreenViewMo
} }
init(userSession: UserSessionProtocol, appSettings: AppSettings) { init(userSession: UserSessionProtocol, appSettings: AppSettings) {
self.userSession = userSession
self.appSettings = appSettings
super.init(initialViewState: .init(deviceID: userSession.deviceID, super.init(initialViewState: .init(deviceID: userSession.deviceID,
userID: userSession.userID, userID: userSession.userID,
accountProfileURL: userSession.clientProxy.accountURL(action: .profile), accountProfileURL: userSession.clientProxy.accountURL(action: .profile),

View File

@ -24,18 +24,11 @@ struct UserDetailsEditScreenCoordinatorParameters {
let userIndicatorController: UserIndicatorControllerProtocol let userIndicatorController: UserIndicatorControllerProtocol
} }
enum UserDetailsEditScreenCoordinatorAction { }
final class UserDetailsEditScreenCoordinator: CoordinatorProtocol { final class UserDetailsEditScreenCoordinator: CoordinatorProtocol {
private let parameters: UserDetailsEditScreenCoordinatorParameters private let parameters: UserDetailsEditScreenCoordinatorParameters
private var viewModel: UserDetailsEditScreenViewModelProtocol private var viewModel: UserDetailsEditScreenViewModelProtocol
private let actionsSubject: PassthroughSubject<UserDetailsEditScreenCoordinatorAction, Never> = .init()
private var cancellables = Set<AnyCancellable>() private var cancellables = Set<AnyCancellable>()
var actions: AnyPublisher<UserDetailsEditScreenCoordinatorAction, Never> {
actionsSubject.eraseToAnyPublisher()
}
init(parameters: UserDetailsEditScreenCoordinatorParameters) { init(parameters: UserDetailsEditScreenCoordinatorParameters) {
self.parameters = parameters self.parameters = parameters

View File

@ -37,12 +37,7 @@ struct UserDetailsEditScreenViewState: BindableState {
var nameDidChange: Bool { var nameDidChange: Bool {
bindings.name != currentDisplayName bindings.name != currentDisplayName
} }
/// The string shown for the room's name when it can't be edited.
var nameRowTitle: String {
bindings.name.isEmpty ? L10n.screenEditProfileDisplayName : bindings.name
}
var avatarDidChange: Bool { var avatarDidChange: Bool {
localMedia != nil || selectedAvatarURL != currentAvatarURL localMedia != nil || selectedAvatarURL != currentAvatarURL
} }

View File

@ -99,6 +99,7 @@ class StartChatScreenViewModel: StartChatScreenViewModelType, StartChatScreenVie
.store(in: &cancellables) .store(in: &cancellables)
} }
// periphery:ignore - auto cancels when reassigned
@CancellableTask @CancellableTask
private var fetchUsersTask: Task<Void, Never>? private var fetchUsersTask: Task<Void, Never>?

View File

@ -1,28 +0,0 @@
//
// Copyright 2021 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 AnalyticsEvents
import Foundation
public extension AnalyticsEvent.UserProperties {
// Initializer for Element. Strips all Web properties.
init(ftueUseCaseSelection: FtueUseCaseSelection?, numFavouriteRooms: Int?, numSpaces: Int?, allChatsActiveFilter: AllChatsActiveFilter?) {
self.init(allChatsActiveFilter: nil,
ftueUseCaseSelection: ftueUseCaseSelection,
numFavouriteRooms: numFavouriteRooms,
numSpaces: numSpaces)
}
}

View File

@ -67,10 +67,9 @@ class PostHogAnalyticsClient: AnalyticsClientProtocol {
} }
// Merge the updated user properties with the existing ones // Merge the updated user properties with the existing ones
self.pendingUserProperties = AnalyticsEvent.UserProperties(ftueUseCaseSelection: userProperties.ftueUseCaseSelection ?? pendingUserProperties.ftueUseCaseSelection, self.pendingUserProperties = AnalyticsEvent.UserProperties(allChatsActiveFilter: userProperties.allChatsActiveFilter ?? pendingUserProperties.allChatsActiveFilter, ftueUseCaseSelection: userProperties.ftueUseCaseSelection ?? pendingUserProperties.ftueUseCaseSelection,
numFavouriteRooms: userProperties.numFavouriteRooms ?? pendingUserProperties.numFavouriteRooms, numFavouriteRooms: userProperties.numFavouriteRooms ?? pendingUserProperties.numFavouriteRooms,
numSpaces: userProperties.numSpaces ?? pendingUserProperties.numSpaces, numSpaces: userProperties.numSpaces ?? pendingUserProperties.numSpaces)
allChatsActiveFilter: userProperties.allChatsActiveFilter ?? pendingUserProperties.allChatsActiveFilter)
} }
// MARK: - Private // MARK: - Private

View File

@ -25,13 +25,11 @@ private final class MediaRequest {
actor MediaLoader: MediaLoaderProtocol { actor MediaLoader: MediaLoaderProtocol {
private let client: ClientProtocol private let client: ClientProtocol
private let clientQueue: DispatchQueue
private var ongoingRequests = [MediaSourceProxy: MediaRequest]() private var ongoingRequests = [MediaSourceProxy: MediaRequest]()
init(client: ClientProtocol, init(client: ClientProtocol,
clientQueue: DispatchQueue = .global()) { clientQueue: DispatchQueue = .global()) {
self.client = client self.client = client
self.clientQueue = clientQueue
} }
func loadMediaContentForSource(_ source: MediaSourceProxy) async throws -> Data { func loadMediaContentForSource(_ source: MediaSourceProxy) async throws -> Data {

View File

@ -20,9 +20,7 @@ import UserNotifications
protocol NotificationItemProxyProtocol { protocol NotificationItemProxyProtocol {
var event: NotificationEvent? { get } var event: NotificationEvent? { get }
var eventID: String { get }
var senderID: String { get } var senderID: String { get }
var roomID: String { get } var roomID: String { get }

View File

@ -29,7 +29,6 @@ class RoomProxy: RoomProxyProtocol {
private let backgroundTaskName = "SendRoomEvent" private let backgroundTaskName = "SendRoomEvent"
private let userInitiatedDispatchQueue = DispatchQueue(label: "io.element.elementx.roomproxy.user_initiated", qos: .userInitiated) private let userInitiatedDispatchQueue = DispatchQueue(label: "io.element.elementx.roomproxy.user_initiated", qos: .userInitiated)
private let lowPriorityDispatchQueue = DispatchQueue(label: "io.element.elementx.roomproxy.low_priority", qos: .utility)
private var sendMessageBackgroundTask: BackgroundTaskProtocol? private var sendMessageBackgroundTask: BackgroundTaskProtocol?
@ -141,10 +140,6 @@ class RoomProxy: RoomProxyProtocol {
roomListItem.avatarUrl().flatMap(URL.init(string:)) roomListItem.avatarUrl().flatMap(URL.init(string:))
} }
var invitedMembersCount: Int {
Int(room.invitedMembersCount())
}
var joinedMembersCount: Int { var joinedMembersCount: Int {
Int(room.joinedMembersCount()) Int(room.joinedMembersCount())
} }

View File

@ -30,6 +30,7 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol {
private let serialDispatchQueue: DispatchQueue private let serialDispatchQueue: DispatchQueue
// periphery:ignore - retaining purpose
private var roomList: RoomListProtocol? private var roomList: RoomListProtocol?
private var cancellables = Set<AnyCancellable>() private var cancellables = Set<AnyCancellable>()
@ -39,7 +40,6 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol {
private let roomListSubject = CurrentValueSubject<[RoomSummary], Never>([]) private let roomListSubject = CurrentValueSubject<[RoomSummary], Never>([])
private let stateSubject = CurrentValueSubject<RoomSummaryProviderState, Never>(.notLoaded) private let stateSubject = CurrentValueSubject<RoomSummaryProviderState, Never>(.notLoaded)
private let countSubject = CurrentValueSubject<UInt, Never>(0)
private let diffsPublisher = PassthroughSubject<[RoomListEntriesUpdate], Never>() private let diffsPublisher = PassthroughSubject<[RoomListEntriesUpdate], Never>()
@ -407,15 +407,6 @@ extension MatrixRustSDK.RoomListEntry {
return "Filled(\(roomId))" return "Filled(\(roomId))"
} }
} }
var isInvalidated: Bool {
switch self {
case .invalidated:
return true
default:
return false
}
}
} }
private class RoomListEntriesListenerProxy: RoomListEntriesListener { private class RoomListEntriesListenerProxy: RoomListEntriesListener {

View File

@ -24,9 +24,12 @@ class SecureBackupController: SecureBackupControllerProtocol {
private let recoveryKeyStateSubject = CurrentValueSubject<SecureBackupRecoveryKeyState, Never>(.unknown) private let recoveryKeyStateSubject = CurrentValueSubject<SecureBackupRecoveryKeyState, Never>(.unknown)
private let keyBackupStateSubject = CurrentValueSubject<SecureBackupKeyBackupState, Never>(.unknown) private let keyBackupStateSubject = CurrentValueSubject<SecureBackupKeyBackupState, Never>(.unknown)
// periphery:ignore - retaining purpose
private var backupStateListenerTaskHandle: TaskHandle? private var backupStateListenerTaskHandle: TaskHandle?
// periphery:ignore - retaining purpose
private var recoveryStateListenerTaskHandle: TaskHandle? private var recoveryStateListenerTaskHandle: TaskHandle?
// periphery:ignore - auto cancels when reassigned
/// Used to dedupe remote backup state requests /// Used to dedupe remote backup state requests
@CancellableTask private var remoteBackupStateTask: Task<Void, Error>? @CancellableTask private var remoteBackupStateTask: Task<Void, Error>?

View File

@ -64,11 +64,3 @@ protocol SecureBackupControllerProtocol {
func waitForKeyBackupUpload() async -> Result<Void, SecureBackupControllerError> func waitForKeyBackupUpload() async -> Result<Void, SecureBackupControllerError>
} }
extension SecureBackupControllerMock {
convenience init(keyBackupState: SecureBackupKeyBackupState, recoveryKeyState: SecureBackupRecoveryKeyState) {
self.init()
underlyingKeyBackupState = CurrentValueSubject<SecureBackupKeyBackupState, Never>(keyBackupState).asCurrentValuePublisher()
underlyingRecoveryKeyState = CurrentValueSubject<SecureBackupRecoveryKeyState, Never>(recoveryKeyState).asCurrentValuePublisher()
}
}

View File

@ -32,10 +32,10 @@ class RoomTimelineProvider: RoomTimelineProviderProtocol {
itemProxiesSubject.value itemProxiesSubject.value
} }
var updatePublisher: AnyPublisher<TimelineProviderUpdate, Never> { var updatePublisher: AnyPublisher<Void, Never> {
itemProxiesSubject itemProxiesSubject
.combineLatest(backPaginationStateSubject) .combineLatest(backPaginationStateSubject)
.map(TimelineProviderUpdate.init) .map { _, _ in () }
.eraseToAnyPublisher() .eraseToAnyPublisher()
} }

View File

@ -19,15 +19,10 @@ import Foundation
import MatrixRustSDK import MatrixRustSDK
struct TimelineProviderUpdate {
let items: [TimelineItemProxy]
let backPaginationState: BackPaginationStatus
}
@MainActor @MainActor
// sourcery: AutoMockable // sourcery: AutoMockable
protocol RoomTimelineProviderProtocol { protocol RoomTimelineProviderProtocol {
var updatePublisher: AnyPublisher<TimelineProviderUpdate, Never> { get } var updatePublisher: AnyPublisher<Void, Never> { get }
var itemProxies: [TimelineItemProxy] { get } var itemProxies: [TimelineItemProxy] { get }
var backPaginationState: BackPaginationStatus { get } var backPaginationState: BackPaginationStatus { get }
} }

View File

@ -27,11 +27,6 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
private let serialDispatchQueue: DispatchQueue private let serialDispatchQueue: DispatchQueue
private var cancellables = Set<AnyCancellable>() private var cancellables = Set<AnyCancellable>()
private var timelineItemsUpdateTask: Task<Void, Never>? {
willSet {
timelineItemsUpdateTask?.cancel()
}
}
let callbacks = PassthroughSubject<RoomTimelineControllerCallback, Never>() let callbacks = PassthroughSubject<RoomTimelineControllerCallback, Never>()
@ -257,13 +252,9 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
for (index, collapsibleChunk) in collapsibleChunks.enumerated() { for (index, collapsibleChunk) in collapsibleChunks.enumerated() {
let isLastItem = index == collapsibleChunks.indices.last let isLastItem = index == collapsibleChunks.indices.last
// Try building a stable identifier for items that don't have one
// We need to avoid duplicates otherwise the diffable datasource will crash
let reversedIndex = collapsibleChunks.count - index
let items = collapsibleChunk.compactMap { itemProxy in let items = collapsibleChunk.compactMap { itemProxy in
let timelineItem = buildTimelineItem(for: itemProxy, chunkIndex: reversedIndex) let timelineItem = buildTimelineItem(for: itemProxy)
if timelineItem is EncryptedHistoryRoomTimelineItem { if timelineItem is EncryptedHistoryRoomTimelineItem {
canBackPaginate = false canBackPaginate = false
@ -319,7 +310,7 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
callbacks.send(.isBackPaginating(isBackPaginating)) callbacks.send(.isBackPaginating(isBackPaginating))
} }
private func buildTimelineItem(for itemProxy: TimelineItemProxy, chunkIndex: Int) -> RoomTimelineItemProtocol? { private func buildTimelineItem(for itemProxy: TimelineItemProxy) -> RoomTimelineItemProtocol? {
switch itemProxy { switch itemProxy {
case .event(let eventTimelineItem): case .event(let eventTimelineItem):
let timelineItem = timelineItemFactory.buildTimelineItem(for: eventTimelineItem) let timelineItem = timelineItemFactory.buildTimelineItem(for: eventTimelineItem)

View File

@ -89,9 +89,7 @@ class EventTimelineItemProxy {
}() }()
lazy var canBeRepliedTo = item.canBeRepliedTo() lazy var canBeRepliedTo = item.canBeRepliedTo()
lazy var isRoomState = content.kind().isRoomState
lazy var content = item.content() lazy var content = item.content()
lazy var isOwn = item.isOwn() lazy var isOwn = item.isOwn()
@ -125,17 +123,6 @@ class EventTimelineItemProxy {
lazy var readReceipts = item.readReceipts() lazy var readReceipts = item.readReceipts()
} }
extension TimelineItemContentKind {
var isRoomState: Bool {
switch self {
case .state, .roomMembership:
return true
default:
return false
}
}
}
struct TimelineItemDebugInfo: Identifiable, CustomStringConvertible { struct TimelineItemDebugInfo: Identifiable, CustomStringConvertible {
let id = UUID() let id = UUID()
let model: String let model: String

View File

@ -19,24 +19,18 @@ import UIKit
import UniformTypeIdentifiers import UniformTypeIdentifiers
struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol { struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
private let mediaProvider: MediaProviderProtocol
private let attributedStringBuilder: AttributedStringBuilderProtocol private let attributedStringBuilder: AttributedStringBuilderProtocol
private let stateEventStringBuilder: RoomStateEventStringBuilder private let stateEventStringBuilder: RoomStateEventStringBuilder
private let appSettings: AppSettings
/// The Matrix ID of the current user. /// The Matrix ID of the current user.
private let userID: String private let userID: String
init(userID: String, init(userID: String,
mediaProvider: MediaProviderProtocol,
attributedStringBuilder: AttributedStringBuilderProtocol, attributedStringBuilder: AttributedStringBuilderProtocol,
stateEventStringBuilder: RoomStateEventStringBuilder, stateEventStringBuilder: RoomStateEventStringBuilder) {
appSettings: AppSettings) {
self.userID = userID self.userID = userID
self.mediaProvider = mediaProvider
self.attributedStringBuilder = attributedStringBuilder self.attributedStringBuilder = attributedStringBuilder
self.stateEventStringBuilder = stateEventStringBuilder self.stateEventStringBuilder = stateEventStringBuilder
self.appSettings = appSettings
} }
func buildTimelineItem(for eventItemProxy: EventTimelineItemProxy) -> RoomTimelineItemProtocol? { func buildTimelineItem(for eventItemProxy: EventTimelineItemProxy) -> RoomTimelineItemProtocol? {
@ -61,7 +55,7 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
case .message: case .message:
return buildMessageTimelineItem(eventItemProxy, isOutgoing) return buildMessageTimelineItem(eventItemProxy, isOutgoing)
case .state(let stateKey, let content): case .state(let stateKey, let content):
return buildStateTimelineItem(for: eventItemProxy, state: content, stateKey: stateKey, isOutgoing: isOutgoing) return buildStateTimelineItem(for: eventItemProxy, state: content, isOutgoing: isOutgoing)
case .roomMembership(userId: let userID, change: let change): case .roomMembership(userId: let userID, change: let change):
return buildStateMembershipChangeTimelineItem(for: eventItemProxy, member: userID, membershipChange: change, isOutgoing: isOutgoing) return buildStateMembershipChangeTimelineItem(for: eventItemProxy, member: userID, membershipChange: change, isOutgoing: isOutgoing)
case .profileChange(let displayName, let prevDisplayName, let avatarUrl, let prevAvatarUrl): case .profileChange(let displayName, let prevDisplayName, let avatarUrl, let prevAvatarUrl):
@ -564,7 +558,6 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
private func buildStateTimelineItem(for eventItemProxy: EventTimelineItemProxy, private func buildStateTimelineItem(for eventItemProxy: EventTimelineItemProxy,
state: OtherState, state: OtherState,
stateKey: String,
isOutgoing: Bool) -> RoomTimelineItemProtocol? { isOutgoing: Bool) -> RoomTimelineItemProtocol? {
guard let text = stateEventStringBuilder.buildString(for: state, sender: eventItemProxy.sender, isOutgoing: isOutgoing) else { return nil } guard let text = stateEventStringBuilder.buildString(for: state, sender: eventItemProxy.sender, isOutgoing: isOutgoing) else { return nil }
return buildStateTimelineItem(for: eventItemProxy, text: text, isOutgoing: isOutgoing) return buildStateTimelineItem(for: eventItemProxy, text: text, isOutgoing: isOutgoing)

View File

@ -78,8 +78,4 @@ struct RoomTimelineItemView: View {
VoiceMessageRoomTimelineView(timelineItem: item, playerState: context.viewState.audioPlayerStateProvider?(item.id) ?? AudioPlayerState(id: .timelineItemIdentifier(item.id), duration: 0)) VoiceMessageRoomTimelineView(timelineItem: item, playerState: context.viewState.audioPlayerStateProvider?(item.id) ?? AudioPlayerState(id: .timelineItemIdentifier(item.id), duration: 0))
} }
} }
var timelineGroupStyle: TimelineGroupStyle {
viewState.groupStyle
}
} }

View File

@ -34,10 +34,6 @@ final class RoomTimelineItemViewState: Identifiable, Equatable, ObservableObject
identifier.timelineID identifier.timelineID
} }
var isReactable: Bool {
type.isReactable
}
init(type: RoomTimelineItemType, groupStyle: TimelineGroupStyle) { init(type: RoomTimelineItemType, groupStyle: TimelineGroupStyle) {
self.type = type self.type = type
self.groupStyle = groupStyle self.groupStyle = groupStyle
@ -146,18 +142,4 @@ enum RoomTimelineItemType: Equatable {
return item.id return item.id
} }
} }
/// Whether or not it is possible to send a reaction to this timeline item.
var isReactable: Bool {
switch self {
case .text, .image, .video, .audio, .file, .emote, .notice, .sticker, .location, .poll, .voice:
return true
case .redacted, .encrypted, .unsupported, .state: // Event based items that aren't reactable
return false
case .timelineStart, .encryptedHistory, .separator, .readMarker, .paginationIndicator: // Virtual items are never reactable
return false
case .group:
return false
}
}
} }

View File

@ -30,6 +30,8 @@ final class TimelineProxy: TimelineProxyProtocol {
private var backPaginationStateObservationToken: TaskHandle? private var backPaginationStateObservationToken: TaskHandle?
private var roomTimelineObservationToken: TaskHandle? private var roomTimelineObservationToken: TaskHandle?
// periphery:ignore - retaining purpose
private var timelineListener: RoomTimelineListener? private var timelineListener: RoomTimelineListener?
private let backPaginationStateSubject = PassthroughSubject<BackPaginationStatus, Never>() private let backPaginationStateSubject = PassthroughSubject<BackPaginationStatus, Never>()
@ -47,10 +49,6 @@ final class TimelineProxy: TimelineProxyProtocol {
innerTimelineProvider innerTimelineProvider
} }
var hasPendingUpdatesSubscription: Bool {
innerTimelineProvider != nil
}
deinit { deinit {
backPaginationStateObservationToken?.cancel() backPaginationStateObservationToken?.cancel()
roomTimelineObservationToken?.cancel() roomTimelineObservationToken?.cancel()

View File

@ -125,14 +125,3 @@ protocol TimelineProxyProtocol {
func sendPollResponse(pollStartID: String, answers: [String]) async -> Result<Void, TimelineProxyError> func sendPollResponse(pollStartID: String, answers: [String]) async -> Result<Void, TimelineProxyError>
} }
extension TimelineProxyProtocol {
func sendMessage(_ message: String,
html: String,
intentionalMentions: IntentionalMentions) async -> Result<Void, TimelineProxyError> {
await sendMessage(message,
html: html,
inReplyTo: nil,
intentionalMentions: intentionalMentions)
}
}

View File

@ -21,7 +21,6 @@ enum UserSessionStoreError: Error {
case missingCredentials case missingCredentials
case failedRestoringLogin case failedRestoringLogin
case failedSettingUpSession case failedSettingUpSession
case failedRefreshingRestoreToken
} }
protocol UserSessionStoreProtocol { protocol UserSessionStoreProtocol {

View File

@ -18,7 +18,6 @@ import Foundation
enum UserDiscoveryErrorType: Error { enum UserDiscoveryErrorType: Error {
case failedSearchingUsers case failedSearchingUsers
case failedFetchingSuggestedUsers
} }
// sourcery: AutoMockable // sourcery: AutoMockable

View File

@ -21,7 +21,6 @@ import MatrixRustSDK
class VoiceMessageRecorder: VoiceMessageRecorderProtocol { class VoiceMessageRecorder: VoiceMessageRecorderProtocol {
let audioRecorder: AudioRecorderProtocol let audioRecorder: AudioRecorderProtocol
private let audioConverter: AudioConverterProtocol
private let voiceMessageCache: VoiceMessageCacheProtocol private let voiceMessageCache: VoiceMessageCacheProtocol
private let mediaPlayerProvider: MediaPlayerProviderProtocol private let mediaPlayerProvider: MediaPlayerProviderProtocol
@ -31,7 +30,6 @@ class VoiceMessageRecorder: VoiceMessageRecorderProtocol {
} }
private let mp4accMimeType = "audio/m4a" private let mp4accMimeType = "audio/m4a"
private let waveformSamplesCount = 100
var isRecording: Bool { var isRecording: Bool {
audioRecorder.isRecording audioRecorder.isRecording
@ -53,11 +51,9 @@ class VoiceMessageRecorder: VoiceMessageRecorderProtocol {
init(audioRecorder: AudioRecorderProtocol = AudioRecorder(), init(audioRecorder: AudioRecorderProtocol = AudioRecorder(),
mediaPlayerProvider: MediaPlayerProviderProtocol, mediaPlayerProvider: MediaPlayerProviderProtocol,
audioConverter: AudioConverterProtocol = AudioConverter(),
voiceMessageCache: VoiceMessageCacheProtocol = VoiceMessageCache()) { voiceMessageCache: VoiceMessageCacheProtocol = VoiceMessageCache()) {
self.audioRecorder = audioRecorder self.audioRecorder = audioRecorder
self.mediaPlayerProvider = mediaPlayerProvider self.mediaPlayerProvider = mediaPlayerProvider
self.audioConverter = audioConverter
self.voiceMessageCache = voiceMessageCache self.voiceMessageCache = voiceMessageCache
addObservers() addObservers()

View File

@ -18,7 +18,6 @@ import Combine
import Foundation import Foundation
enum VoiceMessageRecorderError: Error { enum VoiceMessageRecorderError: Error {
case genericError
case missingRecordingFile case missingRecordingFile
case previewNotAvailable case previewNotAvailable
case audioRecorderError(AudioRecorderError) case audioRecorderError(AudioRecorderError)
@ -33,11 +32,9 @@ enum VoiceMessageRecorderAction {
} }
protocol VoiceMessageRecorderProtocol { protocol VoiceMessageRecorderProtocol {
var audioRecorder: AudioRecorderProtocol { get }
var previewAudioPlayerState: AudioPlayerState? { get } var previewAudioPlayerState: AudioPlayerState? { get }
var isRecording: Bool { get } var isRecording: Bool { get }
var recordingURL: URL? { get } var recordingURL: URL? { get }
var recordingDuration: TimeInterval { get }
var actions: AnyPublisher<VoiceMessageRecorderAction, Never> { get } var actions: AnyPublisher<VoiceMessageRecorderAction, Never> { get }
@ -50,7 +47,6 @@ protocol VoiceMessageRecorderProtocol {
func seekPlayback(to progress: Double) async func seekPlayback(to progress: Double) async
func deleteRecording() async func deleteRecording() async
func buildRecordingWaveform() async -> Result<[UInt16], VoiceMessageRecorderError>
func sendVoiceMessage(inRoom roomProxy: RoomProxyProtocol, audioConverter: AudioConverterProtocol) async -> Result<Void, VoiceMessageRecorderError> func sendVoiceMessage(inRoom roomProxy: RoomProxyProtocol, audioConverter: AudioConverterProtocol) async -> Result<Void, VoiceMessageRecorderError>
} }

View File

@ -21,10 +21,6 @@ import UIKit
class UITestsAppCoordinator: AppCoordinatorProtocol, WindowManagerDelegate { class UITestsAppCoordinator: AppCoordinatorProtocol, WindowManagerDelegate {
private let navigationRootCoordinator: NavigationRootCoordinator private let navigationRootCoordinator: NavigationRootCoordinator
private var mockScreen: MockScreen?
private var alternateWindowMockScreen: MockScreen?
let notificationManager: NotificationManagerProtocol = NotificationManagerMock()
let windowManager = WindowManager() let windowManager = WindowManager()
init() { init() {
@ -51,7 +47,6 @@ class UITestsAppCoordinator: AppCoordinatorProtocol, WindowManagerDelegate {
let mockScreen = MockScreen(id: screenID) let mockScreen = MockScreen(id: screenID)
navigationRootCoordinator.setRootCoordinator(mockScreen.coordinator) navigationRootCoordinator.setRootCoordinator(mockScreen.coordinator)
self.mockScreen = mockScreen
} }
func toPresentable() -> AnyView { func toPresentable() -> AnyView {
@ -69,7 +64,6 @@ class UITestsAppCoordinator: AppCoordinatorProtocol, WindowManagerDelegate {
guard let screenID = ProcessInfo.testScreenID, screenID == .appLockFlow || screenID == .appLockFlowDisabled else { return } guard let screenID = ProcessInfo.testScreenID, screenID == .appLockFlow || screenID == .appLockFlowDisabled else { return }
let screen = MockScreen(id: screenID == .appLockFlow ? .appLockFlowAlternateWindow : .appLockFlowDisabledAlternateWindow, windowManager: windowManager) let screen = MockScreen(id: screenID == .appLockFlow ? .appLockFlowAlternateWindow : .appLockFlowDisabledAlternateWindow, windowManager: windowManager)
windowManager.alternateWindow.rootViewController = UIHostingController(rootView: screen.coordinator.toPresentable().statusBarHidden()) windowManager.alternateWindow.rootViewController = UIHostingController(rootView: screen.coordinator.toPresentable().statusBarHidden())
alternateWindowMockScreen = screen
} }
} }

View File

@ -25,6 +25,7 @@ import SwiftUI
/// - Start the app from the tests and call `client.waitForApp()` to establish communication. /// - Start the app from the tests and call `client.waitForApp()` to establish communication.
/// - Send the notification from the tests you would like posted in the app. /// - Send the notification from the tests you would like posted in the app.
class UITestsNotificationCenter: NotificationCenter { class UITestsNotificationCenter: NotificationCenter {
// periphery:ignore - retaining purpose
private var client: UITestsSignalling.Client? private var client: UITestsSignalling.Client?
private var signalCancellable: AnyCancellable? private var signalCancellable: AnyCancellable?

View File

@ -17,7 +17,6 @@
import SwiftUI import SwiftUI
class UnitTestsAppCoordinator: AppCoordinatorProtocol { class UnitTestsAppCoordinator: AppCoordinatorProtocol {
let notificationManager: NotificationManagerProtocol = NotificationManagerMock()
let windowManager = WindowManager() let windowManager = WindowManager()
init() { init() {

View File

@ -39,7 +39,7 @@ enum TestMeasurementParserMetric: String {
/// This class is responsible for extracting XCTest measurement run results from stderr in lieu of an official API /// This class is responsible for extracting XCTest measurement run results from stderr in lieu of an official API
/// Heavily inspired by https://stackoverflow.com/questions/54814422/how-to-extract-performance-metrics-measured-by-measureblock-in-xctest /// Heavily inspired by https://stackoverflow.com/questions/54814422/how-to-extract-performance-metrics-measured-by-measureblock-in-xctest
class TestMeasurementParser { final class TestMeasurementParser {
private let pipe = Pipe() private let pipe = Pipe()
private let regex: NSRegularExpression private let regex: NSRegularExpression
private var results = [String: Double]() private var results = [String: Double]()
@ -118,11 +118,4 @@ class TestMeasurementParser {
testCase.waitForExpectations(timeout: 10.0) testCase.waitForExpectations(timeout: 10.0)
} }
/// Retrieve the recorded average value for a particular metric
/// - Parameter metric: Needs to match one of the metrics passed in the XCTest measure metrics array
/// - Returns: The resulting average value
func valueForMetric(_ metric: TestMeasurementParserMetric) -> Double? {
results[metric.rawValue]
}
} }

View File

@ -59,7 +59,6 @@ struct NotificationContentBuilder {
let notification = UNMutableNotificationContent() let notification = UNMutableNotificationContent()
notification.receiverID = notificationItem.receiverID notification.receiverID = notificationItem.receiverID
notification.roomID = notificationItem.roomID notification.roomID = notificationItem.roomID
notification.eventID = notificationItem.eventID
notification.sound = notificationItem.isNoisy ? UNNotificationSound(named: UNNotificationSoundName(rawValue: "message.caf")) : nil notification.sound = notificationItem.isNoisy ? UNNotificationSound(named: UNNotificationSoundName(rawValue: "message.caf")) : nil
// So that the UI groups notification that are received for the same room but also for the same user // So that the UI groups notification that are received for the same room but also for the same user
// Removing the @ fixes an iOS bug where the notification crashes if the mute button is tapped // Removing the @ fixes an iOS bug where the notification crashes if the mute button is tapped

View File

@ -14,6 +14,8 @@
// limitations under the License. // limitations under the License.
// //
// periphery:ignore:all - this is just a template remove this comment once generating the final file
import Combine import Combine
import SwiftUI import SwiftUI

View File

@ -134,10 +134,10 @@ class AnalyticsTests: XCTestCase {
XCTAssertNil(client.pendingUserProperties, "No user properties should have been set yet.") XCTAssertNil(client.pendingUserProperties, "No user properties should have been set yet.")
// When updating the user properties // When updating the user properties
client.updateUserProperties(AnalyticsEvent.UserProperties(ftueUseCaseSelection: .PersonalMessaging, client.updateUserProperties(AnalyticsEvent.UserProperties(allChatsActiveFilter: nil,
ftueUseCaseSelection: .PersonalMessaging,
numFavouriteRooms: 4, numFavouriteRooms: 4,
numSpaces: 5, numSpaces: 5))
allChatsActiveFilter: nil))
// Then the properties should be cached // Then the properties should be cached
XCTAssertNotNil(client.pendingUserProperties, "The user properties should be cached.") XCTAssertNotNil(client.pendingUserProperties, "The user properties should be cached.")
@ -149,10 +149,9 @@ class AnalyticsTests: XCTestCase {
func testMergingUserProperties() { func testMergingUserProperties() {
// Given a client with a cached use case user properties // Given a client with a cached use case user properties
let client = PostHogAnalyticsClient() let client = PostHogAnalyticsClient()
client.updateUserProperties(AnalyticsEvent.UserProperties(ftueUseCaseSelection: .PersonalMessaging, client.updateUserProperties(AnalyticsEvent.UserProperties(allChatsActiveFilter: nil, ftueUseCaseSelection: .PersonalMessaging,
numFavouriteRooms: nil, numFavouriteRooms: nil,
numSpaces: nil, numSpaces: nil))
allChatsActiveFilter: nil))
XCTAssertNotNil(client.pendingUserProperties, "The user properties should be cached.") XCTAssertNotNil(client.pendingUserProperties, "The user properties should be cached.")
XCTAssertEqual(client.pendingUserProperties?.ftueUseCaseSelection, .PersonalMessaging, "The use case selection should match.") XCTAssertEqual(client.pendingUserProperties?.ftueUseCaseSelection, .PersonalMessaging, "The use case selection should match.")
@ -160,10 +159,9 @@ class AnalyticsTests: XCTestCase {
XCTAssertNil(client.pendingUserProperties?.numSpaces, "The number of spaces should not be set.") XCTAssertNil(client.pendingUserProperties?.numSpaces, "The number of spaces should not be set.")
// When updating the number of spaced // When updating the number of spaced
client.updateUserProperties(AnalyticsEvent.UserProperties(ftueUseCaseSelection: nil, client.updateUserProperties(AnalyticsEvent.UserProperties(allChatsActiveFilter: nil, ftueUseCaseSelection: nil,
numFavouriteRooms: 4, numFavouriteRooms: 4,
numSpaces: 5, numSpaces: 5))
allChatsActiveFilter: nil))
// Then the new properties should be updated and the existing properties should remain unchanged // Then the new properties should be updated and the existing properties should remain unchanged
XCTAssertNotNil(client.pendingUserProperties, "The user properties should be cached.") XCTAssertNotNil(client.pendingUserProperties, "The user properties should be cached.")
@ -175,10 +173,9 @@ class AnalyticsTests: XCTestCase {
func testSendingUserProperties() { func testSendingUserProperties() {
// Given a client with user properties set // Given a client with user properties set
let client = PostHogAnalyticsClient() let client = PostHogAnalyticsClient()
client.updateUserProperties(AnalyticsEvent.UserProperties(ftueUseCaseSelection: .PersonalMessaging, client.updateUserProperties(AnalyticsEvent.UserProperties(allChatsActiveFilter: nil, ftueUseCaseSelection: .PersonalMessaging,
numFavouriteRooms: nil, numFavouriteRooms: nil,
numSpaces: nil, numSpaces: nil))
allChatsActiveFilter: nil))
client.start(analyticsConfiguration: appSettings.analyticsConfiguration) client.start(analyticsConfiguration: appSettings.analyticsConfiguration)
XCTAssertNotNil(client.pendingUserProperties, "The user properties should be cached.") XCTAssertNotNil(client.pendingUserProperties, "The user properties should be cached.")

View File

@ -19,7 +19,7 @@ import UserNotifications
import XCTest import XCTest
extension UNNotification { extension UNNotification {
static func with(userInfo: [AnyHashable: Any], actionIdentifier: String = UNNotificationDefaultActionIdentifier) throws -> UNNotification { static func with(userInfo: [AnyHashable: Any]) throws -> UNNotification {
let content = UNMutableNotificationContent() let content = UNMutableNotificationContent()
content.userInfo = userInfo content.userInfo = userInfo
let request = UNNotificationRequest(identifier: "", let request = UNNotificationRequest(identifier: "",

View File

@ -24,17 +24,12 @@ class RoomPollsHistoryScreenViewModelTests: XCTestCase {
var interactionHandler: PollInteractionHandlerMock! var interactionHandler: PollInteractionHandlerMock!
var timelineController: MockRoomTimelineController! var timelineController: MockRoomTimelineController!
var context: RoomPollsHistoryScreenViewModelType.Context {
viewModel.context
}
override func setUpWithError() throws { override func setUpWithError() throws {
interactionHandler = PollInteractionHandlerMock() interactionHandler = PollInteractionHandlerMock()
timelineController = MockRoomTimelineController() timelineController = MockRoomTimelineController()
let roomProxyMockConfiguration = RoomProxyMockConfiguration(displayName: "Polls") let roomProxyMockConfiguration = RoomProxyMockConfiguration(displayName: "Polls")
roomProxyMockConfiguration.timeline.timelineStartReached = false roomProxyMockConfiguration.timeline.timelineStartReached = false
viewModel = RoomPollsHistoryScreenViewModel(roomProxy: RoomProxyMock(with: roomProxyMockConfiguration), viewModel = RoomPollsHistoryScreenViewModel(pollInteractionHandler: interactionHandler,
pollInteractionHandler: interactionHandler,
roomTimelineController: timelineController, roomTimelineController: timelineController,
userIndicatorController: UserIndicatorControllerMock()) userIndicatorController: UserIndicatorControllerMock())
} }

View File

@ -20,10 +20,6 @@ import XCTest
@MainActor @MainActor
class ServerSelectionViewModelTests: XCTestCase { class ServerSelectionViewModelTests: XCTestCase {
private enum Constants {
static let counterInitialValue = 0
}
var viewModel: ServerSelectionScreenViewModelProtocol! var viewModel: ServerSelectionScreenViewModelProtocol!
var context: ServerSelectionScreenViewModelType.Context! var context: ServerSelectionScreenViewModelType.Context!

View File

@ -23,7 +23,6 @@ import XCTest
class StaticLocationScreenViewModelTests: XCTestCase { class StaticLocationScreenViewModelTests: XCTestCase {
var viewModel: StaticLocationScreenViewModelProtocol! var viewModel: StaticLocationScreenViewModelProtocol!
private let usersSubject = CurrentValueSubject<[UserProfileProxy], Never>([])
private var cancellables = Set<AnyCancellable>() private var cancellables = Set<AnyCancellable>()
var context: StaticLocationScreenViewModel.Context { var context: StaticLocationScreenViewModel.Context {

View File

@ -26,8 +26,6 @@ class VoiceMessageCacheTests: XCTestCase {
private var fileManager: FileManager! private var fileManager: FileManager!
private let someURL = URL("/some/url") private let someURL = URL("/some/url")
private let cachedFileURL = URL("/cache/file/url")
private let audioOGGMimeType = "audio/ogg"
private let testFilename = "test-file" private let testFilename = "test-file"
private let mpeg4aacFileExtension = "m4a" private let mpeg4aacFileExtension = "m4a"
private let testTemporaryDirectory = URL.temporaryDirectory.appendingPathComponent("test-voice-messsage-cache") private let testTemporaryDirectory = URL.temporaryDirectory.appendingPathComponent("test-voice-messsage-cache")

View File

@ -61,7 +61,6 @@ class VoiceMessageRecorderTests: XCTestCase {
voiceMessageRecorder = VoiceMessageRecorder(audioRecorder: audioRecorder, voiceMessageRecorder = VoiceMessageRecorder(audioRecorder: audioRecorder,
mediaPlayerProvider: mediaPlayerProvider, mediaPlayerProvider: mediaPlayerProvider,
audioConverter: audioConverter,
voiceMessageCache: voiceMessageCache) voiceMessageCache: voiceMessageCache)
} }