mirror of
https://github.com/writeas/writefreely-swiftui-multiplatform.git
synced 2024-11-15 01:11:02 +00:00
Merge pull request #121 from writeas/use-content-if-post-has-no-title
Use content if post has no title
This commit is contained in:
commit
93e055d12f
@ -1,6 +1,7 @@
|
||||
import SwiftUI
|
||||
|
||||
struct PostCellView: View {
|
||||
@EnvironmentObject var model: WriteFreelyModel
|
||||
@ObservedObject var post: WFAPost
|
||||
var collectionName: String?
|
||||
|
||||
@ -12,6 +13,13 @@ struct PostCellView: View {
|
||||
return formatter
|
||||
}()
|
||||
|
||||
var titleText: String {
|
||||
if post.title.isEmpty {
|
||||
return model.posts.getBodyPreview(of: post)
|
||||
}
|
||||
return post.title
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
HStack {
|
||||
VStack(alignment: .leading) {
|
||||
@ -22,7 +30,7 @@ struct PostCellView: View {
|
||||
.padding(EdgeInsets(top: 3, leading: 4, bottom: 3, trailing: 4))
|
||||
.overlay(RoundedRectangle(cornerRadius: 2).stroke(Color.secondary, lineWidth: 1))
|
||||
}
|
||||
Text(post.title)
|
||||
Text(titleText)
|
||||
.font(.headline)
|
||||
Text(post.createdDate ?? Date(), formatter: Self.createdDateFormat)
|
||||
.font(.caption)
|
||||
@ -62,3 +70,17 @@ struct PostCell_NormalPreviews: PreviewProvider {
|
||||
.environment(\.managedObjectContext, context)
|
||||
}
|
||||
}
|
||||
|
||||
struct PostCell_NoTitlePreviews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
let context = LocalStorageManager.persistentContainer.viewContext
|
||||
let testPost = WFAPost(context: context)
|
||||
testPost.title = ""
|
||||
testPost.body = "Here's some cool sample body text."
|
||||
testPost.collectionAlias = "My Cool Blog"
|
||||
testPost.createdDate = Date()
|
||||
|
||||
return PostCellView(post: testPost)
|
||||
.environment(\.managedObjectContext, context)
|
||||
}
|
||||
}
|
||||
|
@ -18,4 +18,107 @@ class PostListModel: ObservableObject {
|
||||
print("Error: Failed to purge cached posts.")
|
||||
}
|
||||
}
|
||||
|
||||
func getBodyPreview(of post: WFAPost) -> String {
|
||||
var elidedPostBody: String = ""
|
||||
|
||||
// Strip any markdown from the post body.
|
||||
let strippedPostBody = stripMarkdown(from: post.body)
|
||||
|
||||
// Extract lede from post.
|
||||
elidedPostBody = extractLede(from: strippedPostBody)
|
||||
|
||||
return elidedPostBody
|
||||
}
|
||||
}
|
||||
|
||||
private extension PostListModel {
|
||||
|
||||
func stripMarkdown(from string: String) -> String {
|
||||
var strippedString = string
|
||||
strippedString = stripHeadingOctothorpes(from: strippedString)
|
||||
strippedString = stripImages(from: strippedString, keepAltText: true)
|
||||
return strippedString
|
||||
}
|
||||
|
||||
func stripHeadingOctothorpes(from string: String) -> String {
|
||||
let newLines = CharacterSet.newlines
|
||||
var processedComponents: [String] = []
|
||||
let components = string.components(separatedBy: newLines)
|
||||
for component in components {
|
||||
if component.isEmpty {
|
||||
continue
|
||||
}
|
||||
var newString = component
|
||||
while newString.first == "#" {
|
||||
newString.removeFirst()
|
||||
}
|
||||
if newString.hasPrefix(" ") {
|
||||
newString.removeFirst()
|
||||
}
|
||||
processedComponents.append(newString)
|
||||
}
|
||||
let headinglessString = processedComponents.joined(separator: "\n\n")
|
||||
return headinglessString
|
||||
}
|
||||
|
||||
func stripImages(from string: String, keepAltText: Bool = false) -> String {
|
||||
let pattern = #"!\[[\"]?(.*?)[\"|]?\]\(.*?\)"#
|
||||
var processedComponents: [String] = []
|
||||
let components = string.components(separatedBy: .newlines)
|
||||
for component in components {
|
||||
if component.isEmpty { continue }
|
||||
var processedString: String = component
|
||||
if keepAltText {
|
||||
let regex = try? NSRegularExpression(pattern: pattern, options: [])
|
||||
if let matches = regex?.matches(
|
||||
in: component, options: [], range: NSRange(location: 0, length: component.utf16.count)
|
||||
) {
|
||||
for match in matches {
|
||||
if let range = Range(match.range(at: 1), in: component) {
|
||||
processedString = "\(component[range])"
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let range = component.startIndex..<component.endIndex
|
||||
processedString = component.replacingOccurrences(
|
||||
of: pattern,
|
||||
with: "",
|
||||
options: .regularExpression,
|
||||
range: range
|
||||
)
|
||||
}
|
||||
if processedString.isEmpty { continue }
|
||||
processedComponents.append(processedString)
|
||||
}
|
||||
return processedComponents.joined(separator: "\n\n")
|
||||
}
|
||||
|
||||
func extractLede(from string: String) -> String {
|
||||
let truncatedString = string.prefix(80)
|
||||
let terminatingPunctuation = ".。?"
|
||||
let terminatingCharacters = CharacterSet(charactersIn: terminatingPunctuation).union(.newlines)
|
||||
|
||||
var lede: String = ""
|
||||
let sentences = truncatedString.components(separatedBy: terminatingCharacters)
|
||||
if let firstSentence = (sentences.filter { !$0.isEmpty }).first {
|
||||
if truncatedString.count > firstSentence.count {
|
||||
if terminatingPunctuation.contains(truncatedString[firstSentence.endIndex]) {
|
||||
lede = String(truncatedString[...firstSentence.endIndex])
|
||||
} else {
|
||||
lede = firstSentence
|
||||
}
|
||||
} else if truncatedString.count == firstSentence.count {
|
||||
if string.count > 80 {
|
||||
if let endOfStringIndex = truncatedString.lastIndex(of: " ") {
|
||||
lede = truncatedString[..<endOfStringIndex] + "…"
|
||||
}
|
||||
} else {
|
||||
lede = firstSentence
|
||||
}
|
||||
}
|
||||
}
|
||||
return lede
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user