Skip to content

Commit

Permalink
Code refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
nimau committed Jul 28, 2023
1 parent fabafad commit 2c6ae72
Show file tree
Hide file tree
Showing 7 changed files with 188 additions and 215 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ final class NotificationSettingsScreenCoordinator: CoordinatorProtocol {
}

func start() {
viewModel.start()
viewModel.fetchInitialContent()
}

func toPresentable() -> AnyView {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,28 @@ struct NotificationSettingsScreenViewState: BindableState {
var showSystemNotificationsAlert: Bool {
bindings.enableNotifications && isUserPermissionGranted == false
}

var groupChatNotificationSettingsState: NotificationSettingsScreenModeState = .loading
var directChatNotificationSettingsState: NotificationSettingsScreenModeState = .loading

var settings: NotificationSettingsScreenSettings?
var applyingChange = false
var inconsistentGroupChatsSettings = false
var inconsistentDirectChatsSettings = false
}

struct NotificationSettingsScreenViewStateBindings {
var enableNotifications = false
var enableRoomMention = false
var enableCalls = false
var roomMentionsEnabled = false
var callsEnabled = false
var alertInfo: AlertInfo<NotificationSettingsScreenErrorType>?
}

struct NotificationSettingsScreenSettings {
let groupChatsMode: RoomNotificationModeProxy
let directChatsMode: RoomNotificationModeProxy
let roomMentionsEnabled: Bool?
let callsEnabled: Bool?
// Old clients were having specific settings for encrypted and unencrypted rooms,
// so it's possible for `group chats` and `direct chats` settings to be inconsistent (e.g. encrypted `direct chats` can have a different mode that unencrypted `direct chats`)
let inconsistentSettings: Bool
}

struct NotificationSettingsScreenStrings {
let changeYourSystemSettings: AttributedString = {
let linkPlaceholder = "{link}"
Expand Down Expand Up @@ -71,39 +78,10 @@ struct NotificationSettingsScreenStrings {
enum NotificationSettingsScreenViewAction {
case linkClicked(url: URL)
case changedEnableNotifications
case processTapGroupChats
case processTapDirectChats
case processToggleRoomMention
case processToggleCalls
}

enum NotificationSettingsScreenModeState {
case loading
case loaded(mode: RoomNotificationModeProxy)
case error
}

extension NotificationSettingsScreenModeState {
var isLoading: Bool {
if case .loading = self {
return true
}
return false
}

var isLoaded: Bool {
if case .loaded = self {
return true
}
return false
}

var isError: Bool {
if case .error = self {
return true
}
return false
}
case groupChatsTapped
case directChatsTapped
case roomMentionChanged
case callsChanged
}

enum NotificationSettingsScreenErrorType: Hashable {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class NotificationSettingsScreenViewModel: NotificationSettingsScreenViewModelTy
setupNotificationSettingsSubscription()
}

func start() {
func fetchInitialContent() {
fetchSettings()
}

Expand All @@ -59,14 +59,20 @@ class NotificationSettingsScreenViewModel: NotificationSettingsScreenViewModelTy
MXLog.warning("Link clicked: \(url)")
case .changedEnableNotifications:
toggleNotifications()
case .processTapGroupChats:
case .groupChatsTapped:
break
case .processTapDirectChats:
case .directChatsTapped:
break
case .processToggleRoomMention:
toggleRoomMention()
case .processToggleCalls:
toggleCalls()
case .roomMentionChanged:
guard let settings = state.settings, settings.roomMentionsEnabled != state.bindings.roomMentionsEnabled else {
return
}
Task { await enableRoomMention(state.bindings.roomMentionsEnabled) }
case .callsChanged:
guard let settings = state.settings, settings.callsEnabled != state.bindings.callsEnabled else {
return
}
Task { await enableCalls(state.bindings.callsEnabled) }
}
}

Expand Down Expand Up @@ -109,104 +115,73 @@ class NotificationSettingsScreenViewModel: NotificationSettingsScreenViewModelTy
.store(in: &cancellables)
}

private struct Settings {
var groupChatsMode: RoomNotificationModeProxy = .allMessages
var encryptedGroupChatsMode: RoomNotificationModeProxy = .allMessages
var directChatsMode: RoomNotificationModeProxy = .allMessages
var encryptedDirectChatsMode: RoomNotificationModeProxy = .allMessages
var roomMentionState: Result<Bool, Error> = .success(false)
var callState: Result<Bool, Error> = .success(false)
}

private func fetchSettings() {
fetchSettingsTask = Task {
var settings = Settings()

// Group chats
settings.groupChatsMode = await notificationSettingsProxy.getDefaultNotificationRoomMode(isEncrypted: false, activeMembersCount: 3)
settings.encryptedGroupChatsMode = await notificationSettingsProxy.getDefaultNotificationRoomMode(isEncrypted: true, activeMembersCount: 3)
// A group chat is a chat having more than 2 active members
let groupChatActiveMembers: UInt64 = 3
var groupChatsMode = await notificationSettingsProxy.getDefaultNotificationRoomMode(isEncrypted: false, activeMembersCount: groupChatActiveMembers)
let encryptedGroupChatsMode = await notificationSettingsProxy.getDefaultNotificationRoomMode(isEncrypted: true, activeMembersCount: groupChatActiveMembers)

// Direct chats
settings.directChatsMode = await notificationSettingsProxy.getDefaultNotificationRoomMode(isEncrypted: false, activeMembersCount: 2)
settings.encryptedDirectChatsMode = await notificationSettingsProxy.getDefaultNotificationRoomMode(isEncrypted: true, activeMembersCount: 2)

// Room mentions
do {
settings.roomMentionState = try await .success(notificationSettingsProxy.isRoomMentionEnabled())
} catch {
settings.roomMentionState = .failure(error)
// A direct chat is a chat having exactly 2 active members
let directChatActiveMembers: UInt64 = 2
var directChatsMode = await notificationSettingsProxy.getDefaultNotificationRoomMode(isEncrypted: false, activeMembersCount: directChatActiveMembers)
let encryptedDirectChatsMode = await notificationSettingsProxy.getDefaultNotificationRoomMode(isEncrypted: true, activeMembersCount: directChatActiveMembers)

// Old clients were having specific settings for encrypted and unencrypted rooms,
// so it's possible for `group chats` and `direct chats` settings to be inconsistent (e.g. encrypted `direct chats` can have a different mode that unencrypted `direct chats`)
var inconsistencyDetected = false
if groupChatsMode != encryptedGroupChatsMode {
groupChatsMode = .allMessages
inconsistencyDetected = true
}

// Calls
do {
settings.callState = try await .success(notificationSettingsProxy.isCallEnabled())
} catch {
settings.callState = .failure(error)
if directChatsMode != encryptedDirectChatsMode {
directChatsMode = .allMessages
inconsistencyDetected = true
}

// The following calls may fail if the associated push rule doesn't exist
let roomMentionsEnabled = try? await notificationSettingsProxy.isRoomMentionEnabled()
let callEnabled = try? await notificationSettingsProxy.isCallEnabled()

guard !Task.isCancelled else { return }

applySettings(settings)
}
}

private func applySettings(_ settings: Settings) {
if settings.groupChatsMode == settings.encryptedGroupChatsMode {
state.groupChatNotificationSettingsState = .loaded(mode: settings.groupChatsMode)
state.inconsistentGroupChatsSettings = false
} else {
state.groupChatNotificationSettingsState = .loaded(mode: .allMessages)
state.inconsistentGroupChatsSettings = true
}

if settings.directChatsMode == settings.encryptedDirectChatsMode {
state.directChatNotificationSettingsState = .loaded(mode: settings.directChatsMode)
state.inconsistentDirectChatsSettings = false
} else {
state.directChatNotificationSettingsState = .loaded(mode: .allMessages)
state.inconsistentDirectChatsSettings = true
}

if case .success(let enabled) = settings.roomMentionState {
state.bindings.enableRoomMention = enabled
} else {
state.bindings.enableRoomMention = false
}

if case .success(let enabled) = settings.callState {
state.bindings.enableCalls = enabled
} else {
state.bindings.enableCalls = false

let notificationSettings = NotificationSettingsScreenSettings(groupChatsMode: groupChatsMode,
directChatsMode: directChatsMode,
roomMentionsEnabled: roomMentionsEnabled,
callsEnabled: callEnabled,
inconsistentSettings: inconsistencyDetected)

state.settings = notificationSettings
state.bindings.roomMentionsEnabled = notificationSettings.roomMentionsEnabled ?? false
state.bindings.callsEnabled = notificationSettings.callsEnabled ?? false
}
}

private func toggleRoomMention() {
Task {
do {
let currentValue = try await notificationSettingsProxy.isRoomMentionEnabled()
let newValue = state.bindings.enableRoomMention
guard currentValue != newValue else { return }
state.applyingChange = true
try await notificationSettingsProxy.setRoomMentionEnabled(enabled: newValue)
} catch {
state.bindings.alertInfo = AlertInfo(id: .alert)
}
state.applyingChange = false
private func enableRoomMention(_ enable: Bool) async {
guard let notificationSettings = state.settings else { return }
do {
state.applyingChange = true
MXLog.info("[NotificationSettingsScreenViewMode] setRoomMentionEnabled(\(enable))")
try await notificationSettingsProxy.setRoomMentionEnabled(enabled: enable)
} catch {
state.bindings.alertInfo = AlertInfo(id: .alert)
state.bindings.roomMentionsEnabled = notificationSettings.roomMentionsEnabled ?? false
}
state.applyingChange = false
}

func toggleCalls() {
Task {
do {
let currentValue = try await notificationSettingsProxy.isCallEnabled()
let newValue = state.bindings.enableCalls
guard currentValue != newValue else { return }
state.applyingChange = true
try await notificationSettingsProxy.setCallEnabled(enabled: newValue)
} catch {
state.bindings.alertInfo = AlertInfo(id: .alert)
}
state.applyingChange = false
func enableCalls(_ enable: Bool) async {
guard let notificationSettings = state.settings else { return }
do {
state.applyingChange = true
MXLog.info("[NotificationSettingsScreenViewMode] setCallEnabled(\(enable))")
try await notificationSettingsProxy.setCallEnabled(enabled: enable)
} catch {
state.bindings.alertInfo = AlertInfo(id: .alert)
state.bindings.callsEnabled = notificationSettings.callsEnabled ?? false
}
state.applyingChange = false
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,5 @@ protocol NotificationSettingsScreenViewModelProtocol {
var actions: AnyPublisher<NotificationSettingsScreenViewModelAction, Never> { get }
var context: NotificationSettingsScreenViewModelType.Context { get }

func start()
func fetchInitialContent()
}
Loading

0 comments on commit 2c6ae72

Please sign in to comment.