notifications

This commit is contained in:
Kylmakalle
2025-01-12 03:12:07 +02:00
parent c67d4a3d63
commit ec2a02ea39
3 changed files with 151 additions and 17 deletions

View File

@@ -827,6 +827,7 @@ public func sgMessageFilterController(presentationData: PresentationData? = nil)
private enum SGDebugControllerSection: Int32, SGItemListSection {
case base
case notifications
}
private enum SGDebugDisclosureLink: String {
@@ -847,7 +848,12 @@ private enum SGDebugToggles: String {
}
private typealias SGDebugControllerEntry = SGItemListUIEntry<SGDebugControllerSection, SGDebugToggles, AnyHashable, AnyHashable, SGDebugDisclosureLink, SGDebugActions>
private enum SGDebugOneFromManySetting: String {
case pinnedMessageNotifications
case mentionsAndRepliesNotifications
}
private typealias SGDebugControllerEntry = SGItemListUIEntry<SGDebugControllerSection, SGDebugToggles, AnyHashable, SGDebugOneFromManySetting, SGDebugDisclosureLink, SGDebugActions>
private func SGDebugControllerEntries(presentationData: PresentationData) -> [SGDebugControllerEntry] {
var entries: [SGDebugControllerEntry] = []
@@ -867,8 +873,12 @@ private func SGDebugControllerEntries(presentationData: PresentationData) -> [SG
}
entries.append(.action(id: id.count, section: .base, actionType: .clearRegDateCache, text: "Clear Regdate cache", kind: .generic))
entries.append(.toggle(id: id.count, section: .base, settingName: .forceImmediateShareSheet, value: SGSimpleSettings.shared.forceSystemSharing, text: "Force System Share Sheet", enabled: true))
entries.append(.toggle(id: id.count, section: .base, settingName: .legacyNotificationsFix, value: SGSimpleSettings.shared.legacyNotificationsFix, text: "[Legacy] Fix empty notifications", enabled: true))
entries.append(.header(id: id.count, section: .notifications, text: "NOTIFICATIONS", badge: nil))
entries.append(.toggle(id: id.count, section: .notifications, settingName: .legacyNotificationsFix, value: SGSimpleSettings.shared.legacyNotificationsFix, text: "[Legacy] Fix empty notifications", enabled: true))
entries.append(.oneFromManySelector(id: id.count, section: .notifications, settingName: .pinnedMessageNotifications, text: "Pinned Messages", value: SGSimpleSettings.shared.pinnedMessageNotifications, enabled: true))
entries.append(.oneFromManySelector(id: id.count, section: .notifications, settingName: .mentionsAndRepliesNotifications, text: "@Mentions and Replies", value: SGSimpleSettings.shared.mentionsAndRepliesNotifications, enabled: true))
return entries
}
private func okUndoController(_ text: String, _ presentationData: PresentationData) -> UndoOverlayController {
@@ -882,7 +892,7 @@ public func sgDebugController(context: AccountContext) -> ViewController {
let simplePromise = ValuePromise(true, ignoreRepeated: false)
let arguments = SGItemListArguments<SGDebugToggles, AnyHashable, AnyHashable, SGDebugDisclosureLink, SGDebugActions>(context: context, setBoolValue: { toggleName, value in
let arguments = SGItemListArguments<SGDebugToggles, AnyHashable, SGDebugOneFromManySetting, SGDebugDisclosureLink, SGDebugActions>(context: context, setBoolValue: { toggleName, value in
switch toggleName {
case .forceImmediateShareSheet:
SGSimpleSettings.shared.forceSystemSharing = value
@@ -891,6 +901,52 @@ public func sgDebugController(context: AccountContext) -> ViewController {
case .inputToolbar:
SGSimpleSettings.shared.inputToolbar = value
}
}, setOneFromManyValue: { setting in
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let actionSheet = ActionSheetController(presentationData: presentationData)
var items: [ActionSheetItem] = []
switch (setting) {
case .pinnedMessageNotifications:
let setAction: (String) -> Void = { value in
SGSimpleSettings.shared.pinnedMessageNotifications = value
simplePromise.set(true)
}
for value in SGSimpleSettings.PinnedMessageNotificationsSettings.allCases {
items.append(ActionSheetButtonItem(title: value.rawValue, color: .accent, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
if SGSimpleSettings.shared.b {
setAction(value.rawValue)
} else {
setAction(SGSimpleSettings.PinnedMessageNotificationsSettings.default.rawValue)
}
}))
}
case .mentionsAndRepliesNotifications:
let setAction: (String) -> Void = { value in
SGSimpleSettings.shared.mentionsAndRepliesNotifications = value
simplePromise.set(true)
}
for value in SGSimpleSettings.MentionsAndRepliesNotificationsSettings.allCases {
items.append(ActionSheetButtonItem(title: value.rawValue, color: .accent, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
if SGSimpleSettings.shared.b {
setAction(value.rawValue)
} else {
setAction(SGSimpleSettings.MentionsAndRepliesNotificationsSettings.default.rawValue)
}
}))
}
}
actionSheet.setItemGroups([ActionSheetItemGroup(items: items), ActionSheetItemGroup(items: [
ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, color: .accent, font: .bold, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
})
])])
presentControllerImpl?(actionSheet, ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
}, openDisclosureLink: { link in
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
switch (link) {

View File

@@ -1,6 +1,8 @@
import Foundation
let appGroupIdentifier = "group.app.swiftgram.ios"
public class SGSimpleSettings {
public static let shared = SGSimpleSettings()
@@ -12,6 +14,11 @@ public class SGSimpleSettings {
private func setDefaultValues() {
UserDefaults.standard.register(defaults: SGSimpleSettings.defaultValues)
// Just in case group defaults will be nil
UserDefaults.standard.register(defaults: SGSimpleSettings.groupDefaultValues)
if let groupUserDefaults = UserDefaults(suiteName: appGroupIdentifier) {
groupUserDefaults.register(defaults: SGSimpleSettings.groupDefaultValues)
}
}
private func preCacheValues() {
@@ -111,6 +118,8 @@ public class SGSimpleSettings {
case legacyNotificationsFix
case messageFilterKeywords
case inputToolbar
case pinnedMessageNotifications
case mentionsAndRepliesNotifications
}
public enum DownloadSpeedBoostValues: String, CaseIterable {
@@ -148,6 +157,18 @@ public class SGSimpleSettings {
case none
}
public enum PinnedMessageNotificationsSettings: String, CaseIterable {
case `default`
case silenced
case disabled
}
public enum MentionsAndRepliesNotificationsSettings: String, CaseIterable {
case `default`
case silenced
case disabled
}
public static let defaultValues: [String: Any] = [
Keys.hidePhoneInSettings.rawValue: true,
Keys.showTabNames.rawValue: true,
@@ -208,11 +229,16 @@ public class SGSimpleSettings {
Keys.forceSystemSharing.rawValue: false,
Keys.confirmCalls.rawValue: true,
Keys.videoPIPSwipeDirection.rawValue: VideoPIPSwipeDirection.up.rawValue,
Keys.legacyNotificationsFix.rawValue: false,
Keys.messageFilterKeywords.rawValue: [],
Keys.inputToolbar.rawValue: false
]
public static let groupDefaultValues: [String: Any] = [
Keys.legacyNotificationsFix.rawValue: false,
Keys.pinnedMessageNotifications.rawValue: PinnedMessageNotificationsSettings.default.rawValue,
Keys.mentionsAndRepliesNotifications.rawValue: MentionsAndRepliesNotificationsSettings.default.rawValue
]
@UserDefault(key: Keys.hidePhoneInSettings.rawValue)
public var hidePhoneInSettings: Bool
@@ -389,7 +415,7 @@ public class SGSimpleSettings {
@UserDefault(key: Keys.videoPIPSwipeDirection.rawValue)
public var videoPIPSwipeDirection: String
@UserDefault(key: Keys.legacyNotificationsFix.rawValue)
@UserDefault(key: Keys.legacyNotificationsFix.rawValue, userDefaults: UserDefaults(suiteName: appGroupIdentifier) ?? .standard)
public var legacyNotificationsFix: Bool
public var b: Bool = true
@@ -399,6 +425,12 @@ public class SGSimpleSettings {
@UserDefault(key: Keys.inputToolbar.rawValue)
public var inputToolbar: Bool
@UserDefault(key: Keys.pinnedMessageNotifications.rawValue, userDefaults: UserDefaults(suiteName: appGroupIdentifier) ?? .standard)
public var pinnedMessageNotifications: String
@UserDefault(key: Keys.mentionsAndRepliesNotifications.rawValue, userDefaults: UserDefaults(suiteName: appGroupIdentifier) ?? .standard)
public var mentionsAndRepliesNotifications: String
}
extension SGSimpleSettings {

View File

@@ -18,7 +18,10 @@ import NotificationsPresentationData
import RangeSet
import ConvertOpusToAAC
private let LEGACY_NOTIFICATIONS_FIX: Bool = UserDefaults.standard.bool(forKey: "legacyNotificationsFix")
private let groupUserDefaults: UserDefaults? = UserDefaults(suiteName: "group.app.swiftgram.ios")
private let LEGACY_NOTIFICATIONS_FIX: Bool = groupUserDefaults?.bool(forKey: "legacyNotificationsFix") ?? false
private let PINNED_MESSAGE_ACTION: String = groupUserDefaults?.string(forKey: "pinnedMessageNotifications") ?? "default"
private let MENTION_AND_REPLY_ACTION: String = groupUserDefaults?.string(forKey: "mentionsAndRepliesNotifications") ?? "default"
private let queue = Queue()
@@ -498,16 +501,20 @@ private struct NotificationContent: CustomStringConvertible {
var userInfo: [AnyHashable: Any] = [:]
var attachments: [UNNotificationAttachment] = []
var silent = false
// MARK: Swiftgram
var isEmpty: Bool
var isMentionOrReply: Bool
var isPinned: Bool = false
var senderPerson: INPerson?
var senderImage: INImage?
var isLockedMessage: String?
init(isLockedMessage: String?, isEmpty: Bool = false) {
init(isLockedMessage: String?, isEmpty: Bool = false, isMentionOrReply: Bool = false) {
self.isLockedMessage = isLockedMessage
self.isEmpty = isEmpty
self.isMentionOrReply = isMentionOrReply
}
var description: String {
@@ -524,6 +531,10 @@ private struct NotificationContent: CustomStringConvertible {
string += " isLockedMessage: \(String(describing: self.isLockedMessage)),\n"
string += " attachments: \(self.attachments),\n"
string += " isEmpty: \(self.isEmpty),\n"
string += " isMentionOrReply: \(self.isMentionOrReply),\n"
string += " isPinned: \(self.isPinned),\n"
string += " forceIsEmpty: \(self.forceIsEmpty),\n"
string += " forceIsSilent: \(self.forceIsSilent),\n"
string += "}"
return string
}
@@ -538,7 +549,7 @@ private struct NotificationContent: CustomStringConvertible {
if let topicTitle {
displayName = "\(topicTitle) (\(displayName))"
}
if self.silent {
if self.silent || self.forceIsSilent {
displayName = "\(displayName) 🔕"
}
@@ -562,9 +573,15 @@ private struct NotificationContent: CustomStringConvertible {
var content = UNMutableNotificationContent()
//Logger.shared.log("NotificationService", "Generating final content: \(self.description)")
// MARK: Swiftgram
#if DEBUG
print("body:\(content.body) silent:\(self.silent) isMentionOrReply:\(self.isMentionOrReply) MENTION_AND_REPLY_ACTION:\(MENTION_AND_REPLY_ACTION) isPinned:\(self.isPinned) PINNED_MESSAGE_ACTION:\(PINNED_MESSAGE_ACTION)" + " forceIsEmpty:\(self.forceIsEmpty) forceIsSilent:\(self.forceIsSilent)")
#endif
if self.forceIsEmpty && !LEGACY_NOTIFICATIONS_FIX {
return UNNotificationContent()
}
if let title = self.title {
if self.silent {
if self.silent || self.forceIsSilent {
content.title = "\(title) 🔕"
} else {
content.title = title
@@ -645,7 +662,7 @@ private struct NotificationContent: CustomStringConvertible {
}
// MARK: Swiftgram
if self.isEmpty && LEGACY_NOTIFICATIONS_FIX {
if (self.isEmpty || self.forceIsEmpty) && LEGACY_NOTIFICATIONS_FIX {
content.title = " "
content.threadIdentifier = "empty-notification"
if #available(iOSApplicationExtension 15.0, iOS 15.0, *) {
@@ -653,7 +670,10 @@ private struct NotificationContent: CustomStringConvertible {
content.relevanceScore = 0.0
}
}
if self.forceIsSilent {
content.sound = nil
}
return content
}
}
@@ -919,6 +939,7 @@ private final class NotificationServiceHandler {
return
}
let isMentionOrReply: Bool = payloadJson["mention"] as? String == "1"
Logger.shared.log("NotificationService \(episode)", "Decrypted payload: \(payloadJson)")
@@ -1016,7 +1037,7 @@ private final class NotificationServiceHandler {
action = .logout
case "MESSAGE_MUTED":
if let peerId = peerId {
action = .poll(peerId: peerId, content: NotificationContent(isLockedMessage: nil, isEmpty: true), messageId: nil, reportDelivery: false)
action = .poll(peerId: peerId, content: NotificationContent(isLockedMessage: nil, isEmpty: true, isMentionOrReply: isMentionOrReply), messageId: nil, reportDelivery: false)
}
case "MESSAGE_DELETED":
if let peerId = peerId {
@@ -1067,7 +1088,7 @@ private final class NotificationServiceHandler {
}
} else {
if let aps = payloadJson["aps"] as? [String: Any], var peerId = peerId {
var content: NotificationContent = NotificationContent(isLockedMessage: isLockedMessage)
var content: NotificationContent = NotificationContent(isLockedMessage: isLockedMessage, isMentionOrReply: isMentionOrReply)
if let alert = aps["alert"] as? [String: Any] {
if let topicTitleValue = payloadJson["topic_title"] as? String {
topicTitle = topicTitleValue
@@ -1277,6 +1298,11 @@ private final class NotificationServiceHandler {
let pollCompletion: (NotificationContent, Media?) -> Void = { content, customMedia in
var content = content
// MARK: Swiftgram
if let mediaAction = customMedia as? TelegramMediaAction, case .pinnedMessageUpdated = mediaAction.action {
content.isPinned = true
}
queue.async {
guard let strongSelf = self, let stateManager = strongSelf.stateManager else {
let content = NotificationContent(isLockedMessage: isLockedMessage)
@@ -1585,7 +1611,7 @@ private final class NotificationServiceHandler {
Logger.shared.log("NotificationService \(episode)", "Updating content to \(content)")
if wasDisplayed {
content = NotificationContent(isLockedMessage: nil)
content = NotificationContent(isLockedMessage: nil, isMentionOrReply: isMentionOrReply)
Logger.shared.log("NotificationService \(episode)", "Was already displayed, skipping content")
} else if let messageId {
let _ = (stateManager.postbox.transaction { transaction -> Void in
@@ -1672,7 +1698,7 @@ private final class NotificationServiceHandler {
case let .idBased(maxIncomingReadId, _, _, _, _):
if maxIncomingReadId >= messageId.id {
Logger.shared.log("NotificationService \(episode)", "maxIncomingReadId: \(maxIncomingReadId), messageId: \(messageId.id), skipping")
content = NotificationContent(isLockedMessage: nil)
content = NotificationContent(isLockedMessage: nil, isMentionOrReply: isMentionOrReply)
} else {
Logger.shared.log("NotificationService \(episode)", "maxIncomingReadId: \(maxIncomingReadId), messageId: \(messageId.id), not skipping")
}
@@ -2337,3 +2363,23 @@ final class NotificationService: UNNotificationServiceExtension {
}
}
}
extension NotificationContent {
var forceIsEmpty: Bool {
if !self.isEmpty {
if PINNED_MESSAGE_ACTION == "disabled" && self.isPinned || MENTION_AND_REPLY_ACTION == "disabled" && self.isMentionOrReply {
return true
}
}
return false
}
var forceIsSilent: Bool {
if !self.silent {
if PINNED_MESSAGE_ACTION == "silenced" && self.isPinned || MENTION_AND_REPLY_ACTION == "silenced" && self.isMentionOrReply {
return true
}
}
return false
}
}