Explorar o código

Merge pull request #448 from deltachat/date_labels

Date labels
björn petersen %!s(int64=5) %!d(string=hai) anos
pai
achega
ec12df8939

+ 32 - 5
deltachat-ios/Controller/ChatViewController.swift

@@ -47,6 +47,8 @@ class ChatViewController: MessagesViewController {
     var msgChangedObserver: Any?
     var incomingMsgObserver: Any?
 
+    weak var timer: Timer?
+
     lazy var navBarTap: UITapGestureRecognizer = {
         UITapGestureRecognizer(target: self, action: #selector(chatProfilePressed))
     }()
@@ -113,6 +115,23 @@ class ChatViewController: MessagesViewController {
                                        object: nil)
     }
 
+    private func startTimer() {
+        timer?.invalidate()
+        timer = Timer.scheduledTimer(withTimeInterval: 60, repeats: true) { [weak self] _ in
+            //reload table
+            DispatchQueue.main.async {
+                guard let self = self else { return }
+                self.messageList = self.getMessageIds(self.messageList.count)
+                self.messagesCollectionView.reloadDataAndKeepOffset()
+                self.refreshControl.endRefreshing()
+            }
+        }
+    }
+
+    private func stopTimer() {
+        timer?.invalidate()
+    }
+
     private func configureEmptyStateView() {
         view.addSubview(emptyStateView)
         view.addConstraints([emptyStateView.constraintCenterYTo(view),
@@ -185,6 +204,7 @@ class ChatViewController: MessagesViewController {
         dcContext.marknoticedChat(chatId: chatId)
         let array = DcArray(arrayPointer: dc_get_fresh_msgs(mailboxPointer))
         UIApplication.shared.applicationIconBadgeNumber = array.count
+        startTimer()
     }
 
     override func viewWillDisappear(_ animated: Bool) {
@@ -206,6 +226,7 @@ class ChatViewController: MessagesViewController {
             nc.removeObserver(incomingMsgObserver)
         }
         audioController.stopAnyOngoingPlaying()
+        stopTimer()
     }
 
     private func updateTitle(chat: DcChat) {
@@ -752,13 +773,19 @@ extension ChatViewController: MessagesDataSource {
             return nil
         }
 
-        let timestampAttributes: [NSAttributedString.Key: Any] = [
+        var timestampAttributes: [NSAttributedString.Key: Any] = [
             .font: UIFont.systemFont(ofSize: 12),
             .foregroundColor: UIColor.lightGray,
+            .paragraphStyle: NSParagraphStyle()
         ]
 
         if isFromCurrentSender(message: message) {
             let text = NSMutableAttributedString()
+            if let style = NSMutableParagraphStyle.default.mutableCopy() as? NSMutableParagraphStyle {
+                style.alignment = .right
+                timestampAttributes[.paragraphStyle] = style
+            }
+
             text.append(NSAttributedString(string: m.formattedSentDate(), attributes: timestampAttributes))
 
             // TODO: this should be replaced by the respective icons,
@@ -789,10 +816,10 @@ extension ChatViewController: MessagesDataSource {
         }
 
         if !isAvatarHidden(at: indexPath) {
-            let text = NSMutableAttributedString()
-            text.append(NSAttributedString(string: "     "))
-            text.append(NSAttributedString(string: m.formattedSentDate(), attributes: timestampAttributes))
-            return text
+            if let style = NSMutableParagraphStyle.default.mutableCopy() as? NSMutableParagraphStyle {
+                style.firstLineHeadIndent = 22
+                timestampAttributes[.paragraphStyle] = style
+            }
         }
 
         return NSAttributedString(string: m.formattedSentDate(), attributes: timestampAttributes)

+ 1 - 8
deltachat-ios/DC/Wrapper.swift

@@ -555,15 +555,8 @@ class DcMsg: MessageType {
         Date(timeIntervalSince1970: Double(timestamp))
     }()
 
-    let localDateFormatter: DateFormatter = {
-        let result = DateFormatter()
-        result.dateStyle = .none
-        result.timeStyle = .short
-        return result
-    }()
-
     func formattedSentDate() -> String {
-        return localDateFormatter.string(from: sentDate)
+        return DateUtils.getExtendedRelativeTimeSpanString(timeStamp: Double(timestamp))
     }
 
     lazy var kind: MessageKind = {

+ 68 - 18
deltachat-ios/Helper/Utils.swift

@@ -179,27 +179,77 @@ struct Utils {
 }
 
 class DateUtils {
-    // TODO: refactor that, it's an improper way for localizations, use stringsdict instead
-    // blocked by: converting androids plurals xml entries to stringsdict
-    static func getBriefRelativeTimeSpanString(timeStamp: Int) -> String {
-        let unixTime = Int(Date().timeIntervalSince1970)
-        let seconds = unixTime - timeStamp
+    typealias DtU = DateUtils
+    static let minute: Double = 60
+    static let hour: Double = 3600
+    static let day: Double = 86400
+    static let year: Double = 365 * day
 
-        if seconds < 60 {
+    private static func getRelativeTimeInSeconds(timeStamp: Double) -> Double {
+        let unixTime = Double(Date().timeIntervalSince1970)
+        return unixTime - timeStamp
+    }
+
+    private static func is24hDefault() -> Bool {
+        let dateString: String = DateFormatter.dateFormat(fromTemplate: "j", options: 0, locale: Locale.current) ?? ""
+        return !dateString.contains("a")
+    }
+
+    private static func getLocalDateFormatter() -> DateFormatter {
+        let formatter = DateFormatter()
+        formatter.timeZone = .current
+        formatter.locale = .current
+        return formatter
+    }
+
+    static func getExtendedRelativeTimeSpanString(timeStamp: Double) -> String {
+        let seconds = getRelativeTimeInSeconds(timeStamp: timeStamp)
+        let date = Date(timeIntervalSince1970: timeStamp)
+        let formatter = getLocalDateFormatter()
+        let is24h = is24hDefault()
+
+        if seconds < DtU.minute {
+            return String.localized("now")
+        } else if seconds < DtU.hour {
+            let mins = seconds / DtU.minute
+            return String.localized(stringID: "n_minutes", count: Int(mins))
+        } else if seconds < DtU.day {
+            formatter.dateFormat = is24h ?  "HH:mm" : "hh:mm a"
+            return formatter.string(from: date)
+        } else if seconds < 6 * DtU.day {
+            formatter.dateFormat = is24h ?  "EEE, HH:mm" : "EEE, hh:mm a"
+            return formatter.string(from: date)
+        } else if seconds < DtU.year {
+            formatter.dateFormat = is24h ? "MMM d, HH:mm" : "MMM d, hh:mm a"
+            return formatter.string(from: date)
+        } else {
+            formatter.dateFormat = is24h ? "MMM d, yyyy, HH:mm" : "MMM d, yyyy, hh:mm a"
+            return formatter.string(from: date)
+        }
+    }
+
+    static func getBriefRelativeTimeSpanString(timeStamp: Double) -> String {
+        let seconds = getRelativeTimeInSeconds(timeStamp: timeStamp)
+        let date = Date(timeIntervalSince1970: timeStamp)
+        let formatter = getLocalDateFormatter()
+
+        if seconds < DtU.minute {
             return String.localized("now")	// under one minute
-        } else if seconds < 3600 {
-            let mins = seconds / 60
-            return String.localized(stringID: "n_minutes", count: mins)
-        } else if seconds < 86400 {
-            let hours = seconds / 3600
-            return String.localized(stringID: "n_hours", count: hours)
+        } else if seconds < DtU.hour {
+            let mins = seconds / DtU.minute
+            return String.localized(stringID: "n_minutes", count: Int(mins))
+        } else if seconds < DtU.day {
+            let hours = seconds / DtU.hour
+            return String.localized(stringID: "n_hours", count: Int(hours))
+        } else if seconds < DtU.day * 6 {
+            formatter.dateFormat = "EEE"
+            return formatter.string(from: date)
+        } else if seconds < DtU.year {
+            formatter.dateFormat = "MMM d"
+            return formatter.string(from: date)
         } else {
-            let date = Date(timeIntervalSince1970: Double(timeStamp))
-            let dateFormatter = DateFormatter()
-            // dateFormatter.timeStyle = DateFormatter.Style.short //Set time style
-            dateFormatter.dateStyle = DateFormatter.Style.medium //Set date style
-            dateFormatter.timeZone = .current
-            let localDate = dateFormatter.string(from: date)
+            formatter.dateFormat = "MMM d, yyyy"
+            let localDate = formatter.string(from: date)
             return localDate
         }
     }

+ 1 - 1
deltachat-ios/View/ContactCell.swift

@@ -166,7 +166,7 @@ class ContactCell: UITableViewCell {
         let timestamp = timestamp ?? 0
         if timestamp != 0 {
             timeLabel.isHidden = false
-            timeLabel.text = DateUtils.getBriefRelativeTimeSpanString(timeStamp: Int(timestamp))
+            timeLabel.text = DateUtils.getBriefRelativeTimeSpanString(timeStamp: Double(timestamp))
         } else {
             timeLabel.isHidden = true
             timeLabel.text = nil