Skip to content
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
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,23 @@ All notable changes to the MMCA.Common packages are documented here. The format
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versions follow [Semantic Versioning](https://semver.org/)
and are derived from git tags by MinVer (see [the published versioning policy](https://ivanball.github.io/docs/guides/common-VERSIONING.html)).

## [1.227.0] - 2026-10-04

### Added

- `RegistrationSettings` (`MMCA.Common.UI`, configuration section `Registration`, bound by `AddUIShared` like `LegalSettings`): `CollectAddress` (default `true`) shows the optional address block on the Register page; a host that stores no address sets it to `false`, which hides the block and skips its validation, so nothing is collected and then dropped.
- `NotificationScopeKey.MetadataKey` (`"scopeKey"`) and `NotificationHubService.NotificationFilter`: a scoped push carries its scope key in the live SignalR metadata, and `NotificationListener` uses the filter with `INotificationScopeProvider` so a notification for another scope (another event, another tenant) neither toasts nor bumps the badge. Unscoped sends and unscoped hosts behave as before.
- Login reads the `error` query parameter (`Login.Error`) that the OAuth completion redirect sets and shows a localized message in the page's alert (`Auth.Login.ExternalError.*`, English and Spanish), where a refused external sign-in used to land on a bare form.

### Fixed

- External sign-in with GitHub creates the account. `OAuthControllerBase` reads the display name from `urn:github:name` before `ClaimTypes.Name`, which GitHub maps to the login handle (never a space, so the split produced an empty last name and every first GitHub sign-up was refused with `User.LastName.Empty`). A missing or single-token name now falls back to the non-empty placeholder "User" for whichever part is absent.
- `TermsAcceptanceGate` keeps its consent dialog open across navigation (`CloseOnNavigation = false`). A list page rewrites its own URL right after it loads, and the dialog provider closed every open dialog on that `LocationChanged`, so consent was skipped for the rest of the session.
- The skip link in `MainLayout` stays on the current page: its href resolves against the current path rather than the base href (which navigated to the home page), the interactive click focuses the main region, and `#main-content` is focusable (`tabindex="-1"`). Nav links show a visible `:focus-visible` outline.
- `BiometricGate` signs out through `IAuthUIService.LogoutAsync`, so the auth state is notified and the read and local caches are cleared; it only cleared the tokens, leaving the UI signed in with the previous session's cached data.
- MAUI capability services keep their null/false contracts on any platform failure: `MauiSpeechToTextService`, `MauiShareService`, `MauiScreenshotService` and `MauiMediaPickerService` catch every non-cancellation exception (they caught a few named types, so anything else surfaced as an unhandled error). Speech recognition starts and stops on the main thread, which Android's recognizer requires.
- `QrCodeImage` shrinks to its container (`max-width: 100%; height: auto`), so a large QR code is no longer clipped on a phone.

## [1.226.0] - 2026-10-04

### Added
Expand Down
1 change: 1 addition & 0 deletions Source/Core/MMCA.Common.Shared/PublicAPI.Shipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1077,3 +1077,4 @@ virtual MMCA.Common.Shared.ValueObjects.ValueObject.PrintMembers(System.Text.Str
~override MMCA.Common.Shared.Concurrency.KeyedSemaphoreStripe.Releaser.ToString() -> string
~override MMCA.Common.Shared.Legal.AcceptLegalTermsRequest.Equals(object obj) -> bool
~override MMCA.Common.Shared.Legal.AcceptLegalTermsRequest.ToString() -> string
const MMCA.Common.Shared.Notifications.NotificationScopeKey.MetadataKey = "scopeKey" -> string!
1 change: 0 additions & 1 deletion Source/Core/MMCA.Common.Shared/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
#nullable enable
const MMCA.Common.Shared.Notifications.NotificationScopeKey.MetadataKey = "scopeKey" -> string!
9 changes: 9 additions & 0 deletions Source/Presentation/MMCA.Common.UI/PublicAPI.Shipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1518,3 +1518,12 @@ virtual MMCA.Common.UI.Services.Api.EntityServiceBase<TEntityDTO, TIdentifierTyp
~override MMCA.Common.UI.Routes.BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder) -> void
~override MMCA.Common.UI.Theme.MmcaThemeProviders.BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder) -> void
~override MMCA.Common.UI.Theme.ThemeToggle.BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder) -> void
MMCA.Common.UI.Common.Settings.RegistrationSettings
MMCA.Common.UI.Common.Settings.RegistrationSettings.CollectAddress.get -> bool
MMCA.Common.UI.Common.Settings.RegistrationSettings.CollectAddress.set -> void
MMCA.Common.UI.Common.Settings.RegistrationSettings.RegistrationSettings() -> void
static readonly MMCA.Common.UI.Common.Settings.RegistrationSettings.SectionName -> string!
MMCA.Common.UI.Pages.Auth.Login.Error.get -> string?
MMCA.Common.UI.Pages.Auth.Login.Error.set -> void
MMCA.Common.UI.Services.Notifications.NotificationHubService.NotificationFilter.get -> System.Func<System.Collections.Generic.IReadOnlyDictionary<string!, string!>?, System.Threading.Tasks.Task<bool>!>?
MMCA.Common.UI.Services.Notifications.NotificationHubService.NotificationFilter.set -> void
9 changes: 0 additions & 9 deletions Source/Presentation/MMCA.Common.UI/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1 @@
#nullable enable
MMCA.Common.UI.Common.Settings.RegistrationSettings
MMCA.Common.UI.Common.Settings.RegistrationSettings.CollectAddress.get -> bool
MMCA.Common.UI.Common.Settings.RegistrationSettings.CollectAddress.set -> void
MMCA.Common.UI.Common.Settings.RegistrationSettings.RegistrationSettings() -> void
static readonly MMCA.Common.UI.Common.Settings.RegistrationSettings.SectionName -> string!
MMCA.Common.UI.Pages.Auth.Login.Error.get -> string?
MMCA.Common.UI.Pages.Auth.Login.Error.set -> void
MMCA.Common.UI.Services.Notifications.NotificationHubService.NotificationFilter.get -> System.Func<System.Collections.Generic.IReadOnlyDictionary<string!, string!>?, System.Threading.Tasks.Task<bool>!>?
MMCA.Common.UI.Services.Notifications.NotificationHubService.NotificationFilter.set -> void
Loading