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: 8 additions & 9 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]

### Changed
- **Shared parameter definitions — resolution groundwork.** A Snip's
`{token}` now resolves its parameter definition by name with precedence:
the Snip's own parameter overrides a CLI-scoped one, which overrides a
global one. A Snip can omit a parameter to inherit the shared definition
(e.g. an `env` Choice defined once on a CLI). Store schema is now v2
(additive: `Cli.Parameters` + `SnipStoreDocument.GlobalParameters`); an
older build refuses a v2 store rather than dropping shared definitions.
The UI to manage shared parameters lands next; existing snips are
unaffected.
- **JSON stores moved to System.Text.Json source generation.** `JsonSnipStore`
and `JsonSettingsStore` now serialise via a generated `JsonSerializerContext`
instead of the reflection-based serializer, removing the IL2026 trim warnings.
Expand All @@ -26,6 +17,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
IL2104 on the WinAppSDK/WinRT/Jdenticon assemblies, which aren't trim-safe.

### Added
- **Shared parameter definitions.** Define a parameter once and reuse it
across snips, at two scopes: **CLI-scoped** (in the CLI editor — inherited by
every snip under that CLI) and **global** (a new "Shared parameters" entry in
the left pane — available to every snip across all CLIs). A snip's `{token}`
resolves its definition by name with precedence **snip-local → CLI → global**;
omit a parameter to inherit the shared one, or define it locally to override.
Existing snips are unaffected. (Store schema is now v2; an older build refuses
a v2 store rather than dropping shared definitions.)
- **Change the storage location.** A "Change…" button on Settings → Storage
location lets you pick a new folder for your snips. If the folder already
contains a Snipdeck store it's adopted (your current snips are left where
Expand Down
101 changes: 84 additions & 17 deletions src/Snipdeck.App/Views/CliEditorDialog.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
x:Class="Snipdeck.App.Views.CliEditorDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:Snipdeck.Core.ViewModels"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Expand All @@ -11,30 +12,96 @@
CloseButtonText="Cancel"
DefaultButton="Primary">

<StackPanel MinWidth="400" Spacing="12">
<TextBox Header="Name"
Text="{x:Bind ViewModel.Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<ScrollViewer VerticalScrollBarVisibility="Auto" MaxHeight="560">
<StackPanel MinWidth="400" Spacing="12">
<TextBox Header="Name"
Text="{x:Bind ViewModel.Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

<StackPanel Spacing="6">
<TextBlock Text="Icon"
Style="{ThemeResource BodyStrongTextBlockStyle}" />
<TextBlock Text="Defaults to a deterministic identicon. Upload an image to override; it'll be cropped square and resized to 256×256."
Style="{ThemeResource CaptionTextBlockStyle}"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
TextWrapping="Wrap" />
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
Text="{x:Bind ViewModel.PickedIconFileName, Mode=OneWay}"
VerticalAlignment="Center"
TextTrimming="CharacterEllipsis" />
<Button Grid.Column="1"
Content="Choose image..."
Click="OnPickIconClicked" />
</Grid>
</StackPanel>

<StackPanel Spacing="6">
<TextBlock Text="Icon"
Style="{ThemeResource BodyStrongTextBlockStyle}" />
<TextBlock Text="Defaults to a deterministic identicon. Upload an image to override; it'll be cropped square and resized to 256×256."
Style="{ThemeResource CaptionTextBlockStyle}"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
TextWrapping="Wrap" />
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
Text="{x:Bind ViewModel.PickedIconFileName, Mode=OneWay}"
VerticalAlignment="Center"
TextTrimming="CharacterEllipsis" />
<StackPanel Grid.Column="0" VerticalAlignment="Center">
<TextBlock Text="Shared parameters"
Style="{ThemeResource BodyStrongTextBlockStyle}" />
<TextBlock Text="Inherited by every snip under this CLI that uses the matching {token}."
Style="{ThemeResource CaptionTextBlockStyle}"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
TextWrapping="Wrap" />
</StackPanel>
<Button Grid.Column="1"
Content="Choose image..."
Click="OnPickIconClicked" />
VerticalAlignment="Top"
Content="Add parameter"
Click="OnAddParameterClicked" />
</Grid>

