diff --git a/GitTrends.Android/GitTrends.Android.csproj b/GitTrends.Android/GitTrends.Android.csproj index 094e7c2a1..1eaf76231 100644 --- a/GitTrends.Android/GitTrends.Android.csproj +++ b/GitTrends.Android/GitTrends.Android.csproj @@ -101,7 +101,7 @@ - + diff --git a/GitTrends.Mobile.Common/Constants/AutomationIds/RepositoryPageAutomationIds.cs b/GitTrends.Mobile.Common/Constants/AutomationIds/RepositoryPageAutomationIds.cs index f6cc2eed5..316725558 100644 --- a/GitTrends.Mobile.Common/Constants/AutomationIds/RepositoryPageAutomationIds.cs +++ b/GitTrends.Mobile.Common/Constants/AutomationIds/RepositoryPageAutomationIds.cs @@ -10,5 +10,21 @@ public static class RepositoryPageAutomationIds public const string EmptyDataView = nameof(RepositoryPageAutomationIds) + nameof(EmptyDataView); public const string LargeScreenTrendingImage = nameof(RepositoryPageAutomationIds) + nameof(LargeScreenTrendingImage); public const string SmallScreenTrendingImage = nameof(RepositoryPageAutomationIds) + nameof(SmallScreenTrendingImage); + public const string InformationButton = nameof(RepositoryPageAutomationIds) + nameof(InformationButton); + public const string InformationLabel = nameof(RepositoryPageAutomationIds) + nameof(InformationLabel); + + public static string GetFloatingActionTextButtonLabelAutomationId(in FloatingActionButtonType floatingActionButtonType) + { + const string label = "Label"; + + return floatingActionButtonType switch + { + FloatingActionButtonType.Information => nameof(RepositoryPageAutomationIds) + nameof(FloatingActionButtonType.Information) + label, + FloatingActionButtonType.Statistic1 => nameof(RepositoryPageAutomationIds) + nameof(FloatingActionButtonType.Statistic1) + label, + FloatingActionButtonType.Statistic2 => nameof(RepositoryPageAutomationIds) + nameof(FloatingActionButtonType.Statistic2) + label, + FloatingActionButtonType.Statistic3 => nameof(RepositoryPageAutomationIds) + nameof(FloatingActionButtonType.Statistic3) + label, + _ => throw new System.NotImplementedException(), + }; + } } } diff --git a/GitTrends.Mobile.Common/Enums/FloatingActionButtonType.cs b/GitTrends.Mobile.Common/Enums/FloatingActionButtonType.cs new file mode 100644 index 000000000..0cbed4f47 --- /dev/null +++ b/GitTrends.Mobile.Common/Enums/FloatingActionButtonType.cs @@ -0,0 +1,4 @@ +namespace GitTrends.Mobile.Common +{ + public enum FloatingActionButtonType { Information, Statistic1, Statistic2, Statistic3 } +} diff --git a/GitTrends.Mobile.Common/Services/StatisticsService.cs b/GitTrends.Mobile.Common/Services/StatisticsService.cs index 9f8798622..2071a197c 100644 --- a/GitTrends.Mobile.Common/Services/StatisticsService.cs +++ b/GitTrends.Mobile.Common/Services/StatisticsService.cs @@ -1,4 +1,10 @@ -namespace GitTrends.Mobile.Common +using System; +using System.Collections.Generic; +using System.Linq; +using GitTrends.Mobile.Common.Constants; +using GitTrends.Shared; + +namespace GitTrends.Mobile.Common { public static class StatisticsService { @@ -17,5 +23,38 @@ public static string ToAbbreviatedText(this long number) return "0"; } + + public static string GetInformationLabelText(in IReadOnlyList repositories, in MobileSortingService mobileSortingService) where TRepository : IRepository => + GetInformationLabelText(repositories, MobileSortingService.GetSortingCategory(mobileSortingService.CurrentOption)); + + public static string GetInformationLabelText(in IReadOnlyList repositories, in SortingCategory sortingCategory) where TRepository : IRepository => (repositories.Any(), sortingCategory) switch + { + (false, _) => string.Empty, + (true, SortingCategory.Views) => $"{SortingConstants.Views} {repositories.Sum(x => x.TotalViews).ToAbbreviatedText()}, {SortingConstants.UniqueViews} {repositories.Sum(x => x.TotalUniqueViews).ToAbbreviatedText()}, {SortingConstants.Stars} {repositories.Sum(x => x.StarCount).ToAbbreviatedText()}", + (true, SortingCategory.Clones) => $"{SortingConstants.Clones} {repositories.Sum(x => x.TotalClones).ToAbbreviatedText()}, {SortingConstants.UniqueClones} {repositories.Sum(x => x.TotalUniqueClones).ToAbbreviatedText()}, {SortingConstants.Stars} {repositories.Sum(x => x.StarCount).ToAbbreviatedText()}", + (true, SortingCategory.IssuesForks) => $"{SortingConstants.Stars} {repositories.Sum(x => x.StarCount).ToAbbreviatedText()}, {SortingConstants.Forks} {repositories.Sum(x => x.ForkCount).ToAbbreviatedText()}, {SortingConstants.Issues} {repositories.Sum(x => x.IssuesCount).ToAbbreviatedText()}", + (_, _) => throw new NotSupportedException() + }; + + public static string GetFloatingActionTextButtonText(in MobileSortingService mobileSortingService, in IReadOnlyList repositories, in FloatingActionButtonType floatingActionButtonType) where TRepository : IRepository => + GetFloatingActionTextButtonText(MobileSortingService.GetSortingCategory(mobileSortingService.CurrentOption), repositories.ToList(), floatingActionButtonType); + + public static string GetFloatingActionTextButtonText(in SortingCategory sortingCategory, in IReadOnlyList repositories, in FloatingActionButtonType floatingActionButtonType) where TRepository : IRepository + { + return (sortingCategory, floatingActionButtonType) switch + { + (SortingCategory.Clones, FloatingActionButtonType.Statistic1) => repositories.Sum(x => x.TotalClones).ToAbbreviatedText(), + (SortingCategory.Clones, FloatingActionButtonType.Statistic2) => repositories.Sum(x => x.TotalUniqueClones).ToAbbreviatedText(), + (SortingCategory.Clones, FloatingActionButtonType.Statistic3) => repositories.Sum(x => x.StarCount).ToAbbreviatedText(), + (SortingCategory.Views, FloatingActionButtonType.Statistic1) => repositories.Sum(x => x.TotalViews).ToAbbreviatedText(), + (SortingCategory.Views, FloatingActionButtonType.Statistic2) => repositories.Sum(x => x.TotalUniqueViews).ToAbbreviatedText(), + (SortingCategory.Views, FloatingActionButtonType.Statistic3) => repositories.Sum(x => x.StarCount).ToAbbreviatedText(), + (SortingCategory.IssuesForks, FloatingActionButtonType.Statistic1) => repositories.Sum(x => x.StarCount).ToAbbreviatedText(), + (SortingCategory.IssuesForks, FloatingActionButtonType.Statistic2) => repositories.Sum(x => x.ForkCount).ToAbbreviatedText(), + (SortingCategory.IssuesForks, FloatingActionButtonType.Statistic3) => repositories.Sum(x => x.IssuesCount).ToAbbreviatedText(), + (_, FloatingActionButtonType.Information) => throw new NotSupportedException(), + (_, _) => throw new NotImplementedException() + }; + } } } diff --git a/GitTrends.UITests/Pages/BaseCollectionPage.cs b/GitTrends.UITests/Pages/BaseCollectionPage.cs index c812021e5..6d48cd517 100644 --- a/GitTrends.UITests/Pages/BaseCollectionPage.cs +++ b/GitTrends.UITests/Pages/BaseCollectionPage.cs @@ -15,7 +15,7 @@ protected BaseCollectionPage(IApp app, Func? getPageTitle) : base(app, g } - public List VisibleCollection => App.InvokeBackdoorMethod>(BackdoorMethodConstants.GetVisibleCollection); + public IReadOnlyList VisibleCollection => App.InvokeBackdoorMethod>(BackdoorMethodConstants.GetVisibleCollection); bool IsRefreshViewRefreshIndicatorDisplayed => App switch { diff --git a/GitTrends.UITests/Pages/RepositoryPage.cs b/GitTrends.UITests/Pages/RepositoryPage.cs index f670e4ae9..745e37547 100644 --- a/GitTrends.UITests/Pages/RepositoryPage.cs +++ b/GitTrends.UITests/Pages/RepositoryPage.cs @@ -14,7 +14,8 @@ class RepositoryPage : BaseCollectionPage { readonly Query _searchBar, _settingsButton, _collectionView, _refreshView, _androidContextMenuOverflowButton, _androidSearchBarButton, _sortButton, _emptyDataView, - _smallScreenTrendingImage, _largeScreenTrendingImage; + _smallScreenTrendingImage, _largeScreenTrendingImage, _informationLabel, _informationButton, + _statistic1FloatingActionButton, _statistic2FloatingActionButton, _statistic3FloatingActionButton; public RepositoryPage(IApp app) : base(app, () => PageTitles.RepositoryPage) { @@ -28,6 +29,11 @@ public RepositoryPage(IApp app) : base(app, () => PageTitles.RepositoryPage) _emptyDataView = GenerateMarkedQuery(RepositoryPageAutomationIds.EmptyDataView); _smallScreenTrendingImage = GenerateMarkedQuery(RepositoryPageAutomationIds.SmallScreenTrendingImage); _largeScreenTrendingImage = GenerateMarkedQuery(RepositoryPageAutomationIds.LargeScreenTrendingImage); + _informationButton = GenerateMarkedQuery(RepositoryPageAutomationIds.InformationButton); + _informationLabel = GenerateMarkedQuery(RepositoryPageAutomationIds.InformationLabel); + _statistic1FloatingActionButton = GenerateMarkedQuery(RepositoryPageAutomationIds.GetFloatingActionTextButtonLabelAutomationId(FloatingActionButtonType.Statistic1)); + _statistic2FloatingActionButton = GenerateMarkedQuery(RepositoryPageAutomationIds.GetFloatingActionTextButtonLabelAutomationId(FloatingActionButtonType.Statistic2)); + _statistic3FloatingActionButton = GenerateMarkedQuery(RepositoryPageAutomationIds.GetFloatingActionTextButtonLabelAutomationId(FloatingActionButtonType.Statistic3)); } public bool IsEmptyDataViewVisible => App.Query(_emptyDataView).Any(); @@ -35,6 +41,25 @@ public RepositoryPage(IApp app) : base(app, () => PageTitles.RepositoryPage) public int SmallScreenTrendingImageCount => App.Query(_smallScreenTrendingImage).Count(); public int LargeScreenTrendingImageCount => App.Query(_largeScreenTrendingImage).Count(); + public string InformationLabelText => App is iOSApp ? GetText(_informationLabel) : throw new NotSupportedException("Information Label Only Available on iOS"); + + public string InformationButtonStatistic1Text => App is AndroidApp ? GetText(_statistic1FloatingActionButton) : throw new NotSupportedException("Information Button Only Available on Android"); + public string InformationButtonStatistic2Text => App is AndroidApp ? GetText(_statistic2FloatingActionButton) : throw new NotSupportedException("Information Button Only Available on Android"); + public string InformationButtonStatistic3Text => App is AndroidApp ? GetText(_statistic3FloatingActionButton) : throw new NotSupportedException("Information Button Only Available on Android"); + + public void TapInformationButton() + { + if (App is AndroidApp) + { + App.Tap(_informationButton); + App.Screenshot("Information Button Tapped"); + } + else + { + throw new NotSupportedException("Information Button Only Available on Android"); + } + } + public void WaitForEmptyDataView() { App.WaitForElement(_emptyDataView); diff --git a/GitTrends.UITests/Tests/ReferringSitesTests.cs b/GitTrends.UITests/Tests/ReferringSitesTests.cs index 8d0454386..9fb58bc31 100644 --- a/GitTrends.UITests/Tests/ReferringSitesTests.cs +++ b/GitTrends.UITests/Tests/ReferringSitesTests.cs @@ -24,7 +24,7 @@ public override async Task BeforeEachTest() { await base.BeforeEachTest().ConfigureAwait(false); - var referringSites = new List(); + IReadOnlyList referringSites = Enumerable.Empty().ToList(); var repositories = RepositoryPage.VisibleCollection; var repositoriesEnumerator = repositories.GetEnumerator(); diff --git a/GitTrends.UITests/Tests/RepositoriesTests.cs b/GitTrends.UITests/Tests/RepositoriesTests.cs index 5d21ef559..04a3ac70b 100644 --- a/GitTrends.UITests/Tests/RepositoriesTests.cs +++ b/GitTrends.UITests/Tests/RepositoriesTests.cs @@ -6,6 +6,8 @@ using GitTrends.Mobile.Common.Constants; using NUnit.Framework; using Xamarin.UITest; +using Xamarin.UITest.Android; +using Xamarin.UITest.iOS; namespace GitTrends.UITests { @@ -105,16 +107,27 @@ public async Task VerifySortingOptions(SortingOption sortingOption) Assert.AreEqual(MobileSortingService.DefaultSortingOption, SortingOption.Views); //Arrange - Repository finalFirstRepository; - Repository finalSecondTopRepository; - Repository finalLastRepository; + Repository finalFirstRepository, finalSecondTopRepository, finalLastRepository; Repository initialFirstRepository = RepositoryPage.VisibleCollection.First(); Repository initialSecondTopRepository = RepositoryPage.VisibleCollection.Skip(1).First(); Repository initialLastRepository = RepositoryPage.VisibleCollection.Last(); + string floatingActionTextButtonStatistic1Text = string.Empty, + floatingActionTextButtonStatistic2Text = string.Empty, + floatingActionTextButtonStatistic3Text = string.Empty; + //Act await RepositoryPage.SetSortingOption(sortingOption).ConfigureAwait(false); + if (App is AndroidApp) + { + floatingActionTextButtonStatistic1Text = RepositoryPage.InformationButtonStatistic1Text; + floatingActionTextButtonStatistic2Text = RepositoryPage.InformationButtonStatistic2Text; + floatingActionTextButtonStatistic3Text = RepositoryPage.InformationButtonStatistic3Text; + + RepositoryPage.TapInformationButton(); + } + //Assert finalFirstRepository = RepositoryPage.VisibleCollection.First(); finalSecondTopRepository = RepositoryPage.VisibleCollection.Skip(1).First(); @@ -125,6 +138,26 @@ public async Task VerifySortingOptions(SortingOption sortingOption) Assert.GreaterOrEqual(initialFirstRepository.TotalViews, initialLastRepository.TotalViews); + if (App is AndroidApp) + { + var floatingActionTextButtonStatistic1Text_Expected = StatisticsService.GetFloatingActionTextButtonText(MobileSortingService.GetSortingCategory(sortingOption), RepositoryPage.VisibleCollection, FloatingActionButtonType.Statistic1); + var floatingActionTextButtonStatistic2Text_Expected = StatisticsService.GetFloatingActionTextButtonText(MobileSortingService.GetSortingCategory(sortingOption), RepositoryPage.VisibleCollection, FloatingActionButtonType.Statistic2); + var floatingActionTextButtonStatistic3Text_Expected = StatisticsService.GetFloatingActionTextButtonText(MobileSortingService.GetSortingCategory(sortingOption), RepositoryPage.VisibleCollection, FloatingActionButtonType.Statistic3); + + Assert.AreEqual(floatingActionTextButtonStatistic1Text_Expected, floatingActionTextButtonStatistic1Text); + Assert.AreEqual(floatingActionTextButtonStatistic2Text_Expected, floatingActionTextButtonStatistic2Text); + Assert.AreEqual(floatingActionTextButtonStatistic3Text_Expected, floatingActionTextButtonStatistic3Text); + } + else if (App is iOSApp) + { + var informationLabelText_Expected = StatisticsService.GetInformationLabelText(RepositoryPage.VisibleCollection, MobileSortingService.GetSortingCategory(sortingOption)); + Assert.AreEqual(informationLabelText_Expected, RepositoryPage.InformationLabelText); + } + else + { + throw new NotSupportedException(); + } + switch (sortingOption) { case SortingOption.Views when finalFirstRepository.IsTrending == finalSecondTopRepository.IsTrending: diff --git a/GitTrends.iOS/GitTrends.iOS.csproj b/GitTrends.iOS/GitTrends.iOS.csproj index 4efc8b527..de23dc0bd 100644 --- a/GitTrends.iOS/GitTrends.iOS.csproj +++ b/GitTrends.iOS/GitTrends.iOS.csproj @@ -438,7 +438,7 @@ - + diff --git a/GitTrends/GitTrends.csproj b/GitTrends/GitTrends.csproj index c286b6247..6a99cbf76 100644 --- a/GitTrends/GitTrends.csproj +++ b/GitTrends/GitTrends.csproj @@ -42,7 +42,7 @@ - + diff --git a/GitTrends/Pages/RepositoryPage.cs b/GitTrends/Pages/RepositoryPage.cs index 32f8fe1a9..f2dd493a0 100644 --- a/GitTrends/Pages/RepositoryPage.cs +++ b/GitTrends/Pages/RepositoryPage.cs @@ -76,9 +76,9 @@ public RepositoryPage(IMainThread mainThread, Children = { - new TotalsLabel().Row(Row.Totals).ColumnSpan(All()) + new InformationLabel().Row(Row.Totals).ColumnSpan(All()) .Bind(IsVisibleProperty,nameof(RepositoryViewModel.IsRefreshing), convert: isRefreshing => !isRefreshing) - .Bind, string>(Label.TextProperty, nameof(RepositoryViewModel.VisibleRepositoryList), convert: repositories => totalsLabelConverter(repositories, mobileSortingService)), + .Bind, string>(Label.TextProperty, nameof(RepositoryViewModel.VisibleRepositoryList), convert: repositories => StatisticsService.GetInformationLabelText(repositories, mobileSortingService)), new RefreshView { @@ -109,21 +109,7 @@ public RepositoryPage(IMainThread mainThread, if (Device.RuntimePlatform is Device.Android) { - grid.Children.Add(new InformationButton(mobileSortingService, mainThread).Row(Row.Information).Column(Column.Information)); - } - - static string totalsLabelConverter(in IReadOnlyList repositories, in MobileSortingService mobileSortingService) - { - if (!repositories.Any()) - return string.Empty; - - return MobileSortingService.GetSortingCategory(mobileSortingService.CurrentOption) switch - { - SortingCategory.Views => $"{SortingConstants.Views} {repositories.Sum(x => x.TotalViews).ToAbbreviatedText()}, {SortingConstants.UniqueViews} {repositories.Sum(x => x.TotalUniqueViews).ToAbbreviatedText()}, {SortingConstants.Stars} {repositories.Sum(x => x.StarCount).ToAbbreviatedText()}", - SortingCategory.Clones => $"{SortingConstants.Clones} {repositories.Sum(x => x.TotalClones).ToAbbreviatedText()}, {SortingConstants.UniqueClones} {repositories.Sum(x => x.TotalUniqueClones).ToAbbreviatedText()}, {SortingConstants.Stars} {repositories.Sum(x => x.StarCount).ToAbbreviatedText()}", - SortingCategory.IssuesForks => $"{SortingConstants.Stars} {repositories.Sum(x => x.StarCount).ToAbbreviatedText()}, {SortingConstants.Forks} {repositories.Sum(x => x.ForkCount).ToAbbreviatedText()}, {SortingConstants.Issues} {repositories.Sum(x => x.IssuesCount).ToAbbreviatedText()}", - _ => throw new NotSupportedException() - }; + grid.Children.Add(new InformationButton(mobileSortingService, mainThread, analyticsService).Row(Row.Information).Column(Column.Information)); } } @@ -248,9 +234,13 @@ void HandlePreferredLanguageChanged(object sender, string? e) void ISearchPage.OnSearchBarTextChanged(in string text) => _searchTextChangedEventManager.RaiseEvent(this, text, nameof(SearchBarTextChanged)); - class TotalsLabel : StatisticsLabel + class InformationLabel : StatisticsLabel { - public TotalsLabel() : base(string.Empty, true, nameof(BaseTheme.PrimaryTextColor)) => this.FillExpand().TextCenter(); + public InformationLabel() : base(string.Empty, true, nameof(BaseTheme.PrimaryTextColor)) + { + AutomationId = RepositoryPageAutomationIds.InformationLabel; + this.FillExpand().TextCenter(); + } } } } diff --git a/GitTrends/Views/Repository/InformationButton.cs b/GitTrends/Views/Repository/InformationButton.cs index 2bfa23b0d..570f999fb 100644 --- a/GitTrends/Views/Repository/InformationButton.cs +++ b/GitTrends/Views/Repository/InformationButton.cs @@ -20,25 +20,29 @@ class InformationButton : Grid const int _diameter = 100; readonly IMainThread _mainThread; + readonly IAnalyticsService _analyticsService; readonly FloatingActionTextButton _statistic1FloatingActionButton, _statistic2FloatingActionButton, _statistic3FloatingActionButton; - public InformationButton(MobileSortingService mobileSortingService, IMainThread mainThread) + public InformationButton(MobileSortingService mobileSortingService, in IMainThread mainThread, in IAnalyticsService analyticsService) { _mainThread = mainThread; + _analyticsService = analyticsService; + + AutomationId = RepositoryPageAutomationIds.InformationButton; RowDefinitions = Rows.Define(AbsoluteGridLength(_diameter)); ColumnDefinitions = Columns.Define(AbsoluteGridLength(_diameter)); Children.Add(new FloatingActionTextButton(mobileSortingService, FloatingActionButtonSize.Mini, FloatingActionButtonType.Statistic1).Assign(out _statistic1FloatingActionButton) - .Bind, string>(FloatingActionTextButton.TextProperty, nameof(RepositoryViewModel.VisibleRepositoryList), convert: repositories => GetLabelTextConverter(mobileSortingService, repositories, FloatingActionButtonType.Statistic1)) + .Bind, string>(FloatingActionTextButton.TextProperty, nameof(RepositoryViewModel.VisibleRepositoryList), convert: repositories => StatisticsService.GetFloatingActionTextButtonText(mobileSortingService, repositories, FloatingActionButtonType.Statistic1)) .Invoke(fab => fab.SetBinding(IsVisibleProperty, getIsVisibleBinding()))); Children.Add(new FloatingActionTextButton(mobileSortingService, FloatingActionButtonSize.Mini, FloatingActionButtonType.Statistic2).Assign(out _statistic2FloatingActionButton) - .Bind, string>(FloatingActionTextButton.TextProperty, nameof(RepositoryViewModel.VisibleRepositoryList), convert: repositories => GetLabelTextConverter(mobileSortingService, repositories, FloatingActionButtonType.Statistic2)) + .Bind, string>(FloatingActionTextButton.TextProperty, nameof(RepositoryViewModel.VisibleRepositoryList), convert: repositories => StatisticsService.GetFloatingActionTextButtonText(mobileSortingService, repositories, FloatingActionButtonType.Statistic2)) .Invoke(fab => fab.SetBinding(IsVisibleProperty, getIsVisibleBinding()))); Children.Add(new FloatingActionTextButton(mobileSortingService, FloatingActionButtonSize.Mini, FloatingActionButtonType.Statistic3).Assign(out _statistic3FloatingActionButton) - .Bind, string>(FloatingActionTextButton.TextProperty, nameof(RepositoryViewModel.VisibleRepositoryList), convert: repositories => GetLabelTextConverter(mobileSortingService, repositories, FloatingActionButtonType.Statistic3)) + .Bind, string>(FloatingActionTextButton.TextProperty, nameof(RepositoryViewModel.VisibleRepositoryList), convert: repositories => StatisticsService.GetFloatingActionTextButtonText(mobileSortingService, repositories, FloatingActionButtonType.Statistic3)) .Invoke(fab => fab.SetBinding(IsVisibleProperty, getIsVisibleBinding()))); Children.Add(new FloatingActionTextButton(mobileSortingService, FloatingActionButtonSize.Normal, FloatingActionButtonType.Information, new AsyncCommand(ExecuteFloatingActionButtonCommand)) { FontFamily = FontFamilyConstants.RobotoMedium, Text = "TOTAL" }.Center() @@ -56,38 +60,24 @@ public InformationButton(MobileSortingService mobileSortingService, IMainThread }; } - static string GetLabelTextConverter(in MobileSortingService mobileSortingService, in IReadOnlyList repositories, in FloatingActionButtonType floatingActionButtonType) - { - return (MobileSortingService.GetSortingCategory(mobileSortingService.CurrentOption), floatingActionButtonType) switch - { - (SortingCategory.Clones, FloatingActionButtonType.Statistic1) => repositories.Sum(x => x.TotalClones).ToAbbreviatedText(), - (SortingCategory.Clones, FloatingActionButtonType.Statistic2) => repositories.Sum(x => x.TotalUniqueClones).ToAbbreviatedText(), - (SortingCategory.Clones, FloatingActionButtonType.Statistic3) => repositories.Sum(x => x.StarCount).ToAbbreviatedText(), - (SortingCategory.Views, FloatingActionButtonType.Statistic1) => repositories.Sum(x => x.TotalViews).ToAbbreviatedText(), - (SortingCategory.Views, FloatingActionButtonType.Statistic2) => repositories.Sum(x => x.TotalUniqueViews).ToAbbreviatedText(), - (SortingCategory.Views, FloatingActionButtonType.Statistic3) => repositories.Sum(x => x.StarCount).ToAbbreviatedText(), - (SortingCategory.IssuesForks, FloatingActionButtonType.Statistic1) => repositories.Sum(x => x.StarCount).ToAbbreviatedText(), - (SortingCategory.IssuesForks, FloatingActionButtonType.Statistic2) => repositories.Sum(x => x.ForkCount).ToAbbreviatedText(), - (SortingCategory.IssuesForks, FloatingActionButtonType.Statistic3) => repositories.Sum(x => x.IssuesCount).ToAbbreviatedText(), - (_, FloatingActionButtonType.Information) => throw new NotSupportedException(), - (_, _) => throw new NotImplementedException() - }; - } - Task ExecuteFloatingActionButtonCommand() { const int animationDuration = 300; + const string informationButtonTapped = "Information Button Tapped"; return _mainThread.InvokeOnMainThreadAsync(() => { if (isVisible(_statistic1FloatingActionButton) && isVisible(_statistic2FloatingActionButton) && isVisible(_statistic3FloatingActionButton)) { + _analyticsService.Track(informationButtonTapped, nameof(isVisible), "true"); return Task.WhenAll(_statistic1FloatingActionButton.TranslateTo(0, 0, animationDuration, Easing.SpringIn), _statistic1FloatingActionButton.RotateTo(0, animationDuration, Easing.SpringIn), _statistic2FloatingActionButton.TranslateTo(0, 0, animationDuration, Easing.SpringIn), _statistic2FloatingActionButton.RotateTo(0, animationDuration, Easing.SpringIn), _statistic3FloatingActionButton.TranslateTo(0, 0, animationDuration, Easing.SpringIn), _statistic3FloatingActionButton.RotateTo(0, animationDuration, Easing.SpringIn)); } + _analyticsService.Track(informationButtonTapped, nameof(isVisible), "false"); + return Task.WhenAll(_statistic1FloatingActionButton.TranslateTo(-75, 10, animationDuration, Easing.SpringOut), _statistic1FloatingActionButton.RotateTo(360, animationDuration, Easing.SpringOut), _statistic2FloatingActionButton.TranslateTo(-50, -50, animationDuration, Easing.SpringOut), _statistic2FloatingActionButton.RotateTo(360, animationDuration, Easing.SpringOut), _statistic3FloatingActionButton.TranslateTo(10, -75, animationDuration, Easing.SpringOut), _statistic3FloatingActionButton.RotateTo(360, animationDuration, Easing.SpringOut)); @@ -96,8 +86,6 @@ Task ExecuteFloatingActionButtonCommand() static bool isVisible(in FloatingActionTextButton statisticButton) => statisticButton.TranslationX != 0 && statisticButton.TranslationY != 0; } - enum FloatingActionButtonType { Information, Statistic1, Statistic2, Statistic3 } - class InformationMultiValueConverter : IMultiValueConverter { public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) @@ -114,13 +102,16 @@ public object Convert(object[] values, Type targetType, object parameter, Cultur class FloatingActionTextButton : Grid { public static readonly BindableProperty TextProperty = BindableProperty.Create(nameof(Text), typeof(string), typeof(FloatingActionTextButton), string.Empty); - public static readonly BindableProperty FontFamilyPropety = BindableProperty.Create(nameof(FontFamily), typeof(string), typeof(FloatingActionTextButton), null); + public static readonly BindableProperty FontFamilyProperty = BindableProperty.Create(nameof(FontFamily), typeof(string), typeof(FloatingActionTextButton), null); readonly MobileSortingService _mobileSortingService; readonly FloatingActionButtonView _floatingActionButtonView; readonly FloatingActionButtonType _floatingActionButtonType; - public FloatingActionTextButton(MobileSortingService mobileSortingService, FloatingActionButtonSize floatingActionButtonSize, FloatingActionButtonType floatingActionButtonType, ICommand? command = null) + public FloatingActionTextButton(in MobileSortingService mobileSortingService, + in FloatingActionButtonSize floatingActionButtonSize, + in FloatingActionButtonType floatingActionButtonType, + in ICommand? command = null) { _mobileSortingService = mobileSortingService; _floatingActionButtonType = floatingActionButtonType; @@ -139,7 +130,7 @@ public FloatingActionTextButton(MobileSortingService mobileSortingService, Float Children.Add(new FloatingActionButtonView { Size = floatingActionButtonSize, Command = command }.Center().Assign(out _floatingActionButtonView) .Bind, Color>(FloatingActionButtonView.ColorNormalProperty, nameof(RepositoryViewModel.VisibleRepositoryList), convert: repositories => GetBackgroundColor())); - Children.Add(new Label { TextColor = Color.Black, InputTransparent = true }.Center().TextCenter().Font(fontSize) + Children.Add(new TextLabel(floatingActionButtonType).Center().TextCenter().Font(fontSize) .Bind(Label.TextProperty, nameof(Text), source: this) .Bind(Label.FontFamilyProperty, nameof(FontFamily), source: this)); } @@ -152,8 +143,8 @@ public string Text public string? FontFamily { - get => (string?)GetValue(FontFamilyPropety); - set => SetValue(FontFamilyPropety, value); + get => (string?)GetValue(FontFamilyProperty); + set => SetValue(FontFamilyProperty, value); } Color GetBackgroundColor() @@ -177,6 +168,16 @@ Color GetBackgroundColor() } void HandlePreferenceChanged(object sender, PreferredTheme e) => _floatingActionButtonView.ColorNormal = GetBackgroundColor(); + + class TextLabel : Label + { + public TextLabel(in FloatingActionButtonType floatingActionButtonType) + { + TextColor = Color.Black; + InputTransparent = true; + AutomationId = RepositoryPageAutomationIds.GetFloatingActionTextButtonLabelAutomationId(floatingActionButtonType); + } + } } } }