mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 06:55:59 +00:00
Fixes #2320 - Implement support for (un)marking rooms as favourite from the room list and room detail screens
This commit is contained in:
@@ -53,8 +53,9 @@ final class HomeScreenCoordinator: CoordinatorProtocol {
|
||||
|
||||
init(parameters: HomeScreenCoordinatorParameters) {
|
||||
viewModel = HomeScreenViewModel(userSession: parameters.userSession,
|
||||
selectedRoomPublisher: parameters.selectedRoomPublisher,
|
||||
analyticsService: ServiceLocator.shared.analytics,
|
||||
appSettings: ServiceLocator.shared.settings,
|
||||
selectedRoomPublisher: parameters.selectedRoomPublisher,
|
||||
userIndicatorController: ServiceLocator.shared.userIndicatorController)
|
||||
bugReportService = parameters.bugReportService
|
||||
|
||||
|
||||
@@ -53,6 +53,7 @@ enum HomeScreenViewAction {
|
||||
case globalSearch
|
||||
case markRoomAsUnread(roomIdentifier: String)
|
||||
case markRoomAsRead(roomIdentifier: String)
|
||||
case markRoomAsFavourite(roomIdentifier: String, isFavourite: Bool)
|
||||
}
|
||||
|
||||
enum HomeScreenRoomListMode: CustomStringConvertible {
|
||||
@@ -95,6 +96,7 @@ struct HomeScreenViewState: BindableState {
|
||||
|
||||
var shouldShowFilters = false
|
||||
var markAsUnreadEnabled = false
|
||||
var markAsFavouriteEnabled = false
|
||||
|
||||
var hasPendingInvitations = false
|
||||
var hasUnreadPendingInvitations = false
|
||||
@@ -154,6 +156,8 @@ struct HomeScreenRoom: Identifiable, Equatable {
|
||||
|
||||
let isHighlighted: Bool
|
||||
|
||||
let isFavourite: Bool
|
||||
|
||||
var timestamp: String?
|
||||
|
||||
var lastMessage: AttributedString?
|
||||
@@ -168,6 +172,7 @@ struct HomeScreenRoom: Identifiable, Equatable {
|
||||
name: "Placeholder room name",
|
||||
badges: .init(isDotShown: false, isMentionShown: false, isMuteShown: false, isCallShown: false),
|
||||
isHighlighted: false,
|
||||
isFavourite: false,
|
||||
timestamp: "Now",
|
||||
lastMessage: placeholderLastMessage,
|
||||
isPlaceholder: true)
|
||||
@@ -194,6 +199,7 @@ extension HomeScreenRoom {
|
||||
isMuteShown: isMuteShown,
|
||||
isCallShown: isCallShown),
|
||||
isHighlighted: isHighlighted,
|
||||
isFavourite: details.isFavourite,
|
||||
timestamp: details.lastMessageFormattedTimestamp,
|
||||
lastMessage: details.lastMessage,
|
||||
avatarURL: details.avatarURL)
|
||||
|
||||
@@ -21,6 +21,7 @@ typealias HomeScreenViewModelType = StateStoreViewModel<HomeScreenViewState, Hom
|
||||
|
||||
class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol {
|
||||
private let userSession: UserSessionProtocol
|
||||
private let analyticsService: AnalyticsService
|
||||
private let appSettings: AppSettings
|
||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||
|
||||
@@ -38,10 +39,12 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
||||
}
|
||||
|
||||
init(userSession: UserSessionProtocol,
|
||||
selectedRoomPublisher: CurrentValuePublisher<String?, Never>,
|
||||
analyticsService: AnalyticsService,
|
||||
appSettings: AppSettings,
|
||||
selectedRoomPublisher: CurrentValuePublisher<String?, Never>,
|
||||
userIndicatorController: UserIndicatorControllerProtocol) {
|
||||
self.userSession = userSession
|
||||
self.analyticsService = analyticsService
|
||||
self.appSettings = appSettings
|
||||
self.userIndicatorController = userIndicatorController
|
||||
|
||||
@@ -115,6 +118,10 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
||||
.weakAssign(to: \.state.markAsUnreadEnabled, on: self)
|
||||
.store(in: &cancellables)
|
||||
|
||||
appSettings.$markAsFavouriteEnabled
|
||||
.weakAssign(to: \.state.markAsFavouriteEnabled, on: self)
|
||||
.store(in: &cancellables)
|
||||
|
||||
appSettings.$hideUnreadMessagesBadge
|
||||
.sink { [weak self] _ in self?.updateRooms() }
|
||||
.store(in: &cancellables)
|
||||
@@ -182,9 +189,9 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
||||
return
|
||||
}
|
||||
|
||||
switch await roomProxy.flagAsUnread() {
|
||||
switch await roomProxy.flagAsUnread(true) {
|
||||
case .success:
|
||||
ServiceLocator.shared.analytics.trackInteraction(name: .MobileRoomListRoomContextMenuUnreadToggle)
|
||||
analyticsService.trackInteraction(name: .MobileRoomListRoomContextMenuUnreadToggle)
|
||||
case .failure(let error):
|
||||
MXLog.error("Failed marking room \(roomIdentifier) as unread with error: \(error)")
|
||||
}
|
||||
@@ -196,9 +203,9 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
||||
return
|
||||
}
|
||||
|
||||
switch await roomProxy.flagAsRead() {
|
||||
switch await roomProxy.flagAsUnread(false) {
|
||||
case .success:
|
||||
ServiceLocator.shared.analytics.trackInteraction(name: .MobileRoomListRoomContextMenuUnreadToggle)
|
||||
analyticsService.trackInteraction(name: .MobileRoomListRoomContextMenuUnreadToggle)
|
||||
|
||||
if case .failure(let error) = await roomProxy.markAsRead(receiptType: appSettings.sharePresence ? .read : .readPrivate) {
|
||||
MXLog.error("Failed marking room \(roomIdentifier) as read with error: \(error)")
|
||||
@@ -207,6 +214,10 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
||||
MXLog.error("Failed flagging room \(roomIdentifier) as read with error: \(error)")
|
||||
}
|
||||
}
|
||||
case .markRoomAsFavourite(let roomIdentifier, let isFavourite):
|
||||
Task {
|
||||
await markRoomAsFavourite(roomIdentifier, isFavourite: isFavourite)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -241,7 +252,7 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
||||
return
|
||||
}
|
||||
|
||||
ServiceLocator.shared.analytics.signpost.beginFirstRooms()
|
||||
analyticsService.signpost.beginFirstRooms()
|
||||
|
||||
let hasUserBeenMigrated = appSettings.migratedAccounts[userSession.userID] == true
|
||||
|
||||
@@ -322,7 +333,7 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
||||
}
|
||||
|
||||
if roomListMode == .rooms, state.roomListMode == .skeletons {
|
||||
ServiceLocator.shared.analytics.signpost.endFirstRooms()
|
||||
analyticsService.signpost.endFirstRooms()
|
||||
}
|
||||
|
||||
state.roomListMode = roomListMode
|
||||
@@ -399,6 +410,20 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
||||
roomSummaryProvider.updateVisibleRange(range)
|
||||
}
|
||||
|
||||
private func markRoomAsFavourite(_ roomID: String, isFavourite: Bool) async {
|
||||
guard let roomProxy = await userSession.clientProxy.roomForIdentifier(roomID) else {
|
||||
MXLog.error("Failed retrieving room for identifier: \(roomID)")
|
||||
return
|
||||
}
|
||||
|
||||
switch await roomProxy.flagAsFavourite(isFavourite) {
|
||||
case .success:
|
||||
analyticsService.trackInteraction(name: .MobileRoomListRoomContextMenuFavouriteToggle)
|
||||
case .failure(let error):
|
||||
MXLog.error("Failed marking room \(roomID) as favourite: \(isFavourite) with error: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
private static let leaveRoomLoadingID = "LeaveRoomLoading"
|
||||
|
||||
private func startLeaveRoomProcess(roomId: String) {
|
||||
|
||||
@@ -238,8 +238,9 @@ struct HomeScreen_Previews: PreviewProvider, TestablePreview {
|
||||
voiceMessageMediaManager: VoiceMessageMediaManagerMock())
|
||||
|
||||
return HomeScreenViewModel(userSession: userSession,
|
||||
selectedRoomPublisher: CurrentValueSubject<String?, Never>(nil).asCurrentValuePublisher(),
|
||||
analyticsService: ServiceLocator.shared.analytics,
|
||||
appSettings: appSettings,
|
||||
selectedRoomPublisher: CurrentValueSubject<String?, Never>(nil).asCurrentValuePublisher(),
|
||||
userIndicatorController: ServiceLocator.shared.userIndicatorController)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,8 +155,9 @@ struct HomeScreenEmptyStateView_Previews: PreviewProvider, TestablePreview {
|
||||
voiceMessageMediaManager: VoiceMessageMediaManagerMock())
|
||||
|
||||
return HomeScreenViewModel(userSession: userSession,
|
||||
selectedRoomPublisher: CurrentValueSubject<String?, Never>(nil).asCurrentValuePublisher(),
|
||||
analyticsService: ServiceLocator.shared.analytics,
|
||||
appSettings: ServiceLocator.shared.settings,
|
||||
selectedRoomPublisher: CurrentValueSubject<String?, Never>(nil).asCurrentValuePublisher(),
|
||||
userIndicatorController: ServiceLocator.shared.userIndicatorController)
|
||||
}()
|
||||
}
|
||||
|
||||
+2
-1
@@ -73,8 +73,9 @@ struct HomeScreenRecoveryKeyConfirmationBanner_Previews: PreviewProvider, Testab
|
||||
voiceMessageMediaManager: VoiceMessageMediaManagerMock())
|
||||
|
||||
return HomeScreenViewModel(userSession: userSession,
|
||||
selectedRoomPublisher: CurrentValueSubject<String?, Never>(nil).asCurrentValuePublisher(),
|
||||
analyticsService: ServiceLocator.shared.analytics,
|
||||
appSettings: ServiceLocator.shared.settings,
|
||||
selectedRoomPublisher: CurrentValueSubject<String?, Never>(nil).asCurrentValuePublisher(),
|
||||
userIndicatorController: ServiceLocator.shared.userIndicatorController)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,8 +181,9 @@ struct HomeScreenRoomCell_Previews: PreviewProvider, TestablePreview {
|
||||
voiceMessageMediaManager: VoiceMessageMediaManagerMock())
|
||||
|
||||
return HomeScreenViewModel(userSession: userSession,
|
||||
selectedRoomPublisher: CurrentValueSubject<String?, Never>(nil).asCurrentValuePublisher(),
|
||||
analyticsService: ServiceLocator.shared.analytics,
|
||||
appSettings: ServiceLocator.shared.settings,
|
||||
selectedRoomPublisher: CurrentValueSubject<String?, Never>(nil).asCurrentValuePublisher(),
|
||||
userIndicatorController: ServiceLocator.shared.userIndicatorController)
|
||||
}()
|
||||
|
||||
@@ -193,8 +194,9 @@ struct HomeScreenRoomCell_Previews: PreviewProvider, TestablePreview {
|
||||
voiceMessageMediaManager: VoiceMessageMediaManagerMock())
|
||||
|
||||
return HomeScreenViewModel(userSession: userSession,
|
||||
selectedRoomPublisher: CurrentValueSubject<String?, Never>(nil).asCurrentValuePublisher(),
|
||||
analyticsService: ServiceLocator.shared.analytics,
|
||||
appSettings: ServiceLocator.shared.settings,
|
||||
selectedRoomPublisher: CurrentValueSubject<String?, Never>(nil).asCurrentValuePublisher(),
|
||||
userIndicatorController: ServiceLocator.shared.userIndicatorController)
|
||||
}()
|
||||
|
||||
|
||||
@@ -63,6 +63,22 @@ struct HomeScreenRoomList: View {
|
||||
}
|
||||
}
|
||||
|
||||
if context.viewState.markAsFavouriteEnabled {
|
||||
if room.isFavourite {
|
||||
Button {
|
||||
context.send(viewAction: .markRoomAsFavourite(roomIdentifier: room.id, isFavourite: false))
|
||||
} label: {
|
||||
Label(L10n.commonFavourited, icon: \.favouriteSolid)
|
||||
}
|
||||
} else {
|
||||
Button {
|
||||
context.send(viewAction: .markRoomAsFavourite(roomIdentifier: room.id, isFavourite: true))
|
||||
} label: {
|
||||
Label(L10n.commonFavourite, icon: \.favourite)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
context.send(viewAction: .showRoomDetails(roomIdentifier: room.id))
|
||||
} label: {
|
||||
|
||||
@@ -73,8 +73,9 @@ struct HomeScreenSessionVerificationBanner_Previews: PreviewProvider, TestablePr
|
||||
voiceMessageMediaManager: VoiceMessageMediaManagerMock())
|
||||
|
||||
return HomeScreenViewModel(userSession: userSession,
|
||||
selectedRoomPublisher: CurrentValueSubject<String?, Never>(nil).asCurrentValuePublisher(),
|
||||
analyticsService: ServiceLocator.shared.analytics,
|
||||
appSettings: ServiceLocator.shared.settings,
|
||||
selectedRoomPublisher: CurrentValueSubject<String?, Never>(nil).asCurrentValuePublisher(),
|
||||
userIndicatorController: ServiceLocator.shared.userIndicatorController)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user