Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 8a7acc1

Browse files
committedApr 22, 2025·
feat: add remote directory picker to file sync
Adds a new remote directory picker window used when creating a file sync to select the remote directory.
1 parent 8f60b4d commit 8a7acc1

23 files changed

+990
-170
lines changed
 

‎App/App.csproj

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@
2929
<SelfContained>false</SelfContained>
3030
</PropertyGroup>
3131

32+
<ItemGroup>
33+
<None Remove="Views\Pages\DirectoryPickerMainPage.xaml" />
34+
</ItemGroup>
35+
3236
<ItemGroup>
3337
<Content Include="coder.ico" />
3438
</ItemGroup>
@@ -56,6 +60,7 @@
5660

5761
<ItemGroup>
5862
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
63+
<PackageReference Include="CommunityToolkit.WinUI.Controls.Primitives" Version="8.2.250402" />
5964
<PackageReference Include="DependencyPropertyGenerator" Version="1.5.0">
6065
<PrivateAssets>all</PrivateAssets>
6166
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
@@ -74,4 +79,16 @@
7479
<ProjectReference Include="..\Vpn.Proto\Vpn.Proto.csproj" />
7580
<ProjectReference Include="..\Vpn\Vpn.csproj" />
7681
</ItemGroup>
82+
83+
<ItemGroup>
84+
<Page Update="Views\Pages\DirectoryPickerMainPage.xaml">
85+
<Generator>MSBuild:Compile</Generator>
86+
</Page>
87+
</ItemGroup>
88+
89+
<ItemGroup>
90+
<Page Update="Views\DirectoryPickerWindow.xaml">
91+
<Generator>MSBuild:Compile</Generator>
92+
</Page>
93+
</ItemGroup>
7794
</Project>

‎App/App.xaml.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using Coder.Desktop.App.ViewModels;
88
using Coder.Desktop.App.Views;
99
using Coder.Desktop.App.Views.Pages;
10+
using Coder.Desktop.CoderSdk.Agent;
1011
using Coder.Desktop.Vpn;
1112
using Microsoft.Extensions.Configuration;
1213
using Microsoft.Extensions.DependencyInjection;
@@ -37,6 +38,8 @@ public App()
3738

3839
var services = builder.Services;
3940

41+
services.AddSingleton<IAgentApiClientFactory, AgentApiClientFactory>();
42+
4043
services.AddSingleton<ICredentialManager, CredentialManager>();
4144
services.AddSingleton<IRpcController, RpcController>();
4245

@@ -53,6 +56,8 @@ public App()
5356
// FileSyncListMainPage is created by FileSyncListWindow.
5457
services.AddTransient<FileSyncListWindow>();
5558

59+
// DirectoryPickerWindow views and view models are created by FileSyncListViewModel.
60+
5661
// TrayWindow views and view models
5762
services.AddTransient<TrayWindowLoadingPage>();
5863
services.AddTransient<TrayWindowDisconnectedViewModel>();

