Skip to content

Commit

Permalink
A bit of clean up
Browse files Browse the repository at this point in the history
  • Loading branch information
IEvangelist committed Apr 6, 2022
1 parent ee6f6ae commit fa1962b
Show file tree
Hide file tree
Showing 12 changed files with 180 additions and 174 deletions.
7 changes: 7 additions & 0 deletions blazorators.sln
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Blazor.SpeechRecognition.We
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Blazor.SpeechRecognition", "src\Blazor.SpeechRecognition\Blazor.SpeechRecognition.csproj", "{7FB98CAE-0CDB-4EF8-B9BB-6C51D62252CD}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Blazor.Permissions.WebAssembly", "src\Blazor.Permissions.WebAssembly\Blazor.Permissions.WebAssembly.csproj", "{FD387378-9B27-4852-8A77-684C33FDE844}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -113,6 +115,10 @@ Global
{7FB98CAE-0CDB-4EF8-B9BB-6C51D62252CD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7FB98CAE-0CDB-4EF8-B9BB-6C51D62252CD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7FB98CAE-0CDB-4EF8-B9BB-6C51D62252CD}.Release|Any CPU.Build.0 = Release|Any CPU
{FD387378-9B27-4852-8A77-684C33FDE844}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FD387378-9B27-4852-8A77-684C33FDE844}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FD387378-9B27-4852-8A77-684C33FDE844}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FD387378-9B27-4852-8A77-684C33FDE844}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -132,6 +138,7 @@ Global
{CC36EFCE-CB59-4541-9E1E-2DBE5D1C290E} = {537EB83C-6982-40B0-801A-479DF3B17DBE}
{F8BC87F2-8864-49F8-B4C2-75662BEBB045} = {537EB83C-6982-40B0-801A-479DF3B17DBE}
{7FB98CAE-0CDB-4EF8-B9BB-6C51D62252CD} = {537EB83C-6982-40B0-801A-479DF3B17DBE}
{FD387378-9B27-4852-8A77-684C33FDE844} = {537EB83C-6982-40B0-801A-479DF3B17DBE}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {3F86284A-32D2-4F79-B23C-7A0CB8775971}
Expand Down
9 changes: 7 additions & 2 deletions samples/Blazor.ExampleConsumer/Pages/ListenToMe.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ namespace Blazor.ExampleConsumer.Pages;

