Notification.swift 4.1 KB

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