mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-24 07:05:35 +00:00
notifications
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user