public sealed partial class ListenToMe : IAsyncDisposable
{
IDisposable? _recognitionSubscription;
bool _isRecognizingSpeech = false;
SpeechRecognitionErrorEvent? _errorEvent;
SpeechRecognitionErrorEvent? _errorEvent;
string? _transcript;

[Inject]
Expand All @@ -29,7 +30,9 @@ void OnRecognizeSpeechClick()
else
{
var bcp47Tag = CurrentUICulture.Name;
SpeechRecognition.RecognizeSpeech(

_recognitionSubscription?.Dispose();
_recognitionSubscription = SpeechRecognition.RecognizeSpeech(
bcp47Tag,
OnRecognized,
OnError,
Expand Down Expand Up @@ -72,5 +75,7 @@ public async ValueTask DisposeAsync()
{
await SpeechRecognition.DisposeAsync();
}

_recognitionSubscription?.Dispose();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>true</ImplicitUsings>
<Description>Source generated JavaScript interop for the browser's permissions API compatible with Blazor WebAssembly.</Description>
<Copyright>Copyright © David Pine. All rights reserved. Licensed under the MIT License.</Copyright>
<NeutralLanguage>en-US</NeutralLanguage>
<CurrentDate>$([System.DateTime]::Now.ToString(yyyyMMdd))</CurrentDate>
<ClientVersion Condition=" '$(IsPreview)' != 'true' ">$(ClientOfficialVersion)</ClientVersion>
<ClientVersion Condition=" '$(IsPreview)' == 'true' ">$(ClientPreviewVersion)</ClientVersion>
<VersionSuffix Condition=" '$(IsNightly)' == 'true' ">nightly-$(CurrentDate)</VersionSuffix>
<VersionSuffix Condition=" '$(IsPreview)' == 'true' ">preview</VersionSuffix>
<Version Condition=" '$(VersionSuffix)' == '' ">$(ClientVersion)</Version>
<Version Condition=" '$(VersionSuffix)' != '' ">$(ClientVersion)-$(VersionSuffix)</Version>
<FileVersion>$(ClientVersion)</FileVersion>
<Authors>David Pine</Authors>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<AssemblyName>Blazor.Permissions.WebAssembly</AssemblyName>
<Title>A C# source-generated class library implementation of the native browser's permissions API available as IJSInProcessRuntime extension methods.</Title>
<PackageId>Blazor.Permissions.WebAssembly</PackageId>
<PackageTags>dotnet;dotnetcore;csharp;blazor;webassembly;wasm;generators;sourcegen;roslyn;</PackageTags>
<PackageReleaseNotes></PackageReleaseNotes>
<PackageProjectUrl>https://github.com/IEvangelist/blazorators</PackageProjectUrl>
<PublishRepositoryUrl Condition=" '$(ProjectRef)' != 'True' ">true</PublishRepositoryUrl>
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<PlatformTarget>AnyCPU</PlatformTarget>
<ShippingScope>External</ShippingScope>
<SigningType>Product</SigningType>
<DebugType>embedded</DebugType>
<IncludeSymbols>false</IncludeSymbols>
<IncludeSource>false</IncludeSource>
<RootNamespace>Blazor.Permissions.WebAssembly</RootNamespace>
<NoWarn>NU5125;NU5039;</NoWarn>
<Optimize Condition="'$(Configuration)'=='Release'">true</Optimize>
<RepositoryUrl>https://github.com/IEvangelist/blazorators</RepositoryUrl>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<RepositoryType>git</RepositoryType>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
<PackageReadmeFile>README.md</PackageReadmeFile>
<IsPackable>true</IsPackable>
<PackageIcon>logo.png</PackageIcon>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="MinVer" Version="2.5.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Primitives" Version="6.0.0" />
<PackageReference Include="Microsoft.JSInterop" Version="6.0.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Blazor.SourceGenerators\Blazor.SourceGenerators.csproj" OutputItemType="Analyzer" SetTargetFramework="TargetFramework=netstandard2.0" ReferenceOutputAssembly="false" />
</ItemGroup>

<ItemGroup Label="Files">
<None Include="..\..\LICENSE" Pack="true" PackagePath="\" />
<None Include="README.md" Pack="true" PackagePath="\" />
<None Include="..\..\logo.png" Pack="true" PackagePath="\" />
</ItemGroup>

</Project>
10 changes: 10 additions & 0 deletions src/Blazor.Permissions.WebAssembly/IPermissionsService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Microsoft.JSInterop;

/// <summary></summary>
[JSAutoInterop(
TypeName = "Permissions",
Implementation = "window.navigator.permissions",
Url = "https://developer.mozilla.org/en-US/docs/Web/API/Navigator/permissions")]
public partial interface IPermissionsService
{
}
78 changes: 78 additions & 0 deletions src/Blazor.Permissions.WebAssembly/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Blazorators: The Source Generated `sessionStorage` JavaScript Interop library for Blazor WebAssembly

The [`Blazor.SessionStorage.WebAssembly`](https://www.nuget.org/packages/Blazor.SessionStorage.WebAssembly) package consumes the [`Blazor.SourceGenerators`](https://www.nuget.org/packages/Blazor.SourceGenerators) package. It exposes a source generated `IStorageService` interface specific to Blazor WebAssembly and the [`sessionStorage`](https://developer.mozilla.org/docs/Web/API/Window/sessionStorage) Web API.

## Get started

After the NuGet package is added as a reference, call the `AddSessionStorageServices` method to register the `ISessionStorageService` service type.

```csharp
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");

builder.Services.AddScoped(
sp => new HttpClient
{
BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)
});

builder.Services.AddSessionStorageServices();

await builder.Build().RunAsync();
```

Anywhere needed within your Razor component, or Blazor client code — either `@inject` or `[Inject]` the `ISessionStorageService` type. The interface takes the following shape:

```csharp
using Blazor.Serialization.Extensions;
using System.Text.Json;

#nullable enable
namespace Microsoft.JSInterop;

/// <summary>
/// Source generated interface definition of the <c>Storage</c> type.
/// </summary>
public interface ISessionStorageService
{
/// <summary>
/// Source generated implementation of <c>window.sessionStorage.clear</c>.
/// <a href="https://developer.mozilla.org/docs/Web/API/Storage/clear"></a>
/// </summary>
void Clear();

/// <summary>
/// Source generated implementation of <c>window.sessionStorage.getItem</c>.
/// <a href="https://developer.mozilla.org/docs/Web/API/Storage/getItem"></a>
/// </summary>
TResult? GetItem<TResult>(string key, JsonSerializerOptions? options = null);

/// <summary>
/// Source generated implementation of <c>window.sessionStorage.key</c>.
/// <a href="https://developer.mozilla.org/docs/Web/API/Storage/key"></a>
/// </summary>
string? Key(double index);

/// <summary>
/// Source generated implementation of <c>window.sessionStorage.removeItem</c>.
/// <a href="https://developer.mozilla.org/docs/Web/API/Storage/removeItem"></a>
/// </summary>
void RemoveItem(string key);

/// <summary>
/// Source generated implementation of <c>window.sessionStorage.setItem</c>.
/// <a href="https://developer.mozilla.org/docs/Web/API/Storage/setItem"></a>
/// </summary>
void SetItem<TArg>(string key, TArg value, JsonSerializerOptions? options = null);

/// <summary>
/// Source generated implementation of <c>window.sessionStorage.length</c>.
/// <a href="https://developer.mozilla.org/docs/Web/API/Storage/length"></a>
/// </summary>
double Length { get; }
}
```
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,9 @@ internal sealed class DefaultSpeechRecognitionService : ISpeechRecognitionServic

SpeechRecognitionSubject? _speechRecognition;
IJSInProcessObjectReference? _speechRecognitionModule;

public DefaultSpeechRecognitionService(
IJSInProcessRuntime javaScript) =>
_javaScript = javaScript;
IJSInProcessRuntime javaScript) => _javaScript = javaScript;

void InitializeSpeechRecognitionSubject()
{
Expand Down Expand Up @@ -56,24 +55,6 @@ void ISpeechRecognitionService.CancelSpeechRecognition(
InteropMethodIdentifiers.JavaScript.CancelSpeechRecognition,
isAborted);

/// <inheritdoc />
void ISpeechRecognitionService.RecognizeSpeech<TComponent>(
TComponent component,
string language,
string onResultCallbackMethodName,
string? onStartCallbackMethodName,
string? onEndCallbackMethodName,
string? onErrorCallbackMethodName) =>
_speechRecognitionModule?.InvokeVoid(
InteropMethodIdentifiers.JavaScript.RecognizeSpeech,
DotNetObjectReference.Create<TComponent>(component),
language,
Guid.Empty,
onResultCallbackMethodName,
onErrorCallbackMethodName,
onStartCallbackMethodName,
onEndCallbackMethodName);

/// <inheritdoc />
IDisposable ISpeechRecognitionService.RecognizeSpeech(
string language,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,37 +24,6 @@ public interface ISpeechRecognitionService : IAsyncDisposable
/// </param>
void CancelSpeechRecognition(bool isAborted);

/// <summary>
/// Starts the speech recognition process. Callbacks will be invoked on
/// the <paramref name="component"/> for the given method names.
/// </summary>
/// <typeparam name="TComponent">The consuming component (or object).</typeparam>
/// <param name="component">The calling Razor (or Blazor) component.</param>
/// <param name="language">The BCP47 language tag.</param>
/// <param name="onResultCallbackMethodName">
/// Expects the name of a <c>"JSInvokableAttribute"</c> C# method with the
/// following <see cref="Action{String, SpeechRecognitionResult}"/> signature.
/// </param>
/// <param name="onErrorCallbackMethodName">
/// Expects the name of a <c>"JSInvokableAttribute"</c> C# method with the
/// following <see cref="Action{String, SpeechRecognitionErrorEvent}"/> signature.
/// </param>
/// <param name="onStartCallbackMethodName">
/// Expects the name of a <c>"JSInvokableAttribute"</c> C# method with the
/// following <see cref="Action{String}"/>.
/// </param>
/// <param name="onEndCallbackMethodName">
/// Expects the name of a <c>"JSInvokableAttribute"</c> C# method with the
/// following <see cref="Action{String}"/> signature.
/// </param>
void RecognizeSpeech<TComponent>(
TComponent component,
string language,
string onResultCallbackMethodName,
string? onErrorCallbackMethodName = null,
string? onStartCallbackMethodName = null,
string? onEndCallbackMethodName = null) where TComponent : class;

/// <summary>
/// Starts the speech recognition process. Returns an <see cref="IDisposable"/>
/// that acts as the subscription. The various callbacks are invoked as they occur,
Expand Down
31 changes: 0 additions & 31 deletions src/Blazor.SpeechRecognition.WebAssembly/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,37 +51,6 @@ public interface ISpeechRecognitionService : IAsyncDisposable
/// </param>
void CancelSpeechRecognition(bool isAborted);

/// <summary>
/// Starts the speech recognition process. Callbacks will be invoked on
/// the <paramref name="component"/> for the given method names.
/// </summary>
/// <typeparam name="TComponent">The consuming component (or object).</typeparam>
/// <param name="component">The calling Razor (or Blazor) component.</param>
/// <param name="language">The BCP47 language tag.</param>
/// <param name="onResultCallbackMethodName">
/// Expects the name of a <c>"JSInvokableAttribute"</c> C# method with the
/// following <see cref="Action{String, SpeechRecognitionResult}"/> signature.
/// </param>
/// <param name="onErrorCallbackMethodName">
/// Expects the name of a <c>"JSInvokableAttribute"</c> C# method with the
/// following <see cref="Action{String, SpeechRecognitionErrorEvent}"/> signature.
/// </param>
/// <param name="onStartCallbackMethodName">
/// Expects the name of a <c>"JSInvokableAttribute"</c> C# method with the
/// following <see cref="Action{String}"/>.
/// </param>
/// <param name="onEndCallbackMethodName">
/// Expects the name of a <c>"JSInvokableAttribute"</c> C# method with the
/// following <see cref="Action{String}"/> signature.
/// </param>
void RecognizeSpeech<TComponent>(
TComponent component,
string language,
string onResultCallbackMethodName,
string? onErrorCallbackMethodName = null,
string? onStartCallbackMethodName = null,
string? onEndCallbackMethodName = null) where TComponent : class;

/// <summary>
/// Starts the speech recognition process. Returns an <see cref="IDisposable"/>
/// that acts as the subscription. The various callbacks are invoked as they occur,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
/**
* Cancels any active speech recognition session,
* considered best practice to properly clean up.
* @param {any} isAborted
* @param {boolean} isAborted
*/
export const cancelSpeechRecognition = (isAborted) => {
if (_recognition !== null) {
Expand All @@ -21,7 +21,7 @@ export const cancelSpeechRecognition = (isAborted) => {
* all the callbacks for the given dotnetObj in context.
* @param {any} dotnetObj
* @param {string} lang The BCP47 tag for the language.
* @param {string} key The used for round-trip verification and read-reciepts.
* @param {string} key Used for round-trip verification and callback-receipts.
* @param {string} onResultMethodName The callback to call for incremental recognition results.
* @param {string | null} onErrorMethodName The optional callback to call in the event of an recognition error.
* @param {string | null} onStartMethodName The optional callback to call when recognition started.
Expand Down Expand Up @@ -74,7 +74,6 @@ export const recognizeSpeech =
_recognition.start();
};

// Prevent client from speaking when user closes tab or window.
window.addEventListener('beforeunload', _ => {
cancelSpeechRecognition(true);
});
24 changes: 0 additions & 24 deletions src/Blazor.SpeechRecognition/DefaultSpeechRecognitionService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,30 +57,6 @@ await module.InvokeVoidAsync(
}
}

/// <inheritdoc />
async Task ISpeechRecognitionService.RecognizeSpeechAsync<TComponent>(
TComponent component,
string language,
string onResultCallbackMethodName,
string? onStartCallbackMethodName,
string? onEndCallbackMethodName,
string? onErrorCallbackMethodName)
{
var module = await _speechRecognitionModule.Value;
if (module is not null)
{
await module.InvokeVoidAsync(
InteropMethodIdentifiers.JavaScript.RecognizeSpeech,
DotNetObjectReference.Create<TComponent>(component),
language,
Guid.Empty,
onResultCallbackMethodName,
onErrorCallbackMethodName,
onStartCallbackMethodName,
onEndCallbackMethodName);
}
}

/// <inheritdoc />
async Task<IDisposable> ISpeechRecognitionService.RecognizeSpeechAsync(
string language,
Expand Down
Loading

0 comments on commit fa1962b

Please sign in to comment.