longform: add estimated read time to longform preview
Display estimated reading time in minutes alongside word count for longform articles. Uses standard 200 words per minute reading rate calculation. Closes: https://github.com/damus-io/damus/issues/3492 Changelog-Added: Added estimated read time to longform preview Signed-off-by: alltheseas
This commit is contained in:
committed by
Daniel D’Aquino
parent
0233f2ae48
commit
e8e2653316
@@ -381,6 +381,11 @@ struct LongformContent {
|
|||||||
let markdown: MarkdownContent
|
let markdown: MarkdownContent
|
||||||
let words: Int
|
let words: Int
|
||||||
|
|
||||||
|
/// Estimated reading time in minutes, based on average reading speed of 200 words per minute.
|
||||||
|
var estimatedReadTimeMinutes: Int {
|
||||||
|
return max(1, words / 200)
|
||||||
|
}
|
||||||
|
|
||||||
init(_ markdown: String) {
|
init(_ markdown: String) {
|
||||||
// Pre-process markdown to ensure images are block-level (have blank lines around them)
|
// Pre-process markdown to ensure images are block-level (have blank lines around them)
|
||||||
// This prevents images from being parsed as inline within text paragraphs
|
// This prevents images from being parsed as inline within text paragraphs
|
||||||
|
|||||||
@@ -35,11 +35,18 @@ struct LongformPreviewBody: View {
|
|||||||
self._artifacts = ObservedObject(wrappedValue: state.events.get_cache_data(ev.id).artifacts_model)
|
self._artifacts = ObservedObject(wrappedValue: state.events.get_cache_data(ev.id).artifacts_model)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Formats word count for display.
|
||||||
func Words(_ words: Int) -> Text {
|
func Words(_ words: Int) -> Text {
|
||||||
let wordCount = pluralizedString(key: "word_count", count: words)
|
let wordCount = pluralizedString(key: "word_count", count: words)
|
||||||
return Text(wordCount)
|
return Text(wordCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Formats estimated read time for display.
|
||||||
|
func ReadTime(_ minutes: Int) -> Text {
|
||||||
|
let readTime = pluralizedString(key: "read_time", count: minutes)
|
||||||
|
return Text(readTime)
|
||||||
|
}
|
||||||
|
|
||||||
var truncate: Bool {
|
var truncate: Bool {
|
||||||
return options.contains(.truncate_content)
|
return options.contains(.truncate_content)
|
||||||
}
|
}
|
||||||
@@ -161,8 +168,14 @@ struct LongformPreviewBody: View {
|
|||||||
if case .loaded(let arts) = artifacts.state,
|
if case .loaded(let arts) = artifacts.state,
|
||||||
case .longform(let longform) = arts
|
case .longform(let longform) = arts
|
||||||
{
|
{
|
||||||
Words(longform.words).font(.footnote)
|
HStack(spacing: 8) {
|
||||||
.padding([.horizontal, .bottom], 10)
|
ReadTime(longform.estimatedReadTimeMinutes)
|
||||||
|
Text("·")
|
||||||
|
Words(longform.words)
|
||||||
|
}
|
||||||
|
.font(.footnote)
|
||||||
|
.foregroundColor(.gray)
|
||||||
|
.padding([.horizontal, .bottom], 10)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.frame(maxWidth: .infinity, alignment: .leading)
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
|
|||||||
@@ -386,6 +386,22 @@
|
|||||||
<string>%d Words</string>
|
<string>%d Words</string>
|
||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
|
<key>read_time</key>
|
||||||
|
<dict>
|
||||||
|
<key>NSStringLocalizedFormatKey</key>
|
||||||
|
<string>%#@MINUTES@</string>
|
||||||
|
<key>MINUTES</key>
|
||||||
|
<dict>
|
||||||
|
<key>NSStringFormatSpecTypeKey</key>
|
||||||
|
<string>NSStringPluralRuleType</string>
|
||||||
|
<key>NSStringFormatValueTypeKey</key>
|
||||||
|
<string>d</string>
|
||||||
|
<key>one</key>
|
||||||
|
<string>%d min read</string>
|
||||||
|
<key>other</key>
|
||||||
|
<string>%d min read</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
<key>zap_notification_no_message</key>
|
<key>zap_notification_no_message</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>NSStringLocalizedFormatKey</key>
|
<key>NSStringLocalizedFormatKey</key>
|
||||||
|
|||||||
Reference in New Issue
Block a user