Add InfiniteCanvasControl to UI.Adaptive (v1.27.0)
Details
Add reusable infinite canvas/whiteboard control with 8 partial class files
for modularity. Includes pan/zoom, element creation (note card, text, rect,
ellipse, freehand, group frame, image, page reference), connector rendering
(straight/curved/elbow with arrow heads), selection with marquee and resize
handles, Douglas-Peucker freehand simplification, viewport culling, drag-drop
support for page references and images, and a performance warning badge.
Models: CanvasData, CanvasElement, CanvasConnector, StrokePoint, CanvasToolMode
enum, CanvasElementType string constants, ConnectorStyle enum.
Bumps PrivStackSdkVersion from 1.26.0 to 1.27.0.
Replace update panel with status bar indicator and centered modal (1.29.0)
Details
The old UpdatePanel was a slide-in panel buried in the user menu that
users rarely discovered. This replaces it with two new surfaces:
1. Status bar indicator — a clickable text link in the bottom-right
status bar that shows "Check for updates" by default. Clicking it
triggers a manual check, briefly shows "On latest version (vX.X.X)"
for 5 seconds, then resets. When an update is found (either via
manual check or the 4-hour auto-check), it switches to "Update
available" with a green dot, persistently visible until acted on.
2. Centered update modal — follows the SubscriptionDetailModal pattern
with a semi-transparent backdrop, centered 440px card, version
transition display (vCurrent → vNew), optional release notes block,
download progress bar, and "Download & Install" / "Not Now" buttons.
Download auto-chains into install+restart on completion.
Also adds ReleaseNotes property to the desktop model (PlatformReleaseGroup
and LatestReleaseInfo) to surface release notes from the API.
Removes: UpdatePanel.axaml, UpdatePanel.axaml.cs, IsUpdatePanelOpen,
ToggleUpdatePanelCommand from MainWindowViewModel.
Wire unified recovery through C# desktop app
Details
Completes the unified recovery kit feature across the C# desktop layer:
Bindings:
- NativeLibrary: add CloudSyncSetupUnifiedRecovery + AuthResetWithUnifiedRecovery
- ICloudSyncService: add SetupUnifiedRecovery method
- CloudSyncService: implement SetupUnifiedRecovery via FFI
- IAuthService: add ResetWithUnifiedRecovery method
- PrivStackService: implement ResetWithUnifiedRecovery via FFI
PDF:
- Add UnifiedRecoveryKitPdfService with blue info box ("recovers BOTH
vault password and cloud data"), red warning, word grid, and two
instruction sections (vault + cloud recovery)
- Delete CloudRecoveryKitPdfService (replaced by unified service)
ViewModels:
- CloudSyncSettingsViewModel: EnableForWorkspaceAsync now calls
SetupUnifiedRecovery instead of SetupPassphrase; SaveRecoveryKitPdf
uses UnifiedRecoveryKitPdfService with updated title/filename
- RecoveryViewModel: ResetPasswordAsync calls ResetWithUnifiedRecovery
to recover both vault and cloud in one step
- SettingsViewModel.EmergencyKit: RegenerateEmergencyKit uses unified
recovery when cloud is active; DownloadRegeneratedKit uses unified
PDF service when cloud is active
Tests:
- Update EnableForWorkspaceAsync_ShowsRecoveryKit to mock SetupUnifiedRecovery
- Add EnableForWorkspaceAsync_DoesNotCallSetupPassphrase test
- Update FailsWhenVaultLocked to verify neither setup method is called
Version: PrivStack.Desktop 1.27.0 -> 1.28.0
Backward compatible: old Emergency Kit mnemonics still work via
existing ResetWithRecovery; old cloud mnemonics work via existing
RecoverFromMnemonic. No existing FFI functions removed.
Add create_recovery_blob_with_mnemonic for unified recovery
Details
Adds a new crypto primitive that encrypts the vault master key with a
caller-provided mnemonic instead of generating a fresh one. This enables
the unified recovery flow where a single BIP39 mnemonic protects both
the vault master key and the cloud X25519 keypair.
Changes:
- privstack-crypto: add create_recovery_blob_with_mnemonic() + tests
- privstack-crypto: export new function from lib.rs
- privstack-vault: add Vault::setup_recovery_with_mnemonic() that
stores a recovery blob using an external mnemonic
- privstack-vault: add VaultManager::setup_recovery_with_mnemonic()
wrapper
- Bump workspace version to 1.10.0
Two new tests verify round-trip decryption and cross-compatibility
(same mnemonic decrypts both vault blob and simulated cloud keypair).
Add cloud sync UI (settings, status bar, workspace creation)
Details
Implement the full Cloud Sync UI layer connecting to the existing
Rust FFI CloudSyncService backend. This adds:
- CloudSyncSettingsViewModel: manages auth, passphrase setup/unlock,
mnemonic recovery, sync status, quota, and device list. Follows the
ConnectionsViewModel pattern as a composed property on SettingsViewModel.
- CloudSyncSettingsSection view: UserControl with visibility-driven
state sections (auth form, passphrase setup, passphrase entry,
recovery form, sync dashboard with status/quota/devices).
- Settings panel integration: new "Cloud Sync" expander between
Connections and Security sections, with xmlns:views namespace.
- Status bar cloud sync indicator: StorageStatePillViewModel now checks
for PrivStackCloud sync tier before file-sync/P2P logic. Shows
"Syncing (N)" with pending count, "Synced" when caught up, or
"Cloud (Paused)" when authenticated but not syncing. Includes a
5-second DispatcherTimer poll while cloud sync is active.
- Workspace creation cloud sync option: WorkspaceSwitcherViewModel gains
SelectedSyncTier and IsCloudSyncAvailable properties plus
SelectCloudSync command. The overlay shows a "PrivStack Cloud" button
(E2E encrypted) alongside Google Drive/iCloud/Custom options.
ConfirmStorageLocation registers the workspace with cloud if selected.
- Unit tests: 18 tests for CloudSyncSettingsViewModel covering auth,
passphrase validation, mnemonic, sync start/stop, quota, and devices.
5 tests for StorageStatePill cloud status model behavior.
Version bumped to 1.27.0 (minor: new feature).
Get notified about new releases