read more less wip
This commit is contained in:
parent
8e39e233dd
commit
8e0663377b
@ -76,13 +76,12 @@ struct ChatItemInfoView: View {
|
|||||||
set: { _ in }
|
set: { _ in }
|
||||||
)
|
)
|
||||||
VStack(alignment: .leading, spacing: 4) {
|
VStack(alignment: .leading, spacing: 4) {
|
||||||
messageText(itemVersion.msgContent.text, parseSimpleXMarkdown(itemVersion.msgContent.text), nil)
|
ExpandableText(itemVersion.msgContent.text, lineLimit: 3)
|
||||||
.allowsHitTesting(false)
|
|
||||||
.padding(.horizontal, 12)
|
.padding(.horizontal, 12)
|
||||||
.padding(.vertical, 6)
|
.padding(.vertical, 6)
|
||||||
.background(ciDirFrameColor(chatItemSent: chatItemSent, colorScheme: colorScheme))
|
.background(ciDirFrameColor(chatItemSent: chatItemSent, colorScheme: colorScheme))
|
||||||
.cornerRadius(18)
|
.cornerRadius(18)
|
||||||
.uiKitContextMenu(menu: uiMenu)
|
// .uiKitContextMenu(menu: uiMenu)
|
||||||
Text(localTimestamp(itemVersion.itemVersionTs) + (current ? " (Current)" : ""))
|
Text(localTimestamp(itemVersion.itemVersionTs) + (current ? " (Current)" : ""))
|
||||||
.foregroundStyle(.secondary)
|
.foregroundStyle(.secondary)
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
@ -128,6 +127,97 @@ struct ChatItemInfoView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ExpandableText: View {
|
||||||
|
@State private var expanded: Bool = false
|
||||||
|
@State private var truncated: Bool = false
|
||||||
|
@State private var shrinkText: String
|
||||||
|
|
||||||
|
private var text: String
|
||||||
|
let font: UIFont
|
||||||
|
let lineLimit: Int
|
||||||
|
|
||||||
|
init(_ text: String, lineLimit: Int, font: UIFont = UIFont.preferredFont(forTextStyle: UIFont.TextStyle.body)) {
|
||||||
|
self.text = text
|
||||||
|
_shrinkText = State(wrappedValue: text)
|
||||||
|
self.lineLimit = lineLimit
|
||||||
|
self.font = font
|
||||||
|
}
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ZStack(alignment: .bottomLeading) {
|
||||||
|
Group {
|
||||||
|
let t = self.expanded ? text : shrinkText
|
||||||
|
messageText(t, parseSimpleXMarkdown(t), nil)
|
||||||
|
+ moreLessText()
|
||||||
|
}
|
||||||
|
.lineLimit(expanded ? nil : lineLimit)
|
||||||
|
.background(
|
||||||
|
Text(text)
|
||||||
|
.lineLimit(lineLimit)
|
||||||
|
.background(GeometryReader { visibleTextGeometry in
|
||||||
|
Color.clear.onAppear() {
|
||||||
|
let size = CGSize(width: visibleTextGeometry.size.width, height: .greatestFiniteMagnitude)
|
||||||
|
let attributes:[NSAttributedString.Key:Any] = [NSAttributedString.Key.font: font]
|
||||||
|
|
||||||
|
var low = 0
|
||||||
|
var high = shrinkText.count
|
||||||
|
var mid = high
|
||||||
|
while ((high - low) > 1) {
|
||||||
|
let attributedText = NSAttributedString(string: shrinkText + moreLessStr, attributes: attributes)
|
||||||
|
let boundingRect = attributedText.boundingRect(with: size, options: NSStringDrawingOptions.usesLineFragmentOrigin, context: nil)
|
||||||
|
if boundingRect.size.height > visibleTextGeometry.size.height {
|
||||||
|
truncated = true
|
||||||
|
high = mid
|
||||||
|
mid = (high + low) / 2
|
||||||
|
} else {
|
||||||
|
if mid == text.count {
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
low = mid
|
||||||
|
mid = (low + high) / 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
shrinkText = String(text.prefix(mid)).trimmingCharacters(in: .whitespaces)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.hidden()
|
||||||
|
)
|
||||||
|
.font(Font(font))
|
||||||
|
if truncated {
|
||||||
|
Button(action: {
|
||||||
|
expanded.toggle()
|
||||||
|
}, label: {
|
||||||
|
HStack {
|
||||||
|
Spacer()
|
||||||
|
Text("")
|
||||||
|
}.opacity(0)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var moreLessStr: String {
|
||||||
|
if !truncated {
|
||||||
|
return ""
|
||||||
|
} else {
|
||||||
|
return self.expanded
|
||||||
|
? "\n" + NSLocalizedString("Read less", comment: "long text button")
|
||||||
|
: "… " + NSLocalizedString("Read more", comment: "long text button")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func moreLessText() -> Text {
|
||||||
|
if !truncated {
|
||||||
|
return Text("")
|
||||||
|
} else {
|
||||||
|
return self.expanded
|
||||||
|
? Text("\n") + Text("Read less").foregroundColor(.accentColor)
|
||||||
|
: Text("… ") + Text("Read more").foregroundColor(.accentColor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func localTimestamp(_ date: Date) -> String {
|
func localTimestamp(_ date: Date) -> String {
|
||||||
let localDateFormatter = DateFormatter()
|
let localDateFormatter = DateFormatter()
|
||||||
localDateFormatter.dateStyle = .medium
|
localDateFormatter.dateStyle = .medium
|
||||||
|
Loading…
Reference in New Issue
Block a user