<ItemsControl ItemsSource="{x:Bind ViewModel.Parameters}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Spacing="8" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="vm:ParameterEditorRowViewModel">
<Border Background="{ThemeResource SubtleFillColorSecondaryBrush}"
CornerRadius="6"
Padding="12">
<StackPanel Spacing="8">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0"
Header="Name"
Text="{x:Bind Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<Button Grid.Column="1"
Margin="8,24,0,0"
Click="OnRemoveParameterClicked"
Tag="{x:Bind}"
ToolTipService.ToolTip="Remove parameter">
<FontIcon Glyph="&#xE74D;" FontSize="14" />
</Button>
</Grid>
<ComboBox Header="Type"
SelectedIndex="{x:Bind TypeIndex, Mode=TwoWay}"
HorizontalAlignment="Stretch">
<x:String>Text</x:String>
<x:String>Choice</x:String>
</ComboBox>
<TextBox Header="Default"
Text="{x:Bind Default, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<TextBox Header="Options (comma-separated, Choice only)"
Text="{x:Bind OptionsText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
IsEnabled="{x:Bind IsChoice, Mode=OneWay}" />
</StackPanel>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</StackPanel>
</ScrollViewer>
</ContentDialog>
13 changes: 13 additions & 0 deletions src/Snipdeck.App/Views/CliEditorDialog.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,19 @@ private void UpdatePrimaryButtonEnabled()
IsPrimaryButtonEnabled = ViewModel.CanSave;
}

private void OnAddParameterClicked(object sender, RoutedEventArgs e)
{
ViewModel.AddParameter();
}

private void OnRemoveParameterClicked(object sender, RoutedEventArgs e)
{
if (sender is FrameworkElement element && element.Tag is ParameterEditorRowViewModel row)
{
ViewModel.RemoveParameter(row);
}
}

private async void OnPickIconClicked(object sender, RoutedEventArgs e)
{
var picked = await _filePicker.PickImageAsync();
Expand Down
3 changes: 3 additions & 0 deletions src/Snipdeck.App/Views/ShellContentTemplateSelector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ public sealed partial class ShellContentTemplateSelector : DataTemplateSelector

public DataTemplate? TrashTemplate { get; set; }

public DataTemplate? GlobalParametersTemplate { get; set; }

protected override DataTemplate? SelectTemplateCore(object item)
{
return item switch
Expand All @@ -27,6 +29,7 @@ public sealed partial class ShellContentTemplateSelector : DataTemplateSelector
CliViewModel => CliTemplate,
SettingsViewModel => SettingsTemplate,
TrashViewModel => TrashTemplate,
GlobalParametersViewModel => GlobalParametersTemplate,
_ => null,
};
}
Expand Down
100 changes: 99 additions & 1 deletion src/Snipdeck.App/Views/ShellPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
<converters:BoolToVisibilityConverter x:Key="BoolToVisibility" />
<converters:BoolToVisibilityConverter x:Key="InvertedBoolToVisibility" Invert="True" />
<converters:CountToVisibilityConverter x:Key="CountToVisibility" />
<converters:CountToVisibilityConverter x:Key="InvertedCountToVisibility" Invert="True" />
<converters:EmptyStringToVisibilityConverter x:Key="EmptyStringToVisibility" />

<DataTemplate x:Key="HomeContentTemplate" x:DataType="vm:HomeViewModel">
Expand Down Expand Up @@ -316,11 +317,97 @@
</ScrollViewer>
</DataTemplate>

