Browse Source

Completed Identity integration

pull/49/merge
Javier Suárez Ruiz 8 years ago
parent
commit
7c8d671bbf
16 changed files with 6011 additions and 67 deletions
  1. +51
    -0
      eShopOnContainers.sln
  2. +3
    -0
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/GlobalSettings.cs
  3. +14
    -0
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/Helpers/Settings.cs
  4. +6
    -1
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Identity/IdentityService.cs
  5. +0
    -5
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/Base/ViewModelLocator.cs
  6. +6
    -3
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/BasketViewModel.cs
  7. +3
    -0
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/CatalogViewModel.cs
  8. +27
    -8
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/CheckoutViewModel.cs
  9. +14
    -7
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/LoginViewModel.cs
  10. +1
    -0
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/MainViewModel.cs
  11. +1
    -2
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/OrderDetailViewModel.cs
  12. +2
    -1
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/ProfileViewModel.cs
  13. +1
    -0
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/SettingsViewModel.cs
  14. +15
    -0
      src/Mobile/eShopOnContainers/eShopOnContainers.Droid/Activities/MainActivity.cs
  15. +1
    -1
      src/Mobile/eShopOnContainers/eShopOnContainers.Droid/Properties/AndroidManifest.xml
  16. +5866
    -39
      src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.Droid/Resources/Resource.Designer.cs

+ 51
- 0
eShopOnContainers.sln View File

@ -73,6 +73,8 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "eShopOnContainers.Identity"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "FunctionalTests", "test\Services\FunctionalTests\FunctionalTests.xproj", "{621E7211-58D0-45FD-9600-1CB490BD930E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.UITests", "src\Mobile\eShopOnContainers\eShopOnContainers.UITests\eShopOnContainers.UITests.csproj", "{E3B18084-842C-4B80-8E4A-A7E588EC3137}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Ad-Hoc|Any CPU = Ad-Hoc|Any CPU
@ -905,6 +907,54 @@ Global
{621E7211-58D0-45FD-9600-1CB490BD930E}.Release|x64.Build.0 = Release|Any CPU
{621E7211-58D0-45FD-9600-1CB490BD930E}.Release|x86.ActiveCfg = Release|Any CPU
{621E7211-58D0-45FD-9600-1CB490BD930E}.Release|x86.Build.0 = Release|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.Ad-Hoc|ARM.Build.0 = Release|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.Ad-Hoc|x64.ActiveCfg = Release|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.Ad-Hoc|x64.Build.0 = Release|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.Ad-Hoc|x86.Build.0 = Release|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.AppStore|Any CPU.Build.0 = Release|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.AppStore|ARM.ActiveCfg = Release|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.AppStore|ARM.Build.0 = Release|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.AppStore|iPhone.ActiveCfg = Release|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.AppStore|iPhone.Build.0 = Release|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.AppStore|x64.ActiveCfg = Release|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.AppStore|x64.Build.0 = Release|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.AppStore|x86.ActiveCfg = Release|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.AppStore|x86.Build.0 = Release|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.Debug|ARM.ActiveCfg = Debug|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.Debug|ARM.Build.0 = Debug|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.Debug|iPhone.Build.0 = Debug|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.Debug|x64.ActiveCfg = Debug|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.Debug|x64.Build.0 = Debug|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.Debug|x86.ActiveCfg = Debug|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.Debug|x86.Build.0 = Debug|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.Release|Any CPU.Build.0 = Release|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.Release|ARM.ActiveCfg = Release|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.Release|ARM.Build.0 = Release|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.Release|iPhone.ActiveCfg = Release|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.Release|iPhone.Build.0 = Release|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.Release|x64.ActiveCfg = Release|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.Release|x64.Build.0 = Release|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.Release|x86.ActiveCfg = Release|Any CPU
{E3B18084-842C-4B80-8E4A-A7E588EC3137}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -939,5 +989,6 @@ Global
{02DF7FEE-C302-433D-A6CD-237A2569F236} = {91CF7717-08AB-4E65-B10E-0B426F01E2E8}
{A579E108-5445-403D-A407-339AC4D1611B} = {02DF7FEE-C302-433D-A6CD-237A2569F236}
{621E7211-58D0-45FD-9600-1CB490BD930E} = {EF0337F2-ED00-4643-89FD-EE10863F1870}
{E3B18084-842C-4B80-8E4A-A7E588EC3137} = {B7B1D395-4E06-4036-BE86-C216756B9367}
EndGlobalSection
EndGlobal

