Skip to content

Commit

Permalink
Added [JsonConverter(typeof(EnumMemberConverter<T>))] attribute to …
Browse files Browse the repository at this point in the history
…enum properties in most "options" classes to ensure that they are correctly serialized.

Changed `MapTypeControlStyle` from a class to an enum, and used the `EnumMember` attribute to force the serialization values.  Note - had to use 0, 1, and 2 instead of "DEFAULT", "HORIZONTAL_BAR", and "DROPDOWN_MENU" to get it to work.
Tidied up various xml comments throughout the codebase.
  • Loading branch information
Enritski committed Dec 19, 2023
1 parent 4014341 commit 32ffc89
Show file tree
Hide file tree
Showing 27 changed files with 286 additions and 223 deletions.
10 changes: 2 additions & 8 deletions GoogleMapsComponents/Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,11 @@ internal static Task MyInvokeAsync(
{
var enumType = typeof(T);

if (int.TryParse(str, out var enumintValue))
if (int.TryParse(str, out var enumIntValue))
{
return (T)Enum.Parse(enumType, enumintValue.ToString());
return (T)Enum.Parse(enumType, enumIntValue.ToString());
}


if (str == "null")
{
return null;
Expand Down Expand Up @@ -179,7 +178,6 @@ private static IEnumerable<object> MakeArgJsFriendly(IJSRuntime jsRuntime, IEnum
return enumItem.ToString();
}


var memberInfo = enumItem2.GetType().GetMember(enumItem2.ToString());
if (memberInfo.Length == 0)
{
Expand Down Expand Up @@ -250,7 +248,6 @@ internal static async Task<object> MyAddListenerAsync(
string identifier,
params object[] args)
{

var jsFriendlyArgs = MakeArgJsFriendly(jsRuntime, args);

return await jsRuntime.InvokeAsync<object>(identifier, jsFriendlyArgs);
Expand Down Expand Up @@ -279,7 +276,6 @@ internal static async Task<OneOf<T, U>> MyInvokeAsync<T, U>(
if (jsonElement.ValueKind == JsonValueKind.Number)
{
json = jsonElement.GetRawText();

}
else if (jsonElement.ValueKind == JsonValueKind.String)
{
Expand All @@ -297,14 +293,12 @@ internal static async Task<OneOf<T, U>> MyInvokeAsync<T, U>(
result = json ?? "";
return (T)result;
}

}
else
{
json = jsonElement.GetString();
}


var propArray = Helper.DeSerializeObject<Dictionary<string, object>>(json);
if (propArray?.TryGetValue("dotnetTypeName", out var typeName) ?? false)
{
Expand Down
10 changes: 5 additions & 5 deletions GoogleMapsComponents/Maps/ControlPosition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
namespace GoogleMapsComponents.Maps;

/// <summary>
/// Identifiers used to specify the placement of controls on the map.
/// Controls are positioned relative to other controls in the same layout position.
/// Controls that are added first are positioned closer to the edge of the map.
/// Identifiers used to specify the placement of controls on the map.<br/>
/// Controls are positioned relative to other controls in the same layout position.<br/>
/// Controls that are added first are positioned closer to the edge of the map.
/// </summary>
[JsonConverter(typeof(JsonStringEnumConverter))]
public enum ControlPosition
Expand All @@ -18,14 +18,14 @@ public enum ControlPosition
BottomCenter,

/// <summary>
/// Elements are positioned in the bottom left and flow towards the middle.
/// Elements are positioned in the bottom left and flow towards the middle.<br/>
/// Elements are positioned to the right of the Google logo.
/// </summary>
[EnumMember(Value = "BOTTOM_LEFT")]
BottomLeft,

/// <summary>
/// Elements are positioned in the bottom right and flow towards the middle.
/// Elements are positioned in the bottom right and flow towards the middle.<br/>
/// Elements are positioned to the left of the copyrights.
/// </summary>
[EnumMember(Value = "BOTTOM_RIGHT")]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
namespace GoogleMapsComponents.Maps.Controls;
using System.Text.Json.Serialization;

namespace GoogleMapsComponents.Maps.Controls;

public class MotionTrackingControlOptions
{
/// <summary>
/// Position id. Used to specify the position of the control on the map.<br/>
/// The default position is <c>RightBottom</c>.
/// </summary>
[JsonConverter(typeof(EnumMemberConverter<ControlPosition>))]
public ControlPosition Position { get; set; }
}
25 changes: 12 additions & 13 deletions GoogleMapsComponents/Maps/Extension/CircleList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,11 @@
namespace GoogleMapsComponents.Maps.Extension;

/// <summary>
/// A class able to manage a lot of Circle objects and get / set their
/// properties at the same time, eventually with different values
/// Main concept is that each Circle to can be distinguished by other ones need
/// to have a "unique key" with a "external world mean", so not necessary it's GUID
///
/// All properties should be called With a Dictionary<string, {property type}> indicating for each Circle(related to that key) the corresponding related property value
/// <para>A class able to manage a lot of Circle objects and get / set their
/// properties at the same time, eventually with different values.<br/>
/// Main concept is that for each Circle to be distinguished from other ones, it needs
/// to have a "unique key" with an "external world meaning", so not necessarily a GUID</para>
/// <para>All properties should be called With a <c>Dictionary&lt;string, {property type}&gt;</c> indicating for each Circle (related to that key) the corresponding related property value</para>
/// </summary>
public class CircleList : ListableEntityListBase<Circle, CircleOptions>
{
Expand All @@ -22,8 +21,8 @@ public class CircleList : ListableEntityListBase<Circle, CircleOptions>
/// Create circles list
/// </summary>
/// <param name="jsRuntime"></param>
/// <param name="opts">Dictionary of desired Circle keys and CircleOptions values. Key as any type unique key. Not nessary Guid</param>
/// <returns>new instance of CircleList class will be returned with its Circles dictionary member populated with the corresponding results</returns>
/// <param name="opts">Dictionary of desired Circle keys and CircleOptions values. Key as any type unique key. Not necessarily Guid</param>
/// <returns>New instance of CircleList class will be returned with its Circles dictionary member populated with the corresponding results</returns>
public static async Task<CircleList> CreateAsync(IJSRuntime jsRuntime, Dictionary<string, CircleOptions> opts)
{
var jsObjectRef = new JsObjectRef(jsRuntime, Guid.NewGuid());
Expand All @@ -40,7 +39,7 @@ public static async Task<CircleList> CreateAsync(IJSRuntime jsRuntime, Dictionar
}

/// <summary>
/// Sync list over lifetime: Create and remove list depending on entity count;
/// Sync list over lifetime: Create and remove list depending on entity count;
/// entities will be removed, added or changed to mirror the given set.
/// </summary>
/// <param name="list">
Expand Down Expand Up @@ -110,7 +109,7 @@ public async Task AddMultipleAsync(Dictionary<string, CircleOptions> opts)

public Task<Dictionary<string, LatLngBoundsLiteral>> GetBounds(List<string>? filterKeys = null)
{
var matchingKeys = ComputeMathingKeys(filterKeys);
var matchingKeys = ComputeMatchingKeys(filterKeys);

if (matchingKeys.Any())
{
Expand All @@ -129,7 +128,7 @@ public Task<Dictionary<string, LatLngBoundsLiteral>> GetBounds(List<string>? fil

public Task<Dictionary<string, LatLngLiteral>> GetCenters(List<string>? filterKeys = null)
{
var matchingKeys = ComputeMathingKeys(filterKeys);
var matchingKeys = ComputeMatchingKeys(filterKeys);

if (matchingKeys.Any())
{
Expand All @@ -148,7 +147,7 @@ public Task<Dictionary<string, LatLngLiteral>> GetCenters(List<string>? filterKe

public Task<Dictionary<string, bool>> GetEditables(List<string>? filterKeys = null)
{
var matchingKeys = ComputeMathingKeys(filterKeys);
var matchingKeys = ComputeMatchingKeys(filterKeys);

if (matchingKeys.Any())
{
Expand All @@ -167,7 +166,7 @@ public Task<Dictionary<string, bool>> GetEditables(List<string>? filterKeys = nu

public Task<Dictionary<string, double>> GetRadiuses(List<string>? filterKeys = null)
{
var matchingKeys = ComputeMathingKeys(filterKeys);
var matchingKeys = ComputeMatchingKeys(filterKeys);

if (matchingKeys.Any())
{
Expand Down
10 changes: 4 additions & 6 deletions GoogleMapsComponents/Maps/Extension/ListableEntityListBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ protected ListableEntityListBase(JsObjectRef jsObjectRef, Dictionary<string, TEn
BaseListableEntities = baseListableEntities;
}



/// <summary>
/// Set the set of entities; entities will be removed, added or changed to mirror the given set.
/// </summary>
Expand Down Expand Up @@ -186,7 +184,7 @@ public virtual async Task RemoveMultipleAsync(List<Guid> guids)
//Find the eventual match between required keys (if any) and yet stored markers key (if any)
//If filterKeys is null or empty all keys are returned
//Otherwise only eventually yet stored marker keys that matches with filterKeys
protected virtual List<string> ComputeMathingKeys(List<string>? filterKeys = null)
protected virtual List<string> ComputeMatchingKeys(List<string>? filterKeys = null)
{
List<string> matchingKeys;

Expand Down Expand Up @@ -222,7 +220,7 @@ protected virtual Task<Dictionary<string, T>> ComputeEmptyResult<T>()

public virtual Task<Dictionary<string, Map>> GetMaps(List<string>? filterKeys = null)
{
List<string> matchingKeys = ComputeMathingKeys(filterKeys);
List<string> matchingKeys = ComputeMatchingKeys(filterKeys);

if (matchingKeys.Any())
{
Expand All @@ -242,7 +240,7 @@ public virtual Task<Dictionary<string, Map>> GetMaps(List<string>? filterKeys =

public virtual Task<Dictionary<string, bool>> GetDraggables(List<string>? filterKeys = null)
{
List<string> matchingKeys = ComputeMathingKeys(filterKeys);
List<string> matchingKeys = ComputeMatchingKeys(filterKeys);

if (matchingKeys.Any())
{
Expand All @@ -262,7 +260,7 @@ public virtual Task<Dictionary<string, bool>> GetDraggables(List<string>? filter

public virtual Task<Dictionary<string, bool>> GetVisibles(List<string>? filterKeys = null)
{
List<string> matchingKeys = ComputeMathingKeys(filterKeys);
List<string> matchingKeys = ComputeMatchingKeys(filterKeys);

if (matchingKeys.Any())
{
Expand Down
66 changes: 47 additions & 19 deletions GoogleMapsComponents/Maps/Extension/MarkerList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,41 @@
namespace GoogleMapsComponents.Maps.Extension;

/// <summary>
/// A class able to manage a lot of Marker objects and get / set their
/// properties at the same time, eventually with different values
/// Main concept is that each Marker to can be distinguished by other ones need
/// to have a "unique key" with a "external world mean", so not necessary it's GUID
///
/// All properties should be called with a Dictionary<string, {property type}> indicating for each Marker(related to that key) the corresponding related property value
/// <para>
/// A class able to manage a lot of Marker objects and get / set their properties at the same time, eventually with different values
/// </para>
/// <para>
/// Main concept is that for each Marker to be distinguished from other ones, it needs
/// to have a "unique key" with an "external world meaning", so not necessarily a GUID.
/// </para>
/// <para>
/// In real cases Markers are likely to be linked to places, activities, transit stops and so on -> So, what better way to choose as Marker "unique key" the "id" of the object each marker is related to?
/// A string key has been selected as type due to its implicit versatility.
/// </para>
/// <para>
/// To create Markers, simply call <c>MarkerList.CreateAsync</c> with a Dictionary of desired Marker keys and MarkerOptions values.
/// After that, a new instance of MarkerList class will be returned with its Markers dictionary member populated with the corresponding results
/// </para>
/// <para>
/// At run-time is possible to:<br/>
/// <list type="number">
/// <item><description>add Marker to the same MarkerList class using <c>AddMultipleAsync</c> method (only keys not matching with existent Marker keys will be created)<br/>
/// Markers dictionary will contain "union distinct" of existent Marker's keys and new keys</description>
/// </item>
/// <item><description>remove Marker from the MarkerList class (only Marker having keys matching with existent keys will be removed)<br/>
/// Markers dictionary will contain "original - required and found" Marker's keys (eventually any is all Marker are removed)</description>
/// </item>
/// </list>
/// </para>
/// <para>
/// Each definer getter properties can be used as follows:<br/>
/// a) without parameter -> all eventually defined markers related property will be returned (if any)<br/>
/// b) with a <c>List&lt;string&gt;</c> of keys -> all eventually matching keys with Markers Dictionary keys produces related markers property extraction (if any defined)
/// </para>
/// <para>
/// Each setter properties can be used as follows:<br/>
/// With a <c>Dictionary&lt;string, {property type}&gt;</c> indicating for each Marker (related to that key) the corresponding related property value.
/// </para>
/// </summary>
public class MarkerList : ListableEntityListBase<Marker, MarkerOptions>
{
Expand All @@ -23,8 +52,8 @@ public class MarkerList : ListableEntityListBase<Marker, MarkerOptions>
/// Create markers list
/// </summary>
/// <param name="jsRuntime"></param>
/// <param name="opts">Dictionary of desired Marker keys and MarkerOptions values. Key as any type unique key. Not nessary Guid</param>
/// <returns>new instance of MarkerList class will be returned with its Markers dictionary member populated with the corresponding results</returns>
/// <param name="opts">Dictionary of desired Marker keys and MarkerOptions values. Key as any type unique key. Not necessarily Guid</param>
/// <returns>New instance of MarkerList class will be returned with its Markers dictionary member populated with the corresponding results</returns>
public static async Task<MarkerList> CreateAsync(IJSRuntime jsRuntime, Dictionary<string, MarkerOptions> opts)
{
var jsObjectRef = new JsObjectRef(jsRuntime, Guid.NewGuid());
Expand Down Expand Up @@ -100,9 +129,8 @@ public async Task SetMultipleAsync(Dictionary<string, MarkerOptions> opts)
}

/// <summary>
/// only keys not matching with existent Marker keys will be created
/// Only keys not matching with existent Marker keys will be created
/// </summary>
/// <param name="opts"></param>
/// <returns></returns>
public async Task AddMultipleAsync(Dictionary<string, MarkerOptions> opts)
{
Expand All @@ -111,7 +139,7 @@ public async Task AddMultipleAsync(Dictionary<string, MarkerOptions> opts)

public Task<Dictionary<string, Animation>> GetAnimations(List<string>? filterKeys = null)
{
var matchingKeys = ComputeMathingKeys(filterKeys);
var matchingKeys = ComputeMatchingKeys(filterKeys);

if (matchingKeys.Any())
{
Expand All @@ -130,7 +158,7 @@ public Task<Dictionary<string, Animation>> GetAnimations(List<string>? filterKey

public Task<Dictionary<string, bool>> GetClickables(List<string>? filterKeys = null)
{
var matchingKeys = ComputeMathingKeys(filterKeys);
var matchingKeys = ComputeMatchingKeys(filterKeys);

if (matchingKeys.Any())
{
Expand All @@ -149,7 +177,7 @@ public Task<Dictionary<string, bool>> GetClickables(List<string>? filterKeys = n

public Task<Dictionary<string, string>> GetCursors(List<string>? filterKeys = null)
{
var matchingKeys = ComputeMathingKeys(filterKeys);
var matchingKeys = ComputeMatchingKeys(filterKeys);

if (matchingKeys.Any())
{
Expand All @@ -168,7 +196,7 @@ public Task<Dictionary<string, string>> GetCursors(List<string>? filterKeys = nu

public Task<Dictionary<string, OneOf<string, Icon, Symbol>>> GetIcons(List<string>? filterKeys = null)
{
var matchingKeys = ComputeMathingKeys(filterKeys);
var matchingKeys = ComputeMatchingKeys(filterKeys);

if (matchingKeys.Any())
{
Expand All @@ -187,7 +215,7 @@ public Task<Dictionary<string, OneOf<string, Icon, Symbol>>> GetIcons(List<strin

public Task<Dictionary<string, string>> GetLabels(List<string>? filterKeys = null)
{
var matchingKeys = ComputeMathingKeys(filterKeys);
var matchingKeys = ComputeMatchingKeys(filterKeys);

if (matchingKeys.Any())
{
Expand All @@ -206,7 +234,7 @@ public Task<Dictionary<string, string>> GetLabels(List<string>? filterKeys = nul

public Task<Dictionary<string, LatLngLiteral>> GetPositions(List<string>? filterKeys = null)
{
var matchingKeys = ComputeMathingKeys(filterKeys);
var matchingKeys = ComputeMatchingKeys(filterKeys);

if (matchingKeys.Any())
{
Expand All @@ -225,7 +253,7 @@ public Task<Dictionary<string, LatLngLiteral>> GetPositions(List<string>? filter

public Task<Dictionary<string, MarkerShape>> GetShapes(List<string>? filterKeys = null)
{
var matchingKeys = ComputeMathingKeys(filterKeys);
var matchingKeys = ComputeMatchingKeys(filterKeys);

if (matchingKeys.Any())
{
Expand All @@ -244,7 +272,7 @@ public Task<Dictionary<string, MarkerShape>> GetShapes(List<string>? filterKeys

public Task<Dictionary<string, string>> GetTitles(List<string>? filterKeys = null)
{
var matchingKeys = ComputeMathingKeys(filterKeys);
var matchingKeys = ComputeMatchingKeys(filterKeys);

if (matchingKeys.Any())
{
Expand All @@ -263,7 +291,7 @@ public Task<Dictionary<string, string>> GetTitles(List<string>? filterKeys = nul

public Task<Dictionary<string, int>> GetZIndexes(List<string>? filterKeys = null)
{
var matchingKeys = ComputeMathingKeys(filterKeys);
var matchingKeys = ComputeMatchingKeys(filterKeys);

if (matchingKeys.Any())
{
Expand Down
Loading

0 comments on commit 32ffc89

Please sign in to comment.