mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
SGToolbar for media
This commit is contained in:
parent
9e1acf72dd
commit
2a1b4bc828
@ -1704,11 +1704,129 @@ extension TextFieldComponent.InputState {
|
|||||||
extension TextFieldComponent.View {
|
extension TextFieldComponent.View {
|
||||||
|
|
||||||
func sgToolbarAction(_ action: String) {
|
func sgToolbarAction(_ action: String) {
|
||||||
|
|
||||||
switch action {
|
switch action {
|
||||||
|
case "quote":
|
||||||
|
self.sgSelectLastWordIfIdle()
|
||||||
|
self.toggleAttribute(key: ChatTextInputAttributes.block, value: ChatTextInputTextQuoteAttribute(kind: .quote, isCollapsed: false))
|
||||||
|
case "spoiler":
|
||||||
|
self.sgSelectLastWordIfIdle()
|
||||||
|
self.toggleAttribute(key: ChatTextInputAttributes.spoiler)
|
||||||
|
case "bold":
|
||||||
|
self.sgSelectLastWordIfIdle()
|
||||||
|
self.toggleAttribute(key: ChatTextInputAttributes.bold)
|
||||||
|
case "italic":
|
||||||
|
self.sgSelectLastWordIfIdle()
|
||||||
|
self.toggleAttribute(key: ChatTextInputAttributes.italic)
|
||||||
|
case "monospace":
|
||||||
|
self.sgSelectLastWordIfIdle()
|
||||||
|
self.toggleAttribute(key: ChatTextInputAttributes.monospace)
|
||||||
|
case "link":
|
||||||
|
self.sgSelectLastWordIfIdle()
|
||||||
|
self.openLinkEditing()
|
||||||
|
case "strikethrough":
|
||||||
|
self.sgSelectLastWordIfIdle()
|
||||||
|
self.toggleAttribute(key: ChatTextInputAttributes.strikethrough)
|
||||||
|
case "underline":
|
||||||
|
self.sgSelectLastWordIfIdle()
|
||||||
|
self.toggleAttribute(key: ChatTextInputAttributes.underline)
|
||||||
|
case "code":
|
||||||
|
self.sgSelectLastWordIfIdle()
|
||||||
|
self.toggleAttribute(key: ChatTextInputAttributes.block, value: ChatTextInputTextQuoteAttribute(kind: .code(language: nil), isCollapsed: false))
|
||||||
|
case "newline":
|
||||||
|
self.sgSetNewLine()
|
||||||
|
case "clearFormatting":
|
||||||
|
self.updateInputState { current in
|
||||||
|
return current.clearFormattingAttributes()
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
print("action: \(action)")
|
assert(false, "Unhandled action \(action)")
|
||||||
// assert(false, "Unhandled action \(action)")
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func sgSelectLastWordIfIdle() {
|
||||||
|
self.updateInputState { current in
|
||||||
|
// No changes to current selection
|
||||||
|
if !current.selectionRange.isEmpty {
|
||||||
|
return current
|
||||||
|
}
|
||||||
|
|
||||||
|
let inputText = (current.inputText.mutableCopy() as? NSMutableAttributedString) ?? NSMutableAttributedString()
|
||||||
|
|
||||||
|
// If text is empty or cursor is at the start, return current state
|
||||||
|
guard inputText.length > 0, current.selectionRange.lowerBound > 0 else {
|
||||||
|
return current
|
||||||
|
}
|
||||||
|
|
||||||
|
let plainText = inputText.string
|
||||||
|
let nsString = plainText as NSString
|
||||||
|
|
||||||
|
// Create character set for word boundaries
|
||||||
|
let wordBoundaries = CharacterSet.whitespacesAndNewlines
|
||||||
|
|
||||||
|
// Start from cursor position instead of end of text
|
||||||
|
var endIndex = current.selectionRange.lowerBound - 1
|
||||||
|
|
||||||
|
// Find last non-whitespace character before cursor
|
||||||
|
while endIndex >= 0 &&
|
||||||
|
(nsString.substring(with: NSRange(location: endIndex, length: 1)) as NSString)
|
||||||
|
.rangeOfCharacter(from: wordBoundaries).location != NSNotFound {
|
||||||
|
endIndex -= 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we only had whitespace before cursor, return current state
|
||||||
|
guard endIndex >= 0 else {
|
||||||
|
return current
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find start of the current word by looking backwards for whitespace
|
||||||
|
var startIndex = endIndex
|
||||||
|
while startIndex > 0 {
|
||||||
|
let char = nsString.substring(with: NSRange(location: startIndex - 1, length: 1))
|
||||||
|
if (char as NSString).rangeOfCharacter(from: wordBoundaries).location != NSNotFound {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
startIndex -= 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create range for the word at cursor
|
||||||
|
let wordLength = endIndex - startIndex + 1
|
||||||
|
let wordRange = NSRange(location: startIndex, length: wordLength)
|
||||||
|
|
||||||
|
// Create new selection range
|
||||||
|
let newSelectionRange = wordRange.location ..< (wordRange.location + wordLength)
|
||||||
|
|
||||||
|
return TextFieldComponent.InputState(inputText: inputText, selectionRange: newSelectionRange)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func sgSetNewLine() {
|
||||||
|
self.updateInputState { current in
|
||||||
|
let inputText = (current.inputText.mutableCopy() as? NSMutableAttributedString) ?? NSMutableAttributedString()
|
||||||
|
|
||||||
|
// Check if there's selected text
|
||||||
|
let hasSelection = current.selectionRange.count > 0
|
||||||
|
|
||||||
|
if hasSelection {
|
||||||
|
// Move selected text to new line
|
||||||
|
let selectedText = inputText.attributedSubstring(from: NSRange(current.selectionRange))
|
||||||
|
let newLineAttr = NSAttributedString(string: "\n")
|
||||||
|
|
||||||
|
// Insert newline and selected text
|
||||||
|
inputText.replaceCharacters(in: NSRange(current.selectionRange), with: newLineAttr)
|
||||||
|
inputText.insert(selectedText, at: current.selectionRange.lowerBound + 1)
|
||||||
|
|
||||||
|
// Update selection range to end of moved text
|
||||||
|
let newPosition = current.selectionRange.lowerBound + 1 + selectedText.length
|
||||||
|
return TextFieldComponent.InputState(inputText: inputText, selectionRange: newPosition ..< newPosition)
|
||||||
|
} else {
|
||||||
|
// Simple newline insertion at current position
|
||||||
|
let attributedString = NSAttributedString(string: "\n")
|
||||||
|
inputText.replaceCharacters(in: NSRange(current.selectionRange), with: attributedString)
|
||||||
|
|
||||||
|
// Update cursor position
|
||||||
|
let newPosition = current.selectionRange.lowerBound + attributedString.length
|
||||||
|
return TextFieldComponent.InputState(inputText: inputText, selectionRange: newPosition ..< newPosition)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user