Skip to content

Commit 25b22c6

Browse files
committed
Merge branch 'MediaElementOptionService' of https://github.com/ne0rrmatrix/MauiOld into MediaElementOptionService
2 parents 178e8ae + cecaf32 commit 25b22c6

File tree

57 files changed

+857
-345
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+857
-345
lines changed

.github/prompts/dotnet/codestyle.prompt.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,7 @@ This guide provides a set of best practices and coding standards for writing C#
581581

582582
### Element Positioning
583583

584-
Please adhere to [Style Cop SA1201](https://docs.github.com/en/copilot/using-github-copilot/code-review/configuring-coding-guidelines#creating-a-coding-guideline) for organizing code in a file.
584+
Please adhere to [Style Cop SA1201](https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1201.md) for organizing code in a file.
585585

586586
Elements at the file root level or within a namespace should be positioned in the following order:
587587

@@ -609,4 +609,4 @@ Indexers
609609
Methods
610610
Records
611611
Structs
612-
Classes
612+
Classes

.github/workflows/dotnet-build.yml

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -287,26 +287,25 @@ jobs:
287287
name: packages
288288
path: ./packages
289289

290-
- name: Remove MediaElement package if that is not being released
291-
if: startsWith(github.ref, 'refs/tags/') && !endsWith(github.ref, '-mediaelement')
290+
- name: Remove packages for MediaElement-only release
291+
if: startsWith(github.ref, 'refs/tags/') && endsWith(github.ref, '-mediaelement')
292292
run: |
293-
Get-ChildItem -Path "${{ github.workspace }}/packages" -Recurse -Filter "*.nupkg" | Where-Object { $_ -notmatch "CommunityToolkit.Maui.MediaElement" } | Remove-Item -Force
293+
Get-ChildItem -Path "${{ github.workspace }}/packages" -Recurse -Filter "*.nupkg" | Where-Object { $_.Name -notmatch "CommunityToolkit\.Maui\.MediaElement" } | Remove-Item -Force
294294
295-
- name: Remove Camera package if that is not being released
296-
if: startsWith(github.ref, 'refs/tags/') && !endsWith(github.ref, '-camera')
295+
- name: Remove packages for Camera-only release
296+
if: startsWith(github.ref, 'refs/tags/') && endsWith(github.ref, '-camera')
297297
run: |
298-
Get-ChildItem -Path "${{ github.workspace }}/packages" -Recurse -Filter "*.nupkg" | Where-Object { $_ -notmatch "CommunityToolkit.Maui.Camera" } | Remove-Item -Force
298+
Get-ChildItem -Path "${{ github.workspace }}/packages" -Recurse -Filter "*.nupkg" | Where-Object { $_.Name -notmatch "CommunityToolkit\.Maui\.Camera" } | Remove-Item -Force
299299
300-
- name: Remove Maps package if that is not being released
301-
if: startsWith(github.ref, 'refs/tags/') && !endsWith(github.ref, '-maps')
300+
- name: Remove packages for Maps-only release
301+
if: startsWith(github.ref, 'refs/tags/') && endsWith(github.ref, '-maps')
302302
run: |
303-
Get-ChildItem -Path "${{ github.workspace }}/packages" -Recurse -Filter "*.nupkg" | Where-Object { $_ -notmatch "CommunityToolkit.Maui.Maps" } | Remove-Item -Force
303+
Get-ChildItem -Path "${{ github.workspace }}/packages" -Recurse -Filter "*.nupkg" | Where-Object { $_.Name -notmatch "CommunityToolkit\.Maui\.Maps" } | Remove-Item -Force
304304
305-
- name: Remove Core & Main package if that is not being released
305+
- name: Remove packages for Core & Main release
306306
if: startsWith(github.ref, 'refs/tags/') && (!endsWith(github.ref, '-mediaelement') && !endsWith(github.ref, '-camera') && !endsWith(github.ref, '-maps'))
307307
run: |
308-
Get-ChildItem -Path "${{ github.workspace }}/packages" -Recurse -Filter "*.nupkg" | Where-Object { $_ -notmatch "CommunityToolkit.Maui" } | Remove-Item -Force
309-
Get-ChildItem -Path "${{ github.workspace }}/packages" -Recurse -Filter "*.nupkg" | Where-Object { $_ -notmatch "CommunityToolkit.Maui.Core" } | Remove-Item -Force
308+
Get-ChildItem -Path "${{ github.workspace }}/packages" -Recurse -Filter "*.nupkg" | Where-Object { $_.Name -match "CommunityToolkit\.Maui\.(Camera|MediaElement|Maps)" } | Remove-Item -Force
310309
311310
- name: Install Signing Tool
312311
run: dotnet tool install --tool-path ./tools sign --version 0.9.1-beta.23356.1
@@ -349,7 +348,7 @@ jobs:
349348
dotnet-version: ${{ env.TOOLKIT_NET_VERSION }}
350349
dotnet-quality: 'ga'
351350

352-
- name: Download signed packages for ${{ matrix.platform }}
351+
- name: Download signed packages
353352
uses: actions/download-artifact@v4
354353
with:
355354
name: signed-packages

Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
<NuGetAuditMode>all</NuGetAuditMode>
1717

1818
<!-- MAUI Specific -->
19-
<MauiPackageVersion>9.0.70</MauiPackageVersion>
19+
<MauiPackageVersion>9.0.80</MauiPackageVersion>
2020
<NextMauiPackageVersion>10.0.0</NextMauiPackageVersion>
2121
<MauiStrictXamlCompilation>true</MauiStrictXamlCompilation>
2222
<SkipValidateMauiImplicitPackageReferences>true</SkipValidateMauiImplicitPackageReferences>

samples/CommunityToolkit.Maui.Sample/Platforms/Windows/Package.appxmanifest

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757

5858
<Capabilities>
5959
<rescap:Capability Name="runFullTrust" />
60+
<DeviceCapability Name="microphone"/>
6061
</Capabilities>
6162

6263
</Package>

samples/CommunityToolkit.Maui.Sample/ViewModels/Essentials/SpeechToTextViewModel.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,9 @@
88

99
namespace CommunityToolkit.Maui.Sample.ViewModels.Essentials;
1010

11-
public partial class SpeechToTextViewModel : BaseViewModel
11+
public partial class SpeechToTextViewModel : BaseViewModel, IAsyncDisposable
1212
{
1313
const string defaultLanguage = "en-US";
14-
const string defaultLanguage_android = "en";
15-
const string defaultLanguage_tizen = "en_US";
1614

1715
readonly ITextToSpeech textToSpeech;
1816
readonly ISpeechToText speechToText;
@@ -55,7 +53,7 @@ async Task SetLocales(CancellationToken token)
5553
Locales.Add(locale);
5654
}
5755

58-
CurrentLocale = Locales.FirstOrDefault(x => x.Language is defaultLanguage or defaultLanguage_android or defaultLanguage_tizen) ?? Locales.FirstOrDefault();
56+
CurrentLocale = Locales.FirstOrDefault();
5957
}
6058

