mirror of
https://github.com/TelegramMessenger/Telegram-iOS.git
synced 2026-07-06 03:33:41 +02:00
Update API
This commit is contained in:
parent
25952cfef6
commit
189d25c32e
59 changed files with 983 additions and 393 deletions
177
submodules/TextFormat/Sources/DateFormat.swift
Normal file
177
submodules/TextFormat/Sources/DateFormat.swift
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
import Foundation
|
||||
import TelegramCore
|
||||
import TelegramPresentationData
|
||||
import TelegramUIPreferences
|
||||
|
||||
public func stringForEntityFormattedDate(timestamp: Int32, format: MessageTextEntityType.DateTimeFormat, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat) -> String {
|
||||
switch format {
|
||||
case .relative:
|
||||
let currentTimestamp = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970)
|
||||
let value = currentTimestamp - timestamp
|
||||
if value > 0 {
|
||||
if value < 60 {
|
||||
return strings.FormattedDate_SecondsAgo(value)
|
||||
} else if value <= 1 * 60 * 60 {
|
||||
return strings.FormattedDate_MinutesAgo(Int32(round(Float(value) / 60)))
|
||||
} else if value <= 24 * 60 * 60 {
|
||||
return strings.FormattedDate_HoursAgo(Int32(round(Float(value) / (60 * 60))))
|
||||
} else {
|
||||
return strings.FormattedDate_DaysAgo(Int32(round(Float(value) / (24 * 60 * 60))))
|
||||
}
|
||||
} else {
|
||||
let value = abs(value)
|
||||
if value < 60 {
|
||||
return strings.FormattedDate_InSeconds(value)
|
||||
} else if value <= 1 * 60 * 60 {
|
||||
return strings.FormattedDate_InMinutes(Int32(round(Float(value) / 60)))
|
||||
} else if value <= 24 * 60 * 60 {
|
||||
return strings.FormattedDate_InHours(Int32(round(Float(value) / (60 * 60))))
|
||||
} else {
|
||||
return strings.FormattedDate_InDays(Int32(round(Float(value) / (24 * 60 * 60))))
|
||||
}
|
||||
}
|
||||
case let .full(timeFormat, dateFormat):
|
||||
var string = ""
|
||||
if let dateFormat {
|
||||
switch dateFormat {
|
||||
case .short:
|
||||
string += stringForShortDate(timestamp: timestamp, strings: strings, dateTimeFormat: dateTimeFormat)
|
||||
case .long:
|
||||
string += stringForFullDate(timestamp: timestamp, strings: strings, dateTimeFormat: dateTimeFormat)
|
||||
}
|
||||
}
|
||||
if let timeFormat {
|
||||
let timeString: String
|
||||
switch timeFormat {
|
||||
case .short:
|
||||
timeString = stringForMessageTimestamp(timestamp: timestamp, dateTimeFormat: dateTimeFormat)
|
||||
case .long:
|
||||
timeString = stringForMessageTimestamp(timestamp: timestamp, dateTimeFormat: dateTimeFormat, withSeconds: true)
|
||||
}
|
||||
if !string.isEmpty {
|
||||
string = strings.Time_AtPreciseDate(string, timeString).string
|
||||
} else {
|
||||
string = timeString
|
||||
}
|
||||
}
|
||||
return string
|
||||
}
|
||||
}
|
||||
|
||||
public func stringForShortTimestamp(hours: Int32, minutes: Int32, seconds: Int32? = nil, dateTimeFormat: PresentationDateTimeFormat, formatAsPlainText: Bool = false) -> String {
|
||||
switch dateTimeFormat.timeFormat {
|
||||
case .regular:
|
||||
let hourString: String
|
||||
if hours == 0 {
|
||||
hourString = "12"
|
||||
} else if hours > 12 {
|
||||
hourString = "\(hours - 12)"
|
||||
} else {
|
||||
hourString = "\(hours)"
|
||||
}
|
||||
|
||||
let periodString: String
|
||||
if hours >= 12 {
|
||||
periodString = "PM"
|
||||
} else {
|
||||
periodString = "AM"
|
||||
}
|
||||
|
||||
let spaceCharacter: String
|
||||
if formatAsPlainText {
|
||||
spaceCharacter = " "
|
||||
} else {
|
||||
spaceCharacter = "\u{00a0}"
|
||||
}
|
||||
|
||||
let minuteString = String(format: "%02d", arguments: [Int(minutes)])
|
||||
if let seconds {
|
||||
let secondString = String(format: "%02d", arguments: [Int(seconds)])
|
||||
return "\(hourString):\(minuteString):\(secondString)\(spaceCharacter)\(periodString)"
|
||||
} else {
|
||||
return "\(hourString):\(minuteString)\(spaceCharacter)\(periodString)"
|
||||
}
|
||||
case .military:
|
||||
if let seconds {
|
||||
return String(format: "%02d:%02d:%02d", arguments: [Int(hours), Int(minutes), Int(seconds)])
|
||||
} else {
|
||||
return String(format: "%02d:%02d", arguments: [Int(hours), Int(minutes)])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func stringForMessageTimestamp(timestamp: Int32, dateTimeFormat: PresentationDateTimeFormat, withSeconds: Bool = false, local: Bool = true) -> String {
|
||||
var t = Int(timestamp)
|
||||
var timeinfo = tm()
|
||||
if local {
|
||||
localtime_r(&t, &timeinfo)
|
||||
} else {
|
||||
gmtime_r(&t, &timeinfo)
|
||||
}
|
||||
|
||||
return stringForShortTimestamp(hours: timeinfo.tm_hour, minutes: timeinfo.tm_min, seconds: withSeconds ? timeinfo.tm_sec : nil, dateTimeFormat: dateTimeFormat)
|
||||
}
|
||||
|
||||
private func stringForShortDate(timestamp: Int32, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat, withTime: Bool = true) -> String {
|
||||
var t: time_t = Int(timestamp)
|
||||
var timeinfo = tm()
|
||||
localtime_r(&t, &timeinfo);
|
||||
|
||||
let day = timeinfo.tm_mday
|
||||
let month = timeinfo.tm_mon + 1
|
||||
let year = timeinfo.tm_year
|
||||
|
||||
let dateString: String
|
||||
let separator = dateTimeFormat.dateSeparator
|
||||
let suffix = dateTimeFormat.dateSuffix
|
||||
let displayYear = dateTimeFormat.requiresFullYear ? year - 100 + 2000 : year - 100
|
||||
switch dateTimeFormat.dateFormat {
|
||||
case .monthFirst:
|
||||
dateString = String(format: "%02d%@%02d%@%02d%@", month, separator, day, separator, displayYear, suffix)
|
||||
case .dayFirst:
|
||||
dateString = String(format: "%02d%@%02d%@%02d%@", day, separator, month, separator, displayYear, suffix)
|
||||
}
|
||||
|
||||
return dateString
|
||||
}
|
||||
|
||||
private func stringForFullDate(timestamp: Int32, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat) -> String {
|
||||
var t: time_t = Int(timestamp)
|
||||
var timeinfo = tm()
|
||||
localtime_r(&t, &timeinfo);
|
||||
|
||||
let dayString = "\(timeinfo.tm_mday)"
|
||||
let yearString = "\(2000 + timeinfo.tm_year - 100)"
|
||||
|
||||
let monthFormat: (String, String) -> PresentationStrings.FormattedString
|
||||
switch timeinfo.tm_mon + 1 {
|
||||
case 1:
|
||||
monthFormat = strings.FormattedDate_LongDate_m1
|
||||
case 2:
|
||||
monthFormat = strings.FormattedDate_LongDate_m2
|
||||
case 3:
|
||||
monthFormat = strings.FormattedDate_LongDate_m3
|
||||
case 4:
|
||||
monthFormat = strings.FormattedDate_LongDate_m4
|
||||
case 5:
|
||||
monthFormat = strings.FormattedDate_LongDate_m5
|
||||
case 6:
|
||||
monthFormat = strings.FormattedDate_LongDate_m6
|
||||
case 7:
|
||||
monthFormat = strings.FormattedDate_LongDate_m7
|
||||
case 8:
|
||||
monthFormat = strings.FormattedDate_LongDate_m8
|
||||
case 9:
|
||||
monthFormat = strings.FormattedDate_LongDate_m9
|
||||
case 10:
|
||||
monthFormat = strings.FormattedDate_LongDate_m10
|
||||
case 11:
|
||||
monthFormat = strings.FormattedDate_LongDate_m11
|
||||
case 12:
|
||||
monthFormat = strings.FormattedDate_LongDate_m12
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
|
||||
return monthFormat(dayString, yearString).string
|
||||
}
|
||||
|
|
@ -299,7 +299,30 @@ public func generateTextEntities(_ text: String, enabledTypes: EnabledEntityType
|
|||
|
||||
type = .Url
|
||||
} else if result.resultType == NSTextCheckingResult.CheckingType.date, let date = result.date?.timeIntervalSince1970 {
|
||||
type = .FormattedDate(format: .relative, date: Int32(date))
|
||||
#if DEBUG
|
||||
var format: MessageTextEntityType.DateTimeFormat?
|
||||
if text.contains("[rel]") {
|
||||
format = .relative
|
||||
}
|
||||
var timeFormat: MessageTextEntityType.DateTimeFormat.TimeFormat?
|
||||
if text.contains("[st]") {
|
||||
timeFormat = .short
|
||||
} else if text.contains("[lt]") {
|
||||
timeFormat = .long
|
||||
}
|
||||
var dateFormat: MessageTextEntityType.DateTimeFormat.DateFormat?
|
||||
if text.contains("[sd]") {
|
||||
dateFormat = .short
|
||||
} else if text.contains("[ld]") {
|
||||
dateFormat = .long
|
||||
}
|
||||
if timeFormat != nil || dateFormat != nil {
|
||||
format = .full(timeFormat: timeFormat, dateFormat: dateFormat)
|
||||
}
|
||||
type = .FormattedDate(format: format, date: Int32(date))
|
||||
#else
|
||||
type = .FormattedDate(format: nil, date: Int32(date))
|
||||
#endif
|
||||
} else {
|
||||
type = .PhoneNumber
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import TelegramCore
|
|||
import Display
|
||||
import libprisma
|
||||
import SwiftSignalKit
|
||||
import TelegramPresentationData
|
||||
|
||||
public func chatInputStateStringWithAppliedEntities(_ text: String, entities: [MessageTextEntity]) -> NSAttributedString {
|
||||
var nsString: NSString?
|
||||
|
|
@ -80,7 +81,7 @@ public func chatInputStateStringWithAppliedEntities(_ text: String, entities: [M
|
|||
|
||||
private let syntaxHighlighter = Syntaxer()
|
||||
|
||||
public func stringWithAppliedEntities(_ text: String, entities: [MessageTextEntity], baseColor: UIColor, linkColor: UIColor, baseQuoteTintColor: UIColor? = nil, baseQuoteSecondaryTintColor: UIColor? = nil, baseQuoteTertiaryTintColor: UIColor? = nil, codeBlockTitleColor: UIColor? = nil, codeBlockAccentColor: UIColor? = nil, codeBlockBackgroundColor: UIColor? = nil, baseFont: UIFont, linkFont: UIFont, boldFont: UIFont, italicFont: UIFont, boldItalicFont: UIFont, fixedFont: UIFont, blockQuoteFont: UIFont, underlineLinks: Bool = true, external: Bool = false, message: Message?, entityFiles: [MediaId: TelegramMediaFile] = [:], adjustQuoteFontSize: Bool = false, cachedMessageSyntaxHighlight: CachedMessageSyntaxHighlight? = nil, paragraphAlignment: NSTextAlignment? = nil) -> NSAttributedString {
|
||||
public func stringWithAppliedEntities(_ text: String, entities: [MessageTextEntity], strings: PresentationStrings? = nil, dateTimeFormat: PresentationDateTimeFormat? = nil, baseColor: UIColor, linkColor: UIColor, baseQuoteTintColor: UIColor? = nil, baseQuoteSecondaryTintColor: UIColor? = nil, baseQuoteTertiaryTintColor: UIColor? = nil, codeBlockTitleColor: UIColor? = nil, codeBlockAccentColor: UIColor? = nil, codeBlockBackgroundColor: UIColor? = nil, baseFont: UIFont, linkFont: UIFont, boldFont: UIFont, italicFont: UIFont, boldItalicFont: UIFont, fixedFont: UIFont, blockQuoteFont: UIFont, underlineLinks: Bool = true, external: Bool = false, message: Message?, entityFiles: [MediaId: TelegramMediaFile] = [:], adjustQuoteFontSize: Bool = false, cachedMessageSyntaxHighlight: CachedMessageSyntaxHighlight? = nil, paragraphAlignment: NSTextAlignment? = nil) -> NSAttributedString {
|
||||
let baseQuoteTintColor = baseQuoteTintColor ?? baseColor
|
||||
|
||||
var nsString: NSString?
|
||||
|
|
@ -94,7 +95,7 @@ public func stringWithAppliedEntities(_ text: String, entities: [MessageTextEnti
|
|||
|
||||
var adjustedRanges: [NSRange?] = []
|
||||
adjustedRanges.reserveCapacity(entities.count)
|
||||
let rangeDelta = 0
|
||||
var rangeDelta = 0
|
||||
for entity in entities {
|
||||
let originalRange = NSRange(location: entity.range.lowerBound, length: entity.range.upperBound - entity.range.lowerBound)
|
||||
var range = NSRange(location: originalRange.location + rangeDelta, length: originalRange.length)
|
||||
|
|
@ -106,23 +107,22 @@ public func stringWithAppliedEntities(_ text: String, entities: [MessageTextEnti
|
|||
range.length = stringLength - range.location
|
||||
}
|
||||
|
||||
// switch entity.type {
|
||||
// case let .FormattedDate(format, date):
|
||||
// let replacement = stringForEntityFormattedDate()
|
||||
// switch format {
|
||||
// case .relative:
|
||||
// replacement = relative
|
||||
// case let .full(timeFormat, dateFormat):
|
||||
// }
|
||||
//
|
||||
// let replacementString = NSAttributedString(string: replacement, attributes: baseAttributes)
|
||||
// string.replaceCharacters(in: range, with: replacementString)
|
||||
// let newRange = NSRange(location: range.location, length: (replacement as NSString).length)
|
||||
// adjustedRanges.append(newRange)
|
||||
// rangeDelta += newRange.length - range.length
|
||||
// default:
|
||||
switch entity.type {
|
||||
case let .FormattedDate(format, date):
|
||||
if let format, let strings, let dateTimeFormat {
|
||||
let replacement = stringForEntityFormattedDate(timestamp: date, format: format, strings: strings, dateTimeFormat: dateTimeFormat)
|
||||
|
||||
let replacementString = NSAttributedString(string: replacement, attributes: baseAttributes)
|
||||
string.replaceCharacters(in: range, with: replacementString)
|
||||
let newRange = NSRange(location: range.location, length: (replacement as NSString).length)
|
||||
adjustedRanges.append(newRange)
|
||||
rangeDelta += newRange.length - range.length
|
||||
} else {
|
||||
adjustedRanges.append(range)
|
||||
}
|
||||
default:
|
||||
adjustedRanges.append(range)
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
var fontAttributeMask: [ChatTextFontAttributes] = Array(repeating: [], count: string.length)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue