import 'package:gravity_sdk/gravity_sdk.dart'; class SelectedContent { const SelectedContent({required this.campaign, required this.content}); final Campaign campaign; final CampaignContent content; } SelectedContent? selectRoot(ContentResponse response) { for (final campaign in response.data) { for (final variation in campaign.payload) { for (final content in variation.contents) { if (content.step == null) { return SelectedContent(campaign: campaign, content: content); } } } } return null; } Future loadSelectedContent({ required String selector, required PageContext pageContext, }) async { final response = await GravitySDK.instance.getContentBySelector( selector: selector, pageContext: pageContext, ); return selectRoot(response); } // Один объект на одно фактическое размещение полученного контента. // Загрузка не считается показом. Показ фиксируем после появления UI. class ContentExposure { ContentExposure(this.selected); final SelectedContent selected; bool _shown = false; bool _visible = false; void onVisibility(double fraction) { if (fraction > 0 && !_shown) { _shown = true; GravitySDK.instance.sendContentEngagement( ContentImpressionEngagement(selected.content, selected.campaign), ); } if (fraction >= 0.5 && !_visible) { _visible = true; GravitySDK.instance.sendContentEngagement( ContentVisibleImpressionEngagement(selected.content, selected.campaign), ); } } void click() { GravitySDK.instance.sendContentEngagement( ContentClickEngagement(selected.content, selected.campaign), ); } }