diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/GlobalSettings.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/GlobalSettings.cs index a75ee7058..b62bb7ba3 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/GlobalSettings.cs +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/GlobalSettings.cs @@ -43,6 +43,8 @@ public string IdentityEndpoint { get; set; } + public string LocationEndpoint { get; set; } + public string UserInfoEndpoint { get; set; } public string LogoutEndpoint { get; set; } @@ -62,6 +64,7 @@ LogoutEndpoint = string.Format("{0}:5105/connect/endsession", baseEndpoint); IdentityCallback = string.Format("{0}:5105/xamarincallback", baseEndpoint); LogoutCallback = string.Format("{0}:5105/Account/Redirecting", baseEndpoint); + LocationEndpoint = string.Format("{0}:5109", baseEndpoint); } } } \ No newline at end of file diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Helpers/Settings.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Helpers/Settings.cs index 24da4fd2b..51b1efe30 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Helpers/Settings.cs +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Helpers/Settings.cs @@ -24,9 +24,13 @@ namespace eShopOnContainers.Core.Helpers private const string IdToken = "id_token"; private const string IdUseMocks = "use_mocks"; private const string IdUrlBase = "url_base"; + private const string IdUseFakeLocation = "use_fake_location"; + private const string IdFakeLatitude = "fake_latitude"; + private const string IdFakeLongitude = "fake_longitude"; private static readonly string AccessTokenDefault = string.Empty; private static readonly string IdTokenDefault = string.Empty; private static readonly bool UseMocksDefault = true; + private static readonly bool UseFakeLocationDefault = false; private static readonly string UrlBaseDefault = GlobalSetting.Instance.BaseEndpoint; #endregion @@ -78,5 +82,40 @@ namespace eShopOnContainers.Core.Helpers AppSettings.AddOrUpdateValue(IdUrlBase, value); } } + + public static bool UseFakeLocation + { + get + { + return AppSettings.GetValueOrDefault(IdUseFakeLocation, UseFakeLocationDefault); + } + set + { + AppSettings.AddOrUpdateValue(IdUseFakeLocation, value); + } + } + + public static double FakeLatitude + { + get + { + return AppSettings.GetValueOrDefault(IdFakeLatitude); + } + set + { + AppSettings.AddOrUpdateValue(IdFakeLatitude, value); + } + } + public static double FakeLongitude + { + get + { + return AppSettings.GetValueOrDefault(IdFakeLongitude); + } + set + { + AppSettings.AddOrUpdateValue(IdFakeLongitude, value); + } + } } } \ No newline at end of file diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Models/Location/LocationRequest.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Models/Location/LocationRequest.cs new file mode 100644 index 000000000..99654914c --- /dev/null +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Models/Location/LocationRequest.cs @@ -0,0 +1,8 @@ +namespace eShopOnContainers.Core.Models.Location +{ + public class LocationRequest + { + public double Longitude { get; set; } + public double Latitude { get; set; } + } +} diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Location/ILocationService.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Location/ILocationService.cs new file mode 100644 index 000000000..bc2c59915 --- /dev/null +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Location/ILocationService.cs @@ -0,0 +1,10 @@ +namespace eShopOnContainers.Core.Services.Location +{ + using System.Threading.Tasks; + using eShopOnContainers.Core.Models.Location; + + public interface ILocationService + { + Task UpdateUserLocation(LocationRequest newLocReq); + } +} \ No newline at end of file diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Location/LocationService.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Location/LocationService.cs new file mode 100644 index 000000000..2149a5118 --- /dev/null +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Location/LocationService.cs @@ -0,0 +1,28 @@ +namespace eShopOnContainers.Core.Services.Location +{ + using eShopOnContainers.Core.Models.Location; + using eShopOnContainers.Core.Services.RequestProvider; + using System; + using System.Threading.Tasks; + + public class LocationService : ILocationService + { + private readonly IRequestProvider _requestProvider; + + public LocationService(IRequestProvider requestProvider) + { + _requestProvider = requestProvider; + } + + public async Task UpdateUserLocation(LocationRequest newLocReq) + { + UriBuilder builder = new UriBuilder(GlobalSetting.Instance.LocationEndpoint); + + builder.Path = "api/v1/locations"; + + string uri = builder.ToString(); + + var result = await _requestProvider.PostAsync(uri, newLocReq); + } + } +} diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/Base/ViewModelLocator.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/Base/ViewModelLocator.cs index 90abb8f09..3eda91b42 100755 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/Base/ViewModelLocator.cs +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/Base/ViewModelLocator.cs @@ -11,6 +11,7 @@ using eShopOnContainers.Core.Services.Identity; using eShopOnContainers.Core.Services.Order; using eShopOnContainers.Core.Services.User; using Xamarin.Forms; +using eShopOnContainers.Core.Services.Location; namespace eShopOnContainers.Core.ViewModels.Base { @@ -53,24 +54,25 @@ namespace eShopOnContainers.Core.ViewModels.Base builder.RegisterType().As(); builder.RegisterType().As(); builder.RegisterType().As(); + builder.RegisterType().As().SingleInstance(); - if (useMockServices) + if (useMockServices) { builder.RegisterInstance(new CatalogMockService()).As(); builder.RegisterInstance(new BasketMockService()).As(); builder.RegisterInstance(new OrderMockService()).As(); builder.RegisterInstance(new UserMockService()).As(); - UseMockService = true; + UseMockService = true; } else { builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); - builder.RegisterType().As().SingleInstance(); + builder.RegisterType().As().SingleInstance(); - UseMockService = false; + UseMockService = false; } if (_container != null) diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/SettingsViewModel.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/SettingsViewModel.cs index 4596eb25c..8bfe9ed25 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/SettingsViewModel.cs +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/SettingsViewModel.cs @@ -4,38 +4,51 @@ 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 { public class SettingsViewModel : ViewModelBase { - private string _title; - private string _description; + private string _titleUseAzureServices; + private string _descriptionUseAzureServices; private bool _useAzureServices; + private string _titleUseFakeLocation; + private string _descriptionUseFakeLocation; + private bool _useFakeLocation; private string _endpoint; + private double _latitude; + private double _longitude; + private ILocationService _locationService; - public SettingsViewModel() + public SettingsViewModel(ILocationService locationService) { UseAzureServices = !Settings.UseMocks; + _useFakeLocation = Settings.UseFakeLocation; + _latitude = Settings.FakeLatitude; + _longitude = Settings.FakeLongitude; + _locationService = locationService; } - public string Title + public string TitleUseAzureServices { - get { return _title; } + get { return _titleUseAzureServices; } set { - _title = value; - RaisePropertyChanged(() => Title); + _titleUseAzureServices = value; + RaisePropertyChanged(() => TitleUseAzureServices); } } - public string Description + public string DescriptionUseAzureServices { - get { return _description; } + get { return _descriptionUseAzureServices; } set { - _description = value; - RaisePropertyChanged(() => Description); + _descriptionUseAzureServices = value; + RaisePropertyChanged(() => DescriptionUseAzureServices); } } @@ -52,6 +65,39 @@ namespace eShopOnContainers.Core.ViewModels } } + public string TitleUseFakeLocation + { + get { return _titleUseFakeLocation; } + set + { + _titleUseFakeLocation = value; + RaisePropertyChanged(() => TitleUseFakeLocation); + } + } + + public string DescriptionUseFakeLocation + { + get { return _descriptionUseFakeLocation; } + set + { + _descriptionUseFakeLocation = value; + RaisePropertyChanged(() => DescriptionUseFakeLocation); + } + } + + public bool UseFakeLocation + { + get { return _useFakeLocation; } + set + { + _useFakeLocation = value; + + // Save use fake location services to local storage + Settings.UseFakeLocation = _useFakeLocation; + RaisePropertyChanged(() => UseFakeLocation); + } + } + public string Endpoint { get { return _endpoint; } @@ -68,12 +114,47 @@ namespace eShopOnContainers.Core.ViewModels } } + public double Latitude + { + get { return _latitude; } + set + { + _latitude = value; + + UpdateLatitude(_latitude); + + RaisePropertyChanged(() => Latitude); + } + } + + public double Longitude + { + get { return _longitude; } + set + { + _longitude = value; + + UpdateLongitude(_longitude); + + RaisePropertyChanged(() => Longitude); + } + } + public ICommand ToggleMockServicesCommand => new Command(async () => await ToggleMockServicesAsync()); + public ICommand ToggleFakeLocationCommand => new Command(() => ToggleFakeLocationAsync()); + + public ICommand ToggleSendLocationCommand => new Command(async () => await ToggleSendLocationAsync()); + public override Task InitializeAsync(object navigationData) { UpdateInfo(); + UpdateInfoFakeLocation(); + Endpoint = Settings.UrlBase; + _latitude = Settings.FakeLatitude; + _longitude = Settings.FakeLongitude; + _useFakeLocation = Settings.UseFakeLocation; return base.InitializeAsync(navigationData); } @@ -100,17 +181,48 @@ namespace eShopOnContainers.Core.ViewModels } } - private void UpdateInfo() + private void ToggleFakeLocationAsync() + { + ViewModelLocator.RegisterDependencies(!UseAzureServices); + UpdateInfoFakeLocation(); + } + + private async Task ToggleSendLocationAsync() + { + LocationRequest locationRequest = new LocationRequest + { + Latitude = _latitude, + Longitude = _longitude + }; + + await _locationService.UpdateUserLocation(locationRequest); + } + + private void UpdateInfo() { if (!UseAzureServices) { - Title = "Use Mock Services"; - Description = "Mock Services are simulated objects that mimic the behavior of real services using a controlled approach."; + TitleUseAzureServices = "Use Mock Services"; + DescriptionUseAzureServices = "Mock Services are simulated objects that mimic the behavior of real services using a controlled approach."; } else { - Title = "Use Microservices/Containers from eShopOnContainers"; - Description = "When enabling the use of microservices/containers, the app will attempt to use real services deployed as Docker containers at the specified base endpoint, which will must be reachable through the network."; + TitleUseAzureServices = "Use Microservices/Containers from eShopOnContainers"; + DescriptionUseAzureServices = "When enabling the use of microservices/containers, the app will attempt to use real services deployed as Docker containers at the specified base endpoint, which will must be reachable through the network."; + } + } + + private void UpdateInfoFakeLocation() + { + if (!UseFakeLocation) + { + TitleUseFakeLocation = "Use Fake Location"; + DescriptionUseFakeLocation = "Fake Location are added for marketing campaign testing."; + } + else + { + TitleUseFakeLocation = "Use Real Location"; + DescriptionUseFakeLocation = "When enabling the use of real location, the app will attempt to use real location from the device."; } } @@ -119,5 +231,17 @@ namespace eShopOnContainers.Core.ViewModels // Update remote endpoint (save to local storage) Settings.UrlBase = endpoint; } + + private void UpdateLatitude(double latitude) + { + // Update fake latitude (save to local storage) + Settings.FakeLatitude = latitude; + } + + private void UpdateLongitude(double longitude) + { + // Update fake longitude (save to local storage) + Settings.FakeLongitude = longitude; + } } } \ No newline at end of file diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/SettingsView.xaml b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/SettingsView.xaml index 7db37dd66..a8da35daa 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/SettingsView.xaml +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/SettingsView.xaml @@ -108,11 +108,11 @@ Grid.Column="0" Grid.Row="1">