Skip to content

Commit 911d616

Browse files
committed
WIP
1 parent efb60ca commit 911d616

File tree

9 files changed

+158
-2
lines changed

9 files changed

+158
-2
lines changed

App/App.csproj

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@
3636
<SelfContained>false</SelfContained>
3737
</PropertyGroup>
3838

39+
<ItemGroup>
40+
<None Remove="Views\Pages\PortForwardCreation.xaml" />
41+
</ItemGroup>
42+
3943
<ItemGroup>
4044
<Content Include="coder.ico" />
4145
<EmbeddedResource Include="Assets\changelog.css" />
@@ -90,4 +94,10 @@
9094
<ProjectReference Include="..\Vpn.Proto\Vpn.Proto.csproj" />
9195
<ProjectReference Include="..\Vpn\Vpn.csproj" />
9296
</ItemGroup>
97+
98+
<ItemGroup>
99+
<Page Update="Views\Pages\PortForwardCreation.xaml">
100+
<Generator>MSBuild:Compile</Generator>
101+
</Page>
102+
</ItemGroup>
93103
</Project>

App/App.xaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
<ResourceDictionary>
1010
<ResourceDictionary.MergedDictionaries>
1111
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
12+
<ResourceDictionary
13+
Source="ms-appx:///CommunityToolkit.WinUI.Controls.SettingsControls/SettingsExpander/SettingsExpander.xaml" />
1214
</ResourceDictionary.MergedDictionaries>
1315

1416
<converters:InverseBoolConverter x:Key="InverseBoolConverter" />

App/Models/Settings.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
using System.Collections.Generic;
2+
13
namespace Coder.Desktop.App.Models;
24

35
public interface ISettings<T> : ICloneable<T>
@@ -34,6 +36,8 @@ public class CoderConnectSettings : ISettings<CoderConnectSettings>
3436
/// </summary>
3537
public bool ConnectOnLaunch { get; set; }
3638

39+
public List<PortForward> PortForwards { get; set; } = [];
40+
3741
/// <summary>
3842
/// CoderConnect current settings version. Increment this when the settings schema changes.
3943
/// In future iterations we will be able to handle migrations when the user has
@@ -60,3 +64,10 @@ public CoderConnectSettings Clone()
6064
return new CoderConnectSettings(Version, ConnectOnLaunch);
6165
}
6266
}
67+
68+
public class PortForward
69+
{
70+
public string Workspace { get; set; } = string.Empty;
71+
public int LocalPort { get; set; }
72+
public int RemotePort { get; set; }
73+
}

App/ViewModels/SettingsViewModel.cs

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
using Coder.Desktop.App.Models;
22
using Coder.Desktop.App.Services;
3+
using Coder.Desktop.App.Views.Pages;
34
using CommunityToolkit.Mvvm.ComponentModel;
5+
using CommunityToolkit.Mvvm.Input;
46
using Microsoft.Extensions.Logging;
7+
using Microsoft.UI.Xaml;
8+
using Microsoft.UI.Xaml.Controls;
59
using System;
10+
using System.Collections;
11+
using System.Collections.Generic;
12+
using System.Linq;
13+
using static Coder.Desktop.App.Models.CoderConnectSettings;
614

715
namespace Coder.Desktop.App.ViewModels;
816

@@ -22,12 +30,19 @@ public partial class SettingsViewModel : ObservableObject
2230
private ISettingsManager<CoderConnectSettings> _connectSettingsManager;
2331
private CoderConnectSettings _connectSettings = new CoderConnectSettings();
2432
private IStartupManager _startupManager;
33+
private IRpcController _rpcController;
2534

26-
public SettingsViewModel(ILogger<SettingsViewModel> logger, ISettingsManager<CoderConnectSettings> settingsManager, IStartupManager startupManager)
35+
private Window? _window;
36+
37+
public IEnumerable<PortForward> PortForwards => _connectSettings.PortForwards;
38+
39+
public SettingsViewModel(ILogger<SettingsViewModel> logger, ISettingsManager<CoderConnectSettings> settingsManager, IStartupManager startupManager,
40+
IRpcController rpcController)
2741
{
2842
_connectSettingsManager = settingsManager;
2943
_startupManager = startupManager;
3044
_logger = logger;
45+
_rpcController = rpcController;
3146
_connectSettings = settingsManager.Read().GetAwaiter().GetResult();
3247
StartOnLogin = startupManager.IsEnabled();
3348
ConnectOnLaunch = _connectSettings.ConnectOnLaunch;
@@ -43,6 +58,11 @@ public SettingsViewModel(ILogger<SettingsViewModel> logger, ISettingsManager<Cod
4358
}
4459
}
4560

