mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2024-11-22 08:20:59 +00:00
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:
parent
6ebee8f5b5
commit
ae3d190799
3 changed files with 12 additions and 3 deletions
|
@ -69,7 +69,7 @@
|
||||||
"location" : "https://github.com/Dimillian/TextView",
|
"location" : "https://github.com/Dimillian/TextView",
|
||||||
"state" : {
|
"state" : {
|
||||||
"branch" : "main",
|
"branch" : "main",
|
||||||
"revision" : "a4ba065a69e3376aeb45b32846d50fd71a7e20e3"
|
"revision" : "22eec87ccac1270557b2b446fddc13c311bae5e7"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
|
@ -37,7 +37,7 @@ public struct StatusEditorView: View {
|
||||||
VStack(spacing: 12) {
|
VStack(spacing: 12) {
|
||||||
accountHeaderView
|
accountHeaderView
|
||||||
.padding(.horizontal, .layoutPadding)
|
.padding(.horizontal, .layoutPadding)
|
||||||
TextView($viewModel.statusText, $viewModel.selectedRange)
|
TextView($viewModel.statusText, $viewModel.selectedRange, $viewModel.markedTextRange)
|
||||||
.placeholder(String(localized: "status.editor.text.placeholder"))
|
.placeholder(String(localized: "status.editor.text.placeholder"))
|
||||||
.font(Font.scaledBodyUIFont)
|
.font(Font.scaledBodyUIFont)
|
||||||
.keyboardType(.twitter)
|
.keyboardType(.twitter)
|
||||||
|
|
|
@ -43,6 +43,7 @@ public class StatusEditorViewModel: ObservableObject {
|
||||||
@Published var spoilerText: String = ""
|
@Published var spoilerText: String = ""
|
||||||
|
|
||||||
@Published var selectedRange: NSRange = .init(location: 0, length: 0)
|
@Published var selectedRange: NSRange = .init(location: 0, length: 0)
|
||||||
|
@Published var markedTextRange: UITextRange? = nil
|
||||||
|
|
||||||
@Published var isPosting: Bool = false
|
@Published var isPosting: Bool = false
|
||||||
@Published var selectedMedias: [PhotosPickerItem] = [] {
|
@Published var selectedMedias: [PhotosPickerItem] = [] {
|
||||||
|
@ -155,6 +156,7 @@ public class StatusEditorViewModel: ObservableObject {
|
||||||
string.mutableString.insert(text, at: selectedRange.location)
|
string.mutableString.insert(text, at: selectedRange.location)
|
||||||
statusText = string
|
statusText = string
|
||||||
selectedRange = NSRange(location: selectedRange.location + text.utf16.count, length: 0)
|
selectedRange = NSRange(location: selectedRange.location + text.utf16.count, length: 0)
|
||||||
|
markedTextRange = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func replaceTextWith(text: String, inRange: NSRange) {
|
func replaceTextWith(text: String, inRange: NSRange) {
|
||||||
|
@ -163,11 +165,13 @@ public class StatusEditorViewModel: ObservableObject {
|
||||||
string.mutableString.insert(text, at: inRange.location)
|
string.mutableString.insert(text, at: inRange.location)
|
||||||
statusText = string
|
statusText = string
|
||||||
selectedRange = NSRange(location: inRange.location + text.utf16.count, length: 0)
|
selectedRange = NSRange(location: inRange.location + text.utf16.count, length: 0)
|
||||||
|
markedTextRange = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func replaceTextWith(text: String) {
|
func replaceTextWith(text: String) {
|
||||||
statusText = .init(string: text)
|
statusText = .init(string: text)
|
||||||
selectedRange = .init(location: text.utf16.count, length: 0)
|
selectedRange = .init(location: text.utf16.count, length: 0)
|
||||||
|
markedTextRange = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func prepareStatusText() {
|
func prepareStatusText() {
|
||||||
|
@ -193,7 +197,7 @@ public class StatusEditorViewModel: ObservableObject {
|
||||||
visibility = status.visibility
|
visibility = status.visibility
|
||||||
statusText = .init(string: mentionString)
|
statusText = .init(string: mentionString)
|
||||||
selectedRange = .init(location: mentionString.utf16.count, length: 0)
|
selectedRange = .init(location: mentionString.utf16.count, length: 0)
|
||||||
|
markedTextRange = nil
|
||||||
if !mentionString.isEmpty {
|
if !mentionString.isEmpty {
|
||||||
self.mentionString = mentionString.trimmingCharacters(in: .whitespaces)
|
self.mentionString = mentionString.trimmingCharacters(in: .whitespaces)
|
||||||
}
|
}
|
||||||
|
@ -201,6 +205,7 @@ public class StatusEditorViewModel: ObservableObject {
|
||||||
statusText = .init(string: "@\(account.acct) ")
|
statusText = .init(string: "@\(account.acct) ")
|
||||||
self.visibility = visibility
|
self.visibility = visibility
|
||||||
selectedRange = .init(location: statusText.string.utf16.count, length: 0)
|
selectedRange = .init(location: statusText.string.utf16.count, length: 0)
|
||||||
|
markedTextRange = nil
|
||||||
case let .edit(status):
|
case let .edit(status):
|
||||||
var rawText = NSAttributedString(status.content.asSafeMarkdownAttributedString).string
|
var rawText = NSAttributedString(status.content.asSafeMarkdownAttributedString).string
|
||||||
for mention in status.mentions {
|
for mention in status.mentions {
|
||||||
|
@ -208,6 +213,7 @@ public class StatusEditorViewModel: ObservableObject {
|
||||||
}
|
}
|
||||||
statusText = .init(string: rawText)
|
statusText = .init(string: rawText)
|
||||||
selectedRange = .init(location: statusText.string.utf16.count, length: 0)
|
selectedRange = .init(location: statusText.string.utf16.count, length: 0)
|
||||||
|
markedTextRange = nil
|
||||||
spoilerOn = !status.spoilerText.asRawText.isEmpty
|
spoilerOn = !status.spoilerText.asRawText.isEmpty
|
||||||
spoilerText = status.spoilerText.asRawText
|
spoilerText = status.spoilerText.asRawText
|
||||||
visibility = status.visibility
|
visibility = status.visibility
|
||||||
|
@ -220,11 +226,13 @@ public class StatusEditorViewModel: ObservableObject {
|
||||||
if let url = embeddedStatusURL {
|
if let url = embeddedStatusURL {
|
||||||
statusText = .init(string: "\n\nFrom: @\(status.reblog?.account.acct ?? status.account.acct)\n\(url)")
|
statusText = .init(string: "\n\nFrom: @\(status.reblog?.account.acct ?? status.account.acct)\n\(url)")
|
||||||
selectedRange = .init(location: 0, length: 0)
|
selectedRange = .init(location: 0, length: 0)
|
||||||
|
markedTextRange = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func processText() {
|
private func processText() {
|
||||||
|
guard markedTextRange == nil else { return }
|
||||||
statusText.addAttributes([.foregroundColor: UIColor(Color.label),
|
statusText.addAttributes([.foregroundColor: UIColor(Color.label),
|
||||||
.underlineColor: .clear],
|
.underlineColor: .clear],
|
||||||
range: NSMakeRange(0, statusText.string.utf16.count))
|
range: NSMakeRange(0, statusText.string.utf16.count))
|
||||||
|
@ -332,6 +340,7 @@ public class StatusEditorViewModel: ObservableObject {
|
||||||
if !initialText.isEmpty {
|
if !initialText.isEmpty {
|
||||||
statusText = .init(string: initialText)
|
statusText = .init(string: initialText)
|
||||||
selectedRange = .init(location: statusText.string.utf16.count, length: 0)
|
selectedRange = .init(location: statusText.string.utf16.count, length: 0)
|
||||||
|
markedTextRange = nil
|
||||||
}
|
}
|
||||||
if !mediasImages.isEmpty {
|
if !mediasImages.isEmpty {
|
||||||
processMediasToUpload()
|
processMediasToUpload()
|
||||||
|
|
Loading…
Reference in a new issue