fix: Improve markdown formatting in release notes view

Add custom AttributedString extension to properly format markdown with correct spacing and header styles. This fixes the compressed appearance of release notes by adding proper line breaks between sections and applying appropriate font sizes to headers.
This commit is contained in:
Ilyas Hallak 2025-10-19 20:41:04 +02:00
parent d97e404cc7
commit 47f8f73664

View File

@ -1,5 +1,46 @@
import SwiftUI import SwiftUI
extension AttributedString {
init(styledMarkdown markdownString: String) throws {
var output = try AttributedString(
markdown: markdownString,
options: .init(
allowsExtendedAttributes: true,
interpretedSyntax: .full,
failurePolicy: .returnPartiallyParsedIfPossible
),
baseURL: nil
)
for (intentBlock, intentRange) in output.runs[AttributeScopes.FoundationAttributes.PresentationIntentAttribute.self].reversed() {
guard let intentBlock = intentBlock else { continue }
for intent in intentBlock.components {
switch intent.kind {
case .header(level: let level):
switch level {
case 1:
output[intentRange].font = .system(.title).bold()
case 2:
output[intentRange].font = .system(.title2).bold()
case 3:
output[intentRange].font = .system(.title3).bold()
default:
break
}
default:
break
}
}
if intentRange.lowerBound != output.startIndex {
output.characters.insert(contentsOf: "\n\n", at: intentRange.lowerBound)
}
}
self = output
}
}
struct ReleaseNotesView: View { struct ReleaseNotesView: View {
@Environment(\.dismiss) private var dismiss @Environment(\.dismiss) private var dismiss
@ -33,10 +74,7 @@ struct ReleaseNotesView: View {
private func loadReleaseNotes() -> AttributedString? { private func loadReleaseNotes() -> AttributedString? {
guard let url = Bundle.main.url(forResource: "RELEASE_NOTES", withExtension: "md"), guard let url = Bundle.main.url(forResource: "RELEASE_NOTES", withExtension: "md"),
let markdownContent = try? String(contentsOf: url), let markdownContent = try? String(contentsOf: url),
let attributedString = try? AttributedString( let attributedString = try? AttributedString(styledMarkdown: markdownContent) else {
markdown: markdownContent,
options: .init(interpretedSyntax: .full)
) else {
return nil return nil
} }
return attributedString return attributedString