61+
public void Initialize(Window window)
62+
{
63+
_window = window;
64+
}
65+
4666
partial void OnConnectOnLaunchChanged(bool oldValue, bool newValue)
4767
{
4868
if (oldValue == newValue)
@@ -78,4 +98,48 @@ partial void OnStartOnLoginChanged(bool oldValue, bool newValue)
7898
_logger.LogError($"Error setting StartOnLogin in registry: {ex.Message}");
7999
}
80100
}
101+
102+
[RelayCommand]
103+
public async void AddPortForward()
104+
{
105+
var rpcModel = _rpcController.GetState();
106+
if(rpcModel.RpcLifecycle != RpcLifecycle.Connected)
107+
{
108+
_logger.LogWarning("Cannot add port forward, RPC is not connected.");
109+
return;
110+
}
111+
var hosts = new List<string>(rpcModel.Agents.Count);
112+
// Agents will only contain started agents.
113+
foreach (var agent in rpcModel.Agents)
114+
{
115+
var fqdn = agent.Fqdn
116+
.Select(a => a.Trim('.'))
117+
.Where(a => !string.IsNullOrWhiteSpace(a))
118+
.Aggregate((a, b) => a.Count(c => c == '.') < b.Count(c => c == '.') ? a : b);
119+
if (string.IsNullOrWhiteSpace(fqdn))
120+
continue;
121+
hosts.Add(fqdn);
122+
}
123+
var dialog = new ContentDialog();
124+
125+
dialog.XamlRoot = _window?.Content.XamlRoot ?? throw new InvalidOperationException("Window content XamlRoot is null.");
126+
dialog.Style = Application.Current.Resources["DefaultContentDialogStyle"] as Style;
127+
dialog.Title = "Save your work?";
128+
dialog.PrimaryButtonText = "Save";
129+
dialog.CloseButtonText = "Cancel";
130+
dialog.DefaultButton = ContentDialogButton.Primary;
131+
dialog.Content = new PortForwardCreation(hosts);
132+
133+
var result = await dialog.ShowAsync();
134+
135+
if (result == ContentDialogResult.Primary)
136+
{
137+
var portForwardCreation = dialog.Content as PortForwardCreation;
138+
if (portForwardCreation != null)
139+
{
140+
_connectSettings.PortForwards.Add(portForwardCreation.PortForward);
141+
_connectSettingsManager.Write(_connectSettings).GetAwaiter().GetResult();
142+
}
143+
}
144+
}
81145
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Page
3+
x:Class="Coder.Desktop.App.Views.Pages.PortForwardCreation"
4+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
5+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
6+
xmlns:local="using:Coder.Desktop.App.Views.Pages"
7+
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
8+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
9+
mc:Ignorable="d">
10+
11+
<StackPanel VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
12+
<ComboBox
13+
ItemsSource="{x:Bind Hosts, Mode=OneWay}"
14+
SelectedItem="{x:Bind PortForward.Workspace, Mode=TwoWay}"
15+
ToolTipService.ToolTip="Workspace to forward the port from"
16+
VerticalAlignment="Stretch"
17+
HorizontalAlignment="Stretch" />
18+
<TextBox Header="Local port" Text="{x:Bind PortForward.LocalPort}" />
19+
<TextBox Header="Remote port" Text="{x:Bind PortForward.RemotePort}" />
20+
</StackPanel>
21+
</Page>
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using Coder.Desktop.App.Models;
2+
using Microsoft.UI.Xaml.Controls;
3+
using System.Collections.Generic;
4+
5+
namespace Coder.Desktop.App.Views.Pages
6+
{
7+
/// <summary>
8+
/// An empty page that can be used on its own or navigated to within a Frame.
9+
/// </summary>
10+
public sealed partial class PortForwardCreation : Page
11+
{
12+
public PortForward PortForward { get; set; } = new();
13+
public List<string> Hosts { get; set; } = [];
14+
public PortForwardCreation()
15+
{
16+
InitializeComponent();
17+
}
18+
19+
public PortForwardCreation(List<string> hosts) : this()
20+
{
21+
Hosts = hosts;
22+
}
23+
}
24+
}

App/Views/Pages/SettingsMainPage.xaml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
xmlns:ui="using:CommunityToolkit.WinUI"
1212
xmlns:win="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
1313
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
14+
xmlns:models="using:Coder.Desktop.App.Models"
1415
mc:Ignorable="d">
1516

1617
<Page.Resources>
@@ -44,6 +45,28 @@
4445
>
4546
<ToggleSwitch IsOn="{x:Bind ViewModel.ConnectOnLaunch, Mode=TwoWay}" />
4647
</controls:SettingsCard>
48+
<controls:SettingsExpander Description="The SettingsExpander can use ItemsSource to define its Items."
49+
Header="Settings Expander with ItemsSource"
50+
HeaderIcon="{ui:FontIcon Glyph=&#xEA37;}"
51+
ItemsSource="{x:Bind ViewModel.PortForwards}">
52+
<controls:SettingsExpander.ItemTemplate>
53+
<DataTemplate x:DataType="models:PortForward">
54+
<controls:SettingsCard Description="{x:Bind LocalPort}"
55+
Header="{x:Bind Workspace}">
56+
</controls:SettingsCard>
57+
</DataTemplate>
58+
</controls:SettingsExpander.ItemTemplate>
59+
<controls:SettingsExpander.ItemsFooter>
60+
<controls:SettingsCard Header="Add mapping"
61+
Style="{StaticResource DefaultSettingsExpanderItemStyle}">
62+
<HyperlinkButton
63+
Command="{x:Bind ViewModel.AddPortForwardCommand}">
64+
<TextBlock Text="Add new port forward" />
65+
</HyperlinkButton>
66+
</controls:SettingsCard>
67+
</controls:SettingsExpander.ItemsFooter>
68+
</controls:SettingsExpander>
69+
4770
</StackPanel>
4871
</Grid>
4972
</ScrollViewer>

App/Views/SettingsWindow.xaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
mc:Ignorable="d"
1111
Title="Coder Settings"
1212
Width="600" Height="350"
13-
MinWidth="600" MinHeight="350">
13+
MinWidth="600" MinHeight="450">
1414

1515
<Window.SystemBackdrop>
1616
<MicaBackdrop/>

App/Views/SettingsWindow.xaml.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ public sealed partial class SettingsWindow : WindowEx
1313
public SettingsWindow(SettingsViewModel viewModel)
1414
{
1515
ViewModel = viewModel;
16+
ViewModel.Initialize(this);
1617
InitializeComponent();
1718
TitleBarIcon.SetTitlebarIcon(this);
1819

0 commit comments

Comments
 (0)