Added marked text range support (#345)

* 👍 Added markedTextRangeSupport.

* 👍 ignore when markedTextRange is non-nil.

* Update TextView revision

Co-authored-by: Hidemune Takahashi <h1d3mun3.74k4h45h1@gmail.com>
Co-authored-by: Thomas Ricouard <ricouard77@gmail.com>
This commit is contained in:
Hidemune Takahashi 2023-01-25 01:26:56 +09:00 committed by GitHub
parent 6ebee8f5b5
commit ae3d190799
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 12 additions and 3 deletions

View file

@ -69,7 +69,7 @@
"location" : "https://github.com/Dimillian/TextView",
"state" : {
"branch" : "main",
"revision" : "a4ba065a69e3376aeb45b32846d50fd71a7e20e3"
"revision" : "22eec87ccac1270557b2b446fddc13c311bae5e7"
}
}
],

View file

@ -37,7 +37,7 @@ public struct StatusEditorView: View {
VStack(spacing: 12) {
accountHeaderView
.padding(.horizontal, .layoutPadding)
TextView($viewModel.statusText, $viewModel.selectedRange)
TextView($viewModel.statusText, $viewModel.selectedRange, $viewModel.markedTextRange)
.placeholder(String(localized: "status.editor.text.placeholder"))
.font(Font.scaledBodyUIFont)
.keyboardType(.twitter)

View file

@ -43,6 +43,7 @@ public class StatusEditorViewModel: ObservableObject {
@Published var spoilerText: String = ""
@Published var selectedRange: NSRange = .init(location: 0, length: 0)
@Published var markedTextRange: UITextRange? = nil
@Published var isPosting: Bool = false
@Published var selectedMedias: [PhotosPickerItem] = [] {
@ -155,6 +156,7 @@ public class StatusEditorViewModel: ObservableObject {
string.mutableString.insert(text, at: selectedRange.location)
statusText = string
selectedRange = NSRange(location: selectedRange.location + text.utf16.count, length: 0)
markedTextRange = nil
}
func replaceTextWith(text: String, inRange: NSRange) {
@ -163,11 +165,13 @@ public class StatusEditorViewModel: ObservableObject {
string.mutableString.insert(text, at: inRange.location)
statusText = string
selectedRange = NSRange(location: inRange.location + text.utf16.count, length: 0)
markedTextRange = nil
}
func replaceTextWith(text: String) {
statusText = .init(string: text)
selectedRange = .init(location: text.utf16.count, length: 0)
markedTextRange = nil
}
func prepareStatusText() {
@ -193,7 +197,7 @@ public class StatusEditorViewModel: ObservableObject {
visibility = status.visibility
statusText = .init(string: mentionString)
selectedRange = .init(location: mentionString.utf16.count, length: 0)
markedTextRange = nil
if !mentionString.isEmpty {
self.mentionString = mentionString.trimmingCharacters(in: .whitespaces)
}
@ -201,6 +205,7 @@ public class StatusEditorViewModel: ObservableObject {
statusText = .init(string: "@\(account.acct) ")
self.visibility = visibility
selectedRange = .init(location: statusText.string.utf16.count, length: 0)
markedTextRange = nil
case let .edit(status):
var rawText = NSAttributedString(status.content.asSafeMarkdownAttributedString).string
for mention in status.mentions {
@ -208,6 +213,7 @@ public class StatusEditorViewModel: ObservableObject {
}
statusText = .init(string: rawText)
selectedRange = .init(location: statusText.string.utf16.count, length: 0)
markedTextRange = nil
spoilerOn = !status.spoilerText.asRawText.isEmpty
spoilerText = status.spoilerText.asRawText
visibility = status.visibility
@ -220,11 +226,13 @@ public class StatusEditorViewModel: ObservableObject {
if let url = embeddedStatusURL {
statusText = .init(string: "\n\nFrom: @\(status.reblog?.account.acct ?? status.account.acct)\n\(url)")
selectedRange = .init(location: 0, length: 0)
markedTextRange = nil
}
}
}
private func processText() {
guard markedTextRange == nil else { return }
statusText.addAttributes([.foregroundColor: UIColor(Color.label),
.underlineColor: .clear],
range: NSMakeRange(0, statusText.string.utf16.count))
@ -332,6 +340,7 @@ public class StatusEditorViewModel: ObservableObject {
if !initialText.isEmpty {
statusText = .init(string: initialText)
selectedRange = .init(location: statusText.string.utf16.count, length: 0)
markedTextRange = nil
}
if !mediasImages.isEmpty {
processMediasToUpload()