Add alter_column_type mutation across Rust, FFI, and SDK (v1.12.0, SDK v1.39.0)
Details
Add ALTER COLUMN SET DATA TYPE support for datasets. The Rust store validates
the target type against a whitelist of known DuckDB types, executes the DDL,
and refreshes column metadata. The FFI layer exposes the operation as
privstack_dataset_alter_column_type returning PrivStackError. The SDK adds
AlterColumnTypeAsync to IDatasetService, with P/Invoke binding and service
implementation following the existing DropColumn/RenameColumn pattern. This
enables the Data plugin to let users change column types after import via
a confirmation overlay.
Replace all hardcoded AXAML colors, font sizes, and shadows with theme resources (v1.34.0, SDK v1.38.0)
Details
Systematic sweep across all AXAML files replacing hardcoded values:
- Modal backdrops: replaced inline #80000000 with Classes="modal-backdrop" (8 files)
- Modal card shadows: replaced inline BoxShadow with Classes="modal" (8 files)
- DashboardView: replaced 10x identical BoxShadow with Classes="shadow-sm"
- MainWindow: banner #E53E3E -> ThemeDangerBrush, Foreground="White" -> ThemeTextPrimaryBrush, raw FontSize -> theme resources
- SensitiveUnlockOverlay: #E0181820 -> modal-backdrop, #30F38BA8 -> ThemeDangerMutedBrush, Foreground="White" -> ThemeTextPrimaryBrush
- PasswordConfirmationWindow: BoxShadow -> modal class, #30F38BA8 -> ThemeDangerMutedBrush
- SettingsPanel: FontSize="18" -> ThemeFontSizeXl, Foreground="White" -> ThemeTextPrimaryBrush
- GraphView tags: #9CA3AF -> ThemeTextMutedBrush
- EmojiPicker/SkinTonePopover: backdrop and shadow -> theme classes
Added to PrivStackTheme.axaml:
- modal-backdrop-light class (#40000000) for lighter overlays
- shadow-sm, shadow-md, shadow-lg utility classes for shadow-only application
- Updated modal-backdrop to #80000000 matching actual modal usage
Add ThemedDropdown and IconLabel controls to UI.Adaptive (v1.37.0)
Details
Add two new shared controls to PrivStack.UI.Adaptive for enforcing
consistent styling across the app:
ThemedDropdown: Wraps a native ComboBox with standardized theme-aware
styling. Supports three size variants (Standard/Compact/Dense) with
enforced padding and corner radius. Properties include ItemsSource,
SelectedItem (TwoWay), SelectedIndex (TwoWay), PlaceholderText,
ItemTemplate, ShowBorder, and MaxDropDownHeight. Uses
GetResourceObservable for Background/Foreground auto-tracking and
ActualThemeVariantChanged for border/radius updates. Includes
re-entrancy guard for selection sync between the outer control
properties and the inner ComboBox.
IconLabel: Horizontal or vertical icon+text pair with optional
PathIcon and TextBlock. Hides icon when IconData is null, hides
text when Text is null/empty. Foreground defaults to
ThemeTextPrimaryBrush via resource observable when not explicitly
set. FontSize defaults to ThemeFontSizeSmMd (sentinel value 0)
for automatic theme binding. Supports configurable IconSize,
Spacing, FontWeight, and Orientation.
Both controls follow the existing PluginToolbar pattern: inherit
Border, compose children in constructor, forward StyledProperties
via OnPropertyChanged, and manage theme lifecycle via
OnAttachedToVisualTree/OnDetachedFromVisualTree.
SDK version: 1.36.0 -> 1.37.0
Desktop version: 1.33.5 -> 1.33.6
Add SupportedLinkTypes and typed NavigateToItemAsync to IDeepLinkTarget (v1.36.0)
Details
Plugins managing multiple entity types (e.g., Contacts with contact, company,
contact_group) had no way to register deep-link routing for sub-entity types.
Only the primary LinkType was matched, causing navigation failures for secondary
types like contact_group and company in both the neuron graph and info panel.
Added SupportedLinkTypes property with default implementation returning [LinkType]
for backward compatibility, and a NavigateToItemAsync(string linkType, string itemId)
overload so plugins can dispatch to the correct sub-view based on entity type.
Fix sync order and add offline email body cache (v1.13.0)
Details
Sync order: Changed FetchHeadersBatchedAsync from fire-and-forget
IProgress<T> callback to sequentially awaited Func<T, Task>. Batches
now persist in guaranteed newest-first order. Messages within each
batch and in the incremental sync path are sorted by date descending.
The MessageBatchSynced event now includes EmailAccount and EmailFolder
context for downstream consumers.
Offline body cache: Added EmailBodyCacheService backed by local
filesystem storage under WorkspaceDataPath/email-cache/. Bodies are
device-local and never synced between devices — each device downloads
its own copy directly from the IMAP server. A background Channel-based
download queue processes newly synced message batches (newest first).
The ViewModel checks the local cache before falling back to IMAP for
on-demand body fetches, and caches the result for future offline
access. Cache is cleaned up on account removal.
Get notified about new releases