<DataTemplate x:Key="GlobalParametersContentTemplate" x:DataType="vm:GlobalParametersViewModel">
<ScrollViewer VerticalScrollBarVisibility="Auto">
<StackPanel Padding="24" Spacing="16" MaxWidth="720" HorizontalAlignment="Stretch">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" VerticalAlignment="Center">
<TextBlock Text="Shared parameters"
Style="{ThemeResource TitleTextBlockStyle}" />
<TextBlock Text="Definitions available to every snip across all CLIs. A snip inherits one when its {token} matches and neither the snip nor its CLI defines that name."
Style="{ThemeResource CaptionTextBlockStyle}"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
TextWrapping="Wrap" />
</StackPanel>
<Button Grid.Column="1"
Margin="0,0,8,0"
Content="Add parameter"
Command="{x:Bind AddParameterCommand}" />
<Button Grid.Column="2"
Content="Save"
Style="{ThemeResource AccentButtonStyle}"
Command="{Binding ElementName=ShellRoot, Path=ViewModel.SaveGlobalParametersCommand}" />
</Grid>

<TextBlock Text="{x:Bind StatusMessage, Mode=OneWay}"
Style="{ThemeResource CaptionTextBlockStyle}"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Visibility="{x:Bind StatusMessage, Mode=OneWay, Converter={StaticResource EmptyStringToVisibility}}" />

<TextBlock Text="No global parameters yet. Add one to share it across every CLI."
Style="{ThemeResource BodyTextBlockStyle}"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Visibility="{x:Bind Parameters.Count, Mode=OneWay, Converter={StaticResource InvertedCountToVisibility}}" />

<ItemsControl ItemsSource="{x:Bind Parameters}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Spacing="8" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="vm:ParameterEditorRowViewModel">
<Border Background="{ThemeResource SubtleFillColorSecondaryBrush}"
CornerRadius="6"
Padding="12">
<StackPanel Spacing="8">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0"
Header="Name"
Text="{x:Bind Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<Button Grid.Column="1"
Margin="8,24,0,0"
Command="{Binding ElementName=ShellRoot, Path=ViewModel.CurrentContent.RemoveParameterCommand}"
CommandParameter="{x:Bind}"
ToolTipService.ToolTip="Remove parameter">
<FontIcon Glyph="&#xE74D;" FontSize="14" />
</Button>
</Grid>
<ComboBox Header="Type"
SelectedIndex="{x:Bind TypeIndex, Mode=TwoWay}"
HorizontalAlignment="Stretch">
<x:String>Text</x:String>
<x:String>Choice</x:String>
</ComboBox>
<TextBox Header="Default"
Text="{x:Bind Default, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<TextBox Header="Options (comma-separated, Choice only)"
Text="{x:Bind OptionsText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
IsEnabled="{x:Bind IsChoice, Mode=OneWay}" />
</StackPanel>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</ScrollViewer>
</DataTemplate>

<local:ShellContentTemplateSelector x:Key="ShellContentSelector"
HomeTemplate="{StaticResource HomeContentTemplate}"
CliTemplate="{StaticResource CliContentTemplate}"
SettingsTemplate="{StaticResource SettingsContentTemplate}"
TrashTemplate="{StaticResource TrashContentTemplate}" />
TrashTemplate="{StaticResource TrashContentTemplate}"
GlobalParametersTemplate="{StaticResource GlobalParametersContentTemplate}" />
</UserControl.Resources>

<NavigationView x:Name="ShellNavigation"
Expand All @@ -347,6 +434,17 @@

<NavigationView.PaneFooter>
<StackPanel>
<Button x:Name="SharedParametersButton"
Click="OnSharedParametersClicked"
HorizontalAlignment="Stretch"
Margin="12,8,12,0"
Background="Transparent"
BorderThickness="0">
<StackPanel Orientation="Horizontal" Spacing="12">
<FontIcon Glyph="&#xE8EC;" FontSize="16" />
<TextBlock Text="Shared parameters" VerticalAlignment="Center" />
</StackPanel>
</Button>
<Button x:Name="TrashButton"
Click="OnTrashClicked"
HorizontalAlignment="Stretch"
Expand Down
5 changes: 5 additions & 0 deletions src/Snipdeck.App/Views/ShellPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ private void OnTrashClicked(object sender, RoutedEventArgs e)
ViewModel.OpenTrash();
}

private void OnSharedParametersClicked(object sender, RoutedEventArgs e)
{
ViewModel.OpenGlobalParameters();
}

private void OnNavigationSelectionChanged(
NavigationView sender,
NavigationViewSelectionChangedEventArgs args)
Expand Down
Loading
Loading