Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release/5.0 #239

Merged
merged 11 commits into from
Jan 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@ state combined with the changes expected for the action.

* [State, actions, and reducers](../Tutorials/02-Blazor/02A-StateActionsReducersTutorial/README.md)
* [Effects](../Tutorials/02-Blazor/02B-EffectsTutorial/README.md)
* [Middleware](../Tutorials/02-Blazor/02C-MiddlewareTutorial/README.md)
* [Redux Dev Tools](../Tutorials/02-Blazor/02D-ReduxDevToolsTutorial/README.md)
2 changes: 1 addition & 1 deletion Docs/disposable-callback-not-disposed.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# DisposableCallback was not disposed

Components that descend from `FluxorComponent` or `FluxorLayout` automatically subscribe to the
`StateChanged` event on every `IState<T>` property in the component automatically. When the component
`StateChanged` event on every `IState<TState>` and `IStateSelection<TState, TValue>` property in the component automatically. When the component
is disposed, this subscription is removed, to avoid memory leaks.

If ever you see an error message like the following
Expand Down
7 changes: 7 additions & 0 deletions Docs/releases.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Releases

## New in 5.0
* **Breaking change**: Removed need to reference `_content/Fluxor.Blazor.Web/scripts/index.js` ([#235](https://github.com/mrpmorris/Fluxor/issues/235))
* **Breaking change**: Removed `IState<TState>` generic `StateChanged` event.
* Separated `IDispatcher` out of `IStore`. ([#209](https://github.com/mrpmorris/Fluxor/issues/209))
* Added `IState<TState>` alternative `IStateSelector<TState, TValue>` for selecting and subscribing to subsets of state. ([#221](https://github.com/mrpmorris/Fluxor/issues/221))
* Made actions that are a generic type human readable in ReduxDevTools. ([#205](https://github.com/mrpmorris/Fluxor/issues/205))

## New in 4.2.1
* Support .NET 6

Expand Down
8 changes: 3 additions & 5 deletions Source/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
<Project>

<PropertyGroup>

<Version>4.2.1</Version>
<AssemblyVersion>4.2.1.0</AssemblyVersion>
<FileVersion>4.2.1.0</FileVersion>
<Version>5.0.0</Version>
<AssemblyVersion>5.0.0.0</AssemblyVersion>
<FileVersion>5.0.0.0</FileVersion>

<Authors>Peter Morris</Authors>
<Company />
Expand Down
20 changes: 18 additions & 2 deletions Source/Fluxor.Blazor.Web.ReduxDevTools/ActionInfo.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;

namespace Fluxor.Blazor.Web.ReduxDevTools
{
Expand All @@ -11,11 +13,25 @@ internal class ActionInfo

public ActionInfo(object action)
{
if (action == null)
if (action is null)
throw new ArgumentNullException(nameof(action));

type = $"{action.GetType().Name} {action.GetType().Namespace}";
type = $"{GetTypeDisplayName(action.GetType())}, {action.GetType().Namespace}";
Payload = action;
Console.WriteLine("TYPE = " + type);
}

public static string GetTypeDisplayName(Type type)
{
if (!type.IsGenericType)
return type.Name;

string name = type.GetGenericTypeDefinition().Name;
name = name.Remove(name.IndexOf('`'));
IEnumerable<string> genericTypes = type
.GetGenericArguments()
.Select(GetTypeDisplayName);
return $"{name}<{string.Join(",", genericTypes)}>";
}
}
}
Original file line number Diff line number Diff line change
@@ -1,39 +1,32 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">

<PropertyGroup>

<TargetFrameworks>netstandard2.0;netstandard2.1;netcoreapp3.1;net5.0;net6.0</TargetFrameworks>
<RazorLangVersion>3.0</RazorLangVersion>

<Product>ReduxDevTools for Fluxor Blazor (Web)</Product>
<Description>Middleware link from a Blazor (Web) Fluxor store to the Redux Dev Tools browser extension for Chrome.</Description>
<PackageIcon>fluxor-blazor-reduxdevtools-small.png</PackageIcon>
<PackageTags>Redux Flux DotNet CSharp Blazor RazorComponents ReduxDevTools</PackageTags>

</PropertyGroup>

<PropertyGroup>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<TargetFrameworks>netstandard2.0;netstandard2.1;netcoreapp3.1;net5.0;net6.0</TargetFrameworks>
<LangVersion>9</LangVersion>
<RazorLangVersion>3.0</RazorLangVersion>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components" Version="3.1.8" />
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="3.1.8" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
</ItemGroup>


<ItemGroup>
<ProjectReference Include="..\Fluxor.Blazor.Web\Fluxor.Blazor.Web.csproj" />
<ProjectReference Include="..\Fluxor\Fluxor.csproj" />
</ItemGroup>


<ItemGroup>
<None Include="..\..\Images\fluxor-blazor-reduxdevtools-small.png">
<Pack>True</Pack>
<PackagePath></PackagePath>
</None>
</ItemGroup>

</Project>
12 changes: 6 additions & 6 deletions Source/Fluxor.Blazor.Web.ReduxDevTools/ReduxDevToolsInterop.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,22 +75,22 @@ public async Task DevToolsCallback(string messageAsJson)

case "COMMIT":
Func<Task> commit = OnCommit;
if (commit != null)
if (commit is not null)
{
Task task = commit();
if (task != null)
if (task is not null)
await task;
}
break;

case "JUMP_TO_STATE":
case "JUMP_TO_ACTION":
Func<JumpToStateCallback, Task> jumpToState = OnJumpToState;
if (jumpToState != null)
if (jumpToState is not null)
{
var callbackInfo = JsonSerialization.Deserialize<JumpToStateCallback>(messageAsJson);
Task task = jumpToState(callbackInfo);
if (task != null)
if (task is not null)
await task;
}
break;
Expand All @@ -107,7 +107,7 @@ void IDisposable.Dispose()
}

private static bool IsDotNetReferenceObject(object x) =>
(x != null)
(x is not null)
&& (x.GetType().IsGenericType)
&& (x.GetType().GetGenericTypeDefinition() == typeof(DotNetObjectReference<>));

Expand All @@ -117,7 +117,7 @@ private ValueTask<TResult> InvokeFluxorDevToolsMethodAsync<TResult>(string ident
return new ValueTask<TResult>(default(TResult));


if (args != null && args.Length > 0)
if (args is not null && args.Length > 0)
{
for (int i = 0; i < args.Length; i++)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public ReduxDevToolsMiddleware(
public override string GetClientScripts() => ReduxDevToolsInterop.GetClientScripts(Options);

/// <see cref="IMiddleware.InitializeAsync(IStore)"/>
public async override Task InitializeAsync(IStore store)
public async override Task InitializeAsync(IDispatcher dispatcher, IStore store)
{
Store = store;
await ReduxDevToolsInterop.InitializeAsync(GetState());
Expand Down
4 changes: 2 additions & 2 deletions Source/Fluxor.Blazor.Web/Components/FluxorComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace Fluxor.Blazor.Web.Components
{
/// <summary>
/// A component that auto-subscribes to state changes on all <see cref="IState"/> properties
/// A component that auto-subscribes to state changes on all <see cref="IStateChangedNotifier"/> properties
/// and ensures <see cref="ComponentBase.StateHasChanged"/> is called
/// </summary>
public abstract class FluxorComponent : ComponentBase, IDisposable
Expand Down Expand Up @@ -76,7 +76,7 @@ protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (StateSubscription == null)
if (StateSubscription is null)
throw new NullReferenceException(ErrorMessages.ForgottenToCallBaseOnInitialized);

StateSubscription.Dispose();
Expand Down
4 changes: 2 additions & 2 deletions Source/Fluxor.Blazor.Web/Components/FluxorLayout.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace Fluxor.Blazor.Web.Components
{
/// <summary>
/// A layout that auto-subscribes to state changes on all <see cref="IState"/> properties
/// A layout that auto-subscribes to state changes on all <see cref="IStateChangedNotifier"/> properties
/// and ensures <see cref="LayoutComponentBase.StateHasChanged"/> is called
/// </summary>
public abstract class FluxorLayout : LayoutComponentBase, IDisposable
Expand Down Expand Up @@ -75,7 +75,7 @@ protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (StateSubscription == null)
if (StateSubscription is null)
throw new NullReferenceException(ErrorMessages.ForgottenToCallBaseOnInitialized);

StateSubscription.Dispose();
Expand Down
12 changes: 5 additions & 7 deletions Source/Fluxor.Blazor.Web/Fluxor.Blazor.Web.csproj
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">

<PropertyGroup>

<TargetFrameworks>netstandard2.0;netstandard2.1;netcoreapp3.1;net5.0;net6.0</TargetFrameworks>
<RazorLangVersion>3.0</RazorLangVersion>

<Product>Fluxor for Blazor (Web)</Product>
<Description>A zero boilerplate Redux/Flux framework for Blazor</Description>
<PackageIcon>fluxor-blazor-logo-small.png</PackageIcon>
<PackageTags>Redux Flux DotNet CSharp Blazor RazorComponents</PackageTags>
</PropertyGroup>

<PropertyGroup>
<TargetFrameworks>netstandard2.0;netstandard2.1;netcoreapp3.1;net5.0;net6.0</TargetFrameworks>
<LangVersion>9</LangVersion>
<RazorLangVersion>3.0</RazorLangVersion>
</PropertyGroup>

<ItemGroup>
Expand All @@ -21,12 +21,10 @@
<ProjectReference Include="..\Fluxor\Fluxor.csproj" />
</ItemGroup>


<ItemGroup>
<None Include="..\..\Images\fluxor-blazor-logo-small.png">
<Pack>True</Pack>
<PackagePath></PackagePath>
</None>
</ItemGroup>

</Project>
2 changes: 1 addition & 1 deletion Source/Fluxor.Blazor.Web/Middlewares/Routing/Effects.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public Effects(NavigationManager navigationManager)
}

[EffectMethod]
public Task HandleGoActionAsync(GoAction action, IDispatcher dispatcher)
public Task HandleGoActionAsync(GoAction action, IDispatcher _)
{
Uri fullUri = NavigationManager.ToAbsoluteUri(action.NewUri);
if (fullUri.ToString() != NavigationManager.Uri || action.ForceLoad)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ internal class RoutingMiddleware : Middleware
{
private readonly NavigationManager NavigationManager;
private readonly IFeature<RoutingState> Feature;
private IStore Store;
private IDispatcher Dispatcher;

/// <summary>
/// Creates a new instance of the routing middleware
Expand All @@ -27,25 +27,25 @@ public RoutingMiddleware(NavigationManager navigationManager, IFeature<RoutingSt
}

/// <see cref="IMiddleware.InitializeAsync(IStore)"/>
public override Task InitializeAsync(IStore store)
public override Task InitializeAsync(IDispatcher dispatcher, IStore store)
{
Store = store;
Dispatcher = dispatcher;
// If the URL changed before we initialized then dispatch an action
Store.Dispatch(new GoAction(NavigationManager.Uri));
Dispatcher.Dispatch(new GoAction(NavigationManager.Uri));
return Task.CompletedTask;
}

/// <see cref="Middleware.OnInternalMiddlewareChangeEnding"/>
protected override void OnInternalMiddlewareChangeEnding()
{
if (Feature.State.Uri != NavigationManager.Uri && Feature.State.Uri != null)
if (Feature.State.Uri != NavigationManager.Uri && Feature.State.Uri is not null)
NavigationManager.NavigateTo(Feature.State.Uri);
}

private void LocationChanged(object sender, LocationChangedEventArgs e)
{
if (Store != null && !IsInsideMiddlewareChange && e.Location != Feature.State.Uri)
Store.Dispatch(new GoAction(e.Location));
if (Dispatcher is not null && !IsInsideMiddlewareChange && e.Location != Feature.State.Uri)
Dispatcher.Dispatch(new GoAction(e.Location));
}
}
}
48 changes: 16 additions & 32 deletions Source/Fluxor.Blazor.Web/StoreInitializer.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using Fluxor.Exceptions;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Rendering;
using Microsoft.JSInterop;
using System;
using System.Linq;
Expand All @@ -23,7 +22,7 @@ public class StoreInitializer : ComponentBase, IDisposable
[Inject]
private IJSRuntime JSRuntime { get; set; }

private string Scripts;
private string MiddlewareInitializationScripts;
private bool Disposed;
private Exception ExceptionToThrow;

Expand All @@ -37,37 +36,23 @@ protected override void OnInitialized()
var webMiddlewares = Store.GetMiddlewares().OfType<IWebMiddleware>();

var scriptBuilder = new StringBuilder();
scriptBuilder.AppendLine("<script id='initializeFluxor'>");
foreach (IWebMiddleware middleware in webMiddlewares)
{
foreach (IWebMiddleware middleware in webMiddlewares)
string script = middleware.GetClientScripts();
if (script is not null)
{
string script = middleware.GetClientScripts();
if (script != null)
{
scriptBuilder.AppendLine($"// Middleware scripts: {middleware.GetType().FullName}");
scriptBuilder.AppendLine(script);
}
scriptBuilder.AppendLine($"// Middleware scripts: {middleware.GetType().FullName}");
scriptBuilder.AppendLine(script);
}
}
scriptBuilder.AppendLine("</script>");
Scripts = scriptBuilder.ToString();
MiddlewareInitializationScripts = scriptBuilder.ToString();
base.OnInitialized();
}

/// <summary>
/// Renders the supporting JavaScript for any Middleware
/// </summary>
/// <param name="builder">The builder</param>
protected override void BuildRenderTree(RenderTreeBuilder builder)
{
base.BuildRenderTree(builder);
builder.AddMarkupContent(0, Scripts);
}

protected override void OnAfterRender(bool firstRender)
{
base.OnAfterRender(firstRender);
if (ExceptionToThrow != null)
if (ExceptionToThrow is not null)
{
Exception exception = ExceptionToThrow;
ExceptionToThrow = null;
Expand All @@ -85,9 +70,8 @@ protected override async Task OnAfterRenderAsync(bool firstRender)
{
try
{
bool success = await JSRuntime.InvokeAsync<bool>("tryInitializeFluxor");
if (!success)
throw new StoreInitializationException("Failed to initialize store");
if (!string.IsNullOrWhiteSpace(MiddlewareInitializationScripts))
await JSRuntime.InvokeVoidAsync("eval", MiddlewareInitializationScripts);

await Store.InitializeAsync();
}
Expand Down Expand Up @@ -115,23 +99,23 @@ protected virtual void Dispose(bool disposing)
Store.UnhandledException -= OnUnhandledException;
}

private void OnUnhandledException(object sender, Exceptions.UnhandledExceptionEventArgs args)
private void OnUnhandledException(object sender, Exceptions.UnhandledExceptionEventArgs e)
{
InvokeAsync(async () =>
{
Exception exceptionThrownInHandler = null;
try
{
await UnhandledException.InvokeAsync(args).ConfigureAwait(false);
await UnhandledException.InvokeAsync(e).ConfigureAwait(false);
}
catch (Exception e)
catch (Exception exception)
{
exceptionThrownInHandler = e;
exceptionThrownInHandler = exception;
}

if (exceptionThrownInHandler != null || !args.WasHandled)
if (exceptionThrownInHandler is not null || !e.WasHandled)
{
ExceptionToThrow = exceptionThrownInHandler ?? args.Exception;
ExceptionToThrow = exceptionThrownInHandler ?? e.Exception;
StateHasChanged();
}
});
Expand Down
Loading