mirror of
https://github.com/element-hq/element-x-ios.git
synced 2025-03-10 13:37:11 +00:00
Filters, Mark Unread/Read/Favourites FF removals + code and tests clean up (#2541)
This commit is contained in:
parent
da0fcfe052
commit
c66ddfb71e
@ -4,11 +4,12 @@ schemes:
|
|||||||
- IntegrationTests
|
- IntegrationTests
|
||||||
- UITests
|
- UITests
|
||||||
- UnitTests
|
- UnitTests
|
||||||
|
- PreviewTests
|
||||||
targets:
|
targets:
|
||||||
- ElementX
|
- ElementX
|
||||||
- IntegrationTests
|
- IntegrationTests
|
||||||
- NSE
|
- NSE
|
||||||
# - NCE
|
- PreviewTests
|
||||||
- UITests
|
- UITests
|
||||||
- UnitTests
|
- UnitTests
|
||||||
report_exclude:
|
report_exclude:
|
||||||
|
@ -275,21 +275,6 @@ final class AppSettings {
|
|||||||
|
|
||||||
// MARK: - Feature Flags
|
// MARK: - Feature Flags
|
||||||
|
|
||||||
@UserPreference(key: UserDefaultsKeys.userSuggestionsEnabled, defaultValue: false, storageType: .volatile)
|
|
||||||
var userSuggestionsEnabled
|
|
||||||
|
|
||||||
@UserPreference(key: UserDefaultsKeys.mentionsBadgeEnabled, defaultValue: true, storageType: .userDefaults(store))
|
|
||||||
var mentionsBadgeEnabled
|
|
||||||
|
|
||||||
@UserPreference(key: UserDefaultsKeys.roomListFiltersEnabled, defaultValue: false, storageType: .userDefaults(store))
|
|
||||||
var roomListFiltersEnabled
|
|
||||||
|
|
||||||
@UserPreference(key: UserDefaultsKeys.markAsUnreadEnabled, defaultValue: false, storageType: .userDefaults(store))
|
|
||||||
var markAsUnreadEnabled
|
|
||||||
|
|
||||||
@UserPreference(key: UserDefaultsKeys.markAsFavouriteEnabled, defaultValue: false, storageType: .userDefaults(store))
|
|
||||||
var markAsFavouriteEnabled
|
|
||||||
|
|
||||||
@UserPreference(key: UserDefaultsKeys.roomModerationEnabled, defaultValue: false, storageType: .userDefaults(store))
|
@UserPreference(key: UserDefaultsKeys.roomModerationEnabled, defaultValue: false, storageType: .userDefaults(store))
|
||||||
var roomModerationEnabled
|
var roomModerationEnabled
|
||||||
|
|
||||||
|
@ -3787,23 +3787,6 @@ class UserDiscoveryServiceMock: UserDiscoveryServiceProtocol {
|
|||||||
return searchProfilesWithReturnValue
|
return searchProfilesWithReturnValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//MARK: - fetchSuggestions
|
|
||||||
|
|
||||||
var fetchSuggestionsCallsCount = 0
|
|
||||||
var fetchSuggestionsCalled: Bool {
|
|
||||||
return fetchSuggestionsCallsCount > 0
|
|
||||||
}
|
|
||||||
var fetchSuggestionsReturnValue: Result<[UserProfileProxy], UserDiscoveryErrorType>!
|
|
||||||
var fetchSuggestionsClosure: (() async -> Result<[UserProfileProxy], UserDiscoveryErrorType>)?
|
|
||||||
|
|
||||||
func fetchSuggestions() async -> Result<[UserProfileProxy], UserDiscoveryErrorType> {
|
|
||||||
fetchSuggestionsCallsCount += 1
|
|
||||||
if let fetchSuggestionsClosure = fetchSuggestionsClosure {
|
|
||||||
return await fetchSuggestionsClosure()
|
|
||||||
} else {
|
|
||||||
return fetchSuggestionsReturnValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
class UserIndicatorControllerMock: UserIndicatorControllerProtocol {
|
class UserIndicatorControllerMock: UserIndicatorControllerProtocol {
|
||||||
var window: UIWindow?
|
var window: UIWindow?
|
||||||
|
@ -22,18 +22,9 @@ struct BlockedUsersScreenCoordinatorParameters {
|
|||||||
let userIndicatorController: UserIndicatorControllerProtocol
|
let userIndicatorController: UserIndicatorControllerProtocol
|
||||||
}
|
}
|
||||||
|
|
||||||
enum BlockedUsersScreenCoordinatorAction { }
|
|
||||||
|
|
||||||
final class BlockedUsersScreenCoordinator: CoordinatorProtocol {
|
final class BlockedUsersScreenCoordinator: CoordinatorProtocol {
|
||||||
private let viewModel: BlockedUsersScreenViewModelProtocol
|
private let viewModel: BlockedUsersScreenViewModelProtocol
|
||||||
|
|
||||||
private var cancellables = Set<AnyCancellable>()
|
|
||||||
|
|
||||||
private let actionsSubject: PassthroughSubject<BlockedUsersScreenCoordinatorAction, Never> = .init()
|
|
||||||
var actionsPublisher: AnyPublisher<BlockedUsersScreenCoordinatorAction, Never> {
|
|
||||||
actionsSubject.eraseToAnyPublisher()
|
|
||||||
}
|
|
||||||
|
|
||||||
init(parameters: BlockedUsersScreenCoordinatorParameters) {
|
init(parameters: BlockedUsersScreenCoordinatorParameters) {
|
||||||
viewModel = BlockedUsersScreenViewModel(clientProxy: parameters.clientProxy,
|
viewModel = BlockedUsersScreenViewModel(clientProxy: parameters.clientProxy,
|
||||||
userIndicatorController: parameters.userIndicatorController)
|
userIndicatorController: parameters.userIndicatorController)
|
||||||
|
@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
enum BlockedUsersScreenViewModelAction { }
|
|
||||||
|
|
||||||
struct BlockedUsersScreenViewState: BindableState {
|
struct BlockedUsersScreenViewState: BindableState {
|
||||||
var blockedUsers: [String]
|
var blockedUsers: [String]
|
||||||
var processingUserID: String?
|
var processingUserID: String?
|
||||||
|
@ -23,11 +23,6 @@ class BlockedUsersScreenViewModel: BlockedUsersScreenViewModelType, BlockedUsers
|
|||||||
let clientProxy: ClientProxyProtocol
|
let clientProxy: ClientProxyProtocol
|
||||||
let userIndicatorController: UserIndicatorControllerProtocol
|
let userIndicatorController: UserIndicatorControllerProtocol
|
||||||
|
|
||||||
private let actionsSubject: PassthroughSubject<BlockedUsersScreenViewModelAction, Never> = .init()
|
|
||||||
var actionsPublisher: AnyPublisher<BlockedUsersScreenViewModelAction, Never> {
|
|
||||||
actionsSubject.eraseToAnyPublisher()
|
|
||||||
}
|
|
||||||
|
|
||||||
init(clientProxy: ClientProxyProtocol,
|
init(clientProxy: ClientProxyProtocol,
|
||||||
userIndicatorController: UserIndicatorControllerProtocol) {
|
userIndicatorController: UserIndicatorControllerProtocol) {
|
||||||
self.clientProxy = clientProxy
|
self.clientProxy = clientProxy
|
||||||
|
@ -18,7 +18,6 @@ import Combine
|
|||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
protocol BlockedUsersScreenViewModelProtocol {
|
protocol BlockedUsersScreenViewModelProtocol {
|
||||||
var actionsPublisher: AnyPublisher<BlockedUsersScreenViewModelAction, Never> { get }
|
|
||||||
var context: BlockedUsersScreenViewModelType.Context { get }
|
var context: BlockedUsersScreenViewModelType.Context { get }
|
||||||
|
|
||||||
func stop()
|
func stop()
|
||||||
|
@ -89,10 +89,6 @@ struct HomeScreenViewState: BindableState {
|
|||||||
var rooms: [HomeScreenRoom] = []
|
var rooms: [HomeScreenRoom] = []
|
||||||
var roomListMode: HomeScreenRoomListMode = .skeletons
|
var roomListMode: HomeScreenRoomListMode = .skeletons
|
||||||
|
|
||||||
var areFiltersEnabled = false
|
|
||||||
var markAsUnreadEnabled = false
|
|
||||||
var markAsFavouriteEnabled = false
|
|
||||||
|
|
||||||
var hasPendingInvitations = false
|
var hasPendingInvitations = false
|
||||||
var hasUnreadPendingInvitations = false
|
var hasUnreadPendingInvitations = false
|
||||||
|
|
||||||
@ -120,11 +116,7 @@ struct HomeScreenViewState: BindableState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var shouldShowEmptyFilterState: Bool {
|
var shouldShowEmptyFilterState: Bool {
|
||||||
shouldShowFilters && bindings.filtersState.isFiltering && visibleRooms.isEmpty
|
!bindings.isSearchFieldFocused && bindings.filtersState.isFiltering && visibleRooms.isEmpty
|
||||||
}
|
|
||||||
|
|
||||||
var shouldShowFilters: Bool {
|
|
||||||
areFiltersEnabled && !bindings.isSearchFieldFocused
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,28 +100,6 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
|||||||
.weakAssign(to: \.state.selectedRoomID, on: self)
|
.weakAssign(to: \.state.selectedRoomID, on: self)
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
|
|
||||||
appSettings.$roomListFiltersEnabled
|
|
||||||
.sink { [weak self] value in
|
|
||||||
guard let self else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !value {
|
|
||||||
state.areFiltersEnabled = false
|
|
||||||
state.bindings.filtersState.clearFilters()
|
|
||||||
} else {
|
|
||||||
state.areFiltersEnabled = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.store(in: &cancellables)
|
|
||||||
|
|
||||||
appSettings.$markAsUnreadEnabled
|
|
||||||
.weakAssign(to: \.state.markAsUnreadEnabled, on: self)
|
|
||||||
.store(in: &cancellables)
|
|
||||||
|
|
||||||
appSettings.$markAsFavouriteEnabled
|
|
||||||
.weakAssign(to: \.state.markAsFavouriteEnabled, on: self)
|
|
||||||
.store(in: &cancellables)
|
|
||||||
|
|
||||||
appSettings.$hideUnreadMessagesBadge
|
appSettings.$hideUnreadMessagesBadge
|
||||||
.sink { [weak self] _ in self?.updateRooms() }
|
.sink { [weak self] _ in self?.updateRooms() }
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
@ -235,7 +213,7 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
|||||||
if state.bindings.isSearchFieldFocused {
|
if state.bindings.isSearchFieldFocused {
|
||||||
roomSummaryProvider?.setFilter(.search(query: state.bindings.searchQuery))
|
roomSummaryProvider?.setFilter(.search(query: state.bindings.searchQuery))
|
||||||
} else {
|
} else {
|
||||||
roomSummaryProvider?.setFilter(.all(filters: state.areFiltersEnabled ? state.bindings.filtersState.activeFilters.set : []))
|
roomSummaryProvider?.setFilter(.all(filters: state.bindings.filtersState.activeFilters.set))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,10 +89,6 @@ struct RoomListFiltersState {
|
|||||||
return availableFilters.elements
|
return availableFilters.elements
|
||||||
}
|
}
|
||||||
|
|
||||||
var orderedFilters: [RoomListFilter] {
|
|
||||||
activeFilters.elements + availableFilters
|
|
||||||
}
|
|
||||||
|
|
||||||
var isFiltering: Bool {
|
var isFiltering: Bool {
|
||||||
!activeFilters.isEmpty
|
!activeFilters.isEmpty
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,6 @@ struct HomeScreenContent: View {
|
|||||||
.layoutPriority(1)
|
.layoutPriority(1)
|
||||||
}
|
}
|
||||||
case .rooms:
|
case .rooms:
|
||||||
if context.viewState.areFiltersEnabled {
|
|
||||||
// Showing empty views in pinned headers makes the room list spasm when reaching the top
|
// Showing empty views in pinned headers makes the room list spasm when reaching the top
|
||||||
LazyVStack(spacing: 0, pinnedViews: [.sectionHeaders]) {
|
LazyVStack(spacing: 0, pinnedViews: [.sectionHeaders]) {
|
||||||
Section {
|
Section {
|
||||||
@ -72,17 +71,6 @@ struct HomeScreenContent: View {
|
|||||||
.searchable(text: $context.searchQuery)
|
.searchable(text: $context.searchQuery)
|
||||||
.compoundSearchField()
|
.compoundSearchField()
|
||||||
.disableAutocorrection(true)
|
.disableAutocorrection(true)
|
||||||
} else {
|
|
||||||
topSection
|
|
||||||
|
|
||||||
LazyVStack(spacing: 0) {
|
|
||||||
HomeScreenRoomList(context: context)
|
|
||||||
.isSearching($context.isSearchFieldFocused)
|
|
||||||
}
|
|
||||||
.searchable(text: $context.searchQuery)
|
|
||||||
.compoundSearchField()
|
|
||||||
.disableAutocorrection(true)
|
|
||||||
}
|
|
||||||
case .migration:
|
case .migration:
|
||||||
EmptyView()
|
EmptyView()
|
||||||
}
|
}
|
||||||
@ -121,7 +109,7 @@ struct HomeScreenContent: View {
|
|||||||
/// The session verification banner and invites button if either are needed.
|
/// The session verification banner and invites button if either are needed.
|
||||||
private var topSection: some View {
|
private var topSection: some View {
|
||||||
VStack(spacing: 0) {
|
VStack(spacing: 0) {
|
||||||
if context.viewState.shouldShowFilters {
|
if !context.isSearchFieldFocused {
|
||||||
filters
|
filters
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,6 @@ struct HomeScreenRoomList: View {
|
|||||||
|
|
||||||
HomeScreenRoomCell(room: room, context: context, isSelected: isSelected)
|
HomeScreenRoomCell(room: room, context: context, isSelected: isSelected)
|
||||||
.contextMenu {
|
.contextMenu {
|
||||||
if context.viewState.markAsUnreadEnabled {
|
|
||||||
if room.badges.isDotShown {
|
if room.badges.isDotShown {
|
||||||
Button {
|
Button {
|
||||||
context.send(viewAction: .markRoomAsRead(roomIdentifier: room.id))
|
context.send(viewAction: .markRoomAsRead(roomIdentifier: room.id))
|
||||||
@ -53,9 +52,7 @@ struct HomeScreenRoomList: View {
|
|||||||
Text(L10n.screenRoomlistMarkAsUnread)
|
Text(L10n.screenRoomlistMarkAsUnread)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if context.viewState.markAsFavouriteEnabled {
|
|
||||||
if room.isFavourite {
|
if room.isFavourite {
|
||||||
Button {
|
Button {
|
||||||
context.send(viewAction: .markRoomAsFavourite(roomIdentifier: room.id, isFavourite: false))
|
context.send(viewAction: .markRoomAsFavourite(roomIdentifier: room.id, isFavourite: false))
|
||||||
@ -69,7 +66,6 @@ struct HomeScreenRoomList: View {
|
|||||||
Label(L10n.commonFavourite, icon: \.favourite)
|
Label(L10n.commonFavourite, icon: \.favourite)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Button {
|
Button {
|
||||||
context.send(viewAction: .showRoomDetails(roomIdentifier: room.id))
|
context.send(viewAction: .showRoomDetails(roomIdentifier: room.id))
|
||||||
|
@ -46,7 +46,6 @@ final class InviteUsersScreenCoordinator: CoordinatorProtocol {
|
|||||||
roomType: parameters.roomType,
|
roomType: parameters.roomType,
|
||||||
mediaProvider: parameters.mediaProvider,
|
mediaProvider: parameters.mediaProvider,
|
||||||
userDiscoveryService: parameters.userDiscoveryService,
|
userDiscoveryService: parameters.userDiscoveryService,
|
||||||
appSettings: ServiceLocator.shared.settings,
|
|
||||||
userIndicatorController: parameters.userIndicatorController)
|
userIndicatorController: parameters.userIndicatorController)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,6 @@ typealias InviteUsersScreenViewModelType = StateStoreViewModel<InviteUsersScreen
|
|||||||
class InviteUsersScreenViewModel: InviteUsersScreenViewModelType, InviteUsersScreenViewModelProtocol {
|
class InviteUsersScreenViewModel: InviteUsersScreenViewModelType, InviteUsersScreenViewModelProtocol {
|
||||||
private let roomType: InviteUsersScreenRoomType
|
private let roomType: InviteUsersScreenRoomType
|
||||||
private let userDiscoveryService: UserDiscoveryServiceProtocol
|
private let userDiscoveryService: UserDiscoveryServiceProtocol
|
||||||
private let appSettings: AppSettings
|
|
||||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||||
|
|
||||||
private let actionsSubject: PassthroughSubject<InviteUsersScreenViewModelAction, Never> = .init()
|
private let actionsSubject: PassthroughSubject<InviteUsersScreenViewModelAction, Never> = .init()
|
||||||
@ -36,11 +35,9 @@ class InviteUsersScreenViewModel: InviteUsersScreenViewModelType, InviteUsersScr
|
|||||||
roomType: InviteUsersScreenRoomType,
|
roomType: InviteUsersScreenRoomType,
|
||||||
mediaProvider: MediaProviderProtocol,
|
mediaProvider: MediaProviderProtocol,
|
||||||
userDiscoveryService: UserDiscoveryServiceProtocol,
|
userDiscoveryService: UserDiscoveryServiceProtocol,
|
||||||
appSettings: AppSettings,
|
|
||||||
userIndicatorController: UserIndicatorControllerProtocol) {
|
userIndicatorController: UserIndicatorControllerProtocol) {
|
||||||
self.roomType = roomType
|
self.roomType = roomType
|
||||||
self.userDiscoveryService = userDiscoveryService
|
self.userDiscoveryService = userDiscoveryService
|
||||||
self.appSettings = appSettings
|
|
||||||
self.userIndicatorController = userIndicatorController
|
self.userIndicatorController = userIndicatorController
|
||||||
super.init(initialViewState: InviteUsersScreenViewState(selectedUsers: selectedUsers.value, isCreatingRoom: roomType.isCreatingRoom), imageProvider: mediaProvider)
|
super.init(initialViewState: InviteUsersScreenViewState(selectedUsers: selectedUsers.value, isCreatingRoom: roomType.isCreatingRoom), imageProvider: mediaProvider)
|
||||||
|
|
||||||
@ -130,7 +127,7 @@ class InviteUsersScreenViewModel: InviteUsersScreenViewModelType, InviteUsersScr
|
|||||||
|
|
||||||
private func fetchUsers() {
|
private func fetchUsers() {
|
||||||
guard searchQuery.count >= 3 else {
|
guard searchQuery.count >= 3 else {
|
||||||
fetchSuggestions()
|
state.usersSection = .init(type: .suggestions, users: [])
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,20 +139,6 @@ class InviteUsersScreenViewModel: InviteUsersScreenViewModelType, InviteUsersScr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func fetchSuggestions() {
|
|
||||||
guard appSettings.userSuggestionsEnabled else {
|
|
||||||
state.usersSection = .init(type: .suggestions, users: [])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
state.isSearching = true
|
|
||||||
fetchUsersTask = Task {
|
|
||||||
let result = await userDiscoveryService.fetchSuggestions()
|
|
||||||
guard !Task.isCancelled else { return }
|
|
||||||
handleResult(for: .suggestions, result: result)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func handleResult(for sectionType: UserDiscoverySectionType, result: Result<[UserProfileProxy], UserDiscoveryErrorType>) {
|
private func handleResult(for sectionType: UserDiscoverySectionType, result: Result<[UserProfileProxy], UserDiscoveryErrorType>) {
|
||||||
state.isSearching = false
|
state.isSearching = false
|
||||||
|
|
||||||
|
@ -159,13 +159,11 @@ struct InviteUsersScreen: View {
|
|||||||
struct InviteUsersScreen_Previews: PreviewProvider, TestablePreview {
|
struct InviteUsersScreen_Previews: PreviewProvider, TestablePreview {
|
||||||
static let viewModel = {
|
static let viewModel = {
|
||||||
let userDiscoveryService = UserDiscoveryServiceMock()
|
let userDiscoveryService = UserDiscoveryServiceMock()
|
||||||
userDiscoveryService.fetchSuggestionsReturnValue = .success([.mockAlice])
|
|
||||||
userDiscoveryService.searchProfilesWithReturnValue = .success([.mockAlice])
|
userDiscoveryService.searchProfilesWithReturnValue = .success([.mockAlice])
|
||||||
return InviteUsersScreenViewModel(selectedUsers: .init([]),
|
return InviteUsersScreenViewModel(selectedUsers: .init([]),
|
||||||
roomType: .draft,
|
roomType: .draft,
|
||||||
mediaProvider: MockMediaProvider(),
|
mediaProvider: MockMediaProvider(),
|
||||||
userDiscoveryService: userDiscoveryService,
|
userDiscoveryService: userDiscoveryService,
|
||||||
appSettings: ServiceLocator.shared.settings,
|
|
||||||
userIndicatorController: UserIndicatorControllerMock())
|
userIndicatorController: UserIndicatorControllerMock())
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -47,15 +47,8 @@ protocol DeveloperOptionsProtocol: AnyObject {
|
|||||||
var logLevel: TracingConfiguration.LogLevel { get set }
|
var logLevel: TracingConfiguration.LogLevel { get set }
|
||||||
var otlpTracingEnabled: Bool { get set }
|
var otlpTracingEnabled: Bool { get set }
|
||||||
var shouldCollapseRoomStateEvents: Bool { get set }
|
var shouldCollapseRoomStateEvents: Bool { get set }
|
||||||
var userSuggestionsEnabled: Bool { get set }
|
|
||||||
var mentionsBadgeEnabled: Bool { get set }
|
|
||||||
var roomListFiltersEnabled: Bool { get set }
|
|
||||||
var hideUnreadMessagesBadge: Bool { get set }
|
var hideUnreadMessagesBadge: Bool { get set }
|
||||||
|
|
||||||
var markAsUnreadEnabled: Bool { get set }
|
|
||||||
var markAsFavouriteEnabled: Bool { get set }
|
|
||||||
var roomModerationEnabled: Bool { get set }
|
var roomModerationEnabled: Bool { get set }
|
||||||
|
|
||||||
var elementCallBaseURL: URL { get set }
|
var elementCallBaseURL: URL { get set }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,32 +41,7 @@ struct DeveloperOptionsScreen: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Section("Room creation") {
|
|
||||||
Toggle(isOn: $context.userSuggestionsEnabled) {
|
|
||||||
Text("User suggestions")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Section("Mentions") {
|
|
||||||
Toggle(isOn: $context.mentionsBadgeEnabled) {
|
|
||||||
Text("Mentions badge")
|
|
||||||
Text("Requires app reboot")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Section("Room List") {
|
Section("Room List") {
|
||||||
Toggle(isOn: $context.roomListFiltersEnabled) {
|
|
||||||
Text("Show filters")
|
|
||||||
}
|
|
||||||
|
|
||||||
Toggle(isOn: $context.markAsUnreadEnabled) {
|
|
||||||
Text("Mark as unread")
|
|
||||||
}
|
|
||||||
|
|
||||||
Toggle(isOn: $context.markAsFavouriteEnabled) {
|
|
||||||
Text("Mark as favourite")
|
|
||||||
}
|
|
||||||
|
|
||||||
Toggle(isOn: $context.hideUnreadMessagesBadge) {
|
Toggle(isOn: $context.hideUnreadMessagesBadge) {
|
||||||
Text("Hide grey dots")
|
Text("Hide grey dots")
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,6 @@ final class StartChatScreenCoordinator: CoordinatorProtocol {
|
|||||||
self.parameters = parameters
|
self.parameters = parameters
|
||||||
|
|
||||||
viewModel = StartChatScreenViewModel(userSession: parameters.userSession,
|
viewModel = StartChatScreenViewModel(userSession: parameters.userSession,
|
||||||
userSuggestionsEnabled: ServiceLocator.shared.settings.userSuggestionsEnabled,
|
|
||||||
analytics: ServiceLocator.shared.analytics,
|
analytics: ServiceLocator.shared.analytics,
|
||||||
userIndicatorController: parameters.userIndicatorController,
|
userIndicatorController: parameters.userIndicatorController,
|
||||||
userDiscoveryService: parameters.userDiscoveryService)
|
userDiscoveryService: parameters.userDiscoveryService)
|
||||||
|
@ -21,7 +21,6 @@ typealias StartChatScreenViewModelType = StateStoreViewModel<StartChatScreenView
|
|||||||
|
|
||||||
class StartChatScreenViewModel: StartChatScreenViewModelType, StartChatScreenViewModelProtocol {
|
class StartChatScreenViewModel: StartChatScreenViewModelType, StartChatScreenViewModelProtocol {
|
||||||
private let userSession: UserSessionProtocol
|
private let userSession: UserSessionProtocol
|
||||||
private let userSuggestionsEnabled: Bool
|
|
||||||
private let analytics: AnalyticsService
|
private let analytics: AnalyticsService
|
||||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||||
private let userDiscoveryService: UserDiscoveryServiceProtocol
|
private let userDiscoveryService: UserDiscoveryServiceProtocol
|
||||||
@ -33,12 +32,10 @@ class StartChatScreenViewModel: StartChatScreenViewModelType, StartChatScreenVie
|
|||||||
}
|
}
|
||||||
|
|
||||||
init(userSession: UserSessionProtocol,
|
init(userSession: UserSessionProtocol,
|
||||||
userSuggestionsEnabled: Bool,
|
|
||||||
analytics: AnalyticsService,
|
analytics: AnalyticsService,
|
||||||
userIndicatorController: UserIndicatorControllerProtocol,
|
userIndicatorController: UserIndicatorControllerProtocol,
|
||||||
userDiscoveryService: UserDiscoveryServiceProtocol) {
|
userDiscoveryService: UserDiscoveryServiceProtocol) {
|
||||||
self.userSession = userSession
|
self.userSession = userSession
|
||||||
self.userSuggestionsEnabled = userSuggestionsEnabled
|
|
||||||
self.analytics = analytics
|
self.analytics = analytics
|
||||||
self.userIndicatorController = userIndicatorController
|
self.userIndicatorController = userIndicatorController
|
||||||
self.userDiscoveryService = userDiscoveryService
|
self.userDiscoveryService = userDiscoveryService
|
||||||
@ -105,7 +102,7 @@ class StartChatScreenViewModel: StartChatScreenViewModelType, StartChatScreenVie
|
|||||||
|
|
||||||
private func fetchUsers() {
|
private func fetchUsers() {
|
||||||
guard searchQuery.count >= 3 else {
|
guard searchQuery.count >= 3 else {
|
||||||
fetchSuggestions()
|
state.usersSection = .init(type: .suggestions, users: [])
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fetchUsersTask = Task {
|
fetchUsersTask = Task {
|
||||||
@ -115,18 +112,6 @@ class StartChatScreenViewModel: StartChatScreenViewModelType, StartChatScreenVie
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func fetchSuggestions() {
|
|
||||||
guard userSuggestionsEnabled else {
|
|
||||||
state.usersSection = .init(type: .suggestions, users: [])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
fetchUsersTask = Task {
|
|
||||||
let result = await userDiscoveryService.fetchSuggestions()
|
|
||||||
guard !Task.isCancelled else { return }
|
|
||||||
handleResult(for: .suggestions, result: result)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func handleResult(for sectionType: UserDiscoverySectionType, result: Result<[UserProfileProxy], UserDiscoveryErrorType>) {
|
private func handleResult(for sectionType: UserDiscoverySectionType, result: Result<[UserProfileProxy], UserDiscoveryErrorType>) {
|
||||||
switch result {
|
switch result {
|
||||||
case .success(let users):
|
case .success(let users):
|
||||||
|
@ -133,10 +133,8 @@ struct StartChatScreen_Previews: PreviewProvider, TestablePreview {
|
|||||||
mediaProvider: MockMediaProvider(),
|
mediaProvider: MockMediaProvider(),
|
||||||
voiceMessageMediaManager: VoiceMessageMediaManagerMock())
|
voiceMessageMediaManager: VoiceMessageMediaManagerMock())
|
||||||
let userDiscoveryService = UserDiscoveryServiceMock()
|
let userDiscoveryService = UserDiscoveryServiceMock()
|
||||||
userDiscoveryService.fetchSuggestionsReturnValue = .success([.mockAlice])
|
|
||||||
userDiscoveryService.searchProfilesWithReturnValue = .success([.mockAlice])
|
userDiscoveryService.searchProfilesWithReturnValue = .success([.mockAlice])
|
||||||
let viewModel = StartChatScreenViewModel(userSession: userSession,
|
let viewModel = StartChatScreenViewModel(userSession: userSession,
|
||||||
userSuggestionsEnabled: true,
|
|
||||||
analytics: ServiceLocator.shared.analytics,
|
analytics: ServiceLocator.shared.analytics,
|
||||||
userIndicatorController: UserIndicatorControllerMock(),
|
userIndicatorController: UserIndicatorControllerMock(),
|
||||||
userDiscoveryService: userDiscoveryService)
|
userDiscoveryService: userDiscoveryService)
|
||||||
|
@ -575,25 +575,19 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
eventStringBuilder: eventStringBuilder,
|
eventStringBuilder: eventStringBuilder,
|
||||||
name: "AllRooms",
|
name: "AllRooms",
|
||||||
shouldUpdateVisibleRange: true,
|
shouldUpdateVisibleRange: true,
|
||||||
notificationSettings: notificationSettings,
|
notificationSettings: notificationSettings)
|
||||||
backgroundTaskService: backgroundTaskService,
|
|
||||||
appSettings: appSettings)
|
|
||||||
try await roomSummaryProvider?.setRoomList(roomListService.allRooms())
|
try await roomSummaryProvider?.setRoomList(roomListService.allRooms())
|
||||||
|
|
||||||
alternateRoomSummaryProvider = RoomSummaryProvider(roomListService: roomListService,
|
alternateRoomSummaryProvider = RoomSummaryProvider(roomListService: roomListService,
|
||||||
eventStringBuilder: eventStringBuilder,
|
eventStringBuilder: eventStringBuilder,
|
||||||
name: "MessageForwarding",
|
name: "MessageForwarding",
|
||||||
notificationSettings: notificationSettings,
|
notificationSettings: notificationSettings)
|
||||||
backgroundTaskService: backgroundTaskService,
|
|
||||||
appSettings: appSettings)
|
|
||||||
try await alternateRoomSummaryProvider?.setRoomList(roomListService.allRooms())
|
try await alternateRoomSummaryProvider?.setRoomList(roomListService.allRooms())
|
||||||
|
|
||||||
inviteSummaryProvider = RoomSummaryProvider(roomListService: roomListService,
|
inviteSummaryProvider = RoomSummaryProvider(roomListService: roomListService,
|
||||||
eventStringBuilder: eventStringBuilder,
|
eventStringBuilder: eventStringBuilder,
|
||||||
name: "Invites",
|
name: "Invites",
|
||||||
notificationSettings: notificationSettings,
|
notificationSettings: notificationSettings)
|
||||||
backgroundTaskService: backgroundTaskService,
|
|
||||||
appSettings: appSettings)
|
|
||||||
try await inviteSummaryProvider?.setRoomList(roomListService.invites())
|
try await inviteSummaryProvider?.setRoomList(roomListService.invites())
|
||||||
|
|
||||||
self.syncService = syncService
|
self.syncService = syncService
|
||||||
|
@ -18,16 +18,9 @@ import Foundation
|
|||||||
import MatrixRustSDK
|
import MatrixRustSDK
|
||||||
|
|
||||||
final class RoomMemberProxy: RoomMemberProxyProtocol {
|
final class RoomMemberProxy: RoomMemberProxyProtocol {
|
||||||
private let backgroundTaskService: BackgroundTaskServiceProtocol
|
|
||||||
private let member: RoomMember
|
private let member: RoomMember
|
||||||
|
|
||||||
private let backgroundAccountDataTaskName = "SendAccountDataEvent"
|
init(member: RoomMember) {
|
||||||
private var sendAccountDataEventBackgroundTask: BackgroundTaskProtocol?
|
|
||||||
|
|
||||||
private let userInitiatedDispatchQueue = DispatchQueue(label: "io.element.elementx.roommemberproxy.userinitiated", qos: .userInitiated)
|
|
||||||
|
|
||||||
init(member: RoomMember, backgroundTaskService: BackgroundTaskServiceProtocol) {
|
|
||||||
self.backgroundTaskService = backgroundTaskService
|
|
||||||
self.member = member
|
self.member = member
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,11 +17,6 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import MatrixRustSDK
|
import MatrixRustSDK
|
||||||
|
|
||||||
enum RoomMemberProxyError: Error {
|
|
||||||
case ignoreUserFailed
|
|
||||||
case unignoreUserFailed
|
|
||||||
}
|
|
||||||
|
|
||||||
// sourcery: AutoMockable
|
// sourcery: AutoMockable
|
||||||
protocol RoomMemberProxyProtocol: AnyObject {
|
protocol RoomMemberProxyProtocol: AnyObject {
|
||||||
var userID: String { get }
|
var userID: String { get }
|
||||||
|
@ -195,9 +195,7 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
do {
|
do {
|
||||||
let membersNoSyncIterator = try await room.membersNoSync()
|
let membersNoSyncIterator = try await room.membersNoSync()
|
||||||
if let members = membersNoSyncIterator.nextChunk(chunkSize: membersNoSyncIterator.len()) {
|
if let members = membersNoSyncIterator.nextChunk(chunkSize: membersNoSyncIterator.len()) {
|
||||||
membersSubject.value = members.map {
|
membersSubject.value = members.map(RoomMemberProxy.init)
|
||||||
RoomMemberProxy(member: $0, backgroundTaskService: self.backgroundTaskService)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("[RoomProxy] Failed to update members using no sync API: \(error)")
|
MXLog.error("[RoomProxy] Failed to update members using no sync API: \(error)")
|
||||||
@ -207,9 +205,7 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
// Then we update members using the sync API, this is slower but will get us the latest members
|
// Then we update members using the sync API, this is slower but will get us the latest members
|
||||||
let membersIterator = try await room.members()
|
let membersIterator = try await room.members()
|
||||||
if let members = membersIterator.nextChunk(chunkSize: membersIterator.len()) {
|
if let members = membersIterator.nextChunk(chunkSize: membersIterator.len()) {
|
||||||
membersSubject.value = members.map {
|
membersSubject.value = members.map(RoomMemberProxy.init)
|
||||||
RoomMemberProxy(member: $0, backgroundTaskService: self.backgroundTaskService)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("[RoomProxy] Failed to update members using sync API: \(error)")
|
MXLog.error("[RoomProxy] Failed to update members using sync API: \(error)")
|
||||||
@ -228,7 +224,7 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
let member = try await room.member(userId: userID)
|
let member = try await room.member(userId: userID)
|
||||||
return .success(RoomMemberProxy(member: member, backgroundTaskService: backgroundTaskService))
|
return .success(RoomMemberProxy(member: member))
|
||||||
} catch {
|
} catch {
|
||||||
return .failure(.failedRetrievingMember)
|
return .failure(.failedRetrievingMember)
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,6 @@ import MatrixRustSDK
|
|||||||
enum RoomProxyError: Error, Equatable {
|
enum RoomProxyError: Error, Equatable {
|
||||||
case failedRedactingEvent
|
case failedRedactingEvent
|
||||||
case failedReportingContent
|
case failedReportingContent
|
||||||
case failedIgnoringUser
|
|
||||||
case failedRetrievingMember
|
case failedRetrievingMember
|
||||||
case failedLeavingRoom
|
case failedLeavingRoom
|
||||||
case failedAcceptingInvite
|
case failedAcceptingInvite
|
||||||
|
@ -24,8 +24,6 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol {
|
|||||||
private let name: String
|
private let name: String
|
||||||
private let shouldUpdateVisibleRange: Bool
|
private let shouldUpdateVisibleRange: Bool
|
||||||
private let notificationSettings: NotificationSettingsProxyProtocol
|
private let notificationSettings: NotificationSettingsProxyProtocol
|
||||||
private let backgroundTaskService: BackgroundTaskServiceProtocol
|
|
||||||
private let appSettings: AppSettings
|
|
||||||
|
|
||||||
private let roomListPageSize = 200
|
private let roomListPageSize = 200
|
||||||
|
|
||||||
@ -67,17 +65,13 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol {
|
|||||||
eventStringBuilder: RoomEventStringBuilder,
|
eventStringBuilder: RoomEventStringBuilder,
|
||||||
name: String,
|
name: String,
|
||||||
shouldUpdateVisibleRange: Bool = false,
|
shouldUpdateVisibleRange: Bool = false,
|
||||||
notificationSettings: NotificationSettingsProxyProtocol,
|
notificationSettings: NotificationSettingsProxyProtocol) {
|
||||||
backgroundTaskService: BackgroundTaskServiceProtocol,
|
|
||||||
appSettings: AppSettings) {
|
|
||||||
self.roomListService = roomListService
|
self.roomListService = roomListService
|
||||||
serialDispatchQueue = DispatchQueue(label: "io.element.elementx.roomsummaryprovider", qos: .default)
|
serialDispatchQueue = DispatchQueue(label: "io.element.elementx.roomsummaryprovider", qos: .default)
|
||||||
self.eventStringBuilder = eventStringBuilder
|
self.eventStringBuilder = eventStringBuilder
|
||||||
self.name = name
|
self.name = name
|
||||||
self.shouldUpdateVisibleRange = shouldUpdateVisibleRange
|
self.shouldUpdateVisibleRange = shouldUpdateVisibleRange
|
||||||
self.notificationSettings = notificationSettings
|
self.notificationSettings = notificationSettings
|
||||||
self.backgroundTaskService = backgroundTaskService
|
|
||||||
self.appSettings = appSettings
|
|
||||||
|
|
||||||
diffsPublisher
|
diffsPublisher
|
||||||
.receive(on: serialDispatchQueue)
|
.receive(on: serialDispatchQueue)
|
||||||
@ -240,7 +234,7 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol {
|
|||||||
|
|
||||||
var inviterProxy: RoomMemberProxyProtocol?
|
var inviterProxy: RoomMemberProxyProtocol?
|
||||||
if let inviter = roomInfo.inviter {
|
if let inviter = roomInfo.inviter {
|
||||||
inviterProxy = RoomMemberProxy(member: inviter, backgroundTaskService: backgroundTaskService)
|
inviterProxy = RoomMemberProxy(member: inviter)
|
||||||
}
|
}
|
||||||
|
|
||||||
let notificationMode = roomInfo.userDefinedNotificationMode.flatMap { RoomNotificationModeProxy.from(roomNotificationMode: $0) }
|
let notificationMode = roomInfo.userDefinedNotificationMode.flatMap { RoomNotificationModeProxy.from(roomNotificationMode: $0) }
|
||||||
@ -251,14 +245,14 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol {
|
|||||||
avatarURL: roomInfo.avatarUrl.flatMap(URL.init(string:)),
|
avatarURL: roomInfo.avatarUrl.flatMap(URL.init(string:)),
|
||||||
lastMessage: attributedLastMessage,
|
lastMessage: attributedLastMessage,
|
||||||
lastMessageFormattedTimestamp: lastMessageFormattedTimestamp,
|
lastMessageFormattedTimestamp: lastMessageFormattedTimestamp,
|
||||||
unreadMessagesCount: appSettings.mentionsBadgeEnabled ? UInt(roomInfo.numUnreadMessages) : 0,
|
unreadMessagesCount: UInt(roomInfo.numUnreadMessages),
|
||||||
unreadMentionsCount: appSettings.mentionsBadgeEnabled ? UInt(roomInfo.numUnreadMentions) : 0,
|
unreadMentionsCount: UInt(roomInfo.numUnreadMentions),
|
||||||
unreadNotificationsCount: appSettings.mentionsBadgeEnabled ? UInt(roomInfo.numUnreadNotifications) : UInt(roomInfo.notificationCount),
|
unreadNotificationsCount: UInt(roomInfo.numUnreadNotifications),
|
||||||
notificationMode: notificationMode,
|
notificationMode: notificationMode,
|
||||||
canonicalAlias: roomInfo.canonicalAlias,
|
canonicalAlias: roomInfo.canonicalAlias,
|
||||||
inviter: inviterProxy,
|
inviter: inviterProxy,
|
||||||
hasOngoingCall: roomInfo.hasRoomCall,
|
hasOngoingCall: roomInfo.hasRoomCall,
|
||||||
isMarkedUnread: appSettings.markAsUnreadEnabled ? roomInfo.isMarkedUnread : false,
|
isMarkedUnread: roomInfo.isMarkedUnread,
|
||||||
isFavourite: roomInfo.isFavourite)
|
isFavourite: roomInfo.isFavourite)
|
||||||
|
|
||||||
return invalidated ? .invalidated(details: details) : .filled(details: details)
|
return invalidated ? .invalidated(details: details) : .filled(details: details)
|
||||||
|
@ -23,10 +23,6 @@ final class UserDiscoveryService: UserDiscoveryServiceProtocol {
|
|||||||
self.clientProxy = clientProxy
|
self.clientProxy = clientProxy
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchSuggestions() async -> Result<[UserProfileProxy], UserDiscoveryErrorType> {
|
|
||||||
.success(filterAccountOwner([.mockAlice, .mockBob, .mockCharlie]))
|
|
||||||
}
|
|
||||||
|
|
||||||
func searchProfiles(with searchQuery: String) async -> Result<[UserProfileProxy], UserDiscoveryErrorType> {
|
func searchProfiles(with searchQuery: String) async -> Result<[UserProfileProxy], UserDiscoveryErrorType> {
|
||||||
async let queriedProfile = profileIfPossible(with: searchQuery)
|
async let queriedProfile = profileIfPossible(with: searchQuery)
|
||||||
|
|
||||||
|
@ -23,5 +23,4 @@ enum UserDiscoveryErrorType: Error {
|
|||||||
// sourcery: AutoMockable
|
// sourcery: AutoMockable
|
||||||
protocol UserDiscoveryServiceProtocol {
|
protocol UserDiscoveryServiceProtocol {
|
||||||
func searchProfiles(with searchQuery: String) async -> Result<[UserProfileProxy], UserDiscoveryErrorType>
|
func searchProfiles(with searchQuery: String) async -> Result<[UserProfileProxy], UserDiscoveryErrorType>
|
||||||
func fetchSuggestions() async -> Result<[UserProfileProxy], UserDiscoveryErrorType>
|
|
||||||
}
|
}
|
||||||
|
@ -743,10 +743,8 @@ class MockScreen: Identifiable {
|
|||||||
navigationStackCoordinator.setRootCoordinator(coordinator)
|
navigationStackCoordinator.setRootCoordinator(coordinator)
|
||||||
return navigationStackCoordinator
|
return navigationStackCoordinator
|
||||||
case .startChat:
|
case .startChat:
|
||||||
ServiceLocator.shared.settings.userSuggestionsEnabled = true
|
|
||||||
let navigationStackCoordinator = NavigationStackCoordinator()
|
let navigationStackCoordinator = NavigationStackCoordinator()
|
||||||
let userDiscoveryMock = UserDiscoveryServiceMock()
|
let userDiscoveryMock = UserDiscoveryServiceMock()
|
||||||
userDiscoveryMock.fetchSuggestionsReturnValue = .success([.mockAlice, .mockBob, .mockCharlie])
|
|
||||||
userDiscoveryMock.searchProfilesWithReturnValue = .success([])
|
userDiscoveryMock.searchProfilesWithReturnValue = .success([])
|
||||||
let userSession = MockUserSession(clientProxy: ClientProxyMock(.init(userID: "@mock:client.com")),
|
let userSession = MockUserSession(clientProxy: ClientProxyMock(.init(userID: "@mock:client.com")),
|
||||||
mediaProvider: MockMediaProvider(),
|
mediaProvider: MockMediaProvider(),
|
||||||
@ -763,7 +761,6 @@ class MockScreen: Identifiable {
|
|||||||
let navigationStackCoordinator = NavigationStackCoordinator()
|
let navigationStackCoordinator = NavigationStackCoordinator()
|
||||||
let clientProxy = ClientProxyMock(.init(userID: "@mock:client.com"))
|
let clientProxy = ClientProxyMock(.init(userID: "@mock:client.com"))
|
||||||
let userDiscoveryMock = UserDiscoveryServiceMock()
|
let userDiscoveryMock = UserDiscoveryServiceMock()
|
||||||
userDiscoveryMock.fetchSuggestionsReturnValue = .success([])
|
|
||||||
userDiscoveryMock.searchProfilesWithReturnValue = .success([.mockBob, .mockBobby])
|
userDiscoveryMock.searchProfilesWithReturnValue = .success([.mockBob, .mockBobby])
|
||||||
let userSession = MockUserSession(clientProxy: clientProxy, mediaProvider: MockMediaProvider(), voiceMessageMediaManager: VoiceMessageMediaManagerMock())
|
let userSession = MockUserSession(clientProxy: clientProxy, mediaProvider: MockMediaProvider(), voiceMessageMediaManager: VoiceMessageMediaManagerMock())
|
||||||
let coordinator = StartChatScreenCoordinator(parameters: .init(orientationManager: OrientationManagerMock(),
|
let coordinator = StartChatScreenCoordinator(parameters: .init(orientationManager: OrientationManagerMock(),
|
||||||
@ -862,15 +859,13 @@ class MockScreen: Identifiable {
|
|||||||
let coordinator = InvitesScreenCoordinator(parameters: .init(userSession: MockUserSession(clientProxy: clientProxy, mediaProvider: MockMediaProvider(), voiceMessageMediaManager: VoiceMessageMediaManagerMock())))
|
let coordinator = InvitesScreenCoordinator(parameters: .init(userSession: MockUserSession(clientProxy: clientProxy, mediaProvider: MockMediaProvider(), voiceMessageMediaManager: VoiceMessageMediaManagerMock())))
|
||||||
navigationStackCoordinator.setRootCoordinator(coordinator)
|
navigationStackCoordinator.setRootCoordinator(coordinator)
|
||||||
return navigationStackCoordinator
|
return navigationStackCoordinator
|
||||||
case .inviteUsers, .inviteUsersInRoom, .inviteUsersInRoomExistingMembers:
|
case .inviteUsers:
|
||||||
ServiceLocator.shared.settings.userSuggestionsEnabled = true
|
|
||||||
let navigationStackCoordinator = NavigationStackCoordinator()
|
let navigationStackCoordinator = NavigationStackCoordinator()
|
||||||
let userDiscoveryMock = UserDiscoveryServiceMock()
|
let userDiscoveryMock = UserDiscoveryServiceMock()
|
||||||
userDiscoveryMock.fetchSuggestionsReturnValue = .success([.mockAlice, .mockBob, .mockCharlie])
|
|
||||||
userDiscoveryMock.searchProfilesWithReturnValue = .success([])
|
userDiscoveryMock.searchProfilesWithReturnValue = .success([])
|
||||||
let mediaProvider = MockMediaProvider()
|
let mediaProvider = MockMediaProvider()
|
||||||
let usersSubject = CurrentValueSubject<[UserProfileProxy], Never>([])
|
let usersSubject = CurrentValueSubject<[UserProfileProxy], Never>([])
|
||||||
let members: [RoomMemberProxyMock] = id == .inviteUsersInRoomExistingMembers ? [.mockInvitedAlice, .mockBob] : []
|
let members: [RoomMemberProxyMock] = []
|
||||||
let roomProxy = RoomProxyMock(with: .init(name: "test", members: members))
|
let roomProxy = RoomProxyMock(with: .init(name: "test", members: members))
|
||||||
let roomType: InviteUsersScreenRoomType = id == .inviteUsers ? .draft : .room(roomProxy: roomProxy)
|
let roomType: InviteUsersScreenRoomType = id == .inviteUsers ? .draft : .room(roomProxy: roomProxy)
|
||||||
let coordinator = InviteUsersScreenCoordinator(parameters: .init(selectedUsers: usersSubject.asCurrentValuePublisher(),
|
let coordinator = InviteUsersScreenCoordinator(parameters: .init(selectedUsers: usersSubject.asCurrentValuePublisher(),
|
||||||
|
@ -80,8 +80,6 @@ enum UITestsScreenIdentifier: String {
|
|||||||
case invitesWithBadges
|
case invitesWithBadges
|
||||||
case invitesNoInvites
|
case invitesNoInvites
|
||||||
case inviteUsers
|
case inviteUsers
|
||||||
case inviteUsersInRoom
|
|
||||||
case inviteUsersInRoomExistingMembers
|
|
||||||
case createRoom
|
case createRoom
|
||||||
case createRoomNoUsers
|
case createRoomNoUsers
|
||||||
case createPoll
|
case createPoll
|
||||||
|
BIN
PreviewTests/__Snapshots__/PreviewTests/test_homeScreen.Empty.png
(Stored with Git LFS)
BIN
PreviewTests/__Snapshots__/PreviewTests/test_homeScreen.Empty.png
(Stored with Git LFS)
Binary file not shown.
BIN
PreviewTests/__Snapshots__/PreviewTests/test_homeScreen.Loaded.png
(Stored with Git LFS)
BIN
PreviewTests/__Snapshots__/PreviewTests/test_homeScreen.Loaded.png
(Stored with Git LFS)
Binary file not shown.
@ -22,22 +22,4 @@ class InviteUsersScreenUITests: XCTestCase {
|
|||||||
let app = Application.launch(.inviteUsers)
|
let app = Application.launch(.inviteUsers)
|
||||||
try await app.assertScreenshot(.inviteUsers)
|
try await app.assertScreenshot(.inviteUsers)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testSelectedUsers() async throws {
|
|
||||||
let app = Application.launch(.inviteUsers)
|
|
||||||
app.buttons[A11yIdentifiers.inviteUsersScreen.userProfile].firstMatch.tap()
|
|
||||||
try await app.assertScreenshot(.inviteUsers, step: 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func testInviteUsers() async throws {
|
|
||||||
let app = Application.launch(.inviteUsersInRoom)
|
|
||||||
app.buttons[A11yIdentifiers.inviteUsersScreen.userProfile].firstMatch.tap()
|
|
||||||
try await app.assertScreenshot(.inviteUsersInRoom, step: 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func testInviteUserExistingMembers() async throws {
|
|
||||||
let app = Application.launch(.inviteUsersInRoomExistingMembers)
|
|
||||||
app.buttons[A11yIdentifiers.inviteUsersScreen.userProfile].firstMatch.tap()
|
|
||||||
try await app.assertScreenshot(.inviteUsersInRoomExistingMembers, step: 1)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.inviteUsers-1.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.inviteUsers-1.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.inviteUsers.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.inviteUsers.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.inviteUsersInRoom-1.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.inviteUsersInRoom-1.png
(Stored with Git LFS)
Binary file not shown.
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.startChat.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.startChat.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.userSessionScreen-1.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.userSessionScreen-1.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.userSessionScreen-2.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.userSessionScreen-2.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.userSessionScreen-3.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.userSessionScreen-3.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.inviteUsers-1.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.inviteUsers-1.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.inviteUsers.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.inviteUsers.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.inviteUsersInRoom-1.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.inviteUsersInRoom-1.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.inviteUsersInRoomExistingMembers-1.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.inviteUsersInRoomExistingMembers-1.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.startChat.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.startChat.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.userSessionScreen-1.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.userSessionScreen-1.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.userSessionScreen-2.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.userSessionScreen-2.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.userSessionScreen-3.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.userSessionScreen-3.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.inviteUsers-1.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.inviteUsers-1.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.inviteUsers.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.inviteUsers.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.inviteUsersInRoom-1.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.inviteUsersInRoom-1.png
(Stored with Git LFS)
Binary file not shown.
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.startChat.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.startChat.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.userSessionScreen-1.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.userSessionScreen-1.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.userSessionScreen-2.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.userSessionScreen-2.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.userSessionScreen-3.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.userSessionScreen-3.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.inviteUsers-1.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.inviteUsers-1.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.inviteUsers.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.inviteUsers.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.inviteUsersInRoom-1.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.inviteUsersInRoom-1.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.inviteUsersInRoomExistingMembers-1.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.inviteUsersInRoomExistingMembers-1.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.startChat.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.startChat.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.userSessionScreen-1.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.userSessionScreen-1.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.userSessionScreen-2.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.userSessionScreen-2.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.userSessionScreen-3.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.userSessionScreen-3.png
(Stored with Git LFS)
Binary file not shown.
@ -28,7 +28,6 @@ class HomeScreenViewModelTests: XCTestCase {
|
|||||||
var roomSummaryProvider: RoomSummaryProviderMock!
|
var roomSummaryProvider: RoomSummaryProviderMock!
|
||||||
|
|
||||||
override func setUpWithError() throws {
|
override func setUpWithError() throws {
|
||||||
ServiceLocator.shared.settings.roomListFiltersEnabled = true
|
|
||||||
cancellables.removeAll()
|
cancellables.removeAll()
|
||||||
roomSummaryProvider = RoomSummaryProviderMock(.init(state: .loaded(.mockRooms)))
|
roomSummaryProvider = RoomSummaryProviderMock(.init(state: .loaded(.mockRooms)))
|
||||||
clientProxy = ClientProxyMock(.init(userID: "@mock:client.com", roomSummaryProvider: roomSummaryProvider))
|
clientProxy = ClientProxyMock(.init(userID: "@mock:client.com", roomSummaryProvider: roomSummaryProvider))
|
||||||
@ -179,7 +178,6 @@ class HomeScreenViewModelTests: XCTestCase {
|
|||||||
try await Task.sleep(for: .milliseconds(100))
|
try await Task.sleep(for: .milliseconds(100))
|
||||||
XCTAssertEqual(roomSummaryProvider.roomListPublisher.value.first?.name, "Prelude to Foundation")
|
XCTAssertEqual(roomSummaryProvider.roomListPublisher.value.first?.name, "Prelude to Foundation")
|
||||||
XCTAssertEqual(roomSummaryProvider.roomListPublisher.value.count, 1)
|
XCTAssertEqual(roomSummaryProvider.roomListPublisher.value.count, 1)
|
||||||
XCTAssertFalse(context.viewState.shouldShowFilters)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testFiltersEmptyState() async throws {
|
func testFiltersEmptyState() async throws {
|
||||||
|
@ -96,13 +96,11 @@ class InviteUsersScreenViewModelTests: XCTestCase {
|
|||||||
private func setupWithRoomType(roomType: InviteUsersScreenRoomType) {
|
private func setupWithRoomType(roomType: InviteUsersScreenRoomType) {
|
||||||
let usersSubject = CurrentValueSubject<[UserProfileProxy], Never>([])
|
let usersSubject = CurrentValueSubject<[UserProfileProxy], Never>([])
|
||||||
userDiscoveryService = UserDiscoveryServiceMock()
|
userDiscoveryService = UserDiscoveryServiceMock()
|
||||||
userDiscoveryService.fetchSuggestionsReturnValue = .success([])
|
|
||||||
userDiscoveryService.searchProfilesWithReturnValue = .success([])
|
userDiscoveryService.searchProfilesWithReturnValue = .success([])
|
||||||
usersSubject.send([])
|
usersSubject.send([])
|
||||||
let viewModel = InviteUsersScreenViewModel(selectedUsers: usersSubject.asCurrentValuePublisher(),
|
let viewModel = InviteUsersScreenViewModel(selectedUsers: usersSubject.asCurrentValuePublisher(),
|
||||||
roomType: roomType, mediaProvider: MockMediaProvider(),
|
roomType: roomType, mediaProvider: MockMediaProvider(),
|
||||||
userDiscoveryService: userDiscoveryService,
|
userDiscoveryService: userDiscoveryService,
|
||||||
appSettings: ServiceLocator.shared.settings,
|
|
||||||
userIndicatorController: UserIndicatorControllerMock())
|
userIndicatorController: UserIndicatorControllerMock())
|
||||||
viewModel.state.usersSection = .init(type: .suggestions, users: [.mockAlice, .mockBob, .mockCharlie])
|
viewModel.state.usersSection = .init(type: .suggestions, users: [.mockAlice, .mockBob, .mockCharlie])
|
||||||
self.viewModel = viewModel
|
self.viewModel = viewModel
|
||||||
|
@ -31,13 +31,11 @@ class StartChatScreenViewModelTests: XCTestCase {
|
|||||||
override func setUpWithError() throws {
|
override func setUpWithError() throws {
|
||||||
clientProxy = .init(.init(userID: ""))
|
clientProxy = .init(.init(userID: ""))
|
||||||
userDiscoveryService = UserDiscoveryServiceMock()
|
userDiscoveryService = UserDiscoveryServiceMock()
|
||||||
userDiscoveryService.fetchSuggestionsReturnValue = .success([])
|
|
||||||
userDiscoveryService.searchProfilesWithReturnValue = .success([])
|
userDiscoveryService.searchProfilesWithReturnValue = .success([])
|
||||||
let userSession = MockUserSession(clientProxy: clientProxy,
|
let userSession = MockUserSession(clientProxy: clientProxy,
|
||||||
mediaProvider: MockMediaProvider(),
|
mediaProvider: MockMediaProvider(),
|
||||||
voiceMessageMediaManager: VoiceMessageMediaManagerMock())
|
voiceMessageMediaManager: VoiceMessageMediaManagerMock())
|
||||||
viewModel = StartChatScreenViewModel(userSession: userSession,
|
viewModel = StartChatScreenViewModel(userSession: userSession,
|
||||||
userSuggestionsEnabled: true,
|
|
||||||
analytics: ServiceLocator.shared.analytics,
|
analytics: ServiceLocator.shared.analytics,
|
||||||
userIndicatorController: UserIndicatorControllerMock(),
|
userIndicatorController: UserIndicatorControllerMock(),
|
||||||
userDiscoveryService: userDiscoveryService)
|
userDiscoveryService: userDiscoveryService)
|
||||||
@ -46,7 +44,6 @@ class StartChatScreenViewModelTests: XCTestCase {
|
|||||||
func testQueryShowingNoResults() async throws {
|
func testQueryShowingNoResults() async throws {
|
||||||
await search(query: "A")
|
await search(query: "A")
|
||||||
XCTAssertEqual(context.viewState.usersSection.type, .suggestions)
|
XCTAssertEqual(context.viewState.usersSection.type, .suggestions)
|
||||||
XCTAssertTrue(userDiscoveryService.fetchSuggestionsCalled)
|
|
||||||
|
|
||||||
await search(query: "AA")
|
await search(query: "AA")
|
||||||
XCTAssertEqual(context.viewState.usersSection.type, .suggestions)
|
XCTAssertEqual(context.viewState.usersSection.type, .suggestions)
|
||||||
|
1
changelog.d/pr-2541.feature
Normal file
1
changelog.d/pr-2541.feature
Normal file
@ -0,0 +1 @@
|
|||||||
|
The features: Filters, Mark as Read/Unread/Favourites are now available.
|
Loading…
x
Reference in New Issue
Block a user