Browse Source

Work in progress.

pull/469/head
David Britch 7 years ago
parent
commit
e358099bcc
36 changed files with 585 additions and 545 deletions
  1. +14
    -14
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/App.xaml.cs
  2. +6
    -8
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Basket/BasketService.cs
  3. +11
    -22
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Catalog/CatalogService.cs
  4. +10
    -0
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Dependency/DependencyService.cs
  5. +7
    -0
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Dependency/IDependencyService.cs
  6. +20
    -12
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/FixUri/FixUriService.cs
  7. +14
    -0
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/FixUri/IFixUriService.cs
  8. +6
    -11
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Marketing/CampaignService.cs
  9. +39
    -31
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Navigation/NavigationService.cs
  10. +14
    -0
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Settings/ISettingsService.cs
  11. +15
    -0
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Settings/ISettingsServiceImplementation.cs
  12. +28
    -30
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Settings/SettingsService.cs
  13. +2
    -1
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/Base/ViewModelBase.cs
  14. +93
    -87
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/Base/ViewModelLocator.cs
  15. +9
    -9
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/BasketViewModel.cs
  16. +9
    -8
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/CampaignDetailsViewModel.cs
  17. +7
    -6
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/CampaignViewModel.cs
  18. +13
    -10
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/CheckoutViewModel.cs
  19. +27
    -24
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/LoginViewModel.cs
  20. +9
    -6
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/OrderDetailViewModel.cs
  21. +6
    -5
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/ProfileViewModel.cs
  22. +53
    -52
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/SettingsViewModel.cs
  23. +5
    -1
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/eShopOnContainers.Core.csproj
  24. +0
    -44
      src/Mobile/eShopOnContainers/eShopOnContainers.Droid/Helpers/Settings.cs
  25. +0
    -7
      src/Mobile/eShopOnContainers/eShopOnContainers.Droid/eShopOnContainers.Droid.csproj
  26. +0
    -1
      src/Mobile/eShopOnContainers/eShopOnContainers.Droid/packages.config
  27. +0
    -44
      src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.Droid/Helpers/Settings.cs
  28. +0
    -7
      src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.Droid/eShopOnContainers.TestRunner.Droid.csproj
  29. +0
    -1
      src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.Droid/packages.config
  30. +0
    -44
      src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.iOS/Helpers/Settings.cs
  31. +0
    -7
      src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.iOS/eShopOnContainers.TestRunner.iOS.csproj
  32. +0
    -1
      src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.iOS/packages.config
  33. +0
    -44
      src/Mobile/eShopOnContainers/eShopOnContainers.iOS/Helpers/Settings.cs
  34. +164
    -0
      src/Mobile/eShopOnContainers/eShopOnContainers.iOS/Services/SettingsServiceImplementation.cs
  35. +4
    -7
      src/Mobile/eShopOnContainers/eShopOnContainers.iOS/eShopOnContainers.iOS.csproj
  36. +0
    -1
      src/Mobile/eShopOnContainers/eShopOnContainers.iOS/packages.config

+ 14
- 14
src/Mobile/eShopOnContainers/eShopOnContainers.Core/App.xaml.cs View File

@ -1,5 +1,4 @@
using System.Globalization;
using eShopOnContainers.Core.Helpers;
using eShopOnContainers.Services;
using eShopOnContainers.Core.ViewModels.Base;
using System.Threading.Tasks;
@ -8,20 +7,21 @@ using eShopOnContainers.Core.Services.Location;
using Plugin.Geolocator;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using eShopOnContainers.Core.Services.Settings;
[assembly: XamlCompilation(XamlCompilationOptions.Compile)]
namespace eShopOnContainers
{
public partial class App : Application
{
public bool UseMockServices { get; set; }
ISettingsService _settingsService;
bool _useMockServices;
public App()
{
InitializeComponent();
InitApp();
if (Device.RuntimePlatform == Device.UWP)
{
InitNavigation();
@ -30,8 +30,9 @@ namespace eShopOnContainers
private void InitApp()
{
UseMockServices = Settings.UseMocks;
ViewModelLocator.RegisterDependencies(UseMockServices);
_useMockServices = true;//_settingsService.UseMocks;
ViewModelLocator.RegisterDependencies(_useMockServices);
_settingsService = ViewModelLocator.Resolve<ISettingsService>();
}
private Task InitNavigation()
@ -49,12 +50,12 @@ namespace eShopOnContainers
await InitNavigation();
}
if (Settings.AllowGpsLocation && !Settings.UseFakeLocation)
if (_settingsService.AllowGpsLocation && !_settingsService.UseFakeLocation)
{
await GetGpsLocation();
}
if (!Settings.UseMocks && !string.IsNullOrEmpty(Settings.AuthAccessToken))
if (!_settingsService.UseMocks && !string.IsNullOrEmpty(_settingsService.AuthAccessToken))
{
await SendCurrentLocation();
}
@ -78,12 +79,12 @@ namespace eShopOnContainers
var position = await locator.GetPositionAsync();
Settings.Latitude = position.Latitude.ToString();
Settings.Longitude = position.Longitude.ToString();
_settingsService.Latitude = position.Latitude.ToString();
_settingsService.Longitude = position.Longitude.ToString();
}
else
{
Settings.AllowGpsLocation = false;
_settingsService.AllowGpsLocation = false;
}
}
@ -91,13 +92,12 @@ namespace eShopOnContainers
{
var location = new Location
{
Latitude = double.Parse(Settings.Latitude, CultureInfo.InvariantCulture),
Longitude = double.Parse(Settings.Longitude, CultureInfo.InvariantCulture)
Latitude = double.Parse(_settingsService.Latitude, CultureInfo.InvariantCulture),
Longitude = double.Parse(_settingsService.Longitude, CultureInfo.InvariantCulture)
};
var locationService = ViewModelLocator.Resolve<ILocationService>();
await locationService.UpdateUserLocation(location,
Settings.AuthAccessToken);
await locationService.UpdateUserLocation(location, _settingsService.AuthAccessToken);
}
}
}

+ 6
- 8
src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Basket/BasketService.cs View File

@ -2,18 +2,21 @@
using System.Threading.Tasks;
using eShopOnContainers.Core.Services.RequestProvider;
using eShopOnContainers.Core.Models.Basket;
using eShopOnContainers.Core.Helpers;
using eShopOnContainers.Core.Services.FixUri;
namespace eShopOnContainers.Core.Services.Basket
{
public class BasketService : IBasketService
{
private readonly IRequestProvider _requestProvider;
private readonly IFixUriService _fixUriService;
private const string ApiUrlBase = "api/v1/basket";
public BasketService(IRequestProvider requestProvider)
public BasketService(IRequestProvider requestProvider, IFixUriService fixUriService)
{
_requestProvider = requestProvider;
_fixUriService = fixUriService;
}
public async Task<CustomerBasket> GetBasketAsync(string guidUser, string token)
@ -28,8 +31,7 @@ namespace eShopOnContainers.Core.Services.Basket
CustomerBasket basket =
await _requestProvider.GetAsync<CustomerBasket>(uri, token);
ServicesHelper.FixBasketItemPictureUri(basket?.Items);
_fixUriService.FixBasketItemPictureUri(basket?.Items);
return basket;
}
@ -41,9 +43,7 @@ namespace eShopOnContainers.Core.Services.Basket
};
var uri = builder.ToString();
var result = await _requestProvider.PostAsync(uri, customerBasket, token);
return result;
}
@ -55,7 +55,6 @@ namespace eShopOnContainers.Core.Services.Basket
};
var uri = builder.ToString();
await _requestProvider.PostAsync(uri, basketCheckout, token);
}
@ -67,7 +66,6 @@ namespace eShopOnContainers.Core.Services.Basket
};
var uri = builder.ToString();
await _requestProvider.DeleteAsync(uri, token);
}
}

+ 11
- 22
src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Catalog/CatalogService.cs View File

