MOBILE-438: Redraw the embedded block shimmer to the design - #769
Merged
Merged
Conversation
added 4 commits
September 7, 2026 16:29
The page reports how many elements it rendered as an Int: SwiftLint 0.59 flags the comparison anyway, and the test build fails on it.
One tint over the host's background whose opacity alone changes: #282A2F in light with a 4% dip, #FFFFFF in dark with a 16% peak, 8% elsewhere. A gradient layer 296% of the block's width sweeps from -188% to -8.3% in one second with ease-in, resting 0.6 s at both ends and jumping back. Every shimmer anchors its cycle to one shared clock, so several blocks on a screen move to the same beat.
The rendered count gets a name the empty_count rule does not mistake for a collection, so the lint directive goes. The shimmer takes its notification center from the outside, and the tests post the foreground notification to a private one instead of the process-wide center. A resize snaps rather than animating the tint into the new bounds. The class comment states the blur's share of the ramp correctly and notes that the shared beat depends on the host leaving the layer clock alone.
A view placed straight into a UIWindow that is released at the end of a test left the test process crashing on the next run-loop turn, about every other run. In the SDK the shimmer always sits inside the block container, so the tests now give it a host view inside the window too.
Contributor
|
justSmK
requested changes
Sep 8, 2026
justSmK
self-requested a review
September 8, 2026 11:41
justSmK
approved these changes
Sep 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The default shimmer of embedded blocks redrawn to the Figma spec (Mobile Launchpad → «Шиммер вью для встроенных блоков»), paired with Android MOBILE-439. 6 commits: the shimmer, a review pass, a test-stability fix, a lint fix the test build on the base needed, and two review follow-ups.
What changed and why:
EmbeddedBlockShimmerView.Designand are pinned by tests.CAKeyframeAnimationover the gradient layer's position: the layer is 296 % of the block width, the leading edge travels from −188 % to −8.3 % W in 1 s with an ease-in curve (0.42, 0, 1, 1), 0.6 s of rest on either side, an instant reset — a 2.2 s cycle. The gradient stops sit outside 0…1 so the ramp waits off-screen between sweeps.beatEpoch(CACurrentMediaTime()at first use) is converted into each layer's time space forbeginTime, so blocks created seconds apart still sweep together — the same idea as theuptimeMillisepoch on Android.bounds/positionactions are switched off once insetUp: a size change during a sweep must not animate the frame. The sweep is restarted onwillEnterForeground, since Core Animation drops animations in the background; the notification center is injected for tests.CALayerhas no public blur, and the difference is not visible at these opacities. Reduced Motion is marked open in the spec itself and keeps the normal behaviour for now, as the old shimmer did; a follow-up task decides between a static frame and the sweep.EmbeddedBlockWebViewProvider: thecountparameter renamed torenderedCount— SwiftLint 0.59 readscount > 0on anIntasempty_countand failed the test build on the base.Tests:
EmbeddedBlockShimmerViewTests, 15 Swift Testing cases — palette per interface style, stop locations at rest and at the end of the sweep, key times and timing functions of the sweep, one sharedbeginTimeacross two views, the restart on foreground, no implicit animation on resize. The shimmer is hosted under a plainUIViewinside the test window: a view placed directly into a per-testUIWindowthat is released at the end of the test crashed the process on the next run-loop turn (iOS 26 simulator).Impact for hosts — the one change a host will see:
systemGray5tile. Now it is a translucent mask: 8 % of one tint over whatever the host draws underneath, and the tint follows the system appearance (#282A2Fin light,#FFFFFFin dark), not the actual background. On a white, a dark and a brand-green host background in both appearances the shimmer reads as intended. A dark host screen under the light appearance, or a light screen under the dark one, gets a placeholder that is almost invisible: 8 % of near-black on near-black. Hosts with such screens should set the container'splaceholderView; the integration guide says so.Full run on iPhone 17: 1931 passed, 3 failed — the three
DateFormatMigrationTestscases fail in this local environment on iOS 26 regardless of branch and do not touch embedded blocks.swiftlint --strictclean.https://tracker.yandex.ru/MOBILE-438