-
Notifications
You must be signed in to change notification settings - Fork 190
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
Link previews #148
Link previews #148
Conversation
8f8b9c9
to
883f9be
Compare
153ca1a
to
a874a5b
Compare
I found a crash after rebasing on 1e4718e (swift 6 change), that didn't show up on swift 5.7. It turned out to be a new concurrency assertion:
So, I added the While at it, I made some minor style changes (moved the link pill code to |
This view lightly wraps LPLinkView, which does not have a SwiftUI equivalent. It is created so we can start adding support for link previews in messages, without requiring the caller to use UIKit. It also applies a light amount of custom styling: restricting the frame of the view so that it appears like a "pill" instead of a full preview to avoid taking up too much space in the message view.
This cache stores the metadata for link previews in memory. It has performance benefits in two situations: When scrolling past a MessageView, the metadata can be retrieved from cache instead of regenerated (preventing the link preview from flickering on scroll). A ReplyMessage containing a link preview can instantly display the cached preview, that was generated by the original Message.
This view abstracts away managing the placeholder and enriched metadata, and swapping out the link preview views when needed. It also transparently manages the link preview metadata cache, allowing the consumer to simply pass a URL and not have to know whether there's already a corresponding entry in the cache. Note that we need to disable strict concurrency checking for the LinkPresentation framework. This is because LPLinkMetadata is not Sendable and startFetchingMetadata(for:) uses a background thread and nonisolated context in order to generate the metadata. As far as I can tell, there is no way to use LinkPresentation with strict concurrency checking, as the preview view requires a metadata instance, and this can't cross isolation boundaries. So, the alternative would be to write our own version of the LinkPresentation framework that supports strict concurrency checks, which seems to be too heavy a solution.
This commit works around a bug in SwiftUI, where applying a .animation modifier to a Group doesn't have any effect. The transition is animated if ZStack is used instead. Meanwhile, make the LinkPreviewMetadata enum equatable, so that the .animation modifier can detect changes to the value. Using the synthesized implementation, two LinkPreviewMetadatas are equal if they are the same case, and have payloads that are memberwise-equal (which is the behaviour we want in this case).
This property extracts all URLs from the given AttributedString. It relies on the AttributedString's link attribute, instead of inferring link position from the text, to allow for custom styling (where consumers of the library annotate where the links should be themselves, via the AttributedString). This property is useful when generating link previews, and prevents us needing to create a new property in Message itself.
A spacer was used to push the time view to the right of the bubble. However, this spacer also pushed the edge of the bubble to the trailing edge of the screen, even if this extra space was not needed to fit the message text in the bubble. This did not cause a noticeable problem, since vstack was only used when the text was long enough to spill onto multiple lines, meaning the spacer would only cause a difference of a few pixels. However, now we are planning to add link previews (and we want a vstack configuration in this case even if the link is only a few characters long), we want to constrain the width of a vstack bubble so that it is only wide enough to hold the text. Otherwise, a single-character message containing a link would take up the full width of the screen, making it look out of place.
a874a5b
to
94a9cd8
Compare
Hey @matthewrfennell, thank you very much for this addition to the lib, have a spectacular day! |
@matthewrfennell Hm, it looks like you didn't include LinkPillView file into the project, could you please add it? EDIT: ah, sorry, just had to re-add the lib to account for the new file, spm is a tad strange on this |
demo.mp4.compressed.mp4
This PR includes:
Let me know if you have any thoughts or suggestions. Have a good day!
Closes #74