Add Chips, InputStyles, Service Implementation, swift-collections and UI cleanup.

This commit is contained in:
David Langley
2021-08-25 13:03:36 +01:00
parent a7d0fec95d
commit 7a4554f53d
27 changed files with 1076 additions and 326 deletions
@@ -0,0 +1,32 @@
//
// Copyright 2021 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import Foundation
/**
The actions defined on a push rule, used int he static push rule definitions.
*/
struct NotificationActions {
let notify: Bool
let highlight: Bool
let sound: String?
init(notify: Bool, highlight: Bool = false, sound: String? = nil) {
self.notify = notify
self.highlight = highlight
self.sound = sound
}
}
@@ -0,0 +1,46 @@
//
// Copyright 2021 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import Foundation
/**
Index that determines the state of the push setting.
Silent case is un-unsed on iOS but keepingin for consistency of
definition across the platforms.
*/
enum NotificationIndex {
case off
case silent
case noisy
}
extension NotificationIndex: CaseIterable { }
extension NotificationIndex {
/**
Used to map the on/off checkarks to an index used in the static push rule definitions.
*/
static func index(enabled: Bool) -> NotificationIndex {
return enabled ? .noisy : .off
}
/**
Used to map from the checked state back to the index.
*/
var enabled: Bool {
return self != .off
}
}
@@ -0,0 +1,73 @@
//
// Copyright 2021 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import Foundation
/**
The push rule ids used in notification settings and the static rule definitions.
*/
enum NotificationPushRuleId: String {
case suppressBots = ".m.rule.suppress_notices"
case inviteMe = ".m.rule.invite_for_me"
case containDisplayName = ".m.rule.contains_display_name"
case tombstone = ".m.rule.tombstone"
case roomNotif = ".m.rule.roomnotif"
case containUserName = ".m.rule.contains_user_name"
case call = ".m.rule.call"
case oneToOneEncryptedRoom = ".m.rule.encrypted_room_one_to_one"
case oneToOneRoom = ".m.rule.room_one_to_one"
case allOtherMessages = ".m.rule.message"
case encrypted = ".m.rule.encrypted"
case keywords = "_keywords"
}
extension NotificationPushRuleId: Identifiable {
var id: String {
rawValue
}
}
extension NotificationPushRuleId {
var title: String {
switch self {
case .suppressBots:
return VectorL10n.settingsMessagesByABot
case .inviteMe:
return VectorL10n.settingsRoomInvitations
case .containDisplayName:
return VectorL10n.settingsMessagesContainingDisplayName
case .tombstone:
return VectorL10n.settingsRoomUpgrades
case .roomNotif:
return VectorL10n.settingsMessagesContainingAtRoom
case .containUserName:
return VectorL10n.settingsMessagesContainingUserName
case .call:
return VectorL10n.settingsCallInvitations
case .oneToOneEncryptedRoom:
return VectorL10n.settingsEncryptedDirectMessages
case .oneToOneRoom:
return VectorL10n.settingsDirectMessages
case .allOtherMessages:
return VectorL10n.settingsGroupMessages
case .encrypted:
return VectorL10n.settingsEncryptedGroupMessages
case .keywords:
return VectorL10n.settingsMessagesContainingKeywords
}
}
}
@@ -16,6 +16,9 @@
import Foundation
/**
The notification settings screen definitions, used when calling the coordinator.
*/
@objc enum NotificationSettingsScreen: Int {
case defaultNotificaitons
case mentionsAndKeywords
@@ -29,7 +32,10 @@ extension NotificationSettingsScreen: Identifiable {
}
extension NotificationSettingsScreen {
var pushRules: [PushRuleId] {
/**
Defines which rules are handled by each of the screens.
*/
var pushRules: [NotificationPushRuleId] {
switch self {
case .defaultNotificaitons:
return [.oneToOneRoom, .allOtherMessages, .oneToOneEncryptedRoom, .encrypted]
@@ -16,104 +16,86 @@
import Foundation
enum NotificationIndex {
case off
case silent
case noisy
}
enum PushRuleId: String {
// Default Override Rules
case disableAll = ".m.rule.master"
case suppressBots = ".m.rule.suppress_notices"
case inviteMe = ".m.rule.invite_for_me"
case peopleJoinLeave = ".m.rule.member_event"
case containDisplayName = ".m.rule.contains_display_name"
case tombstone = ".m.rule.tombstone"
case roomNotif = ".m.rule.roomnotif"
// Default Content Rules
case containUserName = ".m.rule.contains_user_name"
case keywords = "_keywords"
// Default Underride Rules
case call = ".m.rule.call"
case oneToOneEncryptedRoom = ".m.rule.encrypted_room_one_to_one"
case oneToOneRoom = ".m.rule.room_one_to_one"
case allOtherMessages = ".m.rule.message"
case encrypted = ".m.rule.encrypted"
// Not documented
case fallback = ".m.rule.fallback"
case reaction = ".m.rule.reaction"
}
func standardActions(for ruleId: PushRuleId, index: NotificationIndex) -> NotificationStandardActions? {
switch ruleId {
case .containDisplayName:
switch index {
case .off: return .disabled
case .silent: return .notify
case .noisy: return .highlightDefaultSound
extension NotificationPushRuleId {
/*
A static definition of the push rule actions.
It is defined similarly across Web and Android.
*/
func standardActions(for index: NotificationIndex) -> NotificationStandardActions? {
switch self {
case .containDisplayName:
switch index {
case .off: return .disabled
case .silent: return .notify
case .noisy: return .highlightDefaultSound
}
case .containUserName:
switch index {
case .off: return .disabled
case .silent: return .notify
case .noisy: return .highlightDefaultSound
}
case .roomNotif:
switch index {
case .off: return .disabled
case .silent: return .notify
case .noisy: return .highlight
}
case .oneToOneRoom:
switch index {
case .off: return .dontNotify
case .silent: return .notify
case .noisy: return .notifyDefaultSound
}
case .oneToOneEncryptedRoom:
switch index {
case .off: return .dontNotify
case .silent: return .notify
case .noisy: return .notifyDefaultSound
}
case .allOtherMessages:
switch index {
case .off: return .dontNotify
case .silent: return .notify
case .noisy: return .notifyDefaultSound
}
case .encrypted:
switch index {
case .off: return .dontNotify
case .silent: return .notify
case .noisy: return .notifyDefaultSound
}
case .inviteMe:
switch index {
case .off: return .disabled
case .silent: return .notify
case .noisy: return .notifyDefaultSound
}
case .call:
switch index {
case .off: return .disabled
case .silent: return .notify
case .noisy: return .notifyRingSound
}
case .suppressBots:
switch index {
case .off: return .dontNotify
case .silent: return .disabled
case .noisy: return .notifyDefaultSound
}
case .tombstone:
switch index {
case .off: return .disabled
case .silent: return .notify
case .noisy: return .highlight
}
case .keywords:
switch index {
case .off: return .disabled
case .silent: return .notify
case .noisy: return .highlightDefaultSound
}
}
case .containUserName:
switch index {
case .off: return .disabled
case .silent: return .notify
case .noisy: return .highlightDefaultSound
}
case .roomNotif:
switch index {
case .off: return .disabled
case .silent: return .notify
case .noisy: return .highlight
}
case .oneToOneRoom:
switch index {
case .off: return .dontNotify
case .silent: return .notify
case .noisy: return .notifyDefaultSound
}
case .oneToOneEncryptedRoom:
switch index {
case .off: return .dontNotify
case .silent: return .notify
case .noisy: return .notifyDefaultSound
}
case .allOtherMessages:
switch index {
case .off: return .dontNotify
case .silent: return .notify
case .noisy: return .notifyDefaultSound
}
case .encrypted:
switch index {
case .off: return .dontNotify
case .silent: return .notify
case .noisy: return .notifyDefaultSound
}
case .inviteMe:
switch index {
case .off: return .disabled
case .silent: return .notify
case .noisy: return .notifyDefaultSound
}
case .call:
switch index {
case .off: return .disabled
case .silent: return .notify
case .noisy: return .notifyRingSound
}
case .suppressBots:
switch index {
case .off: return .dontNotify
case .silent: return .disabled
case .noisy: return .notifyDefaultSound
}
case .tombstone:
switch index {
case .off: return .disabled
case .silent: return .notify
case .noisy: return .highlight
}
default: return nil
}
}
@@ -16,12 +16,10 @@
import Foundation
enum NotificationAction {
case notify(Bool)
case highlight(Bool)
case sound(String)
}
/*
A static definition of the different actions that can be defined on push rules.
It is defined similarly across Web and Android.
*/
enum NotificationStandardActions {
case notify
case notifyDefaultSound
@@ -31,20 +29,20 @@ enum NotificationStandardActions {
case dontNotify
case disabled
var actions: [NotificationAction]? {
var actions: NotificationActions? {
switch self {
case .notify:
return [.notify(true)]
return NotificationActions(notify: true)
case .notifyDefaultSound:
return [.notify(true), .sound("default")]
return NotificationActions(notify: true, sound: "default")
case .notifyRingSound:
return [.notify(true), .sound("ring")]
return NotificationActions(notify: true, sound: "ring")
case .highlight:
return [.notify(true), .highlight(true)]
return NotificationActions(notify: true, highlight: true)
case .highlightDefaultSound:
return [.notify(true), .highlight(true), .sound("default")]
return NotificationActions(notify: true, highlight: true, sound: "default")
case .dontNotify:
return [.notify(false)]
return NotificationActions(notify: false)
case .disabled:
return nil
}