mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-04 19:11:45 +00:00
Remove message pinning FF (#3318)
This commit is contained in:
@@ -271,9 +271,6 @@ final class AppSettings {
|
|||||||
@UserPreference(key: UserDefaultsKeys.fuzzyRoomListSearchEnabled, defaultValue: false, storageType: .userDefaults(store))
|
@UserPreference(key: UserDefaultsKeys.fuzzyRoomListSearchEnabled, defaultValue: false, storageType: .userDefaults(store))
|
||||||
var fuzzyRoomListSearchEnabled
|
var fuzzyRoomListSearchEnabled
|
||||||
|
|
||||||
@UserPreference(key: UserDefaultsKeys.pinningEnabled, defaultValue: true, storageType: .userDefaults(store))
|
|
||||||
var pinningEnabled
|
|
||||||
|
|
||||||
enum SlidingSyncDiscovery: Codable { case proxy, native, forceNative }
|
enum SlidingSyncDiscovery: Codable { case proxy, native, forceNative }
|
||||||
@UserPreference(key: UserDefaultsKeys.slidingSyncDiscovery, defaultValue: .native, storageType: .userDefaults(store))
|
@UserPreference(key: UserDefaultsKeys.slidingSyncDiscovery, defaultValue: .native, storageType: .userDefaults(store))
|
||||||
var slidingSyncDiscovery: SlidingSyncDiscovery
|
var slidingSyncDiscovery: SlidingSyncDiscovery
|
||||||
|
|||||||
@@ -44,7 +44,6 @@ struct RoomDetailsScreenViewState: BindableState {
|
|||||||
var canEditRolesOrPermissions = false
|
var canEditRolesOrPermissions = false
|
||||||
var notificationSettingsState: RoomDetailsNotificationSettingsState = .loading
|
var notificationSettingsState: RoomDetailsNotificationSettingsState = .loading
|
||||||
var canJoinCall = false
|
var canJoinCall = false
|
||||||
var isPinningEnabled = false
|
|
||||||
var pinnedEventsActionState = RoomDetailsScreenPinnedEventsActionState.loading
|
var pinnedEventsActionState = RoomDetailsScreenPinnedEventsActionState.loading
|
||||||
|
|
||||||
var canEdit: Bool {
|
var canEdit: Bool {
|
||||||
|
|||||||
@@ -75,13 +75,8 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr
|
|||||||
bindings: .init()),
|
bindings: .init()),
|
||||||
mediaProvider: mediaProvider)
|
mediaProvider: mediaProvider)
|
||||||
|
|
||||||
appSettings.$pinningEnabled
|
appMediator.networkMonitor.reachabilityPublisher
|
||||||
.weakAssign(to: \.state.isPinningEnabled, on: self)
|
.filter { $0 == .reachable }
|
||||||
.store(in: &cancellables)
|
|
||||||
|
|
||||||
appSettings.$pinningEnabled
|
|
||||||
.combineLatest(appMediator.networkMonitor.reachabilityPublisher)
|
|
||||||
.filter { $0.0 && $0.1 == .reachable }
|
|
||||||
.receive(on: DispatchQueue.main)
|
.receive(on: DispatchQueue.main)
|
||||||
.sink { [weak self] _ in
|
.sink { [weak self] _ in
|
||||||
self?.setupPinnedEventsTimelineProviderIfNeeded()
|
self?.setupPinnedEventsTimelineProviderIfNeeded()
|
||||||
|
|||||||
@@ -189,15 +189,13 @@ struct RoomDetailsScreen: View {
|
|||||||
context.send(viewAction: .toggleFavourite(isFavourite: newValue))
|
context.send(viewAction: .toggleFavourite(isFavourite: newValue))
|
||||||
}
|
}
|
||||||
|
|
||||||
if context.viewState.isPinningEnabled {
|
ListRow(label: .default(title: L10n.screenRoomDetailsPinnedEventsRowTitle,
|
||||||
ListRow(label: .default(title: L10n.screenRoomDetailsPinnedEventsRowTitle,
|
icon: \.pin),
|
||||||
icon: \.pin),
|
details: context.viewState.pinnedEventsActionState.isLoading ? .isWaiting(true) : .title(context.viewState.pinnedEventsActionState.count),
|
||||||
details: context.viewState.pinnedEventsActionState.isLoading ? .isWaiting(true) : .title(context.viewState.pinnedEventsActionState.count),
|
kind: context.viewState.pinnedEventsActionState.isLoading ? .label : .navigationLink(action: {
|
||||||
kind: context.viewState.pinnedEventsActionState.isLoading ? .label : .navigationLink(action: {
|
context.send(viewAction: .processTapPinnedEvents)
|
||||||
context.send(viewAction: .processTapPinnedEvents)
|
}))
|
||||||
}))
|
.disabled(context.viewState.pinnedEventsActionState.isLoading)
|
||||||
.disabled(context.viewState.pinnedEventsActionState.isLoading)
|
|
||||||
}
|
|
||||||
|
|
||||||
if context.viewState.canEditRolesOrPermissions, context.viewState.dmRecipient == nil {
|
if context.viewState.canEditRolesOrPermissions, context.viewState.dmRecipient == nil {
|
||||||
ListRow(label: .default(title: L10n.screenRoomDetailsRolesAndPermissions,
|
ListRow(label: .default(title: L10n.screenRoomDetailsRolesAndPermissions,
|
||||||
@@ -320,8 +318,6 @@ struct RoomDetailsScreen_Previews: PreviewProvider, TestablePreview {
|
|||||||
var notificationSettingsProxyMockConfiguration = NotificationSettingsProxyMockConfiguration()
|
var notificationSettingsProxyMockConfiguration = NotificationSettingsProxyMockConfiguration()
|
||||||
notificationSettingsProxyMockConfiguration.roomMode.isDefault = false
|
notificationSettingsProxyMockConfiguration.roomMode.isDefault = false
|
||||||
let notificationSettingsProxy = NotificationSettingsProxyMock(with: notificationSettingsProxyMockConfiguration)
|
let notificationSettingsProxy = NotificationSettingsProxyMock(with: notificationSettingsProxyMockConfiguration)
|
||||||
let appSettings = AppSettings()
|
|
||||||
appSettings.pinningEnabled = true
|
|
||||||
|
|
||||||
return RoomDetailsScreenViewModel(roomProxy: roomProxy,
|
return RoomDetailsScreenViewModel(roomProxy: roomProxy,
|
||||||
clientProxy: ClientProxyMock(.init()),
|
clientProxy: ClientProxyMock(.init()),
|
||||||
@@ -331,7 +327,7 @@ struct RoomDetailsScreen_Previews: PreviewProvider, TestablePreview {
|
|||||||
notificationSettingsProxy: notificationSettingsProxy,
|
notificationSettingsProxy: notificationSettingsProxy,
|
||||||
attributedStringBuilder: AttributedStringBuilder(mentionBuilder: MentionBuilder()),
|
attributedStringBuilder: AttributedStringBuilder(mentionBuilder: MentionBuilder()),
|
||||||
appMediator: AppMediatorMock.default,
|
appMediator: AppMediatorMock.default,
|
||||||
appSettings: appSettings)
|
appSettings: ServiceLocator.shared.settings)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
static let dmRoomViewModel = {
|
static let dmRoomViewModel = {
|
||||||
@@ -348,8 +344,6 @@ struct RoomDetailsScreen_Previews: PreviewProvider, TestablePreview {
|
|||||||
canonicalAlias: "#alias:domain.com",
|
canonicalAlias: "#alias:domain.com",
|
||||||
members: members))
|
members: members))
|
||||||
let notificationSettingsProxy = NotificationSettingsProxyMock(with: .init())
|
let notificationSettingsProxy = NotificationSettingsProxyMock(with: .init())
|
||||||
let appSettings = AppSettings()
|
|
||||||
appSettings.pinningEnabled = true
|
|
||||||
|
|
||||||
return RoomDetailsScreenViewModel(roomProxy: roomProxy,
|
return RoomDetailsScreenViewModel(roomProxy: roomProxy,
|
||||||
clientProxy: ClientProxyMock(.init()),
|
clientProxy: ClientProxyMock(.init()),
|
||||||
@@ -359,7 +353,7 @@ struct RoomDetailsScreen_Previews: PreviewProvider, TestablePreview {
|
|||||||
notificationSettingsProxy: notificationSettingsProxy,
|
notificationSettingsProxy: notificationSettingsProxy,
|
||||||
attributedStringBuilder: AttributedStringBuilder(mentionBuilder: MentionBuilder()),
|
attributedStringBuilder: AttributedStringBuilder(mentionBuilder: MentionBuilder()),
|
||||||
appMediator: AppMediatorMock.default,
|
appMediator: AppMediatorMock.default,
|
||||||
appSettings: appSettings)
|
appSettings: ServiceLocator.shared.settings)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
static let simpleRoomViewModel = {
|
static let simpleRoomViewModel = {
|
||||||
@@ -375,8 +369,6 @@ struct RoomDetailsScreen_Previews: PreviewProvider, TestablePreview {
|
|||||||
isEncrypted: false,
|
isEncrypted: false,
|
||||||
members: members))
|
members: members))
|
||||||
let notificationSettingsProxy = NotificationSettingsProxyMock(with: .init())
|
let notificationSettingsProxy = NotificationSettingsProxyMock(with: .init())
|
||||||
let appSettings = AppSettings()
|
|
||||||
appSettings.pinningEnabled = true
|
|
||||||
|
|
||||||
return RoomDetailsScreenViewModel(roomProxy: roomProxy,
|
return RoomDetailsScreenViewModel(roomProxy: roomProxy,
|
||||||
clientProxy: ClientProxyMock(.init()),
|
clientProxy: ClientProxyMock(.init()),
|
||||||
@@ -386,7 +378,7 @@ struct RoomDetailsScreen_Previews: PreviewProvider, TestablePreview {
|
|||||||
notificationSettingsProxy: notificationSettingsProxy,
|
notificationSettingsProxy: notificationSettingsProxy,
|
||||||
attributedStringBuilder: AttributedStringBuilder(mentionBuilder: MentionBuilder()),
|
attributedStringBuilder: AttributedStringBuilder(mentionBuilder: MentionBuilder()),
|
||||||
appMediator: AppMediatorMock.default,
|
appMediator: AppMediatorMock.default,
|
||||||
appSettings: appSettings)
|
appSettings: ServiceLocator.shared.settings)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
|
|||||||
@@ -28,11 +28,10 @@ struct RoomScreenViewState: BindableState {
|
|||||||
var roomAvatar: RoomAvatar
|
var roomAvatar: RoomAvatar
|
||||||
|
|
||||||
var lastScrollDirection: ScrollDirection?
|
var lastScrollDirection: ScrollDirection?
|
||||||
var isPinningEnabled = false
|
|
||||||
// This is used to control the banner
|
// This is used to control the banner
|
||||||
var pinnedEventsBannerState: PinnedEventsBannerState = .loading(numbersOfEvents: 0)
|
var pinnedEventsBannerState: PinnedEventsBannerState = .loading(numbersOfEvents: 0)
|
||||||
var shouldShowPinnedEventsBanner: Bool {
|
var shouldShowPinnedEventsBanner: Bool {
|
||||||
isPinningEnabled && !pinnedEventsBannerState.isEmpty && lastScrollDirection != .top
|
!pinnedEventsBannerState.isEmpty && lastScrollDirection != .top
|
||||||
}
|
}
|
||||||
|
|
||||||
var canJoinCall = false
|
var canJoinCall = false
|
||||||
|
|||||||
@@ -124,15 +124,8 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
|||||||
}
|
}
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
|
|
||||||
let pinningEnabledPublisher = appSettings.$pinningEnabled
|
appMediator.networkMonitor.reachabilityPublisher
|
||||||
|
.filter { $0 == .reachable }
|
||||||
pinningEnabledPublisher
|
|
||||||
.weakAssign(to: \.state.isPinningEnabled, on: self)
|
|
||||||
.store(in: &cancellables)
|
|
||||||
|
|
||||||
pinningEnabledPublisher
|
|
||||||
.combineLatest(appMediator.networkMonitor.reachabilityPublisher)
|
|
||||||
.filter { $0.0 && $0.1 == .reachable }
|
|
||||||
.receive(on: DispatchQueue.main)
|
.receive(on: DispatchQueue.main)
|
||||||
.sink { [weak self] _ in
|
.sink { [weak self] _ in
|
||||||
self?.setupPinnedEventsTimelineProviderIfNeeded()
|
self?.setupPinnedEventsTimelineProviderIfNeeded()
|
||||||
|
|||||||
-1
@@ -46,7 +46,6 @@ protocol DeveloperOptionsProtocol: AnyObject {
|
|||||||
var hideUnreadMessagesBadge: Bool { get set }
|
var hideUnreadMessagesBadge: Bool { get set }
|
||||||
var elementCallBaseURLOverride: URL? { get set }
|
var elementCallBaseURLOverride: URL? { get set }
|
||||||
var fuzzyRoomListSearchEnabled: Bool { get set }
|
var fuzzyRoomListSearchEnabled: Bool { get set }
|
||||||
var pinningEnabled: Bool { get set }
|
|
||||||
var enableOnlySignedDeviceIsolationMode: Bool { get set }
|
var enableOnlySignedDeviceIsolationMode: Bool { get set }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
-7
@@ -35,13 +35,6 @@ struct DeveloperOptionsScreen: View {
|
|||||||
Text(context.viewState.slidingSyncFooter)
|
Text(context.viewState.slidingSyncFooter)
|
||||||
}
|
}
|
||||||
|
|
||||||
Section("Message Pinning") {
|
|
||||||
Toggle(isOn: $context.pinningEnabled) {
|
|
||||||
Text("Enable message pinning")
|
|
||||||
Text("Requires app reboot")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Section("Room List") {
|
Section("Room List") {
|
||||||
Toggle(isOn: $context.hideUnreadMessagesBadge) {
|
Toggle(isOn: $context.hideUnreadMessagesBadge) {
|
||||||
Text("Hide grey dots")
|
Text("Hide grey dots")
|
||||||
|
|||||||
@@ -336,8 +336,7 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
|||||||
state.canCurrentUserRedactSelf = false
|
state.canCurrentUserRedactSelf = false
|
||||||
}
|
}
|
||||||
|
|
||||||
if appSettings.pinningEnabled,
|
if case let .success(value) = await roomProxy.canUserPinOrUnpin(userID: roomProxy.ownUserID) {
|
||||||
case let .success(value) = await roomProxy.canUserPinOrUnpin(userID: roomProxy.ownUserID) {
|
|
||||||
state.canCurrentUserPin = value
|
state.canCurrentUserPin = value
|
||||||
} else {
|
} else {
|
||||||
state.canCurrentUserPin = false
|
state.canCurrentUserPin = false
|
||||||
@@ -444,9 +443,7 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func updatePinnedEventIDs() async {
|
private func updatePinnedEventIDs() async {
|
||||||
if appSettings.pinningEnabled {
|
state.pinnedEventIDs = await roomProxy.pinnedEventIDs
|
||||||
state.pinnedEventIDs = await roomProxy.pinnedEventIDs
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func setupDirectRoomSubscriptionsIfNeeded() {
|
private func setupDirectRoomSubscriptionsIfNeeded() {
|
||||||
|
|||||||
@@ -355,8 +355,6 @@ private extension View {
|
|||||||
struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview {
|
struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview {
|
||||||
static let viewModel = TimelineViewModel.mock
|
static let viewModel = TimelineViewModel.mock
|
||||||
static let viewModelWithPins: TimelineViewModel = {
|
static let viewModelWithPins: TimelineViewModel = {
|
||||||
var settings = AppSettings()
|
|
||||||
settings.pinningEnabled = true
|
|
||||||
let roomProxy = JoinedRoomProxyMock(.init(name: "Preview Room", pinnedEventIDs: [""]))
|
let roomProxy = JoinedRoomProxyMock(.init(name: "Preview Room", pinnedEventIDs: [""]))
|
||||||
return TimelineViewModel(roomProxy: roomProxy,
|
return TimelineViewModel(roomProxy: roomProxy,
|
||||||
focussedEventID: nil,
|
focussedEventID: nil,
|
||||||
@@ -366,7 +364,7 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview
|
|||||||
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
|
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
|
||||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
||||||
appMediator: AppMediatorMock.default,
|
appMediator: AppMediatorMock.default,
|
||||||
appSettings: settings,
|
appSettings: ServiceLocator.shared.settings,
|
||||||
analyticsService: ServiceLocator.shared.analytics)
|
analyticsService: ServiceLocator.shared.analytics)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@@ -384,7 +382,7 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview
|
|||||||
.previewDisplayName("Encryption Indicators")
|
.previewDisplayName("Encryption Indicators")
|
||||||
pinned
|
pinned
|
||||||
.previewDisplayName("Pinned messages")
|
.previewDisplayName("Pinned messages")
|
||||||
.snapshotPreferences(delay: 1.0)
|
.snapshotPreferences(delay: 2.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// These always include a reply
|
// These always include a reply
|
||||||
|
|||||||
@@ -816,12 +816,13 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private lazy var eventFilters: TimelineEventTypeFilter = {
|
private let eventFilters: TimelineEventTypeFilter = {
|
||||||
var stateEventFilters: [StateEventType] = [.roomAliases,
|
var stateEventFilters: [StateEventType] = [.roomAliases,
|
||||||
.roomCanonicalAlias,
|
.roomCanonicalAlias,
|
||||||
.roomGuestAccess,
|
.roomGuestAccess,
|
||||||
.roomHistoryVisibility,
|
.roomHistoryVisibility,
|
||||||
.roomJoinRules,
|
.roomJoinRules,
|
||||||
|
.roomPinnedEvents,
|
||||||
.roomPowerLevels,
|
.roomPowerLevels,
|
||||||
.roomServerAcl,
|
.roomServerAcl,
|
||||||
.roomTombstone,
|
.roomTombstone,
|
||||||
@@ -830,12 +831,6 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
.policyRuleRoom,
|
.policyRuleRoom,
|
||||||
.policyRuleServer,
|
.policyRuleServer,
|
||||||
.policyRuleUser]
|
.policyRuleUser]
|
||||||
|
|
||||||
// Reminder: once the feature flag is not required anymore, change the lazy var back to a let
|
|
||||||
if !appSettings.pinningEnabled {
|
|
||||||
stateEventFilters.append(.roomPinnedEvents)
|
|
||||||
}
|
|
||||||
|
|
||||||
return .exclude(eventTypes: stateEventFilters.map { FilterTimelineEventType.state(eventType: $0) })
|
return .exclude(eventTypes: stateEventFilters.map { FilterTimelineEventType.state(eventType: $0) })
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ class RoomScreenViewModelTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func testPinnedEventsBanner() async throws {
|
func testPinnedEventsBanner() async throws {
|
||||||
ServiceLocator.shared.settings.pinningEnabled = true
|
|
||||||
let timelineSubject = PassthroughSubject<TimelineProxyProtocol, Never>()
|
let timelineSubject = PassthroughSubject<TimelineProxyProtocol, Never>()
|
||||||
let updateSubject = PassthroughSubject<JoinedRoomProxyAction, Never>()
|
let updateSubject = PassthroughSubject<JoinedRoomProxyAction, Never>()
|
||||||
let roomProxyMock = JoinedRoomProxyMock(.init())
|
let roomProxyMock = JoinedRoomProxyMock(.init())
|
||||||
@@ -101,7 +100,6 @@ class RoomScreenViewModelTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func testPinnedEventsBannerSelection() async throws {
|
func testPinnedEventsBannerSelection() async throws {
|
||||||
ServiceLocator.shared.settings.pinningEnabled = true
|
|
||||||
let roomProxyMock = JoinedRoomProxyMock(.init())
|
let roomProxyMock = JoinedRoomProxyMock(.init())
|
||||||
// setup a way to inject the mock of the pinned events timeline
|
// setup a way to inject the mock of the pinned events timeline
|
||||||
let pinnedTimelineMock = TimelineProxyMock()
|
let pinnedTimelineMock = TimelineProxyMock()
|
||||||
|
|||||||
@@ -346,9 +346,6 @@ class TimelineViewModelTests: XCTestCase {
|
|||||||
// MARK: - Pins
|
// MARK: - Pins
|
||||||
|
|
||||||
func testPinnedEvents() async throws {
|
func testPinnedEvents() async throws {
|
||||||
ServiceLocator.shared.settings.pinningEnabled = true
|
|
||||||
|
|
||||||
// Note: We need to start the test with a non-default value so we know the view model has finished the Task.
|
|
||||||
let roomProxyMock = JoinedRoomProxyMock(.init(name: "",
|
let roomProxyMock = JoinedRoomProxyMock(.init(name: "",
|
||||||
pinnedEventIDs: .init(["test1"])))
|
pinnedEventIDs: .init(["test1"])))
|
||||||
let actionsSubject = PassthroughSubject<JoinedRoomProxyAction, Never>()
|
let actionsSubject = PassthroughSubject<JoinedRoomProxyAction, Never>()
|
||||||
@@ -378,9 +375,6 @@ class TimelineViewModelTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func testCanUserPinEvents() async throws {
|
func testCanUserPinEvents() async throws {
|
||||||
ServiceLocator.shared.settings.pinningEnabled = true
|
|
||||||
|
|
||||||
// Note: We need to start the test with the non-default value so we know the view model has finished the Task.
|
|
||||||
let roomProxyMock = JoinedRoomProxyMock(.init(name: "", canUserPin: true))
|
let roomProxyMock = JoinedRoomProxyMock(.init(name: "", canUserPin: true))
|
||||||
let actionsSubject = PassthroughSubject<JoinedRoomProxyAction, Never>()
|
let actionsSubject = PassthroughSubject<JoinedRoomProxyAction, Never>()
|
||||||
roomProxyMock.underlyingActionsPublisher = actionsSubject.eraseToAnyPublisher()
|
roomProxyMock.underlyingActionsPublisher = actionsSubject.eraseToAnyPublisher()
|
||||||
|
|||||||
Reference in New Issue
Block a user