diff --git a/OTRS-Watch.xcodeproj/project.xcworkspace/xcuserdata/linnemann.xcuserdatad/UserInterfaceState.xcuserstate b/OTRS-Watch.xcodeproj/project.xcworkspace/xcuserdata/linnemann.xcuserdatad/UserInterfaceState.xcuserstate index 8c4f5cc..e2d2ca5 100644 Binary files a/OTRS-Watch.xcodeproj/project.xcworkspace/xcuserdata/linnemann.xcuserdatad/UserInterfaceState.xcuserstate and b/OTRS-Watch.xcodeproj/project.xcworkspace/xcuserdata/linnemann.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/OTRS-Watch.xcodeproj/xcuserdata/linnemann.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/OTRS-Watch.xcodeproj/xcuserdata/linnemann.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist index 6911433..928fa50 100644 --- a/OTRS-Watch.xcodeproj/xcuserdata/linnemann.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +++ b/OTRS-Watch.xcodeproj/xcuserdata/linnemann.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -67,5 +67,53 @@ landmarkType = "3"> + + + + + + + + + + + + diff --git a/OTRS-Watch/Base.lproj/Main.storyboard b/OTRS-Watch/Base.lproj/Main.storyboard index c93e08a..edd9967 100644 --- a/OTRS-Watch/Base.lproj/Main.storyboard +++ b/OTRS-Watch/Base.lproj/Main.storyboard @@ -1,5 +1,5 @@ - + @@ -734,8 +734,8 @@ - - + + @@ -748,11 +748,11 @@ - + - + @@ -781,7 +781,7 @@ - + @@ -814,7 +814,7 @@ - + diff --git a/OTRS-Watch/Constants.swift b/OTRS-Watch/Constants.swift index 527bff9..674055b 100644 --- a/OTRS-Watch/Constants.swift +++ b/OTRS-Watch/Constants.swift @@ -45,4 +45,36 @@ struct Constants { static let SETTINGS = 1 } } + + struct DATE_TIME { + struct DE { + static let X_YEARS_AGO = "Vor %d Jahren" + static let X_MONTH_AGO = "Vor %d Monaten" + static let X_WEEKS_AGO = "Vor %d Wochen" + static let X_DAYS_AGO = "Vor %d Tagen" + static let X_HOURS_AGO = "Vor %d Stunden" + static let X_MINUTES_AGO = "Vor %d Minuten" + static let X_SECONDS_AGO = "Vor %d Sekunden" + + static let ONE_YEAR_AGO = "Vor 1 Jahr" + static let ONE_MONTH_AGO = "Vor 1 Monat" + static let ONE_WEEK_AGO = "Vor 1 Woche" + static let ONE_DAY_AGO = "Vor 1 Tag" + static let ONE_MINUTE_AGO = "Vor einer Minute" + + static let AN_HOUR_AGO = "Vor einer Stunde" + static let JUST_NOW = "Gerade eben" + static let LAST_YEAR = "Letztes Jahr" + static let LAST_MONTH = "Letzten Monat" + static let LAST_WEEK = "Letzte Woche" + static let YESTERDAY = "Gestern" + + static let THIS_MORNING = "Heute Morgen" + static let THIS_AFTERNOON = "Heute Nachmittag" + static let THIS_WEEK = "Diese Woche" + static let THIS_MONTH = "Diesen Monat" + static let THIS_YEAR = "Dieses Jahr" + static let TODAY = "Heute" + } + } } diff --git a/OTRS-Watch/Extension/Date.swift b/OTRS-Watch/Extension/Date.swift index 8aeada0..1343082 100644 --- a/OTRS-Watch/Extension/Date.swift +++ b/OTRS-Watch/Extension/Date.swift @@ -8,10 +8,150 @@ import Foundation + + extension Date { func toString() -> String { let dateFormatter = DateFormatter() - dateFormatter.dateFormat = "dd.MM.yyyy hh:mm" + dateFormatter.dateFormat = "dd.MM.yyyy" return dateFormatter.string(from: self) } + + // shows 1 or two letter abbreviation for units. + // does not include 'ago' text ... just {value}{unit-abbreviation} + // does not include interim summary options such as 'Just now' + /*public var timeAgoSimple: String { + let components = self.dateComponents() + + if components.year! > 0 { + return stringFromFormat("%%d%@yr", withValue: components.year!) + } + + if components.month! > 0 { + return stringFromFormat("%%d%@mo", withValue: components.month!) + } + + // TODO: localize for other calanders + if components.day! >= 7 { + let value = components.day!/7 + return stringFromFormat("%%d%@w", withValue: value) + } + + if components.day! > 0 { + return stringFromFormat("%%d%@d", withValue: components.day!) + } + + if components.hour! > 0 { + return stringFromFormat("%%d%@h", withValue: components.hour!) + } + + if components.minute! > 0 { + return stringFromFormat("%%d%@m", withValue: components.minute!) + } + + if components.second! > 0 { + return stringFromFormat("%%d%@s", withValue: components.second! ) + } + + return "" + }*/ + + public var timeAgo: String { + let components = self.dateComponents() + + if components.year! > 0 { + if components.year! < 2 { + return Constants.DATE_TIME.DE.LAST_YEAR + } else { + return stringFromFormat(Constants.DATE_TIME.DE.X_YEARS_AGO, withValue: components.year!) + } + } + + if components.month! > 0 { + if components.month! < 2 { + return Constants.DATE_TIME.DE.LAST_MONTH + } else { + return stringFromFormat(Constants.DATE_TIME.DE.X_MONTH_AGO, withValue: components.month!) + } + } + + if components.day! >= 7 { + let week = components.day!/7 + if week < 2 { + return Constants.DATE_TIME.DE.LAST_WEEK + } else { + return stringFromFormat(Constants.DATE_TIME.DE.X_WEEKS_AGO, withValue: week) + } + } + + if components.day! > 0 { + if components.day! < 2 { + return Constants.DATE_TIME.DE.YESTERDAY + } else { + return stringFromFormat(Constants.DATE_TIME.DE.X_DAYS_AGO, withValue: components.day!) + } + } + + if components.hour! > 0 { + if components.hour! < 2 { + return Constants.DATE_TIME.DE.AN_HOUR_AGO + } else { + return stringFromFormat(Constants.DATE_TIME.DE.X_HOURS_AGO, withValue: components.hour!) + } + } + + if components.minute! > 0 { + if components.minute! < 2 { + return Constants.DATE_TIME.DE.ONE_MINUTE_AGO + } else { + return stringFromFormat(Constants.DATE_TIME.DE.X_MINUTES_AGO, withValue: components.minute!) + } + } + + if components.second! > 0 { + if components.second! < 5 { + return Constants.DATE_TIME.DE.JUST_NOW + } else { + return stringFromFormat(Constants.DATE_TIME.DE.X_SECONDS_AGO, withValue: components.second!) + } + } + + return "" + } + + fileprivate func dateComponents() -> DateComponents { + let calander = Calendar.current + return (calander as NSCalendar).components([.second, .minute, .hour, .day, .month, .year], from: self, to: Date(), options: []) + } + + fileprivate func stringFromFormat(_ format: String, withValue value: Int) -> String { + let localeFormat = String(format: format, getLocaleFormatUnderscoresWithValue(Double(value))) + return String(format: format, value) + } + + fileprivate func getLocaleFormatUnderscoresWithValue(_ value: Double) -> String { + guard let localeCode = Locale.preferredLanguages.first else { + return "" + } + + // Russian (ru) and Ukrainian (uk) + if localeCode.hasPrefix("ru") || localeCode.hasPrefix("uk") { + let XY = Int(floor(value)) % 100 + let Y = Int(floor(value)) % 10 + + if Y == 0 || Y > 4 || (XY > 10 && XY < 15) { + return "" + } + + if Y > 1 && Y < 5 && (XY < 10 || XY > 20) { + return "_" + } + + if Y == 1 && XY != 11 { + return "__" + } + } + + return "" + } } diff --git a/OTRS-Watch/Extension/ViewControllerExtension.swift b/OTRS-Watch/Extension/ViewControllerExtension.swift index 2f7be06..f95fe8f 100644 --- a/OTRS-Watch/Extension/ViewControllerExtension.swift +++ b/OTRS-Watch/Extension/ViewControllerExtension.swift @@ -34,7 +34,7 @@ extension ViewController: NSTableViewDataSource, NSTableViewDelegate { if tableColumn == self.ticketTableView.tableColumns[0] { cellIdentifier = CellIdentifiers.OTRSTicketNumber image = nil - text = item.created.toString() + text = item.created.timeAgo } else if tableColumn == self.ticketTableView.tableColumns[1] { cellIdentifier = CellIdentifiers.OTRSTicketDetails image = nil diff --git a/OTRS-Watch/Model/Extension/TicketExtension.swift b/OTRS-Watch/Model/Extension/TicketExtension.swift index 861dfb6..55c7697 100644 --- a/OTRS-Watch/Model/Extension/TicketExtension.swift +++ b/OTRS-Watch/Model/Extension/TicketExtension.swift @@ -75,6 +75,13 @@ extension Ticket { throw SerializationError.missing("Created") } + // extract created, e.g. 2016-11-24 11:30:11 + + guard let createdUnixJSON = source["CreateTimeUnix"] as? String else { + throw SerializationError.missing("CreateTimeUnix") + } + let epochTime: TimeInterval = Double.init(createdUnixJSON)! + // extract changed, e.g. 2016-11-24 13:33:01 guard let changedJSON = source["Changed"] as? String else { throw SerializationError.missing("Changed") @@ -91,14 +98,11 @@ extension Ticket { self.queue = queue_ self.queueID = queueID_ self.state = state_ - if let created:Date = dateFormatter.date(from: createdJSON) { - self.created = created - } else { - self.created = Date.init() - } + self.created = Date(timeIntervalSince1970: epochTime) if let changed:Date = dateFormatter.date(from: changedJSON) { self.changed = changed } else { + print("Error creating date instance from \(createdJSON)") self.changed = Date.init() } }