@ -5,29 +5,28 @@ using eShopOnContainers.Core.Models.Catalog;
using eShopOnContainers.Core.Services.RequestProvider;
using eShopOnContainers.Core.Extensions;
using System.Collections.Generic;
using eShopOnContainers.Core.Helpers;
using eShopOnContainers.Core.Services.FixUri;
namespace eShopOnContainers.Core.Services.Catalog
{
public class CatalogService : ICatalogService
{
private readonly IRequestProvider _requestProvider;
private readonly IFixUriService _fixUriService;
public CatalogService(IRequestProvider requestProvider)
public CatalogService(IRequestProvider requestProvider, IFixUriService fixUriService)
{
_requestProvider = requestProvider;
_fixUriService = fixUriService;
}
public async Task<ObservableCollection<CatalogItem>> FilterAsync(int catalogBrandId, int catalogTypeId)
{
UriBuilder builder = new UriBuilder(GlobalSetting.Instance.CatalogEndpoint);
builder.Path = string.Format("api/v1/catalog/items/type/{0}/brand/{1}", catalogTypeId, catalogBrandId);
string uri = builder.ToString();
CatalogRoot catalog =
await _requestProvider.GetAsync<CatalogRoot>(uri);
CatalogRoot catalog = await _requestProvider.GetAsync<CatalogRoot>(uri);
if (catalog?.Data != null)
return catalog?.Data.ToObservableCollection();
@ -38,34 +37,27 @@ namespace eShopOnContainers.Core.Services.Catalog
public async Task<ObservableCollection<CatalogItem>> GetCatalogAsync()
{
UriBuilder builder = new UriBuilder(GlobalSetting.Instance.CatalogEndpoint);
builder.Path = "api/v1/catalog/items";
string uri = builder.ToString();
CatalogRoot catalog =
await _requestProvider.GetAsync<CatalogRoot>(uri);
CatalogRoot catalog = await _requestProvider.GetAsync<CatalogRoot>(uri);
if (catalog?.Data != null)
{
ServicesHelper.FixCatalogItemPictureUri(catalog?.Data);
_fixUriService.FixCatalogItemPictureUri(catalog?.Data);
return catalog?.Data.ToObservableCollection();
}
else
return new ObservableCollection<CatalogItem>();
return new ObservableCollection<CatalogItem>();
}
public async Task<ObservableCollection<CatalogBrand>> GetCatalogBrandAsync()
{
UriBuilder builder = new UriBuilder(GlobalSetting.Instance.CatalogEndpoint);
builder.Path = "api/v1/catalog/catalogbrands";
string uri = builder.ToString();
IEnumerable<CatalogBrand> brands =
await _requestProvider.GetAsync<IEnumerable<CatalogBrand>>(uri);
IEnumerable<CatalogBrand> brands = await _requestProvider.GetAsync<IEnumerable<CatalogBrand>>(uri);
if (brands != null)
return brands?.ToObservableCollection();
@ -76,18 +68,15 @@ namespace eShopOnContainers.Core.Services.Catalog
public async Task<ObservableCollection<CatalogType>> GetCatalogTypeAsync()
{
UriBuilder builder = new UriBuilder(GlobalSetting.Instance.CatalogEndpoint);
builder.Path = "api/v1/catalog/catalogtypes";
string uri = builder.ToString();
IEnumerable<CatalogType> types =
await _requestProvider.GetAsync<IEnumerable<CatalogType>>(uri);
IEnumerable<CatalogType> types = await _requestProvider.GetAsync<IEnumerable<CatalogType>>(uri);
if (types != null)
return types.ToObservableCollection();
else
return new ObservableCollection<CatalogType>();
return new ObservableCollection<CatalogType>();
}
}
}

+ 10
- 0
src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Dependency/DependencyService.cs View File

@ -0,0 +1,10 @@
namespace eShopOnContainers.Core.Services.Dependency
{
public class DependencyService : IDependencyService
{
public T Get<T>() where T : class
{
return Xamarin.Forms.DependencyService.Get<T>();
}
}
}

+ 7
- 0
src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Dependency/IDependencyService.cs View File

@ -0,0 +1,7 @@
namespace eShopOnContainers.Core.Services.Dependency
{
public interface IDependencyService
{
T Get<T>() where T : class;
}
}

src/Mobile/eShopOnContainers/eShopOnContainers.Core/Helpers/ServicesHelper.cs → src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/FixUri/FixUriService.cs View File

@ -6,14 +6,22 @@ using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text.RegularExpressions;
using eShopOnContainers.Core.Services.Settings;
namespace eShopOnContainers.Core.Helpers
namespace eShopOnContainers.Core.Services.FixUri
{
public static class ServicesHelper
public class FixUriService : IFixUriService
{
private static Regex IpRegex = new Regex(@"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b");
private readonly ISettingsService _settingsService;
public static void FixCatalogItemPictureUri(IEnumerable<CatalogItem> catalogItems)
private Regex IpRegex = new Regex(@"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b");
public FixUriService(ISettingsService settingsService)
{
_settingsService = settingsService;
}
public void FixCatalogItemPictureUri(IEnumerable<CatalogItem> catalogItems)
{
if (catalogItems == null)
{
@ -23,12 +31,12 @@ namespace eShopOnContainers.Core.Helpers
try
{
if (!ViewModelLocator.UseMockService
&& Settings.UrlBase != GlobalSetting.DefaultEndpoint)
&& _settingsService.UrlBase != GlobalSetting.DefaultEndpoint)
{
foreach (var catalogItem in catalogItems)
{
MatchCollection serverResult = IpRegex.Matches(catalogItem.PictureUri);
MatchCollection localResult = IpRegex.Matches(Settings.UrlBase);
MatchCollection localResult = IpRegex.Matches(_settingsService.UrlBase);
if (serverResult.Count != -1 && localResult.Count != -1)
{
@ -46,7 +54,7 @@ namespace eShopOnContainers.Core.Helpers
}
}
public static void FixBasketItemPictureUri(IEnumerable<BasketItem> basketItems)
public void FixBasketItemPictureUri(IEnumerable<BasketItem> basketItems)
{
if (basketItems == null)
{
@ -56,12 +64,12 @@ namespace eShopOnContainers.Core.Helpers
try
{
if (!ViewModelLocator.UseMockService
&& Settings.UrlBase != GlobalSetting.DefaultEndpoint)
&& _settingsService.UrlBase != GlobalSetting.DefaultEndpoint)
{
foreach (var basketItem in basketItems)
{
MatchCollection serverResult = IpRegex.Matches(basketItem.PictureUrl);
MatchCollection localResult = IpRegex.Matches(Settings.UrlBase);
MatchCollection localResult = IpRegex.Matches(_settingsService.UrlBase);
if (serverResult.Count != -1 && localResult.Count != -1)
{
@ -78,7 +86,7 @@ namespace eShopOnContainers.Core.Helpers
}
}
public static void FixCampaignItemPictureUri(IEnumerable<CampaignItem> campaignItems)
public void FixCampaignItemPictureUri(IEnumerable<CampaignItem> campaignItems)
{
if (campaignItems == null)
{
@ -88,12 +96,12 @@ namespace eShopOnContainers.Core.Helpers
try
{
if (!ViewModelLocator.UseMockService
&& Settings.UrlBase != GlobalSetting.DefaultEndpoint)
&& _settingsService.UrlBase != GlobalSetting.DefaultEndpoint)
{
foreach (var campaignItem in campaignItems)
{
MatchCollection serverResult = IpRegex.Matches(campaignItem.PictureUri);
MatchCollection localResult = IpRegex.Matches(Settings.UrlBase);
MatchCollection localResult = IpRegex.Matches(_settingsService.UrlBase);
if (serverResult.Count != -1 && localResult.Count != -1)
{

+ 14
- 0
src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/FixUri/IFixUriService.cs View File

@ -0,0 +1,14 @@
using System.Collections.Generic;
using eShopOnContainers.Core.Models.Basket;
using eShopOnContainers.Core.Models.Catalog;
using eShopOnContainers.Core.Models.Marketing;
namespace eShopOnContainers.Core.Services.FixUri
{
public interface IFixUriService
{
void FixCatalogItemPictureUri(IEnumerable<CatalogItem> catalogItems);
void FixBasketItemPictureUri(IEnumerable<BasketItem> basketItems);
void FixCampaignItemPictureUri(IEnumerable<CampaignItem> campaignItems);
}
}

+ 6
- 11
src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Marketing/CampaignService.cs View File

@ -4,34 +4,32 @@ using System.Threading.Tasks;
using eShopOnContainers.Core.Models.Marketing;
using eShopOnContainers.Core.Services.RequestProvider;
using eShopOnContainers.Core.Extensions;
using eShopOnContainers.Core.Helpers;
using eShopOnContainers.Core.Services.FixUri;
namespace eShopOnContainers.Core.Services.Marketing
{
public class CampaignService : ICampaignService
{
private readonly IRequestProvider _requestProvider;
private readonly IFixUriService _fixUriService;
public CampaignService(IRequestProvider requestProvider)
public CampaignService(IRequestProvider requestProvider, IFixUriService fixUriService)
{
_requestProvider = requestProvider;
_fixUriService = fixUriService;
}
public async Task<ObservableCollection<CampaignItem>> GetAllCampaignsAsync(string token)
{
UriBuilder builder = new UriBuilder(GlobalSetting.Instance.MarketingEndpoint);
builder.Path = "api/v1/campaigns/user";
string uri = builder.ToString();
CampaignRoot campaign =
await _requestProvider.GetAsync<CampaignRoot>(uri, token);
CampaignRoot campaign = await _requestProvider.GetAsync<CampaignRoot>(uri, token);
if (campaign?.Data != null)
{
ServicesHelper.FixCampaignItemPictureUri(campaign?.Data);
_fixUriService.FixCampaignItemPictureUri(campaign?.Data);
return campaign?.Data.ToObservableCollection();
}
@ -41,11 +39,8 @@ namespace eShopOnContainers.Core.Services.Marketing
public async Task<CampaignItem> GetCampaignByIdAsync(int campaignId, string token)
{
UriBuilder builder = new UriBuilder(GlobalSetting.Instance.MarketingEndpoint);
builder.Path = $"api/v1/campaigns/{campaignId}";
string uri = builder.ToString();
return await _requestProvider.GetAsync<CampaignItem>(uri, token);
}
}

+ 39
- 31
src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Navigation/NavigationService.cs View File

@ -7,24 +7,32 @@ using System.Globalization;
using System.Reflection;
using System.Threading.Tasks;
using Xamarin.Forms;
using eShopOnContainers.Core.Services.Settings;
namespace eShopOnContainers.Services
{
public class NavigationService : INavigationService
{
public ViewModelBase PreviousPageViewModel
{
get
{
var mainPage = Application.Current.MainPage as CustomNavigationView;
var viewModel = mainPage.Navigation.NavigationStack[mainPage.Navigation.NavigationStack.Count - 2].BindingContext;
return viewModel as ViewModelBase;
}
}
private readonly ISettingsService _settingsService;
public ViewModelBase PreviousPageViewModel
{
get
{
var mainPage = Application.Current.MainPage as CustomNavigationView;
var viewModel = mainPage.Navigation.NavigationStack[mainPage.Navigation.NavigationStack.Count - 2].BindingContext;
return viewModel as ViewModelBase;
}
}
public NavigationService(ISettingsService settingsService)
{
_settingsService = settingsService;
}
public Task InitializeAsync()
{
if(string.IsNullOrEmpty(Settings.AuthAccessToken))
if (string.IsNullOrEmpty(_settingsService.AuthAccessToken))
return NavigateToAsync<LoginViewModel>();
else
return NavigateToAsync<MainViewModel>();
@ -78,7 +86,7 @@ namespace eShopOnContainers.Services
Application.Current.MainPage = new CustomNavigationView(page);
}
else
{
{
var navigationPage = Application.Current.MainPage as CustomNavigationView;
if (navigationPage != null)
{
@ -93,25 +101,25 @@ namespace eShopOnContainers.Services
await (page.BindingContext as ViewModelBase).InitializeAsync(parameter);
}
private Type GetPageTypeForViewModel(Type viewModelType)
{
var viewName = viewModelType.FullName.Replace("Model", string.Empty);
var viewModelAssemblyName = viewModelType.GetTypeInfo().Assembly.FullName;
var viewAssemblyName = string.Format(CultureInfo.InvariantCulture, "{0}, {1}", viewName, viewModelAssemblyName);
var viewType = Type.GetType(viewAssemblyName);
return viewType;
}
private Page CreatePage(Type viewModelType, object parameter)
{
Type pageType = GetPageTypeForViewModel(viewModelType);
if (pageType == null)
{
throw new Exception($"Cannot locate page type for {viewModelType}");
}
Page page = Activator.CreateInstance(pageType) as Page;
return page;
}
private Type GetPageTypeForViewModel(Type viewModelType)
{
var viewName = viewModelType.FullName.Replace("Model", string.Empty);
var viewModelAssemblyName = viewModelType.GetTypeInfo().Assembly.FullName;
var viewAssemblyName = string.Format(CultureInfo.InvariantCulture, "{0}, {1}", viewName, viewModelAssemblyName);
var viewType = Type.GetType(viewAssemblyName);
return viewType;
}
private Page CreatePage(Type viewModelType, object parameter)
{
Type pageType = GetPageTypeForViewModel(viewModelType);
if (pageType == null)
{
throw new Exception($"Cannot locate page type for {viewModelType}");
}
Page page = Activator.CreateInstance(pageType) as Page;
return page;
}
}
}

+ 14
- 0
src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Settings/ISettingsService.cs View File

@ -0,0 +1,14 @@
namespace eShopOnContainers.Core.Services.Settings
{
public interface ISettingsService
{
string AuthAccessToken { get; set; }
string AuthIdToken { get; set; }
bool UseMocks { get; set; }
string UrlBase { get; set; }
bool UseFakeLocation { get; set; }
string Latitude { get; set; }
string Longitude { get; set; }
bool AllowGpsLocation { get; set; }
}
}

+ 15
- 0
src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Settings/ISettingsServiceImplementation.cs View File

@ -0,0 +1,15 @@
namespace eShopOnContainers.Core.Services.Settings
{
public interface ISettingsServiceImplementation
{
bool GetValueOrDefault(string key, bool defaultValue);
string GetValueOrDefault(string key, string defaultValue);
bool AddOrUpdateValue(string key, bool value);
bool AddOrUpdateValue(string key, string value);
void Remove(string key);
void Clear();
bool Contains(string key);
}
}

src/Mobile/eShopOnContainers/eShopOnContainers.Core/Helpers/Settings.cs → src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Settings/SettingsService.cs View File

@ -1,21 +1,19 @@
using Plugin.Settings;
using Plugin.Settings.Abstractions;
using eShopOnContainers.Core.Services.Dependency;
namespace eShopOnContainers.Core.Helpers
namespace eShopOnContainers.Core.Services.Settings
{
/// <summary>
/// This is the Settings static class that can be used in your Core solution or in any
/// of your client applications. All settings are laid out the same exact way with getters
/// and setters.
/// </summary>
public static class Settings
public class SettingsService : ISettingsService
{
private static ISettings AppSettings
private readonly ISettingsServiceImplementation _settingsService;
ISettingsServiceImplementation AppSettings
{
get { return _settingsService; }
}
public SettingsService(IDependencyService dependencyService)
{
get
{
return CrossSettings.Current;
}
_settingsService = dependencyService.Get<ISettingsServiceImplementation>();
}
#region Setting Constants
@ -28,60 +26,60 @@ namespace eShopOnContainers.Core.Helpers
private const string IdLatitude = "latitude";
private const string IdLongitude = "longitude";
private const string IdAllowGpsLocation = "allow_gps_location";
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 bool AllowGpsLocationDefault = false;
private static readonly double FakeLatitudeDefault = 47.604610d;
private static readonly double FakeLongitudeDefault = -122.315752d;
private static readonly string UrlBaseDefault = GlobalSetting.Instance.BaseEndpoint;
private readonly string AccessTokenDefault = string.Empty;
private readonly string IdTokenDefault = string.Empty;
private readonly bool UseMocksDefault = true;
private readonly bool UseFakeLocationDefault = false;
private readonly bool AllowGpsLocationDefault = false;
private readonly double FakeLatitudeDefault = 47.604610d;
private readonly double FakeLongitudeDefault = -122.315752d;
private readonly string UrlBaseDefault = GlobalSetting.Instance.BaseEndpoint;
#endregion
public static string AuthAccessToken
public string AuthAccessToken
{
get => AppSettings.GetValueOrDefault(AccessToken, AccessTokenDefault);
set => AppSettings.AddOrUpdateValue(AccessToken, value);
}
public static string AuthIdToken
public string AuthIdToken
{
get => AppSettings.GetValueOrDefault(IdToken, IdTokenDefault);
set => AppSettings.AddOrUpdateValue(IdToken, value);
}
public static bool UseMocks
public bool UseMocks
{
get => AppSettings.GetValueOrDefault(IdUseMocks, UseMocksDefault);
set => AppSettings.AddOrUpdateValue(IdUseMocks, value);
}
public static string UrlBase
public string UrlBase
{
get => AppSettings.GetValueOrDefault(IdUrlBase, UrlBaseDefault);
set => AppSettings.AddOrUpdateValue(IdUrlBase, value);
}
public static bool UseFakeLocation
public bool UseFakeLocation
{
get => AppSettings.GetValueOrDefault(IdUseFakeLocation, UseFakeLocationDefault);
set => AppSettings.AddOrUpdateValue(IdUseFakeLocation, value);
}
public static string Latitude
public string Latitude
{
get => AppSettings.GetValueOrDefault(IdLatitude, FakeLatitudeDefault.ToString());
set => AppSettings.AddOrUpdateValue(IdLatitude, value);
}
public static string Longitude
public string Longitude
{
get => AppSettings.GetValueOrDefault(IdLongitude, FakeLongitudeDefault.ToString());
set => AppSettings.AddOrUpdateValue(IdLongitude, value);
}
public static bool AllowGpsLocation
public bool AllowGpsLocation
{
get => AppSettings.GetValueOrDefault(IdAllowGpsLocation, AllowGpsLocationDefault);
set => AppSettings.AddOrUpdateValue(IdAllowGpsLocation, value);

+ 2
- 1
src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/Base/ViewModelBase.cs View File

@ -1,6 +1,7 @@
using eShopOnContainers.Core.Helpers;
using eShopOnContainers.Services;
using System.Threading.Tasks;
using eShopOnContainers.Core.Services.Settings;
namespace eShopOnContainers.Core.ViewModels.Base
{
@ -29,7 +30,7 @@ namespace eShopOnContainers.Core.ViewModels.Base
{
DialogService = ViewModelLocator.Resolve<IDialogService>();
NavigationService = ViewModelLocator.Resolve<INavigationService>();
GlobalSetting.Instance.BaseEndpoint = Settings.UrlBase;
GlobalSetting.Instance.BaseEndpoint = ViewModelLocator.Resolve<ISettingsService>().UrlBase;
}
public virtual Task InitializeAsync(object navigationData)


+ 93
- 87
src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/Base/ViewModelLocator.cs View File

@ -10,108 +10,114 @@ using eShopOnContainers.Core.Services.Basket;
using eShopOnContainers.Core.Services.Identity;
using eShopOnContainers.Core.Services.Order;
using eShopOnContainers.Core.Services.User;
using Xamarin.Forms;
using eShopOnContainers.Core.Services.Location;
using eShopOnContainers.Core.Services.Marketing;
using eShopOnContainers.Core.Services.Dependency;
using eShopOnContainers.Core.Services.Settings;
using eShopOnContainers.Core.Services.FixUri;
using Xamarin.Forms;
namespace eShopOnContainers.Core.ViewModels.Base
{
public static class ViewModelLocator
{
private static IContainer _container;
public static readonly BindableProperty AutoWireViewModelProperty =
BindableProperty.CreateAttached("AutoWireViewModel", typeof(bool), typeof(ViewModelLocator), default(bool), propertyChanged: OnAutoWireViewModelChanged);
public static bool GetAutoWireViewModel(BindableObject bindable)
{
return (bool)bindable.GetValue(ViewModelLocator.AutoWireViewModelProperty);
}
public static void SetAutoWireViewModel(BindableObject bindable, bool value)
{
bindable.SetValue(ViewModelLocator.AutoWireViewModelProperty, value);
}
public static bool UseMockService { get; set; }
public static void RegisterDependencies(bool useMockServices)
{
var builder = new ContainerBuilder();
// View models
builder.RegisterType<BasketViewModel>();
builder.RegisterType<CatalogViewModel>();
builder.RegisterType<CheckoutViewModel>();
builder.RegisterType<LoginViewModel>();
builder.RegisterType<MainViewModel>();
builder.RegisterType<OrderDetailViewModel>();
builder.RegisterType<ProfileViewModel>();
builder.RegisterType<SettingsViewModel>();
builder.RegisterType<CampaignViewModel>();
builder.RegisterType<CampaignDetailsViewModel>();
private static IContainer _container;
public static readonly BindableProperty AutoWireViewModelProperty =
BindableProperty.CreateAttached("AutoWireViewModel", typeof(bool), typeof(ViewModelLocator), default(bool), propertyChanged: OnAutoWireViewModelChanged);
public static bool GetAutoWireViewModel(BindableObject bindable)
{
return (bool)bindable.GetValue(ViewModelLocator.AutoWireViewModelProperty);
}
public static void SetAutoWireViewModel(BindableObject bindable, bool value)
{
bindable.SetValue(ViewModelLocator.AutoWireViewModelProperty, value);
}
public static bool UseMockService { get; set; }
public static void RegisterDependencies(bool useMockServices)
{
var builder = new ContainerBuilder();
// View models
builder.RegisterType<BasketViewModel>();
builder.RegisterType<CatalogViewModel>();
builder.RegisterType<CheckoutViewModel>();
builder.RegisterType<LoginViewModel>();
builder.RegisterType<MainViewModel>();
builder.RegisterType<OrderDetailViewModel>();
builder.RegisterType<ProfileViewModel>();
builder.RegisterType<SettingsViewModel>();
builder.RegisterType<CampaignViewModel>();
builder.RegisterType<CampaignDetailsViewModel>();
// Services
builder.RegisterType<NavigationService>().As<INavigationService>().SingleInstance();
builder.RegisterType<DialogService>().As<IDialogService>();
builder.RegisterType<OpenUrlService>().As<IOpenUrlService>();
builder.RegisterType<IdentityService>().As<IIdentityService>();
builder.RegisterType<RequestProvider>().As<IRequestProvider>();
builder.RegisterType<DialogService>().As<IDialogService>();
builder.RegisterType<OpenUrlService>().As<IOpenUrlService>();
builder.RegisterType<IdentityService>().As<IIdentityService>();
builder.RegisterType<RequestProvider>().As<IRequestProvider>();
builder.RegisterType<LocationService>().As<ILocationService>().SingleInstance();
builder.RegisterType<Services.Dependency.DependencyService>().As<IDependencyService>();
builder.RegisterType<SettingsService>().As<ISettingsService>().SingleInstance();
builder.RegisterType<FixUriService>().As<FixUriService>().SingleInstance();
if (useMockServices)
{
builder.RegisterInstance(new CatalogMockService()).As<ICatalogService>();
builder.RegisterInstance(new BasketMockService()).As<IBasketService>();
builder.RegisterInstance(new OrderMockService()).As<IOrderService>();
builder.RegisterInstance(new UserMockService()).As<IUserService>();
builder.RegisterInstance(new CampaignMockService()).As<ICampaignService>();
{
builder.RegisterInstance(new CatalogMockService()).As<ICatalogService>();
builder.RegisterInstance(new BasketMockService()).As<IBasketService>();
builder.RegisterInstance(new OrderMockService()).As<IOrderService>();
builder.RegisterInstance(new UserMockService()).As<IUserService>();
builder.RegisterInstance(new CampaignMockService()).As<ICampaignService>();
UseMockService = true;
}
else
{
builder.RegisterType<CatalogService>().As<ICatalogService>().SingleInstance();
builder.RegisterType<BasketService>().As<IBasketService>().SingleInstance();
builder.RegisterType<OrderService>().As<IOrderService>().SingleInstance();
builder.RegisterType<UserService>().As<IUserService>().SingleInstance();
builder.RegisterType<CampaignService>().As<ICampaignService>().SingleInstance();
}
else
{
builder.RegisterType<CatalogService>().As<ICatalogService>().SingleInstance();
builder.RegisterType<BasketService>().As<IBasketService>().SingleInstance();
builder.RegisterType<OrderService>().As<IOrderService>().SingleInstance();
builder.RegisterType<UserService>().As<IUserService>().SingleInstance();
builder.RegisterType<CampaignService>().As<ICampaignService>().SingleInstance();
UseMockService = false;
}
if (_container != null)
{
_container.Dispose();
}
_container = builder.Build();
}
public static T Resolve<T>()
{
return _container.Resolve<T>();
}
private static void OnAutoWireViewModelChanged(BindableObject bindable, object oldValue, object newValue)
{
var view = bindable as Element;
if (view == null)
{
return;
}
var viewType = view.GetType();
var viewName = viewType.FullName.Replace(".Views.", ".ViewModels.");
var viewAssemblyName = viewType.GetTypeInfo().Assembly.FullName;
var viewModelName = string.Format(CultureInfo.InvariantCulture, "{0}Model, {1}", viewName, viewAssemblyName);
var viewModelType = Type.GetType(viewModelName);
if (viewModelType == null)
{
return;
}
var viewModel = _container.Resolve(viewModelType);
view.BindingContext = viewModel;
}
}
}
if (_container != null)
{
_container.Dispose();
}
_container = builder.Build();
}
public static T Resolve<T>()
{
return _container.Resolve<T>();
}
private static void OnAutoWireViewModelChanged(BindableObject bindable, object oldValue, object newValue)
{
var view = bindable as Element;
if (view == null)
{
return;
}
var viewType = view.GetType();
var viewName = viewType.FullName.Replace(".Views.", ".ViewModels.");
var viewAssemblyName = viewType.GetTypeInfo().Assembly.FullName;
var viewModelName = string.Format(CultureInfo.InvariantCulture, "{0}Model, {1}", viewName, viewAssemblyName);
var viewModelType = Type.GetType(viewModelName);
if (viewModelType == null)
{
return;
}
var viewModel = _container.Resolve(viewModelType);
view.BindingContext = viewModel;
}
}
}

+ 9
- 9
src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/BasketViewModel.cs View File

@ -1,4 +1,4 @@
using eShopOnContainers.Core.Helpers;
using eShopOnContainers.Core.Services.Settings;
using eShopOnContainers.Core.Models.Basket;
using eShopOnContainers.Core.Models.Catalog;
using eShopOnContainers.Core.Services.Basket;
@ -18,13 +18,16 @@ namespace eShopOnContainers.Core.ViewModels
private ObservableCollection<BasketItem> _basketItems;
private decimal _total;
private ISettingsService _settingsService;
private IBasketService _basketService;
private IUserService _userService;
public BasketViewModel(
ISettingsService settingsService,
IBasketService basketService,
IUserService userService)
{
_settingsService = settingsService;
_basketService = basketService;
_userService = userService;
}
@ -48,7 +51,7 @@ namespace eShopOnContainers.Core.ViewModels
RaisePropertyChanged(() => BasketItems);
}
}
public decimal Total
{
get { return _total; }
@ -68,7 +71,7 @@ namespace eShopOnContainers.Core.ViewModels
if (BasketItems == null)
BasketItems = new ObservableCollection<BasketItem>();
var authToken = Settings.AuthAccessToken;
var authToken = _settingsService.AuthAccessToken;
var userInfo = await _userService.GetUserInfoAsync(authToken);
// Update Basket
@ -93,7 +96,7 @@ namespace eShopOnContainers.Core.ViewModels
await AddCatalogItemAsync(arg);
});
await base.InitializeAsync(navigationData);
}
@ -114,16 +117,13 @@ namespace eShopOnContainers.Core.ViewModels
private async Task AddItemAsync(BasketItem item)
{
BadgeCount++;
await AddBasketItemAsync(item);
RaisePropertyChanged(() => BasketItems);
}
private async Task AddBasketItemAsync(BasketItem item)
{
BasketItems.Add(item);
await ReCalculateTotalAsync();
}
@ -141,12 +141,12 @@ namespace eShopOnContainers.Core.ViewModels
Total += (orderItem.Quantity * orderItem.UnitPrice);
}
var authToken = Settings.AuthAccessToken;
var authToken = _settingsService.AuthAccessToken;
var userInfo = await _userService.GetUserInfoAsync(authToken);
await _basketService.UpdateBasketAsync(new CustomerBasket
{
BuyerId = userInfo.UserId,
BuyerId = userInfo.UserId,
Items = BasketItems.ToList()
}, authToken);
}


+ 9
- 8
src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/CampaignDetailsViewModel.cs View File

@ -2,7 +2,7 @@
using System.Windows.Input;
using Xamarin.Forms;
using eShopOnContainers.Core.ViewModels.Base;
using eShopOnContainers.Core.Helpers;
using eShopOnContainers.Core.Services.Settings;
using eShopOnContainers.Core.Models.Marketing;
using eShopOnContainers.Core.Services.Marketing;
@ -10,12 +10,17 @@ namespace eShopOnContainers.Core.ViewModels
{
public class CampaignDetailsViewModel : ViewModelBase
{
private readonly ISettingsService _settingsService;
private readonly ICampaignService _campaignService;
private CampaignItem _campaign;
private bool _isDetailsSite;
private readonly ICampaignService _campaignService;
public CampaignDetailsViewModel(ICampaignService campaignService)
public ICommand EnableDetailsSiteCommand => new Command(EnableDetailsSite);
public CampaignDetailsViewModel(ISettingsService settingsService, ICampaignService campaignService)
{
_settingsService = settingsService;
_campaignService = campaignService;
}
@ -44,16 +49,12 @@ namespace eShopOnContainers.Core.ViewModels
if (navigationData is int)
{
IsBusy = true;
// Get campaign by id
Campaign = await _campaignService.GetCampaignByIdAsync((int)navigationData, Settings.AuthAccessToken);
Campaign = await _campaignService.GetCampaignByIdAsync((int)navigationData, _settingsService.AuthAccessToken);
IsBusy = false;
}
}
public ICommand EnableDetailsSiteCommand => new Command(EnableDetailsSite);
private void EnableDetailsSite()
{
IsDetailsSite = true;


+ 7
- 6
src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/CampaignViewModel.cs View File

@ -5,17 +5,20 @@ using System.Collections.ObjectModel;
using eShopOnContainers.Core.Models.Marketing;
using eShopOnContainers.Core.Services.Marketing;
using eShopOnContainers.Core.ViewModels.Base;
using eShopOnContainers.Core.Helpers;
using eShopOnContainers.Core.Services.Settings;
namespace eShopOnContainers.Core.ViewModels
{
public class CampaignViewModel : ViewModelBase
{
private ObservableCollection<CampaignItem> _campaigns;
private readonly ISettingsService _settingsService;
private readonly ICampaignService _campaignService;
public CampaignViewModel(ICampaignService campaignService)
private ObservableCollection<CampaignItem> _campaigns;
public CampaignViewModel(ISettingsService settingsService, ICampaignService campaignService)
{
_settingsService = settingsService;
_campaignService = campaignService;
}
@ -34,10 +37,8 @@ namespace eShopOnContainers.Core.ViewModels
public override async Task InitializeAsync(object navigationData)
{
IsBusy = true;
// Get campaigns by user
Campaigns = await _campaignService.GetAllCampaignsAsync(Settings.AuthAccessToken);
Campaigns = await _campaignService.GetAllCampaignsAsync(_settingsService.AuthAccessToken);
IsBusy = false;
}


+ 13
- 10
src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/CheckoutViewModel.cs View File

@ -10,7 +10,7 @@ using eShopOnContainers.Core.Models.Basket;
using System.Collections.Generic;
using eShopOnContainers.Core.Services.Basket;
using eShopOnContainers.Core.Services.Order;
using eShopOnContainers.Core.Helpers;
using eShopOnContainers.Core.Services.Settings;
using eShopOnContainers.Core.Services.User;
using eShopOnContainers.Core.Models.User;
@ -20,17 +20,20 @@ namespace eShopOnContainers.Core.ViewModels
{
private ObservableCollection<BasketItem> _orderItems;
private Order _order;
private Address _shippingAddress;
private Address _shippingAddress;
private ISettingsService _settingsService;
private IBasketService _basketService;
private IOrderService _orderService;
private IUserService _userService;
public CheckoutViewModel(
ISettingsService settingsService,
IBasketService basketService,
IOrderService orderService,
IUserService userService)
{
_settingsService = settingsService;
_basketService = basketService;
_orderService = orderService;
_userService = userService;
@ -79,7 +82,7 @@ namespace eShopOnContainers.Core.ViewModels
OrderItems = orderItems;
var authToken = Settings.AuthAccessToken;
var authToken = _settingsService.AuthAccessToken;
var userInfo = await _userService.GetUserInfoAsync(authToken);
// Create Shipping Address
@ -98,7 +101,7 @@ namespace eShopOnContainers.Core.ViewModels
{
CardNumber = userInfo?.CardNumber,
CardHolderName = userInfo?.CardHolder,
CardType = new CardType { Id = 3, Name = "MasterCard" },
CardType = new CardType { Id = 3, Name = "MasterCard" },
SecurityNumber = userInfo?.CardSecurityNumber
};
@ -117,12 +120,12 @@ namespace eShopOnContainers.Core.ViewModels
ShippingState = _shippingAddress.State,
ShippingCountry = _shippingAddress.Country,
ShippingStreet = _shippingAddress.Street,
ShippingCity = _shippingAddress.City,
ShippingCity = _shippingAddress.City,
ShippingZipCode = _shippingAddress.ZipCode,
Total = CalculateTotal(CreateOrderItems(orderItems))
};
if (Settings.UseMocks)
if (_settingsService.UseMocks)
{
// Get number of orders
var orders = await _orderService.GetOrdersAsync(authToken);
@ -140,7 +143,7 @@ namespace eShopOnContainers.Core.ViewModels
{
try
{
var authToken = Settings.AuthAccessToken;
var authToken = _settingsService.AuthAccessToken;
var basket = _orderService.MapOrderToBasket(Order);
basket.RequestId = Guid.NewGuid();
@ -148,7 +151,7 @@ namespace eShopOnContainers.Core.ViewModels
// Create basket checkout
await _basketService.CheckoutAsync(basket, authToken);
if (Settings.UseMocks)
if (_settingsService.UseMocks)
{
await _orderService.CreateOrderAsync(Order, authToken);
}
@ -195,13 +198,13 @@ namespace eShopOnContainers.Core.ViewModels
}
return orderItems;
}
}
private decimal CalculateTotal(List<OrderItem> orderItems)
{
decimal total = 0;
foreach(var orderItem in orderItems)
foreach (var orderItem in orderItems)
{
total += (orderItem.Quantity * orderItem.UnitPrice);
}


+ 27
- 24
src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/LoginViewModel.cs View File

@ -1,4 +1,4 @@
using eShopOnContainers.Core.Helpers;
using eShopOnContainers.Core.Services.Settings;
using eShopOnContainers.Core.Models.User;
using eShopOnContainers.Core.Services.Identity;
using eShopOnContainers.Core.Services.OpenUrl;
@ -22,13 +22,16 @@ namespace eShopOnContainers.Core.ViewModels
private bool _isLogin;
private string _authUrl;
private ISettingsService _settingsService;
private IOpenUrlService _openUrlService;
private IIdentityService _identityService;
public LoginViewModel(
ISettingsService settingsService,
IOpenUrlService openUrlService,
IIdentityService identityService)
{
_settingsService = settingsService;
_openUrlService = openUrlService;
_identityService = identityService;
@ -127,13 +130,13 @@ namespace eShopOnContainers.Core.ViewModels
public ICommand SettingsCommand => new Command(async () => await SettingsAsync());
public ICommand ValidateUserNameCommand => new Command(() => ValidateUserName());
public ICommand ValidateUserNameCommand => new Command(() => ValidateUserName());
public ICommand ValidatePasswordCommand => new Command(() => ValidatePassword());
public ICommand ValidatePasswordCommand => new Command(() => ValidatePassword());
public override Task InitializeAsync(object navigationData)
{
if(navigationData is LogoutParameter)
if (navigationData is LogoutParameter)
{
var logoutParameter = (LogoutParameter)navigationData;
@ -173,7 +176,7 @@ namespace eShopOnContainers.Core.ViewModels
if (isAuthenticated)
{
Settings.AuthAccessToken = GlobalSetting.Instance.AuthToken;
_settingsService.AuthAccessToken = GlobalSetting.Instance.AuthToken;
await NavigationService.NavigateToAsync<MainViewModel>();
await NavigationService.RemoveLastFromBackStackAsync();
@ -202,7 +205,7 @@ namespace eShopOnContainers.Core.ViewModels
private void Logout()
{
var authIdToken = Settings.AuthIdToken;
var authIdToken = _settingsService.AuthIdToken;
var logoutRequest = _identityService.CreateLogoutRequest(authIdToken);
if (!string.IsNullOrEmpty(logoutRequest))
@ -211,13 +214,13 @@ namespace eShopOnContainers.Core.ViewModels
LoginUrl = logoutRequest;
}
if (Settings.UseMocks)
if (_settingsService.UseMocks)
{
Settings.AuthAccessToken = string.Empty;
Settings.AuthIdToken = string.Empty;
_settingsService.AuthAccessToken = string.Empty;
_settingsService.AuthIdToken = string.Empty;
}
Settings.UseFakeLocation = false;
_settingsService.UseFakeLocation = false;
}
private async Task NavigateAsync(string url)
@ -226,8 +229,8 @@ namespace eShopOnContainers.Core.ViewModels
if (unescapedUrl.Equals(GlobalSetting.Instance.LogoutCallback))
{
Settings.AuthAccessToken = string.Empty;
Settings.AuthIdToken = string.Empty;
_settingsService.AuthAccessToken = string.Empty;
_settingsService.AuthIdToken = string.Empty;
IsLogin = false;
LoginUrl = _identityService.CreateAuthorizationRequest();
}
@ -241,8 +244,8 @@ namespace eShopOnContainers.Core.ViewModels
if (!string.IsNullOrWhiteSpace(accessToken))
{
Settings.AuthAccessToken = accessToken;
Settings.AuthIdToken = authResponse.IdentityToken;
_settingsService.AuthAccessToken = accessToken;
_settingsService.AuthIdToken = authResponse.IdentityToken;
await NavigationService.NavigateToAsync<MainViewModel>();
await NavigationService.RemoveLastFromBackStackAsync();
}
@ -257,21 +260,21 @@ namespace eShopOnContainers.Core.ViewModels
private bool Validate()
{
bool isValidUser = ValidateUserName();
bool isValidUser = ValidateUserName();
bool isValidPassword = ValidatePassword();
return isValidUser && isValidPassword;
}
private bool ValidateUserName()
{
return _userName.Validate();
}
private bool ValidateUserName()
{
return _userName.Validate();
}
private bool ValidatePassword()
{
return _password.Validate();
}
private bool ValidatePassword()
{
return _password.Validate();
}
private void AddValidations()
{
@ -281,7 +284,7 @@ namespace eShopOnContainers.Core.ViewModels
public void InvalidateMock()
{
IsMock = Settings.UseMocks;
IsMock = _settingsService.UseMocks;
}
}
}

+ 9
- 6
src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/OrderDetailViewModel.cs View File

@ -4,20 +4,23 @@ using eShopOnContainers.Core.ViewModels.Base;
using eShopOnContainers.Core.Services.Order;
using System;
using System.Windows.Input;
using eShopOnContainers.Core.Helpers;
using eShopOnContainers.Core.Services.Settings;
using Xamarin.Forms;
namespace eShopOnContainers.Core.ViewModels
{
public class OrderDetailViewModel : ViewModelBase
{
private readonly ISettingsService _settingsService;
private readonly IOrderService _ordersService;
private Order _order;
private Order _order;
private bool _isSubmittedOrder;
private string _orderStatusText;
public OrderDetailViewModel(IOrderService ordersService)
public OrderDetailViewModel(ISettingsService settingsService, IOrderService ordersService)
{
_settingsService = settingsService;
_ordersService = ordersService;
}
@ -63,7 +66,7 @@ namespace eShopOnContainers.Core.ViewModels
var order = navigationData as Order;
// Get order detail info
var authToken = Settings.AuthAccessToken;
var authToken = _settingsService.AuthAccessToken;
Order = await _ordersService.GetOrderAsync(order.OrderNumber, authToken);
IsSubmittedOrder = Order.OrderStatus == OrderStatus.Submitted;
OrderStatusText = Order.OrderStatus.ToString().ToUpper();
@ -74,13 +77,13 @@ namespace eShopOnContainers.Core.ViewModels
private async Task ToggleCancelOrderAsync()
{
var authToken = Settings.AuthAccessToken;
var authToken = _settingsService.AuthAccessToken;
var result = await _ordersService.CancelOrderAsync(_order.OrderNumber, authToken);
if (result)
{
OrderStatusText = OrderStatus.Cancelled.ToString().ToUpper();
OrderStatusText = OrderStatus.Cancelled.ToString().ToUpper();
}
else
{


+ 6
- 5
src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/ProfileViewModel.cs View File

@ -1,5 +1,4 @@
using eShopOnContainers.Core.Extensions;
using eShopOnContainers.Core.Helpers;
using eShopOnContainers.Core.Models.Orders;
using eShopOnContainers.Core.Models.User;
using eShopOnContainers.Core.Services.Order;
@ -8,17 +7,19 @@ using System.Collections.ObjectModel;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;
using eShopOnContainers.Core.Services.Settings;
namespace eShopOnContainers.Core.ViewModels
{
public class ProfileViewModel : ViewModelBase
{
private readonly ISettingsService _settingsService;
private readonly IOrderService _orderService;
private ObservableCollection<Order> _orders;
private IOrderService _orderService;
public ProfileViewModel(IOrderService orderService)
public ProfileViewModel(ISettingsService settingsService, IOrderService orderService)
{
_settingsService = settingsService;
_orderService = orderService;
}
@ -41,7 +42,7 @@ namespace eShopOnContainers.Core.ViewModels
IsBusy = true;
// Get orders
var authToken = Settings.AuthAccessToken;
var authToken = _settingsService.AuthAccessToken;
var orders = await _orderService.GetOrdersAsync(authToken);
Orders = orders.ToObservableCollection();


+ 53
- 52
src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/SettingsViewModel.cs View File

@ -1,17 +1,16 @@
using System.Globalization;
using System.Windows.Input;
using Xamarin.Forms;
using System.Threading.Tasks;
using eShopOnContainers.Core.Models.User;
using eShopOnContainers.Core.ViewModels.Base;
using eShopOnContainers.Core.Models.Location;
using eShopOnContainers.Core.Services.Location;
using Plugin.Geolocator;
using eShopOnContainers.Core.Services.Settings;
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;
using Plugin.Geolocator;
public class SettingsViewModel : ViewModelBase
{
private string _titleUseAzureServices;
@ -28,18 +27,20 @@ namespace eShopOnContainers.Core.ViewModels
private double _longitude;
private string _gpsWarningMessage;
private readonly ISettingsService _settingsService;
private readonly ILocationService _locationService;
public SettingsViewModel(ILocationService locationService)
public SettingsViewModel(ISettingsService settingsService, ILocationService locationService)
{
_settingsService = settingsService;
_locationService = locationService;
_useAzureServices = !Settings.UseMocks;
_endpoint = Settings.UrlBase;
_latitude = double.Parse(Settings.Latitude, CultureInfo.CurrentCulture);
_longitude = double.Parse(Settings.Longitude, CultureInfo.CurrentCulture);
_useFakeLocation = Settings.UseFakeLocation;
_allowGpsLocation = Settings.AllowGpsLocation;
_useAzureServices = _settingsService.UseMocks;
_endpoint = _settingsService.UrlBase;
_latitude = double.Parse(_settingsService.Latitude, CultureInfo.CurrentCulture);
_longitude = double.Parse(_settingsService.Longitude, CultureInfo.CurrentCulture);
_useFakeLocation = _settingsService.UseFakeLocation;
_allowGpsLocation = _settingsService.AllowGpsLocation;
_gpsWarningMessage = string.Empty;
}
@ -71,7 +72,7 @@ namespace eShopOnContainers.Core.ViewModels
_useAzureServices = value;
UpdateUseAzureServices();
RaisePropertyChanged(() => UseAzureServices);
}
}
@ -146,7 +147,7 @@ namespace eShopOnContainers.Core.ViewModels
{
_endpoint = value;
if(!string.IsNullOrEmpty(_endpoint))
if (!string.IsNullOrEmpty(_endpoint))
{
UpdateEndpoint();
}
@ -194,7 +195,7 @@ namespace eShopOnContainers.Core.ViewModels
}
}
public bool UserIsLogged => !string.IsNullOrEmpty(Settings.AuthAccessToken);
public bool UserIsLogged => !string.IsNullOrEmpty(_settingsService.AuthAccessToken);
public ICommand ToggleMockServicesCommand => new Command(async () => await ToggleMockServicesAsync());
@ -213,28 +214,28 @@ namespace eShopOnContainers.Core.ViewModels
return base.InitializeAsync(navigationData);
}
private async Task ToggleMockServicesAsync()
{
ViewModelLocator.RegisterDependencies(!UseAzureServices);
UpdateInfoUseAzureServices();
var previousPageViewModel = NavigationService.PreviousPageViewModel;
if (previousPageViewModel != null)
{
if (previousPageViewModel is MainViewModel)
{
// Slight delay so that page navigation isn't instantaneous
await Task.Delay(1000);
if (UseAzureServices)
{
Settings.AuthAccessToken = string.Empty;
Settings.AuthIdToken = string.Empty;
await NavigationService.NavigateToAsync<LoginViewModel>(new LogoutParameter { Logout = true });
await NavigationService.RemoveBackStackAsync();
}
}
}
}
private async Task ToggleMockServicesAsync()
{
ViewModelLocator.RegisterDependencies(!UseAzureServices);
UpdateInfoUseAzureServices();
var previousPageViewModel = NavigationService.PreviousPageViewModel;
if (previousPageViewModel != null)
{
if (previousPageViewModel is MainViewModel)
{
// Slight delay so that page navigation isn't instantaneous
await Task.Delay(1000);
if (UseAzureServices)
{
_settingsService.AuthAccessToken = string.Empty;
_settingsService.AuthIdToken = string.Empty;
await NavigationService.NavigateToAsync<LoginViewModel>(new LogoutParameter { Logout = true });
await NavigationService.RemoveBackStackAsync();
}
}
}
}
private void ToggleFakeLocationAsync()
{
@ -244,17 +245,17 @@ namespace eShopOnContainers.Core.ViewModels
private async Task ToggleSendLocationAsync()
{
if (!Settings.UseMocks)
if (!_settingsService.UseMocks)
{
var locationRequest = new Location
{
Latitude = _latitude,
Longitude = _longitude
};
var authToken = Settings.AuthAccessToken;
var authToken = _settingsService.AuthAccessToken;
await _locationService.UpdateUserLocation(locationRequest, authToken);
}
}
}
private void ToggleAllowGpsLocation()
@ -310,30 +311,30 @@ namespace eShopOnContainers.Core.ViewModels
private void UpdateUseAzureServices()
{
// Save use mocks services to local storage
Settings.UseMocks = !_useAzureServices;
_settingsService.UseMocks = !_useAzureServices;
}
private void UpdateEndpoint()
{
// Update remote endpoint (save to local storage)
GlobalSetting.Instance.BaseEndpoint = Settings.UrlBase = _endpoint;
GlobalSetting.Instance.BaseEndpoint = _settingsService.UrlBase = _endpoint;
}
private void UpdateFakeLocation()
{
Settings.UseFakeLocation = _useFakeLocation;
_settingsService.UseFakeLocation = _useFakeLocation;
}
private void UpdateLatitude()
{
// Update fake latitude (save to local storage)
Settings.Latitude = _latitude.ToString();
_settingsService.Latitude = _latitude.ToString();
}
private void UpdateLongitude()
{
// Update fake longitude (save to local storage)
Settings.Longitude = _longitude.ToString();
_settingsService.Longitude = _longitude.ToString();
}
private void UpdateAllowGpsLocation()
@ -348,13 +349,13 @@ namespace eShopOnContainers.Core.ViewModels
}
else
{
Settings.AllowGpsLocation = _allowGpsLocation;
_settingsService.AllowGpsLocation = _allowGpsLocation;
GpsWarningMessage = string.Empty;
}
}
else
{
Settings.AllowGpsLocation = _allowGpsLocation;
_settingsService.AllowGpsLocation = _allowGpsLocation;
}
}
}

+ 5
- 1
src/Mobile/eShopOnContainers/eShopOnContainers.Core/eShopOnContainers.Core.csproj View File

@ -5,7 +5,6 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Xam.Plugins.Settings" Version="3.1.1" />
<PackageReference Include="System.ComponentModel.Annotations" Version="4.4.1" />
<PackageReference Include="Acr.UserDialogs" Version="6.5.1" />
<PackageReference Include="SlideOverKit" Version="2.1.5" />
@ -17,4 +16,9 @@
<PackageReference Include="Autofac" Version="4.6.2" />
<PackageReference Include="IdentityModel" Version="3.0.0" />
</ItemGroup>
<ItemGroup>
<Folder Include="Services\Settings\" />
<Folder Include="Services\Dependency\" />
<Folder Include="Services\FixUri\" />
</ItemGroup>
</Project>

+ 0
- 44
src/Mobile/eShopOnContainers/eShopOnContainers.Droid/Helpers/Settings.cs View File

@ -1,44 +0,0 @@
/*
// Helpers/Settings.cs This file was automatically added when you installed the Settings Plugin. If you are not using a PCL then comment this file back in to use it.
using Plugin.Settings;
using Plugin.Settings.Abstractions;
namespace eShopOnContainers.Droid.Helpers
{
/// <summary>
/// This is the Settings static class that can be used in your Core solution or in any
/// of your client applications. All settings are laid out the same exact way with getters
/// and setters.
/// </summary>
public static class Settings
{
private static ISettings AppSettings
{
get
{
return CrossSettings.Current;
}
}
#region Setting Constants
private const string SettingsKey = "settings_key";
private static readonly string SettingsDefault = string.Empty;
#endregion
public static string GeneralSettings
{
get
{
return AppSettings.GetValueOrDefault(SettingsKey, SettingsDefault);
}
set
{
AppSettings.AddOrUpdateValue(SettingsKey, value);
}
}
}
}*/

+ 0
- 7
src/Mobile/eShopOnContainers/eShopOnContainers.Droid/eShopOnContainers.Droid.csproj View File

@ -166,12 +166,6 @@
<Reference Include="Plugin.Geolocator">
<HintPath>..\..\..\..\packages\Xam.Plugin.Geolocator.3.0.4\lib\MonoAndroid10\Plugin.Geolocator.dll</HintPath>
</Reference>
<Reference Include="Plugin.Settings.Abstractions">
<HintPath>..\..\..\..\packages\Xam.Plugins.Settings.3.1.1\lib\MonoAndroid10\Plugin.Settings.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Plugin.Settings">
<HintPath>..\..\..\..\packages\Xam.Plugins.Settings.3.1.1\lib\MonoAndroid10\Plugin.Settings.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http.Extensions">
<HintPath>..\..\..\..\packages\Microsoft.Net.Http.2.2.28\lib\monoandroid\System.Net.Http.Extensions.dll</HintPath>
</Reference>
@ -235,7 +229,6 @@
<Compile Include="Effects\CircleEffect.cs" />
<Compile Include="Effects\BaseContainerEffect.cs" />
<Compile Include="Activities\SplashActivity.cs" />
<Compile Include="Helpers\Settings.cs" />
</ItemGroup>
<ItemGroup>
<AndroidAsset Include="..\CommonResources\Fonts\Montserrat-Bold.ttf">


+ 0
- 1
src/Mobile/eShopOnContainers/eShopOnContainers.Droid/packages.config View File

@ -71,7 +71,6 @@
<package id="System.Xml.XmlDocument" version="4.3.0" targetFramework="monoandroid80" />
<package id="Validation" version="2.2.8" targetFramework="monoandroid80" />
<package id="Xam.Plugin.Geolocator" version="3.0.4" targetFramework="monoandroid80" />
<package id="Xam.Plugins.Settings" version="3.1.1" targetFramework="monoandroid80" />
<package id="Xamarin.Android.Support.Animated.Vector.Drawable" version="25.4.0.2" targetFramework="monoandroid80" />
<package id="Xamarin.Android.Support.Annotations" version="25.4.0.2" targetFramework="monoandroid80" />
<package id="Xamarin.Android.Support.Compat" version="25.4.0.2" targetFramework="monoandroid80" />


+ 0
- 44
src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.Droid/Helpers/Settings.cs View File

@ -1,44 +0,0 @@
/*
// Helpers/Settings.cs This file was automatically added when you installed the Settings Plugin. If you are not using a PCL then comment this file back in to use it.
using Plugin.Settings;
using Plugin.Settings.Abstractions;
namespace eShopOnContainers.TestRunner.Droid.Helpers
{
/// <summary>
/// This is the Settings static class that can be used in your Core solution or in any
/// of your client applications. All settings are laid out the same exact way with getters
/// and setters.
/// </summary>
public static class Settings
{
private static ISettings AppSettings
{
get
{
return CrossSettings.Current;
}
}
#region Setting Constants
private const string SettingsKey = "settings_key";
private static readonly string SettingsDefault = string.Empty;
#endregion
public static string GeneralSettings
{
get
{
return AppSettings.GetValueOrDefault(SettingsKey, SettingsDefault);
}
set
{
AppSettings.AddOrUpdateValue(SettingsKey, value);
}
}
}
}*/

+ 0
- 7
src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.Droid/eShopOnContainers.TestRunner.Droid.csproj View File

@ -154,12 +154,6 @@
<Reference Include="Autofac">
<HintPath>..\..\..\..\packages\Autofac.4.6.2\lib\netstandard1.1\Autofac.dll</HintPath>
</Reference>
<Reference Include="Plugin.Settings.Abstractions">
<HintPath>..\..\..\..\packages\Xam.Plugins.Settings.3.1.1\lib\MonoAndroid10\Plugin.Settings.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Plugin.Settings">
<HintPath>..\..\..\..\packages\Xam.Plugins.Settings.3.1.1\lib\MonoAndroid10\Plugin.Settings.dll</HintPath>
</Reference>
<Reference Include="Plugin.CurrentActivity">
<HintPath>..\..\..\..\packages\Plugin.CurrentActivity.1.0.1\lib\MonoAndroid10\Plugin.CurrentActivity.dll</HintPath>
</Reference>
@ -234,7 +228,6 @@
<Compile Include="MainActivity.cs" />
<Compile Include="Resources\Resource.Designer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Helpers\Settings.cs" />
<Compile Include="MainApplication.cs" />
</ItemGroup>
<ItemGroup>


+ 0
- 1
src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.Droid/packages.config View File

@ -68,7 +68,6 @@
<package id="System.Xml.XmlDocument" version="4.3.0" targetFramework="monoandroid80" />
<package id="Validation" version="2.2.8" targetFramework="monoandroid80" />
<package id="Xam.Plugin.Geolocator" version="3.0.4" targetFramework="monoandroid80" />
<package id="Xam.Plugins.Settings" version="3.1.1" targetFramework="monoandroid80" />
<package id="Xamarin.Android.Support.Animated.Vector.Drawable" version="25.4.0.2" targetFramework="monoandroid80" />
<package id="Xamarin.Android.Support.Annotations" version="25.4.0.2" targetFramework="monoandroid80" />
<package id="Xamarin.Android.Support.Compat" version="25.4.0.2" targetFramework="monoandroid80" />


+ 0
- 44
src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.iOS/Helpers/Settings.cs View File

@ -1,44 +0,0 @@
/*
// Helpers/Settings.cs This file was automatically added when you installed the Settings Plugin. If you are not using a PCL then comment this file back in to use it.
using Plugin.Settings;
using Plugin.Settings.Abstractions;
namespace eShopOnContainers.TestRunner.iOS.Helpers
{
/// <summary>
/// This is the Settings static class that can be used in your Core solution or in any
/// of your client applications. All settings are laid out the same exact way with getters
/// and setters.
/// </summary>
public static class Settings
{
private static ISettings AppSettings
{
get
{
return CrossSettings.Current;
}
}
#region Setting Constants
private const string SettingsKey = "settings_key";
private static readonly string SettingsDefault = string.Empty;
#endregion
public static string GeneralSettings
{
get
{
return AppSettings.GetValueOrDefault(SettingsKey, SettingsDefault);
}
set
{
AppSettings.AddOrUpdateValue(SettingsKey, value);
}
}
}
}*/

+ 0
- 7
src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.iOS/eShopOnContainers.TestRunner.iOS.csproj View File

@ -105,7 +105,6 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<InterfaceDefinition Include="Resources\LaunchScreen.xib" />
<None Include="packages.config" />
<Compile Include="Helpers\Settings.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
@ -151,12 +150,6 @@
<Reference Include="Newtonsoft.Json">
<HintPath>..\..\..\..\packages\Newtonsoft.Json.10.0.3\lib\netstandard1.3\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="Plugin.Settings.Abstractions">
<HintPath>..\..\..\..\packages\Xam.Plugins.Settings.3.1.1\lib\Xamarin.iOS10\Plugin.Settings.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Plugin.Settings">
<HintPath>..\..\..\..\packages\Xam.Plugins.Settings.3.1.1\lib\Xamarin.iOS10\Plugin.Settings.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Content Include="Entitlements.plist" />


+ 0
- 1
src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.iOS/packages.config View File

@ -53,7 +53,6 @@
<package id="System.Xml.ReaderWriter" version="4.3.0" targetFramework="xamarinios10" />
<package id="System.Xml.XDocument" version="4.3.0" targetFramework="xamarinios10" />
<package id="System.Xml.XmlDocument" version="4.3.0" targetFramework="xamarinios10" />
<package id="Xam.Plugins.Settings" version="3.1.1" targetFramework="xamarinios10" />
<package id="Xamarin.Forms" version="2.5.0.122203" targetFramework="xamarinios10" />
<package id="xunit" version="2.3.1" targetFramework="xamarinios10" />
<package id="xunit.abstractions" version="2.0.1" targetFramework="xamarinios10" />


+ 0
- 44
src/Mobile/eShopOnContainers/eShopOnContainers.iOS/Helpers/Settings.cs View File

@ -1,44 +0,0 @@
/*
// Helpers/Settings.cs This file was automatically added when you installed the Settings Plugin. If you are not using a PCL then comment this file back in to use it.
using Plugin.Settings;
using Plugin.Settings.Abstractions;
namespace eShopOnContainers.iOS.Helpers
{
/// <summary>
/// This is the Settings static class that can be used in your Core solution or in any
/// of your client applications. All settings are laid out the same exact way with getters
/// and setters.
/// </summary>
public static class Settings
{
private static ISettings AppSettings
{
get
{
return CrossSettings.Current;
}
}
#region Setting Constants
private const string SettingsKey = "settings_key";
private static readonly string SettingsDefault = string.Empty;
#endregion
public static string GeneralSettings
{
get
{
return AppSettings.GetValueOrDefault(SettingsKey, SettingsDefault);
}
set
{
AppSettings.AddOrUpdateValue(SettingsKey, value);
}
}
}
}*/

+ 164
- 0
src/Mobile/eShopOnContainers/eShopOnContainers.iOS/Services/SettingsServiceImplementation.cs View File

@ -0,0 +1,164 @@
using System;
using Foundation;
using eShopOnContainers.Core.Services.Settings;
using eShopOnContainers.iOS.Services;
using System.Globalization;
[assembly: Xamarin.Forms.Dependency(typeof(SettingsServiceImplementation))]
namespace eShopOnContainers.iOS.Services
{
public class SettingsServiceImplementation : ISettingsServiceImplementation
{
readonly object locker = new object();
NSUserDefaults GetUserDefaults() => NSUserDefaults.StandardUserDefaults;
bool AddOrUpdateValueInternal<T>(string key, T value)
{
if (value == null)
{
Remove(key);
return true;
}
var type = typeof(T);
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
{
type = Nullable.GetUnderlyingType(type);
}
var typeCode = Type.GetTypeCode(type);
lock (locker)
{
var defaults = GetUserDefaults();
switch (typeCode)
{
case TypeCode.Boolean:
defaults.SetString(Convert.ToString(value, CultureInfo.InvariantCulture), key);
break;
case TypeCode.String:
defaults.SetString(Convert.ToString(value), key);
break;
default:
throw new ArgumentException($"Value of type {typeCode} is unsupported.");
}
try
{
defaults.Synchronize();
}
catch (Exception ex)
{
Console.WriteLine("Unable to save: " + key, " Message: " + ex.Message);
}
}
return true;
}
T GetValueOrDefaultInternal<T>(string key, T defaultValue = default(T))
{
var defaults = GetUserDefaults();
if (defaults[key] == null)
{
return defaultValue;
}
var type = typeof(T);
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
{
type = Nullable.GetUnderlyingType(type);
}
object value = null;
var typeCode = Type.GetTypeCode(type);
switch (typeCode)
{
case TypeCode.Boolean:
value = defaults.BoolForKey(key);
break;
case TypeCode.String:
value = defaults.StringForKey(key);
break;
default:
throw new ArgumentException($"Value of type {typeCode} is unsupported.");
}
return null != value ? (T)value : defaultValue;
}
#region ISettingsService Implementation
public bool AddOrUpdateValue(string key, bool value) => AddOrUpdateValueInternal(key, value);
public bool AddOrUpdateValue(string key, string value) => AddOrUpdateValueInternal(key, value);
public bool GetValueOrDefault(string key, bool defaultValue) => GetValueOrDefaultInternal(key, defaultValue);
public string GetValueOrDefault(string key, string defaultValue) => GetValueOrDefaultInternal(key, defaultValue);
public void Remove(string key)
{
lock (locker)
{
var defaults = GetUserDefaults();
try
{
if (defaults[key] != null)
{
defaults.RemoveObject(key);
defaults.Synchronize();
}
}
catch (Exception ex)
{
Console.WriteLine("Unable to remove: " + key, " Message: " + ex.Message);
}
}
}
public void Clear()
{
lock (locker)
{
var defaults = GetUserDefaults();
try
{
var items = defaults.ToDictionary();
foreach (var item in items.Keys)
{
if (item is NSString nsString)
{
defaults.RemoveObject(nsString);
}
}
defaults.Synchronize();
}
catch (Exception ex)
{
Console.WriteLine("Unable to clear all defaults. Message: " + ex.Message);
}
}
}
public bool Contains(string key)
{
lock (locker)
{
var defaults = GetUserDefaults();
try
{
var setting = defaults[key];
return setting != null;
}
catch (Exception ex)
{
Console.WriteLine("Unable to clear all defaults. Message: " + ex.Message);
}
return false;
}
}
#endregion
}
}

+ 4
- 7
src/Mobile/eShopOnContainers/eShopOnContainers.iOS/eShopOnContainers.iOS.csproj View File

@ -125,7 +125,7 @@
<BundleResource Include="Resources\menu_campaigns%402x.png" />
<BundleResource Include="Resources\menu_campaigns%403x.png" />
<None Include="packages.config" />
<Compile Include="Helpers\Settings.cs" />
<Compile Include="Services\SettingsServiceImplementation.cs" />
</ItemGroup>
<ItemGroup>
<BundleResource Include="Resources\Icon-60%403x.png" />
@ -176,12 +176,6 @@
<Reference Include="Autofac">
<HintPath>..\..\..\..\packages\Autofac.4.6.2\lib\netstandard1.1\Autofac.dll</HintPath>
</Reference>
<Reference Include="Plugin.Settings.Abstractions">
<HintPath>..\..\..\..\packages\Xam.Plugins.Settings.3.1.1\lib\Xamarin.iOS10\Plugin.Settings.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Plugin.Settings">
<HintPath>..\..\..\..\packages\Xam.Plugins.Settings.3.1.1\lib\Xamarin.iOS10\Plugin.Settings.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="Newtonsoft.Json">
<HintPath>..\..\..\..\packages\Newtonsoft.Json.10.0.3\lib\netstandard1.3\Newtonsoft.Json.dll</HintPath>
@ -399,6 +393,9 @@
<Name>eShopOnContainers.Core</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Folder Include="Services\" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
<Import Project="..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\build\netstandard1.0\Xamarin.Forms.targets" Condition="Exists('..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\build\netstandard1.0\Xamarin.Forms.targets')" />
<Import Project="..\..\..\..\packages\NETStandard.Library.2.0.0\build\netstandard2.0\NETStandard.Library.targets" Condition="Exists('..\..\..\..\packages\NETStandard.Library.2.0.0\build\netstandard2.0\NETStandard.Library.targets')" />


+ 0
- 1
src/Mobile/eShopOnContainers/eShopOnContainers.iOS/packages.config View File

@ -60,7 +60,6 @@
<package id="System.Xml.XmlDocument" version="4.3.0" targetFramework="xamarinios10" />
<package id="WebP.Touch" version="1.0.7" targetFramework="xamarinios10" />
<package id="Xam.Plugin.Geolocator" version="3.0.4" targetFramework="xamarinios10" />
<package id="Xam.Plugins.Settings" version="3.1.1" targetFramework="xamarinios10" />
<package id="Xamarin.FFImageLoading" version="2.3.4" targetFramework="xamarinios10" />
<package id="Xamarin.FFImageLoading.Forms" version="2.3.4" targetFramework="xamarinios10" />
<package id="Xamarin.Forms" version="2.5.0.122203" targetFramework="xamarinios10" />

Loading…
Cancel
Save