6159
[RelayCommand]
@@ -148,4 +146,9 @@ void HandleLocalesCollectionChanged(object? sender, NotifyCollectionChangedEvent
148146
{
149147
OnPropertyChanged(nameof(CurrentLocale));
150148
}
149+
150+
public async ValueTask DisposeAsync()
151+
{
152+
await speechToText.DisposeAsync();
153+
}
151154
}

src/CommunityToolkit.Maui.Analyzers.UnitTests/CommunityToolkit.Maui.Analyzers.UnitTests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
<!--Fix vulnerabilities-->
2929
<PackageReference Include="System.Formats.Asn1" Version="9.0.5" />
3030
<PackageReference Include="System.Net.Http" Version="4.3.4" />
31+
<PackageReference Include="System.Private.Uri" Version="4.3.2" />
3132
<PackageReference Include="System.Text.RegularExpressions" Version="4.3.1" />
3233
</ItemGroup>
3334

src/CommunityToolkit.Maui.Analyzers.UnitTests/UseCommunityToolkitCameraInitializationAnalyzerTests.cs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,43 @@ public static MauiApp CreateMauiApp()
118118
await VerifyCameraToolkitAnalyzer(source, Diagnostic().WithSpan(12, 4, 12, 61).WithSeverity(DiagnosticSeverity.Error));
119119
}
120120

