Skip to content
Open
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*.rsuser
*.suo
*.user
*.idea
*.userosscache
*.sln.docstates

Expand Down
3 changes: 2 additions & 1 deletion UndoAssessment/UndoAssessment.Android/MainActivity.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using System;

using Acr.UserDialogs;
using Android.App;
using Android.Content.PM;
using Android.Runtime;
Expand All @@ -16,6 +16,7 @@ protected override void OnCreate(Bundle savedInstanceState)

Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
UserDialogs.Init(this);
LoadApplication(new App());
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
Expand Down
5 changes: 5 additions & 0 deletions UndoAssessment/UndoAssessment/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using UndoAssessment.Services;
using UndoAssessment.Services.Api;
using UndoAssessment.Services.Dialogs;
using UndoAssessment.Services.Storage;
using UndoAssessment.Views;

namespace UndoAssessment
Expand All @@ -14,6 +17,8 @@ public App ()
InitializeComponent();

DependencyService.Register<MockDataStore>();
DependencyService.Register<TaskApiService>();
DependencyService.Register<UserDialogsService>();
MainPage = new AppShell();
}

Expand Down
1 change: 1 addition & 0 deletions UndoAssessment/UndoAssessment/AppShell.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
<TabBar>
<ShellContent Title="About" Icon="icon_about.png" Route="AboutPage" ContentTemplate="{DataTemplate local:AboutPage}" />
<ShellContent Title="Browse" Icon="icon_feed.png" ContentTemplate="{DataTemplate local:ItemsPage}" />
<ShellContent Title="Task" Icon="icon_feed.png" ContentTemplate="{DataTemplate local:TaskPage}" />
</TabBar>

<!--
Expand Down
6 changes: 2 additions & 4 deletions UndoAssessment/UndoAssessment/AppShell.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using UndoAssessment.ViewModels;
using UndoAssessment.Views;
using UndoAssessment.Views;
using Xamarin.Forms;

namespace UndoAssessment
Expand All @@ -13,6 +10,7 @@ public AppShell()
InitializeComponent();
Routing.RegisterRoute(nameof(ItemDetailPage), typeof(ItemDetailPage));
Routing.RegisterRoute(nameof(NewItemPage), typeof(NewItemPage));
Routing.RegisterRoute(nameof(UserDataFormPage), typeof(UserDataFormPage));
}

}
Expand Down
30 changes: 30 additions & 0 deletions UndoAssessment/UndoAssessment/Extensions/HttpExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System.Net.Http;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

namespace UndoAssessment.Extensions
{
public static class HttpExtensions
{
public static HttpRequestBuilder CreateRequest(this HttpClient client)
=> new HttpRequestBuilder(client);

public static HttpContent ToHttpContent(this object requestBody)
{
var result = default(HttpContent);

if (requestBody is HttpContent content)
{
result = content;
}
else
{
var jsonString = JsonConvert.SerializeObject(requestBody ?? new object(), new IsoDateTimeConverter());
result = new StringContent(jsonString, Encoding.UTF8, "application/json");
}

return result;
}
}
}
63 changes: 63 additions & 0 deletions UndoAssessment/UndoAssessment/Extensions/HttpRequestBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
using System;
using System.Diagnostics;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

