mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 14:20:20 +00:00
Refactor more modules
This commit is contained in:
234
submodules/AccountContext/Sources/ChatController.swift
Normal file
234
submodules/AccountContext/Sources/ChatController.swift
Normal file
@@ -0,0 +1,234 @@
|
||||
import Foundation
|
||||
import Postbox
|
||||
import TextFormat
|
||||
|
||||
public enum ChatControllerInitialBotStartBehavior {
|
||||
case interactive
|
||||
case automatic(returnToPeerId: PeerId)
|
||||
}
|
||||
|
||||
public struct ChatControllerInitialBotStart {
|
||||
public let payload: String
|
||||
public let behavior: ChatControllerInitialBotStartBehavior
|
||||
|
||||
public init(payload: String, behavior: ChatControllerInitialBotStartBehavior) {
|
||||
self.payload = payload
|
||||
self.behavior = behavior
|
||||
}
|
||||
}
|
||||
|
||||
public enum ChatControllerInteractionNavigateToPeer {
|
||||
case `default`
|
||||
case chat(textInputState: ChatTextInputState?, messageId: MessageId?)
|
||||
case info
|
||||
case withBotStartPayload(ChatControllerInitialBotStart)
|
||||
}
|
||||
|
||||
public struct ChatTextInputState: PostboxCoding, Equatable {
|
||||
public let inputText: NSAttributedString
|
||||
public let selectionRange: Range<Int>
|
||||
|
||||
public static func ==(lhs: ChatTextInputState, rhs: ChatTextInputState) -> Bool {
|
||||
return lhs.inputText.isEqual(to: rhs.inputText) && lhs.selectionRange == rhs.selectionRange
|
||||
}
|
||||
|
||||
public init() {
|
||||
self.inputText = NSAttributedString()
|
||||
self.selectionRange = 0 ..< 0
|
||||
}
|
||||
|
||||
public init(inputText: NSAttributedString, selectionRange: Range<Int>) {
|
||||
self.inputText = inputText
|
||||
self.selectionRange = selectionRange
|
||||
}
|
||||
|
||||
public init(inputText: NSAttributedString) {
|
||||
self.inputText = inputText
|
||||
let length = inputText.length
|
||||
self.selectionRange = length ..< length
|
||||
}
|
||||
|
||||
public init(decoder: PostboxDecoder) {
|
||||
self.inputText = ((decoder.decodeObjectForKey("at", decoder: { ChatTextInputStateText(decoder: $0) }) as? ChatTextInputStateText) ?? ChatTextInputStateText()).attributedText()
|
||||
self.selectionRange = Int(decoder.decodeInt32ForKey("as0", orElse: 0)) ..< Int(decoder.decodeInt32ForKey("as1", orElse: 0))
|
||||
}
|
||||
|
||||
public func encode(_ encoder: PostboxEncoder) {
|
||||
encoder.encodeObject(ChatTextInputStateText(attributedText: self.inputText), forKey: "at")
|
||||
|
||||
encoder.encodeInt32(Int32(self.selectionRange.lowerBound), forKey: "as0")
|
||||
encoder.encodeInt32(Int32(self.selectionRange.upperBound), forKey: "as1")
|
||||
}
|
||||
}
|
||||
|
||||
public enum ChatTextInputStateTextAttributeType: PostboxCoding, Equatable {
|
||||
case bold
|
||||
case italic
|
||||
case monospace
|
||||
case textMention(PeerId)
|
||||
case textUrl(String)
|
||||
|
||||
public init(decoder: PostboxDecoder) {
|
||||
switch decoder.decodeInt32ForKey("t", orElse: 0) {
|
||||
case 0:
|
||||
self = .bold
|
||||
case 1:
|
||||
self = .italic
|
||||
case 2:
|
||||
self = .monospace
|
||||
case 3:
|
||||
self = .textMention(PeerId(decoder.decodeInt64ForKey("peerId", orElse: 0)))
|
||||
case 4:
|
||||
self = .textUrl(decoder.decodeStringForKey("url", orElse: ""))
|
||||
default:
|
||||
assertionFailure()
|
||||
self = .bold
|
||||
}
|
||||
}
|
||||
|
||||
public func encode(_ encoder: PostboxEncoder) {
|
||||
switch self {
|
||||
case .bold:
|
||||
encoder.encodeInt32(0, forKey: "t")
|
||||
case .italic:
|
||||
encoder.encodeInt32(1, forKey: "t")
|
||||
case .monospace:
|
||||
encoder.encodeInt32(2, forKey: "t")
|
||||
case let .textMention(id):
|
||||
encoder.encodeInt32(3, forKey: "t")
|
||||
encoder.encodeInt64(id.toInt64(), forKey: "peerId")
|
||||
case let .textUrl(url):
|
||||
encoder.encodeInt32(4, forKey: "t")
|
||||
encoder.encodeString(url, forKey: "url")
|
||||
}
|
||||
}
|
||||
|
||||
public static func ==(lhs: ChatTextInputStateTextAttributeType, rhs: ChatTextInputStateTextAttributeType) -> Bool {
|
||||
switch lhs {
|
||||
case .bold:
|
||||
if case .bold = rhs {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case .italic:
|
||||
if case .italic = rhs {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case .monospace:
|
||||
if case .monospace = rhs {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .textMention(id):
|
||||
if case .textMention(id) = rhs {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .textUrl(url):
|
||||
if case .textUrl(url) = rhs {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public struct ChatTextInputStateTextAttribute: PostboxCoding, Equatable {
|
||||
public let type: ChatTextInputStateTextAttributeType
|
||||
public let range: Range<Int>
|
||||
|
||||
public init(type: ChatTextInputStateTextAttributeType, range: Range<Int>) {
|
||||
self.type = type
|
||||
self.range = range
|
||||
}
|
||||
|
||||
public init(decoder: PostboxDecoder) {
|
||||
self.type = decoder.decodeObjectForKey("type", decoder: { ChatTextInputStateTextAttributeType(decoder: $0) }) as! ChatTextInputStateTextAttributeType
|
||||
self.range = Int(decoder.decodeInt32ForKey("range0", orElse: 0)) ..< Int(decoder.decodeInt32ForKey("range1", orElse: 0))
|
||||
}
|
||||
|
||||
public func encode(_ encoder: PostboxEncoder) {
|
||||
encoder.encodeObject(self.type, forKey: "type")
|
||||
encoder.encodeInt32(Int32(self.range.lowerBound), forKey: "range0")
|
||||
encoder.encodeInt32(Int32(self.range.upperBound), forKey: "range1")
|
||||
}
|
||||
|
||||
public static func ==(lhs: ChatTextInputStateTextAttribute, rhs: ChatTextInputStateTextAttribute) -> Bool {
|
||||
return lhs.type == rhs.type && lhs.range == rhs.range
|
||||
}
|
||||
}
|
||||
|
||||
public struct ChatTextInputStateText: PostboxCoding, Equatable {
|
||||
public let text: String
|
||||
public let attributes: [ChatTextInputStateTextAttribute]
|
||||
|
||||
public init() {
|
||||
self.text = ""
|
||||
self.attributes = []
|
||||
}
|
||||
|
||||
public init(text: String, attributes: [ChatTextInputStateTextAttribute]) {
|
||||
self.text = text
|
||||
self.attributes = attributes
|
||||
}
|
||||
|
||||
public init(attributedText: NSAttributedString) {
|
||||
self.text = attributedText.string
|
||||
var parsedAttributes: [ChatTextInputStateTextAttribute] = []
|
||||
attributedText.enumerateAttributes(in: NSRange(location: 0, length: attributedText.length), options: [], using: { attributes, range, _ in
|
||||
for (key, value) in attributes {
|
||||
if key == ChatTextInputAttributes.bold {
|
||||
parsedAttributes.append(ChatTextInputStateTextAttribute(type: .bold, range: range.location ..< (range.location + range.length)))
|
||||
} else if key == ChatTextInputAttributes.italic {
|
||||
parsedAttributes.append(ChatTextInputStateTextAttribute(type: .italic, range: range.location ..< (range.location + range.length)))
|
||||
} else if key == ChatTextInputAttributes.monospace {
|
||||
parsedAttributes.append(ChatTextInputStateTextAttribute(type: .monospace, range: range.location ..< (range.location + range.length)))
|
||||
} else if key == ChatTextInputAttributes.textMention, let value = value as? ChatTextInputTextMentionAttribute {
|
||||
parsedAttributes.append(ChatTextInputStateTextAttribute(type: .textMention(value.peerId), range: range.location ..< (range.location + range.length)))
|
||||
} else if key == ChatTextInputAttributes.textUrl, let value = value as? ChatTextInputTextUrlAttribute {
|
||||
parsedAttributes.append(ChatTextInputStateTextAttribute(type: .textUrl(value.url), range: range.location ..< (range.location + range.length)))
|
||||
}
|
||||
}
|
||||
})
|
||||
self.attributes = parsedAttributes
|
||||
}
|
||||
|
||||
public init(decoder: PostboxDecoder) {
|
||||
self.text = decoder.decodeStringForKey("text", orElse: "")
|
||||
self.attributes = decoder.decodeObjectArrayWithDecoderForKey("attributes")
|
||||
}
|
||||
|
||||
public func encode(_ encoder: PostboxEncoder) {
|
||||
encoder.encodeString(self.text, forKey: "text")
|
||||
encoder.encodeObjectArray(self.attributes, forKey: "attributes")
|
||||
}
|
||||
|
||||
static public func ==(lhs: ChatTextInputStateText, rhs: ChatTextInputStateText) -> Bool {
|
||||
return lhs.text == rhs.text && lhs.attributes == rhs.attributes
|
||||
}
|
||||
|
||||
public func attributedText() -> NSAttributedString {
|
||||
let result = NSMutableAttributedString(string: self.text)
|
||||
for attribute in self.attributes {
|
||||
switch attribute.type {
|
||||
case .bold:
|
||||
result.addAttribute(ChatTextInputAttributes.bold, value: true as NSNumber, range: NSRange(location: attribute.range.lowerBound, length: attribute.range.count))
|
||||
case .italic:
|
||||
result.addAttribute(ChatTextInputAttributes.italic, value: true as NSNumber, range: NSRange(location: attribute.range.lowerBound, length: attribute.range.count))
|
||||
case .monospace:
|
||||
result.addAttribute(ChatTextInputAttributes.monospace, value: true as NSNumber, range: NSRange(location: attribute.range.lowerBound, length: attribute.range.count))
|
||||
case let .textMention(id):
|
||||
result.addAttribute(ChatTextInputAttributes.textMention, value: ChatTextInputTextMentionAttribute(peerId: id), range: NSRange(location: attribute.range.lowerBound, length: attribute.range.count))
|
||||
case let .textUrl(url):
|
||||
result.addAttribute(ChatTextInputAttributes.textUrl, value: ChatTextInputTextUrlAttribute(url: url), range: NSRange(location: attribute.range.lowerBound, length: attribute.range.count))
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user