121+
[Fact]
122+
public async Task VerifyNoErrorsWhenUseMauiCommunityToolkitCameraWrapInPreprocessorDirectives()
123+
{
124+
const string source =
125+
/* language=C#-test */
126+
//lang=csharp
127+
"""
128+
namespace CommunityToolkit.Maui.Analyzers.UnitTests
129+
{
130+
using Microsoft.Maui.Controls.Hosting;
131+
using Microsoft.Maui.Hosting;
132+
using CommunityToolkit.Maui;
133+
134+
public static class MauiProgram
135+
{
136+
public static MauiApp CreateMauiApp()
137+
{
138+
var builder = MauiApp.CreateBuilder();
139+
builder.UseMauiApp<Microsoft.Maui.Controls.Application>()
140+
#if ANDROID || IOS
141+
.UseMauiCommunityToolkitCamera()
142+
#endif
143+
.ConfigureFonts(fonts =>
144+
{
145+
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
146+
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
147+
});
148+
149+
return builder.Build();
150+
}
151+
}
152+
}
153+
""";
154+
155+
await VerifyCameraToolkitAnalyzer(source);
156+
}
157+
121158
static Task VerifyCameraToolkitAnalyzer(string source, params IReadOnlyList<DiagnosticResult> diagnosticResults)
122159
{
123160
return VerifyAnalyzerAsync(

src/CommunityToolkit.Maui.Analyzers.UnitTests/UseCommunityToolkitInitializationAnalyzerTests.cs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,79 @@ public static MauiApp CreateMauiApp()
118118
await VerifyMauiToolkitAnalyzer(source, Diagnostic().WithSpan(12, 4, 12, 61).WithSeverity(DiagnosticSeverity.Error));
119119
}
120120

121+
[Fact]
122+
public async Task VerifyNoErrorsWhenUseMauiCommunityToolkitWrapInPreprocessorDirectives()
123+
{
124+
const string source =
125+
/* language=C#-test */
126+
//lang=csharp
127+
"""
128+
namespace CommunityToolkit.Maui.Analyzers.UnitTests
129+
{
130+
using Microsoft.Maui.Controls.Hosting;
131+
using Microsoft.Maui.Hosting;
132+
using CommunityToolkit.Maui;
133+
134+
public static class MauiProgram
135+
{
136+
public static MauiApp CreateMauiApp()
137+
{
138+
var builder = MauiApp.CreateBuilder();
139+
builder.UseMauiApp<Microsoft.Maui.Controls.Application>()
140+
#if ANDROID || IOS
141+
.UseMauiCommunityToolkit()
142+
#endif
143+
.ConfigureFonts(fonts =>
144+
{
145+
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
146+
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
147+
});
148+
149+
return builder.Build();
150+
}
151+
}
152+
}
153+
""";
154+
155+
156+
await VerifyMauiToolkitAnalyzer(source);
157+
}
158+
159+
[Fact]
160+
public async Task VerifyErrorsWhenUseMauiCommunityToolkitIsCommentedOut()
161+
{
162+
const string source =
163+
/* language=C#-test */
164+
//lang=csharp
165+
"""
166+
namespace CommunityToolkit.Maui.Analyzers.UnitTests
167+
{
168+
using Microsoft.Maui.Controls.Hosting;
169+
using Microsoft.Maui.Hosting;
170+
using CommunityToolkit.Maui;
171+
172+
public static class MauiProgram
173+
{
174+
public static MauiApp CreateMauiApp()
175+
{
176+
var builder = MauiApp.CreateBuilder();
177+
builder.UseMauiApp<Microsoft.Maui.Controls.Application>()
178+
//.UseMauiCommunityToolkit()
179+
.ConfigureFonts(fonts =>
180+
{
181+
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
182+
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
183+
});
184+
185+
return builder.Build();
186+
}
187+
}
188+
}
189+
""";
190+
191+
await VerifyMauiToolkitAnalyzer(source, Diagnostic().WithSpan(12, 4, 12, 61).WithSeverity(DiagnosticSeverity.Error));
192+
}
193+
121194
static Task VerifyMauiToolkitAnalyzer(string source, params IReadOnlyList<DiagnosticResult> expected)
122195
{
123196
return VerifyAnalyzerAsync(

src/CommunityToolkit.Maui.Analyzers.UnitTests/UseCommunityToolkitMediaElementInitializationAnalyzerTests.cs

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using CommunityToolkit.Maui.MediaElement.Analyzers;
1+
using CommunityToolkit.Maui.Core;
2+
using CommunityToolkit.Maui.MediaElement.Analyzers;
23
using Microsoft.CodeAnalysis;
34
using Microsoft.CodeAnalysis.Testing;
45
using Xunit;
@@ -118,12 +119,49 @@ public static MauiApp CreateMauiApp()
118119
await VerifyMediaElementToolkitAnalyzer(source, Diagnostic().WithSpan(12, 4, 12, 61).WithSeverity(DiagnosticSeverity.Error));
119120
}
120121

122+
[Fact]
123+
public async Task VerifyNoErrorsWhenUseMauiCommunityToolkitMediaElementWrapInPreprocessorDirectives()
124+
{
125+
const string source =
126+
/* language=C#-test */
127+
//lang=csharp
128+
"""
129+
namespace CommunityToolkit.Maui.Analyzers.UnitTests
130+
{
131+
using Microsoft.Maui.Controls.Hosting;
132+
using Microsoft.Maui.Hosting;
133+
using CommunityToolkit.Maui;
134+
135+
public static class MauiProgram
136+
{
137+
public static MauiApp CreateMauiApp()
138+
{
139+
var builder = MauiApp.CreateBuilder();
140+
builder.UseMauiApp<Microsoft.Maui.Controls.Application>()
141+
#if ANDROID || IOS
142+
.UseMauiCommunityToolkitMediaElement()
143+
#endif
144+
.ConfigureFonts(fonts =>
145+
{
146+
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
147+
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
148+
});
149+
150+
return builder.Build();
151+
}
152+
}
153+
}
154+
""";
155+
156+
await VerifyMediaElementToolkitAnalyzer(source);
157+
}
158+
121159
static Task VerifyMediaElementToolkitAnalyzer(string source, params IReadOnlyList<DiagnosticResult> diagnosticResults)
122160
{
123161
return VerifyAnalyzerAsync(
124162
source,
125163
[
126-
typeof(Views.MediaElement) // CommunityToolkit.Maui.MediaElement
164+
typeof(MediaElementOptions) // CommunityToolkit.Maui.MediaElement
127165
],
128166
diagnosticResults);
129167
}

src/CommunityToolkit.Maui.Analyzers/UseCommunityToolkitInitializationAnalyzer.cs

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,13 @@ namespace CommunityToolkit.Maui.Analyzers;
1010
public class UseCommunityToolkitInitializationAnalyzer : DiagnosticAnalyzer
1111
{
1212
public const string DiagnosticId = "MCT001";
13-
1413
const string category = "Initialization";
1514
const string useMauiAppMethodName = "UseMauiApp";
1615
const string useMauiCommunityToolkitMethodName = "UseMauiCommunityToolkit";
1716

1817
static readonly LocalizableString title = new LocalizableResourceString(nameof(Resources.InitializationErrorTitle), Resources.ResourceManager, typeof(Resources));
1918
static readonly LocalizableString messageFormat = new LocalizableResourceString(nameof(Resources.InitalizationMessageFormat), Resources.ResourceManager, typeof(Resources));
2019
static readonly LocalizableString description = new LocalizableResourceString(nameof(Resources.InitializationErrorMessage), Resources.ResourceManager, typeof(Resources));
21-
2220
static readonly DiagnosticDescriptor rule = new(DiagnosticId, title, messageFormat, category, DiagnosticSeverity.Error, isEnabledByDefault: true, description: description);
2321

2422
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; } = [rule];
@@ -32,21 +30,42 @@ public override void Initialize(AnalysisContext context)
3230

3331
static void AnalyzeNode(SyntaxNodeAnalysisContext context)
3432
{
35-
if (context.Node is InvocationExpressionSyntax { Expression: MemberAccessExpressionSyntax { Name.Identifier.ValueText: useMauiAppMethodName } } invocationExpression)
33+
if (context.Node is InvocationExpressionSyntax invocationExpression
34+
&& invocationExpression.Expression is MemberAccessExpressionSyntax memberAccessExpression
35+
&& memberAccessExpression.Name.Identifier.ValueText == useMauiAppMethodName)
3636
{
37-
var root = invocationExpression.SyntaxTree.GetRoot();
38-
var methodDeclaration = root.FindNode(invocationExpression.FullSpan)
37+
var methodDeclaration = invocationExpression
3938
.Ancestors()
4039
.OfType<MethodDeclarationSyntax>()
4140
.FirstOrDefault();
4241

43-
if (methodDeclaration is not null
44-
&& !methodDeclaration.DescendantNodes().OfType<InvocationExpressionSyntax>().Any(static n =>
45-
n.Expression is MemberAccessExpressionSyntax { Name.Identifier.ValueText: useMauiCommunityToolkitMethodName }))
42+
if (methodDeclaration is not null && !HasUseMauiCommunityToolkitCall(methodDeclaration))
4643
{
4744
var diagnostic = Diagnostic.Create(rule, invocationExpression.GetLocation());
4845
context.ReportDiagnostic(diagnostic);
4946
}
5047
}
5148
}
49+
50+
static bool HasUseMauiCommunityToolkitCall(MethodDeclarationSyntax methodDeclaration)
51+
{
52+
// Check syntax nodes first (handles active code)
53+
var hasInSyntaxTree = methodDeclaration
54+
.DescendantNodes()
55+
.OfType<InvocationExpressionSyntax>()
56+
.Any(static invocation => invocation.Expression is MemberAccessExpressionSyntax memberAccess
57+
&& memberAccess.Name.Identifier.ValueText == useMauiCommunityToolkitMethodName);
58+
59+
if (hasInSyntaxTree)
60+
{
61+
return true;
62+
}
63+
64+
// Check trivia (comments, preprocessor directives, disabled code)
65+
return methodDeclaration
66+
.DescendantTrivia()
67+
.Any(static trivia =>
68+
trivia.IsKind(SyntaxKind.DisabledTextTrivia) &&
69+
trivia.ToString().Contains(useMauiCommunityToolkitMethodName, StringComparison.Ordinal));
70+
}
5271
}

0 commit comments

Comments
 (0)