Add gps usage options
This commit is contained in:
		
							parent
							
								
									d75f48035f
								
							
						
					
					
						commit
						6a02eb31c9
					
				| @ -50,7 +50,7 @@ namespace eShopOnContainers | |||||||
|                 await InitNavigation(); |                 await InitNavigation(); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             if (!Settings.UseFakeLocation) |             if (Settings.GpsUsage && !Settings.UseFakeLocation) | ||||||
|             { |             { | ||||||
|                 await GetRealLocation(); |                 await GetRealLocation(); | ||||||
|             } |             } | ||||||
| @ -71,13 +71,17 @@ namespace eShopOnContainers | |||||||
|         private async Task GetRealLocation() |         private async Task GetRealLocation() | ||||||
|         { |         { | ||||||
|             var locator = CrossGeolocator.Current; |             var locator = CrossGeolocator.Current; | ||||||
|             locator.AllowsBackgroundUpdates = true; |  | ||||||
|             locator.DesiredAccuracy = 50; |  | ||||||
| 
 | 
 | ||||||
|             var position = await locator.GetPositionAsync(20000); |             if (locator.IsGeolocationEnabled && locator.IsGeolocationAvailable) | ||||||
|  |             {  | ||||||
|  |                 locator.AllowsBackgroundUpdates = true; | ||||||
|  |                 locator.DesiredAccuracy = 50; | ||||||
| 
 | 
 | ||||||
|             Settings.Latitude = position.Latitude; |                 var position = await locator.GetPositionAsync(20000); | ||||||
|             Settings.Longitude = position.Longitude; | 
 | ||||||
|  |                 Settings.Latitude = position.Latitude; | ||||||
|  |                 Settings.Longitude = position.Longitude; | ||||||
|  |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         private async Task SendCurrentLocation() |         private async Task SendCurrentLocation() | ||||||
|  | |||||||
| @ -28,10 +28,12 @@ namespace eShopOnContainers.Core.Helpers | |||||||
|         private const string IdUseFakeLocation = "use_fake_location"; |         private const string IdUseFakeLocation = "use_fake_location"; | ||||||
|         private const string IdLatitude = "latitude"; |         private const string IdLatitude = "latitude"; | ||||||
|         private const string IdLongitude = "flongitude"; |         private const string IdLongitude = "flongitude"; | ||||||
|  |         private const string IdGpsUsage = "gps_usage"; | ||||||
|         private static readonly string AccessTokenDefault = string.Empty; |         private static readonly string AccessTokenDefault = string.Empty; | ||||||
|         private static readonly string IdTokenDefault = string.Empty; |         private static readonly string IdTokenDefault = string.Empty; | ||||||
| 		private static readonly bool UseMocksDefault = true; | 		private static readonly bool UseMocksDefault = true; | ||||||
|         private static readonly bool UseFakeLocationDefault = false; |         private static readonly bool UseFakeLocationDefault = false; | ||||||
|  |         private static readonly bool GpsUsageValue = false; | ||||||
|         private static readonly double FakeLatitudeValue = 47.604610d; |         private static readonly double FakeLatitudeValue = 47.604610d; | ||||||
|         private static readonly double FakeLongitudeValue = -122.315752d; |         private static readonly double FakeLongitudeValue = -122.315752d; | ||||||
|         private static readonly string UrlBaseDefault = GlobalSetting.Instance.BaseEndpoint; |         private static readonly string UrlBaseDefault = GlobalSetting.Instance.BaseEndpoint; | ||||||
| @ -84,5 +86,11 @@ namespace eShopOnContainers.Core.Helpers | |||||||
|             get => AppSettings.GetValueOrDefault<double>(IdLongitude, FakeLongitudeValue); |             get => AppSettings.GetValueOrDefault<double>(IdLongitude, FakeLongitudeValue); | ||||||
|             set => AppSettings.AddOrUpdateValue<double>(IdLongitude, value); |             set => AppSettings.AddOrUpdateValue<double>(IdLongitude, value); | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|  |         public static bool GpsUsage | ||||||
|  |         { | ||||||
|  |             get => AppSettings.GetValueOrDefault<bool>(IdGpsUsage, GpsUsageValue); | ||||||
|  |             set => AppSettings.AddOrUpdateValue<bool>(IdGpsUsage, value); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @ -1,15 +1,14 @@ | |||||||
| using eShopOnContainers.Core.ViewModels.Base; | namespace eShopOnContainers.Core.ViewModels | ||||||
| using System.Windows.Input; |  | ||||||
| using Xamarin.Forms; |  | ||||||
| using System.Threading.Tasks; |  | ||||||
| using eShopOnContainers.Core.Helpers; |  | ||||||
| using eShopOnContainers.Core.Models.User; |  | ||||||
| using System; |  | ||||||
| using eShopOnContainers.Core.Models.Location; |  | ||||||
| using eShopOnContainers.Core.Services.Location; |  | ||||||
| 
 |  | ||||||
| namespace eShopOnContainers.Core.ViewModels |  | ||||||
| { | { | ||||||
|  |     using System.Windows.Input; | ||||||
|  |     using Xamarin.Forms; | ||||||
|  |     using System.Threading.Tasks; | ||||||
|  |     using Helpers; | ||||||
|  |     using Models.User; | ||||||
|  |     using Base; | ||||||
|  |     using Models.Location; | ||||||
|  |     using Services.Location; | ||||||
|  | 
 | ||||||
|     public class SettingsViewModel : ViewModelBase |     public class SettingsViewModel : ViewModelBase | ||||||
|     { |     { | ||||||
|         private string _titleUseAzureServices; |         private string _titleUseAzureServices; | ||||||
| @ -17,24 +16,31 @@ namespace eShopOnContainers.Core.ViewModels | |||||||
|         private bool _useAzureServices; |         private bool _useAzureServices; | ||||||
|         private string _titleUseFakeLocation; |         private string _titleUseFakeLocation; | ||||||
|         private string _descriptionUseFakeLocation; |         private string _descriptionUseFakeLocation; | ||||||
|  |         private bool _gpsUsage; | ||||||
|  |         private string _titleGpsUsage; | ||||||
|  |         private string _descriptionGpsUsage; | ||||||
|         private bool _useFakeLocation; |         private bool _useFakeLocation; | ||||||
|         private string _endpoint; |         private string _endpoint; | ||||||
|         private double _latitude; |         private double _latitude; | ||||||
|         private double _longitude; |         private double _longitude; | ||||||
|         private ILocationService _locationService; |          | ||||||
|  |         private readonly ILocationService _locationService; | ||||||
| 
 | 
 | ||||||
|         public SettingsViewModel(ILocationService locationService) |         public SettingsViewModel(ILocationService locationService) | ||||||
|         { |         { | ||||||
|             UseAzureServices = !Settings.UseMocks; |             _locationService = locationService; | ||||||
|             _useFakeLocation = Settings.UseFakeLocation; | 
 | ||||||
|  |             _useAzureServices = !Settings.UseMocks; | ||||||
|  |             _endpoint = Settings.UrlBase; | ||||||
|             _latitude = Settings.Latitude; |             _latitude = Settings.Latitude; | ||||||
|             _longitude = Settings.Longitude; |             _longitude = Settings.Longitude; | ||||||
|             _locationService = locationService; |             _useFakeLocation = Settings.UseFakeLocation; | ||||||
|  |             _gpsUsage = Settings.GpsUsage; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         public string TitleUseAzureServices |         public string TitleUseAzureServices | ||||||
|         { |         { | ||||||
|             get { return _titleUseAzureServices; } |             get => _titleUseAzureServices; | ||||||
|             set |             set | ||||||
|             { |             { | ||||||
|                 _titleUseAzureServices = value; |                 _titleUseAzureServices = value; | ||||||
| @ -44,7 +50,7 @@ namespace eShopOnContainers.Core.ViewModels | |||||||
| 
 | 
 | ||||||
|         public string DescriptionUseAzureServices |         public string DescriptionUseAzureServices | ||||||
|         { |         { | ||||||
|             get { return _descriptionUseAzureServices; } |             get => _descriptionUseAzureServices; | ||||||
|             set |             set | ||||||
|             { |             { | ||||||
|                 _descriptionUseAzureServices = value; |                 _descriptionUseAzureServices = value; | ||||||
| @ -54,20 +60,20 @@ namespace eShopOnContainers.Core.ViewModels | |||||||
| 
 | 
 | ||||||
|         public bool UseAzureServices |         public bool UseAzureServices | ||||||
|         { |         { | ||||||
|             get { return _useAzureServices; } |             get => _useAzureServices; | ||||||
|             set |             set | ||||||
|             { |             { | ||||||
|                 _useAzureServices = value; |                 _useAzureServices = value; | ||||||
| 
 | 
 | ||||||
|                 // Save use mocks services to local storage |                 UpdateUseAzureServices(); | ||||||
|                 Settings.UseMocks = !_useAzureServices; |                  | ||||||
|                 RaisePropertyChanged(() => UseAzureServices); |                 RaisePropertyChanged(() => UseAzureServices); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         public string TitleUseFakeLocation |         public string TitleUseFakeLocation | ||||||
|         { |         { | ||||||
|             get { return _titleUseFakeLocation; } |             get => _titleUseFakeLocation; | ||||||
|             set |             set | ||||||
|             { |             { | ||||||
|                 _titleUseFakeLocation = value; |                 _titleUseFakeLocation = value; | ||||||
| @ -77,7 +83,7 @@ namespace eShopOnContainers.Core.ViewModels | |||||||
| 
 | 
 | ||||||
|         public string DescriptionUseFakeLocation |         public string DescriptionUseFakeLocation | ||||||
|         { |         { | ||||||
|             get { return _descriptionUseFakeLocation; } |             get => _descriptionUseFakeLocation; | ||||||
|             set |             set | ||||||
|             { |             { | ||||||
|                 _descriptionUseFakeLocation = value; |                 _descriptionUseFakeLocation = value; | ||||||
| @ -87,27 +93,47 @@ namespace eShopOnContainers.Core.ViewModels | |||||||
| 
 | 
 | ||||||
|         public bool UseFakeLocation |         public bool UseFakeLocation | ||||||
|         { |         { | ||||||
|             get { return _useFakeLocation; } |             get => _useFakeLocation; | ||||||
|             set |             set | ||||||
|             { |             { | ||||||
|                 _useFakeLocation = value; |                 _useFakeLocation = value; | ||||||
| 
 | 
 | ||||||
|                 // Save use fake location services to local storage |                 UpdateFakeLocation(); | ||||||
|                 Settings.UseFakeLocation = _useFakeLocation; | 
 | ||||||
|                 RaisePropertyChanged(() => UseFakeLocation); |                 RaisePropertyChanged(() => UseFakeLocation); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         public string TitleGpsUsage | ||||||
|  |         { | ||||||
|  |             get => _titleGpsUsage; | ||||||
|  |             set | ||||||
|  |             { | ||||||
|  |                 _titleGpsUsage = value; | ||||||
|  |                 RaisePropertyChanged(() => TitleGpsUsage); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public string DescriptionGpsUsage | ||||||
|  |         { | ||||||
|  |             get => _descriptionGpsUsage; | ||||||
|  |             set | ||||||
|  |             { | ||||||
|  |                 _descriptionGpsUsage = value; | ||||||
|  |                 RaisePropertyChanged(() => DescriptionGpsUsage); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         public string Endpoint |         public string Endpoint | ||||||
|         { |         { | ||||||
|             get { return _endpoint; } |             get => _endpoint; | ||||||
|             set |             set | ||||||
|             { |             { | ||||||
|                 _endpoint = value; |                 _endpoint = value; | ||||||
| 
 | 
 | ||||||
|                 if(!string.IsNullOrEmpty(_endpoint)) |                 if(!string.IsNullOrEmpty(_endpoint)) | ||||||
|                 { |                 { | ||||||
|                     UpdateEndpoint(_endpoint); |                     UpdateEndpoint(); | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 RaisePropertyChanged(() => Endpoint); |                 RaisePropertyChanged(() => Endpoint); | ||||||
| @ -116,12 +142,12 @@ namespace eShopOnContainers.Core.ViewModels | |||||||
| 
 | 
 | ||||||
|         public double Latitude |         public double Latitude | ||||||
|         { |         { | ||||||
|             get { return _latitude; } |             get => _latitude; | ||||||
|             set |             set | ||||||
|             { |             { | ||||||
|                 _latitude = value; |                 _latitude = value; | ||||||
| 
 | 
 | ||||||
|                 UpdateLatitude(_latitude); |                 UpdateLatitude(); | ||||||
| 
 | 
 | ||||||
|                 RaisePropertyChanged(() => Latitude); |                 RaisePropertyChanged(() => Latitude); | ||||||
|             } |             } | ||||||
| @ -129,41 +155,53 @@ namespace eShopOnContainers.Core.ViewModels | |||||||
| 
 | 
 | ||||||
|         public double Longitude |         public double Longitude | ||||||
|         { |         { | ||||||
|             get { return _longitude; } |             get => _longitude; | ||||||
|             set |             set | ||||||
|             { |             { | ||||||
|                 _longitude = value; |                 _longitude = value; | ||||||
| 
 | 
 | ||||||
|                 UpdateLongitude(_longitude); |                 UpdateLongitude(); | ||||||
| 
 | 
 | ||||||
|                 RaisePropertyChanged(() => Longitude); |                 RaisePropertyChanged(() => Longitude); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         public bool GpsUsage | ||||||
|  |         { | ||||||
|  |             get => _gpsUsage; | ||||||
|  |             set | ||||||
|  |             { | ||||||
|  |                 _gpsUsage = value; | ||||||
|  | 
 | ||||||
|  |                 UpdateGpsUsage(); | ||||||
|  | 
 | ||||||
|  |                 RaisePropertyChanged(() => GpsUsage); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         public bool UserIsLogged => !string.IsNullOrEmpty(Settings.AuthAccessToken); |         public bool UserIsLogged => !string.IsNullOrEmpty(Settings.AuthAccessToken); | ||||||
| 
 | 
 | ||||||
|         public ICommand ToggleMockServicesCommand => new Command(async () => await ToggleMockServicesAsync()); |         public ICommand ToggleMockServicesCommand => new Command(async () => await ToggleMockServicesAsync()); | ||||||
| 
 | 
 | ||||||
|         public ICommand ToggleFakeLocationCommand => new Command(() => ToggleFakeLocationAsync()); |         public ICommand ToggleFakeLocationCommand => new Command(ToggleFakeLocationAsync); | ||||||
| 
 | 
 | ||||||
|         public ICommand ToggleSendLocationCommand => new Command(async () => await ToggleSendLocationAsync()); |         public ICommand ToggleSendLocationCommand => new Command(async () => await ToggleSendLocationAsync()); | ||||||
| 
 | 
 | ||||||
|  |         public ICommand ToggleGpsUsageCommand => new Command(ToggleGpsUsage); | ||||||
|  | 
 | ||||||
|         public override Task InitializeAsync(object navigationData) |         public override Task InitializeAsync(object navigationData) | ||||||
|         { |         { | ||||||
|             UpdateInfo(); |             UpdateInfoUseAzureServices(); | ||||||
|             UpdateInfoFakeLocation(); |             UpdateInfoFakeLocation(); | ||||||
|              |             UpdateInfoGpsUsage(); | ||||||
|             Endpoint = Settings.UrlBase; | 
 | ||||||
|             _latitude = Settings.Latitude; |  | ||||||
|             _longitude = Settings.Longitude; |  | ||||||
|             _useFakeLocation = Settings.UseFakeLocation; |  | ||||||
|             return base.InitializeAsync(navigationData); |             return base.InitializeAsync(navigationData); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| 		private async Task ToggleMockServicesAsync() | 		private async Task ToggleMockServicesAsync() | ||||||
| 		{ | 		{ | ||||||
| 			ViewModelLocator.RegisterDependencies(!UseAzureServices); | 			ViewModelLocator.RegisterDependencies(!UseAzureServices); | ||||||
| 			UpdateInfo(); | 			UpdateInfoUseAzureServices(); | ||||||
| 
 | 
 | ||||||
| 			var previousPageViewModel = NavigationService.PreviousPageViewModel; | 			var previousPageViewModel = NavigationService.PreviousPageViewModel; | ||||||
| 			if (previousPageViewModel != null) | 			if (previousPageViewModel != null) | ||||||
| @ -204,7 +242,12 @@ namespace eShopOnContainers.Core.ViewModels | |||||||
|             }  |             }  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         private void UpdateInfo() |         private void ToggleGpsUsage() | ||||||
|  |         { | ||||||
|  |             UpdateInfoGpsUsage(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private void UpdateInfoUseAzureServices() | ||||||
|         { |         { | ||||||
|             if (!UseAzureServices) |             if (!UseAzureServices) | ||||||
|             { |             { | ||||||
| @ -232,22 +275,53 @@ namespace eShopOnContainers.Core.ViewModels | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         private void UpdateEndpoint(string endpoint) |         private void UpdateInfoGpsUsage() | ||||||
|  |         { | ||||||
|  |             if (!GpsUsage) | ||||||
|  |             { | ||||||
|  |                 TitleGpsUsage = "Enable GPS"; | ||||||
|  |                 DescriptionGpsUsage = "When enabling the use of device gps you will get the location campaigns through your real location."; | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 TitleGpsUsage = "Disable GPS"; | ||||||
|  |                 DescriptionGpsUsage = "When disabling the use of device gps you won't get the location campaigns through your real location."; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         private void UpdateUseAzureServices() | ||||||
|  |         { | ||||||
|  |             // Save use mocks services to local storage | ||||||
|  |             Settings.UseMocks = !_useAzureServices; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private void UpdateEndpoint() | ||||||
|         { |         { | ||||||
|             // Update remote endpoint (save to local storage) |             // Update remote endpoint (save to local storage) | ||||||
|             Settings.UrlBase = endpoint; |             GlobalSetting.Instance.BaseEndpoint = Settings.UrlBase = _endpoint; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         private void UpdateLatitude(double latitude) |         private void UpdateFakeLocation() | ||||||
|  |         { | ||||||
|  |             Settings.UseFakeLocation = _useFakeLocation; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private void UpdateLatitude() | ||||||
|         { |         { | ||||||
|             // Update fake latitude (save to local storage) |             // Update fake latitude (save to local storage) | ||||||
|             Settings.Latitude = latitude; |             Settings.Latitude = _latitude; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         private void UpdateLongitude(double longitude) |         private void UpdateLongitude() | ||||||
|         { |         { | ||||||
|             // Update fake longitude (save to local storage) |             // Update fake longitude (save to local storage) | ||||||
|             Settings.Longitude = longitude; |             Settings.Longitude = _longitude; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private void UpdateGpsUsage() | ||||||
|  |         { | ||||||
|  |             Settings.GpsUsage = _gpsUsage; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @ -100,6 +100,9 @@ | |||||||
|                         <RowDefinition Height="1" /> |                         <RowDefinition Height="1" /> | ||||||
|                         <RowDefinition Height="Auto" /> |                         <RowDefinition Height="Auto" /> | ||||||
|                         <RowDefinition Height="Auto" /> |                         <RowDefinition Height="Auto" /> | ||||||
|  |                         <RowDefinition Height="Auto" /> | ||||||
|  |                         <RowDefinition Height="Auto" /> | ||||||
|  |                         <RowDefinition Height="Auto" /> | ||||||
|                     </Grid.RowDefinitions> |                     </Grid.RowDefinitions> | ||||||
|                     <Grid  |                     <Grid  | ||||||
|                         Grid.Row="0" |                         Grid.Row="0" | ||||||
| @ -236,7 +239,52 @@ | |||||||
|                             Command="{Binding ToggleSendLocationCommand}" |                             Command="{Binding ToggleSendLocationCommand}" | ||||||
|                             Text="Send Location"/> |                             Text="Send Location"/> | ||||||
|                     </StackLayout> |                     </StackLayout> | ||||||
|                      |                     <!-- GPS USAGE --> | ||||||
|  |                     <StackLayout | ||||||
|  |                         Grid.Row="5" | ||||||
|  |                         Grid.Column="0" | ||||||
|  |                         Grid.ColumnSpan="2" | ||||||
|  |                         Margin="12, 0, 12, 12" | ||||||
|  |                         IsVisible="{Binding UseFakeLocation, Converter={StaticResource InverseBoolConverter}}"> | ||||||
|  |                     </StackLayout> | ||||||
|  |                     <Grid  | ||||||
|  |                         Grid.Row="6" | ||||||
|  |                         Grid.Column="0" | ||||||
|  |                         Grid.ColumnSpan="2"/> | ||||||
|  |                     <StackLayout  | ||||||
|  |                         Grid.Column="0"                        | ||||||
|  |                         Grid.Row="7" | ||||||
|  |                         IsVisible="{Binding UseFakeLocation, Converter={StaticResource InverseBoolConverter}}"> | ||||||
|  |                         <Label  | ||||||
|  |                             Text="{Binding TitleGpsUsage}" | ||||||
|  |                             TextColor="{StaticResource GreenColor}" | ||||||
|  |                             Style="{StaticResource SettingsTitleStyle}"/> | ||||||
|  |                         <Label | ||||||
|  |                             Text="{Binding DescriptionGpsUsage}" | ||||||
|  |                             Style="{StaticResource SettingsDescriptionStyle}"/> | ||||||
|  |                     </StackLayout> | ||||||
|  |                     <!-- ON / OFF --> | ||||||
|  |                     <controls:ToggleButton  | ||||||
|  |                         Grid.Column="1"  | ||||||
|  |                         Grid.Row="7"  | ||||||
|  |                         Animate="True"      | ||||||
|  |                         Checked="{Binding GpsUsage, Mode=TwoWay}" | ||||||
|  |                         Command="{Binding ToggleGpsUsageCommand}" | ||||||
|  |                         Style="{StaticResource SettingsToggleButtonStyle}" | ||||||
|  |                         IsVisible="{Binding UseFakeLocation, Converter={StaticResource InverseBoolConverter}}"> | ||||||
|  |                         <controls:ToggleButton.CheckedImage> | ||||||
|  |                             <OnPlatform x:TypeArguments="ImageSource" | ||||||
|  |                                         Android="switch_on.png" | ||||||
|  |                                         iOS="switchOn.png" | ||||||
|  |                                         WinPhone="Assets/switchOn.png"/> | ||||||
|  |                         </controls:ToggleButton.CheckedImage> | ||||||
|  |                         <controls:ToggleButton.UnCheckedImage> | ||||||
|  |                             <OnPlatform x:TypeArguments="ImageSource" | ||||||
|  |                                         Android="switch_off.png" | ||||||
|  |                                         iOS="switchOff.png" | ||||||
|  |                                         WinPhone="Assets/switchOff.png"/> | ||||||
|  |                         </controls:ToggleButton.UnCheckedImage> | ||||||
|  |                     </controls:ToggleButton> | ||||||
|                 </Grid> |                 </Grid> | ||||||
|             </StackLayout> |             </StackLayout> | ||||||
|         </ScrollView> |         </ScrollView> | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user