Public Access
Give the application a settings area built from what really exists
This commit is contained in:
@@ -107,6 +107,9 @@ internal sealed record VaultRowViewModel(
|
||||
};
|
||||
|
||||
internal bool HasState => State.Length > 0;
|
||||
|
||||
/// <summary>The single letter the settings page's card draws on this vault's tile.</summary>
|
||||
internal string Initial => Name.Length > 0 ? Name[..1].ToUpperInvariant() : "?";
|
||||
}
|
||||
|
||||
/// <summary>One member of a vault, as a row in the members table.</summary>
|
||||
@@ -153,6 +156,32 @@ internal sealed record VaultMemberRowViewModel(TeamMemberSummary Member, bool Is
|
||||
|
||||
internal bool CanBeRemoved => Member.Role != TeamMemberRole.Owner;
|
||||
|
||||
/// <summary>
|
||||
/// The two letters the members panel draws on this row's avatar.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The same rule <c>HostRowViewModel.Monogram</c> draws a card's monogram by — the first letters of the
|
||||
/// first two words in the name, or the first two characters where it is one word — except uppercase,
|
||||
/// which is how the design draws a person's initials rather than a host's.
|
||||
/// </remarks>
|
||||
internal string Initials
|
||||
{
|
||||
get
|
||||
{
|
||||
var words = Name.Split(
|
||||
InitialsWordSeparators,
|
||||
StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
|
||||
|
||||
var letters = words.Length >= 2
|
||||
? string.Concat(words[0][0], words[1][0])
|
||||
: Name.Length >= 2 ? Name[..2] : Name;
|
||||
|
||||
return letters.ToUpperInvariant();
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly char[] InitialsWordSeparators = [' ', '-', '_', '.'];
|
||||
|
||||
/// <summary>Whether this member's role can be changed at all.</summary>
|
||||
/// <remarks>
|
||||
/// The owner's cannot, and not for want of an endpoint: ownership is sole, so demoting them is
|
||||
@@ -312,6 +341,33 @@ internal sealed partial class VaultsViewModel(
|
||||
[ObservableProperty]
|
||||
private bool isBusy;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the members panel — v5c's settings-page overlay over the selected vault's people — is open.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Desktop-only presentation state, not a fact about any vault: it says which rectangle is on screen and
|
||||
/// nothing else. Selecting a vault is what actually reads its members, in
|
||||
/// <see cref="OnSelectedVaultChanged"/>; opening this panel over one already selected re-reads nothing.
|
||||
/// </remarks>
|
||||
[ObservableProperty]
|
||||
private bool isMembersPanelOpen;
|
||||
|
||||
/// <summary>Opens the members panel, selecting the vault it is about first if it is not selected already.</summary>
|
||||
[RelayCommand]
|
||||
private void OpenMembersPanel(VaultRowViewModel? vault)
|
||||
{
|
||||
if (vault is not null && !ReferenceEquals(vault, SelectedVault))
|
||||
{
|
||||
SelectedVault = vault;
|
||||
}
|
||||
|
||||
IsMembersPanelOpen = true;
|
||||
}
|
||||
|
||||
/// <summary>Closes the members panel.</summary>
|
||||
[RelayCommand]
|
||||
private void CloseMembersPanel() => IsMembersPanelOpen = false;
|
||||
|
||||
// ---- Creating a vault ----
|
||||
|
||||
[ObservableProperty]
|
||||
@@ -824,6 +880,38 @@ internal sealed partial class VaultsViewModel(
|
||||
Status = string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>Opens the rename form for a specific vault, from the settings page's per-card edit icon.</summary>
|
||||
/// <remarks>
|
||||
/// A thin wrapper around <see cref="RenameVault"/> rather than a second implementation: the settings
|
||||
/// page draws one card per vault with no list selection to lean on the way this screen used to have, so
|
||||
/// this selects the row first and then asks the command that already knows how to open the form.
|
||||
/// </remarks>
|
||||
/// <param name="vault">The vault to rename.</param>
|
||||
[RelayCommand]
|
||||
private void RenameVaultRow(VaultRowViewModel? vault)
|
||||
{
|
||||
if (vault is not null)
|
||||
{
|
||||
SelectedVault = vault;
|
||||
}
|
||||
|
||||
RenameVaultCommand.Execute(null);
|
||||
}
|
||||
|
||||
/// <summary>Arms the delete confirmation for a specific vault, from the settings page's per-card delete icon.</summary>
|
||||
/// <inheritdoc cref="RenameVaultRow" path="/remarks" />
|
||||
/// <param name="vault">The vault to ask about deleting.</param>
|
||||
[RelayCommand]
|
||||
private void DeleteVaultRow(VaultRowViewModel? vault)
|
||||
{
|
||||
if (vault is not null)
|
||||
{
|
||||
SelectedVault = vault;
|
||||
}
|
||||
|
||||
DeleteVaultCommand.Execute(null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves the renamed vault.
|
||||
/// </summary>
|
||||
@@ -1538,6 +1626,13 @@ internal sealed partial class VaultsViewModel(
|
||||
PendingAction = null;
|
||||
IsRenamingVault = false;
|
||||
|
||||
// The members panel is drawn over one vault's people; a selection that clears altogether — the
|
||||
// vault it was showing got deleted, or the list emptied — leaves nothing for it to be about.
|
||||
if (value is null)
|
||||
{
|
||||
IsMembersPanelOpen = false;
|
||||
}
|
||||
|
||||
if (isReselecting)
|
||||
{
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user