Notification.swift 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. import Foundation
  2. /// Extensions to make the notification easier to display
  3. extension Notification {
  4. func shortDateTime() -> String {
  5. let date = Date(timeIntervalSince1970: TimeInterval(self.time))
  6. let calendar = Calendar.current
  7. if calendar.isDateInYesterday(date) {
  8. return "yesterday"
  9. }
  10. let dateFormatter = DateFormatter()
  11. if calendar.isDateInToday(date) {
  12. dateFormatter.dateStyle = .none
  13. dateFormatter.timeStyle = .short
  14. } else {
  15. dateFormatter.dateStyle = .short
  16. dateFormatter.timeStyle = .none
  17. }
  18. return dateFormatter.string(from: date)
  19. }
  20. func formatMessage() -> String {
  21. let message = message ?? ""
  22. if let title = title, title != "" {
  23. return message
  24. }
  25. let emojiTags = emojiTags()
  26. if !emojiTags.isEmpty {
  27. return emojiTags.joined(separator: "") + " " + message
  28. }
  29. return message
  30. }
  31. func formatTitle() -> String? {
  32. if let title = title, title != "" {
  33. let emojiTags = emojiTags()
  34. if !emojiTags.isEmpty {
  35. return emojiTags.joined(separator: "") + " " + title
  36. }
  37. return title
  38. }
  39. return nil
  40. }
  41. func allTags() -> [String] {
  42. return parseAllTags(tags)
  43. }
  44. func emojiTags() -> [String] {
  45. return parseEmojiTags(tags)
  46. }
  47. func nonEmojiTags() -> [String] {
  48. return parseNonEmojiTags(tags)
  49. }
  50. func actionsList() -> [Action] {
  51. return Actions.shared.parse(actions) ?? []
  52. }
  53. }
  54. /// This is the "on the wire" message as it is received from the ntfy server
  55. struct Message: Decodable {
  56. var id: String
  57. var time: Int64
  58. var event: String
  59. var topic: String
  60. var message: String?
  61. var title: String?
  62. var priority: Int16?
  63. var tags: [String]?
  64. var actions: [Action]?
  65. var click: String?
  66. var pollId: String?
  67. func toUserInfo() -> [AnyHashable: Any] {
  68. // This should mimic the way that the ntfy server encodes a message.
  69. // See server_firebase.go for more details.
  70. return [
  71. "id": id,
  72. "time": String(time),
  73. "event": event,
  74. "topic": topic,
  75. "message": message ?? "",
  76. "title": title ?? "",
  77. "priority": String(priority ?? 3),
  78. "tags": tags?.joined(separator: ",") ?? "",
  79. "actions": Actions.shared.encode(actions),
  80. "click": click ?? "",
  81. "poll_id": pollId ?? ""
  82. ]
  83. }
  84. static func from(userInfo: [AnyHashable: Any]) -> Message? {
  85. guard let id = userInfo["id"] as? String,
  86. let time = userInfo["time"] as? String,
  87. let event = userInfo["event"] as? String,
  88. let topic = userInfo["topic"] as? String,
  89. let timeInt = Int64(time),
  90. let message = userInfo["message"] as? String else {
  91. Log.d(Store.tag, "Unknown or irrelevant message", userInfo)
  92. return nil
  93. }
  94. let title = userInfo["title"] as? String
  95. let priority = Int16(userInfo["priority"] as? String ?? "3") ?? 3
  96. let tags = (userInfo["tags"] as? String ?? "").components(separatedBy: ",")
  97. let actions = userInfo["actions"] as? String
  98. let click = userInfo["click"] as? String
  99. let pollId = userInfo["poll_id"] as? String
  100. return Message(
  101. id: id,
  102. time: timeInt,
  103. event: event,
  104. topic: topic,
  105. message: message,
  106. title: title,
  107. priority: priority,
  108. tags: tags,
  109. actions: Actions.shared.parse(actions),
  110. click: click,
  111. pollId: pollId
  112. )
  113. }
  114. }
  115. struct Action: Encodable, Decodable, Identifiable {
  116. var id: String
  117. var action: String
  118. var label: String
  119. var url: String?
  120. var method: String?
  121. var headers: [String: String]?
  122. var body: String?
  123. var clear: Bool?
  124. }