+ 3
- 0
src/Mobile/eShopOnContainers/eShopOnContainers.Core/GlobalSettings.cs View File

@ -44,6 +44,8 @@
public string IdentityCallback { get; set; }
public string LogoutCallback { get; set; }
private void UpdateEndpoint(string baseEndpoint)
{
RegisterWebsite = string.Format("{0}/Account/Register", baseEndpoint);
@ -54,6 +56,7 @@
UserInfoEndpoint = string.Format("{0}:5105/connect/userinfo", baseEndpoint);
LogoutEndpoint = string.Format("{0}:5105/connect/endsession", baseEndpoint);
IdentityCallback = "http://eshopxamarin/callback.html";
LogoutCallback = "http://eshopxamarin/callback.html/index.html";
}
}
}

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

@ -21,7 +21,9 @@ namespace eShopOnContainers.Core.Helpers
#region Setting Constants
private const string AccessToken = "access_token";
private const string IdToken = "id_token";
private static readonly string AccessTokenDefault = string.Empty;
private static readonly string IdTokenDefault = string.Empty;
#endregion
@ -37,5 +39,17 @@ namespace eShopOnContainers.Core.Helpers
AppSettings.AddOrUpdateValue<string>(AccessToken, value);
}
}
public static string AuthIdToken
{
get
{
return AppSettings.GetValueOrDefault<string>(IdToken, IdTokenDefault);
}
set
{
AppSettings.AddOrUpdateValue<string>(IdToken, value);
}
}
}
}

+ 6
- 1
src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Identity/IdentityService.cs View File

@ -35,10 +35,15 @@ namespace eShopOnContainers.Core.Services.Identity
public string CreateLogoutRequest(string token)
{
if(string.IsNullOrEmpty(token))
{
return string.Empty;
}
return string.Format("{0}?id_token_hint={1}&post_logout_redirect_uri={2}",
GlobalSetting.Instance.LogoutEndpoint,
token,
GlobalSetting.Instance.IdentityCallback);
GlobalSetting.Instance.LogoutCallback);
}
public string DecodeToken(string token)


+ 0
- 5
src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/Base/ViewModelLocator.cs View File