namespace UndoAssessment.Extensions
{
public class HttpRequestBuilder
{
private readonly HttpClient _client;

private HttpRequestMessage _buildingRequest;
private CancellationToken _cancellationToken;

public HttpRequestBuilder(HttpClient client)
{
_client = client;

_buildingRequest = new HttpRequestMessage();
}

public HttpRequestBuilder ByResource(string address, string resource, params object[] parameters)
{
var url = address + string.Format(resource, parameters);
_buildingRequest.RequestUri = new Uri(url);
return this;
}

public HttpRequestBuilder WithMethod(HttpMethod method)
{
_buildingRequest.Method = method;
return this;
}

public HttpRequestBuilder WithContent(object content)
{
_buildingRequest.Content = content.ToHttpContent();
return this;
}

public HttpRequestBuilder WithHeader(string type, string val)
{
_buildingRequest.Headers.Add(type, val);
return this;
}

public async Task<HttpResponseMessage> MakeRequestAsync()
{
try
{
return await _client.SendAsync(_buildingRequest, _cancellationToken);
}
catch (Exception e)
{
if (Debugger.IsAttached)
Debugger.Break();
Console.WriteLine(e);
throw;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System.Net.Http;
using System.Threading.Tasks;

namespace UndoAssessment.Extensions
{
public static class HttpResponseMessageExtensions
{
public static async Task<T> ReadContentAsJsonAsync<T>(this Task<HttpResponseMessage> taskMessage)
=> await (await taskMessage).ReadContentAsJsonAsync<T>();

public static async Task<T> ReadContentAsJsonAsync<T>(this HttpResponseMessage message)
=> (await message.ReadAsStringAsync()).ParseAsJson<T>();

public static Task<string> ReadAsStringAsync(this HttpResponseMessage message)
=> message.Content.ReadAsStringAsync();
}
}
11 changes: 11 additions & 0 deletions UndoAssessment/UndoAssessment/Extensions/StringExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

namespace UndoAssessment.Extensions
{
public static class StringExtensions
{
public static T ParseAsJson<T>(this string str)
=> JsonConvert.DeserializeObject<T>(str, converters: new JsonConverter[] { new IsoDateTimeConverter() });
}
}
21 changes: 21 additions & 0 deletions UndoAssessment/UndoAssessment/Models/ApiResponse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System;

namespace UndoAssessment.Models
{
public class ApiResponse
{
public string Message { get; set; }
public DateTime Date { get; set; }
public int ErrorCode { get; set; }

public override string ToString()
{
var errorLine = ErrorCode > 0 ? $"ErrorCode: {ErrorCode}" : "";
return
$"Message: {Message}\n" +
$"Date: {Date.ToString()}\n" +
errorLine;

}
}
}
8 changes: 8 additions & 0 deletions UndoAssessment/UndoAssessment/Models/UserData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace UndoAssessment.Models
{
public class UserData
{
public string Name { get; set; }
public int Age { get; set; }
}
}
11 changes: 11 additions & 0 deletions UndoAssessment/UndoAssessment/Services/Api/IApiService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System.Threading.Tasks;
using UndoAssessment.Models;

namespace UndoAssessment.Services.Api
{
public interface IApiService
{
Task<ApiResponse> SuccessAsync();
Task<ApiResponse> ErrorAsync();
}
}
35 changes: 35 additions & 0 deletions UndoAssessment/UndoAssessment/Services/Api/TaskApiService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System.Net.Http;
using System.Threading.Tasks;
using UndoAssessment.Extensions;
using UndoAssessment.Models;

namespace UndoAssessment.Services.Api
{
public class TaskApiService : IApiService
{
private const string ApiEndpoint = "https://malkarakundostagingpublicapi.azurewebsites.net";

private readonly HttpClient _client;

public TaskApiService()
{
_client = new HttpClient();
}

public Task<ApiResponse> SuccessAsync()
=> _client
.CreateRequest()
.ByResource(ApiEndpoint, "/success")
.WithMethod(HttpMethod.Get)
.MakeRequestAsync()
.ReadContentAsJsonAsync<ApiResponse>();

public Task<ApiResponse> ErrorAsync()
=> _client
.CreateRequest()
.ByResource(ApiEndpoint, "/fail")
.WithMethod(HttpMethod.Get)
.MakeRequestAsync()
.ReadContentAsJsonAsync<ApiResponse>();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using System.Threading.Tasks;

namespace UndoAssessment.Services.Dialogs
{
public interface IDialogsService
{
Task AlertAsync(string title, string message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System.Threading.Tasks;
using Acr.UserDialogs;

namespace UndoAssessment.Services.Dialogs
{
public class UserDialogsService : IDialogsService
{
private readonly IUserDialogs _userDialogs;

public UserDialogsService()
{
_userDialogs = UserDialogs.Instance;
}

public Task AlertAsync(string title, string message)
{
return _userDialogs.AlertAsync(message, title);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace UndoAssessment.Services
namespace UndoAssessment.Services.Storage
{
public interface IDataStore<T>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
using System.Threading.Tasks;
using UndoAssessment.Models;

namespace UndoAssessment.Services
namespace UndoAssessment.Services.Storage
{
public class MockDataStore : IDataStore<Item>
{
Expand Down
2 changes: 2 additions & 0 deletions UndoAssessment/UndoAssessment/UndoAssessment.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Acr.UserDialogs" Version="7.2.0.564" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Xamarin.Forms" Version="5.0.0.2578" />
<PackageReference Include="Xamarin.Essentials" Version="1.7.6" />
</ItemGroup>
Expand Down
1 change: 1 addition & 0 deletions UndoAssessment/UndoAssessment/ViewModels/BaseViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

using UndoAssessment.Models;
using UndoAssessment.Services;
using UndoAssessment.Services.Storage;

namespace UndoAssessment.ViewModels
{
Expand Down
Loading