‎App/Converters/DependencyObjectSelector.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,3 +186,7 @@ private static void SelectedKeyPropertyChanged(DependencyObject obj, DependencyP
186186
public sealed class StringToBrushSelectorItem : DependencyObjectSelectorItem<string, Brush>;
187187

188188
public sealed class StringToBrushSelector : DependencyObjectSelector<string, Brush>;
189+
190+
public sealed class StringToStringSelectorItem : DependencyObjectSelectorItem<string, string>;
191+
192+
public sealed class StringToStringSelector : DependencyObjectSelector<string, string>;

‎App/Services/CredentialManager.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using System.Threading.Tasks;
88
using Coder.Desktop.App.Models;
99
using Coder.Desktop.CoderSdk;
10+
using Coder.Desktop.CoderSdk.Coder;
1011
using Coder.Desktop.Vpn.Utilities;
1112

1213
namespace Coder.Desktop.App.Services;

‎App/Services/MutagenController.cs

Lines changed: 43 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
using Coder.Desktop.MutagenSdk.Proto.Service.Prompting;
1313
using Coder.Desktop.MutagenSdk.Proto.Service.Synchronization;
1414
using Coder.Desktop.MutagenSdk.Proto.Synchronization;
15+
using Coder.Desktop.MutagenSdk.Proto.Synchronization.Core.Ignore;
1516
using Coder.Desktop.MutagenSdk.Proto.Url;
1617
using Coder.Desktop.Vpn.Utilities;
1718
using Grpc.Core;
@@ -213,8 +214,11 @@ public async Task<SyncSessionModel> CreateSyncSession(CreateSyncSessionRequest r
213214
{
214215
Alpha = req.Alpha.MutagenUrl,
215216
Beta = req.Beta.MutagenUrl,
216-
// TODO: probably should set these at some point
217-
Configuration = new Configuration(),
217+
// TODO: probably should add a configuration page for these at some point
218+
Configuration = new Configuration
219+
{
220+
IgnoreVCSMode = IgnoreVCSMode.Ignore,
221+
},
218222
ConfigurationAlpha = new Configuration(),
219223
ConfigurationBeta = new Configuration(),
220224
},
@@ -534,25 +538,43 @@ private void StartDaemonProcess()
534538
Directory.CreateDirectory(_mutagenDataDirectory);
535539
var logPath = Path.Combine(_mutagenDataDirectory, "daemon.log");
536540
var logStream = new StreamWriter(logPath, true);
537-
538-
_daemonProcess = new Process();
539-
_daemonProcess.StartInfo.FileName = _mutagenExecutablePath;
540-
_daemonProcess.StartInfo.Arguments = "daemon run";
541-
_daemonProcess.StartInfo.Environment.Add("MUTAGEN_DATA_DIRECTORY", _mutagenDataDirectory);
542-
// hide the console window
543-
_daemonProcess.StartInfo.CreateNoWindow = true;
544-
// shell needs to be disabled since we set the environment
545-
// https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.processstartinfo.environment?view=net-8.0
546-
_daemonProcess.StartInfo.UseShellExecute = false;
547-
_daemonProcess.StartInfo.RedirectStandardError = true;
548-
// TODO: log exited process
549-
// _daemonProcess.Exited += ...
550-
if (!_daemonProcess.Start())
551-
throw new InvalidOperationException("Failed to start mutagen daemon process, Start returned false");
552-
553-
var writer = new LogWriter(_daemonProcess.StandardError, logStream);
554-
Task.Run(() => { _ = writer.Run(); });
555-
_logWriter = writer;
541+
try
542+
{
543+
_daemonProcess = new Process();
544+
_daemonProcess.StartInfo.FileName = _mutagenExecutablePath;
545+
_daemonProcess.StartInfo.Arguments = "daemon run";
546+
_daemonProcess.StartInfo.Environment.Add("MUTAGEN_DATA_DIRECTORY", _mutagenDataDirectory);
547+
// hide the console window
548+
_daemonProcess.StartInfo.CreateNoWindow = true;
549+
// shell needs to be disabled since we set the environment
550+
// https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.processstartinfo.environment?view=net-8.0
551+
_daemonProcess.StartInfo.UseShellExecute = false;
552+
_daemonProcess.StartInfo.RedirectStandardError = true;
553+
// TODO: log exited process
554+
// _daemonProcess.Exited += ...
555+
if (!_daemonProcess.Start())
556+
throw new InvalidOperationException("Failed to start mutagen daemon process, Start returned false");
557+
558+
var writer = new LogWriter(_daemonProcess.StandardError, logStream);
559+
Task.Run(() => { _ = writer.Run(); });
560+
_logWriter = writer;
561+
}
562+
catch
563+
{
564+
try
565+
{
566+
_daemonProcess?.Kill();
567+
}
568+
catch
569+
{
570+
// ignored
571+
}
572+
_daemonProcess?.Dispose();
573+
_logWriter?.Dispose();
574+
_daemonProcess = null;
575+
_logWriter = null;
576+
throw;
577+
}
556578
}
557579

558580
/// <summary>

0 commit comments

Comments
 (0)
Please sign in to comment.