@ -63,11 +63,6 @@ namespace eShopOnContainers.ViewModels.Base
public void UpdateDependencies(bool useMockServices)
{
// Clear message subscriptions
var basketViewModel = _unityContainer.Resolve<BasketViewModel>();
MessagingCenter.Unsubscribe<CatalogViewModel, List<BasketItem>>(basketViewModel, MessengerKeys.UpdateBasket);
MessagingCenter.Unsubscribe<CatalogViewModel, CatalogItem>(basketViewModel, MessengerKeys.AddProduct);
// Change injected dpendencies
if (useMockServices)
{


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

@ -65,9 +65,13 @@ namespace eShopOnContainers.Core.ViewModels
public ICommand AddCommand => new Command<BasketItem>(AddItem);
public ICommand CheckoutCommand => new Command(Checkout);
public override Task InitializeAsync(object navigationData)
{
if (BasketItems == null)
BasketItems = new ObservableCollection<BasketItem>();
MessagingCenter.Unsubscribe<CatalogViewModel, List<BasketItem>>(this, MessengerKeys.UpdateBasket);
MessagingCenter.Subscribe<CatalogViewModel, List<BasketItem>>(this, MessengerKeys.UpdateBasket, (sender, arg) =>
{
foreach (var basketItem in arg)
@ -77,6 +81,7 @@ namespace eShopOnContainers.Core.ViewModels
}
});
MessagingCenter.Unsubscribe<CatalogViewModel, CatalogItem>(this, MessengerKeys.AddProduct);
MessagingCenter.Subscribe<CatalogViewModel, CatalogItem>(this, MessengerKeys.AddProduct, (sender, arg) =>
{
BadgeCount++;
@ -84,8 +89,6 @@ namespace eShopOnContainers.Core.ViewModels
AddCatalogItem(arg);
});
BasketItems = new ObservableCollection<BasketItem>();
return base.InitializeAsync(navigationData);
}


+ 3
- 0
src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/CatalogViewModel.cs View File

@ -100,6 +100,7 @@ namespace eShopOnContainers.Core.ViewModels
{
IsBusy = true;
// Get Catalog, Brands and Types
Products = await _productsService.GetCatalogAsync();
Brands = await _productsService.GetCatalogBrandAsync();
Types = await _productsService.GetCatalogTypeAsync();
@ -107,6 +108,7 @@ namespace eShopOnContainers.Core.ViewModels
var authToken = Settings.AuthAccessToken;
var userInfo = await _userService.GetUserInfoAsync(authToken);
// Update Basket
var basket = await _basketService.GetBasketAsync(userInfo.UserId, authToken);
if (basket != null && basket.Items.Any())
@ -131,6 +133,7 @@ namespace eShopOnContainers.Core.ViewModels
IsBusy = true;
// Filter
MessagingCenter.Send(this, MessengerKeys.Filter);
Products = await _productsService.FilterAsync(Brand.Id, Type.Id);


+ 27
- 8
src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/CheckoutViewModel.cs View File

@ -74,6 +74,7 @@ namespace eShopOnContainers.Core.ViewModels
{
IsBusy = true;
// Get navigation data
var orderItems = ((ObservableCollection<BasketItem>)navigationData);
OrderItems = orderItems;
@ -81,6 +82,7 @@ namespace eShopOnContainers.Core.ViewModels
var authToken = Settings.AuthAccessToken;
var userInfo = await _userService.GetUserInfoAsync(authToken);
// Create Shipping Address
ShippingAddress = new Address
{
Id = new Guid(userInfo.UserId),
@ -91,6 +93,7 @@ namespace eShopOnContainers.Core.ViewModels
City = string.Empty
};
// Create Payment Info
var paymentInfo = new PaymentInfo
{
CardNumber = userInfo?.CardNumber,
@ -99,6 +102,7 @@ namespace eShopOnContainers.Core.ViewModels
SecurityNumber = userInfo?.CardSecurityNumber
};
// Create new Order
Order = new Order
{
BuyerId = userInfo.UserId,
@ -123,17 +127,32 @@ namespace eShopOnContainers.Core.ViewModels
private async void Checkout()
{
var authToken = Settings.AuthAccessToken;
try
{
var authToken = Settings.AuthAccessToken;
// Create new order
await _orderService.CreateOrderAsync(Order, authToken);
// Clean Basket
await _basketService.ClearBasketAsync(_shippingAddress.Id.ToString(), authToken);
await _orderService.CreateOrderAsync(Order, authToken);
// Reset Basket badge
var basketViewModel = ViewModelLocator.Instance.Resolve<BasketViewModel>();
basketViewModel.BadgeCount = 0;
await _basketService.ClearBasketAsync(_shippingAddress.Id.ToString(), authToken);
await NavigationService.NavigateToAsync<MainViewModel>(new TabParameter { TabIndex = 1 });
await NavigationService.RemoveLastFromBackStackAsync();
// Navigate to Orders
await NavigationService.NavigateToAsync<MainViewModel>(new TabParameter { TabIndex = 1 });
await NavigationService.RemoveLastFromBackStackAsync();
await DialogService.ShowAlertAsync("Order sent successfully!", string.Format("Order {0}", Order.OrderNumber), "Ok");
await NavigationService.RemoveLastFromBackStackAsync();
// Show Dialog
await DialogService.ShowAlertAsync("Order sent successfully!", string.Format("Order {0}", Order.OrderNumber), "Ok");
await NavigationService.RemoveLastFromBackStackAsync();
}
catch
{
await DialogService.ShowAlertAsync("An error ocurred. Please, try again.", "Oops!", "Ok");
}
}
private List<OrderItem> CreateOrderItems(ObservableCollection<BasketItem> basketItems)


+ 14
- 7
src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/LoginViewModel.cs View File

@ -190,7 +190,6 @@ namespace eShopOnContainers.Core.ViewModels
IsValid = true;
IsLogin = true;
IsBusy = false;
}
@ -201,28 +200,36 @@ namespace eShopOnContainers.Core.ViewModels
private void Logout()
{
var token = Settings.AuthAccessToken;
var logoutRequest = _identityService.CreateLogoutRequest(token);
var authIdToken = Settings.AuthIdToken;
var logoutRequest = _identityService.CreateLogoutRequest(authIdToken);
if(!string.IsNullOrEmpty(logoutRequest))
{
// Logout
LoginUrl = logoutRequest;
Settings.AuthAccessToken = string.Empty;
IsLogin = true;
}
}
private async void NavigateAsync(string url)
{
if (url.Contains(GlobalSetting.Instance.IdentityCallback))
if (url.Equals(GlobalSetting.Instance.LogoutCallback))
{
Settings.AuthAccessToken = string.Empty;
Settings.AuthIdToken = string.Empty;
IsLogin = false;
LoginUrl = _identityService.CreateAuthorizeRequest();
}
else if (url.Contains(GlobalSetting.Instance.IdentityCallback))
{
var authResponse = new AuthorizeResponse(url);
if (!string.IsNullOrWhiteSpace(authResponse.AccessToken))
{
if(authResponse.AccessToken != null)
if (authResponse.AccessToken != null)
{
Settings.AuthAccessToken = authResponse.AccessToken;
Settings.AuthIdToken = authResponse.IdentityToken;
await NavigationService.NavigateToAsync<MainViewModel>();
await NavigationService.RemoveLastFromBackStackAsync();


+ 1
- 0
src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/MainViewModel.cs View File

@ -17,6 +17,7 @@ namespace eShopOnContainers.Core.ViewModels
if (navigationData is TabParameter)
{
// Change selected application tab
var tabIndex = ((TabParameter)navigationData).TabIndex;
MessagingCenter.Send(this, MessengerKeys.ChangeTab, tabIndex);
}


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

@ -45,11 +45,10 @@ namespace eShopOnContainers.Core.ViewModels
var order = navigationData as Order;
// Get order detail info
var authToken = Settings.AuthAccessToken;
Order = await _ordersService.GetOrderAsync(Convert.ToInt32(order.OrderNumber), authToken);
// TODO: Change Mock Order Service
IsBusy = false;
}
}


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

@ -3,7 +3,6 @@ using eShopOnContainers.Core.Helpers;
using eShopOnContainers.Core.Models.Orders;
using eShopOnContainers.Core.Models.User;
using eShopOnContainers.Core.Services.Order;
using eShopOnContainers.Core.ViewModels.Base;
using eShopOnContainers.ViewModels.Base;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
@ -41,6 +40,7 @@ namespace eShopOnContainers.Core.ViewModels
{
IsBusy = true;
// Get orders
var authToken = Settings.AuthAccessToken;
var orders = await _orderService.GetOrdersAsync(authToken);
Orders = orders.ToObservableCollection();
@ -52,6 +52,7 @@ namespace eShopOnContainers.Core.ViewModels
{
IsBusy = true;
// Logout
await NavigationService.NavigateToAsync<LoginViewModel>(new LogoutParameter { Logout = true });
await NavigationService.RemoveBackStackAsync();


+ 1
- 0
src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/SettingsViewModel.cs View File

@ -96,6 +96,7 @@ namespace eShopOnContainers.Core.ViewModels
private void UpdateEndpoint(string endpoint)
{
// Update remote endpoint
GlobalSetting.Instance.BaseEndpoint = endpoint;
}
}

+ 15
- 0
src/Mobile/eShopOnContainers/eShopOnContainers.Droid/Activities/MainActivity.cs View File

@ -5,6 +5,10 @@ using Android.Views;
using Xamarin.Forms.Platform.Android;
using FFImageLoading.Forms.Droid;
using Acr.UserDialogs;
using Android.Content;
using Android.Runtime;
using FFImageLoading;
using System;
namespace eShopOnContainers.Droid.Activities
{
@ -41,6 +45,17 @@ namespace eShopOnContainers.Droid.Activities
window.AddFlags(WindowManagerFlags.DrawsSystemBarBackgrounds);
window.SetStatusBarColor(Android.Graphics.Color.Rgb(0, 166, 156));
}
/// <summary>
/// FFImageLoading image service preserves in heap memory of the device every image newly downloaded
/// from url. In order to avoid application crash, you should reclaim memory in low memory situations.
/// </summary>
public override void OnTrimMemory([GeneratedEnum] TrimMemory level)
{
ImageService.Instance.InvalidateMemoryCache();
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
base.OnTrimMemory(level);
}
}
}

+ 1
- 1
src/Mobile/eShopOnContainers/eShopOnContainers.Droid/Properties/AndroidManifest.xml View File

@ -2,5 +2,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="auto">
<uses-sdk android:minSdkVersion="15" />
<uses-permission android:name="android.permission.INTERNET" />
<application android:label="eShopOnContainers" android:icon="@drawable/icon"></application>
<application android:label="eShopOnContainers" android:icon="@drawable/icon" android:largeHeap="true"></application>
</manifest>

+ 5866
- 39
src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.Droid/Resources/Resource.Designer.cs
File diff suppressed because it is too large
View File


Loading…
Cancel
Save