Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Styled markdown with AttributedString #3590

Open
wants to merge 35 commits into
base: develop
Choose a base branch
from

Conversation

laevandus
Copy link
Contributor

@laevandus laevandus commented Feb 12, 2025

🔗 Issue Links

Resolves: IOS-41

🎯 Goal

Use AttributedString's markdown parsing support and apply styling on top of it.

📝 Summary

  • UIKit: Change DefaultMarkdownFormatter to use new AttributedString's markdown support
  • LLC: Add MarkdownParser (will be used by the SwiftUI SDK)
  • Remove SwiftyMarkdown (Remove SwiftyMarkdown #3591)
  • Gives stable markdown support (no parsing related crashes anymore)
  • Adds missing features like code blocks, applying bold or italic traits in headers
  • Remove MarkdownStyles.linkFont because UITextView overrides link attributes

🛠 Implementation

Added MarkdownParser to the LLC which can be used by UIKit and SwiftUI SDKs. It deals with applying additional attributes (injected via a closure because UIKit and SwiftUI use different logic) to various blocks (quote, code, etc). Since SwiftUI text rendering does not support NSParagraphStyle, the extension currently copes with this by adding additional newlines (alternative would have been separate logic for UIKit and SwiftUI, but it felt unnecessary to complicate it so much for our needs).
UIKit also has customisation just for Markdown through MarkdownStyles and MarkdownFont types where the latter is just changes to the default color and font (e.g. I can say that just change font size to 30, but keep using the default font).

Important

MarkdownStyles.linkFont does not really work because we use UITextView in the UIKit for rendering text and UITextView's linkTextAttributes is the one which drives the styling. Therefore, MarkdownStyles.linkFont.color = .green does not actually do anything in the UIKit SDK.

Note

Code blocks would need NSLayoutManager level customisation for background, can't be done with purely AttributedString. Considered this out of scope of this PR.

🎨 Showcase

Before After
uikitbefore1 uikitafter1
uikitbefore2 uikitafter2
uikitbefore3 uikitafter3

Performance

Compared the performance of the new and old implementation and roughly the new is 2x faster (tried a channel with multiple large messages with markdown).

Before After
Screenshot 2025-02-18 at 14 35 01 Screenshot 2025-02-18 at 14 35 33

🧪 Manual Testing Notes

  • Try various markdown combinations (parsing is similar to GitHub)
  • Try various combinations of markdown + mentions (e.g. @username, @userid) + plain links

☑️ Contributor Checklist

  • I have signed the Stream CLA (required)
  • This change should be manually QAed
  • Changelog is updated with client-facing changes
  • Changelog is updated with new localization keys
  • New code is covered by unit tests
  • Documentation has been updated in the docs-content repo

@laevandus laevandus added 🌐 SDK: StreamChat (LLC) Tasks related to the StreamChat LLC SDK 🎨 SDK: StreamChatUI Tasks related to the StreamChatUI SDK ✅ Feature An issue or PR related to a feature labels Feb 12, 2025
@laevandus laevandus requested a review from a team as a code owner February 12, 2025 09:01
Copy link

github-actions bot commented Feb 12, 2025

2 Warnings
⚠️ Big PR
⚠️ The changes should be manually QAed before the Pull Request will be merged

Generated by 🚫 Danger

@laevandus laevandus changed the title Styled markdown with AttributedString [WIP] Styled markdown with AttributedString Feb 12, 2025
@Stream-SDK-Bot
Copy link
Collaborator

SDK Performance

target metric benchmark branch performance status
MessageList Hitches total duration 10 ms 7.03 ms 29.7% 🔼 🟢
Duration 2.6 s 2.55 s 1.92% 🔼 🟢
Hitch time ratio 4 ms per s 2.75 ms per s 31.25% 🔼 🟢
Frame rate 75 fps 78.14 fps 4.19% 🔼 🟢
Number of hitches 1 0.6 40.0% 🔼 🟢

@Stream-SDK-Bot
Copy link
Collaborator

Stream-SDK-Bot commented Feb 12, 2025

SDK Size

title develop branch diff status
StreamChat 7.02 MB 7.04 MB +27 KB 🟢
StreamChatUI 4.77 MB 4.68 MB -92 KB 🚀

@laevandus laevandus changed the title [WIP] Styled markdown with AttributedString Styled markdown with AttributedString Feb 12, 2025
@laevandus laevandus mentioned this pull request Feb 12, 2025
6 tasks
Copy link
Member

@nuno-vieira nuno-vieira left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good, just asked a couple of questions 👍

Copy link
Member

@nuno-vieira nuno-vieira left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall LGTM ✅ Just added a couple of comments. Also, as @martinmitrevski suggested, it would be nice that for code snippets, the whole paragraph as the same background color if possible 🤔

@laevandus laevandus added the 🤞 Ready For QA A PR that is Ready for QA label Feb 18, 2025
Copy link
Member

@nuno-vieira nuno-vieira left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! ✅

@laevandus laevandus added 🧪 QAing and removed 🤞 Ready For QA A PR that is Ready for QA labels Feb 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
✅ Feature An issue or PR related to a feature 🧪 QAing 🌐 SDK: StreamChat (LLC) Tasks related to the StreamChat LLC SDK 🎨 SDK: StreamChatUI Tasks related to the StreamChatUI SDK
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants